Flaxman et
al. recently published a pre-print
claiming covid-19 was near the top of the top-10 leading causes of
death for children during the pandemic. Several have others have already
pointed out numerous issues with this analysis, most notably Kelley
of covid-georgia and @COVIDData3.
In rough order of priority:
- Comparing covid-19 as a multiple cause of death to other
causes as underlying causes.
- Comparing cumulative rates from covid-19 to annualized rate for
other causes.
- Comparing rates for covid-19 across multiple years to a single year
for other causes
- This may be affected seasonality and year-to-year volatility.
Because Flaxman et al. presumably wish to include the most recent
covid-19 deaths up through April 2022, the best way to handle this is to
compare these covid deaths from March 2020 to April 2022 with other
causes of deaths shifted back exactly one year so that we encompass the
same times of year (seasons) and span the same number of days. This has
the advantage of allowing us to get very close to an “apples-to-apples”
comparison with the available data while still trying to
reflect the most recent covid deaths.
Although it’d certainly be even easier to do this in one query for
the exact same time span, including the provisional estimates for other
causes of death in such a manner would substantially inflate covid’s
rank as many other causes of death are not yet
available for the last few weeks of 2021 through 2022.
More specifically, my approach is query this data spanning MMWR
weeks like so:
| Covid-19 |
2020 Week 10 (ending March 07, 2020) |
2022 Week 17 (ending April 30, 2022) |
113 |
| All
other |
2019 Week 10 (ending March 09, 2019) |
2021 Week 17 (ending May 01, 2021) |
113 |
One other advantage of using MMWR weeks is that CDC WONDER provides
population and crude rates whereas that information is not provided with
other sub-annual queries. All of which makes this analysis all that much
more straight forward..
library(knitr)
library(tidyverse)
library(janitor)
library(stringr)
library(reshape2)
library(hrbrthemes)
library(ggrepel)
library(viridis)
readCDCRates=function(filename,period) {
read_delim(filename,delim='\t',show_col_type=F) %>%
clean_names() %>%
transmute(
age_group=str_trim(five_year_age_groups),
cause=str_trim(ucd_icd_10_113_cause_list),
deaths=as.integer(deaths),
pop=as.integer(population),
crude_rate=as.numeric(crude_rate),
rate=deaths/pop*1e6, # per million
rate_rounded=round(rate,1),
period=period
) %>%
filter(
!is.na(deaths),
str_detect(cause,'^#') # only return 'rankable' items from the 113 cause list
)
}
file_co='leading_cause_comp/2020_wk_10 through 2022_wk_17 only covid-19.txt'
lc_covid_only=readCDCRates(file_co,'MMWR weeks: 2020/10 through 2022/17')
file_cl='leading_cause_comp/2019_wk_10 through 2021_wk_17 all 113 cause list.txt'
lc_causelist=readCDCRates(file_cl,'MMWR weeks: 2019/10 through 2021/17')
# calculate annualized adjustment for CDCs crude rates and/or the population (exposures)
actual_weeks=113
possible_weeks=(3*52)+1 # 157 b/c 2020 has a leap week & it's included in both denominators
annualized_adj=possible_weeks/actual_weeks
lc_comb=bind_rows(lc_covid_only,lc_causelist) %>%
filter(
# remove covid-19 item from the period starting in 2019
!( str_detect(period,'2019') & str_detect(cause,'COVID') )
) %>%
mutate(
age_only=str_trim(str_remove(age_group,"years?")),
last_age=case_when(
age_only == '< 1' ~ as.integer(0),
age_only == '100+' ~ as.integer(100),
TRUE ~ as.integer(str_extract(age_only,'\\d+$'))
),
age_group=reorder(age_group,last_age),
age_only=reorder(age_only,last_age),
# prettier names
cause_simp=case_when(
str_detect(cause,"#Congenital malformations") ~ 'Congenital Anomalies',
str_detect(cause,"#Accidents") ~ 'Unintentional Injury',
str_detect(cause,"#Assault") ~ 'Homicide',
str_detect(cause,"#Intentional self-harm") ~ 'Suicide',
str_detect(cause,"benign neoplasms") ~ 'Benign Neoplasms',
T ~ str_remove_all(str_remove(cause,"#"),"\\(.*\\)")
),
cause_simp=str_trim(cause_simp)
) %>%
arrange(age_group,rate,cause) %>%
group_by(age_group) %>%
mutate(
rank=rank(-rate,ties.method ='first'),
rate_annualized=round(rate*annualized_adj,1),
clab=sprintf("%s\n%0.1f",str_wrap(cause_simp,25),rate_annualized)
) %>%
ungroup()
lc_comb %>%
filter(
rank <= 10,
last_age <= 19,
T
) %>%
mutate(
type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
) %>%
ggplot(aes(age_group,rank,fill=rate)) +
geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +
scale_fill_viridis_c(trans='log10') +
geom_text(aes(label=clab),size=4) +
scale_y_reverse(breaks=seq(1,40,1)) +
scale_x_discrete(position='top') +
coord_cartesian(expand=F) +
theme_ipsum() +
theme(
legend.position='none',
panel.grid.minor = element_blank(),
panel.grid.major = element_blank()
) +
labs(
x=NULL,
y='Rank within age group',
title='Leading causes of death for children: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
subtitle='(the number below is annualized deaths per million)',
caption=paste(
'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
'Underlying causes, all rankable items from 113 cause list, ranked by rates',
'Covid-19: MMWR weeks 2020/10 through 2022/17',
'Other causes: MMWR weeks, 2019/10 through 2021/17',
'Same number of weeks and same seasons covered',
sep='\n'
)
)

nformats=format.args = list(decimal.mark = ".", big.mark = ",")
lc_comb %>%
filter(
str_detect(cause,'COVID'),
last_age < 85 # dont have population data to sort 85+ as rates, tho deaths will work
) %>%
transmute(
age_group,
rank,
deaths,
`population`=round(pop),
#`population (100k)`=round(pop/1e5),
`rate (as quoted)`=rate_rounded,
`rate (annualized)`=rate_annualized
) %>%
kable(caption='COVID-19 deaths and rank within age group',format.args = nformats)
COVID-19 deaths and rank within age group
| < 1 year |
9 |
172 |
11,205,030 |
15.4 |
21.3 |
| 1-4 years |
9 |
103 |
46,698,846 |
2.2 |
3.1 |
| 5-9 years |
7 |
106 |
60,713,133 |
1.7 |
2.4 |
| 10-14 years |
8 |
143 |
62,263,269 |
2.3 |
3.2 |
| 15-19 years |
6 |
564 |
62,882,787 |
9.0 |
12.5 |
| 20-24 years |
5 |
1,630 |
64,784,265 |
25.2 |
35.0 |
| 25-29 years |
4 |
3,335 |
69,693,729 |
47.9 |
66.5 |
| 30-34 years |
4 |
6,279 |
68,515,209 |
91.6 |
127.3 |
| 35-39 years |
2 |
9,660 |
65,484,912 |
147.5 |
205.0 |
| 40-44 years |
3 |
15,317 |
60,923,664 |
251.4 |
349.3 |
| 45-49 years |
4 |
24,214 |
59,911,818 |
404.2 |
561.5 |
| 50-54 years |
3 |
37,272 |
61,186,581 |
609.2 |
846.3 |
| 55-59 years |
3 |
55,512 |
64,809,297 |
856.5 |
1,190.1 |
| 60-64 years |
3 |
79,350 |
62,401,734 |
1,271.6 |
1,766.7 |
| 65-69 years |
3 |
95,764 |
53,621,001 |
1,785.9 |
2,481.4 |
| 70-74 years |
3 |
114,144 |
44,027,193 |
2,592.6 |
3,602.1 |
| 75-79 years |
3 |
116,598 |
29,960,499 |
3,891.7 |
5,407.1 |
| 80-84 years |
3 |
113,423 |
19,394,142 |
5,848.3 |
8,125.5 |
While we are at it, we can also report these rates for adults.
lc_comb %>%
filter(
rank <= 10,
last_age > 19,
last_age <= 54,
T
) %>%
mutate(
type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
) %>%
ggplot(aes(age_group,rank,fill=rate)) +
geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +
scale_fill_viridis_c(trans='log10') +
geom_text(aes(label=clab),size=3) +
scale_y_reverse(breaks=seq(1,40,1)) +
scale_x_discrete(position='top') +
coord_cartesian(expand=F) +
theme_ipsum() +
theme(
legend.position='none',
panel.grid.minor = element_blank(),
panel.grid.major = element_blank()
) +
labs(
x=NULL,
y='Rank within age group',
title='Leading causes of death: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
subtitle='(the number below is annualized deaths per million)',
caption=paste(
'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
'Underlying causes, all rankable items from 113 cause list, ranked by rates',
'Covid-19: MMWR weeks 2020/10 through 2022/17',
'Other causes: MMWR weeks, 2019/10 through 2021/17',
'Same number of weeks and same seasons covered',
sep='\n'
)
)

lc_comb %>%
filter(
rank <= 10,
last_age >= 55,
last_age <= 84,
T
) %>%
mutate(
type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
) %>%
ggplot(aes(age_group,rank,fill=rate)) +
geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +
scale_fill_viridis_c(trans='log10') +
geom_text(aes(label=clab),size=3) +
scale_y_reverse(breaks=seq(1,40,1)) +
scale_x_discrete(position='top') +
coord_cartesian(expand=F) +
theme_ipsum() +
theme(
legend.position='none',
panel.grid.minor = element_blank(),
panel.grid.major = element_blank()
) +
labs(
x=NULL,
y='Rank within age group',
title='Leading causes of death: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
subtitle='(the number below is annualized deaths per million)',
caption=paste(
'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
'Underlying causes, all rankable items from 113 cause list, ranked by rates',
'Covid-19: MMWR weeks 2020/10 through 2022/17',
'Other causes: MMWR weeks, 2019/10 through 2021/17',
'Same number of weeks and same seasons covered',
sep='\n'
)
)

LS0tDQp0aXRsZTogIkxlYWRpbmcgY2F1c2VzIGNvbXBhcmlzb24iDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCg0KDQpbRmxheG1hbiBldCBhbC5dKGh0dHBzOi8vdHdpdHRlci5jb20vZmxheHRlci9zdGF0dXMvMTUzODUzMzUzNzM1NTI4ODU3NykgcmVjZW50bHkgcHVibGlzaGVkIGEgW3ByZS1wcmludCBjbGFpbWluZyBjb3ZpZC0xOV0oaHR0cHM6Ly93d3cubWVkcnhpdi5vcmcvY29udGVudC8xMC4xMTAxLzIwMjIuMDUuMjMuMjIyNzU0NTh2Mikgd2FzIG5lYXIgdGhlIHRvcCBvZiB0aGUgdG9wLTEwIGxlYWRpbmcgY2F1c2VzIG9mIGRlYXRoIGZvciBjaGlsZHJlbiBkdXJpbmcgdGhlIHBhbmRlbWljLiAgU2V2ZXJhbCBoYXZlIG90aGVycyBoYXZlIGFscmVhZHkgcG9pbnRlZCBvdXQgbnVtZXJvdXMgaXNzdWVzIHdpdGggdGhpcyBhbmFseXNpcywgbW9zdCBub3RhYmx5IFtLZWxsZXkgb2YgY292aWQtZ2VvcmdpYV0oaHR0cHM6Ly93d3cuY292aWQtZ2VvcmdpYS5jb20vcGVkaWF0cmljLW5ld3MvZmFjdC1jaGVjay1jb3ZpZC1pcy1hLWxlYWRpbmctY2F1c2Utb2YtZGVhdGgtaW4tY2hpbGRyZW4vKSBhbmQgW0BDT1ZJRERhdGEzXShodHRwczovL3R3aXR0ZXIuY29tL0NPVklERGF0YTMvc3RhdHVzLzE1MzgzOTE5OTE1Nzg0MTEwMDkpLg0KDQpJbiByb3VnaCBvcmRlciBvZiBwcmlvcml0eToNCg0KLSBDb21wYXJpbmcgY292aWQtMTkgYXMgYSAqbXVsdGlwbGUqIGNhdXNlIG9mIGRlYXRoIHRvIG90aGVyIGNhdXNlcyBhcyAqdW5kZXJseWluZyogY2F1c2VzLg0KLSBDb21wYXJpbmcgY3VtdWxhdGl2ZSByYXRlcyBmcm9tIGNvdmlkLTE5IHRvIGFubnVhbGl6ZWQgcmF0ZSBmb3Igb3RoZXIgY2F1c2VzLg0KLSBDb21wYXJpbmcgcmF0ZXMgZm9yIGNvdmlkLTE5IGFjcm9zcyBtdWx0aXBsZSB5ZWFycyB0byBhIHNpbmdsZSB5ZWFyIGZvciBvdGhlciBjYXVzZXMNCiAgLSBUaGlzIG1heSBiZSBhZmZlY3RlZCBzZWFzb25hbGl0eSBhbmQgeWVhci10by15ZWFyIHZvbGF0aWxpdHkuDQoNCkJlY2F1c2UgRmxheG1hbiBldCBhbC4gcHJlc3VtYWJseSB3aXNoIHRvIGluY2x1ZGUgdGhlIG1vc3QgcmVjZW50IGNvdmlkLTE5IGRlYXRocyB1cCB0aHJvdWdoIEFwcmlsIDIwMjIsIHRoZSBiZXN0IHdheSB0byBoYW5kbGUgdGhpcyBpcyB0byBjb21wYXJlIHRoZXNlIGNvdmlkIGRlYXRocyBmcm9tIE1hcmNoIDIwMjAgdG8gQXByaWwgMjAyMiB3aXRoIG90aGVyIGNhdXNlcyBvZiBkZWF0aHMgc2hpZnRlZCBiYWNrIGV4YWN0bHkgb25lIHllYXIgc28gdGhhdCB3ZSBlbmNvbXBhc3MgdGhlIHNhbWUgdGltZXMgb2YgeWVhciAoc2Vhc29ucykgYW5kIHNwYW4gdGhlIHNhbWUgbnVtYmVyIG9mIGRheXMuICBUaGlzIGhhcyB0aGUgYWR2YW50YWdlIG9mIGFsbG93aW5nIHVzIHRvIGdldCB2ZXJ5IGNsb3NlIHRvIGFuICJhcHBsZXMtdG8tYXBwbGVzIiBjb21wYXJpc29uIHdpdGggdGhlIGF2YWlsYWJsZSBkYXRhIHdoaWxlIHN0aWxsICp0cnlpbmcqIHRvIHJlZmxlY3QgdGhlIG1vc3QgcmVjZW50IGNvdmlkIGRlYXRocy5eW1doaWNoIGlzbid0IHRvIHNheSBvbmUgY2Fubm90IHF1aWJibGUgd2l0aCB0aGlzIG1ldGhvZG9sb2d5IGVpdGhlci4gRm9yIGV4YW1wbGUsIGNvbXBhcmluZyBNYXJjaCAyMDIwLUFwcmlsIDIwMjIgbWF5IGZhaWwgdG8gcmVmbGVjdCBzb21lIG9mIHRoZSBzZWFzb25hbGl0eSBpbiByaXNrIHRoYXQgd291bGQgYmUgYmV0dGVyIG9ic2VydmVkIGlmIHdlIGNvbXBhcmVkIHRoZXNlIHN0YXRpc3RpY3MgYWNyb3NzIGVudGlyZSB5ZWFycyBvciBpbiBzdWNoIGFzIHdheSBhcyB0byBlbnN1cmUgYWxsIHNlYXNvbnMgYXJlIGVxdWFsbHkgd2VpZ2h0ZWQuXQ0KDQoNCkFsdGhvdWdoIGl0J2QgY2VydGFpbmx5IGJlIGV2ZW4gZWFzaWVyIHRvIGRvIHRoaXMgaW4gb25lIHF1ZXJ5IGZvciB0aGUgZXhhY3Qgc2FtZSB0aW1lIHNwYW4sIGluY2x1ZGluZyB0aGUgcHJvdmlzaW9uYWwgZXN0aW1hdGVzIGZvciBvdGhlciBjYXVzZXMgb2YgZGVhdGggaW4gc3VjaCBhIG1hbm5lciB3b3VsZCBzdWJzdGFudGlhbGx5IGluZmxhdGUgY292aWQncyByYW5rIGFzIG1hbnkgb3RoZXIgY2F1c2VzIG9mIGRlYXRoIGFyZSBbbm90IHlldCBhdmFpbGFibGVdKGh0dHBzOi8vd29uZGVyLmNkYy5nb3YvY29udHJvbGxlci9zYXZlZC9EMTc2L0QyOTZGMzg4KSBmb3IgdGhlIGxhc3QgZmV3IHdlZWtzIG9mIDIwMjEgdGhyb3VnaCAyMDIyLl5bQXMgSSB1bmRlcnN0YW5kIGl0LCB0aGlzIGlzIGJlY2F1c2UgW2NvdmlkLTE5IHdhcyBhZGRlZF0oaHR0cHM6Ly93d3cuY2RjLmdvdi9ubmRzcy9hY3Rpb24vc3Rvcmllcy9jb3ZpZC0xOS1yZXNwb25zZS5odG1sKSBzb21lIHRpbWUgYWdvIHRvIHRoZSBOYXRpb25hbCBOb3RpZmlhYmxlIERpc2Vhc2VzIFN1cnZlaWxsYW5jZSBTeXN0ZW0gd2hlcmVhcyBtYW55IG90aGVyIGNhdXNlcyBoYXZlIHRvIHdhaXQgdG8gd29yayB0aGVpciB3YXkgdGhyb3VnaCBmb3IgdGhlIHVzdWFsL3Nsb3dlciByZXBvcnRpbmcgcHJvY2Vzcy5dDQoNCk1vcmUgc3BlY2lmaWNhbGx5LCBteSBhcHByb2FjaCBpcyBxdWVyeSB0aGlzIGRhdGEgc3Bhbm5pbmcgW01NV1Igd2Vla3NdKGh0dHBzOi8vbmRjLnNlcnZpY2VzLmNkYy5nb3Yvd3AtY29udGVudC91cGxvYWRzL01NV1JfV2Vla19vdmVydmlldy5wZGYpIGxpa2Ugc286DQogIA0KfCBDYXVzZXMgfCBTdGFydCBXZWVrIHwgRW5kIFdlZWsgfCBOdW1iZXIgb2Ygd2Vla3MgfA0KfCAtLS0gfCAtLS0tLS0tLS0tLSB8IC0tLS0tLS0tLSB8IC0tLS0tLS0tLS0gfA0KfCBbQ292aWQtMTldKGh0dHBzOi8vd29uZGVyLmNkYy5nb3YvY29udHJvbGxlci9zYXZlZC9EMTc2L0QyOTZGMjE1KSB8IDIwMjAgV2VlayAxMDxiciAvPihlbmRpbmcgTWFyY2ggMDcsIDIwMjApICB8IDIwMjIgV2VlayAxNzxiciAvPihlbmRpbmcgQXByaWwgMzAsIDIwMjIpIHwgMTEzIA0KfCBbQWxsIG90aGVyXShodHRwczovL3dvbmRlci5jZGMuZ292L2NvbnRyb2xsZXIvc2F2ZWQvRDE3Ni9EMjk2RjIyMikgfCAyMDE5IFdlZWsgMTA8YnIgLz4oZW5kaW5nIE1hcmNoIDA5LCAyMDE5KSB8IDIwMjEgV2VlayAxNzxiciAvPihlbmRpbmcgTWF5IDAxLCAyMDIxKSB8IDExMw0KDQpPbmUgb3RoZXIgYWR2YW50YWdlIG9mIHVzaW5nIE1NV1Igd2Vla3MgaXMgdGhhdCBDREMgV09OREVSIHByb3ZpZGVzIHBvcHVsYXRpb24gYW5kIGNydWRlIHJhdGVzIHdoZXJlYXMgdGhhdCBpbmZvcm1hdGlvbiBpcyBub3QgcHJvdmlkZWQgd2l0aCBvdGhlciBzdWItYW5udWFsIHF1ZXJpZXMuICBBbGwgb2Ygd2hpY2ggbWFrZXMgdGhpcyBhbmFseXNpcyBhbGwgdGhhdCBtdWNoIG1vcmUgc3RyYWlnaHQgZm9yd2FyZC5eW09uIHRoZSBvdGhlciBoYW5kLCB0aGUgcG9wdWxhdGlvbnMgdGhleSBwcm92aWRlIGFyZSBiYXNlZCBvbiB0aGUgc3VtIG9mIHBvcHVsYXRpb24gZXN0aW1hdGVzIGFjcm9zcyBlYWNoIG9mIHRoZSB0aHJlZSB5ZWFycyB0aGVzZSBNTVdSIHdlZWtzIHNwYW4sIHdpdGggdGhlIG51bWVyYXRvciAoZGVhdGhzKSB1bmFkanVzdGVkLCBzbyB0aGUgcmF0ZXMgYXJlIG5vdCBxdWl0ZSBhbm51YWxpemVkIGVpdGhlci4gVGhpcyBtYWtlcyBubyBkaWZmZXJlbmNlIGZvciBpbnRlcm5hbCBjb21wYXJpc29ucyBiZWNhdXNlIGVhY2ggcGVyaW9kIGlzIGV4YWN0bHkgMTEzIHdlZWtzIGxvbmcuICBUaGV5IGNhbiBiZSBhbm51YWxpemVkIGJ5IG11bHRpcGx5aW5nIHRoZSByYXRlIGJ5IH4xLjM5ICgxNTcgLyAxMTMpXS4NCg0KDQoNCg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQ0KDQoNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGhyYnJ0aGVtZXMpDQpsaWJyYXJ5KGdncmVwZWwpDQpsaWJyYXJ5KHZpcmlkaXMpDQoNCnJlYWRDRENSYXRlcz1mdW5jdGlvbihmaWxlbmFtZSxwZXJpb2QpIHsNCiAgcmVhZF9kZWxpbShmaWxlbmFtZSxkZWxpbT0nXHQnLHNob3dfY29sX3R5cGU9RikgJT4lDQogICAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgICB0cmFuc211dGUoDQogICAgICBhZ2VfZ3JvdXA9c3RyX3RyaW0oZml2ZV95ZWFyX2FnZV9ncm91cHMpLA0KICAgICAgY2F1c2U9c3RyX3RyaW0odWNkX2ljZF8xMF8xMTNfY2F1c2VfbGlzdCksDQogICAgICBkZWF0aHM9YXMuaW50ZWdlcihkZWF0aHMpLA0KICAgICAgcG9wPWFzLmludGVnZXIocG9wdWxhdGlvbiksDQogICAgICBjcnVkZV9yYXRlPWFzLm51bWVyaWMoY3J1ZGVfcmF0ZSksDQogICAgICByYXRlPWRlYXRocy9wb3AqMWU2LCAjIHBlciBtaWxsaW9uDQogICAgICByYXRlX3JvdW5kZWQ9cm91bmQocmF0ZSwxKSwgDQogICAgICBwZXJpb2Q9cGVyaW9kDQogICAgKSAlPiUNCiAgICBmaWx0ZXIoDQogICAgICAhaXMubmEoZGVhdGhzKSwNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsJ14jJykgIyBvbmx5IHJldHVybiAncmFua2FibGUnIGl0ZW1zIGZyb20gdGhlIDExMyBjYXVzZSBsaXN0DQogICAgKQ0KfQ0KDQoNCg0KZmlsZV9jbz0nbGVhZGluZ19jYXVzZV9jb21wLzIwMjBfd2tfMTAgdGhyb3VnaCAyMDIyX3drXzE3IG9ubHkgY292aWQtMTkudHh0Jw0KbGNfY292aWRfb25seT1yZWFkQ0RDUmF0ZXMoZmlsZV9jbywnTU1XUiB3ZWVrczogMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnKQ0KDQoNCmZpbGVfY2w9J2xlYWRpbmdfY2F1c2VfY29tcC8yMDE5X3drXzEwIHRocm91Z2ggMjAyMV93a18xNyBhbGwgMTEzIGNhdXNlIGxpc3QudHh0Jw0KbGNfY2F1c2VsaXN0PXJlYWRDRENSYXRlcyhmaWxlX2NsLCdNTVdSIHdlZWtzOiAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycpDQoNCg0KIyBjYWxjdWxhdGUgYW5udWFsaXplZCBhZGp1c3RtZW50IGZvciBDRENzIGNydWRlIHJhdGVzIGFuZC9vciB0aGUgcG9wdWxhdGlvbiAoZXhwb3N1cmVzKQ0KYWN0dWFsX3dlZWtzPTExMw0KcG9zc2libGVfd2Vla3M9KDMqNTIpKzEgIyAxNTcgYi9jIDIwMjAgaGFzIGEgbGVhcCB3ZWVrICYgaXQncyBpbmNsdWRlZCBpbiBib3RoIGRlbm9taW5hdG9ycw0KYW5udWFsaXplZF9hZGo9cG9zc2libGVfd2Vla3MvYWN0dWFsX3dlZWtzDQoNCg0KbGNfY29tYj1iaW5kX3Jvd3MobGNfY292aWRfb25seSxsY19jYXVzZWxpc3QpICU+JQ0KICBmaWx0ZXIoDQogICAgIyByZW1vdmUgY292aWQtMTkgaXRlbSBmcm9tIHRoZSBwZXJpb2Qgc3RhcnRpbmcgaW4gMjAxOQ0KICAgICEoIHN0cl9kZXRlY3QocGVyaW9kLCcyMDE5JykgJiBzdHJfZGV0ZWN0KGNhdXNlLCdDT1ZJRCcpICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIGFnZV9vbmx5PXN0cl90cmltKHN0cl9yZW1vdmUoYWdlX2dyb3VwLCJ5ZWFycz8iKSksDQogICAgbGFzdF9hZ2U9Y2FzZV93aGVuKA0KICAgICAgYWdlX29ubHkgPT0gJzwgMScgfiBhcy5pbnRlZ2VyKDApLA0KICAgICAgYWdlX29ubHkgPT0gJzEwMCsnIH4gYXMuaW50ZWdlcigxMDApLA0KICAgICAgVFJVRSB+IGFzLmludGVnZXIoc3RyX2V4dHJhY3QoYWdlX29ubHksJ1xcZCskJykpICAgICAgICAgICAgDQogICAgKSwNCiAgICBhZ2VfZ3JvdXA9cmVvcmRlcihhZ2VfZ3JvdXAsbGFzdF9hZ2UpLA0KICAgIGFnZV9vbmx5PXJlb3JkZXIoYWdlX29ubHksbGFzdF9hZ2UpLA0KDQogICAgDQogICAgIyBwcmV0dGllciBuYW1lcw0KICAgIGNhdXNlX3NpbXA9Y2FzZV93aGVuKA0KICAgICAgc3RyX2RldGVjdChjYXVzZSwiI0Nvbmdlbml0YWwgbWFsZm9ybWF0aW9ucyIpIH4gJ0Nvbmdlbml0YWwgQW5vbWFsaWVzJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsIiNBY2NpZGVudHMiKSB+ICdVbmludGVudGlvbmFsIEluanVyeScsDQogICAgICBzdHJfZGV0ZWN0KGNhdXNlLCIjQXNzYXVsdCIpIH4gJ0hvbWljaWRlJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsIiNJbnRlbnRpb25hbCBzZWxmLWhhcm0iKSB+ICdTdWljaWRlJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsImJlbmlnbiBuZW9wbGFzbXMiKSB+ICdCZW5pZ24gTmVvcGxhc21zJywNCiAgICAgIFQgfiBzdHJfcmVtb3ZlX2FsbChzdHJfcmVtb3ZlKGNhdXNlLCIjIiksIlxcKC4qXFwpIikNCiAgICApLA0KICAgIGNhdXNlX3NpbXA9c3RyX3RyaW0oY2F1c2Vfc2ltcCkNCiAgICANCiAgKSAlPiUNCiAgYXJyYW5nZShhZ2VfZ3JvdXAscmF0ZSxjYXVzZSkgJT4lDQogIGdyb3VwX2J5KGFnZV9ncm91cCkgJT4lDQogIG11dGF0ZSgNCiAgICByYW5rPXJhbmsoLXJhdGUsdGllcy5tZXRob2QgPSdmaXJzdCcpLA0KICAgIHJhdGVfYW5udWFsaXplZD1yb3VuZChyYXRlKmFubnVhbGl6ZWRfYWRqLDEpLA0KICAgIGNsYWI9c3ByaW50ZigiJXNcbiUwLjFmIixzdHJfd3JhcChjYXVzZV9zaW1wLDI1KSxyYXRlX2FubnVhbGl6ZWQpDQogICkgJT4lDQogIHVuZ3JvdXAoKSANCg0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQoNCmxjX2NvbWIgJT4lDQogIGZpbHRlcigNCiAgICByYW5rIDw9IDEwLA0KICAgIGxhc3RfYWdlIDw9IDE5LA0KICAgIFQNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHR5cGU9aWZlbHNlKHN0cl9kZXRlY3QoY2F1c2UsJ0NPVklEJyksJ0NPVklEJywnT3RoZXJzJykNCiAgKSAlPiUNCiAgZ2dwbG90KGFlcyhhZ2VfZ3JvdXAscmFuayxmaWxsPXJhdGUpKSArDQogICAgZ2VvbV90aWxlKGFscGhhPTAuMyxjb2xvcj0nYmxhY2snLGRhdGE9fmZpbHRlciguLHR5cGUhPSdDT1ZJRCcpKSArDQogICAgZ2VvbV90aWxlKGNvbG9yPSdyZWQnLGFscGhhPTAuMyxzaXplPTEsZGF0YT1+ZmlsdGVyKC4sdHlwZT09J0NPVklEJykpICsgIA0KICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19jKHRyYW5zPSdsb2cxMCcpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPWNsYWIpLHNpemU9NCkgKw0KICAgIHNjYWxlX3lfcmV2ZXJzZShicmVha3M9c2VxKDEsNDAsMSkpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKHBvc2l0aW9uPSd0b3AnKSArDQogICAgY29vcmRfY2FydGVzaWFuKGV4cGFuZD1GKSArDQogICAgdGhlbWVfaXBzdW0oKSArDQogICAgdGhlbWUoDQogICAgICBsZWdlbmQucG9zaXRpb249J25vbmUnLA0KICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCkNCiAgICApICsNCiAgICBsYWJzKA0KICAgICAgeD1OVUxMLA0KICAgICAgeT0nUmFuayB3aXRoaW4gYWdlIGdyb3VwJywNCiAgICAgIHRpdGxlPSdMZWFkaW5nIGNhdXNlcyBvZiBkZWF0aCBmb3IgY2hpbGRyZW46IGNvdmlkLTE5IHNpbmNlIHRoZSBzdGFydCBvZiB0aGUgcGFuZGVtaWNcbnZlcnN1cyBvdGhlciBjYXVzZXMgc2hpZnRlZCBiYWNrIG9uZSBNTVdSIHllYXIuJywNCiAgICAgIHN1YnRpdGxlPScodGhlIG51bWJlciBiZWxvdyBpcyBhbm51YWxpemVkIGRlYXRocyBwZXIgbWlsbGlvbiknLA0KICAgICAgY2FwdGlvbj1wYXN0ZSgNCiAgICAgICAgJ3NvdXJjZTogQ0RDIFdPTkRFUiwgUHJvdmlzaW9uYWwgTW9ydGFsaXR5IFN0YXRpc3RpY3MsIDIwMTggdGhyb3VnaCBMYXN0IE1vbnRoIFJlc3VsdHMnLA0KICAgICAgICAnVW5kZXJseWluZyBjYXVzZXMsIGFsbCByYW5rYWJsZSBpdGVtcyBmcm9tIDExMyBjYXVzZSBsaXN0LCByYW5rZWQgYnkgcmF0ZXMnLA0KICAgICAgICAnQ292aWQtMTk6IE1NV1Igd2Vla3MgMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnLA0KICAgICAgICAnT3RoZXIgY2F1c2VzOiBNTVdSIHdlZWtzLCAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycsDQogICAgICAgICdTYW1lIG51bWJlciBvZiB3ZWVrcyBhbmQgc2FtZSBzZWFzb25zIGNvdmVyZWQnLA0KICAgICAgICBzZXA9J1xuJw0KICAgICAgKQ0KICAgICkNCg0KYGBgDQoNCg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFLHJlc3VsdHM9J2FzaXMnfQ0KDQoNCm5mb3JtYXRzPWZvcm1hdC5hcmdzID0gbGlzdChkZWNpbWFsLm1hcmsgPSAiLiIsIGJpZy5tYXJrID0gIiwiKQ0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHN0cl9kZXRlY3QoY2F1c2UsJ0NPVklEJyksDQogICAgbGFzdF9hZ2UgPCA4NSAjIGRvbnQgaGF2ZSBwb3B1bGF0aW9uIGRhdGEgdG8gc29ydCA4NSsgYXMgcmF0ZXMsIHRobyBkZWF0aHMgd2lsbCB3b3JrDQogICkgJT4lDQogIHRyYW5zbXV0ZSgNCiAgICBhZ2VfZ3JvdXAsDQogICAgcmFuaywNCiAgICBkZWF0aHMsDQogICAgYHBvcHVsYXRpb25gPXJvdW5kKHBvcCksICAgIA0KICAgICNgcG9wdWxhdGlvbiAoMTAwaylgPXJvdW5kKHBvcC8xZTUpLA0KICAgIGByYXRlIChhcyBxdW90ZWQpYD1yYXRlX3JvdW5kZWQsDQogICAgYHJhdGUgKGFubnVhbGl6ZWQpYD1yYXRlX2FubnVhbGl6ZWQNCiAgKSAlPiUgDQogIGthYmxlKGNhcHRpb249J0NPVklELTE5IGRlYXRocyBhbmQgcmFuayB3aXRoaW4gYWdlIGdyb3VwJyxmb3JtYXQuYXJncyA9IG5mb3JtYXRzKQ0KDQpgYGANCg0KDQoNCg0KV2hpbGUgd2UgYXJlIGF0IGl0LCB3ZSBjYW4gYWxzbyByZXBvcnQgdGhlc2UgcmF0ZXMgZm9yIGFkdWx0cy4NCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCg0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHJhbmsgPD0gMTAsDQogICAgbGFzdF9hZ2UgPiAxOSwNCiAgICBsYXN0X2FnZSA8PSA1NCwNCiAgICBUDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICB0eXBlPWlmZWxzZShzdHJfZGV0ZWN0KGNhdXNlLCdDT1ZJRCcpLCdDT1ZJRCcsJ090aGVycycpDQogICkgJT4lDQogIGdncGxvdChhZXMoYWdlX2dyb3VwLHJhbmssZmlsbD1yYXRlKSkgKw0KICAgIGdlb21fdGlsZShhbHBoYT0wLjMsY29sb3I9J2JsYWNrJyxkYXRhPX5maWx0ZXIoLix0eXBlIT0nQ09WSUQnKSkgKw0KICAgIGdlb21fdGlsZShjb2xvcj0ncmVkJyxhbHBoYT0wLjMsc2l6ZT0xLGRhdGE9fmZpbHRlciguLHR5cGU9PSdDT1ZJRCcpKSArICANCiAgICBzY2FsZV9maWxsX3ZpcmlkaXNfYyh0cmFucz0nbG9nMTAnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1jbGFiKSxzaXplPTMpICsNCiAgICBzY2FsZV95X3JldmVyc2UoYnJlYWtzPXNlcSgxLDQwLDEpKSArDQogICAgc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbj0ndG9wJykgKw0KICAgIGNvb3JkX2NhcnRlc2lhbihleHBhbmQ9RikgKw0KICAgIHRoZW1lX2lwc3VtKCkgKw0KICAgIHRoZW1lKA0KICAgICAgbGVnZW5kLnBvc2l0aW9uPSdub25lJywNCiAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpDQogICAgKSArDQogICAgbGFicygNCiAgICAgIHg9TlVMTCwNCiAgICAgIHk9J1Jhbmsgd2l0aGluIGFnZSBncm91cCcsDQogICAgICB0aXRsZT0nTGVhZGluZyBjYXVzZXMgb2YgZGVhdGg6IGNvdmlkLTE5IHNpbmNlIHRoZSBzdGFydCBvZiB0aGUgcGFuZGVtaWNcbnZlcnN1cyBvdGhlciBjYXVzZXMgc2hpZnRlZCBiYWNrIG9uZSBNTVdSIHllYXIuJywNCiAgICAgIHN1YnRpdGxlPScodGhlIG51bWJlciBiZWxvdyBpcyBhbm51YWxpemVkIGRlYXRocyBwZXIgbWlsbGlvbiknLA0KICAgICAgY2FwdGlvbj1wYXN0ZSgNCiAgICAgICAgJ3NvdXJjZTogQ0RDIFdPTkRFUiwgUHJvdmlzaW9uYWwgTW9ydGFsaXR5IFN0YXRpc3RpY3MsIDIwMTggdGhyb3VnaCBMYXN0IE1vbnRoIFJlc3VsdHMnLA0KICAgICAgICAnVW5kZXJseWluZyBjYXVzZXMsIGFsbCByYW5rYWJsZSBpdGVtcyBmcm9tIDExMyBjYXVzZSBsaXN0LCByYW5rZWQgYnkgcmF0ZXMnLA0KICAgICAgICAnQ292aWQtMTk6IE1NV1Igd2Vla3MgMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnLA0KICAgICAgICAnT3RoZXIgY2F1c2VzOiBNTVdSIHdlZWtzLCAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycsDQogICAgICAgICdTYW1lIG51bWJlciBvZiB3ZWVrcyBhbmQgc2FtZSBzZWFzb25zIGNvdmVyZWQnLA0KICAgICAgICBzZXA9J1xuJw0KICAgICAgKQ0KICAgICkNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHJhbmsgPD0gMTAsDQogICAgbGFzdF9hZ2UgPj0gNTUsDQogICAgbGFzdF9hZ2UgPD0gODQsDQogICAgVA0KICApICU+JQ0KICBtdXRhdGUoDQogICAgdHlwZT1pZmVsc2Uoc3RyX2RldGVjdChjYXVzZSwnQ09WSUQnKSwnQ09WSUQnLCdPdGhlcnMnKQ0KICApICU+JQ0KICBnZ3Bsb3QoYWVzKGFnZV9ncm91cCxyYW5rLGZpbGw9cmF0ZSkpICsNCiAgICBnZW9tX3RpbGUoYWxwaGE9MC4zLGNvbG9yPSdibGFjaycsZGF0YT1+ZmlsdGVyKC4sdHlwZSE9J0NPVklEJykpICsNCiAgICBnZW9tX3RpbGUoY29sb3I9J3JlZCcsYWxwaGE9MC4zLHNpemU9MSxkYXRhPX5maWx0ZXIoLix0eXBlPT0nQ09WSUQnKSkgKyAgDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2ModHJhbnM9J2xvZzEwJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9Y2xhYiksc2l6ZT0zKSArDQogICAgc2NhbGVfeV9yZXZlcnNlKGJyZWFrcz1zZXEoMSw0MCwxKSkgKw0KICAgIHNjYWxlX3hfZGlzY3JldGUocG9zaXRpb249J3RvcCcpICsNCiAgICBjb29yZF9jYXJ0ZXNpYW4oZXhwYW5kPUYpICsNCiAgICB0aGVtZV9pcHN1bSgpICsNCiAgICB0aGVtZSgNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScsDQogICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKQ0KICAgICkgKw0KICAgIGxhYnMoDQogICAgICB4PU5VTEwsDQogICAgICB5PSdSYW5rIHdpdGhpbiBhZ2UgZ3JvdXAnLA0KICAgICAgdGl0bGU9J0xlYWRpbmcgY2F1c2VzIG9mIGRlYXRoOiBjb3ZpZC0xOSBzaW5jZSB0aGUgc3RhcnQgb2YgdGhlIHBhbmRlbWljXG52ZXJzdXMgb3RoZXIgY2F1c2VzIHNoaWZ0ZWQgYmFjayBvbmUgTU1XUiB5ZWFyLicsDQogICAgICBzdWJ0aXRsZT0nKHRoZSBudW1iZXIgYmVsb3cgaXMgYW5udWFsaXplZCBkZWF0aHMgcGVyIG1pbGxpb24pJywNCiAgICAgIGNhcHRpb249cGFzdGUoDQogICAgICAgICdzb3VyY2U6IENEQyBXT05ERVIsIFByb3Zpc2lvbmFsIE1vcnRhbGl0eSBTdGF0aXN0aWNzLCAyMDE4IHRocm91Z2ggTGFzdCBNb250aCBSZXN1bHRzJywNCiAgICAgICAgJ1VuZGVybHlpbmcgY2F1c2VzLCBhbGwgcmFua2FibGUgaXRlbXMgZnJvbSAxMTMgY2F1c2UgbGlzdCwgcmFua2VkIGJ5IHJhdGVzJywNCiAgICAgICAgJ0NvdmlkLTE5OiBNTVdSIHdlZWtzIDIwMjAvMTAgdGhyb3VnaCAyMDIyLzE3JywNCiAgICAgICAgJ090aGVyIGNhdXNlczogTU1XUiB3ZWVrcywgMjAxOS8xMCB0aHJvdWdoIDIwMjEvMTcnLA0KICAgICAgICAnU2FtZSBudW1iZXIgb2Ygd2Vla3MgYW5kIHNhbWUgc2Vhc29ucyBjb3ZlcmVkJywNCiAgICAgICAgc2VwPSdcbicNCiAgICAgICkNCiAgICApDQpgYGANCg0K