load library and start h2o

library(h2o)
library(data.table)
library(ggplot2)
h2o.init()
 Connection successful!

R is connected to the H2O cluster: 
    H2O cluster uptime:         2 hours 18 minutes 
    H2O cluster version:        3.10.5.3 
    H2O cluster version age:    2 months and 25 days  
    H2O cluster name:           H2O_started_from_R_r631758_qgy865 
    H2O cluster total nodes:    1 
    H2O cluster total memory:   3.19 GB 
    H2O cluster total cores:    8 
    H2O cluster allowed cores:  8 
    H2O cluster healthy:        TRUE 
    H2O Connection ip:          localhost 
    H2O Connection port:        54321 
    H2O Connection proxy:       NA 
    H2O Internal Security:      FALSE 
    R Version:                  R version 3.4.1 (2017-06-30) 
# airlines<-h2o.importFile("C:\\Users\\r631758\\Desktop\\r631758\\R codes\\H2O\\exercise\\allyears2k_headers.csv")
raw <- h2o.importFile(path = "C:\\Users\\r631758\\Desktop\\r631758\\R codes\\H2O\\exercise\\allyears2k_headers.csv", parse=FALSE)
setup <- h2o.parseSetup(raw)
setup$column_types[which(setup$column_names %in% "AirTime")]  <- "Numeric"
setup$column_types[which(setup$column_names %in% "AirDelay")] <- "Numeric"
airlines.hex <- h2o.parseRaw(raw, col.types=setup$column_types)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=====================================================================================================| 100%
airlines<-fread("C:\\Users\\r631758\\Desktop\\r631758\\R codes\\H2O\\exercise\\allyears2k_headers.csv")
str(airlines)
Classes ‘data.table’ and 'data.frame':  43978 obs. of  31 variables:
 $ Year             : int  1987 1987 1987 1987 1987 1987 1987 1987 1987 1987 ...
 $ Month            : int  10 10 10 10 10 10 10 10 10 10 ...
 $ DayofMonth       : int  14 15 17 18 19 21 22 23 24 25 ...
 $ DayOfWeek        : int  3 4 6 7 1 3 4 5 6 7 ...
 $ DepTime          : int  741 729 741 729 749 728 728 731 744 729 ...
 $ CRSDepTime       : int  730 730 730 730 730 730 730 730 730 730 ...
 $ ArrTime          : int  912 903 918 847 922 848 852 902 908 851 ...
 $ CRSArrTime       : int  849 849 849 849 849 849 849 849 849 849 ...
 $ UniqueCarrier    : chr  "PS" "PS" "PS" "PS" ...
 $ FlightNum        : int  1451 1451 1451 1451 1451 1451 1451 1451 1451 1451 ...
 $ TailNum          : chr  NA NA NA NA ...
 $ ActualElapsedTime: int  91 94 97 78 93 80 84 91 84 82 ...
 $ CRSElapsedTime   : int  79 79 79 79 79 79 79 79 79 79 ...
 $ AirTime          : int  NA NA NA NA NA NA NA NA NA NA ...
 $ ArrDelay         : int  23 14 29 -2 33 -1 3 13 19 2 ...
 $ DepDelay         : int  11 -1 11 -1 19 -2 -2 1 14 -1 ...
 $ Origin           : chr  "SAN" "SAN" "SAN" "SAN" ...
 $ Dest             : chr  "SFO" "SFO" "SFO" "SFO" ...
 $ Distance         : int  447 447 447 447 447 447 447 447 447 447 ...
 $ TaxiIn           : int  NA NA NA NA NA NA NA NA NA NA ...
 $ TaxiOut          : int  NA NA NA NA NA NA NA NA NA NA ...
 $ Cancelled        : int  0 0 0 0 0 0 0 0 0 0 ...
 $ CancellationCode : chr  NA NA NA NA ...
 $ Diverted         : int  0 0 0 0 0 0 0 0 0 0 ...
 $ CarrierDelay     : int  NA NA NA NA NA NA NA NA NA NA ...
 $ WeatherDelay     : int  NA NA NA NA NA NA NA NA NA NA ...
 $ NASDelay         : int  NA NA NA NA NA NA NA NA NA NA ...
 $ SecurityDelay    : int  NA NA NA NA NA NA NA NA NA NA ...
 $ LateAircraftDelay: int  NA NA NA NA NA NA NA NA NA NA ...
 $ IsArrDelayed     : chr  "YES" "YES" "YES" "NO" ...
 $ IsDepDelayed     : chr  "YES" "NO" "YES" "NO" ...
 - attr(*, ".internal.selfref")=<externalptr> 
airlines$UniqueCarrier<-as.factor(airlines$UniqueCarrier)
summary(airlines)
      Year          Month          DayofMonth     DayOfWeek        DepTime       CRSDepTime      ArrTime    
 Min.   :1987   Min.   : 1.000   Min.   : 1.0   Min.   :1.000   Min.   :   1   Min.   :   0   Min.   :   1  
 1st Qu.:1992   1st Qu.: 1.000   1st Qu.: 6.0   1st Qu.:2.000   1st Qu.: 929   1st Qu.: 910   1st Qu.:1118  
 Median :1998   Median : 1.000   Median :14.0   Median :4.000   Median :1330   Median :1320   Median :1527  
 Mean   :1998   Mean   : 1.409   Mean   :14.6   Mean   :3.821   Mean   :1346   Mean   :1313   Mean   :1505  
 3rd Qu.:2003   3rd Qu.: 1.000   3rd Qu.:23.0   3rd Qu.:5.000   3rd Qu.:1735   3rd Qu.:1720   3rd Qu.:1917  
 Max.   :2008   Max.   :10.000   Max.   :31.0   Max.   :7.000   Max.   :2400   Max.   :2359   Max.   :2400  
                                                                NA's   :1086                  NA's   :1195  
   CRSArrTime   UniqueCarrier     FlightNum        TailNum          ActualElapsedTime CRSElapsedTime
 Min.   :   0   US     :18729   Min.   :   1.0   Length:43978       Min.   : 16.0     Min.   : 17   
 1st Qu.:1109   UA     : 9434   1st Qu.: 204.0   Class :character   1st Qu.: 71.0     1st Qu.: 71   
 Median :1516   WN     : 6170   Median : 557.0   Mode  :character   Median :101.0     Median :102   
 Mean   :1485   HP     : 3451   Mean   : 818.8                      Mean   :124.8     Mean   :125   
 3rd Qu.:1903   PS     : 3212   3rd Qu.:1242.0                      3rd Qu.:151.0     3rd Qu.:151   
 Max.   :2359   DL     :  935   Max.   :3949.0                      Max.   :475.0     Max.   :437   
                (Other): 2047                                       NA's   :1195      NA's   :13    
    AirTime         ArrDelay          DepDelay         Origin              Dest              Distance     
 Min.   : 14.0   Min.   :-63.000   Min.   :-16.00   Length:43978       Length:43978       Min.   :  11.0  
 1st Qu.: 61.0   1st Qu.: -6.000   1st Qu.: -2.00   Class :character   Class :character   1st Qu.: 326.0  
 Median : 91.0   Median :  2.000   Median :  1.00   Mode  :character   Mode  :character   Median : 541.0  
 Mean   :114.3   Mean   :  9.317   Mean   : 10.01                                         Mean   : 730.2  
 3rd Qu.:140.0   3rd Qu.: 14.000   3rd Qu.: 10.00                                         3rd Qu.: 920.0  
 Max.   :402.0   Max.   :475.000   Max.   :473.00                                         Max.   :3365.0  
 NA's   :16649   NA's   :1195      NA's   :1086                                           NA's   :35      
     TaxiIn           TaxiOut         Cancelled       CancellationCode      Diverted         CarrierDelay   
 Min.   :  0.000   Min.   :  0.00   Min.   :0.00000   Length:43978       Min.   :0.000000   Min.   :  0.00  
 1st Qu.:  3.000   1st Qu.:  9.00   1st Qu.:0.00000   Class :character   1st Qu.:0.000000   1st Qu.:  0.00  
 Median :  5.000   Median : 12.00   Median :0.00000   Mode  :character   Median :0.000000   Median :  0.00  
 Mean   :  5.381   Mean   : 14.17   Mean   :0.02469                      Mean   :0.002478   Mean   :  4.05  
 3rd Qu.:  6.000   3rd Qu.: 16.00   3rd Qu.:0.00000                      3rd Qu.:0.000000   3rd Qu.:  0.00  
 Max.   :128.000   Max.   :254.00   Max.   :1.00000                      Max.   :1.000000   Max.   :369.00  
 NA's   :16026     NA's   :16024                                                            NA's   :35045   
  WeatherDelay       NASDelay      SecurityDelay   LateAircraftDelay IsArrDelayed       IsDepDelayed      
 Min.   :  0.00   Min.   :  0.00   Min.   : 0.00   Min.   :  0.00    Length:43978       Length:43978      
 1st Qu.:  0.00   1st Qu.:  0.00   1st Qu.: 0.00   1st Qu.:  0.00    Class :character   Class :character  
 Median :  0.00   Median :  0.00   Median : 0.00   Median :  0.00    Mode  :character   Mode  :character  
 Mean   :  0.29   Mean   :  4.86   Mean   : 0.02   Mean   :  7.62                                         
 3rd Qu.:  0.00   3rd Qu.:  0.00   3rd Qu.: 0.00   3rd Qu.:  0.00                                         
 Max.   :201.00   Max.   :323.00   Max.   :14.00   Max.   :373.00                                         
 NA's   :35045    NA's   :35045    NA's   :35045   NA's   :35045                                          
ggplot(airlines, aes(x=Year))+geom_histogram()

# table(airlines$Year)
ggplot(airlines, aes(x=Month))+geom_histogram()

# table(airlines$Month)
hist(airlines$Year)

hist(airlines$Month)

airlines.h2o<-as.h2o(airlines)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=====================================================================================================| 100%

Create scatter plots by taking a random sample into R to plot and graphing linear fit

scatter_plot<-function(data,x,y,max_points=1000, fit=T){
  if(fit){
    lr<-h2o.glm(x=x,y=y,training_frame = data,family="gaussian")
      coeff<-lr@model$coefficients_table$coefficients
  }
  df<-data[,c(x,y)]
  runif<-h2o.runif(df)
  df.subset<-df[runif < max_points/nrow(data),]
  df.R<-as.data.frame(df.subset)
  h2o.rm(df.subset)
  if (fit) h2o.rm(lr@model_id)
  
  plot(x=df.R[,x],y=df.R[,y], col="blue", xlab=x, ylab=y)
  if (fit) abline(coef=coeff,col="black")
}
scatter_plot(data=airlines.h2o,x="Distance", y="AirTime", fit=T)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=====================================================================================================| 100%

# lr<-h2o.glm(x="Distance",y="AirTime",training_frame = airlines.h2o,family="gaussian")
scatter_plot(data = airlines.h2o, x = "UniqueCarrier", y = "ArrDelay", max_points = 5000, fit = F)

# lr<-h2o.glm(x="UniqueCarrier",y="ArrDelay",training_frame = airlines.h2o,family="gaussian")
# lr<-h2o.glm(x="Distance",y="AirTime",training_frame =airlines.h2o,family="gaussian")

Flight by Month calculated using H2O’s fast groupby

print("Splitting data into group of 12 month and aggregating on two columns...")
[1] "Splitting data into group of 12 month and aggregating on two columns..."
flightBymonth<-h2o.group_by(data=airlines.h2o,by="Month", nrow("Month"), sum("Cancelled"))
flightBymonth.R<-as.data.frame(flightBymonth)

Set Column Type for Enumerator or Factor Columns

airlines.h2o$Year<-as.factor(airlines.h2o$Year)
airlines.h2o$Month<-as.factor(airlines.h2o$Month)
airlines.h2o$DayOfWeek<-as.factor(airlines.h2o$DayOfWeek)
airlines.h2o$Cancelled<-as.factor(airlines.h2o$Cancelled)
airlines.h2o$FlightNum<-as.factor(airlines.h2o$FlightNum)
airlines.h2o$Origin<-as.factor(airlines.h2o$Origin)
airlines.h2o$Dest<-as.factor(airlines.h2o$Dest)
airlines.h2o$IsDepDelayed<-as.factor(airlines.h2o$IsDepDelayed)

Parameter Creation

hour1<-airlines.h2o$CRSArrTime %/% 100
mins1<-airlines.h2o$CRSArrTime %% 100
arrTime<-hour1*60+mins1
hour2 <- airlines.h2o$CRSDepTime %/% 100
mins2 <- airlines.h2o$CRSDepTime %% 100
depTime <- hour2*60+mins2
travelTime <- ifelse(arrTime - depTime > 0, arrTime - depTime, NA)
airlines.h2o$TravelTime <- travelTime
scatter_plot(airlines.h2o, "Distance", "TravelTime")

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=====================================================================================================| 100%

imputation: You can also choose to impute missing value by taking the mean of subsets

h2o.impute(data=airlines.h2o, column="Distance", by=c("Origin", "Dest"))
  Origin Dest mean_Distance
1    ABE  CLT           481
2    ABE  PIT           253
3    ABQ  AMA           277
4    ABQ  BWI          1670
5    ABQ  DAL           580
6    ABQ  DEN           349

[1517 rows x 3 columns] 
scatter_plot(airlines.h2o, "Distance", "TravelTime")

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=====================================================================================================| 100%

create test/train split

data.split<-h2o.splitFrame(data=airlines.h2o,ratio=0.8)
data.train<-data.split[[1]]
data.test<-data.split[[2]]

set the predictor names and the response column name

Build GLM

start<-Sys.time()
data.glm<-h2o.glm(y=response,x=predictors,training_frame = data.train, validation_frame = data.test, family="binomial", standardize = T, model_id = "glm_model", alpha=0.5, lambda=1e-05)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |==                                                                                                   |   2%
  |                                                                                                           
  |=====================================================================================================| 100%
glm_time<-Sys.time()-start
print(paste("Took", round(glm_time, digits=2), units(glm_time), "to build logistic regression model."))
[1] "Took 1.62 secs to build logistic regression model."

Build GBM model

predictors=c("Year", "UniqueCarrier","DayOfWeek","Month","Distance")
start<-Sys.time()
#for balance classes https://h2o-release.s3.amazonaws.com/h2o/rel-ueno/2/docs-website/h2o-docs/data-science/algo-params/balance_classes.html
data.gbm<-h2o.gbm(y=response, x=predictors, balance_classes=T,training_frame = data.train, validation_frame = data.test, ntrees=100, max_depth=5, model_id="gbm_model", distribution="bernoulli", learn_rate = .1, min_rows=2)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=                                                                                                    |   1%
  |                                                                                                           
  |===============                                                                                      |  15%
  |                                                                                                           
  |=====================                                                                                |  21%
  |                                                                                                           
  |=========================                                                                            |  25%
  |                                                                                                           
  |=====================================                                                                |  37%
  |                                                                                                           
  |=====================================================================================================| 100%
gbm_time<-Sys.time()-start
print(paste("Took", round(gbm_time, digits = 2), units(gbm_time), "to build a GBM model.")) 
[1] "Took 6.97 secs to build a GBM model."

Build random forest mdoel

predictors=c("Year", "UniqueCarrier","DayOfWeek","Month","Distance")
start<-Sys.time()
data.drf<-h2o.randomForest(y=response, x=predictors, training_frame = data.train, validation_frame = data.test, ntrees=1500, max_depth=5, model_id="drf_model", balance_classes = T)

  |                                                                                                           
  |                                                                                                     |   0%
  |                                                                                                           
  |=                                                                                                    |   1%
  |                                                                                                           
  |==                                                                                                   |   2%
  |                                                                                                           
  |==================                                                                                   |  17%
  |                                                                                                           
  |==================================                                                                   |  34%
  |                                                                                                           
  |==================================================                                                   |  50%
  |                                                                                                           
  |=============================================================                                        |  60%
  |                                                                                                           
  |==========================================================================                           |  74%
  |                                                                                                           
  |===========================================================================================          |  90%
  |                                                                                                           
  |=====================================================================================================| 100%
drf_time <- Sys.time() - start
print(paste("Took", round(drf_time, digits = 2), units(drf_time), "to build a Random Forest model."))
[1] "Took 29.27 secs to build a Random Forest model."

comparing running tiem with randoforest package

cannot handle predictors more than 53 categories

library(randomForest)
library(caret)
trainIndex=createDataPartition(airlines$IsDepDelayed,p=0.7, list=FALSE, times=1)
#https://www.rdocumentation.org/packages/caret/versions/6.0-76/topics/createDataPartition
airlines$Year<-as.factor(airlines$Year)
airlines$Month<-as.factor(airlines$Month)
airlines$DayOfWeek<-as.factor(airlines$DayOfWeek)
airlines$Cancelled<-as.factor(airlines$Cancelled)
airlines$FlightNum<-as.factor(airlines$FlightNum)
airlines$Origin<-as.factor(airlines$Origin)
airlines$Dest<-as.factor(airlines$Dest)
airlines$IsDepDelayed<-as.factor(airlines$IsDepDelayed)
training<-airlines[trainIndex,]
testing<-airlines[-trainIndex,]
training<-as.data.frame(training)
testing<-as.data.frame(testing)
start<-Sys.time()
fit <- randomForest(IsDepDelayed ~ Year+UniqueCarrier+DayOfWeek+Month+Distance,
                      data=training, 
                      importance=TRUE, 
                      ntree=1500, na.action=na.omit)
drf_time <- Sys.time() - start
print(paste("Took", round(drf_time, digits = 2), units(drf_time), "to build a Random Forest model under randomForest package."))
[1] "Took 44.74 secs to build a Random Forest model under randomForest package."

build deep learning model

start   <- Sys.time()
data.dl<-h2o.deeplearning(y=response, x=predictors, training_frame = data.train, validation_frame = data.test, hidden=c(10,10), epochs = 5, balance_classes=T, loss="Automatic", variable_importances=T)
dl_time <- Sys.time() - start
print(paste("Took", round(dl_time, digits = 2), units(dl_time), "to build a Deep Learning model."))

Variable Importance - For feature selection and rerunning a model build

print("GLM: Sorted Standardized Coefficient Magnitudes To Find Nonzero Coefficients")
data.glm@model$standardized_coefficient_magnitudes
print("GBM: Variable Importance")
data.gbm@model$variable_importances
print("Random Forest: Variable Importance")
data.drf@model$variable_importances
print("Deep Learning: Variable Importance")
data.dl@model$variable_importances
LS0tDQp0aXRsZTogImFpcmxpbmUgZGVsYXkgcHJlZGljdGlvbiBhbmFseXNpcyBieSBIMm8iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCiNsb2FkIGxpYnJhcnkgYW5kIHN0YXJ0IGgybw0KYGBge3J9DQpsaWJyYXJ5KGgybykNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoZ2dwbG90MikNCmgyby5pbml0KCkNCmBgYA0KDQpgYGB7cn0NCiMgYWlybGluZXM8LWgyby5pbXBvcnRGaWxlKCJDOlxcVXNlcnNcXHI2MzE3NThcXERlc2t0b3BcXHI2MzE3NThcXFIgY29kZXNcXEgyT1xcZXhlcmNpc2VcXGFsbHllYXJzMmtfaGVhZGVycy5jc3YiKQ0KDQoNCnJhdyA8LSBoMm8uaW1wb3J0RmlsZShwYXRoID0gIkM6XFxVc2Vyc1xccjYzMTc1OFxcRGVza3RvcFxccjYzMTc1OFxcUiBjb2Rlc1xcSDJPXFxleGVyY2lzZVxcYWxseWVhcnMya19oZWFkZXJzLmNzdiIsIHBhcnNlPUZBTFNFKQ0Kc2V0dXAgPC0gaDJvLnBhcnNlU2V0dXAocmF3KQ0Kc2V0dXAkY29sdW1uX3R5cGVzW3doaWNoKHNldHVwJGNvbHVtbl9uYW1lcyAlaW4lICJBaXJUaW1lIildICA8LSAiTnVtZXJpYyINCnNldHVwJGNvbHVtbl90eXBlc1t3aGljaChzZXR1cCRjb2x1bW5fbmFtZXMgJWluJSAiQWlyRGVsYXkiKV0gPC0gIk51bWVyaWMiDQphaXJsaW5lcy5oZXggPC0gaDJvLnBhcnNlUmF3KHJhdywgY29sLnR5cGVzPXNldHVwJGNvbHVtbl90eXBlcykNCg0KDQphaXJsaW5lczwtZnJlYWQoIkM6XFxVc2Vyc1xccjYzMTc1OFxcRGVza3RvcFxccjYzMTc1OFxcUiBjb2Rlc1xcSDJPXFxleGVyY2lzZVxcYWxseWVhcnMya19oZWFkZXJzLmNzdiIpDQpzdHIoYWlybGluZXMpDQoNCg0KYWlybGluZXMkVW5pcXVlQ2FycmllcjwtYXMuZmFjdG9yKGFpcmxpbmVzJFVuaXF1ZUNhcnJpZXIpDQpzdW1tYXJ5KGFpcmxpbmVzKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmdncGxvdChhaXJsaW5lcywgYWVzKHg9WWVhcikpK2dlb21faGlzdG9ncmFtKCkNCiMgdGFibGUoYWlybGluZXMkWWVhcikNCmdncGxvdChhaXJsaW5lcywgYWVzKHg9TW9udGgpKStnZW9tX2hpc3RvZ3JhbSgpDQojIHRhYmxlKGFpcmxpbmVzJE1vbnRoKQ0KaGlzdChhaXJsaW5lcyRZZWFyKQ0KaGlzdChhaXJsaW5lcyRNb250aCkNCg0KYWlybGluZXMuaDJvPC1hcy5oMm8oYWlybGluZXMpDQpgYGANCg0KI0NyZWF0ZSBzY2F0dGVyIHBsb3RzIGJ5IHRha2luZyBhIHJhbmRvbSBzYW1wbGUgaW50byBSIHRvIHBsb3QgYW5kIGdyYXBoaW5nIGxpbmVhciBmaXQNCmBgYHtyfQ0Kc2NhdHRlcl9wbG90PC1mdW5jdGlvbihkYXRhLHgseSxtYXhfcG9pbnRzPTEwMDAsIGZpdD1UKXsNCiAgaWYoZml0KXsNCiAgICBscjwtaDJvLmdsbSh4PXgseT15LHRyYWluaW5nX2ZyYW1lID0gZGF0YSxmYW1pbHk9ImdhdXNzaWFuIikNCiAgICAgIGNvZWZmPC1sckBtb2RlbCRjb2VmZmljaWVudHNfdGFibGUkY29lZmZpY2llbnRzDQogIH0NCiAgZGY8LWRhdGFbLGMoeCx5KV0NCiAgcnVuaWY8LWgyby5ydW5pZihkZikNCiAgZGYuc3Vic2V0PC1kZltydW5pZiA8IG1heF9wb2ludHMvbnJvdyhkYXRhKSxdDQogIGRmLlI8LWFzLmRhdGEuZnJhbWUoZGYuc3Vic2V0KQ0KICBoMm8ucm0oZGYuc3Vic2V0KQ0KICBpZiAoZml0KSBoMm8ucm0obHJAbW9kZWxfaWQpDQogIA0KICBwbG90KHg9ZGYuUlsseF0seT1kZi5SWyx5XSwgY29sPSJibHVlIiwgeGxhYj14LCB5bGFiPXkpDQogIGlmIChmaXQpIGFibGluZShjb2VmPWNvZWZmLGNvbD0iYmxhY2siKQ0KfQ0KDQpzY2F0dGVyX3Bsb3QoZGF0YT1haXJsaW5lcy5oMm8seD0iRGlzdGFuY2UiLCB5PSJBaXJUaW1lIiwgZml0PVQpDQojIGxyPC1oMm8uZ2xtKHg9IkRpc3RhbmNlIix5PSJBaXJUaW1lIix0cmFpbmluZ19mcmFtZSA9IGFpcmxpbmVzLmgybyxmYW1pbHk9ImdhdXNzaWFuIikNCg0KDQpzY2F0dGVyX3Bsb3QoZGF0YSA9IGFpcmxpbmVzLmgybywgeCA9ICJVbmlxdWVDYXJyaWVyIiwgeSA9ICJBcnJEZWxheSIsIG1heF9wb2ludHMgPSA1MDAwLCBmaXQgPSBGKQ0KIyBscjwtaDJvLmdsbSh4PSJVbmlxdWVDYXJyaWVyIix5PSJBcnJEZWxheSIsdHJhaW5pbmdfZnJhbWUgPSBhaXJsaW5lcy5oMm8sZmFtaWx5PSJnYXVzc2lhbiIpDQojIGxyPC1oMm8uZ2xtKHg9IkRpc3RhbmNlIix5PSJBaXJUaW1lIix0cmFpbmluZ19mcmFtZSA9YWlybGluZXMuaDJvLGZhbWlseT0iZ2F1c3NpYW4iKQ0KDQpgYGANCg0KIyMgRmxpZ2h0IGJ5IE1vbnRoIGNhbGN1bGF0ZWQgdXNpbmcgSDJPJ3MgZmFzdCBncm91cGJ5DQpgYGB7cn0NCnByaW50KCJTcGxpdHRpbmcgZGF0YSBpbnRvIGdyb3VwIG9mIDEyIG1vbnRoIGFuZCBhZ2dyZWdhdGluZyBvbiB0d28gY29sdW1ucy4uLiIpDQpmbGlnaHRCeW1vbnRoPC1oMm8uZ3JvdXBfYnkoZGF0YT1haXJsaW5lcy5oMm8sYnk9Ik1vbnRoIiwgbnJvdygiTW9udGgiKSwgc3VtKCJDYW5jZWxsZWQiKSkNCmZsaWdodEJ5bW9udGguUjwtYXMuZGF0YS5mcmFtZShmbGlnaHRCeW1vbnRoKQ0KYGBgDQoNCiNTZXQgQ29sdW1uIFR5cGUgZm9yIEVudW1lcmF0b3Igb3IgRmFjdG9yIENvbHVtbnMNCmBgYHtyfQ0KYWlybGluZXMuaDJvJFllYXI8LWFzLmZhY3RvcihhaXJsaW5lcy5oMm8kWWVhcikNCmFpcmxpbmVzLmgybyRNb250aDwtYXMuZmFjdG9yKGFpcmxpbmVzLmgybyRNb250aCkNCmFpcmxpbmVzLmgybyREYXlPZldlZWs8LWFzLmZhY3RvcihhaXJsaW5lcy5oMm8kRGF5T2ZXZWVrKQ0KYWlybGluZXMuaDJvJENhbmNlbGxlZDwtYXMuZmFjdG9yKGFpcmxpbmVzLmgybyRDYW5jZWxsZWQpDQphaXJsaW5lcy5oMm8kRmxpZ2h0TnVtPC1hcy5mYWN0b3IoYWlybGluZXMuaDJvJEZsaWdodE51bSkNCmFpcmxpbmVzLmgybyRPcmlnaW48LWFzLmZhY3RvcihhaXJsaW5lcy5oMm8kT3JpZ2luKQ0KYWlybGluZXMuaDJvJERlc3Q8LWFzLmZhY3RvcihhaXJsaW5lcy5oMm8kRGVzdCkNCmFpcmxpbmVzLmgybyRJc0RlcERlbGF5ZWQ8LWFzLmZhY3RvcihhaXJsaW5lcy5oMm8kSXNEZXBEZWxheWVkKQ0KYGBgDQojUGFyYW1ldGVyIENyZWF0aW9uDQpgYGB7cn0NCmhvdXIxPC1haXJsaW5lcy5oMm8kQ1JTQXJyVGltZSAlLyUgMTAwDQptaW5zMTwtYWlybGluZXMuaDJvJENSU0FyclRpbWUgJSUgMTAwDQphcnJUaW1lPC1ob3VyMSo2MCttaW5zMQ0KDQpob3VyMiA8LSBhaXJsaW5lcy5oMm8kQ1JTRGVwVGltZSAlLyUgMTAwDQptaW5zMiA8LSBhaXJsaW5lcy5oMm8kQ1JTRGVwVGltZSAlJSAxMDANCmRlcFRpbWUgPC0gaG91cjIqNjArbWluczINCg0KdHJhdmVsVGltZSA8LSBpZmVsc2UoYXJyVGltZSAtIGRlcFRpbWUgPiAwLCBhcnJUaW1lIC0gZGVwVGltZSwgTkEpDQphaXJsaW5lcy5oMm8kVHJhdmVsVGltZSA8LSB0cmF2ZWxUaW1lDQpzY2F0dGVyX3Bsb3QoYWlybGluZXMuaDJvLCAiRGlzdGFuY2UiLCAiVHJhdmVsVGltZSIpDQoNCmBgYA0KDQojaW1wdXRhdGlvbjogWW91IGNhbiBhbHNvIGNob29zZSB0byBpbXB1dGUgbWlzc2luZyB2YWx1ZSBieSB0YWtpbmcgdGhlIG1lYW4gb2Ygc3Vic2V0cw0KYGBge3J9DQpoMm8uaW1wdXRlKGRhdGE9YWlybGluZXMuaDJvLCBjb2x1bW49IkRpc3RhbmNlIiwgYnk9YygiT3JpZ2luIiwgIkRlc3QiKSkNCnNjYXR0ZXJfcGxvdChhaXJsaW5lcy5oMm8sICJEaXN0YW5jZSIsICJUcmF2ZWxUaW1lIikNCmBgYA0KDQojY3JlYXRlIHRlc3QvdHJhaW4gc3BsaXQNCmBgYHtyfQ0KZGF0YS5zcGxpdDwtaDJvLnNwbGl0RnJhbWUoZGF0YT1haXJsaW5lcy5oMm8scmF0aW89MC44KQ0KZGF0YS50cmFpbjwtZGF0YS5zcGxpdFtbMV1dDQpkYXRhLnRlc3Q8LWRhdGEuc3BsaXRbWzJdXQ0KYGBgDQoNCiNzZXQgdGhlIHByZWRpY3RvciBuYW1lcyBhbmQgdGhlIHJlc3BvbnNlIGNvbHVtbiBuYW1lDQpgYGB7cn0NCnByZWRpY3RvcnM9YygiT3JpZ2luIiwiRGVzdCIsIlllYXIiLCAiVW5pcXVlQ2FycmllciIsIkRheU9mV2VlayIsIk1vbnRoIiwiRGlzdGFuY2UiLCJGbGlnaHROdW0iKQ0KcmVzcG9uc2U9IklzRGVwRGVsYXllZCINCg0KYGBgDQoNCiNCdWlsZCBHTE0NCmBgYHtyfQ0Kc3RhcnQ8LVN5cy50aW1lKCkNCmRhdGEuZ2xtPC1oMm8uZ2xtKHk9cmVzcG9uc2UseD1wcmVkaWN0b3JzLHRyYWluaW5nX2ZyYW1lID0gZGF0YS50cmFpbiwgdmFsaWRhdGlvbl9mcmFtZSA9IGRhdGEudGVzdCwgZmFtaWx5PSJiaW5vbWlhbCIsIHN0YW5kYXJkaXplID0gVCwgbW9kZWxfaWQgPSAiZ2xtX21vZGVsIiwgYWxwaGE9MC41LCBsYW1iZGE9MWUtMDUpDQpnbG1fdGltZTwtU3lzLnRpbWUoKS1zdGFydA0KcHJpbnQocGFzdGUoIlRvb2siLCByb3VuZChnbG1fdGltZSwgZGlnaXRzPTIpLCB1bml0cyhnbG1fdGltZSksICJ0byBidWlsZCBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsLiIpKQ0KYGBgDQoNCiNCdWlsZCBHQk0gbW9kZWwNCmBgYHtyfQ0KDQpzdGFydDwtU3lzLnRpbWUoKQ0KI2ZvciBiYWxhbmNlIGNsYXNzZXMgaHR0cHM6Ly9oMm8tcmVsZWFzZS5zMy5hbWF6b25hd3MuY29tL2gyby9yZWwtdWVuby8yL2RvY3Mtd2Vic2l0ZS9oMm8tZG9jcy9kYXRhLXNjaWVuY2UvYWxnby1wYXJhbXMvYmFsYW5jZV9jbGFzc2VzLmh0bWwNCg0KZGF0YS5nYm08LWgyby5nYm0oeT1yZXNwb25zZSwgeD1wcmVkaWN0b3JzLCBiYWxhbmNlX2NsYXNzZXM9VCx0cmFpbmluZ19mcmFtZSA9IGRhdGEudHJhaW4sIHZhbGlkYXRpb25fZnJhbWUgPSBkYXRhLnRlc3QsIG50cmVlcz0xMDAsIG1heF9kZXB0aD01LCBtb2RlbF9pZD0iZ2JtX21vZGVsIiwgZGlzdHJpYnV0aW9uPSJiZXJub3VsbGkiLCBsZWFybl9yYXRlID0gLjEsIG1pbl9yb3dzPTIpDQpnYm1fdGltZTwtU3lzLnRpbWUoKS1zdGFydA0KcHJpbnQocGFzdGUoIlRvb2siLCByb3VuZChnYm1fdGltZSwgZGlnaXRzID0gMiksIHVuaXRzKGdibV90aW1lKSwgInRvIGJ1aWxkIGEgR0JNIG1vZGVsLiIpKSANCg0KYGBgDQojQnVpbGQgcmFuZG9tIGZvcmVzdCBtZG9lbA0KYGBge3J9DQojcHJlZGljdG9ycz1jKCJZZWFyIiwgIlVuaXF1ZUNhcnJpZXIiLCJEYXlPZldlZWsiLCJNb250aCIsIkRpc3RhbmNlIikNCnN0YXJ0PC1TeXMudGltZSgpDQpkYXRhLmRyZjwtaDJvLnJhbmRvbUZvcmVzdCh5PXJlc3BvbnNlLCB4PXByZWRpY3RvcnMsIHRyYWluaW5nX2ZyYW1lID0gZGF0YS50cmFpbiwgdmFsaWRhdGlvbl9mcmFtZSA9IGRhdGEudGVzdCwgbnRyZWVzPTE1MDAsIG1heF9kZXB0aD01LCBtb2RlbF9pZD0iZHJmX21vZGVsIiwgYmFsYW5jZV9jbGFzc2VzID0gVCkNCmRyZl90aW1lIDwtIFN5cy50aW1lKCkgLSBzdGFydA0KcHJpbnQocGFzdGUoIlRvb2siLCByb3VuZChkcmZfdGltZSwgZGlnaXRzID0gMiksIHVuaXRzKGRyZl90aW1lKSwgInRvIGJ1aWxkIGEgUmFuZG9tIEZvcmVzdCBtb2RlbC4iKSkNCmBgYA0KDQojY29tcGFyaW5nIHJ1bm5pbmcgdGllbSB3aXRoIHJhbmRvZm9yZXN0IHBhY2thZ2UNCiNjYW5ub3QgaGFuZGxlIHByZWRpY3RvcnMgbW9yZSB0aGFuIDUzIGNhdGVnb3JpZXMNCmBgYHtyfQ0KbGlicmFyeShyYW5kb21Gb3Jlc3QpDQpsaWJyYXJ5KGNhcmV0KQ0KDQp0cmFpbkluZGV4PWNyZWF0ZURhdGFQYXJ0aXRpb24oYWlybGluZXMkSXNEZXBEZWxheWVkLHA9MC43LCBsaXN0PUZBTFNFLCB0aW1lcz0xKQ0KI2h0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9jYXJldC92ZXJzaW9ucy82LjAtNzYvdG9waWNzL2NyZWF0ZURhdGFQYXJ0aXRpb24NCmFpcmxpbmVzJFllYXI8LWFzLmZhY3RvcihhaXJsaW5lcyRZZWFyKQ0KYWlybGluZXMkTW9udGg8LWFzLmZhY3RvcihhaXJsaW5lcyRNb250aCkNCmFpcmxpbmVzJERheU9mV2VlazwtYXMuZmFjdG9yKGFpcmxpbmVzJERheU9mV2VlaykNCmFpcmxpbmVzJENhbmNlbGxlZDwtYXMuZmFjdG9yKGFpcmxpbmVzJENhbmNlbGxlZCkNCmFpcmxpbmVzJEZsaWdodE51bTwtYXMuZmFjdG9yKGFpcmxpbmVzJEZsaWdodE51bSkNCmFpcmxpbmVzJE9yaWdpbjwtYXMuZmFjdG9yKGFpcmxpbmVzJE9yaWdpbikNCmFpcmxpbmVzJERlc3Q8LWFzLmZhY3RvcihhaXJsaW5lcyREZXN0KQ0KYWlybGluZXMkSXNEZXBEZWxheWVkPC1hcy5mYWN0b3IoYWlybGluZXMkSXNEZXBEZWxheWVkKQ0KDQp0cmFpbmluZzwtYWlybGluZXNbdHJhaW5JbmRleCxdDQp0ZXN0aW5nPC1haXJsaW5lc1stdHJhaW5JbmRleCxdDQp0cmFpbmluZzwtYXMuZGF0YS5mcmFtZSh0cmFpbmluZykNCnRlc3Rpbmc8LWFzLmRhdGEuZnJhbWUodGVzdGluZykNCnN0YXJ0PC1TeXMudGltZSgpDQpmaXQgPC0gcmFuZG9tRm9yZXN0KElzRGVwRGVsYXllZCB+IFllYXIrVW5pcXVlQ2FycmllcitEYXlPZldlZWsrTW9udGgrRGlzdGFuY2UsDQogICAgICAgICAgICAgICAgICAgICAgZGF0YT10cmFpbmluZywgDQogICAgICAgICAgICAgICAgICAgICAgaW1wb3J0YW5jZT1UUlVFLCANCiAgICAgICAgICAgICAgICAgICAgICBudHJlZT0xNTAwLCBuYS5hY3Rpb249bmEub21pdCkNCmRyZl90aW1lIDwtIFN5cy50aW1lKCkgLSBzdGFydA0KcHJpbnQocGFzdGUoIlRvb2siLCByb3VuZChkcmZfdGltZSwgZGlnaXRzID0gMiksIHVuaXRzKGRyZl90aW1lKSwgInRvIGJ1aWxkIGEgUmFuZG9tIEZvcmVzdCBtb2RlbCB1bmRlciByYW5kb21Gb3Jlc3QgcGFja2FnZS4iKSkNCmBgYA0KDQojYnVpbGQgZGVlcCBsZWFybmluZyBtb2RlbA0KYGBge3J9DQpzdGFydCAgIDwtIFN5cy50aW1lKCkNCmRhdGEuZGw8LWgyby5kZWVwbGVhcm5pbmcoeT1yZXNwb25zZSwgeD1wcmVkaWN0b3JzLCB0cmFpbmluZ19mcmFtZSA9IGRhdGEudHJhaW4sIHZhbGlkYXRpb25fZnJhbWUgPSBkYXRhLnRlc3QsIGhpZGRlbj1jKDEwLDEwKSwgZXBvY2hzID0gNSwgYmFsYW5jZV9jbGFzc2VzPVQsIGxvc3M9IkF1dG9tYXRpYyIsIHZhcmlhYmxlX2ltcG9ydGFuY2VzPVQpDQpkbF90aW1lIDwtIFN5cy50aW1lKCkgLSBzdGFydA0KcHJpbnQocGFzdGUoIlRvb2siLCByb3VuZChkbF90aW1lLCBkaWdpdHMgPSAyKSwgdW5pdHMoZGxfdGltZSksICJ0byBidWlsZCBhIERlZXAgTGVhcm5pbmcgbW9kZWwuIikpDQpgYGANCg0KIyMgVmFyaWFibGUgSW1wb3J0YW5jZSAtIEZvciBmZWF0dXJlIHNlbGVjdGlvbiBhbmQgcmVydW5uaW5nIGEgbW9kZWwgYnVpbGQNCmBgYHtyfQ0KcHJpbnQoIkdMTTogU29ydGVkIFN0YW5kYXJkaXplZCBDb2VmZmljaWVudCBNYWduaXR1ZGVzIFRvIEZpbmQgTm9uemVybyBDb2VmZmljaWVudHMiKQ0KZGF0YS5nbG1AbW9kZWwkc3RhbmRhcmRpemVkX2NvZWZmaWNpZW50X21hZ25pdHVkZXMNCnByaW50KCJHQk06IFZhcmlhYmxlIEltcG9ydGFuY2UiKQ0KZGF0YS5nYm1AbW9kZWwkdmFyaWFibGVfaW1wb3J0YW5jZXMNCnByaW50KCJSYW5kb20gRm9yZXN0OiBWYXJpYWJsZSBJbXBvcnRhbmNlIikNCmRhdGEuZHJmQG1vZGVsJHZhcmlhYmxlX2ltcG9ydGFuY2VzDQpwcmludCgiRGVlcCBMZWFybmluZzogVmFyaWFibGUgSW1wb3J0YW5jZSIpDQpkYXRhLmRsQG1vZGVsJHZhcmlhYmxlX2ltcG9ydGFuY2VzDQpgYGANCg0K