Uncertiainty Space Sampeled
I followed the protocol we set up for the AGU aerosol experiment.
# uncertainty_sample_range: samples a range and returns a vector that meeets the rolustion return a vector the
# resolution / max samples argument requirements. The sampeling in unifrom centered around the median.
# Args
# input: a data frame contianing a column of scalars that
# resolution: the number of the desired resolution between sampled space
# max_smaples: a number that determines the limit of the maxiumn number of samples that can be taken from a space.
# TODO This function is okay, and could probably be enhanced.
uncertainty_sample_range <- function(input, resolution, max_samples){
# Find the center of the paramter range.
median_value <- median(input$scalar)
median_extreme_diff <- abs(input$scalar[1] - median_value)
if(median_extreme_diff <= resolution){
# Return the input scalars puls the meidan value.
c(median_value, input$scalar)
} else {
# Determine how many sample would have to be taken in order to meet the resolution
# requirements.
sample_length <- ceiling(median_extreme_diff / resolution)
if( 2 * sample_length > max_samples){
# If the calculated sample length is longer than the max sample size
# default to the max sample size and return a warning.
sample_length <- floor((max_samples / 2)) - 1
warning('Calulated sample size based on the resolution exces the max sample size,
using the max sample size instead.')
}
first_half <- seq(from = min(input$scalar), to = median_value, length.out = sample_length)
second_half <- seq(from = median_value, to = max(input$scalar), length.out = sample_length)
if(length(first_half) < 1){
first_half <- min(input$scalar)
}
if(length(second_half) < 1){
second_half <- max(input$scalar)
}
# Return the sampled sequence
sort(c(first_half, median_value, second_half))
}
}
bind_rows(tibble( species = "SO2i", min = -1.2, max = 0),
tibble( species = "SO2d", min = -.60, max = - 0.2),
tibble( species = "OC", min = -.16,max = -.03),
tibble( species = "BC", min = .05, max = .8)) ->
IPCC_range
# Subset the RF pathways to include the RF values in 2011 for the rcp45 runs for the aerosol species we are
# perturbing in the uncertianty anlaysis.
aerosol_RF <- bind_rows(Hector_RF[ grepl(paste(IPCC_range$species, collapse = '|') , names(Hector_RF))]) %>%
filter( grepl('rcp45', name) ) %>%
filter(year == 2011)
# Now add the IPCC 2011 uncertianty ranges to the aerosol RF tibble.
aerosol_RF %>%
full_join(gather(IPCC_range, extreme, IPCC_range, min, max), by = c('agent' = 'species')) %>%
select(year, IPCC_range, value_2011 = value, agent, extreme) ->
IPCC_2011_values
# Divide the min and max IPCC ranges by the 2011 RF values to calculate the min and matx uncertainty scalars.
IPCC_2011_values %>%
mutate(scalar = IPCC_range / value_2011 ) %>%
select(agent, scalar, extreme) %>%
mutate(species = paste0('rcp45_F', agent)) ->
min_max_scalars
# 3. Sample Uncetianty scalars and Run HIRM -----------------------------------------------------------------------
# Now sample the uncetainty scalars using the function we defined in section 0.5. How often we sample the
# scalar space will depend on how large the range is.
min_max_scalars %>%
filter(agent == 'BC') %>%
uncertainty_sample_range(resolution = 0.02, max_samples = 10) ->
BC_scalars
Calulated sample size based on the resolution exces the max sample size,
using the max sample size instead.
min_max_scalars %>%
filter(agent == 'OC') %>%
uncertainty_sample_range(resolution = 0.02, max_samples = 8) ->
OC_scalars
Calulated sample size based on the resolution exces the max sample size,
using the max sample size instead.
min_max_scalars %>%
filter(agent == 'SO2d') %>%
uncertainty_sample_range(resolution = 0.1, max_samples = 15) ->
SO2d_scalars
min_max_scalars %>%
filter(agent == 'SO2i') %>%
uncertainty_sample_range(resolution = 0.1, max_samples = 20) ->
SO2i_scalars
# Save the scalars a a list.
scalars_1 <- list(rcp45_FBC = BC_scalars,
rcp45_FOC = OC_scalars,
rcp45_FSO2d = SO2d_scalars,
rcp45_FSO2i = SO2i_scalars)
Let’s take a look at what values ended up being samppled.
BC RF
length(scalars_1$rcp45_FBC)
[1] 9
range(scalars_1$rcp45_FOC)
[1] 0.06893547 0.36765582
ggplot(data = tibble(value = scalars_1$rcp45_FBC,
scalar = 'BC')) +
geom_point(aes(scalar, value)) +
labs(y = 'BC RF scalar value')

OC RF
length(scalars_1$rcp45_FOC)
[1] 7
range(scalars_1$rcp45_FOC)
[1] 0.06893547 0.36765582
ggplot(data = tibble(value = scalars_1$rcp45_FOC,
scalar = 'OC')) +
geom_point(aes(scalar, value)) +
labs(y = 'OC RF scalar value')

RF SOd
length(scalars_1$rcp45_FSO2d)
[1] 13
range(scalars_1$rcp45_FSO2d)
[1] 0.567414 1.702242
ggplot(data = tibble(value = scalars_1$rcp45_FSO2d,
scalar = 'SO2d')) +
geom_point(aes(scalar, value)) +
labs(y = 'SO2d RF scalar value')

RF SOi
length(scalars_1$rcp45_FSO2i)
[1] 21
range(scalars_1$rcp45_FSO2i)
[1] 0.00000 1.99043
ggplot(data = tibble(value = scalars_1$rcp45_FSO2i,
scalar = 'SO2i')) +
geom_point(aes(scalar, value)) +
labs(y = 'SO2i RF scalar value')

How many perumataions is this??
total_run_count <- prod(lengths(scalars_1))
total_run_count
[1] 17199
Constraints
Global Mean Temperautre Constraint
# The temperature linear trend for the 1880-2010 period (0.65 to 1.1 oC) was then used to screen out
# cases with trends falling outside this range (Hartmann et al. 2013).
# Hartmann et al. 2013 is IPCC AR5 climate chapter WG I chapter 2.
# Pg 194
# Observations: Atmosphere and Surface
# Coordinating Lead Authors:
# Dennis L. Hartmann (USA), Albert M.G. Klein Tank (Netherlands), Matilde Rusticucci (Argentina)
temp_constraints <- tibble(period_name = '1880_2010',
period_start = 1880,
period_end = 2010,
min = 0.65,
max = 1.1)
For each of the 1.719910^{4} runs I calcualted the slope of the temperature change from 1880 to 2020 multiplied by 131 years for the number of years in the period. And then compared the HIRM slopes with the min and max values of the IPCC slope.
How many runs passed through the IPCC temp change?
passing_rslts <- read.csv(list.files(OUTPUT2_DIR, '.csv', full.names = TRUE))
passing_rslts %>%
filter(constraint == 'temp') %>%
pull(pass) %>%
sum ->
passing_temp_runs
passing_temp_runs
[1] 9304
What percentage of the total run count passed through the temperature observations??
100*(passing_temp_runs / total_run_count)
[1] 54.09617
What does the temp change constraint look like?
ggplot(data = passing_rslts %>%
filter(constraint == 'temp')) +
geom_point(aes(year, value), position = 'jitter') +
geom_hline(aes(yintercept = temp_constraints$min), color = 'red') +
geom_hline(aes(yintercept = temp_constraints$max), color = 'red') +
labs(y = expression(degree~'C'),
title = 'Change in HIRM temperature and IPCC historical temperature constraints')

Total Aerosol RF Constraint
I use the same constraints we did from the AGU analysis however I found several effor in my code.
- I did not constrain to runs with aersol RF I looked at total RF.
- I selected runs that fell outside the constraint region (face palm).
# The IPCC AR5 uncertainty in the aerosol uncertainty in 2011 spans a range of 0.14 to -1.66.
rf <- tibble(year = 2011,
min = 0.14,
max = -1.66)
Now when I limit the sum of the BC, OC, SO2d, and SO2i RF in 2011 to fall within this range there are no runs that pass through the RF constriant. I think that this is an issue that we are going to need to revisit.
passing_rslts %>%
filter(constraint == 'forcing') %>%
pull(pass) %>%
sum ->
passing_rf_runs
passing_rf_runs
[1] 0
Let’s compare the HIRM total aerosol RF values with the constraint values.

LS0tCnRpdGxlOiAiSElSTSBEb2N1bWVudGF0aW9uIFBhcGVyIC0gVW5jZXJ0YWludHkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KYGBge3IsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZz1GQUxTRX0KIyBMb2FkIHRoZSByZXF1aXJlZCBwYWNrYWdlcy4gCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KFNMQ0ZpbXB1bHNlKQpsaWJyYXJ5KGdncGxvdDIpCgpCQVNFX0RJUiA8LSAiL1VzZXJzL2RvcmgwMTIvRG9jdW1lbnRzLzIwMTkvSElSTS1kb2N1bWVudGF0aW9uLXBhcGVyIgpPVVRQVVQyX0RJUiA8LSBmaWxlLnBhdGgoQkFTRV9ESVIsICdvdXRwdXQnLCAnMkMudW5jZXJ0YWludHlfcnNsdHMnKQoKYGBgCgoKIyMgT2JqZWN0aXZlIAoKVGhpcyBkb2N1bWVudCBoaWdobGlnaHRzIHRoZSBtZXRob2QgYW5kIHJlc3V0bHMgZnJvbSB0aGUgYWVyb3NvbCB1bmNlcnRpbmF0eSBjYXNlIHN0dWR5IHRoYXQgd2Ugd291bGQgbGlrZSB0byBpbmNsdWRlIGluIHRoZSBISVJNIGRvY3VlbXRuYXRpb24gcGFwZXIuIAoKIyMgVW5jZXJ0aWFpbnR5IFNwYWNlIFNhbXBlbGVkIAoKSSBmb2xsb3dlZCB0aGUgcHJvdG9jb2wgd2Ugc2V0IHVwIGZvciB0aGUgQUdVIGFlcm9zb2wgZXhwZXJpbWVudC4gCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQoKIyB1bmNlcnRhaW50eV9zYW1wbGVfcmFuZ2U6IHNhbXBsZXMgYSByYW5nZSBhbmQgcmV0dXJucyBhIHZlY3RvciB0aGF0IG1lZWV0cyB0aGUgcm9sdXN0aW9uIHJldHVybiBhIHZlY3RvciB0aGUKIyByZXNvbHV0aW9uIC8gbWF4IHNhbXBsZXMgYXJndW1lbnQgcmVxdWlyZW1lbnRzLiBUaGUgc2FtcGVsaW5nIGluIHVuaWZyb20gY2VudGVyZWQgYXJvdW5kIHRoZSBtZWRpYW4uCiMgQXJncwojICAgaW5wdXQ6IGEgZGF0YSBmcmFtZSBjb250aWFuaW5nIGEgY29sdW1uIG9mIHNjYWxhcnMgdGhhdAojICAgcmVzb2x1dGlvbjogdGhlIG51bWJlciBvZiB0aGUgZGVzaXJlZCByZXNvbHV0aW9uIGJldHdlZW4gc2FtcGxlZCBzcGFjZQojICAgbWF4X3NtYXBsZXM6IGEgbnVtYmVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgbGltaXQgb2YgdGhlIG1heGl1bW4gbnVtYmVyIG9mIHNhbXBsZXMgdGhhdCBjYW4gYmUgdGFrZW4gZnJvbSBhIHNwYWNlLgojIFRPRE8gVGhpcyBmdW5jdGlvbiBpcyBva2F5LCBhbmQgY291bGQgcHJvYmFibHkgYmUgZW5oYW5jZWQuCgp1bmNlcnRhaW50eV9zYW1wbGVfcmFuZ2UgPC0gZnVuY3Rpb24oaW5wdXQsIHJlc29sdXRpb24sIG1heF9zYW1wbGVzKXsKICAKICAjIEZpbmQgdGhlIGNlbnRlciBvZiB0aGUgcGFyYW10ZXIgcmFuZ2UuCiAgbWVkaWFuX3ZhbHVlIDwtIG1lZGlhbihpbnB1dCRzY2FsYXIpCiAgbWVkaWFuX2V4dHJlbWVfZGlmZiA8LSBhYnMoaW5wdXQkc2NhbGFyWzFdIC0gbWVkaWFuX3ZhbHVlKQogIAogIGlmKG1lZGlhbl9leHRyZW1lX2RpZmYgPD0gcmVzb2x1dGlvbil7CiAgICAKICAgICMgUmV0dXJuIHRoZSBpbnB1dCBzY2FsYXJzIHB1bHMgdGhlIG1laWRhbiB2YWx1ZS4KICAgIGMobWVkaWFuX3ZhbHVlLCBpbnB1dCRzY2FsYXIpCiAgICAKICB9IGVsc2UgewogICAgCiAgICAjIERldGVybWluZSBob3cgbWFueSBzYW1wbGUgd291bGQgaGF2ZSB0byBiZSB0YWtlbiBpbiBvcmRlciB0byBtZWV0IHRoZSByZXNvbHV0aW9uCiAgICAjIHJlcXVpcmVtZW50cy4KICAgIHNhbXBsZV9sZW5ndGggPC0gY2VpbGluZyhtZWRpYW5fZXh0cmVtZV9kaWZmIC8gcmVzb2x1dGlvbikKICAgIAogICAgaWYoIDIgKiBzYW1wbGVfbGVuZ3RoID4gbWF4X3NhbXBsZXMpewogICAgICAKICAgICAgIyBJZiB0aGUgY2FsY3VsYXRlZCBzYW1wbGUgbGVuZ3RoIGlzIGxvbmdlciB0aGFuIHRoZSBtYXggc2FtcGxlIHNpemUKICAgICAgIyBkZWZhdWx0IHRvIHRoZSBtYXggc2FtcGxlIHNpemUgYW5kIHJldHVybiBhIHdhcm5pbmcuCiAgICAgIHNhbXBsZV9sZW5ndGggPC0gZmxvb3IoKG1heF9zYW1wbGVzIC8gMikpIC0gMQogICAgICAKICAgICAgd2FybmluZygnQ2FsdWxhdGVkIHNhbXBsZSBzaXplIGJhc2VkIG9uIHRoZSByZXNvbHV0aW9uIGV4Y2VzIHRoZSBtYXggc2FtcGxlIHNpemUsCiAgICAgICAgICAgICAgdXNpbmcgdGhlIG1heCBzYW1wbGUgc2l6ZSBpbnN0ZWFkLicpCiAgICAgIAogICAgfQogICAgCiAgICBmaXJzdF9oYWxmICA8LSBzZXEoZnJvbSA9IG1pbihpbnB1dCRzY2FsYXIpLCB0byA9IG1lZGlhbl92YWx1ZSwgbGVuZ3RoLm91dCA9IHNhbXBsZV9sZW5ndGgpCiAgICBzZWNvbmRfaGFsZiA8LSBzZXEoZnJvbSA9IG1lZGlhbl92YWx1ZSwgdG8gPSBtYXgoaW5wdXQkc2NhbGFyKSwgbGVuZ3RoLm91dCA9IHNhbXBsZV9sZW5ndGgpCiAgICAKICAgIGlmKGxlbmd0aChmaXJzdF9oYWxmKSA8IDEpewogICAgICAKICAgICAgZmlyc3RfaGFsZiA8LSBtaW4oaW5wdXQkc2NhbGFyKQogICAgICAKICAgIH0KICAgIAogICAgaWYobGVuZ3RoKHNlY29uZF9oYWxmKSA8IDEpewogICAgICBzZWNvbmRfaGFsZiA8LSBtYXgoaW5wdXQkc2NhbGFyKQogICAgfQogICAgCiAgICAjIFJldHVybiB0aGUgc2FtcGxlZCBzZXF1ZW5jZQogICAgc29ydChjKGZpcnN0X2hhbGYsIG1lZGlhbl92YWx1ZSwgc2Vjb25kX2hhbGYpKQogICAgCiAgfQogIAp9CgpiaW5kX3Jvd3ModGliYmxlKCBzcGVjaWVzID0gIlNPMmkiLCBtaW4gPSAgLTEuMiwgbWF4ID0gMCksCiAgICAgICAgICB0aWJibGUoIHNwZWNpZXMgPSAiU08yZCIsIG1pbiA9IC0uNjAsIG1heCA9IC0gMC4yKSwKICAgICAgICAgIHRpYmJsZSggc3BlY2llcyA9ICJPQyIsIG1pbiA9IC0uMTYsbWF4ID0gIC0uMDMpLAogICAgICAgICAgdGliYmxlKCBzcGVjaWVzID0gIkJDIiwgbWluID0gLjA1LCBtYXggPSAuOCkpIC0+CiAgSVBDQ19yYW5nZQoKIyBTdWJzZXQgdGhlIFJGIHBhdGh3YXlzIHRvIGluY2x1ZGUgdGhlIFJGIHZhbHVlcyBpbiAyMDExIGZvciB0aGUgcmNwNDUgcnVucyBmb3IgdGhlIGFlcm9zb2wgc3BlY2llcyB3ZSBhcmUKIyBwZXJ0dXJiaW5nIGluIHRoZSB1bmNlcnRpYW50eSBhbmxheXNpcy4KYWVyb3NvbF9SRiA8LSBiaW5kX3Jvd3MoSGVjdG9yX1JGWyBncmVwbChwYXN0ZShJUENDX3JhbmdlJHNwZWNpZXMsIGNvbGxhcHNlID0gJ3wnKSAsIG5hbWVzKEhlY3Rvcl9SRikpXSkgJT4lCiAgZmlsdGVyKCBncmVwbCgncmNwNDUnLCBuYW1lKSApICU+JQogIGZpbHRlcih5ZWFyID09IDIwMTEpCgojIE5vdyBhZGQgdGhlIElQQ0MgMjAxMSB1bmNlcnRpYW50eSByYW5nZXMgdG8gdGhlIGFlcm9zb2wgUkYgdGliYmxlLgphZXJvc29sX1JGICU+JQogIGZ1bGxfam9pbihnYXRoZXIoSVBDQ19yYW5nZSwgZXh0cmVtZSwgSVBDQ19yYW5nZSwgbWluLCBtYXgpLCBieSA9IGMoJ2FnZW50JyA9ICdzcGVjaWVzJykpICU+JQogIHNlbGVjdCh5ZWFyLCBJUENDX3JhbmdlLCB2YWx1ZV8yMDExID0gdmFsdWUsIGFnZW50LCBleHRyZW1lKSAtPgogIElQQ0NfMjAxMV92YWx1ZXMKCiMgRGl2aWRlIHRoZSBtaW4gYW5kIG1heCBJUENDIHJhbmdlcyBieSB0aGUgMjAxMSBSRiB2YWx1ZXMgdG8gY2FsY3VsYXRlIHRoZSBtaW4gYW5kIG1hdHggdW5jZXJ0YWludHkgc2NhbGFycy4KSVBDQ18yMDExX3ZhbHVlcyAlPiUKICBtdXRhdGUoc2NhbGFyID0gSVBDQ19yYW5nZSAvIHZhbHVlXzIwMTEgKSAlPiUKICBzZWxlY3QoYWdlbnQsIHNjYWxhciwgZXh0cmVtZSkgJT4lCiAgbXV0YXRlKHNwZWNpZXMgPSAgcGFzdGUwKCdyY3A0NV9GJywgYWdlbnQpKSAgLT4KICBtaW5fbWF4X3NjYWxhcnMKCiMgMy4gU2FtcGxlIFVuY2V0aWFudHkgc2NhbGFycyBhbmQgUnVuIEhJUk0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyBOb3cgc2FtcGxlIHRoZSB1bmNldGFpbnR5IHNjYWxhcnMgdXNpbmcgdGhlIGZ1bmN0aW9uIHdlIGRlZmluZWQgaW4gc2VjdGlvbiAwLjUuIEhvdyBvZnRlbiB3ZSBzYW1wbGUgdGhlCiMgc2NhbGFyIHNwYWNlIHdpbGwgZGVwZW5kIG9uIGhvdyBsYXJnZSB0aGUgcmFuZ2UgaXMuCm1pbl9tYXhfc2NhbGFycyAlPiUKICBmaWx0ZXIoYWdlbnQgPT0gJ0JDJykgJT4lCiAgdW5jZXJ0YWludHlfc2FtcGxlX3JhbmdlKHJlc29sdXRpb24gPSAwLjAyLCBtYXhfc2FtcGxlcyA9IDEwKSAtPgogIEJDX3NjYWxhcnMKCm1pbl9tYXhfc2NhbGFycyAlPiUKICBmaWx0ZXIoYWdlbnQgPT0gJ09DJykgJT4lCiAgdW5jZXJ0YWludHlfc2FtcGxlX3JhbmdlKHJlc29sdXRpb24gPSAwLjAyLCBtYXhfc2FtcGxlcyA9IDgpIC0+CiAgT0Nfc2NhbGFycwoKbWluX21heF9zY2FsYXJzICU+JQogIGZpbHRlcihhZ2VudCA9PSAnU08yZCcpICU+JQogIHVuY2VydGFpbnR5X3NhbXBsZV9yYW5nZShyZXNvbHV0aW9uID0gMC4xLCBtYXhfc2FtcGxlcyA9IDE1KSAtPgogIFNPMmRfc2NhbGFycwoKbWluX21heF9zY2FsYXJzICU+JQogIGZpbHRlcihhZ2VudCA9PSAnU08yaScpICU+JQogIHVuY2VydGFpbnR5X3NhbXBsZV9yYW5nZShyZXNvbHV0aW9uID0gMC4xLCBtYXhfc2FtcGxlcyA9IDIwKSAtPgogIFNPMmlfc2NhbGFycwoKIyBTYXZlIHRoZSBzY2FsYXJzIGEgYSBsaXN0LgpzY2FsYXJzXzEgPC0gbGlzdChyY3A0NV9GQkMgPSBCQ19zY2FsYXJzLAogICAgICAgICAgICAgICAgICByY3A0NV9GT0MgPSBPQ19zY2FsYXJzLAogICAgICAgICAgICAgICAgICByY3A0NV9GU08yZCA9IFNPMmRfc2NhbGFycywKICAgICAgICAgICAgICAgICAgcmNwNDVfRlNPMmkgPSBTTzJpX3NjYWxhcnMpCgpgYGAKCkxldCdzIHRha2UgYSBsb29rIGF0IHdoYXQgdmFsdWVzIGVuZGVkIHVwIGJlaW5nIHNhbXBwbGVkLiAKCiMjIyBCQyBSRiAgCgpgYGB7cn0KbGVuZ3RoKHNjYWxhcnNfMSRyY3A0NV9GQkMpCmBgYAoKYGBge3J9CnJhbmdlKHNjYWxhcnNfMSRyY3A0NV9GT0MpCmBgYAoKYGBge3J9CmdncGxvdChkYXRhID0gdGliYmxlKHZhbHVlID0gc2NhbGFyc18xJHJjcDQ1X0ZCQywgIAogICAgICAgICAgICAgICAgICAgICBzY2FsYXIgPSAnQkMnKSkgKyAKICBnZW9tX3BvaW50KGFlcyhzY2FsYXIsIHZhbHVlKSkgKyAKICBsYWJzKHkgPSAnQkMgUkYgc2NhbGFyIHZhbHVlJykKYGBgCgojIyMgT0MgUkYgIAoKYGBge3J9Cmxlbmd0aChzY2FsYXJzXzEkcmNwNDVfRk9DKQpgYGAKCmBgYHtyfQpyYW5nZShzY2FsYXJzXzEkcmNwNDVfRk9DKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IHRpYmJsZSh2YWx1ZSA9IHNjYWxhcnNfMSRyY3A0NV9GT0MsICAKICAgICAgICAgICAgICAgICAgICAgc2NhbGFyID0gJ09DJykpICsgCiAgZ2VvbV9wb2ludChhZXMoc2NhbGFyLCB2YWx1ZSkpICsgCiAgbGFicyh5ID0gJ09DIFJGIHNjYWxhciB2YWx1ZScpCmBgYAoKIyMjIFJGIFNPZCAKCmBgYHtyfQpsZW5ndGgoc2NhbGFyc18xJHJjcDQ1X0ZTTzJkKQpgYGAKCmBgYHtyfQpyYW5nZShzY2FsYXJzXzEkcmNwNDVfRlNPMmQpCmBgYAoKYGBge3J9CmdncGxvdChkYXRhID0gdGliYmxlKHZhbHVlID0gc2NhbGFyc18xJHJjcDQ1X0ZTTzJkLCAgCiAgICAgICAgICAgICAgICAgICAgIHNjYWxhciA9ICdTTzJkJykpICsgCiAgZ2VvbV9wb2ludChhZXMoc2NhbGFyLCB2YWx1ZSkpICsgCiAgbGFicyh5ID0gJ1NPMmQgUkYgc2NhbGFyIHZhbHVlJykKYGBgCgojIyMgUkYgU09pIAoKYGBge3J9Cmxlbmd0aChzY2FsYXJzXzEkcmNwNDVfRlNPMmkpCmBgYAoKYGBge3J9CnJhbmdlKHNjYWxhcnNfMSRyY3A0NV9GU08yaSkKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSB0aWJibGUodmFsdWUgPSBzY2FsYXJzXzEkcmNwNDVfRlNPMmksICAKICAgICAgICAgICAgICAgICAgICAgc2NhbGFyID0gJ1NPMmknKSkgKyAKICBnZW9tX3BvaW50KGFlcyhzY2FsYXIsIHZhbHVlKSkgKyAKICBsYWJzKHkgPSAnU08yaSBSRiBzY2FsYXIgdmFsdWUnKQpgYGAKCgojIyMgSG93IG1hbnkgcGVydW1hdGFpb25zIGlzIHRoaXM/PyAKCmBgYHtyfQp0b3RhbF9ydW5fY291bnQgPC0gcHJvZChsZW5ndGhzKHNjYWxhcnNfMSkpCnRvdGFsX3J1bl9jb3VudApgYGAKCiMjIENvbnN0cmFpbnRzIAoKIyMjIEdsb2JhbCBNZWFuIFRlbXBlcmF1dHJlIENvbnN0cmFpbnQgCgpgYGB7cn0KIyBUaGUgdGVtcGVyYXR1cmUgbGluZWFyIHRyZW5kIGZvciB0aGUgMTg4MC0yMDEwIHBlcmlvZCAoMC42NSB0byAxLjEgb0MpIHdhcyB0aGVuIHVzZWQgdG8gc2NyZWVuIG91dAojIGNhc2VzIHdpdGggdHJlbmRzIGZhbGxpbmcgb3V0c2lkZSB0aGlzIHJhbmdlICAoSGFydG1hbm4gZXQgYWwuIDIwMTMpLgojIEhhcnRtYW5uIGV0IGFsLiAyMDEzIGlzIElQQ0MgQVI1IGNsaW1hdGUgY2hhcHRlciBXRyBJIGNoYXB0ZXIgMi4KIyBQZyAxOTQKIyBPYnNlcnZhdGlvbnM6IEF0bW9zcGhlcmUgYW5kIFN1cmZhY2UKIyBDb29yZGluYXRpbmcgTGVhZCBBdXRob3JzOgojIERlbm5pcyBMLiBIYXJ0bWFubiAoVVNBKSwgQWxiZXJ0IE0uRy4gS2xlaW4gVGFuayAoTmV0aGVybGFuZHMpLCBNYXRpbGRlIFJ1c3RpY3VjY2kgKEFyZ2VudGluYSkKdGVtcF9jb25zdHJhaW50cyA8LSB0aWJibGUocGVyaW9kX25hbWUgPSAnMTg4MF8yMDEwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kX3N0YXJ0ID0gMTg4MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVyaW9kX2VuZCA9IDIwMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbiA9IDAuNjUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYXggPSAxLjEpIApgYGAKCgpGb3IgZWFjaCBvZiB0aGUgYHIgdG90YWxfcnVuX2NvdW50YCBydW5zIEkgY2FsY3VhbHRlZCB0aGUgc2xvcGUgb2YgdGhlIHRlbXBlcmF0dXJlIGNoYW5nZSBmcm9tIDE4ODAgdG8gMjAyMCBtdWx0aXBsaWVkIGJ5IDEzMSB5ZWFycyBmb3IgdGhlIG51bWJlciBvZiB5ZWFycyBpbiB0aGUgcGVyaW9kLiBBbmQgdGhlbiBjb21wYXJlZCB0aGUgSElSTSBzbG9wZXMgd2l0aCB0aGUgbWluIGFuZCBtYXggdmFsdWVzIG9mIHRoZSBJUENDIHNsb3BlLiAKCkhvdyBtYW55IHJ1bnMgcGFzc2VkIHRocm91Z2ggdGhlIElQQ0MgdGVtcCBjaGFuZ2U/ICAKCmBgYHtyfQpwYXNzaW5nX3JzbHRzIDwtIHJlYWQuY3N2KGxpc3QuZmlsZXMoT1VUUFVUMl9ESVIsICcuY3N2JywgZnVsbC5uYW1lcyA9IFRSVUUpKQpgYGAKCmBgYHtyfQpwYXNzaW5nX3JzbHRzICU+JSAgCiAgZmlsdGVyKGNvbnN0cmFpbnQgPT0gJ3RlbXAnKSAlPiUgCiAgcHVsbChwYXNzKSAlPiUgCiAgc3VtIC0+IAogIHBhc3NpbmdfdGVtcF9ydW5zCnBhc3NpbmdfdGVtcF9ydW5zCmBgYAoKV2hhdCBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCBydW4gY291bnQgcGFzc2VkIHRocm91Z2ggdGhlIHRlbXBlcmF0dXJlIG9ic2VydmF0aW9ucz8/IAoKYGBge3J9CjEwMCoocGFzc2luZ190ZW1wX3J1bnMgLyB0b3RhbF9ydW5fY291bnQpCmBgYAoKV2hhdCBkb2VzIHRoZSB0ZW1wIGNoYW5nZSBjb25zdHJhaW50IGxvb2sgbGlrZT8gCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBwYXNzaW5nX3JzbHRzICU+JSAgCiAgICAgICAgIGZpbHRlcihjb25zdHJhaW50ID09ICd0ZW1wJykpICsKICBnZW9tX3BvaW50KGFlcyh5ZWFyLCB2YWx1ZSksIHBvc2l0aW9uID0gJ2ppdHRlcicpICsgCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHRlbXBfY29uc3RyYWludHMkbWluKSwgY29sb3IgPSAncmVkJykgKyAKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gdGVtcF9jb25zdHJhaW50cyRtYXgpLCBjb2xvciA9ICdyZWQnKSArIAogIGxhYnMoeSA9IGV4cHJlc3Npb24oZGVncmVlfidDJyksIAogICAgICAgdGl0bGUgPSAnQ2hhbmdlIGluIEhJUk0gdGVtcGVyYXR1cmUgYW5kIElQQ0MgaGlzdG9yaWNhbCB0ZW1wZXJhdHVyZSBjb25zdHJhaW50cycpCmBgYAoKCgojIyMgVG90YWwgQWVyb3NvbCBSRiBDb25zdHJhaW50IAoKSSB1c2UgdGhlIHNhbWUgY29uc3RyYWludHMgd2UgZGlkIGZyb20gdGhlIEFHVSBhbmFseXNpcyBob3dldmVyIEkgZm91bmQgc2V2ZXJhbCBlZmZvciBpbiBteSBjb2RlLiAKCjEuIEkgZGlkIG5vdCBjb25zdHJhaW4gdG8gcnVucyB3aXRoIGFlcnNvbCBSRiBJIGxvb2tlZCBhdCB0b3RhbCBSRi4gCjIuIEkgc2VsZWN0ZWQgcnVucyB0aGF0IGZlbGwgb3V0c2lkZSB0aGUgY29uc3RyYWludCByZWdpb24gKGZhY2UgcGFsbSkuIAoKYGBge3J9CiMgVGhlIElQQ0MgQVI1IHVuY2VydGFpbnR5IGluIHRoZSBhZXJvc29sIHVuY2VydGFpbnR5IGluIDIwMTEgc3BhbnMgYSByYW5nZSBvZiAwLjE0IHRvIC0xLjY2LiAKcmYgPC0gdGliYmxlKHllYXIgPSAyMDExLCAKICAgICAgICAgICAgIG1pbiA9IDAuMTQsIAogICAgICAgICAgICAgbWF4ID0gLTEuNjYpCmBgYAoKCk5vdyB3aGVuIEkgbGltaXQgdGhlIHN1bSBvZiB0aGUgQkMsIE9DLCBTTzJkLCBhbmQgU08yaSBSRiBpbiAyMDExIHRvIGZhbGwgd2l0aGluIHRoaXMgcmFuZ2UgdGhlcmUgYXJlIG5vIHJ1bnMgdGhhdCBwYXNzIHRocm91Z2ggdGhlIFJGIGNvbnN0cmlhbnQuIEkgdGhpbmsgdGhhdCB0aGlzIGlzIGFuIGlzc3VlIHRoYXQgd2UgYXJlIGdvaW5nIHRvIG5lZWQgdG8gcmV2aXNpdC4KCgpgYGB7cn0KcGFzc2luZ19yc2x0cyAlPiUgIAogIGZpbHRlcihjb25zdHJhaW50ID09ICdmb3JjaW5nJykgJT4lIAogIHB1bGwocGFzcykgJT4lIAogIHN1bSAtPiAKICBwYXNzaW5nX3JmX3J1bnMKcGFzc2luZ19yZl9ydW5zCmBgYAoKTGV0J3MgY29tcGFyZSB0aGUgSElSTSB0b3RhbCBhZXJvc29sIFJGIHZhbHVlcyB3aXRoIHRoZSBjb25zdHJhaW50IHZhbHVlcy4KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IHBhc3NpbmdfcnNsdHMgJT4lICAKICAgICAgICAgZmlsdGVyKGNvbnN0cmFpbnQgPT0gJ2ZvcmNpbmcnKSkgKwogIGdlb21fcG9pbnQoYWVzKHllYXIsIHZhbHVlKSwgcG9zaXRpb24gPSAnaml0dGVyJykgKyAKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gcmYkbWluKSwgY29sb3IgPSAncmVkJykgKyAKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gcmYkbWF4KSwgY29sb3IgPSAncmVkJykgKyAKICBsYWJzKHkgPSAnUkYgVy9tMicsIAogICAgICAgdGl0bGUgPSAnVG90YWwgQWVyb3NvbCBSRiB2cyBJUENDIGNvbnN0cmFpbnQnKQpgYGAKCgoKIyMgQ29uY2x1c2lvbnMgCgoxLiBJIHRoaW5rIHRoYXQgdGhlIGdsb2JhbCBtZWFuIHRlbXBlcmF0dXJlIGNoYW5nZSBjb25zdHJhaW50IGxvb2tzIGdvb2QuIAoyLiBJIGFtIGNvbmNlcm5lZCBhYm91dCB3aGF0IGlzIGdvaW5nIG9uIHdpdGggdGhlIGFlcm9zb2wgUkYgY29udHJhaW50LiAKMy4gRG8gd2Ugc2FtcGxlIGVub3VnaCBCQyBhbmQgT0Mgc2NhbGFycz8KCg==