Objective

What is the difference between the emission driven and concentration driven runs? In theory we expect the emission driven runs with the carbon cycle turned on to have feedback mechanimss impacting the temperature and co2 otuput. Corinne brought up the idea, does it even really matter? Is the difference 5 ppm or 100 ppm? Are the ESMs and Hector senstive enough to the carbon cycle for the emission driven runs to be different from the concentration driven runs? Could the climate paramterizations do an adequate job of representing the ESMs?

  1. Is there a difference in the emission vs concentration driven runs for the ESMs and Hector? / How well does the concenration climate paramterizations do with emulating the carbon cycle?
  2. Solving for beta at fixed q10 values.

1. Is there a difference in the emission vs concentration driven runs for the ESMs and Hector?

# What models have esmission driven results? 
cmip_individual %>%  
    filter(grepl('esm', experiment)) %>% 
    pull(model) %>% 
    unique() -> 
    emission_driven_models
# Import the co2 concentration for the concentration driven runs (from the hector inputs). 
# Format the data frame so that it has the model name and ensemble information.
read.csv(system.file('input/constraints/rcp85_co2ppm.csv', package = 'hector'), skip = 1) %>% 
    rename(year = Date, value = Ca_constrain) %>% 
    mutate(experiment = if_else(year <= 2005, 'historical', 'rcp85'), 
           variable = 'co2') %>% 
    mutate(join = 1) %>% 
    left_join(tibble(join = 1, 
                     ensemble = c("r1i1p1", "r2i1p1", "r3i1p1")) %>% 
                         left_join(tibble(join = 1, 
                                   model = emission_driven_models),  by = 'join'), 
              by = 'join') %>% 
    select(-join) -> 
    concentration_co2_values
# Import the CMIP ESM data and make sure that the concentration results does not include co2. 
cmip_individual %>% 
    filter(model %in% emission_driven_models) %>% 
    filter(year <= 2100 & experiment %in% c('historical', 'rcp45')) %>% 
    filter(variable != 'co2') %>% 
    bind_rows(concentration_co2_values) -> 
    concenctraion_rlst
# Import the CMIP ESM emisssion driven results. 
cmip_individual %>% 
    filter(model %in% emission_driven_models) %>% 
    filter(year <= 2100 & experiment %in% c('esmHistorical', 'esmrcp45')) %>% 
    bind_rows(concenctraion_rlst) %>% 
     mutate(driven = if_else(grepl('esm', experiment), 'emissions', 'concentration')) %>%  
    select(year, model, ensemble, variable, value, driven) %>%  
    distinct() -> 
    cmip_conc_emiss
# Calculate the difference between the emission driven anf the concentration driven runs. 
cmip_conc_emiss %>% 
    tidyr::spread(driven, value) %>% 
    na.omit %>% 
    mutate(dif = emissions - concentration) -> 
    diff_emis_conc

How do the ESM emission driven and concentration runs differ from one another?

diff_emis_conc %>%  
    ggplot(aes(concentration, emissions, color = model)) + 
    geom_point() + 
    geom_abline(intercept = 0, slope = 1, col = 'black') +
    facet_wrap('variable', scales = 'free') + 
    labs(y = 'emission driven ESM', 
         x = 'concentration driven ESM')

The black line show the 1:1 relationship between the x and y axis, so if the emission driven and concentration driven runs are fairly similar to one another then we would expect the pattern to be centered around the black line like we see in heatflux and tas. But it does look like the emission driven runs have a higher co2 concentration fo at least 2 of the models. CanESM2 does not seem to be particuarly senstive to the carbon cycle feedbacks.



What is the difference bewteen the runs? What does the noise look like of the conc and emission driven runs look like?

diff_emis_conc %>% 
    group_by(variable, model) %>% 
    summarise(min_dif = min(dif), 
              mean_dif = mean(dif), 
              max_dif = max(dif), 
              sd_dif = sd(dif)) %>% 
    ungroup()



How well does the Emission Hector calibrated with climate best fits models the emission ESM output?

How does the temp and co2 data for Hector calibrated with the results from the bestFit_conc_temp_heat2100 compare with the emission driven results?

paths     <- list.files(DIR, full.names = TRUE) 
to_import <- paths[which(grepl(paste(emission_driven_models, collapse = '|'), paths))]
lapply(to_import, function(input){
    object <- readRDS(input)
    
    data.frame(matrix(object$optim_rslt$par, nrow = 1, dimnames = list(NULL, names(object$optim_rslt$par)))) %>%  
        mutate(model = gsub(pattern = 'conc_|.rds', replacement = '', x = basename(input)))
}) %>% 
    bind_rows -> 
    params_df

Compare Hector emissions and ESM emission driven run results. How well does the concenration climate paramterizations do with emulating the carbon cycle?

path <- system.file('input/hector_rcp85.ini', package = 'hector')
core <- newcore(path)
split(x = params_df, f = params_df$model) %>% 
    lapply(function(input){params <- input[which(names(input) != 'model')]
parameterize_core(params = params, core = core)
reset(core)
run(core, runtodate = 2100)
fetchvars(core, 1850:2100, vars = c(HEAT_FLUX(), GLOBAL_TEMP(), ATMOSPHERIC_CO2())) %>% 
    mutate(experiment = if_else(year < 2005, 'esmHistorical', 'esmrcp85'), 
           model = input[['model']]) %>%  
    mutate(scenario = 'hector') %>% 
    mutate(variable = if_else(variable == 'Tgav', 'tas', variable)) %>% 
    mutate(variable = if_else(variable == 'Ca', 'co2', variable))
}) %>%  
    bind_rows() -> 
    emission_hector
emission_hector %>% 
    bind_rows(cmip_individual %>%  
                  mutate(scenario = 'cmip')) %>% 
    filter(grepl('esm', experiment)) -> 
    emission_hector_output 
emission_hector_output %>% 
    ggplot(aes(year, value, color = scenario, linetype = model)) + 
    geom_line() + 
    facet_grid(variable ~ model, scales = 'free') 

How much does the carbon cycle impact Hector output?

bind_rows(emission_hector_output %>%  mutate(run = 'emission'), 
          concentration_hector_output %>% mutate(run = 'concentration')) %>% 
    filter(grepl('hector', scenario)) -> 
    to_plot 
to_plot %>% 
    ggplot(aes(year, value, color = run, group = experiment)) + 
    geom_line() + 
    facet_grid(variable~model, scale = 'free')

to_plot %>% 
    select(year, variable, value, model, run) %>% 
    spread(run, value) %>%  
    ggplot(aes(concentration, emission, color = model)) +
    geom_point() + 
    geom_abline(intercept = 0, slope = 1) +
    facet_wrap('variable', scales = 'free') + 
      labs(y = 'emission driven ESM', 
         x = 'concentration driven ESM')

I guess I do not know if this sort of difference really seems like it is that notable to me. What do you guys think?

2. Solving for beta at fixed q10 values.

list.files(DIR2, '.rds', full.names = TRUE) %>% 
    lapply(function(input){readRDS(input)[['hector_output']]}) %>% 
    bind_rows() %>% 
    mutate(beta = signif(beta, digits = 3), 
           q10 = signif(q10, digits = 3), 
           beta_q10 = paste0(beta, '_', q10)) %>% 
    filter(scenario == 'esmrcp85') %>%  
    mutate(variable = if_else(variable == 'Tgav', 'tas', variable)) %>%  
    mutate(variable = if_else(variable == 'Ca', 'co2', variable))-> 
    to_plot

How much do the beta and q10 values range?

summary(to_plot$beta)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.000000 0.003237 0.057250 0.061660 0.108500 0.165000 

The beta values that optim solved for do not span the range we see in the DOE PI meeting mcmc PDFs… which I think it curious, very curios.

summary(to_plot$q10)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.998   3.000   3.000   4.003   5.000 
ggplot() + 
    geom_line(data = cmip_individual %>% filter(grepl('esm', experiment) & model == 'CESM1-BGC') %>%  
                  mutate(beta_q10 = 'cmip'),  
              aes(year, value, color = beta_q10), 
              color = 'grey', size = 2) +
    geom_line(data = to_plot, aes(year, value, color = beta_q10), alpha = 0.5) +
    facet_wrap('variable', scale = 'free') + 
    theme_bw(base_size = 18) + 
        theme(legend.position = 'none') 

We see a large range in the potential q10 and beta values, and they results are fairly similar to one another, they fall within the range of the cmip data especially for the tas data. For the co2 data it is some what hard to see but the solved hector runs with the various beta and q10 values do fall on top of the esm cmip data. Which confirms our suspicion that beta and q10 are capable of trading off with one another.

LS0tCnRpdGxlOiAiQ29uY2VudHJhdGlvbiB2cyBFbWlzc2lvbjogV2hhdCdzIHRoZSBkaWZmZXJlbmNlIGFud2F5cz8iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIE9iamVjdGl2ZSAKCldoYXQgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZW1pc3Npb24gZHJpdmVuIGFuZCBjb25jZW50cmF0aW9uIGRyaXZlbiBydW5zPyBJbiB0aGVvcnkgd2UgZXhwZWN0IHRoZSBlbWlzc2lvbiBkcml2ZW4gcnVucyB3aXRoIHRoZSBjYXJib24gY3ljbGUgdHVybmVkIG9uIHRvIGhhdmUgZmVlZGJhY2sgbWVjaGFuaW1zcyBpbXBhY3RpbmcgdGhlIHRlbXBlcmF0dXJlIGFuZCBjbzIgb3R1cHV0LiBDb3Jpbm5lIGJyb3VnaHQgdXAgdGhlIGlkZWEsIGRvZXMgaXQgZXZlbiByZWFsbHkgbWF0dGVyPyBJcyB0aGUgZGlmZmVyZW5jZSA1IHBwbSBvciAxMDAgcHBtPyAgQXJlIHRoZSBFU01zIGFuZCBIZWN0b3Igc2Vuc3RpdmUgZW5vdWdoIHRvIHRoZSBjYXJib24gY3ljbGUgZm9yIHRoZSBlbWlzc2lvbiBkcml2ZW4gcnVucyB0byBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgY29uY2VudHJhdGlvbiBkcml2ZW4gcnVucz8gQ291bGQgdGhlIGNsaW1hdGUgcGFyYW10ZXJpemF0aW9ucyBkbyBhbiBhZGVxdWF0ZSBqb2Igb2YgcmVwcmVzZW50aW5nIHRoZSBFU01zPyAKCjEuIElzIHRoZXJlIGEgZGlmZmVyZW5jZSBpbiB0aGUgZW1pc3Npb24gdnMgY29uY2VudHJhdGlvbiBkcml2ZW4gcnVucyBmb3IgdGhlIEVTTXMgYW5kIEhlY3Rvcj8gLyBIb3cgd2VsbCBkb2VzIHRoZSBjb25jZW5yYXRpb24gY2xpbWF0ZSBwYXJhbXRlcml6YXRpb25zIGRvIHdpdGggZW11bGF0aW5nIHRoZSBjYXJib24gY3ljbGU/IAoyLiBTb2x2aW5nIGZvciBiZXRhIGF0IGZpeGVkIHExMCB2YWx1ZXMuICAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvID0gRkFMU0V9CmxpYnJhcnkoaGVjdG9yKQpsaWJyYXJ5KGhlY3RvcmNhbCkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKRElSICA8LSAiL1VzZXJzL2RvcmgwMTIvRG9jdW1lbnRzLzIwMTkvaGVjdG9yY2FsL2FuYWx5c2lzL2Jlc3RfZml0L2Jlc3RGaXRfY29uY190ZW1wX2hlYXQyMTAwIiAgCkRJUjIgPC0gIi9Vc2Vycy9kb3JoMDEyL0RvY3VtZW50cy8yMDE5L2hlY3RvcmNhbC9hbmFseXNpcy9iZXN0X2ZpdC9yc2x0cy1pbmRldGlmaWFiaWxpdHlfcTEwX2JldGEiCmBgYAoKIyAxLiBJcyB0aGVyZSBhIGRpZmZlcmVuY2UgaW4gdGhlIGVtaXNzaW9uIHZzIGNvbmNlbnRyYXRpb24gZHJpdmVuIHJ1bnMgZm9yIHRoZSBFU01zIGFuZCBIZWN0b3I/IAoKYGBge3J9CiMgV2hhdCBtb2RlbHMgaGF2ZSBlc21pc3Npb24gZHJpdmVuIHJlc3VsdHM/IApjbWlwX2luZGl2aWR1YWwgJT4lICAKICAgIGZpbHRlcihncmVwbCgnZXNtJywgZXhwZXJpbWVudCkpICU+JSAKICAgIHB1bGwobW9kZWwpICU+JSAKICAgIHVuaXF1ZSgpIC0+IAogICAgZW1pc3Npb25fZHJpdmVuX21vZGVscwoKIyBJbXBvcnQgdGhlIGNvMiBjb25jZW50cmF0aW9uIGZvciB0aGUgY29uY2VudHJhdGlvbiBkcml2ZW4gcnVucyAoZnJvbSB0aGUgaGVjdG9yIGlucHV0cykuIAojIEZvcm1hdCB0aGUgZGF0YSBmcmFtZSBzbyB0aGF0IGl0IGhhcyB0aGUgbW9kZWwgbmFtZSBhbmQgZW5zZW1ibGUgaW5mb3JtYXRpb24uCnJlYWQuY3N2KHN5c3RlbS5maWxlKCdpbnB1dC9jb25zdHJhaW50cy9yY3A4NV9jbzJwcG0uY3N2JywgcGFja2FnZSA9ICdoZWN0b3InKSwgc2tpcCA9IDEpICU+JSAKICAgIHJlbmFtZSh5ZWFyID0gRGF0ZSwgdmFsdWUgPSBDYV9jb25zdHJhaW4pICU+JSAKICAgIG11dGF0ZShleHBlcmltZW50ID0gaWZfZWxzZSh5ZWFyIDw9IDIwMDUsICdoaXN0b3JpY2FsJywgJ3JjcDg1JyksIAogICAgICAgICAgIHZhcmlhYmxlID0gJ2NvMicpICU+JSAKICAgIG11dGF0ZShqb2luID0gMSkgJT4lIAogICAgbGVmdF9qb2luKHRpYmJsZShqb2luID0gMSwgCiAgICAgICAgICAgICAgICAgICAgIGVuc2VtYmxlID0gYygicjFpMXAxIiwgInIyaTFwMSIsICJyM2kxcDEiKSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgbGVmdF9qb2luKHRpYmJsZShqb2luID0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSBlbWlzc2lvbl9kcml2ZW5fbW9kZWxzKSwgIGJ5ID0gJ2pvaW4nKSwgCiAgICAgICAgICAgICAgYnkgPSAnam9pbicpICU+JSAKICAgIHNlbGVjdCgtam9pbikgLT4gCiAgICBjb25jZW50cmF0aW9uX2NvMl92YWx1ZXMKCiMgSW1wb3J0IHRoZSBDTUlQIEVTTSBkYXRhIGFuZCBtYWtlIHN1cmUgdGhhdCB0aGUgY29uY2VudHJhdGlvbiByZXN1bHRzIGRvZXMgbm90IGluY2x1ZGUgY28yLiAKY21pcF9pbmRpdmlkdWFsICU+JSAKICAgIGZpbHRlcihtb2RlbCAlaW4lIGVtaXNzaW9uX2RyaXZlbl9tb2RlbHMpICU+JSAKICAgIGZpbHRlcih5ZWFyIDw9IDIxMDAgJiBleHBlcmltZW50ICVpbiUgYygnaGlzdG9yaWNhbCcsICdyY3A0NScpKSAlPiUgCiAgICBmaWx0ZXIodmFyaWFibGUgIT0gJ2NvMicpICU+JSAKICAgIGJpbmRfcm93cyhjb25jZW50cmF0aW9uX2NvMl92YWx1ZXMpIC0+IAogICAgY29uY2VuY3RyYWlvbl9ybHN0CgojIEltcG9ydCB0aGUgQ01JUCBFU00gZW1pc3NzaW9uIGRyaXZlbiByZXN1bHRzLiAKY21pcF9pbmRpdmlkdWFsICU+JSAKICAgIGZpbHRlcihtb2RlbCAlaW4lIGVtaXNzaW9uX2RyaXZlbl9tb2RlbHMpICU+JSAKICAgIGZpbHRlcih5ZWFyIDw9IDIxMDAgJiBleHBlcmltZW50ICVpbiUgYygnZXNtSGlzdG9yaWNhbCcsICdlc21yY3A0NScpKSAlPiUgCiAgICBiaW5kX3Jvd3MoY29uY2VuY3RyYWlvbl9ybHN0KSAlPiUgCiAgICAgbXV0YXRlKGRyaXZlbiA9IGlmX2Vsc2UoZ3JlcGwoJ2VzbScsIGV4cGVyaW1lbnQpLCAnZW1pc3Npb25zJywgJ2NvbmNlbnRyYXRpb24nKSkgJT4lICAKICAgIHNlbGVjdCh5ZWFyLCBtb2RlbCwgZW5zZW1ibGUsIHZhcmlhYmxlLCB2YWx1ZSwgZHJpdmVuKSAlPiUgIAogICAgZGlzdGluY3QoKSAtPiAKICAgIGNtaXBfY29uY19lbWlzcwoKIyBDYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZW1pc3Npb24gZHJpdmVuIGFuZiB0aGUgY29uY2VudHJhdGlvbiBkcml2ZW4gcnVucy4gCmNtaXBfY29uY19lbWlzcyAlPiUgCiAgICB0aWR5cjo6c3ByZWFkKGRyaXZlbiwgdmFsdWUpICU+JSAKICAgIG5hLm9taXQgJT4lIAogICAgbXV0YXRlKGRpZiA9IGVtaXNzaW9ucyAtIGNvbmNlbnRyYXRpb24pIC0+IAogICAgZGlmZl9lbWlzX2NvbmMKYGBgCgojIyBIb3cgZG8gdGhlIEVTTSBlbWlzc2lvbiBkcml2ZW4gYW5kIGNvbmNlbnRyYXRpb24gcnVucyBkaWZmZXIgZnJvbSBvbmUgYW5vdGhlcj8gCgpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CmRpZmZfZW1pc19jb25jICU+JSAgCiAgICBnZ3Bsb3QoYWVzKGNvbmNlbnRyYXRpb24sIGVtaXNzaW9ucywgY29sb3IgPSBtb2RlbCkpICsgCiAgICBnZW9tX3BvaW50KCkgKyAKICAgIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgY29sID0gJ2JsYWNrJykgKwogICAgZmFjZXRfd3JhcCgndmFyaWFibGUnLCBzY2FsZXMgPSAnZnJlZScpICsgCiAgICBsYWJzKHkgPSAnZW1pc3Npb24gZHJpdmVuIEVTTScsIAogICAgICAgICB4ID0gJ2NvbmNlbnRyYXRpb24gZHJpdmVuIEVTTScpCgpgYGAKCgpUaGUgYmxhY2sgbGluZSBzaG93IHRoZSAxOjEgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHggYW5kIHkgYXhpcywgc28gaWYgdGhlIGVtaXNzaW9uIGRyaXZlbiBhbmQgY29uY2VudHJhdGlvbiBkcml2ZW4gcnVucyBhcmUgZmFpcmx5IHNpbWlsYXIgdG8gb25lIGFub3RoZXIgdGhlbiB3ZSB3b3VsZCBleHBlY3QgdGhlIHBhdHRlcm4gdG8gYmUgY2VudGVyZWQgYXJvdW5kIHRoZSBibGFjayBsaW5lIGxpa2Ugd2Ugc2VlIGluIGhlYXRmbHV4IGFuZCB0YXMuIEJ1dCBpdCBkb2VzIGxvb2sgbGlrZSB0aGUgZW1pc3Npb24gZHJpdmVuIHJ1bnMgaGF2ZSBhIGhpZ2hlciBjbzIgY29uY2VudHJhdGlvbiBmbyBhdCBsZWFzdCAyIG9mIHRoZSBtb2RlbHMuIGBDYW5FU00yYCBkb2VzIG5vdCBzZWVtIHRvIGJlIHBhcnRpY3Vhcmx5IHNlbnN0aXZlIHRvIHRoZSBjYXJib24gY3ljbGUgZmVlZGJhY2tzLiAKCgo8YnI+Cjxicj4KCldoYXQgaXMgdGhlIGRpZmZlcmVuY2UgYmV3dGVlbiB0aGUgcnVucz8gV2hhdCBkb2VzIHRoZSBub2lzZSBsb29rIGxpa2Ugb2YgdGhlIGNvbmMgYW5kIGVtaXNzaW9uIGRyaXZlbiBydW5zIGxvb2sgbGlrZT8gCgpgYGB7cn0KZGlmZl9lbWlzX2NvbmMgJT4lIAogICAgZ3JvdXBfYnkodmFyaWFibGUsIG1vZGVsKSAlPiUgCiAgICBzdW1tYXJpc2UobWluX2RpZiA9IG1pbihkaWYpLCAKICAgICAgICAgICAgICBtZWFuX2RpZiA9IG1lYW4oZGlmKSwgCiAgICAgICAgICAgICAgbWF4X2RpZiA9IG1heChkaWYpLCAKICAgICAgICAgICAgICBzZF9kaWYgPSBzZChkaWYpKSAlPiUgCiAgICB1bmdyb3VwKCkKCmBgYAoKPGJyPgo8YnI+CgojIyBIb3cgd2VsbCBkb2VzIHRoZSBFbWlzc2lvbiBIZWN0b3IgY2FsaWJyYXRlZCB3aXRoIGNsaW1hdGUgYmVzdCBmaXRzIG1vZGVscyB0aGUgZW1pc3Npb24gRVNNIG91dHB1dD8gCgpIb3cgZG9lcyB0aGUgdGVtcCBhbmQgY28yIGRhdGEgZm9yIEhlY3RvciBjYWxpYnJhdGVkIHdpdGggdGhlIHJlc3VsdHMgZnJvbSB0aGUgYGJlc3RGaXRfY29uY190ZW1wX2hlYXQyMTAwYCBjb21wYXJlIHdpdGggdGhlIGVtaXNzaW9uIGRyaXZlbiByZXN1bHRzPyAKCgpgYGB7cn0KcGF0aHMgICAgIDwtIGxpc3QuZmlsZXMoRElSLCBmdWxsLm5hbWVzID0gVFJVRSkgCnRvX2ltcG9ydCA8LSBwYXRoc1t3aGljaChncmVwbChwYXN0ZShlbWlzc2lvbl9kcml2ZW5fbW9kZWxzLCBjb2xsYXBzZSA9ICd8JyksIHBhdGhzKSldCgpsYXBwbHkodG9faW1wb3J0LCBmdW5jdGlvbihpbnB1dCl7CiAgICBvYmplY3QgPC0gcmVhZFJEUyhpbnB1dCkKICAgIAogICAgZGF0YS5mcmFtZShtYXRyaXgob2JqZWN0JG9wdGltX3JzbHQkcGFyLCBucm93ID0gMSwgZGltbmFtZXMgPSBsaXN0KE5VTEwsIG5hbWVzKG9iamVjdCRvcHRpbV9yc2x0JHBhcikpKSkgJT4lICAKICAgICAgICBtdXRhdGUobW9kZWwgPSBnc3ViKHBhdHRlcm4gPSAnY29uY198LnJkcycsIHJlcGxhY2VtZW50ID0gJycsIHggPSBiYXNlbmFtZShpbnB1dCkpKQp9KSAlPiUgCiAgICBiaW5kX3Jvd3MgLT4gCiAgICBwYXJhbXNfZGYKYGBgCgpDb21wYXJlIEhlY3RvciBlbWlzc2lvbnMgYW5kIEVTTSBlbWlzc2lvbiBkcml2ZW4gcnVuIHJlc3VsdHMuIEhvdyB3ZWxsIGRvZXMgdGhlIGNvbmNlbnJhdGlvbiBjbGltYXRlIHBhcmFtdGVyaXphdGlvbnMgZG8gd2l0aCBlbXVsYXRpbmcgdGhlIGNhcmJvbiBjeWNsZT8gCgpgYGB7cn0KCnBhdGggPC0gc3lzdGVtLmZpbGUoJ2lucHV0L2hlY3Rvcl9yY3A4NS5pbmknLCBwYWNrYWdlID0gJ2hlY3RvcicpCmNvcmUgPC0gbmV3Y29yZShwYXRoKQoKc3BsaXQoeCA9IHBhcmFtc19kZiwgZiA9IHBhcmFtc19kZiRtb2RlbCkgJT4lIAogICAgbGFwcGx5KGZ1bmN0aW9uKGlucHV0KXtwYXJhbXMgPC0gaW5wdXRbd2hpY2gobmFtZXMoaW5wdXQpICE9ICdtb2RlbCcpXQpwYXJhbWV0ZXJpemVfY29yZShwYXJhbXMgPSBwYXJhbXMsIGNvcmUgPSBjb3JlKQpyZXNldChjb3JlKQpydW4oY29yZSwgcnVudG9kYXRlID0gMjEwMCkKZmV0Y2h2YXJzKGNvcmUsIDE4NTA6MjEwMCwgdmFycyA9IGMoSEVBVF9GTFVYKCksIEdMT0JBTF9URU1QKCksIEFUTU9TUEhFUklDX0NPMigpKSkgJT4lIAogICAgbXV0YXRlKGV4cGVyaW1lbnQgPSBpZl9lbHNlKHllYXIgPCAyMDA1LCAnZXNtSGlzdG9yaWNhbCcsICdlc21yY3A4NScpLCAKICAgICAgICAgICBtb2RlbCA9IGlucHV0W1snbW9kZWwnXV0pICU+JSAgCiAgICBtdXRhdGUoc2NlbmFyaW8gPSAnaGVjdG9yJykgJT4lIAogICAgbXV0YXRlKHZhcmlhYmxlID0gaWZfZWxzZSh2YXJpYWJsZSA9PSAnVGdhdicsICd0YXMnLCB2YXJpYWJsZSkpICU+JSAKICAgIG11dGF0ZSh2YXJpYWJsZSA9IGlmX2Vsc2UodmFyaWFibGUgPT0gJ0NhJywgJ2NvMicsIHZhcmlhYmxlKSkKfSkgJT4lICAKICAgIGJpbmRfcm93cygpIC0+IAogICAgZW1pc3Npb25faGVjdG9yCgplbWlzc2lvbl9oZWN0b3IgJT4lIAogICAgYmluZF9yb3dzKGNtaXBfaW5kaXZpZHVhbCAlPiUgIAogICAgICAgICAgICAgICAgICBtdXRhdGUoc2NlbmFyaW8gPSAnY21pcCcpKSAlPiUgCiAgICBmaWx0ZXIoZ3JlcGwoJ2VzbScsIGV4cGVyaW1lbnQpKSAtPiAKICAgIGVtaXNzaW9uX2hlY3Rvcl9vdXRwdXQgCgplbWlzc2lvbl9oZWN0b3Jfb3V0cHV0ICU+JSAKICAgIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gc2NlbmFyaW8sIGxpbmV0eXBlID0gbW9kZWwpKSArIAogICAgZ2VvbV9saW5lKCkgKyAKICAgIGZhY2V0X2dyaWQodmFyaWFibGUgfiBtb2RlbCwgc2NhbGVzID0gJ2ZyZWUnKSAKCmBgYAoKCiMjIEhvdyBtdWNoIGRvZXMgdGhlIGNhcmJvbiBjeWNsZSBpbXBhY3QgSGVjdG9yIG91dHB1dD8gCgpgYGB7cn0KYmluZF9yb3dzKGVtaXNzaW9uX2hlY3Rvcl9vdXRwdXQgJT4lICBtdXRhdGUocnVuID0gJ2VtaXNzaW9uJyksIAogICAgICAgICAgY29uY2VudHJhdGlvbl9oZWN0b3Jfb3V0cHV0ICU+JSBtdXRhdGUocnVuID0gJ2NvbmNlbnRyYXRpb24nKSkgJT4lIAogICAgZmlsdGVyKGdyZXBsKCdoZWN0b3InLCBzY2VuYXJpbykpIC0+IAogICAgdG9fcGxvdCAKCnRvX3Bsb3QgJT4lIAogICAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBydW4sIGdyb3VwID0gZXhwZXJpbWVudCkpICsgCiAgICBnZW9tX2xpbmUoKSArIAogICAgZmFjZXRfZ3JpZCh2YXJpYWJsZX5tb2RlbCwgc2NhbGUgPSAnZnJlZScpCgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9CnRvX3Bsb3QgJT4lIAogICAgc2VsZWN0KHllYXIsIHZhcmlhYmxlLCB2YWx1ZSwgbW9kZWwsIHJ1bikgJT4lIAogICAgc3ByZWFkKHJ1biwgdmFsdWUpICU+JSAgCiAgICBnZ3Bsb3QoYWVzKGNvbmNlbnRyYXRpb24sIGVtaXNzaW9uLCBjb2xvciA9IG1vZGVsKSkgKwogICAgZ2VvbV9wb2ludCgpICsgCiAgICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDEpICsKICAgIGZhY2V0X3dyYXAoJ3ZhcmlhYmxlJywgc2NhbGVzID0gJ2ZyZWUnKSArIAogICAgICBsYWJzKHkgPSAnZW1pc3Npb24gZHJpdmVuIEVTTScsIAogICAgICAgICB4ID0gJ2NvbmNlbnRyYXRpb24gZHJpdmVuIEVTTScpCmBgYAoKSSBndWVzcyBJIGRvIG5vdCBrbm93IGlmIHRoaXMgc29ydCBvZiBkaWZmZXJlbmNlIHJlYWxseSBzZWVtcyBsaWtlIGl0IGlzIHRoYXQgbm90YWJsZSB0byBtZS4gV2hhdCBkbyB5b3UgZ3V5cyB0aGluaz8KCgojIDIuIFNvbHZpbmcgZm9yIGJldGEgYXQgZml4ZWQgcTEwIHZhbHVlcy4gCgpgYGB7cn0KbGlzdC5maWxlcyhESVIyLCAnLnJkcycsIGZ1bGwubmFtZXMgPSBUUlVFKSAlPiUgCiAgICBsYXBwbHkoZnVuY3Rpb24oaW5wdXQpe3JlYWRSRFMoaW5wdXQpW1snaGVjdG9yX291dHB1dCddXX0pICU+JSAKICAgIGJpbmRfcm93cygpICU+JSAKICAgIG11dGF0ZShiZXRhID0gc2lnbmlmKGJldGEsIGRpZ2l0cyA9IDMpLCAKICAgICAgICAgICBxMTAgPSBzaWduaWYocTEwLCBkaWdpdHMgPSAzKSwgCiAgICAgICAgICAgYmV0YV9xMTAgPSBwYXN0ZTAoYmV0YSwgJ18nLCBxMTApKSAlPiUgCiAgICBmaWx0ZXIoc2NlbmFyaW8gPT0gJ2VzbXJjcDg1JykgJT4lICAKICAgIG11dGF0ZSh2YXJpYWJsZSA9IGlmX2Vsc2UodmFyaWFibGUgPT0gJ1RnYXYnLCAndGFzJywgdmFyaWFibGUpKSAlPiUgIAogICAgbXV0YXRlKHZhcmlhYmxlID0gaWZfZWxzZSh2YXJpYWJsZSA9PSAnQ2EnLCAnY28yJywgdmFyaWFibGUpKS0+IAogICAgdG9fcGxvdApgYGAKCgpIb3cgbXVjaCBkbyB0aGUgYmV0YSBhbmQgcTEwIHZhbHVlcyByYW5nZT8gCgpgYGB7cn0Kc3VtbWFyeSh0b19wbG90JGJldGEpCmBgYAoKVGhlIGJldGEgdmFsdWVzIHRoYXQgb3B0aW0gc29sdmVkIGZvciBkbyBub3Qgc3BhbiB0aGUgcmFuZ2Ugd2Ugc2VlIGluIHRoZSBET0UgUEkgbWVldGluZyBtY21jIFBERnMuLi4gd2hpY2ggSSB0aGluayBpdCBjdXJpb3VzLCB2ZXJ5IGN1cmlvcy4gCgpgYGB7cn0Kc3VtbWFyeSh0b19wbG90JHExMCkKYGBgCgoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQpnZ3Bsb3QoKSArIAogICAgZ2VvbV9saW5lKGRhdGEgPSBjbWlwX2luZGl2aWR1YWwgJT4lIGZpbHRlcihncmVwbCgnZXNtJywgZXhwZXJpbWVudCkgJiBtb2RlbCA9PSAnQ0VTTTEtQkdDJykgJT4lICAKICAgICAgICAgICAgICAgICAgbXV0YXRlKGJldGFfcTEwID0gJ2NtaXAnKSwgIAogICAgICAgICAgICAgIGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBiZXRhX3ExMCksIAogICAgICAgICAgICAgIGNvbG9yID0gJ2dyZXknLCBzaXplID0gMikgKwogICAgZ2VvbV9saW5lKGRhdGEgPSB0b19wbG90LCBhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gYmV0YV9xMTApLCBhbHBoYSA9IDAuNSkgKwogICAgZmFjZXRfd3JhcCgndmFyaWFibGUnLCBzY2FsZSA9ICdmcmVlJykgKyAKICAgIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE4KSArIAogICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgCmBgYAoKV2Ugc2VlIGEgbGFyZ2UgcmFuZ2UgaW4gdGhlIHBvdGVudGlhbCBxMTAgYW5kIGJldGEgdmFsdWVzLCBhbmQgdGhleSByZXN1bHRzIGFyZSBmYWlybHkgc2ltaWxhciB0byBvbmUgYW5vdGhlciwgdGhleSBmYWxsIHdpdGhpbiB0aGUgcmFuZ2Ugb2YgdGhlIGNtaXAgZGF0YSBlc3BlY2lhbGx5IGZvciB0aGUgdGFzIGRhdGEuIEZvciB0aGUgY28yIGRhdGEgaXQgaXMgc29tZSB3aGF0IGhhcmQgdG8gc2VlIGJ1dCB0aGUgc29sdmVkIGhlY3RvciBydW5zIHdpdGggdGhlIHZhcmlvdXMgYmV0YSBhbmQgcTEwIHZhbHVlcyBkbyBmYWxsIG9uIHRvcCBvZiB0aGUgZXNtIGNtaXAgZGF0YS4gV2hpY2ggY29uZmlybXMgb3VyIHN1c3BpY2lvbiB0aGF0IGJldGEgYW5kIHExMCBhcmUgY2FwYWJsZSBvZiB0cmFkaW5nIG9mZiB3aXRoIG9uZSBhbm90aGVyLgo=