Journal of Waste Management
Alejandro Parodi a , Walter J.J. Gerrits b, Joop J.A. Van Loon c, Imke J.M. De Boer a, André J.A. Aarnink d, Hannah H.E. Van Zanten a

a Animal Production Systems group, Wageningen University & Research, P.O. Box 338, 6700 AH Wageningen, the Netherlands
b Animal Nutrition group, Wageningen University & Research, P.O. Box 338, 6700 AH Wageningen, the Netherlands
c Laboratory of Entomology, Wageningen University & Research, P.O. Box 16, 6700 AA Wageningen, the Netherlands
d Department of Livestock and Environment, Wageningen University & Research, P.O. Box 338, 6700 AH Wageningen, the Netherlands

Code elaborated by: Alejandro Parodi.
https://orcid.org/0000-0003-1351-138X

This rnotebook contains all the steps made for data management, statistical analysis, tables and visualizations.

#Set working directory
setwd("write path here")

Graphical summary of this script

Activate packages

The following packages are be needed to run the code:

Part 1 - Nutrient balance

Step 1 - Data manipulation of datasets fresh_biomass.csv and chemical_analysis.csv

#Import datasets fresh_biomass and chemical_analysis
#Fresh biomass - contains initial amounts (in grams) of inputs and outputs (except condensed water and acid)
fresh_biomass <- read.csv("fresh_biomass.csv") 

#Chemical analysis - contains the chemical results of every input and output
chemical_analysis <- read.csv("chemical_analysis.csv")

#Explanation of columns
#Fresh biomass
#[1] rep - repetition number (R1, R2, R3 and R4)
#[2] treatment - treatment name (With_BSFL and Without)
#[3] chamber - chamber number (7 and 8)
#[4] part - name of the part (Fresh_manure, Starters (7-day old larvae), Larvae (16-day old larvae), Residues Without, Residues With_BSFL)
#[5] value - amount (in grams) of each part


# Chemical analysis
#[1] rep - repetition number (R1, R2, R3 and R4)
#[2] treatment name (With_BSFL and Without)
#[3] chamber - chamber number (7 and 8)
#[4] part - name of the part (Fresh_manure, Starters (7-day old larvae), Larvae (16-day old larvae), Residues Without, Residues With_BSFL)
#[5] DM - Dry matter content of every part (g/kg)
#[6] NH3 - Ammonia (g/kg)
#[7] C - Total carbon (g/kg)
#[8] N - Total N (g/kg)
#[9]P - Phosphorus (g/kg)
#[10]K - Potassium (g/kg)
#[11]E - Energy (kJ/kg)

#Create common column in both datasets to merge them
fresh_biomass$concatenate <- with(fresh_biomass, paste0(trial, "_", treatment, "_", part))
chemical_analysis$concatenate <- with(chemical_analysis, paste0(trial, "_", treatment, "_", part))

#merge both datasets
nutrient_balance <- merge(chemical_analysis, fresh_biomass,  by="concatenate", all=T)

#Remove unnecessary columns
nutrient_balance <- nutrient_balance [, -(13:16), drop=FALSE]

#reorder columnns. This dataset contains the fresh yields (g) of each part (columns 5:6) and next to it the chemical composition in dry weight of each part (columns 8:14)
nutrient_balance <- nutrient_balance[,c(1, 2, 3, 4, 5, 13, 6, 7, 8, 9, 10, 11, 12)]

#calculate the dry yields (g) in each part, and estimate how much of each nutrients is present in each part
#create new column for dryweight values
nutrient_balance$dryweight_grams <- nutrient_balance$value*((nutrient_balance$DM)/1000) 

#create new columns for the overall content of each nutrient (in grams)
nutrient_balance$N_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$N)/1000
nutrient_balance$C_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$C)/1000
nutrient_balance$E_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$ENERGY)/1000
nutrient_balance$K_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$K)/1000
nutrient_balance$P_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$P)/1000
nutrient_balance$NH3_overall <- (nutrient_balance$dryweight_grams*nutrient_balance$NH3)/1000

#select and re-name columns
#Select columns
nutrient_balance <- nutrient_balance %>% select(2:5,14:20)
names(nutrient_balance)[1] <- "trial"
names(nutrient_balance)[2] <- "treatment"
names(nutrient_balance)[3] <- "chamber"
names(nutrient_balance)[4] <- "part"

nutrient_balance

Step2 - Data manipulation for nitrogen emissions

#Import dataset Acid (AC) and condensed water (CW) - contains parameters related to AC and CW to estimate how much nitrogen was lost as gaseous losses. 
acid_condensed_water <- read.csv("acid_condensed_water.csv")

#Columns Acid_condensed water:
#[1] rep - repetition number (R1, R2, R3 and R4)
#[2] treatment name (With_BSFL and Without)
#[3] chamber - chamber number (7 and 8)
#[4] acid_bottleempty_grams - Weight of the empty container that contained the acid (grams)
#[5] acid_bottle_afterperiod_grams - Weight of the container with acid sample at the end of the experimental period (grams)
#[6] acid_gasmeter_valueupfront_m3 - Value of the gas meter before the experimental period (in m3). The flowmeter measured the amount of air (m3) that isflushed into the container with acid during the experimental period
#[7] acid_gasmeter_valueafterperiod_m3 - Value of the gas meter at the end of the experimental period (in m3).
#[8] net_air_flowm3 - net amount of air that flushed (column 7 - column 6)
#[9] overall_air_flow - Overall air flow to the climate respiration chambers (in m3)
#[10] N_acid_units - grams of N (g/kg) in acid
#[11] cw_net_grams -  grams of condensed water in each repetition (grams)
#[12] N_condensedwater_units - grams of N (g/kg) in condensed water

#separate the dataset acid_condensed_water in two sections: one for acid and the other for condensed water
acid <- acid_condensed_water %>% select(1:10)
condensedwater <- acid_condensed_water %>% select(1, 2, 3, 11, 12)

# Acid
#calculate net weight values of acid (grams) and total gas flow
acid$netbottle_grams <- acid$acid_bottle_afterperiod_grams - acid$acid_bottleempty_grams

#calculate the total amount of N in each acid sample
acid$N_sample_grams <- (acid$N_acid_units*acid$netbottle_grams)/1000

#calculate the total grams of N in the whole experimental period period
acid$N_overall <- acid$N_acid_units/1000 * (acid$overall_air_flow*acid$netbottle_grams/acid$net_air_flowm3)
acid$C_overall <- 0
acid$E_overall <- 0
acid$K_overall <- 0
acid$P_overall <- 0
acid$NH3_overall <- 0

#Reorder dataset to bind it to nutritional_overall
acid <- acid %>%  select(1:3, 13:18)
acid$part <- "Acid"
acid$dryweight_grams <- NA
acid <- acid[, c(1, 2, 3, 10, 11, 4, 5, 6, 7, 8, 9)]


#Condensed water
condensedwater$N_overall <- (condensedwater$cw_net_grams * condensedwater$N_condensedwater_units)/1000
condensedwater$C_overall <- 0
condensedwater$E_overall <- 0
condensedwater$K_overall <- 0
condensedwater$P_overall <- 0
condensedwater$NH3_overall <- 0


#format dataset as acid2
condensedwater <- condensedwater %>% select (1, 2, 3, 6:11)
condensedwater$part <- "Condensed_Water"
condensedwater$dryweight_grams <- NA
condensedwater <- condensedwater[, c(1, 2, 3, 10, 11, 4:9)]

#newdataset for total N emissions (sum acid and condensed water)
total_n <- rbind((condensedwater %>%select(1, 2, 4, 6)), (acid %>%select(1, 2, 4, 6)))
total_n <-  ddply(total_n, .(trial, treatment), summarize, 
                  N_g= sum(N_overall, na.rm=TRUE))

total_nitrogen <- rbind(condensedwater, acid)
total_nitrogen

Step3 - Data manipulation for CO2 and CH4 emissions, and heat loss

#Import dataset with gas and heat data obtained from the respiration chamber (CO2, CH4, O2, ENERGY)
chambers <- read.csv("chamberdata_manure.csv")

#Columns chamber data
# Chambers
#[1] chamber - chamber number (7 and 8)  
#[3] date - date of the measurement in format day/month/year
#[4] time - time of the measurement in format hour/minute/second
#[5] Heat - Heat production in KJ/day
#[6] O2 - Oxigen consumption (L/day)
#[7] CO2 - Carbon dioxide production (L/day)
#[8] RQ - Respiratory quotient (obtained by dividing CO2/O2)
#[9] Barometric_pressure_mmHg - Barometric_pressure inside the chamber
#[10] Temperature - Temperature (Celsius) inside the chamber
#[11] Humidity - Humidity (%) inside the chamber
#[12] STPD - Air ventilation (L/min) at standard pressure and temperature
#[13] CH4 - methane (L/day)
#[14] treatment - treatment name (With_BSFL and Without)
#[15] hour - hour of the day in 24h format
#[16] minute - minute at which the measurement was taken (from 0 to 60)
#[17] second - second at which the measurement was taken (from 0 to 60)
#[18] daynumber - day number (from day1 and day10) in which the measurement took place

#Calculate the production of each gas and heat per hour
chambers_summary2 <- ddply(chambers, .(treatment, trial, daynumber, hour, chamber), summarize, 
                           mean_CO2= mean(CO2, na.rm=TRUE), 
                           se_CO2= std.error(CO2, na.rm=TRUE),
                           mean_CH4= mean(CH4, na.rm=TRUE), 
                           se_CH4= std.error(CH4, na.rm=TRUE),
                           mean_O2=mean(O2, na.rm=TRUE),
                           se_O2=std.error(O2, na.rm=TRUE),
                           mean_heat= mean(Heat, na.rm=TRUE), 
                           se_heat= std.error(Heat, na.rm=TRUE),
                           mean_temp= mean(Temperature, na.rm=TRUE), 
                           se_temp= std.error(Temperature, na.rm=TRUE),
                           mean_RQ= mean(RQ, na.rm=TRUE), 
                           se_RQ= std.error(RQ, na.rm=TRUE),
                           mean_STDP= mean(STPD, na.rm=TRUE))

#Format column hour as numeric and set the correct order of the days and replicates

chambers_summary2$hour <- as.numeric(as.character(chambers_summary2$hour))
chambers_summary2$daynumber= factor(chambers_summary2$daynumber, levels =c("day1",
                                                                           "day2",
                                                                           "day3",
                                                                           "day4",
                                                                           "day5",
                                                                           "day6",
                                                                           "day7",
                                                                           "day8",
                                                                           "day9",
                                                                           "day10"))

chambers_summary2$trial= factor(chambers_summary2$trial, levels =c("T1", 
                                                               "T2", 
                                                               "T3", 
                                                               "T4"))
#Edit chamber number
chambers_summary2$chamber <- ifelse(chambers_summary2$chamber=="8", "C8", "C7")


#Format column to bind it to the ones from steps 1 and 2
chambers_summary2$part <- "Emissions/loss"
chambers_summary2$dryweight_grams <- NA
chambers_summary2 <- chambers_summary2[, c(2, 1, 5, 19, 20, 3, 4, 6, 8, 10, 12, 14, 16)]

#All gaseous losses are expressed in l/day. To get the overall production of each gas in grams (and heat in KJ), divide every record by 24 and multiply this value by a factor  to convert it from liters to grams. This factor is the molar mass/22.4
#CO2 -> 44.01/22.4 = 1.964732
#O2 -> 32/22.4 = 1.428571
#CH4 -> 16.06/22.4 = 0.7169643

chambers_summary3 <- ddply(chambers_summary2, .(trial, treatment, chamber, part, dryweight_grams), summarize, 
                           CO2= sum(mean_CO2/24, na.rm=TRUE) * 1.964735,
                           O2= sum(mean_O2/24, na.rm=TRUE) * 1.428571,
                           CH4= sum(mean_CH4/24, na.rm=TRUE)* 0.7169643,
                           HEAT= sum(mean_heat/24, na.rm=TRUE))
total_CO2_CH4_HEAT_O2 <- chambers_summary3
                           
#Calculate the content of C (grams) in CO2 and CH4.
chambers_summary3$N_overall <- 0
chambers_summary3$C_overall <- (chambers_summary3$CO2*0.27272727) + (chambers_summary3$CH4*0.747198) #these factors are used to get the grams of carbon.
chambers_summary3$E_overall <- chambers_summary3$HEAT
chambers_summary3$K_overall <- 0
chambers_summary3$P_overall <- 0
chambers_summary3$NH3_overall <- 0
chambers_summary3 <- chambers_summary3 %>% select (1, 2, 3, 4, 5, 10:15)

chambers_summary3

Step 4 - Bind datasets from step1, step2 and step3

#rbind all bases (fresh, acid, condensed water, chambers_summary)
NB <- rbind(nutrient_balance, acid, condensedwater, chambers_summary3)

#Create new columns (category (Input & Output) and part2 that will be used for the figures
NB$category <- ifelse((NB$part=="Starters" | NB$part=="Fresh_manure"), "Input", "Output")
NB$part2 <- ifelse((NB$part=="Acid" | NB$part=="Condensed_Water" | NB$part=="Aerial_losses"), "Emissions/loss", as.character(NB$part))
#reorder columns
NB <- NB[, c(1, 2, 3, 4, 12, 13, 5:11)]

###Step5 - Prepare dataset to calculate recoveries (sum of inputs and outputs)

#Sum the nutrients in starters and fresh manure to get the total inputs per nutrient (in grams) and format dataset to merge
NB_inputs <- subset(NB, (category=="Input"))
NB_inputs <- gather(NB_inputs, "variable", "value", 7:13)
NB_inputs <- ddply(NB_inputs, .(trial, treatment, chamber, variable), summarize, 
                    total_input= sum(value, na.rm=TRUE))

NB_inputs <- spread(NB_inputs, variable, total_input)
NB_inputs$concatenate <- paste(NB_inputs$trial, "_", NB_inputs$treatment)

# Get the total outputs per nutrient (in grams) and format dataset to merge
NB_outputs <- subset(NB, (category=="Output"))
NB_outputs <- gather(NB_outputs, "variable_output", "value_output", 7:13)
NB_outputs <- ddply(NB_outputs, .(trial, treatment, chamber, part2, variable_output), summarize,
                    sum_parts = sum(value_output, na.rm=T))

NB_outputs <- spread(NB_outputs, variable_output, sum_parts)
NB_outputs$concatenate <- paste(NB_outputs$trial, "_", NB_outputs$treatment)

#Add dry material emissions (calculated as equation 4)
DM_inputs <- NB_inputs %>% select(1, 2, 3, 5)
DM_inputs$concatenate <- paste0(DM_inputs$trial, DM_inputs$treatment, DM_inputs$chamber)

DM_outputs <- ddply(NB_outputs, .(trial, treatment, chamber), summarize,
                    sum_parts = sum(dryweight_grams, na.rm=T))
DM_outputs$concatenate <- paste0(DM_outputs$trial, DM_outputs$treatment, DM_outputs$chamber)

DM_emissions <- merge(DM_inputs, DM_outputs, by="concatenate")
DM_emissions$dm_emissions <- DM_emissions$dryweight_grams- DM_emissions$sum_parts
DM_emissions <- DM_emissions %>% select(2:10)
DM_emissions$concatenate <- paste(DM_emissions$trial.x, "_", DM_emissions$treatment.x)

NB_outputs <- merge(NB_outputs, DM_emissions, by="concatenate")
NB_outputs <- NB_outputs %>% select(1:12, 21)
NB_outputs$dryweight_grams.x <- ifelse(NB_outputs$dryweight_grams.x==0, NB_outputs$dm_emissions, NB_outputs$dryweight_grams.x)
NB_outputs <- NB_outputs %>% select(1:12)


#merge outputs with inputs to calculate the recovery in each part
NB_outputs2 <- merge(NB_outputs, NB_inputs, by="concatenate") #Columns 6:12 contain the outputs and columns 16:22 contain the inputs 
NB_outputs2

Step6 - Calculation of recoveries

#Calculate % of each output
NB_outputs2$DM_per <- (NB_outputs2$dryweight_grams.x/NB_outputs2$dryweight_grams)*100
NB_outputs2$N_per <- (NB_outputs2$N_overall.x/NB_outputs2$N_overall.y)*100
NB_outputs2$C_per <- (NB_outputs2$C_overall.x/NB_outputs2$C_overall.y)*100
NB_outputs2$E_per <- (NB_outputs2$E_overall.x/NB_outputs2$E_overall.y)*100
NB_outputs2$K_per <- (NB_outputs2$K_overall.x/NB_outputs2$K_overall.y)*100
NB_outputs2$P_per <- (NB_outputs2$P_overall.x/NB_outputs2$P_overall.y)*100
NB_outputs2$NH3_per <- (NB_outputs2$NH3_overall.x/NB_outputs2$NH3_overall.y)*100

NB_outputs2 <- NB_outputs2[, c(2:5, 23:28)]
NB_outputs2 <- gather(NB_outputs2, "variable", "value", 5:10)
NB_outputs2

Step7 - Figure S1 - recoveries per trial

#Prepare for Figure S1
NB_outputs2$variable2<- ifelse(NB_outputs2$variable=="DM_per", "Dry matter",
                          ifelse(NB_outputs2$variable=="N_per", "Nitrogen", 
                                 ifelse(NB_outputs2$variable=="C_per", "Carbon",
                                        ifelse(NB_outputs2$variable=="E_per", "Energy",
                                               ifelse(NB_outputs2$variable=="K_per", "Potassium", "Phosphorus")))))

NB_outputs2$variable2 = factor(NB_outputs2$variable2, levels = c("Dry matter",
                                                                 "Nitrogen",
                                                                 "Carbon",
                                                                 "Energy",
                                                                 "Phosphorus",
                                                                 "Potassium"))


NB_outputs2$trial.x=factor(NB_outputs2$trial.x, levels=c("T4",
                                                                 "T3",
                                                                 "T2",
                                                                 "T1"))

NB_outputs2$treatment.x=factor(NB_outputs2$treatment.x, levels=c("With_BSFL",
                                                                 "Without"))

#remove air emissions for P and K
NB_outputs2 <- subset(NB_outputs2, (value>0))

#Supplementary Figure 1

ggplot(NB_outputs2, aes(y= value, x=trial.x, fill=part2,), stat="identity")+
  geom_col() + 
  geom_text(aes(label = (paste0(round(value, digits = 1), "%")), group = part2), position = position_stack(vjust = 0.5), size=2.5)+
  scale_fill_manual(values=c("#FFA500", "#8FBC8F", "#808000"))+
  facet_grid(variable2~treatment.x)+
  labs(y=expression("Recovery (%)"))+ 
  xlab("") +
  theme(strip.background = element_rect(colour="white", fill="white"))+
  theme(strip.text = element_text(size=10, face="bold", hjust=0))+ 
  theme(panel.grid.major  = element_line(colour = "white", size = 0.2))+ 
  theme(panel.grid.minor  = element_line(colour = "white", size = 0.5))+ 
  ggtitle("") + 
  theme(plot.title=element_text(size=13, face="bold", hjust = 1, vjust=0)) + 
  theme(plot.title = element_text(hjust = 0)) + 
  theme(axis.text.x = element_text(size = 10, face = "plain",  angle = 0, hjust = 0.5, vjust=1, colour="black", lineheight = 0)) + 
  theme(strip.text.y = element_text(angle = 0)) + 
  theme(strip.background=element_rect(fill="white")) + 
  guides(fill=guide_legend(title="Part")) +
  theme(axis.title.y = element_text(size=12, face="bold")) + 
  theme(axis.title.x  = element_text(size=14, face="bold"))+ 
  coord_cartesian(ylim=c())+
  theme(legend.position="right")+
  scale_y_continuous(expand = c(0, 0),limits=c(0, 110),breaks = seq(0, 100, by = 25))+
  geom_hline(yintercept=100, linetype="dashed", 
             color = "black", size=0.5)+
  coord_flip()
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

#ggsave(path="outputs", "FigureS2.png", width = 22, height = 15, units = "cm", dpi=300)

Step8 - Statistics - Do recovery rates differ between treatments?

statistics2 <- subset(NB_outputs2, (part2!="Larvae"))
statistics2 <- statistics2 %>%select(1, 2, 4, 7, 6)

#Anova
prueba <- statistics2 %>% 
  group_by(part2, variable2) %>%
  group_modify(~ broom::tidy(aov(value~treatment.x + trial.x, data = .x)))

prueba$significance <- ifelse(prueba$p.value<0.05 & prueba$p.value>0.01, "*",
                              ifelse(prueba$p.value<0.01 & prueba$p.value>0.001, "**",
                                     ifelse(prueba$p.value<0.001, "***", "")))

prueba

#write.csv(prueba, file="Anova_recoveries.csv", row.names = F)

Step9 - Figure 1 - Averaged recoveries per nutrient

Figure1 <- NB_outputs2
Figure1 <- ddply(Figure1, .(treatment.x, part2, variable2), summarize, 
                    mean= mean(value, na.rm=TRUE),
                    std_error= std.error(value, na.rm = TRUE))




ggplot(Figure1, aes(y= mean, x=treatment.x, fill=part2,), stat="identity")+
  geom_col(width = 0.85) + 
  geom_text(aes(label = (paste0(round(mean, digits = 0), " ± ", round(std_error, digits = 1))), group = part2), position = position_stack(vjust = 0.5), size=2.5)+
  scale_fill_manual(values=c("#FFA500", "#8FBC8F", "#808000"))+
  labs(y=expression("Recovery (%)"))+ 
  xlab("") +
  facet_grid(.~variable2)+
  theme(strip.background = element_rect(colour="white", fill="white"))+
  theme(strip.text = element_text(size=10, face="bold", hjust=0.5))+ 
  theme(panel.grid.major  = element_line(colour = "white", size = 0.2))+ 
  theme(panel.grid.minor  = element_line(colour = "white", size = 0.5))+ 
  ggtitle("") + 
  theme(plot.title=element_text(size=13, face="bold", hjust = 1, vjust=0)) + 
  theme(plot.title = element_text(hjust = 0)) + 
  theme(axis.text.x = element_text(size = 10, face = "plain",  angle = 90, hjust = 0.5, vjust=1, colour="black", lineheight = 0)) + 
  theme(strip.text.y = element_text(angle = 0)) + 
  theme(strip.background=element_rect(fill="white")) + 
  guides(fill=guide_legend(title="Legend")) +
  theme(axis.title.y = element_text(size=12, face="bold")) + 
  theme(axis.title.x  = element_text(size=14, face="bold"))+ 
  coord_cartesian(ylim=c())+
  theme(legend.position="bottom")+
  scale_y_continuous(expand = c(0, 0),limits=c(0, 110),breaks = seq(0, 100, by = 25))+
  geom_hline(yintercept=100, linetype="dashed", 
             color = "black", size=0.5)


#Save figure. This figure then was editted in Inkscape to add the bars and P.values showing the statistical differences bewtween treatments
#To save:
#ggsave(path="outputs", "Figure1.pdf", width = 22, height = 15, units = "cm", dpi=300)

Part 2 - Ammonia-N balance and nutrient ratios

Step10 - Ammonia balance

#get dataset
ammonia_balance <- NB
ammonia_balance <- subset(ammonia_balance, ((part2=="Fresh_manure" & treatment=="With_BSFL") | part2=="Residues" | part2=="Larvae"))

#select relevant columns
ammonia_balance <- ammonia_balance[, c(1, 2, 6, 8, 13)]

#calculate non nh3 N
ammonia_balance$Non_ammonia_N <- ifelse(is.na(ammonia_balance$NH3_overall), ammonia_balance$N_overall, (ammonia_balance$N_overall-ammonia_balance$NH3_overall))
colnames(ammonia_balance)[4] <- "Total_N"
colnames(ammonia_balance)[5] <- "Ammonia_N"

#save overall N in fresh manure (will be used in a later stage)
manure_n <- ammonia_balance[, c(1:4)]
manure_n <- subset(manure_n, (part2=="Fresh_manure"))

#Re-arrange dataset
ammonia_balance <- ammonia_balance[, c(1, 2, 3, 5, 6)]
ammonia_balance <- gather(ammonia_balance, "type_n", "value", 4:5)

#add  nh3 emissions
emissions_n <- total_n 
emissions_n$part2 <- "Emissions"
emissions_n$type_n <- "Ammonia_N"
colnames(emissions_n)[3] <- "value"
emissions_n <- emissions_n[, c(1, 2, 4, 5, 3)]

#bind two datasets
ammonia_balance <- rbind(ammonia_balance, emissions_n)

#add total n input to calculate percentages
manure_n <- manure_n[, c(1, 4)]
colnames(manure_n) [2] <- "N_input_manure"
ammonia_balance <- merge(ammonia_balance, manure_n, by="trial")

#calculate recovery
ammonia_balance$percentage <- ammonia_balance$value/ammonia_balance$N_input_manure*100
#remove NA
ammonia_balance <- na.omit(ammonia_balance)

ammonia_balance <- ammonia_balance[, c(1:4, 7)]

Step11 - Do ammonia and non-ammonia fractions differ between treatments?

#Anova
statistics_ammonia <- subset(ammonia_balance, (part2!="Fresh_manure" & part2!="Larvae"))

statistics_ammonia2 <- statistics_ammonia %>% 
  group_by(part2, type_n) %>%
  group_modify(~ broom::tidy(aov(percentage~treatment + trial, data = .x)))

statistics_ammonia2

#write.csv(statistics_ammonia2, file="Anova_Nammonia.csv", row.names = F)

Step12 - Figure 2 - Nitrogen balance

figure3 <- ammonia_balance

#New categories for the different fractions
figure3$categories <- ifelse(((ammonia_balance$part2=="Fresh_manure" |  ammonia_balance$part2=="Residues") & (ammonia_balance$type_n=="Ammonia_N")), "Ammonia-N in manure or residues",
                        ifelse(((ammonia_balance$part2=="Fresh_manure" |  ammonia_balance$part2=="Residues") & (ammonia_balance$type_n=="Non_ammonia_N")), "Non ammonia-N in manure or residues",
                               ifelse(ammonia_balance$part2=="Larvae", "N in larval biomass", "Ammonia-N emissions")))

figure3$name2_treatments <- ifelse(figure3$treatment=="With_BSFL" & figure3$part2=="Fresh_manure", "Fresh_manure", 
                   ifelse(figure3$treatment=="With_BSFL" & figure3$part2=="Residues", "With_BSFL",
                          ifelse(figure3$treatment=="With_BSFL" & figure3$part2=="Larvae", "With_BSFL", 
                                  ifelse(figure3$treatment=="With_BSFL" & figure3$part2=="Emissions", "With_BSFL", 
                                          ifelse(figure3$treatment=="Without" & figure3$part2=="Residues", "Without", "Without")))))
                        
figure3_s <- ddply(figure3, .(name2_treatments, categories),
                       summarize,
                       mean=mean(percentage),
                       std_error= std.error(percentage))

#calculate confidence interal for fresh manure
ci_ammonia_manure <- subset(figure3, (part2=="Fresh_manure"))
ci_ammonia_manure <- ci_ammonia_manure[, c(1, 7, 4, 5)]
ci_ammonia_manure <- ci_ammonia_manure %>%
                     group_by(type_n) %>%
                      do(tidy(CI(.$percentage)))
'tidy.numeric' is deprecated.
See help("Deprecated")`data_frame()` was deprecated in tibble 1.1.0.
Please use `tibble()` instead.'tidy.numeric' is deprecated.
See help("Deprecated")
ci_ammonia_manure <- spread(ci_ammonia_manure, names, x)
ci_ammonia_manure$meanlow<- ci_ammonia_manure$mean - ci_ammonia_manure$lower
ci_ammonia_manure$meanup <- ci_ammonia_manure$upper - ci_ammonia_manure$mean

#add column with confidence interval for fresh manure, the rest keep the standard error

figure3_s$variation <- ifelse(figure3_s$name2_treatments=="Fresh_manure" , as.numeric(14), figure3_s$std_error)

figure3_s$categories = factor(figure3_s$categories, 
                                         levels = c("N in larval biomass",
                                                    "Ammonia-N in manure or residues",
                                                    "Ammonia-N emissions",
                                                    "Non ammonia-N in manure or residues"))



ggplot(figure3_s, aes(fill=categories, y=mean, x=name2_treatments)) + 
  geom_bar(position="stack", stat="identity")+
  geom_text(aes(label = (paste0(round(mean, digits = 0), " ± ", round(variation, digits = 0))), group = categories), position = position_stack(vjust = 0.5), size=2.5)+
  theme_classic()+
  ylab("Percentage (%)")+
  xlab("")+
  scale_fill_manual(values = c("#D8E0BB", '#B6CEC7', "#86A3C3",'#7268A6'))+
  theme(legend.position = "right")+
  theme(axis.title.y = element_text(size=12)) + 
  theme(axis.title.x  = element_text(size=12))+
  theme(axis.text.x = element_text(size = 12))+
  theme(axis.text.y = element_text(size = 12))+
  scale_y_continuous(expand = c(0, 0),limits=c(0, 105),breaks = seq(0, 100, by = 25))+
  theme(legend.title=element_blank())

#ggsave(path="outputs", "Figure3.pdf", width = 22, height = 15, units = "cm", dpi=300)

Step13 - Data manipulation to calculate nutrient ratios

#Create new dataset from NB (part 1)
ratio <- NB

#Subset to obtain only the relevant parts
ratio <- subset(ratio, (part=="Fresh_manure" & treatment=="With_BSFL") | part2=="Residues")
#Modify the names of the categories to have "Fresh_manure", "Residues_larvae" and "Residues_manure"
ratio$part2 <- ifelse(ratio$part2=="Residues" & ratio$treatment=="With_BSFL", "Residues_larvae",
                          ifelse(ratio$part2=="Residues" & ratio$treatment=="Without", "Residues_manure", "Fresh_manure"))

#Select relevant columns
ratio <- ratio[, c(1, 6:13)]
#re-name columns
colnames(ratio) <- c("trial", 
                              "Item", 
                              "Dry matter (g)", 
                              "Total nitrogen (g)",
                              "Carbon (g)",
                              "Energy (g)",
                              "Potassium (g)",
                              "Phosphorus (g)",
                              "Ammonia (g)") 

#Remove energy & NH3
ratio <- ratio [, c(1:5,7, 8)]

#Calculate ratios
ratio$C_N <- ratio$`Carbon (g)`/ratio$`Total nitrogen (g)`
ratio$N_P <- ratio$`Total nitrogen (g)`/ratio$`Phosphorus (g)`
ratio$N_K <- ratio$`Total nitrogen (g)`/ratio$`Potassium (g)`
ratio$P_K <- ratio$`Phosphorus (g)`/ratio$`Potassium (g)`
ratio <- ratio[, c(1, 2, 8:11)]

ratio <- gather(ratio, ratio, value, 3:6)
ratio
NA

Step14 - Statistics - Do nutrient ratios differ between treatments?

#Anova
ratio_statistics <- subset(ratio, (Item!="Fresh_manure"))
ratio_statistics <- ratio_statistics%>% 
  group_by(ratio) %>%
  group_modify(~ broom::tidy(aov(value~Item + trial, data = .x)))

ratio_statistics$significance <- ifelse(ratio_statistics$p.value<0.05 & ratio_statistics$p.value>0.01, "*",
                              ifelse(ratio_statistics$p.value<0.01 & ratio_statistics$p.value>0.001, "**",
                                     ifelse(ratio_statistics$p.value<0.001, "***", "")))

ratio_statistics
#write.csv(ratio_statistics, file="Anova_ratios.csv", row.names = F)

Step15- Figure 3 - Averaged nutrient ratios with confidence interval for fresh manure

#Calculate averaged nutrient ratios
ratio_average <- subset(ratio, (Item!="Fresh_manure"))
ratio_average <- ddply(ratio_average, .(Item, ratio),
                       summarize,
                       mean=mean(value, na.rm=T),
                       std_error = std.error(value, na.rm=T))

#confidence interval fresh pig manure
ci_freshmanure <- subset(ratio, (Item=="Fresh_manure"))

ci_freshmanure <- ci_freshmanure %>%
                  group_by(ratio) %>%
                  do(tidy(CI(.$value)))
'tidy.numeric' is deprecated.
See help("Deprecated")'tidy.numeric' is deprecated.
See help("Deprecated")'tidy.numeric' is deprecated.
See help("Deprecated")'tidy.numeric' is deprecated.
See help("Deprecated")
ci_freshmanure <- spread(ci_freshmanure, names, x)

#merge confidence interval in the ratio dataset
ratio_average <- merge(ratio_average, ci_freshmanure, by="ratio")

#Change names of ratios
ratio_average$ratio <- ifelse(ratio_average$ratio=="C_N", "C:N",
                              ifelse(ratio_average$ratio=="N_K", "N:K",
                                     ifelse(ratio_average$ratio=="N_P", "N:P", "P:K")))


#Figure

ggplot(ratio_average, aes(x=Item, y=mean.x)) + 
  geom_point()+ 
  geom_errorbar(aes(min=mean.x-std_error, ymax=mean.x+std_error), width=.3) +
  geom_ribbon(aes(ymin = lower, ymax = upper, group=ratio), fill = "#20639B", alpha=0.6) +
  facet_wrap(~ratio, scales="free_y", ncol = 5) +
  labs(y=expression("Nutrient ratio"))+ 
  xlab("") +
  theme(strip.text = element_text(size=10, face="bold", hjust=0.5))+ 
  theme(panel.grid.major  = element_line(colour = "white", size = 0.2))+ 
  theme(panel.grid.minor  = element_line(colour = "white", size = 0.5))+ 
  ggtitle("") + 
  theme(plot.title=element_text(size=13, face="bold", hjust = 1, vjust=0)) + 
  theme(plot.title = element_text(hjust = 0)) + 
  theme(axis.text.x = element_text(size = 10, face = "plain",  angle = 65, hjust = 0.5, vjust=0.5, colour="black", lineheight = 0)) + 
  theme(strip.text.y = element_text(angle = 0)) + 
  theme(axis.line = element_line(size = 0.5, colour = "black"))+
  theme(strip.background = element_rect(colour="white", fill="white"))+
  theme(panel.background = element_rect(fill = "white", colour = "white"))+
  theme(axis.title.y = element_text(size=12, face="bold")) + 
  theme(axis.title.x  = element_text(size=14, face="bold"))+ 
  coord_cartesian(ylim=c())+
  theme(legend.position="none")


#Save figure. This figure was then editted in Inkscape.
#ggsave(path="outputs", "Figure2.pdf", width = 22, height = 15, units = "cm", dpi=300)

Part3 - Gas emissions and heat loss

Step16 - Gaseous emissions and heat losses (CO2, CH4, heat, oxygen)

#Get CO2, CH4, O2, HEAT and RQ
Gas_average <- chambers_summary2
Gas_average <- Gas_average[, c(1, 2, 3, 6, 7, 8, 9, 10, 11,13)]
Gas_average <- gather(Gas_average, "variable", "value", 6:10)


##import initial dry matter per trial (in grams) to estimate the emissions of gas/hour/kg initial manure
drymanure_g <- subset(NB, ((part2=="Fresh_manure" & treatment=="With_BSFL")))
drymanure_g <- drymanure_g[, c(1, 6, 7)]

#add dry matter manure per trial to calculate emissions per kg of DM initial manure
Gas_average <- merge(Gas_average, drymanure_g, by="trial")

#Calculate emissions (g/hour) per kg of initial DM manure input (except for RQ)
Gas_average$newvalue <- ifelse(Gas_average$variable!="mean_RQ", (((Gas_average$value*1000)/Gas_average$dryweight_grams)/24), Gas_average$value)
Gas_average <- Gas_average[, c(1:6, 10)]

#function to make first letter capital
firstup <- function(x) {
  x <- tolower(x)
  substr(x, 1, 1) <- toupper(substr(x, 1, 1))
  x
}

Gas_average$daynumber <- firstup(Gas_average$daynumber)

Step17 - Ammonia emissions

#Ammonia emissions on time
ammonia <- read.csv("ammonia.csv")

##name of the columns
# Ammonia
#[1] chamber - chamber number (7 and 8)  
#[2] date - date of the measurement in format day/month/year
#[3] time - time of the measurement in format hour/minute/second
#[4] verv_stpd - Air ventilation (L/min) corrected for temperature and pressure
#[5] vol_stp - Volume of the chamber (L) corrected for pressure and temperature
#[6] NH3_prod_lday - Ammonia in L/day
#[7] trial - trial number (T1, T2, T3 and T4)
#[8] treatment - treatment name (With_BSFL and Without)
#[9] hour - hour of the day in 24h format
#[10] minute - minute at which the measurement was taken (from 0 to 60)
#[11] second - second at which the measurement was taken (from 0 to 60)
#[12] daynumber - day number (from day1 and day10) in which the measurement took place

#Create dataset for time series plots (average per hour)
NH3_summary <- ddply(ammonia, .(trial, treatment, chamber, daynumber, hour), summarize, 
                     mean_NH3= mean(NH3_prod_lday, na.rm=TRUE), 
                     se_NH3= std.error(NH3_prod_lday, na.rm=TRUE))


NH3_summary$chamber <- ifelse(NH3_summary$chamber=="7", "C7", "C8")



#calculate emissions per nh3/hour/kg initial dm manure
NH3_summary <- merge(NH3_summary, drymanure_g, by="trial")
NH3_summary$newvalue <- ((NH3_summary$mean_NH3 *1000)/NH3_summary$dryweight_grams)/24
NH3_summary$variable <- "mean_NH3"

#Make the first letter of day capital
##function to make first letter capital
firstup <- function(x) {
  x <- tolower(x)
  substr(x, 1, 1) <- toupper(substr(x, 1, 1))
  x
}

NH3_summary$daynumber <- firstup(NH3_summary$daynumber)

NH3_summary <- NH3_summary[, c(1, 2, 3, 4, 5, 11, 10)] #this dataset will be bind to others to make the figure

Step18 - Bind gaseous with ammonia

#rbind ammonia with gas average
Gasses <- rbind(Gas_average, NH3_summary)

#change names and labels
#new names for figures
Gasses$name2 <- ifelse(Gasses$variable=="mean_CH4", 'CH4 (l/h)',
                       ifelse(Gasses$variable=="mean_CO2", 'CO2 (l/h)',
                              ifelse(Gasses$variable=="mean_heat", "Heat (KJ/h)", 
                                     ifelse(Gasses$variable== "mean_O2", "O2 (l/h)", 
                                            ifelse(Gasses$variable=="mean_RQ", "RQ", "NH3 (l/h)")))))

Step19 - Nitrous oxide - data manipulation

#Import dataset nitrous oxide
nitrous_oxide <- read.csv("nnitrous_oxide.csv")

#Name of columns
#[1] day - day number (from day1 and day10) in which the measurement took place
#[2] trial - trial number (T1, T2, T3 and T4)
#[3] roof - concentration of nitrous oxide (in ppm) outside the chamber
#[4] C7 - concentration of nitrous oxide (in ppm) inside chamber 7
#[5] C8 - concentration of nitrous oxide (in ppm) inside chamber 8


#Calculate the production inside the chamber and keep these columns
nitrous_oxide$Chamber7 <- nitrous_oxide$C7-nitrous_oxide$roof
nitrous_oxide$Chamber8 <- nitrous_oxide$C8-nitrous_oxide$roof
nitrous_oxide <- nitrous_oxide[, c(1, 2, 6, 7)]
nitrous_oxide <- gather(nitrous_oxide,  "chamber", "production", 3:4)

#name of the treatment
nitrous_oxide$treatment <-  ifelse(nitrous_oxide$chamber=="Chamber7" & nitrous_oxide$trial=="T1", "Without", 
                                ifelse(nitrous_oxide$chamber=="Chamber8" & nitrous_oxide$trial=="T1", "With_BSFL",
                                       ifelse(nitrous_oxide$chamber=="Chamber7" & nitrous_oxide$trial=="T2", "With_BSFL",
                                              ifelse(nitrous_oxide$chamber=="Chamber8" & nitrous_oxide$trial=="T2", "Without",
                                                     ifelse(nitrous_oxide$chamber=="Chamber7" & nitrous_oxide$trial=="T3", "Without",
                                                            ifelse(nitrous_oxide$chamber=="Chamber8" & nitrous_oxide$trial=="T3", "With_BSFL",
                                                                   ifelse(nitrous_oxide$chamber=="Chamber7" & nitrous_oxide$trial=="T4", "With_BSFL", "Without")))))))

#To calculate the production of N2O, we need to calculate the average ppm concentrations between two consecutive measurements
nitrous_oxide$con <- paste0(nitrous_oxide$trial, nitrous_oxide$treatment)
nitrous_oxide$value <- ifelse(nitrous_oxide$con== lead(nitrous_oxide$con), ((nitrous_oxide$production + lead(nitrous_oxide$production))/2), NA)
nitrous_oxide$daynumber <- ifelse(nitrous_oxide$con== lead(nitrous_oxide$con), paste0(nitrous_oxide$day, "-", lead(nitrous_oxide$day)), NA)
nitrous_oxide <- nitrous_oxide[, c(2, 5, 7, 8)]
nitrous_oxide <- na.omit(nitrous_oxide)


#Get ventilation per day
chambers_2 <- chambers
chambers_2$hour <- as.numeric(chambers_2$hour)

#ventilation is in l/min so to convert it to l/hour -> STPD*60
chambers_n2o <- ddply(chambers_2, .(trial, treatment, daynumber, hour), summarize, 
                      mean_ventilation = mean(STPD*60, na.rm=TRUE))

chambers_n2o$hour <- as.numeric(as.character(chambers_n2o$hour))

#new day classification based on the time of the day in which air samples were collected for N2O analysis
chambers_n2o$new <- ifelse((chambers_n2o$daynumber=="day1")|(chambers_n2o$daynumber=="day2" & chambers_n2o$hour<=8), "Day1-Day2", 
                         ifelse((chambers_n2o$daynumber=="day2" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day3" & chambers_n2o$hour<=8), "Day2-Day3",
                                ifelse((chambers_n2o$daynumber=="day3" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day4" & chambers_n2o$hour<=8), "Day3-Day4", 
                                       ifelse((chambers_n2o$daynumber=="day4" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day5" & chambers_n2o$hour<=8), "Day4-Day5",
                                              ifelse((chambers_n2o$daynumber=="day5" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day6" & chambers_n2o$hour<=8), "Day5-Day6",
                                                     ifelse((chambers_n2o$daynumber=="day6" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day7" & chambers_n2o$hour<=8), "Day6-Day7",
                                                            ifelse((chambers_n2o$daynumber=="day7" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day8" & chambers_n2o$hour<=8), "Day7-Day8",
                                                                   ifelse((chambers_n2o$daynumber=="day8" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day9" & chambers_n2o$hour<=8), "Day8-Day9",
                                                                          ifelse((chambers_n2o$daynumber=="day9" & chambers_n2o$hour>=9)|(chambers_n2o$daynumber=="day10" & chambers_n2o$hour<=8), "Day9-Day10", "nada"
                                                                          )))))))))
#calculate the total ventilation liters per new day number
chambers_n2o <- ddply(chambers_n2o, .(trial, treatment, new), summarize, 
                      total_stpd_vent = sum(mean_ventilation, na.rm=TRUE))


# merge both datasets (n2o production and ventilation)
chambers_n2o$concatenate <- paste0(chambers_n2o$trial, chambers_n2o$treatment, chambers_n2o$new)
nitrous_oxide$concatenate <- paste0(nitrous_oxide$trial, nitrous_oxide$treatment, nitrous_oxide$daynumber)
nitrous_oxide <- merge(nitrous_oxide, chambers_n2o, by="concatenate")

#apply equation to calculate production in mg per day
# 44 is the molar mass of n2o
# 22.4 is the molar volume of a gas
# *1000 is to convert it to miligrams
nitrous_oxide$n2o_mg <- ((nitrous_oxide$value*10^(-6))*nitrous_oxide$total_stpd_vent*(44/22.4))*1000

nitrous_oxide <- nitrous_oxide[, c(2, 3, 5, 10 )]
names(nitrous_oxide) <- c("trial", "treatment", "day", "n2o_mg")


#merge with drymatter manure to estimate n2o production per kg of dry matter manure
nitrous_oxide <- merge(nitrous_oxide, drymanure_g, by="trial")
nitrous_oxide$n2o_mg_perkg <- (1000*nitrous_oxide$n2o_mg)/nitrous_oxide$dryweight_grams
nitrous_oxide

Step20 - Statistics - Is N2O production different from zero?

#Test if N2O differs from zero
#t-test
t_n2o <- nitrous_oxide %>%
  group_by(treatment, day) %>%
  do(tidy(t.test(.$n2o_mg, alternative = "two.sided")))
t_n2o

#write.csv(t_n2o, "T_test_n2o.csv", row.names = F)

Step21 - Supplementary Figure 3 panel A

#Order factors for Supplementary Figure
Gasses$name2 <- factor(Gasses$name2, levels = c("CO2 (l/h)",
                                                            "CH4 (l/h)",
                                                            "Heat (KJ/h)",
                                                            "NH3 (l/h)",
                                                            "O2 (l/h)",
                                                            "RQ"))
Gasses$daynumber<- factor(Gasses$daynumber, levels = c("Day1", 
                                                                   "Day2", 
                                                                   "Day3", 
                                                                   "Day4", 
                                                                   "Day5", 
                                                                   "Day6", 
                                                                   "Day7", 
                                                                   "Day8", 
                                                                   "Day9", 
                                                                   "Day10"))

 ggplot(data=Gasses, aes(x=as.numeric(hour), y=newvalue, group=trial))+
  geom_line(size=1, aes(linetype=trial, col=trial))+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(name2~treatment+daynumber, scales = "free_y")+
  theme_bw()+
  ylab("")+
  scale_x_continuous(name="Time of the day (hours)", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  ggtitle("")+
  theme(legend.position = "bottom")+
  theme(axis.title.y = element_text(size=12)) + 
  theme(axis.title.x  = element_text(size=12))+
  scale_linetype_manual(values=c("solid", "dotted", "twodash", "longdash"))

 
 #ggsave(path="outputs", file="FigureS3_A.pdf", width = 25, height = 20, units="cm", dpi=300) #saves g

Step21 Supplementary Figure 3 - panel (B)

#Supplementary figure N2O
ggplot(data=nitrous_oxide, aes(x=day, y=n2o_mg_perkg, group=trial))+
  geom_line(size=1, aes(linetype=trial, col=trial))+
  geom_point()+
  facet_wrap(~treatment)+
  theme(axis.text = element_text(angle = 0, hjust = 0.5, size=10)) + 
  ylab("N2O (mg)/day/kg DM manure")+
  xlab("")+
  theme_bw()+
  theme(panel.spacing = unit(0.1, "lines"))+
  ggtitle("")+
  theme(legend.position = "right")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=4))+
  scale_linetype_manual(values=c("solid", "dotted", "twodash", "longdash"))+
  scale_x_discrete(labels=function(x){sub("-", "\n", x)})


#ggsave(path="outputs", file="FigureS3_B.pdf", width = 25, height = 10, units="cm", dpi=300) #saves g

Step22 - Figure 4

#Calculate average and std_error per day per treatment (for all gasses except N2O)
figure4 <- ddply(Gasses, .(treatment, daynumber, hour, name2), summarize, 
                           average= mean(newvalue, na.rm=TRUE),
                           std_error= std.error(newvalue, na.rm=TRUE))


#order days for figure
figure4$daynumber<- factor(figure4$daynumber, levels = c("Day1", 
                                                                   "Day2", 
                                                                   "Day3", 
                                                                   "Day4", 
                                                                   "Day5", 
                                                                   "Day6", 
                                                                   "Day7", 
                                                                   "Day8", 
                                                                   "Day9", 
                                                                   "Day10"))
#subset to make independent figures of each
CO2 <- subset(figure4, (name2=="CO2 (l/h)"))
CH4 <- subset(figure4, (name2=="CH4 (l/h)"))
HEAT <- subset(figure4, (name2=="Heat (KJ/h)"))
NH3 <- subset(figure4, (name2=="NH3 (l/h)"))
RQ <- subset(figure4, (name2=="RQ"))

#Figure CO2
CO2_fig <- ggplot(data=CO2, aes(x=as.numeric(hour), y=average, col= treatment, group=treatment, fill=treatment))+
  geom_line(size=1, aes(linetype=treatment))+
  geom_ribbon(aes(ymin=(average-std_error), ymax=(average+std_error), linetype=treatment), alpha=0.6)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(~daynumber, scales = "free_y")+
  theme_bw()+
  ylab(expression(CO[2]~(L/hour)))+
  scale_x_continuous(name="", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  theme(strip.background =element_rect(fill="white"))+
  scale_colour_manual(values = c("#5cb85c",'#E69F00'))+
  scale_fill_manual(values = c("#5cb85c",'#E69F00'))+
  ggtitle("")+
  theme(legend.position = "none")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=10))+
  scale_linetype_manual(values=c("solid", "dotted"))

#Figure CH4
CH4_fig <- ggplot(data=CH4, aes(x=as.numeric(hour), y=average*1000, col= treatment, group=treatment, fill=treatment))+
  geom_line(size=1, aes(linetype=treatment))+
  geom_ribbon(aes(ymin=(average*1000-std_error*1000), ymax=(average*1000+std_error*1000), linetype=treatment), alpha=0.6)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(~daynumber, scales = "free_y")+
  theme_bw()+
  ylab(expression(CH[4]~(mL/hour)))+
  scale_x_continuous(name="Time of the day (hours)", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  theme(strip.background =element_rect(fill="white"))+
  scale_colour_manual(values = c("#5cb85c",'#E69F00'))+
  scale_fill_manual(values = c("#5cb85c",'#E69F00'))+
  ggtitle("")+
  theme(legend.position = "none")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=10))+
  scale_linetype_manual(values=c("solid", "dotted"))

#Figure NH3
NH3_fig <- ggplot(data=NH3, aes(x=as.numeric(hour), y=average*1000, col= treatment, group=treatment, fill=treatment))+
  geom_line(size=1, aes(linetype=treatment))+
  geom_ribbon(aes(ymin=(average*1000-std_error*1000), ymax=(average*1000+std_error*1000), linetype=treatment), alpha=0.6)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(~daynumber, scales = "free_y")+
  theme_bw()+
  ylab(expression(NH[3]~(mL/hour)))+
  scale_x_continuous(name="Time of the day (hours)", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  theme(strip.background =element_rect(fill="white"))+
  scale_colour_manual(values = c("#5cb85c",'#E69F00'))+
  scale_fill_manual(values = c("#5cb85c",'#E69F00'))+
  ggtitle("")+
  theme(legend.position = "none")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=10))+
  scale_linetype_manual(values=c("solid", "dotted"))


#Figure NH3
RQ_fig <- ggplot(data=RQ, aes(x=as.numeric(hour), y=average, col= treatment, group=treatment, fill=treatment))+
  geom_line(size=1, aes(linetype=treatment))+
  geom_ribbon(aes(ymin=(average-std_error), ymax=(average+std_error), linetype=treatment), alpha=0.6)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(~daynumber, scales = "free_y")+
  theme_bw()+
  ylab("Respiratory quotient")+
  scale_x_continuous(name="Time of the day (hours)", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  theme(strip.background =element_rect(fill="white"))+
  scale_colour_manual(values = c("#5cb85c",'#E69F00'))+
  scale_fill_manual(values = c("#5cb85c",'#E69F00'))+
  ggtitle("")+
  theme(legend.position = "none")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=10))+
  scale_linetype_manual(values=c("solid", "dotted"))


#Figure N2O
#Given that we didn't take hourly measurements of N2O (only once per day), we need to make some data manipulation in order to
#get the same figure as the other gases.

#Extract same format of dataset from the dataset gas_average and adapt it for N2O
fig_n2o <- Gas_average
fig_n2o <- subset(fig_n2o, (variable=="mean_CH4"))
fig_n2o <- fig_n2o[, c(1, 2, 4, 5)]
fig_n2o$variable <- "mean_N2O"
fig_n2o$n2o_mg_perkg <- NA
fig_n2o <- subset(fig_n2o, (hour!="9"))
fig_n2o <- subset(fig_n2o, ((daynumber!="day1") & (hour!=17)))
fig_n2o <- subset(fig_n2o, ((daynumber!="day10") & (hour!=8)))


#Modify the name nomenclature
nitrous_oxide_modified <- nitrous_oxide
nitrous_oxide_modified$daynumber <- ifelse(nitrous_oxide_modified$day=="Day1-Day2", "Day2",
                          ifelse(nitrous_oxide_modified$day=="Day2-Day3", "Day3",
                                 ifelse(nitrous_oxide_modified$day=="Day3-Day4", "Day4",
                                        ifelse(nitrous_oxide_modified$day=="Day4-Day5", "Day5",
                                               ifelse(nitrous_oxide_modified$day=="Day5-Day6", "Day6",
                                                      ifelse(nitrous_oxide_modified$day=="Day6-Day7", "Day7",
                                                             ifelse(nitrous_oxide_modified$day=="Day7-Day8", "Day8",
                                                                    ifelse(nitrous_oxide_modified$day=="Day8-Day9", "Day9", "Day10"))))))))

#Indicate at what hour of the day N2O measurements were taken
nitrous_oxide_modified$hour <- ifelse(nitrous_oxide_modified$daynumber=="Day10", "8", "9")
nitrous_oxide_modified2 <- subset(nitrous_oxide_modified, (day=="Day1-Day2"))
nitrous_oxide_modified2$daynumber <- "Day1"
nitrous_oxide_modified2$hour <- 17
nitrous_oxide_modified2$n2o_mg_perkg <- 0
nitrous_oxide_modified <- rbind(nitrous_oxide_modified, nitrous_oxide_modified2)
nitrous_oxide_modified$variable <- "mean_N2O"
nitrous_oxide_modified <- nitrous_oxide_modified[, c(1, 2, 8, 9, 10, 7)]


#Bind the dataset with the structure of days and hours, with the one that contain the n2o measurements. 
fig_n2o <- rbind(fig_n2o, nitrous_oxide_modified)
names(fig_n2o)[5] <- "average"
fig_n2o$hour <- as.numeric(fig_n2o$hour)

#Make figure
fig_n2o$daynumber <- factor(fig_n2o$daynumber, levels = c("Day1",
                                                    "Day2",
                                                    "Day3",
                                                    "Day4",
                                                    "Day5",
                                                    "Day6",
                                                    "Day7",
                                                    "Day8",
                                                    "Day9",
                                                    "Day10"))


N2O_fig <- ggplot(data=fig_n2o, aes(x=as.numeric(hour), y=n2o_mg_perkg, fill=treatment, linetype=treatment))+
  geom_boxplot(width=8)+
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) + 
  facet_grid(~daynumber, scales = "free_y")+
  theme_bw()+
  ylab(expression(N[2]~O~(mL/day)))+
  scale_x_continuous(name="Time of the day (hours)", expand = c(0, 0), breaks = c(0, 12, 0))+
  theme(panel.spacing = unit(0.1, "lines"))+
  theme(strip.background =element_rect(fill="white"))+
  scale_colour_manual(values = c("#5cb85c",'#E69F00'))+
  scale_fill_manual(values = c("#5cb85c",'#E69F00'))+
  ggtitle("")+
  theme(legend.position = "none")+
  theme(axis.title.y = element_text(size=10)) + 
  theme(axis.title.x  = element_text(size=10))+
  scale_linetype_manual(values=c("solid", "dotted"))


allgraph <- arrangeGrob(CO2_fig, CH4_fig, NH3_fig, N2O_fig, RQ_fig , nrow=3) #generates g
Removed 1456 rows containing non-finite values (stat_boxplot).
#ggsave(path="outputs", file="Figure4.pdf", width = 25, height = 20, units="cm", dpi=300, allgraph) #saves g
knitr::include_graphics("Figure4.png")

Step 22 - Table 2 - emissions per kg of dry manure and per kg of fresh and dry larvae

#Get overall emissions (CO2, CH4, Energy, Oxygen, N and N2O) per replicate, per kg of manure, per kg of fresh and dry larvae
#Calculate N2O in miligrams

nitrous_oxide_mg <- ddply(nitrous_oxide, .(trial,treatment), summarize, 
                 total = sum(n2o_mg))
nitrous_oxide_mg $item <- "N2O (mg)"
names(nitrous_oxide_mg )[3] <- "value"
nitrous_oxide_mg <- nitrous_oxide_mg[, c(1, 2, 4, 3)]


#get total N (sum condensed water + acid)
total_n$item <- "N (g)"
names(total_n)[3] <- "value"
total_n<- total_n[, c(1,2,4,3)]


#get CO2, CH4, Oxygen and Heat
total_CO2_CH4_HEAT_O2
total_CO2_CH4_HEAT_O2 <- total_CO2_CH4_HEAT_O2[, c(1, 2, 6:9)]
names(total_CO2_CH4_HEAT_O2)[3] <- "CO2 (g)"
names(total_CO2_CH4_HEAT_O2)[4] <- "O2 (g)"
names(total_CO2_CH4_HEAT_O2)[5] <- "CH4 (g)"
names(total_CO2_CH4_HEAT_O2)[6] <- "Heat (KJ)"
total_CO2_CH4_HEAT_O2 <- gather(total_CO2_CH4_HEAT_O2, "item", "value", 3:6)


##bind datasets (nitrogen, chambers_summary and nitrous oxide)
Air_emissions <- rbind(total_n, total_CO2_CH4_HEAT_O2, nitrous_oxide_mg)


### Calculate emissions expressed in different units (per kg of dry manure, per kg of fresh larvae, per kg of dry larvae)

#Per kg of fresh larvae
#Add dry matter manure (grams)
Air_emissions <- merge(Air_emissions, drymanure_g, by="trial")
Air_emissions$kg_dry_manure <- (Air_emissions$value*1000)/Air_emissions$dryweight_grams
names(Air_emissions)[2] <- "treatment"


#Per kg of fresh larvae
#Fresh larvae yield per trial
f_l_yield <- subset(fresh_biomass, (part=="Larvae"))
f_l_yield <- f_l_yield[, c(1, 2, 5)]
f_l_yield$treatment <- "Fresh larvae yield (g)"
Air_emissions <- merge(Air_emissions, f_l_yield, by="trial")
Air_emissions$kgfreshlarvae <- (Air_emissions$value.x*1000)/Air_emissions$value.y
Air_emissions <- Air_emissions[, c(1, 2, 3, 4, 7, 10)]

#Per kg of dry larvae
#dry larvae yield per trial
d_l_yield <- subset(NB_outputs, (part2=="Larvae"))
d_l_yield <- d_l_yield[, c(2, 7)]
d_l_yield$treatment <- "Dry larvae yield (g)"
colnames(d_l_yield)[2] <- "value"
Air_emissions <- merge(Air_emissions, d_l_yield, by="trial")
Air_emissions$kgdrylarvae <-  (Air_emissions$value.x*1000)/Air_emissions$value
Air_emissions <- Air_emissions[, c(1:3, 5, 6, 9)]


#Remove the values per kg of fresh and dry larvae for the treatment Without (as there was no larvae)
Air_emissions <- gather(Air_emissions, "variable", "value", 4:6)
Air_emissions$concatenate <- paste0(Air_emissions$treat, Air_emissions$variable)
Air_emissions <- subset(Air_emissions, (concatenate!="Withoutkgfreshlarvae" & concatenate!= "Withoutkgdrylarvae")) #This contains the emissions per trial. This dataset will be used in step 24
names(Air_emissions)[2] <- "treatment"
#Use air emissions table to calculate averages (of all trials)

#Create supplementary table 2
TableS2 <- Air_emissions %>% select(1, 3, 4, 5)
TableS2 <- subset(TableS2, (variable!="kg_dry_manure"))
names(TableS2) <- c("Trial", "Item", "Variable", "Value")
TableS2 <- spread(TableS2, Variable, Value)

write.csv(TableS2, file = "TableS2.csv", row.names = F)

Table4 <- ddply(Air_emissions, .(treatment, item,  variable), summarize, 
                   mean = mean(value),
                   std_error =std.error(value))

#This will be done with standard deviation  to compare our emissions with other studies
Table_emissions_perkg_larvae <- ddply(Air_emissions, .(treatment, item,  variable), summarize, 
                   mean = mean(value),
                   std_dev =sd(value))

Table4$meanstderror <- paste0(round(Table4$mean, digits = 2), "±", round(Table4$std_error, digits = 2))
Table4 <- Table4[, c(1, 2, 3, 6)]
Table4 <- spread(Table4, treatment, meanstderror)

Table_emissions_perkg_larvae$meanstderror <- paste0(round(Table_emissions_perkg_larvae$mean, digits = 2), "±", round(Table_emissions_perkg_larvae$std_dev, digits = 2))
Table_emissions_perkg_larvae <- Table_emissions_perkg_larvae[, c(1, 2, 3, 6)]
Table_emissions_perkg_larvae <- spread(Table_emissions_perkg_larvae, treatment, meanstderror)

#Emissions per kg of fresh and dry larvae
em_dry_fresh <- subset(Table_emissions_perkg_larvae, variable=="kgdrylarvae" | variable=="kgfreshlarvae")
em_dry_fresh <- spread(em_dry_fresh, variable, With_BSFL)

#emissions per kg of dm manure
Table4 <- na.omit(Table4)
Table4 <- Table4[, c(1, 4, 3)]


#Calculate emissions in CO2 eq (combination of CH4 and N2O) to add it to Table4
CO2eq <- Air_emissions
CO2eq$CO2eq <- ifelse(CO2eq$item=="N2O (mg)", (((CO2eq$value)/1000)*298), 
                      ifelse(CO2eq$item=="CH4 (g)", (((CO2eq$value))*34), NA))

CO2eq <- na.omit(CO2eq)
CO2eq <- subset(CO2eq, (variable=="kg_dry_manure" | variable=="kgdrylarvae"))

CO2eq <-  ddply(CO2eq, .(trial, treatment, concatenate), summarize, 
                sum = sum(CO2eq))

CO2eq_mean <- ddply(CO2eq, .(treatment, concatenate), summarize, 
                    mean = mean(sum),
                    std_error = sd(sum))

CO2eq_mean$meanstderror <- paste0(round(CO2eq_mean$mean, digits = 1), "±", round(CO2eq_mean$std_error, digits = 1))#here you can see CO2eq per kg DM larvae 343.99±43.14 grams
CO2eq_mean <- CO2eq_mean[c(1, 3),]
CO2eq_mean <- CO2eq_mean[, c(1, 5)]


CO2eq_mean <- spread(CO2eq_mean, treatment, meanstderror)
CO2eq_mean$item <- "CO2 eq (g)"
CO2eq_mean <- CO2eq_mean[, c(3, 2, 1)]


#Finish table 4 (bind Table 4 with CO2eq_mean)
Table4 <- rbind(Table4, CO2eq_mean)
Table4

Step 24 - Statistics do overall emissions differ per treatment?

#Merge air emissions with CO2_eq before doing the multiple regression
#Mofify dataframe CO2eq to bind it to Air emissions
CO2eq <- subset(CO2eq, (concatenate!="With_BSFLkgdrylarvae")) 
CO2eq$item <- "CO2eq (g)"
CO2eq$variable <- "kg_dry_manure"
names(CO2eq)[4] <- "value"
CO2eq <- CO2eq[, c(1, 2, 5, 6, 4, 3)]

#Bind Air emissions and CO2eq and format dataset for statistical test
Air_emissions2 <- rbind(Air_emissions, CO2eq)
Air_emissions2 <- Air_emissions2[, c(1:5)] #remove column concatenate
#Select only the values expressed per kg of dry manure
Air_emissions2 <- subset(Air_emissions2, (variable=="kg_dry_manure"))

#Multiple regression

stats_gases <- Air_emissions2%>% 
  group_by(item) %>%
  group_modify(~ broom::tidy(aov(value~treatment + trial, data = .x)))

stats_gases$significance <- ifelse(stats_gases$p.value<0.05 & stats_gases$p.value>0.01, "*",
                              ifelse(stats_gases$p.value<0.01 & stats_gases$p.value>0.001, "**",
                                     ifelse(stats_gases$p.value<0.001, "***", "")))


stats_gases

#write.csv(stats_gases, file="ANOVA_Table5.csv", row.names = F)

Part 5 - Bioconversion parameters

Step 25 - Individual starter larvae size per batch (For Table S4)

#Estimate individual size of starter larvae per batch
#Weight (grams) group of 50 starters
starters_batch1 <- c(0.67,0.74,0.65,0.61,0.62,0.61,0.62,0.63,0.61,0.65)
starters_batch2 <- c(0.79,0.82,0.76,0.82,0.7,0.78,0.82,0.76,0.74,0.77)
starters_batch3 <- c(0.34,0.36,0.4,0.36,0.38,0.31,0.43,0.38,0.38,0.36)
starters_batch4 <- c(0.29,0.28,0.29,0.36,0.27,0.27,0.26,0.31,0.25,0.29)

batch_weight <- c(starters_batch1, starters_batch2, starters_batch3, starters_batch4)
trial <- rep(c("T1", "T2", "T3", "T4"), each=10, len=40)

#Create dataset starters_weight
starters_weight <- data.frame(batch_weight, trial)

#Calculate weight per individual larva (mg)
starters_weight$individual_weight <- (starters_weight$batch_weight/50)*1000

#Mean and standard error
starters1<- starters_weight %>%
  group_by(trial) %>%
  summarise(
    mean = mean(individual_weight),
    std_error = std.error(individual_weight))

starters1

Step 26 - Bioconversion parameters

#######Supplementary Table with detailed data of the bioconversion process.
#Fresh manure provided
trial <- c("T1", "T2", "T3", "T4")
fresh_m_provided<- c(20814.06, 16649.35, 18404.91, 18407.05)
fresh_manure <- data.frame(trial, fresh_m_provided)
fresh_manure$treatment <- "Fresh manure provided (g)"
fresh_manure <- fresh_manure[, c(1, 3, 2)]
colnames(fresh_manure)[3] <- "value"

#manure dry matter
dm_manure <- c(21.35, 25.39, 23.21, 25.65)
dry_manure <- data.frame(trial, dm_manure)
dry_manure$treatment <- "Manure dry matter (%)"
dry_manure <- dry_manure[, c(1, 3, 2)]
colnames(dry_manure)[3] <- "value"

#dry manure provided
drymanure <- merge(fresh_manure, dry_manure, by="trial")
drymanure$value <- drymanure$value.x*(drymanure$value.y/100)
drymanure <- drymanure[, c(1, 2, 6)]
colnames(drymanure)[2] <- "treatment"
drymanure$treatment <- "Dry manure provided (g)"


#Fresh larvae yield per trial
f_l_yield <- subset(fresh_biomass, (part=="Larvae"))
f_l_yield <- f_l_yield[, c(1, 2, 5)]
f_l_yield$treatment <- "Fresh larvae yield (g)"

#dry larvae yield per trial
d_l_yield <- subset(NB_outputs, (part2=="Larvae"))
d_l_yield <- d_l_yield[, c(2, 7)]
d_l_yield$treatment <- "Dry larvae yield (g)"
d_l_yield <- d_l_yield[, c(1, 3, 2)]
colnames(d_l_yield)[2] <- "treatment"
colnames(d_l_yield)[3] <- "value"

#DM percentage larvae
dm_l <- subset(chemical_analysis, (part=="Larvae"))
dm_l <- dm_l[, c(1, 2, 5)]
dm_l$treatment <- "Larvae dry matter content(%)"
colnames(dm_l)[3] <- "value"
dm_l$value <- dm_l$value/10

#fresh larvae gain
f_lg <- subset(fresh_biomass, (part=="Starters"))
f_lg <- f_lg[, c(1, 4, 5)]
f_lg$part <- "Fresh larvae gain weight (g)"
colnames(f_lg)[2] <- "treatment"
f_lg <- merge(f_lg, f_l_yield, by="trial")
f_lg$value <- f_lg$value.y-f_lg$value.x
f_lg <- f_lg[, c(1, 4, 6)]
colnames(f_lg) [2] <- "treatment"
f_lg$treatment<- "Fresh larvae gain weight (g)"

#dry larvae gain
d_lg <- subset(fresh_biomass, (part=="Starters"))
d_lg <- d_lg[, c(1, 4, 5)]
startersdm <- subset(chemical_analysis, (part=="Starters"))
startersdm <- subset(startersdm, (treatment=="With_BSFL"))
startersdm <- startersdm[, c(1, 2, 5)]
d_lg <- merge(d_lg, startersdm, by="trial")
d_lg$starters_dry<- d_lg$value*(d_lg$DM/1000)
d_lg <- d_lg[, c(1, 4, 6)]
d_lg <- merge(d_lg, d_l_yield, by="trial")
d_lg$drygain <- d_lg$value-d_lg$starters_dry
d_lg <- d_lg[, c(1, 2, 6)]
colnames(d_lg)[2] <- "treatment"
d_lg$treatment <- "Dry larvae gain weight (g)"
colnames(d_lg)[3] <- "value"


#kg of fresh larvae per kg of fresh
fly_xfreshmanure <- merge(fresh_manure, f_l_yield, by="trial")
fly_xfreshmanure$value2 <-(fly_xfreshmanure$value.y*1000)/fly_xfreshmanure$value.x
fly_xfreshmanure <- fly_xfreshmanure[, c(1, 2, 6)]
colnames(fly_xfreshmanure)[2] <- "treatment"
fly_xfreshmanure$treatment <- "Fresh larvae yield (g) per kg of fresh manure"
colnames(fly_xfreshmanure)[3] <- "value"  

#kg dry larvae per kf of dry manure
fly_xdrymanure <- merge(drymanure, d_l_yield, by="trial")
fly_xdrymanure$value2 <-(fly_xdrymanure$value.y*1000)/fly_xdrymanure$value.x
fly_xdrymanure <- fly_xdrymanure[, c(1, 2, 6)]
colnames(fly_xdrymanure)[2] <- "treatment"
fly_xdrymanure$treatment <- "Dry larvae yield (g) per kg of dry manure"
colnames(fly_xdrymanure)[3] <- "value"  


#Individual mature larvae weight
maturelarvae_trial1 <- c(4.24, 4.29, 4.12, 4.26, 3.45, 4.12, 4.27, 3.4, 4.18, 4.14)
maturelarvae_trial2 <- c(4.96, 5.07, 4.87, 4.69, 4.9, 4.7, 5.07, 5.07, 4.76, 4.74)
maturelarvae_trial3 <- c(3.94, 3.91, 4.03, 3.98, 3.98, 3.84, 4.12, 3.76, 4, 3.98)
maturelarvae_trial4 <- c(3.94, 3.91, 4.03, 3.98, 3.98, 3.84, 4.12, 3.76, 4, 3.98)

weight_mature_trial <- c(maturelarvae_trial1, maturelarvae_trial2, maturelarvae_trial3, maturelarvae_trial4)
trial_name <- rep(c("trial1", "trial2", "trial3", "trial4"), each=10, len=40)

#df weight mature larvae
maturelarvae_weight <- data.frame(trial_name, weight_mature_trial)
maturelarvae_weight$value <- (maturelarvae_weight$weight_mature_trial/50)*1000
colnames(maturelarvae_weight)[1] <- "trial"
colnames(maturelarvae_weight)[2] <- "treatment"
maturelarvae_weight$treatment <- "Final larvae individual weight (mg)"

#Weight starter larvae

starterlarvae_weight <- starters1
starterlarvae_weight$treatment <- "Starter larvae individual weight (mg)"
names(starterlarvae_weight)[2] <- "value"
starterlarvae_weight <- starterlarvae_weight[, c(1, 4, 2)]

#Join all datasets and create one with average and standard error
table_bioconversion_details <- rbind(fresh_manure, dry_manure, drymanure, f_l_yield, d_l_yield, dm_l, f_lg, d_lg, fly_xfreshmanure, fly_xdrymanure, maturelarvae_weight, starterlarvae_weight)
average_table_bioconversion_details <- ddply(table_bioconversion_details, .(treatment),
                                            summarize,
                                            mean=mean(value, na.rm=T),
                                            std_error = std.error(value, na.rm=T))


average_table_bioconversion_details$value2 <- paste0(round(average_table_bioconversion_details$mean, digits = 0), " ± ", 
                                                     (round(average_table_bioconversion_details$std_error, digits = 1)))


average_table_bioconversion_details <- average_table_bioconversion_details[, c(1, 4)]
colnames(average_table_bioconversion_details)[1] <- "Parameter"
colnames(average_table_bioconversion_details)[2] <- "Value"

average_table_bioconversion_details <- average_table_bioconversion_details[c(8, 4, 6, 2, 10, 11, 5, 1, 7, 3, 9),]
average_table_bioconversion_details
#write.csv(average_table_bioconversion_details,file = "Bioconversion_parameters.csv", row.names = F)
LS0tCnRpdGxlOiAnUiBjb2RlIGZvciBwYXBlciBCbGFjayBzb2xkaWVyIGZseSByZWFyZWQgb24gcGlnIG1hbnVyZTogYmlvY29udmVyc2lvbiBlZmZpY2llbmNpZXMsCiAgbnV0cmllbnQgcmVkdWN0aW9ucyBhbmQgZ3JlZW5ob3VzZSBnYXNzZXMnCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KKkpvdXJuYWwgb2YgV2FzdGUgTWFuYWdlbWVudCogIApBbGVqYW5kcm8gUGFyb2RpIF5hXiAsIFdhbHRlciBKLkouIEdlcnJpdHMgXmJeLCBKb29wIEouQS4gVmFuIExvb24gXmNeLCBJbWtlIEouTS4gRGUgQm9lciBeYV4sIEFuZHLDqSBKLkEuIEFhcm5pbmsgXmReLCBIYW5uYWggSC5FLiBWYW4gWmFudGVuIF5hXgoKXmFeIEFuaW1hbCBQcm9kdWN0aW9uIFN5c3RlbXMgZ3JvdXAsIFdhZ2VuaW5nZW4gVW5pdmVyc2l0eSAmIFJlc2VhcmNoLCBQLk8uIEJveCAzMzgsIDY3MDAgQUggV2FnZW5pbmdlbiwgdGhlIE5ldGhlcmxhbmRzICAKXmJeIEFuaW1hbCBOdXRyaXRpb24gZ3JvdXAsIFdhZ2VuaW5nZW4gVW5pdmVyc2l0eSAmIFJlc2VhcmNoLCBQLk8uIEJveCAzMzgsIDY3MDAgQUggV2FnZW5pbmdlbiwgdGhlIE5ldGhlcmxhbmRzICAKXmNeIExhYm9yYXRvcnkgb2YgRW50b21vbG9neSwgV2FnZW5pbmdlbiBVbml2ZXJzaXR5ICYgUmVzZWFyY2gsIFAuTy4gQm94IDE2LCA2NzAwIEFBIFdhZ2VuaW5nZW4sIHRoZSBOZXRoZXJsYW5kcyAgCl5kXiBEZXBhcnRtZW50IG9mIExpdmVzdG9jayBhbmQgRW52aXJvbm1lbnQsIFdhZ2VuaW5nZW4gVW5pdmVyc2l0eSAmIFJlc2VhcmNoLCBQLk8uIEJveCAzMzgsIDY3MDAgQUggV2FnZW5pbmdlbiwgdGhlIE5ldGhlcmxhbmRzICAKCkNvZGUgZWxhYm9yYXRlZCBieTogQWxlamFuZHJvIFBhcm9kaS4gYWxlamFuZHJvLnBhcm9kaXBhcm9kaUB3dXIubmwgIApodHRwczovL29yY2lkLm9yZy8wMDAwLTAwMDMtMTM1MS0xMzhYICAKClRoaXMgcm5vdGVib29rIGNvbnRhaW5zIGFsbCB0aGUgc3RlcHMgbWFkZSBmb3IgZGF0YSBtYW5hZ2VtZW50LCBzdGF0aXN0aWNhbCBhbmFseXNpcywgdGFibGVzIGFuZCB2aXN1YWxpemF0aW9ucy4gICAKCgpgYGB7cn0KI1NldCB3b3JraW5nIGRpcmVjdG9yeQpzZXR3ZCgid3JpdGUgcGF0aCBoZXJlIikKYGBgCgoKIyBHcmFwaGljYWwgc3VtbWFyeSBvZiB0aGlzIHNjcmlwdAoKYGBge3J9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJncmFwaGljYWxfc3VtbWFyeS5wbmciKQpgYGAKCiMgQWN0aXZhdGUgcGFja2FnZXMKVGhlIGZvbGxvd2luZyBwYWNrYWdlcyBhcmUgYmUgbmVlZGVkIHRvIHJ1biB0aGUgY29kZToKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5cikKbGlicmFyeShwbHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdHJpeCkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkocHVycnIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoYWdyaWNvbGFlKQpsaWJyYXJ5KFJtaXNjKQpgYGAKCiMjIFBhcnQgMSAtIE51dHJpZW50IGJhbGFuY2UgIAojIyMgU3RlcCAxIC0gRGF0YSBtYW5pcHVsYXRpb24gb2YgZGF0YXNldHMgZnJlc2hfYmlvbWFzcy5jc3YgYW5kIGNoZW1pY2FsX2FuYWx5c2lzLmNzdiAgCgpgYGB7ciBlY2hvPVRSVUV9CiNJbXBvcnQgZGF0YXNldHMgZnJlc2hfYmlvbWFzcyBhbmQgY2hlbWljYWxfYW5hbHlzaXMKI0ZyZXNoIGJpb21hc3MgLSBjb250YWlucyBpbml0aWFsIGFtb3VudHMgKGluIGdyYW1zKSBvZiBpbnB1dHMgYW5kIG91dHB1dHMgKGV4Y2VwdCBjb25kZW5zZWQgd2F0ZXIgYW5kIGFjaWQpCmZyZXNoX2Jpb21hc3MgPC0gcmVhZC5jc3YoImZyZXNoX2Jpb21hc3MuY3N2IikgCgojQ2hlbWljYWwgYW5hbHlzaXMgLSBjb250YWlucyB0aGUgY2hlbWljYWwgcmVzdWx0cyBvZiBldmVyeSBpbnB1dCBhbmQgb3V0cHV0CmNoZW1pY2FsX2FuYWx5c2lzIDwtIHJlYWQuY3N2KCJjaGVtaWNhbF9hbmFseXNpcy5jc3YiKQoKI0V4cGxhbmF0aW9uIG9mIGNvbHVtbnMKI0ZyZXNoIGJpb21hc3MKI1sxXSByZXAgLSByZXBldGl0aW9uIG51bWJlciAoUjEsIFIyLCBSMyBhbmQgUjQpCiNbMl0gdHJlYXRtZW50IC0gdHJlYXRtZW50IG5hbWUgKFdpdGhfQlNGTCBhbmQgV2l0aG91dCkKI1szXSBjaGFtYmVyIC0gY2hhbWJlciBudW1iZXIgKDcgYW5kIDgpCiNbNF0gcGFydCAtIG5hbWUgb2YgdGhlIHBhcnQgKEZyZXNoX21hbnVyZSwgU3RhcnRlcnMgKDctZGF5IG9sZCBsYXJ2YWUpLCBMYXJ2YWUgKDE2LWRheSBvbGQgbGFydmFlKSwgUmVzaWR1ZXMgV2l0aG91dCwgUmVzaWR1ZXMgV2l0aF9CU0ZMKQojWzVdIHZhbHVlIC0gYW1vdW50IChpbiBncmFtcykgb2YgZWFjaCBwYXJ0CgoKIyBDaGVtaWNhbCBhbmFseXNpcwojWzFdIHJlcCAtIHJlcGV0aXRpb24gbnVtYmVyIChSMSwgUjIsIFIzIGFuZCBSNCkKI1syXSB0cmVhdG1lbnQgbmFtZSAoV2l0aF9CU0ZMIGFuZCBXaXRob3V0KQojWzNdIGNoYW1iZXIgLSBjaGFtYmVyIG51bWJlciAoNyBhbmQgOCkKI1s0XSBwYXJ0IC0gbmFtZSBvZiB0aGUgcGFydCAoRnJlc2hfbWFudXJlLCBTdGFydGVycyAoNy1kYXkgb2xkIGxhcnZhZSksIExhcnZhZSAoMTYtZGF5IG9sZCBsYXJ2YWUpLCBSZXNpZHVlcyBXaXRob3V0LCBSZXNpZHVlcyBXaXRoX0JTRkwpCiNbNV0gRE0gLSBEcnkgbWF0dGVyIGNvbnRlbnQgb2YgZXZlcnkgcGFydCAoZy9rZykKI1s2XSBOSDMgLSBBbW1vbmlhIChnL2tnKQojWzddIEMgLSBUb3RhbCBjYXJib24gKGcva2cpCiNbOF0gTiAtIFRvdGFsIE4gKGcva2cpCiNbOV1QIC0gUGhvc3Bob3J1cyAoZy9rZykKI1sxMF1LIC0gUG90YXNzaXVtIChnL2tnKQojWzExXUUgLSBFbmVyZ3kgKGtKL2tnKQoKI0NyZWF0ZSBjb21tb24gY29sdW1uIGluIGJvdGggZGF0YXNldHMgdG8gbWVyZ2UgdGhlbQpmcmVzaF9iaW9tYXNzJGNvbmNhdGVuYXRlIDwtIHdpdGgoZnJlc2hfYmlvbWFzcywgcGFzdGUwKHRyaWFsLCAiXyIsIHRyZWF0bWVudCwgIl8iLCBwYXJ0KSkKY2hlbWljYWxfYW5hbHlzaXMkY29uY2F0ZW5hdGUgPC0gd2l0aChjaGVtaWNhbF9hbmFseXNpcywgcGFzdGUwKHRyaWFsLCAiXyIsIHRyZWF0bWVudCwgIl8iLCBwYXJ0KSkKCiNtZXJnZSBib3RoIGRhdGFzZXRzCm51dHJpZW50X2JhbGFuY2UgPC0gbWVyZ2UoY2hlbWljYWxfYW5hbHlzaXMsIGZyZXNoX2Jpb21hc3MsICBieT0iY29uY2F0ZW5hdGUiLCBhbGw9VCkKCiNSZW1vdmUgdW5uZWNlc3NhcnkgY29sdW1ucwpudXRyaWVudF9iYWxhbmNlIDwtIG51dHJpZW50X2JhbGFuY2UgWywgLSgxMzoxNiksIGRyb3A9RkFMU0VdCgojcmVvcmRlciBjb2x1bW5ucy4gVGhpcyBkYXRhc2V0IGNvbnRhaW5zIHRoZSBmcmVzaCB5aWVsZHMgKGcpIG9mIGVhY2ggcGFydCAoY29sdW1ucyA1OjYpIGFuZCBuZXh0IHRvIGl0IHRoZSBjaGVtaWNhbCBjb21wb3NpdGlvbiBpbiBkcnkgd2VpZ2h0IG9mIGVhY2ggcGFydCAoY29sdW1ucyA4OjE0KQpudXRyaWVudF9iYWxhbmNlIDwtIG51dHJpZW50X2JhbGFuY2VbLGMoMSwgMiwgMywgNCwgNSwgMTMsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIpXQoKI2NhbGN1bGF0ZSB0aGUgZHJ5IHlpZWxkcyAoZykgaW4gZWFjaCBwYXJ0LCBhbmQgZXN0aW1hdGUgaG93IG11Y2ggb2YgZWFjaCBudXRyaWVudHMgaXMgcHJlc2VudCBpbiBlYWNoIHBhcnQKI2NyZWF0ZSBuZXcgY29sdW1uIGZvciBkcnl3ZWlnaHQgdmFsdWVzCm51dHJpZW50X2JhbGFuY2UkZHJ5d2VpZ2h0X2dyYW1zIDwtIG51dHJpZW50X2JhbGFuY2UkdmFsdWUqKChudXRyaWVudF9iYWxhbmNlJERNKS8xMDAwKSAKCiNjcmVhdGUgbmV3IGNvbHVtbnMgZm9yIHRoZSBvdmVyYWxsIGNvbnRlbnQgb2YgZWFjaCBudXRyaWVudCAoaW4gZ3JhbXMpCm51dHJpZW50X2JhbGFuY2UkTl9vdmVyYWxsIDwtIChudXRyaWVudF9iYWxhbmNlJGRyeXdlaWdodF9ncmFtcypudXRyaWVudF9iYWxhbmNlJE4pLzEwMDAKbnV0cmllbnRfYmFsYW5jZSRDX292ZXJhbGwgPC0gKG51dHJpZW50X2JhbGFuY2UkZHJ5d2VpZ2h0X2dyYW1zKm51dHJpZW50X2JhbGFuY2UkQykvMTAwMApudXRyaWVudF9iYWxhbmNlJEVfb3ZlcmFsbCA8LSAobnV0cmllbnRfYmFsYW5jZSRkcnl3ZWlnaHRfZ3JhbXMqbnV0cmllbnRfYmFsYW5jZSRFTkVSR1kpLzEwMDAKbnV0cmllbnRfYmFsYW5jZSRLX292ZXJhbGwgPC0gKG51dHJpZW50X2JhbGFuY2UkZHJ5d2VpZ2h0X2dyYW1zKm51dHJpZW50X2JhbGFuY2UkSykvMTAwMApudXRyaWVudF9iYWxhbmNlJFBfb3ZlcmFsbCA8LSAobnV0cmllbnRfYmFsYW5jZSRkcnl3ZWlnaHRfZ3JhbXMqbnV0cmllbnRfYmFsYW5jZSRQKS8xMDAwCm51dHJpZW50X2JhbGFuY2UkTkgzX292ZXJhbGwgPC0gKG51dHJpZW50X2JhbGFuY2UkZHJ5d2VpZ2h0X2dyYW1zKm51dHJpZW50X2JhbGFuY2UkTkgzKS8xMDAwCgojc2VsZWN0IGFuZCByZS1uYW1lIGNvbHVtbnMKI1NlbGVjdCBjb2x1bW5zCm51dHJpZW50X2JhbGFuY2UgPC0gbnV0cmllbnRfYmFsYW5jZSAlPiUgc2VsZWN0KDI6NSwxNDoyMCkKbmFtZXMobnV0cmllbnRfYmFsYW5jZSlbMV0gPC0gInRyaWFsIgpuYW1lcyhudXRyaWVudF9iYWxhbmNlKVsyXSA8LSAidHJlYXRtZW50IgpuYW1lcyhudXRyaWVudF9iYWxhbmNlKVszXSA8LSAiY2hhbWJlciIKbmFtZXMobnV0cmllbnRfYmFsYW5jZSlbNF0gPC0gInBhcnQiCgpudXRyaWVudF9iYWxhbmNlCmBgYAojIyMgU3RlcDIgLSBEYXRhIG1hbmlwdWxhdGlvbiBmb3Igbml0cm9nZW4gZW1pc3Npb25zCmBgYHtyIGVjaG89VFJVRX0KI0ltcG9ydCBkYXRhc2V0IEFjaWQgKEFDKSBhbmQgY29uZGVuc2VkIHdhdGVyIChDVykgLSBjb250YWlucyBwYXJhbWV0ZXJzIHJlbGF0ZWQgdG8gQUMgYW5kIENXIHRvIGVzdGltYXRlIGhvdyBtdWNoIG5pdHJvZ2VuIHdhcyBsb3N0IGFzIGdhc2VvdXMgbG9zc2VzLiAKYWNpZF9jb25kZW5zZWRfd2F0ZXIgPC0gcmVhZC5jc3YoImFjaWRfY29uZGVuc2VkX3dhdGVyLmNzdiIpCgojQ29sdW1ucyBBY2lkX2NvbmRlbnNlZCB3YXRlcjoKI1sxXSByZXAgLSByZXBldGl0aW9uIG51bWJlciAoUjEsIFIyLCBSMyBhbmQgUjQpCiNbMl0gdHJlYXRtZW50IG5hbWUgKFdpdGhfQlNGTCBhbmQgV2l0aG91dCkKI1szXSBjaGFtYmVyIC0gY2hhbWJlciBudW1iZXIgKDcgYW5kIDgpCiNbNF0gYWNpZF9ib3R0bGVlbXB0eV9ncmFtcyAtIFdlaWdodCBvZiB0aGUgZW1wdHkgY29udGFpbmVyIHRoYXQgY29udGFpbmVkIHRoZSBhY2lkIChncmFtcykKI1s1XSBhY2lkX2JvdHRsZV9hZnRlcnBlcmlvZF9ncmFtcyAtIFdlaWdodCBvZiB0aGUgY29udGFpbmVyIHdpdGggYWNpZCBzYW1wbGUgYXQgdGhlIGVuZCBvZiB0aGUgZXhwZXJpbWVudGFsIHBlcmlvZCAoZ3JhbXMpCiNbNl0gYWNpZF9nYXNtZXRlcl92YWx1ZXVwZnJvbnRfbTMgLSBWYWx1ZSBvZiB0aGUgZ2FzIG1ldGVyIGJlZm9yZSB0aGUgZXhwZXJpbWVudGFsIHBlcmlvZCAoaW4gbTMpLiBUaGUgZmxvd21ldGVyIG1lYXN1cmVkIHRoZSBhbW91bnQgb2YgYWlyIChtMykgdGhhdCBpc2ZsdXNoZWQgaW50byB0aGUgY29udGFpbmVyIHdpdGggYWNpZCBkdXJpbmcgdGhlIGV4cGVyaW1lbnRhbCBwZXJpb2QKI1s3XSBhY2lkX2dhc21ldGVyX3ZhbHVlYWZ0ZXJwZXJpb2RfbTMgLSBWYWx1ZSBvZiB0aGUgZ2FzIG1ldGVyIGF0IHRoZSBlbmQgb2YgdGhlIGV4cGVyaW1lbnRhbCBwZXJpb2QgKGluIG0zKS4KI1s4XSBuZXRfYWlyX2Zsb3dtMyAtIG5ldCBhbW91bnQgb2YgYWlyIHRoYXQgZmx1c2hlZCAoY29sdW1uIDcgLSBjb2x1bW4gNikKI1s5XSBvdmVyYWxsX2Fpcl9mbG93IC0gT3ZlcmFsbCBhaXIgZmxvdyB0byB0aGUgY2xpbWF0ZSByZXNwaXJhdGlvbiBjaGFtYmVycyAoaW4gbTMpCiNbMTBdIE5fYWNpZF91bml0cyAtIGdyYW1zIG9mIE4gKGcva2cpIGluIGFjaWQKI1sxMV0gY3dfbmV0X2dyYW1zIC0gIGdyYW1zIG9mIGNvbmRlbnNlZCB3YXRlciBpbiBlYWNoIHJlcGV0aXRpb24gKGdyYW1zKQojWzEyXSBOX2NvbmRlbnNlZHdhdGVyX3VuaXRzIC0gZ3JhbXMgb2YgTiAoZy9rZykgaW4gY29uZGVuc2VkIHdhdGVyCgojc2VwYXJhdGUgdGhlIGRhdGFzZXQgYWNpZF9jb25kZW5zZWRfd2F0ZXIgaW4gdHdvIHNlY3Rpb25zOiBvbmUgZm9yIGFjaWQgYW5kIHRoZSBvdGhlciBmb3IgY29uZGVuc2VkIHdhdGVyCmFjaWQgPC0gYWNpZF9jb25kZW5zZWRfd2F0ZXIgJT4lIHNlbGVjdCgxOjEwKQpjb25kZW5zZWR3YXRlciA8LSBhY2lkX2NvbmRlbnNlZF93YXRlciAlPiUgc2VsZWN0KDEsIDIsIDMsIDExLCAxMikKCiMgQWNpZAojY2FsY3VsYXRlIG5ldCB3ZWlnaHQgdmFsdWVzIG9mIGFjaWQgKGdyYW1zKSBhbmQgdG90YWwgZ2FzIGZsb3cKYWNpZCRuZXRib3R0bGVfZ3JhbXMgPC0gYWNpZCRhY2lkX2JvdHRsZV9hZnRlcnBlcmlvZF9ncmFtcyAtIGFjaWQkYWNpZF9ib3R0bGVlbXB0eV9ncmFtcwoKI2NhbGN1bGF0ZSB0aGUgdG90YWwgYW1vdW50IG9mIE4gaW4gZWFjaCBhY2lkIHNhbXBsZQphY2lkJE5fc2FtcGxlX2dyYW1zIDwtIChhY2lkJE5fYWNpZF91bml0cyphY2lkJG5ldGJvdHRsZV9ncmFtcykvMTAwMAoKI2NhbGN1bGF0ZSB0aGUgdG90YWwgZ3JhbXMgb2YgTiBpbiB0aGUgd2hvbGUgZXhwZXJpbWVudGFsIHBlcmlvZCBwZXJpb2QKYWNpZCROX292ZXJhbGwgPC0gYWNpZCROX2FjaWRfdW5pdHMvMTAwMCAqIChhY2lkJG92ZXJhbGxfYWlyX2Zsb3cqYWNpZCRuZXRib3R0bGVfZ3JhbXMvYWNpZCRuZXRfYWlyX2Zsb3dtMykKYWNpZCRDX292ZXJhbGwgPC0gMAphY2lkJEVfb3ZlcmFsbCA8LSAwCmFjaWQkS19vdmVyYWxsIDwtIDAKYWNpZCRQX292ZXJhbGwgPC0gMAphY2lkJE5IM19vdmVyYWxsIDwtIDAKCiNSZW9yZGVyIGRhdGFzZXQgdG8gYmluZCBpdCB0byBudXRyaXRpb25hbF9vdmVyYWxsCmFjaWQgPC0gYWNpZCAlPiUgIHNlbGVjdCgxOjMsIDEzOjE4KQphY2lkJHBhcnQgPC0gIkFjaWQiCmFjaWQkZHJ5d2VpZ2h0X2dyYW1zIDwtIE5BCmFjaWQgPC0gYWNpZFssIGMoMSwgMiwgMywgMTAsIDExLCA0LCA1LCA2LCA3LCA4LCA5KV0KCgojQ29uZGVuc2VkIHdhdGVyCmNvbmRlbnNlZHdhdGVyJE5fb3ZlcmFsbCA8LSAoY29uZGVuc2Vkd2F0ZXIkY3dfbmV0X2dyYW1zICogY29uZGVuc2Vkd2F0ZXIkTl9jb25kZW5zZWR3YXRlcl91bml0cykvMTAwMApjb25kZW5zZWR3YXRlciRDX292ZXJhbGwgPC0gMApjb25kZW5zZWR3YXRlciRFX292ZXJhbGwgPC0gMApjb25kZW5zZWR3YXRlciRLX292ZXJhbGwgPC0gMApjb25kZW5zZWR3YXRlciRQX292ZXJhbGwgPC0gMApjb25kZW5zZWR3YXRlciROSDNfb3ZlcmFsbCA8LSAwCgoKI2Zvcm1hdCBkYXRhc2V0IGFzIGFjaWQyCmNvbmRlbnNlZHdhdGVyIDwtIGNvbmRlbnNlZHdhdGVyICU+JSBzZWxlY3QgKDEsIDIsIDMsIDY6MTEpCmNvbmRlbnNlZHdhdGVyJHBhcnQgPC0gIkNvbmRlbnNlZF9XYXRlciIKY29uZGVuc2Vkd2F0ZXIkZHJ5d2VpZ2h0X2dyYW1zIDwtIE5BCmNvbmRlbnNlZHdhdGVyIDwtIGNvbmRlbnNlZHdhdGVyWywgYygxLCAyLCAzLCAxMCwgMTEsIDQ6OSldCgojbmV3ZGF0YXNldCBmb3IgdG90YWwgTiBlbWlzc2lvbnMgKHN1bSBhY2lkIGFuZCBjb25kZW5zZWQgd2F0ZXIpCnRvdGFsX24gPC0gcmJpbmQoKGNvbmRlbnNlZHdhdGVyICU+JXNlbGVjdCgxLCAyLCA0LCA2KSksIChhY2lkICU+JXNlbGVjdCgxLCAyLCA0LCA2KSkpCnRvdGFsX24gPC0gIGRkcGx5KHRvdGFsX24sIC4odHJpYWwsIHRyZWF0bWVudCksIHN1bW1hcml6ZSwgCiAgICAgICAgICAgICAgICAgIE5fZz0gc3VtKE5fb3ZlcmFsbCwgbmEucm09VFJVRSkpCgp0b3RhbF9uaXRyb2dlbiA8LSByYmluZChjb25kZW5zZWR3YXRlciwgYWNpZCkKdG90YWxfbml0cm9nZW4KYGBgCgojIyMgU3RlcDMgLSBEYXRhIG1hbmlwdWxhdGlvbiBmb3IgQ08yIGFuZCBDSDQgZW1pc3Npb25zLCBhbmQgaGVhdCBsb3NzCgpgYGB7ciBlY2hvPVRSVUV9CiNJbXBvcnQgZGF0YXNldCB3aXRoIGdhcyBhbmQgaGVhdCBkYXRhIG9idGFpbmVkIGZyb20gdGhlIHJlc3BpcmF0aW9uIGNoYW1iZXIgKENPMiwgQ0g0LCBPMiwgRU5FUkdZKQpjaGFtYmVycyA8LSByZWFkLmNzdigiY2hhbWJlcmRhdGFfbWFudXJlLmNzdiIpCgojQ29sdW1ucyBjaGFtYmVyIGRhdGEKIyBDaGFtYmVycwojWzFdIGNoYW1iZXIgLSBjaGFtYmVyIG51bWJlciAoNyBhbmQgOCkgIAojWzNdIGRhdGUgLSBkYXRlIG9mIHRoZSBtZWFzdXJlbWVudCBpbiBmb3JtYXQgZGF5L21vbnRoL3llYXIKI1s0XSB0aW1lIC0gdGltZSBvZiB0aGUgbWVhc3VyZW1lbnQgaW4gZm9ybWF0IGhvdXIvbWludXRlL3NlY29uZAojWzVdIEhlYXQgLSBIZWF0IHByb2R1Y3Rpb24gaW4gS0ovZGF5CiNbNl0gTzIgLSBPeGlnZW4gY29uc3VtcHRpb24gKEwvZGF5KQojWzddIENPMiAtIENhcmJvbiBkaW94aWRlIHByb2R1Y3Rpb24gKEwvZGF5KQojWzhdIFJRIC0gUmVzcGlyYXRvcnkgcXVvdGllbnQgKG9idGFpbmVkIGJ5IGRpdmlkaW5nIENPMi9PMikKI1s5XSBCYXJvbWV0cmljX3ByZXNzdXJlX21tSGcgLSBCYXJvbWV0cmljX3ByZXNzdXJlIGluc2lkZSB0aGUgY2hhbWJlcgojWzEwXSBUZW1wZXJhdHVyZSAtIFRlbXBlcmF0dXJlIChDZWxzaXVzKSBpbnNpZGUgdGhlIGNoYW1iZXIKI1sxMV0gSHVtaWRpdHkgLSBIdW1pZGl0eSAoJSkgaW5zaWRlIHRoZSBjaGFtYmVyCiNbMTJdIFNUUEQgLSBBaXIgdmVudGlsYXRpb24gKEwvbWluKSBhdCBzdGFuZGFyZCBwcmVzc3VyZSBhbmQgdGVtcGVyYXR1cmUKI1sxM10gQ0g0IC0gbWV0aGFuZSAoTC9kYXkpCiNbMTRdIHRyZWF0bWVudCAtIHRyZWF0bWVudCBuYW1lIChXaXRoX0JTRkwgYW5kIFdpdGhvdXQpCiNbMTVdIGhvdXIgLSBob3VyIG9mIHRoZSBkYXkgaW4gMjRoIGZvcm1hdAojWzE2XSBtaW51dGUgLSBtaW51dGUgYXQgd2hpY2ggdGhlIG1lYXN1cmVtZW50IHdhcyB0YWtlbiAoZnJvbSAwIHRvIDYwKQojWzE3XSBzZWNvbmQgLSBzZWNvbmQgYXQgd2hpY2ggdGhlIG1lYXN1cmVtZW50IHdhcyB0YWtlbiAoZnJvbSAwIHRvIDYwKQojWzE4XSBkYXludW1iZXIgLSBkYXkgbnVtYmVyIChmcm9tIGRheTEgYW5kIGRheTEwKSBpbiB3aGljaCB0aGUgbWVhc3VyZW1lbnQgdG9vayBwbGFjZQoKI0NhbGN1bGF0ZSB0aGUgcHJvZHVjdGlvbiBvZiBlYWNoIGdhcyBhbmQgaGVhdCBwZXIgaG91cgpjaGFtYmVyc19zdW1tYXJ5MiA8LSBkZHBseShjaGFtYmVycywgLih0cmVhdG1lbnQsIHRyaWFsLCBkYXludW1iZXIsIGhvdXIsIGNoYW1iZXIpLCBzdW1tYXJpemUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuX0NPMj0gbWVhbihDTzIsIG5hLnJtPVRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VfQ08yPSBzdGQuZXJyb3IoQ08yLCBuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbl9DSDQ9IG1lYW4oQ0g0LCBuYS5ybT1UUlVFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlX0NIND0gc3RkLmVycm9yKENINCwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5fTzI9bWVhbihPMiwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlX08yPXN0ZC5lcnJvcihPMiwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5faGVhdD0gbWVhbihIZWF0LCBuYS5ybT1UUlVFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlX2hlYXQ9IHN0ZC5lcnJvcihIZWF0LCBuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbl90ZW1wPSBtZWFuKFRlbXBlcmF0dXJlLCBuYS5ybT1UUlVFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlX3RlbXA9IHN0ZC5lcnJvcihUZW1wZXJhdHVyZSwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5fUlE9IG1lYW4oUlEsIG5hLnJtPVRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VfUlE9IHN0ZC5lcnJvcihSUSwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5fU1REUD0gbWVhbihTVFBELCBuYS5ybT1UUlVFKSkKCiNGb3JtYXQgY29sdW1uIGhvdXIgYXMgbnVtZXJpYyBhbmQgc2V0IHRoZSBjb3JyZWN0IG9yZGVyIG9mIHRoZSBkYXlzIGFuZCByZXBsaWNhdGVzCgpjaGFtYmVyc19zdW1tYXJ5MiRob3VyIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNoYW1iZXJzX3N1bW1hcnkyJGhvdXIpKQpjaGFtYmVyc19zdW1tYXJ5MiRkYXludW1iZXI9IGZhY3RvcihjaGFtYmVyc19zdW1tYXJ5MiRkYXludW1iZXIsIGxldmVscyA9YygiZGF5MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkYXkyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRheTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF5NCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkYXk1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRheTYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF5NyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkYXk4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRheTkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF5MTAiKSkKCmNoYW1iZXJzX3N1bW1hcnkyJHRyaWFsPSBmYWN0b3IoY2hhbWJlcnNfc3VtbWFyeTIkdHJpYWwsIGxldmVscyA9YygiVDEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlQyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUMyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVDQiKSkKI0VkaXQgY2hhbWJlciBudW1iZXIKY2hhbWJlcnNfc3VtbWFyeTIkY2hhbWJlciA8LSBpZmVsc2UoY2hhbWJlcnNfc3VtbWFyeTIkY2hhbWJlcj09IjgiLCAiQzgiLCAiQzciKQoKCiNGb3JtYXQgY29sdW1uIHRvIGJpbmQgaXQgdG8gdGhlIG9uZXMgZnJvbSBzdGVwcyAxIGFuZCAyCmNoYW1iZXJzX3N1bW1hcnkyJHBhcnQgPC0gIkVtaXNzaW9ucy9sb3NzIgpjaGFtYmVyc19zdW1tYXJ5MiRkcnl3ZWlnaHRfZ3JhbXMgPC0gTkEKY2hhbWJlcnNfc3VtbWFyeTIgPC0gY2hhbWJlcnNfc3VtbWFyeTJbLCBjKDIsIDEsIDUsIDE5LCAyMCwgMywgNCwgNiwgOCwgMTAsIDEyLCAxNCwgMTYpXQoKI0FsbCBnYXNlb3VzIGxvc3NlcyBhcmUgZXhwcmVzc2VkIGluIGwvZGF5LiBUbyBnZXQgdGhlIG92ZXJhbGwgcHJvZHVjdGlvbiBvZiBlYWNoIGdhcyBpbiBncmFtcyAoYW5kIGhlYXQgaW4gS0opLCBkaXZpZGUgZXZlcnkgcmVjb3JkIGJ5IDI0IGFuZCBtdWx0aXBseSB0aGlzIHZhbHVlIGJ5IGEgZmFjdG9yICB0byBjb252ZXJ0IGl0IGZyb20gbGl0ZXJzIHRvIGdyYW1zLiBUaGlzIGZhY3RvciBpcyB0aGUgbW9sYXIgbWFzcy8yMi40CiNDTzIgLT4gNDQuMDEvMjIuNCA9IDEuOTY0NzMyCiNPMiAtPiAzMi8yMi40ID0gMS40Mjg1NzEKI0NINCAtPiAxNi4wNi8yMi40ID0gMC43MTY5NjQzCgpjaGFtYmVyc19zdW1tYXJ5MyA8LSBkZHBseShjaGFtYmVyc19zdW1tYXJ5MiwgLih0cmlhbCwgdHJlYXRtZW50LCBjaGFtYmVyLCBwYXJ0LCBkcnl3ZWlnaHRfZ3JhbXMpLCBzdW1tYXJpemUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBDTzI9IHN1bShtZWFuX0NPMi8yNCwgbmEucm09VFJVRSkgKiAxLjk2NDczNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTzI9IHN1bShtZWFuX08yLzI0LCBuYS5ybT1UUlVFKSAqIDEuNDI4NTcxLAogICAgICAgICAgICAgICAgICAgICAgICAgICBDSDQ9IHN1bShtZWFuX0NINC8yNCwgbmEucm09VFJVRSkqIDAuNzE2OTY0MywKICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBVD0gc3VtKG1lYW5faGVhdC8yNCwgbmEucm09VFJVRSkpCnRvdGFsX0NPMl9DSDRfSEVBVF9PMiA8LSBjaGFtYmVyc19zdW1tYXJ5MwogICAgICAgICAgICAgICAgICAgICAgICAgICAKI0NhbGN1bGF0ZSB0aGUgY29udGVudCBvZiBDIChncmFtcykgaW4gQ08yIGFuZCBDSDQuCmNoYW1iZXJzX3N1bW1hcnkzJE5fb3ZlcmFsbCA8LSAwCmNoYW1iZXJzX3N1bW1hcnkzJENfb3ZlcmFsbCA8LSAoY2hhbWJlcnNfc3VtbWFyeTMkQ08yKjAuMjcyNzI3MjcpICsgKGNoYW1iZXJzX3N1bW1hcnkzJENINCowLjc0NzE5OCkgI3RoZXNlIGZhY3RvcnMgYXJlIHVzZWQgdG8gZ2V0IHRoZSBncmFtcyBvZiBjYXJib24uCmNoYW1iZXJzX3N1bW1hcnkzJEVfb3ZlcmFsbCA8LSBjaGFtYmVyc19zdW1tYXJ5MyRIRUFUCmNoYW1iZXJzX3N1bW1hcnkzJEtfb3ZlcmFsbCA8LSAwCmNoYW1iZXJzX3N1bW1hcnkzJFBfb3ZlcmFsbCA8LSAwCmNoYW1iZXJzX3N1bW1hcnkzJE5IM19vdmVyYWxsIDwtIDAKY2hhbWJlcnNfc3VtbWFyeTMgPC0gY2hhbWJlcnNfc3VtbWFyeTMgJT4lIHNlbGVjdCAoMSwgMiwgMywgNCwgNSwgMTA6MTUpCgpjaGFtYmVyc19zdW1tYXJ5MwpgYGAKIyMjIFN0ZXAgNCAtIEJpbmQgZGF0YXNldHMgZnJvbSBzdGVwMSwgc3RlcDIgYW5kIHN0ZXAzCgpgYGB7ciBlY2hvPVRSVUV9CiNyYmluZCBhbGwgYmFzZXMgKGZyZXNoLCBhY2lkLCBjb25kZW5zZWQgd2F0ZXIsIGNoYW1iZXJzX3N1bW1hcnkpCk5CIDwtIHJiaW5kKG51dHJpZW50X2JhbGFuY2UsIGFjaWQsIGNvbmRlbnNlZHdhdGVyLCBjaGFtYmVyc19zdW1tYXJ5MykKCiNDcmVhdGUgbmV3IGNvbHVtbnMgKGNhdGVnb3J5IChJbnB1dCAmIE91dHB1dCkgYW5kIHBhcnQyIHRoYXQgd2lsbCBiZSB1c2VkIGZvciB0aGUgZmlndXJlcwpOQiRjYXRlZ29yeSA8LSBpZmVsc2UoKE5CJHBhcnQ9PSJTdGFydGVycyIgfCBOQiRwYXJ0PT0iRnJlc2hfbWFudXJlIiksICJJbnB1dCIsICJPdXRwdXQiKQpOQiRwYXJ0MiA8LSBpZmVsc2UoKE5CJHBhcnQ9PSJBY2lkIiB8IE5CJHBhcnQ9PSJDb25kZW5zZWRfV2F0ZXIiIHwgTkIkcGFydD09IkFlcmlhbF9sb3NzZXMiKSwgIkVtaXNzaW9ucy9sb3NzIiwgYXMuY2hhcmFjdGVyKE5CJHBhcnQpKQojcmVvcmRlciBjb2x1bW5zCk5CIDwtIE5CWywgYygxLCAyLCAzLCA0LCAxMiwgMTMsIDU6MTEpXQpgYGAKCiMjI1N0ZXA1IC0gUHJlcGFyZSBkYXRhc2V0IHRvIGNhbGN1bGF0ZSByZWNvdmVyaWVzIChzdW0gb2YgaW5wdXRzIGFuZCBvdXRwdXRzKQoKYGBge3IgZWNobz1UUlVFfQojU3VtIHRoZSBudXRyaWVudHMgaW4gc3RhcnRlcnMgYW5kIGZyZXNoIG1hbnVyZSB0byBnZXQgdGhlIHRvdGFsIGlucHV0cyBwZXIgbnV0cmllbnQgKGluIGdyYW1zKSBhbmQgZm9ybWF0IGRhdGFzZXQgdG8gbWVyZ2UKTkJfaW5wdXRzIDwtIHN1YnNldChOQiwgKGNhdGVnb3J5PT0iSW5wdXQiKSkKTkJfaW5wdXRzIDwtIGdhdGhlcihOQl9pbnB1dHMsICJ2YXJpYWJsZSIsICJ2YWx1ZSIsIDc6MTMpCk5CX2lucHV0cyA8LSBkZHBseShOQl9pbnB1dHMsIC4odHJpYWwsIHRyZWF0bWVudCwgY2hhbWJlciwgdmFyaWFibGUpLCBzdW1tYXJpemUsIAogICAgICAgICAgICAgICAgICAgIHRvdGFsX2lucHV0PSBzdW0odmFsdWUsIG5hLnJtPVRSVUUpKQoKTkJfaW5wdXRzIDwtIHNwcmVhZChOQl9pbnB1dHMsIHZhcmlhYmxlLCB0b3RhbF9pbnB1dCkKTkJfaW5wdXRzJGNvbmNhdGVuYXRlIDwtIHBhc3RlKE5CX2lucHV0cyR0cmlhbCwgIl8iLCBOQl9pbnB1dHMkdHJlYXRtZW50KQoKIyBHZXQgdGhlIHRvdGFsIG91dHB1dHMgcGVyIG51dHJpZW50IChpbiBncmFtcykgYW5kIGZvcm1hdCBkYXRhc2V0IHRvIG1lcmdlCk5CX291dHB1dHMgPC0gc3Vic2V0KE5CLCAoY2F0ZWdvcnk9PSJPdXRwdXQiKSkKTkJfb3V0cHV0cyA8LSBnYXRoZXIoTkJfb3V0cHV0cywgInZhcmlhYmxlX291dHB1dCIsICJ2YWx1ZV9vdXRwdXQiLCA3OjEzKQpOQl9vdXRwdXRzIDwtIGRkcGx5KE5CX291dHB1dHMsIC4odHJpYWwsIHRyZWF0bWVudCwgY2hhbWJlciwgcGFydDIsIHZhcmlhYmxlX291dHB1dCksIHN1bW1hcml6ZSwKICAgICAgICAgICAgICAgICAgICBzdW1fcGFydHMgPSBzdW0odmFsdWVfb3V0cHV0LCBuYS5ybT1UKSkKCk5CX291dHB1dHMgPC0gc3ByZWFkKE5CX291dHB1dHMsIHZhcmlhYmxlX291dHB1dCwgc3VtX3BhcnRzKQpOQl9vdXRwdXRzJGNvbmNhdGVuYXRlIDwtIHBhc3RlKE5CX291dHB1dHMkdHJpYWwsICJfIiwgTkJfb3V0cHV0cyR0cmVhdG1lbnQpCgojQWRkIGRyeSBtYXRlcmlhbCBlbWlzc2lvbnMgKGNhbGN1bGF0ZWQgYXMgZXF1YXRpb24gNCkKRE1faW5wdXRzIDwtIE5CX2lucHV0cyAlPiUgc2VsZWN0KDEsIDIsIDMsIDUpCkRNX2lucHV0cyRjb25jYXRlbmF0ZSA8LSBwYXN0ZTAoRE1faW5wdXRzJHRyaWFsLCBETV9pbnB1dHMkdHJlYXRtZW50LCBETV9pbnB1dHMkY2hhbWJlcikKCkRNX291dHB1dHMgPC0gZGRwbHkoTkJfb3V0cHV0cywgLih0cmlhbCwgdHJlYXRtZW50LCBjaGFtYmVyKSwgc3VtbWFyaXplLAogICAgICAgICAgICAgICAgICAgIHN1bV9wYXJ0cyA9IHN1bShkcnl3ZWlnaHRfZ3JhbXMsIG5hLnJtPVQpKQpETV9vdXRwdXRzJGNvbmNhdGVuYXRlIDwtIHBhc3RlMChETV9vdXRwdXRzJHRyaWFsLCBETV9vdXRwdXRzJHRyZWF0bWVudCwgRE1fb3V0cHV0cyRjaGFtYmVyKQoKRE1fZW1pc3Npb25zIDwtIG1lcmdlKERNX2lucHV0cywgRE1fb3V0cHV0cywgYnk9ImNvbmNhdGVuYXRlIikKRE1fZW1pc3Npb25zJGRtX2VtaXNzaW9ucyA8LSBETV9lbWlzc2lvbnMkZHJ5d2VpZ2h0X2dyYW1zLSBETV9lbWlzc2lvbnMkc3VtX3BhcnRzCkRNX2VtaXNzaW9ucyA8LSBETV9lbWlzc2lvbnMgJT4lIHNlbGVjdCgyOjEwKQpETV9lbWlzc2lvbnMkY29uY2F0ZW5hdGUgPC0gcGFzdGUoRE1fZW1pc3Npb25zJHRyaWFsLngsICJfIiwgRE1fZW1pc3Npb25zJHRyZWF0bWVudC54KQoKTkJfb3V0cHV0cyA8LSBtZXJnZShOQl9vdXRwdXRzLCBETV9lbWlzc2lvbnMsIGJ5PSJjb25jYXRlbmF0ZSIpCk5CX291dHB1dHMgPC0gTkJfb3V0cHV0cyAlPiUgc2VsZWN0KDE6MTIsIDIxKQpOQl9vdXRwdXRzJGRyeXdlaWdodF9ncmFtcy54IDwtIGlmZWxzZShOQl9vdXRwdXRzJGRyeXdlaWdodF9ncmFtcy54PT0wLCBOQl9vdXRwdXRzJGRtX2VtaXNzaW9ucywgTkJfb3V0cHV0cyRkcnl3ZWlnaHRfZ3JhbXMueCkKTkJfb3V0cHV0cyA8LSBOQl9vdXRwdXRzICU+JSBzZWxlY3QoMToxMikKCgojbWVyZ2Ugb3V0cHV0cyB3aXRoIGlucHV0cyB0byBjYWxjdWxhdGUgdGhlIHJlY292ZXJ5IGluIGVhY2ggcGFydApOQl9vdXRwdXRzMiA8LSBtZXJnZShOQl9vdXRwdXRzLCBOQl9pbnB1dHMsIGJ5PSJjb25jYXRlbmF0ZSIpICNDb2x1bW5zIDY6MTIgY29udGFpbiB0aGUgb3V0cHV0cyBhbmQgY29sdW1ucyAxNjoyMiBjb250YWluIHRoZSBpbnB1dHMgCk5CX291dHB1dHMyCmBgYAoKIyMjIFN0ZXA2IC0gQ2FsY3VsYXRpb24gb2YgcmVjb3ZlcmllcwoKYGBge3IgZWNobz1UUlVFfQojQ2FsY3VsYXRlICUgb2YgZWFjaCBvdXRwdXQKTkJfb3V0cHV0czIkRE1fcGVyIDwtIChOQl9vdXRwdXRzMiRkcnl3ZWlnaHRfZ3JhbXMueC9OQl9vdXRwdXRzMiRkcnl3ZWlnaHRfZ3JhbXMpKjEwMApOQl9vdXRwdXRzMiROX3BlciA8LSAoTkJfb3V0cHV0czIkTl9vdmVyYWxsLngvTkJfb3V0cHV0czIkTl9vdmVyYWxsLnkpKjEwMApOQl9vdXRwdXRzMiRDX3BlciA8LSAoTkJfb3V0cHV0czIkQ19vdmVyYWxsLngvTkJfb3V0cHV0czIkQ19vdmVyYWxsLnkpKjEwMApOQl9vdXRwdXRzMiRFX3BlciA8LSAoTkJfb3V0cHV0czIkRV9vdmVyYWxsLngvTkJfb3V0cHV0czIkRV9vdmVyYWxsLnkpKjEwMApOQl9vdXRwdXRzMiRLX3BlciA8LSAoTkJfb3V0cHV0czIkS19vdmVyYWxsLngvTkJfb3V0cHV0czIkS19vdmVyYWxsLnkpKjEwMApOQl9vdXRwdXRzMiRQX3BlciA8LSAoTkJfb3V0cHV0czIkUF9vdmVyYWxsLngvTkJfb3V0cHV0czIkUF9vdmVyYWxsLnkpKjEwMApOQl9vdXRwdXRzMiROSDNfcGVyIDwtIChOQl9vdXRwdXRzMiROSDNfb3ZlcmFsbC54L05CX291dHB1dHMyJE5IM19vdmVyYWxsLnkpKjEwMAoKTkJfb3V0cHV0czIgPC0gTkJfb3V0cHV0czJbLCBjKDI6NSwgMjM6MjgpXQpOQl9vdXRwdXRzMiA8LSBnYXRoZXIoTkJfb3V0cHV0czIsICJ2YXJpYWJsZSIsICJ2YWx1ZSIsIDU6MTApCk5CX291dHB1dHMyCmBgYAoKIyMjIFN0ZXA3IC0gRmlndXJlIFMxIC0gcmVjb3ZlcmllcyBwZXIgdHJpYWwKCmBgYHtyIGVjaG89VFJVRX0KI1ByZXBhcmUgZm9yIEZpZ3VyZSBTMQpOQl9vdXRwdXRzMiR2YXJpYWJsZTI8LSBpZmVsc2UoTkJfb3V0cHV0czIkdmFyaWFibGU9PSJETV9wZXIiLCAiRHJ5IG1hdHRlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKE5CX291dHB1dHMyJHZhcmlhYmxlPT0iTl9wZXIiLCAiTml0cm9nZW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKE5CX291dHB1dHMyJHZhcmlhYmxlPT0iQ19wZXIiLCAiQ2FyYm9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShOQl9vdXRwdXRzMiR2YXJpYWJsZT09IkVfcGVyIiwgIkVuZXJneSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKE5CX291dHB1dHMyJHZhcmlhYmxlPT0iS19wZXIiLCAiUG90YXNzaXVtIiwgIlBob3NwaG9ydXMiKSkpKSkKCk5CX291dHB1dHMyJHZhcmlhYmxlMiA9IGZhY3RvcihOQl9vdXRwdXRzMiR2YXJpYWJsZTIsIGxldmVscyA9IGMoIkRyeSBtYXR0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOaXRyb2dlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhcmJvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVuZXJneSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBob3NwaG9ydXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3Rhc3NpdW0iKSkKCgpOQl9vdXRwdXRzMiR0cmlhbC54PWZhY3RvcihOQl9vdXRwdXRzMiR0cmlhbC54LCBsZXZlbHM9YygiVDQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlQyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVDEiKSkKCk5CX291dHB1dHMyJHRyZWF0bWVudC54PWZhY3RvcihOQl9vdXRwdXRzMiR0cmVhdG1lbnQueCwgbGV2ZWxzPWMoIldpdGhfQlNGTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIldpdGhvdXQiKSkKCiNyZW1vdmUgYWlyIGVtaXNzaW9ucyBmb3IgUCBhbmQgSwpOQl9vdXRwdXRzMiA8LSBzdWJzZXQoTkJfb3V0cHV0czIsICh2YWx1ZT4wKSkKCiNTdXBwbGVtZW50YXJ5IEZpZ3VyZSAxCgpnZ3Bsb3QoTkJfb3V0cHV0czIsIGFlcyh5PSB2YWx1ZSwgeD10cmlhbC54LCBmaWxsPXBhcnQyLCksIHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV9jb2woKSArIAogIGdlb21fdGV4dChhZXMobGFiZWwgPSAocGFzdGUwKHJvdW5kKHZhbHVlLCBkaWdpdHMgPSAxKSwgIiUiKSksIGdyb3VwID0gcGFydDIpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZT0yLjUpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRkZBNTAwIiwgIiM4RkJDOEYiLCAiIzgwODAwMCIpKSsKICBmYWNldF9ncmlkKHZhcmlhYmxlMn50cmVhdG1lbnQueCkrCiAgbGFicyh5PWV4cHJlc3Npb24oIlJlY292ZXJ5ICglKSIpKSsgCiAgeGxhYigiIikgKwogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyPSJ3aGl0ZSIsIGZpbGw9IndoaXRlIikpKwogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgZmFjZT0iYm9sZCIsIGhqdXN0PTApKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIndoaXRlIiwgc2l6ZSA9IDAuMikpKyAKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAid2hpdGUiLCBzaXplID0gMC41KSkrIAogIGdndGl0bGUoIiIpICsgCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0xMywgZmFjZT0iYm9sZCIsIGhqdXN0ID0gMSwgdmp1c3Q9MCkpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFjZSA9ICJwbGFpbiIsICBhbmdsZSA9IDAsIGhqdXN0ID0gMC41LCB2anVzdD0xLCBjb2xvdXI9ImJsYWNrIiwgbGluZWhlaWdodCA9IDApKSArIAogIHRoZW1lKHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApKSArIAogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGZpbGw9IndoaXRlIikpICsgCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJQYXJ0IikpICsKICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiwgZmFjZT0iYm9sZCIpKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCwgZmFjZT0iYm9sZCIpKSsgCiAgY29vcmRfY2FydGVzaWFuKHlsaW09YygpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IikrCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCksbGltaXRzPWMoMCwgMTEwKSxicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDI1KSkrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTEwMCwgbGluZXR5cGU9ImRhc2hlZCIsIAogICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLCBzaXplPTAuNSkrCiAgY29vcmRfZmxpcCgpCgojZ2dzYXZlKHBhdGg9Im91dHB1dHMiLCAiRmlndXJlUzIucG5nIiwgd2lkdGggPSAyMiwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImNtIiwgZHBpPTMwMCkKCmBgYAoKIyMjIFN0ZXA4IC0gU3RhdGlzdGljcyAtIERvIHJlY292ZXJ5IHJhdGVzIGRpZmZlciBiZXR3ZWVuIHRyZWF0bWVudHM/CgpgYGB7ciBlY2hvPVRSVUV9CnN0YXRpc3RpY3MyIDwtIHN1YnNldChOQl9vdXRwdXRzMiwgKHBhcnQyIT0iTGFydmFlIikpCnN0YXRpc3RpY3MyIDwtIHN0YXRpc3RpY3MyICU+JXNlbGVjdCgxLCAyLCA0LCA3LCA2KQoKI0Fub3ZhCnBydWViYSA8LSBzdGF0aXN0aWNzMiAlPiUgCiAgZ3JvdXBfYnkocGFydDIsIHZhcmlhYmxlMikgJT4lCiAgZ3JvdXBfbW9kaWZ5KH4gYnJvb206OnRpZHkoYW92KHZhbHVlfnRyZWF0bWVudC54ICsgdHJpYWwueCwgZGF0YSA9IC54KSkpCgpwcnVlYmEkc2lnbmlmaWNhbmNlIDwtIGlmZWxzZShwcnVlYmEkcC52YWx1ZTwwLjA1ICYgcHJ1ZWJhJHAudmFsdWU+MC4wMSwgIioiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHJ1ZWJhJHAudmFsdWU8MC4wMSAmIHBydWViYSRwLnZhbHVlPjAuMDAxLCAiKioiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHBydWViYSRwLnZhbHVlPDAuMDAxLCAiKioqIiwgIiIpKSkKCnBydWViYQoKI3dyaXRlLmNzdihwcnVlYmEsIGZpbGU9IkFub3ZhX3JlY292ZXJpZXMuY3N2Iiwgcm93Lm5hbWVzID0gRikKYGBgCgojIyMgU3RlcDkgLSBGaWd1cmUgMSAtIEF2ZXJhZ2VkIHJlY292ZXJpZXMgcGVyIG51dHJpZW50CgpgYGB7ciBlY2hvPVRSVUV9CkZpZ3VyZTEgPC0gTkJfb3V0cHV0czIKRmlndXJlMSA8LSBkZHBseShGaWd1cmUxLCAuKHRyZWF0bWVudC54LCBwYXJ0MiwgdmFyaWFibGUyKSwgc3VtbWFyaXplLCAKICAgICAgICAgICAgICAgICAgICBtZWFuPSBtZWFuKHZhbHVlLCBuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgICBzdGRfZXJyb3I9IHN0ZC5lcnJvcih2YWx1ZSwgbmEucm0gPSBUUlVFKSkKCgoKCmdncGxvdChGaWd1cmUxLCBhZXMoeT0gbWVhbiwgeD10cmVhdG1lbnQueCwgZmlsbD1wYXJ0MiwpLCBzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fY29sKHdpZHRoID0gMC44NSkgKyAKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gKHBhc3RlMChyb3VuZChtZWFuLCBkaWdpdHMgPSAwKSwgIiDCsSAiLCByb3VuZChzdGRfZXJyb3IsIGRpZ2l0cyA9IDEpKSksIGdyb3VwID0gcGFydDIpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgc2l6ZT0yLjUpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRkZBNTAwIiwgIiM4RkJDOEYiLCAiIzgwODAwMCIpKSsKICBsYWJzKHk9ZXhwcmVzc2lvbigiUmVjb3ZlcnkgKCUpIikpKyAKICB4bGFiKCIiKSArCiAgZmFjZXRfZ3JpZCgufnZhcmlhYmxlMikrCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXI9IndoaXRlIiwgZmlsbD0id2hpdGUiKSkrCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEwLCBmYWNlPSJib2xkIiwgaGp1c3Q9MC41KSkrIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjIpKSsgCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gIndoaXRlIiwgc2l6ZSA9IDAuNSkpKyAKICBnZ3RpdGxlKCIiKSArIAogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTMsIGZhY2U9ImJvbGQiLCBoanVzdCA9IDEsIHZqdXN0PTApKSArIAogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGZhY2UgPSAicGxhaW4iLCAgYW5nbGUgPSA5MCwgaGp1c3QgPSAwLjUsIHZqdXN0PTEsIGNvbG91cj0iYmxhY2siLCBsaW5laGVpZ2h0ID0gMCkpICsgCiAgdGhlbWUoc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpICsgCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoZmlsbD0id2hpdGUiKSkgKyAKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IkxlZ2VuZCIpKSArCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIsIGZhY2U9ImJvbGQiKSkgKyAKICB0aGVtZShheGlzLnRpdGxlLnggID0gZWxlbWVudF90ZXh0KHNpemU9MTQsIGZhY2U9ImJvbGQiKSkrIAogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSxsaW1pdHM9YygwLCAxMTApLGJyZWFrcyA9IHNlcSgwLCAxMDAsIGJ5ID0gMjUpKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQ9MTAwLCBsaW5ldHlwZT0iZGFzaGVkIiwgCiAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIHNpemU9MC41KQoKI1NhdmUgZmlndXJlLiBUaGlzIGZpZ3VyZSB0aGVuIHdhcyBlZGl0dGVkIGluIElua3NjYXBlIHRvIGFkZCB0aGUgYmFycyBhbmQgUC52YWx1ZXMgc2hvd2luZyB0aGUgc3RhdGlzdGljYWwgZGlmZmVyZW5jZXMgYmV3dHdlZW4gdHJlYXRtZW50cwojVG8gc2F2ZToKI2dnc2F2ZShwYXRoPSJvdXRwdXRzIiwgIkZpZ3VyZTEucGRmIiwgd2lkdGggPSAyMiwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImNtIiwgZHBpPTMwMCkKCmBgYAoKIyMgUGFydCAyIC0gQW1tb25pYS1OIGJhbGFuY2UgYW5kIG51dHJpZW50IHJhdGlvcyAgCiMjIyBTdGVwMTAgLSBBbW1vbmlhIGJhbGFuY2UKYGBge3IgZWNobz1UUlVFfQojZ2V0IGRhdGFzZXQKYW1tb25pYV9iYWxhbmNlIDwtIE5CCmFtbW9uaWFfYmFsYW5jZSA8LSBzdWJzZXQoYW1tb25pYV9iYWxhbmNlLCAoKHBhcnQyPT0iRnJlc2hfbWFudXJlIiAmIHRyZWF0bWVudD09IldpdGhfQlNGTCIpIHwgcGFydDI9PSJSZXNpZHVlcyIgfCBwYXJ0Mj09IkxhcnZhZSIpKQoKI3NlbGVjdCByZWxldmFudCBjb2x1bW5zCmFtbW9uaWFfYmFsYW5jZSA8LSBhbW1vbmlhX2JhbGFuY2VbLCBjKDEsIDIsIDYsIDgsIDEzKV0KCiNjYWxjdWxhdGUgbm9uIG5oMyBOCmFtbW9uaWFfYmFsYW5jZSROb25fYW1tb25pYV9OIDwtIGlmZWxzZShpcy5uYShhbW1vbmlhX2JhbGFuY2UkTkgzX292ZXJhbGwpLCBhbW1vbmlhX2JhbGFuY2UkTl9vdmVyYWxsLCAoYW1tb25pYV9iYWxhbmNlJE5fb3ZlcmFsbC1hbW1vbmlhX2JhbGFuY2UkTkgzX292ZXJhbGwpKQpjb2xuYW1lcyhhbW1vbmlhX2JhbGFuY2UpWzRdIDwtICJUb3RhbF9OIgpjb2xuYW1lcyhhbW1vbmlhX2JhbGFuY2UpWzVdIDwtICJBbW1vbmlhX04iCgojc2F2ZSBvdmVyYWxsIE4gaW4gZnJlc2ggbWFudXJlICh3aWxsIGJlIHVzZWQgaW4gYSBsYXRlciBzdGFnZSkKbWFudXJlX24gPC0gYW1tb25pYV9iYWxhbmNlWywgYygxOjQpXQptYW51cmVfbiA8LSBzdWJzZXQobWFudXJlX24sIChwYXJ0Mj09IkZyZXNoX21hbnVyZSIpKQoKI1JlLWFycmFuZ2UgZGF0YXNldAphbW1vbmlhX2JhbGFuY2UgPC0gYW1tb25pYV9iYWxhbmNlWywgYygxLCAyLCAzLCA1LCA2KV0KYW1tb25pYV9iYWxhbmNlIDwtIGdhdGhlcihhbW1vbmlhX2JhbGFuY2UsICJ0eXBlX24iLCAidmFsdWUiLCA0OjUpCgojYWRkICBuaDMgZW1pc3Npb25zCmVtaXNzaW9uc19uIDwtIHRvdGFsX24gCmVtaXNzaW9uc19uJHBhcnQyIDwtICJFbWlzc2lvbnMiCmVtaXNzaW9uc19uJHR5cGVfbiA8LSAiQW1tb25pYV9OIgpjb2xuYW1lcyhlbWlzc2lvbnNfbilbM10gPC0gInZhbHVlIgplbWlzc2lvbnNfbiA8LSBlbWlzc2lvbnNfblssIGMoMSwgMiwgNCwgNSwgMyldCgojYmluZCB0d28gZGF0YXNldHMKYW1tb25pYV9iYWxhbmNlIDwtIHJiaW5kKGFtbW9uaWFfYmFsYW5jZSwgZW1pc3Npb25zX24pCgojYWRkIHRvdGFsIG4gaW5wdXQgdG8gY2FsY3VsYXRlIHBlcmNlbnRhZ2VzCm1hbnVyZV9uIDwtIG1hbnVyZV9uWywgYygxLCA0KV0KY29sbmFtZXMobWFudXJlX24pIFsyXSA8LSAiTl9pbnB1dF9tYW51cmUiCmFtbW9uaWFfYmFsYW5jZSA8LSBtZXJnZShhbW1vbmlhX2JhbGFuY2UsIG1hbnVyZV9uLCBieT0idHJpYWwiKQoKI2NhbGN1bGF0ZSByZWNvdmVyeQphbW1vbmlhX2JhbGFuY2UkcGVyY2VudGFnZSA8LSBhbW1vbmlhX2JhbGFuY2UkdmFsdWUvYW1tb25pYV9iYWxhbmNlJE5faW5wdXRfbWFudXJlKjEwMAojcmVtb3ZlIE5BCmFtbW9uaWFfYmFsYW5jZSA8LSBuYS5vbWl0KGFtbW9uaWFfYmFsYW5jZSkKCmFtbW9uaWFfYmFsYW5jZSA8LSBhbW1vbmlhX2JhbGFuY2VbLCBjKDE6NCwgNyldCmBgYAoKIyMjIFN0ZXAxMSAtIERvIGFtbW9uaWEgYW5kIG5vbi1hbW1vbmlhIGZyYWN0aW9ucyBkaWZmZXIgYmV0d2VlbiB0cmVhdG1lbnRzPwpgYGB7ciBlY2hvPVRSVUV9CiNBbm92YQpzdGF0aXN0aWNzX2FtbW9uaWEgPC0gc3Vic2V0KGFtbW9uaWFfYmFsYW5jZSwgKHBhcnQyIT0iRnJlc2hfbWFudXJlIiAmIHBhcnQyIT0iTGFydmFlIikpCgpzdGF0aXN0aWNzX2FtbW9uaWEyIDwtIHN0YXRpc3RpY3NfYW1tb25pYSAlPiUgCiAgZ3JvdXBfYnkocGFydDIsIHR5cGVfbikgJT4lCiAgZ3JvdXBfbW9kaWZ5KH4gYnJvb206OnRpZHkoYW92KHBlcmNlbnRhZ2V+dHJlYXRtZW50ICsgdHJpYWwsIGRhdGEgPSAueCkpKQoKc3RhdGlzdGljc19hbW1vbmlhMgoKI3dyaXRlLmNzdihzdGF0aXN0aWNzX2FtbW9uaWEyLCBmaWxlPSJBbm92YV9OYW1tb25pYS5jc3YiLCByb3cubmFtZXMgPSBGKQoKYGBgCiMjIyBTdGVwMTIgLSBGaWd1cmUgMiAtIE5pdHJvZ2VuIGJhbGFuY2UKYGBge3IgZWNobz1UUlVFfQpmaWd1cmUzIDwtIGFtbW9uaWFfYmFsYW5jZQoKI05ldyBjYXRlZ29yaWVzIGZvciB0aGUgZGlmZmVyZW50IGZyYWN0aW9ucwpmaWd1cmUzJGNhdGVnb3JpZXMgPC0gaWZlbHNlKCgoYW1tb25pYV9iYWxhbmNlJHBhcnQyPT0iRnJlc2hfbWFudXJlIiB8ICBhbW1vbmlhX2JhbGFuY2UkcGFydDI9PSJSZXNpZHVlcyIpICYgKGFtbW9uaWFfYmFsYW5jZSR0eXBlX249PSJBbW1vbmlhX04iKSksICJBbW1vbmlhLU4gaW4gbWFudXJlIG9yIHJlc2lkdWVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCgoYW1tb25pYV9iYWxhbmNlJHBhcnQyPT0iRnJlc2hfbWFudXJlIiB8ICBhbW1vbmlhX2JhbGFuY2UkcGFydDI9PSJSZXNpZHVlcyIpICYgKGFtbW9uaWFfYmFsYW5jZSR0eXBlX249PSJOb25fYW1tb25pYV9OIikpLCAiTm9uIGFtbW9uaWEtTiBpbiBtYW51cmUgb3IgcmVzaWR1ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGFtbW9uaWFfYmFsYW5jZSRwYXJ0Mj09IkxhcnZhZSIsICJOIGluIGxhcnZhbCBiaW9tYXNzIiwgIkFtbW9uaWEtTiBlbWlzc2lvbnMiKSkpCgpmaWd1cmUzJG5hbWUyX3RyZWF0bWVudHMgPC0gaWZlbHNlKGZpZ3VyZTMkdHJlYXRtZW50PT0iV2l0aF9CU0ZMIiAmIGZpZ3VyZTMkcGFydDI9PSJGcmVzaF9tYW51cmUiLCAiRnJlc2hfbWFudXJlIiwgCiAgICAgICAgICAgICAgICAgICBpZmVsc2UoZmlndXJlMyR0cmVhdG1lbnQ9PSJXaXRoX0JTRkwiICYgZmlndXJlMyRwYXJ0Mj09IlJlc2lkdWVzIiwgIldpdGhfQlNGTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGZpZ3VyZTMkdHJlYXRtZW50PT0iV2l0aF9CU0ZMIiAmIGZpZ3VyZTMkcGFydDI9PSJMYXJ2YWUiLCAiV2l0aF9CU0ZMIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZmlndXJlMyR0cmVhdG1lbnQ9PSJXaXRoX0JTRkwiICYgZmlndXJlMyRwYXJ0Mj09IkVtaXNzaW9ucyIsICJXaXRoX0JTRkwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGZpZ3VyZTMkdHJlYXRtZW50PT0iV2l0aG91dCIgJiBmaWd1cmUzJHBhcnQyPT0iUmVzaWR1ZXMiLCAiV2l0aG91dCIsICJXaXRob3V0IikpKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIApmaWd1cmUzX3MgPC0gZGRwbHkoZmlndXJlMywgLihuYW1lMl90cmVhdG1lbnRzLCBjYXRlZ29yaWVzKSwKICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpemUsCiAgICAgICAgICAgICAgICAgICAgICAgbWVhbj1tZWFuKHBlcmNlbnRhZ2UpLAogICAgICAgICAgICAgICAgICAgICAgIHN0ZF9lcnJvcj0gc3RkLmVycm9yKHBlcmNlbnRhZ2UpKQoKI2NhbGN1bGF0ZSBjb25maWRlbmNlIGludGVyYWwgZm9yIGZyZXNoIG1hbnVyZQpjaV9hbW1vbmlhX21hbnVyZSA8LSBzdWJzZXQoZmlndXJlMywgKHBhcnQyPT0iRnJlc2hfbWFudXJlIikpCmNpX2FtbW9uaWFfbWFudXJlIDwtIGNpX2FtbW9uaWFfbWFudXJlWywgYygxLCA3LCA0LCA1KV0KY2lfYW1tb25pYV9tYW51cmUgPC0gY2lfYW1tb25pYV9tYW51cmUgJT4lCiAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KHR5cGVfbikgJT4lCiAgICAgICAgICAgICAgICAgICAgICBkbyh0aWR5KENJKC4kcGVyY2VudGFnZSkpKQoKY2lfYW1tb25pYV9tYW51cmUgPC0gc3ByZWFkKGNpX2FtbW9uaWFfbWFudXJlLCBuYW1lcywgeCkKY2lfYW1tb25pYV9tYW51cmUkbWVhbmxvdzwtIGNpX2FtbW9uaWFfbWFudXJlJG1lYW4gLSBjaV9hbW1vbmlhX21hbnVyZSRsb3dlcgpjaV9hbW1vbmlhX21hbnVyZSRtZWFudXAgPC0gY2lfYW1tb25pYV9tYW51cmUkdXBwZXIgLSBjaV9hbW1vbmlhX21hbnVyZSRtZWFuCgojYWRkIGNvbHVtbiB3aXRoIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGZyZXNoIG1hbnVyZSwgdGhlIHJlc3Qga2VlcCB0aGUgc3RhbmRhcmQgZXJyb3IKCmZpZ3VyZTNfcyR2YXJpYXRpb24gPC0gaWZlbHNlKGZpZ3VyZTNfcyRuYW1lMl90cmVhdG1lbnRzPT0iRnJlc2hfbWFudXJlIiAsIGFzLm51bWVyaWMoMTQpLCBmaWd1cmUzX3Mkc3RkX2Vycm9yKQoKZmlndXJlM19zJGNhdGVnb3JpZXMgPSBmYWN0b3IoZmlndXJlM19zJGNhdGVnb3JpZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk4gaW4gbGFydmFsIGJpb21hc3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFtbW9uaWEtTiBpbiBtYW51cmUgb3IgcmVzaWR1ZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFtbW9uaWEtTiBlbWlzc2lvbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vbiBhbW1vbmlhLU4gaW4gbWFudXJlIG9yIHJlc2lkdWVzIikpCgoKCmdncGxvdChmaWd1cmUzX3MsIGFlcyhmaWxsPWNhdGVnb3JpZXMsIHk9bWVhbiwgeD1uYW1lMl90cmVhdG1lbnRzKSkgKyAKICBnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siLCBzdGF0PSJpZGVudGl0eSIpKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSAocGFzdGUwKHJvdW5kKG1lYW4sIGRpZ2l0cyA9IDApLCAiIMKxICIsIHJvdW5kKHZhcmlhdGlvbiwgZGlnaXRzID0gMCkpKSwgZ3JvdXAgPSBjYXRlZ29yaWVzKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemU9Mi41KSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgeWxhYigiUGVyY2VudGFnZSAoJSkiKSsKICB4bGFiKCIiKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRDhFMEJCIiwgJyNCNkNFQzcnLCAiIzg2QTNDMyIsJyM3MjY4QTYnKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApLGxpbWl0cz1jKDAsIDEwNSksYnJlYWtzID0gc2VxKDAsIDEwMCwgYnkgPSAyNSkpKwogIHRoZW1lKGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpCiNnZ3NhdmUocGF0aD0ib3V0cHV0cyIsICJGaWd1cmUzLnBkZiIsIHdpZHRoID0gMjIsIGhlaWdodCA9IDE1LCB1bml0cyA9ICJjbSIsIGRwaT0zMDApCmBgYAojIyMgU3RlcDEzIC0gRGF0YSBtYW5pcHVsYXRpb24gdG8gY2FsY3VsYXRlIG51dHJpZW50IHJhdGlvcyAgCmBgYHtyIGVjaG89VFJVRX0KI0NyZWF0ZSBuZXcgZGF0YXNldCBmcm9tIE5CIChwYXJ0IDEpCnJhdGlvIDwtIE5CCgojU3Vic2V0IHRvIG9idGFpbiBvbmx5IHRoZSByZWxldmFudCBwYXJ0cwpyYXRpbyA8LSBzdWJzZXQocmF0aW8sIChwYXJ0PT0iRnJlc2hfbWFudXJlIiAmIHRyZWF0bWVudD09IldpdGhfQlNGTCIpIHwgcGFydDI9PSJSZXNpZHVlcyIpCiNNb2RpZnkgdGhlIG5hbWVzIG9mIHRoZSBjYXRlZ29yaWVzIHRvIGhhdmUgIkZyZXNoX21hbnVyZSIsICJSZXNpZHVlc19sYXJ2YWUiIGFuZCAiUmVzaWR1ZXNfbWFudXJlIgpyYXRpbyRwYXJ0MiA8LSBpZmVsc2UocmF0aW8kcGFydDI9PSJSZXNpZHVlcyIgJiByYXRpbyR0cmVhdG1lbnQ9PSJXaXRoX0JTRkwiLCAiUmVzaWR1ZXNfbGFydmFlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmF0aW8kcGFydDI9PSJSZXNpZHVlcyIgJiByYXRpbyR0cmVhdG1lbnQ9PSJXaXRob3V0IiwgIlJlc2lkdWVzX21hbnVyZSIsICJGcmVzaF9tYW51cmUiKSkKCiNTZWxlY3QgcmVsZXZhbnQgY29sdW1ucwpyYXRpbyA8LSByYXRpb1ssIGMoMSwgNjoxMyldCiNyZS1uYW1lIGNvbHVtbnMKY29sbmFtZXMocmF0aW8pIDwtIGMoInRyaWFsIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJdGVtIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEcnkgbWF0dGVyIChnKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVG90YWwgbml0cm9nZW4gKGcpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhcmJvbiAoZykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRW5lcmd5IChnKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQb3Rhc3NpdW0gKGcpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBob3NwaG9ydXMgKGcpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFtbW9uaWEgKGcpIikgCgojUmVtb3ZlIGVuZXJneSAmIE5IMwpyYXRpbyA8LSByYXRpbyBbLCBjKDE6NSw3LCA4KV0KCiNDYWxjdWxhdGUgcmF0aW9zCnJhdGlvJENfTiA8LSByYXRpbyRgQ2FyYm9uIChnKWAvcmF0aW8kYFRvdGFsIG5pdHJvZ2VuIChnKWAKcmF0aW8kTl9QIDwtIHJhdGlvJGBUb3RhbCBuaXRyb2dlbiAoZylgL3JhdGlvJGBQaG9zcGhvcnVzIChnKWAKcmF0aW8kTl9LIDwtIHJhdGlvJGBUb3RhbCBuaXRyb2dlbiAoZylgL3JhdGlvJGBQb3Rhc3NpdW0gKGcpYApyYXRpbyRQX0sgPC0gcmF0aW8kYFBob3NwaG9ydXMgKGcpYC9yYXRpbyRgUG90YXNzaXVtIChnKWAKcmF0aW8gPC0gcmF0aW9bLCBjKDEsIDIsIDg6MTEpXQoKcmF0aW8gPC0gZ2F0aGVyKHJhdGlvLCByYXRpbywgdmFsdWUsIDM6NikKcmF0aW8KCmBgYAoKIyMjIFN0ZXAxNCAtIFN0YXRpc3RpY3MgLSBEbyBudXRyaWVudCByYXRpb3MgZGlmZmVyIGJldHdlZW4gdHJlYXRtZW50cz8KYGBge3IgZWNobz1UUlVFfQojQW5vdmEKcmF0aW9fc3RhdGlzdGljcyA8LSBzdWJzZXQocmF0aW8sIChJdGVtIT0iRnJlc2hfbWFudXJlIikpCnJhdGlvX3N0YXRpc3RpY3MgPC0gcmF0aW9fc3RhdGlzdGljcyU+JSAKICBncm91cF9ieShyYXRpbykgJT4lCiAgZ3JvdXBfbW9kaWZ5KH4gYnJvb206OnRpZHkoYW92KHZhbHVlfkl0ZW0gKyB0cmlhbCwgZGF0YSA9IC54KSkpCgpyYXRpb19zdGF0aXN0aWNzJHNpZ25pZmljYW5jZSA8LSBpZmVsc2UocmF0aW9fc3RhdGlzdGljcyRwLnZhbHVlPDAuMDUgJiByYXRpb19zdGF0aXN0aWNzJHAudmFsdWU+MC4wMSwgIioiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmF0aW9fc3RhdGlzdGljcyRwLnZhbHVlPDAuMDEgJiByYXRpb19zdGF0aXN0aWNzJHAudmFsdWU+MC4wMDEsICIqKiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocmF0aW9fc3RhdGlzdGljcyRwLnZhbHVlPDAuMDAxLCAiKioqIiwgIiIpKSkKCnJhdGlvX3N0YXRpc3RpY3MKI3dyaXRlLmNzdihyYXRpb19zdGF0aXN0aWNzLCBmaWxlPSJBbm92YV9yYXRpb3MuY3N2Iiwgcm93Lm5hbWVzID0gRikKYGBgCgojIyMgU3RlcDE1LSBGaWd1cmUgMyAtIEF2ZXJhZ2VkIG51dHJpZW50IHJhdGlvcyB3aXRoIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGZyZXNoIG1hbnVyZSAgCmBgYHtyIGVjaG89VFJVRX0KI0NhbGN1bGF0ZSBhdmVyYWdlZCBudXRyaWVudCByYXRpb3MKcmF0aW9fYXZlcmFnZSA8LSBzdWJzZXQocmF0aW8sIChJdGVtIT0iRnJlc2hfbWFudXJlIikpCnJhdGlvX2F2ZXJhZ2UgPC0gZGRwbHkocmF0aW9fYXZlcmFnZSwgLihJdGVtLCByYXRpbyksCiAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplLAogICAgICAgICAgICAgICAgICAgICAgIG1lYW49bWVhbih2YWx1ZSwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgICAgc3RkX2Vycm9yID0gc3RkLmVycm9yKHZhbHVlLCBuYS5ybT1UKSkKCiNjb25maWRlbmNlIGludGVydmFsIGZyZXNoIHBpZyBtYW51cmUKY2lfZnJlc2htYW51cmUgPC0gc3Vic2V0KHJhdGlvLCAoSXRlbT09IkZyZXNoX21hbnVyZSIpKQoKY2lfZnJlc2htYW51cmUgPC0gY2lfZnJlc2htYW51cmUgJT4lCiAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KHJhdGlvKSAlPiUKICAgICAgICAgICAgICAgICAgZG8odGlkeShDSSguJHZhbHVlKSkpCgpjaV9mcmVzaG1hbnVyZSA8LSBzcHJlYWQoY2lfZnJlc2htYW51cmUsIG5hbWVzLCB4KQoKI21lcmdlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gdGhlIHJhdGlvIGRhdGFzZXQKcmF0aW9fYXZlcmFnZSA8LSBtZXJnZShyYXRpb19hdmVyYWdlLCBjaV9mcmVzaG1hbnVyZSwgYnk9InJhdGlvIikKCiNDaGFuZ2UgbmFtZXMgb2YgcmF0aW9zCnJhdGlvX2F2ZXJhZ2UkcmF0aW8gPC0gaWZlbHNlKHJhdGlvX2F2ZXJhZ2UkcmF0aW89PSJDX04iLCAiQzpOIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJhdGlvX2F2ZXJhZ2UkcmF0aW89PSJOX0siLCAiTjpLIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyYXRpb19hdmVyYWdlJHJhdGlvPT0iTl9QIiwgIk46UCIsICJQOksiKSkpCgoKI0ZpZ3VyZQoKZ2dwbG90KHJhdGlvX2F2ZXJhZ2UsIGFlcyh4PUl0ZW0sIHk9bWVhbi54KSkgKyAKICBnZW9tX3BvaW50KCkrIAogIGdlb21fZXJyb3JiYXIoYWVzKG1pbj1tZWFuLngtc3RkX2Vycm9yLCB5bWF4PW1lYW4ueCtzdGRfZXJyb3IpLCB3aWR0aD0uMykgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbG93ZXIsIHltYXggPSB1cHBlciwgZ3JvdXA9cmF0aW8pLCBmaWxsID0gIiMyMDYzOUIiLCBhbHBoYT0wLjYpICsKICBmYWNldF93cmFwKH5yYXRpbywgc2NhbGVzPSJmcmVlX3kiLCBuY29sID0gNSkgKwogIGxhYnMoeT1leHByZXNzaW9uKCJOdXRyaWVudCByYXRpbyIpKSsgCiAgeGxhYigiIikgKwogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCwgZmFjZT0iYm9sZCIsIGhqdXN0PTAuNSkpKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAid2hpdGUiLCBzaXplID0gMC4yKSkrIAogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJ3aGl0ZSIsIHNpemUgPSAwLjUpKSsgCiAgZ2d0aXRsZSgiIikgKyAKICB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTEzLCBmYWNlPSJib2xkIiwgaGp1c3QgPSAxLCB2anVzdD0wKSkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gInBsYWluIiwgIGFuZ2xlID0gNjUsIGhqdXN0ID0gMC41LCB2anVzdD0wLjUsIGNvbG91cj0iYmxhY2siLCBsaW5laGVpZ2h0ID0gMCkpICsgCiAgdGhlbWUoc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpICsgCiAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUsIGNvbG91ciA9ICJibGFjayIpKSsKICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91cj0id2hpdGUiLCBmaWxsPSJ3aGl0ZSIpKSsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvdXIgPSAid2hpdGUiKSkrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTIsIGZhY2U9ImJvbGQiKSkgKyAKICB0aGVtZShheGlzLnRpdGxlLnggID0gZWxlbWVudF90ZXh0KHNpemU9MTQsIGZhY2U9ImJvbGQiKSkrIAogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoKSkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKCiNTYXZlIGZpZ3VyZS4gVGhpcyBmaWd1cmUgd2FzIHRoZW4gZWRpdHRlZCBpbiBJbmtzY2FwZS4KI2dnc2F2ZShwYXRoPSJvdXRwdXRzIiwgIkZpZ3VyZTIucGRmIiwgd2lkdGggPSAyMiwgaGVpZ2h0ID0gMTUsIHVuaXRzID0gImNtIiwgZHBpPTMwMCkKCmBgYAoKCiMjIFBhcnQzIC0gR2FzIGVtaXNzaW9ucyBhbmQgaGVhdCBsb3NzICAKIyMjIFN0ZXAxNiAtIEdhc2VvdXMgZW1pc3Npb25zIGFuZCBoZWF0IGxvc3NlcyAoQ08yLCBDSDQsIGhlYXQsIG94eWdlbikgIApgYGB7ciBlY2hvPVRSVUV9CiNHZXQgQ08yLCBDSDQsIE8yLCBIRUFUIGFuZCBSUQpHYXNfYXZlcmFnZSA8LSBjaGFtYmVyc19zdW1tYXJ5MgpHYXNfYXZlcmFnZSA8LSBHYXNfYXZlcmFnZVssIGMoMSwgMiwgMywgNiwgNywgOCwgOSwgMTAsIDExLDEzKV0KR2FzX2F2ZXJhZ2UgPC0gZ2F0aGVyKEdhc19hdmVyYWdlLCAidmFyaWFibGUiLCAidmFsdWUiLCA2OjEwKQoKCiMjaW1wb3J0IGluaXRpYWwgZHJ5IG1hdHRlciBwZXIgdHJpYWwgKGluIGdyYW1zKSB0byBlc3RpbWF0ZSB0aGUgZW1pc3Npb25zIG9mIGdhcy9ob3VyL2tnIGluaXRpYWwgbWFudXJlCmRyeW1hbnVyZV9nIDwtIHN1YnNldChOQiwgKChwYXJ0Mj09IkZyZXNoX21hbnVyZSIgJiB0cmVhdG1lbnQ9PSJXaXRoX0JTRkwiKSkpCmRyeW1hbnVyZV9nIDwtIGRyeW1hbnVyZV9nWywgYygxLCA2LCA3KV0KCiNhZGQgZHJ5IG1hdHRlciBtYW51cmUgcGVyIHRyaWFsIHRvIGNhbGN1bGF0ZSBlbWlzc2lvbnMgcGVyIGtnIG9mIERNIGluaXRpYWwgbWFudXJlCkdhc19hdmVyYWdlIDwtIG1lcmdlKEdhc19hdmVyYWdlLCBkcnltYW51cmVfZywgYnk9InRyaWFsIikKCiNDYWxjdWxhdGUgZW1pc3Npb25zIChnL2hvdXIpIHBlciBrZyBvZiBpbml0aWFsIERNIG1hbnVyZSBpbnB1dCAoZXhjZXB0IGZvciBSUSkKR2FzX2F2ZXJhZ2UkbmV3dmFsdWUgPC0gaWZlbHNlKEdhc19hdmVyYWdlJHZhcmlhYmxlIT0ibWVhbl9SUSIsICgoKEdhc19hdmVyYWdlJHZhbHVlKjEwMDApL0dhc19hdmVyYWdlJGRyeXdlaWdodF9ncmFtcykvMjQpLCBHYXNfYXZlcmFnZSR2YWx1ZSkKR2FzX2F2ZXJhZ2UgPC0gR2FzX2F2ZXJhZ2VbLCBjKDE6NiwgMTApXQoKI2Z1bmN0aW9uIHRvIG1ha2UgZmlyc3QgbGV0dGVyIGNhcGl0YWwKZmlyc3R1cCA8LSBmdW5jdGlvbih4KSB7CiAgeCA8LSB0b2xvd2VyKHgpCiAgc3Vic3RyKHgsIDEsIDEpIDwtIHRvdXBwZXIoc3Vic3RyKHgsIDEsIDEpKQogIHgKfQoKR2FzX2F2ZXJhZ2UkZGF5bnVtYmVyIDwtIGZpcnN0dXAoR2FzX2F2ZXJhZ2UkZGF5bnVtYmVyKQpgYGAKCgojIyMgU3RlcDE3IC0gQW1tb25pYSBlbWlzc2lvbnMgIApgYGB7ciBlY2hvPVRSVUV9CiNBbW1vbmlhIGVtaXNzaW9ucyBvbiB0aW1lCmFtbW9uaWEgPC0gcmVhZC5jc3YoImFtbW9uaWEuY3N2IikKCiMjbmFtZSBvZiB0aGUgY29sdW1ucwojIEFtbW9uaWEKI1sxXSBjaGFtYmVyIC0gY2hhbWJlciBudW1iZXIgKDcgYW5kIDgpICAKI1syXSBkYXRlIC0gZGF0ZSBvZiB0aGUgbWVhc3VyZW1lbnQgaW4gZm9ybWF0IGRheS9tb250aC95ZWFyCiNbM10gdGltZSAtIHRpbWUgb2YgdGhlIG1lYXN1cmVtZW50IGluIGZvcm1hdCBob3VyL21pbnV0ZS9zZWNvbmQKI1s0XSB2ZXJ2X3N0cGQgLSBBaXIgdmVudGlsYXRpb24gKEwvbWluKSBjb3JyZWN0ZWQgZm9yIHRlbXBlcmF0dXJlIGFuZCBwcmVzc3VyZQojWzVdIHZvbF9zdHAgLSBWb2x1bWUgb2YgdGhlIGNoYW1iZXIgKEwpIGNvcnJlY3RlZCBmb3IgcHJlc3N1cmUgYW5kIHRlbXBlcmF0dXJlCiNbNl0gTkgzX3Byb2RfbGRheSAtIEFtbW9uaWEgaW4gTC9kYXkKI1s3XSB0cmlhbCAtIHRyaWFsIG51bWJlciAoVDEsIFQyLCBUMyBhbmQgVDQpCiNbOF0gdHJlYXRtZW50IC0gdHJlYXRtZW50IG5hbWUgKFdpdGhfQlNGTCBhbmQgV2l0aG91dCkKI1s5XSBob3VyIC0gaG91ciBvZiB0aGUgZGF5IGluIDI0aCBmb3JtYXQKI1sxMF0gbWludXRlIC0gbWludXRlIGF0IHdoaWNoIHRoZSBtZWFzdXJlbWVudCB3YXMgdGFrZW4gKGZyb20gMCB0byA2MCkKI1sxMV0gc2Vjb25kIC0gc2Vjb25kIGF0IHdoaWNoIHRoZSBtZWFzdXJlbWVudCB3YXMgdGFrZW4gKGZyb20gMCB0byA2MCkKI1sxMl0gZGF5bnVtYmVyIC0gZGF5IG51bWJlciAoZnJvbSBkYXkxIGFuZCBkYXkxMCkgaW4gd2hpY2ggdGhlIG1lYXN1cmVtZW50IHRvb2sgcGxhY2UKCiNDcmVhdGUgZGF0YXNldCBmb3IgdGltZSBzZXJpZXMgcGxvdHMgKGF2ZXJhZ2UgcGVyIGhvdXIpCk5IM19zdW1tYXJ5IDwtIGRkcGx5KGFtbW9uaWEsIC4odHJpYWwsIHRyZWF0bWVudCwgY2hhbWJlciwgZGF5bnVtYmVyLCBob3VyKSwgc3VtbWFyaXplLCAKICAgICAgICAgICAgICAgICAgICAgbWVhbl9OSDM9IG1lYW4oTkgzX3Byb2RfbGRheSwgbmEucm09VFJVRSksIAogICAgICAgICAgICAgICAgICAgICBzZV9OSDM9IHN0ZC5lcnJvcihOSDNfcHJvZF9sZGF5LCBuYS5ybT1UUlVFKSkKCgpOSDNfc3VtbWFyeSRjaGFtYmVyIDwtIGlmZWxzZShOSDNfc3VtbWFyeSRjaGFtYmVyPT0iNyIsICJDNyIsICJDOCIpCgoKCiNjYWxjdWxhdGUgZW1pc3Npb25zIHBlciBuaDMvaG91ci9rZyBpbml0aWFsIGRtIG1hbnVyZQpOSDNfc3VtbWFyeSA8LSBtZXJnZShOSDNfc3VtbWFyeSwgZHJ5bWFudXJlX2csIGJ5PSJ0cmlhbCIpCk5IM19zdW1tYXJ5JG5ld3ZhbHVlIDwtICgoTkgzX3N1bW1hcnkkbWVhbl9OSDMgKjEwMDApL05IM19zdW1tYXJ5JGRyeXdlaWdodF9ncmFtcykvMjQKTkgzX3N1bW1hcnkkdmFyaWFibGUgPC0gIm1lYW5fTkgzIgoKI01ha2UgdGhlIGZpcnN0IGxldHRlciBvZiBkYXkgY2FwaXRhbAojI2Z1bmN0aW9uIHRvIG1ha2UgZmlyc3QgbGV0dGVyIGNhcGl0YWwKZmlyc3R1cCA8LSBmdW5jdGlvbih4KSB7CiAgeCA8LSB0b2xvd2VyKHgpCiAgc3Vic3RyKHgsIDEsIDEpIDwtIHRvdXBwZXIoc3Vic3RyKHgsIDEsIDEpKQogIHgKfQoKTkgzX3N1bW1hcnkkZGF5bnVtYmVyIDwtIGZpcnN0dXAoTkgzX3N1bW1hcnkkZGF5bnVtYmVyKQoKTkgzX3N1bW1hcnkgPC0gTkgzX3N1bW1hcnlbLCBjKDEsIDIsIDMsIDQsIDUsIDExLCAxMCldICN0aGlzIGRhdGFzZXQgd2lsbCBiZSBiaW5kIHRvIG90aGVycyB0byBtYWtlIHRoZSBmaWd1cmUKYGBgCgojIyMgU3RlcDE4IC0gQmluZCBnYXNlb3VzIHdpdGggYW1tb25pYQpgYGB7ciBlY2hvPVRSVUV9CiNyYmluZCBhbW1vbmlhIHdpdGggZ2FzIGF2ZXJhZ2UKR2Fzc2VzIDwtIHJiaW5kKEdhc19hdmVyYWdlLCBOSDNfc3VtbWFyeSkKCiNjaGFuZ2UgbmFtZXMgYW5kIGxhYmVscwojbmV3IG5hbWVzIGZvciBmaWd1cmVzCkdhc3NlcyRuYW1lMiA8LSBpZmVsc2UoR2Fzc2VzJHZhcmlhYmxlPT0ibWVhbl9DSDQiLCAnQ0g0IChsL2gpJywKICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoR2Fzc2VzJHZhcmlhYmxlPT0ibWVhbl9DTzIiLCAnQ08yIChsL2gpJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEdhc3NlcyR2YXJpYWJsZT09Im1lYW5faGVhdCIsICJIZWF0IChLSi9oKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEdhc3NlcyR2YXJpYWJsZT09ICJtZWFuX08yIiwgIk8yIChsL2gpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKEdhc3NlcyR2YXJpYWJsZT09Im1lYW5fUlEiLCAiUlEiLCAiTkgzIChsL2gpIikpKSkpCgpgYGAKCiMjIyBTdGVwMTkgLSBOaXRyb3VzIG94aWRlIC0gZGF0YSBtYW5pcHVsYXRpb24KYGBge3IgZWNobz1UUlVFfQojSW1wb3J0IGRhdGFzZXQgbml0cm91cyBveGlkZQpuaXRyb3VzX294aWRlIDwtIHJlYWQuY3N2KCJubml0cm91c19veGlkZS5jc3YiKQoKI05hbWUgb2YgY29sdW1ucwojWzFdIGRheSAtIGRheSBudW1iZXIgKGZyb20gZGF5MSBhbmQgZGF5MTApIGluIHdoaWNoIHRoZSBtZWFzdXJlbWVudCB0b29rIHBsYWNlCiNbMl0gdHJpYWwgLSB0cmlhbCBudW1iZXIgKFQxLCBUMiwgVDMgYW5kIFQ0KQojWzNdIHJvb2YgLSBjb25jZW50cmF0aW9uIG9mIG5pdHJvdXMgb3hpZGUgKGluIHBwbSkgb3V0c2lkZSB0aGUgY2hhbWJlcgojWzRdIEM3IC0gY29uY2VudHJhdGlvbiBvZiBuaXRyb3VzIG94aWRlIChpbiBwcG0pIGluc2lkZSBjaGFtYmVyIDcKI1s1XSBDOCAtIGNvbmNlbnRyYXRpb24gb2Ygbml0cm91cyBveGlkZSAoaW4gcHBtKSBpbnNpZGUgY2hhbWJlciA4CgoKI0NhbGN1bGF0ZSB0aGUgcHJvZHVjdGlvbiBpbnNpZGUgdGhlIGNoYW1iZXIgYW5kIGtlZXAgdGhlc2UgY29sdW1ucwpuaXRyb3VzX294aWRlJENoYW1iZXI3IDwtIG5pdHJvdXNfb3hpZGUkQzctbml0cm91c19veGlkZSRyb29mCm5pdHJvdXNfb3hpZGUkQ2hhbWJlcjggPC0gbml0cm91c19veGlkZSRDOC1uaXRyb3VzX294aWRlJHJvb2YKbml0cm91c19veGlkZSA8LSBuaXRyb3VzX294aWRlWywgYygxLCAyLCA2LCA3KV0Kbml0cm91c19veGlkZSA8LSBnYXRoZXIobml0cm91c19veGlkZSwgICJjaGFtYmVyIiwgInByb2R1Y3Rpb24iLCAzOjQpCgojbmFtZSBvZiB0aGUgdHJlYXRtZW50Cm5pdHJvdXNfb3hpZGUkdHJlYXRtZW50IDwtICBpZmVsc2Uobml0cm91c19veGlkZSRjaGFtYmVyPT0iQ2hhbWJlcjciICYgbml0cm91c19veGlkZSR0cmlhbD09IlQxIiwgIldpdGhvdXQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uobml0cm91c19veGlkZSRjaGFtYmVyPT0iQ2hhbWJlcjgiICYgbml0cm91c19veGlkZSR0cmlhbD09IlQxIiwgIldpdGhfQlNGTCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlJGNoYW1iZXI9PSJDaGFtYmVyNyIgJiBuaXRyb3VzX294aWRlJHRyaWFsPT0iVDIiLCAiV2l0aF9CU0ZMIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlJGNoYW1iZXI9PSJDaGFtYmVyOCIgJiBuaXRyb3VzX294aWRlJHRyaWFsPT0iVDIiLCAiV2l0aG91dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG5pdHJvdXNfb3hpZGUkY2hhbWJlcj09IkNoYW1iZXI3IiAmIG5pdHJvdXNfb3hpZGUkdHJpYWw9PSJUMyIsICJXaXRob3V0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG5pdHJvdXNfb3hpZGUkY2hhbWJlcj09IkNoYW1iZXI4IiAmIG5pdHJvdXNfb3hpZGUkdHJpYWw9PSJUMyIsICJXaXRoX0JTRkwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKG5pdHJvdXNfb3hpZGUkY2hhbWJlcj09IkNoYW1iZXI3IiAmIG5pdHJvdXNfb3hpZGUkdHJpYWw9PSJUNCIsICJXaXRoX0JTRkwiLCAiV2l0aG91dCIpKSkpKSkpCgojVG8gY2FsY3VsYXRlIHRoZSBwcm9kdWN0aW9uIG9mIE4yTywgd2UgbmVlZCB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgcHBtIGNvbmNlbnRyYXRpb25zIGJldHdlZW4gdHdvIGNvbnNlY3V0aXZlIG1lYXN1cmVtZW50cwpuaXRyb3VzX294aWRlJGNvbiA8LSBwYXN0ZTAobml0cm91c19veGlkZSR0cmlhbCwgbml0cm91c19veGlkZSR0cmVhdG1lbnQpCm5pdHJvdXNfb3hpZGUkdmFsdWUgPC0gaWZlbHNlKG5pdHJvdXNfb3hpZGUkY29uPT0gbGVhZChuaXRyb3VzX294aWRlJGNvbiksICgobml0cm91c19veGlkZSRwcm9kdWN0aW9uICsgbGVhZChuaXRyb3VzX294aWRlJHByb2R1Y3Rpb24pKS8yKSwgTkEpCm5pdHJvdXNfb3hpZGUkZGF5bnVtYmVyIDwtIGlmZWxzZShuaXRyb3VzX294aWRlJGNvbj09IGxlYWQobml0cm91c19veGlkZSRjb24pLCBwYXN0ZTAobml0cm91c19veGlkZSRkYXksICItIiwgbGVhZChuaXRyb3VzX294aWRlJGRheSkpLCBOQSkKbml0cm91c19veGlkZSA8LSBuaXRyb3VzX294aWRlWywgYygyLCA1LCA3LCA4KV0Kbml0cm91c19veGlkZSA8LSBuYS5vbWl0KG5pdHJvdXNfb3hpZGUpCgoKI0dldCB2ZW50aWxhdGlvbiBwZXIgZGF5CmNoYW1iZXJzXzIgPC0gY2hhbWJlcnMKY2hhbWJlcnNfMiRob3VyIDwtIGFzLm51bWVyaWMoY2hhbWJlcnNfMiRob3VyKQoKI3ZlbnRpbGF0aW9uIGlzIGluIGwvbWluIHNvIHRvIGNvbnZlcnQgaXQgdG8gbC9ob3VyIC0+IFNUUEQqNjAKY2hhbWJlcnNfbjJvIDwtIGRkcGx5KGNoYW1iZXJzXzIsIC4odHJpYWwsIHRyZWF0bWVudCwgZGF5bnVtYmVyLCBob3VyKSwgc3VtbWFyaXplLCAKICAgICAgICAgICAgICAgICAgICAgIG1lYW5fdmVudGlsYXRpb24gPSBtZWFuKFNUUEQqNjAsIG5hLnJtPVRSVUUpKQoKY2hhbWJlcnNfbjJvJGhvdXIgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoY2hhbWJlcnNfbjJvJGhvdXIpKQoKI25ldyBkYXkgY2xhc3NpZmljYXRpb24gYmFzZWQgb24gdGhlIHRpbWUgb2YgdGhlIGRheSBpbiB3aGljaCBhaXIgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCBmb3IgTjJPIGFuYWx5c2lzCmNoYW1iZXJzX24ybyRuZXcgPC0gaWZlbHNlKChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5MSIpfChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5MiIgJiBjaGFtYmVyc19uMm8kaG91cjw9OCksICJEYXkxLURheTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTIiICYgY2hhbWJlcnNfbjJvJGhvdXI+PTkpfChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5MyIgJiBjaGFtYmVyc19uMm8kaG91cjw9OCksICJEYXkyLURheTMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTMiICYgY2hhbWJlcnNfbjJvJGhvdXI+PTkpfChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5NCIgJiBjaGFtYmVyc19uMm8kaG91cjw9OCksICJEYXkzLURheTQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5NCIgJiBjaGFtYmVyc19uMm8kaG91cj49OSl8KGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk1IiAmIGNoYW1iZXJzX24ybyRob3VyPD04KSwgIkRheTQtRGF5NSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoKGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk1IiAmIGNoYW1iZXJzX24ybyRob3VyPj05KXwoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTYiICYgY2hhbWJlcnNfbjJvJGhvdXI8PTgpLCAiRGF5NS1EYXk2IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoKGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk2IiAmIGNoYW1iZXJzX24ybyRob3VyPj05KXwoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTciICYgY2hhbWJlcnNfbjJvJGhvdXI8PTgpLCAiRGF5Ni1EYXk3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKChjaGFtYmVyc19uMm8kZGF5bnVtYmVyPT0iZGF5NyIgJiBjaGFtYmVyc19uMm8kaG91cj49OSl8KGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk4IiAmIGNoYW1iZXJzX24ybyRob3VyPD04KSwgIkRheTctRGF5OCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoKGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk4IiAmIGNoYW1iZXJzX24ybyRob3VyPj05KXwoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTkiICYgY2hhbWJlcnNfbjJvJGhvdXI8PTgpLCAiRGF5OC1EYXk5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoKGNoYW1iZXJzX24ybyRkYXludW1iZXI9PSJkYXk5IiAmIGNoYW1iZXJzX24ybyRob3VyPj05KXwoY2hhbWJlcnNfbjJvJGRheW51bWJlcj09ImRheTEwIiAmIGNoYW1iZXJzX24ybyRob3VyPD04KSwgIkRheTktRGF5MTAiLCAibmFkYSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSkpKSkpKSkKI2NhbGN1bGF0ZSB0aGUgdG90YWwgdmVudGlsYXRpb24gbGl0ZXJzIHBlciBuZXcgZGF5IG51bWJlcgpjaGFtYmVyc19uMm8gPC0gZGRwbHkoY2hhbWJlcnNfbjJvLCAuKHRyaWFsLCB0cmVhdG1lbnQsIG5ldyksIHN1bW1hcml6ZSwgCiAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9zdHBkX3ZlbnQgPSBzdW0obWVhbl92ZW50aWxhdGlvbiwgbmEucm09VFJVRSkpCgoKIyBtZXJnZSBib3RoIGRhdGFzZXRzIChuMm8gcHJvZHVjdGlvbiBhbmQgdmVudGlsYXRpb24pCmNoYW1iZXJzX24ybyRjb25jYXRlbmF0ZSA8LSBwYXN0ZTAoY2hhbWJlcnNfbjJvJHRyaWFsLCBjaGFtYmVyc19uMm8kdHJlYXRtZW50LCBjaGFtYmVyc19uMm8kbmV3KQpuaXRyb3VzX294aWRlJGNvbmNhdGVuYXRlIDwtIHBhc3RlMChuaXRyb3VzX294aWRlJHRyaWFsLCBuaXRyb3VzX294aWRlJHRyZWF0bWVudCwgbml0cm91c19veGlkZSRkYXludW1iZXIpCm5pdHJvdXNfb3hpZGUgPC0gbWVyZ2Uobml0cm91c19veGlkZSwgY2hhbWJlcnNfbjJvLCBieT0iY29uY2F0ZW5hdGUiKQoKI2FwcGx5IGVxdWF0aW9uIHRvIGNhbGN1bGF0ZSBwcm9kdWN0aW9uIGluIG1nIHBlciBkYXkKIyA0NCBpcyB0aGUgbW9sYXIgbWFzcyBvZiBuMm8KIyAyMi40IGlzIHRoZSBtb2xhciB2b2x1bWUgb2YgYSBnYXMKIyAqMTAwMCBpcyB0byBjb252ZXJ0IGl0IHRvIG1pbGlncmFtcwpuaXRyb3VzX294aWRlJG4yb19tZyA8LSAoKG5pdHJvdXNfb3hpZGUkdmFsdWUqMTBeKC02KSkqbml0cm91c19veGlkZSR0b3RhbF9zdHBkX3ZlbnQqKDQ0LzIyLjQpKSoxMDAwCgpuaXRyb3VzX294aWRlIDwtIG5pdHJvdXNfb3hpZGVbLCBjKDIsIDMsIDUsIDEwICldCm5hbWVzKG5pdHJvdXNfb3hpZGUpIDwtIGMoInRyaWFsIiwgInRyZWF0bWVudCIsICJkYXkiLCAibjJvX21nIikKCgojbWVyZ2Ugd2l0aCBkcnltYXR0ZXIgbWFudXJlIHRvIGVzdGltYXRlIG4ybyBwcm9kdWN0aW9uIHBlciBrZyBvZiBkcnkgbWF0dGVyIG1hbnVyZQpuaXRyb3VzX294aWRlIDwtIG1lcmdlKG5pdHJvdXNfb3hpZGUsIGRyeW1hbnVyZV9nLCBieT0idHJpYWwiKQpuaXRyb3VzX294aWRlJG4yb19tZ19wZXJrZyA8LSAoMTAwMCpuaXRyb3VzX294aWRlJG4yb19tZykvbml0cm91c19veGlkZSRkcnl3ZWlnaHRfZ3JhbXMKbml0cm91c19veGlkZQpgYGAKCgojIyMgU3RlcDIwIC0gU3RhdGlzdGljcyAtIElzIE4yTyBwcm9kdWN0aW9uIGRpZmZlcmVudCBmcm9tIHplcm8/CmBgYHtyIGVjaG89VFJVRX0KI1Rlc3QgaWYgTjJPIGRpZmZlcnMgZnJvbSB6ZXJvCiN0LXRlc3QKdF9uMm8gPC0gbml0cm91c19veGlkZSAlPiUKICBncm91cF9ieSh0cmVhdG1lbnQsIGRheSkgJT4lCiAgZG8odGlkeSh0LnRlc3QoLiRuMm9fbWcsIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpKSkKdF9uMm8KCiN3cml0ZS5jc3YodF9uMm8sICJUX3Rlc3RfbjJvLmNzdiIsIHJvdy5uYW1lcyA9IEYpCmBgYAoKIyMjIFN0ZXAyMSAtIFN1cHBsZW1lbnRhcnkgRmlndXJlIDMgcGFuZWwgQQpgYGB7ciBlY2hvPVRSVUV9CiNPcmRlciBmYWN0b3JzIGZvciBTdXBwbGVtZW50YXJ5IEZpZ3VyZQpHYXNzZXMkbmFtZTIgPC0gZmFjdG9yKEdhc3NlcyRuYW1lMiwgbGV2ZWxzID0gYygiQ08yIChsL2gpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNINCAobC9oKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJIZWF0IChLSi9oKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOSDMgKGwvaCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTzIgKGwvaCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUlEiKSkKR2Fzc2VzJGRheW51bWJlcjwtIGZhY3RvcihHYXNzZXMkZGF5bnVtYmVyLCBsZXZlbHMgPSBjKCJEYXkxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5MiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5NSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5OCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXkxMCIpKQoKIGdncGxvdChkYXRhPUdhc3NlcywgYWVzKHg9YXMubnVtZXJpYyhob3VyKSwgeT1uZXd2YWx1ZSwgZ3JvdXA9dHJpYWwpKSsKICBnZW9tX2xpbmUoc2l6ZT0xLCBhZXMobGluZXR5cGU9dHJpYWwsIGNvbD10cmlhbCkpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgCiAgZmFjZXRfZ3JpZChuYW1lMn50cmVhdG1lbnQrZGF5bnVtYmVyLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgdGhlbWVfYncoKSsKICB5bGFiKCIiKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iVGltZSBvZiB0aGUgZGF5IChob3VycykiLCBleHBhbmQgPSBjKDAsIDApLCBicmVha3MgPSBjKDAsIDEyLCAwKSkrCiAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMC4xLCAibGluZXMiKSkrCiAgZ2d0aXRsZSgiIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpKwogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKyAKICB0aGVtZShheGlzLnRpdGxlLnggID0gZWxlbWVudF90ZXh0KHNpemU9MTIpKSsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoInNvbGlkIiwgImRvdHRlZCIsICJ0d29kYXNoIiwgImxvbmdkYXNoIikpCiAKICNnZ3NhdmUocGF0aD0ib3V0cHV0cyIsIGZpbGU9IkZpZ3VyZVMzX0EucGRmIiwgd2lkdGggPSAyNSwgaGVpZ2h0ID0gMjAsIHVuaXRzPSJjbSIsIGRwaT0zMDApICNzYXZlcyBnCmBgYAojIyMgU3RlcDIxIFN1cHBsZW1lbnRhcnkgRmlndXJlIDMgLSBwYW5lbCAoQikKYGBge3IgZWNobz1UUlVFfQojU3VwcGxlbWVudGFyeSBmaWd1cmUgTjJPCmdncGxvdChkYXRhPW5pdHJvdXNfb3hpZGUsIGFlcyh4PWRheSwgeT1uMm9fbWdfcGVya2csIGdyb3VwPXRyaWFsKSkrCiAgZ2VvbV9saW5lKHNpemU9MSwgYWVzKGxpbmV0eXBlPXRyaWFsLCBjb2w9dHJpYWwpKSsKICBnZW9tX3BvaW50KCkrCiAgZmFjZXRfd3JhcCh+dHJlYXRtZW50KSsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCBoanVzdCA9IDAuNSwgc2l6ZT0xMCkpICsgCiAgeWxhYigiTjJPIChtZykvZGF5L2tnIERNIG1hbnVyZSIpKwogIHhsYWIoIiIpKwogIHRoZW1lX2J3KCkrCiAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMC4xLCAibGluZXMiKSkrCiAgZ2d0aXRsZSgiIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT00KSkrCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiLCAidHdvZGFzaCIsICJsb25nZGFzaCIpKSsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1mdW5jdGlvbih4KXtzdWIoIi0iLCAiXG4iLCB4KX0pCgojZ2dzYXZlKHBhdGg9Im91dHB1dHMiLCBmaWxlPSJGaWd1cmVTM19CLnBkZiIsIHdpZHRoID0gMjUsIGhlaWdodCA9IDEwLCB1bml0cz0iY20iLCBkcGk9MzAwKSAjc2F2ZXMgZwoKYGBgCiMjIyBTdGVwMjIgLSBGaWd1cmUgNApgYGB7ciBlY2hvPVRSVUV9CiNDYWxjdWxhdGUgYXZlcmFnZSBhbmQgc3RkX2Vycm9yIHBlciBkYXkgcGVyIHRyZWF0bWVudCAoZm9yIGFsbCBnYXNzZXMgZXhjZXB0IE4yTykKZmlndXJlNCA8LSBkZHBseShHYXNzZXMsIC4odHJlYXRtZW50LCBkYXludW1iZXIsIGhvdXIsIG5hbWUyKSwgc3VtbWFyaXplLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZlcmFnZT0gbWVhbihuZXd2YWx1ZSwgbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZF9lcnJvcj0gc3RkLmVycm9yKG5ld3ZhbHVlLCBuYS5ybT1UUlVFKSkKCgojb3JkZXIgZGF5cyBmb3IgZmlndXJlCmZpZ3VyZTQkZGF5bnVtYmVyPC0gZmFjdG9yKGZpZ3VyZTQkZGF5bnVtYmVyLCBsZXZlbHMgPSBjKCJEYXkxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5MiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5NSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGF5OCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRheTkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXkxMCIpKQojc3Vic2V0IHRvIG1ha2UgaW5kZXBlbmRlbnQgZmlndXJlcyBvZiBlYWNoCkNPMiA8LSBzdWJzZXQoZmlndXJlNCwgKG5hbWUyPT0iQ08yIChsL2gpIikpCkNINCA8LSBzdWJzZXQoZmlndXJlNCwgKG5hbWUyPT0iQ0g0IChsL2gpIikpCkhFQVQgPC0gc3Vic2V0KGZpZ3VyZTQsIChuYW1lMj09IkhlYXQgKEtKL2gpIikpCk5IMyA8LSBzdWJzZXQoZmlndXJlNCwgKG5hbWUyPT0iTkgzIChsL2gpIikpClJRIDwtIHN1YnNldChmaWd1cmU0LCAobmFtZTI9PSJSUSIpKQoKI0ZpZ3VyZSBDTzIKQ08yX2ZpZyA8LSBnZ3Bsb3QoZGF0YT1DTzIsIGFlcyh4PWFzLm51bWVyaWMoaG91ciksIHk9YXZlcmFnZSwgY29sPSB0cmVhdG1lbnQsIGdyb3VwPXRyZWF0bWVudCwgZmlsbD10cmVhdG1lbnQpKSsKICBnZW9tX2xpbmUoc2l6ZT0xLCBhZXMobGluZXR5cGU9dHJlYXRtZW50KSkrCiAgZ2VvbV9yaWJib24oYWVzKHltaW49KGF2ZXJhZ2Utc3RkX2Vycm9yKSwgeW1heD0oYXZlcmFnZStzdGRfZXJyb3IpLCBsaW5ldHlwZT10cmVhdG1lbnQpLCBhbHBoYT0wLjYpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgCiAgZmFjZXRfZ3JpZCh+ZGF5bnVtYmVyLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgdGhlbWVfYncoKSsKICB5bGFiKGV4cHJlc3Npb24oQ09bMl1+KEwvaG91cikpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iIiwgZXhwYW5kID0gYygwLCAwKSwgYnJlYWtzID0gYygwLCAxMiwgMCkpKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAuMSwgImxpbmVzIikpKwogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIGdndGl0bGUoIiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9Yygic29saWQiLCAiZG90dGVkIikpCgojRmlndXJlIENINApDSDRfZmlnIDwtIGdncGxvdChkYXRhPUNINCwgYWVzKHg9YXMubnVtZXJpYyhob3VyKSwgeT1hdmVyYWdlKjEwMDAsIGNvbD0gdHJlYXRtZW50LCBncm91cD10cmVhdG1lbnQsIGZpbGw9dHJlYXRtZW50KSkrCiAgZ2VvbV9saW5lKHNpemU9MSwgYWVzKGxpbmV0eXBlPXRyZWF0bWVudCkpKwogIGdlb21fcmliYm9uKGFlcyh5bWluPShhdmVyYWdlKjEwMDAtc3RkX2Vycm9yKjEwMDApLCB5bWF4PShhdmVyYWdlKjEwMDArc3RkX2Vycm9yKjEwMDApLCBsaW5ldHlwZT10cmVhdG1lbnQpLCBhbHBoYT0wLjYpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgCiAgZmFjZXRfZ3JpZCh+ZGF5bnVtYmVyLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgdGhlbWVfYncoKSsKICB5bGFiKGV4cHJlc3Npb24oQ0hbNF1+KG1ML2hvdXIpKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlRpbWUgb2YgdGhlIGRheSAoaG91cnMpIiwgZXhwYW5kID0gYygwLCAwKSwgYnJlYWtzID0gYygwLCAxMiwgMCkpKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAuMSwgImxpbmVzIikpKwogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIGdndGl0bGUoIiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9Yygic29saWQiLCAiZG90dGVkIikpCgojRmlndXJlIE5IMwpOSDNfZmlnIDwtIGdncGxvdChkYXRhPU5IMywgYWVzKHg9YXMubnVtZXJpYyhob3VyKSwgeT1hdmVyYWdlKjEwMDAsIGNvbD0gdHJlYXRtZW50LCBncm91cD10cmVhdG1lbnQsIGZpbGw9dHJlYXRtZW50KSkrCiAgZ2VvbV9saW5lKHNpemU9MSwgYWVzKGxpbmV0eXBlPXRyZWF0bWVudCkpKwogIGdlb21fcmliYm9uKGFlcyh5bWluPShhdmVyYWdlKjEwMDAtc3RkX2Vycm9yKjEwMDApLCB5bWF4PShhdmVyYWdlKjEwMDArc3RkX2Vycm9yKjEwMDApLCBsaW5ldHlwZT10cmVhdG1lbnQpLCBhbHBoYT0wLjYpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgCiAgZmFjZXRfZ3JpZCh+ZGF5bnVtYmVyLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgdGhlbWVfYncoKSsKICB5bGFiKGV4cHJlc3Npb24oTkhbM11+KG1ML2hvdXIpKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlRpbWUgb2YgdGhlIGRheSAoaG91cnMpIiwgZXhwYW5kID0gYygwLCAwKSwgYnJlYWtzID0gYygwLCAxMiwgMCkpKwogIHRoZW1lKHBhbmVsLnNwYWNpbmcgPSB1bml0KDAuMSwgImxpbmVzIikpKwogIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJ3aGl0ZSIpKSsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM1Y2I4NWMiLCcjRTY5RjAwJykpKwogIGdndGl0bGUoIiIpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9MTApKSArIAogIHRoZW1lKGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9Yygic29saWQiLCAiZG90dGVkIikpCgoKI0ZpZ3VyZSBOSDMKUlFfZmlnIDwtIGdncGxvdChkYXRhPVJRLCBhZXMoeD1hcy5udW1lcmljKGhvdXIpLCB5PWF2ZXJhZ2UsIGNvbD0gdHJlYXRtZW50LCBncm91cD10cmVhdG1lbnQsIGZpbGw9dHJlYXRtZW50KSkrCiAgZ2VvbV9saW5lKHNpemU9MSwgYWVzKGxpbmV0eXBlPXRyZWF0bWVudCkpKwogIGdlb21fcmliYm9uKGFlcyh5bWluPShhdmVyYWdlLXN0ZF9lcnJvciksIHltYXg9KGF2ZXJhZ2Urc3RkX2Vycm9yKSwgbGluZXR5cGU9dHJlYXRtZW50KSwgYWxwaGE9MC42KSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIAogIGZhY2V0X2dyaWQofmRheW51bWJlciwgc2NhbGVzID0gImZyZWVfeSIpKwogIHRoZW1lX2J3KCkrCiAgeWxhYigiUmVzcGlyYXRvcnkgcXVvdGllbnQiKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iVGltZSBvZiB0aGUgZGF5IChob3VycykiLCBleHBhbmQgPSBjKDAsIDApLCBicmVha3MgPSBjKDAsIDEyLCAwKSkrCiAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMC4xLCAibGluZXMiKSkrCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9ZWxlbWVudF9yZWN0KGZpbGw9IndoaXRlIikpKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzVjYjg1YyIsJyNFNjlGMDAnKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzVjYjg1YyIsJyNFNjlGMDAnKSkrCiAgZ2d0aXRsZSgiIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpICsgCiAgdGhlbWUoYXhpcy50aXRsZS54ICA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSkrCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiKSkKCgojRmlndXJlIE4yTwojR2l2ZW4gdGhhdCB3ZSBkaWRuJ3QgdGFrZSBob3VybHkgbWVhc3VyZW1lbnRzIG9mIE4yTyAob25seSBvbmNlIHBlciBkYXkpLCB3ZSBuZWVkIHRvIG1ha2Ugc29tZSBkYXRhIG1hbmlwdWxhdGlvbiBpbiBvcmRlciB0bwojZ2V0IHRoZSBzYW1lIGZpZ3VyZSBhcyB0aGUgb3RoZXIgZ2FzZXMuCgojRXh0cmFjdCBzYW1lIGZvcm1hdCBvZiBkYXRhc2V0IGZyb20gdGhlIGRhdGFzZXQgZ2FzX2F2ZXJhZ2UgYW5kIGFkYXB0IGl0IGZvciBOMk8KZmlnX24ybyA8LSBHYXNfYXZlcmFnZQpmaWdfbjJvIDwtIHN1YnNldChmaWdfbjJvLCAodmFyaWFibGU9PSJtZWFuX0NINCIpKQpmaWdfbjJvIDwtIGZpZ19uMm9bLCBjKDEsIDIsIDQsIDUpXQpmaWdfbjJvJHZhcmlhYmxlIDwtICJtZWFuX04yTyIKZmlnX24ybyRuMm9fbWdfcGVya2cgPC0gTkEKZmlnX24ybyA8LSBzdWJzZXQoZmlnX24ybywgKGhvdXIhPSI5IikpCmZpZ19uMm8gPC0gc3Vic2V0KGZpZ19uMm8sICgoZGF5bnVtYmVyIT0iZGF5MSIpICYgKGhvdXIhPTE3KSkpCmZpZ19uMm8gPC0gc3Vic2V0KGZpZ19uMm8sICgoZGF5bnVtYmVyIT0iZGF5MTAiKSAmIChob3VyIT04KSkpCgoKI01vZGlmeSB0aGUgbmFtZSBub21lbmNsYXR1cmUKbml0cm91c19veGlkZV9tb2RpZmllZCA8LSBuaXRyb3VzX294aWRlCm5pdHJvdXNfb3hpZGVfbW9kaWZpZWQkZGF5bnVtYmVyIDwtIGlmZWxzZShuaXRyb3VzX294aWRlX21vZGlmaWVkJGRheT09IkRheTEtRGF5MiIsICJEYXkyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uobml0cm91c19veGlkZV9tb2RpZmllZCRkYXk9PSJEYXkyLURheTMiLCAiRGF5MyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlX21vZGlmaWVkJGRheT09IkRheTMtRGF5NCIsICJEYXk0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlX21vZGlmaWVkJGRheT09IkRheTQtRGF5NSIsICJEYXk1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uobml0cm91c19veGlkZV9tb2RpZmllZCRkYXk9PSJEYXk1LURheTYiLCAiRGF5NiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlX21vZGlmaWVkJGRheT09IkRheTYtRGF5NyIsICJEYXk3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShuaXRyb3VzX294aWRlX21vZGlmaWVkJGRheT09IkRheTctRGF5OCIsICJEYXk4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uobml0cm91c19veGlkZV9tb2RpZmllZCRkYXk9PSJEYXk4LURheTkiLCAiRGF5OSIsICJEYXkxMCIpKSkpKSkpKQoKI0luZGljYXRlIGF0IHdoYXQgaG91ciBvZiB0aGUgZGF5IE4yTyBtZWFzdXJlbWVudHMgd2VyZSB0YWtlbgpuaXRyb3VzX294aWRlX21vZGlmaWVkJGhvdXIgPC0gaWZlbHNlKG5pdHJvdXNfb3hpZGVfbW9kaWZpZWQkZGF5bnVtYmVyPT0iRGF5MTAiLCAiOCIsICI5IikKbml0cm91c19veGlkZV9tb2RpZmllZDIgPC0gc3Vic2V0KG5pdHJvdXNfb3hpZGVfbW9kaWZpZWQsIChkYXk9PSJEYXkxLURheTIiKSkKbml0cm91c19veGlkZV9tb2RpZmllZDIkZGF5bnVtYmVyIDwtICJEYXkxIgpuaXRyb3VzX294aWRlX21vZGlmaWVkMiRob3VyIDwtIDE3Cm5pdHJvdXNfb3hpZGVfbW9kaWZpZWQyJG4yb19tZ19wZXJrZyA8LSAwCm5pdHJvdXNfb3hpZGVfbW9kaWZpZWQgPC0gcmJpbmQobml0cm91c19veGlkZV9tb2RpZmllZCwgbml0cm91c19veGlkZV9tb2RpZmllZDIpCm5pdHJvdXNfb3hpZGVfbW9kaWZpZWQkdmFyaWFibGUgPC0gIm1lYW5fTjJPIgpuaXRyb3VzX294aWRlX21vZGlmaWVkIDwtIG5pdHJvdXNfb3hpZGVfbW9kaWZpZWRbLCBjKDEsIDIsIDgsIDksIDEwLCA3KV0KCgojQmluZCB0aGUgZGF0YXNldCB3aXRoIHRoZSBzdHJ1Y3R1cmUgb2YgZGF5cyBhbmQgaG91cnMsIHdpdGggdGhlIG9uZSB0aGF0IGNvbnRhaW4gdGhlIG4ybyBtZWFzdXJlbWVudHMuIApmaWdfbjJvIDwtIHJiaW5kKGZpZ19uMm8sIG5pdHJvdXNfb3hpZGVfbW9kaWZpZWQpCm5hbWVzKGZpZ19uMm8pWzVdIDwtICJhdmVyYWdlIgpmaWdfbjJvJGhvdXIgPC0gYXMubnVtZXJpYyhmaWdfbjJvJGhvdXIpCgojTWFrZSBmaWd1cmUKZmlnX24ybyRkYXludW1iZXIgPC0gZmFjdG9yKGZpZ19uMm8kZGF5bnVtYmVyLCBsZXZlbHMgPSBjKCJEYXkxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXkyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXkzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk2IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXk5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEYXkxMCIpKQoKCk4yT19maWcgPC0gZ2dwbG90KGRhdGE9ZmlnX24ybywgYWVzKHg9YXMubnVtZXJpYyhob3VyKSwgeT1uMm9fbWdfcGVya2csIGZpbGw9dHJlYXRtZW50LCBsaW5ldHlwZT10cmVhdG1lbnQpKSsKICBnZW9tX2JveHBsb3Qod2lkdGg9OCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyAKICBmYWNldF9ncmlkKH5kYXludW1iZXIsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICB0aGVtZV9idygpKwogIHlsYWIoZXhwcmVzc2lvbihOWzJdfk9+KG1ML2RheSkpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iVGltZSBvZiB0aGUgZGF5IChob3VycykiLCBleHBhbmQgPSBjKDAsIDApLCBicmVha3MgPSBjKDAsIDEyLCAwKSkrCiAgdGhlbWUocGFuZWwuc3BhY2luZyA9IHVuaXQoMC4xLCAibGluZXMiKSkrCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9ZWxlbWVudF9yZWN0KGZpbGw9IndoaXRlIikpKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiIzVjYjg1YyIsJyNFNjlGMDAnKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzVjYjg1YyIsJyNFNjlGMDAnKSkrCiAgZ2d0aXRsZSgiIikrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpICsgCiAgdGhlbWUoYXhpcy50aXRsZS54ICA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSkrCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJzb2xpZCIsICJkb3R0ZWQiKSkKCgphbGxncmFwaCA8LSBhcnJhbmdlR3JvYihDTzJfZmlnLCBDSDRfZmlnLCBOSDNfZmlnLCBOMk9fZmlnLCBSUV9maWcgLCBucm93PTMpICNnZW5lcmF0ZXMgZwojZ2dzYXZlKHBhdGg9Im91dHB1dHMiLCBmaWxlPSJGaWd1cmU0LnBkZiIsIHdpZHRoID0gMjUsIGhlaWdodCA9IDIwLCB1bml0cz0iY20iLCBkcGk9MzAwLCBhbGxncmFwaCkgI3NhdmVzIGcKCgpgYGAKCmBgYHtyfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiRmlndXJlNC5wbmciKQpgYGAKCiMjIyBTdGVwIDIyIC0gVGFibGUgMiAtIGVtaXNzaW9ucyBwZXIga2cgb2YgZHJ5IG1hbnVyZSBhbmQgcGVyIGtnIG9mIGZyZXNoIGFuZCBkcnkgbGFydmFlCmBgYHtyIGVjaG89VFJVRX0KI0dldCBvdmVyYWxsIGVtaXNzaW9ucyAoQ08yLCBDSDQsIEVuZXJneSwgT3h5Z2VuLCBOIGFuZCBOMk8pIHBlciByZXBsaWNhdGUsIHBlciBrZyBvZiBtYW51cmUsIHBlciBrZyBvZiBmcmVzaCBhbmQgZHJ5IGxhcnZhZQojQ2FsY3VsYXRlIE4yTyBpbiBtaWxpZ3JhbXMKCm5pdHJvdXNfb3hpZGVfbWcgPC0gZGRwbHkobml0cm91c19veGlkZSwgLih0cmlhbCx0cmVhdG1lbnQpLCBzdW1tYXJpemUsIAogICAgICAgICAgICAgICAgIHRvdGFsID0gc3VtKG4yb19tZykpCm5pdHJvdXNfb3hpZGVfbWcgJGl0ZW0gPC0gIk4yTyAobWcpIgpuYW1lcyhuaXRyb3VzX294aWRlX21nIClbM10gPC0gInZhbHVlIgpuaXRyb3VzX294aWRlX21nIDwtIG5pdHJvdXNfb3hpZGVfbWdbLCBjKDEsIDIsIDQsIDMpXQoKCiNnZXQgdG90YWwgTiAoc3VtIGNvbmRlbnNlZCB3YXRlciArIGFjaWQpCnRvdGFsX24kaXRlbSA8LSAiTiAoZykiCm5hbWVzKHRvdGFsX24pWzNdIDwtICJ2YWx1ZSIKdG90YWxfbjwtIHRvdGFsX25bLCBjKDEsMiw0LDMpXQoKCiNnZXQgQ08yLCBDSDQsIE94eWdlbiBhbmQgSGVhdAp0b3RhbF9DTzJfQ0g0X0hFQVRfTzIKdG90YWxfQ08yX0NINF9IRUFUX08yIDwtIHRvdGFsX0NPMl9DSDRfSEVBVF9PMlssIGMoMSwgMiwgNjo5KV0KbmFtZXModG90YWxfQ08yX0NINF9IRUFUX08yKVszXSA8LSAiQ08yIChnKSIKbmFtZXModG90YWxfQ08yX0NINF9IRUFUX08yKVs0XSA8LSAiTzIgKGcpIgpuYW1lcyh0b3RhbF9DTzJfQ0g0X0hFQVRfTzIpWzVdIDwtICJDSDQgKGcpIgpuYW1lcyh0b3RhbF9DTzJfQ0g0X0hFQVRfTzIpWzZdIDwtICJIZWF0IChLSikiCnRvdGFsX0NPMl9DSDRfSEVBVF9PMiA8LSBnYXRoZXIodG90YWxfQ08yX0NINF9IRUFUX08yLCAiaXRlbSIsICJ2YWx1ZSIsIDM6NikKCgojI2JpbmQgZGF0YXNldHMgKG5pdHJvZ2VuLCBjaGFtYmVyc19zdW1tYXJ5IGFuZCBuaXRyb3VzIG94aWRlKQpBaXJfZW1pc3Npb25zIDwtIHJiaW5kKHRvdGFsX24sIHRvdGFsX0NPMl9DSDRfSEVBVF9PMiwgbml0cm91c19veGlkZV9tZykKCgojIyMgQ2FsY3VsYXRlIGVtaXNzaW9ucyBleHByZXNzZWQgaW4gZGlmZmVyZW50IHVuaXRzIChwZXIga2cgb2YgZHJ5IG1hbnVyZSwgcGVyIGtnIG9mIGZyZXNoIGxhcnZhZSwgcGVyIGtnIG9mIGRyeSBsYXJ2YWUpCgojUGVyIGtnIG9mIGZyZXNoIGxhcnZhZQojQWRkIGRyeSBtYXR0ZXIgbWFudXJlIChncmFtcykKQWlyX2VtaXNzaW9ucyA8LSBtZXJnZShBaXJfZW1pc3Npb25zLCBkcnltYW51cmVfZywgYnk9InRyaWFsIikKQWlyX2VtaXNzaW9ucyRrZ19kcnlfbWFudXJlIDwtIChBaXJfZW1pc3Npb25zJHZhbHVlKjEwMDApL0Fpcl9lbWlzc2lvbnMkZHJ5d2VpZ2h0X2dyYW1zCm5hbWVzKEFpcl9lbWlzc2lvbnMpWzJdIDwtICJ0cmVhdG1lbnQiCgoKI1BlciBrZyBvZiBmcmVzaCBsYXJ2YWUKI0ZyZXNoIGxhcnZhZSB5aWVsZCBwZXIgdHJpYWwKZl9sX3lpZWxkIDwtIHN1YnNldChmcmVzaF9iaW9tYXNzLCAocGFydD09IkxhcnZhZSIpKQpmX2xfeWllbGQgPC0gZl9sX3lpZWxkWywgYygxLCAyLCA1KV0KZl9sX3lpZWxkJHRyZWF0bWVudCA8LSAiRnJlc2ggbGFydmFlIHlpZWxkIChnKSIKQWlyX2VtaXNzaW9ucyA8LSBtZXJnZShBaXJfZW1pc3Npb25zLCBmX2xfeWllbGQsIGJ5PSJ0cmlhbCIpCkFpcl9lbWlzc2lvbnMka2dmcmVzaGxhcnZhZSA8LSAoQWlyX2VtaXNzaW9ucyR2YWx1ZS54KjEwMDApL0Fpcl9lbWlzc2lvbnMkdmFsdWUueQpBaXJfZW1pc3Npb25zIDwtIEFpcl9lbWlzc2lvbnNbLCBjKDEsIDIsIDMsIDQsIDcsIDEwKV0KCiNQZXIga2cgb2YgZHJ5IGxhcnZhZQojZHJ5IGxhcnZhZSB5aWVsZCBwZXIgdHJpYWwKZF9sX3lpZWxkIDwtIHN1YnNldChOQl9vdXRwdXRzLCAocGFydDI9PSJMYXJ2YWUiKSkKZF9sX3lpZWxkIDwtIGRfbF95aWVsZFssIGMoMiwgNyldCmRfbF95aWVsZCR0cmVhdG1lbnQgPC0gIkRyeSBsYXJ2YWUgeWllbGQgKGcpIgpjb2xuYW1lcyhkX2xfeWllbGQpWzJdIDwtICJ2YWx1ZSIKQWlyX2VtaXNzaW9ucyA8LSBtZXJnZShBaXJfZW1pc3Npb25zLCBkX2xfeWllbGQsIGJ5PSJ0cmlhbCIpCkFpcl9lbWlzc2lvbnMka2dkcnlsYXJ2YWUgPC0gIChBaXJfZW1pc3Npb25zJHZhbHVlLngqMTAwMCkvQWlyX2VtaXNzaW9ucyR2YWx1ZQpBaXJfZW1pc3Npb25zIDwtIEFpcl9lbWlzc2lvbnNbLCBjKDE6MywgNSwgNiwgOSldCgoKI1JlbW92ZSB0aGUgdmFsdWVzIHBlciBrZyBvZiBmcmVzaCBhbmQgZHJ5IGxhcnZhZSBmb3IgdGhlIHRyZWF0bWVudCBXaXRob3V0IChhcyB0aGVyZSB3YXMgbm8gbGFydmFlKQpBaXJfZW1pc3Npb25zIDwtIGdhdGhlcihBaXJfZW1pc3Npb25zLCAidmFyaWFibGUiLCAidmFsdWUiLCA0OjYpCkFpcl9lbWlzc2lvbnMkY29uY2F0ZW5hdGUgPC0gcGFzdGUwKEFpcl9lbWlzc2lvbnMkdHJlYXQsIEFpcl9lbWlzc2lvbnMkdmFyaWFibGUpCkFpcl9lbWlzc2lvbnMgPC0gc3Vic2V0KEFpcl9lbWlzc2lvbnMsIChjb25jYXRlbmF0ZSE9IldpdGhvdXRrZ2ZyZXNobGFydmFlIiAmIGNvbmNhdGVuYXRlIT0gIldpdGhvdXRrZ2RyeWxhcnZhZSIpKSAjVGhpcyBjb250YWlucyB0aGUgZW1pc3Npb25zIHBlciB0cmlhbC4gVGhpcyBkYXRhc2V0IHdpbGwgYmUgdXNlZCBpbiBzdGVwIDI0Cm5hbWVzKEFpcl9lbWlzc2lvbnMpWzJdIDwtICJ0cmVhdG1lbnQiCiNVc2UgYWlyIGVtaXNzaW9ucyB0YWJsZSB0byBjYWxjdWxhdGUgYXZlcmFnZXMgKG9mIGFsbCB0cmlhbHMpCgojQ3JlYXRlIHN1cHBsZW1lbnRhcnkgdGFibGUgMgpUYWJsZVMyIDwtIEFpcl9lbWlzc2lvbnMgJT4lIHNlbGVjdCgxLCAzLCA0LCA1KQpUYWJsZVMyIDwtIHN1YnNldChUYWJsZVMyLCAodmFyaWFibGUhPSJrZ19kcnlfbWFudXJlIikpCm5hbWVzKFRhYmxlUzIpIDwtIGMoIlRyaWFsIiwgIkl0ZW0iLCAiVmFyaWFibGUiLCAiVmFsdWUiKQpUYWJsZVMyIDwtIHNwcmVhZChUYWJsZVMyLCBWYXJpYWJsZSwgVmFsdWUpCgojd3JpdGUuY3N2KFRhYmxlUzIsIGZpbGUgPSAiVGFibGVTMi5jc3YiLCByb3cubmFtZXMgPSBGKQoKVGFibGU0IDwtIGRkcGx5KEFpcl9lbWlzc2lvbnMsIC4odHJlYXRtZW50LCBpdGVtLCAgdmFyaWFibGUpLCBzdW1tYXJpemUsIAogICAgICAgICAgICAgICAgICAgbWVhbiA9IG1lYW4odmFsdWUpLAogICAgICAgICAgICAgICAgICAgc3RkX2Vycm9yID1zdGQuZXJyb3IodmFsdWUpKQoKI1RoaXMgd2lsbCBiZSBkb25lIHdpdGggc3RhbmRhcmQgZGV2aWF0aW9uICB0byBjb21wYXJlIG91ciBlbWlzc2lvbnMgd2l0aCBvdGhlciBzdHVkaWVzClRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUgPC0gZGRwbHkoQWlyX2VtaXNzaW9ucywgLih0cmVhdG1lbnQsIGl0ZW0sICB2YXJpYWJsZSksIHN1bW1hcml6ZSwgCiAgICAgICAgICAgICAgICAgICBtZWFuID0gbWVhbih2YWx1ZSksCiAgICAgICAgICAgICAgICAgICBzdGRfZGV2ID1zZCh2YWx1ZSkpCgpUYWJsZTQkbWVhbnN0ZGVycm9yIDwtIHBhc3RlMChyb3VuZChUYWJsZTQkbWVhbiwgZGlnaXRzID0gMiksICLCsSIsIHJvdW5kKFRhYmxlNCRzdGRfZXJyb3IsIGRpZ2l0cyA9IDIpKQpUYWJsZTQgPC0gVGFibGU0WywgYygxLCAyLCAzLCA2KV0KVGFibGU0IDwtIHNwcmVhZChUYWJsZTQsIHRyZWF0bWVudCwgbWVhbnN0ZGVycm9yKQoKVGFibGVfZW1pc3Npb25zX3BlcmtnX2xhcnZhZSRtZWFuc3RkZXJyb3IgPC0gcGFzdGUwKHJvdW5kKFRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUkbWVhbiwgZGlnaXRzID0gMiksICLCsSIsIHJvdW5kKFRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUkc3RkX2RldiwgZGlnaXRzID0gMikpClRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUgPC0gVGFibGVfZW1pc3Npb25zX3BlcmtnX2xhcnZhZVssIGMoMSwgMiwgMywgNildClRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUgPC0gc3ByZWFkKFRhYmxlX2VtaXNzaW9uc19wZXJrZ19sYXJ2YWUsIHRyZWF0bWVudCwgbWVhbnN0ZGVycm9yKQoKI0VtaXNzaW9ucyBwZXIga2cgb2YgZnJlc2ggYW5kIGRyeSBsYXJ2YWUKZW1fZHJ5X2ZyZXNoIDwtIHN1YnNldChUYWJsZV9lbWlzc2lvbnNfcGVya2dfbGFydmFlLCB2YXJpYWJsZT09ImtnZHJ5bGFydmFlIiB8IHZhcmlhYmxlPT0ia2dmcmVzaGxhcnZhZSIpCmVtX2RyeV9mcmVzaCA8LSBzcHJlYWQoZW1fZHJ5X2ZyZXNoLCB2YXJpYWJsZSwgV2l0aF9CU0ZMKQoKI2VtaXNzaW9ucyBwZXIga2cgb2YgZG0gbWFudXJlClRhYmxlNCA8LSBuYS5vbWl0KFRhYmxlNCkKVGFibGU0IDwtIFRhYmxlNFssIGMoMSwgNCwgMyldCgoKI0NhbGN1bGF0ZSBlbWlzc2lvbnMgaW4gQ08yIGVxIChjb21iaW5hdGlvbiBvZiBDSDQgYW5kIE4yTykgdG8gYWRkIGl0IHRvIFRhYmxlNApDTzJlcSA8LSBBaXJfZW1pc3Npb25zCkNPMmVxJENPMmVxIDwtIGlmZWxzZShDTzJlcSRpdGVtPT0iTjJPIChtZykiLCAoKChDTzJlcSR2YWx1ZSkvMTAwMCkqMjk4KSwgCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoQ08yZXEkaXRlbT09IkNINCAoZykiLCAoKChDTzJlcSR2YWx1ZSkpKjM0KSwgTkEpKQoKQ08yZXEgPC0gbmEub21pdChDTzJlcSkKQ08yZXEgPC0gc3Vic2V0KENPMmVxLCAodmFyaWFibGU9PSJrZ19kcnlfbWFudXJlIiB8IHZhcmlhYmxlPT0ia2dkcnlsYXJ2YWUiKSkKCkNPMmVxIDwtICBkZHBseShDTzJlcSwgLih0cmlhbCwgdHJlYXRtZW50LCBjb25jYXRlbmF0ZSksIHN1bW1hcml6ZSwgCiAgICAgICAgICAgICAgICBzdW0gPSBzdW0oQ08yZXEpKQoKQ08yZXFfbWVhbiA8LSBkZHBseShDTzJlcSwgLih0cmVhdG1lbnQsIGNvbmNhdGVuYXRlKSwgc3VtbWFyaXplLCAKICAgICAgICAgICAgICAgICAgICBtZWFuID0gbWVhbihzdW0pLAogICAgICAgICAgICAgICAgICAgIHN0ZF9lcnJvciA9IHNkKHN1bSkpCgpDTzJlcV9tZWFuJG1lYW5zdGRlcnJvciA8LSBwYXN0ZTAocm91bmQoQ08yZXFfbWVhbiRtZWFuLCBkaWdpdHMgPSAxKSwgIsKxIiwgcm91bmQoQ08yZXFfbWVhbiRzdGRfZXJyb3IsIGRpZ2l0cyA9IDEpKSNoZXJlIHlvdSBjYW4gc2VlIENPMmVxIHBlciBrZyBETSBsYXJ2YWUgMzQzLjk5wrE0My4xNCBncmFtcwpDTzJlcV9tZWFuIDwtIENPMmVxX21lYW5bYygxLCAzKSxdCkNPMmVxX21lYW4gPC0gQ08yZXFfbWVhblssIGMoMSwgNSldCgoKQ08yZXFfbWVhbiA8LSBzcHJlYWQoQ08yZXFfbWVhbiwgdHJlYXRtZW50LCBtZWFuc3RkZXJyb3IpCkNPMmVxX21lYW4kaXRlbSA8LSAiQ08yIGVxIChnKSIKQ08yZXFfbWVhbiA8LSBDTzJlcV9tZWFuWywgYygzLCAyLCAxKV0KCgojRmluaXNoIHRhYmxlIDQgKGJpbmQgVGFibGUgNCB3aXRoIENPMmVxX21lYW4pClRhYmxlNCA8LSByYmluZChUYWJsZTQsIENPMmVxX21lYW4pClRhYmxlNApgYGAKCiMjIyBTdGVwIDI0IC0gU3RhdGlzdGljcyBkbyBvdmVyYWxsIGVtaXNzaW9ucyBkaWZmZXIgcGVyIHRyZWF0bWVudD8KYGBge3IgZWNobz1UUlVFfQojTWVyZ2UgYWlyIGVtaXNzaW9ucyB3aXRoIENPMl9lcSBiZWZvcmUgZG9pbmcgdGhlIG11bHRpcGxlIHJlZ3Jlc3Npb24KI01vZmlmeSBkYXRhZnJhbWUgQ08yZXEgdG8gYmluZCBpdCB0byBBaXIgZW1pc3Npb25zCkNPMmVxIDwtIHN1YnNldChDTzJlcSwgKGNvbmNhdGVuYXRlIT0iV2l0aF9CU0ZMa2dkcnlsYXJ2YWUiKSkgCkNPMmVxJGl0ZW0gPC0gIkNPMmVxIChnKSIKQ08yZXEkdmFyaWFibGUgPC0gImtnX2RyeV9tYW51cmUiCm5hbWVzKENPMmVxKVs0XSA8LSAidmFsdWUiCkNPMmVxIDwtIENPMmVxWywgYygxLCAyLCA1LCA2LCA0LCAzKV0KCiNCaW5kIEFpciBlbWlzc2lvbnMgYW5kIENPMmVxIGFuZCBmb3JtYXQgZGF0YXNldCBmb3Igc3RhdGlzdGljYWwgdGVzdApBaXJfZW1pc3Npb25zMiA8LSByYmluZChBaXJfZW1pc3Npb25zLCBDTzJlcSkKQWlyX2VtaXNzaW9uczIgPC0gQWlyX2VtaXNzaW9uczJbLCBjKDE6NSldICNyZW1vdmUgY29sdW1uIGNvbmNhdGVuYXRlCiNTZWxlY3Qgb25seSB0aGUgdmFsdWVzIGV4cHJlc3NlZCBwZXIga2cgb2YgZHJ5IG1hbnVyZQpBaXJfZW1pc3Npb25zMiA8LSBzdWJzZXQoQWlyX2VtaXNzaW9uczIsICh2YXJpYWJsZT09ImtnX2RyeV9tYW51cmUiKSkKCiNNdWx0aXBsZSByZWdyZXNzaW9uCgpzdGF0c19nYXNlcyA8LSBBaXJfZW1pc3Npb25zMiU+JSAKICBncm91cF9ieShpdGVtKSAlPiUKICBncm91cF9tb2RpZnkofiBicm9vbTo6dGlkeShhb3YodmFsdWV+dHJlYXRtZW50ICsgdHJpYWwsIGRhdGEgPSAueCkpKQoKc3RhdHNfZ2FzZXMkc2lnbmlmaWNhbmNlIDwtIGlmZWxzZShzdGF0c19nYXNlcyRwLnZhbHVlPDAuMDUgJiBzdGF0c19nYXNlcyRwLnZhbHVlPjAuMDEsICIqIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHN0YXRzX2dhc2VzJHAudmFsdWU8MC4wMSAmIHN0YXRzX2dhc2VzJHAudmFsdWU+MC4wMDEsICIqKiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uoc3RhdHNfZ2FzZXMkcC52YWx1ZTwwLjAwMSwgIioqKiIsICIiKSkpCgoKc3RhdHNfZ2FzZXMKCiN3cml0ZS5jc3Yoc3RhdHNfZ2FzZXMsIGZpbGU9IkFOT1ZBX1RhYmxlNS5jc3YiLCByb3cubmFtZXMgPSBGKQoKYGBgCgojIyBQYXJ0IDUgLSBCaW9jb252ZXJzaW9uIHBhcmFtZXRlcnMKIyMjIFN0ZXAgMjUgLSBJbmRpdmlkdWFsIHN0YXJ0ZXIgbGFydmFlIHNpemUgcGVyIGJhdGNoIChGb3IgVGFibGUgUzQpCmBgYHtyIGVjaG89VFJVRX0KI0VzdGltYXRlIGluZGl2aWR1YWwgc2l6ZSBvZiBzdGFydGVyIGxhcnZhZSBwZXIgYmF0Y2gKI1dlaWdodCAoZ3JhbXMpIGdyb3VwIG9mIDUwIHN0YXJ0ZXJzCnN0YXJ0ZXJzX2JhdGNoMSA8LSBjKDAuNjcsMC43NCwwLjY1LDAuNjEsMC42MiwwLjYxLDAuNjIsMC42MywwLjYxLDAuNjUpCnN0YXJ0ZXJzX2JhdGNoMiA8LSBjKDAuNzksMC44MiwwLjc2LDAuODIsMC43LDAuNzgsMC44MiwwLjc2LDAuNzQsMC43NykKc3RhcnRlcnNfYmF0Y2gzIDwtIGMoMC4zNCwwLjM2LDAuNCwwLjM2LDAuMzgsMC4zMSwwLjQzLDAuMzgsMC4zOCwwLjM2KQpzdGFydGVyc19iYXRjaDQgPC0gYygwLjI5LDAuMjgsMC4yOSwwLjM2LDAuMjcsMC4yNywwLjI2LDAuMzEsMC4yNSwwLjI5KQoKYmF0Y2hfd2VpZ2h0IDwtIGMoc3RhcnRlcnNfYmF0Y2gxLCBzdGFydGVyc19iYXRjaDIsIHN0YXJ0ZXJzX2JhdGNoMywgc3RhcnRlcnNfYmF0Y2g0KQp0cmlhbCA8LSByZXAoYygiVDEiLCAiVDIiLCAiVDMiLCAiVDQiKSwgZWFjaD0xMCwgbGVuPTQwKQoKI0NyZWF0ZSBkYXRhc2V0IHN0YXJ0ZXJzX3dlaWdodApzdGFydGVyc193ZWlnaHQgPC0gZGF0YS5mcmFtZShiYXRjaF93ZWlnaHQsIHRyaWFsKQoKI0NhbGN1bGF0ZSB3ZWlnaHQgcGVyIGluZGl2aWR1YWwgbGFydmEgKG1nKQpzdGFydGVyc193ZWlnaHQkaW5kaXZpZHVhbF93ZWlnaHQgPC0gKHN0YXJ0ZXJzX3dlaWdodCRiYXRjaF93ZWlnaHQvNTApKjEwMDAKCiNNZWFuIGFuZCBzdGFuZGFyZCBlcnJvcgpzdGFydGVyczE8LSBzdGFydGVyc193ZWlnaHQgJT4lCiAgZ3JvdXBfYnkodHJpYWwpICU+JQogIHN1bW1hcmlzZSgKICAgIG1lYW4gPSBtZWFuKGluZGl2aWR1YWxfd2VpZ2h0KSwKICAgIHN0ZF9lcnJvciA9IHN0ZC5lcnJvcihpbmRpdmlkdWFsX3dlaWdodCkpCgpzdGFydGVyczEKYGBgCgojIyMgU3RlcCAyNiAtIEJpb2NvbnZlcnNpb24gcGFyYW1ldGVycwpgYGB7ciBlY2hvPVRSVUV9CiMjIyMjIyNTdXBwbGVtZW50YXJ5IFRhYmxlIHdpdGggZGV0YWlsZWQgZGF0YSBvZiB0aGUgYmlvY29udmVyc2lvbiBwcm9jZXNzLgojRnJlc2ggbWFudXJlIHByb3ZpZGVkCnRyaWFsIDwtIGMoIlQxIiwgIlQyIiwgIlQzIiwgIlQ0IikKZnJlc2hfbV9wcm92aWRlZDwtIGMoMjA4MTQuMDYsIDE2NjQ5LjM1LCAxODQwNC45MSwgMTg0MDcuMDUpCmZyZXNoX21hbnVyZSA8LSBkYXRhLmZyYW1lKHRyaWFsLCBmcmVzaF9tX3Byb3ZpZGVkKQpmcmVzaF9tYW51cmUkdHJlYXRtZW50IDwtICJGcmVzaCBtYW51cmUgcHJvdmlkZWQgKGcpIgpmcmVzaF9tYW51cmUgPC0gZnJlc2hfbWFudXJlWywgYygxLCAzLCAyKV0KY29sbmFtZXMoZnJlc2hfbWFudXJlKVszXSA8LSAidmFsdWUiCgojbWFudXJlIGRyeSBtYXR0ZXIKZG1fbWFudXJlIDwtIGMoMjEuMzUsIDI1LjM5LCAyMy4yMSwgMjUuNjUpCmRyeV9tYW51cmUgPC0gZGF0YS5mcmFtZSh0cmlhbCwgZG1fbWFudXJlKQpkcnlfbWFudXJlJHRyZWF0bWVudCA8LSAiTWFudXJlIGRyeSBtYXR0ZXIgKCUpIgpkcnlfbWFudXJlIDwtIGRyeV9tYW51cmVbLCBjKDEsIDMsIDIpXQpjb2xuYW1lcyhkcnlfbWFudXJlKVszXSA8LSAidmFsdWUiCgojZHJ5IG1hbnVyZSBwcm92aWRlZApkcnltYW51cmUgPC0gbWVyZ2UoZnJlc2hfbWFudXJlLCBkcnlfbWFudXJlLCBieT0idHJpYWwiKQpkcnltYW51cmUkdmFsdWUgPC0gZHJ5bWFudXJlJHZhbHVlLngqKGRyeW1hbnVyZSR2YWx1ZS55LzEwMCkKZHJ5bWFudXJlIDwtIGRyeW1hbnVyZVssIGMoMSwgMiwgNildCmNvbG5hbWVzKGRyeW1hbnVyZSlbMl0gPC0gInRyZWF0bWVudCIKZHJ5bWFudXJlJHRyZWF0bWVudCA8LSAiRHJ5IG1hbnVyZSBwcm92aWRlZCAoZykiCgoKI0ZyZXNoIGxhcnZhZSB5aWVsZCBwZXIgdHJpYWwKZl9sX3lpZWxkIDwtIHN1YnNldChmcmVzaF9iaW9tYXNzLCAocGFydD09IkxhcnZhZSIpKQpmX2xfeWllbGQgPC0gZl9sX3lpZWxkWywgYygxLCAyLCA1KV0KZl9sX3lpZWxkJHRyZWF0bWVudCA8LSAiRnJlc2ggbGFydmFlIHlpZWxkIChnKSIKCiNkcnkgbGFydmFlIHlpZWxkIHBlciB0cmlhbApkX2xfeWllbGQgPC0gc3Vic2V0KE5CX291dHB1dHMsIChwYXJ0Mj09IkxhcnZhZSIpKQpkX2xfeWllbGQgPC0gZF9sX3lpZWxkWywgYygyLCA3KV0KZF9sX3lpZWxkJHRyZWF0bWVudCA8LSAiRHJ5IGxhcnZhZSB5aWVsZCAoZykiCmRfbF95aWVsZCA8LSBkX2xfeWllbGRbLCBjKDEsIDMsIDIpXQpjb2xuYW1lcyhkX2xfeWllbGQpWzJdIDwtICJ0cmVhdG1lbnQiCmNvbG5hbWVzKGRfbF95aWVsZClbM10gPC0gInZhbHVlIgoKI0RNIHBlcmNlbnRhZ2UgbGFydmFlCmRtX2wgPC0gc3Vic2V0KGNoZW1pY2FsX2FuYWx5c2lzLCAocGFydD09IkxhcnZhZSIpKQpkbV9sIDwtIGRtX2xbLCBjKDEsIDIsIDUpXQpkbV9sJHRyZWF0bWVudCA8LSAiTGFydmFlIGRyeSBtYXR0ZXIgY29udGVudCglKSIKY29sbmFtZXMoZG1fbClbM10gPC0gInZhbHVlIgpkbV9sJHZhbHVlIDwtIGRtX2wkdmFsdWUvMTAKCiNmcmVzaCBsYXJ2YWUgZ2FpbgpmX2xnIDwtIHN1YnNldChmcmVzaF9iaW9tYXNzLCAocGFydD09IlN0YXJ0ZXJzIikpCmZfbGcgPC0gZl9sZ1ssIGMoMSwgNCwgNSldCmZfbGckcGFydCA8LSAiRnJlc2ggbGFydmFlIGdhaW4gd2VpZ2h0IChnKSIKY29sbmFtZXMoZl9sZylbMl0gPC0gInRyZWF0bWVudCIKZl9sZyA8LSBtZXJnZShmX2xnLCBmX2xfeWllbGQsIGJ5PSJ0cmlhbCIpCmZfbGckdmFsdWUgPC0gZl9sZyR2YWx1ZS55LWZfbGckdmFsdWUueApmX2xnIDwtIGZfbGdbLCBjKDEsIDQsIDYpXQpjb2xuYW1lcyhmX2xnKSBbMl0gPC0gInRyZWF0bWVudCIKZl9sZyR0cmVhdG1lbnQ8LSAiRnJlc2ggbGFydmFlIGdhaW4gd2VpZ2h0IChnKSIKCiNkcnkgbGFydmFlIGdhaW4KZF9sZyA8LSBzdWJzZXQoZnJlc2hfYmlvbWFzcywgKHBhcnQ9PSJTdGFydGVycyIpKQpkX2xnIDwtIGRfbGdbLCBjKDEsIDQsIDUpXQpzdGFydGVyc2RtIDwtIHN1YnNldChjaGVtaWNhbF9hbmFseXNpcywgKHBhcnQ9PSJTdGFydGVycyIpKQpzdGFydGVyc2RtIDwtIHN1YnNldChzdGFydGVyc2RtLCAodHJlYXRtZW50PT0iV2l0aF9CU0ZMIikpCnN0YXJ0ZXJzZG0gPC0gc3RhcnRlcnNkbVssIGMoMSwgMiwgNSldCmRfbGcgPC0gbWVyZ2UoZF9sZywgc3RhcnRlcnNkbSwgYnk9InRyaWFsIikKZF9sZyRzdGFydGVyc19kcnk8LSBkX2xnJHZhbHVlKihkX2xnJERNLzEwMDApCmRfbGcgPC0gZF9sZ1ssIGMoMSwgNCwgNildCmRfbGcgPC0gbWVyZ2UoZF9sZywgZF9sX3lpZWxkLCBieT0idHJpYWwiKQpkX2xnJGRyeWdhaW4gPC0gZF9sZyR2YWx1ZS1kX2xnJHN0YXJ0ZXJzX2RyeQpkX2xnIDwtIGRfbGdbLCBjKDEsIDIsIDYpXQpjb2xuYW1lcyhkX2xnKVsyXSA8LSAidHJlYXRtZW50IgpkX2xnJHRyZWF0bWVudCA8LSAiRHJ5IGxhcnZhZSBnYWluIHdlaWdodCAoZykiCmNvbG5hbWVzKGRfbGcpWzNdIDwtICJ2YWx1ZSIKCgoja2cgb2YgZnJlc2ggbGFydmFlIHBlciBrZyBvZiBmcmVzaApmbHlfeGZyZXNobWFudXJlIDwtIG1lcmdlKGZyZXNoX21hbnVyZSwgZl9sX3lpZWxkLCBieT0idHJpYWwiKQpmbHlfeGZyZXNobWFudXJlJHZhbHVlMiA8LShmbHlfeGZyZXNobWFudXJlJHZhbHVlLnkqMTAwMCkvZmx5X3hmcmVzaG1hbnVyZSR2YWx1ZS54CmZseV94ZnJlc2htYW51cmUgPC0gZmx5X3hmcmVzaG1hbnVyZVssIGMoMSwgMiwgNildCmNvbG5hbWVzKGZseV94ZnJlc2htYW51cmUpWzJdIDwtICJ0cmVhdG1lbnQiCmZseV94ZnJlc2htYW51cmUkdHJlYXRtZW50IDwtICJGcmVzaCBsYXJ2YWUgeWllbGQgKGcpIHBlciBrZyBvZiBmcmVzaCBtYW51cmUiCmNvbG5hbWVzKGZseV94ZnJlc2htYW51cmUpWzNdIDwtICJ2YWx1ZSIgIAoKI2tnIGRyeSBsYXJ2YWUgcGVyIGtmIG9mIGRyeSBtYW51cmUKZmx5X3hkcnltYW51cmUgPC0gbWVyZ2UoZHJ5bWFudXJlLCBkX2xfeWllbGQsIGJ5PSJ0cmlhbCIpCmZseV94ZHJ5bWFudXJlJHZhbHVlMiA8LShmbHlfeGRyeW1hbnVyZSR2YWx1ZS55KjEwMDApL2ZseV94ZHJ5bWFudXJlJHZhbHVlLngKZmx5X3hkcnltYW51cmUgPC0gZmx5X3hkcnltYW51cmVbLCBjKDEsIDIsIDYpXQpjb2xuYW1lcyhmbHlfeGRyeW1hbnVyZSlbMl0gPC0gInRyZWF0bWVudCIKZmx5X3hkcnltYW51cmUkdHJlYXRtZW50IDwtICJEcnkgbGFydmFlIHlpZWxkIChnKSBwZXIga2cgb2YgZHJ5IG1hbnVyZSIKY29sbmFtZXMoZmx5X3hkcnltYW51cmUpWzNdIDwtICJ2YWx1ZSIgIAoKCiNJbmRpdmlkdWFsIG1hdHVyZSBsYXJ2YWUgd2VpZ2h0Cm1hdHVyZWxhcnZhZV90cmlhbDEgPC0gYyg0LjI0LCA0LjI5LCA0LjEyLCA0LjI2LCAzLjQ1LCA0LjEyLCA0LjI3LCAzLjQsIDQuMTgsIDQuMTQpCm1hdHVyZWxhcnZhZV90cmlhbDIgPC0gYyg0Ljk2LCA1LjA3LCA0Ljg3LCA0LjY5LCA0LjksIDQuNywgNS4wNywgNS4wNywgNC43NiwgNC43NCkKbWF0dXJlbGFydmFlX3RyaWFsMyA8LSBjKDMuOTQsIDMuOTEsIDQuMDMsIDMuOTgsIDMuOTgsIDMuODQsIDQuMTIsIDMuNzYsIDQsIDMuOTgpCm1hdHVyZWxhcnZhZV90cmlhbDQgPC0gYygzLjk0LCAzLjkxLCA0LjAzLCAzLjk4LCAzLjk4LCAzLjg0LCA0LjEyLCAzLjc2LCA0LCAzLjk4KQoKd2VpZ2h0X21hdHVyZV90cmlhbCA8LSBjKG1hdHVyZWxhcnZhZV90cmlhbDEsIG1hdHVyZWxhcnZhZV90cmlhbDIsIG1hdHVyZWxhcnZhZV90cmlhbDMsIG1hdHVyZWxhcnZhZV90cmlhbDQpCnRyaWFsX25hbWUgPC0gcmVwKGMoInRyaWFsMSIsICJ0cmlhbDIiLCAidHJpYWwzIiwgInRyaWFsNCIpLCBlYWNoPTEwLCBsZW49NDApCgojZGYgd2VpZ2h0IG1hdHVyZSBsYXJ2YWUKbWF0dXJlbGFydmFlX3dlaWdodCA8LSBkYXRhLmZyYW1lKHRyaWFsX25hbWUsIHdlaWdodF9tYXR1cmVfdHJpYWwpCm1hdHVyZWxhcnZhZV93ZWlnaHQkdmFsdWUgPC0gKG1hdHVyZWxhcnZhZV93ZWlnaHQkd2VpZ2h0X21hdHVyZV90cmlhbC81MCkqMTAwMApjb2xuYW1lcyhtYXR1cmVsYXJ2YWVfd2VpZ2h0KVsxXSA8LSAidHJpYWwiCmNvbG5hbWVzKG1hdHVyZWxhcnZhZV93ZWlnaHQpWzJdIDwtICJ0cmVhdG1lbnQiCm1hdHVyZWxhcnZhZV93ZWlnaHQkdHJlYXRtZW50IDwtICJGaW5hbCBsYXJ2YWUgaW5kaXZpZHVhbCB3ZWlnaHQgKG1nKSIKCiNXZWlnaHQgc3RhcnRlciBsYXJ2YWUKCnN0YXJ0ZXJsYXJ2YWVfd2VpZ2h0IDwtIHN0YXJ0ZXJzMQpzdGFydGVybGFydmFlX3dlaWdodCR0cmVhdG1lbnQgPC0gIlN0YXJ0ZXIgbGFydmFlIGluZGl2aWR1YWwgd2VpZ2h0IChtZykiCm5hbWVzKHN0YXJ0ZXJsYXJ2YWVfd2VpZ2h0KVsyXSA8LSAidmFsdWUiCnN0YXJ0ZXJsYXJ2YWVfd2VpZ2h0IDwtIHN0YXJ0ZXJsYXJ2YWVfd2VpZ2h0WywgYygxLCA0LCAyKV0KCiNKb2luIGFsbCBkYXRhc2V0cyBhbmQgY3JlYXRlIG9uZSB3aXRoIGF2ZXJhZ2UgYW5kIHN0YW5kYXJkIGVycm9yCnRhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscyA8LSByYmluZChmcmVzaF9tYW51cmUsIGRyeV9tYW51cmUsIGRyeW1hbnVyZSwgZl9sX3lpZWxkLCBkX2xfeWllbGQsIGRtX2wsIGZfbGcsIGRfbGcsIGZseV94ZnJlc2htYW51cmUsIGZseV94ZHJ5bWFudXJlLCBtYXR1cmVsYXJ2YWVfd2VpZ2h0LCBzdGFydGVybGFydmFlX3dlaWdodCkKYXZlcmFnZV90YWJsZV9iaW9jb252ZXJzaW9uX2RldGFpbHMgPC0gZGRwbHkodGFibGVfYmlvY29udmVyc2lvbl9kZXRhaWxzLCAuKHRyZWF0bWVudCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW49bWVhbih2YWx1ZSwgbmEucm09VCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkX2Vycm9yID0gc3RkLmVycm9yKHZhbHVlLCBuYS5ybT1UKSkKCgphdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscyR2YWx1ZTIgPC0gcGFzdGUwKHJvdW5kKGF2ZXJhZ2VfdGFibGVfYmlvY29udmVyc2lvbl9kZXRhaWxzJG1lYW4sIGRpZ2l0cyA9IDApLCAiIMKxICIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyb3VuZChhdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscyRzdGRfZXJyb3IsIGRpZ2l0cyA9IDEpKSkKCgphdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscyA8LSBhdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlsc1ssIGMoMSwgNCldCmNvbG5hbWVzKGF2ZXJhZ2VfdGFibGVfYmlvY29udmVyc2lvbl9kZXRhaWxzKVsxXSA8LSAiUGFyYW1ldGVyIgpjb2xuYW1lcyhhdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscylbMl0gPC0gIlZhbHVlIgoKYXZlcmFnZV90YWJsZV9iaW9jb252ZXJzaW9uX2RldGFpbHMgPC0gYXZlcmFnZV90YWJsZV9iaW9jb252ZXJzaW9uX2RldGFpbHNbYyg4LCA0LCA2LCAyLCAxMCwgMTEsIDUsIDEsIDcsIDMsIDkpLF0KYXZlcmFnZV90YWJsZV9iaW9jb252ZXJzaW9uX2RldGFpbHMKI3dyaXRlLmNzdihhdmVyYWdlX3RhYmxlX2Jpb2NvbnZlcnNpb25fZGV0YWlscyxmaWxlID0gIkJpb2NvbnZlcnNpb25fcGFyYW1ldGVycy5jc3YiLCByb3cubmFtZXMgPSBGKQpgYGAKCg==