Regression with Autoregressive Errors
In Lecture 34 we found that a regression can explain the mean quite
well and still leave neighbouring residuals related. If this month’s
response is above the fitted mean, next month’s deviation may also be
positive. How can we account for that dependence when estimating the
regression coefficients and their precision?
By the end of this lecture, students should be able to:
- Write down a regression model with AR(1) errors.
- Explain why autocorrelated errors distort ordinary standard
errors.
- Fit a regression model with
gls() and
corAR1().
- Check whether normalised residuals look closer to white noise.
Main Worked Example: Tourism in Victoria
These data record monthly room nights occupied in hotels, motels, and
guesthouses in Victoria from January 1980 to December 1994. We have 180
observations, one for each month.
Download motel.csv
tourism <- read_csv("../data/motel.csv", show_col_types = FALSE) |>
mutate(Date = as.Date(Date), Time = round(time_length(Date - min(Date), unit = "month")),
Month = factor(month(Date, label = TRUE), ordered = FALSE), Year = year(Date)) |>
arrange(Date)
stopifnot(nrow(tourism) == 180, all(diff(tourism$Time) == 1))
Time counts months from the start of the series.
Month lets expected room nights differ between January,
February, and so on.
Tourism: Fit the Mean First
We allow a linear trend and a separate effect for each month:
tourism_lm <- lm(RoomNights ~ Time + Month, data = tourism)

The fitted mean follows much of the growth and seasonal variation.
Now check the deviations around it.
Tourism: What Remains Over Time?

Follow the residuals in time order. Several consecutive months can
sit on the same side of zero even after fitting trend and month effects.
A seasonal pattern in the mean and dependence among the
errors are different parts of the model.
Tourism: ACF Before GLS
acf(resid(tourism_lm), lag.max = 24, main = "OLS tourism residuals", xlab = "Lag (months)",
ylim = c(-0.4, 1))

Lag 1 is one month; lag 12 is one year. The lag-1 correlation is
about 0.377, with positive correlations at several nearby lags. An AR(1)
error model is a reasonable first attempt to account for that
persistence.
Why Ordinary Least Squares Is Not Enough
If the mean model is correctly specified and the errors average to
zero given the predictors, correlated errors do not by themselves make
the OLS coefficients biased.
The usual OLS standard errors still assume independent errors. When
nearby deviations tend to move together, their contribution to precision
differs from that calculation. Confidence intervals and tests based on
it can therefore be unreliable.
We will keep the same trend and month predictors and change the model
for the errors. The direction and size of the standard-error change
depend on the predictors and the dependence pattern.
The AR(1) Error Model
A first-order autoregressive, or AR(1), error model
is
\[\varepsilon_t = \phi\varepsilon_{t-1} +
\eta_t.\]
The current error contains a contribution from the previous error,
\(\phi\varepsilon_{t-1}\), plus a new
disturbance, \(\eta_t\). We call \(\eta_t\) the innovation:
the part that was not carried forward from the past.
We assume the innovations are independent of past errors and of one
another, with mean zero and constant variance.
- If \(\phi>0\), nearby errors
tend to move in the same direction.
- If \(\phi<0\), nearby errors
tend to alternate.
- If \(\phi=0\), each error is just
its new innovation.
AR(1): Put Numbers Into the Equation
Suppose \(\phi=0.4\) and last
month’s error was 1,000 room nights. The contribution carried into this
month is
\[\phi\varepsilon_{t-1}=0.4\times1{,}000=400.\]
If this month’s error is 500, the new disturbance must be
\[\eta_t=\varepsilon_t-\phi\varepsilon_{t-1}=500-400=100.\]
The model separates the 500 into 400 carried forward and 100 of new
disturbance. Before observing this month’s innovation, its expected
error would be 400. The realised error can differ because a new
disturbance arrives.
These are illustrative errors. In real data we do not know the true
errors, so we estimate the mean and work with residuals.
How Long Does the Dependence Last?
For a stationary AR(1) process, the lag-\(k\) error correlation is \(\phi^k\). With \(\phi=0.4\):
| One month |
\(0.4\) |
| Two months |
\(0.4^2=0.16\) |
| Three months |
\(0.4^3=0.064\) |
The previous error carries information about the next one, but that
information weakens across longer gaps.
We require \(|\phi|<1\) for a
stationary AR(1) error process. Here stationary means
the error process has a stable mean and variance, and correlations
depend on the time gap. The response itself can still have trend and
seasonality through its mean model.
Regression Model with AR(1) Errors
For the tourism data, our two model components are
\[\begin{aligned}
Y_t &= \beta_0 + \beta_1\mathrm{Time}_t + \beta_2z_{t,2} + \cdots +
\beta_{12}z_{t,12} + \varepsilon_t, \\
\varepsilon_t &= \phi\varepsilon_{t-1} + \eta_t.
\end{aligned}\]
The \(z_{t,j}\) terms are the 11
month indicators, with January as the reference month.
The first equation describes expected room nights given time and
month. The second describes how deviations from that expectation
persist. Adding AR(1) errors does not add last month’s observed room
nights as a predictor in the mean formula.
Why GLS Works: Compare Two Adjacent Times
To see the calculation with one predictor, write the regression at
times \(t\) and \(t-1\):
\[\begin{aligned}
y_t &= \beta_0 + \beta_1x_t + \varepsilon_t, \\
y_{t-1} &= \beta_0 + \beta_1x_{t-1} + \varepsilon_{t-1}.
\end{aligned}\]
Multiply the second equation by \(\phi\). Subtracting it from the first
leaves the error difference
\[\varepsilon_t-\phi\varepsilon_{t-1}=\eta_t.\]
Under the AR(1) model, this difference is the new innovation. We have
removed the contribution carried forward from the previous error.
Fitting the AR(1) Model in R
gls() from nlme takes the usual mean
formula plus a correlation structure:
tourism_gls <- gls(RoomNights ~ Time + Month, correlation = corAR1(form = ~Time),
data = tourism)
RoomNights ~ Time + Month specifies the mean.
corAR1(form = ~ Time) specifies how errors are related
according to their separation in time.
Time must be integer-valued and counts months here.
Observations two months apart have modelled error correlation \(\phi^2\), rather than \(\phi\).
Tourism: Interpret the Estimated Dependence
tourism_phi <- unname(coef(tourism_gls$modelStruct$corStruct, unconstrained = FALSE))
We estimate \(\hat\phi\approx
0.393\). After allowing for trend and month effects, errors one
month apart have an estimated correlation of about 0.39 under this
model.
That estimate describes the modelled dependence. We
still need to check whether the model accounts for the pattern in these
data.
How Precisely Have We Estimated the Correlation?
\(\hat\phi\) is an estimate from 180
months of data, so it carries uncertainty of its own.
intervals(tourism_gls)
Approximate 95% confidence intervals
Coefficients:
lower est. upper
(Intercept) 266228.1202 275492.204 284756.287
Time 999.3307 1062.250 1125.169
MonthFeb -39495.9823 -31194.086 -22892.190
MonthMar 13691.2693 23482.727 33274.185
MonthApr -12487.0081 -2170.467 8146.074
MonthMay -29933.5149 -19419.121 -8904.728
MonthJun -76415.1029 -65827.114 -55239.126
MonthJul -55130.5097 -44522.343 -33914.177
MonthAug -40361.8121 -29768.745 -19175.677
MonthSept -22565.9807 -12039.271 -1512.561
MonthOct 16051.4987 26393.955 36736.411
MonthNov 6623.9585 16471.666 26319.373
MonthDec -67066.8155 -58631.939 -50197.063
Correlation structure:
lower est. upper
Phi 0.2419081 0.392721 0.5250065
Residual standard error:
lower est. upper
13041.25 14799.38 16794.53
The Phi row repeats our estimate and adds an approximate
95% interval for the error correlation. In Lab 13 you will read the same
row for the Perth house-price data, where only 45 quarters are available
and the interval is wider.
The lesson to carry forward: an estimate of \(\phi\) near zero does not by itself
establish independence when the interval around it is wide.
Where Does the GLS Standard Error Come From?
Lecture 34 wrote down the variance OLS reports when independence
fails. GLS uses the fitted error model instead:
\[\operatorname{Var}(\widehat{\boldsymbol\beta}_{\text{GLS}})
=(X^\top\widehat\Sigma^{-1}X)^{-1}.\]
\(\widehat\Sigma\) is the estimated
error covariance matrix. For AR(1) errors it is assembled from \(\hat\phi\) and \(\hat\sigma\), because this model fixes
\(\operatorname{Corr}(\varepsilon_s,\varepsilon_t)=\phi^{|s-t|}\).
Here \(\hat\sigma\) is the innovation
standard deviation, the scale of the new disturbances \(\eta_t\): summary(tourism_gls)
reports it as the residual standard deviation, and the raw errors
themselves have variance \(\sigma^2/(1-\phi^2)\).
Neither parameter is known in advance, so gls()
estimates \(\phi\) and \(\sigma\) alongside the regression
coefficients. When neighbouring errors carry overlapping information,
\((X^\top\widehat\Sigma^{-1}X)^{-1}\)
can give larger variances than the independent-errors formula, even with
an almost unchanged mean fit. The comparison below is where that shows
up.
Tourism: What Happens to the Trend and Its Precision?
| OLS |
1058.8 |
21.2 |
| GLS with AR(1) |
1062.2 |
31.9 |
Holding month constant, expected room nights increase by about 1,062
for each additional month. The trend estimate barely changes between the
two fits.
Its standard error increases by about 51%. A similar fitted mean can
have a different precision calculation once we account for dependence.
GLS can also change coefficient estimates; neither the direction nor the
size of these changes is universal.
Selection inherits this change. Comparing models by AIC ranks them
using the fitted error model, and judging a term by its t-statistic
reads the standard errors shown here, so an error model can change which
terms look worth keeping. Any such comparison between models with
different mean formulas should be made with method = "ML"
in gls(), since the default REML likelihood is intended for
models sharing a mean structure.
Which GLS Residuals Should We Check?
The raw GLS residual is still observed minus fitted:
\[e_t=y_t-\widehat\mu_t.\]
Our model allows these deviations to be correlated. We should
therefore expect raw residuals to retain some of that correlation, even
when the error model is reasonable.
Normalised residuals account for the fitted
correlation and rescale the residuals. For adjacent times in this AR(1)
example, the calculation is based on \(e_t-\hat\phi e_{t-1}\), followed by
scaling. We check these for remaining dependence.
The name normalised describes that transformation. It does
not mean the residual distribution has been made normal. See the nlme
residual documentation.
Tourism: Raw and Normalised Residuals
tourism_raw <- residuals(tourism_gls, type = "response")
tourism_normalised <- residuals(tourism_gls, type = "normalized")
| OLS |
0.377 |
0.192 |
| GLS: raw |
0.378 |
0.193 |
| GLS: normalised |
-0.057 |
0.272 |
The raw GLS residuals have much the same lag-1 correlation as the OLS
residuals. After accounting for the fitted dependence, the normalised
residuals have much less lag-1 correlation. The lag-12 value still needs
attention.
Tourism: Residual Patterns Before and After GLS

Both plots use the same months. The OLS residuals are divided by
their estimated residual standard deviation to put them on a comparable
scale. Look for persistence in the sequence, as well as large individual
deviations.
Tourism: ACF Before and After GLS

Lag 0 is omitted because it is always 1. The panels have identical
axes. Lag 1 falls from 0.377 to -0.057, but lag 12 remains positive at
0.272.
The dashed lines are approximate pointwise white-noise reference
limits. They guide inspection; they do not prove independence or form a
simultaneous band across all lags.
Tourism: Repeat Ljung-Box Across One Year
The ACF shows where correlation remains. Ljung-Box combines
the correlations across a chosen set of lags. Use lags 1 through 12 to
include gaps of up to one year:
\[H_0:\rho_1=\cdots=\rho_{12}=0.\]
tourism_lb_ols <- Box.test(resid(tourism_lm), lag = 12, type = "Ljung-Box", fitdf = 0)
tourism_lb_gls <- Box.test(tourism_normalised, lag = 12, type = "Ljung-Box", fitdf = 1)
We chose 12 using the monthly time scale, rather than searching for a
lag that gives a preferred P-value.
Tourism: Has the Dependence Been Accounted For?
| OLS |
71.03 |
12 |
< 1e-04 |
| GLS: normalised |
32.74 |
11 |
0.000579 |
The statistic is smaller after normalisation, and the lag-1
correlation is much reduced. The remaining small P-value and lag-12 ACF
bar still give evidence of dependence across these lags.
Tourism: What Would We Investigate Next?
The month indicators already allow the average January mean
to differ from the average February mean. They do not necessarily
account for changing seasonal effects or dependence between deviations
one year apart.
I would check whether the trend or seasonal mean is missing
structure, then consider whether the errors need a richer model for
seasonal dependence. The lag-12 bar identifies a time gap to
investigate; it does not identify the correct replacement model.
Correlation magnitude tells us how large a particular sample
relationship is. A P-value measures evidence against a reference
hypothesis. A larger P-value, or a smaller Ljung-Box statistic, would
not establish that all dependence had been resolved.
Work Through the AR(1) Calculation
Suppose \(\phi=0.6\), the previous
error is \(-200\), and the current
error is \(-50\). What is the
innovation?
. . .
The contribution carried forward is \(0.6\times(-200)=-120\). Therefore
\[\eta_t=-50-(-120)=70.\]
The new disturbance is positive even though the current error is
negative. It partly offsets the negative contribution from the past.
Which Residuals Answer Our Diagnostic Question?
After fitting AR(1) errors, the raw GLS residuals still have positive
lag-1 correlation. Does that alone show the model failed?
. . .
No. The model allows raw deviations from the fitted mean to be
correlated. We inspect normalised residuals to ask
whether dependence remains after accounting for the fitted error
structure.
A large estimated \(\phi\) and a
small normalised lag-1 correlation can occur together: the model has
estimated substantial dependence and accounted for much of it.
Interpret the Before-and-After ACF
Lag-1 correlation is close to zero after normalisation, but lag-12
correlation remains large. What conclusion can we draw?
. . .
AR(1) has accounted for much of the neighbouring-month dependence. It
has left a pattern at a one-year gap, so we should investigate the mean
and the error model further.
Checking only lag 1 would miss that remaining pattern. We need the
time plot, the wider ACF and a joint diagnostic, rather than a single
numerical verdict.
A Short Comparison: Seoul Bike with AR(1) Errors
Return to the daily Seoul bike model from Lectures 32/33. Its mean
includes the time trend, two Fourier pairs and weather predictors. We
now fit both OLS and GLS to all functioning days.
Download seoul_bike_daily.csv
seoul_lm <- lm(rented_bike_count ~ day_index + S1 + C1 + S2 + C2 + mean_temperature +
total_rainfall + total_solar_radiation, data = seoul_daily)
S1, C1, S2 and C2
are the same annual seasonal terms used earlier. The mean formula is
held constant for the comparison.
Seoul: Fit AR(1) Using Actual Day Distances
seoul_gls <- gls(rented_bike_count ~ day_index + S1 + C1 + S2 + C2 + mean_temperature +
total_rainfall + total_solar_radiation, correlation = corAR1(form = ~day_index),
data = seoul_daily)
Both models use all 352 functioning days. We retain the original
day_index after removing the 13 outage days. A gap of three
days therefore has modelled error correlation \(\phi^3\), rather than being treated as one
step.
Here \(\hat\phi\approx 0.503\). The
next question is whether the normalised residuals show less
dependence.
Seoul: Compare Estimates and Standard Errors
| OLS |
12.68 |
3.80 |
| GLS with AR(1) |
10.07 |
6.46 |
The day-index coefficient is the change in expected daily rentals per
additional day, holding the seasonal and weather predictors constant.
Its estimate changes from 12.68 to 10.07, while its standard error
increases.
As in tourism, accounting for dependence changes the precision
calculation. Here it also makes a more visible difference to the trend
estimate.
Seoul: Make a Matched Diagnostic Comparison
An ordinary ACF assumes equally spaced observations. Use the
uninterrupted period from 1 December 2017 to 10 April 2018 for
both residual sequences:
seoul_run <- seoul_diagnostics |>
filter(date >= as.Date("2017-12-01"), date <= as.Date("2018-04-10"))
stopifnot(nrow(seoul_run) == 131, all(diff(seoul_run$day_index) == 1), all(as.numeric(diff(seoul_run$date)) ==
1))
Both models were fitted on 352 days; these plots examine their
residuals on the same 131-day window. Lecture 34 refitted the
mean model on that window. Its residuals therefore differ from
the full-year OLS residuals compared here.
Seoul: ACF Before and After GLS

Lag-1 correlation falls from 0.549 to 0.042. There is much less
neighbouring-day dependence in this window, although the lag-14 bar
still stands out.
These plots do not establish adequacy across the whole year. We have
not treated the gappy 352-row series as equally spaced, or applied a
formal Ljung-Box test to this selected window.
What Would You Check After Fitting GLS?
Keep the mean and error questions separate. A plausible trend and
seasonal mean can still leave dependence, and a fitted AR(1) parameter
does not establish that the error model is adequate.
Inspect normalised residuals in time order, compare their ACF with
the original residual ACF, and interpret a joint diagnostic where
appropriate. Check longer gaps as well as lag 1.
For tourism, we have accounted for much of the short-term
persistence, while seasonal dependence remains worth investigating. For
Seoul, the matched window shows a substantial improvement, with
conclusions limited to that period. In each case, the next modelling
decision comes from what remains in the residuals.
Looking Forward
We stop at AR(1) errors: the simplest model we could write for
dependence between neighbouring observations. The same move, choosing a
structure for \(\Sigma\) and estimating
it alongside the mean, is the working heart of several fields this
course does not reach.
- ARIMA models: the standard forecasting toolkit.
Differencing removes a trend before fitting, and autoregressive and
moving-average terms let the errors carry longer memory than our single
\(\phi\). Used for short-term forecasts
of demand, energy and economic series, each issued with a prediction
interval.
- GARCH models: for returns and other series where
volatility itself is correlated. Today’s variance is written as a
function of yesterday’s squared innovations, so calm stretches follow
calm and wild follow wild. Banks and insurers build risk measures on
it.
- Mixed models: for grouped data such as repeated
measurements on the same patient, plot or school. Each group receives
its own coefficient drawn from a shared distribution, which builds a
block structure into \(\Sigma\). The
workhorse of longitudinal and clinical studies.
- Gaussian processes: replace the fixed \(\phi^k\) decay with a covariance function
of distance. The joint distribution of fitted values then gives
prediction intervals that widen away from the data. This is kriging in
geostatistics and the surrogate behind Bayesian optimisation in machine
learning.
All four reuse the move we made today: model the covariance, estimate
it with the mean, and let the residuals say whether more structure is
needed.
LS0tDQp0aXRsZTogIkxlY3R1cmUgMzU6IFJlZ3Jlc3Npb24gd2l0aCBBdXRvcmVncmVzc2l2ZSBFcnJvcnMiDQpzdWJ0aXRsZTogMTYxLjI1MSBSZWdyZXNzaW9uIE1vZGVsbGluZw0KYXV0aG9yOiAiUHJlc2VudGVkIGJ5IE5pY2sgS25vd2x0b24gPE4uS25vd2x0b25AbWFzc2V5LmFjLm56PiIgIA0KZGF0ZTogIldlZWsgMTIgb2YgU2VtZXN0ZXIgMiwgYHIgbHVicmlkYXRlOjp5ZWFyKGx1YnJpZGF0ZTo6bm93KCkpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHRfc3R5bGU6IHB5Z21lbnRzDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0X3N0eWxlOiBweWdtZW50cw0KICBpb3NsaWRlc19wcmVzZW50YXRpb246DQogICAgd2lkZXNjcmVlbjogdHJ1ZQ0KICAgIHNtYWxsZXI6IHRydWUNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KICBzbGlkeV9wcmVzZW50YXRpb246IA0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0X3N0eWxlOiBweWdtZW50cw0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQoNCg0KDQo8IS0tLSBEYXRhIGlzIG9uDQpodHRwczovL3ItcmVzb3VyY2VzLm1hc3NleS5hYy5uei9kYXRhLzE2MTI1MS8NCi0tLT4NCg0KYGBge3Igc2V0dXAsIHB1cmw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGtuaXRyKQ0Kb3B0c19jaHVuayRzZXQoZGV2PWMoInBuZyIsICJwZGYiKSkNCm9wdHNfY2h1bmskc2V0KGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTcsIGZpZy5wYXRoPSJGaWd1cmVzLyIsIGZpZy5hbHQ9InVubGFiZWxsZWQiKQ0Kb3B0c19jaHVuayRzZXQoY29tbWVudD0iIiwgZmlnLmFsaWduPSJjZW50ZXIiLCB0aWR5PVRSVUUpDQpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gJycpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnJvb20pDQpgYGANCg0KDQo8IS0tLSBEbyBub3QgZWRpdCBhbnl0aGluZyBhYm92ZSB0aGlzIGxpbmUuIC0tLT4NCmBgYHtyIGF1dG9yZWdyZXNzaXZlLWVycm9ycy1zZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkobmxtZSkNCmxpYnJhcnkoYnJvb20ubWl4ZWQpDQpgYGANCg0KIyMgUmVncmVzc2lvbiB3aXRoIEF1dG9yZWdyZXNzaXZlIEVycm9ycw0KDQpJbiBMZWN0dXJlIDM0IHdlIGZvdW5kIHRoYXQgYSByZWdyZXNzaW9uIGNhbiBleHBsYWluIHRoZSBtZWFuIHF1aXRlIHdlbGwgYW5kIHN0aWxsIGxlYXZlIG5laWdoYm91cmluZyByZXNpZHVhbHMgcmVsYXRlZC4gSWYgdGhpcyBtb250aCdzIHJlc3BvbnNlIGlzIGFib3ZlIHRoZSBmaXR0ZWQgbWVhbiwgbmV4dCBtb250aCdzIGRldmlhdGlvbiBtYXkgYWxzbyBiZSBwb3NpdGl2ZS4gSG93IGNhbiB3ZSBhY2NvdW50IGZvciB0aGF0IGRlcGVuZGVuY2Ugd2hlbiBlc3RpbWF0aW5nIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBhbmQgdGhlaXIgcHJlY2lzaW9uPw0KDQpCeSB0aGUgZW5kIG9mIHRoaXMgbGVjdHVyZSwgc3R1ZGVudHMgc2hvdWxkIGJlIGFibGUgdG86DQoNCjEuIFdyaXRlIGRvd24gYSByZWdyZXNzaW9uIG1vZGVsIHdpdGggQVIoMSkgZXJyb3JzLg0KMi4gRXhwbGFpbiB3aHkgYXV0b2NvcnJlbGF0ZWQgZXJyb3JzIGRpc3RvcnQgb3JkaW5hcnkgc3RhbmRhcmQgZXJyb3JzLg0KMy4gRml0IGEgcmVncmVzc2lvbiBtb2RlbCB3aXRoIGBnbHMoKWAgYW5kIGBjb3JBUjEoKWAuDQo0LiBDaGVjayB3aGV0aGVyIG5vcm1hbGlzZWQgcmVzaWR1YWxzIGxvb2sgY2xvc2VyIHRvIHdoaXRlIG5vaXNlLg0KDQojIyBNYWluIFdvcmtlZCBFeGFtcGxlOiBUb3VyaXNtIGluIFZpY3RvcmlhDQoNClRoZXNlIGRhdGEgcmVjb3JkIG1vbnRobHkgcm9vbSBuaWdodHMgb2NjdXBpZWQgaW4gaG90ZWxzLCBtb3RlbHMsIGFuZCBndWVzdGhvdXNlcyBpbiBWaWN0b3JpYSBmcm9tIEphbnVhcnkgMTk4MCB0byBEZWNlbWJlciAxOTk0LiBXZSBoYXZlIDE4MCBvYnNlcnZhdGlvbnMsIG9uZSBmb3IgZWFjaCBtb250aC4NCg0KYHIgeGZ1bjo6ZW1iZWRfZmlsZSgiLi4vZGF0YS9tb3RlbC5jc3YiKWANCg0KYGBge3IgcmVhZC10b3VyaXNtfQ0KdG91cmlzbSA8LSByZWFkX2NzdigiLi4vZGF0YS9tb3RlbC5jc3YiLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSB8Pg0KICBtdXRhdGUoDQogICAgRGF0ZSA9IGFzLkRhdGUoRGF0ZSksDQogICAgVGltZSA9IHJvdW5kKHRpbWVfbGVuZ3RoKERhdGUgLSBtaW4oRGF0ZSksIHVuaXQgPSAibW9udGgiKSksDQogICAgTW9udGggPSBmYWN0b3IobW9udGgoRGF0ZSwgbGFiZWwgPSBUUlVFKSwgb3JkZXJlZCA9IEZBTFNFKSwNCiAgICBZZWFyID0geWVhcihEYXRlKQ0KICApIHw+DQogIGFycmFuZ2UoRGF0ZSkNCg0Kc3RvcGlmbm90KG5yb3codG91cmlzbSkgPT0gMTgwLCBhbGwoZGlmZih0b3VyaXNtJFRpbWUpID09IDEpKQ0KYGBgDQoNCmBUaW1lYCBjb3VudHMgbW9udGhzIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBzZXJpZXMuIGBNb250aGAgbGV0cyBleHBlY3RlZCByb29tIG5pZ2h0cyBkaWZmZXIgYmV0d2VlbiBKYW51YXJ5LCBGZWJydWFyeSwgYW5kIHNvIG9uLg0KDQojIyBUb3VyaXNtOiBGaXQgdGhlIE1lYW4gRmlyc3QNCg0KV2UgYWxsb3cgYSBsaW5lYXIgdHJlbmQgYW5kIGEgc2VwYXJhdGUgZWZmZWN0IGZvciBlYWNoIG1vbnRoOg0KDQpgYGB7ciB0b3VyaXNtLWxtfQ0KdG91cmlzbV9sbSA8LSBsbShSb29tTmlnaHRzIH4gVGltZSArIE1vbnRoLCBkYXRhID0gdG91cmlzbSkNCmBgYA0KDQpgYGB7ciB0b3VyaXNtLWxtLWZpdC1wbG90LCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0zLjUsIG91dC53aWR0aD0iODAlIiwgZmlnLmFsdD0iTW9udGhseSB0b3VyaXNtIHJvb20gbmlnaHRzIGFuZCB0aGUgT0xTIGZpdHRlZCB0cmVuZCB3aXRoIG1vbnRoIGVmZmVjdHMifQ0KYXVnbWVudCh0b3VyaXNtX2xtLCB0b3VyaXNtKSB8Pg0KICBnZ3Bsb3QoYWVzKHggPSBEYXRlKSkgKw0KICBnZW9tX3BvaW50KGFlcyh5ID0gUm9vbU5pZ2h0cyksIGNvbG91ciA9ICJncmV5NTUiLCBzaXplID0gMSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSAuZml0dGVkKSwgY29sb3VyID0gIiMxNzNmNWYiKSArDQogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJSb29tIG5pZ2h0cyIsIHRpdGxlID0gIk9MUzogdHJlbmQgYW5kIG1vbnRoIGVmZmVjdHMiKQ0KYGBgDQoNClRoZSBmaXR0ZWQgbWVhbiBmb2xsb3dzIG11Y2ggb2YgdGhlIGdyb3d0aCBhbmQgc2Vhc29uYWwgdmFyaWF0aW9uLiBOb3cgY2hlY2sgdGhlIGRldmlhdGlvbnMgYXJvdW5kIGl0Lg0KDQojIyBUb3VyaXNtOiBXaGF0IFJlbWFpbnMgT3ZlciBUaW1lPw0KDQpgYGB7ciB0b3VyaXNtLWxtLXJlc2lkdWFsLXBsb3QsIGVjaG89RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTMuNSwgb3V0LndpZHRoPSI4MCUiLCBmaWcuYWx0PSJPTFMgdG91cmlzbSByZXNpZHVhbHMgaW4gY2hyb25vbG9naWNhbCBvcmRlciB3aXRoIGEgcmVmZXJlbmNlIGxpbmUgYXQgemVybyJ9DQp0b3VyaXNtIHw+DQogIG11dGF0ZShyZXNpZHVhbCA9IHJlc2lkdWFscyh0b3VyaXNtX2xtKSkgfD4NCiAgZ2dwbG90KGFlcyhEYXRlLCByZXNpZHVhbCkpICsNCiAgZ2VvbV9saW5lKGNvbG91ciA9ICIjMTczZjVmIikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlJlc2lkdWFsIChyb29tIG5pZ2h0cykiKQ0KYGBgDQoNCkZvbGxvdyB0aGUgcmVzaWR1YWxzIGluIHRpbWUgb3JkZXIuIFNldmVyYWwgY29uc2VjdXRpdmUgbW9udGhzIGNhbiBzaXQgb24gdGhlIHNhbWUgc2lkZSBvZiB6ZXJvIGV2ZW4gYWZ0ZXIgZml0dGluZyB0cmVuZCBhbmQgbW9udGggZWZmZWN0cy4gQSBzZWFzb25hbCBwYXR0ZXJuIGluIHRoZSAqKm1lYW4qKiBhbmQgZGVwZW5kZW5jZSBhbW9uZyB0aGUgKiplcnJvcnMqKiBhcmUgZGlmZmVyZW50IHBhcnRzIG9mIHRoZSBtb2RlbC4NCg0KIyMgVG91cmlzbTogQUNGIEJlZm9yZSBHTFMNCg0KYGBge3IgdG91cmlzbS1sbS1yZXNpZHVhbC1hY2YsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTMuNSwgb3V0LndpZHRoPSI4MCUiLCBmaWcuYWx0PSJBQ0Ygb2YgT0xTIHRvdXJpc20gcmVzaWR1YWxzIGF0IGxhZ3MgdGhyb3VnaCAyNCBtb250aHMifQ0KYWNmKHJlc2lkKHRvdXJpc21fbG0pLCBsYWcubWF4ID0gMjQsDQogICAgbWFpbiA9ICJPTFMgdG91cmlzbSByZXNpZHVhbHMiLCB4bGFiID0gIkxhZyAobW9udGhzKSIsIHlsaW0gPSBjKC0wLjQsIDEpKQ0KYGBgDQoNCmBgYHtyIHRvdXJpc20tb2xzLWRpYWdub3N0aWMtdmFsdWVzLCBpbmNsdWRlPUZBTFNFfQ0KdG91cmlzbV9vbHNfciA8LSBhcy5udW1lcmljKGFjZihyZXNpZCh0b3VyaXNtX2xtKSwgbGFnLm1heCA9IDI0LCBwbG90ID0gRkFMU0UpJGFjZilbLTFdDQpgYGANCg0KTGFnIDEgaXMgb25lIG1vbnRoOyBsYWcgMTIgaXMgb25lIHllYXIuIFRoZSBsYWctMSBjb3JyZWxhdGlvbiBpcyBhYm91dCBgciByb3VuZCh0b3VyaXNtX29sc19yWzFdLCAzKWAsIHdpdGggcG9zaXRpdmUgY29ycmVsYXRpb25zIGF0IHNldmVyYWwgbmVhcmJ5IGxhZ3MuIEFuIEFSKDEpIGVycm9yIG1vZGVsIGlzIGEgcmVhc29uYWJsZSBmaXJzdCBhdHRlbXB0IHRvIGFjY291bnQgZm9yIHRoYXQgcGVyc2lzdGVuY2UuDQoNCiMjIFdoeSBPcmRpbmFyeSBMZWFzdCBTcXVhcmVzIElzIE5vdCBFbm91Z2gNCg0KSWYgdGhlIG1lYW4gbW9kZWwgaXMgY29ycmVjdGx5IHNwZWNpZmllZCBhbmQgdGhlIGVycm9ycyBhdmVyYWdlIHRvIHplcm8gZ2l2ZW4gdGhlIHByZWRpY3RvcnMsIGNvcnJlbGF0ZWQgZXJyb3JzIGRvIG5vdCBieSB0aGVtc2VsdmVzIG1ha2UgdGhlIE9MUyBjb2VmZmljaWVudHMgYmlhc2VkLg0KDQpUaGUgdXN1YWwgT0xTIHN0YW5kYXJkIGVycm9ycyBzdGlsbCBhc3N1bWUgaW5kZXBlbmRlbnQgZXJyb3JzLiBXaGVuIG5lYXJieSBkZXZpYXRpb25zIHRlbmQgdG8gbW92ZSB0b2dldGhlciwgdGhlaXIgY29udHJpYnV0aW9uIHRvIHByZWNpc2lvbiBkaWZmZXJzIGZyb20gdGhhdCBjYWxjdWxhdGlvbi4gQ29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIHRlc3RzIGJhc2VkIG9uIGl0IGNhbiB0aGVyZWZvcmUgYmUgdW5yZWxpYWJsZS4NCg0KV2Ugd2lsbCBrZWVwIHRoZSBzYW1lIHRyZW5kIGFuZCBtb250aCBwcmVkaWN0b3JzIGFuZCBjaGFuZ2UgdGhlIG1vZGVsIGZvciB0aGUgZXJyb3JzLiBUaGUgZGlyZWN0aW9uIGFuZCBzaXplIG9mIHRoZSBzdGFuZGFyZC1lcnJvciBjaGFuZ2UgZGVwZW5kIG9uIHRoZSBwcmVkaWN0b3JzIGFuZCB0aGUgZGVwZW5kZW5jZSBwYXR0ZXJuLg0KDQojIyBUaGUgQVIoMSkgRXJyb3IgTW9kZWwNCg0KQSAqKmZpcnN0LW9yZGVyIGF1dG9yZWdyZXNzaXZlKiosIG9yIEFSKDEpLCBlcnJvciBtb2RlbCBpcw0KDQokJFx2YXJlcHNpbG9uX3QgPSBccGhpXHZhcmVwc2lsb25fe3QtMX0gKyBcZXRhX3QuJCQNCg0KVGhlIGN1cnJlbnQgZXJyb3IgY29udGFpbnMgYSBjb250cmlidXRpb24gZnJvbSB0aGUgcHJldmlvdXMgZXJyb3IsICRccGhpXHZhcmVwc2lsb25fe3QtMX0kLCBwbHVzIGEgbmV3IGRpc3R1cmJhbmNlLCAkXGV0YV90JC4gV2UgY2FsbCAkXGV0YV90JCB0aGUgKippbm5vdmF0aW9uKio6IHRoZSBwYXJ0IHRoYXQgd2FzIG5vdCBjYXJyaWVkIGZvcndhcmQgZnJvbSB0aGUgcGFzdC4NCg0KV2UgYXNzdW1lIHRoZSBpbm5vdmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgb2YgcGFzdCBlcnJvcnMgYW5kIG9mIG9uZSBhbm90aGVyLCB3aXRoIG1lYW4gemVybyBhbmQgY29uc3RhbnQgdmFyaWFuY2UuDQoNCi0gSWYgJFxwaGk+MCQsIG5lYXJieSBlcnJvcnMgdGVuZCB0byBtb3ZlIGluIHRoZSBzYW1lIGRpcmVjdGlvbi4NCi0gSWYgJFxwaGk8MCQsIG5lYXJieSBlcnJvcnMgdGVuZCB0byBhbHRlcm5hdGUuDQotIElmICRccGhpPTAkLCBlYWNoIGVycm9yIGlzIGp1c3QgaXRzIG5ldyBpbm5vdmF0aW9uLg0KDQojIyBBUigxKTogUHV0IE51bWJlcnMgSW50byB0aGUgRXF1YXRpb24NCg0KU3VwcG9zZSAkXHBoaT0wLjQkIGFuZCBsYXN0IG1vbnRoJ3MgZXJyb3Igd2FzIDEsMDAwIHJvb20gbmlnaHRzLiBUaGUgY29udHJpYnV0aW9uIGNhcnJpZWQgaW50byB0aGlzIG1vbnRoIGlzDQoNCiQkXHBoaVx2YXJlcHNpbG9uX3t0LTF9PTAuNFx0aW1lczF7LH0wMDA9NDAwLiQkDQoNCklmIHRoaXMgbW9udGgncyBlcnJvciBpcyA1MDAsIHRoZSBuZXcgZGlzdHVyYmFuY2UgbXVzdCBiZQ0KDQokJFxldGFfdD1cdmFyZXBzaWxvbl90LVxwaGlcdmFyZXBzaWxvbl97dC0xfT01MDAtNDAwPTEwMC4kJA0KDQpUaGUgbW9kZWwgc2VwYXJhdGVzIHRoZSA1MDAgaW50byA0MDAgY2FycmllZCBmb3J3YXJkIGFuZCAxMDAgb2YgbmV3IGRpc3R1cmJhbmNlLiBCZWZvcmUgb2JzZXJ2aW5nIHRoaXMgbW9udGgncyBpbm5vdmF0aW9uLCBpdHMgZXhwZWN0ZWQgZXJyb3Igd291bGQgYmUgNDAwLiBUaGUgcmVhbGlzZWQgZXJyb3IgY2FuIGRpZmZlciBiZWNhdXNlIGEgbmV3IGRpc3R1cmJhbmNlIGFycml2ZXMuDQoNClRoZXNlIGFyZSBpbGx1c3RyYXRpdmUgZXJyb3JzLiBJbiByZWFsIGRhdGEgd2UgZG8gbm90IGtub3cgdGhlIHRydWUgZXJyb3JzLCBzbyB3ZSBlc3RpbWF0ZSB0aGUgbWVhbiBhbmQgd29yayB3aXRoIHJlc2lkdWFscy4NCg0KIyMgSG93IExvbmcgRG9lcyB0aGUgRGVwZW5kZW5jZSBMYXN0Pw0KDQpGb3IgYSBzdGF0aW9uYXJ5IEFSKDEpIHByb2Nlc3MsIHRoZSBsYWctJGskIGVycm9yIGNvcnJlbGF0aW9uIGlzICRccGhpXmskLiBXaXRoICRccGhpPTAuNCQ6DQoNCnwgVGltZSBnYXAgfCBDb3JyZWxhdGlvbiB8DQp8Oi0tfC0tOnwNCnwgT25lIG1vbnRoIHwgJDAuNCQgfA0KfCBUd28gbW9udGhzIHwgJDAuNF4yPTAuMTYkIHwNCnwgVGhyZWUgbW9udGhzIHwgJDAuNF4zPTAuMDY0JCB8DQoNClRoZSBwcmV2aW91cyBlcnJvciBjYXJyaWVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuZXh0IG9uZSwgYnV0IHRoYXQgaW5mb3JtYXRpb24gd2Vha2VucyBhY3Jvc3MgbG9uZ2VyIGdhcHMuDQoNCldlIHJlcXVpcmUgJHxccGhpfDwxJCBmb3IgYSBzdGF0aW9uYXJ5IEFSKDEpIGVycm9yIHByb2Nlc3MuIEhlcmUgKipzdGF0aW9uYXJ5KiogbWVhbnMgdGhlIGVycm9yIHByb2Nlc3MgaGFzIGEgc3RhYmxlIG1lYW4gYW5kIHZhcmlhbmNlLCBhbmQgY29ycmVsYXRpb25zIGRlcGVuZCBvbiB0aGUgdGltZSBnYXAuIFRoZSByZXNwb25zZSBpdHNlbGYgY2FuIHN0aWxsIGhhdmUgdHJlbmQgYW5kIHNlYXNvbmFsaXR5IHRocm91Z2ggaXRzIG1lYW4gbW9kZWwuDQoNCiMjIFJlZ3Jlc3Npb24gTW9kZWwgd2l0aCBBUigxKSBFcnJvcnMNCg0KRm9yIHRoZSB0b3VyaXNtIGRhdGEsIG91ciB0d28gbW9kZWwgY29tcG9uZW50cyBhcmUNCg0KJCRcYmVnaW57YWxpZ25lZH0NCllfdCAmPSBcYmV0YV8wICsgXGJldGFfMVxtYXRocm17VGltZX1fdCArIFxiZXRhXzJ6X3t0LDJ9ICsgXGNkb3RzICsgXGJldGFfezEyfXpfe3QsMTJ9ICsgXHZhcmVwc2lsb25fdCwgXFwNClx2YXJlcHNpbG9uX3QgJj0gXHBoaVx2YXJlcHNpbG9uX3t0LTF9ICsgXGV0YV90Lg0KXGVuZHthbGlnbmVkfSQkDQoNClRoZSAkel97dCxqfSQgdGVybXMgYXJlIHRoZSAxMSBtb250aCBpbmRpY2F0b3JzLCB3aXRoIEphbnVhcnkgYXMgdGhlIHJlZmVyZW5jZSBtb250aC4NCg0KVGhlIGZpcnN0IGVxdWF0aW9uIGRlc2NyaWJlcyBleHBlY3RlZCByb29tIG5pZ2h0cyBnaXZlbiB0aW1lIGFuZCBtb250aC4gVGhlIHNlY29uZCBkZXNjcmliZXMgaG93IGRldmlhdGlvbnMgZnJvbSB0aGF0IGV4cGVjdGF0aW9uIHBlcnNpc3QuIEFkZGluZyBBUigxKSBlcnJvcnMgZG9lcyBub3QgYWRkIGxhc3QgbW9udGgncyBvYnNlcnZlZCByb29tIG5pZ2h0cyBhcyBhIHByZWRpY3RvciBpbiB0aGUgbWVhbiBmb3JtdWxhLg0KDQojIyBXaHkgR0xTIFdvcmtzOiBDb21wYXJlIFR3byBBZGphY2VudCBUaW1lcw0KDQpUbyBzZWUgdGhlIGNhbGN1bGF0aW9uIHdpdGggb25lIHByZWRpY3Rvciwgd3JpdGUgdGhlIHJlZ3Jlc3Npb24gYXQgdGltZXMgJHQkIGFuZCAkdC0xJDoNCg0KJCRcYmVnaW57YWxpZ25lZH0NCnlfdCAmPSBcYmV0YV8wICsgXGJldGFfMXhfdCArIFx2YXJlcHNpbG9uX3QsIFxcDQp5X3t0LTF9ICY9IFxiZXRhXzAgKyBcYmV0YV8xeF97dC0xfSArIFx2YXJlcHNpbG9uX3t0LTF9Lg0KXGVuZHthbGlnbmVkfSQkDQoNCk11bHRpcGx5IHRoZSBzZWNvbmQgZXF1YXRpb24gYnkgJFxwaGkkLiBTdWJ0cmFjdGluZyBpdCBmcm9tIHRoZSBmaXJzdCBsZWF2ZXMgdGhlIGVycm9yIGRpZmZlcmVuY2UNCg0KJCRcdmFyZXBzaWxvbl90LVxwaGlcdmFyZXBzaWxvbl97dC0xfT1cZXRhX3QuJCQNCg0KVW5kZXIgdGhlIEFSKDEpIG1vZGVsLCB0aGlzIGRpZmZlcmVuY2UgaXMgdGhlIG5ldyBpbm5vdmF0aW9uLiBXZSBoYXZlIHJlbW92ZWQgdGhlIGNvbnRyaWJ1dGlvbiBjYXJyaWVkIGZvcndhcmQgZnJvbSB0aGUgcHJldmlvdXMgZXJyb3IuDQoNCiMjIFdoeSBHTFMgV29ya3M6IFRyYW5zZm9ybSB0aGUgV2hvbGUgUmVncmVzc2lvbg0KDQpTdWJ0cmFjdGluZyB0aGUgdHdvIGVxdWF0aW9ucyBnaXZlcw0KDQokJHlfdC1ccGhpIHlfe3QtMX0NCj1cYmV0YV8wKDEtXHBoaSkrXGJldGFfMSh4X3QtXHBoaSB4X3t0LTF9KStcZXRhX3QuJCQNCg0KLSBUaGUgcmVzcG9uc2UgYmVjb21lcyAkeV90LVxwaGkgeV97dC0xfSQuDQotIFRoZSBwcmVkaWN0b3IgYmVjb21lcyAkeF90LVxwaGkgeF97dC0xfSQuDQotIFRoZSBpbnRlcmNlcHQgbXVsdGlwbGllciBiZWNvbWVzICQxLVxwaGkkLg0KDQpXZSBtdXN0IHRyYW5zZm9ybSB0aGUgd2hvbGUgcmVncmVzc2lvbiwgaW5jbHVkaW5nIGV2ZXJ5IHByZWRpY3Rvci4gVHJhbnNmb3JtaW5nIG9ubHkgdGhlIHJlc3BvbnNlIHdvdWxkIGRlc2NyaWJlIGEgZGlmZmVyZW50IG1lYW4gbW9kZWwuDQoNCioqR2VuZXJhbGlzZWQgbGVhc3Qgc3F1YXJlcyAoR0xTKSoqIHVzZXMgdGhlIGVycm9yIGNvdmFyaWFuY2Ugc3RydWN0dXJlIHRvIGVzdGltYXRlIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cy4gVGhpcyBhZGphY2VudC10aW1lIGNhbGN1bGF0aW9uIGV4cGxhaW5zIGl0cyBtZWNoYW5pc20gZm9yIEFSKDEpOyB0aGUgc29mdHdhcmUgYWxzbyBoYW5kbGVzIHRoZSBmaXJzdCBvYnNlcnZhdGlvbiBhbmQgZXN0aW1hdGVzIHRoZSB1bmtub3duICRccGhpJC4NCg0KIyMgRml0dGluZyB0aGUgQVIoMSkgTW9kZWwgaW4gUg0KDQpgZ2xzKClgIGZyb20gYG5sbWVgIHRha2VzIHRoZSB1c3VhbCBtZWFuIGZvcm11bGEgcGx1cyBhIGNvcnJlbGF0aW9uIHN0cnVjdHVyZToNCg0KYGBge3IgdG91cmlzbS1nbHN9DQp0b3VyaXNtX2dscyA8LSBnbHMoDQogIFJvb21OaWdodHMgfiBUaW1lICsgTW9udGgsDQogIGNvcnJlbGF0aW9uID0gY29yQVIxKGZvcm0gPSB+IFRpbWUpLA0KICBkYXRhID0gdG91cmlzbQ0KKQ0KYGBgDQoNCmBSb29tTmlnaHRzIH4gVGltZSArIE1vbnRoYCBzcGVjaWZpZXMgdGhlIG1lYW4uIGBjb3JBUjEoZm9ybSA9IH4gVGltZSlgIHNwZWNpZmllcyBob3cgZXJyb3JzIGFyZSByZWxhdGVkIGFjY29yZGluZyB0byB0aGVpciBzZXBhcmF0aW9uIGluIHRpbWUuDQoNCmBUaW1lYCBtdXN0IGJlIGludGVnZXItdmFsdWVkIGFuZCBjb3VudHMgbW9udGhzIGhlcmUuIE9ic2VydmF0aW9ucyB0d28gbW9udGhzIGFwYXJ0IGhhdmUgbW9kZWxsZWQgZXJyb3IgY29ycmVsYXRpb24gJFxwaGleMiQsIHJhdGhlciB0aGFuICRccGhpJC4NCg0KIyMgVG91cmlzbTogSW50ZXJwcmV0IHRoZSBFc3RpbWF0ZWQgRGVwZW5kZW5jZQ0KDQpgYGB7ciB0b3VyaXNtLXBoaX0NCnRvdXJpc21fcGhpIDwtIHVubmFtZShjb2VmKA0KICB0b3VyaXNtX2dscyRtb2RlbFN0cnVjdCRjb3JTdHJ1Y3QsIHVuY29uc3RyYWluZWQgPSBGQUxTRQ0KKSkNCmBgYA0KDQpgYGB7ciB0b3VyaXNtLXBoaS10YWJsZSwgZWNobz1GQUxTRX0NCnRpYmJsZSgNCiAgYEdhcCAobW9udGhzKWAgPSAxOjMsDQogIGBGaXR0ZWQgZXJyb3IgY29ycmVsYXRpb25gID0gdG91cmlzbV9waGleKDE6MykNCikgfD4ga2FibGUoZGlnaXRzID0gMykNCmBgYA0KDQpXZSBlc3RpbWF0ZSAkXGhhdFxwaGlcYXBwcm94IGByIHJvdW5kKHRvdXJpc21fcGhpLCAzKWAkLiBBZnRlciBhbGxvd2luZyBmb3IgdHJlbmQgYW5kIG1vbnRoIGVmZmVjdHMsIGVycm9ycyBvbmUgbW9udGggYXBhcnQgaGF2ZSBhbiBlc3RpbWF0ZWQgY29ycmVsYXRpb24gb2YgYWJvdXQgYHIgcm91bmQodG91cmlzbV9waGksIDIpYCB1bmRlciB0aGlzIG1vZGVsLg0KDQpUaGF0IGVzdGltYXRlIGRlc2NyaWJlcyB0aGUgKiptb2RlbGxlZCBkZXBlbmRlbmNlKiouIFdlIHN0aWxsIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgbW9kZWwgYWNjb3VudHMgZm9yIHRoZSBwYXR0ZXJuIGluIHRoZXNlIGRhdGEuDQoNCiMjIEhvdyBQcmVjaXNlbHkgSGF2ZSBXZSBFc3RpbWF0ZWQgdGhlIENvcnJlbGF0aW9uPw0KDQokXGhhdFxwaGkkIGlzIGFuIGVzdGltYXRlIGZyb20gYHIgbnJvdyh0b3VyaXNtKWAgbW9udGhzIG9mIGRhdGEsIHNvIGl0IGNhcnJpZXMgdW5jZXJ0YWludHkgb2YgaXRzIG93bi4NCg0KYGBge3IgdG91cmlzbS1nbHMtaW50ZXJ2YWxzfQ0KaW50ZXJ2YWxzKHRvdXJpc21fZ2xzKQ0KYGBgDQoNClRoZSBgUGhpYCByb3cgcmVwZWF0cyBvdXIgZXN0aW1hdGUgYW5kIGFkZHMgYW4gYXBwcm94aW1hdGUgOTUlIGludGVydmFsIGZvciB0aGUgZXJyb3IgY29ycmVsYXRpb24uIEluIExhYiAxMyB5b3Ugd2lsbCByZWFkIHRoZSBzYW1lIHJvdyBmb3IgdGhlIFBlcnRoIGhvdXNlLXByaWNlIGRhdGEsIHdoZXJlIG9ubHkgNDUgcXVhcnRlcnMgYXJlIGF2YWlsYWJsZSBhbmQgdGhlIGludGVydmFsIGlzIHdpZGVyLg0KDQpUaGUgbGVzc29uIHRvIGNhcnJ5IGZvcndhcmQ6IGFuIGVzdGltYXRlIG9mICRccGhpJCBuZWFyIHplcm8gZG9lcyBub3QgYnkgaXRzZWxmIGVzdGFibGlzaCBpbmRlcGVuZGVuY2Ugd2hlbiB0aGUgaW50ZXJ2YWwgYXJvdW5kIGl0IGlzIHdpZGUuDQoNCiMjIFdoZXJlIERvZXMgdGhlIEdMUyBTdGFuZGFyZCBFcnJvciBDb21lIEZyb20/DQoNCkxlY3R1cmUgMzQgd3JvdGUgZG93biB0aGUgdmFyaWFuY2UgT0xTIHJlcG9ydHMgd2hlbiBpbmRlcGVuZGVuY2UgZmFpbHMuIEdMUyB1c2VzIHRoZSBmaXR0ZWQgZXJyb3IgbW9kZWwgaW5zdGVhZDoNCg0KJCRcb3BlcmF0b3JuYW1le1Zhcn0oXHdpZGVoYXR7XGJvbGRzeW1ib2xcYmV0YX1fe1x0ZXh0e0dMU319KQ0KPShYXlx0b3Bcd2lkZWhhdFxTaWdtYV57LTF9WCleey0xfS4kJA0KDQokXHdpZGVoYXRcU2lnbWEkIGlzIHRoZSBlc3RpbWF0ZWQgZXJyb3IgY292YXJpYW5jZSBtYXRyaXguIEZvciBBUigxKSBlcnJvcnMgaXQgaXMgYXNzZW1ibGVkIGZyb20gJFxoYXRccGhpJCBhbmQgJFxoYXRcc2lnbWEkLCBiZWNhdXNlIHRoaXMgbW9kZWwgZml4ZXMgJFxvcGVyYXRvcm5hbWV7Q29ycn0oXHZhcmVwc2lsb25fcyxcdmFyZXBzaWxvbl90KT1ccGhpXnt8cy10fH0kLiBIZXJlICRcaGF0XHNpZ21hJCBpcyB0aGUgaW5ub3ZhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24sIHRoZSBzY2FsZSBvZiB0aGUgbmV3IGRpc3R1cmJhbmNlcyAkXGV0YV90JDogYHN1bW1hcnkodG91cmlzbV9nbHMpYCByZXBvcnRzIGl0IGFzIHRoZSByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24sIGFuZCB0aGUgcmF3IGVycm9ycyB0aGVtc2VsdmVzIGhhdmUgdmFyaWFuY2UgJFxzaWdtYV4yLygxLVxwaGleMikkLg0KDQpOZWl0aGVyIHBhcmFtZXRlciBpcyBrbm93biBpbiBhZHZhbmNlLCBzbyBgZ2xzKClgIGVzdGltYXRlcyAkXHBoaSQgYW5kICRcc2lnbWEkIGFsb25nc2lkZSB0aGUgcmVncmVzc2lvbiBjb2VmZmljaWVudHMuIFdoZW4gbmVpZ2hib3VyaW5nIGVycm9ycyBjYXJyeSBvdmVybGFwcGluZyBpbmZvcm1hdGlvbiwgJChYXlx0b3Bcd2lkZWhhdFxTaWdtYV57LTF9WCleey0xfSQgY2FuIGdpdmUgbGFyZ2VyIHZhcmlhbmNlcyB0aGFuIHRoZSBpbmRlcGVuZGVudC1lcnJvcnMgZm9ybXVsYSwgZXZlbiB3aXRoIGFuIGFsbW9zdCB1bmNoYW5nZWQgbWVhbiBmaXQuIFRoZSBjb21wYXJpc29uIGJlbG93IGlzIHdoZXJlIHRoYXQgc2hvd3MgdXAuDQoNCiMjIFRvdXJpc206IFdoYXQgSGFwcGVucyB0byB0aGUgVHJlbmQgYW5kIEl0cyBQcmVjaXNpb24/DQoNCmBgYHtyIHRvdXJpc20tc3RhbmRhcmQtZXJyb3ItY29tcGFyaXNvbiwgZWNobz1GQUxTRX0NCnRvdXJpc21fdHJlbmQgPC0gYmluZF9yb3dzKA0KICB0aWR5KHRvdXJpc21fbG0pIHw+IG11dGF0ZShtb2RlbCA9ICJPTFMiKSwNCiAgdGlkeSh0b3VyaXNtX2dscykgfD4gbXV0YXRlKG1vZGVsID0gIkdMUyB3aXRoIEFSKDEpIikNCikgfD4NCiAgZmlsdGVyKHRlcm0gPT0gIlRpbWUiKSB8Pg0KICBzZWxlY3QobW9kZWwsIGVzdGltYXRlLCBzdGQuZXJyb3IpDQoNCnRvdXJpc21fdHJlbmQgfD4NCiAgcmVuYW1lKE1vZGVsID0gbW9kZWwsIGBUcmVuZCBlc3RpbWF0ZWAgPSBlc3RpbWF0ZSwgYFN0YW5kYXJkIGVycm9yYCA9IHN0ZC5lcnJvcikgfD4NCiAga2FibGUoZGlnaXRzID0gMSkNCg0KdG91cmlzbV9zZV9yYXRpbyA8LSB0b3VyaXNtX3RyZW5kJHN0ZC5lcnJvclsyXSAvIHRvdXJpc21fdHJlbmQkc3RkLmVycm9yWzFdDQpgYGANCg0KSG9sZGluZyBtb250aCBjb25zdGFudCwgZXhwZWN0ZWQgcm9vbSBuaWdodHMgaW5jcmVhc2UgYnkgYWJvdXQgYHIgZm9ybWF0KHJvdW5kKHRvdXJpc21fdHJlbmQkZXN0aW1hdGVbMl0pLCBiaWcubWFyayA9ICIsIilgIGZvciBlYWNoIGFkZGl0aW9uYWwgbW9udGguIFRoZSB0cmVuZCBlc3RpbWF0ZSBiYXJlbHkgY2hhbmdlcyBiZXR3ZWVuIHRoZSB0d28gZml0cy4NCg0KSXRzIHN0YW5kYXJkIGVycm9yIGluY3JlYXNlcyBieSBhYm91dCBgciByb3VuZCgxMDAgKiAodG91cmlzbV9zZV9yYXRpbyAtIDEpKWAlLiBBIHNpbWlsYXIgZml0dGVkIG1lYW4gY2FuIGhhdmUgYSBkaWZmZXJlbnQgcHJlY2lzaW9uIGNhbGN1bGF0aW9uIG9uY2Ugd2UgYWNjb3VudCBmb3IgZGVwZW5kZW5jZS4gR0xTIGNhbiBhbHNvIGNoYW5nZSBjb2VmZmljaWVudCBlc3RpbWF0ZXM7IG5laXRoZXIgdGhlIGRpcmVjdGlvbiBub3IgdGhlIHNpemUgb2YgdGhlc2UgY2hhbmdlcyBpcyB1bml2ZXJzYWwuDQoNClNlbGVjdGlvbiBpbmhlcml0cyB0aGlzIGNoYW5nZS4gQ29tcGFyaW5nIG1vZGVscyBieSBBSUMgcmFua3MgdGhlbSB1c2luZyB0aGUgZml0dGVkIGVycm9yIG1vZGVsLCBhbmQganVkZ2luZyBhIHRlcm0gYnkgaXRzIHQtc3RhdGlzdGljIHJlYWRzIHRoZSBzdGFuZGFyZCBlcnJvcnMgc2hvd24gaGVyZSwgc28gYW4gZXJyb3IgbW9kZWwgY2FuIGNoYW5nZSB3aGljaCB0ZXJtcyBsb29rIHdvcnRoIGtlZXBpbmcuIEFueSBzdWNoIGNvbXBhcmlzb24gYmV0d2VlbiBtb2RlbHMgd2l0aCBkaWZmZXJlbnQgbWVhbiBmb3JtdWxhcyBzaG91bGQgYmUgbWFkZSB3aXRoIGBtZXRob2QgPSAiTUwiYCBpbiBgZ2xzKClgLCBzaW5jZSB0aGUgZGVmYXVsdCBSRU1MIGxpa2VsaWhvb2QgaXMgaW50ZW5kZWQgZm9yIG1vZGVscyBzaGFyaW5nIGEgbWVhbiBzdHJ1Y3R1cmUuDQoNCiMjIFdoaWNoIEdMUyBSZXNpZHVhbHMgU2hvdWxkIFdlIENoZWNrPw0KDQpUaGUgcmF3IEdMUyByZXNpZHVhbCBpcyBzdGlsbCBvYnNlcnZlZCBtaW51cyBmaXR0ZWQ6DQoNCiQkZV90PXlfdC1cd2lkZWhhdFxtdV90LiQkDQoNCk91ciBtb2RlbCBhbGxvd3MgdGhlc2UgZGV2aWF0aW9ucyB0byBiZSBjb3JyZWxhdGVkLiBXZSBzaG91bGQgdGhlcmVmb3JlIGV4cGVjdCByYXcgcmVzaWR1YWxzIHRvIHJldGFpbiBzb21lIG9mIHRoYXQgY29ycmVsYXRpb24sIGV2ZW4gd2hlbiB0aGUgZXJyb3IgbW9kZWwgaXMgcmVhc29uYWJsZS4NCg0KKipOb3JtYWxpc2VkIHJlc2lkdWFscyoqIGFjY291bnQgZm9yIHRoZSBmaXR0ZWQgY29ycmVsYXRpb24gYW5kIHJlc2NhbGUgdGhlIHJlc2lkdWFscy4gRm9yIGFkamFjZW50IHRpbWVzIGluIHRoaXMgQVIoMSkgZXhhbXBsZSwgdGhlIGNhbGN1bGF0aW9uIGlzIGJhc2VkIG9uICRlX3QtXGhhdFxwaGkgZV97dC0xfSQsIGZvbGxvd2VkIGJ5IHNjYWxpbmcuIFdlIGNoZWNrIHRoZXNlIGZvciByZW1haW5pbmcgZGVwZW5kZW5jZS4NCg0KVGhlIG5hbWUgKm5vcm1hbGlzZWQqIGRlc2NyaWJlcyB0aGF0IHRyYW5zZm9ybWF0aW9uLiBJdCBkb2VzIG5vdCBtZWFuIHRoZSByZXNpZHVhbCBkaXN0cmlidXRpb24gaGFzIGJlZW4gbWFkZSBub3JtYWwuIFNlZSB0aGUgW2BubG1lYCByZXNpZHVhbCBkb2N1bWVudGF0aW9uXShodHRwczovL3N0YXQuZXRoei5jaC9SLW1hbnVhbC9SLWRldmVsL2xpYnJhcnkvbmxtZS9odG1sL3Jlc2lkdWFscy5nbHMuaHRtbCkuDQoNCiMjIFRvdXJpc206IFJhdyBhbmQgTm9ybWFsaXNlZCBSZXNpZHVhbHMNCg0KYGBge3IgdG91cmlzbS1yZXNpZHVhbC10eXBlc30NCnRvdXJpc21fcmF3IDwtIHJlc2lkdWFscyh0b3VyaXNtX2dscywgdHlwZSA9ICJyZXNwb25zZSIpDQp0b3VyaXNtX25vcm1hbGlzZWQgPC0gcmVzaWR1YWxzKHRvdXJpc21fZ2xzLCB0eXBlID0gIm5vcm1hbGl6ZWQiKQ0KYGBgDQoNCmBgYHtyIHRvdXJpc20tZ2xzLWRpYWdub3N0aWMtdmFsdWVzLCBpbmNsdWRlPUZBTFNFfQ0Kc3RvcGlmbm90KGxlbmd0aCh0b3VyaXNtX3JhdykgPT0gbnJvdyh0b3VyaXNtKSwNCiAgICAgICAgICBsZW5ndGgodG91cmlzbV9ub3JtYWxpc2VkKSA9PSBucm93KHRvdXJpc20pKQ0KdG91cmlzbV9yYXdfciA8LSBhcy5udW1lcmljKGFjZih0b3VyaXNtX3JhdywgbGFnLm1heCA9IDI0LCBwbG90ID0gRkFMU0UpJGFjZilbLTFdDQp0b3VyaXNtX25vcm1hbGlzZWRfciA8LSBhcy5udW1lcmljKGFjZih0b3VyaXNtX25vcm1hbGlzZWQsIGxhZy5tYXggPSAyNCwgcGxvdCA9IEZBTFNFKSRhY2YpWy0xXQ0KYGBgDQoNCmBgYHtyIHRvdXJpc20tcmVzaWR1YWwtdHlwZS1jb21wYXJpc29uLCBlY2hvPUZBTFNFfQ0KdGliYmxlKA0KICBSZXNpZHVhbHMgPSBjKCJPTFMiLCAiR0xTOiByYXciLCAiR0xTOiBub3JtYWxpc2VkIiksDQogIGBMYWctMSBjb3JyZWxhdGlvbmAgPSBjKHRvdXJpc21fb2xzX3JbMV0sIHRvdXJpc21fcmF3X3JbMV0sIHRvdXJpc21fbm9ybWFsaXNlZF9yWzFdKSwNCiAgYExhZy0xMiBjb3JyZWxhdGlvbmAgPSBjKHRvdXJpc21fb2xzX3JbMTJdLCB0b3VyaXNtX3Jhd19yWzEyXSwgdG91cmlzbV9ub3JtYWxpc2VkX3JbMTJdKQ0KKSB8PiBrYWJsZShkaWdpdHMgPSAzKQ0KYGBgDQoNClRoZSByYXcgR0xTIHJlc2lkdWFscyBoYXZlIG11Y2ggdGhlIHNhbWUgbGFnLTEgY29ycmVsYXRpb24gYXMgdGhlIE9MUyByZXNpZHVhbHMuIEFmdGVyIGFjY291bnRpbmcgZm9yIHRoZSBmaXR0ZWQgZGVwZW5kZW5jZSwgdGhlIG5vcm1hbGlzZWQgcmVzaWR1YWxzIGhhdmUgbXVjaCBsZXNzIGxhZy0xIGNvcnJlbGF0aW9uLiBUaGUgbGFnLTEyIHZhbHVlIHN0aWxsIG5lZWRzIGF0dGVudGlvbi4NCg0KIyMgVG91cmlzbTogUmVzaWR1YWwgUGF0dGVybnMgQmVmb3JlIGFuZCBBZnRlciBHTFMNCg0KYGBge3IgdG91cmlzbS1yZXNpZHVhbC10aW1lLWNvbXBhcmlzb24sIGVjaG89RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTQsIG91dC53aWR0aD0iODAlIiwgZmlnLmFsdD0iVGltZSBwbG90cyBjb21wYXJpbmcgc3RhbmRhcmRpc2VkIE9MUyByZXNpZHVhbHMgYW5kIEdMUyBub3JtYWxpc2VkIHJlc2lkdWFscyBvbiB0aGUgc2FtZSBzY2FsZSJ9DQpiaW5kX3Jvd3MoDQogIHRpYmJsZShEYXRlID0gdG91cmlzbSREYXRlLCBSZXNpZHVhbCA9IHJlc2lkKHRvdXJpc21fbG0pIC8gc2lnbWEodG91cmlzbV9sbSksDQogICAgICAgICBNb2RlbCA9ICJPTFM6IHN0YW5kYXJkaXNlZCByZXNpZHVhbHMiKSwNCiAgdGliYmxlKERhdGUgPSB0b3VyaXNtJERhdGUsIFJlc2lkdWFsID0gdG91cmlzbV9ub3JtYWxpc2VkLA0KICAgICAgICAgTW9kZWwgPSAiR0xTOiBub3JtYWxpc2VkIHJlc2lkdWFscyIpDQopIHw+DQogIG11dGF0ZShNb2RlbCA9IGZhY3RvcihNb2RlbCwgbGV2ZWxzID0gYygiT0xTOiBzdGFuZGFyZGlzZWQgcmVzaWR1YWxzIiwgIkdMUzogbm9ybWFsaXNlZCByZXNpZHVhbHMiKSkpIHw+DQogIGdncGxvdChhZXMoRGF0ZSwgUmVzaWR1YWwpKSArDQogIGdlb21fbGluZShjb2xvdXIgPSAiIzE3M2Y1ZiIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogIGZhY2V0X3dyYXAofiBNb2RlbCwgbmNvbCA9IDEpICsNCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlJlc2lkdWFsIChzY2FsZWQgdW5pdHMpIikNCmBgYA0KDQpCb3RoIHBsb3RzIHVzZSB0aGUgc2FtZSBtb250aHMuIFRoZSBPTFMgcmVzaWR1YWxzIGFyZSBkaXZpZGVkIGJ5IHRoZWlyIGVzdGltYXRlZCByZXNpZHVhbCBzdGFuZGFyZCBkZXZpYXRpb24gdG8gcHV0IHRoZW0gb24gYSBjb21wYXJhYmxlIHNjYWxlLiBMb29rIGZvciBwZXJzaXN0ZW5jZSBpbiB0aGUgc2VxdWVuY2UsIGFzIHdlbGwgYXMgbGFyZ2UgaW5kaXZpZHVhbCBkZXZpYXRpb25zLg0KDQojIyBUb3VyaXNtOiBBQ0YgQmVmb3JlIGFuZCBBZnRlciBHTFMNCg0KYGBge3IgdG91cmlzbS1ub3JtYWxpemVkLXJlc2lkdWFsLWFjZiwgZWNobz1GQUxTRSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9My41LCBvdXQud2lkdGg9IjkwJSIsIGZpZy5hbHQ9Ik1hdGNoZWQgQUNGIHBhbmVscyB0aHJvdWdoIDI0IG1vbnRocyBzaG93aW5nIHJlZHVjZWQgbGFnLTEgY29ycmVsYXRpb24gYnV0IHJlbWFpbmluZyBsYWctMTIgY29ycmVsYXRpb24gYWZ0ZXIgR0xTIG5vcm1hbGlzYXRpb24ifQ0KdG91cmlzbV9hY2ZfY29tcGFyaXNvbiA8LSB0aWJibGUoDQogIExhZyA9IHJlcCgxOjI0LCAyKSwNCiAgQ29ycmVsYXRpb24gPSBjKHRvdXJpc21fb2xzX3IsIHRvdXJpc21fbm9ybWFsaXNlZF9yKSwNCiAgTW9kZWwgPSBmYWN0b3IocmVwKGMoIk9MUyByZXNpZHVhbHMiLCAiR0xTIG5vcm1hbGlzZWQgcmVzaWR1YWxzIiksIGVhY2ggPSAyNCksDQogICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk9MUyByZXNpZHVhbHMiLCAiR0xTIG5vcm1hbGlzZWQgcmVzaWR1YWxzIikpDQopDQp0b3VyaXNtX2FjZl9saW1pdCA8LSBxbm9ybSgwLjk3NSkgLyBzcXJ0KG5yb3codG91cmlzbSkpDQoNCmdncGxvdCh0b3VyaXNtX2FjZl9jb21wYXJpc29uLCBhZXMoTGFnLCBDb3JyZWxhdGlvbikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3VyID0gImdyZXk1NSIpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gYygtdG91cmlzbV9hY2ZfbGltaXQsIHRvdXJpc21fYWNmX2xpbWl0KSwNCiAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsIGNvbG91ciA9ICIjMjY3ZjhiIikgKw0KICBnZW9tX3NlZ21lbnQoYWVzKHhlbmQgPSBMYWcsIHllbmQgPSAwKSwgY29sb3VyID0gIiMxNzNmNWYiKSArDQogIGZhY2V0X3dyYXAofiBNb2RlbCwgbnJvdyA9IDEpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwgNiwgMTIsIDE4LCAyNCkpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0wLjQsIDAuNikpICsNCiAgbGFicyh4ID0gIkxhZyAobW9udGhzKSIsIHkgPSAiQUNGIikNCmBgYA0KDQpMYWcgMCBpcyBvbWl0dGVkIGJlY2F1c2UgaXQgaXMgYWx3YXlzIDEuIFRoZSBwYW5lbHMgaGF2ZSBpZGVudGljYWwgYXhlcy4gTGFnIDEgZmFsbHMgZnJvbSBgciByb3VuZCh0b3VyaXNtX29sc19yWzFdLCAzKWAgdG8gYHIgcm91bmQodG91cmlzbV9ub3JtYWxpc2VkX3JbMV0sIDMpYCwgYnV0IGxhZyAxMiByZW1haW5zIHBvc2l0aXZlIGF0IGByIHJvdW5kKHRvdXJpc21fbm9ybWFsaXNlZF9yWzEyXSwgMylgLg0KDQpUaGUgZGFzaGVkIGxpbmVzIGFyZSBhcHByb3hpbWF0ZSBwb2ludHdpc2Ugd2hpdGUtbm9pc2UgcmVmZXJlbmNlIGxpbWl0cy4gVGhleSBndWlkZSBpbnNwZWN0aW9uOyB0aGV5IGRvIG5vdCBwcm92ZSBpbmRlcGVuZGVuY2Ugb3IgZm9ybSBhIHNpbXVsdGFuZW91cyBiYW5kIGFjcm9zcyBhbGwgbGFncy4NCg0KIyMgVG91cmlzbTogUmVwZWF0IExqdW5nLUJveCBBY3Jvc3MgT25lIFllYXINCg0KVGhlIEFDRiBzaG93cyAqd2hlcmUqIGNvcnJlbGF0aW9uIHJlbWFpbnMuIExqdW5nLUJveCBjb21iaW5lcyB0aGUgY29ycmVsYXRpb25zIGFjcm9zcyBhIGNob3NlbiBzZXQgb2YgbGFncy4gVXNlIGxhZ3MgMSB0aHJvdWdoIDEyIHRvIGluY2x1ZGUgZ2FwcyBvZiB1cCB0byBvbmUgeWVhcjoNCg0KJCRIXzA6XHJob18xPVxjZG90cz1ccmhvX3sxMn09MC4kJA0KDQpgYGB7ciB0b3VyaXNtLWxqdW5nLWJveH0NCnRvdXJpc21fbGJfb2xzIDwtIEJveC50ZXN0KA0KICByZXNpZCh0b3VyaXNtX2xtKSwgbGFnID0gMTIsIHR5cGUgPSAiTGp1bmctQm94IiwgZml0ZGYgPSAwDQopDQp0b3VyaXNtX2xiX2dscyA8LSBCb3gudGVzdCgNCiAgdG91cmlzbV9ub3JtYWxpc2VkLCBsYWcgPSAxMiwgdHlwZSA9ICJManVuZy1Cb3giLCBmaXRkZiA9IDENCikNCmBgYA0KDQpXZSBjaG9zZSAxMiB1c2luZyB0aGUgbW9udGhseSB0aW1lIHNjYWxlLCByYXRoZXIgdGhhbiBzZWFyY2hpbmcgZm9yIGEgbGFnIHRoYXQgZ2l2ZXMgYSBwcmVmZXJyZWQgUC12YWx1ZS4NCg0KIyMgVG91cmlzbTogSGFzIHRoZSBEZXBlbmRlbmNlIEJlZW4gQWNjb3VudGVkIEZvcj8NCg0KYGBge3IgdG91cmlzbS1sanVuZy1ib3gtY29tcGFyaXNvbiwgZWNobz1GQUxTRX0NCnRpYmJsZSgNCiAgUmVzaWR1YWxzID0gYygiT0xTIiwgIkdMUzogbm9ybWFsaXNlZCIpLA0KICBgU3RhdGlzdGljIFFgID0gYyh1bm5hbWUodG91cmlzbV9sYl9vbHMkc3RhdGlzdGljKSwgdW5uYW1lKHRvdXJpc21fbGJfZ2xzJHN0YXRpc3RpYykpLA0KICBgUmVmZXJlbmNlIGRmYCA9IGModW5uYW1lKHRvdXJpc21fbGJfb2xzJHBhcmFtZXRlciksIHVubmFtZSh0b3VyaXNtX2xiX2dscyRwYXJhbWV0ZXIpKSwNCiAgYEFwcHJveGltYXRlIFAtdmFsdWVgID0gZm9ybWF0LnB2YWwoYyh0b3VyaXNtX2xiX29scyRwLnZhbHVlLCB0b3VyaXNtX2xiX2dscyRwLnZhbHVlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDMsIGVwcyA9IDAuMDAwMSkNCikgfD4ga2FibGUoZGlnaXRzID0gMikNCmBgYA0KDQpUaGUgc3RhdGlzdGljIGlzIHNtYWxsZXIgYWZ0ZXIgbm9ybWFsaXNhdGlvbiwgYW5kIHRoZSBsYWctMSBjb3JyZWxhdGlvbiBpcyBtdWNoIHJlZHVjZWQuIFRoZSByZW1haW5pbmcgc21hbGwgUC12YWx1ZSBhbmQgbGFnLTEyIEFDRiBiYXIgc3RpbGwgZ2l2ZSBldmlkZW5jZSBvZiBkZXBlbmRlbmNlIGFjcm9zcyB0aGVzZSBsYWdzLg0KDQoNCiMjIFRvdXJpc206IFdoYXQgV291bGQgV2UgSW52ZXN0aWdhdGUgTmV4dD8NCg0KVGhlIG1vbnRoIGluZGljYXRvcnMgYWxyZWFkeSBhbGxvdyB0aGUgKmF2ZXJhZ2UqIEphbnVhcnkgbWVhbiB0byBkaWZmZXIgZnJvbSB0aGUgYXZlcmFnZSBGZWJydWFyeSBtZWFuLiBUaGV5IGRvIG5vdCBuZWNlc3NhcmlseSBhY2NvdW50IGZvciBjaGFuZ2luZyBzZWFzb25hbCBlZmZlY3RzIG9yIGRlcGVuZGVuY2UgYmV0d2VlbiBkZXZpYXRpb25zIG9uZSB5ZWFyIGFwYXJ0Lg0KDQpJIHdvdWxkIGNoZWNrIHdoZXRoZXIgdGhlIHRyZW5kIG9yIHNlYXNvbmFsIG1lYW4gaXMgbWlzc2luZyBzdHJ1Y3R1cmUsIHRoZW4gY29uc2lkZXIgd2hldGhlciB0aGUgZXJyb3JzIG5lZWQgYSByaWNoZXIgbW9kZWwgZm9yIHNlYXNvbmFsIGRlcGVuZGVuY2UuIFRoZSBsYWctMTIgYmFyIGlkZW50aWZpZXMgYSB0aW1lIGdhcCB0byBpbnZlc3RpZ2F0ZTsgaXQgZG9lcyBub3QgaWRlbnRpZnkgdGhlIGNvcnJlY3QgcmVwbGFjZW1lbnQgbW9kZWwuDQoNCkNvcnJlbGF0aW9uIG1hZ25pdHVkZSB0ZWxscyB1cyBob3cgbGFyZ2UgYSBwYXJ0aWN1bGFyIHNhbXBsZSByZWxhdGlvbnNoaXAgaXMuIEEgUC12YWx1ZSBtZWFzdXJlcyBldmlkZW5jZSBhZ2FpbnN0IGEgcmVmZXJlbmNlIGh5cG90aGVzaXMuIEEgbGFyZ2VyIFAtdmFsdWUsIG9yIGEgc21hbGxlciBManVuZy1Cb3ggc3RhdGlzdGljLCB3b3VsZCBub3QgZXN0YWJsaXNoIHRoYXQgYWxsIGRlcGVuZGVuY2UgaGFkIGJlZW4gcmVzb2x2ZWQuDQoNCiMjIFdvcmsgVGhyb3VnaCB0aGUgQVIoMSkgQ2FsY3VsYXRpb24NCg0KU3VwcG9zZSAkXHBoaT0wLjYkLCB0aGUgcHJldmlvdXMgZXJyb3IgaXMgJC0yMDAkLCBhbmQgdGhlIGN1cnJlbnQgZXJyb3IgaXMgJC01MCQuIFdoYXQgaXMgdGhlIGlubm92YXRpb24/DQoNCi4gLiAuDQoNClRoZSBjb250cmlidXRpb24gY2FycmllZCBmb3J3YXJkIGlzICQwLjZcdGltZXMoLTIwMCk9LTEyMCQuIFRoZXJlZm9yZQ0KDQokJFxldGFfdD0tNTAtKC0xMjApPTcwLiQkDQoNClRoZSBuZXcgZGlzdHVyYmFuY2UgaXMgcG9zaXRpdmUgZXZlbiB0aG91Z2ggdGhlIGN1cnJlbnQgZXJyb3IgaXMgbmVnYXRpdmUuIEl0IHBhcnRseSBvZmZzZXRzIHRoZSBuZWdhdGl2ZSBjb250cmlidXRpb24gZnJvbSB0aGUgcGFzdC4NCg0KIyMgV2hpY2ggUmVzaWR1YWxzIEFuc3dlciBPdXIgRGlhZ25vc3RpYyBRdWVzdGlvbj8NCg0KQWZ0ZXIgZml0dGluZyBBUigxKSBlcnJvcnMsIHRoZSByYXcgR0xTIHJlc2lkdWFscyBzdGlsbCBoYXZlIHBvc2l0aXZlIGxhZy0xIGNvcnJlbGF0aW9uLiBEb2VzIHRoYXQgYWxvbmUgc2hvdyB0aGUgbW9kZWwgZmFpbGVkPw0KDQouIC4gLg0KDQpOby4gVGhlIG1vZGVsIGFsbG93cyByYXcgZGV2aWF0aW9ucyBmcm9tIHRoZSBmaXR0ZWQgbWVhbiB0byBiZSBjb3JyZWxhdGVkLiBXZSBpbnNwZWN0ICoqbm9ybWFsaXNlZCByZXNpZHVhbHMqKiB0byBhc2sgd2hldGhlciBkZXBlbmRlbmNlIHJlbWFpbnMgYWZ0ZXIgYWNjb3VudGluZyBmb3IgdGhlIGZpdHRlZCBlcnJvciBzdHJ1Y3R1cmUuDQoNCkEgbGFyZ2UgZXN0aW1hdGVkICRccGhpJCBhbmQgYSBzbWFsbCBub3JtYWxpc2VkIGxhZy0xIGNvcnJlbGF0aW9uIGNhbiBvY2N1ciB0b2dldGhlcjogdGhlIG1vZGVsIGhhcyBlc3RpbWF0ZWQgc3Vic3RhbnRpYWwgZGVwZW5kZW5jZSBhbmQgYWNjb3VudGVkIGZvciBtdWNoIG9mIGl0Lg0KDQojIyBJbnRlcnByZXQgdGhlIEJlZm9yZS1hbmQtQWZ0ZXIgQUNGDQoNCkxhZy0xIGNvcnJlbGF0aW9uIGlzIGNsb3NlIHRvIHplcm8gYWZ0ZXIgbm9ybWFsaXNhdGlvbiwgYnV0IGxhZy0xMiBjb3JyZWxhdGlvbiByZW1haW5zIGxhcmdlLiBXaGF0IGNvbmNsdXNpb24gY2FuIHdlIGRyYXc/DQoNCi4gLiAuDQoNCkFSKDEpIGhhcyBhY2NvdW50ZWQgZm9yIG11Y2ggb2YgdGhlIG5laWdoYm91cmluZy1tb250aCBkZXBlbmRlbmNlLiBJdCBoYXMgbGVmdCBhIHBhdHRlcm4gYXQgYSBvbmUteWVhciBnYXAsIHNvIHdlIHNob3VsZCBpbnZlc3RpZ2F0ZSB0aGUgbWVhbiBhbmQgdGhlIGVycm9yIG1vZGVsIGZ1cnRoZXIuDQoNCkNoZWNraW5nIG9ubHkgbGFnIDEgd291bGQgbWlzcyB0aGF0IHJlbWFpbmluZyBwYXR0ZXJuLiBXZSBuZWVkIHRoZSB0aW1lIHBsb3QsIHRoZSB3aWRlciBBQ0YgYW5kIGEgam9pbnQgZGlhZ25vc3RpYywgcmF0aGVyIHRoYW4gYSBzaW5nbGUgbnVtZXJpY2FsIHZlcmRpY3QuDQoNCiMjIEEgU2hvcnQgQ29tcGFyaXNvbjogU2VvdWwgQmlrZSB3aXRoIEFSKDEpIEVycm9ycw0KDQpSZXR1cm4gdG8gdGhlIGRhaWx5IFNlb3VsIGJpa2UgbW9kZWwgZnJvbSBMZWN0dXJlcyAzMi8zMy4gSXRzIG1lYW4gaW5jbHVkZXMgdGhlIHRpbWUgdHJlbmQsIHR3byBGb3VyaWVyIHBhaXJzIGFuZCB3ZWF0aGVyIHByZWRpY3RvcnMuIFdlIG5vdyBmaXQgYm90aCBPTFMgYW5kIEdMUyB0byBhbGwgZnVuY3Rpb25pbmcgZGF5cy4NCg0KYHIgeGZ1bjo6ZW1iZWRfZmlsZSgiLi4vZGF0YS9zZW91bF9iaWtlX2RhaWx5LmNzdiIpYA0KDQpgYGB7ciByZWFkLXNlb3VsLWRhaWx5LWdscywgaW5jbHVkZT1GQUxTRX0NCnNlb3VsX2RhaWx5IDwtIHJlYWRfY3N2KCIuLi9kYXRhL3Nlb3VsX2Jpa2VfZGFpbHkuY3N2Iiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgfD4NCiAgbXV0YXRlKGRhdGUgPSBhcy5EYXRlKGRhdGUpKSB8Pg0KICBhcnJhbmdlKGRhdGUpIHw+DQogIGZpbHRlcihmdW5jdGlvbmluZ19kYXlfYWxsID09ICJ5ZXMiKSB8Pg0KICBtdXRhdGUoDQogICAgUzEgPSBzaW4oMiAqIHBpICogZGF5X2luZGV4IC8gMzY1KSwNCiAgICBDMSA9IGNvcygyICogcGkgKiBkYXlfaW5kZXggLyAzNjUpLA0KICAgIFMyID0gc2luKDQgKiBwaSAqIGRheV9pbmRleCAvIDM2NSksDQogICAgQzIgPSBjb3MoNCAqIHBpICogZGF5X2luZGV4IC8gMzY1KQ0KICApDQpzdG9waWZub3QobnJvdyhzZW91bF9kYWlseSkgPT0gMzUyLCBhbGwoZGlmZihzZW91bF9kYWlseSRkYXlfaW5kZXgpID4gMCksDQogICAgICAgICAgIWFueUR1cGxpY2F0ZWQoc2VvdWxfZGFpbHkkZGF0ZSkpDQpgYGANCg0KYGBge3Igc2VvdWwtbWVhbi1tb2RlbH0NCnNlb3VsX2xtIDwtIGxtKA0KICByZW50ZWRfYmlrZV9jb3VudCB+IGRheV9pbmRleCArIFMxICsgQzEgKyBTMiArIEMyICsNCiAgICBtZWFuX3RlbXBlcmF0dXJlICsgdG90YWxfcmFpbmZhbGwgKyB0b3RhbF9zb2xhcl9yYWRpYXRpb24sDQogIGRhdGEgPSBzZW91bF9kYWlseQ0KKQ0KYGBgDQoNCmBTMWAsIGBDMWAsIGBTMmAgYW5kIGBDMmAgYXJlIHRoZSBzYW1lIGFubnVhbCBzZWFzb25hbCB0ZXJtcyB1c2VkIGVhcmxpZXIuIFRoZSBtZWFuIGZvcm11bGEgaXMgaGVsZCBjb25zdGFudCBmb3IgdGhlIGNvbXBhcmlzb24uDQoNCiMjIFNlb3VsOiBGaXQgQVIoMSkgVXNpbmcgQWN0dWFsIERheSBEaXN0YW5jZXMNCg0KYGBge3Igc2VvdWwtZ2xzfQ0Kc2VvdWxfZ2xzIDwtIGdscygNCiAgcmVudGVkX2Jpa2VfY291bnQgfiBkYXlfaW5kZXggKyBTMSArIEMxICsgUzIgKyBDMiArDQogICAgbWVhbl90ZW1wZXJhdHVyZSArIHRvdGFsX3JhaW5mYWxsICsgdG90YWxfc29sYXJfcmFkaWF0aW9uLA0KICBjb3JyZWxhdGlvbiA9IGNvckFSMShmb3JtID0gfiBkYXlfaW5kZXgpLA0KICBkYXRhID0gc2VvdWxfZGFpbHkNCikNCmBgYA0KDQpgYGB7ciBzZW91bC1nbHMtdmFsdWVzLCBpbmNsdWRlPUZBTFNFfQ0Kc2VvdWxfcGhpIDwtIHVubmFtZShjb2VmKHNlb3VsX2dscyRtb2RlbFN0cnVjdCRjb3JTdHJ1Y3QsIHVuY29uc3RyYWluZWQgPSBGQUxTRSkpDQpzZW91bF9ub3JtYWxpemVkX3Jlc2lkdWFscyA8LSByZXNpZHVhbHMoc2VvdWxfZ2xzLCB0eXBlID0gIm5vcm1hbGl6ZWQiKQ0Kc2VvdWxfZGlhZ25vc3RpY3MgPC0gc2VvdWxfZGFpbHkgfD4NCiAgbXV0YXRlKG9sc19yZXNpZHVhbCA9IHJlc2lkKHNlb3VsX2xtKSwNCiAgICAgICAgIG5vcm1hbGl6ZWRfcmVzaWR1YWwgPSBzZW91bF9ub3JtYWxpemVkX3Jlc2lkdWFscykNCmBgYA0KDQpCb3RoIG1vZGVscyB1c2UgYWxsIGByIG5yb3coc2VvdWxfZGFpbHkpYCBmdW5jdGlvbmluZyBkYXlzLiBXZSByZXRhaW4gdGhlIG9yaWdpbmFsIGBkYXlfaW5kZXhgIGFmdGVyIHJlbW92aW5nIHRoZSAxMyBvdXRhZ2UgZGF5cy4gQSBnYXAgb2YgdGhyZWUgZGF5cyB0aGVyZWZvcmUgaGFzIG1vZGVsbGVkIGVycm9yIGNvcnJlbGF0aW9uICRccGhpXjMkLCByYXRoZXIgdGhhbiBiZWluZyB0cmVhdGVkIGFzIG9uZSBzdGVwLg0KDQpIZXJlICRcaGF0XHBoaVxhcHByb3ggYHIgcm91bmQoc2VvdWxfcGhpLCAzKWAkLiBUaGUgbmV4dCBxdWVzdGlvbiBpcyB3aGV0aGVyIHRoZSBub3JtYWxpc2VkIHJlc2lkdWFscyBzaG93IGxlc3MgZGVwZW5kZW5jZS4NCg0KIyMgU2VvdWw6IENvbXBhcmUgRXN0aW1hdGVzIGFuZCBTdGFuZGFyZCBFcnJvcnMNCg0KYGBge3Igc2VvdWwtZ2xzLWNvbXBhcmlzb24sIGVjaG89RkFMU0V9DQpzZW91bF90cmVuZCA8LSBiaW5kX3Jvd3MoDQogIHRpZHkoc2VvdWxfbG0pIHw+IG11dGF0ZShtb2RlbCA9ICJPTFMiKSwNCiAgdGlkeShzZW91bF9nbHMpIHw+IG11dGF0ZShtb2RlbCA9ICJHTFMgd2l0aCBBUigxKSIpDQopIHw+DQogIGZpbHRlcih0ZXJtID09ICJkYXlfaW5kZXgiKSB8Pg0KICBzZWxlY3QobW9kZWwsIGVzdGltYXRlLCBzdGQuZXJyb3IpDQoNCnNlb3VsX3RyZW5kIHw+DQogIHJlbmFtZShNb2RlbCA9IG1vZGVsLCBgVHJlbmQgZXN0aW1hdGVgID0gZXN0aW1hdGUsIGBTdGFuZGFyZCBlcnJvcmAgPSBzdGQuZXJyb3IpIHw+DQogIGthYmxlKGRpZ2l0cyA9IDIpDQpgYGANCg0KVGhlIGRheS1pbmRleCBjb2VmZmljaWVudCBpcyB0aGUgY2hhbmdlIGluIGV4cGVjdGVkIGRhaWx5IHJlbnRhbHMgcGVyIGFkZGl0aW9uYWwgZGF5LCBob2xkaW5nIHRoZSBzZWFzb25hbCBhbmQgd2VhdGhlciBwcmVkaWN0b3JzIGNvbnN0YW50LiBJdHMgZXN0aW1hdGUgY2hhbmdlcyBmcm9tIGByIHJvdW5kKHNlb3VsX3RyZW5kJGVzdGltYXRlWzFdLCAyKWAgdG8gYHIgcm91bmQoc2VvdWxfdHJlbmQkZXN0aW1hdGVbMl0sIDIpYCwgd2hpbGUgaXRzIHN0YW5kYXJkIGVycm9yIGluY3JlYXNlcy4NCg0KQXMgaW4gdG91cmlzbSwgYWNjb3VudGluZyBmb3IgZGVwZW5kZW5jZSBjaGFuZ2VzIHRoZSBwcmVjaXNpb24gY2FsY3VsYXRpb24uIEhlcmUgaXQgYWxzbyBtYWtlcyBhIG1vcmUgdmlzaWJsZSBkaWZmZXJlbmNlIHRvIHRoZSB0cmVuZCBlc3RpbWF0ZS4NCg0KIyMgU2VvdWw6IE1ha2UgYSBNYXRjaGVkIERpYWdub3N0aWMgQ29tcGFyaXNvbg0KDQpBbiBvcmRpbmFyeSBBQ0YgYXNzdW1lcyBlcXVhbGx5IHNwYWNlZCBvYnNlcnZhdGlvbnMuIFVzZSB0aGUgdW5pbnRlcnJ1cHRlZCBwZXJpb2QgZnJvbSAxIERlY2VtYmVyIDIwMTcgdG8gMTAgQXByaWwgMjAxOCBmb3IgKipib3RoKiogcmVzaWR1YWwgc2VxdWVuY2VzOg0KDQpgYGB7ciBzZW91bC1kaWFnbm9zdGljLXdpbmRvd30NCnNlb3VsX3J1biA8LSBzZW91bF9kaWFnbm9zdGljcyB8Pg0KICBmaWx0ZXIoZGF0ZSA+PSBhcy5EYXRlKCIyMDE3LTEyLTAxIiksDQogICAgICAgICBkYXRlIDw9IGFzLkRhdGUoIjIwMTgtMDQtMTAiKSkNCg0Kc3RvcGlmbm90KG5yb3coc2VvdWxfcnVuKSA9PSAxMzEsDQogICAgICAgICAgYWxsKGRpZmYoc2VvdWxfcnVuJGRheV9pbmRleCkgPT0gMSksDQogICAgICAgICAgYWxsKGFzLm51bWVyaWMoZGlmZihzZW91bF9ydW4kZGF0ZSkpID09IDEpKQ0KYGBgDQoNCkJvdGggbW9kZWxzIHdlcmUgZml0dGVkIG9uIDM1MiBkYXlzOyB0aGVzZSBwbG90cyBleGFtaW5lIHRoZWlyIHJlc2lkdWFscyBvbiB0aGUgc2FtZSAxMzEtZGF5IHdpbmRvdy4gKipMZWN0dXJlIDM0IHJlZml0dGVkIHRoZSBtZWFuIG1vZGVsIG9uIHRoYXQgd2luZG93LioqIEl0cyByZXNpZHVhbHMgdGhlcmVmb3JlIGRpZmZlciBmcm9tIHRoZSBmdWxsLXllYXIgT0xTIHJlc2lkdWFscyBjb21wYXJlZCBoZXJlLg0KDQojIyBTZW91bDogQUNGIEJlZm9yZSBhbmQgQWZ0ZXIgR0xTDQoNCmBgYHtyIHNlb3VsLW5vcm1hbGl6ZWQtcmVzaWR1YWwtYWNmLCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD0zLjUsIG91dC53aWR0aD0iOTAlIiwgZmlnLmFsdD0iTWF0Y2hlZCBBQ0ZzIG92ZXIgdGhlIHNhbWUgMTMxIGNvbnNlY3V0aXZlIFNlb3VsIGRheXMgZnJvbSBmdWxsLXllYXIgT0xTIGFuZCBHTFMgZml0cyJ9DQpzZW91bF9ydW5fb2xzX3IgPC0gYXMubnVtZXJpYyhhY2Yoc2VvdWxfcnVuJG9sc19yZXNpZHVhbCwgbGFnLm1heCA9IDE0LCBwbG90ID0gRkFMU0UpJGFjZilbLTFdDQpzZW91bF9ydW5fbm9ybWFsaXNlZF9yIDwtIGFzLm51bWVyaWMoYWNmKHNlb3VsX3J1biRub3JtYWxpemVkX3Jlc2lkdWFsLCBsYWcubWF4ID0gMTQsIHBsb3QgPSBGQUxTRSkkYWNmKVstMV0NCnNlb3VsX2FjZl9saW1pdCA8LSBxbm9ybSgwLjk3NSkgLyBzcXJ0KG5yb3coc2VvdWxfcnVuKSkNCg0KdGliYmxlKA0KICBMYWcgPSByZXAoMToxNCwgMiksDQogIENvcnJlbGF0aW9uID0gYyhzZW91bF9ydW5fb2xzX3IsIHNlb3VsX3J1bl9ub3JtYWxpc2VkX3IpLA0KICBNb2RlbCA9IGZhY3RvcihyZXAoYygiT0xTIHJlc2lkdWFscyIsICJHTFMgbm9ybWFsaXNlZCByZXNpZHVhbHMiKSwgZWFjaCA9IDE0KSwNCiAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiT0xTIHJlc2lkdWFscyIsICJHTFMgbm9ybWFsaXNlZCByZXNpZHVhbHMiKSkNCikgfD4NCiAgZ2dwbG90KGFlcyhMYWcsIENvcnJlbGF0aW9uKSkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvdXIgPSAiZ3JleTU1IikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKC1zZW91bF9hY2ZfbGltaXQsIHNlb3VsX2FjZl9saW1pdCksDQogICAgICAgICAgICAgbGluZXR5cGUgPSAyLCBjb2xvdXIgPSAiIzI2N2Y4YiIpICsNCiAgZ2VvbV9zZWdtZW50KGFlcyh4ZW5kID0gTGFnLCB5ZW5kID0gMCksIGNvbG91ciA9ICIjMTczZjVmIikgKw0KICBmYWNldF93cmFwKH4gTW9kZWwsIG5yb3cgPSAxKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDEsIDQsIDcsIDEwLCAxNCkpICsNCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0wLjQsIDAuNikpICsNCiAgbGFicyh4ID0gIkxhZyAoZGF5cykiLCB5ID0gIkFDRiIpDQpgYGANCg0KTGFnLTEgY29ycmVsYXRpb24gZmFsbHMgZnJvbSBgciByb3VuZChzZW91bF9ydW5fb2xzX3JbMV0sIDMpYCB0byBgciByb3VuZChzZW91bF9ydW5fbm9ybWFsaXNlZF9yWzFdLCAzKWAuIFRoZXJlIGlzIG11Y2ggbGVzcyBuZWlnaGJvdXJpbmctZGF5IGRlcGVuZGVuY2UgaW4gdGhpcyB3aW5kb3csIGFsdGhvdWdoIHRoZSBsYWctMTQgYmFyIHN0aWxsIHN0YW5kcyBvdXQuDQoNClRoZXNlIHBsb3RzIGRvIG5vdCBlc3RhYmxpc2ggYWRlcXVhY3kgYWNyb3NzIHRoZSB3aG9sZSB5ZWFyLiBXZSBoYXZlIG5vdCB0cmVhdGVkIHRoZSBnYXBweSAzNTItcm93IHNlcmllcyBhcyBlcXVhbGx5IHNwYWNlZCwgb3IgYXBwbGllZCBhIGZvcm1hbCBManVuZy1Cb3ggdGVzdCB0byB0aGlzIHNlbGVjdGVkIHdpbmRvdy4NCg0KIyMgV2hhdCBXb3VsZCBZb3UgQ2hlY2sgQWZ0ZXIgRml0dGluZyBHTFM/DQoNCktlZXAgdGhlIG1lYW4gYW5kIGVycm9yIHF1ZXN0aW9ucyBzZXBhcmF0ZS4gQSBwbGF1c2libGUgdHJlbmQgYW5kIHNlYXNvbmFsIG1lYW4gY2FuIHN0aWxsIGxlYXZlIGRlcGVuZGVuY2UsIGFuZCBhIGZpdHRlZCBBUigxKSBwYXJhbWV0ZXIgZG9lcyBub3QgZXN0YWJsaXNoIHRoYXQgdGhlIGVycm9yIG1vZGVsIGlzIGFkZXF1YXRlLg0KDQpJbnNwZWN0IG5vcm1hbGlzZWQgcmVzaWR1YWxzIGluIHRpbWUgb3JkZXIsIGNvbXBhcmUgdGhlaXIgQUNGIHdpdGggdGhlIG9yaWdpbmFsIHJlc2lkdWFsIEFDRiwgYW5kIGludGVycHJldCBhIGpvaW50IGRpYWdub3N0aWMgd2hlcmUgYXBwcm9wcmlhdGUuIENoZWNrIGxvbmdlciBnYXBzIGFzIHdlbGwgYXMgbGFnIDEuDQoNCkZvciB0b3VyaXNtLCB3ZSBoYXZlIGFjY291bnRlZCBmb3IgbXVjaCBvZiB0aGUgc2hvcnQtdGVybSBwZXJzaXN0ZW5jZSwgd2hpbGUgc2Vhc29uYWwgZGVwZW5kZW5jZSByZW1haW5zIHdvcnRoIGludmVzdGlnYXRpbmcuIEZvciBTZW91bCwgdGhlIG1hdGNoZWQgd2luZG93IHNob3dzIGEgc3Vic3RhbnRpYWwgaW1wcm92ZW1lbnQsIHdpdGggY29uY2x1c2lvbnMgbGltaXRlZCB0byB0aGF0IHBlcmlvZC4gSW4gZWFjaCBjYXNlLCB0aGUgbmV4dCBtb2RlbGxpbmcgZGVjaXNpb24gY29tZXMgZnJvbSB3aGF0IHJlbWFpbnMgaW4gdGhlIHJlc2lkdWFscy4NCg0KIyMgTG9va2luZyBGb3J3YXJkDQoNCldlIHN0b3AgYXQgQVIoMSkgZXJyb3JzOiB0aGUgc2ltcGxlc3QgbW9kZWwgd2UgY291bGQgd3JpdGUgZm9yIGRlcGVuZGVuY2UgYmV0d2VlbiBuZWlnaGJvdXJpbmcgb2JzZXJ2YXRpb25zLiBUaGUgc2FtZSBtb3ZlLCBjaG9vc2luZyBhIHN0cnVjdHVyZSBmb3IgJFxTaWdtYSQgYW5kIGVzdGltYXRpbmcgaXQgYWxvbmdzaWRlIHRoZSBtZWFuLCBpcyB0aGUgd29ya2luZyBoZWFydCBvZiBzZXZlcmFsIGZpZWxkcyB0aGlzIGNvdXJzZSBkb2VzIG5vdCByZWFjaC4NCg0KOjo6IGluY3JlbWVudGFsDQotICoqQVJJTUEgbW9kZWxzKio6IHRoZSBzdGFuZGFyZCBmb3JlY2FzdGluZyB0b29sa2l0LiBEaWZmZXJlbmNpbmcgcmVtb3ZlcyBhIHRyZW5kIGJlZm9yZSBmaXR0aW5nLCBhbmQgYXV0b3JlZ3Jlc3NpdmUgYW5kIG1vdmluZy1hdmVyYWdlIHRlcm1zIGxldCB0aGUgZXJyb3JzIGNhcnJ5IGxvbmdlciBtZW1vcnkgdGhhbiBvdXIgc2luZ2xlICRccGhpJC4gVXNlZCBmb3Igc2hvcnQtdGVybSBmb3JlY2FzdHMgb2YgZGVtYW5kLCBlbmVyZ3kgYW5kIGVjb25vbWljIHNlcmllcywgZWFjaCBpc3N1ZWQgd2l0aCBhIHByZWRpY3Rpb24gaW50ZXJ2YWwuDQotICoqR0FSQ0ggbW9kZWxzKio6IGZvciByZXR1cm5zIGFuZCBvdGhlciBzZXJpZXMgd2hlcmUgdm9sYXRpbGl0eSBpdHNlbGYgaXMgY29ycmVsYXRlZC4gVG9kYXkncyB2YXJpYW5jZSBpcyB3cml0dGVuIGFzIGEgZnVuY3Rpb24gb2YgeWVzdGVyZGF5J3Mgc3F1YXJlZCBpbm5vdmF0aW9ucywgc28gY2FsbSBzdHJldGNoZXMgZm9sbG93IGNhbG0gYW5kIHdpbGQgZm9sbG93IHdpbGQuIEJhbmtzIGFuZCBpbnN1cmVycyBidWlsZCByaXNrIG1lYXN1cmVzIG9uIGl0Lg0KLSAqKk1peGVkIG1vZGVscyoqOiBmb3IgZ3JvdXBlZCBkYXRhIHN1Y2ggYXMgcmVwZWF0ZWQgbWVhc3VyZW1lbnRzIG9uIHRoZSBzYW1lIHBhdGllbnQsIHBsb3Qgb3Igc2Nob29sLiBFYWNoIGdyb3VwIHJlY2VpdmVzIGl0cyBvd24gY29lZmZpY2llbnQgZHJhd24gZnJvbSBhIHNoYXJlZCBkaXN0cmlidXRpb24sIHdoaWNoIGJ1aWxkcyBhIGJsb2NrIHN0cnVjdHVyZSBpbnRvICRcU2lnbWEkLiBUaGUgd29ya2hvcnNlIG9mIGxvbmdpdHVkaW5hbCBhbmQgY2xpbmljYWwgc3R1ZGllcy4NCi0gKipHYXVzc2lhbiBwcm9jZXNzZXMqKjogcmVwbGFjZSB0aGUgZml4ZWQgJFxwaGleayQgZGVjYXkgd2l0aCBhIGNvdmFyaWFuY2UgZnVuY3Rpb24gb2YgZGlzdGFuY2UuIFRoZSBqb2ludCBkaXN0cmlidXRpb24gb2YgZml0dGVkIHZhbHVlcyB0aGVuIGdpdmVzIHByZWRpY3Rpb24gaW50ZXJ2YWxzIHRoYXQgd2lkZW4gYXdheSBmcm9tIHRoZSBkYXRhLiBUaGlzIGlzIGtyaWdpbmcgaW4gZ2Vvc3RhdGlzdGljcyBhbmQgdGhlIHN1cnJvZ2F0ZSBiZWhpbmQgQmF5ZXNpYW4gb3B0aW1pc2F0aW9uIGluIG1hY2hpbmUgbGVhcm5pbmcuDQo6OjoNCg0KQWxsIGZvdXIgcmV1c2UgdGhlIG1vdmUgd2UgbWFkZSB0b2RheTogbW9kZWwgdGhlIGNvdmFyaWFuY2UsIGVzdGltYXRlIGl0IHdpdGggdGhlIG1lYW4sIGFuZCBsZXQgdGhlIHJlc2lkdWFscyBzYXkgd2hldGhlciBtb3JlIHN0cnVjdHVyZSBpcyBuZWVkZWQuDQo=