Required packages

library(readr)
library(magrittr)
library(tidyr)
library(Hmisc)
library(dplyr)
library(outliers)

Executive Summary

Data

aeroplane<-read_csv("flight-delays/flights.csv")
airports<-read_csv("flight-delays/airports.csv")
airlines<-read_csv("flight-delays/airlines.csv")
#Changing of one of the column names
colnames(airlines)[colnames(airlines)=="AIRLINE"] <- "Plane_Name"
#Changing of one of the column names
colnames(airlines)[colnames(airlines)=="IATA_CODE"] <- "AIRLINE"
air<-aeroplane %>% left_join(airlines, by = "AIRLINE")
#Changing of one of the column names
colnames(airports)[colnames(airports)=="IATA_CODE"] <- "ORIGIN_AIRPORT"
Air_details<-air %>% left_join(airports, by = "ORIGIN_AIRPORT")
head(Air_details, n=10)

Understand

head(Air_details)
dim(Air_details)
[1] 5819079      38
#Any incomplete rows
Air_details[!complete.cases(Air_details),]
Air_details$STATE<-as.factor(Air_details$STATE)
levels(Air_details$STATE)
 [1] "AK" "AL" "AR" "AS" "AZ" "CA" "CO" "CT" "DE" "FL" "GA" "GU" "HI" "IA" "ID" "IL" "IN" "KS" "KY" "LA" "MA" "MD" "ME" "MI"
[25] "MN" "MO" "MS" "MT" "NC" "ND" "NE" "NH" "NJ" "NM" "NV" "NY" "OH" "OK" "OR" "PA" "PR" "RI" "SC" "SD" "TN" "TX" "UT" "VA"
[49] "VI" "VT" "WA" "WI" "WV" "WY"
Air_details$ORIGIN_AIRPORT<-as.factor(Air_details$ORIGIN_AIRPORT)
is.factor(Air_details$ORIGIN_AIRPORT)
[1] TRUE
Air_details$DESTINATION_AIRPORT<-as.factor(Air_details$DESTINATION_AIRPORT)
is.factor(Air_details$DESTINATION_AIRPORT)
[1] TRUE
# Define numbers by actual days and months.
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 1] <- 'Monday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 2] <- 'Tuesday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 3] <- 'Wednesday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 4] <- 'Thursday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 5] <- 'Friday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 6] <- 'Saturday'
Air_details$DAY_OF_WEEK[Air_details$DAY_OF_WEEK == 7] <- 'Sunday'
Air_details$MONTH[Air_details$MONTH == 1] <- 'January'
Air_details$MONTH[Air_details$MONTH == 2] <- 'February'
Air_details$MONTH[Air_details$MONTH == 3] <- 'March'
Air_details$MONTH[Air_details$MONTH == 4] <- 'April'
Air_details$MONTH[Air_details$MONTH == 5] <- 'May'
Air_details$MONTH[Air_details$MONTH== 6] <- 'June'
Air_details$MONTH[Air_details$MONTH == 7] <-'July'
Air_details$MONTH[Air_details$MONTH == 8] <- 'August'
Air_details$MONTH[Air_details$MONTH == 9] <- 'September'
Air_details$MONTH[Air_details$MONTH == 10] <- 'October'
Air_details$MONTH[Air_details$MONTH == 11] <- 'November'
Air_details$MONTH[Air_details$MONTH == 12] <- 'December'
Air_details$DAY_OF_WEEK<-as.factor(Air_details$DAY_OF_WEEK)
levels(Air_details$DAY_OF_WEEK)
[1] "Friday"    "Monday"    "Saturday"  "Sunday"    "Thursday"  "Tuesday"   "Wednesday"
Air_details$MONTH<-as.factor(Air_details$MONTH)
levels(Air_details$MONTH)
 [1] "April"     "August"    "December"  "February"  "January"   "July"      "June"      "March"     "May"       "November" 
[11] "October"   "September"

Tidy & Manipulate Data I

The dataset choosen is already tidy. Here the unwanred variables are removed to increase the ease of anaysis.

#unwanted are removed
Air_details_tidy<- Air_details %>% 
  select(-DIVERTED,-`CANCELLED`,-`CANCELLATION_REASON`,-`AIR_SYSTEM_DELAY`,-SECURITY_DELAY,-AIRLINE_DELAY,-LATE_AIRCRAFT_DELAY,-WEATHER_DELAY)

Tidy & Manipulate Data II

In order to check the speed of aeroplane in km/hr.A mutate function is used to make a new variable that is the Speed_aeroplane by using Distance which is the distance between two airports and by using AIR_TIME.

Air_details_tidy<-mutate(Air_details_tidy,
        Speed_aeroplane = DISTANCE / (AIR_TIME/60))

Scan I

The total number of missing observations are found by using colSums function and the percentage of missing values of total observation is gotten. By using which and is.na function the location of the missing values is found out.The missing values based whether they are mean or catergorical variable are replaced by mean or mode of the respective variable.

colSums(is.na(Air_details_tidy))
               YEAR               MONTH                 DAY         DAY_OF_WEEK             AIRLINE       FLIGHT_NUMBER 
                  0                   0                   0                   0                   0                   0 
        TAIL_NUMBER      ORIGIN_AIRPORT DESTINATION_AIRPORT SCHEDULED_DEPARTURE      DEPARTURE_TIME     DEPARTURE_DELAY 
              14721                   0                   0                   0               86153               86153 
           TAXI_OUT          WHEELS_OFF      SCHEDULED_TIME        ELAPSED_TIME            AIR_TIME            DISTANCE 
              89047               89047                   6              105071              105071                   0 
          WHEELS_ON             TAXI_IN   SCHEDULED_ARRIVAL        ARRIVAL_TIME       ARRIVAL_DELAY          Plane_Name 
              92513               92513                   0               92513              105071                   0 
            AIRPORT                CITY               STATE             COUNTRY            LATITUDE           LONGITUDE 
             486165              486165              486165              486165              490770              490770 
    Speed_aeroplane 
             105071 
NA_DEPARTURE_DELAY<-which(is.na(Air_details_tidy$DEPARTURE_DELAY))
NA_ARRIVAL_DELAY<-which(is.na(Air_details_tidy$ARRIVAL_DELAY))
NA_TAILNUMBER<-which(is.na(Air_details_tidy$TAIL_NUMBER))
NA_AIR_TIME<-which(is.na(Air_details_tidy$AIR_TIME))
NA_Speed_aeroplane<-which(is.na(Air_details_tidy$Speed_aeroplane))
#Replace NA 
Air_details_tidy$DEPARTURE_DELAY[NA_DEPARTURE_DELAY]<-mean(Air_details_tidy$DEPARTURE_DELAY,na.rm = T)
Air_details_tidy$ARRIVAL_DELAY[NA_ARRIVAL_DELAY]<-mean(Air_details_tidy$ARRIVAL_DELAY,na.rm = T)
Air_details_tidy$AIR_TIME[NA_AIR_TIME]<-mean(Air_details_tidy$AIR_TIME,na.rm = T)
Air_details_tidy$Speed_aeroplane[NA_Speed_aeroplane]<-mean(Air_details_tidy$Speed_aeroplane,na.rm = T)
colSums(is.na(Air_details_tidy))
               YEAR               MONTH                 DAY         DAY_OF_WEEK             AIRLINE       FLIGHT_NUMBER 
                  0                   0                   0                   0                   0                   0 
        TAIL_NUMBER      ORIGIN_AIRPORT DESTINATION_AIRPORT SCHEDULED_DEPARTURE      DEPARTURE_TIME     DEPARTURE_DELAY 
              14721                   0                   0                   0               86153                   0 
           TAXI_OUT          WHEELS_OFF      SCHEDULED_TIME        ELAPSED_TIME            AIR_TIME            DISTANCE 
              89047               89047                   6              105071                   0                   0 
          WHEELS_ON             TAXI_IN   SCHEDULED_ARRIVAL        ARRIVAL_TIME       ARRIVAL_DELAY          Plane_Name 
              92513               92513                   0               92513                   0                   0 
            AIRPORT                CITY               STATE             COUNTRY            LATITUDE           LONGITUDE 
             486165              486165              486165              486165              490770              490770 
    Speed_aeroplane 
                  0 

Scan II


#z-score method
# Calculate z-score
z.scores.AIR_TIME <- Air_details_tidy$AIR_TIME %>%  scores(type = "z")
z.scores.DISTANCE <- Air_details_tidy$DISTANCE %>%  scores(type = "z")
clean_AIR_TIME <- Air_details_tidy[- which(abs(z.scores.AIR_TIME) >3 ),]
clean_DISTANCE<- Air_details_tidy[- which(abs(z.scores.DISTANCE) >3 ),]
par(mfrow=c(1,4))
boxplot(Air_details_tidy$AIR_TIME, main = "Box Plot of AIR_TIME",verticle=TRUE, col = "pink")
boxplot(Air_details_tidy$DISTANCE, main = "Box Plot of DISTANCE",verticle=TRUE, col = "pink")
clean_AIR_TIME$AIR_TIME %>%  boxplot(main="Zscore Box Plot of AIR_TIME",
                                       ylab="AIR_TIME($)", col = "pink")
clean_DISTANCE$DISTANCE %>%  boxplot(main="zscore Box Plot of DISTANCE",
                                       ylab="DISTANCE($)", col = "pink")
#Median method air time
Replace_by_median <- function(z) {
 quantiles <- quantile( z, c( 0.25, 0.50, .75 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[2]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[2]
 z}
Replacing_by_1st_quad<- function(z) {
 quantiles <- quantile( z, c( 0.25, 0.50, .75 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[1]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[1]
 z}
Replacing_by_3rd_quad<- function(z) {
 quantiles <- quantile( z, c( 0.05,0.25, 0.75, .95 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[3]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[3]
 z}
par(mfrow=c(1,4))

boxplot(Air_details_tidy$AIR_TIME,main="Before Outlier Removal  ", col= "pink")
After_Cap<-Air_details_tidy$AIR_TIME %>% Replace_by_median()
boxplot(After_Cap,main="AIR_TIME by Median", col= "pink")
After_Cap_1<-Air_details_tidy$AIR_TIME %>% Replacing_by_1st_quad()
boxplot(After_Cap_1,main="AIR_TIME by 1st Qu",col= "red")
After_Cap_2<-Air_details_tidy$AIR_TIME %>% Replacing_by_3rd_quad()
boxplot(After_Cap_2,main="AIR_TIME by 3rd Qu",col= "yellow")
#Median method dustance
Replacing_by_median <- function(z) {
 quantiles <- quantile( z, c( 0.25, 0.50, .75 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[2]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[2]
 z}
Replacing_by_1st<- function(z) {
 quantiles <- quantile( z, c( 0.25, 0.50, .75 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[1]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[1]
 z}

Replacing_by_3rd<- function(z) {
 quantiles <- quantile( z, c( 0.05,0.25, 0.75, .95 ) )
 z[ z < quantiles[1] - 1.5*IQR(z) ] <- quantiles[3]
 z[ z > quantiles[3] + 1.5*IQR(z) ] <- quantiles[3]
 z}
par(mfrow=c(1,4))

boxplot(Air_details_tidy$DISTANCE,main="Before Outlier Removal ", col= "red")
After_Cap<-Air_details_tidy$DISTANCE %>% Replacing_by_median()
boxplot(After_Cap,main="DISTANCE by Median", col= "red")
After_Cap_1<-Air_details_tidy$DISTANCE %>% Replacing_by_1st()
boxplot(After_Cap_1,main="DISTANCE by 1st Qudr",col= "blue")
After_Cap_2<-Air_details_tidy$DISTANCE %>% Replacing_by_3rd()
boxplot(After_Cap_2,main="DISTANCE by 3rd Qu",col= "pink")

Transform

The transformation has been conducted on AIR_TIME and DISTANCE variables. The aim is to decrease the skewness and convert it to normalised data.The log transformation has been used, it spreads out the congested data.Log transformation is used for right skewed.A normal distribution of the data is achieved by this method.

par(mfrow=c(1,4))
hist(Air_details_tidy$AIR_TIME,main="AIR_TIME Before Transformation",col = "green")
Tair<-log10(Air_details_tidy$AIR_TIME)
hist(Tair,main="AIR_TIME After Transformation",col = "green")
hist(Air_details_tidy$DISTANCE,main="DISTANCE Before Transformation",col = "pink")
T_distance<-log10(Air_details_tidy$DISTANCE)
hist(T_distance,main="DISTANCE After Transformation",col = "pink")



LS0tCnRpdGxlOiAiTUFUSDIzNDkgU2VtZXN0ZXIgMiwgMjAxOSIKYXV0aG9yOiAiREhBQ0hBSU5FRSBNVVJVR0FZQUggKFMzNzk0MzM0KSAmIFJBQ0hFQUwgUk9OQUxEIENPRUxITyAoUzM4MDQ0NDgpIgpzdWJ0aXRsZTogQXNzaWdubWVudCAzCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQojIyBSZXF1aXJlZCBwYWNrYWdlcyAKYGBge3J9CmxpYnJhcnkocmVhZHIpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoSG1pc2MpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkob3V0bGllcnMpCmBgYAoKIyMgRXhlY3V0aXZlIFN1bW1hcnkgCiogVGhlIGFzc2lnbm1lbnQgbWFrZXMgdXNlIG9mIHRoZSBrbm93bGVkZ2UgZ2FpbmVkIGluIHRoZSBkYXRhIHByZS1wcm9jZXNzaW5nIGNvdXJzZSB0byBwcm9jZXNzIHRoZSBvcGVuIGRhdGEgc2V0LlRoZSBkYXRhIHV0aWxpc2VkIGluIHRoaXMgYXNzaWdubWVudCBpcyBhYm91dCB0aGUgZmxpZ2h0IGRlbGF5IGFuZCBjYW5jZWxhdGlvbiBpbmZvcm1hdGlvbiBpbiB0aGUgVW5pdGVkIFN0YXRlcy4gVGhlIHRocmVlIGRhdGFzZXRzIHVzZWQgYXJlIGFlcm9wbGFuZS5jc3YsYWlycG9ydC5jc3YgYW5kIGFpcmxpbmVzLmNzdi4gVGhpcyBkYXRhc2V0cyBhcmUgam9pbmVkIHVzaW5nIGxlZnQgam9pbiBieSBhIHZhcmlhYmxlIHRoYXQgaXMgY29tbW9uLiBJbiBvcmRlciB0byBpbmNyZWFzZSB0aGUgZWFzZSBvZiBoYW5kZWxsaW5nIHRoZSBkYXRhLCBmZXcgbm9uIHJlcXVpcmVkIHZhcmlhYmxlcyBhcmUgZXhjbHVkZWQuCiogVGhlIHZhcmlhYmxlcyBhcmUgb2YgZGlmZmVyZW50IGNsYXNzZXMgLHNvbWUgdmFyaWFibGVzIGFyZSBtYWRlIGludG8gYSBmYWN0b3IuIEFuZCB0aGUgbW9udGggYW5kIHRoZSB3ZWVrIHdlcmUgY2hhbmdlZCBmcm9tIG51bWVyaWMgdmFsdWUgdG8gdGhlIG5hbWVzIG9mIHRoZSBtb250aCBhbmQgd2VlayByZXNwZWN0aXZlbHkuCiogVGhlIGRhdGFzZXQgd2FzIGFscmVhZHkgdGlkeS4gVGhlIHZhcmlhYmxlcyB3aGljaCBhcmUgb2Ygbm8gdXNlZCB3ZXJlIHJlbW92ZWQuIEEgbmV3IGNvbHVtbiB3YXMgZ2VuZXJhdGVkIGZyb20gdGhlIGV4aXN0aW5nIG9uZXMgYnkgdXRpbGlzaW5nIHRoZSBtdXRhdGUgZnVuY3Rpb24uCiogVGhlIG1pc3NpbmcgdmFsdWVzIHRoYXQgYmVsb25nZWQgdG8gbnVtZXJpY2FsIGNsYXNzIHdlcmUgcmVwbGFjZWQgYnkgdGhlIG1lYW4gYW5kIHRoZSBtaXNzaW5nIHZhbHVlcyB0aGF0IGJlbG9uZyB0byBjYXRlZ29yaWNhbCB3ZXJlIHJlcGxhY2VkIGJ5IHRoZSBtb2RlLgoqIEJ5IHV0aWxpc2luZyB0aGUgYm94cGxvdCB0aGUgb3V0bGllcnMgd2VyZSBkZXRlY3RlZCBhbmQgY2FwcGluZyB0ZWNobmlxdWVzIHdlcmUgdXRpbGlzZWQgdG8gcmVtb3ZlIHRoZSBvdXRsaWVycyB0byB0aGUgbWF4aW11bSBleHRlbmQuIEZpbmFsbHksIHRyYW5zZm9ybWF0aW9uIHdhcyBjb25kdWN0ZWQgb24gZmV3IHZhcmlhYmxlcyB0byBkZWNyZWFzZSB0aGUgc2tld25lc3Mgb2YgdGhlIGRhdGEgYW5kIHRvIG5vcm1hbGlzZSB0aGUgZGF0YS4gQSBub3JtYWxpc2VkIGRhdGEgaXMgYXBwcm9wcmlhdGUgdG8gY29uZHVjdCBzdGF0aXN0aWNhbCBhbmFseXNpcy4KCiMjIERhdGEgCgoqIFRoZSBkYXRhIGlzIHRha2VuIGZyb20gdGhlIFVuaXRlZCBTdGF0ZXMgZGVwYXJ0bWVudCBvZiB0cmFuc3BvcnRhdGlvbidzIEJ1cmVhdSBvZiBUcmFuc3BvcnRhdGlvbiBTdGF0aXN0aWNzLgoqIFRoZSBkYXRhc2V0IGlzIG9idGFpbmVkIGZyb20gdGhlIGZvbGxvd2luZyBsaW5rOmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vdXNkb3QvZmxpZ2h0LWRlbGF5cyNmbGlnaHRzLmNzdgoqIFRocmVlIGRhdGFzZXRzIGhhdmUgYmVlbiB1dGlsaXNlZCBpbiB0aGlzIGFzc2lnbm1lbnQuIFRoZSBwcmltYXJ5IGRhdGFzZXQgaXMgdGhlIGFlcm9wbGFuZS5jc3YuIFRoZSBvdGhlciBkYXRhc2V0cyBhcmUgYWlycG9ydC5jc3YgYW5kIGFpcmxpbmVzLmNzdi4KKiBCeSB1dGlsaXNpbmcgdGhlIHJlYWRyIHBhY2thZ2UsIHRoZSBkYXRhc2V0cyBhcmUgaW1wb3J0ZWQgYW5kIHJlYWQuIFRoZSBkYXRhcyBhcmUgaW4gY3N2IGZvcm1hdCBzbyByZWFkX2NzdiBmdW5jdGlvbiBpcyBtYWRlIHVzZSBvZi5UaGVzZSBkYXRhc2V0cyBhcmUgYW5hbHlzZWQgYW5kIHRoZW4gY29tYmluZWQgYnkgYSBjb21tb24gdmFyaWFibGUuVGhlIDMgZGF0YXNldHMgYXJlIGpvaW5lZCBieSB1c2luZyBsZWZ0IGpvaW4uCiogVGhlIGNvbW1vbiB2YXJpYWJsZSBpbiBhZXJvcGxhbmUgYW5kIGFpcmxpbmVzIGlzIHRoZSB2YXJpYWJsZSBBSVJMSU5FIHdoaWNoIGhhcyB0aGUgYWlybGluZSBuYW1lLkFuZCB0aGUgYWlycG9ydHMgZGF0YXNldCBpcyBjb21iaW5lZCBieSB0aGUgT1JJR0lOX0FJUlBPUlQgdmFyaWFibGUgd2hpY2ggaGFzIHRoZSB1bmlxdWUgYWlycG9ydCBpZC5UaGUgdmFyaWFibGVzIGluIHRoZSBhaXJsaW5lcyBkYXRhc2V0IGhhcyBiZWVuIGNoYW5nZWQgYWNjb3JkaW5nbHkuCmBgYHtyfQphZXJvcGxhbmU8LXJlYWRfY3N2KCJmbGlnaHQtZGVsYXlzL2ZsaWdodHMuY3N2IikKYWlycG9ydHM8LXJlYWRfY3N2KCJmbGlnaHQtZGVsYXlzL2FpcnBvcnRzLmNzdiIpCmFpcmxpbmVzPC1yZWFkX2NzdigiZmxpZ2h0LWRlbGF5cy9haXJsaW5lcy5jc3YiKQojQ2hhbmdpbmcgb2Ygb25lIG9mIHRoZSBjb2x1bW4gbmFtZXMKY29sbmFtZXMoYWlybGluZXMpW2NvbG5hbWVzKGFpcmxpbmVzKT09IkFJUkxJTkUiXSA8LSAiUGxhbmVfTmFtZSIKI0NoYW5naW5nIG9mIG9uZSBvZiB0aGUgY29sdW1uIG5hbWVzCmNvbG5hbWVzKGFpcmxpbmVzKVtjb2xuYW1lcyhhaXJsaW5lcyk9PSJJQVRBX0NPREUiXSA8LSAiQUlSTElORSIKYWlyPC1hZXJvcGxhbmUgJT4lIGxlZnRfam9pbihhaXJsaW5lcywgYnkgPSAiQUlSTElORSIpCiNDaGFuZ2luZyBvZiBvbmUgb2YgdGhlIGNvbHVtbiBuYW1lcwpjb2xuYW1lcyhhaXJwb3J0cylbY29sbmFtZXMoYWlycG9ydHMpPT0iSUFUQV9DT0RFIl0gPC0gIk9SSUdJTl9BSVJQT1JUIgpBaXJfZGV0YWlsczwtYWlyICU+JSBsZWZ0X2pvaW4oYWlycG9ydHMsIGJ5ID0gIk9SSUdJTl9BSVJQT1JUIikKaGVhZChBaXJfZGV0YWlscywgbj0xMCkKCmBgYAojIyBVbmRlcnN0YW5kIAoqIEluc3BlY3Rpb24gb2YgdGhlIGRhdGFzZXQgQWlyX2RldGFpbHMgaXMgY29uZHVjdGVkLlRoZSBkaW1lbnNpb24gaXMgY2hlY2tlZCB0aGVyZSBhcmUgNTgxOTA3OSBvYnNlcnZhdGlvbnMgYW5kIDM4IHJvd3MuU3RydWN0dXJlIG9mIHRoZSBkYXRhc2V0IGlzIGNoZWNrZWQgYW5kIGZldyB2YXJpYWJsZXMgYXJlIGNvbnZldGVyZCB0byBmYWN0b3IuVGhlIGRhdGFzZXQgaXMgY2hlY2tlZCBmb3IgaW5jb21wbGV0ZSByb3dzIGFuZCBpdCBpcyBkZWFsdCB3aXRoIGxhdGVyIG9uLiBUaGUgbW9udGggYW5kIHdlZWsgdmFyaWFibGUgYXJlIHJlcGxhY2VkIHdpdGggdGhlaXIgcmVzcGVjdGl2ZSBtb250aCBhbmQgd2VlayBuYW1lIGFuZCB0aGVuIGNvbnZlcnRlZCB0byBmYWN0b3IuCmBgYHtyfQpoZWFkKEFpcl9kZXRhaWxzKQpkaW0oQWlyX2RldGFpbHMpCiNBbnkgaW5jb21wbGV0ZSByb3dzCkFpcl9kZXRhaWxzWyFjb21wbGV0ZS5jYXNlcyhBaXJfZGV0YWlscyksXQpBaXJfZGV0YWlscyRTVEFURTwtYXMuZmFjdG9yKEFpcl9kZXRhaWxzJFNUQVRFKQpsZXZlbHMoQWlyX2RldGFpbHMkU1RBVEUpCkFpcl9kZXRhaWxzJE9SSUdJTl9BSVJQT1JUPC1hcy5mYWN0b3IoQWlyX2RldGFpbHMkT1JJR0lOX0FJUlBPUlQpCmlzLmZhY3RvcihBaXJfZGV0YWlscyRPUklHSU5fQUlSUE9SVCkKQWlyX2RldGFpbHMkREVTVElOQVRJT05fQUlSUE9SVDwtYXMuZmFjdG9yKEFpcl9kZXRhaWxzJERFU1RJTkFUSU9OX0FJUlBPUlQpCmlzLmZhY3RvcihBaXJfZGV0YWlscyRERVNUSU5BVElPTl9BSVJQT1JUKQojIERlZmluZSBudW1iZXJzIGJ5IGFjdHVhbCBkYXlzIGFuZCBtb250aHMuCkFpcl9kZXRhaWxzJERBWV9PRl9XRUVLW0Fpcl9kZXRhaWxzJERBWV9PRl9XRUVLID09IDFdIDwtICdNb25kYXknCkFpcl9kZXRhaWxzJERBWV9PRl9XRUVLW0Fpcl9kZXRhaWxzJERBWV9PRl9XRUVLID09IDJdIDwtICdUdWVzZGF5JwpBaXJfZGV0YWlscyREQVlfT0ZfV0VFS1tBaXJfZGV0YWlscyREQVlfT0ZfV0VFSyA9PSAzXSA8LSAnV2VkbmVzZGF5JwpBaXJfZGV0YWlscyREQVlfT0ZfV0VFS1tBaXJfZGV0YWlscyREQVlfT0ZfV0VFSyA9PSA0XSA8LSAnVGh1cnNkYXknCkFpcl9kZXRhaWxzJERBWV9PRl9XRUVLW0Fpcl9kZXRhaWxzJERBWV9PRl9XRUVLID09IDVdIDwtICdGcmlkYXknCkFpcl9kZXRhaWxzJERBWV9PRl9XRUVLW0Fpcl9kZXRhaWxzJERBWV9PRl9XRUVLID09IDZdIDwtICdTYXR1cmRheScKQWlyX2RldGFpbHMkREFZX09GX1dFRUtbQWlyX2RldGFpbHMkREFZX09GX1dFRUsgPT0gN10gPC0gJ1N1bmRheScKQWlyX2RldGFpbHMkTU9OVEhbQWlyX2RldGFpbHMkTU9OVEggPT0gMV0gPC0gJ0phbnVhcnknCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDJdIDwtICdGZWJydWFyeScKQWlyX2RldGFpbHMkTU9OVEhbQWlyX2RldGFpbHMkTU9OVEggPT0gM10gPC0gJ01hcmNoJwpBaXJfZGV0YWlscyRNT05USFtBaXJfZGV0YWlscyRNT05USCA9PSA0XSA8LSAnQXByaWwnCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDVdIDwtICdNYXknCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIPT0gNl0gPC0gJ0p1bmUnCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDddIDwtJ0p1bHknCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDhdIDwtICdBdWd1c3QnCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDldIDwtICdTZXB0ZW1iZXInCkFpcl9kZXRhaWxzJE1PTlRIW0Fpcl9kZXRhaWxzJE1PTlRIID09IDEwXSA8LSAnT2N0b2JlcicKQWlyX2RldGFpbHMkTU9OVEhbQWlyX2RldGFpbHMkTU9OVEggPT0gMTFdIDwtICdOb3ZlbWJlcicKQWlyX2RldGFpbHMkTU9OVEhbQWlyX2RldGFpbHMkTU9OVEggPT0gMTJdIDwtICdEZWNlbWJlcicKQWlyX2RldGFpbHMkREFZX09GX1dFRUs8LWFzLmZhY3RvcihBaXJfZGV0YWlscyREQVlfT0ZfV0VFSykKbGV2ZWxzKEFpcl9kZXRhaWxzJERBWV9PRl9XRUVLKQpBaXJfZGV0YWlscyRNT05USDwtYXMuZmFjdG9yKEFpcl9kZXRhaWxzJE1PTlRIKQpsZXZlbHMoQWlyX2RldGFpbHMkTU9OVEgpCmBgYAoKIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJIApUaGUgZGF0YXNldCBjaG9vc2VuIGlzIGFscmVhZHkgdGlkeS4gSGVyZSB0aGUgdW53YW5yZWQgdmFyaWFibGVzIGFyZSByZW1vdmVkIHRvIGluY3JlYXNlIHRoZSBlYXNlIG9mIGFuYXlzaXMuCmBgYHtyfQojdW53YW50ZWQgYXJlIHJlbW92ZWQKQWlyX2RldGFpbHNfdGlkeTwtIEFpcl9kZXRhaWxzICU+JSAKICBzZWxlY3QoLURJVkVSVEVELC1gQ0FOQ0VMTEVEYCwtYENBTkNFTExBVElPTl9SRUFTT05gLC1gQUlSX1NZU1RFTV9ERUxBWWAsLVNFQ1VSSVRZX0RFTEFZLC1BSVJMSU5FX0RFTEFZLC1MQVRFX0FJUkNSQUZUX0RFTEFZLC1XRUFUSEVSX0RFTEFZKQpgYGAKIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJSSAKSW4gb3JkZXIgdG8gY2hlY2sgdGhlIHNwZWVkIG9mIGFlcm9wbGFuZSBpbiBrbS9oci5BIG11dGF0ZSBmdW5jdGlvbiBpcyB1c2VkIHRvIG1ha2UgYSBuZXcgdmFyaWFibGUgdGhhdCBpcyB0aGUgU3BlZWRfYWVyb3BsYW5lIGJ5IHVzaW5nIERpc3RhbmNlIHdoaWNoIGlzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBhaXJwb3J0cyBhbmQgYnkgdXNpbmcgQUlSX1RJTUUuCmBgYHtyfQpBaXJfZGV0YWlsc190aWR5PC1tdXRhdGUoQWlyX2RldGFpbHNfdGlkeSwKICAgICAgICBTcGVlZF9hZXJvcGxhbmUgPSBESVNUQU5DRSAvIChBSVJfVElNRS82MCkpCmBgYAoKIyMJU2NhbiBJIApUaGUgdG90YWwgbnVtYmVyIG9mIG1pc3Npbmcgb2JzZXJ2YXRpb25zIGFyZSBmb3VuZCBieSB1c2luZyBjb2xTdW1zIGZ1bmN0aW9uIGFuZCB0aGUgcGVyY2VudGFnZSBvZiBtaXNzaW5nIHZhbHVlcyBvZiB0b3RhbCBvYnNlcnZhdGlvbiBpcyBnb3R0ZW4uIEJ5IHVzaW5nIHdoaWNoIGFuZCBpcy5uYSBmdW5jdGlvbiB0aGUgbG9jYXRpb24gb2YgdGhlIG1pc3NpbmcgdmFsdWVzIGlzIGZvdW5kIG91dC5UaGUgbWlzc2luZyB2YWx1ZXMgYmFzZWQgd2hldGhlciB0aGV5IGFyZSBtZWFuIG9yIGNhdGVyZ29yaWNhbCB2YXJpYWJsZSBhcmUgcmVwbGFjZWQgYnkgbWVhbiBvciBtb2RlIG9mIHRoZSByZXNwZWN0aXZlIHZhcmlhYmxlLgpgYGB7cn0KY29sU3Vtcyhpcy5uYShBaXJfZGV0YWlsc190aWR5KSkKTkFfREVQQVJUVVJFX0RFTEFZPC13aGljaChpcy5uYShBaXJfZGV0YWlsc190aWR5JERFUEFSVFVSRV9ERUxBWSkpCk5BX0FSUklWQUxfREVMQVk8LXdoaWNoKGlzLm5hKEFpcl9kZXRhaWxzX3RpZHkkQVJSSVZBTF9ERUxBWSkpCk5BX1RBSUxOVU1CRVI8LXdoaWNoKGlzLm5hKEFpcl9kZXRhaWxzX3RpZHkkVEFJTF9OVU1CRVIpKQpOQV9BSVJfVElNRTwtd2hpY2goaXMubmEoQWlyX2RldGFpbHNfdGlkeSRBSVJfVElNRSkpCk5BX1NwZWVkX2Flcm9wbGFuZTwtd2hpY2goaXMubmEoQWlyX2RldGFpbHNfdGlkeSRTcGVlZF9hZXJvcGxhbmUpKQojUmVwbGFjZSBOQSAKQWlyX2RldGFpbHNfdGlkeSRERVBBUlRVUkVfREVMQVlbTkFfREVQQVJUVVJFX0RFTEFZXTwtbWVhbihBaXJfZGV0YWlsc190aWR5JERFUEFSVFVSRV9ERUxBWSxuYS5ybSA9IFQpCkFpcl9kZXRhaWxzX3RpZHkkQVJSSVZBTF9ERUxBWVtOQV9BUlJJVkFMX0RFTEFZXTwtbWVhbihBaXJfZGV0YWlsc190aWR5JEFSUklWQUxfREVMQVksbmEucm0gPSBUKQpBaXJfZGV0YWlsc190aWR5JEFJUl9USU1FW05BX0FJUl9USU1FXTwtbWVhbihBaXJfZGV0YWlsc190aWR5JEFJUl9USU1FLG5hLnJtID0gVCkKQWlyX2RldGFpbHNfdGlkeSRTcGVlZF9hZXJvcGxhbmVbTkFfU3BlZWRfYWVyb3BsYW5lXTwtbWVhbihBaXJfZGV0YWlsc190aWR5JFNwZWVkX2Flcm9wbGFuZSxuYS5ybSA9IFQpCmNvbFN1bXMoaXMubmEoQWlyX2RldGFpbHNfdGlkeSkpCmBgYAoKIyMJU2NhbiBJSQoqIFRoZSBib3hwbG90IGlzIHV0aWxpc2VkIHRvIHNjYW4gdGhlIHZhcmlhYmxlcyBmb3IgdGhlIG91dGxpZXJzLlRoZSB6LXNjb3JlIG1ldGhvZCBpcyB1c2VkIGJ1dCBpdCBpcyByYXRoZXIgaW5lZmZlY3RpdmUgaW4gcmVtb3ZpbmcgdGhlIG91dGxpZXJzLldoaWxlIHotc2NvcmUgaXMgY2FsY3VsYXRlZCByZXNjYWxpbmcgYW5kIGNlbnRlcmluZyBvZiBkYXRhIHRha2VzIHBsYWNlIGFuZCBkYXRhIHBvaW50cyBhd2F5IGZyb20gemVybyBhcmUgbm90aWNlZC5UaGUgcG9pbnRzIHdoaWNoIGFyZSBhd2F5IGZyb20gemVybyBhcmUgb3V0bGllcnMuQSB0aHJlc2hvbGQgb2YgMyBpcyB1dGlsaXNlZCBpdCBtZWFucyBpZiB0aGUgdmFsdWUgb2Ygei1zY29yZSBpcyBncmV0ZXIgdGhhbiAzIHRhaHQgZGF0YSBwb2ludCBpcyBjb25zaWRlcmVkIHRvIGJlIG91dGxpZXJzLiAKKiBTbyB0aGUgY2FwcGluZyBtZXRob2QgaXMgdXRpbGlzZWQgdG8gcmVtb3ZlIHRoZSBvdXRsaWVycy5JbiB0aGlzIG1ldGhvZG9sb2d5LCB0aGUgbG93ZXIgYW5kIHVwcGVyIHBlcmNlbnRpbGUgaXMgdXRpbGlzZWQgdG8gcmVwbGFjZSB0aGUgb3V0bGllcnMuV2UgdXNlZCByZXBsYWNlIGJ5IG1lZGlhbiwgcmVwbGFjaW5nIGJ5IDFzdCBxdWFkIGFuZCByZXBsYWNpbmcgYnkgM3IgcXVhZC4KKiBJbiByZXBsYWNlIGJ5IG1lZGlhbiBmdW5jdGlvbiwgdGhlIHVwcGVyIGFuZCBsb3dlciBwZXJjZW50aWxlIGxpbWl0IGlzIHNldCB0byAyNSBhbmQgNzUlLkJ1dCBpdCBpcyBub3QgYWZmZWN0aXZlIGluIHRoaXMgY2FzZS4KKiBJbiB0aGUgcmVwbGFjaW5nIGJ5IDFzdCBxdWFkIGZ1bmN0aW9uLCBpdCBpcyBhZmZlY3RpdmUgdG8gYSBjZXJ0YWluIGV4dGVuZC4KKiBJbiB0aGUgcmVwbGFjaW5nIGJ5IDNyIHF1YWQgZnVuY3Rpb24sIHRoZSBsb3dlciBhbmQgdXBwZXIgcGVyY2VudGlsZSBsaW1pdCBoYXMgYmVlbiBleHRlbmRlZCB0byA1IGFuZCA5NSUgYW5kIGl0IG1vcmUgZWZmZWN0aXZlIHRoYW4gdGhlIG90aGVyIGZ1bmN0aW9ucy4KCmBgYHtyfQoKI3otc2NvcmUgbWV0aG9kCiMgQ2FsY3VsYXRlIHotc2NvcmUKei5zY29yZXMuQUlSX1RJTUUgPC0gQWlyX2RldGFpbHNfdGlkeSRBSVJfVElNRSAlPiUgIHNjb3Jlcyh0eXBlID0gInoiKQp6LnNjb3Jlcy5ESVNUQU5DRSA8LSBBaXJfZGV0YWlsc190aWR5JERJU1RBTkNFICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpCmNsZWFuX0FJUl9USU1FIDwtIEFpcl9kZXRhaWxzX3RpZHlbLSB3aGljaChhYnMoei5zY29yZXMuQUlSX1RJTUUpID4zICksXQpjbGVhbl9ESVNUQU5DRTwtIEFpcl9kZXRhaWxzX3RpZHlbLSB3aGljaChhYnMoei5zY29yZXMuRElTVEFOQ0UpID4zICksXQpwYXIobWZyb3c9YygxLDQpKQpib3hwbG90KEFpcl9kZXRhaWxzX3RpZHkkQUlSX1RJTUUsIG1haW4gPSAiQm94IFBsb3Qgb2YgQUlSX1RJTUUiLHZlcnRpY2xlPVRSVUUsIGNvbCA9ICJwaW5rIikKYm94cGxvdChBaXJfZGV0YWlsc190aWR5JERJU1RBTkNFLCBtYWluID0gIkJveCBQbG90IG9mIERJU1RBTkNFIix2ZXJ0aWNsZT1UUlVFLCBjb2wgPSAicGluayIpCmNsZWFuX0FJUl9USU1FJEFJUl9USU1FICU+JSAgYm94cGxvdChtYWluPSJac2NvcmUgQm94IFBsb3Qgb2YgQUlSX1RJTUUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiPSJBSVJfVElNRSgkKSIsIGNvbCA9ICJwaW5rIikKY2xlYW5fRElTVEFOQ0UkRElTVEFOQ0UgJT4lICBib3hwbG90KG1haW49InpzY29yZSBCb3ggUGxvdCBvZiBESVNUQU5DRSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWI9IkRJU1RBTkNFKCQpIiwgY29sID0gInBpbmsiKQojTWVkaWFuIG1ldGhvZCBhaXIgdGltZQpSZXBsYWNlX2J5X21lZGlhbiA8LSBmdW5jdGlvbih6KSB7CiBxdWFudGlsZXMgPC0gcXVhbnRpbGUoIHosIGMoIDAuMjUsIDAuNTAsIC43NSApICkKIHpbIHogPCBxdWFudGlsZXNbMV0gLSAxLjUqSVFSKHopIF0gPC0gcXVhbnRpbGVzWzJdCiB6WyB6ID4gcXVhbnRpbGVzWzNdICsgMS41KklRUih6KSBdIDwtIHF1YW50aWxlc1syXQogen0KUmVwbGFjaW5nX2J5XzFzdF9xdWFkPC0gZnVuY3Rpb24oeikgewogcXVhbnRpbGVzIDwtIHF1YW50aWxlKCB6LCBjKCAwLjI1LCAwLjUwLCAuNzUgKSApCiB6WyB6IDwgcXVhbnRpbGVzWzFdIC0gMS41KklRUih6KSBdIDwtIHF1YW50aWxlc1sxXQogelsgeiA+IHF1YW50aWxlc1szXSArIDEuNSpJUVIoeikgXSA8LSBxdWFudGlsZXNbMV0KIHp9ClJlcGxhY2luZ19ieV8zcmRfcXVhZDwtIGZ1bmN0aW9uKHopIHsKIHF1YW50aWxlcyA8LSBxdWFudGlsZSggeiwgYyggMC4wNSwwLjI1LCAwLjc1LCAuOTUgKSApCiB6WyB6IDwgcXVhbnRpbGVzWzFdIC0gMS41KklRUih6KSBdIDwtIHF1YW50aWxlc1szXQogelsgeiA+IHF1YW50aWxlc1szXSArIDEuNSpJUVIoeikgXSA8LSBxdWFudGlsZXNbM10KIHp9CnBhcihtZnJvdz1jKDEsNCkpCmJveHBsb3QoQWlyX2RldGFpbHNfdGlkeSRBSVJfVElNRSxtYWluPSJCZWZvcmUgT3V0bGllciBSZW1vdmFsICAiLCBjb2w9ICJwaW5rIikKQWZ0ZXJfQ2FwPC1BaXJfZGV0YWlsc190aWR5JEFJUl9USU1FICU+JSBSZXBsYWNlX2J5X21lZGlhbigpCmJveHBsb3QoQWZ0ZXJfQ2FwLG1haW49IkFJUl9USU1FIGJ5IE1lZGlhbiIsIGNvbD0gInBpbmsiKQpBZnRlcl9DYXBfMTwtQWlyX2RldGFpbHNfdGlkeSRBSVJfVElNRSAlPiUgUmVwbGFjaW5nX2J5XzFzdF9xdWFkKCkKYm94cGxvdChBZnRlcl9DYXBfMSxtYWluPSJBSVJfVElNRSBieSAxc3QgUXUiLGNvbD0gInJlZCIpCkFmdGVyX0NhcF8yPC1BaXJfZGV0YWlsc190aWR5JEFJUl9USU1FICU+JSBSZXBsYWNpbmdfYnlfM3JkX3F1YWQoKQpib3hwbG90KEFmdGVyX0NhcF8yLG1haW49IkFJUl9USU1FIGJ5IDNyZCBRdSIsY29sPSAieWVsbG93IikKI01lZGlhbiBtZXRob2QgZHVzdGFuY2UKUmVwbGFjaW5nX2J5X21lZGlhbiA8LSBmdW5jdGlvbih6KSB7CiBxdWFudGlsZXMgPC0gcXVhbnRpbGUoIHosIGMoIDAuMjUsIDAuNTAsIC43NSApICkKIHpbIHogPCBxdWFudGlsZXNbMV0gLSAxLjUqSVFSKHopIF0gPC0gcXVhbnRpbGVzWzJdCiB6WyB6ID4gcXVhbnRpbGVzWzNdICsgMS41KklRUih6KSBdIDwtIHF1YW50aWxlc1syXQogen0KUmVwbGFjaW5nX2J5XzFzdDwtIGZ1bmN0aW9uKHopIHsKIHF1YW50aWxlcyA8LSBxdWFudGlsZSggeiwgYyggMC4yNSwgMC41MCwgLjc1ICkgKQogelsgeiA8IHF1YW50aWxlc1sxXSAtIDEuNSpJUVIoeikgXSA8LSBxdWFudGlsZXNbMV0KIHpbIHogPiBxdWFudGlsZXNbM10gKyAxLjUqSVFSKHopIF0gPC0gcXVhbnRpbGVzWzFdCiB6fQoKUmVwbGFjaW5nX2J5XzNyZDwtIGZ1bmN0aW9uKHopIHsKIHF1YW50aWxlcyA8LSBxdWFudGlsZSggeiwgYyggMC4wNSwwLjI1LCAwLjc1LCAuOTUgKSApCiB6WyB6IDwgcXVhbnRpbGVzWzFdIC0gMS41KklRUih6KSBdIDwtIHF1YW50aWxlc1szXQogelsgeiA+IHF1YW50aWxlc1szXSArIDEuNSpJUVIoeikgXSA8LSBxdWFudGlsZXNbM10KIHp9CnBhcihtZnJvdz1jKDEsNCkpCmJveHBsb3QoQWlyX2RldGFpbHNfdGlkeSRESVNUQU5DRSxtYWluPSJCZWZvcmUgT3V0bGllciBSZW1vdmFsICIsIGNvbD0gInJlZCIpCkFmdGVyX0NhcDwtQWlyX2RldGFpbHNfdGlkeSRESVNUQU5DRSAlPiUgUmVwbGFjaW5nX2J5X21lZGlhbigpCmJveHBsb3QoQWZ0ZXJfQ2FwLG1haW49IkRJU1RBTkNFIGJ5IE1lZGlhbiIsIGNvbD0gInJlZCIpCkFmdGVyX0NhcF8xPC1BaXJfZGV0YWlsc190aWR5JERJU1RBTkNFICU+JSBSZXBsYWNpbmdfYnlfMXN0KCkKYm94cGxvdChBZnRlcl9DYXBfMSxtYWluPSJESVNUQU5DRSBieSAxc3QgUXVkciIsY29sPSAiYmx1ZSIpCkFmdGVyX0NhcF8yPC1BaXJfZGV0YWlsc190aWR5JERJU1RBTkNFICU+JSBSZXBsYWNpbmdfYnlfM3JkKCkKYm94cGxvdChBZnRlcl9DYXBfMixtYWluPSJESVNUQU5DRSBieSAzcmQgUXUiLGNvbD0gInBpbmsiKQoKYGBgCgojIwlUcmFuc2Zvcm0gClRoZSB0cmFuc2Zvcm1hdGlvbiBoYXMgYmVlbiBjb25kdWN0ZWQgb24gQUlSX1RJTUUgYW5kIERJU1RBTkNFIHZhcmlhYmxlcy4gVGhlIGFpbSBpcyB0byBkZWNyZWFzZSB0aGUgc2tld25lc3MgYW5kIGNvbnZlcnQgaXQgdG8gbm9ybWFsaXNlZCBkYXRhLlRoZSBsb2cgdHJhbnNmb3JtYXRpb24gaGFzIGJlZW4gdXNlZCwgaXQgc3ByZWFkcyBvdXQgdGhlIGNvbmdlc3RlZCBkYXRhLkxvZyB0cmFuc2Zvcm1hdGlvbiBpcyB1c2VkIGZvciByaWdodCBza2V3ZWQuQSBub3JtYWwgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhIGlzIGFjaGlldmVkIGJ5IHRoaXMgbWV0aG9kLgpgYGB7cn0KcGFyKG1mcm93PWMoMSw0KSkKaGlzdChBaXJfZGV0YWlsc190aWR5JEFJUl9USU1FLG1haW49IkFJUl9USU1FIEJlZm9yZSBUcmFuc2Zvcm1hdGlvbiIsY29sID0gImdyZWVuIikKVGFpcjwtbG9nMTAoQWlyX2RldGFpbHNfdGlkeSRBSVJfVElNRSkKaGlzdChUYWlyLG1haW49IkFJUl9USU1FIEFmdGVyIFRyYW5zZm9ybWF0aW9uIixjb2wgPSAiZ3JlZW4iKQpoaXN0KEFpcl9kZXRhaWxzX3RpZHkkRElTVEFOQ0UsbWFpbj0iRElTVEFOQ0UgQmVmb3JlIFRyYW5zZm9ybWF0aW9uIixjb2wgPSAicGluayIpClRfZGlzdGFuY2U8LWxvZzEwKEFpcl9kZXRhaWxzX3RpZHkkRElTVEFOQ0UpCmhpc3QoVF9kaXN0YW5jZSxtYWluPSJESVNUQU5DRSBBZnRlciBUcmFuc2Zvcm1hdGlvbiIsY29sID0gInBpbmsiKQpgYGAKPGJyPgo8YnI+Cg==