Let us continue getting started with R as we start discussing important statistical concepts.
Case-scenario 1
Kate must take four quizzes in a math class. If her scores on the first three quizzes are 71, 69, and 79, what score does she need on the final quiz for her overall mean to be at least 70?
Solution
Given that \(x_1 = 71, x_2 = 69, x_3 = 79\)
we want to find \(x_4\) such that the mean (average) grade is \(\bar{x} >= 70\)
Notice that in this case \(n = 4\).
According to the information above: \(70 \times 4 = 71 + 69 + 79 + x_4\)
so when \(x_4 = 61\), the quiz average will be 70.
# Grades so far
grades_before <- c(71, 69, 79)
# Average quiz grade wanted
wanted_grade <- 70
# Number of quizzes
n_quizzes <- 4
# Needed grade on quiz 4
x_4 <- n_quizzes*wanted_grade - sum(grades_before)
# Minimum grade needed by Kate
x_4
[1] 61
According to the calculations above, Kate must score 61 or better on the final quiz to get an average quiz grade of at least 70.
We could confirm this, by using the function mean() in R
# Quiz grades
kate_grades <- c(71, 69, 79,61)
# Find mean
mean(kate_grades)
[1] 70
# Find standard deviation
sd(kate_grades)
[1] 7.393691
# Find maximum grade
max(kate_grades)
[1] 79
# Find minimum grade
min(kate_grades)
[1] 61
We can also use the summary() function to find basic statistics, including the median!
summary(kate_grades)
Min. 1st Qu. Median Mean 3rd Qu. Max.
61 67 70 70 73 79
Next, I would like you to explain in detail every single task we completed above. In addition, let us deal with a similar case scenario and complete every single task we execute in Case-scenario 1.
Frank must take six quizzes in a Physics class. If his scores on the first five quizzes are 41, 69,63,94, and 99, what score does he need on the final quiz for his overall mean to be at least 70?
# Created a vector name quiz_grades and in the vector using the c to combine the values 41,69,63,94,99 into the quiz_grades vector.
quiz_grades <- c(41,69,63,94,99)
# Create variable least_grade to to hold the value of 70 which is the least Frank can have to pass.
least_grade <- 70
# Create another variable nbr_of_quizzes this will contain the number of quizzes Frank must take.
nbr_quizzes <- 6
# Create a variable to hold the minimum grade needed in the last quiz to receive a 70. The formula for need_grade is the number of quizzes nbr_quizzes time the wanted grade least_grade subtracting the sum by using the sum function of previous 5 grades quiz_grades
needed_grade <- nbr_quizzes * least_grade - sum(quiz_grades)
# Display contents of the variable showing the minimum grade needed.
needed_grade
[1] 54
# Create another vector all_grades holds all the grades including the needed_grades
all_grades <- c(41,69,63,94,99,54)
# Display the vector all grades
all_grades
[1] 41 69 63 94 99 54
# We can confirm the results of needed_grade but using the mean function the mean function will divide the total of all grades and in this case divide by 6 to get the minimum grade if not mean is not 70 the the calculation where wrong.
mean(all_grades)
[1] 70
# To get the standard deviation function we use the sd function and the variable of all_grades. The standard deviation is a measure of the amount of variation or dispersion of a set of values.
sd(all_grades)
[1] 22.64509
# Use of the max function to retrieve the max/maximum number in the vector all_grades.
max(all_grades)
[1] 99
# Use of the min function to retrieve the min/minimum number in the vector all_grades.
min(all_grades)
[1] 41
# Summary function is used to produce results summary of all_grades which includes min, max 1st quantile, median, mean, 3rd quantile.
summary(all_grades)
Min. 1st Qu. Median Mean 3rd Qu. Max.
41.00 56.25 66.00 70.00 87.75 99.00
###Now let us go back to Case-scenario 1
Another useful function is quantile to find
# the 25%
quantile(kate_grades, 1/4)
25%
67
# the 75%
quantile(kate_grades, 3/4)
75%
73
# the function IQR finds the interquantile range
# IQR(x) = quantile(x, 3/4) - quantile(x, 1/4)
IQR(kate_grades)
[1] 6
Make comments about the output and run a similar query using Frank_grades
# Use the quantile function produces sample quantile to the given probabilities 1/4 or 25% values are sorted aded then broken into 4 quantile
# The retrieve the value in the 25% of the vector 1/4 by use of the quantile function returns 56.25.
quantile(all_grades, 1/4)
25%
56.25
# Use the quantile function produces sample quantile to the given probabilities 3/4 or 75% values are sorted added ?broken into 4 quantile 3/4 being next to the last
# The retrieve the value in the 75% of the vector 3/4 by use of the quantile function returns 87.75.
quantile(all_grades, 3/4)
75%
87.75
# The function IQR finds the interquantile range, this quantile(x, 3/4) specifies the median of n largest values and quantile(x, 1/4) specifies the median of the smallest values
# IQR(x) = quantile(x, 3/4) - quantile(x, 1/4)
IQR(all_grades)
[1] 31.5
Case-scenario 2
The average salary of 10 men is 72,000 and the average salary of 4 women is 84,000. Find the mean salary of all 14 people.
Solution
We can easily find the joined mean by adding both mean and dividing by the total number of people.
Let \(n_1 = 10\) denote the number of men, and \(y_1 = 72000\) their mean salary. Let \(n_2 = 4\) the number of women and \(y_2 = 84000\) their mean salary. Then the mean salary of all 16 individuals is: \(\frac{n_1 x_1 + n_2 x_2}{n_1 + n_2}\)
We can compute this in R as follows:
n_1 <- 10
n_2 <- 4
y_1 <- 72000
y_2 <- 84000
# Mean salary overall
salary_ave <- (n_1*y_1 + n_2*y_2)/(n_1+n_2)
salary_ave
[1] 75428.57
Solve a similar problem by changing number of men and women as well as the average income for each group. Make comments about the output.
# n_1 is as variable holding the number of men
n_1 <- 20
# n_1 is as variable holding the number of women
n_2 <- 10
# y_1 is a variable holding the men's salary
y_1 <- 200000
# y_1 is a variable holding the women's salary
y_2 <- 150000
# salary_ave is the variable hold Mean salary of both men and woman together, this is done by multiplying the number of men(n_1) times the men's salary(y_1) add to the number of women(y_1) times their salary(y_2)
salary_ave <- (n_1*y_1 + n_2*y_2)/(n_1+n_2)
# Display the contents of the variable salary_ave this will return salary of all 30 individuals 183,333.3
salary_ave
[1] 183333.3
Case-scenario 3
The frequency distribution below lists the results of a test given in Professor Wang’s String theory class.
| 10 |
5 |
| 9 |
10 |
| 8 |
6 |
| 7 |
8 |
| 6 |
3 |
| 5 |
2 |
Find the mean,the median and the standard deviation of the scores.
What percentage of the data lies within one standard deviation of the mean?
What percentage of the data lies within two standard deviations of the mean?
What percent of the data lies within three standard deviations of the mean?
Draw a histogram to illustrate the data.
Solution
The allScores.csv file contains all the students’ scores in the quiz. We can read this file in R using the read.csv() function (hint:First create a csv file with 6 rows and 2 columns)
getwd()
[1] "E:/School/Summer 2021/Security and Data Governance/Scripts"
scores <- read.table("allScores.csv", header = TRUE, sep = ",")
WangScores <- scores$Score
WangScores
[1] 10 9 8 7 6 5 10 10 10 10 9 9 9 9 9 9 9 9 9 8 8 8 8 8 7 7 7 7 7 7 7 6 6 5
Make comments about the code we just ran above.
#I was getting error where I could not retrieve the dataset. So I used the getwd() to get my working directory # I then put the dataset in that working directory to retrieve. # created a dataframe scores to the data from allScores.csv used read.table to create the dataframe in a table format. header = TRUE includes the header from the file to the data frame. And sep - ‘,’ is the data is a separated separator by commas
Create a variable WangScores to hold the data in scores table Score column.
[1] 10 9 8 7 6 5 10 10 10 10 9 9 9 9 9 9 9 9 9 8 8 8 8 8 7 7 7 7 7 7 7 6 6 5
1. To finding the mean,median, observations and the standard deviation
The mean = 8
The median = 8
The number of observations = 34
The Standard Deviation = 1.435481
# Mean
Scores_mean <- mean(WangScores)
Scores_mean
[1] 8
# Median
Scores_median <- median(WangScores)
Scores_median
[1] 8
# Find number of observations
Scores_n <- length(WangScores)
Scores_n
[1] 34
# Find standard deviation
Scores_sd <- sd(WangScores)
Scores_sd
[1] 1.435481
Following the empirical rule also referred as the Three Sigma Rule or the (68-95-99.7) Rule.
- What percentage of the data lies within one standard deviation of the mean? # 68% of the data lies within 0.8529412 of the mean 8.
scores_w1sd <- sum((WangScores - Scores_mean)/Scores_sd < 1)/ Scores_n
# Percentage of observation within one standard deviation of the mean
scores_w1sd
[1] 0.8529412
## Difference from empirical
scores_w1sd - 0.68
[1] 0.1729412
- What percentage of the data lies within two standard deviations of the mean? # # Would tell me that 95% of the data falls within 1 the mean of 8.
## Within 2 sd
scores_w2sd <- sum((WangScores - Scores_mean)/ Scores_sd < 2)/Scores_n
scores_w2sd
[1] 1
## Difference from empirical
scores_w2sd - 0.95
[1] 0.05
- What percent of the data lies within three standard deviations of the mean? # Would tell me that 99.7% of the data falls within 1 the mean of 8.
## Within 3 sd
scores_w3sd <- sum((WangScores - Scores_mean)/ Scores_sd < 3)/Scores_n
scores_w3sd
[1] 1
## Difference from empirical
scores_w3sd - 0.9973
[1] 0.0027
Explain the implications of the results obtained in this problem. # There is a wide range of scores and most fall between 2 and 3 standard deviations.
# Create histogram
hist(WangScores)

In addition, create a similar query but this time addressing Frank_Scores
- Draw a histogram Explain the output and create a similar histogram for Frank_Scores. # –
1. Create a variable for Frank_Scores
Frank_Scores <- c(41,69,63,94,99,54)
Frank_Scores
[1] 41 69 63 94 99 54
2. To find the mean, median and the standard deviation of Frank_Scores
The mean is 70
The median is 66
The number if observation are 6
The Standard Deviation is 22.64509
# Mean
Scores_mean <- mean(Frank_Scores)
Scores_mean
[1] 70
# Median
Scores_median <- median(Frank_Scores)
Scores_median
[1] 66
# Find number of observations
Scores_n <- length(Frank_Scores)
Scores_n
[1] 6
# Find standard deviation
Scores_sd <- sd(Frank_Scores)
Scores_sd
[1] 22.64509
2. Calculating the standard deviation by summing Frank_Score - the mean of Frank_Score divide by Standard Deviation < 1 and dividing that result by the number of observations Scores_n
Using the empirical rule (68-95-99.7) we know that 68% percent fall between 0.6666667 and the mean 70.
scores_w1sd <- sum((Frank_Scores - Scores_mean)/Scores_sd < 1)/ Scores_n
# Percentage of observation within one standard deviation of the mean
scores_w1sd
[1] 0.6666667
## Difference from empirical
scores_w1sd - 0.68
[1] -0.01333333
3. Calculating the standard deviation by summing Frank_Score - the mean of Frank_Score divide by Standard Deviation < 2 and dividing that result by the number of observations Scores_n.
Using the empirical rule (68-95-99.7) we know that 95% percent fall between 0.6666667 and the mean 70.
## Within 2 sd
scores_w2sd <- sum((Frank_Scores - Scores_mean)/ Scores_sd < 2)/Scores_n
scores_w2sd
[1] 1
## Difference from empirical
scores_w2sd - 0.95
[1] 0.05
4. Calculating the standard deviation by summing Frank_Score - the mean of Frank_Score divide by Standard Deviation < 3 and dividing that result by the number of observations Scores_n
Using the empirical rule (68-95-99.7) we know that 95.7% percent fall between 5.666667 and the mean 70.
## Within 3 sd
scores_w3sd <- sum((WangScores - Scores_mean)/ Scores_sd < 3)/Scores_n
scores_w3sd
[1] 5.666667
## Difference from empirical
scores_w3sd - 0.9973
[1] 4.669367
# Create histogram
hist(Frank_Scores)

Frank_Score is not showing much
LS0tDQp0aXRsZTogIkdldHRpbmcgU3RhcnRlZCB3aXRoIFIsUGFydCBJSSINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQpMZXQgdXMgY29udGludWUgZ2V0dGluZyBzdGFydGVkIHdpdGggUiBhcyB3ZSBzdGFydCBkaXNjdXNzaW5nIGltcG9ydGFudCBzdGF0aXN0aWNhbCBjb25jZXB0cy4NCg0KDQojIyBDYXNlLXNjZW5hcmlvIDENCkthdGUgbXVzdCB0YWtlIGZvdXIgcXVpenplcyBpbiBhIG1hdGggY2xhc3MuIElmIGhlciBzY29yZXMgb24gdGhlIGZpcnN0IHRocmVlIHF1aXp6ZXMgYXJlIDcxLCA2OSwgYW5kIDc5LCB3aGF0IHNjb3JlIGRvZXMgc2hlIG5lZWQgb24gdGhlIGZpbmFsIHF1aXogZm9yIGhlciBvdmVyYWxsIG1lYW4gdG8gYmUgYXQgbGVhc3QgNzA/DQoNCiMjIFNvbHV0aW9uDQoNCkdpdmVuIHRoYXQgDQokeF8xID0gNzEsIHhfMiA9IDY5LCB4XzMgPSA3OSQNCg0Kd2Ugd2FudCB0byBmaW5kICR4XzQkIHN1Y2ggdGhhdCB0aGUgbWVhbiAoYXZlcmFnZSkgZ3JhZGUgaXMgDQokXGJhcnt4fSA+PSA3MCQNCg0KTm90aWNlIHRoYXQgaW4gdGhpcyBjYXNlICRuID0gNCQuDQoNCkFjY29yZGluZyB0byB0aGUgaW5mb3JtYXRpb24gYWJvdmU6DQokNzAgXHRpbWVzIDQgPSA3MSArIDY5ICsgNzkgKyB4XzQkDQoNCnNvIHdoZW4gJHhfNCA9IDYxJCwgdGhlIHF1aXogYXZlcmFnZSB3aWxsIGJlIDcwLg0KDQoNCmBgYHtyfQ0KIyBHcmFkZXMgc28gZmFyDQpncmFkZXNfYmVmb3JlIDwtIGMoNzEsIDY5LCA3OSkNCiMgQXZlcmFnZSBxdWl6IGdyYWRlIHdhbnRlZA0Kd2FudGVkX2dyYWRlIDwtIDcwDQojIE51bWJlciBvZiBxdWl6emVzDQpuX3F1aXp6ZXMgPC0gNA0KIyBOZWVkZWQgZ3JhZGUgb24gcXVpeiA0DQp4XzQgPC0gbl9xdWl6emVzKndhbnRlZF9ncmFkZSAtIHN1bShncmFkZXNfYmVmb3JlKQ0KIyBNaW5pbXVtIGdyYWRlIG5lZWRlZCBieSBLYXRlDQp4XzQNCmBgYA0KDQpBY2NvcmRpbmcgdG8gdGhlIGNhbGN1bGF0aW9ucyBhYm92ZSwgS2F0ZSBtdXN0IHNjb3JlIDYxIG9yIGJldHRlciBvbiB0aGUgZmluYWwgcXVpeiB0byBnZXQgYW4gYXZlcmFnZSBxdWl6IGdyYWRlIG9mIGF0IGxlYXN0IDcwLg0KDQoNCldlIGNvdWxkIGNvbmZpcm0gdGhpcywgYnkgdXNpbmcgdGhlIGZ1bmN0aW9uIGBtZWFuKClgIGluIGBSYA0KDQpgYGB7cn0NCiMgUXVpeiBncmFkZXMNCmthdGVfZ3JhZGVzIDwtIGMoNzEsIDY5LCA3OSw2MSkNCiMgRmluZCBtZWFuDQptZWFuKGthdGVfZ3JhZGVzKQ0KIyBGaW5kIHN0YW5kYXJkIGRldmlhdGlvbg0Kc2Qoa2F0ZV9ncmFkZXMpDQojIEZpbmQgbWF4aW11bSBncmFkZQ0KbWF4KGthdGVfZ3JhZGVzKQ0KIyBGaW5kIG1pbmltdW0gZ3JhZGUNCm1pbihrYXRlX2dyYWRlcykNCmBgYA0KDQpXZSBjYW4gYWxzbyB1c2UgdGhlIGBzdW1tYXJ5KClgIGZ1bmN0aW9uIHRvIGZpbmQgYmFzaWMgc3RhdGlzdGljcywgaW5jbHVkaW5nIHRoZSBtZWRpYW4hDQoNCmBgYHtyfQ0Kc3VtbWFyeShrYXRlX2dyYWRlcykNCmBgYA0KTmV4dCwgSSB3b3VsZCBsaWtlIHlvdSB0byBleHBsYWluIGluIGRldGFpbCBldmVyeSBzaW5nbGUgdGFzayB3ZSBjb21wbGV0ZWQgYWJvdmUuIEluIGFkZGl0aW9uLCBsZXQgdXMgZGVhbCB3aXRoIGEgc2ltaWxhciBjYXNlIHNjZW5hcmlvIGFuZCBjb21wbGV0ZSBldmVyeSBzaW5nbGUgdGFzayB3ZSBleGVjdXRlIGluIENhc2Utc2NlbmFyaW8gMS4NCg0KRnJhbmsgbXVzdCB0YWtlIHNpeCBxdWl6emVzIGluIGEgUGh5c2ljcyBjbGFzcy4gSWYgaGlzIHNjb3JlcyBvbiB0aGUgZmlyc3QgZml2ZSBxdWl6emVzIGFyZSA0MSwgNjksNjMsOTQsIGFuZCA5OSwgd2hhdCBzY29yZSBkb2VzIGhlIG5lZWQgb24gdGhlIGZpbmFsIHF1aXogZm9yIGhpcyBvdmVyYWxsIG1lYW4gdG8gYmUgYXQgbGVhc3QgNzA/DQoNCg0KYGBge3J9DQojIENyZWF0ZWQgYSB2ZWN0b3IgbmFtZSBxdWl6X2dyYWRlcyBhbmQgaW4gdGhlIHZlY3RvciB1c2luZyB0aGUgYyB0byBjb21iaW5lIHRoZSB2YWx1ZXMgNDEsNjksNjMsOTQsOTkgaW50byB0aGUgcXVpel9ncmFkZXMgdmVjdG9yLg0KcXVpel9ncmFkZXMgPC0gYyg0MSw2OSw2Myw5NCw5OSkNCg0KIyBDcmVhdGUgdmFyaWFibGUgbGVhc3RfZ3JhZGUgdG8gdG8gaG9sZCB0aGUgdmFsdWUgb2YgNzAgd2hpY2ggaXMgdGhlIGxlYXN0IEZyYW5rIGNhbiBoYXZlIHRvIHBhc3MuDQpsZWFzdF9ncmFkZSA8LSA3MA0KDQojIENyZWF0ZSBhbm90aGVyIHZhcmlhYmxlIG5icl9vZl9xdWl6emVzIHRoaXMgd2lsbCBjb250YWluIHRoZSBudW1iZXIgb2YgcXVpenplcyBGcmFuayBtdXN0IHRha2UuDQpuYnJfcXVpenplcyA8LSA2DQoNCiMgQ3JlYXRlIGEgdmFyaWFibGUgdG8gaG9sZCB0aGUgbWluaW11bSBncmFkZSBuZWVkZWQgaW4gdGhlIGxhc3QgcXVpeiB0byByZWNlaXZlIGEgNzAuIFRoZSBmb3JtdWxhIGZvciBuZWVkX2dyYWRlIGlzIHRoZSBudW1iZXIgb2YgcXVpenplcyBuYnJfcXVpenplcyB0aW1lIHRoZSB3YW50ZWQgZ3JhZGUgbGVhc3RfZ3JhZGUgc3VidHJhY3RpbmcgdGhlIHN1bSBieSB1c2luZyB0aGUgc3VtIGZ1bmN0aW9uIG9mIHByZXZpb3VzIDUgZ3JhZGVzIHF1aXpfZ3JhZGVzDQpuZWVkZWRfZ3JhZGUgPC0gbmJyX3F1aXp6ZXMgKiBsZWFzdF9ncmFkZSAtIHN1bShxdWl6X2dyYWRlcykNCg0KIyBEaXNwbGF5IGNvbnRlbnRzIG9mIHRoZSB2YXJpYWJsZSBzaG93aW5nIHRoZSBtaW5pbXVtIGdyYWRlIG5lZWRlZC4NCm5lZWRlZF9ncmFkZQ0KYGBgDQoNCmBgYHtyfQ0KIyBDcmVhdGUgYW5vdGhlciB2ZWN0b3IgYWxsX2dyYWRlcyBob2xkcyBhbGwgdGhlIGdyYWRlcyBpbmNsdWRpbmcgdGhlIG5lZWRlZF9ncmFkZXMNCmFsbF9ncmFkZXMgPC0gYyg0MSw2OSw2Myw5NCw5OSw1NCkNCg0KIyBEaXNwbGF5IHRoZSB2ZWN0b3IgYWxsIGdyYWRlcw0KYWxsX2dyYWRlcw0KIyBXZSBjYW4gY29uZmlybSB0aGUgcmVzdWx0cyBvZiBuZWVkZWRfZ3JhZGUgYnV0IHVzaW5nIHRoZSBtZWFuIGZ1bmN0aW9uIHRoZSBtZWFuIGZ1bmN0aW9uIHdpbGwgZGl2aWRlIHRoZSB0b3RhbCBvZiBhbGwgZ3JhZGVzIGFuZCBpbiB0aGlzIGNhc2UgZGl2aWRlIGJ5IDYgdG8gZ2V0IHRoZSBtaW5pbXVtIGdyYWRlIGlmIG5vdCBtZWFuIGlzIG5vdCA3MCB0aGUgdGhlIGNhbGN1bGF0aW9uIHdoZXJlIHdyb25nLg0KbWVhbihhbGxfZ3JhZGVzKQ0KYGBgDQpgYGB7cn0NCiMgVG8gZ2V0IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gZnVuY3Rpb24gd2UgdXNlIHRoZSBzZCBmdW5jdGlvbiBhbmQgdGhlIHZhcmlhYmxlIG9mIGFsbF9ncmFkZXMuIFRoZSBzdGFuZGFyZCBkZXZpYXRpb24gaXMgYSBtZWFzdXJlIG9mIHRoZSBhbW91bnQgb2YgdmFyaWF0aW9uIG9yIGRpc3BlcnNpb24gb2YgYSBzZXQgb2YgdmFsdWVzLg0Kc2QoYWxsX2dyYWRlcykNCmBgYA0KDQpgYGB7cn0NCiMgVXNlIG9mIHRoZSBtYXggZnVuY3Rpb24gdG8gcmV0cmlldmUgdGhlIG1heC9tYXhpbXVtIG51bWJlciBpbiB0aGUgdmVjdG9yIGFsbF9ncmFkZXMuDQptYXgoYWxsX2dyYWRlcykNCmBgYA0KDQpgYGB7cn0NCiMgVXNlIG9mIHRoZSBtaW4gZnVuY3Rpb24gdG8gcmV0cmlldmUgdGhlIG1pbi9taW5pbXVtIG51bWJlciBpbiB0aGUgdmVjdG9yIGFsbF9ncmFkZXMuDQptaW4oYWxsX2dyYWRlcykNCmBgYA0KYGBge3J9DQojIFN1bW1hcnkgZnVuY3Rpb24gaXMgdXNlZCB0byBwcm9kdWNlIHJlc3VsdHMgc3VtbWFyeSBvZiBhbGxfZ3JhZGVzIHdoaWNoIGluY2x1ZGVzIG1pbiwgbWF4IDFzdCBxdWFudGlsZSwgbWVkaWFuLCBtZWFuLCAzcmQgcXVhbnRpbGUuDQpzdW1tYXJ5KGFsbF9ncmFkZXMpDQpgYGANCg0KIyMjTm93IGxldCB1cyBnbyBiYWNrIHRvIENhc2Utc2NlbmFyaW8gMQ0KDQpBbm90aGVyIHVzZWZ1bCBmdW5jdGlvbiBpcyBgcXVhbnRpbGVgIHRvIGZpbmQgDQoNCmBgYHtyfQ0KIyB0aGUgMjUlIA0KcXVhbnRpbGUoa2F0ZV9ncmFkZXMsIDEvNCkNCiMgdGhlIDc1JQ0KcXVhbnRpbGUoa2F0ZV9ncmFkZXMsIDMvNCkNCiMgdGhlIGZ1bmN0aW9uIElRUiBmaW5kcyB0aGUgaW50ZXJxdWFudGlsZSByYW5nZQ0KIyBJUVIoeCkgPSBxdWFudGlsZSh4LCAzLzQpIC0gcXVhbnRpbGUoeCwgMS80KQ0KSVFSKGthdGVfZ3JhZGVzKQ0KYGBgDQpNYWtlIGNvbW1lbnRzIGFib3V0IHRoZSBvdXRwdXQgYW5kIHJ1biBhIHNpbWlsYXIgcXVlcnkgdXNpbmcgRnJhbmtfZ3JhZGVzDQoNCmBgYHtyfQ0KIyBVc2UgdGhlIHF1YW50aWxlIGZ1bmN0aW9uIHByb2R1Y2VzIHNhbXBsZSBxdWFudGlsZSB0byB0aGUgZ2l2ZW4gcHJvYmFiaWxpdGllcyAxLzQgb3IgMjUlIHZhbHVlcyBhcmUgc29ydGVkIGFkZWQgdGhlbiBicm9rZW4gaW50byA0IHF1YW50aWxlDQojIFRoZSByZXRyaWV2ZSB0aGUgdmFsdWUgaW4gdGhlIDI1JSBvZiB0aGUgdmVjdG9yIDEvNCBieSB1c2Ugb2YgdGhlIHF1YW50aWxlIGZ1bmN0aW9uIHJldHVybnMgNTYuMjUuIA0KcXVhbnRpbGUoYWxsX2dyYWRlcywgMS80KQ0KIyBVc2UgdGhlIHF1YW50aWxlIGZ1bmN0aW9uIHByb2R1Y2VzIHNhbXBsZSBxdWFudGlsZSB0byB0aGUgZ2l2ZW4gcHJvYmFiaWxpdGllcyAzLzQgb3IgNzUlIHZhbHVlcyBhcmUgc29ydGVkIGFkZGVkID9icm9rZW4gaW50byA0IHF1YW50aWxlIDMvNCBiZWluZyBuZXh0IHRvIHRoZSBsYXN0DQojIFRoZSByZXRyaWV2ZSB0aGUgdmFsdWUgaW4gdGhlIDc1JSBvZiB0aGUgdmVjdG9yIDMvNCBieSB1c2Ugb2YgdGhlIHF1YW50aWxlIGZ1bmN0aW9uIHJldHVybnMgODcuNzUuDQpxdWFudGlsZShhbGxfZ3JhZGVzLCAzLzQpDQojIFRoZSBmdW5jdGlvbiBJUVIgZmluZHMgdGhlIGludGVycXVhbnRpbGUgcmFuZ2UsIHRoaXMgcXVhbnRpbGUoeCwgMy80KSBzcGVjaWZpZXMgdGhlIG1lZGlhbiBvZiBuIGxhcmdlc3QgdmFsdWVzIGFuZCBxdWFudGlsZSh4LCAxLzQpIHNwZWNpZmllcyB0aGUgbWVkaWFuIG9mIHRoZSBzbWFsbGVzdCB2YWx1ZXMNCiMgSVFSKHgpID0gcXVhbnRpbGUoeCwgMy80KSAtIHF1YW50aWxlKHgsIDEvNCkNCklRUihhbGxfZ3JhZGVzKQ0KYGBgDQoNCiMgQ2FzZS1zY2VuYXJpbyAyDQoNCg0KVGhlIGF2ZXJhZ2Ugc2FsYXJ5IG9mIDEwIG1lbiBpcyA3MiwwMDAgYW5kIHRoZSBhdmVyYWdlIHNhbGFyeSBvZiA0IHdvbWVuIGlzIDg0LDAwMC4gRmluZCB0aGUgbWVhbiBzYWxhcnkgb2YgYWxsIDE0IHBlb3BsZS4NCg0KIyMgU29sdXRpb24NCg0KV2UgY2FuIGVhc2lseSBmaW5kIHRoZSBqb2luZWQgbWVhbiBieSBhZGRpbmcgYm90aCBtZWFuIGFuZCBkaXZpZGluZyBieSB0aGUgdG90YWwgbnVtYmVyIG9mIHBlb3BsZS4NCg0KTGV0ICRuXzEgPSAxMCQgZGVub3RlIHRoZSBudW1iZXIgb2YgbWVuLCBhbmQgJHlfMSA9IDcyMDAwJCB0aGVpciBtZWFuIHNhbGFyeS4gTGV0ICRuXzIgPSA0JCB0aGUgbnVtYmVyIG9mIHdvbWVuIGFuZCAkeV8yID0gODQwMDAkIHRoZWlyIG1lYW4gc2FsYXJ5Lg0KVGhlbiB0aGUgbWVhbiBzYWxhcnkgb2YgYWxsIDE2IGluZGl2aWR1YWxzIGlzOg0KJFxmcmFje25fMSB4XzEgKyBuXzIgeF8yfXtuXzEgKyBuXzJ9JA0KDQpXZSBjYW4gY29tcHV0ZSB0aGlzIGluIFIgYXMgZm9sbG93czoNCg0KYGBge3J9DQpuXzEgPC0gMTANCm5fMiA8LSA0DQp5XzEgPC0gNzIwMDANCnlfMiA8LSA4NDAwMA0KIyBNZWFuIHNhbGFyeSBvdmVyYWxsDQpzYWxhcnlfYXZlIDwtICAobl8xKnlfMSArIG5fMip5XzIpLyhuXzErbl8yKQ0Kc2FsYXJ5X2F2ZQ0KYGBgDQoNClNvbHZlIGEgc2ltaWxhciBwcm9ibGVtIGJ5IGNoYW5naW5nIG51bWJlciBvZiBtZW4gYW5kIHdvbWVuIGFzIHdlbGwgYXMgdGhlIGF2ZXJhZ2UgaW5jb21lIGZvciBlYWNoIGdyb3VwLiBNYWtlIGNvbW1lbnRzIGFib3V0IHRoZSBvdXRwdXQuDQoNCmBgYHtyfQ0KIyBuXzEgaXMgYXMgdmFyaWFibGUgaG9sZGluZyB0aGUgbnVtYmVyIG9mIG1lbg0Kbl8xIDwtIDIwDQojIG5fMSBpcyBhcyB2YXJpYWJsZSBob2xkaW5nIHRoZSBudW1iZXIgb2Ygd29tZW4NCm5fMiA8LSAxMA0KIyB5XzEgaXMgYSB2YXJpYWJsZSBob2xkaW5nIHRoZSBtZW4ncyBzYWxhcnkNCnlfMSA8LSAyMDAwMDANCiMgeV8xIGlzIGEgdmFyaWFibGUgaG9sZGluZyB0aGUgd29tZW4ncyBzYWxhcnkNCnlfMiA8LSAxNTAwMDANCiMgc2FsYXJ5X2F2ZSBpcyB0aGUgdmFyaWFibGUgaG9sZCBNZWFuIHNhbGFyeSBvZiBib3RoIG1lbiBhbmQgd29tYW4gdG9nZXRoZXIsIHRoaXMgaXMgZG9uZSBieSBtdWx0aXBseWluZyB0aGUgbnVtYmVyIG9mIG1lbihuXzEpIHRpbWVzIHRoZSBtZW4ncyBzYWxhcnkoeV8xKSBhZGQgdG8gdGhlIG51bWJlciBvZiB3b21lbih5XzEpIHRpbWVzIHRoZWlyIHNhbGFyeSh5XzIpDQpzYWxhcnlfYXZlIDwtICAobl8xKnlfMSArIG5fMip5XzIpLyhuXzErbl8yKQ0KIyBEaXNwbGF5IHRoZSBjb250ZW50cyBvZiB0aGUgdmFyaWFibGUgc2FsYXJ5X2F2ZSB0aGlzIHdpbGwgcmV0dXJuIHNhbGFyeSBvZiBhbGwgMzAgaW5kaXZpZHVhbHMgMTgzLDMzMy4zIA0Kc2FsYXJ5X2F2ZQ0KYGBgDQoNCiMgQ2FzZS1zY2VuYXJpbyAzDQoNClRoZSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIGJlbG93IGxpc3RzIHRoZSByZXN1bHRzIG9mIGEgdGVzdCBnaXZlbiBpbiBQcm9mZXNzb3IgV2FuZydzIFN0cmluZyB0aGVvcnkgY2xhc3MuDQoNClNjb3JlICAgfCAgIE51bWJlciBvZiBzdHVkZW50cw0KLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KMTAgICAgICB8IDUNCjkgICAgICAgfCAxMA0KOCAgICAgICB8IDYNCjcgICAgICAgfCA4DQo2ICAgICAgIHwgMw0KNSAgICAgICB8IDINCg0KDQoNCjEuIEZpbmQgdGhlIG1lYW4sdGhlIG1lZGlhbiBhbmQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgc2NvcmVzLg0KDQoyLiBXaGF0IHBlcmNlbnRhZ2Ugb2YgdGhlIGRhdGEgbGllcyB3aXRoaW4gb25lIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgbWVhbj8NCg0KMy4gV2hhdCBwZXJjZW50YWdlIG9mIHRoZSBkYXRhIGxpZXMgd2l0aGluIHR3byBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIHRoZSBtZWFuPw0KDQo0LiBXaGF0IHBlcmNlbnQgb2YgdGhlIGRhdGEgbGllcyB3aXRoaW4gdGhyZWUgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgbWVhbj8gDQoNCjUuIERyYXcgYSBoaXN0b2dyYW0gdG8gaWxsdXN0cmF0ZSB0aGUgZGF0YS4gDQoNCiMjIFNvbHV0aW9uDQoNClRoZSBgYWxsU2NvcmVzLmNzdmAgZmlsZSBjb250YWlucyBhbGwgdGhlIHN0dWRlbnRzJyBzY29yZXMgaW4gdGhlIHF1aXouIFdlIGNhbiByZWFkIHRoaXMgZmlsZSBpbiBgUmAgdXNpbmcgdGhlIGByZWFkLmNzdigpYCBmdW5jdGlvbiAoaGludDpGaXJzdCBjcmVhdGUgYSBjc3YgZmlsZSB3aXRoIDYgcm93cyBhbmQgMiBjb2x1bW5zKQ0KDQpgYGB7cn0NCmdldHdkKCkNCnNjb3JlcyA8LSByZWFkLnRhYmxlKCJhbGxTY29yZXMuY3N2IiwgaGVhZGVyID0gVFJVRSwgc2VwID0gIiwiKQ0KV2FuZ1Njb3JlcyA8LSBzY29yZXMkU2NvcmUNCldhbmdTY29yZXMNCmBgYA0KDQpNYWtlIGNvbW1lbnRzIGFib3V0IHRoZSBjb2RlIHdlIGp1c3QgcmFuIGFib3ZlLiAgDQoNCiNJIHdhcyBnZXR0aW5nIGVycm9yIHdoZXJlIEkgY291bGQgbm90IHJldHJpZXZlIHRoZSBkYXRhc2V0LiBTbyBJIHVzZWQgdGhlIGdldHdkKCkgdG8gZ2V0IG15IHdvcmtpbmcgZGlyZWN0b3J5DQojIEkgdGhlbiBwdXQgdGhlIGRhdGFzZXQgaW4gdGhhdCB3b3JraW5nIGRpcmVjdG9yeSB0byByZXRyaWV2ZS4NCiMgY3JlYXRlZCBhIGRhdGFmcmFtZSBzY29yZXMgdG8gdGhlIGRhdGEgZnJvbSBhbGxTY29yZXMuY3N2IHVzZWQgcmVhZC50YWJsZSB0byBjcmVhdGUgdGhlIGRhdGFmcmFtZSBpbiBhIHRhYmxlIGZvcm1hdC4gaGVhZGVyID0gVFJVRSBpbmNsdWRlcyB0aGUgaGVhZGVyIGZyb20gdGhlIGZpbGUgdG8gdGhlIGRhdGEgZnJhbWUuIEFuZCBzZXAgLSAnLCcgaXMgdGhlIGRhdGEgaXMgYSBzZXBhcmF0ZWQgc2VwYXJhdG9yIGJ5IGNvbW1hcw0KDQojIENyZWF0ZSBhIHZhcmlhYmxlIFdhbmdTY29yZXMgdG8gaG9sZCB0aGUgZGF0YSBpbiBzY29yZXMgdGFibGUgU2NvcmUgY29sdW1uLg0KIyBbMV0gMTAgIDkgIDggIDcgIDYgIDUgMTAgMTAgMTAgMTAgIDkgIDkgIDkgIDkgIDkgIDkgIDkgIDkgIDkgIDggIDggIDggIDggIDggIDcgIDcgIDcgIDcgIDcgIDcgIDcgIDYgIDYgIDUNCg0KIyAxLiBUbyBmaW5kaW5nIHRoZSBtZWFuLG1lZGlhbiwgb2JzZXJ2YXRpb25zIGFuZCB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uDQojICAgIFRoZSBtZWFuID0gOA0KIyAgICBUaGUgbWVkaWFuID0gOA0KIyAgICBUaGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyA9IDM0DQojICAgIFRoZSBTdGFuZGFyZCBEZXZpYXRpb24gPSAxLjQzNTQ4MQ0KDQpgYGB7cn0NCiMgTWVhbiANClNjb3Jlc19tZWFuICA8LSBtZWFuKFdhbmdTY29yZXMpDQpTY29yZXNfbWVhbg0KIyBNZWRpYW4NClNjb3Jlc19tZWRpYW4gPC0gbWVkaWFuKFdhbmdTY29yZXMpDQpTY29yZXNfbWVkaWFuDQojIEZpbmQgbnVtYmVyIG9mIG9ic2VydmF0aW9ucw0KU2NvcmVzX24gPC0gbGVuZ3RoKFdhbmdTY29yZXMpDQpTY29yZXNfbg0KIyBGaW5kIHN0YW5kYXJkIGRldmlhdGlvbg0KU2NvcmVzX3NkIDwtIHNkKFdhbmdTY29yZXMpDQpTY29yZXNfc2QNCmBgYA0KIyBGb2xsb3dpbmcgdGhlIGVtcGlyaWNhbCBydWxlIGFsc28gcmVmZXJyZWQgYXMgdGhlIFRocmVlIFNpZ21hIFJ1bGUgb3IgdGhlICg2OC05NS05OS43KSBSdWxlLg0KMi4gV2hhdCBwZXJjZW50YWdlIG9mIHRoZSBkYXRhIGxpZXMgd2l0aGluIG9uZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG1lYW4/DQojIDY4JSBvZiB0aGUgZGF0YSBsaWVzIHdpdGhpbiAwLjg1Mjk0MTIgb2YgdGhlIG1lYW4gOC4NCg0KYGBge3J9DQpzY29yZXNfdzFzZCA8LSBzdW0oKFdhbmdTY29yZXMgLSBTY29yZXNfbWVhbikvU2NvcmVzX3NkIDwgMSkvIFNjb3Jlc19uDQojIFBlcmNlbnRhZ2Ugb2Ygb2JzZXJ2YXRpb24gd2l0aGluIG9uZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG1lYW4NCnNjb3Jlc193MXNkDQojIyBEaWZmZXJlbmNlIGZyb20gZW1waXJpY2FsIA0Kc2NvcmVzX3cxc2QgLSAwLjY4DQpgYGANCg0KMy4gV2hhdCBwZXJjZW50YWdlIG9mIHRoZSBkYXRhIGxpZXMgd2l0aGluIHR3byBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIHRoZSBtZWFuPw0KIyANCiMgV291bGQgdGVsbCBtZSB0aGF0IDk1JSBvZiB0aGUgZGF0YSBmYWxscyB3aXRoaW4gMSB0aGUgbWVhbiBvZiA4Lg0KDQpgYGB7cn0NCiMjIFdpdGhpbiAyIHNkDQpzY29yZXNfdzJzZCA8LSBzdW0oKFdhbmdTY29yZXMgLSBTY29yZXNfbWVhbikvIFNjb3Jlc19zZCA8IDIpL1Njb3Jlc19uDQpzY29yZXNfdzJzZA0KIyMgRGlmZmVyZW5jZSBmcm9tIGVtcGlyaWNhbCANCnNjb3Jlc193MnNkIC0gMC45NQ0KYGBgDQoNCjQuIFdoYXQgcGVyY2VudCBvZiB0aGUgZGF0YSBsaWVzIHdpdGhpbiB0aHJlZSBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIHRoZSBtZWFuPw0KIyAgV291bGQgdGVsbCBtZSB0aGF0IDk5LjclIG9mIHRoZSBkYXRhIGZhbGxzIHdpdGhpbiAxIHRoZSBtZWFuIG9mIDguDQoNCmBgYHtyfQ0KIyMgV2l0aGluIDMgc2QgDQpzY29yZXNfdzNzZCA8LSBzdW0oKFdhbmdTY29yZXMgLSBTY29yZXNfbWVhbikvIFNjb3Jlc19zZCA8IDMpL1Njb3Jlc19uDQpzY29yZXNfdzNzZA0KIyMgRGlmZmVyZW5jZSBmcm9tIGVtcGlyaWNhbCANCnNjb3Jlc193M3NkIC0gMC45OTczDQpgYGANCg0KRXhwbGFpbiB0aGUgaW1wbGljYXRpb25zIG9mIHRoZSByZXN1bHRzIG9idGFpbmVkIGluIHRoaXMgcHJvYmxlbS4NCiMgVGhlcmUgaXMgYSB3aWRlIHJhbmdlIG9mIHNjb3JlcyBhbmQgbW9zdCBmYWxsIGJldHdlZW4gMiBhbmQgMyBzdGFuZGFyZCBkZXZpYXRpb25zLg0KDQoNCg0KDQpgYGB7cn0NCiMgQ3JlYXRlIGhpc3RvZ3JhbQ0KaGlzdChXYW5nU2NvcmVzKQ0KYGBgDQpJbiBhZGRpdGlvbiwgY3JlYXRlIGEgc2ltaWxhciBxdWVyeSBidXQgdGhpcyB0aW1lIGFkZHJlc3NpbmcgRnJhbmtfU2NvcmVzDQoNCg0KNS4gRHJhdyBhIGhpc3RvZ3JhbQ0KRXhwbGFpbiB0aGUgb3V0cHV0IGFuZCBjcmVhdGUgYSBzaW1pbGFyIGhpc3RvZ3JhbSBmb3IgRnJhbmtfU2NvcmVzLg0KIyAtLQ0KDQoNCiMgMS4gQ3JlYXRlIGEgdmFyaWFibGUgZm9yIEZyYW5rX1Njb3Jlcw0KYGBge3J9DQpGcmFua19TY29yZXMgPC0gYyg0MSw2OSw2Myw5NCw5OSw1NCkNCkZyYW5rX1Njb3Jlcw0KYGBgDQojIDIuIFRvIGZpbmQgdGhlIG1lYW4sIG1lZGlhbiBhbmQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBGcmFua19TY29yZXMNCiMgICAgVGhlIG1lYW4gaXMgNzANCiMgICAgVGhlIG1lZGlhbiBpcyA2Ng0KIyAgICBUaGUgbnVtYmVyIGlmIG9ic2VydmF0aW9uIGFyZSA2DQojICAgIFRoZSBTdGFuZGFyZCBEZXZpYXRpb24gaXMgMjIuNjQ1MDkNCg0KDQpgYGB7cn0NCiMgTWVhbiANClNjb3Jlc19tZWFuICA8LSBtZWFuKEZyYW5rX1Njb3JlcykNClNjb3Jlc19tZWFuDQojIE1lZGlhbg0KU2NvcmVzX21lZGlhbiA8LSBtZWRpYW4oRnJhbmtfU2NvcmVzKQ0KU2NvcmVzX21lZGlhbg0KIyBGaW5kIG51bWJlciBvZiBvYnNlcnZhdGlvbnMNClNjb3Jlc19uIDwtIGxlbmd0aChGcmFua19TY29yZXMpDQpTY29yZXNfbg0KIyBGaW5kIHN0YW5kYXJkIGRldmlhdGlvbg0KU2NvcmVzX3NkIDwtIHNkKEZyYW5rX1Njb3JlcykNClNjb3Jlc19zZA0KYGBgDQoNCiMgMi4gQ2FsY3VsYXRpbmcgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBieSBzdW1taW5nIEZyYW5rX1Njb3JlIC0gdGhlIG1lYW4gb2YgRnJhbmtfU2NvcmUgZGl2aWRlIGJ5IFN0YW5kYXJkIERldmlhdGlvbiA8IDEgYW5kIGRpdmlkaW5nIHRoYXQgcmVzdWx0IGJ5IHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIFNjb3Jlc19uDQojIFVzaW5nIHRoZSBlbXBpcmljYWwgcnVsZSAoNjgtOTUtOTkuNykgd2Uga25vdyB0aGF0IDY4JSBwZXJjZW50IGZhbGwgYmV0d2VlbiAwLjY2NjY2NjcgYW5kIHRoZSBtZWFuIDcwLg0KYGBge3J9DQpzY29yZXNfdzFzZCA8LSBzdW0oKEZyYW5rX1Njb3JlcyAtIFNjb3Jlc19tZWFuKS9TY29yZXNfc2QgPCAxKS8gU2NvcmVzX24NCiMgUGVyY2VudGFnZSBvZiBvYnNlcnZhdGlvbiB3aXRoaW4gb25lIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgbWVhbg0Kc2NvcmVzX3cxc2QNCiMjIERpZmZlcmVuY2UgZnJvbSBlbXBpcmljYWwgDQpzY29yZXNfdzFzZCAtIDAuNjgNCmBgYA0KIyAzLiBDYWxjdWxhdGluZyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGJ5IHN1bW1pbmcgRnJhbmtfU2NvcmUgLSB0aGUgbWVhbiBvZiBGcmFua19TY29yZSBkaXZpZGUgYnkgU3RhbmRhcmQgRGV2aWF0aW9uIDwgMiBhbmQgZGl2aWRpbmcgdGhhdCByZXN1bHQgYnkgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgU2NvcmVzX24uDQoNCiMgVXNpbmcgdGhlIGVtcGlyaWNhbCBydWxlICg2OC05NS05OS43KSB3ZSBrbm93IHRoYXQgOTUlIHBlcmNlbnQgZmFsbCBiZXR3ZWVuIDAuNjY2NjY2NyBhbmQgdGhlIG1lYW4gNzAuDQpgYGB7cn0NCiMjIFdpdGhpbiAyIHNkDQpzY29yZXNfdzJzZCA8LSBzdW0oKEZyYW5rX1Njb3JlcyAtIFNjb3Jlc19tZWFuKS8gU2NvcmVzX3NkIDwgMikvU2NvcmVzX24NCnNjb3Jlc193MnNkDQojIyBEaWZmZXJlbmNlIGZyb20gZW1waXJpY2FsIA0Kc2NvcmVzX3cyc2QgLSAwLjk1DQpgYGANCiMgNC4gQ2FsY3VsYXRpbmcgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBieSBzdW1taW5nIEZyYW5rX1Njb3JlIC0gdGhlIG1lYW4gb2YgRnJhbmtfU2NvcmUgZGl2aWRlIGJ5IFN0YW5kYXJkIERldmlhdGlvbiA8IDMgYW5kIGRpdmlkaW5nIHRoYXQgcmVzdWx0IGJ5IHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIFNjb3Jlc19uDQojIFVzaW5nIHRoZSBlbXBpcmljYWwgcnVsZSAoNjgtOTUtOTkuNykgd2Uga25vdyB0aGF0IDk1LjclIHBlcmNlbnQgZmFsbCBiZXR3ZWVuIDUuNjY2NjY3IGFuZCB0aGUgbWVhbiA3MC4NCmBgYHtyfQ0KIyMgV2l0aGluIDMgc2QgDQpzY29yZXNfdzNzZCA8LSBzdW0oKEZyYW5rX1Njb3JlcyAtIFNjb3Jlc19tZWFuKS8gU2NvcmVzX3NkIDwgMykvU2NvcmVzX24NCnNjb3Jlc193M3NkDQojIyBEaWZmZXJlbmNlIGZyb20gZW1waXJpY2FsIA0Kc2NvcmVzX3czc2QgLSAwLjk5NzMNCmBgYA0KDQpgYGB7cn0NCiMgQ3JlYXRlIGhpc3RvZ3JhbQ0KaGlzdChGcmFua19TY29yZXMpDQpgYGANCiMgRnJhbmtfU2NvcmUgaXMgbm90IHNob3dpbmcgbXVjaCANCg==