Read in Data

nba_data <- read.csv("C:/Users/patty/Documents/INFOSCI 310/2022-2023_NBA_player_stats_formatted.csv")

Data Inspection

str(nba_data)
'data.frame':   679 obs. of  30 variables:
 $ Rk    : int  1 2 3 4 5 6 6 6 7 8 ...
 $ Player: chr  "Precious Achiuwa" "Steven Adams" "Bam Adebayo" "Ochai Agbaji" ...
 $ Pos   : chr  "C" "C" "C" "SG" ...
 $ Age   : int  23 29 25 22 22 24 24 24 27 24 ...
 $ Tm    : chr  "TOR" "MEM" "MIA" "UTA" ...
 $ G     : int  55 42 75 59 77 59 36 23 72 68 ...
 $ GS    : int  12 42 75 22 20 3 3 0 70 68 ...
 $ MP    : num  20.7 27 34.6 20.5 21.8 15 14.7 15.5 27.4 32.6 ...
 $ FG    : num  3.6 3.7 8 2.8 3.2 2.2 2.3 2.1 3.4 5.9 ...
 $ FGA   : num  7.3 6.3 14.9 6.5 6.8 5 4.7 5.4 7.7 9.2 ...
 $ FG.1  : num  0.485 0.597 0.54 0.427 0.47 0.444 0.488 0.384 0.44 0.644 ...
 $ X3P   : num  0.5 0 0 1.4 1.2 1 1 1.1 2 0 ...
 $ X3PA  : num  2 0 0.2 3.9 3.5 2.7 2.4 3.1 5.1 0.1 ...
 $ X3P.  : num  0.269 0 0.083 0.355 0.353 0.384 0.402 0.361 0.399 0.1 ...
 $ X2P   : num  3 3.7 8 1.4 2 1.2 1.3 1 1.4 5.9 ...
 $ X2PA  : num  5.4 6.2 14.7 2.7 3.4 2.3 2.3 2.3 2.7 9.1 ...
 $ X2P.  : num  0.564 0.599 0.545 0.532 0.591 0.515 0.578 0.415 0.518 0.653 ...
 $ eFG.  : num  0.521 0.597 0.541 0.532 0.56 0.547 0.591 0.488 0.571 0.645 ...
 $ FT    : num  1.6 1.1 4.3 0.9 1.4 0.7 0.8 0.6 1.6 2.4 ...
 $ FTA   : num  2.3 3.1 5.4 1.2 1.9 1 1.1 0.9 1.8 3.3 ...
 $ FT.   : num  0.702 0.364 0.806 0.812 0.75 0.667 0.692 0.619 0.905 0.733 ...
 $ ORB   : num  1.8 5.1 2.5 0.7 1.1 0.3 0.2 0.3 0.8 3.3 ...
 $ DRB   : num  4.1 6.5 6.7 1.3 3.7 1.5 1.4 1.5 2.4 6.5 ...
 $ TRB   : num  6 11.5 9.2 2.1 4.8 1.7 1.6 1.8 3.3 9.8 ...
 $ AST   : num  0.9 2.3 3.2 1.1 1.3 1.8 2.1 1.4 2.3 1.7 ...
 $ STL   : num  0.6 0.9 1.2 0.3 0.6 0.5 0.7 0.3 0.9 0.8 ...
 $ BLK   : num  0.5 1.1 0.8 0.3 0.6 0.4 0.4 0.3 0.2 1.2 ...
 $ TOV   : num  1.1 1.9 2.5 0.7 0.8 0.9 1.3 0.4 1 1.4 ...
 $ PF    : num  1.9 2.3 2.8 1.7 1.9 1.5 1.6 1.3 1.6 2.3 ...
 $ PTS   : num  9.2 8.6 20.4 7.9 9 6.2 6.3 5.9 10.4 14.3 ...
summary(nba_data)
       Rk       
 Min.   :  1.0  
 1st Qu.:132.5  
 Median :264.0  
 Mean   :266.0  
 3rd Qu.:399.5  
 Max.   :539.0  
    Player         
 Length:679        
 Class :character  
 Mode  :character  
                   
                   
                   
     Pos           
 Length:679        
 Class :character  
 Mode  :character  
                   
                   
                   
      Age       
 Min.   :19.00  
 1st Qu.:23.00  
 Median :25.00  
 Mean   :26.03  
 3rd Qu.:29.00  
 Max.   :42.00  
      Tm           
 Length:679        
 Class :character  
 Mode  :character  
                   
                   
                   
       G        
 Min.   : 1.00  
 1st Qu.:22.00  
 Median :45.00  
 Mean   :43.34  
 3rd Qu.:65.50  
 Max.   :83.00  
       GS       
 Min.   : 0.00  
 1st Qu.: 0.00  
 Median : 6.00  
 Mean   :20.07  
 3rd Qu.:36.50  
 Max.   :83.00  
       MP       
 Min.   : 1.00  
 1st Qu.:12.15  
 Median :18.80  
 Mean   :19.46  
 3rd Qu.:27.55  
 Max.   :41.00  
       FG        
 Min.   : 0.000  
 1st Qu.: 1.500  
 Median : 2.600  
 Mean   : 3.249  
 3rd Qu.: 4.200  
 Max.   :11.200  
      FGA        
 Min.   : 0.000  
 1st Qu.: 3.400  
 Median : 5.700  
 Mean   : 6.921  
 3rd Qu.: 9.200  
 Max.   :22.200  
      FG.1       
 Min.   :0.0000  
 1st Qu.:0.4150  
 Median :0.4540  
 Mean   :0.4622  
 3rd Qu.:0.5050  
 Max.   :1.0000  
      X3P        
 Min.   :0.0000  
 1st Qu.:0.3000  
 Median :0.8000  
 Mean   :0.9965  
 3rd Qu.:1.5000  
 Max.   :4.9000  
      X3PA       
 Min.   : 0.000  
 1st Qu.: 1.000  
 Median : 2.400  
 Mean   : 2.783  
 3rd Qu.: 4.150  
 Max.   :11.400  
      X3P.       
 Min.   :0.0000  
 1st Qu.:0.2860  
 Median :0.3460  
 Mean   :0.3181  
 3rd Qu.:0.3880  
 Max.   :1.0000  
      X2P        
 Min.   : 0.000  
 1st Qu.: 0.900  
 Median : 1.600  
 Mean   : 2.255  
 3rd Qu.: 3.000  
 Max.   :10.500  
      X2PA       
 Min.   : 0.000  
 1st Qu.: 1.700  
 Median : 3.100  
 Mean   : 4.138  
 3rd Qu.: 5.550  
 Max.   :17.800  
      X2P.       
 Min.   :0.0000  
 1st Qu.:0.4840  
 Median :0.5350  
 Mean   :0.5271  
 3rd Qu.:0.5940  
 Max.   :1.0000  
      eFG.       
 Min.   :0.0000  
 1st Qu.:0.4960  
 Median :0.5370  
 Mean   :0.5329  
 3rd Qu.:0.5790  
 Max.   :1.0000  
       FT        
 Min.   : 0.000  
 1st Qu.: 0.400  
 Median : 0.900  
 Mean   : 1.367  
 3rd Qu.: 1.700  
 Max.   :10.000  
      FTA        
 Min.   : 0.000  
 1st Qu.: 0.600  
 Median : 1.200  
 Mean   : 1.769  
 3rd Qu.: 2.300  
 Max.   :12.300  
      FT.        
 Min.   :0.0000  
 1st Qu.:0.6670  
 Median :0.7600  
 Mean   :0.7116  
 3rd Qu.:0.8410  
 Max.   :1.0000  
      ORB        
 Min.   :0.0000  
 1st Qu.:0.3000  
 Median :0.7000  
 Mean   :0.8423  
 3rd Qu.:1.1000  
 Max.   :5.1000  
      DRB      
 Min.   :0.00  
 1st Qu.:1.40  
 Median :2.30  
 Mean   :2.62  
 3rd Qu.:3.40  
 Max.   :9.60  
      TRB        
 Min.   : 0.000  
 1st Qu.: 1.800  
 Median : 3.000  
 Mean   : 3.461  
 3rd Qu.: 4.500  
 Max.   :12.500  
      AST        
 Min.   : 0.000  
 1st Qu.: 0.800  
 Median : 1.300  
 Mean   : 2.012  
 3rd Qu.: 2.700  
 Max.   :10.700  
      STL        
 Min.   :0.0000  
 1st Qu.:0.3000  
 Median :0.5000  
 Mean   :0.6018  
 3rd Qu.:0.8000  
 Max.   :3.0000  
      BLK        
 Min.   :0.0000  
 1st Qu.:0.1000  
 Median :0.3000  
 Mean   :0.3704  
 3rd Qu.:0.5000  
 Max.   :3.0000  
      TOV       
 Min.   :0.000  
 1st Qu.:0.500  
 Median :0.900  
 Mean   :1.067  
 3rd Qu.:1.400  
 Max.   :4.100  
       PF       
 Min.   :0.000  
 1st Qu.:1.200  
 Median :1.600  
 Mean   :1.661  
 3rd Qu.:2.200  
 Max.   :5.000  
      PTS        
 Min.   : 0.000  
 1st Qu.: 4.100  
 Median : 6.900  
 Mean   : 8.859  
 3rd Qu.:11.550  
 Max.   :33.100  
head(nba_data)
NA

Data Cleaning (if needed)

nba_data <- na.omit(nba_data)

Compute metrics Calculate points per minute as an efficiency indicator

nba_data$Efficiency <- nba_data$PTS / nba_data$MP

Statistical Analysis a)Descriptive statistics

mean(nba_data$Efficiency)
[1] 0.4215845
median(nba_data$Efficiency)
[1] 0.4049296
sd(nba_data$Efficiency)
[1] 0.1566084

Group Analysis Examine efficiency by player positions

aggregate(nba_data$Efficiency, by=list(nba_data$Pos), mean)
  1. Correlation Analysis
  1. Efficiency vs Points per game
cor(nba_data$Efficiency, nba_data$PTS)
[1] 0.7428214
  1. Efficiency vs Total Rebounds
cor(nba_data$Efficiency, nba_data$TRB)
[1] 0.3615683
  1. Efficiency vs Assist
cor(nba_data$Efficiency, nba_data$AST)
[1] 0.4172295
  1. Efficiency vs effective Field Goal Percentage
cor(nba_data$Efficiency, nba_data$eFG.)
[1] 0.4044894
  1. Efficiency vs 3-Point Percentage
cor(nba_data$Efficiency, nba_data$X3P.)
[1] 0.2269389

6.Efficiency vs Free Throw Percentage

cor(nba_data$Efficiency, nba_data$FT.)
[1] 0.2536861
  1. Efficiency vs Minutes Played
cor(nba_data$Efficiency, nba_data$MP)
[1] 0.4436417
  1. Efficiency vs Turnovers
cor(nba_data$Efficiency, nba_data$TOV)
[1] 0.5650747
  1. Efficiency vs Personal Fouls
cor(nba_data$Efficiency, nba_data$PF)
[1] 0.2586232
  1. Visualization
install.packages("ggplot2")
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/patty/AppData/Local/R/win-library/4.3’
(as ‘lib’ is unspecified)
trying URL 'https://cran.rstudio.com/bin/windows/contrib/4.3/ggplot2_3.4.4.zip'
Content type 'application/zip' length 4299925 bytes (4.1 MB)
downloaded 4.1 MB
package ‘ggplot2’ successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\patty\AppData\Local\Temp\RtmpIVyESS\downloaded_packages
library("ggplot2")
Warning: package ‘ggplot2’ was built under R version 4.3.2
  1. Efficiency vs Points Per Game
ggplot(nba_data, aes(x=Efficiency, y=PTS)) +
  geom_point() +
  geom_smooth(method="lm", color="blue") +
  ggtitle("Efficiency vs Points Per Game") +
  xlab("Efficiency") + ylab("Points Per Game")

  1. Efficiency vs Total Rebounds
ggplot(nba_data, aes(x=Efficiency, y=TRB)) +
  geom_point() + 
  geom_smooth(method="lm",color="blue") +
  ggtitle("Efficiency vs Total Rbounds") +
  xlab("Efficiency") + ylab("Total Rebounds")

  1. Efficiency vs Assists
ggplot(nba_data, aes(x=Efficiency, y=AST)) +
  geom_point() +
  geom_smooth(method="lm", color="blue") +
  ggtitle("Efficiency vs. Assists") +
  xlab("Efficiency") + ylab("Assists")

  1. Efficiency vs Field Goal Percentage
ggplot(nba_data, aes(x=Efficiency, y=eFG.)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. Field Goal Percentage") +
    xlab("Efficiency") + ylab("Field Goal Percentage")

  1. Efficiency vs 3-point percentage
ggplot(nba_data, aes(x=Efficiency, y=X3P.)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. 3-Point Percentage") +
    xlab("Efficiency") + ylab("3-Point Percentage")

  1. Efficiency vs Free Throw percentage
ggplot(nba_data, aes(x=Efficiency, y=FT.)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. Free Throw Percentage") +
    xlab("Efficiency") + ylab("Free Throw Percentage")

  1. Efficiency vs Minutes Played
ggplot(nba_data, aes(x=Efficiency, y=MP)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. Minutes Played") +
    xlab("Efficiency") + ylab("Minutes Played")

  1. Efficiency vs Turnovers (TOV)
ggplot(nba_data, aes(x=Efficiency, y=TOV)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. Turnovers") +
    xlab("Efficiency") + ylab("Turnovers")

  1. Efficiency vs Personal Fouls (PF)
ggplot(nba_data, aes(x=Efficiency, y=PF)) +
    geom_point() +
    geom_smooth(method="lm", color="blue") +
    ggtitle("Efficiency vs. Personal Fouls") +
    xlab("Efficiency") + ylab("Personal Fouls")

Boxplot of Efficiency by Position

ggplot(nba_data, aes(x=Pos, y=Efficiency)) +
  geom_boxplot() +
  ggtitle("Distribution of Efficiency by Position") +
  xlab("Position") + ylab("Efficiency")

Scatter Plot of Efficiency vs Points per Game, Colored by Position

ggplot(nba_data, aes(x=Efficiency, y=PTS, color=Pos)) +
  geom_point() +
  ggtitle("Efficiency vs Points per Game by Position") +
  xlab("Efficiency") + ylab("Points per Game")

Facetted Scatter Plot for Each Postion

ggplot(nba_data, aes(x=Efficiency, y=PTS)) + 
  geom_point() +
  facet_wrap(~Pos) +
  ggtitle("Efficiency vs Points per Game for Each position") +
  xlab("Efficiency") + ylab("Points per Game")

Boxplot of Efficiency by Team

ggplot(nba_data, aes(x=Tm, y=Efficiency)) +
  geom_boxplot() +
  ggtitle("Distribution of Player Efficiency Across NBA Teams") +
  xlab("Team") + ylab("Efficiency") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Team Avg Eff

team_efficiency <- aggregate(Efficiency ~ Tm, data = nba_data, mean)
ggplot(team_efficiency, aes(x=Tm, y=Efficiency)) +
  geom_bar(stat="identity") +
  ggtitle("Average Efficiency of NBA Teams") +
  xlab("Team") + ylab("Average Efficiency") +
  theme(axis.text.x = element_text(angle= 90, hjust = 1))

Histogram of Player Efficiency

ggplot(nba_data, aes(x=Efficiency)) +
    geom_histogram(binwidth = 0.1, fill="blue", color="black") +
    ggtitle("Histogram of Player Efficiency") +
    xlab("Efficiency") + ylab("Frequency")

Efficiency vs Age Scatter Plot

ggplot(nba_data, aes(x=Age, y=Efficiency)) +
    geom_point() +
    geom_smooth(method="lm", color="red") +
    ggtitle("Efficiency vs. Age") +
    xlab("Age") + ylab("Efficiency")

Efficiency Heatmap by Position and Team

ggplot(nba_data, aes(x=Tm, y=Pos, fill=Efficiency)) +
    geom_tile() +
    scale_fill_gradient(low="white", high="red") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 8),  # Adjust angle and size
          axis.text.y = element_text(size = 8)) +
    ggtitle("Efficiency Heatmap by Position and Team") +
    xlab("Team") + ylab("Position")

NA
NA
LS0tDQp0aXRsZTogIk5CQSBQbGF5ZXIgRWZmaWNpZW5jeSBBbmFseXNpcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClJlYWQgaW4gRGF0YQ0KYGBge3J9DQpuYmFfZGF0YSA8LSByZWFkLmNzdigiQzovVXNlcnMvcGF0dHkvRG9jdW1lbnRzL0lORk9TQ0kgMzEwLzIwMjItMjAyM19OQkFfcGxheWVyX3N0YXRzX2Zvcm1hdHRlZC5jc3YiKQ0KYGBgDQoNCkRhdGEgSW5zcGVjdGlvbg0KYGBge3J9DQpzdHIobmJhX2RhdGEpDQpzdW1tYXJ5KG5iYV9kYXRhKQ0KaGVhZChuYmFfZGF0YSkNCg0KYGBgDQpEYXRhIENsZWFuaW5nIChpZiBuZWVkZWQpDQpgYGB7cn0NCm5iYV9kYXRhIDwtIG5hLm9taXQobmJhX2RhdGEpDQpgYGANCg0KQ29tcHV0ZSBtZXRyaWNzDQpDYWxjdWxhdGUgcG9pbnRzIHBlciBtaW51dGUgYXMgYW4gZWZmaWNpZW5jeSBpbmRpY2F0b3INCg0KYGBge3J9DQpuYmFfZGF0YSRFZmZpY2llbmN5IDwtIG5iYV9kYXRhJFBUUyAvIG5iYV9kYXRhJE1QDQpgYGANCg0KU3RhdGlzdGljYWwgQW5hbHlzaXMNCmEpRGVzY3JpcHRpdmUgc3RhdGlzdGljcw0KDQpgYGB7cn0NCm1lYW4obmJhX2RhdGEkRWZmaWNpZW5jeSkNCm1lZGlhbihuYmFfZGF0YSRFZmZpY2llbmN5KQ0Kc2QobmJhX2RhdGEkRWZmaWNpZW5jeSkNCmBgYA0KR3JvdXAgQW5hbHlzaXMNCkV4YW1pbmUgZWZmaWNpZW5jeSBieSBwbGF5ZXIgcG9zaXRpb25zDQoNCmBgYHtyfQ0KYWdncmVnYXRlKG5iYV9kYXRhJEVmZmljaWVuY3ksIGJ5PWxpc3QobmJhX2RhdGEkUG9zKSwgbWVhbikNCmBgYA0KQykgQ29ycmVsYXRpb24gQW5hbHlzaXMNCg0KMS4gRWZmaWNpZW5jeSB2cyBQb2ludHMgcGVyIGdhbWUNCg0KYGBge3J9DQpjb3IobmJhX2RhdGEkRWZmaWNpZW5jeSwgbmJhX2RhdGEkUFRTKQ0KYGBgDQoyLiBFZmZpY2llbmN5IHZzIFRvdGFsIFJlYm91bmRzDQoNCmBgYHtyfQ0KY29yKG5iYV9kYXRhJEVmZmljaWVuY3ksIG5iYV9kYXRhJFRSQikNCmBgYA0KDQozLiBFZmZpY2llbmN5IHZzIEFzc2lzdA0KDQpgYGB7cn0NCmNvcihuYmFfZGF0YSRFZmZpY2llbmN5LCBuYmFfZGF0YSRBU1QpDQpgYGANCg0KNC4gRWZmaWNpZW5jeSB2cyBlZmZlY3RpdmUgRmllbGQgR29hbCBQZXJjZW50YWdlDQoNCmBgYHtyfQ0KY29yKG5iYV9kYXRhJEVmZmljaWVuY3ksIG5iYV9kYXRhJGVGRy4pDQpgYGANCg0KNS4gRWZmaWNpZW5jeSB2cyAzLVBvaW50IFBlcmNlbnRhZ2UNCg0KYGBge3J9DQpjb3IobmJhX2RhdGEkRWZmaWNpZW5jeSwgbmJhX2RhdGEkWDNQLikNCmBgYA0KDQo2LkVmZmljaWVuY3kgdnMgRnJlZSBUaHJvdyBQZXJjZW50YWdlDQoNCmBgYHtyfQ0KY29yKG5iYV9kYXRhJEVmZmljaWVuY3ksIG5iYV9kYXRhJEZULikNCmBgYA0KDQo3LiBFZmZpY2llbmN5IHZzIE1pbnV0ZXMgUGxheWVkDQoNCmBgYHtyfQ0KY29yKG5iYV9kYXRhJEVmZmljaWVuY3ksIG5iYV9kYXRhJE1QKQ0KYGBgDQo4LiBFZmZpY2llbmN5IHZzIFR1cm5vdmVycw0KDQpgYGB7cn0NCmNvcihuYmFfZGF0YSRFZmZpY2llbmN5LCBuYmFfZGF0YSRUT1YpDQpgYGANCg0KOS4gRWZmaWNpZW5jeSB2cyBQZXJzb25hbCBGb3Vscw0KDQpgYGB7cn0NCmNvcihuYmFfZGF0YSRFZmZpY2llbmN5LCBuYmFfZGF0YSRQRikNCmBgYA0KDQpEKSBWaXN1YWxpemF0aW9uDQoNCmBgYHtyfQ0KaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQoNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCmBgYA0KDQoNCg0KMS4gRWZmaWNpZW5jeSB2cyBQb2ludHMgUGVyIEdhbWUNCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PUVmZmljaWVuY3ksIHk9UFRTKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9ImJsdWUiKSArDQogIGdndGl0bGUoIkVmZmljaWVuY3kgdnMgUG9pbnRzIFBlciBHYW1lIikgKw0KICB4bGFiKCJFZmZpY2llbmN5IikgKyB5bGFiKCJQb2ludHMgUGVyIEdhbWUiKQ0KYGBgDQoNCg0KMi4gRWZmaWNpZW5jeSB2cyBUb3RhbCBSZWJvdW5kcw0KDQpgYGB7cn0NCmdncGxvdChuYmFfZGF0YSwgYWVzKHg9RWZmaWNpZW5jeSwgeT1UUkIpKSArDQogIGdlb21fcG9pbnQoKSArIA0KICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIixjb2xvcj0iYmx1ZSIpICsNCiAgZ2d0aXRsZSgiRWZmaWNpZW5jeSB2cyBUb3RhbCBSYm91bmRzIikgKw0KICB4bGFiKCJFZmZpY2llbmN5IikgKyB5bGFiKCJUb3RhbCBSZWJvdW5kcyIpDQpgYGANCjMuIEVmZmljaWVuY3kgdnMgQXNzaXN0cw0KDQpgYGB7cn0NCmdncGxvdChuYmFfZGF0YSwgYWVzKHg9RWZmaWNpZW5jeSwgeT1BU1QpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2xvcj0iYmx1ZSIpICsNCiAgZ2d0aXRsZSgiRWZmaWNpZW5jeSB2cy4gQXNzaXN0cyIpICsNCiAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiQXNzaXN0cyIpDQpgYGANCg0KNC4gRWZmaWNpZW5jeSB2cyBGaWVsZCBHb2FsIFBlcmNlbnRhZ2UNCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PUVmZmljaWVuY3ksIHk9ZUZHLikpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2xvcj0iYmx1ZSIpICsNCiAgICBnZ3RpdGxlKCJFZmZpY2llbmN5IHZzLiBGaWVsZCBHb2FsIFBlcmNlbnRhZ2UiKSArDQogICAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiRmllbGQgR29hbCBQZXJjZW50YWdlIikNCg0KYGBgDQo1LiBFZmZpY2llbmN5IHZzIDMtcG9pbnQgcGVyY2VudGFnZQ0KDQpgYGB7cn0NCmdncGxvdChuYmFfZGF0YSwgYWVzKHg9RWZmaWNpZW5jeSwgeT1YM1AuKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbG9yPSJibHVlIikgKw0KICAgIGdndGl0bGUoIkVmZmljaWVuY3kgdnMuIDMtUG9pbnQgUGVyY2VudGFnZSIpICsNCiAgICB4bGFiKCJFZmZpY2llbmN5IikgKyB5bGFiKCIzLVBvaW50IFBlcmNlbnRhZ2UiKQ0KDQpgYGANCg0KNi4gRWZmaWNpZW5jeSB2cyBGcmVlIFRocm93IHBlcmNlbnRhZ2UNCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PUVmZmljaWVuY3ksIHk9RlQuKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbG9yPSJibHVlIikgKw0KICAgIGdndGl0bGUoIkVmZmljaWVuY3kgdnMuIEZyZWUgVGhyb3cgUGVyY2VudGFnZSIpICsNCiAgICB4bGFiKCJFZmZpY2llbmN5IikgKyB5bGFiKCJGcmVlIFRocm93IFBlcmNlbnRhZ2UiKQ0KDQpgYGANCjcuIEVmZmljaWVuY3kgdnMgTWludXRlcyBQbGF5ZWQNCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PUVmZmljaWVuY3ksIHk9TVApKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9ImJsdWUiKSArDQogICAgZ2d0aXRsZSgiRWZmaWNpZW5jeSB2cy4gTWludXRlcyBQbGF5ZWQiKSArDQogICAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiTWludXRlcyBQbGF5ZWQiKQ0KDQpgYGANCjguIEVmZmljaWVuY3kgdnMgVHVybm92ZXJzIChUT1YpDQoNCmBgYHtyfQ0KZ2dwbG90KG5iYV9kYXRhLCBhZXMoeD1FZmZpY2llbmN5LCB5PVRPVikpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBjb2xvcj0iYmx1ZSIpICsNCiAgICBnZ3RpdGxlKCJFZmZpY2llbmN5IHZzLiBUdXJub3ZlcnMiKSArDQogICAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiVHVybm92ZXJzIikNCg0KYGBgDQo5LiBFZmZpY2llbmN5IHZzIFBlcnNvbmFsIEZvdWxzIChQRikNCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PUVmZmljaWVuY3ksIHk9UEYpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9ImJsdWUiKSArDQogICAgZ2d0aXRsZSgiRWZmaWNpZW5jeSB2cy4gUGVyc29uYWwgRm91bHMiKSArDQogICAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiUGVyc29uYWwgRm91bHMiKQ0KDQpgYGANCg0KQm94cGxvdCBvZiBFZmZpY2llbmN5IGJ5IFBvc2l0aW9uDQoNCmBgYHtyfQ0KZ2dwbG90KG5iYV9kYXRhLCBhZXMoeD1Qb3MsIHk9RWZmaWNpZW5jeSkpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgRWZmaWNpZW5jeSBieSBQb3NpdGlvbiIpICsNCiAgeGxhYigiUG9zaXRpb24iKSArIHlsYWIoIkVmZmljaWVuY3kiKQ0KYGBgDQoNClNjYXR0ZXIgUGxvdCBvZiBFZmZpY2llbmN5IHZzIFBvaW50cyBwZXIgR2FtZSwgQ29sb3JlZCBieSBQb3NpdGlvbg0KDQpgYGB7cn0NCmdncGxvdChuYmFfZGF0YSwgYWVzKHg9RWZmaWNpZW5jeSwgeT1QVFMsIGNvbG9yPVBvcykpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgZ2d0aXRsZSgiRWZmaWNpZW5jeSB2cyBQb2ludHMgcGVyIEdhbWUgYnkgUG9zaXRpb24iKSArDQogIHhsYWIoIkVmZmljaWVuY3kiKSArIHlsYWIoIlBvaW50cyBwZXIgR2FtZSIpDQpgYGANCkZhY2V0dGVkIFNjYXR0ZXIgUGxvdCBmb3IgRWFjaCBQb3N0aW9uDQoNCmBgYHtyfQ0KZ2dwbG90KG5iYV9kYXRhLCBhZXMoeD1FZmZpY2llbmN5LCB5PVBUUykpICsgDQogIGdlb21fcG9pbnQoKSArDQogIGZhY2V0X3dyYXAoflBvcykgKw0KICBnZ3RpdGxlKCJFZmZpY2llbmN5IHZzIFBvaW50cyBwZXIgR2FtZSBmb3IgRWFjaCBwb3NpdGlvbiIpICsNCiAgeGxhYigiRWZmaWNpZW5jeSIpICsgeWxhYigiUG9pbnRzIHBlciBHYW1lIikNCmBgYA0KQm94cGxvdCBvZiBFZmZpY2llbmN5IGJ5IFRlYW0NCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PVRtLCB5PUVmZmljaWVuY3kpKSArDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIFBsYXllciBFZmZpY2llbmN5IEFjcm9zcyBOQkEgVGVhbXMiKSArDQogIHhsYWIoIlRlYW0iKSArIHlsYWIoIkVmZmljaWVuY3kiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQpgYGANClRlYW0gQXZnIEVmZg0KDQpgYGB7cn0NCnRlYW1fZWZmaWNpZW5jeSA8LSBhZ2dyZWdhdGUoRWZmaWNpZW5jeSB+IFRtLCBkYXRhID0gbmJhX2RhdGEsIG1lYW4pDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QodGVhbV9lZmZpY2llbmN5LCBhZXMoeD1UbSwgeT1FZmZpY2llbmN5KSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgZ2d0aXRsZSgiQXZlcmFnZSBFZmZpY2llbmN5IG9mIE5CQSBUZWFtcyIpICsNCiAgeGxhYigiVGVhbSIpICsgeWxhYigiQXZlcmFnZSBFZmZpY2llbmN5IikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT0gOTAsIGhqdXN0ID0gMSkpDQpgYGANCg0KSGlzdG9ncmFtIG9mIFBsYXllciBFZmZpY2llbmN5DQoNCmBgYHtyfQ0KZ2dwbG90KG5iYV9kYXRhLCBhZXMoeD1FZmZpY2llbmN5KSkgKw0KICAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xLCBmaWxsPSJibHVlIiwgY29sb3I9ImJsYWNrIikgKw0KICAgIGdndGl0bGUoIkhpc3RvZ3JhbSBvZiBQbGF5ZXIgRWZmaWNpZW5jeSIpICsNCiAgICB4bGFiKCJFZmZpY2llbmN5IikgKyB5bGFiKCJGcmVxdWVuY3kiKQ0KDQpgYGANCkVmZmljaWVuY3kgdnMgQWdlIFNjYXR0ZXIgUGxvdA0KDQpgYGB7cn0NCmdncGxvdChuYmFfZGF0YSwgYWVzKHg9QWdlLCB5PUVmZmljaWVuY3kpKSArDQogICAgZ2VvbV9wb2ludCgpICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgY29sb3I9InJlZCIpICsNCiAgICBnZ3RpdGxlKCJFZmZpY2llbmN5IHZzLiBBZ2UiKSArDQogICAgeGxhYigiQWdlIikgKyB5bGFiKCJFZmZpY2llbmN5IikNCg0KYGBgDQpFZmZpY2llbmN5IEhlYXRtYXAgYnkgUG9zaXRpb24gYW5kIFRlYW0NCg0KYGBge3J9DQpnZ3Bsb3QobmJhX2RhdGEsIGFlcyh4PVRtLCB5PVBvcywgZmlsbD1FZmZpY2llbmN5KSkgKw0KICAgIGdlb21fdGlsZSgpICsNCiAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdz0id2hpdGUiLCBoaWdoPSJyZWQiKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemUgPSA4KSwgICMgQWRqdXN0IGFuZ2xlIGFuZCBzaXplDQogICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSArDQogICAgZ2d0aXRsZSgiRWZmaWNpZW5jeSBIZWF0bWFwIGJ5IFBvc2l0aW9uIGFuZCBUZWFtIikgKw0KICAgIHhsYWIoIlRlYW0iKSArIHlsYWIoIlBvc2l0aW9uIikNCg0KDQpgYGANCg0K