A Short Essay Describing Normal, t, chi-square, and F Distributions, Their Assumptions, and Their Connections

  • Develop a clear technical understanding of nonparametric cumulative distribution function (CDF) estimation and various kernel density estimators.

  • Translate mathematical formulas into R functions and apply them to solve related problems.

  • Create effective visualizations to demonstrate your understanding of key concepts in the following questions.


The Normal Distribution

The Normal distribution is a continuous, unimodal distribution that is characterized by its symmetric, bell-shaped curve. A Normal distribution is characterized by two values, its mean, \(\mu\) and its variance, \(\sigma^2\). For instance, a Normal distribution is written as \(N(\mu, \sigma^2)\). A Standard Normal is defined as a Normal distribution with \(\mu\) = 0 and \(\sigma^2\) = 1. This would be written as \(N(0, 1)\).

For a random sample of \(X_1, X_2, \ldots, X_n\), we would be interested in finding the sample mean, \(\bar{X}\), as an estimator of \(\mu\). In this case, the mean of the distribution of \(\bar{X}\) would still be \(\mu\). However, the standard deviation would be found by \(\sigma / \sqrt{n}\). So, this would be written as \(N\left(\mu, \frac{\sigma}{\sqrt{n}}\right)\). This value can be standardized by finding the Z-score. This Z-score represents how many standard deviations an observation is away from the mean. A positive Z-score means an observation is to the right of the mean, and a negative Z-score means that an observation is to the left of the mean. In this case, Z = \(\frac{\bar{X}-\mu}{\sigma/\sqrt{n}}\). Once this Z-score is calculated then we have a standardized value with N(0, 1) as seen in the Standard Normal.

Below is a visualization of several Normal distribution curves with different means and variances to show how these values shift the appearance of a Normal curve. This visualization includes a Standard Normal curve with a mean of 0 and a variance of 1. Additionally, the visualization includes two other Normal distributions with a mean of 0, but with different variances. One of these distributions has a variance of 4, and it can be seen how this curve is much flatter and wider than the Standard Normal. The other of these two distributions has a variance of 0.25, and it can be seen how this distribution is much more narrow with a sharper and higher peak than the Standard Normal. This shows that when a Normal distribution has a variance greater than that of a Standard Normal, the curve becomes wider, but if it has a variance less than that of a Standard Normal, the curve becomes narrower. Finally, there is one more Normal distribution which has a mean of 2, and a variance of 1. It can be seen that this distribution has the same spread as a Standard Normal, due to having an equivalent variance, but is shifted two units to the right due to having a mean of 2 rather than 0. This shows that the mean of a Normal distribution affects how the curve is shifted from that of a Standard Normal. A distribution with a positive mean would be shifted to the right, while a distribution with a negative mean would be shifted to the left. Overall, this visualization shows how Normal distribution curves change based upon changes to their mean and variance.

x <- seq(-6, 6, length = 1000)

# Standard Normal: mean = 0, var = 1
y_standard <- dnorm(x, mean = 0, sd = 1)

# mean = 0, var = 4 
y_wide <- dnorm(x, mean = 0, sd = 2)

# mean = 0, var = 0.25 
y_narrow <- dnorm(x, mean = 0, sd = 0.5)

# mean = 2, var = 1
y_shifted <- dnorm(x, mean = 2, sd = 1)

plot(x, y_standard,
     type = "l",
     lwd = 3,
     col = "purple",
     ylim = c(0, max(y_narrow)),
     main = expression("Normal Distributions with Different Values of " * mu * " and " * sigma^2),
     xlab = "x",
     ylab = "Density")

lines(x, y_wide, col = "lightblue", lwd = 3, lty = 2)
lines(x, y_narrow, col = "green", lwd = 3, lty = 3)
lines(x, y_shifted, col = "pink", lwd = 3)

legend("topright",
       legend = c(
         expression(mu == 0 ~ "," ~ sigma^2 == 1),
         expression(mu == 0 ~ "," ~ sigma^2 == 4),
         expression(mu == 0 ~ "," ~ sigma^2 == 0.25),
         expression(mu == 2 ~ "," ~ sigma^2 == 1)
       ),
       col = c("purple", "lightblue", "green", "pink"),
       lty = c(1, 2, 3, 1),
       lwd = 3,
       bty = "n")

The Normal distribution is defined from \(-\infty\) to \(\infty\).

Assumptions of a Normal Distribution

In order to use a Normal distribution, the following assumptions must be met:

  • The observations are independent from one another.

  • The dependent variable must be continuous.

  • The sample errors are normally distributed.

  • The sample size is sufficiently large enough.

Going off of the last assumption, the exact number to be sufficiently large enough can vary, but often is given as n > 30. The importance of this is seen through one of the most fundamental theorems in statistics, the Central Limit Theorem (CLT). This theorem states that the distribution of the sampling mean approaches a normal distribution as the sample size becomes sufficiently large enough. This occurs regardless of the distribution of the population as long as the sample size is sufficiently large enough. Typically n = 30 is the value used in statistics as the marker of a sufficiently large population, however this can vary as a highly skewed population distribution would likely need a much larger sample size to achieve an approximately normal sampling distribution.

Below shows a visualization of how the CLT applies to a sampling distribution. In this visualization, a sample is done three times, first with n = 5, then n = 30, and then n = 100. This shows how as sample size increases and becomes sufficiently large, the sampling distribution begins to follow that of a Normal distribution.

set.seed(123)

n_values <- c(5, 30, 100)
par(mfrow = c(2, 3))  

for (n in n_values) {
  sample_means <- replicate(1000, mean(rexp(n)))
  
  hist(sample_means,
       probability = TRUE,
       breaks = 30,
       col = "lavender",
       border = "purple",
       main = paste("Sampling Distribution (n =", n, ")"),
       xlab = "Sample Mean")
  
  lines(density(sample_means), lwd = 2, col = "purple")
  curve(dnorm(x, mean(sample_means), sd(sample_means)),
        add = TRUE, col = "darkmagenta", lwd = 2, lty = 2)
}
par(mfrow = c(1, 1)) 

As we can see, as the sample size, n, increases, the sample distribution begins to become more like that of a Normal distribution regardless of the population distribution.

The t-Distribution

The t-Distribution is a continuous, unimodal distribution with a symmetric, bell-shaped curve. This type of curve appears similar to that of a Normal distribution, however a t-distribution curve has a flatter shape and thicker tails in comparison. A t-distribution is used over a Normal distribution in the case that the population standard deviation is unknown. Additionally, a t-distribution would also be the ideal choice if the sample size is small, typically n < 30. So, while a Normal distribution would have a known population standard deviation, a t-distribution would have an unknown population standard deviation.

From a random sample of \(X_1, X_2, \ldots, X_n\), let the sample mean \(\bar{X} = \frac{1}{n}\sum_{i=1}^{n} X_i\). In this case, the population standard deviation is unknown, so we are interested in using a t-distribution. It turns out that t = \(\frac{\bar{X} - \mu}{s / \sqrt{n}}\). Where \(s\) is the sample standard deviation, and \(S^2\) the sample variance, where \(S^2 = \frac{1}{n-1}\sum_{i=1}^{n}(X_i - \bar{X})^2\).

An important characteristic of a t-distribution is the degrees of freedom. The degrees of freedom, often represents as v, equals n-1 where n is the sample size. This is the key parameter of a t-distribution, as the degrees of freedom will be a fixed value when the sample size is known. The visualization below shows t-distribution curves for various degrees of freedom values. A Normal curve is included for comparison.

x <- seq(-4, 4, length = 1000)
y_df2  <- dt(x, df = 2)
y_df5  <- dt(x, df = 5)
y_df30 <- dt(x, df = 30)
y_df50 <- dt(x, df = 50)
y_norm <- dnorm(x)
y_max <- max(y_df2, y_df5, y_df30, y_df50, y_norm)

plot(x, y_df2,
     type = "l",
     lwd = 2,
     col = "purple",
     ylim = c(0, y_max),
     main = "t-Distributions with Different Degrees of Freedom",
     ylab = "Density",
     xlab = "x")

lines(x, y_df5,  lwd = 2, col = "lightblue")
lines(x, y_df30, lwd = 2, col = "green")
lines(x, y_df50, lwd = 2, col = "brown", lty = 2)
lines(x, y_norm, lwd = 2, col = "pink")

legend("topright",
       legend = c("df = 2", "df = 5", "df = 30", "df = 50", "Normal"),
       col = c("purple", "lightblue", "green", "brown", "pink"),
       lty = c(1, 1, 1, 2),
       lwd = 2,
       bty = "n")

The t-distribution is defined from \(-\infty\) to \(\infty\).

As seen in the visualization above, a t-distribution with smaller degrees of freedom has a flatter peak with wider tails. On the other hand, a t-distribution with larger degrees of freedom has a higher peak with more narrow tails. Also, the visualization shows that as the number of degrees of freedom increases further and further, the curve of the distribution becomes closer to that of a Normal distribution curve.

Assumptions of a t-Distribution

In order to use a t-distribution, the following assumptions must be met:

  • The observations are independent from one another.

  • The dependent variable must be continuous.

  • The data follows an approximately Normal distribution.

  • The population standard deviation is unknown.

The Chi-Square Distribution

Another commonly used distribution is the Chi-Square distribution. The Chi-Square distribution is a variation of the Gamma distribution that is also represented as the sum of squared standard Normal random variables. If \(Z_1, Z_2, \ldots, Z_k \stackrel{iid}{\sim} N(0,1)\) then \(\sum_{i=1}^{k} Z_i^2 \sim \chi^2_k\) where k is the degrees of freedom. The exact distribution of the scaled sample variance for a Normal distribution is as follows, \(\frac{(n-1)S^2}{\sigma^2} {\to} \chi_{n-1}^2\). This gives us the Chi-Square distribution.

The shape of a Chi-Square distribution depends on its degrees of freedom, just like how the shape of a t-distribution also depends on its degrees of freedom. Once again, degrees of freedom is defined as n-1, where n is the sample size. One major difference of the Chi-Square distribution from the Normal distribution and t-distribution is that the Chi-Square distribution is asymmetrically shaped, and does not follow a symmetric, bell-shaped curve as was seen of the previous two distributions.

The visualization below shows the Chi-Square distributions for various degrees of freedom values.

x <- seq(0, 30, length = 1000)

y_df2  <- dchisq(x, df = 2)
y_df5  <- dchisq(x, df = 5)
y_df15 <- dchisq(x, df = 15)

y_max <- max(y_df2, y_df5, y_df15)

plot(x, y_df2,
     type = "l",
     lwd = 2,
     col = "purple",
     ylim = c(0, y_max),
     main = "Chi-Square Distributions with Different Degrees of Freedom",
     xlab = "x",
     ylab = "Density")

lines(x, y_df5,  lwd = 2, col = "lightblue")
lines(x, y_df15, lwd = 2, col = "green")

legend("topright",
       legend = c("df = 2", "df = 5", "df = 15"),
       col = c("purple", "lightblue", "green"),
       lwd = 2,
       bty = "n")

The Chi-Square distribution is defined from 0 to \(\infty\).

In the visualization above, it can be seen that as the degrees of freedom increases, the distribution curve becomes flatter and wider, and shifts over to the right. The smaller the degrees of freedom, the higher the peak of the distribution is, and the quicker it flattens out. For these smaller degrees of freedom values, the distribution is very much skewed to the right and asymmetric. It can be seen that how as the degrees of freedom becomes larger and larger, the distribution becomes less significantly skewed, and very large values of degrees of freedom begin to become closer and closer to the shape of a Normal distribution.

Assumptions of a Chi-Square Distribution

In order to use a Chi-Square distribution, the following assumptions must be met:

  • The observations are independent from one another.

  • The sample size is sufficiently large enough.

  • The population follows a Normal distribution.

  • The Chi-Square statistics is formed from squared deviations.

The F Distribution

One other important distribution is the F distribution. The F distribution is the sampling distribution for the ratio of two independent sample variances. The F distribution is useful for comparing variances and is used in ANOVA (analysis of variance) and regression modeling.

For a F distribution, we have two independent random samples, \(\{X_1, X_2, \cdots, X_{n_1}\} \overset{i.i.d}{\sim} N(\mu_1, \sigma_1^2) \quad\text{ and } \quad \{Y_1, Y_2, \cdots, Y_{n_2}\} \overset{i.i.d}{\sim} N(\mu_2, \sigma_2^2)\). From these two samples, we have the sample variance for each of the two distributions respectively, \(S_1^2 = \frac{1}{n_1-1} \sum_{i=1}^{n_1} (X_i - \bar{X})^2 \quad\text{ and } \quad S_2^2 = \frac{1}{n_2-1} \sum_{i=1}^{n_2} (Y_i - \bar{Y})^2\). The F statistic, is found as follows, \(F = \frac{S_1^2/\sigma_1^2}{S_2^2/\sigma_2^2} \overset{d}{\to} F_{n_1-1, n_2-1}\). Thus, the F statistic serves as a ratio of the sample variances for the two independent distributions. Once again, the F distribution depends on the degrees of freedom for each of the two independent samples. In this case, \(n_1-1\) and \(n_2-1\) are the degrees of freedom for sample one and sample two respectively, where n is the sample size for each independent, random sample. These two values of the degrees of freedom for the numerator and denominator are the two parameters of a F distribution.

The following visualization shows F distributions for various values of the degrees of freedom for each of the two independent samples. Each F distribution has two parameters, df1 and df2, which are these two degrees of freedom values. This visualization shows how the F distribution changes in appearence based upon these two degrees of freedom parameters.

x <- seq(0, 5, length = 1000)

y_2_10  <- df(x, df1 = 2,  df2 = 10)
y_5_10  <- df(x, df1 = 5,  df2 = 10)
y_10_10 <- df(x, df1 = 10, df2 = 10)

y_max <- max(y_2_10, y_5_10, y_10_10)

plot(x, y_2_10,
     type = "l",
     lwd = 2,
     col = "purple",
     ylim = c(0, y_max),
     main = "F Distributions with Different Degrees of Freedom",
     xlab = "x",
     ylab = "Density")

lines(x, y_5_10,  lwd = 2, col = "lightblue")
lines(x, y_10_10, lwd = 2, col = "green")

legend("topright",
       legend = c("df1 = 2, df2 = 10",
                  "df1 = 5, df2 = 10",
                  "df1 = 10, df2 = 10"),
       col = c("purple", "lightblue", "green"),
       lwd = 2,
       bty = "n")

The F distribution is defined from 0 to \(\infty\).

As seen above, the curves of a F distribution as skewed right and asymmetric. These curves do not follow a symmetric, bell-shaped curve that the Normal distribution was seen to follow. In fact, these curves look quite similar to what was seen with the Chi-Square distribution. Similarly to the Chi-Square distribution, for a F distribution, smaller values of degrees of freedom show steeper, and more skewed distribution while larger values of degrees of freedom show wider distributions with less skew in comparison. In fact, the F distribution can be defined based on two independent Chi-Square distributions. The numerator and denominator of a F distribution can be written in terms of two independent Chi-Square distributions.If the samples are independent and normally distributed, then \(\frac{(n_1 - 1)S_1^2}{\sigma_1^2} \sim \chi^2_{n_1 - 1},\qquad\frac{(n_2 - 1)S_2^2}{\sigma_2^2} \sim \chi^2_{n_2 - 1}\). Taking the ratio results in, \(\frac{S_1^2}{S_2^2} \sim F_{n_1 - 1,\; n_2 - 1}\). Overall, the F distribution is a great way to compare variances between these two independent distributions.

Assummptions of a F Distribution

In order to use a F distribution, the following assumptions must be met:

  • The observations are independent from one another.

  • Each of the two samples are Normally distributed.

  • The samples are drawn independently from one another.

  • The populations should have homogeneity of variances (equal variances).

Connections Between These Distributions

All four of these distributions, the Normal distribution, the t-distribution, the Chi-Square distribution, and the F distribution, are incredibly important to statistical analysis and random sampling.

These distributions connect to one another in several ways. For instance, the sum of squared Normal variables follows a chi-square distribution. Additionally, another example of this is that a F statistic is the ratio of two independent Chi-Square random variables. Another important occurrence of this is that if \(Z \sim N(0,1)\), then \(Z^2 \sim \chi^2\). So, while all four distributions have distinctions from one another, they also overlap in several ways and show clear connections with each other.

The table below shows a clear comparison of key features of the four distributions. These features include a brief description of the shape of each distribution, their paramaters, and the support of values for which the distribution can take on.

dist_table <- data.frame(
  Distribution = c("Normal", "t", "Chi-square", "F"),
  Shape = c("Symmetric", "Symmetric, thicker tails", "Right-skewed", "Right-skewed"),
  Support = c("$(-\\infty, \\infty)$", "$(-\\infty, \\infty)$", "$(0, \\infty)$", "$(0, \\infty)$"),
  Parameters = c("$\\mu, \\sigma^2$", "df(v)", "df", "df$_1$, df$_2$")
)

kable(dist_table, format = "html", escape = FALSE)
Distribution Shape Support Parameters
Normal Symmetric \((-\infty, \infty)\) \(\mu, \sigma^2\)
t Symmetric, thicker tails \((-\infty, \infty)\) df(v)
Chi-square Right-skewed \((0, \infty)\) df
F Right-skewed \((0, \infty)\) df\(_1\), df\(_2\)

Altogether, the Normal distribution, the t-distribution, the Chi-Square distribution, and the F distribution are all important statistical tools when it comes to observing sampling distributions and making assumptions regarding the overall population based upon these distributions. These four distributions have distinct differences from one another, based upon their appearance and the parameters used within each distribution. However, these distributions connect with one another in various ways which shows the importance of each of these distributions based upon how they can work together based upon transformations of random variables through statistical procedures.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMjogQSBTaG9ydCBFc3NheSBEZXNjcmliaW5nIE5vcm1hbCwgdCwgY2hpLXNxdWFyZSwgYW5kIEYgRGlzdHJpYnV0aW9ucyINCmF1dGhvcjogIkpvc2llIEdhbGxvcCINCmRhdGU6ICIgRHVlOiAwMi0xMC0yMDI2Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkEgU2hvcnQgRXNzYXkgRGVzY3JpYmluZyBOb3JtYWwsIHQsIGNoaS1zcXVhcmUsIGFuZCBGIERpc3RyaWJ1dGlvbnMsIFRoZWlyIEFzc3VtcHRpb25zLCBhbmQgVGhlaXIgQ29ubmVjdGlvbnMqKiANCg0KKiBEZXZlbG9wIGEgY2xlYXIgdGVjaG5pY2FsIHVuZGVyc3RhbmRpbmcgb2Ygbm9ucGFyYW1ldHJpYyBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiAoQ0RGKSBlc3RpbWF0aW9uIGFuZCB2YXJpb3VzIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRvcnMuDQoNCiogVHJhbnNsYXRlIG1hdGhlbWF0aWNhbCBmb3JtdWxhcyBpbnRvIFIgZnVuY3Rpb25zIGFuZCBhcHBseSB0aGVtIHRvIHNvbHZlIHJlbGF0ZWQgcHJvYmxlbXMuDQoNCiogQ3JlYXRlIGVmZmVjdGl2ZSB2aXN1YWxpemF0aW9ucyB0byBkZW1vbnN0cmF0ZSB5b3VyIHVuZGVyc3RhbmRpbmcgb2Yga2V5IGNvbmNlcHRzIGluIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zLg0KDQoNCg0KXA0KDQoNCg0KIyBUaGUgTm9ybWFsIERpc3RyaWJ1dGlvbg0KDQpUaGUgTm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBhIGNvbnRpbnVvdXMsIHVuaW1vZGFsIGRpc3RyaWJ1dGlvbiB0aGF0IGlzIGNoYXJhY3Rlcml6ZWQgYnkgaXRzIHN5bW1ldHJpYywgYmVsbC1zaGFwZWQgY3VydmUuIEEgTm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBjaGFyYWN0ZXJpemVkIGJ5IHR3byB2YWx1ZXMsIGl0cyBtZWFuLCAkXG11JCBhbmQgaXRzIHZhcmlhbmNlLCAkXHNpZ21hXjIkLiBGb3IgaW5zdGFuY2UsIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyB3cml0dGVuIGFzICROKFxtdSwgXHNpZ21hXjIpJC4gQSBTdGFuZGFyZCBOb3JtYWwgaXMgZGVmaW5lZCBhcyBhIE5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCAkXG11JCA9IDAgYW5kICRcc2lnbWFeMiQgPSAxLiBUaGlzIHdvdWxkIGJlIHdyaXR0ZW4gYXMgJE4oMCwgMSkkLiANCg0KRm9yIGEgcmFuZG9tIHNhbXBsZSBvZiAkWF8xLCBYXzIsIFxsZG90cywgWF9uJCwgd2Ugd291bGQgYmUgaW50ZXJlc3RlZCBpbiBmaW5kaW5nIHRoZSBzYW1wbGUgbWVhbiwgJFxiYXJ7WH0kLCBhcyBhbiBlc3RpbWF0b3Igb2YgICRcbXUkLiBJbiB0aGlzIGNhc2UsIHRoZSBtZWFuIG9mIHRoZSBkaXN0cmlidXRpb24gb2YgJFxiYXJ7WH0kIHdvdWxkIHN0aWxsIGJlICRcbXUkLiBIb3dldmVyLCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIHdvdWxkIGJlIGZvdW5kIGJ5ICAkXHNpZ21hIC8gXHNxcnR7bn0kLiBTbywgdGhpcyB3b3VsZCBiZSB3cml0dGVuIGFzICROXGxlZnQoXG11LCBcZnJhY3tcc2lnbWF9e1xzcXJ0e259fVxyaWdodCkkLiBUaGlzIHZhbHVlIGNhbiBiZSBzdGFuZGFyZGl6ZWQgYnkgZmluZGluZyB0aGUgWi1zY29yZS4gVGhpcyBaLXNjb3JlIHJlcHJlc2VudHMgaG93IG1hbnkgc3RhbmRhcmQgZGV2aWF0aW9ucyBhbiBvYnNlcnZhdGlvbiBpcyBhd2F5IGZyb20gdGhlIG1lYW4uIEEgcG9zaXRpdmUgWi1zY29yZSBtZWFucyBhbiBvYnNlcnZhdGlvbiBpcyB0byB0aGUgcmlnaHQgb2YgdGhlIG1lYW4sIGFuZCBhIG5lZ2F0aXZlIFotc2NvcmUgbWVhbnMgdGhhdCBhbiBvYnNlcnZhdGlvbiBpcyB0byB0aGUgbGVmdCBvZiB0aGUgbWVhbi4gSW4gdGhpcyBjYXNlLCBaID0gJFxmcmFje1xiYXJ7WH0tXG11fXtcc2lnbWEvXHNxcnR7bn19JC4gT25jZSB0aGlzIFotc2NvcmUgaXMgY2FsY3VsYXRlZCB0aGVuIHdlIGhhdmUgYSBzdGFuZGFyZGl6ZWQgdmFsdWUgd2l0aCBOKDAsIDEpIGFzIHNlZW4gaW4gdGhlIFN0YW5kYXJkIE5vcm1hbC4gDQoNCkJlbG93IGlzIGEgdmlzdWFsaXphdGlvbiBvZiBzZXZlcmFsIE5vcm1hbCBkaXN0cmlidXRpb24gY3VydmVzIHdpdGggZGlmZmVyZW50IG1lYW5zIGFuZCB2YXJpYW5jZXMgdG8gc2hvdyBob3cgdGhlc2UgdmFsdWVzIHNoaWZ0IHRoZSBhcHBlYXJhbmNlIG9mIGEgTm9ybWFsIGN1cnZlLiBUaGlzIHZpc3VhbGl6YXRpb24gaW5jbHVkZXMgYSBTdGFuZGFyZCBOb3JtYWwgY3VydmUgd2l0aCBhIG1lYW4gb2YgMCBhbmQgYSB2YXJpYW5jZSBvZiAxLiBBZGRpdGlvbmFsbHksIHRoZSB2aXN1YWxpemF0aW9uIGluY2x1ZGVzIHR3byBvdGhlciBOb3JtYWwgZGlzdHJpYnV0aW9ucyB3aXRoIGEgbWVhbiBvZiAwLCBidXQgd2l0aCBkaWZmZXJlbnQgdmFyaWFuY2VzLiBPbmUgb2YgdGhlc2UgZGlzdHJpYnV0aW9ucyBoYXMgYSB2YXJpYW5jZSBvZiA0LCBhbmQgaXQgY2FuIGJlIHNlZW4gaG93IHRoaXMgY3VydmUgaXMgbXVjaCBmbGF0dGVyIGFuZCB3aWRlciB0aGFuIHRoZSBTdGFuZGFyZCBOb3JtYWwuIFRoZSBvdGhlciBvZiB0aGVzZSB0d28gZGlzdHJpYnV0aW9ucyBoYXMgYSB2YXJpYW5jZSBvZiAwLjI1LCBhbmQgaXQgY2FuIGJlIHNlZW4gaG93IHRoaXMgZGlzdHJpYnV0aW9uIGlzIG11Y2ggbW9yZSBuYXJyb3cgd2l0aCBhIHNoYXJwZXIgYW5kIGhpZ2hlciBwZWFrIHRoYW4gdGhlIFN0YW5kYXJkIE5vcm1hbC4gVGhpcyBzaG93cyB0aGF0IHdoZW4gYSBOb3JtYWwgZGlzdHJpYnV0aW9uIGhhcyBhIHZhcmlhbmNlIGdyZWF0ZXIgdGhhbiB0aGF0IG9mIGEgU3RhbmRhcmQgTm9ybWFsLCB0aGUgY3VydmUgYmVjb21lcyB3aWRlciwgYnV0IGlmIGl0IGhhcyBhIHZhcmlhbmNlIGxlc3MgdGhhbiB0aGF0IG9mIGEgU3RhbmRhcmQgTm9ybWFsLCB0aGUgY3VydmUgYmVjb21lcyBuYXJyb3dlci4gRmluYWxseSwgdGhlcmUgaXMgb25lIG1vcmUgTm9ybWFsIGRpc3RyaWJ1dGlvbiB3aGljaCBoYXMgYSBtZWFuIG9mIDIsIGFuZCBhIHZhcmlhbmNlIG9mIDEuIEl0IGNhbiBiZSBzZWVuIHRoYXQgdGhpcyBkaXN0cmlidXRpb24gaGFzIHRoZSBzYW1lIHNwcmVhZCBhcyBhIFN0YW5kYXJkIE5vcm1hbCwgZHVlIHRvIGhhdmluZyBhbiBlcXVpdmFsZW50IHZhcmlhbmNlLCBidXQgaXMgc2hpZnRlZCB0d28gdW5pdHMgdG8gdGhlIHJpZ2h0IGR1ZSB0byBoYXZpbmcgYSBtZWFuIG9mIDIgcmF0aGVyIHRoYW4gMC4gVGhpcyBzaG93cyB0aGF0IHRoZSBtZWFuIG9mIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbiBhZmZlY3RzIGhvdyB0aGUgY3VydmUgaXMgc2hpZnRlZCBmcm9tIHRoYXQgb2YgYSBTdGFuZGFyZCBOb3JtYWwuIEEgZGlzdHJpYnV0aW9uIHdpdGggYSBwb3NpdGl2ZSBtZWFuIHdvdWxkIGJlIHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0LCB3aGlsZSBhIGRpc3RyaWJ1dGlvbiB3aXRoIGEgbmVnYXRpdmUgbWVhbiB3b3VsZCBiZSBzaGlmdGVkIHRvIHRoZSBsZWZ0LiBPdmVyYWxsLCB0aGlzIHZpc3VhbGl6YXRpb24gc2hvd3MgaG93IE5vcm1hbCBkaXN0cmlidXRpb24gY3VydmVzIGNoYW5nZSBiYXNlZCB1cG9uIGNoYW5nZXMgdG8gdGhlaXIgbWVhbiBhbmQgdmFyaWFuY2UuIA0KDQpgYGB7ciBub3JtYWwtdmFyaWFuY2UtbWVhbiwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0NCnggPC0gc2VxKC02LCA2LCBsZW5ndGggPSAxMDAwKQ0KDQojIFN0YW5kYXJkIE5vcm1hbDogbWVhbiA9IDAsIHZhciA9IDENCnlfc3RhbmRhcmQgPC0gZG5vcm0oeCwgbWVhbiA9IDAsIHNkID0gMSkNCg0KIyBtZWFuID0gMCwgdmFyID0gNCANCnlfd2lkZSA8LSBkbm9ybSh4LCBtZWFuID0gMCwgc2QgPSAyKQ0KDQojIG1lYW4gPSAwLCB2YXIgPSAwLjI1IA0KeV9uYXJyb3cgPC0gZG5vcm0oeCwgbWVhbiA9IDAsIHNkID0gMC41KQ0KDQojIG1lYW4gPSAyLCB2YXIgPSAxDQp5X3NoaWZ0ZWQgPC0gZG5vcm0oeCwgbWVhbiA9IDIsIHNkID0gMSkNCg0KcGxvdCh4LCB5X3N0YW5kYXJkLA0KICAgICB0eXBlID0gImwiLA0KICAgICBsd2QgPSAzLA0KICAgICBjb2wgPSAicHVycGxlIiwNCiAgICAgeWxpbSA9IGMoMCwgbWF4KHlfbmFycm93KSksDQogICAgIG1haW4gPSBleHByZXNzaW9uKCJOb3JtYWwgRGlzdHJpYnV0aW9ucyB3aXRoIERpZmZlcmVudCBWYWx1ZXMgb2YgIiAqIG11ICogIiBhbmQgIiAqIHNpZ21hXjIpLA0KICAgICB4bGFiID0gIngiLA0KICAgICB5bGFiID0gIkRlbnNpdHkiKQ0KDQpsaW5lcyh4LCB5X3dpZGUsIGNvbCA9ICJsaWdodGJsdWUiLCBsd2QgPSAzLCBsdHkgPSAyKQ0KbGluZXMoeCwgeV9uYXJyb3csIGNvbCA9ICJncmVlbiIsIGx3ZCA9IDMsIGx0eSA9IDMpDQpsaW5lcyh4LCB5X3NoaWZ0ZWQsIGNvbCA9ICJwaW5rIiwgbHdkID0gMykNCg0KbGVnZW5kKCJ0b3ByaWdodCIsDQogICAgICAgbGVnZW5kID0gYygNCiAgICAgICAgIGV4cHJlc3Npb24obXUgPT0gMCB+ICIsIiB+IHNpZ21hXjIgPT0gMSksDQogICAgICAgICBleHByZXNzaW9uKG11ID09IDAgfiAiLCIgfiBzaWdtYV4yID09IDQpLA0KICAgICAgICAgZXhwcmVzc2lvbihtdSA9PSAwIH4gIiwiIH4gc2lnbWFeMiA9PSAwLjI1KSwNCiAgICAgICAgIGV4cHJlc3Npb24obXUgPT0gMiB+ICIsIiB+IHNpZ21hXjIgPT0gMSkNCiAgICAgICApLA0KICAgICAgIGNvbCA9IGMoInB1cnBsZSIsICJsaWdodGJsdWUiLCAiZ3JlZW4iLCAicGluayIpLA0KICAgICAgIGx0eSA9IGMoMSwgMiwgMywgMSksDQogICAgICAgbHdkID0gMywNCiAgICAgICBidHkgPSAibiIpDQoNCmBgYA0KDQpUaGUgTm9ybWFsIGRpc3RyaWJ1dGlvbiBpcyBkZWZpbmVkIGZyb20gJC1caW5mdHkkIHRvICRcaW5mdHkkLg0KDQoNCiMjIEFzc3VtcHRpb25zIG9mIGEgTm9ybWFsIERpc3RyaWJ1dGlvbg0KDQpJbiBvcmRlciB0byB1c2UgYSBOb3JtYWwgZGlzdHJpYnV0aW9uLCB0aGUgZm9sbG93aW5nIGFzc3VtcHRpb25zIG11c3QgYmUgbWV0Og0KDQotIFRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IGZyb20gb25lIGFub3RoZXIuDQoNCi0gVGhlIGRlcGVuZGVudCB2YXJpYWJsZSBtdXN0IGJlIGNvbnRpbnVvdXMuDQoNCi0gVGhlIHNhbXBsZSBlcnJvcnMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KDQotIFRoZSBzYW1wbGUgc2l6ZSBpcyBzdWZmaWNpZW50bHkgbGFyZ2UgZW5vdWdoLiANCg0KDQpHb2luZyBvZmYgb2YgdGhlIGxhc3QgYXNzdW1wdGlvbiwgdGhlIGV4YWN0IG51bWJlciB0byBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgZW5vdWdoIGNhbiB2YXJ5LCBidXQgb2Z0ZW4gaXMgZ2l2ZW4gYXMgbiA+IDMwLiBUaGUgaW1wb3J0YW5jZSBvZiB0aGlzIGlzIHNlZW4gdGhyb3VnaCBvbmUgb2YgdGhlIG1vc3QgZnVuZGFtZW50YWwgdGhlb3JlbXMgaW4gc3RhdGlzdGljcywgdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSAoQ0xUKS4gVGhpcyB0aGVvcmVtIHN0YXRlcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsaW5nIG1lYW4gYXBwcm9hY2hlcyBhIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgdGhlIHNhbXBsZSBzaXplIGJlY29tZXMgc3VmZmljaWVudGx5IGxhcmdlIGVub3VnaC4gVGhpcyBvY2N1cnMgcmVnYXJkbGVzcyBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBwb3B1bGF0aW9uIGFzIGxvbmcgYXMgdGhlIHNhbXBsZSBzaXplIGlzIHN1ZmZpY2llbnRseSBsYXJnZSBlbm91Z2guIFR5cGljYWxseSBuID0gMzAgaXMgdGhlIHZhbHVlIHVzZWQgaW4gc3RhdGlzdGljcyBhcyB0aGUgbWFya2VyIG9mIGEgc3VmZmljaWVudGx5IGxhcmdlIHBvcHVsYXRpb24sIGhvd2V2ZXIgdGhpcyBjYW4gdmFyeSBhcyBhIGhpZ2hseSBza2V3ZWQgcG9wdWxhdGlvbiBkaXN0cmlidXRpb24gd291bGQgbGlrZWx5IG5lZWQgYSBtdWNoIGxhcmdlciBzYW1wbGUgc2l6ZSB0byBhY2hpZXZlIGFuIGFwcHJveGltYXRlbHkgbm9ybWFsIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4gDQoNCkJlbG93IHNob3dzIGEgdmlzdWFsaXphdGlvbiBvZiBob3cgdGhlIENMVCBhcHBsaWVzIHRvIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLiBJbiB0aGlzIHZpc3VhbGl6YXRpb24sIGEgc2FtcGxlIGlzIGRvbmUgdGhyZWUgdGltZXMsIGZpcnN0IHdpdGggbiA9IDUsIHRoZW4gbiA9IDMwLCBhbmQgdGhlbiBuID0gMTAwLiBUaGlzIHNob3dzIGhvdyBhcyBzYW1wbGUgc2l6ZSBpbmNyZWFzZXMgYW5kIGJlY29tZXMgc3VmZmljaWVudGx5IGxhcmdlLCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGJlZ2lucyB0byBmb2xsb3cgdGhhdCBvZiBhIE5vcm1hbCBkaXN0cmlidXRpb24uIA0KDQpgYGB7cn0NCnNldC5zZWVkKDEyMykNCg0Kbl92YWx1ZXMgPC0gYyg1LCAzMCwgMTAwKQ0KcGFyKG1mcm93ID0gYygyLCAzKSkgIA0KDQpmb3IgKG4gaW4gbl92YWx1ZXMpIHsNCiAgc2FtcGxlX21lYW5zIDwtIHJlcGxpY2F0ZSgxMDAwLCBtZWFuKHJleHAobikpKQ0KICANCiAgaGlzdChzYW1wbGVfbWVhbnMsDQogICAgICAgcHJvYmFiaWxpdHkgPSBUUlVFLA0KICAgICAgIGJyZWFrcyA9IDMwLA0KICAgICAgIGNvbCA9ICJsYXZlbmRlciIsDQogICAgICAgYm9yZGVyID0gInB1cnBsZSIsDQogICAgICAgbWFpbiA9IHBhc3RlKCJTYW1wbGluZyBEaXN0cmlidXRpb24gKG4gPSIsIG4sICIpIiksDQogICAgICAgeGxhYiA9ICJTYW1wbGUgTWVhbiIpDQogIA0KICBsaW5lcyhkZW5zaXR5KHNhbXBsZV9tZWFucyksIGx3ZCA9IDIsIGNvbCA9ICJwdXJwbGUiKQ0KICBjdXJ2ZShkbm9ybSh4LCBtZWFuKHNhbXBsZV9tZWFucyksIHNkKHNhbXBsZV9tZWFucykpLA0KICAgICAgICBhZGQgPSBUUlVFLCBjb2wgPSAiZGFya21hZ2VudGEiLCBsd2QgPSAyLCBsdHkgPSAyKQ0KfQ0KcGFyKG1mcm93ID0gYygxLCAxKSkgDQpgYGANCg0KQXMgd2UgY2FuIHNlZSwgYXMgdGhlIHNhbXBsZSBzaXplLCBuLCBpbmNyZWFzZXMsIHRoZSBzYW1wbGUgZGlzdHJpYnV0aW9uIGJlZ2lucyB0byBiZWNvbWUgbW9yZSBsaWtlIHRoYXQgb2YgYSBOb3JtYWwgZGlzdHJpYnV0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIHBvcHVsYXRpb24gZGlzdHJpYnV0aW9uLg0KDQoNCg0KIyBUaGUgdC1EaXN0cmlidXRpb24NCg0KVGhlIHQtRGlzdHJpYnV0aW9uIGlzIGEgY29udGludW91cywgdW5pbW9kYWwgZGlzdHJpYnV0aW9uIHdpdGggYSBzeW1tZXRyaWMsIGJlbGwtc2hhcGVkIGN1cnZlLiBUaGlzIHR5cGUgb2YgY3VydmUgYXBwZWFycyBzaW1pbGFyIHRvIHRoYXQgb2YgYSBOb3JtYWwgZGlzdHJpYnV0aW9uLCBob3dldmVyIGEgdC1kaXN0cmlidXRpb24gY3VydmUgaGFzIGEgZmxhdHRlciBzaGFwZSBhbmQgdGhpY2tlciB0YWlscyBpbiBjb21wYXJpc29uLiBBIHQtZGlzdHJpYnV0aW9uIGlzIHVzZWQgb3ZlciBhIE5vcm1hbCBkaXN0cmlidXRpb24gaW4gdGhlIGNhc2UgdGhhdCB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gaXMgdW5rbm93bi4gQWRkaXRpb25hbGx5LCBhIHQtZGlzdHJpYnV0aW9uIHdvdWxkIGFsc28gYmUgdGhlIGlkZWFsIGNob2ljZSBpZiB0aGUgc2FtcGxlIHNpemUgaXMgc21hbGwsIHR5cGljYWxseSBuIDwgMzAuIFNvLCB3aGlsZSBhIE5vcm1hbCBkaXN0cmlidXRpb24gd291bGQgaGF2ZSBhIGtub3duIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uLCBhIHQtZGlzdHJpYnV0aW9uIHdvdWxkIGhhdmUgYW4gdW5rbm93biBwb3B1bGF0aW9uIHN0YW5kYXJkIGRldmlhdGlvbi4gDQoNCkZyb20gYSByYW5kb20gc2FtcGxlIG9mICRYXzEsIFhfMiwgXGxkb3RzLCBYX24kLCBsZXQgdGhlIHNhbXBsZSBtZWFuICRcYmFye1h9ID0gXGZyYWN7MX17bn1cc3VtX3tpPTF9XntufSBYX2kkLiBJbiB0aGlzIGNhc2UsIHRoZSBwb3B1bGF0aW9uIHN0YW5kYXJkIGRldmlhdGlvbiBpcyB1bmtub3duLCBzbyB3ZSBhcmUgaW50ZXJlc3RlZCBpbiB1c2luZyBhIHQtZGlzdHJpYnV0aW9uLiBJdCB0dXJucyBvdXQgdGhhdCB0ID0gJFxmcmFje1xiYXJ7WH0gLSBcbXV9e3MgLyBcc3FydHtufX0kLiBXaGVyZSAkcyQgaXMgdGhlIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24sIGFuZCAkU14yJCB0aGUgc2FtcGxlIHZhcmlhbmNlLCB3aGVyZSAkU14yID0gXGZyYWN7MX17bi0xfVxzdW1fe2k9MX1ee259KFhfaSAtIFxiYXJ7WH0pXjIkLiANCg0KQW4gaW1wb3J0YW50IGNoYXJhY3RlcmlzdGljIG9mIGEgdC1kaXN0cmlidXRpb24gaXMgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSwgb2Z0ZW4gcmVwcmVzZW50cyBhcyB2LCBlcXVhbHMgbi0xIHdoZXJlIG4gaXMgdGhlIHNhbXBsZSBzaXplLiBUaGlzIGlzIHRoZSBrZXkgcGFyYW1ldGVyIG9mIGEgdC1kaXN0cmlidXRpb24sIGFzIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gd2lsbCBiZSBhIGZpeGVkIHZhbHVlIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGtub3duLiBUaGUgdmlzdWFsaXphdGlvbiBiZWxvdyBzaG93cyB0LWRpc3RyaWJ1dGlvbiBjdXJ2ZXMgZm9yIHZhcmlvdXMgZGVncmVlcyBvZiBmcmVlZG9tIHZhbHVlcy4gQSBOb3JtYWwgY3VydmUgaXMgaW5jbHVkZWQgZm9yIGNvbXBhcmlzb24uDQoNCmBgYHtyfQ0KeCA8LSBzZXEoLTQsIDQsIGxlbmd0aCA9IDEwMDApDQp5X2RmMiAgPC0gZHQoeCwgZGYgPSAyKQ0KeV9kZjUgIDwtIGR0KHgsIGRmID0gNSkNCnlfZGYzMCA8LSBkdCh4LCBkZiA9IDMwKQ0KeV9kZjUwIDwtIGR0KHgsIGRmID0gNTApDQp5X25vcm0gPC0gZG5vcm0oeCkNCnlfbWF4IDwtIG1heCh5X2RmMiwgeV9kZjUsIHlfZGYzMCwgeV9kZjUwLCB5X25vcm0pDQoNCnBsb3QoeCwgeV9kZjIsDQogICAgIHR5cGUgPSAibCIsDQogICAgIGx3ZCA9IDIsDQogICAgIGNvbCA9ICJwdXJwbGUiLA0KICAgICB5bGltID0gYygwLCB5X21heCksDQogICAgIG1haW4gPSAidC1EaXN0cmlidXRpb25zIHdpdGggRGlmZmVyZW50IERlZ3JlZXMgb2YgRnJlZWRvbSIsDQogICAgIHlsYWIgPSAiRGVuc2l0eSIsDQogICAgIHhsYWIgPSAieCIpDQoNCmxpbmVzKHgsIHlfZGY1LCAgbHdkID0gMiwgY29sID0gImxpZ2h0Ymx1ZSIpDQpsaW5lcyh4LCB5X2RmMzAsIGx3ZCA9IDIsIGNvbCA9ICJncmVlbiIpDQpsaW5lcyh4LCB5X2RmNTAsIGx3ZCA9IDIsIGNvbCA9ICJicm93biIsIGx0eSA9IDIpDQpsaW5lcyh4LCB5X25vcm0sIGx3ZCA9IDIsIGNvbCA9ICJwaW5rIikNCg0KbGVnZW5kKCJ0b3ByaWdodCIsDQogICAgICAgbGVnZW5kID0gYygiZGYgPSAyIiwgImRmID0gNSIsICJkZiA9IDMwIiwgImRmID0gNTAiLCAiTm9ybWFsIiksDQogICAgICAgY29sID0gYygicHVycGxlIiwgImxpZ2h0Ymx1ZSIsICJncmVlbiIsICJicm93biIsICJwaW5rIiksDQogICAgICAgbHR5ID0gYygxLCAxLCAxLCAyKSwNCiAgICAgICBsd2QgPSAyLA0KICAgICAgIGJ0eSA9ICJuIikNCg0KYGBgDQpUaGUgdC1kaXN0cmlidXRpb24gaXMgZGVmaW5lZCBmcm9tICQtXGluZnR5JCB0byAkXGluZnR5JC4NCg0KQXMgc2VlbiBpbiB0aGUgdmlzdWFsaXphdGlvbiBhYm92ZSwgYSB0LWRpc3RyaWJ1dGlvbiB3aXRoIHNtYWxsZXIgZGVncmVlcyBvZiBmcmVlZG9tIGhhcyBhIGZsYXR0ZXIgcGVhayB3aXRoIHdpZGVyIHRhaWxzLiBPbiB0aGUgb3RoZXIgaGFuZCwgYSB0LWRpc3RyaWJ1dGlvbiB3aXRoIGxhcmdlciBkZWdyZWVzIG9mIGZyZWVkb20gaGFzIGEgaGlnaGVyIHBlYWsgd2l0aCBtb3JlIG5hcnJvdyB0YWlscy4gQWxzbywgdGhlIHZpc3VhbGl6YXRpb24gc2hvd3MgdGhhdCBhcyB0aGUgbnVtYmVyIG9mIGRlZ3JlZXMgb2YgZnJlZWRvbSBpbmNyZWFzZXMgZnVydGhlciBhbmQgZnVydGhlciwgdGhlIGN1cnZlIG9mIHRoZSBkaXN0cmlidXRpb24gYmVjb21lcyBjbG9zZXIgdG8gdGhhdCBvZiBhIE5vcm1hbCBkaXN0cmlidXRpb24gY3VydmUuIA0KDQoNCiMjIEFzc3VtcHRpb25zIG9mIGEgdC1EaXN0cmlidXRpb24NCg0KSW4gb3JkZXIgdG8gdXNlIGEgdC1kaXN0cmlidXRpb24sIHRoZSBmb2xsb3dpbmcgYXNzdW1wdGlvbnMgbXVzdCBiZSBtZXQ6DQoNCi0gVGhlIG9ic2VydmF0aW9ucyBhcmUgaW5kZXBlbmRlbnQgZnJvbSBvbmUgYW5vdGhlci4NCg0KLSBUaGUgZGVwZW5kZW50IHZhcmlhYmxlIG11c3QgYmUgY29udGludW91cy4NCg0KLSBUaGUgZGF0YSBmb2xsb3dzIGFuIGFwcHJveGltYXRlbHkgTm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KLSBUaGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gaXMgdW5rbm93bi4NCg0KDQoNCg0KDQojIFRoZSBDaGktU3F1YXJlIERpc3RyaWJ1dGlvbg0KDQpBbm90aGVyIGNvbW1vbmx5IHVzZWQgZGlzdHJpYnV0aW9uIGlzIHRoZSBDaGktU3F1YXJlIGRpc3RyaWJ1dGlvbi4gVGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uIGlzIGEgdmFyaWF0aW9uIG9mIHRoZSBHYW1tYSBkaXN0cmlidXRpb24gdGhhdCBpcyBhbHNvIHJlcHJlc2VudGVkIGFzIHRoZSBzdW0gb2Ygc3F1YXJlZCBzdGFuZGFyZCBOb3JtYWwgcmFuZG9tIHZhcmlhYmxlcy4gSWYgJFpfMSwgWl8yLCBcbGRvdHMsIFpfayBcc3RhY2tyZWx7aWlkfXtcc2ltfSBOKDAsMSkkIHRoZW4gJFxzdW1fe2k9MX1ee2t9IFpfaV4yIFxzaW0gXGNoaV4yX2skIHdoZXJlIGsgaXMgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbS4gVGhlIGV4YWN0IGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2NhbGVkIHNhbXBsZSB2YXJpYW5jZSBmb3IgYSBOb3JtYWwgZGlzdHJpYnV0aW9uIGlzIGFzIGZvbGxvd3MsICRcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IHtcdG99IFxjaGlfe24tMX1eMiQuIFRoaXMgZ2l2ZXMgdXMgdGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uLiANCg0KVGhlIHNoYXBlIG9mIGEgQ2hpLVNxdWFyZSBkaXN0cmlidXRpb24gZGVwZW5kcyBvbiBpdHMgZGVncmVlcyBvZiBmcmVlZG9tLCBqdXN0IGxpa2UgaG93IHRoZSBzaGFwZSBvZiBhIHQtZGlzdHJpYnV0aW9uIGFsc28gZGVwZW5kcyBvbiBpdHMgZGVncmVlcyBvZiBmcmVlZG9tLiBPbmNlIGFnYWluLCBkZWdyZWVzIG9mIGZyZWVkb20gaXMgZGVmaW5lZCBhcyBuLTEsIHdoZXJlIG4gaXMgdGhlIHNhbXBsZSBzaXplLiBPbmUgbWFqb3IgZGlmZmVyZW5jZSBvZiB0aGUgQ2hpLVNxdWFyZSBkaXN0cmlidXRpb24gZnJvbSB0aGUgTm9ybWFsIGRpc3RyaWJ1dGlvbiBhbmQgdC1kaXN0cmlidXRpb24gaXMgdGhhdCB0aGUgQ2hpLVNxdWFyZSBkaXN0cmlidXRpb24gaXMgYXN5bW1ldHJpY2FsbHkgc2hhcGVkLCBhbmQgZG9lcyBub3QgZm9sbG93IGEgc3ltbWV0cmljLCBiZWxsLXNoYXBlZCBjdXJ2ZSBhcyB3YXMgc2VlbiBvZiB0aGUgcHJldmlvdXMgdHdvIGRpc3RyaWJ1dGlvbnMuIA0KDQpUaGUgdmlzdWFsaXphdGlvbiBiZWxvdyBzaG93cyB0aGUgQ2hpLVNxdWFyZSBkaXN0cmlidXRpb25zIGZvciB2YXJpb3VzIGRlZ3JlZXMgb2YgZnJlZWRvbSB2YWx1ZXMuIA0KDQpgYGB7cn0NCnggPC0gc2VxKDAsIDMwLCBsZW5ndGggPSAxMDAwKQ0KDQp5X2RmMiAgPC0gZGNoaXNxKHgsIGRmID0gMikNCnlfZGY1ICA8LSBkY2hpc3EoeCwgZGYgPSA1KQ0KeV9kZjE1IDwtIGRjaGlzcSh4LCBkZiA9IDE1KQ0KDQp5X21heCA8LSBtYXgoeV9kZjIsIHlfZGY1LCB5X2RmMTUpDQoNCnBsb3QoeCwgeV9kZjIsDQogICAgIHR5cGUgPSAibCIsDQogICAgIGx3ZCA9IDIsDQogICAgIGNvbCA9ICJwdXJwbGUiLA0KICAgICB5bGltID0gYygwLCB5X21heCksDQogICAgIG1haW4gPSAiQ2hpLVNxdWFyZSBEaXN0cmlidXRpb25zIHdpdGggRGlmZmVyZW50IERlZ3JlZXMgb2YgRnJlZWRvbSIsDQogICAgIHhsYWIgPSAieCIsDQogICAgIHlsYWIgPSAiRGVuc2l0eSIpDQoNCmxpbmVzKHgsIHlfZGY1LCAgbHdkID0gMiwgY29sID0gImxpZ2h0Ymx1ZSIpDQpsaW5lcyh4LCB5X2RmMTUsIGx3ZCA9IDIsIGNvbCA9ICJncmVlbiIpDQoNCmxlZ2VuZCgidG9wcmlnaHQiLA0KICAgICAgIGxlZ2VuZCA9IGMoImRmID0gMiIsICJkZiA9IDUiLCAiZGYgPSAxNSIpLA0KICAgICAgIGNvbCA9IGMoInB1cnBsZSIsICJsaWdodGJsdWUiLCAiZ3JlZW4iKSwNCiAgICAgICBsd2QgPSAyLA0KICAgICAgIGJ0eSA9ICJuIikNCmBgYA0KDQpUaGUgQ2hpLVNxdWFyZSBkaXN0cmlidXRpb24gaXMgZGVmaW5lZCBmcm9tIDAgdG8gJFxpbmZ0eSQuDQoNCkluIHRoZSB2aXN1YWxpemF0aW9uIGFib3ZlLCBpdCBjYW4gYmUgc2VlbiB0aGF0IGFzIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gaW5jcmVhc2VzLCB0aGUgZGlzdHJpYnV0aW9uIGN1cnZlIGJlY29tZXMgZmxhdHRlciBhbmQgd2lkZXIsIGFuZCBzaGlmdHMgb3ZlciB0byB0aGUgcmlnaHQuIFRoZSBzbWFsbGVyIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20sIHRoZSBoaWdoZXIgdGhlIHBlYWsgb2YgdGhlIGRpc3RyaWJ1dGlvbiBpcywgYW5kIHRoZSBxdWlja2VyIGl0IGZsYXR0ZW5zIG91dC4gRm9yIHRoZXNlIHNtYWxsZXIgZGVncmVlcyBvZiBmcmVlZG9tIHZhbHVlcywgdGhlIGRpc3RyaWJ1dGlvbiBpcyB2ZXJ5IG11Y2ggc2tld2VkIHRvIHRoZSByaWdodCBhbmQgYXN5bW1ldHJpYy4gSXQgY2FuIGJlIHNlZW4gdGhhdCBob3cgYXMgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBiZWNvbWVzIGxhcmdlciBhbmQgbGFyZ2VyLCB0aGUgZGlzdHJpYnV0aW9uIGJlY29tZXMgbGVzcyBzaWduaWZpY2FudGx5IHNrZXdlZCwgYW5kIHZlcnkgbGFyZ2UgdmFsdWVzIG9mIGRlZ3JlZXMgb2YgZnJlZWRvbSBiZWdpbiB0byBiZWNvbWUgY2xvc2VyIGFuZCBjbG9zZXIgdG8gdGhlIHNoYXBlIG9mIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbi4gDQoNCg0KIyMgQXNzdW1wdGlvbnMgb2YgYSBDaGktU3F1YXJlIERpc3RyaWJ1dGlvbg0KDQpJbiBvcmRlciB0byB1c2UgYSBDaGktU3F1YXJlIGRpc3RyaWJ1dGlvbiwgdGhlIGZvbGxvd2luZyBhc3N1bXB0aW9ucyBtdXN0IGJlIG1ldDoNCg0KLSBUaGUgb2JzZXJ2YXRpb25zIGFyZSBpbmRlcGVuZGVudCBmcm9tIG9uZSBhbm90aGVyLg0KDQotIFRoZSBzYW1wbGUgc2l6ZSBpcyBzdWZmaWNpZW50bHkgbGFyZ2UgZW5vdWdoLg0KDQotIFRoZSBwb3B1bGF0aW9uIGZvbGxvd3MgYSBOb3JtYWwgZGlzdHJpYnV0aW9uLg0KDQotIFRoZSBDaGktU3F1YXJlIHN0YXRpc3RpY3MgaXMgZm9ybWVkIGZyb20gc3F1YXJlZCBkZXZpYXRpb25zLg0KDQoNCg0KIyBUaGUgRiBEaXN0cmlidXRpb24NCg0KT25lIG90aGVyIGltcG9ydGFudCBkaXN0cmlidXRpb24gaXMgdGhlIEYgZGlzdHJpYnV0aW9uLiBUaGUgRiBkaXN0cmlidXRpb24gaXMgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIHJhdGlvIG9mIHR3byBpbmRlcGVuZGVudCBzYW1wbGUgdmFyaWFuY2VzLiBUaGUgRiBkaXN0cmlidXRpb24gaXMgdXNlZnVsIGZvciBjb21wYXJpbmcgdmFyaWFuY2VzIGFuZCBpcyB1c2VkIGluIEFOT1ZBIChhbmFseXNpcyBvZiB2YXJpYW5jZSkgYW5kIHJlZ3Jlc3Npb24gbW9kZWxpbmcuIA0KDQpGb3IgYSBGIGRpc3RyaWJ1dGlvbiwgd2UgaGF2ZSB0d28gaW5kZXBlbmRlbnQgcmFuZG9tIHNhbXBsZXMsICRce1hfMSwgWF8yLCBcY2RvdHMsIFhfe25fMX1cfSAgXG92ZXJzZXR7aS5pLmR9e1xzaW19IE4oXG11XzEsIFxzaWdtYV8xXjIpIFxxdWFkXHRleHR7IGFuZCB9IFxxdWFkIFx7WV8xLCBZXzIsIFxjZG90cywgWV97bl8yfVx9ICBcb3ZlcnNldHtpLmkuZH17XHNpbX0gTihcbXVfMiwgXHNpZ21hXzJeMikkLiBGcm9tIHRoZXNlIHR3byBzYW1wbGVzLCB3ZSBoYXZlIHRoZSBzYW1wbGUgdmFyaWFuY2UgZm9yIGVhY2ggb2YgdGhlIHR3byBkaXN0cmlidXRpb25zIHJlc3BlY3RpdmVseSwgJFNfMV4yID0gXGZyYWN7MX17bl8xLTF9IFxzdW1fe2k9MX1ee25fMX0gKFhfaSAtIFxiYXJ7WH0pXjIgXHF1YWRcdGV4dHsgYW5kIH0gXHF1YWQgU18yXjIgPSBcZnJhY3sxfXtuXzItMX0gXHN1bV97aT0xfV57bl8yfSAoWV9pIC0gXGJhcntZfSleMiQuIFRoZSBGIHN0YXRpc3RpYywgaXMgZm91bmQgYXMgZm9sbG93cywgJEYgPSBcZnJhY3tTXzFeMi9cc2lnbWFfMV4yfXtTXzJeMi9cc2lnbWFfMl4yfSBcb3ZlcnNldHtkfXtcdG99IEZfe25fMS0xLCBuXzItMX0kLiBUaHVzLCB0aGUgRiBzdGF0aXN0aWMgc2VydmVzIGFzIGEgcmF0aW8gb2YgdGhlIHNhbXBsZSB2YXJpYW5jZXMgZm9yIHRoZSB0d28gaW5kZXBlbmRlbnQgZGlzdHJpYnV0aW9ucy4gT25jZSBhZ2FpbiwgdGhlIEYgZGlzdHJpYnV0aW9uIGRlcGVuZHMgb24gdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBmb3IgZWFjaCBvZiB0aGUgdHdvIGluZGVwZW5kZW50IHNhbXBsZXMuIEluIHRoaXMgY2FzZSwgJG5fMS0xJCBhbmQgJG5fMi0xJCBhcmUgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBmb3Igc2FtcGxlIG9uZSBhbmQgc2FtcGxlIHR3byByZXNwZWN0aXZlbHksIHdoZXJlIG4gaXMgdGhlIHNhbXBsZSBzaXplIGZvciBlYWNoIGluZGVwZW5kZW50LCByYW5kb20gc2FtcGxlLiBUaGVzZSB0d28gdmFsdWVzIG9mIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIHRoZSBudW1lcmF0b3IgYW5kIGRlbm9taW5hdG9yIGFyZSB0aGUgdHdvIHBhcmFtZXRlcnMgb2YgYSBGIGRpc3RyaWJ1dGlvbi4gDQoNClRoZSBmb2xsb3dpbmcgdmlzdWFsaXphdGlvbiBzaG93cyBGIGRpc3RyaWJ1dGlvbnMgZm9yIHZhcmlvdXMgdmFsdWVzIG9mIHRoZSBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIGVhY2ggb2YgdGhlIHR3byBpbmRlcGVuZGVudCBzYW1wbGVzLiBFYWNoIEYgZGlzdHJpYnV0aW9uIGhhcyB0d28gcGFyYW1ldGVycywgZGYxIGFuZCBkZjIsIHdoaWNoIGFyZSB0aGVzZSB0d28gZGVncmVlcyBvZiBmcmVlZG9tIHZhbHVlcy4gVGhpcyB2aXN1YWxpemF0aW9uIHNob3dzIGhvdyB0aGUgRiBkaXN0cmlidXRpb24gY2hhbmdlcyBpbiBhcHBlYXJlbmNlIGJhc2VkIHVwb24gdGhlc2UgdHdvIGRlZ3JlZXMgb2YgZnJlZWRvbSBwYXJhbWV0ZXJzLg0KDQpgYGB7cn0NCnggPC0gc2VxKDAsIDUsIGxlbmd0aCA9IDEwMDApDQoNCnlfMl8xMCAgPC0gZGYoeCwgZGYxID0gMiwgIGRmMiA9IDEwKQ0KeV81XzEwICA8LSBkZih4LCBkZjEgPSA1LCAgZGYyID0gMTApDQp5XzEwXzEwIDwtIGRmKHgsIGRmMSA9IDEwLCBkZjIgPSAxMCkNCg0KeV9tYXggPC0gbWF4KHlfMl8xMCwgeV81XzEwLCB5XzEwXzEwKQ0KDQpwbG90KHgsIHlfMl8xMCwNCiAgICAgdHlwZSA9ICJsIiwNCiAgICAgbHdkID0gMiwNCiAgICAgY29sID0gInB1cnBsZSIsDQogICAgIHlsaW0gPSBjKDAsIHlfbWF4KSwNCiAgICAgbWFpbiA9ICJGIERpc3RyaWJ1dGlvbnMgd2l0aCBEaWZmZXJlbnQgRGVncmVlcyBvZiBGcmVlZG9tIiwNCiAgICAgeGxhYiA9ICJ4IiwNCiAgICAgeWxhYiA9ICJEZW5zaXR5IikNCg0KbGluZXMoeCwgeV81XzEwLCAgbHdkID0gMiwgY29sID0gImxpZ2h0Ymx1ZSIpDQpsaW5lcyh4LCB5XzEwXzEwLCBsd2QgPSAyLCBjb2wgPSAiZ3JlZW4iKQ0KDQpsZWdlbmQoInRvcHJpZ2h0IiwNCiAgICAgICBsZWdlbmQgPSBjKCJkZjEgPSAyLCBkZjIgPSAxMCIsDQogICAgICAgICAgICAgICAgICAiZGYxID0gNSwgZGYyID0gMTAiLA0KICAgICAgICAgICAgICAgICAgImRmMSA9IDEwLCBkZjIgPSAxMCIpLA0KICAgICAgIGNvbCA9IGMoInB1cnBsZSIsICJsaWdodGJsdWUiLCAiZ3JlZW4iKSwNCiAgICAgICBsd2QgPSAyLA0KICAgICAgIGJ0eSA9ICJuIikNCmBgYA0KDQpUaGUgRiBkaXN0cmlidXRpb24gaXMgZGVmaW5lZCBmcm9tIDAgdG8gJFxpbmZ0eSQuDQoNCkFzIHNlZW4gYWJvdmUsIHRoZSBjdXJ2ZXMgb2YgYSBGIGRpc3RyaWJ1dGlvbiBhcyBza2V3ZWQgcmlnaHQgYW5kIGFzeW1tZXRyaWMuIFRoZXNlIGN1cnZlcyBkbyBub3QgZm9sbG93IGEgc3ltbWV0cmljLCBiZWxsLXNoYXBlZCBjdXJ2ZSB0aGF0IHRoZSBOb3JtYWwgZGlzdHJpYnV0aW9uIHdhcyBzZWVuIHRvIGZvbGxvdy4gSW4gZmFjdCwgdGhlc2UgY3VydmVzIGxvb2sgcXVpdGUgc2ltaWxhciB0byB3aGF0IHdhcyBzZWVuIHdpdGggdGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uLiBTaW1pbGFybHkgdG8gdGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uLCBmb3IgYSBGIGRpc3RyaWJ1dGlvbiwgc21hbGxlciB2YWx1ZXMgb2YgZGVncmVlcyBvZiBmcmVlZG9tIHNob3cgc3RlZXBlciwgYW5kIG1vcmUgc2tld2VkIGRpc3RyaWJ1dGlvbiB3aGlsZSBsYXJnZXIgdmFsdWVzIG9mIGRlZ3JlZXMgb2YgZnJlZWRvbSBzaG93IHdpZGVyIGRpc3RyaWJ1dGlvbnMgd2l0aCBsZXNzIHNrZXcgaW4gY29tcGFyaXNvbi4gSW4gZmFjdCwgdGhlIEYgZGlzdHJpYnV0aW9uIGNhbiBiZSBkZWZpbmVkIGJhc2VkIG9uIHR3byBpbmRlcGVuZGVudCBDaGktU3F1YXJlIGRpc3RyaWJ1dGlvbnMuIFRoZSBudW1lcmF0b3IgYW5kIGRlbm9taW5hdG9yIG9mIGEgRiBkaXN0cmlidXRpb24gY2FuIGJlIHdyaXR0ZW4gaW4gdGVybXMgb2YgdHdvIGluZGVwZW5kZW50IENoaS1TcXVhcmUgZGlzdHJpYnV0aW9ucy5JZiB0aGUgc2FtcGxlcyBhcmUgaW5kZXBlbmRlbnQgYW5kIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCB0aGVuICRcZnJhY3sobl8xIC0gMSlTXzFeMn17XHNpZ21hXzFeMn0gXHNpbSBcY2hpXjJfe25fMSAtIDF9LFxxcXVhZFxmcmFjeyhuXzIgLSAxKVNfMl4yfXtcc2lnbWFfMl4yfSBcc2ltIFxjaGleMl97bl8yIC0gMX0kLiBUYWtpbmcgdGhlIHJhdGlvIHJlc3VsdHMgaW4sICRcZnJhY3tTXzFeMn17U18yXjJ9IFxzaW0gRl97bl8xIC0gMSxcOyBuXzIgLSAxfSQuIE92ZXJhbGwsIHRoZSBGIGRpc3RyaWJ1dGlvbiBpcyBhIGdyZWF0IHdheSB0byBjb21wYXJlIHZhcmlhbmNlcyBiZXR3ZWVuIHRoZXNlIHR3byBpbmRlcGVuZGVudCBkaXN0cmlidXRpb25zLg0KDQoNCiMjIEFzc3VtbXB0aW9ucyBvZiBhIEYgRGlzdHJpYnV0aW9uDQoNCkluIG9yZGVyIHRvIHVzZSBhIEYgZGlzdHJpYnV0aW9uLCB0aGUgZm9sbG93aW5nIGFzc3VtcHRpb25zIG11c3QgYmUgbWV0Og0KDQotIFRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IGZyb20gb25lIGFub3RoZXIuDQoNCi0gRWFjaCBvZiB0aGUgdHdvIHNhbXBsZXMgYXJlIE5vcm1hbGx5IGRpc3RyaWJ1dGVkLiANCg0KLSBUaGUgc2FtcGxlcyBhcmUgZHJhd24gaW5kZXBlbmRlbnRseSBmcm9tIG9uZSBhbm90aGVyLiANCg0KLSBUaGUgcG9wdWxhdGlvbnMgc2hvdWxkIGhhdmUgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2VzIChlcXVhbCB2YXJpYW5jZXMpLg0KDQoNCg0KIyBDb25uZWN0aW9ucyBCZXR3ZWVuIFRoZXNlIERpc3RyaWJ1dGlvbnMNCg0KQWxsIGZvdXIgb2YgdGhlc2UgZGlzdHJpYnV0aW9ucywgdGhlIE5vcm1hbCBkaXN0cmlidXRpb24sIHRoZSB0LWRpc3RyaWJ1dGlvbiwgdGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uLCBhbmQgdGhlIEYgZGlzdHJpYnV0aW9uLCBhcmUgaW5jcmVkaWJseSBpbXBvcnRhbnQgdG8gc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIHJhbmRvbSBzYW1wbGluZy4gDQoNClRoZXNlIGRpc3RyaWJ1dGlvbnMgY29ubmVjdCB0byBvbmUgYW5vdGhlciBpbiBzZXZlcmFsIHdheXMuIEZvciBpbnN0YW5jZSwgdGhlIHN1bSBvZiBzcXVhcmVkIE5vcm1hbCB2YXJpYWJsZXMgZm9sbG93cyBhIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uLiBBZGRpdGlvbmFsbHksIGFub3RoZXIgZXhhbXBsZSBvZiB0aGlzIGlzIHRoYXQgYSBGIHN0YXRpc3RpYyBpcyB0aGUgcmF0aW8gb2YgdHdvIGluZGVwZW5kZW50IENoaS1TcXVhcmUgcmFuZG9tIHZhcmlhYmxlcy4gQW5vdGhlciBpbXBvcnRhbnQgb2NjdXJyZW5jZSBvZiB0aGlzIGlzIHRoYXQgaWYgJFogXHNpbSBOKDAsMSkkLCB0aGVuICRaXjIgXHNpbSBcY2hpXjIkLiBTbywgd2hpbGUgYWxsIGZvdXIgZGlzdHJpYnV0aW9ucyBoYXZlIGRpc3RpbmN0aW9ucyBmcm9tIG9uZSBhbm90aGVyLCB0aGV5IGFsc28gb3ZlcmxhcCBpbiBzZXZlcmFsIHdheXMgYW5kIHNob3cgY2xlYXIgY29ubmVjdGlvbnMgd2l0aCBlYWNoIG90aGVyLiANCg0KVGhlIHRhYmxlIGJlbG93IHNob3dzIGEgY2xlYXIgY29tcGFyaXNvbiBvZiBrZXkgZmVhdHVyZXMgb2YgdGhlIGZvdXIgZGlzdHJpYnV0aW9ucy4gVGhlc2UgZmVhdHVyZXMgaW5jbHVkZSBhIGJyaWVmIGRlc2NyaXB0aW9uIG9mIHRoZSBzaGFwZSBvZiBlYWNoIGRpc3RyaWJ1dGlvbiwgdGhlaXIgcGFyYW1hdGVycywgYW5kIHRoZSBzdXBwb3J0IG9mIHZhbHVlcyBmb3Igd2hpY2ggdGhlIGRpc3RyaWJ1dGlvbiBjYW4gdGFrZSBvbi4NCg0KYGBge3J9DQpkaXN0X3RhYmxlIDwtIGRhdGEuZnJhbWUoDQogIERpc3RyaWJ1dGlvbiA9IGMoIk5vcm1hbCIsICJ0IiwgIkNoaS1zcXVhcmUiLCAiRiIpLA0KICBTaGFwZSA9IGMoIlN5bW1ldHJpYyIsICJTeW1tZXRyaWMsIHRoaWNrZXIgdGFpbHMiLCAiUmlnaHQtc2tld2VkIiwgIlJpZ2h0LXNrZXdlZCIpLA0KICBTdXBwb3J0ID0gYygiJCgtXFxpbmZ0eSwgXFxpbmZ0eSkkIiwgIiQoLVxcaW5mdHksIFxcaW5mdHkpJCIsICIkKDAsIFxcaW5mdHkpJCIsICIkKDAsIFxcaW5mdHkpJCIpLA0KICBQYXJhbWV0ZXJzID0gYygiJFxcbXUsIFxcc2lnbWFeMiQiLCAiZGYodikiLCAiZGYiLCAiZGYkXzEkLCBkZiRfMiQiKQ0KKQ0KDQprYWJsZShkaXN0X3RhYmxlLCBmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEZBTFNFKQ0KDQpgYGANCg0KQWx0b2dldGhlciwgdGhlIE5vcm1hbCBkaXN0cmlidXRpb24sIHRoZSB0LWRpc3RyaWJ1dGlvbiwgdGhlIENoaS1TcXVhcmUgZGlzdHJpYnV0aW9uLCBhbmQgdGhlIEYgZGlzdHJpYnV0aW9uIGFyZSBhbGwgaW1wb3J0YW50IHN0YXRpc3RpY2FsIHRvb2xzIHdoZW4gaXQgY29tZXMgdG8gb2JzZXJ2aW5nIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYW5kIG1ha2luZyBhc3N1bXB0aW9ucyByZWdhcmRpbmcgdGhlIG92ZXJhbGwgcG9wdWxhdGlvbiBiYXNlZCB1cG9uIHRoZXNlIGRpc3RyaWJ1dGlvbnMuIFRoZXNlIGZvdXIgZGlzdHJpYnV0aW9ucyBoYXZlIGRpc3RpbmN0IGRpZmZlcmVuY2VzIGZyb20gb25lIGFub3RoZXIsIGJhc2VkIHVwb24gdGhlaXIgYXBwZWFyYW5jZSBhbmQgdGhlIHBhcmFtZXRlcnMgdXNlZCB3aXRoaW4gZWFjaCBkaXN0cmlidXRpb24uIEhvd2V2ZXIsIHRoZXNlIGRpc3RyaWJ1dGlvbnMgY29ubmVjdCB3aXRoIG9uZSBhbm90aGVyIGluIHZhcmlvdXMgd2F5cyB3aGljaCBzaG93cyB0aGUgaW1wb3J0YW5jZSBvZiBlYWNoIG9mIHRoZXNlIGRpc3RyaWJ1dGlvbnMgYmFzZWQgdXBvbiBob3cgdGhleSBjYW4gd29yayB0b2dldGhlciBiYXNlZCB1cG9uIHRyYW5zZm9ybWF0aW9ucyBvZiByYW5kb20gdmFyaWFibGVzIHRocm91Z2ggc3RhdGlzdGljYWwgcHJvY2VkdXJlcy4gDQoNCg0K