¿Qué es R?

Características de R

Filosofía Free software

Desventajas de R

Instalación de R y RStudio por primera vez

Ayuda en R

*En general, para obtener ayuda hay dos formas

help(mean)
?mean

Dos formas de trabajar

  1. Línea de comando
  2. Script (similar a una sintax de SPSS o un .do file de STATA)

Dos formas de trabajar

Esquema de RStudio

Esquema de RStudio

Uso de comandos

sqrt(81)
[1] 9

Uso de comandos

x <- sqrt(81)
x
[1] 9

Uso de comandos

Importando Datos en R

Importando Datos en R: read.table()

Importando Datos en R: read.table()

Importando Datos “grandes” en R: read.table()

Importando Datos “grandes” en R: read.table()

Objetos en R

Objetos en R: Vectores

Generado vectores

x<-1:10 
x        
 [1]  1  2  3  4  5  6  7  8  9 10

Generado vectores

x<-c(1.2,2.3,3.8)       #numérico
x<-c(TRUE, FALSE, TRUE) #lógico
x<-c("a","b","c")       #character
x<-9:20                 #integer
x<-vector("numeric",length=10)
x
 [1] 0 0 0 0 0 0 0 0 0 0

Mezclando vectores

y<-c(1.2,"a")           #character
x<-c(FALSE, 2)          #numérico
x<-c(FALSE, "a")        #character

Coerción explícita

x<-0:6
as.character(x)
[1] "0" "1" "2" "3" "4" "5" "6"
as.logical(x)
[1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
as.character(x)
[1] "0" "1" "2" "3" "4" "5" "6"

Objetos en R: Factors

Objetos en R: Factors

x<-factor(c("Ocup","Ocup","Desoc","Ocup"
        ,"Inact"))
x
[1] Ocup  Ocup  Desoc Ocup  Inact
Levels: Desoc Inact Ocup

Objetos en R: Factors

x<-factor(c("A","A","M","B"
        ,"B"),
      levels=c("B","M","A"))
x
[1] A A M B B
Levels: B M A
table(x)
x
B M A 
2 1 2 

Objetos en R: Data Frames

Objetos en R: Data Frames

x<-data.frame(ident=1:3, tratamiento=c("D","B","B"))
x
nrow(x)
[1] 3
ncol(x)
[1] 2
row.names(x)
[1] "1" "2" "3"

Objetos en R: Listas

Objetos en R: Listas

x<-list(1,"a",TRUE, 4.6)
x
[[1]]
[1] 1

[[2]]
[1] "a"

[[3]]
[1] TRUE

[[4]]
[1] 4.6

Subsetting/Slicing en R

Subsetting/Slicing en R: Vectores

x<-1:10 
x[1:4]
[1] 1 2 3 4
x[4:1]
[1] 4 3 2 1
x[c(1,5,8)]
[1] 1 5 8
x[-c(1,5,8)]
[1]  2  3  4  6  7  9 10

Subsetting/Slicing en R: Data Frames

x<-1:4
y<-c("Z","Z","E","F")
z<-c(TRUE,FALSE,FALSE,FALSE)
df<-as.data.frame(cbind(x,y,z))
df[,2]
[1] Z Z E F
Levels: E F Z
df$x
[1] 1 2 3 4
Levels: 1 2 3 4
df$z[1]
[1] TRUE
Levels: FALSE TRUE

Subsetting/Slicing en R: Listas

x<-list(foo = 1:4, bar = 0.6)
x[1]
$foo
[1] 1 2 3 4
x[[1]]
[1] 1 2 3 4
x$bar
[1] 0.6
x['bar']
$bar
[1] 0.6
x[['bar']]
[1] 0.6

Subsetting/Slicing en R: Listas

x<-list(foo = 1:4, bar = 0.6, baz = 'hola')
x[c(1,3)]
$foo
[1] 1 2 3 4

$baz
[1] "hola"

Subsetting/Slicing en R: Listas

x<-list(foo = 1:4, bar = 0.6, baz = 'hola')
name<-'bar' # Indice computado
x[[name]]
[1] 0.6
x$name
NULL
x$foo
[1] 1 2 3 4

Subsetting/Slicing en R: Listas con elementos anidados

x<-list(a = list(10,12,14), b = c(3.14, 2.81))
x[[c(1,3)]]
[1] 14
x[[1]][[3]]
[1] 14
x[[c(2,1)]]
[1] 3.14

Subsetting/Slicing en R: Indexado Lógico

x<-c("aa", "bb", "cc", "dd", "ee")
index<-c(FALSE, TRUE, FALSE, TRUE, FALSE)
x[index]
[1] "bb" "dd"

Subsetting/Slicing en R: Indexado Lógico

Valores NA: eliminarlos

x<-c(1,2,NA,4,NA)
no<-is.na(x)
x1<-x[!no]
x2<-x[!is.na(x)]
x1
[1] 1 2 4
x2
[1] 1 2 4

Valores NA: eliminarlos

x<-c(1,2,NA,4)
y<-c(NA,"a",NA,"n")
m<-cbind(x,y)
m1<-m[complete.cases(m),]
m1
     x   y  
[1,] "2" "a"
[2,] "4" "n"

Funciones en R

fun<-function(argumentos){
    #[se hace algún cómputo]
}

Funciones en R

Funciones en R: matching de argumentos

data<-rnorm(100)
sd(data)
[1] 0.9719429
sd(x=data)
[1] 0.9719429
sd(x=data,na.rm=TRUE)
[1] 0.9719429
sd(na.rm=TRUE,x=data)
[1] 0.9719429
sd(na.rm=TRUE, data)
[1] 0.9719429

Funciones en R: matching de argumentos

args(lm)
function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 
NULL
lm(data=datos, y~x, model=FALSE,1:100)
lm(y~x,data=datos, 1:100, model=FALSE)

Funciones en R: definiendo una función

squared<-function(x,b,y=NULL,...){
    return(x**2)
}
squared(2)
[1] 4

Funciones en R: definiendo una función

prt<-function(a,b){
    print(a)
    print(b)
}
prt(2)
[1] 2
Error in print(b) : argument "b" is missing, with no default

Funciones en R: definiendo una función

LS0tDQp0aXRsZTogIkludHJvZHVjY2nDs24gYSBsYSBDaWVuY2lhIGRlIERhdG9zIHBhcmEgQ2llbnTDrWZpY29zIFNvY2lhbGVzIg0Kc3VidGl0bGU6ICJVbmlkYWQgMS4gUHJvZ3JhbWFjacOzbiBFc3RhZMOtc3RpY2EgZW4gUjogSW50cm9kdWNjacOzbiBhIFIgYmFzZSINCmF1dGhvcjogIkRyLiBHZXJtYW4gUm9zYXRpIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyDCv1F1w6kgZXMgUj8NCg0KKiBCw6FzaWNhbWVudGUsIFIgZXMgdW4gImRpYWxlY3RvIiBkZSB1biBsZW5ndWFqZSBkZSBsb3MgYcOxb3MgJzcwOiBTLUxhbmd1YWdlDQoqIFMgZnVlIGNyZWFkbyBlbiBsb3MgKkJlbGwgTGFicyogDQoqIFIgY3JlYWRvIGVuIDE5OTEgcG9yIFJvc3MgSXRoYWthIHkgUm9iZXJ0IEdlbnRlbG1hbg0KKiAxOTkzOiBSIHNlIGFudW5jaWEgcG9yIHByaW1lcmEgdmV6DQoqIDIwMDA6IHNlIGxhbnphIGxhIHByaW1lcmEgdmVyc2nDs24gUiAxLjANCiogMjAxNzogbGEgdmVyc2nDs24gbcOhcyBhY3R1YWwgZXMgbGEgUiAzLjQuMA0KDQoNCiMgQ2FyYWN0ZXLDrXN0aWNhcyBkZSBSDQoqIFNpbnRheGlzIHNpbWlsYXIgYSBTIChlbiBzdSBtb21lbnRvIHBlcm1pdMOtYSBoYWNlciBmw6FjaWwgZWwgcGFzYWplKQ0KKiBDb3JyZSBlbiBjYXNpIGN1YWxxdWllciBTTy9wbGF0YWZvcm1hIChpbmNsdXNvIGVuIFBTMykNCiogSGF5IGFjdHVhbGl6YWNpb25lcyBtdXkgZnJlY3VlbnRlcyAoZG9zIG8gdHJlcyBwb3IgYcOxbykNCiogRnVuY2lvbmFsaWRhZCBtb2R1bGFyOiBoYXkgdW4gY29uanVudG8gZGUgZnVuY2lvbmVzIGLDoXNpY2FzIGFsIGN1YWwgc2UgbGUgdmFuIGFncmVnYW5kbyBkaWZlcmVudGVzIHBhcXVldGVzIGNvbiBmdW5jaW9uYWxpZGFkZXMgZXNwZWNpZmljYXMNCiogTXV5IGJ1ZW5hcyBjYXBhY2lkYWRlcyBncsOhZmljYXM6IG11Y2hvIG1lam9yZXMgeSBtw6FzIHNvZmlzdGljYWRhcyBxdWUgY3VhbHF1aWVyIHNvZnR3YXJlIGRlIHByb2Nlc2FtaWVudG8gZXN0YWTDrXN0aWNvIChleHRyZW1vIGBnZ3Bsb3QyYCkgDQoqIExvIG1lam9yIGRlIHRvZG86IGxhIGNvbXVuaWRhZC4gQ2FkYSBlc3RhZMOtc3RpY28gcXVlIHNlIGxlIG9jdXJyZSB1biBhbGdvcml0bW8gbnVldm8gbG8gcHJvZ3JhbWEgZW4gUg0KKiBMbyBzZWd1bmRvIG1lam9yOiAqX0dSQVRJU18qDQoNCiMgRmlsb3NvZsOtYSBfRnJlZSBzb2Z0d2FyZV8NCiogTGliZXJ0YWQgZGUgY29ycmVyIGVsIHNvZnQgY29uIGN1YWxxdWllciBwcm9ww7NzaXRvIChncmFkbyAwKQ0KKiBMaWJlcnRhZCBkZSBlc3R1ZGlhciBjw7NtbyBmdW5jaW9uYSBlbCBwcm9ncmFtYSB5IGFkYXBhdGFybG8gYSBsYXMgbmVjZXNpZGFlcyAoZ3JhZG8gMSkuIFJlcXVpc2l0bzogZGlzcG9uZXIgZGVsIGPDs2RpZ28gZnVlbnRlDQoqIExpYmVydGFkIGRlIHJlZGlzdHJpYnVpciBjb3BpYXMgKGdyYWRvIDIpDQoqIExpYmVydGFkIGRlIG1lam9yYXIgZWwgc29mdHdhcmUgeSBsYW56YXIgbGFzIG1lam9yYXMgYWwgcMO6YmxpY28gKGdyYWRvIDMpLiBNaXNtbyByZXF1aXNpdG8gcXVlIGdyYWRvIDEuIA0KDQojIERlc3ZlbnRhamFzIGRlIFINCiogRW4gZ2VuZXJhbCwgbG9zIGRhdG9zIHNlIGNhcmdhbiBlbiBtZW1vcmlhIFJBTSAoZXMgbcOhcyBvIG1lbm9zIGxvIG1pc21vIHF1ZSBjYXNpIGN1YWxxdWllciBvdHJvIHNvZnQpLiBBbGd1bm9zIHBhcXVldGVzIGNvbWVuemFyb24gYSBtZWpvcmFyIGVzdGEgY3Vlc3Rpw7NuLg0KKiBMYSBpbXBsZW1lbnRhY2nDs24gZXMuLi4gZXNwb250w6FuZWEuIFNpIGEgbmFkaWUgbGUgaW50ZXJlc2EgZ2VuZXJhciB0dSBhbGdvcml0bW8uLi4gdGUgdG9jYSBhIHZvcy4NCg0KIyBJbnN0YWxhY2nDs24gZGUgUiB5IFJTdHVkaW8gcG9yIHByaW1lcmEgdmV6DQoqIElyIGFsIFtzaXRpbyBkZSBSXShodHRwczovL3d3dy5yLXByb2plY3Qub3JnLykNCiogRWxlZ2lyIGVsIHJlcG9zaXRvcmlvIGRlbCBjdWFsIHNlIGRlc2VhIGRlc2Nhcmdhcg0KKiBEZXNjYXJnYXIgbGEgw7psdGltYSB2ZXJzacOzbiBlc3RhYmxlIChhY3R1YWwgUiAzLjQuMCkNCiogTHVlZ28sIGVzIMO6dGlsIGluc3RhbGFyIGFsZ3VuYSBHVUkgcGFyYSBxdWUgZWwgdHJhYmFqbyBjb24gZWwgY8OzZGlnbyBzZWEgbcOhcyBhbWlnYWJsZS4gDQoqIFJTdHVkaW8gZXMgdW5hIGRlIGxhcyBtw6FzIHVzYWRhcy4NCiogRGVzY2FyZ2FyIGxhIMO6bHRpbWEgdmVyc2nDs24gW2RlbCBzaXRpb10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vKS4NCg0KDQojIEF5dWRhIGVuIFINCipFbiBnZW5lcmFsLCBwYXJhIG9idGVuZXIgYXl1ZGEgaGF5IGRvcyBmb3JtYXMNCg0KYGBge3J9DQpoZWxwKG1lYW4pDQo/bWVhbg0KYGBgDQoNCiMgRG9zIGZvcm1hcyBkZSB0cmFiYWphcg0KMS4gTMOtbmVhIGRlIGNvbWFuZG8NCjIuIFNjcmlwdCAoc2ltaWxhciBhIHVuYSBfc2ludGF4XyBkZSBTUFNTIG8gdW4gXy5kbyBmaWxlXyBkZSBTVEFUQSkNCiogU29uIGLDoXNpY2FtZW50ZSBsbyBtaXNtby4gU29sYW1lbnRlIHF1ZSBlbiBsYSBwcmltZXJhIHNlIHZhIGluZ3Jlc2FuZG8gIGNhZGEgY29tYW5kbyBkZSB1bmEgdmV6Lg0KDQoNCiMgRG9zIGZvcm1hcyBkZSB0cmFiYWphcg0KIVtFc3F1ZW1hIGRlIFJTdHVkaW9dKC4uL1JtYXJrZG93bnMvaW1ncy9JbnRlcmZhel9SU3R1ZGlvLmpwZykNCg0KDQojIFVzbyBkZSBjb21hbmRvcw0KKiBFbiB1c2Ftb3MgYsOhc2ljYW1lbnRlIGluc3RydWNjaW9uZXMgcXVlIHRpcGVhbW9zIG8gYmllbiBlbiBsYSBjb25zb2xhIG8gYmllbiBlbiB1biBzY3JpcHQuDQoqIExvcyByZXN1bHRhZG9zIHZhbiBhIGFwYXJlY2VyIGVuIGxhIGNvbnNvbGENCg0KYGBge3J9DQpzcXJ0KDgxKQ0KYGBgDQoqIGBzcXJ0KClgIGVzIHVuYSBmdW5jacOzbiwgZXMgZGVjaXIsIHVuYSBzZWN1ZW5jaWEgZGUgY8OzZGlnbyBsaXN0YSBwYXJhIHVzYXIuDQogICAgICAgICsgQSBzdSB2ZXosIHRpZW5lIHVuICpwYXJtw6l0cm8qIG8gKmFyZ3VtZW50byosIGxvcyB2YWxvcmVzIHF1ZSB1bmEgZnVuY2nDs24gZXNwZXJhIHF1ZSBlbCB1c3VhcmlvIGRlZmluYQ0KKiBMYXMgZnVuY2lvbmVzIGxsZXZhbiB1biBub21icmUgeSB2YW4gZW50cmUgcGFyw6ludGVzaXMNCg0KIyBVc28gZGUgY29tYW5kb3MNCiogQWhvcmEsIMK/cXXDqSBwYXNhIHNpIGluZ3Jlc28gZXN0bz8NCg0KYGBge3J9DQp4IDwtIHNxcnQoODEpDQpgYGANCg0KKiBObyBzZSBvYnNlcnZhIG5pbmfDum4gcmVzdWx0YWRvIHBvcnF1ZSB1c2Ftb3MgdW4gb3BlcmFkb3IgKHVuYSBmdW5jacOzbikgYDwtYA0KKiBFbiBlbCBjw7NkaWdvIGFudGVyaW9yIHNlIGNyZWEgdW5hIHZhcmlhYmxlICh1biBvYmpldG8pIHkgc2UgbGUgYXNpZ25hIGVsIHZhbG9yIGRlIGBzcXJ0KDgxKWANCiogQ3VhbmRvIHBlZGltb3MuLi4gDQoNCmBgYHtyfQ0KeA0KYGBgDQoNCiMgVXNvIGRlIGNvbWFuZG9zDQoqIFRyYWJhamFyIGNvbiB2YXJpYWJsZXMgbm9zIHBlcm1pdGUgYWxtYWNlbmFyIHZhbG9yZXMgcGFyYSB1c2FybG9zIGRlc3B1w6lzDQoqIEhhY2VuIG51ZXN0cm8gY8OzZGlnbyBtw6FzIGbDoWNpbCBkZSBsZWVyIHkgY29tcGFydGlyIGNvbiBvdHJvcw0KDQoNCiMgSW1wb3J0YW5kbyBEYXRvcyBlbiBSDQoqIFZhcmlhcyBmdW5jaW9uZXMgaW1wb3J0YW50ZXM6IA0KCSsgYHJlYWQudGFibGUoKWAgeSBgcmVhZC5jc3YoKWAgcGFyYSBsZWVyIGRhdG9zIHRhYnVsYXJlcw0KCSsgYHJlYWRMaW5lcygpYCBwYXJhIGxlZXIgbMOtbmVhcyBlbiB1biBhcmNoaXZvIGRlIHRleHRvDQoJKyBgcmVhZC5zcHNzKClgIGVuIGVsIHBhcXVldGUgKmZvcmVpZ24qIHF1ZSB1bmlmaWNhIG11Y2hhcyBsYXMgZnVuY2lvbmVzIGRlIGltcG9ydGFjacOzbiBleHBvcnRhY2nDs24NCg0KIyBJbXBvcnRhbmRvIERhdG9zIGVuIFI6IGByZWFkLnRhYmxlKClgDQoqIERlIGxhcyBtw6FzIHVzYWRhcy4gRWwgZm9ybWF0byBlcyBzaW1pbGFyIGFsIHJlc3RvDQoJKyBgZmlsZWA6IHN0cmluZyBjb24gZWwgbm9tYnJlIHkgbGEgcnV0YSBkZWwgYXJjaGl2byBhIGltcG9ydGFyDQoJKyBgaGVhZGVyYDogbG9naWNhbCBpbmRpY2FkbyBzaSBlbCBhcmNoaXZvIHRpZW5lIGNhYmVjZXJhcw0KCSsgYHNlcGA6IHN0cmluZyBxdWUgaW5kaWNhIGPDs21vIHNlIHNlcGFyYW4gbGFzIGNvbHVtbmFzDQoJKyBgY29sQ2xhc3Nlc2A6IGNoYXJhY3RlciB2ZWN0b3IgcXVlIGluZGljYSBsYSBjbGFzZSBkZSBjYWRhIGNvbHVtbmEgKCJjaGFyYWN0ZXIiLCJpbnRlZ2VyIixldGMuKQ0KCSsgYG5yb3dzYDogY2FudGlkYWQgZGUgZmlsYXMgZW4gZWwgZGF0YXNldA0KCSsgYHNraXBgOiBjYW50aWRhZCBkZSBmaWxhcyBxdWUgaGF5IHF1ZSBzYWx0ZWFyIGNvbnRhbmRvIGRlc2RlIGVsIHByaW5jaXBpbyBlbiBlbCBkYXRhc2V0DQoJKyBgc3RyaW5nQXNGYWN0b3JzYDogbG9naWNhbCBxdWUgaW5kaWNhIHNpIGFsIGltcG9ydGFyIGVsIGFyY2hpdm8gZGViZW4gY29kaWZpY2Fyc2UgbG9zIHN0cmluZ3MgY29tbyBmYWN0b3JzDQoNCiMgSW1wb3J0YW5kbyBEYXRvcyBlbiBSOiBgcmVhZC50YWJsZSgpYA0KKiBTaSBlbCBhcmNoaXZvIG5vIGVzIG11eSBncmFuZGUgcHVlZGUgdXNhcnNlIGRpcmVjdGFtZW50ZToNCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmRhdGE8LXJlYWQudGFibGUoInBydWViYS50eHQiKQ0KYGBgDQoNCiogUiB2YSBhIHJlYWxpemFyIGFsZ3VuYXMgdGFyZWFzIGF1dG9tw6F0aWNhbWVudGU6DQoJKyBzYWx0ZWFyIGxhcyBsw61uZWFzIHF1ZSBlbXBpZXphbiBjb24gIw0KCSsgY2FsY3VsYXIgY3XDoW50YXMgZmlsYXMgaGF5IHkgY3XDoW50YSBtZW1vcmlhIG5lY2VzaXRhIHJlc2VydmFyDQoJKyBpZGVudGlmaWNhciBsYSBjbGFzZSBkZSBjYWRhIGNvbHVtbmEgKHNpIHVubyBsbyBkZWZpbmUgY29uIGxvcyBhcmd1bWVudG9zIHJlc3VsdGEgbcOhcyBlZmljaWVudGUpDQoJKyBgcmVhZC5jc3YoKWAgZXMgaWTDqW50aWNvIGEgYHJlYWQudGFibGUoKWAgY29uIGxhIGRpZmVyZW5jaWEgZGUgcXVlIGVsIHNwZXJhZG9yIGVzIGxhIGNvbWEuDQoNCg0KIyBJbXBvcnRhbmRvIERhdG9zICJncmFuZGVzIiBlbiBSOiBgcmVhZC50YWJsZSgpYA0KKiBTaSBzZSBlbmZyZW50YW4gY29uIHVuIGRhdGFzZXQgZ3JhbmRlcyBwdWVkZW4NCgkrIGNvbnN1bHRhciBsYSBkb2N1bWVudGFjacOzbiBkZSBsYSBmdW5jacOzbg0KCSsgU2V0ZWFyIGVsIGFyZ3VtZW50byBgY29sQ2xhc3Nlc2A6IHN1ZWxlIHNlciBtdWNobyBtw6FzIHLDoXBpZG8gZGFkbyBxdWUgUiBubyB0aWVuZSBxdWUgcmVhbGl6YXIgbGEgdGFyZWEgZGUgZGV0ZWN0YXIgbG9zIHRpcG9zIGRlIGNhZGEgY29sdW1uYS4gDQoJKyBTZXRhciBgbnJvd3NgIGVzdG8gYXl1ZGEgYSB1c2FyIG1lbm9zIG1lbW9yaWEuLi4gbm8gYSBxdWUgc2VhIG5lY2VzYXJpYW1lbnRlIG3DoXMgcsOhcGlkby4NCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmluaXQ8LXJlYWQudGFibGUoInBydWViYS50eHQiLG5yb3dzPTEwMCkNCmNsYXNzZXM8LXNhcHBseShpbml0LGNsYXNzKQ0KdG9kb3M8LXJlYWQudGFibGUoInBydWViYS50eHQiDQoJCSAgLGNvbENsYXNzZXMgPSBjbGFzc2VzKQ0KYGBgDQoNCiMgSW1wb3J0YW5kbyBEYXRvcyAiZ3JhbmRlcyIgZW4gUjogYHJlYWQudGFibGUoKWANCiogQWRlbcOhcyBkZSB0b2RvIGVzdG8gZXMgaW1wb3J0YW50ZSBoYWNlciB1bmEgZXN0aW1hY2nDs24gZ3J1ZXNhIGRlIGxhIG1lbW9yaWEgcXVlIHZhIGEgcmVxdWVyaXIgY2FyZ2FyIGVsIGRhdGFzZXQuDQoqIFNpIGxhIG1lbW9yaWEgcmVxdWVyaWRhIGVzIG3DoXMgZGUgbGEgZGlzcG5pYmxlIGVuIGVsIGVsIHNpc3RlbWEuLi4gDQoqIEPDoWxjdWxvIGdydWVzbzogc3Vwb25nYW1vcyB1biBkYXRhZnJhbWUgY29uIDIuMDAwLjAwMCBkZSBmaWxhcyB5IDIwMCBjb2x1bW5hcyB0b2RvcyBkYXRvcyBudW3DqXJpY29zDQoJKyAyLjAwMC4wMDAgeCAyMDAgeCA4IGJ5dGVzL251bWVyaWNzDQoJKyAyLjQwMC4wMDAuMDAwIGJ5dGVzDQoJKyAyLjQwMC4wMDAuMDAwIGJ5dGVzIC8gMl4yMCBieXRlcy9NQg0KCSsgMi4yODgsOCBNQg0KCSsgMi4yNCBHQg0KDQoNCiMgT2JqZXRvcyBlbiBSDQoqIELDoXNpY2FtZW50ZS4uLiBkb25kZSBSIGd1YXJkYSBsb3MgZGF0b3MuDQoqIEhheSBtdWNob3MgdGlwb3MgZGUgb2JqZXRvcyBlbiBSLg0KKiBNdWNob3MgcGFxdWV0ZXMgImdlbmVyYW4iIHN1cyBwcm9waW9zIG9iamV0b3MNCiogTm8gb2JzdGFudGUsIGxhIG1heW9yw61hIGRlIGxhcyB0YXJlYXMgcHVlZGVuIHJlc29sdmVyc2UgY29uIGFsZ3Vub3MgcG9jb3MgdGlwb3MgZGUgb2JqZXRvcyANCiogRW4gUiBoYXkgY2luY28gdGlwb3MgYXTDs21pY29zIGRlIG9iamV0b3MNCgkrIGBjaGFyYWN0ZXJgDQoJKyBgbnVtZXJpY2ANCgkrIGBpbnRlZ2VyYA0KCSsgYGNvbXBsZXhgDQoJKyBgbG9naWNhbGANCg0KIyBPYmpldG9zIGVuIFI6IFZlY3RvcmVzDQoqIEVsIG9iamV0byBtw6FzIGLDoXNpY28gZXMgdW4gdmVjdG9yDQoqIFVuIHZlY3RvciBzb2xvIHB1ZWRlIGNvbnN0ZW5lciBvYmpldG9zIGRlIGxhIG1pc21hIGNsYXNlDQoqIEV4Y2VwY2nDs246IGxpc3RhcywgdGlwbyBlc3BlY2lhbCBkZSB2ZWN0b3IuDQoqIFB1ZWRlbiBjcmVhcnNlIHZlY3RvcmVzIHZhY8Otb3MgY29uIGxhIGZ1bmNpw7NuIGB2ZWN0b3IoKWANCg0KIyBHZW5lcmFkbyB2ZWN0b3Jlcw0KLSBFbCBvcGVyYWRvciBgOmAgc2lydmUgcGFyYSBnZW5lcmFyIHNlY3VlbmNpYXMgZGUgZW50ZXJvcw0KLSBUYW1iacOpbiBwdWVkZSB1c2Fyc2UgbGEgZnVuY2nDs24gYHNlcSgpYCBwYXJhIHNlY3VlbmNpYXMgbcOhcyBjb21wbGVqYXMNCg0KYGBge3J9DQp4PC0xOjEwIA0KeCAgICAgICAgDQpgYGANCg0KIyBHZW5lcmFkbyB2ZWN0b3Jlcw0KKiBMYSBmdW5jacOzbiBgYygpYCBzaXJ2ZSBwYXJhIGNyZWFyIHZlY3RvcmVzIGRlIG9iamV0b3MNCg0KYGBge3J9DQp4PC1jKDEuMiwyLjMsMy44KSAgICAgICAjbnVtw6lyaWNvDQp4PC1jKFRSVUUsIEZBTFNFLCBUUlVFKSAjbMOzZ2ljbw0KeDwtYygiYSIsImIiLCJjIikgICAgICAgI2NoYXJhY3Rlcg0KeDwtOToyMCAgICAgICAgICAgICAgICAgI2ludGVnZXINCmBgYA0KDQoqIFRhbWJpw6luIHB1ZWRlIHVzYXJzZSBsYSBmdW5jacOzbiBgdmVjdG9yKClgIA0KDQpgYGB7cn0NCng8LXZlY3RvcigibnVtZXJpYyIsbGVuZ3RoPTEwKQ0KeA0KYGBgDQoNCiMgTWV6Y2xhbmRvIHZlY3RvcmVzDQoqIEN1YW5kbyBzZSBtZXpjbGFuIGRpZmVyZW50ZXMgb2JqZXRvcyBlbiB1biB2ZWN0b3IgUiBoYWNlIHVzbyBkZSBsYSAiY29lcmNpw7NuIjogc2UgZnVlcnphIGEgbG9zIG9iamV0b3MgYSB0cmFuc2Zvcm1hcnNlIGVuIHVuYSBtaXNtYSBjbGFzZQ0KDQpgYGB7cn0NCnk8LWMoMS4yLCJhIikgICAgICAgICAgICNjaGFyYWN0ZXINCng8LWMoRkFMU0UsIDIpICAgICAgICAgICNudW3DqXJpY28NCng8LWMoRkFMU0UsICJhIikgICAgICAgICNjaGFyYWN0ZXINCmBgYA0KDQojIENvZXJjacOzbiBleHBsw61jaXRhDQoqIFB1ZWRlIGFwbGljYXJzZSBkZSBmb3JtYSBleHBsw61jaXRhIGxhIGNvZXJjaW9uOyBzZSB1c2FuIGxhcyBmdW5jaW9uZXMgYGFzLltjbGFzc11gDQoqIEVzdGEgY29lcmNpb24gcHVlZGUgYXBsaWNhcnNlIGEgb3Ryb3Mgb2JqZXRvcywgbm8gc29sbyBhIHZlY3RvcmVzDQoNCmBgYHtyfQ0KeDwtMDo2DQphcy5jaGFyYWN0ZXIoeCkNCmFzLmxvZ2ljYWwoeCkNCmFzLmNoYXJhY3Rlcih4KQ0KYGBgDQoNCiMgT2JqZXRvcyBlbiBSOiBGYWN0b3JzDQoqIFNlIHVzYW4gcGFyYSByZXByZXNlbnRhciBkYXRvcyBjYXRlZ8Ozcmljb3MgKG5vbWluYWxlcyB1IG9yZGluYWxlcykuIFNvbiBhbGdvIGFzw60gY29tbyB1biB2ZWN0b3IgZGUgaW50ZWdlcnMgY29uIHVuYSBldGlxdWV0YSBhc29jaWFkYSAoYWxnbyBwYXJlY2lkbyBhIFNQU1MpLg0KKiBBbGd1bmFzIGZ1bmNpb25lcyBjb21vIGBsbSgpYCB5IGBnbG0oKWAgaGFjZW4gdW4gdXNvIGVzcGVjaWFsIGRlIGxvcyBmYWN0b3Jlcw0KKiBTdWVsZSBzZXIgbWVqb3IgdXNhciBmYWN0b3JzIHF1ZSBpbnRlZ2VycyBwb3JxdWUgc29uICJhdXRvZGVzY3JpcHRpdm9zIjogIk9jdXBhZG8iLCAiRGVzb2N1cGFkbyIsICJJbmFjdGl2byIgZXMgbWVqb3IgcXVlIDEsMiwzLg0KDQojIE9iamV0b3MgZW4gUjogRmFjdG9ycw0KDQpgYGB7cn0NCng8LWZhY3RvcihjKCJPY3VwIiwiT2N1cCIsIkRlc29jIiwiT2N1cCINCgkgICAgLCJJbmFjdCIpKQ0KeA0KYGBgDQoNCiMgT2JqZXRvcyBlbiBSOiBGYWN0b3JzDQoqIFNlIHB1ZWRlIGdlbmVyYXIgZmFjdG9ycyBvcmRlbmFkb3MgY29uIGVsIGFyZ3VtZW50byBgbGV2ZWxzYC4gDQoNCmBgYHtyfQ0KeDwtZmFjdG9yKGMoIkEiLCJBIiwiTSIsIkIiDQoJICAgICwiQiIpLA0KCSAgbGV2ZWxzPWMoIkIiLCJNIiwiQSIpKQ0KeA0KdGFibGUoeCkNCmBgYA0KDQojIE9iamV0b3MgZW4gUjogRGF0YSBGcmFtZXMNCiogU29uIGxvIG3DoXMgcGFyZWNpZG8gYSBsbyBxdWUgZW50ZW5kZW1vcyBlbiBjaWVuY2lhcyBzb2NpYWxlcyBwb3IgYmFzZSBkZSBkYXRvcy4gU2UgdXNhbiBwYXJhIGFsbWFjZW5hciBkYXRvcyB0YWJ1bGFyZXMuDQoqIFBhcmEgUiBzb24gdW4gdGlwbyBlc3BlY2lhbCBkZSBsaXN0LCBlbiBsYSBjdWFsIGNhZGEgZWxlbWVudG8gZGUgbGEgbGlzdGEgdGllbmUgbGEgbWlzbWEgbG9uZ2l0dWQgKGBsZW5ndGgoKWApDQoqIENhZGEgZWxlbWVudG8gZGUgbGEgbGlzdCBwdWVkZSBzZXIgcGVuc2FkbyBwb3IgdW5hIGNvbHVtbmEgeSBlbCBsYXJnbyBkZSBjYWRhIGVsZW1lbnRvIGRlIGxhIGxpc3QgZXMgZWwgbnJvLiBkZSBmaWxlcyAoYG5yb3coKWApDQoqIEEgZGlmZXJlbmNpYSBkZSBsYXMgbWF0cml4IGNhZGEgZGF0YSBmcmFtZSBwdWVkZSBhbG1hbmNlbmFyIGVsZW1lbnRvcyAoY29sdW1uYXMpIGRlIGRpZmVyZW50ZXMgdGlwb3MuDQoqIFRpZW5lbiB1biBhdHJpYnV0byBlc3BlY2lhbDogYHJvdy5uYW1lc2ANCiogQ3VhbmRvIHZlYW1vcyBpbXBvIHkgZXhwbyBkZSBkYXRvcywgdmVyZW1vcyBxdWUgY3VhbmRvIHVubyBsbGFtYSBhIGxhIGZ1bmNpw7NuIGByZWFkLmNzdigpYCBvIGByZWFkLnRhYmxlKClgIG8gc2ltaWxhcmVzIGxvIHF1ZSBkZXZ1ZWx2ZW4gc29uIHVuIGRhdGEgZnJhbWUNCiogUHVlZGVuIHNlciB0cmFuc2Zvcm1hZG9zIGVuIG1hdHJpY2VzIHVzYW5kbyBgZGF0YS5tYXRyaXgoKWANCg0KIyBPYmpldG9zIGVuIFI6IERhdGEgRnJhbWVzDQoNCmBgYHtyfQ0KeDwtZGF0YS5mcmFtZShpZGVudD0xOjMsIHRyYXRhbWllbnRvPWMoIkQiLCJCIiwiQiIpKQ0KeA0KbnJvdyh4KQ0KbmNvbCh4KQ0Kcm93Lm5hbWVzKHgpDQpgYGANCg0KIyBPYmpldG9zIGVuIFI6IExpc3Rhcw0KKiBMYXMgbGlzdGFzIHNvbiB1bmEgY2xhc2UgZXNwZWNpYWwgZGUgdmVjdG9yOiBwdWVkZW4gY29udGVuZXIgZWxlbWVudG9zIGRlIGN1YWxxdWVpciB0aXBvIGVuIHN1IGludGVyaW9yLg0KKiBTb24gb2JqZXRvcyBtdXkgaW1wb3J0YW50ZXMgZW4gUjogbGEgbWF5b3LDrWEgZGUgbG9zIHJlc3VsdGFkb3MgZGUgbG9zIG1vZGVsb3MgcXVlIHNlIGFwbGljYW4gZW4gUiBkZXZ1ZWx2ZW4gY29tbyBvdXRwdXQgdW4gb2JqZXRvIHF1ZSBlcyB1bmEgbGlzdGEuDQoqIE90cm8gZWplbXBsbzogYWwgaW1wb3J0YXIgZGF0b3MgZGUgdW4gR0lTICguc2hwLCAuZ2VvanNvbiwgZ2VvZGF0YWJhc2UsIGV0Yy4pIFIgbG9zIGludGVycHJldGEgY29tbyB1bmEgbGlzdGEuDQoNCiMgT2JqZXRvcyBlbiBSOiBMaXN0YXMNCg0KYGBge3J9DQp4PC1saXN0KDEsImEiLFRSVUUsIDQuNikNCngNCmBgYA0KDQojIFN1YnNldHRpbmcvU2xpY2luZyBlbiBSDQoqIEFob3JhLCDCv2PDs21vIGV4dHJhZW1vcyBwYXJ0ZXMgZGUgbG9zIG9iamV0b3M/IMK/Q8OzbW8gYXBsaWNhbW9zIHRyYW5zZm9ybWFjaW9uZXMgYSB1biBzdWJjb25qdW50byBkZSB1biBkZXRlcm1pbmFkbyBvYmpldG8/DQoqIEEgYW1iYXMgb3BlcmFjaW9uZXMgc2UgbGFzIGxsYW1hICAqc2xpY2luZyogbyAqc3Vic2V0dGluZyosIHJlc3BlY3RpdmFtZW50ZQ0KKiBDYWRhIG9iamV0byB0aWVuZSBhbGd1bmEgZm9ybWEgZGUgc3Vic2V0dGluZyBvIHNsaWNpbmcuIEhheSB2YXJpb3Mgb3BlcmFkb3Jlcw0KKiBgW2AgZGV2dWVsdmUgc2llbXByZSB1biBvYmpldG8gZGUgbGEgbWlzbWEgY2xhc2UgcXVlIGVsIG9yaWdpbmFsDQoqIGBbW2Agc2UgdXNhIHBhcmEgZXh0cmFlciBkYXRvcyBkZSB1biBkYXRhZnJhbWUgbyB1bmEgbGlzdGEuIE5vIG5lY2VzYXJpYW1lbnRlIGRldnVlbHZlIHNpZW1wcmUgdW4gb2JqZXRvIGRlIGxhIG1pc21hIGNsYXNlIHF1ZSBlbCBvcmlnaW5hbA0KKiBgJGAgc2UgdXNhIHBhcmEgZXh0cmFlciBlbGVtZW50b3MgZGUgdW4gZGF0YWZyYW1lIG8gdW5hIGxpc3RhIHBvciBub21icmUuDQoNCiMgU3Vic2V0dGluZy9TbGljaW5nIGVuIFI6IFZlY3RvcmVzDQoqIE9yZGVuDQoNCmBgYHtyfQ0KeDwtMToxMCANCnhbMTo0XQ0KeFs0OjFdDQp4W2MoMSw1LDgpXQ0KeFstYygxLDUsOCldDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogRGF0YSBGcmFtZXMNCg0KYGBge3J9DQp4PC0xOjQNCnk8LWMoIloiLCJaIiwiRSIsIkYiKQ0KejwtYyhUUlVFLEZBTFNFLEZBTFNFLEZBTFNFKQ0KZGY8LWFzLmRhdGEuZnJhbWUoY2JpbmQoeCx5LHopKQ0KZGZbLDJdDQpkZiR4DQpkZiR6WzFdDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogTGlzdGFzDQoNCmBgYHtyfQ0KeDwtbGlzdChmb28gPSAxOjQsIGJhciA9IDAuNikNCnhbMV0NCnhbWzFdXQ0KeCRiYXINCnhbJ2JhciddDQp4W1snYmFyJ11dDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogTGlzdGFzDQoNCmBgYHtyfQ0KeDwtbGlzdChmb28gPSAxOjQsIGJhciA9IDAuNiwgYmF6ID0gJ2hvbGEnKQ0KeFtjKDEsMyldDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogTGlzdGFzDQoqIEVsIG9wZXJhZG9yIGBbW11dYCBwdWVkZSB1c2Fyc2UgY29uIMOtbmRpY2VzIGNhbGN1bGFkb3MuIGAkYCBzb2xvIHB1ZWRlIHVzYXJzZSBjb24gbm9tYnJlcw0KDQpgYGB7cn0NCng8LWxpc3QoZm9vID0gMTo0LCBiYXIgPSAwLjYsIGJheiA9ICdob2xhJykNCm5hbWU8LSdiYXInICMgSW5kaWNlIGNvbXB1dGFkbw0KeFtbbmFtZV1dDQp4JG5hbWUNCngkZm9vDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogTGlzdGFzIGNvbiBlbGVtZW50b3MgYW5pZGFkb3MNCiogRWwgb3BlcmFkb3IgYFtbXV1gIHB1ZWRlIHRvbWFyIGN1YWxxdWllciBzZWN1ZW5jaWEgZGUgZW50ZXJvcyANCg0KYGBge3J9DQp4PC1saXN0KGEgPSBsaXN0KDEwLDEyLDE0KSwgYiA9IGMoMy4xNCwgMi44MSkpDQp4W1tjKDEsMyldXQ0KeFtbMV1dW1szXV0NCnhbW2MoMiwxKV1dDQpgYGANCg0KIyBTdWJzZXR0aW5nL1NsaWNpbmcgZW4gUjogSW5kZXhhZG8gTMOzZ2ljbyANCiogRW4gUiBlcyBwb3NpYmxlIHV0bGl6YXIgdW4gdmVjdG9yIGRlIGJvb2xlYW5vcyAoYFRSVUVgLWBGQUxTRWApIGNvbW8gaW5zdW1vIHBhcmEgaGFjZXIgc3Vic2V0dGluZy9zbGljaW5nLiBUaWVuZSBxdWUgdGVuZXIgbGEgbWlzbWEgbG9uZ2l0dWQgcXVlIGVsIG9iamV0byBxdWUgdmFtb3MgYSBzdWJzZXRlYXINCiogTGEgaWRlYSBlcyBxdWUgbG9zIG1pZW1icm9zIGRlbCBvYmpldG8gb3JpZ2luYWwgcXVlIGVzdMOhbiBlbiBsYSAicG9zaWNpw7NuIiBgVFJVRWAgZGVsIHZlY3RvciBsw7NnaWNvIHNvbiBleHRyYWlkb3MgcGFyYSBlbCBzbGljZSwgbWllbnRyYXMgcXVlIGxvcyBxdWUgZXN0w6FuIGVuIGxhICJwb3NpY2nDs24iIGBGQUxTRWAsIG5vLiANCg0KYGBge3J9DQp4PC1jKCJhYSIsICJiYiIsICJjYyIsICJkZCIsICJlZSIpDQppbmRleDwtYyhGQUxTRSwgVFJVRSwgRkFMU0UsIFRSVUUsIEZBTFNFKQ0KeFtpbmRleF0NCmBgYA0KDQojIFN1YnNldHRpbmcvU2xpY2luZyBlbiBSOiBJbmRleGFkbyBMw7NnaWNvIA0KKiBFc3RvIHNlIGFwbGljYSBhIGN1YWxxdWllciBvYmpldG8uIEVzIHBhcnRpY3VsYXJtZW50ZSDDunRpbCBwYXJhIHRyYWJhciBjb24gZGF0YSBmcmFtZXMsIHBvciBlamVtcGxvLCBwYXJhIHF1ZWRhcm5vcyBjb24gY2Fzb3MgcXVlIGN1bXBsZW4gZGV0ZXJtaW5hZGEgY29uZGljacOzbi4gRXMgc2ltaWxhciBhIGhhY2VyIHVuIGZpbHRybyBlbiBTUFNTIG8gU1RBVEEuDQoNCg0KIyBWYWxvcmVzIE5BOiBlbGltaW5hcmxvcw0KKiBQdWVkZSBzZXIgcGVuc2FkbyBjb21vIHVuIGNhc28gZGUgaW5kZXhhZG8gbMOzZ2ljbzoNCiogUmVsYXRpdmFtZW50ZSBmw6FjaWw6IGBpcy5uYSgpYCBkZXZ1ZWx2ZSB1biB2ZWN0b3IgZGUgbMOzZ2ljYWxzIA0KDQpgYGB7cn0NCng8LWMoMSwyLE5BLDQsTkEpDQpubzwtaXMubmEoeCkNCngxPC14WyFub10NCngyPC14WyFpcy5uYSh4KV0NCngxDQp4Mg0KYGBgDQoNCiMgVmFsb3JlcyBOQTogZWxpbWluYXJsb3MNCiogU2kgaGF5IHZhcmlhcyBjb2x1bW5hcyBjb24gYE5BwrRzYCwgZW50b25jZXMgcHVlZGUgdXNhcnNlIGBjb21wbGV0ZS5jYXNlcygpYA0KDQpgYGB7cn0NCng8LWMoMSwyLE5BLDQpDQp5PC1jKE5BLCJhIixOQSwibiIpDQptPC1jYmluZCh4LHkpDQptMTwtbVtjb21wbGV0ZS5jYXNlcyhtKSxdDQptMQ0KYGBgDQoNCiMgRnVuY2lvbmVzIGVuIFINCiogTGFzIGZ1bmNpb25lcyBzZSBjcmVhbiBjb24gZWwgYXJndW1lbnRvIGBmdW5jdGlvbigpYCB5IHNlIGFsbWFjZW5hbiBjb21vIHVuIG9iamV0byBlbiBSLiANCg0KYGBge3J9DQpmdW48LWZ1bmN0aW9uKGFyZ3VtZW50b3Mpew0KCSNbc2UgaGFjZSBhbGfDum4gY8OzbXB1dG9dDQp9DQpgYGANCg0KKiBMYXMgZnVuY2lvbmVzIHB1ZWRlbiBwYXNhcnNlIGNvbW8gYXJndW1lbnRvIGEgb3RyYXMgZnVuY2lvbmVzDQoqIFB1ZWRlbiBhbmlkYXJzZTogcHVlZGUgZGVmaW5pcnNlIHVuYSBmdW5jacOzbiBkZW50cm8gZGUgdW5hIGZ1bmNpw7NuDQoqIEVsIHZhbG9yIHF1ZSBkZXZ1ZWx2ZSB1bmEgZnVuY2nDs24gZXMgbGEgw7psdGltYSBleHByZXNpw7NuIGVuIGVsIGN1ZXJwbyBkZSBsYSBmdW5jacOzbg0KDQojIEZ1bmNpb25lcyBlbiBSDQoqIExhcyBmdW5jaW9uZXMgdGllbmVuIHVuIGlucHV0IChhcmd1bWVudG9zKSB5IGRldnVlbHZlbiB1biBvdXRwdXQgKHZhbG9yKQ0KCSsgQXJndW1lbnRvcyBmb3JtYWxlczogbG9zIHF1ZSBlc3TDoW4gaW5jbHVpZG9zIGVuIGxhIGRlZmluaWNpw7NuIGRlIGxhIGZ1bmNpw7NuDQoJKyBMYSBmdW5jacOzbiBgZm9ybWFsKClgIGRldnVlbHZlIGxvcyBhcmd1bWVudG9zIGZvcm1hbGVzIGRlIHVuYSBmdW5jacOzbg0KCSsgTm8gdG9kYXMgbGFzIGZ1bmNpb25lcyBlbiBSIHVzYW4gYXJndW1lbnRvcyBmb3JtYWxlcw0KCSsgTG9zIGFyZ3VtZW50b3MgcHVlZGVuIGVzdGFyICJtaXNzaW5nIiBvIHRlbmVyIHZhbG9yZXMgYXNpZ25hZG9zIHBvciBkZWZlY3RvDQoJDQojIEZ1bmNpb25lcyBlbiBSOiBtYXRjaGluZyBkZSBhcmd1bWVudG9zDQoqIExvcyBhcmd1bWVudG9zIHB1ZWRlbiBzZXIgbWF0Y2hlYWRvcyBwb3Igbm9tYnJlIG8gcG9yIHBvc2ljacOzbi4gTGFzIHNpZ3VpZW50ZXMgc29uIGV4cHJlc2lvbmVzIGVxdWl2YWxlbnRlczoNCg0KYGBge3J9DQpkYXRhPC1ybm9ybSgxMDApDQpzZChkYXRhKQ0Kc2QoeD1kYXRhKQ0Kc2QoeD1kYXRhLG5hLnJtPVRSVUUpDQpzZChuYS5ybT1UUlVFLHg9ZGF0YSkNCnNkKG5hLnJtPVRSVUUsIGRhdGEpDQpgYGANCg0KIyBGdW5jaW9uZXMgZW4gUjogbWF0Y2hpbmcgZGUgYXJndW1lbnRvcw0KKiBTaSBiaWVuIG5vIGVzIHJlY29tZW5kYWJsZSwgc2UgcHVlZGVuICJtZXpjbGFyIiBtYXRjaGluZyBkZSBhcmd1bWVudG9zIHBvciBub21icmUgeSBwb3IgcG9zaWNpw7NuLiBDdWFuZG8gdW4gYXJndW1lbnRvIHNlIGxsYW1hIHBvciBub21icmUgc2UgbG8gc2FjYSBkZSBsYSBsaXN0YSB5IGVsIHJlc3RvIGRlIGxvcyBhcmd1bWVudG9zIHNlIGxsYW1hbiBwb3IgbGEgcG9zaWNpw7NuLiANCg0KYGBge3J9DQphcmdzKGxtKQ0KYGBgDQoNCiogUG9yIGVuZGUsIGxhcyBzaWd1aWVudGVzIGV4cHJlc2lvbmVzIHNvbiBlcXVpdmFsZW50ZXMNCg0KYGBge3J9DQpsbShkYXRhPWRhdG9zLCB5fngsIG1vZGVsPUZBTFNFLDE6MTAwKQ0KbG0oeX54LGRhdGE9ZGF0b3MsIDE6MTAwLCBtb2RlbD1GQUxTRSkNCmBgYA0KDQojIEZ1bmNpb25lcyBlbiBSOiBkZWZpbmllbmRvIHVuYSBmdW5jacOzbg0KDQpgYGB7cn0NCnNxdWFyZWQ8LWZ1bmN0aW9uKHgsYix5PU5VTEwsLi4uKXsNCglyZXR1cm4oeCoqMikNCn0NCnNxdWFyZWQoMikNCmBgYA0KDQoqIFB1ZWRlbiB1c2Fyc2UgYXJndW1lbnRvcyBxdWUgc29uIHNldGVhZG9zIHBvciBkZWZlY3RvIGVuIGBOVUxMYA0KKiBMYSBldmFsdWFjacOzbiBkZSBsb3MgYXJndW1lbnRvcyBlcyAibGF6eSIsIGVzIGRlY2lyIHF1ZSBzb2xhbWVudGUgc2UgZXZhbMO6YW4gbG9zIGFyZ3VtZW50b3MgYSBtZWRpZGEgcXVlIHNvbiBuZWNlc2FyaW9zLg0KCSsgRW4gbGEgZnVuY2nDs24gYW50ZXJpb3IgZWwgYXJndW1lbnRvIGIgbm8gc2UgCWV2YWzDumEsIGVudG9uY2VzIGxsYW1hbmRvIGBzcXVhcmVkKDIpYCBubyBhcnJvamEgCQllcnJvciBwb3JxdWUgZWwgMiBzZSBtYXRjaGVhIGVuIGZ1bmNpw7NuCWEgbGEgcG9zaWNpw7NuDQoNCiMgRnVuY2lvbmVzIGVuIFI6IGRlZmluaWVuZG8gdW5hIGZ1bmNpw7NuDQoNCmBgYHtyfQ0KcHJ0PC1mdW5jdGlvbihhLGIpew0KCXByaW50KGEpDQoJcHJpbnQoYikNCn0NCnBydCgyKQ0KYGBgDQoqIEFxdcOtIHNpIGFycm9qYSB1biBlcnJvcjogYiBkZWJlIHNlciBldmFsdWFkbyBsdWVnbyBkZSBgcHJpbnQoYSlgDQoNCiMgRnVuY2lvbmVzIGVuIFI6IGRlZmluaWVuZG8gdW5hIGZ1bmNpw7NuDQoqIFB1ZWRlIGFncmVnYXJzZSB1biBhcmd1bWVudG8gYCIuLi4iYA0KKiBTZSB1c2EgcGFyYSBwYXNhciBhIGxhIGZ1bmNpw7NuIGFyZ3VtZW50b3MgZGUgb3RyYXMgZnVuY2lvbmVzIHkgbm8gdGVuZXIgcXVlIGNvcGlhciB0b2RhIGxhIGxpc3RhIGRlIGFyZ3VtZW50b3MNCiogVGFtYmnDqW4gZXMgw7p0aWwgY3VhbmRvIGVsIG7Dum1lcm8gZGUgYXJndW1lbnRvcyBkZSBsYSBmdW5jacOzbiBubyBwdWVkZSBzZXIgY29ub2NpZG8gZGUgYW50ZW1hbm8uDQoqIFVuIHB1bnRvIGEgdGVuZXIgZW4gY3VlbnRhOiB0b2RvcyBsb3MgYXJndW1lbnRvcyBsdWVnbyBkZWwgYCIuLi4iYCBkZWJlbiBzZXIgbm9tYnJhZG9zIGV4cGzDrWNpdGFtZW50ZSB5IG5vIHB1ZWRlbiBzZXIgbWF0Y2hlYWRvcyBwYXJjaWFsbWVudGUuDQo=