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 (such as Python) to perform numerical data analysis.

Lognormal Distrubution

5.1 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;µ,σ2) = √ 1 x 2πσ2 exp −(lnx−µ)2 2σ2 where µ ∈ R is the mean of lnX and σ2 > 0 is the variance of lnX.

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 ˆµ and ˆ to µ and σ2 based on an environmental study data.

Question 1: Method of Moments Estimation (MME) of µ and σ2

Estimate the parameters µ and σ2 (caution: not σ!) 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 µ and σ2.
#1a. Deriving the system of two equations for the methods of moment estimators (MME) of mu and sigma_sq

wellsize= sort(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 ))


#m moments for parameters
m1 = mean(wellsize) #xbar
m2= mean(wellsize^2) #x squared bar
#algebric application for closed form population parameters sigma^2 and mu

mom_sigma_sq = log(m2) - 2*log(m1)
mom_mu = log(m1) -0.5 * mom_sigma_sq

cat("MME for mu:", mom_mu, "\nMME for sigma_sq:", mom_sigma_sq)
MME for mu: 3.301269 
MME for sigma_sq: 0.2339652
cat("Sample mean:", m1, "sample standard deviation:", m2)
Sample mean: 30.516 sample standard deviation: 1176.698
  1. Derive the closed-form expressions for the MMEs of µ, σ2, and µLN, denoted by µ~, σ2~, and µLN~, respectively.

System of equations: \[ \ln(\bar{x}) = \mu + \frac{1}{2}\sigma^2 \ln(\bar{x^2}) = 2\mu + 2\sigma^2 \]

Solve Equation 1 for \(\mu\) in terms of \(\sigma^2\): \[ [ mu = \ln(\bar{x}) - \frac{1}{2}\sigma^2 ] \]

Substitute this expression for \(\mu\):

\[ [ln({x^2}) = 2[ \ln(\bar{x}) - \frac{1}{2}\sigma^2] + 2\sigma^2] \]

Distribute and simplify to find \(\tilde{\sigma}^2\):}

\[ [ln({x^2}) = 2ln(\bar{x}) - \sigma^2 + 2\sigma^2] \] \[ [ln({x^2}) = 2ln(\bar{x}) + \sigma^2] \]

\[ [ \tilde{\sigma}^2 = ln({x^2}) - 2ln(\bar{x})] \]

Substitute \(\tilde{\sigma}^2\) back into the expression for \(\mu\):

\[ [\tilde{\mu} = ln(\bar{x}) - \frac{1}{2} [ln({x^2}) - 2ln(\bar{x})]] \] \[ [\tilde{\mu} = ln(\bar{x}) - \frac{1}{2} ln({x^2}) + ln(\bar{x})] \] \[ [\tilde{\mu} = 2ln(\bar{x}) - \frac{1}{2}ln({x^2})] \]

Observing both equations

\[ [\tilde{\mu} = 2ln(\bar{x}) - \frac{1}{2}\ln(x^2)] \]

\[ [\tilde{\sigma}^2 = ln({x^2}) - 2ln(\bar{x})] \]

  1. Write an R function that outputs the MMEs µ, σ2, and µLN based on the given data set.
sigma_squ_tilda = log(m2)-2* log(m1)
mu_tilda = 2*log(m1) - ((1/2)*log(m2))


cat("Mu tilda:", mu_tilda, "Population standard deviation:", sigma_squ_tilda)
Mu tilda: 3.301269 Population standard deviation: 0.2339652
#Writing a function for Methods of Moment Estimation

MMElognorm= function(wellsize)
{
  
#m moments for parameters
m1 = mean(wellsize) #xbar
m2= mean(wellsize^2) #x squared bar
#algebric application for closed form population parameters sigma^2 and mu

#mom_sigma_sq = log(m2) - 2*log(m1)  #remove its the same below
#mom_mu = log(m1) -0.5 * mom_sigma_sq
  
sigma_squ_tilda = log(m2)-2* log(m1) #calculate the MOM for standard deivation
mu_tilda = 2*log(m1) - ((1/2)*log(m2)) # calculate the MOM for mean

return(c(mu_tilda, sigma_squ_tilda, m1) )

}
results = MMElognorm(wellsize)

cat("Mu tilda:", mu_tilda, "Population standard deviation:", sigma_squ_tilda, "mu_LN", m1)
Mu tilda: 3.301269 Population standard deviation: 0.2339652 mu_LN 30.516

The outputs for the method of moment estimators are \(\tilde\mu\) = 3.3012685, \(\tilde\sigma^2\) = 0.2339652, and \(\tilde\mu_{LN}\) = 30.516.

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

Question 2.1

(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 µ and σ2. [Hint: letting β = σ2 may simplify differentiation.]

The log-likelihood for the log-normal distribution is given by:

\[ \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 \] Partial derivative with respect to \(\mu\):

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

Reach the score function of the equations Partial derivative with respect to \(\beta\), we treat \(\beta\) in substitution of \(\sigma^2\) for simplicity: \[ \frac{\partial \ell}{\partial \beta} = \frac{\partial}{\partial \beta} \left[ -\frac{n}{2} \ln \beta \right] - \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} \sum_{i=1}^n (\ln x_i - \mu)^2 \cdot \frac{d}{d\beta}(\beta^{-1}) \\ = -\frac{n}{2\beta} - \frac{1}{2} \sum_{i=1}^n (\ln x_i - \mu)^2 \cdot (-\beta^{-2}) \\ U(\beta) = -\frac{n}{2\beta} + \frac{1}{2\beta^2} \sum_{i=1}^n (\ln x_i - \mu)^2 \]

Replacing \(\beta\) with \(\sigma^2\)

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

Question 2.2

(2). Perform some algebra to find the closed form of the MLE of µ and σ2, denoted by µ and σ2

Solving for \(\hat\mu\)

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

Solving for \(\hat\sigma^2\)

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

Question 2.3

(3). Recall that lognormal population mean (i.e., the first moment) is μLN = E[X] = exp(μ + 1/2σ2). Using the relationship between variance and the first and second moments,

Var(X) = E[X2] − (E[X])2,

we derive the population variance of the lognormal distribution, denoted as σ2 LN. This result will be used in applying the Central Limit Theorem in subsequent questions

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

\[ \sigma^2_{LN} = E[X^2] - (E[X])^2 \]

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

E[X^k] = exp(k+ k22), \

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

$$

\[ \sigma^2_{LN} = E[X^2] - (E[X])^2 \]

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

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

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

Question 3.1

(1). Write an R function to estimate the MLE of μ and σ2, denoted by bμ and cσ2 and return the MLE of μLN, denoted by \(\hat\mu_{LN}\).

The log-likelihood for the log-normal distribution is given by:

\[ \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 \]

#Write the R function that estimations the MLE of the mu and sigma^2 denoted by mu_hat and sigma square hat to then return
#The Maximum Limitation Estimator of the mu_LN, denoted mu_LN_hat


data = wellsize #inserting the data of interest to be wellsize



normlog_mle= function(data)
  {
    #LOG LIKLEIHOOD--> its a normallog so fine
    log_data = log(data)
    #Find the length of the data for gradient equations
    
    n = length(data)
    
    #closed form for mu_hat and sigma_sq_hat
    mu_hat = mean(log_data)
    sigma_sq_hat = mean((log_data-mu_hat)^2) 
    
    #Calculating the population paraters for MLE: mu_ln_hat
    
    mu_ln_hat = exp(mu_hat + (0.5* sigma_sq_hat))
    
cat("Mu hat:", mu_hat, "Sigma Squared hat - Predicted standard deviation:", sigma_sq_hat, "MLE mu_ln", mu_ln_hat)   


return(c(mu_hat = mu_hat, sigma_sq_hat = sigma_sq_hat, mu_ln_hat = mu_ln_hat))
}


mle_results = normlog_mle(wellsize)
Mu hat: 3.268536 Sigma Squared hat - Predicted standard deviation: 0.3271989 MLE mu_ln 30.94264
#no gradient function (closed form no optim) --> partial differentiation and set to 0




# Solve system for MLE (mu_LN_hat)

Question 3.2

(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 μLN, denoted by dμ∗ LN (1) , dμ∗ LN (2) , · · · , dμ∗ LN (1000).

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

set.seed(143)

length(wellsize) #n =50
[1] 50
boot_mu_ln_mle = NULL
log_well= wellsize


for (i in 1:1000)
{

#bootstrap sample
# make sure sample is in its log form
  
 # take raw not log of mean #log(wellsize) --> log the bootstrapped sample
  
bootstrap_well= sample(x=log_well, 50, replace= TRUE) #bootstrapping from the well sample

log_boot_well=log(bootstrap_well) #take the log of the bootstrapped sample to run the log likelihood


#take the mean of the log likelihood bootstrap to input in MLE mu equation
mu_hat = mean(log_boot_well)  #MLE estimator for mu
sigma_sq_hat = mean((log_boot_well-mu_hat)^2) #MLE estimator for simga^2


#Now calculate the mu ln

boot_mu_ln_mle[i] = exp(mu_hat +(0.5* sigma_sq_hat)) #gives distrubution of the bootstrap for the mu ln mle

final_mu_ln_MLE = mean(boot_mu_ln_mle) #gives single value for bootstrapped mle mu ln

#return(c(final_mu_ln_MLE)) #only keeping last thing ran --> VERRY VERYY BAD FOR bootstrapping --> not keeping the distribution for the model
}

cat("Bootstrap MLE of μLN:", final_mu_ln_MLE)
Bootstrap MLE of μLN: 30.93064

The bootstrap MLE of \(\mu_{ln}\) is 30.9306417.

Question 3.3

(3). Using kernel density estimation approach to estimate the bootstrap density curves based on the bootstrap MLEs: dμ∗ LN (1) , dμ∗ LN (2) , · · · , dμ∗ LN (1000).

#sd_ml_MLE=sd(boot_mu_ln_mle) #you would need to calculate standard error of the distribution to make a bandwidth for the kernel 

kde = density(boot_mu_ln_mle, kernel = "gaussian")  #density(boot_mu_ln_mle, bw = sd_ml_MLE)

hist(boot_mu_ln_mle,                     # data used for histogram
     breaks = 14,                            # specify number of vertical bars
     probability = TRUE,
       xlab = "Bootstrap sample means",      # change the label of x-axis
      # add a title to the histogram
        main="Bootstrap Sampling Distribution and Kernel Comparison \n of Sample Means",
          cex.main = 0.9,
       col.main = "navy")  
lines(density(boot_mu_ln_mle, kernel = "gaussian"), col= "skyblue", lwd=2)

x_values <- seq(min(boot_mu_ln_mle), max(boot_mu_ln_mle), length = 100)
y_values <- dnorm(x_values, mean = mean(boot_mu_ln_mle), sd = sd(boot_mu_ln_mle))
lines(x_values, y_values, col = "red", lty = 2, lwd = 2) # Theoretical Normal
legend("topright", legend = c("KDE (Actual)", "Bootstrapped Normal (Theory)"), 
       col = c("skyblue", "red"), lty = c(1, 2), lwd = 2)

##Add asymptotic density curve

Question 3.4

(4). In order to find the asymptotic sampling distribution using the central limit theorem (CLT). That is, when sample size is large, ¯X → N  μLN, σLN √ n  where μLN and σLN can be estimated by using the plug-in principle of MLE. Based on the asymptotic sampling distribution of lognormal sample mean ¯X , add the asymptotic density curve to the above Bootstrap kernel density curve.

n = length(wellsize) #

#sigma / (sqrt(n))

########################Background info for log specific estimators
#a normal distribution  function dnorm() requires a mean and standard deviation 
mu_hat=  mean(log(wellsize)) # mean of natural log of sample


sigma_sq_hat = mean((log(wellsize)-mu_hat)^2) #needed to calculate standard error #no use ln value

#dnorm(wellsize, mean = mu_hat, sd= )
##############################################



#######LN values needed to calculate dnorm() asymptotic distribution 

mu_ln_hat = exp(mu_hat + (0.5* sigma_sq_hat))
sigma_sq_hat_ln= exp(2*mu_hat + sigma_sq_hat) * (exp(sigma_sq_hat) - 1) #sigma^2 ln hat value --> predicted MLE value for variation 


asympt_dis_se=sqrt(sigma_sq_hat_ln)/sqrt(n) #standard error for asymptotic sampling distribution 


x_axis = seq(min(boot_mu_ln_mle), max(boot_mu_ln_mle), length = 200) #defining range for distribution most valuable when being graphed

#Make theoretical density of asymptotic distribution 

asymptotic_dis_theory = dnorm(x_axis, mean = mu_ln_hat, sd = asympt_dis_se)

#asymptotic_dis_theory = dnorm(wellsize, mean= mu_ln_hat, sd=asympt_dis_se ) #sd --> enter standard error asympt_dis_se
kde = density(boot_mu_ln_mle, kernel = "gaussian")  #density(boot_mu_ln_mle, bw = sd_ml_MLE)

hist(boot_mu_ln_mle,                     # data used for histogram
     breaks = 14,                            # specify number of vertical bars
     probability = TRUE,
       xlab = "Bootstrap sample means",      # change the label of x-axis
      # add a title to the histogram
        main="Bootstrap Sampling Distribution, Kernel and Asymptotic Density \n of Sample Means",
          cex.main = 0.9,
       col.main = "navy")  
lines(density(boot_mu_ln_mle, kernel = "gaussian"), col= "skyblue", lwd=2)

lines(x_axis, asymptotic_dis_theory, col = "blue", lwd = 2, lty = 4)

x_values <- seq(min(boot_mu_ln_mle), max(boot_mu_ln_mle), length = 100) #defining graph range bootstrap
y_values <- dnorm(x_values, mean = mean(boot_mu_ln_mle), sd = sd(boot_mu_ln_mle))
lines(x_values, y_values, col = "red", lty = 2, lwd = 2) # Theoretical Normal
legend("topright", legend = c("Bootstrap Normal KDE (Actual)", "Bootstrap Normal (Theory)", "Asymptotic CLT"), 
       col = c("skyblue", "red", "blue"), lty = c(1, 2), lwd = 2)  #col = c("skyblue", "blue"), lty = c(1, 2), lwd = 2)

Question 3.5

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

The description below refers to the behavior of the kernel density estimator (KDE) bootstrap exclusively when referring to the bootstrap distrbution.

The two major sampling distributions used above for the sample mean included bootstrap sampling distribution for \(\mu_{ln}\) and asymptotic distribution. Both distributions are used to estimate the behavior of a distribution and estimations for population parameters.

The bootstrapping distribution is an empirical estimation of the \(\mu_{LN}\) parameter by taking repeated random samples from the original well sample and repeatedly calculating a mean from each sample. All of the bootstrapped samples are then meaned to reach an \(\mu\) estimator. This is a simulated approach to the MLE \(\hat\mu_{LN}\). As the bootstrap resampling method is an indirect way to calculate and estimator, as in the collected distribution is not assessed soley within the single collected distribution but the estimator is calculated over the estimator over of collection of resamples from the originally collected distribution. Repeatably resampling and calculating random bootstrap variables to ultimately calculate the random variable estimator of interest, \(\hat\mu_{LN}\).

We see the relationship in the Figure above (last figure in question 3.4) the bootstrap gaussian kernel density has a better fit to the maxima and minimums of the distribution, while the asymptotic distribution under performs in assuming the shape for the most occurring density at \(\hat\mu_{LN}\) and has fatter tails than the bootstrap KDE, suggesting a weaker fit than the KDE bootstrap.

The more the bootstrap is sampled, it can be assumed the bootstrap estimator reaches closer to the true estimator. In examining the differences between a kernel and asymptotic distribution, the bootstrap kernel density best suits the empirical data rather than assuming normality with a large sample size to met an approximation for the asymptotic distribution. As the best suited normal distribution is assigned to the asymptotic distribution in its parametric approach in approximation rather than fitting for the data empirically.

In reflection for this lognormal distribution specifically, Both distributions are similar in shape showing a natural order pattern in the data set, in which the distributions meets their respective conditions. Additionally, both distributions show a similar value towards the \(\hat\mu_{LN}\), the bootstrap being 30.9306417 and the asymptotic distribution being 30.9426444.

The bootstrapped value for \(\hat\mu_{LN}\) is 30.9306417 which is very close to the asymptotic mean at30.9426444. Our two distributions capture the predicted \(\hat\mu_{LN}\) similarly suggesting some rigor in both tests. If a decision needs to be made about which distribution best suits the model, the bootstrap KDE resamping offers a stronger fit to the histogram’s raw or natural distribution suggesting the MLE parameters derived from this distribution may have more rigor than their asymptotic distribution counterparts, although again, both distributions follow very similar patterns and information. Any selection made between the two distributions, should not vary between each other very much by eye and graph analysis.

4 Bonus Question

Derive the Hessian matrix by computing the second-order partial derivatives of the log-likelihood function (with respect to μ and σ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().

data= wellsize #log(wellsize)
log_like_wells_hess <- function(params, data) 
  {
  mu = params[1]       # shape parameter
  sigma_sq = params[2]  # scale parameter
  
  
  
n <- length(data)
  log_lik = (-n/2 * log(2*pi) - n/2 * log(sigma_sq) - sum(log(data)) - (1/(2*sigma_sq)) * sum((log(data) - mu)^2)) #we flip signs in the matrix process
  
return(log_lik)
}





log_likelihood_gradient = function(params, data) 
  {
  mu = params[1]
  sigma_sq = params[2]
  n = length(data)
#Gradient functions

  
# Taking the partial derivative with respect to mu
 d_mu <- (1/sigma_sq) * sum(log(data) - mu)
  
  # Partial derivative with respect to sigma_sq
  d_sigma_sq <- -n/(2 * sigma_sq) + (1/(2 * sigma_sq^2)) * sum((log(data) - mu)^2)
  
return(c(d_mu, d_sigma_sq))
}



analytical_hessian_func = function(params, data) 
  {
  mu = params[1]
  sigma_sq = params[2]
  n = length(data)
  
#Computing the second derivatives for mu and sigma^2
d2_mu <- -n / sigma_sq
  d2_sigma_sq <- n/(2 * sigma_sq^2) - (1/sigma_sq^3) * sum((log(data) - mu)^2)
  
  d_mu_d_sigma_sq <- -(1/sigma_sq^2) * sum(log(data) - mu)
  
# This analytically derived matrix   
hess_mat <- matrix(c(d2_mu, d_mu_d_sigma_sq, d_mu_d_sigma_sq, d2_sigma_sq),nrow = 2, byrow = TRUE)  

#return(c(d_mu, d_sigma_sq, d2_mu, d2_sigma_sq, d_mu_d_sigma_sq))  # Return log-likelihood  NOT the negative log-likelihood and gradients


  return(hess_mat)
}



# Finding Initial Values
## It is critical to select appropriate initial values to
## ensure fast convergence. In general, we can use whatever
## methods (such as MME) that are available to get appropriate
## initial values


# Using the MLE as the initial parameter estimates

initial_mu = mu_hat

initial_sigma_sq = sigma_sq_hat



#mle_optimization <- optim(par = c(initial_mu,initial_sigma_sq), fn = log_like_wells_hess, x = wellsize, hessian = TRUE)


# MLE using optim() with gradient



mle_result <- optim(
  par = c(mu_hat, sigma_sq_hat), #starting point of the predicted mu and sigma for the MLE
  fn = log_like_wells_hess,  
  gr = log_likelihood_gradient,
  data = wellsize,
  method = "L-BFGS-B",
  lower = c(-Inf, 1e-6),
  hessian = TRUE,
  control = list(fnscale = -1)
)


##
mle_result
$par
[1] 3.2685359 0.3271989

$value
[1] -206.444

$counts
function gradient 
       8        8 

$convergence
[1] 0

$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"

$hessian
              [,1]          [,2]
[1,] -1.528123e+02  5.185142e-14
[2,]  5.185142e-14 -2.335224e+02
#Comparing the hessian matrices derived analytically and optim()

numerical_hessian  <- mle_result$hessian
analytical_hessian <- analytical_hessian_func(mle_result$par, wellsize)

# Print for your midterm report
cat("--- Numerical Hessian from optim() ---\n")
--- Numerical Hessian from optim() ---
print(numerical_hessian)
              [,1]          [,2]
[1,] -1.528123e+02  5.185142e-14
[2,]  5.185142e-14 -2.335224e+02
cat("\n--- Analytically Derived Hessian ---\n")

--- Analytically Derived Hessian ---
print(analytical_hessian)
              [,1]          [,2]
[1,] -1.528123e+02  1.037019e-13
[2,]  1.037019e-13 -2.335158e+02

Both show negative correlation among \(\mu\) and \(\sigma^2\) and present similar values. Both show similarity in their sampling distribution.

LS0tDQp0aXRsZTogIjA3LSBNaWR0ZXJtIEV4YW06IFNUQSA1MDYiDQphdXRob3I6ICJFemFuYSBSaXZlcnMiDQpkYXRlOiAiIER1ZTogMDMtMDgtMjAyNiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCiMjIyMNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQogDQpcDQoNCiMgTWlkdGVybSBFeGFtIE9iamVjdGl2ZXMgDQoNCg0KKiBVbmRlcnN0YW5kIHRoZSBkZWZpbml0aW9uIGFuZCByZWxhdGlvbnNoaXAgYmV0d2VlbiBQREZzIGFuZCBDREZzLCBpbmNsdWRpbmcgdGhlaXIgbm9uLXBhcmFtZXRyaWMgZXN0aW1hdG9yczogdGhlIGVtcGlyaWNhbCBkaXN0cmlidXRpb24gZnVuY3Rpb24gYW5kIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRpb24gKEtERSkuIFwNCg0KKiBFc3RpbWF0ZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIHVzaW5nIHNpbXVsYXRpb24tYmFzZWQgbWV0aG9kcywgc3BlY2lmaWNhbGx5IHRoZSBib290c3RyYXAuIFwNCg0KKiBEZXJpdmUgcG9pbnQgZXN0aW1hdGVzIG9mIHBhcmFtZXRlcnMgdXNpbmcgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGFuZCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiAoTUxFKS4gXA0KKiBEZXNjcmliZSB0aGUgYXN5bXB0b3RpYyAobm9ybWFsKSBhbmQgYm9vdHN0cmFwIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgb2YgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRvcnMuIFwNCiogQXBwbHkgYWxsIHRoZSBhYm92ZSBpbmZlcmVudGlhbCBwcm9jZWR1cmVzIGluIGEgcHJvZ3JhbW1pbmcgZW52aXJvbm1lbnQgKHN1Y2ggYXMgUHl0aG9uKSB0byBwZXJmb3JtIG51bWVyaWNhbCBkYXRhIGFuYWx5c2lzLiBcDQoNCg0KDQojIyBMb2dub3JtYWwgRGlzdHJ1YnV0aW9uDQoNCjUuMSBMb2ctbm9ybWFsIERpc3RyaWJ1dGlvbiBUaGUgbG9nLW5vcm1hbCBkaXN0cmlidXRpb25zIGhhdmUgYmVlbiB3aWRlbHkgdXNlZCBpbiBtYW55IGRpZmZlcmVudCBmaWVsZHMgc3VjaCBhcyBmaW5hbmNlIGFuZCBlY29ub21pY3MsIGVuZ2luZWVyaW5nIGFuZCByZWxpYWJpbGl0eSwgZW52aXJvbm1lbnRhbCBzY2llbmNlLCBtZWRpY2FsIGFuZCBiaW9sb2d5IGV0Yy4gSWYgWCBmb2xsb3dzIGEgbG9nbm9ybWFsIGRpc3RyaWJ1dGlvbjogZih4O8K1LM+DMikgPSDiiJogMSB4IDLPgM+DMiBleHAg4oiSKGxueOKIksK1KTIgMs+DMiB3aGVyZSDCtSDiiIggUiBpcyB0aGUgbWVhbiBvZiBsblggYW5kIM+DMiA+IDAgaXMgdGhlIHZhcmlhbmNlIG9mIGxuWC4NCg0KDQoNCldvcmtpbmcgRGF0YXNldDogQSByZXNlcnZvaXIgZW5naW5lZXIgYXQgYW4gb2lsIGV4cGxvcmF0aW9uIGNvbXBhbnkgaGFzIHJlY2VudGx5IGRyaWxsZWQgNTAgbmV3IHdlbGxzIGluIGEgc2hhbGUgZm9ybWF0aW9uLiBBY2NvcmRpbmcgdG8gZ2VvbG9naWNhbCB0aGVvcnksIHRoZSBzaXplIG9mIG9pbCByZXNlcnZlcyBpbiB0aGlzIHR5cGUgb2YgZm9ybWF0aW9uIGlzIG9mdGVuIG1vZGVsZWQgdXNpbmcgYSBsb2ctbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlIGVuZ2luZWVyIGlzIHJlc3BvbnNpYmxlIGZvciBlc3RpbWF0aW5nIHRoZSB0eXBpY2FsIHJlc2VydmUgc2l6ZSBhbmQgcXVhbnRpZnlpbmcgdGhlIHVuY2VydGFpbnR5IG9mIHRoZXNlIGVzdGltYXRlcyBmb3IgYSBwcmVzZW50YXRpb24gdG8gc2VuaW9yIG1hbmFnZW1lbnQuIFRoZSBlc3RpbWF0ZWQgdWx0aW1hdGUgcmVjb3ZlcnkgKEVVUikgZm9yIHRoZSA1MCB3ZWxscywgbWVhc3VyZWQgaW4gdGhvdXNhbmRzIG9mIGJhcnJlbHMgKE1iYmwpLCBpcyBhcyBmb2xsb3dzOiANCg0KYGBgDQoxNy4zLCAyNC44LCA4LjIsIDMxLjUsIDE0LjEsIDQyLjcsIDExLjksIDU1LjMsIDIxLjQsIDkuNywgMzYuMiwgMTguNiwgNjMuMSwgMTMuMiwgMjguOSwgNDcuNSwgMTkuOCwgNy41LCAzMy40LCA1Mi4xLCAxNi4wLCAyNS45LCAzOC43LCAxMC4zLCA0NC4yLCAyMi41LCA1OC42LCAxMi44LCAzMC4zLCA0OC45LCAyMC4xLCAzNS40LCAxNS43LCA2MC4yLCAyNi43LCA0MS4zLCAxOC4xLCA1My44LCAyMy45LCA0Ni4yLCAyOS40LCAzNy42LCAxNC45LCA1MC41LCAzMi44LCAxOS4zLCA1Ni43LCAxMS4yLCAzOS41LCAyNy4xIA0KYGBgDQoNClRoaXMgYXNzaWdubWVudCBmb2N1c2VzIG9uIGZpbmRpbmcgdGhlIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiB0aGUgTUxFIMuGwrUgYW5kIMuGIHRvIMK1IGFuZCDPgzIgYmFzZWQgb24gYW4gZW52aXJvbm1lbnRhbCBzdHVkeSBkYXRhLg0KDQoNCiMgUXVlc3Rpb24gMTogTWV0aG9kIG9mIE1vbWVudHMgRXN0aW1hdGlvbiAoTU1FKSBvZiDCtSBhbmQgz4MyDQoNCkVzdGltYXRlIHRoZSBwYXJhbWV0ZXJzIMK1IGFuZCDPgzIgKGNhdXRpb246IG5vdCDPgyEpICBmcm9tIHRoZSByYXcgb2lsIHJlc2VydmUgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gay10aCBtb21lbnQgZnVuY3Rpb24uIA0KT3JnYW5pemUgeW91ciB3b3JrIGludG8gdGhyZWUgcGFydHM6DQoNCihhKSBEZXJpdmUgdGhlIHN5c3RlbSBvZiB0d28gZXF1YXRpb25zIGZvciB0aGUgbWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdG9ycyAoTU1Fcykgb2YgwrUgYW5kIM+DMi4NCg0KDQpgYGB7cn0NCiMxYS4gRGVyaXZpbmcgdGhlIHN5c3RlbSBvZiB0d28gZXF1YXRpb25zIGZvciB0aGUgbWV0aG9kcyBvZiBtb21lbnQgZXN0aW1hdG9ycyAoTU1FKSBvZiBtdSBhbmQgc2lnbWFfc3ENCg0Kd2VsbHNpemU9IHNvcnQoYygxNy4zLCAyNC44LCA4LjIsIDMxLjUsIDE0LjEsIDQyLjcsIDExLjksIDU1LjMsIDIxLjQsIDkuNywgMzYuMiwgMTguNiwgNjMuMSwgMTMuMiwgMjguOSwgNDcuNSwgMTkuOCwgNy41LCAzMy40LCA1Mi4xLCAxNi4wLCAyNS45LCAzOC43LCAxMC4zLCA0NC4yLCAyMi41LCA1OC42LCAxMi44LCAzMC4zLCA0OC45LCAyMC4xLCAzNS40LCAxNS43LCA2MC4yLCAyNi43LCA0MS4zLCAxOC4xLCA1My44LCAyMy45LCA0Ni4yLCAyOS40LCAzNy42LCAxNC45LCA1MC41LCAzMi44LCAxOS4zLCA1Ni43LCAxMS4yLCAzOS41LCAyNy4xICkpDQoNCg0KI20gbW9tZW50cyBmb3IgcGFyYW1ldGVycw0KbTEgPSBtZWFuKHdlbGxzaXplKSAjeGJhcg0KbTI9IG1lYW4od2VsbHNpemVeMikgI3ggc3F1YXJlZCBiYXINCiNhbGdlYnJpYyBhcHBsaWNhdGlvbiBmb3IgY2xvc2VkIGZvcm0gcG9wdWxhdGlvbiBwYXJhbWV0ZXJzIHNpZ21hXjIgYW5kIG11DQoNCm1vbV9zaWdtYV9zcSA9IGxvZyhtMikgLSAyKmxvZyhtMSkNCm1vbV9tdSA9IGxvZyhtMSkgLTAuNSAqIG1vbV9zaWdtYV9zcQ0KDQpjYXQoIk1NRSBmb3IgbXU6IiwgbW9tX211LCAiXG5NTUUgZm9yIHNpZ21hX3NxOiIsIG1vbV9zaWdtYV9zcSkNCg0KY2F0KCJTYW1wbGUgbWVhbjoiLCBtMSwgInNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb246IiwgbTIpDQpgYGANCg0KDQooYikgRGVyaXZlIHRoZSBjbG9zZWQtZm9ybSBleHByZXNzaW9ucyBmb3IgdGhlIE1NRXMgb2YgwrUsIM+DMiwgYW5kIMK1TE4sIGRlbm90ZWQgYnkgwrV+LCDPgzJ+LCBhbmQgwrVMTn4sIHJlc3BlY3RpdmVseS4NCg0KDQpTeXN0ZW0gb2YgZXF1YXRpb25zOg0KJCQNCiAgICBcbG4oXGJhcnt4fSkgPSBcbXUgKyBcZnJhY3sxfXsyfVxzaWdtYV4yDQogICAgIFxsbihcYmFye3heMn0pID0gMlxtdSArIDJcc2lnbWFeMg0KJCQNCg0KDQoNCg0KU29sdmUgRXF1YXRpb24gMSBmb3IgJFxtdSQgaW4gdGVybXMgb2YgJFxzaWdtYV4yJDoNCiQkDQpbDQptdSA9IFxsbihcYmFye3h9KSAtIFxmcmFjezF9ezJ9XHNpZ21hXjINCl0NCiQkDQoNClN1YnN0aXR1dGUgdGhpcyBleHByZXNzaW9uIGZvciAkXG11JDoNCiANCiQkIA0KW2xuKHt4XjJ9KSA9IDJbIFxsbihcYmFye3h9KSAtIFxmcmFjezF9ezJ9XHNpZ21hXjJdICsgMlxzaWdtYV4yXQ0KJCQNCg0KRGlzdHJpYnV0ZSBhbmQgc2ltcGxpZnkgdG8gZmluZCAkXHRpbGRle1xzaWdtYX1eMiQ6fQ0KDQokJA0KW2xuKHt4XjJ9KSA9IDJsbihcYmFye3h9KSAtIFxzaWdtYV4yICsgMlxzaWdtYV4yXQ0KJCQNCiQkDQpbbG4oe3heMn0pID0gMmxuKFxiYXJ7eH0pICsgXHNpZ21hXjJdDQokJA0KDQokJA0KWyBcdGlsZGV7XHNpZ21hfV4yID0gbG4oe3heMn0pIC0gMmxuKFxiYXJ7eH0pXQ0KJCQNCiANCg0KDQogU3Vic3RpdHV0ZSAkXHRpbGRle1xzaWdtYX1eMiQgYmFjayBpbnRvIHRoZSBleHByZXNzaW9uIGZvciAkXG11JDoNCg0KJCQNCltcdGlsZGV7XG11fSA9IGxuKFxiYXJ7eH0pIC0gXGZyYWN7MX17Mn0gW2xuKHt4XjJ9KSAtIDJsbihcYmFye3h9KV1dDQokJA0KJCQNCltcdGlsZGV7XG11fSA9IGxuKFxiYXJ7eH0pIC0gXGZyYWN7MX17Mn0gbG4oe3heMn0pICsgbG4oXGJhcnt4fSldDQokJA0KJCQNCltcdGlsZGV7XG11fSA9IDJsbihcYmFye3h9KSAtIFxmcmFjezF9ezJ9bG4oe3heMn0pXQ0KJCQNCg0KDQpPYnNlcnZpbmcgYm90aCBlcXVhdGlvbnMNCg0KJCQNCltcdGlsZGV7XG11fSA9IDJsbihcYmFye3h9KSAtIFxmcmFjezF9ezJ9XGxuKHheMildDQokJA0KDQokJA0KW1x0aWxkZXtcc2lnbWF9XjIgPSBsbih7eF4yfSkgLSAybG4oXGJhcnt4fSldDQokJA0KDQoNCg0KKGMpIFdyaXRlIGFuIFIgZnVuY3Rpb24gdGhhdCBvdXRwdXRzIHRoZSBNTUVzIMK1LCDPgzIsIGFuZCDCtUxOIGJhc2VkIG9uIHRoZSBnaXZlbiBkYXRhIHNldC4NCg0KDQpgYGB7cn0NCg0KDQpzaWdtYV9zcXVfdGlsZGEgPSBsb2cobTIpLTIqIGxvZyhtMSkNCm11X3RpbGRhID0gMipsb2cobTEpIC0gKCgxLzIpKmxvZyhtMikpDQoNCg0KY2F0KCJNdSB0aWxkYToiLCBtdV90aWxkYSwgIlBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uOiIsIHNpZ21hX3NxdV90aWxkYSkNCg0KDQpgYGANCmBgYHtyfQ0KI1dyaXRpbmcgYSBmdW5jdGlvbiBmb3IgTWV0aG9kcyBvZiBNb21lbnQgRXN0aW1hdGlvbg0KDQpNTUVsb2dub3JtPSBmdW5jdGlvbih3ZWxsc2l6ZSkNCnsNCiAgDQojbSBtb21lbnRzIGZvciBwYXJhbWV0ZXJzDQptMSA9IG1lYW4od2VsbHNpemUpICN4YmFyDQptMj0gbWVhbih3ZWxsc2l6ZV4yKSAjeCBzcXVhcmVkIGJhcg0KI2FsZ2VicmljIGFwcGxpY2F0aW9uIGZvciBjbG9zZWQgZm9ybSBwb3B1bGF0aW9uIHBhcmFtZXRlcnMgc2lnbWFeMiBhbmQgbXUNCg0KI21vbV9zaWdtYV9zcSA9IGxvZyhtMikgLSAyKmxvZyhtMSkgICNyZW1vdmUgaXRzIHRoZSBzYW1lIGJlbG93DQojbW9tX211ID0gbG9nKG0xKSAtMC41ICogbW9tX3NpZ21hX3NxDQogIA0Kc2lnbWFfc3F1X3RpbGRhID0gbG9nKG0yKS0yKiBsb2cobTEpICNjYWxjdWxhdGUgdGhlIE1PTSBmb3Igc3RhbmRhcmQgZGVpdmF0aW9uDQptdV90aWxkYSA9IDIqbG9nKG0xKSAtICgoMS8yKSpsb2cobTIpKSAjIGNhbGN1bGF0ZSB0aGUgTU9NIGZvciBtZWFuDQoNCnJldHVybihjKG11X3RpbGRhLCBzaWdtYV9zcXVfdGlsZGEsIG0xKSApDQoNCn0NCnJlc3VsdHMgPSBNTUVsb2dub3JtKHdlbGxzaXplKQ0KDQpjYXQoIk11IHRpbGRhOiIsIG11X3RpbGRhLCAiUG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb246Iiwgc2lnbWFfc3F1X3RpbGRhLCAibXVfTE4iLCBtMSkNCg0KYGBgDQoNClRoZSBvdXRwdXRzIGZvciB0aGUgbWV0aG9kIG9mIG1vbWVudCBlc3RpbWF0b3JzIGFyZSAkXHRpbGRlXG11JCA9IGByIG11X3RpbGRhYCwgJFx0aWxkZVxzaWdtYV4yJCA9IGByIHNpZ21hX3NxdV90aWxkYWAsIGFuZCAkXHRpbGRlXG11X3tMTn0kID0gYHIgbTFgLg0KDQoNCiMgUXVlc3Rpb24gMjogRmluZGluZyB0aGUgTUxFIG9mICRcbXUkIGFuZCAkXHNpZ21hXjIkIA0KDQojIyBRdWVzdGlvbiAyLjEgDQoNCigxKS4gRGVyaXZlIHRoZSBzY29yZSBmdW5jdGlvbnMgKGkuZS4sIHRoZSBncmFkaWVudCBvZiB0aGUgbG9nLWxpa2VsaWhvb2QpIGZvciB0aGUgcGFyYW1ldGVycyBvZiB0aGUgbG9nLW5vcm1hbCBkaXN0cmlidXRpb24sIGFuZCANCg0Kc2V0IHRoZW0gdG8gemVybyB0byBvYnRhaW4gdGhlIHN5c3RlbSBvZiBzY29yZSBlcXVhdGlvbnMuIA0KDQpCZWdpbiB3aXRoIHRoZSBmdWxsIGxvZy1saWtlbGlob29kIGFuZCBjb21wdXRlIGl0cyBwYXJ0aWFsIGRlcml2YXRpdmVzIHdpdGggcmVzcGVjdCB0byDCtSBhbmQgz4MyLiBbSGludDogbGV0dGluZyDOsiA9IM+DMiBtYXkgc2ltcGxpZnkgZGlmZmVyZW50aWF0aW9uLl0NCg0KDQoNClRoZSBsb2ctbGlrZWxpaG9vZCBmb3IgdGhlIGxvZy1ub3JtYWwgZGlzdHJpYnV0aW9uIGlzIGdpdmVuIGJ5Og0KDQokJA0KXGVsbChcbXUsIFxiZXRhKSA9IC1cZnJhY3tufXsyfSBcbG4oMlxwaSkgLSBcZnJhY3tufXsyfSBcbG4gXGJldGEgLSBcc3VtX3tpPTF9Xm4gXGxuIHhfaSAtIFxmcmFjezF9ezJcYmV0YX0gXHN1bV97aT0xfV5uIChcbG4geF9pIC0gXG11KV4yDQokJA0KIFBhcnRpYWwgZGVyaXZhdGl2ZSB3aXRoIHJlc3BlY3QgdG8gJFxtdSQ6DQogDQogDQokJA0KXGZyYWN7XHBhcnRpYWwgXGVsbH17XHBhcnRpYWwgXG11fSA9IFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcbXV9IFxsZWZ0WyAtXGZyYWN7MX17MlxiZXRhfSBcc3VtX3tpPTF9Xm4gKFxsbiB4X2kgLSBcbXUpXjIgXHJpZ2h0XSBcXA0KICAgID0gLVxmcmFjezF9ezJcYmV0YX0gXHN1bV97aT0xfV5uIDIoXGxuIHhfaSAtIFxtdSkgXGNkb3QgXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxtdX0oXGxuIHhfaSAtIFxtdSkgXFwNCiAgICA9IC1cZnJhY3sxfXsyXGJldGF9IFxzdW1fe2k9MX1ebiAyKFxsbiB4X2kgLSBcbXUpIFxjZG90ICgtMSkgXFwNCiAgICBVKFxtdSkgPSBcZnJhY3sxfXtcYmV0YX0gXHN1bV97aT0xfV5uIChcbG4geF9pIC0gXG11KQ0KJCQNCg0KDQoNClJlYWNoIHRoZSBzY29yZSBmdW5jdGlvbiBvZiB0aGUgZXF1YXRpb25zDQpQYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvICRcYmV0YSQsIHdlIHRyZWF0ICRcYmV0YSQgaW4gc3Vic3RpdHV0aW9uIG9mICRcc2lnbWFeMiQgZm9yIHNpbXBsaWNpdHk6DQokJA0KXGZyYWN7XHBhcnRpYWwgXGVsbH17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxiZXRhfSBcbGVmdFsgLVxmcmFje259ezJ9IFxsbiBcYmV0YSBccmlnaHRdIC0gXGZyYWN7XHBhcnRpYWx9e1xwYXJ0aWFsIFxiZXRhfSBcbGVmdFsgXGZyYWN7MX17MlxiZXRhfSBcc3VtX3tpPTF9Xm4gKFxsbiB4X2kgLSBcbXUpXjIgXHJpZ2h0XSBcXA0KICAgID0gLVxmcmFje259ezJcYmV0YX0gLSBcZnJhY3sxfXsyfSBcc3VtX3tpPTF9Xm4gKFxsbiB4X2kgLSBcbXUpXjIgXGNkb3QgXGZyYWN7ZH17ZFxiZXRhfShcYmV0YV57LTF9KSBcXA0KICAgID0gLVxmcmFje259ezJcYmV0YX0gLSBcZnJhY3sxfXsyfSBcc3VtX3tpPTF9Xm4gKFxsbiB4X2kgLSBcbXUpXjIgXGNkb3QgKC1cYmV0YV57LTJ9KSBcXA0KICAgIFUoXGJldGEpID0gLVxmcmFje259ezJcYmV0YX0gKyBcZnJhY3sxfXsyXGJldGFeMn0gXHN1bV97aT0xfV5uIChcbG4geF9pIC0gXG11KV4yDQokJA0KDQpSZXBsYWNpbmcgJFxiZXRhJCB3aXRoICRcc2lnbWFeMiQgIA0KDQokJA0KLVxmcmFje259ezJcc2lnbWFeMn0gKyBcZnJhY3sxfXsyXHNpZ21hXjR9IFxzdW1fe2k9MX1ebiAoXGxuIHhfaSAtIFxtdSleMiA9IDAgDQokJA0KDQoNCiMjIFF1ZXN0aW9uIDIuMg0KDQooMikuIFBlcmZvcm0gc29tZSBhbGdlYnJhIHRvIGZpbmQgdGhlIGNsb3NlZCBmb3JtIG9mIHRoZSBNTEUgb2YgwrUgYW5kIM+DMiwgZGVub3RlZCBieSDCtSBhbmQgz4MyDQoNCg0KU29sdmluZyBmb3IgJFxoYXRcbXUkDQoNCiQkDQpcc3VtX3tpPTF9Xm4gKFxsbiB4X2kgLSBcbXUpID0gMCBcXA0KXHN1bV97aT0xfV5uIFxsbiB4X2kgLSBuXG11ID0gMCBcXA0KXGhhdHtcbXV9ID0gXGZyYWN7MX17bn0gXHN1bV97aT0xfV5uIFxsbiB4X2kNCiQkDQoNCg0KU29sdmluZyBmb3IgJFxoYXRcc2lnbWFeMiQNCg0KJCQNClxmcmFje259ezJcc2lnbWFeMn0gPSBcZnJhY3sxfXsyXHNpZ21hXjR9IFxzdW1fe2k9MX1ebiAoXGxuIHhfaSAtIFxoYXR7XG11fSleMiBcXA0KblxzaWdtYV4yID0gXHN1bV97aT0xfV5uIChcbG4geF9pIC0gXGhhdHtcbXV9KV4yIFxcDQpcaGF0e1xzaWdtYX1eMiA9IFxmcmFjezF9e259IFxzdW1fe2k9MX1ebiAoXGxuIHhfaSAtIFxoYXR7XG11fSleMg0KJCQNCg0KDQoNCiMjIFF1ZXN0aW9uIDIuMyANCg0KKDMpLiBSZWNhbGwgdGhhdCBsb2dub3JtYWwgcG9wdWxhdGlvbiBtZWFuIChpLmUuLCB0aGUgZmlyc3QgbW9tZW50KSBpcw0KzrxMTiA9IEVbWF0gPSBleHAozrwgKyAxLzLPgzIpLg0KVXNpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHZhcmlhbmNlIGFuZCB0aGUgZmlyc3QgYW5kIHNlY29uZCBtb21lbnRzLCANCg0KVmFyKFgpID0gRVtYMl0g4oiSIChFW1hdKTIsIA0KDQp3ZSBkZXJpdmUgdGhlIHBvcHVsYXRpb24gdmFyaWFuY2Ugb2YgdGhlIGxvZ25vcm1hbCBkaXN0cmlidXRpb24sIGRlbm90ZWQgYXMgz4MyDQpMTi4gVGhpcyByZXN1bHQgd2lsbCBiZSB1c2VkIGluDQphcHBseWluZyB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtIGluIHN1YnNlcXVlbnQgcXVlc3Rpb25zDQoNCg0KJCQNCntWYXJ9KFgpID0gRVtYXjJdIC0oRVtYXSleMiBcXA0KJCQNCg0KJCQNClxzaWdtYV4yX3tMTn0gPSBFW1heMl0gLSAoRVtYXSleMiANCiQkDQoNCiQkDQpFW1hdID0gZXhwKFxtdSArIFxmcmFjezF9ezJ9XHNpZ21hXjIpIFxcDQoNCkVbWF5rXSA9IGV4cChrXG11ICsgXGZyYWN7MX17a31rXjJcc2lnbWFeMiksIFxcDQoNCkVbWF4yXSA9IGV4cCgyXG11ICsgXGZyYWN7MX17Mn0oMl4yKVxzaWdtYV4yKSBcXA0KRVtYXjJdID0gZXhwKDJcbXUgKyAyXHNpZ21hXjIpDQoNCiQkDQoNCiQkDQpcc2lnbWFeMl97TE59ID0gRVtYXjJdIC0gKEVbWF0pXjIgDQokJA0KDQoNCiQkDQpcc2lnbWFeMl97TE59ID0gZXhwKDJcbXUgKyAyXHNpZ21hXjIpIC0gWyBleHAoXG11ICsgXGZyYWN7MX17Mn1cc2lnbWFeMildXjIgDQokJA0KJCQNClxzaWdtYV4yX3tMTn0gPSBleHAoMlxtdSArIDJcc2lnbWFeMikgLSBleHAoMlxtdSArIFxzaWdtYV4yKQ0KJCQNCg0KDQoNCg0KDQoNCiMgUXVlc3Rpb24gMzogU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIExvZ25vcm1hbCBTYW1wbGUgTWVhbiAkXGhhdFxtdV97TE59JA0KDQpXZSBoYXZlIGRlcml2ZWQgdHdvIGRpZmZlcmVudCBlc3RpbWF0b3JzIG9mIGxvZ25vcm1hbCBwb3B1bGF0aW9uIG1lYW4gzrxMTi4gVGhpcyBRdWVzdGlvbiBmb2N1c2VzIG9uDQp0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGxvZ25vcm1hbCBzYW1wbGUgc2FtcGxlIG1lYW5zIGJhc2VkIG9uIE1MRS4gVGhlIGZvbGxvd2luZyBhcmUgZGV0YWlsZWQNCmluc3RydWN0aW9ucy4NCg0KIyBRdWVzdGlvbiAzLjEgDQoNCigxKS4gV3JpdGUgYW4gUiBmdW5jdGlvbiB0byBlc3RpbWF0ZSB0aGUgTUxFIG9mIM68IGFuZCDPgzIsIGRlbm90ZWQgYnkgYs68IGFuZCBjz4MyIGFuZCByZXR1cm4gdGhlIE1MRSBvZg0KzrxMTiwgZGVub3RlZCBieSAgJFxoYXRcbXVfe0xOfSQuDQoNClRoZSBsb2ctbGlrZWxpaG9vZCBmb3IgdGhlIGxvZy1ub3JtYWwgZGlzdHJpYnV0aW9uIGlzIGdpdmVuIGJ5Og0KDQokJA0KXGVsbChcbXUsIFxiZXRhKSA9IC1cZnJhY3tufXsyfSBcbG4oMlxwaSkgLSBcZnJhY3tufXsyfSBcbG4gXGJldGEgLSBcc3VtX3tpPTF9Xm4gXGxuIHhfaSAtIFxmcmFjezF9ezJcYmV0YX0gXHN1bV97aT0xfV5uIChcbG4geF9pIC0gXG11KV4yDQokJA0KDQoNCmBgYHtyfQ0KDQojV3JpdGUgdGhlIFIgZnVuY3Rpb24gdGhhdCBlc3RpbWF0aW9ucyB0aGUgTUxFIG9mIHRoZSBtdSBhbmQgc2lnbWFeMiBkZW5vdGVkIGJ5IG11X2hhdCBhbmQgc2lnbWEgc3F1YXJlIGhhdCB0byB0aGVuIHJldHVybg0KI1RoZSBNYXhpbXVtIExpbWl0YXRpb24gRXN0aW1hdG9yIG9mIHRoZSBtdV9MTiwgZGVub3RlZCBtdV9MTl9oYXQNCg0KDQpkYXRhID0gd2VsbHNpemUgI2luc2VydGluZyB0aGUgZGF0YSBvZiBpbnRlcmVzdCB0byBiZSB3ZWxsc2l6ZQ0KDQoNCg0Kbm9ybWxvZ19tbGU9IGZ1bmN0aW9uKGRhdGEpDQogIHsNCiAgICAjTE9HIExJS0xFSUhPT0QtLT4gaXRzIGEgbm9ybWFsbG9nIHNvIGZpbmUNCiAgICBsb2dfZGF0YSA9IGxvZyhkYXRhKQ0KICAgICNGaW5kIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEgZm9yIGdyYWRpZW50IGVxdWF0aW9ucw0KICAgIA0KICAgIG4gPSBsZW5ndGgoZGF0YSkNCiAgICANCiAgICAjY2xvc2VkIGZvcm0gZm9yIG11X2hhdCBhbmQgc2lnbWFfc3FfaGF0DQogICAgbXVfaGF0ID0gbWVhbihsb2dfZGF0YSkNCiAgICBzaWdtYV9zcV9oYXQgPSBtZWFuKChsb2dfZGF0YS1tdV9oYXQpXjIpIA0KICAgIA0KICAgICNDYWxjdWxhdGluZyB0aGUgcG9wdWxhdGlvbiBwYXJhdGVycyBmb3IgTUxFOiBtdV9sbl9oYXQNCiAgICANCiAgICBtdV9sbl9oYXQgPSBleHAobXVfaGF0ICsgKDAuNSogc2lnbWFfc3FfaGF0KSkNCiAgICANCmNhdCgiTXUgaGF0OiIsIG11X2hhdCwgIlNpZ21hIFNxdWFyZWQgaGF0IC0gUHJlZGljdGVkIHN0YW5kYXJkIGRldmlhdGlvbjoiLCBzaWdtYV9zcV9oYXQsICJNTEUgbXVfbG4iLCBtdV9sbl9oYXQpICAgDQoNCg0KcmV0dXJuKGMobXVfaGF0ID0gbXVfaGF0LCBzaWdtYV9zcV9oYXQgPSBzaWdtYV9zcV9oYXQsIG11X2xuX2hhdCA9IG11X2xuX2hhdCkpDQp9DQoNCg0KbWxlX3Jlc3VsdHMgPSBub3JtbG9nX21sZSh3ZWxsc2l6ZSkNCg0KDQojbm8gZ3JhZGllbnQgZnVuY3Rpb24gKGNsb3NlZCBmb3JtIG5vIG9wdGltKSAtLT4gcGFydGlhbCBkaWZmZXJlbnRpYXRpb24gYW5kIHNldCB0byAwDQoNCg0KDQoNCiMgU29sdmUgc3lzdGVtIGZvciBNTEUgKG11X0xOX2hhdCkNCg0KDQpgYGANCiMjIFF1ZXN0aW9uIDMuMiANCg0KKDIpLiBUYWtlIDEwMDAgQm9vdHN0cmFwIHNhbXBsZXMgZnJvbSB0aGUgcmF3IG9pbCBkYXRhIHNldC4gRm9yIGVhY2ggYm9vdHN0cmFwIHNhbXBsZSwgY2FsbCB0aGUgYWJvdmUgUg0KZnVuY3Rpb24gdG8gZmluZCB0aGUgYm9vdHN0cmFwIE1MRSBvZiDOvExOLCBkZW5vdGVkIGJ5IGTOvOKIlw0KTE4NCigxKQ0KLCBkzrziiJcNCkxODQooMikNCiwgwrcgwrcgwrcgLCBkzrziiJcNCkxODQooMTAwMCkuDQoNCk5vdGU6IA0KJCRcbXVfe0xOfSA9IFxleHBcbGVmdChcbXUgKyBcZnJhY3sxfXsyfVxzaWdtYV4yXHJpZ2h0KSQkDQoNCmBgYHtyfQ0KDQpzZXQuc2VlZCgxNDMpDQoNCmxlbmd0aCh3ZWxsc2l6ZSkgI24gPTUwDQoNCmJvb3RfbXVfbG5fbWxlID0gTlVMTA0KbG9nX3dlbGw9IHdlbGxzaXplDQoNCg0KZm9yIChpIGluIDE6MTAwMCkNCnsNCg0KI2Jvb3RzdHJhcCBzYW1wbGUNCiMgbWFrZSBzdXJlIHNhbXBsZSBpcyBpbiBpdHMgbG9nIGZvcm0NCiAgDQogIyB0YWtlIHJhdyBub3QgbG9nIG9mIG1lYW4gI2xvZyh3ZWxsc2l6ZSkgLS0+IGxvZyB0aGUgYm9vdHN0cmFwcGVkIHNhbXBsZQ0KICANCmJvb3RzdHJhcF93ZWxsPSBzYW1wbGUoeD1sb2dfd2VsbCwgNTAsIHJlcGxhY2U9IFRSVUUpICNib290c3RyYXBwaW5nIGZyb20gdGhlIHdlbGwgc2FtcGxlDQoNCmxvZ19ib290X3dlbGw9bG9nKGJvb3RzdHJhcF93ZWxsKSAjdGFrZSB0aGUgbG9nIG9mIHRoZSBib290c3RyYXBwZWQgc2FtcGxlIHRvIHJ1biB0aGUgbG9nIGxpa2VsaWhvb2QNCg0KDQojdGFrZSB0aGUgbWVhbiBvZiB0aGUgbG9nIGxpa2VsaWhvb2QgYm9vdHN0cmFwIHRvIGlucHV0IGluIE1MRSBtdSBlcXVhdGlvbg0KbXVfaGF0ID0gbWVhbihsb2dfYm9vdF93ZWxsKSAgI01MRSBlc3RpbWF0b3IgZm9yIG11DQpzaWdtYV9zcV9oYXQgPSBtZWFuKChsb2dfYm9vdF93ZWxsLW11X2hhdCleMikgI01MRSBlc3RpbWF0b3IgZm9yIHNpbWdhXjINCg0KDQojTm93IGNhbGN1bGF0ZSB0aGUgbXUgbG4NCg0KYm9vdF9tdV9sbl9tbGVbaV0gPSBleHAobXVfaGF0ICsoMC41KiBzaWdtYV9zcV9oYXQpKSAjZ2l2ZXMgZGlzdHJ1YnV0aW9uIG9mIHRoZSBib290c3RyYXAgZm9yIHRoZSBtdSBsbiBtbGUNCg0KZmluYWxfbXVfbG5fTUxFID0gbWVhbihib290X211X2xuX21sZSkgI2dpdmVzIHNpbmdsZSB2YWx1ZSBmb3IgYm9vdHN0cmFwcGVkIG1sZSBtdSBsbg0KDQojcmV0dXJuKGMoZmluYWxfbXVfbG5fTUxFKSkgI29ubHkga2VlcGluZyBsYXN0IHRoaW5nIHJhbiAtLT4gVkVSUlkgVkVSWVkgQkFEIEZPUiBib290c3RyYXBwaW5nIC0tPiBub3Qga2VlcGluZyB0aGUgZGlzdHJpYnV0aW9uIGZvciB0aGUgbW9kZWwNCn0NCg0KY2F0KCJCb290c3RyYXAgTUxFIG9mIM68TE46IiwgZmluYWxfbXVfbG5fTUxFKQ0KDQpgYGANClRoZSBib290c3RyYXAgTUxFIG9mICRcbXVfe2xufSQgaXMgYHIgZmluYWxfbXVfbG5fTUxFYC4gDQoNCmBgYHtyIGluY2x1ZGU9RkFMU0V9IA0KI0NhbiByZW1vdmUgYmMgcXVlc3Rpb24gMy4zIGNyZWF0ZXMgZ3JhcGgNCmhpc3QoYm9vdF9tdV9sbl9tbGUsICAgICAgICAgICAgICAgICAgICAgIyBkYXRhIHVzZWQgZm9yIGhpc3RvZ3JhbQ0KICAgICBicmVha3MgPSAxNCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IG51bWJlciBvZiB2ZXJ0aWNhbCBiYXJzDQogICAgIHByb2JhYmlsaXR5ID0gVFJVRSwNCiAgICAgICB4bGFiID0gIkJvb3RzdHJhcCBzYW1wbGUgbWVhbnMiLCAgICAgICMgY2hhbmdlIHRoZSBsYWJlbCBvZiB4LWF4aXMNCiAgICAgICMgYWRkIGEgdGl0bGUgdG8gdGhlIGhpc3RvZ3JhbQ0KICAgICAgICBtYWluPSJCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIFxuIG9mIFNhbXBsZSBNZWFucyIsDQogICAgICAgICAgY2V4Lm1haW4gPSAwLjksDQogICAgICAgY29sLm1haW4gPSAibmF2eSIpICAgDQpsaW5lcyhkZW5zaXR5KGJvb3RfbXVfbG5fbWxlKSwgY29sID0gInNreWJsdWUiLCBsd2QgPSAyKQ0KDQoNCmBgYA0KIyBRdWVzdGlvbiAzLjMgDQoNCigzKS4gVXNpbmcga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbiBhcHByb2FjaCB0byBlc3RpbWF0ZSB0aGUgYm9vdHN0cmFwIGRlbnNpdHkgY3VydmVzIGJhc2VkIG9uIHRoZSBib290c3RyYXAgTUxFczogDQpkzrziiJcNCkxODQooMSkNCiwgZM684oiXDQpMTg0KKDIpDQosIMK3IMK3IMK3ICwgZM684oiXDQpMTg0KKDEwMDApLg0KDQoNCmBgYHtyfQ0KDQojc2RfbWxfTUxFPXNkKGJvb3RfbXVfbG5fbWxlKSAjeW91IHdvdWxkIG5lZWQgdG8gY2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBkaXN0cmlidXRpb24gdG8gbWFrZSBhIGJhbmR3aWR0aCBmb3IgdGhlIGtlcm5lbCANCg0Ka2RlID0gZGVuc2l0eShib290X211X2xuX21sZSwga2VybmVsID0gImdhdXNzaWFuIikgICNkZW5zaXR5KGJvb3RfbXVfbG5fbWxlLCBidyA9IHNkX21sX01MRSkNCg0KaGlzdChib290X211X2xuX21sZSwgICAgICAgICAgICAgICAgICAgICAjIGRhdGEgdXNlZCBmb3IgaGlzdG9ncmFtDQogICAgIGJyZWFrcyA9IDE0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNwZWNpZnkgbnVtYmVyIG9mIHZlcnRpY2FsIGJhcnMNCiAgICAgcHJvYmFiaWxpdHkgPSBUUlVFLA0KICAgICAgIHhsYWIgPSAiQm9vdHN0cmFwIHNhbXBsZSBtZWFucyIsICAgICAgIyBjaGFuZ2UgdGhlIGxhYmVsIG9mIHgtYXhpcw0KICAgICAgIyBhZGQgYSB0aXRsZSB0byB0aGUgaGlzdG9ncmFtDQogICAgICAgIG1haW49IkJvb3RzdHJhcCBTYW1wbGluZyBEaXN0cmlidXRpb24gYW5kIEtlcm5lbCBDb21wYXJpc29uIFxuIG9mIFNhbXBsZSBNZWFucyIsDQogICAgICAgICAgY2V4Lm1haW4gPSAwLjksDQogICAgICAgY29sLm1haW4gPSAibmF2eSIpICANCmxpbmVzKGRlbnNpdHkoYm9vdF9tdV9sbl9tbGUsIGtlcm5lbCA9ICJnYXVzc2lhbiIpLCBjb2w9ICJza3libHVlIiwgbHdkPTIpDQoNCnhfdmFsdWVzIDwtIHNlcShtaW4oYm9vdF9tdV9sbl9tbGUpLCBtYXgoYm9vdF9tdV9sbl9tbGUpLCBsZW5ndGggPSAxMDApDQp5X3ZhbHVlcyA8LSBkbm9ybSh4X3ZhbHVlcywgbWVhbiA9IG1lYW4oYm9vdF9tdV9sbl9tbGUpLCBzZCA9IHNkKGJvb3RfbXVfbG5fbWxlKSkNCmxpbmVzKHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sID0gInJlZCIsIGx0eSA9IDIsIGx3ZCA9IDIpICMgVGhlb3JldGljYWwgTm9ybWFsDQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiS0RFIChBY3R1YWwpIiwgIkJvb3RzdHJhcHBlZCBOb3JtYWwgKFRoZW9yeSkiKSwgDQogICAgICAgY29sID0gYygic2t5Ymx1ZSIsICJyZWQiKSwgbHR5ID0gYygxLCAyKSwgbHdkID0gMikNCg0KDQojI0FkZCBhc3ltcHRvdGljIGRlbnNpdHkgY3VydmUNCg0KYGBgDQoNCg0KIyMgUXVlc3Rpb24gMy40DQoNCig0KS4gSW4gb3JkZXIgdG8gZmluZCB0aGUgYXN5bXB0b3RpYyBzYW1wbGluZyBkaXN0cmlidXRpb24gdXNpbmcgdGhlIGNlbnRyYWwgbGltaXQgdGhlb3JlbSAoQ0xUKS4gVGhhdCBpcywNCndoZW4gc2FtcGxlIHNpemUgaXMgbGFyZ2UsDQrCr1gNCuKGkiBODQoSDQrOvExOLA0Kz4NMTiDiiJoNCm4NChMNCndoZXJlIM68TE4gYW5kIM+DTE4gY2FuIGJlIGVzdGltYXRlZCBieSB1c2luZyB0aGUgcGx1Zy1pbiBwcmluY2lwbGUgb2YgTUxFLiBCYXNlZCBvbiB0aGUgYXN5bXB0b3RpYw0Kc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGxvZ25vcm1hbCBzYW1wbGUgbWVhbiDCr1ggLCBhZGQgdGhlIGFzeW1wdG90aWMgZGVuc2l0eSBjdXJ2ZSB0byB0aGUgYWJvdmUNCkJvb3RzdHJhcCBrZXJuZWwgZGVuc2l0eSBjdXJ2ZS4NCg0KDQoNCmBgYHtyfQ0KDQpuID0gbGVuZ3RoKHdlbGxzaXplKSAjDQoNCiNzaWdtYSAvIChzcXJ0KG4pKQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNCYWNrZ3JvdW5kIGluZm8gZm9yIGxvZyBzcGVjaWZpYyBlc3RpbWF0b3JzDQojYSBub3JtYWwgZGlzdHJpYnV0aW9uICBmdW5jdGlvbiBkbm9ybSgpIHJlcXVpcmVzIGEgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIA0KbXVfaGF0PSAgbWVhbihsb2cod2VsbHNpemUpKSAjIG1lYW4gb2YgbmF0dXJhbCBsb2cgb2Ygc2FtcGxlDQoNCg0Kc2lnbWFfc3FfaGF0ID0gbWVhbigobG9nKHdlbGxzaXplKS1tdV9oYXQpXjIpICNuZWVkZWQgdG8gY2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yICNubyB1c2UgbG4gdmFsdWUNCg0KI2Rub3JtKHdlbGxzaXplLCBtZWFuID0gbXVfaGF0LCBzZD0gKQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCg0KIyMjIyMjI0xOIHZhbHVlcyBuZWVkZWQgdG8gY2FsY3VsYXRlIGRub3JtKCkgYXN5bXB0b3RpYyBkaXN0cmlidXRpb24gDQoNCm11X2xuX2hhdCA9IGV4cChtdV9oYXQgKyAoMC41KiBzaWdtYV9zcV9oYXQpKQ0Kc2lnbWFfc3FfaGF0X2xuPSBleHAoMiptdV9oYXQgKyBzaWdtYV9zcV9oYXQpICogKGV4cChzaWdtYV9zcV9oYXQpIC0gMSkgI3NpZ21hXjIgbG4gaGF0IHZhbHVlIC0tPiBwcmVkaWN0ZWQgTUxFIHZhbHVlIGZvciB2YXJpYXRpb24gDQoNCg0KYXN5bXB0X2Rpc19zZT1zcXJ0KHNpZ21hX3NxX2hhdF9sbikvc3FydChuKSAjc3RhbmRhcmQgZXJyb3IgZm9yIGFzeW1wdG90aWMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIA0KDQoNCnhfYXhpcyA9IHNlcShtaW4oYm9vdF9tdV9sbl9tbGUpLCBtYXgoYm9vdF9tdV9sbl9tbGUpLCBsZW5ndGggPSAyMDApICNkZWZpbmluZyByYW5nZSBmb3IgZGlzdHJpYnV0aW9uIG1vc3QgdmFsdWFibGUgd2hlbiBiZWluZyBncmFwaGVkDQoNCiNNYWtlIHRoZW9yZXRpY2FsIGRlbnNpdHkgb2YgYXN5bXB0b3RpYyBkaXN0cmlidXRpb24gDQoNCmFzeW1wdG90aWNfZGlzX3RoZW9yeSA9IGRub3JtKHhfYXhpcywgbWVhbiA9IG11X2xuX2hhdCwgc2QgPSBhc3ltcHRfZGlzX3NlKQ0KDQojYXN5bXB0b3RpY19kaXNfdGhlb3J5ID0gZG5vcm0od2VsbHNpemUsIG1lYW49IG11X2xuX2hhdCwgc2Q9YXN5bXB0X2Rpc19zZSApICNzZCAtLT4gZW50ZXIgc3RhbmRhcmQgZXJyb3IgYXN5bXB0X2Rpc19zZQ0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KDQoNCmtkZSA9IGRlbnNpdHkoYm9vdF9tdV9sbl9tbGUsIGtlcm5lbCA9ICJnYXVzc2lhbiIpICAjZGVuc2l0eShib290X211X2xuX21sZSwgYncgPSBzZF9tbF9NTEUpDQoNCmhpc3QoYm9vdF9tdV9sbl9tbGUsICAgICAgICAgICAgICAgICAgICAgIyBkYXRhIHVzZWQgZm9yIGhpc3RvZ3JhbQ0KICAgICBicmVha3MgPSAxNCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBzcGVjaWZ5IG51bWJlciBvZiB2ZXJ0aWNhbCBiYXJzDQogICAgIHByb2JhYmlsaXR5ID0gVFJVRSwNCiAgICAgICB4bGFiID0gIkJvb3RzdHJhcCBzYW1wbGUgbWVhbnMiLCAgICAgICMgY2hhbmdlIHRoZSBsYWJlbCBvZiB4LWF4aXMNCiAgICAgICMgYWRkIGEgdGl0bGUgdG8gdGhlIGhpc3RvZ3JhbQ0KICAgICAgICBtYWluPSJCb290c3RyYXAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uLCBLZXJuZWwgYW5kIEFzeW1wdG90aWMgRGVuc2l0eSBcbiBvZiBTYW1wbGUgTWVhbnMiLA0KICAgICAgICAgIGNleC5tYWluID0gMC45LA0KICAgICAgIGNvbC5tYWluID0gIm5hdnkiKSAgDQpsaW5lcyhkZW5zaXR5KGJvb3RfbXVfbG5fbWxlLCBrZXJuZWwgPSAiZ2F1c3NpYW4iKSwgY29sPSAic2t5Ymx1ZSIsIGx3ZD0yKQ0KDQpsaW5lcyh4X2F4aXMsIGFzeW1wdG90aWNfZGlzX3RoZW9yeSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsdHkgPSA0KQ0KDQp4X3ZhbHVlcyA8LSBzZXEobWluKGJvb3RfbXVfbG5fbWxlKSwgbWF4KGJvb3RfbXVfbG5fbWxlKSwgbGVuZ3RoID0gMTAwKSAjZGVmaW5pbmcgZ3JhcGggcmFuZ2UgYm9vdHN0cmFwDQp5X3ZhbHVlcyA8LSBkbm9ybSh4X3ZhbHVlcywgbWVhbiA9IG1lYW4oYm9vdF9tdV9sbl9tbGUpLCBzZCA9IHNkKGJvb3RfbXVfbG5fbWxlKSkNCmxpbmVzKHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sID0gInJlZCIsIGx0eSA9IDIsIGx3ZCA9IDIpICMgVGhlb3JldGljYWwgTm9ybWFsDQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiQm9vdHN0cmFwIE5vcm1hbCBLREUgKEFjdHVhbCkiLCAiQm9vdHN0cmFwIE5vcm1hbCAoVGhlb3J5KSIsICJBc3ltcHRvdGljIENMVCIpLCANCiAgICAgICBjb2wgPSBjKCJza3libHVlIiwgInJlZCIsICJibHVlIiksIGx0eSA9IGMoMSwgMiksIGx3ZCA9IDIpICAjY29sID0gYygic2t5Ymx1ZSIsICJibHVlIiksIGx0eSA9IGMoMSwgMiksIGx3ZCA9IDIpDQoNCg0KDQpgYGANCg0KDQojIyBRdWVzdGlvbiAzLjUgDQoNCig1KS4gV3JpdGUgYSBzaG9ydCBzdW1tYXJ5IHRvIGNvbXBhcmUgdGhlIHR3byBzYW1wbGluZyBkaXN0cmlidXRpb25zIG9mIHRoZSBzYW1wbGUgbWVhbiBvZiB0aGUgbG9nbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KVGhlIGRlc2NyaXB0aW9uIGJlbG93IHJlZmVycyB0byB0aGUgYmVoYXZpb3Igb2YgdGhlIGtlcm5lbCBkZW5zaXR5IGVzdGltYXRvciAoS0RFKSBib290c3RyYXAgZXhjbHVzaXZlbHkgd2hlbiByZWZlcnJpbmcgdG8gdGhlIGJvb3RzdHJhcCBkaXN0cmJ1dGlvbi4NCg0KVGhlIHR3byBtYWpvciBzYW1wbGluZyBkaXN0cmlidXRpb25zIHVzZWQgYWJvdmUgZm9yIHRoZSBzYW1wbGUgbWVhbiBpbmNsdWRlZCBib290c3RyYXAgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGZvciAkXG11X3tsbn0kIGFuZCBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbi4gQm90aCBkaXN0cmlidXRpb25zIGFyZSB1c2VkIHRvIGVzdGltYXRlIHRoZSBiZWhhdmlvciBvZiBhIGRpc3RyaWJ1dGlvbiBhbmQgZXN0aW1hdGlvbnMgZm9yIHBvcHVsYXRpb24gcGFyYW1ldGVycy4NCg0KDQpUaGUgYm9vdHN0cmFwcGluZyBkaXN0cmlidXRpb24gaXMgYW4gZW1waXJpY2FsIGVzdGltYXRpb24gb2YgdGhlICRcbXVfe0xOfSQgcGFyYW1ldGVyIGJ5IHRha2luZyByZXBlYXRlZCByYW5kb20gc2FtcGxlcyBmcm9tIHRoZSBvcmlnaW5hbCB3ZWxsIHNhbXBsZSBhbmQgcmVwZWF0ZWRseSBjYWxjdWxhdGluZyBhIG1lYW4gZnJvbSBlYWNoIHNhbXBsZS4gQWxsIG9mIHRoZSBib290c3RyYXBwZWQgc2FtcGxlcyBhcmUgdGhlbiBtZWFuZWQgdG8gcmVhY2ggYW4gJFxtdSQgZXN0aW1hdG9yLiBUaGlzIGlzIGEgc2ltdWxhdGVkIGFwcHJvYWNoIHRvIHRoZSBNTEUgJFxoYXRcbXVfe0xOfSQuIEFzIHRoZSBib290c3RyYXAgcmVzYW1wbGluZyBtZXRob2QgaXMgYW4gaW5kaXJlY3Qgd2F5IHRvIGNhbGN1bGF0ZSBhbmQgZXN0aW1hdG9yLCBhcyBpbiB0aGUgY29sbGVjdGVkIGRpc3RyaWJ1dGlvbiBpcyBub3QgYXNzZXNzZWQgc29sZXkgd2l0aGluIHRoZSBzaW5nbGUgY29sbGVjdGVkIGRpc3RyaWJ1dGlvbiBidXQgdGhlIGVzdGltYXRvciBpcyBjYWxjdWxhdGVkIG92ZXIgdGhlIGVzdGltYXRvciBvdmVyIG9mIGNvbGxlY3Rpb24gb2YgcmVzYW1wbGVzIGZyb20gdGhlIG9yaWdpbmFsbHkgY29sbGVjdGVkIGRpc3RyaWJ1dGlvbi4gUmVwZWF0YWJseSByZXNhbXBsaW5nIGFuZCBjYWxjdWxhdGluZyByYW5kb20gYm9vdHN0cmFwIHZhcmlhYmxlcyB0byB1bHRpbWF0ZWx5IGNhbGN1bGF0ZSB0aGUgcmFuZG9tIHZhcmlhYmxlIGVzdGltYXRvciBvZiBpbnRlcmVzdCwgJFxoYXRcbXVfe0xOfSQuDQoNCldlIHNlZSB0aGUgcmVsYXRpb25zaGlwIGluIHRoZSBGaWd1cmUgYWJvdmUgKGxhc3QgZmlndXJlIGluIHF1ZXN0aW9uIDMuNCkgdGhlIGJvb3RzdHJhcCBnYXVzc2lhbiBrZXJuZWwgZGVuc2l0eSBoYXMgYSBiZXR0ZXIgZml0IHRvIHRoZSBtYXhpbWEgYW5kIG1pbmltdW1zIG9mIHRoZSBkaXN0cmlidXRpb24sIHdoaWxlIHRoZSBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbiB1bmRlciBwZXJmb3JtcyBpbiBhc3N1bWluZyB0aGUgc2hhcGUgZm9yIHRoZSBtb3N0IG9jY3VycmluZyBkZW5zaXR5IGF0ICRcaGF0XG11X3tMTn0kIGFuZCBoYXMgZmF0dGVyIHRhaWxzIHRoYW4gdGhlIGJvb3RzdHJhcCBLREUsIHN1Z2dlc3RpbmcgYSB3ZWFrZXIgZml0IHRoYW4gdGhlIEtERSBib290c3RyYXAuDQoNClRoZSBtb3JlIHRoZSBib290c3RyYXAgaXMgc2FtcGxlZCwgaXQgY2FuIGJlIGFzc3VtZWQgdGhlIGJvb3RzdHJhcCBlc3RpbWF0b3IgcmVhY2hlcyBjbG9zZXIgdG8gdGhlIHRydWUgZXN0aW1hdG9yLiBJbiBleGFtaW5pbmcgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYSBrZXJuZWwgYW5kIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uLCB0aGUgYm9vdHN0cmFwIGtlcm5lbCBkZW5zaXR5IGJlc3Qgc3VpdHMgdGhlIGVtcGlyaWNhbCBkYXRhIHJhdGhlciB0aGFuIGFzc3VtaW5nIG5vcm1hbGl0eSB3aXRoIGEgbGFyZ2Ugc2FtcGxlIHNpemUgdG8gbWV0IGFuIGFwcHJveGltYXRpb24gZm9yIHRoZSBhc3ltcHRvdGljIGRpc3RyaWJ1dGlvbi4gQXMgdGhlIGJlc3Qgc3VpdGVkIG5vcm1hbCBkaXN0cmlidXRpb24gaXMgYXNzaWduZWQgdG8gdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIGluIGl0cyBwYXJhbWV0cmljIGFwcHJvYWNoIGluIGFwcHJveGltYXRpb24gcmF0aGVyIHRoYW4gZml0dGluZyBmb3IgdGhlIGRhdGEgZW1waXJpY2FsbHkuIA0KDQpJbiByZWZsZWN0aW9uIGZvciB0aGlzIGxvZ25vcm1hbCBkaXN0cmlidXRpb24gc3BlY2lmaWNhbGx5LCBCb3RoIGRpc3RyaWJ1dGlvbnMgYXJlIHNpbWlsYXIgaW4gc2hhcGUgc2hvd2luZyBhIG5hdHVyYWwgb3JkZXIgcGF0dGVybiBpbiB0aGUgZGF0YSBzZXQsIGluIHdoaWNoIHRoZSBkaXN0cmlidXRpb25zIG1lZXRzIHRoZWlyIHJlc3BlY3RpdmUgY29uZGl0aW9ucy4gQWRkaXRpb25hbGx5LCBib3RoIGRpc3RyaWJ1dGlvbnMgc2hvdyBhIHNpbWlsYXIgdmFsdWUgdG93YXJkcyB0aGUgJFxoYXRcbXVfe0xOfSQsIHRoZSBib290c3RyYXAgYmVpbmcgYHIgZmluYWxfbXVfbG5fTUxFYCBhbmQgdGhlIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIGJlaW5nIGByIG11X2xuX2hhdGAuDQoNClRoZSBib290c3RyYXBwZWQgdmFsdWUgZm9yICRcaGF0XG11X3tMTn0kIGlzIGByIGZpbmFsX211X2xuX01MRWAgd2hpY2ggaXMgdmVyeSBjbG9zZSB0byB0aGUgYXN5bXB0b3RpYyBtZWFuIGF0YHIgbXVfbG5faGF0YC4gT3VyIHR3byBkaXN0cmlidXRpb25zIGNhcHR1cmUgdGhlIHByZWRpY3RlZCAkXGhhdFxtdV97TE59JCBzaW1pbGFybHkgc3VnZ2VzdGluZyBzb21lIHJpZ29yIGluIGJvdGggdGVzdHMuIElmIGEgZGVjaXNpb24gbmVlZHMgdG8gYmUgbWFkZSBhYm91dCB3aGljaCBkaXN0cmlidXRpb24gYmVzdCBzdWl0cyB0aGUgbW9kZWwsIHRoZSBib290c3RyYXAgS0RFIHJlc2FtcGluZyBvZmZlcnMgYSBzdHJvbmdlciBmaXQgdG8gdGhlIGhpc3RvZ3JhbSdzIHJhdyBvciBuYXR1cmFsIGRpc3RyaWJ1dGlvbiBzdWdnZXN0aW5nIHRoZSBNTEUgcGFyYW1ldGVycyBkZXJpdmVkIGZyb20gdGhpcyBkaXN0cmlidXRpb24gbWF5IGhhdmUgbW9yZSByaWdvciB0aGFuIHRoZWlyIGFzeW1wdG90aWMgZGlzdHJpYnV0aW9uIGNvdW50ZXJwYXJ0cywgYWx0aG91Z2ggYWdhaW4sIGJvdGggZGlzdHJpYnV0aW9ucyBmb2xsb3cgdmVyeSBzaW1pbGFyIHBhdHRlcm5zIGFuZCBpbmZvcm1hdGlvbi4gQW55IHNlbGVjdGlvbiBtYWRlIGJldHdlZW4gdGhlIHR3byBkaXN0cmlidXRpb25zLCBzaG91bGQgbm90IHZhcnkgYmV0d2VlbiBlYWNoIG90aGVyIHZlcnkgbXVjaCBieSBleWUgYW5kIGdyYXBoIGFuYWx5c2lzLg0KDQojIDQgQm9udXMgUXVlc3Rpb24NCg0KRGVyaXZlIHRoZSBIZXNzaWFuIG1hdHJpeCBieSBjb21wdXRpbmcgdGhlIHNlY29uZC1vcmRlciBwYXJ0aWFsIGRlcml2YXRpdmVzIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbg0KKHdpdGggcmVzcGVjdCB0byDOvCBhbmQgz4MyKS4gVGhlbiwgdHJhbnNsYXRlIHRoZSBkZXJpdmVkIEhlc3NpYW4gaW50byBhbiBSIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdGhlIE1MRXMgb2YgdGhlIHBhcmFtZXRlcnMgYW5kIHRoZSBkYXRhIGFzIGlucHV0cyBhbmQgcmV0dXJucyB0aGUgSGVzc2lhbiBtYXRyaXguIEZpbmFsbHksIGNvbXBhcmUgeW91ciBhbmFseXRpY2FsbHkgZGVyaXZlZCBIZXNzaWFuIHdpdGggdGhlIG51bWVyaWNhbCBIZXNzaWFuIHJldHVybmVkIGJ5IG9wdGltKCkuDQoNCg0KYGBge3J9DQoNCmRhdGE9IHdlbGxzaXplICNsb2cod2VsbHNpemUpDQpsb2dfbGlrZV93ZWxsc19oZXNzIDwtIGZ1bmN0aW9uKHBhcmFtcywgZGF0YSkgDQogIHsNCiAgbXUgPSBwYXJhbXNbMV0gICAgICAgIyBzaGFwZSBwYXJhbWV0ZXINCiAgc2lnbWFfc3EgPSBwYXJhbXNbMl0gICMgc2NhbGUgcGFyYW1ldGVyDQogIA0KICANCiAgDQpuIDwtIGxlbmd0aChkYXRhKQ0KICBsb2dfbGlrID0gKC1uLzIgKiBsb2coMipwaSkgLSBuLzIgKiBsb2coc2lnbWFfc3EpIC0gc3VtKGxvZyhkYXRhKSkgLSAoMS8oMipzaWdtYV9zcSkpICogc3VtKChsb2coZGF0YSkgLSBtdSleMikpICN3ZSBmbGlwIHNpZ25zIGluIHRoZSBtYXRyaXggcHJvY2Vzcw0KICANCnJldHVybihsb2dfbGlrKQ0KfQ0KDQoNCg0KDQoNCmxvZ19saWtlbGlob29kX2dyYWRpZW50ID0gZnVuY3Rpb24ocGFyYW1zLCBkYXRhKSANCiAgew0KICBtdSA9IHBhcmFtc1sxXQ0KICBzaWdtYV9zcSA9IHBhcmFtc1syXQ0KICBuID0gbGVuZ3RoKGRhdGEpDQojR3JhZGllbnQgZnVuY3Rpb25zDQoNCiAgDQojIFRha2luZyB0aGUgcGFydGlhbCBkZXJpdmF0aXZlIHdpdGggcmVzcGVjdCB0byBtdQ0KIGRfbXUgPC0gKDEvc2lnbWFfc3EpICogc3VtKGxvZyhkYXRhKSAtIG11KQ0KICANCiAgIyBQYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIHNpZ21hX3NxDQogIGRfc2lnbWFfc3EgPC0gLW4vKDIgKiBzaWdtYV9zcSkgKyAoMS8oMiAqIHNpZ21hX3NxXjIpKSAqIHN1bSgobG9nKGRhdGEpIC0gbXUpXjIpDQogIA0KcmV0dXJuKGMoZF9tdSwgZF9zaWdtYV9zcSkpDQp9DQoNCg0KDQphbmFseXRpY2FsX2hlc3NpYW5fZnVuYyA9IGZ1bmN0aW9uKHBhcmFtcywgZGF0YSkgDQogIHsNCiAgbXUgPSBwYXJhbXNbMV0NCiAgc2lnbWFfc3EgPSBwYXJhbXNbMl0NCiAgbiA9IGxlbmd0aChkYXRhKQ0KICANCiNDb21wdXRpbmcgdGhlIHNlY29uZCBkZXJpdmF0aXZlcyBmb3IgbXUgYW5kIHNpZ21hXjINCmQyX211IDwtIC1uIC8gc2lnbWFfc3ENCiAgZDJfc2lnbWFfc3EgPC0gbi8oMiAqIHNpZ21hX3NxXjIpIC0gKDEvc2lnbWFfc3FeMykgKiBzdW0oKGxvZyhkYXRhKSAtIG11KV4yKQ0KICANCiAgZF9tdV9kX3NpZ21hX3NxIDwtIC0oMS9zaWdtYV9zcV4yKSAqIHN1bShsb2coZGF0YSkgLSBtdSkNCiAgDQojIFRoaXMgYW5hbHl0aWNhbGx5IGRlcml2ZWQgbWF0cml4ICAgDQpoZXNzX21hdCA8LSBtYXRyaXgoYyhkMl9tdSwgZF9tdV9kX3NpZ21hX3NxLCBkX211X2Rfc2lnbWFfc3EsIGQyX3NpZ21hX3NxKSxucm93ID0gMiwgYnlyb3cgPSBUUlVFKSAgDQoNCiNyZXR1cm4oYyhkX211LCBkX3NpZ21hX3NxLCBkMl9tdSwgZDJfc2lnbWFfc3EsIGRfbXVfZF9zaWdtYV9zcSkpICAjIFJldHVybiBsb2ctbGlrZWxpaG9vZCAgTk9UIHRoZSBuZWdhdGl2ZSBsb2ctbGlrZWxpaG9vZCBhbmQgZ3JhZGllbnRzDQoNCg0KICByZXR1cm4oaGVzc19tYXQpDQp9DQoNCg0KDQojIEZpbmRpbmcgSW5pdGlhbCBWYWx1ZXMNCiMjIEl0IGlzIGNyaXRpY2FsIHRvIHNlbGVjdCBhcHByb3ByaWF0ZSBpbml0aWFsIHZhbHVlcyB0bw0KIyMgZW5zdXJlIGZhc3QgY29udmVyZ2VuY2UuIEluIGdlbmVyYWwsIHdlIGNhbiB1c2Ugd2hhdGV2ZXINCiMjIG1ldGhvZHMgKHN1Y2ggYXMgTU1FKSB0aGF0IGFyZSBhdmFpbGFibGUgdG8gZ2V0IGFwcHJvcHJpYXRlDQojIyBpbml0aWFsIHZhbHVlcw0KDQoNCiMgVXNpbmcgdGhlIE1MRSBhcyB0aGUgaW5pdGlhbCBwYXJhbWV0ZXIgZXN0aW1hdGVzDQoNCmluaXRpYWxfbXUgPSBtdV9oYXQNCg0KaW5pdGlhbF9zaWdtYV9zcSA9IHNpZ21hX3NxX2hhdA0KDQoNCg0KI21sZV9vcHRpbWl6YXRpb24gPC0gb3B0aW0ocGFyID0gYyhpbml0aWFsX211LGluaXRpYWxfc2lnbWFfc3EpLCBmbiA9IGxvZ19saWtlX3dlbGxzX2hlc3MsIHggPSB3ZWxsc2l6ZSwgaGVzc2lhbiA9IFRSVUUpDQoNCg0KIyBNTEUgdXNpbmcgb3B0aW0oKSB3aXRoIGdyYWRpZW50DQoNCg0KDQptbGVfcmVzdWx0IDwtIG9wdGltKA0KICBwYXIgPSBjKG11X2hhdCwgc2lnbWFfc3FfaGF0KSwgI3N0YXJ0aW5nIHBvaW50IG9mIHRoZSBwcmVkaWN0ZWQgbXUgYW5kIHNpZ21hIGZvciB0aGUgTUxFDQogIGZuID0gbG9nX2xpa2Vfd2VsbHNfaGVzcywgIA0KICBnciA9IGxvZ19saWtlbGlob29kX2dyYWRpZW50LA0KICBkYXRhID0gd2VsbHNpemUsDQogIG1ldGhvZCA9ICJMLUJGR1MtQiIsDQogIGxvd2VyID0gYygtSW5mLCAxZS02KSwNCiAgaGVzc2lhbiA9IFRSVUUsDQogIGNvbnRyb2wgPSBsaXN0KGZuc2NhbGUgPSAtMSkNCikNCg0KDQojIw0KbWxlX3Jlc3VsdA0KDQojQ29tcGFyaW5nIHRoZSBoZXNzaWFuIG1hdHJpY2VzIGRlcml2ZWQgYW5hbHl0aWNhbGx5IGFuZCBvcHRpbSgpDQoNCm51bWVyaWNhbF9oZXNzaWFuICA8LSBtbGVfcmVzdWx0JGhlc3NpYW4NCmFuYWx5dGljYWxfaGVzc2lhbiA8LSBhbmFseXRpY2FsX2hlc3NpYW5fZnVuYyhtbGVfcmVzdWx0JHBhciwgd2VsbHNpemUpDQoNCiMgUHJpbnQgZm9yIHlvdXIgbWlkdGVybSByZXBvcnQNCmNhdCgiLS0tIE51bWVyaWNhbCBIZXNzaWFuIGZyb20gb3B0aW0oKSAtLS1cbiIpDQpwcmludChudW1lcmljYWxfaGVzc2lhbikNCg0KY2F0KCJcbi0tLSBBbmFseXRpY2FsbHkgRGVyaXZlZCBIZXNzaWFuIC0tLVxuIikNCnByaW50KGFuYWx5dGljYWxfaGVzc2lhbikNCg0KYGBgDQpCb3RoIHNob3cgbmVnYXRpdmUgY29ycmVsYXRpb24gYW1vbmcgJFxtdSQgYW5kICRcc2lnbWFeMiQgYW5kIHByZXNlbnQgc2ltaWxhciB2YWx1ZXMuIEJvdGggc2hvdyBzaW1pbGFyaXR5IGluIHRoZWlyIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4gDQog