Required packages

library(dplyr)
library(tidyr)
library(readr)
library(lubridate)
library(outliers)
library(ggplot2)
library(forecast)
Registered S3 method overwritten by 'xts':
  method     from
  as.zoo.xts zoo 
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
Registered S3 methods overwritten by 'forecast':
  method             from    
  fitted.fracdiff    fracdiff
  residuals.fracdiff fracdiff
This is forecast 8.9 
  Want to stay up-to-date? Read the Hyndsight blog:
  https://robjhyndman.com/hyndsight/

Executive Summary

Data

setwd("F:/DataPre/Assignment3")
data1 <- read_csv("Data/Data_rainfall_melbourne.csv")
Parsed with column specification:
cols(
  `Bureau of Meteorology station number` = col_double(),
  Year = col_double(),
  Month = col_double(),
  `Rainfall Amount` = col_double(),
  Quality = col_character(),
  `Report Generation Date` = col_character(),
  Outcome = col_character()
)
data2 <- read_csv("Data/Data_temperature_melbourne.csv")
Parsed with column specification:
cols(
  `Bureau of Meteorology station number` = col_double(),
  Year = col_double(),
  Month = col_double(),
  `Mean maximum temperature` = col_double(),
  Quality = col_character(),
  `Report Generation Date` = col_character(),
  Outcome = col_character()
)

Dataset 1

data1 <- data1 %>% select(-`Bureau of Meteorology station number`)
head(data1)

Dataset 2

data2 <- data2 %>% select(-`Bureau of Meteorology station number`)
head(data2)

Joining Datasets

data <- left_join(data1, data2 , by=c("Year","Month", "Report Generation Date"))
head(data)

Understand

str(data)
Classes ‘spec_tbl_df’, ‘tbl_df’, ‘tbl’ and 'data.frame':    57 obs. of  9 variables:
 $ Year                    : num  2015 2015 2015 2015 2015 ...
 $ Month                   : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Rainfall Amount         : num  1.832 1.478 0.967 1.038 1.38 ...
 $ Quality.x               : chr  "N" "Y" "Y" "Y" ...
 $ Report Generation Date  : chr  "01/02/2015" "01/03/2015" "01/04/2015" "01/05/2015" ...
 $ Outcome.x               : chr  "High" "High" "Low" "Low" ...
 $ Mean maximum temperature: num  25.9 26.4 22.7 19.2 17.1 NA 13.3 13.8 17.3 NA ...
 $ Quality.y               : chr  "Y" "Y" "Y" "N" ...
 $ Outcome.y               : chr  "High" "High" "High" "Low" ...
data$Outcome.x <-  factor(data$Outcome.x, levels = c("Low","High"), ordered = TRUE)
data$Outcome.y <- factor(data$Outcome.y,levels = c("Low","High"), ordered = TRUE)
data$Quality.x <- factor(data$Quality.x,levels = c("N","Y"))
data$Quality.y <- factor(data$Quality.y,levels = c("N","Y"))
data$`Report Generation Date` <- as.Date(data$`Report Generation Date`, format = "%d/%m/%Y")
summary(data$`Rainfall Amount`)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
 0.0410  0.9605  1.5460  1.6048  2.0945  4.7560       6 
summary(data$`Mean maximum temperature`)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  13.30   15.80   20.75   20.40   25.20   27.50       5 
str(data)
Classes ‘spec_tbl_df’, ‘tbl_df’, ‘tbl’ and 'data.frame':    57 obs. of  9 variables:
 $ Year                    : num  2015 2015 2015 2015 2015 ...
 $ Month                   : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Rainfall Amount         : num  1.832 1.478 0.967 1.038 1.38 ...
 $ Quality.x               : Factor w/ 2 levels "N","Y": 1 2 2 2 2 2 1 1 2 2 ...
 $ Report Generation Date  : Date, format: "2015-02-01" "2015-03-01" "2015-04-01" "2015-05-01" ...
 $ Outcome.x               : Ord.factor w/ 2 levels "Low"<"High": 2 2 1 1 2 1 2 NA 1 1 ...
 $ Mean maximum temperature: num  25.9 26.4 22.7 19.2 17.1 NA 13.3 13.8 17.3 NA ...
 $ Quality.y               : Factor w/ 2 levels "N","Y": 2 2 2 1 2 1 2 2 2 1 ...
 $ Outcome.y               : Ord.factor w/ 2 levels "Low"<"High": 2 2 2 1 1 NA 1 1 1 NA ...

Tidy & Manipulate Data I

str(data)
Classes ‘spec_tbl_df’, ‘tbl_df’, ‘tbl’ and 'data.frame':    57 obs. of  9 variables:
 $ Year                    : num  2015 2015 2015 2015 2015 ...
 $ Month                   : num  1 2 3 4 5 6 7 8 9 10 ...
 $ Rainfall Amount         : num  1.832 1.478 0.967 1.038 1.38 ...
 $ Quality.x               : Factor w/ 2 levels "N","Y": 1 2 2 2 2 2 1 1 2 2 ...
 $ Report Generation Date  : Date, format: "2015-02-01" "2015-03-01" "2015-04-01" "2015-05-01" ...
 $ Outcome.x               : Ord.factor w/ 2 levels "Low"<"High": 2 2 1 1 2 1 2 NA 1 1 ...
 $ Mean maximum temperature: num  25.9 26.4 22.7 19.2 17.1 NA 13.3 13.8 17.3 NA ...
 $ Quality.y               : Factor w/ 2 levels "N","Y": 2 2 2 1 2 1 2 2 2 1 ...
 $ Outcome.y               : Ord.factor w/ 2 levels "Low"<"High": 2 2 2 1 1 NA 1 1 1 NA ...
head(data)

Tidy & Manipulate Data II

data <- mutate(data,Month=factor(Month,labels = c('Jan','Feb','Mar','April','May','June','July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec')))
head(data)

Scan I

colSums(is.na(data))
                    Year                    Month          Rainfall Amount                Quality.x   Report Generation Date 
                       0                        0                        6                        0                        0 
               Outcome.x Mean maximum temperature                Quality.y                Outcome.y 
                       6                        5                        0                        5 
sum(is.na(data))
[1] 22
new_data <- na.omit(data) 
colSums(is.na(new_data)) 
                    Year                    Month          Rainfall Amount                Quality.x   Report Generation Date 
                       0                        0                        0                        0                        0 
               Outcome.x Mean maximum temperature                Quality.y                Outcome.y 
                       0                        0                        0                        0 
sum(is.na(new_data))
[1] 0

Scan II

z.scores_rainfall <- new_data$`Rainfall Amount` %>%  scores(type = "z")
length (which( abs(z.scores_rainfall) >3 ))
[1] 1
boxplot(new_data$`Rainfall Amount`, main = "BoxPlot of  Mean Rainfall", ylab = "Rainfall Amount in (mm)" , col = "red" )

z.scores_temperature <- new_data$`Mean maximum temperature` %>%  scores(type = "z")
length (which( abs(z.scores_temperature) >3 ))
[1] 0
boxplot(new_data$`Mean maximum temperature`, main = "BoxPlot of Mean Temperature", ylab = "Mean Temperature in (C)" , col = "blue" )

clean_rainfall <- new_data$`Rainfall Amount`[ - which( abs(z.scores_rainfall) >3 )]
z.scores_rainfall <- clean_rainfall %>%  scores(type = "z")
length (which( abs(z.scores_rainfall) >3 ))
[1] 0

Here we can see we have sucessfully removed all outliers from rainfall data

Transform

hist(new_data$`Rainfall Amount`, main = "Histogram of Temperature with vertical mean line", xlab = " Mean Rainfall in (mm)")
abline(v = mean(new_data$`Rainfall Amount`), col="red", lwd=3, lty=2)

hist(new_data$`Mean maximum temperature`, main = "Histogram of Temperature with vertical mean line", xlab = "Mean Temperature in (C)")
abline(v = mean(new_data$`Mean maximum temperature`), col="red", lwd=3, lty=2)

boxcox_rainfall <- BoxCox(new_data$`Rainfall Amount`, lambda = "auto")
hist(boxcox_rainfall, main="Histogram of Rainfall data after Transformation", xlab = " Mean Rainfall in (mm)" )
abline(v = mean(boxcox_rainfall), col="blue", lwd=3, lty=2)

boxcox_temperature <- BoxCox(new_data$`Mean maximum temperature`, lambda = "auto")
hist(boxcox_temperature, main="Histogram of Temperature data after Transformation", xlab = "Mean Temperature in (C)")
abline(v = mean(boxcox_temperature), col="blue", lwd=3, lty=2)



LS0tDQp0aXRsZTogIk1BVEgyMzQ5IFNlbWVzdGVyIDIsIDIwMTkiDQphdXRob3I6ICJEZXZhbnNoIFBhcm1hciAtIFMzNzkzNTU3Ig0Kc3VidGl0bGU6IEFzc2lnbm1lbnQgMw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQotLS0NCg0KDQojIyBSZXF1aXJlZCBwYWNrYWdlcyANCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkob3V0bGllcnMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KDQpgYGANCg0KDQojIyBFeGVjdXRpdmUgU3VtbWFyeSANCg0KLSBJbiB0aGlzIHRhc2sgb2YgRGF0YSBQcmVwcm9jZXNzaW5nLCBzZWxlY3RpbmcgdHdvIG9wZW4gZGF0YS1zZXRzIGFuZCBjb21iaW5pbmcgdGhlbSBhbmQgdW5kZXJzdGFuZGluZyB0aGUgZGF0YXR5cGVzLCBhcHBseWluZyBwcm9wZXIgdHlwZSBjb252ZXJzaW9ucy4gRnVydGhlciBpZGVudGlmeWluZyB3ZWF0aGVyIHRoZSBkYXRhLXNldCBpcyBpbiBUaWR5IGZvcm1hdCBhbmQgc2F0aXNmaWVzIHRpZHkgcHJpbmNpcGxlcy4gDQotIFRoZW4gd2UgYW5hbHl6ZSB0aGUgZGF0YSBmb3IgbWlzc2luZyB2YWx1ZXMsIGhhbmRsZXMgdGhlIG1pc3NpbmcgdmFsdWVzIGFuZCBhbG9uZyB3aXRoIHRoYXQgc2Nhbm5pbmcgZm9yIGFueSBvdXRsaWVycy4gDQotIEFsb25nIHdpdGggdGhhdCB2ZXJpZnlpbmcgaWYgdGhlIGRhdGEgaXMgaW4gbm9ybWFsaXplZCBmb3JtIGFuZCBwZXJmb3JtaW5nIHJlcXVpcmVkIHN1aXRhYmxlIHRyYW5zZm9ybWF0aW9uIHRvIG1ha2UgaXQgaW50byBub3JtYWxpemVkIGZvcm0uIFBlcmZvcm1pbmcgYXBwcm9wcmlhdGUgbWV0aG9kcyB0byByZW1vdmUgdGhlIG91dGxpZXJzIHN1Y2ggdGhhdCBpdCBoZWxwcyBjcmVhdGluZyB0aGUgcmVwb3J0IG1vcmUgYWNjdXJhdGUuIA0KLSBDb25jbHVkaW5nLCB3ZSBhcmUgbWFraW5nIHRoZSBkYXRhLXNldCByZWFkeSBhbmQgc3VpdGFibGUgZm9yIGFueSBzdGF0aXN0aWNhbCBhbmFseXNpcy4NCg0KDQojIyBEYXRhIA0KDQotIERhdGFzZXRzIGZyb20gQnVyZWF1IG9mIE1ldGVvcm9sb2d5IC0gQXV0cmFsaWFuIEdvdmVybm1lbnQgaGF2ZSBiZWVuIGNvbnNpZGVyZWQgZm9yIHBlcmZvcm1pbmcgZGF0YSBwcmVwcm9jZXNzaW5nLg0KDQotIFNvdXJjZTogaHR0cDovL2JvbS5nb3YuYXUvY2xpbWF0ZS9kYXRhDQoNCi0gV2UgaGF2ZSBjb25zaWRlcmVkIDIgZGF0YXNldHMgd2hpY2ggY29uc2lzdHMgZGF0YSBhYm91dCBSYWluZmFsbCBhbmQgVGVtcGVyYXR1cmUgaW4gbGFzdCA1IHllYXJzLg0KDQotIEluIGRhdGFzZXQgMSBjb250YWluaW5nIFJhaW5mYWxsIGRhdGEgaGF2ZSB2YXJpYWJsZXMgQnVyZWF1IG9mIE1ldGVvcm9sb2d5IHN0YXRpb24gbnVtYmVyLCBZZWFyLCBNb250aCwgUmFpbmZhbGwgQW1vdW50LCBRdWFsaXR5IGFuZCBSZXBvcnQgR2VuZXJhdGlvbiBEYXRlLiANCg0KLSAnQnVyZWF1IG9mIE1ldGVvcm9sb2d5IHN0YXRpb24gbnVtYmVyJyBnaXZlcyB1bmlxdWUgaWRlbnRpZmljYXRpb24gbnVtYmVyIGZvciBhIHdlYXRoZXIgc3RhdGlvbiBmcm9tIHdoaWNoIGRhdGEgaXMgY29sbGVjdGVkLiAnWWVhcicgaW5kaWNhdGVzIHRoZSB5ZWFyIGluIHdoaWNoIHRoZSBvYnNlcnZhdGlvbiB3YXMgcmVjb3JkZWQuIA0KDQotIE1vbnRoIGluZGljYXRlZCBtb250aCBpbiB3aGljaCBvYnNlcnZhdGlvbiB3YXMgcmVjb3JkZWQuIA0KJ1JhaW5mYWxsIEFtb3VudCcgZ2l2ZXMgbWVhbiBxdWFudGl0eSBvZiByYWluZmFsbCBvYnNlcnZlZCBpbiB0aGF0IHBhcnRpY3VsYXIgbW9udGggaW4gbWlsaW1ldGVycyhtbSkgYXMgdW5pdC4gDQoNCi0gJ1F1YWxpdHknIGlzIGEgcXVhbGl0eSBmbGFnLiBDbGltYXRlIGRhdGEgcGFzcyB0aHJvdWdoIGEgbnVtYmVyIG9mIHN0YWdlcyBpbiBxdWFsaXR5IGNvbnRyb2wgd2hpY2ggb2NjdXJzIG92ZXIgYSBwZXJpb2Qgb2YgdGltZS4gIElmIHF1bGl0eSBmbGFnID0gWSB0aGVuIGFsbCB0aGUgbWluaW11bSByZXF1aXJlbWVudHMgYXJlIGZ1bGZpbGxlZCBhbmQgaXQgZW5zdXJlcyB0aGVyZSBpcyBubyBlcnJvcnMuIElmIHF1YWxpdHkgZmxhZyA9IE4gdGhlbiBpdCBpbmRpY2F0ZXMgdGhhdCBhbGwgdGhlIG1pbmltdW4gcmVxdWlyZW1lbnRzIGhhdmUgYmVlbiBmdWxmaWxsZWQuIEhvd2V2ZXIgdGhlcmUgZXhpc3RzIGNlcnRhaW4gZXJyb3IgaW4gdGhlIG9ic2VydmF0aW9ucyBjb25pZGVyZWQuICdSZXBvcnQgR2VuZXJhdGlvbiBEYXRlJyBpcyB0aGUgZGF0ZSBvbiB3aGljaCB0aGUgb2JzZXJ2YXRpb25zIHdlcmUgcHVibGlzaGVkLg0KDQotICdPdXRjb21lJyBpbmRpY2F0ZXMgSGlnaCBpZiBtZWFuIHZhbHVlIGZvciB0aGF0IG1vbnRoIGlzIGhpZ2hlciB0aGFuIEFubnVhbCBtZWFuIHZhbHVlLg0KDQotIEluIGRhdGFzZXQgMiBjb250YWluaW5nIFRlbXBlcmF0dXJlIGRhdGEgaGF2ZSB2YXJpYWJsZXMgQnVyZWF1IG9mIE1ldGVvcm9sb2d5IHN0YXRpb24gbnVtYmVyLCBZZWFyLCBNb250aCwgTWVhbiBNYXhpbXVtIHRlbXBlcmF0dXJlLCBRdWFsaXR5IGFuZCBSZXBvcnQgR2VuZXJhdGlvbiBEYXRlLg0KDQotICdCdXJlYXUgb2YgTWV0ZW9yb2xvZ3kgc3RhdGlvbiBudW1iZXInIGdpdmVzIHVuaXF1ZSBpZGVudGlmaWNhdGlvbiBudW1iZXIgZm9yIGEgd2VhdGhlciBzdGF0aW9uIGZyb20gd2hpY2ggZGF0YSBpcyBjb2xsZWN0ZWQuICdZZWFyJyBpbmRpY2F0ZXMgdGhlIHllYXIgaW4gd2hpY2ggdGhlIG9ic2VydmF0aW9uIHdhcyByZWNvcmRlZC4gTW9udGggaW5kaWNhdGVkIG1vbnRoIGluIHdoaWNoIG9ic2VydmF0aW9uIHdhcyByZWNvcmRlZC4gDQoNCi0gJ01lYW4gTWF4aW11bSB0ZW1wZXJhdHVyZScgZ2l2ZXMgbWVhbiBvZiBtYXhpbXVtIHRlbXBlcmF0dXJlIG9ic2VydmVkIGluIGEgZGF5IGluIGEgbW9udGggaW4gQ2VsY2l1cyAoQykgYXMgdW5pdC4gDQoNCi0gJ1F1YWxpdHknIGlzIGEgcXVhbGl0eSBmbGFnLiBDbGltYXRlIGRhdGEgcGFzcyB0aHJvdWdoIGEgbnVtYmVyIG9mIHN0YWdlcyBpbiBxdWFsaXR5IGNvbnRyb2wgd2hpY2ggb2NjdXJzIG92ZXIgYSBwZXJpb2Qgb2YgdGltZS4gIElmIHF1bGl0eSBmbGFnID0gWSB0aGVuIGFsbCB0aGUgbWluaW11bSByZXF1aXJlbWVudHMgYXJlIGZ1bGZpbGxlZCBhbmQgaXQgZW5zdXJlcyB0aGVyZSBpcyBubyBlcnJvcnMuIElmIHF1YWxpdHkgZmxhZyA9IE4gdGhlbiBpdCBpbmRpY2F0ZXMgdGhhdCBhbGwgdGhlIG1pbmltdW4gcmVxdWlyZW1lbnRzIGhhdmUgYmVlbiBmdWxmaWxsZWQuIEhvd2V2ZXIgdGhlcmUgZXhpc3RzIGNlcnRhaW4gZXJyb3IgaW4gdGhlIG9ic2VydmF0aW9ucyBjb25pZGVyZWQuICdSZXBvcnQgR2VuZXJhdGlvbiBEYXRlJyBpcyB0aGUgZGF0ZSBvbiB3aGljaCB0aGUgb2JzZXJ2YXRpb25zIHdlcmUgcHVibGlzaGVkLiANCg0KLSAnT3V0Y29tZScgaW5kaWNhdGVzIEhpZ2ggaWYgbWVhbiB2YWx1ZSBmb3IgdGhhdCBtb250aCBpcyBoaWdoZXIgdGhhbiBBbm51YWwgbWVhbiB2YWx1ZS4NCg0KYGBge3J9DQpzZXR3ZCgiRjovRGF0YVByZS9Bc3NpZ25tZW50MyIpDQpkYXRhMSA8LSByZWFkX2NzdigiRGF0YS9EYXRhX3JhaW5mYWxsX21lbGJvdXJuZS5jc3YiKQ0KZGF0YTIgPC0gcmVhZF9jc3YoIkRhdGEvRGF0YV90ZW1wZXJhdHVyZV9tZWxib3VybmUuY3N2IikNCmBgYA0KDQojIyBEYXRhc2V0IDENCi0gUmVtb3ZpbmcgdGhlIFN0YXRpb24gbnVtYmVyIHZhcmlhYmxlIGFzIGl0IHBlcnNpc3RlcyBhcyBzYW1lIHRocm91Z2hvdXQgdGhlIGRhdGFzZXQuDQpgYGB7cn0NCmRhdGExIDwtIGRhdGExICU+JSBzZWxlY3QoLWBCdXJlYXUgb2YgTWV0ZW9yb2xvZ3kgc3RhdGlvbiBudW1iZXJgKQ0KaGVhZChkYXRhMSkNCmBgYA0KDQojIyBEYXRhc2V0IDINCi0gUmVtb3ZpbmcgdGhlIFN0YXRpb24gbnVtYmVyIHZhcmlhYmxlIGFzIGl0IHBlcnNpc3RlcyBhcyBzYW1lIHRocm91Z2hvdXQgdGhlIGRhdGFzZXQuDQpgYGB7cn0NCmRhdGEyIDwtIGRhdGEyICU+JSBzZWxlY3QoLWBCdXJlYXUgb2YgTWV0ZW9yb2xvZ3kgc3RhdGlvbiBudW1iZXJgKQ0KaGVhZChkYXRhMikNCmBgYA0KIyMgSm9pbmluZyBEYXRhc2V0cw0KDQotIENvbWJpbmluZyB0aGUgZGF0YXNldHMgdXNpbmcgWWVhciwgTW9udGggYW5kIFJlcG9ydCBnZW5lcmF0aW9uIGRhdGUgYXMgY29tbW9uIGF0dHJpYnV0ZSB1c2luZyBsZWZ0IGpvaW4gdG8gZW5zdXJlIHRoYXQgb25seSB0aG9zZSByZWNvcmRzIGZyb20gc2Vjb25kIGRhdGFzZXQgYXJlIGNvbWJpbmVkIHdoaWNoIGhhdmUgc2FtZSBZZWFyLCBNb250aCBhbmQgUmVwb3J0IGdlbmVyYXRpb24gZGF0ZSBhcyBpbiBmaXJzdCBkYXRhc2V0Lg0KDQpgYGB7cn0NCmRhdGEgPC0gbGVmdF9qb2luKGRhdGExLCBkYXRhMiAsIGJ5PWMoIlllYXIiLCJNb250aCIsICJSZXBvcnQgR2VuZXJhdGlvbiBEYXRlIikpDQpoZWFkKGRhdGEpDQpgYGANCg0KIyMgVW5kZXJzdGFuZCANCg0KLSBJbiB0aGlzIHN0ZXAgd2UgYXJlIHR5cGVjYXN0aW5nIHZhcmlhYmxlIE91dGNvbWUueCBhbmQgT3V0Y29tZS55IGZyb20gY2hhcmFjdGVyIHRvIGFuIG9yZGVyZWQgZmFjdG9yIHVzaW5nIGZhY3RvcigpIGZ1bmN0aW9uLg0KLSBXZSBhcmUgY29udmVydGluZyAnUmVwb3J0IGdlbmVyYXRpb24gRGF0ZScgdmFyaWFibGUgdG8gRGF0ZSB0eXBlIGZyb20gY2hhcmFjdGVyIHR5cGUgdXNpbmcgYXMuRGF0ZSgpIG1ldGhvZC4NCmFuZCBzdW1tYXJpc2luZyBSYWluZmFsbCBhbmQgVGVtcGVyYXR1cmUgd2UgZ2V0IHRvIGtub3cgdGhhdCB0aGVyZSBhcmUgNiBhbmQgNSBtaXNzaW5nIHZhbHVlcyByZXNwZWN0aXZlbHkgYW5kIGhhdmUgbWVhbiByYWluZmFsbCBvZiAxLjYgbW0gYW5kIFRlbXBlcmF0dXJlIG9mIDIwLjQgZGVncmVlIGNlbGNpdXMgbW9udGhseSBmb3IgcGFzdCA1IHllYXJzLg0KDQpgYGB7cn0NCnN0cihkYXRhKQ0KZGF0YSRPdXRjb21lLnggPC0gIGZhY3RvcihkYXRhJE91dGNvbWUueCwgbGV2ZWxzID0gYygiTG93IiwiSGlnaCIpLCBvcmRlcmVkID0gVFJVRSkNCmRhdGEkT3V0Y29tZS55IDwtIGZhY3RvcihkYXRhJE91dGNvbWUueSxsZXZlbHMgPSBjKCJMb3ciLCJIaWdoIiksIG9yZGVyZWQgPSBUUlVFKQ0KZGF0YSRRdWFsaXR5LnggPC0gZmFjdG9yKGRhdGEkUXVhbGl0eS54LGxldmVscyA9IGMoIk4iLCJZIikpDQpkYXRhJFF1YWxpdHkueSA8LSBmYWN0b3IoZGF0YSRRdWFsaXR5LnksbGV2ZWxzID0gYygiTiIsIlkiKSkNCmRhdGEkYFJlcG9ydCBHZW5lcmF0aW9uIERhdGVgIDwtIGFzLkRhdGUoZGF0YSRgUmVwb3J0IEdlbmVyYXRpb24gRGF0ZWAsIGZvcm1hdCA9ICIlZC8lbS8lWSIpDQpzdW1tYXJ5KGRhdGEkYFJhaW5mYWxsIEFtb3VudGApDQpzdW1tYXJ5KGRhdGEkYE1lYW4gbWF4aW11bSB0ZW1wZXJhdHVyZWApDQpzdHIoZGF0YSkNCmBgYA0KDQojIwlUaWR5ICYgTWFuaXB1bGF0ZSBEYXRhIEkgDQoNCmBgYHtyfQ0Kc3RyKGRhdGEpDQpoZWFkKGRhdGEpDQpgYGANCg0KLSBUaGUgZGF0YXNldCBpcyBUaWR5IGFzIGVhY2ggdmFyaWFibGUgaGF2ZSBpdHMgb3duIGNvbHVtbiwgRWFjaCBvYnNlcnZhdGlvbiBoYXZlIGl0cyBvd24gcm93IGFuZCBFYWNoIHZhbHVlIG11c3QgaGF2ZSBpdHMgb3duIGNlbGwuIEhlbmNlIGZ1bGZpbGxpbmcgdGhlIHRpZHkgcHJpbmNpcGxlcyB3ZSBjYW4gc2F5IHRoYXQgdGhlIGRhdGFzZXQgaXMgdGlkeS4gDQoNCg0KIyMJVGlkeSAmIE1hbmlwdWxhdGUgRGF0YSBJSSANCg0KLSBNdXRhdGluZyB0aGUgdmFyaWFibGUgTW9udGggYW5kIHJlcGxhY2luZyB0aGUgbnVtZXJpY2FsIHJlcHJlc2VudGF0aW9uIG9mIG1vbnRoIG51bWJlciB3aXRoIG5hbWUgb2YgbW9udGguDQoNCmBgYHtyfQ0KZGF0YSA8LSBtdXRhdGUoZGF0YSxNb250aD1mYWN0b3IoTW9udGgsbGFiZWxzID0gYygnSmFuJywnRmViJywnTWFyJywnQXByaWwnLCdNYXknLCdKdW5lJywnSnVseScsICdBdWcnLCAnU2VwdCcsICdPY3QnLCAnTm92JywgJ0RlYycpKSkNCmhlYWQoZGF0YSkNCmBgYA0KDQoNCiMjCVNjYW4gSSANCg0KLSBTY2FubmluZyB0aGUgZGF0YSBmb3IgbWlzc2luZyB2YWx1ZXMNCg0KYGBge3J9DQpjb2xTdW1zKGlzLm5hKGRhdGEpKQ0Kc3VtKGlzLm5hKGRhdGEpKQ0KYGBgDQoNCi0gQWZ0ZXIgU2Nhbm5pbmcgdGhlIGRhdGEgZm9yIG1pc3NpbmcgdmFsdWVzIGFuZCB3ZSBjYW4gc2VlIHRoZXJlIGFyZSAyMiBtaXNzaW5nIHZhbHVlcyBpbiB0b3RhbCBmcm9tIGRpZmZlcmVudCBjb2x1bW5zLg0KDQpgYGB7cn0NCm5ld19kYXRhIDwtIG5hLm9taXQoZGF0YSkgDQpjb2xTdW1zKGlzLm5hKG5ld19kYXRhKSkgDQpzdW0oaXMubmEobmV3X2RhdGEpKQ0KYGBgDQoNCi0gSW4gdGhpcyBzdGVwLCByZW1vdmluZyB0aGUgbWlzc2luZyB2YWx1ZXMgcmF0aGVyIHRoYW4gZ29pbmcgZm9yIG90aGVyIGFwcHJvYWNoZXMgbGlrZSByZXBsYWNpbmcgdmFsdWVzIHdpdGggYSBjb25zdGFudCBvciBtZWFuIG9yIG1lZGlhbiBhcyB0aGlzIGNhbiBhZmZlY3QgdGhlICdPdXRjb21lJyB2YXJpYWJsZSBhbmQgZ2l2ZSBmYWxzZSB3cm9uZyB2YWx1ZS4NCg0KIyMJU2NhbiBJSQ0KDQpgYGB7cn0NCnouc2NvcmVzX3JhaW5mYWxsIDwtIG5ld19kYXRhJGBSYWluZmFsbCBBbW91bnRgICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpDQpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXNfcmFpbmZhbGwpID4zICkpDQpib3hwbG90KG5ld19kYXRhJGBSYWluZmFsbCBBbW91bnRgLCBtYWluID0gIkJveFBsb3Qgb2YgIE1lYW4gUmFpbmZhbGwiLCB5bGFiID0gIlJhaW5mYWxsIEFtb3VudCBpbiAobW0pIiAsIGNvbCA9ICJyZWQiICkNCnouc2NvcmVzX3RlbXBlcmF0dXJlIDwtIG5ld19kYXRhJGBNZWFuIG1heGltdW0gdGVtcGVyYXR1cmVgICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpDQpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXNfdGVtcGVyYXR1cmUpID4zICkpDQpib3hwbG90KG5ld19kYXRhJGBNZWFuIG1heGltdW0gdGVtcGVyYXR1cmVgLCBtYWluID0gIkJveFBsb3Qgb2YgTWVhbiBUZW1wZXJhdHVyZSIsIHlsYWIgPSAiTWVhbiBUZW1wZXJhdHVyZSBpbiAoQykiICwgY29sID0gImJsdWUiICkNCmBgYA0KDQotIEluIHRoaXMgc3RlcCwgYWZ0ZXIgc2Nhbm5pbmcgZm9yIG91dGxpZXJzIHVzaW5nIGJveHBsb3Qgd2UgY2FuIGluZmVyIHRoYXQgdGhlcmUgZXhpc3Qgb25seSBvbmUgb3V0bGllciBpbiBSYWluZmFsbCBkYXRhIHdoaWxlIG5vIG91dGxpZXJzIGluIFRlbXBlcmF0dXJlIGRhdGEuDQoNCmBgYHtyfQ0KY2xlYW5fcmFpbmZhbGwgPC0gbmV3X2RhdGEkYFJhaW5mYWxsIEFtb3VudGBbIC0gd2hpY2goIGFicyh6LnNjb3Jlc19yYWluZmFsbCkgPjMgKV0NCnouc2NvcmVzX3JhaW5mYWxsIDwtIGNsZWFuX3JhaW5mYWxsICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpDQpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXNfcmFpbmZhbGwpID4zICkpDQpgYGANCkhlcmUgd2UgY2FuIHNlZSB3ZSBoYXZlIHN1Y2Vzc2Z1bGx5IHJlbW92ZWQgYWxsIG91dGxpZXJzIGZyb20gcmFpbmZhbGwgZGF0YQ0KDQojIwlUcmFuc2Zvcm0gDQoNCmBgYHtyfQ0KaGlzdChuZXdfZGF0YSRgUmFpbmZhbGwgQW1vdW50YCwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgVGVtcGVyYXR1cmUgd2l0aCB2ZXJ0aWNhbCBtZWFuIGxpbmUiLCB4bGFiID0gIiBNZWFuIFJhaW5mYWxsIGluIChtbSkiKQ0KYWJsaW5lKHYgPSBtZWFuKG5ld19kYXRhJGBSYWluZmFsbCBBbW91bnRgKSwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpDQpoaXN0KG5ld19kYXRhJGBNZWFuIG1heGltdW0gdGVtcGVyYXR1cmVgLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBUZW1wZXJhdHVyZSB3aXRoIHZlcnRpY2FsIG1lYW4gbGluZSIsIHhsYWIgPSAiTWVhbiBUZW1wZXJhdHVyZSBpbiAoQykiKQ0KYWJsaW5lKHYgPSBtZWFuKG5ld19kYXRhJGBNZWFuIG1heGltdW0gdGVtcGVyYXR1cmVgKSwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpDQpgYGANCg0KLSBXZSBjYW4gc2VlIHRoYXQgYm90aCB0aGUgZGF0YSBhcmUgc2xpZ2h0bHkgcmlnaHQgc2tld2VkLiBIZW5jZSBhcHBseWluZyBCb3hjb3ggVHJhbnNmb3JtYXRpb24gaW4gb3JkZXIgdG8gbm9ybWFsaXplIHRoZSBkYXRhLg0KDQpgYGB7cn0NCmJveGNveF9yYWluZmFsbCA8LSBCb3hDb3gobmV3X2RhdGEkYFJhaW5mYWxsIEFtb3VudGAsIGxhbWJkYSA9ICJhdXRvIikNCmhpc3QoYm94Y294X3JhaW5mYWxsLCBtYWluPSJIaXN0b2dyYW0gb2YgUmFpbmZhbGwgZGF0YSBhZnRlciBUcmFuc2Zvcm1hdGlvbiIsIHhsYWIgPSAiIE1lYW4gUmFpbmZhbGwgaW4gKG1tKSIgKQ0KYWJsaW5lKHYgPSBtZWFuKGJveGNveF9yYWluZmFsbCksIGNvbD0iYmx1ZSIsIGx3ZD0zLCBsdHk9MikNCmJveGNveF90ZW1wZXJhdHVyZSA8LSBCb3hDb3gobmV3X2RhdGEkYE1lYW4gbWF4aW11bSB0ZW1wZXJhdHVyZWAsIGxhbWJkYSA9ICJhdXRvIikNCmhpc3QoYm94Y294X3RlbXBlcmF0dXJlLCBtYWluPSJIaXN0b2dyYW0gb2YgVGVtcGVyYXR1cmUgZGF0YSBhZnRlciBUcmFuc2Zvcm1hdGlvbiIsIHhsYWIgPSAiTWVhbiBUZW1wZXJhdHVyZSBpbiAoQykiKQ0KYWJsaW5lKHYgPSBtZWFuKGJveGNveF90ZW1wZXJhdHVyZSksIGNvbD0iYmx1ZSIsIGx3ZD0zLCBsdHk9MikNCmBgYA0KLSBIZXJlIGFmdGVyIHRyYW5zZm9ybWF0aW9uIHRocm91Z2ggdmlzdWFsIGluc3BlY3Rpb24gd2UgY2FuIHNlZSB0aGUgZGF0YSBpcyBpbiBub3JtYWxpemVkIGZvcm0gdXNpbmcgbWVhbiBsaW5lIGFzIHJlZmVyZW5jZS4NCg0KPGJyPg0KPGJyPg0K