library('fpp3')
library('tsibble')
library('ggplot2')
library('readr')
library('zoo')
library('cowplot')
library('ggfortify')
library('gridExtra')
library('latex2exp')
library('seasonal')
Instuctions
Do exercises 3.1, 3.2, 3.3, 3.4, 3.5, 3.7, 3.8 and 3.9 from the
online Hyndman book. Please include your Rpubs link along with.pdf file
of your run code
3.1
i
Consider the GDP information in global_economy. Plot the
GDP per capita for each country over time. Which country has the highest
GDP per capita?
# global_economy
# add GDP to the Data frame
global_economy <- global_economy %>%
mutate(GDP_per_capita = GDP / Population)
# get the max values entire row for the title
max_gdp_row <- global_economy[which.max(global_economy$GDP_per_capita), ]
global_economy %>%
autoplot(GDP_per_capita, show.legend = FALSE) +
labs(title = paste("GDP per capita by Country | Max GDP:", max_gdp_row$GDP_per_capita, "for", max_gdp_row$Country, " in ",max_gdp_row$Year),
y = "$US")

NA
NA
na_cnt<-sum(is.na(global_economy%>%
filter(Country=="Monaco")%>%
select(GDP_per_capita)))
Adding missing grouping variables: `Year`
paste("In the date range of 1960 to 2017 Monaco has had ",na_cnt," NA's")
[1] "In the date range of 1960 to 2017 Monaco has had 11 NA's"
ii
How has this changed over time?
global_economy <- index_by(global_economy, Year)
# store only rows with max gdp
max_gdp_annual <- global_economy %>%
slice_max(GDP_per_capita) %>%
ungroup()
# plot by rows selected
ggplot(max_gdp_annual, aes(x = Year, y = GDP_per_capita, color = Country)) +
geom_line() +
labs(title = "Country with Highest GDP per Year",
x = "Year",
y = "GDP") +
theme_minimal()

Looks like Luxembourg is using top in GDP making Monaco’s 2014
GDP
3.2
For each of the following series, make a graph of the data. If
transforming seems appropriate, do so and describe the effect.
i
United States GDP from global_economy.
Using GDP per Capita made the most sense. It was already transformed
by the above manipulations.
fig1<-global_economy%>%
filter(Country=="United States")%>%
autoplot()+
labs(title = "GDP US")
Plot variable not specified, automatically selected `.vars = GDP``mutate_if()` ignored the following grouping variables:
fig2<-global_economy%>%
filter(Country=="United States")%>%
autoplot(GDP_per_capita)+
labs(title = "GDP per Capita US")
`mutate_if()` ignored the following grouping variables:
plot_grid(fig1,
fig2, nrow = 1)

ii
Slaughter of Victorian “Bulls, bullocks and steers” in
aus_livestock.
The data seemed clutter. By grouping it by Quarter the visual is
clearer and the initial dip is apparent.
head(aus_livestock)
fig3 <- aus_livestock %>%
filter(Animal == "Bulls, bullocks and steers") %>%
summarise(Count = sum(Count)) %>%
autoplot(show.legend=FALSE)
Plot variable not specified, automatically selected `.vars = Count`
fig4 <- aus_livestock %>%
filter(Animal == "Bulls, bullocks and steers") %>%
mutate(Quarter = yearquarter(Month)) %>%
index_by(Quarter) %>%
summarise(Count = sum(Count)) %>%
autoplot(Count, show.legend=FALSE)
plot_grid(fig3, fig4, nrow = 1)

iii
Victorian Electricity Demand from vic_elec.
This was a lot of data so dealers choice, but viewing the annual data
in a weekly and monthly basis shows an initial spike the first week and
month for the year.
head(vic_elec)
fig5<-vic_elec%>%
autoplot(Demand)
fig6<-vic_elec%>%
mutate(Week = yearweek(Time)) %>%
index_by(Week) %>%
summarise(Demand = sum(Demand)) %>%
autoplot(Demand, show.legend=FALSE)
fig7<-vic_elec%>%
mutate(Month = yearmonth(Time)) %>%
index_by(Month) %>%
summarise(Demand = sum(Demand)) %>%
autoplot(Demand, show.legend=FALSE)
# fig7<-vic_elec%>%
# mutate(Day = as.Date(Time)) %>%
# group_by(Day) %>%
# summarise(Demand = sum(Demand)) %>%
# autoplot(Demand, show.legend=FALSE)
plot_grid(fig5,
fig6,
fig7, nrow = 2)

iv
Gas production from aus_production.
head(aus_production)
NA
I played with all methods introduced in mathematical transformations
considering the high variability between the start and end of the data,
in an attempt to remove variability.
Than I applied Box-Cox transformations:
\(w_t= \Biggl\{
\genfrac{}{}{0pt}{}{log(y_t),\ \ \ \lambda = 0}{ (sign(y_t)|y_t|^\lambda
-1)/\lambda,\ \ \lambda \ne0}\)
as explained in 3.1
video for transformations
#example
# food |>
# features(Turnover, features = guerrero())
(aus_gas_lambda<-aus_production%>%
features(Gas, features = guerrero)%>%
pull(lambda_guerrero))
[1] 0.1095171
fig8 <- aus_production %>%
autoplot(Gas) +
labs(title = "Original")
# Define fig9
fig9 <- aus_production %>%
autoplot(log(Gas)) +
labs(title = expression(paste("Log Gas ", lambda, "= 0")))
# Define fig10
fig10 <- aus_production %>%
autoplot(-1/Gas) +
labs(title = "Inverse Gas")
fig11 <- aus_production%>%
autoplot(box_cox(Gas,aus_gas_lambda))
plot_grid(fig8 +
labs(title = "Original"),
fig9 +
labs(title = expression(paste("Log Gas ",
lambda, "= 0"))),
fig10 +
labs(title = expression(paste("Inverse Gas ",
lambda, "= 0"))),
fig11 +
labs(title = expression(paste("Box-Cox ",
lambda,
" = 0.1095171"))),
nrow = 2)

3.3
Why is a Box-Cox transformation unhelpful for the
canadian_gas data?
as per the 3.1
Video for transformations.
A low value of \(\lambda\) can give
extremely large prediction intervals and as we see in the plot below
does not do much for transformation.
head(canadian_gas)
(canada_gas_lambda<-canadian_gas%>%
features(Volume, features = guerrero)%>%
pull(lambda_guerrero)
)
[1] 0.5767648
fig12<-canadian_gas%>%
autoplot(Volume)
fig13<-canadian_gas%>%
autoplot(box_cox(Volume, canada_gas_lambda))
plot_grid(fig12+labs(title = "Original"),
fig13+labs(title = expression(paste("Box-Cox ",
lambda,
" =0.5767648"))))

rm(list = ls(pattern = "^fig"))
3.4
What Box-Cox transformation would you select for your retail data
(from Exercise 7 in Section 2.10)?
I would rely on features=guerrero since its
designed to be the best fit.
# data provided
set.seed(123)
myseries <- aus_retail |>
filter(`Series ID` == sample(aus_retail$`Series ID`,1))
head(myseries)
(myseries_lambda <- myseries%>%
features(Turnover,features = guerrero)%>%
pull(lambda_guerrero))
[1] 0.2151641
fig1 <- myseries%>%
autoplot(Turnover)
fig2 <- myseries%>%
autoplot(box_cox(Turnover,myseries_lambda))
fig2<-fig2+ylab("Turnover")
plot_grid(fig1+labs(title = "Original"),
fig2+labs(title = paste("Box-cox λ =",myseries_lambda)), nrow=2)

3.5
For the following series, find an appropriate Box-Cox transformation
in order to stabilize the variance.
i
Tobacco from aus_production
aus_production_lambda<-aus_production%>%
features(Tobacco,features=guerrero)%>%
pull(lambda_guerrero)
aus_production%>%
autoplot(box_cox(Tobacco,aus_production_lambda))+
labs(title =paste("λ =",aus_production_lambda),ylab="" )

ii
Economy class passengers between Melbourne and Sydney from
ansett
head(ansett)
ansett_lambda<-ansett%>%
filter(Class=="Economy"& Airports=='MEL-SYD')%>%
features(Passengers,features=guerrero)%>%
pull(lambda_guerrero)
ansett%>%
filter(Class=="Economy"& Airports=='MEL-SYD')%>%
autoplot(box_cox(Passengers,ansett_lambda))+
labs(title =paste("λ =",ansett_lambda), y=" " )

iii
Pedestrian counts at Southern Cross Station from
pedestrian.
head(pedestrian)
pedestrian_lambda<-pedestrian%>%
filter(Sensor=="Southern Cross Station")%>%
features(Count,features=guerrero)%>%
pull(lambda_guerrero)
pedestrian%>%
filter(Sensor=="Southern Cross Station")%>%
autoplot(box_cox(Count,pedestrian_lambda))+
coord_flip()+
labs(title =paste("λ =",pedestrian_lambda),x = "Date (hourly)",
y="Count" )

3.7
Consider the last five years of the Gas data from
aus_production.
gas <- tail(aus_production, 5*4) |> select(Gas)
head(gas)
a.
Plot the time series. Can you identify seasonal fluctuations and/or a
trend-cycle?
Looks like the trend from 2006-2010 is upwards. Seasonality is
the high every 3rd quarter and low every 1rst Quarter
gas%>%
autoplot(Gas)

b.
Use classical_decomposition with
type=multiplicative to calculate the trend-cycle and
seasonal indices.
Ref 3.4
video
#example
# us_retail_employment |>
# model(classical_decomposition(Employed, type = "additive")) |>
# components()|>
# autoplot()+xlab("Year")+
# ggtitle("Classical additive decomposition of total US retail employment")
gas%>%
model(classical_decomposition(Gas,type= "multiplicative"))%>%
components()%>%
autoplot+xlab("")

c.
Do the results support the graphical interpretation from part a?
The results show a positive trend with quarterly seasonality so
yes it does.
d.
Compute and plot the seasonally adjusted data.
As shown in 3.5
#Example
# x11_dcmp |>
# ggplot(aes(x = Month)) +
# geom_line(aes(y = Employed, colour = "Data")) +
# geom_line(aes(y = season_adjust,
# colour = "Seasonally Adjusted")) +
# geom_line(aes(y = trend, colour = "Trend")) +
# labs(y = "Persons (thousands)",
# title = "Total employment in US retail") +
# scale_colour_manual(
# values = c("gray", "#0072B2", "#D55E00"),
# breaks = c("Data", "Seasonally Adjusted", "Trend")
# )
gas%>%
model(classical_decomposition(Gas,type= "multiplicative"))%>%
components()%>%
ggplot(aes(x = Quarter)) +
geom_line(aes(y = Gas, colour = "Data")) +
geom_line(aes(y = season_adjust,
colour = "Seasonally Adjusted")) +
geom_line(aes(y = trend, colour = "Trend")) +
labs(y = "Gas count in PJ",
title = "Australian Gas Production") +
scale_colour_manual(
values = c("gray", "#0072B2", "#D55E00"),
breaks = c("Data", "Seasonally Adjusted", "Trend")
)

e.
Change one observation to be an outlier (e.g., add 300 to one
observation), and recompute the seasonally adjusted data. What is the
effect of the outlier?
rm(list = ls(pattern = "^fig"))
print(nrow(gas))
[1] 20
gas_begin_edit <- gas
gas_end_edit <- gas
gas_begin_edit$Gas[1] <- gas_begin_edit$Gas[10] + 300
gas_end_edit$Gas[20] <- gas_begin_edit$Gas[10] + 300
fig1<-gas_begin_edit%>%
model(classical_decomposition(Gas,type= "multiplicative"))%>%
components()%>%
ggplot(aes(x = Quarter)) +
geom_line(aes(y = Gas, colour = "Data")) +
geom_line(aes(y = season_adjust,
colour = "Seasonally Adjusted")) +
geom_line(aes(y = trend, colour = "Trend")) +
labs(y = "Gas count in PJ",
title = "Australian Gas Production") +
scale_colour_manual(
values = c("gray", "#0072B2", "#D55E00"),
breaks = c("Data", "Seasonally Adjusted", "Trend")
)
fig2<-gas_end_edit%>%
model(classical_decomposition(Gas,type= "multiplicative"))%>%
components()%>%
ggplot(aes(x = Quarter)) +
geom_line(aes(y = Gas, colour = "Data")) +
geom_line(aes(y = season_adjust,
colour = "Seasonally Adjusted")) +
geom_line(aes(y = trend, colour = "Trend")) +
labs(y = "Gas count in PJ",
title = "Australian Gas Production") +
scale_colour_manual(
values = c("gray", "#0072B2", "#D55E00"),
breaks = c("Data", "Seasonally Adjusted", "Trend")
)
plot_grid(fig1+labs(title = "Edit in the beginning"),
fig2+labs(title = "Edit in the end"), nrow=2)
Warning: Removed 4 rows containing missing values (`geom_line()`).Warning: Removed 4 rows containing missing values (`geom_line()`).

It spikes the data
f.
Does it make any difference if the outlier is near the end rather
than in the middle of the time series?
Just placement, but the effect is the same
3.8
Recall your retail time series data (from Exercise 7 in Section
2.10). Decompose the series using X-11. Does it reveal any outliers, or
unusual features that you had not noticed previously?
As per 3.5 Methods used by official statistics
agencies
#Example
# x11_dcmp <- us_retail_employment |>
# model(x11 = X_13ARIMA_SEATS(Employed ~ x11())) |>
# components()
# autoplot(x11_dcmp) +
# labs(title =
# "Decomposition of total US retail employment using X-11.")
set.seed(241)
myseries <- aus_retail %>%
filter(`Series ID` == sample(aus_retail$`Series ID`,1))
x11_dcmp <- myseries %>%
model(x11 = X_13ARIMA_SEATS(Turnover ~ x11())) %>%
components()
autoplot(x11_dcmp) +
labs(title =
"Decomposition of total US retail employment using X-11.")

**I noted a long-term downward trend and greater volatility with the
seasonal spikes
3.9
Figures 3.19 and 3.20 show the result of decomposing the number of
persons in the civilian labour force in Australia each month from
February 1978 to August 1995.


a.
Write about 3–5 sentences describing the results of the
decomposition. Pay particular attention to the scales of the graphs in
making your interpretation.
The trend is clearly a upward trend from 1978-1995, and what appears
to be some seasonality. This makes sense to me as the spikes are common,
with students leaving school for the holiday and summer, and seasonal
work occurring throughout the year. I’m curious what caused the dip in
1992 which is a pretty clear outlier.
b.
Is the recession of 1991/1992 visible in the estimated
components?
Very much. Its easily observed in the “remainder” plot.
LS0tDQp0aXRsZTogJ0RBVEEgNjI0OiBQUkVESUNUSVZFIEFOQUxZVElDUyBIVzInDQphdXRob3I6ICJHYWJyaWVsIENhbXBvcyINCmRhdGU6ICJMYXN0IGVkaXRlZCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBnZW9tZXRyeTogbGVmdD0wLjVjbSxyaWdodD0wLjVjbSx0b3A9MWNtLGJvdHRvbT0yY20NCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50Og0KICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KdXJsY29sb3I6IGJsdWUNCi0tLQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoJ2ZwcDMnKQ0KbGlicmFyeSgndHNpYmJsZScpDQpsaWJyYXJ5KCdnZ3Bsb3QyJykNCmxpYnJhcnkoJ3JlYWRyJykNCmxpYnJhcnkoJ3pvbycpDQpsaWJyYXJ5KCdjb3dwbG90JykNCmxpYnJhcnkoJ2dnZm9ydGlmeScpDQpsaWJyYXJ5KCdncmlkRXh0cmEnKQ0KbGlicmFyeSgnbGF0ZXgyZXhwJykNCmxpYnJhcnkoJ3NlYXNvbmFsJykNCmBgYA0KDQoNCiMgSW5zdHVjdGlvbnMNCg0KRG8gZXhlcmNpc2VzIDMuMSwgMy4yLCAzLjMsIDMuNCwgMy41LCAzLjcsIDMuOCBhbmQgMy45IGZyb20gdGhlIG9ubGluZSBIeW5kbWFuIGJvb2suICBQbGVhc2UgaW5jbHVkZSB5b3VyIFJwdWJzIGxpbmsgYWxvbmcgd2l0aC5wZGYgZmlsZSBvZiB5b3VyIHJ1biBjb2RlDQoNCiMgMy4xDQoNCiMjIGkgDQoNCiAgQ29uc2lkZXIgdGhlIEdEUCBpbmZvcm1hdGlvbiBpbiBgZ2xvYmFsX2Vjb25vbXlgLiBQbG90IHRoZSBHRFAgcGVyIGNhcGl0YSBmb3IgZWFjaCBjb3VudHJ5IG92ZXIgdGltZS4gV2hpY2ggY291bnRyeSBoYXMgdGhlIGhpZ2hlc3QgR0RQIHBlciBjYXBpdGE/IA0KDQpgYGB7cn0NCg0KIyBnbG9iYWxfZWNvbm9teQ0KDQpgYGANCg0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIGFkZCBHRFAgdG8gdGhlIERhdGEgZnJhbWUNCmdsb2JhbF9lY29ub215IDwtIGdsb2JhbF9lY29ub215ICU+JQ0KICBtdXRhdGUoR0RQX3Blcl9jYXBpdGEgPSBHRFAgLyBQb3B1bGF0aW9uKQ0KDQojIGdldCB0aGUgbWF4IHZhbHVlcyBlbnRpcmUgcm93IGZvciB0aGUgdGl0bGUNCm1heF9nZHBfcm93IDwtIGdsb2JhbF9lY29ub215W3doaWNoLm1heChnbG9iYWxfZWNvbm9teSRHRFBfcGVyX2NhcGl0YSksIF0NCg0KDQpnbG9iYWxfZWNvbm9teSAlPiUNCiAgYXV0b3Bsb3QoR0RQX3Blcl9jYXBpdGEsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgbGFicyh0aXRsZSA9IHBhc3RlKCJHRFAgcGVyIGNhcGl0YSBieSBDb3VudHJ5IHwgTWF4IEdEUDoiLCBtYXhfZ2RwX3JvdyRHRFBfcGVyX2NhcGl0YSwgImZvciIsIG1heF9nZHBfcm93JENvdW50cnksICIgaW4gIixtYXhfZ2RwX3JvdyRZZWFyKSwNCiAgICAgICB5ID0gIiRVUyIpDQoNCg0KYGBgDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KbmFfY250PC1zdW0oaXMubmEoZ2xvYmFsX2Vjb25vbXklPiUNCiAgICAgICAgZmlsdGVyKENvdW50cnk9PSJNb25hY28iKSU+JQ0KICAgICAgICAgIHNlbGVjdChHRFBfcGVyX2NhcGl0YSkpKQ0KDQoNCnBhc3RlKCJJbiB0aGUgZGF0ZSByYW5nZSBvZiAxOTYwIHRvIDIwMTcgTW9uYWNvIGhhcyBoYWQgIixuYV9jbnQsIiBOQSdzIikNCmBgYA0KDQojIyBpaQ0KDQpIb3cgaGFzIHRoaXMgY2hhbmdlZCBvdmVyIHRpbWU/DQoNCmBgYHtyfQ0KDQpnbG9iYWxfZWNvbm9teSA8LSBpbmRleF9ieShnbG9iYWxfZWNvbm9teSwgWWVhcikNCg0KIyBzdG9yZSBvbmx5IHJvd3Mgd2l0aCBtYXggZ2RwDQptYXhfZ2RwX2FubnVhbCA8LSBnbG9iYWxfZWNvbm9teSAlPiUNCiAgc2xpY2VfbWF4KEdEUF9wZXJfY2FwaXRhKSAlPiUNCiAgdW5ncm91cCgpDQoNCiMgcGxvdCBieSByb3dzIHNlbGVjdGVkDQpnZ3Bsb3QobWF4X2dkcF9hbm51YWwsIGFlcyh4ID0gWWVhciwgeSA9IEdEUF9wZXJfY2FwaXRhLCBjb2xvciA9IENvdW50cnkpKSArDQogIGdlb21fbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJDb3VudHJ5IHdpdGggSGlnaGVzdCBHRFAgcGVyIFllYXIiLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJHRFAiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQpMb29rcyBsaWtlIEx1eGVtYm91cmcgaXMgdXNpbmcgdG9wIGluIEdEUCBtYWtpbmcgTW9uYWNvJ3MgMjAxNCBHRFAgDQoNCiMgMy4yDQoNCkZvciBlYWNoIG9mIHRoZSBmb2xsb3dpbmcgc2VyaWVzLCBtYWtlIGEgZ3JhcGggb2YgdGhlIGRhdGEuIElmIHRyYW5zZm9ybWluZyBzZWVtcyBhcHByb3ByaWF0ZSwgZG8gc28gYW5kIGRlc2NyaWJlIHRoZSBlZmZlY3QuDQoNCiMgaQ0KDQpVbml0ZWQgU3RhdGVzIGBHRFAgZnJvbSBnbG9iYWxfZWNvbm9teWAuDQoNClVzaW5nIEdEUCBwZXIgQ2FwaXRhIG1hZGUgdGhlIG1vc3Qgc2Vuc2UuIEl0IHdhcyBhbHJlYWR5IHRyYW5zZm9ybWVkIGJ5IHRoZSBhYm92ZSBtYW5pcHVsYXRpb25zLg0KDQpgYGB7cn0NCg0KZmlnMTwtZ2xvYmFsX2Vjb25vbXklPiUNCiAgZmlsdGVyKENvdW50cnk9PSJVbml0ZWQgU3RhdGVzIiklPiUNCiAgICBhdXRvcGxvdCgpKw0KICBsYWJzKHRpdGxlID0gIkdEUCBVUyIpDQoNCmZpZzI8LWdsb2JhbF9lY29ub215JT4lDQogIGZpbHRlcihDb3VudHJ5PT0iVW5pdGVkIFN0YXRlcyIpJT4lDQogICAgYXV0b3Bsb3QoR0RQX3Blcl9jYXBpdGEpKw0KICBsYWJzKHRpdGxlID0gIkdEUCBwZXIgQ2FwaXRhIFVTIikNCg0KcGxvdF9ncmlkKGZpZzEsDQogICAgICAgICAgZmlnMiwgbnJvdyA9IDEpDQoNCmBgYA0KDQoNCiMgaWkNCg0KU2xhdWdodGVyIG9mIFZpY3RvcmlhbiDigJxCdWxscywgYnVsbG9ja3MgYW5kIHN0ZWVyc+KAnSBpbiBgYXVzX2xpdmVzdG9ja2AuDQoNClRoZSBkYXRhIHNlZW1lZCBjbHV0dGVyLiBCeSBncm91cGluZyBpdCBieSBRdWFydGVyIHRoZSB2aXN1YWwgaXMgY2xlYXJlciBhbmQgdGhlIGluaXRpYWwgZGlwIGlzIGFwcGFyZW50Lg0KDQpgYGB7cn0NCmhlYWQoYXVzX2xpdmVzdG9jaykNCmBgYA0KDQoNCmBgYHtyfQ0KDQpmaWczIDwtIGF1c19saXZlc3RvY2sgJT4lDQogIGZpbHRlcihBbmltYWwgPT0gIkJ1bGxzLCBidWxsb2NrcyBhbmQgc3RlZXJzIikgJT4lDQogIHN1bW1hcmlzZShDb3VudCA9IHN1bShDb3VudCkpICU+JQ0KICBhdXRvcGxvdChzaG93LmxlZ2VuZD1GQUxTRSkNCg0KZmlnNCA8LSBhdXNfbGl2ZXN0b2NrICU+JQ0KICBmaWx0ZXIoQW5pbWFsID09ICJCdWxscywgYnVsbG9ja3MgYW5kIHN0ZWVycyIpICU+JQ0KICBtdXRhdGUoUXVhcnRlciA9IHllYXJxdWFydGVyKE1vbnRoKSkgJT4lDQogIGluZGV4X2J5KFF1YXJ0ZXIpICU+JQ0KICBzdW1tYXJpc2UoQ291bnQgPSBzdW0oQ291bnQpKSAlPiUNCiAgYXV0b3Bsb3QoQ291bnQsIHNob3cubGVnZW5kPUZBTFNFKQ0KDQpwbG90X2dyaWQoZmlnMywgZmlnNCwgbnJvdyA9IDEpDQoNCmBgYA0KDQoNCg0KIyBpaWkNCg0KVmljdG9yaWFuIEVsZWN0cmljaXR5IERlbWFuZCBmcm9tIGB2aWNfZWxlY2AuDQoNClRoaXMgd2FzIGEgbG90IG9mIGRhdGEgc28gZGVhbGVycyBjaG9pY2UsIGJ1dCB2aWV3aW5nIHRoZSBhbm51YWwgZGF0YSBpbiBhIHdlZWtseSBhbmQgbW9udGhseSBiYXNpcyBzaG93cyBhbiBpbml0aWFsIHNwaWtlIHRoZSBmaXJzdCB3ZWVrIGFuZCBtb250aCBmb3IgdGhlIHllYXIuDQoNCmBgYHtyfQ0KaGVhZCh2aWNfZWxlYykNCmBgYA0KDQpgYGB7cn0NCmZpZzU8LXZpY19lbGVjJT4lDQogICAgICAgIGF1dG9wbG90KERlbWFuZCkNCg0KZmlnNjwtdmljX2VsZWMlPiUNCiAgbXV0YXRlKFdlZWsgPSB5ZWFyd2VlayhUaW1lKSkgJT4lDQogIGluZGV4X2J5KFdlZWspICU+JQ0KICBzdW1tYXJpc2UoRGVtYW5kID0gc3VtKERlbWFuZCkpICU+JQ0KICBhdXRvcGxvdChEZW1hbmQsIHNob3cubGVnZW5kPUZBTFNFKQ0KDQpmaWc3PC12aWNfZWxlYyU+JQ0KICBtdXRhdGUoTW9udGggPSB5ZWFybW9udGgoVGltZSkpICU+JQ0KICBpbmRleF9ieShNb250aCkgJT4lDQogIHN1bW1hcmlzZShEZW1hbmQgPSBzdW0oRGVtYW5kKSkgJT4lDQogIGF1dG9wbG90KERlbWFuZCwgc2hvdy5sZWdlbmQ9RkFMU0UpDQoNCiMgZmlnNzwtdmljX2VsZWMlPiUNCiMgICBtdXRhdGUoRGF5ID0gYXMuRGF0ZShUaW1lKSkgJT4lDQojICAgZ3JvdXBfYnkoRGF5KSAlPiUNCiMgICBzdW1tYXJpc2UoRGVtYW5kID0gc3VtKERlbWFuZCkpICU+JQ0KIyAgIGF1dG9wbG90KERlbWFuZCwgc2hvdy5sZWdlbmQ9RkFMU0UpDQoNCnBsb3RfZ3JpZChmaWc1LA0KICAgICAgICAgIGZpZzYsDQogICAgICAgICAgZmlnNywgbnJvdyA9IDIpDQpgYGANCg0KDQojIGl2DQoNCkdhcyBwcm9kdWN0aW9uIGZyb20gYGF1c19wcm9kdWN0aW9uYC4NCg0KYGBge3J9DQoNCmhlYWQoYXVzX3Byb2R1Y3Rpb24pDQoNCmBgYA0KDQpJIHBsYXllZCB3aXRoIGFsbCBtZXRob2RzIGludHJvZHVjZWQgaW4gbWF0aGVtYXRpY2FsIHRyYW5zZm9ybWF0aW9ucyBjb25zaWRlcmluZyB0aGUgaGlnaCB2YXJpYWJpbGl0eSBiZXR3ZWVuIHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBkYXRhLCBpbiBhbiBhdHRlbXB0IHRvIHJlbW92ZSB2YXJpYWJpbGl0eS4NCg0KVGhhbiBJIGFwcGxpZWQgDQoqQm94LUNveCB0cmFuc2Zvcm1hdGlvbnM6Kg0KDQokd190PSBcQmlnZ2xceyBcZ2VuZnJhY3t9e317MHB0fXt9e2xvZyh5X3QpLFwgXCBcIFxsYW1iZGEgPSAwfXsgKHNpZ24oeV90KXx5X3R8XlxsYW1iZGEgLTEpL1xsYW1iZGEsXCBcICBcbGFtYmRhIFxuZTB9JA0KDQphcyBleHBsYWluZWQgaW4gWzMuMSB2aWRlb10oaHR0cHM6Ly95b3V0dS5iZS9WcC1MMXptc3Bzcz9zaT1Sc1BsTXRJODNEdEZJaDJWJnQ9Njg5KSBmb3IgdHJhbnNmb3JtYXRpb25zDQoNCmBgYHtyfQ0KI2V4YW1wbGUNCiMgZm9vZCB8Pg0KIyAgIGZlYXR1cmVzKFR1cm5vdmVyLCBmZWF0dXJlcyA9IGd1ZXJyZXJvKCkpDQoNCihhdXNfZ2FzX2xhbWJkYTwtYXVzX3Byb2R1Y3Rpb24lPiUNCiAgZmVhdHVyZXMoR2FzLCBmZWF0dXJlcyA9IGd1ZXJyZXJvKSU+JQ0KICAgcHVsbChsYW1iZGFfZ3VlcnJlcm8pKQ0KYGBgDQoNCmBgYHtyfQ0KDQpmaWc4IDwtIGF1c19wcm9kdWN0aW9uICU+JQ0KICBhdXRvcGxvdChHYXMpICsNCiAgbGFicyh0aXRsZSA9ICJPcmlnaW5hbCIpDQoNCiMgRGVmaW5lIGZpZzkNCmZpZzkgPC0gYXVzX3Byb2R1Y3Rpb24gJT4lDQogIGF1dG9wbG90KGxvZyhHYXMpKSArDQogIGxhYnModGl0bGUgPSBleHByZXNzaW9uKHBhc3RlKCJMb2cgR2FzICIsIGxhbWJkYSwgIj0gMCIpKSkNCg0KIyBEZWZpbmUgZmlnMTANCmZpZzEwIDwtIGF1c19wcm9kdWN0aW9uICU+JQ0KICBhdXRvcGxvdCgtMS9HYXMpICsNCiAgbGFicyh0aXRsZSA9ICJJbnZlcnNlIEdhcyIpDQoNCmZpZzExIDwtIGF1c19wcm9kdWN0aW9uJT4lDQogICAgICAgICAgYXV0b3Bsb3QoYm94X2NveChHYXMsYXVzX2dhc19sYW1iZGEpKQ0KDQpwbG90X2dyaWQoZmlnOCArDQogICAgICAgICAgICBsYWJzKHRpdGxlID0gIk9yaWdpbmFsIiksIA0KICAgICAgICAgIGZpZzkgKw0KICAgICAgICAgICAgbGFicyh0aXRsZSA9IGV4cHJlc3Npb24ocGFzdGUoIkxvZyBHYXMgIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhbWJkYSwgIj0gMCIpKSksIA0KICAgICAgICAgIGZpZzEwICsNCiAgICAgICAgICAgIGxhYnModGl0bGUgPSBleHByZXNzaW9uKHBhc3RlKCJJbnZlcnNlIEdhcyAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhLCAiPSAwIikpKSwNCiAgICAgICAgICBmaWcxMSArDQogICAgICAgICAgICBsYWJzKHRpdGxlID0gZXhwcmVzc2lvbihwYXN0ZSgiQm94LUNveCAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFtYmRhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiA9IDAuMTA5NTE3MSIpKSksDQogICAgICAgICAgbnJvdyA9IDIpDQoNCmBgYA0KDQoNCiMgMy4zDQoNCldoeSBpcyBhIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gdW5oZWxwZnVsIGZvciB0aGUgYGNhbmFkaWFuX2dhc2AgZGF0YT8NCg0KYXMgcGVyIHRoZSBbMy4xIFZpZGVvXShodHRwczovL3lvdXR1LmJlL1ZwLUwxem1zcHNzP3NpPUJ0WC0yVEluZmN1S2pmYzAmdD03NDkpIGZvciB0cmFuc2Zvcm1hdGlvbnMuDQoNCkEgbG93IHZhbHVlIG9mICRcbGFtYmRhJCBjYW4gZ2l2ZSBleHRyZW1lbHkgbGFyZ2UgcHJlZGljdGlvbiBpbnRlcnZhbHMNCmFuZCBhcyB3ZSBzZWUgaW4gdGhlIHBsb3QgYmVsb3cgZG9lcyBub3QgZG8gbXVjaCBmb3IgdHJhbnNmb3JtYXRpb24uDQoNCmBgYHtyfQ0KaGVhZChjYW5hZGlhbl9nYXMpDQpgYGANCmBgYHtyfQ0KKGNhbmFkYV9nYXNfbGFtYmRhPC1jYW5hZGlhbl9nYXMlPiUNCiAgICBmZWF0dXJlcyhWb2x1bWUsIGZlYXR1cmVzID0gZ3VlcnJlcm8pJT4lDQogICAgcHVsbChsYW1iZGFfZ3VlcnJlcm8pDQopDQoNCmBgYA0KDQpgYGB7cn0NCmZpZzEyPC1jYW5hZGlhbl9nYXMlPiUNCiAgYXV0b3Bsb3QoVm9sdW1lKQ0KDQpmaWcxMzwtY2FuYWRpYW5fZ2FzJT4lDQogIGF1dG9wbG90KGJveF9jb3goVm9sdW1lLCBjYW5hZGFfZ2FzX2xhbWJkYSkpDQoNCnBsb3RfZ3JpZChmaWcxMitsYWJzKHRpdGxlID0gIk9yaWdpbmFsIiksDQogICAgICAgICAgZmlnMTMrbGFicyh0aXRsZSA9IGV4cHJlc3Npb24ocGFzdGUoIkJveC1Db3ggIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiA9MC41NzY3NjQ4IikpKSkNCmBgYA0KDQpgYGB7cn0NCnJtKGxpc3QgPSBscyhwYXR0ZXJuID0gIl5maWciKSkNCmBgYA0KDQoNCiMgMy40DQoNCldoYXQgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiB3b3VsZCB5b3Ugc2VsZWN0IGZvciB5b3VyIHJldGFpbCBkYXRhIChmcm9tIEV4ZXJjaXNlIDcgaW4gU2VjdGlvbiBbMi4xMF0oaHR0cHM6Ly9vdGV4dHMuY29tL2ZwcDMvZ3JhcGhpY3MtZXhlcmNpc2VzLmh0bWwjZ3JhcGhpY3MtZXhlcmNpc2VzKSk/DQoNCkkgd291bGQgcmVseSBvbiBgZmVhdHVyZXNgPWBndWVycmVyb2Agc2luY2UgaXRzIGRlc2lnbmVkIHRvIGJlIHRoZSBiZXN0IGZpdC4NCg0KYGBge3J9DQojIGRhdGEgcHJvdmlkZWQNCnNldC5zZWVkKDEyMykNCm15c2VyaWVzIDwtIGF1c19yZXRhaWwgfD4NCiAgZmlsdGVyKGBTZXJpZXMgSURgID09IHNhbXBsZShhdXNfcmV0YWlsJGBTZXJpZXMgSURgLDEpKQ0KaGVhZChteXNlcmllcykNCmBgYA0KDQpgYGB7cn0NCihteXNlcmllc19sYW1iZGEgPC0gbXlzZXJpZXMlPiUNCiAgICAgICAgZmVhdHVyZXMoVHVybm92ZXIsZmVhdHVyZXMgPSBndWVycmVybyklPiUNCiAgICAgICAgICBwdWxsKGxhbWJkYV9ndWVycmVybykpDQpgYGANCg0KYGBge3J9DQpmaWcxIDwtIG15c2VyaWVzJT4lDQogICAgICAgICAgYXV0b3Bsb3QoVHVybm92ZXIpDQoNCmZpZzIgPC0gbXlzZXJpZXMlPiUNCiAgICAgICAgYXV0b3Bsb3QoYm94X2NveChUdXJub3ZlcixteXNlcmllc19sYW1iZGEpKQ0KZmlnMjwtZmlnMit5bGFiKCJUdXJub3ZlciIpDQoNCnBsb3RfZ3JpZChmaWcxK2xhYnModGl0bGUgPSAiT3JpZ2luYWwiKSwNCiAgICAgICAgICBmaWcyK2xhYnModGl0bGUgPSBwYXN0ZSgiQm94LWNveCDOuyA9IixteXNlcmllc19sYW1iZGEpKSwgbnJvdz0yKQ0KYGBgDQoNCg0KIyAzLjUNCg0KRm9yIHRoZSBmb2xsb3dpbmcgc2VyaWVzLCBmaW5kIGFuIGFwcHJvcHJpYXRlIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gaW4gb3JkZXIgdG8gc3RhYmlsaXplIHRoZSB2YXJpYW5jZS4gDQoNCiMgaQ0KDQpUb2JhY2NvIGZyb20gYGF1c19wcm9kdWN0aW9uYA0KDQpgYGB7cix3YXJuaW5nPUZBTFNFfQ0KYXVzX3Byb2R1Y3Rpb25fbGFtYmRhPC1hdXNfcHJvZHVjdGlvbiU+JQ0KICBmZWF0dXJlcyhUb2JhY2NvLGZlYXR1cmVzPWd1ZXJyZXJvKSU+JQ0KICBwdWxsKGxhbWJkYV9ndWVycmVybykNCg0KYXVzX3Byb2R1Y3Rpb24lPiUNCiAgYXV0b3Bsb3QoYm94X2NveChUb2JhY2NvLGF1c19wcm9kdWN0aW9uX2xhbWJkYSkpKw0KICBsYWJzKHRpdGxlID1wYXN0ZSgizrsgPSIsYXVzX3Byb2R1Y3Rpb25fbGFtYmRhKSx5bGFiPSIiICkNCmBgYA0KDQoNCiMgaWkgDQoNCkVjb25vbXkgY2xhc3MgcGFzc2VuZ2VycyBiZXR3ZWVuIE1lbGJvdXJuZSBhbmQgU3lkbmV5IGZyb20gYGFuc2V0dGANCg0KYGBge3J9DQpoZWFkKGFuc2V0dCkNCmBgYA0KDQoNCmBgYHtyLHdhcm5pbmc9RkFMU0V9DQphbnNldHRfbGFtYmRhPC1hbnNldHQlPiUNCiAgZmlsdGVyKENsYXNzPT0iRWNvbm9teSImIEFpcnBvcnRzPT0nTUVMLVNZRCcpJT4lDQogIGZlYXR1cmVzKFBhc3NlbmdlcnMsZmVhdHVyZXM9Z3VlcnJlcm8pJT4lDQogIHB1bGwobGFtYmRhX2d1ZXJyZXJvKQ0KDQphbnNldHQlPiUNCiAgZmlsdGVyKENsYXNzPT0iRWNvbm9teSImIEFpcnBvcnRzPT0nTUVMLVNZRCcpJT4lDQogIGF1dG9wbG90KGJveF9jb3goUGFzc2VuZ2VycyxhbnNldHRfbGFtYmRhKSkrDQogIGxhYnModGl0bGUgPXBhc3RlKCLOuyA9IixhbnNldHRfbGFtYmRhKSwgeT0iICIgKQ0KYGBgDQoNCiMgaWlpDQoNClBlZGVzdHJpYW4gY291bnRzIGF0IFNvdXRoZXJuIENyb3NzIFN0YXRpb24gZnJvbSBgcGVkZXN0cmlhbmAuDQoNCmBgYHtyfQ0KaGVhZChwZWRlc3RyaWFuKQ0KYGBgDQoNCmBgYHtyfQ0KcGVkZXN0cmlhbl9sYW1iZGE8LXBlZGVzdHJpYW4lPiUNCiAgZmlsdGVyKFNlbnNvcj09IlNvdXRoZXJuIENyb3NzIFN0YXRpb24iKSU+JQ0KICBmZWF0dXJlcyhDb3VudCxmZWF0dXJlcz1ndWVycmVybyklPiUNCiAgcHVsbChsYW1iZGFfZ3VlcnJlcm8pDQoNCnBlZGVzdHJpYW4lPiUNCiAgZmlsdGVyKFNlbnNvcj09IlNvdXRoZXJuIENyb3NzIFN0YXRpb24iKSU+JQ0KICBhdXRvcGxvdChib3hfY294KENvdW50LHBlZGVzdHJpYW5fbGFtYmRhKSkrDQogIGNvb3JkX2ZsaXAoKSsNCiAgbGFicyh0aXRsZSA9cGFzdGUoIs67ID0iLHBlZGVzdHJpYW5fbGFtYmRhKSx4ID0gIkRhdGUgKGhvdXJseSkiLA0KICAgICAgIHk9IkNvdW50IiApDQpgYGANCg0KDQojIDMuNw0KDQpDb25zaWRlciB0aGUgbGFzdCBmaXZlIHllYXJzIG9mIHRoZSBHYXMgZGF0YSBmcm9tIGBhdXNfcHJvZHVjdGlvbmAuDQoNCmBgYHtyfQ0KZ2FzIDwtIHRhaWwoYXVzX3Byb2R1Y3Rpb24sIDUqNCkgfD4gc2VsZWN0KEdhcykNCg0KaGVhZChnYXMpDQpgYGANCg0KIyBhLg0KDQpQbG90IHRoZSB0aW1lIHNlcmllcy4gQ2FuIHlvdSBpZGVudGlmeSBzZWFzb25hbCBmbHVjdHVhdGlvbnMgYW5kL29yIGEgdHJlbmQtY3ljbGU/DQoNCipMb29rcyBsaWtlIHRoZSB0cmVuZCBmcm9tIDIwMDYtMjAxMCBpcyB1cHdhcmRzLiBTZWFzb25hbGl0eSBpcyB0aGUgaGlnaCBldmVyeSAzcmQgcXVhcnRlciBhbmQgbG93IGV2ZXJ5IDFyc3QgUXVhcnRlcioNCg0KYGBge3J9DQpnYXMlPiUNCiAgYXV0b3Bsb3QoR2FzKQ0KYGBgDQoNCg0KIyBiLg0KDQpVc2UgYGNsYXNzaWNhbF9kZWNvbXBvc2l0aW9uYCB3aXRoIGB0eXBlPW11bHRpcGxpY2F0aXZlYCB0byBjYWxjdWxhdGUgdGhlIHRyZW5kLWN5Y2xlIGFuZCBzZWFzb25hbCBpbmRpY2VzLg0KDQpSZWYgWzMuNCB2aWRlb10oaHR0cHM6Ly95b3V0dS5iZS8xbGpfaEpCR2czQT9zaT1UdXBiOWFLQXRqYnBmZjAzJnQ9Mzk5KQ0KDQpgYGB7cn0NCiNleGFtcGxlDQojIHVzX3JldGFpbF9lbXBsb3ltZW50IHw+DQojICAgbW9kZWwoY2xhc3NpY2FsX2RlY29tcG9zaXRpb24oRW1wbG95ZWQsIHR5cGUgPSAiYWRkaXRpdmUiKSkgfD4NCiMgICBjb21wb25lbnRzKCl8Pg0KIyAgIGF1dG9wbG90KCkreGxhYigiWWVhciIpKw0KIyAgIGdndGl0bGUoIkNsYXNzaWNhbCBhZGRpdGl2ZSBkZWNvbXBvc2l0aW9uIG9mIHRvdGFsIFVTIHJldGFpbCBlbXBsb3ltZW50IikNCmBgYA0KDQpgYGB7ciwgd2FybmluZz1GQUxTRX0NCmdhcyU+JQ0KICBtb2RlbChjbGFzc2ljYWxfZGVjb21wb3NpdGlvbihHYXMsdHlwZT0gIm11bHRpcGxpY2F0aXZlIikpJT4lDQogIGNvbXBvbmVudHMoKSU+JQ0KICBhdXRvcGxvdCt4bGFiKCIiKQ0KYGBgDQoNCg0KIyBjLg0KDQpEbyB0aGUgcmVzdWx0cyBzdXBwb3J0IHRoZSBncmFwaGljYWwgaW50ZXJwcmV0YXRpb24gZnJvbSBwYXJ0IGE/DQoNCipUaGUgcmVzdWx0cyBzaG93IGEgcG9zaXRpdmUgdHJlbmQgd2l0aCBxdWFydGVybHkgc2Vhc29uYWxpdHkgc28geWVzIGl0IGRvZXMuKg0KDQojIGQuDQoNCkNvbXB1dGUgYW5kIHBsb3QgdGhlIHNlYXNvbmFsbHkgYWRqdXN0ZWQgZGF0YS4NCg0KQXMgc2hvd24gaW4gMy41DQoNCmBgYHtyfQ0KI0V4YW1wbGUNCiMgeDExX2RjbXAgfD4NCiMgICBnZ3Bsb3QoYWVzKHggPSBNb250aCkpICsNCiMgICBnZW9tX2xpbmUoYWVzKHkgPSBFbXBsb3llZCwgY29sb3VyID0gIkRhdGEiKSkgKw0KIyAgIGdlb21fbGluZShhZXMoeSA9IHNlYXNvbl9hZGp1c3QsDQojICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiU2Vhc29uYWxseSBBZGp1c3RlZCIpKSArDQojICAgZ2VvbV9saW5lKGFlcyh5ID0gdHJlbmQsIGNvbG91ciA9ICJUcmVuZCIpKSArDQojICAgbGFicyh5ID0gIlBlcnNvbnMgKHRob3VzYW5kcykiLA0KIyAgICAgICAgdGl0bGUgPSAiVG90YWwgZW1wbG95bWVudCBpbiBVUyByZXRhaWwiKSArDQojICAgc2NhbGVfY29sb3VyX21hbnVhbCgNCiMgICAgIHZhbHVlcyA9IGMoImdyYXkiLCAiIzAwNzJCMiIsICIjRDU1RTAwIiksDQojICAgICBicmVha3MgPSBjKCJEYXRhIiwgIlNlYXNvbmFsbHkgQWRqdXN0ZWQiLCAiVHJlbmQiKQ0KIyAgICkNCg0KYGBgDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KDQpnYXMlPiUNCiAgbW9kZWwoY2xhc3NpY2FsX2RlY29tcG9zaXRpb24oR2FzLHR5cGU9ICJtdWx0aXBsaWNhdGl2ZSIpKSU+JQ0KICBjb21wb25lbnRzKCklPiUNCiAgZ2dwbG90KGFlcyh4ID0gUXVhcnRlcikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gR2FzLCBjb2xvdXIgPSAiRGF0YSIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IHNlYXNvbl9hZGp1c3QsDQogICAgICAgICAgICAgICAgY29sb3VyID0gIlNlYXNvbmFsbHkgQWRqdXN0ZWQiKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSB0cmVuZCwgY29sb3VyID0gIlRyZW5kIikpICsNCiAgbGFicyh5ID0gIkdhcyBjb3VudCBpbiBQSiIsDQogICAgICAgdGl0bGUgPSAiQXVzdHJhbGlhbiBHYXMgUHJvZHVjdGlvbiIpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKCJncmF5IiwgIiMwMDcyQjIiLCAiI0Q1NUUwMCIpLA0KICAgIGJyZWFrcyA9IGMoIkRhdGEiLCAiU2Vhc29uYWxseSBBZGp1c3RlZCIsICJUcmVuZCIpDQogICkNCg0KYGBgDQoNCg0KIyBlLg0KDQpDaGFuZ2Ugb25lIG9ic2VydmF0aW9uIHRvIGJlIGFuIG91dGxpZXIgKGUuZy4sIGFkZCAzMDAgdG8gb25lIG9ic2VydmF0aW9uKSwgYW5kIHJlY29tcHV0ZSB0aGUgc2Vhc29uYWxseSBhZGp1c3RlZCBkYXRhLiBXaGF0IGlzIHRoZSBlZmZlY3Qgb2YgdGhlIG91dGxpZXI/DQoNCmBgYHtyfQ0Kcm0obGlzdCA9IGxzKHBhdHRlcm4gPSAiXmZpZyIpKQ0KYGBgDQoNCg0KYGBge3J9DQpwcmludChucm93KGdhcykpDQpgYGANCg0KDQpgYGB7cn0NCmdhc19iZWdpbl9lZGl0IDwtIGdhcw0KZ2FzX2VuZF9lZGl0IDwtIGdhcw0KZ2FzX2JlZ2luX2VkaXQkR2FzWzFdIDwtIGdhc19iZWdpbl9lZGl0JEdhc1sxMF0gKyAzMDANCmdhc19lbmRfZWRpdCRHYXNbMjBdIDwtIGdhc19iZWdpbl9lZGl0JEdhc1sxMF0gKyAzMDANCmBgYA0KDQpgYGB7cn0NCg0KZmlnMTwtZ2FzX2JlZ2luX2VkaXQlPiUNCiAgbW9kZWwoY2xhc3NpY2FsX2RlY29tcG9zaXRpb24oR2FzLHR5cGU9ICJtdWx0aXBsaWNhdGl2ZSIpKSU+JQ0KICBjb21wb25lbnRzKCklPiUNCiAgZ2dwbG90KGFlcyh4ID0gUXVhcnRlcikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gR2FzLCBjb2xvdXIgPSAiRGF0YSIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IHNlYXNvbl9hZGp1c3QsDQogICAgICAgICAgICAgICAgY29sb3VyID0gIlNlYXNvbmFsbHkgQWRqdXN0ZWQiKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSB0cmVuZCwgY29sb3VyID0gIlRyZW5kIikpICsNCiAgbGFicyh5ID0gIkdhcyBjb3VudCBpbiBQSiIsDQogICAgICAgdGl0bGUgPSAiQXVzdHJhbGlhbiBHYXMgUHJvZHVjdGlvbiIpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCgNCiAgICB2YWx1ZXMgPSBjKCJncmF5IiwgIiMwMDcyQjIiLCAiI0Q1NUUwMCIpLA0KICAgIGJyZWFrcyA9IGMoIkRhdGEiLCAiU2Vhc29uYWxseSBBZGp1c3RlZCIsICJUcmVuZCIpDQogICkNCg0KZmlnMjwtZ2FzX2VuZF9lZGl0JT4lDQogIG1vZGVsKGNsYXNzaWNhbF9kZWNvbXBvc2l0aW9uKEdhcyx0eXBlPSAibXVsdGlwbGljYXRpdmUiKSklPiUNCiAgY29tcG9uZW50cygpJT4lDQogIGdncGxvdChhZXMoeCA9IFF1YXJ0ZXIpKSArDQogIGdlb21fbGluZShhZXMoeSA9IEdhcywgY29sb3VyID0gIkRhdGEiKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBzZWFzb25fYWRqdXN0LA0KICAgICAgICAgICAgICAgIGNvbG91ciA9ICJTZWFzb25hbGx5IEFkanVzdGVkIikpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gdHJlbmQsIGNvbG91ciA9ICJUcmVuZCIpKSArDQogIGxhYnMoeSA9ICJHYXMgY291bnQgaW4gUEoiLA0KICAgICAgIHRpdGxlID0gIkF1c3RyYWxpYW4gR2FzIFByb2R1Y3Rpb24iKSArDQogIHNjYWxlX2NvbG91cl9tYW51YWwoDQogICAgdmFsdWVzID0gYygiZ3JheSIsICIjMDA3MkIyIiwgIiNENTVFMDAiKSwNCiAgICBicmVha3MgPSBjKCJEYXRhIiwgIlNlYXNvbmFsbHkgQWRqdXN0ZWQiLCAiVHJlbmQiKQ0KICApDQoNCnBsb3RfZ3JpZChmaWcxK2xhYnModGl0bGUgPSAiRWRpdCBpbiB0aGUgYmVnaW5uaW5nIiksDQogICAgICAgICAgZmlnMitsYWJzKHRpdGxlID0gIkVkaXQgaW4gdGhlIGVuZCIpLCBucm93PTIpDQoNCmBgYA0KDQoqSXQgc3Bpa2VzIHRoZSBkYXRhKg0KDQoNCiMgZi4NCg0KRG9lcyBpdCBtYWtlIGFueSBkaWZmZXJlbmNlIGlmIHRoZSBvdXRsaWVyIGlzIG5lYXIgdGhlIGVuZCByYXRoZXIgdGhhbiBpbiB0aGUgbWlkZGxlIG9mIHRoZSB0aW1lIHNlcmllcz8NCg0KKkp1c3QgcGxhY2VtZW50LCBidXQgdGhlIGVmZmVjdCBpcyB0aGUgc2FtZSoNCg0KIyAzLjgNCg0KUmVjYWxsIHlvdXIgcmV0YWlsIHRpbWUgc2VyaWVzIGRhdGEgKGZyb20gRXhlcmNpc2UgNyBpbiBTZWN0aW9uIDIuMTApLiBEZWNvbXBvc2UgdGhlIHNlcmllcyB1c2luZyBYLTExLiBEb2VzIGl0IHJldmVhbCBhbnkgb3V0bGllcnMsIG9yIHVudXN1YWwgZmVhdHVyZXMgdGhhdCB5b3UgaGFkIG5vdCBub3RpY2VkIHByZXZpb3VzbHk/DQoNCioqQXMgcGVyIDMuNSBNZXRob2RzIHVzZWQgYnkgb2ZmaWNpYWwgc3RhdGlzdGljcyBhZ2VuY2llcyoqDQoNCmBgYHtyfQ0KI0V4YW1wbGUNCiMgeDExX2RjbXAgPC0gdXNfcmV0YWlsX2VtcGxveW1lbnQgfD4NCiMgICBtb2RlbCh4MTEgPSBYXzEzQVJJTUFfU0VBVFMoRW1wbG95ZWQgfiB4MTEoKSkpIHw+DQojICAgY29tcG9uZW50cygpDQojIGF1dG9wbG90KHgxMV9kY21wKSArDQojICAgbGFicyh0aXRsZSA9DQojICAgICAiRGVjb21wb3NpdGlvbiBvZiB0b3RhbCBVUyByZXRhaWwgZW1wbG95bWVudCB1c2luZyBYLTExLiIpDQpgYGANCg0KDQpgYGB7cn0NCnNldC5zZWVkKDI0MSkNCg0KbXlzZXJpZXMgPC0gYXVzX3JldGFpbCAlPiUNCiAgZmlsdGVyKGBTZXJpZXMgSURgID09IHNhbXBsZShhdXNfcmV0YWlsJGBTZXJpZXMgSURgLDEpKQ0KDQp4MTFfZGNtcCA8LSBteXNlcmllcyAlPiUNCiAgbW9kZWwoeDExID0gWF8xM0FSSU1BX1NFQVRTKFR1cm5vdmVyIH4geDExKCkpKSAlPiUNCiAgY29tcG9uZW50cygpDQoNCmF1dG9wbG90KHgxMV9kY21wKSArDQogIGxhYnModGl0bGUgPQ0KICAgICJEZWNvbXBvc2l0aW9uIG9mIHRvdGFsIFVTIHJldGFpbCBlbXBsb3ltZW50IHVzaW5nIFgtMTEuIikNCmBgYA0KDQoqKkkgbm90ZWQgYSBsb25nLXRlcm0gZG93bndhcmQgdHJlbmQgYW5kIGdyZWF0ZXIgdm9sYXRpbGl0eSB3aXRoIHRoZSBzZWFzb25hbCBzcGlrZXMNCg0KIyAzLjkNCg0KRmlndXJlcyAzLjE5IGFuZCAzLjIwIHNob3cgdGhlIHJlc3VsdCBvZiBkZWNvbXBvc2luZyB0aGUgbnVtYmVyIG9mIHBlcnNvbnMgaW4gdGhlIGNpdmlsaWFuIGxhYm91ciBmb3JjZSBpbiBBdXN0cmFsaWEgZWFjaCBtb250aCBmcm9tIEZlYnJ1YXJ5IDE5NzggdG8gQXVndXN0IDE5OTUuDQoNCiFbXSguL0ltYWdlcy9JTUczXzE5LnBuZykNCg0KIVtdKC4vSW1hZ2VzL0lNRzNfMjAucG5nKQ0KDQojIGEuDQoNCldyaXRlIGFib3V0IDPigJM1IHNlbnRlbmNlcyBkZXNjcmliaW5nIHRoZSByZXN1bHRzIG9mIHRoZSBkZWNvbXBvc2l0aW9uLiBQYXkgcGFydGljdWxhciBhdHRlbnRpb24gdG8gdGhlIHNjYWxlcyBvZiB0aGUgZ3JhcGhzIGluIG1ha2luZyB5b3VyIGludGVycHJldGF0aW9uLg0KDQpUaGUgdHJlbmQgaXMgY2xlYXJseSBhIHVwd2FyZCB0cmVuZCBmcm9tIDE5NzgtMTk5NSwgYW5kIHdoYXQgYXBwZWFycyB0byBiZSBzb21lIHNlYXNvbmFsaXR5LiBUaGlzIG1ha2VzIHNlbnNlIHRvIG1lIGFzIHRoZSBzcGlrZXMgYXJlIGNvbW1vbiwgd2l0aCBzdHVkZW50cyBsZWF2aW5nIHNjaG9vbCBmb3IgdGhlIGhvbGlkYXkgYW5kIHN1bW1lciwgYW5kIHNlYXNvbmFsIHdvcmsgb2NjdXJyaW5nIHRocm91Z2hvdXQgdGhlIHllYXIuIEknbSBjdXJpb3VzIHdoYXQgY2F1c2VkIHRoZSBkaXAgaW4gMTk5MiB3aGljaCBpcyBhIHByZXR0eSBjbGVhciBvdXRsaWVyLg0KDQojIGIuDQoNCklzIHRoZSByZWNlc3Npb24gb2YgMTk5MS8xOTkyIHZpc2libGUgaW4gdGhlIGVzdGltYXRlZCBjb21wb25lbnRzPw0KDQpWZXJ5IG11Y2guIEl0cyBlYXNpbHkgb2JzZXJ2ZWQgaW4gdGhlICJyZW1haW5kZXIiIHBsb3Qu