Presentador - LUIS ANTONIO CALVO QUISPE

Perfil Linkelind

Google Drive

Video Explicativo

Resumen de Resultados


Presentación del Codigo

# Cargamos las librerias necesarias
library(fabletools)
library(feasts)
library(ggplot2)
library(dplyr)
library(tidyverse)
library(reshape2)
library(fable)
library(lubridate)
library(tsibble)
library(zoo)
library(readxl)
library(tsibbledata)
library(DataExplorer)
library(fpp3)
library(textshape)
library(stats)
library(car)
library(caret)
library(WriteXLS)
library(FactoMineR)
library(pls)
library(lattice)
library(caret)
library(openxlsx)
library(corrplot)
#install.packages('MASS')
#install.packages('pls')
#install.packages('FactoMineR')
#install.packages('textshape')
#install.packages('car')
#install.packages('corrplot')
#install.packages('caret')

# CONFIGURACION INICIAL
rm(list = ls())
graphics.off()
cat("\014")  # control + l (limpia consola)

# estabelcemosla ruta del archivo xlsx

ruta = "jaggia_ba_1e_NBA.xlsx"
datos = read_excel(ruta,"Average stat")

# Analizando Tipos de Datos ...
str(datos)

# Condiciones Generales del Problema
base_datos <- datos %>% filter(Season == 'Career' & Postseason == FALSE)
Name <- base_datos$Name
base_datos <- textshape::column_to_rownames(base_datos,loc = 2)

Salarios <- base_datos$Salary  #salarios escalados
Salarios[is.na(Salarios)] <- 0

# Desagregando Columnas no Numericas (Solo 23 Variables)
datos_filtrado <- base_datos %>%
  select(-Position,-Season,-Postseason,-Team,-Player,-Salary) 

# Analizando Tipos de Datos ...
str(datos_filtrado)

# Eliminando datos Nulos
datos_filtrado <- mutate_all(datos_filtrado, ~replace(., is.na(.), 0))
 
# Aplicando PCA -- Datos Filtrados no NUlos!
datos_filtrado  <- scale(datos_filtrado)
datos_filtrado <- data.frame(datos_filtrado)
pca <- prcomp(datos_filtrado)

print(pca)

summary(pca)


# Matriz de Correlación

biplot(pca, scale = 0, main = 'Diagrama de Componentes Principales')

plot(pca, type = 'l', main = 'Grafica de Componentes Principales')

#Ver Los Pesos de cada una de las Variables para cada uno de los CP
pca$x

# Verctor Desviación Estandar PCA
desv_stand = pca[[1]]
desv_stand

# Vertar Varianza PCA
varianza = desv_stand^2
varianza

sum(varianza)
sum(desv_stand)
acum_var <- varianza/23*100
acum_var
porcen_var = acum_var

tam_var = length(acum_var)

for (i in 2:tam_var){
  acum_var[i] = acum_var[i] + acum_var[i-1]
}

acum_var

#convertir los datos de rotación de PCA a dataframe
pca_frame <- data.frame(pca$rotation)
round(pca_frame,5)


#extraer los nombre de las columnas de myData
columnas <- data.frame(colnames(pca_frame[0,]))
columnas


#crear una tabla que agregue el frame de pca despues del nombre de las columnas
pca_frame_final <- data.frame(columnas,pca_frame)

#Rotar el porcentaje de varianza y su acumulador en un dataframes
acum_var_frame <- data.frame(t(acum_var))
porcen_var_frame <- data.frame(t(porcen_var))

#Convertir porcentaje de varianza y su acumulador en una sola tabla
varianza_frame <- rbind(porcen_var_frame, acum_var_frame)

#Crear un arreglo con el nombre de las columnas de porcentaje de varianza
#y el acumulador de varianza
columnas_varianza <- data.frame(c("Variance %", "Cumulative Variance %"))

#combinas los nombres y los valores de porcentaje de varianza
#y acumulador de varianza en un frame final de varianza
varianza_frame <- cbind(columnas_varianza, varianza_frame)

#cambiar de nombres a las columnas de frame final de varianza con los
#nombre del frame final de pca
colnames(varianza_frame) <- colnames(pca_frame_final)

#agregar el frame final de varianza al frame final de pca
pca_frame_final <- rbind(pca_frame_final,varianza_frame)

#nombrar las filas del pca final con la columna name
rownames(pca_frame_final) <- pca_frame_final$name
pca_frame_final

#exportar la tabla de pca final
write.xlsx(pca_frame_final, "NBA_feature.xlsx")

#borrar la columna de name
pca_frame_final <- pca_frame_final[,-1]
pca_frame_final

#Ver los pesos de la PCA
pca_pesos <- pca$x


#Combinar los nombres de los jugadores y los pesos de los mismos
newdata <- data.frame(pca$x)
newdata_nombre <- data.frame(Name,pca$x)

newdata

#Elegir los 7 pesos principales
newdata_nombre <- newdata_nombre[,-(9:24)]
newdata <- newdata[,-(8:24)]

head(newdata_nombre)

#Exportar la tabla de jugaremos con sus pesos y renombrar el nombre a jugadores
newdata <- rename(newdata, Player = Name)
write.xlsx(newdata, "NBA_players.xlsx")

Nueva_Data <- newdata

# Realizando el Analisis de los 7 Componentes Principales

head(Nueva_Data)
 
modelo1 <- lm(Salarios~. , data = Nueva_Data)

summary(modelo1)

boxplot(modelo1$residuals)

modelo1$coefficients

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


# Rediseñando el Modelo

head(Nueva_Data)

Nueva_Data_Modelo <- Nueva_Data

Nueva_Data_Modelo$PC4 <- NULL
Nueva_Data_Modelo$PC5 <- NULL
Nueva_Data_Modelo$PC7 <- NULL

modelo2 <- lm(Salarios~. , data = Nueva_Data_Modelo )


summary(modelo2)

boxplot(modelo2$residuals)

modelo2$coefficients

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

Resultados

Resumen de Resultados

Graficas Representativas



Diagrama de Correlación


Modelo de Regresión Lineal - 7 Componentes Principales

> summary(modelo1)

Call:
lm(formula = Salarios ~ ., data = Nueva_Data)

Residuals:
      Min        1Q    Median        3Q       Max 
-11567739  -1997608   -141454   1814543  12256955 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4736726     176500  26.837  < 2e-16 ***
PC1         -1106392      55467 -19.947  < 2e-16 ***
PC2           220369      74646   2.952  0.00332 ** 
PC3           457181     141209   3.238  0.00129 ** 
PC4           -22548     160241  -0.141  0.88816    
PC5           153901     203414   0.757  0.44969    
PC6          -660629     213690  -3.092  0.00212 ** 
PC7          -147796     221933  -0.666  0.50579    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3765000 on 447 degrees of freedom
Multiple R-squared:  0.489, Adjusted R-squared:  0.4809 
F-statistic:  61.1 on 7 and 447 DF,  p-value: < 2.2e-16
> modelo1$coefficients
(Intercept)         PC1         PC2         PC3         PC4         PC5 
 4736725.61 -1106391.70   220369.16   457181.26   -22548.12   153901.10 
        PC6         PC7 
 -660628.58  -147796.44

Redefiniendo - Modelo de Regresión Lineal

> summary(modelo2)

Call:
lm(formula = Salarios ~ ., data = Nueva_Data_Modelo)

Residuals:
      Min        1Q    Median        3Q       Max 
-11353541  -2029775   -175004   1909529  11841551 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4736726     176115  26.896  < 2e-16 ***
PC1         -1106392      55346 -19.991  < 2e-16 ***
PC2           220369      74483   2.959  0.00325 ** 
PC3           457181     140900   3.245  0.00126 ** 
PC6          -660629     213223  -3.098  0.00207 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3757000 on 450 degrees of freedom
Multiple R-squared:  0.4878,    Adjusted R-squared:  0.4832 
F-statistic: 107.1 on 4 and 450 DF,  p-value: < 2.2e-16
> modelo2$coefficients
(Intercept)         PC1         PC2         PC3         PC6 
  4736725.6  -1106391.7    220369.2    457181.3   -660628.6 

Diagrama del Diablo

LS0tDQp0aXRsZTogIlByb3llY3RvIEZpbmFsIGRlIEFkdmFuY2VkIEFuYWx5dGljcyINCmF1dGhvcjogIkNhbHZvIFF1aXNwZSwgTHVpcyBBbnRvbmlvIg0KZGF0ZTogIjIwMjIvMDYvMjkiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KLS0tDQoNCjwhLS0gQmllbnZlbmlkb3MgYWwgUHJveWVjdG8gZGUgTHVpcyBBbnRvbmlvIENhbHZvIFF1aXNwZSAtLT4NCg0KPGNlbnRlcj4NCg0KIVtdKEJpZy1EYXRhLXktQW5hbHl0aWNzLnBuZykNCg0KPC9jZW50ZXI+DQoNCjxjZW50ZXI+DQojIFByZXNlbnRhZG9yIC0gTFVJUyBBTlRPTklPIENBTFZPIFFVSVNQRQ0KW1BlcmZpbCBMaW5rZWxpbmRdKGh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9pbi9sdWlzLWFudG9uaW8tY2Fsdm8tcXVpc3BlLTU3YTMzYjIyOS8gIkluZ3Jlc2FyIGFsIFBlcmZpbCBkZWwgQ29tcGHDsWVybyIpe3RhcmdldD0iX2JsYW5rIn0NCg0KDQpbR29vZ2xlIERyaXZlXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZHJpdmUvZm9sZGVycy8xTldjeWQtcVo4N29EZVlVdVZyc3pCcUxQZU00ZXRQdzM/dXNwPXNoYXJpbmcgIkluZ3Jlc2FyIGEgbGEgQ2FycGV0YSBDb21wYXJ0aWRhIil7dGFyZ2V0PSJfYmxhbmsifQ0KDQpbVmlkZW8gRXhwbGljYXRpdm9dKGh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9maWxlL2QvMXF3TUhIREJHaUZBZW9BUkx2Smt6dXB6Nnpra0NVcTcyL3ZpZXc/dXNwPXNoYXJpbmcgIlZpc3VhbGl6YXIgZWwgVmlkZW8gRXhwbGljYXRpdm8iKXt0YXJnZXQ9Il9ibGFuayJ9DQoNCltSZXN1bWVuIGRlIFJlc3VsdGFkb3NdKGh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9maWxlL2QvMWlQUjNCMnZHcXBlWGVaNFhsalp3TFRvZE1TTG5Mank2L3ZpZXc/dXNwPXNoYXJpbmcgIlZpc3VhbGl6YXIgZWwgcmVzdW1lbiBkZSBSZXN1bHRhZG9zIil7dGFyZ2V0PSJfYmxhbmsifQ0KDQohW10oR29vZ2xlLnBuZykNCg0KPC9jZW50ZXI+DQo8YnI+DQo8Y2VudGVyPg0KIyMgUHJlc2VudGFjacOzbiBkZWwgQ29kaWdvDQo8L2NlbnRlcj4NCg0KYGBgUg0KIyBDYXJnYW1vcyBsYXMgbGlicmVyaWFzIG5lY2VzYXJpYXMNCmxpYnJhcnkoZmFibGV0b29scykNCmxpYnJhcnkoZmVhc3RzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoZmFibGUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkodHNpYmJsZSkNCmxpYnJhcnkoem9vKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHRzaWJibGVkYXRhKQ0KbGlicmFyeShEYXRhRXhwbG9yZXIpDQpsaWJyYXJ5KGZwcDMpDQpsaWJyYXJ5KHRleHRzaGFwZSkNCmxpYnJhcnkoc3RhdHMpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KFdyaXRlWExTKQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KbGlicmFyeShwbHMpDQpsaWJyYXJ5KGxhdHRpY2UpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShvcGVueGxzeCkNCmxpYnJhcnkoY29ycnBsb3QpDQojaW5zdGFsbC5wYWNrYWdlcygnTUFTUycpDQojaW5zdGFsbC5wYWNrYWdlcygncGxzJykNCiNpbnN0YWxsLnBhY2thZ2VzKCdGYWN0b01pbmVSJykNCiNpbnN0YWxsLnBhY2thZ2VzKCd0ZXh0c2hhcGUnKQ0KI2luc3RhbGwucGFja2FnZXMoJ2NhcicpDQojaW5zdGFsbC5wYWNrYWdlcygnY29ycnBsb3QnKQ0KI2luc3RhbGwucGFja2FnZXMoJ2NhcmV0JykNCg0KIyBDT05GSUdVUkFDSU9OIElOSUNJQUwNCnJtKGxpc3QgPSBscygpKQ0KZ3JhcGhpY3Mub2ZmKCkNCmNhdCgiXDAxNCIpICAjIGNvbnRyb2wgKyBsIChsaW1waWEgY29uc29sYSkNCg0KIyBlc3RhYmVsY2Vtb3NsYSBydXRhIGRlbCBhcmNoaXZvIHhsc3gNCg0KcnV0YSA9ICJqYWdnaWFfYmFfMWVfTkJBLnhsc3giDQpkYXRvcyA9IHJlYWRfZXhjZWwocnV0YSwiQXZlcmFnZSBzdGF0IikNCg0KIyBBbmFsaXphbmRvIFRpcG9zIGRlIERhdG9zIC4uLg0Kc3RyKGRhdG9zKQ0KDQojIENvbmRpY2lvbmVzIEdlbmVyYWxlcyBkZWwgUHJvYmxlbWENCmJhc2VfZGF0b3MgPC0gZGF0b3MgJT4lIGZpbHRlcihTZWFzb24gPT0gJ0NhcmVlcicgJiBQb3N0c2Vhc29uID09IEZBTFNFKQ0KTmFtZSA8LSBiYXNlX2RhdG9zJE5hbWUNCmJhc2VfZGF0b3MgPC0gdGV4dHNoYXBlOjpjb2x1bW5fdG9fcm93bmFtZXMoYmFzZV9kYXRvcyxsb2MgPSAyKQ0KDQpTYWxhcmlvcyA8LSBiYXNlX2RhdG9zJFNhbGFyeSAgI3NhbGFyaW9zIGVzY2FsYWRvcw0KU2FsYXJpb3NbaXMubmEoU2FsYXJpb3MpXSA8LSAwDQoNCiMgRGVzYWdyZWdhbmRvIENvbHVtbmFzIG5vIE51bWVyaWNhcyAoU29sbyAyMyBWYXJpYWJsZXMpDQpkYXRvc19maWx0cmFkbyA8LSBiYXNlX2RhdG9zICU+JQ0KICBzZWxlY3QoLVBvc2l0aW9uLC1TZWFzb24sLVBvc3RzZWFzb24sLVRlYW0sLVBsYXllciwtU2FsYXJ5KSANCg0KIyBBbmFsaXphbmRvIFRpcG9zIGRlIERhdG9zIC4uLg0Kc3RyKGRhdG9zX2ZpbHRyYWRvKQ0KDQojIEVsaW1pbmFuZG8gZGF0b3MgTnVsb3MNCmRhdG9zX2ZpbHRyYWRvIDwtIG11dGF0ZV9hbGwoZGF0b3NfZmlsdHJhZG8sIH5yZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkNCiANCiMgQXBsaWNhbmRvIFBDQSAtLSBEYXRvcyBGaWx0cmFkb3Mgbm8gTlVsb3MhDQpkYXRvc19maWx0cmFkbyAgPC0gc2NhbGUoZGF0b3NfZmlsdHJhZG8pDQpkYXRvc19maWx0cmFkbyA8LSBkYXRhLmZyYW1lKGRhdG9zX2ZpbHRyYWRvKQ0KcGNhIDwtIHByY29tcChkYXRvc19maWx0cmFkbykNCg0KcHJpbnQocGNhKQ0KDQpzdW1tYXJ5KHBjYSkNCg0KDQojIE1hdHJpeiBkZSBDb3JyZWxhY2nDs24NCg0KYmlwbG90KHBjYSwgc2NhbGUgPSAwLCBtYWluID0gJ0RpYWdyYW1hIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzJykNCg0KcGxvdChwY2EsIHR5cGUgPSAnbCcsIG1haW4gPSAnR3JhZmljYSBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcycpDQoNCiNWZXIgTG9zIFBlc29zIGRlIGNhZGEgdW5hIGRlIGxhcyBWYXJpYWJsZXMgcGFyYSBjYWRhIHVubyBkZSBsb3MgQ1ANCnBjYSR4DQoNCiMgVmVyY3RvciBEZXN2aWFjacOzbiBFc3RhbmRhciBQQ0ENCmRlc3Zfc3RhbmQgPSBwY2FbWzFdXQ0KZGVzdl9zdGFuZA0KDQojIFZlcnRhciBWYXJpYW56YSBQQ0ENCnZhcmlhbnphID0gZGVzdl9zdGFuZF4yDQp2YXJpYW56YQ0KDQpzdW0odmFyaWFuemEpDQpzdW0oZGVzdl9zdGFuZCkNCmFjdW1fdmFyIDwtIHZhcmlhbnphLzIzKjEwMA0KYWN1bV92YXINCnBvcmNlbl92YXIgPSBhY3VtX3Zhcg0KDQp0YW1fdmFyID0gbGVuZ3RoKGFjdW1fdmFyKQ0KDQpmb3IgKGkgaW4gMjp0YW1fdmFyKXsNCiAgYWN1bV92YXJbaV0gPSBhY3VtX3ZhcltpXSArIGFjdW1fdmFyW2ktMV0NCn0NCg0KYWN1bV92YXINCg0KI2NvbnZlcnRpciBsb3MgZGF0b3MgZGUgcm90YWNpw7NuIGRlIFBDQSBhIGRhdGFmcmFtZQ0KcGNhX2ZyYW1lIDwtIGRhdGEuZnJhbWUocGNhJHJvdGF0aW9uKQ0Kcm91bmQocGNhX2ZyYW1lLDUpDQoNCg0KI2V4dHJhZXIgbG9zIG5vbWJyZSBkZSBsYXMgY29sdW1uYXMgZGUgbXlEYXRhDQpjb2x1bW5hcyA8LSBkYXRhLmZyYW1lKGNvbG5hbWVzKHBjYV9mcmFtZVswLF0pKQ0KY29sdW1uYXMNCg0KDQojY3JlYXIgdW5hIHRhYmxhIHF1ZSBhZ3JlZ3VlIGVsIGZyYW1lIGRlIHBjYSBkZXNwdWVzIGRlbCBub21icmUgZGUgbGFzIGNvbHVtbmFzDQpwY2FfZnJhbWVfZmluYWwgPC0gZGF0YS5mcmFtZShjb2x1bW5hcyxwY2FfZnJhbWUpDQoNCiNSb3RhciBlbCBwb3JjZW50YWplIGRlIHZhcmlhbnphIHkgc3UgYWN1bXVsYWRvciBlbiB1biBkYXRhZnJhbWVzDQphY3VtX3Zhcl9mcmFtZSA8LSBkYXRhLmZyYW1lKHQoYWN1bV92YXIpKQ0KcG9yY2VuX3Zhcl9mcmFtZSA8LSBkYXRhLmZyYW1lKHQocG9yY2VuX3ZhcikpDQoNCiNDb252ZXJ0aXIgcG9yY2VudGFqZSBkZSB2YXJpYW56YSB5IHN1IGFjdW11bGFkb3IgZW4gdW5hIHNvbGEgdGFibGENCnZhcmlhbnphX2ZyYW1lIDwtIHJiaW5kKHBvcmNlbl92YXJfZnJhbWUsIGFjdW1fdmFyX2ZyYW1lKQ0KDQojQ3JlYXIgdW4gYXJyZWdsbyBjb24gZWwgbm9tYnJlIGRlIGxhcyBjb2x1bW5hcyBkZSBwb3JjZW50YWplIGRlIHZhcmlhbnphDQojeSBlbCBhY3VtdWxhZG9yIGRlIHZhcmlhbnphDQpjb2x1bW5hc192YXJpYW56YSA8LSBkYXRhLmZyYW1lKGMoIlZhcmlhbmNlICUiLCAiQ3VtdWxhdGl2ZSBWYXJpYW5jZSAlIikpDQoNCiNjb21iaW5hcyBsb3Mgbm9tYnJlcyB5IGxvcyB2YWxvcmVzIGRlIHBvcmNlbnRhamUgZGUgdmFyaWFuemENCiN5IGFjdW11bGFkb3IgZGUgdmFyaWFuemEgZW4gdW4gZnJhbWUgZmluYWwgZGUgdmFyaWFuemENCnZhcmlhbnphX2ZyYW1lIDwtIGNiaW5kKGNvbHVtbmFzX3ZhcmlhbnphLCB2YXJpYW56YV9mcmFtZSkNCg0KI2NhbWJpYXIgZGUgbm9tYnJlcyBhIGxhcyBjb2x1bW5hcyBkZSBmcmFtZSBmaW5hbCBkZSB2YXJpYW56YSBjb24gbG9zDQojbm9tYnJlIGRlbCBmcmFtZSBmaW5hbCBkZSBwY2ENCmNvbG5hbWVzKHZhcmlhbnphX2ZyYW1lKSA8LSBjb2xuYW1lcyhwY2FfZnJhbWVfZmluYWwpDQoNCiNhZ3JlZ2FyIGVsIGZyYW1lIGZpbmFsIGRlIHZhcmlhbnphIGFsIGZyYW1lIGZpbmFsIGRlIHBjYQ0KcGNhX2ZyYW1lX2ZpbmFsIDwtIHJiaW5kKHBjYV9mcmFtZV9maW5hbCx2YXJpYW56YV9mcmFtZSkNCg0KI25vbWJyYXIgbGFzIGZpbGFzIGRlbCBwY2EgZmluYWwgY29uIGxhIGNvbHVtbmEgbmFtZQ0Kcm93bmFtZXMocGNhX2ZyYW1lX2ZpbmFsKSA8LSBwY2FfZnJhbWVfZmluYWwkbmFtZQ0KcGNhX2ZyYW1lX2ZpbmFsDQoNCiNleHBvcnRhciBsYSB0YWJsYSBkZSBwY2EgZmluYWwNCndyaXRlLnhsc3gocGNhX2ZyYW1lX2ZpbmFsLCAiTkJBX2ZlYXR1cmUueGxzeCIpDQoNCiNib3JyYXIgbGEgY29sdW1uYSBkZSBuYW1lDQpwY2FfZnJhbWVfZmluYWwgPC0gcGNhX2ZyYW1lX2ZpbmFsWywtMV0NCnBjYV9mcmFtZV9maW5hbA0KDQojVmVyIGxvcyBwZXNvcyBkZSBsYSBQQ0ENCnBjYV9wZXNvcyA8LSBwY2EkeA0KDQoNCiNDb21iaW5hciBsb3Mgbm9tYnJlcyBkZSBsb3MganVnYWRvcmVzIHkgbG9zIHBlc29zIGRlIGxvcyBtaXNtb3MNCm5ld2RhdGEgPC0gZGF0YS5mcmFtZShwY2EkeCkNCm5ld2RhdGFfbm9tYnJlIDwtIGRhdGEuZnJhbWUoTmFtZSxwY2EkeCkNCg0KbmV3ZGF0YQ0KDQojRWxlZ2lyIGxvcyA3IHBlc29zIHByaW5jaXBhbGVzDQpuZXdkYXRhX25vbWJyZSA8LSBuZXdkYXRhX25vbWJyZVssLSg5OjI0KV0NCm5ld2RhdGEgPC0gbmV3ZGF0YVssLSg4OjI0KV0NCg0KaGVhZChuZXdkYXRhX25vbWJyZSkNCg0KI0V4cG9ydGFyIGxhIHRhYmxhIGRlIGp1Z2FyZW1vcyBjb24gc3VzIHBlc29zIHkgcmVub21icmFyIGVsIG5vbWJyZSBhIGp1Z2Fkb3Jlcw0KbmV3ZGF0YSA8LSByZW5hbWUobmV3ZGF0YSwgUGxheWVyID0gTmFtZSkNCndyaXRlLnhsc3gobmV3ZGF0YSwgIk5CQV9wbGF5ZXJzLnhsc3giKQ0KDQpOdWV2YV9EYXRhIDwtIG5ld2RhdGENCg0KIyBSZWFsaXphbmRvIGVsIEFuYWxpc2lzIGRlIGxvcyA3IENvbXBvbmVudGVzIFByaW5jaXBhbGVzDQoNCmhlYWQoTnVldmFfRGF0YSkNCiANCm1vZGVsbzEgPC0gbG0oU2FsYXJpb3N+LiAsIGRhdGEgPSBOdWV2YV9EYXRhKQ0KDQpzdW1tYXJ5KG1vZGVsbzEpDQoNCmJveHBsb3QobW9kZWxvMSRyZXNpZHVhbHMpDQoNCm1vZGVsbzEkY29lZmZpY2llbnRzDQoNCnBhcihtZnJvdz1jKDIsMikpDQpwbG90KG1vZGVsbzEpDQoNCg0KIyBSZWRpc2XDsWFuZG8gZWwgTW9kZWxvDQoNCmhlYWQoTnVldmFfRGF0YSkNCg0KTnVldmFfRGF0YV9Nb2RlbG8gPC0gTnVldmFfRGF0YQ0KDQpOdWV2YV9EYXRhX01vZGVsbyRQQzQgPC0gTlVMTA0KTnVldmFfRGF0YV9Nb2RlbG8kUEM1IDwtIE5VTEwNCk51ZXZhX0RhdGFfTW9kZWxvJFBDNyA8LSBOVUxMDQoNCm1vZGVsbzIgPC0gbG0oU2FsYXJpb3N+LiAsIGRhdGEgPSBOdWV2YV9EYXRhX01vZGVsbyApDQoNCg0Kc3VtbWFyeShtb2RlbG8yKQ0KDQpib3hwbG90KG1vZGVsbzIkcmVzaWR1YWxzKQ0KDQptb2RlbG8yJGNvZWZmaWNpZW50cw0KDQpwYXIobWZyb3c9YygyLDIpKQ0KcGxvdChtb2RlbG8yKQ0KDQpgYGANCjxjZW50ZXI+IA0KIyMjIFJlc3VsdGFkb3MNCjwvY2VudGVyPg0KDQo8Y2VudGVyPg0KDQohW10oUmVzdWx0YWRvMS5wbmcpDQohW10oUmVzdWx0YWRvMi5wbmcpDQoNCltSZXN1bWVuIGRlIFJlc3VsdGFkb3NdKGh0dHBzOi8vZHJpdmUuZ29vZ2xlLmNvbS9maWxlL2QvMWlQUjNCMnZHcXBlWGVaNFhsalp3TFRvZE1TTG5Mank2L3ZpZXc/dXNwPXNoYXJpbmcgIlZpc3VhbGl6YXIgZWwgcmVzdW1lbiBkZSBSZXN1bHRhZG9zIil7dGFyZ2V0PSJfYmxhbmsifQ0KDQo8L2NlbnRlcj4NCg0KPGNlbnRlcj4NCiMjIyBHcmFmaWNhcyBSZXByZXNlbnRhdGl2YXMNCjwvY2VudGVyPg0KDQo8Y2VudGVyPg0KPGJyPg0KIVtdKEdyYWZpY2FDb21wb25lbnRlc1ByaW5jaXBhbGVzLnBuZykNCjxicj4NCjwvY2VudGVyPg0KDQo8Y2VudGVyPg0KIyMjIyAqKkRpYWdyYW1hIGRlIENvcnJlbGFjacOzbioqDQo8YnI+DQohW10oRGlhZ3JhbWFDb3JyZWxhY2nDs24ucG5nKQ0KPC9jZW50ZXI+DQoNCjxjZW50ZXI+IA0KIyMjIE1vZGVsbyBkZSBSZWdyZXNpw7NuIExpbmVhbCAtIDcgQ29tcG9uZW50ZXMgUHJpbmNpcGFsZXMNCjwvY2VudGVyPg0KDQpgYGB7cn0NCj4gc3VtbWFyeShtb2RlbG8xKQ0KDQpDYWxsOg0KbG0oZm9ybXVsYSA9IFNhbGFyaW9zIH4gLiwgZGF0YSA9IE51ZXZhX0RhdGEpDQoNClJlc2lkdWFsczoNCiAgICAgIE1pbiAgICAgICAgMVEgICAgTWVkaWFuICAgICAgICAzUSAgICAgICBNYXggDQotMTE1Njc3MzkgIC0xOTk3NjA4ICAgLTE0MTQ1NCAgIDE4MTQ1NDMgIDEyMjU2OTU1IA0KDQpDb2VmZmljaWVudHM6DQogICAgICAgICAgICBFc3RpbWF0ZSBTdGQuIEVycm9yIHQgdmFsdWUgUHIoPnx0fCkgICAgDQooSW50ZXJjZXB0KSAgNDczNjcyNiAgICAgMTc2NTAwICAyNi44MzcgIDwgMmUtMTYgKioqDQpQQzEgICAgICAgICAtMTEwNjM5MiAgICAgIDU1NDY3IC0xOS45NDcgIDwgMmUtMTYgKioqDQpQQzIgICAgICAgICAgIDIyMDM2OSAgICAgIDc0NjQ2ICAgMi45NTIgIDAuMDAzMzIgKiogDQpQQzMgICAgICAgICAgIDQ1NzE4MSAgICAgMTQxMjA5ICAgMy4yMzggIDAuMDAxMjkgKiogDQpQQzQgICAgICAgICAgIC0yMjU0OCAgICAgMTYwMjQxICAtMC4xNDEgIDAuODg4MTYgICAgDQpQQzUgICAgICAgICAgIDE1MzkwMSAgICAgMjAzNDE0ICAgMC43NTcgIDAuNDQ5NjkgICAgDQpQQzYgICAgICAgICAgLTY2MDYyOSAgICAgMjEzNjkwICAtMy4wOTIgIDAuMDAyMTIgKiogDQpQQzcgICAgICAgICAgLTE0Nzc5NiAgICAgMjIxOTMzICAtMC42NjYgIDAuNTA1NzkgICAgDQotLS0NClNpZ25pZi4gY29kZXM6ICAwIOKAmCoqKuKAmSAwLjAwMSDigJgqKuKAmSAwLjAxIOKAmCrigJkgMC4wNSDigJgu4oCZIDAuMSDigJgg4oCZIDENCg0KUmVzaWR1YWwgc3RhbmRhcmQgZXJyb3I6IDM3NjUwMDAgb24gNDQ3IGRlZ3JlZXMgb2YgZnJlZWRvbQ0KTXVsdGlwbGUgUi1zcXVhcmVkOiAgMC40ODksCUFkanVzdGVkIFItc3F1YXJlZDogIDAuNDgwOSANCkYtc3RhdGlzdGljOiAgNjEuMSBvbiA3IGFuZCA0NDcgREYsICBwLXZhbHVlOiA8IDIuMmUtMTYNCmBgYA0KDQpgYGB7cn0NCj4gbW9kZWxvMSRjb2VmZmljaWVudHMNCihJbnRlcmNlcHQpICAgICAgICAgUEMxICAgICAgICAgUEMyICAgICAgICAgUEMzICAgICAgICAgUEM0ICAgICAgICAgUEM1IA0KIDQ3MzY3MjUuNjEgLTExMDYzOTEuNzAgICAyMjAzNjkuMTYgICA0NTcxODEuMjYgICAtMjI1NDguMTIgICAxNTM5MDEuMTAgDQogICAgICAgIFBDNiAgICAgICAgIFBDNyANCiAtNjYwNjI4LjU4ICAtMTQ3Nzk2LjQ0DQpgYGANCg0KPGNlbnRlcj4gDQojIyMgUmVkZWZpbmllbmRvIC0gTW9kZWxvIGRlIFJlZ3Jlc2nDs24gTGluZWFsDQo8L2NlbnRlcj4NCmBgYHtyfQ0KPiBzdW1tYXJ5KG1vZGVsbzIpDQoNCkNhbGw6DQpsbShmb3JtdWxhID0gU2FsYXJpb3MgfiAuLCBkYXRhID0gTnVldmFfRGF0YV9Nb2RlbG8pDQoNClJlc2lkdWFsczoNCiAgICAgIE1pbiAgICAgICAgMVEgICAgTWVkaWFuICAgICAgICAzUSAgICAgICBNYXggDQotMTEzNTM1NDEgIC0yMDI5Nzc1ICAgLTE3NTAwNCAgIDE5MDk1MjkgIDExODQxNTUxIA0KDQpDb2VmZmljaWVudHM6DQogICAgICAgICAgICBFc3RpbWF0ZSBTdGQuIEVycm9yIHQgdmFsdWUgUHIoPnx0fCkgICAgDQooSW50ZXJjZXB0KSAgNDczNjcyNiAgICAgMTc2MTE1ICAyNi44OTYgIDwgMmUtMTYgKioqDQpQQzEgICAgICAgICAtMTEwNjM5MiAgICAgIDU1MzQ2IC0xOS45OTEgIDwgMmUtMTYgKioqDQpQQzIgICAgICAgICAgIDIyMDM2OSAgICAgIDc0NDgzICAgMi45NTkgIDAuMDAzMjUgKiogDQpQQzMgICAgICAgICAgIDQ1NzE4MSAgICAgMTQwOTAwICAgMy4yNDUgIDAuMDAxMjYgKiogDQpQQzYgICAgICAgICAgLTY2MDYyOSAgICAgMjEzMjIzICAtMy4wOTggIDAuMDAyMDcgKiogDQotLS0NClNpZ25pZi4gY29kZXM6ICAwIOKAmCoqKuKAmSAwLjAwMSDigJgqKuKAmSAwLjAxIOKAmCrigJkgMC4wNSDigJgu4oCZIDAuMSDigJgg4oCZIDENCg0KUmVzaWR1YWwgc3RhbmRhcmQgZXJyb3I6IDM3NTcwMDAgb24gNDUwIGRlZ3JlZXMgb2YgZnJlZWRvbQ0KTXVsdGlwbGUgUi1zcXVhcmVkOiAgMC40ODc4LAlBZGp1c3RlZCBSLXNxdWFyZWQ6ICAwLjQ4MzIgDQpGLXN0YXRpc3RpYzogMTA3LjEgb24gNCBhbmQgNDUwIERGLCAgcC12YWx1ZTogPCAyLjJlLTE2DQpgYGANCmBgYHtyfQ0KPiBtb2RlbG8yJGNvZWZmaWNpZW50cw0KKEludGVyY2VwdCkgICAgICAgICBQQzEgICAgICAgICBQQzIgICAgICAgICBQQzMgICAgICAgICBQQzYgDQogIDQ3MzY3MjUuNiAgLTExMDYzOTEuNyAgICAyMjAzNjkuMiAgICA0NTcxODEuMyAgIC02NjA2MjguNiANCmBgYA0KPGNlbnRlcj4gDQojIyMjIERpYWdyYW1hIGRlbCBEaWFibG8NCiFbXShEaWFncmFtYURpYWJsby5wbmcpDQo8L2NlbnRlcj4NCg0K