1. PROBLEM SOLVING PART
Problem 1 (5 pts) - similar to Pr. 5 / page 238 in
text A box contains 30 consecutive balls numbered 1 to 30. If
four numbers are drawn at random, how many ways are there for the
largest number to be 19 and the smallest number to be 9?
Use the Fundamental Principle of Counting!
Solution: 36
YOUR CODE HERE:
#largest number to be 19 and the smallest number to be 9? Mutually Independent Events. 1 - 30 not needed. Exclude 9 and 19 itself. 10 - 18
between9and19 <- 10:18
#Total ways to choose 2 numbered balls within range
totalWays <- choose(length(between9and19), 2)
# Print the result
print(totalWays)
[1] 36
Problem 2 (5 pts) - similar to Pr. 14 / page 239 in
text On a multiple-choice exam with four
possible answers for each of the five questions, what is the probability
that a student would get four or more correct answers just by
guessing?
Hint: Use the fact that \(P(E ∩ F) = P(E) ·
P(F)\) for two independent event (generalized for more than
events) Getting one answer correct is independent of another.
Also
\[P(\text{at least } 4) = P(\text{exactly
} 4) + P(\text{exactly } 5)\]
the last events are mutually exclusive so \(P(A \cup B) = P(A) + P(B)\)
YOUR CODE HERE:
# 4 possible answers
# 5 Questions
# Goal: Probability of 4 or 5 questions correct (each question again 4 possible answers, // each Q having 1/4 or 25% chance to be correct)
#Total Questions
q <- 5
# Each question has 1/2 or 25% chance to be correct
eachQuestionRight <- .25
# 4 correct answers only
FourCorrect <- dbinom(4, size = q, prob = eachQuestionRight)
# 5 correct answers only
FiveCorrect <- dbinom(5, size = q, prob = eachQuestionRight)
# Probability of 4 correct answers plus 5 correct answers
FourORFiveCorrect <- FourCorrect + FiveCorrect
print(FourORFiveCorrect)
[1] 0.015625
# Extrapolate to 200 students
print(FourORFiveCorrect * 200)
[1] 3.125
Out of 200 students who adopt this test taking approach how many are
expected to get at least 4 correct? Hint: Use Binomial
experiment settings to answer this questions.
Solution: 3.125 / 3 of the students would get at least 4
correct answers of the 5 questions on the multiple-choice
exam
Problem 3 (5 pts) (IND-OPT) - similar to Pr. 44 page 243 in
text Consider tossing four fair coins. There
are 16 possible outcomes, e.g HHHH,HHHT,HHTH,HTHH,THHH, ...
possible outcomes. Define X as the random variable “number
of heads showing when four coins are tossed.” Obtain the mean and the
variance of X. Simulate tossing four fair coins 10,000 times. Compute
the simulated mean and variance of X. Are the simulated values within 2%
of the theoretical answers?
Hint: To find the theoretical values use
dbinom (x= , size = , prob = )
Solution: No, neither the theoretical mean and variance are
within are within 2% of the simulated mean and variance
YOUR CODE HERE:
library(MASS)
set.seed(007) #Random seed for the rbinom simulations
# Flipping a single/fair coin (1st input - number of draws, 2nd input - number of coins, 3rd input - probability of coin / e.g. 50% or .5)
rbinom(1, 1, .5)
[1] 1
# Flipping 4 fair coins
rbinom(1, 4, .5)
[1] 2
# Flipping 4 fair coins 10,000 times, set to coinflipsX var (Where X is the number of heads showing when 4 coins are tossed)
coinflipsX <- rbinom(10000, 4, .5)
# Simulated mean of coinflipsX
simulated_mean <- mean(coinflipsX)
# Simulated variance of coinflipsX
simulated_variance <- var(coinflipsX)
# theoretical values dbinom (x= 1, size = 16 possible outcomes, prob = .02 / 2%)
dbinom_mean <- (dbinom (x = 2, size = 16, prob = 0.02))
dbinom_variance <- (dbinom (x = 1, size = 16, prob = 0.02))
# Check if theoretical value of dbinom_mean is less than or equal to .02% of simulated_mean
simulated_versus_theoretical_mean <- abs(simulated_mean - dbinom_mean) / dbinom_mean <= 0.02
# Check if theoretical value of dbinom_variance is less than or equal to .02% of simulated_variance
simulated_versus_theoretical_variance <- abs(simulated_variance - dbinom_variance) / dbinom_variance <= 0.02
print(simulated_mean)
[1] 2.0028
print(simulated_variance)
[1] 1.009493
print(simulated_versus_theoretical_mean)
[1] FALSE
print(simulated_versus_theoretical_variance)
[1] FALSE
Problem 4 (10 pts) - similar to Pr. 11 / page 307 in
text
Traffic volume is an important factor for determining the most
cost-effective method to surface a road. Suppose that the average number
of vehicles passing a certain point on a road is 5 every 60 seconds.
- Find the probability that more than 12 cars will pass the point in a
period of 3 minutes.
- What is the probability that more than 100 cars pass the point in
half an hour?
Hint: Adjust the Poisson parameter \(\lambda = 5\) every 60 seconds to
# per every 3 minutes
(a): 0.8152482 (b): 0.9999941
# Avg # of vehicles passing a certain point on a road is 5 every 60 seconds.
# (a) more than 12 cars will pass the point in a period of 3 minutes (3 sets of 60 seconds, or 3 sets of 5 cars / 15 cars MAX)
# 11 as min non-inclusive (to get 12+)
aProbability <- 1 - ppois(11, 15)
# (b) more than 100 cars pass the point in half an hour (30 sets of 60 seconds, or 30 sets of 5 cars / 150 cars MAX)
# 99 as min non-inclusive (to get100+)
bProbability <- 1 - ppois(99, 150)
list(AProbability = aProbability, bProbability = bProbability)
$AProbability
[1] 0.8152482
$bProbability
[1] 0.9999941
Problem 5 (10 pts) - similar to Pr. 18 / page 308 in
text Suppose the percentage of drinks sold from a vending
machine are 70% and 30% for soft drinks and bottled water,
respectively.
- What is the probability that on a randomly selected day, the first
soft drink is the fourth drink sold?
- Find the probability that exactly 4 out of 10 drinks sold is a soft
drink.
Hint: Let X = number of waters (failures) purchased
before the first soft drink is purchased. Then, \(X \sim Geo(0.70)\).
(a): 0.0189 (b): 0.03675691
YOUR CODE HERE::
# Randomly selected day, the first soft drink is the fourth drink sold?
SDPercent <- 0.70
first_SD_fourth_sold_drink <- (1 - SDPercent)^3 * SDPercent
# Result
print(first_SD_fourth_sold_drink)
[1] 0.0189
- Let
X = number of soft drinks sold. Then, \(X \sim Bin(10, 0.70)\) and \(P(X = 1) = 0\) since one has:
SDPercent <- 0.70
# Exactly 4 out of 10 drinks sold is a soft drink
total_drinks <- 10
target_drinks_SD <- 4
#Exactly 4 of 10 drinks as soft drinks
four_of_ten_SD <- choose(total_drinks, target_drinks_SD) * SDPercent^target_drinks_SD * (1 - SDPercent)^(total_drinks - target_drinks_SD)
print(prob_exactly_4_soft_drinks)
[1] 0.03675691
Problem 6 (10 pts) - Exponential Distribution: Light
Bulbs If the life of a certain type of light bulb has an
exponential distribution with a mean of 10 months, find
- The probability that a randomly selected light bulb lasts between 6
and 15 months.
- The 95th percentile of the distribution. How the probability of the
light bulb to last more than 36 months compare to
0.05?
- The probability that a light bulb that has lasted for 10 months will
last more than 25 months.
(a): 0.3256815 (b): 0.02732372 & it
meets comparison to .05 (c): 0.2231302
YOUR CODE HERE:
expDist_Ten_Months <- 1/10 # Exponential distribution with mean of 10 months
# (a) - randomly selected light bulb lasts between 6 and 15 months (15 mo. pexp - 6 mo. pexp)
Six_to_Fifteen <- pexp(15, rate = expDist_Ten_Months) - pexp(6, rate = expDist_Ten_Months)
print(Six_to_Fifteen)
[1] 0.3256815
# (b) - 95th percentile. Probability of the light bulb to last 36 months+ compare to `0.05`?
Percentile_95th <- qexp(0.95, rate = expDist_Ten_Months)
over_36 <- pexp(36, rate = expDist_Ten_Months, lower.tail = FALSE)
print(over_36)
[1] 0.02732372
comparison_to_.05 <- over_36 < 0.05
print(comparison_to_.05)
[1] TRUE
# (c) - Probability that a light bulb that has lasted for 10 months will last 25 months+
Ten_months_last_25_months_plus <- pexp(15, rate = expDist_Ten_Months, lower.tail = FALSE)
print(Ten_months_last_25_months_plus)
[1] 0.2231302
Problem 7 (10 pts) (IND-OPT) - Pr. 8 page 400 A
population has the following elements: 2, 5, 8, 12, 13 (finite
population).
Enumerate all the samples of size 2 that can be drawn with and
without replacement. (Hint: Use the srs() function from the
PASWR2 package)
Calculate the mean of the population.
Calculate the variance of the population.
Calculate the standard deviation of the population.
Calculate the mean of the sample mean, \(E[X]\).
Calculate the variance of the sampled mean, \(Var(\bar X)\)
Calculate the standard deviation of the sample mean.
Calculate the mean of the sample variance, \(E[S^2]\)
Is the variance of \(\bar X\)
larger when sampling with or without replacement? Explain your
answer
Solution:
YOUR CODE HERE:
#individual optional
Problem 8 (10 pts) - similar to Pr. 10 / page 400 in
text
Use the data frame WHEATUSA2004 from the
PASWR2 package; draw all samples of sizes 4, 5, and 6; and
calculate the mean of the means for the variable acres (wheat surface
area measured in thousands of acres). . What size provides the best
approximation to the population mean? What is the variance of these
means?
Hint: Use the srs() function from the
PASWR2 package to draw simple random samples.
YOUR CODE HERE:
#refrencing sampling distributions exercises line 206
library(PASWR2)
# Sample Size 4:
SRS4 <- srs(WHEATUSA2004$acres, 4)
xbarSRS4 <- apply(SRS4, 1, mean) # MEAN
c(mean(xbarSRS4), var(xbarSRS4)) # MEAN & VARIANCE
[1] 1148.733 645755.872
# Sample Size 5:
SRS5 <- srs(WHEATUSA2004$acres, 5)
xbarSRS5 <- apply(SRS5, 1, mean) # MEAN
c(mean(xbarSRS5), var(xbarSRS5)) # MEAN & VARIANCE
[1] 1148.733 496720.646
# Sample Size 6:
SRS6 <- srs(WHEATUSA2004$acres, 6)
xbarSRS6 <- apply(SRS6, 1, mean) # MEAN
c(mean(xbarSRS6), var(xbarSRS6)) # MEAN & VARIANCE
[1] 1148.733 397374.397
Solution: Sample Size 6 has the smallest variance of
397374.397 (compared to Sample size 4’s 645755.872 and Sample size 5’s
496720.646
Problem 9 (10 pts) - Pr. 16 / page 513 in text
A group of engineers working with physicians in a research hospital
is developing a new device to measure blood glucose levels. Based on
measurements taken from patients in a previous study, the physicians
assert that the new device provides blood glucose levels slightly higher
than those provided by the old device. To corroborate their suspicion,
15 diabetic patients were randomly selected, and their
blood glucose levels were measured with both the new and the old
devices. The measurements, in mg/100 ml, appear in data
frame GLUCOSE from the PASWR2 package:
- Are the samples independent? Why or why not?
- If the blood glucose level is a normally distributed random
variable, compute a 95% confidence interval for the mean differences of
the population.
- Use the results in (b) to decide whether or not the two devices give
the same results.
Solution:
The samples are not independent. The patients each have both
measurements obtained from old device as well as their newer device. The
statistics are dependent on each other
The 95% confidence level interval for the mean differences of the
population is −16.3614 to −12.7586.
YOUR CODE HERE:
GLUCOSE <- GLUCOSE %>% mutate(DIFF = old-new) # create variable DIFF for the difference between old and new level
head(GLUCOSE)
ggplot(data = GLUCOSE, aes(sample = DIFF)) +
stat_qq() +
theme_bw()

CI <- t.test(GLUCOSE$DIFF)$conf # use t-test since the sample size is small < 30
CI
[1] -16.36145 -12.75855
attr(,"conf.level")
[1] 0.95
The 95% confidence interval for the mean differences of the
population is [−16.3614,−12.7586].
- The confidence interval suggests that on average, the new device
reports higher blood glucose levels than the old device.
Problem 10 (10 pts) (IND-OPT) - similar to Pr. 9 / page 511
in text
A large company wants to estimate the proportion of its accounts that
are paid on time.
How large a sample is needed to estimate the true proportion
within 2% with a 95% confidence level?
Suppose 700 out of 800 accounts are paid on time. Construct 95%
confidence intervals for the true proportion of accounts that are paid
on time using an asymptotic confidence interval, an Agresti Coull
confidence interval.
Hint: Use the nsize() and binom.confint()
from the library(binom)
Solution:
YOUR CODE HERE:
library(binom)
library(binom)
#(a)
#(b)
#individual optional
Problem 11 (10 pts) - Pr. 10 / page 511 in text
In a study conducted at Appalachian State
University, students used digital oral thermometers to record
their temperatures each day they came to class. A randomly selected day
of student temperatures is provided in the following table and in the
data frame STATTEMPS. Information is also provided with
regard to subject gender and the hour of the day when the students’
temperatures were measured.
Direction: load the data with data(STATTEMPS) having the
library(PASWR2) loaded.
Hint: Use
t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)
the x ad y values are given with formula
expression formula = temperature ~ gender. Then use the
$ access to obtain the confidence interval:
CI <- t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)$conf
Construct a 95% confidence interval for the true average
temperature difference between females and males. Does the interval
contain the value zero? What does this suggest about gender temperature
differences?
Construct a 95% confidence interval for the true average
temperature difference between students taking their temperatures at 8
a.m. and students taking their temperatures at 9 a.m. Give a reason why
one group appears to have a higher temperature reading.
Solution:
YOUR CODE HERE:
library(PASWR2)
data(STATTEMPS)
#(a) 95% confidence interval for the true average temperature difference between females and males
t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)
Error in t.test.formula(temperature ~ gender, data = STATTEMPS, mu = 0, :
cannot use 'paired' in formula method
A 95% confidence interval for the true average
difference between students taking their temperatures at 8
a.m. and students taking their temperatures at 9 a.m. is
[−2.4965,−0.2564]. Note that this interval does not contain
0, indicating that the there is evidence to suggest
students in the 8 a.m. class have temperatures that are not
as warm as the 9 a.m. class. One possible explanation is
that students roll straight out of bed and into the 8 a.m.
class. Consequently, their temperatures are closer to their sleeping
temperatures which are lower than their waking temperatures.
3. BOOTSTRAP ESTIMATION PART
Review the problem below.
Pr. 30 / page 695 in text
The “Wisconsin Card Sorting Test” is widely used by psychiatrists,
neurologists, and neuropsychologists with patients who have a brain
injury, neurodegenerative disease, or a mental illness such as
schizophrenia. Patients with any sort of frontal lobe lesion generally
do poorly on the test. The data frame WCST and the
following table contain the test scores from a group of 50 patients from
the Virgen del Camino Hospital (Pamplona, Spain).
Use the function eda() from the PASWR2
package to explore the data and decide if normality can be assumed. For
details type in console ?eda
What assumption(s) must be made to compute a 95%
confidence interval for the population mean?
Compute the confidence interval from (b).
Compute a 95% BCa bootstrap confidence interval for the mean test
score.
Should you use the confidence interval reported in (c) or the
confidence interval reported in (d)?
Solution:
- Assuming the variable score has a normal distribution is not
reasonable.
See the results of EDA analysis below:
data(WCST)
WCST %>% pull(score) %>% eda()
Size (n) Missing Minimum 1st Qu Mean Median TrMean 3rd Qu Max Stdev Var SE Mean I.Q.R. Range Kurtosis
50.000 0.000 4.000 8.500 21.480 17.000 19.413 26.000 94.000 18.406 338.785 2.603 17.500 90.000 4.511
Skewness SW p-val
2.033 0.000

In order to construct a 95% confidence interval for
the population mean, one assumes that the values in the variable score
are taken from a normal distribution. Although this is
not a reasonable assumption, the sample size might be sufficiently large
to overcome the skewness in the parent population. Consequently, one
might appeal to the Central Limit Theorem and claim
that the sampling distribution of X is
approximately normal due to the sample size
(50). In this problem, the skewness is quite severe, and
one should not be overly confident in the final interval.
If we assume normality one has:
# CI <- with(data = WCST, t.test(score)$conf) #
# or using piping
CI <- WCST %>% pull(score) %>% t.test() %>% .$conf
CI
[1] 16.24904 26.71096
attr(,"conf.level")
[1] 0.95
- Use the
boot.ci() nonparametric bootstrap CIs functions
to obtain the bootstrap CI.
library(boot) # use boot package
MEAN <- function(data, i){
d <- data[i]
M <- mean(d)
}
set.seed(13)
B <- 10^4 - 1 # number of bootstrap samples
b.obj <- boot(data = WCST$score, statistic = MEAN, R = B) # bootstrap object of class "boot" containing the output of a bootstrap calculation
CIB <- boot.ci(b.obj, conf = 0.95, type = "bca")
CIB
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 9999 bootstrap replicates
CALL :
boot.ci(boot.out = b.obj, conf = 0.95, type = "bca")
Intervals :
Level BCa
95% (17.26, 27.86 )
Calculations and Intervals on Original Scale
Problem 12 (10 pts) Set the seed to 23
if your group index is odd number (i.e. group 1,3,5,7),
and the seed to 89 if your group index is even number
(i.e. group 2,4,6,8). Draw a random sample of size
200 from exponential distribution with mean \(\lambda = 4\) (\(rate = \frac{1}{4}\)). Produce all
bootstrap CI with the function boot.ci (use type =
“all”).
How many of them contain the true mean for the sampled
distribution?
YOUR CODE HERE:
library(boot)
set.seed(89)
stat.mean = function(x, indx){
mean( x[indx] )
}
exps200 <- rexp(200,.25)
b.obj <- boot(data = exps200, statistic = stat.mean, 200)
CIB <- boot.ci(b.obj, type = "all")
Warning: bootstrap variances needed for studentized intervals
CIB
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 200 bootstrap replicates
CALL :
boot.ci(boot.out = b.obj, type = "all")
Intervals :
Level Normal Basic
95% ( 3.523, 4.685 ) ( 3.509, 4.718 )
Level Percentile BCa
95% ( 3.486, 4.695 ) ( 3.533, 4.732 )
Calculations and Intervals on Original Scale
Some basic intervals may be unstable
Some percentile intervals may be unstable
Some BCa intervals may be unstable
#bootstrap variances needed for studentized intervals warning
EXTRA CREDIT (10 pts) Set the seed to
23 if your group index is odd number (i.e. group
1,3,5,7), and the seed to 89 if your group index
is even number (i.e. group 2,4,6,8).
Draw a random sample of size 25 from \(Bin(20,\frac{1}{5})\). Produce all
bootstrap CI with the function boot.ci (use type =
“all”).
How many of them contain the true mean for the \(Bin(20,\frac{1}{5})\)?
YOUR CODE HERE:
library(boot)
set.seed(89)
stat.mean = function(x, indx){
mean( x[indx] )
}
exps25 <- rexp(20,1/5)
b.obj <- boot(exps25, statistic = stat.mean, 10000)
CIB <- boot.ci(b.obj, type = "all")
Warning: bootstrap variances needed for studentized intervals
CIB
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 10000 bootstrap replicates
CALL :
boot.ci(boot.out = b.obj, type = "all")
Intervals :
Level Normal Basic
95% ( 3.177, 7.148 ) ( 3.056, 6.997 )
Level Percentile BCa
95% ( 3.326, 7.267 ) ( 3.540, 7.663 )
Calculations and Intervals on Original Scale
LS0tDQp0aXRsZTogIlNUQVQyNzAgLSBQcm9qZWN0IDIgLSBDbGFzc2ljYWwgUHJvYmFiaWxpdHkgYW5kIFN0YXRpc3RpY3MgUHJvYmxlbXMgYW5kIEJvb3RzdHJhcCBFc3RpbWF0aW9uIg0KYXV0aG9yOiAiTWFkZWx5biBGaWd1ZXJhcyINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiMjIERpcmVjdGlvbnM6DQoNClN1Ym1pdCB0aGUgcHJvamVjdCBlaXRoZXIgYXMgKiphIGdyb3VwKiogb3IgYXMgYW4gKippbmRpdmlkdWFsIHdvcmsqKi4NCg0KLSAgIFByb2plY3QgY29uc2lzdCBvZiAqKnRocmVlKiogKDMpIHBhcnRzOiAqKjEuKiogUHJvYmxlbXMgU29sdmluZywgKioyLioqIEJyYWluc3Rvcm1pbmcsIGFuZCAqKjMuKiogQm9vdHN0cmFwIGVzdGltYXRpb24uDQoNCi0gICBGb3IgKipncm91cCoqIHByb2plY3QgKipzdWJtaXNpc29uKio6IGNyZWRpdCB3aWxsIGJlIGdpdmVuIHRvIGFsbCBzdHVkZW50cyBsaXN0ZWQgYXMgY29udHJpYnV0b3JzIC0gKiphbGwgbGlzdGVkIHByb2JsZW0qKiBtdXN0IGJlIGNvbXBsZXRlZC4gTWF4aW11bSBzY29yZSAqKjEwMCoqIHB0cyArICoqMTAqKiBwdHMgKEV4dHJhIENyZWRpdCkuDQoNCi0gICBGb3IgKippbmRpdmlkdWFsIHN1Ym1pc3Npb25zKio6IHByb2JsZW1zIGxpc3RlZCB3aXRoIGxhYmVsICoqKElORC1PUFQpKiogKGluZGl2aWR1YWwtb3B0aW9uYWwpIGluIHBhcmVudGhlc2lzICoqYXJlIG5vdCoqIHJlcXVpcmVkIGFuZCBtYXkgYmUgb21pdHRlZC4gRm9yIGEgbWF4aW11bSBzY29yZSAqKjgwKiogcHRzICsgKioxMCBwdHMqKiAoRXh0cmEgQ3JlZGl0KS4NCg0KYGBge3IgcGFja2FnZXMsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KIyBsb2FkIHRoZSBwYWNrYWdlcyBmb3IgZ3JhcGhpbmcgYW5kIGRhdGEgd3JhbmdsaW5nDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFBBU1dSMikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGxhdHRpY2UpDQpsaWJyYXJ5KGJvb3QpDQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KKipOb3RlOioqIElmIHlvdSBgUm1kYCBmaWxlIHN1Ym1pc3Npb24ga25pdHMgeW91IHdpbGwgcmVjZWl2ZSB0b3RhbCBvZiAqKig1IHBvaW50cykqKg0KDQojIyAxLiBQUk9CTEVNIFNPTFZJTkcgUEFSVA0KDQoqKlByb2JsZW0gMSAoNSBwdHMpIC0gc2ltaWxhciB0byBQci4gNSAvIHBhZ2UgMjM4IGluIHRleHQqKiBBIGJveCBjb250YWlucyAzMCBjb25zZWN1dGl2ZSBiYWxscyBudW1iZXJlZCAxIHRvIDMwLiBJZiBmb3VyIG51bWJlcnMgYXJlIGRyYXduIGF0IHJhbmRvbSwgaG93IG1hbnkgd2F5cyBhcmUgdGhlcmUgZm9yIHRoZSBsYXJnZXN0IG51bWJlciB0byBiZSAxOSBhbmQgdGhlIHNtYWxsZXN0IG51bWJlciB0byBiZSA5Pw0KDQpVc2UgdGhlIEZ1bmRhbWVudGFsIFByaW5jaXBsZSBvZiBDb3VudGluZyENCg0KKipTb2x1dGlvbjogMzYqKg0KDQoqKllPVVIgQ09ERSBIRVJFOioqDQoNCmBgYHtyfQ0KI2xhcmdlc3QgbnVtYmVyIHRvIGJlIDE5IGFuZCB0aGUgc21hbGxlc3QgbnVtYmVyIHRvIGJlIDk/IE11dHVhbGx5IEluZGVwZW5kZW50IEV2ZW50cy4gMSAtIDMwIG5vdCBuZWVkZWQuIEV4Y2x1ZGUgOSBhbmQgMTkgaXRzZWxmLiAxMCAtIDE4DQpiZXR3ZWVuOWFuZDE5IDwtIDEwOjE4DQoNCiNUb3RhbCB3YXlzIHRvIGNob29zZSAyIG51bWJlcmVkIGJhbGxzIHdpdGhpbiByYW5nZQ0KdG90YWxXYXlzIDwtIGNob29zZShsZW5ndGgoYmV0d2VlbjlhbmQxOSksIDIpIA0KDQojIFByaW50IHRoZSByZXN1bHQNCnByaW50KHRvdGFsV2F5cykNCg0KYGBgDQoNCioqUHJvYmxlbSAyICg1IHB0cykgLSBzaW1pbGFyIHRvIFByLiAxNCAvIHBhZ2UgMjM5IGluIHRleHQqKiBPbiBhIG11bHRpcGxlLWNob2ljZSBleGFtIHdpdGggKipmb3VyKiogcG9zc2libGUgYW5zd2VycyBmb3IgZWFjaCBvZiB0aGUgZml2ZSBxdWVzdGlvbnMsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBzdHVkZW50IHdvdWxkIGdldCBmb3VyIG9yIG1vcmUgY29ycmVjdCBhbnN3ZXJzIGp1c3QgYnkgZ3Vlc3Npbmc/DQoNCkhpbnQ6IFVzZSB0aGUgZmFjdCB0aGF0ICRQKEUg4oipIEYpID0gUChFKSDCtyBQKEYpJCBmb3IgdHdvIGluZGVwZW5kZW50IGV2ZW50IChnZW5lcmFsaXplZCBmb3IgbW9yZSB0aGFuIGV2ZW50cykgR2V0dGluZyBvbmUgYW5zd2VyIGNvcnJlY3QgaXMgaW5kZXBlbmRlbnQgb2YgYW5vdGhlci4NCg0KQWxzbw0KDQokJFAoXHRleHR7YXQgbGVhc3QgfSA0KSA9IFAoXHRleHR7ZXhhY3RseSB9IDQpICsgUChcdGV4dHtleGFjdGx5IH0gNSkkJA0KDQp0aGUgbGFzdCBldmVudHMgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSBzbyAkUChBIFxjdXAgQikgPSBQKEEpICsgUChCKSQNCg0KKipZT1VSIENPREUgSEVSRToqKg0KDQpgYGB7cn0NCg0KIyA0IHBvc3NpYmxlIGFuc3dlcnMNCiMgNSBRdWVzdGlvbnMNCiMgR29hbDogUHJvYmFiaWxpdHkgb2YgNCBvciA1IHF1ZXN0aW9ucyBjb3JyZWN0IChlYWNoIHF1ZXN0aW9uIGFnYWluIDQgcG9zc2libGUgYW5zd2VycywgLy8gZWFjaCBRIGhhdmluZyAxLzQgb3IgMjUlIGNoYW5jZSB0byBiZSBjb3JyZWN0KQ0KDQojVG90YWwgUXVlc3Rpb25zDQpxIDwtIDUNCg0KIyBFYWNoIHF1ZXN0aW9uIGhhcyAxLzIgb3IgMjUlIGNoYW5jZSB0byBiZSBjb3JyZWN0DQplYWNoUXVlc3Rpb25SaWdodCA8LSAuMjUNCg0KIyA0IGNvcnJlY3QgYW5zd2VycyBvbmx5DQpGb3VyQ29ycmVjdCA8LSBkYmlub20oNCwgc2l6ZSA9IHEsIHByb2IgPSBlYWNoUXVlc3Rpb25SaWdodCkNCg0KIyA1IGNvcnJlY3QgYW5zd2VycyBvbmx5DQpGaXZlQ29ycmVjdCA8LSBkYmlub20oNSwgc2l6ZSA9IHEsIHByb2IgPSBlYWNoUXVlc3Rpb25SaWdodCkNCg0KIyBQcm9iYWJpbGl0eSBvZiA0IGNvcnJlY3QgYW5zd2VycyBwbHVzIDUgY29ycmVjdCBhbnN3ZXJzDQpGb3VyT1JGaXZlQ29ycmVjdCA8LSBGb3VyQ29ycmVjdCArIEZpdmVDb3JyZWN0DQpwcmludChGb3VyT1JGaXZlQ29ycmVjdCkNCg0KIyBFeHRyYXBvbGF0ZSB0byAyMDAgc3R1ZGVudHMNCg0KcHJpbnQoRm91ck9SRml2ZUNvcnJlY3QgKiAyMDApDQoNCmBgYA0KDQpPdXQgb2YgMjAwIHN0dWRlbnRzIHdobyBhZG9wdCB0aGlzIHRlc3QgdGFraW5nIGFwcHJvYWNoIGhvdyBtYW55IGFyZSBleHBlY3RlZCB0byBnZXQgYXQgbGVhc3QgNCBjb3JyZWN0PyAqKkhpbnQ6KiogVXNlIEJpbm9taWFsIGV4cGVyaW1lbnQgc2V0dGluZ3MgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb25zLg0KDQoqKlNvbHV0aW9uOiAzLjEyNSAvIDMgb2YgdGhlIHN0dWRlbnRzIHdvdWxkIGdldCBhdCBsZWFzdCA0IGNvcnJlY3QgYW5zd2VycyBvZiB0aGUgNSBxdWVzdGlvbnMgb24gdGhlIG11bHRpcGxlLWNob2ljZSBleGFtKioNCg0KKipQcm9ibGVtIDMgKDUgcHRzKSAoSU5ELU9QVCkgLSBzaW1pbGFyIHRvIFByLiA0NCBwYWdlIDI0MyBpbiB0ZXh0KiogQ29uc2lkZXIgdG9zc2luZyAqKmZvdXIqKiBmYWlyIGNvaW5zLiBUaGVyZSBhcmUgMTYgcG9zc2libGUgb3V0Y29tZXMsIGUuZyBgSEhISCxISEhULEhIVEgsSFRISCxUSEhILCAuLi5gIHBvc3NpYmxlIG91dGNvbWVzLiBEZWZpbmUgYFhgIGFzIHRoZSByYW5kb20gdmFyaWFibGUgIm51bWJlciBvZiBoZWFkcyBzaG93aW5nIHdoZW4gZm91ciBjb2lucyBhcmUgdG9zc2VkLiIgT2J0YWluIHRoZSBtZWFuIGFuZCB0aGUgdmFyaWFuY2Ugb2YgWC4gU2ltdWxhdGUgdG9zc2luZyBmb3VyIGZhaXIgY29pbnMgMTAsMDAwIHRpbWVzLiBDb21wdXRlIHRoZSBzaW11bGF0ZWQgbWVhbiBhbmQgdmFyaWFuY2Ugb2YgWC4gQXJlIHRoZSBzaW11bGF0ZWQgdmFsdWVzIHdpdGhpbiAyJSBvZiB0aGUgdGhlb3JldGljYWwgYW5zd2Vycz8NCg0KKipIaW50OioqIFRvIGZpbmQgdGhlIHRoZW9yZXRpY2FsIHZhbHVlcyB1c2UgYGRiaW5vbSAoeD0gLCBzaXplID0gLCBwcm9iID0gIClgDQoNCioqU29sdXRpb246IE5vLCBuZWl0aGVyIHRoZSB0aGVvcmV0aWNhbCBtZWFuIGFuZCB2YXJpYW5jZSBhcmUgd2l0aGluIGFyZSB3aXRoaW4gMiUgb2YgdGhlIHNpbXVsYXRlZCBtZWFuIGFuZCB2YXJpYW5jZSoqDQoNCioqWU9VUiBDT0RFIEhFUkU6KioNCg0KYGBge3J9DQpsaWJyYXJ5KE1BU1MpDQpzZXQuc2VlZCgwMDcpICNSYW5kb20gc2VlZCBmb3IgdGhlIHJiaW5vbSBzaW11bGF0aW9ucw0KDQojIEZsaXBwaW5nIGEgc2luZ2xlL2ZhaXIgY29pbiAoMXN0IGlucHV0IC0gbnVtYmVyIG9mIGRyYXdzLCAybmQgaW5wdXQgLSBudW1iZXIgb2YgY29pbnMsIDNyZCBpbnB1dCAtIHByb2JhYmlsaXR5IG9mIGNvaW4gLyBlLmcuIDUwJSBvciAuNSkNCnJiaW5vbSgxLCAxLCAuNSkNCg0KIyBGbGlwcGluZyA0IGZhaXIgY29pbnMNCnJiaW5vbSgxLCA0LCAuNSkNCg0KIyBGbGlwcGluZyA0IGZhaXIgY29pbnMgMTAsMDAwIHRpbWVzLCBzZXQgdG8gY29pbmZsaXBzWCB2YXIgKFdoZXJlIFggaXMgdGhlIG51bWJlciBvZiBoZWFkcyBzaG93aW5nIHdoZW4gNCBjb2lucyBhcmUgdG9zc2VkKQ0KY29pbmZsaXBzWCA8LSByYmlub20oMTAwMDAsIDQsIC41KQ0KDQojIFNpbXVsYXRlZCBtZWFuIG9mIGNvaW5mbGlwc1gNCnNpbXVsYXRlZF9tZWFuIDwtIG1lYW4oY29pbmZsaXBzWCkNCg0KIyBTaW11bGF0ZWQgdmFyaWFuY2Ugb2YgY29pbmZsaXBzWA0Kc2ltdWxhdGVkX3ZhcmlhbmNlIDwtIHZhcihjb2luZmxpcHNYKQ0KDQojIHRoZW9yZXRpY2FsIHZhbHVlcyBkYmlub20gKHg9IDEsIHNpemUgPSAxNiBwb3NzaWJsZSBvdXRjb21lcywgcHJvYiA9ICAuMDIgLyAyJSkNCmRiaW5vbV9tZWFuIDwtIChkYmlub20gKHggPSAyLCBzaXplID0gMTYsIHByb2IgPSAwLjAyKSkNCmRiaW5vbV92YXJpYW5jZSA8LSAoZGJpbm9tICh4ID0gMSwgc2l6ZSA9IDE2LCBwcm9iID0gMC4wMikpDQoNCiMgQ2hlY2sgaWYgdGhlb3JldGljYWwgdmFsdWUgb2YgZGJpbm9tX21lYW4gaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIC4wMiUgb2Ygc2ltdWxhdGVkX21lYW4NCnNpbXVsYXRlZF92ZXJzdXNfdGhlb3JldGljYWxfbWVhbiA8LSBhYnMoc2ltdWxhdGVkX21lYW4gLSBkYmlub21fbWVhbikgLyBkYmlub21fbWVhbiA8PSAwLjAyDQoNCiMgQ2hlY2sgaWYgdGhlb3JldGljYWwgdmFsdWUgb2YgZGJpbm9tX3ZhcmlhbmNlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byAuMDIlIG9mIHNpbXVsYXRlZF92YXJpYW5jZQ0Kc2ltdWxhdGVkX3ZlcnN1c190aGVvcmV0aWNhbF92YXJpYW5jZSA8LSBhYnMoc2ltdWxhdGVkX3ZhcmlhbmNlIC0gZGJpbm9tX3ZhcmlhbmNlKSAvIGRiaW5vbV92YXJpYW5jZSA8PSAwLjAyDQoNCnByaW50KHNpbXVsYXRlZF9tZWFuKSANCnByaW50KHNpbXVsYXRlZF92YXJpYW5jZSkNCnByaW50KHNpbXVsYXRlZF92ZXJzdXNfdGhlb3JldGljYWxfbWVhbikgDQpwcmludChzaW11bGF0ZWRfdmVyc3VzX3RoZW9yZXRpY2FsX3ZhcmlhbmNlKQ0KDQpgYGANCg0KKipQcm9ibGVtIDQgKDEwIHB0cykgLSBzaW1pbGFyIHRvIFByLiAxMSAvIHBhZ2UgMzA3IGluIHRleHQqKg0KDQpUcmFmZmljIHZvbHVtZSBpcyBhbiBpbXBvcnRhbnQgZmFjdG9yIGZvciBkZXRlcm1pbmluZyB0aGUgbW9zdCBjb3N0LWVmZmVjdGl2ZSBtZXRob2QgdG8gc3VyZmFjZSBhIHJvYWQuIFN1cHBvc2UgdGhhdCB0aGUgYXZlcmFnZSBudW1iZXIgb2YgdmVoaWNsZXMgcGFzc2luZyBhIGNlcnRhaW4gcG9pbnQgb24gYSByb2FkIGlzIDUgZXZlcnkgNjAgc2Vjb25kcy4NCg0KKGEpIEZpbmQgdGhlIHByb2JhYmlsaXR5IHRoYXQgbW9yZSB0aGFuIDEyIGNhcnMgd2lsbCBwYXNzIHRoZSBwb2ludCBpbiBhIHBlcmlvZCBvZiAzIG1pbnV0ZXMuDQooYikgV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBtb3JlIHRoYW4gMTAwIGNhcnMgcGFzcyB0aGUgcG9pbnQgaW4gaGFsZiBhbiBob3VyPw0KDQpIaW50OiBBZGp1c3QgdGhlIFBvaXNzb24gcGFyYW1ldGVyICRcbGFtYmRhID0gNSQgZXZlcnkgNjAgc2Vjb25kcyB0byBgI2AgcGVyIGV2ZXJ5IDMgbWludXRlcw0KDQoqKihhKTogMC44MTUyNDgyKioNCioqKGIpOiAwLjk5OTk5NDEqKg0KDQpgYGB7ciBwciAxMX0NCg0KIyBBdmcgIyBvZiB2ZWhpY2xlcyBwYXNzaW5nIGEgY2VydGFpbiBwb2ludCBvbiBhIHJvYWQgaXMgNSBldmVyeSA2MCBzZWNvbmRzLiANCiMgKGEpIG1vcmUgdGhhbiAxMiBjYXJzIHdpbGwgcGFzcyB0aGUgcG9pbnQgaW4gYSBwZXJpb2Qgb2YgMyBtaW51dGVzICgzIHNldHMgb2YgNjAgc2Vjb25kcywgb3IgMyBzZXRzIG9mIDUgY2FycyAvIDE1IGNhcnMgTUFYKQ0KIyAxMSBhcyBtaW4gbm9uLWluY2x1c2l2ZSAodG8gZ2V0IDEyKykNCmFQcm9iYWJpbGl0eSA8LSAxIC0gcHBvaXMoMTEsIDE1KQ0KDQojIChiKSBtb3JlIHRoYW4gMTAwIGNhcnMgcGFzcyB0aGUgcG9pbnQgaW4gaGFsZiBhbiBob3VyICgzMCBzZXRzIG9mIDYwIHNlY29uZHMsIG9yIDMwIHNldHMgb2YgNSBjYXJzIC8gMTUwIGNhcnMgTUFYKQ0KIyA5OSBhcyBtaW4gbm9uLWluY2x1c2l2ZSAodG8gZ2V0MTAwKykNCmJQcm9iYWJpbGl0eSA8LSAxIC0gcHBvaXMoOTksIDE1MCkNCg0KbGlzdChBUHJvYmFiaWxpdHkgPSBhUHJvYmFiaWxpdHksIGJQcm9iYWJpbGl0eSA9IGJQcm9iYWJpbGl0eSkNCg0KYGBgDQoNCioqUHJvYmxlbSA1ICgxMCBwdHMpIC0gc2ltaWxhciB0byBQci4gMTggLyBwYWdlIDMwOCBpbiB0ZXh0KiogU3VwcG9zZSB0aGUgcGVyY2VudGFnZSBvZiBkcmlua3Mgc29sZCBmcm9tIGEgdmVuZGluZyBtYWNoaW5lIGFyZSA3MCUgYW5kIDMwJSBmb3Igc29mdCBkcmlua3MgYW5kIGJvdHRsZWQgd2F0ZXIsIHJlc3BlY3RpdmVseS4NCg0KKGEpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgb24gYSByYW5kb21seSBzZWxlY3RlZCBkYXksIHRoZSBmaXJzdCBzb2Z0IGRyaW5rIGlzIHRoZSBmb3VydGggZHJpbmsgc29sZD8NCihiKSBGaW5kIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGV4YWN0bHkgNCBvdXQgb2YgMTAgZHJpbmtzIHNvbGQgaXMgYSBzb2Z0IGRyaW5rLg0KDQpIaW50OiBMZXQgYFhgID0gbnVtYmVyIG9mIHdhdGVycyAoZmFpbHVyZXMpIHB1cmNoYXNlZCBiZWZvcmUgdGhlIGZpcnN0IHNvZnQgZHJpbmsgaXMgcHVyY2hhc2VkLiBUaGVuLCAkWCBcc2ltIEdlbygwLjcwKSQuDQoNCioqKGEpOiAwLjAxODkqKg0KKiooYik6IDAuMDM2NzU2OTEqKg0KDQoqKllPVVIgQ09ERSBIRVJFOioqOg0KDQooYSkgDQoNCmBgYHtyIHByLiAxOGF9DQoNCiMgUmFuZG9tbHkgc2VsZWN0ZWQgZGF5LCB0aGUgZmlyc3Qgc29mdCBkcmluayBpcyB0aGUgZm91cnRoIGRyaW5rIHNvbGQ/DQpTRFBlcmNlbnQgPC0gMC43MCANCmZpcnN0X1NEX2ZvdXJ0aF9zb2xkX2RyaW5rIDwtICgxIC0gU0RQZXJjZW50KV4zICogU0RQZXJjZW50DQojIFJlc3VsdA0KcHJpbnQoZmlyc3RfU0RfZm91cnRoX3NvbGRfZHJpbmspDQoNCmBgYA0KDQooYikgTGV0IGBYYCA9IG51bWJlciBvZiBzb2Z0IGRyaW5rcyBzb2xkLiBUaGVuLCAkWCBcc2ltIEJpbigxMCwgMC43MCkkIGFuZCAkUChYID0gMSkgPSAwJCBzaW5jZSBvbmUgaGFzOg0KDQpgYGB7ciBwci4gMThifQ0KDQpTRFBlcmNlbnQgPC0gMC43MCANCg0KIyBFeGFjdGx5IDQgb3V0IG9mIDEwIGRyaW5rcyBzb2xkIGlzIGEgc29mdCBkcmluaw0KdG90YWxfZHJpbmtzIDwtIDEwDQp0YXJnZXRfZHJpbmtzX1NEIDwtIDQNCg0KI0V4YWN0bHkgNCBvZiAxMCBkcmlua3MgYXMgc29mdCBkcmlua3MNCmZvdXJfb2ZfdGVuX1NEIDwtIGNob29zZSh0b3RhbF9kcmlua3MsIHRhcmdldF9kcmlua3NfU0QpICogU0RQZXJjZW50XnRhcmdldF9kcmlua3NfU0QgKiAoMSAtIFNEUGVyY2VudCleKHRvdGFsX2RyaW5rcyAtIHRhcmdldF9kcmlua3NfU0QpDQpwcmludChwcm9iX2V4YWN0bHlfNF9zb2Z0X2RyaW5rcykNCg0KYGBgDQoNCioqUHJvYmxlbSA2ICgxMCBwdHMpIC0gRXhwb25lbnRpYWwgRGlzdHJpYnV0aW9uOiBMaWdodCBCdWxicyoqIElmIHRoZSBsaWZlIG9mIGEgY2VydGFpbiB0eXBlIG9mIGxpZ2h0IGJ1bGIgaGFzIGFuIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiB3aXRoIGEgbWVhbiBvZiAxMCBtb250aHMsIGZpbmQNCg0KKGEpIFRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgcmFuZG9tbHkgc2VsZWN0ZWQgbGlnaHQgYnVsYiBsYXN0cyBiZXR3ZWVuIDYgYW5kIDE1IG1vbnRocy4NCihiKSBUaGUgOTV0aCBwZXJjZW50aWxlIG9mIHRoZSBkaXN0cmlidXRpb24uIEhvdyB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIGxpZ2h0IGJ1bGIgdG8gbGFzdCBtb3JlIHRoYW4gMzYgbW9udGhzIGNvbXBhcmUgdG8gYDAuMDVgP1wNCihjKSBUaGUgcHJvYmFiaWxpdHkgdGhhdCBhIGxpZ2h0IGJ1bGIgdGhhdCBoYXMgbGFzdGVkIGZvciAxMCBtb250aHMgd2lsbCBsYXN0IG1vcmUgdGhhbiAyNSBtb250aHMuDQoNCioqKGEpOiAwLjMyNTY4MTUqKg0KKiooYik6IDAuMDI3MzIzNzIgJiBpdCBtZWV0cyBjb21wYXJpc29uIHRvIC4wNSAqKg0KKiooYyk6IDAuMjIzMTMwMioqDQoNCioqWU9VUiBDT0RFIEhFUkU6KioNCg0KYGBge3IgRXguIDQuMTd9DQoNCmV4cERpc3RfVGVuX01vbnRocyA8LSAxLzEwICMgRXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uIHdpdGggbWVhbiBvZiAxMCBtb250aHMNCg0KIyAoYSkgLSByYW5kb21seSBzZWxlY3RlZCBsaWdodCBidWxiIGxhc3RzIGJldHdlZW4gNiBhbmQgMTUgbW9udGhzICgxNSBtby4gcGV4cCAtIDYgbW8uIHBleHApDQpTaXhfdG9fRmlmdGVlbiA8LSBwZXhwKDE1LCByYXRlID0gZXhwRGlzdF9UZW5fTW9udGhzKSAtIHBleHAoNiwgcmF0ZSA9IGV4cERpc3RfVGVuX01vbnRocykNCnByaW50KFNpeF90b19GaWZ0ZWVuKQ0KDQojIChiKSAtIDk1dGggcGVyY2VudGlsZS4gUHJvYmFiaWxpdHkgb2YgdGhlIGxpZ2h0IGJ1bGIgdG8gbGFzdCAzNiBtb250aHMrIGNvbXBhcmUgdG8gYDAuMDVgPw0KUGVyY2VudGlsZV85NXRoIDwtIHFleHAoMC45NSwgcmF0ZSA9IGV4cERpc3RfVGVuX01vbnRocykNCm92ZXJfMzYgPC0gcGV4cCgzNiwgcmF0ZSA9IGV4cERpc3RfVGVuX01vbnRocywgbG93ZXIudGFpbCA9IEZBTFNFKQ0KcHJpbnQob3Zlcl8zNikNCg0KY29tcGFyaXNvbl90b18uMDUgPC0gb3Zlcl8zNiA8IDAuMDUNCnByaW50KGNvbXBhcmlzb25fdG9fLjA1KQ0KDQojIChjKSAtIFByb2JhYmlsaXR5IHRoYXQgYSBsaWdodCBidWxiIHRoYXQgaGFzIGxhc3RlZCBmb3IgMTAgbW9udGhzIHdpbGwgbGFzdCAyNSBtb250aHMrDQpUZW5fbW9udGhzX2xhc3RfMjVfbW9udGhzX3BsdXMgPC0gcGV4cCgxNSwgcmF0ZSA9IGV4cERpc3RfVGVuX01vbnRocywgbG93ZXIudGFpbCA9IEZBTFNFKQ0KcHJpbnQoVGVuX21vbnRoc19sYXN0XzI1X21vbnRoc19wbHVzKQ0KDQpgYGANCg0KKipQcm9ibGVtIDcgKDEwIHB0cykgKElORC1PUFQpIC0gUHIuIDggcGFnZSA0MDAqKiBBIHBvcHVsYXRpb24gaGFzIHRoZSBmb2xsb3dpbmcgZWxlbWVudHM6IDIsIDUsIDgsIDEyLCAxMyAoKipmaW5pdGUgcG9wdWxhdGlvbioqKS4NCg0KKGEpIEVudW1lcmF0ZSBhbGwgdGhlIHNhbXBsZXMgb2Ygc2l6ZSAyIHRoYXQgY2FuIGJlIGRyYXduIHdpdGggYW5kIHdpdGhvdXQgcmVwbGFjZW1lbnQuIChIaW50OiBVc2UgdGhlIGBzcnMoKWAgZnVuY3Rpb24gZnJvbSB0aGUgYFBBU1dSMmAgcGFja2FnZSkNCg0KKGIpIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgcG9wdWxhdGlvbi4NCg0KKGMpIENhbGN1bGF0ZSB0aGUgdmFyaWFuY2Ugb2YgdGhlIHBvcHVsYXRpb24uDQoNCihkKSBDYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgcG9wdWxhdGlvbi4NCg0KKGUpIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgc2FtcGxlIG1lYW4sICRFW1hdJC4NCg0KKGYpIENhbGN1bGF0ZSB0aGUgdmFyaWFuY2Ugb2YgdGhlIHNhbXBsZWQgbWVhbiwgJFZhcihcYmFyIFgpJA0KDQooZykgQ2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHNhbXBsZSBtZWFuLg0KDQooaCkgQ2FsY3VsYXRlIHRoZSBtZWFuIG9mIHRoZSBzYW1wbGUgdmFyaWFuY2UsICRFW1NeMl0kDQoNCihpKSBJcyB0aGUgdmFyaWFuY2Ugb2YgJFxiYXIgWCQgbGFyZ2VyIHdoZW4gc2FtcGxpbmcgd2l0aCBvciB3aXRob3V0IHJlcGxhY2VtZW50PyBFeHBsYWluIHlvdXIgYW5zd2VyDQoNCioqU29sdXRpb246KioNCg0KKipZT1VSIENPREUgSEVSRToqKg0KDQpgYGB7cn0NCg0KI2luZGl2aWR1YWwgb3B0aW9uYWwNCg0KYGBgDQoNCioqUHJvYmxlbSA4ICgxMCBwdHMpIC0gc2ltaWxhciB0byBQci4gMTAgLyBwYWdlIDQwMCBpbiB0ZXh0KioNCg0KVXNlIHRoZSBkYXRhIGZyYW1lIGBXSEVBVFVTQTIwMDRgIGZyb20gdGhlIGBQQVNXUjJgIHBhY2thZ2U7IGRyYXcgYWxsIHNhbXBsZXMgb2Ygc2l6ZXMgNCwgNSwgYW5kIDY7IGFuZCBjYWxjdWxhdGUgdGhlIG1lYW4gb2YgdGhlIG1lYW5zIGZvciB0aGUgdmFyaWFibGUgYWNyZXMgKHdoZWF0IHN1cmZhY2UgYXJlYSBtZWFzdXJlZCBpbiB0aG91c2FuZHMgb2YgYWNyZXMpLiAuIFdoYXQgc2l6ZSBwcm92aWRlcyB0aGUgYmVzdCBhcHByb3hpbWF0aW9uIHRvIHRoZSBwb3B1bGF0aW9uIG1lYW4/IFdoYXQgaXMgdGhlIHZhcmlhbmNlIG9mIHRoZXNlIG1lYW5zPw0KDQoqKkhpbnQ6KiogVXNlIHRoZSBgc3JzKClgIGZ1bmN0aW9uIGZyb20gdGhlIGBQQVNXUjJgIHBhY2thZ2UgdG8gZHJhdyBzaW1wbGUgcmFuZG9tIHNhbXBsZXMuDQoNCioqWU9VUiBDT0RFIEhFUkU6KioNCg0KYGBge3J9DQoNCiNyZWZyZW5jaW5nIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgZXhlcmNpc2VzIGxpbmUgMjA2DQpsaWJyYXJ5KFBBU1dSMikNCg0KIyBTYW1wbGUgU2l6ZSA0Og0KU1JTNCA8LSBzcnMoV0hFQVRVU0EyMDA0JGFjcmVzLCA0KQ0KeGJhclNSUzQgPC0gYXBwbHkoU1JTNCwgMSwgbWVhbikgIyBNRUFODQpjKG1lYW4oeGJhclNSUzQpLCB2YXIoeGJhclNSUzQpKSAjIE1FQU4gJiBWQVJJQU5DRQ0KDQojIFNhbXBsZSBTaXplIDU6DQpTUlM1IDwtIHNycyhXSEVBVFVTQTIwMDQkYWNyZXMsIDUpIA0KeGJhclNSUzUgPC0gYXBwbHkoU1JTNSwgMSwgbWVhbikgIyBNRUFODQpjKG1lYW4oeGJhclNSUzUpLCB2YXIoeGJhclNSUzUpKSAjIE1FQU4gJiBWQVJJQU5DRQ0KDQojIFNhbXBsZSBTaXplIDY6DQpTUlM2IDwtIHNycyhXSEVBVFVTQTIwMDQkYWNyZXMsIDYpIA0KeGJhclNSUzYgPC0gYXBwbHkoU1JTNiwgMSwgbWVhbikgIyBNRUFODQpjKG1lYW4oeGJhclNSUzYpLCB2YXIoeGJhclNSUzYpKSAjIE1FQU4gJiBWQVJJQU5DRQ0KDQpgYGANCioqU29sdXRpb246IFNhbXBsZSBTaXplIDYgaGFzIHRoZSBzbWFsbGVzdCB2YXJpYW5jZSBvZiAzOTczNzQuMzk3IChjb21wYXJlZCB0byBTYW1wbGUgc2l6ZSA0J3MgNjQ1NzU1Ljg3MiBhbmQgU2FtcGxlIHNpemUgNSdzIDQ5NjcyMC42NDYqKg0KDQoqKlByb2JsZW0gOSAoMTAgcHRzKSAtIFByLiAxNiAvIHBhZ2UgNTEzIGluIHRleHQqKg0KDQpBIGdyb3VwIG9mIGVuZ2luZWVycyB3b3JraW5nIHdpdGggcGh5c2ljaWFucyBpbiBhIHJlc2VhcmNoIGhvc3BpdGFsIGlzIGRldmVsb3BpbmcgYSBuZXcgZGV2aWNlIHRvIG1lYXN1cmUgYmxvb2QgZ2x1Y29zZSBsZXZlbHMuIEJhc2VkIG9uIG1lYXN1cmVtZW50cyB0YWtlbiBmcm9tIHBhdGllbnRzIGluIGEgcHJldmlvdXMgc3R1ZHksIHRoZSBwaHlzaWNpYW5zIGFzc2VydCB0aGF0IHRoZSBuZXcgZGV2aWNlIHByb3ZpZGVzIGJsb29kIGdsdWNvc2UgbGV2ZWxzIHNsaWdodGx5IGhpZ2hlciB0aGFuIHRob3NlIHByb3ZpZGVkIGJ5IHRoZSBvbGQgZGV2aWNlLiBUbyBjb3Jyb2JvcmF0ZSB0aGVpciBzdXNwaWNpb24sIGAxNWAgZGlhYmV0aWMgcGF0aWVudHMgd2VyZSByYW5kb21seSBzZWxlY3RlZCwgYW5kIHRoZWlyIGJsb29kIGdsdWNvc2UgbGV2ZWxzIHdlcmUgbWVhc3VyZWQgd2l0aCBib3RoIHRoZSBuZXcgYW5kIHRoZSBvbGQgZGV2aWNlcy4gVGhlIG1lYXN1cmVtZW50cywgaW4gYG1nLzEwMCBtbGAsIGFwcGVhciBpbiBkYXRhIGZyYW1lIGBHTFVDT1NFYCBmcm9tIHRoZSBgUEFTV1IyYCBwYWNrYWdlOg0KDQooYSkgQXJlIHRoZSBzYW1wbGVzIGluZGVwZW5kZW50PyBXaHkgb3Igd2h5IG5vdD8NCihiKSBJZiB0aGUgYmxvb2QgZ2x1Y29zZSBsZXZlbCBpcyBhIG5vcm1hbGx5IGRpc3RyaWJ1dGVkIHJhbmRvbSB2YXJpYWJsZSwgY29tcHV0ZSBhIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgbWVhbiBkaWZmZXJlbmNlcyBvZiB0aGUgcG9wdWxhdGlvbi4NCihjKSBVc2UgdGhlIHJlc3VsdHMgaW4gKGIpIHRvIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCB0aGUgdHdvIGRldmljZXMgZ2l2ZSB0aGUgc2FtZSByZXN1bHRzLg0KDQoqKlNvbHV0aW9uOioqDQoNCihhKSBUaGUgc2FtcGxlcyBhcmUgbm90IGluZGVwZW5kZW50LiBUaGUgcGF0aWVudHMgZWFjaCBoYXZlIGJvdGggbWVhc3VyZW1lbnRzIG9idGFpbmVkIGZyb20gb2xkIGRldmljZSBhcyB3ZWxsIGFzIHRoZWlyIG5ld2VyIGRldmljZS4gVGhlIHN0YXRpc3RpY3MgYXJlIGRlcGVuZGVudCBvbiBlYWNoIG90aGVyDQoNCihiKSBUaGUgOTUlIGNvbmZpZGVuY2UgbGV2ZWwgaW50ZXJ2YWwgZm9yIHRoZSBtZWFuIGRpZmZlcmVuY2VzIG9mIHRoZSBwb3B1bGF0aW9uIGlzIOKIkjE2LjM2MTQgdG8g4oiSMTIuNzU4Ni4NCg0KKipZT1VSIENPREUgSEVSRToqKg0KDQpgYGB7cn0NCkdMVUNPU0UgPC0gR0xVQ09TRSAlPiUgbXV0YXRlKERJRkYgPSBvbGQtbmV3KSAjIGNyZWF0ZSB2YXJpYWJsZSBESUZGIGZvciB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG9sZCBhbmQgbmV3IGxldmVsDQoNCmhlYWQoR0xVQ09TRSkNCg0KZ2dwbG90KGRhdGEgPSBHTFVDT1NFLCBhZXMoc2FtcGxlID0gRElGRikpICsNCiAgc3RhdF9xcSgpICsNCiAgdGhlbWVfYncoKQ0KDQpDSSA8LSB0LnRlc3QoR0xVQ09TRSRESUZGKSRjb25mICMgdXNlIHQtdGVzdCBzaW5jZSB0aGUgc2FtcGxlIHNpemUgaXMgc21hbGwgPCAzMA0KQ0kNCmBgYA0KDQpUaGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBtZWFuIGRpZmZlcmVuY2VzIG9mIHRoZSBwb3B1bGF0aW9uIGlzIGBb4oiSMTYuMzYxNCziiJIxMi43NTg2XWAuDQoNCihjKSBUaGUgY29uZmlkZW5jZSBpbnRlcnZhbCBzdWdnZXN0cyB0aGF0IG9uIGF2ZXJhZ2UsIHRoZSBuZXcgZGV2aWNlIHJlcG9ydHMgaGlnaGVyIGJsb29kIGdsdWNvc2UgbGV2ZWxzIHRoYW4gdGhlIG9sZCBkZXZpY2UuDQoNCioqUHJvYmxlbSAxMCAoMTAgcHRzKSAoSU5ELU9QVCkgLSBzaW1pbGFyIHRvIFByLiA5IC8gcGFnZSA1MTEgaW4gdGV4dCoqDQoNCkEgbGFyZ2UgY29tcGFueSB3YW50cyB0byBlc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpdHMgYWNjb3VudHMgdGhhdCBhcmUgcGFpZCBvbiB0aW1lLg0KDQooYSkgSG93IGxhcmdlIGEgc2FtcGxlIGlzIG5lZWRlZCB0byBlc3RpbWF0ZSB0aGUgdHJ1ZSBwcm9wb3J0aW9uIHdpdGhpbiAyJSB3aXRoIGEgOTUlIGNvbmZpZGVuY2UgbGV2ZWw/DQoNCihiKSBTdXBwb3NlIDcwMCBvdXQgb2YgODAwIGFjY291bnRzIGFyZSBwYWlkIG9uIHRpbWUuIENvbnN0cnVjdCA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSB0cnVlIHByb3BvcnRpb24gb2YgYWNjb3VudHMgdGhhdCBhcmUgcGFpZCBvbiB0aW1lIHVzaW5nIGFuIGFzeW1wdG90aWMgY29uZmlkZW5jZSBpbnRlcnZhbCwgYW4gQWdyZXN0aSBDb3VsbCBjb25maWRlbmNlIGludGVydmFsLg0KDQpIaW50OiBVc2UgdGhlIGBuc2l6ZSgpYCBhbmQgYGJpbm9tLmNvbmZpbnQoKWAgZnJvbSB0aGUgYGxpYnJhcnkoYmlub20pYA0KDQoqKlNvbHV0aW9uOioqDQoNCioqWU9VUiBDT0RFIEhFUkU6KioNCg0KYGBge3J9DQpsaWJyYXJ5KGJpbm9tKQ0KbGlicmFyeShiaW5vbSkNCiMoYSkgDQoNCiMoYikNCg0KI2luZGl2aWR1YWwgb3B0aW9uYWwNCg0KYGBgDQoNCioqUHJvYmxlbSAxMSAoMTAgcHRzKSAtIFByLiAxMCAvIHBhZ2UgNTExIGluIHRleHQqKg0KDQpJbiBhIHN0dWR5IGNvbmR1Y3RlZCBhdCAqKkFwcGFsYWNoaWFuIFN0YXRlIFVuaXZlcnNpdHkqKiwgc3R1ZGVudHMgdXNlZCBkaWdpdGFsIG9yYWwgdGhlcm1vbWV0ZXJzIHRvIHJlY29yZCB0aGVpciB0ZW1wZXJhdHVyZXMgZWFjaCBkYXkgdGhleSBjYW1lIHRvIGNsYXNzLiBBIHJhbmRvbWx5IHNlbGVjdGVkIGRheSBvZiBzdHVkZW50IHRlbXBlcmF0dXJlcyBpcyBwcm92aWRlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlIGFuZCBpbiB0aGUgZGF0YSBmcmFtZSBgU1RBVFRFTVBTYC4gSW5mb3JtYXRpb24gaXMgYWxzbyBwcm92aWRlZCB3aXRoIHJlZ2FyZCB0byBzdWJqZWN0IGdlbmRlciBhbmQgdGhlIGhvdXIgb2YgdGhlIGRheSB3aGVuIHRoZSBzdHVkZW50cycgdGVtcGVyYXR1cmVzIHdlcmUgbWVhc3VyZWQuDQoNCkRpcmVjdGlvbjogbG9hZCB0aGUgZGF0YSB3aXRoIGBkYXRhKFNUQVRURU1QUylgIGhhdmluZyB0aGUgYGxpYnJhcnkoUEFTV1IyKWAgbG9hZGVkLg0KDQoqKkhpbnQ6KiogVXNlIGB0LnRlc3QodGVtcGVyYXR1cmUgfiBnZW5kZXIsIGRhdGEgPSBTVEFUVEVNUFMsIG11ID0gMCwgcGFpcmVkID0gRkFMU0UpYCB0aGUgYHhgIGFkIGB5YCB2YWx1ZXMgYXJlIGdpdmVuIHdpdGggZm9ybXVsYSBleHByZXNzaW9uIGBmb3JtdWxhID0gdGVtcGVyYXR1cmUgfiBnZW5kZXJgLiBUaGVuIHVzZSB0aGUgYCRgIGFjY2VzcyB0byBvYnRhaW4gdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWw6IGBDSSA8LSB0LnRlc3QodGVtcGVyYXR1cmUgfiBnZW5kZXIsIGRhdGEgPSBTVEFUVEVNUFMsIG11ID0gMCwgcGFpcmVkID0gRkFMU0UpJGNvbmZgDQoNCihhKSBDb25zdHJ1Y3QgYSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgYXZlcmFnZSB0ZW1wZXJhdHVyZSBkaWZmZXJlbmNlIGJldHdlZW4gZmVtYWxlcyBhbmQgbWFsZXMuIERvZXMgdGhlIGludGVydmFsIGNvbnRhaW4gdGhlIHZhbHVlIHplcm8/IFdoYXQgZG9lcyB0aGlzIHN1Z2dlc3QgYWJvdXQgZ2VuZGVyIHRlbXBlcmF0dXJlIGRpZmZlcmVuY2VzPw0KDQooYikgQ29uc3RydWN0IGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSB0cnVlIGF2ZXJhZ2UgdGVtcGVyYXR1cmUgZGlmZmVyZW5jZSBiZXR3ZWVuIHN0dWRlbnRzIHRha2luZyB0aGVpciB0ZW1wZXJhdHVyZXMgYXQgOCBhLm0uIGFuZCBzdHVkZW50cyB0YWtpbmcgdGhlaXIgdGVtcGVyYXR1cmVzIGF0IDkgYS5tLiBHaXZlIGEgcmVhc29uIHdoeSBvbmUgZ3JvdXAgYXBwZWFycyB0byBoYXZlIGEgaGlnaGVyIHRlbXBlcmF0dXJlIHJlYWRpbmcuDQoNCioqU29sdXRpb246KioNCg0KKipZT1VSIENPREUgSEVSRToqKg0KDQpgYGB7cn0NCmxpYnJhcnkoUEFTV1IyKQ0KZGF0YShTVEFUVEVNUFMpDQoNCiMoYSkgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSB0cnVlIGF2ZXJhZ2UgdGVtcGVyYXR1cmUgZGlmZmVyZW5jZSBiZXR3ZWVuIGZlbWFsZXMgYW5kIG1hbGVzDQoNCnQudGVzdCh0ZW1wZXJhdHVyZSB+IGdlbmRlciwgZGF0YSA9IFNUQVRURU1QUywgbXUgPSAwLCBwYWlyZWQgPSBGQUxTRSkNCkNJIDwtIHQudGVzdCh0ZW1wZXJhdHVyZSB+IGdlbmRlciwgZGF0YSA9IFNUQVRURU1QUywgbXUgPSAwLCBwYWlyZWQgPSBGQUxTRSkkY29uZg0KDQojKGIpIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgdHJ1ZSBhdmVyYWdlIHRlbXBlcmF0dXJlIGRpZmZlcmVuY2UgYmV0d2VlbiBzdHVkZW50cyB0YWtpbmcgdGhlaXIgdGVtcGVyYXR1cmVzIGF0IDggYS5tLiBhbmQgc3R1ZGVudHMgdGFraW5nIHRoZWlyIHRlbXBlcmF0dXJlcyBhdCA5IGEubQ0KDQp0LnRlc3QodGVtcGVyYXR1cmUgfiBjbGFzcywgZGF0YSA9IFNUQVRURU1QUywgbXUgPSAwLCBwYWlyZWQgPSBGQUxTRSkNCkNJIDwtIHQudGVzdCh0ZW1wZXJhdHVyZSB+IGNsYXNzLCBkYXRhID0gU1RBVFRFTVBTLCBtdSA9IDAsIHBhaXJlZCA9IEZBTFNFKSRjb25mDQoNCmBgYA0KDQpBIGA5NSVgIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSB0cnVlIGF2ZXJhZ2UgZGlmZmVyZW5jZSBiZXR3ZWVuIHN0dWRlbnRzIHRha2luZyB0aGVpciB0ZW1wZXJhdHVyZXMgYXQgYDhgIGEubS4gYW5kIHN0dWRlbnRzIHRha2luZyB0aGVpciB0ZW1wZXJhdHVyZXMgYXQgYDlgIGEubS4gaXMgYFviiJIyLjQ5NjUs4oiSMC4yNTY0XWAuIE5vdGUgdGhhdCB0aGlzIGludGVydmFsIGRvZXMgbm90IGNvbnRhaW4gYDBgLCBpbmRpY2F0aW5nIHRoYXQgdGhlIHRoZXJlIGlzIGV2aWRlbmNlIHRvIHN1Z2dlc3Qgc3R1ZGVudHMgaW4gdGhlIGA4YCBhLm0uIGNsYXNzIGhhdmUgdGVtcGVyYXR1cmVzIHRoYXQgYXJlIG5vdCBhcyB3YXJtIGFzIHRoZSBgOWAgYS5tLiBjbGFzcy4gT25lIHBvc3NpYmxlIGV4cGxhbmF0aW9uIGlzIHRoYXQgc3R1ZGVudHMgcm9sbCBzdHJhaWdodCBvdXQgb2YgYmVkIGFuZCBpbnRvIHRoZSBgOGAgYS5tLiBjbGFzcy4gQ29uc2VxdWVudGx5LCB0aGVpciB0ZW1wZXJhdHVyZXMgYXJlIGNsb3NlciB0byB0aGVpciBzbGVlcGluZyB0ZW1wZXJhdHVyZXMgd2hpY2ggYXJlIGxvd2VyIHRoYW4gdGhlaXIgd2FraW5nIHRlbXBlcmF0dXJlcy4NCg0KIyMgMi4gQlJBSU5TVE9STUlORyBQQVJUOg0KDQojIyMgSG93IGRvIHdlIGZvcm0gY29uZmlkZW5jZSBpbnRlcnZhbHMgd2hlbiBub3JtYWxpdHkgYXNzdW1wdGlvbiBpcyBub3QgcmVhc29uYWJsZSBhbmQgd2UgaGF2ZSBzbWFsbCBzYW1wbGUgc2l6ZSBzbyB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtIGRvZXMgbm90IGFwcGx5Pw0KDQo+IExvb2sgZm9yIHRoZSBhbnN3ZXIgd2l0aCB0aGUgZm9sbG93aW5nIDoNCg0KKipFbXBpcmljYWwgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBtZWFuLioqDQoNCkZvciB0aGUgZGF0YSBjb250YWluZWQgaW4gYSB2ZWN0b3IgYHggPSBjKDM2LDMwLDM3LDQzLDQyLDQzLDQzLDQ2LDQwLDQyKWAgRXN0aW1hdGUgdGhlIG1lYW4gYM68YCBvZiB0aGUgdW5kZXJseWluZyBkaXN0cmlidXRpb24gYW5kIGdpdmUgYW4gYDkwJWAgYm9vdHN0cmFwIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCmBgYHtyfQ0KeCA9IGMoMzYsMzAsMzcsNDMsNDIsNDMsNDMsNDYsNDAsNDIpDQpxcW5vcm0oeCkgIyBzZWUgaWYgdGhlIGRhdGEgYXBwZWFyIHRvIGZvbGxvdyBub3JtYWwgZGlzdHJpYnV0aW9uDQpgYGANCg0KPiBEYXRhIGlzIG5vdCBxdWl0ZSBub3JtYWwgYXMgaXQgYXBwZWFycyBvbiB0aGUgUS1RIFBMT1QhDQoNCmBgYHtyfQ0KDQpuID0gbGVuZ3RoKHgpDQpzZXQuc2VlZCgyNSkgIA0KDQojIHNhbXBsZSBtZWFuDQp4YmFyID0gbWVhbih4KQ0KDQpjYXQoImRhdGEgbWVhbiA9ICIseGJhciwnXG4nKQ0KDQpuYm9vdCA9IDEwMDAwICMgbnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzIA0KDQojIEdlbmVyYXRlIDEwMDAwIGJvb3RzdHJhcCBzYW1wbGVzLCBpLmUuIGFuIG4geCAxMDAwMCBhcnJheSBvZiByYW5kb20gcmVzYW1wbGVzIGZyb20geC4NCnRtcGRhdGEgPSBzYW1wbGUoeCxuKm5ib290LCByZXBsYWNlPVRSVUUpICMgc2FtcGxlIHdpdGggcmVwbGFjZW1lbnQNCmJvb3RzdHJhcHNhbXBsZSA9IG1hdHJpeCh0bXBkYXRhLCBucm93PW4sIG5jb2w9bmJvb3QpDQoNCiMgQ29tcHV0ZSB0aGUgc2FtcGxlIG1lYW4geGJhciBmb3IgZWFjaCBib290c3RyYXAgc2FtcGxlDQp4YmFyc3RhciA9IGNvbE1lYW5zKGJvb3RzdHJhcHNhbXBsZSkNCg0KIyBDb21wdXRlIGRlbHRhKiBmb3IgZWFjaCBib290c3RyYXAgc2FtcGxlIChkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG9yaWdpbmFsIG1lYW4gYW5kIHRoZSBib290c3RyYXAgc2FtcGxlIG1lYW4pDQpkZWx0YXN0YXIgPSB4YmFyc3RhciAtIHhiYXINCg0KIyBGaW5kIHRoZSAwLjEgYW5kIDAuOSBxdWFudGlsZXMgZm9yIGRlbHRhc3Rhcg0KZCA9IHF1YW50aWxlKGRlbHRhc3RhcixjKDAuMDUsMC45NSkpICMgZm9yIHRoZSA5MDUgQ0kgd2UgbmVlZCA5MCUgYXJlYSBiZXR3ZWVuIHRoZSBxdWFudGlsZXMNCg0KDQojIENhbGN1bGF0ZSB0aGUgOTBcJSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgbWVhbi4NCmNpID0geGJhciAtIGMoZFsyXSxkWzFdKQ0KY2kNCmBgYA0KDQo+IFdlIGNhbiBhY2hpZXZlIHRoZSBzYW1lIENJIHdpdGggdGhlIGZ1bmN0aW9ucyBgYm9vdCgpYCBhbmQgYGJvb3QuY2koKWAgZnJvbSB0aGUgcGFja2FnZSBgYm9vdGANCg0KYGBge3J9DQoNCk1FQU4gPC0gZnVuY3Rpb24oZGF0YSwgaSl7DQogIGQgPC0gZGF0YVtpXQ0KICAgTSA8LSBtZWFuKGQpDQogIH0NCmJvb3Qub2JqIDwtIGJvb3QoeCwgc3RhdGlzdGljID0gTUVBTiwgMTAwMDApDQpDSSA8LSBib290LmNpKGJvb3Qub2JqLCBjb25mID0gMC45MCx0eXBlID0gImFsbCIpICMgYWxsIHR5cGUgb2YgYm9vdHN0cmFwIGludGVydmFscyB3aWxsIGJlIHJldHVybmVkDQpDSQ0KYGBgDQoNCiMjIDMuIEJPT1RTVFJBUCBFU1RJTUFUSU9OIFBBUlQNCg0KPiBSZXZpZXcgdGhlIHByb2JsZW0gYmVsb3cuDQoNCioqUHIuIDMwIC8gcGFnZSA2OTUgaW4gdGV4dCoqDQoNClRoZSAiV2lzY29uc2luIENhcmQgU29ydGluZyBUZXN0IiBpcyB3aWRlbHkgdXNlZCBieSBwc3ljaGlhdHJpc3RzLCBuZXVyb2xvZ2lzdHMsIGFuZCBuZXVyb3BzeWNob2xvZ2lzdHMgd2l0aCBwYXRpZW50cyB3aG8gaGF2ZSBhIGJyYWluIGluanVyeSwgbmV1cm9kZWdlbmVyYXRpdmUgZGlzZWFzZSwgb3IgYSBtZW50YWwgaWxsbmVzcyBzdWNoIGFzIHNjaGl6b3BocmVuaWEuIFBhdGllbnRzIHdpdGggYW55IHNvcnQgb2YgZnJvbnRhbCBsb2JlIGxlc2lvbiBnZW5lcmFsbHkgZG8gcG9vcmx5IG9uIHRoZSB0ZXN0LiBUaGUgZGF0YSBmcmFtZSBgV0NTVGAgYW5kIHRoZSBmb2xsb3dpbmcgdGFibGUgY29udGFpbiB0aGUgdGVzdCBzY29yZXMgZnJvbSBhIGdyb3VwIG9mIDUwIHBhdGllbnRzIGZyb20gdGhlIFZpcmdlbiBkZWwgQ2FtaW5vIEhvc3BpdGFsIChQYW1wbG9uYSwgU3BhaW4pLg0KDQooYSkgVXNlIHRoZSBmdW5jdGlvbiBgZWRhKClgIGZyb20gdGhlIGBQQVNXUjJgIHBhY2thZ2UgdG8gZXhwbG9yZSB0aGUgZGF0YSBhbmQgZGVjaWRlIGlmIG5vcm1hbGl0eSBjYW4gYmUgYXNzdW1lZC4gRm9yIGRldGFpbHMgdHlwZSBpbiBjb25zb2xlIGA/ZWRhYA0KDQooYikgV2hhdCBhc3N1bXB0aW9uKHMpIG11c3QgYmUgbWFkZSB0byBjb21wdXRlIGEgYDk1JWAgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHBvcHVsYXRpb24gbWVhbj8NCg0KKGMpIENvbXB1dGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZnJvbSAoYikuDQoNCihkKSBDb21wdXRlIGEgOTUlIEJDYSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIG1lYW4gdGVzdCBzY29yZS4NCg0KKGUpIFNob3VsZCB5b3UgdXNlIHRoZSBjb25maWRlbmNlIGludGVydmFsIHJlcG9ydGVkIGluIChjKSBvciB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCByZXBvcnRlZCBpbiAoZCk/DQoNCioqU29sdXRpb246KioNCg0KKGEpIEFzc3VtaW5nIHRoZSB2YXJpYWJsZSBzY29yZSBoYXMgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIG5vdCByZWFzb25hYmxlLg0KDQpTZWUgdGhlIHJlc3VsdHMgb2YgRURBIGFuYWx5c2lzIGJlbG93Og0KDQpgYGB7cn0NCmRhdGEoV0NTVCkNCg0KV0NTVCAlPiUgcHVsbChzY29yZSkgJT4lIGVkYSgpDQpgYGANCg0KKGIpIEluIG9yZGVyIHRvIGNvbnN0cnVjdCBhIGA5NSVgIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBwb3B1bGF0aW9uIG1lYW4sIG9uZSBhc3N1bWVzIHRoYXQgdGhlIHZhbHVlcyBpbiB0aGUgdmFyaWFibGUgc2NvcmUgYXJlIHRha2VuIGZyb20gYSAqKm5vcm1hbCBkaXN0cmlidXRpb24qKi4gQWx0aG91Z2ggdGhpcyBpcyBub3QgYSByZWFzb25hYmxlIGFzc3VtcHRpb24sIHRoZSBzYW1wbGUgc2l6ZSBtaWdodCBiZSBzdWZmaWNpZW50bHkgbGFyZ2UgdG8gb3ZlcmNvbWUgdGhlIHNrZXduZXNzIGluIHRoZSBwYXJlbnQgcG9wdWxhdGlvbi4gQ29uc2VxdWVudGx5LCBvbmUgbWlnaHQgYXBwZWFsIHRvIHRoZSAqKkNlbnRyYWwgTGltaXQgVGhlb3JlbSoqIGFuZCBjbGFpbSB0aGF0IHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYFhgIGlzICoqYXBwcm94aW1hdGVseSBub3JtYWwqKiBkdWUgdG8gdGhlIHNhbXBsZSBzaXplIGAoNTApYC4gSW4gdGhpcyBwcm9ibGVtLCB0aGUgc2tld25lc3MgaXMgcXVpdGUgc2V2ZXJlLCBhbmQgb25lIHNob3VsZCBub3QgYmUgb3Zlcmx5IGNvbmZpZGVudCBpbiB0aGUgZmluYWwgaW50ZXJ2YWwuDQoNCihjKSBJZiB3ZSBhc3N1bWUgbm9ybWFsaXR5IG9uZSBoYXM6DQoNCmBgYHtyfQ0KIyBDSSA8LSB3aXRoKGRhdGEgPSBXQ1NULCB0LnRlc3Qoc2NvcmUpJGNvbmYpICMgDQoNCiMgb3IgdXNpbmcgcGlwaW5nDQpDSSA8LSBXQ1NUICU+JSBwdWxsKHNjb3JlKSAlPiUgdC50ZXN0KCkgJT4lIC4kY29uZg0KQ0kNCmBgYA0KDQooZCkgVXNlIHRoZSBgYm9vdC5jaSgpYCBub25wYXJhbWV0cmljIGJvb3RzdHJhcCBDSXMgZnVuY3Rpb25zIHRvIG9idGFpbiB0aGUgYm9vdHN0cmFwIENJLg0KDQpgYGB7cn0NCmxpYnJhcnkoYm9vdCkgIyB1c2UgYm9vdCBwYWNrYWdlDQpNRUFOIDwtIGZ1bmN0aW9uKGRhdGEsIGkpew0KICBkIDwtIGRhdGFbaV0NCiAgIE0gPC0gbWVhbihkKQ0KICB9DQoNCnNldC5zZWVkKDEzKQ0KDQpCIDwtIDEwXjQgLSAxICMgbnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzDQoNCmIub2JqIDwtIGJvb3QoZGF0YSA9IFdDU1Qkc2NvcmUsIHN0YXRpc3RpYyA9IE1FQU4sIFIgPSBCKSAjIGJvb3RzdHJhcCBvYmplY3Qgb2YgY2xhc3MgImJvb3QiIGNvbnRhaW5pbmcgdGhlIG91dHB1dCBvZiBhIGJvb3RzdHJhcCBjYWxjdWxhdGlvbg0KQ0lCIDwtIGJvb3QuY2koYi5vYmosIGNvbmYgPSAwLjk1LCB0eXBlID0gImJjYSIpDQpDSUINCmBgYA0KDQoqKlByb2JsZW0gMTIgKDEwIHB0cykqKiBTZXQgdGhlIHNlZWQgdG8gYDIzYCBpZiB5b3VyIGdyb3VwIGluZGV4IGlzIG9kZCBudW1iZXIgKGkuZS4gKipncm91cCAxLDMsNSw3KiopLCBhbmQgdGhlIHNlZWQgdG8gYDg5YCBpZiB5b3VyIGdyb3VwIGluZGV4IGlzIGV2ZW4gbnVtYmVyIChpLmUuICoqZ3JvdXAgMiw0LDYsOCoqKS4gRHJhdyBhIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSBgMjAwYCBmcm9tIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiB3aXRoIG1lYW4gJFxsYW1iZGEgPSA0JCAoJHJhdGUgPSBcZnJhY3sxfXs0fSQpLiBQcm9kdWNlIGFsbCBib290c3RyYXAgQ0kgd2l0aCB0aGUgZnVuY3Rpb24gYGJvb3QuY2lgICh1c2UgdHlwZSA9ICJhbGwiKS4NCg0KSG93IG1hbnkgb2YgdGhlbSBjb250YWluIHRoZSB0cnVlIG1lYW4gZm9yIHRoZSBzYW1wbGVkIGRpc3RyaWJ1dGlvbj8NCg0KKipZT1VSIENPREUgSEVSRToqKg0KDQpgYGB7cn0NCmxpYnJhcnkoYm9vdCkNCnNldC5zZWVkKDg5KQ0KDQoNCnN0YXQubWVhbiA9IGZ1bmN0aW9uKHgsIGluZHgpew0KICBtZWFuKCB4W2luZHhdICkNCn0NCg0KZXhwczIwMCA8LSByZXhwKDIwMCwuMjUpDQoNCmIub2JqIDwtIGJvb3QoZGF0YSA9IGV4cHMyMDAsIHN0YXRpc3RpYyA9IHN0YXQubWVhbiwgMjAwKQ0KQ0lCIDwtIGJvb3QuY2koYi5vYmosIHR5cGUgPSAiYWxsIikNCkNJQg0KDQojYm9vdHN0cmFwIHZhcmlhbmNlcyBuZWVkZWQgZm9yIHN0dWRlbnRpemVkIGludGVydmFscyB3YXJuaW5nDQoNCmBgYA0KDQoqKkVYVFJBIENSRURJVCAoMTAgcHRzKSoqIFNldCB0aGUgc2VlZCB0byBgMjNgIGlmIHlvdXIgZ3JvdXAgaW5kZXggaXMgb2RkIG51bWJlciAoaS5lLiAqKmdyb3VwIDEsMyw1LDcqKiksIGFuZCB0aGUgc2VlZCB0byBgODlgIGlmIHlvdXIgZ3JvdXAgaW5kZXggaXMgZXZlbiBudW1iZXIgKGkuZS4gKipncm91cCAyLDQsNiw4KiopLg0KDQpEcmF3IGEgcmFuZG9tIHNhbXBsZSBvZiBzaXplIGAyNWAgZnJvbSAkQmluKDIwLFxmcmFjezF9ezV9KSQuIFByb2R1Y2UgYWxsIGJvb3RzdHJhcCBDSSB3aXRoIHRoZSBmdW5jdGlvbiBgYm9vdC5jaWAgKHVzZSB0eXBlID0gImFsbCIpLg0KDQpIb3cgbWFueSBvZiB0aGVtIGNvbnRhaW4gdGhlIHRydWUgbWVhbiBmb3IgdGhlICRCaW4oMjAsXGZyYWN7MX17NX0pJD8NCg0KWU9VUiBDT0RFIEhFUkU6DQoNCmBgYHtyfQ0KbGlicmFyeShib290KQ0Kc2V0LnNlZWQoODkpIA0KDQpzdGF0Lm1lYW4gPSBmdW5jdGlvbih4LCBpbmR4KXsNCiAgbWVhbiggeFtpbmR4XSApDQp9DQpleHBzMjUgPC0gcmV4cCgyMCwxLzUpDQoNCmIub2JqIDwtIGJvb3QoZXhwczI1LCBzdGF0aXN0aWMgPSBzdGF0Lm1lYW4sIDEwMDAwKQ0KQ0lCIDwtIGJvb3QuY2koYi5vYmosIHR5cGUgPSAiYWxsIikNCkNJQg0KYGBgDQo=