Setup
library(stringr)
library(readr)
library(knitr)
library(dplyr)
setwd("C:\\Users\\Parikshit\\Documents\\Master Of Analytics\\Semester 3\\Data Preprocessing")
Data Description
The data used for this assignment has been downloaded from https://catalog.data.gov/dataset/drug-poisoning-mortality-by-state-united-states
The dataset describes drug poisoning death rates in the US at the state level and by selected demographic characteristics.
The crude death rate and the age adjusted death rates are the death rates per 100,000 U.S. Standard Population for 2000.
Both the crude death rate and age adjusted death rate have a lower and an upper confidence limit which capture the uncertainty in the estimates of the death rates.
State crude rate in Range is the interval range of crude death rate of that respective state
The rates are calculated based on multiple cause-of-death mortality data from National Vital Statistics [Prevention, C & Statistics, N 2018, “Drug Poisoning Mortality by State: United States - Data.gov”, Catalog.data.gov, viewed 24 March, 2018, https://catalog.data.gov/dataset/drug-poisoning-mortality-by-state-united-states.].
Read/Import Data
#Reading in the drug dataset at the same time trimming leading and trailing
#whitespaces
drug<-read.csv("Drug_Poisoning_Mortality_by_State__United_States.csv",
strip.white = TRUE)
drug[drug$State=="California",] #printing out observations from the state of California
drug_tail_10<-tail(drug,10) #Subsetting out the last 10 observations of the drug dataset and storing it as a dataframe named drug_tail_10
- The drug dataset has been read using the read.csv() function from the base R package
- I have subsetted and listed out the observations from the state of California
- The last 10 observations of the drug dataframe has been subsetted (using the tail() function)and stored in a dataframe named drug_tail_10
Inspect and Understand
dim(drug)[1] #This gives the number of rows in the drug dataframe: 2862
dim(drug)[2] #This gives the number of columns in the drug dataframe: 18
str(drug) #Chekcing the structure of the drug dataframe
##Rearranging the columns of the dataframe
drug<-drug%>%select(1:5,16,6:15,17,18)
##Renaming columns of the drug dataframe
names(drug)[4]<-"Age_Group"
names(drug)[5]<-"Race_Origin"
names(drug)[6]<-"ST_CR_Range"
names(drug)[9]<-"CR"
names(drug)[10]<-"SE_CR"
names(drug)[11]<-"LCL_CR"
names(drug)[12]<-"UCL_CR"
names(drug)[13]<-"AACR"
names(drug)[14]<-"SE_AACR"
names(drug)[15]<-"LCL_AACR"
names(drug)[16]<-"UCL_AACR"
names(drug)[17]<-"US_CR"
names(drug)[18]<-"US_AACR"
##Setting appropriate data types to the variables
drug$State<-as.character(drug$State)
drug$Year<-as.numeric(drug$Year)
drug$Sex<-factor(drug$Sex,levels=c("Male","Female","Both Sexes"))
drug$Age_Group<-factor(drug$Age_Group,levels=c("0-14","15-24","25-34",
"35-44","45-54","55-64",
"65-74","75+","All Ages"))
drug$Race_Origin<-factor(drug$Race_Origin,levels=
c("Hispanic","Non-Hispanic Black",
"Non-Hispanic White","All Races-All Origins"))
drug$ST_CR_Range<-as.character(drug$ST_CR_Range)
##Converting column number 7 to column 18 to a numeric data type
for(i in 7:18){
drug[,i]<-as.numeric(drug[,i])
}
##Printing the levels of the factor variables and range of numeric variables
sapply(drug,function(x){
if(is.factor(x)){
return(levels(x))
}else if(is.numeric(x)){
return(range(x,na.rm=TRUE))
}
})
#####Complete Cases and Missing Values in the Drug dataframe
miss_val<-data.frame(sapply(drug,function(x){missing_no<-sum(is.na(x))}))
names(miss_val)[1]<-"# Missing Values"
kable(miss_val,format="html",caption="Number of missing values in each attribute")
NA_no<-complete.cases(drug)
sum(NA_no) #Number of rows that have no missing values in the entire row sequence: 1134
The drug data set has been inspected and preprocessed on the following lines:
- Dimensions of the data has been checked
- Structure of the data frame has been checked
- Leading and trailing blanks (if any) have been removed from every column
- The columns of the drug dataframe has been rearranged
- Suitable renaming of the attributes
- Setting appropriate data types to the variables
- Levels of the factor variables have been arranged
- Printing out the levels of all the factor variables and ranges(min and max value) of the numeric variables
- Inspecting missing values and complete cases
With regards to the naming conventions of the columns of the drug dataframe:
- Age.Group has been renamed to Age_Group
- Race.and.Hispanic.Origin has been renamed to Race_Origin
- State.Crude.Rate.in.Range has been renamed to ST_CR_Range
- Crude.Death.Rate has been renamed to CR
- Age-adjusted has been renamed to AACR
- Standard.Error.for.Crude.Rate has been renamed to SE_CR
- Lower.Confidence.Limit.for.Crude.Rate has been renamed to LCL_CR
- Upper.Confidence.Limit.for.Crude.Rate has been renamed to UCL_CR
- US.Crude.Rate has been renamed to US_CR
- US.Age-adjusted.Rate has been renamed to US_AACR
With regards to rearrangment in columns, State.Crude.Rate.in.Range has been brought after the Race.and.Hispanic.Origin column.
Data types of the attributes of the drug dataset has been set as follows:
- State and ST_CR_Range has been set to a Character data type
- Year has been set to a Numeric data type
- Sex, Age_Group and Race_Origin has been type casted to a Factor data type
- All of the other columns has been type casted to a Numeric data type
Subsetting I
Now, I subset the first 10 rows of the drug dataframe and create a matrix out of it.
Since a matrix data structure in R can hold only atomic elements (all elements being of the same data type), all of the 10 observations across the attributes of the drug dataset are coerced to a character data type which is evident when we execute the code print(drug_subset_matrix[1,])
drug_subset<-drug[1:10,] #Subsetting the first 10 rows of the drug dataframe
drug_subset_matrix<-as.matrix(drug_subset) #creating a matrix out of the subsetted data
print(drug_subset_matrix[1,])#Printing out the first row of the matrix
Subsetting II
Now, I subset the original drug dataframe by retaining only the first and the last column.
I save it as an R object. The reason for doing this is to free up some memory space and to load the data frame (in future, if needed) into memory in an as-is state without loss of information.
drug_subset_2<-data.frame(drug[,c(1,dim(drug)[2])])
save(drug_subset_2,file="drug_subsetted.Rda")
LS0tDQp0aXRsZTogIk1BVEgyMzQ5IChEYXRhIFByZXByb2Nlc3NpbmcpIFNlbWVzdGVyIDEsIDIwMTgiDQphdXRob3I6ICJQYXJpa3NoaXQgU3JlZWRoYXIgKFMzNjQzNzk2KSINCnN1YnRpdGxlOiBBc3NpZ25tZW50IDENCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KIyMgU2V0dXANCg0KYGBge3IsZWNobz1UUlVFLHdhcm5pbmdzPUZBTFNFfQ0KDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShrbml0cikgDQpsaWJyYXJ5KGRwbHlyKQ0KDQpzZXR3ZCgiQzpcXFVzZXJzXFxQYXJpa3NoaXRcXERvY3VtZW50c1xcTWFzdGVyIE9mIEFuYWx5dGljc1xcU2VtZXN0ZXIgM1xcRGF0YSBQcmVwcm9jZXNzaW5nIikNCmBgYA0KDQojIyBEYXRhIERlc2NyaXB0aW9uDQoNClRoZSBkYXRhIHVzZWQgZm9yIHRoaXMgYXNzaWdubWVudCBoYXMgYmVlbiBkb3dubG9hZGVkIGZyb20gaHR0cHM6Ly9jYXRhbG9nLmRhdGEuZ292L2RhdGFzZXQvZHJ1Zy1wb2lzb25pbmctbW9ydGFsaXR5LWJ5LXN0YXRlLXVuaXRlZC1zdGF0ZXMNCg0KVGhlIGRhdGFzZXQgZGVzY3JpYmVzICoqZHJ1ZyBwb2lzb25pbmcgZGVhdGggcmF0ZXMgaW4gdGhlIFVTKiogYXQgdGhlIHN0YXRlIGxldmVsIGFuZCBieSBzZWxlY3RlZCBkZW1vZ3JhcGhpYyBjaGFyYWN0ZXJpc3RpY3MuDQoNClRoZSAqKmNydWRlIGRlYXRoIHJhdGUqKiBhbmQgdGhlICoqYWdlIGFkanVzdGVkIGRlYXRoIHJhdGVzKiogYXJlIHRoZSBkZWF0aCByYXRlcyBwZXIgMTAwLDAwMCBVLlMuIFN0YW5kYXJkIFBvcHVsYXRpb24gZm9yIDIwMDAuDQoNCkJvdGggdGhlIGNydWRlIGRlYXRoIHJhdGUgYW5kIGFnZSBhZGp1c3RlZCBkZWF0aCByYXRlIGhhdmUgYSBsb3dlciBhbmQgYW4gdXBwZXIgY29uZmlkZW5jZSBsaW1pdCB3aGljaCBjYXB0dXJlIHRoZSB1bmNlcnRhaW50eSBpbiB0aGUgZXN0aW1hdGVzIG9mIHRoZSBkZWF0aCByYXRlcy4NCg0KKipTdGF0ZSBjcnVkZSByYXRlIGluIFJhbmdlKiogaXMgdGhlIGludGVydmFsIHJhbmdlIG9mIGNydWRlIGRlYXRoIHJhdGUgb2YgdGhhdCByZXNwZWN0aXZlIHN0YXRlDQoNClRoZSByYXRlcyBhcmUgY2FsY3VsYXRlZCBiYXNlZCBvbiBtdWx0aXBsZSBjYXVzZS1vZi1kZWF0aCBtb3J0YWxpdHkgZGF0YSBmcm9tIE5hdGlvbmFsIFZpdGFsIFN0YXRpc3RpY3MgW1ByZXZlbnRpb24sIEMgJiBTdGF0aXN0aWNzLCBOIDIwMTgsICJEcnVnIFBvaXNvbmluZyBNb3J0YWxpdHkgYnkgU3RhdGU6IFVuaXRlZCBTdGF0ZXMgLSBEYXRhLmdvdiIsIENhdGFsb2cuZGF0YS5nb3YsIHZpZXdlZCAyNCBNYXJjaCwgMjAxOCwgPGh0dHBzOi8vY2F0YWxvZy5kYXRhLmdvdi9kYXRhc2V0L2RydWctcG9pc29uaW5nLW1vcnRhbGl0eS1ieS1zdGF0ZS11bml0ZWQtc3RhdGVzPi5dLg0KDQojIyBSZWFkL0ltcG9ydCBEYXRhDQoNCmBgYHtyLHdhcm5pbmdzPUZBTFNFfQ0KI1JlYWRpbmcgaW4gdGhlIGRydWcgZGF0YXNldCBhdCB0aGUgc2FtZSB0aW1lIHRyaW1taW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nDQojd2hpdGVzcGFjZXMNCmRydWc8LXJlYWQuY3N2KCJEcnVnX1BvaXNvbmluZ19Nb3J0YWxpdHlfYnlfU3RhdGVfX1VuaXRlZF9TdGF0ZXMuY3N2IiwNCiAgICAgICAgICAgICAgIHN0cmlwLndoaXRlID0gVFJVRSkNCg0KZHJ1Z1tkcnVnJFN0YXRlPT0iQ2FsaWZvcm5pYSIsXSAjcHJpbnRpbmcgb3V0IG9ic2VydmF0aW9ucyBmcm9tIHRoZSBzdGF0ZSBvZiBDYWxpZm9ybmlhDQoNCmRydWdfdGFpbF8xMDwtdGFpbChkcnVnLDEwKSAjU3Vic2V0dGluZyBvdXQgdGhlIGxhc3QgMTAgb2JzZXJ2YXRpb25zIG9mIHRoZSBkcnVnIGRhdGFzZXQgYW5kIHN0b3JpbmcgaXQgYXMgYSBkYXRhZnJhbWUgbmFtZWQgZHJ1Z190YWlsXzEwDQpgYGANCg0KDQogICogVGhlIGRydWcgZGF0YXNldCBoYXMgYmVlbiByZWFkIHVzaW5nIHRoZSByZWFkLmNzdigpIGZ1bmN0aW9uIGZyb20gdGhlIGJhc2UgUiAgICAgIHBhY2thZ2UNCiAgKiBJIGhhdmUgc3Vic2V0dGVkIGFuZCBsaXN0ZWQgb3V0IHRoZSBvYnNlcnZhdGlvbnMgZnJvbSB0aGUgc3RhdGUgb2YgICAgICAgICAgICAgICAgKipDYWxpZm9ybmlhKioNCiAgKiBUaGUgbGFzdCAxMCBvYnNlcnZhdGlvbnMgb2YgdGhlIGRydWcgZGF0YWZyYW1lIGhhcyBiZWVuIHN1YnNldHRlZCAodXNpbmcgdGhlICAgICAgKip0YWlsKCkqKiBmdW5jdGlvbilhbmQgc3RvcmVkIGluIGEgZGF0YWZyYW1lIG5hbWVkIGRydWdfdGFpbF8xMA0KDQoNCiMjIEluc3BlY3QgYW5kIFVuZGVyc3RhbmQNCg0KYGBge3J9DQpkaW0oZHJ1ZylbMV0gI1RoaXMgZ2l2ZXMgdGhlIG51bWJlciBvZiByb3dzIGluIHRoZSBkcnVnIGRhdGFmcmFtZTogMjg2Mg0KZGltKGRydWcpWzJdICNUaGlzIGdpdmVzIHRoZSBudW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgZHJ1ZyBkYXRhZnJhbWU6IDE4DQoNCnN0cihkcnVnKSAjQ2hla2NpbmcgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZHJ1ZyBkYXRhZnJhbWUNCg0KIyNSZWFycmFuZ2luZyB0aGUgY29sdW1ucyBvZiB0aGUgZGF0YWZyYW1lDQpkcnVnPC1kcnVnJT4lc2VsZWN0KDE6NSwxNiw2OjE1LDE3LDE4KQ0KDQoNCiMjUmVuYW1pbmcgY29sdW1ucyBvZiB0aGUgZHJ1ZyBkYXRhZnJhbWUNCm5hbWVzKGRydWcpWzRdPC0iQWdlX0dyb3VwIg0KbmFtZXMoZHJ1ZylbNV08LSJSYWNlX09yaWdpbiINCm5hbWVzKGRydWcpWzZdPC0iU1RfQ1JfUmFuZ2UiDQpuYW1lcyhkcnVnKVs5XTwtIkNSIg0KbmFtZXMoZHJ1ZylbMTBdPC0iU0VfQ1IiDQpuYW1lcyhkcnVnKVsxMV08LSJMQ0xfQ1IiDQpuYW1lcyhkcnVnKVsxMl08LSJVQ0xfQ1IiDQpuYW1lcyhkcnVnKVsxM108LSJBQUNSIg0KbmFtZXMoZHJ1ZylbMTRdPC0iU0VfQUFDUiINCm5hbWVzKGRydWcpWzE1XTwtIkxDTF9BQUNSIg0KbmFtZXMoZHJ1ZylbMTZdPC0iVUNMX0FBQ1IiDQpuYW1lcyhkcnVnKVsxN108LSJVU19DUiINCm5hbWVzKGRydWcpWzE4XTwtIlVTX0FBQ1IiDQoNCg0KIyNTZXR0aW5nIGFwcHJvcHJpYXRlIGRhdGEgdHlwZXMgdG8gdGhlIHZhcmlhYmxlcw0KZHJ1ZyRTdGF0ZTwtYXMuY2hhcmFjdGVyKGRydWckU3RhdGUpDQoNCmRydWckWWVhcjwtYXMubnVtZXJpYyhkcnVnJFllYXIpDQoNCmRydWckU2V4PC1mYWN0b3IoZHJ1ZyRTZXgsbGV2ZWxzPWMoIk1hbGUiLCJGZW1hbGUiLCJCb3RoIFNleGVzIikpDQoNCmRydWckQWdlX0dyb3VwPC1mYWN0b3IoZHJ1ZyRBZ2VfR3JvdXAsbGV2ZWxzPWMoIjAtMTQiLCIxNS0yNCIsIjI1LTM0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIzNS00NCIsIjQ1LTU0IiwiNTUtNjQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjY1LTc0IiwiNzUrIiwiQWxsIEFnZXMiKSkNCg0KZHJ1ZyRSYWNlX09yaWdpbjwtZmFjdG9yKGRydWckUmFjZV9PcmlnaW4sbGV2ZWxzPQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJIaXNwYW5pYyIsIk5vbi1IaXNwYW5pYyBCbGFjayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm9uLUhpc3BhbmljIFdoaXRlIiwiQWxsIFJhY2VzLUFsbCBPcmlnaW5zIikpDQoNCmRydWckU1RfQ1JfUmFuZ2U8LWFzLmNoYXJhY3RlcihkcnVnJFNUX0NSX1JhbmdlKQ0KDQojI0NvbnZlcnRpbmcgY29sdW1uIG51bWJlciA3IHRvIGNvbHVtbiAxOCB0byBhIG51bWVyaWMgZGF0YSB0eXBlDQpmb3IoaSBpbiA3OjE4KXsNCiAgZHJ1Z1ssaV08LWFzLm51bWVyaWMoZHJ1Z1ssaV0pDQp9IA0KDQoNCiMjUHJpbnRpbmcgdGhlIGxldmVscyBvZiB0aGUgZmFjdG9yIHZhcmlhYmxlcyBhbmQgcmFuZ2Ugb2YgbnVtZXJpYyB2YXJpYWJsZXMNCg0Kc2FwcGx5KGRydWcsZnVuY3Rpb24oeCl7DQogIGlmKGlzLmZhY3Rvcih4KSl7DQogICAgcmV0dXJuKGxldmVscyh4KSkNCiAgfWVsc2UgaWYoaXMubnVtZXJpYyh4KSl7DQogICAgcmV0dXJuKHJhbmdlKHgsbmEucm09VFJVRSkpDQogIH0NCn0pDQoNCiMjIyMjQ29tcGxldGUgQ2FzZXMgYW5kIE1pc3NpbmcgVmFsdWVzIGluIHRoZSBEcnVnIGRhdGFmcmFtZQ0KDQptaXNzX3ZhbDwtZGF0YS5mcmFtZShzYXBwbHkoZHJ1ZyxmdW5jdGlvbih4KXttaXNzaW5nX25vPC1zdW0oaXMubmEoeCkpfSkpDQoNCm5hbWVzKG1pc3NfdmFsKVsxXTwtIiMgTWlzc2luZyBWYWx1ZXMiDQoNCmthYmxlKG1pc3NfdmFsLGZvcm1hdD0iaHRtbCIsY2FwdGlvbj0iTnVtYmVyIG9mIG1pc3NpbmcgdmFsdWVzIGluIGVhY2ggYXR0cmlidXRlIikNCg0KTkFfbm88LWNvbXBsZXRlLmNhc2VzKGRydWcpDQoNCnN1bShOQV9ubykgI051bWJlciBvZiByb3dzIHRoYXQgaGF2ZSBubyBtaXNzaW5nIHZhbHVlcyBpbiB0aGUgZW50aXJlIHJvdyBzZXF1ZW5jZTogMTEzNA0KYGBgDQpUaGUgZHJ1ZyBkYXRhIHNldCBoYXMgYmVlbiBpbnNwZWN0ZWQgYW5kIHByZXByb2Nlc3NlZCBvbiB0aGUgZm9sbG93aW5nIGxpbmVzOg0KDQogICogRGltZW5zaW9ucyBvZiB0aGUgZGF0YSBoYXMgYmVlbiBjaGVja2VkDQogICogU3RydWN0dXJlIG9mIHRoZSBkYXRhIGZyYW1lIGhhcyBiZWVuIGNoZWNrZWQNCiAgKiAqKkxlYWRpbmcgYW5kIHRyYWlsaW5nIGJsYW5rcyAoaWYgYW55KSBoYXZlIGJlZW4gcmVtb3ZlZCBmcm9tIGV2ZXJ5IGNvbHVtbioqDQogICogVGhlIGNvbHVtbnMgb2YgdGhlIGRydWcgZGF0YWZyYW1lIGhhcyBiZWVuIHJlYXJyYW5nZWQNCiAgKiBTdWl0YWJsZSByZW5hbWluZyBvZiB0aGUgYXR0cmlidXRlcw0KICAqIFNldHRpbmcgYXBwcm9wcmlhdGUgZGF0YSB0eXBlcyB0byB0aGUgdmFyaWFibGVzDQogICAgKiBMZXZlbHMgb2YgdGhlIGZhY3RvciB2YXJpYWJsZXMgaGF2ZSBiZWVuIGFycmFuZ2VkDQogICogUHJpbnRpbmcgb3V0IHRoZSBsZXZlbHMgb2YgYWxsIHRoZSBmYWN0b3IgdmFyaWFibGVzIGFuZCByYW5nZXMobWluIGFuZCBtYXggICAgICAgIHZhbHVlKSBvZiB0aGUgbnVtZXJpYyB2YXJpYWJsZXMNCiAgKiAqKkluc3BlY3RpbmcgbWlzc2luZyB2YWx1ZXMgYW5kIGNvbXBsZXRlIGNhc2VzKioNCiAgDQpXaXRoIHJlZ2FyZHMgdG8gdGhlIG5hbWluZyBjb252ZW50aW9ucyBvZiB0aGUgY29sdW1ucyBvZiB0aGUgZHJ1ZyBkYXRhZnJhbWU6DQoNCiAgKiBBZ2UuR3JvdXAgaGFzIGJlZW4gcmVuYW1lZCB0byBBZ2VfR3JvdXANCiAgKiBSYWNlLmFuZC5IaXNwYW5pYy5PcmlnaW4gaGFzIGJlZW4gcmVuYW1lZCB0byBSYWNlX09yaWdpbg0KICAqIFN0YXRlLkNydWRlLlJhdGUuaW4uUmFuZ2UgaGFzIGJlZW4gcmVuYW1lZCB0byBTVF9DUl9SYW5nZQ0KICAqIENydWRlLkRlYXRoLlJhdGUgaGFzIGJlZW4gcmVuYW1lZCB0byBDUg0KICAqIEFnZS1hZGp1c3RlZCBoYXMgYmVlbiByZW5hbWVkIHRvIEFBQ1INCiAgKiBTdGFuZGFyZC5FcnJvci5mb3IuQ3J1ZGUuUmF0ZSBoYXMgYmVlbiByZW5hbWVkIHRvIFNFX0NSDQogICogTG93ZXIuQ29uZmlkZW5jZS5MaW1pdC5mb3IuQ3J1ZGUuUmF0ZSBoYXMgYmVlbiByZW5hbWVkIHRvIExDTF9DUg0KICAqIFVwcGVyLkNvbmZpZGVuY2UuTGltaXQuZm9yLkNydWRlLlJhdGUgaGFzIGJlZW4gcmVuYW1lZCB0byBVQ0xfQ1INCiAgKiBVUy5DcnVkZS5SYXRlIGhhcyBiZWVuIHJlbmFtZWQgdG8gVVNfQ1INCiAgKiBVUy5BZ2UtYWRqdXN0ZWQuUmF0ZSBoYXMgYmVlbiByZW5hbWVkIHRvIFVTX0FBQ1INCiAgDQogIA0KV2l0aCByZWdhcmRzIHRvIHJlYXJyYW5nbWVudCBpbiBjb2x1bW5zLCAqKlN0YXRlLkNydWRlLlJhdGUuaW4uUmFuZ2UqKiBoYXMgYmVlbiBicm91Z2h0IGFmdGVyIHRoZSAqKlJhY2UuYW5kLkhpc3BhbmljLk9yaWdpbioqIGNvbHVtbi4NCg0KRGF0YSB0eXBlcyBvZiB0aGUgYXR0cmlidXRlcyBvZiB0aGUgZHJ1ZyBkYXRhc2V0IGhhcyBiZWVuIHNldCBhcyBmb2xsb3dzOg0KDQogICogU3RhdGUgYW5kIFNUX0NSX1JhbmdlIGhhcyBiZWVuIHNldCB0byBhICoqQ2hhcmFjdGVyKiogZGF0YSB0eXBlDQogICogWWVhciBoYXMgYmVlbiBzZXQgdG8gYSAqKk51bWVyaWMqKiBkYXRhIHR5cGUNCiAgKiBTZXgsIEFnZV9Hcm91cCBhbmQgUmFjZV9PcmlnaW4gaGFzIGJlZW4gdHlwZSBjYXN0ZWQgdG8gYSAqKkZhY3RvcioqIGRhdGEgdHlwZQ0KICAqIEFsbCBvZiB0aGUgb3RoZXIgY29sdW1ucyBoYXMgYmVlbiB0eXBlIGNhc3RlZCB0byBhICoqTnVtZXJpYyoqIGRhdGEgdHlwZQ0KDQojIyBTdWJzZXR0aW5nIEkNCg0KTm93LCBJIHN1YnNldCB0aGUgZmlyc3QgMTAgcm93cyBvZiB0aGUgZHJ1ZyBkYXRhZnJhbWUgYW5kIGNyZWF0ZSBhIG1hdHJpeCBvdXQgb2YgaXQuDQoNClNpbmNlIGEgbWF0cml4IGRhdGEgc3RydWN0dXJlIGluIFIgY2FuIGhvbGQgb25seSBhdG9taWMgZWxlbWVudHMgKGFsbCBlbGVtZW50cyBiZWluZyBvZiB0aGUgc2FtZSBkYXRhIHR5cGUpLCBhbGwgb2YgdGhlIDEwIG9ic2VydmF0aW9ucyBhY3Jvc3MgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGRydWcgZGF0YXNldCBhcmUgY29lcmNlZCB0byBhIGNoYXJhY3RlciBkYXRhIHR5cGUgd2hpY2ggaXMgZXZpZGVudCB3aGVuIHdlIGV4ZWN1dGUgdGhlIGNvZGUgKipwcmludChkcnVnX3N1YnNldF9tYXRyaXhbMSxdKSoqDQoNCg0KYGBge3J9DQpkcnVnX3N1YnNldDwtZHJ1Z1sxOjEwLF0gI1N1YnNldHRpbmcgdGhlIGZpcnN0IDEwIHJvd3Mgb2YgdGhlIGRydWcgZGF0YWZyYW1lDQoNCmRydWdfc3Vic2V0X21hdHJpeDwtYXMubWF0cml4KGRydWdfc3Vic2V0KSAjY3JlYXRpbmcgYSBtYXRyaXggb3V0IG9mIHRoZSBzdWJzZXR0ZWQgZGF0YQ0KDQpwcmludChkcnVnX3N1YnNldF9tYXRyaXhbMSxdKSNQcmludGluZyBvdXQgdGhlIGZpcnN0IHJvdyBvZiB0aGUgbWF0cml4DQpgYGANCg0KIyMgU3Vic2V0dGluZyBJSQ0KDQpOb3csIEkgc3Vic2V0IHRoZSBvcmlnaW5hbCBkcnVnIGRhdGFmcmFtZSBieSByZXRhaW5pbmcgb25seSB0aGUgZmlyc3QgYW5kIHRoZSBsYXN0IGNvbHVtbi4NCg0KSSBzYXZlIGl0IGFzIGFuIFIgb2JqZWN0LiBUaGUgcmVhc29uIGZvciBkb2luZyB0aGlzIGlzIHRvIGZyZWUgdXAgc29tZSBtZW1vcnkgc3BhY2UgYW5kIHRvIGxvYWQgdGhlIGRhdGEgZnJhbWUgKGluIGZ1dHVyZSwgaWYgbmVlZGVkKSBpbnRvIG1lbW9yeSBpbiBhbiBhcy1pcyBzdGF0ZSB3aXRob3V0IGxvc3Mgb2YgaW5mb3JtYXRpb24uDQoNCmBgYHtyfQ0KZHJ1Z19zdWJzZXRfMjwtZGF0YS5mcmFtZShkcnVnWyxjKDEsZGltKGRydWcpWzJdKV0pDQpzYXZlKGRydWdfc3Vic2V0XzIsZmlsZT0iZHJ1Z19zdWJzZXR0ZWQuUmRhIikNCmBgYA0KDQojIyBSRUZFUkVOQ0VTDQoNClByZXZlbnRpb24sIEMgJiBTdGF0aXN0aWNzLCBOIDIwMTgsICJEcnVnIFBvaXNvbmluZyBNb3J0YWxpdHkgYnkgU3RhdGU6IFVuaXRlZCBTdGF0ZXMgLSBEYXRhLmdvdiIsIENhdGFsb2cuZGF0YS5nb3YsIHZpZXdlZCAyNCBNYXJjaCwgMjAxOCwgPGh0dHBzOi8vY2F0YWxvZy5kYXRhLmdvdi9kYXRhc2V0L2RydWctcG9pc29uaW5nLW1vcnRhbGl0eS1ieS1zdGF0ZS11bml0ZWQtc3RhdGVzPi4=