Part A: Methodological Derivations
Problem A1:
Show that the density function of the Kumaraswamy distribution is
\[
f(x; a, b) = ab \, x^{a-1} (1 - x^a)^{b-1}.
\]
Problem A2:
Let \(\{x_1, x_2, \cdots, x_n \}\)
be an i.i.d. random sample taken from a population that follows the
above 2-parameter Kumaraswamy distribution. Write out the loglikelihood
function of \(a\) and \(b\), denoted by \(\ell(a,b)\), based on the above random
sample and derive the gradient vector \([\ell_a^\prime(a,b), \ell_b^\prime(a,b)]\),
the first order partial derivative of the log-likelihood with respect to
parameters \(a\) and \(b\).
Problem A3:
Based on the gradients functions obtained in the above problem A2,
derive the observed Fisher Information matrix (i.e, the
negative Hessian Matrix).
Problem A4:
Consider power distribution \(F(x) = x^a,
(a >0 \quad \text{ and }\quad x \in (0,1))\), a special case
of the Kumaraswamy distribution with \(b =
1\), and a random sample from this distribution \(\{ x_1, x_2, \cdots, x_n\}\).
Derive the MLE and MME of \(a\) respectively. [Hint: To find the
MME, you need to compute the moment of the power distribution; that is,
\(E[X^k] = \int_0^1 x^k F'(x) dx\).
Note that both the MLE and the MME have closed-form
expressions.]
Problem A5:
Using the same setting as in Problem A4, find the
asymptotic (Wald) confidence interval for \(a\). [Hint: Compute the Fisher
information for \(a\), then take its
reciprocal to obtain the variance.]
Problem A6:
Using the same setting as in Problem A4, perform a
likelihood ratio test for the hypothesis \(H_0
:a=1\) (i.e., the power distribution reduces to a uniform
distribution). [Hint: Evaluate the log-likelihood function at the
maximum likelihood estimate \(\hat{a}\)
and at \(a=1\), then use these values
to construct the LRT test statistic.]
Part B: Numerical Analysis
All code must be well commented and adhere to best coding
practices
Working Dataset: A small reservoir supplies water to
a town. During the dry season (50 days), engineers record the fraction
of usable storage filled each morning. Values near 0 mean the reservoir
is nearly empty; values near 1 mean it’s full. The distribution tends to
be right‑skewed (mostly low levels due to drought) but with occasional
replenishment.
The following 50 data points (ordered for clarity) represent the
daily proportion of usable storage:
0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22,
0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32,
0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42,
0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52,
0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.78
Problem B1:
Fit the Kumaraswamy distribution to the above data. Use the
derivations in Problem A2 to find the MLE of \(a\) and \(b\). Please copy the key formulas
before coding.
Formulas:
Gradient Vector for Kumaraswamy distribution log likelihoods.
Gradient Vector \(\ell'_b(a,b)\)
\[
\ell'_b(a,b) = \frac{n}{b} + \sum^n_{i=1} ln(1-X^a_i)
\] \[
\ell'_a(a,b) = \frac{n}{a} +\sum^n_{i=1} ln(X_i)
+(b-1)\sum^n_{i=1}\frac{X^a_i lnX_i}{1-X^a_i}
\]
storage= sort(c(0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22,
0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32,
0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42,
0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52,
0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.78))
hist(storage) #histogram of dataset

#Find MLE of a and b
#Gradient for log_b(a,b)
#n= length(storage)
#function to find values of a and b based on the dataset alone
#finding the gradient of b
grad_bfunc =function(params, data) {
a <- params[1]
b <- params[2]
n <- length(data)
#n/b + sum(log(1-x^a))
sum_term= sum(log(1- data^a)) #n/b + sum(data)
gradient_b = -((n/b) + sum_term)
return(gradient_b)
}
grad_afunc = function(params, data) #building log likelihood for gradient vector
{
a <- params[1]
b <- params[2]
n = length(data)
first =(n/a) #first term of gradient equation for a
logdata= sum(log(data)) #loging all summed data in the dataset
b1= (b-1)
num_a = ((data^a)* log(data)) #numerator of last term
dom_a = (1- (data^a)) #denominator of last term
last_term_ga= sum(num_a/dom_a) #finalized fracttion for last term to be put into gradient equation
grad_a = -(first + logdata + b1 * last_term_ga) #gradient term for a using all data (no bootstraps, etc. just loop)
return(grad_a)
}
#placing a and b fradients in the same function to later compare in optim() and possible matrix building
combined_kum_gradient= function(params, data){
a <- params[1]
b <- params[2]
n = length(data)
##################if you choose to block or change everything in between
# grad_a
# gradient_b
# return(c(grad_a, gradient_b))
########################################
ga <- grad_afunc(params, data)
gb <- grad_bfunc(params, data)
# Return them together as a vector for the optimizer
return(c(ga, gb))
}
# Negative Log-Likelihood (Target for Optimization)
kumar_loglik = function(params, data) {
a <- params[1]
b <- params[2]
n <- length(data)
# Based on your derivation in A2
logl = n*log(a) + n*log(b) + (a-1)*sum(log(data)) + (b-1)*sum(log(1 - data^a))
return(-logl) # We return negative because optim() minimizes by default
}
test_params= c(1,1)
mle.result= optim(
par = test_params, #intial guess (starting value for vector intial guess) . This must be a vector intial guesses for a and b
fn = kumar_loglik, # checks height of likelihood surface
gr = combined_kum_gradient, # gradient uphill should be the combined gradient
data = storage,
method = "L-BFGS-B", #constraints the box
hessian = TRUE,
lower = c(1e-5, 1e-5), # keeps the parameters positive #would remove control if this was in the code
control = list(trace = FALSE,
fnscale = 1, #minimized the negative log likelihood function --> fnscale = -1 maximizes the function
maxit = 500,
abstol = 1e-8)
)
# Extract MLEs a and b
mle_a <- mle.result$par[1]
mle_b <- mle.result$par[2]
cat("MLE for a:", mle_a, "\nMLE for b:", mle_b)
MLE for a: 0.9593218
MLE for b: 1.999172
# Testing your combined function with a guess of a=1, b=1
combined_kum_gradient(params = test_params, data = storage)
[1] 3.23001 -24.56262
The MLE predicted \(\hat{a}\) is
0.9593218 and the MLE predicted \(\hat{b}\) is 1.9991723. The histogram of
storage appears to have some right tail and unimodal distribution
characteristics.
Problem B2:
Fit the power distribution to the above data using
the derived of \(a\) obtained in
Problem A4 to test the following hypothesis using
likelihood ratio procedure at significance level \(\alpha = 0.05\):
\[
H_0: b = 1 \quad \text{ versus } \quad H_a: b \ne 1.
\] $$
= -
$$ When we use log likelihood ratio tests we compared if the complex
nested equation is better at explaining the model than the simple nested
equation. Here we compare the power distribution (b=1) MLE to the full
Kumaraswamy model.
#Likelihood ratio procedure on the data at alpha =0.05
#using power distribution of MLE where b =1
storage
[1] 0.12 0.14 0.15 0.16 0.17 0.18 0.19 0.20 0.21 0.22 0.23 0.24 0.25 0.26 0.27
[16] 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.40 0.41 0.42
[31] 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.50 0.51 0.52 0.53 0.54 0.55 0.56 0.57
[46] 0.58 0.59 0.60 0.61 0.78
n=length(storage)
# - n/ (sum(data)*log(data))
mle_a_power= -n/ (sum(log(storage))) #MLE for a calculation
cat("MLE for a in the special case power distrubution:", mle_a_power)
MLE for a in the special case power distrubution: 0.9393197
#When we use loglikelihood ratio tests we compared if the complex nested equation is better at explaining the model than the simple nested equation. Here we compare the power distribution (b=1) MLE to the full kumaraswamy model
# The loglikelihood model for kumaraswamy a
loglike_kumar = -kumar_loglik(c(mle_a, mle_b), storage) # full unrestriced model
loglike_power = -kumar_loglik(c(mle_a_power, 1), storage) #restricted model log likelihood power distribution
LRT_statistic = 2* (loglike_kumar - loglike_power) #likelihood ratio statistic for the log kumaraswamy and likelihood for power distrubution
p_val = 1- pchisq(LRT_statistic, df=1)
cat("The likelihood ratio test statistic is", LRT_statistic, "p=", p_val, ".")
The likelihood ratio test statistic is 16.00457 p= 6.318993e-05 .
State the statistical decision clearly. What is the practical
implication of the testing result?
As the p value is less than \(\alpha=0.005\), (p=6.3189934^{-5}), we
reject the null hypothesis ($H_o: b=1 $) that the less complex power
distribution log likelihood model better suits the distribution. The
Kumaraswamy distribution should be used to model the daily storage water
data.
Problem B3:
Use the procedure and code from Problem B1 to
estimate the MLEs of \(a\) and \(b\), and then complete the following
analyses:
(1). Obtain the bootstrap sampling distributions of \(\hat{a}\) and \(\hat{b}\) and plot each distribution using
Gaussian kernel density curves.
#Bootstrap MLE for a and b
B=9999
boot_a = numeric(B) #allows number of bootstraps for a
boot_b = numeric(B) #allows number of bootstraps for b
n=length(storage)
set.seed(123)
for(i in 1:B) #begin bootstrap to find mle a and b
{
boot_sample= sample(storage, size=n, replace= TRUE ) #resample with replacement
#Estimate MLEs for bootstrap sample
#using optim
boot_mle= optim(
par = c(mle_a * runif(1, 0.9, 1.1), mle_b * runif(1, 0.9, 1.1)), # Jitter starting values #par = c(mle_a, mle_b), # Start at the original MLEs for speed
fn = kumar_loglik, # checks height of likelihood surface
gr = combined_kum_gradient, # gradient uphill should be the combined gradient
data = boot_sample,
method = "L-BFGS-B", #contraints box
lower = c(1e-5, 1e-5) # keeps the parameters positive #would remove control if this was in the code
)
boot_a[i] <- boot_mle$par[1] #output a MLE parameter
boot_b[i] <- boot_mle$par[2] #output b MLE parameter
}
#gaussian kernel building for a hat
plot(density(boot_a, kernel= "gaussian"), main = "Bootstrap Distrubution of a hat",
xlab="a hat", col= "skyblue", lwd=2)
abline(v= mle_a, col= "red", lty=2)#reference for original MLE

#gaussian kernel density for b hat
plot(density(boot_b, kernel = "gaussian"), main="Bootstrap Distrubution of b hat",
xlab= "b hat", col= "darkgreen", lwd=2)
abline(v = mle_b, col = "red", lty = 2)

The bootstrapped sampling distribution of a is 1.0214885. The
bootstrapped sampling distribution of b is 1.9411152.
(2). Construct both the \(95\%\)
bootstrap confidence interval and the Wald
confidence interval for \(b\).
Do these intervals agree with the results obtained in Problem
B2? [Compute the standard error of \(\hat{b}\) using the observed Fisher
information matrix, i.e., the inverse of the negative Hessian obtained
from optim()]
Wald Equation \[
\hat{b} + z_{\alpha/2} * \sqrt([I_n(\hat{b}]_{2,2}))
\]
## Bootstrapped Confidence Intervals
#boot_ci_a= quantile(boot_a, probs= c(0.025, 0.975))
#boot_ci_b = quantile(boot_b, probs= c(0.025, 0.975))
#cat("The bootstrapped confidence interval")
#Bootstrapped Normal Confidence Interval
alpha <- 0.05
z_critical <- qnorm(1 - alpha/2)
dis_crit_cal=boot_a + z_critical * (boot_a/sqrt(n))
# Calculate Bootstrap Standard Error (se_boot)
se_boot_a = sd(boot_a)
se_boot_b = sd(boot_b)
# Z critical value for 95%
z= qnorm(0.975)
#Confidence level for parameter a
ci_boot_a = c(LCI= mle_a - z*se_boot_a, #lower confidence level
#estimate= mle_a, #the value the CI is centered around
UCL= mle_a + z*se_boot_a #upper confidence level
)
cat("The bootstraped normal confidence interval for parameter a=", mle_a, "is, [", ci_boot_a, "].")
The bootstraped normal confidence interval for parameter a= 0.9593218 is, [ 0.8521865 1.066457 ].
ci_boot_b = c(LCI= mle_b - z*se_boot_b, #lower confidence level
#estimate= mle_b, #the value the CI is centered around
UCL= mle_b + z*se_boot_b #upper confidence level
)
cat("\n The bootstraped normal confidence interval for parameter b=", mle_b, "is, [", ci_boot_b, "].")
The bootstraped normal confidence interval for parameter b= 1.999172 is, [ 1.776119 2.222225 ].
#Percentile CI Boootstraps
boot_percentile_a = as.numeric(quantile(boot_a, probs= c(0.025, 0.975)))
boot_percentile_b = as.numeric(quantile(boot_b, probs= c(0.025, 0.975)))
cat("\n The bootstrapped percentile 95% confidence interval for parameter a= is, [", boot_percentile_a, "].")
The bootstrapped percentile 95% confidence interval for parameter a= is, [ 0.8681103 1.04955 ].
cat("\n The bootstraped percentile 95% confidence interval for parameter b is, [", boot_percentile_b, "].")
The bootstraped percentile 95% confidence interval for parameter b is, [ 1.810586 2.188767 ].
###########Wald CI
#Compute the Wald CI using observed Fisher information
fisher_info= solve(mle.result$hessian) #take the inverse of the mle.result matrix
#have values before this matrix in the equatinn as well as we describe some of the formula below
#variance(Theta1) #covariance(Theta1, Theta2)
#cov(Theta1, Theta2) # variance(theta2)
#inside the hessian matrix for wald which is the inverse of the fisher matrix * the matrix of hat\theta1 - inverse theta10 (on top of) hat\theta2 - theta20
#the inverse of
#variance(hat\a) #covariance(\hat\a, \hat\b)
#cov(\hat\a, \hat\b) # variance(\hat\a)
#we are only the b parameter
#calculate the standard error specific to wald b
se_wald_b = sqrt(fisher_info[2,2]) #standard error wald
z= qnorm(0.975)
wald_ci_b = c(LCI= mle_b- z*se_wald_b, UCL= mle_b + z*se_wald_b)
cat("\n The Wald Confidence Interval for b is [", wald_ci_b, "].")
The Wald Confidence Interval for b is [ 1.44504 2.553304 ].
We are comparing the Wald Confidence interval to a bootstrap sampling
confidence interval. To better capture the skewness of this Kumaraswamy
distribution we compare the bootstrapped Percentile Confidence Interval
to the Wald Confidence Interval. The Percentile 95%CI for parameter b is
[1.8105856, 2.188767] (width = 0.378181) . The Wald Confidence interval
is [1.4450403, 2.5533043] (width= 1.108264). The bootstrapped percentile
CI has a far smaller interval than the Wald Confidence interval
suggesting the Wald test is not the best test to use on the distribution
as it assumes a normal sampling distribution, which is best suited here.
The Wald 95%CI is underperforming the bootstrapped Normal 95%CI as well
[1.7761192, 2.2222254]. Our desire is to have a small confidence
interval as long as the distribution is well represented by the interval
used.
In Problem B2, we rejected the null hypothesis that the simpler model
suits the distribution, concluding the Kumaraswamy distribution better
models the daily storage water data. Considering this more complex
model, most likely has more complex distribution shape that is not well
represented by a normal distribution even when overcoming for some
robustness, the better suited bootstrapped percentile ci agrees with the
complexity of the dataset.
(3). Based on the bootstrap sampling distributions from part (1) of
this problem, assess whether the validity of the Wald confidence
interval is supported.
While the bootstrapped confidence intervals do not include 0, we can
assume our parameters a and b has significance. The bootstrap kernel
figure for \(\hat{a}\) range about from
0.83-1.10 with a MLE value of 1.0214885. The bootstrap kernel figure for
\(\hat{b}\) ranges from about 1.8 to
2.2 with an MLE value of 1.9411152. As the Wald confidence interval
[1.4450403, 2.5533043] is between kernel’s ranges for the entire
encompassing dataset therefore capturing an interval within a plausible
range although it is way less valid than its bootstrapped percentile
Confidence Interval.A percentile confidence interval is preferred for
the storage distribution. The Wald CI assumption for normality and
symmetry cannot well capture the true shape of the distribution. As the
distribution appears to have some unimodal shape and slight tail, rather
than a strong symmetrical shape centered around its MLE. The wider Wald
confidence interval highlights its uncertiany to measure deviations from
normal shape well.
Problem B4:
In the introduction to the working model for this exam, the
Kumaraswamy distribution reduces to the uniform distribution on (0,1).
In this problem, we perform a likelihood ratio test for
the following hypothesis to assess whether the data come from the
uniform distribution on (0,1):
\[
H_0: a = 1\quad \& \quad b = 1\quad \text{ versus } \quad H_a: a \ne
1 \quad \text{or} \quad b \ne 1 \quad \text{or}\quad (a \ne 1 \quad
\& \quad b \ne 1).
\]
Provide a practical interpretation of the above test result.
[Hint: \(H_a\) basically says that
there is no constraints for \(a\) and
\(b\). Please review the lecture note
for module 11 on the likelihood ratio test before coding.]
Here we compare the Kumaraswamy distribution to another special case
uniform distribution model where the distribution ranges between 0 and
1.
\[
LRT_{uni(1,1)}= 2[\ell(\hat{a}, \hat{b})-\ell(1,1)]
\]
n= length(storage)
#unrestricted original log likelihood from kumaraswamy distribution
logL_unrestricted = -kumar_loglik(c(mle_a, mle_b), storage) #presents joint probability of entire dataset give a and b parameters
#log likelihood for Uniform (a=1, b=1)
logL_restricted= -kumar_loglik(c(1,1), storage) #the parameters for 1 and 1 for both a and b
#log ratio test statistic
LRT_stat_unicomparison = 2 * (logL_unrestricted - logL_restricted)
pval_unicompLRT= 1- pchisq(LRT_stat_unicomparison, df=2)
cat("The log likelihood ratio considering the special case kumaswamy uniform distrubutio (a=1, b=1) is", LRT_stat_unicomparison, "(p=", pval_unicompLRT, ").")
The log likelihood ratio considering the special case kumaswamy uniform distrubutio (a=1, b=1) is 16.20465 (p= 0.0003028339 ).
When assessing the stronger model using the Likelihood Ratio Test,
the more complex Kumaraswamy distribution does a better job at modelling
the water storage distribution than the uniform model. If comparing
whether to use the restricted uniform distribution or the unrestricted
Kumaraswamy distribution, use the Kumaraswamy distribution (LRT=
16.2046521, p= 3.0283391^{-4}). Perhaps the slight right skewness of the
model is not well represented by the uniform distribution suggesting
daily water intake is not evenly distributed nor random.
It appears both the Kumaraswamy outperforms the uniform and power
distribution models.
Note: Please download the
template and insert your work into it to complete the exam.
LS0tDQp0aXRsZTogIlNUQSA1MDYgRmluYWwgRXhhbWluYXRpb24gU3ByaW5nICINCmF1dGhvcjogIiBFemFuYSBSaXZlcnMiDQpkYXRlOiAiIER1ZTogTWF5IDUgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgaGlnaGxpZ2h0OiBtb25vY2hyb21lDQogICAgdGhlbWU6IHNwYWNlbGFiDQogICAgc2VsZl9jb250YWluZWQ6IGZhbHNlDQogICAgbGliX2RpcjogbGlicw0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5yZXRpbmEgPSAxLCBkcGkgPSA3MCkNCg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogIGxpYnJhcnkoZ2dwbG90MikNCn0NCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQoNCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgbGlicmFyeShwbG90bHkpDQp9DQojIyMjDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQ0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAjIHNvbWV0aW1lcywgeW91IGNvZGUgbWF5IHByb2R1Y2Ugd2FybmluZyBtZXNzYWdlcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAgIyB5b3UgY2FuIGFsc28gZGVjaWRlIHdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgb3V0cHV0DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLg0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkENCiAgICAgICAgICAgICAgICAgICAgICApICANCmBgYA0KIA0KIFwNCiANCiMjICoqRmluYWwgRXhhbSBHdWlkZWxpbmVzKiogDQoNCiogKipDb3ZlcmFnZSoqOiBUaGUgbWFqb3IgY29uY2VwdHMgYW5kIGluZmVyZW5jZSBwcm9jZWR1cmVz4oCUc3VjaCBhcyBzYW1wbGluZyBkaXN0cmlidXRpb25zLCBjb25maWRlbmNlIGludGVydmFscywgYW5kIGh5cG90aGVzaXMgdGVzdGluZ+KAlGFyZSBjb3ZlcmVkIGFuZCBpbXBsZW1lbnRlZCB1c2luZyBib3RoIGNsYXNzaWNhbCBwYXJhbWV0cmljIGxpa2VsaWhvb2QtYmFzZWQgbWV0aG9kcyBhbmQgbW9kZXJuIG5vbi1wYXJhbWV0cmljIGFwcHJvYWNoZXMsIGluY2x1ZGluZyB0aGUgYm9vdHN0cmFwIGFuZCBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0aW9uLg0KDQoqICoqUGFydCBBKiogcmVxdWlyZXMgZGVyaXZhdGlvbiBvZiBzZWxlY3RlZCBsaWtlbGlob29kLWJhc2VkIGZ1bmN0aW9ucyBmb3IgcGVyZm9ybWluZyB2YXJpb3VzIHR5cGVzIG9mIGluZmVyZW5jZSwgd2l0aCBzdWZmaWNpZW50IGRldGFpbCB0byBlbmFibGUgdHJhbnNsYXRpb24gb2YgdGhlc2UgZGVyaXZhdGlvbnMgaW50byBjb2RlIGZvciBudW1lcmljYWwgYW5hbHlzaXMuDQoNCiogWW91ciBjb2RlIGZvciB0aGUgcHJvYmxlbXMgaW4gKipQYXJ0IEIqKiBtdXN0IGFsaWduIHdpdGggeW91ciBkZXJpdmF0aW9ucyBpbiAqKlBhcnQgQSoqIGFuZCBiZSB3ZWxsIGNvbW1lbnRlZCB3aGVyZSBuZWNlc3NhcnkuDQoNCiogSW4gKipQYXJ0IEIqKiwgYWxsIG51bWVyaWNhbCByZXN1bHRzIG11c3QgYmUgaW50ZXJwcmV0ZWQgZnJvbSBhIHByYWN0aWNhbCBwZXJzcGVjdGl2ZS4NCg0KDQpcDQoNCiMjICoqUG9saWNpZXMgb2YgVXNpbmcgQUkgVG9vbHMqKg0KDQoqICoqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFN0dWRlbnRzIG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKiAqKkNvZGUgSW5jbHVzaW9uIFJlcXVpcmVtZW50Kio6IEFueSBjb2RlIGluY2x1ZGVkIGluIHlvdXIgZXNzYXkgbXVzdCBiZSBwcm9wZXJseSBjb21tZW50ZWQgdG8gZXhwbGFpbiB0aGUgcHVycG9zZSBhbmQvb3IgZXhwZWN0ZWQgb3V0cHV0IG9mIGtleSBjb2RlIGxpbmVzLiBTdWJtaXR0aW5nIEFJLWdlbmVyYXRlZCBjb2RlIHdpdGhvdXQgbWVhbmluZ2Z1bCwgc3R1ZGVudC1hZGRlZCBjb21tZW50cyB3aWxsIG5vdCBiZSBhY2NlcHRlZC4NCg0KXA0KDQojIyAqKldvcmtpbmcgTW9kZWwgZm9yIHRoZSBGaW5hbCBFeGFtKioNCg0KPGZvbnQgY29sb3IgPSAib3JhbmdlIj4qKkNhdXRpb24qKjogKlBsZWFzZSBmb2xsb3cgdGhlIHN1Z2dlc3RlZCBleHByZXNzaW9ucyBhbmQgZ3VpZGVkIHN0ZXBzIHRvIGNvbXBsZXRlIHRoZSBleGFtLiBPdGhlciBhcHByb2FjaGVzIHN1Y2ggYXMgdHJhbnNmb3JtYXRpb24gZm9yIHRyaXZpYWxpemUgdGhlIHByb2JsZW1zIHRoYXQgd2lsbCBub3QgbWVldCB0aGUgZXhhbSBvYmplY3RpdmVzLio8L2ZvbnQ+DQoNCg0KVGhlICoqS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uKiogaXMgYSB0d28tcGFyYW1ldGVyIGNvbnRpbnVvdXMgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGRlZmluZWQgb24gdGhlIGludGVydmFsICgwLCAxKS4gSXQgaXMgb2Z0ZW4gdXNlZCBhcyBhbiBhbHRlcm5hdGl2ZSB0byB0aGUgQmV0YSBkaXN0cmlidXRpb24gZHVlIHRvIGl0cyBzaW1wbGUgY2xvc2VkLWZvcm0gZXhwcmVzc2lvbnMgZm9yIHRoZSBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiAoQ0RGKSBhbmQgcXVhbnRpbGUgZnVuY3Rpb24uIEl0IGlzIGNvbW1vbmx5IHVzZWQgaW4gDQoNCiogKipIeWRyb2xvZ3kqKjogTW9kZWxpbmcgcmFpbmZhbGwsIHN0cmVhbWZsb3csIG9yIG90aGVyIGJvdW5kZWQgbmF0dXJhbCBwaGVub21lbmENCg0KKiAqKkVjb25vbWljcyoqOiBJbmNvbWUgc2hhcmVzLCBwcm9wb3J0aW9ucywgb3IgYm91bmRlZCBpbmRpY2VzDQoNCiogKipNb250ZSBDYXJsbyBzaW11bGF0aW9uKio6IEVmZmljaWVudCByYW5kb20gdmFyaWF0ZSBnZW5lcmF0aW9uICh2aWEgaW52ZXJzZSB0cmFuc2Zvcm0pDQoNCiogKipNYWNoaW5lIGxlYXJuaW5nKio6IE91dHB1dCBsYXllciBmb3IgYm91bmRlZCB0YXJnZXRzLCBwcmlvciBkaXN0cmlidXRpb25zIGluIEJheWVzaWFuIG1vZGVscw0KDQoqICoqUmVsaWFiaWxpdHkgZW5naW5lZXJpbmcqKjogTW9kZWxpbmcgZmFpbHVyZSByYXRlcyBvZiBzeXN0ZW1zIHdpdGggYm91bmRlZCBsaWZldGltZXMNCg0KXA0KDQpMZXQgJFgkIGJlIHRoZSBLdW1hcmFzd2FteSByYW5kb20gdmFyaWFibGUgd2l0aCBDdW11bGF0aXZlIERpc3RyaWJ1dGlvbiBGdW5jdGlvbiAoQ0RGKSAgDQoNCiQkDQpGKHg7IGEsIGIpID0gMSAtICgxIC0geF5hKV5iDQokJA0KDQp3aGVyZSAkYSA+IDAkIGFuZCAkYiA+IDAkIHVua25vd24gcGFyYW1ldGVycyBhbmQgJDAgPCB4IDwgMSQuIA0KDQpUaGUgZm9sbG93aW5nIGFyZSB0d28gc3BlY2lhbCBjYXNlIG9mIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb246DQoNCjEuICoqVW5pZm9ybSBEaXN0cmlidXRpb24qKjogV2hlbiAkYSA9IDEkIGFuZCAkYiA9IDEkLCB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIGJlY29tZXMgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBvdmVyICRbMCwgMV0kIHdpdGggQ0RGICRGKHgpID0geCQuDQoNCg0KMi4gKipQb3dlciBEaXN0cmlidXRpb24qKjogd2hlbiAkYiA9IDEkIGFuZCAkYSA+IDAkLCB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIGJlY29tZXMgYSBwb3dlciBkaXN0cmlidXRpb24gb3ZlciAkWzAsIDFdJCB3aXRoIENERiAkRih4KSA9IHheYSQuIA0KDQpUaGlzIGZpbmFsIGV4YW0gZm9jdXNlcyBvbiBpbmZlcmVuY2VzIG9mIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiBhbmQgcmVsYXRlZCBkYXRhIGFuYWx5c2lzLg0KDQoNCiMjIFBhcnQgQTogTWV0aG9kb2xvZ2ljYWwgRGVyaXZhdGlvbnMNCg0KXA0KDQojIyMgKipQcm9ibGVtIEExKio6IA0KU2hvdyB0aGF0IHRoZSBkZW5zaXR5IGZ1bmN0aW9uIG9mIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gaXMNCg0KJCQNCmYoeDsgYSwgYikgPSBhYiBcLCB4XnthLTF9ICgxIC0geF5hKV57Yi0xfS4NCiQkDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjUwJSIsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLmNhcD0iIFByb2JsZW0gQTEifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImh0dHBzOi8vaS5wb3N0aW1nLmNjLzR4cjl5OWJjL1Byb2JsZW0tQTEuanBnIikNCg0KYGBgDQoNCg0KXA0KDQojIyMgKipQcm9ibGVtIEEyKio6IA0KTGV0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSQgYmUgYW4gaS5pLmQuIHJhbmRvbSBzYW1wbGUgdGFrZW4gZnJvbSBhIHBvcHVsYXRpb24gdGhhdCBmb2xsb3dzIHRoZSBhYm92ZSAyLXBhcmFtZXRlciBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24uIFdyaXRlIG91dCB0aGUgbG9nbGlrZWxpaG9vZCBmdW5jdGlvbiBvZiAkYSQgYW5kICRiJCwgZGVub3RlZCBieSAkXGVsbChhLGIpJCwgYmFzZWQgb24gdGhlIGFib3ZlIHJhbmRvbSBzYW1wbGUgYW5kICoqZGVyaXZlKiogdGhlIGdyYWRpZW50IHZlY3RvciAkW1xlbGxfYV5ccHJpbWUoYSxiKSwgXGVsbF9iXlxwcmltZShhLGIpXSQsIHRoZSBmaXJzdCBvcmRlciBwYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhlIGxvZy1saWtlbGlob29kIHdpdGggcmVzcGVjdCB0byBwYXJhbWV0ZXJzICRhJCBhbmQgJGIkLg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjUwJSIsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLmNhcD0iIFByb2JsZW0gQTIifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImh0dHBzOi8vaS5wb3N0aW1nLmNjL1BmNFl5TmhnL1Byb2JsZW0tQTItcHQxLmpwZyIpDQoNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy5jYXA9IiBQcm9ibGVtIEEyIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2kucG9zdGltZy5jYy9id0ducVRueC9Qcm9ibGVtLUEyLXB0Mi5qcGciKQ0KDQpgYGANCg0KDQpcDQoNCiMjIyAqKlByb2JsZW0gQTMqKjogDQpCYXNlZCBvbiB0aGUgZ3JhZGllbnRzIGZ1bmN0aW9ucyBvYnRhaW5lZCBpbiB0aGUgYWJvdmUgcHJvYmxlbSBBMiwgKipkZXJpdmUqKiB0aGUgb2JzZXJ2ZWQgRmlzaGVyIEluZm9ybWF0aW9uIG1hdHJpeCAoaS5lLCB0aGUgbmVnYXRpdmUgSGVzc2lhbiBNYXRyaXgpLg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy5jYXA9IiBQcm9ibGVtIEEzIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2kucG9zdGltZy5jYy9XMURac25aSC9Qcm9ibGVtLUEzLXB0MS5qcGciKQ0KDQpgYGANCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSI1MCUiLCBmaWcuYWxpZ249ImNlbnRlciIsIGZpZy5jYXA9IiBQcm9ibGVtIEEzIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2kucG9zdGltZy5jYy8yU3FXQ3dXSi9Qcm9ibGVtLUEzLXB0Mi5qcGciKQ0KDQpgYGANCg0KXA0KDQojIyMgKipQcm9ibGVtIEE0Kio6IA0KDQpDb25zaWRlciBwb3dlciBkaXN0cmlidXRpb24gJEYoeCkgPSB4XmEsIChhID4wIFxxdWFkIFx0ZXh0eyBhbmQgfVxxdWFkIHggXGluICgwLDEpKSQsIGEgc3BlY2lhbCBjYXNlIG9mIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gd2l0aCAkYiA9IDEkLCBhbmQgYSByYW5kb20gc2FtcGxlIGZyb20gdGhpcyBkaXN0cmlidXRpb24gJFx7IHhfMSwgeF8yLCBcY2RvdHMsIHhfblx9JC4gKipEZXJpdmUqKiB0aGUgTUxFIGFuZCBNTUUgb2YgJGEkIHJlc3BlY3RpdmVseS4gWypIaW50OiBUbyBmaW5kIHRoZSBNTUUsIHlvdSBuZWVkIHRvIGNvbXB1dGUgdGhlIG1vbWVudCBvZiB0aGUgcG93ZXIgZGlzdHJpYnV0aW9uOyB0aGF0IGlzLCAkRVtYXmtdID0gXGludF8wXjEgeF5rIEYnKHgpIGR4JC4gTm90ZSB0aGF0IGJvdGggdGhlIE1MRSBhbmQgdGhlIE1NRSBoYXZlIGNsb3NlZC1mb3JtIGV4cHJlc3Npb25zLipdDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuY2FwPSIgUHJvYmxlbSBBNCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9pLnBvc3RpbWcuY2MvalNXZlJYZjgvUHJvYmxlbS1BNC1wdDEuanBnIikNCg0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjUwJSIsIGZpZy5hbGlnbj0iY2VudGVyIiwgZmlnLmNhcD0iIFByb2JsZW0gQTQifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImh0dHBzOi8vaS5wb3N0aW1nLmNjL1lDSlcwV2ZCL1Byb2JsZW0tQTQtcHQyLmpwZyIpDQoNCmBgYA0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuY2FwPSIgUHJvYmxlbSBBNCJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9pLnBvc3RpbWcuY2MvM3hQdk52Q3cvUHJvYmxlbS1BNC1wdDMuanBnIikNCg0KYGBgDQoNCg0KXA0KDQojIyMgKipQcm9ibGVtIEE1Kio6DQoNClVzaW5nIHRoZSBzYW1lIHNldHRpbmcgYXMgaW4gKipQcm9ibGVtIEE0KiosIGZpbmQgdGhlIGFzeW1wdG90aWMgKFdhbGQpIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yICRhJC4gWypIaW50OiBDb21wdXRlIHRoZSBGaXNoZXIgaW5mb3JtYXRpb24gZm9yICRhJCwgdGhlbiB0YWtlIGl0cyByZWNpcHJvY2FsIHRvIG9idGFpbiB0aGUgdmFyaWFuY2UqLl0NCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuY2FwPSIgUHJvYmxlbSBBNSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9pLnBvc3RpbWcuY2MvRkgyTHpMZ1IvUHJvYmxlbS1BNS5qcGciKQ0KDQpgYGANCg0KXA0KDQojIyMgKipQcm9ibGVtIEE2Kio6DQoNClVzaW5nIHRoZSBzYW1lIHNldHRpbmcgYXMgaW4gKipQcm9ibGVtIEE0KiosIHBlcmZvcm0gYSBsaWtlbGlob29kIHJhdGlvIHRlc3QgZm9yIHRoZSBoeXBvdGhlc2lzICRIXzAgOmE9MSQgKGkuZS4sIHRoZSBwb3dlciBkaXN0cmlidXRpb24gcmVkdWNlcyB0byBhIHVuaWZvcm0gZGlzdHJpYnV0aW9uKS4gWypIaW50OiBFdmFsdWF0ZSB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gYXQgdGhlIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0ZSAkXGhhdHthfSQgYW5kIGF0ICRhPTEkLCB0aGVuIHVzZSB0aGVzZSB2YWx1ZXMgdG8gY29uc3RydWN0IHRoZSBMUlQgdGVzdCBzdGF0aXN0aWMuKl0NCg0KYGBge3IsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNTAlIiwgZmlnLmFsaWduPSJjZW50ZXIiLCBmaWcuY2FwPSIgUHJvYmxlbSBBNiJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaHR0cHM6Ly9pLnBvc3RpbWcuY2MvalNHNzI3UUwvUHJvYmxlbS1BNi5qcGciKQ0KDQpgYGANCg0KDQoNClwNCg0KIyMgUGFydCBCOiBOdW1lcmljYWwgQW5hbHlzaXMNCg0KKipBbGwgY29kZSBtdXN0IGJlIHdlbGwgY29tbWVudGVkIGFuZCBhZGhlcmUgdG8gYmVzdCBjb2RpbmcgcHJhY3RpY2VzKioNCg0KKipXb3JraW5nIERhdGFzZXQqKjogQSBzbWFsbCByZXNlcnZvaXIgc3VwcGxpZXMgd2F0ZXIgdG8gYSB0b3duLiBEdXJpbmcgdGhlIGRyeSBzZWFzb24gKDUwIGRheXMpLCBlbmdpbmVlcnMgcmVjb3JkIHRoZSBmcmFjdGlvbiBvZiB1c2FibGUgc3RvcmFnZSBmaWxsZWQgZWFjaCBtb3JuaW5nLiBWYWx1ZXMgbmVhciAwIG1lYW4gdGhlIHJlc2Vydm9pciBpcyBuZWFybHkgZW1wdHk7IHZhbHVlcyBuZWFyIDEgbWVhbiBpdCdzIGZ1bGwuIFRoZSBkaXN0cmlidXRpb24gdGVuZHMgdG8gYmUgcmlnaHTigJFza2V3ZWQgKG1vc3RseSBsb3cgbGV2ZWxzIGR1ZSB0byBkcm91Z2h0KSBidXQgd2l0aCBvY2Nhc2lvbmFsIHJlcGxlbmlzaG1lbnQuDQoNClRoZSBmb2xsb3dpbmcgNTAgZGF0YSBwb2ludHMgKG9yZGVyZWQgZm9yIGNsYXJpdHkpIHJlcHJlc2VudCB0aGUgZGFpbHkgcHJvcG9ydGlvbiBvZiB1c2FibGUgc3RvcmFnZToNCg0KYGBgDQowLjEyLCAwLjE0LCAwLjE1LCAwLjE2LCAwLjE3LCAwLjE4LCAwLjE5LCAwLjIwLCAwLjIxLCAwLjIyLA0KMC4yMywgMC4yNCwgMC4yNSwgMC4yNiwgMC4yNywgMC4yOCwgMC4yOSwgMC4zMCwgMC4zMSwgMC4zMiwNCjAuMzMsIDAuMzQsIDAuMzUsIDAuMzYsIDAuMzcsIDAuMzgsIDAuMzksIDAuNDAsIDAuNDEsIDAuNDIsDQowLjQzLCAwLjQ0LCAwLjQ1LCAwLjQ2LCAwLjQ3LCAwLjQ4LCAwLjQ5LCAwLjUwLCAwLjUxLCAwLjUyLA0KMC41MywgMC41NCwgMC41NSwgMC41NiwgMC41NywgMC41OCwgMC41OSwgMC42MCwgMC42MSwgMC43OA0KYGBgDQoNClwNCg0KIyMjICoqUHJvYmxlbSBCMSoqOg0KDQpGaXQgdGhlIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiB0byB0aGUgYWJvdmUgZGF0YS4gVXNlIHRoZSBkZXJpdmF0aW9ucyBpbiAqKlByb2JsZW0gQTIqKiB0byBmaW5kIHRoZSBNTEUgb2YgJGEkIGFuZCAkYiQuICoqUGxlYXNlIGNvcHkgdGhlIGtleSBmb3JtdWxhcyBiZWZvcmUgY29kaW5nLioqDQoNCkZvcm11bGFzOg0KDQpHcmFkaWVudCBWZWN0b3IgZm9yIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiBsb2cgbGlrZWxpaG9vZHMuDQoNCkdyYWRpZW50IFZlY3RvciAkXGVsbCdfYihhLGIpJA0KDQokJA0KXGVsbCdfYihhLGIpID0gXGZyYWN7bn17Yn0gKyBcc3VtXm5fe2k9MX0gbG4oMS1YXmFfaSkNCiQkDQokJA0KXGVsbCdfYShhLGIpID0gXGZyYWN7bn17YX0gK1xzdW1ebl97aT0xfSBsbihYX2kpICsoYi0xKVxzdW1ebl97aT0xfVxmcmFje1heYV9pIGxuWF9pfXsxLVheYV9pfQ0KJCQNCg0KYGBge3J9DQoNCnN0b3JhZ2U9IHNvcnQoYygwLjEyLCAwLjE0LCAwLjE1LCAwLjE2LCAwLjE3LCAwLjE4LCAwLjE5LCAwLjIwLCAwLjIxLCAwLjIyLA0KMC4yMywgMC4yNCwgMC4yNSwgMC4yNiwgMC4yNywgMC4yOCwgMC4yOSwgMC4zMCwgMC4zMSwgMC4zMiwNCjAuMzMsIDAuMzQsIDAuMzUsIDAuMzYsIDAuMzcsIDAuMzgsIDAuMzksIDAuNDAsIDAuNDEsIDAuNDIsDQowLjQzLCAwLjQ0LCAwLjQ1LCAwLjQ2LCAwLjQ3LCAwLjQ4LCAwLjQ5LCAwLjUwLCAwLjUxLCAwLjUyLA0KMC41MywgMC41NCwgMC41NSwgMC41NiwgMC41NywgMC41OCwgMC41OSwgMC42MCwgMC42MSwgMC43OCkpDQoNCmhpc3Qoc3RvcmFnZSkgI2hpc3RvZ3JhbSBvZiBkYXRhc2V0DQoNCiNGaW5kIE1MRSBvZiBhIGFuZCBiDQoNCiNHcmFkaWVudCBmb3IgbG9nX2IoYSxiKQ0KDQoNCiNuPSBsZW5ndGgoc3RvcmFnZSkNCg0KI2Z1bmN0aW9uIHRvIGZpbmQgdmFsdWVzIG9mIGEgYW5kIGIgYmFzZWQgb24gdGhlIGRhdGFzZXQgYWxvbmUNCg0KDQojZmluZGluZyB0aGUgZ3JhZGllbnQgb2YgYg0KZ3JhZF9iZnVuYyA9ZnVuY3Rpb24ocGFyYW1zLCBkYXRhKSB7DQogIGEgPC0gcGFyYW1zWzFdDQogIGIgPC0gcGFyYW1zWzJdDQogIA0KICBuIDwtIGxlbmd0aChkYXRhKQ0KICANCiNuL2IgKyBzdW0obG9nKDEteF5hKSkNCiAgc3VtX3Rlcm09ICBzdW0obG9nKDEtIGRhdGFeYSkpICNuL2IgKyBzdW0oZGF0YSkNCiAgZ3JhZGllbnRfYiA9IC0oKG4vYikgKyBzdW1fdGVybSkNCiAgDQogIHJldHVybihncmFkaWVudF9iKQ0KfQ0KDQoNCmdyYWRfYWZ1bmMgPSBmdW5jdGlvbihwYXJhbXMsIGRhdGEpICNidWlsZGluZyBsb2cgbGlrZWxpaG9vZCBmb3IgZ3JhZGllbnQgdmVjdG9yDQp7DQogIA0KICBhIDwtIHBhcmFtc1sxXQ0KICBiIDwtIHBhcmFtc1syXQ0KICBuID0gbGVuZ3RoKGRhdGEpDQogIA0KICBmaXJzdCA9KG4vYSkgI2ZpcnN0IHRlcm0gb2YgZ3JhZGllbnQgZXF1YXRpb24gZm9yIGENCiAgbG9nZGF0YT0gc3VtKGxvZyhkYXRhKSkgI2xvZ2luZyBhbGwgc3VtbWVkIGRhdGEgaW4gdGhlIGRhdGFzZXQNCiAgYjE9IChiLTEpDQogICAgICBudW1fYSA9ICgoZGF0YV5hKSogbG9nKGRhdGEpKSAjbnVtZXJhdG9yIG9mIGxhc3QgdGVybQ0KICAgICAgZG9tX2EgPSAoMS0gKGRhdGFeYSkpICNkZW5vbWluYXRvciBvZiBsYXN0IHRlcm0NCiAgbGFzdF90ZXJtX2dhPSBzdW0obnVtX2EvZG9tX2EpICNmaW5hbGl6ZWQgZnJhY3R0aW9uIGZvciBsYXN0IHRlcm0gdG8gYmUgcHV0IGludG8gZ3JhZGllbnQgZXF1YXRpb24NCiAgDQogIGdyYWRfYSA9IC0oZmlyc3QgKyBsb2dkYXRhICsgYjEgKiBsYXN0X3Rlcm1fZ2EpICNncmFkaWVudCB0ZXJtIGZvciBhIHVzaW5nIGFsbCBkYXRhIChubyBib290c3RyYXBzLCBldGMuIGp1c3QgbG9vcCkNCiANCnJldHVybihncmFkX2EpDQogICANCn0NCg0KI3BsYWNpbmcgYSBhbmQgYiBmcmFkaWVudHMgaW4gdGhlIHNhbWUgZnVuY3Rpb24gdG8gbGF0ZXIgY29tcGFyZSBpbiBvcHRpbSgpIGFuZCBwb3NzaWJsZSBtYXRyaXggYnVpbGRpbmcNCmNvbWJpbmVkX2t1bV9ncmFkaWVudD0gZnVuY3Rpb24ocGFyYW1zLCBkYXRhKXsNCiAgYSA8LSBwYXJhbXNbMV0NCiAgYiA8LSBwYXJhbXNbMl0NCiAgbiA9IGxlbmd0aChkYXRhKQ0KIyMjIyMjIyMjIyMjIyMjIyMjaWYgeW91IGNob29zZSB0byBibG9jayBvciBjaGFuZ2UgZXZlcnl0aGluZyBpbiBiZXR3ZWVuICANCiAjIGdyYWRfYQ0KIyAgZ3JhZGllbnRfYg0KICANCiMgIHJldHVybihjKGdyYWRfYSwgZ3JhZGllbnRfYikpDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICAgIA0KICANCiAgZ2EgPC0gZ3JhZF9hZnVuYyhwYXJhbXMsIGRhdGEpDQogIGdiIDwtIGdyYWRfYmZ1bmMocGFyYW1zLCBkYXRhKQ0KDQogICMgUmV0dXJuIHRoZW0gdG9nZXRoZXIgYXMgYSB2ZWN0b3IgZm9yIHRoZSBvcHRpbWl6ZXINCiAgcmV0dXJuKGMoZ2EsIGdiKSkNCiAgDQp9DQoNCg0KIyBOZWdhdGl2ZSBMb2ctTGlrZWxpaG9vZCAoVGFyZ2V0IGZvciBPcHRpbWl6YXRpb24pDQprdW1hcl9sb2dsaWsgPSBmdW5jdGlvbihwYXJhbXMsIGRhdGEpIHsNCiAgYSA8LSBwYXJhbXNbMV0NCiAgYiA8LSBwYXJhbXNbMl0NCiAgbiA8LSBsZW5ndGgoZGF0YSkNCiAgDQogICMgQmFzZWQgb24geW91ciBkZXJpdmF0aW9uIGluIEEyDQogIGxvZ2wgPSBuKmxvZyhhKSArIG4qbG9nKGIpICsgKGEtMSkqc3VtKGxvZyhkYXRhKSkgKyAgIChiLTEpKnN1bShsb2coMSAtIGRhdGFeYSkpDQogIA0KICByZXR1cm4oLWxvZ2wpICMgV2UgcmV0dXJuIG5lZ2F0aXZlIGJlY2F1c2Ugb3B0aW0oKSBtaW5pbWl6ZXMgYnkgZGVmYXVsdA0KfQ0KDQp0ZXN0X3BhcmFtcz0gYygxLDEpDQoNCg0KbWxlLnJlc3VsdD0gb3B0aW0oDQogIHBhciA9IHRlc3RfcGFyYW1zLCAgICAjaW50aWFsIGd1ZXNzIChzdGFydGluZyB2YWx1ZSBmb3IgdmVjdG9yIGludGlhbCBndWVzcykgLiBUaGlzIG11c3QgYmUgYSB2ZWN0b3IgaW50aWFsIGd1ZXNzZXMgZm9yIGEgYW5kIGINCiAgZm4gPSBrdW1hcl9sb2dsaWssICMgY2hlY2tzIGhlaWdodCBvZiBsaWtlbGlob29kIHN1cmZhY2UNCiAgZ3IgPSBjb21iaW5lZF9rdW1fZ3JhZGllbnQsICMgZ3JhZGllbnQgdXBoaWxsIHNob3VsZCBiZSB0aGUgY29tYmluZWQgZ3JhZGllbnQNCiAgZGF0YSA9IHN0b3JhZ2UsDQogIG1ldGhvZCA9ICJMLUJGR1MtQiIsICNjb25zdHJhaW50cyB0aGUgYm94DQogIGhlc3NpYW4gPSBUUlVFLA0KICBsb3dlciA9IGMoMWUtNSwgMWUtNSksICMga2VlcHMgdGhlIHBhcmFtZXRlcnMgcG9zaXRpdmUgI3dvdWxkIHJlbW92ZSBjb250cm9sIGlmIHRoaXMgd2FzIGluIHRoZSBjb2RlDQogIGNvbnRyb2wgPSBsaXN0KHRyYWNlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgIGZuc2NhbGUgPSAxLCAjbWluaW1pemVkIHRoZSBuZWdhdGl2ZSBsb2cgbGlrZWxpaG9vZCBmdW5jdGlvbiAtLT4gZm5zY2FsZSA9IC0xIG1heGltaXplcyB0aGUgZnVuY3Rpb24NCiAgICAgICAgICAgICAgICAgbWF4aXQgPSA1MDAsDQogICAgICAgICAgICAgICAgIGFic3RvbCA9IDFlLTgpDQopDQogIA0KDQojIEV4dHJhY3QgTUxFcyBhIGFuZCBiDQptbGVfYSA8LSBtbGUucmVzdWx0JHBhclsxXQ0KbWxlX2IgPC0gbWxlLnJlc3VsdCRwYXJbMl0NCmNhdCgiTUxFIGZvciBhOiIsIG1sZV9hLCAiXG5NTEUgZm9yIGI6IiwgbWxlX2IpDQoNCg0KIyBUZXN0aW5nIHlvdXIgY29tYmluZWQgZnVuY3Rpb24gd2l0aCBhIGd1ZXNzIG9mIGE9MSwgYj0xDQoNCmNvbWJpbmVkX2t1bV9ncmFkaWVudChwYXJhbXMgPSB0ZXN0X3BhcmFtcywgZGF0YSA9IHN0b3JhZ2UpDQpgYGANClRoZSBNTEUgcHJlZGljdGVkICRcaGF0e2F9JCBpcyBgciBtbGVfYWAgYW5kIHRoZSBNTEUgcHJlZGljdGVkICRcaGF0e2J9JCBpcyBgciBtbGVfYmAuDQpUaGUgaGlzdG9ncmFtIG9mIHN0b3JhZ2UgYXBwZWFycyB0byBoYXZlIHNvbWUgcmlnaHQgdGFpbCBhbmQgdW5pbW9kYWwgZGlzdHJpYnV0aW9uIGNoYXJhY3RlcmlzdGljcy4NCg0KXA0KDQojIyMgKipQcm9ibGVtIEIyKio6DQoNCkZpdCB0aGUgKipwb3dlciBkaXN0cmlidXRpb24qKiB0byB0aGUgYWJvdmUgZGF0YSB1c2luZyB0aGUgZGVyaXZlZCAgb2YgJGEkIG9idGFpbmVkIGluICoqUHJvYmxlbSBBNCoqIHRvIHRlc3QgdGhlIGZvbGxvd2luZyBoeXBvdGhlc2lzIHVzaW5nIGxpa2VsaWhvb2QgcmF0aW8gcHJvY2VkdXJlIGF0IHNpZ25pZmljYW5jZSBsZXZlbCAkXGFscGhhID0gMC4wNSQ6DQoNCiQkDQpIXzA6IGIgPSAxIFxxdWFkIFx0ZXh0eyB2ZXJzdXMgfSBccXVhZCBIX2E6IGIgXG5lIDEuDQokJA0KJCQNCg0KXGhhdHthX3tNTEV9fSA9IC1cZnJhY3tufXtcc3VtXm5fe2k9MX1sbnhfaX0NCg0KJCQNCldoZW4gd2UgdXNlIGxvZyBsaWtlbGlob29kIHJhdGlvIHRlc3RzIHdlIGNvbXBhcmVkIGlmIHRoZSBjb21wbGV4IG5lc3RlZCBlcXVhdGlvbiBpcyBiZXR0ZXIgYXQgZXhwbGFpbmluZyB0aGUgbW9kZWwgdGhhbiB0aGUgc2ltcGxlIG5lc3RlZCBlcXVhdGlvbi4gSGVyZSB3ZSBjb21wYXJlIHRoZSBwb3dlciBkaXN0cmlidXRpb24gKGI9MSkgTUxFIHRvIHRoZSBmdWxsIEt1bWFyYXN3YW15IG1vZGVsLg0KDQpgYGB7cn0NCiNMaWtlbGlob29kIHJhdGlvIHByb2NlZHVyZSBvbiB0aGUgZGF0YSBhdCBhbHBoYSA9MC4wNQ0KI3VzaW5nIHBvd2VyIGRpc3RyaWJ1dGlvbiBvZiBNTEUgd2hlcmUgYiA9MSANCg0Kc3RvcmFnZQ0KDQpuPWxlbmd0aChzdG9yYWdlKQ0KDQojIC0gbi8gKHN1bShkYXRhKSpsb2coZGF0YSkpDQoNCm1sZV9hX3Bvd2VyPSAtbi8gKHN1bShsb2coc3RvcmFnZSkpKSAjTUxFIGZvciBhIGNhbGN1bGF0aW9uDQoNCmNhdCgiTUxFIGZvciBhIGluIHRoZSBzcGVjaWFsIGNhc2UgcG93ZXIgZGlzdHJ1YnV0aW9uOiIsIG1sZV9hX3Bvd2VyKQ0KDQojV2hlbiB3ZSB1c2UgbG9nbGlrZWxpaG9vZCByYXRpbyB0ZXN0cyB3ZSBjb21wYXJlZCBpZiB0aGUgY29tcGxleCBuZXN0ZWQgZXF1YXRpb24gaXMgYmV0dGVyIGF0IGV4cGxhaW5pbmcgdGhlIG1vZGVsIHRoYW4gdGhlIHNpbXBsZSBuZXN0ZWQgZXF1YXRpb24uIEhlcmUgd2UgY29tcGFyZSB0aGUgcG93ZXIgZGlzdHJpYnV0aW9uIChiPTEpIE1MRSB0byB0aGUgZnVsbCBrdW1hcmFzd2FteSBtb2RlbA0KDQojIFRoZSBsb2dsaWtlbGlob29kIG1vZGVsIGZvciBrdW1hcmFzd2FteSBhDQoNCmxvZ2xpa2Vfa3VtYXIgPSAta3VtYXJfbG9nbGlrKGMobWxlX2EsIG1sZV9iKSwgc3RvcmFnZSkgIyBmdWxsIHVucmVzdHJpY2VkIG1vZGVsIA0KDQpsb2dsaWtlX3Bvd2VyID0gLWt1bWFyX2xvZ2xpayhjKG1sZV9hX3Bvd2VyLCAxKSwgc3RvcmFnZSkgI3Jlc3RyaWN0ZWQgbW9kZWwgbG9nIGxpa2VsaWhvb2QgcG93ZXIgZGlzdHJpYnV0aW9uDQoNCg0KTFJUX3N0YXRpc3RpYyA9IDIqIChsb2dsaWtlX2t1bWFyIC0gbG9nbGlrZV9wb3dlcikgI2xpa2VsaWhvb2QgcmF0aW8gc3RhdGlzdGljIGZvciB0aGUgbG9nIGt1bWFyYXN3YW15IGFuZCBsaWtlbGlob29kIGZvciBwb3dlciBkaXN0cnVidXRpb24NCg0KDQpwX3ZhbCA9IDEtIHBjaGlzcShMUlRfc3RhdGlzdGljLCBkZj0xKQ0KDQpjYXQoIlRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3Qgc3RhdGlzdGljIGlzIiwgTFJUX3N0YXRpc3RpYywgInA9IiwgcF92YWwsICIuIikNCg0KYGBgDQoNClN0YXRlIHRoZSBzdGF0aXN0aWNhbCBkZWNpc2lvbiBjbGVhcmx5LiBXaGF0IGlzIHRoZSBwcmFjdGljYWwgaW1wbGljYXRpb24gb2YgdGhlIHRlc3RpbmcgcmVzdWx0Pw0KDQpBcyB0aGUgcCB2YWx1ZSBpcyBsZXNzIHRoYW4gJFxhbHBoYT0wLjAwNSQsIChwPWByIHBfdmFsYCksIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzICgkSF9vOiBiPTEgJCkgdGhhdCB0aGUgbGVzcyBjb21wbGV4IHBvd2VyIGRpc3RyaWJ1dGlvbiBsb2cgbGlrZWxpaG9vZCBtb2RlbCBiZXR0ZXIgc3VpdHMgdGhlIGRpc3RyaWJ1dGlvbi4gVGhlIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiBzaG91bGQgYmUgdXNlZCB0byBtb2RlbCB0aGUgZGFpbHkgc3RvcmFnZSB3YXRlciBkYXRhLg0KDQoNCg0KDQoNClwNCg0KIyMjICoqUHJvYmxlbSBCMyoqOg0KDQpVc2UgdGhlIHByb2NlZHVyZSBhbmQgY29kZSBmcm9tICoqUHJvYmxlbSBCMSoqIHRvIGVzdGltYXRlIHRoZSBNTEVzIG9mICRhJCBhbmQgJGIkLCBhbmQgdGhlbiBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIGFuYWx5c2VzOg0KDQooMSkuIE9idGFpbiB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgJFxoYXR7YX0kIGFuZCAkXGhhdHtifSQgYW5kIHBsb3QgZWFjaCBkaXN0cmlidXRpb24gdXNpbmcgKipHYXVzc2lhbiBrZXJuZWwgZGVuc2l0eSBjdXJ2ZXMqKi4NCg0KYGBge3J9DQoNCiNCb290c3RyYXAgTUxFIGZvciBhIGFuZCBiDQoNCkI9OTk5OQ0KYm9vdF9hID0gbnVtZXJpYyhCKSAjYWxsb3dzIG51bWJlciBvZiBib290c3RyYXBzIGZvciBhDQpib290X2IgPSBudW1lcmljKEIpICNhbGxvd3MgbnVtYmVyIG9mIGJvb3RzdHJhcHMgZm9yIGINCm49bGVuZ3RoKHN0b3JhZ2UpDQoNCnNldC5zZWVkKDEyMykNCg0KZm9yKGkgaW4gMTpCKSAjYmVnaW4gYm9vdHN0cmFwIHRvIGZpbmQgbWxlIGEgYW5kIGINCnsNCiAgDQpib290X3NhbXBsZT0gc2FtcGxlKHN0b3JhZ2UsIHNpemU9biwgcmVwbGFjZT0gVFJVRSApICAjcmVzYW1wbGUgd2l0aCByZXBsYWNlbWVudA0KICANCiNFc3RpbWF0ZSBNTEVzIGZvciBib290c3RyYXAgc2FtcGxlIA0KICAjdXNpbmcgb3B0aW0gDQoNCmJvb3RfbWxlPSBvcHRpbSgNCiAgICBwYXIgPSBjKG1sZV9hICogcnVuaWYoMSwgMC45LCAxLjEpLCBtbGVfYiAqIHJ1bmlmKDEsIDAuOSwgMS4xKSksICMgSml0dGVyIHN0YXJ0aW5nIHZhbHVlcyAjcGFyID0gYyhtbGVfYSwgbWxlX2IpLCAjIFN0YXJ0IGF0IHRoZSBvcmlnaW5hbCBNTEVzIGZvciBzcGVlZA0KICAgIGZuID0ga3VtYXJfbG9nbGlrLCAgIyBjaGVja3MgaGVpZ2h0IG9mIGxpa2VsaWhvb2Qgc3VyZmFjZQ0KICAgIGdyID0gY29tYmluZWRfa3VtX2dyYWRpZW50LCAgIyBncmFkaWVudCB1cGhpbGwgc2hvdWxkIGJlIHRoZSBjb21iaW5lZCBncmFkaWVudA0KICAgIGRhdGEgPSBib290X3NhbXBsZSwNCiAgICBtZXRob2QgPSAiTC1CRkdTLUIiLCAjY29udHJhaW50cyBib3gNCiAgICBsb3dlciA9IGMoMWUtNSwgMWUtNSkgIyBrZWVwcyB0aGUgcGFyYW1ldGVycyBwb3NpdGl2ZSAjd291bGQgcmVtb3ZlIGNvbnRyb2wgaWYgdGhpcyB3YXMgaW4gdGhlIGNvZGUNCiAgDQopDQpib290X2FbaV0gPC0gYm9vdF9tbGUkcGFyWzFdICNvdXRwdXQgYSBNTEUgcGFyYW1ldGVyDQpib290X2JbaV0gPC0gYm9vdF9tbGUkcGFyWzJdICNvdXRwdXQgYiBNTEUgcGFyYW1ldGVyDQoNCn0NCg0KDQojZ2F1c3NpYW4ga2VybmVsIGJ1aWxkaW5nIGZvciBhIGhhdA0KcGxvdChkZW5zaXR5KGJvb3RfYSwga2VybmVsPSAiZ2F1c3NpYW4iKSwgbWFpbiA9ICJCb290c3RyYXAgRGlzdHJ1YnV0aW9uIG9mIGEgaGF0IiwNCiAgICAgeGxhYj0iYSBoYXQiLCBjb2w9ICJza3libHVlIiwgbHdkPTIpDQphYmxpbmUodj0gbWxlX2EsIGNvbD0gInJlZCIsIGx0eT0yKSNyZWZlcmVuY2UgZm9yIG9yaWdpbmFsIE1MRQ0KDQojZ2F1c3NpYW4ga2VybmVsIGRlbnNpdHkgZm9yIGIgaGF0DQoNCnBsb3QoZGVuc2l0eShib290X2IsIGtlcm5lbCA9ICJnYXVzc2lhbiIpLCBtYWluPSJCb290c3RyYXAgRGlzdHJ1YnV0aW9uIG9mIGIgaGF0IiwNCiAgICAgeGxhYj0gImIgaGF0IiwgY29sPSAiZGFya2dyZWVuIiwgbHdkPTIpDQphYmxpbmUodiA9IG1sZV9iLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCg0KYGBgDQoNClRoZSBib290c3RyYXBwZWQgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgaXMgYHIgYm9vdF9hW2ldYC4gVGhlIGJvb3RzdHJhcHBlZCBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYiBpcyBgciBib290X2JbaV1gLg0KDQoNCigyKS4gIENvbnN0cnVjdCBib3RoIHRoZSAkOTVcJSQgKipib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbCoqIGFuZCB0aGUgKipXYWxkIGNvbmZpZGVuY2UgaW50ZXJ2YWwqKiBmb3IgJGIkLiBEbyB0aGVzZSBpbnRlcnZhbHMgYWdyZWUgd2l0aCB0aGUgcmVzdWx0cyBvYnRhaW5lZCBpbiAqKlByb2JsZW0gQjIqKj8gWypDb21wdXRlIHRoZSBzdGFuZGFyZCBlcnJvciBvZiAkXGhhdHtifSQgdXNpbmcgdGhlIG9ic2VydmVkIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXgsIGkuZS4sIHRoZSBpbnZlcnNlIG9mIHRoZSBuZWdhdGl2ZSBIZXNzaWFuIG9idGFpbmVkIGZyb20gb3B0aW0oKSpdDQoNCldhbGQgRXF1YXRpb24NCiQkDQpcaGF0e2J9ICsgel97XGFscGhhLzJ9ICogXHNxcnQoW0lfbihcaGF0e2J9XV97MiwyfSkpDQokJA0KDQoNCmBgYHtyfQ0KDQojIyBCb290c3RyYXBwZWQgQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KI2Jvb3RfY2lfYT0gcXVhbnRpbGUoYm9vdF9hLCBwcm9icz0gYygwLjAyNSwgMC45NzUpKQ0KI2Jvb3RfY2lfYiA9IHF1YW50aWxlKGJvb3RfYiwgcHJvYnM9IGMoMC4wMjUsIDAuOTc1KSkNCg0KI2NhdCgiVGhlIGJvb3RzdHJhcHBlZCBjb25maWRlbmNlIGludGVydmFsIikNCg0KI0Jvb3RzdHJhcHBlZCBOb3JtYWwgQ29uZmlkZW5jZSBJbnRlcnZhbA0KDQphbHBoYSA8LSAwLjA1DQp6X2NyaXRpY2FsIDwtIHFub3JtKDEgLSBhbHBoYS8yKQ0KZGlzX2NyaXRfY2FsPWJvb3RfYSArIHpfY3JpdGljYWwgKiAoYm9vdF9hL3NxcnQobikpDQoNCiMgQ2FsY3VsYXRlIEJvb3RzdHJhcCBTdGFuZGFyZCBFcnJvciAoc2VfYm9vdCkNCnNlX2Jvb3RfYSA9IHNkKGJvb3RfYSkNCnNlX2Jvb3RfYiA9IHNkKGJvb3RfYikNCg0KIyBaIGNyaXRpY2FsIHZhbHVlIGZvciA5NSUNCg0Kej0gcW5vcm0oMC45NzUpDQoNCiNDb25maWRlbmNlIGxldmVsIGZvciBwYXJhbWV0ZXIgYQ0KY2lfYm9vdF9hID0gYyhMQ0k9IG1sZV9hIC0geipzZV9ib290X2EsICAjbG93ZXIgY29uZmlkZW5jZSBsZXZlbA0KICAgICAgICAgICAgICAjZXN0aW1hdGU9IG1sZV9hLCAjdGhlIHZhbHVlIHRoZSBDSSBpcyBjZW50ZXJlZCBhcm91bmQNCiAgICAgICAgICAgICAgVUNMPSBtbGVfYSArIHoqc2VfYm9vdF9hICN1cHBlciBjb25maWRlbmNlIGxldmVsDQogICAgICAgICAgICAgICkNCmNhdCgiVGhlIGJvb3RzdHJhcGVkIG5vcm1hbCBjb25maWRlbmNlIGludGVydmFsIGZvciBwYXJhbWV0ZXIgYT0iLCBtbGVfYSwgImlzLCBbIiwgY2lfYm9vdF9hLCAiXS4iKQ0KDQpjaV9ib290X2IgPSBjKExDST0gbWxlX2IgLSB6KnNlX2Jvb3RfYiwgICNsb3dlciBjb25maWRlbmNlIGxldmVsDQogICAgICAgICAgICAgICNlc3RpbWF0ZT0gbWxlX2IsICN0aGUgdmFsdWUgdGhlIENJIGlzIGNlbnRlcmVkIGFyb3VuZA0KICAgICAgICAgICAgICBVQ0w9IG1sZV9iICsgeipzZV9ib290X2IgI3VwcGVyIGNvbmZpZGVuY2UgbGV2ZWwNCiAgICAgICAgICAgICAgKQ0KY2F0KCJcbiBUaGUgYm9vdHN0cmFwZWQgbm9ybWFsIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHBhcmFtZXRlciBiPSIsIG1sZV9iLCAiaXMsIFsiLCBjaV9ib290X2IsICJdLiIpDQoNCg0KI1BlcmNlbnRpbGUgQ0kgQm9vb3RzdHJhcHMNCmJvb3RfcGVyY2VudGlsZV9hID0gYXMubnVtZXJpYyhxdWFudGlsZShib290X2EsIHByb2JzPSBjKDAuMDI1LCAwLjk3NSkpKQ0KYm9vdF9wZXJjZW50aWxlX2IgPSBhcy5udW1lcmljKHF1YW50aWxlKGJvb3RfYiwgcHJvYnM9IGMoMC4wMjUsIDAuOTc1KSkpDQoNCmNhdCgiXG4gVGhlIGJvb3RzdHJhcHBlZCBwZXJjZW50aWxlIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciBwYXJhbWV0ZXIgYT0gaXMsIFsiLCBib290X3BlcmNlbnRpbGVfYSwgIl0uIikNCg0KY2F0KCJcbiBUaGUgYm9vdHN0cmFwZWQgcGVyY2VudGlsZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgcGFyYW1ldGVyIGIgaXMsIFsiLCBib290X3BlcmNlbnRpbGVfYiwgIl0uIikNCg0KDQojIyMjIyMjIyMjI1dhbGQgQ0kgDQojQ29tcHV0ZSB0aGUgV2FsZCBDSSB1c2luZyBvYnNlcnZlZCBGaXNoZXIgaW5mb3JtYXRpb24NCg0KDQoNCmZpc2hlcl9pbmZvPSBzb2x2ZShtbGUucmVzdWx0JGhlc3NpYW4pICN0YWtlIHRoZSBpbnZlcnNlIG9mIHRoZSBtbGUucmVzdWx0IG1hdHJpeA0KI2hhdmUgdmFsdWVzIGJlZm9yZSB0aGlzIG1hdHJpeCBpbiB0aGUgZXF1YXRpbm4gYXMgd2VsbCBhcyB3ZSBkZXNjcmliZSBzb21lIG9mIHRoZSBmb3JtdWxhIGJlbG93DQogICN2YXJpYW5jZShUaGV0YTEpICAgICNjb3ZhcmlhbmNlKFRoZXRhMSwgVGhldGEyKQ0KICAjY292KFRoZXRhMSwgVGhldGEyKSAjIHZhcmlhbmNlKHRoZXRhMikNCiNpbnNpZGUgdGhlIGhlc3NpYW4gbWF0cml4IGZvciB3YWxkIHdoaWNoIGlzIHRoZSBpbnZlcnNlIG9mIHRoZSBmaXNoZXIgbWF0cml4ICAqIHRoZSBtYXRyaXggb2YgaGF0XHRoZXRhMSAtIGludmVyc2UgdGhldGExMCAob24gdG9wIG9mKSBoYXRcdGhldGEyIC0gdGhldGEyMA0KDQojdGhlIGludmVyc2Ugb2YNCiAgI3ZhcmlhbmNlKGhhdFxhKSAgICAjY292YXJpYW5jZShcaGF0XGEsIFxoYXRcYikgDQogICNjb3YoXGhhdFxhLCBcaGF0XGIpICMgdmFyaWFuY2UoXGhhdFxhKQ0KDQojd2UgYXJlIG9ubHkgdGhlIGIgcGFyYW1ldGVyDQoNCiNjYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGVycm9yIHNwZWNpZmljIHRvIHdhbGQgYg0Kc2Vfd2FsZF9iID0gc3FydChmaXNoZXJfaW5mb1syLDJdKSAjc3RhbmRhcmQgZXJyb3Igd2FsZA0KDQp6PSBxbm9ybSgwLjk3NSkNCndhbGRfY2lfYiA9IGMoTENJPSBtbGVfYi0geipzZV93YWxkX2IsIFVDTD0gbWxlX2IgKyB6KnNlX3dhbGRfYikNCg0KY2F0KCJcbiBUaGUgV2FsZCBDb25maWRlbmNlIEludGVydmFsIGZvciBiIGlzIFsiLCB3YWxkX2NpX2IsICJdLiIpDQpgYGANCldlIGFyZSBjb21wYXJpbmcgdGhlIFdhbGQgQ29uZmlkZW5jZSBpbnRlcnZhbCB0byBhIGJvb3RzdHJhcCBzYW1wbGluZyBjb25maWRlbmNlIGludGVydmFsLiBUbyBiZXR0ZXIgY2FwdHVyZSB0aGUgc2tld25lc3Mgb2YgdGhpcyBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gd2UgY29tcGFyZSB0aGUgYm9vdHN0cmFwcGVkIFBlcmNlbnRpbGUgQ29uZmlkZW5jZSBJbnRlcnZhbCB0byB0aGUgV2FsZCBDb25maWRlbmNlIEludGVydmFsLiBUaGUgUGVyY2VudGlsZSA5NSVDSSBmb3IgcGFyYW1ldGVyIGIgaXMgW2ByIGJvb3RfcGVyY2VudGlsZV9iYF0gKHdpZHRoID0gIDAuMzc4MTgxKSAuIFRoZSBXYWxkIENvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgW2ByIHdhbGRfY2lfYmBdICh3aWR0aD0gMS4xMDgyNjQpLiBUaGUgYm9vdHN0cmFwcGVkIHBlcmNlbnRpbGUgQ0kgaGFzIGEgZmFyIHNtYWxsZXIgaW50ZXJ2YWwgdGhhbiB0aGUgV2FsZCBDb25maWRlbmNlIGludGVydmFsIHN1Z2dlc3RpbmcgdGhlIFdhbGQgdGVzdCBpcyBub3QgdGhlIGJlc3QgdGVzdCB0byB1c2Ugb24gdGhlIGRpc3RyaWJ1dGlvbiBhcyBpdCBhc3N1bWVzIGEgbm9ybWFsIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgd2hpY2ggaXMgYmVzdCBzdWl0ZWQgaGVyZS4gVGhlIFdhbGQgOTUlQ0kgaXMgdW5kZXJwZXJmb3JtaW5nIHRoZSBib290c3RyYXBwZWQgTm9ybWFsIDk1JUNJIGFzIHdlbGwgW2ByIGNpX2Jvb3RfYmBdLiBPdXIgZGVzaXJlIGlzIHRvIGhhdmUgYSBzbWFsbCBjb25maWRlbmNlIGludGVydmFsIGFzIGxvbmcgYXMgdGhlIGRpc3RyaWJ1dGlvbiBpcyB3ZWxsIHJlcHJlc2VudGVkIGJ5IHRoZSBpbnRlcnZhbCB1c2VkLg0KDQoNCkluIFByb2JsZW0gQjIsIHdlIHJlamVjdGVkIHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGUgc2ltcGxlciBtb2RlbCBzdWl0cyB0aGUgZGlzdHJpYnV0aW9uLCBjb25jbHVkaW5nIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gYmV0dGVyIG1vZGVscyB0aGUgZGFpbHkgc3RvcmFnZSB3YXRlciBkYXRhLiBDb25zaWRlcmluZyB0aGlzIG1vcmUgY29tcGxleCBtb2RlbCwgbW9zdCBsaWtlbHkgaGFzIG1vcmUgY29tcGxleCBkaXN0cmlidXRpb24gc2hhcGUgdGhhdCBpcyBub3Qgd2VsbCByZXByZXNlbnRlZCBieSBhIG5vcm1hbCBkaXN0cmlidXRpb24gZXZlbiB3aGVuIG92ZXJjb21pbmcgZm9yIHNvbWUgcm9idXN0bmVzcywgdGhlIGJldHRlciBzdWl0ZWQgYm9vdHN0cmFwcGVkIHBlcmNlbnRpbGUgY2kgYWdyZWVzIHdpdGggdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGRhdGFzZXQuIA0KDQogDQoNCg0KKDMpLiBCYXNlZCBvbiB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgZnJvbSBwYXJ0ICgxKSBvZiB0aGlzIHByb2JsZW0sIGFzc2VzcyB3aGV0aGVyIHRoZSB2YWxpZGl0eSBvZiB0aGUgV2FsZCBjb25maWRlbmNlIGludGVydmFsIGlzIHN1cHBvcnRlZC4NCg0KDQpXaGlsZSB0aGUgYm9vdHN0cmFwcGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGRvIG5vdCBpbmNsdWRlIDAsIHdlIGNhbiBhc3N1bWUgb3VyIHBhcmFtZXRlcnMgYSBhbmQgYiBoYXMgc2lnbmlmaWNhbmNlLiBUaGUgYm9vdHN0cmFwIGtlcm5lbCBmaWd1cmUgZm9yICRcaGF0e2F9JCByYW5nZSBhYm91dCBmcm9tIDAuODMtMS4xMCB3aXRoIGEgTUxFIHZhbHVlIG9mIGByIGJvb3RfYVtpXWAuIFRoZSBib290c3RyYXAga2VybmVsIGZpZ3VyZSBmb3IgJFxoYXR7Yn0kIHJhbmdlcyBmcm9tIGFib3V0IDEuOCB0byAyLjIgd2l0aCBhbiBNTEUgdmFsdWUgb2YgYHIgYm9vdF9iW2ldYC4gQXMgdGhlIFdhbGQgY29uZmlkZW5jZSBpbnRlcnZhbCBbYHIgd2FsZF9jaV9iYF0gIGlzIGJldHdlZW4ga2VybmVsJ3MgcmFuZ2VzIGZvciB0aGUgZW50aXJlIGVuY29tcGFzc2luZyBkYXRhc2V0IHRoZXJlZm9yZSBjYXB0dXJpbmcgYW4gaW50ZXJ2YWwgd2l0aGluIGEgcGxhdXNpYmxlIHJhbmdlIGFsdGhvdWdoIGl0IGlzIHdheSBsZXNzIHZhbGlkIHRoYW4gaXRzIGJvb3RzdHJhcHBlZCBwZXJjZW50aWxlIENvbmZpZGVuY2UgSW50ZXJ2YWwuQSBwZXJjZW50aWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgcHJlZmVycmVkIGZvciB0aGUgc3RvcmFnZSBkaXN0cmlidXRpb24uIA0KVGhlIFdhbGQgQ0kgYXNzdW1wdGlvbiBmb3Igbm9ybWFsaXR5IGFuZCBzeW1tZXRyeSBjYW5ub3Qgd2VsbCBjYXB0dXJlIHRoZSB0cnVlIHNoYXBlIG9mIHRoZSBkaXN0cmlidXRpb24uIEFzIHRoZSBkaXN0cmlidXRpb24gYXBwZWFycyB0byBoYXZlIHNvbWUgdW5pbW9kYWwgc2hhcGUgYW5kIHNsaWdodCB0YWlsLCByYXRoZXIgdGhhbiBhIHN0cm9uZyBzeW1tZXRyaWNhbCBzaGFwZSBjZW50ZXJlZCBhcm91bmQgaXRzIE1MRS4gVGhlIHdpZGVyIFdhbGQgY29uZmlkZW5jZSBpbnRlcnZhbCBoaWdobGlnaHRzIGl0cyB1bmNlcnRpYW55IHRvIG1lYXN1cmUgZGV2aWF0aW9ucyBmcm9tIG5vcm1hbCBzaGFwZSB3ZWxsLg0KDQpcDQoNCiMjIyAqKlByb2JsZW0gQjQqKjoNCg0KSW4gdGhlIGludHJvZHVjdGlvbiB0byB0aGUgd29ya2luZyBtb2RlbCBmb3IgdGhpcyBleGFtLCB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIHJlZHVjZXMgdG8gdGhlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIG9uICgwLDEpLiBJbiB0aGlzIHByb2JsZW0sIHdlIHBlcmZvcm0gYSAqKmxpa2VsaWhvb2QgcmF0aW8gdGVzdCoqIGZvciB0aGUgZm9sbG93aW5nIGh5cG90aGVzaXMgdG8gYXNzZXNzIHdoZXRoZXIgdGhlIGRhdGEgY29tZSBmcm9tIHRoZSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBvbiAoMCwxKToNCg0KJCQNCkhfMDogYSA9IDFccXVhZCBcJiBccXVhZCBiID0gMVxxdWFkIFx0ZXh0eyB2ZXJzdXMgfSBccXVhZCBIX2E6IGEgXG5lIDEgXHF1YWQgXHRleHR7b3J9IFxxdWFkIGIgXG5lIDEgXHF1YWQgXHRleHR7b3J9XHF1YWQgKGEgXG5lIDEgXHF1YWQgXCYgXHF1YWQgYiBcbmUgMSkuDQokJA0KDQpQcm92aWRlIGEgcHJhY3RpY2FsIGludGVycHJldGF0aW9uIG9mIHRoZSBhYm92ZSB0ZXN0IHJlc3VsdC4gWypIaW50OiAkSF9hJCBiYXNpY2FsbHkgc2F5cyB0aGF0IHRoZXJlIGlzIG5vIGNvbnN0cmFpbnRzIGZvciAkYSQgYW5kICRiJC4gUGxlYXNlIHJldmlldyB0aGUgbGVjdHVyZSBub3RlIGZvciBtb2R1bGUgMTEgIG9uIHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgYmVmb3JlIGNvZGluZy4qXQ0KDQpcDQoNCkhlcmUgd2UgY29tcGFyZSB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIHRvIGFub3RoZXIgc3BlY2lhbCBjYXNlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIG1vZGVsIHdoZXJlIHRoZSBkaXN0cmlidXRpb24gcmFuZ2VzIGJldHdlZW4gMCBhbmQgMS4gIA0KDQokJA0KTFJUX3t1bmkoMSwxKX09IDJbXGVsbChcaGF0e2F9LCBcaGF0e2J9KS1cZWxsKDEsMSldDQokJA0KDQpgYGB7cn0NCm49IGxlbmd0aChzdG9yYWdlKQ0KDQojdW5yZXN0cmljdGVkIG9yaWdpbmFsIGxvZyBsaWtlbGlob29kIGZyb20ga3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uDQoNCmxvZ0xfdW5yZXN0cmljdGVkID0gLWt1bWFyX2xvZ2xpayhjKG1sZV9hLCBtbGVfYiksIHN0b3JhZ2UpICNwcmVzZW50cyBqb2ludCBwcm9iYWJpbGl0eSBvZiBlbnRpcmUgZGF0YXNldCBnaXZlIGEgYW5kIGIgcGFyYW1ldGVycw0KDQojbG9nIGxpa2VsaWhvb2QgZm9yIFVuaWZvcm0gKGE9MSwgYj0xKQ0KbG9nTF9yZXN0cmljdGVkPSAta3VtYXJfbG9nbGlrKGMoMSwxKSwgc3RvcmFnZSkgI3RoZSBwYXJhbWV0ZXJzIGZvciAxIGFuZCAxIGZvciBib3RoICBhIGFuZCBiDQoNCiNsb2cgcmF0aW8gdGVzdCBzdGF0aXN0aWMNCg0KTFJUX3N0YXRfdW5pY29tcGFyaXNvbiA9IDIgKiAobG9nTF91bnJlc3RyaWN0ZWQgLSBsb2dMX3Jlc3RyaWN0ZWQpIA0KDQpwdmFsX3VuaWNvbXBMUlQ9IDEtIHBjaGlzcShMUlRfc3RhdF91bmljb21wYXJpc29uLCBkZj0yKQ0KDQpjYXQoIlRoZSBsb2cgbGlrZWxpaG9vZCByYXRpbyBjb25zaWRlcmluZyB0aGUgc3BlY2lhbCBjYXNlIGt1bWFzd2FteSB1bmlmb3JtIGRpc3RydWJ1dGlvIChhPTEsIGI9MSkgaXMiLCBMUlRfc3RhdF91bmljb21wYXJpc29uLCAiKHA9IiwgcHZhbF91bmljb21wTFJULCAiKS4iKQ0KDQpgYGANCldoZW4gYXNzZXNzaW5nIHRoZSBzdHJvbmdlciBtb2RlbCB1c2luZyB0aGUgTGlrZWxpaG9vZCBSYXRpbyBUZXN0LCB0aGUgbW9yZSBjb21wbGV4IEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiBkb2VzIGEgYmV0dGVyIGpvYiBhdCBtb2RlbGxpbmcgdGhlIHdhdGVyIHN0b3JhZ2UgZGlzdHJpYnV0aW9uIHRoYW4gdGhlIHVuaWZvcm0gbW9kZWwuIElmIGNvbXBhcmluZyB3aGV0aGVyIHRvIHVzZSB0aGUgcmVzdHJpY3RlZCB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBvciB0aGUgdW5yZXN0cmljdGVkIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiwgdXNlIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gKExSVD0gYHIgTFJUX3N0YXRfdW5pY29tcGFyaXNvbmAsIHA9IGByIHB2YWxfdW5pY29tcExSVGApLiBQZXJoYXBzIHRoZSBzbGlnaHQgcmlnaHQgc2tld25lc3Mgb2YgdGhlIG1vZGVsIGlzIG5vdCB3ZWxsIHJlcHJlc2VudGVkIGJ5IHRoZSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBzdWdnZXN0aW5nIGRhaWx5IHdhdGVyIGludGFrZSBpcyBub3QgZXZlbmx5IGRpc3RyaWJ1dGVkIG5vciByYW5kb20uDQoNCg0KSXQgYXBwZWFycyBib3RoIHRoZSBLdW1hcmFzd2FteSBvdXRwZXJmb3JtcyB0aGUgdW5pZm9ybSBhbmQgcG93ZXIgZGlzdHJpYnV0aW9uIG1vZGVscy4gDQoNCjxmb250IGNvbG9yID0gInJlZCI+KipOb3RlKio6IFBsZWFzZSBkb3dubG9hZCB0aGUgdGVtcGxhdGUgYW5kIGluc2VydCB5b3VyIHdvcmsgaW50byBpdCB0byBjb21wbGV0ZSB0aGUgZXhhbS4gPC9mb250Pg0KDQoNCg0KDQo=