Assignment Objectives

  • Master the fundamental concepts of point estimation and performance metrics

  • Understand the theoretical foundation of the method of moments estimator (MME)

  • Implement MME in R, incorporating numerical approximation methods


Log-logistic Distribution

The log-logistic distribution (also known as the Fisk distribution) is a continuous probability distribution that is particularly useful in contexts where data exhibit non-negative, skewed behavior and where the hazard rate is unimodal (increases to a peak and then decreases). It has been widely used in the areas such as survival analysis and reliability engineering, environmental science, economics, pharmacology, finance and risk management, etc.

For given shape parameter \(\beta\) and scale parameter \(\alpha\), the cumulative distribution function

\[ F(x) = \frac{1}{1+(x/\alpha)^{-\beta}} \]

As an exercise, you can derive the density in the following form

\[ f(x) = \frac{(\beta/\alpha)(x/\alpha)^{\beta-1}}{[1+(x/\alpha)^\beta]^2}, \ \ \text{ for } \ \ x > 0. \]

After some algebra, we can find the \(k\)th moment

\[ \mu_k = E[X^k] = \alpha^k B\left(1+\frac{k}{\beta}, 1 - \frac{k}{\beta} \right). \]

This assignment will focus on finding MME of parameters \(\alpha\) and \(\beta\) based on a real-world application data set.


Question 1: Derive the log-logistic density function

Given the CDF of the two-parameter log-logistic distribution

\[ F(x) = \frac{1}{1+(x/\alpha)^{-\beta}}. \] Answer:

Given the CDF of log-logistic distribution: \[ F(x)=\frac{1}{1+(x/\alpha)^{-\beta}},\quad x>0. \]

Rewrite it as: \[ F(x)=\frac{(x/\alpha)^\beta}{1+(x/\alpha)^\beta}. \]

Let \(t=(x/\alpha)^\beta\). Then \(F(x)=t/(1+t)\), so \[ f(x)=F'(x)=\frac{t'}{(1+t)^2}. \]

Since \(t'=\frac{\beta}{\alpha}(x/\alpha)^{\beta-1}\), we obtain

\[ f(x)=\frac{\beta}{\alpha}\frac{(x/\alpha)^{\beta-1}}{\left[1+(x/\alpha)^\beta\right]^2},\quad x>0. \]


Question 2: Distribution of Recovery Time from A Surgery

Time to recovery (in days) after a specific knee surgery procedure. This follows a typical log-logistic pattern in medical survival/recovery analysis:

8.23, 12.74, 14.83, 16.61, 18.16, 19.55, 20.80, 21.94, 23.00, 23.98, 24.89, 25.75, 26.56, 
27.34, 28.08, 28.79, 29.48, 30.15, 30.81, 31.45, 32.08, 32.70, 33.31, 33.92, 34.53, 35.13, 
35.73, 36.33, 36.93, 37.53, 38.14, 38.75, 39.37, 40.00, 40.64, 41.29, 41.95, 42.63, 43.33, 
44.05, 44.79, 45.56, 46.36, 47.20, 48.08, 49.02, 50.03, 51.12, 52.32, 53.65

Based on the above data to perform the following analysis.

  1. Using method of moment estimation to estimate \(\alpha\) and \(\beta\), denoted by \(\hat{\alpha}\) and \(\hat{\beta}\), respectively.
x <- c(8.23, 12.74, 14.83, 16.61, 18.16, 19.55, 20.80, 21.94, 23.00, 23.98,
       24.89, 25.75, 26.56, 27.34, 28.08, 28.79, 29.48, 30.15, 30.81, 31.45,
       32.08, 32.70, 33.31, 33.92, 34.53, 35.13, 35.73, 36.33, 36.93, 37.53,
       38.14, 38.75, 39.37, 40.00, 40.64, 41.29, 41.95, 42.63, 43.33, 44.05,
       44.79, 45.56, 46.36, 47.20, 48.08, 49.02, 50.03, 51.12, 52.32, 53.65)

n <- length(x)

# sample moments
m1 <- mean(x)
m2 <- mean(x^2)

# target ratio m2/m1^2
target <- m2 / (m1^2)

# MoM equation after eliminating alpha
g_beta <- function(beta){
  A1 <- beta(1 + 1/beta, 1 - 1/beta)
  A2 <- beta(1 + 2/beta, 1 - 2/beta)
  (A2 / (A1^2)) - target
}

# beta must be > 2 (so second moment exists)
beta_hat <- uniroot(g_beta, interval = c(2.01, 50))$root

# plug-in alpha_hat
A1_hat <- beta(1 + 1/beta_hat, 1 - 1/beta_hat)
alpha_hat <- m1 / A1_hat

# # one lean output box: MoM point estimates
data.frame(alpha_hat = alpha_hat, beta_hat = beta_hat)
  alpha_hat beta_hat
1   32.6543 6.006232


  1. Since the moment estimates \(\hat{\alpha}\) and \(\hat{\beta}\) are random, construct bootstrap sampling distributions for each. To visualize these distributions, plot separate bootstrap histograms for \(\hat{\alpha}\) and \(\hat{\beta}\). Then, overlay a smooth density curve on each histogram using Gaussian kernel density estimation. Finally, describe the patterns of these density curves.
set.seed(123)

B <- 1000

alpha_star <- NULL
beta_star  <- NULL

for(i in 1:B){
  
  xb <- sample(x, size = n, replace = TRUE)
  
  m1b <- mean(xb)
  m2b <- mean(xb^2)
  target_b <- m2b / (m1b^2)
  
  # MoM equation for this bootstrap sample
  g_beta_b <- function(beta){
    A1 <- beta(1 + 1/beta, 1 - 1/beta)
    A2 <- beta(1 + 2/beta, 1 - 2/beta)
    (A2 / (A1^2)) - target_b
  }
  
  # Solve for beta_hat* 
  out <- try(uniroot(g_beta_b, interval = c(2.01, 50))$root, silent = TRUE)
  
  if(inherits(out, "try-error")){
    beta_star[i]  <- NA
    alpha_star[i] <- NA
  } else {
    beta_star[i] <- out
    A1b <- beta(1 + 1/beta_star[i], 1 - 1/beta_star[i])
    alpha_star[i] <- m1b / A1b
  }
}

# remove NA's 
alpha_star <- alpha_star[!is.na(alpha_star)]
beta_star  <- beta_star[!is.na(beta_star)]

# one lean output box: bootstrap summary
data.frame(
  B_used = length(alpha_star),
  alpha_boot_mean = mean(alpha_star),
  alpha_boot_sd = sd(alpha_star),
  beta_boot_mean = mean(beta_star),
  beta_boot_sd = sd(beta_star)
)
  B_used alpha_boot_mean alpha_boot_sd beta_boot_mean beta_boot_sd
1   1000        32.65709      1.644027       6.134973    0.5973591
par(mfrow = c(1,2), cex.main = 0.85)

hist(alpha_star, probability = TRUE, breaks = 20,
     main = "Bootstrap of alpha_hat",
     xlab = expression(hat(alpha)))
lines(density(alpha_star), col = "blue", lwd = 2)

hist(beta_star, probability = TRUE, breaks = 20,
     main = "Bootstrap of beta_hat",
     xlab = expression(hat(beta)))
lines(density(beta_star), col = "blue", lwd = 2)

par(mfrow = c(1,1))

Answer: The bootstrap distribution of \(\hat{\alpha}\) is unimodal and roughly symmetric, with most values concentrated around 32–33, suggesting that the MoM estimate of \(\alpha\) is fairly stable. In contrast, the bootstrap distribution of \(\hat{\beta}\) is unimodal but clearly right-skewed: it peaks near 6 and has a longer right tail extending toward about 8–9. This indicates larger sampling variability for \(\hat{\beta}\), which is reasonable because \(\hat{\beta}\) is obtained by numerically solving a nonlinear moment equation.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNDogTWV0aG9kcyBvZiBNb21lbnQgRXN0aW1hdGlvbiINCmF1dGhvcjogIlhpYW95aW5nIE1hICINCmRhdGU6ICIgRHVlOjAyLzI0LzIwMjYgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIE1hc3RlciB0aGUgZnVuZGFtZW50YWwgY29uY2VwdHMgb2YgcG9pbnQgZXN0aW1hdGlvbiBhbmQgcGVyZm9ybWFuY2UgbWV0cmljcw0KDQoqIFVuZGVyc3RhbmQgdGhlIHRoZW9yZXRpY2FsIGZvdW5kYXRpb24gb2YgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGVzdGltYXRvciAoTU1FKQ0KDQoqIEltcGxlbWVudCBNTUUgaW4gUiwgaW5jb3Jwb3JhdGluZyBudW1lcmljYWwgYXBwcm94aW1hdGlvbiBtZXRob2RzDQoNCg0KXA0KDQoqKkxvZy1sb2dpc3RpYyBEaXN0cmlidXRpb24qKg0KDQpUaGUgbG9nLWxvZ2lzdGljIGRpc3RyaWJ1dGlvbiAoYWxzbyBrbm93biBhcyB0aGUgRmlzayBkaXN0cmlidXRpb24pIGlzIGEgY29udGludW91cyBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gdGhhdCBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIGluIGNvbnRleHRzIHdoZXJlIGRhdGEgZXhoaWJpdCBub24tbmVnYXRpdmUsIHNrZXdlZCBiZWhhdmlvciBhbmQgd2hlcmUgdGhlIGhhemFyZCByYXRlIGlzIHVuaW1vZGFsIChpbmNyZWFzZXMgdG8gYSBwZWFrIGFuZCB0aGVuIGRlY3JlYXNlcykuIEl0IGhhcyBiZWVuIHdpZGVseSB1c2VkIGluIHRoZSBhcmVhcyBzdWNoIGFzIHN1cnZpdmFsIGFuYWx5c2lzIGFuZCByZWxpYWJpbGl0eSBlbmdpbmVlcmluZywgZW52aXJvbm1lbnRhbCBzY2llbmNlLCBlY29ub21pY3MsIHBoYXJtYWNvbG9neSwgZmluYW5jZSBhbmQgcmlzayBtYW5hZ2VtZW50LCBldGMuIA0KDQpGb3IgZ2l2ZW4gc2hhcGUgcGFyYW1ldGVyICRcYmV0YSQgYW5kIHNjYWxlIHBhcmFtZXRlciAkXGFscGhhJCwgdGhlIGN1bXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uDQoNCiQkDQpGKHgpID0gXGZyYWN7MX17MSsoeC9cYWxwaGEpXnstXGJldGF9fQ0KJCQNCg0KQXMgYW4gZXhlcmNpc2UsIHlvdSBjYW4gZGVyaXZlIHRoZSBkZW5zaXR5IGluIHRoZSBmb2xsb3dpbmcgZm9ybQ0KDQokJA0KZih4KSA9IFxmcmFjeyhcYmV0YS9cYWxwaGEpKHgvXGFscGhhKV57XGJldGEtMX19e1sxKyh4L1xhbHBoYSleXGJldGFdXjJ9LCBcIFwgXHRleHR7IGZvciB9IFwgXCB4ID4gMC4NCiQkDQoNCkFmdGVyIHNvbWUgYWxnZWJyYSwgd2UgY2FuIGZpbmQgdGhlICRrJHRoIG1vbWVudA0KDQokJA0KXG11X2sgPSBFW1hea10gPSBcYWxwaGFeayBCXGxlZnQoMStcZnJhY3trfXtcYmV0YX0sIDEgLSBcZnJhY3trfXtcYmV0YX0gXHJpZ2h0KS4NCiQkDQoNClRoaXMgYXNzaWdubWVudCB3aWxsIGZvY3VzIG9uIGZpbmRpbmcgTU1FIG9mIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQgYmFzZWQgb24gYSByZWFsLXdvcmxkIGFwcGxpY2F0aW9uIGRhdGEgc2V0Lg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbiAxOiBEZXJpdmUgdGhlIGxvZy1sb2dpc3RpYyBkZW5zaXR5IGZ1bmN0aW9uICoqDQoNCkdpdmVuIHRoZSBDREYgb2YgdGhlIHR3by1wYXJhbWV0ZXIgbG9nLWxvZ2lzdGljIGRpc3RyaWJ1dGlvbg0KDQokJA0KRih4KSA9IFxmcmFjezF9ezErKHgvXGFscGhhKV57LVxiZXRhfX0uDQokJA0KKipBbnN3ZXLvvJoqKiANCg0KR2l2ZW4gdGhlIENERiBvZiBsb2ctbG9naXN0aWMgZGlzdHJpYnV0aW9uOg0KJCQNCkYoeCk9XGZyYWN7MX17MSsoeC9cYWxwaGEpXnstXGJldGF9fSxccXVhZCB4PjAuDQokJA0KDQpSZXdyaXRlIGl0IGFzOg0KJCQNCkYoeCk9XGZyYWN7KHgvXGFscGhhKV5cYmV0YX17MSsoeC9cYWxwaGEpXlxiZXRhfS4NCiQkDQoNCkxldCAkdD0oeC9cYWxwaGEpXlxiZXRhJC4gVGhlbiAkRih4KT10LygxK3QpJCwgc28NCiQkDQpmKHgpPUYnKHgpPVxmcmFje3QnfXsoMSt0KV4yfS4NCiQkDQoNClNpbmNlIFwodCc9XGZyYWN7XGJldGF9e1xhbHBoYX0oeC9cYWxwaGEpXntcYmV0YS0xfVwpLCB3ZSBvYnRhaW4NCg0KJCQNCmYoeCk9XGZyYWN7XGJldGF9e1xhbHBoYX1cZnJhY3soeC9cYWxwaGEpXntcYmV0YS0xfX17XGxlZnRbMSsoeC9cYWxwaGEpXlxiZXRhXHJpZ2h0XV4yfSxccXVhZCB4PjAuDQokJA0KDQpcDQoNCiMjICoqUXVlc3Rpb24gMjogRGlzdHJpYnV0aW9uIG9mIFJlY292ZXJ5IFRpbWUgZnJvbSBBIFN1cmdlcnkqKg0KDQpUaW1lIHRvIHJlY292ZXJ5IChpbiBkYXlzKSBhZnRlciBhIHNwZWNpZmljIGtuZWUgc3VyZ2VyeSBwcm9jZWR1cmUuIFRoaXMgZm9sbG93cyBhIHR5cGljYWwgKipsb2ctbG9naXN0aWMgcGF0dGVybioqIGluIG1lZGljYWwgc3Vydml2YWwvcmVjb3ZlcnkgYW5hbHlzaXM6DQoNCmBgYA0KOC4yMywgMTIuNzQsIDE0LjgzLCAxNi42MSwgMTguMTYsIDE5LjU1LCAyMC44MCwgMjEuOTQsIDIzLjAwLCAyMy45OCwgMjQuODksIDI1Ljc1LCAyNi41NiwgDQoyNy4zNCwgMjguMDgsIDI4Ljc5LCAyOS40OCwgMzAuMTUsIDMwLjgxLCAzMS40NSwgMzIuMDgsIDMyLjcwLCAzMy4zMSwgMzMuOTIsIDM0LjUzLCAzNS4xMywgDQozNS43MywgMzYuMzMsIDM2LjkzLCAzNy41MywgMzguMTQsIDM4Ljc1LCAzOS4zNywgNDAuMDAsIDQwLjY0LCA0MS4yOSwgNDEuOTUsIDQyLjYzLCA0My4zMywgDQo0NC4wNSwgNDQuNzksIDQ1LjU2LCA0Ni4zNiwgNDcuMjAsIDQ4LjA4LCA0OS4wMiwgNTAuMDMsIDUxLjEyLCA1Mi4zMiwgNTMuNjUNCmBgYA0KQmFzZWQgb24gdGhlIGFib3ZlIGRhdGEgdG8gcGVyZm9ybSB0aGUgZm9sbG93aW5nIGFuYWx5c2lzLg0KDQphKSBVc2luZyBtZXRob2Qgb2YgbW9tZW50IGVzdGltYXRpb24gdG8gZXN0aW1hdGUgJFxhbHBoYSQgYW5kICRcYmV0YSQsIGRlbm90ZWQgYnkgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQsIHJlc3BlY3RpdmVseS4gDQoNCmBgYHtyfQ0KeCA8LSBjKDguMjMsIDEyLjc0LCAxNC44MywgMTYuNjEsIDE4LjE2LCAxOS41NSwgMjAuODAsIDIxLjk0LCAyMy4wMCwgMjMuOTgsDQogICAgICAgMjQuODksIDI1Ljc1LCAyNi41NiwgMjcuMzQsIDI4LjA4LCAyOC43OSwgMjkuNDgsIDMwLjE1LCAzMC44MSwgMzEuNDUsDQogICAgICAgMzIuMDgsIDMyLjcwLCAzMy4zMSwgMzMuOTIsIDM0LjUzLCAzNS4xMywgMzUuNzMsIDM2LjMzLCAzNi45MywgMzcuNTMsDQogICAgICAgMzguMTQsIDM4Ljc1LCAzOS4zNywgNDAuMDAsIDQwLjY0LCA0MS4yOSwgNDEuOTUsIDQyLjYzLCA0My4zMywgNDQuMDUsDQogICAgICAgNDQuNzksIDQ1LjU2LCA0Ni4zNiwgNDcuMjAsIDQ4LjA4LCA0OS4wMiwgNTAuMDMsIDUxLjEyLCA1Mi4zMiwgNTMuNjUpDQoNCm4gPC0gbGVuZ3RoKHgpDQoNCiMgc2FtcGxlIG1vbWVudHMNCm0xIDwtIG1lYW4oeCkNCm0yIDwtIG1lYW4oeF4yKQ0KDQojIHRhcmdldCByYXRpbyBtMi9tMV4yDQp0YXJnZXQgPC0gbTIgLyAobTFeMikNCg0KIyBNb00gZXF1YXRpb24gYWZ0ZXIgZWxpbWluYXRpbmcgYWxwaGENCmdfYmV0YSA8LSBmdW5jdGlvbihiZXRhKXsNCiAgQTEgPC0gYmV0YSgxICsgMS9iZXRhLCAxIC0gMS9iZXRhKQ0KICBBMiA8LSBiZXRhKDEgKyAyL2JldGEsIDEgLSAyL2JldGEpDQogIChBMiAvIChBMV4yKSkgLSB0YXJnZXQNCn0NCg0KIyBiZXRhIG11c3QgYmUgPiAyIChzbyBzZWNvbmQgbW9tZW50IGV4aXN0cykNCmJldGFfaGF0IDwtIHVuaXJvb3QoZ19iZXRhLCBpbnRlcnZhbCA9IGMoMi4wMSwgNTApKSRyb290DQoNCiMgcGx1Zy1pbiBhbHBoYV9oYXQNCkExX2hhdCA8LSBiZXRhKDEgKyAxL2JldGFfaGF0LCAxIC0gMS9iZXRhX2hhdCkNCmFscGhhX2hhdCA8LSBtMSAvIEExX2hhdA0KDQojICMgb25lIGxlYW4gb3V0cHV0IGJveDogTW9NIHBvaW50IGVzdGltYXRlcw0KZGF0YS5mcmFtZShhbHBoYV9oYXQgPSBhbHBoYV9oYXQsIGJldGFfaGF0ID0gYmV0YV9oYXQpDQpgYGANClwNCg0KYikgU2luY2UgdGhlIG1vbWVudCBlc3RpbWF0ZXMgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQgYXJlIHJhbmRvbSwgY29uc3RydWN0IGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIGZvciBlYWNoLiBUbyB2aXN1YWxpemUgdGhlc2UgZGlzdHJpYnV0aW9ucywgcGxvdCBzZXBhcmF0ZSBib290c3RyYXAgaGlzdG9ncmFtcyBmb3IgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQuICBUaGVuLCBvdmVybGF5IGEgc21vb3RoIGRlbnNpdHkgY3VydmUgb24gZWFjaCBoaXN0b2dyYW0gdXNpbmcgR2F1c3NpYW4ga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbi4gRmluYWxseSwgZGVzY3JpYmUgdGhlIHBhdHRlcm5zIG9mIHRoZXNlIGRlbnNpdHkgY3VydmVzLg0KDQpgYGB7cn0NCg0Kc2V0LnNlZWQoMTIzKQ0KDQpCIDwtIDEwMDANCg0KYWxwaGFfc3RhciA8LSBOVUxMDQpiZXRhX3N0YXIgIDwtIE5VTEwNCg0KZm9yKGkgaW4gMTpCKXsNCiAgDQogIHhiIDwtIHNhbXBsZSh4LCBzaXplID0gbiwgcmVwbGFjZSA9IFRSVUUpDQogIA0KICBtMWIgPC0gbWVhbih4YikNCiAgbTJiIDwtIG1lYW4oeGJeMikNCiAgdGFyZ2V0X2IgPC0gbTJiIC8gKG0xYl4yKQ0KICANCiAgIyBNb00gZXF1YXRpb24gZm9yIHRoaXMgYm9vdHN0cmFwIHNhbXBsZQ0KICBnX2JldGFfYiA8LSBmdW5jdGlvbihiZXRhKXsNCiAgICBBMSA8LSBiZXRhKDEgKyAxL2JldGEsIDEgLSAxL2JldGEpDQogICAgQTIgPC0gYmV0YSgxICsgMi9iZXRhLCAxIC0gMi9iZXRhKQ0KICAgIChBMiAvIChBMV4yKSkgLSB0YXJnZXRfYg0KICB9DQogIA0KICAjIFNvbHZlIGZvciBiZXRhX2hhdCogDQogIG91dCA8LSB0cnkodW5pcm9vdChnX2JldGFfYiwgaW50ZXJ2YWwgPSBjKDIuMDEsIDUwKSkkcm9vdCwgc2lsZW50ID0gVFJVRSkNCiAgDQogIGlmKGluaGVyaXRzKG91dCwgInRyeS1lcnJvciIpKXsNCiAgICBiZXRhX3N0YXJbaV0gIDwtIE5BDQogICAgYWxwaGFfc3RhcltpXSA8LSBOQQ0KICB9IGVsc2Ugew0KICAgIGJldGFfc3RhcltpXSA8LSBvdXQNCiAgICBBMWIgPC0gYmV0YSgxICsgMS9iZXRhX3N0YXJbaV0sIDEgLSAxL2JldGFfc3RhcltpXSkNCiAgICBhbHBoYV9zdGFyW2ldIDwtIG0xYiAvIEExYg0KICB9DQp9DQoNCiMgcmVtb3ZlIE5BJ3MgDQphbHBoYV9zdGFyIDwtIGFscGhhX3N0YXJbIWlzLm5hKGFscGhhX3N0YXIpXQ0KYmV0YV9zdGFyICA8LSBiZXRhX3N0YXJbIWlzLm5hKGJldGFfc3RhcildDQoNCiMgb25lIGxlYW4gb3V0cHV0IGJveDogYm9vdHN0cmFwIHN1bW1hcnkNCmRhdGEuZnJhbWUoDQogIEJfdXNlZCA9IGxlbmd0aChhbHBoYV9zdGFyKSwNCiAgYWxwaGFfYm9vdF9tZWFuID0gbWVhbihhbHBoYV9zdGFyKSwNCiAgYWxwaGFfYm9vdF9zZCA9IHNkKGFscGhhX3N0YXIpLA0KICBiZXRhX2Jvb3RfbWVhbiA9IG1lYW4oYmV0YV9zdGFyKSwNCiAgYmV0YV9ib290X3NkID0gc2QoYmV0YV9zdGFyKQ0KKQ0KDQpwYXIobWZyb3cgPSBjKDEsMiksIGNleC5tYWluID0gMC44NSkNCg0KaGlzdChhbHBoYV9zdGFyLCBwcm9iYWJpbGl0eSA9IFRSVUUsIGJyZWFrcyA9IDIwLA0KICAgICBtYWluID0gIkJvb3RzdHJhcCBvZiBhbHBoYV9oYXQiLA0KICAgICB4bGFiID0gZXhwcmVzc2lvbihoYXQoYWxwaGEpKSkNCmxpbmVzKGRlbnNpdHkoYWxwaGFfc3RhciksIGNvbCA9ICJibHVlIiwgbHdkID0gMikNCg0KaGlzdChiZXRhX3N0YXIsIHByb2JhYmlsaXR5ID0gVFJVRSwgYnJlYWtzID0gMjAsDQogICAgIG1haW4gPSAiQm9vdHN0cmFwIG9mIGJldGFfaGF0IiwNCiAgICAgeGxhYiA9IGV4cHJlc3Npb24oaGF0KGJldGEpKSkNCmxpbmVzKGRlbnNpdHkoYmV0YV9zdGFyKSwgY29sID0gImJsdWUiLCBsd2QgPSAyKQ0KDQpwYXIobWZyb3cgPSBjKDEsMSkpDQoNCg0KYGBgDQoNCioqQW5zd2VyOioqIFRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9uIG9mICRcaGF0e1xhbHBoYX0kIGlzIHVuaW1vZGFsIGFuZCByb3VnaGx5IHN5bW1ldHJpYywgd2l0aCBtb3N0IHZhbHVlcyBjb25jZW50cmF0ZWQgYXJvdW5kIDMy4oCTMzMsIHN1Z2dlc3RpbmcgdGhhdCB0aGUgTW9NIGVzdGltYXRlIG9mICRcYWxwaGEkIGlzIGZhaXJseSBzdGFibGUuIEluIGNvbnRyYXN0LCB0aGUgYm9vdHN0cmFwIGRpc3RyaWJ1dGlvbiBvZiAkXGhhdHtcYmV0YX0kIGlzIHVuaW1vZGFsIGJ1dCBjbGVhcmx5IHJpZ2h0LXNrZXdlZDogaXQgcGVha3MgbmVhciA2IGFuZCBoYXMgYSBsb25nZXIgcmlnaHQgdGFpbCBleHRlbmRpbmcgdG93YXJkIGFib3V0IDjigJM5LiBUaGlzIGluZGljYXRlcyBsYXJnZXIgc2FtcGxpbmcgdmFyaWFiaWxpdHkgZm9yICRcaGF0e1xiZXRhfSQsIHdoaWNoIGlzIHJlYXNvbmFibGUgYmVjYXVzZSAkXGhhdHtcYmV0YX0kIGlzIG9idGFpbmVkIGJ5IG51bWVyaWNhbGx5IHNvbHZpbmcgYSBub25saW5lYXIgbW9tZW50IGVxdWF0aW9uLg0KDQo=