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