Introduction:
Be sure to toggle the code buttons located on the far
right of the page as you read along! you can also download the RMD by
clicking the code button at the very top of the page.
The analysis demonstrated in this tutorial is part of a two
part study in which data was initially extracted from satellite
imagery in a remote sensing analysis.The initial study hypothesized that
the acceleration of sea level rise and increased storm frequency are
influencing the disappearance of marsh vegetation in Long Island’s South
Shore Estuary. The extracted satellite imagery data will be used to
evaluate the relationship between Long Island’s vegetation density
(NDVI), mean local sea level rise, and storm events frequency over time.
Basic statistical tests will be used to evaluate these relationships by
doing the following analysis:
- Normality testing
- Plotting the data in a dual axis time series plot
- Correlation testing using Spearman’s Rho
- A basic multiple linear regression analysis
Background on remote sensing analysis
Click the tabs below to review the results of a remote
sensing color image analysis.
Shown below, is the composite satellite image that was created to
extract the Long Island vegetation density data used in the statistical
analysis in this tutorial. This single color image is composed of three
normalized difference vegetation index images (NDVI) created in the
initial study.This color image displays the vegetation density in an
area for a given year. Specifically,each primary color represents a
single year containing vegetation. A secondary color represents the
presences of vegetation throughout multiple years. For example red spots
show where vegetation only grew in 2019, blue spots show only where
vegetation grew in 1995, and cyan spots show only where vegetation grew
through out the years 1995 and 2000.
For more information on the methods and out come of the entire study
feel free to read the executive
study.
Jamaica Bay
Color Image

South
Oyster Bay Color Image

Great South
Bay Color Image

Reading in
libraries and organizing data
Let’s begin our analysis with reading in some necessary libraries as
well as reading in and organizing mean local sea level rise (MLSLR)
data.
library(tidyverse)
library(lubridate)
library(janitor)
library(readr)
library(ggplot2)
library(hrbrthemes)
library(tidyquant)
meanL_SLR <-read_csv("TheBattery_meanSLtrend_trim2.csv")
#organize and clean MLSLR data
meanL_SLR<- clean_names(meanL_SLR)
meanL_SLR<- rename(meanL_SLR, month = slr_month)
Now lets read in the NDVI (satellite obtained vegetation density
data) and organize it. Data from nine region of interests (ROI sites)
were extracted from the color image in GEE. Therefore, we will need to
read in nine CSV file. To read the files in more efficiently, a function
that reads in all files and merges them all into one data frame will be
created. The date column will then be converted to yyyy-mm-dd and the
year, month and day will be extracted from the new date column to a new
columns.
multi_merge2 = function(mypath){
filenames=list.files(path=mypath,full.names=TRUE)
datalist = lapply(filenames, read_csv)
Reduce(full_join, datalist)}
NDVI_data <- multi_merge2("SR_timeseries_Final")
#organize/ clean/ reclassify and rename columns NDVI the data
NDVI_data <- clean_names(NDVI_data)
NDVI_data <- rename(NDVI_data, date = system_time_start)
NDVI_data$date<- lubridate::mdy(NDVI_data$date)
NDVI_data <- NDVI_data %>%
dplyr::mutate(year = lubridate::year(date),
month = lubridate::month(date),
day = lubridate::day(date))
Data exploration and normality testing
Now let’s inspect the data. Note how there are 26 observations in the
MLSLR data and there are 72 observation in the NDVI data.
length(!is.na(meanL_SLR$monthly_msl))
## [1] 26
length(!is.na(NDVI_data$gsb95_ndvi))
## [1] 72
Before we run normality testing on the MLSLR and NDVI data, we will
join the data together. This is because we want to correctly assess the
distribution of all the data to choose the correct correlation test when
analyzing for the relationship between vegetation density and MLSLR.
Normality testing can be conducted using the Wilk Shapiro test. We can
analyze the normality of the NDVI data for each ROI site and visualize
the data in a histogram one by one as shown below.
NDVI_ML_SLR <- NDVI_data %>%
left_join(meanL_SLR,
by = c("year" = "year", "month" = "month")) %>%
arrange(year)
Click the tabs below to see the results of the normality
test.
Plot_
hist(NDVI_ML_SLR$gsb_95_00_ndvi,
main ="Histogram of Vegetation Density Values (NDVI) in Great South bay 1995",
xlab = "NDVI values",
ylab = "Frequency")

Result
Summary Values
shapiro.test(NDVI_ML_SLR$gsb_95_00_ndvi) #meanL_SLR$monthly_msl
##
## Shapiro-Wilk normality test
##
## data: NDVI_ML_SLR$gsb_95_00_ndvi
## W = 0.90965, p-value = 0.005525
Table
## # A tibble: 72 x 14
## date gsb95_ndvi gsb19_ndvi gsb_95_00_ndvi jb95_ndvi jb19_ndvi
## <date> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1995-08-12 0.499 0.054 0.466 0.046 0.045
## 2 1995-08-28 0.572 0.332 0.536 0.348 0.104
## 3 1996-08-14 0.476 0.309 0.21 0.205 0.085
## 4 1996-08-30 0.589 0.29 0.528 0.443 0.145
## 5 1996-08-05 NA NA NA 0.364 0.22
## 6 1997-08-17 0.543 0.266 0.456 0.494 0.4
## 7 1997-08-24 NA NA NA 0.449 0.228
## 8 1998-08-20 0.417 0.271 0.5 0.406 0.367
## 9 1998-08-27 NA NA NA 0.023 0.024
## 10 1999-08-23 0.395 0.29 0.523 0.35 0.303
## # ... with 62 more rows, and 8 more variables: jb_95_00_ndvi <dbl>,
## # sob95_ndvi <dbl>, sob19_ndvi <dbl>, sob_95_00_ndvi <dbl>, year <dbl>,
## # month <dbl>, day <int>, monthly_msl <dbl>
HOWEVER, this would take along time. Instead we will organize the
data so that we can loop the test over the data set. Our current table
has some columns that we don’t want to apply the shapiro test on. To fix
this, we will create a new variable and drop the columns we don’t want
from the original table then apply the shapiro test to the new table.
Then we will have a list of test results showing how some data are
skewed.
Normallity_tests <- NDVI_ML_SLR %>%
select(c(jb19_ndvi,jb_95_00_ndvi, jb95_ndvi))%>%
apply(2,shapiro.test)
Normallity_tests
## $jb19_ndvi
##
## Shapiro-Wilk normality test
##
## data: newX[, i]
## W = 0.93742, p-value = 0.001408
##
##
## $jb_95_00_ndvi
##
## Shapiro-Wilk normality test
##
## data: newX[, i]
## W = 0.92965, p-value = 0.000593
##
##
## $jb95_ndvi
##
## Shapiro-Wilk normality test
##
## data: newX[, i]
## W = 0.96114, p-value = 0.02562
Correlation between NDVI and MLSLR
As we saw, some of the data in the data frame are not normally
distributed. We can choose Spearman’s Rho because it is a robust
analysis and doesn’t require normally distributed data. We can now
create a function that will loop over the data set and run the
correlation test.
Lets begin the process by subsetting the data using the select
function. This will remove any columns you don’t need to include in your
correlation. In this section we will create a function that compares
mean local sea level rise data (y) to all x’s (other_var) by using the
apply function to run Spearman’s Rho over all the data.
Code
SubNDVI_mlsr <- NDVI_ML_SLR %>%
select(c(gsb_95_00_ndvi, gsb95_ndvi, monthly_msl))
cor_test_loop <- function(data, y) {
return(apply(
data,
2,
FUN = function (other_var) {
return(cor.test(other_var, data[[y]], data = data, method = "spearman"))
}
))
}
#cor_test_loop(SubNDVI_mlsr,"monthly_msl")
Result
Summary Values
cor_test_loop(SubNDVI_mlsr,"monthly_msl")
## $gsb_95_00_ndvi
##
## Spearman's rank correlation rho
##
## data: other_var and data[[y]]
## S = 12764, p-value = 0.001165
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## -0.5130808
##
##
## $gsb95_ndvi
##
## Spearman's rank correlation rho
##
## data: other_var and data[[y]]
## S = 13187, p-value = 0.000285
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## -0.5631231
##
##
## $monthly_msl
##
## Spearman's rank correlation rho
##
## data: other_var and data[[y]]
## S = 0, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 1
Plotting NDVI vs MLSLR
The correlation analysis reveled that there is a relationship between
the vegetation density (NDVI values) in Queens, Long Island South Bay,
and MLSLR. In this section we will see if the vegetation in each
location has kept growing over time despite the rise in sea level. To
show this, we will compare the NDVI values to MLSLR data by creating a
dual axis box plot and line graph time series analysis.This will help us
visualize the correlation results. To start, lets take the joined NDVI
and MLSLR data frame and make it long.
NDVI_ML_SLR_long <- NDVI_ML_SLR %>%
pivot_longer(cols = contains("ndvi"),
names_to = "roi_marsh",
values_to = "NDVI_val")%>%
filter(!is.na("roi_marsh")&
!is.na("NDVI_val"))
To see the code for the plots select the code button on
your right.
Boxplot
1
Plot of vegetation that grew in the blue sites on the map in 1995
blue site.
# Create custom colors for your boxplot graph
ndvicolor <- "#17c1d4"
MLSLRcolor <- "#d49817"
ndviTXTcolor95 <- "#0c5970"
MLSLRtxtColor95 <- "#4f280a"
# New facet label names for dose variable
roi_marsh.labs <- c("Great South Bay", "Jamaica Bay", "South Oyster Bay")
names(roi_marsh.labs) <- c("gsb95_ndvi", "jb95_ndvi", "sob95_ndvi")
##Create boxplots of Blue NDVI data distribution V.S. Mean Local Sea Level Rise
MLSLR_NDVI_95_bp <- NDVI_ML_SLR_long %>%
filter(roi_marsh %in% c("jb95_ndvi", "sob95_ndvi", "gsb95_ndvi")) %>%
ggplot(aes(x = year)) +
geom_boxplot(aes(y = NDVI_val, group = year),
size = 1,
color = ndvicolor) +
geom_line(aes(y = monthly_msl), size = 1.5, color = MLSLRcolor) +
scale_y_continuous(# Features of the first axis
name = "NDVI Values from Marshes Exsisting in 1995",
# Add a second axis and specify its features
sec.axis = sec_axis(trans = ~ . * 1, name = "Mean Local SLR")) +
ggtitle("Mean Local SLR Compared to NDVI Times Series") +
theme_test(
base_size = 15,
base_family = "",
base_rect_size = 0.5
) + #this changes the text size of the numbers on the xy scale and the facet names
theme(
strip.text = element_text(size = 10, face = "bold"),
axis.title.y = element_text(
color = ndviTXTcolor95 ,
size = 13,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.y.right = element_text(size = 13,
color = MLSLRtxtColor95 ,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.x = element_text(size = 13, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)),
plot.title = element_text(size = 15, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
))
) +
facet_wrap( ~ roi_marsh,
labeller = labeller(roi_marsh = roi_marsh.labs),
nrow = 3)
MLSLR_NDVI_95_bp

Boxplot
2
Plot of vegetation that grew in the cyan sites through out the years
1995 to 2000.Click the code button to see how to change the colors and
variable names
ndvicolor <- "#008080"
MLSLRcolor <- "#d49817"
ndviTXTcolor95_00 <- "#1e3321"
MLSLRtxtColor95_00 <- "#4f280a"
# New facet label names for dose variable
roi_marsh.labs2 <-
c("Great South Bay", "Jamaica Bay", "South Oyster Bay")
names(roi_marsh.labs2) <-
c("gsb_95_00_ndvi", "jb_95_00_ndvi", "sob_95_00_ndvi")
#filter and plot
MLSLR_NDVI_95_00_bp <- NDVI_ML_SLR_long %>%
filter(roi_marsh %in% c("gsb_95_00_ndvi", "jb_95_00_ndvi", "sob_95_00_ndvi")) %>%
ggplot(aes(x = year)) +
geom_boxplot(aes(y = NDVI_val, group = year),
size = 1,
color = ndvicolor) +
geom_line(aes(y = monthly_msl), size = 1.5, color = MLSLRcolor) +
scale_y_continuous(
name = "NDVI Values from Marshes Exsisting in 1995 to 2000",
sec.axis = sec_axis(trans = ~ . * 1, name = "Mean Local SLR")) +
ggtitle("Mean Local SLR Compared to NDVI Times Series") +
theme_test(
base_size = 15,
base_family = "",
base_rect_size = 0.5
) +
theme(
strip.text = element_text(size = 10, face = "bold"),
axis.title.y = element_text(
color = ndviTXTcolor95_00 ,
size = 13,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.y.right = element_text(
size = 13,
color = MLSLRtxtColor95_00 ,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.x = element_text(size = 13, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)),
plot.title = element_text(size = 15, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
))
) +
facet_wrap( ~ roi_marsh,
labeller = labeller(roi_marsh = roi_marsh.labs2),
nrow = 3)
MLSLR_NDVI_95_00_bp

Boxplot
3
Plot of vegetation that grew in the red sites in 2019. Click the code
button to see how to change the colors and variable names.
ndvicolor19 <- "#d11e0a"
MLSLRcolor19 <- "#d49817"
ndviTXTcolor19 <- "#6b1207"
MLSLRtxtColor19 <- "#4f280a"
# New facet label names for dose variable
roi_marsh.labs3 <- c("Great South Bay", "Jamaica Bay", "South Oyster Bay")
names(roi_marsh.labs3) <- c("gsb19_ndvi", "jb19_ndvi", "sob19_ndvi")
# Create boxplots of Red NDVI distribution V.S. Sea Level Rise
MLSLR_NDVI_19_bp <- NDVI_ML_SLR_long %>%
filter(roi_marsh %in% c("gsb19_ndvi", "jb19_ndvi", "sob19_ndvi")) %>%
ggplot(aes(x = year)) +
geom_boxplot(aes(y = NDVI_val, group = year),
size = 1,
color = ndviTXTcolor19) +
geom_line(aes(y = monthly_msl), size = 1.5, color = MLSLRcolor) + # Divide by 10 to
scale_y_continuous(name = "NDVI Values from Marshes Exsisting in 2019",
sec.axis = sec_axis(trans = ~ . * 1, name = "Mean Local SLR")) +
ggtitle("Mean Local SLR Compared to NDVI Times Series") +
theme_test(
base_size = 15,
base_family = "",
base_rect_size = 0.5
) +
theme(
strip.text = element_text(size = 10, face = "bold"),
axis.title.y = element_text(
color = ndviTXTcolor19 ,
size = 13,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.y.right = element_text(
size = 13,
color = MLSLRtxtColor19 ,
margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)
),
axis.title.x = element_text(size = 13, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
)),
plot.title = element_text(size = 15, margin = margin(
t = 5,
r = 10,
b = 10,
l = 10
))
) +
facet_wrap( ~ roi_marsh,
labeller = labeller(roi_marsh = roi_marsh.labs3),
nrow = 3)
MLSLR_NDVI_19_bp

Exploring storm frequency data
The plots show how MLSLR increased overtime as the NDVI data
decreased in the blue and cyan ROI sites. These results are consistent
with the results of the correlation analysis. However, the last time
series plot shows the opposite out come. This indicates that the marshes
in the red ROI sites maybe resilient to sea level rise. Still, not all
blue and cyan ROI sites had a significant negative correlation between
NDVI values and MLSLR.
In this section we will further look into these sites and investigate
the impact of storm frequency on marsh island vegetation. Lets start by
reading in some storm frequency data acquired from NOAA’s storm event
database. Then lets evaluate the frequency of storm events over time in
a smoothed time series analysis plot.
subset_storms <- read.csv("Subset_storm_data.csv")
subset_storms <-clean_names(subset_storms)
Stormplot <- subset_storms%>%
filter(event_type_coarse %in% c("Heavy Rain", "Thunderstorm", "Flood"))%>%
group_by(event_type_coarse, begin_year)%>%
summarise(freq= n())
The plot below shows that there was a high frequency of thunderstorms
in 2009 and a high frequency of floods 2011. There also seemed to have
been some small storm event peaks in heavy rain and thunderstorms in
1997. With this information we can now continue with a regression
analysis to see if the relationship between NDVI and MLSLR changes after
adding storm frequency data to the analysis.
To see the code for the plots select the code button on
your right.
Time Series
Plot
Stormplot %>%
ggplot( aes(x=begin_year, y=freq,
group=event_type_coarse,
color= event_type_coarse)) +
#geom_line() +
geom_smooth(se=FALSE, size = 1.5)+
theme_minimal()+
theme(plot.title = element_text(size=15),
plot.subtitle = element_text(size = 13),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10, face="bold"),
strip.text = element_text(size = 112, face="bold"),
legend.text = element_text(size = 9),
legend.title = element_text(size = 9)) +
geom_vline(xintercept = 2009)+
geom_vline(xintercept = 2011)+
geom_vline(xintercept = 1997)+
labs(colour = "Reported Event Type")+
ylab("Number of Reported Storm Events")+
xlab( "Year")

Table
## # A tibble: 42 x 3
## # Groups: event_type_coarse [3]
## event_type_coarse begin_year freq
## <chr> <int> <int>
## 1 Flood 1997 2
## 2 Flood 1998 2
## 3 Flood 1999 3
## 4 Flood 2000 6
## 5 Flood 2001 5
## 6 Flood 2002 4
## 7 Flood 2003 6
## 8 Flood 2004 4
## 9 Flood 2005 1
## 10 Flood 2007 2
## # ... with 32 more rows
NDVI, MLSLR, storm frequency regression analysis
When comparing MLSLR data to NDVI values derived from cyan ROI sites
specifically in Jamaica bay and South Oyster Bay no significant
correlations was found. In this section we will continue with a
regression analysis to find out if the frequency of storm events impacts
the relationship between vegetation density and MLSLR data.
First lets read in storm event data that has been joined to both
MLSLR and NDVI data. We will then convert the storm data from character
to factor and run the linear model function on both site locations.
Storm_SLR_NDVI<- read_csv("Storm_SLR_NDVI_cyan.csv")
Storm_SLR_NDVI$event_type_coarse <- as.factor(Storm_SLR_NDVI$event_type_coarse)
class(Storm_SLR_NDVI$event_type_coarse)
## [1] "factor"
levels(Storm_SLR_NDVI$event_type_coarse)
## [1] "Flood" "Heavy Rain" "Thunderstorm"
To see the code for the plots select the code button on
your right.
Jamaica Bay
Summary Stats
This summary compares the NDVI values extracted from the Jamaica Bay
cyan ROI site to MLSLR and storm event type frequency.
MLR_jb_95_00_ndvi <-lm(jb_95_00_ndvi ~ monthly_msl + event_type_coarse, data = Storm_SLR_NDVI)
summary(MLR_jb_95_00_ndvi)
##
## Call:
## lm(formula = jb_95_00_ndvi ~ monthly_msl + event_type_coarse,
## data = Storm_SLR_NDVI)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.47603 -0.07626 0.03490 0.10515 0.43025
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.09526 0.01247 -7.641 4.28e-14 ***
## monthly_msl 0.48790 0.11076 4.405 1.15e-05 ***
## event_type_coarseHeavy Rain 0.03428 0.05388 0.636 0.525
## event_type_coarseThunderstorm -0.04767 0.01077 -4.425 1.05e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1839 on 1252 degrees of freedom
## (25 observations deleted due to missingness)
## Multiple R-squared: 0.02866, Adjusted R-squared: 0.02634
## F-statistic: 12.32 on 3 and 1252 DF, p-value: 6.085e-08
South
Oyster Bay Summary Stats
This summary compares the NDVI values extracted from the South Oyster
Bay cyan ROI site to MLSLR and storm event type frequency.
MLR_sob_95_00_ndvi <-lm(sob_95_00_ndvi ~ monthly_msl + event_type_coarse, data = Storm_SLR_NDVI)
summary(MLR_sob_95_00_ndvi)
##
## Call:
## lm(formula = sob_95_00_ndvi ~ monthly_msl + event_type_coarse,
## data = Storm_SLR_NDVI)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.40599 -0.12049 0.03499 0.12451 0.46352
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.02748 0.01528 -1.799 0.07254 .
## monthly_msl 0.36096 0.13358 2.702 0.00707 **
## event_type_coarseHeavy Rain 0.12287 0.06564 1.872 0.06167 .
## event_type_coarseThunderstorm -0.03413 0.01282 -2.662 0.00796 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1585 on 646 degrees of freedom
## (631 observations deleted due to missingness)
## Multiple R-squared: 0.02659, Adjusted R-squared: 0.02207
## F-statistic: 5.882 on 3 and 646 DF, p-value: 0.0005783
Regression
analysis discussion
Notice that both analyses have significant p-values but R-squared
values that are < than 0.5. This means that there is no relationship
between vegetation density, MLSLR, and storm event type frequency at
these specific sites. Other environmental or anthropogenic factors could
be impacting the relationship between MLSLR and marsh island vegetation
density at specific locations and sites throughout Queens and Long
Islands South bay. Still, the analyses conducted through out this
notebook show how tidal wetlands are losing vegetation at accelerating
rates at other sites through out Long Island and are not keeping up with
climate change-derived MLSLR.
LS0tDQp0aXRsZTogImByIGh0bWx0b29sczo6SFRNTCgnPGgxPkRhdGEgQW5hbHlzaXMgb2YgTkRWSSAoVmVnZXRhdGlvbiBkZW5zaXR5IGRhdGEgZXh0cmFjdGVkIGZyb20gUk9JIHNhdGVsaXRlIGltYWdlcyksIG1lYW4gbG9jYWwgc2VhIGxldmVsIHJpc2UgZGF0YSBmcm9tIHRoZSBiYXR0ZXJ5IE4uWS4sIGFuZCBzdG9ybSBldmVudCBmcmVxdWVuY3kgZGF0YS4gPC9oMT4nKWAiDQphdXRob3I6ICJIZWxlbiBQb2xhbmNvIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdGhlbWU6IHBhcGVyDQogICAgaGlnaGxpZ2h0OiBlc3ByZXNzbw0KICAgICNjc3M6ICJzdHlsZXMuY3NzIiB0aGlzIGlzIGFuIG9wdGlvbiBpZiB5b3UgZG9uJ3Qgd2FudCB0byBoYXZlIGEgY3NzIGNvZGUgICAgIGNodW5rIGluIHlvdXIgbm90ZWJvb2suDQotLS0NCmBgYHtjc3MgZm9ybWF0dGluZywgZWNobz1GQUxTRX0NCg0KaDEgew0KICAgICBmb250LXNpemU6IDI1cHg7DQogICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgICBmb250LWZhbWlseTogSGVsdmV0aWNhOw0KICAgICBjb2xvcjogIzM0MzQzNDsNCiB9DQogaDIgew0KICAgICBmb250LXNpemU6IDE1cHg7DQogICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgICBmb250LWZhbWlseTogSGVsdmV0aWNhOw0KICAgICBjb2xvcjogIzM0MzQzNDsNCg0KIH0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfa25pdCRzZXQoIkM6L1VzZXJzL0hlbGVuIFBvbGFuY28vT25lRHJpdmUvRG9jdW1lbnRzL21hcnNoX21hcmtkb3duIikNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQotLS0NCmtuaXQ6ICAoZnVuY3Rpb24oaW5wdXRGaWxlLCBlbmNvZGluZykgeyBvdXRfZGlyIDwtICdkb2NzJzsgcm1hcmtkb3duOjpyZW5kZXIoaW5wdXRGaWxlLCBlbmNvZGluZz1lbmNvZGluZywgb3V0cHV0X2ZpbGU9ZmlsZS5wYXRoKGRpcm5hbWUoaW5wdXRGaWxlKSwgb3V0X2RpciwgJ2luZGV4Lmh0bWwnKSkgfSkNCi0tLQ0KIyMgX19JbnRyb2R1Y3Rpb246X18NCg0KX19fQmUgc3VyZSB0byB0b2dnbGUgdGhlIGNvZGUgYnV0dG9ucyBsb2NhdGVkIG9uIHRoZSBmYXIgcmlnaHQgb2YgdGhlIHBhZ2UgYXMgeW91IHJlYWQgYWxvbmchIHlvdSBjYW4gYWxzbyBkb3dubG9hZCB0aGUgUk1EIGJ5IGNsaWNraW5nIHRoZSBjb2RlIGJ1dHRvbiBhdCB0aGUgdmVyeSB0b3Agb2YgdGhlIHBhZ2UuX19fICANCg0KVGhlIGFuYWx5c2lzIGRlbW9uc3RyYXRlZCBpbiB0aGlzIHR1dG9yaWFsIGlzIHBhcnQgb2YgYSBbdHdvIHBhcnQgc3R1ZHldKGh0dHBzOi8vZ2l0aHViLmNvbS9wb2xhbmNoMTkwL0dFRS1TcGF0aWFsLVRlbXBvcmFsLUFuYWx5c2lzLW9mLUNoYW5nZXMtaW4tTWFyc2gtVmVnZXRhdGlvbi1EZW5zaXR5LS9ibG9iL21haW4vQ29sb3JfY29tcG9zaXRlX0ltYWdlX05CLmlweW5iKSBpbiB3aGljaCBkYXRhIHdhcyBpbml0aWFsbHkgZXh0cmFjdGVkIGZyb20gc2F0ZWxsaXRlIGltYWdlcnkgaW4gYSByZW1vdGUgc2Vuc2luZyBhbmFseXNpcy5UaGUgaW5pdGlhbCBzdHVkeSBoeXBvdGhlc2l6ZWQgdGhhdCB0aGUgYWNjZWxlcmF0aW9uIG9mIHNlYSBsZXZlbCByaXNlIGFuZCBpbmNyZWFzZWQgc3Rvcm0gZnJlcXVlbmN5IGFyZSBpbmZsdWVuY2luZyB0aGUgZGlzYXBwZWFyYW5jZSBvZiBtYXJzaCB2ZWdldGF0aW9uIGluIExvbmcgSXNsYW5k4oCZcyBTb3V0aCBTaG9yZSBFc3R1YXJ5LiBUaGUgZXh0cmFjdGVkIHNhdGVsbGl0ZSBpbWFnZXJ5IGRhdGEgd2lsbCBiZSB1c2VkIHRvIGV2YWx1YXRlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBMb25nIElzbGFuZCdzIHZlZ2V0YXRpb24gZGVuc2l0eSAoTkRWSSksIG1lYW4gbG9jYWwgc2VhIGxldmVsIHJpc2UsIGFuZCBzdG9ybSBldmVudHMgZnJlcXVlbmN5IG92ZXIgdGltZS4gQmFzaWMgc3RhdGlzdGljYWwgdGVzdHMgd2lsbCBiZSB1c2VkIHRvIGV2YWx1YXRlIHRoZXNlIHJlbGF0aW9uc2hpcHMgYnkgZG9pbmcgdGhlIGZvbGxvd2luZyBhbmFseXNpczoNCg0KMS4gTm9ybWFsaXR5IHRlc3RpbmcNCjMuIFBsb3R0aW5nIHRoZSBkYXRhIGluIGEgZHVhbCBheGlzIHRpbWUgc2VyaWVzIHBsb3QgDQo0LiBDb3JyZWxhdGlvbiB0ZXN0aW5nIHVzaW5nIFNwZWFybWFuJ3MgUmhvIA0KNi4gQSBiYXNpYyBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcw0KDQojIyBfX0JhY2tncm91bmQgb24gcmVtb3RlIHNlbnNpbmcgYW5hbHlzaXNfXyB7LnRhYnNldH0NCg0KX19fQ2xpY2sgdGhlIHRhYnMgYmVsb3cgdG8gcmV2aWV3IHRoZSByZXN1bHRzIG9mIGEgcmVtb3RlIHNlbnNpbmcgY29sb3IgaW1hZ2UgYW5hbHlzaXMuX19fIA0KDQoNClNob3duIGJlbG93LCBpcyB0aGUgY29tcG9zaXRlIHNhdGVsbGl0ZSBpbWFnZSB0aGF0IHdhcyBjcmVhdGVkIHRvIGV4dHJhY3QgdGhlIExvbmcgSXNsYW5kIHZlZ2V0YXRpb24gZGVuc2l0eSBkYXRhIHVzZWQgaW4gdGhlIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGluIHRoaXMgdHV0b3JpYWwuIFRoaXMgc2luZ2xlIGNvbG9yIGltYWdlIGlzIGNvbXBvc2VkIG9mIHRocmVlIG5vcm1hbGl6ZWQgZGlmZmVyZW5jZSB2ZWdldGF0aW9uIGluZGV4IGltYWdlcyAoTkRWSSkgY3JlYXRlZCBpbiB0aGUgaW5pdGlhbCBzdHVkeS5UaGlzIGNvbG9yIGltYWdlIGRpc3BsYXlzIHRoZSB2ZWdldGF0aW9uIGRlbnNpdHkgaW4gYW4gYXJlYSBmb3IgYSBnaXZlbiB5ZWFyLiBTcGVjaWZpY2FsbHksZWFjaCBwcmltYXJ5IGNvbG9yIHJlcHJlc2VudHMgYSBzaW5nbGUgeWVhciBjb250YWluaW5nIHZlZ2V0YXRpb24uIEEgc2Vjb25kYXJ5IGNvbG9yIHJlcHJlc2VudHMgdGhlIHByZXNlbmNlcyBvZiB2ZWdldGF0aW9uIHRocm91Z2hvdXQgbXVsdGlwbGUgeWVhcnMuIEZvciBleGFtcGxlIHJlZCBzcG90cyBzaG93IHdoZXJlIHZlZ2V0YXRpb24gb25seSBncmV3IGluIDIwMTksIGJsdWUgc3BvdHMgc2hvdyBvbmx5IHdoZXJlIHZlZ2V0YXRpb24gZ3JldyBpbiAxOTk1LCBhbmQgY3lhbiBzcG90cyBzaG93IG9ubHkgd2hlcmUgdmVnZXRhdGlvbiBncmV3IHRocm91Z2ggb3V0IHRoZSB5ZWFycyAxOTk1IGFuZCAyMDAwLg0KDQpGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgbWV0aG9kcyBhbmQgb3V0IGNvbWUgb2YgdGhlIGVudGlyZSBzdHVkeSBmZWVsIGZyZWUgdG8gcmVhZCB0aGUgW2V4ZWN1dGl2ZSBzdHVkeV0oaHR0cHM6Ly9naXRodWIuY29tL3BvbGFuY2gxOTAvR0VFLVNwYXRpYWwtVGVtcG9yYWwtQW5hbHlzaXMtb2YtQ2hhbmdlcy1pbi1NYXJzaC1WZWdldGF0aW9uLURlbnNpdHktL2Jsb2IvbWFpbi9UaGVzaXNFeGVjdXRpdmVTdW1tYXJ5X1VwZGF0ZWRBbmFseXNpcy5wZGYpLg0KDQoNCiMjIyBfX0phbWFpY2EgQmF5IENvbG9yIEltYWdlX18NCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9JzEwMCUnLCBpbmNsdWRlPVRSVUV9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygnLi9ST0lzX2luX0pCYXkuUE5HJykNCmBgYA0KDQojIyMgX19Tb3V0aCBPeXN0ZXIgQmF5IENvbG9yIEltYWdlX18NCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9JzEwMCUnLCBpbmNsdWRlPVRSVUV9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygnLi9ST0lzX2luX1NPQi5QTkcnKQ0KYGBgDQoNCiMjIyBfX0dyZWF0IFNvdXRoIEJheSBDb2xvciBJbWFnZV9fDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPScxMDAlJywgaW5jbHVkZT1UUlVFfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoJy4vUk9Jc19pbl9HU0IuUE5HJykNCmBgYA0KDQoNCiMjIF9fQWJvdXQgdGhlIGRhdGFfXw0KDQpUaGUgc3Rvcm0gZXZlbnQgZGF0YSB1c2VkIGluIHRoaXMgdHV0b3JpYWwgYXJlIGF2YWlsYWJsZSBvbiBbTk9BQSdzIHN0b3JtIGV2ZW50IGRhdGFiYXNlXShodHRwczovL3d3dy5uY2RjLm5vYWEuZ292L3N0b3JtZXZlbnRzL2Z0cC5qc3ApLiBNZWFuIExvY2FsIHNlZSBsZXZlbCByaXNlIGRhdGEgY2FuIGJlIGZvdW5kIG9uIA0KW05PQUEncyB0aWRlcyBhbmQgY3VycmVudHMgd2VicGFnZV0oaHR0cHM6Ly90aWRlc2FuZGN1cnJlbnRzLm5vYWEuZ292L3NsdHJlbmRzL3NsdHJlbmRzX3N0YXRpb24uc2h0bWw/aWQ9ODUxODc1MCkuVGhlIE5EVkkgZGF0YSB1c2VkIGluIHRoaXMgdHV0b3JpYWwgd2FzIGV4dHJhY3RlZCBmcm9tIHNhdGVsbGl0ZSBpbWFnZXJ5LiBTYXRlbGxpdGUgaW1hZ2VyeSBkYXRhIGFyZSBhY2Nlc3NpYmxlIG9uIFtHb29nbGUgRWFydGggRW5naW5lJ3MgZGF0YSBjYXRhbG9nXShodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9lYXJ0aC1lbmdpbmUvZGF0YXNldHMvY2F0YWxvZy9sYW5kc2F0KS5UbyBsZWFybiBob3cgdG8gdXNlIEdvb2dsZSBFYXJ0aCBFbmdpbmUncyBweXRob24gYXBpIHRvIGV4dHJhY3QgTkRWSSBkYXRhIGZyb20gc2F0ZWxsaXRlIGltYWdlcyBwbGVhc2UgdmlzaXQgW3RoaXNdKGh0dHBzOi8vZ2l0aHViLmNvbS9wb2xhbmNoMTkwL0dFRS1TcGF0aWFsLVRlbXBvcmFsLUFuYWx5c2lzLW9mLUNoYW5nZXMtaW4tTWFyc2gtVmVnZXRhdGlvbi1EZW5zaXR5LS9ibG9iL21haW4vQ29sb3JfY29tcG9zaXRlX0ltYWdlX05CLmlweW5iKSB0dXRvcmlhbC4gDQoNCg0KIyMgX19SZWFkaW5nIGluIGxpYnJhcmllcyBhbmQgb3JnYW5pemluZyBkYXRhX18NCg0KTGV0J3MgYmVnaW4gb3VyIGFuYWx5c2lzIHdpdGggcmVhZGluZyBpbiBzb21lIG5lY2Vzc2FyeSBsaWJyYXJpZXMgYXMgd2VsbCBhcyByZWFkaW5nIGluIGFuZCBvcmdhbml6aW5nIG1lYW4gbG9jYWwgc2VhIGxldmVsIHJpc2UgKE1MU0xSKSBkYXRhLg0KYGBge3IgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGhyYnJ0aGVtZXMpDQpsaWJyYXJ5KHRpZHlxdWFudCkNCg0KbWVhbkxfU0xSIDwtcmVhZF9jc3YoIlRoZUJhdHRlcnlfbWVhblNMdHJlbmRfdHJpbTIuY3N2IikNCiNvcmdhbml6ZSBhbmQgY2xlYW4gTUxTTFIgZGF0YQ0KbWVhbkxfU0xSPC0gY2xlYW5fbmFtZXMobWVhbkxfU0xSKQ0KbWVhbkxfU0xSPC0gcmVuYW1lKG1lYW5MX1NMUiwgbW9udGggPSBzbHJfbW9udGgpDQpgYGANCg0KTm93IGxldHMgcmVhZCBpbiB0aGUgTkRWSSAoc2F0ZWxsaXRlIG9idGFpbmVkIHZlZ2V0YXRpb24gZGVuc2l0eSBkYXRhKSBhbmQgb3JnYW5pemUgaXQuIERhdGEgZnJvbSBuaW5lIHJlZ2lvbiBvZiBpbnRlcmVzdHMgKFJPSSBzaXRlcykgd2VyZSBleHRyYWN0ZWQgZnJvbSB0aGUgY29sb3IgaW1hZ2UgaW4gR0VFLiBUaGVyZWZvcmUsIHdlIHdpbGwgbmVlZCB0byByZWFkIGluIG5pbmUgQ1NWIGZpbGUuIFRvIHJlYWQgdGhlIGZpbGVzIGluIG1vcmUgZWZmaWNpZW50bHksIGEgZnVuY3Rpb24gdGhhdCByZWFkcyBpbiBhbGwgZmlsZXMgYW5kIG1lcmdlcyB0aGVtIGFsbCBpbnRvIG9uZSBkYXRhIGZyYW1lIHdpbGwgYmUgY3JlYXRlZC4gVGhlIGRhdGUgY29sdW1uIHdpbGwgdGhlbiBiZSBjb252ZXJ0ZWQgdG8geXl5eS1tbS1kZCBhbmQgdGhlIHllYXIsIG1vbnRoIGFuZCBkYXkgd2lsbCBiZSBleHRyYWN0ZWQgZnJvbSB0aGUgbmV3IGRhdGUgY29sdW1uIHRvIGEgbmV3IGNvbHVtbnMuICANCmBgYHtyLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93JywgZWNobz1UUlVFLCBpbmNsdWRlPVRSVUUsIG1lc3NhZ2U9IEZBTFNFfQ0KDQptdWx0aV9tZXJnZTIgPSBmdW5jdGlvbihteXBhdGgpew0KICBmaWxlbmFtZXM9bGlzdC5maWxlcyhwYXRoPW15cGF0aCxmdWxsLm5hbWVzPVRSVUUpDQogIGRhdGFsaXN0ID0gbGFwcGx5KGZpbGVuYW1lcywgcmVhZF9jc3YpDQogIFJlZHVjZShmdWxsX2pvaW4sIGRhdGFsaXN0KX0NCg0KTkRWSV9kYXRhIDwtIG11bHRpX21lcmdlMigiU1JfdGltZXNlcmllc19GaW5hbCIpDQoNCiNvcmdhbml6ZS8gY2xlYW4vIHJlY2xhc3NpZnkgYW5kIHJlbmFtZSBjb2x1bW5zIE5EVkkgdGhlIGRhdGENCg0KTkRWSV9kYXRhIDwtIGNsZWFuX25hbWVzKE5EVklfZGF0YSkNCg0KTkRWSV9kYXRhIDwtIHJlbmFtZShORFZJX2RhdGEsIGRhdGUgPSBzeXN0ZW1fdGltZV9zdGFydCkNCg0KTkRWSV9kYXRhJGRhdGU8LSBsdWJyaWRhdGU6Om1keShORFZJX2RhdGEkZGF0ZSkgDQoNCk5EVklfZGF0YSA8LSBORFZJX2RhdGEgJT4lDQogIGRwbHlyOjptdXRhdGUoeWVhciA9IGx1YnJpZGF0ZTo6eWVhcihkYXRlKSwNCiAgICAgICAgICAgICAgICBtb250aCA9IGx1YnJpZGF0ZTo6bW9udGgoZGF0ZSksDQogICAgICAgICAgICAgICAgZGF5ID0gbHVicmlkYXRlOjpkYXkoZGF0ZSkpDQoNCmBgYA0KDQojIyBfX0RhdGEgZXhwbG9yYXRpb24gYW5kIG5vcm1hbGl0eSB0ZXN0aW5nX18gey50YWJzZXR9IA0KDQpOb3cgbGV0J3MgaW5zcGVjdCB0aGUgZGF0YS4gTm90ZSBob3cgdGhlcmUgYXJlIDI2IG9ic2VydmF0aW9ucyBpbiB0aGUgTUxTTFIgZGF0YSBhbmQgdGhlcmUgYXJlIDcyIG9ic2VydmF0aW9uIGluIHRoZSBORFZJIGRhdGEuDQoNCmBgYHtyLGNsYXNzLnNvdXJjZSA9ICdmb2xkLXNob3cnLGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFfQ0KbGVuZ3RoKCFpcy5uYShtZWFuTF9TTFIkbW9udGhseV9tc2wpKSANCg0KbGVuZ3RoKCFpcy5uYShORFZJX2RhdGEkZ3NiOTVfbmR2aSkpDQpgYGANCg0KQmVmb3JlIHdlIHJ1biBub3JtYWxpdHkgdGVzdGluZyBvbiB0aGUgTUxTTFIgYW5kIE5EVkkgZGF0YSwgd2Ugd2lsbCBqb2luIHRoZSBkYXRhIHRvZ2V0aGVyLiBUaGlzIGlzIGJlY2F1c2Ugd2Ugd2FudCB0byBjb3JyZWN0bHkgYXNzZXNzIHRoZSBkaXN0cmlidXRpb24gb2YgYWxsIHRoZSBkYXRhIHRvIGNob29zZSB0aGUgY29ycmVjdCBjb3JyZWxhdGlvbiB0ZXN0IHdoZW4gYW5hbHl6aW5nIGZvciB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdmVnZXRhdGlvbiBkZW5zaXR5IGFuZCBNTFNMUi4gTm9ybWFsaXR5IHRlc3RpbmcgY2FuIGJlIGNvbmR1Y3RlZCB1c2luZyB0aGUgV2lsayBTaGFwaXJvIHRlc3QuIFdlIGNhbiBhbmFseXplIHRoZSBub3JtYWxpdHkgb2YgdGhlIE5EVkkgZGF0YSBmb3IgZWFjaCBST0kgc2l0ZSBhbmQgdmlzdWFsaXplIHRoZSBkYXRhIGluIGEgaGlzdG9ncmFtIG9uZSBieSBvbmUgYXMgc2hvd24gYmVsb3cuICAgDQoNCmBgYHtyLGNsYXNzLnNvdXJjZSA9ICdmb2xkLXNob3cnLGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFfQ0KTkRWSV9NTF9TTFIgPC0gTkRWSV9kYXRhICU+JQ0KICBsZWZ0X2pvaW4obWVhbkxfU0xSLA0KICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiA9ICJ5ZWFyIiwgIm1vbnRoIiA9ICJtb250aCIpKSAlPiUNCiAgYXJyYW5nZSh5ZWFyKQ0KYGBgDQpfX19DbGljayB0aGUgdGFicyBiZWxvdyB0byBzZWUgdGhlIHJlc3VsdHMgb2YgdGhlIG5vcm1hbGl0eSB0ZXN0Ll9fXw0KDQojIyMgX19QbG90X19fDQpgYGB7cn0NCmhpc3QoTkRWSV9NTF9TTFIkZ3NiXzk1XzAwX25kdmksIA0KICAgICBtYWluID0iSGlzdG9ncmFtIG9mIFZlZ2V0YXRpb24gRGVuc2l0eSBWYWx1ZXMgKE5EVkkpIGluIEdyZWF0IFNvdXRoIGJheSAxOTk1IiwNCiAgICAgeGxhYiA9ICJORFZJIHZhbHVlcyIsDQogICAgIHlsYWIgPSAiRnJlcXVlbmN5IikNCg0KYGBgDQoNCiMjIyBfX1Jlc3VsdCBTdW1tYXJ5IFZhbHVlc19fDQpgYGB7cn0NCnNoYXBpcm8udGVzdChORFZJX01MX1NMUiRnc2JfOTVfMDBfbmR2aSkgI21lYW5MX1NMUiRtb250aGx5X21zbA0KYGBgDQoNCiMjIyBfX1RhYmxlX18NCmBgYHtyfQ0KTkRWSV9NTF9TTFINCmBgYA0KDQpIT1dFVkVSLCB0aGlzIHdvdWxkIHRha2UgYWxvbmcgdGltZS4gSW5zdGVhZCB3ZSB3aWxsIG9yZ2FuaXplIHRoZSBkYXRhIHNvIHRoYXQgd2UgY2FuIGxvb3AgdGhlIHRlc3Qgb3ZlciB0aGUgZGF0YSBzZXQuIE91ciBjdXJyZW50IHRhYmxlIGhhcyBzb21lIGNvbHVtbnMgdGhhdCB3ZSBkb24ndCB3YW50IHRvIGFwcGx5IHRoZSBzaGFwaXJvIHRlc3Qgb24uIFRvIGZpeCB0aGlzLCB3ZSB3aWxsIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSBhbmQgZHJvcCB0aGUgY29sdW1ucyB3ZSBkb24ndCB3YW50IGZyb20gdGhlIG9yaWdpbmFsIHRhYmxlIHRoZW4gYXBwbHkgdGhlIHNoYXBpcm8gdGVzdCB0byB0aGUgbmV3IHRhYmxlLiBUaGVuIHdlIHdpbGwgaGF2ZSBhIGxpc3Qgb2YgdGVzdCByZXN1bHRzIHNob3dpbmcgaG93IHNvbWUgZGF0YSBhcmUgc2tld2VkLg0KDQpgYGB7ciwgZWNobz1UUlVFLCBpbmNsdWRlPVRSVUV9DQoNCk5vcm1hbGxpdHlfdGVzdHMgPC0gTkRWSV9NTF9TTFIgJT4lDQogIHNlbGVjdChjKGpiMTlfbmR2aSxqYl85NV8wMF9uZHZpLCBqYjk1X25kdmkpKSU+JQ0KICBhcHBseSgyLHNoYXBpcm8udGVzdCkNCg0KTm9ybWFsbGl0eV90ZXN0cyANCg0KYGBgDQoNCg0KIyMgX19Db3JyZWxhdGlvbiBiZXR3ZWVuIE5EVkkgYW5kIE1MU0xSX18gey50YWJzZXR9DQoNCkFzIHdlIHNhdywgc29tZSBvZiB0aGUgZGF0YSBpbiB0aGUgZGF0YSBmcmFtZSBhcmUgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBXZSBjYW4gY2hvb3NlIFNwZWFybWFuJ3MgUmhvIGJlY2F1c2UgaXQgaXMgYSByb2J1c3QgYW5hbHlzaXMgYW5kIGRvZXNuJ3QgcmVxdWlyZSBub3JtYWxseSBkaXN0cmlidXRlZCBkYXRhLiBXZSBjYW4gbm93IGNyZWF0ZSBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBsb29wIG92ZXIgdGhlIGRhdGEgc2V0IGFuZCBydW4gdGhlIGNvcnJlbGF0aW9uIHRlc3QuIA0KDQoNCkxldHMgYmVnaW4gdGhlIHByb2Nlc3MgYnkgc3Vic2V0dGluZyB0aGUgZGF0YSB1c2luZyB0aGUgc2VsZWN0IGZ1bmN0aW9uLiBUaGlzIHdpbGwgcmVtb3ZlIGFueSBjb2x1bW5zIHlvdSBkb24ndCBuZWVkIHRvIGluY2x1ZGUgaW4geW91ciBjb3JyZWxhdGlvbi4gSW4gdGhpcyBzZWN0aW9uIHdlIHdpbGwgY3JlYXRlIGEgZnVuY3Rpb24gdGhhdCBjb21wYXJlcyBtZWFuIGxvY2FsIHNlYSBsZXZlbCByaXNlIGRhdGEgKHkpIHRvIGFsbCB4J3MgKG90aGVyX3ZhcikgYnkgdXNpbmcgdGhlIGFwcGx5IGZ1bmN0aW9uIHRvIHJ1biBTcGVhcm1hbidzIFJobyBvdmVyIGFsbCB0aGUgZGF0YS4NCg0KIyMjIF9fQ29kZV9fDQpgYGB7ciwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycgLGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgcmVzdWx0cz0naGlkZSd9DQpTdWJORFZJX21sc3IgPC0gTkRWSV9NTF9TTFIgJT4lDQogIHNlbGVjdChjKGdzYl85NV8wMF9uZHZpLCBnc2I5NV9uZHZpLCBtb250aGx5X21zbCkpDQoNCmNvcl90ZXN0X2xvb3AgPC0gZnVuY3Rpb24oZGF0YSwgeSkgew0KICByZXR1cm4oYXBwbHkoDQogICAgZGF0YSwNCiAgICAyLA0KICAgIEZVTiA9IGZ1bmN0aW9uIChvdGhlcl92YXIpIHsNCiAgICAgIHJldHVybihjb3IudGVzdChvdGhlcl92YXIsIGRhdGFbW3ldXSwgZGF0YSA9IGRhdGEsIG1ldGhvZCA9ICJzcGVhcm1hbiIpKQ0KICAgIH0NCiAgKSkNCn0NCg0KI2Nvcl90ZXN0X2xvb3AoU3ViTkRWSV9tbHNyLCJtb250aGx5X21zbCIpDQoNCmBgYA0KDQojIyMgX19SZXN1bHQgU3VtbWFyeSBWYWx1ZXNfXw0KYGBge3IsIGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRX0NCmNvcl90ZXN0X2xvb3AoU3ViTkRWSV9tbHNyLCJtb250aGx5X21zbCIpDQoNCmBgYA0KDQoNCg0KIyMgX19QbG90dGluZyBORFZJIHZzIE1MU0xSX18gey50YWJzZXR9DQoNClRoZSBjb3JyZWxhdGlvbiBhbmFseXNpcyByZXZlbGVkIHRoYXQgdGhlcmUgaXMgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdmVnZXRhdGlvbiBkZW5zaXR5IChORFZJIHZhbHVlcykgaW4gUXVlZW5zLCBMb25nIElzbGFuZCBTb3V0aCBCYXksIGFuZCBNTFNMUi4gSW4gdGhpcyBzZWN0aW9uIHdlIHdpbGwgc2VlIGlmIHRoZSB2ZWdldGF0aW9uIGluIGVhY2ggbG9jYXRpb24gaGFzIGtlcHQgZ3Jvd2luZyBvdmVyIHRpbWUgZGVzcGl0ZSB0aGUgcmlzZSBpbiBzZWEgbGV2ZWwuIFRvIHNob3cgdGhpcywgd2Ugd2lsbCBjb21wYXJlIHRoZSBORFZJIHZhbHVlcyB0byBNTFNMUiBkYXRhIGJ5IGNyZWF0aW5nIGEgZHVhbCBheGlzIGJveCBwbG90IGFuZCBsaW5lIGdyYXBoIHRpbWUgc2VyaWVzIGFuYWx5c2lzLlRoaXMgd2lsbCBoZWxwIHVzIHZpc3VhbGl6ZSB0aGUgY29ycmVsYXRpb24gcmVzdWx0cy4gVG8gc3RhcnQsIGxldHMgdGFrZSB0aGUgam9pbmVkIE5EVkkgYW5kIE1MU0xSIGRhdGEgZnJhbWUgYW5kIG1ha2UgaXQgbG9uZy4gDQoNCg0KDQpgYGB7cixlY2hvPVRSVUUsIGluY2x1ZGU9VFJVRSwgY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdyd9DQoNCk5EVklfTUxfU0xSX2xvbmcgPC0gTkRWSV9NTF9TTFIgICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGNvbnRhaW5zKCJuZHZpIiksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJyb2lfbWFyc2giLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIk5EVklfdmFsIiklPiUNCiAgZmlsdGVyKCFpcy5uYSgicm9pX21hcnNoIikmDQogICAgICAgICAgICFpcy5uYSgiTkRWSV92YWwiKSkNCmBgYA0KDQpfX19UbyBzZWUgdGhlIGNvZGUgZm9yIHRoZSBwbG90cyBzZWxlY3QgdGhlIGNvZGUgYnV0dG9uIG9uIHlvdXIgcmlnaHQuX19fDQoNCiMjIyBfX0JveHBsb3QgMV9fDQpQbG90IG9mIHZlZ2V0YXRpb24gdGhhdCBncmV3IGluIHRoZSBibHVlIHNpdGVzIG9uIHRoZSBtYXAgaW4gMTk5NSBibHVlIHNpdGUuIA0KYGBge3IsIGVjaG89IFRSVUUsIGNvbGxhcHNlID0gVFJVRSwgaW5jbHVkZT1UUlVFLHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gOH0NCg0KIyBDcmVhdGUgY3VzdG9tIGNvbG9ycyBmb3IgeW91ciBib3hwbG90IGdyYXBoDQoNCm5kdmljb2xvciA8LSAiIzE3YzFkNCINCk1MU0xSY29sb3IgPC0gIiNkNDk4MTciDQpuZHZpVFhUY29sb3I5NSA8LSAiIzBjNTk3MCINCk1MU0xSdHh0Q29sb3I5NSA8LSAiIzRmMjgwYSINCg0KIyBOZXcgZmFjZXQgbGFiZWwgbmFtZXMgZm9yIGRvc2UgdmFyaWFibGUNCnJvaV9tYXJzaC5sYWJzIDwtIGMoIkdyZWF0IFNvdXRoIEJheSIsICJKYW1haWNhIEJheSIsICJTb3V0aCBPeXN0ZXIgQmF5IikNCm5hbWVzKHJvaV9tYXJzaC5sYWJzKSA8LSBjKCJnc2I5NV9uZHZpIiwgImpiOTVfbmR2aSIsICJzb2I5NV9uZHZpIikNCg0KDQojI0NyZWF0ZSBib3hwbG90cyBvZiBCbHVlIE5EVkkgZGF0YSBkaXN0cmlidXRpb24gVi5TLiBNZWFuIExvY2FsIFNlYSBMZXZlbCBSaXNlDQoNCg0KTUxTTFJfTkRWSV85NV9icCA8LSBORFZJX01MX1NMUl9sb25nICU+JQ0KICBmaWx0ZXIocm9pX21hcnNoICVpbiUgYygiamI5NV9uZHZpIiwgInNvYjk1X25kdmkiLCAiZ3NiOTVfbmR2aSIpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhcikpICsNCiAgZ2VvbV9ib3hwbG90KGFlcyh5ID0gTkRWSV92YWwsIGdyb3VwID0geWVhciksDQogICAgICAgICAgICAgICBzaXplID0gMSwNCiAgICAgICAgICAgICAgIGNvbG9yID0gbmR2aWNvbG9yKSArDQogIGdlb21fbGluZShhZXMoeSA9IG1vbnRobHlfbXNsKSwgc2l6ZSA9IDEuNSwgY29sb3IgPSBNTFNMUmNvbG9yKSArDQogIHNjYWxlX3lfY29udGludW91cygjIEZlYXR1cmVzIG9mIHRoZSBmaXJzdCBheGlzDQogICAgbmFtZSA9ICJORFZJIFZhbHVlcyBmcm9tIE1hcnNoZXMgRXhzaXN0aW5nIGluIDE5OTUiLA0KICAgIA0KICAgICMgQWRkIGEgc2Vjb25kIGF4aXMgYW5kIHNwZWNpZnkgaXRzIGZlYXR1cmVzDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh0cmFucyA9ICB+IC4gKiAxLCBuYW1lID0gIk1lYW4gTG9jYWwgU0xSIikpICsNCiAgZ2d0aXRsZSgiTWVhbiBMb2NhbCBTTFIgQ29tcGFyZWQgdG8gTkRWSSBUaW1lcyBTZXJpZXMiKSArDQogIHRoZW1lX3Rlc3QoDQogICAgYmFzZV9zaXplID0gMTUsDQogICAgYmFzZV9mYW1pbHkgPSAiIiwNCiAgICBiYXNlX3JlY3Rfc2l6ZSA9IDAuNQ0KICApICsgI3RoaXMgY2hhbmdlcyB0aGUgdGV4dCBzaXplIG9mIHRoZSBudW1iZXJzIG9uIHRoZSB4eSBzY2FsZSBhbmQgdGhlIGZhY2V0IG5hbWVzDQogIHRoZW1lKA0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoDQogICAgICBjb2xvciA9IG5kdmlUWFRjb2xvcjk1ICwNCiAgICAgIHNpemUgPSAxMywNCiAgICAgIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgICAgdCA9IDUsDQogICAgICAgIHIgPSAxMCwNCiAgICAgICAgYiA9IDEwLA0KICAgICAgICBsID0gMTANCiAgICAgICkNCiAgICApLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsDQogICAgICBjb2xvciA9IE1MU0xSdHh0Q29sb3I5NSAsDQogICAgICBtYXJnaW4gPSBtYXJnaW4oDQogICAgICAgIHQgPSA1LA0KICAgICAgICByID0gMTAsDQogICAgICAgIGIgPSAxMCwNCiAgICAgICAgbCA9IDEwDQogICAgICApDQogICAgKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBtYXJnaW4gPSBtYXJnaW4oDQogICAgICB0ID0gNSwNCiAgICAgIHIgPSAxMCwNCiAgICAgIGIgPSAxMCwNCiAgICAgIGwgPSAxMA0KICAgICkpLA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBtYXJnaW4gPSBtYXJnaW4oDQogICAgICB0ID0gNSwNCiAgICAgIHIgPSAxMCwNCiAgICAgIGIgPSAxMCwNCiAgICAgIGwgPSAxMA0KICAgICkpDQogICkgKw0KICBmYWNldF93cmFwKCB+IHJvaV9tYXJzaCwNCiAgICAgICAgICAgICAgbGFiZWxsZXIgPSBsYWJlbGxlcihyb2lfbWFyc2ggPSByb2lfbWFyc2gubGFicyksDQogICAgICAgICAgICAgIG5yb3cgPSAzKQ0KDQpNTFNMUl9ORFZJXzk1X2JwDQpgYGANCg0KIyMjIF9fQm94cGxvdCAyX18NCg0KUGxvdCBvZiB2ZWdldGF0aW9uIHRoYXQgZ3JldyBpbiB0aGUgY3lhbiBzaXRlcyB0aHJvdWdoIG91dCB0aGUgeWVhcnMgMTk5NSB0byAyMDAwLkNsaWNrIHRoZSBjb2RlIGJ1dHRvbiB0byBzZWUgaG93IHRvIGNoYW5nZSB0aGUgY29sb3JzIGFuZCB2YXJpYWJsZSBuYW1lcw0KYGBgYGBge3IsIGVjaG89IFRSVUUsIGluY2x1ZGUgPSBUUlVFLGNvbGxhcHNlID0gVFJVRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSA4fQ0KbmR2aWNvbG9yIDwtICIjMDA4MDgwIg0KTUxTTFJjb2xvciA8LSAiI2Q0OTgxNyINCm5kdmlUWFRjb2xvcjk1XzAwIDwtICIjMWUzMzIxIg0KTUxTTFJ0eHRDb2xvcjk1XzAwIDwtICIjNGYyODBhIg0KDQojIE5ldyBmYWNldCBsYWJlbCBuYW1lcyBmb3IgZG9zZSB2YXJpYWJsZQ0Kcm9pX21hcnNoLmxhYnMyIDwtDQogIGMoIkdyZWF0IFNvdXRoIEJheSIsICJKYW1haWNhIEJheSIsICJTb3V0aCBPeXN0ZXIgQmF5IikNCm5hbWVzKHJvaV9tYXJzaC5sYWJzMikgPC0NCiAgYygiZ3NiXzk1XzAwX25kdmkiLCAiamJfOTVfMDBfbmR2aSIsICJzb2JfOTVfMDBfbmR2aSIpDQoNCiNmaWx0ZXIgYW5kIHBsb3QNCk1MU0xSX05EVklfOTVfMDBfYnAgPC0gTkRWSV9NTF9TTFJfbG9uZyAlPiUNCiAgZmlsdGVyKHJvaV9tYXJzaCAlaW4lIGMoImdzYl85NV8wMF9uZHZpIiwgImpiXzk1XzAwX25kdmkiLCAic29iXzk1XzAwX25kdmkiKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXIpKSArDQogIGdlb21fYm94cGxvdChhZXMoeSA9IE5EVklfdmFsLCBncm91cCA9IHllYXIpLA0KICAgICAgICAgICAgICAgc2l6ZSA9IDEsDQogICAgICAgICAgICAgICBjb2xvciA9IG5kdmljb2xvcikgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBtb250aGx5X21zbCksIHNpemUgPSAxLjUsIGNvbG9yID0gTUxTTFJjb2xvcikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoDQogICAgbmFtZSA9ICJORFZJIFZhbHVlcyBmcm9tIE1hcnNoZXMgRXhzaXN0aW5nIGluIDE5OTUgdG8gMjAwMCIsDQogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh0cmFucyA9ICB+IC4gKiAxLCBuYW1lID0gIk1lYW4gTG9jYWwgU0xSIikpICsNCiAgZ2d0aXRsZSgiTWVhbiBMb2NhbCBTTFIgQ29tcGFyZWQgdG8gTkRWSSBUaW1lcyBTZXJpZXMiKSArDQogIHRoZW1lX3Rlc3QoDQogICAgYmFzZV9zaXplID0gMTUsDQogICAgYmFzZV9mYW1pbHkgPSAiIiwNCiAgICBiYXNlX3JlY3Rfc2l6ZSA9IDAuNQ0KICApICsgDQogIHRoZW1lKA0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoDQogICAgICBjb2xvciA9IG5kdmlUWFRjb2xvcjk1XzAwICwNCiAgICAgIHNpemUgPSAxMywNCiAgICAgIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgICAgdCA9IDUsDQogICAgICAgIHIgPSAxMCwNCiAgICAgICAgYiA9IDEwLA0KICAgICAgICBsID0gMTANCiAgICAgICkNCiAgICApLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIHNpemUgPSAxMywNCiAgICAgIGNvbG9yID0gTUxTTFJ0eHRDb2xvcjk1XzAwICwNCiAgICAgIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgICAgdCA9IDUsDQogICAgICAgIHIgPSAxMCwNCiAgICAgICAgYiA9IDEwLA0KICAgICAgICBsID0gMTANCiAgICAgICkNCiAgICApLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgIHQgPSA1LA0KICAgICAgciA9IDEwLA0KICAgICAgYiA9IDEwLA0KICAgICAgbCA9IDEwDQogICAgKSksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgIHQgPSA1LA0KICAgICAgciA9IDEwLA0KICAgICAgYiA9IDEwLA0KICAgICAgbCA9IDEwDQogICAgKSkNCiAgKSArDQogIGZhY2V0X3dyYXAoIH4gcm9pX21hcnNoLA0KICAgICAgICAgICAgICBsYWJlbGxlciA9IGxhYmVsbGVyKHJvaV9tYXJzaCA9IHJvaV9tYXJzaC5sYWJzMiksDQogICAgICAgICAgICAgIG5yb3cgPSAzKQ0KDQpNTFNMUl9ORFZJXzk1XzAwX2JwDQpgYGANCg0KIyMjIF9fQm94cGxvdCAzX18NClBsb3Qgb2YgdmVnZXRhdGlvbiB0aGF0IGdyZXcgaW4gdGhlIHJlZCBzaXRlcyBpbiAyMDE5LiBDbGljayB0aGUgY29kZSBidXR0b24gdG8gc2VlIGhvdyB0byBjaGFuZ2UgdGhlIGNvbG9ycyBhbmQgdmFyaWFibGUgbmFtZXMuDQpgYGB7ciwgZWNobz0gVFJVRSwgaW5jbHVkZSA9IFRSVUUsY29sbGFwc2UgPSBUUlVFLCB3YXJuaW5nPUZBTFNFLCBlcnJvcj1GQUxTRSwgbWVzc2FnZT1GQUxTRSxmaWcuaGVpZ2h0ID0gMTAsIGZpZy53aWR0aCA9IDh9DQpuZHZpY29sb3IxOSA8LSAiI2QxMWUwYSINCk1MU0xSY29sb3IxOSA8LSAiI2Q0OTgxNyINCm5kdmlUWFRjb2xvcjE5IDwtICIjNmIxMjA3Ig0KTUxTTFJ0eHRDb2xvcjE5IDwtICIjNGYyODBhIg0KDQoNCiMgTmV3IGZhY2V0IGxhYmVsIG5hbWVzIGZvciBkb3NlIHZhcmlhYmxlDQpyb2lfbWFyc2gubGFiczMgPC0gYygiR3JlYXQgU291dGggQmF5IiwgIkphbWFpY2EgQmF5IiwgIlNvdXRoIE95c3RlciBCYXkiKQ0KbmFtZXMocm9pX21hcnNoLmxhYnMzKSA8LSBjKCJnc2IxOV9uZHZpIiwgImpiMTlfbmR2aSIsICJzb2IxOV9uZHZpIikNCg0KDQoNCiMgQ3JlYXRlIGJveHBsb3RzIG9mIFJlZCBORFZJIGRpc3RyaWJ1dGlvbiBWLlMuIFNlYSBMZXZlbCBSaXNlIA0KDQpNTFNMUl9ORFZJXzE5X2JwIDwtIE5EVklfTUxfU0xSX2xvbmcgJT4lDQogIGZpbHRlcihyb2lfbWFyc2ggJWluJSBjKCJnc2IxOV9uZHZpIiwgImpiMTlfbmR2aSIsICJzb2IxOV9uZHZpIikpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyKSkgKw0KICBnZW9tX2JveHBsb3QoYWVzKHkgPSBORFZJX3ZhbCwgZ3JvdXAgPSB5ZWFyKSwNCiAgICAgICAgICAgICAgIHNpemUgPSAxLA0KICAgICAgICAgICAgICAgY29sb3IgPSBuZHZpVFhUY29sb3IxOSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBtb250aGx5X21zbCksIHNpemUgPSAxLjUsIGNvbG9yID0gTUxTTFJjb2xvcikgKyAjIERpdmlkZSBieSAxMCB0bw0KICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJORFZJIFZhbHVlcyBmcm9tIE1hcnNoZXMgRXhzaXN0aW5nIGluIDIwMTkiLA0KICAgICAgICAgICAgICAgICAgICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh0cmFucyA9ICB+IC4gKiAxLCBuYW1lID0gIk1lYW4gTG9jYWwgU0xSIikpICsNCiAgZ2d0aXRsZSgiTWVhbiBMb2NhbCBTTFIgQ29tcGFyZWQgdG8gTkRWSSBUaW1lcyBTZXJpZXMiKSArDQogIHRoZW1lX3Rlc3QoDQogICAgYmFzZV9zaXplID0gMTUsDQogICAgYmFzZV9mYW1pbHkgPSAiIiwNCiAgICBiYXNlX3JlY3Rfc2l6ZSA9IDAuNQ0KICApICsNCiAgdGhlbWUoDQogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGZhY2UgPSAiYm9sZCIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIGNvbG9yID0gbmR2aVRYVGNvbG9yMTkgLA0KICAgICAgc2l6ZSA9IDEzLA0KICAgICAgbWFyZ2luID0gICAgIG1hcmdpbigNCiAgICAgICAgdCA9IDUsDQogICAgICAgIHIgPSAxMCwNCiAgICAgICAgYiA9IDEwLA0KICAgICAgICBsID0gMTANCiAgICAgICkNCiAgICApLA0KICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfdGV4dCgNCiAgICAgIHNpemUgPSAxMywNCiAgICAgIGNvbG9yID0gTUxTTFJ0eHRDb2xvcjE5ICwNCiAgICAgIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgICAgdCA9IDUsDQogICAgICAgIHIgPSAxMCwNCiAgICAgICAgYiA9IDEwLA0KICAgICAgICBsID0gMTANCiAgICAgICkNCiAgICApLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTMsIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgIHQgPSA1LA0KICAgICAgciA9IDEwLA0KICAgICAgYiA9IDEwLA0KICAgICAgbCA9IDEwDQogICAgKSksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIG1hcmdpbiA9IG1hcmdpbigNCiAgICAgIHQgPSA1LA0KICAgICAgciA9IDEwLA0KICAgICAgYiA9IDEwLA0KICAgICAgbCA9IDEwDQogICAgKSkNCiAgKSArDQogIGZhY2V0X3dyYXAoIH4gcm9pX21hcnNoLA0KICAgICAgICAgICAgICBsYWJlbGxlciA9IGxhYmVsbGVyKHJvaV9tYXJzaCA9IHJvaV9tYXJzaC5sYWJzMyksDQogICAgICAgICAgICAgIG5yb3cgPSAzKQ0KTUxTTFJfTkRWSV8xOV9icA0KYGBgDQoNCiMjIF9fRXhwbG9yaW5nIHN0b3JtIGZyZXF1ZW5jeSBkYXRhX197LnRhYnNldH0NCg0KVGhlIHBsb3RzIHNob3cgaG93IE1MU0xSIGluY3JlYXNlZCBvdmVydGltZSBhcyB0aGUgTkRWSSBkYXRhIGRlY3JlYXNlZCBpbiB0aGUgYmx1ZSBhbmQgY3lhbiBST0kgc2l0ZXMuIFRoZXNlIHJlc3VsdHMgYXJlIGNvbnNpc3RlbnQgd2l0aCB0aGUgcmVzdWx0cyBvZiB0aGUgY29ycmVsYXRpb24gYW5hbHlzaXMuIEhvd2V2ZXIsIHRoZSBsYXN0IHRpbWUgc2VyaWVzIHBsb3Qgc2hvd3MgdGhlIG9wcG9zaXRlIG91dCBjb21lLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBtYXJzaGVzIGluIHRoZSByZWQgUk9JIHNpdGVzIG1heWJlIHJlc2lsaWVudCB0byBzZWEgbGV2ZWwgcmlzZS4gU3RpbGwsIG5vdCBhbGwgYmx1ZSBhbmQgY3lhbiBST0kgc2l0ZXMgaGFkIGEgc2lnbmlmaWNhbnQgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBORFZJIHZhbHVlcyBhbmQgTUxTTFIuIA0KDQpJbiB0aGlzIHNlY3Rpb24gd2Ugd2lsbCBmdXJ0aGVyIGxvb2sgaW50byB0aGVzZSBzaXRlcyBhbmQgaW52ZXN0aWdhdGUgdGhlIGltcGFjdCBvZiBzdG9ybSBmcmVxdWVuY3kgb24gbWFyc2ggaXNsYW5kIHZlZ2V0YXRpb24uIExldHMgc3RhcnQgYnkgcmVhZGluZyBpbiBzb21lIHN0b3JtIGZyZXF1ZW5jeSBkYXRhIGFjcXVpcmVkIGZyb20gTk9BQSdzIHN0b3JtIGV2ZW50IGRhdGFiYXNlLiBUaGVuIGxldHMgZXZhbHVhdGUgdGhlIGZyZXF1ZW5jeSBvZiBzdG9ybSBldmVudHMgb3ZlciB0aW1lIGluIGEgc21vb3RoZWQgdGltZSBzZXJpZXMgYW5hbHlzaXMgcGxvdC4NCg0KDQpgYGB7cixlY2hvPVRSVUUsaW5jbHVlID1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBjbGFzcy5zb3VyY2UgPSAnZm9sZC1zaG93J30NCnN1YnNldF9zdG9ybXMgPC0gcmVhZC5jc3YoIlN1YnNldF9zdG9ybV9kYXRhLmNzdiIpIA0Kc3Vic2V0X3N0b3JtcyA8LWNsZWFuX25hbWVzKHN1YnNldF9zdG9ybXMpIA0KDQoNClN0b3JtcGxvdCA8LSAgc3Vic2V0X3N0b3JtcyU+JSANCiAgZmlsdGVyKGV2ZW50X3R5cGVfY29hcnNlICVpbiUgYygiSGVhdnkgUmFpbiIsICJUaHVuZGVyc3Rvcm0iLCAiRmxvb2QiKSklPiUNCiAgZ3JvdXBfYnkoZXZlbnRfdHlwZV9jb2Fyc2UsIGJlZ2luX3llYXIpJT4lDQogIHN1bW1hcmlzZShmcmVxPSBuKCkpDQoNCg0KYGBgDQoNClRoZSBwbG90IGJlbG93IHNob3dzIHRoYXQgdGhlcmUgd2FzIGEgaGlnaCBmcmVxdWVuY3kgb2YgdGh1bmRlcnN0b3JtcyBpbiAyMDA5IGFuZCBhIGhpZ2ggZnJlcXVlbmN5IG9mIGZsb29kcyAyMDExLiBUaGVyZSBhbHNvIHNlZW1lZCB0byBoYXZlIGJlZW4gc29tZSBzbWFsbCBzdG9ybSBldmVudCBwZWFrcyBpbiBoZWF2eSByYWluIGFuZCB0aHVuZGVyc3Rvcm1zIGluIDE5OTcuIFdpdGggdGhpcyBpbmZvcm1hdGlvbiB3ZSBjYW4gbm93IGNvbnRpbnVlIHdpdGggYSByZWdyZXNzaW9uIGFuYWx5c2lzIHRvIHNlZSBpZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gTkRWSSBhbmQgTUxTTFIgY2hhbmdlcyBhZnRlciBhZGRpbmcgc3Rvcm0gZnJlcXVlbmN5IGRhdGEgdG8gdGhlIGFuYWx5c2lzLg0KDQpfX19UbyBzZWUgdGhlIGNvZGUgZm9yIHRoZSBwbG90cyBzZWxlY3QgdGhlIGNvZGUgYnV0dG9uIG9uIHlvdXIgcmlnaHQuX19fDQoNCiMjIyBfX1RpbWUgU2VyaWVzIFBsb3RfXw0KYGBge3IsZWNobz1UUlVFLCBpbmNsdWRlPVRSVUUsd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxtZXNzYWdlPUZBTFNFLCBvdXQud2lkdGg9JzEwMCUnfQ0KDQpTdG9ybXBsb3QgJT4lDQogIGdncGxvdCggYWVzKHg9YmVnaW5feWVhciwgeT1mcmVxLCANCiAgICAgICAgICAgICAgZ3JvdXA9ZXZlbnRfdHlwZV9jb2Fyc2UsIA0KICAgICAgICAgICAgICBjb2xvcj0gZXZlbnRfdHlwZV9jb2Fyc2UpKSArDQogICNnZW9tX2xpbmUoKSArDQogIGdlb21fc21vb3RoKHNlPUZBTFNFLCBzaXplID0gMS41KSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMyksDQogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwgDQogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGZhY2U9ImJvbGQiKSwNCiAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEyLCBmYWNlPSJib2xkIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyMDA5KSsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMjAxMSkrDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDE5OTcpKw0KICBsYWJzKGNvbG91ciA9ICJSZXBvcnRlZCBFdmVudCBUeXBlIikrICANCiAgeWxhYigiTnVtYmVyIG9mIFJlcG9ydGVkIFN0b3JtIEV2ZW50cyIpKw0KICB4bGFiKCAiWWVhciIpDQoNCmBgYA0KDQojIyMgX19UYWJsZV9fDQpgYGB7cixlY2hvPUZBTFNFLGluY2x1ZSA9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpTdG9ybXBsb3QNCmBgYA0KDQoNCiMjIF9fTkRWSSwgTUxTTFIsIHN0b3JtIGZyZXF1ZW5jeSByZWdyZXNzaW9uIGFuYWx5c2lzX18gey50YWJzZXR9DQoNCldoZW4gY29tcGFyaW5nIE1MU0xSIGRhdGEgdG8gTkRWSSB2YWx1ZXMgZGVyaXZlZCBmcm9tIGN5YW4gUk9JIHNpdGVzIHNwZWNpZmljYWxseSBpbiBKYW1haWNhIGJheSBhbmQgU291dGggT3lzdGVyIEJheSBubyBzaWduaWZpY2FudCBjb3JyZWxhdGlvbnMgd2FzIGZvdW5kLiBJbiB0aGlzIHNlY3Rpb24gd2Ugd2lsbCBjb250aW51ZSB3aXRoIGEgcmVncmVzc2lvbiBhbmFseXNpcyB0byBmaW5kIG91dCBpZiB0aGUgZnJlcXVlbmN5IG9mIHN0b3JtIGV2ZW50cyBpbXBhY3RzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB2ZWdldGF0aW9uIGRlbnNpdHkgYW5kIE1MU0xSIGRhdGEuIA0KDQpGaXJzdCBsZXRzIHJlYWQgaW4gc3Rvcm0gZXZlbnQgZGF0YSB0aGF0IGhhcyBiZWVuIGpvaW5lZCB0byBib3RoIE1MU0xSIGFuZCBORFZJIGRhdGEuIFdlIHdpbGwgdGhlbiBjb252ZXJ0IHRoZSBzdG9ybSBkYXRhIGZyb20gY2hhcmFjdGVyIHRvIGZhY3RvciBhbmQgcnVuIHRoZSBsaW5lYXIgbW9kZWwgZnVuY3Rpb24gb24gYm90aCBzaXRlIGxvY2F0aW9ucy4gDQoNCg0KYGBge3IsY2xhc3Muc291cmNlID0gJ2ZvbGQtc2hvdycsZWNobz1UUlVFLGluY2x1ZGU9VFJVRSwgbWVzc2FnZT1GQUxTRX0NClN0b3JtX1NMUl9ORFZJPC0gcmVhZF9jc3YoIlN0b3JtX1NMUl9ORFZJX2N5YW4uY3N2IikNCg0KU3Rvcm1fU0xSX05EVkkkZXZlbnRfdHlwZV9jb2Fyc2UgPC0gYXMuZmFjdG9yKFN0b3JtX1NMUl9ORFZJJGV2ZW50X3R5cGVfY29hcnNlKQ0KY2xhc3MoU3Rvcm1fU0xSX05EVkkkZXZlbnRfdHlwZV9jb2Fyc2UpDQpsZXZlbHMoU3Rvcm1fU0xSX05EVkkkZXZlbnRfdHlwZV9jb2Fyc2UpDQpgYGANCg0KX19fVG8gc2VlIHRoZSBjb2RlIGZvciB0aGUgcGxvdHMgc2VsZWN0IHRoZSBjb2RlIGJ1dHRvbiBvbiB5b3VyIHJpZ2h0Ll9fXw0KDQojIyMgX19KYW1haWNhIEJheSBTdW1tYXJ5IFN0YXRzX18NCg0KVGhpcyBzdW1tYXJ5IGNvbXBhcmVzIHRoZSBORFZJIHZhbHVlcyBleHRyYWN0ZWQgZnJvbSB0aGUgSmFtYWljYSBCYXkgY3lhbiBST0kgc2l0ZSB0byBNTFNMUiBhbmQgc3Rvcm0gZXZlbnQgdHlwZSBmcmVxdWVuY3kuDQpgYGB7ciwgZWNobz0gVFJVRSxpbmNsdWRlID0gVFJVRX0NCk1MUl9qYl85NV8wMF9uZHZpIDwtbG0oamJfOTVfMDBfbmR2aSB+IG1vbnRobHlfbXNsICsgZXZlbnRfdHlwZV9jb2Fyc2UsIGRhdGEgPSBTdG9ybV9TTFJfTkRWSSkNCg0Kc3VtbWFyeShNTFJfamJfOTVfMDBfbmR2aSkNCmBgYA0KDQojIyMgX19Tb3V0aCBPeXN0ZXIgQmF5IFN1bW1hcnkgU3RhdHNfXw0KDQpUaGlzIHN1bW1hcnkgY29tcGFyZXMgdGhlIE5EVkkgdmFsdWVzIGV4dHJhY3RlZCBmcm9tIHRoZSBTb3V0aCBPeXN0ZXIgQmF5IGN5YW4gUk9JIHNpdGUgdG8gTUxTTFIgYW5kIHN0b3JtIGV2ZW50IHR5cGUgZnJlcXVlbmN5Lg0KYGBge3IsIGVjaG89VFJVRSxpbmNsdWRlPVRSVUV9DQpNTFJfc29iXzk1XzAwX25kdmkgPC1sbShzb2JfOTVfMDBfbmR2aSB+IG1vbnRobHlfbXNsICsgZXZlbnRfdHlwZV9jb2Fyc2UsIGRhdGEgPSBTdG9ybV9TTFJfTkRWSSkNCg0Kc3VtbWFyeShNTFJfc29iXzk1XzAwX25kdmkpDQpgYGANCg0KDQojIyBfX1JlZ3Jlc3Npb24gYW5hbHlzaXMgZGlzY3Vzc2lvbl9fDQpOb3RpY2UgdGhhdCBib3RoIGFuYWx5c2VzIGhhdmUgc2lnbmlmaWNhbnQgcC12YWx1ZXMgYnV0IFItc3F1YXJlZCB2YWx1ZXMgdGhhdCBhcmUgPCB0aGFuIDAuNS4gVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIG5vIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHZlZ2V0YXRpb24gZGVuc2l0eSwgTUxTTFIsIGFuZCBzdG9ybSBldmVudCB0eXBlIGZyZXF1ZW5jeSBhdCB0aGVzZSBzcGVjaWZpYyBzaXRlcy4gT3RoZXIgZW52aXJvbm1lbnRhbCBvciBhbnRocm9wb2dlbmljIGZhY3RvcnMgY291bGQgYmUgaW1wYWN0aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBNTFNMUiBhbmQgbWFyc2ggaXNsYW5kIHZlZ2V0YXRpb24gZGVuc2l0eSBhdCBzcGVjaWZpYyBsb2NhdGlvbnMgYW5kIHNpdGVzIHRocm91Z2hvdXQgUXVlZW5zIGFuZCBMb25nIElzbGFuZHMgU291dGggYmF5LiBTdGlsbCwgdGhlIGFuYWx5c2VzIGNvbmR1Y3RlZCB0aHJvdWdoIG91dCB0aGlzIG5vdGVib29rIHNob3cgaG93IHRpZGFsIHdldGxhbmRzIGFyZSBsb3NpbmcgdmVnZXRhdGlvbiBhdCBhY2NlbGVyYXRpbmcgcmF0ZXMgYXQgb3RoZXIgc2l0ZXMgdGhyb3VnaCBvdXQgTG9uZyBJc2xhbmQgYW5kIGFyZSBub3Qga2VlcGluZyB1cCB3aXRoIGNsaW1hdGUgY2hhbmdlLWRlcml2ZWQgTUxTTFIuIA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=