Setup

# Clear the environment and the console
rm(list = ls()); cat("\f")

#----------------------------#
# Install required libraries #
#----------------------------#
packages <- c("ggplot2", "ggpubr", "readxl", "readr", "dplyr", "tidyr", "psych", "stringr",
              "lubridate", "knitr", "outliers", "MVN", "TSA", "tseries", "lmtest", "FSAdata",
              "forecast", "matrixcalc", "car", "corpcor", "scales", "QuantPsyc",
              "urca", "rugarch", "fGarch", "tswge",
              "imputeTS", "shiny", "coda", "rjags", "runjags", "ks", "epiDisplay", "fastDummies")
# Install any packages not already installed
installed_packages <- packages %in% rownames(installed.packages())
if (any(installed_packages == FALSE)) { install.packages(packages[!installed_packages]) }
#-------------------------#
# Load libraries          #
#-------------------------#
invisible(lapply(packages, library, character.only = TRUE))
#-------------------------#
# Clear the environment and the console
rm(list = ls()); cat("\f")

Required packages

library(TSA)
library(readr)
library(stringr)
library(dplyr)
library(lubridate)

Introduction

Aims/Objectives

This report summarises the analysis of the Antarctica land ice mass series, and the process followed to identify suitable ARIMA(p,d,q) models as part of Assignment 2 for Time Series Analysis. The report covers analysis of the dataset, addressing non-stationarity, and using model specification tools to suggest possible ARIMA models.

Methodology

Creating a function for producing ACF and PACF plots

To reduce repetition of R codes, a function was created to produce ACF and PACF plots.

acf_pacf <- function(ts_object, plot_note){
 # Produce ACF and PACF plots for a time series object.
 # Optional: specify a plot note (as a string) to improve plot titles.
 # Example: acf_pacf(price_ts, "Box-Cox transformed, first differenced price series.")
 par(mfrow=c(1,2))
 if (missing(plot_note)) {
 acf(ts_object, main ="ACF plot", lag.max = min(c(length(ts_object), 50)))
 pacf(ts_object, main ="PACF plot", lag.max = min(c(length(ts_object), 50)))
 } else {
 acf(ts_object, main=paste("ACF plot of", plot_note), lag.max = min(c(length(ts_object),50)))
 pacf(ts_object, main=paste("PACF plot of", plot_note), lag.max = min(c(length(ts_object),50)))
 }
 par(mfrow=c(1,1))
}

Retrieving the data

A summary of the Antarctica land ice mass data imported into R showed the imported dataset had 19 observations, including a minimum date of 2002 and a maximum date of 2020, the same as the original data file.

ice <- read_csv("assignment2Data2022.csv", col_names = TRUE)
colnames(ice) <- c("Year", "Annual_ice_mass")
describe(ice, fast=TRUE, quant=c(.25, .5, .75))

The data summary also showed that between 2002 and 2020, the mean annual change in land ice mass relative to 2001 was -1,063.77 billion metric tons. Considering the timeframe for the series was 19 years, it was shocking to note that the ‘Annual_ice_mass’ had a range of 2,531.51 billion metric tons, more than double the mean annual change and indicative of a very large change in land ice mass over the course of less than 20 years.

As the Antarctic land Ice dataset had been stored as a dataframe when it was first imported into R, it was converted to a time series object with a frequency of 1 as each observation was an annual change.

ice_ts <- ts(ice$Annual_ice_mass, start = 2002, frequency = 1)
ice_ts
Time Series:
Start = 2002 
End = 2020 
Frequency = 1 
 [1]    -7.546667  -115.186364  -262.302500  -228.376667  -129.987500  -316.476667
 [7]  -587.155833  -562.316667  -840.778333  -938.991111 -1073.690909 -1283.981111
[13] -1494.724444 -1846.245556 -1768.321111 -1801.952000 -2146.672000 -2267.945000
[19] -2539.055000

Exploring the data

The Antarctic land ice series was plotted to visually inspect the series for the 5 key time series traits; trend, seasonality, changing variance, behaviour, and change point/intervention.

plot(ice_ts, type="o", xlab="Year",
 ylab="Change in Antarctica land ice mass, relative to 2001 (billion metric tons)",
 main="Time series plot of the NASA Annual Antarctica land ice mass series.")

Figure 1: Time series plot of the Annual Antarctica land ice mass series.

The time series plot of the Antarctica land ice mass series showed the following time series traits;

  1. Trend

From the time series plot in Figure 1, it was clear the series had a downward, linear trend, indicating that the Antarctic land ice mass was getting smaller relative to 2001 as time progressed.

  1. Seasonality

There were no clear signs of seasonality in Figure 1.

  1. Changing variance

There were no clear signs of changing variance in Figure 1.

  1. Behaviour

The time series plot in Figure 1 exhibited autoregressive (AR) behaviour, with many successive points. There were no clear fluctuations in the series, so there was no evidence of moving average (MA) behaviour.

  1. Change point

There was no clear evidence of a change point (intervention) in the Antarctica land ice mass series as the series appeared to exhibit the same trend and behaviour, with no sudden changes. This was not surprising considering the factors that would affect Antarctic land ice mass (e.g., climate change) do not change substantially from year to year. It would take a very large intervention (e.g., a meteor strike) to change the behaviour of the series.

The points in Figure 1 show evidence of succeeding measurements being related to one another, and Figure 2 highlights this relationship more clearly using a scatter plot of neighbouring pairs.

#lag the time series
par(mfrow=c(1,1))
plot(y=ice_ts, x=zlag(ice_ts), 
 ylab="Change in Antarctica land ice mass, relative to 2001 (billion metric tons)", 
 xlab="Change in Antarctica land ice mass in previous year",
 main = "Scatter plot of Change in Antarctica land ice mass in consecutive Years.")

Figure 2: Scatter plot of each Annual Antarctica land ice mass measurement and the measurement taken in the previous year.

# correlation of neighbouring pairs
y = ice_ts # Assign the ice data to y
x = zlag(ice_ts) # Generate first lag of the ice series
index = 2:length(x) # Create an index to get rid of the first NA value in x
cor(y[index],x[index]) # Calculate correlation between numerical values in x and y
[1] 0.985486

The scatter plot in Figure 2 shows a strong, upward trend, indicative of a strong correlation between neighbouring pairs. The plot indicates that small annual changes in Antarctic land ice mass (relative to 2001) tend to be followed by small changes, moderate changes tend to be followed by moderate changes, and large changes tend to be followed by large changes. These observations were supported by the correlation between neighbouring annual land ice mass changes which, at 0.985, indicated a very strong, positive correlation between neighbouring points.

Assessing stationarity

Figure 1 showed a strong, downward, linear trend in the Antarctica ice series, suggesting that the raw Antarctica ice series was non-stationary. As ARIMA models can only be produced using a stationary series, ACF and PACF plotswere produced to assess the series for stationarity.

acf_pacf(ice_ts, "the Antarctica Ice series.")

Figure 3: ACF and PACF plots of the Antarctica land ice mass series.

The ACF plot in Figure 3 showed 3 significant autocorrelation lags and a decaying pattern, indicative of a non-stationary, autoregressive process. There was no evidence of seasonality in the series as there was no clear wave pattern in the ACF lags.

The first partial autocorrelation lag in the PACF plot in Figure 3 was highly significant, while all other lags were not significant, indicative of a non-stationary, autoregressive series. Several unit root tests, including an Augmented Dickey-Fuller test, were also used to assess the series for stationarity, with results shown in Table 4.

adf.test(ice_ts, alternative = c("stationary")) # significant=stationary, doubt range:(0.03 - 0.1)

    Augmented Dickey-Fuller Test

data:  ice_ts
Dickey-Fuller = -2.7141, Lag order = 2, p-value = 0.3004
alternative hypothesis: stationary
pp.test(ice_ts) # significant = stationary

    Phillips-Perron Unit Root Test

data:  ice_ts
Dickey-Fuller Z(alpha) = -5.8754, Truncation lag parameter = 2, p-value = 0.7516
alternative hypothesis: stationary
kpss.test(ice_ts) # significant = non-stationary

    KPSS Test for Level Stationarity

data:  ice_ts
KPSS Level = 0.72818, Truncation lag parameter = 2, p-value = 0.01098

Table 4: Statistical tests for stationarity and normality in the Antarctica land ice mass series.

The null hypothesis under the Augmented Dickey-Fuller test and the Phillips-Perron (PP) test is that the series Is non-stationary. With p-values of 0.30 for the Augmented Dickey-Fuller test, and 0.75 for the PP test, there was insufficient evidence to reject the null hypothesis of both tests and therefore we could conclude that the series was not stationary. This conclusion was supported by results of a KPSS test, which produced a p-value of 0.01, indicating there was sufficient evidence to reject the null hypothesis under the KPSS test that the series was stationary. Finally, a Q-Q plot was produced to assess the raw series for normality, alongside a Shapiro-Wilk test. Although the Q-Q plot in Figure 4 showed deviations from the diagonal in each tail of the series, the Shapiro-Wilk test produced a p-value of 0.147, indicating that the measurements in the Antarctica land ice mass series were approximately normally distributed.

## Normality checks
qqnorm(ice_ts)
qqline(ice_ts, col = 2)

Figure 4: Normal Q-Q plot of the Antarctica land ice mass series.

shapiro.test(ice_ts) # not significant - approximately normal

    Shapiro-Wilk normality test

data:  ice_ts
W = 0.92616, p-value = 0.1471

Table 5: Result of the Shapiro-Wilk test on the raw Antarctica Ice series.

Addressing non-stationarity

Transformation

Although there was no clear evidence of changing variance in Figure 1, a Box-Cox transformation was applied to the series to observe the impact of transformation on the series.

As the series contained negative values (declines in the land ice mass relative to 2001), a constant had to be added to the series to make all values greater than zero before a Box-Cox transformation could be applied. A vector of candidate power transformation values was also required to obtain candidate lambda values for the Box-Cox transformation due to computational limits. Through trial and error, limits of zero and 2 were identified as appropriate power transformation limits for the Box-Cox transformation.

The plot of candidate lambda values for the Box-Cox transformation of the Antarctica land ice mass series can be seen in Figure 5. Table 6 shows the values of the first and third vertical lines from Figure 5 were 0.65 and 1.22, respectively, and the chosen lambda value for the Box-Cox transformation (the middle vertical line in Figure 5) was 0.89.

#BC = BoxCox.ar(ice_ts) # ERROR: data values must be positive.
min(ice_ts) # minimum is -2539.055
[1] -2539.055
# add the minimum to each value in the series, to make all values greater than zero.
ice_ts2 <- ice_ts + abs(min(ice_ts)) + 0.01
BC <- BoxCox.ar(y=ice_ts2, lambda=seq(0, 2, 0.01))

Figure 5: Log likelihood plot for the lambda values in the Box-Cox transformation of the Antarctica land ice mass series.

BC$ci #Values of the first and third vertical lines
[1] 0.65 1.22
# To find the lambda value of the middle vertical line
lambda <- BC$lambda[which(max(BC$loglike) == BC$loglike)]
lambda
[1] 0.89

Table 6: Results for candidate lambda values from the Box-Cox power transformation function.

With an appropriate lambda value identified, the Box-Cox transformation was applied to the Antarctica Ice series and the resultant series was plotted for visual inspection in Figure 6.

# Apply Box-Cox transformation
iceBC <- ((ice_ts2^lambda) - 1) / lambda
plot(iceBC, type="o", xlab="Years", 
 ylab="Change in Antarctica land ice mass, relative to 2001 (billion metric tons)",
 main = "Time series plot of BoxCox transformed Antarctica Ice series.")

Figure 6: Time series plot of the Box-Cox transformed Annual Antarctica land ice mass series.

The time series plot in Figure 6 showed no clear change or improvement in the variation of the series, and the Q-Q plot in Figure 7 still showed deviations from the diagonal at both tails of the series. There was also little change in the result from the Shapiro-Wilk test of the Box-Cox transformed series, shown in Table 7, indicating that values in the series were still approximately normally distributed.

qqnorm(iceBC, main = "Normal Q-Q Plot for the Box-Cox transformed Antarctica Ice series.")
qqline(iceBC, col = 2)

Figure 7: Normal Q-Q Plot for the Box-Cox transformed Antarctica Ice series.

shapiro.test(iceBC)

    Shapiro-Wilk normality test

data:  iceBC
W = 0.92582, p-value = 0.145

Table 7: Results from the Shapiro-Wilk test of the Box-Cox transformed Antarctic Ice series.

Finally, the Augmented Dickey-Fuller test (Table 8) produced a p-value of 0.563, indicating that the Box-Cox transformed Antarctica Ice series was non-stationary.

adf.test(iceBC) # significant = stationary, doubt range: (0.03 - 0.1)

    Augmented Dickey-Fuller Test

data:  iceBC
Dickey-Fuller = -2.0237, Lag order = 2, p-value = 0.5634
alternative hypothesis: stationary

Table 8: Results from the Augmented Dickey-Fuller test of the Box-Cox transformed Antarctic Ice series.

As there was no evidence to suggest the raw Antarctica Ice series exhibited changing variation, and the Box-Cox transformation did not change or improve the normality of the series, the Box-Cox transformation was deemed unnecessary, and the raw series would be used when applying differencing to address non-stationarity.

Differencing

Differencing was applied to the raw Antarctica Ice series to address the trend in the raw series, with the resulting series plotted in Figure 8.

ice_diff <- diff(ice_ts, differences = 1)
par(mar=c(5,6,4,1)+.1) #set plot window margins
plot(ice_diff, type="o", xlab="Year",
 ylab="Change in Antarctica land ice mass, relative to 2001 \n(billion metric tons)",
 main="Time series plot of first differenced Antarctica Ice series.")

Figure 8: Time series plot of first differenced Antarctica Ice series

The time series plot in Figure 8 appeared to exhibit a slight downward trend, indicating that the first differenced series may still be non-stationary. However, the ACF and PACF plots of the first differenced Antarctica Ice series (Figure 9) showed no significant points and no decaying pattern, suggesting the first differenced series may have been stationary.

acf_pacf(ice_diff, "the first differenced \nAntarctica Ice series.")

Figure 9: ACF and PACF plots of the first differenced Antarctica land ice mass series.

To test for stationarity, an Augmented Dickey-Fuller test of the first differenced series was performed, with the test resulting in a p-value of 0.357 which, at the α=0.05 level, indicated that the first differenced Antarctica Ice series was non-stationary.

adf.test(ice_diff)# significant = stationary, doubt range: (0.03 - 0.1)

    Augmented Dickey-Fuller Test

data:  ice_diff
Dickey-Fuller = -2.5664, Lag order = 2, p-value = 0.3566
alternative hypothesis: stationary

Table 9: Result from the Augmented Dickey-Fuller test of the first differenced Antarctic Ice series.

As first differencing had not produced a stationary series, second differencing was applied to the raw Antarctica Ice series, with the resulting series plotted in Figure 10.

ice_diff2 <- diff(ice_ts, differences = 2)
plot(ice_diff2, type="o", xlab="Year",
 ylab="Change in Antarctica land ice mass, relative to 2001 \n(billion metric tons)",
 main="Time series plot of second differenced Antarctica Ice series.")

Figure 10: Time series plot of second differenced Antarctica Ice series.

The second differenced time series in Figure 10 showed no clear trend, suggesting that second differencing may have resulted in a stationary series.

acf_pacf(ice_diff2, "the \nsecond differenced Antarctica Ice series")

Figure 11: ACF and PACF plots of the second differenced Antarctica land ice mass series.

The ACF and PACF plots of the second differenced series (Figure 11) showed a significant PACF lag at the second lag, suggesting the second differenced series may be non-stationary. Supporting this was the Augmented Dickey-Fuller test of the second differenced series (Table 10), which produced a p-value of 0.073, indicating that, at the α=0.05 level, the second differenced series may still have been non-stationary.

However, as the result of the Augmented Dickey-Fuller test was within the “doubt range” of 0.03 to 0.1, additional unit root tests were performed to better evaluate whether second differencing had resulted in a stationary series.

adf.test(ice_diff2)# significant = stationary, doubt range: (0.03 - 0.1)

    Augmented Dickey-Fuller Test

data:  ice_diff2
Dickey-Fuller = -3.438, Lag order = 2, p-value = 0.0725
alternative hypothesis: stationary

Table 10: Results from the Augmented Dickey-Fuller test, Phillips-Perron test, and KPSS test of the second differenced Antarctic Ice series.

A Phillips-Perron Unit Root test and a KPSS test (Table 11) produced p-values of 0.026, and 0.1, respectively, indicating there was sufficient evidence to conclude the second differenced series was stationary.

# p-value is in the doubt range, so refer to additional tests.
pp.test(ice_diff2) # significant = stationary

    Phillips-Perron Unit Root Test

data:  ice_diff2
Dickey-Fuller Z(alpha) = -19.817, Truncation lag parameter = 2, p-value = 0.02604
alternative hypothesis: stationary
kpss.test(ice_diff2) # significant = non-stationary

    KPSS Test for Level Stationarity

data:  ice_diff2
KPSS Level = 0.11554, Truncation lag parameter = 2, p-value = 0.1

Table 11: Results from the Phillips-Perron test, and KPSS test of the second differenced Antarctic Ice series.

As the series appeared stationary in Figure 10, and the Phillips-Perron Unit Root test and KPSS test in Table 11 indicated the second differenced series was stationary, it was concluded that second differencing of the Antarctica Ice series had resulted in a stationary series.

As second differencing the Antarctica Ice series had resulted in a stationary series, it was deemed suitable for use in model specification. All proposed ARIMA(p,d,q) models would have a value of “d” equal to 2, as second differencing had been applied.

Model specification

ACF & PACF plots

The first step in identifying potential models for the Antarctica Ice series was to use ACF and PACF plots to propose values for the orders of autoregression (p) and moving average (q).

acf_pacf(ice_diff2, "the \nsecond differenced Antarctica Ice series")

Figure 12: ACF and PACF plots of the second differenced Antarctica Ice series.

From the PACF plot in Figure 12, the second partial autocorrelation lag was deemed significant, and the first lag was deemed borderline significant, indicating that the value of “p” could be 1 or 2. These values were understandable given autoregressive behaviour was identified in the raw Antarctica Ice series.

There were no clearly significant autocorrelation lags in the ACF plot of the second differenced series. However, the first lag of the ACF plot was deemed borderline significant, and thus the value of “q” was proposed as either 0 or 1.

The resulting proposed models from the ACF and PACF plots were:

  • { ARIMA(1,2,0), ARIMA(2,2,0), ARIMA(1,2,1), ARIMA(2,2,1) }

EACF

The second step in identifying potential models for the Antarctica Ice series involved using the extended ACF function, or EACF. Running the EACF function on the second differenced series with default parameters resulted in an error, which was overcome by specifying the maximum values for AR and MA in the EACF function. The resulting output is shown in Table 12.

# eacf(ice_diff2) #ERROR: requires numeric/complex matrix/vector arguments
# eacf(ice_diff2, ar.max = 5, ma.max = 5) #ERROR: requires numeric/complex matrix/vector arguments
eacf(ice_diff2, ar.max = 4, ma.max = 3)
AR/MA
  0 1 2 3
0 o o o o
1 x x o o
2 o x o o
3 o o o o
4 o o o o

Table 12: EACF plot of the second differenced Antarctic Ice series.

The most top-left point in the EACF plot was selected as (0,0), and the models proposed using the EACF plot were:

  • { ARIMA(0,2,0), ARIMA(0,2,1) }

It should be noted that the ARIMA(0,2,0) model will have no coefficients. Trend modelling would be used to see if this model captures the autocorrelation in the series.

BIC

The third step in identifying potential models for the Antarctica Ice series was to use the Bayesian Information Criterion, or “BIC”, to propose values for “p” and “q”.

The BIC plot was first produced using values of 10 for ‘nma’ and ‘nar’ however, this resulted in an error. As it was known from the ACF, PAC, and EACF plots that the orders of “p” and “q” would likely be small, the values of ‘nma’ and ‘nar’ were reduced to 5, and then to 3, with the resulting BIC plots shown in Figure 13 and Figure 14, respectively.

#res = armasubsets(y=ice_diff2, nar=10, nma=10, y.name='p', ar.method='ols') #ERRORs
#plot(res) #ERRORs
## evidence so far suggests p and q will be small, so try with a reduced value for 'nma' and 'nar'.
res2 = armasubsets(y=ice_diff2, nar=5, nma=5, y.name='p', ar.method='ols')
plot(res2) # algorithm hits a BIC value that was NaN

Figure 13: BIC plot of the second differenced Antarctic Ice series, using ‘nar’ and ‘nma’ values of 5.

# evidence so far suggests p and q will be small, so try with a further reduced value for 'nma' and 'nar'.
res3 = armasubsets(y=ice_diff2, nar=3, nma=3, y.name='p', ar.method='ols')
plot(res3) # algorithm hits a BIC value that was inf

Figure 14: BIC plot of the second differenced Antarctic Ice series, using ‘nar’ and ‘nma’ values of 3.

The BIC plot with values of 3 for ‘nar’ and ‘nma’ (Figure 14) proposed models that were in-line with the ACF, PACF, and EACF plots, so it was selected for use in proposing models for the second differenced series.

The model proposals from the BIC model specification method were:

  • { ARIMA(1,2,1), ARIMA(2,2,1), ARIMA(3,2,1), ARIMA(1,2,0), ARIMA(2,2,0) }

Results

Final set of possible models

The final set of possible models for the Antarctica land ice mass series was:

  • { ARIMA(1,2,0),
  • ARIMA(2,2,0),
  • ARIMA(1,2,1),
  • ARIMA(2,2,1),
  • ARIMA(0,2,0),
  • ARIMA(0,2,1),
  • ARIMA(3,2,1) }

Most of these models made sense in the context of the data exploration, which identified autoregressive behaviour in the raw Antarctica Ice series (i.e., “p” would likely be non-zero) and no clear evidence of moving average behaviour (i.e., “q” would likely be low or zero). It should be noted that the ARIMA(0,2,0) model will have no coefficients, and trend modelling would be required to see if this model captures the autocorrelation in the series.

The following models were proposed by more than one model specification method;

  • { ARIMA(1,2,0),
  • ARIMA(2,2,0),
  • ARIMA(1,2,1),
  • ARIMA(2,2,1) }

Further testing, including diagnostic checking, would be required to identify the optimal model from the set of proposed models.

Summary & Conclusion

The objective of the analysis and model specification conducted was to understand the Antarctica land ice mass dataset, and to propose a set of possible ARIMA(p,d,q) models for the series.

Exploration of the Antarctica land ice mass dataset revealed a large range and a mean change of -1,063.77 billion metric tons, relative to the ice mass in 2001.

Analysis of the Antarctica Ice series identified that the series exhibited a clear downward trend and autoregressive behaviour (successive points), with no clear signs of seasonality, changing variance, or a change point. A high correlation between neighbouring points was also identified, which aligned with the autocorrelation behaviour observed when the series was plotted.

ACF and PACF plots of the Antarctica Ice series identified significant autocorrelation lags, and a single, very significant partial autocorrelation lag, indicative of a non-stationary series. Further tests confirmed that the raw series was not stationary, but that the measurements in the series were approximately normally distributed.

Although the series did not exhibit changing variance, a Box-Cox transformation was applied to the series to observe its impact. Visual inspection, a Shapiro-Wilk test, and a unit root test identified that the Box-Cox transformation did not change the series much, so the transformation was deemed unnecessary.

Differencing was then applied to the raw series to address the trend in the series. Visual inspection and a unit root test confirmed that first differencing did not overcome the non-stationarity, and so second differencing was applied. Although the Augmented Dickey-Fuller test of the second differenced series suggested the series was still non-stationary, visual inspection, and further unit root tests (PP and KPSS) confirmed that second differencing had made the series stationary. As such, the second differenced series was chosen for use in model specification.

ACF, PACF, EACF and BIC model specification tools were used to proposed suitable ARIMA(p,d,q) models for the Antarctica Ice series, with the final set of proposed models containing 7 ARIMA(p,d,q) models;

{ ARIMA(1,2,0), ARIMA(2,2,0), ARIMA(1,2,1), ARIMA(2,2,1), ARIMA(0,2,0), ARIMA(0,2,1), ARIMA(3,2,1) }.



LS0tDQp0aXRsZTogIlRpbWUgU2VyaWVzIEFuYWx5c2lzIC0gQXNzaWdubWVudCAyIg0KYXV0aG9yOiAiSmFtZXMgQW5ndXMiDQpzdWJ0aXRsZTogIlRpbWUgU2VyaWVzIEFuYWx5c2lzIG9mIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCiMgU2V0IHdvcmtpbmcgZGlyZWN0b3J5IGZvciBwcm9qZWN0ICMNCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gbm9ybWFsaXplUGF0aCgiQzovVXNlcnMvamFtZXMvT25lRHJpdmUvRGVza3RvcC9VbmkgU3R1ZGllcy9STUlULzIwMjIgU2VtZXN0ZXIgMS9UaW1lIFNlcmllcyBBbmFseXNpcyAtIE1BVEgxMzE4L0Fzc2lnbm1lbnQgMiIpKQ0KIyBTd2l0Y2ggb2ZmIHdhcm5pbmdzIGFuZCBtZXNzYWdlcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCiMgU2V0dXANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQojIENsZWFyIHRoZSBlbnZpcm9ubWVudCBhbmQgdGhlIGNvbnNvbGUNCnJtKGxpc3QgPSBscygpKTsgY2F0KCJcZiIpDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMNCiMgSW5zdGFsbCByZXF1aXJlZCBsaWJyYXJpZXMgIw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jDQpwYWNrYWdlcyA8LSBjKCJnZ3Bsb3QyIiwgImdncHViciIsICJyZWFkeGwiLCAicmVhZHIiLCAiZHBseXIiLCAidGlkeXIiLCAicHN5Y2giLCAic3RyaW5nciIsDQogICAgICAgICAgICAgICJsdWJyaWRhdGUiLCAia25pdHIiLCAib3V0bGllcnMiLCAiTVZOIiwgIlRTQSIsICJ0c2VyaWVzIiwgImxtdGVzdCIsICJGU0FkYXRhIiwNCiAgICAgICAgICAgICAgImZvcmVjYXN0IiwgIm1hdHJpeGNhbGMiLCAiY2FyIiwgImNvcnBjb3IiLCAic2NhbGVzIiwgIlF1YW50UHN5YyIsDQogICAgICAgICAgICAgICJ1cmNhIiwgInJ1Z2FyY2giLCAiZkdhcmNoIiwgInRzd2dlIiwNCiAgICAgICAgICAgICAgImltcHV0ZVRTIiwgInNoaW55IiwgImNvZGEiLCAicmphZ3MiLCAicnVuamFncyIsICJrcyIsICJlcGlEaXNwbGF5IiwgImZhc3REdW1taWVzIikNCiMgSW5zdGFsbCBhbnkgcGFja2FnZXMgbm90IGFscmVhZHkgaW5zdGFsbGVkDQppbnN0YWxsZWRfcGFja2FnZXMgPC0gcGFja2FnZXMgJWluJSByb3duYW1lcyhpbnN0YWxsZWQucGFja2FnZXMoKSkNCmlmIChhbnkoaW5zdGFsbGVkX3BhY2thZ2VzID09IEZBTFNFKSkgeyBpbnN0YWxsLnBhY2thZ2VzKHBhY2thZ2VzWyFpbnN0YWxsZWRfcGFja2FnZXNdKSB9DQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSMNCiMgTG9hZCBsaWJyYXJpZXMgICAgICAgICAgIw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jDQppbnZpc2libGUobGFwcGx5KHBhY2thZ2VzLCBsaWJyYXJ5LCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKQ0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0jDQojIENsZWFyIHRoZSBlbnZpcm9ubWVudCBhbmQgdGhlIGNvbnNvbGUNCnJtKGxpc3QgPSBscygpKTsgY2F0KCJcZiIpDQpgYGANCiMgUmVxdWlyZWQgcGFja2FnZXMgDQpgYGB7cn0NCmxpYnJhcnkoVFNBKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmBgYA0KDQojIEludHJvZHVjdGlvbiANCiMjIEFpbXMvT2JqZWN0aXZlcw0KVGhpcyByZXBvcnQgc3VtbWFyaXNlcyB0aGUgYW5hbHlzaXMgb2YgdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMsIGFuZCB0aGUgcHJvY2VzcyBmb2xsb3dlZCB0byBpZGVudGlmeSBzdWl0YWJsZSBBUklNQShwLGQscSkgbW9kZWxzIGFzIHBhcnQgb2YgQXNzaWdubWVudCAyIGZvciBUaW1lIFNlcmllcyBBbmFseXNpcy4gVGhlIHJlcG9ydCBjb3ZlcnMgYW5hbHlzaXMgb2YgdGhlIGRhdGFzZXQsIGFkZHJlc3Npbmcgbm9uLXN0YXRpb25hcml0eSwgYW5kIHVzaW5nIG1vZGVsIHNwZWNpZmljYXRpb24gdG9vbHMgdG8gc3VnZ2VzdCBwb3NzaWJsZSBBUklNQSBtb2RlbHMuDQoNCg0KIyBNZXRob2RvbG9neSANCiMjIENyZWF0aW5nIGEgZnVuY3Rpb24gZm9yIHByb2R1Y2luZyBBQ0YgYW5kIFBBQ0YgcGxvdHMNClRvIHJlZHVjZSByZXBldGl0aW9uIG9mIFIgY29kZXMsIGEgZnVuY3Rpb24gd2FzIGNyZWF0ZWQgdG8gcHJvZHVjZSBBQ0YgYW5kIFBBQ0YgcGxvdHMuDQoNCmBgYHtyfQ0KYWNmX3BhY2YgPC0gZnVuY3Rpb24odHNfb2JqZWN0LCBwbG90X25vdGUpew0KICMgUHJvZHVjZSBBQ0YgYW5kIFBBQ0YgcGxvdHMgZm9yIGEgdGltZSBzZXJpZXMgb2JqZWN0Lg0KICMgT3B0aW9uYWw6IHNwZWNpZnkgYSBwbG90IG5vdGUgKGFzIGEgc3RyaW5nKSB0byBpbXByb3ZlIHBsb3QgdGl0bGVzLg0KICMgRXhhbXBsZTogYWNmX3BhY2YocHJpY2VfdHMsICJCb3gtQ294IHRyYW5zZm9ybWVkLCBmaXJzdCBkaWZmZXJlbmNlZCBwcmljZSBzZXJpZXMuIikNCiBwYXIobWZyb3c9YygxLDIpKQ0KIGlmIChtaXNzaW5nKHBsb3Rfbm90ZSkpIHsNCiBhY2YodHNfb2JqZWN0LCBtYWluID0iQUNGIHBsb3QiLCBsYWcubWF4ID0gbWluKGMobGVuZ3RoKHRzX29iamVjdCksIDUwKSkpDQogcGFjZih0c19vYmplY3QsIG1haW4gPSJQQUNGIHBsb3QiLCBsYWcubWF4ID0gbWluKGMobGVuZ3RoKHRzX29iamVjdCksIDUwKSkpDQogfSBlbHNlIHsNCiBhY2YodHNfb2JqZWN0LCBtYWluPXBhc3RlKCJBQ0YgcGxvdCBvZiIsIHBsb3Rfbm90ZSksIGxhZy5tYXggPSBtaW4oYyhsZW5ndGgodHNfb2JqZWN0KSw1MCkpKQ0KIHBhY2YodHNfb2JqZWN0LCBtYWluPXBhc3RlKCJQQUNGIHBsb3Qgb2YiLCBwbG90X25vdGUpLCBsYWcubWF4ID0gbWluKGMobGVuZ3RoKHRzX29iamVjdCksNTApKSkNCiB9DQogcGFyKG1mcm93PWMoMSwxKSkNCn0NCmBgYA0KDQojIyBSZXRyaWV2aW5nIHRoZSBkYXRhDQpBIHN1bW1hcnkgb2YgdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBkYXRhIGltcG9ydGVkIGludG8gUiBzaG93ZWQgdGhlIGltcG9ydGVkIGRhdGFzZXQgaGFkIDE5IG9ic2VydmF0aW9ucywgaW5jbHVkaW5nIGEgbWluaW11bSBkYXRlIG9mIDIwMDIgYW5kIGEgbWF4aW11bSBkYXRlIG9mIDIwMjAsIHRoZSBzYW1lIGFzIHRoZSBvcmlnaW5hbCBkYXRhIGZpbGUuDQoNCmBgYHtyfQ0KaWNlIDwtIHJlYWRfY3N2KCJhc3NpZ25tZW50MkRhdGEyMDIyLmNzdiIsIGNvbF9uYW1lcyA9IFRSVUUpDQpjb2xuYW1lcyhpY2UpIDwtIGMoIlllYXIiLCAiQW5udWFsX2ljZV9tYXNzIikNCmRlc2NyaWJlKGljZSwgZmFzdD1UUlVFLCBxdWFudD1jKC4yNSwgLjUsIC43NSkpDQpgYGANCg0KVGhlIGRhdGEgc3VtbWFyeSBhbHNvIHNob3dlZCB0aGF0IGJldHdlZW4gMjAwMiBhbmQgMjAyMCwgdGhlIG1lYW4gYW5udWFsIGNoYW5nZSBpbiBsYW5kIGljZSBtYXNzIHJlbGF0aXZlIHRvIDIwMDEgd2FzIC0xLDA2My43NyBiaWxsaW9uIG1ldHJpYyB0b25zLiBDb25zaWRlcmluZyB0aGUgdGltZWZyYW1lIGZvciB0aGUgc2VyaWVzIHdhcyAxOSB5ZWFycywgaXQgd2FzIHNob2NraW5nIHRvIG5vdGUgdGhhdCB0aGUg4oCYQW5udWFsX2ljZV9tYXNz4oCZIGhhZCBhIHJhbmdlIG9mIDIsNTMxLjUxIGJpbGxpb24gbWV0cmljIHRvbnMsIG1vcmUgdGhhbiBkb3VibGUgdGhlIG1lYW4gYW5udWFsIGNoYW5nZSBhbmQgaW5kaWNhdGl2ZSBvZiBhIHZlcnkgbGFyZ2UgY2hhbmdlIGluIGxhbmQgaWNlIG1hc3Mgb3ZlciB0aGUgY291cnNlIG9mIGxlc3MgdGhhbiAyMCB5ZWFycy4NCg0KQXMgdGhlIEFudGFyY3RpYyBsYW5kIEljZSBkYXRhc2V0IGhhZCBiZWVuIHN0b3JlZCBhcyBhIGRhdGFmcmFtZSB3aGVuIGl0IHdhcyBmaXJzdCBpbXBvcnRlZCBpbnRvIFIsIGl0IHdhcyBjb252ZXJ0ZWQgdG8gYSB0aW1lIHNlcmllcyBvYmplY3Qgd2l0aCBhIGZyZXF1ZW5jeSBvZiAxIGFzIGVhY2ggb2JzZXJ2YXRpb24gd2FzIGFuIGFubnVhbCBjaGFuZ2UuDQoNCmBgYHtyfQ0KaWNlX3RzIDwtIHRzKGljZSRBbm51YWxfaWNlX21hc3MsIHN0YXJ0ID0gMjAwMiwgZnJlcXVlbmN5ID0gMSkNCmljZV90cw0KYGBgDQoNCg0KIyMgRXhwbG9yaW5nIHRoZSBkYXRhDQpUaGUgQW50YXJjdGljIGxhbmQgaWNlIHNlcmllcyB3YXMgcGxvdHRlZCB0byB2aXN1YWxseSBpbnNwZWN0IHRoZSBzZXJpZXMgZm9yIHRoZSA1IGtleSB0aW1lIHNlcmllcyB0cmFpdHM7IHRyZW5kLCBzZWFzb25hbGl0eSwgY2hhbmdpbmcgdmFyaWFuY2UsIGJlaGF2aW91ciwgYW5kIGNoYW5nZSBwb2ludC9pbnRlcnZlbnRpb24uDQoNCmBgYHtyfQ0KcGxvdChpY2VfdHMsIHR5cGU9Im8iLCB4bGFiPSJZZWFyIiwNCiB5bGFiPSJDaGFuZ2UgaW4gQW50YXJjdGljYSBsYW5kIGljZSBtYXNzLCByZWxhdGl2ZSB0byAyMDAxIChiaWxsaW9uIG1ldHJpYyB0b25zKSIsDQogbWFpbj0iVGltZSBzZXJpZXMgcGxvdCBvZiB0aGUgTkFTQSBBbm51YWwgQW50YXJjdGljYSBsYW5kIGljZSBtYXNzIHNlcmllcy4iKQ0KYGBgDQpGaWd1cmUgMTogVGltZSBzZXJpZXMgcGxvdCBvZiB0aGUgQW5udWFsIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMuDQoNClRoZSB0aW1lIHNlcmllcyBwbG90IG9mIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzIHNob3dlZCB0aGUgZm9sbG93aW5nIHRpbWUgc2VyaWVzIHRyYWl0czsgDQoNCjEuIFRyZW5kDQoNCkZyb20gdGhlIHRpbWUgc2VyaWVzIHBsb3QgaW4gRmlndXJlIDEsIGl0IHdhcyBjbGVhciB0aGUgc2VyaWVzIGhhZCBhIGRvd253YXJkLCBsaW5lYXIgdHJlbmQsIGluZGljYXRpbmcgdGhhdCB0aGUgQW50YXJjdGljIGxhbmQgaWNlIG1hc3Mgd2FzIGdldHRpbmcgc21hbGxlciByZWxhdGl2ZSB0byAyMDAxIGFzIHRpbWUgcHJvZ3Jlc3NlZC4NCg0KMi4gU2Vhc29uYWxpdHkgDQoNClRoZXJlIHdlcmUgbm8gY2xlYXIgc2lnbnMgb2Ygc2Vhc29uYWxpdHkgaW4gRmlndXJlIDEuDQoNCjMuIENoYW5naW5nIHZhcmlhbmNlIA0KDQpUaGVyZSB3ZXJlIG5vIGNsZWFyIHNpZ25zIG9mIGNoYW5naW5nIHZhcmlhbmNlIGluIEZpZ3VyZSAxLg0KDQo0LiBCZWhhdmlvdXIgDQoNClRoZSB0aW1lIHNlcmllcyBwbG90IGluIEZpZ3VyZSAxIGV4aGliaXRlZCBhdXRvcmVncmVzc2l2ZSAoQVIpIGJlaGF2aW91ciwgd2l0aCBtYW55IHN1Y2Nlc3NpdmUgcG9pbnRzLiBUaGVyZSB3ZXJlIG5vIGNsZWFyIGZsdWN0dWF0aW9ucyBpbiB0aGUgc2VyaWVzLCBzbyB0aGVyZSB3YXMgbm8gZXZpZGVuY2Ugb2YgbW92aW5nIGF2ZXJhZ2UgKE1BKSBiZWhhdmlvdXIuDQoNCjUuIENoYW5nZSBwb2ludCANCg0KVGhlcmUgd2FzIG5vIGNsZWFyIGV2aWRlbmNlIG9mIGEgY2hhbmdlIHBvaW50IChpbnRlcnZlbnRpb24pIGluIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzIGFzIHRoZSBzZXJpZXMgYXBwZWFyZWQgdG8gZXhoaWJpdCB0aGUgc2FtZSB0cmVuZCBhbmQgYmVoYXZpb3VyLCB3aXRoIG5vIHN1ZGRlbiBjaGFuZ2VzLiBUaGlzIHdhcyBub3Qgc3VycHJpc2luZyBjb25zaWRlcmluZyB0aGUgZmFjdG9ycyB0aGF0IHdvdWxkIGFmZmVjdCBBbnRhcmN0aWMgbGFuZCBpY2UgbWFzcyAoZS5nLiwgY2xpbWF0ZSBjaGFuZ2UpIGRvIG5vdCBjaGFuZ2Ugc3Vic3RhbnRpYWxseSBmcm9tIHllYXIgdG8geWVhci4gSXQgd291bGQgdGFrZSBhIHZlcnkgbGFyZ2UgaW50ZXJ2ZW50aW9uIChlLmcuLCBhIG1ldGVvciBzdHJpa2UpIHRvIGNoYW5nZSB0aGUgYmVoYXZpb3VyIG9mIHRoZSBzZXJpZXMuDQoNClRoZSBwb2ludHMgaW4gRmlndXJlIDEgc2hvdyBldmlkZW5jZSBvZiBzdWNjZWVkaW5nIG1lYXN1cmVtZW50cyBiZWluZyByZWxhdGVkIHRvIG9uZSBhbm90aGVyLCBhbmQgRmlndXJlIDIgaGlnaGxpZ2h0cyB0aGlzIHJlbGF0aW9uc2hpcCBtb3JlIGNsZWFybHkgdXNpbmcgYSBzY2F0dGVyIHBsb3Qgb2YgbmVpZ2hib3VyaW5nIHBhaXJzLg0KDQpgYGB7cn0NCiNsYWcgdGhlIHRpbWUgc2VyaWVzDQpwYXIobWZyb3c9YygxLDEpKQ0KcGxvdCh5PWljZV90cywgeD16bGFnKGljZV90cyksIA0KIHlsYWI9IkNoYW5nZSBpbiBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3MsIHJlbGF0aXZlIHRvIDIwMDEgKGJpbGxpb24gbWV0cmljIHRvbnMpIiwgDQogeGxhYj0iQ2hhbmdlIGluIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBpbiBwcmV2aW91cyB5ZWFyIiwNCiBtYWluID0gIlNjYXR0ZXIgcGxvdCBvZiBDaGFuZ2UgaW4gQW50YXJjdGljYSBsYW5kIGljZSBtYXNzIGluIGNvbnNlY3V0aXZlIFllYXJzLiIpDQpgYGANCkZpZ3VyZSAyOiBTY2F0dGVyIHBsb3Qgb2YgZWFjaCBBbm51YWwgQW50YXJjdGljYSBsYW5kIGljZSBtYXNzIG1lYXN1cmVtZW50IGFuZCB0aGUgbWVhc3VyZW1lbnQgdGFrZW4gaW4gdGhlIHByZXZpb3VzIHllYXIuDQoNCmBgYHtyfQ0KIyBjb3JyZWxhdGlvbiBvZiBuZWlnaGJvdXJpbmcgcGFpcnMNCnkgPSBpY2VfdHMgIyBBc3NpZ24gdGhlIGljZSBkYXRhIHRvIHkNCnggPSB6bGFnKGljZV90cykgIyBHZW5lcmF0ZSBmaXJzdCBsYWcgb2YgdGhlIGljZSBzZXJpZXMNCmluZGV4ID0gMjpsZW5ndGgoeCkgIyBDcmVhdGUgYW4gaW5kZXggdG8gZ2V0IHJpZCBvZiB0aGUgZmlyc3QgTkEgdmFsdWUgaW4geA0KY29yKHlbaW5kZXhdLHhbaW5kZXhdKSAjIENhbGN1bGF0ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIG51bWVyaWNhbCB2YWx1ZXMgaW4geCBhbmQgeQ0KYGBgDQoNClRoZSBzY2F0dGVyIHBsb3QgaW4gRmlndXJlIDIgc2hvd3MgYSBzdHJvbmcsIHVwd2FyZCB0cmVuZCwgaW5kaWNhdGl2ZSBvZiBhIHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIG5laWdoYm91cmluZyBwYWlycy4gVGhlIHBsb3QgaW5kaWNhdGVzIHRoYXQgc21hbGwgYW5udWFsIGNoYW5nZXMgaW4gQW50YXJjdGljIGxhbmQgaWNlIG1hc3MgKHJlbGF0aXZlIHRvIDIwMDEpIHRlbmQgdG8gYmUgZm9sbG93ZWQgYnkgc21hbGwgY2hhbmdlcywgbW9kZXJhdGUgY2hhbmdlcyB0ZW5kIHRvIGJlIGZvbGxvd2VkIGJ5IG1vZGVyYXRlIGNoYW5nZXMsIGFuZCBsYXJnZSBjaGFuZ2VzIHRlbmQgdG8gYmUgZm9sbG93ZWQgYnkgbGFyZ2UgY2hhbmdlcy4gVGhlc2Ugb2JzZXJ2YXRpb25zIHdlcmUgc3VwcG9ydGVkIGJ5IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIG5laWdoYm91cmluZyBhbm51YWwgbGFuZCBpY2UgbWFzcyBjaGFuZ2VzIHdoaWNoLCBhdCAwLjk4NSwgaW5kaWNhdGVkIGEgdmVyeSBzdHJvbmcsIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gbmVpZ2hib3VyaW5nIHBvaW50cy4NCg0KIyMgQXNzZXNzaW5nIHN0YXRpb25hcml0eQ0KRmlndXJlIDEgc2hvd2VkIGEgc3Ryb25nLCBkb3dud2FyZCwgbGluZWFyIHRyZW5kIGluIHRoZSBBbnRhcmN0aWNhIGljZSBzZXJpZXMsIHN1Z2dlc3RpbmcgdGhhdCB0aGUgcmF3IEFudGFyY3RpY2EgaWNlIHNlcmllcyB3YXMgbm9uLXN0YXRpb25hcnkuIEFzIEFSSU1BIG1vZGVscyBjYW4gb25seSBiZSBwcm9kdWNlZCB1c2luZyBhIHN0YXRpb25hcnkgc2VyaWVzLCBBQ0YgYW5kIFBBQ0YgcGxvdHN3ZXJlIHByb2R1Y2VkIHRvIGFzc2VzcyB0aGUgc2VyaWVzIGZvciBzdGF0aW9uYXJpdHkuDQoNCmBgYHtyfQ0KYWNmX3BhY2YoaWNlX3RzLCAidGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcy4iKQ0KYGBgDQpGaWd1cmUgMzogQUNGIGFuZCBQQUNGIHBsb3RzIG9mIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzLg0KDQpUaGUgQUNGIHBsb3QgaW4gRmlndXJlIDMgc2hvd2VkIDMgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uIGxhZ3MgYW5kIGEgZGVjYXlpbmcgcGF0dGVybiwgaW5kaWNhdGl2ZSBvZiBhIG5vbi1zdGF0aW9uYXJ5LCBhdXRvcmVncmVzc2l2ZSBwcm9jZXNzLiBUaGVyZSB3YXMgbm8gZXZpZGVuY2Ugb2Ygc2Vhc29uYWxpdHkgaW4gdGhlIHNlcmllcyBhcyB0aGVyZSB3YXMgbm8gY2xlYXIgd2F2ZSBwYXR0ZXJuIGluIHRoZSBBQ0YgbGFncy4gDQoNClRoZSBmaXJzdCBwYXJ0aWFsIGF1dG9jb3JyZWxhdGlvbiBsYWcgaW4gdGhlIFBBQ0YgcGxvdCBpbiBGaWd1cmUgMyB3YXMgaGlnaGx5IHNpZ25pZmljYW50LCB3aGlsZSBhbGwgb3RoZXIgbGFncyB3ZXJlIG5vdCBzaWduaWZpY2FudCwgaW5kaWNhdGl2ZSBvZiBhIG5vbi1zdGF0aW9uYXJ5LCBhdXRvcmVncmVzc2l2ZSBzZXJpZXMuDQpTZXZlcmFsIHVuaXQgcm9vdCB0ZXN0cywgaW5jbHVkaW5nIGFuIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3QsIHdlcmUgYWxzbyB1c2VkIHRvIGFzc2VzcyB0aGUgc2VyaWVzIGZvciBzdGF0aW9uYXJpdHksIHdpdGggcmVzdWx0cyBzaG93biBpbiBUYWJsZSA0Lg0KDQpgYGB7cn0NCmFkZi50ZXN0KGljZV90cywgYWx0ZXJuYXRpdmUgPSBjKCJzdGF0aW9uYXJ5IikpICMgc2lnbmlmaWNhbnQ9c3RhdGlvbmFyeSwgZG91YnQgcmFuZ2U6KDAuMDMgLSAwLjEpDQpwcC50ZXN0KGljZV90cykgIyBzaWduaWZpY2FudCA9IHN0YXRpb25hcnkNCmtwc3MudGVzdChpY2VfdHMpICMgc2lnbmlmaWNhbnQgPSBub24tc3RhdGlvbmFyeQ0KYGBgDQpUYWJsZSA0OiBTdGF0aXN0aWNhbCB0ZXN0cyBmb3Igc3RhdGlvbmFyaXR5IGFuZCBub3JtYWxpdHkgaW4gdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMuDQoNClRoZSBudWxsIGh5cG90aGVzaXMgdW5kZXIgdGhlIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3QgYW5kIHRoZSBQaGlsbGlwcy1QZXJyb24gKFBQKSB0ZXN0IGlzIHRoYXQgdGhlIHNlcmllcyBJcyBub24tc3RhdGlvbmFyeS4gV2l0aCBwLXZhbHVlcyBvZiAwLjMwIGZvciB0aGUgQXVnbWVudGVkIERpY2tleS1GdWxsZXIgdGVzdCwgYW5kIDAuNzUgZm9yIHRoZSBQUCB0ZXN0LCB0aGVyZSB3YXMgaW5zdWZmaWNpZW50IGV2aWRlbmNlIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGJvdGggdGVzdHMgYW5kIHRoZXJlZm9yZSB3ZSBjb3VsZCBjb25jbHVkZSB0aGF0IHRoZSBzZXJpZXMgd2FzIG5vdCBzdGF0aW9uYXJ5LiBUaGlzIGNvbmNsdXNpb24gd2FzIHN1cHBvcnRlZCBieSByZXN1bHRzIG9mIGEgS1BTUyB0ZXN0LCB3aGljaCBwcm9kdWNlZCBhIHAtdmFsdWUgb2YgMC4wMSwgaW5kaWNhdGluZyB0aGVyZSB3YXMgc3VmZmljaWVudCBldmlkZW5jZSB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB1bmRlciB0aGUgS1BTUyB0ZXN0IHRoYXQgdGhlIHNlcmllcyB3YXMgc3RhdGlvbmFyeS4gRmluYWxseSwgYSBRLVEgcGxvdCB3YXMgcHJvZHVjZWQgdG8gYXNzZXNzIHRoZSByYXcgc2VyaWVzIGZvciBub3JtYWxpdHksIGFsb25nc2lkZSBhIFNoYXBpcm8tV2lsayB0ZXN0LiBBbHRob3VnaCB0aGUgUS1RIHBsb3QgaW4gRmlndXJlIDQgc2hvd2VkIGRldmlhdGlvbnMgZnJvbSB0aGUgZGlhZ29uYWwgaW4gZWFjaCB0YWlsIG9mIHRoZSBzZXJpZXMsIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBwcm9kdWNlZCBhIHAtdmFsdWUgb2YgMC4xNDcsIGluZGljYXRpbmcgdGhhdCB0aGUgbWVhc3VyZW1lbnRzIGluIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzIHdlcmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KYGBge3J9DQojIyBOb3JtYWxpdHkgY2hlY2tzDQpxcW5vcm0oaWNlX3RzKQ0KcXFsaW5lKGljZV90cywgY29sID0gMikNCmBgYA0KRmlndXJlIDQ6IE5vcm1hbCBRLVEgcGxvdCBvZiB0aGUgQW50YXJjdGljYSBsYW5kIGljZSBtYXNzIHNlcmllcy4NCg0KYGBge3J9DQpzaGFwaXJvLnRlc3QoaWNlX3RzKSAjIG5vdCBzaWduaWZpY2FudCAtIGFwcHJveGltYXRlbHkgbm9ybWFsDQpgYGANClRhYmxlIDU6IFJlc3VsdCBvZiB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgb24gdGhlIHJhdyBBbnRhcmN0aWNhIEljZSBzZXJpZXMuDQoNCg0KIyMgQWRkcmVzc2luZyBub24tc3RhdGlvbmFyaXR5DQojIyMgVHJhbnNmb3JtYXRpb24NCkFsdGhvdWdoIHRoZXJlIHdhcyBubyBjbGVhciBldmlkZW5jZSBvZiBjaGFuZ2luZyB2YXJpYW5jZSBpbiBGaWd1cmUgMSwgYSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIHdhcyBhcHBsaWVkIHRvIHRoZSBzZXJpZXMgdG8gb2JzZXJ2ZSB0aGUgaW1wYWN0IG9mIHRyYW5zZm9ybWF0aW9uIG9uIHRoZSBzZXJpZXMuDQoNCkFzIHRoZSBzZXJpZXMgY29udGFpbmVkIG5lZ2F0aXZlIHZhbHVlcyAoZGVjbGluZXMgaW4gdGhlIGxhbmQgaWNlIG1hc3MgcmVsYXRpdmUgdG8gMjAwMSksIGEgY29uc3RhbnQgaGFkIHRvIGJlIGFkZGVkIHRvIHRoZSBzZXJpZXMgdG8gbWFrZSBhbGwgdmFsdWVzIGdyZWF0ZXIgdGhhbiB6ZXJvIGJlZm9yZSBhIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gY291bGQgYmUgYXBwbGllZC4gQSB2ZWN0b3Igb2YgY2FuZGlkYXRlIHBvd2VyIHRyYW5zZm9ybWF0aW9uIHZhbHVlcyB3YXMgYWxzbyByZXF1aXJlZCB0byBvYnRhaW4gY2FuZGlkYXRlIGxhbWJkYSB2YWx1ZXMgZm9yIHRoZSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIGR1ZSB0byBjb21wdXRhdGlvbmFsIGxpbWl0cy4gVGhyb3VnaCB0cmlhbCBhbmQgZXJyb3IsIGxpbWl0cyBvZiB6ZXJvIGFuZCAyIHdlcmUgaWRlbnRpZmllZCBhcyBhcHByb3ByaWF0ZSBwb3dlciB0cmFuc2Zvcm1hdGlvbiBsaW1pdHMgZm9yIHRoZSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uLg0KDQpUaGUgcGxvdCBvZiBjYW5kaWRhdGUgbGFtYmRhIHZhbHVlcyBmb3IgdGhlIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gb2YgdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMgY2FuIGJlIHNlZW4gaW4gRmlndXJlIDUuIFRhYmxlIDYgc2hvd3MgdGhlIHZhbHVlcyBvZiB0aGUgZmlyc3QgYW5kIHRoaXJkIHZlcnRpY2FsIGxpbmVzIGZyb20gRmlndXJlIDUgd2VyZSAwLjY1IGFuZCAxLjIyLCByZXNwZWN0aXZlbHksIGFuZCB0aGUgY2hvc2VuIGxhbWJkYSB2YWx1ZSBmb3IgdGhlIEJveC1Db3ggdHJhbnNmb3JtYXRpb24gKHRoZSBtaWRkbGUgdmVydGljYWwgbGluZSBpbiBGaWd1cmUgNSkgd2FzIDAuODkuDQoNCmBgYHtyfQ0KI0JDID0gQm94Q294LmFyKGljZV90cykgIyBFUlJPUjogZGF0YSB2YWx1ZXMgbXVzdCBiZSBwb3NpdGl2ZS4NCm1pbihpY2VfdHMpICMgbWluaW11bSBpcyAtMjUzOS4wNTUNCiMgYWRkIHRoZSBtaW5pbXVtIHRvIGVhY2ggdmFsdWUgaW4gdGhlIHNlcmllcywgdG8gbWFrZSBhbGwgdmFsdWVzIGdyZWF0ZXIgdGhhbiB6ZXJvLg0KaWNlX3RzMiA8LSBpY2VfdHMgKyBhYnMobWluKGljZV90cykpICsgMC4wMQ0KQkMgPC0gQm94Q294LmFyKHk9aWNlX3RzMiwgbGFtYmRhPXNlcSgwLCAyLCAwLjAxKSkNCmBgYA0KRmlndXJlIDU6IExvZyBsaWtlbGlob29kIHBsb3QgZm9yIHRoZSBsYW1iZGEgdmFsdWVzIGluIHRoZSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzLg0KDQpgYGB7cn0NCkJDJGNpICNWYWx1ZXMgb2YgdGhlIGZpcnN0IGFuZCB0aGlyZCB2ZXJ0aWNhbCBsaW5lcw0KIyBUbyBmaW5kIHRoZSBsYW1iZGEgdmFsdWUgb2YgdGhlIG1pZGRsZSB2ZXJ0aWNhbCBsaW5lDQpsYW1iZGEgPC0gQkMkbGFtYmRhW3doaWNoKG1heChCQyRsb2dsaWtlKSA9PSBCQyRsb2dsaWtlKV0NCmxhbWJkYQ0KYGBgDQpUYWJsZSA2OiBSZXN1bHRzIGZvciBjYW5kaWRhdGUgbGFtYmRhIHZhbHVlcyBmcm9tIHRoZSBCb3gtQ294IHBvd2VyIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uLg0KDQpXaXRoIGFuIGFwcHJvcHJpYXRlIGxhbWJkYSB2YWx1ZSBpZGVudGlmaWVkLCB0aGUgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZCB0byB0aGUgQW50YXJjdGljYSBJY2Ugc2VyaWVzIGFuZCB0aGUgcmVzdWx0YW50IHNlcmllcyB3YXMgcGxvdHRlZCBmb3IgdmlzdWFsIGluc3BlY3Rpb24gaW4gRmlndXJlIDYuDQoNCmBgYHtyfQ0KIyBBcHBseSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uDQppY2VCQyA8LSAoKGljZV90czJebGFtYmRhKSAtIDEpIC8gbGFtYmRhDQpwbG90KGljZUJDLCB0eXBlPSJvIiwgeGxhYj0iWWVhcnMiLCANCiB5bGFiPSJDaGFuZ2UgaW4gQW50YXJjdGljYSBsYW5kIGljZSBtYXNzLCByZWxhdGl2ZSB0byAyMDAxIChiaWxsaW9uIG1ldHJpYyB0b25zKSIsDQogbWFpbiA9ICJUaW1lIHNlcmllcyBwbG90IG9mIEJveENveCB0cmFuc2Zvcm1lZCBBbnRhcmN0aWNhIEljZSBzZXJpZXMuIikNCmBgYA0KRmlndXJlIDY6IFRpbWUgc2VyaWVzIHBsb3Qgb2YgdGhlIEJveC1Db3ggdHJhbnNmb3JtZWQgQW5udWFsIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMuDQoNClRoZSB0aW1lIHNlcmllcyBwbG90IGluIEZpZ3VyZSA2IHNob3dlZCBubyBjbGVhciBjaGFuZ2Ugb3IgaW1wcm92ZW1lbnQgaW4gdGhlIHZhcmlhdGlvbiBvZiB0aGUgc2VyaWVzLCBhbmQgdGhlIFEtUSBwbG90IGluIEZpZ3VyZSA3IHN0aWxsIHNob3dlZCBkZXZpYXRpb25zIGZyb20gdGhlIGRpYWdvbmFsIGF0IGJvdGggdGFpbHMgb2YgdGhlIHNlcmllcy4gVGhlcmUgd2FzIGFsc28gbGl0dGxlIGNoYW5nZSBpbiB0aGUgcmVzdWx0IGZyb20gdGhlIFNoYXBpcm8tV2lsayB0ZXN0IG9mIHRoZSBCb3gtQ294IHRyYW5zZm9ybWVkIHNlcmllcywgc2hvd24gaW4gVGFibGUgNywgaW5kaWNhdGluZyB0aGF0IHZhbHVlcyBpbiB0aGUgc2VyaWVzIHdlcmUgc3RpbGwgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KYGBge3J9DQpxcW5vcm0oaWNlQkMsIG1haW4gPSAiTm9ybWFsIFEtUSBQbG90IGZvciB0aGUgQm94LUNveCB0cmFuc2Zvcm1lZCBBbnRhcmN0aWNhIEljZSBzZXJpZXMuIikNCnFxbGluZShpY2VCQywgY29sID0gMikNCmBgYA0KRmlndXJlIDc6IE5vcm1hbCBRLVEgUGxvdCBmb3IgdGhlIEJveC1Db3ggdHJhbnNmb3JtZWQgQW50YXJjdGljYSBJY2Ugc2VyaWVzLg0KDQpgYGB7cn0NCnNoYXBpcm8udGVzdChpY2VCQykNCmBgYA0KVGFibGUgNzogUmVzdWx0cyBmcm9tIHRoZSBTaGFwaXJvLVdpbGsgdGVzdCBvZiB0aGUgQm94LUNveCB0cmFuc2Zvcm1lZCBBbnRhcmN0aWMgSWNlIHNlcmllcy4NCg0KRmluYWxseSwgdGhlIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3QgKFRhYmxlIDgpIHByb2R1Y2VkIGEgcC12YWx1ZSBvZiAwLjU2MywgaW5kaWNhdGluZyB0aGF0IHRoZSBCb3gtQ294IHRyYW5zZm9ybWVkIEFudGFyY3RpY2EgSWNlIHNlcmllcyB3YXMgbm9uLXN0YXRpb25hcnkuDQoNCmBgYHtyfQ0KYWRmLnRlc3QoaWNlQkMpICMgc2lnbmlmaWNhbnQgPSBzdGF0aW9uYXJ5LCBkb3VidCByYW5nZTogKDAuMDMgLSAwLjEpDQpgYGANClRhYmxlIDg6IFJlc3VsdHMgZnJvbSB0aGUgQXVnbWVudGVkIERpY2tleS1GdWxsZXIgdGVzdCBvZiB0aGUgQm94LUNveCB0cmFuc2Zvcm1lZCBBbnRhcmN0aWMgSWNlIHNlcmllcy4NCg0KQXMgdGhlcmUgd2FzIG5vIGV2aWRlbmNlIHRvIHN1Z2dlc3QgdGhlIHJhdyBBbnRhcmN0aWNhIEljZSBzZXJpZXMgZXhoaWJpdGVkIGNoYW5naW5nIHZhcmlhdGlvbiwgYW5kIHRoZSBCb3gtQ294IHRyYW5zZm9ybWF0aW9uIGRpZCBub3QgY2hhbmdlIG9yIGltcHJvdmUgdGhlIG5vcm1hbGl0eSBvZiB0aGUgc2VyaWVzLCB0aGUgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiB3YXMgZGVlbWVkIHVubmVjZXNzYXJ5LCBhbmQgdGhlIHJhdyBzZXJpZXMgd291bGQgYmUgdXNlZCB3aGVuIGFwcGx5aW5nIGRpZmZlcmVuY2luZyB0byBhZGRyZXNzIG5vbi1zdGF0aW9uYXJpdHkuDQoNCiMjIyBEaWZmZXJlbmNpbmcNCkRpZmZlcmVuY2luZyB3YXMgYXBwbGllZCB0byB0aGUgcmF3IEFudGFyY3RpY2EgSWNlIHNlcmllcyB0byBhZGRyZXNzIHRoZSB0cmVuZCBpbiB0aGUgcmF3IHNlcmllcywgd2l0aCB0aGUgcmVzdWx0aW5nIHNlcmllcyBwbG90dGVkIGluIEZpZ3VyZSA4Lg0KDQpgYGB7cn0NCmljZV9kaWZmIDwtIGRpZmYoaWNlX3RzLCBkaWZmZXJlbmNlcyA9IDEpDQpwYXIobWFyPWMoNSw2LDQsMSkrLjEpICNzZXQgcGxvdCB3aW5kb3cgbWFyZ2lucw0KcGxvdChpY2VfZGlmZiwgdHlwZT0ibyIsIHhsYWI9IlllYXIiLA0KIHlsYWI9IkNoYW5nZSBpbiBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3MsIHJlbGF0aXZlIHRvIDIwMDEgXG4oYmlsbGlvbiBtZXRyaWMgdG9ucykiLA0KIG1haW49IlRpbWUgc2VyaWVzIHBsb3Qgb2YgZmlyc3QgZGlmZmVyZW5jZWQgQW50YXJjdGljYSBJY2Ugc2VyaWVzLiIpDQpgYGANCkZpZ3VyZSA4OiBUaW1lIHNlcmllcyBwbG90IG9mIGZpcnN0IGRpZmZlcmVuY2VkIEFudGFyY3RpY2EgSWNlIHNlcmllcw0KDQpUaGUgdGltZSBzZXJpZXMgcGxvdCBpbiBGaWd1cmUgOCBhcHBlYXJlZCB0byBleGhpYml0IGEgc2xpZ2h0IGRvd253YXJkIHRyZW5kLCBpbmRpY2F0aW5nIHRoYXQgdGhlIGZpcnN0IGRpZmZlcmVuY2VkIHNlcmllcyBtYXkgc3RpbGwgYmUgbm9uLXN0YXRpb25hcnkuIEhvd2V2ZXIsIHRoZSBBQ0YgYW5kIFBBQ0YgcGxvdHMgb2YgdGhlIGZpcnN0IGRpZmZlcmVuY2VkIEFudGFyY3RpY2EgSWNlIHNlcmllcyAoRmlndXJlIDkpIHNob3dlZCBubyBzaWduaWZpY2FudCBwb2ludHMgYW5kIG5vIGRlY2F5aW5nIHBhdHRlcm4sIHN1Z2dlc3RpbmcgdGhlIGZpcnN0IGRpZmZlcmVuY2VkIHNlcmllcyBtYXkgaGF2ZSBiZWVuIHN0YXRpb25hcnkuDQoNCmBgYHtyfQ0KYWNmX3BhY2YoaWNlX2RpZmYsICJ0aGUgZmlyc3QgZGlmZmVyZW5jZWQgXG5BbnRhcmN0aWNhIEljZSBzZXJpZXMuIikNCmBgYA0KRmlndXJlIDk6IEFDRiBhbmQgUEFDRiBwbG90cyBvZiB0aGUgZmlyc3QgZGlmZmVyZW5jZWQgQW50YXJjdGljYSBsYW5kIGljZSBtYXNzIHNlcmllcy4NCg0KVG8gdGVzdCBmb3Igc3RhdGlvbmFyaXR5LCBhbiBBdWdtZW50ZWQgRGlja2V5LUZ1bGxlciB0ZXN0IG9mIHRoZSBmaXJzdCBkaWZmZXJlbmNlZCBzZXJpZXMgd2FzIHBlcmZvcm1lZCwgd2l0aCB0aGUgdGVzdCByZXN1bHRpbmcgaW4gYSBwLXZhbHVlIG9mIDAuMzU3IHdoaWNoLCBhdCB0aGUgzrE9MC4wNSBsZXZlbCwgaW5kaWNhdGVkIHRoYXQgdGhlIGZpcnN0IGRpZmZlcmVuY2VkIEFudGFyY3RpY2EgSWNlIHNlcmllcyB3YXMgbm9uLXN0YXRpb25hcnkuDQoNCmBgYHtyfQ0KYWRmLnRlc3QoaWNlX2RpZmYpIyBzaWduaWZpY2FudCA9IHN0YXRpb25hcnksIGRvdWJ0IHJhbmdlOiAoMC4wMyAtIDAuMSkNCmBgYA0KVGFibGUgOTogUmVzdWx0IGZyb20gdGhlIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3Qgb2YgdGhlIGZpcnN0IGRpZmZlcmVuY2VkIEFudGFyY3RpYyBJY2Ugc2VyaWVzLg0KDQpBcyBmaXJzdCBkaWZmZXJlbmNpbmcgaGFkIG5vdCBwcm9kdWNlZCBhIHN0YXRpb25hcnkgc2VyaWVzLCBzZWNvbmQgZGlmZmVyZW5jaW5nIHdhcyBhcHBsaWVkIHRvIHRoZSByYXcgQW50YXJjdGljYSBJY2Ugc2VyaWVzLCB3aXRoIHRoZSByZXN1bHRpbmcgc2VyaWVzIHBsb3R0ZWQgaW4gRmlndXJlIDEwLg0KDQpgYGB7cn0NCmljZV9kaWZmMiA8LSBkaWZmKGljZV90cywgZGlmZmVyZW5jZXMgPSAyKQ0KcGxvdChpY2VfZGlmZjIsIHR5cGU9Im8iLCB4bGFiPSJZZWFyIiwNCiB5bGFiPSJDaGFuZ2UgaW4gQW50YXJjdGljYSBsYW5kIGljZSBtYXNzLCByZWxhdGl2ZSB0byAyMDAxIFxuKGJpbGxpb24gbWV0cmljIHRvbnMpIiwNCiBtYWluPSJUaW1lIHNlcmllcyBwbG90IG9mIHNlY29uZCBkaWZmZXJlbmNlZCBBbnRhcmN0aWNhIEljZSBzZXJpZXMuIikNCmBgYA0KRmlndXJlIDEwOiBUaW1lIHNlcmllcyBwbG90IG9mIHNlY29uZCBkaWZmZXJlbmNlZCBBbnRhcmN0aWNhIEljZSBzZXJpZXMuDQoNClRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgdGltZSBzZXJpZXMgaW4gRmlndXJlIDEwIHNob3dlZCBubyBjbGVhciB0cmVuZCwgc3VnZ2VzdGluZyB0aGF0IHNlY29uZCBkaWZmZXJlbmNpbmcgbWF5IGhhdmUgcmVzdWx0ZWQgaW4gYSBzdGF0aW9uYXJ5IHNlcmllcy4NCg0KYGBge3J9DQphY2ZfcGFjZihpY2VfZGlmZjIsICJ0aGUgXG5zZWNvbmQgZGlmZmVyZW5jZWQgQW50YXJjdGljYSBJY2Ugc2VyaWVzIikNCmBgYA0KRmlndXJlIDExOiBBQ0YgYW5kIFBBQ0YgcGxvdHMgb2YgdGhlIHNlY29uZCBkaWZmZXJlbmNlZCBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3Mgc2VyaWVzLg0KDQpUaGUgQUNGIGFuZCBQQUNGIHBsb3RzIG9mIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIChGaWd1cmUgMTEpIHNob3dlZCBhIHNpZ25pZmljYW50IFBBQ0YgbGFnIGF0IHRoZSBzZWNvbmQgbGFnLCBzdWdnZXN0aW5nIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIG1heSBiZSBub24tc3RhdGlvbmFyeS4gU3VwcG9ydGluZyB0aGlzIHdhcyB0aGUgQXVnbWVudGVkIERpY2tleS1GdWxsZXIgdGVzdCBvZiB0aGUgc2Vjb25kIGRpZmZlcmVuY2VkIHNlcmllcyAoVGFibGUgMTApLCB3aGljaCBwcm9kdWNlZCBhIHAtdmFsdWUgb2YgMC4wNzMsIGluZGljYXRpbmcgdGhhdCwgYXQgdGhlIM6xPTAuMDUgbGV2ZWwsIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIG1heSBzdGlsbCBoYXZlIGJlZW4gbm9uLXN0YXRpb25hcnkuDQoNCkhvd2V2ZXIsIGFzIHRoZSByZXN1bHQgb2YgdGhlIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3Qgd2FzIHdpdGhpbiB0aGUg4oCcZG91YnQgcmFuZ2XigJ0gb2YgMC4wMyB0byAwLjEsIGFkZGl0aW9uYWwgdW5pdCByb290IHRlc3RzIHdlcmUgcGVyZm9ybWVkIHRvIGJldHRlciBldmFsdWF0ZSB3aGV0aGVyIHNlY29uZCBkaWZmZXJlbmNpbmcgaGFkIHJlc3VsdGVkIGluIGEgc3RhdGlvbmFyeSBzZXJpZXMuDQoNCmBgYHtyfQ0KYWRmLnRlc3QoaWNlX2RpZmYyKSMgc2lnbmlmaWNhbnQgPSBzdGF0aW9uYXJ5LCBkb3VidCByYW5nZTogKDAuMDMgLSAwLjEpDQpgYGANClRhYmxlIDEwOiBSZXN1bHRzIGZyb20gdGhlIEF1Z21lbnRlZCBEaWNrZXktRnVsbGVyIHRlc3QsIFBoaWxsaXBzLVBlcnJvbiB0ZXN0LCBhbmQgS1BTUyB0ZXN0IG9mIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgQW50YXJjdGljIEljZSBzZXJpZXMuDQoNCkEgUGhpbGxpcHMtUGVycm9uIFVuaXQgUm9vdCB0ZXN0IGFuZCBhIEtQU1MgdGVzdCAoVGFibGUgMTEpIHByb2R1Y2VkIHAtdmFsdWVzIG9mIDAuMDI2LCBhbmQgMC4xLCByZXNwZWN0aXZlbHksIGluZGljYXRpbmcgdGhlcmUgd2FzIHN1ZmZpY2llbnQgZXZpZGVuY2UgdG8gY29uY2x1ZGUgdGhlIHNlY29uZCBkaWZmZXJlbmNlZCBzZXJpZXMgd2FzIHN0YXRpb25hcnkuDQoNCmBgYHtyfQ0KIyBwLXZhbHVlIGlzIGluIHRoZSBkb3VidCByYW5nZSwgc28gcmVmZXIgdG8gYWRkaXRpb25hbCB0ZXN0cy4NCnBwLnRlc3QoaWNlX2RpZmYyKSAjIHNpZ25pZmljYW50ID0gc3RhdGlvbmFyeQ0Ka3Bzcy50ZXN0KGljZV9kaWZmMikgIyBzaWduaWZpY2FudCA9IG5vbi1zdGF0aW9uYXJ5DQpgYGANClRhYmxlIDExOiBSZXN1bHRzIGZyb20gdGhlIFBoaWxsaXBzLVBlcnJvbiB0ZXN0LCBhbmQgS1BTUyB0ZXN0IG9mIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgQW50YXJjdGljIEljZSBzZXJpZXMuDQoNCkFzIHRoZSBzZXJpZXMgYXBwZWFyZWQgc3RhdGlvbmFyeSBpbiBGaWd1cmUgMTAsIGFuZCB0aGUgUGhpbGxpcHMtUGVycm9uIFVuaXQgUm9vdCB0ZXN0IGFuZCBLUFNTIHRlc3QgaW4gVGFibGUgMTEgaW5kaWNhdGVkIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIHdhcyBzdGF0aW9uYXJ5LCBpdCB3YXMgY29uY2x1ZGVkIHRoYXQgc2Vjb25kIGRpZmZlcmVuY2luZyBvZiB0aGUgQW50YXJjdGljYSBJY2Ugc2VyaWVzIGhhZCByZXN1bHRlZCBpbiBhIHN0YXRpb25hcnkgc2VyaWVzLg0KDQpBcyBzZWNvbmQgZGlmZmVyZW5jaW5nIHRoZSBBbnRhcmN0aWNhIEljZSBzZXJpZXMgaGFkIHJlc3VsdGVkIGluIGEgc3RhdGlvbmFyeSBzZXJpZXMsIGl0IHdhcyBkZWVtZWQgc3VpdGFibGUgZm9yIHVzZSBpbiBtb2RlbCBzcGVjaWZpY2F0aW9uLiBBbGwgcHJvcG9zZWQgQVJJTUEocCxkLHEpIG1vZGVscyB3b3VsZCBoYXZlIGEgdmFsdWUgb2Yg4oCcZOKAnSBlcXVhbCB0byAyLCBhcyBzZWNvbmQgZGlmZmVyZW5jaW5nIGhhZCBiZWVuIGFwcGxpZWQuDQoNCiMjIE1vZGVsIHNwZWNpZmljYXRpb24NCiMjIyBBQ0YgJiBQQUNGIHBsb3RzDQpUaGUgZmlyc3Qgc3RlcCBpbiBpZGVudGlmeWluZyBwb3RlbnRpYWwgbW9kZWxzIGZvciB0aGUgQW50YXJjdGljYSBJY2Ugc2VyaWVzIHdhcyB0byB1c2UgQUNGIGFuZCBQQUNGIHBsb3RzIHRvIHByb3Bvc2UgdmFsdWVzIGZvciB0aGUgb3JkZXJzIG9mIGF1dG9yZWdyZXNzaW9uIChwKSBhbmQgbW92aW5nIGF2ZXJhZ2UgKHEpLg0KDQpgYGB7cn0NCmFjZl9wYWNmKGljZV9kaWZmMiwgInRoZSBcbnNlY29uZCBkaWZmZXJlbmNlZCBBbnRhcmN0aWNhIEljZSBzZXJpZXMiKQ0KYGBgDQpGaWd1cmUgMTI6IEFDRiBhbmQgUEFDRiBwbG90cyBvZiB0aGUgc2Vjb25kIGRpZmZlcmVuY2VkIEFudGFyY3RpY2EgSWNlIHNlcmllcy4NCg0KRnJvbSB0aGUgUEFDRiBwbG90IGluIEZpZ3VyZSAxMiwgdGhlIHNlY29uZCBwYXJ0aWFsIGF1dG9jb3JyZWxhdGlvbiBsYWcgd2FzIGRlZW1lZCBzaWduaWZpY2FudCwgYW5kIHRoZSBmaXJzdCBsYWcgd2FzIGRlZW1lZCBib3JkZXJsaW5lIHNpZ25pZmljYW50LCBpbmRpY2F0aW5nIHRoYXQgdGhlIHZhbHVlIG9mIOKAnHDigJ0gY291bGQgYmUgMSBvciAyLiBUaGVzZSB2YWx1ZXMgd2VyZSB1bmRlcnN0YW5kYWJsZSBnaXZlbiBhdXRvcmVncmVzc2l2ZSBiZWhhdmlvdXIgd2FzIGlkZW50aWZpZWQgaW4gdGhlIHJhdyBBbnRhcmN0aWNhIEljZSBzZXJpZXMuIA0KDQpUaGVyZSB3ZXJlIG5vIGNsZWFybHkgc2lnbmlmaWNhbnQgYXV0b2NvcnJlbGF0aW9uIGxhZ3MgaW4gdGhlIEFDRiBwbG90IG9mIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzLiBIb3dldmVyLCB0aGUgZmlyc3QgbGFnIG9mIHRoZSBBQ0YgcGxvdCB3YXMgZGVlbWVkIGJvcmRlcmxpbmUgc2lnbmlmaWNhbnQsIGFuZCB0aHVzIHRoZSB2YWx1ZSBvZiDigJxx4oCdIHdhcyBwcm9wb3NlZCBhcyBlaXRoZXIgMCBvciAxLg0KDQpUaGUgcmVzdWx0aW5nIHByb3Bvc2VkIG1vZGVscyBmcm9tIHRoZSBBQ0YgYW5kIFBBQ0YgcGxvdHMgd2VyZToNCg0KKiB7IEFSSU1BKDEsMiwwKSwgQVJJTUEoMiwyLDApLCBBUklNQSgxLDIsMSksIEFSSU1BKDIsMiwxKSB9DQoNCiMjIyBFQUNGDQpUaGUgc2Vjb25kIHN0ZXAgaW4gaWRlbnRpZnlpbmcgcG90ZW50aWFsIG1vZGVscyBmb3IgdGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcyBpbnZvbHZlZCB1c2luZyB0aGUgZXh0ZW5kZWQgQUNGIGZ1bmN0aW9uLCBvciBFQUNGLiBSdW5uaW5nIHRoZSBFQUNGIGZ1bmN0aW9uIG9uIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzIHJlc3VsdGVkIGluIGFuIGVycm9yLCB3aGljaCB3YXMgb3ZlcmNvbWUgYnkgc3BlY2lmeWluZyB0aGUgbWF4aW11bSB2YWx1ZXMgZm9yIEFSIGFuZCBNQSBpbiB0aGUgRUFDRiBmdW5jdGlvbi4gVGhlIHJlc3VsdGluZyBvdXRwdXQgaXMgc2hvd24gaW4gVGFibGUgMTIuDQoNCmBgYHtyfQ0KIyBlYWNmKGljZV9kaWZmMikgI0VSUk9SOiByZXF1aXJlcyBudW1lcmljL2NvbXBsZXggbWF0cml4L3ZlY3RvciBhcmd1bWVudHMNCiMgZWFjZihpY2VfZGlmZjIsIGFyLm1heCA9IDUsIG1hLm1heCA9IDUpICNFUlJPUjogcmVxdWlyZXMgbnVtZXJpYy9jb21wbGV4IG1hdHJpeC92ZWN0b3IgYXJndW1lbnRzDQplYWNmKGljZV9kaWZmMiwgYXIubWF4ID0gNCwgbWEubWF4ID0gMykNCmBgYA0KVGFibGUgMTI6IEVBQ0YgcGxvdCBvZiB0aGUgc2Vjb25kIGRpZmZlcmVuY2VkIEFudGFyY3RpYyBJY2Ugc2VyaWVzLg0KDQpUaGUgbW9zdCB0b3AtbGVmdCBwb2ludCBpbiB0aGUgRUFDRiBwbG90IHdhcyBzZWxlY3RlZCBhcyAoMCwwKSwgYW5kIHRoZSBtb2RlbHMgcHJvcG9zZWQgdXNpbmcgdGhlIEVBQ0YgcGxvdCB3ZXJlOg0KDQoqIHsgQVJJTUEoMCwyLDApLCBBUklNQSgwLDIsMSkgfQ0KDQpJdCBzaG91bGQgYmUgbm90ZWQgdGhhdCB0aGUgQVJJTUEoMCwyLDApIG1vZGVsIHdpbGwgaGF2ZSBubyBjb2VmZmljaWVudHMuIFRyZW5kIG1vZGVsbGluZyB3b3VsZCBiZSB1c2VkIHRvIHNlZSBpZiB0aGlzIG1vZGVsIGNhcHR1cmVzIHRoZSBhdXRvY29ycmVsYXRpb24gaW4gdGhlIHNlcmllcy4NCg0KIyMjIEJJQw0KVGhlIHRoaXJkIHN0ZXAgaW4gaWRlbnRpZnlpbmcgcG90ZW50aWFsIG1vZGVscyBmb3IgdGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcyB3YXMgdG8gdXNlIHRoZSBCYXllc2lhbiBJbmZvcm1hdGlvbiBDcml0ZXJpb24sIG9yIOKAnEJJQ+KAnSwgdG8gcHJvcG9zZSB2YWx1ZXMgZm9yIOKAnHDigJ0gYW5kIOKAnHHigJ0uDQoNClRoZSBCSUMgcGxvdCB3YXMgZmlyc3QgcHJvZHVjZWQgdXNpbmcgdmFsdWVzIG9mIDEwIGZvciDigJhubWHigJkgYW5kIOKAmG5hcuKAmSBob3dldmVyLCB0aGlzIHJlc3VsdGVkIGluIGFuIGVycm9yLiBBcyBpdCB3YXMga25vd24gZnJvbSB0aGUgQUNGLCBQQUMsIGFuZCBFQUNGIHBsb3RzIHRoYXQgdGhlIG9yZGVycyBvZiDigJxw4oCdIGFuZCDigJxx4oCdIHdvdWxkIGxpa2VseSBiZSBzbWFsbCwgdGhlIHZhbHVlcyBvZiDigJhubWHigJkgYW5kIOKAmG5hcuKAmSB3ZXJlIHJlZHVjZWQgdG8gNSwgYW5kIHRoZW4gdG8gMywgd2l0aCB0aGUgcmVzdWx0aW5nIEJJQyBwbG90cyBzaG93biBpbiBGaWd1cmUgMTMgYW5kIEZpZ3VyZSAxNCwgcmVzcGVjdGl2ZWx5Lg0KDQpgYGB7cn0NCiNyZXMgPSBhcm1hc3Vic2V0cyh5PWljZV9kaWZmMiwgbmFyPTEwLCBubWE9MTAsIHkubmFtZT0ncCcsIGFyLm1ldGhvZD0nb2xzJykgI0VSUk9Scw0KI3Bsb3QocmVzKSAjRVJST1JzDQojIyBldmlkZW5jZSBzbyBmYXIgc3VnZ2VzdHMgcCBhbmQgcSB3aWxsIGJlIHNtYWxsLCBzbyB0cnkgd2l0aCBhIHJlZHVjZWQgdmFsdWUgZm9yICdubWEnIGFuZCAnbmFyJy4NCnJlczIgPSBhcm1hc3Vic2V0cyh5PWljZV9kaWZmMiwgbmFyPTUsIG5tYT01LCB5Lm5hbWU9J3AnLCBhci5tZXRob2Q9J29scycpDQpwbG90KHJlczIpICMgYWxnb3JpdGhtIGhpdHMgYSBCSUMgdmFsdWUgdGhhdCB3YXMgTmFODQpgYGANCkZpZ3VyZSAxMzogQklDIHBsb3Qgb2YgdGhlIHNlY29uZCBkaWZmZXJlbmNlZCBBbnRhcmN0aWMgSWNlIHNlcmllcywgdXNpbmcg4oCYbmFy4oCZIGFuZCDigJhubWHigJkgdmFsdWVzIG9mIDUuDQoNCmBgYHtyfQ0KIyBldmlkZW5jZSBzbyBmYXIgc3VnZ2VzdHMgcCBhbmQgcSB3aWxsIGJlIHNtYWxsLCBzbyB0cnkgd2l0aCBhIGZ1cnRoZXIgcmVkdWNlZCB2YWx1ZSBmb3IgJ25tYScgYW5kICduYXInLg0KcmVzMyA9IGFybWFzdWJzZXRzKHk9aWNlX2RpZmYyLCBuYXI9Mywgbm1hPTMsIHkubmFtZT0ncCcsIGFyLm1ldGhvZD0nb2xzJykNCnBsb3QocmVzMykgIyBhbGdvcml0aG0gaGl0cyBhIEJJQyB2YWx1ZSB0aGF0IHdhcyBpbmYNCmBgYA0KRmlndXJlIDE0OiBCSUMgcGxvdCBvZiB0aGUgc2Vjb25kIGRpZmZlcmVuY2VkIEFudGFyY3RpYyBJY2Ugc2VyaWVzLCB1c2luZyDigJhuYXLigJkgYW5kIOKAmG5tYeKAmSB2YWx1ZXMgb2YgMy4NCg0KVGhlIEJJQyBwbG90IHdpdGggdmFsdWVzIG9mIDMgZm9yIOKAmG5hcuKAmSBhbmQg4oCYbm1h4oCZIChGaWd1cmUgMTQpIHByb3Bvc2VkIG1vZGVscyB0aGF0IHdlcmUgaW4tbGluZSB3aXRoIHRoZSBBQ0YsIFBBQ0YsIGFuZCBFQUNGIHBsb3RzLCBzbyBpdCB3YXMgc2VsZWN0ZWQgZm9yIHVzZSBpbiBwcm9wb3NpbmcgbW9kZWxzIGZvciB0aGUgc2Vjb25kIGRpZmZlcmVuY2VkIHNlcmllcy4NCg0KVGhlIG1vZGVsIHByb3Bvc2FscyBmcm9tIHRoZSBCSUMgbW9kZWwgc3BlY2lmaWNhdGlvbiBtZXRob2Qgd2VyZToNCg0KKiB7IEFSSU1BKDEsMiwxKSwgQVJJTUEoMiwyLDEpLCBBUklNQSgzLDIsMSksIEFSSU1BKDEsMiwwKSwgQVJJTUEoMiwyLDApIH0NCg0KIyMgUmVzdWx0cyANCiMjIyBGaW5hbCBzZXQgb2YgcG9zc2libGUgbW9kZWxzDQpUaGUgZmluYWwgc2V0IG9mIHBvc3NpYmxlIG1vZGVscyBmb3IgdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBzZXJpZXMgd2FzOg0KDQoqIHsgQVJJTUEoMSwyLDApLCANCiogQVJJTUEoMiwyLDApLA0KKiBBUklNQSgxLDIsMSksIA0KKiBBUklNQSgyLDIsMSksDQoqIEFSSU1BKDAsMiwwKSwgDQoqIEFSSU1BKDAsMiwxKSwNCiogQVJJTUEoMywyLDEpIH0NCg0KTW9zdCBvZiB0aGVzZSBtb2RlbHMgbWFkZSBzZW5zZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgZGF0YSBleHBsb3JhdGlvbiwgd2hpY2ggaWRlbnRpZmllZCBhdXRvcmVncmVzc2l2ZSBiZWhhdmlvdXIgaW4gdGhlIHJhdyBBbnRhcmN0aWNhIEljZSBzZXJpZXMgKGkuZS4sIOKAnHDigJ0gd291bGQgbGlrZWx5IGJlIG5vbi16ZXJvKSBhbmQgbm8gY2xlYXIgZXZpZGVuY2Ugb2YgbW92aW5nIGF2ZXJhZ2UgYmVoYXZpb3VyIChpLmUuLCDigJxx4oCdIHdvdWxkIGxpa2VseSBiZSBsb3cgb3IgemVybykuIEl0IHNob3VsZCBiZSBub3RlZCB0aGF0IHRoZSBBUklNQSgwLDIsMCkgbW9kZWwgd2lsbCBoYXZlIG5vIGNvZWZmaWNpZW50cywgYW5kIHRyZW5kIG1vZGVsbGluZyB3b3VsZCBiZSByZXF1aXJlZCB0byBzZWUgaWYgdGhpcyBtb2RlbCBjYXB0dXJlcyB0aGUgYXV0b2NvcnJlbGF0aW9uIGluIHRoZSBzZXJpZXMuDQoNClRoZSBmb2xsb3dpbmcgbW9kZWxzIHdlcmUgcHJvcG9zZWQgYnkgbW9yZSB0aGFuIG9uZSBtb2RlbCBzcGVjaWZpY2F0aW9uIG1ldGhvZDsNCg0KKiB7IEFSSU1BKDEsMiwwKSwgDQoqIEFSSU1BKDIsMiwwKSwNCiogQVJJTUEoMSwyLDEpLCANCiogQVJJTUEoMiwyLDEpIH0NCg0KRnVydGhlciB0ZXN0aW5nLCBpbmNsdWRpbmcgZGlhZ25vc3RpYyBjaGVja2luZywgd291bGQgYmUgcmVxdWlyZWQgdG8gaWRlbnRpZnkgdGhlIG9wdGltYWwgbW9kZWwgZnJvbSB0aGUgc2V0IG9mICBwcm9wb3NlZCBtb2RlbHMuDQoNCiMjIFN1bW1hcnkgJiBDb25jbHVzaW9uIA0KVGhlIG9iamVjdGl2ZSBvZiB0aGUgYW5hbHlzaXMgYW5kIG1vZGVsIHNwZWNpZmljYXRpb24gY29uZHVjdGVkIHdhcyB0byB1bmRlcnN0YW5kIHRoZSBBbnRhcmN0aWNhIGxhbmQgaWNlIG1hc3MgZGF0YXNldCwgYW5kIHRvIHByb3Bvc2UgYSBzZXQgb2YgcG9zc2libGUgQVJJTUEocCxkLHEpIG1vZGVscyBmb3IgdGhlIHNlcmllcy4NCg0KRXhwbG9yYXRpb24gb2YgdGhlIEFudGFyY3RpY2EgbGFuZCBpY2UgbWFzcyBkYXRhc2V0IHJldmVhbGVkIGEgbGFyZ2UgcmFuZ2UgYW5kIGEgbWVhbiBjaGFuZ2Ugb2YgLTEsMDYzLjc3IGJpbGxpb24gbWV0cmljIHRvbnMsIHJlbGF0aXZlIHRvIHRoZSBpY2UgbWFzcyBpbiAyMDAxLiANCg0KQW5hbHlzaXMgb2YgdGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcyBpZGVudGlmaWVkIHRoYXQgdGhlIHNlcmllcyBleGhpYml0ZWQgYSBjbGVhciBkb3dud2FyZCB0cmVuZCBhbmQgYXV0b3JlZ3Jlc3NpdmUgYmVoYXZpb3VyIChzdWNjZXNzaXZlIHBvaW50cyksIHdpdGggbm8gY2xlYXIgc2lnbnMgb2Ygc2Vhc29uYWxpdHksIGNoYW5naW5nIHZhcmlhbmNlLCBvciBhIGNoYW5nZSBwb2ludC4gQSBoaWdoIGNvcnJlbGF0aW9uIGJldHdlZW4gbmVpZ2hib3VyaW5nIHBvaW50cyB3YXMgYWxzbyBpZGVudGlmaWVkLCB3aGljaCBhbGlnbmVkIHdpdGggdGhlIGF1dG9jb3JyZWxhdGlvbiBiZWhhdmlvdXIgb2JzZXJ2ZWQgd2hlbiB0aGUgc2VyaWVzIHdhcyBwbG90dGVkLg0KDQpBQ0YgYW5kIFBBQ0YgcGxvdHMgb2YgdGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcyBpZGVudGlmaWVkIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbiBsYWdzLCBhbmQgYSBzaW5nbGUsIHZlcnkgc2lnbmlmaWNhbnQgcGFydGlhbCBhdXRvY29ycmVsYXRpb24gbGFnLCBpbmRpY2F0aXZlIG9mIGEgbm9uLXN0YXRpb25hcnkgc2VyaWVzLiBGdXJ0aGVyIHRlc3RzIGNvbmZpcm1lZCB0aGF0IHRoZSByYXcgc2VyaWVzIHdhcyBub3Qgc3RhdGlvbmFyeSwgYnV0IHRoYXQgdGhlIG1lYXN1cmVtZW50cyBpbiB0aGUgc2VyaWVzIHdlcmUgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KQWx0aG91Z2ggdGhlIHNlcmllcyBkaWQgbm90IGV4aGliaXQgY2hhbmdpbmcgdmFyaWFuY2UsIGEgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZCB0byB0aGUgc2VyaWVzIHRvIG9ic2VydmUgaXRzIGltcGFjdC4gVmlzdWFsIGluc3BlY3Rpb24sIGEgU2hhcGlyby1XaWxrIHRlc3QsIGFuZCBhIHVuaXQgcm9vdCB0ZXN0IGlkZW50aWZpZWQgdGhhdCB0aGUgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiBkaWQgbm90IGNoYW5nZSB0aGUgc2VyaWVzIG11Y2gsIHNvIHRoZSB0cmFuc2Zvcm1hdGlvbiB3YXMgZGVlbWVkIHVubmVjZXNzYXJ5Lg0KDQpEaWZmZXJlbmNpbmcgd2FzIHRoZW4gYXBwbGllZCB0byB0aGUgcmF3IHNlcmllcyB0byBhZGRyZXNzIHRoZSB0cmVuZCBpbiB0aGUgc2VyaWVzLiBWaXN1YWwgaW5zcGVjdGlvbiBhbmQgYSB1bml0IHJvb3QgdGVzdCBjb25maXJtZWQgdGhhdCBmaXJzdCBkaWZmZXJlbmNpbmcgZGlkIG5vdCBvdmVyY29tZSB0aGUgbm9uLXN0YXRpb25hcml0eSwgYW5kIHNvIHNlY29uZCBkaWZmZXJlbmNpbmcgd2FzIGFwcGxpZWQuIEFsdGhvdWdoIHRoZSBBdWdtZW50ZWQgRGlja2V5LUZ1bGxlciB0ZXN0IG9mIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIHN1Z2dlc3RlZCB0aGUgc2VyaWVzIHdhcyBzdGlsbCBub24tc3RhdGlvbmFyeSwgdmlzdWFsIGluc3BlY3Rpb24sIGFuZCBmdXJ0aGVyIHVuaXQgcm9vdCB0ZXN0cyAoUFAgYW5kIEtQU1MpIGNvbmZpcm1lZCB0aGF0IHNlY29uZCBkaWZmZXJlbmNpbmcgaGFkIG1hZGUgDQp0aGUgc2VyaWVzIHN0YXRpb25hcnkuIEFzIHN1Y2gsIHRoZSBzZWNvbmQgZGlmZmVyZW5jZWQgc2VyaWVzIHdhcyBjaG9zZW4gZm9yIHVzZSBpbiBtb2RlbCBzcGVjaWZpY2F0aW9uLiANCg0KQUNGLCBQQUNGLCBFQUNGIGFuZCBCSUMgbW9kZWwgc3BlY2lmaWNhdGlvbiB0b29scyB3ZXJlIHVzZWQgdG8gcHJvcG9zZWQgc3VpdGFibGUgQVJJTUEocCxkLHEpIG1vZGVscyBmb3IgdGhlIEFudGFyY3RpY2EgSWNlIHNlcmllcywgd2l0aCB0aGUgZmluYWwgc2V0IG9mIHByb3Bvc2VkIG1vZGVscyBjb250YWluaW5nIDcgQVJJTUEocCxkLHEpIG1vZGVsczsNCg0KeyBBUklNQSgxLDIsMCksIEFSSU1BKDIsMiwwKSwgQVJJTUEoMSwyLDEpLCBBUklNQSgyLDIsMSksIEFSSU1BKDAsMiwwKSwgQVJJTUEoMCwyLDEpLCBBUklNQSgzLDIsMSkgfS4NCg0KPGJyPg0KPGJyPg==