NOTES!!!!!
How to do Hypothesis testing
- Read the question carefully. what is known?
- Data
- one sample, n > 30, sd known = Z test
- one sample, n < 30, sd unknown = t test
- two sample, n > 30, sd known = Z test
- two sample, n < 30, sd unknwon = t test
- Compute the Z or t score
- Write PDF for z and t distribution
- use integration method (trapezoidal/simpson) -> if using t,
inside the function add v(df) in function (f,a,b,n=1000)
Things to remember
A. P (P-value)
- two tail: 2*1- (P(abs(Ztest)))
- upper tail: 1 - P(Ztest)
- lower tail: P(Ztest)
B. q (Inverse of P)
- two tail: q(1-alpha/2)
- upper tail: q(1-alpha)
- lower tail: q(alpha)
C. P-value integral
- two tail: a = |Zscore|, b = 100
- upper tail: a = Zscore, b = 100
- lower tail: a = -100, b = Zscore
One Sample Z test
An electrical firm manufactures light bulbs that have a lifetime that
is approximately normally distributet with a mean of 800 hours and a
standard deviation of 40 hours. Test the hypothesis that µ = 800 hours
against the alternative, µ != 800 hours, if a random sample of 30 bulbs
has an average life of 788 hours. Use a P-value in your answer.
n = 30
miu = 800
xbar = 788
sd = 40
#HO : µ = 800
#H1 : µ != 800
# ------ Sample Z-Test Function ---
OneSample_Z <- function(xbar, miu, sigma, n, alpha = 0.05, type = "two.tail") {
zscore <- (xbar - miu) / (sigma / sqrt(n))
PDF_Normal <- function(x) {
1/sqrt(2*pi) * exp(-x^2/2)
}
# --- Trapezoidal function to find PDF ---
trap <- function (f, a, b, n = 1000) {
h = (b - a) / n
integral = (f(a) + f(b)) / 2
for (i in 1:(n-1)) {
integral = integral + f(a + i * h)
}
integral = integral * h
return(integral)
}
# --- Manual integration using Trapezoidal ---
if (type == "two.tail") {
p_trap <- 2 * trap(PDF_Normal, abs(zscore), 100)
} else if (type == "lower") {
p_trap <- trap(PDF_Normal, -100, zscore)
} else if (type == "upper") {
p_trap <- trap(PDF_Normal, zscore, 100)
}
# --- Built-in pnorm comparison ---
if (type == "two.tail") {
p_builtin <- 2 * (1 - pnorm(abs(zscore)))
crit_val <- qnorm(1 - alpha / 2)
} else if (type == "lower") {
p_builtin <- pnorm(zscore)
crit_val <- qnorm(alpha)
} else if (type == "upper") {
p_builtin <- 1 - pnorm(zscore)
crit_val <- qnorm(1 - alpha)
}
# --- Output Results ---
cat("=== One Sample Z-Test ===\n")
cat("Sample mean (x̄) =" ,round(xbar, 4), "\n")
cat("Population mean μ =", miu, "\n")
cat("Z-statistic =", round(zscore, 4), "\n")
cat("p-value (Trap) =", round(p_trap, 5), "\n")
cat("p-value (pnorm) =", round(p_builtin, 5), "\n")
cat("alpha =", alpha, "\n")
cat("Critical Z value =", round(crit_val, 4), "\n\n")
if (p_builtin < alpha) {
cat(">>> Reject H0 (Significant)\n")
} else {
cat(">>> Fail to Reject H0 (Not Significant)\n")
}
}
OneSample_Z(xbar, miu, sd, n)
=== One Sample Z-Test ===
Sample mean (x̄) = 788
Population mean μ = 800
Z-statistic = -1.6432
p-value (Trap) = 0.10062
p-value (pnorm) = 0.10035
alpha = 0.05
Critical Z value = 1.96
>>> Fail to Reject H0 (Not Significant)
One Sample t test
Test the hypothesis that the average content of containers of a
particular lubricant is 10 liters if the contents of a random sample of
10 containers are 10.2, 9.7, 10.1, 10.3, 10.1, 9.8, 9.9, 10.4, 10.3, and
9.8 liters. Use a 0.01 level of significance and assume that the
distribution of contents is normal.
data <- c(10.2, 9.7, 10.1, 10.3, 10.1, 9.8, 9.9, 10.4, 10.3, 9.8)
miu <- 10
OneSample_t <- function(x, miu, alpha = 0.01, type = "two.tail") {
# --- define the xbar, s, etc ---
n = length(x)
x_bar = sum(x)/n
s = sd(x)
v = n-1
# --- define the tscore and pdf ---
t_score = (x_bar - miu) / (s/ sqrt(n))
PDF_t <- function(t, v) {
(gamma((v+1)/2) / (sqrt(v*pi) * gamma(v/2))) * (1 + (t^2)/v)^(-(v+1)/2)
}
# --- Trapezoidal function to find PDF ---
trap <- function (f, a, b, n = 1000) {
h = (b - a) / n
integral = (f(a, v) + f(b, v)) / 2
for (i in 1:(n-1)) {
integral = integral + f(a + i * h, v)
}
integral = integral * h
return(integral)
}
# --- Manual integration using Trapezoidal ---
if (type == "two.tail") {
p_trap <- 2 * trap(PDF_t, abs(t_score), 100)
} else if (type == "lower") {
p_trap <- trap(PDF_t, -100, t_score)
} else if (type == "upper") {
p_trap <- trap(PDF_t, t_score, 100)
}
# --- Built-in pnorm comparison ---
if (type == "two.tail") {
p_builtin <- 2 * (1 - pt(abs(t_score),v))
crit_val <- qt(1 - alpha / 2,v)
} else if (type == "lower") {
p_builtin <- pt(t_score, v)
crit_val <- qt(alpha,v)
} else if (type == "upper") {
p_builtin <- 1 - pt(t_score,v)
crit_val <- qt(1 - alpha,v)
}
# --- Output Results ---
cat("=== One Sample Z-Test ===\n")
cat("Sample mean (x̄) =" ,round(x_bar, 4), "\n")
cat("Population mean μ =", miu, "\n")
cat("t-statistic =", round(t_score, 4), "\n")
cat("p-value (Trap) =", round(p_trap, 5), "\n")
cat("p-value (pnorm) =", round(p_builtin, 5), "\n")
cat("alpha =", alpha, "\n")
cat("Critical t value =", round(crit_val, 4), "\n\n")
if (p_builtin < alpha) {
cat(">>> Reject H0 (Significant)\n")
} else {
cat(">>> Fail to Reject H0 (Not Significant)\n")
}
}
OneSample_t(data, miu)
=== One Sample Z-Test ===
Sample mean (x̄) = 10.06
Population mean μ = 10
t-statistic = 0.7717
p-value (Trap) = 0.46042
p-value (pnorm) = 0.46005
alpha = 0.01
Critical t value = 3.2498
>>> Fail to Reject H0 (Not Significant)
Two Sample Z-test
A random sample of size n1 = 25, taken from a normal population with
a standard deviation σ1 = 5.2, has a mean xbar1 = 81. A second random
sample of size n2 = 36, taken from a different normal population with a
standard deviation σ2 = 3.4, has a mean xbar2 = 76. Test the hypothesis
that μ1 = μ2 against the alternative, μ1 != μ2. Quote a P-value in your
conclusion
n1 = 25
sd1 = 5.2
xbar1 = 81
n2 = 36
sd2 = 3.4
xbar2 = 76
# H0 : μ1 = μ2
# H1 : μ1 != μ2
TwoSample_Z <- function(xbar1, xbar2, sigma1, sigma2, n1, n2, alpha = 0.05, d0 = 0, type = "two.tail") {
zscore <- (xbar1 - xbar2 - d0) / sqrt((sigma1^2/n1) + (sigma2^2/n2))
PDF_Normal <- function(x) {
1/sqrt(2*pi) * exp(-x^2/2)
}
# --- Trapezoidal function to find PDF ---
trap <- function (f, a, b, n = 1000) {
h = (b - a) / n
integral = (f(a) + f(b)) / 2
for (i in 1:(n-1)) {
integral = integral + f(a + i * h)
}
integral = integral * h
return(integral)
}
# --- Manual integration using Trapezoidal ---
if (type == "two.tail") {
p_trap <- 2 * trap(PDF_Normal, abs(zscore), 100)
} else if (type == "lower") {
p_trap <- trap(PDF_Normal, -100, zscore)
} else if (type == "upper") {
p_trap <- trap(PDF_Normal, zscore, 100)
}
# --- Built-in pnorm comparison ---
if (type == "two.tail") {
p_builtin <- 2 * (1 - pnorm(abs(zscore)))
crit_val <- qnorm(1 - alpha / 2)
} else if (type == "lower") {
p_builtin <- pnorm(zscore)
crit_val <- qnorm(alpha)
} else if (type == "upper") {
p_builtin <- 1 - pnorm(zscore)
crit_val <- qnorm(1 - alpha)
}
# --- Output Results ---
cat("=== Two Sample Z-Test ===\n")
cat("Sample mean (x̄1) =" ,round(xbar1, 4), "\n")
cat("Sample mean (x̄2) =" ,round(xbar2, 4), "\n")
cat("Z-statistic =", round(zscore, 4), "\n")
cat("p-value (Trap) =", round(p_trap, 5), "\n")
cat("p-value (pnorm) =", round(p_builtin, 5), "\n")
cat("alpha =", alpha, "\n")
cat("Critical Z value =", round(crit_val, 4), "\n\n")
if (p_builtin < alpha) {
cat(">>> Reject H0 (Significant)\n")
} else {
cat(">>> Fail to Reject H0 (Not Significant)\n")
}
}
TwoSample_Z(xbar1, xbar2, sd1, sd2, n1, n2)
=== Two Sample Z-Test ===
Sample mean (x̄1) = 81
Sample mean (x̄2) = 76
Z-statistic = 4.2217
p-value (Trap) = 2e-05
p-value (pnorm) = 2e-05
alpha = 0.05
Critical Z value = 1.96
>>> Reject H0 (Significant)
Two sample t-test, variance is equal
To find out whether a new serum will arrest leukemia, 9 mice, all
with an advanced stage of the disease, are selected. Five mice receive
the treatment and 4 do not. Survival times, in years, from the time the
experiment commenced are as follows:
Treatment = 2.1, 5.3, 1.4, 4.6, 0.9 No Treatment = 1.9, 0.5, 2.8,
3.1
At the 0.05 level of significance, can the serum be said to be
effective? Assume the two population to be normally distributed with
equal variances.
data1 <- c(2.1, 5.3, 1.4, 4.6, 0.9)
data2 <- c(1.9, 0.5, 2.8, 3.1)
# H0 : The serum is effective (μ1 = μ2)
# H1 : The serum is not effective
TwoSample_t_same <- function(x1, x2, alpha = 0.05, type = "two.tail", d0 = 0) {
# --- define the xbar, s, etc ---
n1 = length(x1)
n2 = length (x2)
x_bar1 = sum(x1)/n1
x_bar2 = sum(x2)/n2
s1 = sd(x1)
s2 = sd(x2)
v = (n1 + n2) - 2
sp_2 = (((n1 - 1)*s1^2) + ((n2 - 1)*s2^2)) / v
sp = sqrt(sp_2)
# --- define the tscore and pdf ---
t_score = (x_bar1 - x_bar2 - d0) / (sp*sqrt((1/n1)+(1/n2)))
PDF_t <- function(t, v) {
(gamma((v+1)/2) / (sqrt(v*pi) * gamma(v/2))) * (1 + (t^2)/v)^(-(v+1)/2)
}
# --- Trapezoidal function to find PDF ---
trap <- function (f, a, b, n = 1000) {
h = (b - a) / n
integral = (f(a, v) + f(b, v)) / 2
for (i in 1:(n-1)) {
integral = integral + f(a + i * h, v)
}
integral = integral * h
return(integral)
}
# --- Manual integration using Trapezoidal ---
if (type == "two.tail") {
p_trap <- 2 * trap(PDF_t, abs(t_score), 100)
} else if (type == "lower") {
p_trap <- trap(PDF_t, -100, t_score)
} else if (type == "upper") {
p_trap <- trap(PDF_t, t_score, 100)
}
# --- Built-in pnorm comparison ---
if (type == "two.tail") {
p_builtin <- 2 * (1 - pt(abs(t_score),v))
crit_val <- qt(1 - alpha / 2,v)
} else if (type == "lower") {
p_builtin <- pt(t_score, v)
crit_val <- qt(alpha,v)
} else if (type == "upper") {
p_builtin <- 1 - pt(t_score,v)
crit_val <- qt(1 - alpha,v)
}
# --- Output Results ---
cat("=== One Sample Z-Test ===\n")
cat("Sample mean (x̄1) =" ,round(x_bar1, 4), "\n")
cat("Sample mean (x2) =" ,round(x_bar2, 4), "\n")
cat("Population mean μ =", miu, "\n")
cat("t-statistic =", round(t_score, 4), "\n")
cat("p-value (Trap) =", round(p_trap, 5), "\n")
cat("p-value (pnorm) =", round(p_builtin, 5), "\n")
cat("alpha =", alpha, "\n")
cat("Critical t value =", round(crit_val, 4), "\n\n")
if (p_builtin < alpha) {
cat(">>> Reject H0 (Significant)\n")
} else {
cat(">>> Fail to Reject H0 (Not Significant)\n")
}
}
TwoSample_t_same(data1, data2)
=== One Sample Z-Test ===
Sample mean (x̄1) = 2.86
Sample mean (x2) = 2.075
Population mean μ = 10
t-statistic = 0.699
p-value (Trap) = 0.50747
p-value (pnorm) = 0.50711
alpha = 0.05
Critical t value = 2.3646
>>> Fail to Reject H0 (Not Significant)
Two sample t-test, variance is not equal
A study was conducted by the Department of Zoology at Virginia Tech
to determine if there is a significant difference in the density of
organisms at two different stations located on Cedar Run, a secondary
stream in the Roanoke River drainage basin. Sewage from a sewage
treatment plant and overflow from the Federal Mogul Corporation settling
pond enter the stream near its headwaters. The following data give the
density measurements, in number of organisms per square meter, at the
two collecting stations
Station 1 = 5030, 13700, 10730, 11400, 860, 2200, 4250, 15040, 4980,
11910, 8130, 26850, 17660, 22800, 1130, 1690 Station 2 = 2800, 4670,
6890, 7720, 7030, 7330, 2810, 1330, 3320, 1230, 2130, 2190
Can we conclude, at the 0.05 level of significance, that the average
densities at the two stations are equal? Assume that the observations
come from normal populations with different variances.
station1 <- c(5030, 13700, 10730, 11400, 860, 2200, 4250, 15040, 4980, 11910, 8130, 26850, 17660, 22800, 1130, 1690)
station2 <- c(2800, 4670, 6890, 7720, 7030, 7330, 2810, 1330, 3320, 1230, 2130, 2190)
TwoSample_t_diff <- function(x1, x2, alpha = 0.05, type = "two.tail", d0 = 0) {
# --- define the xbar, s, etc ---
n1 = length(x1)
n2 = length (x2)
x_bar1 = sum(x1)/n1
x_bar2 = sum(x2)/n2
s1 = sd(x1)
s2 = sd(x2)
a = ((s1^2/n1) + (s2^2/n2))^2
b = (((s1^2/n1)^2)/(n1-1)) + (((s2^2/n2)^2)/(n2-1))
v = a/b
# --- define the tscore and pdf ---
t_score = ((x_bar1 - x_bar2) - d0) / (sqrt((s1^2/n1) + (s2^2/n2)))
PDF_t <- function(t, v) {
(gamma((v+1)/2) / (sqrt(v*pi) * gamma(v/2))) * (1 + (t^2)/v)^(-(v+1)/2)
}
# --- Trapezoidal function to find PDF ---
trap <- function (f, a, b, n = 1000) {
h = (b - a) / n
integral = (f(a, v) + f(b, v)) / 2
for (i in 1:(n-1)) {
integral = integral + f(a + i * h, v)
}
integral = integral * h
return(integral)
}
# --- Manual integration using Trapezoidal ---
if (type == "two.tail") {
p_trap <- 2 * trap(PDF_t, abs(t_score), 100)
} else if (type == "lower") {
p_trap <- trap(PDF_t, -100, t_score)
} else if (type == "upper") {
p_trap <- trap(PDF_t, t_score, 100)
}
# --- Built-in pnorm comparison ---
if (type == "two.tail") {
p_builtin <- 2 * (1 - pt(abs(t_score),v))
crit_val <- qt(1 - alpha / 2,v)
} else if (type == "lower") {
p_builtin <- pt(t_score, v)
crit_val <- qt(alpha,v)
} else if (type == "upper") {
p_builtin <- 1 - pt(t_score,v)
crit_val <- qt(1 - alpha,v)
}
# --- Output Results ---
cat("=== One Sample Z-Test ===\n")
cat("Sample mean (x̄1) =" ,round(x_bar1, 4), "\n")
cat("Sample mean (x2) =" ,round(x_bar2, 4), "\n")
cat("Population mean μ =", miu, "\n")
cat("t-statistic =", round(t_score, 4), "\n")
cat("p-value (Trap) =", round(p_trap, 5), "\n")
cat("p-value (pnorm) =", round(p_builtin, 5), "\n")
cat("alpha =", alpha, "\n")
cat("Critical t value =", round(crit_val, 4), "\n\n")
if (p_builtin < alpha) {
cat(">>> Reject H0 (Significant)\n")
} else {
cat(">>> Fail to Reject H0 (Not Significant)\n")
}
}
TwoSample_t_diff(station1, station2)
=== One Sample Z-Test ===
Sample mean (x̄1) = 9897.5
Sample mean (x2) = 4120.833
Population mean μ = 10
t-statistic = 2.7578
p-value (Trap) = 0.01266
p-value (pnorm) = 0.01261
alpha = 0.05
Critical t value = 2.0947
>>> Reject H0 (Significant)
LS0tDQp0aXRsZTogIkxhdGloYW4gRVRTIChXNikiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIF8qKk5PVEVTISEhISEqKl8NCiMjIEhvdyB0byBkbyBIeXBvdGhlc2lzIHRlc3RpbmcNCjEuIFJlYWQgdGhlIHF1ZXN0aW9uIGNhcmVmdWxseS4gd2hhdCBpcyBrbm93bj8NCjIuIERhdGEgDQogICAgYSkgb25lIHNhbXBsZSwgbiA+IDMwLCBzZCBrbm93biA9IFogdGVzdA0KICAgIGIpIG9uZSBzYW1wbGUsIG4gPCAzMCwgc2QgdW5rbm93biA9IHQgdGVzdA0KICAgIGMpIHR3byBzYW1wbGUsIG4gPiAzMCwgc2Qga25vd24gPSBaIHRlc3QNCiAgICBkKSB0d28gc2FtcGxlLCBuIDwgMzAsIHNkIHVua253b24gPSB0IHRlc3QNCjMuIENvbXB1dGUgdGhlIFogb3IgdCBzY29yZQ0KNC4gV3JpdGUgUERGIGZvciB6IGFuZCB0IGRpc3RyaWJ1dGlvbg0KNS4gdXNlIGludGVncmF0aW9uIG1ldGhvZCAodHJhcGV6b2lkYWwvc2ltcHNvbikNCiAgIC0+IGlmIHVzaW5nIHQsIGluc2lkZSB0aGUgZnVuY3Rpb24gYWRkIHYoZGYpIGluIGZ1bmN0aW9uIChmLGEsYixuPTEwMDApDQogIA0KIyMgVGhpbmdzIHRvIHJlbWVtYmVyDQpBLiBQIChQLXZhbHVlKQ0KDQogICAtIHR3byB0YWlsOiAyKjEtIChQKGFicyhadGVzdCkpKQ0KICAgLSB1cHBlciB0YWlsOiAxIC0gUChadGVzdCkNCiAgIC0gbG93ZXIgdGFpbDogUChadGVzdCkNCiAgIA0KQi4gcSAoSW52ZXJzZSBvZiBQKQ0KDQogICAtIHR3byB0YWlsOiBxKDEtYWxwaGEvMikNCiAgIC0gdXBwZXIgdGFpbDogcSgxLWFscGhhKQ0KICAgLSBsb3dlciB0YWlsOiBxKGFscGhhKQ0KICANCkMuIFAtdmFsdWUgaW50ZWdyYWwNCg0KICAtIHR3byB0YWlsOiBhID0gfFpzY29yZXwsIGIgPSAxMDANCiAgLSB1cHBlciB0YWlsOiBhID0gWnNjb3JlLCBiID0gMTAwDQogIC0gbG93ZXIgdGFpbDogYSA9IC0xMDAsIGIgPSBac2NvcmUNCg0KDQoNCg0KDQojIyAqKk9uZSBTYW1wbGUgWiB0ZXN0KioNCg0KDQpBbiBlbGVjdHJpY2FsIGZpcm0gbWFudWZhY3R1cmVzIGxpZ2h0IGJ1bGJzIHRoYXQgaGF2ZSBhIGxpZmV0aW1lIHRoYXQgaXMgYXBwcm94aW1hdGVseSBub3JtYWxseSBkaXN0cmlidXRldCB3aXRoIGEgbWVhbiBvZiA4MDAgaG91cnMgYW5kIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDQwIGhvdXJzLiBUZXN0IHRoZSBoeXBvdGhlc2lzIHRoYXQgwrUgPSA4MDAgaG91cnMgYWdhaW5zdCB0aGUgYWx0ZXJuYXRpdmUsIMK1ICE9IDgwMCBob3VycywgaWYgYSByYW5kb20gc2FtcGxlIG9mIDMwIGJ1bGJzIGhhcyBhbiBhdmVyYWdlIGxpZmUgb2YgNzg4IGhvdXJzLiBVc2UgYSBQLXZhbHVlIGluIHlvdXIgYW5zd2VyLg0KDQpgYGB7cn0NCm4gPSAzMA0KbWl1ID0gODAwDQp4YmFyID0gNzg4DQpzZCA9IDQwDQoNCiNITyA6IMK1ID0gODAwDQojSDEgOiDCtSAhPSA4MDANCg0KDQojIC0tLS0tLSBTYW1wbGUgWi1UZXN0IEZ1bmN0aW9uIC0tLQ0KT25lU2FtcGxlX1ogPC0gZnVuY3Rpb24oeGJhciwgbWl1LCBzaWdtYSwgbiwgYWxwaGEgPSAwLjA1LCB0eXBlID0gInR3by50YWlsIikgew0KICANCiAgenNjb3JlIDwtICh4YmFyIC0gbWl1KSAvIChzaWdtYSAvIHNxcnQobikpDQogIA0KICBQREZfTm9ybWFsIDwtIGZ1bmN0aW9uKHgpIHsNCiAgICAxL3NxcnQoMipwaSkgKiBleHAoLXheMi8yKQ0KICB9DQogIA0KICAjIC0tLSBUcmFwZXpvaWRhbCBmdW5jdGlvbiB0byBmaW5kIFBERiAtLS0NCiAgdHJhcCA8LSBmdW5jdGlvbiAoZiwgYSwgYiwgbiA9IDEwMDApIHsNCiAgICAgIGggPSAoYiAtIGEpIC8gbg0KICAgICAgaW50ZWdyYWwgPSAoZihhKSArIGYoYikpIC8gMg0KICAgICAgZm9yIChpIGluIDE6KG4tMSkpIHsNCiAgICAgICAgaW50ZWdyYWwgPSBpbnRlZ3JhbCArIGYoYSArIGkgKiBoKQ0KICAgICAgfQ0KICAgICAgDQogICAgICBpbnRlZ3JhbCA9IGludGVncmFsICogaCANCiAgICAgIHJldHVybihpbnRlZ3JhbCkNCiAgfQ0KICANCiAgDQogICMgLS0tIE1hbnVhbCBpbnRlZ3JhdGlvbiB1c2luZyBUcmFwZXpvaWRhbCAtLS0NCiAgaWYgKHR5cGUgPT0gInR3by50YWlsIikgew0KICAgIHBfdHJhcCA8LSAyICogdHJhcChQREZfTm9ybWFsLCBhYnMoenNjb3JlKSwgMTAwKQ0KICB9IGVsc2UgaWYgKHR5cGUgPT0gImxvd2VyIikgew0KICAgIHBfdHJhcCA8LSB0cmFwKFBERl9Ob3JtYWwsIC0xMDAsIHpzY29yZSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfTm9ybWFsLCB6c2NvcmUsIDEwMCkNCiAgfQ0KICANCiAgDQogICMgLS0tIEJ1aWx0LWluIHBub3JtIGNvbXBhcmlzb24gLS0tDQogIGlmICh0eXBlID09ICJ0d28udGFpbCIpIHsNCiAgICBwX2J1aWx0aW4gPC0gMiAqICgxIC0gcG5vcm0oYWJzKHpzY29yZSkpKQ0KICAgIGNyaXRfdmFsIDwtIHFub3JtKDEgLSBhbHBoYSAvIDIpDQogIH0gZWxzZSBpZiAodHlwZSA9PSAibG93ZXIiKSB7DQogICAgcF9idWlsdGluIDwtIHBub3JtKHpzY29yZSkNCiAgICBjcml0X3ZhbCA8LSBxbm9ybShhbHBoYSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX2J1aWx0aW4gPC0gMSAtIHBub3JtKHpzY29yZSkNCiAgICBjcml0X3ZhbCA8LSBxbm9ybSgxIC0gYWxwaGEpDQogIH0NCiAgDQogIA0KICAjIC0tLSBPdXRwdXQgUmVzdWx0cyAtLS0NCiAgY2F0KCI9PT0gT25lIFNhbXBsZSBaLVRlc3QgPT09XG4iKQ0KICBjYXQoIlNhbXBsZSBtZWFuICh4zIQpICAgID0iICxyb3VuZCh4YmFyLCA0KSwgIlxuIikNCiAgY2F0KCJQb3B1bGF0aW9uIG1lYW4gzrwgID0iLCBtaXUsICJcbiIpDQogIGNhdCgiWi1zdGF0aXN0aWMgICAgICAgID0iLCByb3VuZCh6c2NvcmUsIDQpLCAiXG4iKQ0KICBjYXQoInAtdmFsdWUgKFRyYXApICAgICA9Iiwgcm91bmQocF90cmFwLCA1KSwgIlxuIikNCiAgY2F0KCJwLXZhbHVlIChwbm9ybSkgICAgPSIsIHJvdW5kKHBfYnVpbHRpbiwgNSksICJcbiIpDQogIGNhdCgiYWxwaGEgICAgICAgICAgICAgID0iLCBhbHBoYSwgIlxuIikNCiAgY2F0KCJDcml0aWNhbCBaIHZhbHVlICAgPSIsIHJvdW5kKGNyaXRfdmFsLCA0KSwgIlxuXG4iKQ0KICANCiAgaWYgKHBfYnVpbHRpbiA8IGFscGhhKSB7DQogICAgY2F0KCI+Pj4gUmVqZWN0IEgwIChTaWduaWZpY2FudClcbiIpDQogIH0gZWxzZSB7DQogICAgY2F0KCI+Pj4gRmFpbCB0byBSZWplY3QgSDAgKE5vdCBTaWduaWZpY2FudClcbiIpDQogIH0NCn0NCg0KT25lU2FtcGxlX1ooeGJhciwgbWl1LCBzZCwgbikNCmBgYA0KIyMgKipPbmUgU2FtcGxlIHQgdGVzdCoqIA0KDQpUZXN0IHRoZSBoeXBvdGhlc2lzIHRoYXQgdGhlIGF2ZXJhZ2UgY29udGVudCBvZiBjb250YWluZXJzIG9mIGEgcGFydGljdWxhciBsdWJyaWNhbnQgaXMgMTAgbGl0ZXJzIGlmIHRoZSBjb250ZW50cyBvZiBhIHJhbmRvbSBzYW1wbGUgb2YgMTAgY29udGFpbmVycyBhcmUgMTAuMiwgOS43LCAxMC4xLCAxMC4zLCAxMC4xLCA5LjgsIDkuOSwgMTAuNCwgMTAuMywgYW5kIDkuOCBsaXRlcnMuIFVzZSBhIDAuMDEgbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlIGFuZCBhc3N1bWUgdGhhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIGNvbnRlbnRzIGlzIG5vcm1hbC4NCg0KYGBge3J9DQoNCmRhdGEgPC0gYygxMC4yLCA5LjcsIDEwLjEsIDEwLjMsIDEwLjEsIDkuOCwgOS45LCAxMC40LCAxMC4zLCA5LjgpDQptaXUgPC0gMTANCg0KDQoNCk9uZVNhbXBsZV90IDwtIGZ1bmN0aW9uKHgsIG1pdSwgYWxwaGEgPSAwLjAxLCB0eXBlID0gInR3by50YWlsIikgew0KICANCiAgIyAtLS0gZGVmaW5lIHRoZSB4YmFyLCBzLCBldGMgLS0tDQogIG4gPSBsZW5ndGgoeCkNCiAgeF9iYXIgPSBzdW0oeCkvbg0KICBzID0gc2QoeCkNCiAgdiA9IG4tMQ0KICANCiAgIyAtLS0gZGVmaW5lIHRoZSB0c2NvcmUgYW5kIHBkZiAtLS0NCiAgDQogIHRfc2NvcmUgPSAoeF9iYXIgLSBtaXUpIC8gKHMvIHNxcnQobikpDQogIA0KICBQREZfdCA8LSBmdW5jdGlvbih0LCB2KSB7DQogIChnYW1tYSgodisxKS8yKSAvIChzcXJ0KHYqcGkpICogZ2FtbWEodi8yKSkpICogKDEgKyAodF4yKS92KV4oLSh2KzEpLzIpDQp9DQogIA0KICAjIC0tLSBUcmFwZXpvaWRhbCBmdW5jdGlvbiB0byBmaW5kIFBERiAtLS0NCiAgdHJhcCA8LSBmdW5jdGlvbiAoZiwgYSwgYiwgbiA9IDEwMDApIHsNCiAgICAgIGggPSAoYiAtIGEpIC8gbg0KICAgICAgaW50ZWdyYWwgPSAoZihhLCB2KSArIGYoYiwgdikpIC8gMg0KICAgICAgZm9yIChpIGluIDE6KG4tMSkpIHsNCiAgICAgICAgaW50ZWdyYWwgPSBpbnRlZ3JhbCArIGYoYSArIGkgKiBoLCB2KQ0KICAgICAgfQ0KICAgICAgDQogICAgICBpbnRlZ3JhbCA9IGludGVncmFsICogaCANCiAgICAgIHJldHVybihpbnRlZ3JhbCkNCiAgfQ0KICANCiAgDQogICMgLS0tIE1hbnVhbCBpbnRlZ3JhdGlvbiB1c2luZyBUcmFwZXpvaWRhbCAtLS0NCiAgaWYgKHR5cGUgPT0gInR3by50YWlsIikgew0KICAgIHBfdHJhcCA8LSAyICogdHJhcChQREZfdCwgYWJzKHRfc2NvcmUpLCAxMDApDQogIH0gZWxzZSBpZiAodHlwZSA9PSAibG93ZXIiKSB7DQogICAgcF90cmFwIDwtIHRyYXAoUERGX3QsIC0xMDAsIHRfc2NvcmUpDQogIH0gZWxzZSBpZiAodHlwZSA9PSAidXBwZXIiKSB7DQogICAgcF90cmFwIDwtIHRyYXAoUERGX3QsIHRfc2NvcmUsIDEwMCkNCiAgfQ0KICANCiAgDQogICMgLS0tIEJ1aWx0LWluIHBub3JtIGNvbXBhcmlzb24gLS0tDQogIGlmICh0eXBlID09ICJ0d28udGFpbCIpIHsNCiAgICBwX2J1aWx0aW4gPC0gMiAqICgxIC0gcHQoYWJzKHRfc2NvcmUpLHYpKQ0KICAgIGNyaXRfdmFsIDwtIHF0KDEgLSBhbHBoYSAvIDIsdikNCiAgfSBlbHNlIGlmICh0eXBlID09ICJsb3dlciIpIHsNCiAgICBwX2J1aWx0aW4gPC0gcHQodF9zY29yZSwgdikNCiAgICBjcml0X3ZhbCA8LSBxdChhbHBoYSx2KQ0KICB9IGVsc2UgaWYgKHR5cGUgPT0gInVwcGVyIikgew0KICAgIHBfYnVpbHRpbiA8LSAxIC0gcHQodF9zY29yZSx2KQ0KICAgIGNyaXRfdmFsIDwtIHF0KDEgLSBhbHBoYSx2KQ0KICB9DQogIA0KICANCiAgIyAtLS0gT3V0cHV0IFJlc3VsdHMgLS0tDQogIGNhdCgiPT09IE9uZSBTYW1wbGUgWi1UZXN0ID09PVxuIikNCiAgY2F0KCJTYW1wbGUgbWVhbiAoeMyEKSAgICA9IiAscm91bmQoeF9iYXIsIDQpLCAiXG4iKQ0KICBjYXQoIlBvcHVsYXRpb24gbWVhbiDOvCAgPSIsIG1pdSwgIlxuIikNCiAgY2F0KCJ0LXN0YXRpc3RpYyAgICAgICAgPSIsIHJvdW5kKHRfc2NvcmUsIDQpLCAiXG4iKQ0KICBjYXQoInAtdmFsdWUgKFRyYXApICAgICA9Iiwgcm91bmQocF90cmFwLCA1KSwgIlxuIikNCiAgY2F0KCJwLXZhbHVlIChwbm9ybSkgICAgPSIsIHJvdW5kKHBfYnVpbHRpbiwgNSksICJcbiIpDQogIGNhdCgiYWxwaGEgICAgICAgICAgICAgID0iLCBhbHBoYSwgIlxuIikNCiAgY2F0KCJDcml0aWNhbCB0IHZhbHVlICAgPSIsIHJvdW5kKGNyaXRfdmFsLCA0KSwgIlxuXG4iKQ0KICANCiAgaWYgKHBfYnVpbHRpbiA8IGFscGhhKSB7DQogICAgY2F0KCI+Pj4gUmVqZWN0IEgwIChTaWduaWZpY2FudClcbiIpDQogIH0gZWxzZSB7DQogICAgY2F0KCI+Pj4gRmFpbCB0byBSZWplY3QgSDAgKE5vdCBTaWduaWZpY2FudClcbiIpDQogIH0NCn0NCg0KT25lU2FtcGxlX3QoZGF0YSwgbWl1KQ0KDQpgYGANCiMjICoqVHdvIFNhbXBsZSBaLXRlc3QqKg0KDQpBIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSBuMSA9IDI1LCB0YWtlbiBmcm9tIGEgbm9ybWFsIHBvcHVsYXRpb24gd2l0aCBhIHN0YW5kYXJkIGRldmlhdGlvbiDPgzEgPSA1LjIsIGhhcyBhIG1lYW4geGJhcjEgPSA4MS4gQSBzZWNvbmQgcmFuZG9tIHNhbXBsZSBvZiBzaXplIG4yID0gMzYsIHRha2VuIGZyb20gYSBkaWZmZXJlbnQgbm9ybWFsIHBvcHVsYXRpb24gd2l0aCBhIHN0YW5kYXJkIGRldmlhdGlvbiDPgzIgPSAzLjQsIGhhcyBhIG1lYW4geGJhcjIgPSA3Ni4gVGVzdCB0aGUgaHlwb3RoZXNpcyB0aGF0IM68MSA9IM68MiBhZ2FpbnN0IHRoZSBhbHRlcm5hdGl2ZSwgzrwxICE9IM68Mi4gUXVvdGUgYSBQLXZhbHVlIGluIHlvdXIgY29uY2x1c2lvbg0KDQpgYGB7cn0NCm4xID0gMjUNCnNkMSA9IDUuMg0KeGJhcjEgPSA4MQ0KDQpuMiA9IDM2DQpzZDIgPSAzLjQNCnhiYXIyID0gNzYNCg0KIyBIMCA6IM68MSA9IM68Mg0KIyBIMSA6IM68MSAhPSDOvDINCg0KVHdvU2FtcGxlX1ogPC0gZnVuY3Rpb24oeGJhcjEsIHhiYXIyLCBzaWdtYTEsIHNpZ21hMiwgbjEsIG4yLCBhbHBoYSA9IDAuMDUsIGQwID0gMCwgdHlwZSA9ICJ0d28udGFpbCIpIHsNCiAgDQogIHpzY29yZSA8LSAoeGJhcjEgLSB4YmFyMiAtIGQwKSAvIHNxcnQoKHNpZ21hMV4yL24xKSArIChzaWdtYTJeMi9uMikpDQogIA0KICBQREZfTm9ybWFsIDwtIGZ1bmN0aW9uKHgpIHsNCiAgICAxL3NxcnQoMipwaSkgKiBleHAoLXheMi8yKQ0KICB9DQogIA0KICAjIC0tLSBUcmFwZXpvaWRhbCBmdW5jdGlvbiB0byBmaW5kIFBERiAtLS0NCiAgdHJhcCA8LSBmdW5jdGlvbiAoZiwgYSwgYiwgbiA9IDEwMDApIHsNCiAgICAgIGggPSAoYiAtIGEpIC8gbg0KICAgICAgaW50ZWdyYWwgPSAoZihhKSArIGYoYikpIC8gMg0KICAgICAgZm9yIChpIGluIDE6KG4tMSkpIHsNCiAgICAgICAgaW50ZWdyYWwgPSBpbnRlZ3JhbCArIGYoYSArIGkgKiBoKQ0KICAgICAgfQ0KICAgICAgDQogICAgICBpbnRlZ3JhbCA9IGludGVncmFsICogaCANCiAgICAgIHJldHVybihpbnRlZ3JhbCkNCiAgfQ0KICANCiAgDQogICMgLS0tIE1hbnVhbCBpbnRlZ3JhdGlvbiB1c2luZyBUcmFwZXpvaWRhbCAtLS0NCiAgaWYgKHR5cGUgPT0gInR3by50YWlsIikgew0KICAgIHBfdHJhcCA8LSAyICogdHJhcChQREZfTm9ybWFsLCBhYnMoenNjb3JlKSwgMTAwKQ0KICB9IGVsc2UgaWYgKHR5cGUgPT0gImxvd2VyIikgew0KICAgIHBfdHJhcCA8LSB0cmFwKFBERl9Ob3JtYWwsIC0xMDAsIHpzY29yZSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfTm9ybWFsLCB6c2NvcmUsIDEwMCkNCiAgfQ0KICANCiAgDQogICMgLS0tIEJ1aWx0LWluIHBub3JtIGNvbXBhcmlzb24gLS0tDQogIGlmICh0eXBlID09ICJ0d28udGFpbCIpIHsNCiAgICBwX2J1aWx0aW4gPC0gMiAqICgxIC0gcG5vcm0oYWJzKHpzY29yZSkpKQ0KICAgIGNyaXRfdmFsIDwtIHFub3JtKDEgLSBhbHBoYSAvIDIpDQogIH0gZWxzZSBpZiAodHlwZSA9PSAibG93ZXIiKSB7DQogICAgcF9idWlsdGluIDwtIHBub3JtKHpzY29yZSkNCiAgICBjcml0X3ZhbCA8LSBxbm9ybShhbHBoYSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX2J1aWx0aW4gPC0gMSAtIHBub3JtKHpzY29yZSkNCiAgICBjcml0X3ZhbCA8LSBxbm9ybSgxIC0gYWxwaGEpDQogIH0NCiAgDQogIA0KICAjIC0tLSBPdXRwdXQgUmVzdWx0cyAtLS0NCiAgY2F0KCI9PT0gVHdvIFNhbXBsZSBaLVRlc3QgPT09XG4iKQ0KICBjYXQoIlNhbXBsZSBtZWFuICh4zIQxKSAgID0iICxyb3VuZCh4YmFyMSwgNCksICJcbiIpDQogIGNhdCgiU2FtcGxlIG1lYW4gKHjMhDIpICAgPSIgLHJvdW5kKHhiYXIyLCA0KSwgIlxuIikNCiAgY2F0KCJaLXN0YXRpc3RpYyAgICAgICAgPSIsIHJvdW5kKHpzY29yZSwgNCksICJcbiIpDQogIGNhdCgicC12YWx1ZSAoVHJhcCkgICAgID0iLCByb3VuZChwX3RyYXAsIDUpLCAiXG4iKQ0KICBjYXQoInAtdmFsdWUgKHBub3JtKSAgICA9Iiwgcm91bmQocF9idWlsdGluLCA1KSwgIlxuIikNCiAgY2F0KCJhbHBoYSAgICAgICAgICAgICAgPSIsIGFscGhhLCAiXG4iKQ0KICBjYXQoIkNyaXRpY2FsIFogdmFsdWUgICA9Iiwgcm91bmQoY3JpdF92YWwsIDQpLCAiXG5cbiIpDQogIA0KICBpZiAocF9idWlsdGluIDwgYWxwaGEpIHsNCiAgICBjYXQoIj4+PiBSZWplY3QgSDAgKFNpZ25pZmljYW50KVxuIikNCiAgfSBlbHNlIHsNCiAgICBjYXQoIj4+PiBGYWlsIHRvIFJlamVjdCBIMCAoTm90IFNpZ25pZmljYW50KVxuIikNCiAgfQ0KfQ0KDQpUd29TYW1wbGVfWih4YmFyMSwgeGJhcjIsIHNkMSwgc2QyLCBuMSwgbjIpDQoNCmBgYA0KDQojIyAqKlR3byBzYW1wbGUgdC10ZXN0LCB2YXJpYW5jZSBpcyBlcXVhbCoqDQoNClRvIGZpbmQgb3V0IHdoZXRoZXIgYSBuZXcgc2VydW0gd2lsbCBhcnJlc3QgbGV1a2VtaWEsIDkgbWljZSwgYWxsIHdpdGggYW4gYWR2YW5jZWQgc3RhZ2Ugb2YgdGhlIGRpc2Vhc2UsIGFyZSBzZWxlY3RlZC4gRml2ZSBtaWNlIHJlY2VpdmUgdGhlIHRyZWF0bWVudCBhbmQgNCBkbyBub3QuIFN1cnZpdmFsIHRpbWVzLCBpbiB5ZWFycywgZnJvbSB0aGUgdGltZSB0aGUgZXhwZXJpbWVudCBjb21tZW5jZWQgYXJlIGFzIGZvbGxvd3M6IA0KDQpUcmVhdG1lbnQgPSAyLjEsIDUuMywgMS40LCA0LjYsIDAuOQ0KTm8gVHJlYXRtZW50ID0gMS45LCAwLjUsIDIuOCwgMy4xDQoNCkF0IHRoZSAwLjA1IGxldmVsIG9mIHNpZ25pZmljYW5jZSwgY2FuIHRoZSBzZXJ1bSBiZSBzYWlkIHRvIGJlIGVmZmVjdGl2ZT8gQXNzdW1lIHRoZSB0d28gcG9wdWxhdGlvbiB0byBiZSBub3JtYWxseSBkaXN0cmlidXRlZCB3aXRoIGVxdWFsIHZhcmlhbmNlcy4gDQpgYGB7cn0NCmRhdGExIDwtIGMoMi4xLCA1LjMsIDEuNCwgNC42LCAwLjkpDQpkYXRhMiA8LSBjKDEuOSwgMC41LCAyLjgsIDMuMSkNCg0KIyBIMCA6IFRoZSBzZXJ1bSBpcyBlZmZlY3RpdmUgKM68MSA9IM68MikNCiMgSDEgOiBUaGUgc2VydW0gaXMgbm90IGVmZmVjdGl2ZQ0KDQpUd29TYW1wbGVfdF9zYW1lIDwtIGZ1bmN0aW9uKHgxLCB4MiwgYWxwaGEgPSAwLjA1LCB0eXBlID0gInR3by50YWlsIiwgZDAgPSAwKSB7DQogIA0KICAjIC0tLSBkZWZpbmUgdGhlIHhiYXIsIHMsIGV0YyAtLS0NCiAgbjEgPSBsZW5ndGgoeDEpDQogIG4yID0gbGVuZ3RoICh4MikNCiAgeF9iYXIxID0gc3VtKHgxKS9uMQ0KICB4X2JhcjIgPSBzdW0oeDIpL24yDQogIHMxID0gc2QoeDEpDQogIHMyID0gc2QoeDIpDQogIHYgPSAobjEgKyBuMikgLSAyDQogIHNwXzIgPSAoKChuMSAtIDEpKnMxXjIpICsgKChuMiAtIDEpKnMyXjIpKSAvIHYNCiAgc3AgPSBzcXJ0KHNwXzIpDQogIA0KICAjIC0tLSBkZWZpbmUgdGhlIHRzY29yZSBhbmQgcGRmIC0tLQ0KICANCiAgdF9zY29yZSA9ICh4X2JhcjEgLSB4X2JhcjIgLSBkMCkgLyAoc3Aqc3FydCgoMS9uMSkrKDEvbjIpKSkNCiAgDQogIFBERl90IDwtIGZ1bmN0aW9uKHQsIHYpIHsNCiAgKGdhbW1hKCh2KzEpLzIpIC8gKHNxcnQodipwaSkgKiBnYW1tYSh2LzIpKSkgKiAoMSArICh0XjIpL3YpXigtKHYrMSkvMikNCn0NCiAgDQogICMgLS0tIFRyYXBlem9pZGFsIGZ1bmN0aW9uIHRvIGZpbmQgUERGIC0tLQ0KICB0cmFwIDwtIGZ1bmN0aW9uIChmLCBhLCBiLCBuID0gMTAwMCkgew0KICAgICAgaCA9IChiIC0gYSkgLyBuDQogICAgICBpbnRlZ3JhbCA9IChmKGEsIHYpICsgZihiLCB2KSkgLyAyDQogICAgICBmb3IgKGkgaW4gMToobi0xKSkgew0KICAgICAgICBpbnRlZ3JhbCA9IGludGVncmFsICsgZihhICsgaSAqIGgsIHYpDQogICAgICB9DQogICAgICANCiAgICAgIGludGVncmFsID0gaW50ZWdyYWwgKiBoIA0KICAgICAgcmV0dXJuKGludGVncmFsKQ0KICB9DQogIA0KICANCiAgIyAtLS0gTWFudWFsIGludGVncmF0aW9uIHVzaW5nIFRyYXBlem9pZGFsIC0tLQ0KICBpZiAodHlwZSA9PSAidHdvLnRhaWwiKSB7DQogICAgcF90cmFwIDwtIDIgKiB0cmFwKFBERl90LCBhYnModF9zY29yZSksIDEwMCkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJsb3dlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfdCwgLTEwMCwgdF9zY29yZSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfdCwgdF9zY29yZSwgMTAwKQ0KICB9DQogIA0KICANCiAgIyAtLS0gQnVpbHQtaW4gcG5vcm0gY29tcGFyaXNvbiAtLS0NCiAgaWYgKHR5cGUgPT0gInR3by50YWlsIikgew0KICAgIHBfYnVpbHRpbiA8LSAyICogKDEgLSBwdChhYnModF9zY29yZSksdikpDQogICAgY3JpdF92YWwgPC0gcXQoMSAtIGFscGhhIC8gMix2KQ0KICB9IGVsc2UgaWYgKHR5cGUgPT0gImxvd2VyIikgew0KICAgIHBfYnVpbHRpbiA8LSBwdCh0X3Njb3JlLCB2KQ0KICAgIGNyaXRfdmFsIDwtIHF0KGFscGhhLHYpDQogIH0gZWxzZSBpZiAodHlwZSA9PSAidXBwZXIiKSB7DQogICAgcF9idWlsdGluIDwtIDEgLSBwdCh0X3Njb3JlLHYpDQogICAgY3JpdF92YWwgPC0gcXQoMSAtIGFscGhhLHYpDQogIH0NCiAgDQogIA0KICAjIC0tLSBPdXRwdXQgUmVzdWx0cyAtLS0NCiAgY2F0KCI9PT0gT25lIFNhbXBsZSBaLVRlc3QgPT09XG4iKQ0KICBjYXQoIlNhbXBsZSBtZWFuICh4zIQxKSAgICA9IiAscm91bmQoeF9iYXIxLCA0KSwgIlxuIikNCiAgY2F0KCJTYW1wbGUgbWVhbiAoeDIpICAgID0iICxyb3VuZCh4X2JhcjIsIDQpLCAiXG4iKQ0KICBjYXQoIlBvcHVsYXRpb24gbWVhbiDOvCAgPSIsIG1pdSwgIlxuIikNCiAgY2F0KCJ0LXN0YXRpc3RpYyAgICAgICAgPSIsIHJvdW5kKHRfc2NvcmUsIDQpLCAiXG4iKQ0KICBjYXQoInAtdmFsdWUgKFRyYXApICAgICA9Iiwgcm91bmQocF90cmFwLCA1KSwgIlxuIikNCiAgY2F0KCJwLXZhbHVlIChwbm9ybSkgICAgPSIsIHJvdW5kKHBfYnVpbHRpbiwgNSksICJcbiIpDQogIGNhdCgiYWxwaGEgICAgICAgICAgICAgID0iLCBhbHBoYSwgIlxuIikNCiAgY2F0KCJDcml0aWNhbCB0IHZhbHVlICAgPSIsIHJvdW5kKGNyaXRfdmFsLCA0KSwgIlxuXG4iKQ0KICANCiAgaWYgKHBfYnVpbHRpbiA8IGFscGhhKSB7DQogICAgY2F0KCI+Pj4gUmVqZWN0IEgwIChTaWduaWZpY2FudClcbiIpDQogIH0gZWxzZSB7DQogICAgY2F0KCI+Pj4gRmFpbCB0byBSZWplY3QgSDAgKE5vdCBTaWduaWZpY2FudClcbiIpDQogIH0NCn0NCg0KVHdvU2FtcGxlX3Rfc2FtZShkYXRhMSwgZGF0YTIpDQpgYGANCg0KIyMgKipUd28gc2FtcGxlIHQtdGVzdCwgdmFyaWFuY2UgaXMgbm90IGVxdWFsKioNCg0KQSBzdHVkeSB3YXMgY29uZHVjdGVkIGJ5IHRoZSBEZXBhcnRtZW50IG9mIFpvb2xvZ3kgYXQgVmlyZ2luaWEgVGVjaCB0byBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRoZSBkZW5zaXR5IG9mIG9yZ2FuaXNtcyBhdCB0d28gZGlmZmVyZW50IHN0YXRpb25zIGxvY2F0ZWQgb24gQ2VkYXIgUnVuLCBhIHNlY29uZGFyeSBzdHJlYW0gaW4gdGhlIFJvYW5va2UgUml2ZXIgZHJhaW5hZ2UgYmFzaW4uIFNld2FnZSBmcm9tIGEgc2V3YWdlIHRyZWF0bWVudCBwbGFudCBhbmQgb3ZlcmZsb3cgZnJvbSB0aGUgRmVkZXJhbCBNb2d1bCBDb3Jwb3JhdGlvbiBzZXR0bGluZyBwb25kIGVudGVyIHRoZSBzdHJlYW0gbmVhciBpdHMgaGVhZHdhdGVycy4gVGhlIGZvbGxvd2luZyBkYXRhIGdpdmUgdGhlIGRlbnNpdHkgbWVhc3VyZW1lbnRzLCBpbiBudW1iZXIgb2Ygb3JnYW5pc21zIHBlciBzcXVhcmUgbWV0ZXIsIGF0IHRoZSB0d28gY29sbGVjdGluZyBzdGF0aW9ucw0KDQpTdGF0aW9uIDEgPSA1MDMwLCAxMzcwMCwgMTA3MzAsIDExNDAwLCA4NjAsIDIyMDAsIDQyNTAsIDE1MDQwLCA0OTgwLCAxMTkxMCwgODEzMCwgMjY4NTAsIDE3NjYwLCAyMjgwMCwgMTEzMCwgMTY5MA0KU3RhdGlvbiAyID0gMjgwMCwgNDY3MCwgNjg5MCwgNzcyMCwgNzAzMCwgNzMzMCwgMjgxMCwgMTMzMCwgMzMyMCwgMTIzMCwgMjEzMCwgMjE5MA0KDQpDYW4gd2UgY29uY2x1ZGUsIGF0IHRoZSAwLjA1IGxldmVsIG9mIHNpZ25pZmljYW5jZSwgdGhhdCB0aGUgYXZlcmFnZSBkZW5zaXRpZXMgYXQgdGhlIHR3byBzdGF0aW9ucyBhcmUgZXF1YWw/IEFzc3VtZSB0aGF0IHRoZSBvYnNlcnZhdGlvbnMgY29tZSBmcm9tIG5vcm1hbCBwb3B1bGF0aW9ucyB3aXRoIGRpZmZlcmVudCB2YXJpYW5jZXMuDQoNCmBgYHtyfQ0Kc3RhdGlvbjEgPC0gYyg1MDMwLCAxMzcwMCwgMTA3MzAsIDExNDAwLCA4NjAsIDIyMDAsIDQyNTAsIDE1MDQwLCA0OTgwLCAxMTkxMCwgODEzMCwgMjY4NTAsIDE3NjYwLCAyMjgwMCwgMTEzMCwgMTY5MCkNCnN0YXRpb24yIDwtIGMoMjgwMCwgNDY3MCwgNjg5MCwgNzcyMCwgNzAzMCwgNzMzMCwgMjgxMCwgMTMzMCwgMzMyMCwgMTIzMCwgMjEzMCwgMjE5MCkNCg0KVHdvU2FtcGxlX3RfZGlmZiA8LSBmdW5jdGlvbih4MSwgeDIsIGFscGhhID0gMC4wNSwgdHlwZSA9ICJ0d28udGFpbCIsIGQwID0gMCkgew0KICANCiAgIyAtLS0gZGVmaW5lIHRoZSB4YmFyLCBzLCBldGMgLS0tDQogIG4xID0gbGVuZ3RoKHgxKQ0KICBuMiA9IGxlbmd0aCAoeDIpDQogIHhfYmFyMSA9IHN1bSh4MSkvbjENCiAgeF9iYXIyID0gc3VtKHgyKS9uMg0KICBzMSA9IHNkKHgxKQ0KICBzMiA9IHNkKHgyKQ0KICBhID0gKChzMV4yL24xKSArIChzMl4yL24yKSleMg0KICBiID0gKCgoczFeMi9uMSleMikvKG4xLTEpKSArICgoKHMyXjIvbjIpXjIpLyhuMi0xKSkNCiAgdiA9IGEvYg0KICANCiAgDQogICMgLS0tIGRlZmluZSB0aGUgdHNjb3JlIGFuZCBwZGYgLS0tDQogIA0KICB0X3Njb3JlID0gKCh4X2JhcjEgLSB4X2JhcjIpIC0gZDApIC8gKHNxcnQoKHMxXjIvbjEpICsgKHMyXjIvbjIpKSkNCiAgDQogIFBERl90IDwtIGZ1bmN0aW9uKHQsIHYpIHsNCiAgKGdhbW1hKCh2KzEpLzIpIC8gKHNxcnQodipwaSkgKiBnYW1tYSh2LzIpKSkgKiAoMSArICh0XjIpL3YpXigtKHYrMSkvMikNCn0NCiAgDQogICMgLS0tIFRyYXBlem9pZGFsIGZ1bmN0aW9uIHRvIGZpbmQgUERGIC0tLQ0KICB0cmFwIDwtIGZ1bmN0aW9uIChmLCBhLCBiLCBuID0gMTAwMCkgew0KICAgICAgaCA9IChiIC0gYSkgLyBuDQogICAgICBpbnRlZ3JhbCA9IChmKGEsIHYpICsgZihiLCB2KSkgLyAyDQogICAgICBmb3IgKGkgaW4gMToobi0xKSkgew0KICAgICAgICBpbnRlZ3JhbCA9IGludGVncmFsICsgZihhICsgaSAqIGgsIHYpDQogICAgICB9DQogICAgICANCiAgICAgIGludGVncmFsID0gaW50ZWdyYWwgKiBoIA0KICAgICAgcmV0dXJuKGludGVncmFsKQ0KICB9DQogIA0KICANCiAgIyAtLS0gTWFudWFsIGludGVncmF0aW9uIHVzaW5nIFRyYXBlem9pZGFsIC0tLQ0KICBpZiAodHlwZSA9PSAidHdvLnRhaWwiKSB7DQogICAgcF90cmFwIDwtIDIgKiB0cmFwKFBERl90LCBhYnModF9zY29yZSksIDEwMCkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJsb3dlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfdCwgLTEwMCwgdF9zY29yZSkNCiAgfSBlbHNlIGlmICh0eXBlID09ICJ1cHBlciIpIHsNCiAgICBwX3RyYXAgPC0gdHJhcChQREZfdCwgdF9zY29yZSwgMTAwKQ0KICB9DQogIA0KICANCiAgIyAtLS0gQnVpbHQtaW4gcG5vcm0gY29tcGFyaXNvbiAtLS0NCiAgaWYgKHR5cGUgPT0gInR3by50YWlsIikgew0KICAgIHBfYnVpbHRpbiA8LSAyICogKDEgLSBwdChhYnModF9zY29yZSksdikpDQogICAgY3JpdF92YWwgPC0gcXQoMSAtIGFscGhhIC8gMix2KQ0KICB9IGVsc2UgaWYgKHR5cGUgPT0gImxvd2VyIikgew0KICAgIHBfYnVpbHRpbiA8LSBwdCh0X3Njb3JlLCB2KQ0KICAgIGNyaXRfdmFsIDwtIHF0KGFscGhhLHYpDQogIH0gZWxzZSBpZiAodHlwZSA9PSAidXBwZXIiKSB7DQogICAgcF9idWlsdGluIDwtIDEgLSBwdCh0X3Njb3JlLHYpDQogICAgY3JpdF92YWwgPC0gcXQoMSAtIGFscGhhLHYpDQogIH0NCiAgDQogIA0KICAjIC0tLSBPdXRwdXQgUmVzdWx0cyAtLS0NCiAgY2F0KCI9PT0gT25lIFNhbXBsZSBaLVRlc3QgPT09XG4iKQ0KICBjYXQoIlNhbXBsZSBtZWFuICh4zIQxKSAgICA9IiAscm91bmQoeF9iYXIxLCA0KSwgIlxuIikNCiAgY2F0KCJTYW1wbGUgbWVhbiAoeDIpICAgID0iICxyb3VuZCh4X2JhcjIsIDQpLCAiXG4iKQ0KICBjYXQoIlBvcHVsYXRpb24gbWVhbiDOvCAgPSIsIG1pdSwgIlxuIikNCiAgY2F0KCJ0LXN0YXRpc3RpYyAgICAgICAgPSIsIHJvdW5kKHRfc2NvcmUsIDQpLCAiXG4iKQ0KICBjYXQoInAtdmFsdWUgKFRyYXApICAgICA9Iiwgcm91bmQocF90cmFwLCA1KSwgIlxuIikNCiAgY2F0KCJwLXZhbHVlIChwbm9ybSkgICAgPSIsIHJvdW5kKHBfYnVpbHRpbiwgNSksICJcbiIpDQogIGNhdCgiYWxwaGEgICAgICAgICAgICAgID0iLCBhbHBoYSwgIlxuIikNCiAgY2F0KCJDcml0aWNhbCB0IHZhbHVlICAgPSIsIHJvdW5kKGNyaXRfdmFsLCA0KSwgIlxuXG4iKQ0KICANCiAgaWYgKHBfYnVpbHRpbiA8IGFscGhhKSB7DQogICAgY2F0KCI+Pj4gUmVqZWN0IEgwIChTaWduaWZpY2FudClcbiIpDQogIH0gZWxzZSB7DQogICAgY2F0KCI+Pj4gRmFpbCB0byBSZWplY3QgSDAgKE5vdCBTaWduaWZpY2FudClcbiIpDQogIH0NCn0NCg0KVHdvU2FtcGxlX3RfZGlmZihzdGF0aW9uMSwgc3RhdGlvbjIpDQpgYGANCg0K