Question2. The Public Service Answering Point (PSAP) in San Francisco employs \(19\) operators in \(8\)-hour shifts to process \(911\) calls. There are at least \(5\) operators always answering calls. The number of calls processed per operator can be modeled with a Poisson random variable with rate \(\lambda_0 =20\) calls per hour.

Quesion 2 (a) What is the probability an operator can process 20 calls in an hour? Repeat for 30 calls in an hour?

#Answer 2a

#Param
lambda <- 20 #calls per hour

#number of call to calc probabilties

k1 <- 20
k2 <- 30

#probabilities
prob_20 <- dpois(k1, lambda)
prob_30 <- dpois(k2, lambda)

cat("Probability of an operator processing 20 calls in an hour:", prob_20, "\n")
Probability of an operator processing 20 calls in an hour: 0.08883532 
cat("Probability of an operation processing 30 calls in an hour:", prob_30, "\n")
Probability of an operation processing 30 calls in an hour: 0.008343536 

Quesion 2 (b) Given that 240 calls occurred in an hour, what is the probability that the ten operators can process them all assuming they are split equally among the operators?

#Answer 2b
lambda <- 20
expected_calls <- 24 #calls split equally

prob_single_operator <- dpois(expected_calls, lambda)

cat("Probability of a single operator processing 24 calls:", prob_single_operator, "\n")
Probability of a single operator processing 24 calls: 0.05573456 

Quesion 2 (c) Now, If the aggregate call rate per hour \(\lambda_c\) , is measured by \(\lambda_c = 85\) calls per hour, what is the probability of more than \(100\) calls in an hour

#Answer 2c

lambda <- 85
k <- 100

prob_less_100 <- ppois(k, lambda)

prob_more_100 <- 1 - prob_less_100

cat("Probability of more than 100 calls in an hour:", prob_more_100, "\n")
Probability of more than 100 calls in an hour: 0.04934533 

Question 3. For the two random number generator below A and B(don’t forget to add your R code)

- [A] \(Z_i = (9Z_{i-1} + 1) \mod 16\) with \(Z_0 = 5\).

- [B] \(Z_i = (7Z_{i-1} + 3) \mod 32\) with \(Z_0 = 10\),

Quesion 3 (a) Compute \(Z_i\) and \(U_i\) for values of \(i\) until a number is repeated, what is the period of both the generator? Provide your comments about the period of both RGN

Generator A

#Answer 3a

#Initialize parameters Generator A

Z_A <- 5
period_A <- 0

Z_A_values <- c(Z_A)
u_A_values <- c(Z_A / 16)

#Simulate Generator A until number repeated

while(TRUE) {
  Z_A <- (9 * Z_A + 1) %% 16
  period_A <- period_A + 1
  Z_A_values <- c(Z_A_values, Z_A)
  u_A_values <- c(u_A_values, Z_A / 16)
  if (Z_A %in% Z_A_values [-length(Z_A_values)]){
    break
  }
}

cat("Generator A Period:", period_A, "\n")
Generator A Period: 16 

Generator B

#Initialize para Generator B
Z_B <- 10
period_B <- 0
Z_B_values <- c(Z_B)
u_B_values <- c(Z_B / 32)

#Simulate Generator B till number repeated

while (TRUE){
  Z_B <- (7 * Z_B + 3) %% 32
  period_B <- period_B + 1
  Z_B_values <- c(Z_B_values, Z_B)
  u_B_values <- c(u_B_values, Z_B / 32)
  if (Z_B %in% Z_B_values[-length(Z_B_values)]){
    break
  }
}
cat("Generator B Period:", period_B, "\n")
Generator B Period: 8 

Quesion 3 (b) Which of these parameters effect the period of LCG – \(a\), \(b\), \(Z_0\)

#Answer 
cat("Among the parameters of LCG, the multiplier (a) has the most significant effect on the period. The period of an LCG is determined by how many unique values it can generate before repeating. If a is carefully chosen with the modulus it can lead to a longer period to increase the range of possible values the geerator can produce. Howeverm, if is is poorly chosen, the period can be short and repeat numbers.")
Among the parameters of LCG, the multiplier (a) has the most significant effect on the period. The period of an LCG is determined by how many unique values it can generate before repeating. If a is carefully chosen with the modulus it can lead to a longer period to increase the range of possible values the geerator can produce. Howeverm, if is is poorly chosen, the period can be short and repeat numbers.

Quesion 3 (c) For both generators plot a scatter diagram of the Zi values 1 apart. What are your observations from these plots? What do you think about the property of randomness of these generators?

#Answer
#initialize parameters for generator A

Z_A <- 5
period_A <- 0
Z_A_values <- c(Z_A)

#Simulate Generator

while (period_A < 1000) {
  Z_A <- (9 * Z_A + 1) %% 16
  period_A <- period_A + 1
  Z_A_values <- c(Z_A_values, Z_A)
  if (Z_A %in% Z_A_values[-length(Z_A_values)]){
    break
  }
}

#Gen A Scatter Plot

plot(Z_A_values[-length(Z_A_values)], Z_A_values[-1],
     main = "Generator A Scatter Plot",
     xlab = "Z_i", ylab = "Z_(i+1) (i + 1)",
     pch = 19, col = "navyblue"
)

NA
NA
NA
#Initialize parameters

Z_B <- 10
period_B <- 0
Z_B_values <- c(Z_B)

#Simulate Gen B
while (period_B < 1000){
  Z_B <- (7 * Z_B + 3) %% 32
  period_B <- period_B + 1
  Z_B_values <- c(Z_B_values, Z_B)
  if (Z_B %in% Z_B_values[-length(Z_B_values)]){
    break
  }
}

#Gen B Scatterplot

plot(Z_B_values[-length(Z_B_values)], Z_B_values[-1],
     main = "Generator B Scatterplot",
     xlab = "Z_i", ylab= "Z_(i+1) (i+1)",
     pch = 19, col = "magenta")

cat("Generator A exhibits a clear pattern. The values appear to follow a deterministic sequence. There is no apparent randomness.")
Generator A exhibits a clear pattern. The values appear to follow a deterministic sequence. There is no apparent randomness.
cat("Generator B displays a noticeable pattern in its scatterplot. It is somewhat less regular than Generator A. There is still a degree of predicatability.")
Generator B displays a noticeable pattern in its scatterplot. It is somewhat less regular than Generator A. There is still a degree of predicatability.
cat("In both cases, scatterplots suggest that they do not possess the properties of true randomness. They show patterns that can be indicative of the limitations or flaws in their parameter choice.")
In both cases, scatterplots suggest that they do not possess the properties of true randomness. They show patterns that can be indicative of the limitations or flaws in their parameter choice.

Quesion 3 (d) Randomness of default random generator of R – Run runif command to generate 100 random numbers and plot the scatter diagram of these numbers ( values 1 apart) and discuss your observations about randomness of this random generator.

#Answer
#Generate 100 random numbers
random_numbers <- runif(100)

#Scatter plot
plot(1:99, random_numbers[1:99],
     main = "Random Number Plot",
     xlab = "Index", ylab = "Random Value",
     pch = 19, col="green")

cat("The random number generator shows no apparent pattern or structure. The points appear to be distributed randomly across the plot.
#There are no discernible trends or regularities in the distribution of the points.")
The random number generator shows no apparent pattern or structure. The points appear to be distributed randomly across the plot.
#There are no discernible trends or regularities in the distribution of the points.

Quesion 3 (e) Compute the mean value of \(U_i\) across the period

#Answer

mean_UA <- mean(Z_A_values / 16)
cat("Mean value of U_i for Generator A:", mean_UA, "\n")
Mean value of U_i for Generator A: 0.4595588 
mean_UB <- mean(Z_B_values / 32)
cat("Mean value of U_i for Generator B:", mean_UB, "\n")
Mean value of U_i for Generator B: 0.4097222 

Quesion 3 (f) By providing a plot of density (histogram) discuss the uniformity of both of the generators

#Answer

#Gen A Histogram
hist(Z_A_values[-length(Z_A_values)] / 16, breaks = 20, 
     main = "Generator A Histogram",
     xlab = " U_i Value", ylab = "Frequency", col = "blue")

NA
NA
NA
#Generator B Histogram
hist(Z_B_values[-length(Z_B_values)] / 32, breaks = 20,
     main = "Generator B Histogram",
     xlab = "U_i Value", ylab = "Frequency", col = "red")

cat("Complete Uniformity in these histograms is a positive characteristic, as it suggest that the generators are performing well in terms of producing uniformly distributed random values.")
Complete Uniformity in these histograms is a positive characteristic, as it suggest that the generators are performing well in terms of producing uniformly distributed random values.

Question 4. Using the inverse transform method

Question 4.(a) Develop an algorithm for the random variable with cumulative distribution function F(x) below.

\[ F(x) = 1 - e^{-(x/\lambda)^k} \]

where \(x \geq 0\), \(\lambda \geq 0\), and \(k \geq 0\).

# Answer 4a
# This might be hard to print using R - you can write the step in your notebook and then include image here / or you can include as seperate file when upload

# Check if the IRdisplay package is already installed
if (!require(IRdisplay, quietly = TRUE)) {
  # If not installed, install it
  install.packages("IRdisplay")
  
  # Load the IRdisplay library
  library(IRdisplay)
} else {
  # If already installed, just load the library
  library(IRdisplay)
}


# Embed an image
#display_png(file = "example.png")
#Define parameters
lambda_param <- 2.0
k_param <- 1.5

#Generate random sample U from a uniform distribution [0,1]

U <- runif(1)

X <- lambda_param * (-log(1-U))^(1/k_param)

cat("Random Variable X:", X, "\n")
Random Variable X: 0.1124825 

Quesion 4 (b) Use the first three Ui values from part (a) and generator [A] of previous problem to create 3 values from the random variable when, \(\lambda = 1\), \(𝑘 = 5\)

#Answer

lambda_param <- 1
k_param <- 5

U_values <- c(0.1124825 , 0.9622323 , 0.6541394 )

inverse_transformation <- function(U, lambda, k){
  X <- lambda * (-log(1 - U))^(1/k)
  return(X)
}

random_values <- inverse_transformation(U_values, lambda_param, k_param)

cat("Random Generated Values:", random_values, "\n")
Random Generated Values: 0.6536538 1.267876 1.01205 

Quesion 4 (c) sing R generate 10,000 values from your algorithm when = 1 , 𝑘 = 5 and plot a histogram of the density. Discuss what insights you obtain when you look at the plot generated here vs the plot you generated in question 3 (e)

#Answer

#Parameters
lambda_param <- 1
k_param <- 5
num_samples <- 10000

set.seed(42)
U_values <- runif(num_samples)
X_values <- lambda_param * (-log(1 - U_values))^(1/k_param)

hist(X_values, breaks = 30,
     main = "Generated Random Values Histogram",
     xlab = "X Value",
     ylab = "Frequency",
     col = "pink")

cat("In question 4e, I talked about the uniformity of the histogram for Generator A. In this case the histogram represents a different distribution.This pattern indicated that values are concentrated in specific regions and alternate with lower frequency reginons.")
In question 4e, I talked about the uniformity of the histogram for Generator A. In this case the histogram represents a different distribution.This pattern indicated that values are concentrated in specific regions and alternate with lower frequency reginons.

Question 5. Develop a Monte Carlo simulation in R that counts the number of uniform [0,1] random numbers that must be summed to get a sum greater than 1. Run a single simulation with n = 10,000 times and find the mean of the number of counts. Do you think this number looks somewhat familiar. Every student might get slightly different value any ideas why?

#Answer

#number of trials
n <- 10000

#empty vector to store counts
counts <- numeric(n)

#Monte Carlo Sim

for (i in 1:n) {
  sum <- 0
  count <- 0
  
  while (sum <= 1) {
    u <- runif(1) #Generate a uniform number [0, 1]
    sum <- sum + u
    count <- count + 1
  }
  counts[i] <- count
}

#calc mean
mean_count <- mean(counts)

cat("Mean number of random numbers needed to exceed 1:", mean_count, "\n")
Mean number of random numbers needed to exceed 1: 2.733 
cat("The numbers should look somewhat familiar because its closely related to the concept of the expected value or mean of a certain mathematical distribution.")
The numbers should look somewhat familiar because its closely related to the concept of the expected value or mean of a certain mathematical distribution.
cat("Every student may get a slightly different value due to the stochastic nature of random number generation.")
Every student may get a slightly different value due to the stochastic nature of random number generation.

Question 6. For our specific random variable, we know that its PDF is defined by the function \(f(x) = 10x(1-x)\). Utilize the accept-reject algorithm to draw samples from this distribution. Take a look at Lecture 10 slide 8 and 9

#Answer
#Define the target pdf function f(x)

pdf <- function(x) {
  return(10 * x * (1-x))
}

#Define proposal distribution g(x) uniform in 0,1
proposal_pdf <- function(x) {
  return(1)
}

#Set the number of samples wanting to generate
num_samples <- 10000

#Initialize an empty vector
samples <- numeric(num_samples)

#Perform accept-reject

M <- 10 #Upper bound
count <- 0

while (count < num_samples) {
  x <- runif(1)
  u <- runif(1)
  
  #acceptance condition
  if (u <= pdf(x) / (M * proposal_pdf(x))) {
    samples[count + 1] <- x
    count <- count + 1
  }
}

#Display the first few generated samples
head(samples)
[1] 0.6273986 0.2820369 0.5372046 0.7136449
[5] 0.5897641 0.3917895
LS0tDQp0aXRsZTogIiA8Y2VudGVyPjxzcGFuIHN0eWxlPSdjb2xvcjogYmx1ZTsnPiBIb21ld29yayAzIDwvc3Bhbj48L2NlbnRlcj4iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiMgUXVlc3Rpb24gMS4gIENvbnNpZGVyIHRoZSBCaW5vbWlhbCBkaXN0cmlidXRpb24gd2l0aCAkbiA9IDI0JCBhbmQgJHAgPSAuOSQgdGhhdCBpcyB1c2VkIHRvIG1vZGVsIHRoZSBudW1iZXIgb2YgY29ycmVjdGx5IHJlY2VpdmVkIGJpdHMgb24gYSBzYXRlbGxpdGUgbGluayB0aGF0IHRyYW5zbWl0cyBkYXRhIGluICQyNCQtYml0IGJsb2Nrcy4NCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc2lvbiAxIChhKSBQbG90IHRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGZ1bmN0aW9uIGFuZCBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiBmb3IgdGhlIG51bWJlciBvZiBjb3JyZWN0bHkgcmVjZWl2ZWQgYml0czwvc3Bhbj4NCg0KYGBge3J9DQojQW5zd2VyIDFhDQoNCiNwYXJhbWV0ZXJzDQpuIDwtIDI0DQpwIDwtIDAuOQ0KDQojVmFsdWUgZm9yIHJhbmRvbSB2YXINCg0KeCA8LSAwOm4NCg0KI3Byb2IgZGVuc2l0eSBmdW5jDQoNCnBkZl92YWx1ZXMgPC0gZGJpbm9tKHgsIHNpemUgPSBuLCBwcm9iID1wKQ0KDQojY3VtdWxhdGl2ZSBkaXN0cmlidXRpb24gZnVuY3Rpb24NCg0KY2RmX3ZhbHVlcyA8LSBwYmlub20oeCwgc2l6ZSA9IG4sIHByb2IgPSBwKQ0KDQojZGYgZm9yIHBsb3R0aW5nDQpkYXRhIDwtIGRhdGEuZnJhbWUoeCA9IHgsIFBERiA9IHBkZl92YWx1ZXMsIENERiA9IGNkZl92YWx1ZXMpDQoNCiNwbG90IHRoZSBQREYNCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkYXRhLCBhZXMoeCA9eCwgeSA9UERGKSkrDQogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknLCBmaWxsID0gJ3B1cnBsZScsIGFscGhhID0gMC43KSArDQogIGxhYnModGl0bGUgPSAnQmlub21pYWwgRGlzdHJpYnV0aW9uIFBERicsDQogICAgICAgeCA9ICdOdW1iZXIgb2YgY29ycmVjdGx5IHJlY2lldmVkIGJpdHMnLA0KICAgICAgIHkgPSAnUHJvYmFiaWxpdHknKQ0KdGhlbWVfbWluaW1hbCgpDQoNCiNwbG90IHRoZSBDREYNCg0KZ2dwbG90KGRhdGEsIGFlcyh4ID0geCwgeSA9IENERikpKw0KICBnZW9tX3N0ZXAoY29sb3IgPSAiYmx1ZSIpKw0KICBsYWJzKHRpdGxlID0gIkJpbm9taWFsIERpc3RyaWJ1dGlvbiBDREYiLA0KICAgICAgIHggPSAiTnVtYmVyIG9mIGNvcnJlY3RseSByZWNpZXZlZCBiaXRzIiwNCiAgICAgICB5ID0gIkN1bXVsYXRpdmUgUHJvYmFiaWxpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQoNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc2lvbiAxIChiKSBXaGF0IGlzIHRoZSBtZWFuIG51bWJlciBvZiBjb3JyZWN0bHkgcmVjZWl2ZWQgYml0cz8gV2hhdCBpcyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uPzwvc3Bhbj4NCmBgYHtyfQ0KI0Fuc3dlciAxYg0KIyhtYWtlIHN1cmUgdGhhdCB3aGF0IHlvdSBwcmludCBtYWtlIHNlbnNlIHRvIG1lKSAtIGZvciBleGFtcGxlIHRvIHByaW50IG1lYW4geW91IGNhbiB1c2UgY2F0IGNvbW1hbmQgb25jZSB5b3UgZG9uZSB3aXRoIHRoZSBjYWxjdWxhdGlvbiBhbmQgaGF2ZSB2YWx1ZSBpbiB0aGUgdmFyaWFibGUNCiN2YXJpYWJsZV9uYW1lPTEwIA0KI2NhdCgiTWVhbiBudW1iZXIgb2YgY29ycmVjdGx5IHJlY2VpdmVkIGJpdHMgIiwgIHZhcmlhYmxlX25hbWUpDQoNCiNwYXJhbQ0KbiA8LSAyNA0KcCA8LSAwLjkNCg0KI0NhbGN1bGF0ZSBtZWFuDQptZWFuIDwtIG4gKiBwDQoNCiNjYWxjdWxhdGUgc3RkDQoNCnN0ZF9kZXYgPC0gc3FydChuICogcCAqKDEtcCkpDQoNCiNwcmludCByZXN1bHRzDQpjYXQoIk1lYW4gbnVtYmVyIG9mIGNvcnJlY3RseSByZWNpZXZlZCBiaXRzOiAiLCBtZWFuLCAiXG4iKQ0KY2F0KCJTdGFuZGFyZCBEZXZpYXRpb246ICIsIHN0ZF9kZXYsICJcbiIpDQoNCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDEgKGMpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIG1vcmUgdGhhbiAkMyQtYml0IGVycm9ycyBpbiB0aGUgYmxvY2sgb2YgJDI0JD88L3NwYW4+DQpgYGB7cn0NCiNBbnN3ZXIgMWMNCg0KI3BhcmFtDQpuIDwgLTI0DQpwIDwtIDAuMSAjcHJvYiBvZiBzaW5nbGUgYml0IGVycm9yDQoNCiNjYWxjdWxhdGUgcHJvYiBvZiAwLCAxLCAyLCBhbmQgMyBiaXQgZXJyb3INCg0KcHJvYl9sZXNzXzQgPC0gc3VtKGRiaW5vbSgwOjMsIHNpemUgPSBuLCBwcm9iID0gcCkpDQoNCiNQcm9iIG9mIG1vcmUgdGhhbiAzIGJpdCBlcnJvcg0KDQpwcm9iX21vcmVfMyA8LSAxIC0gcHJvYl9sZXNzXzQNCg0KY2F0KCJQcm9iYWJpbGl0eSBvZiBtb3JlIHRoYW4gMy1iaXQgZXJyb3IgaW4gdGhlIGJsb2NrIG9mIDI0OiAiLCBwcm9iX21vcmVfMywgIlxuIikNCg0KDQoNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDEgKGQpIFdoYXQgaXMgdGhlIG1lZGlhbiBvZiB0aGlzIGRpc3RyaWJ1dGlvbj8gV2hhdCBjYW4geW91IGludGVycHJldCBmcm9tIHRoZSBtZWRpYW4gdmFsdWU/IDwvc3Bhbj4NCmBgYHtyfQ0KI0Fuc3dlciAxZA0KI3BhcmFtDQpuIDwtIDI0DQpwIDwtIDAuOQ0KDQojQ2FsY3VsYXRlIHRoZSBtZWRpYW4NCg0KbWVkaWFuX3ZhbCA8LSBmbG9vcihuICogcCArIDEvMikNCg0KY2F0KCJNZWRpYW4gb2YgdGhlIGRpc3RyaWJ1dGlvbjoiLCBtZWRpYW5fdmFsLCAiXG4iKQ0KDQpjYXQoIlRoZSBtZWRpYW4gY2FuIHJlcHJlc2VudCB0aGUgbWlkZGxlIHZhbHVlIGluIHRoZSBkaXN0cmlidXRpb24gd2hlbiB0aGUgZGF0YSBpcyBhcnJyYW5nZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBUaGUgbWVkaWFuIG9mIHRoZSBkaXN0cmlidXRpb24gdGVsbHMgdGhlIG51bWJlciBvZiBjb3JyZWN0bHkgcmVjaWV2ZWQgYml0cyBhdCB3aGljaCB0aGVyZSBpcyBhbiBlcXVhbCBjaGFuY2Ugb2YgaGF2aW5nIG1vcmUgb3IgZmV3ZXIgY29ycmVjdGx5IHJlY2lldmVkIGJpdHMuIikNCg0KDQoNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDEgKGUpICBXaGF0IGlzIHRoZSA2MHRoIHF1YW50aWxlIG9mIHRoaXMgZGlzdHJpYnV0aW9uPyBXaGF0IGNhbiB5b3UgaW50ZXJwcmV0IGZyb20gdGhpcyB2YWx1ZT88L3NwYW4+DQpgYGB7cn0NCiNBbnN3ZXIgMWUNCm4gPC0gMjQNCnAgPC0gMC45DQoNCnF1YW50aWxlX3BlcmNlbnQgPC0gMC42MA0KDQpxdWFudGlsZV92YWwgPC0gcWJpbm9tKHF1YW50aWxlX3BlcmNlbnQsIHNpemUgPSBuLCBwcm9iID0gcCwgbG93ZXIudGFpbCA9IFRSVUUpDQoNCmNhdCgiNjB0aCBxdWFudGlsZSBvZiB0aGUgZGlzdHJpYnV0aW9uOiAiLCBxdWFudGlsZV92YWwsICJcbiIpDQoNCiNJbnRlcnByZXRhdGlvbg0KY2F0KCJJdCByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgY29ycmVjdGx5IHJlY2lldmVkIGJpdHMgYmVsb3cgd2hpY2ggNjAlIG9mIHRoZSBkYXRhIGJsb2NrcyBmYWxsLiBCYXNlZCBvbiB0aGUgZ2l2ZW4gcGFyYW1ldGVycywgNjAlIG9mIHRoZSB0aW1lLCBpdCBjYW4gYmUgZXhwZWN0ZWQgdG8gaGF2ZSB0aGlzIG1hbnkgb3IgZmV3ZXIgY29ycmVjdGx5IHJlY2lldmVkIGJpdHMgaW4gYSBibG9jayIpDQoNCmBgYA0KDQojIFF1ZXN0aW9uMi4gVGhlIFB1YmxpYyBTZXJ2aWNlIEFuc3dlcmluZyBQb2ludCAoUFNBUCkgaW4gU2FuIEZyYW5jaXNjbyBlbXBsb3lzICQxOSQgb3BlcmF0b3JzIGluICQ4JC1ob3VyIHNoaWZ0cyB0byBwcm9jZXNzICQ5MTEkIGNhbGxzLiBUaGVyZSBhcmUgYXQgbGVhc3QgJDUkIG9wZXJhdG9ycyBhbHdheXMgYW5zd2VyaW5nIGNhbGxzLiBUaGUgbnVtYmVyIG9mIGNhbGxzIHByb2Nlc3NlZCBwZXIgb3BlcmF0b3IgY2FuIGJlIG1vZGVsZWQgd2l0aCBhIFBvaXNzb24gcmFuZG9tIHZhcmlhYmxlIHdpdGggcmF0ZSAkXGxhbWJkYV8wID0yMCQgY2FsbHMgcGVyIGhvdXIuDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDIgKGEpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IGFuIG9wZXJhdG9yIGNhbiBwcm9jZXNzIDIwIGNhbGxzIGluIGFuIGhvdXI/IFJlcGVhdCBmb3IgMzAgY2FsbHMgaW4gYW4gaG91cj8gPC9zcGFuPg0KYGBge3J9DQojQW5zd2VyIDJhDQoNCiNQYXJhbQ0KbGFtYmRhIDwtIDIwICNjYWxscyBwZXIgaG91cg0KDQojbnVtYmVyIG9mIGNhbGwgdG8gY2FsYyBwcm9iYWJpbHRpZXMNCg0KazEgPC0gMjANCmsyIDwtIDMwDQoNCiNwcm9iYWJpbGl0aWVzDQpwcm9iXzIwIDwtIGRwb2lzKGsxLCBsYW1iZGEpDQpwcm9iXzMwIDwtIGRwb2lzKGsyLCBsYW1iZGEpDQoNCmNhdCgiUHJvYmFiaWxpdHkgb2YgYW4gb3BlcmF0b3IgcHJvY2Vzc2luZyAyMCBjYWxscyBpbiBhbiBob3VyOiIsIHByb2JfMjAsICJcbiIpDQpjYXQoIlByb2JhYmlsaXR5IG9mIGFuIG9wZXJhdGlvbiBwcm9jZXNzaW5nIDMwIGNhbGxzIGluIGFuIGhvdXI6IiwgcHJvYl8zMCwgIlxuIikNCg0KDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc2lvbiAyIChiKSBHaXZlbiB0aGF0IDI0MCBjYWxscyBvY2N1cnJlZCBpbiBhbiBob3VyLCB3aGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSB0ZW4gb3BlcmF0b3JzIGNhbiBwcm9jZXNzIHRoZW0gYWxsIGFzc3VtaW5nIHRoZXkgYXJlIHNwbGl0IGVxdWFsbHkgYW1vbmcgdGhlIG9wZXJhdG9ycz88L3NwYW4+DQpgYGB7cn0NCiNBbnN3ZXIgMmINCmxhbWJkYSA8LSAyMA0KZXhwZWN0ZWRfY2FsbHMgPC0gMjQgI2NhbGxzIHNwbGl0IGVxdWFsbHkNCg0KcHJvYl9zaW5nbGVfb3BlcmF0b3IgPC0gZHBvaXMoZXhwZWN0ZWRfY2FsbHMsIGxhbWJkYSkNCg0KY2F0KCJQcm9iYWJpbGl0eSBvZiBhIHNpbmdsZSBvcGVyYXRvciBwcm9jZXNzaW5nIDI0IGNhbGxzOiIsIHByb2Jfc2luZ2xlX29wZXJhdG9yLCAiXG4iKQ0KDQoNCg0KYGBgDQoNCg0KIyMjIDxzcGFuIHN0eWxlPSdjb2xvcjogZ3JleTsnPlF1ZXNpb24gMiAoYykgTm93LCBJZiB0aGUgYWdncmVnYXRlIGNhbGwgcmF0ZSBwZXIgaG91ciAkXGxhbWJkYV9jJCAsIGlzIG1lYXN1cmVkIGJ5ICRcbGFtYmRhX2MgPSA4NSQgY2FsbHMgcGVyIGhvdXIsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IG9mIG1vcmUgdGhhbiAkMTAwJCBjYWxscyBpbiBhbiBob3VyPC9zcGFuPg0KYGBge3J9DQojQW5zd2VyIDJjDQoNCmxhbWJkYSA8LSA4NQ0KayA8LSAxMDANCg0KcHJvYl9sZXNzXzEwMCA8LSBwcG9pcyhrLCBsYW1iZGEpDQoNCnByb2JfbW9yZV8xMDAgPC0gMSAtIHByb2JfbGVzc18xMDANCg0KY2F0KCJQcm9iYWJpbGl0eSBvZiBtb3JlIHRoYW4gMTAwIGNhbGxzIGluIGFuIGhvdXI6IiwgcHJvYl9tb3JlXzEwMCwgIlxuIikNCg0KDQpgYGANCg0KIyBRdWVzdGlvbiAzLiBGb3IgdGhlIHR3byByYW5kb20gbnVtYmVyIGdlbmVyYXRvciBiZWxvdyBBIGFuZCBCKGRvbuKAmXQgZm9yZ2V0IHRvIGFkZCB5b3VyIFIgY29kZSkNCiMjIyAtIFtBXSBcKFpfaSA9ICg5Wl97aS0xfSArIDEpIFxtb2QgMTZcKSB3aXRoIFwoWl8wID0gNVwpLg0KIyMjIC0gW0JdIFwoWl9pID0gKDdaX3tpLTF9ICsgMykgXG1vZCAzMlwpIHdpdGggXChaXzAgPSAxMFwpLA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDMgKGEpIENvbXB1dGUgJFpfaSQgYW5kICRVX2kkIGZvciB2YWx1ZXMgb2YgJGkkIHVudGlsIGEgbnVtYmVyIGlzIHJlcGVhdGVkLCB3aGF0IGlzIHRoZSBwZXJpb2Qgb2YgYm90aCB0aGUgZ2VuZXJhdG9yPyBQcm92aWRlIHlvdXIgY29tbWVudHMgYWJvdXQgdGhlIHBlcmlvZCBvZiBib3RoIFJHTiA8L3NwYW4+DQoNCkdlbmVyYXRvciBBDQpgYGB7cn0NCiNBbnN3ZXIgM2ENCg0KI0luaXRpYWxpemUgcGFyYW1ldGVycyBHZW5lcmF0b3IgQQ0KDQpaX0EgPC0gNQ0KcGVyaW9kX0EgPC0gMA0KDQpaX0FfdmFsdWVzIDwtIGMoWl9BKQ0KdV9BX3ZhbHVlcyA8LSBjKFpfQSAvIDE2KQ0KDQojU2ltdWxhdGUgR2VuZXJhdG9yIEEgdW50aWwgbnVtYmVyIHJlcGVhdGVkDQoNCndoaWxlKFRSVUUpIHsNCiAgWl9BIDwtICg5ICogWl9BICsgMSkgJSUgMTYNCiAgcGVyaW9kX0EgPC0gcGVyaW9kX0EgKyAxDQogIFpfQV92YWx1ZXMgPC0gYyhaX0FfdmFsdWVzLCBaX0EpDQogIHVfQV92YWx1ZXMgPC0gYyh1X0FfdmFsdWVzLCBaX0EgLyAxNikNCiAgaWYgKFpfQSAlaW4lIFpfQV92YWx1ZXMgWy1sZW5ndGgoWl9BX3ZhbHVlcyldKXsNCiAgICBicmVhaw0KICB9DQp9DQoNCmNhdCgiR2VuZXJhdG9yIEEgUGVyaW9kOiIsIHBlcmlvZF9BLCAiXG4iKQ0KDQoNCmBgYA0KR2VuZXJhdG9yIEINCmBgYHtyfQ0KI0luaXRpYWxpemUgcGFyYSBHZW5lcmF0b3IgQg0KWl9CIDwtIDEwDQpwZXJpb2RfQiA8LSAwDQpaX0JfdmFsdWVzIDwtIGMoWl9CKQ0KdV9CX3ZhbHVlcyA8LSBjKFpfQiAvIDMyKQ0KDQojU2ltdWxhdGUgR2VuZXJhdG9yIEIgdGlsbCBudW1iZXIgcmVwZWF0ZWQNCg0Kd2hpbGUgKFRSVUUpew0KICBaX0IgPC0gKDcgKiBaX0IgKyAzKSAlJSAzMg0KICBwZXJpb2RfQiA8LSBwZXJpb2RfQiArIDENCiAgWl9CX3ZhbHVlcyA8LSBjKFpfQl92YWx1ZXMsIFpfQikNCiAgdV9CX3ZhbHVlcyA8LSBjKHVfQl92YWx1ZXMsIFpfQiAvIDMyKQ0KICBpZiAoWl9CICVpbiUgWl9CX3ZhbHVlc1stbGVuZ3RoKFpfQl92YWx1ZXMpXSl7DQogICAgYnJlYWsNCiAgfQ0KfQ0KY2F0KCJHZW5lcmF0b3IgQiBQZXJpb2Q6IiwgcGVyaW9kX0IsICJcbiIpDQoNCg0KDQoNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDMgKGIpIFdoaWNoIG9mIHRoZXNlIHBhcmFtZXRlcnMgZWZmZWN0IHRoZSBwZXJpb2Qgb2YgTENHIOKAkyAkYSQsICRiJCwgJFpfMCQgPC9zcGFuPg0KYGBge3J9DQojQW5zd2VyIA0KY2F0KCJBbW9uZyB0aGUgcGFyYW1ldGVycyBvZiBMQ0csIHRoZSBtdWx0aXBsaWVyIChhKSBoYXMgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIHRoZSBwZXJpb2QuIFRoZSBwZXJpb2Qgb2YgYW4gTENHIGlzIGRldGVybWluZWQgYnkgaG93IG1hbnkgdW5pcXVlIHZhbHVlcyBpdCBjYW4gZ2VuZXJhdGUgYmVmb3JlIHJlcGVhdGluZy4gSWYgYSBpcyBjYXJlZnVsbHkgY2hvc2VuIHdpdGggdGhlIG1vZHVsdXMgaXQgY2FuIGxlYWQgdG8gYSBsb25nZXIgcGVyaW9kIHRvIGluY3JlYXNlIHRoZSByYW5nZSBvZiBwb3NzaWJsZSB2YWx1ZXMgdGhlIGdlZXJhdG9yIGNhbiBwcm9kdWNlLiBIb3dldmVybSwgaWYgaXMgaXMgcG9vcmx5IGNob3NlbiwgdGhlIHBlcmlvZCBjYW4gYmUgc2hvcnQgYW5kIHJlcGVhdCBudW1iZXJzLiIpDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc2lvbiAzIChjKSBGb3IgYm90aCBnZW5lcmF0b3JzIHBsb3QgYSBzY2F0dGVyIGRpYWdyYW0gb2YgdGhlIFppIHZhbHVlcyAxIGFwYXJ0LiBXaGF0IGFyZSB5b3VyIG9ic2VydmF0aW9ucyBmcm9tIHRoZXNlIHBsb3RzPyBXaGF0IGRvIHlvdSB0aGluayBhYm91dCB0aGUgcHJvcGVydHkgb2YgcmFuZG9tbmVzcyBvZiB0aGVzZSBnZW5lcmF0b3JzPyA8L3NwYW4+DQpgYGB7cn0NCiNBbnN3ZXINCiNpbml0aWFsaXplIHBhcmFtZXRlcnMgZm9yIGdlbmVyYXRvciBBDQoNClpfQSA8LSA1DQpwZXJpb2RfQSA8LSAwDQpaX0FfdmFsdWVzIDwtIGMoWl9BKQ0KDQojU2ltdWxhdGUgR2VuZXJhdG9yDQoNCndoaWxlIChwZXJpb2RfQSA8IDEwMDApIHsNCiAgWl9BIDwtICg5ICogWl9BICsgMSkgJSUgMTYNCiAgcGVyaW9kX0EgPC0gcGVyaW9kX0EgKyAxDQogIFpfQV92YWx1ZXMgPC0gYyhaX0FfdmFsdWVzLCBaX0EpDQogIGlmIChaX0EgJWluJSBaX0FfdmFsdWVzWy1sZW5ndGgoWl9BX3ZhbHVlcyldKXsNCiAgICBicmVhaw0KICB9DQp9DQoNCiNHZW4gQSBTY2F0dGVyIFBsb3QNCg0KcGxvdChaX0FfdmFsdWVzWy1sZW5ndGgoWl9BX3ZhbHVlcyldLCBaX0FfdmFsdWVzWy0xXSwNCiAgICAgbWFpbiA9ICJHZW5lcmF0b3IgQSBTY2F0dGVyIFBsb3QiLA0KICAgICB4bGFiID0gIlpfaSIsIHlsYWIgPSAiWl8oaSsxKSAoaSArIDEpIiwNCiAgICAgcGNoID0gMTksIGNvbCA9ICJuYXZ5Ymx1ZSINCikNCg0KDQoNCmBgYA0KDQpgYGB7cn0NCiNJbml0aWFsaXplIHBhcmFtZXRlcnMNCg0KWl9CIDwtIDEwDQpwZXJpb2RfQiA8LSAwDQpaX0JfdmFsdWVzIDwtIGMoWl9CKQ0KDQojU2ltdWxhdGUgR2VuIEINCndoaWxlIChwZXJpb2RfQiA8IDEwMDApew0KICBaX0IgPC0gKDcgKiBaX0IgKyAzKSAlJSAzMg0KICBwZXJpb2RfQiA8LSBwZXJpb2RfQiArIDENCiAgWl9CX3ZhbHVlcyA8LSBjKFpfQl92YWx1ZXMsIFpfQikNCiAgaWYgKFpfQiAlaW4lIFpfQl92YWx1ZXNbLWxlbmd0aChaX0JfdmFsdWVzKV0pew0KICAgIGJyZWFrDQogIH0NCn0NCg0KI0dlbiBCIFNjYXR0ZXJwbG90DQoNCnBsb3QoWl9CX3ZhbHVlc1stbGVuZ3RoKFpfQl92YWx1ZXMpXSwgWl9CX3ZhbHVlc1stMV0sDQogICAgIG1haW4gPSAiR2VuZXJhdG9yIEIgU2NhdHRlcnBsb3QiLA0KICAgICB4bGFiID0gIlpfaSIsIHlsYWI9ICJaXyhpKzEpIChpKzEpIiwNCiAgICAgcGNoID0gMTksIGNvbCA9ICJtYWdlbnRhIikNCmBgYA0KDQoNCmBgYHtyfQ0KY2F0KCJHZW5lcmF0b3IgQSBleGhpYml0cyBhIGNsZWFyIHBhdHRlcm4uIFRoZSB2YWx1ZXMgYXBwZWFyIHRvIGZvbGxvdyBhIGRldGVybWluaXN0aWMgc2VxdWVuY2UuIFRoZXJlIGlzIG5vIGFwcGFyZW50IHJhbmRvbW5lc3MuIikNCg0KY2F0KCJHZW5lcmF0b3IgQiBkaXNwbGF5cyBhIG5vdGljZWFibGUgcGF0dGVybiBpbiBpdHMgc2NhdHRlcnBsb3QuIEl0IGlzIHNvbWV3aGF0IGxlc3MgcmVndWxhciB0aGFuIEdlbmVyYXRvciBBLiBUaGVyZSBpcyBzdGlsbCBhIGRlZ3JlZSBvZiBwcmVkaWNhdGFiaWxpdHkuIikNCg0KY2F0KCJJbiBib3RoIGNhc2VzLCBzY2F0dGVycGxvdHMgc3VnZ2VzdCB0aGF0IHRoZXkgZG8gbm90IHBvc3Nlc3MgdGhlIHByb3BlcnRpZXMgb2YgdHJ1ZSByYW5kb21uZXNzLiBUaGV5IHNob3cgcGF0dGVybnMgdGhhdCBjYW4gYmUgaW5kaWNhdGl2ZSBvZiB0aGUgbGltaXRhdGlvbnMgb3IgZmxhd3MgaW4gdGhlaXIgcGFyYW1ldGVyIGNob2ljZS4iKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDMgKGQpIFJhbmRvbW5lc3Mgb2YgZGVmYXVsdCByYW5kb20gZ2VuZXJhdG9yIG9mIFIg4oCTIFJ1biBydW5pZiBjb21tYW5kIHRvIGdlbmVyYXRlIDEwMCByYW5kb20gbnVtYmVycyBhbmQgcGxvdCB0aGUgc2NhdHRlciBkaWFncmFtIG9mIHRoZXNlIG51bWJlcnMgKCB2YWx1ZXMgMSBhcGFydCkgYW5kIGRpc2N1c3MgeW91ciBvYnNlcnZhdGlvbnMgYWJvdXQgcmFuZG9tbmVzcyBvZiB0aGlzIHJhbmRvbSBnZW5lcmF0b3IuIDwvc3Bhbj4NCmBgYHtyfQ0KI0Fuc3dlcg0KI0dlbmVyYXRlIDEwMCByYW5kb20gbnVtYmVycw0KcmFuZG9tX251bWJlcnMgPC0gcnVuaWYoMTAwKQ0KDQojU2NhdHRlciBwbG90DQpwbG90KDE6OTksIHJhbmRvbV9udW1iZXJzWzE6OTldLA0KICAgICBtYWluID0gIlJhbmRvbSBOdW1iZXIgUGxvdCIsDQogICAgIHhsYWIgPSAiSW5kZXgiLCB5bGFiID0gIlJhbmRvbSBWYWx1ZSIsDQogICAgIHBjaCA9IDE5LCBjb2w9ImdyZWVuIikNCmBgYA0KYGBge3J9DQpjYXQoIlRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvciBzaG93cyBubyBhcHBhcmVudCBwYXR0ZXJuIG9yIHN0cnVjdHVyZS4gVGhlIHBvaW50cyBhcHBlYXIgdG8gYmUgZGlzdHJpYnV0ZWQgcmFuZG9tbHkgYWNyb3NzIHRoZSBwbG90Lg0KI1RoZXJlIGFyZSBubyBkaXNjZXJuaWJsZSB0cmVuZHMgb3IgcmVndWxhcml0aWVzIGluIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHBvaW50cy4iKQ0KYGBgDQoNCg0KIyMjIDxzcGFuIHN0eWxlPSdjb2xvcjogZ3JleTsnPlF1ZXNpb24gMyAoZSkgQ29tcHV0ZSB0aGUgbWVhbiB2YWx1ZSBvZiAkVV9pJCBhY3Jvc3MgdGhlIHBlcmlvZDwvc3Bhbj4NCmBgYHtyfQ0KI0Fuc3dlcg0KDQptZWFuX1VBIDwtIG1lYW4oWl9BX3ZhbHVlcyAvIDE2KQ0KY2F0KCJNZWFuIHZhbHVlIG9mIFVfaSBmb3IgR2VuZXJhdG9yIEE6IiwgbWVhbl9VQSwgIlxuIikNCg0KbWVhbl9VQiA8LSBtZWFuKFpfQl92YWx1ZXMgLyAzMikNCmNhdCgiTWVhbiB2YWx1ZSBvZiBVX2kgZm9yIEdlbmVyYXRvciBCOiIsIG1lYW5fVUIsICJcbiIpDQoNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDMgKGYpIEJ5IHByb3ZpZGluZyBhIHBsb3Qgb2YgZGVuc2l0eSAoaGlzdG9ncmFtKSBkaXNjdXNzIHRoZSB1bmlmb3JtaXR5IG9mIGJvdGggb2YgdGhlIGdlbmVyYXRvcnMgPC9zcGFuPg0KYGBge3J9DQojQW5zd2VyDQoNCiNHZW4gQSBIaXN0b2dyYW0NCmhpc3QoWl9BX3ZhbHVlc1stbGVuZ3RoKFpfQV92YWx1ZXMpXSAvIDE2LCBicmVha3MgPSAyMCwgDQogICAgIG1haW4gPSAiR2VuZXJhdG9yIEEgSGlzdG9ncmFtIiwNCiAgICAgeGxhYiA9ICIgVV9pIFZhbHVlIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAiYmx1ZSIpDQoNCg0KDQpgYGANCmBgYHtyfQ0KI0dlbmVyYXRvciBCIEhpc3RvZ3JhbQ0KaGlzdChaX0JfdmFsdWVzWy1sZW5ndGgoWl9CX3ZhbHVlcyldIC8gMzIsIGJyZWFrcyA9IDIwLA0KICAgICBtYWluID0gIkdlbmVyYXRvciBCIEhpc3RvZ3JhbSIsDQogICAgIHhsYWIgPSAiVV9pIFZhbHVlIiwgeWxhYiA9ICJGcmVxdWVuY3kiLCBjb2wgPSAicmVkIikNCmBgYA0KDQpgYGB7cn0NCmNhdCgiQ29tcGxldGUgVW5pZm9ybWl0eSBpbiB0aGVzZSBoaXN0b2dyYW1zIGlzIGEgcG9zaXRpdmUgY2hhcmFjdGVyaXN0aWMsIGFzIGl0IHN1Z2dlc3QgdGhhdCB0aGUgZ2VuZXJhdG9ycyBhcmUgcGVyZm9ybWluZyB3ZWxsIGluIHRlcm1zIG9mIHByb2R1Y2luZyB1bmlmb3JtbHkgZGlzdHJpYnV0ZWQgcmFuZG9tIHZhbHVlcy4iKQ0KYGBgDQoNCiMgUXVlc3Rpb24gNC4gVXNpbmcgdGhlIGludmVyc2UgdHJhbnNmb3JtIG1ldGhvZA0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc3Rpb24gNC4oYSkgRGV2ZWxvcCBhbiBhbGdvcml0aG0gZm9yIHRoZSByYW5kb20gdmFyaWFibGUgd2l0aCBjdW11bGF0aXZlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiBGKHgpIGJlbG93Ljwvc3Bhbj4NCg0KXFsgRih4KSA9IDEgLSBlXnstKHgvXGxhbWJkYSlea30gXF0NCg0Kd2hlcmUgXCggeCBcZ2VxIDAgXCksIFwoIFxsYW1iZGEgXGdlcSAwIFwpLCBhbmQgXCggayBcZ2VxIDAgXCkuDQoNCmBgYHtyfQ0KIyBBbnN3ZXIgNGENCiMgVGhpcyBtaWdodCBiZSBoYXJkIHRvIHByaW50IHVzaW5nIFIgLSB5b3UgY2FuIHdyaXRlIHRoZSBzdGVwIGluIHlvdXIgbm90ZWJvb2sgYW5kIHRoZW4gaW5jbHVkZSBpbWFnZSBoZXJlIC8gb3IgeW91IGNhbiBpbmNsdWRlIGFzIHNlcGVyYXRlIGZpbGUgd2hlbiB1cGxvYWQNCg0KIyBDaGVjayBpZiB0aGUgSVJkaXNwbGF5IHBhY2thZ2UgaXMgYWxyZWFkeSBpbnN0YWxsZWQNCmlmICghcmVxdWlyZShJUmRpc3BsYXksIHF1aWV0bHkgPSBUUlVFKSkgew0KICAjIElmIG5vdCBpbnN0YWxsZWQsIGluc3RhbGwgaXQNCiAgaW5zdGFsbC5wYWNrYWdlcygiSVJkaXNwbGF5IikNCiAgDQogICMgTG9hZCB0aGUgSVJkaXNwbGF5IGxpYnJhcnkNCiAgbGlicmFyeShJUmRpc3BsYXkpDQp9IGVsc2Ugew0KICAjIElmIGFscmVhZHkgaW5zdGFsbGVkLCBqdXN0IGxvYWQgdGhlIGxpYnJhcnkNCiAgbGlicmFyeShJUmRpc3BsYXkpDQp9DQoNCg0KIyBFbWJlZCBhbiBpbWFnZQ0KI2Rpc3BsYXlfcG5nKGZpbGUgPSAiZXhhbXBsZS5wbmciKQ0KDQoNCmBgYA0KYGBge3J9DQojRGVmaW5lIHBhcmFtZXRlcnMNCmxhbWJkYV9wYXJhbSA8LSAyLjANCmtfcGFyYW0gPC0gMS41DQoNCiNHZW5lcmF0ZSByYW5kb20gc2FtcGxlIFUgZnJvbSBhIHVuaWZvcm0gZGlzdHJpYnV0aW9uIFswLDFdDQoNClUgPC0gcnVuaWYoMSkNCg0KWCA8LSBsYW1iZGFfcGFyYW0gKiAoLWxvZygxLVUpKV4oMS9rX3BhcmFtKQ0KDQpjYXQoIlJhbmRvbSBWYXJpYWJsZSBYOiIsIFgsICJcbiIpDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9J2NvbG9yOiBncmV5Oyc+UXVlc2lvbiA0IChiKSBVc2UgdGhlIGZpcnN0IHRocmVlIFVpIHZhbHVlcyBmcm9tIHBhcnQgKGEpIGFuZCBnZW5lcmF0b3IgW0FdIG9mIHByZXZpb3VzIHByb2JsZW0gdG8gY3JlYXRlIDMgdmFsdWVzIGZyb20gdGhlIHJhbmRvbSB2YXJpYWJsZSB3aGVuLCAkXGxhbWJkYSA9IDEkLCAk8J2RmCA9IDUkPC9zcGFuPg0KYGBge3J9DQojQW5zd2VyDQoNCmxhbWJkYV9wYXJhbSA8LSAxDQprX3BhcmFtIDwtIDUNCg0KVV92YWx1ZXMgPC0gYygwLjExMjQ4MjUgLCAwLjk2MjIzMjMgLCAwLjY1NDEzOTQgKQ0KDQppbnZlcnNlX3RyYW5zZm9ybWF0aW9uIDwtIGZ1bmN0aW9uKFUsIGxhbWJkYSwgayl7DQogIFggPC0gbGFtYmRhICogKC1sb2coMSAtIFUpKV4oMS9rKQ0KICByZXR1cm4oWCkNCn0NCg0KcmFuZG9tX3ZhbHVlcyA8LSBpbnZlcnNlX3RyYW5zZm9ybWF0aW9uKFVfdmFsdWVzLCBsYW1iZGFfcGFyYW0sIGtfcGFyYW0pDQoNCmNhdCgiUmFuZG9tIEdlbmVyYXRlZCBWYWx1ZXM6IiwgcmFuZG9tX3ZhbHVlcywgIlxuIikNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0nY29sb3I6IGdyZXk7Jz5RdWVzaW9uIDQgKGMpIHNpbmcgUiBnZW5lcmF0ZSAxMCwwMDAgdmFsdWVzIGZyb20geW91ciBhbGdvcml0aG0gd2hlbiAgXGxhbWJkYSA9IDEgLCDwnZGYID0gNSAgYW5kIHBsb3QgYSBoaXN0b2dyYW0gb2YgdGhlIGRlbnNpdHkuIERpc2N1c3Mgd2hhdCBpbnNpZ2h0cyB5b3Ugb2J0YWluIHdoZW4geW91IGxvb2sgYXQgdGhlIHBsb3QgZ2VuZXJhdGVkIGhlcmUgdnMgdGhlIHBsb3QgeW91IGdlbmVyYXRlZCBpbiBxdWVzdGlvbiAzIChlKSA8L3NwYW4+DQpgYGB7cn0NCiNBbnN3ZXINCg0KI1BhcmFtZXRlcnMNCmxhbWJkYV9wYXJhbSA8LSAxDQprX3BhcmFtIDwtIDUNCm51bV9zYW1wbGVzIDwtIDEwMDAwDQoNCnNldC5zZWVkKDQyKQ0KVV92YWx1ZXMgPC0gcnVuaWYobnVtX3NhbXBsZXMpDQpYX3ZhbHVlcyA8LSBsYW1iZGFfcGFyYW0gKiAoLWxvZygxIC0gVV92YWx1ZXMpKV4oMS9rX3BhcmFtKQ0KDQpoaXN0KFhfdmFsdWVzLCBicmVha3MgPSAzMCwNCiAgICAgbWFpbiA9ICJHZW5lcmF0ZWQgUmFuZG9tIFZhbHVlcyBIaXN0b2dyYW0iLA0KICAgICB4bGFiID0gIlggVmFsdWUiLA0KICAgICB5bGFiID0gIkZyZXF1ZW5jeSIsDQogICAgIGNvbCA9ICJwaW5rIikNCg0KYGBgDQpgYGB7cn0NCmNhdCgiSW4gcXVlc3Rpb24gNGUsIEkgdGFsa2VkIGFib3V0IHRoZSB1bmlmb3JtaXR5IG9mIHRoZSBoaXN0b2dyYW0gZm9yIEdlbmVyYXRvciBBLiBJbiB0aGlzIGNhc2UgdGhlIGhpc3RvZ3JhbSByZXByZXNlbnRzIGEgZGlmZmVyZW50IGRpc3RyaWJ1dGlvbi5UaGlzIHBhdHRlcm4gaW5kaWNhdGVkIHRoYXQgdmFsdWVzIGFyZSBjb25jZW50cmF0ZWQgaW4gc3BlY2lmaWMgcmVnaW9ucyBhbmQgYWx0ZXJuYXRlIHdpdGggbG93ZXIgZnJlcXVlbmN5IHJlZ2lub25zLiIpDQpgYGANCg0KIyBRdWVzdGlvbiA1LiBEZXZlbG9wIGEgTW9udGUgQ2FybG8gc2ltdWxhdGlvbiBpbiBSIHRoYXQgY291bnRzIHRoZSBudW1iZXIgb2YgdW5pZm9ybSBbMCwxXSByYW5kb20gbnVtYmVycyB0aGF0IG11c3QgYmUgc3VtbWVkIHRvIGdldCBhIHN1bSBncmVhdGVyIHRoYW4gMS4gUnVuIGEgc2luZ2xlIHNpbXVsYXRpb24gd2l0aCBuID0gMTAsMDAwIHRpbWVzIGFuZCBmaW5kIHRoZSBtZWFuIG9mIHRoZSBudW1iZXIgb2YgY291bnRzLiBEbyB5b3UgdGhpbmsgdGhpcyBudW1iZXIgbG9va3Mgc29tZXdoYXQgZmFtaWxpYXIuIEV2ZXJ5IHN0dWRlbnQgbWlnaHQgZ2V0IHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZSBhbnkgaWRlYXMgd2h5Pw0KYGBge3J9DQojQW5zd2VyDQoNCiNudW1iZXIgb2YgdHJpYWxzDQpuIDwtIDEwMDAwDQoNCiNlbXB0eSB2ZWN0b3IgdG8gc3RvcmUgY291bnRzDQpjb3VudHMgPC0gbnVtZXJpYyhuKQ0KDQojTW9udGUgQ2FybG8gU2ltDQoNCmZvciAoaSBpbiAxOm4pIHsNCiAgc3VtIDwtIDANCiAgY291bnQgPC0gMA0KICANCiAgd2hpbGUgKHN1bSA8PSAxKSB7DQogICAgdSA8LSBydW5pZigxKSAjR2VuZXJhdGUgYSB1bmlmb3JtIG51bWJlciBbMCwgMV0NCiAgICBzdW0gPC0gc3VtICsgdQ0KICAgIGNvdW50IDwtIGNvdW50ICsgMQ0KICB9DQogIGNvdW50c1tpXSA8LSBjb3VudA0KfQ0KDQojY2FsYyBtZWFuDQptZWFuX2NvdW50IDwtIG1lYW4oY291bnRzKQ0KDQpjYXQoIk1lYW4gbnVtYmVyIG9mIHJhbmRvbSBudW1iZXJzIG5lZWRlZCB0byBleGNlZWQgMToiLCBtZWFuX2NvdW50LCAiXG4iKQ0KDQpjYXQoIlRoZSBudW1iZXJzIHNob3VsZCBsb29rIHNvbWV3aGF0IGZhbWlsaWFyIGJlY2F1c2UgaXRzIGNsb3NlbHkgcmVsYXRlZCB0byB0aGUgY29uY2VwdCBvZiB0aGUgZXhwZWN0ZWQgdmFsdWUgb3IgbWVhbiBvZiBhIGNlcnRhaW4gbWF0aGVtYXRpY2FsIGRpc3RyaWJ1dGlvbi4iKQ0KDQpjYXQoIkV2ZXJ5IHN0dWRlbnQgbWF5IGdldCBhIHNsaWdodGx5IGRpZmZlcmVudCB2YWx1ZSBkdWUgdG8gdGhlIHN0b2NoYXN0aWMgbmF0dXJlIG9mIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbi4iKQ0KDQpgYGANCg0KIyBRdWVzdGlvbiA2LiBGb3Igb3VyIHNwZWNpZmljIHJhbmRvbSB2YXJpYWJsZSwgd2Uga25vdyB0aGF0IGl0cyBQREYgaXMgZGVmaW5lZCBieSB0aGUgZnVuY3Rpb24gJGYoeCkgPSAxMHgoMS14KSQuIFV0aWxpemUgdGhlIGFjY2VwdC1yZWplY3QgYWxnb3JpdGhtIHRvIGRyYXcgc2FtcGxlcyBmcm9tIHRoaXMgZGlzdHJpYnV0aW9uLiBUYWtlIGEgbG9vayBhdCBMZWN0dXJlIDEwIHNsaWRlIDggYW5kIDkNCg0KYGBge3J9DQojQW5zd2VyDQojRGVmaW5lIHRoZSB0YXJnZXQgcGRmIGZ1bmN0aW9uIGYoeCkNCg0KcGRmIDwtIGZ1bmN0aW9uKHgpIHsNCiAgcmV0dXJuKDEwICogeCAqICgxLXgpKQ0KfQ0KDQojRGVmaW5lIHByb3Bvc2FsIGRpc3RyaWJ1dGlvbiBnKHgpIHVuaWZvcm0gaW4gMCwxDQpwcm9wb3NhbF9wZGYgPC0gZnVuY3Rpb24oeCkgew0KICByZXR1cm4oMSkNCn0NCg0KI1NldCB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgd2FudGluZyB0byBnZW5lcmF0ZQ0KbnVtX3NhbXBsZXMgPC0gMTAwMDANCg0KI0luaXRpYWxpemUgYW4gZW1wdHkgdmVjdG9yDQpzYW1wbGVzIDwtIG51bWVyaWMobnVtX3NhbXBsZXMpDQoNCiNQZXJmb3JtIGFjY2VwdC1yZWplY3QNCg0KTSA8LSAxMCAjVXBwZXIgYm91bmQNCmNvdW50IDwtIDANCg0Kd2hpbGUgKGNvdW50IDwgbnVtX3NhbXBsZXMpIHsNCiAgeCA8LSBydW5pZigxKQ0KICB1IDwtIHJ1bmlmKDEpDQogIA0KICAjYWNjZXB0YW5jZSBjb25kaXRpb24NCiAgaWYgKHUgPD0gcGRmKHgpIC8gKE0gKiBwcm9wb3NhbF9wZGYoeCkpKSB7DQogICAgc2FtcGxlc1tjb3VudCArIDFdIDwtIHgNCiAgICBjb3VudCA8LSBjb3VudCArIDENCiAgfQ0KfQ0KDQojRGlzcGxheSB0aGUgZmlyc3QgZmV3IGdlbmVyYXRlZCBzYW1wbGVzDQpoZWFkKHNhbXBsZXMpDQoNCg0KYGBgDQoNCg==