TITULO: CLASIFICACION KMEANS
# recortando a sibate
extent(landsat8)
class : Extent
xmin : 446085
xmax : 673515
ymin : 362985
ymax : 595215
landsat8crop2015 = crop(ndviLandSat8, ext)
landsat8crop2015
class : RasterLayer
dimensions : 617, 351, 216567 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 576795, 587325, 484005, 502515 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : memory
names : layer
values : -0.1625031, 0.6681765 (min, max)
plot(landsat8crop2015)

# convertir el raster a vector / matriz
nr=getValues(landsat8crop2015)
str(nr)
num [1:216567] 0.471 0.441 0.435 0.396 0.378 ...
Tenga en cuenta que -getValues- convirtio el -ndvi- RasterLayer en una matriz (matriz). Ahora realizaremos el -kmeans- agrupamiento en la matriz e inspeccionaremos la salida.
# Es importante configurar el generador de semillas porque `kmeans` inicia los centros en ubicaciones aleatorias, para eso utilizaremos set.seed
set.seed (99)
# Queremos crear 10 grupos, permitir 500 iteraciones, comenzar con 5 conjuntos aleatorios utilizando el método "Lloyd"
kmncluster = kmeans(na.omit(nr), centers = 10, iter.max = 500, nstart = 5, algorithm = "Lloyd")
# kmeans devuelve un objeto de la clase "kmeans"
str(kmncluster)
List of 9
$ cluster : int [1:216567] 10 4 4 8 8 8 8 4 10 8 ...
$ centers : num [1:10, 1] 0.181 0.285 0.548 0.425 0.236 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:10] "1" "2" "3" "4" ...
.. ..$ : NULL
$ totss : num 3096
$ withinss : num [1:10] 6.4 6 7.92 6.11 5.84 ...
$ tot.withinss: num 57.6
$ betweenss : num 3039
$ size : int [1:10] 19149 32049 9132 28567 25928 34882 5743 33820 6570 20727
$ iter : int 103
$ ifault : NULL
- attr(*, "class")= chr "kmeans"
-kmeans-devuelve un objeto con 9 elementos. La longitud del -cluster- elemento dentro -kmncluster- es 216567 que es igual a la longitud de -nr- creado desde -ndvi-. Los valores de celda de -kmncluster\(cluster- rango entre 1 a 10 correspondientes al numero de entrada del cluster que proporcionamos en la -kmeans- funcion. -kmncluster\)cluster- indica la etiqueta del cluster para el pixel correspondiente. Necesitamos convertir los -kmncluster$cluster- valores nuevamente a RasterLayer de la misma dimension que -ndvi-.
# Use el objeto ndvi (en este caso se llama "landsat8crop2015") para establecer los valores del cluster en un nuevo raster
knr = setValues(landsat8crop2015, kmncluster$cluster)
# Tambien puedes hacerlo asi
knr= raster(landsat8crop2015)
values(knr) = kmncluster$cluster
knr
class : RasterLayer
dimensions : 617, 351, 216567 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 576795, 587325, 484005, 502515 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : memory
names : layer
values : 1, 10 (min, max)
Podemos ver que -knr- es un RasterLayer, pero no sabemos que grupo (1-10) pertenece a que clase de cobertura terrestre (y si pertenece a una clase que reconoceriamos). Puede averiguarlo trazandolos lado a lado con capas de referencia y usando un color unico para cada grupo.
#Defina un vector de color para 10 grupos (mas informacion sobre como configurar el color mas adelante)
mycolor = c ("#fef65b","#ff0000", "#daa520","#0000ff","#0000ff","#00ff00","#cbbeb5",
"#c3ff5b", "#ff7373", "#00ff00", "#808080")
par(mfrow = c(1,2))
plot(landsat8crop2015, col = rev(terrain.colors(10)), main = 'Landsat-NDVI')
plot(knr, main = 'Unsupervised classification', col = mycolor )

Si bien para otros fines suele ser mejor definir mas clases (y posiblemente fusionar clases mas adelante), una clasificacion simple como esta podria ser util, por ejemplo, fusionar los grupos 4 y 5 para construir una mascara de agua para el año 2015.
Puedes cambiar los colores en mi -mycolor-. Obtenga mas informacion sobre la seleccion de colores en R -aqui- y -aqui- .
Pregunta 2 : Grafique el RGB de 3 bandas de “landsat8” para el subconjunto (extensión “ext”) y el resultado de la agrupacion “kmeans” lado a lado y haga una tabla de cobertura del suelo para el uso del suelo Etiquetas para los grupos. Por ejemplo, los grupos 4 y 5 son agua.
landsat8p2 = stack(b6, b3, b2)
#plotRGB(landsat8p2, axes=TRUE, stretch="lin", main="Landsat composicion de color falsa ")
#crop landsat by the extent
landsatsibatep2 = crop(landsat8p2, ext)
plotRGB(landsatsibatep2, axes = TRUE, stretch = "lin", main = "Landsat FCC - SIBATE")

# convertir el raster a vector / matriz
nr_p2=getValues(landsatsibatep2)
str(nr_p2)
int [1:216567, 1:3] 13348 12473 12269 13387 14576 14992 14842 12425 11290 9894 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:3] "LC08_L1TP_008057_20150104_20170415_01_T1_B6" "LC08_L1TP_008057_20150104_20170415_01_T1_B3" "LC08_L1TP_008057_20150104_20170415_01_T1_B2"
# Es importante configurar el generador de semillas porque `kmeans` inicia los centros en ubicaciones aleatorias, para eso utilizaremos set.seed
set.seed (99)
# Queremos crear 10 grupos, permitir 500 iteraciones, comenzar con 5 conjuntos aleatorios utilizando el método "Lloyd"
kmncluster_p2 = kmeans(na.omit(nr), centers = 10, iter.max = 500, nstart = 5, algorithm = "Lloyd")
# kmeans devuelve un objeto de la clase "kmeans"
str(kmncluster_p2)
List of 9
$ cluster : int [1:216567] 10 4 4 8 8 8 8 4 10 8 ...
$ centers : num [1:10, 1] 0.181 0.285 0.548 0.425 0.236 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:10] "1" "2" "3" "4" ...
.. ..$ : NULL
$ totss : num 3096
$ withinss : num [1:10] 6.4 6 7.92 6.11 5.84 ...
$ tot.withinss: num 57.6
$ betweenss : num 3039
$ size : int [1:10] 19149 32049 9132 28567 25928 34882 5743 33820 6570 20727
$ iter : int 103
$ ifault : NULL
- attr(*, "class")= chr "kmeans"
# Use el objeto ndvi (en este caso se llama "landsatsibatep2") para establecer los valores del cluster en un nuevo raster
knr_p2 = setValues(landsatsibatep2, kmncluster_p2$cluster)
# Tambien puedes hacerlo asi
knr_p2= raster(landsatsibatep2)
values(knr_p2) = kmncluster_p2$cluster
knr_p2
class : RasterLayer
dimensions : 617, 351, 216567 (nrow, ncol, ncell)
resolution : 30, 30 (x, y)
extent : 576795, 587325, 484005, 502515 (xmin, xmax, ymin, ymax)
crs : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
source : memory
names : layer
values : 1, 10 (min, max)
#Defina un vector de color para 10 grupos (mas informacion sobre como configurar el color mas adelante)
#mycolor_p2 = c (topo.colors(10))
plot(knr_p2, main = 'Unsupervised classification', col = rev(topo.colors(10)))

NA
NA
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).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.
LS0tDQp0aXRsZTogIioqSW1hZ2VuIExhbmRTYXQgOCwgU2liYXRlIDIwMTUgLSBDbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhKioiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KDQoNCiMjIyMjIEVuIGVzdGUgY2FwaXR1bG8gZXhwbG9yYW1vcyBsYSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhLiBFeGlzdGVuIHZhcmlvcyBhbGdvcml0bW9zIGRlIGNsYXNpZmljYWNpw7NuIG5vIHN1cGVydmlzYWRvcywgeSBsYSBlbGVjY2lvbiBkZWwgYWxnb3JpdG1vIHB1ZWRlIGFmZWN0YXIgbG9zIHJlc3VsdGFkb3MuIEV4cGxvcmFyZW1vcyB1biBzb2xvIGFsZ29yaXRtbyAoay1tZWFucykgcGFyYSBpbHVzdHJhciBlbCBwcmluY2lwaW8gZ2VuZXJhbA0KDQoNCiMjIyMjIFBhcmEgZXN0ZSBlamVtcGxvLCBzZWd1aXJlbW9zIGVsIGVzcXVlbWEgZGUgY2xhc2lmaWNhY2lvbiBkZSBsYSAtQmFzZSBkZSBkYXRvcyBuYWNpb25hbCBkZSBjb2JlcnR1cmEgZGUgbGEgdGllcnJhIDIwMTEgKE5MQ0QgMjAxMSktIHBhcmEgdW4gc3ViY29uanVudG8gZGUgbGFzIHJlZ2lvbmVzIGRlbCBWYWxsZSBDZW50cmFsLiBVdGlsaXphbW9zIGltYWdlbmVzIGNvbXB1ZXN0YXMgc2luIG51YmVzIGRlIExhbmRzYXQgNSBjb24gNiBiYW5kYXMuDQoNCg0KIyMjIyMgU2liYXRlLCBJbWFnZW4gTGFuZFNhdCA4IDIwMTUsIHV0aWxpemFuZG8gNyBiYW5kYXMNCg0KYGBge3J9DQpsaWJyYXJ5KHJhc3RlcikNCmxhbmRzYXQ4ID0gc3RhY2soYjIsYjMsYjQsYjUsYjYsYjcpDQpuYW1lcyhsYW5kc2F0OCkgPSBjICgnYmx1ZScsICdncmVlbicsICdyZWQnLCAnTklSJywgJ1NXSVIxJywnU1dJUjInKQ0KcGxvdChsYW5kc2F0OCkNCmBgYA0KDQoNCiMjIyMjIFByZWd1bnRhIDEgOiBIYWdhIHVuYSB0cmFtYSBjb21wdWVzdGEgZGUgMyBiYW5kYXMgZGUgZmFsc28gY29sb3IgZGUgYGAgbGFuZHNhdDggJycuDQoNCg0KYGBge3J9DQoNCmxhbmRzYXQ4RkNDX2ltYWdlbiA9IHN0YWNrKGI1LCBiNiwgYjQpDQpwbG90UkdCKGxhbmRzYXQ4RkNDX2ltYWdlbiwgYXhlcz1UUlVFLCBzdHJldGNoPSJsaW4iLCBtYWluPSJMYW5kc2F0IGNvbXBvc2ljaW9uIGRlIGNvbG9yIGZhbHNhIC0gQWd1YSAvIFRpZXJyYSIpDQoNCiMgcmVjb3J0YW5kbyBhIHNpYmF0ZQ0KDQpzaWJhdGV4dGVuZCA9IHNoYXBlZmlsZSgnQzovVXNlcnMvRGF2aWQtUEMvRGVza3RvcC9FU0NSSVRPUklPL1NJQkFURV9SVVJBTC9ydXJhbC5zaHAnKQ0KDQpleHQgPSBleHRlbnQoc2liYXRleHRlbmQpDQoNCiMgY3JvcCBsYW5kc2F0IGJ5IHRoZSBleHRlbnQNCg0KbGFuZHNhdGZjYyA9IGNyb3AobGFuZHNhdDhGQ0NfaW1hZ2VuLCBleHQpDQoNCnBsb3RSR0IobGFuZHNhdGZjYywgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJMYW5kc2F0IFRydWUgQ29sb3IgQ29tcG9zaXRlIikNCg0KDQpgYGANCg0KDQojIyMjIyBFbiBsYSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhLCB1dGlsaXphbW9zIGxvcyBkYXRvcyBkZSByZWZsZWN0YW5jaWEsIHBlcm8gbm8gcHJvcG9yY2lvbmFtb3MgbmluZ3VuIGRhdG8gZGUgcmVzcHVlc3RhIChlcyBkZWNpciwgbm8gaWRlbnRpZmljYW1vcyBuaW5ndW4gcGl4ZWwgY29tbyBwZXJ0ZW5lY2llbnRlIGEgdW5hIGNsYXNlIGVuIHBhcnRpY3VsYXIpLiBFc3RvIHB1ZWRlIHBhcmVjZXIgZXh0cmHDsW8sIHBlcm8gcHVlZGUgc2VyIHV0aWwgY3VhbmRvIG5vIHRlbmVtb3MgbXVjaG8gY29ub2NpbWllbnRvIHByZXZpbyBkZSB1biBhcmVhIGRlIGVzdHVkaW8uIE8gc2kgdGllbmUgdW4gYW1wbGlvIGNvbm9jaW1pZW50byBkZSBsYSBkaXN0cmlidWNpb24gZGUgbGFzIGNsYXNlcyBkZSBpbnRlcmVzIGRlIGxhIGNvYmVydHVyYSBkZWwgc3VlbG8sIHBlcm8gbm8gdGllbmUgZGF0b3MgZXNwZWNpZmljb3MgDQoNCg0KIyMjIyMgRWwgYWxnb3JpdG1vIGFncnVwYSBwaXhlbGVzIGNvbiBjYXJhY3RlcmlzdGljYXMgZXNwZWN0cmFsZXMgc2ltaWxhcmVzIGVuIGdydXBvcy4NCg0KDQojIyMjIyBPYnRlbmdhIG1hcyBpbmZvcm1hY2lvbiBzb2JyZSBLLW1lYW5zIHkgb3Ryb3MgYWxnb3JpdG1vcyBzdXBlcnZpc2Fkb3Mgc2luIHN1cGVydmlzaW9uIC1hcXVpLSAuDQoNCg0KIyMjIyMgUmVhbGl6YXJlbW9zIHVuYSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhIGVuIHVuIHN1YmNvbmp1bnRvIGVzcGFjaWFsIGRlIGxhIC1uZHZpLSBjYXBhLiBBcXVpIGhheSBvdHJhIGZvcm1hIGRlIGNhbGN1bGFyIC1uZHZpLS4gRW4gZXN0ZSBjYXNvLCBubyB1c2Ftb3MgdW5hIGZ1bmNpb24gc2VwYXJhZGEsIHNpbm8gdW5hIG5vdGFjaW9uIGFsZ2VicmFpY2EgZGlyZWN0YS4NCg0KDQpgYGB7cn0NCm5kdmlMYW5kU2F0OD0obGFuZHNhdDhbWydOSVInXV0tbGFuZHNhdDhbWydyZWQnXV0pLyhsYW5kc2F0OFtbJ05JUiddXStsYW5kc2F0OFtbJ3JlZCddXSkNCnBsb3QobmR2aUxhbmRTYXQ4KQ0KDQoNCmBgYA0KDQoNCiMjIyMjIEhhcmVtb3MgdW4gLWttZWFucy0gYWdydXBhbWllbnRvIGRlIGxvcyAtbmR2aS0gZGF0b3MuIFByaW1lcm8gdXNhbW9zIC1jcm9wLSBwYXJhIGhhY2VyIHVuIHN1YmNvbmp1bnRvIGVzcGFjaWFsIGRlIC1uZHZpLSwgcGFyYSBwZXJtaXRpciB1biBwcm9jZXNhbWllbnRvIG1hcyByYXBpZG8gKHB1ZWRlIHNlbGVjY2lvbmFyIGN1YWxxdWllcmEgLWV4dGVudC0gdXNhbmRvIGxhIC1kcmF3RXh0ZW50KCktIGZ1bmNpw7NuKS4NCg0KDQojIyMgKipUSVRVTE86IENMQVNJRklDQUNJT04gS01FQU5TKioNCg0KDQpgYGB7cn0NCiMgcmVjb3J0YW5kbyBhIHNpYmF0ZQ0KDQpleHRlbnQobGFuZHNhdDgpDQpsYW5kc2F0OGNyb3AyMDE1ID0gY3JvcChuZHZpTGFuZFNhdDgsIGV4dCkNCmxhbmRzYXQ4Y3JvcDIwMTUNCnBsb3QobGFuZHNhdDhjcm9wMjAxNSkNCg0KIyBjb252ZXJ0aXIgZWwgcmFzdGVyIGEgdmVjdG9yIC8gbWF0cml6DQpucj1nZXRWYWx1ZXMobGFuZHNhdDhjcm9wMjAxNSkNCnN0cihucikNCg0KDQoNCmBgYA0KDQoNCiMjIyMjIFRlbmdhIGVuIGN1ZW50YSBxdWUgLWdldFZhbHVlcy0gY29udmlydGlvIGVsIC1uZHZpLSBSYXN0ZXJMYXllciBlbiB1bmEgbWF0cml6IChtYXRyaXopLiBBaG9yYSByZWFsaXphcmVtb3MgZWwgLWttZWFucy0gYWdydXBhbWllbnRvIGVuIGxhIG1hdHJpeiBlIGluc3BlY2Npb25hcmVtb3MgbGEgc2FsaWRhLg0KDQoNCmBgYHtyfQ0KDQojIEVzIGltcG9ydGFudGUgY29uZmlndXJhciBlbCBnZW5lcmFkb3IgZGUgc2VtaWxsYXMgcG9ycXVlIGBrbWVhbnNgIGluaWNpYSBsb3MgY2VudHJvcyBlbiB1YmljYWNpb25lcyBhbGVhdG9yaWFzLCBwYXJhIGVzbyB1dGlsaXphcmVtb3Mgc2V0LnNlZWQNCg0Kc2V0LnNlZWQgKDk5KQ0KDQojIFF1ZXJlbW9zIGNyZWFyIDEwIGdydXBvcywgcGVybWl0aXIgNTAwIGl0ZXJhY2lvbmVzLCBjb21lbnphciBjb24gNSBjb25qdW50b3MgYWxlYXRvcmlvcyB1dGlsaXphbmRvIGVsIG3DqXRvZG8gIkxsb3lkIg0KDQprbW5jbHVzdGVyID0ga21lYW5zKG5hLm9taXQobnIpLCBjZW50ZXJzID0gMTAsIGl0ZXIubWF4ID0gNTAwLCBuc3RhcnQgPSA1LCBhbGdvcml0aG0gPSAiTGxveWQiKQ0KDQojIGttZWFucyBkZXZ1ZWx2ZSB1biBvYmpldG8gZGUgbGEgY2xhc2UgImttZWFucyINCg0Kc3RyKGttbmNsdXN0ZXIpDQoNCg0KYGBgDQoNCg0KIyMjIyMgLWttZWFucy1kZXZ1ZWx2ZSB1biBvYmpldG8gY29uIDkgZWxlbWVudG9zLiBMYSBsb25naXR1ZCBkZWwgLWNsdXN0ZXItIGVsZW1lbnRvIGRlbnRybyAta21uY2x1c3Rlci0gZXMgMjE2NTY3IHF1ZSBlcyBpZ3VhbCBhIGxhIGxvbmdpdHVkIGRlIC1uci0gY3JlYWRvIGRlc2RlIC1uZHZpLS4gTG9zIHZhbG9yZXMgZGUgY2VsZGEgZGUgLWttbmNsdXN0ZXIkY2x1c3Rlci0gcmFuZ28gZW50cmUgMSBhIDEwIGNvcnJlc3BvbmRpZW50ZXMgYWwgbnVtZXJvIGRlIGVudHJhZGEgZGVsIGNsdXN0ZXIgcXVlIHByb3BvcmNpb25hbW9zIGVuIGxhIC1rbWVhbnMtIGZ1bmNpb24uIC1rbW5jbHVzdGVyJGNsdXN0ZXItIGluZGljYSBsYSBldGlxdWV0YSBkZWwgY2x1c3RlciBwYXJhIGVsIHBpeGVsIGNvcnJlc3BvbmRpZW50ZS4gTmVjZXNpdGFtb3MgY29udmVydGlyIGxvcyAta21uY2x1c3RlciRjbHVzdGVyLSB2YWxvcmVzIG51ZXZhbWVudGUgYSBSYXN0ZXJMYXllciBkZSBsYSBtaXNtYSBkaW1lbnNpb24gcXVlIC1uZHZpLS4NCg0KDQpgYGB7cn0NCiMgVXNlIGVsIG9iamV0byBuZHZpIChlbiBlc3RlIGNhc28gc2UgbGxhbWEgImxhbmRzYXQ4Y3JvcDIwMTUiKSBwYXJhIGVzdGFibGVjZXIgbG9zIHZhbG9yZXMgZGVsIGNsdXN0ZXIgZW4gdW4gbnVldm8gcmFzdGVyDQoNCmtuciA9IHNldFZhbHVlcyhsYW5kc2F0OGNyb3AyMDE1LCBrbW5jbHVzdGVyJGNsdXN0ZXIpDQoNCiMgVGFtYmllbiBwdWVkZXMgaGFjZXJsbyBhc2kNCg0Ka25yPSByYXN0ZXIobGFuZHNhdDhjcm9wMjAxNSkNCnZhbHVlcyhrbnIpID0ga21uY2x1c3RlciRjbHVzdGVyDQprbnINCg0KYGBgDQoNCg0KIyMjIyMgUG9kZW1vcyB2ZXIgcXVlIC1rbnItIGVzIHVuIFJhc3RlckxheWVyLCBwZXJvIG5vIHNhYmVtb3MgcXVlIGdydXBvICgxLTEwKSBwZXJ0ZW5lY2UgYSBxdWUgY2xhc2UgZGUgY29iZXJ0dXJhIHRlcnJlc3RyZSAoeSBzaSBwZXJ0ZW5lY2UgYSB1bmEgY2xhc2UgcXVlIHJlY29ub2NlcmlhbW9zKS4gUHVlZGUgYXZlcmlndWFybG8gdHJhemFuZG9sb3MgbGFkbyBhIGxhZG8gY29uIGNhcGFzIGRlIHJlZmVyZW5jaWEgeSB1c2FuZG8gdW4gY29sb3IgdW5pY28gcGFyYSBjYWRhIGdydXBvLg0KDQoNCmBgYHtyfQ0KI0RlZmluYSB1biB2ZWN0b3IgZGUgY29sb3IgcGFyYSAxMCBncnVwb3MgKG1hcyBpbmZvcm1hY2lvbiBzb2JyZSBjb21vIGNvbmZpZ3VyYXIgZWwgY29sb3IgbWFzIGFkZWxhbnRlKQ0KDQpteWNvbG9yID0gYyAoIiNmZWY2NWIiLCIjZmYwMDAwIiwgIiNkYWE1MjAiLCIjMDAwMGZmIiwiIzAwMDBmZiIsIiMwMGZmMDAiLCIjY2JiZWI1IiwNCiAgICAgICAgICAgICAiI2MzZmY1YiIsICIjZmY3MzczIiwgIiMwMGZmMDAiLCAiIzgwODA4MCIpDQpwYXIobWZyb3cgPSBjKDEsMikpDQpwbG90KGxhbmRzYXQ4Y3JvcDIwMTUsIGNvbCA9IHJldih0ZXJyYWluLmNvbG9ycygxMCkpLCBtYWluID0gJ0xhbmRzYXQtTkRWSScpDQpwbG90KGtuciwgbWFpbiA9ICdVbnN1cGVydmlzZWQgY2xhc3NpZmljYXRpb24nLCBjb2wgPSBteWNvbG9yICkNCg0KYGBgDQoNCg0KIyMjIyMgU2kgYmllbiBwYXJhIG90cm9zIGZpbmVzIHN1ZWxlIHNlciBtZWpvciBkZWZpbmlyIG1hcyBjbGFzZXMgKHkgcG9zaWJsZW1lbnRlIGZ1c2lvbmFyIGNsYXNlcyBtYXMgYWRlbGFudGUpLCB1bmEgY2xhc2lmaWNhY2lvbiBzaW1wbGUgY29tbyBlc3RhIHBvZHJpYSBzZXIgdXRpbCwgcG9yIGVqZW1wbG8sIGZ1c2lvbmFyIGxvcyBncnVwb3MgNCB5IDUgcGFyYSBjb25zdHJ1aXIgdW5hIG1hc2NhcmEgZGUgYWd1YSBwYXJhIGVsIGHDsW8gMjAxNS4NCg0KDQojIyMjIyBQdWVkZXMgY2FtYmlhciBsb3MgY29sb3JlcyBlbiBtaSAtbXljb2xvci0uIE9idGVuZ2EgbWFzIGluZm9ybWFjaW9uIHNvYnJlIGxhIHNlbGVjY2lvbiBkZSBjb2xvcmVzIGVuIFIgLWFxdWktIHkgLWFxdWktIC4NCg0KDQojIyMjIyBQcmVndW50YSAyIDogR3JhZmlxdWUgZWwgUkdCIGRlIDMgYmFuZGFzIGRlICAibGFuZHNhdDgiIHBhcmEgZWwgc3ViY29uanVudG8gKGV4dGVuc2nDs24gImV4dCIpIHkgZWwgcmVzdWx0YWRvIGRlIGxhIGFncnVwYWNpb24gImttZWFucyIgbGFkbyBhIGxhZG8geSBoYWdhIHVuYSB0YWJsYSBkZSBjb2JlcnR1cmEgZGVsIHN1ZWxvIHBhcmEgZWwgdXNvIGRlbCBzdWVsbyBFdGlxdWV0YXMgcGFyYSBsb3MgZ3J1cG9zLiBQb3IgZWplbXBsbywgbG9zIGdydXBvcyA0IHkgNSBzb24gYWd1YS4NCg0KDQpgYGB7cn0NCg0KbGFuZHNhdDhwMiA9IHN0YWNrKGI2LCBiMywgYjIpDQojcGxvdFJHQihsYW5kc2F0OHAyLCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IkxhbmRzYXQgY29tcG9zaWNpb24gZGUgY29sb3IgZmFsc2EgIikNCg0KI2Nyb3AgbGFuZHNhdCBieSB0aGUgZXh0ZW50DQoNCmxhbmRzYXRzaWJhdGVwMiA9IGNyb3AobGFuZHNhdDhwMiwgZXh0KQ0KDQpwbG90UkdCKGxhbmRzYXRzaWJhdGVwMiwgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJMYW5kc2F0IEZDQyAtIFNJQkFURSIpDQoNCg0KDQoNCiMgY29udmVydGlyIGVsIHJhc3RlciBhIHZlY3RvciAvIG1hdHJpeg0KbnJfcDI9Z2V0VmFsdWVzKGxhbmRzYXRzaWJhdGVwMikNCnN0cihucl9wMikNCg0KDQoNCg0KIyBFcyBpbXBvcnRhbnRlIGNvbmZpZ3VyYXIgZWwgZ2VuZXJhZG9yIGRlIHNlbWlsbGFzIHBvcnF1ZSBga21lYW5zYCBpbmljaWEgbG9zIGNlbnRyb3MgZW4gdWJpY2FjaW9uZXMgYWxlYXRvcmlhcywgcGFyYSBlc28gdXRpbGl6YXJlbW9zIHNldC5zZWVkDQoNCnNldC5zZWVkICg5OSkNCg0KIyBRdWVyZW1vcyBjcmVhciAxMCBncnVwb3MsIHBlcm1pdGlyIDUwMCBpdGVyYWNpb25lcywgY29tZW56YXIgY29uIDUgY29uanVudG9zIGFsZWF0b3Jpb3MgdXRpbGl6YW5kbyBlbCBtw6l0b2RvICJMbG95ZCINCg0Ka21uY2x1c3Rlcl9wMiA9IGttZWFucyhuYS5vbWl0KG5yKSwgY2VudGVycyA9IDEwLCBpdGVyLm1heCA9IDUwMCwgbnN0YXJ0ID0gNSwgYWxnb3JpdGhtID0gIkxsb3lkIikNCg0KIyBrbWVhbnMgZGV2dWVsdmUgdW4gb2JqZXRvIGRlIGxhIGNsYXNlICJrbWVhbnMiDQoNCnN0cihrbW5jbHVzdGVyX3AyKQ0KDQoNCg0KDQojIFVzZSBlbCBvYmpldG8gbmR2aSAoZW4gZXN0ZSBjYXNvIHNlIGxsYW1hICJsYW5kc2F0c2liYXRlcDIiKSBwYXJhIGVzdGFibGVjZXIgbG9zIHZhbG9yZXMgZGVsIGNsdXN0ZXIgZW4gdW4gbnVldm8gcmFzdGVyDQoNCmtucl9wMiA9IHNldFZhbHVlcyhsYW5kc2F0c2liYXRlcDIsIGttbmNsdXN0ZXJfcDIkY2x1c3RlcikNCg0KIyBUYW1iaWVuIHB1ZWRlcyBoYWNlcmxvIGFzaQ0KDQprbnJfcDI9IHJhc3RlcihsYW5kc2F0c2liYXRlcDIpDQp2YWx1ZXMoa25yX3AyKSA9IGttbmNsdXN0ZXJfcDIkY2x1c3Rlcg0Ka25yX3AyDQoNCg0KDQojRGVmaW5hIHVuIHZlY3RvciBkZSBjb2xvciBwYXJhIDEwIGdydXBvcyAobWFzIGluZm9ybWFjaW9uIHNvYnJlIGNvbW8gY29uZmlndXJhciBlbCBjb2xvciBtYXMgYWRlbGFudGUpDQoNCiNteWNvbG9yX3AyID0gYyAodG9wby5jb2xvcnMoMTApKQ0KDQpwbG90KGtucl9wMiwgbWFpbiA9ICdVbnN1cGVydmlzZWQgY2xhc3NpZmljYXRpb24nLCBjb2wgPSByZXYodG9wby5jb2xvcnMoMTApKSkgDQoNCg0KYGBgDQoNCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0K