Log-normal Distribution Revisited

If \(Y = \ln(X) \sim N(\mu, \sigma^2)\), then \(X\) follows a lognormal distribution \(X \sim \text{Lognormal}(\mu, \sigma^2)\). The probability density is given by

\[ f(x|\mu,\sigma) = \frac{1}{x\sigma\sqrt{2\pi}} \exp\left(-\frac{(\ln x - \mu)^2}{2\sigma^2}\right), \quad x > 0 \]

After some algebra, we can express the mean and variance of the above lognormal distribution in the following

\[ \begin{align} \mathbb{E}[X] &= \exp\left(\mu + \frac{\sigma^2}{2}\right) \\ \text{Var}(X) &= [\exp(\sigma^2) - 1] \exp(2\mu + \sigma^2) \end{align} \]

Using the relationship between normal and log-normal distribution and a sample \(\{x_1, x_2, \dots, x_n\}\), the MLE estimators of \(\mu\) and \(\sigma^2\) are given by

\[ \begin{align} \hat{\mu} &= \frac{1}{n}\sum_{i=1}^n \ln(x_i) \\ \hat{\sigma}^2 &= \frac{1}{n}\sum_{i=1}^n (\ln(x_i) - \hat{\mu})^2 \end{align} \]

Using the plug-in principle of MLE, we have the MLE of \(\mathbb{E}[X]\) and \(\text{Var}(X)\) in the following

\[ \boxed{\widehat{\mathbb{E}[X]} = \exp\left(\hat{\mu} + \frac{\hat{\sigma}^2}{2}\right)} \]

This assignment focuses on constructing various bootstrap confidence intervals of the lognormal population mean \(\mathbb{E}[X]\)


Question: Trace Metal Concentrations in Soil

Soil lead (Pb) concentrations (mg/kg) from 55 urban garden sites. Trace metals in environmental media typically follow lognormal distributions due to:

  • Multiplicative processes controlling accumulation

  • Positive constraints (concentrations cannot be negative)

  • Right-skewed nature of contamination patterns

0.85, 1.23, 0.92, 3.45, 2.11, 1.56, 4.89, 2.34, 1.78, 6.72, 0.95, 1.34, 8.91, 
2.67, 1.89, 5.43, 1.12, 3.78, 2.45, 7.65, 1.05, 1.45, 12.34, 2.89, 2.01, 4.56, 
1.23, 4.32, 2.67, 9.87, 0.99, 1.56, 15.23, 3.12, 2.34, 3.89, 1.34, 5.67, 2.89, 
11.45, 1.12, 1.67, 18.90, 3.45, 2.56, 3.45, 1.45, 6.78, 3.12, 14.56, 1.23, 1.78, 
22.34, 3.78, 2.78

Assuming the data follow a log-normal distribution. For each of the following questions, first describe your reasoning process for the analysis, then write code to perform the actual analysis. Finally, summarize the results to conclude the question.

a). Perform 5000 bootstrap samples to estimate the bootstrap sampling distribution of \(\boxed{\widehat{\mathbb{E}[X]}}\) and plot it as either a histogram or a kernel density curve. Comment on the shape and patterns observed in the bootstrap sampling distribution.

# Soil lead concentration data (mg/kg)
x <- c(
  0.85, 1.23, 0.92, 3.45, 2.11, 1.56, 4.89, 2.34, 1.78, 6.72, 0.95, 1.34, 8.91, 
  2.67, 1.89, 5.43, 1.12, 3.78, 2.45, 7.65, 1.05, 1.45, 12.34, 2.89, 2.01, 4.56, 
  1.23, 4.32, 2.67, 9.87, 0.99, 1.56, 15.23, 3.12, 2.34, 3.89, 1.34, 5.67, 2.89, 
  11.45, 1.12, 1.67, 18.90, 3.45, 2.56, 3.45, 1.45, 6.78, 3.12, 14.56, 1.23, 1.78, 
  22.34, 3.78, 2.78
)

n <- length(x)

# Function to compute the MLE of E[X] under lognormal model
lognormal.mean.mle <- function(x){
  
  # MLE of mu based on log-transformed data
  mu_hat <- mean(log(x))
  
  # MLE of sigma^2 (denominator n)
  sigma2_hat <- mean((log(x) - mu_hat)^2)
  
  # Plug-in MLE of E[X]
  EX_hat <- exp(mu_hat + sigma2_hat / 2)
  
  return(EX_hat)
}

# MLE from original sample
theta_hat <- lognormal.mean.mle(x)

# Bootstrap sampling distribution
set.seed(123)
B <- 5000
boot_mean <- NULL

for(b in 1:B){
  
  # Draw one bootstrap sample
  boot_sample <- sample(x, size = n, replace = TRUE)
  
  # Compute bootstrap MLE of E[X]
  boot_mean[b] <- lognormal.mean.mle(boot_sample)
}

# One clean output box
data.frame(
  theta_hat = theta_hat,
  boot_mean_avg = mean(boot_mean),
  boot_sd = sd(boot_mean)
)
  theta_hat boot_mean_avg   boot_sd
1  4.218099      4.231785 0.6420592
# Histogram and kernel density estimate of bootstrap distribution
hist(boot_mean,
     probability = TRUE,
     breaks = 20,
     main = "Bootstrap Sampling Distribution of MLE of E[X]",
     xlab = expression(hat(E[X])))

lines(density(boot_mean), col = "blue", lwd = 2)

Answer: The bootstrap sampling distribution of \(\widehat{\mathbb{E}[X]}\)is unimodal and slightly right-skewed. This is reasonable because the original soil concentration data are right-skewed, and the estimated lognormal mean is influenced by larger values in the sample. The distribution is still fairly smooth because the sample size is moderate and the number of bootstrap samples is large.

  1. Construct a 95% bootstrap percentile confidence interval for \(\mathbb{E}[X]\).
# 95% percentile bootstrap confidence interval
alpha <- 0.05

ci_perc <- quantile(boot_mean, probs = c(alpha/2, 1 - alpha/2))

data.frame(
  lower_percentile = ci_perc[1],
  upper_percentile = ci_perc[2]
)
     lower_percentile upper_percentile
2.5%          3.09388         5.643249
  1. Construct a 95% bootstrap BCa confidence interval for \(\mathbb{E}[X]\).
library(boot)

# Statistic function for boot()
lognormal.mean.stat <- function(data, indices){
  sample_data <- data[indices]
  lognormal.mean.mle(sample_data)
}

# Run bootstrap using boot package
set.seed(123)
boot_result <- boot(x, statistic = lognormal.mean.stat, R = 5000)

# BCa confidence interval
bca_result <- boot.ci(boot_result, type = "bca")
bca_result
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 5000 bootstrap replicates

CALL : 
boot.ci(boot.out = boot_result, type = "bca")

Intervals : 
Level       BCa          
95%   ( 3.225,  5.865 )  
Calculations and Intervals on Original Scale
  1. Assuming both confidence intervals above are valid, compare them in terms of performance and recommend which method should be used in this analysis. Justify your recommendation.

# Percentile CI using boot package for direct comparison
perc_result <- boot.ci(boot_result, type = "perc")
perc_result
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 5000 bootstrap replicates

CALL : 
boot.ci(boot.out = boot_result, type = "perc")

Intervals : 
Level     Percentile     
95%   ( 3.097,  5.598 )  
Calculations and Intervals on Original Scale

Answer:

Both intervals are valid bootstrap confidence intervals, but the percentile CI is simple and easy to interpret and the BCa CI is more refined because it corrects for bias and skewness. Since the bootstrap distribution of \(\widehat{\mathbb{E}[X]}\)is slightly right-skewed, I would recommend using the BCa confidence interval in this analysis. It is better suited for skewed distributions and usually provides more accurate coverage than the percentile method.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNzogQm9vdHN0cmFwIE1ldGhvZHMgYW5kIEFwcGxpY2F0aW9ucyINCmF1dGhvcjogIlhpYW95aW5nIE1hICINCmRhdGU6ICIgRHVlOiAwMy8zMS8yMDI2ICINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7YmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjsNCiAgICAgIGNvbG9yOiAjMDAwMDAwOw0KICAgICAgZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOw0KICAgICAgZm9udC1zaXplOiAxcmVtOw0KICAgICAgbGluZS1oZWlnaHQ6IDEuNjsNCiAgICAgIH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJWR0FNIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiVkdBTSIpDQogIGxpYnJhcnkoVkdBTSkNCn0NCiMjIyMgVkdBTQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQo8cD4qKkxvZy1ub3JtYWwgRGlzdHJpYnV0aW9uIFJldmlzaXRlZCoqPC9wPg0KDQo8cD4NCklmICRZID0gXGxuKFgpIFxzaW0gTihcbXUsIFxzaWdtYV4yKSQsIHRoZW4gJFgkIGZvbGxvd3MgYSBsb2dub3JtYWwgZGlzdHJpYnV0aW9uICRYIFxzaW0gXHRleHR7TG9nbm9ybWFsfShcbXUsIFxzaWdtYV4yKSQuIFRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGlzIGdpdmVuIGJ5DQoNCiQkDQpmKHh8XG11LFxzaWdtYSkgPSBcZnJhY3sxfXt4XHNpZ21hXHNxcnR7MlxwaX19IFxleHBcbGVmdCgtXGZyYWN7KFxsbiB4IC0gXG11KV4yfXsyXHNpZ21hXjJ9XHJpZ2h0KSwgXHF1YWQgeCA+IDANCiQkDQoNCkFmdGVyIHNvbWUgYWxnZWJyYSwgd2UgY2FuIGV4cHJlc3MgdGhlIG1lYW4gYW5kIHZhcmlhbmNlIG9mIHRoZSBhYm92ZSBsb2dub3JtYWwgZGlzdHJpYnV0aW9uIGluIHRoZSBmb2xsb3dpbmcNCg0KJCQNClxiZWdpbnthbGlnbn0NClxtYXRoYmJ7RX1bWF0gJj0gXGV4cFxsZWZ0KFxtdSArIFxmcmFje1xzaWdtYV4yfXsyfVxyaWdodCkgXFwNClx0ZXh0e1Zhcn0oWCkgJj0gW1xleHAoXHNpZ21hXjIpIC0gMV0gXGV4cCgyXG11ICsgXHNpZ21hXjIpDQpcZW5ke2FsaWdufQ0KJCQNCg0KVXNpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG5vcm1hbCBhbmQgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24gYW5kIGEgc2FtcGxlICRce3hfMSwgeF8yLCBcZG90cywgeF9uXH0kLCB0aGUgTUxFIGVzdGltYXRvcnMgb2YgJFxtdSQgYW5kICRcc2lnbWFeMiQgYXJlIGdpdmVuIGJ5DQoNCiQkDQpcYmVnaW57YWxpZ259DQpcaGF0e1xtdX0gJj0gXGZyYWN7MX17bn1cc3VtX3tpPTF9Xm4gXGxuKHhfaSkgXFwNClxoYXR7XHNpZ21hfV4yICY9IFxmcmFjezF9e259XHN1bV97aT0xfV5uIChcbG4oeF9pKSAtIFxoYXR7XG11fSleMg0KXGVuZHthbGlnbn0NCiQkDQoNClVzaW5nIHRoZSBwbHVnLWluIHByaW5jaXBsZSBvZiBNTEUsIHdlIGhhdmUgdGhlIE1MRSBvZiAkXG1hdGhiYntFfVtYXSQgYW5kICRcdGV4dHtWYXJ9KFgpJCBpbiB0aGUgZm9sbG93aW5nDQoNCiQkDQpcYm94ZWR7XHdpZGVoYXR7XG1hdGhiYntFfVtYXX0gPSBcZXhwXGxlZnQoXGhhdHtcbXV9ICsgXGZyYWN7XGhhdHtcc2lnbWF9XjJ9ezJ9XHJpZ2h0KX0NCiQkDQoNCjwvUD4NCg0KDQoNCjxwPjxmb250IGNvbG9yID0gImJsdWUiPioqVGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gY29uc3RydWN0aW5nIHZhcmlvdXMgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIG9mIHRoZSBsb2dub3JtYWwgcG9wdWxhdGlvbiBtZWFuICRcbWF0aGJie0V9W1hdJCoqPC9mb250PjwvcD4NCg0KDQpcDQoNCiMjICoqUXVlc3Rpb246IFRyYWNlIE1ldGFsIENvbmNlbnRyYXRpb25zIGluIFNvaWwqKg0KDQo8cD4NClNvaWwgbGVhZCAoUGIpIGNvbmNlbnRyYXRpb25zIChtZy9rZykgZnJvbSA1NSB1cmJhbiBnYXJkZW4gc2l0ZXMuIFRyYWNlIG1ldGFscyBpbiBlbnZpcm9ubWVudGFsIG1lZGlhIHR5cGljYWxseSBmb2xsb3cgbG9nbm9ybWFsIGRpc3RyaWJ1dGlvbnMgZHVlIHRvOg0KDQoqIE11bHRpcGxpY2F0aXZlIHByb2Nlc3NlcyBjb250cm9sbGluZyBhY2N1bXVsYXRpb24NCg0KKiBQb3NpdGl2ZSBjb25zdHJhaW50cyAoY29uY2VudHJhdGlvbnMgY2Fubm90IGJlIG5lZ2F0aXZlKQ0KDQoqIFJpZ2h0LXNrZXdlZCBuYXR1cmUgb2YgY29udGFtaW5hdGlvbiBwYXR0ZXJucw0KPC9wPg0KDQo8cD4NCmBgYA0KMC44NSwgMS4yMywgMC45MiwgMy40NSwgMi4xMSwgMS41NiwgNC44OSwgMi4zNCwgMS43OCwgNi43MiwgMC45NSwgMS4zNCwgOC45MSwgDQoyLjY3LCAxLjg5LCA1LjQzLCAxLjEyLCAzLjc4LCAyLjQ1LCA3LjY1LCAxLjA1LCAxLjQ1LCAxMi4zNCwgMi44OSwgMi4wMSwgNC41NiwgDQoxLjIzLCA0LjMyLCAyLjY3LCA5Ljg3LCAwLjk5LCAxLjU2LCAxNS4yMywgMy4xMiwgMi4zNCwgMy44OSwgMS4zNCwgNS42NywgMi44OSwgDQoxMS40NSwgMS4xMiwgMS42NywgMTguOTAsIDMuNDUsIDIuNTYsIDMuNDUsIDEuNDUsIDYuNzgsIDMuMTIsIDE0LjU2LCAxLjIzLCAxLjc4LCANCjIyLjM0LCAzLjc4LCAyLjc4DQpgYGANCjwvcD4NCg0KPHA+DQpBc3N1bWluZyB0aGUgZGF0YSBmb2xsb3cgYSBsb2ctbm9ybWFsIGRpc3RyaWJ1dGlvbi4gRm9yIGVhY2ggb2YgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMsIGZpcnN0IGRlc2NyaWJlIHlvdXIgcmVhc29uaW5nIHByb2Nlc3MgZm9yIHRoZSBhbmFseXNpcywgdGhlbiB3cml0ZSBjb2RlIHRvIHBlcmZvcm0gdGhlIGFjdHVhbCBhbmFseXNpcy4gRmluYWxseSwgc3VtbWFyaXplIHRoZSByZXN1bHRzIHRvIGNvbmNsdWRlIHRoZSBxdWVzdGlvbi4NCjwvUD4NCg0KPHA+DQphKS4gUGVyZm9ybSA1MDAwIGJvb3RzdHJhcCBzYW1wbGVzIHRvIGVzdGltYXRlIHRoZSAqKmJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24qKiBvZiAkXGJveGVke1x3aWRlaGF0e1xtYXRoYmJ7RX1bWF19fSQgYW5kIHBsb3QgaXQgYXMgZWl0aGVyIGEgaGlzdG9ncmFtIG9yIGEga2VybmVsIGRlbnNpdHkgY3VydmUuIENvbW1lbnQgb24gdGhlIHNoYXBlIGFuZCBwYXR0ZXJucyBvYnNlcnZlZCBpbiB0aGUgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4NCmBgYHtyfQ0KIyBTb2lsIGxlYWQgY29uY2VudHJhdGlvbiBkYXRhIChtZy9rZykNCnggPC0gYygNCiAgMC44NSwgMS4yMywgMC45MiwgMy40NSwgMi4xMSwgMS41NiwgNC44OSwgMi4zNCwgMS43OCwgNi43MiwgMC45NSwgMS4zNCwgOC45MSwgDQogIDIuNjcsIDEuODksIDUuNDMsIDEuMTIsIDMuNzgsIDIuNDUsIDcuNjUsIDEuMDUsIDEuNDUsIDEyLjM0LCAyLjg5LCAyLjAxLCA0LjU2LCANCiAgMS4yMywgNC4zMiwgMi42NywgOS44NywgMC45OSwgMS41NiwgMTUuMjMsIDMuMTIsIDIuMzQsIDMuODksIDEuMzQsIDUuNjcsIDIuODksIA0KICAxMS40NSwgMS4xMiwgMS42NywgMTguOTAsIDMuNDUsIDIuNTYsIDMuNDUsIDEuNDUsIDYuNzgsIDMuMTIsIDE0LjU2LCAxLjIzLCAxLjc4LCANCiAgMjIuMzQsIDMuNzgsIDIuNzgNCikNCg0KbiA8LSBsZW5ndGgoeCkNCg0KIyBGdW5jdGlvbiB0byBjb21wdXRlIHRoZSBNTEUgb2YgRVtYXSB1bmRlciBsb2dub3JtYWwgbW9kZWwNCmxvZ25vcm1hbC5tZWFuLm1sZSA8LSBmdW5jdGlvbih4KXsNCiAgDQogICMgTUxFIG9mIG11IGJhc2VkIG9uIGxvZy10cmFuc2Zvcm1lZCBkYXRhDQogIG11X2hhdCA8LSBtZWFuKGxvZyh4KSkNCiAgDQogICMgTUxFIG9mIHNpZ21hXjIgKGRlbm9taW5hdG9yIG4pDQogIHNpZ21hMl9oYXQgPC0gbWVhbigobG9nKHgpIC0gbXVfaGF0KV4yKQ0KICANCiAgIyBQbHVnLWluIE1MRSBvZiBFW1hdDQogIEVYX2hhdCA8LSBleHAobXVfaGF0ICsgc2lnbWEyX2hhdCAvIDIpDQogIA0KICByZXR1cm4oRVhfaGF0KQ0KfQ0KDQojIE1MRSBmcm9tIG9yaWdpbmFsIHNhbXBsZQ0KdGhldGFfaGF0IDwtIGxvZ25vcm1hbC5tZWFuLm1sZSh4KQ0KDQojIEJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24NCnNldC5zZWVkKDEyMykNCkIgPC0gNTAwMA0KYm9vdF9tZWFuIDwtIE5VTEwNCg0KZm9yKGIgaW4gMTpCKXsNCiAgDQogICMgRHJhdyBvbmUgYm9vdHN0cmFwIHNhbXBsZQ0KICBib290X3NhbXBsZSA8LSBzYW1wbGUoeCwgc2l6ZSA9IG4sIHJlcGxhY2UgPSBUUlVFKQ0KICANCiAgIyBDb21wdXRlIGJvb3RzdHJhcCBNTEUgb2YgRVtYXQ0KICBib290X21lYW5bYl0gPC0gbG9nbm9ybWFsLm1lYW4ubWxlKGJvb3Rfc2FtcGxlKQ0KfQ0KDQojIE9uZSBjbGVhbiBvdXRwdXQgYm94DQpkYXRhLmZyYW1lKA0KICB0aGV0YV9oYXQgPSB0aGV0YV9oYXQsDQogIGJvb3RfbWVhbl9hdmcgPSBtZWFuKGJvb3RfbWVhbiksDQogIGJvb3Rfc2QgPSBzZChib290X21lYW4pDQopDQoNCiMgSGlzdG9ncmFtIGFuZCBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZSBvZiBib290c3RyYXAgZGlzdHJpYnV0aW9uDQpoaXN0KGJvb3RfbWVhbiwNCiAgICAgcHJvYmFiaWxpdHkgPSBUUlVFLA0KICAgICBicmVha3MgPSAyMCwNCiAgICAgbWFpbiA9ICJCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIE1MRSBvZiBFW1hdIiwNCiAgICAgeGxhYiA9IGV4cHJlc3Npb24oaGF0KEVbWF0pKSkNCg0KbGluZXMoZGVuc2l0eShib290X21lYW4pLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIpDQpgYGANCg0KKipBbnN3ZXI6KiogVGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgJFx3aWRlaGF0e1xtYXRoYmJ7RX1bWF19JGlzIHVuaW1vZGFsIGFuZCBzbGlnaHRseSByaWdodC1za2V3ZWQuIFRoaXMgaXMgcmVhc29uYWJsZSBiZWNhdXNlIHRoZSBvcmlnaW5hbCBzb2lsIGNvbmNlbnRyYXRpb24gZGF0YSBhcmUgcmlnaHQtc2tld2VkLCBhbmQgdGhlIGVzdGltYXRlZCBsb2dub3JtYWwgbWVhbiBpcyBpbmZsdWVuY2VkIGJ5IGxhcmdlciB2YWx1ZXMgaW4gdGhlIHNhbXBsZS4gVGhlIGRpc3RyaWJ1dGlvbiBpcyBzdGlsbCBmYWlybHkgc21vb3RoIGJlY2F1c2UgdGhlIHNhbXBsZSBzaXplIGlzIG1vZGVyYXRlIGFuZCB0aGUgbnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzIGlzIGxhcmdlLg0KDQpiKSBDb25zdHJ1Y3QgYSAqKjk1JSBib290c3RyYXAgcGVyY2VudGlsZSBjb25maWRlbmNlIGludGVydmFsIGZvciAkXG1hdGhiYntFfVtYXSQqKi4NCmBgYHtyfQ0KIyA5NSUgcGVyY2VudGlsZSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbA0KYWxwaGEgPC0gMC4wNQ0KDQpjaV9wZXJjIDwtIHF1YW50aWxlKGJvb3RfbWVhbiwgcHJvYnMgPSBjKGFscGhhLzIsIDEgLSBhbHBoYS8yKSkNCg0KZGF0YS5mcmFtZSgNCiAgbG93ZXJfcGVyY2VudGlsZSA9IGNpX3BlcmNbMV0sDQogIHVwcGVyX3BlcmNlbnRpbGUgPSBjaV9wZXJjWzJdDQopDQpgYGANCmMpIENvbnN0cnVjdCBhICoqOTUlIGJvb3RzdHJhcCBCQ2EgY29uZmlkZW5jZSBpbnRlcnZhbCoqIGZvciAkXG1hdGhiYntFfVtYXSQuDQpgYGB7cn0NCg0KbGlicmFyeShib290KQ0KDQojIFN0YXRpc3RpYyBmdW5jdGlvbiBmb3IgYm9vdCgpDQpsb2dub3JtYWwubWVhbi5zdGF0IDwtIGZ1bmN0aW9uKGRhdGEsIGluZGljZXMpew0KICBzYW1wbGVfZGF0YSA8LSBkYXRhW2luZGljZXNdDQogIGxvZ25vcm1hbC5tZWFuLm1sZShzYW1wbGVfZGF0YSkNCn0NCg0KIyBSdW4gYm9vdHN0cmFwIHVzaW5nIGJvb3QgcGFja2FnZQ0Kc2V0LnNlZWQoMTIzKQ0KYm9vdF9yZXN1bHQgPC0gYm9vdCh4LCBzdGF0aXN0aWMgPSBsb2dub3JtYWwubWVhbi5zdGF0LCBSID0gNTAwMCkNCg0KIyBCQ2EgY29uZmlkZW5jZSBpbnRlcnZhbA0KYmNhX3Jlc3VsdCA8LSBib290LmNpKGJvb3RfcmVzdWx0LCB0eXBlID0gImJjYSIpDQpiY2FfcmVzdWx0DQpgYGANCmQpIEFzc3VtaW5nIGJvdGggY29uZmlkZW5jZSBpbnRlcnZhbHMgYWJvdmUgYXJlIHZhbGlkLCBjb21wYXJlIHRoZW0gaW4gdGVybXMgb2YgcGVyZm9ybWFuY2UgYW5kIHJlY29tbWVuZCB3aGljaCBtZXRob2Qgc2hvdWxkIGJlIHVzZWQgaW4gdGhpcyBhbmFseXNpcy4gSnVzdGlmeSB5b3VyIHJlY29tbWVuZGF0aW9uLg0KPC9wPg0KYGBge3J9DQojIFBlcmNlbnRpbGUgQ0kgdXNpbmcgYm9vdCBwYWNrYWdlIGZvciBkaXJlY3QgY29tcGFyaXNvbg0KcGVyY19yZXN1bHQgPC0gYm9vdC5jaShib290X3Jlc3VsdCwgdHlwZSA9ICJwZXJjIikNCnBlcmNfcmVzdWx0DQpgYGANCioqQW5zd2VyOioqIA0KDQpCb3RoIGludGVydmFscyBhcmUgdmFsaWQgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBidXQgdGhlIHBlcmNlbnRpbGUgQ0kgaXMgc2ltcGxlIGFuZCBlYXN5IHRvIGludGVycHJldCBhbmQgdGhlIEJDYSBDSSBpcyBtb3JlIHJlZmluZWQgYmVjYXVzZSBpdCBjb3JyZWN0cyBmb3IgYmlhcyBhbmQgc2tld25lc3MuIFNpbmNlIHRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9uIG9mICRcd2lkZWhhdHtcbWF0aGJie0V9W1hdfSRpcyBzbGlnaHRseSByaWdodC1za2V3ZWQsIEkgd291bGQgcmVjb21tZW5kIHVzaW5nIHRoZSBCQ2EgY29uZmlkZW5jZSBpbnRlcnZhbCBpbiB0aGlzIGFuYWx5c2lzLiBJdCBpcyBiZXR0ZXIgc3VpdGVkIGZvciBza2V3ZWQgZGlzdHJpYnV0aW9ucyBhbmQgdXN1YWxseSBwcm92aWRlcyBtb3JlIGFjY3VyYXRlIGNvdmVyYWdlIHRoYW4gdGhlIHBlcmNlbnRpbGUgbWV0aG9kLg0KDQoNCg==