Final Exam Guidelines

  • Coverage: The major concepts and inference procedures—such as sampling distributions, confidence intervals, and hypothesis testing—are covered and implemented using both classical parametric likelihood-based methods and modern non-parametric approaches, including the bootstrap and kernel density estimation.

  • Part A requires derivation of selected likelihood-based functions for performing various types of inference, with sufficient detail to enable translation of these derivations into code for numerical analysis.

  • Your code for the problems in Part B must align with your derivations in Part A and be well commented where necessary.

  • In Part B, all numerical results must be interpreted from a practical perspective.


Policies of Using AI Tools

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

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


Working Model for the Final Exam

Caution: Please follow the suggested expressions and guided steps to complete the exam. Other approaches such as transformation for trivialize the problems that will not meet the exam objectives.

The Kumaraswamy distribution is a two-parameter continuous probability distribution defined on the interval (0, 1). It is often used as an alternative to the Beta distribution due to its simple closed-form expressions for the cumulative distribution function (CDF) and quantile function. It is commonly used in

  • Hydrology: Modeling rainfall, streamflow, or other bounded natural phenomena

  • Economics: Income shares, proportions, or bounded indices

  • Monte Carlo simulation: Efficient random variate generation (via inverse transform)

  • Machine learning: Output layer for bounded targets, prior distributions in Bayesian models

  • Reliability engineering: Modeling failure rates of systems with bounded lifetimes


Let \(X\) be the Kumaraswamy random variable with Cumulative Distribution Function (CDF)

\[ F(x; a, b) = 1 - (1 - x^a)^b \]

where \(a > 0\) and \(b > 0\) unknown parameters and \(0 < x < 1\).

The following are two special case of the Kumaraswamy distribution:

  1. Uniform Distribution: When \(a = 1\) and \(b = 1\), the Kumaraswamy distribution becomes a uniform distribution over \([0, 1]\) with CDF \(F(x) = x\).

  2. Power Distribution: when \(b = 1\) and \(a > 0\), the Kumaraswamy distribution becomes a power distribution over \([0, 1]\) with CDF \(F(x) = x^a\).

This final exam focuses on inferences of Kumaraswamy distribution and related data analysis.

Part A: Methodological Derivations


Show that the density function of the Kumaraswamy distribution is

\[ f(x; a, b) = ab \, x^{a-1} (1 - x^a)^{b-1}. \]

Given the cumulative distribution function (CDF): \[ F(x; a,b) = 1 - (1 - x^a)^b \]

Differentiate with respect to (x): \[ f(x; a,b) = \frac{d}{dx}F(x) \] Applying the chain rule:

\[ f(x) = b(1 - x^a)^{b-1} \cdot ax^{a-1} \] \[ f(x) = ab , x^{a-1}(1 - x^a)^{b-1} \]

\[ f(x; a,b) = ab \cdot 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 aove 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\).

Given a sample (x_1, …, x_n), the likelihood is:

\[ L(a,b) = \prod_{i=1}^n ab , x_i^{a-1}(1 - x_i^a)^{b-1} \]

Taking logs:

\[ \ell(a,b) = n\log a + n\log b + (a-1)\sum \log x_i + (b-1)\sum \log(1 - x_i^a) \]

Gradient with respect to (a):

\[ \frac{\partial \ell}{\partial a} = \frac{n}{a} + \sum \log x_i - (b-1)\sum \frac{x_i^a \log x_i}{1 - x_i^a} \]

Gradient with respect to (b):

\[ \frac{\partial \ell}{\partial b} = \frac{n}{b} + \sum \log(1 - x_i^a) \] ————————————————————————


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).

The observed Fisher information is defined as:

\[ \mathcal{I}(a,b) = - \nabla^2 \ell(a,b) \]

The second derivatives are:

\[ \frac{\partial^2 \ell}{\partial a^2} = -\frac{n}{a^2} \]

\[ \frac{\partial^2 \ell}{\partial b^2} = -\frac{n}{b^2} \]

\[ \frac{\partial^2 \ell}{\partial a \partial b} = \sum \frac{-x_i^a \log x_i}{1-x_i^a} \]



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.]

CDF: \[ f(x)=x^a \]

PDF: \[ f(x; a,1) = a x^{a-1} \]

MLE of : \[ \hat{a} = -\frac{n}{\sum \log x_i} \]

Method of Moments of : \[ \boxed{\hat{a}_{MM} = \frac{\bar{x}}{1-\bar{x}}} \] ————————————————————————

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.]

For the power distribution, the log-likelihood is

\[ \ell(a)=n\log(a)+(a-1)\sum_{i=1}^n\log(x_i). \]

The second derivative is

\[ \ell''(a)=-\frac{n}{a^2}. \]

Therefore, the Fisher information is

\[ I(a)=-\ell''(a)=\frac{n}{a^2}. \]

The estimated variance of \(\hat a\) is the reciprocal of the observed Fisher information evaluated at \(\hat a\):

\[ {Var}(\hat a)=\frac{ a^2}{n}. \]

Thus, the estimated standard error is

\[ SE(\hat a)=\frac{\hat a}{\sqrt n}. \]

The 95% Wald confidence interval for \(a\) is

\[ \boxed{\hat a \pm 1.96\frac{\hat a}{\sqrt n}}. \] ————————————————————————


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.]

The parameter (a) controls behavior near 0, while (b) controls behavior near 1. Together, they determine the skewness and shape of the distribution over ([0,1]).

We test

\[ H_0:a=1 \qquad \text{versus} \qquad H_a:a\ne 1. \]

For the power distribution, the likelihood ratio test statistic is

\[ G^2=2\left[\ell(\hat a)-\ell(a_0)\right], \]

where \(a_0=1\). Under \(H_0\), the asymptotic reference distribution is

\[ G^2 \sim \chi^2_1. \]

The decision rule at \(\alpha=0.05\) is to reject \(H_0\) if

\[ \boxed{G^2>\chi^2_{0.95,1}}. \]


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.

# Dataset
x <- 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)

# Sample size
n <- length(x)

# Negative log-likelihood for Kumaraswamy distribution
loglik_kumar <- function(par) {
  
  # Extract parameters numerically
  a <- as.numeric(par[1])
  b <- as.numeric(par[2])
  
  # Parameter restrictions
  if (a <= 0 || b <= 0) {
    return(Inf)
  }
  
  # Log-likelihood
  ll <- n * log(a) +
        n * log(b) +
        (a - 1) * sum(log(x)) +
        (b - 1) * sum(log(1 - x^a))
  
  # Return negative log-likelihood for minimization
  return(-ll)
}

# Optimize
fit <- optim(
  par = c(1, 1),
  fn = loglik_kumar,
  hessian = TRUE
)

# MLEs
a_hat <- fit$par[1]
b_hat <- fit$par[2]

# Output
a_hat
[1] 2.529599
b_hat
[1] 7.883367


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 ar significance level \(\alpha = 0.05\):

\[ H_0: b = 1 \quad \text{ versus } \quad H_a: b \ne 1. \]

State the statistical decision clearly. What is the practical implication of the testing result?

# Step 1: Fit power distribution (restricted model)
a_hat_power <- -n / sum(log(x))

# Step 2: Log-likelihoods
ll_full <- -fit$value

ll_restricted <- n*log(a_hat_power) +
                 (a_hat_power - 1)*sum(log(x))

# Step 3: LRT statistic
LRT <- 2 * (ll_full - ll_restricted)
p_value <- 1 - pchisq(LRT, df = 1)

cat("B2 Results:\n")
B2 Results:
cat("LRT statistic =", LRT, "\n")
LRT statistic = 48.92533 
cat("p-value =", p_value, "\n")
p-value = 2.658984e-12 
if (p_value < 0.05) {
  cat("Decision: Reject H0 (b ≠ 1)\n\n")
} else {
  cat("Decision: Fail to reject H0 (b = 1 is adequate)\n\n")
}
Decision: Reject H0 (b ≠ 1)


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.

set.seed(123)
B <- 1000

a_boot <- numeric(B)
b_boot <- numeric(B)

for (i in 1:B) {
  
  # Resample with replacement
  xb <- sample(x, size = n, replace = TRUE)
  
  # Define log-likelihood for bootstrap sample
  loglik_boot <- function(par) {
    a <- par[1]
    b <- par[2]
    
    if (a <= 0 || b <= 0) return(Inf)
    
    ll <- length(xb)*log(a) + length(xb)*log(b) +
          (a - 1)*sum(log(xb)) +
          (b - 1)*sum(log(1 - xb^a))
    
    return(-ll)
  }
  
  fit_b <- optim(c(a_hat, b_hat), loglik_boot)
  
  a_boot[i] <- fit_b$par[1]
  b_boot[i] <- fit_b$par[2]
}

# Plot densities
plot(density(a_boot), main = "Bootstrap Density of a_hat")

plot(density(b_boot), main = "Bootstrap Density of b_hat")

(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()]

# Bootstrap percentile CI
boot_ci_b <- quantile(b_boot, c(0.025, 0.975))

# Wald CI using Hessian
H <- fit$hessian
vcov_matrix <- solve(H)

se_b <- sqrt(vcov_matrix[2,2])

wald_ci_b <- c(b_hat - 1.96*se_b,
               b_hat + 1.96*se_b)

cat("B3 Results:\n")
B3 Results:
cat("Bootstrap CI for b:\n")
Bootstrap CI for b:
print(boot_ci_b)
     2.5%     97.5% 
 5.127115 16.304358 
cat("\nWald CI for b:\n")

Wald CI for b:
print(wald_ci_b)
[1]  3.483944 12.282791

(3). Based on the bootstrap sampling distributions from part (1) of this problem, assess whether the validity of the Wald confidence interval is supported.

plot(density(b_boot),
     main = "Bootstrap Distribution of b_hat")
abline(v = wald_ci_b, col = "red", lty = 2)
abline(v = 1, col = "blue", lty = 2)

legend("topright",
       legend = c("Wald CI", "b = 1"),
       col = c("red", "blue"),
       lty = 2)


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.]


# Likelihood under the null hypothesis: degenerate at 1
likelihood_null <- function(data) {
  if(all(data == 1)) {
    return(1)
  } else {
    return(0)
  }
}

# Likelihood under the alternative hypothesis: uniform on observed range
likelihood_alt <- function(data) {
  a_hat <- min(data)
  b_hat <- max(data)
  n <- length(data)
  
  # Check if data are within [a_hat, b_hat]
  if(any(data < a_hat) || any(data > b_hat)) {
    return(0)
  }
  
  # Likelihood for uniform distribution
  likelihood <- (1 / (b_hat - a_hat))^n
  return(likelihood)
}

# Calculate likelihoods
L_null <- likelihood_null(x)
L_alt <- likelihood_alt(x)

# Calculate likelihood ratio
if(L_null == 0) {
  LRT <- Inf  # Data incompatible with null
} else {
  LRT <- L_alt / L_null
}

# Output the results
cat("Likelihood under null (degenerate at 1):", L_null, "\n")
Likelihood under null (degenerate at 1): 0 
cat("Likelihood under alternative:", L_alt, "\n")
Likelihood under alternative: 1053909266 
cat("Likelihood Ratio (LRT):", LRT, "\n")
Likelihood Ratio (LRT): Inf 

Since the data clearly are not all 1, the likelihood under the null will be zero, making the likelihood ratio tend to infinity or undefined. This indicates strong evidence against the null hypothesis that the reservoir is always full.**

Note: Please download the template and insert your work into it to complete the exam.

LS0tDQp0aXRsZTogIlNUQSA1MDYgRmluYWwgRXhhbWluYXRpb24iDQphdXRob3I6ICJLaWVyYW4gSGVmZmVyYW4iDQpkYXRlOiAnTWF5IDUsIDIwMjYgJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQogIHdvcmRfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA3Mg0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCg0KXA0KDQojIyAqKkZpbmFsIEV4YW0gR3VpZGVsaW5lcyoqDQoNCi0gICAqKkNvdmVyYWdlKio6IFRoZSBtYWpvciBjb25jZXB0cyBhbmQgaW5mZXJlbmNlIHByb2NlZHVyZXPigJRzdWNoIGFzDQogICAgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucywgY29uZmlkZW5jZSBpbnRlcnZhbHMsIGFuZCBoeXBvdGhlc2lzDQogICAgdGVzdGluZ+KAlGFyZSBjb3ZlcmVkIGFuZCBpbXBsZW1lbnRlZCB1c2luZyBib3RoIGNsYXNzaWNhbCBwYXJhbWV0cmljDQogICAgbGlrZWxpaG9vZC1iYXNlZCBtZXRob2RzIGFuZCBtb2Rlcm4gbm9uLXBhcmFtZXRyaWMgYXBwcm9hY2hlcywNCiAgICBpbmNsdWRpbmcgdGhlIGJvb3RzdHJhcCBhbmQga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbi4NCg0KLSAgICoqUGFydCBBKiogcmVxdWlyZXMgZGVyaXZhdGlvbiBvZiBzZWxlY3RlZCBsaWtlbGlob29kLWJhc2VkDQogICAgZnVuY3Rpb25zIGZvciBwZXJmb3JtaW5nIHZhcmlvdXMgdHlwZXMgb2YgaW5mZXJlbmNlLCB3aXRoIHN1ZmZpY2llbnQNCiAgICBkZXRhaWwgdG8gZW5hYmxlIHRyYW5zbGF0aW9uIG9mIHRoZXNlIGRlcml2YXRpb25zIGludG8gY29kZSBmb3INCiAgICBudW1lcmljYWwgYW5hbHlzaXMuDQoNCi0gICBZb3VyIGNvZGUgZm9yIHRoZSBwcm9ibGVtcyBpbiAqKlBhcnQgQioqIG11c3QgYWxpZ24gd2l0aCB5b3VyDQogICAgZGVyaXZhdGlvbnMgaW4gKipQYXJ0IEEqKiBhbmQgYmUgd2VsbCBjb21tZW50ZWQgd2hlcmUgbmVjZXNzYXJ5Lg0KDQotICAgSW4gKipQYXJ0IEIqKiwgYWxsIG51bWVyaWNhbCByZXN1bHRzIG11c3QgYmUgaW50ZXJwcmV0ZWQgZnJvbSBhDQogICAgcHJhY3RpY2FsIHBlcnNwZWN0aXZlLg0KDQpcDQoNCiMjICoqUG9saWNpZXMgb2YgVXNpbmcgQUkgVG9vbHMqKg0KDQotICAgKipQb2xpY3kgb24gQUkgVG9vbCBVc2UqKjogU3R1ZGVudHMgbXVzdCBhZGhlcmUgdG8gdGhlIEFJIHRvb2wNCiAgICBwb2xpY3kgc3BlY2lmaWVkIGluIHRoZSBjb3Vyc2Ugc3lsbGFidXMuIFRoZSBkaXJlY3QgY29weWluZyBvZg0KICAgIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0DQogICAgcmVmbGVjdCB5b3VyIG93biB1bmRlcnN0YW5kaW5nOyB3aGVyZSBleHRlcm5hbCB0b29scyBhcmUgY29uc3VsdGVkLA0KICAgIGNvbnRlbnQgbXVzdCBiZSB0aG9yb3VnaGx5IHJlcGhyYXNlZCBhbmQgc3ludGhlc2l6ZWQgaW4geW91ciBvd24NCiAgICB3b3Jkcy4NCg0KLSAgICoqQ29kZSBJbmNsdXNpb24gUmVxdWlyZW1lbnQqKjogQW55IGNvZGUgaW5jbHVkZWQgaW4geW91ciBlc3NheSBtdXN0DQogICAgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dA0KICAgIG9mIGtleSBjb2RlIGxpbmVzLiBTdWJtaXR0aW5nIEFJLWdlbmVyYXRlZCBjb2RlIHdpdGhvdXQgbWVhbmluZ2Z1bCwNCiAgICBzdHVkZW50LWFkZGVkIGNvbW1lbnRzIHdpbGwgbm90IGJlIGFjY2VwdGVkLg0KDQpcDQoNCiMjICoqV29ya2luZyBNb2RlbCBmb3IgdGhlIEZpbmFsIEV4YW0qKg0KDQo8Zm9udCBjb2xvciA9ICJvcmFuZ2UiPioqQ2F1dGlvbioqOiAqUGxlYXNlIGZvbGxvdyB0aGUgc3VnZ2VzdGVkDQpleHByZXNzaW9ucyBhbmQgZ3VpZGVkIHN0ZXBzIHRvIGNvbXBsZXRlIHRoZSBleGFtLiBPdGhlciBhcHByb2FjaGVzIHN1Y2gNCmFzIHRyYW5zZm9ybWF0aW9uIGZvciB0cml2aWFsaXplIHRoZSBwcm9ibGVtcyB0aGF0IHdpbGwgbm90IG1lZXQgdGhlDQpleGFtIG9iamVjdGl2ZXMuKjwvZm9udD4NCg0KVGhlICoqS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uKiogaXMgYSB0d28tcGFyYW1ldGVyIGNvbnRpbnVvdXMNCnByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiBkZWZpbmVkIG9uIHRoZSBpbnRlcnZhbCAoMCwgMSkuIEl0IGlzIG9mdGVuDQp1c2VkIGFzIGFuIGFsdGVybmF0aXZlIHRvIHRoZSBCZXRhIGRpc3RyaWJ1dGlvbiBkdWUgdG8gaXRzIHNpbXBsZQ0KY2xvc2VkLWZvcm0gZXhwcmVzc2lvbnMgZm9yIHRoZSBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiAoQ0RGKQ0KYW5kIHF1YW50aWxlIGZ1bmN0aW9uLiBJdCBpcyBjb21tb25seSB1c2VkIGluDQoNCi0gICAqKkh5ZHJvbG9neSoqOiBNb2RlbGluZyByYWluZmFsbCwgc3RyZWFtZmxvdywgb3Igb3RoZXIgYm91bmRlZA0KICAgIG5hdHVyYWwgcGhlbm9tZW5hDQoNCi0gICAqKkVjb25vbWljcyoqOiBJbmNvbWUgc2hhcmVzLCBwcm9wb3J0aW9ucywgb3IgYm91bmRlZCBpbmRpY2VzDQoNCi0gICAqKk1vbnRlIENhcmxvIHNpbXVsYXRpb24qKjogRWZmaWNpZW50IHJhbmRvbSB2YXJpYXRlIGdlbmVyYXRpb24gKHZpYQ0KICAgIGludmVyc2UgdHJhbnNmb3JtKQ0KDQotICAgKipNYWNoaW5lIGxlYXJuaW5nKio6IE91dHB1dCBsYXllciBmb3IgYm91bmRlZCB0YXJnZXRzLCBwcmlvcg0KICAgIGRpc3RyaWJ1dGlvbnMgaW4gQmF5ZXNpYW4gbW9kZWxzDQoNCi0gICAqKlJlbGlhYmlsaXR5IGVuZ2luZWVyaW5nKio6IE1vZGVsaW5nIGZhaWx1cmUgcmF0ZXMgb2Ygc3lzdGVtcyB3aXRoDQogICAgYm91bmRlZCBsaWZldGltZXMNCg0KXA0KDQpMZXQgJFgkIGJlIHRoZSBLdW1hcmFzd2FteSByYW5kb20gdmFyaWFibGUgd2l0aCBDdW11bGF0aXZlIERpc3RyaWJ1dGlvbg0KRnVuY3Rpb24gKENERikNCg0KJCQNCkYoeDsgYSwgYikgPSAxIC0gKDEgLSB4XmEpXmINCiQkDQoNCndoZXJlICRhID4gMCQgYW5kICRiID4gMCQgdW5rbm93biBwYXJhbWV0ZXJzIGFuZCAkMCA8IHggPCAxJC4NCg0KVGhlIGZvbGxvd2luZyBhcmUgdHdvIHNwZWNpYWwgY2FzZSBvZiB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uOg0KDQoxLiAgKipVbmlmb3JtIERpc3RyaWJ1dGlvbioqOiBXaGVuICRhID0gMSQgYW5kICRiID0gMSQsIHRoZSBLdW1hcmFzd2FteQ0KICAgIGRpc3RyaWJ1dGlvbiBiZWNvbWVzIGEgdW5pZm9ybSBkaXN0cmlidXRpb24gb3ZlciAkWzAsIDFdJCB3aXRoIENERg0KICAgICRGKHgpID0geCQuDQoNCjIuICAqKlBvd2VyIERpc3RyaWJ1dGlvbioqOiB3aGVuICRiID0gMSQgYW5kICRhID4gMCQsIHRoZSBLdW1hcmFzd2FteQ0KICAgIGRpc3RyaWJ1dGlvbiBiZWNvbWVzIGEgcG93ZXIgZGlzdHJpYnV0aW9uIG92ZXIgJFswLCAxXSQgd2l0aCBDREYNCiAgICAkRih4KSA9IHheYSQuDQoNClRoaXMgZmluYWwgZXhhbSBmb2N1c2VzIG9uIGluZmVyZW5jZXMgb2YgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIGFuZA0KcmVsYXRlZCBkYXRhIGFuYWx5c2lzLg0KDQojIyBQYXJ0IEE6IE1ldGhvZG9sb2dpY2FsIERlcml2YXRpb25zDQoNClwNCg0KU2hvdyB0aGF0IHRoZSBkZW5zaXR5IGZ1bmN0aW9uIG9mIHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gaXMNCg0KJCQNCmYoeDsgYSwgYikgPSBhYiBcLCB4XnthLTF9ICgxIC0geF5hKV57Yi0xfS4NCiQkDQoNCkdpdmVuIHRoZSBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiAoQ0RGKTogDQokJA0KRih4OyBhLGIpID0gMSAtICgxIC0geF5hKV5iDQokJA0KDQpEaWZmZXJlbnRpYXRlIHdpdGggcmVzcGVjdCB0byAoeCk6IA0KJCQNCmYoeDsgYSxiKSA9IFxmcmFje2R9e2R4fUYoeCkNCiQkIA0KQXBwbHlpbmcgdGhlIGNoYWluIHJ1bGU6DQoNCiQkDQpmKHgpID0gYigxIC0geF5hKV57Yi0xfSBcY2RvdCBheF57YS0xfQ0KJCQNCiQkDQpmKHgpID0gYWIgLCB4XnthLTF9KDEgLSB4XmEpXntiLTF9IA0KJCQgDQoNCiQkDQpmKHg7IGEsYikgPSBhYiBcY2RvdCB4XnthLTF9KDEgLSB4XmEpXntiLTF9DQokJA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpcDQoNCiMjICoqUHJvYmxlbSBBMioqOiANCkxldCAkXHt4XzEsIHhfMiwgXGNkb3RzLCB4X24gXH0kIGJlIGFuIGkuaS5kLiByYW5kb20gc2FtcGxlIHRha2VuIGZyb20gYSBwb3B1bGF0aW9uIHRoYXQgZm9sbG93cyB0aGUgYW92ZSAyLXBhcmFtZXRlciBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24uIFdyaXRlIG91dCB0aGUgbG9nbGlrZWxpaG9vZCBmdW5jdGlvbiBvZiAkYSQgYW5kICRiJCwgZGVub3RlZCBieSAkXGVsbChhLGIpJCwgYmFzZWQgb24gdGhlIGFib3ZlIHJhbmRvbSBzYW1wbGUgYW5kICoqZGVyaXZlKiogdGhlIGdyYWRpZW50IHZlY3RvciAkW1xlbGxfYV5ccHJpbWUoYSxiKSwgXGVsbF9iXlxwcmltZShhLGIpXSQsIHRoZSBmaXJzdCBvcmRlciBwYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhlIGxvZy1saWtlbGlob29kIHdpdGggcmVzcGVjdCB0byBwYXJhbWV0ZXJzICRhJCBhbmQgJGIkLg0KDQpHaXZlbiBhIHNhbXBsZSAoeF8xLCAuLi4sIHhfbiksIHRoZSBsaWtlbGlob29kIGlzOg0KDQokJA0KTChhLGIpID0gXHByb2Rfe2k9MX1ebiBhYiAsIHhfaV57YS0xfSgxIC0geF9pXmEpXntiLTF9DQokJA0KDQpUYWtpbmcgbG9nczoNCg0KJCQNClxlbGwoYSxiKSA9IG5cbG9nIGEgKyBuXGxvZyBiICsgKGEtMSlcc3VtIFxsb2cgeF9pICsgKGItMSlcc3VtIFxsb2coMSAtIHhfaV5hKQ0KJCQNCg0KIyMjIEdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAoYSk6DQoNCiQkDQpcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBhfSA9IFxmcmFje259e2F9ICsgXHN1bSBcbG9nIHhfaSAtIChiLTEpXHN1bSBcZnJhY3t4X2leYSBcbG9nIHhfaX17MSAtIHhfaV5hfQ0KJCQNCg0KIyMjIEdyYWRpZW50IHdpdGggcmVzcGVjdCB0byAoYik6DQoNCiQkDQpcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBifSA9IFxmcmFje259e2J9ICsgXHN1bSBcbG9nKDEgLSB4X2leYSkNCiQkDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KXA0KDQojIyAqKlByb2JsZW0gQTMqKjoNCg0KQmFzZWQgb24gdGhlIGdyYWRpZW50cyBmdW5jdGlvbnMgb2J0YWluZWQgaW4gdGhlIGFib3ZlIHByb2JsZW0gQTIsDQoqKmRlcml2ZSoqIHRoZSBvYnNlcnZlZCBGaXNoZXIgSW5mb3JtYXRpb24gbWF0cml4IChpLmUsIHRoZSBuZWdhdGl2ZQ0KSGVzc2lhbiBNYXRyaXgpLg0KDQpUaGUgb2JzZXJ2ZWQgRmlzaGVyIGluZm9ybWF0aW9uIGlzIGRlZmluZWQgYXM6DQoNCiQkDQpcbWF0aGNhbHtJfShhLGIpID0gLSBcbmFibGFeMiBcZWxsKGEsYikNCiQkDQoNClRoZSBzZWNvbmQgZGVyaXZhdGl2ZXMgYXJlOg0KDQokJA0KXGZyYWN7XHBhcnRpYWxeMiBcZWxsfXtccGFydGlhbCBhXjJ9ID0gLVxmcmFje259e2FeMn0NCiQkDQoNCiQkDQpcZnJhY3tccGFydGlhbF4yIFxlbGx9e1xwYXJ0aWFsIGJeMn0gPSAtXGZyYWN7bn17Yl4yfQ0KJCQNCg0KJCQNClxmcmFje1xwYXJ0aWFsXjIgXGVsbH17XHBhcnRpYWwgYSBccGFydGlhbCBifQ0KPSBcc3VtIFxmcmFjey14X2leYSBcbG9nIHhfaX17MS14X2leYX0NCiQkDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpcDQoNCiMjICoqUHJvYmxlbSBBNCoqOg0KDQpDb25zaWRlciBwb3dlciBkaXN0cmlidXRpb24NCiRGKHgpID0geF5hLCAoYSA+MCBccXVhZCBcdGV4dHsgYW5kIH1ccXVhZCB4IFxpbiAoMCwxKSkkLCBhIHNwZWNpYWwgY2FzZQ0Kb2YgdGhlIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiB3aXRoICRiID0gMSQsIGFuZCBhIHJhbmRvbSBzYW1wbGUgZnJvbQ0KdGhpcyBkaXN0cmlidXRpb24gJFx7IHhfMSwgeF8yLCBcY2RvdHMsIHhfblx9JC4gKipEZXJpdmUqKiB0aGUgTUxFIGFuZA0KTU1FIG9mICRhJCByZXNwZWN0aXZlbHkuIFsqSGludDogVG8gZmluZCB0aGUgTU1FLCB5b3UgbmVlZCB0byBjb21wdXRlDQp0aGUgbW9tZW50IG9mIHRoZSBwb3dlciBkaXN0cmlidXRpb247IHRoYXQgaXMsKg0KJEVbWF5rXSA9IFxpbnRfMF4xIHheayBGJyh4KSBkeCQuIE5vdGUgdGhhdCBib3RoIHRoZSBNTEUgYW5kIHRoZSBNTUUNCmhhdmUgY2xvc2VkLWZvcm0gZXhwcmVzc2lvbnMuXQ0KDQoNCkNERjoNCiQkDQpmKHgpPXheYQ0KJCQNCg0KUERGOg0KJCQNCmYoeDsgYSwxKSA9IGEgeF57YS0xfQ0KJCQNCg0KTUxFIG9mIFxoYXR7YX06IA0KJCQNClxoYXR7YX0gPSAtXGZyYWN7bn17XHN1bSBcbG9nIHhfaX0NCiQkDQoNCk1ldGhvZCBvZiBNb21lbnRzIG9mIFxoYXR7YX06DQokJA0KXGJveGVke1xoYXR7YX1fe01NfSA9IFxmcmFje1xiYXJ7eH19ezEtXGJhcnt4fX19DQokJA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpcDQoNCiMjICoqUHJvYmxlbSBBNSoqOg0KDQpVc2luZyB0aGUgc2FtZSBzZXR0aW5nIGFzIGluICoqUHJvYmxlbSBBNCoqLCBmaW5kIHRoZSBhc3ltcHRvdGljIChXYWxkKQ0KY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgJGEkLiBbKkhpbnQ6IENvbXB1dGUgdGhlIEZpc2hlciBpbmZvcm1hdGlvbiBmb3IqDQokYSQsIHRoZW4gdGFrZSBpdHMgcmVjaXByb2NhbCB0byBvYnRhaW4gdGhlIHZhcmlhbmNlLl0NCg0KRm9yIHRoZSBwb3dlciBkaXN0cmlidXRpb24sIHRoZSBsb2ctbGlrZWxpaG9vZCBpcw0KDQokJA0KXGVsbChhKT1uXGxvZyhhKSsoYS0xKVxzdW1fe2k9MX1eblxsb2coeF9pKS4NCiQkDQoNClRoZSBzZWNvbmQgZGVyaXZhdGl2ZSBpcw0KDQokJA0KXGVsbCcnKGEpPS1cZnJhY3tufXthXjJ9Lg0KJCQNCg0KVGhlcmVmb3JlLCB0aGUgRmlzaGVyIGluZm9ybWF0aW9uIGlzDQoNCiQkDQpJKGEpPS1cZWxsJycoYSk9XGZyYWN7bn17YV4yfS4NCiQkDQoNClRoZSBlc3RpbWF0ZWQgdmFyaWFuY2Ugb2YgXChcaGF0IGFcKSBpcyB0aGUgcmVjaXByb2NhbCBvZiB0aGUgb2JzZXJ2ZWQgRmlzaGVyIGluZm9ybWF0aW9uIGV2YWx1YXRlZCBhdCBcKFxoYXQgYVwpOg0KDQokJA0Ke1Zhcn0oXGhhdCBhKT1cZnJhY3sgYV4yfXtufS4NCiQkDQoNClRodXMsIHRoZSBlc3RpbWF0ZWQgc3RhbmRhcmQgZXJyb3IgaXMNCg0KJCQNClNFKFxoYXQgYSk9XGZyYWN7XGhhdCBhfXtcc3FydCBufS4NCiQkDQoNClRoZSA5NVwlIFdhbGQgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgXChhXCkgaXMNCg0KJCQNClxib3hlZHtcaGF0IGEgXHBtIDEuOTZcZnJhY3tcaGF0IGF9e1xzcXJ0IG59fS4NCiQkDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KXA0KDQojIyAqKlByb2JsZW0gQTYqKjoNCg0KVXNpbmcgdGhlIHNhbWUgc2V0dGluZyBhcyBpbiAqKlByb2JsZW0gQTQqKiwgcGVyZm9ybSBhIGxpa2VsaWhvb2QgcmF0aW8NCnRlc3QgZm9yIHRoZSBoeXBvdGhlc2lzICRIXzAgOmE9MSQgKGkuZS4sIHRoZSBwb3dlciBkaXN0cmlidXRpb24gcmVkdWNlcw0KdG8gYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbikuIFsqSGludDogRXZhbHVhdGUgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uDQphdCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlKiAkXGhhdHthfSQgYW5kIGF0ICRhPTEkLCB0aGVuIHVzZQ0KdGhlc2UgdmFsdWVzIHRvIGNvbnN0cnVjdCB0aGUgTFJUIHRlc3Qgc3RhdGlzdGljLl0NCg0KVGhlIHBhcmFtZXRlciAoYSkgY29udHJvbHMgYmVoYXZpb3IgbmVhciAwLCB3aGlsZSAoYikgY29udHJvbHMgYmVoYXZpb3INCm5lYXIgMS4gVG9nZXRoZXIsIHRoZXkgZGV0ZXJtaW5lIHRoZSBza2V3bmVzcyBhbmQgc2hhcGUgb2YgdGhlDQpkaXN0cmlidXRpb24gb3ZlciAoWzAsMV0pLg0KDQpXZSB0ZXN0DQoNCiQkDQpIXzA6YT0xIFxxcXVhZCBcdGV4dHt2ZXJzdXN9IFxxcXVhZCBIX2E6YVxuZSAxLg0KJCQNCg0KRm9yIHRoZSBwb3dlciBkaXN0cmlidXRpb24sIHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3Qgc3RhdGlzdGljIGlzDQoNCiQkDQpHXjI9MlxsZWZ0W1xlbGwoXGhhdCBhKS1cZWxsKGFfMClccmlnaHRdLA0KJCQNCg0Kd2hlcmUgXChhXzA9MVwpLiBVbmRlciBcKEhfMFwpLCB0aGUgYXN5bXB0b3RpYyByZWZlcmVuY2UgZGlzdHJpYnV0aW9uIGlzDQoNCiQkDQpHXjIgXHNpbSBcY2hpXjJfMS4NCiQkDQoNClRoZSBkZWNpc2lvbiBydWxlIGF0IFwoXGFscGhhPTAuMDVcKSBpcyB0byByZWplY3QgXChIXzBcKSBpZg0KDQokJA0KXGJveGVke0deMj5cY2hpXjJfezAuOTUsMX19Lg0KJCQNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIFBhcnQgQjogTnVtZXJpY2FsIEFuYWx5c2lzDQoNCioqQWxsIGNvZGUgbXVzdCBiZSB3ZWxsIGNvbW1lbnRlZCBhbmQgYWRoZXJlIHRvIGJlc3QgY29kaW5nIHByYWN0aWNlcyoqDQoNCioqV29ya2luZyBEYXRhc2V0Kio6IEEgc21hbGwgcmVzZXJ2b2lyIHN1cHBsaWVzIHdhdGVyIHRvIGEgdG93bi4gRHVyaW5nDQp0aGUgZHJ5IHNlYXNvbiAoNTAgZGF5cyksIGVuZ2luZWVycyByZWNvcmQgdGhlIGZyYWN0aW9uIG9mIHVzYWJsZQ0Kc3RvcmFnZSBmaWxsZWQgZWFjaCBtb3JuaW5nLiBWYWx1ZXMgbmVhciAwIG1lYW4gdGhlIHJlc2Vydm9pciBpcyBuZWFybHkNCmVtcHR5OyB2YWx1ZXMgbmVhciAxIG1lYW4gaXQncyBmdWxsLiBUaGUgZGlzdHJpYnV0aW9uIHRlbmRzIHRvIGJlDQpyaWdodOKAkXNrZXdlZCAobW9zdGx5IGxvdyBsZXZlbHMgZHVlIHRvIGRyb3VnaHQpIGJ1dCB3aXRoIG9jY2FzaW9uYWwNCnJlcGxlbmlzaG1lbnQuDQoNClRoZSBmb2xsb3dpbmcgNTAgZGF0YSBwb2ludHMgKG9yZGVyZWQgZm9yIGNsYXJpdHkpIHJlcHJlc2VudCB0aGUgZGFpbHkNCnByb3BvcnRpb24gb2YgdXNhYmxlIHN0b3JhZ2U6DQoNCmBgYCAgICAgICAgIA0KMC4xMiwgMC4xNCwgMC4xNSwgMC4xNiwgMC4xNywgMC4xOCwgMC4xOSwgMC4yMCwgMC4yMSwgMC4yMiwNCjAuMjMsIDAuMjQsIDAuMjUsIDAuMjYsIDAuMjcsIDAuMjgsIDAuMjksIDAuMzAsIDAuMzEsIDAuMzIsDQowLjMzLCAwLjM0LCAwLjM1LCAwLjM2LCAwLjM3LCAwLjM4LCAwLjM5LCAwLjQwLCAwLjQxLCAwLjQyLA0KMC40MywgMC40NCwgMC40NSwgMC40NiwgMC40NywgMC40OCwgMC40OSwgMC41MCwgMC41MSwgMC41MiwNCjAuNTMsIDAuNTQsIDAuNTUsIDAuNTYsIDAuNTcsIDAuNTgsIDAuNTksIDAuNjAsIDAuNjEsIDAuNzgNCmBgYA0KDQpcDQoNCiMjIyAqKlByb2JsZW0gQjEqKjoNCg0KRml0IHRoZSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gdG8gdGhlIGFib3ZlIGRhdGEuIFVzZSB0aGUgZGVyaXZhdGlvbnMNCmluICoqUHJvYmxlbSBBMioqIHRvIGZpbmQgdGhlIE1MRSBvZiAkYSQgYW5kICRiJC4gUGxlYXNlIGNvcHkgdGhlIGtleQ0KZm9ybXVsYXMgYmVmb3JlIGNvZGluZy4NCg0KYGBge3J9DQojIERhdGFzZXQNCnggPC0gYygwLjEyLDAuMTQsMC4xNSwwLjE2LDAuMTcsMC4xOCwwLjE5LDAuMjAsMC4yMSwwLjIyLA0KICAgICAgIDAuMjMsMC4yNCwwLjI1LDAuMjYsMC4yNywwLjI4LDAuMjksMC4zMCwwLjMxLDAuMzIsDQogICAgICAgMC4zMywwLjM0LDAuMzUsMC4zNiwwLjM3LDAuMzgsMC4zOSwwLjQwLDAuNDEsMC40MiwNCiAgICAgICAwLjQzLDAuNDQsMC40NSwwLjQ2LDAuNDcsMC40OCwwLjQ5LDAuNTAsMC41MSwwLjUyLA0KICAgICAgIDAuNTMsMC41NCwwLjU1LDAuNTYsMC41NywwLjU4LDAuNTksMC42MCwwLjYxLDAuNzgpDQoNCiMgU2FtcGxlIHNpemUNCm4gPC0gbGVuZ3RoKHgpDQoNCiMgTmVnYXRpdmUgbG9nLWxpa2VsaWhvb2QgZm9yIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbg0KbG9nbGlrX2t1bWFyIDwtIGZ1bmN0aW9uKHBhcikgew0KICANCiAgIyBFeHRyYWN0IHBhcmFtZXRlcnMgbnVtZXJpY2FsbHkNCiAgYSA8LSBhcy5udW1lcmljKHBhclsxXSkNCiAgYiA8LSBhcy5udW1lcmljKHBhclsyXSkNCiAgDQogICMgUGFyYW1ldGVyIHJlc3RyaWN0aW9ucw0KICBpZiAoYSA8PSAwIHx8IGIgPD0gMCkgew0KICAgIHJldHVybihJbmYpDQogIH0NCiAgDQogICMgTG9nLWxpa2VsaWhvb2QNCiAgbGwgPC0gbiAqIGxvZyhhKSArDQogICAgICAgIG4gKiBsb2coYikgKw0KICAgICAgICAoYSAtIDEpICogc3VtKGxvZyh4KSkgKw0KICAgICAgICAoYiAtIDEpICogc3VtKGxvZygxIC0geF5hKSkNCiAgDQogICMgUmV0dXJuIG5lZ2F0aXZlIGxvZy1saWtlbGlob29kIGZvciBtaW5pbWl6YXRpb24NCiAgcmV0dXJuKC1sbCkNCn0NCg0KIyBPcHRpbWl6ZQ0KZml0IDwtIG9wdGltKA0KICBwYXIgPSBjKDEsIDEpLA0KICBmbiA9IGxvZ2xpa19rdW1hciwNCiAgaGVzc2lhbiA9IFRSVUUNCikNCg0KIyBNTEVzDQphX2hhdCA8LSBmaXQkcGFyWzFdDQpiX2hhdCA8LSBmaXQkcGFyWzJdDQoNCiMgT3V0cHV0DQphX2hhdA0KYl9oYXQNCmBgYA0KDQpcDQoNCiMjIyAqKlByb2JsZW0gQjIqKjoNCg0KRml0IHRoZSAqKnBvd2VyIGRpc3RyaWJ1dGlvbioqIHRvIHRoZSBhYm92ZSBkYXRhIHVzaW5nIHRoZSBkZXJpdmVkIG9mDQokYSQgb2J0YWluZWQgaW4gKipQcm9ibGVtIEE0KiogdG8gdGVzdCB0aGUgZm9sbG93aW5nIGh5cG90aGVzaXMgdXNpbmcNCmxpa2VsaWhvb2QgcmF0aW8gcHJvY2VkdXJlIGFyIHNpZ25pZmljYW5jZSBsZXZlbCAkXGFscGhhID0gMC4wNSQ6DQoNCiQkDQpIXzA6IGIgPSAxIFxxdWFkIFx0ZXh0eyB2ZXJzdXMgfSBccXVhZCBIX2E6IGIgXG5lIDEuDQokJA0KDQpTdGF0ZSB0aGUgc3RhdGlzdGljYWwgZGVjaXNpb24gY2xlYXJseS4gV2hhdCBpcyB0aGUgcHJhY3RpY2FsDQppbXBsaWNhdGlvbiBvZiB0aGUgdGVzdGluZyByZXN1bHQ/DQoNCmBgYHtyfQ0KIyBTdGVwIDE6IEZpdCBwb3dlciBkaXN0cmlidXRpb24gKHJlc3RyaWN0ZWQgbW9kZWwpDQphX2hhdF9wb3dlciA8LSAtbiAvIHN1bShsb2coeCkpDQoNCiMgU3RlcCAyOiBMb2ctbGlrZWxpaG9vZHMNCmxsX2Z1bGwgPC0gLWZpdCR2YWx1ZQ0KDQpsbF9yZXN0cmljdGVkIDwtIG4qbG9nKGFfaGF0X3Bvd2VyKSArDQogICAgICAgICAgICAgICAgIChhX2hhdF9wb3dlciAtIDEpKnN1bShsb2coeCkpDQoNCiMgU3RlcCAzOiBMUlQgc3RhdGlzdGljDQpMUlQgPC0gMiAqIChsbF9mdWxsIC0gbGxfcmVzdHJpY3RlZCkNCnBfdmFsdWUgPC0gMSAtIHBjaGlzcShMUlQsIGRmID0gMSkNCg0KY2F0KCJCMiBSZXN1bHRzOlxuIikNCmNhdCgiTFJUIHN0YXRpc3RpYyA9IiwgTFJULCAiXG4iKQ0KY2F0KCJwLXZhbHVlID0iLCBwX3ZhbHVlLCAiXG4iKQ0KDQppZiAocF92YWx1ZSA8IDAuMDUpIHsNCiAgY2F0KCJEZWNpc2lvbjogUmVqZWN0IEgwIChiIOKJoCAxKVxuXG4iKQ0KfSBlbHNlIHsNCiAgY2F0KCJEZWNpc2lvbjogRmFpbCB0byByZWplY3QgSDAgKGIgPSAxIGlzIGFkZXF1YXRlKVxuXG4iKQ0KfQ0KYGBgDQoNClwNCg0KIyMjICoqUHJvYmxlbSBCMyoqOg0KDQpVc2UgdGhlIHByb2NlZHVyZSBhbmQgY29kZSBmcm9tICoqUHJvYmxlbSBCMSoqIHRvIGVzdGltYXRlIHRoZSBNTEVzIG9mDQokYSQgYW5kICRiJCwgYW5kIHRoZW4gY29tcGxldGUgdGhlIGZvbGxvd2luZyBhbmFseXNlczoNCg0KKDEpLiBPYnRhaW4gdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mICRcaGF0e2F9JCBhbmQNCiRcaGF0e2J9JCBhbmQgcGxvdCBlYWNoIGRpc3RyaWJ1dGlvbiB1c2luZyAqKkdhdXNzaWFuIGtlcm5lbCBkZW5zaXR5DQpjdXJ2ZXMqKi4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpCIDwtIDEwMDANCg0KYV9ib290IDwtIG51bWVyaWMoQikNCmJfYm9vdCA8LSBudW1lcmljKEIpDQoNCmZvciAoaSBpbiAxOkIpIHsNCiAgDQogICMgUmVzYW1wbGUgd2l0aCByZXBsYWNlbWVudA0KICB4YiA8LSBzYW1wbGUoeCwgc2l6ZSA9IG4sIHJlcGxhY2UgPSBUUlVFKQ0KICANCiAgIyBEZWZpbmUgbG9nLWxpa2VsaWhvb2QgZm9yIGJvb3RzdHJhcCBzYW1wbGUNCiAgbG9nbGlrX2Jvb3QgPC0gZnVuY3Rpb24ocGFyKSB7DQogICAgYSA8LSBwYXJbMV0NCiAgICBiIDwtIHBhclsyXQ0KICAgIA0KICAgIGlmIChhIDw9IDAgfHwgYiA8PSAwKSByZXR1cm4oSW5mKQ0KICAgIA0KICAgIGxsIDwtIGxlbmd0aCh4YikqbG9nKGEpICsgbGVuZ3RoKHhiKSpsb2coYikgKw0KICAgICAgICAgIChhIC0gMSkqc3VtKGxvZyh4YikpICsNCiAgICAgICAgICAoYiAtIDEpKnN1bShsb2coMSAtIHhiXmEpKQ0KICAgIA0KICAgIHJldHVybigtbGwpDQogIH0NCiAgDQogIGZpdF9iIDwtIG9wdGltKGMoYV9oYXQsIGJfaGF0KSwgbG9nbGlrX2Jvb3QpDQogIA0KICBhX2Jvb3RbaV0gPC0gZml0X2IkcGFyWzFdDQogIGJfYm9vdFtpXSA8LSBmaXRfYiRwYXJbMl0NCn0NCg0KIyBQbG90IGRlbnNpdGllcw0KcGxvdChkZW5zaXR5KGFfYm9vdCksIG1haW4gPSAiQm9vdHN0cmFwIERlbnNpdHkgb2YgYV9oYXQiKQ0KcGxvdChkZW5zaXR5KGJfYm9vdCksIG1haW4gPSAiQm9vdHN0cmFwIERlbnNpdHkgb2YgYl9oYXQiKQ0KYGBgDQoNCigyKS4gQ29uc3RydWN0IGJvdGggdGhlICQ5NVwlJCAqKmJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFsKiogYW5kIHRoZQ0KKipXYWxkIGNvbmZpZGVuY2UgaW50ZXJ2YWwqKiBmb3IgJGIkLiBEbyB0aGVzZSBpbnRlcnZhbHMgYWdyZWUgd2l0aCB0aGUNCnJlc3VsdHMgb2J0YWluZWQgaW4gKipQcm9ibGVtIEIyKio/IFsqQ29tcHV0ZSB0aGUgc3RhbmRhcmQgZXJyb3Igb2YqDQokXGhhdHtifSQgdXNpbmcgdGhlIG9ic2VydmVkIEZpc2hlciBpbmZvcm1hdGlvbiBtYXRyaXgsIGkuZS4sIHRoZQ0KaW52ZXJzZSBvZiB0aGUgbmVnYXRpdmUgSGVzc2lhbiBvYnRhaW5lZCBmcm9tIG9wdGltKCldDQoNCmBgYHtyfQ0KIyBCb290c3RyYXAgcGVyY2VudGlsZSBDSQ0KYm9vdF9jaV9iIDwtIHF1YW50aWxlKGJfYm9vdCwgYygwLjAyNSwgMC45NzUpKQ0KDQojIFdhbGQgQ0kgdXNpbmcgSGVzc2lhbg0KSCA8LSBmaXQkaGVzc2lhbg0KdmNvdl9tYXRyaXggPC0gc29sdmUoSCkNCg0Kc2VfYiA8LSBzcXJ0KHZjb3ZfbWF0cml4WzIsMl0pDQoNCndhbGRfY2lfYiA8LSBjKGJfaGF0IC0gMS45NipzZV9iLA0KICAgICAgICAgICAgICAgYl9oYXQgKyAxLjk2KnNlX2IpDQoNCmNhdCgiQjMgUmVzdWx0czpcbiIpDQpjYXQoIkJvb3RzdHJhcCBDSSBmb3IgYjpcbiIpDQpwcmludChib290X2NpX2IpDQoNCmNhdCgiXG5XYWxkIENJIGZvciBiOlxuIikNCnByaW50KHdhbGRfY2lfYikNCg0KYGBgDQoNCigzKS4gQmFzZWQgb24gdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIGZyb20gcGFydCAoMSkgb2YgdGhpcw0KcHJvYmxlbSwgYXNzZXNzIHdoZXRoZXIgdGhlIHZhbGlkaXR5IG9mIHRoZSBXYWxkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMNCnN1cHBvcnRlZC4NCg0KYGBge3J9DQpwbG90KGRlbnNpdHkoYl9ib290KSwNCiAgICAgbWFpbiA9ICJCb290c3RyYXAgRGlzdHJpYnV0aW9uIG9mIGJfaGF0IikNCmFibGluZSh2ID0gd2FsZF9jaV9iLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCmFibGluZSh2ID0gMSwgY29sID0gImJsdWUiLCBsdHkgPSAyKQ0KDQpsZWdlbmQoInRvcHJpZ2h0IiwNCiAgICAgICBsZWdlbmQgPSBjKCJXYWxkIENJIiwgImIgPSAxIiksDQogICAgICAgY29sID0gYygicmVkIiwgImJsdWUiKSwNCiAgICAgICBsdHkgPSAyKQ0KYGBgDQoNClwNCg0KIyMjICoqUHJvYmxlbSBCNCoqOg0KDQpJbiB0aGUgaW50cm9kdWN0aW9uIHRvIHRoZSB3b3JraW5nIG1vZGVsIGZvciB0aGlzIGV4YW0sIHRoZSBLdW1hcmFzd2FteQ0KZGlzdHJpYnV0aW9uIHJlZHVjZXMgdG8gdGhlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIG9uICgwLDEpLiBJbiB0aGlzDQpwcm9ibGVtLCB3ZSBwZXJmb3JtIGEgKipsaWtlbGlob29kIHJhdGlvIHRlc3QqKiBmb3IgdGhlIGZvbGxvd2luZw0KaHlwb3RoZXNpcyB0byBhc3Nlc3Mgd2hldGhlciB0aGUgZGF0YSBjb21lIGZyb20gdGhlIHVuaWZvcm0gZGlzdHJpYnV0aW9uDQpvbiAoMCwxKToNCg0KJCQNCkhfMDogYSA9IDFccXVhZCBcJiBccXVhZCBiID0gMVxxdWFkIFx0ZXh0eyB2ZXJzdXMgfSBccXVhZCBIX2E6IGEgXG5lIDEgXHF1YWQgXHRleHR7b3J9IFxxdWFkIGIgXG5lIDEgXHF1YWQgXHRleHR7b3J9XHF1YWQgKGEgXG5lIDEgXHF1YWQgXCYgXHF1YWQgYiBcbmUgMSkuDQokJA0KDQpQcm92aWRlIGEgcHJhY3RpY2FsIGludGVycHJldGF0aW9uIG9mIHRoZSBhYm92ZSB0ZXN0IHJlc3VsdC4gWypIaW50OioNCiRIX2EkIGJhc2ljYWxseSBzYXlzIHRoYXQgdGhlcmUgaXMgbm8gY29uc3RyYWludHMgZm9yICRhJCBhbmQgJGIkLg0KUGxlYXNlIHJldmlldyB0aGUgbGVjdHVyZSBub3RlIGZvciBtb2R1bGUgMTEgb24gdGhlIGxpa2VsaWhvb2QgcmF0aW8NCnRlc3QgYmVmb3JlIGNvZGluZy5dDQoNClwNCg0KYGBge3J9DQojIExpa2VsaWhvb2QgdW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpczogZGVnZW5lcmF0ZSBhdCAxDQpsaWtlbGlob29kX251bGwgPC0gZnVuY3Rpb24oZGF0YSkgew0KICBpZihhbGwoZGF0YSA9PSAxKSkgew0KICAgIHJldHVybigxKQ0KICB9IGVsc2Ugew0KICAgIHJldHVybigwKQ0KICB9DQp9DQoNCiMgTGlrZWxpaG9vZCB1bmRlciB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogdW5pZm9ybSBvbiBvYnNlcnZlZCByYW5nZQ0KbGlrZWxpaG9vZF9hbHQgPC0gZnVuY3Rpb24oZGF0YSkgew0KICBhX2hhdCA8LSBtaW4oZGF0YSkNCiAgYl9oYXQgPC0gbWF4KGRhdGEpDQogIG4gPC0gbGVuZ3RoKGRhdGEpDQogIA0KICAjIENoZWNrIGlmIGRhdGEgYXJlIHdpdGhpbiBbYV9oYXQsIGJfaGF0XQ0KICBpZihhbnkoZGF0YSA8IGFfaGF0KSB8fCBhbnkoZGF0YSA+IGJfaGF0KSkgew0KICAgIHJldHVybigwKQ0KICB9DQogIA0KICAjIExpa2VsaWhvb2QgZm9yIHVuaWZvcm0gZGlzdHJpYnV0aW9uDQogIGxpa2VsaWhvb2QgPC0gKDEgLyAoYl9oYXQgLSBhX2hhdCkpXm4NCiAgcmV0dXJuKGxpa2VsaWhvb2QpDQp9DQoNCiMgQ2FsY3VsYXRlIGxpa2VsaWhvb2RzDQpMX251bGwgPC0gbGlrZWxpaG9vZF9udWxsKHgpDQpMX2FsdCA8LSBsaWtlbGlob29kX2FsdCh4KQ0KDQojIENhbGN1bGF0ZSBsaWtlbGlob29kIHJhdGlvDQppZihMX251bGwgPT0gMCkgew0KICBMUlQgPC0gSW5mICAjIERhdGEgaW5jb21wYXRpYmxlIHdpdGggbnVsbA0KfSBlbHNlIHsNCiAgTFJUIDwtIExfYWx0IC8gTF9udWxsDQp9DQoNCiMgT3V0cHV0IHRoZSByZXN1bHRzDQpjYXQoIkxpa2VsaWhvb2QgdW5kZXIgbnVsbCAoZGVnZW5lcmF0ZSBhdCAxKToiLCBMX251bGwsICJcbiIpDQpjYXQoIkxpa2VsaWhvb2QgdW5kZXIgYWx0ZXJuYXRpdmU6IiwgTF9hbHQsICJcbiIpDQpjYXQoIkxpa2VsaWhvb2QgUmF0aW8gKExSVCk6IiwgTFJULCAiXG4iKQ0KYGBgDQoNClNpbmNlIHRoZSBkYXRhIGNsZWFybHkgYXJlIG5vdCBhbGwgMSwgdGhlIGxpa2VsaWhvb2QgdW5kZXIgdGhlIG51bGwgd2lsbA0KYmUgemVybywgbWFraW5nIHRoZSBsaWtlbGlob29kIHJhdGlvIHRlbmQgdG8gaW5maW5pdHkgb3IgdW5kZWZpbmVkLiBUaGlzDQppbmRpY2F0ZXMgc3Ryb25nIGV2aWRlbmNlIGFnYWluc3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSByZXNlcnZvaXINCmlzIGFsd2F5cyBmdWxsLlwqXCoNCg0KPGZvbnQgY29sb3IgPSAicmVkIj4qKk5vdGUqKjogUGxlYXNlIGRvd25sb2FkIHRoZSB0ZW1wbGF0ZSBhbmQgaW5zZXJ0DQp5b3VyIHdvcmsgaW50byBpdCB0byBjb21wbGV0ZSB0aGUgZXhhbS4gPC9mb250Pg0K