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.
true.alpha <- 2.5
true.beta <- 1.8
sample.data= rgamma(1000, shape = true.alpha, scale = true.beta )
# Log-Likelihood Function (to simplify computation)
gammas.loglik = function(params, data)
{
alpha_shape = params[1] #shape parameter
beta_scale = params[2] # scale parameter
n = length(data)
# giving a log to the gamma distribution function and simplifying the equation
#replacing log(alpha)or log(gamma(alpha)) with lgamma()
loglik_gamma = -n * lgamma(alpha_shape) -
n * alpha_shape * log(beta_scale) +
(alpha_shape - 1) * sum(log(data)) -
(1/beta_scale) * sum(data)
return(loglik_gamma)
}
Expanding the log and crafting the summation \[
\ell(\alpha, \beta)= \sum [ln(1)-ln\Gamma(\alpha)-ln(\beta^\alpha) +
ln(x_i^{\alpha-1})+ln(e^{-x_i/\beta})]
\]
The log likelihood function of the gamma distribution function: \[
\ell(x \mid \alpha, \beta)= -n \ln \Gamma(\alpha) - n \alpha \ln(\beta)
+ (\alpha - 1) \sum_{i=1}^{n} \ln(x_i) - \frac{1}{\beta} \sum_{i=1}^{n}
x_i
\]
b). Derive the score functions (the gradient of the log-likelihood)
from the full log-likelihood function in part (a).
# Corrected Score Function
gamma.score = function(params, data)
{
alpha_shape = params[1]
beta_scale = params[2]
n = length(data)
# Getting the gradient parameters, replacing with digamma
gradient_alpha = -n * digamma(alpha_shape) - n * log(beta_scale) + sum(log(data)) #Partial derivative to alpha #The first derivative of log gamma function which you need for the partial derivatives mentioned
gradient_beta = -(n * alpha_shape) / beta_scale + sum(data) / (beta_scale^2)
#Partial derivative with respect to Beta
return(c(gradient_alpha, gradient_beta))
}
Performing the log likelihood partial derivatives for the Gamma
distribution.
Taking the partial derivative in respect to the parameter \(\alpha\).
\[
\frac{\partial \ell}{\partial \alpha} = \frac{\partial}{\partial \alpha}
\left[ -n \ln \Gamma(\alpha) - n \alpha \ln(\beta) + (\alpha - 1)
\sum_{i=1}^{n} \ln(x_i) - \frac{1}{\beta} \sum_{i=1}^{n} x_i \right]
\]
\[
\frac{\partial}{\partial \alpha} [-n \ln \Gamma(\alpha)] = -n
\psi_0(\alpha)
\]
\[
\frac{\partial}{\partial \alpha} [-n \alpha \ln(\beta)] = -n \ln(\beta)
\]
\[
\frac{\partial}{\partial \alpha} [(\alpha - 1) \sum \ln(x_i)] = \sum
\ln(x_i)
\]
\[
\frac{\partial}{\partial \alpha} [-\frac{1}{\beta} \sum x_i] = 0
\]
\[
U_\alpha = -n \psi_0(\alpha) - n \ln(\beta) + \sum_{i=1}^{n} \ln(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.
databirth= sort(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))
#gammas.loglik(params = params, data = databirth)
# Score Function to reach the gradient function of alpha and beta
gamma.score = function(params, data)
{
alpha_shape = params[1]
beta_scale = params[2]
n = length(data)
# Math Fix: Combined into one expression
gradient_alpha = -n * digamma(alpha_shape) - n * log(beta_scale) + sum(log(data))
gradient_beta = -(n * alpha_shape) / beta_scale + sum(data) / (beta_scale^2)
return(c(gradient_alpha, gradient_beta))
}
initial.params = c(alpha_shape = 5 , beta_scale= 2 ) #change later
#Using optim() to reach gradient, gamma is a nonlinear, nonclosed function. We use optim() to get more accurate parameters
mle.result <- optim(
par = initial.params,
fn = gammas.loglik, # fn, maps the territory of the function to follow/find the height of the function(here it is the gamma function)
gr = gamma.score, # scored gamma function --> needed for gradient
data = databirth,
method = "L-BFGS-B", # Best for gradients + bounds
hessian = TRUE, # A matrix second order partial derivatives. If the Gradient is the first derivative (slope), the hessian is the second derivative (curvature)
control = list(trace = FALSE,
fnscale = -1, # We want to MAXIMIZE the log-likelihood, so choose -1
maxit = 500,
abstol = 1e-8)
)
mle.result
$par
alpha_shape beta_scale
4.387853 1.760123
$value
[1] -251.1173
$counts
function gradient
13 13
$convergence
[1] 0
$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"
$hessian
alpha_shape beta_scale
alpha_shape -24.30334 -53.97352
beta_scale -53.97352 -134.55199
The predicted shape parameter in the birth times is $$ = 4.387853.
The predicted scale parameter \(\hat\beta\) = 1.7601226.
b). Apply the method of moments to obtain estimators for \(\alpha\) and \(\beta\). Denote these moment estimators as
\(\tilde{\alpha}\) and \(\tilde{\beta}\).
#MME: Method of Moments (Scale Parameter)
m1 <- mean(databirth)
s2 <- var(databirth) # Sample Variance (s^2)
# Scale parameter MoM formulas:
mom_beta <- s2 / m1 # This is the Scale Beta
mom_alpha <- m1^2 / s2 # This is the Shape Alpha
#mom_beta
#mom_alpha
initial.params = c(alpha_shape = mom_alpha, beta_scale= mom_beta ) #change later
#Using optim like above 2a to optimze() the nonlinear and nonclosed function of the method of moment estimators mme
mle.result <- optim(
par = initial.params,
fn = gammas.loglik, # gamma function
gr = gamma.score, # scored gamma function
data = databirth,
method = "L-BFGS-B", # Best for gradients + bounds
hessian = TRUE,
control = list(trace = FALSE,
fnscale = -1, # We want to MAXIMIZE the log-likelihood, so choose -1
maxit = 500,
abstol = 1e-8)
)
mle.result
$par
alpha_shape beta_scale
4.387854 1.760122
$value
[1] -251.1173
$counts
function gradient
8 8
$convergence
[1] 0
$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"
$hessian
alpha_shape beta_scale
alpha_shape -24.30333 -53.97352
beta_scale -53.97352 -134.55199
The method of moments estimators for \(\tilde{\alpha}\) is 4.6850734 and \(\tilde{\beta}\) is 1.6484604.
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.
Method of moments estimation (MME) and Maximum likelihood estimation
(MLE) are both methods to connect distributions with estimated
parameters using a random sample. The method of moment estimation (MME)
is a simpler test than the Maximum likelihood estimation (MLE).
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNDogTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24iDQphdXRob3I6ICJFemFuYSBSaXZlcnMiDQpkYXRlOiAiIER1ZTogMDMtMDMtMjAyNiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCiMjIyMNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQogDQpcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIENvbXByZWhlbmQgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gYW5kIGl0cyBwcm9wZXJ0aWVzLg0KDQoqIE1hc3RlciB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gZnJhbWV3b3JrIGFuZCByZXF1aXJlZCBjb21wb25lbnRzLg0KDQoqIFVuZGVyc3RhbmQgdGhlIHBsdWctaW4gcHJpbmNpcGxlIHVuZGVybHlpbmcgTUxFLg0KDQoqIEltcGxlbWVudCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBwcm9jZWR1cmVzIGluIFIuDQoNClwNCg0KIyMgKipQb2xpY2llcyBvZiBVc2luZyBBSSBUb29scyoqDQoNCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFN0dWRlbnRzIG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuDQoNClwNCg0KKipHYW1tYSBEaXN0cmlidXRpb24gUmV2aXNpdGVkKioNCg0KTGV0ICRYJCBiZSB0aGUgdHdvIHBhcmFtZXRlciBHYW1tYSByYW5kb20gdmFyaWFibGUgd2l0aCBkZW5zaXR5IGZ1bmN0aW9uDQoNCiQkDQpmKHggXG1pZCBcYWxwaGEsIFxiZXRhKSA9IFxmcmFjezF9e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfSB4XntcYWxwaGEtMX0gZV57LXgvXGJldGF9ICBcIFwgXHRleHR7Zm9yfSBcIFwgIHggPiAwLA0KJCQNCg0Kd2hlcmUgd2l0aCAkXGFscGhhID4gMCQgKHNoYXBlKSwgJFxiZXRhPjAkIChzY2FsZSksIGFuZA0KDQokJA0KXEdhbW1hKFxhbHBoYSkgPSBcaW50X3swfV57XGluZnR5fSB0XntcYWxwaGEtMX0gZV57LXR9IFwsIGR0LCBccXVhZCBcYWxwaGEgPiAwLg0KJCQNCg0KJFxHYW1tYSh4KSQgY2FuIGJlIGNvbXB1dGVkIGluIFIgdXNpbmcgdGhlIGBnYW1tYSgpYCBmdW5jdGlvbi4gVGhlIGRlcml2YXRpdmUgb2YgJFxHYW1tYSh4KSQgYXJlIGdpdmVuIHJlc3BlY3RpdmVseSBieQ0KDQokJA0KXEdhbW1hXlxwcmltZSh6KSA9IFxHYW1tYSAoeilccHNpXzAoeikNCiQkDQoNCndoZXJlICRccHNpXzAoeikgPSBcZnJhY3tkfXtken0gXGxuIFxHYW1tYXt6fSQuIEluIFIsIHRoZSBkaWdhbW1hIGZ1bmN0aW9uICRccHNpXzAoeikkIGlzIGV2YWx1YXRlZCBieSBgZGlnYW1tYSgpYC4NCg0KDQoNClwNCg0KPGZvbnQgY29sb3IgPSAiYmx1ZSI+VGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gZmluZGluZyBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGUgb2YgcGFyYW1ldGVycyAkXGFscGhhJCBhbmQgJFxiZXRhJCBiYXNlZCBvbiBhIHJlYWwtd29ybGQgYXBwbGljYXRpb24gZGF0YSBzZXQuPC9mb250Pg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbiAxOiBEZXJpdmUgZ3JhZGllbnQgKGZpcnN0IG9yZGVyIHBhcnRpYWwgZGVyaXZhdGl2ZSkgb2YgbGlrZWxpaG9vZCBmdW5jdGlvbioqDQoNCkFzc3VtZSB0aGF0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcdG8gXHRleHR7IGdhbW1hIH0oXGFscGhhLCBcYmV0YSkkIHdpdGggZGVuc2l0eSBmdW5jdGlvbiBnaXZlbiBieQ0KDQokJA0KZih4IFxtaWQgXGFscGhhLCBcYmV0YSkgPSBcZnJhY3sxfXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX0geF57XGFscGhhLTF9IGVeey14L1xiZXRhfSAgXCBcIFx0ZXh0e2Zvcn0gXCBcICB4ID4gMCwNCiQkDQoNCkRlcml2ZSB0aGUgZ3JhZGllbnQgb2YgdGhlICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiB3aXRoIHJlc3BlY3QgdG8gdGhlIGdhbW1hIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzICRcYWxwaGEkIGFuZCAkXGJldGEkLiBUbyB0aGlzIGVuZCwNCg0KDQphKS4gV3JpdGUgb3V0IHRoZSBmdWxsICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiBiYXNlZCBvbiB0aGUgZ2l2ZW4gZGF0YSBhbmQgdGhlIGRlbnNpdHkgZnVuY3Rpb24gcHJvdmlkZWQgYWJvdmUuDQpgYGB7cn0NCg0KdHJ1ZS5hbHBoYSA8LSAyLjUNCnRydWUuYmV0YSA8LSAxLjgNCg0KDQpzYW1wbGUuZGF0YT0gcmdhbW1hKDEwMDAsIHNoYXBlID0gdHJ1ZS5hbHBoYSwgc2NhbGUgPSB0cnVlLmJldGEgKQ0KDQoNCiMgTG9nLUxpa2VsaWhvb2QgRnVuY3Rpb24gKHRvIHNpbXBsaWZ5IGNvbXB1dGF0aW9uKQ0KZ2FtbWFzLmxvZ2xpayA9IGZ1bmN0aW9uKHBhcmFtcywgZGF0YSkgDQogIHsNCiAgYWxwaGFfc2hhcGUgPSBwYXJhbXNbMV0gI3NoYXBlIHBhcmFtZXRlcg0KICBiZXRhX3NjYWxlID0gcGFyYW1zWzJdICMgc2NhbGUgcGFyYW1ldGVyDQogIG4gPSBsZW5ndGgoZGF0YSkNCiAgDQogICMgZ2l2aW5nIGEgbG9nIHRvIHRoZSBnYW1tYSBkaXN0cmlidXRpb24gZnVuY3Rpb24gYW5kIHNpbXBsaWZ5aW5nIHRoZSBlcXVhdGlvbg0KICAjcmVwbGFjaW5nIGxvZyhhbHBoYSlvciBsb2coZ2FtbWEoYWxwaGEpKSB3aXRoIGxnYW1tYSgpDQogIGxvZ2xpa19nYW1tYSA9IC1uICogbGdhbW1hKGFscGhhX3NoYXBlKSAtIA0KICAgICAgICAgICAgICAgICBuICogYWxwaGFfc2hhcGUgKiBsb2coYmV0YV9zY2FsZSkgKyANCiAgICAgICAgICAgICAgICAgKGFscGhhX3NoYXBlIC0gMSkgKiBzdW0obG9nKGRhdGEpKSAtIA0KICAgICAgICAgICAgICAgICAoMS9iZXRhX3NjYWxlKSAqIHN1bShkYXRhKQ0KICANCiAgcmV0dXJuKGxvZ2xpa19nYW1tYSkgDQp9DQoNCmBgYA0KDQoNCg0KRXhwYW5kaW5nIHRoZSBsb2cgYW5kIGNyYWZ0aW5nIHRoZSBzdW1tYXRpb24NCiQkIA0KIFxlbGwoXGFscGhhLCBcYmV0YSk9IFxzdW0gW2xuKDEpLWxuXEdhbW1hKFxhbHBoYSktbG4oXGJldGFeXGFscGhhKSArIGxuKHhfaV57XGFscGhhLTF9KStsbihlXnsteF9pL1xiZXRhfSldDQokJA0KDQoNClRoZSBsb2cgbGlrZWxpaG9vZCBmdW5jdGlvbiBvZiB0aGUgZ2FtbWEgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uOg0KJCQNClxlbGwoeCBcbWlkIFxhbHBoYSwgXGJldGEpPSAtbiBcbG4gXEdhbW1hKFxhbHBoYSkgLSBuIFxhbHBoYSBcbG4oXGJldGEpICsgKFxhbHBoYSAtIDEpIFxzdW1fe2k9MX1ee259IFxsbih4X2kpIC0gXGZyYWN7MX17XGJldGF9IFxzdW1fe2k9MX1ee259IHhfaQ0KJCQNCg0KDQpiKS4gRGVyaXZlIHRoZSBzY29yZSBmdW5jdGlvbnMgKHRoZSBncmFkaWVudCBvZiB0aGUgbG9nLWxpa2VsaWhvb2QpIGZyb20gdGhlIGZ1bGwgKipsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbioqIGluIHBhcnQgKGEpLg0KDQoNCmBgYHtyfQ0KDQoNCiMgQ29ycmVjdGVkIFNjb3JlIEZ1bmN0aW9uDQpnYW1tYS5zY29yZSA9IGZ1bmN0aW9uKHBhcmFtcywgZGF0YSkgDQogIHsNCiAgYWxwaGFfc2hhcGUgPSBwYXJhbXNbMV0NCiAgYmV0YV9zY2FsZSA9IHBhcmFtc1syXQ0KICBuID0gbGVuZ3RoKGRhdGEpDQoNCiAgIyBHZXR0aW5nIHRoZSBncmFkaWVudCBwYXJhbWV0ZXJzLCByZXBsYWNpbmcgd2l0aCBkaWdhbW1hIA0KICBncmFkaWVudF9hbHBoYSA9IC1uICogZGlnYW1tYShhbHBoYV9zaGFwZSkgLSBuICogbG9nKGJldGFfc2NhbGUpICsgc3VtKGxvZyhkYXRhKSkgI1BhcnRpYWwgZGVyaXZhdGl2ZSB0byBhbHBoYSAjVGhlIGZpcnN0IGRlcml2YXRpdmUgb2YgbG9nIGdhbW1hIGZ1bmN0aW9uIHdoaWNoIHlvdSBuZWVkIGZvciB0aGUgcGFydGlhbCBkZXJpdmF0aXZlcyBtZW50aW9uZWQNCiAgZ3JhZGllbnRfYmV0YSA9IC0obiAqIGFscGhhX3NoYXBlKSAvIGJldGFfc2NhbGUgKyBzdW0oZGF0YSkgLyAoYmV0YV9zY2FsZV4yKSANCiNQYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIEJldGENCg0KICByZXR1cm4oYyhncmFkaWVudF9hbHBoYSwgZ3JhZGllbnRfYmV0YSkpDQp9DQoNCg0KYGBgDQoNCg0KUGVyZm9ybWluZyB0aGUgbG9nIGxpa2VsaWhvb2QgcGFydGlhbCBkZXJpdmF0aXZlcyBmb3IgdGhlIEdhbW1hIGRpc3RyaWJ1dGlvbi4gDQoNClRha2luZyB0aGUgcGFydGlhbCBkZXJpdmF0aXZlIGluIHJlc3BlY3QgdG8gdGhlIHBhcmFtZXRlciAkXGFscGhhJC4gDQoNCiQkDQpcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcYWxwaGF9ID0gXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxhbHBoYX0gXGxlZnRbIC1uIFxsbiBcR2FtbWEoXGFscGhhKSAtIG4gXGFscGhhIFxsbihcYmV0YSkgKyAoXGFscGhhIC0gMSkgXHN1bV97aT0xfV57bn0gXGxuKHhfaSkgLSBcZnJhY3sxfXtcYmV0YX0gXHN1bV97aT0xfV57bn0geF9pIFxyaWdodF0NCiQkDQoNCg0KJCQNClxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYWxwaGF9IFstbiBcbG4gXEdhbW1hKFxhbHBoYSldID0gLW4gXHBzaV8wKFxhbHBoYSkNCiQkDQoNCg0KDQokJA0KXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxhbHBoYX0gWy1uIFxhbHBoYSBcbG4oXGJldGEpXSA9IC1uIFxsbihcYmV0YSkNCiQkDQoNCg0KJCQNClxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYWxwaGF9IFsoXGFscGhhIC0gMSkgXHN1bSBcbG4oeF9pKV0gPSBcc3VtIFxsbih4X2kpDQokJA0KDQoNCiQkDQpcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGFscGhhfSBbLVxmcmFjezF9e1xiZXRhfSBcc3VtIHhfaV0gPSAwDQokJA0KDQokJA0KVV9cYWxwaGEgPSAtbiBccHNpXzAoXGFscGhhKSAtIG4gXGxuKFxiZXRhKSArIFxzdW1fe2k9MX1ee259IFxsbih4X2kpDQokJA0KDQoNCiMjIEJldGEgDQoNClRha2luZyB0aGUgcGFydGlhbCBkZXJpdmF0aXZlIGluIHJlc3BlY3QgdG8gdGhlIHBhcmFtZXRlciAkXGJldGEkLg0KDQokJA0KDQpcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGJldGF9IFstbiBcbG4gXEdhbW1hKFxhbHBoYSldID0gMA0KDQokJA0KDQoNClRoZSBQYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhlIEJldGEgcGFyYW1ldGVyIGlzOg0KDQokJA0KXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxiZXRhfSBbLW5cYWxwaGEgXGxuKFxiZXRhKV0gPSAtXGZyYWN7biBcYWxwaGF9e1xiZXRhfQ0KJCQNCg0KDQozLiBEaWZmZXJlbnRpYXRlIGFuZCBzZXQgdGhlIGJldGEgc2VjdGlvbiB0byAwOg0KDQokJA0KXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxiZXRhfSBbKFxhbHBoYSAtIDEpIFxzdW0gXGxuKHhfaSldID0gMA0KJCQNClJlbW92ZSBsaW5lIGJlbG93Og0KJCQNClxmcmFje1xwYXJ0aWFsXGVsbH17XHBhcnRpYWwgXGJldGF9PVxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYmV0YX0gWy1uXGFscGhhIFxsbihcYmV0YSkgKyhcYWxwaGEtMSkgXHN1bV5uX3tpPTF9KHhfaSkgLSBcZnJhY3sxfXtcYmV0YX0gXHN1bV5uX3tpPTF9eF9pDQokJA0KDQoNCiQkDQpcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGJldGF9IFstXGZyYWN7MX17XGJldGF9IFxzdW0geF9pXSA9IFxmcmFje1xzdW0geF9pfXtcYmV0YV4yfQ0KJCQNCg0KDQpUaGUgc2NvcmUgZnVuY3Rpb24gZm9yIHRoZSBzY2FsZSAkXGJldGEkIHBhcmFtZXRlciBpczoNCg0KJCQNClVfXGJldGEgPSAtXGZyYWN7biBcYWxwaGF9e1xiZXRhfSArIFxmcmFje1xzdW1fe2k9MX1ee259IHhfaX17XGJldGFeMn0NCiQkDQoNClRoZSBncmFkaWVudCB2ZWN0b3Igd2l0aCBBbHBoYSAoU2hhcGUpIGFuZCBCZXRhIChTY2FsZSkgUGFyYW1ldGVyczoNCg0KDQokJA0KVV9cYWxwaGEgPSAtbiBccHNpXzAoXGFscGhhKSAtIG4gXGxuKFxiZXRhKSArIFxzdW1fe2k9MX1ee259IFxsbih4X2kpIC4uLi4uLi4uLihBKQ0KJCQNCg0KJCQNClVfXGJldGEgPSAtXGZyYWN7biBcYWxwaGF9e1xiZXRhfSArIFxmcmFje1xzdW1fe2k9MX1ee259IHhfaX17XGJldGFeMn0gLi4uLi4uLi4uLiAoQikNCiQkDQoNCg0KXA0KDQoNCg0KIyMgKipRdWVzdGlvbiAyOiBCaXJ0aCBkYXRhIHNldCoqDQoNClRoZSBmb2xsb3dpbmcgUiBjb2RlIHJlYWRzIGluIGEgZGF0YSBzZXQgY29udGFpbmluZywgZm9yIGVhY2ggb2YgNyBkYXlzLCB0aGUgbGVuZ3RocyBvZiB0aW1lIGluIGhvdXJzIHNwZW50IGJ5DQp3b21lbiBpbiB0aGUgZGVsaXZlcnkgc3VpdGUgd2hpbGUgZ2l2aW5nIGJpcnRoICh3aXRob3V0IGEgY2Vhc2FyaWFuIHNlY3Rpb24pIGF0IEpvaG4gUmFkY2xpZmZlIEhvc3BpdGFsIGluDQpPeGZvcmQsIEVuZ2xhbmQuIFRoZSBkYXRhIGFyZSB0YWtlbiBmcm9tIERhdmlzb24gKFN0YXRpc3RpY2FsIE1vZGVscy4gQ2FtYnJpZGdlIFVuaXZlcnNpdHkgUHJlc3MsIDIwMDMpLg0KDQpgYGANCjIuMSwgMy40LCA0LjI1LCA1LjYsIDYuNCwgNy4zLCA4LjUsIDguNzUsIDguOSwgOS41LCA5Ljc1LCAxMCwgMTAuNCwgMTAuNCwgMTYsIDE5LA0KNCwgNC4xLCA1LCA1LjUsIDUuNywgNi41LCA3LjI1LCA3LjMsIDcuNSwgOC4yLCA4LjUsIDkuNzUsIDExLCAxMS4yLCAxNSwgMTYuNSwgMi42LCANCjMuNiwgMy42LCA2LjQsIDYuOCwgNy41LCA3LjUsIDguMjUsIDguNSwgMTAuNCwgMTAuNzUsIDE0LjI1LCAxNC41LCAxLjUsIDQuNywgNC43LCANCjcuMiwgNy4yNSwgOC4xLCA4LjUsIDkuMiwgOS41LCAxMC43LCAxMS41LCAyLjUsIDIuNSwgMy40LCA0LjIsIDUuOSwgNi4yNSwgNy4zLCA3LjUsIA0KNy44LCA4LjMsIDguMywgMTAuMjUsIDEyLjksIDE0LjMsIDQsIDQsIDUuMjUsIDYuMSwgNi41LCA2LjksIDcsIDguNDUsIDkuMjUsIDEwLjEsIA0KMTAuMiwgMTIuNzUsIDE0LjYsIDIsIDIuNywgMi43NSwgMy40LCA0LjIsIDQuMywgNC45LCA2LjI1LCA3LCA5LCA5LjI1LCAxMC43DQpgYGANCg0KQXNzdW1lIHRoZSBkYXRhIGFyZSBnZW5lcmF0ZWQgZnJvbSBhIGdhbW1hIGRpc3RyaWJ1dGlvbi4gVGhlIG9iamVjdGl2ZSBpcyB0byB1c2UgdGhlc2UgZGF0YSBhbmQgdGhlIGRlc2lnbmF0ZWQgYWxnb3JpdGhtIHRvIGZpbmQgdGhlIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0ZXMgKE1MRXMpIG9mIHRoZSBwYXJhbWV0ZXJzICRcYWxwaGEkIGFuZCAkXGJldGEkLg0KDQoNCmEpLiBGaW5kIHRoZSBNTEVzIG9mICRcYWxwaGEkIGFuZCAkXGJldGEkLCBkZW5vdGVkIGJ5ICRcaGF0e1xhbHBoYX0kIGFuZCAkXGhhdHtcYmV0YX0kLCAgdXNpbmcgZ3JhZGllbnQtYmFzZWQgb3B0aW1pemF0aW9uIHZpYSB0aGUgUiBmdW5jdGlvbiBgb3B0aW0oKWAgd2l0aCB0aGUgZ3JhZGllbnQgdmVjdG9yIGRlcml2ZWQgaW4gUXVlc3Rpb24gMS4NCg0KDQpgYGB7cn0NCg0KZGF0YWJpcnRoPSBzb3J0KGMoMi4xLCAzLjQsIDQuMjUsIDUuNiwgNi40LCA3LjMsIDguNSwgOC43NSwgOC45LCA5LjUsIDkuNzUsIDEwLCAxMC40LCAxMC40LCAxNiwgMTksDQo0LCA0LjEsIDUsIDUuNSwgNS43LCA2LjUsIDcuMjUsIDcuMywgNy41LCA4LjIsIDguNSwgOS43NSwgMTEsIDExLjIsIDE1LCAxNi41LCAyLjYsIA0KMy42LCAzLjYsIDYuNCwgNi44LCA3LjUsIDcuNSwgOC4yNSwgOC41LCAxMC40LCAxMC43NSwgMTQuMjUsIDE0LjUsIDEuNSwgNC43LCA0LjcsIA0KNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgDQo3LjgsIDguMywgOC4zLCAxMC4yNSwgMTIuOSwgMTQuMywgNCwgNCwgNS4yNSwgNi4xLCA2LjUsIDYuOSwgNywgOC40NSwgOS4yNSwgMTAuMSwgDQoxMC4yLCAxMi43NSwgMTQuNiwgMiwgMi43LCAyLjc1LCAzLjQsIDQuMiwgNC4zLCA0LjksIDYuMjUsIDcsIDksIDkuMjUsIDEwLjcpKQ0KDQojZ2FtbWFzLmxvZ2xpayhwYXJhbXMgPSBwYXJhbXMsIGRhdGEgPSBkYXRhYmlydGgpDQoNCg0KIyBTY29yZSBGdW5jdGlvbiB0byByZWFjaCB0aGUgZ3JhZGllbnQgZnVuY3Rpb24gb2YgYWxwaGEgYW5kIGJldGENCmdhbW1hLnNjb3JlID0gZnVuY3Rpb24ocGFyYW1zLCBkYXRhKSANCiAgew0KICBhbHBoYV9zaGFwZSA9IHBhcmFtc1sxXQ0KICBiZXRhX3NjYWxlID0gcGFyYW1zWzJdDQogIG4gPSBsZW5ndGgoZGF0YSkNCg0KICAjIE1hdGggRml4OiBDb21iaW5lZCBpbnRvIG9uZSBleHByZXNzaW9uDQogIGdyYWRpZW50X2FscGhhID0gLW4gKiBkaWdhbW1hKGFscGhhX3NoYXBlKSAtIG4gKiBsb2coYmV0YV9zY2FsZSkgKyBzdW0obG9nKGRhdGEpKQ0KICBncmFkaWVudF9iZXRhID0gLShuICogYWxwaGFfc2hhcGUpIC8gYmV0YV9zY2FsZSArIHN1bShkYXRhKSAvIChiZXRhX3NjYWxlXjIpDQoNCiAgcmV0dXJuKGMoZ3JhZGllbnRfYWxwaGEsIGdyYWRpZW50X2JldGEpKQ0KfQ0KDQppbml0aWFsLnBhcmFtcyA9IGMoYWxwaGFfc2hhcGUgPSA1ICwgYmV0YV9zY2FsZT0gMiApICNjaGFuZ2UgbGF0ZXINCg0KI1VzaW5nIG9wdGltKCkgdG8gcmVhY2ggZ3JhZGllbnQsIGdhbW1hIGlzIGEgbm9ubGluZWFyLCBub25jbG9zZWQgZnVuY3Rpb24uIFdlIHVzZSBvcHRpbSgpIHRvIGdldCBtb3JlIGFjY3VyYXRlIHBhcmFtZXRlcnMNCm1sZS5yZXN1bHQgPC0gb3B0aW0oDQogIHBhciA9IGluaXRpYWwucGFyYW1zLA0KICBmbiA9IGdhbW1hcy5sb2dsaWssICMgZm4sIG1hcHMgdGhlIHRlcnJpdG9yeSBvZiB0aGUgZnVuY3Rpb24gdG8gZm9sbG93L2ZpbmQgdGhlIGhlaWdodCBvZiB0aGUgZnVuY3Rpb24oaGVyZSBpdCBpcyB0aGUgZ2FtbWEgZnVuY3Rpb24pDQogIGdyID0gZ2FtbWEuc2NvcmUsICAgICAjIHNjb3JlZCBnYW1tYSAgZnVuY3Rpb24gLS0+IG5lZWRlZCBmb3IgZ3JhZGllbnQNCiAgZGF0YSA9IGRhdGFiaXJ0aCwgICAgICAgICAgIA0KICBtZXRob2QgPSAiTC1CRkdTLUIiLCAgIyBCZXN0IGZvciBncmFkaWVudHMgKyBib3VuZHMNCiAgaGVzc2lhbiA9IFRSVUUsICAjIEEgbWF0cml4IHNlY29uZCBvcmRlciBwYXJ0aWFsIGRlcml2YXRpdmVzLiBJZiB0aGUgR3JhZGllbnQgaXMgdGhlIGZpcnN0IGRlcml2YXRpdmUgKHNsb3BlKSwgdGhlIGhlc3NpYW4gaXMgdGhlIHNlY29uZCBkZXJpdmF0aXZlIChjdXJ2YXR1cmUpDQogIGNvbnRyb2wgPSBsaXN0KHRyYWNlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGZuc2NhbGUgPSAtMSwgIyBXZSB3YW50IHRvIE1BWElNSVpFIHRoZSBsb2ctbGlrZWxpaG9vZCwgc28gY2hvb3NlIC0xDQogICAgICAgICAgICAgICAgIG1heGl0ID0gNTAwLA0KICAgICAgICAgICAgICAgICBhYnN0b2wgPSAxZS04KQ0KKQ0KDQoNCm1sZS5yZXN1bHQNCg0KYGBgDQoNCg0KVGhlIHByZWRpY3RlZCBzaGFwZSBwYXJhbWV0ZXIgaW4gdGhlIGJpcnRoIHRpbWVzIGlzICRcaGF0XGFscGhhICQgPSAgYHIgbWxlLnJlc3VsdCRwYXJbMV1gLiBUaGUgcHJlZGljdGVkIHNjYWxlIHBhcmFtZXRlciAkXGhhdFxiZXRhJCA9IGByIG1sZS5yZXN1bHQkcGFyWzJdYC4NCg0KDQpiKS4gQXBwbHkgdGhlIG1ldGhvZCBvZiBtb21lbnRzIHRvIG9idGFpbiBlc3RpbWF0b3JzIGZvciAkXGFscGhhJCBhbmQgJFxiZXRhJC4gRGVub3RlIHRoZXNlIG1vbWVudCBlc3RpbWF0b3JzIGFzICRcdGlsZGV7XGFscGhhfSQgYW5kICRcdGlsZGV7XGJldGF9JC4NCg0KDQpgYGB7ciB0MmIyfQ0KDQoNCiNNTUU6IE1ldGhvZCBvZiBNb21lbnRzIChTY2FsZSBQYXJhbWV0ZXIpDQptMSA8LSBtZWFuKGRhdGFiaXJ0aCkgDQpzMiA8LSB2YXIoZGF0YWJpcnRoKSAgIyBTYW1wbGUgVmFyaWFuY2UgKHNeMikNCg0KIyBTY2FsZSBwYXJhbWV0ZXIgTW9NIGZvcm11bGFzOg0KbW9tX2JldGEgIDwtIHMyIC8gbTEgICAgICAgICAgIyBUaGlzIGlzIHRoZSBTY2FsZSBCZXRhDQptb21fYWxwaGEgPC0gbTFeMiAvIHMyICAgICAgICAjIFRoaXMgaXMgdGhlIFNoYXBlIEFscGhhDQoNCiNtb21fYmV0YQ0KI21vbV9hbHBoYQ0KDQppbml0aWFsLnBhcmFtcyA9IGMoYWxwaGFfc2hhcGUgPSBtb21fYWxwaGEsIGJldGFfc2NhbGU9IG1vbV9iZXRhICkgI2NoYW5nZSBsYXRlcg0KDQojVXNpbmcgb3B0aW0gbGlrZSBhYm92ZSAyYSB0byBvcHRpbXplKCkgdGhlIG5vbmxpbmVhciBhbmQgbm9uY2xvc2VkIGZ1bmN0aW9uIG9mIHRoZSBtZXRob2Qgb2YgbW9tZW50IGVzdGltYXRvcnMgbW1lDQptbGUucmVzdWx0IDwtIG9wdGltKA0KICBwYXIgPSBpbml0aWFsLnBhcmFtcywNCiAgZm4gPSBnYW1tYXMubG9nbGlrLCAgICMgZ2FtbWEgZnVuY3Rpb24NCiAgZ3IgPSBnYW1tYS5zY29yZSwgICAgICMgc2NvcmVkIGdhbW1hICBmdW5jdGlvbg0KICBkYXRhID0gZGF0YWJpcnRoLCAgICAgICAgICAgDQogIG1ldGhvZCA9ICJMLUJGR1MtQiIsICAjIEJlc3QgZm9yIGdyYWRpZW50cyArIGJvdW5kcw0KICBoZXNzaWFuID0gVFJVRSwNCiAgY29udHJvbCA9IGxpc3QodHJhY2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgZm5zY2FsZSA9IC0xLCAjIFdlIHdhbnQgdG8gTUFYSU1JWkUgdGhlIGxvZy1saWtlbGlob29kLCBzbyBjaG9vc2UgLTENCiAgICAgICAgICAgICAgICAgbWF4aXQgPSA1MDAsDQogICAgICAgICAgICAgICAgIGFic3RvbCA9IDFlLTgpDQopDQoNCg0KbWxlLnJlc3VsdA0KYGBgDQoNCg0KDQpUaGUgbWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdG9ycyBmb3IgJFx0aWxkZXtcYWxwaGF9JCBpcyBgciBtb21fYWxwaGFgIGFuZCAkXHRpbGRle1xiZXRhfSQgaXMgYHIgbW9tX2JldGFgLg0KDQoNCg0KYykuIENvbmR1Y3QgYSBicmllZiBsaXRlcmF0dXJlIHJldmlldyBjb21wYXJpbmcgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGVzdGltYXRpb24gKE1NRSkgYW5kIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIChNTEUpLiBTeW50aGVzaXplIHRoZSBrZXkgYWR2YW50YWdlcyBhbmQgbGltaXRhdGlvbnMgb2YgZWFjaCwgY29uY2x1ZGluZyB3aXRoIGEgcHJhY3RpY2FsIHJlY29tbWVuZGF0aW9uLg0KDQpNZXRob2Qgb2YgbW9tZW50cyBlc3RpbWF0aW9uIChNTUUpIGFuZCBNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiAoTUxFKSBhcmUgYm90aCBtZXRob2RzIHRvIGNvbm5lY3QgZGlzdHJpYnV0aW9ucyB3aXRoIGVzdGltYXRlZCBwYXJhbWV0ZXJzIHVzaW5nIGEgcmFuZG9tIHNhbXBsZS4gVGhlIG1ldGhvZCBvZiBtb21lbnQgZXN0aW1hdGlvbiAoTU1FKSBpcyBhIHNpbXBsZXIgdGVzdCB0aGFuIHRoZSBNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiAoTUxFKS4NCg0KIyBNZXRob2RzIG9mIE1vbWVudHMgRXN0aW1hdGlvbg0KDQpNZXRob2Qgb2YgbW9tZW50cyBlc3RpbWF0aW9uIGlzIGEgc2ltcGxlciBlc3RpbWF0b3IsIHVzaW5nIHRoZSBwb3B1bGF0aW9uIG1vbWVudHMgKGluZm9ybWF0aW9uIGZyb20gdGhlIHBvcHVsYXRpb24pIGFuZCBzZXR0aW5nIGl0IGVxdWFsIHRvIHRoZSBrbm93biBzYW1wbGUgIG1vbWVudHMgKGtub3duIHNhbXBsZSBpbmZvcm1hdGlvbikgdG8gc29sdmUgZm9yIHdoYXQgdGhlIHBvcHVsYXRpb24gcGFyYW1ldGVycyB3b3VsZCBiZS4gUGFyYW1ldGVycyBhcmUgbnVtZXJpY2FsIHBvcHVsYXRpb24gZGVzY3JpcHRpb25zIHRoYXQgc3VtbWFyaXplIGNoYXJhY3RlcmlzdGljcyBhYm91dCBvdXIgcG9wdWxhdGlvbiwgZm9yIGV4YW1wbGUsIG1lYW4gb3IgdmFyaWFuY2UuIFRoZSBnb2FsIG9mIHRoZSBsaWtlbGlob29kIGVzdGltYXRpb24gaXMgdG8gbWVhc3VyZSBob3cgd2VsbCBwYXJhbWV0ZXIgdmFsdWVzIGV4cGxhaW5zIHRoZSBvYnNlcnZlZCBkYXRhLg0KDQoNClRoZSBtYWpvciBhZHZhbnRhZ2UgdG8gdGhlIE1vbWVudCBvZiBtZXRob2RzIGVzdGltYXRpb24gaXMgaXRzIHNpbXBsaWNpdHkuIE1NRSBkb2VzIG5vdCByZXF1aXJlIG11Y2ggY29tcHV0YXRpb25hbCBwb3dlciwgYWxsb3dpbmcgZm9yIGZhc3QgY29tcHV0YXRpb25zIHRoYXQgY2FuIGJlIHVzZWQgYXMgZ2VuZXJhbCBlc3RpbWF0b3JzLiANClRoZSBkb3duc2lkZSBvZiB0aGVlIE1ldGhvZCBvZiBtb21lbnQncyBzaW1wbGljaXR5LCBpcyBpdHMgbGFjayBvZiBzcGVjaWZ5IG1heSB5aWVsZCBlc3RpbWF0b3JzIHdpdGggd2lkZXIgdmFyaWFuY2UgYW5kIGxlc3MgYWNjdXJhY3ktIGFsc28ga25vd24gYXMgZWZmaWNpZW5jeS4gDQoNCldoZW4gd2Ugc2V0IHVwIHR3byBlcXVhdGlvbnMgdG9nZXRoZXIgYW5kIHNvbHZlIGZvciB0aGUgdW5rbm93biBwb3B1bGF0aW9uIHBhcmFtZXRlciBvZiBpbnRlcmVzdCwgc29tZXRpbWVzLCBkZXBlbmRpbmcgb24gdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGRpc3RyaWJ1dGlvbiwgd2UgbWF5IG5vdCBoYXZlIGEgbm9ubGluZWFyIGVxdWF0aW9uLiBJbiBvdGhlciB3b3Jkcywgc29sdmluZyBmb3IgdGhlIHVua25vd24gcGFyYW1ldGVyLCBjYW5ub3QgYmUgZG9uZSB1c2luZyBzaW1wbGUgYWxnZWJyYWljIGV4cHJlc3Npb25zIGFuZCByZXF1aXJlIG1vcmUgY29tcHV0YXRpb25hbCByaWdvciBvZnRlbiByZXF1aXJpbmcgYSBiYWNrZ3JvdW5kIGFwcGxpY2F0aW9uIGluIGNhbGN1bHVzIG9yIGxpbmVhciBhbGdlYnJhLiBXaGVuIGFuIGV4cHJlc3Npb24gaXMgbm9uLWxpbmVhciB3ZSBjYW4gbm8gbG9uZ2VyIGdldCBkZWZpbmVkIHZhbHVlcyBmb3IgdGhlIHBhcmFtZXRlcnMgb2YgaW50ZXJlc3QsIGJ1dCBhcHByb3hpbWF0aW9ucy4gQ29ubmVjdGluZyB0aGUgaGlnaGVyIHZhcmlhbmNlIG9mIE1NRSBjYWxjdWxhdGlvbnMgd2l0aCBhIHBvc3NpYmxlIGFkZGVkIG5vaXNlIG9yIGJpYXMgd2l0aCBhIG5vbi1saW5lYXIgYXBwcm94aW1hdGlvbiwgdGhlIHBhcmFtZXRlcnMgY2FsY3VsYXRlZCB1c2luZyBNTUUgaGF2ZSBhIGdyZWF0ZXIgY2hhbmNlIHRvIGJlaW5nIGxlc3MgYWNjdXJhdGUgaW4gY29tcGFyaXNvbiB0byBvdGhlciB0ZXN0cywgc3VjaCBhcyB0aGUgTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gKE1MRSkuIA0KDQpUaGUgaGlnaGVyIGNoYW5jZSBvZiBiaWFzIHBsYWNlcyBpbXBvcnRhbmNlIG9mIHBhaXJpbmcgdGhlIE1NRSB3aXRoIGEgRmlzaGVyIEluZm9ybWF0aW9uIHRlc3QuIFRoZSBGaXNoZXIgSW5mb3JtYXRpb24gdGVzdCBtZWFzdXJlcyBob3cgd2VsbCB0aGUgc2FtcGxlIGNhcnJpZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBvcHVsYXRpb24gcGFyYW1ldGVyLiBXaXRoIGl0cyBzaW1wbGVyIGNhbGN1bGF0aW9ucywgdGhlIE1NRSBpcyBiZXN0IHN1aXRlZCB0byBwcm92aWRlIGdlbmVyYWwgc3RhcnRpbmcgcG9pbnQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBhcmFtZXRlciBmcm9tIHRoZSBzYW1wbGUsIGluIGZhY3QgaXQgaXMgb2Z0ZW4gdXNlZCBhcyBhIHN0YXJ0aW5nIHBvaW50IHByaW9yIHRvIE1MRSBhbmFseXNpcy4NCg0KDQojIyBNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdGlvbg0KDQpNYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBpcyBhbiBlc3RpbWF0b3IgcHJvY2VzcyB0aGF0IGFzc3VtZXMgdGhlIGNvbGxlY3RlZCBkYXRhIGlzIGZpeGVkLiBJdCBwZXJmb3JtcyBhIHNlcmllcyBvZiB0ZXN0cyB0byBmaW5kICBhdCBmb3IgdGhlIGdyZWF0ZXN0IHBvaW50IGluIHRoZSBkaXN0cmlidXRpb24gdG8gY2FsY3VsYXRlIHRoZSBwYXJhbWV0ZXIgdGhhdCBpcyBtb3N0IGxpa2VseSB0aGF0IHN1bW1hcml6ZXMgdGhlIHNhbXBsZS4gIA0KDQpJbiByZXRyb3NwZWN0LCB0aGUgbGlrZWxpaG9vZCBlc3RpbWF0aW9uIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIGxpa2VsaWhvb2Qgb2YgYSBwYXJhbWV0ZXIgYWNyb3NzIHRoZSBlbnRpcmUgZGlzdHJpYnV0aW9uIHdoaWxlIGVhY2ggcG9pbnQgaW4gdGhlIGRpc3RyaWJ1dGlvbiBoYXMgaXRzIG93biB1bmlxdWUgcGFyYW1ldGVyIHZhbHVlLiBUaGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRvciBmaW5kcyB0aGUgcmVnaW9uIGluIHRoZSBkaXN0cmlidXRpb24gd2l0aCB0aGUgZ3JlYXRlc3QgbGlrZWxpaG9vZCB0byBwcm92aWRlIGEgcmVhc29uYWJsZSBlc3RpbWF0ZSBmb3IgdGhlIHBhcmFtZXRlciB0aGF0IG1heGltaXplcyB0aGUgbGlrZWxpaG9vZCBmb3IgdGhlIG9ic2VydmVkIGRhdGEgZ2l2aW5nIGEgc3RhdGlzdGljYWxseSBwcm9iYWJsZSBlc3RpbWF0ZSBmb3IgdGhlIHBhcmFtZXRlcnMuIA0KDQpVbmxpa2UgdGhlIE1NRSwgdGhlIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIGlzIGEgbW9yZSBjb21wdXRhdGlvbmFsbHkgaW52b2x2ZWQgcHJvY2Vzcy4NCg0KQWRkaXRpb25hbGx5IHRoZSBNTUUgY2Fubm90IGJlIGNoZWNrZWQgd2l0aCBxdWFsaXR5IG1ldHJpY3MgdGhhdCByZXF1aXJlIGRhdGEgb3V0c2lkZSBvZiB0aGUgY29sbGVjdGVkIHNhbXBsZSwgc3VjaCBhcyBoeXBvdGhlc2l6ZWQgZGF0YSBzdWNoIGFzIGEgcC12YWx1ZSB0ZXN0LiANCg0KDQojIENvbXBhcmlzb24gb2YgTWV0aG9kIG9mIE1vbWVudHMgRXN0aW1hdGlvbiBhbmQgTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24NCg0KVGhlIE1MRSBpcyBtb3JlIGFjY3VyYXRlIHRoYW4gdGhlIE1NRSwgaW5zdGVhZCBvZiBhcHByb3hpbWF0aW5nIHRoZSBoaWdoZXN0IHBvaW50cyBvZiBmcmVxdWVuY3kgaW4gdGhlIGRpc3RyaWJ1dGlvbiB3ZSBkaXJlY3RseSBjYWxjdWxhdGUgdGhlIGhpZ2hlc3QgbWF4aW1pYSB2aWEgcGFydGlhbCBkZXJpdmF0aXZlIGNhbGN1bHVzIC4gVGhlIE1MRSBoYXMgbG93ZXIgdmFyaWFuY2UgdGhhbiB0aGUgTUxFIGxlYWRpbmcgdG8gbG93ZXIgYmlhcy4NCg0KQm90aCB0aGUgTUxFIGFuZCBNTUUgaGF2ZSB0aGUgY2hhbmNlIHRvIGhhdmUgbm9uLWxpbmVhciwgbm9uLWNsb3NlZCBmb3JtIGVxdWF0aW9ucy4gQXMgdGhlIE1MRSBpcyBhbHJlYWR5IG9mdGVuIGEgbW9yZSBjb21wbGV4IHRlc3QsIHRoaXMgb25seSBzbG93cyB0aGUgY29tcHV0YXRpb25hbCB0aW1lLCBhbmQgb2Z0ZW4gcmVzdWx0cyBpbiBjb21wdXRhdGlvbmFsIGFwcHJveGltYXRpb25zLCByYXRoZXIgdGhhbiBkZWZpbmVkIHBhcmFtZXRlciBhbnN3ZXJzLiANCg0KDQpEdWUgdG8gYWNjdXJhY3ksIGlmIHRpbWUgaXMgYWxsb3RlZCB0aGUgTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gaXMgdGhlIGJlc3QgdGVzdCB0byB1c2UuIFVsdGltYXRlbHkgdGhlIE1MRSBzaGFyZXMgc29tZSBtZXRob2RvbG9neSBmcm9tIHRoZSBNTUUsIG1ha2luZyBpdCBhIG1vcmUgcmVmaW5lZCB0ZXN0IG9mIHRoZSBNTEUuIE9mdGVuIHRoZSBNTEUgYW5kIE1NRSBjYW4gYmUgdXNlZCB0b2dldGhlci4gVGhlIE1NRSBjYW4gYWN0IGFzIGEgbGVzcyBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIHN0YXJ0aW5nIHBvaW50IGZvciB0aGUgTUxFIGFzIHRoZSBNTEUgYmVjb21lcyBtb3JlIGNvbXBsZXguIA0KDQojIyBDb21wYXJpc29uIE1MRSBhbmQgTU1FIHdpdGggQmlydGhpbmcgVGltZSBEYXRhDQpJbiBvYnNlcnZpbmcgdGhlIGRpZmZlcmVuY2UgaW4gdGhlIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0aW9uIGFuZCBNZXRob2RzIG9mIE1vbWVudHMgRXN0aW1hdGlvbiBkaXJlY3RseSBvbiB0aGUgYmlydGhpbmcgdGltZSBkYXRhc2V0LCB3ZSBzZWUgdGhlIGdhbW1hIGFscGhhIHBhcmFtZXRlciBjYWxjdWxhdGVkIHVzaW5nIHRoZSBNTUUgaXMgJFx0aWxkZXtcYWxwaGF9X3tNTUV9JCA9IGByIG1vbV9hbHBoYWAgYW5kIHRoZSBiZXRhIHBhcmFtZXRlciBpcyAkXHRpbGRle1xiZXRhfV97TU1FfSQgPSBgciBtb21fYmV0YWAuIFRoZSBNTEUgZ2FtbWEgYWxwaGEgcGFyYW1ldGVyIGlzICRcaGF0e1xhbHBoYX1fe01MRX0kID0gYHIgbWxlLnJlc3VsdCRwYXJbMV1gIGFuZCB0aGUgYmV0YSBwYXJhbWV0ZXIgaXMgJFxoYXR7XGJldGF9X3tNTEV9JCA9IGByIG1sZS5yZXN1bHQkcGFyWzJdYC4gQWx0aG91Z2ggdGhlIGNhbGN1bGF0ZWQgcGFyYW1ldGVyIHZhbHVlcyBhcmUgc2ltaWxhciwgaXQgaXMgdW5kZXJzdG9vZCB0aGF0IHRoZSBNTUUgcGFyYW1ldGVycyBoYXZlIG1vcmUgdmFyaWFuY2UgdGhhbiB0aGVpciBNTEUgY291bnRlcnBhcnRzLg0KDQoNCmBgYHtyfQ0KDQojIERlZmluaW5nIHRoZSByYW5nZSBmb3IgdGhlIHgtYXhpcyBiYXNlZCBvbiBiaXJ0aCBkYXRhDQp4X3JhbmdlIDwtIHNlcSgwLCBtYXgoZGF0YWJpcnRoKSArIDUsIGxlbmd0aC5vdXQgPSAyMDApDQoNCiMgQ2FsY3VsYXRlIHRoZSBEZW5zaXR5IGN1cnZlcw0KIyBVc2luZyAgTU1FIHZhbHVlcw0KbW9tX2RlbnMgPC0gZGdhbW1hKHhfcmFuZ2UsIHNoYXBlID0gbW9tX2FscGhhLCBzY2FsZSA9IG1vbV9iZXRhKQ0KDQojIFVzaW5nIHlvdXIgTUxFIHZhbHVlcyBmcm9tIG9wdGltDQptbGVfZGVucyA8LSBkZ2FtbWEoeF9yYW5nZSwgc2hhcGUgPSBtbGUucmVzdWx0JHBhclsxXSwgc2NhbGUgPSBtbGUucmVzdWx0JHBhclsyXSkNCg0KIyBDcmVhdGUgdGhlIGRhdGEgZnJhbWUgZm9yIGdncGxvdA0KcGxvdF9kYXRhIDwtIGRhdGEuZnJhbWUoDQogIHggPSByZXAoeF9yYW5nZSwgMiksDQogIGRlbnNpdHkgPSBjKG1vbV9kZW5zLCBtbGVfZGVucyksDQogIE1ldGhvZCA9IHJlcChjKCJNZXRob2Qgb2YgTW9tZW50IEVzdGltYXRvciIsICJNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdG9yIiksIGVhY2ggPSBsZW5ndGgoeF9yYW5nZSkpDQopDQoNCiMgQnVpbGRpbmcgcGxvdA0KZ2FtbWFfcGx0IDwtIGdncGxvdCgpICsNCiAgIyBBZGQgdGhlIGFjdHVhbCBkYXRhIGFzIGEgaGlzdG9ncmFtIG9yIGRlbnNpdHkgYXJlYQ0KICAjZ3JheSBpcyB0aGUgYmlydGhkYXRhIGRpc3RyaWJ1dGlvbg0KICBnZW9tX2RlbnNpdHkoZGF0YSA9IGRhdGEuZnJhbWUoeCA9IGRhdGFiaXJ0aCksIGFlcyh4ID0geCksIA0KICAgICAgICAgICAgICAgZmlsbCA9ICJncmF5OTAiLCBjb2xvciA9ICJncmF5NjAiLCBhbHBoYSA9IDAuNSkgKw0KICAjIEFkZCB0aGUgdHdvIHRoZW9yZXRpY2FsIGxpbmVzDQogIGdlb21fbGluZShkYXRhID0gcGxvdF9kYXRhLCBhZXMoeCA9IHgsIHkgPSBkZW5zaXR5LCBjb2xvciA9IE1ldGhvZCwgbGluZXR5cGUgPSBNZXRob2QpLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIk1ldGhvZCBvZiBNb21lbnQgRXN0aW1hdG9ycyBDb21wYXJlZCB0byANCiAgICAgICBNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdG9ycyBmb3IgQmlydGggVGltZXMiLA0KICAgICAgIHN1YnRpdGxlID0gIkNvbXBhcmluZyBlc3RpbWF0b3IgZGVuc2l0aWVzIGFnYWluc3Qgb2JzZXJ2ZWQgZGF0YSBpbiBhIGdhbW1hIGRpc3RyaWJ1dGlvbiIsDQogICAgICAgeCA9ICJIb3VycyBpbiBEZWxpdmVyeSBTdWl0ZSIsIA0KICAgICAgIHkgPSAiRGVuc2l0eSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIk1ldGhvZCBvZiBNb21lbnQgRXN0aW1hdG9yIiA9ICJibHVlIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYXhpbXVtIExpa2VsaWhvb2QgRXN0aW1hdG9yIiA9ICJyZWQiKSkgKyAjVGhlIGVzdGltYXRvcidzIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIE1NRSBhbmQgdGhlIE1MRSBpbiBkaWZmZXJlbnQgY29sb3JzDQoNCiNUaGUgZGlzdHJpYnV0aW9uIGlzIGRyYXduIHdlIG5lZWQgYm90aCB0aGUgcGFyYW1ldGVycyBhbHBoYSBhbmQgYmV0YSB0aGUgZHJhdyB0aGUgZGlzdHJpYnV0aW9uLCBzbyB0aGV5IGFyZSBib3RoIHJlcHJlc2VudGVkDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCg0KIyBNYWtlIGl0IGludGVyYWN0aXZlDQpnZ3Bsb3RseShnYW1tYV9wbHQpDQoNCmBgYA0KVXNpbmcgdGhlIGRlbGl2ZXJ5IHN1aXRlIGJpcnRoaW5nIHRpbWVzIGRhdGEsIHdlIHNlZSB0aGF0IGJvdGggdGhlIE1ldGhvZCBvZiBNb21lbnQgRXN0aW1hdG9yIChibHVlKSBhbmQgdGhlIE1heGltdW0gTGlrZWxpaG9vZCBFc3RpbWF0b3IgKHJlZCkgY2FwdHVyZSB0aGUgZGlzdHJpYnV0aW9uIHNpbWlsYXJseSwgYWx0aG91Z2ggdGhlIE1MRSBjYXB0dXJlIHRoZSBkaXN0cmlidXRpb24gY2xvc2VyIHRvIHRoZSB0cnVlIGRpc3RyaWJ1dGlvbiAoZ3JheSkuIFRoZXNlIHNhbXBsZSBlc3RpbWF0aW9ucyB3b3VsZCB0aGVuIGJlIHVzZWQgdG8gYmVzdCBwYXJhbWV0ZXJpemUgdGhlIHBvcHVsYXRpb24u