CAP 3330. Summer 2023

Assignment 6 (100 points)

Instructions

Create an R notebook and include all the code and interpretations/explanations needed to answer the three questions below.

The submission for this assignment consists of uploading to Canvas the R notebook with the answers for all the questions below. You can submit either the HTML version of the notebook OR an exported PDF. ONLY these two formats will be accepted !!! (DO NOT submit the .Rmd file)

Make sure the document that you submit (HTML or the PDF) includes:

  1. The R code you used for each exercise part.

  2. The R output you got after running each line of code.

  3. Your written answers (if needed). If a question asks you to justify/explain, your notebook must include a text section with the justification/explanation.

Dataset

The dataset you are going to use for this assignment is called Hitters_Fixed, which is a cleaned version of the Hitters dataset. First, you are going to read the Hitters dataset; then, you will clean it to get the Hitters_Fixed dataset. Take the following steps to do so:

Hitters_Fixed = na.omit(Hitters )

That is all. Now you can use the Hitters_Fixed dataset to do this assignment! Note: If you want more info about the variables in the Hitters_Fixed dataset, you can get it using this link: https://docs.google.com/document/d/1qKeEoWVnAkrlPDwuq7Uz65ybOzrXpBC2pplRbabcgJ0/edit?usp=sharing

install.packages("ISLR") 
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:

https://cran.rstudio.com/bin/windows/Rtools/
Installing package into ‘C:/Users/gisse/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/ISLR_1.4.zip'
Content type 'application/zip' length 2924200 bytes (2.8 MB)
downloaded 2.8 MB
package ‘ISLR’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\gisse\AppData\Local\Temp\Rtmp2jdNZP\downloaded_packages
library(ISLR)

Hitters <- ISLR::Hitters 

str(Hitters)
'data.frame':   322 obs. of  20 variables:
 $ AtBat    : int  293 315 479 496 321 594 185 298 323 401 ...
 $ Hits     : int  66 81 130 141 87 169 37 73 81 92 ...
 $ HmRun    : int  1 7 18 20 10 4 1 0 6 17 ...
 $ Runs     : int  30 24 66 65 39 74 23 24 26 49 ...
 $ RBI      : int  29 38 72 78 42 51 8 24 32 66 ...
 $ Walks    : int  14 39 76 37 30 35 21 7 8 65 ...
 $ Years    : int  1 14 3 11 2 11 2 3 2 13 ...
 $ CAtBat   : int  293 3449 1624 5628 396 4408 214 509 341 5206 ...
 $ CHits    : int  66 835 457 1575 101 1133 42 108 86 1332 ...
 $ CHmRun   : int  1 69 63 225 12 19 1 0 6 253 ...
 $ CRuns    : int  30 321 224 828 48 501 30 41 32 784 ...
 $ CRBI     : int  29 414 266 838 46 336 9 37 34 890 ...
 $ CWalks   : int  14 375 263 354 33 194 24 12 8 866 ...
 $ League   : Factor w/ 2 levels "A","N": 1 2 1 2 2 1 2 1 2 1 ...
 $ Division : Factor w/ 2 levels "E","W": 1 2 2 1 1 2 1 2 2 1 ...
 $ PutOuts  : int  446 632 880 200 805 282 76 121 143 0 ...
 $ Assists  : int  33 43 82 11 40 421 127 283 290 0 ...
 $ Errors   : int  20 10 14 3 4 25 7 9 19 0 ...
 $ Salary   : num  NA 475 480 500 91.5 750 70 100 75 1100 ...
 $ NewLeague: Factor w/ 2 levels "A","N": 1 2 1 2 2 1 1 1 2 1 ...
summary(Hitters)
     AtBat            Hits         HmRun            Runs             RBI             Walks            Years            CAtBat            CHits            CHmRun           CRuns             CRBI             CWalks        League  Division
 Min.   : 16.0   Min.   :  1   Min.   : 0.00   Min.   :  0.00   Min.   :  0.00   Min.   :  0.00   Min.   : 1.000   Min.   :   19.0   Min.   :   4.0   Min.   :  0.00   Min.   :   1.0   Min.   :   0.00   Min.   :   0.00   A:175   E:157   
 1st Qu.:255.2   1st Qu.: 64   1st Qu.: 4.00   1st Qu.: 30.25   1st Qu.: 28.00   1st Qu.: 22.00   1st Qu.: 4.000   1st Qu.:  816.8   1st Qu.: 209.0   1st Qu.: 14.00   1st Qu.: 100.2   1st Qu.:  88.75   1st Qu.:  67.25   N:147   W:165   
 Median :379.5   Median : 96   Median : 8.00   Median : 48.00   Median : 44.00   Median : 35.00   Median : 6.000   Median : 1928.0   Median : 508.0   Median : 37.50   Median : 247.0   Median : 220.50   Median : 170.50                   
 Mean   :380.9   Mean   :101   Mean   :10.77   Mean   : 50.91   Mean   : 48.03   Mean   : 38.74   Mean   : 7.444   Mean   : 2648.7   Mean   : 717.6   Mean   : 69.49   Mean   : 358.8   Mean   : 330.12   Mean   : 260.24                   
 3rd Qu.:512.0   3rd Qu.:137   3rd Qu.:16.00   3rd Qu.: 69.00   3rd Qu.: 64.75   3rd Qu.: 53.00   3rd Qu.:11.000   3rd Qu.: 3924.2   3rd Qu.:1059.2   3rd Qu.: 90.00   3rd Qu.: 526.2   3rd Qu.: 426.25   3rd Qu.: 339.25                   
 Max.   :687.0   Max.   :238   Max.   :40.00   Max.   :130.00   Max.   :121.00   Max.   :105.00   Max.   :24.000   Max.   :14053.0   Max.   :4256.0   Max.   :548.00   Max.   :2165.0   Max.   :1659.00   Max.   :1566.00                   
                                                                                                                                                                                                                                            
    PutOuts          Assists          Errors          Salary       NewLeague
 Min.   :   0.0   Min.   :  0.0   Min.   : 0.00   Min.   :  67.5   A:176    
 1st Qu.: 109.2   1st Qu.:  7.0   1st Qu.: 3.00   1st Qu.: 190.0   N:146    
 Median : 212.0   Median : 39.5   Median : 6.00   Median : 425.0            
 Mean   : 288.9   Mean   :106.9   Mean   : 8.04   Mean   : 535.9            
 3rd Qu.: 325.0   3rd Qu.:166.0   3rd Qu.:11.00   3rd Qu.: 750.0            
 Max.   :1378.0   Max.   :492.0   Max.   :32.00   Max.   :2460.0            
                                                  NA's   :59                
Hitters_Fixed <-na.omit(Hitters)

Questions We are going to obtain a regression equation to predict “Salary” (i.e., Salary is the outcome variable) Question 1) Conduct a regression analysis using “Hits” as the only predictor. Answer the following questions:

plot(Hitters_Fixed$Hits, Hitters_Fixed$Salary)

abline(lm(Salary~Hits, data = Hitters_Fixed), col = "red")

abline(h = mean(Hitters_Fixed$Salary), col = "blue")


sum_lm <- lm(Salary~Hits,data=Hitters_Fixed)

summary(sum_lm)

Call:
lm(formula = Salary ~ Hits, data = Hitters_Fixed)

Residuals:
    Min      1Q  Median      3Q     Max 
-893.99 -245.63  -59.08  181.12 2059.90 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  63.0488    64.9822   0.970    0.333    
Hits          4.3854     0.5561   7.886 8.53e-14 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 406.2 on 261 degrees of freedom
Multiple R-squared:  0.1924,    Adjusted R-squared:  0.1893 
F-statistic: 62.19 on 1 and 261 DF,  p-value: 8.531e-14
  1. Based on your results, discuss BOTH the statistical significance and the quality of the linear equation that uses “Hits” to predict the player’s salary.

Hits and salary are related. After analyzing the p-value, it is less than 0.05. We can conclude that the relationship between hits and salary are satistically significant.

  1. Write out the equation that you would use to predict salary based on the player’s number of hits in the 1986 season.

Y = 63.0488 + Hits * 4.3854

Question 2) Use the same regression analysis from question 1 to answer this question.

Assume that Assumption 2 regarding the validity of the linear regression analysis is satisfied. Run an analysis to check for the validity of all other assumptions. Comment on your findings.

par(mfrow=c(2,2))
plot(sum_lm)

Assuming that “Assumption 2” is satisfied we can look at Plot 1 (Residuals vs Fitted Values). The residuals show a non-linear pattern, so the assumption is not satisfied and a quadratic model should be used instead of a linear one. Assumption 1 is not satisfied.

Question 3) Apply the best subset selection method to find a good multiple linear equation. DO NOT INCLUDE in the analysis the following four predictors:

CHits, CAtBat, CRuns, CRBI

  1. After applying the best subset selection method, write the equation that includes the predictors that you consider appropriate. JUSTIFY (by showing your work and commenting) why you selected this equation.
library(leaps)

best_subset_Salary <- regsubsets(Salary~.-CHits -CAtBat -CRuns -CRBI, data=Hitters_Fixed, nvmax=13) 

summary(best_subset_Salary)
Subset selection object
Call: regsubsets.formula(Salary ~ . - CHits - CAtBat - CRuns - CRBI, 
    data = Hitters_Fixed, nvmax = 13)
15 Variables  (and intercept)
           Forced in Forced out
AtBat          FALSE      FALSE
Hits           FALSE      FALSE
HmRun          FALSE      FALSE
Runs           FALSE      FALSE
RBI            FALSE      FALSE
Walks          FALSE      FALSE
Years          FALSE      FALSE
CHmRun         FALSE      FALSE
CWalks         FALSE      FALSE
LeagueN        FALSE      FALSE
DivisionW      FALSE      FALSE
PutOuts        FALSE      FALSE
Assists        FALSE      FALSE
Errors         FALSE      FALSE
NewLeagueN     FALSE      FALSE
1 subsets of each size up to 13
Selection Algorithm: exhaustive
          AtBat Hits HmRun Runs RBI Walks Years CHmRun CWalks LeagueN DivisionW PutOuts Assists Errors NewLeagueN
1  ( 1 )  " "   " "  " "   " "  " " " "   " "   "*"    " "    " "     " "       " "     " "     " "    " "       
2  ( 1 )  " "   "*"  " "   " "  " " " "   " "   "*"    " "    " "     " "       " "     " "     " "    " "       
3  ( 1 )  " "   "*"  " "   " "  " " " "   " "   "*"    " "    " "     " "       "*"     " "     " "    " "       
4  ( 1 )  "*"   "*"  " "   " "  " " " "   " "   "*"    " "    " "     " "       "*"     " "     " "    " "       
5  ( 1 )  "*"   "*"  " "   " "  " " " "   " "   "*"    " "    " "     "*"       "*"     " "     " "    " "       
6  ( 1 )  "*"   "*"  " "   " "  " " "*"   " "   "*"    " "    " "     "*"       "*"     " "     " "    " "       
7  ( 1 )  "*"   "*"  " "   " "  " " "*"   "*"   "*"    " "    " "     "*"       "*"     " "     " "    " "       
8  ( 1 )  "*"   "*"  " "   " "  " " "*"   "*"   "*"    " "    " "     "*"       "*"     "*"     " "    " "       
9  ( 1 )  "*"   "*"  " "   " "  " " "*"   "*"   "*"    " "    "*"     "*"       "*"     "*"     " "    " "       
10  ( 1 ) "*"   "*"  "*"   " "  " " "*"   "*"   "*"    " "    "*"     "*"       "*"     "*"     " "    " "       
11  ( 1 ) "*"   "*"  "*"   " "  " " "*"   "*"   "*"    " "    "*"     "*"       "*"     "*"     "*"    " "       
12  ( 1 ) "*"   "*"  "*"   " "  "*" "*"   "*"   "*"    " "    "*"     "*"       "*"     "*"     "*"    " "       
13  ( 1 ) "*"   "*"  "*"   "*"  "*" "*"   "*"   "*"    " "    "*"     "*"       "*"     "*"     "*"    " "       
summary(best_subset_Salary)$adjr2
 [1] 0.2727764 0.3902841 0.4136565 0.4410945 0.4578190 0.4699300 0.4759338 0.4781049 0.4790087 0.4780628 0.4766292 0.4745954 0.4725383
adjR2_vector <- round(summary(best_subset_Salary)$adjr2,3)

a <- data.frame(model_size <- 1:13,round(summary(best_subset_Salary)$adjr2,3))

colnames(a)<-c("model_size","adjR2") 
a


which.max(adjR2_vector)
[1] 9

coef(best_subest_Salary, 9). When we use which.max(), we can see the max value of adj R2 occurs at position 9. This means that when we add a 10th predictor, the adj R2 value is going to go down. Therefore, adding a 10th predictor from this dataset is not statistically valuable. It is better to use the equation with 9 predictors.

  1. What percentage of the total variability in the salary values does the equation that you chose in 3 a) eliminate?
summary(best_subset_Salary)$rsq[9]
[1] 0.4969054

Based on the function above nearly 50% (0.497) of the total variability is eliminated.

  1. Is the prediction error of this equation low or high? Justify your answer (Note: Just give me a well thought, very short, and simple answer for why you consider the error low or high)

I would say that the prediction error in this equation is a bit high. 50% of the proportion of the variance in the dependent variable is explained by the independent variable.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQpDQVAgMzMzMC4gU3VtbWVyIDIwMjMNCg0KQXNzaWdubWVudCA2ICgxMDAgcG9pbnRzKQ0KDQoNCg0KSW5zdHJ1Y3Rpb25zDQoNCkNyZWF0ZSBhbiBSIG5vdGVib29rIGFuZCBpbmNsdWRlIGFsbCB0aGUgY29kZSBhbmQgaW50ZXJwcmV0YXRpb25zL2V4cGxhbmF0aW9ucyBuZWVkZWQgdG8gYW5zd2VyIHRoZSB0aHJlZSBxdWVzdGlvbnMgYmVsb3cuDQoNClRoZSBzdWJtaXNzaW9uIGZvciB0aGlzIGFzc2lnbm1lbnQgY29uc2lzdHMgb2YgdXBsb2FkaW5nIHRvIENhbnZhcyB0aGUgUiBub3RlYm9vayB3aXRoIHRoZSBhbnN3ZXJzIGZvciBhbGwgdGhlIHF1ZXN0aW9ucyBiZWxvdy4gWW91IGNhbiBzdWJtaXQgZWl0aGVyIHRoZSBIVE1MIHZlcnNpb24gb2YgdGhlIG5vdGVib29rIE9SIGFuIGV4cG9ydGVkIFBERi4gT05MWSB0aGVzZSB0d28gZm9ybWF0cyB3aWxsIGJlIGFjY2VwdGVkICEhISAoRE8gTk9UIHN1Ym1pdCB0aGUgLlJtZCBmaWxlKQ0KDQpNYWtlIHN1cmUgdGhlIGRvY3VtZW50IHRoYXQgeW91IHN1Ym1pdCAoSFRNTCBvciB0aGUgUERGKSBpbmNsdWRlczoNCg0KYSkgVGhlIFIgY29kZSB5b3UgdXNlZCBmb3IgZWFjaCBleGVyY2lzZSBwYXJ0Lg0KDQpiKSBUaGUgUiBvdXRwdXQgeW91IGdvdCBhZnRlciBydW5uaW5nIGVhY2ggbGluZSBvZiBjb2RlLg0KDQpjKSBZb3VyIHdyaXR0ZW4gYW5zd2VycyAoaWYgbmVlZGVkKS4gSWYgYSBxdWVzdGlvbiBhc2tzIHlvdSB0byBqdXN0aWZ5L2V4cGxhaW4sIHlvdXIgbm90ZWJvb2sgbXVzdCBpbmNsdWRlIGEgdGV4dCBzZWN0aW9uIHdpdGggdGhlIGp1c3RpZmljYXRpb24vZXhwbGFuYXRpb24uDQoNCg0KRGF0YXNldA0KDQpUaGUgZGF0YXNldCB5b3UgYXJlIGdvaW5nIHRvIHVzZSBmb3IgdGhpcyBhc3NpZ25tZW50IGlzIGNhbGxlZCBIaXR0ZXJzX0ZpeGVkLCB3aGljaCBpcyBhIGNsZWFuZWQgdmVyc2lvbiBvZiB0aGUgSGl0dGVycyBkYXRhc2V0LiBGaXJzdCwgeW91IGFyZSBnb2luZyB0byByZWFkIHRoZSBIaXR0ZXJzIGRhdGFzZXQ7IHRoZW4sIHlvdSB3aWxsIGNsZWFuIGl0IHRvIGdldCB0aGUgSGl0dGVyc19GaXhlZCBkYXRhc2V0LiBUYWtlIHRoZSBmb2xsb3dpbmcgc3RlcHMgdG8gZG8gc286DQoNCi0gTG9hZCB0aGUg4oCcSVNMUuKAnSBwYWNrYWdlIGluIFIuIFRoZSDigJxJU0xS4oCdIGNvbnRhaW5zIHRoZSBIaXR0ZXJzIGRhdGFzZXQuDQoNCi0gUmVtb3ZlIHRoZSBtaXNzaW5nIGRhdGEgZnJvbSB0aGUgSGl0dGVycyBkYXRhc2V0IGFuZCBzYXZlIHRoZSByZXN1bHRzIGludG8gSGl0dGVyc19GaXhlZC4gUnVuIHRoZSBmb2xsb3dpbmcgbGluZSBvZiBjb2RlIHRvIGRvIHNvOg0KDQpIaXR0ZXJzX0ZpeGVkID0gbmEub21pdChIaXR0ZXJzICkNCg0KVGhhdCBpcyBhbGwuIE5vdyB5b3UgY2FuIHVzZSB0aGUgSGl0dGVyc19GaXhlZCBkYXRhc2V0IHRvIGRvIHRoaXMgYXNzaWdubWVudCENCk5vdGU6IElmIHlvdSB3YW50IG1vcmUgaW5mbyBhYm91dCB0aGUgdmFyaWFibGVzIGluIHRoZSBIaXR0ZXJzX0ZpeGVkIGRhdGFzZXQsIHlvdSBjYW4gZ2V0IGl0IHVzaW5nIHRoaXMgbGluazoNCmh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RvY3VtZW50L2QvMXFLZUVvV1ZuQWtybFBEd3VxN1V6NjV5Yk96clhwQkMycHBsUmJhYmNnSjAvZWRpdD91c3A9c2hhcmluZw0KDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoIklTTFIiKSANCg0KbGlicmFyeShJU0xSKQ0KDQpIaXR0ZXJzIDwtIElTTFI6OkhpdHRlcnMgDQoNCnN0cihIaXR0ZXJzKQ0KDQpzdW1tYXJ5KEhpdHRlcnMpDQoNCkhpdHRlcnNfRml4ZWQgPC1uYS5vbWl0KEhpdHRlcnMpDQpgYGANCg0KDQpRdWVzdGlvbnMNCldlIGFyZSBnb2luZyB0byBvYnRhaW4gYSByZWdyZXNzaW9uIGVxdWF0aW9uIHRvIHByZWRpY3Qg4oCcU2FsYXJ54oCdIChpLmUuLCBTYWxhcnkgaXMgdGhlIG91dGNvbWUgdmFyaWFibGUpDQpRdWVzdGlvbiAxKSBDb25kdWN0IGEgcmVncmVzc2lvbiBhbmFseXNpcyB1c2luZyDigJxIaXRz4oCdIGFzIHRoZSBvbmx5IHByZWRpY3Rvci4gQW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOg0KDQpgYGB7cn0NCnBsb3QoSGl0dGVyc19GaXhlZCRIaXRzLCBIaXR0ZXJzX0ZpeGVkJFNhbGFyeSkNCg0KYWJsaW5lKGxtKFNhbGFyeX5IaXRzLCBkYXRhID0gSGl0dGVyc19GaXhlZCksIGNvbCA9ICJyZWQiKQ0KDQphYmxpbmUoaCA9IG1lYW4oSGl0dGVyc19GaXhlZCRTYWxhcnkpLCBjb2wgPSAiYmx1ZSIpDQoNCnN1bV9sbSA8LSBsbShTYWxhcnl+SGl0cyxkYXRhPUhpdHRlcnNfRml4ZWQpDQoNCnN1bW1hcnkoc3VtX2xtKQ0KYGBgDQoNCg0KYSkgQmFzZWQgb24geW91ciByZXN1bHRzLCBkaXNjdXNzIEJPVEggdGhlIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBhbmQgdGhlIHF1YWxpdHkgb2YgdGhlIGxpbmVhciBlcXVhdGlvbiB0aGF0IHVzZXMg4oCcSGl0c+KAnSB0byBwcmVkaWN0IHRoZSBwbGF5ZXLigJlzIHNhbGFyeS4NCg0KSGl0cyBhbmQgc2FsYXJ5IGFyZSByZWxhdGVkLiBBZnRlciBhbmFseXppbmcgdGhlIHAtdmFsdWUsIGl0IGlzIGxlc3MgdGhhbiAwLjA1LiBXZSBjYW4gY29uY2x1ZGUgdGhhdCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaGl0cyBhbmQgc2FsYXJ5IGFyZSBzYXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuDQoNCmIpIFdyaXRlIG91dCB0aGUgZXF1YXRpb24gdGhhdCB5b3Ugd291bGQgdXNlIHRvIHByZWRpY3Qgc2FsYXJ5IGJhc2VkIG9uIHRoZSBwbGF5ZXLigJlzIG51bWJlciBvZiBoaXRzIGluIHRoZSAxOTg2IHNlYXNvbi4NCg0KWSA9IDYzLjA0ODggKyBIaXRzICogNC4zODU0DQoNCg0KDQpRdWVzdGlvbiAyKSBVc2UgdGhlIHNhbWUgcmVncmVzc2lvbiBhbmFseXNpcyBmcm9tIHF1ZXN0aW9uIDEgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb24uDQoNCkFzc3VtZSB0aGF0IEFzc3VtcHRpb24gMiByZWdhcmRpbmcgdGhlIHZhbGlkaXR5IG9mIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyBpcyBzYXRpc2ZpZWQuIFJ1biBhbiBhbmFseXNpcyB0byBjaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIGFsbCBvdGhlciBhc3N1bXB0aW9ucy4gQ29tbWVudCBvbiB5b3VyIGZpbmRpbmdzLg0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDIsMikpDQpwbG90KHN1bV9sbSkNCmBgYA0KQXNzdW1pbmcgdGhhdCDigJxBc3N1bXB0aW9uIDLigJ0gaXMgc2F0aXNmaWVkIHdlIGNhbiBsb29rIGF0IFBsb3QgMSAoUmVzaWR1YWxzIHZzIEZpdHRlZCBWYWx1ZXMpLiBUaGUgcmVzaWR1YWxzIHNob3cgYSBub24tbGluZWFyIHBhdHRlcm4sIHNvIHRoZSBhc3N1bXB0aW9uIGlzIG5vdCBzYXRpc2ZpZWQgYW5kIGEgcXVhZHJhdGljIG1vZGVsIHNob3VsZCBiZSB1c2VkIGluc3RlYWQgb2YgYSBsaW5lYXIgb25lLiBBc3N1bXB0aW9uIDEgaXMgbm90IHNhdGlzZmllZC4NCg0KDQoNClF1ZXN0aW9uIDMpIEFwcGx5IHRoZSBiZXN0IHN1YnNldCBzZWxlY3Rpb24gbWV0aG9kIHRvIGZpbmQgYSBnb29kIG11bHRpcGxlIGxpbmVhciBlcXVhdGlvbi4gRE8gTk9UIElOQ0xVREUgaW4gdGhlIGFuYWx5c2lzIHRoZSBmb2xsb3dpbmcgZm91ciBwcmVkaWN0b3JzOg0KDQpDSGl0cywgQ0F0QmF0LCBDUnVucywgQ1JCSQ0KDQphKSBBZnRlciBhcHBseWluZyB0aGUgYmVzdCBzdWJzZXQgc2VsZWN0aW9uIG1ldGhvZCwgd3JpdGUgdGhlIGVxdWF0aW9uIHRoYXQgaW5jbHVkZXMgdGhlIHByZWRpY3RvcnMgdGhhdCB5b3UgY29uc2lkZXIgYXBwcm9wcmlhdGUuIEpVU1RJRlkgKGJ5IHNob3dpbmcgeW91ciB3b3JrIGFuZCBjb21tZW50aW5nKSB3aHkgeW91IHNlbGVjdGVkIHRoaXMgZXF1YXRpb24uDQpgYGB7cn0NCmxpYnJhcnkobGVhcHMpDQoNCmJlc3Rfc3Vic2V0X1NhbGFyeSA8LSByZWdzdWJzZXRzKFNhbGFyeX4uLUNIaXRzIC1DQXRCYXQgLUNSdW5zIC1DUkJJLCBkYXRhPUhpdHRlcnNfRml4ZWQsIG52bWF4PTEzKSANCg0Kc3VtbWFyeShiZXN0X3N1YnNldF9TYWxhcnkpDQoNCnN1bW1hcnkoYmVzdF9zdWJzZXRfU2FsYXJ5KSRhZGpyMg0KDQoNCmFkalIyX3ZlY3RvciA8LSByb3VuZChzdW1tYXJ5KGJlc3Rfc3Vic2V0X1NhbGFyeSkkYWRqcjIsMykNCg0KYSA8LSBkYXRhLmZyYW1lKG1vZGVsX3NpemUgPC0gMToxMyxyb3VuZChzdW1tYXJ5KGJlc3Rfc3Vic2V0X1NhbGFyeSkkYWRqcjIsMykpDQoNCmNvbG5hbWVzKGEpPC1jKCJtb2RlbF9zaXplIiwiYWRqUjIiKSANCmENCg0KDQp3aGljaC5tYXgoYWRqUjJfdmVjdG9yKQ0KYGBgDQoNCmNvZWYoYmVzdF9zdWJlc3RfU2FsYXJ5LCA5KS4gV2hlbiB3ZSB1c2Ugd2hpY2gubWF4KCksIHdlIGNhbiBzZWUgdGhlIG1heCB2YWx1ZSBvZiBhZGogUjIgb2NjdXJzIGF0IHBvc2l0aW9uIDkuIFRoaXMgbWVhbnMgdGhhdCB3aGVuIHdlIGFkZCBhIDEwdGggcHJlZGljdG9yLCB0aGUgYWRqIFIyIHZhbHVlIGlzIGdvaW5nIHRvIGdvIGRvd24uIFRoZXJlZm9yZSwgYWRkaW5nIGEgMTB0aCBwcmVkaWN0b3IgZnJvbSB0aGlzIGRhdGFzZXQgaXMgbm90IHN0YXRpc3RpY2FsbHkgdmFsdWFibGUuIEl0IGlzIGJldHRlciB0byB1c2UgdGhlIGVxdWF0aW9uIHdpdGggOSBwcmVkaWN0b3JzLg0KDQoNCmIpIFdoYXQgcGVyY2VudGFnZSBvZiB0aGUgdG90YWwgdmFyaWFiaWxpdHkgaW4gdGhlIHNhbGFyeSB2YWx1ZXMgZG9lcyB0aGUgZXF1YXRpb24gdGhhdCB5b3UgY2hvc2UgaW4gMyBhKSBlbGltaW5hdGU/DQoNCmBgYHtyfQ0Kc3VtbWFyeShiZXN0X3N1YnNldF9TYWxhcnkpJHJzcVs5XQ0KYGBgDQoNCkJhc2VkIG9uIHRoZSBmdW5jdGlvbiBhYm92ZSBuZWFybHkgNTAlICgwLjQ5Nykgb2YgdGhlIHRvdGFsIHZhcmlhYmlsaXR5IGlzIGVsaW1pbmF0ZWQuDQoNCmMpIElzIHRoZSBwcmVkaWN0aW9uIGVycm9yIG9mIHRoaXMgZXF1YXRpb24gbG93IG9yIGhpZ2g/IEp1c3RpZnkgeW91ciBhbnN3ZXIgKE5vdGU6IEp1c3QgZ2l2ZSBtZSBhIHdlbGwgdGhvdWdodCwgdmVyeSBzaG9ydCwgYW5kIHNpbXBsZSBhbnN3ZXIgZm9yIHdoeSB5b3UgY29uc2lkZXIgdGhlIGVycm9yIGxvdyBvciBoaWdoKQ0KDQpJIHdvdWxkIHNheSB0aGF0IHRoZSBwcmVkaWN0aW9uIGVycm9yIGluIHRoaXMgZXF1YXRpb24gaXMgYSBiaXQgaGlnaC4gNTAlIG9mIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGlzIGV4cGxhaW5lZCBieSB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuDQoNCg==