Heat Flux Data
# Make a table of the cmip info wide by variable with indicator information about whether or not there is
# data for that variable.
cmip_individual %>%
select(year, model, ensemble, variable, experiment) %>%
full_join(heat_flux %>% select(year, model, ensemble, experiment, variable2=variable),
by = c("year", "model", "ensemble", "experiment")) %>%
gather(vari, name, variable, variable2) %>%
mutate(yes = TRUE) %>%
select(model, ensemble, experiment, name, yes) %>%
na.omit %>%
distinct %>%
spread(name, yes) ->
wide_variables
How many models do we have temp / heat flux data for?
length(unique(wide_variables$model))
[1] 35
So it looks like we have both tas and heat flux data for 35 models. However I am not sure if the historical data will constrain heat flux like we think is will. We are also concerned if the heat flux is too high during the historical period for Hector to be able to emulate.
What do the values look like?
The mean and sd of of the heat flux data for each scenario at 1850, 1900, 1950, and 2010, 2050, 2100.
heat_flux %>%
filter(year %in% c(1850, 1900, 1950, 2100, 2010, 2050, 2100)) %>%
group_by(experiment, year) %>%
summarise(mean = mean(value),
sd = sd(value)) %>%
na.omit %>%
arrange(experiment, year) %>%
kable(digits = 3) %>%
kable_styling("striped", full_width = F) %>%
collapse_rows(columns = 1)
| experiment |
year |
mean |
sd |
| historical |
1850 |
-1.875 |
23.387 |
| 1900 |
1.183 |
0.504 |
| 1950 |
1.304 |
0.608 |
| rcp26 |
2010 |
1.945 |
0.761 |
| 2050 |
2.062 |
0.867 |
| 2100 |
1.417 |
0.714 |
| rcp45 |
2010 |
1.975 |
1.307 |
| 2050 |
2.550 |
1.426 |
| 2100 |
2.334 |
1.383 |
| rcp60 |
2010 |
2.159 |
0.581 |
| 2050 |
2.835 |
0.717 |
| 2100 |
3.204 |
0.734 |
| rcp85 |
2010 |
1.631 |
1.397 |
| 2050 |
2.831 |
1.347 |
| 2100 |
3.997 |
1.678 |
Right off the bat I am surprised to see that the sd is so large in the historical period, I think that means that there is most likely some unrealistic values sneaking in there.
heat_flux %>%
ggplot(aes(year, value, color = model)) +
geom_point() +
facet_wrap('experiment', scales = 'free') +
theme(legend.position = 'none')

Right off the bat it looks like there are some questionable values for the historical period, rcp26, rcp45, and rcp85. I wonder if the points that are outlines in the historical and rcp26 are artifacts of numerical instability or if time series that underestimate the heat flux in rcp45 and rcp85 are because some variable is missing, but I thought that my prepossessing code would have taken care of that.
What models have outliers in the historical period?
Let’s define the outlines as heat flux values with a magnitude greater than 10.
heat_flux %>%
filter(experiment == 'historical') %>%
filter(abs(value) > 10) %>%
pull(model) %>%
unique() ->
hist_outliers
If we remove these models from do the historical runs look good?
heat_flux %>%
filter(!model %in% hist_outliers & experiment == 'historical') %>%
ggplot(aes(year, value, color = model, group = interaction(model, ensemble))) +
geom_line(alpha = 0.3) +
labs(y = 'w/m2') ->
hist_plot
hist_plot

Yes I think so! I think that the models look pretty consistent in noise and trend.
What about the modes that have outlier values? Are they single years or for multiple years?
heat_flux %>%
filter(model %in% hist_outliers & experiment == 'historical') %>%
ggplot(aes(year, value, color = model, group = interaction(model, ensemble))) +
geom_point(alpha = 0.3) +
labs(y = 'w/m2') ->
hist_outlier_plot
hist_outlier_plot

How many years are outlines? for each ensemble / model?
hist_outlier_plot$data %>%
filter(abs(value) >= 10) %>%
group_by(experiment, ensemble, model) %>%
summarise(n_outlier = n_distinct(year)) %>%
kable(digits = 3) %>%
kable_styling("striped", full_width = F) %>%
collapse_rows(columns = 1:2)
| experiment |
ensemble |
model |
n_outlier |
| historical |
r2i1p1 |
CCSM4 |
3 |
| MRI-CGCM3 |
3 |
| r3i1p1 |
CCSM4 |
3 |
| r5i1p1 |
CCSM4 |
6 |
If the outlines were removed what would the time series be more realistic?
hist_outlier_plot +
coord_cartesian(ylim = c(-10,10))

ggplot() +
geom_line(data = hist_plot$data,
aes(year, value, color = 'non outlier models', group = interaction(model, ensemble)),
alpha = 0.2) +
geom_point(data = hist_outlier_plot$data %>%
filter(abs(value) < 10),
aes(year, value, color = model, group = interaction(model, ensemble))) +
labs(y = 'W/m2')

It looks like there are a few year for CCSM4 and MRI-CGCM3 that fall outside of the CMIP5 range but they don’t seem too drastic. Do we want to exclude the years with the heat Flux values greater than 10 and then keep the rest of the time series? Or do we exclude the heat flux data from our analysis? I thought that may be they had to do with the the models missing data at the end / start of runs or how they save data (some times modeling groups can write out multiple files for a single experiment every 5 years or so) but that was not the case few these models.
What models have outliers in the rcp26?
heat_flux %>%
filter(experiment == 'rcp26' & abs(value) >= 10) %>%
pull(model) %>%
unique() ->
outlier_rcp26
outlier_rcp26
[1] "CCSM4" "MRI-CGCM3"
It looks like the same models have outlines in rcp26.
What models have outliers in rcp 85?
heat_flux %>%
filter(experiment == 'rcp85' & value > 10) %>%
pull(model) %>%
unique() ->
outliers_rcp85;
outliers_rcp85
[1] "CESM1-BGC"
heat_flux %>%
filter(experiment == 'rcp85' & model == outliers_rcp85) %>%
ggplot(aes(year, value, color = model)) +
geom_line(data = heat_flux %>%
filter(experiment == 'rcp85' & model != outliers_rcp85),
aes(year, value, color = 'other models', group = interaction(model, ensemble)), alpha = 0.3) +
geom_point() +
labs(y = 'w/m2') +
coord_cartesian(xlim = c(2006, 2100))

Well it loos like from 2990 to 2995 the CESM1-BGC has abnormally high heat flux values but reasonable values for the other years. Once again what do we do when there are only some of the years with suspicious data?
Below Expected Time Series
Both the rcp45 and rcp85 experiments have time series with values that are below.
heat_flux %>%
filter(experiment %in% c('rcp45', 'rcp85')) %>%
filter(value < -1) %>%
pull(model) %>%
unique()
[1] "inmcm4"
So it looks like the same model is the has unexpectedly low heat flux values. I wonder what could be causing it. I checked the errata (https://cmip.llnl.gov/cmip5/errata/cmip5errata.html) to see if inmcm4 had reported any problems with the data we used. While it did appear multiple times in the errata it wasn’t for any of the variables we used to calculate the heat flux.
LS0tCnRpdGxlOiAiV2hhdCdzIFVwIFdpdGggdGhlIEhlYXQgRmx1eCBEYXRhPyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgT2JqZWN0aXZlIAoKV0UgRklOQUxMWSBIQVZFIEhFQVQgRkxVWCBEQVRBIChJIGFtIGV4dHJlbWVseSBleGNpdGVkIGJ5IHRoaXMgYmVjYXVzZSBkb3dubG9hZGluZyBkYXRhIGlzIG5vIGZ1bikuIEJ1dCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBkYXRhIGlzIHJlYXNvbmFibGUgYW5kIGNvbmZpcm0gdGhhdCB3ZSBoYXZlIGVub3VnaCBoZWF0IGZsdXggZGF0YSB0byBjb250aW51ZSB3aXRoIHRoZSBoZWN0b3IgY2FsaWJyYXRpb24gcHJvamVjdChzKS4KCmBgYHtyLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShoZWN0b3JjYWwpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5cikKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKQkFTRV9ESVIgIDwtICAiL1VzZXJzL2RvcmgwMTIvRG9jdW1lbnRzLzIwMTkvaGVjdG9yY2FsIgpJTlBVVF9ESVIgPC0gZmlsZS5wYXRoKEJBU0VfRElSLCAnZGF0YS1yYXcnKQoKaGVhdF9mbHV4IDwtIHJlYWQuY3N2KGZpbGUucGF0aChJTlBVVF9ESVIsICdDTUlQNV9oZWF0X2ZsdXguY3N2JyksIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkgJT4lICAKICAgIGZpbHRlcihtb2RlbCAlaW4lIGNtaXBfaW5kaXZpZHVhbCRtb2RlbCkKYGBgCgojIyBIZWF0IEZsdXggRGF0YSAKCmBgYHtyfQojIE1ha2UgYSB0YWJsZSBvZiB0aGUgY21pcCBpbmZvIHdpZGUgYnkgdmFyaWFibGUgd2l0aCBpbmRpY2F0b3IgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBvciBub3QgdGhlcmUgaXMgCiMgZGF0YSBmb3IgdGhhdCB2YXJpYWJsZS4KY21pcF9pbmRpdmlkdWFsICU+JSAKICAgIHNlbGVjdCh5ZWFyLCBtb2RlbCwgZW5zZW1ibGUsIHZhcmlhYmxlLCBleHBlcmltZW50KSAlPiUgCiAgICBmdWxsX2pvaW4oaGVhdF9mbHV4ICU+JSAgc2VsZWN0KHllYXIsIG1vZGVsLCBlbnNlbWJsZSwgZXhwZXJpbWVudCwgdmFyaWFibGUyPXZhcmlhYmxlKSwgCiAgICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwgIm1vZGVsIiwgImVuc2VtYmxlIiwgImV4cGVyaW1lbnQiKSkgJT4lIAogICAgZ2F0aGVyKHZhcmksIG5hbWUsIHZhcmlhYmxlLCB2YXJpYWJsZTIpICU+JSAKICAgIG11dGF0ZSh5ZXMgPSBUUlVFKSAlPiUgCiAgICBzZWxlY3QobW9kZWwsIGVuc2VtYmxlLCBleHBlcmltZW50LCBuYW1lLCB5ZXMpICU+JSAgCiAgICBuYS5vbWl0ICU+JSAKICAgIGRpc3RpbmN0ICU+JSAKICAgIHNwcmVhZChuYW1lLCB5ZXMpIC0+IAogICAgd2lkZV92YXJpYWJsZXMKYGBgCgpIb3cgbWFueSBtb2RlbHMgZG8gd2UgaGF2ZSB0ZW1wIC8gaGVhdCBmbHV4IGRhdGEgZm9yPyAKCmBgYHtyfQpsZW5ndGgodW5pcXVlKHdpZGVfdmFyaWFibGVzJG1vZGVsKSkKYGBgCgpTbyBpdCBsb29rcyBsaWtlIHdlIGhhdmUgYm90aCB0YXMgYW5kIGhlYXQgZmx1eCBkYXRhIGZvciAzNSBtb2RlbHMuIEhvd2V2ZXIgSSBhbSBub3Qgc3VyZSBpZiB0aGUgaGlzdG9yaWNhbCBkYXRhIHdpbGwgY29uc3RyYWluIGhlYXQgZmx1eCBsaWtlIHdlIHRoaW5rIGlzIHdpbGwuIFdlIGFyZSBhbHNvIGNvbmNlcm5lZCBpZiB0aGUgaGVhdCBmbHV4IGlzIHRvbyBoaWdoIGR1cmluZyB0aGUgaGlzdG9yaWNhbCBwZXJpb2QgZm9yIEhlY3RvciB0byBiZSBhYmxlIHRvIGVtdWxhdGUuIAoKCgojIyBXaGF0IGRvIHRoZSB2YWx1ZXMgbG9vayBsaWtlPyAKClRoZSBtZWFuIGFuZCBzZCBvZiBvZiB0aGUgaGVhdCBmbHV4IGRhdGEgZm9yIGVhY2ggc2NlbmFyaW8gYXQgMTg1MCwgMTkwMCwgMTk1MCwgYW5kIDIwMTAsIDIwNTAsIDIxMDAuCgpgYGB7cn0KCmhlYXRfZmx1eCAlPiUgCiAgICBmaWx0ZXIoeWVhciAlaW4lIGMoMTg1MCwgMTkwMCwgMTk1MCwgMjEwMCwgMjAxMCwgMjA1MCwgMjEwMCkpICU+JSAKICAgIGdyb3VwX2J5KGV4cGVyaW1lbnQsIHllYXIpICU+JSAKICAgIHN1bW1hcmlzZShtZWFuID0gbWVhbih2YWx1ZSksIAogICAgICAgICAgICAgIHNkID0gc2QodmFsdWUpKSAgJT4lIAogICAgbmEub21pdCAlPiUgCiAgICBhcnJhbmdlKGV4cGVyaW1lbnQsIHllYXIpICU+JSAgCiAgICBrYWJsZShkaWdpdHMgPSAzKSAgJT4lIAogICAga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUKICAgIGNvbGxhcHNlX3Jvd3MoY29sdW1ucyA9IDEpCmBgYAoKUmlnaHQgb2ZmIHRoZSBiYXQgSSBhbSBzdXJwcmlzZWQgdG8gc2VlIHRoYXQgdGhlIHNkIGlzIHNvIGxhcmdlIGluIHRoZSBoaXN0b3JpY2FsIHBlcmlvZCwgSSB0aGluayB0aGF0IG1lYW5zIHRoYXQgdGhlcmUgaXMgbW9zdCBsaWtlbHkgc29tZSB1bnJlYWxpc3RpYyB2YWx1ZXMgc25lYWtpbmcgaW4gdGhlcmUuIAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgCiAgICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IG1vZGVsKSkgKyAKICAgIGdlb21fcG9pbnQoKSArIAogICAgZmFjZXRfd3JhcCgnZXhwZXJpbWVudCcsIHNjYWxlcyA9ICdmcmVlJykgKyAKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykKYGBgCgpSaWdodCBvZmYgdGhlIGJhdCBpdCBsb29rcyBsaWtlIHRoZXJlIGFyZSBzb21lIHF1ZXN0aW9uYWJsZSB2YWx1ZXMgZm9yIHRoZSBoaXN0b3JpY2FsIHBlcmlvZCwgcmNwMjYsIHJjcDQ1LCBhbmQgcmNwODUuIEkgd29uZGVyIGlmIHRoZSBwb2ludHMgdGhhdCBhcmUgb3V0bGluZXMgaW4gdGhlIGhpc3RvcmljYWwgYW5kIHJjcDI2IGFyZSBhcnRpZmFjdHMgb2YgbnVtZXJpY2FsIGluc3RhYmlsaXR5IG9yIGlmIHRpbWUgc2VyaWVzIHRoYXQgdW5kZXJlc3RpbWF0ZSB0aGUgaGVhdCBmbHV4IGluIHJjcDQ1IGFuZCByY3A4NSBhcmUgYmVjYXVzZSBzb21lIHZhcmlhYmxlIGlzIG1pc3NpbmcsIGJ1dCBJIHRob3VnaHQgdGhhdCBteSBwcmVwb3NzZXNzaW5nIGNvZGUgd291bGQgaGF2ZSB0YWtlbiBjYXJlIG9mIHRoYXQuIAoKCgojIyMgV2hhdCBtb2RlbHMgaGF2ZSBvdXRsaWVycyBpbiB0aGUgaGlzdG9yaWNhbCBwZXJpb2Q/IAoKTGV0J3MgZGVmaW5lIHRoZSBvdXRsaW5lcyBhcyBoZWF0IGZsdXggdmFsdWVzIHdpdGggYSBtYWduaXR1ZGUgZ3JlYXRlciB0aGFuIDEwLiAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lCiAgICBmaWx0ZXIoZXhwZXJpbWVudCA9PSAnaGlzdG9yaWNhbCcpICU+JSAgCiAgICBmaWx0ZXIoYWJzKHZhbHVlKSA+IDEwKSAlPiUgIAogICAgcHVsbChtb2RlbCkgJT4lCiAgICB1bmlxdWUoKSAtPiAKICAgIGhpc3Rfb3V0bGllcnMKYGBgCgpJZiB3ZSByZW1vdmUgdGhlc2UgbW9kZWxzIGZyb20gZG8gdGhlIGhpc3RvcmljYWwgcnVucyBsb29rIGdvb2Q/IAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgIAogICAgZmlsdGVyKCFtb2RlbCAlaW4lIGhpc3Rfb3V0bGllcnMgJiBleHBlcmltZW50ID09ICdoaXN0b3JpY2FsJykgJT4lIAogICAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBtb2RlbCwgZ3JvdXAgPSBpbnRlcmFjdGlvbihtb2RlbCwgZW5zZW1ibGUpKSkgKyAKICAgIGdlb21fbGluZShhbHBoYSA9IDAuMykgKyAKICAgIGxhYnMoeSA9ICd3L20yJykgIC0+IAogICAgaGlzdF9wbG90Cmhpc3RfcGxvdApgYGAKClllcyBJIHRoaW5rIHNvISBJIHRoaW5rIHRoYXQgdGhlIG1vZGVscyBsb29rIHByZXR0eSBjb25zaXN0ZW50IGluIG5vaXNlIGFuZCB0cmVuZC4gCgo8YnI+CgpXaGF0IGFib3V0IHRoZSBtb2RlcyB0aGF0IGhhdmUgb3V0bGllciB2YWx1ZXM/IEFyZSB0aGV5IHNpbmdsZSB5ZWFycyBvciBmb3IgbXVsdGlwbGUgeWVhcnM/IAoKYGBge3J9CmhlYXRfZmx1eCAlPiUgCiAgICBmaWx0ZXIobW9kZWwgJWluJSBoaXN0X291dGxpZXJzICYgZXhwZXJpbWVudCA9PSAnaGlzdG9yaWNhbCcpICU+JSAKICAgIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gbW9kZWwsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArIAogICAgbGFicyh5ID0gJ3cvbTInKSAtPiAKICAgIGhpc3Rfb3V0bGllcl9wbG90Cmhpc3Rfb3V0bGllcl9wbG90CmBgYAoKSG93IG1hbnkgeWVhcnMgYXJlIG91dGxpbmVzPyBmb3IgZWFjaCBlbnNlbWJsZSAvIG1vZGVsPyAKCmBgYHtyfQpoaXN0X291dGxpZXJfcGxvdCRkYXRhICU+JQogICAgZmlsdGVyKGFicyh2YWx1ZSkgPj0gMTApICU+JSAKICAgIGdyb3VwX2J5KGV4cGVyaW1lbnQsIGVuc2VtYmxlLCBtb2RlbCkgJT4lIAogICAgc3VtbWFyaXNlKG5fb3V0bGllciA9IG5fZGlzdGluY3QoeWVhcikpICU+JSAKICAgIGthYmxlKGRpZ2l0cyA9IDMpICAlPiUgCiAgICBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JQogICAgY29sbGFwc2Vfcm93cyhjb2x1bW5zID0gMToyKQpgYGAKCgpJZiB0aGUgb3V0bGluZXMgd2VyZSByZW1vdmVkIHdoYXQgd291bGQgdGhlIHRpbWUgc2VyaWVzIGJlIG1vcmUgcmVhbGlzdGljPyAKCgpgYGB7cn0KaGlzdF9vdXRsaWVyX3Bsb3QgKyAKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtMTAsMTApKQogICAgCmdncGxvdCgpICsgCiAgICBnZW9tX2xpbmUoZGF0YSA9IGhpc3RfcGxvdCRkYXRhLCAKICAgICAgICAgICAgICBhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gJ25vbiBvdXRsaWVyIG1vZGVscycsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSksIAogICAgICAgICAgICAgIGFscGhhID0gMC4yKSArIAogICAgZ2VvbV9wb2ludChkYXRhID0gaGlzdF9vdXRsaWVyX3Bsb3QkZGF0YSAlPiUgCiAgICAgICAgICAgICAgICAgIGZpbHRlcihhYnModmFsdWUpIDwgMTApLCAKICAgICAgICAgICAgICBhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gbW9kZWwsIGdyb3VwID0gaW50ZXJhY3Rpb24obW9kZWwsIGVuc2VtYmxlKSkpICsgCiAgICBsYWJzKHkgPSAnVy9tMicpCmBgYAoKSXQgbG9va3MgbGlrZSB0aGVyZSBhcmUgYSBmZXcgeWVhciBmb3IgQ0NTTTQgYW5kIE1SSS1DR0NNMyB0aGF0IGZhbGwgb3V0c2lkZSBvZiB0aGUgQ01JUDUgcmFuZ2UgYnV0IHRoZXkgZG9uJ3Qgc2VlbSB0b28gZHJhc3RpYy4gRG8gd2Ugd2FudCB0byBleGNsdWRlIHRoZSB5ZWFycyB3aXRoIHRoZSBoZWF0IEZsdXggdmFsdWVzIGdyZWF0ZXIgdGhhbiAxMCBhbmQgdGhlbiBrZWVwIHRoZSByZXN0IG9mIHRoZSB0aW1lIHNlcmllcz8gT3IgZG8gd2UgZXhjbHVkZSB0aGUgaGVhdCBmbHV4IGRhdGEgZnJvbSBvdXIgYW5hbHlzaXM/IEkgdGhvdWdodCB0aGF0IG1heSBiZSB0aGV5IGhhZCB0byBkbyB3aXRoIHRoZSB0aGUgbW9kZWxzIG1pc3NpbmcgZGF0YSBhdCB0aGUgZW5kIC8gc3RhcnQgb2YgcnVucyBvciBob3cgdGhleSBzYXZlIGRhdGEgKHNvbWUgdGltZXMgbW9kZWxpbmcgZ3JvdXBzIGNhbiB3cml0ZSBvdXQgbXVsdGlwbGUgZmlsZXMgZm9yIGEgc2luZ2xlIGV4cGVyaW1lbnQgZXZlcnkgNSB5ZWFycyBvciBzbykgYnV0IHRoYXQgd2FzIG5vdCB0aGUgY2FzZSBmZXcgdGhlc2UgbW9kZWxzLiAKCjxicj4KCiMjIyBXaGF0IG1vZGVscyBoYXZlIG91dGxpZXJzIGluIHRoZSByY3AyNj8gCgoKYGBge3J9CmhlYXRfZmx1eCAlPiUKICAgIGZpbHRlcihleHBlcmltZW50ID09ICdyY3AyNicgJiBhYnModmFsdWUpID49IDEwKSAgJT4lICAKICAgIHB1bGwobW9kZWwpICU+JSAgCiAgICB1bmlxdWUoKSAtPiAKICAgIG91dGxpZXJfcmNwMjYKb3V0bGllcl9yY3AyNgpgYGAKCkl0IGxvb2tzIGxpa2UgdGhlIHNhbWUgbW9kZWxzIGhhdmUgb3V0bGluZXMgaW4gcmNwMjYuIAoKPGJyPgoKIyMjIFdoYXQgbW9kZWxzIGhhdmUgb3V0bGllcnMgaW4gcmNwIDg1PyAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lCiAgICBmaWx0ZXIoZXhwZXJpbWVudCA9PSAncmNwODUnICYgdmFsdWUgPiAxMCkgJT4lIAogICAgcHVsbChtb2RlbCkgJT4lIAogICAgdW5pcXVlKCkgLT4gCiAgICBvdXRsaWVyc19yY3A4NTsgCm91dGxpZXJzX3JjcDg1CmBgYAoKCmBgYHtyfQoKaGVhdF9mbHV4ICU+JSAKICAgIGZpbHRlcihleHBlcmltZW50ID09ICdyY3A4NScgJiBtb2RlbCA9PSBvdXRsaWVyc19yY3A4NSkgJT4lICAKICAgIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yICA9IG1vZGVsKSkgKyAKICAgIGdlb21fbGluZShkYXRhID0gaGVhdF9mbHV4ICU+JSAKICAgICAgICAgICAgICAgICAgZmlsdGVyKGV4cGVyaW1lbnQgPT0gJ3JjcDg1JyAmIG1vZGVsICE9IG91dGxpZXJzX3JjcDg1KSwgCiAgICAgICAgICAgICAgYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9ICdvdGhlciBtb2RlbHMnLCBncm91cCA9IGludGVyYWN0aW9uKG1vZGVsLCBlbnNlbWJsZSkpLCBhbHBoYSA9IDAuMykgKyAKICAgIGdlb21fcG9pbnQoKSArIAogICAgbGFicyh5ID0gJ3cvbTInKSArIAogICAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDIwMDYsIDIxMDApKQpgYGAKCldlbGwgaXQgbG9vcyBsaWtlIGZyb20gMjk5MCB0byAyOTk1IHRoZSBDRVNNMS1CR0MgaGFzIGFibm9ybWFsbHkgaGlnaCBoZWF0IGZsdXggdmFsdWVzIGJ1dCByZWFzb25hYmxlIHZhbHVlcyBmb3IgdGhlIG90aGVyIHllYXJzLiBPbmNlIGFnYWluIHdoYXQgZG8gd2UgZG8gd2hlbiB0aGVyZSBhcmUgb25seSBzb21lIG9mIHRoZSB5ZWFycyB3aXRoIHN1c3BpY2lvdXMgZGF0YT8KCiMjIyBCZWxvdyBFeHBlY3RlZCBUaW1lIFNlcmllcyAKCkJvdGggdGhlIHJjcDQ1IGFuZCByY3A4NSBleHBlcmltZW50cyBoYXZlIHRpbWUgc2VyaWVzIHdpdGggdmFsdWVzIHRoYXQgYXJlIGJlbG93LiAKCmBgYHtyfQpoZWF0X2ZsdXggJT4lIAogICAgZmlsdGVyKGV4cGVyaW1lbnQgJWluJSBjKCdyY3A0NScsICdyY3A4NScpKSAlPiUgCiAgICBmaWx0ZXIodmFsdWUgPCAtMSkgJT4lIAogICAgcHVsbChtb2RlbCkgJT4lICAKICAgIHVuaXF1ZSgpCmBgYAoKU28gaXQgbG9va3MgbGlrZSB0aGUgc2FtZSBtb2RlbCBpcyB0aGUgaGFzIHVuZXhwZWN0ZWRseSBsb3cgaGVhdCBmbHV4IHZhbHVlcy4gSSB3b25kZXIgd2hhdCBjb3VsZCBiZSBjYXVzaW5nIGl0LiBJIGNoZWNrZWQgdGhlIGVycmF0YSAoaHR0cHM6Ly9jbWlwLmxsbmwuZ292L2NtaXA1L2VycmF0YS9jbWlwNWVycmF0YS5odG1sKSB0byBzZWUgaWYgaW5tY200IGhhZCByZXBvcnRlZCBhbnkgcHJvYmxlbXMgd2l0aCB0aGUgZGF0YSB3ZSB1c2VkLiBXaGlsZSBpdCBkaWQgYXBwZWFyIG11bHRpcGxlIHRpbWVzIGluIHRoZSBlcnJhdGEgaXQgd2Fzbid0IGZvciBhbnkgb2YgdGhlIHZhcmlhYmxlcyB3ZSB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaGVhdCBmbHV4LgoKIyMgQ29uY2x1ZGluZyBUaG91Z2h0cwoKV2VsbCBpdHMgNTowMCBvbiBhIEZyaWRheSBhbmQgSSBoYXZlIGJyYWluIG11c2ggc28gdGhpcyBsb29rIGF0IG91ciBoZWF0IGZsdXggZGF0YSBoYXMgbm90IGJlZW4gYXMgdGhvcm91Z2ggYXMgSSB3b3VsZCBsaWtlIGl0IHRvIGJlLiBCdXQgaXQgZG9lcyByYWlzZSBzb21lIHF1ZXN0aW9ucyB0byBjb25zaWRlci4gCgoxLiBXaGVuIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSBoZWF0IGZsdXggZm9yIGEgaGFuZGZ1bCBvZiB5ZWFyIGxvb2tzIGZ1bmt5IGRvIHdlIHdhbnQgdG8gcmVtb3ZlIHRoZSBvdXRsaWVyIHllYXJzIG9yIGRpc2NhcmQgdGhlIGVudGlyZSB0aW1lIHNlcmllcz8gCjIuIEZvciBpbm1jbTQgd2hhdCBpcyBnb2luZyBvbj8gSXMgdGhlcmUgYSBwcm9ibGVtIHdpdGggb25lIG9mIHRoZSBuZXRjZGYgZmlsZXMgd2UgdXNlZCBiZWNhdXNlIHRoZSB0cmVuZCBhbmQgc3ByZWFkIGxvb2tzIGdvb2QgdG8gbWUsIGl0IGlzIGFsbW9zdCBsaWtlIHRoZSB0aW1lIHNlcmllcyBoYXMgYmVlbiBvZmYgc2V0IGEgYml0LiAKCgo=