• Getting started
    • clean up
    • general custom functions
    • necessary packages
    • load data-set
    • last alterations
  • multilevel model
    • variance partitioning
    • ties nested in alters/dyads
    • seperate analyses by tie type
  • Average marginal effects
    • define data-sets
    • get models
    • functions to calculate AME
    • bootstrapping
    • AME / AMME
    • AME / AMIE
    • separate analyses by tie type
  • Robustness analyses
    • accounting for ‘forgetting’
    • confidant loss analyses by gender
    • alternative ‘age dissimilarity’ measure

Getting started

To copy the code, click the button in the upper right corner of the code-chunks.

clean up

rm(list = ls())
gc()


general custom functions

  • fpackage.check: Check if packages are installed (and install if not) in R
  • fsave: Function to save data with time stamp in correct directory
  • fload: Function to load R-objects under new names
  • ftheme: pretty ggplot2 theme
  • fshowdf: Print objects (tibble / data.frame) nicely on screen in .Rmd.
  • ffit: fit a series of (here, generalized linear mixed-effects) models
fpackage.check <- function(packages) {
    lapply(packages, FUN = function(x) {
        if (!require(x, character.only = TRUE)) {
            install.packages(x, dependencies = TRUE)
            library(x, character.only = TRUE)
        }
    })
}

fsave <- function(x, file, location = "./data/processed/", ...) {
    if (!dir.exists(location))
        dir.create(location)
    datename <- substr(gsub("[:-]", "", Sys.time()), 1, 8)
    totalname <- paste(location, datename, file, sep = "")
    print(paste("SAVED: ", totalname, sep = ""))
    save(x, file = totalname)
}

fload <- function(fileName) {
    load(fileName)
    get(ls()[ls() != "fileName"])
}

# extrafont::font_import(paths = c('C:/Users/u244147/Downloads/Jost/', prompt = FALSE))
ftheme <- function() {

    # download font at https://fonts.google.com/specimen/Jost/
    theme_minimal(base_family = "Jost") + theme(panel.grid.minor = element_blank(), plot.title = element_text(family = "Jost",
        face = "bold"), axis.title = element_text(family = "Jost Medium"), axis.title.x = element_text(hjust = 0),
        axis.title.y = element_text(hjust = 1), strip.text = element_text(family = "Jost", face = "bold",
            size = rel(0.75), hjust = 0), strip.background = element_rect(fill = "grey90", color = NA),
        legend.position = "bottom")
}

fshowdf <- function(x, digits = 2, ...) {
    knitr::kable(x, digits = digits, "html", ...) %>%
        kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
        kableExtra::scroll_box(width = "100%", height = "300px")
}

ffit <- function(formula, data) {
    tryCatch({
        model <- lme4::glmer(formula, data = data, family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa",
            optCtrl = list(maxfun = 1e+05)))
        cat("Fitting model:", as.character(formula), "\n")
        summary(model)
        cat("\n")
        return(model)
    }, error = function(e) {
        cat("Error fitting model:", as.character(formula), "\n")
        cat("Error message:", conditionMessage(e), "\n")
        return(NULL)
    })
}


necessary packages

  • lme4: fitting random effects models
  • mlmhelpr, containing the icc function to calculate the intraclass correlation for multilevel models
  • lmtest: diagnostic tests (likelihood ratio test)
  • car: companion applied regression (calculate VIF)
  • texreg: output to HTML table
  • ggpubr: format ggplot2 plots
  • ggh4x: hacks for ggplot2
packages = c("lme4", "mlmhelpr", "lmtest", "textreg", "car", "ggplot2", "parallel", "ggpubr", "ggh4x")
fpackage.check(packages)
rm(packages)


load data-set

Load the replicated data-set (constructed here). To load these file, adjust the filename in the following code so that it matches the most recent version of the .RDa file you have in your ./data/processed/ folder.

You may also obtain them by downloading: Download data_nested.RDa

# list files in processed data folder
list.files("./data/processed/")

# get todays date:
today <- gsub("-", "", Sys.Date())

# use fload
df <- fload(paste0("./data/processed/", today, "data_nested.RDa"))


last alterations

  • make Y indicate tie loss instead of tie maintenance
  • make X reflect dissimilarity instead of similarity
  • standardize embeddedness in other network layers
  • proximity levels
df$Y <- ifelse(df$Y == 1, 0, 1)

df$different_gender <- ifelse(df$same_gender == 1, 0, 1)
df$different_educ <- ifelse(df$sim_educ == 1, 0, 1)

df$embed.ext <- df$embed.ext/3

df$proximity <- factor(df$proximity, levels = c("far", "close", "roommate"))


multilevel model

variance partitioning

Starting with null model (one-level, assuming independent observations). Then include random ego-level intercept, and random ego-alter combination intercept:

# null/flat model (assuming no clustering at all)
model01 <- glm(Y ~ 1, data = df, family = binomial(link = "logit"))
summary(model01)

# add random ego-level intercept
model02 <- glmer(Y ~ 1 + (1 | ego), data = df, family = binomial(link = "logit"))
summary(model02)
icc(model02)

# add random ego-alter combi intercept
model03 <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid), data = df, family = binomial(link = "logit"))
summary(model03)
icc(model03)

# retrieve variance components
varcomp <- VarCorr(model03)

# 1. ego-level
var3 <- varcomp$ego[1]
# 2. dyad-level
var2 <- varcomp$"ego:alterid"[1]
# 3. latent variable method: substitute the constant quantity π^2/3 for the level-1 variance.
var1 <- (pi^2)/3

# vpc3 <- var3/(var1+var2+var3) vpc2 <- (var2 + var3)/(var1+var2+var3) 1 - vpc2

# final 'null model', including period and social role fixed effects
model0 <- glmer(Y ~ 1 + tie + period + (1 | ego) + (1 | ego:alterid), data = df, family = binomial(link = "logit"))
summary(model0)
icc(model0)

# variance partitioning:
varcomp <- VarCorr(model0)

# 1. ego-level
var3 <- varcomp$ego[1]
# 2. dyad-level
var2 <- varcomp$"ego:alterid"[1]
# 3. latent variable method: substitute the constant quantity π^2/3 for the level-1 variance.
var1 <- (pi^2)/3

# vpc3 <- var3/(var1+var2+var3) vpc2 <- (var2 + var3)/(var1+var2+var3) 1 - vpc2

# perform likelihood ratio test for differences in models
lrtest(model01, model02, model03, model0)


ties nested in alters/dyads

  • M0 : null (empty) model including random intercepts for ego and ego:alter
  • M1 : tie + period
  • M2 : tie + period + dissimilarity
  • M3 : tie + period + dissimilarity + controls
  • M4 : tie + period + dissimilarity + controls + closeness + multiplexity
  • M5 : tie + period + dissimilarity + controls + structural1 + structural2
  • M6 : tie + period + dissimilarity + controls + closeness + multiplexity + structural1 + structural2
  • M7 : tie + period + dissimilarity + controls + closeness + multiplexity + structural1 + structural2 + dissimilarity:tie
  • M8 : tie + period + dissimilarity + controls + closeness:tie + multiplexity:tie + structural1:tie + structural2:tie
#list of models
formula <- list(
  
  #0. null model
  Y ~ 1 + (1 | ego) + (1 | ego:alterid),
  
  #1 incl. fixed effects of role and time)
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + period,
  
  #2. dissimilarity
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period,

  #3. controls
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size),
  
  #4. relational embeddedness as mediator
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t,
  
  #5. str. embeddedness as mediator
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + scale(embed) + scale(embed.ext),

  #6. both relational and structural
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
  
  #7. interaction dissimilarity * tie type
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext) + different_gender:tie + different_educ:tie + scale(dif_age):tie,
  
  #8. interaction mediators * tie type
  Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext)  + closeness.t:tie + multiplex:tie + scale(embed):tie + scale(embed.ext):tie
)

#estimate using `ffit`
ans <- lapply(formula, ffit, data = df)

#use likelihood ratio test to compare models
do.call(lrtest, ans)

#summary(ans[[3]])

#save output
save(ans, file="./results/ans_all.RData")
Results of random effects models predicting tie dissolution at t+1 (1=yes, 0=no)
  M0 M1 M2 M3 M4 M5 M6 M7 M8
(Intercept) -0.21 (0.04)*** -0.71 (0.08)*** -0.67 (0.08)*** 0.21 (0.19) 2.33 (0.24)*** 0.16 (0.19) 2.28 (0.24)*** 2.38 (0.25)*** 4.92 (0.46)***
Best friend   -0.24 (0.08)** -0.22 (0.08)** -0.25 (0.08)** -0.34 (0.08)*** -0.26 (0.08)*** -0.32 (0.08)*** -0.50 (0.11)*** -1.90 (0.49)***
Sports partner   1.30 (0.09)*** 1.27 (0.09)*** 1.38 (0.10)*** 1.00 (0.10)*** 1.36 (0.10)*** 1.05 (0.10)*** 1.11 (0.13)*** -2.18 (0.50)***
Study partner   1.52 (0.09)*** 1.50 (0.09)*** 1.51 (0.10)*** 1.05 (0.10)*** 1.52 (0.10)*** 1.15 (0.10)*** 1.03 (0.13)*** -2.24 (0.49)***
Period: wave 2 -> wave 3   0.04 (0.07) -0.05 (0.07) 0.03 (0.08) 0.06 (0.08) 0.01 (0.08) 0.05 (0.08) 0.06 (0.08) 0.04 (0.08)
Different gender     -0.20 (0.08)* -0.13 (0.10) -0.03 (0.09) -0.15 (0.10) -0.04 (0.09) -0.54 (0.15)*** -0.06 (0.09)
Different education     0.08 (0.08) -0.19 (0.09)* -0.16 (0.09) -0.16 (0.09) -0.15 (0.09) 0.02 (0.14) -0.14 (0.09)
Age difference     0.20 (0.04)*** 0.17 (0.05)*** 0.13 (0.04)** 0.16 (0.04)*** 0.13 (0.04)** 0.17 (0.06)** 0.10 (0.04)*
Research university student       -0.33 (0.11)** -0.15 (0.10) -0.30 (0.10)** -0.16 (0.10) -0.16 (0.10) -0.18 (0.10)
Second year student       -0.37 (0.14)** -0.37 (0.13)** -0.37 (0.13)** -0.38 (0.13)** -0.37 (0.13)** -0.36 (0.13)**
Third year or higher       -0.37 (0.11)*** -0.36 (0.11)*** -0.38 (0.11)*** -0.37 (0.11)*** -0.36 (0.11)*** -0.35 (0.11)***
Age       -0.13 (0.05)** -0.16 (0.05)*** -0.14 (0.05)** -0.17 (0.05)*** -0.16 (0.05)*** -0.14 (0.05)**
Female       -0.18 (0.11) -0.12 (0.11) -0.21 (0.11) -0.14 (0.11) -0.15 (0.11) -0.09 (0.11)
Extraversion       0.05 (0.04) 0.12 (0.04)** 0.06 (0.04) 0.12 (0.04)** 0.12 (0.04)** 0.13 (0.04)**
Financial restrictions       -0.04 (0.04) -0.02 (0.04) -0.02 (0.04) -0.02 (0.04) -0.02 (0.04) -0.01 (0.04)
Romantic relationship       -0.20 (0.09)* -0.17 (0.08)* -0.19 (0.08)* -0.17 (0.08)* -0.15 (0.08) -0.18 (0.08)*
Housing transition       0.30 (0.13)* 0.29 (0.12)* 0.30 (0.12)* 0.29 (0.12)* 0.30 (0.12)* 0.29 (0.12)*
Study transition       0.18 (0.16) 0.07 (0.15) 0.19 (0.16) 0.08 (0.15) 0.08 (0.16) 0.08 (0.15)
Female       0.09 (0.10) 0.08 (0.09) 0.06 (0.10) 0.07 (0.09) 0.08 (0.10) 0.03 (0.09)
Education       -0.14 (0.04)** -0.12 (0.04)** -0.12 (0.04)** -0.12 (0.04)** -0.10 (0.04)* -0.12 (0.04)**
Age       0.04 (0.05) 0.01 (0.04) 0.02 (0.05) 0.00 (0.04) -0.01 (0.05) -0.02 (0.04)
Years known       -0.14 (0.04)*** -0.01 (0.04) -0.12 (0.04)** -0.01 (0.04) -0.01 (0.04) -0.06 (0.04)
Same municipality       -0.21 (0.08)* -0.13 (0.08) -0.14 (0.08) -0.12 (0.08) -0.13 (0.08) -0.11 (0.08)
Same house       -0.66 (0.14)*** -0.27 (0.13)* -0.55 (0.14)*** -0.26 (0.13)* -0.28 (0.13)* -0.29 (0.13)*
Network size       0.16 (0.03)*** 0.11 (0.03)** 0.17 (0.03)*** 0.13 (0.03)*** 0.12 (0.03)*** 0.15 (0.04)***
Multiplexity         -0.17 (0.04)***   -0.19 (0.05)*** -0.21 (0.05)*** -0.56 (0.11)***
Emotional closeness         -0.65 (0.05)***   -0.63 (0.05)*** -0.63 (0.05)*** -1.23 (0.12)***
Str. embeddedness focal layer           -0.16 (0.03)*** -0.14 (0.03)*** -0.13 (0.03)*** -0.07 (0.09)
Str. embeddedness other layers           -0.23 (0.04)*** 0.01 (0.05) 0.00 (0.05) 0.08 (0.08)
Different gender : Friendship               0.82 (0.18)***  
Different gender : Sports partner               0.46 (0.21)*  
Different gender : Study partner               0.56 (0.20)**  
Different education : Friendship               -0.05 (0.16)  
Different education : Sports partner               -0.45 (0.19)*  
Different education : Study partner               -0.13 (0.20)  
Age difference : Friendship               0.15 (0.08)  
Age difference : Sports partner               -0.27 (0.09)**  
Age difference : Study partner               -0.14 (0.10)  
Emotional closeness : Friendship                 0.32 (0.14)*
Emotional closeness : Sports partner                 0.71 (0.15)***
Emotional closeness : Study partner                 0.84 (0.15)***
Multiplexity : Friendship                 0.24 (0.13)
Multiplexity : Sports partner                 0.59 (0.15)***
Multiplexity : Study partner                 0.48 (0.14)***
Str. embeddedness focal layer : Friendship                 0.06 (0.10)
Str. embeddedness focal layer : Sports partner                 -0.03 (0.11)
Str. embeddedness focal layer : Study partner                 -0.27 (0.11)*
Str. embeddedness other layers : Friendship                 -0.17 (0.11)
Str. embeddedness other layers : Sports partner                 -0.10 (0.12)
Str. embeddedness other layers : Study partner                 0.06 (0.12)
AIC 10434.53 9781.14 9746.31 9647.03 9368.72 9586.24 9353.54 9313.62 9229.13
BIC 10455.47 9829.99 9816.09 9835.42 9571.07 9788.59 9569.85 9592.72 9529.17
Log Likelihood -5214.27 -4883.57 -4863.16 -4796.51 -4655.36 -4764.12 -4645.77 -4616.81 -4571.57
Num. obs. 7924 7924 7924 7924 7924 7924 7924 7924 7924
Num. groups: ego:alterid 3905 3905 3905 3905 3905 3905 3905 3905 3905
Num. groups: ego 514 514 514 514 514 514 514 514 514
Var: ego:alterid (Intercept) 1.13 1.40 1.29 1.18 0.77 1.04 0.77 0.78 0.71
Var: ego (Intercept) 0.29 0.36 0.34 0.26 0.26 0.26 0.27 0.27 0.26
***p < 0.001; **p < 0.01; *p < 0.05


seperate analyses by tie type

Here, we drop the random alter-intercept.

#1. seperate dataframes for each tie type
dfconfidant <- df[df$tie=="Confidant",]
dffriend <- df[df$tie=="Friend",]
dfsport <- df[df$tie=="Sport",]
dfstudy <- df[df$tie=="Study",]

#2. new list of formulas
#here, exclude the random alter-intercept (as no nestig of ties in alters/dyads)
#fewer models, since we dont include tie-level relational role as an (interaction) variable

formula2 <- list(
  #0. main variables
  Y ~ 1 + (1 | ego) + different_gender + different_educ + scale(dif_age) + period,

  #1. controls
  Y ~ 1 + (1 | ego) + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size),
  
  #2. relational embeddedness as mediator
  Y ~ 1 + (1 | ego) + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t,
  
  #3. str. embeddedness as mediator
  Y ~ 1 + (1 | ego) + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + scale(embed) + scale(embed.ext),

  #4. both relational and structural
  Y ~ 1 + (1 | ego) + different_gender + different_educ + scale(dif_age) + period + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext)
  )

#3. estimate
ansconfidant <- lapply(formula2, ffit, data = dfconfidant)
ansfriend <- lapply(formula2, ffit, data = dffriend)
anssport <- lapply(formula2, ffit, data = dfsport)
ansstudy <- lapply(formula2, ffit, data = dfstudy)

#list output
ans_seperate <- list(ansconfidant,ansfriend,anssport,ansstudy)

#save listed output
save(ans_seperate, file="./results/ans_separate_list.RData")
Results of random effects models predicting confidant tie dissolution at t+1 (1=yes, 0=no)
  M0 M1 M2 M3 M4
(Intercept) -0.66 (0.09)*** 0.56 (0.27)* 4.72 (0.49)*** 0.53 (0.27) 4.73 (0.49)***
Different gender -0.58 (0.12)*** -0.38 (0.15)** -0.42 (0.16)** -0.48 (0.15)** -0.42 (0.16)**
Different education 0.26 (0.11)* -0.09 (0.14) -0.08 (0.15) -0.08 (0.15) -0.08 (0.15)
Age difference 0.31 (0.06)*** 0.34 (0.08)*** 0.17 (0.09) 0.33 (0.08)*** 0.17 (0.09)
Period: wave 2 -> wave 3 -0.16 (0.11) -0.11 (0.12) -0.06 (0.13) -0.11 (0.12) -0.06 (0.13)
Research university student   -0.50 (0.15)*** -0.35 (0.16)* -0.46 (0.15)** -0.36 (0.16)*
Second year student   -0.27 (0.18) -0.18 (0.19) -0.27 (0.19) -0.19 (0.20)
Third year or higher   -0.27 (0.15) -0.21 (0.16) -0.26 (0.15) -0.21 (0.16)
Age   -0.07 (0.07) -0.14 (0.07)* -0.10 (0.07) -0.14 (0.07)
Female   -0.58 (0.15)*** -0.47 (0.16)** -0.62 (0.15)*** -0.47 (0.16)**
Extraversion   0.06 (0.06) 0.12 (0.06) 0.06 (0.06) 0.12 (0.06)
Financial restrictions   0.01 (0.06) 0.03 (0.06) 0.02 (0.06) 0.04 (0.06)
Romantic relationship   -0.26 (0.12)* -0.21 (0.12) -0.26 (0.12)* -0.21 (0.12)
Housing transition   0.40 (0.19)* 0.48 (0.20)* 0.40 (0.19)* 0.48 (0.20)*
Study transition   0.39 (0.24) 0.29 (0.26) 0.40 (0.25) 0.28 (0.26)
Female   0.16 (0.14) 0.01 (0.15) 0.12 (0.15) 0.01 (0.15)
Education   -0.09 (0.07) -0.09 (0.07) -0.09 (0.07) -0.09 (0.07)
Age   -0.08 (0.08) -0.17 (0.09) -0.11 (0.08) -0.17 (0.09)
Years known   -0.12 (0.06)* -0.02 (0.06) -0.12 (0.06)* -0.02 (0.06)
Same municipality   -0.17 (0.12) -0.04 (0.13) -0.09 (0.12) -0.04 (0.13)
Same house   -0.68 (0.19)*** -0.45 (0.20)* -0.63 (0.19)** -0.45 (0.20)*
Network size   0.32 (0.06)*** 0.30 (0.07)*** 0.32 (0.06)*** 0.30 (0.07)***
Multiplexity     -0.58 (0.08)***   -0.60 (0.10)***
Emotional closeness     -1.04 (0.11)***   -1.03 (0.11)***
Str. embeddedness focal layer       0.00 (0.06) -0.03 (0.07)
Str. embeddedness other layers       -0.31 (0.07)*** 0.02 (0.08)
AIC 2251.28 2176.70 1976.42 2154.00 1980.20
BIC 2284.40 2303.64 2114.40 2291.98 2129.22
Log Likelihood -1119.64 -1065.35 -963.21 -1052.00 -963.10
Num. obs. 1843 1843 1843 1843 1843
Num. groups: ego 490 490 490 490 490
Var: ego (Intercept) 0.16 0.05 0.05 0.08 0.05
***p < 0.001; **p < 0.01; *p < 0.05
Results of random effects models predicting friendship dissolution at t+1 (1=yes, 0=no)
  M0 M1 M2 M3 M4
(Intercept) -0.88 (0.07)*** -0.12 (0.21) 2.42 (0.34)*** -0.23 (0.21) 2.38 (0.34)***
Different gender 0.15 (0.10) 0.01 (0.13) 0.08 (0.13) 0.04 (0.13) 0.08 (0.13)
Different education 0.22 (0.09)* 0.07 (0.11) 0.10 (0.12) 0.07 (0.11) 0.10 (0.12)
Age difference 0.23 (0.04)*** 0.15 (0.05)** 0.18 (0.05)** 0.16 (0.05)** 0.18 (0.05)***
Period: wave 2 -> wave 3 -0.28 (0.09)** -0.28 (0.10)** -0.15 (0.11) -0.27 (0.10)** -0.15 (0.11)
Research university student   -0.38 (0.12)** -0.17 (0.13) -0.34 (0.12)** -0.17 (0.13)
Second year student   -0.29 (0.15) -0.37 (0.16)* -0.32 (0.15)* -0.37 (0.16)*
Third year or higher   -0.41 (0.12)*** -0.44 (0.13)*** -0.42 (0.12)*** -0.44 (0.13)**
Age   -0.00 (0.06) -0.06 (0.07) -0.01 (0.06) -0.06 (0.07)
Female   0.12 (0.13) 0.21 (0.15) 0.12 (0.14) 0.22 (0.15)
Extraversion   -0.05 (0.05) 0.05 (0.05) -0.02 (0.05) 0.05 (0.05)
Financial restrictions   -0.06 (0.05) -0.04 (0.05) -0.03 (0.05) -0.03 (0.05)
Romantic relationship   -0.05 (0.10) -0.10 (0.10) -0.07 (0.10) -0.10 (0.10)
Housing transition   0.32 (0.14)* 0.27 (0.15) 0.28 (0.15) 0.27 (0.15)
Study transition   -0.01 (0.19) -0.13 (0.21) -0.03 (0.20) -0.14 (0.21)
Female   -0.17 (0.13) -0.19 (0.13) -0.18 (0.13) -0.19 (0.13)
Education   -0.04 (0.05) -0.01 (0.06) -0.03 (0.05) -0.01 (0.06)
Age   -0.02 (0.06) -0.01 (0.06) -0.01 (0.06) -0.00 (0.06)
Years known   -0.23 (0.05)*** -0.27 (0.05)*** -0.29 (0.05)*** -0.28 (0.05)***
Same municipality   -0.06 (0.09) 0.08 (0.10) 0.01 (0.10) 0.07 (0.10)
Same house   -0.54 (0.17)** -0.12 (0.19) -0.42 (0.18)* -0.13 (0.19)
Network size   0.14 (0.05)** 0.13 (0.05)** 0.14 (0.05)** 0.14 (0.05)**
Multiplexity     -0.51 (0.06)***   -0.44 (0.08)***
Emotional closeness     -0.72 (0.08)***   -0.73 (0.08)***
Str. embeddedness focal layer       0.11 (0.05)* 0.04 (0.05)
Str. embeddedness other layers       -0.44 (0.05)*** -0.09 (0.07)
AIC 3623.35 3577.74 3350.99 3508.99 3353.09
BIC 3659.35 3715.74 3500.99 3659.00 3515.09
Log Likelihood -1805.68 -1765.87 -1650.49 -1729.50 -1649.54
Num. obs. 2981 2981 2981 2981 2981
Num. groups: ego 507 507 507 507 507
Var: ego (Intercept) 0.24 0.18 0.27 0.19 0.28
***p < 0.001; **p < 0.01; *p < 0.05
Results of random effects models predicting sports partnership dissolution at t+1 (1=yes, 0=no)
  M0 M1 M2 M3 M4
(Intercept) 0.52 (0.10)*** 1.51 (0.31)*** 3.03 (0.41)*** 1.54 (0.31)*** 3.01 (0.41)***
Different gender -0.26 (0.13)* -0.08 (0.17) 0.07 (0.18) -0.09 (0.17) 0.05 (0.18)
Different education 0.04 (0.12) -0.35 (0.15)* -0.40 (0.15)** -0.35 (0.15)* -0.40 (0.15)**
Age difference 0.07 (0.06) -0.02 (0.07) -0.05 (0.07) -0.03 (0.07) -0.06 (0.07)
Period: wave 2 -> wave 3 -0.48 (0.12)*** -0.45 (0.14)** -0.37 (0.15)* -0.42 (0.14)** -0.37 (0.15)*
Research university student   -0.30 (0.16) -0.19 (0.17) -0.26 (0.17) -0.20 (0.17)
Second year student   -0.21 (0.22) -0.19 (0.23) -0.22 (0.22) -0.18 (0.23)
Third year or higher   -0.41 (0.17)* -0.39 (0.18)* -0.43 (0.17)* -0.39 (0.18)*
Age   -0.04 (0.08) -0.08 (0.08) -0.05 (0.08) -0.08 (0.08)
Female   0.11 (0.18) 0.10 (0.19) 0.08 (0.18) 0.09 (0.19)
Extraversion   0.11 (0.06) 0.16 (0.07)* 0.12 (0.06) 0.15 (0.07)*
Financial restrictions   -0.13 (0.06)* -0.13 (0.07)* -0.13 (0.06)* -0.13 (0.07)*
Romantic relationship   -0.25 (0.13) -0.18 (0.13) -0.24 (0.13) -0.18 (0.13)
Housing transition   0.31 (0.24) 0.31 (0.25) 0.30 (0.24) 0.30 (0.25)
Study transition   0.21 (0.29) -0.03 (0.30) 0.13 (0.29) -0.03 (0.30)
Female   0.18 (0.17) 0.22 (0.18) 0.16 (0.17) 0.20 (0.18)
Education   -0.16 (0.07)* -0.15 (0.08)* -0.15 (0.07)* -0.15 (0.08)*
Age   0.07 (0.07) 0.05 (0.07) 0.05 (0.07) 0.05 (0.07)
Years known   -0.07 (0.06) 0.07 (0.07) -0.03 (0.06) 0.07 (0.07)
Same municipality   -0.55 (0.17)** -0.56 (0.18)** -0.57 (0.17)*** -0.56 (0.18)**
Same house   -0.87 (0.23)*** -0.70 (0.23)** -0.87 (0.23)*** -0.72 (0.23)**
Network size   0.22 (0.06)*** 0.15 (0.07)* 0.21 (0.07)** 0.18 (0.07)**
Multiplexity     -0.09 (0.08)   -0.09 (0.10)
Emotional closeness     -0.52 (0.10)***   -0.50 (0.10)***
Str. embeddedness focal layer       -0.08 (0.06) -0.09 (0.07)
Str. embeddedness other layers       -0.23 (0.06)*** -0.01 (0.09)
AIC 2006.44 1970.79 1911.79 1956.32 1913.67
BIC 2038.25 2092.75 2044.35 2088.89 2056.84
Log Likelihood -997.22 -962.40 -930.90 -953.16 -929.83
Num. obs. 1484 1484 1484 1484 1484
Num. groups: ego 420 420 420 420 420
Var: ego (Intercept) 0.31 0.24 0.27 0.24 0.26
***p < 0.001; **p < 0.01; *p < 0.05
Results of random effects models predicting study partnership dissolution at t+1 (1=yes, 0=no)
  M0 M1 M2 M3 M4
(Intercept) 0.64 (0.11)*** 1.25 (0.37)*** 2.45 (0.45)*** 1.23 (0.38)** 2.38 (0.45)***
Different gender -0.15 (0.14) -0.18 (0.18) -0.18 (0.19) -0.20 (0.18) -0.19 (0.19)
Different education 0.17 (0.17) 0.06 (0.22) 0.11 (0.24) 0.10 (0.23) 0.11 (0.23)
Age difference 0.09 (0.07) 0.10 (0.09) 0.13 (0.10) 0.10 (0.10) 0.13 (0.10)
Period: wave 2 -> wave 3 -0.05 (0.14) 0.22 (0.16) 0.49 (0.18)** 0.29 (0.17) 0.47 (0.18)**
Research university student   -0.05 (0.23) 0.34 (0.25) 0.08 (0.24) 0.33 (0.25)
Second year student   -0.33 (0.26) -0.49 (0.28) -0.39 (0.26) -0.49 (0.27)
Third year or higher   -0.06 (0.22) -0.13 (0.23) -0.13 (0.22) -0.14 (0.23)
Age   -0.07 (0.11) -0.17 (0.12) -0.10 (0.11) -0.18 (0.12)
Female   -0.31 (0.22) -0.30 (0.23) -0.36 (0.22) -0.31 (0.23)
Extraversion   -0.00 (0.08) 0.06 (0.09) 0.03 (0.08) 0.08 (0.09)
Financial restrictions   0.10 (0.08) 0.10 (0.09) 0.11 (0.08) 0.10 (0.08)
Romantic relationship   -0.20 (0.17) -0.20 (0.18) -0.20 (0.17) -0.20 (0.17)
Housing transition   0.19 (0.27) 0.18 (0.29) 0.18 (0.27) 0.20 (0.28)
Study transition   0.93 (0.37)* 0.84 (0.39)* 0.85 (0.38)* 0.76 (0.39)
Female   -0.02 (0.18) -0.01 (0.19) -0.07 (0.19) -0.04 (0.19)
Education   -0.13 (0.09) -0.13 (0.10) -0.13 (0.09) -0.14 (0.10)
Age   0.13 (0.08) 0.10 (0.09) 0.10 (0.08) 0.08 (0.09)
Years known   0.10 (0.07) 0.24 (0.08)** 0.14 (0.07) 0.23 (0.08)**
Same municipality   -0.27 (0.15) -0.17 (0.16) -0.23 (0.16) -0.17 (0.16)
Same house   -0.51 (0.31) 0.07 (0.33) -0.37 (0.32) 0.02 (0.33)
Network size   0.04 (0.07) -0.01 (0.08) 0.09 (0.08) 0.04 (0.08)
Multiplexity     -0.22 (0.09)*   -0.25 (0.11)*
Emotional closeness     -0.49 (0.10)***   -0.44 (0.10)***
Str. embeddedness focal layer       -0.27 (0.07)*** -0.28 (0.08)***
Str. embeddedness other layers       -0.25 (0.07)*** 0.05 (0.09)
AIC 2082.42 2082.13 2019.86 2053.76 2010.72
BIC 2114.74 2206.04 2154.55 2188.45 2156.19
Log Likelihood -1035.21 -1018.06 -984.93 -1001.88 -978.36
Num. obs. 1616 1616 1616 1616 1616
Num. groups: ego 424 424 424 424 424
Var: ego (Intercept) 0.97 1.05 1.24 1.03 1.14
***p < 0.001; **p < 0.01; *p < 0.05



Average marginal effects

For more information on the (numerical) approach to computing AMEs, see https://www.jochemtolsma.nl/tutorials/me/.


define data-sets

# A. data-sets for mediation analyses
dfgender1 <- dfgender0 <- df
dfageplus <- dfagemin <- df
dfeduc1 <- dfeduc0 <- df

dfgender1$different_gender <- 1
dfgender0$different_gender <- 0
dfeduc1$different_educ <- 1
dfeduc0$different_educ <- 0

# define small step for continuous variable
s <- 0.001
dfageplus$dif_age <- df$dif_age + s
dfagemin$dif_age <- df$dif_age - s

# B data-sets for interaction dissimilarity * tie type
dfgenderfriend00 <- dfgenderfriend01 <- dfgenderfriend10 <- dfgenderfriend11 <- df
dfgenderfriend00$different_gender <- 0
dfgenderfriend01$different_gender <- 0
dfgenderfriend10$different_gender <- 1
dfgenderfriend11$different_gender <- 1
dfgenderfriend00$tie <- "Confidant"
dfgenderfriend01$tie <- "Friend"
dfgenderfriend10$tie <- "Confidant"
dfgenderfriend11$tie <- "Friend"

dfeducfriend00 <- dfeducfriend01 <- dfeducfriend10 <- dfeducfriend11 <- df
dfeducfriend00$different_educ <- 0
dfeducfriend01$different_educ <- 0
dfeducfriend10$different_educ <- 1
dfeducfriend11$different_educ <- 1
dfeducfriend00$tie <- "Confidant"
dfeducfriend01$tie <- "Friend"
dfeducfriend10$tie <- "Confidant"
dfeducfriend11$tie <- "Friend"

dfagefriendmin0 <- dfagefriendmin1 <- dfagefriendplus0 <- dfagefriendplus1 <- df
dfagefriendmin0$dif_age <- df$dif_age - s
dfagefriendmin1$dif_age <- df$dif_age - s
dfagefriendplus0$dif_age <- df$dif_age + s
dfagefriendplus1$dif_age <- df$dif_age + s
dfagefriendmin0$tie <- "Confidant"
dfagefriendmin1$tie <- "Friend"
dfagefriendplus0$tie <- "Confidant"
dfagefriendplus1$tie <- "Friend"

dfgendersport00 <- dfgendersport01 <- dfgendersport10 <- dfgendersport11 <- df
dfgendersport00$different_gender <- 0
dfgendersport01$different_gender <- 0
dfgendersport10$different_gender <- 1
dfgendersport11$different_gender <- 1
dfgendersport00$tie <- "Confidant"
dfgendersport01$tie <- "Sport"
dfgendersport10$tie <- "Confidant"
dfgendersport11$tie <- "Sport"

dfeducsport00 <- dfeducsport01 <- dfeducsport10 <- dfeducsport11 <- df
dfeducsport00$different_educ <- 0
dfeducsport01$different_educ <- 0
dfeducsport10$different_educ <- 1
dfeducsport11$different_educ <- 1
dfeducsport00$tie <- "Confidant"
dfeducsport01$tie <- "Sport"
dfeducsport10$tie <- "Confidant"
dfeducsport11$tie <- "Sport"

dfagesportmin0 <- dfagesportmin1 <- dfagesportplus0 <- dfagesportplus1 <- df
dfagesportmin0$dif_age <- df$dif_age - s
dfagesportmin1$dif_age <- df$dif_age - s
dfagesportplus0$dif_age <- df$dif_age + s
dfagesportplus1$dif_age <- df$dif_age + s
dfagesportmin0$tie <- "Confidant"
dfagesportmin1$tie <- "Sport"
dfagesportplus0$tie <- "Confidant"
dfagesportplus1$tie <- "Sport"

dfgenderstudy00 <- dfgenderstudy01 <- dfgenderstudy10 <- dfgenderstudy11 <- df
dfgenderstudy00$different_gender <- 0
dfgenderstudy01$different_gender <- 0
dfgenderstudy10$different_gender <- 1
dfgenderstudy11$different_gender <- 1
dfgenderstudy00$tie <- "Confidant"
dfgenderstudy01$tie <- "Study"
dfgenderstudy10$tie <- "Confidant"
dfgenderstudy11$tie <- "Study"

dfeducstudy00 <- dfeducstudy01 <- dfeducstudy10 <- dfeducstudy11 <- df
dfeducstudy00$different_educ <- 0
dfeducstudy01$different_educ <- 0
dfeducstudy10$different_educ <- 1
dfeducstudy11$different_educ <- 1
dfeducstudy00$tie <- "Confidant"
dfeducstudy01$tie <- "Study"
dfeducstudy10$tie <- "Confidant"
dfeducstudy11$tie <- "Study"

dfagestudymin0 <- dfagestudymin1 <- dfagestudyplus0 <- dfagestudyplus1 <- df
dfagestudymin0$dif_age <- df$dif_age - s
dfagestudymin1$dif_age <- df$dif_age - s
dfagestudyplus0$dif_age <- df$dif_age + s
dfagestudyplus1$dif_age <- df$dif_age + s
dfagestudymin0$tie <- "Confidant"
dfagestudymin1$tie <- "Study"
dfagestudyplus0$tie <- "Confidant"
dfagestudyplus1$tie <- "Study"

# C data-sets for interaction moderators * tie type
dfcloseplus <- dfclosemin <- df
dfcloseplus$closeness.t <- df$closeness.t + s
dfclosemin$closeness.t <- df$closeness.t - s

dfmultiplus <- dfmultimin <- df
dfmultiplus$multiplex <- df$multiplex + s
dfmultimin$multiplex <- df$multiplex - s

dffembedplus <- dffembedmin <- df
dffembedplus$embed <- df$embed + s
dffembedmin$embed <- df$embed - s

dfoembedplus <- dfoembedmin <- df
dfoembedplus$embed.ext <- df$embed.ext + s
dfoembedmin$embed.ext <- df$embed.ext - s

# closeness * friend
dfclosefriendmin0 <- dfclosefriendmin1 <- dfclosefriendplus0 <- dfclosefriendplus1 <- df
dfclosefriendmin0$closeness.t <- df$closeness.t - s
dfclosefriendmin1$closeness.t <- df$closeness.t - s
dfclosefriendplus0$closeness.t <- df$closeness.t + s
dfclosefriendplus1$closeness.t <- df$closeness.t + s
dfclosefriendmin0$tie <- "Confidant"
dfclosefriendmin1$tie <- "Friend"
dfclosefriendplus0$tie <- "Confidant"
dfclosefriendplus1$tie <- "Friend"

# closeness * sport
dfclosesportmin0 <- dfclosesportmin1 <- dfclosesportplus0 <- dfclosesportplus1 <- df
dfclosesportmin0$closeness.t <- df$closeness.t - s
dfclosesportmin1$closeness.t <- df$closeness.t - s
dfclosesportplus0$closeness.t <- df$closeness.t + s
dfclosesportplus1$closeness.t <- df$closeness.t + s
dfclosesportmin0$tie <- "Confidant"
dfclosesportmin1$tie <- "Sport"
dfclosesportplus0$tie <- "Confidant"
dfclosesportplus1$tie <- "Sport"

# closeness * study
dfclosestudymin0 <- dfclosestudymin1 <- dfclosestudyplus0 <- dfclosestudyplus1 <- df
dfclosestudymin0$closeness.t <- df$closeness.t - s
dfclosestudymin1$closeness.t <- df$closeness.t - s
dfclosestudyplus0$closeness.t <- df$closeness.t + s
dfclosestudyplus1$closeness.t <- df$closeness.t + s
dfclosestudymin0$tie <- "Confidant"
dfclosestudymin1$tie <- "Study"
dfclosestudyplus0$tie <- "Confidant"
dfclosestudyplus1$tie <- "Study"

# multiplexity * friend
dfmultifriendmin0 <- dfmultifriendmin1 <- dfmultifriendplus0 <- dfmultifriendplus1 <- df
dfmultifriendmin0$multiplex <- df$multiplex - s
dfmultifriendmin1$multiplex <- df$multiplex - s
dfmultifriendplus0$multiplex <- df$multiplex + s
dfmultifriendplus1$multiplex <- df$multiplex + s
dfmultifriendmin0$tie <- "Confidant"
dfmultifriendmin1$tie <- "Friend"
dfmultifriendplus0$tie <- "Confidant"
dfmultifriendplus1$tie <- "Friend"

# multiplexity * sport
dfmultisportmin0 <- dfmultisportmin1 <- dfmultisportplus0 <- dfmultisportplus1 <- df
dfmultisportmin0$multiplex <- df$multiplex - s
dfmultisportmin1$multiplex <- df$multiplex - s
dfmultisportplus0$multiplex <- df$multiplex + s
dfmultisportplus1$multiplex <- df$multiplex + s
dfmultisportmin0$tie <- "Confidant"
dfmultisportmin1$tie <- "Sport"
dfmultisportplus0$tie <- "Confidant"
dfmultisportplus1$tie <- "Sport"

# multiplexity * study
dfmultistudymin0 <- dfmultistudymin1 <- dfmultistudyplus0 <- dfmultistudyplus1 <- df
dfmultistudymin0$multiplex <- df$multiplex - s
dfmultistudymin1$multiplex <- df$multiplex - s
dfmultistudyplus0$multiplex <- df$multiplex + s
dfmultistudyplus1$multiplex <- df$multiplex + s
dfmultistudymin0$tie <- "Confidant"
dfmultistudymin1$tie <- "Study"
dfmultistudyplus0$tie <- "Confidant"
dfmultistudyplus1$tie <- "Study"

# structural embeddedness focal layer * friend
dffembedfriendmin0 <- dffembedfriendmin1 <- dffembedfriendplus0 <- dffembedfriendplus1 <- df
dffembedfriendmin0$embed <- df$embed - s
dffembedfriendmin1$embed <- df$embed - s
dffembedfriendplus0$embed <- df$embed + s
dffembedfriendplus1$embed <- df$embed + s
dffembedfriendmin0$tie <- "Confidant"
dffembedfriendmin1$tie <- "Friend"
dffembedfriendplus0$tie <- "Confidant"
dffembedfriendplus1$tie <- "Friend"

# structural embeddedness focal layer * sport
dffembedsportmin0 <- dffembedsportmin1 <- dffembedsportplus0 <- dffembedsportplus1 <- df
dffembedsportmin0$embed <- df$embed - s
dffembedsportmin1$embed <- df$embed - s
dffembedsportplus0$embed <- df$embed + s
dffembedsportplus1$embed <- df$embed + s
dffembedsportmin0$tie <- "Confidant"
dffembedsportmin1$tie <- "Sport"
dffembedsportplus0$tie <- "Confidant"
dffembedsportplus1$tie <- "Sport"

# structural embeddedness focal layer * study
dffembedstudymin0 <- dffembedstudymin1 <- dffembedstudyplus0 <- dffembedstudyplus1 <- df
dffembedstudymin0$embed <- df$embed - s
dffembedstudymin1$embed <- df$embed - s
dffembedstudyplus0$embed <- df$embed + s
dffembedstudyplus1$embed <- df$embed + s
dffembedstudymin0$tie <- "Confidant"
dffembedstudymin1$tie <- "Study"
dffembedstudyplus0$tie <- "Confidant"
dffembedstudyplus1$tie <- "Study"

# structural embeddedness other layers * friend
dfoembedfriendmin0 <- dfoembedfriendmin1 <- dfoembedfriendplus0 <- dfoembedfriendplus1 <- df
dfoembedfriendmin0$embed <- df$embed.ext - s
dfoembedfriendmin1$embed <- df$embed.ext - s
dfoembedfriendplus0$embed <- df$embed.ext + s
dfoembedfriendplus1$embed <- df$embed.ext + s
dfoembedfriendmin0$tie <- "Confidant"
dfoembedfriendmin1$tie <- "Friend"
dfoembedfriendplus0$tie <- "Confidant"
dfoembedfriendplus1$tie <- "Friend"

# structural embeddedness other layers * sport
dfoembedsportmin0 <- dfoembedsportmin1 <- dfoembedsportplus0 <- dfoembedsportplus1 <- df
dfoembedsportmin0$embed <- df$embed.ext - s
dfoembedsportmin1$embed <- df$embed.ext - s
dfoembedsportplus0$embed <- df$embed.ext + s
dfoembedsportplus1$embed <- df$embed.ext + s
dfoembedsportmin0$tie <- "Confidant"
dfoembedsportmin1$tie <- "Sport"
dfoembedsportplus0$tie <- "Confidant"
dfoembedsportplus1$tie <- "Sport"

# structural embeddedness other layers * study
dfoembedstudymin0 <- dfoembedstudymin1 <- dfoembedstudyplus0 <- dfoembedstudyplus1 <- df
dfoembedstudymin0$embed <- df$embed.ext - s
dfoembedstudymin1$embed <- df$embed.ext - s
dfoembedstudyplus0$embed <- df$embed.ext + s
dfoembedstudyplus1$embed <- df$embed.ext + s
dfoembedstudymin0$tie <- "Confidant"
dfoembedstudymin1$tie <- "Study"
dfoembedstudyplus0$tie <- "Confidant"
dfoembedstudyplus1$tie <- "Study"


get models

m3 <- ans[[4]]  #base
m4 <- ans[[5]]  #+mediator 1 (relational embeddedness)
m5 <- ans[[6]]  #+mediator 2 (structural embeddedness)
m6 <- ans[[7]]  #+both mediators
m7 <- ans[[8]]  #+interaction dissim * tie type
m8 <- ans[[9]]  #+interaction moderators* tie type


functions to calculate AME

make functions that calculates average marginal (interaction) effects over models

  • model 1: AMEs for dissimilarities
  • model 2: AMEs for dissimilarities, controlling for relational embeddedness (closeness + multiplexity)
  • model 3: AMEs for dissimilarities, controlling for structural embeddedness
  • model 4: AMEs for dissimilarities, controlling for both relational and structural and embeddedness
  • model 5: AMIEs for dissimilarities * tie type
  • model 6: AMIEs for mediators * tie type
# model 1: AMEs dissimilarities in base model
fpred1 <- function(m1) {
    me_gender <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfgender1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfageplus) - lme4:::predict.merMod(m1,
        type = "response", re.form = NULL, newdata = dfagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfeduc1) - lme4:::predict.merMod(m1,
        type = "response", re.form = NULL, newdata = dfeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# model 2: AMEs dissimilarities after including relational embeddedenss (closeness and
# multiplexity)
fpred2 <- function(m2) {
    me_gender <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfgender1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfageplus) - lme4:::predict.merMod(m2,
        type = "response", re.form = NULL, newdata = dfagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfeduc1) - lme4:::predict.merMod(m2,
        type = "response", re.form = NULL, newdata = dfeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# model 3: AMEs dissimilarities after including structural embeddedness
fpred3 <- function(m3) {
    me_gender <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfgender1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfageplus) - lme4:::predict.merMod(m3,
        type = "response", re.form = NULL, newdata = dfagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfeduc1) - lme4:::predict.merMod(m3,
        type = "response", re.form = NULL, newdata = dfeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# model 4: both mediators also get main effects for interaction analyses (m6)
fpred4 <- function(m4) {
    me_gender <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfgender1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfageplus) - lme4:::predict.merMod(m4,
        type = "response", re.form = NULL, newdata = dfagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfeduc1) - lme4:::predict.merMod(m4,
        type = "response", re.form = NULL, newdata = dfeduc0)
    ame_educ <- mean(me_educ)

    me_close <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfcloseplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfclosemin))/(2 * s)
    ame_close <- mean(me_close)

    me_multi <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfmultiplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfmultimin))/(2 * s)
    ame_multi <- mean(me_multi)

    me_fembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffembedmin))/(2 * s)
    ame_fembed <- mean(me_fembed)

    me_oembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfoembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfoembedmin))/(2 * s)
    ame_oembed <- mean(me_oembed)

    c(ame_gender, ame_age, ame_educ, ame_close, ame_multi, ame_fembed, ame_oembed)
}

# model 5: interaction dissimilarity * tie type:
fpred5 <- function(m5) {

    # different_gender (confidants = ref.)
    me_gender <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgender1) -
        lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgender0)
    ame_gender <- mean(me_gender)

    # * friend
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderfriend11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderfriend10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderfriend01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderfriend00)
    me_genderfriend <- (p11 - p01) - (p10 - p00)
    ame_genderfriend <- mean(me_genderfriend)

    # * sport
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgendersport11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgendersport10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgendersport01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgendersport00)
    me_gendersport <- (p11 - p01) - (p10 - p00)
    ame_gendersport <- mean(me_gendersport)

    # * study
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderstudy11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderstudy10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderstudy01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfgenderstudy00)
    me_genderstudy <- (p11 - p01) - (p10 - p00)
    ame_genderstudy <- mean(me_genderstudy)

    # age_difference (confidants = ref.)
    me_age <- (lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfageplus) - lme4:::predict.merMod(m5,
        type = "response", re.form = NULL, newdata = dfagemin))/(2 * s)
    ame_age <- mean(me_age)

    # * friend
    pplus1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagefriendplus1)
    pplus0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagefriendplus0)
    pmin1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagefriendmin1)
    pmin0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagefriendmin0)
    me_agefriend <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_agefriend <- mean(me_agefriend)

    # * sport
    pplus1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagesportplus1)
    pplus0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagesportplus0)
    pmin1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagesportmin1)
    pmin0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagesportmin0)
    me_agesport <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_agesport <- mean(me_agesport)

    # * study
    pplus1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagestudyplus1)
    pplus0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagestudyplus0)
    pmin1 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagestudymin1)
    pmin0 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfagestudymin0)
    me_agestudy <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_agestudy <- mean(me_agestudy)

    # different educ (confidant = ref)
    me_educ <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeduc1) - lme4:::predict.merMod(m5,
        type = "response", re.form = NULL, newdata = dfeduc0)
    ame_educ <- mean(me_educ)

    # * friend
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducfriend11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducfriend10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducfriend01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducfriend00)
    me_educfriend <- (p11 - p01) - (p10 - p00)
    ame_educfriend <- mean(me_educfriend)

    # * sport
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducsport11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducsport10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducsport01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducsport00)
    me_educsport <- (p11 - p01) - (p10 - p00)
    ame_educsport <- mean(me_educsport)

    # * study
    p11 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducstudy11)
    p10 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducstudy10)
    p01 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducstudy01)
    p00 <- lme4:::predict.merMod(m5, type = "response", re.form = NULL, newdata = dfeducstudy00)
    me_educstudy <- (p11 - p01) - (p10 - p00)
    ame_educstudy <- mean(me_educstudy)

    c(ame_gender, ame_genderfriend, ame_gendersport, ame_genderstudy, ame_age, ame_agefriend, ame_agesport,
        ame_agestudy, ame_educ, ame_educfriend, ame_educsport, ame_educstudy)
}

# model 6: interaction mediator * tie type:
fpred6 <- function(m6) {

    # closeness (confidant = ref)
    me_close <- (lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfcloseplus) -
        lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosemin))/(2 * s)
    ame_close <- mean(me_close)

    # * friend
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosefriendplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosefriendplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosefriendmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosefriendmin0)
    me_closefriend <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_closefriend <- mean(me_closefriend)

    # * sport
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosesportplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosesportplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosesportmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosesportmin0)
    me_closesport <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_closesport <- mean(me_closesport)

    # * study
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosestudyplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosestudyplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosestudymin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfclosestudymin0)
    me_closestudy <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_closestudy <- mean(me_closestudy)

    # multiplex (confidant = ref)
    me_multi <- (lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultiplus) -
        lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultimin))/(2 * s)
    ame_multi <- mean(me_multi)

    # * friend
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultifriendplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultifriendplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultifriendmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultifriendmin0)
    me_multifriend <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_multifriend <- mean(me_multifriend)

    # * sport
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultisportplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultisportplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultisportmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultisportmin0)
    me_multisport <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_multisport <- mean(me_multisport)

    # * study
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultistudyplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultistudyplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultistudymin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfmultistudymin0)
    me_multistudy <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_multistudy <- mean(me_multistudy)

    # focal str embededness (confidant = ref)
    me_fembed <- (lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedplus) -
        lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedmin))/(2 * s)
    ame_fembed <- mean(me_fembed)

    # * friend
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedfriendplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedfriendplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedfriendmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedfriendmin0)
    me_fembedfriend <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_fembedfriend <- mean(me_fembedfriend)

    # * sport
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedsportplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedsportplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedsportmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedsportmin0)
    me_fembedsport <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_fembedsport <- mean(me_fembedsport)

    # * study
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedstudyplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedstudyplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedstudymin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dffembedstudymin0)
    me_fembedstudy <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_fembedstudy <- mean(me_fembedstudy)

    # str embededness other layers (confidant = ref)
    me_oembed <- (lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedplus) -
        lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedmin))/(2 * s)
    ame_oembed <- mean(me_oembed)

    # * friend
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedfriendplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedfriendplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedfriendmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedfriendmin0)
    me_oembedfriend <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_oembedfriend <- mean(me_oembedfriend)

    # * sport
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedsportplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedsportplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedsportmin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedsportmin0)
    me_oembedsport <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_oembedsport <- mean(me_oembedsport)

    # * study
    pplus1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedstudyplus1)
    pplus0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedstudyplus0)
    pmin1 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedstudymin1)
    pmin0 <- lme4:::predict.merMod(m6, type = "response", re.form = NULL, newdata = dfoembedstudymin0)
    me_oembedstudy <- ((pplus1 - pmin1)/(2 * s)) - ((pplus0 - pmin0)/(2 * s))
    ame_oembedstudy <- mean(me_oembedstudy)

    c(ame_close, ame_closefriend, ame_closesport, ame_closestudy, ame_multi, ame_multifriend, ame_multisport,
        ame_multistudy, ame_fembed, ame_fembedfriend, ame_fembedsport, ame_fembedstudy, ame_oembed, ame_oembedfriend,
        ame_oembedsport, ame_oembedstudy)
}

# fpred1(m1) fpred4(m4) fpred5(m5) fpred6(m6)


bootstrapping

seed <- 2425323
nIter <- 500

nCore <- parallel::detectCores()

mycl <- makeCluster(rep("localhost", nCore))

clusterEvalQ(mycl, library(lme4))

clusterExport(mycl, varlist=c(
  "m3","m4", "m5", "m6", "m7", "m8", 
  #increment `s`
  "s",
  #datsets
  "dfgender0", "dfgender1", "dfeduc0", "dfeduc1","dfageplus","dfagemin",
  "dfgenderfriend11","dfgenderfriend10","dfgenderfriend01","dfgenderfriend00",
  "dfgendersport11","dfgendersport10","dfgendersport01","dfgendersport00",
  "dfgenderstudy11","dfgenderstudy10","dfgenderstudy01","dfgenderstudy00",
  "dfeducfriend11","dfeducfriend10","dfeducfriend01","dfeducfriend00",
  "dfeducsport11","dfeducsport10","dfeducsport01","dfeducsport00",
  "dfeducstudy11","dfeducstudy10","dfeducstudy01","dfeducstudy00",
  "dfagefriendmin0","dfagefriendmin1","dfagefriendplus0","dfagefriendplus1",
  "dfagesportmin0","dfagesportmin1","dfagesportplus0","dfagesportplus1",
  "dfagestudymin0","dfagestudymin1","dfagestudyplus0","dfagestudyplus1",
  "dfclosemin", "dfcloseplus", "dfmultimin", "dfmultiplus", "dffembedmin", "dffembedplus", "dfoembedmin", "dfoembedplus",
  "dfclosefriendplus1","dfclosefriendplus0","dfclosefriendmin1","dfclosefriendmin0",
  "dfclosesportplus1","dfclosesportplus0","dfclosesportmin1","dfclosesportmin0",
  "dfclosestudyplus1","dfclosestudyplus0","dfclosestudymin1","dfclosestudymin0",
   "dfmultifriendplus1","dfmultifriendplus0","dfmultifriendmin1","dfmultifriendmin0",
  "dfmultisportplus1","dfmultisportplus0","dfmultisportmin1","dfmultisportmin0",
  "dfmultistudyplus1","dfmultistudyplus0","dfmultistudymin1","dfmultistudymin0",
    "dffembedfriendplus1","dffembedfriendplus0","dffembedfriendmin1","dffembedfriendmin0",
  "dffembedsportplus1","dffembedsportplus0","dffembedsportmin1","dffembedsportmin0",
  "dffembedstudyplus1","dffembedstudyplus0","dffembedstudymin1","dffembedstudymin0",
  "dfoembedfriendplus1","dfoembedfriendplus0","dfoembedfriendmin1","dfoembedfriendmin0",
  "dfoembedsportplus1","dfoembedsportplus0","dfoembedsportmin1","dfoembedsportmin0",
  "dfoembedstudyplus1","dfoembedstudyplus0","dfoembedstudymin1","dfoembedstudymin0"))

{
system.time (boo_m1 <- bootMer(m1, fpred1, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
system.time (boo_m2 <- bootMer(m2, fpred2, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
system.time (boo_m3 <- bootMer(m3, fpred3, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
system.time (boo_m4 <- bootMer(m4, fpred4, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
system.time (boo_m5 <- bootMer(m5, fpred5, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
system.time (boo_m6 <- bootMer(m6, fpred6, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl, seed = seed))
}

booL <- list(boo_m1,boo_m2,boo_m3,boo_m4,boo_m5,boo_m6) 
save(booL, file = "./boot.Rda")

stopCluster(mycl)


AME / AMME

nIter = 500
load("./results/boot.rda")

plotdata <- data.frame(pred = rep(c("Different\ngender", "Age\ndifference", "Different\neducation"),
    4), model = rep(c("M3", "M4", "M5", "M6"), each = 3), ame = c(booL[[1]]$t0, booL[[2]]$t0, booL[[3]]$t0,
    booL[[4]]$t0[1:3]), ame_se = c(apply(booL[[1]]$t, 2, sd), apply(booL[[2]]$t, 2, sd), apply(booL[[3]]$t,
    2, sd), apply(booL[[4]]$t, 2, sd)[1:3]))

# also calculate average estimated AME over bootstraps
plotdata$ame_b <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for model get estimated AMEs of dissimilarity i of model j
    for (j in c(1:4)) {
        amesb <- booL[[j]]$t[, i]
        # and calculate mean
        plotdata$ame_b[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(amesb)
    }
}

# calculate average marginal mediation effects
plotdata$amme <- NA
plotdata$amme_se <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for extended model get AMEs of dissimilarity i of baseline model
    for (j in c(2:4)) {
        ame_i_base <- booL[[1]]$t[, i]
        # get AMEs of dissimilarity i of extended model j
        ame_i_modelj <- booL[[j]]$t[, i]
        # calculate cross-model AME difference per bootstrap iteration
        cm_ame_difs <- ame_i_base - ame_i_modelj
        # calculate average marginal mediation effect by taking the average
        plotdata$amme[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(cm_ame_difs)
        # and SE
        plotdata$amme_se[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- sd(cm_ame_difs)/sqrt(nIter)
    }
}

# variables to class factor, reorder:
plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation"))
plotdata$model <- factor(plotdata$model, levels = rev(c("M3", "M4", "M5", "M6")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)
fshowdf(plotdata, digits = 3)
pred model ame ame_se ame_b amme amme_se
Different gender M3 -0.024 0.018 -0.024 NA NA
Different gender M4 -0.006 0.016 -0.006 -0.017 0.001
Different gender M5 -0.028 0.018 -0.028 0.004 0.000
Different gender M6 -0.008 0.017 -0.009 -0.015 0.001
Age difference M3 0.014 0.004 0.014 NA NA
Age difference M4 0.011 0.004 0.011 0.003 0.000
Age difference M5 0.013 0.004 0.013 0.001 0.000
Age difference M6 0.010 0.003 0.011 0.003 0.000
Different education M3 -0.035 0.018 -0.036 NA NA
Different education M4 -0.030 0.017 -0.031 -0.005 0.001
Different education M5 -0.030 0.017 -0.031 -0.006 0.000
Different education M6 -0.028 0.016 -0.028 -0.008 0.001
#plot 1: AMEs

plotdata2 <- data.frame(
  pred = c("Different\ngender","Age\ndifference", "Different\neducation"),
  model = "M4-M6",
  ame = NA, ame_se = NA, amme = NA, amme_se = NA)

  
bind_rows(plotdata, plotdata2) -> plotdata1
plotdata1$model <- factor(plotdata1$model, levels = rev(c("M3", "M4", "M5", "M6", "M4-M6")))
plotdata1$pred <- factor(plotdata1$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation"))

plot1 <- ggplot(plotdata1, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.075, 0.05)) + #x-axis to %-point, and set range
  
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
  scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3"))

#plot 2: AMMEs

# relational and structural embeddedness influence each other. i want to also test whether structural embeddedness has an *additional* role in explaining the faster tie loss of dissimilar others, above and beyond relational embeddedness
#thus i calculate the ame change when comparing the model including only relational embeddedness (m2) and both embeddedness type (m4)

plotdata2 <- data.frame(
  pred = c("Different\ngender","Age\ndifference", "Different\neducation"),
  model = "M4-M6",
  ame = NA, ame_se = NA, amme = NA, amme_se = NA)
  
for (i in c(1:3)) {
  #get AMEs of dissimilarity i of model 2 (including relational embeddedness only)
  ame_i_base <- booL[[2]]$t[,i]
  #get AME of dissimilarity i of extended model 4 (adding also structural embeddedness)
  ame_i_modelj <- booL[[4]]$t[,i]
  #calculate cross-model AME difference
  cm_ame_difs <- ame_i_base - ame_i_modelj
  #calcualte average marginal mediation
  plotdata2$amme[plotdata2$pred == unique(plotdata2$pred)[i]] <- mean(cm_ame_difs)
  #and SE
  plotdata2$amme_se[plotdata2$pred == unique(plotdata2$pred)[i]] <- sd(cm_ame_difs)/sqrt(nIter)
  }

bind_rows(plotdata,plotdata2) -> plotdata2

plotdata2$pred <- factor(plotdata2$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation"))
plotdata2$model <- factor(plotdata2$model, levels = rev(c("M3", "M4", "M5", "M6", "M4-M6")))
plotdata2 <- plotdata2[order(plotdata2$pred),]
row.names(plotdata2) <- 1:nrow(plotdata2)
#fshowdf(plotdata2)

plot2 <- ggplot(plotdata2, aes(x = amme, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "red") +
  geom_errorbar(aes(xmin = amme - 1.96*amme_se, xmax = amme + 1.96*amme_se), color="red", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMME") +
  scale_x_continuous(labels = scales::percent, limits = c(-0.075, 0.05)) +
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "red"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) +
  scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""),
                   position = "right") +
  theme(strip.text = element_blank())

#combine plots
#?ggarrange

(figure <- ggarrange(plot1, plot2, ncol=2, widths=c(1.1, 1)))

AME / AMIE

gender <- data.frame(pred = "Different\ngender", model = c("Pooled", "best friends vs. confidants", "sports vs. confidants",
    "study vs. confidants"), ame = c(booL[[5]]$t0[1], rep(NA, 3)), ame_se = c(apply(booL[[5]]$t, 2, sd)[1],
    rep(NA, 3)), amie = c(NA, booL[[5]]$t0[2:4]), amie_se = c(NA, apply(booL[[5]]$t, 2, sd)[2:4]))

age <- data.frame(pred = "Age\ndifference", model = c("Pooled", "best friends vs. confidants", "sports vs. confidants",
    "study vs. confidants"), ame = c(booL[[5]]$t0[5], rep(NA, 3)), ame_se = c(apply(booL[[5]]$t, 2, sd)[5],
    rep(NA, 3)), amie = c(NA, booL[[5]]$t0[6:8]), amie_se = c(NA, apply(booL[[5]]$t, 2, sd)[6:8]))

educ <- data.frame(pred = "Different\neducation", model = c("Pooled", "best friends vs. confidants",
    "sports vs. confidants", "study vs. confidants"), ame = c(booL[[5]]$t0[9], rep(NA, 3)), ame_se = c(apply(booL[[5]]$t,
    2, sd)[9], rep(NA, 3)), amie = c(NA, booL[[5]]$t0[10:12]), amie_se = c(NA, apply(booL[[5]]$t, 2,
    sd)[10:12]))

plotdata <- rbind(gender, age, educ)

# variables to class factor, reorder:
plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation"))
plotdata$model <- factor(plotdata$model, levels = rev(c("Pooled", "best friends vs. confidants", "sports vs. confidants",
    "study vs. confidants")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)
fshowdf(plotdata, digits = 4)
pred model ame ame_se amie amie_se
Different gender Pooled -0.0035 0.0170 NA NA
Different gender best friends vs. confidants NA NA 0.1502 0.0292
Different gender sports vs. confidants NA NA 0.0826 0.0359
Different gender study vs. confidants NA NA 0.1044 0.0350
Age difference Pooled 0.0113 0.0035 NA NA
Age difference best friends vs. confidants NA NA 0.0098 0.0063
Age difference sports vs. confidants NA NA -0.0226 0.0074
Age difference study vs. confidants NA NA -0.0116 0.0080
Different education Pooled -0.0214 0.0166 NA NA
Different education best friends vs. confidants NA NA -0.0083 0.0285
Different education sports vs. confidants NA NA -0.0910 0.0349
Different education study vs. confidants NA NA -0.0265 0.0383
#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.1, 0.1)) + #x-axis to %-point, and set range 
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
  pred == "Different\ngender" ~ scale_y_discrete(labels = c( "", "", "", "M7")),
  pred == "Different\neducation" ~ scale_y_discrete(labels = c( "", "", "", "M7")),
  pred == "Age\ndifference" ~ scale_y_discrete(labels = c( "", "", "", "M7"))))


#plot 2: AMIEs
plot2 <- ggplot(plotdata, aes(x = amie, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "orange") +
  geom_errorbar(aes(xmin = amie - 1.96*amie_se, xmax = amie + 1.96*amie_se), color="orange", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMIE") +
  scale_x_continuous(labels = scales::percent, limits = c(-.25,.25)) + #x-axis to %-point, and set range 
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "orange"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) +
  scale_y_discrete(labels = c("study vs. confidant", "sports vs. confidant", "best friend vs. confidant", ""),
                   position = "right") +
  theme(strip.text = element_blank())

(figure <- ggarrange(plot1, plot2, ncol=2, align="hv", widths = c(1,1.2)))

close <- data.frame(pred = "Emotional\ncloseness", model = c("Pooled", "best friends vs. confidants",
    "sports vs. confidants", "study vs. confidants"), ame = c(booL[[6]]$t0[1], rep(NA, 3)), ame_se = c(apply(booL[[6]]$t,
    2, sd)[1], rep(NA, 3)), amie = c(NA, booL[[6]]$t0[2:4]), amie_se = c(NA, apply(booL[[6]]$t, 2, sd)[2:4]))

multi <- data.frame(pred = "Relational\nmultiplexity", model = c("Pooled", "best friends vs. confidants",
    "sports vs. confidants", "study vs. confidants"), ame = c(booL[[6]]$t0[5], rep(NA, 3)), ame_se = c(apply(booL[[6]]$t,
    2, sd)[5], rep(NA, 3)), amie = c(NA, booL[[6]]$t0[6:8]), amie_se = c(NA, apply(booL[[6]]$t, 2, sd)[6:8]))

strf <- data.frame(pred = "Structural\nembedded-\nness\nfocal layer", model = c("Pooled", "best friends vs. confidants",
    "sports vs. confidants", "study vs. confidants"), ame = c(booL[[6]]$t0[9], rep(NA, 3)), ame_se = c(apply(booL[[6]]$t,
    2, sd)[9], rep(NA, 3)), amie = c(NA, booL[[6]]$t0[10:12]), amie_se = c(NA, apply(booL[[6]]$t, 2,
    sd)[10:12]))

stro <- data.frame(pred = "Structural\nembedded-\nness\nother layers", model = c("Pooled", "best friends vs. confidants",
    "sports vs. confidants", "study vs. confidants"), ame = c(booL[[6]]$t0[13], rep(NA, 3)), ame_se = c(apply(booL[[6]]$t,
    2, sd)[13], rep(NA, 3)), amie = c(NA, booL[[6]]$t0[14:16]), amie_se = c(NA, apply(booL[[6]]$t, 2,
    sd)[14:16]))

plotdata <- rbind(close, multi, strf, stro)

# variables to class factor, reorder:
plotdata$pred <- factor(plotdata$pred, levels = c("Emotional\ncloseness", "Relational\nmultiplexity",
    "Structural\nembedded-\nness\nfocal layer", "Structural\nembedded-\nness\nother layers"))

plotdata$model <- factor(plotdata$model, levels = rev(c("Pooled", "best friends vs. confidants", "sports vs. confidants",
    "study vs. confidants")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)
fshowdf(plotdata, digits = 4)
pred model ame ame_se amie amie_se
Emotional closeness Pooled -0.1425 0.0088 NA NA
Emotional closeness best friends vs. confidants NA NA 0.0552 0.0171
Emotional closeness sports vs. confidants NA NA 0.0938 0.0234
Emotional closeness study vs. confidants NA NA 0.1254 0.0236
Relational multiplexity Pooled -0.0449 0.0093 NA NA
Relational multiplexity best friends vs. confidants NA NA 0.0411 0.0198
Relational multiplexity sports vs. confidants NA NA 0.0995 0.0248
Relational multiplexity study vs. confidants NA NA 0.0769 0.0239
Structural embedded- ness focal layer Pooled -0.0551 0.0157 NA NA
Structural embedded- ness focal layer best friends vs. confidants NA NA 0.0279 0.0438
Structural embedded- ness focal layer sports vs. confidants NA NA -0.0277 0.0514
Structural embedded- ness focal layer study vs. confidants NA NA -0.1560 0.0482
Structural embedded- ness other layers Pooled 0.0092 0.0465 NA NA
Structural embedded- ness other layers best friends vs. confidants NA NA 0.0279 0.0438
Structural embedded- ness other layers sports vs. confidants NA NA -0.0271 0.0508
Structural embedded- ness other layers study vs. confidants NA NA -0.1464 0.0462
#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
 scale_x_continuous(labels = scales::percent, limits = c(-0.2, 0.15)) + #x-axis to %-point, and set range 
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
  pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = c( "", "", "", "M8")),
  pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = c( "", "", "", "M8")),
  pred == "Structural\nembedded-\nness\nfocal layer" ~ scale_y_discrete(labels = c( "", "", "", "M8")),
  pred == "Structural\nembedded-\nness\nother layers" ~ scale_y_discrete(labels = c( "", "", "", "M8"))
  ))


#plot 2: AMIEs
plot2 <- ggplot(plotdata, aes(x = amie, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "orange") +
  geom_errorbar(aes(xmin = amie - 1.96*amie_se, xmax = amie + 1.96*amie_se), color="orange", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMIE") +
  scale_x_continuous(labels = scales::percent, limits = c(-.3,.25)) + #x-axis to %-point, and set range 
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "orange"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) +
  scale_y_discrete(labels = c("study vs. confidant", "sports vs. confidant", "best friend vs. confidant", ""),
                   position = "right") +
  theme(strip.text = element_blank())


(figure <- ggarrange(plot1, plot2, ncol=2, align="hv", widths = c(1,1.2)))


separate analyses by tie type

AMIEs provide a clear causal interpretation (i.e., how an AME changes when comparing a specific type of tie, when compared to confidants), but they lack a clear descriptive interpretation, regarding the significance and valence of AMEs across relational roles. To enhance our interpretation of AMIEs, we will compute AMEs (and AMMEs) for each specific network layer. This enables us to:

  • assess the sign and significance of AMEs per relational role
  • test mediation effects (AMMEs) per relational role


1. create new datasets

# dissimilarity
dfconfidantgender1 <- dfconfidantgender0 <- dfconfidant
dfconfidantageplus <- dfconfidantagemin <- dfconfidant
dfconfidanteduc1 <- dfconfidanteduc0 <- dfconfidant

dfconfidantgender1$different_gender <- 1
dfconfidantgender0$different_gender <- 0
dfconfidanteduc1$different_educ <- 1
dfconfidanteduc0$different_educ <- 0

# define small step for continuous variable
s <- 0.001
dfconfidantageplus$dif_age <- dfconfidant$dif_age + s
dfconfidantagemin$dif_age <- dfconfidant$dif_age - s

# embeddedness
dfconfidantcloseplus <- dfconfidantclosemin <- dfconfidant
dfconfidantcloseplus$closeness.t <- dfconfidant$closeness.t + s
dfconfidantclosemin$closeness.t <- dfconfidant$closeness.t - s

dfconfidantmultiplus <- dfconfidantmultimin <- dfconfidant
dfconfidantmultiplus$multiplex <- dfconfidant$multiplex + s
dfconfidantmultimin$multiplex <- dfconfidant$multiplex - s

dfconfidantfembedplus <- dfconfidantfembedmin <- dfconfidant
dfconfidantfembedplus$embed <- dfconfidant$embed + s
dfconfidantfembedmin$embed <- dfconfidant$embed - s

dfconfidantoembedplus <- dfconfidantoembedmin <- dfconfidant
dfconfidantoembedplus$embed.ext <- dfconfidant$embed.ext + s
dfconfidantoembedmin$embed.ext <- dfconfidant$embed.ext - s

2. get models

m1 <- ansconfidant[[2]]  #base
m2 <- ansconfidant[[3]]  #+mediator 1 (relational embeddedness)
m3 <- ansconfidant[[4]]  #+mediator 2 (structural embeddedness)
m4 <- ansconfidant[[5]]  #+both mediators

3. create fpred() functions

# 1. AMEs dissimilarities base model
fpred1 <- function(m1) {
    me_gender <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidantgender1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidantgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidantageplus) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidantagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidanteduc1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfconfidanteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 2. after controlling for relational embeddedness
fpred2 <- function(m2) {
    me_gender <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidantgender1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidantgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidantageplus) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidantagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidanteduc1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfconfidanteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 3. after controlling for structural embeddedness
fpred3 <- function(m3) {
    me_gender <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidantgender1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidantgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidantageplus) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidantagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidanteduc1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfconfidanteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 4. after controlling for both mediators
fpred4 <- function(m4) {
    me_gender <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantgender1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantageplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidanteduc1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidanteduc0)
    ame_educ <- mean(me_educ)

    # also AMEs of embeddedness
    me_close <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantcloseplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantclosemin))/(2 *
        s)
    ame_close <- mean(me_close)
    summary(m4)

    me_multi <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantmultiplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantmultimin))/(2 *
        s)
    ame_multi <- mean(me_multi)

    me_fembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantfembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantfembedmin))/(2 *
        s)
    ame_fembed <- mean(me_fembed)

    me_oembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantoembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfconfidantoembedmin))/(2 *
        s)
    ame_oembed <- mean(me_oembed)

    c(ame_gender, ame_age, ame_educ, ame_close, ame_multi, ame_fembed, ame_oembed)
}

# fpred1(m1) fpred2(m2) fpred3(m3) fpred4(m4)

4. bootstrap AMEs

seed <- 2425323
nIter <- 500

nCore <- parallel::detectCores()
mycl <- makeCluster(rep("localhost", nCore))
clusterEvalQ(mycl, library(lme4))
clusterExport(mycl, varlist = c("m1", "m2", "m3", "m4", "s", "seed", "dfconfidantgender1", "dfconfidantgender0",
    "dfconfidantageplus", "dfconfidantagemin", "dfconfidanteduc1", "dfconfidanteduc0", "dfconfidantcloseplus",
    "dfconfidantclosemin", "dfconfidantmultiplus", "dfconfidantmultimin", "dfconfidantfembedplus", "dfconfidantfembedmin",
    "dfconfidantoembedplus", "dfconfidantoembedmin"))

system.time(boo_m1 <- bootMer(m1, fpred1, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m2 <- bootMer(m2, fpred2, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m3 <- bootMer(m3, fpred3, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m4 <- bootMer(m4, fpred4, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))

booL <- list(boo_m1, boo_m2, boo_m3, boo_m4)
save(booL, file = "./results/boot_confidants.Rda")
stopCluster(mycl)

5. construct plot dataset

nIter = 500
load("./results/boot_confidants.rda")

# AMEs dissimilarities
plotdata <- data.frame(pred = rep(c("Different\ngender", "Age\ndifference", "Different\neducation"),
    4), model = rep(c("M3", "M4", "M5", "M6"), each = 3), ame = c(booL[[1]]$t0, booL[[2]]$t0, booL[[3]]$t0,
    booL[[4]]$t0[1:3]), ame_se = c(apply(booL[[1]]$t, 2, sd), apply(booL[[2]]$t, 2, sd), apply(booL[[3]]$t,
    2, sd), apply(booL[[4]]$t, 2, sd)[1:3]))

# AMMEs
plotdata$amme <- NA
plotdata$amme_se <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for extended model get AMEs of dissimilarity i of baseline model
    for (j in c(2:4)) {
        ame_i_base <- booL[[1]]$t[, i]
        # get AMEs of dissimilarity i of extended model j
        ame_i_modelj <- booL[[j]]$t[, i]
        # calculate cross-model AME difference per bootstrap iteration
        cm_ame_difs <- ame_i_base - ame_i_modelj
        # calculate average marginal mediation effect by taking the average
        plotdata$amme[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(cm_ame_difs)
        # and SE
        plotdata$amme_se[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- sd(cm_ame_difs)/sqrt(nIter)
    }
}

plotdata2 <- data.frame(pred = c("Different\ngender", "Age\ndifference", "Different\neducation"), model = "M4-M6",
    ame = NA, ame_se = NA, amme = NA, amme_se = NA)

for (i in c(1:3)) {
    # get AMEs of dissimilarity i of model 2 (including relational embeddedness only)
    ame_i_base <- booL[[2]]$t[, i]
    # get AME of dissimilarity i of extended model 4 (adding also structural embeddedness)
    ame_i_modelj <- booL[[4]]$t[, i]
    # calculate cross-model AME difference
    cm_ame_difs <- ame_i_base - ame_i_modelj
    # calcualte average marginal mediation
    plotdata2$amme[plotdata2$pred == unique(plotdata2$pred)[i]] <- mean(cm_ame_difs)
    # and SE
    plotdata2$amme_se[plotdata2$pred == unique(plotdata2$pred)[i]] <- sd(cm_ame_difs)/sqrt(nIter)
}

# AME embeddedness
plotdata3 <- data.frame(pred = c("Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer",
    "Str. embed.\nother layers"), model = "M6", ame = booL[[4]]$t0[4:7], ame_se = apply(booL[[4]]$t,
    2, sd)[4:7])

bind_rows(plotdata, plotdata2, plotdata3) -> plotdata

plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation",
    "Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer", "Str. embed.\nother layers"))
plotdata$model <- factor(plotdata$model, levels = rev(c("M2", "M4", "M5", "M6", "M4-M6")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)

6. result

#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.25, 0.30)) + #x-axis to %-point, and set range
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
    ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
      pred == "Different\ngender" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Age\ndifference" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Different\neducation" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = "M6"),
      pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nfocal layer" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = "M6")
      ))

plot2 <- ggplot(plotdata, aes(x = amme, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "red") +
  geom_errorbar(aes(xmin = amme - 1.96*amme_se, xmax = amme + 1.96*amme_se), color="red", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMME") +
  scale_x_continuous(labels = scales::percent, limits = c(-0.05, 0.05)) +
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "red"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) + 
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
    pred == "Different\ngender" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Age\ndifference" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Different\neducation" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nfocal layer" ~  scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = NULL, position = "right"))) +
  theme(strip.text = element_blank())
  
#combine plots
#?ggarrange
fshowdf(plotdata,digits=3)
pred model ame ame_se amme amme_se
Different gender NA -0.073 0.028 NA NA
Different gender M4 -0.071 0.028 -0.001 0.001
Different gender M5 -0.089 0.028 0.017 0.001
Different gender M6 -0.071 0.028 -0.001 0.001
Different gender M4-M6 NA NA 0.000 0.000
Age difference NA 0.022 0.005 NA NA
Age difference M4 0.010 0.005 0.012 0.000
Age difference M5 0.021 0.005 0.001 0.000
Age difference M6 0.010 0.005 0.012 0.000
Age difference M4-M6 NA NA 0.000 0.000
Different education NA -0.018 0.027 NA NA
Different education M4 -0.014 0.026 -0.004 0.001
Different education M5 -0.016 0.027 -0.003 0.001
Different education M6 -0.014 0.026 -0.005 0.001
Different education M4-M6 NA NA -0.001 0.000
Emotional closeness M6 -0.179 0.016 NA NA
Relational multiplexity M6 -0.103 0.016 NA NA
Str. embed. focal layer M6 -0.016 0.037 NA NA
Str. embed. other layers M6 0.021 0.068 NA NA
figure <- ggarrange(plot1, plot2, ncol=2, widths=c(1.1, 1))
(figure <- annotate_figure(figure, top = text_grob("Confidants", color = "black", face = "bold", size = 14)))

1. create new datasets

# dissimilarity
dffriendgender1 <- dffriendgender0 <- dffriend
dffriendageplus <- dffriendagemin <- dffriend
dffriendeduc1 <- dffriendeduc0 <- dffriend

dffriendgender1$different_gender <- 1
dffriendgender0$different_gender <- 0
dffriendeduc1$different_educ <- 1
dffriendeduc0$different_educ <- 0

# define small step for continuous variable
s <- 0.001
dffriendageplus$dif_age <- dffriend$dif_age + s
dffriendagemin$dif_age <- dffriend$dif_age - s

# embeddedness
dffriendcloseplus <- dffriendclosemin <- dffriend
dffriendcloseplus$closeness.t <- dffriend$closeness.t + s
dffriendclosemin$closeness.t <- dffriend$closeness.t - s

dffriendmultiplus <- dffriendmultimin <- dffriend
dffriendmultiplus$multiplex <- dffriend$multiplex + s
dffriendmultimin$multiplex <- dffriend$multiplex - s

dffriendfembedplus <- dffriendfembedmin <- dffriend
dffriendfembedplus$embed <- dffriend$embed + s
dffriendfembedmin$embed <- dffriend$embed - s

dffriendoembedplus <- dffriendoembedmin <- dffriend
dffriendoembedplus$embed.ext <- dffriend$embed.ext + s
dffriendoembedmin$embed.ext <- dffriend$embed.ext - s

2. get models

m1 <- ansfriend[[2]]  #base
m2 <- ansfriend[[3]]  #+mediator 1 (relational embeddedness)
m3 <- ansfriend[[4]]  #+mediator 2 (structural embeddedness)
m4 <- ansfriend[[5]]  #+both mediators

3. create fpred() functions

# 1. AMEs dissimilarities base model
fpred1 <- function(m1) {
    me_gender <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendgender1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendageplus) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendeduc1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dffriendeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 2. after controlling for relational embeddedness
fpred2 <- function(m2) {
    me_gender <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendgender1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendageplus) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendeduc1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dffriendeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 3. after controlling for structural embeddedness
fpred3 <- function(m3) {
    me_gender <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendgender1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendageplus) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendeduc1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dffriendeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 4. after controlling for both mediators
fpred4 <- function(m4) {
    me_gender <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendgender1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendageplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendagemin))/(2 *
        s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendeduc1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendeduc0)
    ame_educ <- mean(me_educ)

    # also AMEs of embeddedness
    me_close <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendcloseplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendclosemin))/(2 *
        s)
    ame_close <- mean(me_close)
    summary(m4)

    me_multi <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendmultiplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendmultimin))/(2 *
        s)
    ame_multi <- mean(me_multi)

    me_fembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendfembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendfembedmin))/(2 *
        s)
    ame_fembed <- mean(me_fembed)

    me_oembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendoembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dffriendoembedmin))/(2 *
        s)
    ame_oembed <- mean(me_oembed)

    c(ame_gender, ame_age, ame_educ, ame_close, ame_multi, ame_fembed, ame_oembed)
}

# fpred1(m1) fpred2(m2) fpred3(m3) fpred4(m4)

4. bootstrap AMEs

seed <- 2425323
nIter <- 500

nCore <- parallel::detectCores()
mycl <- makeCluster(rep("localhost", nCore))
clusterEvalQ(mycl, library(lme4))
clusterExport(mycl, varlist = c("m1", "m2", "m3", "m4", "s", "seed", "dffriendgender1", "dffriendgender0",
    "dffriendageplus", "dffriendagemin", "dffriendeduc1", "dffriendeduc0", "dffriendcloseplus", "dffriendclosemin",
    "dffriendmultiplus", "dffriendmultimin", "dffriendfembedplus", "dffriendfembedmin", "dffriendoembedplus",
    "dffriendoembedmin"))

system.time(boo_m1 <- bootMer(m1, fpred1, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m2 <- bootMer(m2, fpred2, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m3 <- bootMer(m3, fpred3, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m4 <- bootMer(m4, fpred4, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))

booL <- list(boo_m1, boo_m2, boo_m3, boo_m4)
save(booL, file = "./results/boot_friends.Rda")
stopCluster(mycl)

5. construct plot dataset

nIter = 500
load("./results/boot_friends.rda")

# AMEs dissimilarities
plotdata <- data.frame(pred = rep(c("Different\ngender", "Age\ndifference", "Different\neducation"),
    4), model = rep(c("M3", "M4", "M5", "M6"), each = 3), ame = c(booL[[1]]$t0, booL[[2]]$t0, booL[[3]]$t0,
    booL[[4]]$t0[1:3]), ame_se = c(apply(booL[[1]]$t, 2, sd), apply(booL[[2]]$t, 2, sd), apply(booL[[3]]$t,
    2, sd), apply(booL[[4]]$t, 2, sd)[1:3]))

# AMMEs
plotdata$amme <- NA
plotdata$amme_se <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for extended model get AMEs of dissimilarity i of baseline model
    for (j in c(2:4)) {
        ame_i_base <- booL[[1]]$t[, i]
        # get AMEs of dissimilarity i of extended model j
        ame_i_modelj <- booL[[j]]$t[, i]
        # calculate cross-model AME difference per bootstrap iteration
        cm_ame_difs <- ame_i_base - ame_i_modelj
        # calculate average marginal mediation effect by taking the average
        plotdata$amme[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(cm_ame_difs)
        # and SE
        plotdata$amme_se[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- sd(cm_ame_difs)/sqrt(nIter)
    }
}

plotdata2 <- data.frame(pred = c("Different\ngender", "Age\ndifference", "Different\neducation"), model = "M4-M6",
    ame = NA, ame_se = NA, amme = NA, amme_se = NA)

for (i in c(1:3)) {
    # get AMEs of dissimilarity i of model 2 (including relational embeddedness only)
    ame_i_base <- booL[[2]]$t[, i]
    # get AME of dissimilarity i of extended model 4 (adding also structural embeddedness)
    ame_i_modelj <- booL[[4]]$t[, i]
    # calculate cross-model AME difference
    cm_ame_difs <- ame_i_base - ame_i_modelj
    # calcualte average marginal mediation
    plotdata2$amme[plotdata2$pred == unique(plotdata2$pred)[i]] <- mean(cm_ame_difs)
    # and SE
    plotdata2$amme_se[plotdata2$pred == unique(plotdata2$pred)[i]] <- sd(cm_ame_difs)/sqrt(nIter)
}

# AME embeddedness
plotdata3 <- data.frame(pred = c("Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer",
    "Str. embed.\nother layers"), model = "M6", ame = booL[[4]]$t0[4:7], ame_se = apply(booL[[4]]$t,
    2, sd)[4:7])

bind_rows(plotdata, plotdata2, plotdata3) -> plotdata

plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation",
    "Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer", "Str. embed.\nother layers"))
plotdata$model <- factor(plotdata$model, levels = rev(c("M3", "M4", "M5", "M6", "M4-M6")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)

6. result

#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.25, .30)) + #x-axis to %-point, and set range
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
    ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
      pred == "Different\ngender" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Age\ndifference" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Different\neducation" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = "M6"),
      pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nfocal layer" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = "M6")
      ))

plot2 <- ggplot(plotdata, aes(x = amme, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "red") +
  geom_errorbar(aes(xmin = amme - 1.96*amme_se, xmax = amme + 1.96*amme_se), color="red", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMME") +
  scale_x_continuous(labels = scales::percent, limits = c(-0.05, 0.05)) +
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "red"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) + 
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
    pred == "Different\ngender" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Age\ndifference" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Different\neducation" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nfocal layer" ~  scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = NULL, position = "right"))) +
  theme(strip.text = element_blank())
  
#combine plots
#?ggarrange
fshowdf(plotdata, digits=3)
pred model ame ame_se amme amme_se
Different gender M3 0.002 0.026 NA NA
Different gender M4 0.015 0.026 -0.012 0.001
Different gender M5 0.008 0.026 -0.003 0.001
Different gender M6 0.015 0.025 -0.013 0.001
Different gender M4-M6 NA NA -0.001 0.000
Age difference M3 0.016 0.005 NA NA
Age difference M4 0.018 0.006 -0.001 0.000
Age difference M5 0.017 0.005 -0.001 0.000
Age difference M6 0.018 0.006 -0.001 0.000
Age difference M4-M6 NA NA 0.000 0.000
Different education M3 0.014 0.024 NA NA
Different education M4 0.018 0.022 -0.005 0.001
Different education M5 0.014 0.022 0.001 0.001
Different education M6 0.017 0.022 -0.003 0.001
Different education M4-M6 NA NA 0.001 0.000
Emotional closeness M6 -0.132 0.013 NA NA
Relational multiplexity M6 -0.081 0.014 NA NA
Str. embed. focal layer M6 0.024 0.027 NA NA
Str. embed. other layers M6 -0.098 0.072 NA NA
figure <- ggarrange(plot1, plot2, ncol=2, widths=c(1.1, 1))
(figure <- annotate_figure(figure, top = text_grob("Best friends", color = "black", face = "bold", size = 14)))

1. create new datasets

# dissimilarity
dfsportgender1 <- dfsportgender0 <- dfsport
dfsportageplus <- dfsportagemin <- dfsport
dfsporteduc1 <- dfsporteduc0 <- dfsport

dfsportgender1$different_gender <- 1
dfsportgender0$different_gender <- 0
dfsporteduc1$different_educ <- 1
dfsporteduc0$different_educ <- 0

# define small step for continuous variable
s <- 0.001
dfsportageplus$dif_age <- dfsport$dif_age + s
dfsportagemin$dif_age <- dfsport$dif_age - s

# embeddedness
dfsportcloseplus <- dfsportclosemin <- dfsport
dfsportcloseplus$closeness.t <- dfsport$closeness.t + s
dfsportclosemin$closeness.t <- dfsport$closeness.t - s

dfsportmultiplus <- dfsportmultimin <- dfsport
dfsportmultiplus$multiplex <- dfsport$multiplex + s
dfsportmultimin$multiplex <- dfsport$multiplex - s

dfsportfembedplus <- dfsportfembedmin <- dfsport
dfsportfembedplus$embed <- dfsport$embed + s
dfsportfembedmin$embed <- dfsport$embed - s

dfsportoembedplus <- dfsportoembedmin <- dfsport
dfsportoembedplus$embed.ext <- dfsport$embed.ext + s
dfsportoembedmin$embed.ext <- dfsport$embed.ext - s

2. get models

m1 <- anssport[[2]]  #base
m2 <- anssport[[3]]  #+mediator 1 (relational embeddedness)
m3 <- anssport[[4]]  #+mediator 2 (structural embeddedness)
m4 <- anssport[[5]]  #+both mediators

3. create fpred() functions

# 1. AMEs dissimilarities base model
fpred1 <- function(m1) {
    me_gender <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsportgender1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsportgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsportageplus) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsportagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsporteduc1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfsporteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 2. after controlling for relational embeddedness
fpred2 <- function(m2) {
    me_gender <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsportgender1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsportgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsportageplus) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsportagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsporteduc1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfsporteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 3. after controlling for structural embeddedness
fpred3 <- function(m3) {
    me_gender <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsportgender1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsportgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsportageplus) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsportagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsporteduc1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfsporteduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 4. after controlling for both mediators
fpred4 <- function(m4) {
    me_gender <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportgender1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportgender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportageplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsporteduc1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsporteduc0)
    ame_educ <- mean(me_educ)

    # also AMEs of embeddedness
    me_close <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportcloseplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportclosemin))/(2 *
        s)
    ame_close <- mean(me_close)
    summary(m4)

    me_multi <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportmultiplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportmultimin))/(2 *
        s)
    ame_multi <- mean(me_multi)

    me_fembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportfembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportfembedmin))/(2 *
        s)
    ame_fembed <- mean(me_fembed)

    me_oembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportoembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfsportoembedmin))/(2 *
        s)
    ame_oembed <- mean(me_oembed)

    c(ame_gender, ame_age, ame_educ, ame_close, ame_multi, ame_fembed, ame_oembed)
}

# fpred1(m1) fpred2(m2) fpred3(m3) fpred4(m4)

4. bootstrap AMEs

seed <- 2425323
nIter <- 500
nCore <- parallel::detectCores() - 1
mycl <- makeCluster(rep("localhost", nCore))
clusterEvalQ(mycl, library(lme4))
clusterExport(mycl, varlist = c("m1", "m2", "m3", "m4", "s", "seed", "dfsportgender1", "dfsportgender0",
    "dfsportageplus", "dfsportagemin", "dfsporteduc1", "dfsporteduc0", "dfsportcloseplus", "dfsportclosemin",
    "dfsportmultiplus", "dfsportmultimin", "dfsportfembedplus", "dfsportfembedmin", "dfsportoembedplus",
    "dfsportoembedmin"))

system.time(boo_m1 <- bootMer(m1, fpred1, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m2 <- bootMer(m2, fpred2, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m3 <- bootMer(m3, fpred3, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m4 <- bootMer(m4, fpred4, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))

booL <- list(boo_m1, boo_m2, boo_m3, boo_m4)
save(booL, file = "./results/boot_sports.Rda")
stopCluster(mycl)

5. construct plot dataset

nIter = 500
load("./results/boot_sports.rda")

# AMEs dissimilarities
plotdata <- data.frame(pred = rep(c("Different\ngender", "Age\ndifference", "Different\neducation"),
    4), model = rep(c("M3", "M4", "M5", "M6"), each = 3), ame = c(booL[[1]]$t0, booL[[2]]$t0, booL[[3]]$t0,
    booL[[4]]$t0[1:3]), ame_se = c(apply(booL[[1]]$t, 2, sd), apply(booL[[2]]$t, 2, sd), apply(booL[[3]]$t,
    2, sd), apply(booL[[4]]$t, 2, sd)[1:3]))

# AMMEs
plotdata$amme <- NA
plotdata$amme_se <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for extended model get AMEs of dissimilarity i of baseline model
    for (j in c(2:4)) {
        ame_i_base <- booL[[1]]$t[, i]
        # get AMEs of dissimilarity i of extended model j
        ame_i_modelj <- booL[[j]]$t[, i]
        # calculate cross-model AME difference per bootstrap iteration
        cm_ame_difs <- ame_i_base - ame_i_modelj
        # calculate average marginal mediation effect by taking the average
        plotdata$amme[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(cm_ame_difs)
        # and SE
        plotdata$amme_se[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- sd(cm_ame_difs)/sqrt(nIter)
    }
}

plotdata2 <- data.frame(pred = c("Different\ngender", "Age\ndifference", "Different\neducation"), model = "M4-M6",
    ame = NA, ame_se = NA, amme = NA, amme_se = NA)

for (i in c(1:3)) {
    # get AMEs of dissimilarity i of model 2 (including relational embeddedness only)
    ame_i_base <- booL[[2]]$t[, i]
    # get AME of dissimilarity i of extended model 4 (adding also structural embeddedness)
    ame_i_modelj <- booL[[4]]$t[, i]
    # calculate cross-model AME difference
    cm_ame_difs <- ame_i_base - ame_i_modelj
    # calcualte average marginal mediation
    plotdata2$amme[plotdata2$pred == unique(plotdata2$pred)[i]] <- mean(cm_ame_difs)
    # and SE
    plotdata2$amme_se[plotdata2$pred == unique(plotdata2$pred)[i]] <- sd(cm_ame_difs)/sqrt(nIter)
}


# AME embeddedness
plotdata3 <- data.frame(pred = c("Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer",
    "Str. embed.\nother layers"), model = "M6", ame = booL[[4]]$t0[4:7], ame_se = apply(booL[[4]]$t,
    2, sd)[4:7])

bind_rows(plotdata, plotdata2, plotdata3) -> plotdata

plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation",
    "Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer", "Str. embed.\nother layers"))
plotdata$model <- factor(plotdata$model, levels = rev(c("M3", "M4", "M5", "M6", "M4-M6")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)

6. result

#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.25, 0.30)) + #x-axis to %-point, and set range
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
    ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
      pred == "Different\ngender" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Age\ndifference" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Different\neducation" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = "M6"),
      pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nfocal layer" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = "M6")
      ))

plot2 <- ggplot(plotdata, aes(x = amme, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "red") +
  geom_errorbar(aes(xmin = amme - 1.96*amme_se, xmax = amme + 1.96*amme_se), color="red", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMME") +
  scale_x_continuous(labels = scales::percent, limits = c(-0.05, 0.05)) +
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "red"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) + 
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
    pred == "Different\ngender" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Age\ndifference" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Different\neducation" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M4", ""), position = "right"),
    pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nfocal layer" ~  scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = NULL, position = "right"))) +
  theme(strip.text = element_blank())

#combine plots
#?ggarrange
fshowdf(plotdata, digits=3)
pred model ame ame_se amme amme_se
Different gender M3 -0.019 0.038 NA NA
Different gender M4 0.015 0.037 -0.034 0.002
Different gender M5 -0.020 0.039 0.001 0.001
Different gender M6 0.011 0.038 -0.031 0.002
Different gender M4-M6 NA NA 0.004 0.001
Age difference M3 -0.002 0.007 NA NA
Age difference M4 -0.005 0.007 0.003 0.000
Age difference M5 -0.003 0.007 0.001 0.000
Age difference M6 -0.005 0.008 0.004 0.000
Age difference M4-M6 NA NA 0.001 0.000
Different education M3 -0.078 0.034 NA NA
Different education M4 -0.086 0.033 0.006 0.001
Different education M5 -0.078 0.033 -0.002 0.001
Different education M6 -0.085 0.033 0.006 0.001
Different education M4-M6 NA NA 0.000 0.001
Emotional closeness M6 -0.108 0.020 NA NA
Relational multiplexity M6 -0.020 0.021 NA NA
Str. embed. focal layer M6 -0.049 0.036 NA NA
Str. embed. other layers M6 -0.009 0.099 NA NA
figure <- ggarrange(plot1, plot2, ncol=2, widths=c(1.1, 1))
(figure <- annotate_figure(figure, top = text_grob("Sports partners", color = "black", face = "bold", size = 14)))

1. create new datasets

# dissimilarity
dfstudygender1 <- dfstudygender0 <- dfstudy
dfstudyageplus <- dfstudyagemin <- dfstudy
dfstudyeduc1 <- dfstudyeduc0 <- dfstudy

dfstudygender1$different_gender <- 1
dfstudygender0$different_gender <- 0
dfstudyeduc1$different_educ <- 1
dfstudyeduc0$different_educ <- 0

# define small step for continuous variable
s <- 0.001
dfstudyageplus$dif_age <- dfstudy$dif_age + s
dfstudyagemin$dif_age <- dfstudy$dif_age - s

# embeddedness
dfstudycloseplus <- dfstudyclosemin <- dfstudy
dfstudycloseplus$closeness.t <- dfstudy$closeness.t + s
dfstudyclosemin$closeness.t <- dfstudy$closeness.t - s

dfstudymultiplus <- dfstudymultimin <- dfstudy
dfstudymultiplus$multiplex <- dfstudy$multiplex + s
dfstudymultimin$multiplex <- dfstudy$multiplex - s

dfstudyfembedplus <- dfstudyfembedmin <- dfstudy
dfstudyfembedplus$embed <- dfstudy$embed + s
dfstudyfembedmin$embed <- dfstudy$embed - s

dfstudyoembedplus <- dfstudyoembedmin <- dfstudy
dfstudyoembedplus$embed.ext <- dfstudy$embed.ext + s
dfstudyoembedmin$embed.ext <- dfstudy$embed.ext - s

2. get models

m1 <- ansstudy[[2]]  #base
m2 <- ansstudy[[3]]  #+mediator 1 (relational embeddedness)
m3 <- ansstudy[[4]]  #+mediator 2 (structural embeddedness)
m4 <- ansstudy[[5]]  #+both mediators

3. create fpred() functions

# 1. AMEs dissimilarities base model
fpred1 <- function(m1) {
    me_gender <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudygender1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudygender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudyageplus) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudyagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudyeduc1) -
        lme4:::predict.merMod(m1, type = "response", re.form = NULL, newdata = dfstudyeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 2. after controlling for relational embeddedness
fpred2 <- function(m2) {
    me_gender <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudygender1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudygender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudyageplus) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudyagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudyeduc1) -
        lme4:::predict.merMod(m2, type = "response", re.form = NULL, newdata = dfstudyeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 3. after controlling for structural embeddedness
fpred3 <- function(m3) {
    me_gender <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudygender1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudygender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudyageplus) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudyagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudyeduc1) -
        lme4:::predict.merMod(m3, type = "response", re.form = NULL, newdata = dfstudyeduc0)
    ame_educ <- mean(me_educ)

    c(ame_gender, ame_age, ame_educ)
}

# 4. after controlling for both mediators
fpred4 <- function(m4) {
    me_gender <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudygender1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudygender0)
    ame_gender <- mean(me_gender)

    me_age <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyageplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyagemin))/(2 * s)
    ame_age <- mean(me_age)

    me_educ <- lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyeduc1) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyeduc0)
    ame_educ <- mean(me_educ)

    # also AMEs of embeddedness
    me_close <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudycloseplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyclosemin))/(2 *
        s)
    ame_close <- mean(me_close)
    summary(m4)

    me_multi <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudymultiplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudymultimin))/(2 *
        s)
    ame_multi <- mean(me_multi)

    me_fembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyfembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyfembedmin))/(2 *
        s)
    ame_fembed <- mean(me_fembed)

    me_oembed <- (lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyoembedplus) -
        lme4:::predict.merMod(m4, type = "response", re.form = NULL, newdata = dfstudyoembedmin))/(2 *
        s)
    ame_oembed <- mean(me_oembed)

    c(ame_gender, ame_age, ame_educ, ame_close, ame_multi, ame_fembed, ame_oembed)
}

# fpred1(m1) fpred2(m2) fpred3(m3) fpred4(m4)

4. bootstrap AMEs

seed <- 2425323
nIter <- 500
nCore <- parallel::detectCores()
mycl <- makeCluster(rep("localhost", nCore))

clusterEvalQ(mycl, library(lme4))
clusterExport(mycl, varlist = c("m1", "m2", "m3", "m4", "s", "seed", "dfstudygender1", "dfstudygender0",
    "dfstudyageplus", "dfstudyagemin", "dfstudyeduc1", "dfstudyeduc0", "dfstudycloseplus", "dfstudyclosemin",
    "dfstudymultiplus", "dfstudymultimin", "dfstudyfembedplus", "dfstudyfembedmin", "dfstudyoembedplus",
    "dfstudyoembedmin"))

system.time(boo_m1 <- bootMer(m1, fpred1, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m2 <- bootMer(m2, fpred2, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m3 <- bootMer(m3, fpred3, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))
system.time(boo_m4 <- bootMer(m4, fpred4, nsim = nIter, parallel = "snow", ncpus = nCore, cl = mycl,
    seed = seed))

booL <- list(boo_m1, boo_m2, boo_m3, boo_m4)
save(booL, file = "./results/boot_study.Rda")
stopCluster(mycl)

5. construct plot dataset

nIter = 500
load("./results/boot_study.rda")

# AMEs dissimilarities
plotdata <- data.frame(pred = rep(c("Different\ngender", "Age\ndifference", "Different\neducation"),
    4), model = rep(c("M3", "M4", "M5", "M6"), each = 3), ame = c(booL[[1]]$t0, booL[[2]]$t0, booL[[3]]$t0,
    booL[[4]]$t0[1:3]), ame_se = c(apply(booL[[1]]$t, 2, sd), apply(booL[[2]]$t, 2, sd), apply(booL[[3]]$t,
    2, sd), apply(booL[[4]]$t, 2, sd)[1:3]))

# AMMEs
plotdata$amme <- NA
plotdata$amme_se <- NA

for (i in c(1:3)) {
    # for dissimilarity ground for extended model get AMEs of dissimilarity i of baseline model
    for (j in c(2:4)) {
        ame_i_base <- booL[[1]]$t[, i]
        # get AMEs of dissimilarity i of extended model j
        ame_i_modelj <- booL[[j]]$t[, i]
        # calculate cross-model AME difference per bootstrap iteration
        cm_ame_difs <- ame_i_base - ame_i_modelj
        # calculate average marginal mediation effect by taking the average
        plotdata$amme[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- mean(cm_ame_difs)
        # and SE
        plotdata$amme_se[plotdata$pred == unique(plotdata$pred)[i] & plotdata$model == unique(plotdata$model)[j]] <- sd(cm_ame_difs)/sqrt(nIter)
    }
}

plotdata2 <- data.frame(pred = c("Different\ngender", "Age\ndifference", "Different\neducation"), model = "M4-M6",
    ame = NA, ame_se = NA, amme = NA, amme_se = NA)

for (i in c(1:3)) {
    # get AMEs of dissimilarity i of model 2 (including relational embeddedness only)
    ame_i_base <- booL[[2]]$t[, i]
    # get AME of dissimilarity i of extended model 4 (adding also structural embeddedness)
    ame_i_modelj <- booL[[4]]$t[, i]
    # calculate cross-model AME difference
    cm_ame_difs <- ame_i_base - ame_i_modelj
    # calcualte average marginal mediation
    plotdata2$amme[plotdata2$pred == unique(plotdata2$pred)[i]] <- mean(cm_ame_difs)
    # and SE
    plotdata2$amme_se[plotdata2$pred == unique(plotdata2$pred)[i]] <- sd(cm_ame_difs)/sqrt(nIter)
}

# AME embeddedness
plotdata3 <- data.frame(pred = c("Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer",
    "Str. embed.\nother layers"), model = "M6", ame = booL[[4]]$t0[4:7], ame_se = apply(booL[[4]]$t,
    2, sd)[4:7])

bind_rows(plotdata, plotdata2, plotdata3) -> plotdata

plotdata$pred <- factor(plotdata$pred, levels = c("Different\ngender", "Age\ndifference", "Different\neducation",
    "Emotional\ncloseness", "Relational\nmultiplexity", "Str. embed.\nfocal layer", "Str. embed.\nother layers"))
plotdata$model <- factor(plotdata$model, levels = rev(c("M3", "M4", "M5", "M6", "M4-M6")))
plotdata <- plotdata[order(plotdata$pred), ]
row.names(plotdata) <- 1:nrow(plotdata)

6. result

#plot 1: AMEs
plot1 <- ggplot(plotdata, aes(x = ame, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") + #vertical line at 0
  geom_point(size = 2, color = "blue") + #point indicating observed AME
  #geom_point(aes(x = ame_b, y = model, fill = pred), size = 3, shape = 4) + #cross indicating average bootstrap AME estimate
  geom_errorbar(aes(xmin = ame - 1.96*ame_se, xmax = ame + 1.96*ame_se), color="blue", width=.5) + #error bars for 95% CI
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") + #arrange facets by dissimilarity type
  labs(x = "AME") + #rename x-axis name
  scale_x_continuous(labels = scales::percent, limits = c(-0.25, 0.30)) + #x-axis to %-point, and set range
  theme( #customize theme
    axis.title.y = element_blank(),
    axis.title.x = element_text(color = "blue"),
    strip.text.y.left = element_text(angle = 0),
    legend.position = "none",
    strip.background = element_blank(),
    strip.placement = "outside",
    strip.text.x = element_text(face = "bold"),
    axis.line = element_line()) +
    ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
      pred == "Different\ngender" ~ scale_y_discrete(labels = c("", "M6", "M5", "M4", "M3")),
      pred == "Age\ndifference" ~ scale_y_discrete(labels =  c("", "M6", "M5", "M4", "M3")),
      pred == "Different\neducation" ~ scale_y_discrete(labels =  c("", "M6", "M5", "M4", "M3")),
      pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = "M6"),
      pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nfocal layer" ~ scale_y_discrete(labels = "M6"),
      pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = "M6")
      ))

plot2 <- ggplot(plotdata, aes(x = amme, y = model, fill = pred)) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  geom_point(size = 2, color = "red") +
  geom_errorbar(aes(xmin = amme - 1.96*amme_se, xmax = amme + 1.96*amme_se), color="red", width=.5) +
  facet_grid(pred ~., switch = "y", scales = "free_y", space = "free_y") +
  labs(x = "AMME") +
  scale_x_continuous(labels = scales::percent, limits = c(-0.05, 0.05)) +
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(color = "red"),
        legend.position = "none",
        strip.background = element_blank(),
        strip.placement = "outside",
        strip.text.x = element_text(face = "bold"),
        axis.line = element_line()) + 
  ggh4x::facetted_pos_scales(y = list( #customize y axis per facet..
    pred == "Different\ngender" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M5", ""), position = "right"),
    pred == "Age\ndifference" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M5", ""), position = "right"),
    pred == "Different\neducation" ~ scale_y_discrete(labels = c("Δ M4-M6", "Δ M3-M6", "Δ M3-M5", "Δ M3-M5", ""), position = "right"),
    pred == "Emotional\ncloseness" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Relational\nmultiplexity" ~ scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nfocal layer" ~  scale_y_discrete(labels = NULL, position = "right"),
    pred == "Str. embed.\nother layers" ~ scale_y_discrete(labels = NULL, position = "right"))) +
  theme(strip.text = element_blank())
  
#combine plots
#?ggarrange
fshowdf(plotdata, digits=3)
pred model ame ame_se amme amme_se
Different gender M3 -0.038 0.040 NA NA
Different gender M4 -0.034 0.038 -0.005 0.001
Different gender M5 -0.041 0.039 0.003 0.001
Different gender M6 -0.036 0.036 -0.002 0.002
Different gender M4-M6 NA NA 0.003 0.001
Age difference M3 0.009 0.009 NA NA
Age difference M4 0.011 0.009 -0.002 0.000
Age difference M5 0.009 0.008 0.000 0.000
Age difference M6 0.012 0.009 -0.003 0.000
Age difference M4-M6 NA NA -0.001 0.000
Different education M3 0.012 0.046 NA NA
Different education M4 0.021 0.044 -0.008 0.002
Different education M5 0.021 0.045 -0.009 0.001
Different education M6 0.022 0.044 -0.008 0.002
Different education M4-M6 NA NA 0.000 0.001
Emotional closeness M6 -0.086 0.019 NA NA
Relational multiplexity M6 -0.049 0.020 NA NA
Str. embed. focal layer M6 -0.130 0.037 NA NA
Str. embed. other layers M6 0.055 0.109 NA NA
figure <- ggarrange(plot1, plot2, ncol=2, widths=c(1.1, 1))
(figure <- annotate_figure(figure, top = text_grob("Study partners", color = "black", face = "bold", size = 14)))



Robustness analyses

accounting for ‘forgetting’

#1. new dependent variable: tie loss, treating forgotten as maintained
df$Ynf <- ifelse(df$reason == "forgotten", 0, df$Y)

#2. subset data of period 2
df23 <- df[df$period == "w2 -> w3",]

#prop.table(table(df23$Y)) #40 percent of ties dropped in w3
#prop.table(table(df23$Ynf)) #34 percent if we correct for forgetting as a cause for tie loss

#3. new formula list (new Y; excluding period effects)
formula3 <- list(
  #0. null
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid),

  #1. tie
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie,

  #2. disismilarity
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) ,
  
  #3. controls
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size),
  
  #4. relational embeddedness as mediator
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t,
  
  #5. str. embeddedness as mediator
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + scale(embed) + scale(embed.ext),

  #6. both relational and structural
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
  
  #7. interaction dissimilarity * tie type
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age)  + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext) + different_gender:tie + different_educ:tie + scale(dif_age):tie,
  
  #8. interaction mediators * tie type
  Ynf ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age) + ego_educ  + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) + romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) + scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext)  + closeness.t:tie + multiplex:tie + scale(embed):tie + scale(embed.ext):tie
)

#estimate using `ffit`
ans3 <- lapply(formula3, ffit, data = df23)


save(ans3, file="./results/ans_forgotten.RData")
Results of random effects models predicting tie dissolution at t+1 (1=yes, 0=no), counting ties to forgotten alters as maintained
  M0 M1 M2 M3 M4 M5 M6 M7 M8
(Intercept) -0.78 (0.06)*** -1.32 (0.12)*** -1.33 (0.14)*** -1.07 (0.34)** 0.75 (0.45) -1.10 (0.35)** 0.71 (0.46) 0.72 (0.47) 4.15 (0.82)***
Friendship   -0.32 (0.13)* -0.30 (0.14)* -0.32 (0.14)* -0.36 (0.14)** -0.31 (0.14)* -0.34 (0.14)* -0.37 (0.21) -2.75 (0.88)**
Sports partner   0.97 (0.16)*** 0.91 (0.16)*** 0.91 (0.17)*** 0.71 (0.17)*** 0.97 (0.17)*** 0.78 (0.17)*** 0.87 (0.26)*** -3.52 (0.88)***
Study partner   1.65 (0.16)*** 1.56 (0.16)*** 1.52 (0.17)*** 1.26 (0.17)*** 1.62 (0.18)*** 1.38 (0.18)*** 1.50 (0.26)*** -2.65 (0.82)**
Different gender     -0.07 (0.13) 0.14 (0.20) 0.19 (0.19) 0.13 (0.20) 0.18 (0.20) -0.29 (0.29) 0.20 (0.20)
Different education     0.11 (0.13) -0.26 (0.15) -0.30 (0.15)* -0.25 (0.15) -0.30 (0.15)* 0.08 (0.25) -0.27 (0.15)
Age difference     0.25 (0.06)*** 0.17 (0.08)* 0.18 (0.08)* 0.16 (0.08)* 0.18 (0.08)* 0.19 (0.11) 0.15 (0.08)
Research university student       -0.54 (0.20)** -0.34 (0.20) -0.53 (0.20)** -0.34 (0.20) -0.32 (0.21) -0.36 (0.21)
Second year student       -0.09 (0.22) -0.15 (0.22) -0.10 (0.22) -0.16 (0.22) -0.14 (0.23) -0.12 (0.23)
Third year or higher       -0.20 (0.17) -0.21 (0.17) -0.22 (0.17) -0.22 (0.17) -0.21 (0.17) -0.16 (0.17)
Age       -0.09 (0.10) -0.17 (0.10) -0.10 (0.10) -0.17 (0.10) -0.18 (0.10) -0.16 (0.10)
Female       0.33 (0.22) 0.35 (0.22) 0.31 (0.22) 0.36 (0.22) 0.37 (0.22) 0.43 (0.22)
Extraversion       0.13 (0.07) 0.17 (0.07)* 0.13 (0.07) 0.16 (0.07)* 0.17 (0.07)* 0.17 (0.07)*
Financial restrictions       0.03 (0.07) 0.02 (0.07) 0.02 (0.07) 0.02 (0.07) 0.02 (0.07) 0.02 (0.07)
Romantic relationship       -0.04 (0.14) -0.05 (0.15) -0.03 (0.14) -0.04 (0.15) -0.04 (0.15) -0.07 (0.15)
Female       0.23 (0.20) 0.19 (0.19) 0.21 (0.20) 0.18 (0.19) 0.19 (0.20) 0.17 (0.20)
Education       -0.24 (0.07)*** -0.25 (0.07)*** -0.24 (0.07)*** -0.25 (0.07)*** -0.23 (0.07)*** -0.27 (0.07)***
Age       -0.02 (0.07) -0.04 (0.07) -0.03 (0.07) -0.04 (0.07) -0.06 (0.07) -0.05 (0.07)
Years known       -0.07 (0.07) 0.01 (0.07) -0.06 (0.07) 0.01 (0.07) 0.01 (0.07) -0.05 (0.07)
Same municipality       -0.11 (0.14) -0.11 (0.14) -0.08 (0.14) -0.09 (0.14) -0.10 (0.14) -0.10 (0.14)
Same house       -0.61 (0.24)* -0.38 (0.24) -0.59 (0.24)* -0.37 (0.24) -0.39 (0.24) -0.46 (0.24)
Network size       0.02 (0.06) 0.01 (0.06) 0.04 (0.06) 0.02 (0.06) 0.01 (0.06) 0.06 (0.06)
Multiplexity         -0.05 (0.08)   -0.14 (0.10) -0.18 (0.10) -0.72 (0.19)***
Emotional closeness         -0.54 (0.10)***   -0.52 (0.10)*** -0.53 (0.10)*** -1.30 (0.21)***
Str. embeddedness focal layer           -0.16 (0.06)** -0.13 (0.06)* -0.12 (0.06)* -0.00 (0.16)
Str. embeddedness other layers           -0.06 (0.07) 0.13 (0.08) 0.13 (0.08) 0.30 (0.15)*
Different gender : Friendship               0.79 (0.32)*  
Different gender : Sports partner               0.49 (0.35)  
Different gender : Study partner               0.54 (0.34)  
Different education : Friendship               -0.39 (0.29)  
Different education : Sports partner               -0.45 (0.33)  
Different education : Study partner               -0.60 (0.34)  
Age difference : Friendship               0.25 (0.14)  
Age difference : Sports partner               -0.33 (0.17)  
Age difference : Study partner               -0.01 (0.16)  
Emotional closeness : Friendship                 0.45 (0.25)
Emotional closeness : Sports partner                 0.95 (0.27)***
Emotional closeness : Study partner                 0.97 (0.25)***
Multiplexity : Friendship                 0.62 (0.24)**
Multiplexity : Sports partner                 0.81 (0.26)**
Multiplexity : Study partner                 0.60 (0.25)*
Str. embeddedness focal layer : Friendship                 0.19 (0.20)
Str. embeddedness focal layer : Sports partner                 -0.23 (0.20)
Str. embeddedness focal layer : Study partner                 -0.29 (0.19)
Str. embeddedness other layers : Friendship                 -0.42 (0.21)*
Str. embeddedness other layers : Sports partner                 -0.16 (0.21)
Str. embeddedness other layers : Study partner                 -0.06 (0.21)
AIC 3775.54 3534.78 3519.17 3506.70 3463.32 3502.03 3460.48 3453.23 3416.39
BIC 3793.54 3570.78 3573.18 3650.73 3619.35 3658.07 3628.51 3675.28 3656.44
Log Likelihood -1884.77 -1761.39 -1750.58 -1729.35 -1705.66 -1725.02 -1702.24 -1689.62 -1668.19
Num. obs. 2985 2985 2985 2985 2985 2985 2985 2985 2985
Num. groups: ego:alterid 1859 1859 1859 1859 1859 1859 1859 1859 1859
Num. groups: ego 281 281 281 281 281 281 281 281 281
Var: ego:alterid (Intercept) 0.97 1.46 1.44 1.41 1.29 1.43 1.34 1.38 1.35
Var: ego (Intercept) 0.28 0.38 0.36 0.35 0.40 0.36 0.40 0.41 0.43
***p < 0.001; **p < 0.01; *p < 0.05

confidant loss analyses by gender

We surprisingly found that different-gender confidants are less, rather than more often dissolved compared to their same-gender counterpart. We subset the analyses on confidant loss by ego’s gender, to explore if this result is driven by one of the genders. Naturally, here we drop the ego- and alter-level gender effects…

ans_women <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid) + different_gender + different_educ + scale(dif_age) +
    period + ego_educ + as.factor(study.year) + scale(ego_age) + scale(extraversion) + scale(fin_restr) +
    romantic + housing.transition + occupation.transition + scale(alter_educ) + scale(as.numeric(alter_age)) +
    scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
    data = dfconfidant[dfconfidant$ego_female == 1, ], family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa",
        optCtrl = list(maxfun = 1e+05)))

ans_men <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid) + different_gender + different_educ + scale(dif_age) +
    period + ego_educ + as.factor(study.year) + scale(ego_age) + scale(extraversion) + scale(fin_restr) +
    romantic + housing.transition + occupation.transition + scale(alter_educ) + scale(as.numeric(alter_age)) +
    scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
    data = dfconfidant[dfconfidant$ego_female == 0, ], family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa",
        optCtrl = list(maxfun = 1e+05)))
# summary(ans_women) summary(ans_men)
ansgender <- list(ans_women, ans_men)

save(ansgender, file = "./results/ans_confidant_gender.RData")
Results of random effects models predicting confidant dissolution at t+1 (1=yes, 0=no), disaggregated by ego's gender
  Women Men
(Intercept) 4.35 (0.52)*** 4.37 (1.18)***
Different gender -0.45 (0.17)** -0.59 (0.30)*
Different education 0.00 (0.17) -0.35 (0.40)
Age difference 0.09 (0.10) 0.53 (0.26)*
Period: wave 2 -> wave 3 0.03 (0.15) -0.57 (0.34)
Research university student -0.42 (0.18)* 0.36 (0.42)
Second year student -0.15 (0.22) -0.54 (0.45)
Third year or higher -0.23 (0.18) -0.17 (0.37)
Age -0.14 (0.08) -0.29 (0.20)
Extraversion 0.15 (0.07)* 0.01 (0.15)
Financial restrictions 0.04 (0.07) 0.06 (0.15)
Romantic relationship -0.23 (0.14) -0.31 (0.30)
Housing transition 0.66 (0.22)** -0.45 (0.49)
Study transition 0.28 (0.30) 0.15 (0.59)
Education -0.12 (0.08) 0.08 (0.19)
Age -0.07 (0.10) -0.56 (0.29)*
Years known -0.03 (0.07) 0.12 (0.16)
Same municipality -0.01 (0.15) -0.29 (0.32)
Same house -0.48 (0.23)* -0.46 (0.46)
Network size 0.30 (0.07)*** 0.32 (0.16)*
Multiplexity -0.57 (0.11)*** -0.65 (0.23)**
Emotional closeness -1.07 (0.12)*** -0.93 (0.26)***
Str. embeddedness focal layer -0.06 (0.07) 0.01 (0.15)
Str. embeddedness other layers 0.04 (0.09) -0.08 (0.20)
AIC 1593.29 416.51
BIC 1731.50 515.99
Log Likelihood -770.64 -182.26
Num. obs. 1504 339
Num. groups: ego:alterid 1162 267
Num. groups: ego 405 108
Var: ego:alterid (Intercept) 0.00 0.00
Var: ego (Intercept) 0.05 0.05
***p < 0.001; **p < 0.01; *p < 0.05

alternative ‘age dissimilarity’ measure

We also use alternative operationalizations of age dissimilarity:

  1. we calculated “sameness” dichotomously: We first assigned each ego to an age category (e.g., 22-25). Alters were then considered similar if they fell into the same category as ego and different otherwise.

  2. we treat age categories as linear, and calculate the the age distance between ego and alter in categories.

  3. if ego and alter fall in the same age category, their age difference == 0, otherwise, we take the difference between ego’s age and alters age category midpoint.

# first, retrieve the original age range, based on which we assigned alters' age (using the range
# midpoint)
df$alter_age_range <- ifelse(df$alter_age == 16, "Jonger dan 18 jaar", ifelse(df$alter_age == 20, "18 tot 21 jaar",
    ifelse(df$alter_age == 23, "22 tot 25 jaar", ifelse(df$alter_age == 28, "26 tot 30 jaar", ifelse(df$alter_age ==
        35, "31 tot 40 jaar", ifelse(df$alter_age == 45, "Ouder dan 40 jaar", NA))))))
# convert ego age to age ranges
df$ego_age_range <- cut(df$ego_age, breaks = c(-Inf, 17, 21, 25, 30, 40, Inf), labels = c("Jonger dan 18 jaar",
    "18 tot 21 jaar", "22 tot 25 jaar", "26 tot 30 jaar", "31 tot 40 jaar", "Ouder dan 40 jaar"), right = TRUE)

# now construct new sameness (inverse to different..) variable, based on whether ego and alter fall
# in same category
df$different_age <- ifelse(df$ego_age_range == df$alter_age_range, 0, 1)

# prop.table(table(df$different_age)) # 37% of ties are between egos and alters falling in the same
# age category df %>% distinct(alterid, .keep_all = TRUE) %>% select(different_age) -> cats
# prop.table(table(cats)) #43% of alters are in a different age range than ego.

# estimate new model:
ans_age2 <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + different_age +
    period + ego_educ + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) +
    romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) +
    scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
    data = df, family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 1e+05)))

# summary(ans_age2)

# save(ans_age2, file='./results/ans_age_sameness.RData')
Results of random effects models predicting tie dissolution at t+1 (1=yes, 0=no), using an alternative operationalization of age dissimilarity
  M6
(Intercept) 2.27 (0.25)***
Friendship -0.32 (0.08)***
Sports partner 1.05 (0.10)***
Study partner 1.15 (0.10)***
Different gender -0.05 (0.09)
Different education -0.14 (0.09)
Different age (range) 0.16 (0.08)*
Period: wave 2 -> wave 3 0.07 (0.08)
Research university student -0.19 (0.10)
Second year student -0.39 (0.13)**
Third year or higher -0.40 (0.11)***
Age -0.17 (0.05)***
Female -0.14 (0.11)
Extraversion 0.11 (0.04)**
Financial restrictions -0.02 (0.04)
Romantic relationship -0.17 (0.08)*
Housing transition 0.30 (0.12)*
Study transition 0.10 (0.15)
Female 0.08 (0.09)
Education -0.12 (0.04)**
Age 0.06 (0.04)
Years known -0.02 (0.04)
Same municipality -0.12 (0.08)
Same house -0.28 (0.13)*
Network size 0.13 (0.03)***
Multiplexity -0.19 (0.05)***
Emotional closeness -0.64 (0.05)***
Str. embeddedness focal layer -0.14 (0.03)***
Str. embeddedness other layers 0.01 (0.05)
AIC 9358.47
BIC 9574.77
Log Likelihood -4648.23
Num. obs. 7924
Num. groups: ego:alterid 3905
Num. groups: ego 514
Var: ego:alterid (Intercept) 0.78
Var: ego (Intercept) 0.27
***p < 0.001; **p < 0.01; *p < 0.05
df$alter_age_range <- factor(df$alter_age_range)
df$dif_agecat <- abs(as.numeric(df$ego_age_range) - as.numeric(df$alter_age_range))

# estimate new model:
ans_age3 <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_agecat) +
    period + ego_educ + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) +
    romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) +
    scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
    data = df, family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 1e+05)))

# summary(ans_age3)

# save(ans_age3, file='./results/coeftab_age_linear.RData')
Results of random effects models predicting tie dissolution at t+1 (1=yes, 0=no), using an alternative operationalization of age dissimilarity
  M6
(Intercept) 2.29 (0.24)***
Best friend -0.32 (0.08)***
Sports partner 1.06 (0.10)***
Study partner 1.16 (0.10)***
Different gender -0.06 (0.09)
Different education -0.15 (0.09)
Age category distance 0.17 (0.05)***
Period: wave 2 -> wave 3 0.05 (0.08)
Research university student -0.16 (0.10)
Second year student -0.37 (0.13)**
Third year or higher -0.36 (0.11)***
Age -0.25 (0.06)***
Female -0.13 (0.11)
Extraversion 0.11 (0.04)**
Financial restrictions -0.02 (0.04)
Romantic relationship -0.18 (0.08)*
Housing transition 0.30 (0.12)*
Study transition 0.04 (0.16)
Female 0.05 (0.09)
Education -0.11 (0.04)**
Age 0.14 (0.05)**
Years known -0.03 (0.04)
Same municipality -0.13 (0.08)
Same house -0.28 (0.13)*
Network size 0.13 (0.03)***
Multiplexity -0.18 (0.05)***
Emotional closeness -0.63 (0.05)***
Str. embeddedness focal layer -0.15 (0.03)***
Str. embeddedness other layers 0.01 (0.05)
AIC 9350.56
BIC 9566.87
Log Likelihood -4644.28
Num. obs. 7924
Num. groups: ego:alterid 3905
Num. groups: ego 514
Var: ego:alterid (Intercept) 0.78
Var: ego (Intercept) 0.27
***p < 0.001; **p < 0.01; *p < 0.05
df$dif_age2 <- ifelse(df$different_age == 1, df$dif_age, 0)

# estimate new model:
ans_age4 <- glmer(Y ~ 1 + (1 | ego) + (1 | ego:alterid) + tie + different_gender + different_educ + scale(dif_age2) +
    period + ego_educ + as.factor(study.year) + scale(ego_age) + ego_female + scale(extraversion) + scale(fin_restr) +
    romantic + housing.transition + occupation.transition + alter_female + scale(alter_educ) + scale(as.numeric(alter_age)) +
    scale(duration) + proximity + scale(size) + multiplex + closeness.t + scale(embed) + scale(embed.ext),
    data = df, family = binomial(link = "logit"), control = glmerControl(optimizer = "bobyqa", optCtrl = list(maxfun = 1e+05)))

# summary(ans_age4)

# save(ans_age4, file='./results/coeftab_age_linear2.RData')
Results of random effects models predicting tie dissolution at t+1 (1=yes, 0=no), using an alternative operationalization of age dissimilarity
  M6
(Intercept) 2.29 (0.24)***
Best friend -0.32 (0.08)***
Sports partner 1.05 (0.10)***
Study partner 1.15 (0.10)***
Different gender -0.05 (0.09)
Different education -0.15 (0.09)
Age difference 0.11 (0.04)**
Period: wave 2 -> wave 3 0.06 (0.08)
Research university student -0.16 (0.10)
Second year student -0.38 (0.13)**
Third year or higher -0.38 (0.11)***
Age -0.17 (0.05)***
Female -0.14 (0.11)
Extraversion 0.12 (0.04)**
Financial restrictions -0.02 (0.04)
Romantic relationship -0.17 (0.08)*
Housing transition 0.30 (0.12)*
Study transition 0.10 (0.15)
Female 0.07 (0.09)
Education -0.12 (0.04)**
Age 0.02 (0.04)
Years known -0.01 (0.04)
Same municipality -0.12 (0.08)
Same house -0.27 (0.13)*
Network size 0.13 (0.03)***
Multiplexity -0.19 (0.05)***
Emotional closeness -0.63 (0.05)***
Str. embeddedness focal layer -0.14 (0.03)***
Str. embeddedness other layers 0.01 (0.05)
AIC 9355.41
BIC 9571.71
Log Likelihood -4646.70
Num. obs. 7924
Num. groups: ego:alterid 3905
Num. groups: ego 514
Var: ego:alterid (Intercept) 0.78
Var: ego (Intercept) 0.27
***p < 0.001; **p < 0.01; *p < 0.05


LS0tDQp0aXRsZTogIk11bHRpdmFyaWF0ZSBhbmFseXNlcyINCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWINCmxpbmstY2l0YXRpb25zOiB0cnVlDQpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCLCAlWScpYCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY3NzOiB0d2Vha3MuY3NzDQogICAgdG9jOiAgdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICB0b2NfZGVwdGg6IDINCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCi0tLQ0KDQpgYGB7ciwgZ2xvYmFsc2V0dGluZ3MsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnLG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9MTAwKSx0aWR5PVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLGNvbW1lbnQgPSAiIz4iLCBjYWNoZT1UUlVFLCBjbGFzcy5zb3VyY2U9YygidGVzdCIpLCBjbGFzcy5vdXRwdXQ9YygidGVzdDMiKSkNCm9wdGlvbnMod2lkdGggPSAxMDApDQpyZ2w6OnNldHVwS25pdHIoKQ0KDQoNCmNvbG9yaXplIDwtIGZ1bmN0aW9uKHgsIGNvbG9yKSB7c3ByaW50ZigiPHNwYW4gc3R5bGU9J2NvbG9yOiAlczsnPiVzPC9zcGFuPiIsIGNvbG9yLCB4KSB9DQpgYGANCg0KDQpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygndG9wJywgJ3JpZ2h0JykpDQoja2xpcHB5OjprbGlwcHkoY29sb3IgPSAnZGFya3JlZCcpDQoja2xpcHB5OjprbGlwcHkodG9vbHRpcF9tZXNzYWdlID0gJ0NsaWNrIHRvIGNvcHknLCB0b29sdGlwX3N1Y2Nlc3MgPSAnRG9uZScpDQpgYGANCg0KDQoNCi0tLSAgDQogIA0KIyBHZXR0aW5nIHN0YXJ0ZWQNCg0KVG8gY29weSB0aGUgY29kZSwgY2xpY2sgdGhlIGJ1dHRvbiBpbiB0aGUgdXBwZXIgcmlnaHQgY29ybmVyIG9mIHRoZSBjb2RlLWNodW5rcy4NCg0KIyMgY2xlYW4gdXANCg0KYGBge3IsIGV2YWw9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0Kcm0obGlzdD1scygpKQ0KZ2MoKQ0KYGBgDQoNCjxicj4NCg0KIyMgZ2VuZXJhbCBjdXN0b20gZnVuY3Rpb25zDQoNCi0gYGZwYWNrYWdlLmNoZWNrYDogQ2hlY2sgaWYgcGFja2FnZXMgYXJlIGluc3RhbGxlZCAoYW5kIGluc3RhbGwgaWYgbm90KSBpbiBSDQotIGBmc2F2ZWA6IEZ1bmN0aW9uIHRvIHNhdmUgZGF0YSB3aXRoIHRpbWUgc3RhbXAgaW4gY29ycmVjdCBkaXJlY3RvcnkNCi0gYGZsb2FkYDogRnVuY3Rpb24gdG8gbG9hZCBSLW9iamVjdHMgdW5kZXIgbmV3IG5hbWVzDQotIGBmdGhlbWVgOiBwcmV0dHkgZ2dwbG90MiB0aGVtZQ0KLSBgZnNob3dkZmA6IFByaW50IG9iamVjdHMgKGB0aWJibGVgIC8gYGRhdGEuZnJhbWVgKSBuaWNlbHkgb24gc2NyZWVuIGluIGAuUm1kYC4NCi0gYGZmaXRgOiBmaXQgYSBzZXJpZXMgb2YgKGhlcmUsIGdlbmVyYWxpemVkIGxpbmVhciBtaXhlZC1lZmZlY3RzKSBtb2RlbHMgDQoNCmBgYHtyfQ0KZnBhY2thZ2UuY2hlY2sgPC0gZnVuY3Rpb24ocGFja2FnZXMpIHsNCiAgICBsYXBwbHkocGFja2FnZXMsIEZVTiA9IGZ1bmN0aW9uKHgpIHsNCiAgICAgICAgaWYgKCFyZXF1aXJlKHgsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgICAgICAgICAgIGluc3RhbGwucGFja2FnZXMoeCwgZGVwZW5kZW5jaWVzID0gVFJVRSkNCiAgICAgICAgICAgIGxpYnJhcnkoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KICAgICAgICB9DQogICAgfSkNCn0NCg0KZnNhdmUgPC0gZnVuY3Rpb24oeCwgZmlsZSwgbG9jYXRpb24gPSAiLi9kYXRhL3Byb2Nlc3NlZC8iLCAuLi4pIHsNCiAgICBpZiAoIWRpci5leGlzdHMobG9jYXRpb24pKQ0KICAgICAgICBkaXIuY3JlYXRlKGxvY2F0aW9uKQ0KICAgIGRhdGVuYW1lIDwtIHN1YnN0cihnc3ViKCJbOi1dIiwgIiIsIFN5cy50aW1lKCkpLCAxLCA4KQ0KICAgIHRvdGFsbmFtZSA8LSBwYXN0ZShsb2NhdGlvbiwgZGF0ZW5hbWUsIGZpbGUsIHNlcCA9ICIiKQ0KICAgIHByaW50KHBhc3RlKCJTQVZFRDogIiwgdG90YWxuYW1lLCBzZXAgPSAiIikpDQogICAgc2F2ZSh4LCBmaWxlID0gdG90YWxuYW1lKQ0KfQ0KDQpmbG9hZCAgPC0gZnVuY3Rpb24oZmlsZU5hbWUpew0KICBsb2FkKGZpbGVOYW1lKQ0KICBnZXQobHMoKVtscygpICE9ICJmaWxlTmFtZSJdKQ0KfQ0KDQojZXh0cmFmb250Ojpmb250X2ltcG9ydChwYXRocyA9IGMoIkM6L1VzZXJzL3UyNDQxNDcvRG93bmxvYWRzL0pvc3QvIiwgcHJvbXB0ID0gRkFMU0UpKQ0KZnRoZW1lIDwtIGZ1bmN0aW9uKCkgew0KICANCiAgI2Rvd25sb2FkIGZvbnQgYXQgaHR0cHM6Ly9mb250cy5nb29nbGUuY29tL3NwZWNpbWVuL0pvc3QvDQogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAiSm9zdCIpICsNCiAgICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkpvc3QiLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJKb3N0IE1lZGl1bSIpLA0KICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApLA0KICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpLA0KICAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkpvc3QiLCBmYWNlID0gImJvbGQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IHJlbCgwLjc1KSwgaGp1c3QgPSAwKSwNCiAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiZ3JleTkwIiwgY29sb3IgPSBOQSksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQp9DQoNCmZzaG93ZGYgPC0gZnVuY3Rpb24oeCwgZGlnaXRzID0gMiwgLi4uKSB7DQogICAga25pdHI6OmthYmxlKHgsIGRpZ2l0cyA9IGRpZ2l0cywgImh0bWwiLCAuLi4pICU+JQ0KICAgICAgICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpKSAlPiUNCiAgICAgICAga2FibGVFeHRyYTo6c2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjMwMHB4IikNCn0NCg0KZmZpdCA8LSBmdW5jdGlvbihmb3JtdWxhLCBkYXRhKSB7DQogIHRyeUNhdGNoKHsNCiAgICBtb2RlbCA8LSBsbWU0OjpnbG1lcihmb3JtdWxhLCBkYXRhID0gZGF0YSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJsb2dpdCIpLA0KICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBnbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIsIG9wdEN0cmwgPSBsaXN0KG1heGZ1biA9IDFlNSkpKQ0KICAgIGNhdCgiRml0dGluZyBtb2RlbDoiLCBhcy5jaGFyYWN0ZXIoZm9ybXVsYSksICJcbiIpDQogICAgc3VtbWFyeShtb2RlbCkNCiAgICBjYXQoIlxuIikNCiAgICByZXR1cm4obW9kZWwpDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgIGNhdCgiRXJyb3IgZml0dGluZyBtb2RlbDoiLCBhcy5jaGFyYWN0ZXIoZm9ybXVsYSksICJcbiIpDQogICAgY2F0KCJFcnJvciBtZXNzYWdlOiIsIGNvbmRpdGlvbk1lc3NhZ2UoZSksICJcbiIpDQogICAgcmV0dXJuKE5VTEwpDQogIH0pDQp9DQoNCmBgYA0KDQpgYGB7ciBmb250cywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQojIGltcG9ydCBmb250IEpPU1QNCiNleHRyYWZvbnQ6OmZvbnRfaW1wb3J0KHBhdHRlcm4gPSAiSm9zdCIpDQpleHRyYWZvbnQ6OmxvYWRmb250cyhkZXZpY2U9IndpbiIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCiMgU2V0IGRlZmF1bHQgdGhlbWUgYW5kIGZvbnQgc3R1ZmYNCnRoZW1lX3NldChmdGhlbWUoKSkNCnVwZGF0ZV9nZW9tX2RlZmF1bHRzKCJ0ZXh0IiwgbGlzdChmYW1pbHkgPSAiSm9zdCIsIGZvbnRmYWNlID0gInBsYWluIikpDQp1cGRhdGVfZ2VvbV9kZWZhdWx0cygibGFiZWwiLCBsaXN0KGZhbWlseSA9ICJKb3N0IiwgZm9udGZhY2UgPSAicGxhaW4iKSkNCg0KI25pY2UgY29sb3IgcGFsZXR0ZQ0KY2JQYWxldHRlIDwtIGMoIiM5OTk5OTkiLCAiI0U2OUYwMCIsICIjNTZCNEU5IiwgIiMwMDlFNzMiLCAiI0YwRTQ0MiIsICIjMDA3MkIyIiwgIiNENTVFMDAiLCAiI0NDNzlBNyIpDQpgYGANCg0KPGJyPg0KDQojIyBuZWNlc3NhcnkgcGFja2FnZXMNCg0KLSBgbG1lNGA6IGZpdHRpbmcgcmFuZG9tIGVmZmVjdHMgbW9kZWxzDQotIGBtbG1oZWxwcmAsIGNvbnRhaW5pbmcgdGhlIGBpY2NgIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgaW50cmFjbGFzcyBjb3JyZWxhdGlvbiBmb3IgbXVsdGlsZXZlbCBtb2RlbHMNCi0gYGxtdGVzdGA6IGRpYWdub3N0aWMgdGVzdHMgKGxpa2VsaWhvb2QgcmF0aW8gdGVzdCkNCi0gYGNhcmA6IGNvbXBhbmlvbiBhcHBsaWVkIHJlZ3Jlc3Npb24gKGNhbGN1bGF0ZSBWSUYpDQotIGB0ZXhyZWdgOiBvdXRwdXQgdG8gSFRNTCB0YWJsZQ0KLSBgZ2dwdWJyYDogZm9ybWF0IGdncGxvdDIgcGxvdHMNCi0gYGdnaDR4YDogaGFja3MgZm9yIGdncGxvdDINCg0KDQpgYGB7ciwgcmVzdWx0cz0naGlkZScsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwYWNrYWdlcyA9IGMoImxtZTQiLCAibWxtaGVscHIiLCAibG10ZXN0IiwgInRleHRyZWciLCAiY2FyIiwgImdncGxvdDIiLCAicGFyYWxsZWwiLCAiZ2dwdWJyIiwgImdnaDR4IikNCmZwYWNrYWdlLmNoZWNrKHBhY2thZ2VzKQ0Kcm0ocGFja2FnZXMpDQpgYGAgDQoNCjxicj4NCg0KIyMgbG9hZCBkYXRhLXNldA0KDQpMb2FkIHRoZSByZXBsaWNhdGVkIGRhdGEtc2V0IChjb25zdHJ1Y3RlZCBbaGVyZV0oaHR0cHM6Ly9uZXRjaGFuZ2UubmV0bGlmeS5hcHAvcHJlcC5odG1sKSkuIFRvIGxvYWQgdGhlc2UgZmlsZSwgYWRqdXN0IHRoZSBmaWxlbmFtZSBpbiB0aGUgZm9sbG93aW5nIGNvZGUgc28gdGhhdCBpdCBtYXRjaGVzIHRoZSBtb3N0IHJlY2VudCB2ZXJzaW9uIG9mIHRoZSBgLlJEYWAgZmlsZSB5b3UgaGF2ZSBpbiB5b3VyIGAuL2RhdGEvcHJvY2Vzc2VkL2AgZm9sZGVyLg0KDQpZb3UgbWF5IGFsc28gb2J0YWluIHRoZW0gYnkgZG93bmxvYWRpbmc6IGByIHhmdW46OmVtYmVkX2ZpbGUoIi4vZGF0YV9zaGFyZWQvZGF0YV9uZXN0ZWQuUkRhIilgDQoNCg0KYGBge3IsZXZhbD1GQUxTRX0NCiNsaXN0IGZpbGVzIGluIHByb2Nlc3NlZCBkYXRhIGZvbGRlcg0KbGlzdC5maWxlcygiLi9kYXRhL3Byb2Nlc3NlZC8iKQ0KDQojZ2V0IHRvZGF5cyBkYXRlOg0KdG9kYXkgPC0gZ3N1YigiLSIsICIiLCBTeXMuRGF0ZSgpKQ0KDQojdXNlIGZsb2FkDQpkZiA8LSBmbG9hZChwYXN0ZTAoIi4vZGF0YS9wcm9jZXNzZWQvIiwgdG9kYXksICJkYXRhX25lc3RlZC5SRGEiKSkNCmBgYA0KDQo8YnI+DQoNCiMjIGxhc3QgYWx0ZXJhdGlvbnMNCg0KLSBtYWtlIFkgaW5kaWNhdGUgdGllICoqbG9zcyoqIGluc3RlYWQgb2YgdGllICoqbWFpbnRlbmFuY2UqKg0KLSBtYWtlIFggcmVmbGVjdCAqKmRpc3NpbWlsYXJpdHkqKiBpbnN0ZWFkIG9mICoqc2ltaWxhcml0eSoqDQotIHN0YW5kYXJkaXplIGVtYmVkZGVkbmVzcyBpbiBvdGhlciBuZXR3b3JrIGxheWVycw0KLSBwcm94aW1pdHkgbGV2ZWxzDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpkZiRZIDwtIGlmZWxzZShkZiRZPT0xLCAwLCAxKQ0KDQpkZiRkaWZmZXJlbnRfZ2VuZGVyIDwtIGlmZWxzZShkZiRzYW1lX2dlbmRlcj09MSwgMCwgMSkNCmRmJGRpZmZlcmVudF9lZHVjIDwtIGlmZWxzZShkZiRzaW1fZWR1Yz09MSwgMCwgMSkNCg0KZGYkZW1iZWQuZXh0IDwtIGRmJGVtYmVkLmV4dC8zDQoNCmRmJHByb3hpbWl0eSA8LSBmYWN0b3IoZGYkcHJveGltaXR5LCBsZXZlbHMgPSBjKCJmYXIiLCJjbG9zZSIsInJvb21tYXRlIikpDQpgYGANCg0KPGJyPg0KDQojIG11bHRpbGV2ZWwgbW9kZWwNCg0KIyMgdmFyaWFuY2UgcGFydGl0aW9uaW5nDQoNClN0YXJ0aW5nIHdpdGggbnVsbCBtb2RlbCAob25lLWxldmVsLCBhc3N1bWluZyBpbmRlcGVuZGVudCBvYnNlcnZhdGlvbnMpLiBUaGVuIGluY2x1ZGUgcmFuZG9tIGVnby1sZXZlbCBpbnRlcmNlcHQsIGFuZCByYW5kb20gZWdvLWFsdGVyIGNvbWJpbmF0aW9uIGludGVyY2VwdDoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojbnVsbC9mbGF0IG1vZGVsIChhc3N1bWluZyBubyBjbHVzdGVyaW5nIGF0IGFsbCkNCm1vZGVsMDEgPC0gZ2xtKFkgfiAxLCBkYXRhID0gZGYsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkNCnN1bW1hcnkobW9kZWwwMSkNCg0KI2FkZCByYW5kb20gZWdvLWxldmVsIGludGVyY2VwdA0KbW9kZWwwMiA8LSBnbG1lcihZIH4gMSArICgxIHwgZWdvKSwgZGF0YSA9IGRmLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IikpDQpzdW1tYXJ5KG1vZGVsMDIpDQppY2MobW9kZWwwMikNCg0KI2FkZCByYW5kb20gZWdvLWFsdGVyIGNvbWJpIGludGVyY2VwdA0KbW9kZWwwMyA8LSBnbG1lcihZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpLCBkYXRhID0gZGYsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSkNCnN1bW1hcnkobW9kZWwwMykNCmljYyhtb2RlbDAzKQ0KDQojcmV0cmlldmUgdmFyaWFuY2UgY29tcG9uZW50cw0KdmFyY29tcCA8LSBWYXJDb3JyKG1vZGVsMDMpDQoNCiMxLiBlZ28tbGV2ZWwNCnZhcjMgPC0gdmFyY29tcCQnZWdvJ1sxXQ0KIzIuIGR5YWQtbGV2ZWwNCnZhcjIgPC0gdmFyY29tcCQnZWdvOmFsdGVyaWQnWzFdDQojMy4gbGF0ZW50IHZhcmlhYmxlIG1ldGhvZDogc3Vic3RpdHV0ZSB0aGUgY29uc3RhbnQgcXVhbnRpdHkgz4BeMi8zIGZvciB0aGUgbGV2ZWwtMSB2YXJpYW5jZS4NCnZhcjEgPC0gKHBpXjIpLzMNCg0KI3ZwYzMgPC0gdmFyMy8odmFyMSt2YXIyK3ZhcjMpDQojdnBjMiA8LSAodmFyMiArIHZhcjMpLyh2YXIxK3ZhcjIrdmFyMykNCiMxIC0gdnBjMg0KDQojZmluYWwgJ251bGwgbW9kZWwnLCBpbmNsdWRpbmcgcGVyaW9kIGFuZCBzb2NpYWwgcm9sZSBmaXhlZCBlZmZlY3RzDQptb2RlbDAgPC0gZ2xtZXIoWSB+IDEgKyB0aWUgKyBwZXJpb2QgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSwgZGF0YSA9IGRmLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IikpDQpzdW1tYXJ5KG1vZGVsMCkNCmljYyhtb2RlbDApDQoNCiN2YXJpYW5jZSBwYXJ0aXRpb25pbmc6DQp2YXJjb21wIDwtIFZhckNvcnIobW9kZWwwKQ0KDQojMS4gZWdvLWxldmVsDQp2YXIzIDwtIHZhcmNvbXAkJ2VnbydbMV0NCiMyLiBkeWFkLWxldmVsDQp2YXIyIDwtIHZhcmNvbXAkJ2VnbzphbHRlcmlkJ1sxXQ0KIzMuIGxhdGVudCB2YXJpYWJsZSBtZXRob2Q6IHN1YnN0aXR1dGUgdGhlIGNvbnN0YW50IHF1YW50aXR5IM+AXjIvMyBmb3IgdGhlIGxldmVsLTEgdmFyaWFuY2UuDQp2YXIxIDwtIChwaV4yKS8zDQoNCiN2cGMzIDwtIHZhcjMvKHZhcjErdmFyMit2YXIzKQ0KI3ZwYzIgPC0gKHZhcjIgKyB2YXIzKS8odmFyMSt2YXIyK3ZhcjMpDQojMSAtIHZwYzINCg0KI3BlcmZvcm0gbGlrZWxpaG9vZCByYXRpbyB0ZXN0IGZvciBkaWZmZXJlbmNlcyBpbiBtb2RlbHMNCmxydGVzdChtb2RlbDAxLCBtb2RlbDAyLCBtb2RlbDAzLCBtb2RlbDApDQpgYGANCg0KPGJyPg0KDQojIyB0aWVzIG5lc3RlZCBpbiBhbHRlcnMvZHlhZHMNCg0KLSBNMCA6IG51bGwgKGVtcHR5KSBtb2RlbCBpbmNsdWRpbmcgcmFuZG9tIGludGVyY2VwdHMgZm9yIGVnbyBhbmQgZWdvOmFsdGVyDQotIE0xIDogdGllICsgcGVyaW9kDQotIE0yIDogdGllICsgcGVyaW9kICsgZGlzc2ltaWxhcml0eQ0KLSBNMyA6IHRpZSArIHBlcmlvZCArIGRpc3NpbWlsYXJpdHkgKyBjb250cm9scw0KLSBNNCA6IHRpZSArIHBlcmlvZCArIGRpc3NpbWlsYXJpdHkgKyBjb250cm9scyArIGNsb3NlbmVzcyArIG11bHRpcGxleGl0eQ0KLSBNNSA6IHRpZSArIHBlcmlvZCArIGRpc3NpbWlsYXJpdHkgKyBjb250cm9scyArIHN0cnVjdHVyYWwxICsgc3RydWN0dXJhbDINCi0gTTYgOiB0aWUgKyBwZXJpb2QgKyBkaXNzaW1pbGFyaXR5ICsgY29udHJvbHMgKyBjbG9zZW5lc3MgKyBtdWx0aXBsZXhpdHkgKyBzdHJ1Y3R1cmFsMSArIHN0cnVjdHVyYWwyDQotIE03IDogdGllICsgcGVyaW9kICsgZGlzc2ltaWxhcml0eSArIGNvbnRyb2xzICsgY2xvc2VuZXNzICsgbXVsdGlwbGV4aXR5ICsgc3RydWN0dXJhbDEgKyBzdHJ1Y3R1cmFsMiArIGRpc3NpbWlsYXJpdHk6dGllDQotIE04IDogdGllICsgcGVyaW9kICsgZGlzc2ltaWxhcml0eSArIGNvbnRyb2xzICsgY2xvc2VuZXNzOnRpZSArIG11bHRpcGxleGl0eTp0aWUgKyBzdHJ1Y3R1cmFsMTp0aWUgKyBzdHJ1Y3R1cmFsMjp0aWUNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojbGlzdCBvZiBtb2RlbHMNCmZvcm11bGEgPC0gbGlzdCgNCiAgDQogICMwLiBudWxsIG1vZGVsDQogIFkgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCksDQogIA0KICAjMSBpbmNsLiBmaXhlZCBlZmZlY3RzIG9mIHJvbGUgYW5kIHRpbWUpDQogIFkgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBwZXJpb2QsDQogIA0KICAjMi4gZGlzc2ltaWxhcml0eQ0KICBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QsDQoNCiAgIzMuIGNvbnRyb2xzDQogIFkgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSArIHBlcmlvZCArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSwNCiAgDQogICM0LiByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcyBhcyBtZWRpYXRvcg0KICBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCwNCiAgDQogICM1LiBzdHIuIGVtYmVkZGVkbmVzcyBhcyBtZWRpYXRvcg0KICBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBzY2FsZShlbWJlZCkgKyBzY2FsZShlbWJlZC5leHQpLA0KDQogICM2LiBib3RoIHJlbGF0aW9uYWwgYW5kIHN0cnVjdHVyYWwNCiAgWSB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgcGVyaW9kICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgbXVsdGlwbGV4ICsgY2xvc2VuZXNzLnQgKyBzY2FsZShlbWJlZCkgKyBzY2FsZShlbWJlZC5leHQpLA0KICANCiAgIzcuIGludGVyYWN0aW9uIGRpc3NpbWlsYXJpdHkgKiB0aWUgdHlwZQ0KICBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCArIHNjYWxlKGVtYmVkKSArIHNjYWxlKGVtYmVkLmV4dCkgKyBkaWZmZXJlbnRfZ2VuZGVyOnRpZSArIGRpZmZlcmVudF9lZHVjOnRpZSArIHNjYWxlKGRpZl9hZ2UpOnRpZSwNCiAgDQogICM4LiBpbnRlcmFjdGlvbiBtZWRpYXRvcnMgKiB0aWUgdHlwZQ0KICBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCArIHNjYWxlKGVtYmVkKSArIHNjYWxlKGVtYmVkLmV4dCkgICsgY2xvc2VuZXNzLnQ6dGllICsgbXVsdGlwbGV4OnRpZSArIHNjYWxlKGVtYmVkKTp0aWUgKyBzY2FsZShlbWJlZC5leHQpOnRpZQ0KKQ0KDQojZXN0aW1hdGUgdXNpbmcgYGZmaXRgDQphbnMgPC0gbGFwcGx5KGZvcm11bGEsIGZmaXQsIGRhdGEgPSBkZikNCg0KI3VzZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgdG8gY29tcGFyZSBtb2RlbHMNCmRvLmNhbGwobHJ0ZXN0LCBhbnMpDQoNCiNzdW1tYXJ5KGFuc1tbM11dKQ0KDQojc2F2ZSBvdXRwdXQNCnNhdmUoYW5zLCBmaWxlPSIuL3Jlc3VsdHMvYW5zX2FsbC5SRGF0YSIpDQoNCmBgYA0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCnRleHJlZzo6aHRtbHJlZyhhbnMsDQogICAgICAgIGZpbGU9Ii4vcmVzdWx0cy9jb2VmdGFiX2FsbC5odG1sIiwNCiAgICAgICAgY2FwdGlvbj0iUmVzdWx0cyBvZiByYW5kb20gZWZmZWN0cyBtb2RlbHMgcHJlZGljdGluZyB0aWUgZGlzc29sdXRpb24gYXQgdCsxICgxPXllcywgMD1ubykiLCBjYXB0aW9uLmFib3ZlID0gVFJVRSwgDQogICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IHBhc3RlMCgiTSIsYygwOjgpKSwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSBjKCIoSW50ZXJjZXB0KSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJlc3QgZnJpZW5kIiwgIlNwb3J0cyBwYXJ0bmVyIiwgIlN0dWR5IHBhcnRuZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmlvZDogd2F2ZSAyIC0+IHdhdmUgMyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlmZmVyZW50IGdlbmRlciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIiwgIkFnZSBkaWZmZXJlbmNlIiwNCiAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNlYXJjaCB1bml2ZXJzaXR5IHN0dWRlbnQiLCAiU2Vjb25kIHllYXIgc3R1ZGVudCIsICJUaGlyZCB5ZWFyIG9yIGhpZ2hlciIsICJBZ2UgIiwgIkZlbWFsZSAiLCAiRXh0cmF2ZXJzaW9uIiwgIkZpbmFuY2lhbCByZXN0cmljdGlvbnMiLCAiUm9tYW50aWMgcmVsYXRpb25zaGlwIiwgIkhvdXNpbmcgdHJhbnNpdGlvbiIsICJTdHVkeSB0cmFuc2l0aW9uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIiwgIkVkdWNhdGlvbiIsICJBZ2UiLCAiWWVhcnMga25vd24iLCAiU2FtZSBtdW5pY2lwYWxpdHkiLCAiU2FtZSBob3VzZSIsICJOZXR3b3JrIHNpemUiLCAiTXVsdGlwbGV4aXR5IiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MiLCAiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIiLCAiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIiwgIkRpZmZlcmVudCBnZW5kZXIgOiBGcmllbmRzaGlwIiwgIkRpZmZlcmVudCBnZW5kZXIgOiBTcG9ydHMgcGFydG5lciIsICJEaWZmZXJlbnQgZ2VuZGVyIDogU3R1ZHkgcGFydG5lciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIDogRnJpZW5kc2hpcCIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIDogU3BvcnRzIHBhcnRuZXIiLCAiRGlmZmVyZW50IGVkdWNhdGlvbiA6IFN0dWR5IHBhcnRuZXIiLCAiQWdlIGRpZmZlcmVuY2UgOiBGcmllbmRzaGlwIiwgIkFnZSBkaWZmZXJlbmNlIDogU3BvcnRzIHBhcnRuZXIiLCAiQWdlIGRpZmZlcmVuY2UgOiBTdHVkeSBwYXJ0bmVyIiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MgOiBGcmllbmRzaGlwIiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MgOiBTcG9ydHMgcGFydG5lciIsIkVtb3Rpb25hbCBjbG9zZW5lc3MgOiBTdHVkeSBwYXJ0bmVyIiwgIk11bHRpcGxleGl0eSA6IEZyaWVuZHNoaXAiLCAiTXVsdGlwbGV4aXR5IDogU3BvcnRzIHBhcnRuZXIiLCAiTXVsdGlwbGV4aXR5IDogU3R1ZHkgcGFydG5lciIsICJTdHIuIGVtYmVkZGVkbmVzcyBmb2NhbCBsYXllciA6IEZyaWVuZHNoaXAiLCJTdHIuIGVtYmVkZGVkbmVzcyBmb2NhbCBsYXllciA6IFNwb3J0cyBwYXJ0bmVyIiwiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIgOiBTdHVkeSBwYXJ0bmVyIiwiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIDogRnJpZW5kc2hpcCIsIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyA6IFNwb3J0cyBwYXJ0bmVyIiwiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIDogU3R1ZHkgcGFydG5lciIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUNCiAgICAgICAgKQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpodG1sdG9vbHM6OnRhZ3MkZGl2KA0KICBzdHlsZSA9ICJoZWlnaHQ6IDYwMHB4OyBvdmVyZmxvdy15OiBzY3JvbGw7IiwNCiAgaHRtbHRvb2xzOjppbmNsdWRlSFRNTCgiLi9yZXN1bHRzL2NvZWZ0YWJfYWxsLmh0bWwiKQ0KKQ0KYGBgDQoNCg0KLS0tLSANCg0KPGJyPg0KDQojIyBzZXBlcmF0ZSBhbmFseXNlcyBieSB0aWUgdHlwZSB7LnRhYnNldCAudGFic2V0LWZhZGV9DQoNCkhlcmUsIHdlIGRyb3AgdGhlIHJhbmRvbSBhbHRlci1pbnRlcmNlcHQuDQoNCg0KYGBge3IsIHNlcGFuYWx5c2VzLCBldmFsPUZBTFNFLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJ30NCiMxLiBzZXBlcmF0ZSBkYXRhZnJhbWVzIGZvciBlYWNoIHRpZSB0eXBlDQpkZmNvbmZpZGFudCA8LSBkZltkZiR0aWU9PSJDb25maWRhbnQiLF0NCmRmZnJpZW5kIDwtIGRmW2RmJHRpZT09IkZyaWVuZCIsXQ0KZGZzcG9ydCA8LSBkZltkZiR0aWU9PSJTcG9ydCIsXQ0KZGZzdHVkeSA8LSBkZltkZiR0aWU9PSJTdHVkeSIsXQ0KDQojMi4gbmV3IGxpc3Qgb2YgZm9ybXVsYXMNCiNoZXJlLCBleGNsdWRlIHRoZSByYW5kb20gYWx0ZXItaW50ZXJjZXB0IChhcyBubyBuZXN0aWcgb2YgdGllcyBpbiBhbHRlcnMvZHlhZHMpDQojZmV3ZXIgbW9kZWxzLCBzaW5jZSB3ZSBkb250IGluY2x1ZGUgdGllLWxldmVsIHJlbGF0aW9uYWwgcm9sZSBhcyBhbiAoaW50ZXJhY3Rpb24pIHZhcmlhYmxlDQoNCmZvcm11bGEyIDwtIGxpc3QoDQogICMwLiBtYWluIHZhcmlhYmxlcw0KICBZIH4gMSArICgxIHwgZWdvKSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgcGVyaW9kLA0KDQogICMxLiBjb250cm9scw0KICBZIH4gMSArICgxIHwgZWdvKSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgcGVyaW9kICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpLA0KICANCiAgIzIuIHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzIGFzIG1lZGlhdG9yDQogIFkgfiAxICsgKDEgfCBlZ28pICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCwNCiAgDQogICMzLiBzdHIuIGVtYmVkZGVkbmVzcyBhcyBtZWRpYXRvcg0KICBZIH4gMSArICgxIHwgZWdvKSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgcGVyaW9kICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSwNCg0KICAjNC4gYm90aCByZWxhdGlvbmFsIGFuZCBzdHJ1Y3R1cmFsDQogIFkgfiAxICsgKDEgfCBlZ28pICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCArIHNjYWxlKGVtYmVkKSArIHNjYWxlKGVtYmVkLmV4dCkNCiAgKQ0KDQojMy4gZXN0aW1hdGUNCmFuc2NvbmZpZGFudCA8LSBsYXBwbHkoZm9ybXVsYTIsIGZmaXQsIGRhdGEgPSBkZmNvbmZpZGFudCkNCmFuc2ZyaWVuZCA8LSBsYXBwbHkoZm9ybXVsYTIsIGZmaXQsIGRhdGEgPSBkZmZyaWVuZCkNCmFuc3Nwb3J0IDwtIGxhcHBseShmb3JtdWxhMiwgZmZpdCwgZGF0YSA9IGRmc3BvcnQpDQphbnNzdHVkeSA8LSBsYXBwbHkoZm9ybXVsYTIsIGZmaXQsIGRhdGEgPSBkZnN0dWR5KQ0KDQojbGlzdCBvdXRwdXQNCmFuc19zZXBlcmF0ZSA8LSBsaXN0KGFuc2NvbmZpZGFudCxhbnNmcmllbmQsYW5zc3BvcnQsYW5zc3R1ZHkpDQoNCiNzYXZlIGxpc3RlZCBvdXRwdXQNCnNhdmUoYW5zX3NlcGVyYXRlLCBmaWxlPSIuL3Jlc3VsdHMvYW5zX3NlcGFyYXRlX2xpc3QuUkRhdGEiKQ0KYGBgDQoNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsb2FkKCIuL3Jlc3VsdHMvYW5zX3NlcGFyYXRlX2xpc3QuUkRhdGEiKQ0KDQphbnNfc2VwZXJhdGVbWzFdXSAtPiBhbnNjb25maWRhbnQNCmFuc19zZXBlcmF0ZVtbMl1dIC0+IGFuc2ZyaWVuZA0KYW5zX3NlcGVyYXRlW1szXV0gLT4gYW5zc3BvcnQNCmFuc19zZXBlcmF0ZVtbNF1dIC0+IGFuc3N0dWR5DQoNCnRleHJlZzo6aHRtbHJlZyhhbnNjb25maWRhbnQsDQogICAgICAgIGZpbGU9Ii4vcmVzdWx0cy9jb2VmdGFiX2NvbmZpZGFudC5odG1sIiwNCiAgICAgICAgY2FwdGlvbj0iUmVzdWx0cyBvZiByYW5kb20gZWZmZWN0cyBtb2RlbHMgcHJlZGljdGluZyBjb25maWRhbnQgdGllIGRpc3NvbHV0aW9uIGF0IHQrMSAoMT15ZXMsIDA9bm8pIiwgY2FwdGlvbi5hYm92ZSA9IFRSVUUsIA0KICAgICAgICAgICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IHBhc3RlMCgiTSIsMDo0KSwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSBjKCIoSW50ZXJjZXB0KSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpZmZlcmVudCBnZW5kZXIiLCAiRGlmZmVyZW50IGVkdWNhdGlvbiIsICJBZ2UgZGlmZmVyZW5jZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVyaW9kOiB3YXZlIDIgLT4gd2F2ZSAzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNlYXJjaCB1bml2ZXJzaXR5IHN0dWRlbnQiLCAiU2Vjb25kIHllYXIgc3R1ZGVudCIsICJUaGlyZCB5ZWFyIG9yIGhpZ2hlciIsICJBZ2UgIiwgIkZlbWFsZSAiLCAiRXh0cmF2ZXJzaW9uIiwgIkZpbmFuY2lhbA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3Rpb25zIiwgIlJvbWFudGljIHJlbGF0aW9uc2hpcCIsICJIb3VzaW5nIHRyYW5zaXRpb24iLCAiU3R1ZHkgdHJhbnNpdGlvbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSIsICJFZHVjYXRpb24iLCAiQWdlIiwgIlllYXJzIGtub3duIiwgIlNhbWUgbXVuaWNpcGFsaXR5IiwgIlNhbWUgaG91c2UiLCAiTmV0d29yayBzaXplIiwgIk11bHRpcGxleGl0eSIsICJFbW90aW9uYWwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlbmVzcyIsICJTdHIuIGVtYmVkZGVkbmVzcyBmb2NhbCBsYXllciIsICJTdHIuIGVtYmVkZGVkbmVzcyBvdGhlciBsYXllcnMiKSwNCiAgICAgICAgZGlnaXRzPTIsIHNpbmdsZS5yb3cgPSBUUlVFKQ0KDQp0ZXhyZWc6Omh0bWxyZWcoYW5zZnJpZW5kLA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9mcmllbmQuaHRtbCIsDQogICAgICAgIGNhcHRpb249IlJlc3VsdHMgb2YgcmFuZG9tIGVmZmVjdHMgbW9kZWxzIHByZWRpY3RpbmcgZnJpZW5kc2hpcCBkaXNzb2x1dGlvbiBhdCB0KzEgKDE9eWVzLCAwPW5vKSIsIGNhcHRpb24uYWJvdmUgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gcGFzdGUwKCJNIiwwOjQpLA0KICAgICAgICBjdXN0b20uY29lZi5uYW1lcyA9IGMoIihJbnRlcmNlcHQpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlmZmVyZW50IGdlbmRlciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIiwgIkFnZSBkaWZmZXJlbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQZXJpb2Q6IHdhdmUgMiAtPiB3YXZlIDMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc2VhcmNoIHVuaXZlcnNpdHkgc3R1ZGVudCIsICJTZWNvbmQgeWVhciBzdHVkZW50IiwgIlRoaXJkIHllYXIgb3IgaGlnaGVyIiwgIkFnZSAiLCAiRmVtYWxlICIsICJFeHRyYXZlcnNpb24iLCAiRmluYW5jaWFsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGlvbnMiLCAiUm9tYW50aWMgcmVsYXRpb25zaGlwIiwgIkhvdXNpbmcgdHJhbnNpdGlvbiIsICJTdHVkeSB0cmFuc2l0aW9uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIiwgIkVkdWNhdGlvbiIsICJBZ2UiLCAiWWVhcnMga25vd24iLCAiU2FtZSBtdW5pY2lwYWxpdHkiLCAiU2FtZSBob3VzZSIsICJOZXR3b3JrIHNpemUiLCAiTXVsdGlwbGV4aXR5IiwgIkVtb3Rpb25hbA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VuZXNzIiwgIlN0ci4gZW1iZWRkZWRuZXNzIGZvY2FsIGxheWVyIiwgIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUpDQoNCnRleHJlZzo6aHRtbHJlZyhhbnNzcG9ydCwNCiAgICAgICAgZmlsZT0iLi9yZXN1bHRzL2NvZWZ0YWJfc3BvcnQuaHRtbCIsDQogICAgICAgIGNhcHRpb249IlJlc3VsdHMgb2YgcmFuZG9tIGVmZmVjdHMgbW9kZWxzIHByZWRpY3Rpbmcgc3BvcnRzIHBhcnRuZXJzaGlwIGRpc3NvbHV0aW9uIGF0IHQrMSAoMT15ZXMsIDA9bm8pIiwgY2FwdGlvbi5hYm92ZSA9IFRSVUUsIA0KICAgICAgICAgICAgICAgICAgICBjdXN0b20ubW9kZWwubmFtZXMgPSBwYXN0ZTAoIk0iLDA6NCksDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gYygiKEludGVyY2VwdCkiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaWZmZXJlbnQgZ2VuZGVyIiwgIkRpZmZlcmVudCBlZHVjYXRpb24iLCAiQWdlIGRpZmZlcmVuY2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmlvZDogd2F2ZSAyIC0+IHdhdmUgMyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVzZWFyY2ggdW5pdmVyc2l0eSBzdHVkZW50IiwgIlNlY29uZCB5ZWFyIHN0dWRlbnQiLCAiVGhpcmQgeWVhciBvciBoaWdoZXIiLCAiQWdlICIsICJGZW1hbGUgIiwgIkV4dHJhdmVyc2lvbiIsICJGaW5hbmNpYWwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0aW9ucyIsICJSb21hbnRpYyByZWxhdGlvbnNoaXAiLCAiSG91c2luZyB0cmFuc2l0aW9uIiwgIlN0dWR5IHRyYW5zaXRpb24iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUiLCAiRWR1Y2F0aW9uIiwgIkFnZSIsICJZZWFycyBrbm93biIsICJTYW1lIG11bmljaXBhbGl0eSIsICJTYW1lIGhvdXNlIiwgIk5ldHdvcmsgc2l6ZSIsICJNdWx0aXBsZXhpdHkiLCAiRW1vdGlvbmFsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zZW5lc3MiLCAiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIiLCAiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIiksDQogICAgICAgIGRpZ2l0cz0yLCBzaW5nbGUucm93ID0gVFJVRSkNCg0KdGV4cmVnOjpodG1scmVnKGFuc3N0dWR5LA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9zdHVkeS5odG1sIiwNCiAgICAgICAgY2FwdGlvbj0iUmVzdWx0cyBvZiByYW5kb20gZWZmZWN0cyBtb2RlbHMgcHJlZGljdGluZyBzdHVkeSBwYXJ0bmVyc2hpcCBkaXNzb2x1dGlvbiBhdCB0KzEgKDE9eWVzLCAwPW5vKSIsIGNhcHRpb24uYWJvdmUgPSBUUlVFLCANCiAgICAgICAgICAgICAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gcGFzdGUwKCJNIiwwOjQpLA0KICAgICAgICBjdXN0b20uY29lZi5uYW1lcyA9IGMoIihJbnRlcmNlcHQpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlmZmVyZW50IGdlbmRlciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIiwgIkFnZSBkaWZmZXJlbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQZXJpb2Q6IHdhdmUgMiAtPiB3YXZlIDMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc2VhcmNoIHVuaXZlcnNpdHkgc3R1ZGVudCIsICJTZWNvbmQgeWVhciBzdHVkZW50IiwgIlRoaXJkIHllYXIgb3IgaGlnaGVyIiwgIkFnZSAiLCAiRmVtYWxlICIsICJFeHRyYXZlcnNpb24iLCAiRmluYW5jaWFsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGlvbnMiLCAiUm9tYW50aWMgcmVsYXRpb25zaGlwIiwgIkhvdXNpbmcgdHJhbnNpdGlvbiIsICJTdHVkeSB0cmFuc2l0aW9uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIiwgIkVkdWNhdGlvbiIsICJBZ2UiLCAiWWVhcnMga25vd24iLCAiU2FtZSBtdW5pY2lwYWxpdHkiLCAiU2FtZSBob3VzZSIsICJOZXR3b3JrIHNpemUiLCAiTXVsdGlwbGV4aXR5IiwgIkVtb3Rpb25hbA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VuZXNzIiwgIlN0ci4gZW1iZWRkZWRuZXNzIGZvY2FsIGxheWVyIiwgIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUpDQpgYGANCg0KIyMjIGNvbmZpZGFudHMNCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCmh0bWx0b29sczo6dGFncyRkaXYoDQogIHN0eWxlID0gImhlaWdodDogNjAwcHg7IG92ZXJmbG93LXk6IHNjcm9sbDsiLA0KICBodG1sdG9vbHM6OmluY2x1ZGVIVE1MKCIuL3Jlc3VsdHMvY29lZnRhYl9jb25maWRhbnQuaHRtbCIpDQopDQpgYGANCg0KIyMjIGJlc3QgZnJpZW5kcw0KDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KaHRtbHRvb2xzOjp0YWdzJGRpdigNCiAgc3R5bGUgPSAiaGVpZ2h0OiA2MDBweDsgb3ZlcmZsb3cteTogc2Nyb2xsOyIsDQogIGh0bWx0b29sczo6aW5jbHVkZUhUTUwoIi4vcmVzdWx0cy9jb2VmdGFiX2ZyaWVuZC5odG1sIikNCikNCmBgYA0KDQojIyMgc3BvcnRzIHBhcnRuZXJzDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpodG1sdG9vbHM6OnRhZ3MkZGl2KA0KICBzdHlsZSA9ICJoZWlnaHQ6IDYwMHB4OyBvdmVyZmxvdy15OiBzY3JvbGw7IiwNCiAgaHRtbHRvb2xzOjppbmNsdWRlSFRNTCgiLi9yZXN1bHRzL2NvZWZ0YWJfc3BvcnQuaHRtbCIpDQopDQpgYGANCg0KIyMjIHN0dWR5IHBhcnRuZXJzDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpodG1sdG9vbHM6OnRhZ3MkZGl2KA0KICBzdHlsZSA9ICJoZWlnaHQ6IDYwMHB4OyBvdmVyZmxvdy15OiBzY3JvbGw7IiwNCiAgaHRtbHRvb2xzOjppbmNsdWRlSFRNTCgiLi9yZXN1bHRzL2NvZWZ0YWJfc3R1ZHkuaHRtbCIpDQopDQpgYGANCg0KIyMgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KLS0tLQ0KDQo8YnI+DQoNCiMgQXZlcmFnZSBtYXJnaW5hbCBlZmZlY3RzIA0KDQpGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgKG51bWVyaWNhbCkgYXBwcm9hY2ggdG8gY29tcHV0aW5nIEFNRXMsIHNlZSBodHRwczovL3d3dy5qb2NoZW10b2xzbWEubmwvdHV0b3JpYWxzL21lLy4NCg0KPGJyPg0KDQojIyBkZWZpbmUgZGF0YS1zZXRzDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KI0EuIGRhdGEtc2V0cyBmb3IgbWVkaWF0aW9uIGFuYWx5c2VzDQpkZmdlbmRlcjEgPC0gZGZnZW5kZXIwIDwtIGRmDQpkZmFnZXBsdXMgPC0gZGZhZ2VtaW4gPC0gZGYNCmRmZWR1YzEgPC0gZGZlZHVjMCA8LSBkZg0KDQpkZmdlbmRlcjEkZGlmZmVyZW50X2dlbmRlciA8LSAxDQpkZmdlbmRlcjAkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZmVkdWMxJGRpZmZlcmVudF9lZHVjIDwtIDENCmRmZWR1YzAkZGlmZmVyZW50X2VkdWMgPC0gMA0KDQojZGVmaW5lIHNtYWxsIHN0ZXAgZm9yIGNvbnRpbnVvdXMgdmFyaWFibGUNCnMgPC0gLjAwMQ0KZGZhZ2VwbHVzJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSArIHMNCmRmYWdlbWluJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSAtIHMNCg0KI0IgZGF0YS1zZXRzIGZvciBpbnRlcmFjdGlvbiBkaXNzaW1pbGFyaXR5ICogdGllIHR5cGUNCmRmZ2VuZGVyZnJpZW5kMDAgPC0gZGZnZW5kZXJmcmllbmQwMSA8LSBkZmdlbmRlcmZyaWVuZDEwIDwtIGRmZ2VuZGVyZnJpZW5kMTEgPC0gZGYNCmRmZ2VuZGVyZnJpZW5kMDAkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZmdlbmRlcmZyaWVuZDAxJGRpZmZlcmVudF9nZW5kZXIgPC0gMA0KZGZnZW5kZXJmcmllbmQxMCRkaWZmZXJlbnRfZ2VuZGVyIDwtIDENCmRmZ2VuZGVyZnJpZW5kMTEkZGlmZmVyZW50X2dlbmRlciA8LSAxDQpkZmdlbmRlcmZyaWVuZDAwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZnZW5kZXJmcmllbmQwMSR0aWUgPC0gIkZyaWVuZCINCmRmZ2VuZGVyZnJpZW5kMTAkdGllIDwtICJDb25maWRhbnQiDQpkZmdlbmRlcmZyaWVuZDExJHRpZSA8LSAiRnJpZW5kIg0KDQpkZmVkdWNmcmllbmQwMCA8LSBkZmVkdWNmcmllbmQwMSA8LSBkZmVkdWNmcmllbmQxMCA8LSBkZmVkdWNmcmllbmQxMSA8LSBkZg0KZGZlZHVjZnJpZW5kMDAkZGlmZmVyZW50X2VkdWMgPC0gMA0KZGZlZHVjZnJpZW5kMDEkZGlmZmVyZW50X2VkdWMgPC0gMA0KZGZlZHVjZnJpZW5kMTAkZGlmZmVyZW50X2VkdWMgPC0gMQ0KZGZlZHVjZnJpZW5kMTEkZGlmZmVyZW50X2VkdWMgPC0gMQ0KZGZlZHVjZnJpZW5kMDAkdGllIDwtICJDb25maWRhbnQiDQpkZmVkdWNmcmllbmQwMSR0aWUgPC0gIkZyaWVuZCINCmRmZWR1Y2ZyaWVuZDEwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZlZHVjZnJpZW5kMTEkdGllIDwtICJGcmllbmQiDQoNCmRmYWdlZnJpZW5kbWluMCA8LSBkZmFnZWZyaWVuZG1pbjEgPC0gZGZhZ2VmcmllbmRwbHVzMCA8LSBkZmFnZWZyaWVuZHBsdXMxIDwtIGRmDQpkZmFnZWZyaWVuZG1pbjAkZGlmX2FnZSA8LSBkZiRkaWZfYWdlIC0gcw0KZGZhZ2VmcmllbmRtaW4xJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSAtIHMNCmRmYWdlZnJpZW5kcGx1czAkZGlmX2FnZSA8LSBkZiRkaWZfYWdlICsgcw0KZGZhZ2VmcmllbmRwbHVzMSRkaWZfYWdlIDwtIGRmJGRpZl9hZ2UgKyBzDQpkZmFnZWZyaWVuZG1pbjAkdGllIDwtICJDb25maWRhbnQiDQpkZmFnZWZyaWVuZG1pbjEkdGllIDwtICJGcmllbmQiDQpkZmFnZWZyaWVuZHBsdXMwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZhZ2VmcmllbmRwbHVzMSR0aWUgPC0gIkZyaWVuZCINCg0KZGZnZW5kZXJzcG9ydDAwIDwtIGRmZ2VuZGVyc3BvcnQwMSA8LSBkZmdlbmRlcnNwb3J0MTAgPC0gZGZnZW5kZXJzcG9ydDExIDwtIGRmDQpkZmdlbmRlcnNwb3J0MDAkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZmdlbmRlcnNwb3J0MDEkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZmdlbmRlcnNwb3J0MTAkZGlmZmVyZW50X2dlbmRlciA8LSAxDQpkZmdlbmRlcnNwb3J0MTEkZGlmZmVyZW50X2dlbmRlciA8LSAxDQpkZmdlbmRlcnNwb3J0MDAkdGllIDwtICJDb25maWRhbnQiDQpkZmdlbmRlcnNwb3J0MDEkdGllIDwtICJTcG9ydCINCmRmZ2VuZGVyc3BvcnQxMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZ2VuZGVyc3BvcnQxMSR0aWUgPC0gIlNwb3J0Ig0KDQpkZmVkdWNzcG9ydDAwIDwtIGRmZWR1Y3Nwb3J0MDEgPC0gZGZlZHVjc3BvcnQxMCA8LSBkZmVkdWNzcG9ydDExIDwtIGRmDQpkZmVkdWNzcG9ydDAwJGRpZmZlcmVudF9lZHVjIDwtIDANCmRmZWR1Y3Nwb3J0MDEkZGlmZmVyZW50X2VkdWMgPC0gMA0KZGZlZHVjc3BvcnQxMCRkaWZmZXJlbnRfZWR1YyA8LSAxDQpkZmVkdWNzcG9ydDExJGRpZmZlcmVudF9lZHVjIDwtIDENCmRmZWR1Y3Nwb3J0MDAkdGllIDwtICJDb25maWRhbnQiDQpkZmVkdWNzcG9ydDAxJHRpZSA8LSAiU3BvcnQiDQpkZmVkdWNzcG9ydDEwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZlZHVjc3BvcnQxMSR0aWUgPC0gIlNwb3J0Ig0KDQpkZmFnZXNwb3J0bWluMCA8LSBkZmFnZXNwb3J0bWluMSA8LSBkZmFnZXNwb3J0cGx1czAgPC0gZGZhZ2VzcG9ydHBsdXMxIDwtIGRmDQpkZmFnZXNwb3J0bWluMCRkaWZfYWdlIDwtIGRmJGRpZl9hZ2UgLSBzDQpkZmFnZXNwb3J0bWluMSRkaWZfYWdlIDwtIGRmJGRpZl9hZ2UgLSBzDQpkZmFnZXNwb3J0cGx1czAkZGlmX2FnZSA8LSBkZiRkaWZfYWdlICsgcw0KZGZhZ2VzcG9ydHBsdXMxJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSArIHMNCmRmYWdlc3BvcnRtaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZhZ2VzcG9ydG1pbjEkdGllIDwtICJTcG9ydCINCmRmYWdlc3BvcnRwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmYWdlc3BvcnRwbHVzMSR0aWUgPC0gIlNwb3J0Ig0KDQpkZmdlbmRlcnN0dWR5MDAgPC0gZGZnZW5kZXJzdHVkeTAxIDwtIGRmZ2VuZGVyc3R1ZHkxMCA8LSBkZmdlbmRlcnN0dWR5MTEgPC0gZGYNCmRmZ2VuZGVyc3R1ZHkwMCRkaWZmZXJlbnRfZ2VuZGVyIDwtIDANCmRmZ2VuZGVyc3R1ZHkwMSRkaWZmZXJlbnRfZ2VuZGVyIDwtIDANCmRmZ2VuZGVyc3R1ZHkxMCRkaWZmZXJlbnRfZ2VuZGVyIDwtIDENCmRmZ2VuZGVyc3R1ZHkxMSRkaWZmZXJlbnRfZ2VuZGVyIDwtIDENCmRmZ2VuZGVyc3R1ZHkwMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZ2VuZGVyc3R1ZHkwMSR0aWUgPC0gIlN0dWR5Ig0KZGZnZW5kZXJzdHVkeTEwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZnZW5kZXJzdHVkeTExJHRpZSA8LSAiU3R1ZHkiDQoNCmRmZWR1Y3N0dWR5MDAgPC0gZGZlZHVjc3R1ZHkwMSA8LSBkZmVkdWNzdHVkeTEwIDwtIGRmZWR1Y3N0dWR5MTEgPC0gZGYNCmRmZWR1Y3N0dWR5MDAkZGlmZmVyZW50X2VkdWMgPC0gMA0KZGZlZHVjc3R1ZHkwMSRkaWZmZXJlbnRfZWR1YyA8LSAwDQpkZmVkdWNzdHVkeTEwJGRpZmZlcmVudF9lZHVjIDwtIDENCmRmZWR1Y3N0dWR5MTEkZGlmZmVyZW50X2VkdWMgPC0gMQ0KZGZlZHVjc3R1ZHkwMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZWR1Y3N0dWR5MDEkdGllIDwtICJTdHVkeSINCmRmZWR1Y3N0dWR5MTAkdGllIDwtICJDb25maWRhbnQiDQpkZmVkdWNzdHVkeTExJHRpZSA8LSAiU3R1ZHkiDQoNCmRmYWdlc3R1ZHltaW4wIDwtIGRmYWdlc3R1ZHltaW4xIDwtIGRmYWdlc3R1ZHlwbHVzMCA8LSBkZmFnZXN0dWR5cGx1czEgPC0gZGYNCmRmYWdlc3R1ZHltaW4wJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSAtIHMNCmRmYWdlc3R1ZHltaW4xJGRpZl9hZ2UgPC0gZGYkZGlmX2FnZSAtIHMNCmRmYWdlc3R1ZHlwbHVzMCRkaWZfYWdlIDwtIGRmJGRpZl9hZ2UgKyBzDQpkZmFnZXN0dWR5cGx1czEkZGlmX2FnZSA8LSBkZiRkaWZfYWdlICsgcw0KZGZhZ2VzdHVkeW1pbjAkdGllIDwtICJDb25maWRhbnQiDQpkZmFnZXN0dWR5bWluMSR0aWUgPC0gIlN0dWR5Ig0KZGZhZ2VzdHVkeXBsdXMwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZhZ2VzdHVkeXBsdXMxJHRpZSA8LSAiU3R1ZHkiDQoNCiNDIGRhdGEtc2V0cyBmb3IgaW50ZXJhY3Rpb24gbW9kZXJhdG9ycyAqIHRpZSB0eXBlDQpkZmNsb3NlcGx1cyA8LSBkZmNsb3NlbWluIDwtIGRmDQpkZmNsb3NlcGx1cyRjbG9zZW5lc3MudCA8LSBkZiRjbG9zZW5lc3MudCArIHMNCmRmY2xvc2VtaW4kY2xvc2VuZXNzLnQgPC0gZGYkY2xvc2VuZXNzLnQgLSBzDQoNCmRmbXVsdGlwbHVzIDwtIGRmbXVsdGltaW4gPC0gZGYNCmRmbXVsdGlwbHVzJG11bHRpcGxleCA8LSBkZiRtdWx0aXBsZXggKyBzDQpkZm11bHRpbWluJG11bHRpcGxleCA8LSBkZiRtdWx0aXBsZXggLSBzDQoNCmRmZmVtYmVkcGx1cyA8LSBkZmZlbWJlZG1pbiA8LSBkZg0KZGZmZW1iZWRwbHVzJGVtYmVkIDwtIGRmJGVtYmVkICsgcw0KZGZmZW1iZWRtaW4kZW1iZWQgPC0gZGYkZW1iZWQgLSBzDQoNCmRmb2VtYmVkcGx1cyA8LSBkZm9lbWJlZG1pbiA8LSBkZg0KZGZvZW1iZWRwbHVzJGVtYmVkLmV4dCA8LSBkZiRlbWJlZC5leHQgKyBzDQpkZm9lbWJlZG1pbiRlbWJlZC5leHQgPC0gZGYkZW1iZWQuZXh0IC0gcw0KDQojY2xvc2VuZXNzICogZnJpZW5kDQpkZmNsb3NlZnJpZW5kbWluMCA8LSBkZmNsb3NlZnJpZW5kbWluMSA8LSBkZmNsb3NlZnJpZW5kcGx1czAgPC0gZGZjbG9zZWZyaWVuZHBsdXMxIDwtIGRmDQpkZmNsb3NlZnJpZW5kbWluMCRjbG9zZW5lc3MudCA8LSBkZiRjbG9zZW5lc3MudCAtIHMNCmRmY2xvc2VmcmllbmRtaW4xJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50IC0gcw0KZGZjbG9zZWZyaWVuZHBsdXMwJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50ICsgcw0KZGZjbG9zZWZyaWVuZHBsdXMxJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50ICsgcw0KZGZjbG9zZWZyaWVuZG1pbjAkdGllIDwtICJDb25maWRhbnQiDQpkZmNsb3NlZnJpZW5kbWluMSR0aWUgPC0gIkZyaWVuZCINCmRmY2xvc2VmcmllbmRwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmY2xvc2VmcmllbmRwbHVzMSR0aWUgPC0gIkZyaWVuZCINCg0KI2Nsb3NlbmVzcyAqIHNwb3J0DQpkZmNsb3Nlc3BvcnRtaW4wIDwtIGRmY2xvc2VzcG9ydG1pbjEgPC0gZGZjbG9zZXNwb3J0cGx1czAgPC0gZGZjbG9zZXNwb3J0cGx1czEgPC0gZGYNCmRmY2xvc2VzcG9ydG1pbjAkY2xvc2VuZXNzLnQgPC0gZGYkY2xvc2VuZXNzLnQgLSBzDQpkZmNsb3Nlc3BvcnRtaW4xJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50IC0gcw0KZGZjbG9zZXNwb3J0cGx1czAkY2xvc2VuZXNzLnQgPC0gZGYkY2xvc2VuZXNzLnQgKyBzDQpkZmNsb3Nlc3BvcnRwbHVzMSRjbG9zZW5lc3MudCA8LSBkZiRjbG9zZW5lc3MudCArIHMNCmRmY2xvc2VzcG9ydG1pbjAkdGllIDwtICJDb25maWRhbnQiDQpkZmNsb3Nlc3BvcnRtaW4xJHRpZSA8LSAiU3BvcnQiDQpkZmNsb3Nlc3BvcnRwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmY2xvc2VzcG9ydHBsdXMxJHRpZSA8LSAiU3BvcnQiDQoNCiNjbG9zZW5lc3MgKiBzdHVkeQ0KZGZjbG9zZXN0dWR5bWluMCA8LSBkZmNsb3Nlc3R1ZHltaW4xIDwtIGRmY2xvc2VzdHVkeXBsdXMwIDwtIGRmY2xvc2VzdHVkeXBsdXMxIDwtIGRmDQpkZmNsb3Nlc3R1ZHltaW4wJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50IC0gcw0KZGZjbG9zZXN0dWR5bWluMSRjbG9zZW5lc3MudCA8LSBkZiRjbG9zZW5lc3MudCAtIHMNCmRmY2xvc2VzdHVkeXBsdXMwJGNsb3NlbmVzcy50IDwtIGRmJGNsb3NlbmVzcy50ICsgcw0KZGZjbG9zZXN0dWR5cGx1czEkY2xvc2VuZXNzLnQgPC0gZGYkY2xvc2VuZXNzLnQgKyBzDQpkZmNsb3Nlc3R1ZHltaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZjbG9zZXN0dWR5bWluMSR0aWUgPC0gIlN0dWR5Ig0KZGZjbG9zZXN0dWR5cGx1czAkdGllIDwtICJDb25maWRhbnQiDQpkZmNsb3Nlc3R1ZHlwbHVzMSR0aWUgPC0gIlN0dWR5Ig0KDQojbXVsdGlwbGV4aXR5ICogZnJpZW5kDQpkZm11bHRpZnJpZW5kbWluMCA8LSBkZm11bHRpZnJpZW5kbWluMSA8LSBkZm11bHRpZnJpZW5kcGx1czAgPC0gZGZtdWx0aWZyaWVuZHBsdXMxIDwtIGRmDQpkZm11bHRpZnJpZW5kbWluMCRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4IC0gcw0KZGZtdWx0aWZyaWVuZG1pbjEkbXVsdGlwbGV4IDwtIGRmJG11bHRpcGxleCAtIHMNCmRmbXVsdGlmcmllbmRwbHVzMCRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4ICsgcw0KZGZtdWx0aWZyaWVuZHBsdXMxJG11bHRpcGxleCA8LSBkZiRtdWx0aXBsZXggKyBzDQpkZm11bHRpZnJpZW5kbWluMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmbXVsdGlmcmllbmRtaW4xJHRpZSA8LSAiRnJpZW5kIg0KZGZtdWx0aWZyaWVuZHBsdXMwJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZtdWx0aWZyaWVuZHBsdXMxJHRpZSA8LSAiRnJpZW5kIg0KDQojbXVsdGlwbGV4aXR5ICogc3BvcnQNCmRmbXVsdGlzcG9ydG1pbjAgPC0gZGZtdWx0aXNwb3J0bWluMSA8LSBkZm11bHRpc3BvcnRwbHVzMCA8LSBkZm11bHRpc3BvcnRwbHVzMSA8LSBkZg0KZGZtdWx0aXNwb3J0bWluMCRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4IC0gcw0KZGZtdWx0aXNwb3J0bWluMSRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4IC0gcw0KZGZtdWx0aXNwb3J0cGx1czAkbXVsdGlwbGV4IDwtIGRmJG11bHRpcGxleCArIHMNCmRmbXVsdGlzcG9ydHBsdXMxJG11bHRpcGxleCA8LSBkZiRtdWx0aXBsZXggKyBzDQpkZm11bHRpc3BvcnRtaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZtdWx0aXNwb3J0bWluMSR0aWUgPC0gIlNwb3J0Ig0KZGZtdWx0aXNwb3J0cGx1czAkdGllIDwtICJDb25maWRhbnQiDQpkZm11bHRpc3BvcnRwbHVzMSR0aWUgPC0gIlNwb3J0Ig0KDQojbXVsdGlwbGV4aXR5ICogc3R1ZHkNCmRmbXVsdGlzdHVkeW1pbjAgPC0gZGZtdWx0aXN0dWR5bWluMSA8LSBkZm11bHRpc3R1ZHlwbHVzMCA8LSBkZm11bHRpc3R1ZHlwbHVzMSA8LSBkZg0KZGZtdWx0aXN0dWR5bWluMCRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4IC0gcw0KZGZtdWx0aXN0dWR5bWluMSRtdWx0aXBsZXggPC0gZGYkbXVsdGlwbGV4IC0gcw0KZGZtdWx0aXN0dWR5cGx1czAkbXVsdGlwbGV4IDwtIGRmJG11bHRpcGxleCArIHMNCmRmbXVsdGlzdHVkeXBsdXMxJG11bHRpcGxleCA8LSBkZiRtdWx0aXBsZXggKyBzDQpkZm11bHRpc3R1ZHltaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZtdWx0aXN0dWR5bWluMSR0aWUgPC0gIlN0dWR5Ig0KZGZtdWx0aXN0dWR5cGx1czAkdGllIDwtICJDb25maWRhbnQiDQpkZm11bHRpc3R1ZHlwbHVzMSR0aWUgPC0gIlN0dWR5Ig0KDQojc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIgKiBmcmllbmQNCmRmZmVtYmVkZnJpZW5kbWluMCA8LSBkZmZlbWJlZGZyaWVuZG1pbjEgPC0gZGZmZW1iZWRmcmllbmRwbHVzMCA8LSBkZmZlbWJlZGZyaWVuZHBsdXMxIDwtIGRmDQpkZmZlbWJlZGZyaWVuZG1pbjAkZW1iZWQgPC0gZGYkZW1iZWQgLSBzDQpkZmZlbWJlZGZyaWVuZG1pbjEkZW1iZWQgPC0gZGYkZW1iZWQgLSBzDQpkZmZlbWJlZGZyaWVuZHBsdXMwJGVtYmVkIDwtIGRmJGVtYmVkICsgcw0KZGZmZW1iZWRmcmllbmRwbHVzMSRlbWJlZCA8LSBkZiRlbWJlZCArIHMNCmRmZmVtYmVkZnJpZW5kbWluMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZmVtYmVkZnJpZW5kbWluMSR0aWUgPC0gIkZyaWVuZCINCmRmZmVtYmVkZnJpZW5kcGx1czAkdGllIDwtICJDb25maWRhbnQiDQpkZmZlbWJlZGZyaWVuZHBsdXMxJHRpZSA8LSAiRnJpZW5kIg0KDQojc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIgKiBzcG9ydA0KZGZmZW1iZWRzcG9ydG1pbjAgPC0gZGZmZW1iZWRzcG9ydG1pbjEgPC0gZGZmZW1iZWRzcG9ydHBsdXMwIDwtIGRmZmVtYmVkc3BvcnRwbHVzMSA8LSBkZg0KZGZmZW1iZWRzcG9ydG1pbjAkZW1iZWQgPC0gZGYkZW1iZWQgLSBzDQpkZmZlbWJlZHNwb3J0bWluMSRlbWJlZCA8LSBkZiRlbWJlZCAtIHMNCmRmZmVtYmVkc3BvcnRwbHVzMCRlbWJlZCA8LSBkZiRlbWJlZCArIHMNCmRmZmVtYmVkc3BvcnRwbHVzMSRlbWJlZCA8LSBkZiRlbWJlZCArIHMNCmRmZmVtYmVkc3BvcnRtaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZmZW1iZWRzcG9ydG1pbjEkdGllIDwtICJTcG9ydCINCmRmZmVtYmVkc3BvcnRwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZmVtYmVkc3BvcnRwbHVzMSR0aWUgPC0gIlNwb3J0Ig0KDQojc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIgKiBzdHVkeQ0KZGZmZW1iZWRzdHVkeW1pbjAgPC0gZGZmZW1iZWRzdHVkeW1pbjEgPC0gZGZmZW1iZWRzdHVkeXBsdXMwIDwtIGRmZmVtYmVkc3R1ZHlwbHVzMSA8LSBkZg0KZGZmZW1iZWRzdHVkeW1pbjAkZW1iZWQgPC0gZGYkZW1iZWQgLSBzDQpkZmZlbWJlZHN0dWR5bWluMSRlbWJlZCA8LSBkZiRlbWJlZCAtIHMNCmRmZmVtYmVkc3R1ZHlwbHVzMCRlbWJlZCA8LSBkZiRlbWJlZCArIHMNCmRmZmVtYmVkc3R1ZHlwbHVzMSRlbWJlZCA8LSBkZiRlbWJlZCArIHMNCmRmZmVtYmVkc3R1ZHltaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZmZW1iZWRzdHVkeW1pbjEkdGllIDwtICJTdHVkeSINCmRmZmVtYmVkc3R1ZHlwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmZmVtYmVkc3R1ZHlwbHVzMSR0aWUgPC0gIlN0dWR5Ig0KDQojc3RydWN0dXJhbCBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzICogZnJpZW5kDQpkZm9lbWJlZGZyaWVuZG1pbjAgPC0gZGZvZW1iZWRmcmllbmRtaW4xIDwtIGRmb2VtYmVkZnJpZW5kcGx1czAgPC0gZGZvZW1iZWRmcmllbmRwbHVzMSA8LSBkZg0KZGZvZW1iZWRmcmllbmRtaW4wJGVtYmVkIDwtIGRmJGVtYmVkLmV4dCAtIHMNCmRmb2VtYmVkZnJpZW5kbWluMSRlbWJlZCA8LSBkZiRlbWJlZC5leHQgLSBzDQpkZm9lbWJlZGZyaWVuZHBsdXMwJGVtYmVkIDwtIGRmJGVtYmVkLmV4dCArIHMNCmRmb2VtYmVkZnJpZW5kcGx1czEkZW1iZWQgPC0gZGYkZW1iZWQuZXh0ICsgcw0KZGZvZW1iZWRmcmllbmRtaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZvZW1iZWRmcmllbmRtaW4xJHRpZSA8LSAiRnJpZW5kIg0KZGZvZW1iZWRmcmllbmRwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmb2VtYmVkZnJpZW5kcGx1czEkdGllIDwtICJGcmllbmQiDQoNCiNzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcyBvdGhlciBsYXllcnMgKiBzcG9ydA0KZGZvZW1iZWRzcG9ydG1pbjAgPC0gZGZvZW1iZWRzcG9ydG1pbjEgPC0gZGZvZW1iZWRzcG9ydHBsdXMwIDwtIGRmb2VtYmVkc3BvcnRwbHVzMSA8LSBkZg0KZGZvZW1iZWRzcG9ydG1pbjAkZW1iZWQgPC0gZGYkZW1iZWQuZXh0IC0gcw0KZGZvZW1iZWRzcG9ydG1pbjEkZW1iZWQgPC0gZGYkZW1iZWQuZXh0IC0gcw0KZGZvZW1iZWRzcG9ydHBsdXMwJGVtYmVkIDwtIGRmJGVtYmVkLmV4dCArIHMNCmRmb2VtYmVkc3BvcnRwbHVzMSRlbWJlZCA8LSBkZiRlbWJlZC5leHQgKyBzDQpkZm9lbWJlZHNwb3J0bWluMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmb2VtYmVkc3BvcnRtaW4xJHRpZSA8LSAiU3BvcnQiDQpkZm9lbWJlZHNwb3J0cGx1czAkdGllIDwtICJDb25maWRhbnQiDQpkZm9lbWJlZHNwb3J0cGx1czEkdGllIDwtICJTcG9ydCINCg0KI3N0cnVjdHVyYWwgZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyAqIHN0dWR5DQpkZm9lbWJlZHN0dWR5bWluMCA8LSBkZm9lbWJlZHN0dWR5bWluMSA8LSBkZm9lbWJlZHN0dWR5cGx1czAgPC0gZGZvZW1iZWRzdHVkeXBsdXMxIDwtIGRmDQpkZm9lbWJlZHN0dWR5bWluMCRlbWJlZCA8LSBkZiRlbWJlZC5leHQgLSBzDQpkZm9lbWJlZHN0dWR5bWluMSRlbWJlZCA8LSBkZiRlbWJlZC5leHQgLSBzDQpkZm9lbWJlZHN0dWR5cGx1czAkZW1iZWQgPC0gZGYkZW1iZWQuZXh0ICsgcw0KZGZvZW1iZWRzdHVkeXBsdXMxJGVtYmVkIDwtIGRmJGVtYmVkLmV4dCArIHMNCmRmb2VtYmVkc3R1ZHltaW4wJHRpZSA8LSAiQ29uZmlkYW50Ig0KZGZvZW1iZWRzdHVkeW1pbjEkdGllIDwtICJTdHVkeSINCmRmb2VtYmVkc3R1ZHlwbHVzMCR0aWUgPC0gIkNvbmZpZGFudCINCmRmb2VtYmVkc3R1ZHlwbHVzMSR0aWUgPC0gIlN0dWR5Ig0KYGBgDQoNCg0KPGJyPg0KDQojIyBnZXQgbW9kZWxzDQoNCmBgYHtyLGV2YWw9RkFMU0V9DQptMyA8LSBhbnNbWzRdXSAjYmFzZQ0KbTQgPC0gYW5zW1s1XV0gIyttZWRpYXRvciAxIChyZWxhdGlvbmFsIGVtYmVkZGVkbmVzcykNCm01IDwtIGFuc1tbNl1dICMrbWVkaWF0b3IgMiAoc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MpDQptNiA8LSBhbnNbWzddXSAjK2JvdGggbWVkaWF0b3JzDQptNyA8LSBhbnNbWzhdXSAjK2ludGVyYWN0aW9uIGRpc3NpbSAqIHRpZSB0eXBlDQptOCA8LSBhbnNbWzldXSAjK2ludGVyYWN0aW9uIG1vZGVyYXRvcnMqIHRpZSB0eXBlDQpgYGANCg0KPGJyPg0KDQojIyBmdW5jdGlvbnMgdG8gY2FsY3VsYXRlIEFNRQ0KDQptYWtlIGZ1bmN0aW9ucyB0aGF0IGNhbGN1bGF0ZXMgYXZlcmFnZSBtYXJnaW5hbCAoaW50ZXJhY3Rpb24pIGVmZmVjdHMgb3ZlciBtb2RlbHMNCg0KLSBtb2RlbCAxOiBBTUVzIGZvciBkaXNzaW1pbGFyaXRpZXMNCi0gbW9kZWwgMjogQU1FcyBmb3IgZGlzc2ltaWxhcml0aWVzLCBjb250cm9sbGluZyBmb3IgcmVsYXRpb25hbCBlbWJlZGRlZG5lc3MgKGNsb3NlbmVzcyArIG11bHRpcGxleGl0eSkNCi0gbW9kZWwgMzogQU1FcyBmb3IgZGlzc2ltaWxhcml0aWVzLCBjb250cm9sbGluZyBmb3Igc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MNCi0gbW9kZWwgNDogQU1FcyBmb3IgZGlzc2ltaWxhcml0aWVzLCBjb250cm9sbGluZyBmb3IgYm90aCByZWxhdGlvbmFsIGFuZCBzdHJ1Y3R1cmFsIGFuZCBlbWJlZGRlZG5lc3MNCi0gbW9kZWwgNTogQU1JRXMgZm9yIGRpc3NpbWlsYXJpdGllcyAqIHRpZSB0eXBlDQotIG1vZGVsIDY6IEFNSUVzIGZvciBtZWRpYXRvcnMgKiB0aWUgdHlwZQ0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KI21vZGVsIDE6IEFNRXMgZGlzc2ltaWxhcml0aWVzIGluIGJhc2UgbW9kZWwNCmZwcmVkMSA8LSBmdW5jdGlvbihtMSkgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZ2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmYWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojbW9kZWwgMjogQU1FcyBkaXNzaW1pbGFyaXRpZXMgYWZ0ZXIgaW5jbHVkaW5nIHJlbGF0aW9uYWwgZW1iZWRkZWRlbnNzIChjbG9zZW5lc3MgYW5kIG11bHRpcGxleGl0eSkNCmZwcmVkMiA8LSBmdW5jdGlvbihtMikgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZ2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmYWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojbW9kZWwgMzogQU1FcyBkaXNzaW1pbGFyaXRpZXMgYWZ0ZXIgaW5jbHVkaW5nIHN0cnVjdHVyYWwgZW1iZWRkZWRuZXNzDQpmcHJlZDMgPC0gZnVuY3Rpb24obTMpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmYWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YykNCn0NCg0KI21vZGVsIDQ6IGJvdGggbWVkaWF0b3JzDQojYWxzbyBnZXQgbWFpbiBlZmZlY3RzIGZvciBpbnRlcmFjdGlvbiBhbmFseXNlcyAobTYpDQpmcHJlZDQgPC0gZnVuY3Rpb24obTQpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmYWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCiAgDQogICBtZV9jbG9zZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNsb3NlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNsb3NlbWluKSkvKDIgKiBzKQ0KICBhbWVfY2xvc2UgPC0gbWVhbihtZV9jbG9zZSkNCiAgDQogIG1lX211bHRpIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmbXVsdGlwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmbXVsdGltaW4pKS8oMiAqIHMpDQogIGFtZV9tdWx0aSA8LSBtZWFuKG1lX211bHRpKQ0KICANCiAgbWVfZmVtYmVkIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZlbWJlZG1pbikpLygyICogcykNCiAgYW1lX2ZlbWJlZCA8LSBtZWFuKG1lX2ZlbWJlZCkNCiAgDQogIG1lX29lbWJlZCA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm9lbWJlZHBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZvZW1iZWRtaW4pKS8oMiAqIHMpDQogIGFtZV9vZW1iZWQgPC0gbWVhbihtZV9vZW1iZWQpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMsYW1lX2Nsb3NlLGFtZV9tdWx0aSxhbWVfZmVtYmVkLGFtZV9vZW1iZWQpDQp9DQoNCiNtb2RlbCA1OiBpbnRlcmFjdGlvbiBkaXNzaW1pbGFyaXR5ICogdGllIHR5cGU6DQpmcHJlZDUgPC0gZnVuY3Rpb24obTUpew0KDQogICMgZGlmZmVyZW50X2dlbmRlciAoY29uZmlkYW50cyA9IHJlZi4pDQogIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZ2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICAjICogZnJpZW5kICANCiAgcDExIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJmcmllbmQxMSkNCiAgcDEwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJmcmllbmQxMCkNCiAgcDAxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJmcmllbmQwMSkNCiAgcDAwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJmcmllbmQwMCkNCiAgbWVfZ2VuZGVyZnJpZW5kIDwtIChwMTEgLSBwMDEpIC0gKHAxMCAtIHAwMCkNCiAgYW1lX2dlbmRlcmZyaWVuZCA8LSBtZWFuKG1lX2dlbmRlcmZyaWVuZCkNCiAgDQogICMgKiBzcG9ydA0KICBwMTEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmdlbmRlcnNwb3J0MTEpDQogIHAxMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZ2VuZGVyc3BvcnQxMCkNCiAgcDAxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJzcG9ydDAxKQ0KICBwMDAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmdlbmRlcnNwb3J0MDApDQogIG1lX2dlbmRlcnNwb3J0IDwtIChwMTEgLSBwMDEpIC0gKHAxMCAtIHAwMCkNCiAgYW1lX2dlbmRlcnNwb3J0IDwtIG1lYW4obWVfZ2VuZGVyc3BvcnQpDQogIA0KICAjICogc3R1ZHkNCiAgcDExIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJzdHVkeTExKQ0KICBwMTAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmdlbmRlcnN0dWR5MTApDQogIHAwMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZ2VuZGVyc3R1ZHkwMSkNCiAgcDAwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZnZW5kZXJzdHVkeTAwKQ0KICBtZV9nZW5kZXJzdHVkeSA8LSAocDExIC0gcDAxKSAtIChwMTAgLSBwMDApDQogIGFtZV9nZW5kZXJzdHVkeSA8LSBtZWFuKG1lX2dlbmRlcnN0dWR5KQ0KICANCiAgI2FnZV9kaWZmZXJlbmNlIChjb25maWRhbnRzID0gcmVmLikgIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmYWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgIyAqIGZyaWVuZA0KICBwcGx1czEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmFnZWZyaWVuZHBsdXMxKQ0KICBwcGx1czAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmFnZWZyaWVuZHBsdXMwKQ0KICBwbWluMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmYWdlZnJpZW5kbWluMSkNCiAgcG1pbjAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmFnZWZyaWVuZG1pbjApDQogIG1lX2FnZWZyaWVuZCA8LSAoKHBwbHVzMSAtIHBtaW4xKS8oMiAqIHMpKSAtICgocHBsdXMwIC0gcG1pbjApLygyICogcykpDQogIGFtZV9hZ2VmcmllbmQgPC0gbWVhbihtZV9hZ2VmcmllbmQpDQogIA0KICAjICogc3BvcnQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzcG9ydHBsdXMxKQ0KICBwcGx1czAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmFnZXNwb3J0cGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzcG9ydG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzcG9ydG1pbjApDQogIG1lX2FnZXNwb3J0IDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX2FnZXNwb3J0IDwtIG1lYW4obWVfYWdlc3BvcnQpDQogIA0KICAjICogc3R1ZHkNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzdHVkeXBsdXMxKQ0KICBwcGx1czAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmFnZXN0dWR5cGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzdHVkeW1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZhZ2VzdHVkeW1pbjApDQogIG1lX2FnZXN0dWR5IDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX2FnZXN0dWR5IDwtIG1lYW4obWVfYWdlc3R1ZHkpDQogIA0KICAjZGlmZmVyZW50IGVkdWMgKGNvbmZpZGFudCA9IHJlZikNCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KICANCiAgIyAqIGZyaWVuZA0KICBwMTEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNmcmllbmQxMSkNCiAgcDEwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZlZHVjZnJpZW5kMTApDQogIHAwMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1Y2ZyaWVuZDAxKQ0KICBwMDAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNmcmllbmQwMCkNCiAgbWVfZWR1Y2ZyaWVuZCA8LSAocDExIC0gcDAxKSAtIChwMTAgLSBwMDApDQogIGFtZV9lZHVjZnJpZW5kIDwtIG1lYW4obWVfZWR1Y2ZyaWVuZCkNCiAgDQogICMgKiBzcG9ydA0KICBwMTEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNzcG9ydDExKQ0KICBwMTAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNzcG9ydDEwKQ0KICBwMDEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNzcG9ydDAxKQ0KICBwMDAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG01LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmVkdWNzcG9ydDAwKQ0KICBtZV9lZHVjc3BvcnQgPC0gKHAxMSAtIHAwMSkgLSAocDEwIC0gcDAwKQ0KICBhbWVfZWR1Y3Nwb3J0IDwtIG1lYW4obWVfZWR1Y3Nwb3J0KQ0KICANCiAgIyAqIHN0dWR5DQogIHAxMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1Y3N0dWR5MTEpDQogIHAxMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1Y3N0dWR5MTApDQogIHAwMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1Y3N0dWR5MDEpDQogIHAwMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTUsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZWR1Y3N0dWR5MDApDQogIG1lX2VkdWNzdHVkeSA8LSAocDExIC0gcDAxKSAtIChwMTAgLSBwMDApDQogIGFtZV9lZHVjc3R1ZHkgPC0gbWVhbihtZV9lZHVjc3R1ZHkpDQoNCiAgICBjKGFtZV9nZW5kZXIsYW1lX2dlbmRlcmZyaWVuZCxhbWVfZ2VuZGVyc3BvcnQsYW1lX2dlbmRlcnN0dWR5LGFtZV9hZ2UsYW1lX2FnZWZyaWVuZCxhbWVfYWdlc3BvcnQsYW1lX2FnZXN0dWR5LGFtZV9lZHVjLGFtZV9lZHVjZnJpZW5kLGFtZV9lZHVjc3BvcnQsYW1lX2VkdWNzdHVkeSkgIA0KfQ0KDQojbW9kZWwgNjogaW50ZXJhY3Rpb24gbWVkaWF0b3IgKiB0aWUgdHlwZToNCmZwcmVkNiA8LSBmdW5jdGlvbihtNil7DQogIA0KICAjY2xvc2VuZXNzIChjb25maWRhbnQgPSByZWYpIA0KICBtZV9jbG9zZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNsb3NlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNsb3NlbWluKSkvKDIgKiBzKQ0KICBhbWVfY2xvc2UgPC0gbWVhbihtZV9jbG9zZSkNCiAgDQogICMgKiBmcmllbmQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZWZyaWVuZHBsdXMxKQ0KICBwcGx1czAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNsb3NlZnJpZW5kcGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZWZyaWVuZG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZWZyaWVuZG1pbjApDQogIG1lX2Nsb3NlZnJpZW5kIDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX2Nsb3NlZnJpZW5kIDwtIG1lYW4obWVfY2xvc2VmcmllbmQpDQogIA0KICAjICogc3BvcnQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZXNwb3J0cGx1czEpDQogIHBwbHVzMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY2xvc2VzcG9ydHBsdXMwKQ0KICBwbWluMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY2xvc2VzcG9ydG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZXNwb3J0bWluMCkNCiAgbWVfY2xvc2VzcG9ydCA8LSAoKHBwbHVzMSAtIHBtaW4xKS8oMiAqIHMpKSAtICgocHBsdXMwIC0gcG1pbjApLygyICogcykpDQogIGFtZV9jbG9zZXNwb3J0IDwtIG1lYW4obWVfY2xvc2VzcG9ydCkNCiAgDQogICMgKiBzdHVkeQ0KICBwcGx1czEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNsb3Nlc3R1ZHlwbHVzMSkNCiAgcHBsdXMwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZXN0dWR5cGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjbG9zZXN0dWR5bWluMSkNCiAgcG1pbjAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNsb3Nlc3R1ZHltaW4wKQ0KICBtZV9jbG9zZXN0dWR5IDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX2Nsb3Nlc3R1ZHkgPC0gbWVhbihtZV9jbG9zZXN0dWR5KQ0KICANCiAgICAjbXVsdGlwbGV4IChjb25maWRhbnQgPSByZWYpIA0KICBtZV9tdWx0aSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm11bHRpcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZm11bHRpbWluKSkvKDIgKiBzKQ0KICBhbWVfbXVsdGkgPC0gbWVhbihtZV9tdWx0aSkNCiAgDQogICMgKiBmcmllbmQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aWZyaWVuZHBsdXMxKQ0KICBwcGx1czAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm11bHRpZnJpZW5kcGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aWZyaWVuZG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aWZyaWVuZG1pbjApDQogIG1lX211bHRpZnJpZW5kIDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX211bHRpZnJpZW5kIDwtIG1lYW4obWVfbXVsdGlmcmllbmQpDQogIA0KICAjICogc3BvcnQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aXNwb3J0cGx1czEpDQogIHBwbHVzMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmbXVsdGlzcG9ydHBsdXMwKQ0KICBwbWluMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmbXVsdGlzcG9ydG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aXNwb3J0bWluMCkNCiAgbWVfbXVsdGlzcG9ydCA8LSAoKHBwbHVzMSAtIHBtaW4xKS8oMiAqIHMpKSAtICgocHBsdXMwIC0gcG1pbjApLygyICogcykpDQogIGFtZV9tdWx0aXNwb3J0IDwtIG1lYW4obWVfbXVsdGlzcG9ydCkNCiAgDQogICMgKiBzdHVkeQ0KICBwcGx1czEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm11bHRpc3R1ZHlwbHVzMSkNCiAgcHBsdXMwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aXN0dWR5cGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZtdWx0aXN0dWR5bWluMSkNCiAgcG1pbjAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm11bHRpc3R1ZHltaW4wKQ0KICBtZV9tdWx0aXN0dWR5IDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX211bHRpc3R1ZHkgPC0gbWVhbihtZV9tdWx0aXN0dWR5KQ0KICANCg0KICAgICNmb2NhbCBzdHIgZW1iZWRlZG5lc3MgKGNvbmZpZGFudCA9IHJlZikgDQogIG1lX2ZlbWJlZCA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmZW1iZWRtaW4pKS8oMiAqIHMpDQogIGFtZV9mZW1iZWQgPC0gbWVhbihtZV9mZW1iZWQpDQogIA0KICAjICogZnJpZW5kDQogIHBwbHVzMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkZnJpZW5kcGx1czEpDQogIHBwbHVzMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkZnJpZW5kcGx1czApDQogIHBtaW4xIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmZW1iZWRmcmllbmRtaW4xKQ0KICBwbWluMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkZnJpZW5kbWluMCkNCiAgbWVfZmVtYmVkZnJpZW5kIDwtICgocHBsdXMxIC0gcG1pbjEpLygyICogcykpIC0gKChwcGx1czAgLSBwbWluMCkvKDIgKiBzKSkNCiAgYW1lX2ZlbWJlZGZyaWVuZCA8LSBtZWFuKG1lX2ZlbWJlZGZyaWVuZCkNCiAgDQogICMgKiBzcG9ydA0KICBwcGx1czEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHNwb3J0cGx1czEpDQogIHBwbHVzMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkc3BvcnRwbHVzMCkNCiAgcG1pbjEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHNwb3J0bWluMSkNCiAgcG1pbjAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHNwb3J0bWluMCkNCiAgbWVfZmVtYmVkc3BvcnQgPC0gKChwcGx1czEgLSBwbWluMSkvKDIgKiBzKSkgLSAoKHBwbHVzMCAtIHBtaW4wKS8oMiAqIHMpKQ0KICBhbWVfZmVtYmVkc3BvcnQgPC0gbWVhbihtZV9mZW1iZWRzcG9ydCkNCiAgDQogICMgKiBzdHVkeQ0KICBwcGx1czEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHN0dWR5cGx1czEpDQogIHBwbHVzMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZmVtYmVkc3R1ZHlwbHVzMCkNCiAgcG1pbjEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHN0dWR5bWluMSkNCiAgcG1pbjAgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZlbWJlZHN0dWR5bWluMCkNCiAgbWVfZmVtYmVkc3R1ZHkgPC0gKChwcGx1czEgLSBwbWluMSkvKDIgKiBzKSkgLSAoKHBwbHVzMCAtIHBtaW4wKS8oMiAqIHMpKQ0KICBhbWVfZmVtYmVkc3R1ZHkgPC0gbWVhbihtZV9mZW1iZWRzdHVkeSkNCiAgDQogICMgc3RyIGVtYmVkZWRuZXNzIG90aGVyIGxheWVycyAoY29uZmlkYW50ID0gcmVmKSANCiAgbWVfb2VtYmVkIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZm9lbWJlZG1pbikpLygyICogcykNCiAgYW1lX29lbWJlZCA8LSBtZWFuKG1lX29lbWJlZCkNCiAgDQogICMgKiBmcmllbmQNCiAgcHBsdXMxIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZvZW1iZWRmcmllbmRwbHVzMSkNCiAgcHBsdXMwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZvZW1iZWRmcmllbmRwbHVzMCkNCiAgcG1pbjEgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG02LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZm9lbWJlZGZyaWVuZG1pbjEpDQogIHBtaW4wIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZvZW1iZWRmcmllbmRtaW4wKQ0KICBtZV9vZW1iZWRmcmllbmQgPC0gKChwcGx1czEgLSBwbWluMSkvKDIgKiBzKSkgLSAoKHBwbHVzMCAtIHBtaW4wKS8oMiAqIHMpKQ0KICBhbWVfb2VtYmVkZnJpZW5kIDwtIG1lYW4obWVfb2VtYmVkZnJpZW5kKQ0KICANCiAgIyAqIHNwb3J0DQogIHBwbHVzMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3BvcnRwbHVzMSkNCiAgcHBsdXMwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZvZW1iZWRzcG9ydHBsdXMwKQ0KICBwbWluMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3BvcnRtaW4xKQ0KICBwbWluMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3BvcnRtaW4wKQ0KICBtZV9vZW1iZWRzcG9ydCA8LSAoKHBwbHVzMSAtIHBtaW4xKS8oMiAqIHMpKSAtICgocHBsdXMwIC0gcG1pbjApLygyICogcykpDQogIGFtZV9vZW1iZWRzcG9ydCA8LSBtZWFuKG1lX29lbWJlZHNwb3J0KQ0KICANCiAgIyAqIHN0dWR5DQogIHBwbHVzMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3R1ZHlwbHVzMSkNCiAgcHBsdXMwIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZvZW1iZWRzdHVkeXBsdXMwKQ0KICBwbWluMSA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3R1ZHltaW4xKQ0KICBwbWluMCA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTYsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmb2VtYmVkc3R1ZHltaW4wKQ0KICBtZV9vZW1iZWRzdHVkeSA8LSAoKHBwbHVzMSAtIHBtaW4xKS8oMiAqIHMpKSAtICgocHBsdXMwIC0gcG1pbjApLygyICogcykpDQogIGFtZV9vZW1iZWRzdHVkeSA8LSBtZWFuKG1lX29lbWJlZHN0dWR5KQ0KICANCiAgYyhhbWVfY2xvc2UsYW1lX2Nsb3NlZnJpZW5kLGFtZV9jbG9zZXNwb3J0LGFtZV9jbG9zZXN0dWR5LA0KICAgIGFtZV9tdWx0aSxhbWVfbXVsdGlmcmllbmQsYW1lX211bHRpc3BvcnQsYW1lX211bHRpc3R1ZHksDQogICAgYW1lX2ZlbWJlZCxhbWVfZmVtYmVkZnJpZW5kLGFtZV9mZW1iZWRzcG9ydCxhbWVfZmVtYmVkc3R1ZHksDQogICAgYW1lX29lbWJlZCxhbWVfb2VtYmVkZnJpZW5kLGFtZV9vZW1iZWRzcG9ydCxhbWVfb2VtYmVkc3R1ZHkpDQp9DQoNCiNmcHJlZDEobTEpDQojZnByZWQ0KG00KQ0KI2ZwcmVkNShtNSkNCiNmcHJlZDYobTYpDQpgYGANCg0KPGJyPg0KDQojIyBib290c3RyYXBwaW5nDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpzZWVkIDwtIDI0MjUzMjMNCm5JdGVyIDwtIDUwMA0KDQpuQ29yZSA8LSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKQ0KDQpteWNsIDwtIG1ha2VDbHVzdGVyKHJlcCgibG9jYWxob3N0IiwgbkNvcmUpKQ0KDQpjbHVzdGVyRXZhbFEobXljbCwgbGlicmFyeShsbWU0KSkNCg0KY2x1c3RlckV4cG9ydChteWNsLCB2YXJsaXN0PWMoDQogICJtMyIsIm00IiwgIm01IiwgIm02IiwgIm03IiwgIm04IiwgDQogICNpbmNyZW1lbnQgYHNgDQogICJzIiwNCiAgI2RhdHNldHMNCiAgImRmZ2VuZGVyMCIsICJkZmdlbmRlcjEiLCAiZGZlZHVjMCIsICJkZmVkdWMxIiwiZGZhZ2VwbHVzIiwiZGZhZ2VtaW4iLA0KICAiZGZnZW5kZXJmcmllbmQxMSIsImRmZ2VuZGVyZnJpZW5kMTAiLCJkZmdlbmRlcmZyaWVuZDAxIiwiZGZnZW5kZXJmcmllbmQwMCIsDQogICJkZmdlbmRlcnNwb3J0MTEiLCJkZmdlbmRlcnNwb3J0MTAiLCJkZmdlbmRlcnNwb3J0MDEiLCJkZmdlbmRlcnNwb3J0MDAiLA0KICAiZGZnZW5kZXJzdHVkeTExIiwiZGZnZW5kZXJzdHVkeTEwIiwiZGZnZW5kZXJzdHVkeTAxIiwiZGZnZW5kZXJzdHVkeTAwIiwNCiAgImRmZWR1Y2ZyaWVuZDExIiwiZGZlZHVjZnJpZW5kMTAiLCJkZmVkdWNmcmllbmQwMSIsImRmZWR1Y2ZyaWVuZDAwIiwNCiAgImRmZWR1Y3Nwb3J0MTEiLCJkZmVkdWNzcG9ydDEwIiwiZGZlZHVjc3BvcnQwMSIsImRmZWR1Y3Nwb3J0MDAiLA0KICAiZGZlZHVjc3R1ZHkxMSIsImRmZWR1Y3N0dWR5MTAiLCJkZmVkdWNzdHVkeTAxIiwiZGZlZHVjc3R1ZHkwMCIsDQogICJkZmFnZWZyaWVuZG1pbjAiLCJkZmFnZWZyaWVuZG1pbjEiLCJkZmFnZWZyaWVuZHBsdXMwIiwiZGZhZ2VmcmllbmRwbHVzMSIsDQogICJkZmFnZXNwb3J0bWluMCIsImRmYWdlc3BvcnRtaW4xIiwiZGZhZ2VzcG9ydHBsdXMwIiwiZGZhZ2VzcG9ydHBsdXMxIiwNCiAgImRmYWdlc3R1ZHltaW4wIiwiZGZhZ2VzdHVkeW1pbjEiLCJkZmFnZXN0dWR5cGx1czAiLCJkZmFnZXN0dWR5cGx1czEiLA0KICAiZGZjbG9zZW1pbiIsICJkZmNsb3NlcGx1cyIsICJkZm11bHRpbWluIiwgImRmbXVsdGlwbHVzIiwgImRmZmVtYmVkbWluIiwgImRmZmVtYmVkcGx1cyIsICJkZm9lbWJlZG1pbiIsICJkZm9lbWJlZHBsdXMiLA0KICAiZGZjbG9zZWZyaWVuZHBsdXMxIiwiZGZjbG9zZWZyaWVuZHBsdXMwIiwiZGZjbG9zZWZyaWVuZG1pbjEiLCJkZmNsb3NlZnJpZW5kbWluMCIsDQogICJkZmNsb3Nlc3BvcnRwbHVzMSIsImRmY2xvc2VzcG9ydHBsdXMwIiwiZGZjbG9zZXNwb3J0bWluMSIsImRmY2xvc2VzcG9ydG1pbjAiLA0KICAiZGZjbG9zZXN0dWR5cGx1czEiLCJkZmNsb3Nlc3R1ZHlwbHVzMCIsImRmY2xvc2VzdHVkeW1pbjEiLCJkZmNsb3Nlc3R1ZHltaW4wIiwNCiAgICJkZm11bHRpZnJpZW5kcGx1czEiLCJkZm11bHRpZnJpZW5kcGx1czAiLCJkZm11bHRpZnJpZW5kbWluMSIsImRmbXVsdGlmcmllbmRtaW4wIiwNCiAgImRmbXVsdGlzcG9ydHBsdXMxIiwiZGZtdWx0aXNwb3J0cGx1czAiLCJkZm11bHRpc3BvcnRtaW4xIiwiZGZtdWx0aXNwb3J0bWluMCIsDQogICJkZm11bHRpc3R1ZHlwbHVzMSIsImRmbXVsdGlzdHVkeXBsdXMwIiwiZGZtdWx0aXN0dWR5bWluMSIsImRmbXVsdGlzdHVkeW1pbjAiLA0KICAgICJkZmZlbWJlZGZyaWVuZHBsdXMxIiwiZGZmZW1iZWRmcmllbmRwbHVzMCIsImRmZmVtYmVkZnJpZW5kbWluMSIsImRmZmVtYmVkZnJpZW5kbWluMCIsDQogICJkZmZlbWJlZHNwb3J0cGx1czEiLCJkZmZlbWJlZHNwb3J0cGx1czAiLCJkZmZlbWJlZHNwb3J0bWluMSIsImRmZmVtYmVkc3BvcnRtaW4wIiwNCiAgImRmZmVtYmVkc3R1ZHlwbHVzMSIsImRmZmVtYmVkc3R1ZHlwbHVzMCIsImRmZmVtYmVkc3R1ZHltaW4xIiwiZGZmZW1iZWRzdHVkeW1pbjAiLA0KICAiZGZvZW1iZWRmcmllbmRwbHVzMSIsImRmb2VtYmVkZnJpZW5kcGx1czAiLCJkZm9lbWJlZGZyaWVuZG1pbjEiLCJkZm9lbWJlZGZyaWVuZG1pbjAiLA0KICAiZGZvZW1iZWRzcG9ydHBsdXMxIiwiZGZvZW1iZWRzcG9ydHBsdXMwIiwiZGZvZW1iZWRzcG9ydG1pbjEiLCJkZm9lbWJlZHNwb3J0bWluMCIsDQogICJkZm9lbWJlZHN0dWR5cGx1czEiLCJkZm9lbWJlZHN0dWR5cGx1czAiLCJkZm9lbWJlZHN0dWR5bWluMSIsImRmb2VtYmVkc3R1ZHltaW4wIikpDQoNCnsNCnN5c3RlbS50aW1lIChib29fbTEgPC0gYm9vdE1lcihtMSwgZnByZWQxLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTIgPC0gYm9vdE1lcihtMiwgZnByZWQyLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTMgPC0gYm9vdE1lcihtMywgZnByZWQzLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTQgPC0gYm9vdE1lcihtNCwgZnByZWQ0LCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTUgPC0gYm9vdE1lcihtNSwgZnByZWQ1LCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTYgPC0gYm9vdE1lcihtNiwgZnByZWQ2LCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCn0NCg0KYm9vTCA8LSBsaXN0KGJvb19tMSxib29fbTIsYm9vX20zLGJvb19tNCxib29fbTUsYm9vX202KSANCnNhdmUoYm9vTCwgZmlsZSA9ICIuL2Jvb3QuUmRhIikNCg0Kc3RvcENsdXN0ZXIobXljbCkNCmBgYA0KDQoNCjxicj4NCg0KIyMgQU1FIC8gQU1NRQ0KDQoNCmBgYHtyLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJ30NCm5JdGVyID0gNTAwDQpsb2FkKCIuL3Jlc3VsdHMvYm9vdC5yZGEiKSAgDQoNCnBsb3RkYXRhIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSByZXAoYygiRGlmZmVyZW50XG5nZW5kZXIiLCJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSwgNCksDQogIG1vZGVsID0gcmVwKGMoIk0zIiwgIk00IiwgIk01IiwgIk02IiksIGVhY2g9MyksDQogIGFtZSA9IGMoYm9vTFtbMV1dJHQwLCBib29MW1syXV0kdDAsIGJvb0xbWzNdXSR0MCwgYm9vTFtbNF1dJHQwWzE6M10pLA0KICBhbWVfc2UgPSAgYyhhcHBseShib29MW1sxXV0kdCwgMiwgc2QpLCBhcHBseShib29MW1syXV0kdCwgMiwgc2QpLCBhcHBseShib29MW1szXV0kdCwgMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QpLA0KICAgICAgICAgICAgICBhcHBseShib29MW1s0XV0kdCwgMiwgc2QpWzE6M10gKSkNCg0KI2Fsc28gY2FsY3VsYXRlIGF2ZXJhZ2UgZXN0aW1hdGVkIEFNRSBvdmVyIGJvb3RzdHJhcHMNCnBsb3RkYXRhJGFtZV9iIDwtIE5BDQoNCmZvciAoaSBpbiBjKDE6MykpIHsgIyBmb3IgZGlzc2ltaWxhcml0eSBncm91bmQNCiAgZm9yIChqIGluIGMoMTo0KSkgeyAjIGZvciAgbW9kZWwNCiAgICAjZ2V0IGVzdGltYXRlZCBBTUVzIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBtb2RlbCBqDQogICAgYW1lc2IgPC0gYm9vTFtbal1dJHRbLCBpXQ0KICAgICNhbmQgY2FsY3VsYXRlIG1lYW4NCiAgICBwbG90ZGF0YSRhbWVfYltwbG90ZGF0YSRwcmVkID09IHVuaXF1ZShwbG90ZGF0YSRwcmVkKVtpXSAmIHBsb3RkYXRhJG1vZGVsID09IHVuaXF1ZShwbG90ZGF0YSRtb2RlbClbal1dIDwtIG1lYW4oYW1lc2IpDQogIH0NCn0NCg0KI2NhbGN1bGF0ZSBhdmVyYWdlIG1hcmdpbmFsIG1lZGlhdGlvbiBlZmZlY3RzDQpwbG90ZGF0YSRhbW1lIDwtIE5BDQpwbG90ZGF0YSRhbW1lX3NlIDwtIE5BDQoNCmZvciAoaSBpbiBjKDE6MykpIHsgIyBmb3IgZGlzc2ltaWxhcml0eSBncm91bmQNCiAgZm9yIChqIGluIGMoMjo0KSkgeyAjIGZvciBleHRlbmRlZCBtb2RlbA0KICAgICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgYmFzZWxpbmUgbW9kZWwNCiAgICBhbWVfaV9iYXNlIDwtIGJvb0xbWzFdXSR0WywgaV0NCiAgICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIGV4dGVuZGVkIG1vZGVsIGoNCiAgICBhbWVfaV9tb2RlbGogPC0gYm9vTFtbal1dJHRbLCBpXQ0KICAgICNjYWxjdWxhdGUgY3Jvc3MtbW9kZWwgQU1FIGRpZmZlcmVuY2UgcGVyIGJvb3RzdHJhcCBpdGVyYXRpb24NCiAgICBjbV9hbWVfZGlmcyA8LSBhbWVfaV9iYXNlIC0gYW1lX2lfbW9kZWxqDQogICAgI2NhbGN1bGF0ZSBhdmVyYWdlIG1hcmdpbmFsIG1lZGlhdGlvbiBlZmZlY3QgYnkgdGFraW5nIHRoZSBhdmVyYWdlDQogICAgcGxvdGRhdGEkYW1tZVtwbG90ZGF0YSRwcmVkID09IHVuaXF1ZShwbG90ZGF0YSRwcmVkKVtpXSAmIHBsb3RkYXRhJG1vZGVsID09IHVuaXF1ZShwbG90ZGF0YSRtb2RlbClbal1dIDwtIG1lYW4oY21fYW1lX2RpZnMpDQogICAgI2FuZCBTRQ0KICAgIHBsb3RkYXRhJGFtbWVfc2VbcGxvdGRhdGEkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEkcHJlZClbaV0gJiBwbG90ZGF0YSRtb2RlbCA9PSB1bmlxdWUocGxvdGRhdGEkbW9kZWwpW2pdXSA8LSBzZChjbV9hbWVfZGlmcykvc3FydChuSXRlcikNCiAgICB9DQp9DQoNCiN2YXJpYWJsZXMgdG8gY2xhc3MgZmFjdG9yLCByZW9yZGVyOg0KcGxvdGRhdGEkcHJlZCA8LSBmYWN0b3IocGxvdGRhdGEkcHJlZCwgbGV2ZWxzID0gYygiRGlmZmVyZW50XG5nZW5kZXIiLCAiQWdlXG5kaWZmZXJlbmNlIiwgIkRpZmZlcmVudFxuZWR1Y2F0aW9uIikpDQpwbG90ZGF0YSRtb2RlbCA8LSBmYWN0b3IocGxvdGRhdGEkbW9kZWwsIGxldmVscyA9IHJldihjKCJNMyIsICJNNCIsICJNNSIsICJNNiIpKSkNCnBsb3RkYXRhIDwtIHBsb3RkYXRhW29yZGVyKHBsb3RkYXRhJHByZWQpLF0NCnJvdy5uYW1lcyhwbG90ZGF0YSkgPC0gMTpucm93KHBsb3RkYXRhKQ0KZnNob3dkZihwbG90ZGF0YSwgZGlnaXRzPTMpDQpgYGANCg0KDQpgYGB7ciwgZmlnLndpZHRoPTgsZmlnLmhlaWdodD00LCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJ30NCiNwbG90IDE6IEFNRXMNCg0KcGxvdGRhdGEyIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIpLA0KICBtb2RlbCA9ICJNNC1NNiIsDQogIGFtZSA9IE5BLCBhbWVfc2UgPSBOQSwgYW1tZSA9IE5BLCBhbW1lX3NlID0gTkEpDQoNCiAgDQpiaW5kX3Jvd3MocGxvdGRhdGEsIHBsb3RkYXRhMikgLT4gcGxvdGRhdGExDQpwbG90ZGF0YTEkbW9kZWwgPC0gZmFjdG9yKHBsb3RkYXRhMSRtb2RlbCwgbGV2ZWxzID0gcmV2KGMoIk0zIiwgIk00IiwgIk01IiwgIk02IiwgIk00LU02IikpKQ0KcGxvdGRhdGExJHByZWQgPC0gZmFjdG9yKHBsb3RkYXRhMSRwcmVkLCBsZXZlbHMgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsICJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSkNCg0KcGxvdDEgPC0gZ2dwbG90KHBsb3RkYXRhMSwgYWVzKHggPSBhbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgI3ZlcnRpY2FsIGxpbmUgYXQgMA0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJibHVlIikgKyAjcG9pbnQgaW5kaWNhdGluZyBvYnNlcnZlZCBBTUUNCiAgI2dlb21fcG9pbnQoYWVzKHggPSBhbWVfYiwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCksIHNpemUgPSAzLCBzaGFwZSA9IDQpICsgI2Nyb3NzIGluZGljYXRpbmcgYXZlcmFnZSBib290c3RyYXAgQU1FIGVzdGltYXRlDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbWUgLSAxLjk2KmFtZV9zZSwgeG1heCA9IGFtZSArIDEuOTYqYW1lX3NlKSwgY29sb3I9ImJsdWUiLCB3aWR0aD0uNSkgKyAjZXJyb3IgYmFycyBmb3IgOTUlIENJDQogIGZhY2V0X2dyaWQocHJlZCB+Liwgc3dpdGNoID0gInkiLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKyAjYXJyYW5nZSBmYWNldHMgYnkgZGlzc2ltaWxhcml0eSB0eXBlDQogIGxhYnMoeCA9ICJBTUUiKSArICNyZW5hbWUgeC1heGlzIG5hbWUNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygtMC4wNzUsIDAuMDUpKSArICN4LWF4aXMgdG8gJS1wb2ludCwgYW5kIHNldCByYW5nZQ0KICANCiAgdGhlbWUoICNjdXN0b21pemUgdGhlbWUNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsdWUiKSwNCiAgICBzdHJpcC50ZXh0LnkubGVmdCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsNCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSkNCg0KI3Bsb3QgMjogQU1NRXMNCg0KIyByZWxhdGlvbmFsIGFuZCBzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcyBpbmZsdWVuY2UgZWFjaCBvdGhlci4gaSB3YW50IHRvIGFsc28gdGVzdCB3aGV0aGVyIHN0cnVjdHVyYWwgZW1iZWRkZWRuZXNzIGhhcyBhbiAqYWRkaXRpb25hbCogcm9sZSBpbiBleHBsYWluaW5nIHRoZSBmYXN0ZXIgdGllIGxvc3Mgb2YgZGlzc2ltaWxhciBvdGhlcnMsIGFib3ZlIGFuZCBiZXlvbmQgcmVsYXRpb25hbCBlbWJlZGRlZG5lc3MNCiN0aHVzIGkgY2FsY3VsYXRlIHRoZSBhbWUgY2hhbmdlIHdoZW4gY29tcGFyaW5nIHRoZSBtb2RlbCBpbmNsdWRpbmcgb25seSByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcyAobTIpIGFuZCBib3RoIGVtYmVkZGVkbmVzcyB0eXBlIChtNCkNCg0KcGxvdGRhdGEyIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIpLA0KICBtb2RlbCA9ICJNNC1NNiIsDQogIGFtZSA9IE5BLCBhbWVfc2UgPSBOQSwgYW1tZSA9IE5BLCBhbW1lX3NlID0gTkEpDQogIA0KZm9yIChpIGluIGMoMTozKSkgew0KICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIG1vZGVsIDIgKGluY2x1ZGluZyByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcyBvbmx5KQ0KICBhbWVfaV9iYXNlIDwtIGJvb0xbWzJdXSR0WyxpXQ0KICAjZ2V0IEFNRSBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgZXh0ZW5kZWQgbW9kZWwgNCAoYWRkaW5nIGFsc28gc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MpDQogIGFtZV9pX21vZGVsaiA8LSBib29MW1s0XV0kdFssaV0NCiAgI2NhbGN1bGF0ZSBjcm9zcy1tb2RlbCBBTUUgZGlmZmVyZW5jZQ0KICBjbV9hbWVfZGlmcyA8LSBhbWVfaV9iYXNlIC0gYW1lX2lfbW9kZWxqDQogICNjYWxjdWFsdGUgYXZlcmFnZSBtYXJnaW5hbCBtZWRpYXRpb24NCiAgcGxvdGRhdGEyJGFtbWVbcGxvdGRhdGEyJHByZWQgPT0gdW5pcXVlKHBsb3RkYXRhMiRwcmVkKVtpXV0gPC0gbWVhbihjbV9hbWVfZGlmcykNCiAgI2FuZCBTRQ0KICBwbG90ZGF0YTIkYW1tZV9zZVtwbG90ZGF0YTIkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEyJHByZWQpW2ldXSA8LSBzZChjbV9hbWVfZGlmcykvc3FydChuSXRlcikNCiAgfQ0KDQpiaW5kX3Jvd3MocGxvdGRhdGEscGxvdGRhdGEyKSAtPiBwbG90ZGF0YTINCg0KcGxvdGRhdGEyJHByZWQgPC0gZmFjdG9yKHBsb3RkYXRhMiRwcmVkLCBsZXZlbHMgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsICJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSkNCnBsb3RkYXRhMiRtb2RlbCA8LSBmYWN0b3IocGxvdGRhdGEyJG1vZGVsLCBsZXZlbHMgPSByZXYoYygiTTMiLCAiTTQiLCAiTTUiLCAiTTYiLCAiTTQtTTYiKSkpDQpwbG90ZGF0YTIgPC0gcGxvdGRhdGEyW29yZGVyKHBsb3RkYXRhMiRwcmVkKSxdDQpyb3cubmFtZXMocGxvdGRhdGEyKSA8LSAxOm5yb3cocGxvdGRhdGEyKQ0KI2ZzaG93ZGYocGxvdGRhdGEyKQ0KDQpwbG90MiA8LSBnZ3Bsb3QocGxvdGRhdGEyLCBhZXMoeCA9IGFtbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1tZSAtIDEuOTYqYW1tZV9zZSwgeG1heCA9IGFtbWUgKyAxLjk2KmFtbWVfc2UpLCBjb2xvcj0icmVkIiwgd2lkdGg9LjUpICsNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArDQogIGxhYnMoeCA9ICJBTU1FIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0wLjA3NSwgMC4wNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAicmVkIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZSgpKSArDQogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTQiLCAiIiksDQogICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAicmlnaHQiKSArDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpDQoNCiNjb21iaW5lIHBsb3RzDQojP2dnYXJyYW5nZQ0KDQooZmlndXJlIDwtIGdnYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2w9Miwgd2lkdGhzPWMoMS4xLCAxKSkpDQpgYGANCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpnZ3NhdmUoZmlndXJlLCANCiAgICAgICBmaWxlID0gIi4vZmlndXJlcy9hbWVhbW1lLnBuZyIsDQogICAgICAgZHBpID0gMzIwLCANCiAgICAgICB3aWR0aCA9IDcsDQogICAgICAgaGVpZ2h0ID0gNCkNCmBgYA0KDQojIyBBTUUgLyBBTUlFIHsudGFic2V0IC50YWJzZXQtZmFkZX0NCg0KIyMjIGRpc3NpbWlsYXJpdHkgKiB0aWUgdHlwZQ0KDQpgYGB7ciwgIGNsYXNzLnNvdXJjZSA9ICdmb2xkLWhpZGUnfQ0KZ2VuZGVyIDwtIGRhdGEuZnJhbWUocHJlZCA9ICJEaWZmZXJlbnRcbmdlbmRlciIsIA0KICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCA9IGMoIlBvb2xlZCIsICJiZXN0IGZyaWVuZHMgdnMuIGNvbmZpZGFudHMiLCAic3BvcnRzIHZzLiBjb25maWRhbnRzIiwgInN0dWR5IHZzLiBjb25maWRhbnRzIiksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZSA9IGMoYm9vTFtbNV1dJHQwWzFdLCByZXAoTkEsMykpLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWVfc2UgPSBjKGFwcGx5KGJvb0xbWzVdXSR0LCAyLCBzZClbMV0sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtaWUgPSBjKE5BLGJvb0xbWzVdXSR0MFsyOjRdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1pZV9zZSA9IGMoTkEsYXBwbHkoYm9vTFtbNV1dJHQsIDIsIHNkKVsyOjRdKSkNCg0KYWdlIDwtIGRhdGEuZnJhbWUocHJlZCA9ICJBZ2VcbmRpZmZlcmVuY2UiLCANCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSBjKCJQb29sZWQiLCAiYmVzdCBmcmllbmRzIHZzLiBjb25maWRhbnRzIiwgInNwb3J0cyB2cy4gY29uZmlkYW50cyIsICJzdHVkeSB2cy4gY29uZmlkYW50cyIpLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWUgPSBjKGJvb0xbWzVdXSR0MFs1XSwgcmVwKE5BLDMpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1lX3NlID0gYyhhcHBseShib29MW1s1XV0kdCwgMiwgc2QpWzVdLCByZXAoTkEsMykpLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWllID0gYyhOQSxib29MW1s1XV0kdDBbNjo4XSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtaWVfc2UgPSBjKE5BLGFwcGx5KGJvb0xbWzVdXSR0LCAyLCBzZClbNjo4XSkpDQoNCmVkdWMgPC0gZGF0YS5mcmFtZShwcmVkID0gIkRpZmZlcmVudFxuZWR1Y2F0aW9uIiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsID0gYygiUG9vbGVkIiwgImJlc3QgZnJpZW5kcyB2cy4gY29uZmlkYW50cyIsICJzcG9ydHMgdnMuIGNvbmZpZGFudHMiLCAic3R1ZHkgdnMuIGNvbmZpZGFudHMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1lID0gYyhib29MW1s1XV0kdDBbOV0sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbNV1dJHQsIDIsIHNkKVs5XSwgcmVwKE5BLDMpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1pZSA9IGMoTkEsYm9vTFtbNV1dJHQwWzEwOjEyXSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtaWVfc2UgPSBjKE5BLGFwcGx5KGJvb0xbWzVdXSR0LCAyLCBzZClbMTA6MTJdKSkNCg0KcGxvdGRhdGEgPC0gcmJpbmQoZ2VuZGVyLGFnZSxlZHVjKQ0KDQojdmFyaWFibGVzIHRvIGNsYXNzIGZhY3RvciwgcmVvcmRlcjoNCnBsb3RkYXRhJHByZWQgPC0gZmFjdG9yKHBsb3RkYXRhJHByZWQsIGxldmVscyA9IGMoIkRpZmZlcmVudFxuZ2VuZGVyIiwgIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIpKQ0KcGxvdGRhdGEkbW9kZWwgPC0gZmFjdG9yKHBsb3RkYXRhJG1vZGVsLCBsZXZlbHMgPSByZXYoYygiUG9vbGVkIiwgImJlc3QgZnJpZW5kcyB2cy4gY29uZmlkYW50cyIsICJzcG9ydHMgdnMuIGNvbmZpZGFudHMiLCAic3R1ZHkgdnMuIGNvbmZpZGFudHMiKSkpDQpwbG90ZGF0YSA8LSBwbG90ZGF0YVtvcmRlcihwbG90ZGF0YSRwcmVkKSxdDQpyb3cubmFtZXMocGxvdGRhdGEpIDwtIDE6bnJvdyhwbG90ZGF0YSkNCmZzaG93ZGYocGxvdGRhdGEsIGRpZ2l0cz00KQ0KYGBgDQoNCmBgYHtyLCBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTQsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCiNwbG90IDE6IEFNRXMNCnBsb3QxIDwtIGdncGxvdChwbG90ZGF0YSwgYWVzKHggPSBhbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgI3ZlcnRpY2FsIGxpbmUgYXQgMA0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJibHVlIikgKyAjcG9pbnQgaW5kaWNhdGluZyBvYnNlcnZlZCBBTUUNCiAgI2dlb21fcG9pbnQoYWVzKHggPSBhbWVfYiwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCksIHNpemUgPSAzLCBzaGFwZSA9IDQpICsgI2Nyb3NzIGluZGljYXRpbmcgYXZlcmFnZSBib290c3RyYXAgQU1FIGVzdGltYXRlDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbWUgLSAxLjk2KmFtZV9zZSwgeG1heCA9IGFtZSArIDEuOTYqYW1lX3NlKSwgY29sb3I9ImJsdWUiLCB3aWR0aD0uNSkgKyAjZXJyb3IgYmFycyBmb3IgOTUlIENJDQogIGZhY2V0X2dyaWQocHJlZCB+Liwgc3dpdGNoID0gInkiLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKyAjYXJyYW5nZSBmYWNldHMgYnkgZGlzc2ltaWxhcml0eSB0eXBlDQogIGxhYnMoeCA9ICJBTUUiKSArICNyZW5hbWUgeC1heGlzIG5hbWUNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygtMC4xLCAwLjEpKSArICN4LWF4aXMgdG8gJS1wb2ludCwgYW5kIHNldCByYW5nZSANCiAgdGhlbWUoICNjdXN0b21pemUgdGhlbWUNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsdWUiKSwNCiAgICBzdHJpcC50ZXh0LnkubGVmdCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsNCiAgZ2doNHg6OmZhY2V0dGVkX3Bvc19zY2FsZXMoeSA9IGxpc3QoICNjdXN0b21pemUgeSBheGlzIHBlciBmYWNldC4uDQogIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYyggIiIsICIiLCAiIiwgIk03IikpLA0KICBwcmVkID09ICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoICIiLCAiIiwgIiIsICJNNyIpKSwNCiAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYyggIiIsICIiLCAiIiwgIk03IikpKSkNCg0KDQojcGxvdCAyOiBBTUlFcw0KcGxvdDIgPC0gZ2dwbG90KHBsb3RkYXRhLCBhZXMoeCA9IGFtaWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAib3JhbmdlIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1pZSAtIDEuOTYqYW1pZV9zZSwgeG1heCA9IGFtaWUgKyAxLjk2KmFtaWVfc2UpLCBjb2xvcj0ib3JhbmdlIiwgd2lkdGg9LjUpICsNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArDQogIGxhYnMoeCA9ICJBTUlFIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0uMjUsLjI1KSkgKyAjeC1heGlzIHRvICUtcG9pbnQsIGFuZCBzZXQgcmFuZ2UgDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIm9yYW5nZSIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoKSkgKw0KICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoInN0dWR5IHZzLiBjb25maWRhbnQiLCAic3BvcnRzIHZzLiBjb25maWRhbnQiLCAiYmVzdCBmcmllbmQgdnMuIGNvbmZpZGFudCIsICIiKSwNCiAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICJyaWdodCIpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KKGZpZ3VyZSA8LSBnZ2FycmFuZ2UocGxvdDEsIHBsb3QyLCBuY29sPTIsIGFsaWduPSJodiIsIHdpZHRocyA9IGMoMSwxLjIpKSkNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KZ2dzYXZlKGZpZ3VyZSwgDQogICAgICAgZmlsZSA9ICIuL2ZpZ3VyZXMvYW1lYW1pZTEucG5nIiwNCiAgICAgICBkcGkgPSAzMjAsIA0KICAgICAgIHdpZHRoID0gNywNCiAgICAgICBoZWlnaHQgPSA0KQ0KYGBgDQoNCiMjIyBlbWJlZGRlZG5lc3MgKiB0aWUgdHlwZQ0KDQpgYGB7ciwgIGNsYXNzLnNvdXJjZSA9ICdmb2xkLWhpZGUnfQ0KY2xvc2UgPC0gZGF0YS5mcmFtZShwcmVkID0gIkVtb3Rpb25hbFxuY2xvc2VuZXNzIiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsID0gYygiUG9vbGVkIiwgImJlc3QgZnJpZW5kcyB2cy4gY29uZmlkYW50cyIsICJzcG9ydHMgdnMuIGNvbmZpZGFudHMiLCAic3R1ZHkgdnMuIGNvbmZpZGFudHMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1lID0gYyhib29MW1s2XV0kdDBbMV0sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbNl1dJHQsIDIsIHNkKVsxXSwgcmVwKE5BLDMpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1pZSA9IGMoTkEsYm9vTFtbNl1dJHQwWzI6NF0pLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWllX3NlID0gYyhOQSxhcHBseShib29MW1s2XV0kdCwgMiwgc2QpWzI6NF0pKQ0KDQptdWx0aSA8LSBkYXRhLmZyYW1lKHByZWQgPSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsID0gYygiUG9vbGVkIiwgImJlc3QgZnJpZW5kcyB2cy4gY29uZmlkYW50cyIsICJzcG9ydHMgdnMuIGNvbmZpZGFudHMiLCAic3R1ZHkgdnMuIGNvbmZpZGFudHMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1lID0gYyhib29MW1s2XV0kdDBbNV0sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbNl1dJHQsIDIsIHNkKVs1XSwgcmVwKE5BLDMpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1pZSA9IGMoTkEsYm9vTFtbNl1dJHQwWzY6OF0pLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWllX3NlID0gYyhOQSxhcHBseShib29MW1s2XV0kdCwgMiwgc2QpWzY6OF0pKQ0KDQpzdHJmIDwtIGRhdGEuZnJhbWUocHJlZCA9ICJTdHJ1Y3R1cmFsXG5lbWJlZGRlZC1cbm5lc3NcbmZvY2FsIGxheWVyIiwgDQogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsID0gYygiUG9vbGVkIiwgImJlc3QgZnJpZW5kcyB2cy4gY29uZmlkYW50cyIsICJzcG9ydHMgdnMuIGNvbmZpZGFudHMiLCAic3R1ZHkgdnMuIGNvbmZpZGFudHMiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1lID0gYyhib29MW1s2XV0kdDBbOV0sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbNl1dJHQsIDIsIHNkKVs5XSwgcmVwKE5BLDMpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgYW1pZSA9IGMoTkEsYm9vTFtbNl1dJHQwWzEwOjEyXSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtaWVfc2UgPSBjKE5BLGFwcGx5KGJvb0xbWzZdXSR0LCAyLCBzZClbMTA6MTJdKSkNCg0Kc3RybyA8LSBkYXRhLmZyYW1lKHByZWQgPSAiU3RydWN0dXJhbFxuZW1iZWRkZWQtXG5uZXNzXG5vdGhlciBsYXllcnMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSBjKCJQb29sZWQiLCAiYmVzdCBmcmllbmRzIHZzLiBjb25maWRhbnRzIiwgInNwb3J0cyB2cy4gY29uZmlkYW50cyIsICJzdHVkeSB2cy4gY29uZmlkYW50cyIpLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWUgPSBjKGJvb0xbWzZdXSR0MFsxM10sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbNl1dJHQsIDIsIHNkKVsxM10sIHJlcChOQSwzKSksDQogICAgICAgICAgICAgICAgICAgICAgIGFtaWUgPSBjKE5BLGJvb0xbWzZdXSR0MFsxNDoxNl0pLA0KICAgICAgICAgICAgICAgICAgICAgICBhbWllX3NlID0gYyhOQSxhcHBseShib29MW1s2XV0kdCwgMiwgc2QpWzE0OjE2XSkpDQoNCnBsb3RkYXRhIDwtIHJiaW5kKGNsb3NlLG11bHRpLHN0cmYsc3RybykNCg0KI3ZhcmlhYmxlcyB0byBjbGFzcyBmYWN0b3IsIHJlb3JkZXI6DQpwbG90ZGF0YSRwcmVkIDwtIGZhY3RvcihwbG90ZGF0YSRwcmVkLCBsZXZlbHMgPSBjKCJFbW90aW9uYWxcbmNsb3NlbmVzcyIsICJSZWxhdGlvbmFsXG5tdWx0aXBsZXhpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3RydWN0dXJhbFxuZW1iZWRkZWQtXG5uZXNzXG5mb2NhbCBsYXllciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJ1Y3R1cmFsXG5lbWJlZGRlZC1cbm5lc3Ncbm90aGVyIGxheWVycyIpKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCnBsb3RkYXRhJG1vZGVsIDwtIGZhY3RvcihwbG90ZGF0YSRtb2RlbCwgbGV2ZWxzID0gcmV2KGMoIlBvb2xlZCIsICJiZXN0IGZyaWVuZHMgdnMuIGNvbmZpZGFudHMiLCAic3BvcnRzIHZzLiBjb25maWRhbnRzIiwgInN0dWR5IHZzLiBjb25maWRhbnRzIikpKQ0KcGxvdGRhdGEgPC0gcGxvdGRhdGFbb3JkZXIocGxvdGRhdGEkcHJlZCksXQ0Kcm93Lm5hbWVzKHBsb3RkYXRhKSA8LSAxOm5yb3cocGxvdGRhdGEpDQpmc2hvd2RmKHBsb3RkYXRhLCBkaWdpdHM9NCkNCmBgYA0KDQpgYGB7ciwgZmlnLndpZHRoPTgsZmlnLmhlaWdodD00LCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQojcGxvdCAxOiBBTUVzDQpwbG90MSA8LSBnZ3Bsb3QocGxvdGRhdGEsIGFlcyh4ID0gYW1lLCB5ID0gbW9kZWwsIGZpbGwgPSBwcmVkKSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArICN2ZXJ0aWNhbCBsaW5lIGF0IDANCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAiYmx1ZSIpICsgI3BvaW50IGluZGljYXRpbmcgb2JzZXJ2ZWQgQU1FDQogICNnZW9tX3BvaW50KGFlcyh4ID0gYW1lX2IsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpLCBzaXplID0gMywgc2hhcGUgPSA0KSArICNjcm9zcyBpbmRpY2F0aW5nIGF2ZXJhZ2UgYm9vdHN0cmFwIEFNRSBlc3RpbWF0ZQ0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1lIC0gMS45NiphbWVfc2UsIHhtYXggPSBhbWUgKyAxLjk2KmFtZV9zZSksIGNvbG9yPSJibHVlIiwgd2lkdGg9LjUpICsgI2Vycm9yIGJhcnMgZm9yIDk1JSBDSQ0KICBmYWNldF9ncmlkKHByZWQgfi4sIHN3aXRjaCA9ICJ5Iiwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsgI2FycmFuZ2UgZmFjZXRzIGJ5IGRpc3NpbWlsYXJpdHkgdHlwZQ0KICBsYWJzKHggPSAiQU1FIikgKyAjcmVuYW1lIHgtYXhpcyBuYW1lDQogc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygtMC4yLCAwLjE1KSkgKyAjeC1heGlzIHRvICUtcG9pbnQsIGFuZCBzZXQgcmFuZ2UgDQogIHRoZW1lKCAjY3VzdG9taXplIHRoZW1lDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibHVlIiksDQogICAgc3RyaXAudGV4dC55LmxlZnQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZSgpKSArDQogIGdnaDR4OjpmYWNldHRlZF9wb3Nfc2NhbGVzKHkgPSBsaXN0KCAjY3VzdG9taXplIHkgYXhpcyBwZXIgZmFjZXQuLg0KICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoICIiLCAiIiwgIiIsICJNOCIpKSwNCiAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYyggIiIsICIiLCAiIiwgIk04IikpLA0KICBwcmVkID09ICJTdHJ1Y3R1cmFsXG5lbWJlZGRlZC1cbm5lc3NcbmZvY2FsIGxheWVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYyggIiIsICIiLCAiIiwgIk04IikpLA0KICBwcmVkID09ICJTdHJ1Y3R1cmFsXG5lbWJlZGRlZC1cbm5lc3Ncbm90aGVyIGxheWVycyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoICIiLCAiIiwgIiIsICJNOCIpKQ0KICApKQ0KDQoNCiNwbG90IDI6IEFNSUVzDQpwbG90MiA8LSBnZ3Bsb3QocGxvdGRhdGEsIGFlcyh4ID0gYW1pZSwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCkpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJvcmFuZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbWllIC0gMS45NiphbWllX3NlLCB4bWF4ID0gYW1pZSArIDEuOTYqYW1pZV9zZSksIGNvbG9yPSJvcmFuZ2UiLCB3aWR0aD0uNSkgKw0KICBmYWNldF9ncmlkKHByZWQgfi4sIHN3aXRjaCA9ICJ5Iiwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsNCiAgbGFicyh4ID0gIkFNSUUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQsIGxpbWl0cyA9IGMoLS4zLC4yNSkpICsgI3gtYXhpcyB0byAlLXBvaW50LCBhbmQgc2V0IHJhbmdlIA0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJvcmFuZ2UiKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsNCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCJzdHVkeSB2cy4gY29uZmlkYW50IiwgInNwb3J0cyB2cy4gY29uZmlkYW50IiwgImJlc3QgZnJpZW5kIHZzLiBjb25maWRhbnQiLCAiIiksDQogICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAicmlnaHQiKSArDQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpDQoNCg0KKGZpZ3VyZSA8LSBnZ2FycmFuZ2UocGxvdDEsIHBsb3QyLCBuY29sPTIsIGFsaWduPSJodiIsIHdpZHRocyA9IGMoMSwxLjIpKSkNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KZ2dzYXZlKGZpZ3VyZSwgDQogICAgICAgZmlsZSA9ICIuL2ZpZ3VyZXMvYW1lYW1pZTIucG5nIiwNCiAgICAgICBkcGkgPSAzMjAsIA0KICAgICAgIHdpZHRoID0gNywNCiAgICAgICBoZWlnaHQgPSA0KQ0KYGBgDQoNCiMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCjxicj4NCg0KIyMgc2VwYXJhdGUgYW5hbHlzZXMgYnkgdGllIHR5cGUgey50YWJzZXQgLnRhYnNldC1mYWRlfQ0KDQpBTUlFcyBwcm92aWRlIGEgY2xlYXIgKmNhdXNhbCogaW50ZXJwcmV0YXRpb24gKGkuZS4sIGhvdyBhbiBBTUUgY2hhbmdlcyB3aGVuIGNvbXBhcmluZyBhIHNwZWNpZmljIHR5cGUgb2YgdGllLCB3aGVuIGNvbXBhcmVkIHRvIGNvbmZpZGFudHMpLCBidXQgdGhleSBsYWNrIGEgY2xlYXIgKmRlc2NyaXB0aXZlKiBpbnRlcnByZXRhdGlvbiwgcmVnYXJkaW5nIHRoZSBzaWduaWZpY2FuY2UgYW5kIHZhbGVuY2Ugb2YgQU1FcyBhY3Jvc3MgcmVsYXRpb25hbCByb2xlcy4gVG8gZW5oYW5jZSBvdXIgaW50ZXJwcmV0YXRpb24gb2YgQU1JRXMsIHdlIHdpbGwgY29tcHV0ZSBBTUVzIChhbmQgQU1NRXMpIGZvciBlYWNoIHNwZWNpZmljIG5ldHdvcmsgbGF5ZXIuIFRoaXMgZW5hYmxlcyB1cyB0bzoNCg0KLSBhc3Nlc3MgdGhlIHNpZ24gYW5kIHNpZ25pZmljYW5jZSBvZiBBTUVzIHBlciByZWxhdGlvbmFsIHJvbGUNCi0gdGVzdCBtZWRpYXRpb24gZWZmZWN0cyAoQU1NRXMpIHBlciByZWxhdGlvbmFsIHJvbGUNCg0KPGJyPg0KDQojIyMgY29uZmlkYW50cw0KDQojIyMjIDEuIGNyZWF0ZSBuZXcgZGF0YXNldHMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCiNkaXNzaW1pbGFyaXR5DQpkZmNvbmZpZGFudGdlbmRlcjEgPC0gZGZjb25maWRhbnRnZW5kZXIwIDwtIGRmY29uZmlkYW50DQpkZmNvbmZpZGFudGFnZXBsdXMgPC0gZGZjb25maWRhbnRhZ2VtaW4gPC0gZGZjb25maWRhbnQNCmRmY29uZmlkYW50ZWR1YzEgPC0gZGZjb25maWRhbnRlZHVjMCA8LSBkZmNvbmZpZGFudA0KDQpkZmNvbmZpZGFudGdlbmRlcjEkZGlmZmVyZW50X2dlbmRlciA8LSAxDQpkZmNvbmZpZGFudGdlbmRlcjAkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZmNvbmZpZGFudGVkdWMxJGRpZmZlcmVudF9lZHVjIDwtIDENCmRmY29uZmlkYW50ZWR1YzAkZGlmZmVyZW50X2VkdWMgPC0gMA0KDQojZGVmaW5lIHNtYWxsIHN0ZXAgZm9yIGNvbnRpbnVvdXMgdmFyaWFibGUNCnMgPC0gLjAwMQ0KZGZjb25maWRhbnRhZ2VwbHVzJGRpZl9hZ2UgPC0gZGZjb25maWRhbnQkZGlmX2FnZSArIHMNCmRmY29uZmlkYW50YWdlbWluJGRpZl9hZ2UgPC0gZGZjb25maWRhbnQkZGlmX2FnZSAtIHMNCg0KI2VtYmVkZGVkbmVzcw0KZGZjb25maWRhbnRjbG9zZXBsdXMgPC0gZGZjb25maWRhbnRjbG9zZW1pbiA8LSBkZmNvbmZpZGFudA0KZGZjb25maWRhbnRjbG9zZXBsdXMkY2xvc2VuZXNzLnQgPC0gZGZjb25maWRhbnQkY2xvc2VuZXNzLnQgKyBzDQpkZmNvbmZpZGFudGNsb3NlbWluJGNsb3NlbmVzcy50IDwtIGRmY29uZmlkYW50JGNsb3NlbmVzcy50IC0gcw0KDQpkZmNvbmZpZGFudG11bHRpcGx1cyA8LSBkZmNvbmZpZGFudG11bHRpbWluIDwtIGRmY29uZmlkYW50DQpkZmNvbmZpZGFudG11bHRpcGx1cyRtdWx0aXBsZXggPC0gZGZjb25maWRhbnQkbXVsdGlwbGV4ICsgcw0KZGZjb25maWRhbnRtdWx0aW1pbiRtdWx0aXBsZXggPC0gZGZjb25maWRhbnQkbXVsdGlwbGV4IC0gcw0KDQpkZmNvbmZpZGFudGZlbWJlZHBsdXMgPC0gZGZjb25maWRhbnRmZW1iZWRtaW4gPC0gZGZjb25maWRhbnQNCmRmY29uZmlkYW50ZmVtYmVkcGx1cyRlbWJlZCA8LSBkZmNvbmZpZGFudCRlbWJlZCArIHMNCmRmY29uZmlkYW50ZmVtYmVkbWluJGVtYmVkIDwtIGRmY29uZmlkYW50JGVtYmVkIC0gcw0KDQpkZmNvbmZpZGFudG9lbWJlZHBsdXMgPC0gZGZjb25maWRhbnRvZW1iZWRtaW4gPC0gZGZjb25maWRhbnQNCmRmY29uZmlkYW50b2VtYmVkcGx1cyRlbWJlZC5leHQgPC0gZGZjb25maWRhbnQkZW1iZWQuZXh0ICsgcw0KZGZjb25maWRhbnRvZW1iZWRtaW4kZW1iZWQuZXh0IDwtIGRmY29uZmlkYW50JGVtYmVkLmV4dCAtIHMNCmBgYA0KDQojIyMjIDIuIGdldCBtb2RlbHMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCm0xIDwtIGFuc2NvbmZpZGFudFtbMl1dICNiYXNlDQptMiA8LSBhbnNjb25maWRhbnRbWzNdXSAjK21lZGlhdG9yIDEgKHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzKQ0KbTMgPC0gYW5zY29uZmlkYW50W1s0XV0gIyttZWRpYXRvciAyIChzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcykNCm00IDwtIGFuc2NvbmZpZGFudFtbNV1dICMrYm90aCBtZWRpYXRvcnMNCmBgYA0KDQojIyMjIDMuIGNyZWF0ZSBmcHJlZCgpIGZ1bmN0aW9ucw0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0KIzEuIEFNRXMgZGlzc2ltaWxhcml0aWVzIGJhc2UgbW9kZWwNCmZwcmVkMSA8LSBmdW5jdGlvbihtMSkgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY29uZmlkYW50Z2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNvbmZpZGFudGdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmY29uZmlkYW50YWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY29uZmlkYW50ZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojMi4gYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzDQpmcHJlZDIgPC0gZnVuY3Rpb24obTIpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNvbmZpZGFudGdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY29uZmlkYW50YWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNvbmZpZGFudGFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNvbmZpZGFudGVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmY29uZmlkYW50ZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YykNCn0NCg0KIzMuIGFmdGVyIGNvbnRyb2xsaW5nIGZvciBzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcw0KZnByZWQzIDwtIGZ1bmN0aW9uKG0zKSB7DQogICAgbWVfZ2VuZGVyIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRnZW5kZXIxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmY29uZmlkYW50Z2VuZGVyMCkNCiAgYW1lX2dlbmRlciA8LSBtZWFuKG1lX2dlbmRlcikNCiAgDQogIG1lX2FnZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNvbmZpZGFudGFnZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRhZ2VtaW4pKS8oMiAqIHMpDQogIGFtZV9hZ2UgPC0gbWVhbihtZV9hZ2UpDQogIA0KICBtZV9lZHVjIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRlZHVjMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNvbmZpZGFudGVkdWMwKQ0KICBhbWVfZWR1YyA8LSBtZWFuKG1lX2VkdWMpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMpDQp9DQoNCiM0LiBhZnRlciBjb250cm9sbGluZyBmb3IgYm90aCBtZWRpYXRvcnMNCmZwcmVkNCA8LSBmdW5jdGlvbihtNCkgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY29uZmlkYW50Z2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNvbmZpZGFudGdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmY29uZmlkYW50YWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmY29uZmlkYW50ZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KICANCiAgI2Fsc28gQU1FcyBvZiBlbWJlZGRlZG5lc3MNCiAgbWVfY2xvc2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRjbG9zZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRjbG9zZW1pbikpLygyICogcykNCiAgYW1lX2Nsb3NlIDwtIG1lYW4obWVfY2xvc2UpDQogIHN1bW1hcnkobTQpDQogIA0KICBtZV9tdWx0aSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNvbmZpZGFudG11bHRpcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmNvbmZpZGFudG11bHRpbWluKSkvKDIgKiBzKQ0KICBhbWVfbXVsdGkgPC0gbWVhbihtZV9tdWx0aSkNCiAgDQogIG1lX2ZlbWJlZCA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmNvbmZpZGFudGZlbWJlZHBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZjb25maWRhbnRmZW1iZWRtaW4pKS8oMiAqIHMpDQogIGFtZV9mZW1iZWQgPC0gbWVhbihtZV9mZW1iZWQpDQogIA0KICBtZV9vZW1iZWQgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZjb25maWRhbnRvZW1iZWRwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmY29uZmlkYW50b2VtYmVkbWluKSkvKDIgKiBzKQ0KICBhbWVfb2VtYmVkIDwtIG1lYW4obWVfb2VtYmVkKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjLGFtZV9jbG9zZSxhbWVfbXVsdGksYW1lX2ZlbWJlZCxhbWVfb2VtYmVkKQ0KfQ0KDQojZnByZWQxKG0xKQ0KI2ZwcmVkMihtMikNCiNmcHJlZDMobTMpDQojZnByZWQ0KG00KQ0KYGBgDQoNCiMjIyMgNC4gYm9vdHN0cmFwIEFNRXMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCnNlZWQgPC0gMjQyNTMyMw0Kbkl0ZXIgPC0gNTAwDQoNCm5Db3JlIDwtIHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpDQpteWNsIDwtIG1ha2VDbHVzdGVyKHJlcCgibG9jYWxob3N0IiwgbkNvcmUpKQ0KY2x1c3RlckV2YWxRKG15Y2wsIGxpYnJhcnkobG1lNCkpDQpjbHVzdGVyRXhwb3J0KG15Y2wsIHZhcmxpc3QgPSBjKA0KICAibTEiLCAibTIiLCAibTMiLCAibTQiLCAicyIsICJzZWVkIiwNCiAgImRmY29uZmlkYW50Z2VuZGVyMSIsICJkZmNvbmZpZGFudGdlbmRlcjAiLCAiZGZjb25maWRhbnRhZ2VwbHVzIiwgImRmY29uZmlkYW50YWdlbWluIiwgImRmY29uZmlkYW50ZWR1YzEiLCAiZGZjb25maWRhbnRlZHVjMCIsDQogICJkZmNvbmZpZGFudGNsb3NlcGx1cyIsICJkZmNvbmZpZGFudGNsb3NlbWluIiwgImRmY29uZmlkYW50bXVsdGlwbHVzIiwgImRmY29uZmlkYW50bXVsdGltaW4iLCAiZGZjb25maWRhbnRmZW1iZWRwbHVzIiwgImRmY29uZmlkYW50ZmVtYmVkbWluIiwNCiAgImRmY29uZmlkYW50b2VtYmVkcGx1cyIsICJkZmNvbmZpZGFudG9lbWJlZG1pbiIpKQ0KDQpzeXN0ZW0udGltZSAoYm9vX20xIDwtIGJvb3RNZXIobTEsIGZwcmVkMSwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20yIDwtIGJvb3RNZXIobTIsIGZwcmVkMiwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20zIDwtIGJvb3RNZXIobTMsIGZwcmVkMywgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX200IDwtIGJvb3RNZXIobTQsIGZwcmVkNCwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQoNCmJvb0wgPC0gbGlzdChib29fbTEsYm9vX20yLGJvb19tMyxib29fbTQpDQpzYXZlKGJvb0wsIGZpbGUgPSAiLi9yZXN1bHRzL2Jvb3RfY29uZmlkYW50cy5SZGEiKQ0Kc3RvcENsdXN0ZXIobXljbCkNCmBgYA0KDQojIyMjIDUuIGNvbnN0cnVjdCBwbG90IGRhdGFzZXQNCg0KYGBge3IsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCm5JdGVyID0gNTAwDQpsb2FkKCIuL3Jlc3VsdHMvYm9vdF9jb25maWRhbnRzLnJkYSIpICANCg0KI0FNRXMgZGlzc2ltaWxhcml0aWVzDQpwbG90ZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBwcmVkID0gcmVwKGMoIkRpZmZlcmVudFxuZ2VuZGVyIiwiQWdlXG5kaWZmZXJlbmNlIiwgIkRpZmZlcmVudFxuZWR1Y2F0aW9uIiksIDQpLA0KICBtb2RlbCA9IHJlcChjKCJNMyIsICJNNCIsICJNNSIsICJNNiIpLCBlYWNoPTMpLA0KICBhbWUgPSBjKGJvb0xbWzFdXSR0MCwgYm9vTFtbMl1dJHQwLCBib29MW1szXV0kdDAsIGJvb0xbWzRdXSR0MFsxOjNdKSwNCiAgYW1lX3NlID0gYyhhcHBseShib29MW1sxXV0kdCwgMiwgc2QpLCBhcHBseShib29MW1syXV0kdCwgMiwgc2QpLCBhcHBseShib29MW1szXV0kdCwgMiwgc2QpLA0KICAgICAgICAgICAgIGFwcGx5KGJvb0xbWzRdXSR0LCAyLCBzZClbMTozXSkNCiAgKQ0KDQojQU1NRXMNCnBsb3RkYXRhJGFtbWUgPC0gTkENCnBsb3RkYXRhJGFtbWVfc2UgPC0gTkENCg0KZm9yIChpIGluIGMoMTozKSkgeyAjIGZvciBkaXNzaW1pbGFyaXR5IGdyb3VuZA0KICBmb3IgKGogaW4gYygyOjQpKSB7ICMgZm9yIGV4dGVuZGVkIG1vZGVsDQogICAgI2dldCBBTUVzIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBiYXNlbGluZSBtb2RlbA0KICAgIGFtZV9pX2Jhc2UgPC0gYm9vTFtbMV1dJHRbLCBpXSANCiAgICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIGV4dGVuZGVkIG1vZGVsIGoNCiAgICBhbWVfaV9tb2RlbGogPC0gYm9vTFtbal1dJHRbLCBpXQ0KICAgICNjYWxjdWxhdGUgY3Jvc3MtbW9kZWwgQU1FIGRpZmZlcmVuY2UgcGVyIGJvb3RzdHJhcCBpdGVyYXRpb24NCiAgICBjbV9hbWVfZGlmcyA8LSBhbWVfaV9iYXNlIC0gYW1lX2lfbW9kZWxqDQogICAgI2NhbGN1bGF0ZSBhdmVyYWdlIG1hcmdpbmFsIG1lZGlhdGlvbiBlZmZlY3QgYnkgdGFraW5nIHRoZSBhdmVyYWdlIA0KICAgIHBsb3RkYXRhJGFtbWVbcGxvdGRhdGEkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEkcHJlZClbaV0gJiBwbG90ZGF0YSRtb2RlbCA9PSB1bmlxdWUocGxvdGRhdGEkbW9kZWwpW2pdXSA8LSBtZWFuKGNtX2FtZV9kaWZzKQ0KICAgICNhbmQgU0UNCiAgICBwbG90ZGF0YSRhbW1lX3NlW3Bsb3RkYXRhJHByZWQgPT0gdW5pcXVlKHBsb3RkYXRhJHByZWQpW2ldICYgcGxvdGRhdGEkbW9kZWwgPT0gdW5pcXVlKHBsb3RkYXRhJG1vZGVsKVtqXV0gPC0gc2QoY21fYW1lX2RpZnMpL3NxcnQobkl0ZXIpDQogICAgfQ0KfQ0KDQpwbG90ZGF0YTIgPC0gZGF0YS5mcmFtZSgNCiAgcHJlZCA9IGMoIkRpZmZlcmVudFxuZ2VuZGVyIiwiQWdlXG5kaWZmZXJlbmNlIiwgIkRpZmZlcmVudFxuZWR1Y2F0aW9uIiksDQogIG1vZGVsID0gIk00LU02IiwNCiAgYW1lID0gTkEsIGFtZV9zZSA9IE5BLCBhbW1lID0gTkEsIGFtbWVfc2UgPSBOQSkNCg0KZm9yIChpIGluIGMoMTozKSkgew0KICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIG1vZGVsIDIgKGluY2x1ZGluZyByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcyBvbmx5KQ0KICBhbWVfaV9iYXNlIDwtIGJvb0xbWzJdXSR0WyxpXQ0KICAjZ2V0IEFNRSBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgZXh0ZW5kZWQgbW9kZWwgNCAoYWRkaW5nIGFsc28gc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MpDQogIGFtZV9pX21vZGVsaiA8LSBib29MW1s0XV0kdFssaV0NCiAgI2NhbGN1bGF0ZSBjcm9zcy1tb2RlbCBBTUUgZGlmZmVyZW5jZQ0KICBjbV9hbWVfZGlmcyA8LSBhbWVfaV9iYXNlIC0gYW1lX2lfbW9kZWxqDQogICNjYWxjdWFsdGUgYXZlcmFnZSBtYXJnaW5hbCBtZWRpYXRpb24NCiAgcGxvdGRhdGEyJGFtbWVbcGxvdGRhdGEyJHByZWQgPT0gdW5pcXVlKHBsb3RkYXRhMiRwcmVkKVtpXV0gPC0gbWVhbihjbV9hbWVfZGlmcykNCiAgI2FuZCBTRQ0KICBwbG90ZGF0YTIkYW1tZV9zZVtwbG90ZGF0YTIkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEyJHByZWQpW2ldXSA8LSBzZChjbV9hbWVfZGlmcykvc3FydChuSXRlcikNCiAgfQ0KDQojQU1FIGVtYmVkZGVkbmVzcw0KcGxvdGRhdGEzIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSBjKCJFbW90aW9uYWxcbmNsb3NlbmVzcyIsIA0KICAgICAgICAgICAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiwNCiAgICAgICAgICAgIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIsDQogICAgICAgICAgICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIiksDQogIG1vZGVsID0gIk02IiwNCiAgYW1lID0gIGJvb0xbWzRdXSR0MFs0OjddLA0KICBhbWVfc2UgPSBhcHBseShib29MW1s0XV0kdCwgMiwgc2QpWzQ6N10pDQoNCmJpbmRfcm93cyhwbG90ZGF0YSxwbG90ZGF0YTIscGxvdGRhdGEzKSAtPiBwbG90ZGF0YQ0KDQpwbG90ZGF0YSRwcmVkIDwtIGZhY3RvcihwbG90ZGF0YSRwcmVkLCBsZXZlbHMgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsICJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iLCAiRW1vdGlvbmFsXG5jbG9zZW5lc3MiLCANCiAgICAgICAgICAgIlJlbGF0aW9uYWxcbm11bHRpcGxleGl0eSIsIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIsDQogICAgICAgICAgICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIikpDQpwbG90ZGF0YSRtb2RlbCA8LSBmYWN0b3IocGxvdGRhdGEkbW9kZWwsIGxldmVscyA9IHJldihjKCJNMiIsICJNNCIsICJNNSIsICJNNiIsIk00LU02IikpKQ0KcGxvdGRhdGEgPC0gcGxvdGRhdGFbb3JkZXIocGxvdGRhdGEkcHJlZCksXQ0Kcm93Lm5hbWVzKHBsb3RkYXRhKSA8LSAxOm5yb3cocGxvdGRhdGEpDQpgYGANCg0KIyMjIyA2LiByZXN1bHQNCg0KYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTUsIGNsYXNzLnNvdXJjZSA9ICdmb2xkLWhpZGUnLCB3YXJuaW5nPUZBTFNFICxtZXNzYWdlPUZBTFNFfQ0KI3Bsb3QgMTogQU1Fcw0KcGxvdDEgPC0gZ2dwbG90KHBsb3RkYXRhLCBhZXMoeCA9IGFtZSwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCkpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyAjdmVydGljYWwgbGluZSBhdCAwDQogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGNvbG9yID0gImJsdWUiKSArICNwb2ludCBpbmRpY2F0aW5nIG9ic2VydmVkIEFNRQ0KICAjZ2VvbV9wb2ludChhZXMoeCA9IGFtZV9iLCB5ID0gbW9kZWwsIGZpbGwgPSBwcmVkKSwgc2l6ZSA9IDMsIHNoYXBlID0gNCkgKyAjY3Jvc3MgaW5kaWNhdGluZyBhdmVyYWdlIGJvb3RzdHJhcCBBTUUgZXN0aW1hdGUNCiAgZ2VvbV9lcnJvcmJhcihhZXMoeG1pbiA9IGFtZSAtIDEuOTYqYW1lX3NlLCB4bWF4ID0gYW1lICsgMS45NiphbWVfc2UpLCBjb2xvcj0iYmx1ZSIsIHdpZHRoPS41KSArICNlcnJvciBiYXJzIGZvciA5NSUgQ0kNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArICNhcnJhbmdlIGZhY2V0cyBieSBkaXNzaW1pbGFyaXR5IHR5cGUNCiAgbGFicyh4ID0gIkFNRSIpICsgI3JlbmFtZSB4LWF4aXMgbmFtZQ0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0wLjI1LCAwLjMwKSkgKyAjeC1heGlzIHRvICUtcG9pbnQsIGFuZCBzZXQgcmFuZ2UNCiAgdGhlbWUoICNjdXN0b21pemUgdGhlbWUNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsdWUiKSwNCiAgICBzdHJpcC50ZXh0LnkubGVmdCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsNCiAgICBnZ2g0eDo6ZmFjZXR0ZWRfcG9zX3NjYWxlcyh5ID0gbGlzdCggI2N1c3RvbWl6ZSB5IGF4aXMgcGVyIGZhY2V0Li4NCiAgICAgIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygiIiwgIk02IiwgIk01IiwgIk00IiwgIk0zIikpLA0KICAgICAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygiIiwgIk02IiwgIk01IiwgIk00IiwgIk0zIikpLA0KICAgICAgcHJlZCA9PSAiRGlmZmVyZW50XG5lZHVjYXRpb24iIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICJNNiIpLA0KICAgICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gIk02IiksDQogICAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKSwNCiAgICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKQ0KICAgICAgKSkNCg0KcGxvdDIgPC0gZ2dwbG90KHBsb3RkYXRhLCBhZXMoeCA9IGFtbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1tZSAtIDEuOTYqYW1tZV9zZSwgeG1heCA9IGFtbWUgKyAxLjk2KmFtbWVfc2UpLCBjb2xvcj0icmVkIiwgd2lkdGg9LjUpICsNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArDQogIGxhYnMoeCA9ICJBTU1FIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0wLjA1LCAwLjA1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJyZWQiKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsgDQogIGdnaDR4OjpmYWNldHRlZF9wb3Nfc2NhbGVzKHkgPSBsaXN0KCAjY3VzdG9taXplIHkgYXhpcyBwZXIgZmFjZXQuLg0KICAgIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTQiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTQiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiRGlmZmVyZW50XG5lZHVjYXRpb24iIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCLOlCBNNC1NNiIsICLOlCBNMy1NNiIsICLOlCBNMy1NNSIsICLOlCBNMy1NNCIsICIiKSwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IE5VTEwsIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSkpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkNCiAgDQojY29tYmluZSBwbG90cw0KIz9nZ2FycmFuZ2UNCmZzaG93ZGYocGxvdGRhdGEsZGlnaXRzPTMpDQpmaWd1cmUgPC0gZ2dhcnJhbmdlKHBsb3QxLCBwbG90MiwgbmNvbD0yLCB3aWR0aHM9YygxLjEsIDEpKQ0KKGZpZ3VyZSA8LSBhbm5vdGF0ZV9maWd1cmUoZmlndXJlLCB0b3AgPSB0ZXh0X2dyb2IoIkNvbmZpZGFudHMiLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpKQ0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KZ2dzYXZlKGZpZ3VyZSwgDQogICAgICAgZmlsZSA9ICIuL2ZpZ3VyZXMvYW1lYW1tZV9jb25maWRhbnQucG5nIiwNCiAgICAgICBkcGkgPSAzMjAsIA0KICAgICAgIHdpZHRoID0gOCwNCiAgICAgICBoZWlnaHQgPSA1KQ0KYGBgDQoNCiMjIyBiZXN0IGZyaWVuZHMNCg0KIyMjIyAxLiBjcmVhdGUgbmV3IGRhdGFzZXRzDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQojZGlzc2ltaWxhcml0eQ0KZGZmcmllbmRnZW5kZXIxIDwtIGRmZnJpZW5kZ2VuZGVyMCA8LSBkZmZyaWVuZA0KZGZmcmllbmRhZ2VwbHVzIDwtIGRmZnJpZW5kYWdlbWluIDwtIGRmZnJpZW5kDQpkZmZyaWVuZGVkdWMxIDwtIGRmZnJpZW5kZWR1YzAgPC0gZGZmcmllbmQNCg0KZGZmcmllbmRnZW5kZXIxJGRpZmZlcmVudF9nZW5kZXIgPC0gMQ0KZGZmcmllbmRnZW5kZXIwJGRpZmZlcmVudF9nZW5kZXIgPC0gMA0KZGZmcmllbmRlZHVjMSRkaWZmZXJlbnRfZWR1YyA8LSAxDQpkZmZyaWVuZGVkdWMwJGRpZmZlcmVudF9lZHVjIDwtIDANCg0KI2RlZmluZSBzbWFsbCBzdGVwIGZvciBjb250aW51b3VzIHZhcmlhYmxlDQpzIDwtIC4wMDENCmRmZnJpZW5kYWdlcGx1cyRkaWZfYWdlIDwtIGRmZnJpZW5kJGRpZl9hZ2UgKyBzDQpkZmZyaWVuZGFnZW1pbiRkaWZfYWdlIDwtIGRmZnJpZW5kJGRpZl9hZ2UgLSBzDQoNCiNlbWJlZGRlZG5lc3MNCmRmZnJpZW5kY2xvc2VwbHVzIDwtIGRmZnJpZW5kY2xvc2VtaW4gPC0gZGZmcmllbmQNCmRmZnJpZW5kY2xvc2VwbHVzJGNsb3NlbmVzcy50IDwtIGRmZnJpZW5kJGNsb3NlbmVzcy50ICsgcw0KZGZmcmllbmRjbG9zZW1pbiRjbG9zZW5lc3MudCA8LSBkZmZyaWVuZCRjbG9zZW5lc3MudCAtIHMNCg0KZGZmcmllbmRtdWx0aXBsdXMgPC0gZGZmcmllbmRtdWx0aW1pbiA8LSBkZmZyaWVuZA0KZGZmcmllbmRtdWx0aXBsdXMkbXVsdGlwbGV4IDwtIGRmZnJpZW5kJG11bHRpcGxleCArIHMNCmRmZnJpZW5kbXVsdGltaW4kbXVsdGlwbGV4IDwtIGRmZnJpZW5kJG11bHRpcGxleCAtIHMNCg0KZGZmcmllbmRmZW1iZWRwbHVzIDwtIGRmZnJpZW5kZmVtYmVkbWluIDwtIGRmZnJpZW5kDQpkZmZyaWVuZGZlbWJlZHBsdXMkZW1iZWQgPC0gZGZmcmllbmQkZW1iZWQgKyBzDQpkZmZyaWVuZGZlbWJlZG1pbiRlbWJlZCA8LSBkZmZyaWVuZCRlbWJlZCAtIHMNCg0KZGZmcmllbmRvZW1iZWRwbHVzIDwtIGRmZnJpZW5kb2VtYmVkbWluIDwtIGRmZnJpZW5kDQpkZmZyaWVuZG9lbWJlZHBsdXMkZW1iZWQuZXh0IDwtIGRmZnJpZW5kJGVtYmVkLmV4dCArIHMNCmRmZnJpZW5kb2VtYmVkbWluJGVtYmVkLmV4dCA8LSBkZmZyaWVuZCRlbWJlZC5leHQgLSBzDQpgYGANCg0KIyMjIyAyLiBnZXQgbW9kZWxzDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQptMSA8LSBhbnNmcmllbmRbWzJdXSAjYmFzZQ0KbTIgPC0gYW5zZnJpZW5kW1szXV0gIyttZWRpYXRvciAxIChyZWxhdGlvbmFsIGVtYmVkZGVkbmVzcykNCm0zIDwtIGFuc2ZyaWVuZFtbNF1dICMrbWVkaWF0b3IgMiAoc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MpDQptNCA8LSBhbnNmcmllbmRbWzVdXSAjK2JvdGggbWVkaWF0b3JzDQpgYGANCg0KIyMjIyAzLiBjcmVhdGUgZnByZWQoKSBmdW5jdGlvbnMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCiMxLiBBTUVzIGRpc3NpbWlsYXJpdGllcyBiYXNlIG1vZGVsDQpmcHJlZDEgPC0gZnVuY3Rpb24obTEpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZyaWVuZGdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmcmllbmRnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kYWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZyaWVuZGFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZyaWVuZGVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YykNCn0NCg0KIzIuIGFmdGVyIGNvbnRyb2xsaW5nIGZvciByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcw0KZnByZWQyIDwtIGZ1bmN0aW9uKG0yKSB7DQogICAgbWVfZ2VuZGVyIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmcmllbmRnZW5kZXIxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kZ2VuZGVyMCkNCiAgYW1lX2dlbmRlciA8LSBtZWFuKG1lX2dlbmRlcikNCiAgDQogIG1lX2FnZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZyaWVuZGFnZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmcmllbmRhZ2VtaW4pKS8oMiAqIHMpDQogIGFtZV9hZ2UgPC0gbWVhbihtZV9hZ2UpDQogIA0KICBtZV9lZHVjIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmcmllbmRlZHVjMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZyaWVuZGVkdWMwKQ0KICBhbWVfZWR1YyA8LSBtZWFuKG1lX2VkdWMpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMpDQp9DQoNCiMzLiBhZnRlciBjb250cm9sbGluZyBmb3Igc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MNCmZwcmVkMyA8LSBmdW5jdGlvbihtMykgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kZ2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZyaWVuZGdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmcmllbmRhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kYWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmcmllbmRlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojNC4gYWZ0ZXIgY29udHJvbGxpbmcgZm9yIGJvdGggbWVkaWF0b3JzDQpmcHJlZDQgPC0gZnVuY3Rpb24obTQpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZyaWVuZGdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmcmllbmRnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kYWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZyaWVuZGFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZmZyaWVuZGVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCiAgDQogICNhbHNvIEFNRXMgb2YgZW1iZWRkZWRuZXNzDQogIG1lX2Nsb3NlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kY2xvc2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kY2xvc2VtaW4pKS8oMiAqIHMpDQogIGFtZV9jbG9zZSA8LSBtZWFuKG1lX2Nsb3NlKQ0KICBzdW1tYXJ5KG00KQ0KICANCiAgbWVfbXVsdGkgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmcmllbmRtdWx0aXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZmcmllbmRtdWx0aW1pbikpLygyICogcykNCiAgYW1lX211bHRpIDwtIG1lYW4obWVfbXVsdGkpDQogIA0KICBtZV9mZW1iZWQgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZmcmllbmRmZW1iZWRwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmZnJpZW5kZmVtYmVkbWluKSkvKDIgKiBzKQ0KICBhbWVfZmVtYmVkIDwtIG1lYW4obWVfZmVtYmVkKQ0KICANCiAgbWVfb2VtYmVkIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmZnJpZW5kb2VtYmVkcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZmZyaWVuZG9lbWJlZG1pbikpLygyICogcykNCiAgYW1lX29lbWJlZCA8LSBtZWFuKG1lX29lbWJlZCkNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YyxhbWVfY2xvc2UsYW1lX211bHRpLGFtZV9mZW1iZWQsYW1lX29lbWJlZCkNCn0NCg0KI2ZwcmVkMShtMSkNCiNmcHJlZDIobTIpDQojZnByZWQzKG0zKQ0KI2ZwcmVkNChtNCkNCmBgYA0KDQojIyMjIDQuIGJvb3RzdHJhcCBBTUVzDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQpzZWVkIDwtIDI0MjUzMjMNCm5JdGVyIDwtIDUwMA0KDQpuQ29yZSA8LSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSANCm15Y2wgPC0gbWFrZUNsdXN0ZXIocmVwKCJsb2NhbGhvc3QiLCBuQ29yZSkpDQpjbHVzdGVyRXZhbFEobXljbCwgbGlicmFyeShsbWU0KSkNCmNsdXN0ZXJFeHBvcnQobXljbCwgdmFybGlzdCA9IGMoDQogICJtMSIsICJtMiIsICJtMyIsICJtNCIsICJzIiwgInNlZWQiLA0KICAiZGZmcmllbmRnZW5kZXIxIiwgImRmZnJpZW5kZ2VuZGVyMCIsICJkZmZyaWVuZGFnZXBsdXMiLCAiZGZmcmllbmRhZ2VtaW4iLCAiZGZmcmllbmRlZHVjMSIsICJkZmZyaWVuZGVkdWMwIiwNCiAgImRmZnJpZW5kY2xvc2VwbHVzIiwgImRmZnJpZW5kY2xvc2VtaW4iLCAiZGZmcmllbmRtdWx0aXBsdXMiLCAiZGZmcmllbmRtdWx0aW1pbiIsICJkZmZyaWVuZGZlbWJlZHBsdXMiLCAiZGZmcmllbmRmZW1iZWRtaW4iLA0KICAiZGZmcmllbmRvZW1iZWRwbHVzIiwgImRmZnJpZW5kb2VtYmVkbWluIikpDQoNCnN5c3RlbS50aW1lIChib29fbTEgPC0gYm9vdE1lcihtMSwgZnByZWQxLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTIgPC0gYm9vdE1lcihtMiwgZnByZWQyLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTMgPC0gYm9vdE1lcihtMywgZnByZWQzLCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCnN5c3RlbS50aW1lIChib29fbTQgPC0gYm9vdE1lcihtNCwgZnByZWQ0LCBuc2ltID0gbkl0ZXIsIHBhcmFsbGVsID0gInNub3ciLCBuY3B1cyA9IG5Db3JlLCBjbCA9IG15Y2wsIHNlZWQgPSBzZWVkKSkNCg0KYm9vTCA8LSBsaXN0KGJvb19tMSxib29fbTIsYm9vX20zLGJvb19tNCkNCnNhdmUoYm9vTCwgZmlsZSA9ICIuL3Jlc3VsdHMvYm9vdF9mcmllbmRzLlJkYSIpDQpzdG9wQ2x1c3RlcihteWNsKQ0KYGBgDQoNCiMjIyMgNS4gY29uc3RydWN0IHBsb3QgZGF0YXNldA0KDQpgYGB7ciwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0Kbkl0ZXIgPSA1MDANCmxvYWQoIi4vcmVzdWx0cy9ib290X2ZyaWVuZHMucmRhIikgIA0KDQojQU1FcyBkaXNzaW1pbGFyaXRpZXMNCnBsb3RkYXRhIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSByZXAoYygiRGlmZmVyZW50XG5nZW5kZXIiLCJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSwgNCksDQogIG1vZGVsID0gcmVwKGMoIk0zIiwgIk00IiwgIk01IiwgIk02IiksIGVhY2g9MyksDQogIGFtZSA9IGMoYm9vTFtbMV1dJHQwLCBib29MW1syXV0kdDAsIGJvb0xbWzNdXSR0MCwgYm9vTFtbNF1dJHQwWzE6M10pLA0KICBhbWVfc2UgPSBjKGFwcGx5KGJvb0xbWzFdXSR0LCAyLCBzZCksIGFwcGx5KGJvb0xbWzJdXSR0LCAyLCBzZCksIGFwcGx5KGJvb0xbWzNdXSR0LCAyLCBzZCksDQogICAgICAgICAgICAgYXBwbHkoYm9vTFtbNF1dJHQsIDIsIHNkKVsxOjNdKQ0KICApDQoNCiNBTU1Fcw0KcGxvdGRhdGEkYW1tZSA8LSBOQQ0KcGxvdGRhdGEkYW1tZV9zZSA8LSBOQQ0KDQpmb3IgKGkgaW4gYygxOjMpKSB7ICMgZm9yIGRpc3NpbWlsYXJpdHkgZ3JvdW5kDQogIGZvciAoaiBpbiBjKDI6NCkpIHsgIyBmb3IgZXh0ZW5kZWQgbW9kZWwNCiAgICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIGJhc2VsaW5lIG1vZGVsDQogICAgYW1lX2lfYmFzZSA8LSBib29MW1sxXV0kdFssIGldIA0KICAgICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgZXh0ZW5kZWQgbW9kZWwgag0KICAgIGFtZV9pX21vZGVsaiA8LSBib29MW1tqXV0kdFssIGldDQogICAgI2NhbGN1bGF0ZSBjcm9zcy1tb2RlbCBBTUUgZGlmZmVyZW5jZSBwZXIgYm9vdHN0cmFwIGl0ZXJhdGlvbg0KICAgIGNtX2FtZV9kaWZzIDwtIGFtZV9pX2Jhc2UgLSBhbWVfaV9tb2RlbGoNCiAgICAjY2FsY3VsYXRlIGF2ZXJhZ2UgbWFyZ2luYWwgbWVkaWF0aW9uIGVmZmVjdCBieSB0YWtpbmcgdGhlIGF2ZXJhZ2UgDQogICAgcGxvdGRhdGEkYW1tZVtwbG90ZGF0YSRwcmVkID09IHVuaXF1ZShwbG90ZGF0YSRwcmVkKVtpXSAmIHBsb3RkYXRhJG1vZGVsID09IHVuaXF1ZShwbG90ZGF0YSRtb2RlbClbal1dIDwtIG1lYW4oY21fYW1lX2RpZnMpDQogICAgI2FuZCBTRQ0KICAgIHBsb3RkYXRhJGFtbWVfc2VbcGxvdGRhdGEkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEkcHJlZClbaV0gJiBwbG90ZGF0YSRtb2RlbCA9PSB1bmlxdWUocGxvdGRhdGEkbW9kZWwpW2pdXSA8LSBzZChjbV9hbWVfZGlmcykvc3FydChuSXRlcikNCiAgICB9DQp9DQoNCnBsb3RkYXRhMiA8LSBkYXRhLmZyYW1lKA0KICBwcmVkID0gYygiRGlmZmVyZW50XG5nZW5kZXIiLCJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSwNCiAgbW9kZWwgPSAiTTQtTTYiLA0KICBhbWUgPSBOQSwgYW1lX3NlID0gTkEsIGFtbWUgPSBOQSwgYW1tZV9zZSA9IE5BKQ0KDQpmb3IgKGkgaW4gYygxOjMpKSB7DQogICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgbW9kZWwgMiAoaW5jbHVkaW5nIHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzIG9ubHkpDQogIGFtZV9pX2Jhc2UgPC0gYm9vTFtbMl1dJHRbLGldDQogICNnZXQgQU1FIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBleHRlbmRlZCBtb2RlbCA0IChhZGRpbmcgYWxzbyBzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcykNCiAgYW1lX2lfbW9kZWxqIDwtIGJvb0xbWzRdXSR0WyxpXQ0KICAjY2FsY3VsYXRlIGNyb3NzLW1vZGVsIEFNRSBkaWZmZXJlbmNlDQogIGNtX2FtZV9kaWZzIDwtIGFtZV9pX2Jhc2UgLSBhbWVfaV9tb2RlbGoNCiAgI2NhbGN1YWx0ZSBhdmVyYWdlIG1hcmdpbmFsIG1lZGlhdGlvbg0KICBwbG90ZGF0YTIkYW1tZVtwbG90ZGF0YTIkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEyJHByZWQpW2ldXSA8LSBtZWFuKGNtX2FtZV9kaWZzKQ0KICAjYW5kIFNFDQogIHBsb3RkYXRhMiRhbW1lX3NlW3Bsb3RkYXRhMiRwcmVkID09IHVuaXF1ZShwbG90ZGF0YTIkcHJlZClbaV1dIDwtIHNkKGNtX2FtZV9kaWZzKS9zcXJ0KG5JdGVyKQ0KICB9DQoNCiNBTUUgZW1iZWRkZWRuZXNzDQpwbG90ZGF0YTMgPC0gZGF0YS5mcmFtZSgNCiAgcHJlZCA9IGMoIkVtb3Rpb25hbFxuY2xvc2VuZXNzIiwgDQogICAgICAgICAgICJSZWxhdGlvbmFsXG5tdWx0aXBsZXhpdHkiLA0KICAgICAgICAgICAiU3RyLiBlbWJlZC5cbmZvY2FsIGxheWVyIiwNCiAgICAgICAgICAgIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiKSwNCiAgbW9kZWwgPSAiTTYiLA0KICBhbWUgPSAgYm9vTFtbNF1dJHQwWzQ6N10sDQogIGFtZV9zZSA9IGFwcGx5KGJvb0xbWzRdXSR0LCAyLCBzZClbNDo3XSkNCg0KYmluZF9yb3dzKHBsb3RkYXRhLHBsb3RkYXRhMixwbG90ZGF0YTMpIC0+IHBsb3RkYXRhDQoNCnBsb3RkYXRhJHByZWQgPC0gZmFjdG9yKHBsb3RkYXRhJHByZWQsIGxldmVscyA9IGMoIkRpZmZlcmVudFxuZ2VuZGVyIiwgIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIsICJFbW90aW9uYWxcbmNsb3NlbmVzcyIsIA0KICAgICAgICAgICAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiwiU3RyLiBlbWJlZC5cbmZvY2FsIGxheWVyIiwiU3RyLiBlbWJlZC5cbm90aGVyIGxheWVycyIpKQ0KcGxvdGRhdGEkbW9kZWwgPC0gZmFjdG9yKHBsb3RkYXRhJG1vZGVsLCBsZXZlbHMgPSByZXYoYygiTTMiLCAiTTQiLCAiTTUiLCAiTTYiLCJNNC1NNiIpKSkNCnBsb3RkYXRhIDwtIHBsb3RkYXRhW29yZGVyKHBsb3RkYXRhJHByZWQpLF0NCnJvdy5uYW1lcyhwbG90ZGF0YSkgPC0gMTpucm93KHBsb3RkYXRhKQ0KYGBgDQoNCiMjIyMgNi4gcmVzdWx0DQoNCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01LCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiNwbG90IDE6IEFNRXMNCnBsb3QxIDwtIGdncGxvdChwbG90ZGF0YSwgYWVzKHggPSBhbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgI3ZlcnRpY2FsIGxpbmUgYXQgMA0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJibHVlIikgKyAjcG9pbnQgaW5kaWNhdGluZyBvYnNlcnZlZCBBTUUNCiAgI2dlb21fcG9pbnQoYWVzKHggPSBhbWVfYiwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCksIHNpemUgPSAzLCBzaGFwZSA9IDQpICsgI2Nyb3NzIGluZGljYXRpbmcgYXZlcmFnZSBib290c3RyYXAgQU1FIGVzdGltYXRlDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbWUgLSAxLjk2KmFtZV9zZSwgeG1heCA9IGFtZSArIDEuOTYqYW1lX3NlKSwgY29sb3I9ImJsdWUiLCB3aWR0aD0uNSkgKyAjZXJyb3IgYmFycyBmb3IgOTUlIENJDQogIGZhY2V0X2dyaWQocHJlZCB+Liwgc3dpdGNoID0gInkiLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKyAjYXJyYW5nZSBmYWNldHMgYnkgZGlzc2ltaWxhcml0eSB0eXBlDQogIGxhYnMoeCA9ICJBTUUiKSArICNyZW5hbWUgeC1heGlzIG5hbWUNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygtMC4yNSwgLjMwKSkgKyAjeC1heGlzIHRvICUtcG9pbnQsIGFuZCBzZXQgcmFuZ2UNCiAgdGhlbWUoICNjdXN0b21pemUgdGhlbWUNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsdWUiKSwNCiAgICBzdHJpcC50ZXh0LnkubGVmdCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDApLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksDQogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsNCiAgICBnZ2g0eDo6ZmFjZXR0ZWRfcG9zX3NjYWxlcyh5ID0gbGlzdCggI2N1c3RvbWl6ZSB5IGF4aXMgcGVyIGZhY2V0Li4NCiAgICAgIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygiIiwgIk02IiwgIk01IiwgIk00IiwgIk0zIikpLA0KICAgICAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygiIiwgIk02IiwgIk01IiwgIk00IiwgIk0zIikpLA0KICAgICAgcHJlZCA9PSAiRGlmZmVyZW50XG5lZHVjYXRpb24iIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICJNNiIpLA0KICAgICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gIk02IiksDQogICAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKSwNCiAgICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKQ0KICAgICAgKSkNCg0KcGxvdDIgPC0gZ2dwbG90KHBsb3RkYXRhLCBhZXMoeCA9IGFtbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1tZSAtIDEuOTYqYW1tZV9zZSwgeG1heCA9IGFtbWUgKyAxLjk2KmFtbWVfc2UpLCBjb2xvcj0icmVkIiwgd2lkdGg9LjUpICsNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArDQogIGxhYnMoeCA9ICJBTU1FIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0wLjA1LCAwLjA1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJyZWQiKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsgDQogIGdnaDR4OjpmYWNldHRlZF9wb3Nfc2NhbGVzKHkgPSBsaXN0KCAjY3VzdG9taXplIHkgYXhpcyBwZXIgZmFjZXQuLg0KICAgIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTQiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTQiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiRGlmZmVyZW50XG5lZHVjYXRpb24iIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCLOlCBNNC1NNiIsICLOlCBNMy1NNiIsICLOlCBNMy1NNSIsICLOlCBNMy1NNCIsICIiKSwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IE5VTEwsIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSkpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkNCiAgDQojY29tYmluZSBwbG90cw0KIz9nZ2FycmFuZ2UNCmZzaG93ZGYocGxvdGRhdGEsIGRpZ2l0cz0zKQ0KZmlndXJlIDwtIGdnYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2w9Miwgd2lkdGhzPWMoMS4xLCAxKSkNCihmaWd1cmUgPC0gYW5ub3RhdGVfZmlndXJlKGZpZ3VyZSwgdG9wID0gdGV4dF9ncm9iKCJCZXN0IGZyaWVuZHMiLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpKQ0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KZ2dzYXZlKGZpZ3VyZSwgDQogICAgICAgZmlsZSA9ICIuL2ZpZ3VyZXMvYW1lYW1tZV9mcmllbmQucG5nIiwNCiAgICAgICBkcGkgPSAzMjAsIA0KICAgICAgIHdpZHRoID0gOCwNCiAgICAgICBoZWlnaHQgPSA1KQ0KYGBgDQoNCg0KIyMjIHNwb3J0cyBwYXJ0bmVycw0KDQojIyMjIDEuIGNyZWF0ZSBuZXcgZGF0YXNldHMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCiNkaXNzaW1pbGFyaXR5DQpkZnNwb3J0Z2VuZGVyMSA8LSBkZnNwb3J0Z2VuZGVyMCA8LSBkZnNwb3J0DQpkZnNwb3J0YWdlcGx1cyA8LSBkZnNwb3J0YWdlbWluIDwtIGRmc3BvcnQNCmRmc3BvcnRlZHVjMSA8LSBkZnNwb3J0ZWR1YzAgPC0gZGZzcG9ydA0KDQpkZnNwb3J0Z2VuZGVyMSRkaWZmZXJlbnRfZ2VuZGVyIDwtIDENCmRmc3BvcnRnZW5kZXIwJGRpZmZlcmVudF9nZW5kZXIgPC0gMA0KZGZzcG9ydGVkdWMxJGRpZmZlcmVudF9lZHVjIDwtIDENCmRmc3BvcnRlZHVjMCRkaWZmZXJlbnRfZWR1YyA8LSAwDQoNCiNkZWZpbmUgc21hbGwgc3RlcCBmb3IgY29udGludW91cyB2YXJpYWJsZQ0KcyA8LSAuMDAxDQpkZnNwb3J0YWdlcGx1cyRkaWZfYWdlIDwtIGRmc3BvcnQkZGlmX2FnZSArIHMNCmRmc3BvcnRhZ2VtaW4kZGlmX2FnZSA8LSBkZnNwb3J0JGRpZl9hZ2UgLSBzDQoNCiNlbWJlZGRlZG5lc3MNCmRmc3BvcnRjbG9zZXBsdXMgPC0gZGZzcG9ydGNsb3NlbWluIDwtIGRmc3BvcnQNCmRmc3BvcnRjbG9zZXBsdXMkY2xvc2VuZXNzLnQgPC0gZGZzcG9ydCRjbG9zZW5lc3MudCArIHMNCmRmc3BvcnRjbG9zZW1pbiRjbG9zZW5lc3MudCA8LSBkZnNwb3J0JGNsb3NlbmVzcy50IC0gcw0KDQpkZnNwb3J0bXVsdGlwbHVzIDwtIGRmc3BvcnRtdWx0aW1pbiA8LSBkZnNwb3J0DQpkZnNwb3J0bXVsdGlwbHVzJG11bHRpcGxleCA8LSBkZnNwb3J0JG11bHRpcGxleCArIHMNCmRmc3BvcnRtdWx0aW1pbiRtdWx0aXBsZXggPC0gZGZzcG9ydCRtdWx0aXBsZXggLSBzDQoNCmRmc3BvcnRmZW1iZWRwbHVzIDwtIGRmc3BvcnRmZW1iZWRtaW4gPC0gZGZzcG9ydA0KZGZzcG9ydGZlbWJlZHBsdXMkZW1iZWQgPC0gZGZzcG9ydCRlbWJlZCArIHMNCmRmc3BvcnRmZW1iZWRtaW4kZW1iZWQgPC0gZGZzcG9ydCRlbWJlZCAtIHMNCg0KZGZzcG9ydG9lbWJlZHBsdXMgPC0gZGZzcG9ydG9lbWJlZG1pbiA8LSBkZnNwb3J0DQpkZnNwb3J0b2VtYmVkcGx1cyRlbWJlZC5leHQgPC0gZGZzcG9ydCRlbWJlZC5leHQgKyBzDQpkZnNwb3J0b2VtYmVkbWluJGVtYmVkLmV4dCA8LSBkZnNwb3J0JGVtYmVkLmV4dCAtIHMNCmBgYA0KDQojIyMjIDIuIGdldCBtb2RlbHMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCm0xIDwtIGFuc3Nwb3J0W1syXV0gI2Jhc2UNCm0yIDwtIGFuc3Nwb3J0W1szXV0gIyttZWRpYXRvciAxIChyZWxhdGlvbmFsIGVtYmVkZGVkbmVzcykNCm0zIDwtIGFuc3Nwb3J0W1s0XV0gIyttZWRpYXRvciAyIChzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcykNCm00IDwtIGFuc3Nwb3J0W1s1XV0gIytib3RoIG1lZGlhdG9ycw0KYGBgDQoNCiMjIyMgMy4gY3JlYXRlIGZwcmVkKCkgZnVuY3Rpb25zDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQojMS4gQU1FcyBkaXNzaW1pbGFyaXRpZXMgYmFzZSBtb2RlbA0KZnByZWQxIDwtIGZ1bmN0aW9uKG0xKSB7DQogICAgbWVfZ2VuZGVyIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMSwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGFnZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0ZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGVkdWMwKQ0KICBhbWVfZWR1YyA8LSBtZWFuKG1lX2VkdWMpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMpDQp9DQoNCiMyLiBhZnRlciBjb250cm9sbGluZyBmb3IgcmVsYXRpb25hbCBlbWJlZGRlZG5lc3MNCmZwcmVkMiA8LSBmdW5jdGlvbihtMikgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3BvcnRnZW5kZXIxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3BvcnRnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTIsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3BvcnRhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3BvcnRhZ2VtaW4pKS8oMiAqIHMpDQogIGFtZV9hZ2UgPC0gbWVhbihtZV9hZ2UpDQogIA0KICBtZV9lZHVjIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3BvcnRlZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojMy4gYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHN0cnVjdHVyYWwgZW1iZWRkZWRuZXNzDQpmcHJlZDMgPC0gZnVuY3Rpb24obTMpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0Z2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnNwb3J0Z2VuZGVyMCkNCiAgYW1lX2dlbmRlciA8LSBtZWFuKG1lX2dlbmRlcikNCiAgDQogIG1lX2FnZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG0zLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0YWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnNwb3J0YWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3BvcnRlZHVjMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnNwb3J0ZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YykNCn0NCg0KIzQuIGFmdGVyIGNvbnRyb2xsaW5nIGZvciBib3RoIG1lZGlhdG9ycw0KZnByZWQ0IDwtIGZ1bmN0aW9uKG00KSB7DQogICAgbWVfZ2VuZGVyIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGFnZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0ZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGVkdWMwKQ0KICBhbWVfZWR1YyA8LSBtZWFuKG1lX2VkdWMpDQogIA0KICAjYWxzbyBBTUVzIG9mIGVtYmVkZGVkbmVzcw0KICBtZV9jbG9zZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0Y2xvc2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3BvcnRjbG9zZW1pbikpLygyICogcykNCiAgYW1lX2Nsb3NlIDwtIG1lYW4obWVfY2xvc2UpDQogIHN1bW1hcnkobTQpDQogIA0KICBtZV9tdWx0aSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0bXVsdGlwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3BvcnRtdWx0aW1pbikpLygyICogcykNCiAgYW1lX211bHRpIDwtIG1lYW4obWVfbXVsdGkpDQogIA0KICBtZV9mZW1iZWQgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzcG9ydGZlbWJlZHBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzcG9ydGZlbWJlZG1pbikpLygyICogcykNCiAgYW1lX2ZlbWJlZCA8LSBtZWFuKG1lX2ZlbWJlZCkNCiAgDQogIG1lX29lbWJlZCA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnNwb3J0b2VtYmVkcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnNwb3J0b2VtYmVkbWluKSkvKDIgKiBzKQ0KICBhbWVfb2VtYmVkIDwtIG1lYW4obWVfb2VtYmVkKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjLGFtZV9jbG9zZSxhbWVfbXVsdGksYW1lX2ZlbWJlZCxhbWVfb2VtYmVkKQ0KfQ0KDQojZnByZWQxKG0xKQ0KI2ZwcmVkMihtMikNCiNmcHJlZDMobTMpDQojZnByZWQ0KG00KQ0KYGBgDQoNCiMjIyMgNC4gYm9vdHN0cmFwIEFNRXMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCnNlZWQgPC0gMjQyNTMyMw0Kbkl0ZXIgPC0gNTAwDQpuQ29yZSA8LSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSAtIDENCm15Y2wgPC0gbWFrZUNsdXN0ZXIocmVwKCJsb2NhbGhvc3QiLCBuQ29yZSkpDQpjbHVzdGVyRXZhbFEobXljbCwgbGlicmFyeShsbWU0KSkNCmNsdXN0ZXJFeHBvcnQobXljbCwgdmFybGlzdCA9IGMoDQogICJtMSIsICJtMiIsICJtMyIsICJtNCIsICJzIiwgInNlZWQiLA0KICAiZGZzcG9ydGdlbmRlcjEiLCAiZGZzcG9ydGdlbmRlcjAiLCAiZGZzcG9ydGFnZXBsdXMiLCAiZGZzcG9ydGFnZW1pbiIsICJkZnNwb3J0ZWR1YzEiLCAiZGZzcG9ydGVkdWMwIiwNCiAgImRmc3BvcnRjbG9zZXBsdXMiLCAiZGZzcG9ydGNsb3NlbWluIiwgImRmc3BvcnRtdWx0aXBsdXMiLCAiZGZzcG9ydG11bHRpbWluIiwgImRmc3BvcnRmZW1iZWRwbHVzIiwgImRmc3BvcnRmZW1iZWRtaW4iLA0KICAiZGZzcG9ydG9lbWJlZHBsdXMiLCAiZGZzcG9ydG9lbWJlZG1pbiIpKQ0KDQpzeXN0ZW0udGltZSAoYm9vX20xIDwtIGJvb3RNZXIobTEsIGZwcmVkMSwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20yIDwtIGJvb3RNZXIobTIsIGZwcmVkMiwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20zIDwtIGJvb3RNZXIobTMsIGZwcmVkMywgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX200IDwtIGJvb3RNZXIobTQsIGZwcmVkNCwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQoNCmJvb0wgPC0gbGlzdChib29fbTEsYm9vX20yLGJvb19tMyxib29fbTQpDQpzYXZlKGJvb0wsIGZpbGUgPSAiLi9yZXN1bHRzL2Jvb3Rfc3BvcnRzLlJkYSIpDQpzdG9wQ2x1c3RlcihteWNsKQ0KYGBgDQoNCiMjIyMgNS4gY29uc3RydWN0IHBsb3QgZGF0YXNldA0KDQpgYGB7ciwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0Kbkl0ZXIgPSA1MDANCmxvYWQoIi4vcmVzdWx0cy9ib290X3Nwb3J0cy5yZGEiKSAgDQoNCiNBTUVzIGRpc3NpbWlsYXJpdGllcw0KcGxvdGRhdGEgPC0gZGF0YS5mcmFtZSgNCiAgcHJlZCA9IHJlcChjKCJEaWZmZXJlbnRcbmdlbmRlciIsIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIpLCA0KSwNCiAgbW9kZWwgPSByZXAoYygiTTMiLCAiTTQiLCAiTTUiLCAiTTYiKSwgZWFjaD0zKSwNCiAgYW1lID0gYyhib29MW1sxXV0kdDAsIGJvb0xbWzJdXSR0MCwgYm9vTFtbM11dJHQwLCBib29MW1s0XV0kdDBbMTozXSksDQogIGFtZV9zZSA9IGMoYXBwbHkoYm9vTFtbMV1dJHQsIDIsIHNkKSwgYXBwbHkoYm9vTFtbMl1dJHQsIDIsIHNkKSwgYXBwbHkoYm9vTFtbM11dJHQsIDIsIHNkKSwNCiAgICAgICAgICAgICBhcHBseShib29MW1s0XV0kdCwgMiwgc2QpWzE6M10pDQogICkNCg0KI0FNTUVzDQpwbG90ZGF0YSRhbW1lIDwtIE5BDQpwbG90ZGF0YSRhbW1lX3NlIDwtIE5BDQoNCmZvciAoaSBpbiBjKDE6MykpIHsgIyBmb3IgZGlzc2ltaWxhcml0eSBncm91bmQNCiAgZm9yIChqIGluIGMoMjo0KSkgeyAjIGZvciBleHRlbmRlZCBtb2RlbA0KICAgICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgYmFzZWxpbmUgbW9kZWwNCiAgICBhbWVfaV9iYXNlIDwtIGJvb0xbWzFdXSR0WywgaV0gDQogICAgI2dldCBBTUVzIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBleHRlbmRlZCBtb2RlbCBqDQogICAgYW1lX2lfbW9kZWxqIDwtIGJvb0xbW2pdXSR0WywgaV0NCiAgICAjY2FsY3VsYXRlIGNyb3NzLW1vZGVsIEFNRSBkaWZmZXJlbmNlIHBlciBib290c3RyYXAgaXRlcmF0aW9uDQogICAgY21fYW1lX2RpZnMgPC0gYW1lX2lfYmFzZSAtIGFtZV9pX21vZGVsag0KICAgICNjYWxjdWxhdGUgYXZlcmFnZSBtYXJnaW5hbCBtZWRpYXRpb24gZWZmZWN0IGJ5IHRha2luZyB0aGUgYXZlcmFnZSANCiAgICBwbG90ZGF0YSRhbW1lW3Bsb3RkYXRhJHByZWQgPT0gdW5pcXVlKHBsb3RkYXRhJHByZWQpW2ldICYgcGxvdGRhdGEkbW9kZWwgPT0gdW5pcXVlKHBsb3RkYXRhJG1vZGVsKVtqXV0gPC0gbWVhbihjbV9hbWVfZGlmcykNCiAgICAjYW5kIFNFDQogICAgcGxvdGRhdGEkYW1tZV9zZVtwbG90ZGF0YSRwcmVkID09IHVuaXF1ZShwbG90ZGF0YSRwcmVkKVtpXSAmIHBsb3RkYXRhJG1vZGVsID09IHVuaXF1ZShwbG90ZGF0YSRtb2RlbClbal1dIDwtIHNkKGNtX2FtZV9kaWZzKS9zcXJ0KG5JdGVyKQ0KICAgIH0NCn0NCg0KcGxvdGRhdGEyIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIpLA0KICBtb2RlbCA9ICJNNC1NNiIsDQogIGFtZSA9IE5BLCBhbWVfc2UgPSBOQSwgYW1tZSA9IE5BLCBhbW1lX3NlID0gTkEpDQoNCmZvciAoaSBpbiBjKDE6MykpIHsNCiAgI2dldCBBTUVzIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBtb2RlbCAyIChpbmNsdWRpbmcgcmVsYXRpb25hbCBlbWJlZGRlZG5lc3Mgb25seSkNCiAgYW1lX2lfYmFzZSA8LSBib29MW1syXV0kdFssaV0NCiAgI2dldCBBTUUgb2YgZGlzc2ltaWxhcml0eSBpIG9mIGV4dGVuZGVkIG1vZGVsIDQgKGFkZGluZyBhbHNvIHN0cnVjdHVyYWwgZW1iZWRkZWRuZXNzKQ0KICBhbWVfaV9tb2RlbGogPC0gYm9vTFtbNF1dJHRbLGldDQogICNjYWxjdWxhdGUgY3Jvc3MtbW9kZWwgQU1FIGRpZmZlcmVuY2UNCiAgY21fYW1lX2RpZnMgPC0gYW1lX2lfYmFzZSAtIGFtZV9pX21vZGVsag0KICAjY2FsY3VhbHRlIGF2ZXJhZ2UgbWFyZ2luYWwgbWVkaWF0aW9uDQogIHBsb3RkYXRhMiRhbW1lW3Bsb3RkYXRhMiRwcmVkID09IHVuaXF1ZShwbG90ZGF0YTIkcHJlZClbaV1dIDwtIG1lYW4oY21fYW1lX2RpZnMpDQogICNhbmQgU0UNCiAgcGxvdGRhdGEyJGFtbWVfc2VbcGxvdGRhdGEyJHByZWQgPT0gdW5pcXVlKHBsb3RkYXRhMiRwcmVkKVtpXV0gPC0gc2QoY21fYW1lX2RpZnMpL3NxcnQobkl0ZXIpDQogIH0NCg0KDQojQU1FIGVtYmVkZGVkbmVzcw0KcGxvdGRhdGEzIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSBjKCJFbW90aW9uYWxcbmNsb3NlbmVzcyIsIA0KICAgICAgICAgICAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiwNCiAgICAgICAgICAgIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIsDQogICAgICAgICAgICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIiksDQogIG1vZGVsID0gIk02IiwNCiAgYW1lID0gIGJvb0xbWzRdXSR0MFs0OjddLA0KICBhbWVfc2UgPSBhcHBseShib29MW1s0XV0kdCwgMiwgc2QpWzQ6N10pDQoNCmJpbmRfcm93cyhwbG90ZGF0YSxwbG90ZGF0YTIscGxvdGRhdGEzKSAtPiBwbG90ZGF0YQ0KDQpwbG90ZGF0YSRwcmVkIDwtIGZhY3RvcihwbG90ZGF0YSRwcmVkLCBsZXZlbHMgPSBjKCJEaWZmZXJlbnRcbmdlbmRlciIsICJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iLCAiRW1vdGlvbmFsXG5jbG9zZW5lc3MiLCANCiAgICAgICAgICAgIlJlbGF0aW9uYWxcbm11bHRpcGxleGl0eSIsIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIsIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiKSkNCnBsb3RkYXRhJG1vZGVsIDwtIGZhY3RvcihwbG90ZGF0YSRtb2RlbCwgbGV2ZWxzID0gcmV2KGMoIk0zIiwgIk00IiwgIk01IiwgIk02IiwiTTQtTTYiKSkpDQpwbG90ZGF0YSA8LSBwbG90ZGF0YVtvcmRlcihwbG90ZGF0YSRwcmVkKSxdDQpyb3cubmFtZXMocGxvdGRhdGEpIDwtIDE6bnJvdyhwbG90ZGF0YSkNCmBgYA0KDQojIyMjIDYuIHJlc3VsdA0KDQpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NSwgY2xhc3Muc291cmNlID0gJ2ZvbGQtaGlkZScsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQojcGxvdCAxOiBBTUVzDQpwbG90MSA8LSBnZ3Bsb3QocGxvdGRhdGEsIGFlcyh4ID0gYW1lLCB5ID0gbW9kZWwsIGZpbGwgPSBwcmVkKSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArICN2ZXJ0aWNhbCBsaW5lIGF0IDANCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAiYmx1ZSIpICsgI3BvaW50IGluZGljYXRpbmcgb2JzZXJ2ZWQgQU1FDQogICNnZW9tX3BvaW50KGFlcyh4ID0gYW1lX2IsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpLCBzaXplID0gMywgc2hhcGUgPSA0KSArICNjcm9zcyBpbmRpY2F0aW5nIGF2ZXJhZ2UgYm9vdHN0cmFwIEFNRSBlc3RpbWF0ZQ0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1lIC0gMS45NiphbWVfc2UsIHhtYXggPSBhbWUgKyAxLjk2KmFtZV9zZSksIGNvbG9yPSJibHVlIiwgd2lkdGg9LjUpICsgI2Vycm9yIGJhcnMgZm9yIDk1JSBDSQ0KICBmYWNldF9ncmlkKHByZWQgfi4sIHN3aXRjaCA9ICJ5Iiwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsgI2FycmFuZ2UgZmFjZXRzIGJ5IGRpc3NpbWlsYXJpdHkgdHlwZQ0KICBsYWJzKHggPSAiQU1FIikgKyAjcmVuYW1lIHgtYXhpcyBuYW1lDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQsIGxpbWl0cyA9IGMoLTAuMjUsIDAuMzApKSArICN4LWF4aXMgdG8gJS1wb2ludCwgYW5kIHNldCByYW5nZQ0KICB0aGVtZSggI2N1c3RvbWl6ZSB0aGVtZQ0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmx1ZSIpLA0KICAgIHN0cmlwLnRleHQueS5sZWZ0ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgc3RyaXAucGxhY2VtZW50ID0gIm91dHNpZGUiLA0KICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoKSkgKw0KICAgIGdnaDR4OjpmYWNldHRlZF9wb3Nfc2NhbGVzKHkgPSBsaXN0KCAjY3VzdG9taXplIHkgYXhpcyBwZXIgZmFjZXQuLg0KICAgICAgcHJlZCA9PSAiRGlmZmVyZW50XG5nZW5kZXIiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJBZ2VcbmRpZmZlcmVuY2UiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoIiIsICJNNiIsICJNNSIsICJNNCIsICJNMyIpKSwNCiAgICAgIHByZWQgPT0gIkVtb3Rpb25hbFxuY2xvc2VuZXNzIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gIk02IiksDQogICAgICBwcmVkID09ICJSZWxhdGlvbmFsXG5tdWx0aXBsZXhpdHkiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKSwNCiAgICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICJNNiIpLA0KICAgICAgcHJlZCA9PSAiU3RyLiBlbWJlZC5cbm90aGVyIGxheWVycyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICJNNiIpDQogICAgICApKQ0KDQpwbG90MiA8LSBnZ3Bsb3QocGxvdGRhdGEsIGFlcyh4ID0gYW1tZSwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCkpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJyZWQiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbW1lIC0gMS45NiphbW1lX3NlLCB4bWF4ID0gYW1tZSArIDEuOTYqYW1tZV9zZSksIGNvbG9yPSJyZWQiLCB3aWR0aD0uNSkgKw0KICBmYWNldF9ncmlkKHByZWQgfi4sIHN3aXRjaCA9ICJ5Iiwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsNCiAgbGFicyh4ID0gIkFNTUUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQsIGxpbWl0cyA9IGMoLTAuMDUsIDAuMDUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gInJlZCIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHN0cmlwLnBsYWNlbWVudCA9ICJvdXRzaWRlIiwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoKSkgKyANCiAgZ2doNHg6OmZhY2V0dGVkX3Bvc19zY2FsZXMoeSA9IGxpc3QoICNjdXN0b21pemUgeSBheGlzIHBlciBmYWNldC4uDQogICAgcHJlZCA9PSAiRGlmZmVyZW50XG5nZW5kZXIiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCLOlCBNNC1NNiIsICLOlCBNMy1NNiIsICLOlCBNMy1NNSIsICLOlCBNMy1NNCIsICIiKSwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJBZ2VcbmRpZmZlcmVuY2UiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCLOlCBNNC1NNiIsICLOlCBNMy1NNiIsICLOlCBNMy1NNSIsICLOlCBNMy1NNCIsICIiKSwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoIs6UIE00LU02IiwgIs6UIE0zLU02IiwgIs6UIE0zLU01IiwgIs6UIE0zLU00IiwgIiIpLCBwb3NpdGlvbiA9ICJyaWdodCIpLA0KICAgIHByZWQgPT0gIkVtb3Rpb25hbFxuY2xvc2VuZXNzIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJSZWxhdGlvbmFsXG5tdWx0aXBsZXhpdHkiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBOVUxMLCBwb3NpdGlvbiA9ICJyaWdodCIpLA0KICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5mb2NhbCBsYXllciIgfiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBOVUxMLCBwb3NpdGlvbiA9ICJyaWdodCIpLA0KICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBOVUxMLCBwb3NpdGlvbiA9ICJyaWdodCIpKSkgKw0KICB0aGVtZShzdHJpcC50ZXh0ID0gZWxlbWVudF9ibGFuaygpKQ0KDQojY29tYmluZSBwbG90cw0KIz9nZ2FycmFuZ2UNCmZzaG93ZGYocGxvdGRhdGEsIGRpZ2l0cz0zKQ0KZmlndXJlIDwtIGdnYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2w9Miwgd2lkdGhzPWMoMS4xLCAxKSkNCihmaWd1cmUgPC0gYW5ub3RhdGVfZmlndXJlKGZpZ3VyZSwgdG9wID0gdGV4dF9ncm9iKCJTcG9ydHMgcGFydG5lcnMiLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkpKQ0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KZ2dzYXZlKGZpZ3VyZSwgDQogICAgICAgZmlsZSA9ICIuL2ZpZ3VyZXMvYW1lYW1tZV9zcG9ydC5wbmciLA0KICAgICAgIGRwaSA9IDMyMCwgDQogICAgICAgd2lkdGggPSA4LA0KICAgICAgIGhlaWdodCA9IDUpDQpgYGANCg0KIyMjIHN0dWR5IHBhcnRuZXJzDQoNCiMjIyMgMS4gY3JlYXRlIG5ldyBkYXRhc2V0cw0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0KI2Rpc3NpbWlsYXJpdHkNCmRmc3R1ZHlnZW5kZXIxIDwtIGRmc3R1ZHlnZW5kZXIwIDwtIGRmc3R1ZHkNCmRmc3R1ZHlhZ2VwbHVzIDwtIGRmc3R1ZHlhZ2VtaW4gPC0gZGZzdHVkeQ0KZGZzdHVkeWVkdWMxIDwtIGRmc3R1ZHllZHVjMCA8LSBkZnN0dWR5DQoNCmRmc3R1ZHlnZW5kZXIxJGRpZmZlcmVudF9nZW5kZXIgPC0gMQ0KZGZzdHVkeWdlbmRlcjAkZGlmZmVyZW50X2dlbmRlciA8LSAwDQpkZnN0dWR5ZWR1YzEkZGlmZmVyZW50X2VkdWMgPC0gMQ0KZGZzdHVkeWVkdWMwJGRpZmZlcmVudF9lZHVjIDwtIDANCg0KI2RlZmluZSBzbWFsbCBzdGVwIGZvciBjb250aW51b3VzIHZhcmlhYmxlDQpzIDwtIC4wMDENCmRmc3R1ZHlhZ2VwbHVzJGRpZl9hZ2UgPC0gZGZzdHVkeSRkaWZfYWdlICsgcw0KZGZzdHVkeWFnZW1pbiRkaWZfYWdlIDwtIGRmc3R1ZHkkZGlmX2FnZSAtIHMNCg0KI2VtYmVkZGVkbmVzcw0KZGZzdHVkeWNsb3NlcGx1cyA8LSBkZnN0dWR5Y2xvc2VtaW4gPC0gZGZzdHVkeQ0KZGZzdHVkeWNsb3NlcGx1cyRjbG9zZW5lc3MudCA8LSBkZnN0dWR5JGNsb3NlbmVzcy50ICsgcw0KZGZzdHVkeWNsb3NlbWluJGNsb3NlbmVzcy50IDwtIGRmc3R1ZHkkY2xvc2VuZXNzLnQgLSBzDQoNCmRmc3R1ZHltdWx0aXBsdXMgPC0gZGZzdHVkeW11bHRpbWluIDwtIGRmc3R1ZHkNCmRmc3R1ZHltdWx0aXBsdXMkbXVsdGlwbGV4IDwtIGRmc3R1ZHkkbXVsdGlwbGV4ICsgcw0KZGZzdHVkeW11bHRpbWluJG11bHRpcGxleCA8LSBkZnN0dWR5JG11bHRpcGxleCAtIHMNCg0KZGZzdHVkeWZlbWJlZHBsdXMgPC0gZGZzdHVkeWZlbWJlZG1pbiA8LSBkZnN0dWR5DQpkZnN0dWR5ZmVtYmVkcGx1cyRlbWJlZCA8LSBkZnN0dWR5JGVtYmVkICsgcw0KZGZzdHVkeWZlbWJlZG1pbiRlbWJlZCA8LSBkZnN0dWR5JGVtYmVkIC0gcw0KDQpkZnN0dWR5b2VtYmVkcGx1cyA8LSBkZnN0dWR5b2VtYmVkbWluIDwtIGRmc3R1ZHkNCmRmc3R1ZHlvZW1iZWRwbHVzJGVtYmVkLmV4dCA8LSBkZnN0dWR5JGVtYmVkLmV4dCArIHMNCmRmc3R1ZHlvZW1iZWRtaW4kZW1iZWQuZXh0IDwtIGRmc3R1ZHkkZW1iZWQuZXh0IC0gcw0KYGBgDQoNCiMjIyMgMi4gZ2V0IG1vZGVscw0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0KbTEgPC0gYW5zc3R1ZHlbWzJdXSAjYmFzZQ0KbTIgPC0gYW5zc3R1ZHlbWzNdXSAjK21lZGlhdG9yIDEgKHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzKQ0KbTMgPC0gYW5zc3R1ZHlbWzRdXSAjK21lZGlhdG9yIDIgKHN0cnVjdHVyYWwgZW1iZWRkZWRuZXNzKQ0KbTQgPC0gYW5zc3R1ZHlbWzVdXSAjK2JvdGggbWVkaWF0b3JzDQpgYGANCg0KIyMjIyAzLiBjcmVhdGUgZnByZWQoKSBmdW5jdGlvbnMNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGNsYXNzLnNvdXJjZT0nZm9sZC1oaWRlJ30NCiMxLiBBTUVzIGRpc3NpbWlsYXJpdGllcyBiYXNlIG1vZGVsDQpmcHJlZDEgPC0gZnVuY3Rpb24obTEpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5Z2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5Z2VuZGVyMCkNCiAgYW1lX2dlbmRlciA8LSBtZWFuKG1lX2dlbmRlcikNCiAgDQogIG1lX2FnZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG0xLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5YWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5YWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHllZHVjMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTEsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5ZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCg0KICBjKGFtZV9nZW5kZXIsYW1lX2FnZSxhbWVfZWR1YykNCn0NCg0KIzIuIGFmdGVyIGNvbnRyb2xsaW5nIGZvciByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcw0KZnByZWQyIDwtIGZ1bmN0aW9uKG0yKSB7DQogICAgbWVfZ2VuZGVyIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzdHVkeWdlbmRlcjEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzdHVkeWdlbmRlcjApDQogIGFtZV9nZW5kZXIgPC0gbWVhbihtZV9nZW5kZXIpDQogIA0KICBtZV9hZ2UgPC0gKGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMiwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzdHVkeWFnZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzdHVkeWFnZW1pbikpLygyICogcykNCiAgYW1lX2FnZSA8LSBtZWFuKG1lX2FnZSkNCiAgDQogIG1lX2VkdWMgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5ZWR1YzEpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG0yLCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzdHVkeWVkdWMwKQ0KICBhbWVfZWR1YyA8LSBtZWFuKG1lX2VkdWMpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMpDQp9DQoNCiMzLiBhZnRlciBjb250cm9sbGluZyBmb3Igc3RydWN0dXJhbCBlbWJlZGRlZG5lc3MNCmZwcmVkMyA8LSBmdW5jdGlvbihtMykgew0KICAgIG1lX2dlbmRlciA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHlnZW5kZXIxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3R1ZHlnZW5kZXIwKQ0KICBhbWVfZ2VuZGVyIDwtIG1lYW4obWVfZ2VuZGVyKQ0KICANCiAgbWVfYWdlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTMsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHlhZ2VwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3R1ZHlhZ2VtaW4pKS8oMiAqIHMpDQogIGFtZV9hZ2UgPC0gbWVhbihtZV9hZ2UpDQogIA0KICBtZV9lZHVjIDwtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCBuZXdkYXRhID0gZGZzdHVkeWVkdWMxKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtMywgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3R1ZHllZHVjMCkNCiAgYW1lX2VkdWMgPC0gbWVhbihtZV9lZHVjKQ0KDQogIGMoYW1lX2dlbmRlcixhbWVfYWdlLGFtZV9lZHVjKQ0KfQ0KDQojNC4gYWZ0ZXIgY29udHJvbGxpbmcgZm9yIGJvdGggbWVkaWF0b3JzDQpmcHJlZDQgPC0gZnVuY3Rpb24obTQpIHsNCiAgICBtZV9nZW5kZXIgPC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5Z2VuZGVyMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5Z2VuZGVyMCkNCiAgYW1lX2dlbmRlciA8LSBtZWFuKG1lX2dlbmRlcikNCiAgDQogIG1lX2FnZSA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5YWdlcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5YWdlbWluKSkvKDIgKiBzKQ0KICBhbWVfYWdlIDwtIG1lYW4obWVfYWdlKQ0KICANCiAgbWVfZWR1YyA8LSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHllZHVjMSkgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5ZWR1YzApDQogIGFtZV9lZHVjIDwtIG1lYW4obWVfZWR1YykNCiAgDQogICNhbHNvIEFNRXMgb2YgZW1iZWRkZWRuZXNzDQogIG1lX2Nsb3NlIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHljbG9zZXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzdHVkeWNsb3NlbWluKSkvKDIgKiBzKQ0KICBhbWVfY2xvc2UgPC0gbWVhbihtZV9jbG9zZSkNCiAgc3VtbWFyeShtNCkNCiAgDQogIG1lX211bHRpIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHltdWx0aXBsdXMpIC0gbG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsICBuZXdkYXRhID0gZGZzdHVkeW11bHRpbWluKSkvKDIgKiBzKQ0KICBhbWVfbXVsdGkgPC0gbWVhbihtZV9tdWx0aSkNCiAgDQogIG1lX2ZlbWJlZCA8LSAobG1lNDo6OnByZWRpY3QubWVyTW9kKG00LCB0eXBlID0gInJlc3BvbnNlIiwgcmUuZm9ybSA9IE5VTEwsIG5ld2RhdGEgPSBkZnN0dWR5ZmVtYmVkcGx1cykgLSBsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgIG5ld2RhdGEgPSBkZnN0dWR5ZmVtYmVkbWluKSkvKDIgKiBzKQ0KICBhbWVfZmVtYmVkIDwtIG1lYW4obWVfZmVtYmVkKQ0KICANCiAgbWVfb2VtYmVkIDwtIChsbWU0Ojo6cHJlZGljdC5tZXJNb2QobTQsIHR5cGUgPSAicmVzcG9uc2UiLCByZS5mb3JtID0gTlVMTCwgbmV3ZGF0YSA9IGRmc3R1ZHlvZW1iZWRwbHVzKSAtIGxtZTQ6OjpwcmVkaWN0Lm1lck1vZChtNCwgdHlwZSA9ICJyZXNwb25zZSIsIHJlLmZvcm0gPSBOVUxMLCAgbmV3ZGF0YSA9IGRmc3R1ZHlvZW1iZWRtaW4pKS8oMiAqIHMpDQogIGFtZV9vZW1iZWQgPC0gbWVhbihtZV9vZW1iZWQpDQoNCiAgYyhhbWVfZ2VuZGVyLGFtZV9hZ2UsYW1lX2VkdWMsYW1lX2Nsb3NlLGFtZV9tdWx0aSxhbWVfZmVtYmVkLGFtZV9vZW1iZWQpDQp9DQoNCiNmcHJlZDEobTEpDQojZnByZWQyKG0yKQ0KI2ZwcmVkMyhtMykNCiNmcHJlZDQobTQpDQpgYGANCg0KIyMjIyA0LiBib290c3RyYXAgQU1Fcw0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgY2xhc3Muc291cmNlPSdmb2xkLWhpZGUnfQ0Kc2VlZCA8LSAyNDI1MzIzDQpuSXRlciA8LSA1MDANCm5Db3JlIDwtIHBhcmFsbGVsOjpkZXRlY3RDb3JlcygpDQpteWNsIDwtIG1ha2VDbHVzdGVyKHJlcCgibG9jYWxob3N0IiwgbkNvcmUpKQ0KDQpjbHVzdGVyRXZhbFEobXljbCwgbGlicmFyeShsbWU0KSkNCmNsdXN0ZXJFeHBvcnQobXljbCwgdmFybGlzdCA9IGMoDQogICJtMSIsICJtMiIsICJtMyIsICJtNCIsICJzIiwgInNlZWQiLA0KICAiZGZzdHVkeWdlbmRlcjEiLCAiZGZzdHVkeWdlbmRlcjAiLCAiZGZzdHVkeWFnZXBsdXMiLCAiZGZzdHVkeWFnZW1pbiIsICJkZnN0dWR5ZWR1YzEiLCAiZGZzdHVkeWVkdWMwIiwNCiAgImRmc3R1ZHljbG9zZXBsdXMiLCAiZGZzdHVkeWNsb3NlbWluIiwgImRmc3R1ZHltdWx0aXBsdXMiLCAiZGZzdHVkeW11bHRpbWluIiwgImRmc3R1ZHlmZW1iZWRwbHVzIiwgImRmc3R1ZHlmZW1iZWRtaW4iLA0KICAiZGZzdHVkeW9lbWJlZHBsdXMiLCAiZGZzdHVkeW9lbWJlZG1pbiIpKQ0KDQpzeXN0ZW0udGltZSAoYm9vX20xIDwtIGJvb3RNZXIobTEsIGZwcmVkMSwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20yIDwtIGJvb3RNZXIobTIsIGZwcmVkMiwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX20zIDwtIGJvb3RNZXIobTMsIGZwcmVkMywgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQpzeXN0ZW0udGltZSAoYm9vX200IDwtIGJvb3RNZXIobTQsIGZwcmVkNCwgbnNpbSA9IG5JdGVyLCBwYXJhbGxlbCA9ICJzbm93IiwgbmNwdXMgPSBuQ29yZSwgY2wgPSBteWNsLCBzZWVkID0gc2VlZCkpDQoNCmJvb0wgPC0gbGlzdChib29fbTEsYm9vX20yLGJvb19tMyxib29fbTQpDQpzYXZlKGJvb0wsIGZpbGUgPSAiLi9yZXN1bHRzL2Jvb3Rfc3R1ZHkuUmRhIikNCnN0b3BDbHVzdGVyKG15Y2wpDQpgYGANCg0KIyMjIyA1LiBjb25zdHJ1Y3QgcGxvdCBkYXRhc2V0DQoNCmBgYHtyLCBjbGFzcy5zb3VyY2U9J2ZvbGQtaGlkZSd9DQpuSXRlciA9IDUwMA0KbG9hZCgiLi9yZXN1bHRzL2Jvb3Rfc3R1ZHkucmRhIikgIA0KDQojQU1FcyBkaXNzaW1pbGFyaXRpZXMNCnBsb3RkYXRhIDwtIGRhdGEuZnJhbWUoDQogIHByZWQgPSByZXAoYygiRGlmZmVyZW50XG5nZW5kZXIiLCJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSwgNCksDQogIG1vZGVsID0gcmVwKGMoIk0zIiwgIk00IiwgIk01IiwgIk02IiksIGVhY2g9MyksDQogIGFtZSA9IGMoYm9vTFtbMV1dJHQwLCBib29MW1syXV0kdDAsIGJvb0xbWzNdXSR0MCwgYm9vTFtbNF1dJHQwWzE6M10pLA0KICBhbWVfc2UgPSBjKGFwcGx5KGJvb0xbWzFdXSR0LCAyLCBzZCksIGFwcGx5KGJvb0xbWzJdXSR0LCAyLCBzZCksIGFwcGx5KGJvb0xbWzNdXSR0LCAyLCBzZCksDQogICAgICAgICAgICAgYXBwbHkoYm9vTFtbNF1dJHQsIDIsIHNkKVsxOjNdKQ0KICApDQoNCiNBTU1Fcw0KcGxvdGRhdGEkYW1tZSA8LSBOQQ0KcGxvdGRhdGEkYW1tZV9zZSA8LSBOQQ0KDQpmb3IgKGkgaW4gYygxOjMpKSB7ICMgZm9yIGRpc3NpbWlsYXJpdHkgZ3JvdW5kDQogIGZvciAoaiBpbiBjKDI6NCkpIHsgIyBmb3IgZXh0ZW5kZWQgbW9kZWwNCiAgICAjZ2V0IEFNRXMgb2YgZGlzc2ltaWxhcml0eSBpIG9mIGJhc2VsaW5lIG1vZGVsDQogICAgYW1lX2lfYmFzZSA8LSBib29MW1sxXV0kdFssIGldIA0KICAgICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgZXh0ZW5kZWQgbW9kZWwgag0KICAgIGFtZV9pX21vZGVsaiA8LSBib29MW1tqXV0kdFssIGldDQogICAgI2NhbGN1bGF0ZSBjcm9zcy1tb2RlbCBBTUUgZGlmZmVyZW5jZSBwZXIgYm9vdHN0cmFwIGl0ZXJhdGlvbg0KICAgIGNtX2FtZV9kaWZzIDwtIGFtZV9pX2Jhc2UgLSBhbWVfaV9tb2RlbGoNCiAgICAjY2FsY3VsYXRlIGF2ZXJhZ2UgbWFyZ2luYWwgbWVkaWF0aW9uIGVmZmVjdCBieSB0YWtpbmcgdGhlIGF2ZXJhZ2UgDQogICAgcGxvdGRhdGEkYW1tZVtwbG90ZGF0YSRwcmVkID09IHVuaXF1ZShwbG90ZGF0YSRwcmVkKVtpXSAmIHBsb3RkYXRhJG1vZGVsID09IHVuaXF1ZShwbG90ZGF0YSRtb2RlbClbal1dIDwtIG1lYW4oY21fYW1lX2RpZnMpDQogICAgI2FuZCBTRQ0KICAgIHBsb3RkYXRhJGFtbWVfc2VbcGxvdGRhdGEkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEkcHJlZClbaV0gJiBwbG90ZGF0YSRtb2RlbCA9PSB1bmlxdWUocGxvdGRhdGEkbW9kZWwpW2pdXSA8LSBzZChjbV9hbWVfZGlmcykvc3FydChuSXRlcikNCiAgICB9DQp9DQoNCnBsb3RkYXRhMiA8LSBkYXRhLmZyYW1lKA0KICBwcmVkID0gYygiRGlmZmVyZW50XG5nZW5kZXIiLCJBZ2VcbmRpZmZlcmVuY2UiLCAiRGlmZmVyZW50XG5lZHVjYXRpb24iKSwNCiAgbW9kZWwgPSAiTTQtTTYiLA0KICBhbWUgPSBOQSwgYW1lX3NlID0gTkEsIGFtbWUgPSBOQSwgYW1tZV9zZSA9IE5BKQ0KDQpmb3IgKGkgaW4gYygxOjMpKSB7DQogICNnZXQgQU1FcyBvZiBkaXNzaW1pbGFyaXR5IGkgb2YgbW9kZWwgMiAoaW5jbHVkaW5nIHJlbGF0aW9uYWwgZW1iZWRkZWRuZXNzIG9ubHkpDQogIGFtZV9pX2Jhc2UgPC0gYm9vTFtbMl1dJHRbLGldDQogICNnZXQgQU1FIG9mIGRpc3NpbWlsYXJpdHkgaSBvZiBleHRlbmRlZCBtb2RlbCA0IChhZGRpbmcgYWxzbyBzdHJ1Y3R1cmFsIGVtYmVkZGVkbmVzcykNCiAgYW1lX2lfbW9kZWxqIDwtIGJvb0xbWzRdXSR0WyxpXQ0KICAjY2FsY3VsYXRlIGNyb3NzLW1vZGVsIEFNRSBkaWZmZXJlbmNlDQogIGNtX2FtZV9kaWZzIDwtIGFtZV9pX2Jhc2UgLSBhbWVfaV9tb2RlbGoNCiAgI2NhbGN1YWx0ZSBhdmVyYWdlIG1hcmdpbmFsIG1lZGlhdGlvbg0KICBwbG90ZGF0YTIkYW1tZVtwbG90ZGF0YTIkcHJlZCA9PSB1bmlxdWUocGxvdGRhdGEyJHByZWQpW2ldXSA8LSBtZWFuKGNtX2FtZV9kaWZzKQ0KICAjYW5kIFNFDQogIHBsb3RkYXRhMiRhbW1lX3NlW3Bsb3RkYXRhMiRwcmVkID09IHVuaXF1ZShwbG90ZGF0YTIkcHJlZClbaV1dIDwtIHNkKGNtX2FtZV9kaWZzKS9zcXJ0KG5JdGVyKQ0KICB9DQoNCiNBTUUgZW1iZWRkZWRuZXNzDQpwbG90ZGF0YTMgPC0gZGF0YS5mcmFtZSgNCiAgcHJlZCA9IGMoIkVtb3Rpb25hbFxuY2xvc2VuZXNzIiwgDQogICAgICAgICAgICJSZWxhdGlvbmFsXG5tdWx0aXBsZXhpdHkiLA0KICAgICAgICAgICAiU3RyLiBlbWJlZC5cbmZvY2FsIGxheWVyIiwNCiAgICAgICAgICAgIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiKSwNCiAgbW9kZWwgPSAiTTYiLA0KICBhbWUgPSAgYm9vTFtbNF1dJHQwWzQ6N10sDQogIGFtZV9zZSA9IGFwcGx5KGJvb0xbWzRdXSR0LCAyLCBzZClbNDo3XSkNCg0KYmluZF9yb3dzKHBsb3RkYXRhLHBsb3RkYXRhMixwbG90ZGF0YTMpIC0+IHBsb3RkYXRhDQoNCnBsb3RkYXRhJHByZWQgPC0gZmFjdG9yKHBsb3RkYXRhJHByZWQsIGxldmVscyA9IGMoIkRpZmZlcmVudFxuZ2VuZGVyIiwgIkFnZVxuZGlmZmVyZW5jZSIsICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIsICJFbW90aW9uYWxcbmNsb3NlbmVzcyIsIA0KICAgICAgICAgICAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiwiU3RyLiBlbWJlZC5cbmZvY2FsIGxheWVyIiwiU3RyLiBlbWJlZC5cbm90aGVyIGxheWVycyIpKQ0KcGxvdGRhdGEkbW9kZWwgPC0gZmFjdG9yKHBsb3RkYXRhJG1vZGVsLCBsZXZlbHMgPSByZXYoYygiTTMiLCAiTTQiLCAiTTUiLCAiTTYiLCJNNC1NNiIpKSkNCnBsb3RkYXRhIDwtIHBsb3RkYXRhW29yZGVyKHBsb3RkYXRhJHByZWQpLF0NCnJvdy5uYW1lcyhwbG90ZGF0YSkgPC0gMTpucm93KHBsb3RkYXRhKQ0KYGBgDQoNCiMjIyMgNi4gcmVzdWx0DQoNCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01LCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiNwbG90IDE6IEFNRXMNCnBsb3QxIDwtIGdncGxvdChwbG90ZGF0YSwgYWVzKHggPSBhbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsgI3ZlcnRpY2FsIGxpbmUgYXQgMA0KICBnZW9tX3BvaW50KHNpemUgPSAyLCBjb2xvciA9ICJibHVlIikgKyAjcG9pbnQgaW5kaWNhdGluZyBvYnNlcnZlZCBBTUUNCiAgI2dlb21fcG9pbnQoYWVzKHggPSBhbWVfYiwgeSA9IG1vZGVsLCBmaWxsID0gcHJlZCksIHNpemUgPSAzLCBzaGFwZSA9IDQpICsgI2Nyb3NzIGluZGljYXRpbmcgYXZlcmFnZSBib290c3RyYXAgQU1FIGVzdGltYXRlDQogIGdlb21fZXJyb3JiYXIoYWVzKHhtaW4gPSBhbWUgLSAxLjk2KmFtZV9zZSwgeG1heCA9IGFtZSArIDEuOTYqYW1lX3NlKSwgY29sb3I9ImJsdWUiLCB3aWR0aD0uNSkgKyAjZXJyb3IgYmFycyBmb3IgOTUlIENJDQogIGZhY2V0X2dyaWQocHJlZCB+Liwgc3dpdGNoID0gInkiLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKyAjYXJyYW5nZSBmYWNldHMgYnkgZGlzc2ltaWxhcml0eSB0eXBlDQogIGxhYnMoeCA9ICJBTUUiKSArICNyZW5hbWUgeC1heGlzIG5hbWUNCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygtMC4yNSwgMC4zMCkpICsgI3gtYXhpcyB0byAlLXBvaW50LCBhbmQgc2V0IHJhbmdlDQogIHRoZW1lKCAjY3VzdG9taXplIHRoZW1lDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibHVlIiksDQogICAgc3RyaXAudGV4dC55LmxlZnQgPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZSgpKSArDQogICAgZ2doNHg6OmZhY2V0dGVkX3Bvc19zY2FsZXMoeSA9IGxpc3QoICNjdXN0b21pemUgeSBheGlzIHBlciBmYWNldC4uDQogICAgICBwcmVkID09ICJEaWZmZXJlbnRcbmdlbmRlciIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IGMoIiIsICJNNiIsICJNNSIsICJNNCIsICJNMyIpKSwNCiAgICAgIHByZWQgPT0gIkFnZVxuZGlmZmVyZW5jZSIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJEaWZmZXJlbnRcbmVkdWNhdGlvbiIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICBjKCIiLCAiTTYiLCAiTTUiLCAiTTQiLCAiTTMiKSksDQogICAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9ICJNNiIpLA0KICAgICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gIk02IiksDQogICAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKSwNCiAgICAgIHByZWQgPT0gIlN0ci4gZW1iZWQuXG5vdGhlciBsYXllcnMiIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSAiTTYiKQ0KICAgICAgKSkNCg0KcGxvdDIgPC0gZ2dwbG90KHBsb3RkYXRhLCBhZXMoeCA9IGFtbWUsIHkgPSBtb2RlbCwgZmlsbCA9IHByZWQpKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMiwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh4bWluID0gYW1tZSAtIDEuOTYqYW1tZV9zZSwgeG1heCA9IGFtbWUgKyAxLjk2KmFtbWVfc2UpLCBjb2xvcj0icmVkIiwgd2lkdGg9LjUpICsNCiAgZmFjZXRfZ3JpZChwcmVkIH4uLCBzd2l0Y2ggPSAieSIsIHNjYWxlcyA9ICJmcmVlX3kiLCBzcGFjZSA9ICJmcmVlX3kiKSArDQogIGxhYnMoeCA9ICJBTU1FIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50LCBsaW1pdHMgPSBjKC0wLjA1LCAwLjA1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJyZWQiKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBzdHJpcC5wbGFjZW1lbnQgPSAib3V0c2lkZSIsDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwNCiAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKCkpICsgDQogIGdnaDR4OjpmYWNldHRlZF9wb3Nfc2NhbGVzKHkgPSBsaXN0KCAjY3VzdG9taXplIHkgYXhpcyBwZXIgZmFjZXQuLg0KICAgIHByZWQgPT0gIkRpZmZlcmVudFxuZ2VuZGVyIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTUiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiQWdlXG5kaWZmZXJlbmNlIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gYygizpQgTTQtTTYiLCAizpQgTTMtTTYiLCAizpQgTTMtTTUiLCAizpQgTTMtTTUiLCAiIiksIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiRGlmZmVyZW50XG5lZHVjYXRpb24iIH4gc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHMgPSBjKCLOlCBNNC1NNiIsICLOlCBNMy1NNiIsICLOlCBNMy1NNSIsICLOlCBNMy1NNSIsICIiKSwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJFbW90aW9uYWxcbmNsb3NlbmVzcyIgfiBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscyA9IE5VTEwsIHBvc2l0aW9uID0gInJpZ2h0IiksDQogICAgcHJlZCA9PSAiUmVsYXRpb25hbFxubXVsdGlwbGV4aXR5IiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxuZm9jYWwgbGF5ZXIiIH4gIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSwNCiAgICBwcmVkID09ICJTdHIuIGVtYmVkLlxub3RoZXIgbGF5ZXJzIiB+IHNjYWxlX3lfZGlzY3JldGUobGFiZWxzID0gTlVMTCwgcG9zaXRpb24gPSAicmlnaHQiKSkpICsNCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSkNCiAgDQojY29tYmluZSBwbG90cw0KIz9nZ2FycmFuZ2UNCmZzaG93ZGYocGxvdGRhdGEsIGRpZ2l0cz0zKQ0KZmlndXJlIDwtIGdnYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2w9Miwgd2lkdGhzPWMoMS4xLCAxKSkNCihmaWd1cmUgPC0gYW5ub3RhdGVfZmlndXJlKGZpZ3VyZSwgdG9wID0gdGV4dF9ncm9iKCJTdHVkeSBwYXJ0bmVycyIsIGNvbG9yID0gImJsYWNrIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSkpDQpgYGANCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpnZ3NhdmUoZmlndXJlLCANCiAgICAgICBmaWxlID0gIi4vZmlndXJlcy9hbWVhbW1lX3N0dWR5LnBuZyIsDQogICAgICAgZHBpID0gMzIwLCANCiAgICAgICB3aWR0aCA9IDgsDQogICAgICAgaGVpZ2h0ID0gNSkNCmBgYA0KDQojIyB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQotLS0NCg0KPGJyPg0KDQojIFJvYnVzdG5lc3MgYW5hbHlzZXMgDQoNCg0KIyMgYWNjb3VudGluZyBmb3IgJ2ZvcmdldHRpbmcnDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIzEuIG5ldyBkZXBlbmRlbnQgdmFyaWFibGU6IHRpZSBsb3NzLCB0cmVhdGluZyBmb3Jnb3R0ZW4gYXMgbWFpbnRhaW5lZA0KZGYkWW5mIDwtIGlmZWxzZShkZiRyZWFzb24gPT0gImZvcmdvdHRlbiIsIDAsIGRmJFkpDQoNCiMyLiBzdWJzZXQgZGF0YSBvZiBwZXJpb2QgMg0KZGYyMyA8LSBkZltkZiRwZXJpb2QgPT0gIncyIC0+IHczIixdDQoNCiNwcm9wLnRhYmxlKHRhYmxlKGRmMjMkWSkpICM0MCBwZXJjZW50IG9mIHRpZXMgZHJvcHBlZCBpbiB3Mw0KI3Byb3AudGFibGUodGFibGUoZGYyMyRZbmYpKSAjMzQgcGVyY2VudCBpZiB3ZSBjb3JyZWN0IGZvciBmb3JnZXR0aW5nIGFzIGEgY2F1c2UgZm9yIHRpZSBsb3NzDQoNCiMzLiBuZXcgZm9ybXVsYSBsaXN0IChuZXcgWTsgZXhjbHVkaW5nIHBlcmlvZCBlZmZlY3RzKQ0KZm9ybXVsYTMgPC0gbGlzdCgNCiAgIzAuIG51bGwNCiAgWW5mIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpLA0KDQogICMxLiB0aWUNCiAgWW5mIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllLA0KDQogICMyLiBkaXNpc21pbGFyaXR5DQogIFluZiB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICwNCiAgDQogICMzLiBjb250cm9scw0KICBZbmYgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSwNCiAgDQogICM0LiByZWxhdGlvbmFsIGVtYmVkZGVkbmVzcyBhcyBtZWRpYXRvcg0KICBZbmYgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSArIG11bHRpcGxleCArIGNsb3NlbmVzcy50LA0KICANCiAgIzUuIHN0ci4gZW1iZWRkZWRuZXNzIGFzIG1lZGlhdG9yDQogIFluZiB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSwNCg0KICAjNi4gYm90aCByZWxhdGlvbmFsIGFuZCBzdHJ1Y3R1cmFsDQogIFluZiB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UpICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgbXVsdGlwbGV4ICsgY2xvc2VuZXNzLnQgKyBzY2FsZShlbWJlZCkgKyBzY2FsZShlbWJlZC5leHQpLA0KICANCiAgIzcuIGludGVyYWN0aW9uIGRpc3NpbWlsYXJpdHkgKiB0aWUgdHlwZQ0KICBZbmYgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSAgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIGVnb19mZW1hbGUgKyBzY2FsZShleHRyYXZlcnNpb24pICsgc2NhbGUoZmluX3Jlc3RyKSArIHJvbWFudGljICsgaG91c2luZy50cmFuc2l0aW9uICsgb2NjdXBhdGlvbi50cmFuc2l0aW9uICsgYWx0ZXJfZmVtYWxlICsgc2NhbGUoYWx0ZXJfZWR1YykgKyBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCArIHNjYWxlKGVtYmVkKSArIHNjYWxlKGVtYmVkLmV4dCkgKyBkaWZmZXJlbnRfZ2VuZGVyOnRpZSArIGRpZmZlcmVudF9lZHVjOnRpZSArIHNjYWxlKGRpZl9hZ2UpOnRpZSwNCiAgDQogICM4LiBpbnRlcmFjdGlvbiBtZWRpYXRvcnMgKiB0aWUgdHlwZQ0KICBZbmYgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyB0aWUgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSArIG11bHRpcGxleCArIGNsb3NlbmVzcy50ICsgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSAgKyBjbG9zZW5lc3MudDp0aWUgKyBtdWx0aXBsZXg6dGllICsgc2NhbGUoZW1iZWQpOnRpZSArIHNjYWxlKGVtYmVkLmV4dCk6dGllDQopDQoNCiNlc3RpbWF0ZSB1c2luZyBgZmZpdGANCmFuczMgPC0gbGFwcGx5KGZvcm11bGEzLCBmZml0LCBkYXRhID0gZGYyMykNCg0KDQpzYXZlKGFuczMsIGZpbGU9Ii4vcmVzdWx0cy9hbnNfZm9yZ290dGVuLlJEYXRhIikNCmBgYCANCg0KYGBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbG9hZCgiLi9yZXN1bHRzL2Fuc19mb3Jnb3R0ZW4uUmRhdGEiKQ0KDQp0ZXhyZWc6Omh0bWxyZWcoYW5zMywNCiAgICAgICAgZmlsZT0iLi9yZXN1bHRzL2NvZWZ0YWJfZm9yZ290dGVuLmh0bWwiLA0KICAgICAgICBjYXB0aW9uPSJSZXN1bHRzIG9mIHJhbmRvbSBlZmZlY3RzIG1vZGVscyBwcmVkaWN0aW5nIHRpZSBkaXNzb2x1dGlvbiBhdCB0KzEgKDE9eWVzLCAwPW5vKSwgY291bnRpbmcgdGllcyB0byBmb3Jnb3R0ZW4gYWx0ZXJzIGFzIG1haW50YWluZWQiLCBjYXB0aW9uLmFib3ZlID0gVFJVRSwNCiAgICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9IHBhc3RlMCgiTSIsYygwOjgpKSwNCg0KICAgICAgICBjdXN0b20uY29lZi5uYW1lcyA9IGMoIihJbnRlcmNlcHQpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmVzdCBmcmllbmQiLCAiU3BvcnRzIHBhcnRuZXIiLCAiU3R1ZHkgcGFydG5lciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlmZmVyZW50IGdlbmRlciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIiwgIkFnZSBkaWZmZXJlbmNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlc2VhcmNoIHVuaXZlcnNpdHkgc3R1ZGVudCIsICJTZWNvbmQgeWVhciBzdHVkZW50IiwgIlRoaXJkIHllYXIgb3IgaGlnaGVyIiwgIkFnZSAiLCAiRmVtYWxlICIsICJFeHRyYXZlcnNpb24iLCAiRmluYW5jaWFsIHJlc3RyaWN0aW9ucyIsICJSb21hbnRpYyByZWxhdGlvbnNoaXAiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGZW1hbGUiLCAiRWR1Y2F0aW9uIiwgIkFnZSIsICJZZWFycyBrbm93biIsICJTYW1lIG11bmljaXBhbGl0eSIsICJTYW1lIGhvdXNlIiwgIk5ldHdvcmsgc2l6ZSIsICJNdWx0aXBsZXhpdHkiLCAiRW1vdGlvbmFsIGNsb3NlbmVzcyIsICJTdHIuIGVtYmVkZGVkbmVzcyBmb2NhbCBsYXllciIsICJTdHIuIGVtYmVkZGVkbmVzcyBvdGhlciBsYXllcnMiLCAiRGlmZmVyZW50IGdlbmRlciA6IEJlc3QgZnJpZW5kIiwgIkRpZmZlcmVudCBnZW5kZXIgOiBTcG9ydHMgcGFydG5lciIsICJEaWZmZXJlbnQgZ2VuZGVyIDogU3R1ZHkgcGFydG5lciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIDogQmVzdCBmcmllbmQiLCAiRGlmZmVyZW50IGVkdWNhdGlvbiA6IFNwb3J0cyBwYXJ0bmVyIiwgIkRpZmZlcmVudCBlZHVjYXRpb24gOiBTdHVkeSBwYXJ0bmVyIiwgIkFnZSBkaWZmZXJlbmNlIDogQmVzdCBmcmllbmQiLCAiQWdlIGRpZmZlcmVuY2UgOiBTcG9ydHMgcGFydG5lciIsICJBZ2UgZGlmZmVyZW5jZSA6IFN0dWR5IHBhcnRuZXIiLCAiRW1vdGlvbmFsIGNsb3NlbmVzcyA6IEJlc3QgZnJpZW5kIiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MgOiBTcG9ydHMgcGFydG5lciIsIkVtb3Rpb25hbCBjbG9zZW5lc3MgOiBTdHVkeSBwYXJ0bmVyIiwgIk11bHRpcGxleGl0eSA6IEJlc3QgZnJpZW5kIiwgIk11bHRpcGxleGl0eSA6IFNwb3J0cyBwYXJ0bmVyIiwgIk11bHRpcGxleGl0eSA6IFN0dWR5IHBhcnRuZXIiLCAiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIgOiBCZXN0IGZyaWVuZCIsIlN0ci4gZW1iZWRkZWRuZXNzIGZvY2FsIGxheWVyIDogU3BvcnRzIHBhcnRuZXIiLCJTdHIuIGVtYmVkZGVkbmVzcyBmb2NhbCBsYXllciA6IFN0dWR5IHBhcnRuZXIiLCJTdHIuIGVtYmVkZGVkbmVzcyBvdGhlciBsYXllcnMgOiBCZXN0IGZyaWVuZCIsIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyA6IFNwb3J0cyBwYXJ0bmVyIiwiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIDogU3R1ZHkgcGFydG5lciIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUNCiAgICAgICAgKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCmh0bWx0b29sczo6dGFncyRkaXYoDQogIHN0eWxlID0gImhlaWdodDogNjAwcHg7IG92ZXJmbG93LXk6IHNjcm9sbDsiLA0KICBodG1sdG9vbHM6OmluY2x1ZGVIVE1MKCIuL3Jlc3VsdHMvY29lZnRhYl9mb3Jnb3R0ZW4uaHRtbCIpDQopDQpgYGANCg0KDQotLS0NCg0KIyMgY29uZmlkYW50IGxvc3MgYW5hbHlzZXMgYnkgZ2VuZGVyDQoNCldlIHN1cnByaXNpbmdseSBmb3VuZCB0aGF0IGRpZmZlcmVudC1nZW5kZXIgY29uZmlkYW50cyBhcmUgbGVzcywgcmF0aGVyIHRoYW4gbW9yZSBvZnRlbiBkaXNzb2x2ZWQgY29tcGFyZWQgdG8gdGhlaXIgc2FtZS1nZW5kZXIgY291bnRlcnBhcnQuIFdlIHN1YnNldCB0aGUgYW5hbHlzZXMgb24gY29uZmlkYW50IGxvc3MgYnkgZWdvJ3MgZ2VuZGVyLCB0byBleHBsb3JlIGlmIHRoaXMgcmVzdWx0IGlzIGRyaXZlbiBieSBvbmUgb2YgdGhlIGdlbmRlcnMuIE5hdHVyYWxseSwgaGVyZSB3ZSBkcm9wIHRoZSBlZ28tIGFuZCBhbHRlci1sZXZlbCBnZW5kZXIgZWZmZWN0cy4uLg0KDQpgYGB7ciwgc2VwZ2VuZGVyLCBldmFsPUZBTFNFfQ0KYW5zX3dvbWVuIDwtIGdsbWVyKCBZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgc2NhbGUoZGlmX2FnZSkgKyBwZXJpb2QNCiAgICAgICAgICAgICAgICAgICAgKyBlZ29fZWR1YyAgKyBhcy5mYWN0b3Ioc3R1ZHkueWVhcikgKyBzY2FsZShlZ29fYWdlKSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMNCiAgICAgICAgICAgICAgICAgICAgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBzY2FsZShhbHRlcl9lZHVjKSArDQogICAgICAgICAgICAgICAgICAgICAgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgbXVsdGlwbGV4ICsgY2xvc2VuZXNzLnQgKw0KICAgICAgICAgICAgICAgICAgICAgIHNjYWxlKGVtYmVkKSArIHNjYWxlKGVtYmVkLmV4dCksDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZmNvbmZpZGFudFtkZmNvbmZpZGFudCRlZ29fZmVtYWxlPT0xLF0sIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSwNCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGdsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIiwgb3B0Q3RybCA9IGxpc3QobWF4ZnVuID0gMWU1KSkpDQoNCmFuc19tZW4gPC0gZ2xtZXIoIFkgfiAxICsgKDEgfCBlZ28pICsgKDEgfCBlZ286YWx0ZXJpZCkgKyBkaWZmZXJlbnRfZ2VuZGVyICsgZGlmZmVyZW50X2VkdWMgKyBzY2FsZShkaWZfYWdlKSArIHBlcmlvZA0KICAgICAgICAgICAgICAgICAgICArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYw0KICAgICAgICAgICAgICAgICAgICArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIHNjYWxlKGFsdGVyX2VkdWMpICsNCiAgICAgICAgICAgICAgICAgICAgICBzY2FsZShhcy5udW1lcmljKGFsdGVyX2FnZSkpICsgc2NhbGUoZHVyYXRpb24pICsgcHJveGltaXR5ICsgc2NhbGUoc2l6ZSkgKyBtdWx0aXBsZXggKyBjbG9zZW5lc3MudCArDQogICAgICAgICAgICAgICAgICAgICAgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmY29uZmlkYW50W2RmY29uZmlkYW50JGVnb19mZW1hbGU9PTAsXSwgZmFtaWx5ID0gYmlub21pYWwobGluayA9ICJsb2dpdCIpLA0KICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gZ2xtZXJDb250cm9sKG9wdGltaXplciA9ICJib2J5cWEiLCBvcHRDdHJsID0gbGlzdChtYXhmdW4gPSAxZTUpKSkNCiNzdW1tYXJ5KGFuc193b21lbikNCiNzdW1tYXJ5KGFuc19tZW4pDQphbnNnZW5kZXIgPC0gbGlzdChhbnNfd29tZW4sIGFuc19tZW4pDQoNCnNhdmUoYW5zZ2VuZGVyLCBmaWxlPSIuL3Jlc3VsdHMvYW5zX2NvbmZpZGFudF9nZW5kZXIuUkRhdGEiKQ0KYGBgIA0KDQpgYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsb2FkKCIuL3Jlc3VsdHMvYW5zX2NvbmZpZGFudF9nZW5kZXIuUmRhdGEiKQ0KDQp0ZXhyZWc6Omh0bWxyZWcoYW5zZ2VuZGVyLA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9jb25maWRhbnRfZ2VuZGVyLmh0bWwiLA0KICAgICAgICBjYXB0aW9uPSJSZXN1bHRzIG9mIHJhbmRvbSBlZmZlY3RzIG1vZGVscyBwcmVkaWN0aW5nIGNvbmZpZGFudCBkaXNzb2x1dGlvbiBhdCB0KzEgKDE9eWVzLCAwPW5vKSwgZGlzYWdncmVnYXRlZCBieSBlZ28ncyBnZW5kZXIiLCANCiAgICAgICAgY2FwdGlvbi5hYm92ZSA9IFRSVUUsDQogICAgICAgICBjdXN0b20ubW9kZWwubmFtZXMgPSBjKCJXb21lbiIsICJNZW4iKSwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSBjKCIoSW50ZXJjZXB0KSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpZmZlcmVudCBnZW5kZXIiLCAiRGlmZmVyZW50IGVkdWNhdGlvbiIsICJBZ2UgZGlmZmVyZW5jZSIsICJQZXJpb2Q6IHdhdmUgMiAtPiB3YXZlIDMiLCAgIlJlc2VhcmNoIHVuaXZlcnNpdHkgc3R1ZGVudCIsICJTZWNvbmQgeWVhciBzdHVkZW50IiwgIlRoaXJkIHllYXIgb3IgaGlnaGVyIiwgIkFnZSAiLCAiRXh0cmF2ZXJzaW9uIiwgIkZpbmFuY2lhbCByZXN0cmljdGlvbnMiLCAiUm9tYW50aWMgcmVsYXRpb25zaGlwIiwgIkhvdXNpbmcgdHJhbnNpdGlvbiIsICJTdHVkeSB0cmFuc2l0aW9uIiwgIkVkdWNhdGlvbiIsICJBZ2UiLCAiWWVhcnMga25vd24iLCAiU2FtZSBtdW5pY2lwYWxpdHkiLCAiU2FtZSBob3VzZSIsICJOZXR3b3JrIHNpemUiLCAiTXVsdGlwbGV4aXR5IiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MiLCAiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIiLCAiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIiksDQogICAgICAgIGRpZ2l0cz0yLCBzaW5nbGUucm93ID0gVFJVRQ0KICAgICAgICApDQpgYGANCg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KaHRtbHRvb2xzOjp0YWdzJGRpdigNCiAgc3R5bGUgPSAiaGVpZ2h0OiA2MDBweDsgb3ZlcmZsb3cteTogc2Nyb2xsOyIsDQogIGh0bWx0b29sczo6aW5jbHVkZUhUTUwoIi4vcmVzdWx0cy9jb2VmdGFiX2NvbmZpZGFudF9nZW5kZXIuaHRtbCIpDQopDQpgYGANCg0KDQotLS0NCg0KIyMgYWx0ZXJuYXRpdmUgJ2FnZSBkaXNzaW1pbGFyaXR5JyBtZWFzdXJlIHsudGFic2V0IC50YWJzZXQtZmFkZX0NCg0KV2UgYWxzbyB1c2UgYWx0ZXJuYXRpdmUgb3BlcmF0aW9uYWxpemF0aW9ucyBvZiBhZ2UgZGlzc2ltaWxhcml0eToNCg0KMS4gd2UgY2FsY3VsYXRlZCAic2FtZW5lc3MiIGRpY2hvdG9tb3VzbHk6IFdlIGZpcnN0IGFzc2lnbmVkIGVhY2ggZWdvIHRvIGFuIGFnZSBjYXRlZ29yeSAoZS5nLiwgMjItMjUpLiBBbHRlcnMgd2VyZSB0aGVuIGNvbnNpZGVyZWQgc2ltaWxhciBpZiB0aGV5IGZlbGwgaW50byB0aGUgc2FtZSBjYXRlZ29yeSBhcyBlZ28gYW5kIGRpZmZlcmVudCBvdGhlcndpc2UuIA0KDQoyLiB3ZSB0cmVhdCBhZ2UgY2F0ZWdvcmllcyBhcyBsaW5lYXIsIGFuZCBjYWxjdWxhdGUgdGhlIHRoZSBhZ2UgZGlzdGFuY2UgYmV0d2VlbiBlZ28gYW5kIGFsdGVyIGluIGNhdGVnb3JpZXMuDQoNCjMuIGlmIGVnbyBhbmQgYWx0ZXIgZmFsbCBpbiB0aGUgc2FtZSBhZ2UgY2F0ZWdvcnksIHRoZWlyIGFnZSBkaWZmZXJlbmNlID09IDAsIG90aGVyd2lzZSwgd2UgdGFrZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGVnbydzIGFnZSBhbmQgYWx0ZXJzIGFnZSBjYXRlZ29yeSBtaWRwb2ludC4gDQoNCiMjIyBkaWNodG9tb3VzIHNhbWVuZXNzDQoNCmBgYHtyLCBkaWZhZ2UyLCBldmFsPUZBTFNFfQ0KI2ZpcnN0LCByZXRyaWV2ZSB0aGUgb3JpZ2luYWwgYWdlIHJhbmdlLCBiYXNlZCBvbiB3aGljaCB3ZSBhc3NpZ25lZCBhbHRlcnMnIGFnZSAodXNpbmcgdGhlIHJhbmdlIG1pZHBvaW50KQ0KZGYkYWx0ZXJfYWdlX3JhbmdlIDwtIGlmZWxzZShkZiRhbHRlcl9hZ2UgPT0gMTYsICAiSm9uZ2VyIGRhbiAxOCBqYWFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmJGFsdGVyX2FnZSA9PSAyMCwgIjE4IHRvdCAyMSBqYWFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShkZiRhbHRlcl9hZ2UgPT0gMjMsICIyMiB0b3QgMjUgamFhciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRmJGFsdGVyX2FnZSA9PSAyOCwgIjI2IHRvdCAzMCBqYWFyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZGYkYWx0ZXJfYWdlID09IDM1LCAiMzEgdG90IDQwIGphYXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZGYkYWx0ZXJfYWdlID09IDQ1LCAiT3VkZXIgZGFuIDQwIGphYXIiLCBOQSkpKSkpKQ0KI2NvbnZlcnQgZWdvIGFnZSB0byBhZ2UgcmFuZ2VzDQpkZiRlZ29fYWdlX3JhbmdlPC0gY3V0KGRmJGVnb19hZ2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC1JbmYsIDE3LCAyMSwgMjUsIDMwLCA0MCwgSW5mKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkpvbmdlciBkYW4gMTggamFhciIsICIxOCB0b3QgMjEgamFhciIsICIyMiB0b3QgMjUgamFhciIsICIyNiB0b3QgMzAgamFhciIsICIzMSB0b3QgNDAgamFhciIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3VkZXIgZGFuIDQwIGphYXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gVFJVRSkNCg0KI25vdyBjb25zdHJ1Y3QgbmV3IHNhbWVuZXNzIChpbnZlcnNlIHRvIGRpZmZlcmVudC4uKSB2YXJpYWJsZSwgYmFzZWQgb24gd2hldGhlciBlZ28gYW5kIGFsdGVyIGZhbGwgaW4gc2FtZSBjYXRlZ29yeQ0KZGYkZGlmZmVyZW50X2FnZSA8LSBpZmVsc2UoZGYkZWdvX2FnZV9yYW5nZSA9PSBkZiRhbHRlcl9hZ2VfcmFuZ2UsMCwxKQ0KDQojcHJvcC50YWJsZSh0YWJsZShkZiRkaWZmZXJlbnRfYWdlKSkgIyAzNyUgb2YgdGllcyBhcmUgYmV0d2VlbiBlZ29zIGFuZCBhbHRlcnMgZmFsbGluZyBpbiB0aGUgc2FtZSBhZ2UgY2F0ZWdvcnkNCiNkZiAlPiUgZGlzdGluY3QoYWx0ZXJpZCwgLmtlZXBfYWxsID0gVFJVRSkgJT4lDQojICBzZWxlY3QoZGlmZmVyZW50X2FnZSkgLT4gY2F0cw0KI3Byb3AudGFibGUodGFibGUoY2F0cykpICM0MyUgb2YgYWx0ZXJzIGFyZSBpbiBhIGRpZmZlcmVudCBhZ2UgcmFuZ2UgdGhhbiBlZ28uDQoNCiNlc3RpbWF0ZSBuZXcgbW9kZWw6DQphbnNfYWdlMiA8LSBnbG1lcihZIH4gMSArICgxIHwgZWdvKSArICgxIHwgZWdvOmFsdGVyaWQpICsgdGllICsgZGlmZmVyZW50X2dlbmRlciArIGRpZmZlcmVudF9lZHVjICsgZGlmZmVyZW50X2FnZSArIHBlcmlvZCArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSArIG11bHRpcGxleCArIGNsb3NlbmVzcy50ICsgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksDQogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBnbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIsIG9wdEN0cmwgPSBsaXN0KG1heGZ1biA9IDFlNSkpKQ0KDQojc3VtbWFyeShhbnNfYWdlMikNCg0KI3NhdmUoYW5zX2FnZTIsIGZpbGU9Ii4vcmVzdWx0cy9hbnNfYWdlX3NhbWVuZXNzLlJEYXRhIikNCmBgYCANCiAgDQpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCmxvYWQoIi4vcmVzdWx0cy9hbnNfYWdlX3NhbWVuZXNzLlJEYXRhIikNCg0KdGV4cmVnOjpodG1scmVnKGFuc19hZ2UyLA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9hZ2Vfc2FtZW5lc3MuaHRtbCIsDQogICAgICAgIGNhcHRpb249IlJlc3VsdHMgb2YgcmFuZG9tIGVmZmVjdHMgbW9kZWxzIHByZWRpY3RpbmcgdGllIGRpc3NvbHV0aW9uIGF0IHQrMSAoMT15ZXMsIDA9bm8pLCB1c2luZyBhbiBhbHRlcm5hdGl2ZSBvcGVyYXRpb25hbGl6YXRpb24gb2YgYWdlIGRpc3NpbWlsYXJpdHkiLCBjYXB0aW9uLmFib3ZlID0gVFJVRSwNCiAgICAgICAgY3VzdG9tLm1vZGVsLm5hbWVzID0gIk02IiwNCiAgICAgICAgY3VzdG9tLmNvZWYubmFtZXMgPSBjKCIoSW50ZXJjZXB0KSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJlc3QgZnJpZW5kIiwgIlNwb3J0cyBwYXJ0bmVyIiwgIlN0dWR5IHBhcnRuZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpZmZlcmVudCBnZW5kZXIiLCAiRGlmZmVyZW50IGVkdWNhdGlvbiIsICJEaWZmZXJlbnQgYWdlIChyYW5nZSkiLCAiUGVyaW9kOiB3YXZlIDIgLT4gd2F2ZSAzIiwNCiAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXNlYXJjaCB1bml2ZXJzaXR5IHN0dWRlbnQiLCAiU2Vjb25kIHllYXIgc3R1ZGVudCIsICJUaGlyZCB5ZWFyIG9yIGhpZ2hlciIsICJBZ2UgIiwgIkZlbWFsZSAiLCAiRXh0cmF2ZXJzaW9uIiwgIkZpbmFuY2lhbCByZXN0cmljdGlvbnMiLCAiUm9tYW50aWMgcmVsYXRpb25zaGlwIiwgIkhvdXNpbmcgdHJhbnNpdGlvbiIsICJTdHVkeSB0cmFuc2l0aW9uIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmVtYWxlIiwgIkVkdWNhdGlvbiIsICJBZ2UiLCAiWWVhcnMga25vd24iLCAiU2FtZSBtdW5pY2lwYWxpdHkiLCAiU2FtZSBob3VzZSIsICJOZXR3b3JrIHNpemUiLCAiTXVsdGlwbGV4aXR5IiwgIkVtb3Rpb25hbCBjbG9zZW5lc3MiLCAiU3RyLiBlbWJlZGRlZG5lc3MgZm9jYWwgbGF5ZXIiLCAiU3RyLiBlbWJlZGRlZG5lc3Mgb3RoZXIgbGF5ZXJzIiksDQogICAgICAgIGRpZ2l0cz0yLCBzaW5nbGUucm93ID0gVFJVRQ0KICAgICAgICApDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCmh0bWx0b29sczo6dGFncyRkaXYoDQogIHN0eWxlID0gImhlaWdodDogNjAwcHg7IG92ZXJmbG93LXk6IHNjcm9sbDsiLA0KICBodG1sdG9vbHM6OmluY2x1ZGVIVE1MKCIuL3Jlc3VsdHMvY29lZnRhYl9hZ2Vfc2FtZW5lc3MuaHRtbCIpDQopDQpgYGANCg0KDQojIyMgbGluZWFyIChkaXN0YW5jZSBpbiBjYXRlZ29yaWVzKQ0KDQoNCmBgYHtyLCBkaWZhZ2UzLCBldmFsPUZBTFNFfQ0KZGYkYWx0ZXJfYWdlX3JhbmdlIDwtIGZhY3RvcihkZiRhbHRlcl9hZ2VfcmFuZ2UpDQpkZiRkaWZfYWdlY2F0IDwtIGFicyhhcy5udW1lcmljKGRmJGVnb19hZ2VfcmFuZ2UpIC0gYXMubnVtZXJpYyhkZiRhbHRlcl9hZ2VfcmFuZ2UpKQ0KDQojZXN0aW1hdGUgbmV3IG1vZGVsOg0KYW5zX2FnZTMgPC0gZ2xtZXIoWSB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2VjYXQpICsgcGVyaW9kICsgZWdvX2VkdWMgICsgYXMuZmFjdG9yKHN0dWR5LnllYXIpICsgc2NhbGUoZWdvX2FnZSkgKyBlZ29fZmVtYWxlICsgc2NhbGUoZXh0cmF2ZXJzaW9uKSArIHNjYWxlKGZpbl9yZXN0cikgKyByb21hbnRpYyArIGhvdXNpbmcudHJhbnNpdGlvbiArIG9jY3VwYXRpb24udHJhbnNpdGlvbiArIGFsdGVyX2ZlbWFsZSArIHNjYWxlKGFsdGVyX2VkdWMpICsgc2NhbGUoYXMubnVtZXJpYyhhbHRlcl9hZ2UpKSArIHNjYWxlKGR1cmF0aW9uKSArIHByb3hpbWl0eSArIHNjYWxlKHNpemUpICsgbXVsdGlwbGV4ICsgY2xvc2VuZXNzLnQgKyBzY2FsZShlbWJlZCkgKyBzY2FsZShlbWJlZC5leHQpLA0KICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGYsIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSwNCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGdsbWVyQ29udHJvbChvcHRpbWl6ZXIgPSAiYm9ieXFhIiwgb3B0Q3RybCA9IGxpc3QobWF4ZnVuID0gMWU1KSkpDQoNCiNzdW1tYXJ5KGFuc19hZ2UzKQ0KDQojc2F2ZShhbnNfYWdlMywgZmlsZT0iLi9yZXN1bHRzL2NvZWZ0YWJfYWdlX2xpbmVhci5SRGF0YSIpDQpgYGAgDQogIA0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsb2FkKCIuL3Jlc3VsdHMvY29lZnRhYl9hZ2VfbGluZWFyLlJEYXRhIikNCg0KdGV4cmVnOjpodG1scmVnKGFuc19hZ2UzLA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9hZ2VfbGluZWFyLmh0bWwiLA0KICAgICAgICBjYXB0aW9uPSJSZXN1bHRzIG9mIHJhbmRvbSBlZmZlY3RzIG1vZGVscyBwcmVkaWN0aW5nIHRpZSBkaXNzb2x1dGlvbiBhdCB0KzEgKDE9eWVzLCAwPW5vKSwgdXNpbmcgYW4gYWx0ZXJuYXRpdmUgb3BlcmF0aW9uYWxpemF0aW9uIG9mIGFnZSBkaXNzaW1pbGFyaXR5IiwgY2FwdGlvbi5hYm92ZSA9IFRSVUUsDQogICAgICAgIGN1c3RvbS5tb2RlbC5uYW1lcyA9ICJNNiIsDQogICAgICAgIGN1c3RvbS5jb2VmLm5hbWVzID0gYygiKEludGVyY2VwdCkiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCZXN0IGZyaWVuZCIsICJTcG9ydHMgcGFydG5lciIsICJTdHVkeSBwYXJ0bmVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEaWZmZXJlbnQgZ2VuZGVyIiwgIkRpZmZlcmVudCBlZHVjYXRpb24iLCAiQWdlIGNhdGVnb3J5IGRpc3RhbmNlIiwgIlBlcmlvZDogd2F2ZSAyIC0+IHdhdmUgMyIsDQogICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVzZWFyY2ggdW5pdmVyc2l0eSBzdHVkZW50IiwgIlNlY29uZCB5ZWFyIHN0dWRlbnQiLCAiVGhpcmQgeWVhciBvciBoaWdoZXIiLCAiQWdlICIsICJGZW1hbGUgIiwgIkV4dHJhdmVyc2lvbiIsICJGaW5hbmNpYWwgcmVzdHJpY3Rpb25zIiwgIlJvbWFudGljIHJlbGF0aW9uc2hpcCIsICJIb3VzaW5nIHRyYW5zaXRpb24iLCAiU3R1ZHkgdHJhbnNpdGlvbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSIsICJFZHVjYXRpb24iLCAiQWdlIiwgIlllYXJzIGtub3duIiwgIlNhbWUgbXVuaWNpcGFsaXR5IiwgIlNhbWUgaG91c2UiLCAiTmV0d29yayBzaXplIiwgIk11bHRpcGxleGl0eSIsICJFbW90aW9uYWwgY2xvc2VuZXNzIiwgIlN0ci4gZW1iZWRkZWRuZXNzIGZvY2FsIGxheWVyIiwgIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUNCiAgICAgICAgKQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpodG1sdG9vbHM6OnRhZ3MkZGl2KA0KICBzdHlsZSA9ICJoZWlnaHQ6IDYwMHB4OyBvdmVyZmxvdy15OiBzY3JvbGw7IiwNCiAgaHRtbHRvb2xzOjppbmNsdWRlSFRNTCgiLi9yZXN1bHRzL2NvZWZ0YWJfYWdlX2xpbmVhci5odG1sIikNCikNCmBgYA0KDQojIyMgbGluZWFyIChzYW1lIGNhdGVnb3J5ID09IDApDQoNCg0KYGBge3IsIGRpZmFnZTQsIGV2YWw9RkFMU0V9DQpkZiRkaWZfYWdlMiA8LSBpZmVsc2UoZGYkZGlmZmVyZW50X2FnZSA9PSAxLCBkZiRkaWZfYWdlLCAwKQ0KDQojZXN0aW1hdGUgbmV3IG1vZGVsOg0KYW5zX2FnZTQgPC0gZ2xtZXIoWSB+IDEgKyAoMSB8IGVnbykgKyAoMSB8IGVnbzphbHRlcmlkKSArIHRpZSArIGRpZmZlcmVudF9nZW5kZXIgKyBkaWZmZXJlbnRfZWR1YyArIHNjYWxlKGRpZl9hZ2UyKSArIHBlcmlvZCArIGVnb19lZHVjICArIGFzLmZhY3RvcihzdHVkeS55ZWFyKSArIHNjYWxlKGVnb19hZ2UpICsgZWdvX2ZlbWFsZSArIHNjYWxlKGV4dHJhdmVyc2lvbikgKyBzY2FsZShmaW5fcmVzdHIpICsgcm9tYW50aWMgKyBob3VzaW5nLnRyYW5zaXRpb24gKyBvY2N1cGF0aW9uLnRyYW5zaXRpb24gKyBhbHRlcl9mZW1hbGUgKyBzY2FsZShhbHRlcl9lZHVjKSArIHNjYWxlKGFzLm51bWVyaWMoYWx0ZXJfYWdlKSkgKyBzY2FsZShkdXJhdGlvbikgKyBwcm94aW1pdHkgKyBzY2FsZShzaXplKSArIG11bHRpcGxleCArIGNsb3NlbmVzcy50ICsgc2NhbGUoZW1iZWQpICsgc2NhbGUoZW1iZWQuZXh0KSwNCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmLCBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksDQogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBnbG1lckNvbnRyb2wob3B0aW1pemVyID0gImJvYnlxYSIsIG9wdEN0cmwgPSBsaXN0KG1heGZ1biA9IDFlNSkpKQ0KDQojc3VtbWFyeShhbnNfYWdlNCkNCg0KI3NhdmUoYW5zX2FnZTQsIGZpbGU9Ii4vcmVzdWx0cy9jb2VmdGFiX2FnZV9saW5lYXIyLlJEYXRhIikNCmBgYCANCiAgDQpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCmxvYWQoIi4vcmVzdWx0cy9jb2VmdGFiX2FnZV9saW5lYXIyLlJEYXRhIikNCg0KdGV4cmVnOjpodG1scmVnKGFuc19hZ2U0LA0KICAgICAgICBmaWxlPSIuL3Jlc3VsdHMvY29lZnRhYl9hZ2VfbGluZWFyMi5odG1sIiwNCiAgICAgICAgY2FwdGlvbj0iUmVzdWx0cyBvZiByYW5kb20gZWZmZWN0cyBtb2RlbHMgcHJlZGljdGluZyB0aWUgZGlzc29sdXRpb24gYXQgdCsxICgxPXllcywgMD1ubyksIHVzaW5nIGFuIGFsdGVybmF0aXZlIG9wZXJhdGlvbmFsaXphdGlvbiBvZiBhZ2UgZGlzc2ltaWxhcml0eSIsIGNhcHRpb24uYWJvdmUgPSBUUlVFLA0KICAgICAgICBjdXN0b20ubW9kZWwubmFtZXMgPSAiTTYiLA0KICAgICAgICBjdXN0b20uY29lZi5uYW1lcyA9IGMoIihJbnRlcmNlcHQpIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmVzdCBmcmllbmQiLCAiU3BvcnRzIHBhcnRuZXIiLCAiU3R1ZHkgcGFydG5lciIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlmZmVyZW50IGdlbmRlciIsICJEaWZmZXJlbnQgZWR1Y2F0aW9uIiwgIkFnZSBkaWZmZXJlbmNlIiwgIlBlcmlvZDogd2F2ZSAyIC0+IHdhdmUgMyIsDQogICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVzZWFyY2ggdW5pdmVyc2l0eSBzdHVkZW50IiwgIlNlY29uZCB5ZWFyIHN0dWRlbnQiLCAiVGhpcmQgeWVhciBvciBoaWdoZXIiLCAiQWdlICIsICJGZW1hbGUgIiwgIkV4dHJhdmVyc2lvbiIsICJGaW5hbmNpYWwgcmVzdHJpY3Rpb25zIiwgIlJvbWFudGljIHJlbGF0aW9uc2hpcCIsICJIb3VzaW5nIHRyYW5zaXRpb24iLCAiU3R1ZHkgdHJhbnNpdGlvbiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZlbWFsZSIsICJFZHVjYXRpb24iLCAiQWdlIiwgIlllYXJzIGtub3duIiwgIlNhbWUgbXVuaWNpcGFsaXR5IiwgIlNhbWUgaG91c2UiLCAiTmV0d29yayBzaXplIiwgIk11bHRpcGxleGl0eSIsICJFbW90aW9uYWwgY2xvc2VuZXNzIiwgIlN0ci4gZW1iZWRkZWRuZXNzIGZvY2FsIGxheWVyIiwgIlN0ci4gZW1iZWRkZWRuZXNzIG90aGVyIGxheWVycyIpLA0KICAgICAgICBkaWdpdHM9Miwgc2luZ2xlLnJvdyA9IFRSVUUNCiAgICAgICAgKQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpodG1sdG9vbHM6OnRhZ3MkZGl2KA0KICBzdHlsZSA9ICJoZWlnaHQ6IDYwMHB4OyBvdmVyZmxvdy15OiBzY3JvbGw7IiwNCiAgaHRtbHRvb2xzOjppbmNsdWRlSFRNTCgiLi9yZXN1bHRzL2NvZWZ0YWJfYWdlX2xpbmVhcjIuaHRtbCIpDQopDQpgYGANCg0KIyMgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KLS0tDQo=


Copyright © 2025 Rob Franken