1 Objective

Here we are comparing Hector’s RF with the RF results from AR6 the objectives of the document are as follows

  • validate the update to the AR6 RF modeling
  • where Hector v3 and AR6 RF values are not identical determine why

1.1 Set Up

library(data.table)
library(dplyr)
library(ggplot2)
library(hector)
library(knitr)
library(kableExtra)
library(tidyr)
theme_set(theme_bw())
DIR <- "/Users/dorh012/Documents/2021/2021-hector-ar6rf"

1.2 Hector Results

run_hector_ssp <- function(ini){
    
    vars <- c(RF_CO2(), RF_CH4(), RF_N2O(), RF_O3_TROP(), RF_H2O_STRAT(), RF_ACI(),
              RF_VOL(), RF_TOTAL(), RF_HFC134A(), RF_HFC23(),
              RF_HFC32(), RF_HFC125(), RF_HFC143A(), RF_HFC227EA(), RF_HFC245FA(),
              RF_SF6(), RF_CF4(), RF_CFC11(),
              RF_CFC113(), RF_CFC114(), RF_CFC115(), RF_BC(), RF_SO2(), 
              RF_OC(), RF_NH3(), ATMOSPHERIC_N2O(), GLOBAL_TEMP(), RF_T_ALBEDO(), 
              RF_CF4(), RF_C2F6(), RF_HFC23(), RF_HFC32(), RF_HFC4310(), RF_HFC125(),
              RF_HFC134A(), RF_HFC143A(), RF_HFC227EA(), RF_HFC245FA(), RF_SF6(),
              RF_CFC11(), RF_CFC12(), RF_CFC113(), RF_CFC114() , RF_CFC115(), RF_CCL4(),
              RF_CH3CCL3(), RF_HCFC22(), RF_HCFC141B(), RF_HCFC142B(), RF_HALON1211(), 
              RF_HALON1301(), RF_HALON2402(), RF_CH3CL(), RF_CH3BR(), ATMOSPHERIC_CH4(), RF_MISC(),
              GLOBAL_TEMP()) 
    
    name <- gsub(pattern = "hector_|.ini", replacement = "", x = basename(ini))
    core <- newcore(ini, name = name)
    run(core, runtodate = 2100)
    out <- fetchvars(core, 1745:2100, vars)
    
    return(out)
    
}
list.files(file.path(DIR, "input"), pattern = "ini", full.names = TRUE) %>% 
  lapply(run_hector_ssp) %>% 
  bind_rows() %>%  
  mutate(driven = ifelse(grepl(pattern = "-GHG", scenario), "GHG", "emiss")) %>% 
  mutate(driven = ifelse(grepl(pattern = "-rf", scenario), "RF", driven)) %>% 
  mutate(scenario = gsub(pattern = "-rf", replacement = "", x = scenario)) %>%  
  mutate(scenario = gsub(pattern = "-GHG", replacement = "", x = scenario))-> 
  hector_out
Error in RF_ACI() : could not find function "RF_ACI"

1.3 AR6 Results

format_data <- function(path){
  
  x <- gsub(pattern = ".csv", replacement = "", x = basename(path))
  xx <- unlist(strsplit(x, split = "_"))
  
  if (length(xx) == 3 ){
    out <- as.data.frame(matrix(xx, nrow = 1, dimnames = list(NULL, c("output", "scn", "time"))))
  }
  
  if (length(xx) == 4 ){
    out <- as.data.frame(matrix(xx, nrow = 1, dimnames = list(NULL, c("output", "scn", "time", "percent"))))
  }
  
  return(out)
  
}
get_cmip_data <- function(path){
  
  dat <- read.csv(path, stringsAsFactors = FALSE)
  info <- format_data(path)
  
  dat %>% 
    melt(id.vars = c( "year"), 
         variable.name = "variable", value.name = "value") %>% 
    cbind(info) -> 
    out
  
  return(out)
}
files   <- list.files(file.path(DIR,"SSPs"), pattern = "ERF", full.names = TRUE)  
files %>% 
    lapply(get_cmip_data) %>% 
    bind_rows() %>% 
    select(year, variable, value, scenario = scn, percent) %>% 
    as.data.table() %>% 
    dplyr::filter(is.na(percent))  -> 
    ar6_data_og
ar6_names <- c("co2","ch4","n2o","o3","h2o_stratospheric","aerosol.cloud_interactions",
               "volcanic","total", "HFC.134a","HFC.23","HFC.32","HFC.125","HFC.143a", 
               "HFC.227ea", "HFC.245fa", "SF6","CF4","CFC.11", "CFC.113", 
               "CFC.114", "CFC.115", "land_use", "solar", "bc_on_snow", "contrails",
               "aerosol.radiation_interactions")
hector_names <- c(RF_CO2(), RF_CH4(), RF_N2O(), RF_O3_TROP(), RF_H2O_STRAT(), RF_ACI(),
                  RF_VOL() ,RF_TOTAL(), RF_HFC134A(),RF_HFC23(), RF_HFC32(), RF_HFC125(),
                  RF_HFC143A(), RF_HFC227EA(), RF_HFC245FA(), RF_SF6(), RF_CF4(),
                  RF_CFC11(), RF_CFC113(), RF_CFC114(), RF_CFC115(), RF_T_ALBEDO(), 
                  RF_MISC(), RF_MISC(), RF_MISC(), "ari") 
ar6_data_og %>% 
  filter(variable %in% ar6_names) %>%
  left_join(data.frame(variable = ar6_names, 
                       hvar = hector_names)) %>% 
  select(year, variable = hvar, value, scenario) %>%  
  filter(scenario %in% hector_out$scenario) %>% 
  mutate(driven = "AR6") %>% 
  group_by(year, variable, scenario, driven) %>%  
  summarise(value = sum(value)) %>%  
  ungroup -> 
  ar6_results_1
# Read in and format the halo-carbon RF. 
files   <- list.files(file.path(DIR,"SSPs"), pattern = "minorGHGs", full.names = TRUE)  
lapply(files, function(x){
  
  name <- gsub(x = basename(x), pattern = "ERF_|_minorGHGs_1750-2500.csv", replacement = "" )
read.csv(x) %>% 
  as.data.table() %>%
  pivot_longer(!year, names_to = "variable", values_to = "value") %>% 
  mutate(variable = gsub(pattern = "\\.", replacement = "", x = variable)) %>%
  mutate(variable = paste0("F", variable)) %>%
  mutate(variable = ifelse(grepl(pattern = "Halon", variable), 
                           gsub(replacement = "halon", pattern = "Halon", variable), variable)) %>% 
  mutate(scenario = name)
  
}) %>% 
  bind_rows() -> 
  ar6_results_2
  
ar6_results <- bind_rows(ar6_results_1, ar6_results_2)
ar6_results$source <- "AR6"
ar6_results$driven <- "AR6"
# A data frame of the hector annd AR6 output results! 
data <- bind_rows(hector_out, ar6_results) 
# Figure out the percent difference btween the Hector and AR6 results! 
data %>%  
  filter(driven == "AR6" & source == "AR6") %>%  
  select(scenario, year, variable, AR6 = value) %>% 
  distinct() -> 
  AR6_variable_output
# Calculate the percent difference from the AR6 output. 
data %>%
  filter(driven %in% c("emiss", "GHG")) %>% 
  full_join(AR6_variable_output) %>% 
  select(scenario, year, driven, value, variable, AR6) %>% 
  na.omit() %>% 
  mutate(value = 100 * (value - AR6) / AR6) %>% 
  select(scenario, year, driven, value, variable) %>% 
  mutate(units = "% diff. from AR6 output") %>% 
  mutate(scenario = if_else(year < 2014, "historical", scenario)) -> 
  percent_difference
  
# How much of the total RF does the difference represent? 
data %>%  
  filter(driven == "AR6" & source == "AR6") %>%  
  filter(variable == RF_TOTAL()) %>% 
  select(scenario, year, AR6_total = value) %>% 
  distinct() -> 
  AR6_total
# Now calculate how much of the total AR6 RF does this represent? 
data %>%
  filter(driven %in% c("emiss", "GHG")) %>% 
  full_join(AR6_variable_output) %>% 
  select(scenario, year, driven, value, variable, AR6) %>% 
  na.omit() %>% 
  left_join(AR6_total) %>% 
  mutate(value = 100 * (value - AR6)/ AR6_total) %>%  
  select(scenario, year, driven, value, variable) %>% 
  mutate(units = "% diff. / AR6 total") -> 
  percent_diff_of_totals

2 Big Picture

  • RF CO2 ❓
  • RF N2O ❓
  • RF CH4 ✅
  • RF O3 Trop 🆗 no update in Hector
  • RF H2O strat ❓ looks okay historical not great in the future periods
  • RF Faci 👎
  • RF Ari 🆗
  • RF Fvol ✅
  • RF F halocarbons 🆗
  • RF Falbedo ✅
  • RF Fmisc ✅

2.1 Total RF & Temperature

How much does total RF differ by and what does that mean in terms of temperature?

hector_out %>% 
  filter(variable %in% c(RF_TOTAL(), GLOBAL_TEMP())) %>% 
  mutate(driven = if_else(driven == "RF", "AR6", driven)) %>%
  ggplot() + 
  geom_line(aes(year, value, color = driven, groupby = scenario)) + 
  labs(title = "AR6 vs Hector Comparison", 
       x = "Year") + 
  facet_wrap("variable", scales = "free") +
  theme(legend.title = element_blank())

The differnces in total RF results in a temperature that differ by a tenth of a degree.

hector_out %>% 
  filter(variable %in% c(RF_TOTAL(), GLOBAL_TEMP())) %>% 
  mutate(driven = if_else(driven == "RF", "AR6", driven)) %>%
  select(scenario, year, driven, value, variable) %>% 
  distinct() %>% 
  spread(driven, value) %>% 
  mutate(emiss = (emiss - AR6), 
         GHG =  (GHG - AR6)) %>% 
  ggplot() + 
  geom_line(aes(year, emiss, groupby = scenario, linetype = scenario, color = "emiss")) + 
  geom_line(aes(year, GHG, groupby = scenario, linetype = scenario, color = "GHG")) + 
  labs(x = "Year", 
       y = "Difference") + 
  facet_wrap("variable", scales = "free") 

What does the percent difference look like?

hector_out %>% 
  filter(variable %in% c(RF_TOTAL(), GLOBAL_TEMP())) %>% 
  mutate(driven = if_else(driven == "RF", "AR6", driven)) %>%
  select(scenario, year, driven, value, variable) %>% 
  distinct() %>% 
  spread(driven, value) %>% 
  mutate(emiss =  100 * (emiss - AR6) / AR6, 
         GHG =  100 * (GHG - AR6) / AR6) %>% 
  pivot_longer(c(emiss, GHG), names_to = "driven", values_to = "value") -> 
  difference_tgav_rf
difference_tgav_rf %>% 
  filter(year >= 2014) %>% 
  distinct() %>% 
  ggplot() + 
  geom_line(aes(year, value, color = driven, groupby = scenario, linetype = scenario)) + 
  labs(title = "(X - AR6)/AR6", 
       x = "Year", 
       y = "%") + 
  facet_wrap("variable") 

A 5 % change in the future global temperature.

percent_difference %>% 
  filter(variable == RF_TOTAL()) %>% 
  group_by(scenario, variable, units, driven) %>% 
  summarise(mean = mean(value, na.rm = TRUE)) %>% 
  pivot_wider(names_from = driven, values_from = mean) %>% 
  kable(digits = 3) %>% 
  kable_styling()
scenario variable units emiss GHG
historical Ftot % diff. from AR6 output -19.702 7.059
ssp119 Ftot % diff. from AR6 output 2.247 2.558
ssp126 Ftot % diff. from AR6 output 5.365 2.395
ssp245 Ftot % diff. from AR6 output 4.234 1.615
ssp370 Ftot % diff. from AR6 output 2.758 0.444
ssp434 Ftot % diff. from AR6 output 0.789 0.128
ssp460 Ftot % diff. from AR6 output 2.439 0.767
ssp534-over Ftot % diff. from AR6 output 2.534 1.485
ssp585 Ftot % diff. from AR6 output 3.505 1.079

What is our biggest problem??? Ignoring the historical period for now.

percent_diff_of_totals %>%
  filter(year >= 2018) %>% 
  filter(driven == "GHG") %>% 
  filter(variable != RF_TOTAL()) %>% 
  ggplot(aes(year, value, color = variable, groupby = scenario)) + 
  geom_line()

Which of the differnces between Hector & AR6 RF makes up the largest portion or percentage of the total AR6 RF.

percent_diff_of_totals %>%
  filter(driven == "GHG" & variable != RF_TOTAL()) %>% 
  filter(year > 2016) %>% 
  group_by(scenario, variable) %>% 
  summarise(mean = mean(value), sd = sd(value)) %>% 
  ungroup %>% 
  group_by(variable) %>% 
  summarise(mean = mean(mean)) %>% 
  arrange(desc(abs(mean))) %>% 
  kable() %>% 
  kable_styling()
variable mean
Faci 1.5589220
FCO2 0.6065983
FN2O -0.3359772
FCFC12 -0.1667583
FO3_trop -0.0780491
FCFC11 -0.0605428
FH2O_strat 0.0530474
FCCl4 0.0388072
FHFC125 -0.0321915
FCH4 -0.0320444
ari 0.0312118
FCFC113 -0.0226616
FHCFC22 -0.0219828
FHFC134a -0.0150403
FSF6 -0.0125557
FHFC143a -0.0112304
FCF4 -0.0091429
FHFC23 -0.0088893
FCFC114 -0.0066638
FCFC115 -0.0034864
FHCFC141b -0.0032827
FHCFC142b -0.0029106
FC2F6 -0.0024139
FCH3Cl 0.0014011
Fhalon1301 -0.0010669
FHFC32 -0.0010259
Fhalon1211 -0.0007799
FHFC227ea -0.0006600
FHFC245fa -0.0005684
Fhalon2402 -0.0001053
FCH3CCl3 -0.0000724
FCH3Br 0.0000648
Fmisc 0.0000000
Ftalbedo 0.0000000
Fvol 0.0000000

The top four culprits is the forcing from cloud interactions (F aci), CO2, N2O, and trop O3. What would be really helpful would be for you to take a look and provide input, do you think these discrepancies are large enough to be a problem? Or are we okay with them?

3 Major GHGs

Let’s take a look at the major GHGs, CO2, N2O, and CH4. For these plots we are intrested in comparing the AR6 results vs the concentration driven Hector (the GHG plot in the runs). The purpose here is to show that the we have implented the AR6’s concentration to RF step for these three GHGs correctly.

3.1 CO2

data %>% 
  filter(variable == RF_CO2()) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("GHG", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line()

The percent difference between CO2 constrained Hector & AR6 CO2 RF. Honestly the difference of 2% in RF is more than I was expecting espcially since the concentration values are identical & we are using the same functional form at the AR6 report so it is surprising to me that we would see this level of difference, does not seem like just numerical error and since CO2 RF is such a large and important part of the overall RF balance I am conflicted. I have double and tripple checked, BBL & SJS what do you think?

data %>% 
  filter(variable == RF_CO2()) %>%  
  filter(year <= 2100) %>% 
  filter(year != 2015) %>% 
  filter(driven %in% c("GHG", "AR6")) %>% 
  mutate(scenario = if_else(year <= 2015, "historical", scenario)) %>% 
  select(scenario, year, driven, value, variable) %>% 
  distinct() %>%  
  spread(driven, value) %>%
  mutate(percent =  100 * (GHG - AR6)/AR6) %>% 
  ggplot(aes(year, percent)) + 
  geom_line()

Here is the functional form for the CO2 RF with the parameters if that is something that interests you

IPCC AR6 SM 7.SM.1 table

3.2 N2O

var <- RF_N2O()
data %>% 
  dplyr::filter(variable == var) %>%  
  dplyr::filter(year <= 2100) %>% 
  dplyr::filter(driven %in% c("GHG", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%
  dplyr::filter(variable == RF_N2O()) %>%
  dplyr::filter(driven == "GHG") %>%
  group_by(scenario, driven, variable) %>%
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%
  filter(variable == var & driven == "GHG") %>%
  group_by(scenario, driven, variable) %>%
  summarise(value = mean(value, na.rm = TRUE))

So it is not great that Hector under estimated RF by 4 percent out of total RF it is somewhat small. Regardless I am not thrilled by how different it is.

Looking over the constants values and the functional form from the IPCC AR6 report.

IPCC AR6 SM 7.SM.1 table IPCC AR6 SM 7.SM.1 table cont

I am at a lost as to what is wrong, but BBL & SJS what do you think? Do you have any ideas as to what could be wrong? Do you thikn it is a problem?

3.3 CH4

var <- RF_CH4()
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("GHG", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

Because the percent error is different on the concentration drien run I am less than thrilled what could be causing this probelm? Either an incorect functional form or some issue with convverting the N2O units to the N which is what we use with Hector.

Eyeballing it it the CH4 output looks great, and the percent differnce between AR6 & Hector CH4 RF is less than 1% in the future scenarios

percent_difference %>%  
  filter(variable == var & driven == "GHG") %>%  
  mutate(scenario = if_else(year <= 2015, "historical", scenario)) %>% 
  distinct() %>% 
  ungroup() %>% 
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

Comparing the difference betwee the Hector CH4 RF and AR6 CH4 RF compared to the total AR6 RF this is a really small percent.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "GHG") %>%  
  mutate(scenario = if_else(year <= 2015, "historical", scenario)) %>% 
  distinct() %>% 
  ungroup() %>% 
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

4 Minor GHGs

4.1 FO3_trop

var <- RF_O3_TROP()
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("GHG", "emiss")) %>% 
  ggplot(aes(year, value, color = scenario, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "GHG") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "GHG") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

Troposphere O3 doesn’t look great, all though this discrepancy overall makes up a small percentage of the total RF.

4.2 FH2O_strat

AR6 did not do an update, here we scaled estimates to AR6 in 2014 with the 2014 methane concentration. We used this relationship to estimate RF. While this works well for the historical and some of the future scearios it is does not work equally well for some of the larger EOC RF.

var <- RF_H2O_STRAT()
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("GHG", "AR6")) %>% 
  ggplot(aes(year, value, color = scenario, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "GHG") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "GHG") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

5 Aerosols

5.1 Faci

ERF from aerosol-cloud interactions (ERFaci) Equation 7.SM.1.2

ERF aci = - beta (1 + emissions SO2/param SO2 + (emissions BC + OC) / param BCOC)

var <- RF_ACI()
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = scenario, linetype = driven, groupby = scenario)) +
  geom_vline(xintercept = 2015, alpha = 0.4) + 
  geom_line() + 
  labs(title = var) 

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

This does not look good, because the ari looks especially during the futture period it where we know that we used the same emission leads be to conclude that this is not being caused by a difference in emissions. Which leads me to belive it has to do with a parameter value? SJS do you have any ideas?

5.2 Ari

ERF ari = (beta BC)(emissions BC) + (beta OC)(emissions OC) + (beta NH3)(emissions NH3) : Equation 7.SM.1.1

var <- "ari"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_vline(xintercept = 2015, alpha = 0.4) + 
  geom_line() + 
  labs(title = var) 

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var) %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

So it is not surprising to me that that the largest difference between Hector and the AR6 outputs because it sounds like we might have have used different historic time sereis for areosol emissions.

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6 Halocarbons

6.1 FHFC134a

var <- "FHFC134a"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.2 FHFC23

var <- "FHFC23"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.3 FHFC32

var <- "FHFC32"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.4 FHFC125

var <- "FHFC125"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.5 FHFC143a

var <- "FHFC143a"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.6 FHFC227ea

var <- "FHFC227ea"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.7 FHFC245fa

var <- "FHFC245fa"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.8 FSF6

var <- "FSF6"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.9 FCF4

var <- "FCF4"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.10 FCFC11

var <- "FCFC11"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.11 FCFC113

var <- "FCFC113"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.12 FCFC114

var <- "FCFC114"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.13 FCFC115

var <- "FCFC115"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.14 FC2F6

var <- "FC2F6"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.15 FCFC12

var <- "FCFC12"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.16 FCCl4

var <- "FCCl4"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.17 FCH3CCl3

var <- "FCH3CCl3"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.18 FHCFC22

var <- "FHCFC22"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.19 FHCFC141b

var <- "FHCFC141b"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.20 FHCFC142b

var <- "FHCFC142b"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.21 Fhalon1211

var <- "Fhalon1211"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.22 Fhalon1301

var <- "Fhalon1301"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.23 Fhalon2402

var <- "Fhalon2402"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.24 FCH3Cl

var <- "FCH3Cl"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.25 FCH3Br

var <- "FCH3Br"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

6.26 FHFC4310mee

var <- c("FHFC4310mee", "FHFC4310")
data %>% 
  filter(variable %in% var) %>% 
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

7 Other forcings

7.1 Fvol

var <- "Fvol"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

Great! looks like there is a 0% difference!

7.2 Ftalbedo

var <- "Ftalbedo"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

Great no difference!

7.3 Fmisc

var <- "Fmisc"
data %>% 
  filter(variable == var) %>%  
  filter(year <= 2100) %>% 
  filter(driven %in% c("emiss", "AR6")) %>% 
  ggplot(aes(year, value, color = driven, linetype = driven, groupby = scenario)) +
  geom_line() + 
  labs(title = var)

The percent difference bewtween Hector FN2O and AR6 FN2O.

percent_difference %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

The difference bewtween Hector FN2O and AR6 FN2O compared to the total AR6 RF.

percent_diff_of_totals %>%  
  filter(variable == var & driven == "emiss") %>%  
  group_by(scenario, driven, variable) %>% 
  summarise(value = mean(value, na.rm = TRUE))

Great there is no difference!

8 Hector v Hector

How do these changes affect Hector output? I’ve run Hector v 2.5 with the SPPs and Hector v3 updated with the AR6 functions and parameterizations. Comparing the total RF and major GHG outputs Hector v3 runs at a higher RF which means that it will be also be warmer.

var <- RF_TOTAL()
hector_v_hector %>%  
  filter(variable == var) %>% 
  mutate(version = as.character(version)) %>% 
  ggplot(aes(year, value, color = version, linetype = scenario)) + 
  geom_line() + 
  labs(title = var)

var <- RF_CO2()
hector_v_hector %>%  
  filter(variable == var) %>% 
  mutate(version = as.character(version)) %>% 
  ggplot(aes(year, value, color = version, linetype = scenario)) + 
  geom_line() + 
  labs(title = var)

var <- RF_CH4()
hector_v_hector %>%  
  filter(variable == var) %>% 
  mutate(version = as.character(version)) %>% 
  ggplot(aes(year, value, color = version, linetype = scenario)) + 
  geom_line() + 
  labs(title = var)

var <- RF_N2O()
hector_v_hector %>%  
  filter(variable == var) %>% 
  mutate(version = as.character(version)) %>% 
  ggplot(aes(year, value, color = version, linetype = scenario)) + 
  geom_line() + 
  labs(title = var)

LS0tCnRpdGxlOiAiQ29tcGFyaW5nIEhlY3RvciBBUjYiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCi0tLQoKIyBPYmplY3RpdmUgCgpIZXJlIHdlIGFyZSBjb21wYXJpbmcgSGVjdG9yJ3MgUkYgd2l0aCB0aGUgUkYgcmVzdWx0cyBmcm9tIEFSNiB0aGUgb2JqZWN0aXZlcyBvZiB0aGUgZG9jdW1lbnQgYXJlIGFzIGZvbGxvd3MgCgoqIHZhbGlkYXRlIHRoZSB1cGRhdGUgdG8gdGhlIEFSNiBSRiBtb2RlbGluZyAKKiB3aGVyZSBIZWN0b3IgdjMgYW5kIEFSNiBSRiB2YWx1ZXMgYXJlIG5vdCBpZGVudGljYWwgZGV0ZXJtaW5lIHdoeQoKCiMjIFNldCBVcCAKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQpgYGAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGhlY3RvcikKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KHRpZHlyKQoKdGhlbWVfc2V0KHRoZW1lX2J3KCkpCgpESVIgPC0gIi9Vc2Vycy9kb3JoMDEyL0RvY3VtZW50cy8yMDIxLzIwMjEtaGVjdG9yLWFyNnJmIgpgYGAKCgojIyBIZWN0b3IgUmVzdWx0cwoKYGBge3J9CnJ1bl9oZWN0b3Jfc3NwIDwtIGZ1bmN0aW9uKGluaSl7CiAgICAKICAgIHZhcnMgPC0gYyhSRl9DTzIoKSwgUkZfQ0g0KCksIFJGX04yTygpLCBSRl9PM19UUk9QKCksIFJGX0gyT19TVFJBVCgpLCBSRl9BQ0koKSwKICAgICAgICAgICAgICBSRl9WT0woKSwgUkZfVE9UQUwoKSwgUkZfSEZDMTM0QSgpLCBSRl9IRkMyMygpLAogICAgICAgICAgICAgIFJGX0hGQzMyKCksIFJGX0hGQzEyNSgpLCBSRl9IRkMxNDNBKCksIFJGX0hGQzIyN0VBKCksIFJGX0hGQzI0NUZBKCksCiAgICAgICAgICAgICAgUkZfU0Y2KCksIFJGX0NGNCgpLCBSRl9DRkMxMSgpLAogICAgICAgICAgICAgIFJGX0NGQzExMygpLCBSRl9DRkMxMTQoKSwgUkZfQ0ZDMTE1KCksIFJGX0JDKCksIFJGX1NPMigpLCAKICAgICAgICAgICAgICBSRl9PQygpLCBSRl9OSDMoKSwgQVRNT1NQSEVSSUNfTjJPKCksIEdMT0JBTF9URU1QKCksIFJGX1RfQUxCRURPKCksIAogICAgICAgICAgICAgIFJGX0NGNCgpLCBSRl9DMkY2KCksIFJGX0hGQzIzKCksIFJGX0hGQzMyKCksIFJGX0hGQzQzMTAoKSwgUkZfSEZDMTI1KCksCiAgICAgICAgICAgICAgUkZfSEZDMTM0QSgpLCBSRl9IRkMxNDNBKCksIFJGX0hGQzIyN0VBKCksIFJGX0hGQzI0NUZBKCksIFJGX1NGNigpLAogICAgICAgICAgICAgIFJGX0NGQzExKCksIFJGX0NGQzEyKCksIFJGX0NGQzExMygpLCBSRl9DRkMxMTQoKSAsIFJGX0NGQzExNSgpLCBSRl9DQ0w0KCksCiAgICAgICAgICAgICAgUkZfQ0gzQ0NMMygpLCBSRl9IQ0ZDMjIoKSwgUkZfSENGQzE0MUIoKSwgUkZfSENGQzE0MkIoKSwgUkZfSEFMT04xMjExKCksIAogICAgICAgICAgICAgIFJGX0hBTE9OMTMwMSgpLCBSRl9IQUxPTjI0MDIoKSwgUkZfQ0gzQ0woKSwgUkZfQ0gzQlIoKSwgQVRNT1NQSEVSSUNfQ0g0KCksIFJGX01JU0MoKSwKICAgICAgICAgICAgICBHTE9CQUxfVEVNUCgpKSAKICAgIAogICAgbmFtZSA8LSBnc3ViKHBhdHRlcm4gPSAiaGVjdG9yX3wuaW5pIiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IGJhc2VuYW1lKGluaSkpCiAgICBjb3JlIDwtIG5ld2NvcmUoaW5pLCBuYW1lID0gbmFtZSkKICAgIHJ1bihjb3JlLCBydW50b2RhdGUgPSAyMTAwKQogICAgb3V0IDwtIGZldGNodmFycyhjb3JlLCAxNzQ1OjIxMDAsIHZhcnMpCiAgICAKICAgIHJldHVybihvdXQpCiAgICAKfQoKbGlzdC5maWxlcyhmaWxlLnBhdGgoRElSLCAiaW5wdXQiKSwgcGF0dGVybiA9ICJpbmkiLCBmdWxsLm5hbWVzID0gVFJVRSkgJT4lIAogIGxhcHBseShydW5faGVjdG9yX3NzcCkgJT4lIAogIGJpbmRfcm93cygpICU+JSAgCiAgbXV0YXRlKGRyaXZlbiA9IGlmZWxzZShncmVwbChwYXR0ZXJuID0gIi1HSEciLCBzY2VuYXJpbyksICJHSEciLCAiZW1pc3MiKSkgJT4lIAogIG11dGF0ZShkcml2ZW4gPSBpZmVsc2UoZ3JlcGwocGF0dGVybiA9ICItcmYiLCBzY2VuYXJpbyksICJSRiIsIGRyaXZlbikpICU+JSAKICBtdXRhdGUoc2NlbmFyaW8gPSBnc3ViKHBhdHRlcm4gPSAiLXJmIiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IHNjZW5hcmlvKSkgJT4lICAKICBtdXRhdGUoc2NlbmFyaW8gPSBnc3ViKHBhdHRlcm4gPSAiLUdIRyIsIHJlcGxhY2VtZW50ID0gIiIsIHggPSBzY2VuYXJpbykpLT4gCiAgaGVjdG9yX291dApoZWN0b3Jfb3V0JHNvdXJjZSA8LSAiSGVjdG9yIgoKaGVjdG9yX291dCAlPiUgCiAgZHBseXI6OmZpbHRlcih2YXJpYWJsZSAlaW4lIGMoUkZfQkMoKSwgUkZfT0MoKSwgUkZfU08yKCksIFJGX05IMygpKSkgJT4lIAogIGdyb3VwX2J5KHNjZW5hcmlvLCB5ZWFyLCBkcml2ZW4sIHNvdXJjZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IHN1bSh2YWx1ZSkpICU+JSAKICB1bmdyb3VwICU+JSAKICBtdXRhdGUodmFyaWFibGUgPSAiYXJpIikgJT4lIAogIGJpbmRfcm93cyhoZWN0b3Jfb3V0KSAtPiAKICBoZWN0b3Jfb3V0CgpoZWN0b3Jfb3V0JHZlcnNpb24gPC0gMwoKaGVjdG9yX29sZCA8LSByZWFkLmNzdihmaWxlLnBhdGgoRElSLCAiSGVjdG9yXzI1LmNzdiIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgpoZWN0b3Jfb3V0ICU+JSAKICBmaWx0ZXIoZHJpdmVuID09ICJlbWlzcyIpICU+JSAKICBzZWxlY3Qoc2NlbmFyaW8sIHllYXIsIHZhbHVlLCB2YXJpYWJsZSwgdW5pdHMsIHZlcnNpb24pICU+JSAKICBiaW5kX3Jvd3MoaGVjdG9yX29sZCkgLT4gCiAgaGVjdG9yX3ZfaGVjdG9yCmBgYAoKIyMgQVI2IFJlc3VsdHMKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpmb3JtYXRfZGF0YSA8LSBmdW5jdGlvbihwYXRoKXsKICAKICB4IDwtIGdzdWIocGF0dGVybiA9ICIuY3N2IiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IGJhc2VuYW1lKHBhdGgpKQogIHh4IDwtIHVubGlzdChzdHJzcGxpdCh4LCBzcGxpdCA9ICJfIikpCiAgCiAgaWYgKGxlbmd0aCh4eCkgPT0gMyApewogICAgb3V0IDwtIGFzLmRhdGEuZnJhbWUobWF0cml4KHh4LCBucm93ID0gMSwgZGltbmFtZXMgPSBsaXN0KE5VTEwsIGMoIm91dHB1dCIsICJzY24iLCAidGltZSIpKSkpCiAgfQogIAogIGlmIChsZW5ndGgoeHgpID09IDQgKXsKICAgIG91dCA8LSBhcy5kYXRhLmZyYW1lKG1hdHJpeCh4eCwgbnJvdyA9IDEsIGRpbW5hbWVzID0gbGlzdChOVUxMLCBjKCJvdXRwdXQiLCAic2NuIiwgInRpbWUiLCAicGVyY2VudCIpKSkpCiAgfQogIAogIHJldHVybihvdXQpCiAgCn0KCmdldF9jbWlwX2RhdGEgPC0gZnVuY3Rpb24ocGF0aCl7CiAgCiAgZGF0IDwtIHJlYWQuY3N2KHBhdGgsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICBpbmZvIDwtIGZvcm1hdF9kYXRhKHBhdGgpCiAgCiAgZGF0ICU+JSAKICAgIG1lbHQoaWQudmFycyA9IGMoICJ5ZWFyIiksIAogICAgICAgICB2YXJpYWJsZS5uYW1lID0gInZhcmlhYmxlIiwgdmFsdWUubmFtZSA9ICJ2YWx1ZSIpICU+JSAKICAgIGNiaW5kKGluZm8pIC0+IAogICAgb3V0CiAgCiAgcmV0dXJuKG91dCkKfQoKZmlsZXMgICA8LSBsaXN0LmZpbGVzKGZpbGUucGF0aChESVIsIlNTUHMiKSwgcGF0dGVybiA9ICJFUkYiLCBmdWxsLm5hbWVzID0gVFJVRSkgIAoKZmlsZXMgJT4lIAogICAgbGFwcGx5KGdldF9jbWlwX2RhdGEpICU+JSAKICAgIGJpbmRfcm93cygpICU+JSAKICAgIHNlbGVjdCh5ZWFyLCB2YXJpYWJsZSwgdmFsdWUsIHNjZW5hcmlvID0gc2NuLCBwZXJjZW50KSAlPiUgCiAgICBhcy5kYXRhLnRhYmxlKCkgJT4lIAogICAgZHBseXI6OmZpbHRlcihpcy5uYShwZXJjZW50KSkgIC0+IAogICAgYXI2X2RhdGFfb2cKCmFyNl9uYW1lcyA8LSBjKCJjbzIiLCJjaDQiLCJuMm8iLCJvMyIsImgyb19zdHJhdG9zcGhlcmljIiwiYWVyb3NvbC5jbG91ZF9pbnRlcmFjdGlvbnMiLAogICAgICAgICAgICAgICAidm9sY2FuaWMiLCJ0b3RhbCIsICJIRkMuMTM0YSIsIkhGQy4yMyIsIkhGQy4zMiIsIkhGQy4xMjUiLCJIRkMuMTQzYSIsIAogICAgICAgICAgICAgICAiSEZDLjIyN2VhIiwgIkhGQy4yNDVmYSIsICJTRjYiLCJDRjQiLCJDRkMuMTEiLCAiQ0ZDLjExMyIsIAogICAgICAgICAgICAgICAiQ0ZDLjExNCIsICJDRkMuMTE1IiwgImxhbmRfdXNlIiwgInNvbGFyIiwgImJjX29uX3Nub3ciLCAiY29udHJhaWxzIiwKICAgICAgICAgICAgICAgImFlcm9zb2wucmFkaWF0aW9uX2ludGVyYWN0aW9ucyIpCmhlY3Rvcl9uYW1lcyA8LSBjKFJGX0NPMigpLCBSRl9DSDQoKSwgUkZfTjJPKCksIFJGX08zX1RST1AoKSwgUkZfSDJPX1NUUkFUKCksIFJGX0FDSSgpLAogICAgICAgICAgICAgICAgICBSRl9WT0woKSAsUkZfVE9UQUwoKSwgUkZfSEZDMTM0QSgpLFJGX0hGQzIzKCksIFJGX0hGQzMyKCksIFJGX0hGQzEyNSgpLAogICAgICAgICAgICAgICAgICBSRl9IRkMxNDNBKCksIFJGX0hGQzIyN0VBKCksIFJGX0hGQzI0NUZBKCksIFJGX1NGNigpLCBSRl9DRjQoKSwKICAgICAgICAgICAgICAgICAgUkZfQ0ZDMTEoKSwgUkZfQ0ZDMTEzKCksIFJGX0NGQzExNCgpLCBSRl9DRkMxMTUoKSwgUkZfVF9BTEJFRE8oKSwgCiAgICAgICAgICAgICAgICAgIFJGX01JU0MoKSwgUkZfTUlTQygpLCBSRl9NSVNDKCksICJhcmkiKSAKCmFyNl9kYXRhX29nICU+JSAKICBmaWx0ZXIodmFyaWFibGUgJWluJSBhcjZfbmFtZXMpICU+JQogIGxlZnRfam9pbihkYXRhLmZyYW1lKHZhcmlhYmxlID0gYXI2X25hbWVzLCAKICAgICAgICAgICAgICAgICAgICAgICBodmFyID0gaGVjdG9yX25hbWVzKSkgJT4lIAogIHNlbGVjdCh5ZWFyLCB2YXJpYWJsZSA9IGh2YXIsIHZhbHVlLCBzY2VuYXJpbykgJT4lICAKICBmaWx0ZXIoc2NlbmFyaW8gJWluJSBoZWN0b3Jfb3V0JHNjZW5hcmlvKSAlPiUgCiAgbXV0YXRlKGRyaXZlbiA9ICJBUjYiKSAlPiUgCiAgZ3JvdXBfYnkoeWVhciwgdmFyaWFibGUsIHNjZW5hcmlvLCBkcml2ZW4pICU+JSAgCiAgc3VtbWFyaXNlKHZhbHVlID0gc3VtKHZhbHVlKSkgJT4lICAKICB1bmdyb3VwIC0+IAogIGFyNl9yZXN1bHRzXzEKCiMgUmVhZCBpbiBhbmQgZm9ybWF0IHRoZSBoYWxvLWNhcmJvbiBSRi4gCgpmaWxlcyAgIDwtIGxpc3QuZmlsZXMoZmlsZS5wYXRoKERJUiwiU1NQcyIpLCBwYXR0ZXJuID0gIm1pbm9yR0hHcyIsIGZ1bGwubmFtZXMgPSBUUlVFKSAgCgpsYXBwbHkoZmlsZXMsIGZ1bmN0aW9uKHgpewogIAogIG5hbWUgPC0gZ3N1Yih4ID0gYmFzZW5hbWUoeCksIHBhdHRlcm4gPSAiRVJGX3xfbWlub3JHSEdzXzE3NTAtMjUwMC5jc3YiLCByZXBsYWNlbWVudCA9ICIiICkKCnJlYWQuY3N2KHgpICU+JSAKICBhcy5kYXRhLnRhYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF5ZWFyLCBuYW1lc190byA9ICJ2YXJpYWJsZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JSAKICBtdXRhdGUodmFyaWFibGUgPSBnc3ViKHBhdHRlcm4gPSAiXFwuIiwgcmVwbGFjZW1lbnQgPSAiIiwgeCA9IHZhcmlhYmxlKSkgJT4lCiAgbXV0YXRlKHZhcmlhYmxlID0gcGFzdGUwKCJGIiwgdmFyaWFibGUpKSAlPiUKICBtdXRhdGUodmFyaWFibGUgPSBpZmVsc2UoZ3JlcGwocGF0dGVybiA9ICJIYWxvbiIsIHZhcmlhYmxlKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdzdWIocmVwbGFjZW1lbnQgPSAiaGFsb24iLCBwYXR0ZXJuID0gIkhhbG9uIiwgdmFyaWFibGUpLCB2YXJpYWJsZSkpICU+JSAKICBtdXRhdGUoc2NlbmFyaW8gPSBuYW1lKQogIAp9KSAlPiUgCiAgYmluZF9yb3dzKCkgLT4gCiAgYXI2X3Jlc3VsdHNfMgoKICAKYXI2X3Jlc3VsdHMgPC0gYmluZF9yb3dzKGFyNl9yZXN1bHRzXzEsIGFyNl9yZXN1bHRzXzIpCmFyNl9yZXN1bHRzJHNvdXJjZSA8LSAiQVI2IgphcjZfcmVzdWx0cyRkcml2ZW4gPC0gIkFSNiIKCiMgQSBkYXRhIGZyYW1lIG9mIHRoZSBoZWN0b3IgYW5uZCBBUjYgb3V0cHV0IHJlc3VsdHMhIApkYXRhIDwtIGJpbmRfcm93cyhoZWN0b3Jfb3V0LCBhcjZfcmVzdWx0cykgCmBgYAoKCgpgYGB7cn0KIyBGaWd1cmUgb3V0IHRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYnR3ZWVuIHRoZSBIZWN0b3IgYW5kIEFSNiByZXN1bHRzISAKZGF0YSAlPiUgIAogIGZpbHRlcihkcml2ZW4gPT0gIkFSNiIgJiBzb3VyY2UgPT0gIkFSNiIpICU+JSAgCiAgc2VsZWN0KHNjZW5hcmlvLCB5ZWFyLCB2YXJpYWJsZSwgQVI2ID0gdmFsdWUpICU+JSAKICBkaXN0aW5jdCgpIC0+IAogIEFSNl92YXJpYWJsZV9vdXRwdXQKCiMgQ2FsY3VsYXRlIHRoZSBwZXJjZW50IGRpZmZlcmVuY2UgZnJvbSB0aGUgQVI2IG91dHB1dC4gCmRhdGEgJT4lCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkdIRyIpKSAlPiUgCiAgZnVsbF9qb2luKEFSNl92YXJpYWJsZV9vdXRwdXQpICU+JSAKICBzZWxlY3Qoc2NlbmFyaW8sIHllYXIsIGRyaXZlbiwgdmFsdWUsIHZhcmlhYmxlLCBBUjYpICU+JSAKICBuYS5vbWl0KCkgJT4lIAogIG11dGF0ZSh2YWx1ZSA9IDEwMCAqICh2YWx1ZSAtIEFSNikgLyBBUjYpICU+JSAKICBzZWxlY3Qoc2NlbmFyaW8sIHllYXIsIGRyaXZlbiwgdmFsdWUsIHZhcmlhYmxlKSAlPiUgCiAgbXV0YXRlKHVuaXRzID0gIiUgZGlmZi4gZnJvbSBBUjYgb3V0cHV0IikgJT4lIAogIG11dGF0ZShzY2VuYXJpbyA9IGlmX2Vsc2UoeWVhciA8IDIwMTQsICJoaXN0b3JpY2FsIiwgc2NlbmFyaW8pKSAtPiAKICBwZXJjZW50X2RpZmZlcmVuY2UKICAKIyBIb3cgbXVjaCBvZiB0aGUgdG90YWwgUkYgZG9lcyB0aGUgZGlmZmVyZW5jZSByZXByZXNlbnQ/IApkYXRhICU+JSAgCiAgZmlsdGVyKGRyaXZlbiA9PSAiQVI2IiAmIHNvdXJjZSA9PSAiQVI2IikgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gUkZfVE9UQUwoKSkgJT4lIAogIHNlbGVjdChzY2VuYXJpbywgeWVhciwgQVI2X3RvdGFsID0gdmFsdWUpICU+JSAKICBkaXN0aW5jdCgpIC0+IAogIEFSNl90b3RhbAoKIyBOb3cgY2FsY3VsYXRlIGhvdyBtdWNoIG9mIHRoZSB0b3RhbCBBUjYgUkYgZG9lcyB0aGlzIHJlcHJlc2VudD8gCmRhdGEgJT4lCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkdIRyIpKSAlPiUgCiAgZnVsbF9qb2luKEFSNl92YXJpYWJsZV9vdXRwdXQpICU+JSAKICBzZWxlY3Qoc2NlbmFyaW8sIHllYXIsIGRyaXZlbiwgdmFsdWUsIHZhcmlhYmxlLCBBUjYpICU+JSAKICBuYS5vbWl0KCkgJT4lIAogIGxlZnRfam9pbihBUjZfdG90YWwpICU+JSAKICBtdXRhdGUodmFsdWUgPSAxMDAgKiAodmFsdWUgLSBBUjYpLyBBUjZfdG90YWwpICU+JSAgCiAgc2VsZWN0KHNjZW5hcmlvLCB5ZWFyLCBkcml2ZW4sIHZhbHVlLCB2YXJpYWJsZSkgJT4lIAogIG11dGF0ZSh1bml0cyA9ICIlIGRpZmYuIC8gQVI2IHRvdGFsIikgLT4gCiAgcGVyY2VudF9kaWZmX29mX3RvdGFscwoKYGBgCgojIEJpZyBQaWN0dXJlCgoqIFJGIENPMiAgYHIgZW1vOjpqaSgicXVlc3Rpb24iKWAKKiBSRiBOMk8gIGByIGVtbzo6amkoInF1ZXN0aW9uIilgCiogUkYgQ0g0ICBgciBlbW86OmppKCJjaGVjayIpYAoqIFJGIE8zIFRyb3AgIGByIGVtbzo6amkoIm9rIilgIG5vIHVwZGF0ZSBpbiBIZWN0b3IKKiBSRiBIMk8gc3RyYXQgIGByIGVtbzo6amkoInF1ZXN0aW9uIilgIGxvb2tzIG9rYXkgaGlzdG9yaWNhbCBub3QgZ3JlYXQgaW4gdGhlIGZ1dHVyZSBwZXJpb2RzCiogUkYgRmFjaSBgciBlbW86OmppKCJ0aHVtYnMgZG93biIpYAoqIFJGIEFyaSAgYHIgZW1vOjpqaSgib2siKWAKKiBSRiBGdm9sICBgciBlbW86OmppKCJjaGVjayIpYAoqIFJGIEYgaGFsb2NhcmJvbnMgIGByIGVtbzo6amkoIm9rIilgCiogUkYgRmFsYmVkbyAgYHIgZW1vOjpqaSgiY2hlY2siKWAKKiBSRiBGbWlzYyBgciBlbW86OmppKCJjaGVjayIpYAoKCiMjIFRvdGFsIFJGICYgVGVtcGVyYXR1cmUgCgpIb3cgbXVjaCBkb2VzIHRvdGFsIFJGIGRpZmZlciBieSBhbmQgd2hhdCBkb2VzIHRoYXQgbWVhbiBpbiB0ZXJtcyBvZiB0ZW1wZXJhdHVyZT8gCgpgYGB7cn0KaGVjdG9yX291dCAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlICVpbiUgYyhSRl9UT1RBTCgpLCBHTE9CQUxfVEVNUCgpKSkgJT4lIAogIG11dGF0ZShkcml2ZW4gPSBpZl9lbHNlKGRyaXZlbiA9PSAiUkYiLCAiQVI2IiwgZHJpdmVuKSkgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKyAKICBsYWJzKHRpdGxlID0gIkFSNiB2cyBIZWN0b3IgQ29tcGFyaXNvbiIsIAogICAgICAgeCA9ICJZZWFyIikgKyAKICBmYWNldF93cmFwKCJ2YXJpYWJsZSIsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgoKVGhlIGRpZmZlcm5jZXMgaW4gdG90YWwgUkYgcmVzdWx0cyBpbiBhIHRlbXBlcmF0dXJlIHRoYXQgZGlmZmVyIGJ5IGEgdGVudGggb2YgYSBkZWdyZWUuIAoKYGBge3J9CmhlY3Rvcl9vdXQgJT4lIAogIGZpbHRlcih2YXJpYWJsZSAlaW4lIGMoUkZfVE9UQUwoKSwgR0xPQkFMX1RFTVAoKSkpICU+JSAKICBtdXRhdGUoZHJpdmVuID0gaWZfZWxzZShkcml2ZW4gPT0gIlJGIiwgIkFSNiIsIGRyaXZlbikpICU+JQogIHNlbGVjdChzY2VuYXJpbywgeWVhciwgZHJpdmVuLCB2YWx1ZSwgdmFyaWFibGUpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBzcHJlYWQoZHJpdmVuLCB2YWx1ZSkgJT4lIAogIG11dGF0ZShlbWlzcyA9IChlbWlzcyAtIEFSNiksIAogICAgICAgICBHSEcgPSAgKEdIRyAtIEFSNikpICU+JSAKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeWVhciwgZW1pc3MsIGdyb3VwYnkgPSBzY2VuYXJpbywgbGluZXR5cGUgPSBzY2VuYXJpbywgY29sb3IgPSAiZW1pc3MiKSkgKyAKICBnZW9tX2xpbmUoYWVzKHllYXIsIEdIRywgZ3JvdXBieSA9IHNjZW5hcmlvLCBsaW5ldHlwZSA9IHNjZW5hcmlvLCBjb2xvciA9ICJHSEciKSkgKyAKICBsYWJzKHggPSAiWWVhciIsIAogICAgICAgeSA9ICJEaWZmZXJlbmNlIikgKyAKICBmYWNldF93cmFwKCJ2YXJpYWJsZSIsIHNjYWxlcyA9ICJmcmVlIikgCmBgYAoKCldoYXQgZG9lcyB0aGUgcGVyY2VudCBkaWZmZXJlbmNlIGxvb2sgbGlrZT8gCgpgYGB7cn0KaGVjdG9yX291dCAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlICVpbiUgYyhSRl9UT1RBTCgpLCBHTE9CQUxfVEVNUCgpKSkgJT4lIAogIG11dGF0ZShkcml2ZW4gPSBpZl9lbHNlKGRyaXZlbiA9PSAiUkYiLCAiQVI2IiwgZHJpdmVuKSkgJT4lCiAgc2VsZWN0KHNjZW5hcmlvLCB5ZWFyLCBkcml2ZW4sIHZhbHVlLCB2YXJpYWJsZSkgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIHNwcmVhZChkcml2ZW4sIHZhbHVlKSAlPiUgCiAgbXV0YXRlKGVtaXNzID0gIDEwMCAqIChlbWlzcyAtIEFSNikgLyBBUjYsIAogICAgICAgICBHSEcgPSAgMTAwICogKEdIRyAtIEFSNikgLyBBUjYpICU+JSAKICBwaXZvdF9sb25nZXIoYyhlbWlzcywgR0hHKSwgbmFtZXNfdG8gPSAiZHJpdmVuIiwgdmFsdWVzX3RvID0gInZhbHVlIikgLT4gCiAgZGlmZmVyZW5jZV90Z2F2X3JmCmBgYAoKCmBgYHtyfQpkaWZmZXJlbmNlX3RnYXZfcmYgJT4lIAogIGZpbHRlcih5ZWFyID49IDIwMTQpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8sIGxpbmV0eXBlID0gc2NlbmFyaW8pKSArIAogIGxhYnModGl0bGUgPSAiKFggLSBBUjYpL0FSNiIsIAogICAgICAgeCA9ICJZZWFyIiwgCiAgICAgICB5ID0gIiUiKSArIAogIGZhY2V0X3dyYXAoInZhcmlhYmxlIikgCmBgYAoKQSA1ICUgY2hhbmdlIGluIHRoZSBmdXR1cmUgZ2xvYmFsIHRlbXBlcmF0dXJlLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSBSRl9UT1RBTCgpKSAlPiUgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIHZhcmlhYmxlLCB1bml0cywgZHJpdmVuKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKSAlPiUgCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGRyaXZlbiwgdmFsdWVzX2Zyb20gPSBtZWFuKSAlPiUgCiAga2FibGUoZGlnaXRzID0gMykgJT4lIAogIGthYmxlX3N0eWxpbmcoKQpgYGAKCgoKCldoYXQgaXMgb3VyIGJpZ2dlc3QgcHJvYmxlbT8/PyBJZ25vcmluZyB0aGUgaGlzdG9yaWNhbCBwZXJpb2QgZm9yIG5vdy4KCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUKICBmaWx0ZXIoeWVhciA+PSAyMDE4KSAlPiUgCiAgZmlsdGVyKGRyaXZlbiA9PSAiR0hHIikgJT4lIAogIGZpbHRlcih2YXJpYWJsZSAhPSBSRl9UT1RBTCgpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSB2YXJpYWJsZSwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKyAKICBnZW9tX2xpbmUoKQpgYGAKCgpXaGljaCBvZiB0aGUgZGlmZmVybmNlcyBiZXR3ZWVuIEhlY3RvciAmIEFSNiBSRiBtYWtlcyB1cCB0aGUgbGFyZ2VzdCBwb3J0aW9uIG9yIHBlcmNlbnRhZ2Ugb2YgdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUKICBmaWx0ZXIoZHJpdmVuID09ICJHSEciICYgdmFyaWFibGUgIT0gUkZfVE9UQUwoKSkgJT4lIAogIGZpbHRlcih5ZWFyID4gMjAxNikgJT4lIAogIGdyb3VwX2J5KHNjZW5hcmlvLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbih2YWx1ZSksIHNkID0gc2QodmFsdWUpKSAlPiUgCiAgdW5ncm91cCAlPiUgCiAgZ3JvdXBfYnkodmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4obWVhbikpICU+JSAKICBhcnJhbmdlKGRlc2MoYWJzKG1lYW4pKSkgJT4lIAogIGthYmxlKCkgJT4lIAogIGthYmxlX3N0eWxpbmcoKQpgYGAKCgpUaGUgdG9wIGZvdXIgY3VscHJpdHMgaXMgdGhlIGZvcmNpbmcgZnJvbSBjbG91ZCBpbnRlcmFjdGlvbnMgKEYgYWNpKSwgQ08yLCBOMk8sIGFuZCB0cm9wIE8zLiBXaGF0IHdvdWxkIGJlIHJlYWxseSBoZWxwZnVsIHdvdWxkIGJlIGZvciB5b3UgdG8gdGFrZSBhIGxvb2sgYW5kIHByb3ZpZGUgaW5wdXQsIGRvIHlvdSB0aGluayB0aGVzZSBkaXNjcmVwYW5jaWVzIGFyZSBsYXJnZSBlbm91Z2ggdG8gYmUgYSBwcm9ibGVtPyBPciBhcmUgd2Ugb2theSB3aXRoIHRoZW0/ICAKCiMgTWFqb3IgR0hHcyAKCgpMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgbWFqb3IgR0hHcywgQ08yLCBOMk8sIGFuZCBDSDQuIEZvciB0aGVzZSBwbG90cyB3ZSBhcmUgaW50cmVzdGVkIGluIGNvbXBhcmluZyB0aGUgQVI2IHJlc3VsdHMgdnMgdGhlIGNvbmNlbnRyYXRpb24gZHJpdmVuIEhlY3RvciAodGhlIEdIRyBwbG90IGluIHRoZSBydW5zKS4gVGhlIHB1cnBvc2UgaGVyZSBpcyB0byBzaG93IHRoYXQgdGhlIHdlIGhhdmUgaW1wbGVudGVkIHRoZSBBUjYncyBjb25jZW50cmF0aW9uIHRvIFJGIHN0ZXAgZm9yIHRoZXNlIHRocmVlIEdIR3MgY29ycmVjdGx5LiAgCgoKIyMgQ08yIAoKYGBge3J9CmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSBSRl9DTzIoKSkgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoIkdIRyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpCmBgYAoKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV0d2VlbiBDTzIgY29uc3RyYWluZWQgSGVjdG9yICYgQVI2IENPMiBSRi4gSG9uZXN0bHkgdGhlIGRpZmZlcmVuY2Ugb2YgMiUgaW4gUkYgaXMgbW9yZSB0aGFuIEkgd2FzIGV4cGVjdGluZyBlc3BjaWFsbHkgc2luY2UgdGhlIGNvbmNlbnRyYXRpb24gdmFsdWVzIGFyZSBpZGVudGljYWwgJiB3ZSBhcmUgdXNpbmcgdGhlIHNhbWUgZnVuY3Rpb25hbCBmb3JtIGF0IHRoZSBBUjYgcmVwb3J0IHNvIGl0IGlzIHN1cnByaXNpbmcgdG8gbWUgdGhhdCB3ZSB3b3VsZCBzZWUgdGhpcyBsZXZlbCBvZiBkaWZmZXJlbmNlLCBkb2VzIG5vdCBzZWVtIGxpa2UganVzdCBudW1lcmljYWwgZXJyb3IgYW5kIHNpbmNlIENPMiBSRiBpcyBzdWNoIGEgbGFyZ2UgYW5kIGltcG9ydGFudCBwYXJ0IG9mIHRoZSBvdmVyYWxsIFJGIGJhbGFuY2UgSSBhbSBjb25mbGljdGVkLiBJIGhhdmUgZG91YmxlIGFuZCB0cmlwcGxlIGNoZWNrZWQsIEJCTCAmIFNKUyB3aGF0IGRvIHlvdSB0aGluaz8gCgpgYGB7cn0KCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSBSRl9DTzIoKSkgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKHllYXIgIT0gMjAxNSkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJHSEciLCAiQVI2IikpICU+JSAKICBtdXRhdGUoc2NlbmFyaW8gPSBpZl9lbHNlKHllYXIgPD0gMjAxNSwgImhpc3RvcmljYWwiLCBzY2VuYXJpbykpICU+JSAKICBzZWxlY3Qoc2NlbmFyaW8sIHllYXIsIGRyaXZlbiwgdmFsdWUsIHZhcmlhYmxlKSAlPiUgCiAgZGlzdGluY3QoKSAlPiUgIAogIHNwcmVhZChkcml2ZW4sIHZhbHVlKSAlPiUKICBtdXRhdGUocGVyY2VudCA9ICAxMDAgKiAoR0hHIC0gQVI2KS9BUjYpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHBlcmNlbnQpKSArIAogIGdlb21fbGluZSgpCmBgYAoKCkhlcmUgaXMgdGhlIGZ1bmN0aW9uYWwgZm9ybSBmb3IgdGhlIENPMiBSRiB3aXRoIHRoZSBwYXJhbWV0ZXJzIGlmIHRoYXQgaXMgc29tZXRoaW5nIHRoYXQgaW50ZXJlc3RzIHlvdSAKCiFbSVBDQyBBUjYgU00gNy5TTS4xIHRhYmxlXShhcjYvY28yX3JmLnBuZykKCgojIyBOMk8gCgpgYGB7cn0KdmFyIDwtIFJGX04yTygpCmRhdGEgJT4lIAogIGRwbHlyOjpmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGRwbHlyOjpmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZHBseXI6OmZpbHRlcihkcml2ZW4gJWluJSBjKCJHSEciLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JQogIGRwbHlyOjpmaWx0ZXIodmFyaWFibGUgPT0gUkZfTjJPKCkpICU+JQogIGRwbHlyOjpmaWx0ZXIoZHJpdmVuID09ICJHSEciKSAlPiUKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JQogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gIkdIRyIpICU+JQogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgpTbyBpdCBpcyBub3QgZ3JlYXQgdGhhdCBIZWN0b3IgdW5kZXIgZXN0aW1hdGVkIFJGIGJ5IDQgcGVyY2VudCBvdXQgb2YgdG90YWwgUkYgaXQgaXMgc29tZXdoYXQgc21hbGwuIFJlZ2FyZGxlc3MgSSBhbSBub3QgdGhyaWxsZWQgYnkgaG93IGRpZmZlcmVudCBpdCBpcy4gCgpMb29raW5nIG92ZXIgdGhlIGNvbnN0YW50cyB2YWx1ZXMgYW5kIHRoZSBmdW5jdGlvbmFsIGZvcm0gZnJvbSB0aGUgSVBDQyBBUjYgcmVwb3J0LiAKCiFbSVBDQyBBUjYgU00gNy5TTS4xIHRhYmxlXShhcjYvbjJvX3JmXzEucG5nKQohW0lQQ0MgQVI2IFNNIDcuU00uMSB0YWJsZSBjb250XShhcjYvbjJvX3JmXzIucG5nKQoKSSBhbSBhdCBhIGxvc3QgYXMgdG8gd2hhdCBpcyB3cm9uZywgYnV0IEJCTCAmIFNKUyB3aGF0IGRvIHlvdSB0aGluaz8gRG8geW91IGhhdmUgYW55IGlkZWFzIGFzIHRvIHdoYXQgY291bGQgYmUgd3Jvbmc/IERvIHlvdSB0aGlrbiBpdCBpcyBhIHByb2JsZW0/IAoKCgojIyBDSDQgCgpgYGB7cn0KdmFyIDwtIFJGX0NINCgpCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJHSEciLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKQmVjYXVzZSB0aGUgcGVyY2VudCBlcnJvciBpcyBkaWZmZXJlbnQgb24gdGhlIGNvbmNlbnRyYXRpb24gZHJpZW4gcnVuIEkgYW0gbGVzcyB0aGFuIHRocmlsbGVkIHdoYXQgY291bGQgYmUgY2F1c2luZyB0aGlzIHByb2JlbG0/IEVpdGhlciBhbiBpbmNvcmVjdCBmdW5jdGlvbmFsIGZvcm0gb3Igc29tZSBpc3N1ZSB3aXRoIGNvbnZ2ZXJ0aW5nIHRoZSBOMk8gdW5pdHMgdG8gdGhlIE4gd2hpY2ggaXMgd2hhdCB3ZSB1c2Ugd2l0aCBIZWN0b3IuIAoKRXllYmFsbGluZyBpdCBpdCB0aGUgQ0g0IG91dHB1dCBsb29rcyBncmVhdCwgYW5kIHRoZSBwZXJjZW50IGRpZmZlcm5jZSBiZXR3ZWVuIEFSNiAmIEhlY3RvciBDSDQgUkYgaXMgIGxlc3MgdGhhbiAxJSBpbiB0aGUgZnV0dXJlIHNjZW5hcmlvcyAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJHSEciKSAlPiUgIAogIG11dGF0ZShzY2VuYXJpbyA9IGlmX2Vsc2UoeWVhciA8PSAyMDE1LCAiaGlzdG9yaWNhbCIsIHNjZW5hcmlvKSkgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCkNvbXBhcmluZyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWUgdGhlIEhlY3RvciBDSDQgUkYgYW5kIEFSNiBDSDQgUkYgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRiB0aGlzIGlzIGEgcmVhbGx5IHNtYWxsIHBlcmNlbnQuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJHSEciKSAlPiUgIAogIG11dGF0ZShzY2VuYXJpbyA9IGlmX2Vsc2UoeWVhciA8PSAyMDE1LCAiaGlzdG9yaWNhbCIsIHNjZW5hcmlvKSkgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCiMgTWlub3IgR0hHcyAKCiMjIEZPM190cm9wCgpgYGB7cn0KdmFyIDwtIFJGX08zX1RST1AoKQpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiR0hHIiwgImVtaXNzIikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IHNjZW5hcmlvLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiR0hHIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJHSEciKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKVHJvcG9zcGhlcmUgTzMgZG9lc24ndCBsb29rIGdyZWF0LCBhbGwgdGhvdWdoIHRoaXMgZGlzY3JlcGFuY3kgb3ZlcmFsbCBtYWtlcyB1cCBhIHNtYWxsIHBlcmNlbnRhZ2Ugb2YgdGhlIHRvdGFsIFJGLiAKCiMjIEZIMk9fc3RyYXQKCkFSNiBkaWQgbm90IGRvIGFuIHVwZGF0ZSwgaGVyZSB3ZSBzY2FsZWQgZXN0aW1hdGVzIHRvIEFSNiBpbiAyMDE0IHdpdGggdGhlIDIwMTQgbWV0aGFuZSBjb25jZW50cmF0aW9uLiBXZSB1c2VkIHRoaXMgcmVsYXRpb25zaGlwIHRvIGVzdGltYXRlIFJGLiBXaGlsZSB0aGlzIHdvcmtzIHdlbGwgZm9yIHRoZSBoaXN0b3JpY2FsIGFuZCBzb21lIG9mIHRoZSBmdXR1cmUgc2NlYXJpb3MgaXQgaXMgZG9lcyBub3Qgd29yayBlcXVhbGx5IHdlbGwgZm9yIHNvbWUgb2YgdGhlIGxhcmdlciBFT0MgUkYuIAoKYGBge3J9CnZhciA8LSBSRl9IMk9fU1RSQVQoKQpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiR0hHIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBzY2VuYXJpbywgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gIkdIRyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiR0hHIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMgQWVyb3NvbHMgCgojIyBGYWNpCgpFUkYgZnJvbSBhZXJvc29sLWNsb3VkIGludGVyYWN0aW9ucyAoRVJGYWNpKSBFcXVhdGlvbiA3LlNNLjEuMiAKCkVSRiBhY2kgPSAtIGJldGEgKDEgKyBlbWlzc2lvbnMgU08yL3BhcmFtIFNPMiArIChlbWlzc2lvbnMgQkMgKyBPQykgLyBwYXJhbSBCQ09DKQoKYGBge3J9CnZhciA8LSBSRl9BQ0koKQpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IHNjZW5hcmlvLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMTUsIGFscGhhID0gMC40KSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikgCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoaXMgZG9lcyBub3QgbG9vayBnb29kLCBiZWNhdXNlIHRoZSBhcmkgbG9va3MgZXNwZWNpYWxseSBkdXJpbmcgdGhlIGZ1dHR1cmUgcGVyaW9kIGl0IHdoZXJlIHdlIGtub3cgdGhhdCB3ZSB1c2VkIHRoZSBzYW1lIGVtaXNzaW9uIGxlYWRzIGJlIHRvIGNvbmNsdWRlIHRoYXQgdGhpcyBpcyBub3QgYmVpbmcgY2F1c2VkIGJ5IGEgZGlmZmVyZW5jZSBpbiBlbWlzc2lvbnMuIFdoaWNoIGxlYWRzIG1lIHRvIGJlbGl2ZSBpdCBoYXMgdG8gZG8gd2l0aCBhIHBhcmFtZXRlciB2YWx1ZT8gU0pTIGRvIHlvdSBoYXZlIGFueSBpZGVhcz8gCgoKIyMgQXJpICAKCkVSRiBhcmkgPSAoYmV0YSBCQykoZW1pc3Npb25zIEJDKSArIChiZXRhIE9DKShlbWlzc2lvbnMgT0MpICsgKGJldGEgTkgzKShlbWlzc2lvbnMgTkgzKSA6IEVxdWF0aW9uIDcuU00uMS4xCgpgYGB7cn0KdmFyIDwtICJhcmkiCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDIwMTUsIGFscGhhID0gMC40KSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikgCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClNvIGl0IGlzIG5vdCBzdXJwcmlzaW5nIHRvIG1lIHRoYXQgdGhhdCB0aGUgbGFyZ2VzdCBkaWZmZXJlbmNlIGJldHdlZW4gSGVjdG9yIGFuZCB0aGUgQVI2IG91dHB1dHMgYmVjYXVzZSBpdCBzb3VuZHMgbGlrZSB3ZSBtaWdodCBoYXZlIGhhdmUgdXNlZCBkaWZmZXJlbnQgaGlzdG9yaWMgdGltZSBzZXJlaXMgZm9yIGFyZW9zb2wgZW1pc3Npb25zLiAKCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCgojIEhhbG9jYXJib25zIAoKIyMgRkhGQzEzNGEgCgpgYGB7cn0KdmFyIDwtICJGSEZDMTM0YSIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZIRkMyMyAKCmBgYHtyfQp2YXIgPC0gIkZIRkMyMyIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZIRkMzMiAKCmBgYHtyfQp2YXIgPC0gIkZIRkMzMiIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKIyMgRkhGQzEyNSAKCmBgYHtyfQp2YXIgPC0gIkZIRkMxMjUiCgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIyBGSEZDMTQzYSAKCmBgYHtyfQp2YXIgPC0gIkZIRkMxNDNhIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkhGQzIyN2VhIAoKYGBge3J9CnZhciA8LSAiRkhGQzIyN2VhIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkhGQzI0NWZhIAoKYGBge3J9CnZhciA8LSAiRkhGQzI0NWZhIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRlNGNiAKCmBgYHtyfQp2YXIgPC0gIkZTRjYiCgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIyBGQ0Y0IAoKYGBge3J9CnZhciA8LSAiRkNGNCIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZDRkMxMSAKCmBgYHtyfQp2YXIgPC0gIkZDRkMxMSIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZDRkMxMTMgCgpgYGB7cn0KdmFyIDwtICJGQ0ZDMTEzIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkNGQzExNCAKCmBgYHtyfQp2YXIgPC0gIkZDRkMxMTQiCgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIyBGQ0ZDMTE1IAoKYGBge3J9CnZhciA8LSAiRkNGQzExNSIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZDMkY2IAoKYGBge3J9CnZhciA8LSAiRkMyRjYiCgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIyBGQ0ZDMTIgCgpgYGB7cn0KdmFyIDwtICJGQ0ZDMTIiCgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIyBGQ0NsNCAKCmBgYHtyfQp2YXIgPC0gIkZDQ2w0IgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkNIM0NDbDMgCgpgYGB7cn0KdmFyIDwtICJGQ0gzQ0NsMyIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCgojIyBGSENGQzIyIAoKYGBge3J9CnZhciA8LSAiRkhDRkMyMiIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZIQ0ZDMTQxYiAKCmBgYHtyfQp2YXIgPC0gIkZIQ0ZDMTQxYiIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZIQ0ZDMTQyYiAKCmBgYHtyfQp2YXIgPC0gIkZIQ0ZDMTQyYiIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZoYWxvbjEyMTEgCgpgYGB7cn0KdmFyIDwtICJGaGFsb24xMjExIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgojIyBGaGFsb24xMzAxIAoKYGBge3J9CnZhciA8LSAiRmhhbG9uMTMwMSIKCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKCiMjIEZoYWxvbjI0MDIgCgpgYGB7cn0KdmFyIDwtICJGaGFsb24yNDAyIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkNIM0NsIAoKYGBge3J9CnZhciA8LSAiRkNIM0NsIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRkNIM0JyIAoKYGBge3J9CnZhciA8LSAiRkNIM0JyIgoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhcikgJT4lICAKICBmaWx0ZXIoeWVhciA8PSAyMTAwKSAlPiUgCiAgZmlsdGVyKGRyaXZlbiAlaW4lIGMoImVtaXNzIiwgIkFSNiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ZWFyLCB2YWx1ZSwgY29sb3IgPSBkcml2ZW4sIGxpbmV0eXBlID0gZHJpdmVuLCBncm91cGJ5ID0gc2NlbmFyaW8pKSArCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKClRoZSBwZXJjZW50IGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZlcmVuY2UgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZSBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYCBjb21wYXJlZCB0byB0aGUgdG90YWwgQVI2IFJGLiAKCmBgYHtyfQpwZXJjZW50X2RpZmZfb2ZfdG90YWxzICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgoKCgojIyBGSEZDNDMxMG1lZSAKCmBgYHtyfQp2YXIgPC0gYygiRkhGQzQzMTBtZWUiLCAiRkhGQzQzMTAiKQoKZGF0YSAlPiUgCiAgZmlsdGVyKHZhcmlhYmxlICVpbiUgdmFyKSAlPiUgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpUaGUgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAgY29tcGFyZWQgdG8gdGhlIHRvdGFsIEFSNiBSRi4gCgpgYGB7cn0KcGVyY2VudF9kaWZmX29mX3RvdGFscyAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKIyBPdGhlciBmb3JjaW5ncwoKIyMgRnZvbCAKCmBgYHtyfQp2YXIgPC0gIkZ2b2wiCmRhdGEgJT4lIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAgCiAgZmlsdGVyKHllYXIgPD0gMjEwMCkgJT4lIAogIGZpbHRlcihkcml2ZW4gJWluJSBjKCJlbWlzcyIsICJBUjYiKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gZHJpdmVuLCBsaW5ldHlwZSA9IGRyaXZlbiwgZ3JvdXBieSA9IHNjZW5hcmlvKSkgKwogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpUaGUgcGVyY2VudCBkaWZmZXJlbmNlIGJld3R3ZWVuIEhlY3RvciBgciB2YXJgIGFuZCBBUjYgYHIgdmFyYC4gCgpgYGB7cn0KcGVyY2VudF9kaWZmZXJlbmNlICU+JSAgCiAgZmlsdGVyKHZhcmlhYmxlID09IHZhciAmIGRyaXZlbiA9PSAiZW1pc3MiKSAlPiUgIAogIGdyb3VwX2J5KHNjZW5hcmlvLCBkcml2ZW4sIHZhcmlhYmxlKSAlPiUgCiAgc3VtbWFyaXNlKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKYGBgCgpHcmVhdCEgbG9va3MgbGlrZSB0aGVyZSBpcyAgYSAwJSBkaWZmZXJlbmNlISAKCgojIyBGdGFsYmVkbyAKCmBgYHtyfQp2YXIgPC0gIkZ0YWxiZWRvIgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCkdyZWF0IG5vIGRpZmZlcmVuY2UhCgojIyBGbWlzYyAKCmBgYHtyfQp2YXIgPC0gIkZtaXNjIgpkYXRhICU+JSAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgIAogIGZpbHRlcih5ZWFyIDw9IDIxMDApICU+JSAKICBmaWx0ZXIoZHJpdmVuICVpbiUgYygiZW1pc3MiLCAiQVI2IikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IGRyaXZlbiwgbGluZXR5cGUgPSBkcml2ZW4sIGdyb3VwYnkgPSBzY2VuYXJpbykpICsKICBnZW9tX2xpbmUoKSArIAogIGxhYnModGl0bGUgPSB2YXIpCmBgYAoKVGhlIHBlcmNlbnQgZGlmZmVyZW5jZSBiZXd0d2VlbiBIZWN0b3IgYHIgdmFyYCBhbmQgQVI2IGByIHZhcmAuIAoKYGBge3J9CnBlcmNlbnRfZGlmZmVyZW5jZSAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIgJiBkcml2ZW4gPT0gImVtaXNzIikgJT4lICAKICBncm91cF9ieShzY2VuYXJpbywgZHJpdmVuLCB2YXJpYWJsZSkgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSkpCmBgYAoKVGhlIGRpZmZlcmVuY2UgYmV3dHdlZW4gSGVjdG9yIGByIHZhcmAgYW5kIEFSNiBgciB2YXJgIGNvbXBhcmVkIHRvIHRoZSB0b3RhbCBBUjYgUkYuIAoKYGBge3J9CnBlcmNlbnRfZGlmZl9vZl90b3RhbHMgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyICYgZHJpdmVuID09ICJlbWlzcyIpICU+JSAgCiAgZ3JvdXBfYnkoc2NlbmFyaW8sIGRyaXZlbiwgdmFyaWFibGUpICU+JSAKICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpKQpgYGAKCkdyZWF0IHRoZXJlIGlzIG5vIGRpZmZlcmVuY2UhCgojIEhlY3RvciB2IEhlY3RvciAKCkhvdyBkbyB0aGVzZSBjaGFuZ2VzIGFmZmVjdCBIZWN0b3Igb3V0cHV0PyBJJ3ZlIHJ1biBIZWN0b3IgdiAyLjUgd2l0aCB0aGUgU1BQcyBhbmQgSGVjdG9yIHYzIHVwZGF0ZWQgd2l0aCB0aGUgQVI2IGZ1bmN0aW9ucyBhbmQgcGFyYW1ldGVyaXphdGlvbnMuIENvbXBhcmluZyB0aGUgdG90YWwgUkYgYW5kIG1ham9yIEdIRyBvdXRwdXRzIEhlY3RvciB2MyBydW5zIGF0IGEgaGlnaGVyIFJGIHdoaWNoIG1lYW5zIHRoYXQgaXQgd2lsbCBiZSBhbHNvIGJlIHdhcm1lci4gCgpgYGB7cn0KdmFyIDwtIFJGX1RPVEFMKCkKCmhlY3Rvcl92X2hlY3RvciAlPiUgIAogIGZpbHRlcih2YXJpYWJsZSA9PSB2YXIpICU+JSAKICBtdXRhdGUodmVyc2lvbiA9IGFzLmNoYXJhY3Rlcih2ZXJzaW9uKSkgJT4lIAogIGdncGxvdChhZXMoeWVhciwgdmFsdWUsIGNvbG9yID0gdmVyc2lvbiwgbGluZXR5cGUgPSBzY2VuYXJpbykpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBsYWJzKHRpdGxlID0gdmFyKQpgYGAKCgpgYGB7cn0KdmFyIDwtIFJGX0NPMigpCgpoZWN0b3Jfdl9oZWN0b3IgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgCiAgbXV0YXRlKHZlcnNpb24gPSBhcy5jaGFyYWN0ZXIodmVyc2lvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IHZlcnNpb24sIGxpbmV0eXBlID0gc2NlbmFyaW8pKSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpgYGB7cn0KdmFyIDwtIFJGX0NINCgpCgpoZWN0b3Jfdl9oZWN0b3IgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgCiAgbXV0YXRlKHZlcnNpb24gPSBhcy5jaGFyYWN0ZXIodmVyc2lvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IHZlcnNpb24sIGxpbmV0eXBlID0gc2NlbmFyaW8pKSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCgpgYGB7cn0KdmFyIDwtIFJGX04yTygpCgpoZWN0b3Jfdl9oZWN0b3IgJT4lICAKICBmaWx0ZXIodmFyaWFibGUgPT0gdmFyKSAlPiUgCiAgbXV0YXRlKHZlcnNpb24gPSBhcy5jaGFyYWN0ZXIodmVyc2lvbikpICU+JSAKICBnZ3Bsb3QoYWVzKHllYXIsIHZhbHVlLCBjb2xvciA9IHZlcnNpb24sIGxpbmV0eXBlID0gc2NlbmFyaW8pKSArIAogIGdlb21fbGluZSgpICsgCiAgbGFicyh0aXRsZSA9IHZhcikKYGBgCg==