Human Computer Interaction Section 2

Team 2-4

21400704 Jung Haejun

21500675 Jeong Pil Won

21500737 Choi Yeabin

21800741 Choi Yun Seo

date: 2020 06 06


library(h2o)
library(caret)
library(tidyverse)
setwd("C:/Users/PHILIP JEONG/Documents/R/deep")
load("C:/Users/PHILIP JEONG/Documents/datasets/Fulldata.Rdata")
Sys.setenv(JAVA_HOME = "C:/Program Files/Java/jre1.8.0_251")

load("plane_lens.Rdata")
Fulldata %>% filter(bulb=="p") %>% select(-bulb) -> Fulldata_p
index <- createDataPartition(Fulldata_p$volume,list=F,p=0.8)
train_p <- Fulldata_p[index,]
test_p <- Fulldata_p[-index,]

Deeplearning





deep1 <- h2o.deeplearning(
  model_id="deep1",
  training_frame=train_p_h2o,
  x=predictors,
  y=response,
  hidden=c(256,128,128),                  ## small network, runs faster
  epochs=1000,                      ## hopefully converges earlier...
  stopping_rounds=5,
  stopping_metric="RMSE", ## could be "MSE","logloss","r2"
  stopping_tolerance=0.0001
)
summary(deep1)

prediction1 <- h2o.predict(deep1,test_p_h2o[,-10])
prediction1 <- as.data.frame(prediction1)
actual1 <- as.data.frame(test_p$temp_c)
predactual <- cbind(prediction1,actual1)
sqrt(mean((predactual$predict-predactual$`test_p$temp_c`)^2)) #0.1738127


prediction2 <- h2o.predict(deep1,test_p_virtual_h2o)
testp150150120 <- cbind(as.data.frame(prediction2),testp150150120)
testp150150120 %>% group_by(c,w,volume) %>% summarise(mean=mean(predict))
library(readxl)

각 전구별 데이터셋 만들기 딥러닝 해서 하이퍼파라미터 주면 딥러닝 돌리기 데이터셋 만든거 돌려서 개별은 저장해놓고 평균온도로 주기 w 4개 10 20 30 40 c 5개 50 70 85 90 100

grid search

h2o.init(nthreads = 2,max_mem_size = "8g", enable_assertions = FALSE)
train_p_h2o <- as.h2o(train_p,destination_frame = "train_p_h2o")
test_p_h2o <- as.h2o(test_p,destination_frame = "test_p_h2o")
#test_p_virtual_h2o <- as.h2o(testp150150120,destination_frame = "test_p_virtual_h2o")

response <- "temp_c"
predictors <- setdiff(names(train_p_h2o), response)

hyper_params <- list(
  hidden = list(c(128, 128, 64), c(256, 256, 128)),
  epochs = 500,  
  rate = c(0.05,0.01)
)
  #input_dropout_ratio=c(0,0.05),
  #l1=seq(0,1e-6,length.out = 3),
  #l2=seq(0,1e-6,length.out = 3)

search_criteria <- list(
  strategy = "RandomDiscrete", stopping_rounds = 5,
  stopping_metric = "RMSE", ## could be "MSE","logloss","r2"
  stopping_tolerance = 0.001)


p_grid_model <- h2o.grid(algorithm = "deeplearning", 
                        x = predictors, y = response,
                        grid_id = "p_grid_model",
                        training_frame = train_p_h2o,
                        nfolds = 3,
                        hyper_params = hyper_params,
                        search_criteria = search_criteria)
p_grid <- h2o.getGrid(grid_id = "p_grid_model",
                             sort_by = "rmse",
                             decreasing = TRUE)
p_grid

p_grid_model.h2o <- h2o.getModel(p_grid_model@model_ids[[1]])

setwd("C:/Users/PHILIP JEONG/Documents/R/deep")
hidden_rate_path <- h2o.saveModel(object = hidden_rate_model@model_ids[[1]], 
                                  path = getwd(), force = TRUE)

deeplearning_grid_1 <- h2o.loadModel(hidden_rate_path)

Grab the top deeplearning model

######

#best for hidden: c(256,128) and c(128,64) from list(c(256,128), c(128,64), c(256,256,128), c(128,128,64))

# 모델 rmse / test셋 rmse
# 1: 0.2667804 / 0.2673417
# 2: 0.2169014 / 






#for(i in 1:10){
#  j <- cbind(test_p$temp_c,as.data.frame(get(paste0("pred",i))))
#  print(
#    sqrt(mean((j$`test_p$temp_c`-j$predict)^2))
#  )
#}

Shutdown

h2o::h2o.shutdown(prompt = FALSE)

fulldata (hidden rate, rate)

Hyper-Parameter Search Summary: ordered by decreasing rmse epochs hidden rate model_ids 1 55.337133806655295 [128, 128, 64] 0.01 p_grid_model_model_2 2 39.74071333035025 [256, 256, 128] 0.01 p_grid_model_model_3 3 54.41185987854036 [128, 64] 0.01 p_grid_model_model_1 4 35.43564494774071 [128, 64] 0.05 p_grid_model_model_5 5 36.11255034716078 [128, 64] 0.01 p_grid_model_model_6 6 33.920045818944836 [256, 128] 0.01 p_grid_model_model_8 7 37.67070705997133 [256, 128] 0.01 p_grid_model_model_4 8 40.661579306478814 [256, 128] 0.05 p_grid_model_model_7 rmse 1 0.2708127656077341 2 0.2586228534850487 3 0.24570491827919483 4 0.24377382888693253 5 0.2027425537057507 6 0.19774907468459532 7 0.15651192077650344 8 0.15074363912858893

Merged by bulb, lens, up

h2o.init(nthreads = 2,max_mem_size = "8g")

unseen_bulb <- unseen_bulb[-c(14:15)]
unseen_lens <- unseen_lens[-length(unseen_lens)]
unseen_up <- unseen_up[-length(unseen_up)]
unseen_bulb <- unseen_bulb[-length(unseen_bulb)]

unseen_bulb_h2o <- as.h2o(unseen_bulb)
unseen_lens_h2o <- as.h2o(unseen_lens)
unseen_up_h2o <- as.h2o(unseen_up)

unseen_bulb <- cbind(unseen_bulb,as.data.frame(h2o.predict(h2o.getModel(p_grid_model@model_ids[[1]]),unseen_bulb_h2o)))
rmse(unseen_bulb$temp_c,unseen_bulb$predict)

unseen_lens <- cbind(unseen_lens,as.data.frame(h2o.predict(h2o.getModel(plane_h_lens_model@model_ids[[1]]),unseen_lens_h2o[-c(7,9,11)])))
rmse(unseen_lens$temp_c,unseen_lens$predict)

unseen_up <- cbind(unseen_up,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),unseen_up_h2o[-c(7,9,11)])))
rmse(unseen_up$temp_c,unseen_up$predict)

bulb

unseen_bulb %>% filter(w==15 & c==50 & box_x==65 & box_y==65 & box_z==64) -> bulb1
unseen_bulb %>% filter(w==20 & c==60 & box_x==65 & box_y==65 & box_z==64) -> bulb2
unseen_bulb %>% filter(w==35 & c==85 & box_x==80 & box_y==80 & box_z==94) -> bulb3
unseen_bulb %>% filter(w==40 & c==95 & box_x==80 & box_y==80 & box_z==94) -> bulb4
unseen_bulb %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==64) -> bulb5
unseen_bulb %>% filter(w==20 & c==50 & box_x==60 & box_y==60 & box_z==64) -> bulb6
unseen_bulb %>% filter(w==20 & c==60 & box_x==60 & box_y==60 & box_z==64) -> bulb7
unseen_bulb %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==84) -> bulb8
unseen_bulb %>% filter(w==20 & c==50 & box_x==65 & box_y==65 & box_z==84) -> bulb9
unseen_bulb %>% filter(w==35 & c==95 & box_x==90 & box_y==90 & box_z==94) -> bulb10
unseen_bulb %>% filter(w==40 & c==85 & box_x==90 & box_y==90 & box_z==104) -> bulb11
unseen_bulb %>% filter(w==35 & c==95 & box_x==100 & box_y==100 & box_z==104) -> bulb12
unseen_bulb %>% filter(w==40 & c==85 & box_x==100 & box_y==100 & box_z==104) -> bulb13
unseen_bulb %>% filter(w==40 & c==95 & box_x==100 & box_y==100 & box_z==104) -> bulb14


bulb1_h2o <- as.h2o(bulb1)
bulb2_h2o <- as.h2o(bulb2)
bulb3_h2o <- as.h2o(bulb3)
bulb4_h2o <- as.h2o(bulb4)
bulb5_h2o <- as.h2o(bulb5)
bulb6_h2o <- as.h2o(bulb6)
bulb7_h2o <- as.h2o(bulb7)
bulb8_h2o <- as.h2o(bulb8)
bulb9_h2o <- as.h2o(bulb9)
bulb10_h2o <- as.h2o(bulb10)
bulb11_h2o <- as.h2o(bulb11)
bulb12_h2o <- as.h2o(bulb12)
bulb13_h2o <- as.h2o(bulb13)
bulb14_h2o <- as.h2o(bulb14)

bulb1 <- cbind(bulb1,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb1_h2o[-c(7,9,11)])))
bulb2 <- cbind(bulb2,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb2_h2o[-c(7,9,11)])))
bulb3 <- cbind(bulb3,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb3_h2o[-c(7,9,11)])))
bulb4 <- cbind(bulb4,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb4_h2o[-c(7,9,11)])))
bulb5 <- cbind(bulb5,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb5_h2o[-c(7,9,11)])))
bulb6 <- cbind(bulb6,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb6_h2o[-c(7,9,11)])))
bulb7 <- cbind(bulb7,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb7_h2o[-c(7,9,11)])))
bulb8 <- cbind(bulb8,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb8_h2o[-c(7,9,11)])))
bulb9 <- cbind(bulb9,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb9_h2o[-c(7,9,11)])))
bulb10 <- cbind(bulb10,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb10_h2o[-c(7,9,11)])))
bulb11 <- cbind(bulb11,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb11_h2o[-c(7,9,11)])))
bulb12 <- cbind(bulb12,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb12_h2o[-c(7,9,11)])))
bulb13 <- cbind(bulb13,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb13_h2o[-c(7,9,11)])))
bulb14 <- cbind(bulb14,as.data.frame(h2o.predict(h2o.getModel(p_grid_model_1@model_id[[1]]),bulb14_h2o[-c(7,9,11)])))

rmse(bulb1$temp_c,bulb1$predict) #3.765109
rmse(bulb2$temp_c,bulb2$predict) #1.739043
rmse(bulb3$temp_c,bulb3$predict) #10.12168
rmse(bulb4$temp_c,bulb4$predict) #3.407646
rmse(bulb5$temp_c,bulb5$predict) #2.73814
rmse(bulb6$temp_c,bulb6$predict) #2.482949
rmse(bulb7$temp_c,bulb7$predict) #1.401555
rmse(bulb8$temp_c,bulb8$predict) #4.064616
rmse(bulb9$temp_c,bulb9$predict) #7.929102
rmse(bulb10$temp_c,bulb10$predict) #6.308332
rmse(bulb11$temp_c,bulb11$predict) #6.282534
rmse(bulb12$temp_c,bulb12$predict) #0.6292883
rmse(bulb13$temp_c,bulb13$predict) #0.8309286
rmse(bulb14$temp_c,bulb14$predict) #0.6835631

lens

unseen_lens %>% filter(w==15 & c==50 & box_x==65 & box_y==65 & box_z==64) -> lens1
unseen_lens %>% filter(w==20 & c==60 & box_x==65 & box_y==65 & box_z==64) -> lens2
unseen_lens %>% filter(w==35 & c==85 & box_x==80 & box_y==80 & box_z==94) -> lens3
unseen_lens %>% filter(w==40 & c==95 & box_x==80 & box_y==80 & box_z==94) -> lens4
unseen_lens %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==64) -> lens5
unseen_lens %>% filter(w==20 & c==50 & box_x==60 & box_y==60 & box_z==64) -> lens6
unseen_lens %>% filter(w==20 & c==60 & box_x==60 & box_y==60 & box_z==64) -> lens7
unseen_lens %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==84) -> lens8
unseen_lens %>% filter(w==20 & c==50 & box_x==65 & box_y==65 & box_z==84) -> lens9
unseen_lens %>% filter(w==35 & c==95 & box_x==90 & box_y==90 & box_z==94) -> lens10
unseen_lens %>% filter(w==40 & c==85 & box_x==90 & box_y==90 & box_z==104) -> lens11
unseen_lens %>% filter(w==35 & c==95 & box_x==100 & box_y==100 & box_z==104) -> lens12
unseen_lens %>% filter(w==40 & c==85 & box_x==100 & box_y==100 & box_z==104) -> lens13
unseen_lens %>% filter(w==40 & c==95 & box_x==100 & box_y==100 & box_z==104) -> lens14

lens1_h2o <- as.h2o(lens1)
lens2_h2o <- as.h2o(lens2)
lens3_h2o <- as.h2o(lens3)
lens4_h2o <- as.h2o(lens4)
lens5_h2o <- as.h2o(lens5)
lens6_h2o <- as.h2o(lens6)
lens7_h2o <- as.h2o(lens7)
lens8_h2o <- as.h2o(lens8)
lens9_h2o <- as.h2o(lens9)
lens10_h2o <- as.h2o(lens10)
lens11_h2o <- as.h2o(lens11)
lens12_h2o <- as.h2o(lens12)
lens13_h2o <- as.h2o(lens13)
lens14_h2o <- as.h2o(lens14)

lens1 <- cbind(lens1,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens1_h2o[-c(7,9,11)])))
lens2 <- cbind(lens2,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens2_h2o[-c(7,9,11)])))
lens3 <- cbind(lens3,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens3_h2o[-c(7,9,11)])))
lens4 <- cbind(lens4,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens4_h2o[-c(7,9,11)])))
lens5 <- cbind(lens5,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens5_h2o[-c(7,9,11)])))
lens6 <- cbind(lens6,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens6_h2o[-c(7,9,11)])))
lens7 <- cbind(lens7,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens7_h2o[-c(7,9,11)])))
lens8 <- cbind(lens8,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens8_h2o[-c(7,9,11)])))
lens9 <- cbind(lens9,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens9_h2o[-c(7,9,11)])))
lens10 <- cbind(lens10,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens10_h2o[-c(7,9,11)])))
lens11 <- cbind(lens11,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens11_h2o[-c(7,9,11)])))
lens12 <- cbind(lens12,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens12_h2o[-c(7,9,11)])))
lens13 <- cbind(lens13,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens13_h2o[-c(7,9,11)])))
lens14 <- cbind(lens14,as.data.frame(h2o.predict(h2o.getModel(plane_p_lens_model@model_ids[[1]]),lens14_h2o[-c(7,9,11)])))

rmse(lens1$temp_c,lens1$predict) #2.53
rmse(lens2$temp_c,lens2$predict) #2.91
rmse(lens3$temp_c,lens3$predict) #32.10
rmse(lens4$temp_c,lens4$predict) #5.50
rmse(lens5$temp_c,lens5$predict) #0.90
rmse(lens6$temp_c,lens6$predict) #2.43
rmse(lens7$temp_c,lens7$predict) #1.26
rmse(lens8$temp_c,lens8$predict) #5.69
rmse(lens9$temp_c,lens9$predict) #8.59
rmse(lens10$temp_c,lens10$predict) #1.47
rmse(lens11$temp_c,lens11$predict) #5.54
rmse(lens12$temp_c,lens12$predict) #1.93
rmse(lens13$temp_c,lens13$predict) #2.95
rmse(lens14$temp_c,lens14$predict) #2.16

up

unseen_up %>% filter(w==15 & c==50 & box_x==65 & box_y==65 & box_z==64) -> up1
unseen_up %>% filter(w==20 & c==60 & box_x==65 & box_y==65 & box_z==64) -> up2
unseen_up %>% filter(w==35 & c==85 & box_x==80 & box_y==80 & box_z==94) -> up3
unseen_up %>% filter(w==40 & c==95 & box_x==80 & box_y==80 & box_z==94) -> up4
unseen_up %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==64) -> up5
unseen_up %>% filter(w==20 & c==50 & box_x==60 & box_y==60 & box_z==64) -> up6
unseen_up %>% filter(w==20 & c==60 & box_x==60 & box_y==60 & box_z==64) -> up7
unseen_up %>% filter(w==15 & c==60 & box_x==60 & box_y==60 & box_z==84) -> up8
unseen_up %>% filter(w==20 & c==50 & box_x==65 & box_y==65 & box_z==84) -> up9
unseen_up %>% filter(w==35 & c==95 & box_x==90 & box_y==90 & box_z==94) -> up10
unseen_up %>% filter(w==40 & c==85 & box_x==90 & box_y==90 & box_z==104) -> up11
unseen_up %>% filter(w==35 & c==95 & box_x==100 & box_y==100 & box_z==104) -> up12
unseen_up %>% filter(w==40 & c==85 & box_x==100 & box_y==100 & box_z==104) -> up13
unseen_up %>% filter(w==40 & c==95 & box_x==100 & box_y==100 & box_z==104) -> up14

up1_h2o <- as.h2o(up1)
up2_h2o <- as.h2o(up2)
up3_h2o <- as.h2o(up3)
up4_h2o <- as.h2o(up4)
up5_h2o <- as.h2o(up5)
up6_h2o <- as.h2o(up6)
up7_h2o <- as.h2o(up7)
up8_h2o <- as.h2o(up8)
up9_h2o <- as.h2o(up9)
up10_h2o <- as.h2o(up10)
up11_h2o <- as.h2o(up11)
up12_h2o <- as.h2o(up12)
up13_h2o <- as.h2o(up13)
up14_h2o <- as.h2o(up14)

up1 <- cbind(up1,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up1_h2o[-c(7,9,11)])))
up2 <- cbind(up2,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up2_h2o[-c(7,9,11)])))
up3 <- cbind(up3,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up3_h2o[-c(7,9,11)])))
up4 <- cbind(up4,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up4_h2o[-c(7,9,11)])))
up5 <- cbind(up5,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up5_h2o[-c(7,9,11)])))
up6 <- cbind(up6,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up6_h2o[-c(7,9,11)])))
up7 <- cbind(up7,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up7_h2o[-c(7,9,11)])))
up8 <- cbind(up8,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up8_h2o[-c(7,9,11)])))
up9 <- cbind(up9,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up9_h2o[-c(7,9,11)])))
up10 <- cbind(up10,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up10_h2o[-c(7,9,11)])))
up11 <- cbind(up11,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up11_h2o[-c(7,9,11)])))
up12 <- cbind(up12,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up12_h2o[-c(7,9,11)])))
up13 <- cbind(up13,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up13_h2o[-c(7,9,11)])))
up14 <- cbind(up14,as.data.frame(h2o.predict(h2o.getModel(plane_h_up_model@model_ids[[1]]),up14_h2o[-c(7,9,11)])))



rmse(up1$temp_c,up1$predict) #18.57
rmse(up2$temp_c,up2$predict) #11.64
rmse(up3$temp_c,up3$predict) #40.61
rmse(up4$temp_c,up4$predict) #3.88
rmse(up5$temp_c,up5$predict) #18.44
rmse(up6$temp_c,up6$predict) #11.58
rmse(up7$temp_c,up7$predict) #11.38
rmse(up8$temp_c,up8$predict) #18.87
rmse(up9$temp_c,up9$predict) #13.63
rmse(up10$temp_c,up10$predict) #3.57
rmse(up11$temp_c,up11$predict) #3.88
rmse(up12$temp_c,up12$predict) #2.59
rmse(up13$temp_c,up13$predict) #2.77
rmse(up14$temp_c,up14$predict) #2.42
LS0tDQp0aXRsZTogIkhDSSAyLTQgSW5DYXJUZWNoIERlZXAgTGVhcm5pbmcgdG8gUHJlZGljdCBIZWFkbGFtcCBUZW1wZXJhdHVyZSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCg0KSHVtYW4gQ29tcHV0ZXIgSW50ZXJhY3Rpb24gU2VjdGlvbiAyDQoNClRlYW0gMi00DQoNCjIxNDAwNzA0IEp1bmcgSGFlanVuDQoNCjIxNTAwNjc1IEplb25nIFBpbCBXb24NCg0KMjE1MDA3MzcgQ2hvaSBZZWFiaW4NCg0KMjE4MDA3NDEgQ2hvaSBZdW4gU2VvDQoNCmRhdGU6IDIwMjAgMDYgMDYNCg0KLS0tDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGgybykNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7cn0NCnNldHdkKCJDOi9Vc2Vycy9QSElMSVAgSkVPTkcvRG9jdW1lbnRzL1IvZGVlcCIpDQpsb2FkKCJDOi9Vc2Vycy9QSElMSVAgSkVPTkcvRG9jdW1lbnRzL2RhdGFzZXRzL0Z1bGxkYXRhLlJkYXRhIikNClN5cy5zZXRlbnYoSkFWQV9IT01FID0gIkM6L1Byb2dyYW0gRmlsZXMvSmF2YS9qcmUxLjguMF8yNTEiKQ0KDQpsb2FkKCJwbGFuZV9sZW5zLlJkYXRhIikNCg0KDQpgYGANCg0KYGBge3J9DQpGdWxsZGF0YSAlPiUgZmlsdGVyKGJ1bGI9PSJwIikgJT4lIHNlbGVjdCgtYnVsYikgLT4gRnVsbGRhdGFfcA0KaW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbihGdWxsZGF0YV9wJHZvbHVtZSxsaXN0PUYscD0wLjgpDQp0cmFpbl9wIDwtIEZ1bGxkYXRhX3BbaW5kZXgsXQ0KdGVzdF9wIDwtIEZ1bGxkYXRhX3BbLWluZGV4LF0NCg0KDQoNCmBgYA0KDQoNCg0KIyBEZWVwbGVhcm5pbmcNCmBgYHtyfQ0KDQoNCg0KDQpkZWVwMSA8LSBoMm8uZGVlcGxlYXJuaW5nKA0KICBtb2RlbF9pZD0iZGVlcDEiLA0KICB0cmFpbmluZ19mcmFtZT10cmFpbl9wX2gybywNCiAgeD1wcmVkaWN0b3JzLA0KICB5PXJlc3BvbnNlLA0KICBoaWRkZW49YygyNTYsMTI4LDEyOCksICAgICAgICAgICAgICAgICAgIyMgc21hbGwgbmV0d29yaywgcnVucyBmYXN0ZXINCiAgZXBvY2hzPTEwMDAsICAgICAgICAgICAgICAgICAgICAgICMjIGhvcGVmdWxseSBjb252ZXJnZXMgZWFybGllci4uLg0KICBzdG9wcGluZ19yb3VuZHM9NSwNCiAgc3RvcHBpbmdfbWV0cmljPSJSTVNFIiwgIyMgY291bGQgYmUgIk1TRSIsImxvZ2xvc3MiLCJyMiINCiAgc3RvcHBpbmdfdG9sZXJhbmNlPTAuMDAwMQ0KKQ0Kc3VtbWFyeShkZWVwMSkNCg0KcHJlZGljdGlvbjEgPC0gaDJvLnByZWRpY3QoZGVlcDEsdGVzdF9wX2gyb1ssLTEwXSkNCnByZWRpY3Rpb24xIDwtIGFzLmRhdGEuZnJhbWUocHJlZGljdGlvbjEpDQphY3R1YWwxIDwtIGFzLmRhdGEuZnJhbWUodGVzdF9wJHRlbXBfYykNCnByZWRhY3R1YWwgPC0gY2JpbmQocHJlZGljdGlvbjEsYWN0dWFsMSkNCnNxcnQobWVhbigocHJlZGFjdHVhbCRwcmVkaWN0LXByZWRhY3R1YWwkYHRlc3RfcCR0ZW1wX2NgKV4yKSkgIzAuMTczODEyNw0KDQoNCnByZWRpY3Rpb24yIDwtIGgyby5wcmVkaWN0KGRlZXAxLHRlc3RfcF92aXJ0dWFsX2gybykNCnRlc3RwMTUwMTUwMTIwIDwtIGNiaW5kKGFzLmRhdGEuZnJhbWUocHJlZGljdGlvbjIpLHRlc3RwMTUwMTUwMTIwKQ0KdGVzdHAxNTAxNTAxMjAgJT4lIGdyb3VwX2J5KGMsdyx2b2x1bWUpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKHByZWRpY3QpKQ0KDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KDQoNCuqwgSDsoITqtazrs4Qg642w7J207YSw7IWLIOunjOuTpOq4sA0K65Sl65+s64udIO2VtOyEnCDtlZjsnbTtjbztjIzrnbzrr7jthLAg7KO866m0IOuUpeufrOuLnSDrj4zrpqzquLANCuuNsOydtO2EsOyFiyDrp4zrk6DqsbAg64+M66Ck7IScIOqwnOuzhOydgCDsoIDsnqXtlbTrhpPqs6Ag7Y+J6reg7Jio64+E66GcIOyjvOq4sA0KdyA06rCcIDEwIDIwIDMwIDQwDQpjIDXqsJwgNTAgNzAgODUgOTAgMTAwDQoNCmdyaWQgc2VhcmNoDQpgYGB7cn0NCmgyby5pbml0KG50aHJlYWRzID0gMixtYXhfbWVtX3NpemUgPSAiOGciLCBlbmFibGVfYXNzZXJ0aW9ucyA9IEZBTFNFKQ0KdHJhaW5fcF9oMm8gPC0gYXMuaDJvKHRyYWluX3AsZGVzdGluYXRpb25fZnJhbWUgPSAidHJhaW5fcF9oMm8iKQ0KdGVzdF9wX2gybyA8LSBhcy5oMm8odGVzdF9wLGRlc3RpbmF0aW9uX2ZyYW1lID0gInRlc3RfcF9oMm8iKQ0KI3Rlc3RfcF92aXJ0dWFsX2gybyA8LSBhcy5oMm8odGVzdHAxNTAxNTAxMjAsZGVzdGluYXRpb25fZnJhbWUgPSAidGVzdF9wX3ZpcnR1YWxfaDJvIikNCg0KcmVzcG9uc2UgPC0gInRlbXBfYyINCnByZWRpY3RvcnMgPC0gc2V0ZGlmZihuYW1lcyh0cmFpbl9wX2gybyksIHJlc3BvbnNlKQ0KDQpoeXBlcl9wYXJhbXMgPC0gbGlzdCgNCiAgaGlkZGVuID0gbGlzdChjKDEyOCwgMTI4LCA2NCksIGMoMjU2LCAyNTYsIDEyOCkpLA0KICBlcG9jaHMgPSA1MDAsICANCiAgcmF0ZSA9IGMoMC4wNSwwLjAxKQ0KKQ0KICAjaW5wdXRfZHJvcG91dF9yYXRpbz1jKDAsMC4wNSksDQogICNsMT1zZXEoMCwxZS02LGxlbmd0aC5vdXQgPSAzKSwNCiAgI2wyPXNlcSgwLDFlLTYsbGVuZ3RoLm91dCA9IDMpDQoNCnNlYXJjaF9jcml0ZXJpYSA8LSBsaXN0KA0KICBzdHJhdGVneSA9ICJSYW5kb21EaXNjcmV0ZSIsIHN0b3BwaW5nX3JvdW5kcyA9IDUsDQogIHN0b3BwaW5nX21ldHJpYyA9ICJSTVNFIiwgIyMgY291bGQgYmUgIk1TRSIsImxvZ2xvc3MiLCJyMiINCiAgc3RvcHBpbmdfdG9sZXJhbmNlID0gMC4wMDEpDQoNCg0KcF9ncmlkX21vZGVsIDwtIGgyby5ncmlkKGFsZ29yaXRobSA9ICJkZWVwbGVhcm5pbmciLCANCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSBwcmVkaWN0b3JzLCB5ID0gcmVzcG9uc2UsDQogICAgICAgICAgICAgICAgICAgICAgICBncmlkX2lkID0gInBfZ3JpZF9tb2RlbCIsDQogICAgICAgICAgICAgICAgICAgICAgICB0cmFpbmluZ19mcmFtZSA9IHRyYWluX3BfaDJvLA0KICAgICAgICAgICAgICAgICAgICAgICAgbmZvbGRzID0gMywNCiAgICAgICAgICAgICAgICAgICAgICAgIGh5cGVyX3BhcmFtcyA9IGh5cGVyX3BhcmFtcywNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlYXJjaF9jcml0ZXJpYSA9IHNlYXJjaF9jcml0ZXJpYSkNCg0KDQpgYGANCg0KYGBge3J9DQpwX2dyaWQgPC0gaDJvLmdldEdyaWQoZ3JpZF9pZCA9ICJwX2dyaWRfbW9kZWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3J0X2J5ID0gInJtc2UiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzaW5nID0gVFJVRSkNCnBfZ3JpZA0KDQpwX2dyaWRfbW9kZWwuaDJvIDwtIGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxAbW9kZWxfaWRzW1sxXV0pDQoNCnNldHdkKCJDOi9Vc2Vycy9QSElMSVAgSkVPTkcvRG9jdW1lbnRzL1IvZGVlcCIpDQpoaWRkZW5fcmF0ZV9wYXRoIDwtIGgyby5zYXZlTW9kZWwob2JqZWN0ID0gaGlkZGVuX3JhdGVfbW9kZWxAbW9kZWxfaWRzW1sxXV0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBnZXR3ZCgpLCBmb3JjZSA9IFRSVUUpDQoNCmRlZXBsZWFybmluZ19ncmlkXzEgPC0gaDJvLmxvYWRNb2RlbChoaWRkZW5fcmF0ZV9wYXRoKQ0KYGBgDQoNCiMgR3JhYiB0aGUgdG9wIGRlZXBsZWFybmluZyBtb2RlbA0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCg0KIyMjIyMjIyMjIyMjIyMjIyB0ZXN0IHByZWRpY3Qg7Je0IOqzhOyGjSDsg53qsqggDQpiZXN0X2RlZXBsZWFybmluZ19ncmlkMSA8LSBoMm8uZ2V0TW9kZWwoc2F2ZWRfaGlkZGVuX3JhdGVfbW9kZWxAbW9kZWxfaWRzW1sxXV0pDQpiZXN0X2RlZXBsZWFybmluZ19ncmlkMSAjUk1TRTogIDAuMjY2NzgwNA0KDQpiZXN0X2RlZXBsZWFybmluZ19ncmlkMiA8LSBoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsQG1vZGVsX2lkc1tbMl1dKQ0KYmVzdF9kZWVwbGVhcm5pbmdfZ3JpZDIgI1JNU0U6ICAwLjIxNjkwMTQNCg0KYmVzdF9kZWVwbGVhcm5pbmdfZ3JpZDMgPC0gaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbEBtb2RlbF9pZHNbWzNdXSkNCmJlc3RfZGVlcGxlYXJuaW5nX2dyaWQzICNSTVNFOiAgMC42OTQyNjENCg0KYmVzdF9kZWVwbGVhcm5pbmdfZ3JpZDQgPC0gaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbEBtb2RlbF9pZHNbWzRdXSkNCmJlc3RfZGVlcGxlYXJuaW5nX2dyaWQ0ICNSTVNFOiAgMS4wODI2MjkNCg0KDQpoMm8ubG9hZE1vZGVsKGRlZXBsZWFybmluZ19ncmlkXzEpDQpoMm8ubG9hZE1vZGVsKGRlZXBsZWFybmluZ19ncmlkXzIpDQoNCiNwcmVkMSA8LSBoMm8ucHJlZGljdChiZXN0X2RlZXBsZWFybmluZ19ncmlkLHRlc3RfcF9oMm8pDQoNCiNbWzFdXQ0KZGVlcGxlYXJuaW5nX2dyaWRfMSA8LSBoMm8uc2F2ZU1vZGVsKG9iamVjdD1iZXN0X2RlZXBsZWFybmluZ19ncmlkMSwgcGF0aD1nZXR3ZCgpLCBmb3JjZT1UUlVFKSANCnRlc3RfcCA8LSBjYmluZCh0ZXN0X3AsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChiZXN0X2RlZXBsZWFybmluZ19ncmlkMSx0ZXN0X3BfaDJvKSkpDQpybXNlKHRlc3RfcCR0ZW1wX2MsdGVzdF9wJHByZWRpY3QpICMgUk1TRTogMC4yNjczNDE3DQp0ZXN0X3AkcHJlZGljdCA8LSBOVUxMDQoNCiNbWzJdXQ0KZGVlcGxlYXJuaW5nX2dyaWRfMiA8LSBoMm8uc2F2ZU1vZGVsKG9iamVjdD1iZXN0X2RlZXBsZWFybmluZ19ncmlkMiwgcGF0aD1nZXR3ZCgpLCBmb3JjZT1UUlVFKQ0KVmlldyh0ZXN0X3ApDQp0ZXN0X3AgPC0gY2JpbmQodGVzdF9wLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoYmVzdF9kZWVwbGVhcm5pbmdfZ3JpZDIsdGVzdF9wX2gybykpKQ0Kcm1zZSh0ZXN0X3AkdGVtcF9jLHRlc3RfcCRwcmVkaWN0KQ0KdGVzdF9wJHByZWRpY3QgPC0gTlVMTA0KDQoNCmBgYA0KDQpgYGB7cn0NCiMjIyMjIw0KDQojYmVzdCBmb3IgaGlkZGVuOiBjKDI1NiwxMjgpIGFuZCBjKDEyOCw2NCkgZnJvbSBsaXN0KGMoMjU2LDEyOCksIGMoMTI4LDY0KSwgYygyNTYsMjU2LDEyOCksIGMoMTI4LDEyOCw2NCkpDQoNCiMg66qo6424IHJtc2UgLyB0ZXN07IWLIHJtc2UNCiMgMTogMC4yNjY3ODA0IC8gMC4yNjczNDE3DQojIDI6IDAuMjE2OTAxNCAvIA0KDQoNCg0KDQoNCg0KI2ZvcihpIGluIDE6MTApew0KIyAgaiA8LSBjYmluZCh0ZXN0X3AkdGVtcF9jLGFzLmRhdGEuZnJhbWUoZ2V0KHBhc3RlMCgicHJlZCIsaSkpKSkNCiMgIHByaW50KA0KIyAgICBzcXJ0KG1lYW4oKGokYHRlc3RfcCR0ZW1wX2NgLWokcHJlZGljdCleMikpDQojICApDQojfQ0KYGBgDQoNCg0KU2h1dGRvd24NCmBgYHtyfQ0KaDJvOjpoMm8uc2h1dGRvd24ocHJvbXB0ID0gRkFMU0UpDQpgYGANCg0KDQoNCg0KZnVsbGRhdGEgKGhpZGRlbiByYXRlLCByYXRlKQ0KDQpIeXBlci1QYXJhbWV0ZXIgU2VhcmNoIFN1bW1hcnk6IG9yZGVyZWQgYnkgZGVjcmVhc2luZyBybXNlDQogICAgICAgICAgICAgIGVwb2NocyAgICAgICAgICBoaWRkZW4gcmF0ZSAgICAgICAgICAgIG1vZGVsX2lkcw0KMSA1NS4zMzcxMzM4MDY2NTUyOTUgIFsxMjgsIDEyOCwgNjRdIDAuMDEgcF9ncmlkX21vZGVsX21vZGVsXzINCjIgIDM5Ljc0MDcxMzMzMDM1MDI1IFsyNTYsIDI1NiwgMTI4XSAwLjAxIHBfZ3JpZF9tb2RlbF9tb2RlbF8zDQozICA1NC40MTE4NTk4Nzg1NDAzNiAgICAgICBbMTI4LCA2NF0gMC4wMSBwX2dyaWRfbW9kZWxfbW9kZWxfMQ0KNCAgMzUuNDM1NjQ0OTQ3NzQwNzEgICAgICAgWzEyOCwgNjRdIDAuMDUgcF9ncmlkX21vZGVsX21vZGVsXzUNCjUgIDM2LjExMjU1MDM0NzE2MDc4ICAgICAgIFsxMjgsIDY0XSAwLjAxIHBfZ3JpZF9tb2RlbF9tb2RlbF82DQo2IDMzLjkyMDA0NTgxODk0NDgzNiAgICAgIFsyNTYsIDEyOF0gMC4wMSBwX2dyaWRfbW9kZWxfbW9kZWxfOA0KNyAgMzcuNjcwNzA3MDU5OTcxMzMgICAgICBbMjU2LCAxMjhdIDAuMDEgcF9ncmlkX21vZGVsX21vZGVsXzQNCjggNDAuNjYxNTc5MzA2NDc4ODE0ICAgICAgWzI1NiwgMTI4XSAwLjA1IHBfZ3JpZF9tb2RlbF9tb2RlbF83DQogICAgICAgICAgICAgICAgIHJtc2UNCjEgIDAuMjcwODEyNzY1NjA3NzM0MQ0KMiAgMC4yNTg2MjI4NTM0ODUwNDg3DQozIDAuMjQ1NzA0OTE4Mjc5MTk0ODMNCjQgMC4yNDM3NzM4Mjg4ODY5MzI1Mw0KNSAgMC4yMDI3NDI1NTM3MDU3NTA3DQo2IDAuMTk3NzQ5MDc0Njg0NTk1MzINCjcgMC4xNTY1MTE5MjA3NzY1MDM0NA0KOCAwLjE1MDc0MzYzOTEyODU4ODkzDQoNCg0KTWVyZ2VkIGJ5IGJ1bGIsIGxlbnMsIHVwDQpgYGB7cn0NCmgyby5pbml0KG50aHJlYWRzID0gMixtYXhfbWVtX3NpemUgPSAiOGciKQ0KDQp1bnNlZW5fYnVsYiA8LSB1bnNlZW5fYnVsYlstYygxNDoxNSldDQp1bnNlZW5fbGVucyA8LSB1bnNlZW5fbGVuc1stbGVuZ3RoKHVuc2Vlbl9sZW5zKV0NCnVuc2Vlbl91cCA8LSB1bnNlZW5fdXBbLWxlbmd0aCh1bnNlZW5fdXApXQ0KdW5zZWVuX2J1bGIgPC0gdW5zZWVuX2J1bGJbLWxlbmd0aCh1bnNlZW5fYnVsYildDQoNCnVuc2Vlbl9idWxiX2gybyA8LSBhcy5oMm8odW5zZWVuX2J1bGIpDQp1bnNlZW5fbGVuc19oMm8gPC0gYXMuaDJvKHVuc2Vlbl9sZW5zKQ0KdW5zZWVuX3VwX2gybyA8LSBhcy5oMm8odW5zZWVuX3VwKQ0KDQp1bnNlZW5fYnVsYiA8LSBjYmluZCh1bnNlZW5fYnVsYixhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLHVuc2Vlbl9idWxiX2gybykpKQ0Kcm1zZSh1bnNlZW5fYnVsYiR0ZW1wX2MsdW5zZWVuX2J1bGIkcHJlZGljdCkNCg0KdW5zZWVuX2xlbnMgPC0gY2JpbmQodW5zZWVuX2xlbnMsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1bnNlZW5fbGVuc19oMm9bLWMoNyw5LDExKV0pKSkNCnJtc2UodW5zZWVuX2xlbnMkdGVtcF9jLHVuc2Vlbl9sZW5zJHByZWRpY3QpDQoNCnVuc2Vlbl91cCA8LSBjYmluZCh1bnNlZW5fdXAsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdW5zZWVuX3VwX2gyb1stYyg3LDksMTEpXSkpKQ0Kcm1zZSh1bnNlZW5fdXAkdGVtcF9jLHVuc2Vlbl91cCRwcmVkaWN0KQ0KDQpgYGANCg0KYnVsYg0KYGBge3J9DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NTAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09NjQpIC0+IGJ1bGIxDQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTIwICYgYz09NjAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09NjQpIC0+IGJ1bGIyDQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTM1ICYgYz09ODUgJiBib3hfeD09ODAgJiBib3hfeT09ODAgJiBib3hfej09OTQpIC0+IGJ1bGIzDQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTQwICYgYz09OTUgJiBib3hfeD09ODAgJiBib3hfeT09ODAgJiBib3hfej09OTQpIC0+IGJ1bGI0DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGJ1bGI1DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTIwICYgYz09NTAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGJ1bGI2DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTIwICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGJ1bGI3DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09ODQpIC0+IGJ1bGI4DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTIwICYgYz09NTAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09ODQpIC0+IGJ1bGI5DQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTM1ICYgYz09OTUgJiBib3hfeD09OTAgJiBib3hfeT09OTAgJiBib3hfej09OTQpIC0+IGJ1bGIxMA0KdW5zZWVuX2J1bGIgJT4lIGZpbHRlcih3PT00MCAmIGM9PTg1ICYgYm94X3g9PTkwICYgYm94X3k9PTkwICYgYm94X3o9PTEwNCkgLT4gYnVsYjExDQp1bnNlZW5fYnVsYiAlPiUgZmlsdGVyKHc9PTM1ICYgYz09OTUgJiBib3hfeD09MTAwICYgYm94X3k9PTEwMCAmIGJveF96PT0xMDQpIC0+IGJ1bGIxMg0KdW5zZWVuX2J1bGIgJT4lIGZpbHRlcih3PT00MCAmIGM9PTg1ICYgYm94X3g9PTEwMCAmIGJveF95PT0xMDAgJiBib3hfej09MTA0KSAtPiBidWxiMTMNCnVuc2Vlbl9idWxiICU+JSBmaWx0ZXIodz09NDAgJiBjPT05NSAmIGJveF94PT0xMDAgJiBib3hfeT09MTAwICYgYm94X3o9PTEwNCkgLT4gYnVsYjE0DQoNCg0KYnVsYjFfaDJvIDwtIGFzLmgybyhidWxiMSkNCmJ1bGIyX2gybyA8LSBhcy5oMm8oYnVsYjIpDQpidWxiM19oMm8gPC0gYXMuaDJvKGJ1bGIzKQ0KYnVsYjRfaDJvIDwtIGFzLmgybyhidWxiNCkNCmJ1bGI1X2gybyA8LSBhcy5oMm8oYnVsYjUpDQpidWxiNl9oMm8gPC0gYXMuaDJvKGJ1bGI2KQ0KYnVsYjdfaDJvIDwtIGFzLmgybyhidWxiNykNCmJ1bGI4X2gybyA8LSBhcy5oMm8oYnVsYjgpDQpidWxiOV9oMm8gPC0gYXMuaDJvKGJ1bGI5KQ0KYnVsYjEwX2gybyA8LSBhcy5oMm8oYnVsYjEwKQ0KYnVsYjExX2gybyA8LSBhcy5oMm8oYnVsYjExKQ0KYnVsYjEyX2gybyA8LSBhcy5oMm8oYnVsYjEyKQ0KYnVsYjEzX2gybyA8LSBhcy5oMm8oYnVsYjEzKQ0KYnVsYjE0X2gybyA8LSBhcy5oMm8oYnVsYjE0KQ0KDQpidWxiMSA8LSBjYmluZChidWxiMSxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxfMUBtb2RlbF9pZFtbMV1dKSxidWxiMV9oMm9bLWMoNyw5LDExKV0pKSkNCmJ1bGIyIDwtIGNiaW5kKGJ1bGIyLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbF8xQG1vZGVsX2lkW1sxXV0pLGJ1bGIyX2gyb1stYyg3LDksMTEpXSkpKQ0KYnVsYjMgPC0gY2JpbmQoYnVsYjMsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsXzFAbW9kZWxfaWRbWzFdXSksYnVsYjNfaDJvWy1jKDcsOSwxMSldKSkpDQpidWxiNCA8LSBjYmluZChidWxiNCxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxfMUBtb2RlbF9pZFtbMV1dKSxidWxiNF9oMm9bLWMoNyw5LDExKV0pKSkNCmJ1bGI1IDwtIGNiaW5kKGJ1bGI1LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbF8xQG1vZGVsX2lkW1sxXV0pLGJ1bGI1X2gyb1stYyg3LDksMTEpXSkpKQ0KYnVsYjYgPC0gY2JpbmQoYnVsYjYsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsXzFAbW9kZWxfaWRbWzFdXSksYnVsYjZfaDJvWy1jKDcsOSwxMSldKSkpDQpidWxiNyA8LSBjYmluZChidWxiNyxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxfMUBtb2RlbF9pZFtbMV1dKSxidWxiN19oMm9bLWMoNyw5LDExKV0pKSkNCmJ1bGI4IDwtIGNiaW5kKGJ1bGI4LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbF8xQG1vZGVsX2lkW1sxXV0pLGJ1bGI4X2gyb1stYyg3LDksMTEpXSkpKQ0KYnVsYjkgPC0gY2JpbmQoYnVsYjksYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsXzFAbW9kZWxfaWRbWzFdXSksYnVsYjlfaDJvWy1jKDcsOSwxMSldKSkpDQpidWxiMTAgPC0gY2JpbmQoYnVsYjEwLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbF8xQG1vZGVsX2lkW1sxXV0pLGJ1bGIxMF9oMm9bLWMoNyw5LDExKV0pKSkNCmJ1bGIxMSA8LSBjYmluZChidWxiMTEsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsXzFAbW9kZWxfaWRbWzFdXSksYnVsYjExX2gyb1stYyg3LDksMTEpXSkpKQ0KYnVsYjEyIDwtIGNiaW5kKGJ1bGIxMixhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwX2dyaWRfbW9kZWxfMUBtb2RlbF9pZFtbMV1dKSxidWxiMTJfaDJvWy1jKDcsOSwxMSldKSkpDQpidWxiMTMgPC0gY2JpbmQoYnVsYjEzLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBfZ3JpZF9tb2RlbF8xQG1vZGVsX2lkW1sxXV0pLGJ1bGIxM19oMm9bLWMoNyw5LDExKV0pKSkNCmJ1bGIxNCA8LSBjYmluZChidWxiMTQsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocF9ncmlkX21vZGVsXzFAbW9kZWxfaWRbWzFdXSksYnVsYjE0X2gyb1stYyg3LDksMTEpXSkpKQ0KDQpybXNlKGJ1bGIxJHRlbXBfYyxidWxiMSRwcmVkaWN0KSAjMy43NjUxMDkNCnJtc2UoYnVsYjIkdGVtcF9jLGJ1bGIyJHByZWRpY3QpICMxLjczOTA0Mw0Kcm1zZShidWxiMyR0ZW1wX2MsYnVsYjMkcHJlZGljdCkgIzEwLjEyMTY4DQpybXNlKGJ1bGI0JHRlbXBfYyxidWxiNCRwcmVkaWN0KSAjMy40MDc2NDYNCnJtc2UoYnVsYjUkdGVtcF9jLGJ1bGI1JHByZWRpY3QpICMyLjczODE0DQpybXNlKGJ1bGI2JHRlbXBfYyxidWxiNiRwcmVkaWN0KSAjMi40ODI5NDkNCnJtc2UoYnVsYjckdGVtcF9jLGJ1bGI3JHByZWRpY3QpICMxLjQwMTU1NQ0Kcm1zZShidWxiOCR0ZW1wX2MsYnVsYjgkcHJlZGljdCkgIzQuMDY0NjE2DQpybXNlKGJ1bGI5JHRlbXBfYyxidWxiOSRwcmVkaWN0KSAjNy45MjkxMDINCnJtc2UoYnVsYjEwJHRlbXBfYyxidWxiMTAkcHJlZGljdCkgIzYuMzA4MzMyDQpybXNlKGJ1bGIxMSR0ZW1wX2MsYnVsYjExJHByZWRpY3QpICM2LjI4MjUzNA0Kcm1zZShidWxiMTIkdGVtcF9jLGJ1bGIxMiRwcmVkaWN0KSAjMC42MjkyODgzDQpybXNlKGJ1bGIxMyR0ZW1wX2MsYnVsYjEzJHByZWRpY3QpICMwLjgzMDkyODYNCnJtc2UoYnVsYjE0JHRlbXBfYyxidWxiMTQkcHJlZGljdCkgIzAuNjgzNTYzMQ0KDQpgYGANCg0KbGVucw0KYGBge3J9DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NTAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09NjQpIC0+IGxlbnMxDQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTIwICYgYz09NjAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09NjQpIC0+IGxlbnMyDQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTM1ICYgYz09ODUgJiBib3hfeD09ODAgJiBib3hfeT09ODAgJiBib3hfej09OTQpIC0+IGxlbnMzDQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTQwICYgYz09OTUgJiBib3hfeD09ODAgJiBib3hfeT09ODAgJiBib3hfej09OTQpIC0+IGxlbnM0DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGxlbnM1DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTIwICYgYz09NTAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGxlbnM2DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTIwICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IGxlbnM3DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09ODQpIC0+IGxlbnM4DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTIwICYgYz09NTAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09ODQpIC0+IGxlbnM5DQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTM1ICYgYz09OTUgJiBib3hfeD09OTAgJiBib3hfeT09OTAgJiBib3hfej09OTQpIC0+IGxlbnMxMA0KdW5zZWVuX2xlbnMgJT4lIGZpbHRlcih3PT00MCAmIGM9PTg1ICYgYm94X3g9PTkwICYgYm94X3k9PTkwICYgYm94X3o9PTEwNCkgLT4gbGVuczExDQp1bnNlZW5fbGVucyAlPiUgZmlsdGVyKHc9PTM1ICYgYz09OTUgJiBib3hfeD09MTAwICYgYm94X3k9PTEwMCAmIGJveF96PT0xMDQpIC0+IGxlbnMxMg0KdW5zZWVuX2xlbnMgJT4lIGZpbHRlcih3PT00MCAmIGM9PTg1ICYgYm94X3g9PTEwMCAmIGJveF95PT0xMDAgJiBib3hfej09MTA0KSAtPiBsZW5zMTMNCnVuc2Vlbl9sZW5zICU+JSBmaWx0ZXIodz09NDAgJiBjPT05NSAmIGJveF94PT0xMDAgJiBib3hfeT09MTAwICYgYm94X3o9PTEwNCkgLT4gbGVuczE0DQoNCmxlbnMxX2gybyA8LSBhcy5oMm8obGVuczEpDQpsZW5zMl9oMm8gPC0gYXMuaDJvKGxlbnMyKQ0KbGVuczNfaDJvIDwtIGFzLmgybyhsZW5zMykNCmxlbnM0X2gybyA8LSBhcy5oMm8obGVuczQpDQpsZW5zNV9oMm8gPC0gYXMuaDJvKGxlbnM1KQ0KbGVuczZfaDJvIDwtIGFzLmgybyhsZW5zNikNCmxlbnM3X2gybyA8LSBhcy5oMm8obGVuczcpDQpsZW5zOF9oMm8gPC0gYXMuaDJvKGxlbnM4KQ0KbGVuczlfaDJvIDwtIGFzLmgybyhsZW5zOSkNCmxlbnMxMF9oMm8gPC0gYXMuaDJvKGxlbnMxMCkNCmxlbnMxMV9oMm8gPC0gYXMuaDJvKGxlbnMxMSkNCmxlbnMxMl9oMm8gPC0gYXMuaDJvKGxlbnMxMikNCmxlbnMxM19oMm8gPC0gYXMuaDJvKGxlbnMxMykNCmxlbnMxNF9oMm8gPC0gYXMuaDJvKGxlbnMxNCkNCg0KbGVuczEgPC0gY2JpbmQobGVuczEsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfcF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSxsZW5zMV9oMm9bLWMoNyw5LDExKV0pKSkNCmxlbnMyIDwtIGNiaW5kKGxlbnMyLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX3BfbGVuc19tb2RlbEBtb2RlbF9pZHNbWzFdXSksbGVuczJfaDJvWy1jKDcsOSwxMSldKSkpDQpsZW5zMyA8LSBjYmluZChsZW5zMyxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9wX2xlbnNfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLGxlbnMzX2gyb1stYyg3LDksMTEpXSkpKQ0KbGVuczQgPC0gY2JpbmQobGVuczQsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfcF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSxsZW5zNF9oMm9bLWMoNyw5LDExKV0pKSkNCmxlbnM1IDwtIGNiaW5kKGxlbnM1LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX3BfbGVuc19tb2RlbEBtb2RlbF9pZHNbWzFdXSksbGVuczVfaDJvWy1jKDcsOSwxMSldKSkpDQpsZW5zNiA8LSBjYmluZChsZW5zNixhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9wX2xlbnNfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLGxlbnM2X2gyb1stYyg3LDksMTEpXSkpKQ0KbGVuczcgPC0gY2JpbmQobGVuczcsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfcF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSxsZW5zN19oMm9bLWMoNyw5LDExKV0pKSkNCmxlbnM4IDwtIGNiaW5kKGxlbnM4LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX3BfbGVuc19tb2RlbEBtb2RlbF9pZHNbWzFdXSksbGVuczhfaDJvWy1jKDcsOSwxMSldKSkpDQpsZW5zOSA8LSBjYmluZChsZW5zOSxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9wX2xlbnNfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLGxlbnM5X2gyb1stYyg3LDksMTEpXSkpKQ0KbGVuczEwIDwtIGNiaW5kKGxlbnMxMCxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9wX2xlbnNfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLGxlbnMxMF9oMm9bLWMoNyw5LDExKV0pKSkNCmxlbnMxMSA8LSBjYmluZChsZW5zMTEsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfcF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSxsZW5zMTFfaDJvWy1jKDcsOSwxMSldKSkpDQpsZW5zMTIgPC0gY2JpbmQobGVuczEyLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX3BfbGVuc19tb2RlbEBtb2RlbF9pZHNbWzFdXSksbGVuczEyX2gyb1stYyg3LDksMTEpXSkpKQ0KbGVuczEzIDwtIGNiaW5kKGxlbnMxMyxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9wX2xlbnNfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLGxlbnMxM19oMm9bLWMoNyw5LDExKV0pKSkNCmxlbnMxNCA8LSBjYmluZChsZW5zMTQsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfcF9sZW5zX21vZGVsQG1vZGVsX2lkc1tbMV1dKSxsZW5zMTRfaDJvWy1jKDcsOSwxMSldKSkpDQoNCnJtc2UobGVuczEkdGVtcF9jLGxlbnMxJHByZWRpY3QpICMyLjUzDQpybXNlKGxlbnMyJHRlbXBfYyxsZW5zMiRwcmVkaWN0KSAjMi45MQ0Kcm1zZShsZW5zMyR0ZW1wX2MsbGVuczMkcHJlZGljdCkgIzMyLjEwDQpybXNlKGxlbnM0JHRlbXBfYyxsZW5zNCRwcmVkaWN0KSAjNS41MA0Kcm1zZShsZW5zNSR0ZW1wX2MsbGVuczUkcHJlZGljdCkgIzAuOTANCnJtc2UobGVuczYkdGVtcF9jLGxlbnM2JHByZWRpY3QpICMyLjQzDQpybXNlKGxlbnM3JHRlbXBfYyxsZW5zNyRwcmVkaWN0KSAjMS4yNg0Kcm1zZShsZW5zOCR0ZW1wX2MsbGVuczgkcHJlZGljdCkgIzUuNjkNCnJtc2UobGVuczkkdGVtcF9jLGxlbnM5JHByZWRpY3QpICM4LjU5DQpybXNlKGxlbnMxMCR0ZW1wX2MsbGVuczEwJHByZWRpY3QpICMxLjQ3DQpybXNlKGxlbnMxMSR0ZW1wX2MsbGVuczExJHByZWRpY3QpICM1LjU0DQpybXNlKGxlbnMxMiR0ZW1wX2MsbGVuczEyJHByZWRpY3QpICMxLjkzDQpybXNlKGxlbnMxMyR0ZW1wX2MsbGVuczEzJHByZWRpY3QpICMyLjk1DQpybXNlKGxlbnMxNCR0ZW1wX2MsbGVuczE0JHByZWRpY3QpICMyLjE2DQoNCmBgYA0KDQp1cA0KYGBge3J9DQp1bnNlZW5fdXAgJT4lIGZpbHRlcih3PT0xNSAmIGM9PTUwICYgYm94X3g9PTY1ICYgYm94X3k9PTY1ICYgYm94X3o9PTY0KSAtPiB1cDENCnVuc2Vlbl91cCAlPiUgZmlsdGVyKHc9PTIwICYgYz09NjAgJiBib3hfeD09NjUgJiBib3hfeT09NjUgJiBib3hfej09NjQpIC0+IHVwMg0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09MzUgJiBjPT04NSAmIGJveF94PT04MCAmIGJveF95PT04MCAmIGJveF96PT05NCkgLT4gdXAzDQp1bnNlZW5fdXAgJT4lIGZpbHRlcih3PT00MCAmIGM9PTk1ICYgYm94X3g9PTgwICYgYm94X3k9PTgwICYgYm94X3o9PTk0KSAtPiB1cDQNCnVuc2Vlbl91cCAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09NjQpIC0+IHVwNQ0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09MjAgJiBjPT01MCAmIGJveF94PT02MCAmIGJveF95PT02MCAmIGJveF96PT02NCkgLT4gdXA2DQp1bnNlZW5fdXAgJT4lIGZpbHRlcih3PT0yMCAmIGM9PTYwICYgYm94X3g9PTYwICYgYm94X3k9PTYwICYgYm94X3o9PTY0KSAtPiB1cDcNCnVuc2Vlbl91cCAlPiUgZmlsdGVyKHc9PTE1ICYgYz09NjAgJiBib3hfeD09NjAgJiBib3hfeT09NjAgJiBib3hfej09ODQpIC0+IHVwOA0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09MjAgJiBjPT01MCAmIGJveF94PT02NSAmIGJveF95PT02NSAmIGJveF96PT04NCkgLT4gdXA5DQp1bnNlZW5fdXAgJT4lIGZpbHRlcih3PT0zNSAmIGM9PTk1ICYgYm94X3g9PTkwICYgYm94X3k9PTkwICYgYm94X3o9PTk0KSAtPiB1cDEwDQp1bnNlZW5fdXAgJT4lIGZpbHRlcih3PT00MCAmIGM9PTg1ICYgYm94X3g9PTkwICYgYm94X3k9PTkwICYgYm94X3o9PTEwNCkgLT4gdXAxMQ0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09MzUgJiBjPT05NSAmIGJveF94PT0xMDAgJiBib3hfeT09MTAwICYgYm94X3o9PTEwNCkgLT4gdXAxMg0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09NDAgJiBjPT04NSAmIGJveF94PT0xMDAgJiBib3hfeT09MTAwICYgYm94X3o9PTEwNCkgLT4gdXAxMw0KdW5zZWVuX3VwICU+JSBmaWx0ZXIodz09NDAgJiBjPT05NSAmIGJveF94PT0xMDAgJiBib3hfeT09MTAwICYgYm94X3o9PTEwNCkgLT4gdXAxNA0KDQp1cDFfaDJvIDwtIGFzLmgybyh1cDEpDQp1cDJfaDJvIDwtIGFzLmgybyh1cDIpDQp1cDNfaDJvIDwtIGFzLmgybyh1cDMpDQp1cDRfaDJvIDwtIGFzLmgybyh1cDQpDQp1cDVfaDJvIDwtIGFzLmgybyh1cDUpDQp1cDZfaDJvIDwtIGFzLmgybyh1cDYpDQp1cDdfaDJvIDwtIGFzLmgybyh1cDcpDQp1cDhfaDJvIDwtIGFzLmgybyh1cDgpDQp1cDlfaDJvIDwtIGFzLmgybyh1cDkpDQp1cDEwX2gybyA8LSBhcy5oMm8odXAxMCkNCnVwMTFfaDJvIDwtIGFzLmgybyh1cDExKQ0KdXAxMl9oMm8gPC0gYXMuaDJvKHVwMTIpDQp1cDEzX2gybyA8LSBhcy5oMm8odXAxMykNCnVwMTRfaDJvIDwtIGFzLmgybyh1cDE0KQ0KDQp1cDEgPC0gY2JpbmQodXAxLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX2hfdXBfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLHVwMV9oMm9bLWMoNyw5LDExKV0pKSkNCnVwMiA8LSBjYmluZCh1cDIsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdXAyX2gyb1stYyg3LDksMTEpXSkpKQ0KdXAzIDwtIGNiaW5kKHVwMyxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9oX3VwX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1cDNfaDJvWy1jKDcsOSwxMSldKSkpDQp1cDQgPC0gY2JpbmQodXA0LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX2hfdXBfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLHVwNF9oMm9bLWMoNyw5LDExKV0pKSkNCnVwNSA8LSBjYmluZCh1cDUsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdXA1X2gyb1stYyg3LDksMTEpXSkpKQ0KdXA2IDwtIGNiaW5kKHVwNixhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9oX3VwX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1cDZfaDJvWy1jKDcsOSwxMSldKSkpDQp1cDcgPC0gY2JpbmQodXA3LGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX2hfdXBfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLHVwN19oMm9bLWMoNyw5LDExKV0pKSkNCnVwOCA8LSBjYmluZCh1cDgsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdXA4X2gyb1stYyg3LDksMTEpXSkpKQ0KdXA5IDwtIGNiaW5kKHVwOSxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9oX3VwX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1cDlfaDJvWy1jKDcsOSwxMSldKSkpDQp1cDEwIDwtIGNiaW5kKHVwMTAsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdXAxMF9oMm9bLWMoNyw5LDExKV0pKSkNCnVwMTEgPC0gY2JpbmQodXAxMSxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9oX3VwX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1cDExX2gyb1stYyg3LDksMTEpXSkpKQ0KdXAxMiA8LSBjYmluZCh1cDEyLGFzLmRhdGEuZnJhbWUoaDJvLnByZWRpY3QoaDJvLmdldE1vZGVsKHBsYW5lX2hfdXBfbW9kZWxAbW9kZWxfaWRzW1sxXV0pLHVwMTJfaDJvWy1jKDcsOSwxMSldKSkpDQp1cDEzIDwtIGNiaW5kKHVwMTMsYXMuZGF0YS5mcmFtZShoMm8ucHJlZGljdChoMm8uZ2V0TW9kZWwocGxhbmVfaF91cF9tb2RlbEBtb2RlbF9pZHNbWzFdXSksdXAxM19oMm9bLWMoNyw5LDExKV0pKSkNCnVwMTQgPC0gY2JpbmQodXAxNCxhcy5kYXRhLmZyYW1lKGgyby5wcmVkaWN0KGgyby5nZXRNb2RlbChwbGFuZV9oX3VwX21vZGVsQG1vZGVsX2lkc1tbMV1dKSx1cDE0X2gyb1stYyg3LDksMTEpXSkpKQ0KDQoNCg0Kcm1zZSh1cDEkdGVtcF9jLHVwMSRwcmVkaWN0KSAjMTguNTcNCnJtc2UodXAyJHRlbXBfYyx1cDIkcHJlZGljdCkgIzExLjY0DQpybXNlKHVwMyR0ZW1wX2MsdXAzJHByZWRpY3QpICM0MC42MQ0Kcm1zZSh1cDQkdGVtcF9jLHVwNCRwcmVkaWN0KSAjMy44OA0Kcm1zZSh1cDUkdGVtcF9jLHVwNSRwcmVkaWN0KSAjMTguNDQNCnJtc2UodXA2JHRlbXBfYyx1cDYkcHJlZGljdCkgIzExLjU4DQpybXNlKHVwNyR0ZW1wX2MsdXA3JHByZWRpY3QpICMxMS4zOA0Kcm1zZSh1cDgkdGVtcF9jLHVwOCRwcmVkaWN0KSAjMTguODcNCnJtc2UodXA5JHRlbXBfYyx1cDkkcHJlZGljdCkgIzEzLjYzDQpybXNlKHVwMTAkdGVtcF9jLHVwMTAkcHJlZGljdCkgIzMuNTcNCnJtc2UodXAxMSR0ZW1wX2MsdXAxMSRwcmVkaWN0KSAjMy44OA0Kcm1zZSh1cDEyJHRlbXBfYyx1cDEyJHByZWRpY3QpICMyLjU5DQpybXNlKHVwMTMkdGVtcF9jLHVwMTMkcHJlZGljdCkgIzIuNzcNCnJtc2UodXAxNCR0ZW1wX2MsdXAxNCRwcmVkaWN0KSAjMi40Mg0KDQpgYGANCg0KDQoNCg0K