Question 1: Derive gradient (first order partial derivative)
of likelihood function
Assume that \(\{x_1, x_2, \cdots, x_n \}
\to \text{ gamma }(\alpha, \beta)\) with density function given
by
\[
f(x \mid \alpha, \beta) = \frac{1}{\Gamma(\alpha)\beta^\alpha}
x^{\alpha-1} e^{-x/\beta} \ \ \text{for} \ \ x > 0,
\]
Derive the gradient of the log-likelihood function
with respect to the gamma distribution parameters \(\alpha\) and \(\beta\). To this end,
a). Write out the full log-likelihood function based
on the given data and the density function provided above.
I will begin by finding the likelihood function.
\(L(\alpha, \beta) = \prod_{i=1}^{n}
\frac{1}{\Gamma(\alpha)\beta^\alpha} x_i^{\alpha-1}
e^{-x_i/\beta}\)
This likelihood function can be rewritten as follows.
\(L(\alpha, \beta) =
\left[\frac{1}{\Gamma(\alpha)\beta^\alpha}\right]^n \prod_{i=1}^{n}
x_i^{\alpha-1} \exp\left(-\frac{1}{\beta}\sum_{i=1}^{n}
x_i\right).\)
Next, I will take the logarithm of this likelihood function in order
to obtain the log-likelihood function.
\(\ell(\alpha, \beta) = \log L(\alpha,
\beta)\)
Taking the logarithm of the likelihood function results in:
\(\ell(\alpha, \beta) = -n \log
\Gamma(\alpha) - n\alpha \log \beta + (\alpha - 1)\sum_{i=1}^{n} \log
x_i - \frac{1}{\beta}\sum_{i=1}^{n} x_i\)
Therefore, this is the log-likelihood function of the Gamma
distribution with parameters \(\alpha\)
and \(\beta\).
b). Derive the score functions (the gradient of the log-likelihood)
from the full log-likelihood function in part (a).
First, I will derive the score function for \(\alpha\) from the log-likelihood function
that I found in the previous part. I will take the partial derivative
with respect to the \(\alpha\)
parameter. This will give the score function.
To begin, I know that \(\frac{d}{d\alpha}\log \Gamma(\alpha) =
\psi_0(\alpha)\) . So, I can use this fact to help with taking
the partial derivative of the log-likelihood function with respect to
the \(\alpha\) parameter. Doing so
results in the following:
\(\frac{\partial \ell}{\partial \alpha} =
-n\psi_0(\alpha) - n\log \beta + \sum_{i=1}^{n} \log x_i\)
Therefore the score function for \(\alpha\) is: \(s_\alpha(\alpha,\beta) = \sum_{i=1}^{n} \log x_i -
n\log \beta - n\psi(\alpha)\)
Now, I will find the score function for \(\beta\). I will begin by taking the
derivative with respect to \(\beta\) to
get the partial derivative for the \(\beta\) parameter. This will give the score
function.
To begin, I will differentiate the log-likelihood function with
respect to the \(\beta\) parameter.
From the original log-likelihood functions, there are two terms with the
\(\beta\) parameter. I know these
derivatives are as follows, \(\frac{\partial}{\partial \beta} (-n\alpha \log
\beta) = -\frac{n\alpha}{\beta}\) and \(\frac{\partial}{\partial \beta}
\left(-\frac{1}{\beta}\sum_{i=1}^{n} x_i\right) =
\frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)
So, the partial derivative of the log-likelihood function altogether
results in the following.
\(\frac{\partial \ell}{\partial \beta} =
-\frac{n\alpha}{\beta} + \frac{1}{\beta^2}\sum_{i=1}^{n}
x_i\)
Therefore, the score function for \(\beta\) is: \(s_\beta(\alpha,\beta) = -\frac{n\alpha}{\beta} +
\frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)
So altogether, the score functions for \(\alpha\) and \(\beta\), respectively are the
following:
\(s_\alpha(\alpha,\beta) = \sum_{i=1}^{n}
\log x_i - n\log \beta - n\psi(\alpha)\)
\(s_\beta(\alpha,\beta) =
-\frac{n\alpha}{\beta} + \frac{1}{\beta^2}\sum_{i=1}^{n}
x_i\)
Question 2: Birth data set
The following R code reads in a data set containing, for each of 7
days, the lengths of time in hours spent by women in the delivery suite
while giving birth (without a ceasarian section) at John Radcliffe
Hospital in Oxford, England. The data are taken from Davison
(Statistical Models. Cambridge University Press, 2003).
2.1, 3.4, 4.25, 5.6, 6.4, 7.3, 8.5, 8.75, 8.9, 9.5, 9.75, 10, 10.4, 10.4, 16, 19,
4, 4.1, 5, 5.5, 5.7, 6.5, 7.25, 7.3, 7.5, 8.2, 8.5, 9.75, 11, 11.2, 15, 16.5, 2.6,
3.6, 3.6, 6.4, 6.8, 7.5, 7.5, 8.25, 8.5, 10.4, 10.75, 14.25, 14.5, 1.5, 4.7, 4.7,
7.2, 7.25, 8.1, 8.5, 9.2, 9.5, 10.7, 11.5, 2.5, 2.5, 3.4, 4.2, 5.9, 6.25, 7.3, 7.5,
7.8, 8.3, 8.3, 10.25, 12.9, 14.3, 4, 4, 5.25, 6.1, 6.5, 6.9, 7, 8.45, 9.25, 10.1,
10.2, 12.75, 14.6, 2, 2.7, 2.75, 3.4, 4.2, 4.3, 4.9, 6.25, 7, 9, 9.25, 10.7
Assume the data are generated from a gamma distribution. The
objective is to use these data and the designated algorithm to find the
maximum likelihood estimates (MLEs) of the parameters \(\alpha\) and \(\beta\).
a). Find the MLEs of \(\alpha\) and
\(\beta\), denoted by \(\hat{\alpha}\) and \(\hat{\beta}\), using gradient-based
optimization via the R function optim() with the gradient
vector derived in Question 1.
I will begin by storing the data values in a data set that will be
named ‘time’.
time <- c(2.1, 3.4, 4.25, 5.6, 6.4, 7.3, 8.5, 8.75, 8.9, 9.5, 9.75, 10, 10.4, 10.4, 16, 19, 4, 4.1, 5, 5.5, 5.7, 6.5, 7.25, 7.3, 7.5, 8.2, 8.5, 9.75, 11, 11.2, 15, 16.5, 2.6, 3.6, 3.6, 6.4, 6.8, 7.5, 7.5, 8.25, 8.5, 10.4, 10.75, 14.25, 14.5, 1.5, 4.7, 4.7, 7.2, 7.25, 8.1, 8.5, 9.2, 9.5, 10.7, 11.5, 2.5, 2.5, 3.4, 4.2, 5.9, 6.25, 7.3, 7.5, 7.8, 8.3, 8.3, 10.25, 12.9, 14.3, 4, 4, 5.25, 6.1, 6.5, 6.9, 7, 8.45, 9.25, 10.1, 10.2, 12.75, 14.6, 2, 2.7, 2.75, 3.4, 4.2, 4.3, 4.9, 6.25, 7, 9, 9.25, 10.7)
Next, I will find the MLEs for \(\alpha\) and \(\beta\) by using the optim() function and
the score functions I found in question #1 part b.
n <- length(time)
# Log-likelihood function
loglik <- function(par){
alpha <- par[1]
beta <- par[2]
if(alpha <= 0 || beta <= 0) return(Inf)
-(-n*lgamma(alpha)
- n*alpha*log(beta)
+ (alpha-1)*sum(log(time))
- sum(time)/beta)}
# Gradient functions from question #1
grad <- function(par){
alpha <- par[1]
beta <- par[2]
d_alpha <- sum(log(time)) - n*log(beta) - n*digamma(alpha)
d_beta <- -n*alpha/beta + sum(time)/beta^2
return(-c(d_alpha, d_beta))
}
mean_time <- mean(time)
var_time <- var(time)
alpha_init <- mean_time^2 / var_time
beta_init <- var_time / mean_time
# Using the optim() function to get the MLEs
optim(c(alpha_init, beta_init),
loglik,
grad,
method="L-BFGS-B",
lower=c(1e-6,1e-6))
$par
[1] 4.387855 1.760122
$value
[1] 251.1173
$counts
function gradient
8 8
$convergence
[1] 0
$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"
It turns out that \(\hat{\alpha}\) =
4.388 and \(\hat{\beta}\) = 1.760.
b). Apply the method of moments to obtain estimators for \(\alpha\) and \(\beta\). Denote these moment estimators as
\(\tilde{\alpha}\) and \(\tilde{\beta}\).
In this part, I will apply the method of moments to obtain the
estimators for \(\alpha\) and \(\beta\). For a Gamma distribution, I know
that \(E(X) = \alpha \beta\) and Var(X)
= \(\alpha \beta^2\). I will write
these in terms of the sample mean \(\bar{x}\) and the sample variance \(s^2 = \alpha \beta^2\).
\(\tilde{\alpha} =
\frac{\bar{x}^2}{s^2}\)
\(\tilde{\beta} =
\frac{s^2}{\bar{x}}\)
Now, to calculate the values of \(\tilde{\alpha}\) and \(\tilde{\beta}\) based upon these
moments.
# Method of moments
alpha_mom <- mean_time^2 / var_time
beta_mom <- var_time / mean_time
alpha_mom
[1] 4.685073
beta_mom
[1] 1.64846
It turns out that \(\tilde{\alpha}\)
= 4.685 and \(\tilde{\beta}\) =
1.648.
c). Conduct a brief literature review comparing the method of moments
estimation (MME) and maximum likelihood estimation (MLE). Synthesize the
key advantages and limitations of each, concluding with a practical
recommendation.
I used both the method of moments estimation and the maximum
likelihood estimation to estimate the parameters \(\alpha\) and \(\beta\). Both the MLE and the MME methods
resulted in similar values. The MLE method resulted in \(\hat{\alpha}\) = 4.388 and \(\hat{\beta}\) = 1.760. The MME method
resulted in \(\tilde{\alpha}\) = 4.685
and \(\tilde{\beta}\) = 1.648. These
values are quite similar showing that both methods provide use in
estimating the parameters.
A major advantage of the Method of moments estimation method was that
it is simpler and quicker to compute. For this method, I used facts I
knew about the Gamma distribution and its mean and variance in order to
get the sample moments, and with some short calculations, this gave me
my parameter estimates. On the other hand, the maximum likelihood
function required some more complex calculations which required the use
of the R optim() function. This required a few extra steps and work to
obtain the MLE estimations due to the additional computations required,
and needing the use of the gradient functions I calculated in question
#1 for the partial derivatives to get the score functions.
However, the MLE method does bring some advantages of its own. The
MLE has strong asymptotic normality which brings consistency and states
that the distribution of the estimators, in this case \(\alpha\) and \(\beta\) will approach a Normal distribution
as the sample size increases to infinity. This property makes the MLE
method consistent, reliable, and efficient.
Some limitations of the MME method include that it can be prone to
bias, and this can happen especially in skewed distributions. This could
occur if the sample moments are not the best representations of the true
parameters they are estimating. Therefore, the MME does have some
drawbacks and limitations when it comes to potential bias in its
estimations if the population is skewed and therefore the sample moments
do not provide the greatest accuracy towards the true parameters. On the
other hand, the MLE method can also have some drawbacks. While the MLE
method is great for large samples, in the case of small samples it can
have some potential for bias as well. Additionally, the MLE method
requires more complexity in its calculations especially when compared to
the MME method.
Overall, I would use the Maximum likelihood estimation as the
preferred approach due to its consistency and reliability, even for
large sample sizes. The sample size in this scenario was significantly
large, meaning that the issue of the MLE having potential for bias in
small sample sizes will not be relevant in this case due to a large
sample size. Additionally, even though the MLE method requires more
complex calculations than the MME method, this trade off is worthwhile
due to the consistency and reliability of its calculations. The MLE
method is efficient and reliable, making it a great choice for
estimation. In this case, I would recommend the MLE method for these
reasons.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNDogTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24iDQphdXRob3I6ICJKb3NpZSBHYWxsb3AiDQpkYXRlOiAiIER1ZTogMDMtMDMtMjAyNiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCiMjIyMNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQogDQpcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIENvbXByZWhlbmQgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gYW5kIGl0cyBwcm9wZXJ0aWVzLg0KDQoqIE1hc3RlciB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gZnJhbWV3b3JrIGFuZCByZXF1aXJlZCBjb21wb25lbnRzLg0KDQoqIFVuZGVyc3RhbmQgdGhlIHBsdWctaW4gcHJpbmNpcGxlIHVuZGVybHlpbmcgTUxFLg0KDQoqIEltcGxlbWVudCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBwcm9jZWR1cmVzIGluIFIuDQoNClwNCg0KIyMgKipQb2xpY2llcyBvZiBVc2luZyBBSSBUb29scyoqDQoNCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFN0dWRlbnRzIG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuDQoNClwNCg0KKipHYW1tYSBEaXN0cmlidXRpb24gUmV2aXNpdGVkKioNCg0KTGV0ICRYJCBiZSB0aGUgdHdvIHBhcmFtZXRlciBHYW1tYSByYW5kb20gdmFyaWFibGUgd2l0aCBkZW5zaXR5IGZ1bmN0aW9uDQoNCiQkDQpmKHggXG1pZCBcYWxwaGEsIFxiZXRhKSA9IFxmcmFjezF9e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfSB4XntcYWxwaGEtMX0gZV57LXgvXGJldGF9ICBcIFwgXHRleHR7Zm9yfSBcIFwgIHggPiAwLA0KJCQNCg0Kd2hlcmUgd2l0aCAkXGFscGhhID4gMCQgKHNoYXBlKSwgJFxiZXRhPjAkIChzY2FsZSksIGFuZA0KDQokJA0KXEdhbW1hKFxhbHBoYSkgPSBcaW50X3swfV57XGluZnR5fSB0XntcYWxwaGEtMX0gZV57LXR9IFwsIGR0LCBccXVhZCBcYWxwaGEgPiAwLg0KJCQNCg0KJFxHYW1tYSh4KSQgY2FuIGJlIGNvbXB1dGVkIGluIFIgdXNpbmcgdGhlIGBnYW1tYSgpYCBmdW5jdGlvbi4gVGhlIGRlcml2YXRpdmUgb2YgJFxHYW1tYSh4KSQgYXJlIGdpdmVuIHJlc3BlY3RpdmVseSBieQ0KDQokJA0KXEdhbW1hXlxwcmltZSh6KSA9IFxHYW1tYSAoeilccHNpXzAoeikNCiQkDQoNCndoZXJlICRccHNpXzAoeikgPSBcZnJhY3tkfXtken0gXGxuIFxHYW1tYXt6fSQuIEluIFIsIHRoZSBkaWdhbW1hIGZ1bmN0aW9uICRccHNpXzAoeikkIGlzIGV2YWx1YXRlZCBieSBgZGlnYW1tYSgpYC4NCg0KDQoNClwNCg0KPGZvbnQgY29sb3IgPSAiYmx1ZSI+VGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gZmluZGluZyBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGUgb2YgcGFyYW1ldGVycyAkXGFscGhhJCBhbmQgJFxiZXRhJCBiYXNlZCBvbiBhIHJlYWwtd29ybGQgYXBwbGljYXRpb24gZGF0YSBzZXQuPC9mb250Pg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbiAxOiBEZXJpdmUgZ3JhZGllbnQgKGZpcnN0IG9yZGVyIHBhcnRpYWwgZGVyaXZhdGl2ZSkgb2YgbGlrZWxpaG9vZCBmdW5jdGlvbioqDQoNCkFzc3VtZSB0aGF0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcdG8gXHRleHR7IGdhbW1hIH0oXGFscGhhLCBcYmV0YSkkIHdpdGggZGVuc2l0eSBmdW5jdGlvbiBnaXZlbiBieQ0KDQokJA0KZih4IFxtaWQgXGFscGhhLCBcYmV0YSkgPSBcZnJhY3sxfXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX0geF57XGFscGhhLTF9IGVeey14L1xiZXRhfSAgXCBcIFx0ZXh0e2Zvcn0gXCBcICB4ID4gMCwNCiQkDQoNCkRlcml2ZSB0aGUgZ3JhZGllbnQgb2YgdGhlICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiB3aXRoIHJlc3BlY3QgdG8gdGhlIGdhbW1hIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzICRcYWxwaGEkIGFuZCAkXGJldGEkLiBUbyB0aGlzIGVuZCwNCg0KDQphKS4gV3JpdGUgb3V0IHRoZSBmdWxsICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiBiYXNlZCBvbiB0aGUgZ2l2ZW4gZGF0YSBhbmQgdGhlIGRlbnNpdHkgZnVuY3Rpb24gcHJvdmlkZWQgYWJvdmUuDQoNCkkgd2lsbCBiZWdpbiBieSBmaW5kaW5nIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uLiANCg0KJEwoXGFscGhhLCBcYmV0YSkgPSBccHJvZF97aT0xfV57bn0gXGZyYWN7MX17XEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGF9IHhfaV57XGFscGhhLTF9IGVeey14X2kvXGJldGF9JA0KDQpUaGlzIGxpa2VsaWhvb2QgZnVuY3Rpb24gY2FuIGJlIHJld3JpdHRlbiBhcyBmb2xsb3dzLg0KDQokTChcYWxwaGEsIFxiZXRhKSA9IFxsZWZ0W1xmcmFjezF9e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfVxyaWdodF1ebiBccHJvZF97aT0xfV57bn0geF9pXntcYWxwaGEtMX0gXGV4cFxsZWZ0KC1cZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2lccmlnaHQpLiQNCg0KTmV4dCwgSSB3aWxsIHRha2UgdGhlIGxvZ2FyaXRobSBvZiB0aGlzIGxpa2VsaWhvb2QgZnVuY3Rpb24gaW4gb3JkZXIgdG8gb2J0YWluIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbi4gDQoNCiRcZWxsKFxhbHBoYSwgXGJldGEpID0gXGxvZyBMKFxhbHBoYSwgXGJldGEpJA0KDQpUYWtpbmcgdGhlIGxvZ2FyaXRobSBvZiB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiByZXN1bHRzIGluOiANCg0KJFxlbGwoXGFscGhhLCBcYmV0YSkgPSAtbiBcbG9nIFxHYW1tYShcYWxwaGEpIC0gblxhbHBoYSBcbG9nIFxiZXRhICsgKFxhbHBoYSAtIDEpXHN1bV97aT0xfV57bn0gXGxvZyB4X2kgLSBcZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2kkDQoNClRoZXJlZm9yZSwgdGhpcyBpcyB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gb2YgdGhlIEdhbW1hIGRpc3RyaWJ1dGlvbiB3aXRoIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuDQoNCg0KYikuIERlcml2ZSB0aGUgc2NvcmUgZnVuY3Rpb25zICh0aGUgZ3JhZGllbnQgb2YgdGhlIGxvZy1saWtlbGlob29kKSBmcm9tIHRoZSBmdWxsICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiBpbiBwYXJ0IChhKS4NCg0KRmlyc3QsIEkgd2lsbCBkZXJpdmUgdGhlIHNjb3JlIGZ1bmN0aW9uIGZvciAkXGFscGhhJCBmcm9tIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiB0aGF0IEkgZm91bmQgaW4gdGhlIHByZXZpb3VzIHBhcnQuIEkgd2lsbCB0YWtlIHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIHRoZSAkXGFscGhhJCBwYXJhbWV0ZXIuIFRoaXMgd2lsbCBnaXZlIHRoZSBzY29yZSBmdW5jdGlvbi4NCg0KVG8gYmVnaW4sIEkga25vdyB0aGF0ICRcZnJhY3tkfXtkXGFscGhhfVxsb2cgXEdhbW1hKFxhbHBoYSkgPSBccHNpXzAoXGFscGhhKSQgLiBTbywgSSBjYW4gdXNlIHRoaXMgZmFjdCB0byBoZWxwIHdpdGggdGFraW5nIHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgJFxhbHBoYSQgcGFyYW1ldGVyLiBEb2luZyBzbyByZXN1bHRzIGluIHRoZSBmb2xsb3dpbmc6DQoNCiRcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcYWxwaGF9ID0gLW5ccHNpXzAoXGFscGhhKSAtIG5cbG9nIFxiZXRhICsgXHN1bV97aT0xfV57bn0gXGxvZyB4X2kkDQoNClRoZXJlZm9yZSB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYWxwaGEkIGlzOg0KJHNfXGFscGhhKFxhbHBoYSxcYmV0YSkgPSBcc3VtX3tpPTF9XntufSBcbG9nIHhfaSAtIG5cbG9nIFxiZXRhIC0gblxwc2koXGFscGhhKSQNCg0KDQoNCg0KTm93LCBJIHdpbGwgZmluZCB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYmV0YSQuIEkgd2lsbCBiZWdpbiBieSB0YWtpbmcgdGhlIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvICRcYmV0YSQgdG8gZ2V0IHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgZm9yIHRoZSAkXGJldGEkIHBhcmFtZXRlci4gVGhpcyB3aWxsIGdpdmUgdGhlIHNjb3JlIGZ1bmN0aW9uLg0KDQpUbyBiZWdpbiwgSSB3aWxsIGRpZmZlcmVudGlhdGUgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgJFxiZXRhJCBwYXJhbWV0ZXIuIEZyb20gdGhlIG9yaWdpbmFsIGxvZy1saWtlbGlob29kIGZ1bmN0aW9ucywgdGhlcmUgYXJlIHR3byB0ZXJtcyB3aXRoIHRoZSAkXGJldGEkIHBhcmFtZXRlci4gSSBrbm93IHRoZXNlIGRlcml2YXRpdmVzIGFyZSBhcyBmb2xsb3dzLA0KJFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYmV0YX0gKC1uXGFscGhhIFxsb2cgXGJldGEpID0gLVxmcmFje25cYWxwaGF9e1xiZXRhfSQgYW5kICRcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGJldGF9IFxsZWZ0KC1cZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2lccmlnaHQpID0gXGZyYWN7MX17XGJldGFeMn1cc3VtX3tpPTF9XntufSB4X2kkDQoNClNvLCB0aGUgcGFydGlhbCBkZXJpdmF0aXZlIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiBhbHRvZ2V0aGVyIHJlc3VsdHMgaW4gdGhlIGZvbGxvd2luZy4NCg0KJFxmcmFje1xwYXJ0aWFsIFxlbGx9e1xwYXJ0aWFsIFxiZXRhfSA9IC1cZnJhY3tuXGFscGhhfXtcYmV0YX0gKyBcZnJhY3sxfXtcYmV0YV4yfVxzdW1fe2k9MX1ee259IHhfaSQNCg0KVGhlcmVmb3JlLCB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYmV0YSQgaXM6DQokc19cYmV0YShcYWxwaGEsXGJldGEpID0gLVxmcmFje25cYWxwaGF9e1xiZXRhfSArIFxmcmFjezF9e1xiZXRhXjJ9XHN1bV97aT0xfV57bn0geF9pJA0KDQoNClNvIGFsdG9nZXRoZXIsIHRoZSBzY29yZSBmdW5jdGlvbnMgZm9yICRcYWxwaGEkIGFuZCAkXGJldGEkLCByZXNwZWN0aXZlbHkgYXJlIHRoZSBmb2xsb3dpbmc6DQoNCiRzX1xhbHBoYShcYWxwaGEsXGJldGEpID0gXHN1bV97aT0xfV57bn0gXGxvZyB4X2kgLSBuXGxvZyBcYmV0YSAtIG5ccHNpKFxhbHBoYSkkDQoNCiRzX1xiZXRhKFxhbHBoYSxcYmV0YSkgPSAtXGZyYWN7blxhbHBoYX17XGJldGF9ICsgXGZyYWN7MX17XGJldGFeMn1cc3VtX3tpPTF9XntufSB4X2kkDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uIDI6IEJpcnRoIGRhdGEgc2V0KioNCg0KVGhlIGZvbGxvd2luZyBSIGNvZGUgcmVhZHMgaW4gYSBkYXRhIHNldCBjb250YWluaW5nLCBmb3IgZWFjaCBvZiA3IGRheXMsIHRoZSBsZW5ndGhzIG9mIHRpbWUgaW4gaG91cnMgc3BlbnQgYnkNCndvbWVuIGluIHRoZSBkZWxpdmVyeSBzdWl0ZSB3aGlsZSBnaXZpbmcgYmlydGggKHdpdGhvdXQgYSBjZWFzYXJpYW4gc2VjdGlvbikgYXQgSm9obiBSYWRjbGlmZmUgSG9zcGl0YWwgaW4NCk94Zm9yZCwgRW5nbGFuZC4gVGhlIGRhdGEgYXJlIHRha2VuIGZyb20gRGF2aXNvbiAoU3RhdGlzdGljYWwgTW9kZWxzLiBDYW1icmlkZ2UgVW5pdmVyc2l0eSBQcmVzcywgMjAwMykuDQoNCmBgYA0KMi4xLCAzLjQsIDQuMjUsIDUuNiwgNi40LCA3LjMsIDguNSwgOC43NSwgOC45LCA5LjUsIDkuNzUsIDEwLCAxMC40LCAxMC40LCAxNiwgMTksDQo0LCA0LjEsIDUsIDUuNSwgNS43LCA2LjUsIDcuMjUsIDcuMywgNy41LCA4LjIsIDguNSwgOS43NSwgMTEsIDExLjIsIDE1LCAxNi41LCAyLjYsIA0KMy42LCAzLjYsIDYuNCwgNi44LCA3LjUsIDcuNSwgOC4yNSwgOC41LCAxMC40LCAxMC43NSwgMTQuMjUsIDE0LjUsIDEuNSwgNC43LCA0LjcsIA0KNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgDQo3LjgsIDguMywgOC4zLCAxMC4yNSwgMTIuOSwgMTQuMywgNCwgNCwgNS4yNSwgNi4xLCA2LjUsIDYuOSwgNywgOC40NSwgOS4yNSwgMTAuMSwgDQoxMC4yLCAxMi43NSwgMTQuNiwgMiwgMi43LCAyLjc1LCAzLjQsIDQuMiwgNC4zLCA0LjksIDYuMjUsIDcsIDksIDkuMjUsIDEwLjcNCmBgYA0KDQpBc3N1bWUgdGhlIGRhdGEgYXJlIGdlbmVyYXRlZCBmcm9tIGEgZ2FtbWEgZGlzdHJpYnV0aW9uLiBUaGUgb2JqZWN0aXZlIGlzIHRvIHVzZSB0aGVzZSBkYXRhIGFuZCB0aGUgZGVzaWduYXRlZCBhbGdvcml0aG0gdG8gZmluZCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlcyAoTUxFcykgb2YgdGhlIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuDQoNCg0KYSkuIEZpbmQgdGhlIE1MRXMgb2YgJFxhbHBoYSQgYW5kICRcYmV0YSQsIGRlbm90ZWQgYnkgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQsICB1c2luZyBncmFkaWVudC1iYXNlZCBvcHRpbWl6YXRpb24gdmlhIHRoZSBSIGZ1bmN0aW9uIGBvcHRpbSgpYCB3aXRoIHRoZSBncmFkaWVudCB2ZWN0b3IgZGVyaXZlZCBpbiBRdWVzdGlvbiAxLg0KDQpJIHdpbGwgYmVnaW4gYnkgc3RvcmluZyB0aGUgZGF0YSB2YWx1ZXMgaW4gYSBkYXRhIHNldCB0aGF0IHdpbGwgYmUgbmFtZWQgJ3RpbWUnLg0KDQpgYGB7cn0NCnRpbWUgPC0gYygyLjEsIDMuNCwgNC4yNSwgNS42LCA2LjQsIDcuMywgOC41LCA4Ljc1LCA4LjksIDkuNSwgOS43NSwgMTAsIDEwLjQsIDEwLjQsIDE2LCAxOSwgNCwgNC4xLCA1LCA1LjUsIDUuNywgNi41LCA3LjI1LCA3LjMsIDcuNSwgOC4yLCA4LjUsIDkuNzUsIDExLCAxMS4yLCAxNSwgMTYuNSwgMi42LCAzLjYsIDMuNiwgNi40LCA2LjgsIDcuNSwgNy41LCA4LjI1LCA4LjUsIDEwLjQsIDEwLjc1LCAxNC4yNSwgMTQuNSwgMS41LCA0LjcsIDQuNywgNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgNy44LCA4LjMsIDguMywgMTAuMjUsIDEyLjksIDE0LjMsIDQsIDQsIDUuMjUsIDYuMSwgNi41LCA2LjksIDcsIDguNDUsIDkuMjUsIDEwLjEsIDEwLjIsIDEyLjc1LCAxNC42LCAyLCAyLjcsIDIuNzUsIDMuNCwgNC4yLCA0LjMsIDQuOSwgNi4yNSwgNywgOSwgOS4yNSwgMTAuNykNCmBgYA0KDQpOZXh0LCBJIHdpbGwgZmluZCB0aGUgTUxFcyBmb3IgJFxhbHBoYSQgYW5kICRcYmV0YSQgYnkgdXNpbmcgdGhlIG9wdGltKCkgZnVuY3Rpb24gYW5kIHRoZSBzY29yZSBmdW5jdGlvbnMgSSBmb3VuZCBpbiBxdWVzdGlvbiAjMSBwYXJ0IGIuIA0KDQpgYGB7cn0NCm4gPC0gbGVuZ3RoKHRpbWUpDQoNCiMgTG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24NCmxvZ2xpayA8LSBmdW5jdGlvbihwYXIpew0KICBhbHBoYSA8LSBwYXJbMV0NCiAgYmV0YSAgPC0gcGFyWzJdDQogIA0KICBpZihhbHBoYSA8PSAwIHx8IGJldGEgPD0gMCkgcmV0dXJuKEluZikNCiAgDQogIC0oLW4qbGdhbW1hKGFscGhhKSANCiAgICAtIG4qYWxwaGEqbG9nKGJldGEpDQogICAgKyAoYWxwaGEtMSkqc3VtKGxvZyh0aW1lKSkNCiAgICAtIHN1bSh0aW1lKS9iZXRhKX0NCg0KIyBHcmFkaWVudCBmdW5jdGlvbnMgZnJvbSBxdWVzdGlvbiAjMQ0KZ3JhZCA8LSBmdW5jdGlvbihwYXIpew0KICBhbHBoYSA8LSBwYXJbMV0NCiAgYmV0YSAgPC0gcGFyWzJdDQogIA0KICBkX2FscGhhIDwtIHN1bShsb2codGltZSkpIC0gbipsb2coYmV0YSkgLSBuKmRpZ2FtbWEoYWxwaGEpDQogIGRfYmV0YSAgPC0gLW4qYWxwaGEvYmV0YSArIHN1bSh0aW1lKS9iZXRhXjINCiAgDQogIHJldHVybigtYyhkX2FscGhhLCBkX2JldGEpKQ0KfQ0KDQptZWFuX3RpbWUgPC0gbWVhbih0aW1lKQ0KdmFyX3RpbWUgPC0gdmFyKHRpbWUpDQoNCmFscGhhX2luaXQgPC0gbWVhbl90aW1lXjIgLyB2YXJfdGltZQ0KYmV0YV9pbml0ICA8LSB2YXJfdGltZSAvIG1lYW5fdGltZQ0KDQojIFVzaW5nIHRoZSBvcHRpbSgpIGZ1bmN0aW9uIHRvIGdldCB0aGUgTUxFcw0Kb3B0aW0oYyhhbHBoYV9pbml0LCBiZXRhX2luaXQpLA0KICAgICAgbG9nbGlrLA0KICAgICAgZ3JhZCwNCiAgICAgIG1ldGhvZD0iTC1CRkdTLUIiLA0KICAgICAgbG93ZXI9YygxZS02LDFlLTYpKQ0KYGBgDQoNCkl0IHR1cm5zIG91dCB0aGF0ICRcaGF0e1xhbHBoYX0kID0gNC4zODggYW5kICRcaGF0e1xiZXRhfSQgPSAxLjc2MC4gDQoNCg0KYikuIEFwcGx5IHRoZSBtZXRob2Qgb2YgbW9tZW50cyB0byBvYnRhaW4gZXN0aW1hdG9ycyBmb3IgJFxhbHBoYSQgYW5kICRcYmV0YSQuIERlbm90ZSB0aGVzZSBtb21lbnQgZXN0aW1hdG9ycyBhcyAkXHRpbGRle1xhbHBoYX0kIGFuZCAkXHRpbGRle1xiZXRhfSQuDQoNCkluIHRoaXMgcGFydCwgSSB3aWxsIGFwcGx5IHRoZSBtZXRob2Qgb2YgbW9tZW50cyB0byBvYnRhaW4gdGhlIGVzdGltYXRvcnMgZm9yICRcYWxwaGEkIGFuZCAkXGJldGEkLiAgRm9yIGEgR2FtbWEgZGlzdHJpYnV0aW9uLCBJIGtub3cgdGhhdCAkRShYKSA9IFxhbHBoYSBcYmV0YSQgYW5kIFZhcihYKSA9ICRcYWxwaGEgXGJldGFeMiQuIEkgd2lsbCB3cml0ZSB0aGVzZSBpbiB0ZXJtcyBvZiB0aGUgc2FtcGxlIG1lYW4gJFxiYXJ7eH0kIGFuZCB0aGUgc2FtcGxlIHZhcmlhbmNlICRzXjIgPSBcYWxwaGEgXGJldGFeMiQuIA0KDQokXHRpbGRle1xhbHBoYX0gPSBcZnJhY3tcYmFye3h9XjJ9e3NeMn0kDQoNCiRcdGlsZGV7XGJldGF9ID0gXGZyYWN7c14yfXtcYmFye3h9fSQNCg0KTm93LCB0byBjYWxjdWxhdGUgdGhlIHZhbHVlcyBvZiAkXHRpbGRle1xhbHBoYX0kIGFuZCAkXHRpbGRle1xiZXRhfSQgYmFzZWQgdXBvbiB0aGVzZSBtb21lbnRzLiANCg0KYGBge3J9DQojIE1ldGhvZCBvZiBtb21lbnRzDQphbHBoYV9tb20gPC0gbWVhbl90aW1lXjIgLyB2YXJfdGltZQ0KYmV0YV9tb20gIDwtIHZhcl90aW1lIC8gbWVhbl90aW1lDQoNCmFscGhhX21vbQ0KYmV0YV9tb20NCmBgYA0KDQpJdCB0dXJucyBvdXQgdGhhdCAkXHRpbGRle1xhbHBoYX0kID0gNC42ODUgYW5kICRcdGlsZGV7XGJldGF9JCA9IDEuNjQ4LiANCg0KDQpjKS4gQ29uZHVjdCBhIGJyaWVmIGxpdGVyYXR1cmUgcmV2aWV3IGNvbXBhcmluZyB0aGUgbWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdGlvbiAoTU1FKSBhbmQgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gKE1MRSkuIFN5bnRoZXNpemUgdGhlIGtleSBhZHZhbnRhZ2VzIGFuZCBsaW1pdGF0aW9ucyBvZiBlYWNoLCBjb25jbHVkaW5nIHdpdGggYSBwcmFjdGljYWwgcmVjb21tZW5kYXRpb24uDQoNCkkgdXNlZCBib3RoIHRoZSBtZXRob2Qgb2YgbW9tZW50cyBlc3RpbWF0aW9uIGFuZCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gdG8gZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuIEJvdGggdGhlIE1MRSBhbmQgdGhlIE1NRSBtZXRob2RzIHJlc3VsdGVkIGluIHNpbWlsYXIgdmFsdWVzLiBUaGUgTUxFIG1ldGhvZCByZXN1bHRlZCBpbiAkXGhhdHtcYWxwaGF9JCA9IDQuMzg4IGFuZCAkXGhhdHtcYmV0YX0kID0gMS43NjAuIFRoZSBNTUUgbWV0aG9kIHJlc3VsdGVkIGluICRcdGlsZGV7XGFscGhhfSQgPSA0LjY4NSBhbmQgJFx0aWxkZXtcYmV0YX0kID0gMS42NDguIFRoZXNlIHZhbHVlcyBhcmUgcXVpdGUgc2ltaWxhciBzaG93aW5nIHRoYXQgYm90aCBtZXRob2RzIHByb3ZpZGUgdXNlIGluIGVzdGltYXRpbmcgdGhlIHBhcmFtZXRlcnMuIA0KDQpBIG1ham9yIGFkdmFudGFnZSBvZiB0aGUgTWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdGlvbiBtZXRob2Qgd2FzIHRoYXQgaXQgaXMgc2ltcGxlciBhbmQgcXVpY2tlciB0byBjb21wdXRlLiBGb3IgdGhpcyBtZXRob2QsIEkgdXNlZCBmYWN0cyBJIGtuZXcgYWJvdXQgdGhlIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgaXRzIG1lYW4gYW5kIHZhcmlhbmNlIGluIG9yZGVyIHRvIGdldCB0aGUgc2FtcGxlIG1vbWVudHMsIGFuZCB3aXRoIHNvbWUgc2hvcnQgY2FsY3VsYXRpb25zLCB0aGlzIGdhdmUgbWUgbXkgcGFyYW1ldGVyIGVzdGltYXRlcy4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSBtYXhpbXVtIGxpa2VsaWhvb2QgZnVuY3Rpb24gcmVxdWlyZWQgc29tZSBtb3JlIGNvbXBsZXggY2FsY3VsYXRpb25zIHdoaWNoIHJlcXVpcmVkIHRoZSB1c2Ugb2YgdGhlIFIgb3B0aW0oKSBmdW5jdGlvbi4gVGhpcyByZXF1aXJlZCBhIGZldyBleHRyYSBzdGVwcyBhbmQgd29yayB0byBvYnRhaW4gdGhlIE1MRSBlc3RpbWF0aW9ucyBkdWUgdG8gdGhlIGFkZGl0aW9uYWwgY29tcHV0YXRpb25zIHJlcXVpcmVkLCBhbmQgbmVlZGluZyB0aGUgdXNlIG9mIHRoZSBncmFkaWVudCBmdW5jdGlvbnMgSSBjYWxjdWxhdGVkIGluIHF1ZXN0aW9uICMxIGZvciB0aGUgcGFydGlhbCBkZXJpdmF0aXZlcyB0byBnZXQgdGhlIHNjb3JlIGZ1bmN0aW9ucy4gDQoNCkhvd2V2ZXIsIHRoZSBNTEUgbWV0aG9kIGRvZXMgYnJpbmcgc29tZSBhZHZhbnRhZ2VzIG9mIGl0cyBvd24uIFRoZSBNTEUgaGFzIHN0cm9uZyBhc3ltcHRvdGljIG5vcm1hbGl0eSB3aGljaCBicmluZ3MgY29uc2lzdGVuY3kgYW5kIHN0YXRlcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIGVzdGltYXRvcnMsIGluIHRoaXMgY2FzZSAkXGFscGhhJCBhbmQgJFxiZXRhJCB3aWxsIGFwcHJvYWNoIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyB0aGUgc2FtcGxlIHNpemUgaW5jcmVhc2VzIHRvIGluZmluaXR5LiBUaGlzIHByb3BlcnR5IG1ha2VzIHRoZSBNTEUgbWV0aG9kIGNvbnNpc3RlbnQsIHJlbGlhYmxlLCBhbmQgZWZmaWNpZW50LiANCg0KU29tZSBsaW1pdGF0aW9ucyBvZiB0aGUgTU1FIG1ldGhvZCBpbmNsdWRlIHRoYXQgaXQgY2FuIGJlIHByb25lIHRvIGJpYXMsIGFuZCB0aGlzIGNhbiBoYXBwZW4gZXNwZWNpYWxseSBpbiBza2V3ZWQgZGlzdHJpYnV0aW9ucy4gVGhpcyBjb3VsZCBvY2N1ciBpZiB0aGUgc2FtcGxlIG1vbWVudHMgYXJlIG5vdCB0aGUgYmVzdCByZXByZXNlbnRhdGlvbnMgb2YgdGhlIHRydWUgcGFyYW1ldGVycyB0aGV5IGFyZSBlc3RpbWF0aW5nLiBUaGVyZWZvcmUsIHRoZSBNTUUgZG9lcyBoYXZlIHNvbWUgZHJhd2JhY2tzIGFuZCBsaW1pdGF0aW9ucyB3aGVuIGl0IGNvbWVzIHRvIHBvdGVudGlhbCBiaWFzIGluIGl0cyBlc3RpbWF0aW9ucyBpZiB0aGUgcG9wdWxhdGlvbiBpcyBza2V3ZWQgYW5kIHRoZXJlZm9yZSB0aGUgc2FtcGxlIG1vbWVudHMgZG8gbm90IHByb3ZpZGUgdGhlIGdyZWF0ZXN0IGFjY3VyYWN5IHRvd2FyZHMgdGhlIHRydWUgcGFyYW1ldGVycy4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSBNTEUgbWV0aG9kIGNhbiBhbHNvIGhhdmUgc29tZSBkcmF3YmFja3MuIFdoaWxlIHRoZSBNTEUgbWV0aG9kIGlzIGdyZWF0IGZvciBsYXJnZSBzYW1wbGVzLCBpbiB0aGUgY2FzZSBvZiBzbWFsbCBzYW1wbGVzIGl0IGNhbiBoYXZlIHNvbWUgcG90ZW50aWFsIGZvciBiaWFzIGFzIHdlbGwuIEFkZGl0aW9uYWxseSwgdGhlIE1MRSBtZXRob2QgcmVxdWlyZXMgbW9yZSBjb21wbGV4aXR5IGluIGl0cyBjYWxjdWxhdGlvbnMgZXNwZWNpYWxseSB3aGVuIGNvbXBhcmVkIHRvIHRoZSBNTUUgbWV0aG9kLiANCg0KT3ZlcmFsbCwgSSB3b3VsZCB1c2UgdGhlIE1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIGFzIHRoZSBwcmVmZXJyZWQgYXBwcm9hY2ggZHVlIHRvIGl0cyBjb25zaXN0ZW5jeSBhbmQgcmVsaWFiaWxpdHksIGV2ZW4gZm9yIGxhcmdlIHNhbXBsZSBzaXplcy4gVGhlIHNhbXBsZSBzaXplIGluIHRoaXMgc2NlbmFyaW8gd2FzIHNpZ25pZmljYW50bHkgbGFyZ2UsIG1lYW5pbmcgdGhhdCB0aGUgaXNzdWUgb2YgdGhlIE1MRSBoYXZpbmcgcG90ZW50aWFsIGZvciBiaWFzIGluIHNtYWxsIHNhbXBsZSBzaXplcyB3aWxsIG5vdCBiZSByZWxldmFudCBpbiB0aGlzIGNhc2UgZHVlIHRvIGEgbGFyZ2Ugc2FtcGxlIHNpemUuIEFkZGl0aW9uYWxseSwgZXZlbiB0aG91Z2ggdGhlIE1MRSBtZXRob2QgcmVxdWlyZXMgbW9yZSBjb21wbGV4IGNhbGN1bGF0aW9ucyB0aGFuIHRoZSBNTUUgbWV0aG9kLCB0aGlzIHRyYWRlIG9mZiBpcyB3b3J0aHdoaWxlIGR1ZSB0byB0aGUgY29uc2lzdGVuY3kgYW5kIHJlbGlhYmlsaXR5IG9mIGl0cyBjYWxjdWxhdGlvbnMuIFRoZSBNTEUgbWV0aG9kIGlzIGVmZmljaWVudCBhbmQgcmVsaWFibGUsIG1ha2luZyBpdCBhIGdyZWF0IGNob2ljZSBmb3IgZXN0aW1hdGlvbi4gSW4gdGhpcyBjYXNlLCBJIHdvdWxkIHJlY29tbWVuZCB0aGUgTUxFIG1ldGhvZCBmb3IgdGhlc2UgcmVhc29ucy4g