Landsat 8 recopilada el 04 de enero de 2015. El subconjunto cubre el area de Sibate, departamento de Cundinamarca, en Colombia # #
Seleccionar la carpeta de destino

# "C:/Users/David-PC/Desktop/ESCRITORIO/Landsat_procesamiento"
getwd()
[1] "C:/Users/David-PC/Desktop/ESCRITORIO/Landsat_procesamiento"

Crear objetos RasterLayer para capas individuales Landsat (bandas) y las llamamos enrutandolas como por ejemplo (‘./data/LC08_L1TP_008057_20180317_20180403_01_T1_B2.tif’)

En este capitulo se describe la forma de acceder y explorar, por satelite, datos de teledeteccion con R . Tambien mostramos como usarlos para hacer mapas.

Utilizaremos principalmente un subconjunto espacial de una escena Landsat 8 recopilada el 04 de enero de 2015. El subconjunto cubre el area de Sibaté, en Cundinamarca, Colombia.

Todas las escenas de imagenes de Landsat tienen una identificacion de producto y metadatos unicos. Puede encontrar la informacion sobre el sensor Landsat, el satelite, la ubicacion en la Tierra (ruta WRS, fila WRS) y la fecha de adquisicion a partir de la ID del producto. Por ejemplo, el identificador de producto de los datos que utilizaremos es ‘LC08_L1TP_008057_20150104’. Con base en esta guia , puede ver que el Sensor-Satelite es OLI / TIRS combinados Landsat 8, WRS Path 80, WRS Row 57 y recopilados el 04 de enero de 2015. Las escenas de Landsat se entregan mas comunmente como un archivo comprimido, que contiene archivos separados para cada banda

Comenzaremos explorando y visualizando los datos (consulte las instrucciones en el Capitulo 1 para obtener instrucciones de descarga de datos si aun no lo ha hecho).

CAPITULO 1

PROPIEDADES DE IMAGEN

Crear objetos RasterLayer para capas individuales Landsat (bandas)

library(raster)
# Costera
b1 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B1.tif')
# Azul
b2 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B2.tif')
# Verde
b3 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B3.tif')
# Rojo
b4 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B4.tif')
# Infrarojo cercano (NIR)
b5 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B5.tif')
# Infrarrojo de Onda Corta 1 (SWIR 1)
b6 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B6.tif')
# Infrarrojo de Onda Corta 2 (SWIR 2)
b7 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B7.tif')
# Pancromatica
b8 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B8.tif')
# Cirros (Cirrus)
b9 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B9.tif')
# Sensor Térmico Infrarrojo 1 (TIRS 1)
b10 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B10.tif')
# Sensor Térmico Infrarrojo 2 (TIRS 2)
b11 = raster('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B11.tif')

se inserta un nuevo bloque de codigo ctrl+alt+i para imprimir las variables a verificar, por ejemplo con la banda dos (b2):

b2
class      : RasterLayer 
dimensions : 7741, 7581, 58684521  (nrow, ncol, ncell)
resolution : 30, 30  (x, y)
extent     : 446085, 673515, 362985, 595215  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
source     : C:/Users/David-PC/Desktop/ESCRITORIO/Landsat_procesamiento/data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B2.tif 
names      : LC08_L1TP_008057_20150104_20170415_01_T1_B2 
values     : 0, 65535  (min, max)

Puede ver la resolucion espacial, la extension, el numero de capas, el sistema de referencia de coordenadas y mas.

INFORMACION DE IMAGEN Y ESTADISTICAS

A continuacion se muestra como puede acceder a varias propiedades desde un objeto Raster * (esto es lo mismo para cualquier conjunto de datos raster).

# Sistema de coordenadas de referencia (CRS)
crs(b2)
CRS arguments:
 +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
## CRS arguments:
## +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84
## +towgs84=0,0,0

# Numero de celdas, filas, columnas
ncell(b2)
[1] 58684521
## [1] 58684521

# Dimension
dim(b2)
[1] 7741 7581    1
## [1] 7741 7581    1

# Resolucion espacial
res(b2)
[1] 30 30
## [1] 30 30

# Numero de badas 
nlayers(b2)
[1] 1
## [1] 1

# ¿Las bandas tienen la misma extension, numero de filas y columnas, proyeccion, resolucion y origen?
compareRaster(b2,b3)
[1] TRUE
## [1] TRUE

Puede crear un RasterStack (un objeto con varias capas) a partir de los objetos RasterLayer (banda unica) existentes

Las bandas que llamos son las mismas que hemos llamadodo arriba como RasterLayer

# Creamos el RasterStack
s2015 = stack(b5, b4, b3)

# Revisamos las propiedades del RasterStack
s2015
class      : RasterStack 
dimensions : 7741, 7581, 58684521, 3  (nrow, ncol, ncell, nlayers)
resolution : 30, 30  (x, y)
extent     : 446085, 673515, 362985, 595215  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      : LC08_L1TP_008057_20150104_20170415_01_T1_B5, LC08_L1TP_008057_20150104_20170415_01_T1_B4, LC08_L1TP_008057_20150104_20170415_01_T1_B3 
min values :                                           0,                                           0,                                           0 
max values :                                       65535,                                       65535,                                       65535 
## class      : RasterStack
## dimensions : 7741, 7581, 58684521, 3  (nrow, ncol, ncell, nlayers)
## resolution : 30, 30  (x, y)
## extent     : 446085, 673515, 362985, 595215  (xmin, xmax, ymin, ymax)
## crs        : ++proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
## names      : LC08_L1TP_008057_20180317_20180403_01_T1_B5, LC08_L1TP_008057_20180317_20180403_01_T1_B4,     LC08_L1TP_008057_20180317_20180403_01_T1_B3
## min values :  0, 0, 0 
## max values :  65535, 65535, 65535

Tambien puede crear el RasterStack usando los nombres de archivo. Un RasterStack es una coleccion de objetos RasterLayer con la misma extension y resolucion espacial. Se puede crear un RasterStack a partir de objetos RasterLayer, o de archivos raster, o ambos. Tambien se puede crear desde un objeto SpatialPixelsDataFrame o un objeto SpatialGridDataFrame.

# Primero creamos una lista de los raster layers usando:

filenames = paste0('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B', 1:7, ".tif")
filenames
[1] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B1.tif"
[2] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B2.tif"
[3] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B3.tif"
[4] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B4.tif"
[5] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B5.tif"
[6] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B6.tif"
[7] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B7.tif"
## [1] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B1.tif" 
## [2] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B2.tif" 
## [3] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B3.tif" 
## [4] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B4.tif" 
## [5] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B5.tif" 
## [6] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B6.tif" 
## [7] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B7.tif" 

###### no lee la banda 8 porque tiene diferente extension, la banda 9 es cirro, y las bandas 10 y 11 son termales

## [8] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B8.tif" 
## [9] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B9.tif" 
## [10] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B10.tif"
## [11] "./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B11.tif"

# Creo el RasterStack de las bandas seleccionadas, es decir  de la 1 a la  7 (1:7)
landsat2015= stack(filenames)
landsat2015
class      : RasterStack 
dimensions : 7741, 7581, 58684521, 7  (nrow, ncol, ncell, nlayers)
resolution : 30, 30  (x, y)
extent     : 446085, 673515, 362985, 595215  (xmin, xmax, ymin, ymax)
crs        : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
names      : LC08_L1TP//5_01_T1_B1, LC08_L1TP//5_01_T1_B2, LC08_L1TP//5_01_T1_B3, LC08_L1TP//5_01_T1_B4, LC08_L1TP//5_01_T1_B5, LC08_L1TP//5_01_T1_B6, LC08_L1TP//5_01_T1_B7 
min values :                     0,                     0,                     0,                     0,                     0,                     0,                     0 
max values :                 65535,                 65535,                 65535,                 65535,                 65535,                 65535,                 65535 
## class      : RasterStack
## dimensions : 7741, 7581, 58684521, 7  (nrow, ncol, ncell, nlayers)
## resolution : 30, 30  (x, y)
## extent     : 446085, 673515, 362985, 595215  (xmin, xmax, ymin, ymax)
## crs        : +proj=utm +zone=10 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
## names      : LC08_L1TP//5_01_T1_B1, LC08_L1TP//5_01_T1_B2, LC08_L1TP//5_01_T1_B3, LC08_L1TP//5_01_T1_B4, LC08_L1TP//5_01_T1_B5, LC08_L1TP//5_01_T1_B6, LC08_L1TP//5_01_T1_B7
## min values :                     0,                     0,                     0,                     0,                     0,                     0,                     0 
## max values :                 65535,                 65535,                 65535,                 65535,                 65535,                 65535,                 65535 

Arriba creamos un RasterStack con 11 capas. Las capas representan la intensidad de la reflexion en las siguientes longitudes de onda: Ultra azul, azul, verde, rojo, infrarrojo cercano (NIR), infrarrojo de onda corta (SWIR) 1, infrarrojo de onda corta (SWIR) 2, pancromatico, cirro, infrarrojo termico (TIRS) 1, Infrarrojo termico (TIRS) 2. No utilizaremos las ultimas cuatro capas y vera como eliminarlas en las siguientes secciones.

BANDA UNICA Y MAPAS COMPUESTOS

Puede trazar capas individuales de un RasterStack de una imagen multiespectral.

# Trazando capas indivuduales (aZUL, VERDE, ROJO, INFRAROJO CERCANO) a partir del RasterStack
par(mfrow = c(2,2))
plot(b2, main = "Azul", col = gray(0:100 / 100), axes = FALSE)
plot(b3, main = "Verde", col = gray(0:100 / 100), axes = FALSE)
plot(b4, main = "Rojo", col = gray(0:100 / 100), axes = FALSE)
plot(b5, main = "NIR", col = gray(0:100 / 100), axes = FALSE)

Echa un vistazo a las leyendas de los mapas creados anteriormente. Pueden variar entre 0 y 1. Observe la diferencia en el sombreado y el rango de leyendas entre las diferentes bandas. Esto se debe a que las diferentes caracteristicas de la superficie reflejan la radiacion solar incidente de manera diferente. Cada capa representa la cantidad de radiacion solar incidente que se refleja para un rango de longitud de onda particular. Por ejemplo, la vegetacion refleja mas energia en NIR que otras longitudes de onda y, por lo tanto, parece mas brillante. Por el contrario, el agua absorbe la mayor parte de la energia en la longitud de onda NIR y parece oscura.

No obtenemos tanta informacion de estas parcelas en escala de grises; a menudo se combinan en un “compuesto” para crear tramas mas interesantes.

Para hacer una imagen de “color verdadero (o natural)”, es decir, algo que se parece a una fotografia normal (vegetacion en verde, azul agua, etc.), necesitamos bandas en las regiones roja, verde y azul. Para esta imagen Landsat, se pueden usar las bandas 4 (rojo), 3 (verde) y 2 (azul). El metodo - plotRGB - se puede utilizar para combinarlos en un solo compuesto. Tambien puede proporcionar argumentos adicionales - plotRGB - para mejorar la visualizacion (por ejemplo, un estiramiento lineal de los valores, utilizando ).- strecth = “lin” -.

# Ploteamos la combinacion de bandas 4, 3 y 2 que para L8 es color verdadero
landsatRGB2015 = stack(b4, b3, b2)
plotRGB(landsatRGB2015, axes = TRUE, stretch = "lin", main = "Composicion de color verdadero - Landsat 8")

El compuesto de color verdadero revela mucho mas sobre el paisaje que las imagenes grises anteriores. Otro metodo popular de visualizacion de imagenes en la teledeteccion es la imagen conocida como “color falso” en la que se combinan las bandas NIR, rojo y verde. Esta representacion es popular ya que hace que sea facil ver la vegetacion (en rojo).

El maximo de bandas que podemos emplear por composicion es de tres y la apariencia dependera de las bandas espectrales que asignemos a los canales rojo, verde y azul del monitor. El proceso permite visualizar, simultáneamente, informacion de distintas regiones del espectro, lo que facilita la delimitacion visual de algunas cubiertas

La eleccion de las bandas para realizar la composicion, y el orden de los colores destinados a cada una, dependen del sensor sobre el que se trabaje y de la aplicacion ultima del proyecto. La composicion mas habitual es la denominada falso color o infrarrojo color, fruto de aplicar las balas de rojo, verde y azul sobre las bandas correspondientes al infrarrojo cercano, el rojo y el verde respectivamente

# Ploteamos la combinacion de bandas 5, 4 y 3 que para L8 es color falso
par(mfrow = c(1,2))
plotRGB(landsatRGB2015, axes=TRUE, stretch="lin", main="Composicion de color verdadero")
landsatFCC2015 = stack(b5, b4, b3)
plotRGB(landsatFCC2015, axes=TRUE, stretch="lin", main="Composicion de color falso")

Nota : Compruebe siempre la documentacion del paquete (- help(plotRGB) -) para ver otros argumentos que se pueden agregar (como la escala) para mejorar o modificar la imagen.

Pregunta 1 : Use la funcion plotRGB con RasterStack `` landsat ’’ para crear un compuesto de color verdadero y falso (recuerde la posicion de las bandas en la pila).

## solucion a la pregunta 1, ploteamos la combinacion de bandas 5, 6 y 4 que para L8 es color falso
landsatFCC2015_p1 = stack(b5, b6, b4)
plotRGB(landsatFCC2015_p1, axes=TRUE, stretch="lin", main="Composicion de color falsa - Agua / Tierra")

SUBCONJUNTO Y RENOMBRAR BANDAS

Puede seleccionar capas (bandas) especificas mediante la funcion - subset - o mediante indexacion.

# Seleccionamos unicamente las 3 primeras bandas
landsat2015sub01 = subset(landsat2015, 1:3)
# Mismo
landsat2015sub02 = landsat2015[[1:3]]

# Numero de bandas en los datos originales y nuevos.
nlayers(landsat2015)
[1] 7
## [1] 7
nlayers(landsat2015sub01)
[1] 3
## [1] 3
nlayers(landsat2015sub02)
[1] 3
## [1] 3

No usaremos las ultimas cuatro bandas - landsat -. Puedes eliminar aquellos usando:

## Eliminando las ultimas cuatro bandas, es decir, seleccionaremos para nuestro ejercicio las bandas de 1 a la 7 (1:7)
landsat2015 = subset(landsat2015, 1:7)
plot(landsat2015)

Para mayor claridad, es util establecer los nombres de las bandas.

# Aca vemos que nombres tienen las bandas
names(landsat2015)
[1] "LC08_L1TP_008057_20150104_20170415_01_T1_B1" "LC08_L1TP_008057_20150104_20170415_01_T1_B2"
[3] "LC08_L1TP_008057_20150104_20170415_01_T1_B3" "LC08_L1TP_008057_20150104_20170415_01_T1_B4"
[5] "LC08_L1TP_008057_20150104_20170415_01_T1_B5" "LC08_L1TP_008057_20150104_20170415_01_T1_B6"
[7] "LC08_L1TP_008057_20150104_20170415_01_T1_B7"
## [1] "LC08_L1TP_008057_20180317_20180403_01_T1_B1" "LC08_L1TP_008057_20180317_20180403_01_T1_B2"
## [3] "LC08_L1TP_008057_20180317_20180403_01_T1_B3" "LC08_L1TP_008057_20180317_20180403_01_T1_B4"
## [5] "LC08_L1TP_008057_20180317_20180403_01_T1_B5" "LC08_L1TP_008057_20180317_20180403_01_T1_B6"
## [7] "LC08_L1TP_008057_20180317_20180403_01_T1_B7"

# Aca las renombramos y las ploteamos
names(landsat2015) = c('ultra-azul', 'azul', 'verde', 'rojo', 'NIR', 'SWIR1', 'SWIR2')
names(landsat2015)
[1] "ultra.azul" "azul"       "verde"      "rojo"       "NIR"        "SWIR1"      "SWIR2"     
## [1] "ultra.azuk" "azul"       "verde"      "rojo"       "NIR"        "SWIR1"      "SWIR2"     
## [1] "ultra.azul" "azul"       "verde"      "rojo"       "NIR"        "SWIR1"      "SWIR2"

SUBCONJUNTO ESPACIAL O RECORTE

El subconjunto espacial se puede usar para limitar el analisis a un subconjunto geografico de la imagen. Los subconjuntos espaciales se pueden crear con la funcion - crop -, utilizando un objeto - extent - u otro objeto espacial del que se puede extraer una Extension.

# Usando Extension
extent(landsat2015)
class      : Extent 
xmin       : 446085 
xmax       : 673515 
ymin       : 362985 
ymax       : 595215 
## class      : Extent
## xmin       : 446085 
## xmax       : 673515
## ymin       : 362985
## ymax       : 595215

# Cargamos un objeto espacial que se encuentra en un shapefile. Esta extension es el area de Sibate
sibate2015 = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
# Define que la extension es Sibate
e = extent(sibate2015)

# Corta la imagen landsat con el area de sibate
landsatcrop2015 = crop(landsat2015, e)

# Plotea a Sibate
plotRGB(landsatcrop2015, r= 6, g= 5, b=2, axes = TRUE, stretch = "lin", main = "Composicion de color falsa - Sibaté")

Pregunta 2 : Tambien es posible la seleccion interactiva de la imagen. Use -drawExtent- y -drawPoly- para seleccionar un area de interes

se da respuesta a esta pregunta con el ejercicio anterior

Pregunta 3 : Use el -Landsatcrop- de RasterStack para crear un compuesto de color verdadero y falso

# Creacion de un compuesto de color verdadero, para landsat 8 la combinacion de color es 4,3,2
landsatcrop2015pregunta = crop(stack(b4, b3, b2), e)

# Ploteamos la combinacion
plotRGB(landsatcrop2015pregunta, axes = TRUE, stretch = "lin", main = "Sibaté 2015 - Color Verdadero")

GUARDANDO RESULTADOS EN EL DISCO

En esta etapa, es posible que queramos guardar el raster en el disco usando la funcion - writeRaster -. Se admiten multiples tipos de archivos. Utilizaremos el formato GeoTiff de uso comun. Mientras se conserva el orden de las capas, los nombres de las capas se pierden desafortunadamente en el formato GeoTiff

# Aca guardanmos nuestro raster de Sibate y lo imprimimos para ver lo que se ha guardado
x = writeRaster(landsatcrop2015, filename="Sibaté_banda.tif", overwrite=TRUE)
plot(x)

Alternativamente, puede utilizar el formato ‘raster-grd’.


# Lo guardamos tambien en formato .grd ya que este formato si guarda los nombres de las capas
writeRaster(landsatcrop2015, filename="Sibate_banda.grd", overwrite=TRUE)

Una ventaja de este formato es que guarda los nombres de las capas. La desventaja de este formato es que no muchos otros programas pueden leer los datos, en contraste con el formato GeoTiff.

Nota: Consulte la documentacion del paquete (- help(writeRaster) -) para ver argumentos utiles adicionales que se pueden agregar

RELACION ENTRE BANDAS

Una matriz de diagrama de dispersion puede ser util para explorar las relaciones entre capas raster. Esto se puede hacer con la funcion pares () del paquete raster.

Trazado de reflejo en la longitud de onda ultra azul contra el reflejo en la longitud de onda azul.

A continuacion podemos ver como las bandas del ultra azul y el azul estan casi perfectamente correlacionadas entre si. Una correlacion positiva indica una relación directa entre dos bandas, tal como cuando los valores de celda de una capa aumentan, es probable que los valores de celda de otra capa tambien aumenten. Una correlacion negativa significa que una variable cambia de manera inversa a la otra. Una correlación de cero significa que las bandas son independientes entre si.

# Comparacion del reflejo en la longitud de onda Ulta azul vs azul
pairs(landsatcrop2015[[1:2]], main = "Ultra-Azul versus Azul")

Trazado de reflejo en la longitud de onda roja contra reflejo en la longitud de onda NIR.

A diferencia de las bandas anteriores, la siguiente es una correlacion baja en positivo, lo que infire que son mas independientes una de la otra.

# Comparacion del reflejo en la longitud de onda Roja vs NIR
pairs(landsatcrop2015[[4:5]], main = "Roja versus NIR")

La primera grafica revela altas correlaciones entre las regiones de longitud de onda azul. Debido a la alta correlacion, podemos usar una de las bandas azules sin perder mucha informacion.

Esta distribucion de puntos en la segunda grafica (entre NIR y rojo) es unica debido a su forma triangular. La vegetacion se refleja muy bien en el rango NIR que en el rojo y crea la esquina superior cerca del eje NIR (y). El agua absorbe energia de todas las bandas y ocupa el lugar cercano al origen. El rincon mas alejado se crea debido a las caracteristicas superficiales altamente reflectantes, como el suelo brillante o el hormigon.

EXTRAER VALORES DE PIXELES

A menudo, queremos obtener los valores de las celdas raster para ubicaciones geograficas o areas especificas. La funcion - extract - se utiliza para obtener valores raster en las ubicaciones de otros datos espaciales. Puede usar puntos, lineas, poligonos o un objeto de extension (rectangulo). Tambien puede usar numeros de celda para extraer valores. Al usar puntos, - extract - devuelve los valores de un objeto - Raster* - para las celdas en las que se ubica un conjunto de puntos.

# Cargar los poligonos con informacion sobre el uso del suelo
sibatecobert = shapefile ('C:/Users/David-PC/Desktop/ESCRITORIO/PERCEPCION REMOTA/TRABAJO_COBERTURAS/cobertu.shp')
Z-dimension discarded
    
# Generar muestras de 300 puntos a partir de los poligonos
ptsibatecobert = spsample(sibatecobert,300, type='regular')

# Agregar la clase de cobertura del suelo a los puntos
ptsibatecobert$Name = over(ptsibatecobert, sibatecobert)$Name
    
# Extraer valores con puntos
df = extract(landsat2015, ptsibatecobert)
   
# Para ver algunos de los valores de reflectancia
head(df)
     ultra.azul azul verde rojo   NIR SWIR1 SWIR2
[1,]       7928 7237  6660 6081 12490  7668  6064
[2,]       7957 7278  6700 6101 13199  7933  6123
[3,]       7952 7288  6733 6158 13073  8111  6255
[4,]       7951 7297  6744 6105 14049  7740  6011
[5,]       7953 7273  6723 6076 13661  8025  6186
[6,]       7959 7262  6716 6121 12563  8113  6218
#     ultra.azul azul verde rojo  NIR  SWIR1 SWIR2
#[1,]       7928 7238  6623 6033 12696  7520  5997
#[2,]       7957 7278  6700 6101 13199  7933  6123
#[3,]       7973 7285  6741 6148 13482  8072  6219
#[4,]       7962 7262  6710 6114 13413  8116  6199
#[5,]       7931 7246  6671 6060 13541  7655  6014
#[6,]       7943 7242  6623 6024 12437  7529  6039

PERFILES ESPECTRALES

Una grafica del espectro (todas las bandas) para los pixeles que representan ciertas caracteristicas de la superficie terrestre (p. Ej. Agua) se conoce como perfil espectral. Dichos perfiles demuestran las diferencias en las propiedades espectrales de varias caracteristicas de la superficie terrestre y constituyen la base para el analisis de imagenes. Los valores espectrales se pueden extraer de cualquier conjunto de datos multiespectrales utilizando la funcion - extract -. En el ejemplo anterior, extrajimos valores de datos de Landsat para las muestras. Estas muestras incluyen: tierras de cultivo, agua, barbecho, construido y abierto. Primero calculamos los valores medios de reflectancia para cada clase y cada banda.

numero= length(ptsibatecobert)
numero
[1] 298
df_samples = as (ptsibatecobert, "SpatialPointsDataFrame")
df_samples
class       : SpatialPointsDataFrame 
features    : 298 
extent      : 577367, 585597.8, 486272.4, 501061.1  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 1
names       :         Name 
min values  :         Agua 
max values  : zona desnuda 
df_samples@data=data.frame(ID=1:numero,size=1)
df_samples
class       : SpatialPointsDataFrame 
features    : 298 
extent      : 577367, 585597.8, 486272.4, 501061.1  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 2
names       :  ID, size 
min values  :   1,    1 
max values  : 298,    1 
plot(landsatcrop2015)
plot(sibatecobert, add= TRUE)
plot(df_samples,pch=1, cex=(df_samples$size)/4, add=TRUE)



df_samples$Name =over(df_samples,sibatecobert)$Name
df_samples
class       : SpatialPointsDataFrame 
features    : 298 
extent      : 577367, 585597.8, 486272.4, 501061.1  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 3
names       :  ID, size,         Name 
min values  :   1,    1,         Agua 
max values  : 298,    1, zona desnuda 
df1=raster::extract(landsatcrop2015, df_samples)


ms = aggregate(df1, list(ptsibatecobert$Name), mean)

# En lugar de la primera columna, usamos nombres de fila
rownames(ms) = ms[,1]
ms = ms[,-1]
ms

##              ultra.blue       blue      green       red        NIR      SWIR1    SWIR2
# Agua           8251.053     7501.298   6840.658     6066.404  5762.921    5081.289    5050.825
# Bosque           8026.761   7326.134   6773.410     6172.284  11207.410   7962.134    6412.746
# Cultivos       8417.864     7800.318   7603.682     7197.955  18156.818   14063.045   11198.864
# Fresa          8541.667   7870.667     7464.667     6902.000  13157.667   9832.333    7806.000
# Invernadero     11522.083  11035.833  11442.333    11179.083  18368.333   14785.000   11300.083
# pastos           8481.000   7926.727   8267.909     7331.636  21093.273   12449.000   8507.273
# zona desnuda  10975.500    11035.500  12884.750    14428.000  17930.750   20671.750   16907.500

Ahora trazamos el espectro medio de estas caracteristicas.

Una de las mayores dificultades de generar un mapa de uso de la tierra es delimitar las diferentes coberturas. Establecer limites entre tipos de uso o vegetacion es un proceso muchas veces subjetivo, pero para ello existen diversas herramientas que pueden ayudar en el proceso de interpretacion, entre ellas realizar un perfil espectral. Un perfil espectral es la representacion del comportamiento espectral a lo largo de un trayecto, por lo tanto, es un proceso similar a crear un perfil topografico, en vez de la elevacion del terreno se grafican los valores de los pixeles.

# Cree un vector de color para las clases de cobertura del suelo para usar en el trazado
mycolor = c('darkred', 'yellow', 'burlywood', 'cyan', 'blue', 'green','magenta', "darkgreen")

# transformar ms de un data.frame a una matriz
ms = as.matrix(ms)

# Primero crea una parcela vacia
plot(0, ylim=c(0,25000), xlim = c(1,7), type='n', xlab="Bandas", ylab = "Reflectancia")

# Agrega las diferentes clases
for (i in 1:nrow(ms)){
  lines(ms[i,], type = "l", lwd = 3, lty = 1, col = mycolor[i])
}

# Titulo
title(main="Perfil espectral de Landsat", font.main = 2)

# Leyenda
legend("topleft", rownames(ms),
      cex=0.8, col=mycolor, lty = 1, lwd =3, bty = "n")

El perfil espectral muestra (des) similitud en la reflectancia de diferentes caracteristicas en la superficie de la tierra (o por encima de ella). ‘Agua’ muestra una reflexion relativamente baja en todas las longitudes de onda, y ‘Pastos’, ‘Invernadero’ y ‘Zona desnuda’ tienen una reflectancia relativamente alta en las longitudes de onda mas largas.

OPERACIONES MATEMATICAS BASICAS

El paquete - raster- admite muchas operaciones matematicas. Las operaciones matematicas generalmente se realizan por pixel (celda de cuadricula). Primero haremos algunas operaciones aritmeticas basicas para combinar bandas. En el primer ejemplo, escribimos una funcion matematica personalizada para calcular el indice de vegetacion de diferencia normalizada (NDVI).

### solo puedo cargar las bandas de la 1 a la 7 porque la 8 no tiene la misma extension de las demas
raslistp3 = paste0('./data2015/LC08_L1TP_008057_20150104_20170415_01_T1_B', 1:7, ".tif")
##raslistp3= practica 3

# Stack de las bandas cargadas
landsatp3 = stack(raslistp3)
plot(landsatp3)


# Combinacion de las bandas 4,3,2
landsatRGBp3 = landsatp3[[c(4,3,2)]]
## landsatRGBp3 = practica 3
plot(landsatRGBp3)


# Combinacion de las bandas en falso color 5,4,3
landsatFCCp3 = landsatp3[[c(5,4,3)]]
## landsatFCCp3 = practica 3
plot(landsatFCCp3)

INDICES DE VEGETACION

Definamos una funciOn general para un Indice basado en razOn (vegetaciOn). En la funcion a continuacion, -img- es un objeto Raster * de multiples capas -i- y -k- son los indices de las capas (numeros de capa) utilizados para calcular el indice de vegetacion.

## vi2015= indice de vegetacion para la imagen 2015
vi2015 = function(img, k, i) {
  
  bk = img [[k]]
  bi = img [[i]]
  vi2015=(bk-bi)/(bk+bi)
  return(vi2015)
}

El NDVI, es un indice usado para estimar la cantidad, calidad y desarrollo de la vegetacion con base a la medicion de la intensidad de la radiacion de ciertas bandas del espectro electromagnetico que la vegetacion emite o refleja, en este caso, el NDVI, esta ligado a un gran numero de factores en los cultivos. La biomasa suele ser el factor mas importante. Lo que resulta mas complicado del NDVI es que este esta relacionado con la biomasa y la biomasa se ve afectada por todo.

## para landsat NIR = 5, red = 4
## ndvi2015= indice de vegetacion de direfencia normalizada (NDVI) para la imagen landsat 2015

ndvi2015 = vi2015(landsatp3, 5, 4) 
plot(ndvi2015, col=rev(terrain.colors(9)), main= "Landsat 2015 - NVDI")


# Seleccionando el shape del area de sibate, cargandolo y recortandolo con respecto del NDVI de la imagen Landsat
NDVI1_sibate_2015 = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
eNDVI1_sibate = extent(NDVI1_sibate_2015)
NDVI_recorte_1 = crop(ndvi2015, eNDVI1_sibate)
plot(NDVI_recorte_1, col=rev(terrain.colors(10)), main = "Landsat 2015 - NDVI")

Puedes ver la variacion en el verdor desde la trama.

Una forma alternativa de lograr esto es asi


vi2_2015 = function(x, y) {
  (x-y)/(x+y)
}

ndvi2_2015 = overlay(landsatp3[[5]], landsatp3[[4]], fun = vi2_2015)
plot(ndvi2_2015, col=rev(terrain.colors(10)), main = "Landsat 2015 - NDVI v2")


# Seleccionando el shape del area de sibate, cargandolo y recortandolo con respecto del NDVI de la imagen Landsat
NDVI2_sibate_2015 = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
eNDVI2_sibate = extent(NDVI2_sibate_2015)
NDVI_recorte_2 = crop(ndvi2_2015, eNDVI2_sibate)
plot(NDVI_recorte_2, col=rev(terrain.colors(10)), main = "Landsat 2015 - NDVI")

Pregunta 1 : Adapte el codigo que se muestra arriba para calcular los indices para identificar i) agua y ii) acumulados. Sugerencia: Use el diagrama del perfil espectral para encontrar las bandas que tienen reflectancia maxima y minima para estas dos clases.

El indice Diferencial de Agua Normalizado (NDWI) se utiliza para el analisis de masas de agua. El índice utiliza bandas verdes y casi infrarrojas de imagenes de teledeteccion. El NDWI puede mejorar la informacion sobre el agua de manera eficiente en la mayoria de los casos. Es sensible a la acumulacion de tierra y resulta en la sobreestimacion de los cuerpos de agua. Los productos NDWI pueden ser usados en conjunto con los productos de cambio NDVI para evaluar el contexto de las areas de cambio aparente

## p1 es pregunta 1

ndvi2015_p1 = vi2015(landsatp3, 3, 6) 
plot(ndvi2015_p1, col=rev(terrain.colors(10)), main= "Landsat 2015 - NDWI")


vi2_2015_p1 = function(x, y) {
  (x-y)/(x+y)
}

ndvi2_2015_p1 = overlay(landsatp3[[3]], landsatp3[[6]], fun = vi2_2015_p1)
plot(ndvi2_2015_p1, col=rev(topo.colors(10)), main = "Landsat 2015 - NDWI")


### PARA INDICE DE AGUA DE DIFERENCIA NORMALIZADA - NDWI
# Seleccionando el shape del area de sibate, cargandolo y recortandolo con respecto del NDwI de la imagen Landsat

NDWI_sibate = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
eNDWI = extent(NDWI_sibate)
NDWI_recorte = crop(ndvi2_2015_p1, eNDWI)
plot(NDWI_recorte, col=rev(topo.colors(10)), main = "Landsat 2015 - NDWI")

El NDBI o indice de Diferencia Normalizada Edificada permite llevar a cabo la estimacion de zonas con superficies edificadas o en desarrollo de construccion frente a las habituales zonas naturalizadas con vegetacion o desnudas. El indice NDBI, junto a otros como el indice NDVI y el indice UI son una via de analisis territorial en estudios urbanisticos, infraestructuras y la comparacion de la evolucion de las urbes en el tiempo.

### PARA INDICE INCORPORADO DE DIFERENCIA NORMALIZADA - NDBI

ndbi1_2015_p1 = overlay(landsatp3[[6]], landsatp3[[5]], fun = vi2_2015_p1)
plot(ndbi1_2015_p1, col=rev(heat.colors(10)), main = "Landsat 2015 - NDBI")


# Seleccionando el shape del area de sibate, cargandolo y recortandolo con respecto del NDBI de la imagen Landsat

NDBI_sibate = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
eNDBI = extent(NDBI_sibate)
NDBI_recorte = crop(ndbi1_2015_p1, eNDBI)
plot(NDBI_recorte, col=rev(heat.colors(10)), main = "Landsat 2015 - NDBI")

HISTOGRAMA

Podemos explorar la distribucion de valores contenidos en nuestro raster utilizando la funcion -hist ()- que produce un histograma. Los histogramas a menudo son utiles para identificar valores atipicos y valores de datos incorrectos en nuestros datos raster

## ver histograma de datos
hist(NDVI_recorte_1,
     main= "Dsitribucion de valores del NDVI",
     xlab= "NDVI",
     ylab= "Frecuencia",
     col= terrain.colors(50),
     xlim= c (-0.1,0.7),
     breaks = 30,
     xaxt= 'n')

axis(side = 1, at=seq(-0.5,1,0.05), labels = seq(-0.5,1,0.05))

Nos referiremos a este histograma para la siguiente subseccion sobre umbralizacion.

Pregunta 2 : Haga histogramas de los valores que los indices de vegetacion desarrollaron en la pregunta 1

## respuesta a la pregunta 2: ver histograma de datos
hist(NDWI_recorte,
     main= "Dsitribucion de valores del NDWI",
     xlab= "NDWI",
     ylab= "Frecuencia",
     col= topo.colors(50),
     xlim= c (-0.5,0.3),
     breaks = 30,
     xaxt= 'n')

axis(side = 1, at=seq(-0.5,1,0.05), labels = seq(-0.5,1,0.05))

## respuesta a la pregunta 2: ver histograma de datos
hist(NDBI_recorte,
     main= "Dsitribucion de valores del NDBI",
     xlab= "NDBI",
     ylab= "Frecuencia",
     col= heat.colors(50),
     xlim= c (-0.5,0.3),
     breaks = 30,
     xaxt= 'n')

axis(side = 1, at=seq(-0.5,1,0.05), labels = seq(-0.5,1,0.05))

UMBRALIZACION

Podemos aplicar reglas basicas para obtener una estimacion de la extension espacial de diferentes caracteristicas de la superficie terrestre. Tenga en cuenta que los valores NDVI estan estandarizados y varian entre -1 y +1. Los valores mas altos indican mas cobertura verde.

Las celdas con valores de NDVI superiores a 0.4 son definitivamente vegetacion. La siguiente operacion enmascara todas las celdas que tal vez no sean vegetacion.

La funcion (reclassify) clasifica grupos de valores a otros valores. Por ejemplo, todos los valores entre 1 y 10 se convierten en 1, y todos los valores entre 11 y 15 se convierten en 2.

veg = reclassify(NDVI_recorte_1, cbind(-Inf, 0.4, NA))
plot(veg, main = "Vegetacion")

Vamos a mapear el area que corresponde al pico entre 0.25 y 0.3 en el histograma NDVI.

land = reclassify(NDVI_recorte_1, c(-Inf, 0.25, NA, 0.25, 0.3, 1, 0.3, Inf, NA))
plot(land, main = " Que es esto?")

Estas pueden ser las areas abiertas. Puede trazar -land- sobre el -landsatFCC- raster original para obtener mas informacion

plotRGB(landsatcrop2015, r=7, g=6, b=4, axes = TRUE, stretch="lin", main = "Sibate composicion en falso color")
plot(land, add = TRUE, legend= FALSE)

Tambien puede crear clases para diferentes cantidades de presencia de vegetacion.

vegc = reclassify(NDVI_recorte_1, c(-Inf,0.25,1, 0.25,0.3,2, 0.3,0.4,3, 0.4,0.5,4, 0.5,Inf, 5))
plot(vegc, col = rev(terrain.colors(4)), main = 'Umbral basado en NDVI')

Pregunta 3 : Es posible encontrar agua usando el umbral de NDVI o cualquier otro indice

# Umbral, en este caso para agua
agua = reclassify(NDWI_recorte, cbind(-Inf, 0.1, NA))
plot(agua, main = "Agua", col= topo.colors(10))


#Reclasifico el Umbral, en este caso para agua
aguac = reclassify(NDWI_recorte, c(-Inf,0.025,1, 0.025,0.03,2, 0.03,0.1,3, 0.1,0.2,4, 0.2,Inf, 5))
plot(aguac, col = rev(topo.colors(10)), main = 'Umbral basado en NDWI')

ANALISIS DE COMPONENTES PRINCIPALES

Los datos multiespectrales a veces se transforman para ayudar a reducir la dimensionalidad y el ruido en los datos. La transformacion de componentes principales es un metodo generico de reduccion de datos que se puede utilizar para crear algunas bandas no correlacionadas a partir de un conjunto mas grande de bandas correlacionadas.

Puede calcular el mismo numero de componentes principales que el numero de bandas de entrada. El primer componente principal (PC) explica el mayor porcentaje de varianza y otros PC explican la varianza adicional en orden decreciente.

sampleRandom toma una muestra aleatoria de los valores de celda de un objeto Raster (sin reemplazo).

set.seed(1)

sr = sampleRandom(landsatp3, 100000)
plot(sr[,c(4,5)], main = "NIR - ROJO")

Esto se conoce como diagrama de vegetacion y linea de suelo (igual que el diagrama de dispersion en la seccion anterior).

La tecnica de Analisis por Componentes Principales (PCA, Principal Components Analysis) es una transformacion que permite reducir esta redundancia y puede ser aplicada previamente a un analisis visual o a un proceso mas complejo de clasificacion a traves de algoritmos matematico-estadisticos. El proposito de esta tecnica es “comprimir” toda la informacion contenida en un conjunto original de N bandas espectrales a un conjunto menor de nuevas bandas o componentes.

pca = prcomp(sr, scale = TRUE)
pca
Standard deviations (1, .., p=7):
[1] 2.59169224 0.42707865 0.29072035 0.10439979 0.06868262 0.02120325 0.01227403

Rotation (n x k) = (7 x 7):
                                                   PC1          PC2          PC3         PC4
LC08_L1TP_008057_20150104_20170415_01_T1_B1 -0.3828686  0.146466958 -0.285016623  0.64295434
LC08_L1TP_008057_20150104_20170415_01_T1_B2 -0.3824643  0.251163610 -0.246675390  0.25077406
LC08_L1TP_008057_20150104_20170415_01_T1_B3 -0.3831958  0.239695066 -0.165224729 -0.23270432
LC08_L1TP_008057_20150104_20170415_01_T1_B4 -0.3785953  0.424481057  0.002225169 -0.62514538
LC08_L1TP_008057_20150104_20170415_01_T1_B5 -0.3622638 -0.745210227 -0.440008806 -0.23096773
LC08_L1TP_008057_20150104_20170415_01_T1_B6 -0.3766513 -0.349896939  0.516775974  0.01974348
LC08_L1TP_008057_20150104_20170415_01_T1_B7 -0.3792861 -0.007760711  0.608233062  0.15820288
                                                    PC5          PC6          PC7
LC08_L1TP_008057_20150104_20170415_01_T1_B1 -0.10311614  0.074615517 -0.566686791
LC08_L1TP_008057_20150104_20170415_01_T1_B2 -0.04410742  0.257250131  0.773807743
LC08_L1TP_008057_20150104_20170415_01_T1_B3 -0.03046576 -0.843888776  0.034355651
LC08_L1TP_008057_20150104_20170415_01_T1_B4 -0.05067863  0.455034481 -0.275762605
LC08_L1TP_008057_20150104_20170415_01_T1_B5  0.23955731  0.093210905 -0.019919926
LC08_L1TP_008057_20150104_20170415_01_T1_B6 -0.68244282 -0.008319047  0.049611469
LC08_L1TP_008057_20150104_20170415_01_T1_B7  0.67882929 -0.017110515  0.002057162
screeplot(pca)

pci = predict(landsatp3, pca, index = 1:2)
plot(pci[[1]])


## Recortado a sibate
pci_sibate = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
epci = extent(pci_sibate)
pci_recorte = crop(pci, epci)
plot(pci_recorte, col=rev(terrain.colors(20)), main = "pci Sibate")

El primer componente principal resalta los limites entre las clases de uso de la tierra o los detalles espaciales, que es la informacion mas comun entre todas las longitudes de onda. Es dificil entender lo que destaca el segundo componente principal. Vamos a intentar umbral de nuevo:

landsatFCC2015 = stack(b5, b4, b3)

## recortado a sibate
pc2 = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
epc2 = extent(pc2)
pc2_rec= crop(landsatFCC2015, epc2)

pc2 = reclassify(pci_recorte[[2]], c(-Inf,0,1,0,Inf,NA))
par(mfrow = c(1,2))
plotRGB(pc2_rec, r = 1, g = 2, b = 3, axes = TRUE, stretch = "lin", main = "FFC")
plotRGB(pc2_rec, r = 1, g = 2, b = 3, axes = TRUE, stretch = "lin", main = "FFC")
plot(pc2, legend = FALSE, add = TRUE)

Para obtener mas informacion acerca de la informacion contenida en las parcelas de vegetacion y lineas de suelo, lea este documento de -Gitelson et al- . Una extension de PCA en la teledeteccion se conoce como Transformacion -Tasseled-cap- .

CAPITULO 2

En este capitulo exploramos la clasificacion no supervisada. Existen varios algoritmos de clasificación no supervisados, y la eleccion del algoritmo puede afectar los resultados. Exploraremos un solo algoritmo (k-means) para ilustrar el principio general

Para este ejemplo, seguiremos el esquema de clasificacion de la -Base de datos nacional de cobertura de la tierra 2011 (NLCD 2011)- para Sibate, Cundinamarca, Colombia. Utilizamos imagenes compuestas sin nubes de Landsat 8 con 7 bandas.

Sibate, Imagen LandSat 8 2015, utilizando 7 bandas

library(raster)
landsat8 = stack(b2,b3,b4,b5,b6,b7)
names(landsat8) = c ('blue', 'green', 'red', 'NIR', 'SWIR1','SWIR2')
plot(landsat8)

Pregunta 1 : Haga una trama compuesta de 3 bandas de falso color de `` landsat8 ’’.

landsat8FCC_imagen = stack(b5, b6, b4)
plotRGB(landsat8FCC_imagen, axes=TRUE, stretch="lin", main="Landsat composicion de color falsa - Agua / Tierra")


# recortando a sibate

sibatextend = shapefile('C:/Users/David-PC/Desktop/ESCRITORIO/SIBATE_RURAL/rural.shp')
ext = extent(sibatextend)
landsatfcc = crop(landsat8FCC_imagen, ext)
plotRGB(landsatfcc, axes = TRUE, stretch = "lin", main = "Landsat True Color Composite")

En la clasificacion no supervisada, utilizamos los datos de reflectancia, pero no proporcionamos ningun dato de respuesta (es decir, no identificamos ningun pixel como perteneciente a una clase en particular). Esto puede parecer extraño, pero puede ser util cuando no tenemos mucho conocimiento previo de un area de estudio. O si tiene un amplio conocimiento de la distribucion de las clases de interes de la cobertura del suelo, pero no tiene datos especificos

El algoritmo agrupa pixeles con caracteristicas espectrales similares en grupos.

Obtenga mas informacion sobre K-means y otros algoritmos supervisados sin supervision -aqui- .

Realizaremos una clasificacion no supervisada en un subconjunto espacial de la capa -ndvi-. Aqui hay otra forma de calcular -ndvi-. En este caso, no usamos una funcion separada, sino una notacion algebraica directa.

ndviLandSat8=(landsat8[['NIR']]-landsat8[['red']])/(landsat8[['NIR']]+landsat8[['red']])
plot(ndviLandSat8)

Haremos un agrupamiento -kmeans- de los datos -ndvi-. Primero usamos -crop- para hacer un subconjunto espacial de -ndvi-, para permitir un procesamiento mas rapido (puede seleccionar cualquier -extent- usando la función -drawExtent()).

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 RasterLayer -ndvi- en una matriz (matriz). Ahora realizaremos el agrupamiento -kmeans- en la matriz e inspeccionaremos la salida.

K-means es un algoritmo de clasificacion no supervisada (clusterizacion) que agrupa objetos en k grupos basandose en sus caracteristicas. El agrupamiento se realiza minimizando la suma de distancias entre cada objeto y el centroide de su grupo o cluster. Se suele usar la distancia cuadratica.

El algoritmo consta de tres pasos:

Inicializacion: una vez escogido el numero de grupos, k, se establecen k centroides en el espacio de los datos, por ejemplo, escogiendolos aleatoriamente.

1.Asignacion objetos a los centroides: cada objeto de los datos es asignado a su centroide mas cercano.
2.Actualizacion centroides: se actualiza la posicion del centroide de cada grupo tomando como nuevo centroide la posicion del promedio de los objetos pertenecientes a dicho grupo.
3.Se repiten los pasos 2 y 3 hasta que los centroides no se mueven, o se mueven por debajo de una distancia umbral en cada paso.

#El algoritmo k-means resuelve un problema de optimizacion, siendo la funcion a optimizar (minimizar) la suma de las distancias cuadraticas de cada objeto al centroide de su cluster. # #

# 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] 6 10 10 3 3 3 3 10 6 3 ...
 $ centers     : num [1:10, 1] 0.285 0.099 0.376 0.548 0.331 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:10] "1" "2" "3" "4" ...
  .. ..$ : NULL
 $ totss       : num 3096
 $ withinss    : num [1:10] 6 4.46 6.17 7.92 5.96 ...
 $ tot.withinss: num 57.6
 $ betweenss   : num 3039
 $ size        : int [1:10] 32049 5743 33820 9132 34882 20727 25928 6570 19149 28567
 $ iter        : int 163
 $ ifault      : NULL
 - attr(*, "class")= chr "kmeans"

-kmeans-devuelve un objeto con 9 elementos. La longitud del elemento -cluster- dentro -kmncluster- es 216567 que es igual a la longitud de -nr- creado desde -ndvi-. Los valores de celda de rango -kmnclustercluster- entre 1 a 10 correspondientes al numero de entrada del cluster que proporcionamos en la funcion -kmeans-. -kmncluster\(cluster- indica la etiqueta del cluster para el pixel correspondiente. Necesitamos convertir los valores -kmncluster\)cluster- 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] 6 10 10 3 3 3 3 10 6 3 ...
 $ centers     : num [1:10, 1] 0.285 0.099 0.376 0.548 0.331 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:10] "1" "2" "3" "4" ...
  .. ..$ : NULL
 $ totss       : num 3096
 $ withinss    : num [1:10] 6 4.46 6.17 7.92 5.96 ...
 $ tot.withinss: num 57.6
 $ betweenss   : num 3039
 $ size        : int [1:10] 32049 5743 33820 9132 34882 20727 25928 6570 19149 28567
 $ iter        : int 163
 $ 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))) 

CAPITULO 3

CLASIFICACION SUPERVISADA

Aqui exploramos la clasificacion supervisada. Existen varios algoritmos de clasificacion supervisados, y la eleccion del algoritmo puede afectar los resultados. Aqui exploramos dos algoritmos relacionados (RandomForest y arbol de decision).

En la clasificacion supervisada, tenemos conocimiento previo sobre algunos de los tipos de cobertura del suelo mediante, por ejemplo, trabajo de campo, datos espaciales de referencia o interpretación de imagenes de alta resolucion (como las disponibles en los mapas de Google). Se identifican sitios especificos en el area de estudio que representan ejemplos homogeneos de estos tipos de cobertura terrestre conocidos. Estas areas se conocen comunmente como sitios de entrenamiento porque las propiedades espectrales de estos sitios se usan para entrenar el algoritmo de clasificacion.

# Directorio de trabajo

setwd("C:/Users/David-PC/Desktop/ESCRITORIO/Landsat_procesamiento/")

# Importar las imagenes
B2 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B2.TIF")
B3 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B3.TIF")
B4 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B4.TIF")
B5 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B5.TIF")
B6 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B6.TIF")
B7 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B7.TIF")

# Datos imagen MTL
dia <- 004
SUN_ELEVATION = 51.89134539

RADIANCE_MULT_BAND_2 = 1.3298E-02
RADIANCE_MULT_BAND_3 = 1.2254E-02
RADIANCE_MULT_BAND_4 = 1.0333E-02
RADIANCE_MULT_BAND_5 = 6.3236E-03
RADIANCE_MULT_BAND_6 = 1.5726E-03
RADIANCE_MULT_BAND_7 = 5.3006E-04

RADIANCE_ADD_BAND_2 = -66.49141
RADIANCE_ADD_BAND_3 = -61.27126
RADIANCE_ADD_BAND_4 = -51.66738
RADIANCE_ADD_BAND_5 = -31.61786
RADIANCE_ADD_BAND_6 = -7.86307
RADIANCE_ADD_BAND_7 = -2.65028

REFLECTANCE_MAXIMUM_BAND_2 = 1.210700
REFLECTANCE_MAXIMUM_BAND_3 = 1.210700
REFLECTANCE_MAXIMUM_BAND_4 = 1.210700
REFLECTANCE_MAXIMUM_BAND_5 = 1.210700
REFLECTANCE_MAXIMUM_BAND_6 = 1.210700
REFLECTANCE_MAXIMUM_BAND_7 = 1.210700

RADIANCE_MAXIMUM_BAND_2 = 805.01141
RADIANCE_MAXIMUM_BAND_3 = 741.81116
RADIANCE_MAXIMUM_BAND_4 = 625.53699
RADIANCE_MAXIMUM_BAND_5 = 382.79742
RADIANCE_MAXIMUM_BAND_6 = 95.19823
RADIANCE_MAXIMUM_BAND_7 = 32.08690

# Conversion
SUN_ELEVATION_R <- SUN_ELEVATION*pi/180  # radianes
d <- 1+0.0167*(sin((2*pi*(dia-93.5))/365)) # distancia del sol a la tierra

# Determinacion ESUN
ESUN2 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_2/REFLECTANCE_MAXIMUM_BAND_2
ESUN3 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_3/REFLECTANCE_MAXIMUM_BAND_3
ESUN4 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_4/REFLECTANCE_MAXIMUM_BAND_4
ESUN5 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_5/REFLECTANCE_MAXIMUM_BAND_5
ESUN6 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_6/REFLECTANCE_MAXIMUM_BAND_6
ESUN7 <- pi*(d^2)*RADIANCE_MAXIMUM_BAND_7/REFLECTANCE_MAXIMUM_BAND_7

# Elimar valores nulos
B2[B2==0] <- NA
B3[B3==0] <- NA
B4[B4==0] <- NA
B5[B5==0] <- NA
B6[B6==0] <- NA
B7[B7==0] <- NA

# Determinacion de radiancia sensor
L2 <- RADIANCE_MULT_BAND_2*B2 + RADIANCE_ADD_BAND_2
L3 <- RADIANCE_MULT_BAND_3*B3 + RADIANCE_ADD_BAND_3
L4 <- RADIANCE_MULT_BAND_4*B4 + RADIANCE_ADD_BAND_4
L5 <- RADIANCE_MULT_BAND_5*B5 + RADIANCE_ADD_BAND_5
L6 <- RADIANCE_MULT_BAND_6*B6 + RADIANCE_ADD_BAND_6
L7 <- RADIANCE_MULT_BAND_7*B7 + RADIANCE_ADD_BAND_7

# Determinacion de la radiancia minima
Lmin2 <- RADIANCE_MULT_BAND_2*min(getValues(B2), na.rm = TRUE)+ RADIANCE_ADD_BAND_2
Lmin3 <- RADIANCE_MULT_BAND_3*min(getValues(B3), na.rm = TRUE)+ RADIANCE_ADD_BAND_3
Lmin4 <- RADIANCE_MULT_BAND_4*min(getValues(B4), na.rm = TRUE)+ RADIANCE_ADD_BAND_4
Lmin5 <- RADIANCE_MULT_BAND_5*min(getValues(B5), na.rm = TRUE)+ RADIANCE_ADD_BAND_5
Lmin6 <- RADIANCE_MULT_BAND_6*min(getValues(B6), na.rm = TRUE)+ RADIANCE_ADD_BAND_6
Lmin7 <- RADIANCE_MULT_BAND_7*min(getValues(B7), na.rm = TRUE)+ RADIANCE_ADD_BAND_7

# Determinacion radiancia del objeto oscuro
LDOS2 <- 0.01*ESUN2*sin(SUN_ELEVATION_R)/pi*(d^2)
LDOS3 <- 0.01*ESUN3*sin(SUN_ELEVATION_R)/pi*(d^2)
LDOS4 <- 0.01*ESUN4*sin(SUN_ELEVATION_R)/pi*(d^2)
LDOS5 <- 0.01*ESUN5*sin(SUN_ELEVATION_R)/pi*(d^2)
LDOS6 <- 0.01*ESUN6*sin(SUN_ELEVATION_R)/pi*(d^2)
LDOS7 <- 0.01*ESUN7*sin(SUN_ELEVATION_R)/pi*(d^2)

# Determinar el efecto bruma
LP2 <- Lmin2-LDOS2
LP3 <- Lmin3-LDOS3
LP4 <- Lmin4-LDOS4
LP5 <- Lmin5-LDOS5
LP6 <- Lmin6-LDOS6
LP7 <- Lmin7-LDOS7

# Banda Reflectancia Superficie Dark Object Substrction (DOS)
RS_dos_B2 <- (pi*(L2-LP2)*(d)^2)/(ESUN2*sin(SUN_ELEVATION_R))
RS_dos_B3 <- (pi*(L3-LP3)*(d)^2)/(ESUN3*sin(SUN_ELEVATION_R))
RS_dos_B4 <- (pi*(L4-LP4)*(d)^2)/(ESUN4*sin(SUN_ELEVATION_R))
RS_dos_B5 <- (pi*(L5-LP5)*(d)^2)/(ESUN5*sin(SUN_ELEVATION_R))
RS_dos_B6 <- (pi*(L6-LP6)*(d)^2)/(ESUN6*sin(SUN_ELEVATION_R))
RS_dos_B7 <- (pi*(L7-LP7)*(d)^2)/(ESUN7*sin(SUN_ELEVATION_R))

# Combinacion de bandas
L8_B234567_RS_DOS <- stack(RS_dos_B2,RS_dos_B3,RS_dos_B4,RS_dos_B5,RS_dos_B6,RS_dos_B7)

# Exportacion imagen reflectancia Superfie DOS
#setwd("C:/Users/David-PC/Desktop/ESCRITORIO/Landsat_procesamiento/SHAPE/")
writeRaster(L8_B234567_RS_DOS,"L8_B234567_RS_DOS1.tif", drivername="Gtiff", overwrite=TRUE)


## Tema: Temperatura de brillo de Landsat 8 TIRS


# Importar las imagenes
B10 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B10.TIF")
B11 = raster("LC08_L1TP_008057_20150104_20170415_01_T1/LC08_L1TP_008057_20150104_20170415_01_T1_B11.TIF")

# K imagen Landsat 8 TIRS
K1_CONSTANT_BAND_10 = 774.8853
K2_CONSTANT_BAND_10 = 1321.0789
K1_CONSTANT_BAND_11 = 480.8883
K2_CONSTANT_BAND_11 = 1201.1442

# Datos de radiancia del sensor imagen Landsat
RADIANCE_MULT_BAND_10 = 3.3420E-04
RADIANCE_MULT_BAND_11 = 3.3420E-04

RADIANCE_ADD_BAND_10 = 0.10000
RADIANCE_ADD_BAND_11 = 0.10000

# Elimar valores nulos
B10[B10==0] <- NA
B11[B11==0] <- NA

# Determinancion de la Radianca
L10 <- RADIANCE_MULT_BAND_10*(na.omit(B10)) + RADIANCE_ADD_BAND_10
L11 <- RADIANCE_MULT_BAND_11*(na.omit(B11)) + RADIANCE_ADD_BAND_11


# Determinacion Temperatura de brillo Celsius
TB_B10 <- K2_CONSTANT_BAND_10/log(K1_CONSTANT_BAND_10/L10+1) - 273.15
TB_B11 <- K2_CONSTANT_BAND_11/log(K1_CONSTANT_BAND_11/L11+1) - 273.15

# Exportacion imagen Temperatura de brillo Celsius
writeRaster(TB_B10,"L8_TB_B10.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(TB_B11,"L8_TB_B11.tif", drivername="Gtiff",overwrite=TRUE)

Usualmente, la clasificacion supervisada requiere que el usuario seleccione una o más Regiones de Interes (ROIs, o Áreas de Entrenamiento) para cada clase de cobertura del suelo identificada en la imagen. Las ROIs son poligonos o puntos dibujados sobre areas homogeneas de la imagen que se superponen a pixeles pertenecientes a la misma clase de cobertura del suelo.

##Reproyectar y recorte de images con la zona de estudio Landsat 8 OLI

# Importar las imagen
L8_B234567_RS_DOS = stack("L8_B234567_RS_DOS1.tif")

# Verificar sistemas de coordenada
st_crs(L8_B234567_RS_DOS)
Coordinate Reference System:
  User input: +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
  wkt:
PROJCS["UTM Zone 18, Northern Hemisphere",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-75],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["Meter",1]]
# Reproyectar imagen
L8_B234567_RS_DOS_py = projectRaster(L8_B234567_RS_DOS, crs = "+init=epsg:32618")

## importar shapefile
Zona_UTM_18n <- shapefile("rural.shp")
st_crs(Zona_UTM_18n)
Coordinate Reference System:
  User input: +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
  wkt:
PROJCS["UTM Zone 18, Northern Hemisphere",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-75],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",0],
    UNIT["Meter",1]]
# Recortar imagen segun shapefile Landsat 8 extension
clip_L8_B234567_RS_DOS_py <- crop(L8_B234567_RS_DOS_py,Zona_UTM_18n)

# Visualizacion del recorte de la zona de estudio
plotRGB(clip_L8_B234567_RS_DOS_py, 5,4,3, stretch = "lin")


# Guardar archivo por banda recortada y proyectada
L8_SR_B2 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.1
L8_SR_B3 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.2
L8_SR_B4 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.3
L8_SR_B5 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.4
L8_SR_B6 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.5
L8_SR_B7 <- clip_L8_B234567_RS_DOS_py$L8_B234567_RS_DOS1.6

# Exportacion imagen reflectancia Superfie DOS1 Proyectado y recortado
writeRaster(clip_L8_B234567_RS_DOS_py,"clip_L8_B234567_RS_DOS_py.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B2,"L8_SR_B2.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B3,"L8_SR_B3.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B4,"L8_SR_B4.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B5,"L8_SR_B5.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B6,"L8_SR_B6.tif", drivername="Gtiff",overwrite=TRUE)
writeRaster(L8_SR_B7,"L8_SR_B7.tif", drivername="Gtiff",overwrite=TRUE)

Usualmente, la clasificacion supervisada requiere que el usuario seleccione una o más Regiones de Interes (ROIs, o Áreas de Entrenamiento) para cada clase de cobertura del suelo identificada en la imagen. Las ROIs son poligonos o puntos dibujados sobre areas homogeneas de la imagen que se superponen a pixeles pertenecientes a la misma clase de cobertura del suelo.

Random Forest se considera como la “panacea” en todos los problemas de ciencia de datos, pues es a) Util para regresion y clasificacion, b) un grupo de modelos “debiles”, se combinan en un modelo robusto, c) Sirve como una tecnica para reduccion de la dimensionalidad, d) Se generan multiples arboles (a diferencia de CART), e) Cada arbol da una clasificacion, y f) el resultado es la clase con mayor numero de votos en todo el bosque (forest). Importante: Para regresion, se toma el promedio de las salidas (predicciones) de todos los arboles.

##Clasificacion supervisada con Random Forest - Landsat 8 OLI

# Agregar raster multibandas de landsat 8
L8_2015 <- stack("clip_L8_B234567_RS_DOS_py.tif")

# Dimension de la banda
dim(L8_2015)
[1] 617 351   6
# Nombre de las bandas
names(L8_2015)
[1] "clip_L8_B234567_RS_DOS_py.1" "clip_L8_B234567_RS_DOS_py.2" "clip_L8_B234567_RS_DOS_py.3"
[4] "clip_L8_B234567_RS_DOS_py.4" "clip_L8_B234567_RS_DOS_py.5" "clip_L8_B234567_RS_DOS_py.6"
# cambiar nombre de las bandas
names(L8_2015) <- c("BLUE", "GREEN", "RED", "NIR", "SWIR1", "SWIR2")

# Agregar los shapefile del ROI 2019
roi <- shapefile("clasificacion.shp")

# Informacion de la tabla de atribu del shp
print(roi)
class       : SpatialPointsDataFrame 
features    : 2236 
extent      : 576861.3, 587313.9, 484041, 502444.5  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 1
names       :   Class 
min values  :    Agua 
max values  : represa 
head(roi@data,10)

# Ploteamos la imagen y las puntos de muestreo
plotRGB(L8_2015,5,4,3, stretch="lin")
plot(roi,add=TRUE,col="red",pch = 15, lwd=3)


# Extraer los valores del raster a tabla
Extraer_R_Shp <- extract(L8_2015,roi) # tenemos los valores Reflectancia Superficie
print(Extraer_R_Shp)
              BLUE      GREEN        RED        NIR      SWIR1      SWIR2
   [1,] 0.11948301 0.10713014 0.15300514 0.20682272 0.21726671 0.23338568
   [2,] 0.14195211 0.14032544 0.18904631 0.28627995 0.25465634 0.25938857
   [3,] 0.13981703 0.12992968 0.17885414 0.20590763 0.22130814 0.25041595
   [4,] 0.13353890 0.12339737 0.17298281 0.20509428 0.23986316 0.25702471
   [5,] 0.13272555 0.11833928 0.18025205 0.22367497 0.23935480 0.26587027
   [6,] 0.11739877 0.10430878 0.15051429 0.18308212 0.20117721 0.22385383
   [7,] 0.12504944 0.12171981 0.17222030 0.21627825 0.26657730 0.29423705
   [8,] 0.12408359 0.11864429 0.16342606 0.20778859 0.23960897 0.24990755
   [9,] 0.16721714 0.18783084 0.25812945 0.30389476 0.33190113 0.31569013
  [10,] 0.13750404 0.12835379 0.19438384 0.25173664 0.23488127 0.24190079
  [11,] 0.14421427 0.13440315 0.18312417 0.21787962 0.22941643 0.24884000
  [12,] 0.11633123 0.11823761 0.16057937 0.19596913 0.21848677 0.23968942
  [13,] 0.10212284 0.08895659 0.15107346 0.20140861 0.23887186 0.27967238
  [14,] 0.12123682 0.11289991 0.16035064 0.19642667 0.21386071 0.23534288
  [15,] 0.12009303 0.11099361 0.15963896 0.19932434 0.20892966 0.23008130
  [16,] 0.13386934 0.12621871 0.17130531 0.21518528 0.22204526 0.24863666
  [17,] 0.13432685 0.13193767 0.18236166 0.20326416 0.22977228 0.25041595
  [18,] 0.14545973 0.13656366 0.20048392 0.23823957 0.26634854 0.28318012
  [19,] 0.12446485 0.12393113 0.18406458 0.20867822 0.25341088 0.24474765
  [20,] 0.24280888 0.30968258 0.34589398 0.34636855 0.37988999 0.35981625
  [21,] 0.11048520 0.10702846 0.14987886 0.21734583 0.20770961 0.22479427
  [22,] 0.11920342 0.10662179 0.16085896 0.18979251 0.20781128 0.22842909
  [23,] 0.12624407 0.10896020 0.15999480 0.20537385 0.21879178 0.23651212
  [24,] 0.11381490 0.10512215 0.15562309 0.19121596 0.20168558 0.22362503
  [25,] 0.11955926 0.12797251 0.16243480 0.32898250 0.24881025 0.22329462
  [26,] 0.20991859 0.20224260 0.23990552 0.38136935 0.30973679 0.31513089
  [27,] 0.15661803 0.14357890 0.18261583 0.40424570 0.26855990 0.20860283
  [28,] 0.15061949 0.12476992 0.15282722 0.32120451 0.19456859 0.15461437
  [29,] 0.21157074 0.22529630 0.26933828 0.44804126 0.39295477 0.32021454
  [30,] 0.13958828 0.11432330 0.13846667 0.37722617 0.18361349 0.14180356
  [31,] 0.12118598 0.09121875 0.11948025 0.32567811 0.17522562 0.14208318
  [32,] 0.13819031 0.12301610 0.15526725 0.34535182 0.21452157 0.17106001
  [33,] 0.13412350 0.10763849 0.13905126 0.30547065 0.20331231 0.16874696
  [34,] 0.15516923 0.12014393 0.14441423 0.37150708 0.19339935 0.14965782
  [35,] 0.11727168 0.10865519 0.14388047 0.35803548 0.23122109 0.17975307
  [36,] 0.16142194 0.13297978 0.15691935 0.38724095 0.23289867 0.21978688
  [37,] 0.13142926 0.11592461 0.14108463 0.35373980 0.18661280 0.14383703
  [38,] 0.12626949 0.10169078 0.13249370 0.29517630 0.17784365 0.14531130
  [39,] 0.10507127 0.08481354 0.11782815 0.27532470 0.23195821 0.19607161
  [40,] 0.15125492 0.17141111 0.23273796 0.32562730 0.33741680 0.31307203
  [41,] 0.16205738 0.18755126 0.26628825 0.35061336 0.37147668 0.33706689
  [42,] 0.21843347 0.24718082 0.30619279 0.34125948 0.33703554 0.32046872
  [43,] 0.16254032 0.16856435 0.24547182 0.34059864 0.44353625 0.57050848
  [44,] 0.16401453 0.15989697 0.21642032 0.23973925 0.23589797 0.26045614
  [45,] 0.14253671 0.13010760 0.17717662 0.19957852 0.18780744 0.22893746
  [46,] 0.14304507 0.13447942 0.18332751 0.19581662 0.20254979 0.23991817
  [47,] 0.28368029 0.23523457 0.25718901 0.33658251 0.44587469 0.45945597
  [48,] 0.18373853 0.20249678 0.26745746 0.27270666 0.27399930 0.28401890
  [49,] 0.12586281 0.13539445 0.17737995 0.30445394 0.22743383 0.22611605
  [50,] 0.10311412 0.09889485 0.14967553 0.18333629 0.16104247 0.17914303
  [51,] 0.19512559 0.27142915 0.38285017 0.46720660 0.52271277 0.50396347
  [52,] 0.16360785 0.19011843 0.26440740 0.29624388 0.30434820 0.31718978
  [53,] 0.16198112 0.13984253 0.17209323 0.42310601 0.23724513 0.17873633
  [54,] 0.09597179 0.07205392 0.11299895 0.11862161 0.11427364 0.15237758
  [55,] 0.13897826 0.14002044 0.17961663 0.18514098 0.21759714 0.23178431
  [56,] 0.17329192 0.15468636 0.19118132 0.39555272 0.23205988 0.17899053
  [57,] 0.11007852 0.08056880 0.10674638 0.29260907 0.15628932 0.12777266
  [58,] 0.11727168 0.10865519 0.14388047 0.35803548 0.23122109 0.17975307
  [59,] 0.16213363 0.13577572 0.16606943 0.39677274 0.25541887 0.20252787
  [60,] 0.17878212 0.13859706 0.16291772 0.41131201 0.21248816 0.16239238
  [61,] 0.14891651 0.14230803 0.19268093 0.22835191 0.24748851 0.27542755
  [62,] 0.14218086 0.13468276 0.18815672 0.21653244 0.23127194 0.24878915
  [63,] 0.13430142 0.13125138 0.17290658 0.26149720 0.25003028 0.25738055
  [64,] 0.13539438 0.13033636 0.19712889 0.29044852 0.29466400 0.31660518
  [65,] 0.13023463 0.13445400 0.17966747 0.32888082 0.29550281 0.28295133
  [66,] 0.12441401 0.11714465 0.16932280 0.24756806 0.25613058 0.25849897
  [67,] 0.15984605 0.15608433 0.22114785 0.32916039 0.27588022 0.26648030
  [68,] 0.16154903 0.11717007 0.13012993 0.35602742 0.17387846 0.13636403
  [69,] 0.11228985 0.10006406 0.12494488 0.33459991 0.22740841 0.18694644
  [70,] 0.12626949 0.11198489 0.14967553 0.26808050 0.22977228 0.19706292
  [71,] 0.12184684 0.10024198 0.12573281 0.37549773 0.20875172 0.16086729
  [72,] 0.12583739 0.10191954 0.12807116 0.36266160 0.21335237 0.16795899
  [73,] 0.18533984 0.17822301 0.19900973 0.47473034 0.29303727 0.21536411
  [74,] 0.15201746 0.12977718 0.15608059 0.30468270 0.21035306 0.18384542
  [75,] 0.58754689 0.50305927 0.51372182 0.88973302 0.84374005 1.00053525
  [76,] 0.65017569 0.66074973 0.83089924 1.22665107 1.43452680 1.43663681
  [77,] 0.33850589 0.34951183 0.38991606 0.62424010 0.61609793 0.76833904
  [78,] 0.12365148 0.10906187 0.13790751 0.32397512 0.20483738 0.16945866
  [79,] 0.13516563 0.10715555 0.13691625 0.37171045 0.20387150 0.15921509
  [80,] 0.11770378 0.10463922 0.13711958 0.34166616 0.24682765 0.20499343
  [81,] 0.10763844 0.08438143 0.10753432 0.37076998 0.19253515 0.14681096
  [82,] 0.14706104 0.11887304 0.13783126 0.37132919 0.20455779 0.15763915
  [83,] 0.11439950 0.09576850 0.12413154 0.35806090 0.21520786 0.16376497
  [84,] 0.11930509 0.08979537 0.11399020 0.35859463 0.19652575 0.14897153
  [85,] 0.12253311 0.10298707 0.13107036 0.33724341 0.20994636 0.16905196
  [86,] 0.11183233 0.08519480 0.11269394 0.27545178 0.17748781 0.14879359
  [87,] 0.12367690 0.09429427 0.12392822 0.21366020 0.11897594 0.12881482
  [88,] 0.10367330 0.08478811 0.11500689 0.28091669 0.15034156 0.14160022
  [89,] 0.10446125 0.08059422 0.10832224 0.22202279 0.12093312 0.12604423
  [90,] 0.12728620 0.10204662 0.13124827 0.26452199 0.17527644 0.15850338
  [91,] 0.07670530 0.05700673 0.10184093 0.13509259 0.11572246 0.12792517
  [92,] 0.07843369 0.06353904 0.10639055 0.18237041 0.13476042 0.13827042
  [93,] 0.08206840 0.06803795 0.10377261 0.18089615 0.12395784 0.13219544
  [94,] 0.11376406 0.10057241 0.15244599 0.22982617 0.21947806 0.21180555
  [95,] 0.09899648 0.08178885 0.12120862 0.19009753 0.15867861 0.17299181
  [96,] 0.09770019 0.08438143 0.13401872 0.22560674 0.17779282 0.16729811
  [97,] 0.07579027 0.05110987 0.09256377 0.19792633 0.12459329 0.12754390
  [98,] 0.10591005 0.09274381 0.12809658 0.21790501 0.14233494 0.14289655
  [99,] 0.09988609 0.08936327 0.13734832 0.31914565 0.19418731 0.15814753
 [100,] 0.08852445 0.07309604 0.10102759 0.17904063 0.13216780 0.15441102
 [101,] 0.09004951 0.06292903 0.10046842 0.16663656 0.11747629 0.13130581
 [102,] 0.09841187 0.08837198 0.12911326 0.20430629 0.17677610 0.18148151
 [103,] 0.11157816 0.12591371 0.17407575 0.32816908 0.26741609 0.23272480
 [104,] 0.09581929 0.10395294 0.15038720 0.34865615 0.28792828 0.23160641
 [105,] 0.11203567 0.11978807 0.16558652 0.32183999 0.25549513 0.22728528
 [106,] 0.15649094 0.17102985 0.25866321 0.37837005 0.39193806 0.34931850
 [107,] 0.08610979 0.06236984 0.10435720 0.10301483 0.08346723 0.12640007
 [108,] 0.11068854 0.10850269 0.15361516 0.15918903 0.14279246 0.16948406
 [109,] 0.12548155 0.10049617 0.12524989 0.30961385 0.16571933 0.13257672
 [110,] 0.07924705 0.06137855 0.11251602 0.22751309 0.32732594 0.27125892
 [111,] 0.10522377 0.08549980 0.12443656 0.19474904 0.18208842 0.17759253
 [112,] 0.10242785 0.09071040 0.13211246 0.18280253 0.15814483 0.16701850
 [113,] 0.10044528 0.08288179 0.12166610 0.16096829 0.14012359 0.15784252
 [114,] 0.05324491 0.03197045 0.05827636 0.22949573 0.09927713 0.09706736
 [115,] 0.05192320 0.02889493 0.05560759 0.19032629 0.08644112 0.09239040
 [116,] 0.05360076 0.03382593 0.05921679 0.23295259 0.10990179 0.10115971
 [117,] 0.05403286 0.03158919 0.05908971 0.24525499 0.10736000 0.10235438
 [118,] 0.05482080 0.03402928 0.05835262 0.24411118 0.10349648 0.09894831
 [119,] 0.05403286 0.03186878 0.05860678 0.24395867 0.10059886 0.09401717
 [120,] 0.04800890 0.01674534 0.04627959 0.06496382 0.02904765 0.06676877
 [121,] 0.04841559 0.01613532 0.04615251 0.05639789 0.02452328 0.06547242
 [122,] 0.05047441 0.02238804 0.05034629 0.12154470 0.05250832 0.07777487
 [123,] 0.05301616 0.02930161 0.05581092 0.20316248 0.09465108 0.09475429
 [124,] 0.05459205 0.03265673 0.05924221 0.20517051 0.09828583 0.09849078
 [125,] 0.05245697 0.02782739 0.05649718 0.18511556 0.08659363 0.09302586
 [126,] 0.05367702 0.03146210 0.05847970 0.23008035 0.10326773 0.10027008
 [127,] 0.05227905 0.02838658 0.05555676 0.19858722 0.08890665 0.09498306
 [128,] 0.05421078 0.03240255 0.05954721 0.23803625 0.10880881 0.10080384
 [129,] 0.05601543 0.03659645 0.06178389 0.27855280 0.12248360 0.10708217
 [130,] 0.04994064 0.02015129 0.04912628 0.08880607 0.04168032 0.07299624
 [131,] 0.04844100 0.01641491 0.04661001 0.05840593 0.02594668 0.06618414
 [132,] 0.04889852 0.01687243 0.04630500 0.06219324 0.02759884 0.06628581
 [133,] 0.05332117 0.03105542 0.05731052 0.24139144 0.08173882 0.08715423
 [134,] 0.05451579 0.03374968 0.05896262 0.23102081 0.09981090 0.09744864
 [135,] 0.05271115 0.03075041 0.05743761 0.23623154 0.10049719 0.09640648
 [136,] 0.05375327 0.03151293 0.05832720 0.23651116 0.10390317 0.10334568
 [137,] 0.05474455 0.03496972 0.06188557 0.27163908 0.12667754 0.10797182
 [138,] 0.05476997 0.03636769 0.06094513 0.24047638 0.11142685 0.10263397
 [139,] 0.05395661 0.03245339 0.05901346 0.22985159 0.10919008 0.10382863
 [140,] 0.05253322 0.02851367 0.05509925 0.18831825 0.08326389 0.08989941
 [141,] 0.05016939 0.02780198 0.05710719 0.23313053 0.08687323 0.08934020
 [142,] 0.04968646 0.02701403 0.05603968 0.21104212 0.08417894 0.08893352
 [143,] 0.05192320 0.02874242 0.05761553 0.18145534 0.07622316 0.08756092
 [144,] 0.04902561 0.02439602 0.05393007 0.17235565 0.08644112 0.09165327
 [145,] 0.04983897 0.02355725 0.05260840 0.19022465 0.08600902 0.09813493
 [146,] 0.05606626 0.03710480 0.06328350 0.29479501 0.12334782 0.10720927
 [147,] 0.05149111 0.03019123 0.05886095 0.19881597 0.08369599 0.08771344
 [148,] 0.04940687 0.02632776 0.05535342 0.19042797 0.08611069 0.09211080
 [149,] 0.05205029 0.03280923 0.05769177 0.25239751 0.11834050 0.10344736
 [150,] 0.04851726 0.02365891 0.05326923 0.16671281 0.06613228 0.08362109
 [151,] 0.04818683 0.02335390 0.05212548 0.15466458 0.06191291 0.08153679
 [152,] 0.05354993 0.03136043 0.05903887 0.20707689 0.09576946 0.09683859
 [153,] 0.04811057 0.02129508 0.05082922 0.13732938 0.06142997 0.08146054
 [154,] 0.05116068 0.02731904 0.05481967 0.18211621 0.08550067 0.09277167
 [155,] 0.04887310 0.02391309 0.05202381 0.17624463 0.08730532 0.09396634
 [156,] 0.05301616 0.03240255 0.05601426 0.26137012 0.10891049 0.10436241
 [157,] 0.05446496 0.03324133 0.05959805 0.22019267 0.09188054 0.09404259
 [158,] 0.05316867 0.03021664 0.05794595 0.20651768 0.09099092 0.09361047
 [159,] 0.05380410 0.03268214 0.05881012 0.21477859 0.09060965 0.09305128
 [160,] 0.05245697 0.02675986 0.05438758 0.15311408 0.06625936 0.08629001
 [161,] 0.04864434 0.01631324 0.04663542 0.06257451 0.02838679 0.06681960
 [162,] 0.05217738 0.02658193 0.05311674 0.14525986 0.06674231 0.08369735
 [163,] 0.05421078 0.03087750 0.05542967 0.20438254 0.08450937 0.09066195
 [164,] 0.04894935 0.01966836 0.04955837 0.09747367 0.04345956 0.07241162
 [165,] 0.05334659 0.02942870 0.05624301 0.18928415 0.08684781 0.09068737
 [166,] 0.04971188 0.02297264 0.05169339 0.13097484 0.06081995 0.08174013
 [ reached getOption("max.print") -- omitted 2070 rows ]
# Seleccionar la columna de las clases
Class <- roi@data$Class
print(Class)
   [1] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
   [8] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [15] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [22] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [29] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [36] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [43] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [50] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [57] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [64] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [71] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [78] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [85] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [92] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [99] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
 [106] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
 [113] "Artificial" "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [120] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [127] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [134] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [141] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [148] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [155] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [162] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [169] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [176] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [183] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [190] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [197] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [204] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [211] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [218] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [225] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [232] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [239] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [246] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [253] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [260] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [267] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [274] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [281] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [288] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [295] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [302] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [309] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [316] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [323] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [330] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [337] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [344] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [351] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [358] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [365] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [372] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [379] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [386] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [393] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [400] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [407] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [414] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [421] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [428] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [435] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [442] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [449] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [456] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [463] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [470] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [477] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [484] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [491] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [498] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [505] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [512] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [519] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [526] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [533] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [540] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [547] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [554] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [561] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [568] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [575] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [582] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [589] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [596] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [603] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [610] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [617] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [624] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [631] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [638] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [645] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [652] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [659] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [666] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [673] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [680] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [687] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [694] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [701] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [708] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [715] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [722] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [729] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [736] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [743] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [750] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [757] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [764] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [771] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [778] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [785] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [792] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [799] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [806] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [813] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [820] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [827] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [834] "bosque"     "bosque"     "bosque"     "bosque"     "represa"    "represa"    "represa"   
 [841] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [848] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [855] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [862] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [869] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [876] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [883] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [890] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [897] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [904] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [911] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [918] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [925] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [932] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [939] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [946] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [953] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [960] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [967] "represa"    "represa"    "represa"    "Agua"       "Agua"       "Agua"       "Agua"      
 [974] "Agua"       "Agua"       "Agua"       "Agua"       "pastos"     "pastos"     "pastos"    
 [981] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [988] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [995] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [ reached getOption("max.print") -- omitted 1236 entries ]
# Crear un data frame con los datos reflectancia superficie y las clases
tabla <- data.frame(Extraer_R_Shp, Class)
summary(tabla$Class)
      Agua Artificial     bosque   cultivos    Desnudo     pastos    represa 
         8        113        724        747         23        489        132 
# Seperando los datos en Entrenamiento y prueba
Muestra <- sample(1:2235,1000) # sample separa aleatoriamente los datos
Pruebas <- tabla[Muestra,]
Entrenamiento <- tabla[-Muestra,]

# Aplicando el algoritmo Random Forest
modelo <- randomForest(Class ~.,data=Entrenamiento, importance=TRUE)
prediccion<- predict(modelo, Pruebas[,-7])

# Definimos la paleta de colores segun las 7 clases
mycolor <- c("#00FF00","#0000FF","#228B22","#FF1493", "#1C1CE2", "#1C1CE2" ,"#5454AA")

## Visualizar prediccion a obtener
## Cantidad de punto que se encuentra en la clase
plot(prediccion, main = "Numero de pixeles identificados",
     axes = TRUE, xlab = "Clases", ylab = "Numero de pixel", col= mycolor)

# Matriz de confusion
MC<-table(Pruebas[,7],prediccion)
MC
            prediccion
             Agua Artificial bosque cultivos Desnudo pastos represa
  Agua          0          0      3        0       0      0       1
  Artificial    0         53      0        2       1      1       0
  bosque        0          0    326        1       0      1       0
  cultivos      0          0      3      322       0      0       0
  Desnudo       0          1      0        7       6      0       0
  pastos        0          0      0        1       0    213       0
  represa       0          0      0        0       0      0      58
# Indice de Kappa
kappa<-sum(diag(MC))/sum(MC)
kappa
[1] 0.978
# Ejecutamos el clasificador Random Forest
beginCluster()
8 cores detected, using 7
## 8 cores detected, using 7
rf_class<- clusterR(L8_2015, raster::predict,args = list(model =modelo))
endCluster()

# Ploteamos la clasificación con Support vector machine
plot(rf_class,main=paste("kappa = ",kappa,sep =""),col =mycolor,cex.lab=0.8,
     cex.axis=0.8,cex.main=0.9)

# Exportacion de bandas
writeRaster(rf_class,"Class_L8_Random_Forest.tif", drivername="Gtiff",overwrite=TRUE)

Ventajas de RandomForest : Existen muy pocas suposiciones y por lo tanto la preparacion de los datos es minima, puede manejar hasta miles de variables de entrada e identificar las mas significativas, una de las salidas del modelo es la importancia de variables, incorpora metodos efectivos para estimar valores faltantes, y es posible usarlo como metodo no supervisado (clustering) y deteccion de outliers.

Desventajas de RandomForest : Perdida de interpretacion, bueno para clasificacion, no tanto para regresion. Las predicciones no son de naturaleza continua, en regresion, no puede predecir mas alla del rango de valores del conjunto de entrenamiento y poco control en lo que hace el modelo (modelo caja negra para modeladores estadisticos)

## Clasificacion supervisada con Decision_Tree - Landsat 8 OLI

# Agregar raster multibandas de landsat 8
L8_2015 <- stack("clip_L8_B234567_RS_DOS_py.tif")

# Dimension de la banda
dim(L8_2015)
[1] 617 351   6
# Nombre de las bandas
names(L8_2015)
[1] "clip_L8_B234567_RS_DOS_py.1" "clip_L8_B234567_RS_DOS_py.2" "clip_L8_B234567_RS_DOS_py.3"
[4] "clip_L8_B234567_RS_DOS_py.4" "clip_L8_B234567_RS_DOS_py.5" "clip_L8_B234567_RS_DOS_py.6"
# cambiar nombre de las bandas
names(L8_2015) <- c("BLUE", "GREEN", "RED", "NIR", "SWIR1", "SWIR2")

# Agregar los shapefile del ROI 2019

roi <- shapefile("clasificacion.shp")
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 9 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 8 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 7 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 6 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 5 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 4 (<-DESKTOP-QM41LE8:11036)
Warning in .Internal(gc(verbose, reset, full)) :
  closing unused connection 3 (<-DESKTOP-QM41LE8:11036)
# Informacion de la tabla de atribu del shp
print(roi)
class       : SpatialPointsDataFrame 
features    : 2236 
extent      : 576861.3, 587313.9, 484041, 502444.5  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=18 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0 
variables   : 1
names       :   Class 
min values  :    Agua 
max values  : represa 
head(roi@data,10)

# Ploteamos la imagen y las puntos de muestreo
plotRGB(L8_2015,5,4,3, stretch="lin")
plot(roi,add=TRUE,col="red",pch = 15, lwd=3)


# Extraer los valores del raster a tabla
Extraer_R_Shp <- extract(L8_2015,roi) # tenemos los valores Reflectancia Superficie
print(Extraer_R_Shp)
              BLUE      GREEN        RED        NIR      SWIR1      SWIR2
   [1,] 0.11948301 0.10713014 0.15300514 0.20682272 0.21726671 0.23338568
   [2,] 0.14195211 0.14032544 0.18904631 0.28627995 0.25465634 0.25938857
   [3,] 0.13981703 0.12992968 0.17885414 0.20590763 0.22130814 0.25041595
   [4,] 0.13353890 0.12339737 0.17298281 0.20509428 0.23986316 0.25702471
   [5,] 0.13272555 0.11833928 0.18025205 0.22367497 0.23935480 0.26587027
   [6,] 0.11739877 0.10430878 0.15051429 0.18308212 0.20117721 0.22385383
   [7,] 0.12504944 0.12171981 0.17222030 0.21627825 0.26657730 0.29423705
   [8,] 0.12408359 0.11864429 0.16342606 0.20778859 0.23960897 0.24990755
   [9,] 0.16721714 0.18783084 0.25812945 0.30389476 0.33190113 0.31569013
  [10,] 0.13750404 0.12835379 0.19438384 0.25173664 0.23488127 0.24190079
  [11,] 0.14421427 0.13440315 0.18312417 0.21787962 0.22941643 0.24884000
  [12,] 0.11633123 0.11823761 0.16057937 0.19596913 0.21848677 0.23968942
  [13,] 0.10212284 0.08895659 0.15107346 0.20140861 0.23887186 0.27967238
  [14,] 0.12123682 0.11289991 0.16035064 0.19642667 0.21386071 0.23534288
  [15,] 0.12009303 0.11099361 0.15963896 0.19932434 0.20892966 0.23008130
  [16,] 0.13386934 0.12621871 0.17130531 0.21518528 0.22204526 0.24863666
  [17,] 0.13432685 0.13193767 0.18236166 0.20326416 0.22977228 0.25041595
  [18,] 0.14545973 0.13656366 0.20048392 0.23823957 0.26634854 0.28318012
  [19,] 0.12446485 0.12393113 0.18406458 0.20867822 0.25341088 0.24474765
  [20,] 0.24280888 0.30968258 0.34589398 0.34636855 0.37988999 0.35981625
  [21,] 0.11048520 0.10702846 0.14987886 0.21734583 0.20770961 0.22479427
  [22,] 0.11920342 0.10662179 0.16085896 0.18979251 0.20781128 0.22842909
  [23,] 0.12624407 0.10896020 0.15999480 0.20537385 0.21879178 0.23651212
  [24,] 0.11381490 0.10512215 0.15562309 0.19121596 0.20168558 0.22362503
  [25,] 0.11955926 0.12797251 0.16243480 0.32898250 0.24881025 0.22329462
  [26,] 0.20991859 0.20224260 0.23990552 0.38136935 0.30973679 0.31513089
  [27,] 0.15661803 0.14357890 0.18261583 0.40424570 0.26855990 0.20860283
  [28,] 0.15061949 0.12476992 0.15282722 0.32120451 0.19456859 0.15461437
  [29,] 0.21157074 0.22529630 0.26933828 0.44804126 0.39295477 0.32021454
  [30,] 0.13958828 0.11432330 0.13846667 0.37722617 0.18361349 0.14180356
  [31,] 0.12118598 0.09121875 0.11948025 0.32567811 0.17522562 0.14208318
  [32,] 0.13819031 0.12301610 0.15526725 0.34535182 0.21452157 0.17106001
  [33,] 0.13412350 0.10763849 0.13905126 0.30547065 0.20331231 0.16874696
  [34,] 0.15516923 0.12014393 0.14441423 0.37150708 0.19339935 0.14965782
  [35,] 0.11727168 0.10865519 0.14388047 0.35803548 0.23122109 0.17975307
  [36,] 0.16142194 0.13297978 0.15691935 0.38724095 0.23289867 0.21978688
  [37,] 0.13142926 0.11592461 0.14108463 0.35373980 0.18661280 0.14383703
  [38,] 0.12626949 0.10169078 0.13249370 0.29517630 0.17784365 0.14531130
  [39,] 0.10507127 0.08481354 0.11782815 0.27532470 0.23195821 0.19607161
  [40,] 0.15125492 0.17141111 0.23273796 0.32562730 0.33741680 0.31307203
  [41,] 0.16205738 0.18755126 0.26628825 0.35061336 0.37147668 0.33706689
  [42,] 0.21843347 0.24718082 0.30619279 0.34125948 0.33703554 0.32046872
  [43,] 0.16254032 0.16856435 0.24547182 0.34059864 0.44353625 0.57050848
  [44,] 0.16401453 0.15989697 0.21642032 0.23973925 0.23589797 0.26045614
  [45,] 0.14253671 0.13010760 0.17717662 0.19957852 0.18780744 0.22893746
  [46,] 0.14304507 0.13447942 0.18332751 0.19581662 0.20254979 0.23991817
  [47,] 0.28368029 0.23523457 0.25718901 0.33658251 0.44587469 0.45945597
  [48,] 0.18373853 0.20249678 0.26745746 0.27270666 0.27399930 0.28401890
  [49,] 0.12586281 0.13539445 0.17737995 0.30445394 0.22743383 0.22611605
  [50,] 0.10311412 0.09889485 0.14967553 0.18333629 0.16104247 0.17914303
  [51,] 0.19512559 0.27142915 0.38285017 0.46720660 0.52271277 0.50396347
  [52,] 0.16360785 0.19011843 0.26440740 0.29624388 0.30434820 0.31718978
  [53,] 0.16198112 0.13984253 0.17209323 0.42310601 0.23724513 0.17873633
  [54,] 0.09597179 0.07205392 0.11299895 0.11862161 0.11427364 0.15237758
  [55,] 0.13897826 0.14002044 0.17961663 0.18514098 0.21759714 0.23178431
  [56,] 0.17329192 0.15468636 0.19118132 0.39555272 0.23205988 0.17899053
  [57,] 0.11007852 0.08056880 0.10674638 0.29260907 0.15628932 0.12777266
  [58,] 0.11727168 0.10865519 0.14388047 0.35803548 0.23122109 0.17975307
  [59,] 0.16213363 0.13577572 0.16606943 0.39677274 0.25541887 0.20252787
  [60,] 0.17878212 0.13859706 0.16291772 0.41131201 0.21248816 0.16239238
  [61,] 0.14891651 0.14230803 0.19268093 0.22835191 0.24748851 0.27542755
  [62,] 0.14218086 0.13468276 0.18815672 0.21653244 0.23127194 0.24878915
  [63,] 0.13430142 0.13125138 0.17290658 0.26149720 0.25003028 0.25738055
  [64,] 0.13539438 0.13033636 0.19712889 0.29044852 0.29466400 0.31660518
  [65,] 0.13023463 0.13445400 0.17966747 0.32888082 0.29550281 0.28295133
  [66,] 0.12441401 0.11714465 0.16932280 0.24756806 0.25613058 0.25849897
  [67,] 0.15984605 0.15608433 0.22114785 0.32916039 0.27588022 0.26648030
  [68,] 0.16154903 0.11717007 0.13012993 0.35602742 0.17387846 0.13636403
  [69,] 0.11228985 0.10006406 0.12494488 0.33459991 0.22740841 0.18694644
  [70,] 0.12626949 0.11198489 0.14967553 0.26808050 0.22977228 0.19706292
  [71,] 0.12184684 0.10024198 0.12573281 0.37549773 0.20875172 0.16086729
  [72,] 0.12583739 0.10191954 0.12807116 0.36266160 0.21335237 0.16795899
  [73,] 0.18533984 0.17822301 0.19900973 0.47473034 0.29303727 0.21536411
  [74,] 0.15201746 0.12977718 0.15608059 0.30468270 0.21035306 0.18384542
  [75,] 0.58754689 0.50305927 0.51372182 0.88973302 0.84374005 1.00053525
  [76,] 0.65017569 0.66074973 0.83089924 1.22665107 1.43452680 1.43663681
  [77,] 0.33850589 0.34951183 0.38991606 0.62424010 0.61609793 0.76833904
  [78,] 0.12365148 0.10906187 0.13790751 0.32397512 0.20483738 0.16945866
  [79,] 0.13516563 0.10715555 0.13691625 0.37171045 0.20387150 0.15921509
  [80,] 0.11770378 0.10463922 0.13711958 0.34166616 0.24682765 0.20499343
  [81,] 0.10763844 0.08438143 0.10753432 0.37076998 0.19253515 0.14681096
  [82,] 0.14706104 0.11887304 0.13783126 0.37132919 0.20455779 0.15763915
  [83,] 0.11439950 0.09576850 0.12413154 0.35806090 0.21520786 0.16376497
  [84,] 0.11930509 0.08979537 0.11399020 0.35859463 0.19652575 0.14897153
  [85,] 0.12253311 0.10298707 0.13107036 0.33724341 0.20994636 0.16905196
  [86,] 0.11183233 0.08519480 0.11269394 0.27545178 0.17748781 0.14879359
  [87,] 0.12367690 0.09429427 0.12392822 0.21366020 0.11897594 0.12881482
  [88,] 0.10367330 0.08478811 0.11500689 0.28091669 0.15034156 0.14160022
  [89,] 0.10446125 0.08059422 0.10832224 0.22202279 0.12093312 0.12604423
  [90,] 0.12728620 0.10204662 0.13124827 0.26452199 0.17527644 0.15850338
  [91,] 0.07670530 0.05700673 0.10184093 0.13509259 0.11572246 0.12792517
  [92,] 0.07843369 0.06353904 0.10639055 0.18237041 0.13476042 0.13827042
  [93,] 0.08206840 0.06803795 0.10377261 0.18089615 0.12395784 0.13219544
  [94,] 0.11376406 0.10057241 0.15244599 0.22982617 0.21947806 0.21180555
  [95,] 0.09899648 0.08178885 0.12120862 0.19009753 0.15867861 0.17299181
  [96,] 0.09770019 0.08438143 0.13401872 0.22560674 0.17779282 0.16729811
  [97,] 0.07579027 0.05110987 0.09256377 0.19792633 0.12459329 0.12754390
  [98,] 0.10591005 0.09274381 0.12809658 0.21790501 0.14233494 0.14289655
  [99,] 0.09988609 0.08936327 0.13734832 0.31914565 0.19418731 0.15814753
 [100,] 0.08852445 0.07309604 0.10102759 0.17904063 0.13216780 0.15441102
 [101,] 0.09004951 0.06292903 0.10046842 0.16663656 0.11747629 0.13130581
 [102,] 0.09841187 0.08837198 0.12911326 0.20430629 0.17677610 0.18148151
 [103,] 0.11157816 0.12591371 0.17407575 0.32816908 0.26741609 0.23272480
 [104,] 0.09581929 0.10395294 0.15038720 0.34865615 0.28792828 0.23160641
 [105,] 0.11203567 0.11978807 0.16558652 0.32183999 0.25549513 0.22728528
 [106,] 0.15649094 0.17102985 0.25866321 0.37837005 0.39193806 0.34931850
 [107,] 0.08610979 0.06236984 0.10435720 0.10301483 0.08346723 0.12640007
 [108,] 0.11068854 0.10850269 0.15361516 0.15918903 0.14279246 0.16948406
 [109,] 0.12548155 0.10049617 0.12524989 0.30961385 0.16571933 0.13257672
 [110,] 0.07924705 0.06137855 0.11251602 0.22751309 0.32732594 0.27125892
 [111,] 0.10522377 0.08549980 0.12443656 0.19474904 0.18208842 0.17759253
 [112,] 0.10242785 0.09071040 0.13211246 0.18280253 0.15814483 0.16701850
 [113,] 0.10044528 0.08288179 0.12166610 0.16096829 0.14012359 0.15784252
 [114,] 0.05324491 0.03197045 0.05827636 0.22949573 0.09927713 0.09706736
 [115,] 0.05192320 0.02889493 0.05560759 0.19032629 0.08644112 0.09239040
 [116,] 0.05360076 0.03382593 0.05921679 0.23295259 0.10990179 0.10115971
 [117,] 0.05403286 0.03158919 0.05908971 0.24525499 0.10736000 0.10235438
 [118,] 0.05482080 0.03402928 0.05835262 0.24411118 0.10349648 0.09894831
 [119,] 0.05403286 0.03186878 0.05860678 0.24395867 0.10059886 0.09401717
 [120,] 0.04800890 0.01674534 0.04627959 0.06496382 0.02904765 0.06676877
 [121,] 0.04841559 0.01613532 0.04615251 0.05639789 0.02452328 0.06547242
 [122,] 0.05047441 0.02238804 0.05034629 0.12154470 0.05250832 0.07777487
 [123,] 0.05301616 0.02930161 0.05581092 0.20316248 0.09465108 0.09475429
 [124,] 0.05459205 0.03265673 0.05924221 0.20517051 0.09828583 0.09849078
 [125,] 0.05245697 0.02782739 0.05649718 0.18511556 0.08659363 0.09302586
 [126,] 0.05367702 0.03146210 0.05847970 0.23008035 0.10326773 0.10027008
 [127,] 0.05227905 0.02838658 0.05555676 0.19858722 0.08890665 0.09498306
 [128,] 0.05421078 0.03240255 0.05954721 0.23803625 0.10880881 0.10080384
 [129,] 0.05601543 0.03659645 0.06178389 0.27855280 0.12248360 0.10708217
 [130,] 0.04994064 0.02015129 0.04912628 0.08880607 0.04168032 0.07299624
 [131,] 0.04844100 0.01641491 0.04661001 0.05840593 0.02594668 0.06618414
 [132,] 0.04889852 0.01687243 0.04630500 0.06219324 0.02759884 0.06628581
 [133,] 0.05332117 0.03105542 0.05731052 0.24139144 0.08173882 0.08715423
 [134,] 0.05451579 0.03374968 0.05896262 0.23102081 0.09981090 0.09744864
 [135,] 0.05271115 0.03075041 0.05743761 0.23623154 0.10049719 0.09640648
 [136,] 0.05375327 0.03151293 0.05832720 0.23651116 0.10390317 0.10334568
 [137,] 0.05474455 0.03496972 0.06188557 0.27163908 0.12667754 0.10797182
 [138,] 0.05476997 0.03636769 0.06094513 0.24047638 0.11142685 0.10263397
 [139,] 0.05395661 0.03245339 0.05901346 0.22985159 0.10919008 0.10382863
 [140,] 0.05253322 0.02851367 0.05509925 0.18831825 0.08326389 0.08989941
 [141,] 0.05016939 0.02780198 0.05710719 0.23313053 0.08687323 0.08934020
 [142,] 0.04968646 0.02701403 0.05603968 0.21104212 0.08417894 0.08893352
 [143,] 0.05192320 0.02874242 0.05761553 0.18145534 0.07622316 0.08756092
 [144,] 0.04902561 0.02439602 0.05393007 0.17235565 0.08644112 0.09165327
 [145,] 0.04983897 0.02355725 0.05260840 0.19022465 0.08600902 0.09813493
 [146,] 0.05606626 0.03710480 0.06328350 0.29479501 0.12334782 0.10720927
 [147,] 0.05149111 0.03019123 0.05886095 0.19881597 0.08369599 0.08771344
 [148,] 0.04940687 0.02632776 0.05535342 0.19042797 0.08611069 0.09211080
 [149,] 0.05205029 0.03280923 0.05769177 0.25239751 0.11834050 0.10344736
 [150,] 0.04851726 0.02365891 0.05326923 0.16671281 0.06613228 0.08362109
 [151,] 0.04818683 0.02335390 0.05212548 0.15466458 0.06191291 0.08153679
 [152,] 0.05354993 0.03136043 0.05903887 0.20707689 0.09576946 0.09683859
 [153,] 0.04811057 0.02129508 0.05082922 0.13732938 0.06142997 0.08146054
 [154,] 0.05116068 0.02731904 0.05481967 0.18211621 0.08550067 0.09277167
 [155,] 0.04887310 0.02391309 0.05202381 0.17624463 0.08730532 0.09396634
 [156,] 0.05301616 0.03240255 0.05601426 0.26137012 0.10891049 0.10436241
 [157,] 0.05446496 0.03324133 0.05959805 0.22019267 0.09188054 0.09404259
 [158,] 0.05316867 0.03021664 0.05794595 0.20651768 0.09099092 0.09361047
 [159,] 0.05380410 0.03268214 0.05881012 0.21477859 0.09060965 0.09305128
 [160,] 0.05245697 0.02675986 0.05438758 0.15311408 0.06625936 0.08629001
 [161,] 0.04864434 0.01631324 0.04663542 0.06257451 0.02838679 0.06681960
 [162,] 0.05217738 0.02658193 0.05311674 0.14525986 0.06674231 0.08369735
 [163,] 0.05421078 0.03087750 0.05542967 0.20438254 0.08450937 0.09066195
 [164,] 0.04894935 0.01966836 0.04955837 0.09747367 0.04345956 0.07241162
 [165,] 0.05334659 0.02942870 0.05624301 0.18928415 0.08684781 0.09068737
 [166,] 0.04971188 0.02297264 0.05169339 0.13097484 0.06081995 0.08174013
 [ reached getOption("max.print") -- omitted 2070 rows ]
# Seleccionar la columna de las clases
Class <- roi@data$Class
print(Class)
   [1] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
   [8] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [15] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [22] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [29] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [36] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [43] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [50] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [57] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [64] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [71] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [78] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [85] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [92] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
  [99] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
 [106] "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial" "Artificial"
 [113] "Artificial" "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [120] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [127] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [134] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [141] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [148] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [155] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [162] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [169] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [176] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [183] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [190] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [197] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [204] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [211] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [218] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [225] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [232] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [239] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [246] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [253] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [260] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [267] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [274] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [281] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [288] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [295] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [302] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [309] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [316] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [323] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [330] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [337] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [344] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [351] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [358] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [365] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [372] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [379] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [386] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [393] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [400] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [407] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [414] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [421] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [428] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [435] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [442] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [449] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [456] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [463] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [470] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [477] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [484] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [491] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [498] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [505] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [512] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [519] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [526] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [533] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [540] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [547] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [554] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [561] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [568] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [575] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [582] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [589] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [596] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [603] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [610] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [617] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [624] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [631] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [638] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [645] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [652] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [659] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [666] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [673] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [680] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [687] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [694] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [701] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [708] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [715] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [722] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [729] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [736] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [743] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [750] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [757] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [764] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [771] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [778] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [785] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [792] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [799] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [806] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [813] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [820] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [827] "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"     "bosque"    
 [834] "bosque"     "bosque"     "bosque"     "bosque"     "represa"    "represa"    "represa"   
 [841] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [848] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [855] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [862] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [869] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [876] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [883] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [890] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [897] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [904] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [911] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [918] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [925] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [932] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [939] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [946] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [953] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [960] "represa"    "represa"    "represa"    "represa"    "represa"    "represa"    "represa"   
 [967] "represa"    "represa"    "represa"    "Agua"       "Agua"       "Agua"       "Agua"      
 [974] "Agua"       "Agua"       "Agua"       "Agua"       "pastos"     "pastos"     "pastos"    
 [981] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [988] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [995] "pastos"     "pastos"     "pastos"     "pastos"     "pastos"     "pastos"    
 [ reached getOption("max.print") -- omitted 1236 entries ]
# Crear un data frame con los datos reflectancia superficie y las clases
tabla <- data.frame(Extraer_R_Shp, Class)
summary(tabla$Class)
      Agua Artificial     bosque   cultivos    Desnudo     pastos    represa 
         8        113        724        747         23        489        132 
# Seperando los datos en Entrenamiento y prueba
Muestra <- sample(1:2235,1000) # sample separa aleatoriamente los datos
Pruebas <- tabla[Muestra,]
Entrenamiento <- tabla[-Muestra,]

# Aplicando el algoritmo DT
modelo <- rpart(Class ~.,data=Entrenamiento)

# Prediccion del modelo a obtener
prediccion <- predict(modelo, Pruebas[,-7],type="class")

# Definimos la paleta de colores segun las 7 clases
mycolor <- c("#00FF00","#0000FF","#228B22","#FF1493", "#1C1CE2", "#1C1CE2" ,"#5454AA")

## Visualizar prediccion a obtener
## Cantidad de punto que se encuentra en la clase
plot(prediccion, main = "Numero de pixeles identificados",
     axes = TRUE, xlab = "Clases", ylab = "Numero de pixel", col= mycolor)


# Determinacion del indice de kappa de la clasificacion
MC <- table(Pruebas[,7],prediccion)
kappa<-sum(diag(MC))/sum(MC)
print(kappa)
[1] 0.952
# Graficando el arbol de decision
prp(modelo, extra=104, branch.type =1, box.col = c("pink","palegreen3")[modelo$frame$yval])


# Ejecutamos el clasificador DT
beginCluster()
8 cores detected, using 7
## 8 cores detected, using 7
tc_class<- clusterR(L8_2015, raster::predict,args = list(model =modelo,type="class"))
endCluster()

# Ploteamos la clasificación con Support vector machine
plot(tc_class,main=paste("kappa = ",kappa,sep =""),col =mycolor,cex.lab=0.8,
     cex.axis=0.8,cex.main=0.9)


# Exportacion de bandas
writeRaster(tc_class,"Class_L8_Decision_Tree.tif", drivername="Gtiff",overwrite=TRUE)

Es importante y util un arbol de decicion:

Si la relacion entre la variable dependiente y la(s) independiente se aproxima a un modelo lineal, la regresion lineal dara mejores resultados que un modelo de arbol de decision

Si la relacion es compleja y altamento no lineal, entonces el arbol de decision tendra mejores resultados de que un metodo clasico de regresion.

Si se quiere construir un modelo que sea fácil de explicar, entonces un modelo de arbol de decision sera mejor que un modelo lineal.

Por otro lado, el indice de Kappa mide el grado de concordancia de las evaluaciones nominales u ordinales realizadas por multiples evaluadores cuando se evaluan las mismas muestras, los valores de kappa varian de –1 a +1. Mientras mas alto sea el valor de kappa, mas fuerte sera la concordancia. Cuando: Kappa = 1, existe concordancia perfecta, Kappa = 0, la concordancia es la misma que se esperaria en virtud de las probabilidades, y Kappa < 0, la concordancia es mas debil que lo esperado en virtud de las probabilidades; esto casi nunca sucede.

Para nuestro ejercicio el indice de kappa es de 0,952, lo que obedece a una concordancia perfecta.
LS0tDQp0aXRsZTogJyoqSW1hZ2VuIExhbmRTYXQgOCwgU2liYXRlIDIwMTUqKicNCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+PHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPkxhbmRzYXQgOCByZWNvcGlsYWRhIGVsIDA0IGRlIGVuZXJvIGRlIDIwMTUuIEVsIHN1YmNvbmp1bnRvIGN1YnJlIGVsIGFyZWEgZGUgU2liYXRlLCBkZXBhcnRhbWVudG8gZGUgQ3VuZGluYW1hcmNhLCBlbiBDb2xvbWJpYSA8L3NwYW4+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5TZWxlY2Npb25hciBsYSBjYXJwZXRhIGRlIGRlc3Rpbm8gPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgIkM6L1VzZXJzL0RhdmlkLVBDL0Rlc2t0b3AvRVNDUklUT1JJTy9MYW5kc2F0X3Byb2Nlc2FtaWVudG8iDQpnZXR3ZCgpDQpgYGANCiMNCiMNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPiBDcmVhciBvYmpldG9zIFJhc3RlckxheWVyIHBhcmEgY2FwYXMgaW5kaXZpZHVhbGVzIExhbmRzYXQgKGJhbmRhcykgeSBsYXMgbGxhbWFtb3MgZW5ydXRhbmRvbGFzIGNvbW8gcG9yIGVqZW1wbG8gKCcuL2RhdGEvTEMwOF9MMVRQXzAwODA1N18yMDE4MDMxN18yMDE4MDQwM18wMV9UMV9CMi50aWYnKTxkaXYvPg0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IEVuIGVzdGUgY2FwaXR1bG8gc2UgZGVzY3JpYmUgbGEgZm9ybWEgZGUgYWNjZWRlciB5IGV4cGxvcmFyLCBwb3Igc2F0ZWxpdGUsIGRhdG9zIGRlIHRlbGVkZXRlY2Npb24gY29uIFIgLiBUYW1iaWVuIG1vc3RyYW1vcyBjb21vIHVzYXJsb3MgcGFyYSBoYWNlciBtYXBhcy48ZGl2Lz4NCiMNCiMNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPiAgVXRpbGl6YXJlbW9zIHByaW5jaXBhbG1lbnRlIHVuIHN1YmNvbmp1bnRvIGVzcGFjaWFsIGRlIHVuYSBlc2NlbmEgTGFuZHNhdCA4IHJlY29waWxhZGEgZWwgMDQgZGUgZW5lcm8gZGUgMjAxNS4gRWwgc3ViY29uanVudG8gY3VicmUgZWwgYXJlYSBkZSBTaWJhdMOpLCBlbiBDdW5kaW5hbWFyY2EsIENvbG9tYmlhLjxkaXYvPg0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IFRvZGFzIGxhcyBlc2NlbmFzIGRlIGltYWdlbmVzIGRlIExhbmRzYXQgdGllbmVuIHVuYSBpZGVudGlmaWNhY2lvbiBkZSBwcm9kdWN0byB5IG1ldGFkYXRvcyB1bmljb3MuIFB1ZWRlIGVuY29udHJhciBsYSBpbmZvcm1hY2lvbiBzb2JyZSBlbCBzZW5zb3IgTGFuZHNhdCwgZWwgc2F0ZWxpdGUsIGxhIHViaWNhY2lvbiBlbiBsYSBUaWVycmEgKHJ1dGEgV1JTLCBmaWxhIFdSUykgeSBsYSBmZWNoYSBkZSBhZHF1aXNpY2lvbiBhIHBhcnRpciBkZSBsYSBJRCBkZWwgcHJvZHVjdG8uIFBvciBlamVtcGxvLCBlbCBpZGVudGlmaWNhZG9yIGRlIHByb2R1Y3RvIGRlIGxvcyBkYXRvcyBxdWUgdXRpbGl6YXJlbW9zIGVzICdMQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0Jy4gQ29uIGJhc2UgZW4gZXN0YSBndWlhICwgcHVlZGUgdmVyIHF1ZSBlbCBTZW5zb3ItU2F0ZWxpdGUgZXMgT0xJIC8gVElSUyBjb21iaW5hZG9zIExhbmRzYXQgOCwgV1JTIFBhdGggODAsIFdSUyBSb3cgNTcgeSByZWNvcGlsYWRvcyBlbCAwNCBkZSBlbmVybyBkZSAyMDE1LiBMYXMgZXNjZW5hcyBkZSBMYW5kc2F0IHNlIGVudHJlZ2FuIG1hcyBjb211bm1lbnRlIGNvbW8gdW4gYXJjaGl2byBjb21wcmltaWRvLCBxdWUgY29udGllbmUgYXJjaGl2b3Mgc2VwYXJhZG9zIHBhcmEgY2FkYSBiYW5kYTxkaXYvPg0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IENvbWVuemFyZW1vcyBleHBsb3JhbmRvIHkgdmlzdWFsaXphbmRvIGxvcyBkYXRvcyAoY29uc3VsdGUgbGFzIGluc3RydWNjaW9uZXMgZW4gZWwgQ2FwaXR1bG8gMSBwYXJhIG9idGVuZXIgaW5zdHJ1Y2Npb25lcyBkZSBkZXNjYXJnYSBkZSBkYXRvcyBzaSBhdW4gbm8gbG8gaGEgaGVjaG8pLjxkaXYvPg0KIw0KIw0KIw0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBDQVBJVFVMTyAxPC9zcGFuPg0KIw0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj5QUk9QSUVEQURFUyBERSBJTUFHRU48L3NwYW4+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5DcmVhciBvYmpldG9zIFJhc3RlckxheWVyIHBhcmEgY2FwYXMgaW5kaXZpZHVhbGVzIExhbmRzYXQgKGJhbmRhcyk8ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KbGlicmFyeShyYXN0ZXIpDQojIENvc3RlcmENCmIxID0gcmFzdGVyKCcuL2RhdGEyMDE1L0xDMDhfTDFUUF8wMDgwNTdfMjAxNTAxMDRfMjAxNzA0MTVfMDFfVDFfQjEudGlmJykNCiMgQXp1bA0KYjIgPSByYXN0ZXIoJy4vZGF0YTIwMTUvTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMV9CMi50aWYnKQ0KIyBWZXJkZQ0KYjMgPSByYXN0ZXIoJy4vZGF0YTIwMTUvTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMV9CMy50aWYnKQ0KIyBSb2pvDQpiNCA9IHJhc3RlcignLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I0LnRpZicpDQojIEluZnJhcm9qbyBjZXJjYW5vIChOSVIpDQpiNSA9IHJhc3RlcignLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I1LnRpZicpDQojIEluZnJhcnJvam8gZGUgT25kYSBDb3J0YSAxIChTV0lSIDEpDQpiNiA9IHJhc3RlcignLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I2LnRpZicpDQojIEluZnJhcnJvam8gZGUgT25kYSBDb3J0YSAyIChTV0lSIDIpDQpiNyA9IHJhc3RlcignLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I3LnRpZicpDQojIFBhbmNyb21hdGljYQ0KYjggPSByYXN0ZXIoJy4vZGF0YTIwMTUvTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMV9COC50aWYnKQ0KIyBDaXJyb3MgKENpcnJ1cykNCmI5ID0gcmFzdGVyKCcuL2RhdGEyMDE1L0xDMDhfTDFUUF8wMDgwNTdfMjAxNTAxMDRfMjAxNzA0MTVfMDFfVDFfQjkudGlmJykNCiMgU2Vuc29yIFTDqXJtaWNvIEluZnJhcnJvam8gMSAoVElSUyAxKQ0KYjEwID0gcmFzdGVyKCcuL2RhdGEyMDE1L0xDMDhfTDFUUF8wMDgwNTdfMjAxNTAxMDRfMjAxNzA0MTVfMDFfVDFfQjEwLnRpZicpDQojIFNlbnNvciBUw6lybWljbyBJbmZyYXJyb2pvIDIgKFRJUlMgMikNCmIxMSA9IHJhc3RlcignLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0IxMS50aWYnKQ0KYGBgDQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5zZSBpbnNlcnRhIHVuIG51ZXZvIGJsb3F1ZSBkZSBjb2RpZ28gY3RybCthbHQraSBwYXJhIGltcHJpbWlyIGxhcyB2YXJpYWJsZXMgYSB2ZXJpZmljYXIsIHBvciBlamVtcGxvIGNvbiBsYSBiYW5kYSBkb3MgKGIyKTo8ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KYjINCmBgYA0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IFB1ZWRlIHZlciBsYSByZXNvbHVjaW9uIGVzcGFjaWFsLCBsYSBleHRlbnNpb24sIGVsIG51bWVybyBkZSBjYXBhcywgZWwgc2lzdGVtYSBkZSByZWZlcmVuY2lhIGRlIGNvb3JkZW5hZGFzIHkgbWFzLjxkaXYvPg0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gSU5GT1JNQUNJT04gREUgSU1BR0VOIFkgRVNUQURJU1RJQ0FTIDwvc3Bhbj4NCiMNCiMgIA0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+QSBjb250aW51YWNpb24gc2UgbXVlc3RyYSBjb21vIHB1ZWRlIGFjY2VkZXIgYSB2YXJpYXMgcHJvcGllZGFkZXMgZGVzZGUgdW4gb2JqZXRvIFJhc3RlciAqIChlc3RvIGVzIGxvIG1pc21vIHBhcmEgY3VhbHF1aWVyIGNvbmp1bnRvIGRlIGRhdG9zIHJhc3RlcikuPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgU2lzdGVtYSBkZSBjb29yZGVuYWRhcyBkZSByZWZlcmVuY2lhIChDUlMpDQpjcnMoYjIpDQoNCiMgTnVtZXJvIGRlIGNlbGRhcywgZmlsYXMsIGNvbHVtbmFzDQpuY2VsbChiMikNCg0KIyBEaW1lbnNpb24NCmRpbShiMikNCg0KIyBSZXNvbHVjaW9uIGVzcGFjaWFsDQpyZXMoYjIpDQoNCiMgTnVtZXJvIGRlIGJhZGFzIA0KbmxheWVycyhiMikNCg0KIyDCv0xhcyBiYW5kYXMgdGllbmVuIGxhIG1pc21hIGV4dGVuc2lvbiwgbnVtZXJvIGRlIGZpbGFzIHkgY29sdW1uYXMsIHByb3llY2Npb24sIHJlc29sdWNpb24geSBvcmlnZW4/DQpjb21wYXJlUmFzdGVyKGIyLGIzKQ0KIyMgWzFdIFRSVUUNCmBgYA0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+IFB1ZWRlIGNyZWFyIHVuIFJhc3RlclN0YWNrICh1biBvYmpldG8gY29uIHZhcmlhcyBjYXBhcykgYSBwYXJ0aXIgZGUgbG9zIG9iamV0b3MgUmFzdGVyTGF5ZXIgKGJhbmRhIHVuaWNhKSBleGlzdGVudGVzIDxkaXYvPg0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+TGFzIGJhbmRhcyBxdWUgbGxhbW9zIHNvbiBsYXMgbWlzbWFzIHF1ZSBoZW1vcyBsbGFtYWRvZG8gYXJyaWJhIGNvbW8gUmFzdGVyTGF5ZXI8ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KIyBDcmVhbW9zIGVsIFJhc3RlclN0YWNrDQpzMjAxNSA9IHN0YWNrKGI1LCBiNCwgYjMpDQoNCiMgUmV2aXNhbW9zIGxhcyBwcm9waWVkYWRlcyBkZWwgUmFzdGVyU3RhY2sNCnMyMDE1DQpgYGANCiMNCiMNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPlRhbWJpZW4gcHVlZGUgY3JlYXIgZWwgUmFzdGVyU3RhY2sgdXNhbmRvIGxvcyBub21icmVzIGRlIGFyY2hpdm8uIFVuIFJhc3RlclN0YWNrIGVzIHVuYSBjb2xlY2Npb24gZGUgb2JqZXRvcyBSYXN0ZXJMYXllciBjb24gbGEgbWlzbWEgZXh0ZW5zaW9uIHkgcmVzb2x1Y2lvbiBlc3BhY2lhbC4gU2UgcHVlZGUgY3JlYXIgdW4gUmFzdGVyU3RhY2sgYSBwYXJ0aXIgZGUgb2JqZXRvcyBSYXN0ZXJMYXllciwgbyBkZSBhcmNoaXZvcyByYXN0ZXIsIG8gYW1ib3MuIFRhbWJpZW4gc2UgcHVlZGUgY3JlYXIgZGVzZGUgdW4gb2JqZXRvIFNwYXRpYWxQaXhlbHNEYXRhRnJhbWUgbyB1biBvYmpldG8gU3BhdGlhbEdyaWREYXRhRnJhbWUuDQogPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgUHJpbWVybyBjcmVhbW9zIHVuYSBsaXN0YSBkZSBsb3MgcmFzdGVyIGxheWVycyB1c2FuZG86DQoNCmZpbGVuYW1lcyA9IHBhc3RlMCgnLi9kYXRhMjAxNS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0InLCAxOjcsICIudGlmIikNCmZpbGVuYW1lcw0KDQojIyMjIyMgbm8gbGVlIGxhIGJhbmRhIDggcG9ycXVlIHRpZW5lIGRpZmVyZW50ZSBleHRlbnNpb24sIGxhIGJhbmRhIDkgZXMgY2lycm8sIHkgbGFzIGJhbmRhcyAxMCB5IDExIHNvbiB0ZXJtYWxlcw0KDQoNCiMgQ3JlbyBlbCBSYXN0ZXJTdGFjayBkZSBsYXMgYmFuZGFzIHNlbGVjY2lvbmFkYXMsIGVzIGRlY2lyICBkZSBsYSAxIGEgbGEgIDcgKDE6NykNCmxhbmRzYXQyMDE1PSBzdGFjayhmaWxlbmFtZXMpDQpsYW5kc2F0MjAxNQ0KDQpgYGANCiMNCiMNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPkFycmliYSBjcmVhbW9zIHVuIFJhc3RlclN0YWNrIGNvbiAxMSBjYXBhcy4gTGFzIGNhcGFzIHJlcHJlc2VudGFuIGxhIGludGVuc2lkYWQgZGUgbGEgcmVmbGV4aW9uIGVuIGxhcyBzaWd1aWVudGVzIGxvbmdpdHVkZXMgZGUgb25kYTogVWx0cmEgYXp1bCwgYXp1bCwgdmVyZGUsIHJvam8sIGluZnJhcnJvam8gY2VyY2FubyAoTklSKSwgaW5mcmFycm9qbyBkZSBvbmRhIGNvcnRhIChTV0lSKSAxLCBpbmZyYXJyb2pvIGRlIG9uZGEgY29ydGEgKFNXSVIpIDIsIHBhbmNyb21hdGljbywgY2lycm8sIGluZnJhcnJvam8gdGVybWljbyAoVElSUykgMSwgSW5mcmFycm9qbyB0ZXJtaWNvIChUSVJTKSAyLiBObyB1dGlsaXphcmVtb3MgbGFzIHVsdGltYXMgY3VhdHJvIGNhcGFzIHkgdmVyYSBjb21vIGVsaW1pbmFybGFzIGVuIGxhcyBzaWd1aWVudGVzIHNlY2Npb25lcy48ZGl2Lz4NCiMNCiMNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IEJBTkRBIFVOSUNBIFkgTUFQQVMgQ09NUFVFU1RPUyA8L3NwYW4+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5QdWVkZSB0cmF6YXIgY2FwYXMgaW5kaXZpZHVhbGVzIGRlIHVuIFJhc3RlclN0YWNrIGRlIHVuYSBpbWFnZW4gbXVsdGllc3BlY3RyYWwuPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgVHJhemFuZG8gY2FwYXMgaW5kaXZ1ZHVhbGVzIChhWlVMLCBWRVJERSwgUk9KTywgSU5GUkFST0pPIENFUkNBTk8pIGEgcGFydGlyIGRlbCBSYXN0ZXJTdGFjaw0KcGFyKG1mcm93ID0gYygyLDIpKQ0KcGxvdChiMiwgbWFpbiA9ICJBenVsIiwgY29sID0gZ3JheSgwOjEwMCAvIDEwMCksIGF4ZXMgPSBGQUxTRSkNCnBsb3QoYjMsIG1haW4gPSAiVmVyZGUiLCBjb2wgPSBncmF5KDA6MTAwIC8gMTAwKSwgYXhlcyA9IEZBTFNFKQ0KcGxvdChiNCwgbWFpbiA9ICJSb2pvIiwgY29sID0gZ3JheSgwOjEwMCAvIDEwMCksIGF4ZXMgPSBGQUxTRSkNCnBsb3QoYjUsIG1haW4gPSAiTklSIiwgY29sID0gZ3JheSgwOjEwMCAvIDEwMCksIGF4ZXMgPSBGQUxTRSkNCmBgYA0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+RWNoYSB1biB2aXN0YXpvIGEgbGFzIGxleWVuZGFzIGRlIGxvcyBtYXBhcyBjcmVhZG9zIGFudGVyaW9ybWVudGUuIFB1ZWRlbiB2YXJpYXIgZW50cmUgMCB5IDEuIE9ic2VydmUgbGEgZGlmZXJlbmNpYSBlbiBlbCBzb21icmVhZG8geSBlbCByYW5nbyBkZSBsZXllbmRhcyBlbnRyZSBsYXMgZGlmZXJlbnRlcyBiYW5kYXMuIEVzdG8gc2UgZGViZSBhIHF1ZSBsYXMgZGlmZXJlbnRlcyBjYXJhY3RlcmlzdGljYXMgZGUgbGEgc3VwZXJmaWNpZSByZWZsZWphbiBsYSByYWRpYWNpb24gc29sYXIgaW5jaWRlbnRlIGRlIG1hbmVyYSBkaWZlcmVudGUuIENhZGEgY2FwYSByZXByZXNlbnRhIGxhIGNhbnRpZGFkIGRlIHJhZGlhY2lvbiBzb2xhciBpbmNpZGVudGUgcXVlIHNlIHJlZmxlamEgcGFyYSB1biByYW5nbyBkZSBsb25naXR1ZCBkZSBvbmRhIHBhcnRpY3VsYXIuIFBvciBlamVtcGxvLCBsYSB2ZWdldGFjaW9uIHJlZmxlamEgbWFzIGVuZXJnaWEgZW4gTklSIHF1ZSBvdHJhcyBsb25naXR1ZGVzIGRlIG9uZGEgeSwgcG9yIGxvIHRhbnRvLCBwYXJlY2UgbWFzIGJyaWxsYW50ZS4gUG9yIGVsIGNvbnRyYXJpbywgZWwgYWd1YSBhYnNvcmJlIGxhIG1heW9yIHBhcnRlIGRlIGxhIGVuZXJnaWEgZW4gbGEgbG9uZ2l0dWQgZGUgb25kYSBOSVIgeSBwYXJlY2Ugb3NjdXJhLjxkaXYvPg0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+Tm8gb2J0ZW5lbW9zIHRhbnRhIGluZm9ybWFjaW9uIGRlIGVzdGFzIHBhcmNlbGFzIGVuIGVzY2FsYSBkZSBncmlzZXM7IGEgbWVudWRvIHNlIGNvbWJpbmFuIGVuIHVuICJjb21wdWVzdG8iIHBhcmEgY3JlYXIgdHJhbWFzIG1hcyBpbnRlcmVzYW50ZXMuPGRpdi8+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5QYXJhIGhhY2VyIHVuYSBpbWFnZW4gZGUgImNvbG9yIHZlcmRhZGVybyAobyBuYXR1cmFsKSIsIGVzIGRlY2lyLCBhbGdvIHF1ZSBzZSBwYXJlY2UgYSB1bmEgZm90b2dyYWZpYSBub3JtYWwgKHZlZ2V0YWNpb24gZW4gdmVyZGUsIGF6dWwgYWd1YSwgZXRjLiksIG5lY2VzaXRhbW9zIGJhbmRhcyBlbiBsYXMgcmVnaW9uZXMgcm9qYSwgdmVyZGUgeSBhenVsLiBQYXJhIGVzdGEgaW1hZ2VuIExhbmRzYXQsIHNlIHB1ZWRlbiB1c2FyIGxhcyBiYW5kYXMgNCAocm9qbyksIDMgKHZlcmRlKSB5IDIgKGF6dWwpLiBFbCBtZXRvZG8gLSBwbG90UkdCIC0gIHNlIHB1ZWRlIHV0aWxpemFyIHBhcmEgY29tYmluYXJsb3MgZW4gdW4gc29sbyBjb21wdWVzdG8uIFRhbWJpZW4gcHVlZGUgcHJvcG9yY2lvbmFyIGFyZ3VtZW50b3MgYWRpY2lvbmFsZXMgLSBwbG90UkdCIC0gcGFyYSBtZWpvcmFyIGxhIHZpc3VhbGl6YWNpb24gKHBvciBlamVtcGxvLCB1biBlc3RpcmFtaWVudG8gbGluZWFsIGRlIGxvcyB2YWxvcmVzLCB1dGlsaXphbmRvICkuLSBzdHJlY3RoID0gImxpbiIgLS48ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KIyBQbG90ZWFtb3MgbGEgY29tYmluYWNpb24gZGUgYmFuZGFzIDQsIDMgeSAyIHF1ZSBwYXJhIEw4IGVzIGNvbG9yIHZlcmRhZGVybw0KbGFuZHNhdFJHQjIwMTUgPSBzdGFjayhiNCwgYjMsIGIyKQ0KcGxvdFJHQihsYW5kc2F0UkdCMjAxNSwgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJDb21wb3NpY2lvbiBkZSBjb2xvciB2ZXJkYWRlcm8gLSBMYW5kc2F0IDgiKQ0KYGBgDQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5FbCBjb21wdWVzdG8gZGUgY29sb3IgdmVyZGFkZXJvIHJldmVsYSBtdWNobyBtYXMgc29icmUgZWwgcGFpc2FqZSBxdWUgbGFzIGltYWdlbmVzIGdyaXNlcyBhbnRlcmlvcmVzLiBPdHJvIG1ldG9kbyBwb3B1bGFyIGRlIHZpc3VhbGl6YWNpb24gZGUgaW1hZ2VuZXMgZW4gbGEgdGVsZWRldGVjY2lvbiBlcyBsYSBpbWFnZW4gY29ub2NpZGEgY29tbyAiY29sb3IgZmFsc28iIGVuIGxhIHF1ZSBzZSBjb21iaW5hbiBsYXMgYmFuZGFzIE5JUiwgcm9qbyB5IHZlcmRlLiBFc3RhIHJlcHJlc2VudGFjaW9uIGVzIHBvcHVsYXIgeWEgcXVlIGhhY2UgcXVlIHNlYSBmYWNpbCB2ZXIgbGEgdmVnZXRhY2lvbiAoZW4gcm9qbykuPGRpdi8+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij4gRWwgbWF4aW1vIGRlIGJhbmRhcyBxdWUgcG9kZW1vcyBlbXBsZWFyIHBvciBjb21wb3NpY2lvbiBlcyBkZSB0cmVzIHkgbGEgYXBhcmllbmNpYSBkZXBlbmRlcmEgZGUgbGFzIGJhbmRhcyBlc3BlY3RyYWxlcyBxdWUgYXNpZ25lbW9zIGEgbG9zIGNhbmFsZXMgcm9qbywgdmVyZGUgeSBhenVsIGRlbCBtb25pdG9yLiBFbCBwcm9jZXNvIHBlcm1pdGUgdmlzdWFsaXphciwgc2ltdWx0w6FuZWFtZW50ZSwgaW5mb3JtYWNpb24gZGUgZGlzdGludGFzIHJlZ2lvbmVzIGRlbCBlc3BlY3RybywgbG8gcXVlIGZhY2lsaXRhIGxhIGRlbGltaXRhY2lvbiB2aXN1YWwgZGUgYWxndW5hcyBjdWJpZXJ0YXMgPGRpdi8+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij4gTGEgZWxlY2Npb24gZGUgbGFzIGJhbmRhcyBwYXJhIHJlYWxpemFyIGxhIGNvbXBvc2ljaW9uLCB5IGVsIG9yZGVuIGRlIGxvcyBjb2xvcmVzIGRlc3RpbmFkb3MgYSBjYWRhIHVuYSwgZGVwZW5kZW4gZGVsIHNlbnNvciBzb2JyZSBlbCBxdWUgc2UgdHJhYmFqZSB5IGRlIGxhIGFwbGljYWNpb24gdWx0aW1hIGRlbCBwcm95ZWN0by4gTGEgY29tcG9zaWNpb24gbWFzIGhhYml0dWFsIGVzIGxhIGRlbm9taW5hZGEgZmFsc28gY29sb3IgbyBpbmZyYXJyb2pvIGNvbG9yLCBmcnV0byBkZSBhcGxpY2FyIGxhcyBiYWxhcyBkZSByb2pvLCB2ZXJkZSB5IGF6dWwgc29icmUgbGFzIGJhbmRhcyBjb3JyZXNwb25kaWVudGVzIGFsIGluZnJhcnJvam8gY2VyY2FubywgZWwgcm9qbyB5IGVsIHZlcmRlIHJlc3BlY3RpdmFtZW50ZSA8ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KIyBQbG90ZWFtb3MgbGEgY29tYmluYWNpb24gZGUgYmFuZGFzIDUsIDQgeSAzIHF1ZSBwYXJhIEw4IGVzIGNvbG9yIGZhbHNvDQpwYXIobWZyb3cgPSBjKDEsMikpDQpwbG90UkdCKGxhbmRzYXRSR0IyMDE1LCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IkNvbXBvc2ljaW9uIGRlIGNvbG9yIHZlcmRhZGVybyIpDQpsYW5kc2F0RkNDMjAxNSA9IHN0YWNrKGI1LCBiNCwgYjMpDQpwbG90UkdCKGxhbmRzYXRGQ0MyMDE1LCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IkNvbXBvc2ljaW9uIGRlIGNvbG9yIGZhbHNvIikNCmBgYA0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+Tm90YSA6IENvbXBydWViZSBzaWVtcHJlIGxhIGRvY3VtZW50YWNpb24gZGVsIHBhcXVldGUgKC0gaGVscChwbG90UkdCKSAtKSBwYXJhIHZlciBvdHJvcyBhcmd1bWVudG9zIHF1ZSBzZSBwdWVkZW4gYWdyZWdhciAoY29tbyBsYSBlc2NhbGEpIHBhcmEgbWVqb3JhciBvIG1vZGlmaWNhciBsYSBpbWFnZW4uPGRpdi8+DQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5QcmVndW50YSAxIDogVXNlIGxhIGZ1bmNpb24gcGxvdFJHQiBjb24gUmFzdGVyU3RhY2sgYGAgbGFuZHNhdCAnJyBwYXJhIGNyZWFyIHVuIGNvbXB1ZXN0byBkZSBjb2xvciB2ZXJkYWRlcm8geSBmYWxzbyAocmVjdWVyZGUgbGEgcG9zaWNpb24gZGUgbGFzIGJhbmRhcyBlbiBsYSBwaWxhKS48ZGl2Lz4NCiMNCiMNCmBgYHtyfQ0KIyMgc29sdWNpb24gYSBsYSBwcmVndW50YSAxLCBwbG90ZWFtb3MgbGEgY29tYmluYWNpb24gZGUgYmFuZGFzIDUsIDYgeSA0IHF1ZSBwYXJhIEw4IGVzIGNvbG9yIGZhbHNvDQpsYW5kc2F0RkNDMjAxNV9wMSA9IHN0YWNrKGI1LCBiNiwgYjQpDQpwbG90UkdCKGxhbmRzYXRGQ0MyMDE1X3AxLCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IkNvbXBvc2ljaW9uIGRlIGNvbG9yIGZhbHNhIC0gQWd1YSAvIFRpZXJyYSIpDQpgYGANCiMNCiMNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IFNVQkNPTkpVTlRPIFkgUkVOT01CUkFSIEJBTkRBUzwvc3Bhbj4NCiMNCiMNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGp1c3RpZnkiPlB1ZWRlIHNlbGVjY2lvbmFyIGNhcGFzIChiYW5kYXMpIGVzcGVjaWZpY2FzIG1lZGlhbnRlIGxhIGZ1bmNpb24gLSBzdWJzZXQgLSBvIG1lZGlhbnRlIGluZGV4YWNpb24uPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgU2VsZWNjaW9uYW1vcyB1bmljYW1lbnRlIGxhcyAzIHByaW1lcmFzIGJhbmRhcw0KbGFuZHNhdDIwMTVzdWIwMSA9IHN1YnNldChsYW5kc2F0MjAxNSwgMTozKQ0KIyBNaXNtbw0KbGFuZHNhdDIwMTVzdWIwMiA9IGxhbmRzYXQyMDE1W1sxOjNdXQ0KDQojIE51bWVybyBkZSBiYW5kYXMgZW4gbG9zIGRhdG9zIG9yaWdpbmFsZXMgeSBudWV2b3MuDQpubGF5ZXJzKGxhbmRzYXQyMDE1KQ0KbmxheWVycyhsYW5kc2F0MjAxNXN1YjAxKQ0KbmxheWVycyhsYW5kc2F0MjAxNXN1YjAyKQ0KYGBgDQojDQojDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBqdXN0aWZ5Ij5ObyB1c2FyZW1vcyBsYXMgdWx0aW1hcyBjdWF0cm8gYmFuZGFzIC0gbGFuZHNhdCAtLiBQdWVkZXMgZWxpbWluYXIgYXF1ZWxsb3MgdXNhbmRvOjxkaXYvPg0KIw0KIw0KYGBge3J9DQojIyBFbGltaW5hbmRvIGxhcyB1bHRpbWFzIGN1YXRybyBiYW5kYXMsIGVzIGRlY2lyLCBzZWxlY2Npb25hcmVtb3MgcGFyYSBudWVzdHJvIGVqZXJjaWNpbyBsYXMgYmFuZGFzIGRlIDEgYSBsYSA3ICgxOjcpDQpsYW5kc2F0MjAxNSA9IHN1YnNldChsYW5kc2F0MjAxNSwgMTo3KQ0KcGxvdChsYW5kc2F0MjAxNSkNCmBgYA0KIw0KIw0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjoganVzdGlmeSI+UGFyYSBtYXlvciBjbGFyaWRhZCwgZXMgdXRpbCBlc3RhYmxlY2VyIGxvcyBub21icmVzIGRlIGxhcyBiYW5kYXMuPGRpdi8+DQojDQojDQpgYGB7cn0NCiMgQWNhIHZlbW9zIHF1ZSBub21icmVzIHRpZW5lbiBsYXMgYmFuZGFzDQpuYW1lcyhsYW5kc2F0MjAxNSkNCg0KIyBBY2EgbGFzIHJlbm9tYnJhbW9zIHkgbGFzIHBsb3RlYW1vcw0KbmFtZXMobGFuZHNhdDIwMTUpID0gYygndWx0cmEtYXp1bCcsICdhenVsJywgJ3ZlcmRlJywgJ3Jvam8nLCAnTklSJywgJ1NXSVIxJywgJ1NXSVIyJykNCm5hbWVzKGxhbmRzYXQyMDE1KQ0KYGBgDQojDQojDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBTVUJDT05KVU5UTyBFU1BBQ0lBTCBPIFJFQ09SVEUgPC9zcGFuPg0KIw0KIw0KIyMjIyMgRWwgc3ViY29uanVudG8gZXNwYWNpYWwgc2UgcHVlZGUgdXNhciBwYXJhIGxpbWl0YXIgZWwgYW5hbGlzaXMgYSB1biBzdWJjb25qdW50byBnZW9ncmFmaWNvIGRlIGxhIGltYWdlbi4gTG9zIHN1YmNvbmp1bnRvcyBlc3BhY2lhbGVzIHNlIHB1ZWRlbiBjcmVhciBjb24gbGEgZnVuY2lvbiAtIGNyb3AgLSwgdXRpbGl6YW5kbyB1biBvYmpldG8gLSBleHRlbnQgLSAgdSBvdHJvIG9iamV0byBlc3BhY2lhbCBkZWwgcXVlIHNlIHB1ZWRlIGV4dHJhZXIgdW5hIEV4dGVuc2lvbi4NCiMNCiMNCmBgYHtyfQ0KIyBVc2FuZG8gbGEgaGVycmFtaWVudGEgRXh0ZW5zaW9uDQpleHRlbnQobGFuZHNhdDIwMTUpDQoNCiMgQ2FyZ2Ftb3MgdW4gb2JqZXRvIGVzcGFjaWFsIHF1ZSBzZSBlbmN1ZW50cmEgZW4gdW4gc2hhcGVmaWxlLiBFc3RhIGV4dGVuc2lvbiBlcyBlbCBhcmVhIGRlIFNpYmF0ZQ0Kc2liYXRlMjAxNSA9IHNoYXBlZmlsZSgnQzovVXNlcnMvRGF2aWQtUEMvRGVza3RvcC9FU0NSSVRPUklPL1NJQkFURV9SVVJBTC9ydXJhbC5zaHAnKQ0KDQojIERlZmluZSBxdWUgbGEgZXh0ZW5zaW9uIGVzIFNpYmF0ZQ0KZSA9IGV4dGVudChzaWJhdGUyMDE1KQ0KDQojIENvcnRhIGxhIGltYWdlbiBsYW5kc2F0IGNvbiBlbCBhcmVhIGRlIHNpYmF0ZQ0KbGFuZHNhdGNyb3AyMDE1ID0gY3JvcChsYW5kc2F0MjAxNSwgZSkNCg0KIyBQbG90ZWEgYSBTaWJhdGUNCnBsb3RSR0IobGFuZHNhdGNyb3AyMDE1LCByPSA2LCBnPSA1LCBiPTIsIGF4ZXMgPSBUUlVFLCBzdHJldGNoID0gImxpbiIsIG1haW4gPSAiQ29tcG9zaWNpb24gZGUgY29sb3IgZmFsc2EgLSBTaWJhdMOpIikNCmBgYA0KIw0KIw0KIyMjIyMgUHJlZ3VudGEgMiA6IFRhbWJpZW4gZXMgcG9zaWJsZSBsYSBzZWxlY2Npb24gaW50ZXJhY3RpdmEgZGUgbGEgaW1hZ2VuLiBVc2UgIC1kcmF3RXh0ZW50LSB5IC1kcmF3UG9seS0gcGFyYSBzZWxlY2Npb25hciB1biBhcmVhIGRlIGludGVyZXMNCiMNCiMNCiMjIyMjIHNlIGRhIHJlc3B1ZXN0YSBhIGVzdGEgcHJlZ3VudGEgY29uIGVsIGVqZXJjaWNpbyBhbnRlcmlvcg0KIw0KIw0KIyMjIyMgUHJlZ3VudGEgMyA6IFVzZSBlbCAtTGFuZHNhdGNyb3AtIGRlIFJhc3RlclN0YWNrIHBhcmEgY3JlYXIgdW4gY29tcHVlc3RvIGRlIGNvbG9yIHZlcmRhZGVybyB5IGZhbHNvDQojDQojDQpgYGB7cn0NCiMgQ3JlYWNpb24gZGUgdW4gY29tcHVlc3RvIGRlIGNvbG9yIHZlcmRhZGVybywgcGFyYSBsYW5kc2F0IDggbGEgY29tYmluYWNpb24gZGUgY29sb3IgZXMgNCwzLDINCmxhbmRzYXRjcm9wMjAxNXByZWd1bnRhID0gY3JvcChzdGFjayhiNCwgYjMsIGIyKSwgZSkNCg0KIyBQbG90ZWFtb3MgbGEgY29tYmluYWNpb24NCnBsb3RSR0IobGFuZHNhdGNyb3AyMDE1cHJlZ3VudGEsIGF4ZXMgPSBUUlVFLCBzdHJldGNoID0gImxpbiIsIG1haW4gPSAiU2liYXTDqSAyMDE1IC0gQ29sb3IgVmVyZGFkZXJvIikNCmBgYA0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gR1VBUkRBTkRPIFJFU1VMVEFET1MgRU4gRUwgRElTQ08gPHNwYW4vID4NCiMNCiMNCiMjIyMjIEVuIGVzdGEgZXRhcGEsIGVzIHBvc2libGUgcXVlIHF1ZXJhbW9zIGd1YXJkYXIgZWwgcmFzdGVyIGVuIGVsIGRpc2NvIHVzYW5kbyBsYSBmdW5jaW9uIC0gd3JpdGVSYXN0ZXIgLS4gU2UgYWRtaXRlbiBtdWx0aXBsZXMgdGlwb3MgZGUgYXJjaGl2b3MuIFV0aWxpemFyZW1vcyBlbCBmb3JtYXRvIEdlb1RpZmYgZGUgdXNvIGNvbXVuLiBNaWVudHJhcyBzZSBjb25zZXJ2YSBlbCBvcmRlbiBkZSBsYXMgY2FwYXMsIGxvcyBub21icmVzIGRlIGxhcyBjYXBhcyBzZSBwaWVyZGVuIGRlc2Fmb3J0dW5hZGFtZW50ZSBlbiBlbCBmb3JtYXRvIEdlb1RpZmYNCiMNCiMNCmBgYHtyfQ0KIyBBY2EgZ3VhcmRhbm1vcyBudWVzdHJvIHJhc3RlciBkZSBTaWJhdGUgeSBsbyBpbXByaW1pbW9zIHBhcmEgdmVyIGxvIHF1ZSBzZSBoYSBndWFyZGFkbw0KeCA9IHdyaXRlUmFzdGVyKGxhbmRzYXRjcm9wMjAxNSwgZmlsZW5hbWU9IlNpYmF0w6lfYmFuZGEudGlmIiwgb3ZlcndyaXRlPVRSVUUpDQpwbG90KHgpDQoNCmBgYA0KIw0KIw0KIyMjIyMgQWx0ZXJuYXRpdmFtZW50ZSwgcHVlZGUgdXRpbGl6YXIgZWwgZm9ybWF0byAncmFzdGVyLWdyZCcuDQojDQojDQpgYGB7cn0NCiMgTG8gZ3VhcmRhbW9zIHRhbWJpZW4gZW4gZm9ybWF0byAuZ3JkIHlhIHF1ZSBlc3RlIGZvcm1hdG8gc2kgZ3VhcmRhIGxvcyBub21icmVzIGRlIGxhcyBjYXBhcw0Kd3JpdGVSYXN0ZXIobGFuZHNhdGNyb3AyMDE1LCBmaWxlbmFtZT0iU2liYXRlX2JhbmRhLmdyZCIsIG92ZXJ3cml0ZT1UUlVFKQ0KDQpgYGANCiMNCiMNCiMjIyMjIFVuYSB2ZW50YWphIGRlIGVzdGUgZm9ybWF0byBlcyBxdWUgZ3VhcmRhIGxvcyBub21icmVzIGRlIGxhcyBjYXBhcy4gTGEgZGVzdmVudGFqYSBkZSBlc3RlIGZvcm1hdG8gZXMgcXVlIG5vIG11Y2hvcyBvdHJvcyBwcm9ncmFtYXMgcHVlZGVuIGxlZXIgbG9zIGRhdG9zLCBlbiBjb250cmFzdGUgY29uIGVsIGZvcm1hdG8gR2VvVGlmZi4NCiMNCiMNCiMjIyMjIE5vdGE6IENvbnN1bHRlIGxhIGRvY3VtZW50YWNpb24gZGVsIHBhcXVldGUgKC0gaGVscCh3cml0ZVJhc3RlcikgLSkgcGFyYSB2ZXIgYXJndW1lbnRvcyB1dGlsZXMgYWRpY2lvbmFsZXMgcXVlIHNlIHB1ZWRlbiBhZ3JlZ2FyDQojDQojDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBSRUxBQ0lPTiBFTlRSRSBCQU5EQVMgPHNwYW4vPg0KIw0KIw0KIyMjIyMgVW5hIG1hdHJpeiBkZSBkaWFncmFtYSBkZSBkaXNwZXJzaW9uIHB1ZWRlIHNlciB1dGlsIHBhcmEgZXhwbG9yYXIgbGFzIHJlbGFjaW9uZXMgZW50cmUgY2FwYXMgcmFzdGVyLiBFc3RvIHNlIHB1ZWRlIGhhY2VyIGNvbiBsYSBmdW5jaW9uIHBhcmVzICgpIGRlbCBwYXF1ZXRlIHJhc3Rlci4NCiMNCiMNCiMjIyMjIFRyYXphZG8gZGUgcmVmbGVqbyBlbiBsYSBsb25naXR1ZCBkZSBvbmRhIHVsdHJhIGF6dWwgY29udHJhIGVsIHJlZmxlam8gZW4gbGEgbG9uZ2l0dWQgZGUgb25kYSBhenVsLg0KIw0KIw0KIyMjIyMgQSBjb250aW51YWNpb24gcG9kZW1vcyB2ZXIgY29tbyBsYXMgYmFuZGFzIGRlbCB1bHRyYSBhenVsIHkgZWwgYXp1bCBlc3RhbiBjYXNpIHBlcmZlY3RhbWVudGUgY29ycmVsYWNpb25hZGFzIGVudHJlIHNpLiBVbmEgY29ycmVsYWNpb24gcG9zaXRpdmEgaW5kaWNhIHVuYSByZWxhY2nDs24gZGlyZWN0YSBlbnRyZSBkb3MgYmFuZGFzLCB0YWwgY29tbyBjdWFuZG8gbG9zIHZhbG9yZXMgZGUgY2VsZGEgZGUgdW5hIGNhcGEgYXVtZW50YW4sIGVzIHByb2JhYmxlIHF1ZSBsb3MgdmFsb3JlcyBkZSBjZWxkYSBkZSBvdHJhIGNhcGEgdGFtYmllbiBhdW1lbnRlbi4gVW5hIGNvcnJlbGFjaW9uIG5lZ2F0aXZhIHNpZ25pZmljYSBxdWUgdW5hIHZhcmlhYmxlIGNhbWJpYSBkZSBtYW5lcmEgaW52ZXJzYSBhIGxhIG90cmEuIFVuYSBjb3JyZWxhY2nDs24gZGUgY2VybyBzaWduaWZpY2EgcXVlIGxhcyBiYW5kYXMgc29uIGluZGVwZW5kaWVudGVzIGVudHJlIHNpLiANCiMNCiMNCmBgYHtyfQ0KIyBDb21wYXJhY2lvbiBkZWwgcmVmbGVqbyBlbiBsYSBsb25naXR1ZCBkZSBvbmRhIFVsdGEgYXp1bCB2cyBhenVsDQpwYWlycyhsYW5kc2F0Y3JvcDIwMTVbWzE6Ml1dLCBtYWluID0gIlVsdHJhLUF6dWwgdmVyc3VzIEF6dWwiKQ0KYGBgDQojDQojDQojIyMjIyBUcmF6YWRvIGRlIHJlZmxlam8gZW4gbGEgbG9uZ2l0dWQgZGUgb25kYSByb2phIGNvbnRyYSByZWZsZWpvIGVuIGxhIGxvbmdpdHVkIGRlIG9uZGEgTklSLg0KIw0KIw0KIyMjIyMgQSBkaWZlcmVuY2lhIGRlIGxhcyBiYW5kYXMgYW50ZXJpb3JlcywgbGEgc2lndWllbnRlIGVzIHVuYSBjb3JyZWxhY2lvbiBiYWphIGVuIHBvc2l0aXZvLCBsbyBxdWUgaW5maXJlIHF1ZSBzb24gbWFzIGluZGVwZW5kaWVudGVzIHVuYSBkZSBsYSBvdHJhLg0KIw0KIw0KYGBge3J9DQojIENvbXBhcmFjaW9uIGRlbCByZWZsZWpvIGVuIGxhIGxvbmdpdHVkIGRlIG9uZGEgUm9qYSB2cyBOSVINCnBhaXJzKGxhbmRzYXRjcm9wMjAxNVtbNDo1XV0sIG1haW4gPSAiUm9qYSB2ZXJzdXMgTklSIikNCmBgYA0KIw0KIw0KIyMjIyMgTGEgcHJpbWVyYSBncmFmaWNhIHJldmVsYSBhbHRhcyBjb3JyZWxhY2lvbmVzIGVudHJlIGxhcyByZWdpb25lcyBkZSBsb25naXR1ZCBkZSBvbmRhIGF6dWwuIERlYmlkbyBhIGxhIGFsdGEgY29ycmVsYWNpb24sIHBvZGVtb3MgdXNhciB1bmEgZGUgbGFzIGJhbmRhcyBhenVsZXMgc2luIHBlcmRlciBtdWNoYSBpbmZvcm1hY2lvbi4NCiMNCiMNCiMjIyMjIEVzdGEgZGlzdHJpYnVjaW9uIGRlIHB1bnRvcyBlbiBsYSBzZWd1bmRhIGdyYWZpY2EgKGVudHJlIE5JUiB5IHJvam8pIGVzIHVuaWNhIGRlYmlkbyBhIHN1IGZvcm1hIHRyaWFuZ3VsYXIuIExhIHZlZ2V0YWNpb24gc2UgcmVmbGVqYSBtdXkgYmllbiBlbiBlbCByYW5nbyBOSVIgcXVlIGVuIGVsIHJvam8geSBjcmVhIGxhIGVzcXVpbmEgc3VwZXJpb3IgY2VyY2EgZGVsIGVqZSBOSVIgKHkpLiBFbCBhZ3VhIGFic29yYmUgZW5lcmdpYSBkZSB0b2RhcyBsYXMgYmFuZGFzIHkgb2N1cGEgZWwgbHVnYXIgY2VyY2FubyBhbCBvcmlnZW4uIEVsIHJpbmNvbiBtYXMgYWxlamFkbyBzZSBjcmVhIGRlYmlkbyBhIGxhcyBjYXJhY3RlcmlzdGljYXMgc3VwZXJmaWNpYWxlcyBhbHRhbWVudGUgcmVmbGVjdGFudGVzLCBjb21vIGVsIHN1ZWxvIGJyaWxsYW50ZSBvIGVsIGhvcm1pZ29uLg0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gRVhUUkFFUiBWQUxPUkVTIERFIFBJWEVMRVMgPHNwYW4vPg0KIw0KIw0KIyMjIyMgQSBtZW51ZG8sIHF1ZXJlbW9zIG9idGVuZXIgbG9zIHZhbG9yZXMgZGUgbGFzIGNlbGRhcyByYXN0ZXIgcGFyYSB1YmljYWNpb25lcyBnZW9ncmFmaWNhcyBvIGFyZWFzIGVzcGVjaWZpY2FzLiBMYSBmdW5jaW9uIC0gZXh0cmFjdCAtIHNlIHV0aWxpemEgcGFyYSBvYnRlbmVyIHZhbG9yZXMgcmFzdGVyIGVuIGxhcyB1YmljYWNpb25lcyBkZSBvdHJvcyBkYXRvcyBlc3BhY2lhbGVzLiBQdWVkZSB1c2FyIHB1bnRvcywgbGluZWFzLCBwb2xpZ29ub3MgbyB1biBvYmpldG8gZGUgZXh0ZW5zaW9uIChyZWN0YW5ndWxvKS4gVGFtYmllbiBwdWVkZSB1c2FyIG51bWVyb3MgZGUgY2VsZGEgcGFyYSBleHRyYWVyIHZhbG9yZXMuIEFsIHVzYXIgcHVudG9zLCAtIGV4dHJhY3QgLSBkZXZ1ZWx2ZSBsb3MgdmFsb3JlcyBkZSB1biBvYmpldG8gLSBSYXN0ZXIqIC0gIHBhcmEgbGFzIGNlbGRhcyBlbiBsYXMgcXVlIHNlIHViaWNhIHVuIGNvbmp1bnRvIGRlIHB1bnRvcy4NCiMNCiMNCmBgYHtyfQ0KIyBDYXJnYXIgbG9zIHBvbGlnb25vcyBjb24gaW5mb3JtYWNpb24gc29icmUgZWwgdXNvIGRlbCBzdWVsbw0Kc2liYXRlY29iZXJ0ID0gc2hhcGVmaWxlICgnQzovVXNlcnMvRGF2aWQtUEMvRGVza3RvcC9FU0NSSVRPUklPL1BFUkNFUENJT04gUkVNT1RBL1RSQUJBSk9fQ09CRVJUVVJBUy9jb2JlcnR1LnNocCcpDQogICAgDQojIEdlbmVyYXIgbXVlc3RyYXMgZGUgMzAwIHB1bnRvcyBhIHBhcnRpciBkZSBsb3MgcG9saWdvbm9zDQpwdHNpYmF0ZWNvYmVydCA9IHNwc2FtcGxlKHNpYmF0ZWNvYmVydCwzMDAsIHR5cGU9J3JlZ3VsYXInKQ0KDQojIEFncmVnYXIgbGEgY2xhc2UgZGUgY29iZXJ0dXJhIGRlbCBzdWVsbyBhIGxvcyBwdW50b3MNCnB0c2liYXRlY29iZXJ0JE5hbWUgPSBvdmVyKHB0c2liYXRlY29iZXJ0LCBzaWJhdGVjb2JlcnQpJE5hbWUNCiAgICANCiMgRXh0cmFlciB2YWxvcmVzIGNvbiBwdW50b3MNCmRmID0gZXh0cmFjdChsYW5kc2F0MjAxNSwgcHRzaWJhdGVjb2JlcnQpDQogICANCiMgUGFyYSB2ZXIgYWxndW5vcyBkZSBsb3MgdmFsb3JlcyBkZSByZWZsZWN0YW5jaWENCmhlYWQoZGYpDQpgYGANCiMNCiMNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IFBFUkZJTEVTIEVTUEVDVFJBTEVTIDxzcGFuLz4NCiMNCiMNCiMjIyMjIFVuYSBncmFmaWNhIGRlbCBlc3BlY3RybyAodG9kYXMgbGFzIGJhbmRhcykgcGFyYSBsb3MgcGl4ZWxlcyBxdWUgcmVwcmVzZW50YW4gY2llcnRhcyBjYXJhY3RlcmlzdGljYXMgZGUgbGEgc3VwZXJmaWNpZSB0ZXJyZXN0cmUgKHAuIEVqLiBBZ3VhKSBzZSBjb25vY2UgY29tbyBwZXJmaWwgZXNwZWN0cmFsLiBEaWNob3MgcGVyZmlsZXMgZGVtdWVzdHJhbiBsYXMgZGlmZXJlbmNpYXMgZW4gbGFzIHByb3BpZWRhZGVzIGVzcGVjdHJhbGVzIGRlIHZhcmlhcyBjYXJhY3RlcmlzdGljYXMgZGUgbGEgc3VwZXJmaWNpZSB0ZXJyZXN0cmUgeSBjb25zdGl0dXllbiBsYSBiYXNlIHBhcmEgZWwgYW5hbGlzaXMgZGUgaW1hZ2VuZXMuIExvcyB2YWxvcmVzIGVzcGVjdHJhbGVzIHNlIHB1ZWRlbiBleHRyYWVyIGRlIGN1YWxxdWllciBjb25qdW50byBkZSBkYXRvcyBtdWx0aWVzcGVjdHJhbGVzIHV0aWxpemFuZG8gbGEgZnVuY2lvbiAtIGV4dHJhY3QgLS4gIEVuIGVsIGVqZW1wbG8gYW50ZXJpb3IsIGV4dHJhamltb3MgdmFsb3JlcyBkZSBkYXRvcyBkZSBMYW5kc2F0IHBhcmEgbGFzIG11ZXN0cmFzLiBFc3RhcyBtdWVzdHJhcyBpbmNsdXllbjogdGllcnJhcyBkZSBjdWx0aXZvLCBhZ3VhLCBiYXJiZWNobywgY29uc3RydWlkbyB5IGFiaWVydG8uIFByaW1lcm8gY2FsY3VsYW1vcyBsb3MgdmFsb3JlcyBtZWRpb3MgZGUgcmVmbGVjdGFuY2lhIHBhcmEgY2FkYSBjbGFzZSB5IGNhZGEgYmFuZGEuDQojDQojDQpgYGB7cn0NCm51bWVybz0gbGVuZ3RoKHB0c2liYXRlY29iZXJ0KQ0KbnVtZXJvDQoNCiMgQ3JlYW1vcyB1biBkYXRhIGZyYW1lIGNvbiBsb3MgcHVudG9zIGVzcGFjaWFsZXMNCmRmX3NhbXBsZXMgPSBhcyAocHRzaWJhdGVjb2JlcnQsICJTcGF0aWFsUG9pbnRzRGF0YUZyYW1lIikNCmRmX3NhbXBsZXMNCmRmX3NhbXBsZXNAZGF0YT1kYXRhLmZyYW1lKElEPTE6bnVtZXJvLHNpemU9MSkNCmRmX3NhbXBsZXMNCg0KIyBwbG90ZWFtb3MgZWwgYXJlYSBkZSBzaWJhdGUgeSBzdXMgcHVudG9zIGRlIG11ZXN0cmVvIGRlIGNvYmVydHVyYQ0KcGxvdChsYW5kc2F0Y3JvcDIwMTUpDQpwbG90KHNpYmF0ZWNvYmVydCwgYWRkPSBUUlVFKQ0KcGxvdChkZl9zYW1wbGVzLHBjaD0xLCBjZXg9KGRmX3NhbXBsZXMkc2l6ZSkvNCwgYWRkPVRSVUUpDQoNCg0KZGZfc2FtcGxlcyROYW1lID1vdmVyKGRmX3NhbXBsZXMsc2liYXRlY29iZXJ0KSROYW1lDQpkZl9zYW1wbGVzDQpkZjE9cmFzdGVyOjpleHRyYWN0KGxhbmRzYXRjcm9wMjAxNSwgZGZfc2FtcGxlcykNCg0KDQptcyA9IGFnZ3JlZ2F0ZShkZjEsIGxpc3QocHRzaWJhdGVjb2JlcnQkTmFtZSksIG1lYW4pDQoNCiMgRW4gbHVnYXIgZGUgbGEgcHJpbWVyYSBjb2x1bW5hLCB1c2Ftb3Mgbm9tYnJlcyBkZSBmaWxhDQpyb3duYW1lcyhtcykgPSBtc1ssMV0NCm1zID0gbXNbLC0xXQ0KbXMNCg0KYGBgDQojDQojDQojIyMjIyBBaG9yYSB0cmF6YW1vcyBlbCBlc3BlY3RybyBtZWRpbyBkZSBlc3RhcyBjYXJhY3RlcmlzdGljYXMuDQojDQojDQojIyMjIyBVbmEgZGUgbGFzIG1heW9yZXMgZGlmaWN1bHRhZGVzIGRlIGdlbmVyYXIgdW4gbWFwYSBkZSB1c28gZGUgbGEgdGllcnJhIGVzIGRlbGltaXRhciBsYXMgZGlmZXJlbnRlcyBjb2JlcnR1cmFzLiBFc3RhYmxlY2VyIGxpbWl0ZXMgZW50cmUgdGlwb3MgZGUgdXNvIG8gdmVnZXRhY2lvbiBlcyB1biBwcm9jZXNvIG11Y2hhcyB2ZWNlcyBzdWJqZXRpdm8sIHBlcm8gcGFyYSBlbGxvIGV4aXN0ZW4gZGl2ZXJzYXMgaGVycmFtaWVudGFzIHF1ZSBwdWVkZW4gYXl1ZGFyIGVuIGVsIHByb2Nlc28gZGUgaW50ZXJwcmV0YWNpb24sIGVudHJlIGVsbGFzIHJlYWxpemFyIHVuIHBlcmZpbCBlc3BlY3RyYWwuIFVuIHBlcmZpbCBlc3BlY3RyYWwgZXMgbGEgcmVwcmVzZW50YWNpb24gZGVsIGNvbXBvcnRhbWllbnRvIGVzcGVjdHJhbCBhIGxvIGxhcmdvIGRlIHVuIHRyYXllY3RvLCBwb3IgbG8gdGFudG8sIGVzIHVuIHByb2Nlc28gc2ltaWxhciBhIGNyZWFyIHVuIHBlcmZpbCB0b3BvZ3JhZmljbywgZW4gdmV6IGRlIGxhIGVsZXZhY2lvbiBkZWwgdGVycmVubyBzZSBncmFmaWNhbiBsb3MgdmFsb3JlcyBkZSBsb3MgcGl4ZWxlcy4NCiMNCiMNCmBgYHtyfQ0KIyBDcmVlIHVuIHZlY3RvciBkZSBjb2xvciBwYXJhIGxhcyBjbGFzZXMgZGUgY29iZXJ0dXJhIGRlbCBzdWVsbyBwYXJhIHVzYXIgZW4gZWwgdHJhemFkbw0KbXljb2xvciA9IGMoJ2RhcmtyZWQnLCAneWVsbG93JywgJ2J1cmx5d29vZCcsICdjeWFuJywgJ2JsdWUnLCAnZ3JlZW4nLCdtYWdlbnRhJywgImRhcmtncmVlbiIpDQoNCiMgdHJhbnNmb3JtYXIgbXMgZGUgdW4gZGF0YS5mcmFtZSBhIHVuYSBtYXRyaXoNCm1zID0gYXMubWF0cml4KG1zKQ0KDQojIFByaW1lcm8gY3JlYSB1bmEgcGFyY2VsYSB2YWNpYQ0KcGxvdCgwLCB5bGltPWMoMCwyNTAwMCksIHhsaW0gPSBjKDEsNyksIHR5cGU9J24nLCB4bGFiPSJCYW5kYXMiLCB5bGFiID0gIlJlZmxlY3RhbmNpYSIpDQoNCiMgQWdyZWdhIGxhcyBkaWZlcmVudGVzIGNsYXNlcw0KZm9yIChpIGluIDE6bnJvdyhtcykpew0KICBsaW5lcyhtc1tpLF0sIHR5cGUgPSAibCIsIGx3ZCA9IDMsIGx0eSA9IDEsIGNvbCA9IG15Y29sb3JbaV0pDQp9DQoNCiMgQWdyZWdhbW9zIHVuIHRpdHVsbw0KdGl0bGUobWFpbj0iUGVyZmlsIGVzcGVjdHJhbCBkZSBMYW5kc2F0IiwgZm9udC5tYWluID0gMikNCg0KIyBBZ3JlZ2Ftb3MgbGEgbGV5ZW5kYQ0KbGVnZW5kKCJ0b3BsZWZ0Iiwgcm93bmFtZXMobXMpLA0KICAgICAgY2V4PTAuOCwgY29sPW15Y29sb3IsIGx0eSA9IDEsIGx3ZCA9MywgYnR5ID0gIm4iKQ0KYGBgDQojDQojDQojIyMjIyBFbCBwZXJmaWwgZXNwZWN0cmFsIG11ZXN0cmEgKGRlcykgc2ltaWxpdHVkIGVuIGxhIHJlZmxlY3RhbmNpYSBkZSBkaWZlcmVudGVzIGNhcmFjdGVyaXN0aWNhcyBlbiBsYSBzdXBlcmZpY2llIGRlIGxhIHRpZXJyYSAobyBwb3IgZW5jaW1hIGRlIGVsbGEpLiAnQWd1YScgbXVlc3RyYSB1bmEgcmVmbGV4aW9uIHJlbGF0aXZhbWVudGUgYmFqYSBlbiB0b2RhcyBsYXMgbG9uZ2l0dWRlcyBkZSBvbmRhLCB5ICdQYXN0b3MnLCAnSW52ZXJuYWRlcm8nIHkgJ1pvbmEgZGVzbnVkYScgdGllbmVuIHVuYSByZWZsZWN0YW5jaWEgcmVsYXRpdmFtZW50ZSBhbHRhIGVuIGxhcyBsb25naXR1ZGVzIGRlIG9uZGEgbWFzIGxhcmdhcy4NCiMNCiMNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IE9QRVJBQ0lPTkVTIE1BVEVNQVRJQ0FTIEJBU0lDQVMgPHNwYW4vPg0KIw0KIw0KIyMjIyMgRWwgcGFxdWV0ZSAtIHJhc3Rlci0gYWRtaXRlIG11Y2hhcyBvcGVyYWNpb25lcyBtYXRlbWF0aWNhcy4gTGFzIG9wZXJhY2lvbmVzIG1hdGVtYXRpY2FzIGdlbmVyYWxtZW50ZSBzZSByZWFsaXphbiBwb3IgcGl4ZWwgKGNlbGRhIGRlIGN1YWRyaWN1bGEpLiBQcmltZXJvIGhhcmVtb3MgYWxndW5hcyBvcGVyYWNpb25lcyBhcml0bWV0aWNhcyBiYXNpY2FzIHBhcmEgY29tYmluYXIgYmFuZGFzLiBFbiBlbCBwcmltZXIgZWplbXBsbywgZXNjcmliaW1vcyB1bmEgZnVuY2lvbiBtYXRlbWF0aWNhIHBlcnNvbmFsaXphZGEgcGFyYSBjYWxjdWxhciBlbCBpbmRpY2UgZGUgdmVnZXRhY2lvbiBkZSBkaWZlcmVuY2lhIG5vcm1hbGl6YWRhIChORFZJKS4NCiMNCiMNCmBgYHtyfQ0KIyMjIHNvbG8gcHVlZG8gY2FyZ2FyIGxhcyBiYW5kYXMgZGUgbGEgMSBhIGxhIDcgcG9ycXVlIGxhIDggbm8gdGllbmUgbGEgbWlzbWEgZXh0ZW5zaW9uIGRlIGxhcyBkZW1hcw0KcmFzbGlzdHAzID0gcGFzdGUwKCcuL2RhdGEyMDE1L0xDMDhfTDFUUF8wMDgwNTdfMjAxNTAxMDRfMjAxNzA0MTVfMDFfVDFfQicsIDE6NywgIi50aWYiKQ0KDQojIFN0YWNrIGRlIGxhcyBiYW5kYXMgY2FyZ2FkYXMNCmxhbmRzYXRwMyA9IHN0YWNrKHJhc2xpc3RwMykNCnBsb3QobGFuZHNhdHAzKQ0KDQojIENvbWJpbmFjaW9uIGRlIGxhcyBiYW5kYXMgNCwzLDINCmxhbmRzYXRSR0JwMyA9IGxhbmRzYXRwM1tbYyg0LDMsMildXQ0KcGxvdChsYW5kc2F0UkdCcDMpDQoNCiMgQ29tYmluYWNpb24gZGUgbGFzIGJhbmRhcyBlbiBmYWxzbyBjb2xvciA1LDQsMw0KbGFuZHNhdEZDQ3AzID0gbGFuZHNhdHAzW1tjKDUsNCwzKV1dDQpwbG90KGxhbmRzYXRGQ0NwMykNCmBgYA0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gSU5ESUNFUyBERSBWRUdFVEFDSU9OIDxzcGFuLz4NCiMNCiMNCiMjIyMjIERlZmluYW1vcyB1bmEgZnVuY2lPbiBnZW5lcmFsIHBhcmEgdW4gSW5kaWNlIGJhc2FkbyBlbiByYXpPbiAodmVnZXRhY2lPbikuIEVuIGxhIGZ1bmNpb24gYSBjb250aW51YWNpb24sIC1pbWctIGVzIHVuIG9iamV0byBSYXN0ZXIgKiBkZSBtdWx0aXBsZXMgY2FwYXMgLWktIHkgLWstIHNvbiBsb3MgaW5kaWNlcyBkZSBsYXMgY2FwYXMgKG51bWVyb3MgZGUgY2FwYSkgdXRpbGl6YWRvcyBwYXJhIGNhbGN1bGFyIGVsIGluZGljZSBkZSB2ZWdldGFjaW9uLg0KIw0KIw0KYGBge3J9DQojIyB2aTIwMTU9IGluZGljZSBkZSB2ZWdldGFjaW9uIHBhcmEgbGEgaW1hZ2VuIDIwMTUNCnZpMjAxNSA9IGZ1bmN0aW9uKGltZywgaywgaSkgew0KICANCiAgYmsgPSBpbWcgW1trXV0NCiAgYmkgPSBpbWcgW1tpXV0NCiAgdmkyMDE1PShiay1iaSkvKGJrK2JpKQ0KICByZXR1cm4odmkyMDE1KQ0KfQ0KYGBgDQojDQojDQojIyMjIyBFbCBORFZJLCBlcyB1biBpbmRpY2UgdXNhZG8gcGFyYSBlc3RpbWFyIGxhIGNhbnRpZGFkLCBjYWxpZGFkIHkgZGVzYXJyb2xsbyBkZSBsYSB2ZWdldGFjaW9uIGNvbiBiYXNlIGEgbGEgbWVkaWNpb24gZGUgbGEgaW50ZW5zaWRhZCBkZSBsYSByYWRpYWNpb24gZGUgY2llcnRhcyBiYW5kYXMgZGVsIGVzcGVjdHJvIGVsZWN0cm9tYWduZXRpY28gcXVlIGxhIHZlZ2V0YWNpb24gZW1pdGUgbyByZWZsZWphLCBlbiBlc3RlIGNhc28sIGVsIE5EVkksIGVzdGEgbGlnYWRvIGEgdW4gZ3JhbiBudW1lcm8gZGUgZmFjdG9yZXMgZW4gbG9zIGN1bHRpdm9zLiBMYSBiaW9tYXNhIHN1ZWxlIHNlciBlbCBmYWN0b3IgbWFzIGltcG9ydGFudGUuIExvIHF1ZSByZXN1bHRhIG1hcyBjb21wbGljYWRvIGRlbCBORFZJIGVzIHF1ZSBlc3RlIGVzdGEgcmVsYWNpb25hZG8gY29uIGxhIGJpb21hc2EgeSBsYSBiaW9tYXNhIHNlIHZlIGFmZWN0YWRhIHBvciB0b2RvLg0KIw0KIw0KYGBge3J9DQojIyBwYXJhIGxhbmRzYXQgTklSID0gNSwgcmVkID0gNA0KIyMgbmR2aTIwMTU9IGluZGljZSBkZSB2ZWdldGFjaW9uIGRlIGRpcmVmZW5jaWEgbm9ybWFsaXphZGEgKE5EVkkpIHBhcmEgbGEgaW1hZ2VuIGxhbmRzYXQgMjAxNQ0KDQpuZHZpMjAxNSA9IHZpMjAxNShsYW5kc2F0cDMsIDUsIDQpIA0KcGxvdChuZHZpMjAxNSwgY29sPXJldih0ZXJyYWluLmNvbG9ycyg5KSksIG1haW49ICJMYW5kc2F0IDIwMTUgLSBOVkRJIikNCg0KIyBTZWxlY2Npb25hbmRvIGVsIHNoYXBlIGRlbCBhcmVhIGRlIHNpYmF0ZSwgY2FyZ2FuZG9sbyB5IHJlY29ydGFuZG9sbyBjb24gcmVzcGVjdG8gZGVsIE5EVkkgZGUgbGEgaW1hZ2VuIExhbmRzYXQNCk5EVkkxX3NpYmF0ZV8yMDE1ID0gc2hhcGVmaWxlKCdDOi9Vc2Vycy9EYXZpZC1QQy9EZXNrdG9wL0VTQ1JJVE9SSU8vU0lCQVRFX1JVUkFML3J1cmFsLnNocCcpDQplTkRWSTFfc2liYXRlID0gZXh0ZW50KE5EVkkxX3NpYmF0ZV8yMDE1KQ0KTkRWSV9yZWNvcnRlXzEgPSBjcm9wKG5kdmkyMDE1LCBlTkRWSTFfc2liYXRlKQ0KcGxvdChORFZJX3JlY29ydGVfMSwgY29sPXJldih0ZXJyYWluLmNvbG9ycygxMCkpLCBtYWluID0gIkxhbmRzYXQgMjAxNSAtIE5EVkkiKQ0KYGBgDQojDQojDQojIyMjIyBQdWVkZXMgdmVyIGxhIHZhcmlhY2lvbiBlbiBlbCB2ZXJkb3IgZGVzZGUgbGEgdHJhbWEuDQojDQojDQojIyMjIyBVbmEgZm9ybWEgYWx0ZXJuYXRpdmEgZGUgbG9ncmFyIGVzdG8gZXMgYXNpDQojDQojDQpgYGB7cn0NCg0KdmkyXzIwMTUgPSBmdW5jdGlvbih4LCB5KSB7DQogICh4LXkpLyh4K3kpDQp9DQoNCm5kdmkyXzIwMTUgPSBvdmVybGF5KGxhbmRzYXRwM1tbNV1dLCBsYW5kc2F0cDNbWzRdXSwgZnVuID0gdmkyXzIwMTUpDQpwbG90KG5kdmkyXzIwMTUsIGNvbD1yZXYodGVycmFpbi5jb2xvcnMoMTApKSwgbWFpbiA9ICJMYW5kc2F0IDIwMTUgLSBORFZJIHYyIikNCg0KIyBTZWxlY2Npb25hbmRvIGVsIHNoYXBlIGRlbCBhcmVhIGRlIHNpYmF0ZSwgY2FyZ2FuZG9sbyB5IHJlY29ydGFuZG9sbyBjb24gcmVzcGVjdG8gZGVsIE5EVkkgZGUgbGEgaW1hZ2VuIExhbmRzYXQNCk5EVkkyX3NpYmF0ZV8yMDE1ID0gc2hhcGVmaWxlKCdDOi9Vc2Vycy9EYXZpZC1QQy9EZXNrdG9wL0VTQ1JJVE9SSU8vU0lCQVRFX1JVUkFML3J1cmFsLnNocCcpDQplTkRWSTJfc2liYXRlID0gZXh0ZW50KE5EVkkyX3NpYmF0ZV8yMDE1KQ0KTkRWSV9yZWNvcnRlXzIgPSBjcm9wKG5kdmkyXzIwMTUsIGVORFZJMl9zaWJhdGUpDQpwbG90KE5EVklfcmVjb3J0ZV8yLCBjb2w9cmV2KHRlcnJhaW4uY29sb3JzKDEwKSksIG1haW4gPSAiTGFuZHNhdCAyMDE1IC0gTkRWSSIpDQoNCmBgYA0KIw0KIw0KIyMjIyMgUHJlZ3VudGEgMSA6IEFkYXB0ZSBlbCBjb2RpZ28gcXVlIHNlIG11ZXN0cmEgYXJyaWJhIHBhcmEgY2FsY3VsYXIgbG9zIGluZGljZXMgcGFyYSBpZGVudGlmaWNhciBpKSBhZ3VhIHkgaWkpIGFjdW11bGFkb3MuIFN1Z2VyZW5jaWE6IFVzZSBlbCBkaWFncmFtYSBkZWwgcGVyZmlsIGVzcGVjdHJhbCBwYXJhIGVuY29udHJhciBsYXMgYmFuZGFzIHF1ZSB0aWVuZW4gcmVmbGVjdGFuY2lhIG1heGltYSB5IG1pbmltYSBwYXJhIGVzdGFzIGRvcyBjbGFzZXMuDQojDQojDQojIyMjIyBFbCBpbmRpY2UgRGlmZXJlbmNpYWwgZGUgQWd1YSBOb3JtYWxpemFkbyAoTkRXSSkgc2UgdXRpbGl6YSBwYXJhIGVsIGFuYWxpc2lzIGRlIG1hc2FzIGRlIGFndWEuIEVsIMOtbmRpY2UgdXRpbGl6YSBiYW5kYXMgdmVyZGVzIHkgY2FzaSBpbmZyYXJyb2phcyBkZSBpbWFnZW5lcyBkZSB0ZWxlZGV0ZWNjaW9uLiBFbCBORFdJIHB1ZWRlIG1lam9yYXIgbGEgaW5mb3JtYWNpb24gc29icmUgZWwgYWd1YSBkZSBtYW5lcmEgZWZpY2llbnRlIGVuIGxhIG1heW9yaWEgZGUgbG9zIGNhc29zLiBFcyBzZW5zaWJsZSBhIGxhIGFjdW11bGFjaW9uIGRlIHRpZXJyYSB5IHJlc3VsdGEgZW4gbGEgc29icmVlc3RpbWFjaW9uIGRlIGxvcyBjdWVycG9zIGRlIGFndWEuIExvcyBwcm9kdWN0b3MgTkRXSSBwdWVkZW4gc2VyIHVzYWRvcyBlbiBjb25qdW50byBjb24gbG9zIHByb2R1Y3RvcyBkZSBjYW1iaW8gTkRWSSBwYXJhIGV2YWx1YXIgZWwgY29udGV4dG8gZGUgbGFzIGFyZWFzIGRlIGNhbWJpbyBhcGFyZW50ZQ0KIw0KIw0KYGBge3J9DQojIyBwMSBlcyBwcmVndW50YSAxDQoNCm5kdmkyMDE1X3AxID0gdmkyMDE1KGxhbmRzYXRwMywgMywgNikgDQpwbG90KG5kdmkyMDE1X3AxLCBjb2w9cmV2KHRlcnJhaW4uY29sb3JzKDEwKSksIG1haW49ICJMYW5kc2F0IDIwMTUgLSBORFdJIikNCg0KdmkyXzIwMTVfcDEgPSBmdW5jdGlvbih4LCB5KSB7DQogICh4LXkpLyh4K3kpDQp9DQoNCm5kdmkyXzIwMTVfcDEgPSBvdmVybGF5KGxhbmRzYXRwM1tbM11dLCBsYW5kc2F0cDNbWzZdXSwgZnVuID0gdmkyXzIwMTVfcDEpDQpwbG90KG5kdmkyXzIwMTVfcDEsIGNvbD1yZXYodG9wby5jb2xvcnMoMTApKSwgbWFpbiA9ICJMYW5kc2F0IDIwMTUgLSBORFdJIikNCg0KIyMjIFBBUkEgSU5ESUNFIERFIEFHVUEgREUgRElGRVJFTkNJQSBOT1JNQUxJWkFEQSAtIE5EV0kNCiMgU2VsZWNjaW9uYW5kbyBlbCBzaGFwZSBkZWwgYXJlYSBkZSBzaWJhdGUsIGNhcmdhbmRvbG8geSByZWNvcnRhbmRvbG8gY29uIHJlc3BlY3RvIGRlbCBORHdJIGRlIGxhIGltYWdlbiBMYW5kc2F0DQoNCk5EV0lfc2liYXRlID0gc2hhcGVmaWxlKCdDOi9Vc2Vycy9EYXZpZC1QQy9EZXNrdG9wL0VTQ1JJVE9SSU8vU0lCQVRFX1JVUkFML3J1cmFsLnNocCcpDQplTkRXSSA9IGV4dGVudChORFdJX3NpYmF0ZSkNCk5EV0lfcmVjb3J0ZSA9IGNyb3AobmR2aTJfMjAxNV9wMSwgZU5EV0kpDQpwbG90KE5EV0lfcmVjb3J0ZSwgY29sPXJldih0b3BvLmNvbG9ycygxMCkpLCBtYWluID0gIkxhbmRzYXQgMjAxNSAtIE5EV0kiKQ0KYGBgDQojDQojDQojIyMjIyBFbCBOREJJIG8gaW5kaWNlIGRlIERpZmVyZW5jaWEgTm9ybWFsaXphZGEgRWRpZmljYWRhIHBlcm1pdGUgbGxldmFyIGEgY2FibyBsYSBlc3RpbWFjaW9uIGRlIHpvbmFzIGNvbiBzdXBlcmZpY2llcyBlZGlmaWNhZGFzIG8gZW4gZGVzYXJyb2xsbyBkZSBjb25zdHJ1Y2Npb24gZnJlbnRlIGEgbGFzIGhhYml0dWFsZXMgem9uYXMgbmF0dXJhbGl6YWRhcyBjb24gdmVnZXRhY2lvbiBvIGRlc251ZGFzLiBFbCBpbmRpY2UgTkRCSSwganVudG8gYSBvdHJvcyBjb21vIGVsIGluZGljZSBORFZJIHkgZWwgaW5kaWNlIFVJIHNvbiB1bmEgdmlhIGRlIGFuYWxpc2lzIHRlcnJpdG9yaWFsIGVuIGVzdHVkaW9zIHVyYmFuaXN0aWNvcywgaW5mcmFlc3RydWN0dXJhcyB5IGxhIGNvbXBhcmFjaW9uIGRlIGxhIGV2b2x1Y2lvbiBkZSBsYXMgdXJiZXMgZW4gZWwgdGllbXBvLg0KIw0KIw0KYGBge3J9DQojIyMgUEFSQSBJTkRJQ0UgSU5DT1JQT1JBRE8gREUgRElGRVJFTkNJQSBOT1JNQUxJWkFEQSAtIE5EQkkNCg0KbmRiaTFfMjAxNV9wMSA9IG92ZXJsYXkobGFuZHNhdHAzW1s2XV0sIGxhbmRzYXRwM1tbNV1dLCBmdW4gPSB2aTJfMjAxNV9wMSkNCnBsb3QobmRiaTFfMjAxNV9wMSwgY29sPXJldihoZWF0LmNvbG9ycygxMCkpLCBtYWluID0gIkxhbmRzYXQgMjAxNSAtIE5EQkkiKQ0KDQojIFNlbGVjY2lvbmFuZG8gZWwgc2hhcGUgZGVsIGFyZWEgZGUgc2liYXRlLCBjYXJnYW5kb2xvIHkgcmVjb3J0YW5kb2xvIGNvbiByZXNwZWN0byBkZWwgTkRCSSBkZSBsYSBpbWFnZW4gTGFuZHNhdA0KDQpOREJJX3NpYmF0ZSA9IHNoYXBlZmlsZSgnQzovVXNlcnMvRGF2aWQtUEMvRGVza3RvcC9FU0NSSVRPUklPL1NJQkFURV9SVVJBTC9ydXJhbC5zaHAnKQ0KZU5EQkkgPSBleHRlbnQoTkRCSV9zaWJhdGUpDQpOREJJX3JlY29ydGUgPSBjcm9wKG5kYmkxXzIwMTVfcDEsIGVOREJJKQ0KcGxvdChOREJJX3JlY29ydGUsIGNvbD1yZXYoaGVhdC5jb2xvcnMoMTApKSwgbWFpbiA9ICJMYW5kc2F0IDIwMTUgLSBOREJJIikNCg0KYGBgDQojDQojDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBISVNUT0dSQU1BIDxzcGFuLz4NCiMNCiMNCiMjIyMjIFBvZGVtb3MgZXhwbG9yYXIgbGEgZGlzdHJpYnVjaW9uIGRlIHZhbG9yZXMgY29udGVuaWRvcyBlbiBudWVzdHJvIHJhc3RlciB1dGlsaXphbmRvIGxhIGZ1bmNpb24gLWhpc3QgKCktIHF1ZSBwcm9kdWNlIHVuIGhpc3RvZ3JhbWEuIExvcyBoaXN0b2dyYW1hcyBhIG1lbnVkbyBzb24gdXRpbGVzIHBhcmEgaWRlbnRpZmljYXIgdmFsb3JlcyBhdGlwaWNvcyB5IHZhbG9yZXMgZGUgZGF0b3MgaW5jb3JyZWN0b3MgZW4gbnVlc3Ryb3MgZGF0b3MgcmFzdGVyDQojDQojDQpgYGB7cn0NCiMjIHZlciBoaXN0b2dyYW1hIGRlIGRhdG9zDQpoaXN0KE5EVklfcmVjb3J0ZV8xLA0KICAgICBtYWluPSAiRHNpdHJpYnVjaW9uIGRlIHZhbG9yZXMgZGVsIE5EVkkiLA0KICAgICB4bGFiPSAiTkRWSSIsDQogICAgIHlsYWI9ICJGcmVjdWVuY2lhIiwNCiAgICAgY29sPSB0ZXJyYWluLmNvbG9ycyg1MCksDQogICAgIHhsaW09IGMgKC0wLjEsMC43KSwNCiAgICAgYnJlYWtzID0gMzAsDQogICAgIHhheHQ9ICduJykNCg0KYXhpcyhzaWRlID0gMSwgYXQ9c2VxKC0wLjUsMSwwLjA1KSwgbGFiZWxzID0gc2VxKC0wLjUsMSwwLjA1KSkNCmBgYA0KIw0KIw0KIyMjIyMgTm9zIHJlZmVyaXJlbW9zIGEgZXN0ZSBoaXN0b2dyYW1hIHBhcmEgbGEgc2lndWllbnRlIHN1YnNlY2Npb24gc29icmUgdW1icmFsaXphY2lvbi4NCiMNCiMNCiMjIyMjIFByZWd1bnRhIDIgOiBIYWdhIGhpc3RvZ3JhbWFzIGRlIGxvcyB2YWxvcmVzIHF1ZSBsb3MgaW5kaWNlcyBkZSB2ZWdldGFjaW9uIGRlc2Fycm9sbGFyb24gZW4gbGEgcHJlZ3VudGEgMQ0KIw0KIw0KYGBge3J9DQojIyByZXNwdWVzdGEgYSBsYSBwcmVndW50YSAyOiB2ZXIgaGlzdG9ncmFtYSBkZSBkYXRvcw0KaGlzdChORFdJX3JlY29ydGUsDQogICAgIG1haW49ICJEc2l0cmlidWNpb24gZGUgdmFsb3JlcyBkZWwgTkRXSSIsDQogICAgIHhsYWI9ICJORFdJIiwNCiAgICAgeWxhYj0gIkZyZWN1ZW5jaWEiLA0KICAgICBjb2w9IHRvcG8uY29sb3JzKDUwKSwNCiAgICAgeGxpbT0gYyAoLTAuNSwwLjMpLA0KICAgICBicmVha3MgPSAzMCwNCiAgICAgeGF4dD0gJ24nKQ0KDQpheGlzKHNpZGUgPSAxLCBhdD1zZXEoLTAuNSwxLDAuMDUpLCBsYWJlbHMgPSBzZXEoLTAuNSwxLDAuMDUpKQ0KYGBgDQojDQojDQpgYGB7cn0NCiMjIHJlc3B1ZXN0YSBhIGxhIHByZWd1bnRhIDI6IHZlciBoaXN0b2dyYW1hIGRlIGRhdG9zDQpoaXN0KE5EQklfcmVjb3J0ZSwNCiAgICAgbWFpbj0gIkRzaXRyaWJ1Y2lvbiBkZSB2YWxvcmVzIGRlbCBOREJJIiwNCiAgICAgeGxhYj0gIk5EQkkiLA0KICAgICB5bGFiPSAiRnJlY3VlbmNpYSIsDQogICAgIGNvbD0gaGVhdC5jb2xvcnMoNTApLA0KICAgICB4bGltPSBjICgtMC41LDAuMyksDQogICAgIGJyZWFrcyA9IDMwLA0KICAgICB4YXh0PSAnbicpDQoNCmF4aXMoc2lkZSA9IDEsIGF0PXNlcSgtMC41LDEsMC4wNSksIGxhYmVscyA9IHNlcSgtMC41LDEsMC4wNSkpDQpgYGANCiMNCiMNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IFVNQlJBTElaQUNJT04gPHNwYW4vPg0KIw0KIw0KIyMjIyMgUG9kZW1vcyBhcGxpY2FyIHJlZ2xhcyBiYXNpY2FzIHBhcmEgb2J0ZW5lciB1bmEgZXN0aW1hY2lvbiBkZSBsYSBleHRlbnNpb24gZXNwYWNpYWwgZGUgZGlmZXJlbnRlcyBjYXJhY3RlcmlzdGljYXMgZGUgbGEgc3VwZXJmaWNpZSB0ZXJyZXN0cmUuIFRlbmdhIGVuIGN1ZW50YSBxdWUgbG9zIHZhbG9yZXMgTkRWSSBlc3RhbiBlc3RhbmRhcml6YWRvcyB5IHZhcmlhbiBlbnRyZSAtMSB5ICsxLiBMb3MgdmFsb3JlcyBtYXMgYWx0b3MgaW5kaWNhbiBtYXMgY29iZXJ0dXJhIHZlcmRlLg0KIw0KIw0KIyMjIyMgTGFzIGNlbGRhcyBjb24gdmFsb3JlcyBkZSBORFZJIHN1cGVyaW9yZXMgYSAwLjQgc29uIGRlZmluaXRpdmFtZW50ZSB2ZWdldGFjaW9uLiBMYSBzaWd1aWVudGUgb3BlcmFjaW9uIGVubWFzY2FyYSB0b2RhcyBsYXMgY2VsZGFzIHF1ZSB0YWwgdmV6IG5vIHNlYW4gdmVnZXRhY2lvbi4NCiMNCiMNCiMjIyMjIExhIGZ1bmNpb24gKHJlY2xhc3NpZnkpIGNsYXNpZmljYSBncnVwb3MgZGUgdmFsb3JlcyBhIG90cm9zIHZhbG9yZXMuIFBvciBlamVtcGxvLCB0b2RvcyBsb3MgdmFsb3JlcyBlbnRyZSAxIHkgMTAgc2UgY29udmllcnRlbiBlbiAxLCB5IHRvZG9zIGxvcyB2YWxvcmVzIGVudHJlIDExIHkgMTUgc2UgY29udmllcnRlbiBlbiAyLg0KIw0KIw0KYGBge3J9DQp2ZWcgPSByZWNsYXNzaWZ5KE5EVklfcmVjb3J0ZV8xLCBjYmluZCgtSW5mLCAwLjQsIE5BKSkNCnBsb3QodmVnLCBtYWluID0gIlZlZ2V0YWNpb24iKQ0KYGBgDQojDQojDQojIyMjIyBWYW1vcyBhIG1hcGVhciBlbCBhcmVhIHF1ZSBjb3JyZXNwb25kZSBhbCBwaWNvIGVudHJlIDAuMjUgeSAwLjMgZW4gZWwgaGlzdG9ncmFtYSBORFZJLg0KIw0KIw0KYGBge3J9DQpsYW5kID0gcmVjbGFzc2lmeShORFZJX3JlY29ydGVfMSwgYygtSW5mLCAwLjI1LCBOQSwgMC4yNSwgMC4zLCAxLCAwLjMsIEluZiwgTkEpKQ0KcGxvdChsYW5kLCBtYWluID0gIiBRdWUgZXMgZXN0bz8iKQ0KYGBgDQojDQojDQojIyMjIyBFc3RhcyBwdWVkZW4gc2VyIGxhcyBhcmVhcyBhYmllcnRhcy4gUHVlZGUgdHJhemFyIC1sYW5kLSBzb2JyZSBlbCAtbGFuZHNhdEZDQy0gcmFzdGVyIG9yaWdpbmFsIHBhcmEgb2J0ZW5lciBtYXMgaW5mb3JtYWNpb24NCiMNCiMNCmBgYHtyfQ0KcGxvdFJHQihsYW5kc2F0Y3JvcDIwMTUsIHI9NywgZz02LCBiPTQsIGF4ZXMgPSBUUlVFLCBzdHJldGNoPSJsaW4iLCBtYWluID0gIlNpYmF0ZSBjb21wb3NpY2lvbiBlbiBmYWxzbyBjb2xvciIpDQpwbG90KGxhbmQsIGFkZCA9IFRSVUUsIGxlZ2VuZD0gRkFMU0UpDQpgYGANCiMNCiMNCiMjIyMjIFRhbWJpZW4gcHVlZGUgY3JlYXIgY2xhc2VzIHBhcmEgZGlmZXJlbnRlcyBjYW50aWRhZGVzIGRlIHByZXNlbmNpYSBkZSB2ZWdldGFjaW9uLg0KIw0KIw0KYGBge3J9DQp2ZWdjID0gcmVjbGFzc2lmeShORFZJX3JlY29ydGVfMSwgYygtSW5mLDAuMjUsMSwgMC4yNSwwLjMsMiwgMC4zLDAuNCwzLCAwLjQsMC41LDQsIDAuNSxJbmYsIDUpKQ0KcGxvdCh2ZWdjLCBjb2wgPSByZXYodGVycmFpbi5jb2xvcnMoNCkpLCBtYWluID0gJ1VtYnJhbCBiYXNhZG8gZW4gTkRWSScpDQpgYGANCiMNCiMNCiMjIyMjIFByZWd1bnRhIDMgOiBFcyBwb3NpYmxlIGVuY29udHJhciBhZ3VhIHVzYW5kbyBlbCB1bWJyYWwgZGUgTkRWSSBvIGN1YWxxdWllciBvdHJvIGluZGljZQ0KIw0KIw0KYGBge3J9DQojIFVtYnJhbCwgZW4gZXN0ZSBjYXNvIHBhcmEgYWd1YQ0KYWd1YSA9IHJlY2xhc3NpZnkoTkRXSV9yZWNvcnRlLCBjYmluZCgtSW5mLCAwLjEsIE5BKSkNCnBsb3QoYWd1YSwgbWFpbiA9ICJBZ3VhIiwgY29sPSB0b3BvLmNvbG9ycygxMCkpDQoNCiNSZWNsYXNpZmljbyBlbCBVbWJyYWwsIGVuIGVzdGUgY2FzbyBwYXJhIGFndWENCmFndWFjID0gcmVjbGFzc2lmeShORFdJX3JlY29ydGUsIGMoLUluZiwwLjAyNSwxLCAwLjAyNSwwLjAzLDIsIDAuMDMsMC4xLDMsIDAuMSwwLjIsNCwgMC4yLEluZiwgNSkpDQpwbG90KGFndWFjLCBjb2wgPSByZXYodG9wby5jb2xvcnMoMTApKSwgbWFpbiA9ICdVbWJyYWwgYmFzYWRvIGVuIE5EV0knKQ0KYGBgDQojDQojDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBBTkFMSVNJUyBERSBDT01QT05FTlRFUyBQUklOQ0lQQUxFUyAgPHNwYW4vPg0KIw0KIw0KIyMjIyMgTG9zIGRhdG9zIG11bHRpZXNwZWN0cmFsZXMgYSB2ZWNlcyBzZSB0cmFuc2Zvcm1hbiBwYXJhIGF5dWRhciBhIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIHkgZWwgcnVpZG8gZW4gbG9zIGRhdG9zLiBMYSB0cmFuc2Zvcm1hY2lvbiBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBlcyB1biBtZXRvZG8gZ2VuZXJpY28gZGUgcmVkdWNjaW9uIGRlIGRhdG9zIHF1ZSBzZSBwdWVkZSB1dGlsaXphciBwYXJhIGNyZWFyIGFsZ3VuYXMgYmFuZGFzIG5vIGNvcnJlbGFjaW9uYWRhcyBhIHBhcnRpciBkZSB1biBjb25qdW50byBtYXMgZ3JhbmRlIGRlIGJhbmRhcyBjb3JyZWxhY2lvbmFkYXMuDQojDQojDQojIyMjIyBQdWVkZSBjYWxjdWxhciBlbCBtaXNtbyBudW1lcm8gZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgcXVlIGVsIG51bWVybyBkZSBiYW5kYXMgZGUgZW50cmFkYS4gRWwgcHJpbWVyIGNvbXBvbmVudGUgcHJpbmNpcGFsIChQQykgZXhwbGljYSBlbCBtYXlvciBwb3JjZW50YWplIGRlIHZhcmlhbnphIHkgb3Ryb3MgUEMgZXhwbGljYW4gbGEgdmFyaWFuemEgYWRpY2lvbmFsIGVuIG9yZGVuIGRlY3JlY2llbnRlLg0KIw0KIw0KIyMjIyMgc2FtcGxlUmFuZG9tIHRvbWEgdW5hIG11ZXN0cmEgYWxlYXRvcmlhIGRlIGxvcyB2YWxvcmVzIGRlIGNlbGRhIGRlIHVuIG9iamV0byBSYXN0ZXIgKHNpbiByZWVtcGxhem8pLg0KIw0KIw0KYGBge3J9DQpzZXQuc2VlZCgxKQ0KDQojIENyZWFtb3MgdW4gbXVlc3RyZW8gZW50cmUgbGEgYmFuZGEgTklSIHkgbGEgYmFuZGEgcm9qYSBkZSAxMDAwMDAgcHVudG9zDQpzciA9IHNhbXBsZVJhbmRvbShsYW5kc2F0cDMsIDEwMDAwMCkNCnBsb3Qoc3JbLGMoNCw1KV0sIG1haW4gPSAiTklSIC0gUk9KTyIpDQpgYGANCiMNCiMNCiMjIyMjIEVzdG8gc2UgY29ub2NlIGNvbW8gZGlhZ3JhbWEgZGUgdmVnZXRhY2lvbiB5IGxpbmVhIGRlIHN1ZWxvIChpZ3VhbCBxdWUgZWwgZGlhZ3JhbWEgZGUgZGlzcGVyc2lvbiBlbiBsYSBzZWNjaW9uIGFudGVyaW9yKS4NCiMNCiMNCiMjIyMjIExhIHRlY25pY2EgZGUgQW5hbGlzaXMgcG9yIENvbXBvbmVudGVzIFByaW5jaXBhbGVzIChQQ0EsIFByaW5jaXBhbCBDb21wb25lbnRzIEFuYWx5c2lzKSAgIGVzIHVuYSB0cmFuc2Zvcm1hY2lvbiBxdWUgcGVybWl0ZSByZWR1Y2lyIGVzdGEgcmVkdW5kYW5jaWEgeSBwdWVkZSBzZXIgYXBsaWNhZGEgIHByZXZpYW1lbnRlIGEgdW4gYW5hbGlzaXMgdmlzdWFsIG8gYSB1biBwcm9jZXNvIG1hcyBjb21wbGVqbyBkZSBjbGFzaWZpY2FjaW9uIGEgdHJhdmVzIGRlICBhbGdvcml0bW9zIG1hdGVtYXRpY28tZXN0YWRpc3RpY29zLiBFbCBwcm9wb3NpdG8gZGUgZXN0YSB0ZWNuaWNhIGVzIOKAnGNvbXByaW1pcuKAnSB0b2RhIGxhICBpbmZvcm1hY2lvbiBjb250ZW5pZGEgZW4gdW4gY29uanVudG8gb3JpZ2luYWwgZGUgTiBiYW5kYXMgZXNwZWN0cmFsZXMgYSB1biBjb25qdW50byBtZW5vciBkZSBudWV2YXMgYmFuZGFzIG8gY29tcG9uZW50ZXMuDQojDQojDQpgYGB7cn0NCiMgZXN0b3Mgc29uIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBkZSBsYSBpbWFnZW4NCnBjYSA9IHByY29tcChzciwgc2NhbGUgPSBUUlVFKQ0KcGNhDQoNCnNjcmVlcGxvdChwY2EpDQpgYGANCiMNCiMNCmBgYHtyfQ0KcGNpID0gcHJlZGljdChsYW5kc2F0cDMsIHBjYSwgaW5kZXggPSAxOjIpDQpwbG90KHBjaVtbMV1dKQ0KDQojIyBSZWNvcnRhZG8gYSBzaWJhdGUNCnBjaV9zaWJhdGUgPSBzaGFwZWZpbGUoJ0M6L1VzZXJzL0RhdmlkLVBDL0Rlc2t0b3AvRVNDUklUT1JJTy9TSUJBVEVfUlVSQUwvcnVyYWwuc2hwJykNCmVwY2kgPSBleHRlbnQocGNpX3NpYmF0ZSkNCnBjaV9yZWNvcnRlID0gY3JvcChwY2ksIGVwY2kpDQpwbG90KHBjaV9yZWNvcnRlLCBjb2w9cmV2KHRlcnJhaW4uY29sb3JzKDIwKSksIG1haW4gPSAicGNpIFNpYmF0ZSIpDQpgYGANCiMNCiMNCiMjIyMjIEVsIHByaW1lciBjb21wb25lbnRlIHByaW5jaXBhbCByZXNhbHRhIGxvcyBsaW1pdGVzIGVudHJlIGxhcyBjbGFzZXMgZGUgdXNvIGRlIGxhIHRpZXJyYSBvIGxvcyBkZXRhbGxlcyBlc3BhY2lhbGVzLCBxdWUgZXMgbGEgaW5mb3JtYWNpb24gbWFzIGNvbXVuIGVudHJlIHRvZGFzIGxhcyBsb25naXR1ZGVzIGRlIG9uZGEuIEVzIGRpZmljaWwgZW50ZW5kZXIgbG8gcXVlIGRlc3RhY2EgZWwgc2VndW5kbyBjb21wb25lbnRlIHByaW5jaXBhbC4gVmFtb3MgYSBpbnRlbnRhciB1bWJyYWwgZGUgbnVldm86DQojDQojDQpgYGB7cn0NCmxhbmRzYXRGQ0MyMDE1ID0gc3RhY2soYjUsIGI0LCBiMykNCg0KIyMgcmVjb3J0YWRvIGEgc2liYXRlDQpwYzIgPSBzaGFwZWZpbGUoJ0M6L1VzZXJzL0RhdmlkLVBDL0Rlc2t0b3AvRVNDUklUT1JJTy9TSUJBVEVfUlVSQUwvcnVyYWwuc2hwJykNCmVwYzIgPSBleHRlbnQocGMyKQ0KcGMyX3JlYz0gY3JvcChsYW5kc2F0RkNDMjAxNSwgZXBjMikNCg0KIyBSZWNsYXNpZmljYW5kbyBlIGludGVudGFuZG8gdW4gdW1icmFsIG51ZXZvIGRlIGxvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcw0KcGMyID0gcmVjbGFzc2lmeShwY2lfcmVjb3J0ZVtbMl1dLCBjKC1JbmYsMCwxLDAsSW5mLE5BKSkNCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBsb3RSR0IocGMyX3JlYywgciA9IDEsIGcgPSAyLCBiID0gMywgYXhlcyA9IFRSVUUsIHN0cmV0Y2ggPSAibGluIiwgbWFpbiA9ICJGRkMiKQ0KcGxvdFJHQihwYzJfcmVjLCByID0gMSwgZyA9IDIsIGIgPSAzLCBheGVzID0gVFJVRSwgc3RyZXRjaCA9ICJsaW4iLCBtYWluID0gIkZGQyIpDQpwbG90KHBjMiwgbGVnZW5kID0gRkFMU0UsIGFkZCA9IFRSVUUpDQpgYGANCiMNCiMNCiMjIyMjIFBhcmEgb2J0ZW5lciBtYXMgaW5mb3JtYWNpb24gYWNlcmNhIGRlIGxhIGluZm9ybWFjaW9uIGNvbnRlbmlkYSBlbiBsYXMgcGFyY2VsYXMgZGUgdmVnZXRhY2lvbiB5IGxpbmVhcyBkZSBzdWVsbywgbGVhIGVzdGUgZG9jdW1lbnRvIGRlIC1HaXRlbHNvbiBldCBhbC0gLiBVbmEgZXh0ZW5zaW9uIGRlIFBDQSBlbiBsYSB0ZWxlZGV0ZWNjaW9uIHNlIGNvbm9jZSBjb21vIFRyYW5zZm9ybWFjaW9uIC1UYXNzZWxlZC1jYXAtIC4NCiMNCiMNCiMNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gQ0FQSVRVTE8gMiA8c3Bhbi8+DQojDQojDQojDQojIyMjIyBFbiBlc3RlIGNhcGl0dWxvIGV4cGxvcmFtb3MgbGEgY2xhc2lmaWNhY2lvbiBubyBzdXBlcnZpc2FkYS4gRXhpc3RlbiB2YXJpb3MgYWxnb3JpdG1vcyBkZSBjbGFzaWZpY2FjacOzbiBubyBzdXBlcnZpc2Fkb3MsIHkgbGEgZWxlY2Npb24gZGVsIGFsZ29yaXRtbyBwdWVkZSBhZmVjdGFyIGxvcyByZXN1bHRhZG9zLiBFeHBsb3JhcmVtb3MgdW4gc29sbyBhbGdvcml0bW8gKGstbWVhbnMpIHBhcmEgaWx1c3RyYXIgZWwgcHJpbmNpcGlvIGdlbmVyYWwNCiMNCiMNCiMjIyMjIFBhcmEgZXN0ZSBlamVtcGxvLCBzZWd1aXJlbW9zIGVsIGVzcXVlbWEgZGUgY2xhc2lmaWNhY2lvbiBkZSBsYSAtQmFzZSBkZSBkYXRvcyBuYWNpb25hbCBkZSBjb2JlcnR1cmEgZGUgbGEgdGllcnJhIDIwMTEgKE5MQ0QgMjAxMSktIHBhcmEgU2liYXRlLCBDdW5kaW5hbWFyY2EsIENvbG9tYmlhLiBVdGlsaXphbW9zIGltYWdlbmVzIGNvbXB1ZXN0YXMgc2luIG51YmVzIGRlIExhbmRzYXQgOCBjb24gNyBiYW5kYXMuDQojDQojDQojIyMjIyBTaWJhdGUsIEltYWdlbiBMYW5kU2F0IDggMjAxNSwgdXRpbGl6YW5kbyA3IGJhbmRhcw0KIw0KIw0KYGBge3J9DQpsaWJyYXJ5KHJhc3RlcikNCmxhbmRzYXQ4ID0gc3RhY2soYjIsYjMsYjQsYjUsYjYsYjcpDQpuYW1lcyhsYW5kc2F0OCkgPSBjICgnYmx1ZScsICdncmVlbicsICdyZWQnLCAnTklSJywgJ1NXSVIxJywnU1dJUjInKQ0KcGxvdChsYW5kc2F0OCkNCmBgYA0KIw0KIw0KIyMjIyMgUHJlZ3VudGEgMSA6IEhhZ2EgdW5hIHRyYW1hIGNvbXB1ZXN0YSBkZSAzIGJhbmRhcyBkZSBmYWxzbyBjb2xvciBkZSBgYCBsYW5kc2F0OCAnJy4NCiMNCiMNCmBgYHtyfQ0KIyBBZ3JlZ2Ftb3MgbGEgaW1hZ2VuIGxhbmRzYXQgeSBsZSBoYWNlbW9zIHVuYSBjb21iaW5hY2lvbiBkZSBlbiBmYWxzbyBjb2xvciwgdXRpbGl6YW5kbyBsYSBoZXJyYW1pZW50YSBzdGFjaw0KbGFuZHNhdDhGQ0NfaW1hZ2VuID0gc3RhY2soYjUsIGI2LCBiNCkNCnBsb3RSR0IobGFuZHNhdDhGQ0NfaW1hZ2VuLCBheGVzPVRSVUUsIHN0cmV0Y2g9ImxpbiIsIG1haW49IkxhbmRzYXQgY29tcG9zaWNpb24gZGUgY29sb3IgZmFsc2EgLSBBZ3VhIC8gVGllcnJhIikNCg0KIyByZWNvcnRhbmRvIGEgc2liYXRlIGNvbiBlc2EgbWlzbWEgY29tYmluYWNpb24gZW4gZmFsc28gY29sb3INCg0Kc2liYXRleHRlbmQgPSBzaGFwZWZpbGUoJ0M6L1VzZXJzL0RhdmlkLVBDL0Rlc2t0b3AvRVNDUklUT1JJTy9TSUJBVEVfUlVSQUwvcnVyYWwuc2hwJykNCmV4dCA9IGV4dGVudChzaWJhdGV4dGVuZCkNCmxhbmRzYXRmY2MgPSBjcm9wKGxhbmRzYXQ4RkNDX2ltYWdlbiwgZXh0KQ0KcGxvdFJHQihsYW5kc2F0ZmNjLCBheGVzID0gVFJVRSwgc3RyZXRjaCA9ICJsaW4iLCBtYWluID0gIkxhbmRzYXQgVHJ1ZSBDb2xvciBDb21wb3NpdGUiKQ0KYGBgDQojDQojDQojIyMjIyBFbiBsYSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhLCB1dGlsaXphbW9zIGxvcyBkYXRvcyBkZSByZWZsZWN0YW5jaWEsIHBlcm8gbm8gcHJvcG9yY2lvbmFtb3MgbmluZ3VuIGRhdG8gZGUgcmVzcHVlc3RhIChlcyBkZWNpciwgbm8gaWRlbnRpZmljYW1vcyBuaW5ndW4gcGl4ZWwgY29tbyBwZXJ0ZW5lY2llbnRlIGEgdW5hIGNsYXNlIGVuIHBhcnRpY3VsYXIpLiBFc3RvIHB1ZWRlIHBhcmVjZXIgZXh0cmHDsW8sIHBlcm8gcHVlZGUgc2VyIHV0aWwgY3VhbmRvIG5vIHRlbmVtb3MgbXVjaG8gY29ub2NpbWllbnRvIHByZXZpbyBkZSB1biBhcmVhIGRlIGVzdHVkaW8uIE8gc2kgdGllbmUgdW4gYW1wbGlvIGNvbm9jaW1pZW50byBkZSBsYSBkaXN0cmlidWNpb24gZGUgbGFzIGNsYXNlcyBkZSBpbnRlcmVzIGRlIGxhIGNvYmVydHVyYSBkZWwgc3VlbG8sIHBlcm8gbm8gdGllbmUgZGF0b3MgZXNwZWNpZmljb3MgDQojDQojDQojIyMjIyBFbCBhbGdvcml0bW8gYWdydXBhIHBpeGVsZXMgY29uIGNhcmFjdGVyaXN0aWNhcyBlc3BlY3RyYWxlcyBzaW1pbGFyZXMgZW4gZ3J1cG9zLg0KIw0KIw0KIyMjIyMgT2J0ZW5nYSBtYXMgaW5mb3JtYWNpb24gc29icmUgSy1tZWFucyB5IG90cm9zIGFsZ29yaXRtb3Mgc3VwZXJ2aXNhZG9zIHNpbiBzdXBlcnZpc2lvbiAtYXF1aS0gLg0KIw0KIw0KIyMjIyMgUmVhbGl6YXJlbW9zIHVuYSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhIGVuIHVuIHN1YmNvbmp1bnRvIGVzcGFjaWFsIGRlIGxhIGNhcGEgLW5kdmktLiBBcXVpIGhheSBvdHJhIGZvcm1hIGRlIGNhbGN1bGFyIC1uZHZpLS4gRW4gZXN0ZSBjYXNvLCBubyB1c2Ftb3MgdW5hIGZ1bmNpb24gc2VwYXJhZGEsIHNpbm8gdW5hIG5vdGFjaW9uIGFsZ2VicmFpY2EgZGlyZWN0YS4NCiMNCiMNCmBgYHtyfQ0KIyBHZW5lcmFjaW9uIGRlbCBpbmRpY2Ugbm9ybWFsaXphZG8gZGUgdmVnZXRhY2lvbg0KbmR2aUxhbmRTYXQ4PShsYW5kc2F0OFtbJ05JUiddXS1sYW5kc2F0OFtbJ3JlZCddXSkvKGxhbmRzYXQ4W1snTklSJ11dK2xhbmRzYXQ4W1sncmVkJ11dKQ0KcGxvdChuZHZpTGFuZFNhdDgpDQpgYGANCiMNCiMNCiMjIyMjIEhhcmVtb3MgdW4gYWdydXBhbWllbnRvIC1rbWVhbnMtIGRlIGxvcyBkYXRvcyAtbmR2aS0uICBQcmltZXJvIHVzYW1vcyAtY3JvcC0gcGFyYSBoYWNlciB1biBzdWJjb25qdW50byBlc3BhY2lhbCBkZSAtbmR2aS0sIHBhcmEgcGVybWl0aXIgdW4gcHJvY2VzYW1pZW50byBtYXMgcmFwaWRvIChwdWVkZSBzZWxlY2Npb25hciBjdWFscXVpZXIgLWV4dGVudC0gdXNhbmRvIGxhIGZ1bmNpw7NuIC1kcmF3RXh0ZW50KCkpLg0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gQ0xBU0lGSUNBQ0lPTiBLTUVBTlMgPHNwYW4vPiANCiMNCiMNCmBgYHtyfQ0KIyByZWNvcnRhbmRvIGEgc2liYXRlDQpleHRlbnQobGFuZHNhdDgpDQpsYW5kc2F0OGNyb3AyMDE1ID0gY3JvcChuZHZpTGFuZFNhdDgsIGV4dCkNCmxhbmRzYXQ4Y3JvcDIwMTUNCnBsb3QobGFuZHNhdDhjcm9wMjAxNSkNCg0KIyBjb252ZXJ0aXIgZWwgcmFzdGVyIGEgdmVjdG9yIC8gbWF0cml6DQpucj1nZXRWYWx1ZXMobGFuZHNhdDhjcm9wMjAxNSkNCnN0cihucikNCmBgYA0KIw0KIw0KIyMjIyMgVGVuZ2EgZW4gY3VlbnRhIHF1ZSAtZ2V0VmFsdWVzLSBjb252aXJ0aW8gZWwgUmFzdGVyTGF5ZXIgLW5kdmktIGVuIHVuYSBtYXRyaXogKG1hdHJpeikuIEFob3JhIHJlYWxpemFyZW1vcyBlbCBhZ3J1cGFtaWVudG8gLWttZWFucy0gZW4gbGEgbWF0cml6IGUgaW5zcGVjY2lvbmFyZW1vcyBsYSBzYWxpZGEuDQojDQojDQojIyMjIyBLLW1lYW5zIGVzIHVuIGFsZ29yaXRtbyBkZSBjbGFzaWZpY2FjaW9uIG5vIHN1cGVydmlzYWRhIChjbHVzdGVyaXphY2lvbikgcXVlIGFncnVwYSBvYmpldG9zIGVuIGsgZ3J1cG9zIGJhc2FuZG9zZSBlbiBzdXMgY2FyYWN0ZXJpc3RpY2FzLiBFbCBhZ3J1cGFtaWVudG8gc2UgcmVhbGl6YSBtaW5pbWl6YW5kbyBsYSBzdW1hIGRlIGRpc3RhbmNpYXMgZW50cmUgY2FkYSBvYmpldG8geSBlbCBjZW50cm9pZGUgZGUgc3UgZ3J1cG8gbyBjbHVzdGVyLiBTZSBzdWVsZSB1c2FyIGxhIGRpc3RhbmNpYSBjdWFkcmF0aWNhLg0KIw0KIw0KIyMjIyMgRWwgYWxnb3JpdG1vIGNvbnN0YSBkZSB0cmVzIHBhc29zOg0KIw0KIw0KIyMjIyMgSW5pY2lhbGl6YWNpb246IHVuYSB2ZXogZXNjb2dpZG8gZWwgbnVtZXJvIGRlIGdydXBvcywgaywgc2UgZXN0YWJsZWNlbiBrIGNlbnRyb2lkZXMgZW4gZWwgZXNwYWNpbyBkZSBsb3MgZGF0b3MsIHBvciBlamVtcGxvLCBlc2NvZ2llbmRvbG9zIGFsZWF0b3JpYW1lbnRlLiANCiMNCiMNCiMjIyMjIDEuQXNpZ25hY2lvbiBvYmpldG9zIGEgbG9zIGNlbnRyb2lkZXM6IGNhZGEgb2JqZXRvIGRlIGxvcyBkYXRvcyBlcyBhc2lnbmFkbyBhIHN1IGNlbnRyb2lkZSBtYXMgY2VyY2Fuby4NCiMjIyMjIDIuQWN0dWFsaXphY2lvbiBjZW50cm9pZGVzOiBzZSBhY3R1YWxpemEgbGEgcG9zaWNpb24gZGVsIGNlbnRyb2lkZSBkZSBjYWRhIGdydXBvIHRvbWFuZG8gY29tbyBudWV2byBjZW50cm9pZGUgbGEgcG9zaWNpb24gZGVsIHByb21lZGlvIGRlIGxvcyBvYmpldG9zIHBlcnRlbmVjaWVudGVzIGEgZGljaG8gZ3J1cG8uDQojIyMjIyAzLlNlIHJlcGl0ZW4gbG9zIHBhc29zIDIgeSAzIGhhc3RhIHF1ZSBsb3MgY2VudHJvaWRlcyBubyBzZSBtdWV2ZW4sIG8gc2UgbXVldmVuIHBvciBkZWJham8gZGUgdW5hIGRpc3RhbmNpYSB1bWJyYWwgZW4gY2FkYSBwYXNvLg0KIw0KIw0KI0VsIGFsZ29yaXRtbyBrLW1lYW5zIHJlc3VlbHZlIHVuIHByb2JsZW1hIGRlIG9wdGltaXphY2lvbiwgc2llbmRvIGxhIGZ1bmNpb24gYSBvcHRpbWl6YXIgKG1pbmltaXphcikgbGEgc3VtYSBkZSBsYXMgZGlzdGFuY2lhcyBjdWFkcmF0aWNhcyBkZSBjYWRhIG9iamV0byBhbCBjZW50cm9pZGUgZGUgc3UgY2x1c3Rlci4NCiMNCiMNCmBgYHtyfQ0KIyBFcyBpbXBvcnRhbnRlIGNvbmZpZ3VyYXIgZWwgZ2VuZXJhZG9yIGRlIHNlbWlsbGFzIHBvcnF1ZSBga21lYW5zYCBpbmljaWEgbG9zIGNlbnRyb3MgZW4gdWJpY2FjaW9uZXMgYWxlYXRvcmlhcywgcGFyYSBlc28gdXRpbGl6YXJlbW9zIHNldC5zZWVkDQpzZXQuc2VlZCAoOTkpDQoNCiMgUXVlcmVtb3MgY3JlYXIgMTAgZ3J1cG9zLCBwZXJtaXRpciA1MDAgaXRlcmFjaW9uZXMsIGNvbWVuemFyIGNvbiA1IGNvbmp1bnRvcyBhbGVhdG9yaW9zIHV0aWxpemFuZG8gZWwgbcOpdG9kbyAiTGxveWQiDQprbW5jbHVzdGVyID0ga21lYW5zKG5hLm9taXQobnIpLCBjZW50ZXJzID0gMTAsIGl0ZXIubWF4ID0gNTAwLCBuc3RhcnQgPSA1LCBhbGdvcml0aG0gPSAiTGxveWQiKQ0KDQojIGttZWFucyBkZXZ1ZWx2ZSB1biBvYmpldG8gZGUgbGEgY2xhc2UgImttZWFucyINCnN0cihrbW5jbHVzdGVyKQ0KYGBgDQojDQojDQojIyMjIyAta21lYW5zLWRldnVlbHZlIHVuIG9iamV0byBjb24gOSBlbGVtZW50b3MuIExhIGxvbmdpdHVkIGRlbCBlbGVtZW50byAtY2x1c3Rlci0gZGVudHJvIC1rbW5jbHVzdGVyLSBlcyAyMTY1NjcgcXVlIGVzIGlndWFsIGEgbGEgbG9uZ2l0dWQgZGUgLW5yLSBjcmVhZG8gZGVzZGUgLW5kdmktLiBMb3MgdmFsb3JlcyBkZSBjZWxkYSBkZSByYW5nbyAta21uY2x1c3RlcmNsdXN0ZXItIGVudHJlIDEgYSAxMCBjb3JyZXNwb25kaWVudGVzIGFsIG51bWVybyBkZSBlbnRyYWRhIGRlbCBjbHVzdGVyIHF1ZSBwcm9wb3JjaW9uYW1vcyBlbiBsYSBmdW5jaW9uIC1rbWVhbnMtLiAgLWttbmNsdXN0ZXIkY2x1c3Rlci0gaW5kaWNhIGxhIGV0aXF1ZXRhIGRlbCBjbHVzdGVyIHBhcmEgZWwgcGl4ZWwgY29ycmVzcG9uZGllbnRlLiBOZWNlc2l0YW1vcyBjb252ZXJ0aXIgbG9zIHZhbG9yZXMgLWttbmNsdXN0ZXIkY2x1c3Rlci0gbnVldmFtZW50ZSBhIFJhc3RlckxheWVyIGRlIGxhIG1pc21hIGRpbWVuc2lvbiBxdWUgLW5kdmktLg0KIw0KIw0KYGBge3J9DQojIFVzZSBlbCBvYmpldG8gbmR2aSAoZW4gZXN0ZSBjYXNvIHNlIGxsYW1hICJsYW5kc2F0OGNyb3AyMDE1IikgcGFyYSBlc3RhYmxlY2VyIGxvcyB2YWxvcmVzIGRlbCBjbHVzdGVyIGVuIHVuIG51ZXZvIHJhc3Rlcg0Ka25yID0gc2V0VmFsdWVzKGxhbmRzYXQ4Y3JvcDIwMTUsIGttbmNsdXN0ZXIkY2x1c3RlcikNCg0KIyBUYW1iaWVuIHB1ZWRlcyBoYWNlcmxvIGFzaQ0Ka25yPSByYXN0ZXIobGFuZHNhdDhjcm9wMjAxNSkNCnZhbHVlcyhrbnIpID0ga21uY2x1c3RlciRjbHVzdGVyDQprbnINCg0KYGBgDQojDQojDQojIyMjIyBQb2RlbW9zIHZlciBxdWUgLWtuci0gZXMgdW4gUmFzdGVyTGF5ZXIsIHBlcm8gbm8gc2FiZW1vcyBxdWUgZ3J1cG8gKDEtMTApIHBlcnRlbmVjZSBhIHF1ZSBjbGFzZSBkZSBjb2JlcnR1cmEgdGVycmVzdHJlICh5IHNpIHBlcnRlbmVjZSBhIHVuYSBjbGFzZSBxdWUgcmVjb25vY2VyaWFtb3MpLiBQdWVkZSBhdmVyaWd1YXJsbyB0cmF6YW5kb2xvcyBsYWRvIGEgbGFkbyBjb24gY2FwYXMgZGUgcmVmZXJlbmNpYSB5IHVzYW5kbyB1biBjb2xvciB1bmljbyBwYXJhIGNhZGEgZ3J1cG8uDQojDQojDQpgYGB7cn0NCiNEZWZpbmEgdW4gdmVjdG9yIGRlIGNvbG9yIHBhcmEgMTAgZ3J1cG9zIChtYXMgaW5mb3JtYWNpb24gc29icmUgY29tbyBjb25maWd1cmFyIGVsIGNvbG9yIG1hcyBhZGVsYW50ZSkNCg0KbXljb2xvciA9IGMgKCIjZmVmNjViIiwiI2ZmMDAwMCIsICIjZGFhNTIwIiwiIzAwMDBmZiIsIiMwMDAwZmYiLCIjMDBmZjAwIiwiI2NiYmViNSIsDQogICAgICAgICAgICAgIiNjM2ZmNWIiLCAiI2ZmNzM3MyIsICIjMDBmZjAwIiwgIiM4MDgwODAiKQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGxvdChsYW5kc2F0OGNyb3AyMDE1LCBjb2wgPSByZXYodGVycmFpbi5jb2xvcnMoMTApKSwgbWFpbiA9ICdMYW5kc2F0LU5EVkknKQ0KcGxvdChrbnIsIG1haW4gPSAnVW5zdXBlcnZpc2VkIGNsYXNzaWZpY2F0aW9uJywgY29sID0gbXljb2xvciApDQoNCmBgYA0KIw0KIw0KIyMjIyMgU2kgYmllbiBwYXJhIG90cm9zIGZpbmVzIHN1ZWxlIHNlciBtZWpvciBkZWZpbmlyIG1hcyBjbGFzZXMgKHkgcG9zaWJsZW1lbnRlIGZ1c2lvbmFyIGNsYXNlcyBtYXMgYWRlbGFudGUpLCB1bmEgY2xhc2lmaWNhY2lvbiBzaW1wbGUgY29tbyBlc3RhIHBvZHJpYSBzZXIgdXRpbCwgcG9yIGVqZW1wbG8sIGZ1c2lvbmFyIGxvcyBncnVwb3MgNCB5IDUgcGFyYSBjb25zdHJ1aXIgdW5hIG1hc2NhcmEgZGUgYWd1YSBwYXJhIGVsIGHDsW8gMjAxNS4NCiMNCiMNCiMjIyMjIFB1ZWRlcyBjYW1iaWFyIGxvcyBjb2xvcmVzIGVuIG1pIC1teWNvbG9yLS4gT2J0ZW5nYSBtYXMgaW5mb3JtYWNpb24gc29icmUgbGEgc2VsZWNjaW9uIGRlIGNvbG9yZXMgZW4gUiAtYXF1aS0geSAtYXF1aS0gLg0KIw0KDQojIyMjIyBQcmVndW50YSAyIDogR3JhZmlxdWUgZWwgUkdCIGRlIDMgYmFuZGFzIGRlICAibGFuZHNhdDgiIHBhcmEgZWwgc3ViY29uanVudG8gKGV4dGVuc2nDs24gImV4dCIpIHkgZWwgcmVzdWx0YWRvIGRlIGxhIGFncnVwYWNpb24gImttZWFucyIgbGFkbyBhIGxhZG8geSBoYWdhIHVuYSB0YWJsYSBkZSBjb2JlcnR1cmEgZGVsIHN1ZWxvIHBhcmEgZWwgdXNvIGRlbCBzdWVsbyBFdGlxdWV0YXMgcGFyYSBsb3MgZ3J1cG9zLiBQb3IgZWplbXBsbywgbG9zIGdydXBvcyA0IHkgNSBzb24gYWd1YS4NCiMNCiMNCmBgYHtyfQ0KbGFuZHNhdDhwMiA9IHN0YWNrKGI2LCBiMywgYjIpDQoNCiMgUmVjb3J0ZSBkZSBsYW5kc2F0IGNvbiBzaWJhdGUNCmxhbmRzYXRzaWJhdGVwMiA9IGNyb3AobGFuZHNhdDhwMiwgZXh0KQ0KcGxvdFJHQihsYW5kc2F0c2liYXRlcDIsIGF4ZXMgPSBUUlVFLCBzdHJldGNoID0gImxpbiIsIG1haW4gPSAiTGFuZHNhdCBGQ0MgLSBTSUJBVEUiKQ0KDQojIGNvbnZlcnRpciBlbCByYXN0ZXIgYSB2ZWN0b3IgLyBtYXRyaXoNCm5yX3AyPWdldFZhbHVlcyhsYW5kc2F0c2liYXRlcDIpDQpzdHIobnJfcDIpDQoNCg0KIyBFcyBpbXBvcnRhbnRlIGNvbmZpZ3VyYXIgZWwgZ2VuZXJhZG9yIGRlIHNlbWlsbGFzIHBvcnF1ZSBga21lYW5zYCBpbmljaWEgbG9zIGNlbnRyb3MgZW4gdWJpY2FjaW9uZXMgYWxlYXRvcmlhcywgcGFyYSBlc28gdXRpbGl6YXJlbW9zIHNldC5zZWVkDQpzZXQuc2VlZCAoOTkpDQoNCiMgUXVlcmVtb3MgY3JlYXIgMTAgZ3J1cG9zLCBwZXJtaXRpciA1MDAgaXRlcmFjaW9uZXMsIGNvbWVuemFyIGNvbiA1IGNvbmp1bnRvcyBhbGVhdG9yaW9zIHV0aWxpemFuZG8gZWwgbcOpdG9kbyAiTGxveWQiDQprbW5jbHVzdGVyX3AyID0ga21lYW5zKG5hLm9taXQobnIpLCBjZW50ZXJzID0gMTAsIGl0ZXIubWF4ID0gNTAwLCBuc3RhcnQgPSA1LCBhbGdvcml0aG0gPSAiTGxveWQiKQ0KDQojIGttZWFucyBkZXZ1ZWx2ZSB1biBvYmpldG8gZGUgbGEgY2xhc2UgImttZWFucyINCnN0cihrbW5jbHVzdGVyX3AyKQ0KDQojIFVzZSBlbCBvYmpldG8gbmR2aSAoZW4gZXN0ZSBjYXNvIHNlIGxsYW1hICJsYW5kc2F0c2liYXRlcDIiKSBwYXJhIGVzdGFibGVjZXIgbG9zIHZhbG9yZXMgZGVsIGNsdXN0ZXIgZW4gdW4gbnVldm8gcmFzdGVyDQprbnJfcDIgPSBzZXRWYWx1ZXMobGFuZHNhdHNpYmF0ZXAyLCBrbW5jbHVzdGVyX3AyJGNsdXN0ZXIpDQoNCiMgVGFtYmllbiBwdWVkZXMgaGFjZXJsbyBhc2kNCmtucl9wMj0gcmFzdGVyKGxhbmRzYXRzaWJhdGVwMikNCnZhbHVlcyhrbnJfcDIpID0ga21uY2x1c3Rlcl9wMiRjbHVzdGVyDQprbnJfcDINCg0KI0RlZmluYSB1biB2ZWN0b3IgZGUgY29sb3IgcGFyYSAxMCBncnVwb3MgKG1hcyBpbmZvcm1hY2lvbiBzb2JyZSBjb21vIGNvbmZpZ3VyYXIgZWwgY29sb3IgbWFzIGFkZWxhbnRlKQ0KI215Y29sb3JfcDIgPSBjICh0b3BvLmNvbG9ycygxMCkpDQpwbG90KGtucl9wMiwgbWFpbiA9ICdVbnN1cGVydmlzZWQgY2xhc3NpZmljYXRpb24nLCBjb2wgPSByZXYodG9wby5jb2xvcnMoMTApKSkgDQpgYGANCiMNCiMNCiMNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gQ0FQSVRVTE8gMyA8c3Bhbi8+IA0KIw0KIw0KIw0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gQ0xBU0lGSUNBQ0lPTiBTVVBFUlZJU0FEQSA8c3Bhbi8+IA0KIw0KIw0KIyMjIyMgQXF1aSBleHBsb3JhbW9zIGxhIGNsYXNpZmljYWNpb24gc3VwZXJ2aXNhZGEuIEV4aXN0ZW4gdmFyaW9zIGFsZ29yaXRtb3MgZGUgY2xhc2lmaWNhY2lvbiBzdXBlcnZpc2Fkb3MsIHkgbGEgZWxlY2Npb24gZGVsIGFsZ29yaXRtbyBwdWVkZSBhZmVjdGFyIGxvcyByZXN1bHRhZG9zLiBBcXVpIGV4cGxvcmFtb3MgZG9zIGFsZ29yaXRtb3MgcmVsYWNpb25hZG9zIChSYW5kb21Gb3Jlc3QgeSBhcmJvbCBkZSBkZWNpc2lvbikuDQojDQojDQojIyMjIyBFbiBsYSBjbGFzaWZpY2FjaW9uIHN1cGVydmlzYWRhLCB0ZW5lbW9zIGNvbm9jaW1pZW50byBwcmV2aW8gc29icmUgYWxndW5vcyBkZSBsb3MgdGlwb3MgZGUgY29iZXJ0dXJhIGRlbCBzdWVsbyBtZWRpYW50ZSwgcG9yIGVqZW1wbG8sIHRyYWJham8gZGUgY2FtcG8sIGRhdG9zIGVzcGFjaWFsZXMgZGUgcmVmZXJlbmNpYSBvIGludGVycHJldGFjacOzbiBkZSBpbWFnZW5lcyBkZSBhbHRhIHJlc29sdWNpb24gKGNvbW8gbGFzIGRpc3BvbmlibGVzIGVuIGxvcyBtYXBhcyBkZSBHb29nbGUpLiBTZSBpZGVudGlmaWNhbiBzaXRpb3MgZXNwZWNpZmljb3MgZW4gZWwgYXJlYSBkZSBlc3R1ZGlvIHF1ZSByZXByZXNlbnRhbiBlamVtcGxvcyBob21vZ2VuZW9zIGRlIGVzdG9zIHRpcG9zIGRlIGNvYmVydHVyYSB0ZXJyZXN0cmUgY29ub2NpZG9zLiBFc3RhcyBhcmVhcyBzZSBjb25vY2VuIGNvbXVubWVudGUgY29tbyBzaXRpb3MgZGUgZW50cmVuYW1pZW50byBwb3JxdWUgbGFzIHByb3BpZWRhZGVzIGVzcGVjdHJhbGVzIGRlIGVzdG9zIHNpdGlvcyBzZSB1c2FuIHBhcmEgZW50cmVuYXIgZWwgYWxnb3JpdG1vIGRlIGNsYXNpZmljYWNpb24uDQojDQojDQpgYGB7cn0NCiMgRGlyZWN0b3JpbyBkZSB0cmFiYWpvDQoNCnNldHdkKCJDOi9Vc2Vycy9EYXZpZC1QQy9EZXNrdG9wL0VTQ1JJVE9SSU8vTGFuZHNhdF9wcm9jZXNhbWllbnRvLyIpDQoNCiMgSW1wb3J0YXIgbGFzIGltYWdlbmVzIGRlc2RlIGxhIGJhbmRhIDIgYSBsYSBiYW5kYSA3DQpCMiA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0IyLlRJRiIpDQpCMyA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0IzLlRJRiIpDQpCNCA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I0LlRJRiIpDQpCNSA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I1LlRJRiIpDQpCNiA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I2LlRJRiIpDQpCNyA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0I3LlRJRiIpDQoNCiMgRGF0b3MgaW1hZ2VuIE1UTCwgZXMgZGVjaXIgZWwgbWV0YWRhdG8uIEVzdG9zIGRhdG9zIHNlIGluZ3Jlc2FuIGRlIGZvcm1hIG1hbnVhbA0KIyBTZSByZWxhY2lvbmEgZWwgZGlhIGp1bGlhbm8gZGUgbGEgaW1hZ2VuOyBlc3RlIGRhdG8gc2UgcmVsYWNpb25hIGVuIGVsIE1UTA0KZGlhIDwtIDAwNA0KIyBJbmNsdWltb3MgbGEgZWxldmFjaW9uIHNvbGFyIGVuIGdyYWRvcyByYWRpYW5lcywgdGFsIGNvbW8gYXBhcmVjZSBlbiBlbCBNVEwNClNVTl9FTEVWQVRJT04gPSA1MS44OTEzNDUzOQ0KIyBFc3RvcyBkYXRvcyBzb24gaW1wb3J0YW50ZXMgcGFyYSBsYSB0cmFuc2Zvcm1hY2lvbiBkZSBORCBhIGRhdG9zIGRlIHJlZmxlY3RhbmNpYSBkZSBzdXBlcmZpY2llDQpSQURJQU5DRV9NVUxUX0JBTkRfMiA9IDEuMzI5OEUtMDINClJBRElBTkNFX01VTFRfQkFORF8zID0gMS4yMjU0RS0wMg0KUkFESUFOQ0VfTVVMVF9CQU5EXzQgPSAxLjAzMzNFLTAyDQpSQURJQU5DRV9NVUxUX0JBTkRfNSA9IDYuMzIzNkUtMDMNClJBRElBTkNFX01VTFRfQkFORF82ID0gMS41NzI2RS0wMw0KUkFESUFOQ0VfTVVMVF9CQU5EXzcgPSA1LjMwMDZFLTA0DQoNClJBRElBTkNFX0FERF9CQU5EXzIgPSAtNjYuNDkxNDENClJBRElBTkNFX0FERF9CQU5EXzMgPSAtNjEuMjcxMjYNClJBRElBTkNFX0FERF9CQU5EXzQgPSAtNTEuNjY3MzgNClJBRElBTkNFX0FERF9CQU5EXzUgPSAtMzEuNjE3ODYNClJBRElBTkNFX0FERF9CQU5EXzYgPSAtNy44NjMwNw0KUkFESUFOQ0VfQUREX0JBTkRfNyA9IC0yLjY1MDI4DQoNClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8yID0gMS4yMTA3MDANClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF8zID0gMS4yMTA3MDANClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF80ID0gMS4yMTA3MDANClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF81ID0gMS4yMTA3MDANClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF82ID0gMS4yMTA3MDANClJFRkxFQ1RBTkNFX01BWElNVU1fQkFORF83ID0gMS4yMTA3MDANCg0KUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzIgPSA4MDUuMDExNDENClJBRElBTkNFX01BWElNVU1fQkFORF8zID0gNzQxLjgxMTE2DQpSQURJQU5DRV9NQVhJTVVNX0JBTkRfNCA9IDYyNS41MzY5OQ0KUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzUgPSAzODIuNzk3NDINClJBRElBTkNFX01BWElNVU1fQkFORF82ID0gOTUuMTk4MjMNClJBRElBTkNFX01BWElNVU1fQkFORF83ID0gMzIuMDg2OTANCg0KIyBDb252ZXJzaW9uIGEgdHJhdmVzIGRlIGxhIGZvcm11bGEgDQpTVU5fRUxFVkFUSU9OX1IgPC0gU1VOX0VMRVZBVElPTipwaS8xODAgICMgcmFkaWFuZXMNCiMgY29uIGVzdGEgZm9ybXVsYSBkZXRlcm1pbmFtb3MgbGEgZGlzdGFuY2lhIGRlbCBzb2wgYSBsYSB0aWVycmENCmQgPC0gMSswLjAxNjcqKHNpbigoMipwaSooZGlhLTkzLjUpKS8zNjUpKSAjIGRpc3RhbmNpYSBkZWwgc29sIGEgbGEgdGllcnJhDQoNCiMgRGV0ZXJtaW5hY2lvbiBFU1VODQpFU1VOMiA8LSBwaSooZF4yKSpSQURJQU5DRV9NQVhJTVVNX0JBTkRfMi9SRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfMg0KRVNVTjMgPC0gcGkqKGReMikqUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzMvUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzMNCkVTVU40IDwtIHBpKihkXjIpKlJBRElBTkNFX01BWElNVU1fQkFORF80L1JFRkxFQ1RBTkNFX01BWElNVU1fQkFORF80DQpFU1VONSA8LSBwaSooZF4yKSpSQURJQU5DRV9NQVhJTVVNX0JBTkRfNS9SRUZMRUNUQU5DRV9NQVhJTVVNX0JBTkRfNQ0KRVNVTjYgPC0gcGkqKGReMikqUkFESUFOQ0VfTUFYSU1VTV9CQU5EXzYvUkVGTEVDVEFOQ0VfTUFYSU1VTV9CQU5EXzYNCkVTVU43IDwtIHBpKihkXjIpKlJBRElBTkNFX01BWElNVU1fQkFORF83L1JFRkxFQ1RBTkNFX01BWElNVU1fQkFORF83DQoNCiMgRWxpbWFyIHZhbG9yZXMgbnVsb3MsIGVzIGRlY2lyIHF1ZSB0b2RvcyBsb3MgdmFsb3JlcyBpZ3VhbGVzIGEgY2VybyBzZXJhbiBlbGltaW5hZG9zIA0KQjJbQjI9PTBdIDwtIE5BDQpCM1tCMz09MF0gPC0gTkENCkI0W0I0PT0wXSA8LSBOQQ0KQjVbQjU9PTBdIDwtIE5BDQpCNltCNj09MF0gPC0gTkENCkI3W0I3PT0wXSA8LSBOQQ0KDQojIERldGVybWluYWNpb24gZGUgcmFkaWFuY2lhIHNlbnNvcg0KTDIgPC0gUkFESUFOQ0VfTVVMVF9CQU5EXzIqQjIgKyBSQURJQU5DRV9BRERfQkFORF8yDQpMMyA8LSBSQURJQU5DRV9NVUxUX0JBTkRfMypCMyArIFJBRElBTkNFX0FERF9CQU5EXzMNCkw0IDwtIFJBRElBTkNFX01VTFRfQkFORF80KkI0ICsgUkFESUFOQ0VfQUREX0JBTkRfNA0KTDUgPC0gUkFESUFOQ0VfTVVMVF9CQU5EXzUqQjUgKyBSQURJQU5DRV9BRERfQkFORF81DQpMNiA8LSBSQURJQU5DRV9NVUxUX0JBTkRfNipCNiArIFJBRElBTkNFX0FERF9CQU5EXzYNCkw3IDwtIFJBRElBTkNFX01VTFRfQkFORF83KkI3ICsgUkFESUFOQ0VfQUREX0JBTkRfNw0KDQojIERldGVybWluYWNpb24gZGUgbGEgcmFkaWFuY2lhIG1pbmltYQ0KTG1pbjIgPC0gUkFESUFOQ0VfTVVMVF9CQU5EXzIqbWluKGdldFZhbHVlcyhCMiksIG5hLnJtID0gVFJVRSkrIFJBRElBTkNFX0FERF9CQU5EXzINCkxtaW4zIDwtIFJBRElBTkNFX01VTFRfQkFORF8zKm1pbihnZXRWYWx1ZXMoQjMpLCBuYS5ybSA9IFRSVUUpKyBSQURJQU5DRV9BRERfQkFORF8zDQpMbWluNCA8LSBSQURJQU5DRV9NVUxUX0JBTkRfNCptaW4oZ2V0VmFsdWVzKEI0KSwgbmEucm0gPSBUUlVFKSsgUkFESUFOQ0VfQUREX0JBTkRfNA0KTG1pbjUgPC0gUkFESUFOQ0VfTVVMVF9CQU5EXzUqbWluKGdldFZhbHVlcyhCNSksIG5hLnJtID0gVFJVRSkrIFJBRElBTkNFX0FERF9CQU5EXzUNCkxtaW42IDwtIFJBRElBTkNFX01VTFRfQkFORF82Km1pbihnZXRWYWx1ZXMoQjYpLCBuYS5ybSA9IFRSVUUpKyBSQURJQU5DRV9BRERfQkFORF82DQpMbWluNyA8LSBSQURJQU5DRV9NVUxUX0JBTkRfNyptaW4oZ2V0VmFsdWVzKEI3KSwgbmEucm0gPSBUUlVFKSsgUkFESUFOQ0VfQUREX0JBTkRfNw0KDQojIERldGVybWluYWNpb24gcmFkaWFuY2lhIGRlbCBvYmpldG8gb3NjdXJvDQpMRE9TMiA8LSAwLjAxKkVTVU4yKnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQpMRE9TMyA8LSAwLjAxKkVTVU4zKnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQpMRE9TNCA8LSAwLjAxKkVTVU40KnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQpMRE9TNSA8LSAwLjAxKkVTVU41KnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQpMRE9TNiA8LSAwLjAxKkVTVU42KnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQpMRE9TNyA8LSAwLjAxKkVTVU43KnNpbihTVU5fRUxFVkFUSU9OX1IpL3BpKihkXjIpDQoNCiMgRGV0ZXJtaW5hciBlbCBlZmVjdG8gYnJ1bWENCkxQMiA8LSBMbWluMi1MRE9TMg0KTFAzIDwtIExtaW4zLUxET1MzDQpMUDQgPC0gTG1pbjQtTERPUzQNCkxQNSA8LSBMbWluNS1MRE9TNQ0KTFA2IDwtIExtaW42LUxET1M2DQpMUDcgPC0gTG1pbjctTERPUzcNCg0KIyBCYW5kYSBSZWZsZWN0YW5jaWEgU3VwZXJmaWNpZSBEYXJrIE9iamVjdCBTdWJzdHJjdGlvbiAoRE9TKQ0KUlNfZG9zX0IyIDwtIChwaSooTDItTFAyKSooZCleMikvKEVTVU4yKnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KUlNfZG9zX0IzIDwtIChwaSooTDMtTFAzKSooZCleMikvKEVTVU4zKnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KUlNfZG9zX0I0IDwtIChwaSooTDQtTFA0KSooZCleMikvKEVTVU40KnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KUlNfZG9zX0I1IDwtIChwaSooTDUtTFA1KSooZCleMikvKEVTVU41KnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KUlNfZG9zX0I2IDwtIChwaSooTDYtTFA2KSooZCleMikvKEVTVU42KnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KUlNfZG9zX0I3IDwtIChwaSooTDctTFA3KSooZCleMikvKEVTVU43KnNpbihTVU5fRUxFVkFUSU9OX1IpKQ0KDQojIENvbWJpbmFjaW9uIGRlIGJhbmRhcyBhIHRyYXZleiBkZSBsYSBoZXJyYW1pZW50YSBzdGFjaw0KTDhfQjIzNDU2N19SU19ET1MgPC0gc3RhY2soUlNfZG9zX0IyLFJTX2Rvc19CMyxSU19kb3NfQjQsUlNfZG9zX0I1LFJTX2Rvc19CNixSU19kb3NfQjcpDQoNCiMgRXhwb3J0YWNpb24gaW1hZ2VuIHJlZmxlY3RhbmNpYSBTdXBlcmZpZSBET1MNCiNzZXR3ZCgiQzovVXNlcnMvRGF2aWQtUEMvRGVza3RvcC9FU0NSSVRPUklPL0xhbmRzYXRfcHJvY2VzYW1pZW50by9TSEFQRS8iKQ0Kd3JpdGVSYXN0ZXIoTDhfQjIzNDU2N19SU19ET1MsIkw4X0IyMzQ1NjdfUlNfRE9TMS50aWYiLCBkcml2ZXJuYW1lPSJHdGlmZiIsIG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQojDQojDQpgYGB7cn0NCg0KIyMgVGVtcGVyYXR1cmEgZGUgYnJpbGxvIGRlIExhbmRzYXQgOCBUSVJTDQoNCg0KIyBJbXBvcnRhciBsYXMgaW1hZ2VuZXMNCkIxMCA9IHJhc3RlcigiTEMwOF9MMVRQXzAwODA1N18yMDE1MDEwNF8yMDE3MDQxNV8wMV9UMS9MQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxX0IxMC5USUYiKQ0KQjExID0gcmFzdGVyKCJMQzA4X0wxVFBfMDA4MDU3XzIwMTUwMTA0XzIwMTcwNDE1XzAxX1QxL0xDMDhfTDFUUF8wMDgwNTdfMjAxNTAxMDRfMjAxNzA0MTVfMDFfVDFfQjExLlRJRiIpDQoNCiMgSyBpbWFnZW4gTGFuZHNhdCA4IFRJUlMNCksxX0NPTlNUQU5UX0JBTkRfMTAgPSA3NzQuODg1Mw0KSzJfQ09OU1RBTlRfQkFORF8xMCA9IDEzMjEuMDc4OQ0KSzFfQ09OU1RBTlRfQkFORF8xMSA9IDQ4MC44ODgzDQpLMl9DT05TVEFOVF9CQU5EXzExID0gMTIwMS4xNDQyDQoNCiMgRGF0b3MgZGUgcmFkaWFuY2lhIGRlbCBzZW5zb3IgaW1hZ2VuIExhbmRzYXQNClJBRElBTkNFX01VTFRfQkFORF8xMCA9IDMuMzQyMEUtMDQNClJBRElBTkNFX01VTFRfQkFORF8xMSA9IDMuMzQyMEUtMDQNCg0KUkFESUFOQ0VfQUREX0JBTkRfMTAgPSAwLjEwMDAwDQpSQURJQU5DRV9BRERfQkFORF8xMSA9IDAuMTAwMDANCg0KIyBFbGltYXIgdmFsb3JlcyBudWxvcw0KQjEwW0IxMD09MF0gPC0gTkENCkIxMVtCMTE9PTBdIDwtIE5BDQoNCiMgRGV0ZXJtaW5hbmNpb24gZGUgbGEgUmFkaWFuY2ENCkwxMCA8LSBSQURJQU5DRV9NVUxUX0JBTkRfMTAqKG5hLm9taXQoQjEwKSkgKyBSQURJQU5DRV9BRERfQkFORF8xMA0KTDExIDwtIFJBRElBTkNFX01VTFRfQkFORF8xMSoobmEub21pdChCMTEpKSArIFJBRElBTkNFX0FERF9CQU5EXzExDQoNCg0KIyBEZXRlcm1pbmFjaW9uIFRlbXBlcmF0dXJhIGRlIGJyaWxsbyBDZWxzaXVzDQpUQl9CMTAgPC0gSzJfQ09OU1RBTlRfQkFORF8xMC9sb2coSzFfQ09OU1RBTlRfQkFORF8xMC9MMTArMSkgLSAyNzMuMTUNClRCX0IxMSA8LSBLMl9DT05TVEFOVF9CQU5EXzExL2xvZyhLMV9DT05TVEFOVF9CQU5EXzExL0wxMSsxKSAtIDI3My4xNQ0KDQojIEV4cG9ydGFjaW9uIGltYWdlbiBUZW1wZXJhdHVyYSBkZSBicmlsbG8gQ2Vsc2l1cw0Kd3JpdGVSYXN0ZXIoVEJfQjEwLCJMOF9UQl9CMTAudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoVEJfQjExLCJMOF9UQl9CMTEudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0KDQpgYGANCiMNCiMNCiMjIyMjIFVzdWFsbWVudGUsIGxhIGNsYXNpZmljYWNpb24gc3VwZXJ2aXNhZGEgcmVxdWllcmUgcXVlIGVsIHVzdWFyaW8gc2VsZWNjaW9uZSB1bmEgbyBtw6FzIFJlZ2lvbmVzIGRlIEludGVyZXMgKFJPSXMsIG8gw4FyZWFzIGRlIEVudHJlbmFtaWVudG8pIHBhcmEgY2FkYSBjbGFzZSBkZSBjb2JlcnR1cmEgZGVsIHN1ZWxvIGlkZW50aWZpY2FkYSBlbiBsYSBpbWFnZW4uIExhcyBST0lzIHNvbiBwb2xpZ29ub3MgbyBwdW50b3MgZGlidWphZG9zIHNvYnJlIGFyZWFzIGhvbW9nZW5lYXMgZGUgbGEgaW1hZ2VuIHF1ZSBzZSBzdXBlcnBvbmVuIGEgcGl4ZWxlcyBwZXJ0ZW5lY2llbnRlcyBhIGxhIG1pc21hIGNsYXNlIGRlIGNvYmVydHVyYSBkZWwgc3VlbG8uDQojDQojDQpgYGB7cn0NCiMjUmVwcm95ZWN0YXIgeSByZWNvcnRlIGRlIGltYWdlcyBjb24gbGEgem9uYSBkZSBlc3R1ZGlvIExhbmRzYXQgOCBPTEkNCg0KIyBJbXBvcnRhciBsYXMgaW1hZ2VuDQpMOF9CMjM0NTY3X1JTX0RPUyA9IHN0YWNrKCJMOF9CMjM0NTY3X1JTX0RPUzEudGlmIikNCg0KIyBWZXJpZmljYXIgc2lzdGVtYXMgZGUgY29vcmRlbmFkYQ0Kc3RfY3JzKEw4X0IyMzQ1NjdfUlNfRE9TKQ0KDQojIFJlcHJveWVjdGFyIGltYWdlbg0KTDhfQjIzNDU2N19SU19ET1NfcHkgPSBwcm9qZWN0UmFzdGVyKEw4X0IyMzQ1NjdfUlNfRE9TLCBjcnMgPSAiK2luaXQ9ZXBzZzozMjYxOCIpDQoNCiMjIGltcG9ydGFyIHNoYXBlZmlsZQ0KWm9uYV9VVE1fMThuIDwtIHNoYXBlZmlsZSgicnVyYWwuc2hwIikNCnN0X2Nycyhab25hX1VUTV8xOG4pDQoNCiMgUmVjb3J0YXIgaW1hZ2VuIHNlZ3VuIHNoYXBlZmlsZSBMYW5kc2F0IDggZXh0ZW5zaW9uDQpjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5IDwtIGNyb3AoTDhfQjIzNDU2N19SU19ET1NfcHksWm9uYV9VVE1fMThuKQ0KDQojIFZpc3VhbGl6YWNpb24gZGVsIHJlY29ydGUgZGUgbGEgem9uYSBkZSBlc3R1ZGlvDQpwbG90UkdCKGNsaXBfTDhfQjIzNDU2N19SU19ET1NfcHksIDUsNCwzLCBzdHJldGNoID0gImxpbiIpDQoNCiMgR3VhcmRhciBhcmNoaXZvIHBvciBiYW5kYSByZWNvcnRhZGEgeSBwcm95ZWN0YWRhDQpMOF9TUl9CMiA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS4xDQpMOF9TUl9CMyA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS4yDQpMOF9TUl9CNCA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS4zDQpMOF9TUl9CNSA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS40DQpMOF9TUl9CNiA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS41DQpMOF9TUl9CNyA8LSBjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5JEw4X0IyMzQ1NjdfUlNfRE9TMS42DQoNCiMgRXhwb3J0YWNpb24gaW1hZ2VuIHJlZmxlY3RhbmNpYSBTdXBlcmZpZSBET1MxIFByb3llY3RhZG8geSByZWNvcnRhZG8NCndyaXRlUmFzdGVyKGNsaXBfTDhfQjIzNDU2N19SU19ET1NfcHksImNsaXBfTDhfQjIzNDU2N19SU19ET1NfcHkudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoTDhfU1JfQjIsIkw4X1NSX0IyLnRpZiIsIGRyaXZlcm5hbWU9Ikd0aWZmIixvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKEw4X1NSX0IzLCJMOF9TUl9CMy50aWYiLCBkcml2ZXJuYW1lPSJHdGlmZiIsb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihMOF9TUl9CNCwiTDhfU1JfQjQudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0Kd3JpdGVSYXN0ZXIoTDhfU1JfQjUsIkw4X1NSX0I1LnRpZiIsIGRyaXZlcm5hbWU9Ikd0aWZmIixvdmVyd3JpdGU9VFJVRSkNCndyaXRlUmFzdGVyKEw4X1NSX0I2LCJMOF9TUl9CNi50aWYiLCBkcml2ZXJuYW1lPSJHdGlmZiIsb3ZlcndyaXRlPVRSVUUpDQp3cml0ZVJhc3RlcihMOF9TUl9CNywiTDhfU1JfQjcudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQojDQojDQojIyMjIyBVc3VhbG1lbnRlLCBsYSBjbGFzaWZpY2FjaW9uIHN1cGVydmlzYWRhIHJlcXVpZXJlIHF1ZSBlbCB1c3VhcmlvIHNlbGVjY2lvbmUgdW5hIG8gbcOhcyBSZWdpb25lcyBkZSBJbnRlcmVzIChST0lzLCBvIMOBcmVhcyBkZSBFbnRyZW5hbWllbnRvKSBwYXJhIGNhZGEgY2xhc2UgZGUgY29iZXJ0dXJhIGRlbCBzdWVsbyBpZGVudGlmaWNhZGEgZW4gbGEgaW1hZ2VuLiBMYXMgUk9JcyBzb24gcG9saWdvbm9zIG8gcHVudG9zIGRpYnVqYWRvcyBzb2JyZSBhcmVhcyBob21vZ2VuZWFzIGRlIGxhIGltYWdlbiBxdWUgc2Ugc3VwZXJwb25lbiBhIHBpeGVsZXMgcGVydGVuZWNpZW50ZXMgYSBsYSBtaXNtYSBjbGFzZSBkZSBjb2JlcnR1cmEgZGVsIHN1ZWxvLg0KIw0KIw0KIyMjIyMgUmFuZG9tIEZvcmVzdCBzZSBjb25zaWRlcmEgY29tbyBsYSDigJxwYW5hY2Vh4oCdIGVuIHRvZG9zIGxvcyBwcm9ibGVtYXMgZGUgY2llbmNpYSBkZSBkYXRvcywgcHVlcyBlcyBhKSBVdGlsIHBhcmEgcmVncmVzaW9uIHkgY2xhc2lmaWNhY2lvbiwgYikgdW4gZ3J1cG8gZGUgbW9kZWxvcyDigJxkZWJpbGVz4oCdLCBzZSBjb21iaW5hbiBlbiB1biBtb2RlbG8gcm9idXN0bywgYykgU2lydmUgY29tbyB1bmEgdGVjbmljYSBwYXJhIHJlZHVjY2lvbiBkZSBsYSBkaW1lbnNpb25hbGlkYWQsIGQpIFNlIGdlbmVyYW4gbXVsdGlwbGVzIGFyYm9sZXMgKGEgZGlmZXJlbmNpYSBkZSBDQVJUKSwgZSkgQ2FkYSBhcmJvbCBkYSB1bmEgY2xhc2lmaWNhY2lvbiwgeSBmKSBlbCByZXN1bHRhZG8gZXMgbGEgY2xhc2UgY29uIG1heW9yIG51bWVybyBkZSB2b3RvcyBlbiB0b2RvIGVsIGJvc3F1ZSAoZm9yZXN0KS4gSW1wb3J0YW50ZTogUGFyYSByZWdyZXNpb24sIHNlIHRvbWEgZWwgcHJvbWVkaW8gZGUgbGFzIHNhbGlkYXMgKHByZWRpY2Npb25lcykgZGUgdG9kb3MgbG9zIGFyYm9sZXMuDQojDQojDQpgYGB7cn0NCiMjQ2xhc2lmaWNhY2lvbiBzdXBlcnZpc2FkYSBjb24gUmFuZG9tIEZvcmVzdCAtIExhbmRzYXQgOCBPTEkNCg0KIyBBZ3JlZ2FyIHJhc3RlciBtdWx0aWJhbmRhcyBkZSBsYW5kc2F0IDgNCkw4XzIwMTUgPC0gc3RhY2soImNsaXBfTDhfQjIzNDU2N19SU19ET1NfcHkudGlmIikNCg0KIyBEaW1lbnNpb24gZGUgbGEgYmFuZGENCmRpbShMOF8yMDE1KQ0KDQojIE5vbWJyZSBkZSBsYXMgYmFuZGFzDQpuYW1lcyhMOF8yMDE1KQ0KDQojIGNhbWJpYXIgbm9tYnJlIGRlIGxhcyBiYW5kYXMNCm5hbWVzKEw4XzIwMTUpIDwtIGMoIkJMVUUiLCAiR1JFRU4iLCAiUkVEIiwgIk5JUiIsICJTV0lSMSIsICJTV0lSMiIpDQoNCiMgQWdyZWdhciBsb3Mgc2hhcGVmaWxlIGRlbCBST0kgMjAxOQ0Kcm9pIDwtIHNoYXBlZmlsZSgiY2xhc2lmaWNhY2lvbi5zaHAiKQ0KDQojIEluZm9ybWFjaW9uIGRlIGxhIHRhYmxhIGRlIGF0cmlidSBkZWwgc2hwDQpwcmludChyb2kpDQpoZWFkKHJvaUBkYXRhLDEwKQ0KDQojIFBsb3RlYW1vcyBsYSBpbWFnZW4geSBsYXMgcHVudG9zIGRlIG11ZXN0cmVvDQpwbG90UkdCKEw4XzIwMTUsNSw0LDMsIHN0cmV0Y2g9ImxpbiIpDQpwbG90KHJvaSxhZGQ9VFJVRSxjb2w9InJlZCIscGNoID0gMTUsIGx3ZD0zKQ0KDQojIEV4dHJhZXIgbG9zIHZhbG9yZXMgZGVsIHJhc3RlciBhIHRhYmxhDQpFeHRyYWVyX1JfU2hwIDwtIGV4dHJhY3QoTDhfMjAxNSxyb2kpICMgdGVuZW1vcyBsb3MgdmFsb3JlcyBSZWZsZWN0YW5jaWEgU3VwZXJmaWNpZQ0KcHJpbnQoRXh0cmFlcl9SX1NocCkNCg0KIyBTZWxlY2Npb25hciBsYSBjb2x1bW5hIGRlIGxhcyBjbGFzZXMNCkNsYXNzIDwtIHJvaUBkYXRhJENsYXNzDQpwcmludChDbGFzcykNCg0KIyBDcmVhciB1biBkYXRhIGZyYW1lIGNvbiBsb3MgZGF0b3MgcmVmbGVjdGFuY2lhIHN1cGVyZmljaWUgeSBsYXMgY2xhc2VzDQp0YWJsYSA8LSBkYXRhLmZyYW1lKEV4dHJhZXJfUl9TaHAsIENsYXNzKQ0Kc3VtbWFyeSh0YWJsYSRDbGFzcykNCg0KIyBTZXBlcmFuZG8gbG9zIGRhdG9zIGVuIEVudHJlbmFtaWVudG8geSBwcnVlYmENCk11ZXN0cmEgPC0gc2FtcGxlKDE6MjIzNSwxMDAwKSAjIHNhbXBsZSBzZXBhcmEgYWxlYXRvcmlhbWVudGUgbG9zIGRhdG9zDQpQcnVlYmFzIDwtIHRhYmxhW011ZXN0cmEsXQ0KRW50cmVuYW1pZW50byA8LSB0YWJsYVstTXVlc3RyYSxdDQoNCiMgQXBsaWNhbmRvIGVsIGFsZ29yaXRtbyBSYW5kb20gRm9yZXN0DQptb2RlbG8gPC0gcmFuZG9tRm9yZXN0KENsYXNzIH4uLGRhdGE9RW50cmVuYW1pZW50bywgaW1wb3J0YW5jZT1UUlVFKQ0KcHJlZGljY2lvbjwtIHByZWRpY3QobW9kZWxvLCBQcnVlYmFzWywtN10pDQoNCiMgRGVmaW5pbW9zIGxhIHBhbGV0YSBkZSBjb2xvcmVzIHNlZ3VuIGxhcyA3IGNsYXNlcw0KbXljb2xvciA8LSBjKCIjMDBGRjAwIiwiIzAwMDBGRiIsIiMyMjhCMjIiLCIjRkYxNDkzIiwgIiMxQzFDRTIiLCAiIzFDMUNFMiIgLCIjNTQ1NEFBIikNCg0KIyMgVmlzdWFsaXphciBwcmVkaWNjaW9uIGEgb2J0ZW5lcg0KIyMgQ2FudGlkYWQgZGUgcHVudG8gcXVlIHNlIGVuY3VlbnRyYSBlbiBsYSBjbGFzZQ0KcGxvdChwcmVkaWNjaW9uLCBtYWluID0gIk51bWVybyBkZSBwaXhlbGVzIGlkZW50aWZpY2Fkb3MiLA0KICAgICBheGVzID0gVFJVRSwgeGxhYiA9ICJDbGFzZXMiLCB5bGFiID0gIk51bWVybyBkZSBwaXhlbCIsIGNvbD0gbXljb2xvcikNCg0KIyBNYXRyaXogZGUgY29uZnVzaW9uDQpNQzwtdGFibGUoUHJ1ZWJhc1ssN10scHJlZGljY2lvbikNCk1DDQoNCiMgSW5kaWNlIGRlIEthcHBhDQprYXBwYTwtc3VtKGRpYWcoTUMpKS9zdW0oTUMpDQprYXBwYQ0KDQojIEVqZWN1dGFtb3MgZWwgY2xhc2lmaWNhZG9yIFJhbmRvbSBGb3Jlc3QNCmJlZ2luQ2x1c3RlcigpDQoNCiMjIDggY29yZXMgZGV0ZWN0ZWQsIHVzaW5nIDcNCnJmX2NsYXNzPC0gY2x1c3RlclIoTDhfMjAxNSwgcmFzdGVyOjpwcmVkaWN0LGFyZ3MgPSBsaXN0KG1vZGVsID1tb2RlbG8pKQ0KZW5kQ2x1c3RlcigpDQoNCiMgUGxvdGVhbW9zIGxhIGNsYXNpZmljYWNpw7NuIGNvbiBTdXBwb3J0IHZlY3RvciBtYWNoaW5lDQpwbG90KHJmX2NsYXNzLG1haW49cGFzdGUoImthcHBhID0gIixrYXBwYSxzZXAgPSIiKSxjb2wgPW15Y29sb3IsY2V4LmxhYj0wLjgsDQogICAgIGNleC5heGlzPTAuOCxjZXgubWFpbj0wLjkpDQoNCiMgRXhwb3J0YWNpb24gZGUgYmFuZGFzDQp3cml0ZVJhc3RlcihyZl9jbGFzcywiQ2xhc3NfTDhfUmFuZG9tX0ZvcmVzdC50aWYiLCBkcml2ZXJuYW1lPSJHdGlmZiIsb3ZlcndyaXRlPVRSVUUpDQpgYGANCiMNCiMNCiMjIyMjIFZlbnRhamFzIGRlIFJhbmRvbUZvcmVzdCA6IEV4aXN0ZW4gbXV5IHBvY2FzIHN1cG9zaWNpb25lcyB5IHBvciBsbyB0YW50byBsYSBwcmVwYXJhY2lvbiBkZSBsb3MgZGF0b3MgZXMgbWluaW1hLCBwdWVkZSBtYW5lamFyIGhhc3RhIG1pbGVzIGRlIHZhcmlhYmxlcyBkZSBlbnRyYWRhIGUgaWRlbnRpZmljYXIgbGFzIG1hcyBzaWduaWZpY2F0aXZhcywgdW5hIGRlIGxhcyBzYWxpZGFzIGRlbCBtb2RlbG8gZXMgbGEgaW1wb3J0YW5jaWEgZGUgdmFyaWFibGVzLCBpbmNvcnBvcmEgbWV0b2RvcyBlZmVjdGl2b3MgcGFyYSBlc3RpbWFyIHZhbG9yZXMgZmFsdGFudGVzLCB5IGVzIHBvc2libGUgdXNhcmxvIGNvbW8gbWV0b2RvIG5vIHN1cGVydmlzYWRvIChjbHVzdGVyaW5nKSB5IGRldGVjY2lvbiBkZSBvdXRsaWVycy4NCiMNCiMNCiMjIyMjIERlc3ZlbnRhamFzIGRlIFJhbmRvbUZvcmVzdCA6IFBlcmRpZGEgZGUgaW50ZXJwcmV0YWNpb24sIGJ1ZW5vIHBhcmEgY2xhc2lmaWNhY2lvbiwgbm8gdGFudG8gcGFyYSByZWdyZXNpb24uIExhcyBwcmVkaWNjaW9uZXMgbm8gc29uIGRlIG5hdHVyYWxlemEgY29udGludWEsIGVuIHJlZ3Jlc2lvbiwgbm8gcHVlZGUgcHJlZGVjaXIgbWFzIGFsbGEgZGVsIHJhbmdvIGRlIHZhbG9yZXMgZGVsIGNvbmp1bnRvIGRlIGVudHJlbmFtaWVudG8geSBwb2NvIGNvbnRyb2wgZW4gbG8gcXVlIGhhY2UgZWwgbW9kZWxvIChtb2RlbG8gY2FqYSBuZWdyYSBwYXJhIG1vZGVsYWRvcmVzIGVzdGFkaXN0aWNvcykNCiMNCiMNCmBgYHtyfQ0KIyMgQ2xhc2lmaWNhY2lvbiBzdXBlcnZpc2FkYSBjb24gQXJib2wgZGUgZGVzaWNpb24gLSBMYW5kc2F0IDggT0xJDQoNCiMgQWdyZWdhciByYXN0ZXIgbXVsdGliYW5kYXMgZGUgbGFuZHNhdCA4DQpMOF8yMDE1IDwtIHN0YWNrKCJjbGlwX0w4X0IyMzQ1NjdfUlNfRE9TX3B5LnRpZiIpDQoNCiMgRGltZW5zaW9uIGRlIGxhIGJhbmRhDQpkaW0oTDhfMjAxNSkNCg0KIyBOb21icmUgZGUgbGFzIGJhbmRhcw0KbmFtZXMoTDhfMjAxNSkNCg0KIyBjYW1iaWFyIG5vbWJyZSBkZSBsYXMgYmFuZGFzDQpuYW1lcyhMOF8yMDE1KSA8LSBjKCJCTFVFIiwgIkdSRUVOIiwgIlJFRCIsICJOSVIiLCAiU1dJUjEiLCAiU1dJUjIiKQ0KDQojIEFncmVnYXIgbG9zIHNoYXBlZmlsZSBkZWwgUk9JIDIwMTkNCg0Kcm9pIDwtIHNoYXBlZmlsZSgiY2xhc2lmaWNhY2lvbi5zaHAiKQ0KDQojIEluZm9ybWFjaW9uIGRlIGxhIHRhYmxhIGRlIGF0cmlidSBkZWwgc2hwDQpwcmludChyb2kpDQpoZWFkKHJvaUBkYXRhLDEwKQ0KDQojIFBsb3RlYW1vcyBsYSBpbWFnZW4geSBsYXMgcHVudG9zIGRlIG11ZXN0cmVvDQpwbG90UkdCKEw4XzIwMTUsNSw0LDMsIHN0cmV0Y2g9ImxpbiIpDQpwbG90KHJvaSxhZGQ9VFJVRSxjb2w9InJlZCIscGNoID0gMTUsIGx3ZD0zKQ0KDQojIEV4dHJhZXIgbG9zIHZhbG9yZXMgZGVsIHJhc3RlciBhIHRhYmxhDQpFeHRyYWVyX1JfU2hwIDwtIGV4dHJhY3QoTDhfMjAxNSxyb2kpICMgdGVuZW1vcyBsb3MgdmFsb3JlcyBSZWZsZWN0YW5jaWEgU3VwZXJmaWNpZQ0KcHJpbnQoRXh0cmFlcl9SX1NocCkNCg0KIyBTZWxlY2Npb25hciBsYSBjb2x1bW5hIGRlIGxhcyBjbGFzZXMNCkNsYXNzIDwtIHJvaUBkYXRhJENsYXNzDQpwcmludChDbGFzcykNCg0KIyBDcmVhciB1biBkYXRhIGZyYW1lIGNvbiBsb3MgZGF0b3MgcmVmbGVjdGFuY2lhIHN1cGVyZmljaWUgeSBsYXMgY2xhc2VzDQp0YWJsYSA8LSBkYXRhLmZyYW1lKEV4dHJhZXJfUl9TaHAsIENsYXNzKQ0Kc3VtbWFyeSh0YWJsYSRDbGFzcykNCg0KIyBTZXBlcmFuZG8gbG9zIGRhdG9zIGVuIEVudHJlbmFtaWVudG8geSBwcnVlYmENCk11ZXN0cmEgPC0gc2FtcGxlKDE6MjIzNSwxMDAwKSAjIHNhbXBsZSBzZXBhcmEgYWxlYXRvcmlhbWVudGUgbG9zIGRhdG9zDQpQcnVlYmFzIDwtIHRhYmxhW011ZXN0cmEsXQ0KRW50cmVuYW1pZW50byA8LSB0YWJsYVstTXVlc3RyYSxdDQoNCiMgQXBsaWNhbmRvIGVsIGFsZ29yaXRtbyBEVA0KbW9kZWxvIDwtIHJwYXJ0KENsYXNzIH4uLGRhdGE9RW50cmVuYW1pZW50bykNCg0KIyBQcmVkaWNjaW9uIGRlbCBtb2RlbG8gYSBvYnRlbmVyDQpwcmVkaWNjaW9uIDwtIHByZWRpY3QobW9kZWxvLCBQcnVlYmFzWywtN10sdHlwZT0iY2xhc3MiKQ0KDQojIERlZmluaW1vcyBsYSBwYWxldGEgZGUgY29sb3JlcyBzZWd1biBsYXMgNyBjbGFzZXMNCm15Y29sb3IgPC0gYygiIzAwRkYwMCIsIiMwMDAwRkYiLCIjMjI4QjIyIiwiI0ZGMTQ5MyIsICIjMUMxQ0UyIiwgIiMxQzFDRTIiICwiIzU0NTRBQSIpDQoNCiMjIFZpc3VhbGl6YXIgcHJlZGljY2lvbiBhIG9idGVuZXINCiMjIENhbnRpZGFkIGRlIHB1bnRvIHF1ZSBzZSBlbmN1ZW50cmEgZW4gbGEgY2xhc2UNCnBsb3QocHJlZGljY2lvbiwgbWFpbiA9ICJOdW1lcm8gZGUgcGl4ZWxlcyBpZGVudGlmaWNhZG9zIiwNCiAgICAgYXhlcyA9IFRSVUUsIHhsYWIgPSAiQ2xhc2VzIiwgeWxhYiA9ICJOdW1lcm8gZGUgcGl4ZWwiLCBjb2w9IG15Y29sb3IpDQoNCiMgRGV0ZXJtaW5hY2lvbiBkZWwgaW5kaWNlIGRlIGthcHBhIGRlIGxhIGNsYXNpZmljYWNpb24NCk1DIDwtIHRhYmxlKFBydWViYXNbLDddLHByZWRpY2Npb24pDQprYXBwYTwtc3VtKGRpYWcoTUMpKS9zdW0oTUMpDQpwcmludChrYXBwYSkNCg0KIyBHcmFmaWNhbmRvIGVsIGFyYm9sIGRlIGRlY2lzaW9uDQpwcnAobW9kZWxvLCBleHRyYT0xMDQsIGJyYW5jaC50eXBlID0xLCBib3guY29sID0gYygicGluayIsInBhbGVncmVlbjMiKVttb2RlbG8kZnJhbWUkeXZhbF0pDQoNCiMgRWplY3V0YW1vcyBlbCBjbGFzaWZpY2Fkb3IgRFQNCmJlZ2luQ2x1c3RlcigpDQoNCiMjIDggY29yZXMgZGV0ZWN0ZWQsIHVzaW5nIDcNCnRjX2NsYXNzPC0gY2x1c3RlclIoTDhfMjAxNSwgcmFzdGVyOjpwcmVkaWN0LGFyZ3MgPSBsaXN0KG1vZGVsID1tb2RlbG8sdHlwZT0iY2xhc3MiKSkNCmVuZENsdXN0ZXIoKQ0KDQojIFBsb3RlYW1vcyBsYSBjbGFzaWZpY2FjacOzbiBjb24gU3VwcG9ydCB2ZWN0b3IgbWFjaGluZQ0KcGxvdCh0Y19jbGFzcyxtYWluPXBhc3RlKCJrYXBwYSA9ICIsa2FwcGEsc2VwID0iIiksY29sID1teWNvbG9yLGNleC5sYWI9MC44LA0KICAgICBjZXguYXhpcz0wLjgsY2V4Lm1haW49MC45KQ0KDQojIEV4cG9ydGFjaW9uIGRlIGJhbmRhcw0Kd3JpdGVSYXN0ZXIodGNfY2xhc3MsIkNsYXNzX0w4X0RlY2lzaW9uX1RyZWUudGlmIiwgZHJpdmVybmFtZT0iR3RpZmYiLG92ZXJ3cml0ZT1UUlVFKQ0KYGBgDQojDQojDQojIyMjIyBFcyBpbXBvcnRhbnRlIHkgdXRpbCB1biBhcmJvbCBkZSBkZWNpY2lvbjoNCiMNCiMNCiMjIyMjIFNpIGxhIHJlbGFjaW9uIGVudHJlIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlIHkgbGEocykgaW5kZXBlbmRpZW50ZSBzZSBhcHJveGltYSBhIHVuIG1vZGVsbyBsaW5lYWwsIGxhIHJlZ3Jlc2lvbiBsaW5lYWwgZGFyYSBtZWpvcmVzIHJlc3VsdGFkb3MgcXVlIHVuIG1vZGVsbyBkZSBhcmJvbCBkZSBkZWNpc2lvbg0KIw0KIw0KIyMjIyMgU2kgbGEgcmVsYWNpb24gZXMgY29tcGxlamEgeSBhbHRhbWVudG8gbm8gbGluZWFsLCBlbnRvbmNlcyBlbCBhcmJvbCBkZSBkZWNpc2lvbiB0ZW5kcmEgbWVqb3JlcyByZXN1bHRhZG9zIGRlIHF1ZSB1biBtZXRvZG8gY2xhc2ljbyBkZSByZWdyZXNpb24uDQojDQojDQojIyMjIyBTaSBzZSBxdWllcmUgY29uc3RydWlyIHVuIG1vZGVsbyBxdWUgc2VhIGbDoWNpbCBkZSBleHBsaWNhciwgZW50b25jZXMgdW4gbW9kZWxvIGRlIGFyYm9sIGRlIGRlY2lzaW9uIHNlcmEgbWVqb3IgcXVlIHVuIG1vZGVsbyBsaW5lYWwuDQojDQojDQojIyMjIyBQb3Igb3RybyBsYWRvLCBlbCBpbmRpY2UgZGUgS2FwcGEgbWlkZSBlbCBncmFkbyBkZSBjb25jb3JkYW5jaWEgZGUgbGFzIGV2YWx1YWNpb25lcyBub21pbmFsZXMgdSBvcmRpbmFsZXMgcmVhbGl6YWRhcyBwb3IgbXVsdGlwbGVzIGV2YWx1YWRvcmVzIGN1YW5kbyBzZSBldmFsdWFuIGxhcyBtaXNtYXMgbXVlc3RyYXMsIGxvcyB2YWxvcmVzIGRlIGthcHBhIHZhcmlhbiBkZSDigJMxIGEgKzEuIE1pZW50cmFzIG1hcyBhbHRvIHNlYSBlbCB2YWxvciBkZSBrYXBwYSwgbWFzIGZ1ZXJ0ZSBzZXJhIGxhIGNvbmNvcmRhbmNpYS4gQ3VhbmRvOiBLYXBwYSA9IDEsIGV4aXN0ZSBjb25jb3JkYW5jaWEgcGVyZmVjdGEsIEthcHBhID0gMCwgbGEgY29uY29yZGFuY2lhIGVzIGxhIG1pc21hIHF1ZSBzZSBlc3BlcmFyaWEgZW4gdmlydHVkIGRlIGxhcyBwcm9iYWJpbGlkYWRlcywgeSBLYXBwYSA8IDAsIGxhIGNvbmNvcmRhbmNpYSBlcyBtYXMgZGViaWwgcXVlIGxvIGVzcGVyYWRvIGVuIHZpcnR1ZCBkZSBsYXMgcHJvYmFiaWxpZGFkZXM7IGVzdG8gY2FzaSBudW5jYSBzdWNlZGUuDQojDQojDQojIyMjIyBQYXJhIG51ZXN0cm8gZWplcmNpY2lvIGVsIGluZGljZSBkZSBrYXBwYSBlcyBkZSAwLDk1MiwgbG8gcXVlIG9iZWRlY2UgYSB1bmEgY29uY29yZGFuY2lhIHBlcmZlY3RhLg0KDQoNCg0KDQoNCg0K