Final Project Code for IS310
Group 2
Group Members: Linda Schnabel, Eric Hibbs, Daphne Giffin, Amy
Zhang
# Spatial Data Mapping
##install.packages(c("ggplot2", "sf"))
library(ggplot2)
library(sf)
# Specify the path to the shapefile folder (without file extension)
shapefile_folder <- "PittHoods"
# Read the shapefile using st_read
shapefile_sf <- st_read(dsn = shapefile_folder)
Reading layer `Neighborhoods_' from data source `/Users/amyzhang/Downloads/amyFile/ISHW/IS310_final/PittHoods' using driver `ESRI Shapefile'
Simple feature collection with 90 features and 39 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -80.09533 ymin: 40.36152 xmax: -79.86585 ymax: 40.50104
Geodetic CRS: WGS 84
#print(shapefile_sf)
# Plot w ggplot2
ggplot() +
geom_sf(data = shapefile_sf) +
theme_minimal()

ZOOM IN ON HILL DISTRICT
# ZOOM IN ON HILL DISTRICT
library(ggplot2)
library(sf)
# Specify the path to the shapefile folder (without file extension)
Pitt_sf_folder <- "PittHoods"
# Read the shapefile using st_read
shapefile_sf <- st_read(dsn = shapefile_folder)
Reading layer `Neighborhoods_' from data source `/Users/amyzhang/Downloads/amyFile/ISHW/IS310_final/PittHoods' using driver `ESRI Shapefile'
Simple feature collection with 90 features and 39 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -80.09533 ymin: 40.36152 xmax: -79.86585 ymax: 40.50104
Geodetic CRS: WGS 84
#print(shapefile_sf)
hoods_of_interest <- c("Crawford-Roberts", "Upper Hill", "Middle Hill", "Bedford Dwellings","Terrace Village")
# Filter the shapefile to include the hoods that make up Hill Dist.
subset_sf <- shapefile_sf[shapefile_sf$hood %in% hoods_of_interest, ]
# Display using ggplot2
ggplot() +
geom_sf(data = subset_sf) +
theme_minimal()

First, filtered data to Hill District census tracts
df<- read.csv("food_access_research_atlas.csv")
##library("lpsolve")
library("dplyr")
library("plotly")
head(df)
##filtering out data by Pennsylvania
penndata <-filter(df,State == "Pennsylvania")
##filter out by Allegheny
alleghenydata <- filter(df, County == "Allegheny")
## allegheny data
head(alleghenydata)
##scatter plot of reality, x= lapop1(low access pop at 1 mile or more), y = share
##actualx <- data$lapop1
##actualy <-data$lapop1share
## ideal scatterplot x = lapop1 when 500 or 33% of pop, y = share 33%
hilldata <- filter(alleghenydata, CensusTract == 42003030500)
for (row in 1:nrow(alleghenydata)){
if(alleghenydata[row,"CensusTract"] == 42003050100)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003050600)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003050900)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003051000)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003051100)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
}
#42003050100 ||42003050900 |42003051000 | 42003051100
#42003030500, 42003050100,42003050600,42003050900,42003051000,42003051100)
head(hilldata)
#as of 2010 the area comprises Census Tracts 305 (Crawford Roberts, "Lower Hill"), 501 (Crawford-Roberts, "Middle Hill"), 506 (Upper Hill), 509 (Bedford Dwellings), 510 and 511 (Terrace Village)
##function for finding ideal
## first you take an actual share, than you subtract 33 from it to see by how much its over, lapop1share - 33%
## calculate how much that would be in people,
##then subtract that amount from lapop1 to know how many people there are at <33%
idealxvalues <- c()
thresholdcalculator <- function(xvalues){
for (row in 1:nrow(hilldata)){
x <- hilldata[row,"POP2010"] *.33
if(x < 500){
x <- hilldata[row,"POP2010"] *.33}
else {x <- 500}
xvalues<- c(xvalues,x)}
return(xvalues)
}
thresholdx <- thresholdcalculator(idealxvalues)
for(element in thresholdx)
{
print(element)
}
[1] 500
[1] 500
[1] 500
[1] 396.66
[1] 500
[1] 370.26
##ROWS 396 and 400 have 0 population, pero they arent hill so no problem
#vector to store shares
thresholdpopshare <- c()
thresholdsharecalc <- function(xthreshshare,xvals)
{
for (row in 1:nrow(hilldata))
{
i<- 1
x <- xvals[i]/hilldata[row,"POP2010"]
xthreshshare <- c(xthreshshare,x)
i<- i + 1
}
return(xthreshshare)
}
thresholdpop <- thresholdcalculator(idealxvalues)
thresholdpopshare <- thresholdsharecalc(thresholdpopshare,thresholdpop)
lapophalf <- hilldata$lapophalf
lapophalfshare <- hilldata$lapophalfshare
for(element in thresholdpopshare)
{
print(element)
}
[1] 0.2216312
[1] 0.2929115
[1] 0.2430724
[1] 0.4159734
[1] 0.2374169
[1] 0.4456328
head(hilldata)
#PLOTLY EXAMPLE
#CHANGE CENSUS TRACTS TO STRINGS Y WE ARE SET
ctnames <- c()
for(element in hilldata$CensusTract)
{
ctnames <- c(ctnames,toString(element))
}
lapopdata <- data.frame(ctnames,lapophalf,thresholdpop)
popbargraph <- plot_ly(lapopdata, x = ~ctnames, y = ~lapophalf, type = 'bar', name = 'low access at half mile')
popbargraph <- popbargraph %>% add_trace(y = ~thresholdpop, name = 'threshold pop')
popbargraph <- popbargraph %>% layout(yaxis = list(title = 'population'), barmode = 'group')
popbargraph
#poverty rate
twenties <- c(20,20,20,20,20,20)
poppovertyrate <- hilldata$PovertyRate
povertyrates <- data.frame(ctnames,poppovertyrate,twenties)
povertybargraph <- plot_ly(povertyrates, x = ~ctnames, y = ~poppovertyrate, type = 'bar', name = 'census poverty rate')
povertybargraph <- povertybargraph %>% add_trace(y = ~twenties, name = 'threshold for low income tract')
povertybargraph <- povertybargraph %>% layout(yaxis = list(title = 'population'), barmode = 'group')
povertybargraph
#TEAM REFERENCE
library("dplyr")
##filtering out data by Pennsylvania
filter(df,State == "Pennsylvania")
##filter out by Allegheny
alleghenydata <- filter(df, County == "Allegheny")
hilldata <- filter(alleghenydata, CensusTract == 42003030500)
for (row in 1:nrow(alleghenydata)){
if(alleghenydata[row,"CensusTract"] == 42003050100)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003050600)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003050900)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003051000)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
else if(alleghenydata[row,"CensusTract"] == 42003051100)
{
hilldata <- rbind(hilldata, alleghenydata[row,])
}
}
head(hilldata)
FIND STANDARDIZED FOOD INSECURITY SCORES FOR 2019
# FIND STANDARDIZED FOOD INSECURITY SCORES FOR 2019
FARA_2019 <- read.csv("food_access_research_atlas.csv")
# Filter down to Hill District census tracts for 2019
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2019 <- FARA_2019[FARA_2019$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns <- scale(HD_FARA2019[, columns])
# Create overall score as the sum of standardized values
HD_FARA2019$overall_FI_score <- rowSums(standardized_columns)
# Create a new dataframe with lapophalf and lalowihalf columns and their and overall scores for each tract
results_2019_df <- data.frame(
CensusTract = HD_FARA2019$CensusTract,
lapophalf = HD_FARA2019$lapophalf,
lalowihalf = HD_FARA2019$lalowihalf,
overall_FI_score = HD_FARA2019$overall_FI_score
)
# Print the resulting dataframe
print(results_2019_df)
#import to latex
library(xtable)
table_latex <- xtable(results_2019_df, caption = "Food Insecurity Scores for 2019 in Hill District", label = "tab:food_insecurity_2019_hd")
print.xtable(table_latex, type = "latex", file = "METHODStable_2019_hd.tex")
FIND STANDARDIZED FOOD INSECURITY SCORES FOR 2010
# FIND STANDARDIZED FOOD INSECURITY SCORES FOR 2010
FARA_2010 <- read.csv("FoodAccessResearchAtlasData2010.csv")
# Filter down to Hill District census tracts for 2019
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2010 <- FARA_2010[FARA_2010$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns <- scale(HD_FARA2010[, columns])
# Create overall score as the sum of standardized values
HD_FARA2010$overall_score <- rowSums(standardized_columns)
# Create a new dataframe with relevant columns and overall score
result_df <- data.frame(
CensusTract = HD_FARA2010$CensusTract,
lapophalf = HD_FARA2010$lapophalf,
lalowihalf = HD_FARA2010$lalowihalf,
overall_score = HD_FARA2010$overall_score
)
# Print the resulting dataframe
print(result_df)
#import to latex
library(xtable)
table_latex <- xtable(result_df, caption = "Food Insecurity Scores for 2010 in Hill District", label = "tab:food_insecurity_2010_hd")
print.xtable(table_latex, type = "latex", file = "methodstable2010.tex")
quick visualization for 2010
# Let's make a quick visualization for 2010
FARA_2010 <- read.csv("FoodAccessResearchAtlasData2010.csv")
# Filter down to Hill District census tracts for 2010
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2010 <- FARA_2010[FARA_2010$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns <- scale(HD_FARA2010[, columns])
# Create overall Food Access score as the sum of standardized values
HD_FARA2010$overall_score <- rowSums(standardized_columns)
# Create a scatter plot with ggplot2
library(ggplot2)
ggplot(HD_FARA2010, aes(x = lapophalf, y = lalowihalf, color = overall_score)) +
geom_point() +
scale_color_gradient(low = "blue", high = "red") +
labs(title = "Food Accessibility in 2010 - Hill District Census Tracts",
x = "Population Beyond 1/2 Mile from Supermarket",
y = "Low-Income Population Beyond 1/2 Mile from Supermarket",
color = "Overall Score") +
theme_minimal()

#2010 bar graph of normalized change
# Load required libraries
library(ggplot2)
# Filter down to Hill District census tracts for 2010
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2010 <- FARA_2010[FARA_2010$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns_2010 <- scale(HD_FARA2010[, columns])
# Create overall Food Access score as the sum of standardized values
HD_FARA2010$overall_score <- rowSums(standardized_columns_2010)
# Normalize the overall score
normalized_score_2010 <- (HD_FARA2010$overall_score - min(HD_FARA2010$overall_score)) / (max(HD_FARA2010$overall_score) - min(HD_FARA2010$overall_score))
# Add NormalizedScore to the dataframe
HD_FARA2010$NormalizedScore <- normalized_score_2010
# Create a bar plot
ggplot(HD_FARA2010, aes(x = as.factor(CensusTract), y = NormalizedScore)) +
geom_bar(stat = "identity", fill = "blue") +
labs(x = "Hill District Census Tract", y = "Normalized Overall Change", title = "Normalized Overall Change in Hill District Census Tracts for 2010") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

Now for 2019- plots for normalized change and scores
# Now for 2019
FARA_2019 <- read.csv("food_access_research_atlas.csv")
# Filter down to Hill District census tracts for 2019
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2019 <- FARA_2019[FARA_2019$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns_2019 <- scale(HD_FARA2019[, columns])
# Create overall score as the sum of standardized values
HD_FARA2019$overall_FI_score <- rowSums(standardized_columns_2019)
# Create a scatter plot with ggplot2
library(ggplot2)
ggplot(HD_FARA2019, aes(x = lapophalf, y = lalowihalf, color = overall_FI_score)) +
geom_point() +
scale_color_gradient(low = "blue", high = "red") +
labs(title = "Food Accessibility in 2019 - Hill District Census Tracts",
x = "Population Beyond 1/2 Mile from Supermarket",
y = "Low-Income Population Beyond 1/2 Mile from Supermarket",
color = "Overall Score") +
theme_minimal()

#bar graph for 2019
# Load required libraries
library(ggplot2)
# Filter down to Hill District census tracts for 2019
HillDist_census_tracts <- c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100)
HD_FARA2019 <- FARA_2019[FARA_2019$CensusTract %in% HillDist_census_tracts, ]
# Define columns for the overall score
columns <- c("lapophalf", "lalowihalf")
# Standardize each column
standardized_columns_2019 <- scale(HD_FARA2019[, columns])
# Create overall score as the sum of standardized values
HD_FARA2019$overall_FI_score <- rowSums(standardized_columns_2019)
# Normalize the overall score
normalized_score <- (HD_FARA2019$overall_FI_score - min(HD_FARA2019$overall_FI_score)) / (max(HD_FARA2019$overall_FI_score) - min(HD_FARA2019$overall_FI_score))
# Add NormalizedScore to the dataframe
HD_FARA2019$NormalizedScore <- normalized_score
# Create a bar plot
ggplot(HD_FARA2019, aes(x = as.factor(CensusTract), y = NormalizedScore)) +
geom_bar(stat = "identity", fill = "blue") +
labs(x = "Hill District Census Tract", y = "Normalized Overall Change", title = "Normalized Overall Change in Hill District Census Tracts for 2019") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

install.packages(c("igraph", "dplyr"))
Error in install.packages : Updating loaded packages
library(igraph)
library(dplyr)
# Create a data frame with Census Tract and overall score information
data <- data.frame(
CensusTract = c(42003030500, 42003050100, 42003050600, 42003050900, 42003051000, 42003051100),
overall_score_2019 = c(-2.0894987, -0.1954796, 0.4843697, 0.6179349, 3.2418969, -2.0592232),
overall_score_2010 = c(-1.22912461, -0.67851833, 0.09874682, -2.32037971, 3.35460811, 0.77466771)
)
# Create a graph based on overall scores above a certain threshold
threshold <- 0 # You can adjust the threshold as needed
# Create a graph from the data
graph_data <- data %>%
filter(overall_score_2019 > threshold) %>%
select(from = CensusTract, to = overall_score_2010)
# Create a graph object
graph <- graph_from_data_frame(graph_data, directed = FALSE)
# Plot the graph
plot(graph, main = "Graph of Census Tracts based on Overall Scores")

## Edges in the graph represent relationships between Census Tracts, where a relationship is established if the overall score in 2019 is above the specified threshold, provided in exploratory data analysis
LS0tCnRpdGxlOiAiRmluYWwgUHJvamVjdCBDb2RlIE5vdGVib29rIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCiMgRmluYWwgUHJvamVjdCBDb2RlIGZvciBJUzMxMAojIyBHcm91cCAyCkdyb3VwIE1lbWJlcnM6IExpbmRhIFNjaG5hYmVsLCBFcmljIEhpYmJzLCBEYXBobmUgR2lmZmluLCBBbXkgWmhhbmcKCgpgYGB7cn0KIyBTcGF0aWFsIERhdGEgTWFwcGluZwojI2luc3RhbGwucGFja2FnZXMoYygiZ2dwbG90MiIsICJzZiIpKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoc2YpCgojIFNwZWNpZnkgdGhlIHBhdGggdG8gdGhlIHNoYXBlZmlsZSBmb2xkZXIgKHdpdGhvdXQgZmlsZSBleHRlbnNpb24pCnNoYXBlZmlsZV9mb2xkZXIgPC0gIlBpdHRIb29kcyIKCiMgUmVhZCB0aGUgc2hhcGVmaWxlIHVzaW5nIHN0X3JlYWQKc2hhcGVmaWxlX3NmIDwtIHN0X3JlYWQoZHNuID0gc2hhcGVmaWxlX2ZvbGRlcikKI3ByaW50KHNoYXBlZmlsZV9zZikKCiMgUGxvdCB3IGdncGxvdDIKZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IHNoYXBlZmlsZV9zZikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgojIFpPT00gSU4gT04gSElMTCBESVNUUklDVApgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHNmKQoKIyBTcGVjaWZ5IHRoZSBwYXRoIHRvIHRoZSBzaGFwZWZpbGUgZm9sZGVyICh3aXRob3V0IGZpbGUgZXh0ZW5zaW9uKQpQaXR0X3NmX2ZvbGRlciA8LSAiUGl0dEhvb2RzIgoKIyBSZWFkIHRoZSBzaGFwZWZpbGUgdXNpbmcgc3RfcmVhZApzaGFwZWZpbGVfc2YgPC0gc3RfcmVhZChkc24gPSBzaGFwZWZpbGVfZm9sZGVyKQojcHJpbnQoc2hhcGVmaWxlX3NmKQoKaG9vZHNfb2ZfaW50ZXJlc3QgPC0gYygiQ3Jhd2ZvcmQtUm9iZXJ0cyIsICJVcHBlciBIaWxsIiwgIk1pZGRsZSBIaWxsIiwgIkJlZGZvcmQgRHdlbGxpbmdzIiwiVGVycmFjZSBWaWxsYWdlIikKCiMgRmlsdGVyIHRoZSBzaGFwZWZpbGUgdG8gaW5jbHVkZSB0aGUgaG9vZHMgdGhhdCBtYWtlIHVwIEhpbGwgRGlzdC4Kc3Vic2V0X3NmIDwtIHNoYXBlZmlsZV9zZltzaGFwZWZpbGVfc2YkaG9vZCAlaW4lIGhvb2RzX29mX2ludGVyZXN0LCBdCgojIERpc3BsYXkgdXNpbmcgZ2dwbG90MgpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gc3Vic2V0X3NmKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCiMgRmlyc3QsIGZpbHRlcmVkIGRhdGEgdG8gSGlsbCBEaXN0cmljdCBjZW5zdXMgdHJhY3RzIApgYGB7cn0KZGY8LSByZWFkLmNzdigiZm9vZF9hY2Nlc3NfcmVzZWFyY2hfYXRsYXMuY3N2IikKYGBgCgpgYGB7cn0KIyNsaWJyYXJ5KCJscHNvbHZlIikKbGlicmFyeSgiZHBseXIiKQpsaWJyYXJ5KCJwbG90bHkiKQpoZWFkKGRmKQpgYGAKYGBge3J9CiMjZmlsdGVyaW5nIG91dCBkYXRhIGJ5IFBlbm5zeWx2YW5pYSAKcGVubmRhdGEgPC1maWx0ZXIoZGYsU3RhdGUgPT0gIlBlbm5zeWx2YW5pYSIpCiMjZmlsdGVyIG91dCBieSBBbGxlZ2hlbnkKYWxsZWdoZW55ZGF0YSA8LSBmaWx0ZXIoZGYsIENvdW50eSA9PSAiQWxsZWdoZW55IikKIyMgYWxsZWdoZW55IGRhdGEKaGVhZChhbGxlZ2hlbnlkYXRhKQpgYGAKCmBgYHtyfQojI3NjYXR0ZXIgcGxvdCBvZiByZWFsaXR5LCB4PSBsYXBvcDEobG93IGFjY2VzcyBwb3AgYXQgMSBtaWxlIG9yIG1vcmUpLCB5ID0gc2hhcmUKIyNhY3R1YWx4IDwtIGRhdGEkbGFwb3AxCiMjYWN0dWFseSA8LWRhdGEkbGFwb3Axc2hhcmUKIyMgaWRlYWwgc2NhdHRlcnBsb3QgeCA9IGxhcG9wMSB3aGVuIDUwMCBvciAzMyUgb2YgcG9wLCB5ID0gc2hhcmUgMzMlCmhpbGxkYXRhIDwtIGZpbHRlcihhbGxlZ2hlbnlkYXRhLCBDZW5zdXNUcmFjdCA9PSA0MjAwMzAzMDUwMCkKIGZvciAocm93IGluIDE6bnJvdyhhbGxlZ2hlbnlkYXRhKSl7CiAgIGlmKGFsbGVnaGVueWRhdGFbcm93LCJDZW5zdXNUcmFjdCJdID09IDQyMDAzMDUwMTAwKQogICB7CiAgICAgaGlsbGRhdGEgPC0gcmJpbmQoaGlsbGRhdGEsIGFsbGVnaGVueWRhdGFbcm93LF0pCiAgIH0KICAgZWxzZSBpZihhbGxlZ2hlbnlkYXRhW3JvdywiQ2Vuc3VzVHJhY3QiXSA9PSA0MjAwMzA1MDYwMCkKICAgewogICAgIGhpbGxkYXRhIDwtIHJiaW5kKGhpbGxkYXRhLCBhbGxlZ2hlbnlkYXRhW3JvdyxdKQogICB9CiAgIGVsc2UgaWYoYWxsZWdoZW55ZGF0YVtyb3csIkNlbnN1c1RyYWN0Il0gPT0gNDIwMDMwNTA5MDApCiAgIHsKICAgICBoaWxsZGF0YSA8LSByYmluZChoaWxsZGF0YSwgYWxsZWdoZW55ZGF0YVtyb3csXSkKICAgfQogICAgZWxzZSBpZihhbGxlZ2hlbnlkYXRhW3JvdywiQ2Vuc3VzVHJhY3QiXSA9PSA0MjAwMzA1MTAwMCkKICAgewogICAgIGhpbGxkYXRhIDwtIHJiaW5kKGhpbGxkYXRhLCBhbGxlZ2hlbnlkYXRhW3JvdyxdKQogICAgfQogICAgIGVsc2UgaWYoYWxsZWdoZW55ZGF0YVtyb3csIkNlbnN1c1RyYWN0Il0gPT0gNDIwMDMwNTExMDApCiAgIHsKICAgICBoaWxsZGF0YSA8LSByYmluZChoaWxsZGF0YSwgYWxsZWdoZW55ZGF0YVtyb3csXSkKICAgfQogfQojNDIwMDMwNTAxMDAgfHw0MjAwMzA1MDkwMCB8NDIwMDMwNTEwMDAgfCA0MjAwMzA1MTEwMAogICAgICAgICAgICAgICAgICAgIzQyMDAzMDMwNTAwLCA0MjAwMzA1MDEwMCw0MjAwMzA1MDYwMCw0MjAwMzA1MDkwMCw0MjAwMzA1MTAwMCw0MjAwMzA1MTEwMCkKCmhlYWQoaGlsbGRhdGEpCiNhcyBvZiAyMDEwIHRoZSBhcmVhIGNvbXByaXNlcyBDZW5zdXMgVHJhY3RzIDMwNSAoQ3Jhd2ZvcmQgUm9iZXJ0cywgIkxvd2VyIEhpbGwiKSwgNTAxIChDcmF3Zm9yZC1Sb2JlcnRzLCAiTWlkZGxlIEhpbGwiKSwgNTA2IChVcHBlciBIaWxsKSwgNTA5IChCZWRmb3JkIER3ZWxsaW5ncyksIDUxMCBhbmQgNTExIChUZXJyYWNlIFZpbGxhZ2UpCmBgYApgYGB7cn0KIyNmdW5jdGlvbiBmb3IgZmluZGluZyBpZGVhbAogICMjIGZpcnN0IHlvdSB0YWtlIGFuIGFjdHVhbCBzaGFyZSwgdGhhbiB5b3Ugc3VidHJhY3QgMzMgZnJvbSBpdCB0byBzZWUgYnkgaG93IG11Y2ggaXRzIG92ZXIsIGxhcG9wMXNoYXJlIC0gMzMlCiAgIyMgY2FsY3VsYXRlIGhvdyBtdWNoIHRoYXQgd291bGQgYmUgaW4gcGVvcGxlLCAKICAjI3RoZW4gc3VidHJhY3QgdGhhdCBhbW91bnQgZnJvbSBsYXBvcDEgdG8ga25vdyBob3cgbWFueSBwZW9wbGUgdGhlcmUgYXJlIGF0IDwzMyUKaWRlYWx4dmFsdWVzIDwtIGMoKQp0aHJlc2hvbGRjYWxjdWxhdG9yIDwtIGZ1bmN0aW9uKHh2YWx1ZXMpewogIGZvciAocm93IGluIDE6bnJvdyhoaWxsZGF0YSkpewogICB4IDwtIGhpbGxkYXRhW3JvdywiUE9QMjAxMCJdICouMzMKICAgICAgaWYoeCA8IDUwMCl7CiAgICAgICAgIHggPC0gaGlsbGRhdGFbcm93LCJQT1AyMDEwIl0gKi4zM30KICAgICAgZWxzZSB7eCA8LSA1MDB9CiAgICAgIHh2YWx1ZXM8LSBjKHh2YWx1ZXMseCl9CiAgcmV0dXJuKHh2YWx1ZXMpCn0KdGhyZXNob2xkeCA8LSB0aHJlc2hvbGRjYWxjdWxhdG9yKGlkZWFseHZhbHVlcykKZm9yKGVsZW1lbnQgaW4gdGhyZXNob2xkeCkKewogIHByaW50KGVsZW1lbnQpCn0gICAgICAgCmBgYApgYGB7cn0KIyNST1dTIDM5NiBhbmQgNDAwIGhhdmUgMCBwb3B1bGF0aW9uLCBwZXJvIHRoZXkgYXJlbnQgaGlsbCBzbyBubyBwcm9ibGVtCiN2ZWN0b3IgdG8gc3RvcmUgc2hhcmVzCnRocmVzaG9sZHBvcHNoYXJlIDwtIGMoKQp0aHJlc2hvbGRzaGFyZWNhbGMgPC0gZnVuY3Rpb24oeHRocmVzaHNoYXJlLHh2YWxzKQp7CiAgZm9yIChyb3cgaW4gMTpucm93KGhpbGxkYXRhKSkKICB7CiAgICBpPC0gMQogICAgeCA8LSB4dmFsc1tpXS9oaWxsZGF0YVtyb3csIlBPUDIwMTAiXSAgCiAgICB4dGhyZXNoc2hhcmUgPC0gYyh4dGhyZXNoc2hhcmUseCkKICAgIGk8LSBpICsgMQogIH0gICAgICAgIAogIHJldHVybih4dGhyZXNoc2hhcmUpCn0KdGhyZXNob2xkcG9wIDwtIHRocmVzaG9sZGNhbGN1bGF0b3IoaWRlYWx4dmFsdWVzKQp0aHJlc2hvbGRwb3BzaGFyZSA8LSB0aHJlc2hvbGRzaGFyZWNhbGModGhyZXNob2xkcG9wc2hhcmUsdGhyZXNob2xkcG9wKQpsYXBvcGhhbGYgPC0gaGlsbGRhdGEkbGFwb3BoYWxmCmxhcG9waGFsZnNoYXJlIDwtIGhpbGxkYXRhJGxhcG9waGFsZnNoYXJlCmZvcihlbGVtZW50IGluIHRocmVzaG9sZHBvcHNoYXJlKQp7CiAgcHJpbnQoZWxlbWVudCkKfQpoZWFkKGhpbGxkYXRhKQpgYGAKCmBgYHtyfQojUExPVExZIEVYQU1QTEUKI0NIQU5HRSBDRU5TVVMgVFJBQ1RTIFRPIFNUUklOR1MgWSBXRSBBUkUgU0VUCmN0bmFtZXMgPC0gYygpCmZvcihlbGVtZW50IGluIGhpbGxkYXRhJENlbnN1c1RyYWN0KQp7CiAgY3RuYW1lcyA8LSBjKGN0bmFtZXMsdG9TdHJpbmcoZWxlbWVudCkpCn0KbGFwb3BkYXRhIDwtIGRhdGEuZnJhbWUoY3RuYW1lcyxsYXBvcGhhbGYsdGhyZXNob2xkcG9wKQpwb3BiYXJncmFwaCA8LSBwbG90X2x5KGxhcG9wZGF0YSwgeCA9IH5jdG5hbWVzLCB5ID0gfmxhcG9waGFsZiwgdHlwZSA9ICdiYXInLCBuYW1lID0gJ2xvdyBhY2Nlc3MgYXQgaGFsZiBtaWxlJykKcG9wYmFyZ3JhcGggPC0gcG9wYmFyZ3JhcGggJT4lIGFkZF90cmFjZSh5ID0gfnRocmVzaG9sZHBvcCwgbmFtZSA9ICd0aHJlc2hvbGQgcG9wJykKcG9wYmFyZ3JhcGggPC0gcG9wYmFyZ3JhcGggJT4lIGxheW91dCh5YXhpcyA9IGxpc3QodGl0bGUgPSAncG9wdWxhdGlvbicpLCBiYXJtb2RlID0gJ2dyb3VwJykKCnBvcGJhcmdyYXBoCmBgYAoKYGBge3J9CiNwb3ZlcnR5IHJhdGUKdHdlbnRpZXMgPC0gYygyMCwyMCwyMCwyMCwyMCwyMCkKcG9wcG92ZXJ0eXJhdGUgPC0gaGlsbGRhdGEkUG92ZXJ0eVJhdGUKcG92ZXJ0eXJhdGVzIDwtIGRhdGEuZnJhbWUoY3RuYW1lcyxwb3Bwb3ZlcnR5cmF0ZSx0d2VudGllcykKcG92ZXJ0eWJhcmdyYXBoIDwtIHBsb3RfbHkocG92ZXJ0eXJhdGVzLCB4ID0gfmN0bmFtZXMsIHkgPSB+cG9wcG92ZXJ0eXJhdGUsIHR5cGUgPSAnYmFyJywgbmFtZSA9ICdjZW5zdXMgcG92ZXJ0eSByYXRlJykKcG92ZXJ0eWJhcmdyYXBoIDwtIHBvdmVydHliYXJncmFwaCAlPiUgYWRkX3RyYWNlKHkgPSB+dHdlbnRpZXMsIG5hbWUgPSAndGhyZXNob2xkIGZvciBsb3cgaW5jb21lIHRyYWN0JykKcG92ZXJ0eWJhcmdyYXBoIDwtIHBvdmVydHliYXJncmFwaCAlPiUgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZSA9ICdwb3B1bGF0aW9uJyksIGJhcm1vZGUgPSAnZ3JvdXAnKQoKcG92ZXJ0eWJhcmdyYXBoCmBgYCAgICAKCmBgYHtyfQojVEVBTSBSRUZFUkVOQ0UgICAKbGlicmFyeSgiZHBseXIiKQojI2ZpbHRlcmluZyBvdXQgZGF0YSBieSBQZW5uc3lsdmFuaWEgCmZpbHRlcihkZixTdGF0ZSA9PSAiUGVubnN5bHZhbmlhIikKIyNmaWx0ZXIgb3V0IGJ5IEFsbGVnaGVueQphbGxlZ2hlbnlkYXRhIDwtIGZpbHRlcihkZiwgQ291bnR5ID09ICJBbGxlZ2hlbnkiKQpoaWxsZGF0YSA8LSBmaWx0ZXIoYWxsZWdoZW55ZGF0YSwgQ2Vuc3VzVHJhY3QgPT0gNDIwMDMwMzA1MDApCiBmb3IgKHJvdyBpbiAxOm5yb3coYWxsZWdoZW55ZGF0YSkpewogICBpZihhbGxlZ2hlbnlkYXRhW3JvdywiQ2Vuc3VzVHJhY3QiXSA9PSA0MjAwMzA1MDEwMCkKICAgewogICAgIGhpbGxkYXRhIDwtIHJiaW5kKGhpbGxkYXRhLCBhbGxlZ2hlbnlkYXRhW3JvdyxdKQogICB9CiAgIGVsc2UgaWYoYWxsZWdoZW55ZGF0YVtyb3csIkNlbnN1c1RyYWN0Il0gPT0gNDIwMDMwNTA2MDApCiAgIHsKICAgICBoaWxsZGF0YSA8LSByYmluZChoaWxsZGF0YSwgYWxsZWdoZW55ZGF0YVtyb3csXSkKICAgfQogICBlbHNlIGlmKGFsbGVnaGVueWRhdGFbcm93LCJDZW5zdXNUcmFjdCJdID09IDQyMDAzMDUwOTAwKQogICB7CiAgICAgaGlsbGRhdGEgPC0gcmJpbmQoaGlsbGRhdGEsIGFsbGVnaGVueWRhdGFbcm93LF0pCiAgIH0KICAgIGVsc2UgaWYoYWxsZWdoZW55ZGF0YVtyb3csIkNlbnN1c1RyYWN0Il0gPT0gNDIwMDMwNTEwMDApCiAgIHsKICAgICBoaWxsZGF0YSA8LSByYmluZChoaWxsZGF0YSwgYWxsZWdoZW55ZGF0YVtyb3csXSkKICAgIH0KICAgICBlbHNlIGlmKGFsbGVnaGVueWRhdGFbcm93LCJDZW5zdXNUcmFjdCJdID09IDQyMDAzMDUxMTAwKQogICB7CiAgICAgaGlsbGRhdGEgPC0gcmJpbmQoaGlsbGRhdGEsIGFsbGVnaGVueWRhdGFbcm93LF0pCiAgIH0KIH0KaGVhZChoaWxsZGF0YSkKYGBgCiMgRklORCBTVEFOREFSRElaRUQgRk9PRCBJTlNFQ1VSSVRZIFNDT1JFUyBGT1IgMjAxOQoKYGBge3J9CkZBUkFfMjAxOSA8LSByZWFkLmNzdigiZm9vZF9hY2Nlc3NfcmVzZWFyY2hfYXRsYXMuY3N2IikKCiMgRmlsdGVyIGRvd24gdG8gSGlsbCBEaXN0cmljdCBjZW5zdXMgdHJhY3RzIGZvciAyMDE5CkhpbGxEaXN0X2NlbnN1c190cmFjdHMgPC0gYyg0MjAwMzAzMDUwMCwgNDIwMDMwNTAxMDAsIDQyMDAzMDUwNjAwLCA0MjAwMzA1MDkwMCwgNDIwMDMwNTEwMDAsIDQyMDAzMDUxMTAwKQpIRF9GQVJBMjAxOSA8LSBGQVJBXzIwMTlbRkFSQV8yMDE5JENlbnN1c1RyYWN0ICVpbiUgSGlsbERpc3RfY2Vuc3VzX3RyYWN0cywgXQoKIyBEZWZpbmUgY29sdW1ucyBmb3IgdGhlIG92ZXJhbGwgc2NvcmUKY29sdW1ucyA8LSBjKCJsYXBvcGhhbGYiLCAibGFsb3dpaGFsZiIpCgojIFN0YW5kYXJkaXplIGVhY2ggY29sdW1uCnN0YW5kYXJkaXplZF9jb2x1bW5zIDwtIHNjYWxlKEhEX0ZBUkEyMDE5WywgY29sdW1uc10pCgojIENyZWF0ZSBvdmVyYWxsIHNjb3JlIGFzIHRoZSBzdW0gb2Ygc3RhbmRhcmRpemVkIHZhbHVlcwpIRF9GQVJBMjAxOSRvdmVyYWxsX0ZJX3Njb3JlIDwtIHJvd1N1bXMoc3RhbmRhcmRpemVkX2NvbHVtbnMpCgojIENyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgd2l0aCBsYXBvcGhhbGYgYW5kIGxhbG93aWhhbGYgY29sdW1ucyBhbmQgdGhlaXIgYW5kIG92ZXJhbGwgc2NvcmVzIGZvciBlYWNoIHRyYWN0CnJlc3VsdHNfMjAxOV9kZiA8LSBkYXRhLmZyYW1lKAogIENlbnN1c1RyYWN0ID0gSERfRkFSQTIwMTkkQ2Vuc3VzVHJhY3QsCiAgbGFwb3BoYWxmID0gSERfRkFSQTIwMTkkbGFwb3BoYWxmLAogIGxhbG93aWhhbGYgPSBIRF9GQVJBMjAxOSRsYWxvd2loYWxmLAogIG92ZXJhbGxfRklfc2NvcmUgPSBIRF9GQVJBMjAxOSRvdmVyYWxsX0ZJX3Njb3JlCikKCiMgUHJpbnQgdGhlIHJlc3VsdGluZyBkYXRhZnJhbWUKcHJpbnQocmVzdWx0c18yMDE5X2RmKQpgYGAKCiMgIEZJTkQgU1RBTkRBUkRJWkVEIEZPT0QgSU5TRUNVUklUWSBTQ09SRVMgRk9SIDIwMTAKYGBge3J9CkZBUkFfMjAxMCA8LSByZWFkLmNzdigiRm9vZEFjY2Vzc1Jlc2VhcmNoQXRsYXNEYXRhMjAxMC5jc3YiKQoKIyBGaWx0ZXIgZG93biB0byBIaWxsIERpc3RyaWN0IGNlbnN1cyB0cmFjdHMgZm9yIDIwMTkKSGlsbERpc3RfY2Vuc3VzX3RyYWN0cyA8LSBjKDQyMDAzMDMwNTAwLCA0MjAwMzA1MDEwMCwgNDIwMDMwNTA2MDAsIDQyMDAzMDUwOTAwLCA0MjAwMzA1MTAwMCwgNDIwMDMwNTExMDApCkhEX0ZBUkEyMDEwIDwtIEZBUkFfMjAxMFtGQVJBXzIwMTAkQ2Vuc3VzVHJhY3QgJWluJSBIaWxsRGlzdF9jZW5zdXNfdHJhY3RzLCBdCgojIERlZmluZSBjb2x1bW5zIGZvciB0aGUgb3ZlcmFsbCBzY29yZQpjb2x1bW5zIDwtIGMoImxhcG9waGFsZiIsICJsYWxvd2loYWxmIikKCiMgU3RhbmRhcmRpemUgZWFjaCBjb2x1bW4Kc3RhbmRhcmRpemVkX2NvbHVtbnMgPC0gc2NhbGUoSERfRkFSQTIwMTBbLCBjb2x1bW5zXSkKCiMgQ3JlYXRlIG92ZXJhbGwgc2NvcmUgYXMgdGhlIHN1bSBvZiBzdGFuZGFyZGl6ZWQgdmFsdWVzCkhEX0ZBUkEyMDEwJG92ZXJhbGxfc2NvcmUgPC0gcm93U3VtcyhzdGFuZGFyZGl6ZWRfY29sdW1ucykKCiMgQ3JlYXRlIGEgbmV3IGRhdGFmcmFtZSB3aXRoIHJlbGV2YW50IGNvbHVtbnMgYW5kIG92ZXJhbGwgc2NvcmUKcmVzdWx0X2RmIDwtIGRhdGEuZnJhbWUoCiAgQ2Vuc3VzVHJhY3QgPSBIRF9GQVJBMjAxMCRDZW5zdXNUcmFjdCwKICBsYXBvcGhhbGYgPSBIRF9GQVJBMjAxMCRsYXBvcGhhbGYsCiAgbGFsb3dpaGFsZiA9IEhEX0ZBUkEyMDEwJGxhbG93aWhhbGYsCiAgb3ZlcmFsbF9zY29yZSA9IEhEX0ZBUkEyMDEwJG92ZXJhbGxfc2NvcmUKKQoKIyBQcmludCB0aGUgcmVzdWx0aW5nIGRhdGFmcmFtZQpwcmludChyZXN1bHRfZGYpCgoKCiNpbXBvcnQgdG8gbGF0ZXgKbGlicmFyeSh4dGFibGUpCnRhYmxlX2xhdGV4IDwtIHh0YWJsZShyZXN1bHRfZGYsIGNhcHRpb24gPSAiRm9vZCBJbnNlY3VyaXR5IFNjb3JlcyBmb3IgMjAxMCBpbiBIaWxsIERpc3RyaWN0IiwgbGFiZWwgPSAidGFiOmZvb2RfaW5zZWN1cml0eV8yMDEwX2hkIikKcHJpbnQueHRhYmxlKHRhYmxlX2xhdGV4LCB0eXBlID0gImxhdGV4IiwgZmlsZSA9ICJtZXRob2RzdGFibGUyMDEwLnRleCIpCmBgYAoKIyBxdWljayB2aXN1YWxpemF0aW9uIGZvciAyMDEwCmBgYHtyfQpGQVJBXzIwMTAgPC0gcmVhZC5jc3YoIkZvb2RBY2Nlc3NSZXNlYXJjaEF0bGFzRGF0YTIwMTAuY3N2IikKCiMgRmlsdGVyIGRvd24gdG8gSGlsbCBEaXN0cmljdCBjZW5zdXMgdHJhY3RzIGZvciAyMDEwCkhpbGxEaXN0X2NlbnN1c190cmFjdHMgPC0gYyg0MjAwMzAzMDUwMCwgNDIwMDMwNTAxMDAsIDQyMDAzMDUwNjAwLCA0MjAwMzA1MDkwMCwgNDIwMDMwNTEwMDAsIDQyMDAzMDUxMTAwKQpIRF9GQVJBMjAxMCA8LSBGQVJBXzIwMTBbRkFSQV8yMDEwJENlbnN1c1RyYWN0ICVpbiUgSGlsbERpc3RfY2Vuc3VzX3RyYWN0cywgXQoKIyBEZWZpbmUgY29sdW1ucyBmb3IgdGhlIG92ZXJhbGwgc2NvcmUKY29sdW1ucyA8LSBjKCJsYXBvcGhhbGYiLCAibGFsb3dpaGFsZiIpCgojIFN0YW5kYXJkaXplIGVhY2ggY29sdW1uCnN0YW5kYXJkaXplZF9jb2x1bW5zIDwtIHNjYWxlKEhEX0ZBUkEyMDEwWywgY29sdW1uc10pCgojIENyZWF0ZSBvdmVyYWxsIEZvb2QgQWNjZXNzIHNjb3JlIGFzIHRoZSBzdW0gb2Ygc3RhbmRhcmRpemVkIHZhbHVlcwpIRF9GQVJBMjAxMCRvdmVyYWxsX3Njb3JlIDwtIHJvd1N1bXMoc3RhbmRhcmRpemVkX2NvbHVtbnMpCgojIENyZWF0ZSBhIHNjYXR0ZXIgcGxvdCB3aXRoIGdncGxvdDIKbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KEhEX0ZBUkEyMDEwLCBhZXMoeCA9IGxhcG9waGFsZiwgeSA9IGxhbG93aWhhbGYsIGNvbG9yID0gb3ZlcmFsbF9zY29yZSkpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdyA9ICJibHVlIiwgaGlnaCA9ICJyZWQiKSArCiAgbGFicyh0aXRsZSA9ICJGb29kIEFjY2Vzc2liaWxpdHkgaW4gMjAxMCAtIEhpbGwgRGlzdHJpY3QgQ2Vuc3VzIFRyYWN0cyIsCiAgICAgICB4ID0gIlBvcHVsYXRpb24gQmV5b25kIDEvMiBNaWxlIGZyb20gU3VwZXJtYXJrZXQiLAogICAgICAgeSA9ICJMb3ctSW5jb21lIFBvcHVsYXRpb24gQmV5b25kIDEvMiBNaWxlIGZyb20gU3VwZXJtYXJrZXQiLAogICAgICAgY29sb3IgPSAiT3ZlcmFsbCBTY29yZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAoKIzIwMTAgYmFyIGdyYXBoIG9mIG5vcm1hbGl6ZWQgY2hhbmdlCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZ2dwbG90MikKCiMgRmlsdGVyIGRvd24gdG8gSGlsbCBEaXN0cmljdCBjZW5zdXMgdHJhY3RzIGZvciAyMDEwCkhpbGxEaXN0X2NlbnN1c190cmFjdHMgPC0gYyg0MjAwMzAzMDUwMCwgNDIwMDMwNTAxMDAsIDQyMDAzMDUwNjAwLCA0MjAwMzA1MDkwMCwgNDIwMDMwNTEwMDAsIDQyMDAzMDUxMTAwKQpIRF9GQVJBMjAxMCA8LSBGQVJBXzIwMTBbRkFSQV8yMDEwJENlbnN1c1RyYWN0ICVpbiUgSGlsbERpc3RfY2Vuc3VzX3RyYWN0cywgXQoKIyBEZWZpbmUgY29sdW1ucyBmb3IgdGhlIG92ZXJhbGwgc2NvcmUKY29sdW1ucyA8LSBjKCJsYXBvcGhhbGYiLCAibGFsb3dpaGFsZiIpCgojIFN0YW5kYXJkaXplIGVhY2ggY29sdW1uCnN0YW5kYXJkaXplZF9jb2x1bW5zXzIwMTAgPC0gc2NhbGUoSERfRkFSQTIwMTBbLCBjb2x1bW5zXSkKCiMgQ3JlYXRlIG92ZXJhbGwgRm9vZCBBY2Nlc3Mgc2NvcmUgYXMgdGhlIHN1bSBvZiBzdGFuZGFyZGl6ZWQgdmFsdWVzCkhEX0ZBUkEyMDEwJG92ZXJhbGxfc2NvcmUgPC0gcm93U3VtcyhzdGFuZGFyZGl6ZWRfY29sdW1uc18yMDEwKQoKIyBOb3JtYWxpemUgdGhlIG92ZXJhbGwgc2NvcmUKbm9ybWFsaXplZF9zY29yZV8yMDEwIDwtIChIRF9GQVJBMjAxMCRvdmVyYWxsX3Njb3JlIC0gbWluKEhEX0ZBUkEyMDEwJG92ZXJhbGxfc2NvcmUpKSAvIChtYXgoSERfRkFSQTIwMTAkb3ZlcmFsbF9zY29yZSkgLSBtaW4oSERfRkFSQTIwMTAkb3ZlcmFsbF9zY29yZSkpCgojIEFkZCBOb3JtYWxpemVkU2NvcmUgdG8gdGhlIGRhdGFmcmFtZQpIRF9GQVJBMjAxMCROb3JtYWxpemVkU2NvcmUgPC0gbm9ybWFsaXplZF9zY29yZV8yMDEwCgojIENyZWF0ZSBhIGJhciBwbG90CmdncGxvdChIRF9GQVJBMjAxMCwgYWVzKHggPSBhcy5mYWN0b3IoQ2Vuc3VzVHJhY3QpLCB5ID0gTm9ybWFsaXplZFNjb3JlKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImJsdWUiKSArCiAgbGFicyh4ID0gIkhpbGwgRGlzdHJpY3QgQ2Vuc3VzIFRyYWN0IiwgeSA9ICJOb3JtYWxpemVkIE92ZXJhbGwgQ2hhbmdlIiwgdGl0bGUgPSAiTm9ybWFsaXplZCBPdmVyYWxsIENoYW5nZSBpbiBIaWxsIERpc3RyaWN0IENlbnN1cyBUcmFjdHMgZm9yIDIwMTAiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKCmBgYAoKIyBOb3cgZm9yIDIwMTktIHBsb3RzIGZvciBub3JtYWxpemVkIGNoYW5nZSBhbmQgc2NvcmVzCmBgYHtyfQpGQVJBXzIwMTkgPC0gcmVhZC5jc3YoImZvb2RfYWNjZXNzX3Jlc2VhcmNoX2F0bGFzLmNzdiIpCgojIEZpbHRlciBkb3duIHRvIEhpbGwgRGlzdHJpY3QgY2Vuc3VzIHRyYWN0cyBmb3IgMjAxOQpIaWxsRGlzdF9jZW5zdXNfdHJhY3RzIDwtIGMoNDIwMDMwMzA1MDAsIDQyMDAzMDUwMTAwLCA0MjAwMzA1MDYwMCwgNDIwMDMwNTA5MDAsIDQyMDAzMDUxMDAwLCA0MjAwMzA1MTEwMCkKSERfRkFSQTIwMTkgPC0gRkFSQV8yMDE5W0ZBUkFfMjAxOSRDZW5zdXNUcmFjdCAlaW4lIEhpbGxEaXN0X2NlbnN1c190cmFjdHMsIF0KCiMgRGVmaW5lIGNvbHVtbnMgZm9yIHRoZSBvdmVyYWxsIHNjb3JlCmNvbHVtbnMgPC0gYygibGFwb3BoYWxmIiwgImxhbG93aWhhbGYiKQoKIyBTdGFuZGFyZGl6ZSBlYWNoIGNvbHVtbgpzdGFuZGFyZGl6ZWRfY29sdW1uc18yMDE5IDwtIHNjYWxlKEhEX0ZBUkEyMDE5WywgY29sdW1uc10pCgojIENyZWF0ZSBvdmVyYWxsIHNjb3JlIGFzIHRoZSBzdW0gb2Ygc3RhbmRhcmRpemVkIHZhbHVlcwpIRF9GQVJBMjAxOSRvdmVyYWxsX0ZJX3Njb3JlIDwtIHJvd1N1bXMoc3RhbmRhcmRpemVkX2NvbHVtbnNfMjAxOSkKCgojIENyZWF0ZSBhIHNjYXR0ZXIgcGxvdCB3aXRoIGdncGxvdDIKbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KEhEX0ZBUkEyMDE5LCBhZXMoeCA9IGxhcG9waGFsZiwgeSA9IGxhbG93aWhhbGYsIGNvbG9yID0gb3ZlcmFsbF9GSV9zY29yZSkpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdyA9ICJibHVlIiwgaGlnaCA9ICJyZWQiKSArCiAgbGFicyh0aXRsZSA9ICJGb29kIEFjY2Vzc2liaWxpdHkgaW4gMjAxOSAtIEhpbGwgRGlzdHJpY3QgQ2Vuc3VzIFRyYWN0cyIsCiAgICAgICB4ID0gIlBvcHVsYXRpb24gQmV5b25kIDEvMiBNaWxlIGZyb20gU3VwZXJtYXJrZXQiLAogICAgICAgeSA9ICJMb3ctSW5jb21lIFBvcHVsYXRpb24gQmV5b25kIDEvMiBNaWxlIGZyb20gU3VwZXJtYXJrZXQiLAogICAgICAgY29sb3IgPSAiT3ZlcmFsbCBTY29yZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAojYmFyIGdyYXBoIGZvciAyMDE5CmBgYHtyfQojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZ2dwbG90MikKCiMgRmlsdGVyIGRvd24gdG8gSGlsbCBEaXN0cmljdCBjZW5zdXMgdHJhY3RzIGZvciAyMDE5CkhpbGxEaXN0X2NlbnN1c190cmFjdHMgPC0gYyg0MjAwMzAzMDUwMCwgNDIwMDMwNTAxMDAsIDQyMDAzMDUwNjAwLCA0MjAwMzA1MDkwMCwgNDIwMDMwNTEwMDAsIDQyMDAzMDUxMTAwKQpIRF9GQVJBMjAxOSA8LSBGQVJBXzIwMTlbRkFSQV8yMDE5JENlbnN1c1RyYWN0ICVpbiUgSGlsbERpc3RfY2Vuc3VzX3RyYWN0cywgXQoKIyBEZWZpbmUgY29sdW1ucyBmb3IgdGhlIG92ZXJhbGwgc2NvcmUKY29sdW1ucyA8LSBjKCJsYXBvcGhhbGYiLCAibGFsb3dpaGFsZiIpCgojIFN0YW5kYXJkaXplIGVhY2ggY29sdW1uCnN0YW5kYXJkaXplZF9jb2x1bW5zXzIwMTkgPC0gc2NhbGUoSERfRkFSQTIwMTlbLCBjb2x1bW5zXSkKCiMgQ3JlYXRlIG92ZXJhbGwgc2NvcmUgYXMgdGhlIHN1bSBvZiBzdGFuZGFyZGl6ZWQgdmFsdWVzCkhEX0ZBUkEyMDE5JG92ZXJhbGxfRklfc2NvcmUgPC0gcm93U3VtcyhzdGFuZGFyZGl6ZWRfY29sdW1uc18yMDE5KQoKIyBOb3JtYWxpemUgdGhlIG92ZXJhbGwgc2NvcmUKbm9ybWFsaXplZF9zY29yZSA8LSAoSERfRkFSQTIwMTkkb3ZlcmFsbF9GSV9zY29yZSAtIG1pbihIRF9GQVJBMjAxOSRvdmVyYWxsX0ZJX3Njb3JlKSkgLyAobWF4KEhEX0ZBUkEyMDE5JG92ZXJhbGxfRklfc2NvcmUpIC0gbWluKEhEX0ZBUkEyMDE5JG92ZXJhbGxfRklfc2NvcmUpKQoKIyBBZGQgTm9ybWFsaXplZFNjb3JlIHRvIHRoZSBkYXRhZnJhbWUKSERfRkFSQTIwMTkkTm9ybWFsaXplZFNjb3JlIDwtIG5vcm1hbGl6ZWRfc2NvcmUKCiMgQ3JlYXRlIGEgYmFyIHBsb3QKZ2dwbG90KEhEX0ZBUkEyMDE5LCBhZXMoeCA9IGFzLmZhY3RvcihDZW5zdXNUcmFjdCksIHkgPSBOb3JtYWxpemVkU2NvcmUpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiYmx1ZSIpICsKICBsYWJzKHggPSAiSGlsbCBEaXN0cmljdCBDZW5zdXMgVHJhY3QiLCB5ID0gIk5vcm1hbGl6ZWQgT3ZlcmFsbCBDaGFuZ2UiLCB0aXRsZSA9ICJOb3JtYWxpemVkIE92ZXJhbGwgQ2hhbmdlIGluIEhpbGwgRGlzdHJpY3QgQ2Vuc3VzIFRyYWN0cyBmb3IgMjAxOSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoYygiaWdyYXBoIiwgImRwbHlyIikpCmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KGRwbHlyKQoKIyBDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggQ2Vuc3VzIFRyYWN0IGFuZCBvdmVyYWxsIHNjb3JlIGluZm9ybWF0aW9uCmRhdGEgPC0gZGF0YS5mcmFtZSgKICBDZW5zdXNUcmFjdCA9IGMoNDIwMDMwMzA1MDAsIDQyMDAzMDUwMTAwLCA0MjAwMzA1MDYwMCwgNDIwMDMwNTA5MDAsIDQyMDAzMDUxMDAwLCA0MjAwMzA1MTEwMCksCiAgb3ZlcmFsbF9zY29yZV8yMDE5ID0gYygtMi4wODk0OTg3LCAtMC4xOTU0Nzk2LCAwLjQ4NDM2OTcsIDAuNjE3OTM0OSwgMy4yNDE4OTY5LCAtMi4wNTkyMjMyKSwKICBvdmVyYWxsX3Njb3JlXzIwMTAgPSBjKC0xLjIyOTEyNDYxLCAtMC42Nzg1MTgzMywgMC4wOTg3NDY4MiwgLTIuMzIwMzc5NzEsIDMuMzU0NjA4MTEsIDAuNzc0NjY3NzEpCikKCiMgQ3JlYXRlIGEgZ3JhcGggYmFzZWQgb24gb3ZlcmFsbCBzY29yZXMgYWJvdmUgYSBjZXJ0YWluIHRocmVzaG9sZAp0aHJlc2hvbGQgPC0gMCAgIyBZb3UgY2FuIGFkanVzdCB0aGUgdGhyZXNob2xkIGFzIG5lZWRlZAoKIyBDcmVhdGUgYSBncmFwaCBmcm9tIHRoZSBkYXRhCmdyYXBoX2RhdGEgPC0gZGF0YSAlPiUKICBmaWx0ZXIob3ZlcmFsbF9zY29yZV8yMDE5ID4gdGhyZXNob2xkKSAlPiUKICBzZWxlY3QoZnJvbSA9IENlbnN1c1RyYWN0LCB0byA9IG92ZXJhbGxfc2NvcmVfMjAxMCkKCiMgQ3JlYXRlIGEgZ3JhcGggb2JqZWN0CmdyYXBoIDwtIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShncmFwaF9kYXRhLCBkaXJlY3RlZCA9IEZBTFNFKQoKIyBQbG90IHRoZSBncmFwaApwbG90KGdyYXBoLCBtYWluID0gIkdyYXBoIG9mIENlbnN1cyBUcmFjdHMgYmFzZWQgb24gT3ZlcmFsbCBTY29yZXMiKQpgYGAKYGBge3J9CiMjIEVkZ2VzIGluIHRoZSBncmFwaCByZXByZXNlbnQgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIENlbnN1cyBUcmFjdHMsIHdoZXJlIGEgcmVsYXRpb25zaGlwIGlzIGVzdGFibGlzaGVkIGlmIHRoZSBvdmVyYWxsIHNjb3JlIGluIDIwMTkgaXMgYWJvdmUgdGhlIHNwZWNpZmllZCB0aHJlc2hvbGQsIHByb3ZpZGVkIGluIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMKYGBgCgo=