Assignment Objectives

  • Understand the theoretical basis of Bootstrap sampling methods for approximating sampling distributions.

  • Assess the performance of Bootstrap sampling distributions against exact and asymptotic sampling distributions.

  • Implement Bootstrap sampling algorithm and construct sampling distributions using R.


Use of AI Tools

Policy on AI Tool Use: Students must adhere to the AI tool policy specified in the course syllabus. The direct copying of AI-generated content is strictly prohibited. All submitted work must reflect your own understanding; where external tools are consulted, content must be thoroughly rephrased and synthesized in your own words.

Code Inclusion Requirement: Any code included in your essay must be properly commented to explain the purpose and/or expected output of key code lines. Submitting AI-generated code without meaningful, student-added comments will not be accepted.


Asymptotic Distribution of Sample Variance

Assume that \(\{ x_1, x_2, \cdots, x_n \} \to F(x)\) with \(\mu = E[X]\) and \(\sigma^2 = \text{var}(X)\). Denote

\[ s^2 = \frac{1}{n-1}\sum_{i=1}^n (x_i - \mu)^2 \]

If \(n\) is large,

\[ s^2 \to N\left(\sigma^2, \frac{\mu_4-\sigma^4}{n} \right) \]

where \(\mu_4 = E[(X_i - \mu)^4]\) is tje 4th central moment which can be estimated by

\[ \hat{\mu}_4 = \frac{1}{n}\sum_{i=1}^n(x_i-\bar{x})^4. \]

Note: This describes the asymptotic convergence of the sample variance, following from the central limit theorem (CLT). The sample size required for this approximation to hold is situation-dependent.


Question 1: Asymptotic vs Bootstrap Sampling Distributions

Write an essay summarizing the concepts of Asymptotic and Bootstrap Sampling Distributions, along with their key applications. Your discussion should be grounded in your personal understanding of the material. Any external sources including AI tools consulted must be clearly cited.

Essay Prompt: Discuss the concepts of the bootstrap sampling plan, the bootstrap sampling distribution, and the asymptotic sampling distribution in the context of statistics (e.g., sample mean and variance) computed from an independent and identically distributed (i.i.d.) sample. Your discussion should:

  • Clearly outline the key assumptions required for each method.

  • Explain the practical application of each distribution.

  • Provide guidance on when and why one should be preferred over the other in statistical inference.

Essay on Boostrap vs. Asymptotic Sampling Distribution

The bootstrap sampling distribution and the asymptotic sampling distribution are involved in two contrasting methods of approximating the sampling distribution for a specific statistic (mean, variance, etc.). For ease of understanding, let’s consider an example to walk through the assumptions underpinning each method, the practical application of these distributions, and finally conclude with a discussion of when these distributions should be used.

Suppose we have a six-sided die, and we are hoping to approximate the sampling distribution of the sample means of this six-sided die. Now, we may know intuitively that the distribution of a die would follow a Discrete Uniform Distribution between the values of 1 and 6. That is to say, if we were to roll a six-sided die we would expect to see some value between 1 and 6 with an equal probability of the die landing on each of these values. However, suppose we wanted to take a sample of these values and use that sample to find a sample mean. And then suppose that we took this sample again and again, finding the sample means for multiple different samples. Would we expect this distribution of sample means to follow a uniform distribution? Below is a histogram of 1000 sample means, each taken from a simulated sample of size 30:

set.seed(123)  #Used to set seed so that result can be replicated
n <- 30
samples <- 1000 

die <- replicate(samples, mean(runif(n, min=1, max=6))) #Samples from a discrete uniform distribution the amount of times indicated by 'samples' and at sample size 'n' to find mean values for each sample


hist(die, breaks=20, prob=TRUE, main="Histogram of Sample Means of 6-sided Dice", xlab="Sample Means", xlim=c(2,5)) #Creates histogram of sample means

This result doesn’t appear uniform at all! Which leads us to the question of how we should we go about approximating the distribution of sample means (or any statistic for that matter). To answer that question we will consider two methods, one involving the asymptotic sampling distribution and the other involving the bootstrap sampling distribution.

The asymptotic sampling distribution relies on the concept that as the sample size (\(n\)) approaches infinity, the distribution of a specific statistic can be approximated in a specific way. Most commonly, the asymptotic sampling distribution is discussed in relation to the Central Limit Theorem (CLT). The Central Limit Theorem holds that, for many statistics, the asymptotic sampling distribution turns out to be a normal distribution. However, in order to assume that it is appropriate to use an asymptotic sampling distribution we must first ensure that our observations are independent and identically distributed and that our \(n\) is sufficiently large. In order to use the CLT in particular, we must also know that our samples come a population with a finite mean \(\mu\) and variance \(\sigma^2\). In our example, we know that our observations are independent (one roll of the die does not affect the other) and identically distributed (our results are coming from the same population). Furthermore, we know that there is some finite \(\mu\) and \(\sigma^2\) since our observations can only be between 1 and 6. The only question to whether or not we can use the Central Limit Theorem and the associated normal asymptotic sampling distribution is the sample size.

In our previous example we used a sample size of 30. In most cases this is considered an appropriate sample size for using the CLT. However, for the sake of understanding the importance of this large sample size, lets instead imagine that we only used a sample size of 2:

set.seed(2) #Used to set seed so that result can be replicated
n <- 2
mu <- 3.5
sigma <- 1.7078
samples <- 100

die <- replicate(samples, mean(runif(n, min=1, max=6))) #Samples from a discrete uniform distribution the amount of times indicated by 'samples' and at sample size 'n' to find mean values for each sample

x <- seq(mu - 3*sigma/sqrt(n), mu + 3*sigma/sqrt(n), length.out = 100) #Used to later create normal curve based on 'mu' and 'sigma'
nc <- dnorm(x, mu, sd=sigma/sqrt(n))

hist(die, breaks=seq(min(die), max(die), length.out=20), prob=TRUE, main="Histogram of Sample Means of 6-sided Dice (n = 2)", xlab="Sample Means", xlim=c(1,6))
lines(x, nc, col="red", lwd=2) #Creates histogram of sample means

An appropriate normal curve is overlayed over our histogram. However, we can see that our resulting sample means don’t appear to closely follow the the normal curve. On the other hand, what if we were to choose a significantly higher \(n\) of 100:

set.seed(123) #Used to set seed so that result can be replicated
n <- 100
mu <- 3.5
sigma <- 1.7078
samples <- 100

die <- replicate(samples, mean(runif(n, min=1, max=6))) #Samples from a discrete uniform distribution the amount of times indicated by 'samples' and at sample size 'n' to find mean values for each sample

x <- seq(mu - 3*sigma/sqrt(n), mu + 3*sigma/sqrt(n), length.out = 100) #Used to later create normal curve based on 'mu' and 'sigma'
nc <- dnorm(x, mu, sd=sigma/sqrt(n))

hist(die, breaks=seq(min(die), max(die), length.out=7), prob=TRUE, main="Histogram of Sample Means of 6-sided Dice (n = 100)", xlab="Sample Means", xlim=c(2,5))
lines(x, nc, col="red", lwd=2) #Creates histogram of sample means

Here we can see our histogram much more closely follows the appropriate normal curve. This is a visual example of why our assumption of a large \(n\) is fundamental to using an asymptotic sampling distribution. This also serves to demonstrate how an asymptotic sampling distribution could be used, specifically in regards to the CLT. In practice, we wouldn’t necessarily have the ability to repeatedly sample our population. However, by using the CLT (as long as the associated assumptions are met) we are able to safely assume that our sample means will approximately follow the following distribution:

\[ \bar{X} \rightarrow N(\mu, \frac{\sigma}{\sqrt{n}}) \] Where \(\bar{X}\) is the sample mean. A similar assumption can be made in regards to the distribution of the sample variance using the CLT:

\[ s^2 \to N\left(\sigma^2, \frac{\mu_4-\sigma^4}{n} \right) \]

Where \(s^2\) is the sample variance and \(\mu_4\) is the 4th central moment.

In contrast to the asymptotic sampling distribution, the bootstrap sampling distribution relies a fundamentally different method of approximating the sample distribution for a statistic. Instead of relying on the idea that as sample size gets larger it may become possible to approximate the true distribution of a sample statistic, the bootstrap sampling distribution is found by resampling the existing sample in order to estimate the true distribution of a sample statistic.

Much like the asymptotic sampling distribution, there are several assumptions that must be met in order for our bootstrap sampling distribution to accurately approximate the true sample statistic distribution. It assumes that our observations are independent and identically distributed. Furthermore, it also has some requirements regarding the size of the sample, given that it is harder to treat the sample as an accurate substitute for the population with a smaller sample size. However, these requirements are less stringent (especially when the population is heavily skewed) than with the Central Limit Theorem. Once again going back to our six-sided die example, we already know our observations are independent and identically distributed. In the following example we will also use a sample size of 50 in order to ensure our bootstrap sample distribution is an accurate approximation.

In order to perform bootstrap sampling and obtain our bootstrap distribution we will repeatedly randomly sample, with replacement, from an already existing sample. Below we will simulate a random sample of 50 rolls of a six sided and then randomly sample from this sample 1000 times. We will then use the resulting sample means to form the bootstrap distribution. The results of our analysis can be seen below:

set.seed(123) #Used to set seed so that result can be replicated
n <- 50
die2 <- runif(n, min=1, max=6) #Samples from a discrete uniform distribution a sample of size 'n'
B <- 1000

bootstrap.means <- numeric(B) #Resets 'bootstrap.means' 

for (i in 1:B){
  boot.sample <- sample(die2, size=n, replace=TRUE)
  bootstrap.means[i] <- mean(boot.sample)
} #Used to randomly sample (with replacement) from 'die2' 'B' times to get sample means

kde.die <- density(bootstrap.means)

hist(bootstrap.means, prob=TRUE, main="Bootstrap Sampling Distribution of 6-sided Die", xlab="Sample Means", xlim=c(2,5))
lines(kde.die, col="red", lwd=2) #Used to create histogram of bootstrap sampling distribution

As stated, we randomly sampled our initial simulated sample of 50 observations, 1000 times. This allows us to form the Bootstrap Sampling Distribution of our 6-sided die based on our one sample.

Finally, its worth considering, given the similarities between the assumptions of these two distributions, why we would choose to use one over the other. The asymptotic sampling distribution most accurately models symmetric, non skewed data. While it can be used to model skewed data, it often requires a larger sample size to achieve an accurate result. However, it is not as computationally intensive to use as the bootstrap sampling distribution. Conversely, the bootstrap sampling distribution can be more accurate than the asymptotic sampling distribution when applied to heavily skewed data and complex or unknown distributions. However, it takes a lot of computational power to accurately model, since it requires repeated resampling to obtain. Ultimately, it is important to know both the limitations and applications of both in order most accurately model the sampling distributions of sampling statistics.

Sources:

https://pengdsci.github.io/STA506/w03/03-SamplingDistributions.html

https://pengdsci.github.io/STA506/w04/04-ECDandBootstrapSampling.html

Question 2: Daily Coffee Sales (in mL) at Two Different Cafe Locations

This data set represents the volume of regular brewed coffee sold per day (in milliliters) at two different cafe locations over a period of 50 days.

2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500

We are interested in finding the sampling distribution of sample means that will be used for various inferences about the underlying population mean.

  1. Based on the given data, can the Central Limit Theorem be used to derive the asymptotic sampling distribution of the sample mean? Justify your answer.

Answer to Part A

In order to use the Central Limit Theorem to derive the asymptotic sampling distribution of the sample mean we need independent, identically distributed observations from a population with a finite \(\mu\) and \(\sigma^2\) and enough observations that we can justify using the Central Limit Theorem. The observations are from a single population of cafes so we can assume the observations are identically distributed. There is a finite amount of coffee that can be brewed per day so we can assume that there is a finite \(\mu\) and \(\sigma^2\). Finally, there appear to be enough observations to use the Central Limit Theorem, given that the sample size of 54 is greater than the typical CLT cutoff of 30. However, the question does not provide information on whether or not the observations were part of a random sample so we do not have enough evidence to state that the observations are independent of one another. That being said, if the observations are from a random sample then we should meet the conditions to use the CLT.

  1. Apply the bootstrap method to estimate the sampling distribution (often called the bootstrap sampling distribution) of the sample mean. Generate a kernel density estimate from the bootstrap sample means and plot it. Then, use this bootstrap distribution to validate your conclusion from part (a). Make sure your visuals are effective in enhancing the presentation of these results.

Answer to Part B

set.seed(123) #Used to set seed so that result can be replicated
coffee <-  c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500)

n <- length(coffee)
B <- 1000

bootstrap.means <- numeric(B) #Resets 'bootstrap.means' 

for (i in 1:B){
  boot.sample <- sample(coffee, size=n, replace=TRUE)
  bootstrap.means[i] <- mean(boot.sample) #Used to randomly sample (with replacement) from 'coffee' 'B' times to get sample means
}

kde.coffee <- density(bootstrap.means) #Makes KDE of bootstrap sample means

x <- seq(mean(bootstrap.means) - 3*sd(bootstrap.means), mean(bootstrap.means) + 3*sd(bootstrap.means), length.out = 100)
nc <- dnorm(x, mean(bootstrap.means), sd=sd(bootstrap.means)) #Used to later create normal curve

plot(kde.coffee, main = "KDE from Bootstrap Sample Means", xlab = "Sample Means", col="blue")
lines(x, nc, col="red") #Used to create histogram of bootstrap sampling distribution

Above, in blue, is the KDE from the bootstrap sampling distribution of sample means obtained by using the bootstrap method. As we can see, it fairly closely follows the normal curve (in red), indicating that there is evidence that it would be appropriate to use the Central Limit Theorem.

  1. Repeat the analysis in parts (a) and (b) for the sample variance.

Answer to Part C

As stated previously, in order to use the Central Limit Theorem to derive the asymptotic sampling distribution of the sample mean we need independent, identically distributed observations from a population with a finite \(\mu\) and \(\sigma^2\) and enough observations that we can justify using the Central Limit Theorem. Since this is the same random sample as used previously, we can assume the observations are identically distributed with a finite \(\mu\) and \(\sigma^2\) and there are enough observations to use the CLT. However, we are still unsure of independence.

set.seed(123) #Used to set seed so that result can be replicated
coffee <-  c(2850, 3200, 2900, 3100, 2950, 7800, 8100, 7900, 3300, 3050, 4000, 4200, 3150, 3400, 7700, 8200, 
3250, 4400, 3100, 4200, 4500, 4800, 4300, 8500, 8200, 8900, 8700, 3250, 3000, 4600, 4100, 8400, 
8800, 3350, 4700, 3100, 8100, 3050, 8300, 4100, 3100, 8300, 8900, 8200, 4400, 4500, 3250, 4600, 
8400, 3300, 4200, 4500, 4800, 4300, 8500)

n <- length(coffee)
B <- 1000

bootstrap.variances <- numeric(B) #Resets 'bootstrap.variances' 

for (i in 1:B){
  boot.sample <- sample(coffee, size=n, replace=TRUE)
  bootstrap.variances[i] <- var(boot.sample)
} #Used to randomly sample (with replacement) from 'coffee' 'B' times to get sample variances

x <- seq(mean(bootstrap.variances) - 3*sd(bootstrap.variances), mean(bootstrap.variances) + 3*sd(bootstrap.variances), length.out = 100)
nc <- dnorm(x, mean(bootstrap.variances), sd=sd(bootstrap.variances)) #Used to later create normal curve

kde.coffee <- density(bootstrap.variances) #Makes KDE of bootstrap sample variances

plot(kde.coffee, main = "KDE from Bootstrap Sample Variances", xlab="Sample Variances", col="blue")
lines(x, nc, col="red") #Used to create histogram of bootstrap sampling distribution

Above, in blue, is the KDE from the bootstrap sampling distribution of sample variances obtained by using the bootstrap method. Similar to the KDE from the bootstrap sampling distribution of sample means, it fairly closely follows the normal curve (in red), indicating that there is evidence that it would be appropriate to use the Central Limit Theorem.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMzogRUNERiBhbmQgQm9vdHN0cmFwIFNhbXBsaW5nIGFuZCBBcHBsaWNhdGlvbnMiDQphdXRob3I6ICJHcmFjZSBMaXBwZXJ0ICINCmRhdGU6ICIgRHVlOiAyLzE3LzIwMjYgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIFVuZGVyc3RhbmQgdGhlIHRoZW9yZXRpY2FsIGJhc2lzIG9mIEJvb3RzdHJhcCBzYW1wbGluZyBtZXRob2RzIGZvciBhcHByb3hpbWF0aW5nIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMuDQoNCiogQXNzZXNzIHRoZSBwZXJmb3JtYW5jZSBvZiBCb290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBhZ2FpbnN0IGV4YWN0IGFuZCBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMuDQoNCiogSW1wbGVtZW50IEJvb3RzdHJhcCBzYW1wbGluZyBhbGdvcml0aG0gYW5kIGNvbnN0cnVjdCBzYW1wbGluZyBkaXN0cmlidXRpb25zIHVzaW5nIFIuDQoNClwNCg0KKipVc2Ugb2YgQUkgVG9vbHMqKg0KDQoqKlBvbGljeSBvbiBBSSBUb29sIFVzZSoqOiBTdHVkZW50cyBtdXN0IGFkaGVyZSB0byB0aGUgQUkgdG9vbCBwb2xpY3kgc3BlY2lmaWVkIGluIHRoZSBjb3Vyc2Ugc3lsbGFidXMuIFRoZSBkaXJlY3QgY29weWluZyBvZiBBSS1nZW5lcmF0ZWQgY29udGVudCBpcyBzdHJpY3RseSBwcm9oaWJpdGVkLiBBbGwgc3VibWl0dGVkIHdvcmsgbXVzdCByZWZsZWN0IHlvdXIgb3duIHVuZGVyc3RhbmRpbmc7IHdoZXJlIGV4dGVybmFsIHRvb2xzIGFyZSBjb25zdWx0ZWQsIGNvbnRlbnQgbXVzdCBiZSB0aG9yb3VnaGx5IHJlcGhyYXNlZCBhbmQgc3ludGhlc2l6ZWQgaW4geW91ciBvd24gd29yZHMuDQoNCioqQ29kZSBJbmNsdXNpb24gUmVxdWlyZW1lbnQqKjogQW55IGNvZGUgaW5jbHVkZWQgaW4geW91ciBlc3NheSBtdXN0IGJlIHByb3Blcmx5IGNvbW1lbnRlZCB0byBleHBsYWluIHRoZSBwdXJwb3NlIGFuZC9vciBleHBlY3RlZCBvdXRwdXQgb2Yga2V5IGNvZGUgbGluZXMuIFN1Ym1pdHRpbmcgQUktZ2VuZXJhdGVkIGNvZGUgd2l0aG91dCBtZWFuaW5nZnVsLCBzdHVkZW50LWFkZGVkIGNvbW1lbnRzIHdpbGwgbm90IGJlIGFjY2VwdGVkLg0KDQpcDQoNCioqQXN5bXB0b3RpYyBEaXN0cmlidXRpb24gb2YgU2FtcGxlIFZhcmlhbmNlKioNCg0KQXNzdW1lIHRoYXQgJFx7IHhfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcdG8gRih4KSQgd2l0aCAkXG11ID0gRVtYXSQgYW5kICRcc2lnbWFeMiA9IFx0ZXh0e3Zhcn0oWCkkLiBEZW5vdGUgDQoNCiQkDQpzXjIgPSBcZnJhY3sxfXtuLTF9XHN1bV97aT0xfV5uICh4X2kgLSBcbXUpXjINCiQkDQoNCklmICRuJCBpcyBsYXJnZSwgDQoNCiQkDQpzXjIgXHRvIE5cbGVmdChcc2lnbWFeMiwgIFxmcmFje1xtdV80LVxzaWdtYV40fXtufSBccmlnaHQpDQokJA0KDQp3aGVyZSAkXG11XzQgPSBFWyhYX2kgLSBcbXUpXjRdJCBpcyB0amUgNHRoIGNlbnRyYWwgbW9tZW50IHdoaWNoIGNhbiBiZSBlc3RpbWF0ZWQgYnkNCg0KJCQNClxoYXR7XG11fV80ID0gXGZyYWN7MX17bn1cc3VtX3tpPTF9Xm4oeF9pLVxiYXJ7eH0pXjQuDQokJA0KDQoqKk5vdGUqKjogVGhpcyBkZXNjcmliZXMgdGhlIGFzeW1wdG90aWMgY29udmVyZ2VuY2Ugb2YgdGhlIHNhbXBsZSB2YXJpYW5jZSwgZm9sbG93aW5nIGZyb20gdGhlIGNlbnRyYWwgbGltaXQgdGhlb3JlbSAoQ0xUKS4gVGhlIHNhbXBsZSBzaXplIHJlcXVpcmVkIGZvciB0aGlzIGFwcHJveGltYXRpb24gdG8gaG9sZCBpcyBzaXR1YXRpb24tZGVwZW5kZW50Lg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbiAxOiBBc3ltcHRvdGljIHZzIEJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb25zKioNCg0KV3JpdGUgYW4gZXNzYXkgc3VtbWFyaXppbmcgdGhlIGNvbmNlcHRzIG9mIEFzeW1wdG90aWMgYW5kIEJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb25zLCBhbG9uZyB3aXRoIHRoZWlyIGtleSBhcHBsaWNhdGlvbnMuIFlvdXIgZGlzY3Vzc2lvbiBzaG91bGQgYmUgZ3JvdW5kZWQgaW4geW91ciBwZXJzb25hbCB1bmRlcnN0YW5kaW5nIG9mIHRoZSBtYXRlcmlhbC4gQW55IGV4dGVybmFsIHNvdXJjZXMgaW5jbHVkaW5nIEFJIHRvb2xzIGNvbnN1bHRlZCBtdXN0IGJlIGNsZWFybHkgY2l0ZWQuIA0KDQoNCioqRXNzYXkgUHJvbXB0Kio6IERpc2N1c3MgdGhlIGNvbmNlcHRzIG9mIHRoZSBib290c3RyYXAgc2FtcGxpbmcgcGxhbiwgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24sIGFuZCB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gaW4gdGhlIGNvbnRleHQgb2Ygc3RhdGlzdGljcyAoZS5nLiwgc2FtcGxlIG1lYW4gYW5kIHZhcmlhbmNlKSBjb21wdXRlZCBmcm9tIGFuIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCAoaS5pLmQuKSBzYW1wbGUuIFlvdXIgZGlzY3Vzc2lvbiBzaG91bGQ6DQoNCiogQ2xlYXJseSBvdXRsaW5lIHRoZSBrZXkgYXNzdW1wdGlvbnMgcmVxdWlyZWQgZm9yIGVhY2ggbWV0aG9kLg0KDQoqIEV4cGxhaW4gdGhlIHByYWN0aWNhbCBhcHBsaWNhdGlvbiBvZiBlYWNoIGRpc3RyaWJ1dGlvbi4NCg0KKiBQcm92aWRlIGd1aWRhbmNlIG9uIHdoZW4gYW5kIHdoeSBvbmUgc2hvdWxkIGJlIHByZWZlcnJlZCBvdmVyIHRoZSBvdGhlciBpbiBzdGF0aXN0aWNhbCBpbmZlcmVuY2UuDQoNCiMgRXNzYXkgb24gQm9vc3RyYXAgdnMuIEFzeW1wdG90aWMgU2FtcGxpbmcgRGlzdHJpYnV0aW9uDQoNClRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGFuZCB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gYXJlIGludm9sdmVkIGluIHR3byBjb250cmFzdGluZyBtZXRob2RzIG9mIGFwcHJveGltYXRpbmcgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBmb3IgYSBzcGVjaWZpYyBzdGF0aXN0aWMgKG1lYW4sIHZhcmlhbmNlLCBldGMuKS4gIEZvciBlYXNlIG9mIHVuZGVyc3RhbmRpbmcsIGxldCdzIGNvbnNpZGVyIGFuIGV4YW1wbGUgdG8gd2FsayB0aHJvdWdoIHRoZSBhc3N1bXB0aW9ucyB1bmRlcnBpbm5pbmcgZWFjaCBtZXRob2QsIHRoZSBwcmFjdGljYWwgYXBwbGljYXRpb24gb2YgdGhlc2UgZGlzdHJpYnV0aW9ucywgYW5kIGZpbmFsbHkgY29uY2x1ZGUgd2l0aCBhIGRpc2N1c3Npb24gb2Ygd2hlbiB0aGVzZSBkaXN0cmlidXRpb25zIHNob3VsZCBiZSB1c2VkLiAgDQoNClN1cHBvc2Ugd2UgaGF2ZSBhIHNpeC1zaWRlZCBkaWUsIGFuZCB3ZSBhcmUgaG9waW5nIHRvIGFwcHJveGltYXRlIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBtZWFucyBvZiB0aGlzIHNpeC1zaWRlZCBkaWUuICBOb3csIHdlIG1heSBrbm93IGludHVpdGl2ZWx5IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIGRpZSB3b3VsZCBmb2xsb3cgYSBEaXNjcmV0ZSBVbmlmb3JtIERpc3RyaWJ1dGlvbiBiZXR3ZWVuIHRoZSB2YWx1ZXMgb2YgMSBhbmQgNi4gIFRoYXQgaXMgdG8gc2F5LCBpZiB3ZSB3ZXJlIHRvIHJvbGwgYSBzaXgtc2lkZWQgZGllIHdlIHdvdWxkIGV4cGVjdCB0byBzZWUgc29tZSB2YWx1ZSBiZXR3ZWVuIDEgYW5kIDYgd2l0aCBhbiBlcXVhbCBwcm9iYWJpbGl0eSBvZiB0aGUgZGllIGxhbmRpbmcgb24gZWFjaCBvZiB0aGVzZSB2YWx1ZXMuICBIb3dldmVyLCBzdXBwb3NlIHdlIHdhbnRlZCB0byB0YWtlIGEgc2FtcGxlIG9mIHRoZXNlIHZhbHVlcyBhbmQgdXNlIHRoYXQgc2FtcGxlIHRvIGZpbmQgYSBzYW1wbGUgbWVhbi4gIEFuZCB0aGVuIHN1cHBvc2UgdGhhdCB3ZSB0b29rIHRoaXMgc2FtcGxlIGFnYWluIGFuZCBhZ2FpbiwgZmluZGluZyB0aGUgc2FtcGxlIG1lYW5zIGZvciBtdWx0aXBsZSBkaWZmZXJlbnQgc2FtcGxlcy4gIFdvdWxkIHdlIGV4cGVjdCB0aGlzIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgdG8gZm9sbG93IGEgdW5pZm9ybSBkaXN0cmlidXRpb24/ICBCZWxvdyBpcyBhIGhpc3RvZ3JhbSBvZiAxMDAwIHNhbXBsZSBtZWFucywgZWFjaCB0YWtlbiBmcm9tIGEgc2ltdWxhdGVkIHNhbXBsZSBvZiBzaXplIDMwOg0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykgICNVc2VkIHRvIHNldCBzZWVkIHNvIHRoYXQgcmVzdWx0IGNhbiBiZSByZXBsaWNhdGVkDQpuIDwtIDMwDQpzYW1wbGVzIDwtIDEwMDAgDQoNCmRpZSA8LSByZXBsaWNhdGUoc2FtcGxlcywgbWVhbihydW5pZihuLCBtaW49MSwgbWF4PTYpKSkgI1NhbXBsZXMgZnJvbSBhIGRpc2NyZXRlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIHRoZSBhbW91bnQgb2YgdGltZXMgaW5kaWNhdGVkIGJ5ICdzYW1wbGVzJyBhbmQgYXQgc2FtcGxlIHNpemUgJ24nIHRvIGZpbmQgbWVhbiB2YWx1ZXMgZm9yIGVhY2ggc2FtcGxlDQoNCg0KaGlzdChkaWUsIGJyZWFrcz0yMCwgcHJvYj1UUlVFLCBtYWluPSJIaXN0b2dyYW0gb2YgU2FtcGxlIE1lYW5zIG9mIDYtc2lkZWQgRGljZSIsIHhsYWI9IlNhbXBsZSBNZWFucyIsIHhsaW09YygyLDUpKSAjQ3JlYXRlcyBoaXN0b2dyYW0gb2Ygc2FtcGxlIG1lYW5zDQoNCg0KYGBgDQoNClRoaXMgcmVzdWx0IGRvZXNuJ3QgYXBwZWFyIHVuaWZvcm0gYXQgYWxsISAgV2hpY2ggbGVhZHMgdXMgdG8gdGhlIHF1ZXN0aW9uIG9mIGhvdyB3ZSBzaG91bGQgd2UgZ28gYWJvdXQgYXBwcm94aW1hdGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBtZWFucyAob3IgYW55IHN0YXRpc3RpYyBmb3IgdGhhdCBtYXR0ZXIpLiAgVG8gYW5zd2VyIHRoYXQgcXVlc3Rpb24gd2Ugd2lsbCBjb25zaWRlciB0d28gbWV0aG9kcywgb25lIGludm9sdmluZyB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gYW5kIHRoZSBvdGhlciBpbnZvbHZpbmcgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24uDQoNClRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiByZWxpZXMgb24gdGhlIGNvbmNlcHQgdGhhdCBhcyB0aGUgc2FtcGxlIHNpemUgKCRuJCkgYXBwcm9hY2hlcyBpbmZpbml0eSwgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIHNwZWNpZmljIHN0YXRpc3RpYyBjYW4gYmUgYXBwcm94aW1hdGVkIGluIGEgc3BlY2lmaWMgd2F5LiAgTW9zdCBjb21tb25seSwgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGlzIGRpc2N1c3NlZCBpbiByZWxhdGlvbiB0byB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtIChDTFQpLiAgVGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSBob2xkcyB0aGF0LCBmb3IgbWFueSBzdGF0aXN0aWNzLCB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gdHVybnMgb3V0IHRvIGJlIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gIEhvd2V2ZXIsIGluIG9yZGVyIHRvIGFzc3VtZSB0aGF0IGl0IGlzIGFwcHJvcHJpYXRlIHRvIHVzZSBhbiBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB3ZSBtdXN0IGZpcnN0IGVuc3VyZSB0aGF0IG91ciBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCBhbmQgdGhhdCBvdXIgJG4kIGlzIHN1ZmZpY2llbnRseSBsYXJnZS4gIEluIG9yZGVyIHRvIHVzZSB0aGUgQ0xUIGluIHBhcnRpY3VsYXIsIHdlIG11c3QgYWxzbyBrbm93IHRoYXQgb3VyIHNhbXBsZXMgY29tZSBhIHBvcHVsYXRpb24gd2l0aCBhIGZpbml0ZSBtZWFuICRcbXUkIGFuZCB2YXJpYW5jZSAkXHNpZ21hXjIkLiAgSW4gb3VyIGV4YW1wbGUsIHdlIGtub3cgdGhhdCBvdXIgb2JzZXJ2YXRpb25zIGFyZSBpbmRlcGVuZGVudCAob25lIHJvbGwgb2YgdGhlIGRpZSBkb2VzIG5vdCBhZmZlY3QgdGhlIG90aGVyKSBhbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgKG91ciByZXN1bHRzIGFyZSBjb21pbmcgZnJvbSB0aGUgc2FtZSBwb3B1bGF0aW9uKS4gIEZ1cnRoZXJtb3JlLCB3ZSBrbm93IHRoYXQgdGhlcmUgaXMgc29tZSBmaW5pdGUgJFxtdSQgYW5kICRcc2lnbWFeMiQgc2luY2Ugb3VyIG9ic2VydmF0aW9ucyBjYW4gb25seSBiZSBiZXR3ZWVuIDEgYW5kIDYuICBUaGUgb25seSBxdWVzdGlvbiB0byB3aGV0aGVyIG9yIG5vdCB3ZSBjYW4gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gYW5kIHRoZSBhc3NvY2lhdGVkIG5vcm1hbCBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBpcyB0aGUgc2FtcGxlIHNpemUuDQoNCkluIG91ciBwcmV2aW91cyBleGFtcGxlIHdlIHVzZWQgYSBzYW1wbGUgc2l6ZSBvZiAzMC4gIEluIG1vc3QgY2FzZXMgdGhpcyBpcyBjb25zaWRlcmVkIGFuIGFwcHJvcHJpYXRlIHNhbXBsZSBzaXplIGZvciB1c2luZyB0aGUgQ0xULiAgSG93ZXZlciwgZm9yIHRoZSBzYWtlIG9mIHVuZGVyc3RhbmRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgdGhpcyBsYXJnZSBzYW1wbGUgc2l6ZSwgbGV0cyBpbnN0ZWFkIGltYWdpbmUgdGhhdCB3ZSBvbmx5IHVzZWQgYSBzYW1wbGUgc2l6ZSBvZiAyOg0KDQpgYGB7cn0NCnNldC5zZWVkKDIpICNVc2VkIHRvIHNldCBzZWVkIHNvIHRoYXQgcmVzdWx0IGNhbiBiZSByZXBsaWNhdGVkDQpuIDwtIDINCm11IDwtIDMuNQ0Kc2lnbWEgPC0gMS43MDc4DQpzYW1wbGVzIDwtIDEwMA0KDQpkaWUgPC0gcmVwbGljYXRlKHNhbXBsZXMsIG1lYW4ocnVuaWYobiwgbWluPTEsIG1heD02KSkpICNTYW1wbGVzIGZyb20gYSBkaXNjcmV0ZSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiB0aGUgYW1vdW50IG9mIHRpbWVzIGluZGljYXRlZCBieSAnc2FtcGxlcycgYW5kIGF0IHNhbXBsZSBzaXplICduJyB0byBmaW5kIG1lYW4gdmFsdWVzIGZvciBlYWNoIHNhbXBsZQ0KDQp4IDwtIHNlcShtdSAtIDMqc2lnbWEvc3FydChuKSwgbXUgKyAzKnNpZ21hL3NxcnQobiksIGxlbmd0aC5vdXQgPSAxMDApICNVc2VkIHRvIGxhdGVyIGNyZWF0ZSBub3JtYWwgY3VydmUgYmFzZWQgb24gJ211JyBhbmQgJ3NpZ21hJw0KbmMgPC0gZG5vcm0oeCwgbXUsIHNkPXNpZ21hL3NxcnQobikpDQoNCmhpc3QoZGllLCBicmVha3M9c2VxKG1pbihkaWUpLCBtYXgoZGllKSwgbGVuZ3RoLm91dD0yMCksIHByb2I9VFJVRSwgbWFpbj0iSGlzdG9ncmFtIG9mIFNhbXBsZSBNZWFucyBvZiA2LXNpZGVkIERpY2UgKG4gPSAyKSIsIHhsYWI9IlNhbXBsZSBNZWFucyIsIHhsaW09YygxLDYpKQ0KbGluZXMoeCwgbmMsIGNvbD0icmVkIiwgbHdkPTIpICNDcmVhdGVzIGhpc3RvZ3JhbSBvZiBzYW1wbGUgbWVhbnMNCmBgYA0KDQpBbiBhcHByb3ByaWF0ZSBub3JtYWwgY3VydmUgaXMgb3ZlcmxheWVkIG92ZXIgb3VyIGhpc3RvZ3JhbS4gIEhvd2V2ZXIsIHdlIGNhbiBzZWUgdGhhdCBvdXIgcmVzdWx0aW5nIHNhbXBsZSBtZWFucyBkb24ndCBhcHBlYXIgdG8gY2xvc2VseSBmb2xsb3cgdGhlIHRoZSBub3JtYWwgY3VydmUuICBPbiB0aGUgb3RoZXIgaGFuZCwgd2hhdCBpZiB3ZSB3ZXJlIHRvIGNob29zZSBhIHNpZ25pZmljYW50bHkgaGlnaGVyICRuJCBvZiAxMDA6DQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKSAjVXNlZCB0byBzZXQgc2VlZCBzbyB0aGF0IHJlc3VsdCBjYW4gYmUgcmVwbGljYXRlZA0KbiA8LSAxMDANCm11IDwtIDMuNQ0Kc2lnbWEgPC0gMS43MDc4DQpzYW1wbGVzIDwtIDEwMA0KDQpkaWUgPC0gcmVwbGljYXRlKHNhbXBsZXMsIG1lYW4ocnVuaWYobiwgbWluPTEsIG1heD02KSkpICNTYW1wbGVzIGZyb20gYSBkaXNjcmV0ZSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiB0aGUgYW1vdW50IG9mIHRpbWVzIGluZGljYXRlZCBieSAnc2FtcGxlcycgYW5kIGF0IHNhbXBsZSBzaXplICduJyB0byBmaW5kIG1lYW4gdmFsdWVzIGZvciBlYWNoIHNhbXBsZQ0KDQp4IDwtIHNlcShtdSAtIDMqc2lnbWEvc3FydChuKSwgbXUgKyAzKnNpZ21hL3NxcnQobiksIGxlbmd0aC5vdXQgPSAxMDApICNVc2VkIHRvIGxhdGVyIGNyZWF0ZSBub3JtYWwgY3VydmUgYmFzZWQgb24gJ211JyBhbmQgJ3NpZ21hJw0KbmMgPC0gZG5vcm0oeCwgbXUsIHNkPXNpZ21hL3NxcnQobikpDQoNCmhpc3QoZGllLCBicmVha3M9c2VxKG1pbihkaWUpLCBtYXgoZGllKSwgbGVuZ3RoLm91dD03KSwgcHJvYj1UUlVFLCBtYWluPSJIaXN0b2dyYW0gb2YgU2FtcGxlIE1lYW5zIG9mIDYtc2lkZWQgRGljZSAobiA9IDEwMCkiLCB4bGFiPSJTYW1wbGUgTWVhbnMiLCB4bGltPWMoMiw1KSkNCmxpbmVzKHgsIG5jLCBjb2w9InJlZCIsIGx3ZD0yKSAjQ3JlYXRlcyBoaXN0b2dyYW0gb2Ygc2FtcGxlIG1lYW5zDQpgYGANCg0KSGVyZSB3ZSBjYW4gc2VlIG91ciBoaXN0b2dyYW0gbXVjaCBtb3JlIGNsb3NlbHkgZm9sbG93cyB0aGUgYXBwcm9wcmlhdGUgbm9ybWFsIGN1cnZlLiAgVGhpcyBpcyBhIHZpc3VhbCBleGFtcGxlIG9mIHdoeSBvdXIgYXNzdW1wdGlvbiBvZiBhIGxhcmdlICRuJCBpcyBmdW5kYW1lbnRhbCB0byB1c2luZyBhbiBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4gIFRoaXMgYWxzbyBzZXJ2ZXMgdG8gZGVtb25zdHJhdGUgaG93IGFuIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGNvdWxkIGJlIHVzZWQsIHNwZWNpZmljYWxseSBpbiByZWdhcmRzIHRvIHRoZSBDTFQuICBJbiBwcmFjdGljZSwgd2Ugd291bGRuJ3QgbmVjZXNzYXJpbHkgaGF2ZSB0aGUgYWJpbGl0eSB0byByZXBlYXRlZGx5IHNhbXBsZSBvdXIgcG9wdWxhdGlvbi4gIEhvd2V2ZXIsIGJ5IHVzaW5nIHRoZSBDTFQgKGFzIGxvbmcgYXMgdGhlIGFzc29jaWF0ZWQgYXNzdW1wdGlvbnMgYXJlIG1ldCkgd2UgYXJlIGFibGUgdG8gc2FmZWx5IGFzc3VtZSB0aGF0IG91ciBzYW1wbGUgbWVhbnMgd2lsbCBhcHByb3hpbWF0ZWx5IGZvbGxvdyB0aGUgZm9sbG93aW5nIGRpc3RyaWJ1dGlvbjoNCg0KJCQNClxiYXJ7WH0gXHJpZ2h0YXJyb3cgTihcbXUsIFxmcmFje1xzaWdtYX17XHNxcnR7bn19KQ0KJCQNCldoZXJlICRcYmFye1h9JCBpcyB0aGUgc2FtcGxlIG1lYW4uICBBIHNpbWlsYXIgYXNzdW1wdGlvbiBjYW4gYmUgbWFkZSBpbiByZWdhcmRzIHRvIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSB2YXJpYW5jZSB1c2luZyB0aGUgQ0xUOg0KDQoNCiQkDQpzXjIgXHRvIE5cbGVmdChcc2lnbWFeMiwgIFxmcmFje1xtdV80LVxzaWdtYV40fXtufSBccmlnaHQpDQokJA0KDQpXaGVyZSAkc14yJCBpcyB0aGUgc2FtcGxlIHZhcmlhbmNlIGFuZCAkXG11XzQkIGlzIHRoZSA0dGggY2VudHJhbCBtb21lbnQuDQoNCkluIGNvbnRyYXN0IHRvIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24gcmVsaWVzIGEgZnVuZGFtZW50YWxseSBkaWZmZXJlbnQgbWV0aG9kIG9mIGFwcHJveGltYXRpbmcgdGhlIHNhbXBsZSBkaXN0cmlidXRpb24gZm9yIGEgc3RhdGlzdGljLiAgSW5zdGVhZCBvZiByZWx5aW5nIG9uIHRoZSBpZGVhIHRoYXQgYXMgc2FtcGxlIHNpemUgZ2V0cyBsYXJnZXIgaXQgbWF5IGJlY29tZSBwb3NzaWJsZSB0byBhcHByb3hpbWF0ZSB0aGUgdHJ1ZSBkaXN0cmlidXRpb24gb2YgYSBzYW1wbGUgc3RhdGlzdGljLCB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBpcyBmb3VuZCBieSByZXNhbXBsaW5nIHRoZSBleGlzdGluZyBzYW1wbGUgaW4gb3JkZXIgdG8gZXN0aW1hdGUgdGhlIHRydWUgZGlzdHJpYnV0aW9uIG9mIGEgc2FtcGxlIHN0YXRpc3RpYy4gIA0KDQpNdWNoIGxpa2UgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCB0aGVyZSBhcmUgc2V2ZXJhbCBhc3N1bXB0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGluIG9yZGVyIGZvciBvdXIgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB0byBhY2N1cmF0ZWx5IGFwcHJveGltYXRlIHRoZSB0cnVlIHNhbXBsZSBzdGF0aXN0aWMgZGlzdHJpYnV0aW9uLiBJdCBhc3N1bWVzIHRoYXQgb3VyIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgYW5kIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkLiAgRnVydGhlcm1vcmUsIGl0IGFsc28gaGFzIHNvbWUgcmVxdWlyZW1lbnRzIHJlZ2FyZGluZyB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlLCBnaXZlbiB0aGF0IGl0IGlzIGhhcmRlciB0byB0cmVhdCB0aGUgc2FtcGxlIGFzIGFuIGFjY3VyYXRlIHN1YnN0aXR1dGUgZm9yIHRoZSBwb3B1bGF0aW9uIHdpdGggYSBzbWFsbGVyIHNhbXBsZSBzaXplLiAgSG93ZXZlciwgdGhlc2UgcmVxdWlyZW1lbnRzIGFyZSBsZXNzIHN0cmluZ2VudCAoZXNwZWNpYWxseSB3aGVuIHRoZSBwb3B1bGF0aW9uIGlzIGhlYXZpbHkgc2tld2VkKSB0aGFuIHdpdGggdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbS4gIE9uY2UgYWdhaW4gZ29pbmcgYmFjayB0byBvdXIgc2l4LXNpZGVkIGRpZSBleGFtcGxlLCB3ZSBhbHJlYWR5IGtub3cgb3VyIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgYW5kIGlkZW50aWNhbGx5IGRpc3RyaWJ1dGVkLiAgSW4gdGhlIGZvbGxvd2luZyBleGFtcGxlIHdlIHdpbGwgYWxzbyB1c2UgYSBzYW1wbGUgc2l6ZSBvZiA1MCBpbiBvcmRlciB0byBlbnN1cmUgb3VyIGJvb3RzdHJhcCBzYW1wbGUgZGlzdHJpYnV0aW9uIGlzIGFuIGFjY3VyYXRlIGFwcHJveGltYXRpb24uICANCg0KSW4gb3JkZXIgdG8gcGVyZm9ybSBib290c3RyYXAgc2FtcGxpbmcgYW5kIG9idGFpbiBvdXIgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiB3ZSB3aWxsIHJlcGVhdGVkbHkgcmFuZG9tbHkgc2FtcGxlLCB3aXRoIHJlcGxhY2VtZW50LCBmcm9tIGFuIGFscmVhZHkgZXhpc3Rpbmcgc2FtcGxlLiAgQmVsb3cgd2Ugd2lsbCBzaW11bGF0ZSBhIHJhbmRvbSBzYW1wbGUgb2YgNTAgcm9sbHMgb2YgYSBzaXggc2lkZWQgYW5kIHRoZW4gcmFuZG9tbHkgc2FtcGxlIGZyb20gdGhpcyBzYW1wbGUgMTAwMCB0aW1lcy4gIFdlIHdpbGwgdGhlbiB1c2UgdGhlIHJlc3VsdGluZyBzYW1wbGUgbWVhbnMgdG8gZm9ybSB0aGUgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbi4gIFRoZSByZXN1bHRzIG9mIG91ciBhbmFseXNpcyBjYW4gYmUgc2VlbiBiZWxvdzoNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpICNVc2VkIHRvIHNldCBzZWVkIHNvIHRoYXQgcmVzdWx0IGNhbiBiZSByZXBsaWNhdGVkDQpuIDwtIDUwDQpkaWUyIDwtIHJ1bmlmKG4sIG1pbj0xLCBtYXg9NikgI1NhbXBsZXMgZnJvbSBhIGRpc2NyZXRlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIGEgc2FtcGxlIG9mIHNpemUgJ24nDQpCIDwtIDEwMDANCg0KYm9vdHN0cmFwLm1lYW5zIDwtIG51bWVyaWMoQikgI1Jlc2V0cyAnYm9vdHN0cmFwLm1lYW5zJyANCg0KZm9yIChpIGluIDE6Qil7DQogIGJvb3Quc2FtcGxlIDwtIHNhbXBsZShkaWUyLCBzaXplPW4sIHJlcGxhY2U9VFJVRSkNCiAgYm9vdHN0cmFwLm1lYW5zW2ldIDwtIG1lYW4oYm9vdC5zYW1wbGUpDQp9ICNVc2VkIHRvIHJhbmRvbWx5IHNhbXBsZSAod2l0aCByZXBsYWNlbWVudCkgZnJvbSAnZGllMicgJ0InIHRpbWVzIHRvIGdldCBzYW1wbGUgbWVhbnMNCg0Ka2RlLmRpZSA8LSBkZW5zaXR5KGJvb3RzdHJhcC5tZWFucykNCg0KaGlzdChib290c3RyYXAubWVhbnMsIHByb2I9VFJVRSwgbWFpbj0iQm9vdHN0cmFwIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiA2LXNpZGVkIERpZSIsIHhsYWI9IlNhbXBsZSBNZWFucyIsIHhsaW09YygyLDUpKQ0KbGluZXMoa2RlLmRpZSwgY29sPSJyZWQiLCBsd2Q9MikgI1VzZWQgdG8gY3JlYXRlIGhpc3RvZ3JhbSBvZiBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQoNCmBgYA0KDQpBcyBzdGF0ZWQsIHdlIHJhbmRvbWx5IHNhbXBsZWQgb3VyIGluaXRpYWwgc2ltdWxhdGVkIHNhbXBsZSBvZiA1MCBvYnNlcnZhdGlvbnMsIDEwMDAgdGltZXMuICBUaGlzIGFsbG93cyB1cyB0byBmb3JtIHRoZSBCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIG91ciA2LXNpZGVkIGRpZSBiYXNlZCBvbiBvdXIgb25lIHNhbXBsZS4NCg0KRmluYWxseSwgaXRzIHdvcnRoIGNvbnNpZGVyaW5nLCBnaXZlbiB0aGUgc2ltaWxhcml0aWVzIGJldHdlZW4gdGhlIGFzc3VtcHRpb25zIG9mIHRoZXNlIHR3byBkaXN0cmlidXRpb25zLCB3aHkgd2Ugd291bGQgY2hvb3NlIHRvIHVzZSBvbmUgb3ZlciB0aGUgb3RoZXIuICBUaGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gbW9zdCBhY2N1cmF0ZWx5IG1vZGVscyBzeW1tZXRyaWMsIG5vbiBza2V3ZWQgZGF0YS4gIFdoaWxlIGl0IGNhbiBiZSB1c2VkIHRvIG1vZGVsIHNrZXdlZCBkYXRhLCBpdCBvZnRlbiByZXF1aXJlcyBhIGxhcmdlciBzYW1wbGUgc2l6ZSB0byBhY2hpZXZlIGFuIGFjY3VyYXRlIHJlc3VsdC4gIEhvd2V2ZXIsIGl0IGlzIG5vdCBhcyBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIHRvIHVzZSBhcyB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4gIENvbnZlcnNlbHksIHRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGNhbiBiZSBtb3JlIGFjY3VyYXRlIHRoYW4gdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHdoZW4gYXBwbGllZCB0byBoZWF2aWx5IHNrZXdlZCBkYXRhIGFuZCBjb21wbGV4IG9yIHVua25vd24gZGlzdHJpYnV0aW9ucy4gIEhvd2V2ZXIsIGl0IHRha2VzIGEgbG90IG9mIGNvbXB1dGF0aW9uYWwgcG93ZXIgdG8gYWNjdXJhdGVseSBtb2RlbCwgc2luY2UgaXQgcmVxdWlyZXMgcmVwZWF0ZWQgcmVzYW1wbGluZyB0byBvYnRhaW4uICBVbHRpbWF0ZWx5LCBpdCBpcyBpbXBvcnRhbnQgdG8ga25vdyBib3RoIHRoZSBsaW1pdGF0aW9ucyBhbmQgYXBwbGljYXRpb25zIG9mIGJvdGggaW4gb3JkZXIgbW9zdCBhY2N1cmF0ZWx5IG1vZGVsIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIHNhbXBsaW5nIHN0YXRpc3RpY3MuDQoNClNvdXJjZXM6DQoNCmh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTUwNi93MDMvMDMtU2FtcGxpbmdEaXN0cmlidXRpb25zLmh0bWwNCg0KaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vU1RBNTA2L3cwNC8wNC1FQ0RhbmRCb290c3RyYXBTYW1wbGluZy5odG1sDQoNCg0KDQojIyAqKlF1ZXN0aW9uIDI6IERhaWx5IENvZmZlZSBTYWxlcyAoaW4gbUwpIGF0IFR3byBEaWZmZXJlbnQgQ2FmZSBMb2NhdGlvbnMqKg0KDQpUaGlzIGRhdGEgc2V0IHJlcHJlc2VudHMgdGhlIHZvbHVtZSBvZiByZWd1bGFyIGJyZXdlZCBjb2ZmZWUgc29sZCBwZXIgZGF5IChpbiBtaWxsaWxpdGVycykgYXQgdHdvIGRpZmZlcmVudCBjYWZlIGxvY2F0aW9ucyBvdmVyIGEgcGVyaW9kIG9mIDUwIGRheXMuIA0KDQpgYGANCjI4NTAsIDMyMDAsIDI5MDAsIDMxMDAsIDI5NTAsIDc4MDAsIDgxMDAsIDc5MDAsIDMzMDAsIDMwNTAsIDQwMDAsIDQyMDAsIDMxNTAsIDM0MDAsIDc3MDAsIDgyMDAsIA0KMzI1MCwgNDQwMCwgMzEwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCwgODIwMCwgODkwMCwgODcwMCwgMzI1MCwgMzAwMCwgNDYwMCwgNDEwMCwgODQwMCwgDQo4ODAwLCAzMzUwLCA0NzAwLCAzMTAwLCA4MTAwLCAzMDUwLCA4MzAwLCA0MTAwLCAzMTAwLCA4MzAwLCA4OTAwLCA4MjAwLCA0NDAwLCA0NTAwLCAzMjUwLCA0NjAwLCANCjg0MDAsIDMzMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDANCmBgYA0KV2UgYXJlIGludGVyZXN0ZWQgaW4gZmluZGluZyB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBtZWFucyB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgdmFyaW91cyBpbmZlcmVuY2VzIGFib3V0IHRoZSB1bmRlcmx5aW5nIHBvcHVsYXRpb24gbWVhbi4NCg0KYSkgQmFzZWQgb24gdGhlIGdpdmVuIGRhdGEsIGNhbiB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtIGJlIHVzZWQgdG8gZGVyaXZlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4/IEp1c3RpZnkgeW91ciBhbnN3ZXIuDQoNCiMgQW5zd2VyIHRvIFBhcnQgQQ0KDQpJbiBvcmRlciB0byB1c2UgdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSB0byBkZXJpdmUgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiB3ZSBuZWVkIGluZGVwZW5kZW50LCBpZGVudGljYWxseSBkaXN0cmlidXRlZCBvYnNlcnZhdGlvbnMgZnJvbSBhIHBvcHVsYXRpb24gd2l0aCBhIGZpbml0ZSAkXG11JCBhbmQgJFxzaWdtYV4yJCBhbmQgZW5vdWdoIG9ic2VydmF0aW9ucyB0aGF0IHdlIGNhbiBqdXN0aWZ5IHVzaW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0uICBUaGUgb2JzZXJ2YXRpb25zIGFyZSBmcm9tIGEgc2luZ2xlIHBvcHVsYXRpb24gb2YgY2FmZXMgc28gd2UgY2FuIGFzc3VtZSB0aGUgb2JzZXJ2YXRpb25zIGFyZSBpZGVudGljYWxseSBkaXN0cmlidXRlZC4gIFRoZXJlIGlzIGEgZmluaXRlIGFtb3VudCBvZiBjb2ZmZWUgdGhhdCBjYW4gYmUgYnJld2VkIHBlciBkYXkgc28gd2UgY2FuIGFzc3VtZSB0aGF0IHRoZXJlIGlzIGEgZmluaXRlICRcbXUkIGFuZCAkXHNpZ21hXjIkLiAgRmluYWxseSwgdGhlcmUgYXBwZWFyIHRvIGJlIGVub3VnaCBvYnNlcnZhdGlvbnMgdG8gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0sIGdpdmVuIHRoYXQgdGhlIHNhbXBsZSBzaXplIG9mIDU0IGlzIGdyZWF0ZXIgdGhhbiB0aGUgdHlwaWNhbCBDTFQgY3V0b2ZmIG9mIDMwLiAgSG93ZXZlciwgdGhlIHF1ZXN0aW9uIGRvZXMgbm90IHByb3ZpZGUgaW5mb3JtYXRpb24gb24gd2hldGhlciBvciBub3QgdGhlIG9ic2VydmF0aW9ucyB3ZXJlIHBhcnQgb2YgYSByYW5kb20gc2FtcGxlIHNvIHdlIGRvIG5vdCBoYXZlIGVub3VnaCBldmlkZW5jZSB0byBzdGF0ZSB0aGF0IHRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IG9mIG9uZSBhbm90aGVyLiAgVGhhdCBiZWluZyBzYWlkLCBpZiB0aGUgb2JzZXJ2YXRpb25zIGFyZSBmcm9tIGEgcmFuZG9tIHNhbXBsZSB0aGVuIHdlIHNob3VsZCBtZWV0IHRoZSBjb25kaXRpb25zIHRvIHVzZSB0aGUgQ0xULiAgIA0KDQpiKSBBcHBseSB0aGUgYm9vdHN0cmFwIG1ldGhvZCB0byBlc3RpbWF0ZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIChvZnRlbiBjYWxsZWQgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24pIG9mIHRoZSBzYW1wbGUgbWVhbi4gR2VuZXJhdGUgYSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxlIG1lYW5zIGFuZCBwbG90IGl0LiBUaGVuLCB1c2UgdGhpcyBib290c3RyYXAgZGlzdHJpYnV0aW9uIHRvIHZhbGlkYXRlIHlvdXIgY29uY2x1c2lvbiBmcm9tIHBhcnQgKGEpLiBNYWtlIHN1cmUgeW91ciB2aXN1YWxzIGFyZSBlZmZlY3RpdmUgaW4gZW5oYW5jaW5nIHRoZSBwcmVzZW50YXRpb24gb2YgdGhlc2UgcmVzdWx0cy4NCg0KIyBBbnN3ZXIgdG8gUGFydCBCDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKSAjVXNlZCB0byBzZXQgc2VlZCBzbyB0aGF0IHJlc3VsdCBjYW4gYmUgcmVwbGljYXRlZA0KY29mZmVlIDwtICBjKDI4NTAsIDMyMDAsIDI5MDAsIDMxMDAsIDI5NTAsIDc4MDAsIDgxMDAsIDc5MDAsIDMzMDAsIDMwNTAsIDQwMDAsIDQyMDAsIDMxNTAsIDM0MDAsIDc3MDAsIDgyMDAsIA0KMzI1MCwgNDQwMCwgMzEwMCwgNDIwMCwgNDUwMCwgNDgwMCwgNDMwMCwgODUwMCwgODIwMCwgODkwMCwgODcwMCwgMzI1MCwgMzAwMCwgNDYwMCwgNDEwMCwgODQwMCwgDQo4ODAwLCAzMzUwLCA0NzAwLCAzMTAwLCA4MTAwLCAzMDUwLCA4MzAwLCA0MTAwLCAzMTAwLCA4MzAwLCA4OTAwLCA4MjAwLCA0NDAwLCA0NTAwLCAzMjUwLCA0NjAwLCANCjg0MDAsIDMzMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDApDQoNCm4gPC0gbGVuZ3RoKGNvZmZlZSkNCkIgPC0gMTAwMA0KDQpib290c3RyYXAubWVhbnMgPC0gbnVtZXJpYyhCKSAjUmVzZXRzICdib290c3RyYXAubWVhbnMnIA0KDQpmb3IgKGkgaW4gMTpCKXsNCiAgYm9vdC5zYW1wbGUgPC0gc2FtcGxlKGNvZmZlZSwgc2l6ZT1uLCByZXBsYWNlPVRSVUUpDQogIGJvb3RzdHJhcC5tZWFuc1tpXSA8LSBtZWFuKGJvb3Quc2FtcGxlKSAjVXNlZCB0byByYW5kb21seSBzYW1wbGUgKHdpdGggcmVwbGFjZW1lbnQpIGZyb20gJ2NvZmZlZScgJ0InIHRpbWVzIHRvIGdldCBzYW1wbGUgbWVhbnMNCn0NCg0Ka2RlLmNvZmZlZSA8LSBkZW5zaXR5KGJvb3RzdHJhcC5tZWFucykgI01ha2VzIEtERSBvZiBib290c3RyYXAgc2FtcGxlIG1lYW5zDQoNCnggPC0gc2VxKG1lYW4oYm9vdHN0cmFwLm1lYW5zKSAtIDMqc2QoYm9vdHN0cmFwLm1lYW5zKSwgbWVhbihib290c3RyYXAubWVhbnMpICsgMypzZChib290c3RyYXAubWVhbnMpLCBsZW5ndGgub3V0ID0gMTAwKQ0KbmMgPC0gZG5vcm0oeCwgbWVhbihib290c3RyYXAubWVhbnMpLCBzZD1zZChib290c3RyYXAubWVhbnMpKSAjVXNlZCB0byBsYXRlciBjcmVhdGUgbm9ybWFsIGN1cnZlDQoNCnBsb3Qoa2RlLmNvZmZlZSwgbWFpbiA9ICJLREUgZnJvbSBCb290c3RyYXAgU2FtcGxlIE1lYW5zIiwgeGxhYiA9ICJTYW1wbGUgTWVhbnMiLCBjb2w9ImJsdWUiKQ0KbGluZXMoeCwgbmMsIGNvbD0icmVkIikgI1VzZWQgdG8gY3JlYXRlIGhpc3RvZ3JhbSBvZiBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQoNCmBgYA0KDQpBYm92ZSwgaW4gYmx1ZSwgaXMgdGhlIEtERSBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBtZWFucyBvYnRhaW5lZCBieSB1c2luZyB0aGUgYm9vdHN0cmFwIG1ldGhvZC4gIEFzIHdlIGNhbiBzZWUsIGl0IGZhaXJseSBjbG9zZWx5IGZvbGxvd3MgdGhlIG5vcm1hbCBjdXJ2ZSAoaW4gcmVkKSwgaW5kaWNhdGluZyB0aGF0IHRoZXJlIGlzIGV2aWRlbmNlIHRoYXQgaXQgd291bGQgYmUgYXBwcm9wcmlhdGUgdG8gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0uDQoNCmMpIFJlcGVhdCB0aGUgYW5hbHlzaXMgaW4gcGFydHMgKGEpIGFuZCAoYikgZm9yIHRoZSBzYW1wbGUgdmFyaWFuY2UuDQoNCiMgQW5zd2VyIHRvIFBhcnQgQw0KDQpBcyBzdGF0ZWQgcHJldmlvdXNseSwgaW4gb3JkZXIgdG8gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gdG8gZGVyaXZlIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2FtcGxlIG1lYW4gd2UgbmVlZCBpbmRlcGVuZGVudCwgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgb2JzZXJ2YXRpb25zIGZyb20gYSBwb3B1bGF0aW9uIHdpdGggYSBmaW5pdGUgJFxtdSQgYW5kICRcc2lnbWFeMiQgYW5kIGVub3VnaCBvYnNlcnZhdGlvbnMgdGhhdCB3ZSBjYW4ganVzdGlmeSB1c2luZyB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtLiAgU2luY2UgdGhpcyBpcyB0aGUgc2FtZSByYW5kb20gc2FtcGxlIGFzIHVzZWQgcHJldmlvdXNseSwgd2UgY2FuIGFzc3VtZSB0aGUgb2JzZXJ2YXRpb25zIGFyZSBpZGVudGljYWxseSBkaXN0cmlidXRlZCB3aXRoIGEgZmluaXRlICRcbXUkIGFuZCAkXHNpZ21hXjIkIGFuZCB0aGVyZSBhcmUgZW5vdWdoIG9ic2VydmF0aW9ucyB0byB1c2UgdGhlIENMVC4gIEhvd2V2ZXIsIHdlIGFyZSBzdGlsbCB1bnN1cmUgb2YgaW5kZXBlbmRlbmNlLg0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykgI1VzZWQgdG8gc2V0IHNlZWQgc28gdGhhdCByZXN1bHQgY2FuIGJlIHJlcGxpY2F0ZWQNCmNvZmZlZSA8LSAgYygyODUwLCAzMjAwLCAyOTAwLCAzMTAwLCAyOTUwLCA3ODAwLCA4MTAwLCA3OTAwLCAzMzAwLCAzMDUwLCA0MDAwLCA0MjAwLCAzMTUwLCAzNDAwLCA3NzAwLCA4MjAwLCANCjMyNTAsIDQ0MDAsIDMxMDAsIDQyMDAsIDQ1MDAsIDQ4MDAsIDQzMDAsIDg1MDAsIDgyMDAsIDg5MDAsIDg3MDAsIDMyNTAsIDMwMDAsIDQ2MDAsIDQxMDAsIDg0MDAsIA0KODgwMCwgMzM1MCwgNDcwMCwgMzEwMCwgODEwMCwgMzA1MCwgODMwMCwgNDEwMCwgMzEwMCwgODMwMCwgODkwMCwgODIwMCwgNDQwMCwgNDUwMCwgMzI1MCwgNDYwMCwgDQo4NDAwLCAzMzAwLCA0MjAwLCA0NTAwLCA0ODAwLCA0MzAwLCA4NTAwKQ0KDQpuIDwtIGxlbmd0aChjb2ZmZWUpDQpCIDwtIDEwMDANCg0KYm9vdHN0cmFwLnZhcmlhbmNlcyA8LSBudW1lcmljKEIpICNSZXNldHMgJ2Jvb3RzdHJhcC52YXJpYW5jZXMnIA0KDQpmb3IgKGkgaW4gMTpCKXsNCiAgYm9vdC5zYW1wbGUgPC0gc2FtcGxlKGNvZmZlZSwgc2l6ZT1uLCByZXBsYWNlPVRSVUUpDQogIGJvb3RzdHJhcC52YXJpYW5jZXNbaV0gPC0gdmFyKGJvb3Quc2FtcGxlKQ0KfSAjVXNlZCB0byByYW5kb21seSBzYW1wbGUgKHdpdGggcmVwbGFjZW1lbnQpIGZyb20gJ2NvZmZlZScgJ0InIHRpbWVzIHRvIGdldCBzYW1wbGUgdmFyaWFuY2VzDQoNCnggPC0gc2VxKG1lYW4oYm9vdHN0cmFwLnZhcmlhbmNlcykgLSAzKnNkKGJvb3RzdHJhcC52YXJpYW5jZXMpLCBtZWFuKGJvb3RzdHJhcC52YXJpYW5jZXMpICsgMypzZChib290c3RyYXAudmFyaWFuY2VzKSwgbGVuZ3RoLm91dCA9IDEwMCkNCm5jIDwtIGRub3JtKHgsIG1lYW4oYm9vdHN0cmFwLnZhcmlhbmNlcyksIHNkPXNkKGJvb3RzdHJhcC52YXJpYW5jZXMpKSAjVXNlZCB0byBsYXRlciBjcmVhdGUgbm9ybWFsIGN1cnZlDQoNCmtkZS5jb2ZmZWUgPC0gZGVuc2l0eShib290c3RyYXAudmFyaWFuY2VzKSAjTWFrZXMgS0RFIG9mIGJvb3RzdHJhcCBzYW1wbGUgdmFyaWFuY2VzDQoNCnBsb3Qoa2RlLmNvZmZlZSwgbWFpbiA9ICJLREUgZnJvbSBCb290c3RyYXAgU2FtcGxlIFZhcmlhbmNlcyIsIHhsYWI9IlNhbXBsZSBWYXJpYW5jZXMiLCBjb2w9ImJsdWUiKQ0KbGluZXMoeCwgbmMsIGNvbD0icmVkIikgI1VzZWQgdG8gY3JlYXRlIGhpc3RvZ3JhbSBvZiBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQoNCmBgYA0KDQpBYm92ZSwgaW4gYmx1ZSwgaXMgdGhlIEtERSBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSB2YXJpYW5jZXMgb2J0YWluZWQgYnkgdXNpbmcgdGhlIGJvb3RzdHJhcCBtZXRob2QuICBTaW1pbGFyIHRvIHRoZSBLREUgZnJvbSB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMsIGl0IGZhaXJseSBjbG9zZWx5IGZvbGxvd3MgdGhlIG5vcm1hbCBjdXJ2ZSAoaW4gcmVkKSwgaW5kaWNhdGluZyB0aGF0IHRoZXJlIGlzIGV2aWRlbmNlIHRoYXQgaXQgd291bGQgYmUgYXBwcm9wcmlhdGUgdG8gdXNlIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0uDQoNCg0KDQoNCg==