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

estandarizar la información por variable

wine.stand <- scale(wine[-1]) # el -1 es porque la columna 1 es tipo y esta no es variable wine.stand #ver los datos estandarizados

Porque se debe estandarizar?

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

descargar http://analisisydecision.es/wp-content/uploads/2009/06/alimentos2.txt

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