Awareness and Adoption of Open Research Practices in Ireland

Training Preferences Analysis

This notebook contains the preregistered analyses of training preferences: background variables, COM-B factors, and mean awareness/engagement as predictors of interest in receiving training in Open Research Practices.

library(readxl)
library(broom)
library(ggplot2)
library(sandwich)
library(lmtest)

1. Load data

The file contains background variables, COM-B composites, mean awareness, mean engagement, and the recoded training interest outcome (WantTraining_recoded: 0 = No, 1 = Yes).

df_train <-  read_excel("TrainingPreferences_Analysis.xlsx")

df_train$Gender_new      <- as.factor(df_train$Gender_new)
df_train$Role_new        <- as.factor(df_train$Role_new)
df_train$Methodology_new <- as.factor(df_train$Methodology_new)
df_train$Rank_new        <- as.factor(df_train$Rank_new)
df_train$Discipline_new  <- as.factor(df_train$Discipline_new)

2. Note on model choice

The preregistered plan specified logistic regression for the binary outcome (WantTraining_recoded: 0 = No, 1 = Yes). However, standard logistic regression did not converge due to complete separation in sparse categorical predictors.

Train_logit <- glm(WantTraining_recoded ~ Gender_new + Role_new +
                           Methodology_new + Rank_new + Discipline_new,
                           data = df_train,
                           family = binomial)

summary(Train_logit)
# Check for complete separation
table(df_train$Rank_new, df_train$WantTraining_recoded, useNA = "ifany")

The standard errors for the affected categories are in the thousands, indicating that the model cannot estimate these coefficients. The crosstab above shows the reason: Rank = “Other” has 0 respondents who said “No” to training, so the outcome is perfectly predicted by that category.

A linear probability model (LPM) was therefore used for the reported analyses. The LPM is a standard and interpretable alternative for binary outcomes; coefficients represent changes in the probability of the outcome.

3. Baseline model: background variables only

Train_baseline <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                     Methodology_new + Rank_new + Discipline_new,
                     data = df_train)
summary(Train_baseline)

4. Separate models: background + one COM-B component

Train_PC <- lm(WantTraining_recoded ~ Gender_new + Role_new +
               Methodology_new + Rank_new + Discipline_new +
               PhysicalCapability, data = df_train)

Train_PsyC <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                 Methodology_new + Rank_new + Discipline_new +
                 PsychologicalCapability, data = df_train)

Train_PO <- lm(WantTraining_recoded ~ Gender_new + Role_new +
               Methodology_new + Rank_new + Discipline_new +
               PhysicalOpportunity, data = df_train)

Train_SO <- lm(WantTraining_recoded ~ Gender_new + Role_new +
               Methodology_new + Rank_new + Discipline_new +
               SocialOpportunity, data = df_train)

Train_RM <- lm(WantTraining_recoded ~ Gender_new + Role_new +
               Methodology_new + Rank_new + Discipline_new +
               ReflectiveMotivation, data = df_train)

Train_AM <- lm(WantTraining_recoded ~ Gender_new + Role_new +
               Methodology_new + Rank_new + Discipline_new +
               AutomaticMotivation, data = df_train)

Extract just the COM-B coefficient from each separate model:

summary(Train_PC)$coefficients["PhysicalCapability", ]
summary(Train_PsyC)$coefficients["PsychologicalCapability", ]
summary(Train_PO)$coefficients["PhysicalOpportunity", ]
summary(Train_SO)$coefficients["SocialOpportunity", ]
summary(Train_RM)$coefficients["ReflectiveMotivation", ]
summary(Train_AM)$coefficients["AutomaticMotivation", ]

5. All COM-B model

Train_AllComb <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                    Methodology_new + Rank_new + Discipline_new +
                    PhysicalCapability + PsychologicalCapability +
                    PhysicalOpportunity + SocialOpportunity +
                    ReflectiveMotivation + AutomaticMotivation,
                    data = df_train)
summary(Train_AllComb)

6. Awareness and engagement models

Train_aware_bg <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                     Methodology_new + Rank_new + Discipline_new +
                     MeanAwareness, data = df_train)

Train_engage_bg <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                      Methodology_new + Rank_new + Discipline_new +
                      MeanEngagement, data = df_train)

Train_AE_bg <- lm(WantTraining_recoded ~ Gender_new + Role_new +
                  Methodology_new + Rank_new + Discipline_new +
                  MeanAwareness + MeanEngagement, data = df_train)

summary(Train_aware_bg)
summary(Train_engage_bg)
summary(Train_AE_bg)

7. Robust standard errors

The LPM assumes homoscedasticity, which is not strictly met with a binary outcome. Robust (heteroscedasticity-consistent) standard errors are reported below for the main models.

coeftest(Train_baseline, vcov = vcovHC(Train_baseline, type = "HC1"))
coeftest(Train_AllComb,  vcov = vcovHC(Train_AllComb,  type = "HC1"))
coeftest(Train_AE_bg,    vcov = vcovHC(Train_AE_bg,    type = "HC1"))
# Means and SDs
aggregate(cbind(MeanAwareness, MeanEngagement) ~ Discipline_new, 
          data = df_train, FUN = mean)

aggregate(cbind(MeanAwareness, MeanEngagement) ~ Discipline_new, 
          data = df_train, FUN = sd)

# Sample size per discipline
table(df_train$Discipline_new, useNA = "ifany")
# Subset: three main disciplines only (exclude "Other")
df_disc <- df_train[df_train$Discipline_new %in% c(0, 1, 2), ]

# Awareness
disc_aware <- lm(MeanAwareness ~ Discipline_new, data = df_disc)
summary(disc_aware)
anova(disc_aware)

# Engagement
disc_engage <- lm(MeanEngagement ~ Discipline_new, data = df_disc)
summary(disc_engage)
anova(disc_engage)
# Subset: three main methodologies (exclude "Other")
df_meth <- df_train[df_train$Methodology_new %in% c(0, 1, 2), ]

# Confirm counts
table(df_meth$Methodology_new)

# Awareness across methodologies
meth_aware <- lm(MeanAwareness ~ Methodology_new, data = df_meth)
summary(meth_aware)
anova(meth_aware)

# Engagement across methodologies
meth_engage <- lm(MeanEngagement ~ Methodology_new, data = df_meth)
summary(meth_engage)
anova(meth_engage)
# Recode so Qualitative (1) is the reference
df_meth$Methodology_factor <- factor(df_meth$Methodology_new, 
                                     levels = c(1, 0, 2))
# Now: 1 = Qualitative (reference), 0 = Quantitative, 2 = Mixed

meth_engage2 <- lm(MeanEngagement ~ Methodology_factor, data = df_meth)
summary(meth_engage2)
# Create a binary flag: research-active vs not
df_train$Role_group <- ifelse(df_train$Role_new == 0, "Research/Academic", "Other roles")

# Descriptives by role group
aggregate(cbind(MeanAwareness, MeanEngagement) ~ Role_group, 
          data = df_train, FUN = mean)

aggregate(cbind(MeanAwareness, MeanEngagement) ~ Role_group, 
          data = df_train, FUN = sd)

table(df_train$Role_group, useNA = "ifany")
# Ensure Role_group is a factor with Research/Academic as the reference
df_train$Role_group <- factor(df_train$Role_group, 
                              levels = c("Research/Academic", "Other roles"))

# Awareness
role_aware <- lm(MeanAwareness ~ Role_group, data = df_train)
summary(role_aware)
anova(role_aware)

# Engagement
role_engage <- lm(MeanEngagement ~ Role_group, data = df_train)
summary(role_engage)
anova(role_engage)
library(ggplot2)
library(dplyr)
library(tidyr)
library(scales)

# Compute means by discipline (three main disciplines only)
disc_means <- df_train %>%
  filter(Discipline_new %in% c(0, 1, 2)) %>%
  group_by(Discipline_new) %>%
  summarise(
    Awareness  = mean(MeanAwareness, na.rm = TRUE),
    Engagement = mean(MeanEngagement, na.rm = TRUE),
    N = n()
  ) %>%
  mutate(Discipline = factor(Discipline_new,
                              levels = c(0, 1, 2),
                              labels = c("Science", "Social Sciences", "Humanities")))

# Print to verify numbers
print(disc_means)

# Reshape to long format
disc_long <- disc_means %>%
  pivot_longer(cols = c(Awareness, Engagement),
               names_to = "Outcome",
               values_to = "Mean") %>%
  mutate(Outcome = factor(Outcome, levels = c("Awareness", "Engagement")))

# Publication-ready plot
ggplot(disc_long, aes(x = Discipline, y = Mean, fill = Outcome)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65,
           colour = "black", linewidth = 0.3) +
  geom_text(aes(label = sprintf("%.0f%%", Mean * 100)),
            position = position_dodge(width = 0.75),
            vjust = -0.5, size = 3, family = "serif") +
  scale_fill_manual(values = c("Awareness" = "#A8C4C4", "Engagement" = "#4A6E8A")) +
  scale_y_continuous(limits = c(0, 1.05),
                     breaks = seq(0, 1, 0.2),
                     labels = percent_format(accuracy = 1),
                     expand = c(0, 0)) +
  labs(x = NULL, y = "Mean (% of practices)", fill = NULL) +
  theme_classic(base_family = "serif", base_size = 11) +
  theme(
    legend.position   = "top",
    legend.key.size   = unit(0.4, "cm"),
    legend.text       = element_text(size = 10),
    axis.text         = element_text(colour = "black", size = 10),
    axis.title.y      = element_text(size = 11, margin = margin(r = 8)),
    axis.line         = element_line(colour = "black", linewidth = 0.4),
    axis.ticks        = element_line(colour = "black", linewidth = 0.4),
    plot.margin       = margin(10, 10, 10, 10)
  )

# Save as PNG (300 DPI) and PDF (vector)
ggsave("FigureA2_discipline.png", width = 6.5, height = 4.5, dpi = 300)
ggsave("FigureA2_discipline.pdf", width = 6.5, height = 4.5)
library(ggplot2)
library(dplyr)
library(tidyr)

# Compute COM-B means by discipline (three main disciplines only)
comb_means <- df_train %>%
  filter(Discipline_new %in% c(0, 1, 2)) %>%
  group_by(Discipline_new) %>%
  summarise(
    PhysicalCapability      = mean(PhysicalCapability, na.rm = TRUE),
    PsychologicalCapability = mean(PsychologicalCapability, na.rm = TRUE),
    PhysicalOpportunity     = mean(PhysicalOpportunity, na.rm = TRUE),
    SocialOpportunity       = mean(SocialOpportunity, na.rm = TRUE),
    ReflectiveMotivation    = mean(ReflectiveMotivation, na.rm = TRUE),
    AutomaticMotivation     = mean(AutomaticMotivation, na.rm = TRUE),
    N = n()
  ) %>%
  pivot_longer(cols = -c(Discipline_new, N),
               names_to = "COM_B",
               values_to = "Mean") %>%
  mutate(
    Discipline = factor(Discipline_new,
                        levels = c(0, 1, 2),
                        labels = c("Science", "Social Sciences", "Humanities")),
    COM_B = factor(COM_B,
                   levels = c("PhysicalCapability", "PsychologicalCapability",
                              "PhysicalOpportunity", "SocialOpportunity",
                              "ReflectiveMotivation", "AutomaticMotivation"),
                   labels = c("Physical Capability", "Psychological Capability",
                              "Physical Opportunity", "Social Opportunity",
                              "Reflective Motivation", "Automatic Motivation"))
  )

# Print to verify numbers
print(comb_means %>% select(Discipline, COM_B, Mean))

# Publication-ready plot
ggplot(comb_means, aes(x = COM_B, y = Mean, fill = Discipline)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65,
           colour = "black", linewidth = 0.3) +

  geom_text(aes(label = sprintf("%.2f", Mean)),
            position = position_dodge(width = 0.75),
            hjust = -0.15, size = 3.5, family = "serif") +
  scale_fill_manual(values = c("Science"          = "#4A6E8A",
                                "Social Sciences"  = "#A8C4C4",
                                "Humanities"       = "#D9E2E2")) +
  scale_y_continuous(limits = c(0, 7.5),
                     breaks = seq(0, 7, 1),
                     expand = c(0, 0)) +
  coord_flip() +
  labs(x = NULL, y = "Mean score", fill = NULL) +
  theme_classic(base_family = "serif", base_size = 11) +
  theme(
    legend.position   = "top",
    legend.key.size   = unit(0.4, "cm"),
    legend.text       = element_text(size = 12),
    axis.text         = element_text(colour = "black", size = 12),
    axis.title.x      = element_text(size = 11, margin = margin(t = 8)),
    axis.line         = element_line(colour = "black", linewidth = 0.4),
    axis.ticks        = element_line(colour = "black", linewidth = 0.4),
    plot.margin       = margin(10, 10, 10, 10)
  )

# Save
ggsave("Figure4_comb.png", width = 8, height = 7, dpi = 300)
ggsave("Figure4_comb.pdf", width = 8, height = 7)
library(ggplot2)
library(dplyr)
library(tidyr)
library(forcats) # Added for fct_reorder

# Compute COM-B means by discipline (three main disciplines only)
comb_means <- df_train %>%
  filter(Discipline_new %in% c(0, 1, 2)) %>%
  group_by(Discipline_new) %>%
  summarise(
    PhysicalCapability      = mean(PhysicalCapability, na.rm = TRUE),
    PsychologicalCapability = mean(PsychologicalCapability, na.rm = TRUE),
    PhysicalOpportunity     = mean(PhysicalOpportunity, na.rm = TRUE),
    SocialOpportunity       = mean(SocialOpportunity, na.rm = TRUE),
    ReflectiveMotivation    = mean(ReflectiveMotivation, na.rm = TRUE),
    AutomaticMotivation     = mean(AutomaticMotivation, na.rm = TRUE),
    N = n()
  ) %>%
  pivot_longer(cols = -c(Discipline_new, N),
               names_to = "COM_B",
               values_to = "Mean") %>%
  mutate(
    # 1. Science on top: Reverse levels so Science is last (top in coord_flip)
    Discipline = factor(Discipline_new,
                        levels = c(2, 1, 0), 
                        labels = c("Humanities", "Social Sciences", "Science")),
    COM_B = factor(COM_B,
                   levels = c("PhysicalCapability", "PsychologicalCapability",
                              "PhysicalOpportunity", "SocialOpportunity",
                              "ReflectiveMotivation", "AutomaticMotivation"),
                   labels = c("Physical Capability", "Psychological Capability",
                              "Physical Opportunity", "Social Opportunity",
                              "Reflective Motivation", "Automatic Motivation"))
  ) %>%
  mutate(
    # 2. Increasing order top to bottom: Largest mean gets first level (bottom)
    COM_B = fct_reorder(COM_B, Mean, .fun = mean, .desc = TRUE)
  )

# Print to verify numbers
print(comb_means %>% select(Discipline, COM_B, Mean))

# Publication-ready plot
ggplot(comb_means, aes(x = COM_B, y = Mean, fill = Discipline)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65,
           colour = "black", linewidth = 0.3) +
  geom_text(aes(label = sprintf("%.2f", Mean)),
            position = position_dodge(width = 0.75),
            hjust = -0.15, size = 3.5, family = "serif") +
  scale_fill_manual(values = c("Science"          = "#4A6E8A",
                                "Social Sciences"  = "#A8C4C4",
                                "Humanities"       = "#D9E2E2")) +
  scale_y_continuous(limits = c(0, 7.5),
                     breaks = seq(0, 7, 1),
                     expand = c(0, 0)) +
  coord_flip() +
  labs(x = NULL, y = "Mean score", fill = NULL) +
  theme_classic(base_family = "serif", base_size = 11) +
  theme(
    legend.position   = "top",
    legend.key.size   = unit(0.4, "cm"),
    legend.text       = element_text(size = 12),
    axis.text         = element_text(colour = "black", size = 12),
    axis.title.x      = element_text(size = 11, margin = margin(t = 8)),
    axis.line         = element_line(colour = "black", linewidth = 0.4),
    axis.ticks        = element_line(colour = "black", linewidth = 0.4),
    plot.margin       = margin(10, 10, 10, 10)
  )

# Save
ggsave("Figure4_comb.png", width = 8, height = 7, dpi = 300)
ggsave("Figure4_comb.pdf", width = 8, height = 7)
library(ggplot2)
library(dplyr)
library(tidyr)
library(scales)

# Compute means by discipline (three main disciplines only)
disc_means <- df_train %>%
  filter(Discipline_new %in% c(0, 1, 2)) %>%
  group_by(Discipline_new) %>%
  summarise(
    Awareness  = mean(MeanAwareness, na.rm = TRUE),
    Engagement = mean(MeanEngagement, na.rm = TRUE),
    N = n()
  ) %>%
  mutate(Discipline = factor(Discipline_new,
                              levels = c(0, 1, 2),
                              labels = c("Science", "Social Sciences", "Humanities")))

# Print to verify numbers
print(disc_means)

# Reshape to long format
disc_long <- disc_means %>%
  pivot_longer(cols = c(Awareness, Engagement),
               names_to = "Outcome",
               values_to = "Mean") %>%
  mutate(Outcome = factor(Outcome, levels = c("Awareness", "Engagement")))

# Publication-ready plot
ggplot(disc_long, aes(x = Discipline, y = Mean, fill = Outcome)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65,
           colour = "black", linewidth = 0.3) +
  scale_fill_manual(values = c("Awareness" = "#A8C4C4", "Engagement" = "#4A6E8A")) +
  scale_y_continuous(limits = c(0, 1.05),
                     breaks = seq(0, 1, 0.2),
                     labels = percent_format(accuracy = 1),
                     expand = c(0, 0)) +
  labs(x = NULL, y = NULL, fill = NULL) +  
  theme_classic(base_family = "serif", base_size = 11) +
  theme(
    legend.position   = "top",
    legend.key.size   = unit(0.4, "cm"),
    legend.text       = element_text(size = 10),
    axis.text         = element_text(colour = "black", size = 10),
    axis.line         = element_line(colour = "black", linewidth = 0.4),
    axis.ticks        = element_line(colour = "black", linewidth = 0.4),
    plot.margin       = margin(10, 10, 10, 10)
  )

# Save as PNG (300 DPI) and PDF (vector)
ggsave("FigureA2_discipline.png", width = 3.5, height = 4.5, dpi = 300)
ggsave("FigureA2_discipline.pdf", width = 3.5, height = 4.5)
library(ggplot2)
library(dplyr)
library(tidyr)
library(scales)

# Compute means by methodology
meth_means <- df_train %>%
  filter(Methodology_new %in% c(0, 1, 2)) %>%
  group_by(Methodology_new) %>%
  summarise(
    Awareness  = mean(MeanAwareness, na.rm = TRUE),
    Engagement = mean(MeanEngagement, na.rm = TRUE),
    N = n()
  ) %>%
  mutate(Methodology = factor(Methodology_new,
                              levels = c(0, 1, 2),
                              labels = c("Quantitative", "Qualitative", "Mixed methods")))

# Print to verify numbers
print(meth_means)

# Reshape to long format
meth_long <- meth_means %>%
  pivot_longer(cols = c(Awareness, Engagement),
               names_to = "Outcome",
               values_to = "Mean") %>%
  mutate(Outcome = factor(Outcome, levels = c("Awareness", "Engagement")))

# Publication-ready plot
ggplot(meth_long, aes(x = Methodology, y = Mean, fill = Outcome)) +
  geom_col(position = position_dodge(width = 0.75), width = 0.65,
           colour = "black", linewidth = 0.3) +
  scale_fill_manual(values = c("Awareness" = "#A8C4C4", "Engagement" = "#4A6E8A")) +
  scale_y_continuous(limits = c(0, 1.05),
                     breaks = seq(0, 1, 0.2),
                     labels = percent_format(accuracy = 1),
                     expand = c(0, 0)) +
  labs(x = NULL, y = NULL, fill = NULL) +  
  theme_classic(base_family = "serif", base_size = 11) +
  theme(
    legend.position   = "top",
    legend.key.size   = unit(0.4, "cm"),
    legend.text       = element_text(size = 10),
    axis.text.x       = element_text(colour = "black", size = 10),
    axis.text.y       = element_blank(),   
    axis.line         = element_line(colour = "black", linewidth = 0.4),
    axis.ticks        = element_line(colour = "black", linewidth = 0.4),
    plot.margin       = margin(10, 10, 10, 10)
  )

# Save as PNG (300 DPI for submission) and PDF (vector)
ggsave("FigureA2_methodology.png", width = 3.5, height = 4.5, dpi = 300)
ggsave("FigureA2_methodology.pdf", width = 3.5, height = 4.5)
LS0tDQp0aXRsZTogIlRyYWluaW5nIFByZWZlcmVuY2VzIEFuYWx5c2lzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgdG9jOiB0cnVlDQotLS0NCg0KIyBBd2FyZW5lc3MgYW5kIEFkb3B0aW9uIG9mIE9wZW4gUmVzZWFyY2ggUHJhY3RpY2VzIGluIElyZWxhbmQNCg0KIyBUcmFpbmluZyBQcmVmZXJlbmNlcyBBbmFseXNpcw0KDQpUaGlzIG5vdGVib29rIGNvbnRhaW5zIHRoZSBwcmVyZWdpc3RlcmVkIGFuYWx5c2VzIG9mIHRyYWluaW5nIHByZWZlcmVuY2VzOiBiYWNrZ3JvdW5kIHZhcmlhYmxlcywgQ09NLUIgZmFjdG9ycywgYW5kIG1lYW4gYXdhcmVuZXNzL2VuZ2FnZW1lbnQgYXMgcHJlZGljdG9ycyBvZiBpbnRlcmVzdCBpbiByZWNlaXZpbmcgdHJhaW5pbmcgaW4gT3BlbiBSZXNlYXJjaCBQcmFjdGljZXMuDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzYW5kd2ljaCkNCmxpYnJhcnkobG10ZXN0KQ0KDQpgYGANCg0KIyMgMS4gTG9hZCBkYXRhDQoNClRoZSBmaWxlIGNvbnRhaW5zIGJhY2tncm91bmQgdmFyaWFibGVzLCBDT00tQiBjb21wb3NpdGVzLCBtZWFuIGF3YXJlbmVzcywgbWVhbiBlbmdhZ2VtZW50LCBhbmQgdGhlIHJlY29kZWQgdHJhaW5pbmcgaW50ZXJlc3Qgb3V0Y29tZSAoYFdhbnRUcmFpbmluZ19yZWNvZGVkYDogMCA9IE5vLCAxID0gWWVzKS4NCg0KYGBge3J9DQpkZl90cmFpbiA8LSAgcmVhZF9leGNlbCgiVHJhaW5pbmdQcmVmZXJlbmNlc19BbmFseXNpcy54bHN4IikNCg0KZGZfdHJhaW4kR2VuZGVyX25ldyAgICAgIDwtIGFzLmZhY3RvcihkZl90cmFpbiRHZW5kZXJfbmV3KQ0KZGZfdHJhaW4kUm9sZV9uZXcgICAgICAgIDwtIGFzLmZhY3RvcihkZl90cmFpbiRSb2xlX25ldykNCmRmX3RyYWluJE1ldGhvZG9sb2d5X25ldyA8LSBhcy5mYWN0b3IoZGZfdHJhaW4kTWV0aG9kb2xvZ3lfbmV3KQ0KZGZfdHJhaW4kUmFua19uZXcgICAgICAgIDwtIGFzLmZhY3RvcihkZl90cmFpbiRSYW5rX25ldykNCmRmX3RyYWluJERpc2NpcGxpbmVfbmV3ICA8LSBhcy5mYWN0b3IoZGZfdHJhaW4kRGlzY2lwbGluZV9uZXcpDQoNCmBgYA0KDQojIyAyLiBOb3RlIG9uIG1vZGVsIGNob2ljZQ0KDQpUaGUgcHJlcmVnaXN0ZXJlZCBwbGFuIHNwZWNpZmllZCBsb2dpc3RpYyByZWdyZXNzaW9uIGZvciB0aGUgYmluYXJ5IG91dGNvbWUgKGBXYW50VHJhaW5pbmdfcmVjb2RlZGA6IDAgPSBObywgMSA9IFllcykuIEhvd2V2ZXIsIHN0YW5kYXJkIGxvZ2lzdGljIHJlZ3Jlc3Npb24gZGlkIG5vdCBjb252ZXJnZSBkdWUgdG8gY29tcGxldGUgc2VwYXJhdGlvbiBpbiBzcGFyc2UgY2F0ZWdvcmljYWwgcHJlZGljdG9ycy4NCg0KYGBge3J9DQpUcmFpbl9sb2dpdCA8LSBnbG0oV2FudFRyYWluaW5nX3JlY29kZWQgfiBHZW5kZXJfbmV3ICsgUm9sZV9uZXcgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgTWV0aG9kb2xvZ3lfbmV3ICsgUmFua19uZXcgKyBEaXNjaXBsaW5lX25ldywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKQ0KDQpzdW1tYXJ5KFRyYWluX2xvZ2l0KQ0KDQpgYGANCg0KYGBge3J9DQojIENoZWNrIGZvciBjb21wbGV0ZSBzZXBhcmF0aW9uDQp0YWJsZShkZl90cmFpbiRSYW5rX25ldywgZGZfdHJhaW4kV2FudFRyYWluaW5nX3JlY29kZWQsIHVzZU5BID0gImlmYW55IikNCg0KYGBgDQoNClRoZSBzdGFuZGFyZCBlcnJvcnMgZm9yIHRoZSBhZmZlY3RlZCBjYXRlZ29yaWVzIGFyZSBpbiB0aGUgdGhvdXNhbmRzLCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vZGVsIGNhbm5vdCBlc3RpbWF0ZSB0aGVzZSBjb2VmZmljaWVudHMuIFRoZSBjcm9zc3RhYiBhYm92ZSBzaG93cyB0aGUgcmVhc29uOiBSYW5rID0gIk90aGVyIiBoYXMgMCByZXNwb25kZW50cyB3aG8gc2FpZCAiTm8iIHRvIHRyYWluaW5nLCBzbyB0aGUgb3V0Y29tZSBpcyBwZXJmZWN0bHkgcHJlZGljdGVkIGJ5IHRoYXQgY2F0ZWdvcnkuDQoNCkEgbGluZWFyIHByb2JhYmlsaXR5IG1vZGVsIChMUE0pIHdhcyB0aGVyZWZvcmUgdXNlZCBmb3IgdGhlIHJlcG9ydGVkIGFuYWx5c2VzLiBUaGUgTFBNIGlzIGEgc3RhbmRhcmQgYW5kIGludGVycHJldGFibGUgYWx0ZXJuYXRpdmUgZm9yIGJpbmFyeSBvdXRjb21lczsgY29lZmZpY2llbnRzIHJlcHJlc2VudCBjaGFuZ2VzIGluIHRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgb3V0Y29tZS4NCg0KIyMgMy4gQmFzZWxpbmUgbW9kZWw6IGJhY2tncm91bmQgdmFyaWFibGVzIG9ubHkNCg0KYGBge3J9DQpUcmFpbl9iYXNlbGluZSA8LSBsbShXYW50VHJhaW5pbmdfcmVjb2RlZCB+IEdlbmRlcl9uZXcgKyBSb2xlX25ldyArDQogICAgICAgICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3LA0KICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX3RyYWluKQ0Kc3VtbWFyeShUcmFpbl9iYXNlbGluZSkNCg0KYGBgDQoNCiMjIDQuIFNlcGFyYXRlIG1vZGVsczogYmFja2dyb3VuZCArIG9uZSBDT00tQiBjb21wb25lbnQNCg0KYGBge3J9DQpUcmFpbl9QQyA8LSBsbShXYW50VHJhaW5pbmdfcmVjb2RlZCB+IEdlbmRlcl9uZXcgKyBSb2xlX25ldyArDQogICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgIFBoeXNpY2FsQ2FwYWJpbGl0eSwgZGF0YSA9IGRmX3RyYWluKQ0KDQpUcmFpbl9Qc3lDIDwtIGxtKFdhbnRUcmFpbmluZ19yZWNvZGVkIH4gR2VuZGVyX25ldyArIFJvbGVfbmV3ICsNCiAgICAgICAgICAgICAgICAgTWV0aG9kb2xvZ3lfbmV3ICsgUmFua19uZXcgKyBEaXNjaXBsaW5lX25ldyArDQogICAgICAgICAgICAgICAgIFBzeWNob2xvZ2ljYWxDYXBhYmlsaXR5LCBkYXRhID0gZGZfdHJhaW4pDQoNClRyYWluX1BPIDwtIGxtKFdhbnRUcmFpbmluZ19yZWNvZGVkIH4gR2VuZGVyX25ldyArIFJvbGVfbmV3ICsNCiAgICAgICAgICAgICAgIE1ldGhvZG9sb2d5X25ldyArIFJhbmtfbmV3ICsgRGlzY2lwbGluZV9uZXcgKw0KICAgICAgICAgICAgICAgUGh5c2ljYWxPcHBvcnR1bml0eSwgZGF0YSA9IGRmX3RyYWluKQ0KDQpUcmFpbl9TTyA8LSBsbShXYW50VHJhaW5pbmdfcmVjb2RlZCB+IEdlbmRlcl9uZXcgKyBSb2xlX25ldyArDQogICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgIFNvY2lhbE9wcG9ydHVuaXR5LCBkYXRhID0gZGZfdHJhaW4pDQoNClRyYWluX1JNIDwtIGxtKFdhbnRUcmFpbmluZ19yZWNvZGVkIH4gR2VuZGVyX25ldyArIFJvbGVfbmV3ICsNCiAgICAgICAgICAgICAgIE1ldGhvZG9sb2d5X25ldyArIFJhbmtfbmV3ICsgRGlzY2lwbGluZV9uZXcgKw0KICAgICAgICAgICAgICAgUmVmbGVjdGl2ZU1vdGl2YXRpb24sIGRhdGEgPSBkZl90cmFpbikNCg0KVHJhaW5fQU0gPC0gbG0oV2FudFRyYWluaW5nX3JlY29kZWQgfiBHZW5kZXJfbmV3ICsgUm9sZV9uZXcgKw0KICAgICAgICAgICAgICAgTWV0aG9kb2xvZ3lfbmV3ICsgUmFua19uZXcgKyBEaXNjaXBsaW5lX25ldyArDQogICAgICAgICAgICAgICBBdXRvbWF0aWNNb3RpdmF0aW9uLCBkYXRhID0gZGZfdHJhaW4pDQpgYGANCg0KRXh0cmFjdCBqdXN0IHRoZSBDT00tQiBjb2VmZmljaWVudCBmcm9tIGVhY2ggc2VwYXJhdGUgbW9kZWw6DQoNCmBgYHtyfQ0Kc3VtbWFyeShUcmFpbl9QQykkY29lZmZpY2llbnRzWyJQaHlzaWNhbENhcGFiaWxpdHkiLCBdDQpzdW1tYXJ5KFRyYWluX1BzeUMpJGNvZWZmaWNpZW50c1siUHN5Y2hvbG9naWNhbENhcGFiaWxpdHkiLCBdDQpzdW1tYXJ5KFRyYWluX1BPKSRjb2VmZmljaWVudHNbIlBoeXNpY2FsT3Bwb3J0dW5pdHkiLCBdDQpzdW1tYXJ5KFRyYWluX1NPKSRjb2VmZmljaWVudHNbIlNvY2lhbE9wcG9ydHVuaXR5IiwgXQ0Kc3VtbWFyeShUcmFpbl9STSkkY29lZmZpY2llbnRzWyJSZWZsZWN0aXZlTW90aXZhdGlvbiIsIF0NCnN1bW1hcnkoVHJhaW5fQU0pJGNvZWZmaWNpZW50c1siQXV0b21hdGljTW90aXZhdGlvbiIsIF0NCg0KYGBgDQoNCiMjIDUuIEFsbCBDT00tQiBtb2RlbA0KDQpgYGB7cn0NClRyYWluX0FsbENvbWIgPC0gbG0oV2FudFRyYWluaW5nX3JlY29kZWQgfiBHZW5kZXJfbmV3ICsgUm9sZV9uZXcgKw0KICAgICAgICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgICAgICAgUGh5c2ljYWxDYXBhYmlsaXR5ICsgUHN5Y2hvbG9naWNhbENhcGFiaWxpdHkgKw0KICAgICAgICAgICAgICAgICAgICBQaHlzaWNhbE9wcG9ydHVuaXR5ICsgU29jaWFsT3Bwb3J0dW5pdHkgKw0KICAgICAgICAgICAgICAgICAgICBSZWZsZWN0aXZlTW90aXZhdGlvbiArIEF1dG9tYXRpY01vdGl2YXRpb24sDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl90cmFpbikNCnN1bW1hcnkoVHJhaW5fQWxsQ29tYikNCg0KYGBgDQoNCiMjIDYuIEF3YXJlbmVzcyBhbmQgZW5nYWdlbWVudCBtb2RlbHMNCg0KYGBge3J9DQpUcmFpbl9hd2FyZV9iZyA8LSBsbShXYW50VHJhaW5pbmdfcmVjb2RlZCB+IEdlbmRlcl9uZXcgKyBSb2xlX25ldyArDQogICAgICAgICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgICAgICAgIE1lYW5Bd2FyZW5lc3MsIGRhdGEgPSBkZl90cmFpbikNCg0KVHJhaW5fZW5nYWdlX2JnIDwtIGxtKFdhbnRUcmFpbmluZ19yZWNvZGVkIH4gR2VuZGVyX25ldyArIFJvbGVfbmV3ICsNCiAgICAgICAgICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgICAgICAgICBNZWFuRW5nYWdlbWVudCwgZGF0YSA9IGRmX3RyYWluKQ0KDQpUcmFpbl9BRV9iZyA8LSBsbShXYW50VHJhaW5pbmdfcmVjb2RlZCB+IEdlbmRlcl9uZXcgKyBSb2xlX25ldyArDQogICAgICAgICAgICAgICAgICBNZXRob2RvbG9neV9uZXcgKyBSYW5rX25ldyArIERpc2NpcGxpbmVfbmV3ICsNCiAgICAgICAgICAgICAgICAgIE1lYW5Bd2FyZW5lc3MgKyBNZWFuRW5nYWdlbWVudCwgZGF0YSA9IGRmX3RyYWluKQ0KDQpzdW1tYXJ5KFRyYWluX2F3YXJlX2JnKQ0Kc3VtbWFyeShUcmFpbl9lbmdhZ2VfYmcpDQpzdW1tYXJ5KFRyYWluX0FFX2JnKQ0KDQpgYGANCg0KIyMgNy4gUm9idXN0IHN0YW5kYXJkIGVycm9ycw0KDQpUaGUgTFBNIGFzc3VtZXMgaG9tb3NjZWRhc3RpY2l0eSwgd2hpY2ggaXMgbm90IHN0cmljdGx5IG1ldCB3aXRoIGEgYmluYXJ5IG91dGNvbWUuIFJvYnVzdCAoaGV0ZXJvc2NlZGFzdGljaXR5LWNvbnNpc3RlbnQpIHN0YW5kYXJkIGVycm9ycyBhcmUgcmVwb3J0ZWQgYmVsb3cgZm9yIHRoZSBtYWluIG1vZGVscy4NCg0KYGBge3J9DQpjb2VmdGVzdChUcmFpbl9iYXNlbGluZSwgdmNvdiA9IHZjb3ZIQyhUcmFpbl9iYXNlbGluZSwgdHlwZSA9ICJIQzEiKSkNCmNvZWZ0ZXN0KFRyYWluX0FsbENvbWIsICB2Y292ID0gdmNvdkhDKFRyYWluX0FsbENvbWIsICB0eXBlID0gIkhDMSIpKQ0KY29lZnRlc3QoVHJhaW5fQUVfYmcsICAgIHZjb3YgPSB2Y292SEMoVHJhaW5fQUVfYmcsICAgIHR5cGUgPSAiSEMxIikpDQoNCmBgYA0KDQpgYGB7cn0NCiMgTWVhbnMgYW5kIFNEcw0KYWdncmVnYXRlKGNiaW5kKE1lYW5Bd2FyZW5lc3MsIE1lYW5FbmdhZ2VtZW50KSB+IERpc2NpcGxpbmVfbmV3LCANCiAgICAgICAgICBkYXRhID0gZGZfdHJhaW4sIEZVTiA9IG1lYW4pDQoNCmFnZ3JlZ2F0ZShjYmluZChNZWFuQXdhcmVuZXNzLCBNZWFuRW5nYWdlbWVudCkgfiBEaXNjaXBsaW5lX25ldywgDQogICAgICAgICAgZGF0YSA9IGRmX3RyYWluLCBGVU4gPSBzZCkNCg0KIyBTYW1wbGUgc2l6ZSBwZXIgZGlzY2lwbGluZQ0KdGFibGUoZGZfdHJhaW4kRGlzY2lwbGluZV9uZXcsIHVzZU5BID0gImlmYW55IikNCmBgYA0KDQpgYGB7cn0NCiMgU3Vic2V0OiB0aHJlZSBtYWluIGRpc2NpcGxpbmVzIG9ubHkgKGV4Y2x1ZGUgIk90aGVyIikNCmRmX2Rpc2MgPC0gZGZfdHJhaW5bZGZfdHJhaW4kRGlzY2lwbGluZV9uZXcgJWluJSBjKDAsIDEsIDIpLCBdDQoNCiMgQXdhcmVuZXNzDQpkaXNjX2F3YXJlIDwtIGxtKE1lYW5Bd2FyZW5lc3MgfiBEaXNjaXBsaW5lX25ldywgZGF0YSA9IGRmX2Rpc2MpDQpzdW1tYXJ5KGRpc2NfYXdhcmUpDQphbm92YShkaXNjX2F3YXJlKQ0KDQojIEVuZ2FnZW1lbnQNCmRpc2NfZW5nYWdlIDwtIGxtKE1lYW5FbmdhZ2VtZW50IH4gRGlzY2lwbGluZV9uZXcsIGRhdGEgPSBkZl9kaXNjKQ0Kc3VtbWFyeShkaXNjX2VuZ2FnZSkNCmFub3ZhKGRpc2NfZW5nYWdlKQ0KYGBgDQoNCmBgYHtyfQ0KIyBTdWJzZXQ6IHRocmVlIG1haW4gbWV0aG9kb2xvZ2llcyAoZXhjbHVkZSAiT3RoZXIiKQ0KZGZfbWV0aCA8LSBkZl90cmFpbltkZl90cmFpbiRNZXRob2RvbG9neV9uZXcgJWluJSBjKDAsIDEsIDIpLCBdDQoNCiMgQ29uZmlybSBjb3VudHMNCnRhYmxlKGRmX21ldGgkTWV0aG9kb2xvZ3lfbmV3KQ0KDQojIEF3YXJlbmVzcyBhY3Jvc3MgbWV0aG9kb2xvZ2llcw0KbWV0aF9hd2FyZSA8LSBsbShNZWFuQXdhcmVuZXNzIH4gTWV0aG9kb2xvZ3lfbmV3LCBkYXRhID0gZGZfbWV0aCkNCnN1bW1hcnkobWV0aF9hd2FyZSkNCmFub3ZhKG1ldGhfYXdhcmUpDQoNCiMgRW5nYWdlbWVudCBhY3Jvc3MgbWV0aG9kb2xvZ2llcw0KbWV0aF9lbmdhZ2UgPC0gbG0oTWVhbkVuZ2FnZW1lbnQgfiBNZXRob2RvbG9neV9uZXcsIGRhdGEgPSBkZl9tZXRoKQ0Kc3VtbWFyeShtZXRoX2VuZ2FnZSkNCmFub3ZhKG1ldGhfZW5nYWdlKQ0KYGBgDQoNCmBgYHtyfQ0KIyBSZWNvZGUgc28gUXVhbGl0YXRpdmUgKDEpIGlzIHRoZSByZWZlcmVuY2UNCmRmX21ldGgkTWV0aG9kb2xvZ3lfZmFjdG9yIDwtIGZhY3RvcihkZl9tZXRoJE1ldGhvZG9sb2d5X25ldywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygxLCAwLCAyKSkNCiMgTm93OiAxID0gUXVhbGl0YXRpdmUgKHJlZmVyZW5jZSksIDAgPSBRdWFudGl0YXRpdmUsIDIgPSBNaXhlZA0KDQptZXRoX2VuZ2FnZTIgPC0gbG0oTWVhbkVuZ2FnZW1lbnQgfiBNZXRob2RvbG9neV9mYWN0b3IsIGRhdGEgPSBkZl9tZXRoKQ0Kc3VtbWFyeShtZXRoX2VuZ2FnZTIpDQpgYGANCg0KYGBge3J9DQojIENyZWF0ZSBhIGJpbmFyeSBmbGFnOiByZXNlYXJjaC1hY3RpdmUgdnMgbm90DQpkZl90cmFpbiRSb2xlX2dyb3VwIDwtIGlmZWxzZShkZl90cmFpbiRSb2xlX25ldyA9PSAwLCAiUmVzZWFyY2gvQWNhZGVtaWMiLCAiT3RoZXIgcm9sZXMiKQ0KDQojIERlc2NyaXB0aXZlcyBieSByb2xlIGdyb3VwDQphZ2dyZWdhdGUoY2JpbmQoTWVhbkF3YXJlbmVzcywgTWVhbkVuZ2FnZW1lbnQpIH4gUm9sZV9ncm91cCwgDQogICAgICAgICAgZGF0YSA9IGRmX3RyYWluLCBGVU4gPSBtZWFuKQ0KDQphZ2dyZWdhdGUoY2JpbmQoTWVhbkF3YXJlbmVzcywgTWVhbkVuZ2FnZW1lbnQpIH4gUm9sZV9ncm91cCwgDQogICAgICAgICAgZGF0YSA9IGRmX3RyYWluLCBGVU4gPSBzZCkNCg0KdGFibGUoZGZfdHJhaW4kUm9sZV9ncm91cCwgdXNlTkEgPSAiaWZhbnkiKQ0KYGBgDQoNCmBgYHtyfQ0KIyBFbnN1cmUgUm9sZV9ncm91cCBpcyBhIGZhY3RvciB3aXRoIFJlc2VhcmNoL0FjYWRlbWljIGFzIHRoZSByZWZlcmVuY2UNCmRmX3RyYWluJFJvbGVfZ3JvdXAgPC0gZmFjdG9yKGRmX3RyYWluJFJvbGVfZ3JvdXAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiUmVzZWFyY2gvQWNhZGVtaWMiLCAiT3RoZXIgcm9sZXMiKSkNCg0KIyBBd2FyZW5lc3MNCnJvbGVfYXdhcmUgPC0gbG0oTWVhbkF3YXJlbmVzcyB+IFJvbGVfZ3JvdXAsIGRhdGEgPSBkZl90cmFpbikNCnN1bW1hcnkocm9sZV9hd2FyZSkNCmFub3ZhKHJvbGVfYXdhcmUpDQoNCiMgRW5nYWdlbWVudA0Kcm9sZV9lbmdhZ2UgPC0gbG0oTWVhbkVuZ2FnZW1lbnQgfiBSb2xlX2dyb3VwLCBkYXRhID0gZGZfdHJhaW4pDQpzdW1tYXJ5KHJvbGVfZW5nYWdlKQ0KYW5vdmEocm9sZV9lbmdhZ2UpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoc2NhbGVzKQ0KDQojIENvbXB1dGUgbWVhbnMgYnkgZGlzY2lwbGluZSAodGhyZWUgbWFpbiBkaXNjaXBsaW5lcyBvbmx5KQ0KZGlzY19tZWFucyA8LSBkZl90cmFpbiAlPiUNCiAgZmlsdGVyKERpc2NpcGxpbmVfbmV3ICVpbiUgYygwLCAxLCAyKSkgJT4lDQogIGdyb3VwX2J5KERpc2NpcGxpbmVfbmV3KSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIEF3YXJlbmVzcyAgPSBtZWFuKE1lYW5Bd2FyZW5lc3MsIG5hLnJtID0gVFJVRSksDQogICAgRW5nYWdlbWVudCA9IG1lYW4oTWVhbkVuZ2FnZW1lbnQsIG5hLnJtID0gVFJVRSksDQogICAgTiA9IG4oKQ0KICApICU+JQ0KICBtdXRhdGUoRGlzY2lwbGluZSA9IGZhY3RvcihEaXNjaXBsaW5lX25ldywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoMCwgMSwgMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJTY2llbmNlIiwgIlNvY2lhbCBTY2llbmNlcyIsICJIdW1hbml0aWVzIikpKQ0KDQojIFByaW50IHRvIHZlcmlmeSBudW1iZXJzDQpwcmludChkaXNjX21lYW5zKQ0KDQojIFJlc2hhcGUgdG8gbG9uZyBmb3JtYXQNCmRpc2NfbG9uZyA8LSBkaXNjX21lYW5zICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoQXdhcmVuZXNzLCBFbmdhZ2VtZW50KSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIk91dGNvbWUiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIk1lYW4iKSAlPiUNCiAgbXV0YXRlKE91dGNvbWUgPSBmYWN0b3IoT3V0Y29tZSwgbGV2ZWxzID0gYygiQXdhcmVuZXNzIiwgIkVuZ2FnZW1lbnQiKSkpDQoNCiMgUHVibGljYXRpb24tcmVhZHkgcGxvdA0KZ2dwbG90KGRpc2NfbG9uZywgYWVzKHggPSBEaXNjaXBsaW5lLCB5ID0gTWVhbiwgZmlsbCA9IE91dGNvbWUpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwgd2lkdGggPSAwLjY1LA0KICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjMpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUuMGYlJSIsIE1lYW4gKiAxMDApKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwNCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDMsIGZhbWlseSA9ICJzZXJpZiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiQXdhcmVuZXNzIiA9ICIjQThDNEM0IiwgIkVuZ2FnZW1lbnQiID0gIiM0QTZFOEEiKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxLjA1KSwNCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLCAxLCAwLjIpLA0KICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwNCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9ICJNZWFuICglIG9mIHByYWN0aWNlcykiLCBmaWxsID0gTlVMTCkgKw0KICB0aGVtZV9jbGFzc2ljKGJhc2VfZmFtaWx5ID0gInNlcmlmIiwgYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uICAgPSAidG9wIiwNCiAgICBsZWdlbmQua2V5LnNpemUgICA9IHVuaXQoMC40LCAiY20iKSwNCiAgICBsZWdlbmQudGV4dCAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dCAgICAgICAgID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMCksDQogICAgYXhpcy50aXRsZS55ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBtYXJnaW4gPSBtYXJnaW4ociA9IDgpKSwNCiAgICBheGlzLmxpbmUgICAgICAgICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjQpLA0KICAgIGF4aXMudGlja3MgICAgICAgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuNCksDQogICAgcGxvdC5tYXJnaW4gICAgICAgPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApDQogICkNCg0KIyBTYXZlIGFzIFBORyAoMzAwIERQSSkgYW5kIFBERiAodmVjdG9yKQ0KZ2dzYXZlKCJGaWd1cmVBMl9kaXNjaXBsaW5lLnBuZyIsIHdpZHRoID0gNi41LCBoZWlnaHQgPSA0LjUsIGRwaSA9IDMwMCkNCmdnc2F2ZSgiRmlndXJlQTJfZGlzY2lwbGluZS5wZGYiLCB3aWR0aCA9IDYuNSwgaGVpZ2h0ID0gNC41KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXIpDQoNCiMgQ29tcHV0ZSBDT00tQiBtZWFucyBieSBkaXNjaXBsaW5lICh0aHJlZSBtYWluIGRpc2NpcGxpbmVzIG9ubHkpDQpjb21iX21lYW5zIDwtIGRmX3RyYWluICU+JQ0KICBmaWx0ZXIoRGlzY2lwbGluZV9uZXcgJWluJSBjKDAsIDEsIDIpKSAlPiUNCiAgZ3JvdXBfYnkoRGlzY2lwbGluZV9uZXcpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgUGh5c2ljYWxDYXBhYmlsaXR5ICAgICAgPSBtZWFuKFBoeXNpY2FsQ2FwYWJpbGl0eSwgbmEucm0gPSBUUlVFKSwNCiAgICBQc3ljaG9sb2dpY2FsQ2FwYWJpbGl0eSA9IG1lYW4oUHN5Y2hvbG9naWNhbENhcGFiaWxpdHksIG5hLnJtID0gVFJVRSksDQogICAgUGh5c2ljYWxPcHBvcnR1bml0eSAgICAgPSBtZWFuKFBoeXNpY2FsT3Bwb3J0dW5pdHksIG5hLnJtID0gVFJVRSksDQogICAgU29jaWFsT3Bwb3J0dW5pdHkgICAgICAgPSBtZWFuKFNvY2lhbE9wcG9ydHVuaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIFJlZmxlY3RpdmVNb3RpdmF0aW9uICAgID0gbWVhbihSZWZsZWN0aXZlTW90aXZhdGlvbiwgbmEucm0gPSBUUlVFKSwNCiAgICBBdXRvbWF0aWNNb3RpdmF0aW9uICAgICA9IG1lYW4oQXV0b21hdGljTW90aXZhdGlvbiwgbmEucm0gPSBUUlVFKSwNCiAgICBOID0gbigpDQogICkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gLWMoRGlzY2lwbGluZV9uZXcsIE4pLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiQ09NX0IiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIk1lYW4iKSAlPiUNCiAgbXV0YXRlKA0KICAgIERpc2NpcGxpbmUgPSBmYWN0b3IoRGlzY2lwbGluZV9uZXcsDQogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDAsIDEsIDIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiU2NpZW5jZSIsICJTb2NpYWwgU2NpZW5jZXMiLCAiSHVtYW5pdGllcyIpKSwNCiAgICBDT01fQiA9IGZhY3RvcihDT01fQiwNCiAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJQaHlzaWNhbENhcGFiaWxpdHkiLCAiUHN5Y2hvbG9naWNhbENhcGFiaWxpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBoeXNpY2FsT3Bwb3J0dW5pdHkiLCAiU29jaWFsT3Bwb3J0dW5pdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZmxlY3RpdmVNb3RpdmF0aW9uIiwgIkF1dG9tYXRpY01vdGl2YXRpb24iKSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJQaHlzaWNhbCBDYXBhYmlsaXR5IiwgIlBzeWNob2xvZ2ljYWwgQ2FwYWJpbGl0eSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGh5c2ljYWwgT3Bwb3J0dW5pdHkiLCAiU29jaWFsIE9wcG9ydHVuaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWZsZWN0aXZlIE1vdGl2YXRpb24iLCAiQXV0b21hdGljIE1vdGl2YXRpb24iKSkNCiAgKQ0KDQojIFByaW50IHRvIHZlcmlmeSBudW1iZXJzDQpwcmludChjb21iX21lYW5zICU+JSBzZWxlY3QoRGlzY2lwbGluZSwgQ09NX0IsIE1lYW4pKQ0KDQojIFB1YmxpY2F0aW9uLXJlYWR5IHBsb3QNCmdncGxvdChjb21iX21lYW5zLCBhZXMoeCA9IENPTV9CLCB5ID0gTWVhbiwgZmlsbCA9IERpc2NpcGxpbmUpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwgd2lkdGggPSAwLjY1LA0KICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjMpICsNCg0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJS4yZiIsIE1lYW4pKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMTUsIHNpemUgPSAzLjUsIGZhbWlseSA9ICJzZXJpZiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiU2NpZW5jZSIgICAgICAgICAgPSAiIzRBNkU4QSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTb2NpYWwgU2NpZW5jZXMiICA9ICIjQThDNEM0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkh1bWFuaXRpZXMiICAgICAgID0gIiNEOUUyRTIiKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCA3LjUpLA0KICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsIDcsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLCAwKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gIk1lYW4gc2NvcmUiLCBmaWxsID0gTlVMTCkgKw0KICB0aGVtZV9jbGFzc2ljKGJhc2VfZmFtaWx5ID0gInNlcmlmIiwgYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uICAgPSAidG9wIiwNCiAgICBsZWdlbmQua2V5LnNpemUgICA9IHVuaXQoMC40LCAiY20iKSwNCiAgICBsZWdlbmQudGV4dCAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGV4dCAgICAgICAgID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS54ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBtYXJnaW4gPSBtYXJnaW4odCA9IDgpKSwNCiAgICBheGlzLmxpbmUgICAgICAgICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjQpLA0KICAgIGF4aXMudGlja3MgICAgICAgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuNCksDQogICAgcGxvdC5tYXJnaW4gICAgICAgPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApDQogICkNCg0KIyBTYXZlDQpnZ3NhdmUoIkZpZ3VyZTRfY29tYi5wbmciLCB3aWR0aCA9IDgsIGhlaWdodCA9IDcsIGRwaSA9IDMwMCkNCmdnc2F2ZSgiRmlndXJlNF9jb21iLnBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNykNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShmb3JjYXRzKSAjIEFkZGVkIGZvciBmY3RfcmVvcmRlcg0KDQojIENvbXB1dGUgQ09NLUIgbWVhbnMgYnkgZGlzY2lwbGluZSAodGhyZWUgbWFpbiBkaXNjaXBsaW5lcyBvbmx5KQ0KY29tYl9tZWFucyA8LSBkZl90cmFpbiAlPiUNCiAgZmlsdGVyKERpc2NpcGxpbmVfbmV3ICVpbiUgYygwLCAxLCAyKSkgJT4lDQogIGdyb3VwX2J5KERpc2NpcGxpbmVfbmV3KSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIFBoeXNpY2FsQ2FwYWJpbGl0eSAgICAgID0gbWVhbihQaHlzaWNhbENhcGFiaWxpdHksIG5hLnJtID0gVFJVRSksDQogICAgUHN5Y2hvbG9naWNhbENhcGFiaWxpdHkgPSBtZWFuKFBzeWNob2xvZ2ljYWxDYXBhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIFBoeXNpY2FsT3Bwb3J0dW5pdHkgICAgID0gbWVhbihQaHlzaWNhbE9wcG9ydHVuaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIFNvY2lhbE9wcG9ydHVuaXR5ICAgICAgID0gbWVhbihTb2NpYWxPcHBvcnR1bml0eSwgbmEucm0gPSBUUlVFKSwNCiAgICBSZWZsZWN0aXZlTW90aXZhdGlvbiAgICA9IG1lYW4oUmVmbGVjdGl2ZU1vdGl2YXRpb24sIG5hLnJtID0gVFJVRSksDQogICAgQXV0b21hdGljTW90aXZhdGlvbiAgICAgPSBtZWFuKEF1dG9tYXRpY01vdGl2YXRpb24sIG5hLnJtID0gVFJVRSksDQogICAgTiA9IG4oKQ0KICApICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IC1jKERpc2NpcGxpbmVfbmV3LCBOKSwNCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIkNPTV9CIiwNCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJNZWFuIikgJT4lDQogIG11dGF0ZSgNCiAgICAjIDEuIFNjaWVuY2Ugb24gdG9wOiBSZXZlcnNlIGxldmVscyBzbyBTY2llbmNlIGlzIGxhc3QgKHRvcCBpbiBjb29yZF9mbGlwKQ0KICAgIERpc2NpcGxpbmUgPSBmYWN0b3IoRGlzY2lwbGluZV9uZXcsDQogICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDIsIDEsIDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkh1bWFuaXRpZXMiLCAiU29jaWFsIFNjaWVuY2VzIiwgIlNjaWVuY2UiKSksDQogICAgQ09NX0IgPSBmYWN0b3IoQ09NX0IsDQogICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiUGh5c2ljYWxDYXBhYmlsaXR5IiwgIlBzeWNob2xvZ2ljYWxDYXBhYmlsaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQaHlzaWNhbE9wcG9ydHVuaXR5IiwgIlNvY2lhbE9wcG9ydHVuaXR5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWZsZWN0aXZlTW90aXZhdGlvbiIsICJBdXRvbWF0aWNNb3RpdmF0aW9uIiksDQogICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUGh5c2ljYWwgQ2FwYWJpbGl0eSIsICJQc3ljaG9sb2dpY2FsIENhcGFiaWxpdHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBoeXNpY2FsIE9wcG9ydHVuaXR5IiwgIlNvY2lhbCBPcHBvcnR1bml0eSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVmbGVjdGl2ZSBNb3RpdmF0aW9uIiwgIkF1dG9tYXRpYyBNb3RpdmF0aW9uIikpDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICAjIDIuIEluY3JlYXNpbmcgb3JkZXIgdG9wIHRvIGJvdHRvbTogTGFyZ2VzdCBtZWFuIGdldHMgZmlyc3QgbGV2ZWwgKGJvdHRvbSkNCiAgICBDT01fQiA9IGZjdF9yZW9yZGVyKENPTV9CLCBNZWFuLCAuZnVuID0gbWVhbiwgLmRlc2MgPSBUUlVFKQ0KICApDQoNCiMgUHJpbnQgdG8gdmVyaWZ5IG51bWJlcnMNCnByaW50KGNvbWJfbWVhbnMgJT4lIHNlbGVjdChEaXNjaXBsaW5lLCBDT01fQiwgTWVhbikpDQoNCiMgUHVibGljYXRpb24tcmVhZHkgcGxvdA0KZ2dwbG90KGNvbWJfbWVhbnMsIGFlcyh4ID0gQ09NX0IsIHkgPSBNZWFuLCBmaWxsID0gRGlzY2lwbGluZSkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNzUpLCB3aWR0aCA9IDAuNjUsDQogICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJS4yZiIsIE1lYW4pKSwNCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwNCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMTUsIHNpemUgPSAzLjUsIGZhbWlseSA9ICJzZXJpZiIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiU2NpZW5jZSIgICAgICAgICAgPSAiIzRBNkU4QSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTb2NpYWwgU2NpZW5jZXMiICA9ICIjQThDNEM0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkh1bWFuaXRpZXMiICAgICAgID0gIiNEOUUyRTIiKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCA3LjUpLA0KICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsIDcsIDEpLA0KICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLCAwKSkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gIk1lYW4gc2NvcmUiLCBmaWxsID0gTlVMTCkgKw0KICB0aGVtZV9jbGFzc2ljKGJhc2VfZmFtaWx5ID0gInNlcmlmIiwgYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uICAgPSAidG9wIiwNCiAgICBsZWdlbmQua2V5LnNpemUgICA9IHVuaXQoMC40LCAiY20iKSwNCiAgICBsZWdlbmQudGV4dCAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGV4dCAgICAgICAgID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMiksDQogICAgYXhpcy50aXRsZS54ICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBtYXJnaW4gPSBtYXJnaW4odCA9IDgpKSwNCiAgICBheGlzLmxpbmUgICAgICAgICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjQpLA0KICAgIGF4aXMudGlja3MgICAgICAgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuNCksDQogICAgcGxvdC5tYXJnaW4gICAgICAgPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApDQogICkNCg0KIyBTYXZlDQpnZ3NhdmUoIkZpZ3VyZTRfY29tYi5wbmciLCB3aWR0aCA9IDgsIGhlaWdodCA9IDcsIGRwaSA9IDMwMCkNCmdnc2F2ZSgiRmlndXJlNF9jb21iLnBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNykNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShzY2FsZXMpDQoNCiMgQ29tcHV0ZSBtZWFucyBieSBkaXNjaXBsaW5lICh0aHJlZSBtYWluIGRpc2NpcGxpbmVzIG9ubHkpDQpkaXNjX21lYW5zIDwtIGRmX3RyYWluICU+JQ0KICBmaWx0ZXIoRGlzY2lwbGluZV9uZXcgJWluJSBjKDAsIDEsIDIpKSAlPiUNCiAgZ3JvdXBfYnkoRGlzY2lwbGluZV9uZXcpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgQXdhcmVuZXNzICA9IG1lYW4oTWVhbkF3YXJlbmVzcywgbmEucm0gPSBUUlVFKSwNCiAgICBFbmdhZ2VtZW50ID0gbWVhbihNZWFuRW5nYWdlbWVudCwgbmEucm0gPSBUUlVFKSwNCiAgICBOID0gbigpDQogICkgJT4lDQogIG11dGF0ZShEaXNjaXBsaW5lID0gZmFjdG9yKERpc2NpcGxpbmVfbmV3LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygwLCAxLCAyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlNjaWVuY2UiLCAiU29jaWFsIFNjaWVuY2VzIiwgIkh1bWFuaXRpZXMiKSkpDQoNCiMgUHJpbnQgdG8gdmVyaWZ5IG51bWJlcnMNCnByaW50KGRpc2NfbWVhbnMpDQoNCiMgUmVzaGFwZSB0byBsb25nIGZvcm1hdA0KZGlzY19sb25nIDwtIGRpc2NfbWVhbnMgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhBd2FyZW5lc3MsIEVuZ2FnZW1lbnQpLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiT3V0Y29tZSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiTWVhbiIpICU+JQ0KICBtdXRhdGUoT3V0Y29tZSA9IGZhY3RvcihPdXRjb21lLCBsZXZlbHMgPSBjKCJBd2FyZW5lc3MiLCAiRW5nYWdlbWVudCIpKSkNCg0KIyBQdWJsaWNhdGlvbi1yZWFkeSBwbG90DQpnZ3Bsb3QoZGlzY19sb25nLCBhZXMoeCA9IERpc2NpcGxpbmUsIHkgPSBNZWFuLCBmaWxsID0gT3V0Y29tZSkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNzUpLCB3aWR0aCA9IDAuNjUsDQogICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuMykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJBd2FyZW5lc3MiID0gIiNBOEM0QzQiLCAiRW5nYWdlbWVudCIgPSAiIzRBNkU4QSIpKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEuMDUpLA0KICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsIDEsIDAuMiksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLA0KICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gYygwLCAwKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgZmlsbCA9IE5VTEwpICsgIA0KICB0aGVtZV9jbGFzc2ljKGJhc2VfZmFtaWx5ID0gInNlcmlmIiwgYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgbGVnZW5kLnBvc2l0aW9uICAgPSAidG9wIiwNCiAgICBsZWdlbmQua2V5LnNpemUgICA9IHVuaXQoMC40LCAiY20iKSwNCiAgICBsZWdlbmQudGV4dCAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgIGF4aXMudGV4dCAgICAgICAgID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMCksDQogICAgYXhpcy5saW5lICAgICAgICAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiwgbGluZXdpZHRoID0gMC40KSwNCiAgICBheGlzLnRpY2tzICAgICAgICA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjQpLA0KICAgIHBsb3QubWFyZ2luICAgICAgID0gbWFyZ2luKDEwLCAxMCwgMTAsIDEwKQ0KICApDQoNCiMgU2F2ZSBhcyBQTkcgKDMwMCBEUEkpIGFuZCBQREYgKHZlY3RvcikNCmdnc2F2ZSgiRmlndXJlQTJfZGlzY2lwbGluZS5wbmciLCB3aWR0aCA9IDMuNSwgaGVpZ2h0ID0gNC41LCBkcGkgPSAzMDApDQpnZ3NhdmUoIkZpZ3VyZUEyX2Rpc2NpcGxpbmUucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDQuNSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShzY2FsZXMpDQoNCiMgQ29tcHV0ZSBtZWFucyBieSBtZXRob2RvbG9neQ0KbWV0aF9tZWFucyA8LSBkZl90cmFpbiAlPiUNCiAgZmlsdGVyKE1ldGhvZG9sb2d5X25ldyAlaW4lIGMoMCwgMSwgMikpICU+JQ0KICBncm91cF9ieShNZXRob2RvbG9neV9uZXcpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgQXdhcmVuZXNzICA9IG1lYW4oTWVhbkF3YXJlbmVzcywgbmEucm0gPSBUUlVFKSwNCiAgICBFbmdhZ2VtZW50ID0gbWVhbihNZWFuRW5nYWdlbWVudCwgbmEucm0gPSBUUlVFKSwNCiAgICBOID0gbigpDQogICkgJT4lDQogIG11dGF0ZShNZXRob2RvbG9neSA9IGZhY3RvcihNZXRob2RvbG9neV9uZXcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKDAsIDEsIDIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUXVhbnRpdGF0aXZlIiwgIlF1YWxpdGF0aXZlIiwgIk1peGVkIG1ldGhvZHMiKSkpDQoNCiMgUHJpbnQgdG8gdmVyaWZ5IG51bWJlcnMNCnByaW50KG1ldGhfbWVhbnMpDQoNCiMgUmVzaGFwZSB0byBsb25nIGZvcm1hdA0KbWV0aF9sb25nIDwtIG1ldGhfbWVhbnMgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhBd2FyZW5lc3MsIEVuZ2FnZW1lbnQpLA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiT3V0Y29tZSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiTWVhbiIpICU+JQ0KICBtdXRhdGUoT3V0Y29tZSA9IGZhY3RvcihPdXRjb21lLCBsZXZlbHMgPSBjKCJBd2FyZW5lc3MiLCAiRW5nYWdlbWVudCIpKSkNCg0KIyBQdWJsaWNhdGlvbi1yZWFkeSBwbG90DQpnZ3Bsb3QobWV0aF9sb25nLCBhZXMoeCA9IE1ldGhvZG9sb2d5LCB5ID0gTWVhbiwgZmlsbCA9IE91dGNvbWUpKSArDQogIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjc1KSwgd2lkdGggPSAwLjY1LA0KICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjMpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiQXdhcmVuZXNzIiA9ICIjQThDNEM0IiwgIkVuZ2FnZW1lbnQiID0gIiM0QTZFOEEiKSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxLjA1KSwNCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLCAxLCAwLjIpLA0KICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwNCiAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGMoMCwgMCkpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIGZpbGwgPSBOVUxMKSArICANCiAgdGhlbWVfY2xhc3NpYyhiYXNlX2ZhbWlseSA9ICJzZXJpZiIsIGJhc2Vfc2l6ZSA9IDExKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiAgID0gInRvcCIsDQogICAgbGVnZW5kLmtleS5zaXplICAgPSB1bml0KDAuNCwgImNtIiksDQogICAgbGVnZW5kLnRleHQgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBheGlzLnRleHQueCAgICAgICA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMTApLA0KICAgIGF4aXMudGV4dC55ICAgICAgID0gZWxlbWVudF9ibGFuaygpLCAgIA0KICAgIGF4aXMubGluZSAgICAgICAgID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDAuNCksDQogICAgYXhpcy50aWNrcyAgICAgICAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiwgbGluZXdpZHRoID0gMC40KSwNCiAgICBwbG90Lm1hcmdpbiAgICAgICA9IG1hcmdpbigxMCwgMTAsIDEwLCAxMCkNCiAgKQ0KDQojIFNhdmUgYXMgUE5HICgzMDAgRFBJIGZvciBzdWJtaXNzaW9uKSBhbmQgUERGICh2ZWN0b3IpDQpnZ3NhdmUoIkZpZ3VyZUEyX21ldGhvZG9sb2d5LnBuZyIsIHdpZHRoID0gMy41LCBoZWlnaHQgPSA0LjUsIGRwaSA9IDMwMCkNCmdnc2F2ZSgiRmlndXJlQTJfbWV0aG9kb2xvZ3kucGRmIiwgd2lkdGggPSAzLjUsIGhlaWdodCA9IDQuNSkNCmBgYA0K