Intro and Setup

For this exam, we will be examining and utilizing the Kumaraswamy distribution. This distribution is continuous, bounded between 0 and 1, and defined by two parameters (\(a\) and \(b\)).

With \(X\) denoting a Kumaraswamy random variable, the CDF of our distribution is the following.

\[\Large F(x; a,b) = 1 - (1-x^a)^b \]

Two special cases of the Kumaraswamy distribution are the uniform and power distributions. A distribution is uniform if \(a, b\) = 1, while such is power if \(a > 0, b = 1\).


Part A: Methodological Derivations

A1.)

Given the distribution’s cumulative function, we can use calculus-based methods to derive the probability density function (PDF). Said calculations were completed by hand and can be seen below.

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A1.jpg")

Moving forward, we define our density function as the following. \[\Large f(x; a, b) = ab \, x^{a-1} (1 - x^a)^{b-1}\]

A2.)

Now having our distribution’s density function, we can denote our log-likelihood, \(\ell(a,b)\), function and subsequent gradient vector. The gradient vector is made up of the partial derivatives of the log-likelihood function, first with respect to \(a\) then with respect to \(b\). Below are calculations and ultimate results.

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A2_1.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A2_2.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A2_3.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A2_4.jpg")

\[\Large \ell(a,b) = n\ln(a) + n\ln(b) + \left[ (a-1)\sum \ln(x_i) \right] + \left[ (b-1)\sum\ln(1-x_i^a) \right]\]

\[\Large \ell_a^\prime(a,b) = \frac{n}{a} + \left[ \sum\ln(x_i) \right] - \left[(b-1)\sum\frac{x_i^a \times \ln(x_i)}{1 - x_i^a} \right]\]

\[\Large \ell_b^\prime(a,b) = \frac{n}{b} + \sum\ln(1-x_i^a)\]

A3.)

Then taking the gradient vector components, I was able to calculate the Fisher information matrix (\(I\)), which is simply the negative of the Hessian matrix (composed of all second-derivative extensions of that distribution’s log-likelihood). The Fisher Information matrix for the Kumaraswamy distribution is below.

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A3_1.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A3_2.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A3_3.jpg")

A4.)

We now consider the power distribution, a special and more simplistic case of the Kumaraswamy distribution, which occurs when the parameter \(b\) = 1. Given the Kumaraswamy formula, a value of \(b\) = 1 means that the relative density function of the power distribution is \(ax^{a-1}\). Knowing this, below are formulas which can be used to estimate the parameter \(a\) via moment or maximum likelihood estimation (MOM or MLE).

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A4_1.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A4_2.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A4_3.jpg")

A5.)

Given an estimate of our parameter \(a\), (\(\hat{a}\)), we can setup a general confidence interval (CI) formula for the value of \(a\). Assuming 95% confidence, therefore a critical value of 1.96 predicated on the normal distribution, the makeup of the CI would look like the following.

The variance and standard deviation of the interval were found from the power distribution’s information matrix. The inverse of such matrix serves as the variance when applied in single-parameter scenarios.

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A5_1.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A5_2.jpg")

A6.)

The likelihood ratio test involves the subtraction of the log likelihood estimate of a simpler model (the uniform distribution in this case) from the log likelihood estimate of a more complex and more parameterized model (the power distribution in this scenario). This test is is meant to measure the improvement in fit that the more complex and unrestricted model provides.

Below shows the formula for what our test statistic, \(\Lambda\) would equal in this instance. Since \(\ell(1) = 0\), it is relatively straightforward. When performing a likelihood ratio test, the distribution of \(\Lambda\) follows a chi-squared distribution. Again assuming a 95% confidence level, we would consider any value of \(\Lambda\) greater than about 3.841 sufficient evidence to suggest there is value in using the more complex power distribution.

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A6_1.jpg")

knitr::include_graphics("/Users/chrisbahm/Library/Mobile Documents/com~apple~CloudDocs/West Chester/Spring 2026/STA 506 - Grad Math Stat 2 /STA 506 R Folder/Final/A6_2.jpg")


Part B: Numerical Analysis

# read in data
data = rbind.data.frame(0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22,
0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32,
0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42,
0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52,
0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.78)
colnames(data) = "storage"

The dataset we will analyze consists of 50 recorded usable storage proportions of a reservoir in a small town, with a value of 0 representing a basically empty reservoir and a value of 1 representing a full body of water. Summary statistics and a histogram of the data are below.

sum_stats_table = function(variable){
  table = cbind(
    round(min(variable),2),
    round(quantile(variable, 0.25),2),
    round(median(variable),2),
    round(mean(variable),2),
    round(quantile(variable, 0.75),2),
    round(max(variable),2)
  )
  colnames(table) = c("Min", "Q1", "Med", "Mean", "Q3", "Max")
  rownames(table) = NULL
  return(table)
}

Summary_Table = sum_stats_table(variable = data$storage)
kable(Summary_Table,align = "c",
      caption = "<span style='color:##000000;'>
      Summary Stats of Storage Volumes </span>") %>%
  kable_styling(
    bootstrap_options = c("striped", "bordered"),
    full_width = FALSE,
    position = "center")
Summary Stats of Storage Volumes
Min Q1 Med Mean Q3 Max
0.12 0.25 0.38 0.38 0.5 0.78
ggplot(data = data) +
  geom_histogram(mapping = aes(x = storage, y = after_stat(density)),
                 color = "black",
                  # argument color in geom_histogram is for color of bin lines
                 fill = "lightblue",
                 bins = 10,) +
  labs(title = "Distribution of Storage Volumes",
       x = "Storage Volume",
       y = "Probabiity Density") + 
  theme(
    panel.border = element_rect(color = "black", fill = NA, linewidth = 3)
  ) # this is the equivalent of box(lwd = 3) in base R

B1.)

Now using the available sample data, and assuming a Kumaraswamy distribution is applicable in this case, I will perform MLE to estimate parameters \(a\) and \(b\). Key formulas for such calculation are the log likelihood and gradient functions seen below.

\[\Large \ell(a,b) = n\ln(a) + n\ln(b) + \left[ (a-1)\sum \ln(x_i) \right] + \left[ (b-1)\sum\ln(1-x_i^a) \right]\]

\[\Large \ell_a^\prime(a,b) = \frac{n}{a} + \left[ \sum\ln(x_i) \right] - \left[(b-1)\sum\frac{x_i^a \times \ln(x_i)}{1 - x_i^a} \right]\]

\[\Large \ell_b^\prime(a,b) = \frac{n}{b} + \sum\ln(1-x_i^a)\]

## first define log likelihood of Kumaraswamy distribution
log_like_kum = function(parameters, data){
    a = parameters[1]
    b = parameters[2]
    n = length(data)
    
    log_likelihood = n * log(a) + 
      n * log(b) + 
      (a-1) * sum(log(data)) + 
      (b-1) * sum(log(1-data^a))
    }

## gradient functions
gradient_kum = function(parameters, data){
    a = parameters[1]
    b = parameters[2]
    n = length(data)
    
    ## partial derivative with respect to a
    partial_a = n/a +
      sum(log(data)) -
      (b-1)*sum((data^a*log(data))/(1-data^a))
    
    ## partial derivative with respect to b 
    partial_b = n/b + sum(log(1-data^a))
    
    return(c(partial_a,
             partial_b))
  
    }

## now get an MLE estimate
mle_kum = optim(
    par = c(a = 1.5, b = 5),
      # tried MANY different starting estimates, continued to adjust based on histogram visual below.
    fn = log_like_kum,
    gr = gradient_kum,
    data = data$storage,
   # method = "L-BFGS-B",
    hessian = TRUE,
    control = list(trace = FALSE,
                   fnscale = -1,
                   maxit = 500,
                   abstol = 1e-8)
    )

mle_kum_a_estimate = mle_kum$par[1] # a
  ## controls behavior near 0
mle_kum_b_estimate = mle_kum$par[2] # b
  ## controls behavior approaching 1 / think right tail

Using R’s optim function, and performing numerous iterations with different starting parameter estimates of both \(a\) and \(b\), a reasonable estimate for the two shape parameters are 2 and 5 respectively. Below is a visual of our sample data with a Kumaraswamy distribution curve with said parameter values additionally overlaid.

library(extraDistr) # needed to plot Kumaraswamy distribution curve

## visual confirmation
ggplot(data = data) +
  geom_histogram(mapping = aes(x = storage, y = after_stat(density)),
                 color = "black",
                 fill = "lightblue",
                 bins = 10,) +
      stat_function(fun = dkumar, 
                args = list(a = mle_kum_a_estimate, b = mle_kum_b_estimate),
                color = "black",
                linewidth = 1.5,
                xlim = range(0:1))+
  labs(title = "Distribution of Storage Volumes",
       x = "Storage Volume",
       y = "Probabiity Density") + 
  theme(
    panel.border = element_rect(color = "black", fill = NA, linewidth = 3)
  ) 

B2.) PICK UP HERE

## same procedure as B1, now use power distribution characteristics
log_like_power = function(a, data){
    n = length(data)
    log_likelihood = n * log(a) +
      (a-1)*sum(log(data))
    }

gradient_power = function(a, data){
    partial_a = n/a + sum(log(data))
    return(partial_a)
    }

B3.)

B4.)

LS0tCnRpdGxlOiAiU1RBIDUwNiBGaW5hbCBFeGFtOiBFc3RpbWF0aW9uIHcvIEt1bWFyYXN3YW15IERpc3RyaWJ1dGlvbiIKYXV0aG9yOiAiQ2hyaXMgQmFobSIKZGF0ZTogIk1heSA1LCAyMDI2IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgdG9jX2RlcHRoOiA0CiAgICBmaWdfd2lkdGg6IDYKICAgIGZpZ19oZWlnaHQ6IDQKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBsdW1lbgogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgc2VsZl9jb250YWluZWQ6IGZhbHNlCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICB3b3JkX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKLS0tCgpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9CmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47CiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7CiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOwogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOwp9CgpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLwogIGZvbnQtc2l6ZTogMjRweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogIGNvbG9yOiBEYXJrQmx1ZTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgxIHsgLyogSGVhZGVyIDEgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMjBweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogZGFya3JlZDsKICAgIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxOHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxNnB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxNHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogZGFya3JlZDsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8KLmhlYWRlci1zZWN0aW9uLW51bWJlcjo6YWZ0ZXIgewogIGNvbnRlbnQ6ICIuIjsKfQpgYGAKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLgoKaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7ICAgICAgICAgICAgICAgICAgICAgICMgdXNlIGNvbmRpdGlvbmFsIHN0YXRlbWVudCB0byBkZXRlY3QKICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKSAgICAgICAgICAgICAgICAgICMgd2hldGhlciBhIHBhY2thZ2Ugd2FzIGluc3RhbGxlZCBpbgogICBsaWJyYXJ5KGtuaXRyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3VyIG1hY2hpbmUuIElmIG5vdCwgaW5zdGFsbCBpdCBhbmQKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbG9hZCBpdCB0byB0aGUgd29ya2luZyBkaXJlY3RvcnkuCgppZiAoIXJlcXVpcmUodGlkeXZlcnNlKSkge2xpYnJhcnkodGlkeXZzZXJzZSl9IAoKaWYgKCFyZXF1aXJlKEdHYWxseSkpIHtsaWJyYXJ5KEdHYWxseSl9IAoKaWYgKCFyZXF1aXJlKGthYmxlRXh0cmEpKSB7bGlicmFyeShrYWJsZUV4dHJhKX0gCgppZiAoIXJlcXVpcmUoZ2dwbG90MikpIHtsaWJyYXJ5KGdncGxvdDIpfSAKCmlmICghcmVxdWlyZShjYXIpKSB7bGlicmFyeShjYXIpfSAKCmlmICghcmVxdWlyZShkcGx5cikpIHtsaWJyYXJ5KGRwbHlyKX0gCgppZiAoIXJlcXVpcmUocGFuZGVyKSkge2xpYnJhcnkocGFuZGVyKX0gCgppZiAoIXJlcXVpcmUoZm9yZWNhc3QpKSB7bGlicmFyeShmb3JlY2FzdCl9IAoKaWYgKCFyZXF1aXJlKGx1YnJpZGF0ZSkpIHtsaWJyYXJ5KGx1YnJpZGF0ZSl9IAoKaWYgKCFyZXF1aXJlKCJzY2FsZXMiKSkgewppbnN0YWxsLnBhY2thZ2VzKCJzY2FsZXMiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKbGlicmFyeSgic2NhbGVzIikgCn0KCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKCWVjaG8gPSBUUlVFLAoJbWVzc2FnZSA9IEZBTFNFLAoJd2FybmluZyA9IEZBTFNFLAoJY29tbWVudCA9IE5BLAoJcmVzdWx0cyA9IFRSVUUsCglmaWcuYWxpZ24gPSAiY2VudGVyIgopCmBgYAoKIyBJbnRybyBhbmQgU2V0dXAKRm9yIHRoaXMgZXhhbSwgd2Ugd2lsbCBiZSBleGFtaW5pbmcgYW5kIHV0aWxpemluZyB0aGUgKipLdW1hcmFzd2FteSBkaXN0cmlidXRpb24qKi4gVGhpcyBkaXN0cmlidXRpb24gaXMgY29udGludW91cywgYm91bmRlZCBiZXR3ZWVuIDAgYW5kIDEsIGFuZCBkZWZpbmVkIGJ5IHR3byBwYXJhbWV0ZXJzICgkYSQgYW5kICRiJCkuCgpXaXRoICRYJCBkZW5vdGluZyBhIEt1bWFyYXN3YW15IHJhbmRvbSB2YXJpYWJsZSwgdGhlIENERiBvZiBvdXIgZGlzdHJpYnV0aW9uIGlzIHRoZSBmb2xsb3dpbmcuCgokJFxMYXJnZSBGKHg7IGEsYikgPSAxIC0gKDEteF5hKV5iICQkCgpUd28gc3BlY2lhbCBjYXNlcyBvZiB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uIGFyZSB0aGUgdW5pZm9ybSBhbmQgcG93ZXIgZGlzdHJpYnV0aW9ucy4gQSBkaXN0cmlidXRpb24gaXMgdW5pZm9ybSBpZiAkYSwgYiQgPSAxLCB3aGlsZSBzdWNoIGlzIHBvd2VyIGlmICRhID4gMCwgYiA9IDEkLgoKPGJyPgoKIyBQYXJ0IEE6IE1ldGhvZG9sb2dpY2FsIERlcml2YXRpb25zCgojIyBBMS4pCkdpdmVuIHRoZSBkaXN0cmlidXRpb24ncyBjdW11bGF0aXZlIGZ1bmN0aW9uLCB3ZSBjYW4gdXNlIGNhbGN1bHVzLWJhc2VkIG1ldGhvZHMgdG8gZGVyaXZlIHRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGZ1bmN0aW9uIChQREYpLiBTYWlkIGNhbGN1bGF0aW9ucyB3ZXJlIGNvbXBsZXRlZCBieSBoYW5kIGFuZCBjYW4gYmUgc2VlbiBiZWxvdy4KCmBgYHtyLCBvdXQud2lkdGg9IjUwJSJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIvVXNlcnMvY2hyaXNiYWhtL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL1dlc3QgQ2hlc3Rlci9TcHJpbmcgMjAyNi9TVEEgNTA2IC0gR3JhZCBNYXRoIFN0YXQgMiAvU1RBIDUwNiBSIEZvbGRlci9GaW5hbC9BMS5qcGciKQpgYGAKCk1vdmluZyBmb3J3YXJkLCB3ZSBkZWZpbmUgb3VyIGRlbnNpdHkgZnVuY3Rpb24gYXMgdGhlIGZvbGxvd2luZy4KJCRcTGFyZ2UgIGYoeDsgYSwgYikgPSBhYiBcLCB4XnthLTF9ICgxIC0geF5hKV57Yi0xfSQkCgojIyBBMi4pIApOb3cgaGF2aW5nIG91ciBkaXN0cmlidXRpb24ncyBkZW5zaXR5IGZ1bmN0aW9uLCB3ZSBjYW4gZGVub3RlIG91ciBsb2ctbGlrZWxpaG9vZCwgJFxlbGwoYSxiKSQsIGZ1bmN0aW9uIGFuZCBzdWJzZXF1ZW50IGdyYWRpZW50IHZlY3Rvci4gVGhlIGdyYWRpZW50IHZlY3RvciBpcyBtYWRlIHVwIG9mIHRoZSBwYXJ0aWFsIGRlcml2YXRpdmVzIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiwgZmlyc3Qgd2l0aCByZXNwZWN0IHRvICRhJCB0aGVuIHdpdGggcmVzcGVjdCB0byAkYiQuIEJlbG93IGFyZSBjYWxjdWxhdGlvbnMgYW5kIHVsdGltYXRlIHJlc3VsdHMuCgpgYGB7ciwgb3V0LndpZHRoPSI1MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTJfMS5qcGciKQoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi9Vc2Vycy9jaHJpc2JhaG0vTGlicmFyeS9Nb2JpbGUgRG9jdW1lbnRzL2NvbX5hcHBsZX5DbG91ZERvY3MvV2VzdCBDaGVzdGVyL1NwcmluZyAyMDI2L1NUQSA1MDYgLSBHcmFkIE1hdGggU3RhdCAyIC9TVEEgNTA2IFIgRm9sZGVyL0ZpbmFsL0EyXzIuanBnIikKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIvVXNlcnMvY2hyaXNiYWhtL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL1dlc3QgQ2hlc3Rlci9TcHJpbmcgMjAyNi9TVEEgNTA2IC0gR3JhZCBNYXRoIFN0YXQgMiAvU1RBIDUwNiBSIEZvbGRlci9GaW5hbC9BMl8zLmpwZyIpCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTJfNC5qcGciKQpgYGAKCgokJFxMYXJnZSBcZWxsKGEsYikgPSBuXGxuKGEpICsgblxsbihiKSArIFxsZWZ0WyAoYS0xKVxzdW0gXGxuKHhfaSkgXHJpZ2h0XSArIFxsZWZ0WyAoYi0xKVxzdW1cbG4oMS14X2leYSkgXHJpZ2h0XSQkCgokJFxMYXJnZSBcZWxsX2FeXHByaW1lKGEsYikgPSBcZnJhY3tufXthfSArIFxsZWZ0WyBcc3VtXGxuKHhfaSkgXHJpZ2h0XSAtIFxsZWZ0WyhiLTEpXHN1bVxmcmFje3hfaV5hIFx0aW1lcyBcbG4oeF9pKX17MSAtIHhfaV5hfSBccmlnaHRdJCQKCiQkXExhcmdlIFxlbGxfYl5ccHJpbWUoYSxiKSA9IFxmcmFje259e2J9ICsgXHN1bVxsbigxLXhfaV5hKSQkCgoKIyMgQTMuKSAKVGhlbiB0YWtpbmcgdGhlIGdyYWRpZW50IHZlY3RvciBjb21wb25lbnRzLCBJIHdhcyBhYmxlIHRvIGNhbGN1bGF0ZSB0aGUgRmlzaGVyIGluZm9ybWF0aW9uIG1hdHJpeCAoJEkkKSwgd2hpY2ggaXMgc2ltcGx5IHRoZSBuZWdhdGl2ZSBvZiB0aGUgSGVzc2lhbiBtYXRyaXggKGNvbXBvc2VkIG9mIGFsbCBzZWNvbmQtZGVyaXZhdGl2ZSBleHRlbnNpb25zIG9mIHRoYXQgZGlzdHJpYnV0aW9uJ3MgbG9nLWxpa2VsaWhvb2QpLiBUaGUgRmlzaGVyIEluZm9ybWF0aW9uIG1hdHJpeCBmb3IgdGhlIEt1bWFyYXN3YW15IGRpc3RyaWJ1dGlvbiBpcyBiZWxvdy4KCmBgYHtyLCBvdXQud2lkdGg9IjUwJSIsIG91dC5oZWlnaHQ9IjUwJSJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIvVXNlcnMvY2hyaXNiYWhtL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL1dlc3QgQ2hlc3Rlci9TcHJpbmcgMjAyNi9TVEEgNTA2IC0gR3JhZCBNYXRoIFN0YXQgMiAvU1RBIDUwNiBSIEZvbGRlci9GaW5hbC9BM18xLmpwZyIpCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTNfMi5qcGciKQoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi9Vc2Vycy9jaHJpc2JhaG0vTGlicmFyeS9Nb2JpbGUgRG9jdW1lbnRzL2NvbX5hcHBsZX5DbG91ZERvY3MvV2VzdCBDaGVzdGVyL1NwcmluZyAyMDI2L1NUQSA1MDYgLSBHcmFkIE1hdGggU3RhdCAyIC9TVEEgNTA2IFIgRm9sZGVyL0ZpbmFsL0EzXzMuanBnIikKYGBgCgojIyBBNC4pCldlIG5vdyBjb25zaWRlciB0aGUgKipwb3dlcioqIGRpc3RyaWJ1dGlvbiwgYSBzcGVjaWFsIGFuZCBtb3JlIHNpbXBsaXN0aWMgY2FzZSBvZiB0aGUgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uLCB3aGljaCBvY2N1cnMgd2hlbiB0aGUgcGFyYW1ldGVyICRiJCA9IDEuIEdpdmVuIHRoZSBLdW1hcmFzd2FteSBmb3JtdWxhLCBhIHZhbHVlIG9mICRiJCA9IDEgbWVhbnMgdGhhdCB0aGUgcmVsYXRpdmUgZGVuc2l0eSBmdW5jdGlvbiBvZiB0aGUgcG93ZXIgZGlzdHJpYnV0aW9uIGlzICRheF57YS0xfSQuIEtub3dpbmcgdGhpcywgYmVsb3cgYXJlIGZvcm11bGFzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGVzdGltYXRlIHRoZSBwYXJhbWV0ZXIgJGEkIHZpYSBtb21lbnQgb3IgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gKE1PTSBvciBNTEUpLgoKYGBge3IsIG91dC53aWR0aD0iNTAlIn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi9Vc2Vycy9jaHJpc2JhaG0vTGlicmFyeS9Nb2JpbGUgRG9jdW1lbnRzL2NvbX5hcHBsZX5DbG91ZERvY3MvV2VzdCBDaGVzdGVyL1NwcmluZyAyMDI2L1NUQSA1MDYgLSBHcmFkIE1hdGggU3RhdCAyIC9TVEEgNTA2IFIgRm9sZGVyL0ZpbmFsL0E0XzEuanBnIikKCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIvVXNlcnMvY2hyaXNiYWhtL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL1dlc3QgQ2hlc3Rlci9TcHJpbmcgMjAyNi9TVEEgNTA2IC0gR3JhZCBNYXRoIFN0YXQgMiAvU1RBIDUwNiBSIEZvbGRlci9GaW5hbC9BNF8yLmpwZyIpCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTRfMy5qcGciKQpgYGAKCgojIyBBNS4pCkdpdmVuIGFuIGVzdGltYXRlIG9mIG91ciBwYXJhbWV0ZXIgJGEkLCAoJFxoYXR7YX0kKSwgd2UgY2FuIHNldHVwIGEgZ2VuZXJhbCBjb25maWRlbmNlIGludGVydmFsIChDSSkgZm9ybXVsYSBmb3IgdGhlIHZhbHVlIG9mICRhJC4gQXNzdW1pbmcgOTUlIGNvbmZpZGVuY2UsIHRoZXJlZm9yZSBhIGNyaXRpY2FsIHZhbHVlIG9mIDEuOTYgcHJlZGljYXRlZCBvbiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlIG1ha2V1cCBvZiB0aGUgQ0kgd291bGQgbG9vayBsaWtlIHRoZSBmb2xsb3dpbmcuIAoKVGhlIHZhcmlhbmNlIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGludGVydmFsIHdlcmUgZm91bmQgZnJvbSB0aGUgcG93ZXIgZGlzdHJpYnV0aW9uJ3MgaW5mb3JtYXRpb24gbWF0cml4LiBUaGUgaW52ZXJzZSBvZiBzdWNoIG1hdHJpeCBzZXJ2ZXMgYXMgdGhlIHZhcmlhbmNlIHdoZW4gYXBwbGllZCBpbiBzaW5nbGUtcGFyYW1ldGVyIHNjZW5hcmlvcy4KCmBgYHtyLCBvdXQud2lkdGg9IjUwJSJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCIvVXNlcnMvY2hyaXNiYWhtL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL1dlc3QgQ2hlc3Rlci9TcHJpbmcgMjAyNi9TVEEgNTA2IC0gR3JhZCBNYXRoIFN0YXQgMiAvU1RBIDUwNiBSIEZvbGRlci9GaW5hbC9BNV8xLmpwZyIpCgprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTVfMi5qcGciKQpgYGAKCiMjIEE2LikKVGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBpbnZvbHZlcyB0aGUgc3VidHJhY3Rpb24gb2YgdGhlIGxvZyBsaWtlbGlob29kIGVzdGltYXRlIG9mIGEgc2ltcGxlciBtb2RlbCAodGhlIHVuaWZvcm0gZGlzdHJpYnV0aW9uIGluIHRoaXMgY2FzZSkgZnJvbSB0aGUgbG9nIGxpa2VsaWhvb2QgZXN0aW1hdGUgb2YgYSBtb3JlIGNvbXBsZXggYW5kIG1vcmUgcGFyYW1ldGVyaXplZCBtb2RlbCAodGhlIHBvd2VyIGRpc3RyaWJ1dGlvbiBpbiB0aGlzIHNjZW5hcmlvKS4gVGhpcyB0ZXN0IGlzIGlzIG1lYW50IHRvIG1lYXN1cmUgdGhlIGltcHJvdmVtZW50IGluIGZpdCB0aGF0IHRoZSBtb3JlIGNvbXBsZXggYW5kIHVucmVzdHJpY3RlZCBtb2RlbCBwcm92aWRlcy4gCgpCZWxvdyBzaG93cyB0aGUgZm9ybXVsYSBmb3Igd2hhdCBvdXIgdGVzdCBzdGF0aXN0aWMsICRcTGFtYmRhJCB3b3VsZCBlcXVhbCBpbiB0aGlzIGluc3RhbmNlLiBTaW5jZSAkXGVsbCgxKSA9IDAkLCBpdCBpcyByZWxhdGl2ZWx5IHN0cmFpZ2h0Zm9yd2FyZC4gV2hlbiBwZXJmb3JtaW5nIGEgbGlrZWxpaG9vZCByYXRpbyB0ZXN0LCB0aGUgZGlzdHJpYnV0aW9uIG9mICRcTGFtYmRhJCBmb2xsb3dzIGEgY2hpLXNxdWFyZWQgZGlzdHJpYnV0aW9uLiBBZ2FpbiBhc3N1bWluZyBhIDk1JSBjb25maWRlbmNlIGxldmVsLCB3ZSB3b3VsZCBjb25zaWRlciBhbnkgdmFsdWUgb2YgJFxMYW1iZGEkIGdyZWF0ZXIgdGhhbiBhYm91dCAzLjg0MSBzdWZmaWNpZW50IGV2aWRlbmNlIHRvIHN1Z2dlc3QgdGhlcmUgaXMgdmFsdWUgaW4gdXNpbmcgdGhlIG1vcmUgY29tcGxleCBwb3dlciBkaXN0cmlidXRpb24uCgpgYGB7ciwgb3V0LndpZHRoPSI1MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiL1VzZXJzL2NocmlzYmFobS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9XZXN0IENoZXN0ZXIvU3ByaW5nIDIwMjYvU1RBIDUwNiAtIEdyYWQgTWF0aCBTdGF0IDIgL1NUQSA1MDYgUiBGb2xkZXIvRmluYWwvQTZfMS5qcGciKQoKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi9Vc2Vycy9jaHJpc2JhaG0vTGlicmFyeS9Nb2JpbGUgRG9jdW1lbnRzL2NvbX5hcHBsZX5DbG91ZERvY3MvV2VzdCBDaGVzdGVyL1NwcmluZyAyMDI2L1NUQSA1MDYgLSBHcmFkIE1hdGggU3RhdCAyIC9TVEEgNTA2IFIgRm9sZGVyL0ZpbmFsL0E2XzIuanBnIikKYGBgCgo8YnI+CgojIFBhcnQgQjogTnVtZXJpY2FsIEFuYWx5c2lzCgpgYGB7cn0KIyByZWFkIGluIGRhdGEKZGF0YSA9IHJiaW5kLmRhdGEuZnJhbWUoMC4xMiwgMC4xNCwgMC4xNSwgMC4xNiwgMC4xNywgMC4xOCwgMC4xOSwgMC4yMCwgMC4yMSwgMC4yMiwKMC4yMywgMC4yNCwgMC4yNSwgMC4yNiwgMC4yNywgMC4yOCwgMC4yOSwgMC4zMCwgMC4zMSwgMC4zMiwKMC4zMywgMC4zNCwgMC4zNSwgMC4zNiwgMC4zNywgMC4zOCwgMC4zOSwgMC40MCwgMC40MSwgMC40MiwKMC40MywgMC40NCwgMC40NSwgMC40NiwgMC40NywgMC40OCwgMC40OSwgMC41MCwgMC41MSwgMC41MiwKMC41MywgMC41NCwgMC41NSwgMC41NiwgMC41NywgMC41OCwgMC41OSwgMC42MCwgMC42MSwgMC43OCkKY29sbmFtZXMoZGF0YSkgPSAic3RvcmFnZSIKYGBgClRoZSBkYXRhc2V0IHdlIHdpbGwgYW5hbHl6ZSBjb25zaXN0cyBvZiBgciBucm93KGRhdGEpYCByZWNvcmRlZCB1c2FibGUgc3RvcmFnZSBwcm9wb3J0aW9ucyBvZiBhIHJlc2Vydm9pciBpbiBhIHNtYWxsIHRvd24sIHdpdGggYSB2YWx1ZSBvZiAwIHJlcHJlc2VudGluZyBhIGJhc2ljYWxseSBlbXB0eSByZXNlcnZvaXIgYW5kIGEgdmFsdWUgb2YgMSByZXByZXNlbnRpbmcgYSBmdWxsIGJvZHkgb2Ygd2F0ZXIuIFN1bW1hcnkgc3RhdGlzdGljcyBhbmQgYSBoaXN0b2dyYW0gb2YgdGhlIGRhdGEgYXJlIGJlbG93LgoKYGBge3J9CnN1bV9zdGF0c190YWJsZSA9IGZ1bmN0aW9uKHZhcmlhYmxlKXsKICB0YWJsZSA9IGNiaW5kKAogICAgcm91bmQobWluKHZhcmlhYmxlKSwyKSwKICAgIHJvdW5kKHF1YW50aWxlKHZhcmlhYmxlLCAwLjI1KSwyKSwKICAgIHJvdW5kKG1lZGlhbih2YXJpYWJsZSksMiksCiAgICByb3VuZChtZWFuKHZhcmlhYmxlKSwyKSwKICAgIHJvdW5kKHF1YW50aWxlKHZhcmlhYmxlLCAwLjc1KSwyKSwKICAgIHJvdW5kKG1heCh2YXJpYWJsZSksMikKICApCiAgY29sbmFtZXModGFibGUpID0gYygiTWluIiwgIlExIiwgIk1lZCIsICJNZWFuIiwgIlEzIiwgIk1heCIpCiAgcm93bmFtZXModGFibGUpID0gTlVMTAogIHJldHVybih0YWJsZSkKfQoKU3VtbWFyeV9UYWJsZSA9IHN1bV9zdGF0c190YWJsZSh2YXJpYWJsZSA9IGRhdGEkc3RvcmFnZSkKa2FibGUoU3VtbWFyeV9UYWJsZSxhbGlnbiA9ICJjIiwKICAgICAgY2FwdGlvbiA9ICI8c3BhbiBzdHlsZT0nY29sb3I6IyMwMDAwMDA7Jz4KICAgICAgU3VtbWFyeSBTdGF0cyBvZiBTdG9yYWdlIFZvbHVtZXMgPC9zcGFuPiIpICU+JQogIGthYmxlX3N0eWxpbmcoCiAgICBib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiYm9yZGVyZWQiKSwKICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwKICAgIHBvc2l0aW9uID0gImNlbnRlciIpCgpnZ3Bsb3QoZGF0YSA9IGRhdGEpICsKICBnZW9tX2hpc3RvZ3JhbShtYXBwaW5nID0gYWVzKHggPSBzdG9yYWdlLCB5ID0gYWZ0ZXJfc3RhdChkZW5zaXR5KSksCiAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siLAogICAgICAgICAgICAgICAgICAjIGFyZ3VtZW50IGNvbG9yIGluIGdlb21faGlzdG9ncmFtIGlzIGZvciBjb2xvciBvZiBiaW4gbGluZXMKICAgICAgICAgICAgICAgICBmaWxsID0gImxpZ2h0Ymx1ZSIsCiAgICAgICAgICAgICAgICAgYmlucyA9IDEwLCkgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFN0b3JhZ2UgVm9sdW1lcyIsCiAgICAgICB4ID0gIlN0b3JhZ2UgVm9sdW1lIiwKICAgICAgIHkgPSAiUHJvYmFiaWl0eSBEZW5zaXR5IikgKyAKICB0aGVtZSgKICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbGluZXdpZHRoID0gMykKICApICMgdGhpcyBpcyB0aGUgZXF1aXZhbGVudCBvZiBib3gobHdkID0gMykgaW4gYmFzZSBSCmBgYAoKIyMgQjEuKQpOb3cgdXNpbmcgdGhlIGF2YWlsYWJsZSBzYW1wbGUgZGF0YSwgYW5kIGFzc3VtaW5nIGEgKipLdW1hcmFzd2FteSBkaXN0cmlidXRpb24qKiBpcyBhcHBsaWNhYmxlIGluIHRoaXMgY2FzZSwgSSB3aWxsIHBlcmZvcm0gTUxFIHRvIGVzdGltYXRlIHBhcmFtZXRlcnMgJGEkIGFuZCAkYiQuIEtleSBmb3JtdWxhcyBmb3Igc3VjaCBjYWxjdWxhdGlvbiBhcmUgdGhlIGxvZyBsaWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgc2VlbiBiZWxvdy4KCiQkXExhcmdlIFxlbGwoYSxiKSA9IG5cbG4oYSkgKyBuXGxuKGIpICsgXGxlZnRbIChhLTEpXHN1bSBcbG4oeF9pKSBccmlnaHRdICsgXGxlZnRbIChiLTEpXHN1bVxsbigxLXhfaV5hKSBccmlnaHRdJCQKCiQkXExhcmdlIFxlbGxfYV5ccHJpbWUoYSxiKSA9IFxmcmFje259e2F9ICsgXGxlZnRbIFxzdW1cbG4oeF9pKSBccmlnaHRdIC0gXGxlZnRbKGItMSlcc3VtXGZyYWN7eF9pXmEgXHRpbWVzIFxsbih4X2kpfXsxIC0geF9pXmF9IFxyaWdodF0kJAoKJCRcTGFyZ2UgXGVsbF9iXlxwcmltZShhLGIpID0gXGZyYWN7bn17Yn0gKyBcc3VtXGxuKDEteF9pXmEpJCQKCmBgYHtyfQojIyBmaXJzdCBkZWZpbmUgbG9nIGxpa2VsaWhvb2Qgb2YgS3VtYXJhc3dhbXkgZGlzdHJpYnV0aW9uCmxvZ19saWtlX2t1bSA9IGZ1bmN0aW9uKHBhcmFtZXRlcnMsIGRhdGEpewogICAgYSA9IHBhcmFtZXRlcnNbMV0KICAgIGIgPSBwYXJhbWV0ZXJzWzJdCiAgICBuID0gbGVuZ3RoKGRhdGEpCiAgICAKICAgIGxvZ19saWtlbGlob29kID0gbiAqIGxvZyhhKSArIAogICAgICBuICogbG9nKGIpICsgCiAgICAgIChhLTEpICogc3VtKGxvZyhkYXRhKSkgKyAKICAgICAgKGItMSkgKiBzdW0obG9nKDEtZGF0YV5hKSkKICAgIH0KCiMjIGdyYWRpZW50IGZ1bmN0aW9ucwpncmFkaWVudF9rdW0gPSBmdW5jdGlvbihwYXJhbWV0ZXJzLCBkYXRhKXsKICAgIGEgPSBwYXJhbWV0ZXJzWzFdCiAgICBiID0gcGFyYW1ldGVyc1syXQogICAgbiA9IGxlbmd0aChkYXRhKQogICAgCiAgICAjIyBwYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIGEKICAgIHBhcnRpYWxfYSA9IG4vYSArCiAgICAgIHN1bShsb2coZGF0YSkpIC0KICAgICAgKGItMSkqc3VtKChkYXRhXmEqbG9nKGRhdGEpKS8oMS1kYXRhXmEpKQogICAgCiAgICAjIyBwYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIGIgCiAgICBwYXJ0aWFsX2IgPSBuL2IgKyBzdW0obG9nKDEtZGF0YV5hKSkKICAgIAogICAgcmV0dXJuKGMocGFydGlhbF9hLAogICAgICAgICAgICAgcGFydGlhbF9iKSkKICAKICAgIH0KCiMjIG5vdyBnZXQgYW4gTUxFIGVzdGltYXRlCm1sZV9rdW0gPSBvcHRpbSgKICAgIHBhciA9IGMoYSA9IDEuNSwgYiA9IDUpLAogICAgICAjIHRyaWVkIE1BTlkgZGlmZmVyZW50IHN0YXJ0aW5nIGVzdGltYXRlcywgY29udGludWVkIHRvIGFkanVzdCBiYXNlZCBvbiBoaXN0b2dyYW0gdmlzdWFsIGJlbG93LgogICAgZm4gPSBsb2dfbGlrZV9rdW0sCiAgICBnciA9IGdyYWRpZW50X2t1bSwKICAgIGRhdGEgPSBkYXRhJHN0b3JhZ2UsCiAgICMgbWV0aG9kID0gIkwtQkZHUy1CIiwKICAgIGhlc3NpYW4gPSBUUlVFLAogICAgY29udHJvbCA9IGxpc3QodHJhY2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgIGZuc2NhbGUgPSAtMSwKICAgICAgICAgICAgICAgICAgIG1heGl0ID0gNTAwLAogICAgICAgICAgICAgICAgICAgYWJzdG9sID0gMWUtOCkKICAgICkKCm1sZV9rdW1fYV9lc3RpbWF0ZSA9IG1sZV9rdW0kcGFyWzFdICMgYQogICMjIGNvbnRyb2xzIGJlaGF2aW9yIG5lYXIgMAptbGVfa3VtX2JfZXN0aW1hdGUgPSBtbGVfa3VtJHBhclsyXSAjIGIKICAjIyBjb250cm9scyBiZWhhdmlvciBhcHByb2FjaGluZyAxIC8gdGhpbmsgcmlnaHQgdGFpbApgYGAKClVzaW5nIFIncyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPm9wdGltPC9zcGFuPiBmdW5jdGlvbiwgYW5kIHBlcmZvcm1pbmcgbnVtZXJvdXMgaXRlcmF0aW9ucyB3aXRoIGRpZmZlcmVudCBzdGFydGluZyBwYXJhbWV0ZXIgZXN0aW1hdGVzIG9mIGJvdGggJGEkIGFuZCAkYiQsIGEgcmVhc29uYWJsZSBlc3RpbWF0ZSBmb3IgdGhlIHR3byBzaGFwZSBwYXJhbWV0ZXJzIGFyZSBgciBtbGVfa3VtX2FfZXN0aW1hdGVgIGFuZCBgciBtbGVfa3VtX2JfZXN0aW1hdGVgIHJlc3BlY3RpdmVseS4gQmVsb3cgaXMgYSB2aXN1YWwgb2Ygb3VyIHNhbXBsZSBkYXRhIHdpdGggYSBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gY3VydmUgd2l0aCBzYWlkIHBhcmFtZXRlciB2YWx1ZXMgYWRkaXRpb25hbGx5IG92ZXJsYWlkLgoKYGBge3J9CmxpYnJhcnkoZXh0cmFEaXN0cikgIyBuZWVkZWQgdG8gcGxvdCBLdW1hcmFzd2FteSBkaXN0cmlidXRpb24gY3VydmUKCiMjIHZpc3VhbCBjb25maXJtYXRpb24KZ2dwbG90KGRhdGEgPSBkYXRhKSArCiAgZ2VvbV9oaXN0b2dyYW0obWFwcGluZyA9IGFlcyh4ID0gc3RvcmFnZSwgeSA9IGFmdGVyX3N0YXQoZGVuc2l0eSkpLAogICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgICBmaWxsID0gImxpZ2h0Ymx1ZSIsCiAgICAgICAgICAgICAgICAgYmlucyA9IDEwLCkgKwogICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRrdW1hciwgCiAgICAgICAgICAgICAgICBhcmdzID0gbGlzdChhID0gbWxlX2t1bV9hX2VzdGltYXRlLCBiID0gbWxlX2t1bV9iX2VzdGltYXRlKSwKICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSwKICAgICAgICAgICAgICAgIHhsaW0gPSByYW5nZSgwOjEpKSsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBTdG9yYWdlIFZvbHVtZXMiLAogICAgICAgeCA9ICJTdG9yYWdlIFZvbHVtZSIsCiAgICAgICB5ID0gIlByb2JhYmlpdHkgRGVuc2l0eSIpICsgCiAgdGhlbWUoCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDMpCiAgKSAKYGBgCgojIyBCMi4pIFBJQ0sgVVAgSEVSRQoKYGBge3J9CiMjIHNhbWUgcHJvY2VkdXJlIGFzIEIxLCBub3cgdXNlIHBvd2VyIGRpc3RyaWJ1dGlvbiBjaGFyYWN0ZXJpc3RpY3MKbG9nX2xpa2VfcG93ZXIgPSBmdW5jdGlvbihhLCBkYXRhKXsKICAgIG4gPSBsZW5ndGgoZGF0YSkKICAgIGxvZ19saWtlbGlob29kID0gbiAqIGxvZyhhKSArCiAgICAgIChhLTEpKnN1bShsb2coZGF0YSkpCiAgICB9CgpncmFkaWVudF9wb3dlciA9IGZ1bmN0aW9uKGEsIGRhdGEpewogICAgcGFydGlhbF9hID0gbi9hICsgc3VtKGxvZyhkYXRhKSkKICAgIHJldHVybihwYXJ0aWFsX2EpCiAgICB9CgoKCmBgYAoKIyMgQjMuKQoKYGBge3J9CgoKYGBgCgoKIyMgQjQuKQoKYGBge3J9CgoKYGBgCgo=