library(DescTools)
library(lmtest)
Loading required package: zoo
Attaching package: 'zoo'
The following objects are masked from 'package:base':
as.Date, as.Date.numeric
Introduction: Autocorrelation
The standard assumption in regression models is that errors are
uncorrelated. This means that, once you take out the overall linear
trend in the data, then the residuals are randomly scattered. For
example, having a high positive residual on one row of the data gives
you no clue about whether the residual is likely to be positive or
negative on the next row.
If this assumption is untrue then we describe the data as having
“correlated errors”. When it occurs because observations have a
natural sequential order, this correlation is referred to as serial
correlation, or autocorrelation.
Autocorrelation (usually) implies that adjacent residuals will tend
to be similar.
This may be because of some omitted variable. For example
spatial (“space–ial”) autocorrelation may occur in
agriculture because adjacent plots of ground have similar soil, drainage
and weather patterns, compare to plots in different areas. Or
district-by-district medical data may show autocorrelation in cases of
disease, again because of weather or because of similarity of ethnic
background and lifestyle of people in adjacent districts.
Temporal autocorrelation (i.e. in time) in stock or exchange
rate prices may also be because of omitted variables. For example,
prices may be relatively high one week because of certain economic
conditions etc. Then unless those conditions have suddenly changed the
prices are likely to remain relatively high the following week.
The point is that if we were to include information about the omitted
variable in the analysis, then the apparent autocorrelation
would disappear.
However autocorrelation may also occur because of some genuine
infectious-type behaviour. For example:
in agriculture, if a field of barley is diseased, then the
adjacent field may be infected by the first one;
in business, if one business fails it may damage the ability of
other businesses to keep trading;
in education, if one student uses drugs then other students may
be encouraged to try them, etc.
Whilst adding an appropriate variable to the model may remove the
apparent autocorrelation in some situations, there is less we can do
about infectious behaviour. We have to live with it and adjust our
analysis.
If the errors are correlated then this is both a nuisance (makes the
analysis harder) and an opportunity (maybe there is information in the
data we can exploit).
Positive or Negative Autocorrelation?
• When data are positively autocorrelated, high positive residuals
tend to be followed by more positive residuals, and high negative
residuals tend to be followed by further negative ones.
The result is that the residuals show a long slow wandering
behaviour.
X = 1:2000
err = rnorm(2000, 0, 0.5)
Y = rep(100, 2000)
for (i in 2:2000) Y[i] = Y[i - 1] + err[i]
plot(X, Y, type = "l")
Example. Suppose the stock market is fairly stable and the price of a
particular stock is not going anywhere. However by chance someone comes
into a lot of cash, and decides to invest in that stock. (Or,
alternatively, somebody decides to sell their shares for some reason
totally unrelated to the stock). In terms of modelling the stock market,
both of these would be regarded as random events. However, if the sale
is big enough, others may take notice. In the case of a big purchase,
they may think there is some good news in the wings, for the company,
and so may decide to buy as well. Then the positive blip in prices is
reinforced. (In the alternative case of the big sale, others may think
there is something wrong with the company, and so decide to sell their
shares as well. Then the negative blip is repeated by more negative
blips.)
Both these situations are referred to as positive
autocorrelation: the tendency for random blips to be reinforced
by blips in the same direction. Eventually, in either case, it will
become clear there was no problem with the stock, and the price will
return to about normal - the effect will die out.
You can also get negative autocorrelation. This is where figures
oscillate above average (or above the trend), below average, above ,
below, above, …
For example (purely hypothetical?!) Suppose by chance there are far
more car accident fatalities than usual one month. This would generally
lead to a police blitz on speed/drink driving etc.
As there is more law-enforcement, the public may take more care. This
will probably lead to fewer fatalities next month (below average).
However, once the numbers are down, the police will divert resources to
some other area of crime. I.e. there will be a relaxation of the
blitz.
It is possible that the public will then go back to their old ways. In a
really bad situation you would get an oscillatory effect, above and
below the long-term mean.
The above example may be a little far-fetched, but we may see
oscillatory behaviour in the case of sales of some goods where there is
a continual (periodic) demand. (E.g. I started buying my favourite
breakfast cereal when it was “on special” and thereafter I buy it every
two weeks).
The Effects of Autocorrelation
Least squares estimates are unbiased but are not efficient.
Basically what this means is that we still expect errors above and below
the line to cancel out, but they will take longer to do so (require more
data). We can get better estimates using a more sophisticated method
than Least Squares, that takes account of the autocorrelation. These
better estimates will usually have more reliable standard errors than
the Least Squares ones.
The estimate of \(\sigma\) and
related standard errors that we get from Least Squares may be
understated, i.e. the estimated regression parameters would appear to be
more accurate than they really are. This is a serious drawback, because
we have a problem with accuracy and yet may not realise it.
Confidence intervals and hypothesis tests are not valid (have
wrong significance level etc). This is a consequence of the previous
point.
In summary, if we have autocorrelation then we need to take action.
What action we take depends on whether the autocorrelation is apparent
(due to omitted variables) or “pure autocorrelation”. The former is
something we can start to deal with in this course. The latter may
require a transformation of the data, or the application of specialist
Time Series techniques. Next we consider a numerical example.
Example: Consumer Expenditure and Money Stock
This example from the Chatterjee and Price book (3rd Ed, p202). It
concerns Consumer Expenditure (y) and the Stock of Money (x) in billions
of US Dollars.
A simple theoretical model suggests \[y =
\alpha + \beta x + \varepsilon\]
where the so-called multiplier, \(\beta\), is a quantity of considerable
importance to fiscal and monetary policy.
Download MoneyStock.csv
## MoneyStock = read.csv("MoneyStock.csv", header = TRUE)
MoneyStock |>
head() |>
kable()
1952 |
1 |
214.6 |
159.3 |
1952.00 |
1952 |
2 |
217.7 |
161.2 |
1952.25 |
1952 |
3 |
219.6 |
162.8 |
1952.50 |
1952 |
4 |
227.2 |
164.6 |
1952.75 |
1953 |
1 |
230.9 |
165.9 |
1953.00 |
1953 |
2 |
233.3 |
167.9 |
1953.25 |
A regression seems to give us quite a good estimate of \(\beta\):
MoneyStock.lm1 = lm(ConsExp ~ MoneyStk, data = MoneyStock)
summary(MoneyStock.lm1)
Call:
lm(formula = ConsExp ~ MoneyStk, data = MoneyStock)
Residuals:
Min 1Q Median 3Q Max
-7.176 -3.396 1.396 2.928 6.361
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -154.7192 19.8500 -7.794 3.54e-07 ***
MoneyStk 2.3004 0.1146 20.080 8.99e-14 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.983 on 18 degrees of freedom
Multiple R-squared: 0.9573, Adjusted R-squared: 0.9549
F-statistic: 403.2 on 1 and 18 DF, p-value: 8.988e-14
plot(residuals(MoneyStock.lm1), type = "b")
abline(h = 0, lty = 2)
Note the 95% Confidence Interval for \(\beta\), using standard formulae, is \(\hat\beta \pm t_{18}(0.025) se(\hat\beta)\)
i.e. 2.300 \(\pm\) 2.10 \(\times\) 0.115 or 2.06 to 2.54. The model
looks to be giving useful output, but are the assumptions valid?
The Residual Plot above suggests problems. The residuals show the
long slow wandering behaviour that is typical of positively
autocorrelated data. The high positive residuals tend to be followed by
more positive residuals, and high negative residuals tend to be followed
by further negative ones. Thus a curve connecting the residuals together
does not cross the zero line (axis) very often. The idea in the last
sentence is actually the basis for our first proper test of serial
correlation: the runs test.
Analysis of Runs
The residuals have signs
+ + - + + + – – – – – – – – – + + + + + +
That is, there are five “runs” of residuals .
We can use the number of runs as a test for randomness. Suppose there
are \(n_1\) positive residuals and
\(n_2\) negative residuals.
If we assume the +s and –s occur in random order, a bit of
mathematical theory can give us the expected number or runs, and also a
theoretical standard deviation for the number of runs. We (or rather the
computer) can compare the observed number of runs with this theoretical
ideal, and come up with a P-value for the data.
Since the software will do all the calculations for us, we will not
concern ourselves with the details of the method.
Then, on the basis of the P-value, we can decide whether the null
hypothesis
\(H_0\): residuals are random
is indeed tenable, or whether it must be rejected. If rejected, then
we conclude
\(H_1\): residuals are correlated. An
example of the calculation follows (this needs loading of the library
DescTools ).
library(DescTools)
RunsTest(residuals(MoneyStock.lm1))
Runs Test for Randomness
data: residuals(MoneyStock.lm1)
runs = 5, m = 10, n = 10, p-value = 0.008985
alternative hypothesis: true number of runs is not equal the expected number
sample estimates:
median(x)
1.395704
Durbin-Watson Test
An alternative (more powerful) approach is the Durbin-Watson test.
Again this test is based on the sample residuals \(e_t\) from the linear model.
The idea is that if we have positive autocorrelation, the residual at
time t will often be similar (at least in sign) to the residual at time
t-1.
So if we subtract \(e_t – e_{t-1}\)
then we should get a number which is small compared to the average
residual. This is the basis of the test.
The actual formula for the test statistic is not examinable.
library(lmtest)
dwtest(MoneyStock.lm1, alternative = "greater") #other alternatives are 'two.sided', 'less'
Durbin-Watson test
data: MoneyStock.lm1
DW = 0.32821, p-value = 2.303e-08
alternative hypothesis: true autocorrelation is greater than 0
The small P-value indicates that we reject the null hypothesis \(H_0\): no autocorrelation, in favour of the
alternative hypothesis \(H_1\):
positive autocorrelation.
What Can We Do About Serial Correlation?
If the series is reasonably long, then we can shift to the Time
Series paradigm of analysis. This is possibly the best way.
For short series and simple regression-type problems, we can use
a transformation method called the Cochrane-Orcutt method.
Cochrane-Orcutt method (details can be omitted 2024)
The following method can be applied to models with more than one
predictor variable.
Suppose the errors in the model \[ Y_t =
\alpha + \beta X_t + \varepsilon_t\]
are AR(1) i.e. a first-order autoregressive series
\[\varepsilon_t = \phi \varepsilon_{t-1} +
\eta_t\]
This represents that the errors \(\varepsilon_t\) at one time point \(t\) “remember” where they were the previous
time point, \(\varepsilon_{t-1}\), but
then there is an additional independent error component \(\eta_t\) specific to that time point.
(Independent essentially means we can’t predict any specific component
from any previous component.)
The multiplier \(\phi\) is a number
between -1 and +1, that ensures that the effect of previous years
gradually dies out, so that the series should eventually return to
around the long-term trend. It turns out that \(\phi\) equals the autocorrelation
coefficient,
\[\phi = \mbox{Corr}(Y_t, Y_{t-1}) =
\mbox{Corr}( \varepsilon_t,\varepsilon_{t-1})~.\]
Now suppose we let \(y_t^*= y_t - \phi
y_{t-1}\) and \(x_t^* = x_t - \phi
x_{t-1}\).
Now
\[y_t^* = (\alpha + \beta X_t +
\varepsilon_t) - \phi( \alpha + \beta X_{t-1} +
\varepsilon_{t-1})\] \[= \alpha(1-\phi) + \beta (x_t-\phi x_{t-1})
+ (\varepsilon_t - \phi \varepsilon_{t-1}) = \alpha^* + \beta^* x_t^*
+ \eta_t ~~~~ (*)\] where \(\alpha^* =
\alpha(1-\phi)\), \(\beta^* =
\beta\) and the errors \(\eta_t\) are uncorrelated, so that the
model (*) satisfies the general linear model assumptions.
However \(\phi\) is not known. So we
need to plug in an estimate, which we can get from Time Series Analysis
or the Durbin-Watson test. We can fit the model, then, using the
Cochrane-Orcutt Iterative Method. The steps are:
Calculate \(\alpha\) and \(\beta\) by ordinary least squares.
Calculate the residuals \(e_t\),
and from these estimate \(\rho\).
Fit the regression model (*) by least squares, using transformed
variables \(y^*\) and \(x^*\).
Estimate \(\alpha^*\) and \(\beta^*\).
- Compute residuals and examine again for autocorrelation. If there is
none, then stop; if there is still autocorrelation then repeat from step
2 using residuals from step 3.
In practice Chatterjee and Price advise that if the one-step
procedure doesn’t remove the autocorrelation then one should look for
alternative methods, since further iteration is not likely to give much
improvement.
Example
For the MoneyStock problem, \(r=0.751\) by the dwt output. We use this as
an estimate of \(\phi\).
r = 0.751
y = MoneyStock$ConsExp
yStar = y[2:20] - r * y[1:19]
x = MoneyStock$MoneyStk
xStar = x[2:20] - r * x[1:19]
lmstar = lm(yStar ~ xStar)
dwtest(lmstar)
Durbin-Watson test
data: lmstar
DW = 1.427, p-value = 0.05814
alternative hypothesis: true autocorrelation is greater than 0
Call:
lm(formula = yStar ~ xStar)
Residuals:
Min 1Q Median 3Q Max
-4.3746 -0.7854 0.2731 1.0405 3.9782
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -53.6355 13.6166 -3.939 0.00106 **
xStar 2.6440 0.3074 8.602 1.34e-07 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 2.262 on 17 degrees of freedom
Multiple R-squared: 0.8132, Adjusted R-squared: 0.8022
F-statistic: 74 on 1 and 17 DF, p-value: 1.34e-07
2.5 % 97.5 %
(Intercept) -82.363983 -24.907052
xStar 1.995503 3.292408
The transformed series has a non-significant Durbin-Watson test, so
it looks that the first-order autocorrelation has been fixed.
The confidence interval for the regression coefficients show that
\(\beta\) is in the wider interval
(2.0, 3.29). So our real knowledge of \(\beta\) is much less precise than the
earlier misleading regression model have told us.
Conclusion
The above example illustrates the point made earlier, that ignoring
the autocorrelation can lead to misleading results.
In particular, positive autocorrelation implies that the usual
(independence model) standard errors of the slopes are too small, while
negative autocorrelation implies that the standard errors in the
independence model are too big.
LS0tDQp0aXRsZTogIkxlY3R1cmUgNDc6IFNlcmlhbCBDb3JyZWxhdGlvbiINCnN1YnRpdGxlOiAxNjEuMjUxIFJlZ3Jlc3Npb24gTW9kZWxsaW5nDQphdXRob3I6ICJQcmVzZW50ZWQgYnkgSm9uYXRoYW4gTWFyc2hhbGwgPEouQy5tYXJzaGFsbEBtYXNzZXkuYWMubno+IiAgDQpkYXRlOiAiV2VlayAxMiBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0KDQoNCmBgYHtyIGV4dHJhTGlic30NCmxpYnJhcnkoRGVzY1Rvb2xzKQ0KbGlicmFyeShsbXRlc3QpDQpgYGANCg0KDQojIyMgSW50cm9kdWN0aW9uOglBdXRvY29ycmVsYXRpb24gICANCg0KVGhlIHN0YW5kYXJkIGFzc3VtcHRpb24gaW4gcmVncmVzc2lvbiBtb2RlbHMgaXMgdGhhdCBlcnJvcnMgYXJlIHVuY29ycmVsYXRlZC4gICAgIFRoaXMgbWVhbnMgdGhhdCwgb25jZSB5b3UgdGFrZSBvdXQgdGhlIG92ZXJhbGwgbGluZWFyIHRyZW5kIGluIHRoZSBkYXRhLCAgdGhlbiB0aGUgcmVzaWR1YWxzIGFyZSByYW5kb21seSBzY2F0dGVyZWQuICAgRm9yIGV4YW1wbGUsIGhhdmluZyBhIGhpZ2ggcG9zaXRpdmUgcmVzaWR1YWwgb24gb25lIHJvdyBvZiB0aGUgZGF0YSBnaXZlcyB5b3Ugbm8gY2x1ZSBhYm91dCB3aGV0aGVyIHRoZSByZXNpZHVhbCBpcyBsaWtlbHkgdG8gYmUgcG9zaXRpdmUgb3IgbmVnYXRpdmUgb24gdGhlIG5leHQgcm93LiANCg0KSWYgdGhpcyBhc3N1bXB0aW9uIGlzIHVudHJ1ZSB0aGVuIHdlIGRlc2NyaWJlIHRoZSBkYXRhIGFzIGhhdmluZyAq4oCcY29ycmVsYXRlZCBlcnJvcnPigJ0qLiAgV2hlbiBpdCBvY2N1cnMgYmVjYXVzZSBvYnNlcnZhdGlvbnMgaGF2ZSBhIG5hdHVyYWwgc2VxdWVudGlhbCBvcmRlciwgdGhpcyBjb3JyZWxhdGlvbiBpcyByZWZlcnJlZCB0byBhcyAqc2VyaWFsIGNvcnJlbGF0aW9uKiwgb3IgICphdXRvY29ycmVsYXRpb24qLiAgIA0KDQpBdXRvY29ycmVsYXRpb24gKHVzdWFsbHkpIGltcGxpZXMgdGhhdCBhZGphY2VudCByZXNpZHVhbHMgd2lsbCB0ZW5kIHRvIGJlIHNpbWlsYXIuDQoNClRoaXMgbWF5IGJlIGJlY2F1c2Ugb2Ygc29tZSBvbWl0dGVkIHZhcmlhYmxlLiAgRm9yIGV4YW1wbGUgKnNwYXRpYWwqICjigJxzcGFjZeKAk2lhbOKAnSkgKmF1dG9jb3JyZWxhdGlvbiogbWF5IG9jY3VyIGluIGFncmljdWx0dXJlIGJlY2F1c2UgYWRqYWNlbnQgcGxvdHMgb2YgZ3JvdW5kIGhhdmUgc2ltaWxhciBzb2lsLCBkcmFpbmFnZSBhbmQgd2VhdGhlciBwYXR0ZXJucywgY29tcGFyZSB0byBwbG90cyBpbiBkaWZmZXJlbnQgYXJlYXMuICBPciBkaXN0cmljdC1ieS1kaXN0cmljdCBtZWRpY2FsIGRhdGEgbWF5IHNob3cgYXV0b2NvcnJlbGF0aW9uIGluIGNhc2VzIG9mIGRpc2Vhc2UsIGFnYWluIGJlY2F1c2Ugb2Ygd2VhdGhlciBvciBiZWNhdXNlIG9mIHNpbWlsYXJpdHkgb2YgZXRobmljIGJhY2tncm91bmQgYW5kIGxpZmVzdHlsZSBvZiBwZW9wbGUgaW4gYWRqYWNlbnQgZGlzdHJpY3RzLg0KDQoNCipUZW1wb3JhbCBhdXRvY29ycmVsYXRpb24qIChpLmUuIGluIHRpbWUpIGluIHN0b2NrIG9yIGV4Y2hhbmdlIHJhdGUgcHJpY2VzIG1heSBhbHNvIGJlIGJlY2F1c2Ugb2Ygb21pdHRlZCB2YXJpYWJsZXMuICBGb3IgZXhhbXBsZSwgcHJpY2VzIG1heSBiZSByZWxhdGl2ZWx5IGhpZ2ggb25lIHdlZWsgYmVjYXVzZSBvZiBjZXJ0YWluIGVjb25vbWljIGNvbmRpdGlvbnMgZXRjLiBUaGVuIHVubGVzcyB0aG9zZSBjb25kaXRpb25zIGhhdmUgc3VkZGVubHkgY2hhbmdlZCB0aGUgcHJpY2VzIGFyZSBsaWtlbHkgdG8gcmVtYWluIHJlbGF0aXZlbHkgaGlnaCB0aGUgZm9sbG93aW5nIHdlZWsuDQoNClRoZSBwb2ludCBpcyB0aGF0IGlmIHdlIHdlcmUgdG8gaW5jbHVkZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb21pdHRlZCB2YXJpYWJsZSBpbiB0aGUgYW5hbHlzaXMsIHRoZW4gdGhlICphcHBhcmVudCogYXV0b2NvcnJlbGF0aW9uIHdvdWxkIGRpc2FwcGVhci4gDQoNCkhvd2V2ZXIgYXV0b2NvcnJlbGF0aW9uIG1heSBhbHNvIG9jY3VyIGJlY2F1c2Ugb2Ygc29tZSBnZW51aW5lIGluZmVjdGlvdXMtdHlwZSBiZWhhdmlvdXIuICBGb3IgZXhhbXBsZTogDQoNCi0gaW4gYWdyaWN1bHR1cmUsIGlmIGEgZmllbGQgb2YgYmFybGV5IGlzIGRpc2Vhc2VkLCB0aGVuIHRoZSBhZGphY2VudCBmaWVsZCBtYXkgYmUgaW5mZWN0ZWQgYnkgdGhlIGZpcnN0IG9uZTsgDQoNCi0gaW4gYnVzaW5lc3MsIGlmIG9uZSBidXNpbmVzcyBmYWlscyBpdCBtYXkgZGFtYWdlIHRoZSBhYmlsaXR5IG9mIG90aGVyIGJ1c2luZXNzZXMgdG8ga2VlcCB0cmFkaW5nOw0KDQotIGluIGVkdWNhdGlvbiwgaWYgb25lIHN0dWRlbnQgdXNlcyBkcnVncyB0aGVuIG90aGVyIHN0dWRlbnRzIG1heSBiZSBlbmNvdXJhZ2VkIHRvIHRyeSB0aGVtLCAgZXRjLg0KDQpXaGlsc3QgYWRkaW5nIGFuIGFwcHJvcHJpYXRlIHZhcmlhYmxlIHRvIHRoZSBtb2RlbCBtYXkgcmVtb3ZlIHRoZSBhcHBhcmVudCBhdXRvY29ycmVsYXRpb24gaW4gc29tZSBzaXR1YXRpb25zLCB0aGVyZSBpcyBsZXNzIHdlIGNhbiBkbyBhYm91dCBpbmZlY3Rpb3VzIGJlaGF2aW91ci4gIFdlIGhhdmUgdG8gbGl2ZSB3aXRoIGl0IGFuZCBhZGp1c3Qgb3VyIGFuYWx5c2lzLiANCg0KSWYgdGhlIGVycm9ycyBhcmUgY29ycmVsYXRlZCB0aGVuIHRoaXMgaXMgYm90aCBhIG51aXNhbmNlIChtYWtlcyB0aGUgYW5hbHlzaXMgaGFyZGVyKSBhbmQgYW4gb3Bwb3J0dW5pdHkgKG1heWJlIHRoZXJlIGlzIGluZm9ybWF0aW9uIGluIHRoZSBkYXRhIHdlIGNhbiBleHBsb2l0KS4NCg0KIyMgUG9zaXRpdmUgb3IgTmVnYXRpdmUgQXV0b2NvcnJlbGF0aW9uPw0KDQrigKIJV2hlbiBkYXRhIGFyZSBwb3NpdGl2ZWx5IGF1dG9jb3JyZWxhdGVkLCBoaWdoIHBvc2l0aXZlIHJlc2lkdWFscyB0ZW5kIHRvIGJlIGZvbGxvd2VkIGJ5IG1vcmUgcG9zaXRpdmUgcmVzaWR1YWxzLCBhbmQgaGlnaCBuZWdhdGl2ZSByZXNpZHVhbHMgdGVuZCB0byBiZSBmb2xsb3dlZCBieSBmdXJ0aGVyIG5lZ2F0aXZlIG9uZXMuICAgDQpUaGUgcmVzdWx0IGlzIHRoYXQgdGhlIHJlc2lkdWFscyBzaG93IGEgbG9uZyBzbG93IHdhbmRlcmluZyBiZWhhdmlvdXIuIA0KDQpgYGB7ciBsb25nIHNsb3cgd2FuZGVyaW5nfQ0KWD0xOjIwMDAgOyAgICBlcnI9cm5vcm0oMjAwMCwwLDAuNSkNClk9cmVwKDEwMCwyMDAwKQ0KZm9yKGkgaW4gMjoyMDAwKSBZW2ldID0gWVsgaS0xXSArZXJyW2ldDQpwbG90KFgsWSwgdHlwZT0nbCcpDQpgYGANCg0KDQpFeGFtcGxlLiBTdXBwb3NlIHRoZSBzdG9jayBtYXJrZXQgaXMgZmFpcmx5IHN0YWJsZSBhbmQgdGhlIHByaWNlIG9mIGEgcGFydGljdWxhciBzdG9jayBpcyBub3QgZ29pbmcgYW55d2hlcmUuICBIb3dldmVyIGJ5IGNoYW5jZSBzb21lb25lIGNvbWVzIGludG8gYSBsb3Qgb2YgY2FzaCwgYW5kIGRlY2lkZXMgdG8gaW52ZXN0IGluIHRoYXQgc3RvY2suIChPciwgYWx0ZXJuYXRpdmVseSwgc29tZWJvZHkgZGVjaWRlcyB0byBzZWxsIHRoZWlyIHNoYXJlcyBmb3Igc29tZSByZWFzb24gdG90YWxseSB1bnJlbGF0ZWQgdG8gdGhlIHN0b2NrKS4gICBJbiB0ZXJtcyBvZiBtb2RlbGxpbmcgdGhlIHN0b2NrIG1hcmtldCwgYm90aCBvZiB0aGVzZSB3b3VsZCBiZSByZWdhcmRlZCBhcyByYW5kb20gZXZlbnRzLg0KSG93ZXZlciwgaWYgdGhlIHNhbGUgaXMgYmlnIGVub3VnaCwgb3RoZXJzIG1heSB0YWtlIG5vdGljZS4gIEluIHRoZSBjYXNlIG9mIGEgYmlnIHB1cmNoYXNlLCB0aGV5IG1heSB0aGluayB0aGVyZSBpcyBzb21lIGdvb2QgbmV3cyBpbiB0aGUgd2luZ3MsIGZvciB0aGUgY29tcGFueSwgYW5kIHNvIG1heSBkZWNpZGUgdG8gYnV5IGFzIHdlbGwuICAgVGhlbiB0aGUgcG9zaXRpdmUgYmxpcCBpbiBwcmljZXMgaXMgcmVpbmZvcmNlZC4gICAgKEluIHRoZSBhbHRlcm5hdGl2ZSBjYXNlIG9mIHRoZSBiaWcgc2FsZSwgb3RoZXJzIG1heSB0aGluayB0aGVyZSBpcyBzb21ldGhpbmcgd3Jvbmcgd2l0aCB0aGUgY29tcGFueSwgYW5kIHNvIGRlY2lkZSB0byBzZWxsIHRoZWlyIHNoYXJlcyBhcyB3ZWxsLiAgICBUaGVuIHRoZSBuZWdhdGl2ZSBibGlwIGlzIHJlcGVhdGVkIGJ5IG1vcmUgbmVnYXRpdmUgYmxpcHMuKSANCg0KQm90aCB0aGVzZSBzaXR1YXRpb25zIGFyZSByZWZlcnJlZCB0byBhcyAqKnBvc2l0aXZlIGF1dG9jb3JyZWxhdGlvbioqOiB0aGUgdGVuZGVuY3kgZm9yIHJhbmRvbSBibGlwcyB0byBiZSByZWluZm9yY2VkIGJ5IGJsaXBzIGluIHRoZSBzYW1lIGRpcmVjdGlvbi4NCkV2ZW50dWFsbHksIGluIGVpdGhlciBjYXNlLCAgaXQgd2lsbCBiZWNvbWUgY2xlYXIgdGhlcmUgd2FzIG5vIHByb2JsZW0gd2l0aCB0aGUgc3RvY2ssIGFuZCB0aGUgcHJpY2Ugd2lsbCByZXR1cm4gdG8gYWJvdXQgbm9ybWFsIC0gdGhlIGVmZmVjdCB3aWxsIGRpZSBvdXQuIA0KICANCllvdSBjYW4gYWxzbyBnZXQgbmVnYXRpdmUgYXV0b2NvcnJlbGF0aW9uLiAgIFRoaXMgaXMgd2hlcmUgZmlndXJlcyBvc2NpbGxhdGUgYWJvdmUgYXZlcmFnZSAob3IgYWJvdmUgdGhlIHRyZW5kKSwgYmVsb3cgYXZlcmFnZSwgYWJvdmUgLCBiZWxvdywgYWJvdmUsIC4uLg0KIA0KDQpGb3IgZXhhbXBsZSAocHVyZWx5IGh5cG90aGV0aWNhbD8hKSAgICAgU3VwcG9zZSBieSBjaGFuY2UgdGhlcmUgYXJlIGZhciBtb3JlIGNhciBhY2NpZGVudCBmYXRhbGl0aWVzIHRoYW4gdXN1YWwgb25lIG1vbnRoLiAgVGhpcyB3b3VsZCBnZW5lcmFsbHkgbGVhZCB0byBhIHBvbGljZSBibGl0eiBvbiBzcGVlZC9kcmluayBkcml2aW5nIGV0Yy4gIA0KQXMgdGhlcmUgaXMgbW9yZSBsYXctZW5mb3JjZW1lbnQsICB0aGUgcHVibGljIG1heSB0YWtlIG1vcmUgY2FyZS4gIFRoaXMgd2lsbCBwcm9iYWJseSBsZWFkIHRvIGZld2VyIGZhdGFsaXRpZXMgbmV4dCBtb250aCAoYmVsb3cgYXZlcmFnZSkuDQpIb3dldmVyLCBvbmNlIHRoZSBudW1iZXJzIGFyZSBkb3duLCB0aGUgcG9saWNlIHdpbGwgZGl2ZXJ0IHJlc291cmNlcyB0byBzb21lIG90aGVyIGFyZWEgb2YgY3JpbWUuICAgICBJLmUuIHRoZXJlIHdpbGwgYmUgYSByZWxheGF0aW9uIG9mIHRoZSBibGl0ei4gICANCkl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIHB1YmxpYyB3aWxsIHRoZW4gZ28gYmFjayB0byB0aGVpciBvbGQgd2F5cy4gICAgSW4gYSByZWFsbHkgYmFkIHNpdHVhdGlvbiB5b3Ugd291bGQgZ2V0IGFuIG9zY2lsbGF0b3J5IGVmZmVjdCwgYWJvdmUgYW5kIGJlbG93IHRoZSBsb25nLXRlcm0gbWVhbi4gDQoNClRoZSBhYm92ZSBleGFtcGxlIG1heSBiZSBhIGxpdHRsZSBmYXItZmV0Y2hlZCwgYnV0IHdlIG1heSBzZWUgb3NjaWxsYXRvcnkgYmVoYXZpb3VyIGluIHRoZSBjYXNlIG9mIHNhbGVzIG9mIHNvbWUgZ29vZHMgd2hlcmUgdGhlcmUgaXMgYSBjb250aW51YWwgKHBlcmlvZGljKSBkZW1hbmQuICAoRS5nLiBJIHN0YXJ0ZWQgYnV5aW5nIG15IGZhdm91cml0ZSBicmVha2Zhc3QgY2VyZWFsIHdoZW4gaXQgd2FzIOKAnG9uIHNwZWNpYWzigJ0gYW5kIHRoZXJlYWZ0ZXIgSSBidXkgaXQgIGV2ZXJ5IHR3byB3ZWVrcykuIA0KDQojIyBUaGUgRWZmZWN0cyBvZiBBdXRvY29ycmVsYXRpb24NCg0KLSBMZWFzdCBzcXVhcmVzIGVzdGltYXRlcyBhcmUgdW5iaWFzZWQgYnV0IGFyZSBub3QgZWZmaWNpZW50LiAgDQogIEJhc2ljYWxseSB3aGF0IHRoaXMgbWVhbnMgaXMgdGhhdCB3ZSBzdGlsbCBleHBlY3QgZXJyb3JzIGFib3ZlIGFuZCBiZWxvdyB0aGUgbGluZSB0byBjYW5jZWwgb3V0LCBidXQgdGhleSB3aWxsIHRha2UgbG9uZ2VyIHRvIGRvIHNvIChyZXF1aXJlIG1vcmUgZGF0YSkuICAgV2UgY2FuIGdldCBiZXR0ZXIgZXN0aW1hdGVzIHVzaW5nIGEgbW9yZSBzb3BoaXN0aWNhdGVkIG1ldGhvZCB0aGFuIExlYXN0IFNxdWFyZXMsIHRoYXQgdGFrZXMgYWNjb3VudCBvZiB0aGUgYXV0b2NvcnJlbGF0aW9uLiAgIFRoZXNlIGJldHRlciBlc3RpbWF0ZXMgd2lsbCB1c3VhbGx5IGhhdmUgbW9yZSByZWxpYWJsZSBzdGFuZGFyZCBlcnJvcnMgdGhhbiB0aGUgTGVhc3QgU3F1YXJlcyBvbmVzLg0KDQotIFRoZSBlc3RpbWF0ZSBvZiAgJFxzaWdtYSQgIGFuZCByZWxhdGVkIHN0YW5kYXJkIGVycm9ycyB0aGF0IHdlIGdldCBmcm9tIExlYXN0IFNxdWFyZXMgbWF5IGJlIHVuZGVyc3RhdGVkLCBpLmUuIHRoZSBlc3RpbWF0ZWQgcmVncmVzc2lvbiBwYXJhbWV0ZXJzIHdvdWxkIGFwcGVhciB0byBiZSBtb3JlIGFjY3VyYXRlIHRoYW4gdGhleSByZWFsbHkgYXJlLiAgIFRoaXMgaXMgYSBzZXJpb3VzIGRyYXdiYWNrLCBiZWNhdXNlIHdlIGhhdmUgYSBwcm9ibGVtIHdpdGggYWNjdXJhY3kgYW5kIHlldCBtYXkgbm90IHJlYWxpc2UgaXQuIA0KDQotIENvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCBoeXBvdGhlc2lzIHRlc3RzIGFyZSBub3QgdmFsaWQgKGhhdmUgd3Jvbmcgc2lnbmlmaWNhbmNlIGxldmVsIGV0YykuICBUaGlzIGlzIGEgY29uc2VxdWVuY2Ugb2YgdGhlIHByZXZpb3VzIHBvaW50Lg0KDQpJbiBzdW1tYXJ5LCBpZiB3ZSBoYXZlIGF1dG9jb3JyZWxhdGlvbiB0aGVuIHdlIG5lZWQgdG8gdGFrZSBhY3Rpb24uICBXaGF0IGFjdGlvbiB3ZSB0YWtlIGRlcGVuZHMgb24gd2hldGhlciB0aGUgYXV0b2NvcnJlbGF0aW9uIGlzIGFwcGFyZW50IChkdWUgdG8gb21pdHRlZCB2YXJpYWJsZXMpIG9yIOKAnHB1cmUgYXV0b2NvcnJlbGF0aW9u4oCdLiAgIFRoZSBmb3JtZXIgaXMgc29tZXRoaW5nIHdlIGNhbiBzdGFydCB0byBkZWFsIHdpdGggaW4gdGhpcyBjb3Vyc2UuICBUaGUgbGF0dGVyIG1heSByZXF1aXJlIGEgdHJhbnNmb3JtYXRpb24gb2YgdGhlIGRhdGEsIG9yIHRoZSBhcHBsaWNhdGlvbiBvZiBzcGVjaWFsaXN0IFRpbWUgU2VyaWVzIHRlY2huaXF1ZXMuICAgIE5leHQgd2UgY29uc2lkZXIgYSBudW1lcmljYWwgZXhhbXBsZS4NCg0KIyMgRXhhbXBsZTogQ29uc3VtZXIgRXhwZW5kaXR1cmUgYW5kIE1vbmV5IFN0b2NrICAgIA0KDQpUaGlzIGV4YW1wbGUgZnJvbSB0aGUgQ2hhdHRlcmplZSBhbmQgUHJpY2UgYm9vayAgKDNyZCBFZCwgcDIwMikuICAgIEl0IGNvbmNlcm5zIENvbnN1bWVyIEV4cGVuZGl0dXJlICh5KSBhbmQgdGhlIFN0b2NrIG9mIE1vbmV5ICh4KSBpbiBiaWxsaW9ucyBvZiBVUyBEb2xsYXJzLg0KDQpBIHNpbXBsZSB0aGVvcmV0aWNhbCBtb2RlbCBzdWdnZXN0cyANCiQkeSA9IFxhbHBoYSArIFxiZXRhIHggKyBcdmFyZXBzaWxvbiQkDQoNCndoZXJlIHRoZSBzby1jYWxsZWQgbXVsdGlwbGllciwgJFxiZXRhJCwgICBpcyBhIHF1YW50aXR5IG9mIGNvbnNpZGVyYWJsZSBpbXBvcnRhbmNlIHRvIGZpc2NhbCBhbmQgbW9uZXRhcnkgcG9saWN5Lg0KDQoNCmByIHhmdW46OmVtYmVkX2ZpbGUoIi4uLy4uL2RhdGEvTW9uZXlTdG9jay5jc3YiKWAgDQoNCmBgYHtyIHJlYWQgTW9uZXlTdG9jaywgZXZhbD0tMSwgZWNobz0tMn0NCk1vbmV5U3RvY2sgPSByZWFkLmNzdigiTW9uZXlTdG9jay5jc3YiLGhlYWRlcj1UUlVFKQ0KTW9uZXlTdG9jayA9IHJlYWQuY3N2KCIuLi8uLi9kYXRhL01vbmV5U3RvY2suY3N2IixoZWFkZXI9VFJVRSkNCk1vbmV5U3RvY2sgIHw+IGhlYWQoKSB8PiBrYWJsZSgpDQpgYGANCg0KYGBge3IgTW9uZXlTdG9ja1BhaXJzfQ0KcGFpcnMoTW9uZXlTdG9ja1szOjVdKQ0KYGBgDQoNCkEgcmVncmVzc2lvbiBzZWVtcyB0byBnaXZlIHVzIHF1aXRlIGEgZ29vZCBlc3RpbWF0ZSBvZiAkXGJldGEkOg0KDQpgYGB7ciBNb25leVN0b2NrIHJlZ3Jlc3Npb259DQpNb25leVN0b2NrLmxtMT0gbG0oQ29uc0V4cH4gTW9uZXlTdGssIGRhdGE9TW9uZXlTdG9jaykNCnN1bW1hcnkoTW9uZXlTdG9jay5sbTEpDQpwbG90KHJlc2lkdWFscyhNb25leVN0b2NrLmxtMSksdHlwZT0nYicpDQphYmxpbmUoaD0wLGx0eT0yKQ0KYGBgDQoNCk5vdGUgdGhlICA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbCAgZm9yICRcYmV0YSQsIHVzaW5nIHN0YW5kYXJkIGZvcm11bGFlLCAgIGlzICAgICRcaGF0XGJldGEgXHBtIHRfezE4fSgwLjAyNSkgc2UoXGhhdFxiZXRhKSQgICAgICAgICBpLmUuIDIuMzAwICRccG0kIDIuMTAgJFx0aW1lcyQgMC4xMTUgICAgb3IgIDIuMDYgdG8gMi41NC4NClRoZSBtb2RlbCAgbG9va3MgIHRvIGJlIGdpdmluZyB1c2VmdWwgb3V0cHV0LCBidXQgYXJlIHRoZSBhc3N1bXB0aW9ucyB2YWxpZD8NCg0KDQpUaGUgICBSZXNpZHVhbCBQbG90ICBhYm92ZSBzdWdnZXN0cyBwcm9ibGVtcy4gIFRoZSByZXNpZHVhbHMgc2hvdyB0aGUgbG9uZyBzbG93IHdhbmRlcmluZyBiZWhhdmlvdXIgdGhhdCBpcyB0eXBpY2FsIG9mIHBvc2l0aXZlbHkgIGF1dG9jb3JyZWxhdGVkIGRhdGEuICAgIFRoZSBoaWdoIHBvc2l0aXZlIHJlc2lkdWFscyB0ZW5kIHRvIGJlIGZvbGxvd2VkIGJ5IG1vcmUgcG9zaXRpdmUgcmVzaWR1YWxzLCBhbmQgaGlnaCBuZWdhdGl2ZSByZXNpZHVhbHMgdGVuZCB0byBiZSBmb2xsb3dlZCBieSBmdXJ0aGVyIG5lZ2F0aXZlIG9uZXMuICAgICAgICBUaHVzIGEgY3VydmUgY29ubmVjdGluZyB0aGUgcmVzaWR1YWxzIHRvZ2V0aGVyIGRvZXMgbm90IGNyb3NzIHRoZSB6ZXJvIGxpbmUgKGF4aXMpIHZlcnkgb2Z0ZW4uICAgIFRoZSBpZGVhIGluIHRoZSBsYXN0ICBzZW50ZW5jZSBpcyBhY3R1YWxseSB0aGUgYmFzaXMgZm9yIG91ciBmaXJzdCBwcm9wZXIgIHRlc3Qgb2Ygc2VyaWFsIGNvcnJlbGF0aW9uOiAgdGhlIHJ1bnMgdGVzdC4gDQoNCiMjIEFuYWx5c2lzIG9mIFJ1bnMNCg0KVGhlIHJlc2lkdWFscyBoYXZlIHNpZ25zDQoNCgkrICsgLSArICsgKyDigJMg4oCTIOKAkyDigJMg4oCTIOKAkyDigJMg4oCTIOKAkyArICsgKyArICsgKwkgDQoJDQpUaGF0IGlzLCB0aGVyZSBhcmUgZml2ZSDigJxydW5z4oCdIG9mIHJlc2lkdWFscyAuICANCg0KV2UgY2FuIHVzZSB0aGUgbnVtYmVyIG9mIHJ1bnMgYXMgYSB0ZXN0IGZvciByYW5kb21uZXNzLiAgU3VwcG9zZSB0aGVyZSBhcmUgICRuXzEkICBwb3NpdGl2ZSByZXNpZHVhbHMgYW5kICAkbl8yJCAgbmVnYXRpdmUgcmVzaWR1YWxzLg0KDQpJZiB3ZSBhc3N1bWUgdGhlICtzIGFuZCDigJNzIG9jY3VyIGluIHJhbmRvbSBvcmRlciwgYSBiaXQgb2YgbWF0aGVtYXRpY2FsIHRoZW9yeSBjYW4gZ2l2ZSB1cyB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9yIHJ1bnMsIGFuZCBhbHNvIGEgdGhlb3JldGljYWwgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciB0aGUgbnVtYmVyIG9mIHJ1bnMuICAgV2UgKG9yIHJhdGhlciB0aGUgY29tcHV0ZXIpIGNhbiBjb21wYXJlIHRoZSBvYnNlcnZlZCBudW1iZXIgb2YgcnVucyB3aXRoIHRoaXMgdGhlb3JldGljYWwgaWRlYWwsIGFuZCBjb21lIHVwIHdpdGggYSBQLXZhbHVlIGZvciB0aGUgZGF0YS4gDQoNClNpbmNlIHRoZSBzb2Z0d2FyZSB3aWxsIGRvIGFsbCB0aGUgY2FsY3VsYXRpb25zIGZvciB1cywgd2Ugd2lsbCBub3QgY29uY2VybiBvdXJzZWx2ZXMgd2l0aCB0aGUgZGV0YWlscyBvZiB0aGUgbWV0aG9kLg0KDQpUaGVuLCBvbiB0aGUgYmFzaXMgb2YgdGhlIFAtdmFsdWUsICB3ZSBjYW4gZGVjaWRlIHdoZXRoZXIgdGhlIG51bGwgaHlwb3RoZXNpcyANCg0KJEhfMCQ6IHJlc2lkdWFscyBhcmUgcmFuZG9tDQoNCiBpcyBpbmRlZWQgdGVuYWJsZSwgb3Igd2hldGhlciBpdCBtdXN0IGJlIHJlamVjdGVkLiAgSWYgcmVqZWN0ZWQsIHRoZW4gd2UgY29uY2x1ZGUJICAgICAgICAgICAgICAgICAgDQokSF8xJDogcmVzaWR1YWxzIGFyZSBjb3JyZWxhdGVkLg0KQW4gZXhhbXBsZSBvZiB0aGUgY2FsY3VsYXRpb24gZm9sbG93cyAodGhpcyBuZWVkcyBsb2FkaW5nIG9mIHRoZSBsaWJyYXJ5IERlc2NUb29scyAgKS4gDQoNCmBgYHtyIHJ1bnMgdGVzdH0NCmxpYnJhcnkoRGVzY1Rvb2xzKQ0KUnVuc1Rlc3QocmVzaWR1YWxzKE1vbmV5U3RvY2subG0xKSkNCmBgYA0KDQojIyBEdXJiaW4tV2F0c29uIFRlc3QNCg0KQW4gYWx0ZXJuYXRpdmUgKG1vcmUgcG93ZXJmdWwpIGFwcHJvYWNoIGlzIHRoZSBEdXJiaW4tV2F0c29uIHRlc3QuICAgIEFnYWluIHRoaXMgdGVzdCBpcyBiYXNlZCBvbiB0aGUgc2FtcGxlIHJlc2lkdWFscyAgICAkZV90JCAgZnJvbSB0aGUgbGluZWFyIG1vZGVsLiAgDQogICAgDQpUaGUgaWRlYSBpcyB0aGF0IGlmIHdlIGhhdmUgcG9zaXRpdmUgYXV0b2NvcnJlbGF0aW9uLCAgIHRoZSAgcmVzaWR1YWwgYXQgdGltZSAgdCB3aWxsIG9mdGVuIGJlIHNpbWlsYXIgKGF0IGxlYXN0IGluIHNpZ24pICB0byB0aGUgcmVzaWR1YWwgYXQgdGltZSB0LTEuICAgDQoNClNvIGlmIHdlIHN1YnRyYWN0ICAkZV90IOKAkyBlX3t0LTF9JCAgIHRoZW4gIHdlIHNob3VsZCBnZXQgYSBudW1iZXIgd2hpY2ggaXMgc21hbGwgY29tcGFyZWQgdG8gdGhlIGF2ZXJhZ2UgcmVzaWR1YWwuICAgIFRoaXMgaXMgdGhlIGJhc2lzIG9mIHRoZSB0ZXN0Lg0KDQpUaGUgYWN0dWFsIGZvcm11bGEgZm9yIHRoZSB0ZXN0IHN0YXRpc3RpYyBpcyANCm5vdCBleGFtaW5hYmxlLiAgICANCg0KYGBge3IgZHd0ZXN0fQ0KbGlicmFyeShsbXRlc3QpDQpkd3Rlc3QoTW9uZXlTdG9jay5sbTEsYWx0ZXJuYXRpdmU9ImdyZWF0ZXIiKSAgICAjb3RoZXIgYWx0ZXJuYXRpdmVzIGFyZSAidHdvLnNpZGVkIiwgImxlc3MiDQpgYGANCg0KVGhlIHNtYWxsIFAtdmFsdWUgaW5kaWNhdGVzIHRoYXQgd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgDQokSF8wJDogbm8gYXV0b2NvcnJlbGF0aW9uLCANCmluIGZhdm91ciBvZiB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyANCiRIXzEkOiBwb3NpdGl2ZSBhdXRvY29ycmVsYXRpb24uIA0KDQojIyBXaGF0IENhbiBXZSBEbyBBYm91dCBTZXJpYWwgQ29ycmVsYXRpb24/DQoNCi0gIElmIHRoZSBzZXJpZXMgaXMgcmVhc29uYWJseSBsb25nLCB0aGVuIHdlIGNhbiBzaGlmdCB0byB0aGUgVGltZSBTZXJpZXMgcGFyYWRpZ20gb2YgYW5hbHlzaXMuICAgVGhpcyBpcyBwb3NzaWJseSB0aGUgYmVzdCB3YXkuIA0KDQotICBGb3Igc2hvcnQgc2VyaWVzIGFuZCBzaW1wbGUgcmVncmVzc2lvbi10eXBlIHByb2JsZW1zLCB3ZSBjYW4gdXNlIGEgdHJhbnNmb3JtYXRpb24gbWV0aG9kIGNhbGxlZCB0aGUgQ29jaHJhbmUtT3JjdXR0IG1ldGhvZC4gICANCg0KIyMjIENvY2hyYW5lLU9yY3V0dCBtZXRob2QgIChkZXRhaWxzIGNhbiBiZSBvbWl0dGVkIGByIGx1YnJpZGF0ZTo6eWVhcihsdWJyaWRhdGU6Om5vdygpKWApDQoNClRoZSBmb2xsb3dpbmcgbWV0aG9kIGNhbiBiZSBhcHBsaWVkIHRvIG1vZGVscyB3aXRoIG1vcmUgdGhhbiBvbmUgcHJlZGljdG9yIHZhcmlhYmxlLiANCg0KU3VwcG9zZSB0aGUgZXJyb3JzIGluIHRoZSBtb2RlbCANCiQkIFlfdCA9IFxhbHBoYSArIFxiZXRhIFhfdCArIFx2YXJlcHNpbG9uX3QkJA0KDQphcmUgQVIoMSkgIGkuZS4gIGEgKmZpcnN0LW9yZGVyIGF1dG9yZWdyZXNzaXZlIHNlcmllcyoNCg0KJCRcdmFyZXBzaWxvbl90ID0gXHBoaSBcdmFyZXBzaWxvbl97dC0xfSArIFxldGFfdCQkDQoNClRoaXMgcmVwcmVzZW50cyB0aGF0IHRoZSBlcnJvcnMgICRcdmFyZXBzaWxvbl90JCAgYXQgb25lIHRpbWUgcG9pbnQgJHQkICDigJxyZW1lbWJlcuKAnSB3aGVyZSB0aGV5IHdlcmUgdGhlIHByZXZpb3VzIHRpbWUgcG9pbnQsICAkXHZhcmVwc2lsb25fe3QtMX0kLCAgYnV0IHRoZW4gdGhlcmUgaXMgYW4gYWRkaXRpb25hbCBpbmRlcGVuZGVudCBlcnJvciBjb21wb25lbnQgICRcZXRhX3QkICAgc3BlY2lmaWMgdG8gdGhhdCB0aW1lIHBvaW50LiAgICAgDQooSW5kZXBlbmRlbnQgZXNzZW50aWFsbHkgbWVhbnMgd2UgY2Fu4oCZdCBwcmVkaWN0IGFueSBzcGVjaWZpYyBjb21wb25lbnQgZnJvbSBhbnkgcHJldmlvdXMgY29tcG9uZW50LikNCg0KVGhlIG11bHRpcGxpZXIgJFxwaGkkIGlzIGEgbnVtYmVyIGJldHdlZW4gIC0xIGFuZCArMSwgIHRoYXQgZW5zdXJlcyB0aGF0IHRoZSBlZmZlY3Qgb2YgcHJldmlvdXMgeWVhcnMgZ3JhZHVhbGx5IGRpZXMgb3V0LCBzbyB0aGF0IHRoZSBzZXJpZXMgc2hvdWxkIGV2ZW50dWFsbHkgcmV0dXJuIHRvIGFyb3VuZCB0aGUgbG9uZy10ZXJtIHRyZW5kLiAgICAgIEl0IHR1cm5zIG91dCB0aGF0ICRccGhpJCBlcXVhbHMgdGhlIGF1dG9jb3JyZWxhdGlvbiBjb2VmZmljaWVudCwgIA0KJCRccGhpID0gXG1ib3h7Q29ycn0oWV90LCBZX3t0LTF9KSAgPSBcbWJveHtDb3JyfSggXHZhcmVwc2lsb25fdCxcdmFyZXBzaWxvbl97dC0xfSl+LiQkIA0KDQpOb3cgc3VwcG9zZSB3ZSBsZXQgICR5X3ReKj0geV90IC0gXHBoaSB5X3t0LTF9JCAgICBhbmQgJHhfdF4qID0geF90IC0gXHBoaSB4X3t0LTF9JC4gICANCk5vdyAgDQoNCiQkeV90XiogPSAoXGFscGhhICsgXGJldGEgWF90ICsgXHZhcmVwc2lsb25fdCkgLSBccGhpKCBcYWxwaGEgKyBcYmV0YSBYX3t0LTF9ICsgXHZhcmVwc2lsb25fe3QtMX0pJCQNCiQkPSAgXGFscGhhKDEtXHBoaSkgKyBcYmV0YSAoeF90LVxwaGkgeF97dC0xfSkgKyAgKFx2YXJlcHNpbG9uX3QgLSBccGhpIFx2YXJlcHNpbG9uX3t0LTF9KSA9ICBcYWxwaGFeKiArIFxiZXRhXiogeF90XiogKyBcZXRhX3Qgfn5+fiAoKikkJA0Kd2hlcmUgICRcYWxwaGFeKiA9IFxhbHBoYSgxLVxwaGkpJCwgJFxiZXRhXiogPSBcYmV0YSQgICAgICAgIGFuZCB0aGUgZXJyb3JzICAkXGV0YV90JCAgYXJlIHVuY29ycmVsYXRlZCwgc28gdGhhdCB0aGUgbW9kZWwgICgqKSAgc2F0aXNmaWVzIHRoZSBnZW5lcmFsIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucy4NCg0KSG93ZXZlciAkXHBoaSQgaXMgbm90IGtub3duLiAgU28gd2UgbmVlZCB0byBwbHVnIGluIGFuIGVzdGltYXRlLCB3aGljaCB3ZSBjYW4gZ2V0IGZyb20gVGltZSBTZXJpZXMgQW5hbHlzaXMgb3IgdGhlIER1cmJpbi1XYXRzb24gdGVzdC4gV2UgY2FuIGZpdCB0aGUgIG1vZGVsLCB0aGVuLCB1c2luZyB0aGUgQ29jaHJhbmUtT3JjdXR0IEl0ZXJhdGl2ZSBNZXRob2QuICBUaGUgc3RlcHMgYXJlOg0KDQoxLiBDYWxjdWxhdGUgICRcYWxwaGEkIGFuZCAkXGJldGEkICBieSBvcmRpbmFyeSBsZWFzdCBzcXVhcmVzLg0KDQoyLiBDYWxjdWxhdGUgdGhlIHJlc2lkdWFscyAkZV90JCwgIGFuZCBmcm9tIHRoZXNlIGVzdGltYXRlICRccmhvJC4gIA0KDQozLglGaXQgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgKCopICBieSBsZWFzdCBzcXVhcmVzLCANCnVzaW5nIHRyYW5zZm9ybWVkIHZhcmlhYmxlcyAkeV4qJCAgYW5kICR4XiokLiANCg0KRXN0aW1hdGUgJFxhbHBoYV4qJCAgYW5kICRcYmV0YV4qJC4gDQoNCjQuIENvbXB1dGUgcmVzaWR1YWxzIGFuZCBleGFtaW5lIGFnYWluIGZvciBhdXRvY29ycmVsYXRpb24uICBJZiB0aGVyZSBpcyBub25lLCB0aGVuIHN0b3A7ICBpZiB0aGVyZSBpcyBzdGlsbCBhdXRvY29ycmVsYXRpb24gdGhlbiByZXBlYXQgZnJvbSBzdGVwIDIgdXNpbmcgcmVzaWR1YWxzIGZyb20gc3RlcCAzLiANCg0KSW4gcHJhY3RpY2UgQ2hhdHRlcmplZSBhbmQgUHJpY2UgYWR2aXNlIHRoYXQgaWYgdGhlIG9uZS1zdGVwIHByb2NlZHVyZSBkb2VzbuKAmXQgcmVtb3ZlIHRoZSBhdXRvY29ycmVsYXRpb24gdGhlbiBvbmUgc2hvdWxkIGxvb2sgZm9yIGFsdGVybmF0aXZlIG1ldGhvZHMsIHNpbmNlIGZ1cnRoZXIgaXRlcmF0aW9uIGlzIG5vdCBsaWtlbHkgdG8gZ2l2ZSBtdWNoIGltcHJvdmVtZW50Lg0KDQojIyMgRXhhbXBsZQ0KDQpGb3IgdGhlIE1vbmV5U3RvY2sgcHJvYmxlbSwgJHI9MC43NTEkIGJ5IHRoZSBkd3Qgb3V0cHV0LiBXZSB1c2UgdGhpcyBhcyBhbiBlc3RpbWF0ZSBvZiAkXHBoaSQuIA0KDQpgYGB7ciBjb2NocmFuZX0NCnI9IDAuNzUxDQp5PU1vbmV5U3RvY2skQ29uc0V4cA0KeVN0YXIgPSB5WzI6MjBdIC0gcip5WzE6MTldDQp4ID0gTW9uZXlTdG9jayRNb25leVN0aw0KeFN0YXIgPSB4WzI6MjBdIC0gcip4WzE6MTldDQpsbXN0YXI9IGxtKHlTdGFyIH4geFN0YXIpDQoNCmR3dGVzdChsbXN0YXIpDQpzdW1tYXJ5KGxtc3RhcikNCmNvbmZpbnQobG1zdGFyKQ0KYGBgDQoNClRoZSB0cmFuc2Zvcm1lZCBzZXJpZXMgaGFzIGEgbm9uLXNpZ25pZmljYW50IER1cmJpbi1XYXRzb24gdGVzdCwgc28gaXQgbG9va3MgdGhhdCB0aGUgZmlyc3Qtb3JkZXIgYXV0b2NvcnJlbGF0aW9uIGhhcyBiZWVuIGZpeGVkLiANCg0KVGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyBzaG93IHRoYXQgJFxiZXRhJCBpcyBpbiB0aGUgd2lkZXIgaW50ZXJ2YWwgKDIuMCwgMy4yOSkuIFNvIG91ciByZWFsIGtub3dsZWRnZSBvZiAkXGJldGEkIGlzIG11Y2ggbGVzcyBwcmVjaXNlIHRoYW4gdGhlIGVhcmxpZXIgbWlzbGVhZGluZyByZWdyZXNzaW9uIG1vZGVsIGhhdmUgdG9sZCB1cy4gDQoNCiMjIyBDb25jbHVzaW9uICANCg0KVGhlIGFib3ZlIGV4YW1wbGUgaWxsdXN0cmF0ZXMgdGhlIHBvaW50IG1hZGUgZWFybGllciwgdGhhdCBpZ25vcmluZyB0aGUgYXV0b2NvcnJlbGF0aW9uIGNhbiBsZWFkIHRvIG1pc2xlYWRpbmcgcmVzdWx0cy4NCg0KSW4gcGFydGljdWxhciwgcG9zaXRpdmUgYXV0b2NvcnJlbGF0aW9uIGltcGxpZXMgdGhhdCB0aGUgdXN1YWwgKGluZGVwZW5kZW5jZSBtb2RlbCkgc3RhbmRhcmQgZXJyb3JzIG9mIHRoZSBzbG9wZXMgYXJlIHRvbyBzbWFsbCwgIHdoaWxlIG5lZ2F0aXZlIGF1dG9jb3JyZWxhdGlvbiBpbXBsaWVzIHRoYXQgdGhlIHN0YW5kYXJkIGVycm9ycyBpbiB0aGUgaW5kZXBlbmRlbmNlIG1vZGVsIGFyZSB0b28gYmlnLiANCg==