Midterm Exam Objectives

  • Understand the definition and relationship between PDFs and CDFs, including their non-parametric estimators: the empirical distribution function and kernel density estimation (KDE).

  • Estimate sampling distributions using simulation-based methods, specifically the bootstrap.

  • Derive point estimates of parameters using the method of moments and maximum likelihood estimation (MLE).

  • Describe the asymptotic (normal) and bootstrap sampling distributions of maximum likelihood estimators.

  • Apply all the above inferential procedures in a programming environment to perform numerical data analysis.


Policies of Using AI Tools

  • Policy on AI Tool Use: Students must adhere to the AI tool policy specified in the course syllabus. The direct copying of AI-generated content is strictly prohibited. All submitted work must reflect your own understanding; where external tools are consulted, content must be thoroughly rephrased and synthesized in your own words.

  • Code Inclusion Requirement: Any code included in your essay must be properly commented to explain the purpose and/or expected output of key code lines. Submitting AI-generated code without meaningful, student-added comments will not be accepted.


Policies of the Midterm Exam

  • This exam must be completed independently. Collaboration with others is not permitted.

  • You may consult class notes and online resources. However, please ensure that your use of AI tools complies with the AI policy established for this course.

  • All work must be submitted by the deadline. Submissions (including partial work) received after the deadline will not be accepted.


Submission Preparation

Since this exam involves derivations, you can use the following approaches to prepare your submission and save time:

  1. Handwrite the derivation on paper and take a photo. From there, you can either use AI tools to convert it into LaTeX code and paste it into RMarkdown, or insert the image directly into your RMarkdown document, following the example shown in class this week.

  2. Prepare the formulas using other non-programmatic editors and take a screenshot to embed the image in your RMarkdown document using knitr::include_graphics.

  3. Compile all handwritten derivations into a single file and submit it as an attachment.

Please follow the same submission procedure as used for the weekly assignments.


Exam Questions

Caution: Please follow the suggested expressions and guided steps to complete the exam. Other approaches, such as transformations that trivialize the problems, will not meet the exam objectives.

Log-normal Distribution

The log-normal distributions have been widely used in many different fields such as finance and economics, engineering and reliability, environmental science, medical and biology etc.

If \(X\) follows a lognormal distribution:

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

where \(\mu \in \mathbb{R}\) is the mean of \(\ln X\) and \(\sigma^2 > 0\) is the variance of \(\ln X\).

Caution: \(\mu\) and \(\sigma^2\) are not population mean and variance of the lognormal distribution!. Instead, we will use \(\mu_{LN}\) and \(\sigma_{LN}^2\) to denote the lognormal mean and variance respectively.

For an i.i.d. random sample \(x_1, x_2, \dots, x_n\):

\[\begin{align*} \ell(\mu, \sigma^2) &= \sum_{i=1}^n \ln f(x_i; \mu, \sigma^2) \\ &= -\frac{n}{2} \ln(2\pi) - \frac{n}{2} \ln \sigma^2 - \sum_{i=1}^n \ln x_i - \frac{1}{2\sigma^2} \sum_{i=1}^n (\ln x_i - \mu)^2 \end{align*}\]

The \(k\)-th moment of a lognormal distribution given by

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

Particularly, the mean of the above lognormal distribution, denoted by \(\mu_{LN}\), is given by

\[ \mu_{LN} = \mathbb{E}[X] = \exp\left( \mu + \frac{1}{2} \sigma^2 \right). \]

Once the parameters were estimated, say \((\overline{\mu}, \overline{\sigma^2})\), we can use the plug-in Principle to estimate the lognormal mean by

\[ \boxed{\overline{\mu_{LN}} = \exp\left( \overline{\mu} + \frac{1}{2} \overline{\sigma^2} \right).} \]

Working Dataset: A reservoir engineer at an oil exploration company has recently drilled 50 new wells in a shale formation. According to geological theory, the size of oil reserves in this type of formation is often modeled using a log-normal distribution. The engineer is responsible for estimating the typical reserve size and quantifying the uncertainty of these estimates for a presentation to senior management. The estimated ultimate recovery (EUR) for the 50 wells, measured in thousands of barrels (Mbbl), is as follows:

17.3, 24.8, 8.2, 31.5, 14.1, 42.7, 11.9, 55.3, 21.4, 9.7, 36.2, 18.6, 63.1, 13.2, 28.9, 
47.5, 19.8, 7.5, 33.4, 52.1, 16.0, 25.9, 38.7, 10.3, 44.2, 22.5, 58.6, 12.8, 30.3, 48.9, 
20.1, 35.4, 15.7, 60.2, 26.7, 41.3, 18.1, 53.8, 23.9, 46.2, 29.4, 37.6, 14.9, 50.5, 32.8, 
19.3, 56.7, 11.2, 39.5, 27.1

This assignment focuses on finding the asymptotic sampling distributions of the MLE \(\hat{\mu}\) and \(\hat{\sigma^2}\) corresponding to \(\mu\) and \(\sigma^2\) based on an environmental study data.


Question 1: Method of Moments Estimation (MME) of \(\mu\) and \(\sigma^2\)

Estimate the parameters \(\mu\) and \(\sigma^2\) (caution: not \(\sigma\)!) from the raw oil reserve data using the given \(k\)-th moment function. Organize your work into three parts:

  1. Derive the system of two equations for the method of moments estimators (MMEs) of \(\mu\) and \(\sigma^2\).

The \(k\)-th moment of lognormal random variable is given by \[ \boxed{ \mathbb{E}[X^k] = \exp\left( k\mu + \frac{1}{2} k^2 \sigma^2 \right). } \]

Since there are two unknown parameters, \(\mu\) and \(\sigma^2\), we use the first two moments.

Use the first moment to create the first equation

For \(k=1\), \[ \mathbb{E}[X] = \exp\left(\mu + \frac{\sigma^2}{2}\right) \]

Set the population moment equal to the first sample moment.

\[ \frac{1}{n}\sum_{i=1}^{n} X_i = \exp\left(\mu + \frac{\sigma^2}{2}\right) \]

Use the second moment to create the second equation

For \(k=2\), \[ \mathbb{E}[X^2] = \exp\left(2\mu + 2\sigma^2\right) \]

Set the population second moment equal to the second sample moment.

\[ \frac{1}{n}\sum_{i=1}^{n} X_i^2 = \exp\left(2\mu + 2\sigma^2\right) \]

These two equations form the method of moments system

\[ \frac{1}{n}\sum_{i=1}^{n} X_i = \exp\left(\mu + \frac{\sigma^2}{2}\right) \]

\[ \frac{1}{n}\sum_{i=1}^{n} X_i^2 = \exp\left(2\mu + 2\sigma^2\right) \]

  1. Derive the closed-form expressions for the MMEs of \(\mu\), \(\sigma^2\), and \(\mu_{LN}\), denoted by \(\widetilde{\mu}\), \(\widetilde{\sigma^2}\), and \(\widetilde{\mu_{LN}}\), respectively.

We now solve the system from part (a) to obtain closed-form MMEs.

Let

\[ m_1 = \frac{1}{n}\sum_{i=1}^{n}X_i \]

\[ m_2 = \frac{1}{n}\sum_{i=1}^{n}X_i^2 \]

These represent the first and second sample moments.

Take the natural log of both equations to remove the exponential terms.

\[ \ln(m_1) = \mu + \frac{\sigma^2}{2} \]

\[ \ln(m_2) = 2\mu + 2\sigma^2 \]

Multiply the first equation by 2.

\[ 2\ln(m_1) = 2\mu + \sigma^2 \]

Subtract the equations to isolate \(\sigma^2\).

\[ \widetilde{\sigma^2} = \ln(m_2) - 2\ln(m_1) \]

Substitute this result back into the first equation to solve for \(\mu\).

\[ \widetilde{\mu} = \ln(m_1) - \frac{1}{2}\widetilde{\sigma^2} \]

Using the plug-in principle, the estimator for the lognormal mean is

\[ \widetilde{\mu_{LN}} = \exp\left(\widetilde{\mu} + \frac{1}{2}\widetilde{\sigma^2}\right) \]

  1. Write an R function that outputs the MMEs \(\widetilde{\mu}\), \(\widetilde{\sigma^2}\), and \(\widetilde{\mu_{LN}}\) based on the given data set.
# Compute the first two sample moments
mme_lognormal <- function(x) {
  m1 <- mean(x)
  m2 <- mean(x^2)
  
  # Compute MME of sigma^2
  sigma2_tilde <- log(m2) - 2 * log(m1)
  
  # Compute MME of mu
  mu_tilde <- log(m1) - 0.5 * sigma2_tilde
  
  # Compute plug-in estimate of lognormal mean
  mu_LN_tilde <- exp(mu_tilde + 0.5 * sigma2_tilde)
  
  # Return all three estimates
  return(list(
    mu_tilde = mu_tilde,
    sigma2_tilde = sigma2_tilde,
    mu_LN_tilde = mu_LN_tilde
  ))
}

# Store the data
oil_data <- c(
  17.3, 24.8, 8.2, 31.5, 14.1, 42.7, 11.9, 55.3, 21.4, 9.7,
  36.2, 18.6, 63.1, 13.2, 28.9, 47.5, 19.8, 7.5, 33.4, 52.1,
  16.0, 25.9, 38.7, 10.3, 44.2, 22.5, 58.6, 12.8, 30.3, 48.9,
  20.1, 35.4, 15.7, 60.2, 26.7, 41.3, 18.1, 53.8, 23.9, 46.2,
  29.4, 37.6, 14.9, 50.5, 32.8, 19.3, 56.7, 11.2, 39.5, 27.1
)

# Compute the estimates
mme_lognormal(oil_data)
$mu_tilde
[1] 3.301269

$sigma2_tilde
[1] 0.2339652

$mu_LN_tilde
[1] 30.516


Question 2: Finding the MLE of \(\mu\) and \(\sigma^2\)

This question involves two parts:

(1). Derive the score functions (i.e., the gradient of the log-likelihood) for the parameters of the log-normal distribution, and set them to zero to obtain the system of score equations. Begin with the full log-likelihood and compute its partial derivatives with respect to \(\mu\) and \(\sigma^2\). [Hint: letting \(\beta = \sigma^2\) may simplify differentiation.]

Assume that \(\{x_1, x_2, \cdots, x_n \} \to \text{ LN }(\mu, \sigma^2)\) with density function given by

\[ \ell(\mu, \sigma^2) = -\frac{n}{2} \ln(2\pi) - n \ln \sigma - \sum_{i=1}^n \ln x_i - \frac{1}{2\sigma^2} \sum_{i=1}^n (\ln x_i - \mu)^2 \]

Let \(\beta = \sigma^2\)

\[ \ell(\mu,\beta) = -\frac{n}{2}\ln(2\pi) -\frac{n}{2}\ln\beta -\sum_{i=1}^n \ln x_i -\frac{1}{2\beta}\sum_{i=1}^n(\ln x_i-\mu)^2 \]

Score function for \(\mu\)

\[ \frac{\partial \ell}{\partial \mu} = -\frac{1}{2\beta} \frac{\partial}{\partial \mu} \left[ \sum_{i=1}^n(\ln x_i-\mu)^2 \right] \]

\[ = -\frac{1}{2\beta} \sum_{i=1}^n 2(\ln x_i-\mu)(-1) \]

\[ = \frac{1}{\beta}\sum_{i=1}^n(\ln x_i-\mu) \]

Set score equation equal to zero

\[ \frac{1}{\beta}\sum_{i=1}^n(\ln x_i-\mu)=0 \]

\[ \sum_{i=1}^n(\ln x_i-\mu)=0 \]

Score function for \(\beta\)

\[ \frac{\partial \ell}{\partial \beta} = -\frac{n}{2\beta} - \frac{\partial}{\partial \beta} \left[ \frac{1}{2\beta}\sum_{i=1}^n(\ln x_i-\mu)^2 \right] \]

\[ = -\frac{n}{2\beta} + \frac{1}{2\beta^2}\sum_{i=1}^n(\ln x_i-\mu)^2 \]

Set score equation equal to zero

\[ -\frac{n}{2\beta} + \frac{1}{2\beta^2}\sum_{i=1}^n(\ln x_i-\mu)^2 =0 \]

Score equations

\[ \sum_{i=1}^n \ln x_i - n\mu = 0 \]

\[ \sum_{i=1}^n(\ln x_i-\mu)^2 - n\sigma^2 = 0 \] (2). Perform some algebra to find the closed form of the MLE of \(\mu\) and \(\sigma^2\), denoted by \(\widehat{\mu}\) and \(\widehat{\sigma^2}\).

Solve the score equations

\[ \sum_{i=1}^{n} \ln x_i - n\mu = 0 \]

Solve for \(\mu\):

\[ \sum_{i=1}^{n} \ln x_i = n\mu \]

\[ \widehat{\mu} = \frac{1}{n}\sum_{i=1}^{n}\ln x_i \]

Now use the second score equation:

\[ \sum_{i=1}^{n}(\ln x_i-\mu)^2 - n\sigma^2 = 0 \]

Substitute \(\widehat{\mu}=\frac{1}{n}\sum_{i=1}^{n}\ln x_i\) into the equation:

\[ \sum_{i=1}^{n}(\ln x_i-\widehat{\mu})^2 - n\sigma^2 = 0 \]

Solve for \(\sigma^2\):

\[ \sum_{i=1}^{n}(\ln x_i-\widehat{\mu})^2 = n\sigma^2 \]

\[ \widehat{\sigma^2} = \frac{1}{n}\sum_{i=1}^{n}(\ln x_i-\widehat{\mu})^2 \]

(3). Recall that lognormal population mean (i.e., the first moment) is

\[ \mu_{LN} = \mathbb{E}[X] = \exp\left( \mu + \frac{1}{2} \sigma^2 \right). \]

Using the relationship between variance and the first and second moments, \(\text{Var}(X) = \mathbb{E}[X^2] - \left(\mathbb{E}[X]\right)^2\), we derive the population variance of the lognormal distribution, denoted as \(\sigma_{\text{LN}}^2\). This result will be used in applying the Central Limit Theorem in subsequent questions

Lognormal population mean

\[ \mu_{LN} = E[X] = \exp\left(\mu + \frac{1}{2}\sigma^2\right) \]

Second moment of a lognormal variable

\[ E[X^2] = \exp(2\mu + 2\sigma^2) \]

Use the variance identity

\[ \operatorname{Var}(X) = E[X^2] - (E[X])^2 \]

\[ \sigma_{LN}^2 = \exp(2\mu + 2\sigma^2) - \left[\exp\left(\mu + \frac{1}{2}\sigma^2\right)\right]^2 \]

Simplify the second term

\[ \left[\exp\left(\mu + \frac{1}{2}\sigma^2\right)\right]^2 = \exp(2\mu + \sigma^2) \]

Factor common term

\[ \sigma_{LN}^2 = \exp(2\mu + 2\sigma^2) - \exp(2\mu + \sigma^2) \]

\[ \sigma_{LN}^2 = \exp(2\mu + \sigma^2)\left(\exp(\sigma^2)-1\right) \]


Question 3: Sampling Distribution of Lognormal Sample Mean \(\widehat{\mu_{LN}}\)

We have derived two different estimators of lognormal population mean \(\mu_{LN}\). This Question focuses on the sampling distribution of lognormal sample sample means based on MLE. The following are detailed instructions.

(1). Write an R function to estimate the MLE of \(\mu\) and \(\sigma^2\), denoted by \(\widehat{\mu}\) and \(\widehat{\sigma^2}\) and return the MLE of \(\mu_{LN}\), denoted by \(\widehat{\mu_{LN}}\).

Compute MLEs from one sample

# Compute MLEs from one sample
mle_lognormal <- function(x) {

  log_x <- log(x)
  n <- length(x)

  # MLE of mu (derived in Question 2)
  mu_hat <- mean(log_x)

  # MLE of sigma^2 (derived in Question 2)
  sigma2_hat <- sum((log_x - mu_hat)^2) / n

  # Plug-in estimate of lognormal mean
  mu_LN_hat <- exp(mu_hat + 0.5 * sigma2_hat)

  return(list(
    mu_hat = mu_hat,
    sigma2_hat = sigma2_hat,
    mu_LN_hat = mu_LN_hat
  ))
}

Apply the function to the oil reserve data

mle_lognormal(oil_data)
$mu_hat
[1] 3.268536

$sigma2_hat
[1] 0.3271989

$mu_LN_hat
[1] 30.94264

(2). Take 1000 Bootstrap samples from the raw oil data set. For each bootstrap sample, call the above R function to find the bootstrap MLE of \(\mu_{LN}\), denoted by \(\widehat{\mu_{LN}^*}^{(1)}, \widehat{\mu_{LN}^*}^{(2)}, \cdots, \widehat{\mu_{LN}^*}^{(1000)}\).

# Number of bootstrap samples
B <- 1000

# Sample size
n <- length(oil_data)

# Store bootstrap MLEs of mu_LN
boot_mu_LN <- numeric(B)

for(i in 1:B) {

  # Draw bootstrap sample with replacement
  boot_sample <- sample(oil_data, size = n, replace = TRUE)

  # Compute MLEs from the bootstrap sample
  boot_fit <- mle_lognormal(boot_sample)

  # Store bootstrap MLE of mu_LN
  boot_mu_LN[i] <- boot_fit$mu_LN_hat
}

#Verify that 1000 bootstrap estimates were generated
length(boot_mu_LN)
[1] 1000

(3). Using kernel density estimation approach to estimate the bootstrap density curves based on the bootstrap MLEs: \(\widehat{\mu_{LN}^*}^{(1)}, \widehat{\mu_{LN}^*}^{(2)}, \cdots, \widehat{\mu_{LN}^*}^{(1000)}\).

Using the bootstrap estimates \(\widehat{\mu}_{LN}^{*(1)}, \widehat{\mu}_{LN}^{*(2)}, \ldots, \widehat{\mu}_{LN}^{*(1000)}\) obtained in part (2), we estimate the bootstrap sampling density using kernel density estimation.

# Estimate the bootstrap density using kernel density estimation
boot_density <- density(boot_mu_LN)

# Plot the bootstrap kernel density estimate
plot(boot_density,
     main = "Bootstrap Density of Lognormal Mean",
     xlab = expression(hat(mu[LN])),
     ylab = "Density",
     lwd = 2)

(4). In order to find the asymptotic sampling distribution using the central limit theorem (CLT). That is, when sample size is large,

By the central limit theorem, when the sample size is large,

\[ \bar{X} \approx N\left(\mu_{LN}, \frac{\sigma_{LN}^2}{n}\right). \]

From Question 2, the plug-in estimate of the lognormal mean is

\[ \widehat{\mu}_{LN} = \exp\left(\widehat{\mu} + \frac{1}{2}\widehat{\sigma}^2\right). \]

From the question page, the lognormal population variance is

\[ \sigma_{LN}^2 = \mathbb{E}[X^2] - (\mathbb{E}[X])^2. \]

Since

\[ \mathbb{E}[X] = \exp\left(\mu + \frac{1}{2}\sigma^2\right) \quad\text{and}\quad \mathbb{E}[X^2] = \exp(2\mu + 2\sigma^2), \]

the lognormal variance is

\[ \sigma_{LN}^2 = \exp(2\mu + 2\sigma^2) - \exp(2\mu + \sigma^2). \]

Applying the MLE plug-in principle,

\[ \widehat{\sigma}_{LN}^2 = \exp(2\widehat{\mu} + 2\widehat{\sigma}^2) - \exp(2\widehat{\mu} + \widehat{\sigma}^2). \]

The asymptotic sampling distribution is therefore estimated by

\[ \bar{X} \approx N\left(\widehat{\mu}_{LN}, \frac{\widehat{\sigma}_{LN}^2}{n}\right). \]

(5). Write a short summary to compare the two sampling distributions of the sample mean of the lognormal distribution.

The bootstrap sampling distribution of the lognormal sample mean was estimated using 1000 bootstrap MLEs of \(\mu_{LN}\). The resulting kernel density curve is centered near the estimated lognormal mean \(\widehat{\mu}_{LN} \approx 30.94\). The asymptotic sampling distribution obtained from the central limit theorem is a normal distribution with mean \(\widehat{\mu}_{LN}\) and variance \(\widehat{\sigma}_{LN}^2/n\). In the plot, the asymptotic normal density closely follows the bootstrap density in both location and spread. This indicates that the normal approximation provides a reasonable description of the sampling distribution of the lognormal sample mean for this sample size.

Question 4: Extra Bonus Credit

Derive the Hessian matrix by computing the second-order partial derivatives of the log-likelihood function (with respect to \(\mu\) and \(\sigma^2\)). Then, translate the derived Hessian into an R function that takes the MLEs of the parameters and the data as inputs and returns the Hessian matrix. Finally, compare your analytically derived Hessian with the numerical Hessian returned by optim().

(1) Analytical Hessian Matrix

The Hessian matrix is the matrix of second derivatives of the log-likelihood function.

\[ H(\mu,\sigma^2) = \begin{bmatrix} \frac{\partial^2 \ell}{\partial \mu^2} & \frac{\partial^2 \ell}{\partial \mu \partial \sigma^2} \\ \frac{\partial^2 \ell}{\partial \sigma^2 \partial \mu} & \frac{\partial^2 \ell}{\partial (\sigma^2)^2} \end{bmatrix} \]

From Question 2,

\[ \frac{\partial \ell}{\partial \mu} = \frac{1}{\sigma^2}\sum_{i=1}^{n}(\ln x_i-\mu) \]

Taking another derivative,

\[ \frac{\partial^2 \ell}{\partial \mu^2} = -\frac{n}{\sigma^2} \]

The mixed derivative is

\[ \frac{\partial^2 \ell}{\partial \mu \partial \sigma^2} = -\frac{1}{(\sigma^2)^2}\sum_{i=1}^{n}(\ln x_i-\mu) \]

From Question 2,

\[ \frac{\partial \ell}{\partial \sigma^2} = -\frac{n}{2\sigma^2} + \frac{1}{2(\sigma^2)^2} \sum_{i=1}^{n}(\ln x_i-\mu)^2 \]

Taking another derivative,

\[ \frac{\partial^2 \ell}{\partial (\sigma^2)^2} = \frac{n}{2(\sigma^2)^2} - \frac{1}{(\sigma^2)^3} \sum_{i=1}^{n}(\ln x_i-\mu)^2 \]

Therefore the Hessian matrix is

\[ H(\mu,\sigma^2) = \begin{bmatrix} -\frac{n}{\sigma^2} & -\frac{1}{(\sigma^2)^2}\sum_{i=1}^{n}(\ln x_i-\mu) \\ -\frac{1}{(\sigma^2)^2}\sum_{i=1}^{n}(\ln x_i-\mu) & \frac{n}{2(\sigma^2)^2} - \frac{1}{(\sigma^2)^3}\sum_{i=1}^{n}(\ln x_i-\mu)^2 \end{bmatrix} \]

(2) Analytical Hessian Matrix in R

# Analytical Hessian matrix based on formulas from part (1)
hessian_lognormal <- function(mu, sigma2, x){

  log_x <- log(x)
  n <- length(x)

  H11 <- -n / sigma2
  H12 <- -(1 / (sigma2^2)) * sum(log_x - mu)
  H21 <- H12
  H22 <- (n / (2 * sigma2^2)) - (1 / (sigma2^3)) * sum((log_x - mu)^2)

  matrix(c(H11, H12,
           H21, H22),
         nrow = 2,
         byrow = TRUE)
}

# Compute Hessian using the MLE estimates
mle_fit <- mle_lognormal(oil_data)

H_analytical <- hessian_lognormal(
  mle_fit$mu_hat,
  mle_fit$sigma2_hat,
  oil_data
)

H_analytical
              [,1]          [,2]
[1,] -1.528123e+02  1.037019e-13
[2,]  1.037019e-13 -2.335158e+02

(3) Numerical Hessian from optim()

# Negative log-likelihood function
neg_loglik <- function(par, x){

  mu <- par[1]
  sigma2 <- par[2]

  log_x <- log(x)
  n <- length(x)

  -( -n/2*log(2*pi)
     -n/2*log(sigma2)
     -sum(log_x)
     -(1/(2*sigma2))*sum((log_x - mu)^2) )
}

# Compute numerical Hessian
optim_fit <- optim(
  par = c(mle_fit$mu_hat, mle_fit$sigma2_hat),
  fn = neg_loglik,
  x = oil_data,
  hessian = TRUE
)

H_numerical <- optim_fit$hessian

H_numerical
         [,1]     [,2]
[1,] 152.8123   0.0000
[2,]   0.0000 233.5289

The analytical Hessian matrix and the numerical Hessian obtained from optim() have the same magnitudes but opposite signs because optim() computes the Hessian of the negative log-likelihood. This confirms that the analytical Hessian derivation is correct.-

LS0tCnRpdGxlOiAiU1RBIDUwNiAtIE1pZHRlcm0gRXhhbWluYXRpb24iCmF1dGhvcjogIktheWxhIER5ZXIiCmRhdGU6ICIgRHVlOiBTdW5kYXksIDAzLzA4LzIwMjYgYXQgMTE6NTkgUE0iCm91dHB1dDoKICBodG1sX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMKICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBmaWdfd2lkdGg6IDMKICAgIGZpZ19oZWlnaHQ6IDMKICB3b3JkX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KI1RPQzo6YmVmb3JlIHsKICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtc2l6ZTogMS4yZW07CiAgZGlzcGxheTogYmxvY2s7CiAgY29sb3I6IG5hdnk7CiAgbWFyZ2luLWJvdHRvbTogMTBweDsKfQoKCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47CiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7CiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOwogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOwp9CgpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLwogIGZvbnQtc2l6ZTogMjJweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOwp9CgpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMTVweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogc3lzdGVtLXVpOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIwcHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTRweDsKICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsKICBjb250ZW50OiAiLiI7Cgpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQoKLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0KCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9Cgp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCAKIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuCmlmICghcmVxdWlyZSgia25pdHIiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpCiAgIGxpYnJhcnkoa25pdHIpCn0KaWYgKCFyZXF1aXJlKCJwYW5kZXIiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQogICBsaWJyYXJ5KHBhbmRlcikKfQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgewogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQogIGxpYnJhcnkoZ2dwbG90MikKfQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfQoKaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgewogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpCiAgbGlicmFyeShwbG90bHkpCn0KIyMjIwprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiAKICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQogICAgICAgICAgICAgICAgICAgICAgKSAgCmBgYAogCiBcCiAKIyAqKk1pZHRlcm0gRXhhbSBPYmplY3RpdmVzKiogCgoqIFVuZGVyc3RhbmQgdGhlIGRlZmluaXRpb24gYW5kIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIFBERnMgYW5kIENERnMsIGluY2x1ZGluZyB0aGVpciBub24tcGFyYW1ldHJpYyBlc3RpbWF0b3JzOiB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiBhbmQga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbiAoS0RFKS4KCiogRXN0aW1hdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyB1c2luZyBzaW11bGF0aW9uLWJhc2VkIG1ldGhvZHMsIHNwZWNpZmljYWxseSB0aGUgYm9vdHN0cmFwLgoKKiBEZXJpdmUgcG9pbnQgZXN0aW1hdGVzIG9mIHBhcmFtZXRlcnMgdXNpbmcgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGFuZCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiAoTUxFKS4KCiogRGVzY3JpYmUgdGhlIGFzeW1wdG90aWMgKG5vcm1hbCkgYW5kIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0b3JzLgoKKiBBcHBseSBhbGwgdGhlIGFib3ZlIGluZmVyZW50aWFsIHByb2NlZHVyZXMgaW4gYSBwcm9ncmFtbWluZyBlbnZpcm9ubWVudCB0byBwZXJmb3JtIG51bWVyaWNhbCBkYXRhIGFuYWx5c2lzLgoKXAoKIyAqKlBvbGljaWVzIG9mIFVzaW5nIEFJIFRvb2xzKioKCiogKipQb2xpY3kgb24gQUkgVG9vbCBVc2UqKjogU3R1ZGVudHMgbXVzdCBhZGhlcmUgdG8gdGhlIEFJIHRvb2wgcG9saWN5IHNwZWNpZmllZCBpbiB0aGUgY291cnNlIHN5bGxhYnVzLiBUaGUgZGlyZWN0IGNvcHlpbmcgb2YgQUktZ2VuZXJhdGVkIGNvbnRlbnQgaXMgc3RyaWN0bHkgcHJvaGliaXRlZC4gQWxsIHN1Ym1pdHRlZCB3b3JrIG11c3QgcmVmbGVjdCB5b3VyIG93biB1bmRlcnN0YW5kaW5nOyB3aGVyZSBleHRlcm5hbCB0b29scyBhcmUgY29uc3VsdGVkLCBjb250ZW50IG11c3QgYmUgdGhvcm91Z2hseSByZXBocmFzZWQgYW5kIHN5bnRoZXNpemVkIGluIHlvdXIgb3duIHdvcmRzLgoKKiAqKkNvZGUgSW5jbHVzaW9uIFJlcXVpcmVtZW50Kio6IEFueSBjb2RlIGluY2x1ZGVkIGluIHlvdXIgZXNzYXkgbXVzdCBiZSBwcm9wZXJseSBjb21tZW50ZWQgdG8gZXhwbGFpbiB0aGUgcHVycG9zZSBhbmQvb3IgZXhwZWN0ZWQgb3V0cHV0IG9mIGtleSBjb2RlIGxpbmVzLiBTdWJtaXR0aW5nIEFJLWdlbmVyYXRlZCBjb2RlIHdpdGhvdXQgbWVhbmluZ2Z1bCwgc3R1ZGVudC1hZGRlZCBjb21tZW50cyB3aWxsIG5vdCBiZSBhY2NlcHRlZC4KClwKCiMgKipQb2xpY2llcyBvZiB0aGUgTWlkdGVybSBFeGFtKioKCiogVGhpcyBleGFtIG11c3QgYmUgY29tcGxldGVkIGluZGVwZW5kZW50bHkuIENvbGxhYm9yYXRpb24gd2l0aCBvdGhlcnMgaXMgbm90IHBlcm1pdHRlZC4KCiogWW91IG1heSBjb25zdWx0IGNsYXNzIG5vdGVzIGFuZCBvbmxpbmUgcmVzb3VyY2VzLiBIb3dldmVyLCBwbGVhc2UgZW5zdXJlIHRoYXQgeW91ciB1c2Ugb2YgQUkgdG9vbHMgY29tcGxpZXMgd2l0aCB0aGUgQUkgcG9saWN5IGVzdGFibGlzaGVkIGZvciB0aGlzIGNvdXJzZS4KCiogQWxsIHdvcmsgbXVzdCBiZSBzdWJtaXR0ZWQgYnkgdGhlIGRlYWRsaW5lLiBTdWJtaXNzaW9ucyAoaW5jbHVkaW5nIHBhcnRpYWwgd29yaykgcmVjZWl2ZWQgYWZ0ZXIgdGhlIGRlYWRsaW5lIHdpbGwgbm90IGJlIGFjY2VwdGVkLgoKXAoKIyAqKlN1Ym1pc3Npb24gUHJlcGFyYXRpb24qKgoKU2luY2UgdGhpcyBleGFtIGludm9sdmVzIGRlcml2YXRpb25zLCB5b3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIGFwcHJvYWNoZXMgdG8gcHJlcGFyZSB5b3VyIHN1Ym1pc3Npb24gYW5kIHNhdmUgdGltZToKCjEuIEhhbmR3cml0ZSB0aGUgZGVyaXZhdGlvbiBvbiBwYXBlciBhbmQgdGFrZSBhIHBob3RvLiBGcm9tIHRoZXJlLCB5b3UgY2FuIGVpdGhlciB1c2UgQUkgdG9vbHMgdG8gY29udmVydCBpdCBpbnRvIExhVGVYIGNvZGUgYW5kIHBhc3RlIGl0IGludG8gUk1hcmtkb3duLCBvciBpbnNlcnQgdGhlIGltYWdlIGRpcmVjdGx5IGludG8geW91ciBSTWFya2Rvd24gZG9jdW1lbnQsIGZvbGxvd2luZyB0aGUgZXhhbXBsZSBzaG93biBpbiBjbGFzcyB0aGlzIHdlZWsuCgoyLiBQcmVwYXJlIHRoZSBmb3JtdWxhcyB1c2luZyBvdGhlciBub24tcHJvZ3JhbW1hdGljIGVkaXRvcnMgYW5kIHRha2UgYSBzY3JlZW5zaG90IHRvIGVtYmVkIHRoZSBpbWFnZSBpbiB5b3VyIFJNYXJrZG93biBkb2N1bWVudCB1c2luZyBga25pdHI6OmluY2x1ZGVfZ3JhcGhpY3NgLgoKMy4gQ29tcGlsZSBhbGwgaGFuZHdyaXR0ZW4gZGVyaXZhdGlvbnMgaW50byBhIHNpbmdsZSBmaWxlIGFuZCBzdWJtaXQgaXQgYXMgYW4gYXR0YWNobWVudC4KClBsZWFzZSBmb2xsb3cgdGhlIHNhbWUgc3VibWlzc2lvbiBwcm9jZWR1cmUgYXMgdXNlZCBmb3IgdGhlIHdlZWtseSBhc3NpZ25tZW50cy4KClwKCiMgKipFeGFtIFF1ZXN0aW9ucyoqCgo8Zm9udCBjb2xvciA9ICJvcmFuZ2UiPioqXGNvbG9ye3JlZH1DYXV0aW9uKio6ICpcY29sb3J7cmVkfVBsZWFzZSBmb2xsb3cgdGhlIHN1Z2dlc3RlZCBleHByZXNzaW9ucyBhbmQgZ3VpZGVkIHN0ZXBzIHRvIGNvbXBsZXRlIHRoZSBleGFtLiBPdGhlciBhcHByb2FjaGVzLCBzdWNoIGFzIHRyYW5zZm9ybWF0aW9ucyB0aGF0IHRyaXZpYWxpemUgdGhlIHByb2JsZW1zLCB3aWxsIG5vdCBtZWV0IHRoZSBleGFtIG9iamVjdGl2ZXMuKjwvZm9udD4KCiMjICoqTG9nLW5vcm1hbCBEaXN0cmlidXRpb24qKgoKVGhlIGxvZy1ub3JtYWwgZGlzdHJpYnV0aW9ucyBoYXZlIGJlZW4gd2lkZWx5IHVzZWQgaW4gbWFueSBkaWZmZXJlbnQgZmllbGRzIHN1Y2ggYXMgZmluYW5jZSBhbmQgZWNvbm9taWNzLCBlbmdpbmVlcmluZyBhbmQgcmVsaWFiaWxpdHksIGVudmlyb25tZW50YWwgc2NpZW5jZSwgbWVkaWNhbCBhbmQgYmlvbG9neSBldGMuIAoKSWYgJFgkIGZvbGxvd3MgYSBsb2dub3JtYWwgZGlzdHJpYnV0aW9uOgoKJCQKZih4OyBcbXUsIFxzaWdtYV4yKSA9IFxmcmFjezF9e3hcc3FydHsyXHBpIFxzaWdtYV4yfX0gClxleHBcbGVmdFstXGZyYWN7KFxsbiB4IC0gXG11KV4yfXsyXHNpZ21hXjJ9XHJpZ2h0XSwgXHF1YWQgeCA+IDAKJCQKCndoZXJlICAkXG11IFxpbiBcbWF0aGJie1J9JCBpcyB0aGUgbWVhbiBvZiAkXGxuIFgkIGFuZCAkXHNpZ21hXjIgPiAwJCBpcyB0aGUgdmFyaWFuY2Ugb2YgJFxsbiBYJC4KCjxmb250IGNvbG9yID0icmVkIj4qKlxjb2xvcntyZWR9Q2F1dGlvbjoqKiAqXGNvbG9ye3JlZH0kXG11JCBhbmQgJFxzaWdtYV4yJCBhcmUgbm90IHBvcHVsYXRpb24gbWVhbiBhbmQgdmFyaWFuY2Ugb2YgdGhlIGxvZ25vcm1hbCBkaXN0cmlidXRpb24hKi4gKipcY29sb3J7Ymx1ZX0gSW5zdGVhZCwgd2Ugd2lsbCB1c2UgJFxtdV97TE59JCBhbmQgJFxzaWdtYV97TE59XjIkIHRvIGRlbm90ZSB0aGUgbG9nbm9ybWFsIG1lYW4gYW5kIHZhcmlhbmNlIHJlc3BlY3RpdmVseS4qKjwvZm9udD4KCgpGb3IgYW4gaS5pLmQuIHJhbmRvbSBzYW1wbGUgJHhfMSwgeF8yLCBcZG90cywgeF9uJDoKCgpcYmVnaW57YWxpZ24qfQpcZWxsKFxtdSwgXHNpZ21hXjIpICY9IFxzdW1fe2k9MX1ebiBcbG4gZih4X2k7IFxtdSwgXHNpZ21hXjIpIFxcCiY9IC1cZnJhY3tufXsyfSBcbG4oMlxwaSkgLSBcZnJhY3tufXsyfSBcbG4gXHNpZ21hXjIgLSBcc3VtX3tpPTF9Xm4gXGxuIHhfaSAKICAgLSBcZnJhY3sxfXsyXHNpZ21hXjJ9IFxzdW1fe2k9MX1ebiAoXGxuIHhfaSAtIFxtdSleMgpcZW5ke2FsaWduKn0KCgpUaGUgJGskLXRoIG1vbWVudCBvZiBhIGxvZ25vcm1hbCBkaXN0cmlidXRpb24gZ2l2ZW4gYnkKCiQkClxib3hlZHsgXG1hdGhiYntFfVtYXmtdID0gXGV4cFxsZWZ0KCBrXG11ICsgXGZyYWN7MX17Mn0ga14yIFxzaWdtYV4yIFxyaWdodCkuIH0KJCQKClBhcnRpY3VsYXJseSwgdGhlIG1lYW4gb2YgdGhlIGFib3ZlIGxvZ25vcm1hbCBkaXN0cmlidXRpb24sIGRlbm90ZWQgYnkgJFxtdV97TE59JCwgaXMgZ2l2ZW4gYnkKCiQkClxtdV97TE59ID0gXG1hdGhiYntFfVtYXSA9IFxleHBcbGVmdCggXG11ICsgXGZyYWN7MX17Mn0gIFxzaWdtYV4yIFxyaWdodCkuCiQkCgpPbmNlIHRoZSBwYXJhbWV0ZXJzIHdlcmUgZXN0aW1hdGVkLCBzYXkgJChcb3ZlcmxpbmV7XG11fSwgXG92ZXJsaW5le1xzaWdtYV4yfSkkLCB3ZSBjYW4gdXNlICoqdGhlIHBsdWctaW4gUHJpbmNpcGxlKiogdG8gZXN0aW1hdGUgdGhlIGxvZ25vcm1hbCBtZWFuIGJ5CgokJApcYm94ZWR7XG92ZXJsaW5le1xtdV97TE59fSA9ICBcZXhwXGxlZnQoIFxvdmVybGluZXtcbXV9ICsgXGZyYWN7MX17Mn0gIFxvdmVybGluZXtcc2lnbWFeMn0gXHJpZ2h0KS59CiQkCgoKCgoKKipXb3JraW5nIERhdGFzZXQqKjogQSByZXNlcnZvaXIgZW5naW5lZXIgYXQgYW4gb2lsIGV4cGxvcmF0aW9uIGNvbXBhbnkgaGFzIHJlY2VudGx5IGRyaWxsZWQgNTAgbmV3IHdlbGxzIGluIGEgc2hhbGUgZm9ybWF0aW9uLiBBY2NvcmRpbmcgdG8gZ2VvbG9naWNhbCB0aGVvcnksIHRoZSBzaXplIG9mIG9pbCByZXNlcnZlcyBpbiB0aGlzIHR5cGUgb2YgZm9ybWF0aW9uIGlzIG9mdGVuIG1vZGVsZWQgdXNpbmcgYSBsb2ctbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlIGVuZ2luZWVyIGlzIHJlc3BvbnNpYmxlIGZvciBlc3RpbWF0aW5nIHRoZSB0eXBpY2FsIHJlc2VydmUgc2l6ZSBhbmQgcXVhbnRpZnlpbmcgdGhlIHVuY2VydGFpbnR5IG9mIHRoZXNlIGVzdGltYXRlcyBmb3IgYSBwcmVzZW50YXRpb24gdG8gc2VuaW9yIG1hbmFnZW1lbnQuIFRoZSBlc3RpbWF0ZWQgdWx0aW1hdGUgcmVjb3ZlcnkgKEVVUikgZm9yIHRoZSA1MCB3ZWxscywgbWVhc3VyZWQgaW4gdGhvdXNhbmRzIG9mIGJhcnJlbHMgKE1iYmwpLCBpcyBhcyBmb2xsb3dzOgoKYGBgCjE3LjMsIDI0LjgsIDguMiwgMzEuNSwgMTQuMSwgNDIuNywgMTEuOSwgNTUuMywgMjEuNCwgOS43LCAzNi4yLCAxOC42LCA2My4xLCAxMy4yLCAyOC45LCAKNDcuNSwgMTkuOCwgNy41LCAzMy40LCA1Mi4xLCAxNi4wLCAyNS45LCAzOC43LCAxMC4zLCA0NC4yLCAyMi41LCA1OC42LCAxMi44LCAzMC4zLCA0OC45LCAKMjAuMSwgMzUuNCwgMTUuNywgNjAuMiwgMjYuNywgNDEuMywgMTguMSwgNTMuOCwgMjMuOSwgNDYuMiwgMjkuNCwgMzcuNiwgMTQuOSwgNTAuNSwgMzIuOCwgCjE5LjMsIDU2LjcsIDExLjIsIDM5LjUsIDI3LjEKYGBgCgo8Zm9udCBjb2xvciA9ICJibHVlIj5UaGlzIGFzc2lnbm1lbnQgZm9jdXNlcyBvbiBmaW5kaW5nIHRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIE1MRSAkXGhhdHtcbXV9JCBhbmQgJFxoYXR7XHNpZ21hXjJ9JCBjb3JyZXNwb25kaW5nIHRvICRcbXUkIGFuZCAkXHNpZ21hXjIkIGJhc2VkIG9uIGFuIGVudmlyb25tZW50YWwgc3R1ZHkgZGF0YS48L2ZvbnQ+CgoKXAoKCiMjICoqUXVlc3Rpb24gMSoqOiBNZXRob2Qgb2YgTW9tZW50cyBFc3RpbWF0aW9uIChNTUUpIG9mICRcbXUkIGFuZCAkXHNpZ21hXjIkCgpFc3RpbWF0ZSB0aGUgcGFyYW1ldGVycyAkXG11JCBhbmQgJFxzaWdtYV4yJCAoPGZvbnQgY29sb3I9InJlZCI+Klxjb2xvcntyZWR9Y2F1dGlvbjogbm90ICRcc2lnbWEkISo8L2ZvbnQ+KSBmcm9tIHRoZSByYXcgb2lsIHJlc2VydmUgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gJGskLXRoIG1vbWVudCBmdW5jdGlvbi4gT3JnYW5pemUgeW91ciB3b3JrIGludG8gdGhyZWUgcGFydHM6CgooYSkgRGVyaXZlIHRoZSBzeXN0ZW0gb2YgdHdvIGVxdWF0aW9ucyBmb3IgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGVzdGltYXRvcnMgKE1NRXMpIG9mICRcbXUkIGFuZCAkXHNpZ21hXjIkLgoKVGhlICRrJC10aCBtb21lbnQgb2YgbG9nbm9ybWFsIHJhbmRvbSB2YXJpYWJsZSBpcyBnaXZlbiBieQokJApcYm94ZWR7IFxtYXRoYmJ7RX1bWF5rXSA9IFxleHBcbGVmdCgga1xtdSArIFxmcmFjezF9ezJ9IGteMiBcc2lnbWFeMiBccmlnaHQpLiB9CiQkCgpTaW5jZSB0aGVyZSBhcmUgdHdvIHVua25vd24gcGFyYW1ldGVycywgJFxtdSQgYW5kICRcc2lnbWFeMiQsIHdlIHVzZSB0aGUgZmlyc3QgdHdvIG1vbWVudHMuCgojIFVzZSB0aGUgZmlyc3QgbW9tZW50IHRvIGNyZWF0ZSB0aGUgZmlyc3QgZXF1YXRpb24KCkZvciAkaz0xJCwKJCQKXG1hdGhiYntFfVtYXSA9IFxleHBcbGVmdChcbXUgKyBcZnJhY3tcc2lnbWFeMn17Mn1ccmlnaHQpCiQkCgpTZXQgdGhlIHBvcHVsYXRpb24gbW9tZW50IGVxdWFsIHRvIHRoZSBmaXJzdCBzYW1wbGUgbW9tZW50LgoKJCQKXGZyYWN7MX17bn1cc3VtX3tpPTF9XntufSBYX2kKPQpcZXhwXGxlZnQoXG11ICsgXGZyYWN7XHNpZ21hXjJ9ezJ9XHJpZ2h0KQokJAoKCiMgVXNlIHRoZSBzZWNvbmQgbW9tZW50IHRvIGNyZWF0ZSB0aGUgc2Vjb25kIGVxdWF0aW9uCgpGb3IgJGs9MiQsCiQkClxtYXRoYmJ7RX1bWF4yXQo9ClxleHBcbGVmdCgyXG11ICsgMlxzaWdtYV4yXHJpZ2h0KQokJAoKU2V0IHRoZSBwb3B1bGF0aW9uIHNlY29uZCBtb21lbnQgZXF1YWwgdG8gdGhlIHNlY29uZCBzYW1wbGUgbW9tZW50LgoKJCQKXGZyYWN7MX17bn1cc3VtX3tpPTF9XntufSBYX2leMgo9ClxleHBcbGVmdCgyXG11ICsgMlxzaWdtYV4yXHJpZ2h0KQokJAoKCiMgVGhlc2UgdHdvIGVxdWF0aW9ucyBmb3JtIHRoZSBtZXRob2Qgb2YgbW9tZW50cyBzeXN0ZW0KCiQkClxmcmFjezF9e259XHN1bV97aT0xfV57bn0gWF9pCj0KXGV4cFxsZWZ0KFxtdSArIFxmcmFje1xzaWdtYV4yfXsyfVxyaWdodCkKJCQKCiQkClxmcmFjezF9e259XHN1bV97aT0xfV57bn0gWF9pXjIKPQpcZXhwXGxlZnQoMlxtdSArIDJcc2lnbWFeMlxyaWdodCkKJCQKCihiKSBEZXJpdmUgdGhlIGNsb3NlZC1mb3JtIGV4cHJlc3Npb25zIGZvciB0aGUgTU1FcyBvZiAkXG11JCwgJFxzaWdtYV4yJCwgYW5kICRcbXVfe0xOfSQsIGRlbm90ZWQgYnkgJFx3aWRldGlsZGV7XG11fSQsICRcd2lkZXRpbGRle1xzaWdtYV4yfSQsIGFuZCAkXHdpZGV0aWxkZXtcbXVfe0xOfX0kLCByZXNwZWN0aXZlbHkuCgpXZSBub3cgc29sdmUgdGhlIHN5c3RlbSBmcm9tIHBhcnQgKGEpIHRvIG9idGFpbiBjbG9zZWQtZm9ybSBNTUVzLgoKTGV0CgokJAptXzEgPSBcZnJhY3sxfXtufVxzdW1fe2k9MX1ee259WF9pCiQkCgokJAptXzIgPSBcZnJhY3sxfXtufVxzdW1fe2k9MX1ee259WF9pXjIKJCQKClRoZXNlIHJlcHJlc2VudCB0aGUgZmlyc3QgYW5kIHNlY29uZCBzYW1wbGUgbW9tZW50cy4KClRha2UgdGhlIG5hdHVyYWwgbG9nIG9mIGJvdGggZXF1YXRpb25zIHRvIHJlbW92ZSB0aGUgZXhwb25lbnRpYWwgdGVybXMuCgokJApcbG4obV8xKSA9IFxtdSArIFxmcmFje1xzaWdtYV4yfXsyfQokJAoKJCQKXGxuKG1fMikgPSAyXG11ICsgMlxzaWdtYV4yCiQkCgpNdWx0aXBseSB0aGUgZmlyc3QgZXF1YXRpb24gYnkgMi4KCiQkCjJcbG4obV8xKSA9IDJcbXUgKyBcc2lnbWFeMgokJAoKU3VidHJhY3QgdGhlIGVxdWF0aW9ucyB0byBpc29sYXRlICRcc2lnbWFeMiQuCgokJApcd2lkZXRpbGRle1xzaWdtYV4yfSA9IFxsbihtXzIpIC0gMlxsbihtXzEpCiQkCgpTdWJzdGl0dXRlIHRoaXMgcmVzdWx0IGJhY2sgaW50byB0aGUgZmlyc3QgZXF1YXRpb24gdG8gc29sdmUgZm9yICRcbXUkLgoKJCQKXHdpZGV0aWxkZXtcbXV9Cj0KXGxuKG1fMSkgLSBcZnJhY3sxfXsyfVx3aWRldGlsZGV7XHNpZ21hXjJ9CiQkCgpVc2luZyB0aGUgcGx1Zy1pbiBwcmluY2lwbGUsIHRoZSBlc3RpbWF0b3IgZm9yIHRoZSBsb2dub3JtYWwgbWVhbiBpcwoKJCQKXHdpZGV0aWxkZXtcbXVfe0xOfX0KPQpcZXhwXGxlZnQoXHdpZGV0aWxkZXtcbXV9ICsgXGZyYWN7MX17Mn1cd2lkZXRpbGRle1xzaWdtYV4yfVxyaWdodCkKJCQKCihjKSBXcml0ZSBhbiBSIGZ1bmN0aW9uIHRoYXQgb3V0cHV0cyB0aGUgTU1FcyAkXHdpZGV0aWxkZXtcbXV9JCwgJFx3aWRldGlsZGV7XHNpZ21hXjJ9JCwgYW5kICRcd2lkZXRpbGRle1xtdV97TE59fSQgYmFzZWQgb24gdGhlIGdpdmVuIGRhdGEgc2V0LgoKYGBge3J9CiMgQ29tcHV0ZSB0aGUgZmlyc3QgdHdvIHNhbXBsZSBtb21lbnRzCm1tZV9sb2dub3JtYWwgPC0gZnVuY3Rpb24oeCkgewogIG0xIDwtIG1lYW4oeCkKICBtMiA8LSBtZWFuKHheMikKICAKICAjIENvbXB1dGUgTU1FIG9mIHNpZ21hXjIKICBzaWdtYTJfdGlsZGUgPC0gbG9nKG0yKSAtIDIgKiBsb2cobTEpCiAgCiAgIyBDb21wdXRlIE1NRSBvZiBtdQogIG11X3RpbGRlIDwtIGxvZyhtMSkgLSAwLjUgKiBzaWdtYTJfdGlsZGUKICAKICAjIENvbXB1dGUgcGx1Zy1pbiBlc3RpbWF0ZSBvZiBsb2dub3JtYWwgbWVhbgogIG11X0xOX3RpbGRlIDwtIGV4cChtdV90aWxkZSArIDAuNSAqIHNpZ21hMl90aWxkZSkKICAKICAjIFJldHVybiBhbGwgdGhyZWUgZXN0aW1hdGVzCiAgcmV0dXJuKGxpc3QoCiAgICBtdV90aWxkZSA9IG11X3RpbGRlLAogICAgc2lnbWEyX3RpbGRlID0gc2lnbWEyX3RpbGRlLAogICAgbXVfTE5fdGlsZGUgPSBtdV9MTl90aWxkZQogICkpCn0KCiMgU3RvcmUgdGhlIGRhdGEKb2lsX2RhdGEgPC0gYygKICAxNy4zLCAyNC44LCA4LjIsIDMxLjUsIDE0LjEsIDQyLjcsIDExLjksIDU1LjMsIDIxLjQsIDkuNywKICAzNi4yLCAxOC42LCA2My4xLCAxMy4yLCAyOC45LCA0Ny41LCAxOS44LCA3LjUsIDMzLjQsIDUyLjEsCiAgMTYuMCwgMjUuOSwgMzguNywgMTAuMywgNDQuMiwgMjIuNSwgNTguNiwgMTIuOCwgMzAuMywgNDguOSwKICAyMC4xLCAzNS40LCAxNS43LCA2MC4yLCAyNi43LCA0MS4zLCAxOC4xLCA1My44LCAyMy45LCA0Ni4yLAogIDI5LjQsIDM3LjYsIDE0LjksIDUwLjUsIDMyLjgsIDE5LjMsIDU2LjcsIDExLjIsIDM5LjUsIDI3LjEKKQoKIyBDb21wdXRlIHRoZSBlc3RpbWF0ZXMKbW1lX2xvZ25vcm1hbChvaWxfZGF0YSkKYGBgCgpcCgojIyAqKlF1ZXN0aW9uIDIqKjogRmluZGluZyB0aGUgTUxFIG9mICRcbXUkIGFuZCAkXHNpZ21hXjIkCgpUaGlzIHF1ZXN0aW9uIGludm9sdmVzIHR3byBwYXJ0czoKCigxKS4gRGVyaXZlIHRoZSBzY29yZSBmdW5jdGlvbnMgKGkuZS4sIHRoZSBncmFkaWVudCBvZiB0aGUgbG9nLWxpa2VsaWhvb2QpIGZvciB0aGUgcGFyYW1ldGVycyBvZiB0aGUgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24sIGFuZCBzZXQgdGhlbSB0byB6ZXJvIHRvIG9idGFpbiB0aGUgc3lzdGVtIG9mIHNjb3JlIGVxdWF0aW9ucy4gQmVnaW4gd2l0aCB0aGUgZnVsbCBsb2ctbGlrZWxpaG9vZCBhbmQgY29tcHV0ZSBpdHMgcGFydGlhbCBkZXJpdmF0aXZlcyB3aXRoIHJlc3BlY3QgdG8gJFxtdSQgYW5kICRcc2lnbWFeMiQuIFtIaW50OiBsZXR0aW5nICRcYmV0YSA9IFxzaWdtYV4yJCBtYXkgc2ltcGxpZnkgZGlmZmVyZW50aWF0aW9uLl0KCkFzc3VtZSB0aGF0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcdG8gXHRleHR7IExOIH0oXG11LCBcc2lnbWFeMikkIHdpdGggZGVuc2l0eSBmdW5jdGlvbiBnaXZlbiBieQoKJCQKXGVsbChcbXUsIFxzaWdtYV4yKSA9IC1cZnJhY3tufXsyfSBcbG4oMlxwaSkgLSBuIFxsbiBcc2lnbWEgLSBcc3VtX3tpPTF9Xm4gXGxuIHhfaSAKICAgLSBcZnJhY3sxfXsyXHNpZ21hXjJ9IFxzdW1fe2k9MX1ebiAoXGxuIHhfaSAtIFxtdSleMgokJAoKIyMjICBMZXQgJFxiZXRhID0gXHNpZ21hXjIkICAKCgokJApcZWxsKFxtdSxcYmV0YSkKPQotXGZyYWN7bn17Mn1cbG4oMlxwaSkKLVxmcmFje259ezJ9XGxuXGJldGEKLVxzdW1fe2k9MX1ebiBcbG4geF9pCi1cZnJhY3sxfXsyXGJldGF9XHN1bV97aT0xfV5uKFxsbiB4X2ktXG11KV4yCiQkCgojIyMgU2NvcmUgZnVuY3Rpb24gZm9yICRcbXUkCgokJApcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcbXV9Cj0KLVxmcmFjezF9ezJcYmV0YX0KXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxtdX0KXGxlZnRbClxzdW1fe2k9MX1ebihcbG4geF9pLVxtdSleMgpccmlnaHRdCiQkCgokJAo9Ci1cZnJhY3sxfXsyXGJldGF9ClxzdW1fe2k9MX1ebiAyKFxsbiB4X2ktXG11KSgtMSkKJCQKCiQkCj0KXGZyYWN7MX17XGJldGF9XHN1bV97aT0xfV5uKFxsbiB4X2ktXG11KQokJAoKIyMjIFNldCBzY29yZSBlcXVhdGlvbiBlcXVhbCB0byB6ZXJvCgokJApcZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9Xm4oXGxuIHhfaS1cbXUpPTAKJCQKCiQkClxzdW1fe2k9MX1ebihcbG4geF9pLVxtdSk9MAokJAoKIyMjIFNjb3JlIGZ1bmN0aW9uIGZvciAkXGJldGEkCgokJApcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcYmV0YX0KPQotXGZyYWN7bn17MlxiZXRhfQotClxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYmV0YX0KXGxlZnRbClxmcmFjezF9ezJcYmV0YX1cc3VtX3tpPTF9Xm4oXGxuIHhfaS1cbXUpXjIKXHJpZ2h0XQokJAoKJCQKPQotXGZyYWN7bn17MlxiZXRhfQorClxmcmFjezF9ezJcYmV0YV4yfVxzdW1fe2k9MX1ebihcbG4geF9pLVxtdSleMgokJAoKIyMjIFNldCBzY29yZSBlcXVhdGlvbiBlcXVhbCB0byB6ZXJvCgokJAotXGZyYWN7bn17MlxiZXRhfQorClxmcmFjezF9ezJcYmV0YV4yfVxzdW1fe2k9MX1ebihcbG4geF9pLVxtdSleMgo9MAokJAoKIyMjIFNjb3JlIGVxdWF0aW9ucwoKJCQKXHN1bV97aT0xfV5uIFxsbiB4X2kgLSBuXG11ID0gMAokJAoKJCQKXHN1bV97aT0xfV5uKFxsbiB4X2ktXG11KV4yIC0gblxzaWdtYV4yID0gMAokJAooMikuIFBlcmZvcm0gc29tZSBhbGdlYnJhIHRvIGZpbmQgdGhlIGNsb3NlZCBmb3JtIG9mIHRoZSBNTEUgb2YgJFxtdSQgYW5kICRcc2lnbWFeMiQsIGRlbm90ZWQgYnkgJFx3aWRlaGF0e1xtdX0kIGFuZCAkXHdpZGVoYXR7XHNpZ21hXjJ9JC4KCiMjIyBTb2x2ZSB0aGUgc2NvcmUgZXF1YXRpb25zCgokJApcc3VtX3tpPTF9XntufSBcbG4geF9pIC0gblxtdSA9IDAKJCQKClNvbHZlIGZvciAkXG11JDoKCiQkClxzdW1fe2k9MX1ee259IFxsbiB4X2kgPSBuXG11CiQkCgokJApcd2lkZWhhdHtcbXV9ID0gXGZyYWN7MX17bn1cc3VtX3tpPTF9XntufVxsbiB4X2kKJCQKCk5vdyB1c2UgdGhlIHNlY29uZCBzY29yZSBlcXVhdGlvbjoKCiQkClxzdW1fe2k9MX1ee259KFxsbiB4X2ktXG11KV4yIC0gblxzaWdtYV4yID0gMAokJAoKU3Vic3RpdHV0ZSAkXHdpZGVoYXR7XG11fT1cZnJhY3sxfXtufVxzdW1fe2k9MX1ee259XGxuIHhfaSQgaW50byB0aGUgZXF1YXRpb246CgokJApcc3VtX3tpPTF9XntufShcbG4geF9pLVx3aWRlaGF0e1xtdX0pXjIgLSBuXHNpZ21hXjIgPSAwCiQkCgpTb2x2ZSBmb3IgJFxzaWdtYV4yJDoKCiQkClxzdW1fe2k9MX1ee259KFxsbiB4X2ktXHdpZGVoYXR7XG11fSleMiA9IG5cc2lnbWFeMgokJAoKJCQKXHdpZGVoYXR7XHNpZ21hXjJ9ID0KXGZyYWN7MX17bn1cc3VtX3tpPTF9XntufShcbG4geF9pLVx3aWRlaGF0e1xtdX0pXjIKJCQKCigzKS4gUmVjYWxsIHRoYXQgbG9nbm9ybWFsIHBvcHVsYXRpb24gbWVhbiAoaS5lLiwgdGhlIGZpcnN0IG1vbWVudCkgaXMgCgokJApcbXVfe0xOfSA9IFxtYXRoYmJ7RX1bWF0gPSBcZXhwXGxlZnQoIFxtdSArIFxmcmFjezF9ezJ9ICBcc2lnbWFeMiBccmlnaHQpLgokJAoKVXNpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHZhcmlhbmNlIGFuZCB0aGUgZmlyc3QgYW5kIHNlY29uZCBtb21lbnRzLCAkXHRleHR7VmFyfShYKSA9IFxtYXRoYmJ7RX1bWF4yXSAtIFxsZWZ0KFxtYXRoYmJ7RX1bWF1ccmlnaHQpXjIkLCB3ZSBkZXJpdmUgdGhlIHBvcHVsYXRpb24gdmFyaWFuY2Ugb2YgdGhlIGxvZ25vcm1hbCBkaXN0cmlidXRpb24sIGRlbm90ZWQgYXMgJFxzaWdtYV97XHRleHR7TE59fV4yJC4gVGhpcyByZXN1bHQgd2lsbCBiZSB1c2VkIGluIGFwcGx5aW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gaW4gc3Vic2VxdWVudCBxdWVzdGlvbnMKCiMjIyBMb2dub3JtYWwgcG9wdWxhdGlvbiBtZWFuCgokJApcbXVfe0xOfSA9IEVbWF0gPSBcZXhwXGxlZnQoXG11ICsgXGZyYWN7MX17Mn1cc2lnbWFeMlxyaWdodCkKJCQKCiMjIyBTZWNvbmQgbW9tZW50IG9mIGEgbG9nbm9ybWFsIHZhcmlhYmxlCgokJApFW1heMl0gPSBcZXhwKDJcbXUgKyAyXHNpZ21hXjIpCiQkCgojIyMgVXNlIHRoZSB2YXJpYW5jZSBpZGVudGl0eQoKJCQKXG9wZXJhdG9ybmFtZXtWYXJ9KFgpID0gRVtYXjJdIC0gKEVbWF0pXjIKJCQKCiQkClxzaWdtYV97TE59XjIKPQpcZXhwKDJcbXUgKyAyXHNpZ21hXjIpCi0KXGxlZnRbXGV4cFxsZWZ0KFxtdSArIFxmcmFjezF9ezJ9XHNpZ21hXjJccmlnaHQpXHJpZ2h0XV4yCiQkCgojIyMgU2ltcGxpZnkgdGhlIHNlY29uZCB0ZXJtCgokJApcbGVmdFtcZXhwXGxlZnQoXG11ICsgXGZyYWN7MX17Mn1cc2lnbWFeMlxyaWdodClccmlnaHRdXjIKPQpcZXhwKDJcbXUgKyBcc2lnbWFeMikKJCQKCiMjIyBGYWN0b3IgY29tbW9uIHRlcm0KCiQkClxzaWdtYV97TE59XjIKPQpcZXhwKDJcbXUgKyAyXHNpZ21hXjIpCi0KXGV4cCgyXG11ICsgXHNpZ21hXjIpCiQkCgokJApcc2lnbWFfe0xOfV4yCj0KXGV4cCgyXG11ICsgXHNpZ21hXjIpXGxlZnQoXGV4cChcc2lnbWFeMiktMVxyaWdodCkKJCQKClwKCiMjICoqUXVlc3Rpb24gMyoqOiBTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgTG9nbm9ybWFsICoqU2FtcGxlIE1lYW4qKiAkXHdpZGVoYXR7XG11X3tMTn19JAoKV2UgaGF2ZSBkZXJpdmVkIHR3byBkaWZmZXJlbnQgZXN0aW1hdG9ycyBvZiBsb2dub3JtYWwgcG9wdWxhdGlvbiBtZWFuICRcbXVfe0xOfSQuIFRoaXMgUXVlc3Rpb24gZm9jdXNlcyBvbiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGxvZ25vcm1hbCBzYW1wbGUgc2FtcGxlIG1lYW5zIGJhc2VkIG9uIE1MRS4gVGhlIGZvbGxvd2luZyBhcmUgZGV0YWlsZWQgaW5zdHJ1Y3Rpb25zLgoKKDEpLiBXcml0ZSBhbiBSIGZ1bmN0aW9uIHRvIGVzdGltYXRlIHRoZSBNTEUgb2YgJFxtdSQgYW5kICRcc2lnbWFeMiQsIGRlbm90ZWQgYnkgJFx3aWRlaGF0e1xtdX0kIGFuZCAkXHdpZGVoYXR7XHNpZ21hXjJ9JCBhbmQgcmV0dXJuIHRoZSBNTEUgb2YgJFxtdV97TE59JCwgZGVub3RlZCBieSAkXHdpZGVoYXR7XG11X3tMTn19JC4KCkNvbXB1dGUgTUxFcyBmcm9tIG9uZSBzYW1wbGUKYGBge3J9CiMgQ29tcHV0ZSBNTEVzIGZyb20gb25lIHNhbXBsZQptbGVfbG9nbm9ybWFsIDwtIGZ1bmN0aW9uKHgpIHsKCiAgbG9nX3ggPC0gbG9nKHgpCiAgbiA8LSBsZW5ndGgoeCkKCiAgIyBNTEUgb2YgbXUgKGRlcml2ZWQgaW4gUXVlc3Rpb24gMikKICBtdV9oYXQgPC0gbWVhbihsb2dfeCkKCiAgIyBNTEUgb2Ygc2lnbWFeMiAoZGVyaXZlZCBpbiBRdWVzdGlvbiAyKQogIHNpZ21hMl9oYXQgPC0gc3VtKChsb2dfeCAtIG11X2hhdCleMikgLyBuCgogICMgUGx1Zy1pbiBlc3RpbWF0ZSBvZiBsb2dub3JtYWwgbWVhbgogIG11X0xOX2hhdCA8LSBleHAobXVfaGF0ICsgMC41ICogc2lnbWEyX2hhdCkKCiAgcmV0dXJuKGxpc3QoCiAgICBtdV9oYXQgPSBtdV9oYXQsCiAgICBzaWdtYTJfaGF0ID0gc2lnbWEyX2hhdCwKICAgIG11X0xOX2hhdCA9IG11X0xOX2hhdAogICkpCn0KYGBgCgojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byB0aGUgb2lsIHJlc2VydmUgZGF0YQoKYGBge3J9Cm1sZV9sb2dub3JtYWwob2lsX2RhdGEpCmBgYAoKKDIpLiBUYWtlIDEwMDAgQm9vdHN0cmFwIHNhbXBsZXMgZnJvbSB0aGUgcmF3IG9pbCBkYXRhIHNldC4gRm9yIGVhY2ggYm9vdHN0cmFwIHNhbXBsZSwgY2FsbCB0aGUgYWJvdmUgUiBmdW5jdGlvbiB0byBmaW5kIHRoZSAqKmJvb3RzdHJhcCBNTEUqKiBvZiAkXG11X3tMTn0kLCBkZW5vdGVkIGJ5ICRcd2lkZWhhdHtcbXVfe0xOfV4qfV57KDEpfSwgXHdpZGVoYXR7XG11X3tMTn1eKn1eeygyKX0sIFxjZG90cywgXHdpZGVoYXR7XG11X3tMTn1eKn1eeygxMDAwKX0kLgoKYGBge3J9CiMgTnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzCkIgPC0gMTAwMAoKIyBTYW1wbGUgc2l6ZQpuIDwtIGxlbmd0aChvaWxfZGF0YSkKCiMgU3RvcmUgYm9vdHN0cmFwIE1MRXMgb2YgbXVfTE4KYm9vdF9tdV9MTiA8LSBudW1lcmljKEIpCgpmb3IoaSBpbiAxOkIpIHsKCiAgIyBEcmF3IGJvb3RzdHJhcCBzYW1wbGUgd2l0aCByZXBsYWNlbWVudAogIGJvb3Rfc2FtcGxlIDwtIHNhbXBsZShvaWxfZGF0YSwgc2l6ZSA9IG4sIHJlcGxhY2UgPSBUUlVFKQoKICAjIENvbXB1dGUgTUxFcyBmcm9tIHRoZSBib290c3RyYXAgc2FtcGxlCiAgYm9vdF9maXQgPC0gbWxlX2xvZ25vcm1hbChib290X3NhbXBsZSkKCiAgIyBTdG9yZSBib290c3RyYXAgTUxFIG9mIG11X0xOCiAgYm9vdF9tdV9MTltpXSA8LSBib290X2ZpdCRtdV9MTl9oYXQKfQoKI1ZlcmlmeSB0aGF0IDEwMDAgYm9vdHN0cmFwIGVzdGltYXRlcyB3ZXJlIGdlbmVyYXRlZApsZW5ndGgoYm9vdF9tdV9MTikKYGBgCgooMykuIFVzaW5nIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRpb24gYXBwcm9hY2ggdG8gZXN0aW1hdGUgdGhlIGJvb3RzdHJhcCBkZW5zaXR5IGN1cnZlcyBiYXNlZCBvbiB0aGUgYm9vdHN0cmFwIE1MRXM6ICRcd2lkZWhhdHtcbXVfe0xOfV4qfV57KDEpfSwgXHdpZGVoYXR7XG11X3tMTn1eKn1eeygyKX0sIFxjZG90cywgXHdpZGVoYXR7XG11X3tMTn1eKn1eeygxMDAwKX0kLgoKVXNpbmcgdGhlIGJvb3RzdHJhcCBlc3RpbWF0ZXMgCiRcd2lkZWhhdHtcbXV9X3tMTn1eeyooMSl9LCBcd2lkZWhhdHtcbXV9X3tMTn1eeyooMil9LCBcbGRvdHMsIFx3aWRlaGF0e1xtdX1fe0xOfV57KigxMDAwKX0kIApvYnRhaW5lZCBpbiBwYXJ0ICgyKSwgd2UgZXN0aW1hdGUgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkZW5zaXR5IHVzaW5nIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRpb24uCgpgYGB7cn0KIyBFc3RpbWF0ZSB0aGUgYm9vdHN0cmFwIGRlbnNpdHkgdXNpbmcga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbgpib290X2RlbnNpdHkgPC0gZGVuc2l0eShib290X211X0xOKQoKIyBQbG90IHRoZSBib290c3RyYXAga2VybmVsIGRlbnNpdHkgZXN0aW1hdGUKcGxvdChib290X2RlbnNpdHksCiAgICAgbWFpbiA9ICJCb290c3RyYXAgRGVuc2l0eSBvZiBMb2dub3JtYWwgTWVhbiIsCiAgICAgeGxhYiA9IGV4cHJlc3Npb24oaGF0KG11W0xOXSkpLAogICAgIHlsYWIgPSAiRGVuc2l0eSIsCiAgICAgbHdkID0gMikKYGBgCgooNCkuIEluIG9yZGVyIHRvIGZpbmQgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVzaW5nIHRoZSAqKmNlbnRyYWwgbGltaXQgdGhlb3JlbSAoQ0xUKSoqLiBUaGF0IGlzLCB3aGVuIHNhbXBsZSBzaXplIGlzIGxhcmdlLCAKCkJ5IHRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0sIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlLAoKJCQKXGJhcntYfSBcYXBwcm94IE5cbGVmdChcbXVfe0xOfSwgXGZyYWN7XHNpZ21hX3tMTn1eMn17bn1ccmlnaHQpLgokJAoKRnJvbSBRdWVzdGlvbiAyLCB0aGUgcGx1Zy1pbiBlc3RpbWF0ZSBvZiB0aGUgbG9nbm9ybWFsIG1lYW4gaXMKCiQkClx3aWRlaGF0e1xtdX1fe0xOfSA9IFxleHBcbGVmdChcd2lkZWhhdHtcbXV9ICsgXGZyYWN7MX17Mn1cd2lkZWhhdHtcc2lnbWF9XjJccmlnaHQpLgokJAoKRnJvbSB0aGUgcXVlc3Rpb24gcGFnZSwgdGhlIGxvZ25vcm1hbCBwb3B1bGF0aW9uIHZhcmlhbmNlIGlzCgokJApcc2lnbWFfe0xOfV4yID0gXG1hdGhiYntFfVtYXjJdIC0gKFxtYXRoYmJ7RX1bWF0pXjIuCiQkCgpTaW5jZQoKJCQKXG1hdGhiYntFfVtYXSA9IFxleHBcbGVmdChcbXUgKyBcZnJhY3sxfXsyfVxzaWdtYV4yXHJpZ2h0KQpccXVhZFx0ZXh0e2FuZH1ccXVhZApcbWF0aGJie0V9W1heMl0gPSBcZXhwKDJcbXUgKyAyXHNpZ21hXjIpLAokJAoKdGhlIGxvZ25vcm1hbCB2YXJpYW5jZSBpcwoKJCQKXHNpZ21hX3tMTn1eMiA9IFxleHAoMlxtdSArIDJcc2lnbWFeMikgLSBcZXhwKDJcbXUgKyBcc2lnbWFeMikuCiQkCgpBcHBseWluZyB0aGUgTUxFIHBsdWctaW4gcHJpbmNpcGxlLAoKJCQKXHdpZGVoYXR7XHNpZ21hfV97TE59XjIgPQpcZXhwKDJcd2lkZWhhdHtcbXV9ICsgMlx3aWRlaGF0e1xzaWdtYX1eMikKLQpcZXhwKDJcd2lkZWhhdHtcbXV9ICsgXHdpZGVoYXR7XHNpZ21hfV4yKS4KJCQKClRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBpcyB0aGVyZWZvcmUgZXN0aW1hdGVkIGJ5CgokJApcYmFye1h9IFxhcHByb3ggTlxsZWZ0KFx3aWRlaGF0e1xtdX1fe0xOfSwgXGZyYWN7XHdpZGVoYXR7XHNpZ21hfV97TE59XjJ9e259XHJpZ2h0KS4KJCQKCig1KS4gV3JpdGUgYSBzaG9ydCBzdW1tYXJ5IHRvIGNvbXBhcmUgdGhlIHR3byBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIHRoZSBzYW1wbGUgbWVhbiBvZiB0aGUgbG9nbm9ybWFsIGRpc3RyaWJ1dGlvbi4KClRoZSBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBsb2dub3JtYWwgc2FtcGxlIG1lYW4gd2FzIGVzdGltYXRlZCB1c2luZyAxMDAwIGJvb3RzdHJhcCBNTEVzIG9mICRcbXVfe0xOfSQuIFRoZSByZXN1bHRpbmcga2VybmVsIGRlbnNpdHkgY3VydmUgaXMgY2VudGVyZWQgbmVhciB0aGUgZXN0aW1hdGVkIGxvZ25vcm1hbCBtZWFuICRcd2lkZWhhdHtcbXV9X3tMTn0gXGFwcHJveCAzMC45NCQuIFRoZSBhc3ltcHRvdGljIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvYnRhaW5lZCBmcm9tIHRoZSBjZW50cmFsIGxpbWl0IHRoZW9yZW0gaXMgYSBub3JtYWwgZGlzdHJpYnV0aW9uIHdpdGggbWVhbiAkXHdpZGVoYXR7XG11fV97TE59JCBhbmQgdmFyaWFuY2UgJFx3aWRlaGF0e1xzaWdtYX1fe0xOfV4yL24kLiBJbiB0aGUgcGxvdCwgdGhlIGFzeW1wdG90aWMgbm9ybWFsIGRlbnNpdHkgY2xvc2VseSBmb2xsb3dzIHRoZSBib290c3RyYXAgZGVuc2l0eSBpbiBib3RoIGxvY2F0aW9uIGFuZCBzcHJlYWQuIFRoaXMgaW5kaWNhdGVzIHRoYXQgdGhlIG5vcm1hbCBhcHByb3hpbWF0aW9uIHByb3ZpZGVzIGEgcmVhc29uYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBsb2dub3JtYWwgc2FtcGxlIG1lYW4gZm9yIHRoaXMgc2FtcGxlIHNpemUuCgojIyAqKlF1ZXN0aW9uIDQqKjogRXh0cmEgQm9udXMgQ3JlZGl0CgpEZXJpdmUgdGhlIEhlc3NpYW4gbWF0cml4IGJ5IGNvbXB1dGluZyB0aGUgc2Vjb25kLW9yZGVyIHBhcnRpYWwgZGVyaXZhdGl2ZXMgb2YgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uICh3aXRoIHJlc3BlY3QgdG8gJFxtdSQgYW5kICRcc2lnbWFeMiQpLiBUaGVuLCB0cmFuc2xhdGUgdGhlIGRlcml2ZWQgSGVzc2lhbiBpbnRvIGFuIFIgZnVuY3Rpb24gdGhhdCB0YWtlcyB0aGUgTUxFcyBvZiB0aGUgcGFyYW1ldGVycyBhbmQgdGhlIGRhdGEgYXMgaW5wdXRzIGFuZCByZXR1cm5zIHRoZSBIZXNzaWFuIG1hdHJpeC4gRmluYWxseSwgY29tcGFyZSB5b3VyIGFuYWx5dGljYWxseSBkZXJpdmVkIEhlc3NpYW4gd2l0aCB0aGUgbnVtZXJpY2FsIEhlc3NpYW4gcmV0dXJuZWQgYnkgYG9wdGltKClgLgoKIyMjICgxKSBBbmFseXRpY2FsIEhlc3NpYW4gTWF0cml4CgpUaGUgSGVzc2lhbiBtYXRyaXggaXMgdGhlIG1hdHJpeCBvZiBzZWNvbmQgZGVyaXZhdGl2ZXMgb2YgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uLgoKJCQKSChcbXUsXHNpZ21hXjIpCj0KXGJlZ2lue2JtYXRyaXh9ClxmcmFje1xwYXJ0aWFsXjIgXGVsbH17XHBhcnRpYWwgXG11XjJ9ICYKXGZyYWN7XHBhcnRpYWxeMiBcZWxsfXtccGFydGlhbCBcbXUgXHBhcnRpYWwgXHNpZ21hXjJ9ClxcClxmcmFje1xwYXJ0aWFsXjIgXGVsbH17XHBhcnRpYWwgXHNpZ21hXjIgXHBhcnRpYWwgXG11fSAmClxmcmFje1xwYXJ0aWFsXjIgXGVsbH17XHBhcnRpYWwgKFxzaWdtYV4yKV4yfQpcZW5ke2JtYXRyaXh9CiQkCgpGcm9tIFF1ZXN0aW9uIDIsCgokJApcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcbXV9Cj0KXGZyYWN7MX17XHNpZ21hXjJ9XHN1bV97aT0xfV57bn0oXGxuIHhfaS1cbXUpCiQkCgpUYWtpbmcgYW5vdGhlciBkZXJpdmF0aXZlLAoKJCQKXGZyYWN7XHBhcnRpYWxeMiBcZWxsfXtccGFydGlhbCBcbXVeMn0KPQotXGZyYWN7bn17XHNpZ21hXjJ9CiQkCgpUaGUgbWl4ZWQgZGVyaXZhdGl2ZSBpcwoKJCQKXGZyYWN7XHBhcnRpYWxeMiBcZWxsfXtccGFydGlhbCBcbXUgXHBhcnRpYWwgXHNpZ21hXjJ9Cj0KLVxmcmFjezF9eyhcc2lnbWFeMileMn1cc3VtX3tpPTF9XntufShcbG4geF9pLVxtdSkKJCQKCkZyb20gUXVlc3Rpb24gMiwKCiQkClxmcmFje1xwYXJ0aWFsIFxlbGx9e1xwYXJ0aWFsIFxzaWdtYV4yfQo9Ci1cZnJhY3tufXsyXHNpZ21hXjJ9CisKXGZyYWN7MX17Mihcc2lnbWFeMileMn0KXHN1bV97aT0xfV57bn0oXGxuIHhfaS1cbXUpXjIKJCQKClRha2luZyBhbm90aGVyIGRlcml2YXRpdmUsCgokJApcZnJhY3tccGFydGlhbF4yIFxlbGx9e1xwYXJ0aWFsIChcc2lnbWFeMileMn0KPQpcZnJhY3tufXsyKFxzaWdtYV4yKV4yfQotClxmcmFjezF9eyhcc2lnbWFeMileM30KXHN1bV97aT0xfV57bn0oXGxuIHhfaS1cbXUpXjIKJCQKClRoZXJlZm9yZSB0aGUgSGVzc2lhbiBtYXRyaXggaXMKCiQkCkgoXG11LFxzaWdtYV4yKQo9ClxiZWdpbntibWF0cml4fQotXGZyYWN7bn17XHNpZ21hXjJ9CiYKLVxmcmFjezF9eyhcc2lnbWFeMileMn1cc3VtX3tpPTF9XntufShcbG4geF9pLVxtdSkKXFwKLVxmcmFjezF9eyhcc2lnbWFeMileMn1cc3VtX3tpPTF9XntufShcbG4geF9pLVxtdSkKJgpcZnJhY3tufXsyKFxzaWdtYV4yKV4yfQotClxmcmFjezF9eyhcc2lnbWFeMileM31cc3VtX3tpPTF9XntufShcbG4geF9pLVxtdSleMgpcZW5ke2JtYXRyaXh9CiQkCgojIyMgKDIpIEFuYWx5dGljYWwgSGVzc2lhbiBNYXRyaXggaW4gUgoKYGBge3J9CiMgQW5hbHl0aWNhbCBIZXNzaWFuIG1hdHJpeCBiYXNlZCBvbiBmb3JtdWxhcyBmcm9tIHBhcnQgKDEpCmhlc3NpYW5fbG9nbm9ybWFsIDwtIGZ1bmN0aW9uKG11LCBzaWdtYTIsIHgpewoKICBsb2dfeCA8LSBsb2coeCkKICBuIDwtIGxlbmd0aCh4KQoKICBIMTEgPC0gLW4gLyBzaWdtYTIKICBIMTIgPC0gLSgxIC8gKHNpZ21hMl4yKSkgKiBzdW0obG9nX3ggLSBtdSkKICBIMjEgPC0gSDEyCiAgSDIyIDwtIChuIC8gKDIgKiBzaWdtYTJeMikpIC0gKDEgLyAoc2lnbWEyXjMpKSAqIHN1bSgobG9nX3ggLSBtdSleMikKCiAgbWF0cml4KGMoSDExLCBIMTIsCiAgICAgICAgICAgSDIxLCBIMjIpLAogICAgICAgICBucm93ID0gMiwKICAgICAgICAgYnlyb3cgPSBUUlVFKQp9CgojIENvbXB1dGUgSGVzc2lhbiB1c2luZyB0aGUgTUxFIGVzdGltYXRlcwptbGVfZml0IDwtIG1sZV9sb2dub3JtYWwob2lsX2RhdGEpCgpIX2FuYWx5dGljYWwgPC0gaGVzc2lhbl9sb2dub3JtYWwoCiAgbWxlX2ZpdCRtdV9oYXQsCiAgbWxlX2ZpdCRzaWdtYTJfaGF0LAogIG9pbF9kYXRhCikKCkhfYW5hbHl0aWNhbApgYGAKCiMjIyAoMykgTnVtZXJpY2FsIEhlc3NpYW4gZnJvbSBvcHRpbSgpCgpgYGB7cn0KIyBOZWdhdGl2ZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbgpuZWdfbG9nbGlrIDwtIGZ1bmN0aW9uKHBhciwgeCl7CgogIG11IDwtIHBhclsxXQogIHNpZ21hMiA8LSBwYXJbMl0KCiAgbG9nX3ggPC0gbG9nKHgpCiAgbiA8LSBsZW5ndGgoeCkKCiAgLSggLW4vMipsb2coMipwaSkKICAgICAtbi8yKmxvZyhzaWdtYTIpCiAgICAgLXN1bShsb2dfeCkKICAgICAtKDEvKDIqc2lnbWEyKSkqc3VtKChsb2dfeCAtIG11KV4yKSApCn0KCiMgQ29tcHV0ZSBudW1lcmljYWwgSGVzc2lhbgpvcHRpbV9maXQgPC0gb3B0aW0oCiAgcGFyID0gYyhtbGVfZml0JG11X2hhdCwgbWxlX2ZpdCRzaWdtYTJfaGF0KSwKICBmbiA9IG5lZ19sb2dsaWssCiAgeCA9IG9pbF9kYXRhLAogIGhlc3NpYW4gPSBUUlVFCikKCkhfbnVtZXJpY2FsIDwtIG9wdGltX2ZpdCRoZXNzaWFuCgpIX251bWVyaWNhbApgYGAKClRoZSBhbmFseXRpY2FsIEhlc3NpYW4gbWF0cml4IGFuZCB0aGUgbnVtZXJpY2FsIEhlc3NpYW4gb2J0YWluZWQgZnJvbSBgb3B0aW0oKWAgaGF2ZSB0aGUgc2FtZSBtYWduaXR1ZGVzIGJ1dCBvcHBvc2l0ZSBzaWducyBiZWNhdXNlIGBvcHRpbSgpYCBjb21wdXRlcyB0aGUgSGVzc2lhbiBvZiB0aGUgbmVnYXRpdmUgbG9nLWxpa2VsaWhvb2QuIFRoaXMgY29uZmlybXMgdGhhdCB0aGUgYW5hbHl0aWNhbCBIZXNzaWFuIGRlcml2YXRpb24gaXMgY29ycmVjdC4t