#Addition

2-3
[1] -1
5-3
[1] 2
#Division

2/3
[1] 0.6666667
8/6
[1] 1.333333
#Exponentiation

2^3
[1] 8
10^2
[1] 100
#Square root

sqrt(2)
[1] 1.414214
sqrt(25)
[1] 5
#Logarithms. 

log(2) #This is a natural logarithm calculation
[1] 0.6931472
#to calculate the Log base 10, of 2:
log(2,10)
[1] 0.30103
#Question_1: Compute the log base 5 of 10 and the log of 10.

log(10, 5) #base 5 of 10
[1] 1.430677
log(10,10) #log of 10 base 10
[1] 1

Computing some offensive metrics in Baseball

#Batting Average=(No. of Hits)/(No. of At Bats)
#What is the batting average of a player that bats 29 hits in 112 at bats?

BA = 29/112
BA
[1] 0.2589286
  
#Round 3 decimal places

Batting_Average=round(BA,digits = 3)
Batting_Average
[1] 0.259
#Question_2:What is the batting average of a player that bats 42 hits in 212 at bats?

BA_2 = 42/212
BA_2
[1] 0.1981132
#On Base Percentage

#OBP=(H+BB+HBP)/(At Bats+H+BB+HBP+SF)

#Let us compute the OBP for a player with the following general stats
#AB=515,H=172,BB=84,HBP=5,SF=6

OBP=(172+84+5)/(515+172+84+5+6)
OBP
[1] 0.3337596
#Round 3 decimal places
OBP_rounded = round(OBP, 3)
OBP_rounded
[1] 0.334
#OBP=(H+BB+HBP)/(At Bats+H+BB+HBP+SF)

#Question_3:Compute the OBP for a player with the following general stats:
#AB=565,H=156,BB=65,HBP=3,SF=7

OBP_2 = (156+65+3) / (565+156+65+3+7)
OBP_2
[1] 0.281407

Often you will want to test whether something is less than, greater than or equal to something.

#Does 3 equals 8?
3 ==8
[1] FALSE
#does y = z?
x = y = 2
z = 2

y == z
[1] TRUE
#Is 3 different from 8
3 != 8
[1] TRUE
#Is y different from z
y != z
[1] FALSE
#Is 3 less than or equal to 8?
3 <= 8
[1] TRUE
#Is 2 less than or equal to y?
2 <= y
[1] TRUE
#Is 3 greater than 4?
3>4
[1] FALSE

The logical operators are & for logical AND, | for logical OR, and ! for NOT. These are some examples:

# Logical Disjunction (or)
FALSE | FALSE # False OR False
[1] FALSE
#Same for TRUE
TRUE | TRUE
[1] TRUE
# Logical Conjunction (and)
TRUE & FALSE #True AND False
[1] FALSE
TRUE & TRUE
[1] TRUE
#Negation

!TRUE #Simply the opposite
[1] FALSE
# Combination of statements
2 < 3 | 1 == 5 # 2<3 is True, 1==5 is False, True OR False is True
[1] TRUE

#Assigning Values to Variables In R, you create a variable and assign it a value using <- as follows

Total_Bases <- 6 + 5
Total_Bases*3
[1] 33

To see the variables that are currently defined, use ls (as in “list”)

ls()
 [1] "BA"                
 [2] "BA_2"              
 [3] "Batting_Average"   
 [4] "OBP"               
 [5] "OBP_2"             
 [6] "OBP_r"             
 [7] "OBP_rounded"       
 [8] "On_Base_Percentage"
 [9] "Total_Bases"       
[10] "x"                 
[11] "y"                 
[12] "z"                 
#Remove variables
rm(x,y,z)

Either <- or = can be used to assign a value to a variable, but I prefer <- because is less likely to be confused with the logical operator ==

#Vectors The basic type of object in R is a vector, which is an ordered list of values of the same type. You can create a vector using the c() function (as in “concatenate”).

pitches_by_innings <- c(12, 15, 10, 20, 10) 
pitches_by_innings
[1] 12 15 10 20 10
strikes_by_innings <- c(9, 12, 6, 14, 9)
strikes_by_innings
[1]  9 12  6 14  9
#Question_4: Define two vectors,runs_per_9innings and hits_per_9innings, each with five elements.

runs_per_9innings <- c(2,8,5,6,4)
runs_per_9innings
[1] 2 8 5 6 4
hits_per_9innings <- c(8,6,3,9,7)
hits_per_9innings
[1] 8 6 3 9 7

There are also some functions that will create vectors with regular patterns, like repeated elements.

#Replicate the function
rep(2,5)
[1] 2 2 2 2 2
rep(5,2)
[1] 5 5
rep(1,4)
[1] 1 1 1 1
#Consecutive numbers, this is inclusive
2:10
[1]  2  3  4  5  6  7  8  9 10
1:5
[1] 1 2 3 4 5
# sequence from 1 to 10 with a step of 2
seq(1, 10, by=2)
[1] 1 3 5 7 9
#sequence from 1 to 12 with a step of 3 
seq(1,12, by=3)
[1]  1  4  7 10
#sequence from 2 to 13 with a step of 3
seq(2,13,by=3)
[1]  2  5  8 11

Many functions and operators like + or - will work on all elements of the vector.

# add vectors
pitches_by_innings
[1] 12 15 10 20 10
strikes_by_innings
[1]  9 12  6 14  9
pitches_by_innings+strikes_by_innings
[1] 21 27 16 34 19
# compare vectors
pitches_by_innings == strikes_by_innings
[1] FALSE FALSE FALSE FALSE FALSE
# find length of vector
length(pitches_by_innings)
[1] 5
length(strikes_by_innings)
[1] 5
# find minimum value in vector
min(pitches_by_innings)
[1] 10
min(strikes_by_innings)
[1] 6
# find average value in vector
mean(pitches_by_innings)
[1] 13.4
mean(strikes_by_innings)
[1] 10

You can access parts of a vector by using [. Recall what the value is of the vector pitches_by_innings.

#Find the third element of the pitches_by_innings vector
pitches_by_innings[3]
[1] 10
#Question_5: Get the first element of hits_per_9innings.
hits_per_9innings[1]
[1] 8

If you want to get the last element of pitches_by_innings without explicitly typing the number of elements of pitches_by_innings, make use of the length function, which calculates the length of a vector:

pitches_by_innings[5] #reference the last element
[1] 10
#using the length function
pitches_by_innings[length(pitches_by_innings)]
[1] 10
#Question_6: Get the last element of hits_per_9innings.
hits_per_9innings[5]
[1] 7
hits_per_9innings[length(hits_per_9innings)]
[1] 7

You can also extract multiple values from a vector. For instance to get the 2nd through 4th values use

pitches_by_innings[c(2, 3, 4)]
[1] 15 10 20
pitches_by_innings[c(2:4)]
[1] 15 10 20

Vectors can also be strings or logical values

player_positions
[1] "catcher"     "pitcher"     "infielders"  "outfielders"

#Data Frames In statistical applications, data is often stored as a data frame, which is like a spreadsheet, with rows as observations and columns as variables.

To manually create a data frame, use the data.frame() function.

data.frame(bonus = c(2, 3, 1),#in millions 
           active_roster = c("yes", "no", "yes"), 
           salary = c(1.5, 2.5, 1))#in millions 

Most often you will be using data frames loaded from a file. For example, load the results of a fan’s survey. The function load or read.table can be used for this.

#How to Make a Random Sample

To randomly select a sample use the function sample(). The following code selects 5 numbers between 1 and 10 at random (without duplication)

sample(1:10, size=5)
[1]  4  7 10  8  9
#random sample from 80 to 900 of 3 numbers
sample(80:900, 3)
[1] 638 753 187
#the outcomes are not reproducible. Each time the cell is run the results will change

Taking a simple random sample from a data frame is only slightly more complicated, having two steps:

Use sample() to select a sample of size n from a vector of the row numbers of the data frame. Use the index operator [ to select those rows from the data frame. Consider the following example with fake data. First, make up a data frame with two columns. (LETTERS is a character vector of length 26 with capital letters “A” to “Z”; LETTERS is automatically defined and pre-loaded in R)

#The sample uses the first 10 letter of the alphabet
bar <- data.frame(var1= LETTERS[1:10], var2=1:10)

#check the data frame
bar

#if we add a third variable, it would look like
bar <- data.frame(var1= LETTERS[1:10], var2=1:10, var3=sample(1:20,2))
bar

Suppose you want to select a random sample of size 5. First, define a variable n with the size of the sample, i.e. 5

n <- 5

Now, select a sample of size 5 from the vector with 1 to 10 (the number of rows in bar). Use the function nrow() to find the number of rows in bar instead of manually entering that number.

Use : to create a vector with all the integers between 1 and the number of rows in bar.

samplerows <- sample(1:nrow(bar), size=n) 
# print sample rows
samplerows
[1]  4  5 10  8  1

The variable samplerows contains the rows of bar which make a random sample from all the rows in bar. Extract those rows from bar with

# extract rows
barsample <- bar[samplerows, ]
# print sample
print(barsample)

The code above creates a new data frame called barsample with a random sample of rows from bar.

In a single line of code

bar[sample(1:nrow(bar), n), ]

#Using Tables The table() command allows us to look at tables. Its simplest usage looks like table(x) where x is a categorical variable.

For example, a survey asks people if they support the home team or not. The data is

Yes, No, No, Yes, Yes

We can enter this into R with the c() command, and summarize with the table() command as follows

x <- c("Yes","No","No","Yes","Yes") 
table(x)
x
 No Yes 
  2   3 

#Numerical measures of center and spread Suppose, MLB Teams’ CEOs yearly compensations are sampled and the following are found (in millions)

12 .4 5 2 50 8 3 1 4 0.25

sals <- c(12, .4, 5, 2, 50, 8, 3, 1, 4, 0.25)

# the average salary among the CEO's in millions
mean(sals)
[1] 8.565
#the variance, which represents how far from the mean are all of the salaries
var(sals)
[1] 225.5145

The number above should be interpreted as thousands of dollars

#standard deviation, the deviation of the salaries from the mean
sd(sals)
[1] 15.01714
#the median
median(sals)
[1] 3.5
# Tukey's five number summary, usefull for boxplots
# five numbers: min, lower hinge, median, upper hinge, max
fivenum(sals)
[1]  0.25  1.00  3.50  8.00 50.00
# summary statistics
summary(sals)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.250   1.250   3.500   8.565   7.250  50.000 

#How about the mode? In R we can write our own functions, and a first example of a function is shown below in order to compute the mode of a vector of observations x

# Function to find the mode, i.e. most frequent value
getMode <- function(x) {
     ux <- unique(x)
     ux[which.max(tabulate(match(x, ux)))]
 }

As an example, we can use the function defined above to find the most frequent value of the number of pitches_by_innings

getMode(pitches_by_innings)
[1] 10
#Question_7: Find the most frequent value of hits_per_9innings.
getMode(hits_per_9innings)
[1] 8
game_day<-c("Saturday", "Saturday", "Sunday", "Monday", "Saturday","Tuesday", "Sunday", "Friday", "Friday", "Monday")

#Question_8: Summarize the following survey with the `table()` command:
table(game_day)
game_day
  Friday   Monday Saturday   Sunday  Tuesday 
       2        2        3        2        1 
#What is your favorite day of the week to watch baseball? A total of 10 fans submitted this survey.
getMode(game_day)
[1] "Saturday"
#Saturday, Saturday, Sunday, Monday, Saturday,Tuesday, Sunday, Friday, Friday, Monday
LS0tDQp0aXRsZTogRmlyc3QgU3RlcHMgd2l0aCBSIGFjdGl2aXR5IA0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCmBgYHtyfQ0KI0FkZGl0aW9uDQoyLTMNCjUtMw0KYGBgDQpgYGB7cn0NCiNEaXZpc2lvbg0KMi8zDQo4LzYNCmBgYA0KDQpgYGB7cn0NCiNFeHBvbmVudGlhdGlvbg0KMl4zDQoxMF4yDQpgYGANCg0KYGBge3J9DQojU3F1YXJlIHJvb3QNCnNxcnQoMikNCnNxcnQoMjUpDQoNCmBgYA0KDQpgYGB7cn0NCiNMb2dhcml0aG1zLiANCg0KbG9nKDIpICNUaGlzIGlzIGEgbmF0dXJhbCBsb2dhcml0aG0gY2FsY3VsYXRpb24NCg0KI3RvIGNhbGN1bGF0ZSB0aGUgTG9nIGJhc2UgMTAsIG9mIDI6DQpsb2coMiwxMCkNCg0KYGBgDQoNCmBgYHtyfQ0KI1F1ZXN0aW9uXzE6IENvbXB1dGUgdGhlIGxvZyBiYXNlIDUgb2YgMTAgYW5kIHRoZSBsb2cgb2YgMTAuDQoNCmxvZygxMCwgNSkgI2Jhc2UgNSBvZiAxMA0KbG9nKDEwLDEwKSAjbG9nIG9mIDEwIGJhc2UgMTANCmBgYA0KQ29tcHV0aW5nIHNvbWUgb2ZmZW5zaXZlIG1ldHJpY3MgaW4gQmFzZWJhbGwNCmBgYHtyfQ0KI0JhdHRpbmcgQXZlcmFnZT0oTm8uIG9mIEhpdHMpLyhOby4gb2YgQXQgQmF0cykNCiNXaGF0IGlzIHRoZSBiYXR0aW5nIGF2ZXJhZ2Ugb2YgYSBwbGF5ZXIgdGhhdCBiYXRzIDI5IGhpdHMgaW4gMTEyIGF0IGJhdHM/DQoNCkJBID0gMjkvMTEyDQpCQQ0KICANCmBgYA0KDQpgYGB7cn0NCiNSb3VuZCAzIGRlY2ltYWwgcGxhY2VzDQoNCkJhdHRpbmdfQXZlcmFnZT1yb3VuZChCQSxkaWdpdHMgPSAzKQ0KQmF0dGluZ19BdmVyYWdlDQpgYGANCg0KYGBge3J9DQojUXVlc3Rpb25fMjpXaGF0IGlzIHRoZSBiYXR0aW5nIGF2ZXJhZ2Ugb2YgYSBwbGF5ZXIgdGhhdCBiYXRzIDQyIGhpdHMgaW4gMjEyIGF0IGJhdHM/DQoNCkJBXzIgPSA0Mi8yMTINCkJBXzINCmBgYA0KDQpgYGB7cn0NCiNPbiBCYXNlIFBlcmNlbnRhZ2UNCg0KI09CUD0oSCtCQitIQlApLyhBdCBCYXRzK0grQkIrSEJQK1NGKQ0KDQojTGV0IHVzIGNvbXB1dGUgdGhlIE9CUCBmb3IgYSBwbGF5ZXIgd2l0aCB0aGUgZm9sbG93aW5nIGdlbmVyYWwgc3RhdHMNCiNBQj01MTUsSD0xNzIsQkI9ODQsSEJQPTUsU0Y9Ng0KDQpPQlA9KDE3Mis4NCs1KS8oNTE1KzE3Mis4NCs1KzYpDQpPQlANCmBgYA0KDQpgYGB7cn0NCiNSb3VuZCAzIGRlY2ltYWwgcGxhY2VzDQpPQlBfcm91bmRlZCA9IHJvdW5kKE9CUCwgMykNCk9CUF9yb3VuZGVkDQpgYGANCg0KYGBge3J9DQojT0JQPShIK0JCK0hCUCkvKEF0IEJhdHMrSCtCQitIQlArU0YpDQoNCiNRdWVzdGlvbl8zOkNvbXB1dGUgdGhlIE9CUCBmb3IgYSBwbGF5ZXIgd2l0aCB0aGUgZm9sbG93aW5nIGdlbmVyYWwgc3RhdHM6DQojQUI9NTY1LEg9MTU2LEJCPTY1LEhCUD0zLFNGPTcNCg0KT0JQXzIgPSAoMTU2KzY1KzMpIC8gKDU2NSsxNTYrNjUrMys3KQ0KT0JQXzINCmBgYA0KDQpPZnRlbiB5b3Ugd2lsbCB3YW50IHRvIHRlc3Qgd2hldGhlciBzb21ldGhpbmcgaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gc29tZXRoaW5nLg0KYGBge3J9DQojRG9lcyAzIGVxdWFscyA4Pw0KMyA9PTgNCg0KI2RvZXMgeSA9IHo/DQp4ID0geSA9IDINCnogPSAyDQoNCnkgPT0geg0KYGBgDQoNCmBgYHtyfQ0KI0lzIDMgZGlmZmVyZW50IGZyb20gOA0KMyAhPSA4DQoNCiNJcyB5IGRpZmZlcmVudCBmcm9tIHoNCnkgIT0geg0KYGBgDQoNCmBgYHtyfQ0KI0lzIDMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDg/DQozIDw9IDgNCg0KI0lzIDIgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHk/DQoyIDw9IHkNCmBgYA0KDQpgYGB7cn0NCiNJcyAzIGdyZWF0ZXIgdGhhbiA0Pw0KMz40DQpgYGANClRoZSBsb2dpY2FsIG9wZXJhdG9ycyBhcmUgJiBmb3IgbG9naWNhbCBBTkQsIHwgZm9yIGxvZ2ljYWwgT1IsIGFuZCAhIGZvciBOT1QuIFRoZXNlIGFyZSBzb21lIGV4YW1wbGVzOg0KYGBge3J9DQojIExvZ2ljYWwgRGlzanVuY3Rpb24gKG9yKQ0KRkFMU0UgfCBGQUxTRSAjIEZhbHNlIE9SIEZhbHNlDQpgYGANCg0KYGBge3J9DQojU2FtZSBmb3IgVFJVRQ0KVFJVRSB8IFRSVUUNCmBgYA0KDQpgYGB7cn0NCiMgTG9naWNhbCBDb25qdW5jdGlvbiAoYW5kKQ0KVFJVRSAmIEZBTFNFICNUcnVlIEFORCBGYWxzZQ0KDQpUUlVFICYgVFJVRQ0KYGBgDQoNCmBgYHtyfQ0KI05lZ2F0aW9uDQoNCiFUUlVFICNTaW1wbHkgdGhlIG9wcG9zaXRlDQpgYGANCg0KYGBge3J9DQojIENvbWJpbmF0aW9uIG9mIHN0YXRlbWVudHMNCjIgPCAzIHwgMSA9PSA1ICMgMjwzIGlzIFRydWUsIDE9PTUgaXMgRmFsc2UsIFRydWUgT1IgRmFsc2UgaXMgVHJ1ZQ0KYGBgDQojQXNzaWduaW5nIFZhbHVlcyB0byBWYXJpYWJsZXMNCkluIFIsIHlvdSBjcmVhdGUgYSB2YXJpYWJsZSBhbmQgYXNzaWduIGl0IGEgdmFsdWUgdXNpbmcgPC0gYXMgZm9sbG93cw0KYGBge3J9DQpUb3RhbF9CYXNlcyA8LSA2ICsgNQ0KVG90YWxfQmFzZXMqMw0KYGBgDQpUbyBzZWUgdGhlIHZhcmlhYmxlcyB0aGF0IGFyZSBjdXJyZW50bHkgZGVmaW5lZCwgdXNlIGxzIChhcyBpbiDigJxsaXN04oCdKQ0KYGBge3J9DQojTGlzdCBvZiB2YXJpYWJsZXMgc2F2ZWQNCmxzKCkNCmBgYA0KYGBge3J9DQojUmVtb3ZlIHZhcmlhYmxlcw0Kcm0oeCx5LHopDQpgYGANCg0KRWl0aGVyIDwtIG9yID0gY2FuIGJlIHVzZWQgdG8gYXNzaWduIGEgdmFsdWUgdG8gYSB2YXJpYWJsZSwgYnV0IEkgcHJlZmVyIDwtIGJlY2F1c2UgaXMgbGVzcyBsaWtlbHkgdG8gYmUgY29uZnVzZWQgd2l0aCB0aGUgbG9naWNhbCBvcGVyYXRvciA9PQ0KDQojVmVjdG9ycw0KVGhlIGJhc2ljIHR5cGUgb2Ygb2JqZWN0IGluIFIgaXMgYSB2ZWN0b3IsIHdoaWNoIGlzIGFuIG9yZGVyZWQgbGlzdCBvZiB2YWx1ZXMgb2YgdGhlIHNhbWUgdHlwZS4gWW91IGNhbiBjcmVhdGUgYSB2ZWN0b3IgdXNpbmcgdGhlIGMoKSBmdW5jdGlvbiAoYXMgaW4g4oCcY29uY2F0ZW5hdGXigJ0pLg0KYGBge3J9DQpwaXRjaGVzX2J5X2lubmluZ3MgPC0gYygxMiwgMTUsIDEwLCAyMCwgMTApIA0KcGl0Y2hlc19ieV9pbm5pbmdzDQpgYGANCg0KYGBge3J9DQpzdHJpa2VzX2J5X2lubmluZ3MgPC0gYyg5LCAxMiwgNiwgMTQsIDkpDQpzdHJpa2VzX2J5X2lubmluZ3MNCmBgYA0KDQpgYGB7cn0NCiNRdWVzdGlvbl80OiBEZWZpbmUgdHdvIHZlY3RvcnMscnVuc19wZXJfOWlubmluZ3MgYW5kIGhpdHNfcGVyXzlpbm5pbmdzLCBlYWNoIHdpdGggZml2ZSBlbGVtZW50cy4NCg0KcnVuc19wZXJfOWlubmluZ3MgPC0gYygyLDgsNSw2LDQpDQpydW5zX3Blcl85aW5uaW5ncw0KDQpoaXRzX3Blcl85aW5uaW5ncyA8LSBjKDgsNiwzLDksNykNCmhpdHNfcGVyXzlpbm5pbmdzDQpgYGANCg0KVGhlcmUgYXJlIGFsc28gc29tZSBmdW5jdGlvbnMgdGhhdCB3aWxsIGNyZWF0ZSB2ZWN0b3JzIHdpdGggcmVndWxhciBwYXR0ZXJucywgbGlrZSByZXBlYXRlZCBlbGVtZW50cy4NCmBgYHtyfQ0KI1JlcGxpY2F0ZSB0aGUgZnVuY3Rpb24NCnJlcCgyLDUpDQpyZXAoNSwyKQ0KcmVwKDEsNCkNCmBgYA0KYGBge3J9DQojQ29uc2VjdXRpdmUgbnVtYmVycywgdGhpcyBpcyBpbmNsdXNpdmUNCjI6MTANCjE6NQ0KYGBgDQoNCmBgYHtyfQ0KIyBzZXF1ZW5jZSBmcm9tIDEgdG8gMTAgd2l0aCBhIHN0ZXAgb2YgMg0Kc2VxKDEsIDEwLCBieT0yKQ0KDQojc2VxdWVuY2UgZnJvbSAxIHRvIDEyIHdpdGggYSBzdGVwIG9mIDMgDQpzZXEoMSwxMiwgYnk9MykNCg0KI3NlcXVlbmNlIGZyb20gMiB0byAxMyB3aXRoIGEgc3RlcCBvZiAzDQpzZXEoMiwxMyxieT0zKQ0KYGBgDQpNYW55IGZ1bmN0aW9ucyBhbmQgb3BlcmF0b3JzIGxpa2UgKyBvciAtIHdpbGwgd29yayBvbiBhbGwgZWxlbWVudHMgb2YgdGhlIHZlY3Rvci4NCmBgYHtyfQ0KIyBhZGQgdmVjdG9ycywgdGhpcyBhZGRzIHRoZSBmaXJzdCBlbGVtZW50IG9mIGVhY2ggdmVjdG9yIHRvIGdldCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUgcmVzdWx0aW5nIHZlY3RvciBhbmQgc28gb24uLi4NCg0KcGl0Y2hlc19ieV9pbm5pbmdzDQpzdHJpa2VzX2J5X2lubmluZ3MNCg0KcGl0Y2hlc19ieV9pbm5pbmdzK3N0cmlrZXNfYnlfaW5uaW5ncw0KYGBgDQoNCmBgYHtyfQ0KIyBjb21wYXJlIHZlY3RvcnMsIHRoaXMgd2lsbCBjb21wYXJlIGVhY2ggZWxlbWVudCByZXNwZWN0aXZlbHkgb2YgdGhlIGZpcnN0IHZlY3RvciB0byB0aGUgb25lIGluIHRoZSBzZWNvbmQgdmVjdG9yDQpwaXRjaGVzX2J5X2lubmluZ3MgPT0gc3RyaWtlc19ieV9pbm5pbmdzDQpgYGANCg0KYGBge3J9DQojIGZpbmQgbGVuZ3RoIG9mIHZlY3Rvcg0KbGVuZ3RoKHBpdGNoZXNfYnlfaW5uaW5ncykNCmxlbmd0aChzdHJpa2VzX2J5X2lubmluZ3MpDQpgYGANCg0KYGBge3J9DQojIGZpbmQgbWluaW11bSB2YWx1ZSBpbiB2ZWN0b3INCm1pbihwaXRjaGVzX2J5X2lubmluZ3MpDQptaW4oc3RyaWtlc19ieV9pbm5pbmdzKQ0KYGBgDQoNCmBgYHtyfQ0KIyBmaW5kIGF2ZXJhZ2UgdmFsdWUgaW4gdmVjdG9yDQptZWFuKHBpdGNoZXNfYnlfaW5uaW5ncykNCm1lYW4oc3RyaWtlc19ieV9pbm5pbmdzKQ0KYGBgDQpZb3UgY2FuIGFjY2VzcyBwYXJ0cyBvZiBhIHZlY3RvciBieSB1c2luZyBbLiBSZWNhbGwgd2hhdCB0aGUgdmFsdWUgaXMgb2YgdGhlIHZlY3RvciBwaXRjaGVzX2J5X2lubmluZ3MuDQpgYGB7cn0NCnBpdGNoZXNfYnlfaW5uaW5ncw0KDQojRmluZCB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGUgcGl0Y2hlc19ieV9pbm5pbmdzIHZlY3Rvcg0KcGl0Y2hlc19ieV9pbm5pbmdzWzFdDQoNCiNGaW5kIHRoZSB0aGlyZCBlbGVtZW50IG9mIHRoZSBwaXRjaGVzX2J5X2lubmluZ3MgdmVjdG9yDQpwaXRjaGVzX2J5X2lubmluZ3NbM10NCmBgYA0KDQpgYGB7cn0NCiNRdWVzdGlvbl81OiBHZXQgdGhlIGZpcnN0IGVsZW1lbnQgb2YgaGl0c19wZXJfOWlubmluZ3MuDQpoaXRzX3Blcl85aW5uaW5nc1sxXQ0KYGBgDQoNCklmIHlvdSB3YW50IHRvIGdldCB0aGUgbGFzdCBlbGVtZW50IG9mIHBpdGNoZXNfYnlfaW5uaW5ncyB3aXRob3V0IGV4cGxpY2l0bHkgdHlwaW5nIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgb2YgcGl0Y2hlc19ieV9pbm5pbmdzLCBtYWtlIHVzZSBvZiB0aGUgbGVuZ3RoIGZ1bmN0aW9uLCB3aGljaCBjYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgYSB2ZWN0b3I6DQpgYGB7cn0NCnBpdGNoZXNfYnlfaW5uaW5nc1s1XSAjcmVmZXJlbmNlIHRoZSBsYXN0IGVsZW1lbnQNCg0KI3VzaW5nIHRoZSBsZW5ndGggZnVuY3Rpb24NCnBpdGNoZXNfYnlfaW5uaW5nc1tsZW5ndGgocGl0Y2hlc19ieV9pbm5pbmdzKV0NCmBgYA0KDQpgYGB7cn0NCiNRdWVzdGlvbl82OiBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBoaXRzX3Blcl85aW5uaW5ncy4NCmhpdHNfcGVyXzlpbm5pbmdzWzVdDQpoaXRzX3Blcl85aW5uaW5nc1tsZW5ndGgoaGl0c19wZXJfOWlubmluZ3MpXQ0KYGBgDQoNCllvdSBjYW4gYWxzbyBleHRyYWN0IG11bHRpcGxlIHZhbHVlcyBmcm9tIGEgdmVjdG9yLiBGb3IgaW5zdGFuY2UgdG8gZ2V0IHRoZSAybmQgdGhyb3VnaCA0dGggdmFsdWVzIHVzZQ0KYGBge3J9DQpwaXRjaGVzX2J5X2lubmluZ3NbYygyLCAzLCA0KV0NCnBpdGNoZXNfYnlfaW5uaW5nc1tjKDI6NCldICNzZWNvbmQgd2F5IA0KYGBgDQpWZWN0b3JzIGNhbiBhbHNvIGJlIHN0cmluZ3Mgb3IgbG9naWNhbCB2YWx1ZXMNCmBgYHtyfQ0KcGxheWVyX3Bvc2l0aW9ucyA8LSBjKCJjYXRjaGVyIiwgInBpdGNoZXIiLCAiaW5maWVsZGVycyIsICJvdXRmaWVsZGVycyIpDQpwbGF5ZXJfcG9zaXRpb25zDQpgYGANCiNEYXRhIEZyYW1lcw0KSW4gc3RhdGlzdGljYWwgYXBwbGljYXRpb25zLCBkYXRhIGlzIG9mdGVuIHN0b3JlZCBhcyBhIGRhdGEgZnJhbWUsIHdoaWNoIGlzIGxpa2UgYSBzcHJlYWRzaGVldCwgd2l0aCByb3dzIGFzIG9ic2VydmF0aW9ucyBhbmQgY29sdW1ucyBhcyB2YXJpYWJsZXMuDQoNClRvIG1hbnVhbGx5IGNyZWF0ZSBhIGRhdGEgZnJhbWUsIHVzZSB0aGUgZGF0YS5mcmFtZSgpIGZ1bmN0aW9uLg0KYGBge3J9IA0KI3RoaXMgd29ya3Mgb24gYSBrZXksIHZhbHVlIGZhc2hpb24gSyA9IFYgb3IgYyh4LHgseCkNCg0KZGF0YS5mcmFtZShib251cyA9IGMoMiwgMywgMSksI2luIG1pbGxpb25zIA0KICAgICAgICAgICBhY3RpdmVfcm9zdGVyID0gYygieWVzIiwgIm5vIiwgInllcyIpLCANCiAgICAgICAgICAgc2FsYXJ5ID0gYygxLjUsIDIuNSwgMSkpI2luIG1pbGxpb25zIA0KYGBgDQpNb3N0IG9mdGVuIHlvdSB3aWxsIGJlIHVzaW5nIGRhdGEgZnJhbWVzIGxvYWRlZCBmcm9tIGEgZmlsZS4gRm9yIGV4YW1wbGUsIGxvYWQgdGhlIHJlc3VsdHMgb2YgYSBmYW7igJlzIHN1cnZleS4gVGhlIGZ1bmN0aW9uIGxvYWQgb3IgcmVhZC50YWJsZSBjYW4gYmUgdXNlZCBmb3IgdGhpcy4NCg0KI0hvdyB0byBNYWtlIGEgUmFuZG9tIFNhbXBsZQ0KDQpUbyByYW5kb21seSBzZWxlY3QgYSBzYW1wbGUgdXNlIHRoZSBmdW5jdGlvbiBzYW1wbGUoKS4gVGhlIGZvbGxvd2luZyBjb2RlIHNlbGVjdHMgNSBudW1iZXJzIGJldHdlZW4gMSBhbmQgMTAgYXQgcmFuZG9tICh3aXRob3V0IGR1cGxpY2F0aW9uKQ0KYGBge3J9DQpzYW1wbGUoMToxMCwgc2l6ZT01KQ0KDQojcmFuZG9tIHNhbXBsZSBmcm9tIDgwIHRvIDkwMCBvZiAzIG51bWJlcnMNCnNhbXBsZSg4MDo5MDAsIDMpDQoNCiN0aGUgb3V0Y29tZXMgYXJlIG5vdCByZXByb2R1Y2libGUuIEVhY2ggdGltZSB0aGUgY2VsbCBpcyBydW4gdGhlIHJlc3VsdHMgd2lsbCBjaGFuZ2UNCmBgYA0KKiBUaGUgZmlyc3QgYXJndW1lbnQgZ2l2ZXMgdGhlIHZlY3RvciBvZiBkYXRhIHRvIHNlbGVjdCBlbGVtZW50cyBmcm9tLg0KKiBUaGUgc2Vjb25kIGFyZ3VtZW50IChzaXplPSkgZ2l2ZXMgdGhlIHNpemUgb2YgdGhlIHNhbXBsZSB0byBzZWxlY3QuDQoNClRha2luZyBhIHNpbXBsZSByYW5kb20gc2FtcGxlIGZyb20gYSBkYXRhIGZyYW1lIGlzIG9ubHkgc2xpZ2h0bHkgbW9yZSBjb21wbGljYXRlZCwgaGF2aW5nIHR3byBzdGVwczoNCg0KVXNlIHNhbXBsZSgpIHRvIHNlbGVjdCBhIHNhbXBsZSBvZiBzaXplIG4gZnJvbSBhIHZlY3RvciBvZiB0aGUgcm93IG51bWJlcnMgb2YgdGhlIGRhdGEgZnJhbWUuDQpVc2UgdGhlIGluZGV4IG9wZXJhdG9yIFsgdG8gc2VsZWN0IHRob3NlIHJvd3MgZnJvbSB0aGUgZGF0YSBmcmFtZS4NCkNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSB3aXRoIGZha2UgZGF0YS4gRmlyc3QsIG1ha2UgdXAgYSBkYXRhIGZyYW1lIHdpdGggdHdvIGNvbHVtbnMuIChMRVRURVJTIGlzIGEgY2hhcmFjdGVyIHZlY3RvciBvZiBsZW5ndGggMjYgd2l0aCBjYXBpdGFsIGxldHRlcnMgw6LCgMKcQcOiwoDCnSB0byDDosKAwpxaw6LCgMKdOyBMRVRURVJTIGlzIGF1dG9tYXRpY2FsbHkgZGVmaW5lZCBhbmQgcHJlLWxvYWRlZCBpbiBSKQ0KYGBge3J9DQojVGhlIHNhbXBsZSB1c2VzIHRoZSBmaXJzdCAxMCBsZXR0ZXIgb2YgdGhlIGFscGhhYmV0DQpiYXIgPC0gZGF0YS5mcmFtZSh2YXIxPSBMRVRURVJTWzE6MTBdLCB2YXIyPTE6MTApDQoNCiNjaGVjayB0aGUgZGF0YSBmcmFtZQ0KYmFyDQoNCiNpZiB3ZSBhZGQgYSB0aGlyZCB2YXJpYWJsZSwgaXQgd291bGQgbG9vayBsaWtlDQpiYXIgPC0gZGF0YS5mcmFtZSh2YXIxPSBMRVRURVJTWzE6MTBdLCB2YXIyPTE6MTAsIHZhcjM9c2FtcGxlKDE6MjAsMikpDQpiYXINCmBgYA0KDQpTdXBwb3NlIHlvdSB3YW50IHRvIHNlbGVjdCBhIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSA1LiBGaXJzdCwgZGVmaW5lIGEgdmFyaWFibGUgbiB3aXRoIHRoZSBzaXplIG9mIHRoZSBzYW1wbGUsIGkuZS4gNQ0KYGBge3J9DQpuIDwtIDUNCmBgYA0KDQpOb3csIHNlbGVjdCBhIHNhbXBsZSBvZiBzaXplIDUgZnJvbSB0aGUgdmVjdG9yIHdpdGggMSB0byAxMCAodGhlIG51bWJlciBvZiByb3dzIGluIGJhcikuIFVzZSB0aGUgZnVuY3Rpb24gbnJvdygpIHRvIGZpbmQgdGhlIG51bWJlciBvZiByb3dzIGluIGJhciBpbnN0ZWFkIG9mIG1hbnVhbGx5IGVudGVyaW5nIHRoYXQgbnVtYmVyLg0KDQpVc2UgOiB0byBjcmVhdGUgYSB2ZWN0b3Igd2l0aCBhbGwgdGhlIGludGVnZXJzIGJldHdlZW4gMSBhbmQgdGhlIG51bWJlciBvZiByb3dzIGluIGJhci4NCmBgYHtyfQ0Kc2FtcGxlcm93cyA8LSBzYW1wbGUoMTpucm93KGJhciksIHNpemU9bikgDQojIHByaW50IHNhbXBsZSByb3dzDQpzYW1wbGVyb3dzDQpgYGANCg0KVGhlIHZhcmlhYmxlIHNhbXBsZXJvd3MgY29udGFpbnMgdGhlIHJvd3Mgb2YgYmFyIHdoaWNoIG1ha2UgYSByYW5kb20gc2FtcGxlIGZyb20gYWxsIHRoZSByb3dzIGluIGJhci4gRXh0cmFjdCB0aG9zZSByb3dzIGZyb20gYmFyIHdpdGgNCmBgYHtyfQ0KIyBleHRyYWN0IHJvd3MNCmJhcnNhbXBsZSA8LSBiYXJbc2FtcGxlcm93cywgXQ0KIyBwcmludCBzYW1wbGUNCnByaW50KGJhcnNhbXBsZSkNCmBgYA0KVGhlIGNvZGUgYWJvdmUgY3JlYXRlcyBhIG5ldyBkYXRhIGZyYW1lIGNhbGxlZCBiYXJzYW1wbGUgd2l0aCBhIHJhbmRvbSBzYW1wbGUgb2Ygcm93cyBmcm9tIGJhci4NCg0KSW4gYSBzaW5nbGUgbGluZSBvZiBjb2RlDQpgYGB7cn0NCmJhcltzYW1wbGUoMTpucm93KGJhciksIG4pLCBdDQpgYGANCg0KI1VzaW5nIFRhYmxlcw0KVGhlIHRhYmxlKCkgY29tbWFuZCBhbGxvd3MgdXMgdG8gbG9vayBhdCB0YWJsZXMuIEl0cyBzaW1wbGVzdCB1c2FnZSBsb29rcyBsaWtlIHRhYmxlKHgpIHdoZXJlIHggaXMgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZS4NCg0KRm9yIGV4YW1wbGUsIGEgc3VydmV5IGFza3MgcGVvcGxlIGlmIHRoZXkgc3VwcG9ydCB0aGUgaG9tZSB0ZWFtIG9yIG5vdC4gVGhlIGRhdGEgaXMNCg0KWWVzLCBObywgTm8sIFllcywgWWVzDQoNCldlIGNhbiBlbnRlciB0aGlzIGludG8gUiB3aXRoIHRoZSBjKCkgY29tbWFuZCwgYW5kIHN1bW1hcml6ZSB3aXRoIHRoZSB0YWJsZSgpIGNvbW1hbmQgYXMgZm9sbG93cw0KYGBge3J9DQp4IDwtIGMoIlllcyIsIk5vIiwiTm8iLCJZZXMiLCJZZXMiKSANCg0KI3N1bW1hcnkgb2YgdW5pcXVlIHZhbHVlcyBpbiB0aGUgdmFyaWFibGUgeA0KdGFibGUoeCkNCmBgYA0KI051bWVyaWNhbCBtZWFzdXJlcyBvZiBjZW50ZXIgYW5kIHNwcmVhZA0KU3VwcG9zZSwgTUxCIFRlYW1z4oCZIENFT3MgeWVhcmx5IGNvbXBlbnNhdGlvbnMgYXJlIHNhbXBsZWQgYW5kIHRoZSBmb2xsb3dpbmcgYXJlIGZvdW5kIChpbiBtaWxsaW9ucykNCg0KMTIgLjQgNSAyIDUwIDggMyAxIDQgMC4yNQ0KYGBge3J9DQpzYWxzIDwtIGMoMTIsIC40LCA1LCAyLCA1MCwgOCwgMywgMSwgNCwgMC4yNSkNCg0KIyB0aGUgYXZlcmFnZSBzYWxhcnkgYW1vbmcgdGhlIENFTydzIChpbiBtaWxsaW9ucykNCm1lYW4oc2FscykNCmBgYA0KDQpgYGB7cn0NCiN0aGUgdmFyaWFuY2UsIHdoaWNoIHJlcHJlc2VudHMgaG93IGZhciBmcm9tIHRoZSBtZWFuIGFyZSBhbGwgb2YgdGhlIHNhbGFyaWVzDQp2YXIoc2FscykgDQpgYGANClRoZSBudW1iZXIgYWJvdmUgc2hvdWxkIGJlIGludGVycHJldGVkIGFzIHRob3VzYW5kcyBvZiBkb2xsYXJzDQpgYGB7cn0NCiNzdGFuZGFyZCBkZXZpYXRpb24NCnNkKHNhbHMpDQpgYGANCg0KYGBge3J9DQojdGhlIG1lZGlhbiwgdGhpcyBjb3VsZCBiZSBhIG1vcmUgcm9idXN0IG1lYXN1cmUgY29tcGFyZWQgdG8gdGhlIG1lYW4sIHNpbmNlIGFuIG91dGxpZXIgY2FuIHRocm93IG9mZiB0aGUgZW50aXJlIGF2ZXJhZ2UuIFdlIGNhbiBzZWUgaGVyZSB0aGF0IHRoZSB2YWx1ZSBpbiB0aGUgbWlkZGxlIG9mIHRoZSBkYXRhc2V0IGlzIDMuNW1pbGxpb25zDQptZWRpYW4oc2FscykNCmBgYA0KDQpgYGB7cn0NCiMgVHVrZXkncyBmaXZlIG51bWJlciBzdW1tYXJ5LCB1c2VmdWwgZm9yIGJveHBsb3RzDQojIGZpdmUgbnVtYmVyczogbWluLCBsb3dlciBoaW5nZSwgbWVkaWFuLCB1cHBlciBoaW5nZSwgbWF4DQpmaXZlbnVtKHNhbHMpDQoNCiNUaGlzIGlzIHRoZSBlbnRpcmUgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhIHN1bW1hcml6ZWQNCmBgYA0KDQpgYGB7cn0NCiMgc3VtbWFyeSBzdGF0aXN0aWNzLCBhIG1vcmUgb3JnYW5pemVkIHdheSB0byBwaWN0dXJlIGEgYm94cGxvdCBmb3IgdGhlIHNhbHMgZGF0YXNldA0Kc3VtbWFyeShzYWxzKQ0KYGBgDQoNCiNIb3cgYWJvdXQgdGhlIG1vZGU/DQpJbiBSIHdlIGNhbiB3cml0ZSBvdXIgb3duIGZ1bmN0aW9ucywgYW5kIGEgZmlyc3QgZXhhbXBsZSBvZiBhIGZ1bmN0aW9uIGlzIHNob3duIGJlbG93IGluIG9yZGVyIHRvIGNvbXB1dGUgdGhlIG1vZGUgb2YgYSB2ZWN0b3Igb2Ygb2JzZXJ2YXRpb25zIHgNCmBgYHtyfQ0KIyBGdW5jdGlvbiB0byBmaW5kIHRoZSBtb2RlLCBpLmUuIG1vc3QgZnJlcXVlbnQgdmFsdWUNCmdldE1vZGUgPC0gZnVuY3Rpb24oeCkgew0KICAgICB1eCA8LSB1bmlxdWUoeCkNCiAgICAgdXhbd2hpY2gubWF4KHRhYnVsYXRlKG1hdGNoKHgsIHV4KSkpXQ0KIH0NCmBgYA0KDQpBcyBhbiBleGFtcGxlLCB3ZSBjYW4gdXNlIHRoZSBmdW5jdGlvbiBkZWZpbmVkIGFib3ZlIHRvIGZpbmQgdGhlIG1vc3QgZnJlcXVlbnQgdmFsdWUgb2YgdGhlIG51bWJlciBvZiBwaXRjaGVzX2J5X2lubmluZ3MNCmBgYHtyfQ0KZ2V0TW9kZShwaXRjaGVzX2J5X2lubmluZ3MpDQpgYGANCg0KYGBge3J9DQojUXVlc3Rpb25fNzogRmluZCB0aGUgbW9zdCBmcmVxdWVudCB2YWx1ZSBvZiBoaXRzX3Blcl85aW5uaW5ncy4NCmdldE1vZGUoaGl0c19wZXJfOWlubmluZ3MpDQpgYGANCg0KYGBge3J9DQpnYW1lX2RheTwtYygiU2F0dXJkYXkiLCAiU2F0dXJkYXkiLCAiU3VuZGF5IiwgIk1vbmRheSIsICJTYXR1cmRheSIsIlR1ZXNkYXkiLCAiU3VuZGF5IiwgIkZyaWRheSIsICJGcmlkYXkiLCAiTW9uZGF5IikNCg0KI1F1ZXN0aW9uXzg6IFN1bW1hcml6ZSB0aGUgZm9sbG93aW5nIHN1cnZleSB3aXRoIHRoZSBgdGFibGUoKWAgY29tbWFuZDoNCnRhYmxlKGdhbWVfZGF5KQ0KYGBgDQoNCmBgYHtyfQ0KI1doYXQgaXMgeW91ciBmYXZvcml0ZSBkYXkgb2YgdGhlIHdlZWsgdG8gd2F0Y2ggYmFzZWJhbGw/IEEgdG90YWwgb2YgMTAgZmFucyBzdWJtaXR0ZWQgdGhpcyBzdXJ2ZXkuDQpnZXRNb2RlKGdhbWVfZGF5KQ0KDQojU2F0dXJkYXksIFNhdHVyZGF5LCBTdW5kYXksIE1vbmRheSwgU2F0dXJkYXksVHVlc2RheSwgU3VuZGF5LCBGcmlkYXksIEZyaWRheSwgTW9uZGF5DQpgYGANCg0K