Install/Load PackAges
# Load the packages needed for data cleaning, analysis, and visualization
library(tidyverse) # Core data wrangling and plotting tools (dplyr, ggplot2, etc.)
library(janitor) # Helpful tools for cleaning data and summarizing missingness
library(psych) # Descriptive statistics and scale-related functions
library(patchwork) # Combine multiple ggplots into one figure
library(naniar) # Missing data summaries and visualization
library(stringr) # cleaning messy text data
library(forcats) # working with categorical variables
library(purrr) # doing things repeatedly without loops
library(zipcodeR) # turn zip codes into locations
library(maps) # draw the U.S. map
library(Hmisc) # for correlations and significance tests
Load the dataset
# Set working directory
setwd("/Users/maya/Desktop")
# Read the CSV (prevents unwanted factor conversion)
df <- read.csv("MKTG 4450.csv")
head(df)
names(df)
[1] "Start.Date" "EndDate" "Status"
[4] "IPAddress" "Progress" "Duration..in.seconds."
[7] "Finished" "RecordedDate" "ResponseId"
[10] "UserLanguage" "purchase.intention" "brand.attitude_NPS_GROUP"
[13] "brand.attitude" "seller.trust" "fairness_1"
[16] "fairness_2" "quality.perception" "perceived.benefits"
[19] "seller.control" "Attention.check" "Year.of.Birth"
[22] "EDU" "Ethnicity" "Ethnicity1"
[25] "Ethnicity2" "Ethnicity3" "Ethnicity4"
[28] "Ethnicity5" "Ethnicity6" "Ethnicity7"
[31] "Gender" "Income" "Zip.code"
[34] "open.comments" "Condition" "IV1_price_format"
[37] "IV2_Surcharge_type"
# Check variable names (the name of each column in your cleaned excel dataset)
names(df)
[1] "Start.Date" "EndDate" "Status"
[4] "IPAddress" "Progress" "Duration..in.seconds."
[7] "Finished" "RecordedDate" "ResponseId"
[10] "UserLanguage" "purchase.intention" "brand.attitude_NPS_GROUP"
[13] "brand.attitude" "seller.trust" "fairness_1"
[16] "fairness_2" "quality.perception" "perceived.benefits"
[19] "seller.control" "Attention.check" "Year.of.Birth"
[22] "EDU" "Ethnicity" "Ethnicity1"
[25] "Ethnicity2" "Ethnicity3" "Ethnicity4"
[28] "Ethnicity5" "Ethnicity6" "Ethnicity7"
[31] "Gender" "Income" "Zip.code"
[34] "open.comments" "Condition" "IV1_price_format"
[37] "IV2_Surcharge_type"
Check for missing values (nice to better understand the data, not
necessary since we’ve cleaned up the dataset)
# Missing data overview
colSums(is.na(df)) # Count how many missing values for each variable
Start.Date EndDate Status
0 0 0
IPAddress Progress Duration..in.seconds.
0 0 0
Finished RecordedDate ResponseId
0 0 0
UserLanguage purchase.intention brand.attitude_NPS_GROUP
0 0 0
brand.attitude seller.trust fairness_1
0 0 0
fairness_2 quality.perception perceived.benefits
0 0 0
seller.control Attention.check Year.of.Birth
0 0 0
EDU Ethnicity Ethnicity1
0 0 0
Ethnicity2 Ethnicity3 Ethnicity4
0 0 0
Ethnicity5 Ethnicity6 Ethnicity7
0 0 0
Gender Income Zip.code
0 0 0
open.comments Condition IV1_price_format
12 0 0
IV2_Surcharge_type
0
miss_var_summary(df) # A cleaner summary of missing values by variable
Recorde variaboes, if necessary
# fairness_1 and fairness_2 are supposed to measure the same idea,
# but fairness_2 is worded/scaled in the opposite direction.
# fairness_1: 1 = very unfairly, 7 = very fairly; fairness_2: 1 = extremely fairly, 7= extremely unfairly; This is why we need to reverse code fairness_2 to make the scale consistent with fairness_1
df$fairness_2_reverse <- 8 - df$fairness_2
df$fairness <- (df$fairness_1 + df$fairness_2_reverse)/2 # Create a composite fairness score by averaging the two fairness items
# Age: We measured year of birth, and we want to turn it into participants' age for easier interpretation
df$Year.of.Birth <- as.numeric(df$Year.of.Birth) # Convert Year.of.Birth to numeric in case it was imported as text
df$Age <- 2026 - df$Year.of.Birth
Prepare variables
Goal: Make sure your IVs are categorical and DVs are numerical (the
most common type of DVs; for linear regression) or categorical (for chi
square test or logistic regression)
# Make sure IVs are categorical factors. as.factor() tells R that these are categorical variables
df$IV1_price_format <- as.factor(df$IV1_price_format) # Categorical
df$IV2_surcharge_type <- as.factor(df$IV2_surcharge_type) # Categorical
# Make sure (most of the) DVs and covariates are numerical values
#DVs
df$purchase.intention <- as.numeric(df$purchase.intention) # Numeric
df$brand.attitude_NPS_GROUP <- as.factor(df$brand.attitude_NPS_GROUP) # Categorical
df$brand.attitude <- as.numeric(df$brand.attitude) # Numeric
df$seller.trust <- as.numeric(df$seller.trust) # Numeric
df$fairness <- as.numeric(df$fairness) # Numeric
# Covariates
df$quality.perception <- as.numeric(df$quality.perception) # Numeric
df$perceived.benefits <- as.numeric(df$perceived.benefits) # Numeric
df$seller.control <- as.numeric(df$seller.control) # Numeric
df$surcharge.novelty <- as.numeric(df$surcharge.novelty) # Numeric
a) Explore demographics
Goal: To understand who is in our data (their demographics)
# Make sure Age is numeric
df$Age <- as.numeric(df$Age)
# Age: summarize # of valid cases, mean, SD, min, median, and max (na.rm = TRUE: NAs are removed before calculation)
df %>%
summarise(
n_nonmissing = sum(!is.na(Age)),
mean = mean(Age, na.rm = TRUE),
sd = sd(Age, na.rm = TRUE),
min = min(Age, na.rm = TRUE),
median = median(Age, na.rm = TRUE),
max = max(Age, na.rm = TRUE)
)
# Age histogram
ggplot(df, aes(x = Age)) +
geom_histogram(
binwidth = 5, # Each bar covers a 5-year range
fill = "#7A0019", # Bar color
color = "white" # White border around bars
) +
labs(
title = "Age Distribution",
subtitle = "Sample Characteristics",
x = "Age (years)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Gender distribution: frequency table and proportions (since Gender is a categorical variable)
df %>%
count(Gender) %>%
mutate(prop = n / sum(n))
# Bar chart for gender counts
df %>%
count(Gender) %>%
ggplot(aes(x = fct_reorder(Gender, n), y = n)) +
geom_col() +
coord_flip() +
labs(
title = "Gender",
x = NULL,
y = "Count"
) +
theme_minimal()
# Education distribution: counts and proportions
df %>%
count(EDU) %>%
mutate(prop = n / sum(n)) %>%
arrange(desc(n))
# Bar chart for education counts
df %>%
count(EDU) %>%
ggplot(aes(x = fct_reorder(EDU, n), y = n)) +
geom_col() +
coord_flip() +
labs(
title = "Education",
x = NULL,
y = "Count"
) +
theme_minimal()
# Income distribution: counts and percentages
df %>%
count(Income) %>%
mutate(percent = round(100 * n / sum(n), 1))
# Bar chart of income categories
df %>%
count(Income) %>%
ggplot(aes(x = Income, y = n)) +
geom_col() +
coord_flip() +
labs(
title = "Income",
x = NULL,
y = "Count"
) +
theme_minimal()
# Zip code: count how many zip codes are present and the number of unique zip codes
df %>%
summarise(
n_zip_nonmissing = sum(!is.na(Zip.code) & Zip.code != ""),
n_unique_zip = n_distinct(Zip.code[!is.na(Zip.code) & Zip.code != ""])
)
# Show the 15 most common zip codes in the dataset
df %>%
count(Zip.code, sort = TRUE) %>%
filter(!is.na(Zip.code), Zip.code != "") %>%
slice_head(n = 15)
# Plot zip codes
# 1) Clean zip codes
zip_counts <- df %>%
filter(!is.na(Zip.code), Zip.code != "") %>% # Keep only non-missing zip codes
mutate(
Zip.code = str_extract(as.character(Zip.code), "\\d{5}"), # Exact 5-digit zip code
Zip.code = str_pad(Zip.code, width = 5, side = "left", pad = "0") # Add leading zeros if needed
) %>%
filter(!is.na(Zip.code)) %>%
count(Zip.code, sort = TRUE) # Count participants per zip code
# 2) Look up zip metadata (lat/lng) with reverse_zipcode()
zip_lookup <- map_dfr(zip_counts$Zip.code, ~{
out <- tryCatch(
reverse_zipcode(.x),
error = function(e) NULL
)
out
})
# 3) Keep only the columns needed for mapping
zip_lookup <- zip_lookup %>%
select(zipcode, lat, lng, state, major_city)
# 4) Merge counts with coordinates
df_map <- zip_counts %>%
left_join(zip_lookup, by = c("Zip.code" = "zipcode"))
# 5) Optional: check zips that did not match
df_map %>%
filter(is.na(lat) | is.na(lng))
# 6) US base map
us_map <- map_data("state")
# 7) Plot
ggplot() +
geom_polygon(
data = us_map,
aes(x = long, y = lat, group = group),
fill = "gray95",
color = "white",
linewidth = 0.2
) +
geom_point(
data = df_map,
aes(x = lng, y = lat, size = n, color = n),
alpha = 0.75
) +
scale_size(range = c(2, 8)) +
scale_color_viridis_c() +
coord_fixed(1.3) +
labs(
title = "Participant ZIP Codes Across the United States",
x = NULL,
y = NULL,
size = "Count",
color = "Count"
) +
theme_minimal()
b) Distributions of covariates
Goal: To understand who is in our data (their consumption
tendencies)
# Overall descriptives for covariates
covariates <- df %>% # Create a new data frame with only four covariate variables
select(
quality.perception,
perceived.benefits,
seller.control,
surcharge.novelty,
)
# Get descriptive stats for these covariates
describe(covariates)
b) Distributions of covariates (Visualizing the distributions)
Goal: Plot histograms and explore variables individually
# Histogram: quality.perception
p6 <- ggplot(df, aes(x = quality.perception)) + # initiate ggplot using dataset "df" and use quality.perception as the x-axis
geom_histogram(
binwidth = 1, # each bar represents a width of 1 unit (this fits interval/ratio scales)
boundary = 0.5, # make bars centered on integers
fill = "#7A0019", # set bar fill color
color = "white" # set border color of bars
) +
geom_vline( # add a vertical line
xintercept = mean(df$quality.perception, na.rm = TRUE), # position line at the mean
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Quality Perception", # add labels and titles
subtitle = "Dashed line = Mean",
x = "PQuality Perception (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) + # apply a clean minimal theme with base front size 14
theme(
plot.title = element_text(hjust = 0.5, face = "bold"), # center and bold the title
plot.subtitle = element_text(hjust = 0.5), # center the subtitle
panel.grid.major.x = element_blank(), # remove vertical major grid lines
panel.grid.minor = element_blank() # remove all minor grid lines
)
# Histogram: perceived benefits
p7 <- ggplot(df, aes(x = perceived.benefits)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$perceived.benefits, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Perceived Benefits",
subtitle = "Dashed line = Mean",
x = "Perceived benefits (1–5 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Histogram: seller control
p8 <- ggplot(df, aes(x = seller.control)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$seller.control, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Seller Control",
subtitle = "Dashed line = Mean",
x = "Seller Control (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Histogram: surcharge novelty
p9 <- ggplot(df, aes(x = surcharge.novelty)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$surcharge.novelty, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Surcharge Novelty",
subtitle = "Dashed line = Mean",
x = "Surcharge Novelty (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
p6 + p7 + p8 + p9 # Option#1: Combine the four plots into one figure
p6 # Option#2: Plot the four plots on separate pages
p7
p7
p9
Overall descriptive stats
Goal: Check if the randomization is successful (the number of
participants should be largely the same across conditions)
# Count number of participants in each 2 x 2 experimental cell
df %>%
count(IV1_price_format, IV2_surcharge_type)
Variable distributions
# Overall descriptives for DVs
DVs <- df %>%
select(
purchase.intention,
brand.attitude,
seller.trust,
fairness
)
describe(DVs)
Distributions of DVs (Visualizing the distributions)
Goal: Plot histograms and explore variables individually
# Histogram: purchase intention
p1 <- ggplot(df, aes(x = purchase.intention)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$purchase.intention, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Purchase Intention",
subtitle = "Dashed line = Mean",
x = "Purchase Intention (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Histogram: brand attitude
p2 <- ggplot(df, aes(x = brand.attitude)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$brand.attitude, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Brand Attitude",
subtitle = "Dashed line = Mean",
x = "Brand Attitude (1–10 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Bar chart, brand attitude (NPS)
p3 <- ggplot(df, aes(x = brand.attitude_NPS_GROUP)) +
geom_bar(fill = "#7A0019") +
labs(
title = "Distribution of NPS Groups",
x = "NPS Group",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Histogram: seller trust
p4 <- ggplot(df, aes(x = seller.trust)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$seller.trust, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Seller Trust",
subtitle = "Dashed line = Mean",
x = "Seller trust (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
# Histogram: fairness
p5 <- ggplot(df, aes(x = fairness)) +
geom_histogram(
binwidth = 1,
boundary = 0.5,
fill = "#7A0019",
color = "white"
) +
geom_vline(
xintercept = mean(df$fairness, na.rm = TRUE),
linetype = "dashed",
linewidth = 1
) +
labs(
title = "Distribution of Fairness",
subtitle = "Dashed line = Mean",
x = "Fairness (1–7 scale)",
y = "Number of Participants"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank()
)
p1
p2
p3
p4
p5
Scatterplots for relationships among DVs
Goal: Visually assess many variable relationships at once
# Plot 1: brand attitude by purchase intention
ggplot(df, aes(x = brand.attitude, y = purchase.intention)) + # aes(...) = aesthetics (tell RStudio what goes on axes). Here we are plotting brand attitude on the x-axis and purchase intention on the y-axis
geom_smooth(method = "lm", se = TRUE) + # We are using a linear regression model ("lm") to draw a best-fitting line between brand attitude and purchase intention
geom_jitter(width = 0.2, height = 0.2) + # this function helps us plot each participant as a dot
theme_minimal() + # Make the plot cleaner and easier to read
labs(title = "Brand Attitude and Purchase Intention",
x = "Brand Attitude", y = "Purchase Intention") # Add labels to the figure, x-axis, and y-axis
# Plot 2: seller trust by purchase intention
ggplot(df, aes(x = seller.trust, y = purchase.intention)) +
geom_smooth(method = "lm", se = TRUE) +
geom_jitter(width = 0.2, height = 0.2) +
theme_minimal() +
labs(title = "Seller Trust and Purchase Intention",
x = "Seller Trust", y = "Purchase Intention")
# Plot 3: fairness by purchase intention
ggplot(df, aes(x = fairness, y = purchase.intention)) +
geom_smooth(method = "lm", se = TRUE) +
geom_jitter(width = 0.2, height = 0.2) +
theme_minimal() +
labs(title = "Fairness and Purchase Intention",
x = "Perceived Fairness", y = "Purchase Intention")
# Plot 4: seller trust by brand attitude
ggplot(df, aes(x = seller.trust, y = brand.attitude)) +
geom_smooth(method = "lm", se = TRUE) +
geom_jitter(width = 0.2, height = 0.2) +
theme_minimal() +
labs(title = "Seller Trust and Brand Attitude",
x = "Seller Trust", y = "Brand Attitude")
# Plot 5: fairness by brand attitude
ggplot(df, aes(x = fairness, y = brand.attitude)) +
geom_smooth(method = "lm", se = TRUE) +
geom_jitter(width = 0.2, height = 0.2) +
theme_minimal() +
labs(title = "Fairness and Brand Attitude",
x = "Perceived Fairness", y = "Brand Attitude")
# Plot 6: fairness by seller trust
ggplot(df, aes(x = fairness, y = seller.trust)) +
geom_smooth(method = "lm", se = TRUE) +
geom_jitter(width = 0.2, height = 0.2) +
theme_minimal() +
labs(title = "Fairness and Seller Trust",
x = "Perceived Fairness", y = "Seller Trust")
Correlation matrix
# Select the variables to include in the correlation matrix
corr_vars <- df%>%
select(
purchase.intention,
brand.attitude,
seller.trust,
fairness,
quality.perception,
perceived.benefits,
seller.control,
surcharge.novelty
)
# Compute correlations and p-values
cor_results <- rcorr(as.matrix(corr_vars))
# Correlation matrix
cor_matrix <- cor_results$r
# P-value matrix
p_matrix <- cor_results$P
# View correlation matrix
round(cor_matrix, 2)
# Convert correlation matrix to long format
cor_df <- as.data.frame(cor_matrix) %>%
rownames_to_column("var1") %>%
pivot_longer(-var1, names_to = "var2", values_to = "correlation")
# Convert p-value matrix to long format
p_df <- as.data.frame(p_matrix) %>%
rownames_to_column("var1") %>%
pivot_longer(-var1, names_to = "var2", values_to = "p_value")
# Merge correlations and p-values
cor_df <- cor_df %>%
left_join(p_df, by = c("var1", "var2")) %>%
mutate(
sig = case_when(
p_value < .001 ~ "***",
p_value < .01 ~ "**",
p_value < .05 ~ "*",
TRUE ~ ""
)
)
# Plot the correlation matrix
ggplot(cor_df, aes(x = var1, y = var2)) +
geom_point(aes(size = abs(correlation), color = correlation)) +
geom_text(aes(label = paste0(round(correlation, 2), sig)), size = 3) +
scale_size(range = c(2, 8)) +
scale_color_gradient2(
low = "#B2182B",
mid = "white",
high = "#2166AC",
midpoint = 0
) +
coord_equal() +
labs(
title = "Correlation Matrix (with Significance)",
x = "",
y = "",
color = "Correlation",
size = "|r|"
) +
theme_minimal(base_size = 14) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid = element_blank(),
plot.title = element_text(hjust = 0.5, face = "bold")
)
# Your R code here
summary(cars)
plot(cars)
LS0tCnRpdGxlOiAiUHJpY2luZyBwcm9qZWN0IGRlbW87IGRhdGEgZXhwbG9yYXRpb247IFNwcmluZyAyMDI2IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBJbnN0YWxsL0xvYWQgUGFja0FnZXMKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgpgYGB7cn0KCiMgTG9hZCB0aGUgcGFja2FnZXMgbmVlZGVkIGZvciBkYXRhIGNsZWFuaW5nLCBhbmFseXNpcywgYW5kIHZpc3VhbGl6YXRpb24KbGlicmFyeSh0aWR5dmVyc2UpICMgQ29yZSBkYXRhIHdyYW5nbGluZyBhbmQgcGxvdHRpbmcgdG9vbHMgKGRwbHlyLCBnZ3Bsb3QyLCBldGMuKQpsaWJyYXJ5KGphbml0b3IpICMgSGVscGZ1bCB0b29scyBmb3IgY2xlYW5pbmcgZGF0YSBhbmQgc3VtbWFyaXppbmcgbWlzc2luZ25lc3MKbGlicmFyeShwc3ljaCkgIyBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFuZCBzY2FsZS1yZWxhdGVkIGZ1bmN0aW9ucwpsaWJyYXJ5KHBhdGNod29yaykgIyBDb21iaW5lIG11bHRpcGxlIGdncGxvdHMgaW50byBvbmUgZmlndXJlCmxpYnJhcnkobmFuaWFyKSAgIyBNaXNzaW5nIGRhdGEgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uCgpsaWJyYXJ5KHN0cmluZ3IpICMgY2xlYW5pbmcgbWVzc3kgdGV4dCBkYXRhCmxpYnJhcnkoZm9yY2F0cykgIyB3b3JraW5nIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzCgpsaWJyYXJ5KHB1cnJyKSAjIGRvaW5nIHRoaW5ncyByZXBlYXRlZGx5IHdpdGhvdXQgbG9vcHMKbGlicmFyeSh6aXBjb2RlUikgIyB0dXJuIHppcCBjb2RlcyBpbnRvIGxvY2F0aW9ucwpsaWJyYXJ5KG1hcHMpICMgZHJhdyB0aGUgVS5TLiBtYXAKCmxpYnJhcnkoSG1pc2MpICMgZm9yIGNvcnJlbGF0aW9ucyBhbmQgc2lnbmlmaWNhbmNlIHRlc3RzCmBgYAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgTG9hZCB0aGUgZGF0YXNldAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCmBgYHtyfQojIFNldCB3b3JraW5nIGRpcmVjdG9yeQpzZXR3ZCgiL1VzZXJzL21heWEvRGVza3RvcCIpCgojIFJlYWQgdGhlIENTViAocHJldmVudHMgdW53YW50ZWQgZmFjdG9yIGNvbnZlcnNpb24pCmRmIDwtIHJlYWQuY3N2KCJNS1RHIDQ0NTAuY3N2IikKaGVhZChkZikKbmFtZXMoZGYpCmBgYAoKYGBge3J9CiMgQ2hlY2sgdmFyaWFibGUgbmFtZXMgKHRoZSBuYW1lIG9mIGVhY2ggY29sdW1uIGluIHlvdXIgY2xlYW5lZCBleGNlbCBkYXRhc2V0KQpuYW1lcyhkZikKYGBgCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBQcmVwYXJlIHRoZSBkYXRhCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBDaGVjayBmb3IgbWlzc2luZyB2YWx1ZXMgKG5pY2UgdG8gYmV0dGVyIHVuZGVyc3RhbmQgdGhlIGRhdGEsIG5vdCBuZWNlc3Nhcnkgc2luY2Ugd2UndmUgY2xlYW5lZCB1cCB0aGUgZGF0YXNldCkKCmBgYHtyfQojIE1pc3NpbmcgZGF0YSBvdmVydmlldwpjb2xTdW1zKGlzLm5hKGRmKSkgIyBDb3VudCBob3cgbWFueSBtaXNzaW5nIHZhbHVlcyBmb3IgZWFjaCB2YXJpYWJsZQptaXNzX3Zhcl9zdW1tYXJ5KGRmKSAjIEEgY2xlYW5lciBzdW1tYXJ5IG9mIG1pc3NpbmcgdmFsdWVzIGJ5IHZhcmlhYmxlCmBgYAoKIyBSZWNvcmRlIHZhcmlhYm9lcywgaWYgbmVjZXNzYXJ5CgpgYGB7cn0KIyBmYWlybmVzc18xIGFuZCBmYWlybmVzc18yIGFyZSBzdXBwb3NlZCB0byBtZWFzdXJlIHRoZSBzYW1lIGlkZWEsCiMgYnV0IGZhaXJuZXNzXzIgaXMgd29yZGVkL3NjYWxlZCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uLgojIGZhaXJuZXNzXzE6IDEgPSB2ZXJ5IHVuZmFpcmx5LCA3ID0gdmVyeSBmYWlybHk7IGZhaXJuZXNzXzI6IDEgPSBleHRyZW1lbHkgZmFpcmx5LCA3PSBleHRyZW1lbHkgdW5mYWlybHk7IFRoaXMgaXMgd2h5IHdlIG5lZWQgdG8gcmV2ZXJzZSBjb2RlIGZhaXJuZXNzXzIgdG8gbWFrZSB0aGUgc2NhbGUgY29uc2lzdGVudCB3aXRoIGZhaXJuZXNzXzEKZGYkZmFpcm5lc3NfMl9yZXZlcnNlIDwtIDggLSBkZiRmYWlybmVzc18yCmRmJGZhaXJuZXNzIDwtIChkZiRmYWlybmVzc18xICsgZGYkZmFpcm5lc3NfMl9yZXZlcnNlKS8yICMgQ3JlYXRlIGEgY29tcG9zaXRlIGZhaXJuZXNzIHNjb3JlIGJ5IGF2ZXJhZ2luZyB0aGUgdHdvIGZhaXJuZXNzIGl0ZW1zCgojIEFnZTogV2UgbWVhc3VyZWQgeWVhciBvZiBiaXJ0aCwgYW5kIHdlIHdhbnQgdG8gdHVybiBpdCBpbnRvIHBhcnRpY2lwYW50cycgYWdlIGZvciBlYXNpZXIgaW50ZXJwcmV0YXRpb24KZGYkWWVhci5vZi5CaXJ0aCA8LSBhcy5udW1lcmljKGRmJFllYXIub2YuQmlydGgpICMgQ29udmVydCBZZWFyLm9mLkJpcnRoIHRvIG51bWVyaWMgaW4gY2FzZSBpdCB3YXMgaW1wb3J0ZWQgYXMgdGV4dApkZiRBZ2UgPC0gMjAyNiAtIGRmJFllYXIub2YuQmlydGgKYGBgCgojIFByZXBhcmUgdmFyaWFibGVzCgojIEdvYWw6IE1ha2Ugc3VyZSB5b3VyIElWcyBhcmUgY2F0ZWdvcmljYWwgYW5kIERWcyBhcmUgbnVtZXJpY2FsICh0aGUgbW9zdCBjb21tb24gdHlwZSBvZiBEVnM7IGZvciBsaW5lYXIgcmVncmVzc2lvbikgb3IgY2F0ZWdvcmljYWwgKGZvciBjaGkgc3F1YXJlIHRlc3Qgb3IgbG9naXN0aWMgcmVncmVzc2lvbikKCmBgYHtyfQojIE1ha2Ugc3VyZSBJVnMgYXJlIGNhdGVnb3JpY2FsIGZhY3RvcnMuIGFzLmZhY3RvcigpIHRlbGxzIFIgdGhhdCB0aGVzZSBhcmUgY2F0ZWdvcmljYWwgdmFyaWFibGVzCmRmJElWMV9wcmljZV9mb3JtYXQgPC0gYXMuZmFjdG9yKGRmJElWMV9wcmljZV9mb3JtYXQpICMgQ2F0ZWdvcmljYWwKZGYkSVYyX3N1cmNoYXJnZV90eXBlIDwtIGFzLmZhY3RvcihkZiRJVjJfc3VyY2hhcmdlX3R5cGUpICMgQ2F0ZWdvcmljYWwKYGBgCgpgYGB7cn0KIyBNYWtlIHN1cmUgKG1vc3Qgb2YgdGhlKSBEVnMgYW5kIGNvdmFyaWF0ZXMgYXJlIG51bWVyaWNhbCB2YWx1ZXMKI0RWcwpkZiRwdXJjaGFzZS5pbnRlbnRpb24gPC0gYXMubnVtZXJpYyhkZiRwdXJjaGFzZS5pbnRlbnRpb24pICMgTnVtZXJpYwpkZiRicmFuZC5hdHRpdHVkZV9OUFNfR1JPVVAgPC0gYXMuZmFjdG9yKGRmJGJyYW5kLmF0dGl0dWRlX05QU19HUk9VUCkgIyBDYXRlZ29yaWNhbApkZiRicmFuZC5hdHRpdHVkZSA8LSBhcy5udW1lcmljKGRmJGJyYW5kLmF0dGl0dWRlKSAjIE51bWVyaWMKZGYkc2VsbGVyLnRydXN0IDwtIGFzLm51bWVyaWMoZGYkc2VsbGVyLnRydXN0KSAjIE51bWVyaWMKZGYkZmFpcm5lc3MgPC0gYXMubnVtZXJpYyhkZiRmYWlybmVzcykgIyBOdW1lcmljCgojIENvdmFyaWF0ZXMKZGYkcXVhbGl0eS5wZXJjZXB0aW9uIDwtIGFzLm51bWVyaWMoZGYkcXVhbGl0eS5wZXJjZXB0aW9uKSAjIE51bWVyaWMKZGYkcGVyY2VpdmVkLmJlbmVmaXRzIDwtIGFzLm51bWVyaWMoZGYkcGVyY2VpdmVkLmJlbmVmaXRzKSAjIE51bWVyaWMKZGYkc2VsbGVyLmNvbnRyb2wgPC0gYXMubnVtZXJpYyhkZiRzZWxsZXIuY29udHJvbCkgIyBOdW1lcmljCmRmJHN1cmNoYXJnZS5ub3ZlbHR5IDwtIGFzLm51bWVyaWMoZGYkc3VyY2hhcmdlLm5vdmVsdHkpICMgTnVtZXJpYwpgYGAKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIEFzc2VzcyB0aGUgc2FtcGxlCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBhKSBFeHBsb3JlIGRlbW9ncmFwaGljcwoKIyBHb2FsOiBUbyB1bmRlcnN0YW5kIHdobyBpcyBpbiBvdXIgZGF0YSAodGhlaXIgZGVtb2dyYXBoaWNzKQoKYGBge3J9CiMgTWFrZSBzdXJlIEFnZSBpcyBudW1lcmljCmRmJEFnZSA8LSBhcy5udW1lcmljKGRmJEFnZSkKCiMgQWdlOiBzdW1tYXJpemUgIyBvZiB2YWxpZCBjYXNlcywgbWVhbiwgU0QsIG1pbiwgbWVkaWFuLCBhbmQgbWF4IChuYS5ybSA9IFRSVUU6IE5BcyBhcmUgcmVtb3ZlZCBiZWZvcmUgY2FsY3VsYXRpb24pCmRmICU+JQogIHN1bW1hcmlzZSgKICAgIG5fbm9ubWlzc2luZyA9IHN1bSghaXMubmEoQWdlKSksCiAgICBtZWFuID0gbWVhbihBZ2UsIG5hLnJtID0gVFJVRSksCiAgICBzZCA9IHNkKEFnZSwgbmEucm0gPSBUUlVFKSwKICAgIG1pbiA9IG1pbihBZ2UsIG5hLnJtID0gVFJVRSksCiAgICBtZWRpYW4gPSBtZWRpYW4oQWdlLCBuYS5ybSA9IFRSVUUpLAogICAgbWF4ID0gbWF4KEFnZSwgbmEucm0gPSBUUlVFKQogICkKCiMgQWdlIGhpc3RvZ3JhbQpnZ3Bsb3QoZGYsIGFlcyh4ID0gQWdlKSkgKwogIGdlb21faGlzdG9ncmFtKAogICAgYmlud2lkdGggPSA1LCAgICAgICAjIEVhY2ggYmFyIGNvdmVycyBhIDUteWVhciByYW5nZQogICAgZmlsbCA9ICIjN0EwMDE5IiwgICAjIEJhciBjb2xvcgogICAgY29sb3IgPSAid2hpdGUiICAgICMgV2hpdGUgYm9yZGVyIGFyb3VuZCBiYXJzCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkFnZSBEaXN0cmlidXRpb24iLAogICAgc3VidGl0bGUgPSAiU2FtcGxlIENoYXJhY3RlcmlzdGljcyIsCiAgICB4ID0gIkFnZSAoeWVhcnMpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKYGBgCgpgYGB7cn0KIyBHZW5kZXIgZGlzdHJpYnV0aW9uOiBmcmVxdWVuY3kgdGFibGUgYW5kIHByb3BvcnRpb25zIChzaW5jZSBHZW5kZXIgaXMgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSkKZGYgJT4lCiAgY291bnQoR2VuZGVyKSAlPiUKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obikpCgojIEJhciBjaGFydCBmb3IgZ2VuZGVyIGNvdW50cwpkZiAlPiUKICBjb3VudChHZW5kZXIpICU+JQogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKEdlbmRlciwgbiksIHkgPSBuKSkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkdlbmRlciIsCiAgICB4ID0gTlVMTCwKICAgIHkgPSAiQ291bnQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKYGBge3J9CiMgRWR1Y2F0aW9uIGRpc3RyaWJ1dGlvbjogY291bnRzIGFuZCBwcm9wb3J0aW9ucwpkZiAlPiUKICBjb3VudChFRFUpICU+JQogIG11dGF0ZShwcm9wID0gbiAvIHN1bShuKSkgJT4lCiAgYXJyYW5nZShkZXNjKG4pKQoKIyBCYXIgY2hhcnQgZm9yIGVkdWNhdGlvbiBjb3VudHMKZGYgJT4lCiAgY291bnQoRURVKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmY3RfcmVvcmRlcihFRFUsIG4pLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBjb29yZF9mbGlwKCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJFZHVjYXRpb24iLAogICAgeCA9IE5VTEwsCiAgICB5ID0gIkNvdW50IgogICkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCmBgYHtyfQojIEluY29tZSBkaXN0cmlidXRpb246IGNvdW50cyBhbmQgcGVyY2VudGFnZXMKZGYgJT4lCiAgY291bnQoSW5jb21lKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IHJvdW5kKDEwMCAqIG4gLyBzdW0obiksIDEpKQoKIyBCYXIgY2hhcnQgb2YgaW5jb21lIGNhdGVnb3JpZXMKZGYgJT4lCiAgY291bnQoSW5jb21lKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBJbmNvbWUsIHkgPSBuKSkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkluY29tZSIsCiAgICB4ID0gTlVMTCwKICAgIHkgPSAiQ291bnQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKYGBge3J9CiMgWmlwIGNvZGU6IGNvdW50IGhvdyBtYW55IHppcCBjb2RlcyBhcmUgcHJlc2VudCBhbmQgdGhlIG51bWJlciBvZiB1bmlxdWUgemlwIGNvZGVzIApkZiAlPiUKICBzdW1tYXJpc2UoCiAgICBuX3ppcF9ub25taXNzaW5nID0gc3VtKCFpcy5uYShaaXAuY29kZSkgJiBaaXAuY29kZSAhPSAiIiksCiAgICBuX3VuaXF1ZV96aXAgPSBuX2Rpc3RpbmN0KFppcC5jb2RlWyFpcy5uYShaaXAuY29kZSkgJiBaaXAuY29kZSAhPSAiIl0pCiAgKQoKIyBTaG93IHRoZSAxNSBtb3N0IGNvbW1vbiB6aXAgY29kZXMgaW4gdGhlIGRhdGFzZXQKZGYgJT4lCiAgY291bnQoWmlwLmNvZGUsIHNvcnQgPSBUUlVFKSAlPiUKICBmaWx0ZXIoIWlzLm5hKFppcC5jb2RlKSwgWmlwLmNvZGUgIT0gIiIpICU+JQogIHNsaWNlX2hlYWQobiA9IDE1KQpgYGAKCmBgYHtyfQojIFBsb3QgemlwIGNvZGVzCiMgMSkgQ2xlYW4gemlwIGNvZGVzCnppcF9jb3VudHMgPC0gZGYgJT4lCiAgZmlsdGVyKCFpcy5uYShaaXAuY29kZSksIFppcC5jb2RlICE9ICIiKSAlPiUgICAjIEtlZXAgb25seSBub24tbWlzc2luZyB6aXAgY29kZXMKICBtdXRhdGUoCiAgICBaaXAuY29kZSA9IHN0cl9leHRyYWN0KGFzLmNoYXJhY3RlcihaaXAuY29kZSksICJcXGR7NX0iKSwgICMgRXhhY3QgNS1kaWdpdCB6aXAgY29kZQogICAgWmlwLmNvZGUgPSBzdHJfcGFkKFppcC5jb2RlLCB3aWR0aCA9IDUsIHNpZGUgPSAibGVmdCIsIHBhZCA9ICIwIikgIyBBZGQgbGVhZGluZyB6ZXJvcyBpZiBuZWVkZWQKICApICU+JSAKICBmaWx0ZXIoIWlzLm5hKFppcC5jb2RlKSkgJT4lCiAgY291bnQoWmlwLmNvZGUsIHNvcnQgPSBUUlVFKSAjIENvdW50IHBhcnRpY2lwYW50cyBwZXIgemlwIGNvZGUKCiMgMikgTG9vayB1cCB6aXAgbWV0YWRhdGEgKGxhdC9sbmcpIHdpdGggcmV2ZXJzZV96aXBjb2RlKCkKemlwX2xvb2t1cCA8LSBtYXBfZGZyKHppcF9jb3VudHMkWmlwLmNvZGUsIH57CiAgb3V0IDwtIHRyeUNhdGNoKAogICAgcmV2ZXJzZV96aXBjb2RlKC54KSwKICAgIGVycm9yID0gZnVuY3Rpb24oZSkgTlVMTAogICkKICBvdXQKfSkKCiMgMykgS2VlcCBvbmx5IHRoZSBjb2x1bW5zIG5lZWRlZCBmb3IgbWFwcGluZwp6aXBfbG9va3VwIDwtIHppcF9sb29rdXAgJT4lCiAgc2VsZWN0KHppcGNvZGUsIGxhdCwgbG5nLCBzdGF0ZSwgbWFqb3JfY2l0eSkKCiMgNCkgTWVyZ2UgY291bnRzIHdpdGggY29vcmRpbmF0ZXMKZGZfbWFwIDwtIHppcF9jb3VudHMgJT4lCiAgbGVmdF9qb2luKHppcF9sb29rdXAsIGJ5ID0gYygiWmlwLmNvZGUiID0gInppcGNvZGUiKSkKCiMgNSkgT3B0aW9uYWw6IGNoZWNrIHppcHMgdGhhdCBkaWQgbm90IG1hdGNoCmRmX21hcCAlPiUKICBmaWx0ZXIoaXMubmEobGF0KSB8IGlzLm5hKGxuZykpCgojIDYpIFVTIGJhc2UgbWFwCnVzX21hcCA8LSBtYXBfZGF0YSgic3RhdGUiKQoKIyA3KSBQbG90CmdncGxvdCgpICsKICBnZW9tX3BvbHlnb24oCiAgICBkYXRhID0gdXNfbWFwLAogICAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwKICAgIGZpbGwgPSAiZ3JheTk1IiwKICAgIGNvbG9yID0gIndoaXRlIiwKICAgIGxpbmV3aWR0aCA9IDAuMgogICkgKwogIGdlb21fcG9pbnQoCiAgICBkYXRhID0gZGZfbWFwLAogICAgYWVzKHggPSBsbmcsIHkgPSBsYXQsIHNpemUgPSBuLCBjb2xvciA9IG4pLAogICAgYWxwaGEgPSAwLjc1CiAgKSArCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwgOCkpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKSArCiAgY29vcmRfZml4ZWQoMS4zKSArCiAgbGFicygKICAgIHRpdGxlID0gIlBhcnRpY2lwYW50IFpJUCBDb2RlcyBBY3Jvc3MgdGhlIFVuaXRlZCBTdGF0ZXMiLAogICAgeCA9IE5VTEwsCiAgICB5ID0gTlVMTCwKICAgIHNpemUgPSAiQ291bnQiLAogICAgY29sb3IgPSAiQ291bnQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyBiKSBEaXN0cmlidXRpb25zIG9mIGNvdmFyaWF0ZXMKCiMgR29hbDogVG8gdW5kZXJzdGFuZCB3aG8gaXMgaW4gb3VyIGRhdGEgKHRoZWlyIGNvbnN1bXB0aW9uIHRlbmRlbmNpZXMpCgpgYGB7cn0KIyBPdmVyYWxsIGRlc2NyaXB0aXZlcyBmb3IgY292YXJpYXRlcwpjb3ZhcmlhdGVzIDwtIGRmICU+JSAjIENyZWF0ZSBhIG5ldyBkYXRhIGZyYW1lIHdpdGggb25seSBmb3VyIGNvdmFyaWF0ZSB2YXJpYWJsZXMKICBzZWxlY3QoCiAgICBxdWFsaXR5LnBlcmNlcHRpb24sCiAgICBwZXJjZWl2ZWQuYmVuZWZpdHMsCiAgICBzZWxsZXIuY29udHJvbCwKICAgIHN1cmNoYXJnZS5ub3ZlbHR5LAogICkKCiMgR2V0IGRlc2NyaXB0aXZlIHN0YXRzIGZvciB0aGVzZSBjb3ZhcmlhdGVzCmRlc2NyaWJlKGNvdmFyaWF0ZXMpCmBgYAoKIyBiKSBEaXN0cmlidXRpb25zIG9mIGNvdmFyaWF0ZXMgKFZpc3VhbGl6aW5nIHRoZSBkaXN0cmlidXRpb25zKQoKIyBHb2FsOiBQbG90IGhpc3RvZ3JhbXMgYW5kIGV4cGxvcmUgdmFyaWFibGVzIGluZGl2aWR1YWxseQoKYGBge3J9CiMgSGlzdG9ncmFtOiBxdWFsaXR5LnBlcmNlcHRpb24KcDYgPC0gZ2dwbG90KGRmLCBhZXMoeCA9IHF1YWxpdHkucGVyY2VwdGlvbikpICsgIyBpbml0aWF0ZSBnZ3Bsb3QgdXNpbmcgZGF0YXNldCAiZGYiIGFuZCB1c2UgcXVhbGl0eS5wZXJjZXB0aW9uIGFzIHRoZSB4LWF4aXMKICBnZW9tX2hpc3RvZ3JhbSgKICAgIGJpbndpZHRoID0gMSwgICAgIyBlYWNoIGJhciByZXByZXNlbnRzIGEgd2lkdGggb2YgMSB1bml0ICh0aGlzIGZpdHMgaW50ZXJ2YWwvcmF0aW8gc2NhbGVzKQogICAgYm91bmRhcnkgPSAwLjUsICAjIG1ha2UgYmFycyBjZW50ZXJlZCBvbiBpbnRlZ2VycwogICAgZmlsbCA9ICIjN0EwMDE5IiwgIyBzZXQgYmFyIGZpbGwgY29sb3IKICAgIGNvbG9yID0gIndoaXRlIiAgICMgc2V0IGJvcmRlciBjb2xvciBvZiBiYXJzCiAgKSArCiAgZ2VvbV92bGluZSggICMgYWRkIGEgdmVydGljYWwgbGluZQogICAgeGludGVyY2VwdCA9IG1lYW4oZGYkcXVhbGl0eS5wZXJjZXB0aW9uLCBuYS5ybSA9IFRSVUUpLCAjIHBvc2l0aW9uIGxpbmUgYXQgdGhlIG1lYW4KICAgIGxpbmV0eXBlID0gImRhc2hlZCIsCiAgICBsaW5ld2lkdGggPSAxCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBRdWFsaXR5IFBlcmNlcHRpb24iLCAjIGFkZCBsYWJlbHMgYW5kIHRpdGxlcwogICAgc3VidGl0bGUgPSAiRGFzaGVkIGxpbmUgPSBNZWFuIiwKICAgIHggPSAiUFF1YWxpdHkgUGVyY2VwdGlvbiAoMeKAkzcgc2NhbGUpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArICMgYXBwbHkgYSBjbGVhbiBtaW5pbWFsIHRoZW1lIHdpdGggYmFzZSBmcm9udCBzaXplIDE0CiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwgIyBjZW50ZXIgYW5kIGJvbGQgdGhlIHRpdGxlCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgIyBjZW50ZXIgdGhlIHN1YnRpdGxlCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksICMgcmVtb3ZlIHZlcnRpY2FsIG1ham9yIGdyaWQgbGluZXMKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkgIyByZW1vdmUgYWxsIG1pbm9yIGdyaWQgbGluZXMKICApCgojIEhpc3RvZ3JhbTogcGVyY2VpdmVkIGJlbmVmaXRzCnA3IDwtIGdncGxvdChkZiwgYWVzKHggPSBwZXJjZWl2ZWQuYmVuZWZpdHMpKSArCiAgZ2VvbV9oaXN0b2dyYW0oCiAgICBiaW53aWR0aCA9IDEsIAogICAgYm91bmRhcnkgPSAwLjUsCiAgICBmaWxsID0gIiM3QTAwMTkiLAogICAgY29sb3IgPSAid2hpdGUiCiAgKSArCiAgZ2VvbV92bGluZSgKICAgIHhpbnRlcmNlcHQgPSBtZWFuKGRmJHBlcmNlaXZlZC5iZW5lZml0cywgbmEucm0gPSBUUlVFKSwKICAgIGxpbmV0eXBlID0gImRhc2hlZCIsCiAgICBsaW5ld2lkdGggPSAxCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBQZXJjZWl2ZWQgQmVuZWZpdHMiLAogICAgc3VidGl0bGUgPSAiRGFzaGVkIGxpbmUgPSBNZWFuIiwKICAgIHggPSAiUGVyY2VpdmVkIGJlbmVmaXRzICgx4oCTNSBzY2FsZSkiLAogICAgeSA9ICJOdW1iZXIgb2YgUGFydGljaXBhbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTQpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLAogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpCiAgKQoKIyBIaXN0b2dyYW06IHNlbGxlciBjb250cm9sCnA4IDwtIGdncGxvdChkZiwgYWVzKHggPSBzZWxsZXIuY29udHJvbCkpICsKICBnZW9tX2hpc3RvZ3JhbSgKICAgIGJpbndpZHRoID0gMSwgCiAgICBib3VuZGFyeSA9IDAuNSwKICAgIGZpbGwgPSAiIzdBMDAxOSIsCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICBnZW9tX3ZsaW5lKAogICAgeGludGVyY2VwdCA9IG1lYW4oZGYkc2VsbGVyLmNvbnRyb2wsIG5hLnJtID0gVFJVRSksCiAgICBsaW5ldHlwZSA9ICJkYXNoZWQiLAogICAgbGluZXdpZHRoID0gMQogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgU2VsbGVyIENvbnRyb2wiLAogICAgc3VidGl0bGUgPSAiRGFzaGVkIGxpbmUgPSBNZWFuIiwKICAgIHggPSAiU2VsbGVyIENvbnRyb2wgKDHigJM3IHNjYWxlKSIsCiAgICB5ID0gIk51bWJlciBvZiBQYXJ0aWNpcGFudHMiCiAgKSArCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxNCkgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkKICApCgojIEhpc3RvZ3JhbTogc3VyY2hhcmdlIG5vdmVsdHkKcDkgPC0gZ2dwbG90KGRmLCBhZXMoeCA9IHN1cmNoYXJnZS5ub3ZlbHR5KSkgKwogIGdlb21faGlzdG9ncmFtKAogICAgYmlud2lkdGggPSAxLCAKICAgIGJvdW5kYXJ5ID0gMC41LAogICAgZmlsbCA9ICIjN0EwMDE5IiwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGdlb21fdmxpbmUoCiAgICB4aW50ZXJjZXB0ID0gbWVhbihkZiRzdXJjaGFyZ2Uubm92ZWx0eSwgbmEucm0gPSBUUlVFKSwKICAgIGxpbmV0eXBlID0gImRhc2hlZCIsCiAgICBsaW5ld2lkdGggPSAxCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBTdXJjaGFyZ2UgTm92ZWx0eSIsCiAgICBzdWJ0aXRsZSA9ICJEYXNoZWQgbGluZSA9IE1lYW4iLAogICAgeCA9ICJTdXJjaGFyZ2UgTm92ZWx0eSAoMeKAkzcgc2NhbGUpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKCnA2ICsgcDcgKyBwOCArIHA5ICMgT3B0aW9uIzE6IENvbWJpbmUgdGhlIGZvdXIgcGxvdHMgaW50byBvbmUgZmlndXJlCnA2ICMgT3B0aW9uIzI6IFBsb3QgdGhlIGZvdXIgcGxvdHMgb24gc2VwYXJhdGUgcGFnZXMKcDcKcDcKcDkKYGBgCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBBc3Nlc3MgcmFuZG9taXphdGlvbgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgT3ZlcmFsbCBkZXNjcmlwdGl2ZSBzdGF0cwoKIyBHb2FsOiBDaGVjayBpZiB0aGUgcmFuZG9taXphdGlvbiBpcyBzdWNjZXNzZnVsICh0aGUgbnVtYmVyIG9mIHBhcnRpY2lwYW50cyBzaG91bGQgYmUgbGFyZ2VseSB0aGUgc2FtZSBhY3Jvc3MgY29uZGl0aW9ucykKCmBgYHtyfQojIENvdW50IG51bWJlciBvZiBwYXJ0aWNpcGFudHMgaW4gZWFjaCAyIHggMiBleHBlcmltZW50YWwgY2VsbApkZiAlPiUKICBjb3VudChJVjFfcHJpY2VfZm9ybWF0LCBJVjJfc3VyY2hhcmdlX3R5cGUpCmBgYAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgVmFyaWFibGUgZGlzdHJpYnV0aW9ucwoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCmBgYHtyfQojIE92ZXJhbGwgZGVzY3JpcHRpdmVzIGZvciBEVnMKRFZzIDwtIGRmICU+JQogIHNlbGVjdCgKICAgIHB1cmNoYXNlLmludGVudGlvbiwKICAgIGJyYW5kLmF0dGl0dWRlLAogICAgc2VsbGVyLnRydXN0LAogICAgZmFpcm5lc3MKICApCgpkZXNjcmliZShEVnMpCmBgYAoKIyBEaXN0cmlidXRpb25zIG9mIERWcyAoVmlzdWFsaXppbmcgdGhlIGRpc3RyaWJ1dGlvbnMpCgojIEdvYWw6IFBsb3QgaGlzdG9ncmFtcyBhbmQgZXhwbG9yZSB2YXJpYWJsZXMgaW5kaXZpZHVhbGx5CgpgYGB7cn0KIyBIaXN0b2dyYW06IHB1cmNoYXNlIGludGVudGlvbgpwMSA8LSBnZ3Bsb3QoZGYsIGFlcyh4ID0gcHVyY2hhc2UuaW50ZW50aW9uKSkgKwogIGdlb21faGlzdG9ncmFtKAogICAgYmlud2lkdGggPSAxLCAKICAgIGJvdW5kYXJ5ID0gMC41LAogICAgZmlsbCA9ICIjN0EwMDE5IiwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGdlb21fdmxpbmUoCiAgICB4aW50ZXJjZXB0ID0gbWVhbihkZiRwdXJjaGFzZS5pbnRlbnRpb24sIG5hLnJtID0gVFJVRSksCiAgICBsaW5ldHlwZSA9ICJkYXNoZWQiLAogICAgbGluZXdpZHRoID0gMQogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgUHVyY2hhc2UgSW50ZW50aW9uIiwKICAgIHN1YnRpdGxlID0gIkRhc2hlZCBsaW5lID0gTWVhbiIsCiAgICB4ID0gIlB1cmNoYXNlIEludGVudGlvbiAoMeKAkzcgc2NhbGUpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKCiMgSGlzdG9ncmFtOiBicmFuZCBhdHRpdHVkZQpwMiA8LSBnZ3Bsb3QoZGYsIGFlcyh4ID0gYnJhbmQuYXR0aXR1ZGUpKSArCiAgZ2VvbV9oaXN0b2dyYW0oCiAgICBiaW53aWR0aCA9IDEsIAogICAgYm91bmRhcnkgPSAwLjUsCiAgICBmaWxsID0gIiM3QTAwMTkiLAogICAgY29sb3IgPSAid2hpdGUiCiAgKSArCiAgZ2VvbV92bGluZSgKICAgIHhpbnRlcmNlcHQgPSBtZWFuKGRmJGJyYW5kLmF0dGl0dWRlLCBuYS5ybSA9IFRSVUUpLAogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwKICAgIGxpbmV3aWR0aCA9IDEKICApICsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEJyYW5kIEF0dGl0dWRlIiwKICAgIHN1YnRpdGxlID0gIkRhc2hlZCBsaW5lID0gTWVhbiIsCiAgICB4ID0gIkJyYW5kIEF0dGl0dWRlICgx4oCTMTAgc2NhbGUpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKCiMgQmFyIGNoYXJ0LCBicmFuZCBhdHRpdHVkZSAoTlBTKQpwMyA8LSBnZ3Bsb3QoZGYsIGFlcyh4ID0gYnJhbmQuYXR0aXR1ZGVfTlBTX0dST1VQKSkgKwogIGdlb21fYmFyKGZpbGwgPSAiIzdBMDAxOSIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIE5QUyBHcm91cHMiLAogICAgeCA9ICJOUFMgR3JvdXAiLAogICAgeSA9ICJOdW1iZXIgb2YgUGFydGljaXBhbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTQpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKCiMgSGlzdG9ncmFtOiBzZWxsZXIgdHJ1c3QKcDQgPC0gZ2dwbG90KGRmLCBhZXMoeCA9IHNlbGxlci50cnVzdCkpICsKICBnZW9tX2hpc3RvZ3JhbSgKICAgIGJpbndpZHRoID0gMSwgCiAgICBib3VuZGFyeSA9IDAuNSwKICAgIGZpbGwgPSAiIzdBMDAxOSIsCiAgICBjb2xvciA9ICJ3aGl0ZSIKICApICsKICBnZW9tX3ZsaW5lKAogICAgeGludGVyY2VwdCA9IG1lYW4oZGYkc2VsbGVyLnRydXN0LCBuYS5ybSA9IFRSVUUpLAogICAgbGluZXR5cGUgPSAiZGFzaGVkIiwKICAgIGxpbmV3aWR0aCA9IDEKICApICsKICBsYWJzKAogICAgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFNlbGxlciBUcnVzdCIsCiAgICBzdWJ0aXRsZSA9ICJEYXNoZWQgbGluZSA9IE1lYW4iLAogICAgeCA9ICJTZWxsZXIgdHJ1c3QgKDHigJM3IHNjYWxlKSIsCiAgICB5ID0gIk51bWJlciBvZiBQYXJ0aWNpcGFudHMiCiAgKSArCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxNCkgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIiksCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkKICApCgojIEhpc3RvZ3JhbTogZmFpcm5lc3MKcDUgPC0gZ2dwbG90KGRmLCBhZXMoeCA9IGZhaXJuZXNzKSkgKwogIGdlb21faGlzdG9ncmFtKAogICAgYmlud2lkdGggPSAxLCAKICAgIGJvdW5kYXJ5ID0gMC41LAogICAgZmlsbCA9ICIjN0EwMDE5IiwKICAgIGNvbG9yID0gIndoaXRlIgogICkgKwogIGdlb21fdmxpbmUoCiAgICB4aW50ZXJjZXB0ID0gbWVhbihkZiRmYWlybmVzcywgbmEucm0gPSBUUlVFKSwKICAgIGxpbmV0eXBlID0gImRhc2hlZCIsCiAgICBsaW5ld2lkdGggPSAxCiAgKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBGYWlybmVzcyIsCiAgICBzdWJ0aXRsZSA9ICJEYXNoZWQgbGluZSA9IE1lYW4iLAogICAgeCA9ICJGYWlybmVzcyAoMeKAkzcgc2NhbGUpIiwKICAgIHkgPSAiTnVtYmVyIG9mIFBhcnRpY2lwYW50cyIKICApICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwKICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKQogICkKCnAxIApwMiAKcDMgCnA0IApwNQpgYGAKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIFZhcmlhYmxlIHJlbGF0aW9uc2hpcHMKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIFNjYXR0ZXJwbG90cyBmb3IgcmVsYXRpb25zaGlwcyBhbW9uZyBEVnMKCiMgR29hbDogVmlzdWFsbHkgYXNzZXNzIG1hbnkgdmFyaWFibGUgcmVsYXRpb25zaGlwcyBhdCBvbmNlCgpgYGB7cn0KIyBQbG90IDE6IGJyYW5kIGF0dGl0dWRlIGJ5IHB1cmNoYXNlIGludGVudGlvbgpnZ3Bsb3QoZGYsIGFlcyh4ID0gYnJhbmQuYXR0aXR1ZGUsIHkgPSBwdXJjaGFzZS5pbnRlbnRpb24pKSArICMgYWVzKC4uLikgPSBhZXN0aGV0aWNzICh0ZWxsIFJTdHVkaW8gd2hhdCBnb2VzIG9uIGF4ZXMpLiBIZXJlIHdlIGFyZSBwbG90dGluZyBicmFuZCBhdHRpdHVkZSBvbiB0aGUgeC1heGlzIGFuZCBwdXJjaGFzZSBpbnRlbnRpb24gb24gdGhlIHktYXhpcwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSkgKyAjIFdlIGFyZSB1c2luZyBhIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsICgibG0iKSB0byBkcmF3IGEgYmVzdC1maXR0aW5nIGxpbmUgYmV0d2VlbiBicmFuZCBhdHRpdHVkZSBhbmQgcHVyY2hhc2UgaW50ZW50aW9uIAogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBoZWlnaHQgPSAwLjIpICsgIyB0aGlzIGZ1bmN0aW9uIGhlbHBzIHVzIHBsb3QgZWFjaCBwYXJ0aWNpcGFudCBhcyBhIGRvdAogIHRoZW1lX21pbmltYWwoKSArICMgTWFrZSB0aGUgcGxvdCBjbGVhbmVyIGFuZCBlYXNpZXIgdG8gcmVhZAogIGxhYnModGl0bGUgPSAiQnJhbmQgQXR0aXR1ZGUgYW5kIFB1cmNoYXNlIEludGVudGlvbiIsIAogICAgICAgeCA9ICJCcmFuZCBBdHRpdHVkZSIsIHkgPSAiUHVyY2hhc2UgSW50ZW50aW9uIikgIyBBZGQgbGFiZWxzIHRvIHRoZSBmaWd1cmUsIHgtYXhpcywgYW5kIHktYXhpcwoKIyBQbG90IDI6IHNlbGxlciB0cnVzdCBieSBwdXJjaGFzZSBpbnRlbnRpb24KZ2dwbG90KGRmLCBhZXMoeCA9IHNlbGxlci50cnVzdCwgeSA9IHB1cmNoYXNlLmludGVudGlvbikpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMiwgaGVpZ2h0ID0gMC4yKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIlNlbGxlciBUcnVzdCBhbmQgUHVyY2hhc2UgSW50ZW50aW9uIiwKICAgICAgIHggPSAiU2VsbGVyIFRydXN0IiwgeSA9ICJQdXJjaGFzZSBJbnRlbnRpb24iKQoKIyBQbG90IDM6IGZhaXJuZXNzIGJ5IHB1cmNoYXNlIGludGVudGlvbgpnZ3Bsb3QoZGYsIGFlcyh4ID0gZmFpcm5lc3MsIHkgPSBwdXJjaGFzZS5pbnRlbnRpb24pKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGhlaWdodCA9IDAuMikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJGYWlybmVzcyBhbmQgUHVyY2hhc2UgSW50ZW50aW9uIiwKICAgICAgIHggPSAiUGVyY2VpdmVkIEZhaXJuZXNzIiwgeSA9ICJQdXJjaGFzZSBJbnRlbnRpb24iKQoKIyBQbG90IDQ6IHNlbGxlciB0cnVzdCBieSBicmFuZCBhdHRpdHVkZQpnZ3Bsb3QoZGYsIGFlcyh4ID0gc2VsbGVyLnRydXN0LCB5ID0gYnJhbmQuYXR0aXR1ZGUpKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGhlaWdodCA9IDAuMikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJTZWxsZXIgVHJ1c3QgYW5kIEJyYW5kIEF0dGl0dWRlIiwKICAgICAgIHggPSAiU2VsbGVyIFRydXN0IiwgeSA9ICJCcmFuZCBBdHRpdHVkZSIpCgojIFBsb3QgNTogZmFpcm5lc3MgYnkgYnJhbmQgYXR0aXR1ZGUKZ2dwbG90KGRmLCBhZXMoeCA9IGZhaXJuZXNzLCB5ID0gYnJhbmQuYXR0aXR1ZGUpKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGhlaWdodCA9IDAuMikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJGYWlybmVzcyBhbmQgQnJhbmQgQXR0aXR1ZGUiLAogICAgICAgeCA9ICJQZXJjZWl2ZWQgRmFpcm5lc3MiLCB5ID0gIkJyYW5kIEF0dGl0dWRlIikKCiMgUGxvdCA2OiBmYWlybmVzcyBieSBzZWxsZXIgdHJ1c3QKZ2dwbG90KGRmLCBhZXMoeCA9IGZhaXJuZXNzLCB5ID0gc2VsbGVyLnRydXN0KSkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBoZWlnaHQgPSAwLjIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnModGl0bGUgPSAiRmFpcm5lc3MgYW5kIFNlbGxlciBUcnVzdCIsCiAgICAgICB4ID0gIlBlcmNlaXZlZCBGYWlybmVzcyIsIHkgPSAiU2VsbGVyIFRydXN0IikKYGBgCgojIENvcnJlbGF0aW9uIG1hdHJpeAoKYGBge3J9CiMgU2VsZWN0IHRoZSB2YXJpYWJsZXMgdG8gaW5jbHVkZSBpbiB0aGUgY29ycmVsYXRpb24gbWF0cml4CmNvcnJfdmFycyA8LSBkZiU+JQogIHNlbGVjdCgKICAgIHB1cmNoYXNlLmludGVudGlvbiwKICAgIGJyYW5kLmF0dGl0dWRlLAogICAgc2VsbGVyLnRydXN0LAogICAgZmFpcm5lc3MsCiAgICBxdWFsaXR5LnBlcmNlcHRpb24sCiAgICBwZXJjZWl2ZWQuYmVuZWZpdHMsCiAgICBzZWxsZXIuY29udHJvbCwKICAgIHN1cmNoYXJnZS5ub3ZlbHR5CiAgKQoKIyBDb21wdXRlIGNvcnJlbGF0aW9ucyBhbmQgcC12YWx1ZXMKY29yX3Jlc3VsdHMgPC0gcmNvcnIoYXMubWF0cml4KGNvcnJfdmFycykpCgojIENvcnJlbGF0aW9uIG1hdHJpeApjb3JfbWF0cml4IDwtIGNvcl9yZXN1bHRzJHIKCiMgUC12YWx1ZSBtYXRyaXgKcF9tYXRyaXggPC0gY29yX3Jlc3VsdHMkUAoKIyBWaWV3IGNvcnJlbGF0aW9uIG1hdHJpeApyb3VuZChjb3JfbWF0cml4LCAyKQpgYGAKCmBgYHtyfQojIENvbnZlcnQgY29ycmVsYXRpb24gbWF0cml4IHRvIGxvbmcgZm9ybWF0CmNvcl9kZiA8LSBhcy5kYXRhLmZyYW1lKGNvcl9tYXRyaXgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigidmFyMSIpICU+JQogIHBpdm90X2xvbmdlcigtdmFyMSwgbmFtZXNfdG8gPSAidmFyMiIsIHZhbHVlc190byA9ICJjb3JyZWxhdGlvbiIpCgojIENvbnZlcnQgcC12YWx1ZSBtYXRyaXggdG8gbG9uZyBmb3JtYXQKcF9kZiA8LSBhcy5kYXRhLmZyYW1lKHBfbWF0cml4KSAlPiUKICByb3duYW1lc190b19jb2x1bW4oInZhcjEiKSAlPiUKICBwaXZvdF9sb25nZXIoLXZhcjEsIG5hbWVzX3RvID0gInZhcjIiLCB2YWx1ZXNfdG8gPSAicF92YWx1ZSIpCgojIE1lcmdlIGNvcnJlbGF0aW9ucyBhbmQgcC12YWx1ZXMKY29yX2RmIDwtIGNvcl9kZiAlPiUKICBsZWZ0X2pvaW4ocF9kZiwgYnkgPSBjKCJ2YXIxIiwgInZhcjIiKSkgJT4lCiAgbXV0YXRlKAogICAgc2lnID0gY2FzZV93aGVuKAogICAgICBwX3ZhbHVlIDwgLjAwMSB+ICIqKioiLAogICAgICBwX3ZhbHVlIDwgLjAxICB+ICIqKiIsCiAgICAgIHBfdmFsdWUgPCAuMDUgIH4gIioiLAogICAgICBUUlVFIH4gIiIKICAgICkKICApCgojIFBsb3QgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeApnZ3Bsb3QoY29yX2RmLCBhZXMoeCA9IHZhcjEsIHkgPSB2YXIyKSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBhYnMoY29ycmVsYXRpb24pLCBjb2xvciA9IGNvcnJlbGF0aW9uKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocm91bmQoY29ycmVsYXRpb24sIDIpLCBzaWcpKSwgc2l6ZSA9IDMpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygyLCA4KSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50MigKICAgIGxvdyA9ICIjQjIxODJCIiwKICAgIG1pZCA9ICJ3aGl0ZSIsCiAgICBoaWdoID0gIiMyMTY2QUMiLAogICAgbWlkcG9pbnQgPSAwCiAgKSArCiAgY29vcmRfZXF1YWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIkNvcnJlbGF0aW9uIE1hdHJpeCAod2l0aCBTaWduaWZpY2FuY2UpIiwKICAgIHggPSAiIiwKICAgIHkgPSAiIiwKICAgIGNvbG9yID0gIkNvcnJlbGF0aW9uIiwKICAgIHNpemUgPSAifHJ8IgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTQpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikKICApCmBgYAoKYGBge3J9CiMgWW91ciBSIGNvZGUgaGVyZQpzdW1tYXJ5KGNhcnMpCnBsb3QoY2FycykKYGBgCg==