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:

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")

unlabelled

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

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()
Year Quarter ConsExp MoneyStk Year.Q
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
pairs(MoneyStock[3:5])

unlabelled

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)

unlabelled

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?

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:

  1. Calculate \(\alpha\) and \(\beta\) by ordinary least squares.

  2. Calculate the residuals \(e_t\), and from these estimate \(\rho\).

  3. Fit the regression model (*) by least squares, using transformed variables \(y^*\) and \(x^*\).

Estimate \(\alpha^*\) and \(\beta^*\).

  1. 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
summary(lmstar)

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
confint(lmstar)
                 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==