Assignment Objectives

  • Enhance understanding the procedure of likelihood-based chi-square hypothesis testing .

  • Implement the procedures for detecting overfitting/underfitting issues in practical applications.

Policies of Using AI Tools

Policy on AI Tool Use: Please 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.

Testing Overfitting/Underfitting

In Machine Learning and Statistics, overfitting occurs when a model is too complex and learns noise, leading to poor performance on new data, while underfitting happens when a model is too simple to capture important patterns, resulting in high errors overall; both issues are explained by the Bias–Variance Tradeoff and can cause unreliable predictions in real-world applications.

The probability density function (PDF) of the Weibull distribution is:

\[ f(t; \lambda, \beta) = \frac{\beta}{\lambda} \left( \frac{t}{\lambda} \right)^{\beta-1} \exp\left[ -\left( \frac{t}{\lambda} \right)^\beta \right], \quad t \ge 0 \] where \(\lambda > 0\) is the scale parameter (characteristic life) and \(\beta > 0\) is the shape parameter.

When \(\beta = 1\), the Weibull PDF simplifies to the exponential PDF:

\[ f(t; \lambda) = \frac{1}{\lambda} \exp\left( -\frac{t}{\lambda} \right) \] with constant hazard rate \(h(t) = 1/\lambda\).

This assignment focuses on performing a hypothesis test for the shape parameter (\(\beta\)) of the Weibull distribution within a reliability mode

\[\begin{align} H_0&: \beta = 1 \quad \text{(Exponential model, simpler)} \\ H_1&: \beta \neq 1 \quad \text{(Weibull model, more complex)} \end{align}\]


Question: Reliability Application

A mid-sized manufacturing company producing industrial conveyor systems began experiencing unexpected downtime in one of its distribution facilities, prompting concern about the reliability of a newly sourced batch of ball bearings used in the motor assemblies. These bearings, supplied by a vendor adopting cost-saving production methods, were installed across multiple units operating under continuous load conditions. After several months, maintenance logs revealed a pattern of increasing failures, with components lasting anywhere from a few dozen to over 150 hours before breakdown. To investigate, the engineering team collected time-to-failure data from 50 identical bearings and conducted a Weibull analysis within the framework of Reliability Engineering. The 50 time-to-failure (survival time) are:

12.4, 18.7, 25.3, 30.1, 33.5, 35.2, 38.9, 40.3, 42.7, 45.1, 47.6, 49.8, 52.4, 55.0, 
57.3, 60.2, 62.8, 65.1, 67.9, 70.5, 72.3, 75.6, 78.2, 80.9, 83.4, 85.7, 88.1, 90.6, 
93.2, 95.8, 98.4, 101.0, 104.5, 107.3, 110.6, 113.2, 116.8, 120.1, 123.7, 127.4,
130.9, 134.5, 138.2, 142.0, 146.3, 150.7, 155.2, 160.8, 168.4, 175.9
# Store the 50 failure times as a numeric vector for analysis
time <- c(
  12.4, 18.7, 25.3, 30.1, 33.5, 35.2, 38.9, 40.3, 42.7, 45.1,
  47.6, 49.8, 52.4, 55.0, 57.3, 60.2, 62.8, 65.1, 67.9, 70.5,
  72.3, 75.6, 78.2, 80.9, 83.4, 85.7, 88.1, 90.6, 93.2, 95.8,
  98.4, 101.0, 104.5, 107.3, 110.6, 113.2, 116.8, 120.1, 123.7, 127.4,
  130.9, 134.5, 138.2, 142.0, 146.3, 150.7, 155.2, 160.8, 168.4, 175.9
)

This assignment focuses on hypothesis \(H_0: \beta = 1\) (exponential) against \(H_1: \beta \neq 1\) (Weibull). This framework detects overfitting (fitting a Weibull when exponential is true) and underfitting (fitting exponential when Weibull with \(\beta \neq 1\) is true).

a). Find the MLE of the Weibull parameters \(\lambda\) (scale) and \(\beta\) (shape), denoted by \(\hat{\lambda}\) and \(\hat{\beta}\), respectively, using the optim() procedure. [Hint: You should provide explicit expressions for the log-likelihood and gradient functions of the Weibull distribution parameters.]

# Define the Weibull log-likelihood for (lambda, beta)
weibull_loglik <- function(par, x) {
  lambda <- par[1]
  beta <- par[2]
  
  # Restrict parameters to positive values
  if (lambda <= 0 || beta <= 0) return(-Inf)
  
  n <- length(x)
  
  n * log(beta) -
    n * beta * log(lambda) +
    (beta - 1) * sum(log(x)) -
    sum((x / lambda)^beta)
}

# Define the gradient for faster optimization
weibull_grad <- function(par, x) {
  lambda <- par[1]
  beta <- par[2]
  n <- length(x)
  
  # Repeated term in derivatives
  s <- (x / lambda)^beta
  
  d_lambda <- (beta / lambda) * (sum(s) - n)
  d_beta <- n / beta - n * log(lambda) + sum(log(x)) -
    sum(s * log(x / lambda))
  
  c(d_lambda, d_beta)
}
# Use optim() to maximize the log-likelihood numerically
fit_weibull <- optim(
  par = c(mean(time), 1.5),   # starting values
  fn = function(par, x) -weibull_loglik(par, x),  # minimize negative log-likelihood
  gr = function(par, x) -weibull_grad(par, x),    # negative gradient
  x = time,
  method = "BFGS",
  hessian = TRUE
)

# Extract MLE estimates
fit_weibull$par
[1] 98.992745  2.205676

Using the optim() procedure to maximize the Weibull log-likelihood, the maximum likelihood estimates are \(\hat{\lambda} = 98.992745\) and \(\hat{\beta} = 2.205676\).

b). Find the MLE of the exponential parameter \(\lambda\) (scale), denoted by \(\hat{\lambda}\), using any procedure. [Hint: You should provide explicit expressions for the log-likelihood and gradient functions of the exponential distribution parameters.]

For the exponential model, the log-likelihood is \(\ell(\lambda) = -n \log \lambda - \frac{1}{\lambda} \sum_{i=1}^n t_i\).

The gradient is \(\frac{d\ell}{d\lambda} = -\frac{n}{\lambda} + \frac{1}{\lambda^2} \sum_{i=1}^n t_i\).

Setting the derivative equal to zero gives \(\hat{\lambda} = \bar{t}\).

# Define the exponential log-likelihood for lambda
exp_loglik <- function(lambda, x) {
  n <- length(x)
  -n * log(lambda) - sum(x) / lambda
}

# Define the gradient of the exponential log-likelihood
exp_grad <- function(lambda, x) {
  n <- length(x)
  -n / lambda + sum(x) / lambda^2
}

# Compute the exponential MLE using the sample mean
lambda_hat_exp <- mean(time)

lambda_hat_exp
[1] 87.61

Using the sample mean, the maximum likelihood estimate is \(\hat{\lambda} = 87.61\).

c). Perform the likelihood ratio \(\chi^2\) test on \(\beta = 1\). What is the p-value? [Hint: Use the results in a) and b).]

The likelihood ratio statistic is \(LR = 2\left[\ell(\hat{\lambda}, \hat{\beta}) - \ell(\hat{\lambda}_0, 1)\right]\).

# Compute log-likelihood for Weibull (full model)
loglik_weibull <- weibull_loglik(fit_weibull$par, time)

# Compute log-likelihood for exponential (restricted model, beta = 1)
lambda_hat_exp <- mean(time)
n <- length(time)

loglik_exp <- -n * log(lambda_hat_exp) - sum(time) / lambda_hat_exp

# Compute likelihood ratio statistic
LR <- 2 * (loglik_weibull - loglik_exp)

# Compute p-value from chi-square distribution with 1 df
p_value_LR <- pchisq(LR, df = 1, lower.tail = FALSE)

LR
[1] 34.44994
p_value_LR
[1] 4.373569e-09

The likelihood ratio statistic is \(LR = 34.44994\). The corresponding p-value is approximately \(4.373569 \times 10^{-9}\).

d). Perform the Wald \(\chi^2\) on the same hypothesis \(\beta = 1\). What is the p-value? [Hint: You need to find the observed Fisher information matrix (i.e., the negative Hessian matrix from optim()) based on the Weibull distribution. The inverse of the negative observed Hessian matrix is the covariance matrix.]

The Wald statistic for testing \(H_0:\beta = 1\) is \(W = \dfrac{(\hat{\beta} - 1)^2}{\widehat{\mathrm{Var}}(\hat{\beta})}\).

# Extract the Hessian from the Weibull fit
info_weibull <- fit_weibull$hessian

# Invert the Hessian to get the covariance matrix
cov_weibull <- solve(info_weibull)

# Extract the Weibull estimate and its variance
beta_hat <- fit_weibull$par[2]
var_beta_hat <- cov_weibull[2, 2]

# Compute the Wald chi-square statistic
W <- (beta_hat - 1)^2 / var_beta_hat

# Compute the p-value using a chi-square distribution with 1 df
p_value_W <- pchisq(W, df = 1, lower.tail = FALSE)

W
[1] 23.10267
p_value_W
[1] 1.535777e-06

The Wald statistic is \(W = 23.10267\). The corresponding p-value is \(1.535777 \times 10^{-6}\).

e). Write a summary of the above analyses to address the following:

  • Whether the two tests generated the same results.

  • Which model is recommended for the data.

  • Draw the density curve based on the MLE(s) of the parameter(s) and describe the distribution of the time-to-failure.

Both the likelihood ratio test and the Wald test generate the same result. The likelihood ratio test gave a p-value of \(4.373569 \times 10^{-9}\), and the Wald test gave a p-value of \(1.535777 \times 10^{-6}\). Both p-values are extremely small and are statistically significant. We have enough evidence to reject the null hypothesis \(H_0: \beta = 1\).

The null hypothesis represents the exponential model, so rejecting \(H_0\) means that the exponential model does not fit this data well. Because of this, the Weibull model is a better choice for modeling the time-to-failure data.

# Draw the fitted Weibull density using the MLEs from part (a)
curve(
  dweibull(x, shape = fit_weibull$par[2], scale = fit_weibull$par[1]),
  from = 0, to = 200,
  lwd = 2,
  xlab = "Time to failure",
  ylab = "Density",
  main = "Fitted Weibull Density"
)

Using the MLEs from part (a), the fitted Weibull density is unimodal and right-skewed. The estimated Weibull shape parameter is \(\hat{\beta} = 2.205676\), which is greater than 1. This suggests that the failure rate is not constant, but instead increases as time goes on. The fitted Weibull density shows that larger time values are associated with a higher concentration of failures. Based on our observation, this is consistent with wear-out failure in reliability analysis. Components tend to weaken over time, so the longer they are in use, the more likely they are to experience failure.

LS0tCnRpdGxlOiAiQXNzaWdubWVudCA5OiBMaWtlbGlob29kLWJhc2VkIENoaS1TcXVhcmUgVGVzdHMiCmF1dGhvcjogIiBLYXlsYSBEeWVyICIKZGF0ZTogIiBEdWU6IEFwcmlsIDE0LCAyMDI2IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICB0b2NfZmxvYXQ6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiBubwogICAgdG9jX2NvbGxhcHNlZDogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgc21vb3RoX3Njcm9sbDogeWVzCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUKICAgIHRoZW1lOiBzcGFjZWxhYgogIHdvcmRfZG9jdW1lbnQ6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgZmlnX2NhcHRpb246IHllcwogICAga2VlcF9tZDogeWVzCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBmaWdfd2lkdGg6IDMKICAgIGZpZ19oZWlnaHQ6IDMKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9CiNUT0M6OmJlZm9yZSB7CiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LXNpemU6IDEuMmVtOwogIGRpc3BsYXk6IGJsb2NrOwogIGNvbG9yOiBuYXZ5OwogIG1hcmdpbi1ib3R0b206IDEwcHg7Cn0KCgpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQoKaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8KICBmb250LXNpemU6IDIycHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKfQoKaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE1cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsKICBjb2xvcjogbmF2eTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAyMHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE4cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE2cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLwouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7CiAgY29udGVudDogIi4iOwoKYm9keSB7YmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjsKICAgICAgY29sb3I6ICMwMDAwMDA7CiAgICAgIGZvbnQtZmFtaWx5OiBBcmlhbCwgc2Fucy1zZXJpZjsKICAgICAgZm9udC1zaXplOiAxcmVtOwogICAgICBsaW5lLWhlaWdodDogMS42OwogICAgICB9CgouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQoKcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0KCn0KYGBgCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IAojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikKICAgbGlicmFyeShrbml0cikKfQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpCiAgIGxpYnJhcnkocGFuZGVyKQp9CmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCiAgbGlicmFyeShnZ3Bsb3QyKQp9CmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQogIGxpYnJhcnkodGlkeXZlcnNlKQp9CgppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikKICBsaWJyYXJ5KHBsb3RseSkKfQoKaWYgKCFyZXF1aXJlKCJWR0FNIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJWR0FNIikKICBsaWJyYXJ5KFZHQU0pCn0KIyMjIyBWR0FNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIAogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLgogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BCiAgICAgICAgICAgICAgICAgICAgICApICAKYGBgCiAKIFwKIAojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIAoKPHA+CiogRW5oYW5jZSB1bmRlcnN0YW5kaW5nIHRoZSBwcm9jZWR1cmUgb2YgbGlrZWxpaG9vZC1iYXNlZCBjaGktc3F1YXJlIGh5cG90aGVzaXMgdGVzdGluZyAuCgoqIEltcGxlbWVudCB0aGUgcHJvY2VkdXJlcyBmb3IgZGV0ZWN0aW5nIG92ZXJmaXR0aW5nL3VuZGVyZml0dGluZyBpc3N1ZXMgaW4gcHJhY3RpY2FsIGFwcGxpY2F0aW9ucy4KPC9wPgoKCiMjICoqUG9saWNpZXMgb2YgVXNpbmcgQUkgVG9vbHMqKgoKPHA+CioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFBsZWFzZSBhZGhlcmUgdG8gdGhlIEFJIHRvb2wgcG9saWN5IHNwZWNpZmllZCBpbiB0aGUgY291cnNlIHN5bGxhYnVzLiBUaGUgZGlyZWN0IGNvcHlpbmcgb2YgQUktZ2VuZXJhdGVkIGNvbnRlbnQgaXMgc3RyaWN0bHkgcHJvaGliaXRlZC4gQWxsIHN1Ym1pdHRlZCB3b3JrIG11c3QgcmVmbGVjdCB5b3VyIG93biB1bmRlcnN0YW5kaW5nOyB3aGVyZSBleHRlcm5hbCB0b29scyBhcmUgY29uc3VsdGVkLCBjb250ZW50IG11c3QgYmUgdGhvcm91Z2hseSByZXBocmFzZWQgYW5kIHN5bnRoZXNpemVkIGluIHlvdXIgb3duIHdvcmRzLgo8L3A+Cgo8cD4KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuCjwvcD4KCgojIyBUZXN0aW5nIE92ZXJmaXR0aW5nL1VuZGVyZml0dGluZwoKSW4gTWFjaGluZSBMZWFybmluZyBhbmQgU3RhdGlzdGljcywgb3ZlcmZpdHRpbmcgb2NjdXJzIHdoZW4gYSBtb2RlbCBpcyB0b28gY29tcGxleCBhbmQgbGVhcm5zIG5vaXNlLCBsZWFkaW5nIHRvIHBvb3IgcGVyZm9ybWFuY2Ugb24gbmV3IGRhdGEsIHdoaWxlIHVuZGVyZml0dGluZyBoYXBwZW5zIHdoZW4gYSBtb2RlbCBpcyB0b28gc2ltcGxlIHRvIGNhcHR1cmUgaW1wb3J0YW50IHBhdHRlcm5zLCByZXN1bHRpbmcgaW4gaGlnaCBlcnJvcnMgb3ZlcmFsbDsgYm90aCBpc3N1ZXMgYXJlIGV4cGxhaW5lZCBieSB0aGUgQmlhc+KAk1ZhcmlhbmNlIFRyYWRlb2ZmIGFuZCBjYW4gY2F1c2UgdW5yZWxpYWJsZSBwcmVkaWN0aW9ucyBpbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4KCgpUaGUgcHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbiAoUERGKSBvZiB0aGUgV2VpYnVsbCBkaXN0cmlidXRpb24gaXM6CgokJApmKHQ7IFxsYW1iZGEsIFxiZXRhKSA9IFxmcmFje1xiZXRhfXtcbGFtYmRhfSBcbGVmdCggXGZyYWN7dH17XGxhbWJkYX0gXHJpZ2h0KV57XGJldGEtMX0gXGV4cFxsZWZ0WyAtXGxlZnQoIFxmcmFje3R9e1xsYW1iZGF9IFxyaWdodCleXGJldGEgXHJpZ2h0XSwgXHF1YWQgdCBcZ2UgMAokJAp3aGVyZSAkXGxhbWJkYSA+IDAkIGlzIHRoZSBzY2FsZSBwYXJhbWV0ZXIgKGNoYXJhY3RlcmlzdGljIGxpZmUpIGFuZCAkXGJldGEgPiAwJCBpcyB0aGUgc2hhcGUgcGFyYW1ldGVyLgoKV2hlbiAkXGJldGEgPSAxJCwgdGhlIFdlaWJ1bGwgUERGIHNpbXBsaWZpZXMgdG8gdGhlIGV4cG9uZW50aWFsIFBERjoKCiQkCmYodDsgXGxhbWJkYSkgPSBcZnJhY3sxfXtcbGFtYmRhfSBcZXhwXGxlZnQoIC1cZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpCiQkCndpdGggY29uc3RhbnQgaGF6YXJkIHJhdGUgJGgodCkgPSAxL1xsYW1iZGEkLgoKCjxwPjxmb250IGNvbG9yID0gImRhcmtyZWQiPioqVGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gcGVyZm9ybWluZyBhIGh5cG90aGVzaXMgdGVzdCBmb3IgdGhlIHNoYXBlIHBhcmFtZXRlciAoJFxiZXRhJCkgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIHdpdGhpbiBhIHJlbGlhYmlsaXR5IG1vZGUqKjwvZm9udD48L3A+CgoKXGJlZ2lue2FsaWdufQpIXzAmOiBcYmV0YSA9IDEgXHF1YWQgXHRleHR7KEV4cG9uZW50aWFsIG1vZGVsLCBzaW1wbGVyKX0gXFwKSF8xJjogXGJldGEgXG5lcSAxIFxxdWFkIFx0ZXh0eyhXZWlidWxsIG1vZGVsLCBtb3JlIGNvbXBsZXgpfQpcZW5ke2FsaWdufQoKClwKCiMjICoqUXVlc3Rpb246IFJlbGlhYmlsaXR5IEFwcGxpY2F0aW9uKioKCjxwPgpBIG1pZC1zaXplZCBtYW51ZmFjdHVyaW5nIGNvbXBhbnkgcHJvZHVjaW5nIGluZHVzdHJpYWwgY29udmV5b3Igc3lzdGVtcyBiZWdhbiBleHBlcmllbmNpbmcgdW5leHBlY3RlZCBkb3dudGltZSBpbiBvbmUgb2YgaXRzIGRpc3RyaWJ1dGlvbiBmYWNpbGl0aWVzLCBwcm9tcHRpbmcgY29uY2VybiBhYm91dCB0aGUgcmVsaWFiaWxpdHkgb2YgYSBuZXdseSBzb3VyY2VkIGJhdGNoIG9mIGJhbGwgYmVhcmluZ3MgdXNlZCBpbiB0aGUgbW90b3IgYXNzZW1ibGllcy4gVGhlc2UgYmVhcmluZ3MsIHN1cHBsaWVkIGJ5IGEgdmVuZG9yIGFkb3B0aW5nIGNvc3Qtc2F2aW5nIHByb2R1Y3Rpb24gbWV0aG9kcywgd2VyZSBpbnN0YWxsZWQgYWNyb3NzIG11bHRpcGxlIHVuaXRzIG9wZXJhdGluZyB1bmRlciBjb250aW51b3VzIGxvYWQgY29uZGl0aW9ucy4gQWZ0ZXIgc2V2ZXJhbCBtb250aHMsIG1haW50ZW5hbmNlIGxvZ3MgcmV2ZWFsZWQgYSBwYXR0ZXJuIG9mIGluY3JlYXNpbmcgZmFpbHVyZXMsIHdpdGggY29tcG9uZW50cyBsYXN0aW5nIGFueXdoZXJlIGZyb20gYSBmZXcgZG96ZW4gdG8gb3ZlciAxNTAgaG91cnMgYmVmb3JlIGJyZWFrZG93bi4gVG8gaW52ZXN0aWdhdGUsIHRoZSBlbmdpbmVlcmluZyB0ZWFtIGNvbGxlY3RlZCB0aW1lLXRvLWZhaWx1cmUgZGF0YSBmcm9tIDUwIGlkZW50aWNhbCBiZWFyaW5ncyBhbmQgY29uZHVjdGVkIGEgV2VpYnVsbCBhbmFseXNpcyB3aXRoaW4gdGhlIGZyYW1ld29yayBvZiBSZWxpYWJpbGl0eSBFbmdpbmVlcmluZy4gVGhlIDUwIHRpbWUtdG8tZmFpbHVyZSAoc3Vydml2YWwgdGltZSkgYXJlOgoKYGBgCjEyLjQsIDE4LjcsIDI1LjMsIDMwLjEsIDMzLjUsIDM1LjIsIDM4LjksIDQwLjMsIDQyLjcsIDQ1LjEsIDQ3LjYsIDQ5LjgsIDUyLjQsIDU1LjAsIAo1Ny4zLCA2MC4yLCA2Mi44LCA2NS4xLCA2Ny45LCA3MC41LCA3Mi4zLCA3NS42LCA3OC4yLCA4MC45LCA4My40LCA4NS43LCA4OC4xLCA5MC42LCAKOTMuMiwgOTUuOCwgOTguNCwgMTAxLjAsIDEwNC41LCAxMDcuMywgMTEwLjYsIDExMy4yLCAxMTYuOCwgMTIwLjEsIDEyMy43LCAxMjcuNCwKMTMwLjksIDEzNC41LCAxMzguMiwgMTQyLjAsIDE0Ni4zLCAxNTAuNywgMTU1LjIsIDE2MC44LCAxNjguNCwgMTc1LjkKYGBgCgpgYGB7cn0KIyBTdG9yZSB0aGUgNTAgZmFpbHVyZSB0aW1lcyBhcyBhIG51bWVyaWMgdmVjdG9yIGZvciBhbmFseXNpcwp0aW1lIDwtIGMoCiAgMTIuNCwgMTguNywgMjUuMywgMzAuMSwgMzMuNSwgMzUuMiwgMzguOSwgNDAuMywgNDIuNywgNDUuMSwKICA0Ny42LCA0OS44LCA1Mi40LCA1NS4wLCA1Ny4zLCA2MC4yLCA2Mi44LCA2NS4xLCA2Ny45LCA3MC41LAogIDcyLjMsIDc1LjYsIDc4LjIsIDgwLjksIDgzLjQsIDg1LjcsIDg4LjEsIDkwLjYsIDkzLjIsIDk1LjgsCiAgOTguNCwgMTAxLjAsIDEwNC41LCAxMDcuMywgMTEwLjYsIDExMy4yLCAxMTYuOCwgMTIwLjEsIDEyMy43LCAxMjcuNCwKICAxMzAuOSwgMTM0LjUsIDEzOC4yLCAxNDIuMCwgMTQ2LjMsIDE1MC43LCAxNTUuMiwgMTYwLjgsIDE2OC40LCAxNzUuOQopCmBgYAoKPC9wPgoKVGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gaHlwb3RoZXNpcyAkSF8wOiBcYmV0YSA9IDEkIChleHBvbmVudGlhbCkgYWdhaW5zdCAkSF8xOiBcYmV0YSBcbmVxIDEkIChXZWlidWxsKS4gVGhpcyBmcmFtZXdvcmsgZGV0ZWN0cyBvdmVyZml0dGluZyAoZml0dGluZyBhIFdlaWJ1bGwgd2hlbiBleHBvbmVudGlhbCBpcyB0cnVlKSBhbmQgdW5kZXJmaXR0aW5nIChmaXR0aW5nIGV4cG9uZW50aWFsIHdoZW4gV2VpYnVsbCB3aXRoICRcYmV0YSBcbmVxIDEkIGlzIHRydWUpLiAKCgo8cD4KYSkuIEZpbmQgdGhlIE1MRSBvZiB0aGUgV2VpYnVsbCBwYXJhbWV0ZXJzICRcbGFtYmRhJCAoc2NhbGUpIGFuZCAkXGJldGEkIChzaGFwZSksIGRlbm90ZWQgYnkgJFxoYXR7XGxhbWJkYX0kIGFuZCAkXGhhdHtcYmV0YX0kLCByZXNwZWN0aXZlbHksIHVzaW5nIHRoZSBgb3B0aW0oKWAgcHJvY2VkdXJlLiBbKkhpbnQ6IFlvdSBzaG91bGQgcHJvdmlkZSBleHBsaWNpdCBleHByZXNzaW9ucyBmb3IgdGhlIGxvZy1saWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIHBhcmFtZXRlcnMuKl0KCmBgYHtyfQojIERlZmluZSB0aGUgV2VpYnVsbCBsb2ctbGlrZWxpaG9vZCBmb3IgKGxhbWJkYSwgYmV0YSkKd2VpYnVsbF9sb2dsaWsgPC0gZnVuY3Rpb24ocGFyLCB4KSB7CiAgbGFtYmRhIDwtIHBhclsxXQogIGJldGEgPC0gcGFyWzJdCiAgCiAgIyBSZXN0cmljdCBwYXJhbWV0ZXJzIHRvIHBvc2l0aXZlIHZhbHVlcwogIGlmIChsYW1iZGEgPD0gMCB8fCBiZXRhIDw9IDApIHJldHVybigtSW5mKQogIAogIG4gPC0gbGVuZ3RoKHgpCiAgCiAgbiAqIGxvZyhiZXRhKSAtCiAgICBuICogYmV0YSAqIGxvZyhsYW1iZGEpICsKICAgIChiZXRhIC0gMSkgKiBzdW0obG9nKHgpKSAtCiAgICBzdW0oKHggLyBsYW1iZGEpXmJldGEpCn0KCiMgRGVmaW5lIHRoZSBncmFkaWVudCBmb3IgZmFzdGVyIG9wdGltaXphdGlvbgp3ZWlidWxsX2dyYWQgPC0gZnVuY3Rpb24ocGFyLCB4KSB7CiAgbGFtYmRhIDwtIHBhclsxXQogIGJldGEgPC0gcGFyWzJdCiAgbiA8LSBsZW5ndGgoeCkKICAKICAjIFJlcGVhdGVkIHRlcm0gaW4gZGVyaXZhdGl2ZXMKICBzIDwtICh4IC8gbGFtYmRhKV5iZXRhCiAgCiAgZF9sYW1iZGEgPC0gKGJldGEgLyBsYW1iZGEpICogKHN1bShzKSAtIG4pCiAgZF9iZXRhIDwtIG4gLyBiZXRhIC0gbiAqIGxvZyhsYW1iZGEpICsgc3VtKGxvZyh4KSkgLQogICAgc3VtKHMgKiBsb2coeCAvIGxhbWJkYSkpCiAgCiAgYyhkX2xhbWJkYSwgZF9iZXRhKQp9CmBgYAoKYGBge3J9CiMgVXNlIG9wdGltKCkgdG8gbWF4aW1pemUgdGhlIGxvZy1saWtlbGlob29kIG51bWVyaWNhbGx5CmZpdF93ZWlidWxsIDwtIG9wdGltKAogIHBhciA9IGMobWVhbih0aW1lKSwgMS41KSwgICAjIHN0YXJ0aW5nIHZhbHVlcwogIGZuID0gZnVuY3Rpb24ocGFyLCB4KSAtd2VpYnVsbF9sb2dsaWsocGFyLCB4KSwgICMgbWluaW1pemUgbmVnYXRpdmUgbG9nLWxpa2VsaWhvb2QKICBnciA9IGZ1bmN0aW9uKHBhciwgeCkgLXdlaWJ1bGxfZ3JhZChwYXIsIHgpLCAgICAjIG5lZ2F0aXZlIGdyYWRpZW50CiAgeCA9IHRpbWUsCiAgbWV0aG9kID0gIkJGR1MiLAogIGhlc3NpYW4gPSBUUlVFCikKCiMgRXh0cmFjdCBNTEUgZXN0aW1hdGVzCmZpdF93ZWlidWxsJHBhcgpgYGAKClVzaW5nIHRoZSBgb3B0aW0oKWAgcHJvY2VkdXJlIHRvIG1heGltaXplIHRoZSBXZWlidWxsIGxvZy1saWtlbGlob29kLCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlcyBhcmUgJFxoYXR7XGxhbWJkYX0gPSA5OC45OTI3NDUkIGFuZCAkXGhhdHtcYmV0YX0gPSAyLjIwNTY3NiQuCgpiKS4gRmluZCB0aGUgTUxFIG9mIHRoZSBleHBvbmVudGlhbCBwYXJhbWV0ZXIgJFxsYW1iZGEkIChzY2FsZSksIGRlbm90ZWQgYnkgJFxoYXR7XGxhbWJkYX0kLCB1c2luZyBhbnkgcHJvY2VkdXJlLiBbKkhpbnQ6IFlvdSBzaG91bGQgcHJvdmlkZSBleHBsaWNpdCBleHByZXNzaW9ucyBmb3IgdGhlIGxvZy1saWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgb2YgdGhlIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzLipdCgpGb3IgdGhlIGV4cG9uZW50aWFsIG1vZGVsLCB0aGUgbG9nLWxpa2VsaWhvb2QgaXMgJFxlbGwoXGxhbWJkYSkgPSAtbiBcbG9nIFxsYW1iZGEgLSBcZnJhY3sxfXtcbGFtYmRhfSBcc3VtX3tpPTF9Xm4gdF9pJC4KClRoZSBncmFkaWVudCBpcyAkXGZyYWN7ZFxlbGx9e2RcbGFtYmRhfSA9IC1cZnJhY3tufXtcbGFtYmRhfSArIFxmcmFjezF9e1xsYW1iZGFeMn0gXHN1bV97aT0xfV5uIHRfaSQuCgpTZXR0aW5nIHRoZSBkZXJpdmF0aXZlIGVxdWFsIHRvIHplcm8gZ2l2ZXMgJFxoYXR7XGxhbWJkYX0gPSBcYmFye3R9JC4KCmBgYHtyfQojIERlZmluZSB0aGUgZXhwb25lbnRpYWwgbG9nLWxpa2VsaWhvb2QgZm9yIGxhbWJkYQpleHBfbG9nbGlrIDwtIGZ1bmN0aW9uKGxhbWJkYSwgeCkgewogIG4gPC0gbGVuZ3RoKHgpCiAgLW4gKiBsb2cobGFtYmRhKSAtIHN1bSh4KSAvIGxhbWJkYQp9CgojIERlZmluZSB0aGUgZ3JhZGllbnQgb2YgdGhlIGV4cG9uZW50aWFsIGxvZy1saWtlbGlob29kCmV4cF9ncmFkIDwtIGZ1bmN0aW9uKGxhbWJkYSwgeCkgewogIG4gPC0gbGVuZ3RoKHgpCiAgLW4gLyBsYW1iZGEgKyBzdW0oeCkgLyBsYW1iZGFeMgp9CgojIENvbXB1dGUgdGhlIGV4cG9uZW50aWFsIE1MRSB1c2luZyB0aGUgc2FtcGxlIG1lYW4KbGFtYmRhX2hhdF9leHAgPC0gbWVhbih0aW1lKQoKbGFtYmRhX2hhdF9leHAKYGBgCgpVc2luZyB0aGUgc2FtcGxlIG1lYW4sIHRoZSBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGUgaXMgJFxoYXR7XGxhbWJkYX0gPSA4Ny42MSQuCgpjKS4gUGVyZm9ybSB0aGUgbGlrZWxpaG9vZCByYXRpbyAkXGNoaV4yJCB0ZXN0IG9uICRcYmV0YSA9IDEkLiBXaGF0IGlzIHRoZSBwLXZhbHVlPyBbKkhpbnQ6IFVzZSB0aGUgcmVzdWx0cyBpbiBhKSBhbmQgYikqLl0gCgpUaGUgbGlrZWxpaG9vZCByYXRpbyBzdGF0aXN0aWMgaXMgJExSID0gMlxsZWZ0W1xlbGwoXGhhdHtcbGFtYmRhfSwgXGhhdHtcYmV0YX0pIC0gXGVsbChcaGF0e1xsYW1iZGF9XzAsIDEpXHJpZ2h0XSQuCgpgYGB7cn0KIyBDb21wdXRlIGxvZy1saWtlbGlob29kIGZvciBXZWlidWxsIChmdWxsIG1vZGVsKQpsb2dsaWtfd2VpYnVsbCA8LSB3ZWlidWxsX2xvZ2xpayhmaXRfd2VpYnVsbCRwYXIsIHRpbWUpCgojIENvbXB1dGUgbG9nLWxpa2VsaWhvb2QgZm9yIGV4cG9uZW50aWFsIChyZXN0cmljdGVkIG1vZGVsLCBiZXRhID0gMSkKbGFtYmRhX2hhdF9leHAgPC0gbWVhbih0aW1lKQpuIDwtIGxlbmd0aCh0aW1lKQoKbG9nbGlrX2V4cCA8LSAtbiAqIGxvZyhsYW1iZGFfaGF0X2V4cCkgLSBzdW0odGltZSkgLyBsYW1iZGFfaGF0X2V4cAoKIyBDb21wdXRlIGxpa2VsaWhvb2QgcmF0aW8gc3RhdGlzdGljCkxSIDwtIDIgKiAobG9nbGlrX3dlaWJ1bGwgLSBsb2dsaWtfZXhwKQoKIyBDb21wdXRlIHAtdmFsdWUgZnJvbSBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbiB3aXRoIDEgZGYKcF92YWx1ZV9MUiA8LSBwY2hpc3EoTFIsIGRmID0gMSwgbG93ZXIudGFpbCA9IEZBTFNFKQoKTFIKcF92YWx1ZV9MUgpgYGAKClRoZSBsaWtlbGlob29kIHJhdGlvIHN0YXRpc3RpYyBpcyAkTFIgPSAzNC40NDk5NCQuIFRoZSBjb3JyZXNwb25kaW5nIHAtdmFsdWUgaXMgYXBwcm94aW1hdGVseSAkNC4zNzM1NjkgXHRpbWVzIDEwXnstOX0kLgoKZCkuIFBlcmZvcm0gdGhlIFdhbGQgJFxjaGleMiQgb24gdGhlIHNhbWUgaHlwb3RoZXNpcyAkXGJldGEgPSAxJC4gV2hhdCBpcyB0aGUgcC12YWx1ZT8gWypIaW50OiBZb3UgbmVlZCB0byBmaW5kIHRoZSBvYnNlcnZlZCBGaXNoZXIgaW5mb3JtYXRpb24gbWF0cml4IChpLmUuLCB0aGUgbmVnYXRpdmUgSGVzc2lhbiBtYXRyaXggZnJvbSBgb3B0aW0oKWApIGJhc2VkIG9uIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbi4gVGhlIGludmVyc2Ugb2YgdGhlIDxmb250IGNvbG9yID0gImJsdWUiPm5lZ2F0aXZlPC9mb250PiBvYnNlcnZlZCBIZXNzaWFuIG1hdHJpeCBpcyB0aGUgY292YXJpYW5jZSBtYXRyaXgqLl0gCgpUaGUgV2FsZCBzdGF0aXN0aWMgZm9yIHRlc3RpbmcgJEhfMDpcYmV0YSA9IDEkIGlzICRXID0gXGRmcmFjeyhcaGF0e1xiZXRhfSAtIDEpXjJ9e1x3aWRlaGF0e1xtYXRocm17VmFyfX0oXGhhdHtcYmV0YX0pfSQuCgpgYGB7cn0KIyBFeHRyYWN0IHRoZSBIZXNzaWFuIGZyb20gdGhlIFdlaWJ1bGwgZml0CmluZm9fd2VpYnVsbCA8LSBmaXRfd2VpYnVsbCRoZXNzaWFuCgojIEludmVydCB0aGUgSGVzc2lhbiB0byBnZXQgdGhlIGNvdmFyaWFuY2UgbWF0cml4CmNvdl93ZWlidWxsIDwtIHNvbHZlKGluZm9fd2VpYnVsbCkKCiMgRXh0cmFjdCB0aGUgV2VpYnVsbCBlc3RpbWF0ZSBhbmQgaXRzIHZhcmlhbmNlCmJldGFfaGF0IDwtIGZpdF93ZWlidWxsJHBhclsyXQp2YXJfYmV0YV9oYXQgPC0gY292X3dlaWJ1bGxbMiwgMl0KCiMgQ29tcHV0ZSB0aGUgV2FsZCBjaGktc3F1YXJlIHN0YXRpc3RpYwpXIDwtIChiZXRhX2hhdCAtIDEpXjIgLyB2YXJfYmV0YV9oYXQKCiMgQ29tcHV0ZSB0aGUgcC12YWx1ZSB1c2luZyBhIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uIHdpdGggMSBkZgpwX3ZhbHVlX1cgPC0gcGNoaXNxKFcsIGRmID0gMSwgbG93ZXIudGFpbCA9IEZBTFNFKQoKVwpwX3ZhbHVlX1cKYGBgCgpUaGUgV2FsZCBzdGF0aXN0aWMgaXMgJFcgPSAyMy4xMDI2NyQuIFRoZSBjb3JyZXNwb25kaW5nIHAtdmFsdWUgaXMgJDEuNTM1Nzc3IFx0aW1lcyAxMF57LTZ9JC4KCmUpLiBXcml0ZSBhIHN1bW1hcnkgb2YgdGhlIGFib3ZlIGFuYWx5c2VzIHRvIGFkZHJlc3MgdGhlIGZvbGxvd2luZzoKCiogV2hldGhlciB0aGUgdHdvIHRlc3RzIGdlbmVyYXRlZCB0aGUgc2FtZSByZXN1bHRzLgoKKiBXaGljaCBtb2RlbCBpcyByZWNvbW1lbmRlZCBmb3IgdGhlIGRhdGEuCgoqIERyYXcgdGhlIGRlbnNpdHkgY3VydmUgYmFzZWQgb24gdGhlIE1MRShzKSBvZiB0aGUgcGFyYW1ldGVyKHMpIGFuZCBkZXNjcmliZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB0aW1lLXRvLWZhaWx1cmUuCgpCb3RoIHRoZSBsaWtlbGlob29kIHJhdGlvIHRlc3QgYW5kIHRoZSBXYWxkIHRlc3QgZ2VuZXJhdGUgdGhlIHNhbWUgcmVzdWx0LiBUaGUgbGlrZWxpaG9vZCByYXRpbyB0ZXN0IGdhdmUgYSBwLXZhbHVlIG9mICQ0LjM3MzU2OSBcdGltZXMgMTBeey05fSQsIGFuZCB0aGUgV2FsZCB0ZXN0IGdhdmUgYSBwLXZhbHVlIG9mICQxLjUzNTc3NyBcdGltZXMgMTBeey02fSQuIEJvdGggcC12YWx1ZXMgYXJlIGV4dHJlbWVseSBzbWFsbCBhbmQgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIFdlIGhhdmUgZW5vdWdoIGV2aWRlbmNlIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzICRIXzA6IFxiZXRhID0gMSQuCgpUaGUgbnVsbCBoeXBvdGhlc2lzIHJlcHJlc2VudHMgdGhlIGV4cG9uZW50aWFsIG1vZGVsLCBzbyByZWplY3RpbmcgJEhfMCQgbWVhbnMgdGhhdCB0aGUgZXhwb25lbnRpYWwgbW9kZWwgZG9lcyBub3QgZml0IHRoaXMgZGF0YSB3ZWxsLiBCZWNhdXNlIG9mIHRoaXMsIHRoZSBXZWlidWxsIG1vZGVsIGlzIGEgYmV0dGVyIGNob2ljZSBmb3IgbW9kZWxpbmcgdGhlIHRpbWUtdG8tZmFpbHVyZSBkYXRhLgoKCmBgYHtyfQojIERyYXcgdGhlIGZpdHRlZCBXZWlidWxsIGRlbnNpdHkgdXNpbmcgdGhlIE1MRXMgZnJvbSBwYXJ0IChhKQpjdXJ2ZSgKICBkd2VpYnVsbCh4LCBzaGFwZSA9IGZpdF93ZWlidWxsJHBhclsyXSwgc2NhbGUgPSBmaXRfd2VpYnVsbCRwYXJbMV0pLAogIGZyb20gPSAwLCB0byA9IDIwMCwKICBsd2QgPSAyLAogIHhsYWIgPSAiVGltZSB0byBmYWlsdXJlIiwKICB5bGFiID0gIkRlbnNpdHkiLAogIG1haW4gPSAiRml0dGVkIFdlaWJ1bGwgRGVuc2l0eSIKKQpgYGAKClVzaW5nIHRoZSBNTEVzIGZyb20gcGFydCAoYSksIHRoZSBmaXR0ZWQgV2VpYnVsbCBkZW5zaXR5IGlzIHVuaW1vZGFsIGFuZCByaWdodC1za2V3ZWQuIFRoZSBlc3RpbWF0ZWQgV2VpYnVsbCBzaGFwZSBwYXJhbWV0ZXIgaXMgJFxoYXR7XGJldGF9ID0gMi4yMDU2NzYkLCB3aGljaCBpcyBncmVhdGVyIHRoYW4gMS4gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBmYWlsdXJlIHJhdGUgaXMgbm90IGNvbnN0YW50LCBidXQgaW5zdGVhZCBpbmNyZWFzZXMgYXMgdGltZSBnb2VzIG9uLiBUaGUgZml0dGVkIFdlaWJ1bGwgZGVuc2l0eSBzaG93cyB0aGF0IGxhcmdlciB0aW1lIHZhbHVlcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGEgaGlnaGVyIGNvbmNlbnRyYXRpb24gb2YgZmFpbHVyZXMuIEJhc2VkIG9uIG91ciBvYnNlcnZhdGlvbiwgdGhpcyBpcyBjb25zaXN0ZW50IHdpdGggd2Vhci1vdXQgZmFpbHVyZSBpbiByZWxpYWJpbGl0eSBhbmFseXNpcy4gQ29tcG9uZW50cyB0ZW5kIHRvIHdlYWtlbiBvdmVyIHRpbWUsIHNvIHRoZSBsb25nZXIgdGhleSBhcmUgaW4gdXNlLCB0aGUgbW9yZSBsaWtlbHkgdGhleSBhcmUgdG8gZXhwZXJpZW5jZSBmYWlsdXJlLgoKPC9wPgoKCgo=