This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.
plot(cars)
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file). ## analisis cluster
install.packages(“rattle.data”)#instalar paquete install.packages(“reshape”) install.packages(“ggplot2”) install.packages(“factoextra”) install.packages(“cluster”) library(“cluster”) library(“factoextra”) library(rattle.data)#cargar la libreria library(reshape) library(ggplot2)
cargar las bases de datos
data(wine, package=“rattle.data”)#cargar un dataset head(wine,10)#ver los primeros 10 datos help(wine)#ver una descripción de la información #El conjunto de datos contiene los resultados de un análisis químico de vinos cultivados en una zona # específica de Italia. # Se presentan tres tipos de vino en las 178 muestras, con los resultados de 13 análisis químicos registrados para cada muestra. # Hay una variable categórica= tipo las ottras variables .
Estadísticos Básicos
with(wine, tapply(Proanthocyanins, list(Type), mean, na.rm=TRUE))
summary(wine[,c(“Alcalinity”, “Alcohol”, “Ash”, “Color”, “Dilution”, “Flavanoids”, “Hue”, “Magnesium”, “Malic”, “Nonflavanoids”, “Phenols”, “Proanthocyanins”, “Proline”), drop=FALSE], groups=wine$Type, statistics=c(“mean”, “sd”, “IQR”, “quantiles”), quantiles=c(0,.25,.5,.75,1))
data(weather, package=“rattle.data”)#vargar una dataset head(weather)
pruebas de normalidad de la variable alcohol por tipo de vino
normalityTest(Alcohol ~ Type, test=“shapiro.test”, data=wine)
prueba<- shapiro.test(wine$Alcohol) prueba #graficas #with(wine, dotplot(Alcohol, by=Type, bin=FALSE)) boxplot(Alcohol~Type, data=wine, id.method=“y”, xlab=“qimico”, ylab=“”, main=“bosxplot de vino”)
Analisis cluster
Selección de el metodo de analisi cluster
k.means.fit <- kmeans(wine.stand, 3) # k = 3 k.means.fit attributes(k.means.fit) k.means.fit\(size k.means.fit\)betweenss # K-Means k.means.fit <- kmeans(wine.stand, 3) # k = 3 attributes(k.means.fit) clusplot(wine, k.means.fit$cluster, main=‘2D representation of the Cluster solution’, color=TRUE, shade=TRUE, labels=2, lines=0)
k.means.fit2 <- kmeans(wine.stand, 2) # k = 2 k.means.fit2 attributes(k.means.fit)
k.means.fit5 <- kmeans(wine.stand, 5) # k = 5 k.means.fit5 attributes(k.means.fit)
distancias1<-dist(wine,method=“manhattan”) cluster1<-hclust(distancias1) plot(cluster1)
distancias2<-dist(wine,method=“euclidean”) cluster2<-hclust(distancias2)
distancias3<-dist(wine,method=“maximum”) cluster3<-hclust(distancias3) wine.stand <- scale(wine[-1]) # To standarize the variables
2 Ejercicio con las frutas
los leemos sin cabecera
frutas<-read.table(“C:/Users/lenovo/Documents/alimentos2.txt”,header=FALSE,sep=“”) frutas
url= “http://analisisydecision.es/wp-content/uploads/2009/06/alimentos2.txt” frutas1<-read.table(url,header=FALSE,sep=“”) head(frutas1,10)
nombres<-c(“nombre”,“inter_hidratos”,“kcal”,“proteinas”,“grasas”) names(frutas1)<- nombres names(frutas1) frutas1.stand <- scale(frutas1[-1]) frutas1.stand k.means.fit <- kmeans(frutas1.stand, 3) k.means.fit k.means.fit1 <- kmeans(frutas1.stand, 4) attributes(k.means.fit1) attributes(k.means.fit) k.means.fit\(centers k.means.fit\)size k.means.fit\(cluster k.means.fit\)withinss k.means.fit$betweenss
wssplot <- function(data, nc=15, seed=1234){ wss <- (nrow(data)-1)*sum(apply(data,2,var)) for (i in 2:nc){ set.seed(seed) wss[i] <- sum(kmeans(data, centers=i)$withinss)} plot(1:nc, wss, type=“b”, xlab=“Number of Clusters”, ylab=“Within groups sum of squares”)}
wssplot(frutas1.stand, nc=6)
clusplot(frutas1.stand, k.means.fit\(cluster, main='2D representation of the Cluster solution', color=TRUE, shade=TRUE, labels=2, lines=0) clusplot(frutas1.stand, k.means.fit1\)cluster, main=‘2D representation of the Cluster solution’, color=TRUE, shade=TRUE, labels=2, lines=0)
table(frutas1[,1],k.means.fit$cluster)
distancias2<-dist(frutas1.stand,method=“euclidean”) cluster2<-hclust(distancias2, method=“euclidean”) cluster2
plot(cluster2) # display dendogram groups <- cutree(cluster2, k=4) # cut tree into 5 clusters plot(groups) # draw dendogram with red borders around the 5 clusters groups <- cutree(cluster2, k=4)
par(mfrow=c(2,2)) pie(colSums(frutas1[k.means.fit1$cluster==1,]),cex=0.5)
pie(colSums(interests[teen_clusters$cluster==2,]),cex=0.5)
pie(colSums(interests[teen_clusters$cluster==3,]),cex=0.5)
pie(colSums(interests[teen_clusters$cluster==4,]),cex=0.5)
distancias1<-dist(frutas,method=“manhattan”) distancias1 cluster1<-hclust(distancias1) cluster1 distancias2<-dist(frutas1.stand,method=“euclidean”) cluster2<-hclust(distancias2) cluster2 distancias3<-dist(frutas,method=“maximum”) cluster3<-hclust(distancias3) distancias4<-dist(frutas,method=“canberra”) cluster4<-hclust(distancias4)
op <- par(mfcol = c(2, 2)) #Nos permite presentar par(las =1) #el gráfico en 4 partes plot(cluster1,main=“Método Manhatan”) plot(cluster2,main=“Distancia euclídea”) plot(cluster3,main=“Distancia por máximos”) plot(cluster4,main=“Método Camberra”) paso1<-pam(distancias2,2) paso2<-pam(distancias2,3) paso3<-pam(distancias2,4) paso4<-pam(distancias2,5) par(mfrow=c(2,2)) plot(paso1) plot(paso2) plot(paso3) plot(paso4) cluster.final<- kmeans(distancias2,3) cluster.final\(size #Obtenemos el tamaño de los cluster cluster.final1<- kmeans(distancias2,4) cluster.final1\)size #Obtenemos el tamaño de los cluster cluster.final2<- kmeans(distancias2,5) cluster.final2\(size #Obtenemos el tamaño de los cluster cluster.final<- kmeans(distancias2,4) grupos<-data.frame(frutas) clus<-as.factor(cluster.final\)cluster) grupos<-cbind(data.frame(frutas),clus) grupos<-sort_df(grupos,vars=‘clus’) grupos nombres<-c(“nombre”,“inter_hidratos”,“kcal”,“proteinas”,“grasas”,“clus”) names(grupos)<-nombres aggregate(grupos\(inter_hidratos,list(grupos\)clus),mean) aggregate(grupos\(kcal,list(grupos\)clus),mean) aggregate(grupos\(proteinas,list(grupos\)clus),mean) aggregate(grupos\(grasas,list(grupos\)clus),mean)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQpwbG90KGNhcnMpDQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCiMjIGFuYWxpc2lzIGNsdXN0ZXINCg0KaW5zdGFsbC5wYWNrYWdlcygicmF0dGxlLmRhdGEiKSNpbnN0YWxhciBwYXF1ZXRlDQppbnN0YWxsLnBhY2thZ2VzKCJyZXNoYXBlIikNCmluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KaW5zdGFsbC5wYWNrYWdlcygiZmFjdG9leHRyYSIpDQppbnN0YWxsLnBhY2thZ2VzKCJjbHVzdGVyIikNCmxpYnJhcnkoImNsdXN0ZXIiKQ0KbGlicmFyeSgiZmFjdG9leHRyYSIpDQpsaWJyYXJ5KHJhdHRsZS5kYXRhKSNjYXJnYXIgbGEgbGlicmVyaWENCmxpYnJhcnkocmVzaGFwZSkNCmxpYnJhcnkoZ2dwbG90MikNCg0KDQoNCg0KI2NhcmdhciBsYXMgYmFzZXMgZGUgZGF0b3MNCmRhdGEod2luZSwgcGFja2FnZT0icmF0dGxlLmRhdGEiKSNjYXJnYXIgdW4gZGF0YXNldA0KaGVhZCh3aW5lLDEwKSN2ZXIgbG9zIHByaW1lcm9zIDEwIGRhdG9zIA0KaGVscCh3aW5lKSN2ZXIgdW5hIGRlc2NyaXBjafNuIGRlIGxhIGluZm9ybWFjafNuDQojRWwgY29uanVudG8gZGUgZGF0b3MgY29udGllbmUgbG9zIHJlc3VsdGFkb3MgZGUgdW4gYW7hbGlzaXMgcXXtbWljbyBkZSB2aW5vcyBjdWx0aXZhZG9zIGVuIHVuYSB6b25hDQojIGVzcGVj7WZpY2EgZGUgSXRhbGlhLg0KIyBTZSBwcmVzZW50YW4gdHJlcyB0aXBvcyBkZSB2aW5vIGVuIGxhcyAxNzggbXVlc3RyYXMsIGNvbiBsb3MgcmVzdWx0YWRvcyBkZSAxMyBhbuFsaXNpcyBxde1taWNvcyByZWdpc3RyYWRvcyBwYXJhIGNhZGEgbXVlc3RyYS4NCiMgSGF5IHVuYSB2YXJpYWJsZSBjYXRlZ/NyaWNhPSB0aXBvIGxhcyBvdHRyYXMgdmFyaWFibGVzIC4NCg0KI0VzdGFk7XN0aWNvcyBC4XNpY29zDQp3aXRoKHdpbmUsIHRhcHBseShQcm9hbnRob2N5YW5pbnMsIGxpc3QoVHlwZSksIG1lYW4sIG5hLnJtPVRSVUUpKQ0KDQpzdW1tYXJ5KHdpbmVbLGMoIkFsY2FsaW5pdHkiLCAiQWxjb2hvbCIsICJBc2giLCAiQ29sb3IiLCAiRGlsdXRpb24iLCAiRmxhdmFub2lkcyIsIA0KICAiSHVlIiwgIk1hZ25lc2l1bSIsICJNYWxpYyIsICJOb25mbGF2YW5vaWRzIiwgIlBoZW5vbHMiLCAiUHJvYW50aG9jeWFuaW5zIiwgIlByb2xpbmUiKSwNCiAgIGRyb3A9RkFMU0VdLCBncm91cHM9d2luZSRUeXBlLCBzdGF0aXN0aWNzPWMoIm1lYW4iLCAic2QiLCAiSVFSIiwgInF1YW50aWxlcyIpLCANCiAgcXVhbnRpbGVzPWMoMCwuMjUsLjUsLjc1LDEpKQ0KDQoNCg0KZGF0YSh3ZWF0aGVyLCBwYWNrYWdlPSJyYXR0bGUuZGF0YSIpI3ZhcmdhciB1bmEgZGF0YXNldA0KaGVhZCh3ZWF0aGVyKQ0KDQojcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIGRlIGxhIHZhcmlhYmxlIGFsY29ob2wgcG9yIHRpcG8gZGUgdmlubw0KI25vcm1hbGl0eVRlc3QoQWxjb2hvbCB+IFR5cGUsIHRlc3Q9InNoYXBpcm8udGVzdCIsIGRhdGE9d2luZSkNCnBydWViYTwtIHNoYXBpcm8udGVzdCh3aW5lJEFsY29ob2wpDQpwcnVlYmENCiNncmFmaWNhcw0KI3dpdGgod2luZSwgZG90cGxvdChBbGNvaG9sLCBieT1UeXBlLCBiaW49RkFMU0UpKQ0KYm94cGxvdChBbGNvaG9sflR5cGUsIGRhdGE9d2luZSwgaWQubWV0aG9kPSJ5IiwgeGxhYj0icWltaWNvIiwgeWxhYj0iIiwgbWFpbj0iYm9zeHBsb3QgZGUgdmlubyIpDQoNCiMjI0FuYWxpc2lzIGNsdXN0ZXINCg0KI2VzdGFuZGFyaXphciBsYSBpbmZvcm1hY2nzbiBwb3IgdmFyaWFibGUNCndpbmUuc3RhbmQgPC0gc2NhbGUod2luZVstMV0pICAjIGVsIC0xIGVzIHBvcnF1ZSBsYSBjb2x1bW5hIDEgZXMgdGlwbyB5IGVzdGEgbm8gZXMgdmFyaWFibGUgDQp3aW5lLnN0YW5kICN2ZXIgbG9zIGRhdG9zIGVzdGFuZGFyaXphZG9zDQoNCiMjUG9ycXVlIHNlIGRlYmUgZXN0YW5kYXJpemFyPw0KDQojU2VsZWNjafNuIGRlIGVsIG1ldG9kbyBkZSBhbmFsaXNpIGNsdXN0ZXINCmsubWVhbnMuZml0IDwtIGttZWFucyh3aW5lLnN0YW5kLCAzKSAjIGsgPSAzDQprLm1lYW5zLmZpdA0KYXR0cmlidXRlcyhrLm1lYW5zLmZpdCkNCmsubWVhbnMuZml0JHNpemUNCmsubWVhbnMuZml0JGJldHdlZW5zcw0KIyBLLU1lYW5zDQprLm1lYW5zLmZpdCA8LSBrbWVhbnMod2luZS5zdGFuZCwgMykgIyBrID0gMw0KYXR0cmlidXRlcyhrLm1lYW5zLmZpdCkNCmNsdXNwbG90KHdpbmUsIGsubWVhbnMuZml0JGNsdXN0ZXIsIG1haW49JzJEIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBDbHVzdGVyIHNvbHV0aW9uJywNCiAgICAgICAgIGNvbG9yPVRSVUUsIHNoYWRlPVRSVUUsDQogICAgICAgICBsYWJlbHM9MiwgbGluZXM9MCkNCg0KDQprLm1lYW5zLmZpdDIgPC0ga21lYW5zKHdpbmUuc3RhbmQsIDIpICMgayA9IDINCmsubWVhbnMuZml0Mg0KYXR0cmlidXRlcyhrLm1lYW5zLmZpdCkNCg0Kay5tZWFucy5maXQ1IDwtIGttZWFucyh3aW5lLnN0YW5kLCA1KSAjIGsgPSA1DQprLm1lYW5zLmZpdDUNCmF0dHJpYnV0ZXMoay5tZWFucy5maXQpDQoNCg0KDQoNCg0KZGlzdGFuY2lhczE8LWRpc3Qod2luZSxtZXRob2Q9Im1hbmhhdHRhbiIpDQpjbHVzdGVyMTwtaGNsdXN0KGRpc3RhbmNpYXMxKQ0KcGxvdChjbHVzdGVyMSkNCg0KZGlzdGFuY2lhczI8LWRpc3Qod2luZSxtZXRob2Q9ImV1Y2xpZGVhbiIpDQpjbHVzdGVyMjwtaGNsdXN0KGRpc3RhbmNpYXMyKQ0KDQpkaXN0YW5jaWFzMzwtZGlzdCh3aW5lLG1ldGhvZD0ibWF4aW11bSIpDQpjbHVzdGVyMzwtaGNsdXN0KGRpc3RhbmNpYXMzKQ0Kd2luZS5zdGFuZCA8LSBzY2FsZSh3aW5lWy0xXSkgICMgVG8gc3RhbmRhcml6ZSB0aGUgdmFyaWFibGVzDQoNCiMyIEVqZXJjaWNpbyBjb24gbGFzIGZydXRhcw0KIyBsb3MgbGVlbW9zIHNpbiBjYWJlY2VyYQ0KI2Rlc2NhcmdhciBodHRwOi8vYW5hbGlzaXN5ZGVjaXNpb24uZXMvd3AtY29udGVudC91cGxvYWRzLzIwMDkvMDYvYWxpbWVudG9zMi50eHQNCiBmcnV0YXM8LXJlYWQudGFibGUoIkM6L1VzZXJzL2xlbm92by9Eb2N1bWVudHMvYWxpbWVudG9zMi50eHQiLGhlYWRlcj1GQUxTRSxzZXA9Ilx0IikNCmZydXRhcw0KDQoNCnVybD0gICAgImh0dHA6Ly9hbmFsaXNpc3lkZWNpc2lvbi5lcy93cC1jb250ZW50L3VwbG9hZHMvMjAwOS8wNi9hbGltZW50b3MyLnR4dCINCmZydXRhczE8LXJlYWQudGFibGUodXJsLGhlYWRlcj1GQUxTRSxzZXA9Ilx0IikNCmhlYWQoZnJ1dGFzMSwxMCkNCg0Kbm9tYnJlczwtYygibm9tYnJlIiwiaW50ZXJfaGlkcmF0b3MiLCJrY2FsIiwicHJvdGVpbmFzIiwiZ3Jhc2FzIikNCm5hbWVzKGZydXRhczEpPC0gbm9tYnJlcw0KbmFtZXMoZnJ1dGFzMSkNCmZydXRhczEuc3RhbmQgPC0gc2NhbGUoZnJ1dGFzMVstMV0pIA0KZnJ1dGFzMS5zdGFuZA0Kay5tZWFucy5maXQgPC0ga21lYW5zKGZydXRhczEuc3RhbmQsIDMpIA0Kay5tZWFucy5maXQNCmsubWVhbnMuZml0MSA8LSBrbWVhbnMoZnJ1dGFzMS5zdGFuZCwgNCkgDQphdHRyaWJ1dGVzKGsubWVhbnMuZml0MSkNCmF0dHJpYnV0ZXMoay5tZWFucy5maXQpDQprLm1lYW5zLmZpdCRjZW50ZXJzDQprLm1lYW5zLmZpdCRzaXplDQprLm1lYW5zLmZpdCRjbHVzdGVyDQprLm1lYW5zLmZpdCR3aXRoaW5zcw0Kay5tZWFucy5maXQkYmV0d2VlbnNzDQoNCndzc3Bsb3QgPC0gZnVuY3Rpb24oZGF0YSwgbmM9MTUsIHNlZWQ9MTIzNCl7DQogIHdzcyA8LSAobnJvdyhkYXRhKS0xKSpzdW0oYXBwbHkoZGF0YSwyLHZhcikpDQogIGZvciAoaSBpbiAyOm5jKXsNCiAgICBzZXQuc2VlZChzZWVkKQ0KICAgIHdzc1tpXSA8LSBzdW0oa21lYW5zKGRhdGEsIGNlbnRlcnM9aSkkd2l0aGluc3MpfQ0KICBwbG90KDE6bmMsIHdzcywgdHlwZT0iYiIsIHhsYWI9Ik51bWJlciBvZiBDbHVzdGVycyIsDQogICAgICAgeWxhYj0iV2l0aGluIGdyb3VwcyBzdW0gb2Ygc3F1YXJlcyIpfQ0KDQp3c3NwbG90KGZydXRhczEuc3RhbmQsIG5jPTYpIA0KDQpjbHVzcGxvdChmcnV0YXMxLnN0YW5kLCBrLm1lYW5zLmZpdCRjbHVzdGVyLCBtYWluPScyRCByZXByZXNlbnRhdGlvbiBvZiB0aGUgQ2x1c3RlciBzb2x1dGlvbicsDQogICAgICAgICBjb2xvcj1UUlVFLCBzaGFkZT1UUlVFLA0KICAgICAgICAgbGFiZWxzPTIsIGxpbmVzPTApDQpjbHVzcGxvdChmcnV0YXMxLnN0YW5kLCBrLm1lYW5zLmZpdDEkY2x1c3RlciwgbWFpbj0nMkQgcmVwcmVzZW50YXRpb24gb2YgdGhlIENsdXN0ZXIgc29sdXRpb24nLA0KICAgICAgICAgY29sb3I9VFJVRSwgc2hhZGU9VFJVRSwNCiAgICAgICAgIGxhYmVscz0yLCBsaW5lcz0wKQ0KDQoNCnRhYmxlKGZydXRhczFbLDFdLGsubWVhbnMuZml0JGNsdXN0ZXIpDQoNCmRpc3RhbmNpYXMyPC1kaXN0KGZydXRhczEuc3RhbmQsbWV0aG9kPSJldWNsaWRlYW4iKQ0KY2x1c3RlcjI8LWhjbHVzdChkaXN0YW5jaWFzMiwgbWV0aG9kPSJldWNsaWRlYW4iKQ0KY2x1c3RlcjINCg0KcGxvdChjbHVzdGVyMikgIyBkaXNwbGF5IGRlbmRvZ3JhbQ0KZ3JvdXBzIDwtIGN1dHJlZShjbHVzdGVyMiwgaz00KSAjIGN1dCB0cmVlIGludG8gNSBjbHVzdGVycw0KcGxvdChncm91cHMpDQojIGRyYXcgZGVuZG9ncmFtIHdpdGggcmVkIGJvcmRlcnMgYXJvdW5kIHRoZSA1IGNsdXN0ZXJzDQpncm91cHMgPC0gY3V0cmVlKGNsdXN0ZXIyLCBrPTQpDQoNCnBhcihtZnJvdz1jKDIsMikpDQpwaWUoY29sU3VtcyhmcnV0YXMxW2subWVhbnMuZml0MSRjbHVzdGVyPT0xLF0pLGNleD0wLjUpDQoNCnBpZShjb2xTdW1zKGludGVyZXN0c1t0ZWVuX2NsdXN0ZXJzJGNsdXN0ZXI9PTIsXSksY2V4PTAuNSkNCg0KcGllKGNvbFN1bXMoaW50ZXJlc3RzW3RlZW5fY2x1c3RlcnMkY2x1c3Rlcj09MyxdKSxjZXg9MC41KQ0KDQpwaWUoY29sU3VtcyhpbnRlcmVzdHNbdGVlbl9jbHVzdGVycyRjbHVzdGVyPT00LF0pLGNleD0wLjUpDQoNCg0KDQoNCg0KDQpkaXN0YW5jaWFzMTwtZGlzdChmcnV0YXMsbWV0aG9kPSJtYW5oYXR0YW4iKQ0KZGlzdGFuY2lhczENCmNsdXN0ZXIxPC1oY2x1c3QoZGlzdGFuY2lhczEpDQpjbHVzdGVyMQ0KZGlzdGFuY2lhczI8LWRpc3QoZnJ1dGFzMS5zdGFuZCxtZXRob2Q9ImV1Y2xpZGVhbiIpDQpjbHVzdGVyMjwtaGNsdXN0KGRpc3RhbmNpYXMyKQ0KY2x1c3RlcjINCmRpc3RhbmNpYXMzPC1kaXN0KGZydXRhcyxtZXRob2Q9Im1heGltdW0iKQ0KY2x1c3RlcjM8LWhjbHVzdChkaXN0YW5jaWFzMykNCmRpc3RhbmNpYXM0PC1kaXN0KGZydXRhcyxtZXRob2Q9ImNhbmJlcnJhIikNCmNsdXN0ZXI0PC1oY2x1c3QoZGlzdGFuY2lhczQpDQoNCm9wIDwtIHBhcihtZmNvbCA9IGMoMiwgMikpICNOb3MgcGVybWl0ZSBwcmVzZW50YXINCnBhcihsYXMgPTEpICNlbCBncuFmaWNvIGVuIDQgcGFydGVzDQpwbG90KGNsdXN0ZXIxLG1haW49Ik3pdG9kbyBNYW5oYXRhbiIpDQpwbG90KGNsdXN0ZXIyLG1haW49IkRpc3RhbmNpYSBldWNs7WRlYSIpDQpwbG90KGNsdXN0ZXIzLG1haW49IkRpc3RhbmNpYSBwb3IgbeF4aW1vcyIpDQpwbG90KGNsdXN0ZXI0LG1haW49Ik3pdG9kbyBDYW1iZXJyYSIpDQpwYXNvMTwtcGFtKGRpc3RhbmNpYXMyLDIpDQpwYXNvMjwtcGFtKGRpc3RhbmNpYXMyLDMpDQpwYXNvMzwtcGFtKGRpc3RhbmNpYXMyLDQpDQpwYXNvNDwtcGFtKGRpc3RhbmNpYXMyLDUpDQpwYXIobWZyb3c9YygyLDIpKQ0KcGxvdChwYXNvMSkNCnBsb3QocGFzbzIpDQpwbG90KHBhc28zKQ0KcGxvdChwYXNvNCkNCmNsdXN0ZXIuZmluYWw8LSBrbWVhbnMoZGlzdGFuY2lhczIsMykNCmNsdXN0ZXIuZmluYWwkc2l6ZSAjT2J0ZW5lbW9zIGVsIHRhbWHxbyBkZSBsb3MgY2x1c3Rlcg0KY2x1c3Rlci5maW5hbDE8LSBrbWVhbnMoZGlzdGFuY2lhczIsNCkNCmNsdXN0ZXIuZmluYWwxJHNpemUgI09idGVuZW1vcyBlbCB0YW1h8W8gZGUgbG9zIGNsdXN0ZXINCmNsdXN0ZXIuZmluYWwyPC0ga21lYW5zKGRpc3RhbmNpYXMyLDUpDQpjbHVzdGVyLmZpbmFsMiRzaXplICNPYnRlbmVtb3MgZWwgdGFtYfFvIGRlIGxvcyBjbHVzdGVyDQpjbHVzdGVyLmZpbmFsPC0ga21lYW5zKGRpc3RhbmNpYXMyLDQpDQpncnVwb3M8LWRhdGEuZnJhbWUoZnJ1dGFzKQ0KY2x1czwtYXMuZmFjdG9yKGNsdXN0ZXIuZmluYWwkY2x1c3RlcikNCmdydXBvczwtY2JpbmQoZGF0YS5mcmFtZShmcnV0YXMpLGNsdXMpDQpncnVwb3M8LXNvcnRfZGYoZ3J1cG9zLHZhcnM9J2NsdXMnKQ0KZ3J1cG9zDQpub21icmVzPC1jKCJub21icmUiLCJpbnRlcl9oaWRyYXRvcyIsImtjYWwiLCJwcm90ZWluYXMiLCJncmFzYXMiLCJjbHVzIikNCm5hbWVzKGdydXBvcyk8LW5vbWJyZXMNCmFnZ3JlZ2F0ZShncnVwb3MkaW50ZXJfaGlkcmF0b3MsbGlzdChncnVwb3MkY2x1cyksbWVhbikNCmFnZ3JlZ2F0ZShncnVwb3Mka2NhbCxsaXN0KGdydXBvcyRjbHVzKSxtZWFuKQ0KYWdncmVnYXRlKGdydXBvcyRwcm90ZWluYXMsbGlzdChncnVwb3MkY2x1cyksbWVhbikNCmFnZ3JlZ2F0ZShncnVwb3MkZ3Jhc2FzLGxpc3QoZ3J1cG9zJGNsdXMpLG1lYW4p