Import Library

knitr::opts_chunk$set(echo = TRUE)
packages = c('dplyr','forecast','ggplot2','reshape2','readxl')
for (p in packages){
  if(!require(p, character.only = T)){
    install.packages(p) 
  } 
  library(p,character.only = T) 
}

Glimpse of Data

df <- read_excel( "./Singapore_Residents_by_Planning.xlsx")

-
/
                                                                                                                        
head(df)

Filter only Punggol PA & Clean Data

punggol_PA <- df %>%
  filter(`Planning Area` == "Punggol") %>%
  filter(`Subzone` != "Total")  %>%
   filter(`Age Group` != "Total") 
str(punggol_PA)
Classes 'tbl_df', 'tbl' and 'data.frame':   1197 obs. of  13 variables:
 $ Planning Area   : chr  "Punggol" "Punggol" "Punggol" "Punggol" ...
 $ Subzone         : chr  "Coney Island" "Coney Island" "Coney Island" "Coney Island" ...
 $ Age Group       : chr  "0 - 4" "0 - 4" "0 - 4" "0 - 4" ...
 $ Type of Dwelling: chr  "Total" "Total HDB^" "1- and 2-Room Flats*" "3-Room Flats" ...
 $ 2011            : chr  "-" "-" "-" "-" ...
 $ 2012            : chr  "-" "-" "-" "-" ...
 $ 2013            : chr  "-" "-" "-" "-" ...
 $ 2014            : chr  "-" "-" "-" "-" ...
 $ 2015            : chr  "-" "-" "-" "-" ...
 $ 2016            : chr  "-" "-" "-" "-" ...
 $ 2017            : chr  "-" "-" "-" "-" ...
 $ 2018            : chr  "-" "-" "-" "-" ...
 $ 2019            : chr  "-" "-" "-" "-" ...
punggol_PA$`2011`[punggol_PA$`2011` == "-" | is.na(punggol_PA$`2011`)] <- 0
punggol_PA$`2012`[punggol_PA$`2012` == "-" | is.na(punggol_PA$`2012`)] <- 0
punggol_PA$`2013`[punggol_PA$`2013` == "-" | is.na(punggol_PA$`2013`)] <- 0
punggol_PA$`2014`[punggol_PA$`2014` == "-" | is.na(punggol_PA$`2014`)] <- 0
punggol_PA$`2015`[punggol_PA$`2015` == "-" | is.na(punggol_PA$`2015`)] <- 0
punggol_PA$`2016`[punggol_PA$`2016` == "-" | is.na(punggol_PA$`2016`)] <- 0
punggol_PA$`2017`[punggol_PA$`2017` == "-" | is.na(punggol_PA$`2017`)] <- 0
punggol_PA$`2018`[punggol_PA$`2018` == "-" | is.na(punggol_PA$`2018`)] <- 0
punggol_PA$`2019`[punggol_PA$`2019` == "-" | is.na(punggol_PA$`2019`)] <- 0
punggol_PA[,5:13] <- punggol_PA[,5:13] %>% mutate_if(is.character, as.numeric)
punggol_PA <-punggol_PA[ , c(1, 2, 3,5:13)]
tail(punggol_PA,20)

Group By PA,SZ, AGE GROUP

punggol_PA_aggregated <- punggol_PA %>% 
  group_by(`Planning Area`, `Subzone`, `Age Group`) %>% 
  summarize_all(sum)

Classiying age groups based on age group classification

#age groups classification
economic_active <- c('25 - 29','30 - 34','35 - 39','40 - 44','45 - 49', '50 - 54', '55 - 59', '60 - 64')
younger <- c('0 - 4','10 - 14','15 - 19','20 - 24')
#age groups: Aged (0-24) economic active, younger group
punggol_PA_aggregated$`Economic Group` <- ifelse(punggol_PA_aggregated$`Age Group` %in% economic_active, 'Economic  Active', ifelse(punggol_PA_aggregated$`Age Group` %in% younger, 'Younger Group', 'Aged Group'))
                  
tail(punggol_PA_aggregated,20)
NA

Reselect fields and grouping

younger_age_group <-  punggol_PA_aggregated %>% filter(`Economic Group` == "Younger Group")
younger_age_group$colname <- paste(younger_age_group$Subzone,younger_age_group$`Age Group`)
younger_age_group <-younger_age_group[ , c(14,4:12)]
younger_age_group <- younger_age_group %>% 
  group_by(`colname`) %>% 
  summarize_all(sum)
reverse<-data.frame(t(younger_age_group))
colnames(reverse) <- unlist(reverse[row.names(reverse)=='colname',])
reverse$Year <- rownames(reverse)
reverse<-reverse[-1,]
rownames(reverse) <- NULL
reverse[,1:28] <- lapply(reverse, function(x) as.numeric(as.character(x)))
provided 29 variables to replace 28 variables
#Overall diagram
meltdf <- melt(reverse,id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

Matilda’s: Younger Age Group Analysis

meltdf <- melt(reverse[, c(5:8,29)],id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

Northshore’s: Younger Age Group Analysis

meltdf <- melt(reverse[, c(9:12,29)],id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

1 Punggol Field’s: Younger Age Group Analysis

meltdf <- melt(reverse[, c(17:20,29)],id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

2 Punggol Town Centre: Younger Age Group Analysis

meltdf <- melt(reverse[, c(21:24,29)],id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

3 Waterway East: Younger Age Group Analysis

meltdf <- melt(reverse[, c(25:28,29)],id="Year")
ggplot(meltdf,aes(x=Year,y=value,colour=variable,group=variable)) + geom_line()

punggol_PA_aggregated <-punggol_PA_aggregated[ , c(2,13,4:12)]
punggol_PA_aggregated <- punggol_PA_aggregated %>% 
  group_by(`Subzone`, `Economic Group`) %>% 
  summarize_all(sum)
reverse<-data.frame(t(punggol_PA_aggregated))
reverse
#Conney
conney_grp<-reverse[1:3]
conney_grp<-conney_grp[-1,]
colnames(conney_grp) <- unlist(conney_grp[row.names(conney_grp)=='Economic Group',])
conney_grp$Year <- rownames(conney_grp)
conney_grp<-conney_grp[-1,]
rownames(conney_grp) <- NULL
conney_grp$`Aged Group`<-as.numeric(levels(conney_grp$`Aged Group`)[conney_grp$`Aged Group`])
conney_grp$`Economic  Active`<-as.numeric(levels(conney_grp$`Economic  Active`)[conney_grp$`Economic  Active`])
conney_grp$`Younger Group`<-as.numeric(levels(conney_grp$`Younger Group`)[conney_grp$`Younger Group`])
#Matilda
matilda_grp<-reverse[4:6]
matilda_grp<-matilda_grp[-1,]
colnames(matilda_grp) <- unlist(matilda_grp[row.names(matilda_grp)=='Economic Group',])
matilda_grp$Year <- rownames(matilda_grp)
matilda_grp<-matilda_grp[-1,]
rownames(matilda_grp) <- NULL
matilda_grp$`Aged Group`<-as.numeric(levels(matilda_grp$`Aged Group`)[matilda_grp$`Aged Group`])
matilda_grp$`Economic  Active`<-as.numeric(levels(matilda_grp$`Economic  Active`)[matilda_grp$`Economic  Active`])
matilda_grp$`Younger Group`<-as.numeric(levels(matilda_grp$`Younger Group`)[matilda_grp$`Younger Group`])
#Northshore
northsore_group<-reverse[7:9]
northsore_group<-northsore_group[-1,]
colnames(northsore_group) <- unlist(northsore_group[row.names(northsore_group)=='Economic Group',])
northsore_group$Year <- rownames(northsore_group)
northsore_group<-northsore_group[-1,]
rownames(northsore_group) <- NULL
northsore_group$`Aged Group`<-as.numeric(levels(northsore_group$`Aged Group`)[northsore_group$`Aged Group`])
northsore_group$`Economic  Active`<-as.numeric(levels(northsore_group$`Economic  Active`)[northsore_group$`Economic  Active`])
northsore_group$`Younger Group`<-as.numeric(levels(northsore_group$`Younger Group`)[northsore_group$`Younger Group`])
#Punggol Canal
punggol_canal_group<-reverse[10:12]
punggol_canal_group<-punggol_canal_group[-1,]
colnames(punggol_canal_group) <- unlist(punggol_canal_group[row.names(punggol_canal_group)=='Economic Group',])
punggol_canal_group$Year <- rownames(punggol_canal_group)
punggol_canal_group<-punggol_canal_group[-1,]
rownames(punggol_canal_group) <- NULL
punggol_canal_group$`Aged Group`<-as.numeric(levels(punggol_canal_group$`Aged Group`)[punggol_canal_group$`Aged Group`])
punggol_canal_group$`Economic  Active`<-as.numeric(levels(punggol_canal_group$`Economic  Active`)[punggol_canal_group$`Economic  Active`])
punggol_canal_group$`Younger Group`<-as.numeric(levels(punggol_canal_group$`Younger Group`)[punggol_canal_group$`Younger Group`])
#Punggol Field
punggol_field_group <-reverse[13:15]
punggol_field_group<-punggol_field_group[-1,]
colnames(punggol_field_group) <- unlist(punggol_field_group[row.names(punggol_field_group)=='Economic Group',])
punggol_field_group$Year <- rownames(punggol_field_group)
punggol_field_group<-punggol_field_group[-1,]
rownames(punggol_field_group) <- NULL
punggol_field_group$`Aged Group`<-as.numeric(levels(punggol_field_group$`Aged Group`)[punggol_field_group$`Aged Group`])
punggol_field_group$`Economic  Active`<-as.numeric(levels(punggol_field_group$`Economic  Active`)[punggol_field_group$`Economic  Active`])
punggol_field_group$`Younger Group`<-as.numeric(levels(punggol_field_group$`Younger Group`)[punggol_field_group$`Younger Group`])
#Punggol Town Centre
punggol_tc_group <-reverse[16:18]
punggol_tc_group<-punggol_tc_group[-1,]
colnames(punggol_tc_group) <- unlist(punggol_tc_group[row.names(punggol_tc_group)=='Economic Group',])
punggol_tc_group$Year <- rownames(punggol_tc_group)
punggol_tc_group<-punggol_tc_group[-1,]
rownames(punggol_tc_group) <- NULL
punggol_tc_group$`Aged Group`<-as.numeric(levels(punggol_tc_group$`Aged Group`)[punggol_tc_group$`Aged Group`])
punggol_tc_group$`Economic  Active`<-as.numeric(levels(punggol_tc_group$`Economic  Active`)[punggol_tc_group$`Economic  Active`])
punggol_tc_group$`Younger Group`<-as.numeric(levels(punggol_tc_group$`Younger Group`)[punggol_tc_group$`Younger Group`])
#Waterway East
waterway_east_group <-reverse[19:21]
waterway_east_group<-waterway_east_group[-1,]
colnames(waterway_east_group) <- unlist(waterway_east_group[row.names(waterway_east_group)=='Economic Group',])
waterway_east_group$Year <- rownames(waterway_east_group)
waterway_east_group<-waterway_east_group[-1,]
rownames(waterway_east_group) <- NULL
waterway_east_group$`Aged Group`<-as.numeric(levels(waterway_east_group$`Aged Group`)[waterway_east_group$`Aged Group`])
waterway_east_group$`Economic  Active`<-as.numeric(levels(waterway_east_group$`Economic  Active`)[waterway_east_group$`Economic  Active`])
waterway_east_group$`Younger Group`<-as.numeric(levels(waterway_east_group$`Younger Group`)[waterway_east_group$`Younger Group`])

Matilda’s Current Population

ggplot(matilda_grp, aes(x=matilda_grp$Year)) + 
  geom_line(aes( y=matilda_grp$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=matilda_grp$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=matilda_grp$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Matilda's Current Population",
        x ="Year", y = "Total Population")

Northshore’s Current Population

ggplot(northsore_group, aes(x=northsore_group$Year)) + 
  geom_line(aes( y=northsore_group$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=northsore_group$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=northsore_group$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Northshore's Current Population",
        x ="Year", y = "Total Population")

Punggol Canal’s Current Population

ggplot(punggol_canal_group, aes(x=punggol_canal_group$Year)) + 
  geom_line(aes( y=punggol_canal_group$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=punggol_canal_group$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=punggol_canal_group$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Punggol Canal's Current Population",
        x ="Year", y = "Total Population")

Punggol Field’s Current Population

ggplot(punggol_field_group, aes(x=punggol_field_group$Year)) + 
  geom_line(aes( y=punggol_field_group$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=punggol_field_group$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=punggol_field_group$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Punggol Field's Current Population",
        x ="Year", y = "Total Population")

Punggol Town Centre’s Current Population

ggplot(punggol_tc_group, aes(x=punggol_tc_group$Year)) + 
  geom_line(aes( y=punggol_tc_group$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=punggol_tc_group$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=punggol_tc_group$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Punggol Town Centre's Current Population",
        x ="Year", y = "Total Population")

Waterway East’s Current Population

ggplot(waterway_east_group, aes(x=waterway_east_group$Year)) + 
  geom_line(aes( y=waterway_east_group$`Younger Group`, color="steelblue",group=1))+
    geom_line(aes( y=waterway_east_group$`Economic  Active`, color="green",group=1))+
  geom_line(aes(y=waterway_east_group$`Aged Group`, color = "darkred", group=1)) + 
      scale_color_discrete(name = "Population Group", labels = c("Younger Group (Below 25)","Economic Active (25-64)",  "Aged Group (Above 64)"))+
  labs(title="Waterway East's Current Population",
        x ="Year", y = "Total Population")

5 Forecasting Matilda’s Population

https://stackoverflow.com/questions/47852567/arima-forecast-keep-getting-error-data-must-be-of-a-vector-type-was-null https://stackoverflow.com/questions/53099289/error-in-array-data-must-be-of-a-vector-type-was-null-in-r

Developing a ARIMA Model to Matilda’s Population Forecast Preassumption that the data is stationary, which means trends and seasonality has been removed due to a consistent demand.

#predict aged group
matilda_grp$`Aged Group`
[1]  2680  3850  5890  9000 11430 14450 17320 20760 23130
matilda_forecast_AG <- ts(matilda_grp$`Aged Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(matilda_forecast_AG)

matilda_ARIMAfit_AG <- auto.arima(matilda_forecast_AG)
pred_AG <- forecast(matilda_ARIMAfit_AG, h = 5)
plot(pred_AG)

pred_AG_df <- data.frame(pred_AG)
#predict economic active
matilda_grp$`Economic  Active`
[1] 12560 21230 34360 48880 56200 65590 71980 81070 86090
matilda_forecast_EA <- ts(matilda_grp$`Economic  Active`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(matilda_forecast_EA)

matilda_ARIMAfit_EA <- auto.arima(matilda_forecast_EA)
pred_EA <- forecast(matilda_ARIMAfit_EA, h = 5)
plot(pred_EA)

pred_EA_df <- data.frame(pred_EA)

5.1 Matilda’s Forecast Data Table

#predict younger gen
matilda_grp$`Younger Group`
[1]  4730  7690 12320 18150 21760 26570 29670 32780 34310
matilda_forecast_YG <- ts(matilda_grp$`Younger Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(matilda_forecast_YG)

matilda_ARIMAfit_YG <- auto.arima(matilda_forecast_YG)
pred_YG <- forecast(matilda_ARIMAfit_YG, h = 5)
plot(pred_YG)

pred_YG_df <- data.frame(pred_YG)
#add ARIMA prediction to current 
matilda_grp[nrow(matilda_grp) + 1,] <-  c(pred_AG_df[1,]$Point.Forecast, pred_EA_df[1,]$Point.Forecast, pred_YG_df[1,]$Point.Forecast, 2020)
matilda_grp[nrow(matilda_grp) + 1,] <-  c(pred_AG_df[2,]$Point.Forecast, pred_EA_df[2,]$Point.Forecast, pred_YG_df[2,]$Point.Forecast, 2021)
matilda_grp[nrow(matilda_grp) + 1,] <-  c(pred_AG_df[3,]$Point.Forecast, pred_EA_df[3,]$Point.Forecast, pred_YG_df[3,]$Point.Forecast, 2022)
matilda_grp[nrow(matilda_grp) + 1,] <-  c(pred_AG_df[4,]$Point.Forecast, pred_EA_df[4,]$Point.Forecast, pred_YG_df[4,]$Point.Forecast, 2023)
matilda_grp[nrow(matilda_grp) + 1,] <-  c(pred_AG_df[5,]$Point.Forecast, pred_EA_df[5,]$Point.Forecast, pred_YG_df[5,]$Point.Forecast, 2024)
matilda_grp

6 Forecasting Northsore’s Population

An ARIMA(0,0,0) model with zero mean is white noise, means that the errors are uncorrelated across time.

#predict aged group
northsore_group$`Aged Group`
[1] 100 100 120 120 120 120 100  80 120
northsore_forecast_AG <- ts(northsore_group$`Aged Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(northsore_forecast_AG)

northsore_ARIMAfit_AG <- auto.arima(northsore_forecast_AG)
pred_AG <- forecast(northsore_ARIMAfit_AG, h = 5)
plot(pred_AG)

pred_AG_df <- data.frame(pred_AG)
#predict economic active
northsore_group$`Economic  Active`
[1] 320 300 360 330 360 340 340 300 340
northsore_forecast_EA <- ts(northsore_group$`Economic  Active`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(northsore_forecast_EA)

northsore_ARIMAfit_EA <- auto.arima(northsore_forecast_EA)
pred_EA <- forecast(northsore_ARIMAfit_EA, h = 5)
plot(pred_EA)

pred_EA_df <- data.frame(pred_EA)
#predict younger gen
northsore_group$`Younger Group`
[1] 120 140 140 140 160 180 160 140 140
northsore_forecast_YG <- ts(northsore_group$`Younger Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(northsore_forecast_YG)

northsore_ARIMAfit_YG <- auto.arima(northsore_forecast_YG)
pred_YG <- forecast(northsore_ARIMAfit_YG, h = 5)
plot(pred_YG)

pred_YG_df <- data.frame(pred_YG)

6.1 Northsore’s Forecast Data Table

northsore_group[nrow(northsore_group) + 1,] <-  c(pred_AG_df[1,]$Point.Forecast, pred_EA_df[1,]$Point.Forecast, pred_YG_df[1,]$Point.Forecast, 2020)
northsore_group[nrow(northsore_group) + 1,] <-  c(pred_AG_df[2,]$Point.Forecast, pred_EA_df[2,]$Point.Forecast, pred_YG_df[2,]$Point.Forecast, 2021)
northsore_group[nrow(northsore_group) + 1,] <-  c(pred_AG_df[3,]$Point.Forecast, pred_EA_df[3,]$Point.Forecast, pred_YG_df[3,]$Point.Forecast, 2022)
northsore_group[nrow(northsore_group) + 1,] <-  c(pred_AG_df[4,]$Point.Forecast, pred_EA_df[4,]$Point.Forecast, pred_YG_df[4,]$Point.Forecast, 2023)
northsore_group[nrow(northsore_group) + 1,] <-  c(pred_AG_df[5,]$Point.Forecast, pred_EA_df[5,]$Point.Forecast, pred_YG_df[5,]$Point.Forecast, 2024)
northsore_group

7 Forecasting Punggol Field’s Population

#predict aged group
punggol_field_group$`Aged Group`
[1] 18200 19080 20340 20930 20970 21550 22710 22540 22990
pf_forecast_AG <- ts(punggol_field_group$`Aged Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(pf_forecast_AG)

pf_ARIMAfit_AG <- auto.arima(pf_forecast_AG)
pred_AG <- forecast(pf_ARIMAfit_AG, h = 5)
plot(pred_AG)

pred_AG_df <- data.frame(pred_AG)
#predict economic active
punggol_field_group$`Economic  Active`
[1] 77910 77670 79190 78800 77340 79070 82710 81940 82080
pf_forecast_EA <- ts(punggol_field_group$`Economic  Active`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(pf_forecast_EA)

pf_ARIMAfit_EA <- auto.arima(pf_forecast_EA)
pred_EA <- forecast(pf_ARIMAfit_EA, h = 5)
plot(pred_EA)

pred_EA_df <- data.frame(pred_EA)
#predict younger gen
punggol_field_group$`Younger Group`
[1] 31950 31790 31950 31600 31400 32620 35050 35400 35710
pf_forecast_YG <- ts(punggol_field_group$`Younger Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(pf_forecast_YG)

pf_ARIMAfit_YG <- auto.arima(pf_forecast_YG)
pred_YG <- forecast(pf_ARIMAfit_YG, h = 5)
plot(pred_YG)

pred_YG_df <- data.frame(pred_YG)

7.1 Punggol Field’s Forecast Data Table

punggol_field_group[nrow(punggol_field_group) + 1,] <-  c(pred_AG_df[1,]$Point.Forecast, pred_EA_df[1,]$Point.Forecast, pred_YG_df[1,]$Point.Forecast, 2020)
punggol_field_group[nrow(punggol_field_group) + 1,] <-  c(pred_AG_df[2,]$Point.Forecast, pred_EA_df[2,]$Point.Forecast, pred_YG_df[2,]$Point.Forecast, 2021)
punggol_field_group[nrow(punggol_field_group) + 1,] <-  c(pred_AG_df[3,]$Point.Forecast, pred_EA_df[3,]$Point.Forecast, pred_YG_df[3,]$Point.Forecast, 2022)
punggol_field_group[nrow(punggol_field_group) + 1,] <-  c(pred_AG_df[4,]$Point.Forecast, pred_EA_df[4,]$Point.Forecast, pred_YG_df[4,]$Point.Forecast, 2023)
punggol_field_group[nrow(punggol_field_group) + 1,] <-  c(pred_AG_df[5,]$Point.Forecast, pred_EA_df[5,]$Point.Forecast, pred_YG_df[5,]$Point.Forecast, 2024)
punggol_field_group

8 Forecasting Punggol Town Centre’s Population

#predict aged group
punggol_tc_group$`Aged Group`
[1]  850 1170 1490 1890 2770 4430 5780 7470 9140
tc_forecast_AG <- ts(punggol_tc_group$`Aged Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(tc_forecast_AG)

tc_ARIMAfit_AG <- auto.arima(tc_forecast_AG)
pred_AG <- forecast(tc_ARIMAfit_AG, h = 5)
plot(pred_AG)

pred_AG_df <- data.frame(pred_AG)
#predict economic active
punggol_tc_group$`Economic  Active`
[1]  6750  8320  8770  9380 14100 21990 27390 31840 37340
tc_forecast_EA <- ts(punggol_tc_group$`Economic  Active`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(tc_forecast_EA)

tc_ARIMAfit_EA <- auto.arima(tc_forecast_EA)
pred_EA <- forecast(tc_ARIMAfit_EA, h = 5)
plot(pred_EA)

pred_EA_df <- data.frame(pred_EA)
#predict younger gen
punggol_tc_group$`Younger Group`
[1]  2290  3020  3450  3700  5340  8500 10560 12450 14980
tc_forecast_YG <- ts(punggol_tc_group$`Younger Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
plot(tc_forecast_YG)

tc_ARIMAfit_YG <- auto.arima(tc_forecast_YG)
pred_YG <- forecast(tc_ARIMAfit_YG, h = 5)
plot(pred_YG)

pred_YG_df <- data.frame(pred_YG)

8.1 Punggol Town Centre’s Forecast Data Table

punggol_tc_group[nrow(punggol_tc_group) + 1,] <-  c(pred_AG_df[1,]$Point.Forecast, pred_EA_df[1,]$Point.Forecast, pred_YG_df[1,]$Point.Forecast, 2020)
punggol_tc_group[nrow(punggol_tc_group) + 1,] <-  c(pred_AG_df[2,]$Point.Forecast, pred_EA_df[2,]$Point.Forecast, pred_YG_df[2,]$Point.Forecast, 2021)
punggol_tc_group[nrow(punggol_tc_group) + 1,] <-  c(pred_AG_df[3,]$Point.Forecast, pred_EA_df[3,]$Point.Forecast, pred_YG_df[3,]$Point.Forecast, 2022)
punggol_tc_group[nrow(punggol_tc_group) + 1,] <-  c(pred_AG_df[4,]$Point.Forecast, pred_EA_df[4,]$Point.Forecast, pred_YG_df[4,]$Point.Forecast, 2023)
punggol_tc_group[nrow(punggol_tc_group) + 1,] <-  c(pred_AG_df[5,]$Point.Forecast, pred_EA_df[5,]$Point.Forecast, pred_YG_df[5,]$Point.Forecast, 2024)
punggol_tc_group

9 Forecasting Waterway East’s Population

#predict aged group
we_forecast_AG <- ts(waterway_east_group$`Aged Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
we_ARIMAfit_AG <- auto.arima(we_forecast_AG)
pred_AG <- forecast(we_ARIMAfit_AG, h = 5)
plot(pred_AG)

pred_AG_df <- data.frame(pred_AG)
#predict economic active
waterway_east_group$`Economic  Active`
[1] 22130 31840 41830 43790 51280 65140 72910 82700 85560
we_forecast_EA <- ts(waterway_east_group$`Economic  Active`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
we_ARIMAfit_EA <- auto.arima(we_forecast_EA)
pred_EA <- forecast(we_ARIMAfit_EA, h = 5)
plot(pred_EA)

pred_EA_df <- data.frame(pred_EA)
#predict younger gen
waterway_east_group$`Younger Group`
[1]  8320 11580 15240 16340 20200 25720 29450 33950 35310
we_forecast_YG <- ts(waterway_east_group$`Younger Group`,start = c(2011,1),  end=c(2019, 1),frequency = 1)
we_ARIMAfit_YG <- auto.arima(we_forecast_YG)
pred_YG <- forecast(we_ARIMAfit_YG, h = 5)
plot(pred_YG)

pred_YG_df <- data.frame(pred_YG)
waterway_east_group[nrow(waterway_east_group) + 1,] <-  c(pred_AG_df[1,]$Point.Forecast, pred_EA_df[1,]$Point.Forecast, pred_YG_df[1,]$Point.Forecast, 2020)
waterway_east_group[nrow(waterway_east_group) + 1,] <-  c(pred_AG_df[2,]$Point.Forecast, pred_EA_df[2,]$Point.Forecast, pred_YG_df[2,]$Point.Forecast, 2021)
waterway_east_group[nrow(waterway_east_group) + 1,] <-  c(pred_AG_df[3,]$Point.Forecast, pred_EA_df[3,]$Point.Forecast, pred_YG_df[3,]$Point.Forecast, 2022)
waterway_east_group[nrow(waterway_east_group) + 1,] <-  c(pred_AG_df[4,]$Point.Forecast, pred_EA_df[4,]$Point.Forecast, pred_YG_df[4,]$Point.Forecast, 2023)
waterway_east_group[nrow(waterway_east_group) + 1,] <-  c(pred_AG_df[5,]$Point.Forecast, pred_EA_df[5,]$Point.Forecast, pred_YG_df[5,]$Point.Forecast, 2024)
waterway_east_group
waterway_east_group

9.1 Assumption: Areas like Conney Island & Punggol Canal will be treated as an empty region.

punggol_canal_group[nrow(punggol_canal_group) + 1,] <-  c(0,0,0, 2020)
punggol_canal_group[nrow(punggol_canal_group) + 1,] <-  c(0,0,0, 2021)
punggol_canal_group[nrow(punggol_canal_group) + 1,] <-  c(0,0,0, 2022)
punggol_canal_group[nrow(punggol_canal_group) + 1,] <-  c(0,0,0, 2023)
punggol_canal_group[nrow(punggol_canal_group) + 1,] <-  c(0,0,0, 2024)
conney_grp[nrow(conney_grp) + 1,] <-  c(0,0,0, 2020)
conney_grp[nrow(conney_grp) + 1,] <-  c(0,0,0, 2021)
conney_grp[nrow(conney_grp) + 1,] <-  c(0,0,0, 2022)
conney_grp[nrow(conney_grp) + 1,] <-  c(0,0,0, 2023)
conney_grp[nrow(conney_grp) + 1,] <-  c(0,0,0, 2024)

10 Merging dataframes and adding back subzone values for data aggregation to be done on QGIS

conney_grp$Subzone <- "Coney Island"
punggol_canal_group$Subzone <- "Punggol Canal"
matilda_grp$Subzone <- "Matilda"
punggol_field_group$Subzone <-"Punggol Field"
waterway_east_group$Subzone <- "Waterway East"
punggol_tc_group$Subzone <- "Punggol Town Centre"
northsore_group$Subzone <-  "Northshore"
combined_forecast <- rbind(punggol_tc_group, waterway_east_group,punggol_field_group,matilda_grp,punggol_canal_group,conney_grp, northsore_group)
combined_forecast

11 Write data to CSV

write.csv(combined_forecast,'punggol_pop_predicted.csv')
LS0tCnRpdGxlOiAnUHVuZ2dvbCBGb3JlY2FzdCBQb3B1bGF0aW9uIEFuYWx5c2lzJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uOiB5ZXMKICAgIHRoZW1lOiBmbGF0bHkKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB5ZXMKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwotLS0KCkltcG9ydCBMaWJyYXJ5CmBgYHtyIHNldHVwLCBpbmNsdWRlPVRSVUUsIGV2YWw9VFJVRSxtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKCmBgYHtyfQpwYWNrYWdlcyA9IGMoJ2RwbHlyJywnZm9yZWNhc3QnLCdnZ3Bsb3QyJywncmVzaGFwZTInLCdyZWFkeGwnKQpmb3IgKHAgaW4gcGFja2FnZXMpewogIGlmKCFyZXF1aXJlKHAsIGNoYXJhY3Rlci5vbmx5ID0gVCkpewogICAgaW5zdGFsbC5wYWNrYWdlcyhwKSAKICB9IAogIGxpYnJhcnkocCxjaGFyYWN0ZXIub25seSA9IFQpIAp9CmBgYAoKR2xpbXBzZSBvZiBEYXRhCmBgYHtyfQpkZiA8LSByZWFkX2V4Y2VsKCAiLi9TaW5nYXBvcmVfUmVzaWRlbnRzX2J5X1BsYW5uaW5nLnhsc3giKQpoZWFkKGRmKQpgYGAKCkZpbHRlciBvbmx5IFB1bmdnb2wgUEEgJiBDbGVhbiBEYXRhCmBgYHtyfQpwdW5nZ29sX1BBIDwtIGRmICU+JQogIGZpbHRlcihgUGxhbm5pbmcgQXJlYWAgPT0gIlB1bmdnb2wiKSAlPiUKICBmaWx0ZXIoYFN1YnpvbmVgICE9ICJUb3RhbCIpICAlPiUKICAgZmlsdGVyKGBBZ2UgR3JvdXBgICE9ICJUb3RhbCIpIApzdHIocHVuZ2dvbF9QQSkKCnB1bmdnb2xfUEEkYDIwMTFgW3B1bmdnb2xfUEEkYDIwMTFgID09ICItIiB8IGlzLm5hKHB1bmdnb2xfUEEkYDIwMTFgKV0gPC0gMApwdW5nZ29sX1BBJGAyMDEyYFtwdW5nZ29sX1BBJGAyMDEyYCA9PSAiLSIgfCBpcy5uYShwdW5nZ29sX1BBJGAyMDEyYCldIDwtIDAKcHVuZ2dvbF9QQSRgMjAxM2BbcHVuZ2dvbF9QQSRgMjAxM2AgPT0gIi0iIHwgaXMubmEocHVuZ2dvbF9QQSRgMjAxM2ApXSA8LSAwCnB1bmdnb2xfUEEkYDIwMTRgW3B1bmdnb2xfUEEkYDIwMTRgID09ICItIiB8IGlzLm5hKHB1bmdnb2xfUEEkYDIwMTRgKV0gPC0gMApwdW5nZ29sX1BBJGAyMDE1YFtwdW5nZ29sX1BBJGAyMDE1YCA9PSAiLSIgfCBpcy5uYShwdW5nZ29sX1BBJGAyMDE1YCldIDwtIDAKcHVuZ2dvbF9QQSRgMjAxNmBbcHVuZ2dvbF9QQSRgMjAxNmAgPT0gIi0iIHwgaXMubmEocHVuZ2dvbF9QQSRgMjAxNmApXSA8LSAwCnB1bmdnb2xfUEEkYDIwMTdgW3B1bmdnb2xfUEEkYDIwMTdgID09ICItIiB8IGlzLm5hKHB1bmdnb2xfUEEkYDIwMTdgKV0gPC0gMApwdW5nZ29sX1BBJGAyMDE4YFtwdW5nZ29sX1BBJGAyMDE4YCA9PSAiLSIgfCBpcy5uYShwdW5nZ29sX1BBJGAyMDE4YCldIDwtIDAKcHVuZ2dvbF9QQSRgMjAxOWBbcHVuZ2dvbF9QQSRgMjAxOWAgPT0gIi0iIHwgaXMubmEocHVuZ2dvbF9QQSRgMjAxOWApXSA8LSAwCgoKCnB1bmdnb2xfUEFbLDU6MTNdIDwtIHB1bmdnb2xfUEFbLDU6MTNdICU+JSBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5udW1lcmljKQoKcHVuZ2dvbF9QQSA8LXB1bmdnb2xfUEFbICwgYygxLCAyLCAzLDU6MTMpXQp0YWlsKHB1bmdnb2xfUEEsMjApCmBgYAoKCkdyb3VwIEJ5IFBBLFNaLCBBR0UgR1JPVVAKYGBge3J9CnB1bmdnb2xfUEFfYWdncmVnYXRlZCA8LSBwdW5nZ29sX1BBICU+JSAKICBncm91cF9ieShgUGxhbm5pbmcgQXJlYWAsIGBTdWJ6b25lYCwgYEFnZSBHcm91cGApICU+JSAKICBzdW1tYXJpemVfYWxsKHN1bSkKYGBgCgpDbGFzc2l5aW5nIGFnZSBncm91cHMgYmFzZWQgb24gYWdlIGdyb3VwIGNsYXNzaWZpY2F0aW9uCmBgYHtyfQojYWdlIGdyb3VwcyBjbGFzc2lmaWNhdGlvbgplY29ub21pY19hY3RpdmUgPC0gYygnMjUgLSAyOScsJzMwIC0gMzQnLCczNSAtIDM5JywnNDAgLSA0NCcsJzQ1IC0gNDknLCAnNTAgLSA1NCcsICc1NSAtIDU5JywgJzYwIC0gNjQnKQp5b3VuZ2VyIDwtIGMoJzAgLSA0JywnMTAgLSAxNCcsJzE1IC0gMTknLCcyMCAtIDI0JykKCiNhZ2UgZ3JvdXBzOiBBZ2VkICgwLTI0KSBlY29ub21pYyBhY3RpdmUsIHlvdW5nZXIgZ3JvdXAKcHVuZ2dvbF9QQV9hZ2dyZWdhdGVkJGBFY29ub21pYyBHcm91cGAgPC0gaWZlbHNlKHB1bmdnb2xfUEFfYWdncmVnYXRlZCRgQWdlIEdyb3VwYCAlaW4lIGVjb25vbWljX2FjdGl2ZSwgJ0Vjb25vbWljICBBY3RpdmUnLCBpZmVsc2UocHVuZ2dvbF9QQV9hZ2dyZWdhdGVkJGBBZ2UgR3JvdXBgICVpbiUgeW91bmdlciwgJ1lvdW5nZXIgR3JvdXAnLCAnQWdlZCBHcm91cCcpKQogICAgICAgICAgICAgICAgICAKdGFpbChwdW5nZ29sX1BBX2FnZ3JlZ2F0ZWQsMjApCiAgICAgCgpgYGAKClJlc2VsZWN0IGZpZWxkcyBhbmQgZ3JvdXBpbmcKYGBge3J9CnlvdW5nZXJfYWdlX2dyb3VwIDwtICBwdW5nZ29sX1BBX2FnZ3JlZ2F0ZWQgJT4lIGZpbHRlcihgRWNvbm9taWMgR3JvdXBgID09ICJZb3VuZ2VyIEdyb3VwIikKeW91bmdlcl9hZ2VfZ3JvdXAkY29sbmFtZSA8LSBwYXN0ZSh5b3VuZ2VyX2FnZV9ncm91cCRTdWJ6b25lLHlvdW5nZXJfYWdlX2dyb3VwJGBBZ2UgR3JvdXBgKQp5b3VuZ2VyX2FnZV9ncm91cCA8LXlvdW5nZXJfYWdlX2dyb3VwWyAsIGMoMTQsNDoxMildCnlvdW5nZXJfYWdlX2dyb3VwIDwtIHlvdW5nZXJfYWdlX2dyb3VwICU+JSAKICBncm91cF9ieShgY29sbmFtZWApICU+JSAKICBzdW1tYXJpemVfYWxsKHN1bSkKCgpyZXZlcnNlPC1kYXRhLmZyYW1lKHQoeW91bmdlcl9hZ2VfZ3JvdXApKQpjb2xuYW1lcyhyZXZlcnNlKSA8LSB1bmxpc3QocmV2ZXJzZVtyb3cubmFtZXMocmV2ZXJzZSk9PSdjb2xuYW1lJyxdKQpyZXZlcnNlJFllYXIgPC0gcm93bmFtZXMocmV2ZXJzZSkKcmV2ZXJzZTwtcmV2ZXJzZVstMSxdCnJvd25hbWVzKHJldmVyc2UpIDwtIE5VTEwKcmV2ZXJzZVssMToyOF0gPC0gbGFwcGx5KHJldmVyc2UsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgpKSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KcHJpbnQocmV2ZXJzZSwgcmlnaHQ9RkFMU0UpCmBgYAoKYGBge3J9CiNPdmVyYWxsIGRpYWdyYW0KbWVsdGRmIDwtIG1lbHQocmV2ZXJzZSxpZD0iWWVhciIpCmdncGxvdChtZWx0ZGYsYWVzKHg9WWVhcix5PXZhbHVlLGNvbG91cj12YXJpYWJsZSxncm91cD12YXJpYWJsZSkpICsgZ2VvbV9saW5lKCkKYGBgCk1hdGlsZGEnczogWW91bmdlciBBZ2UgR3JvdXAgQW5hbHlzaXMKYGBge3J9CgptZWx0ZGYgPC0gbWVsdChyZXZlcnNlWywgYyg1OjgsMjkpXSxpZD0iWWVhciIpCmdncGxvdChtZWx0ZGYsYWVzKHg9WWVhcix5PXZhbHVlLGNvbG91cj12YXJpYWJsZSxncm91cD12YXJpYWJsZSkpICsgZ2VvbV9saW5lKCkKYGBgCgpOb3J0aHNob3JlJ3M6IFlvdW5nZXIgQWdlIEdyb3VwIEFuYWx5c2lzCmBgYHtyfQptZWx0ZGYgPC0gbWVsdChyZXZlcnNlWywgYyg5OjEyLDI5KV0saWQ9IlllYXIiKQpnZ3Bsb3QobWVsdGRmLGFlcyh4PVllYXIseT12YWx1ZSxjb2xvdXI9dmFyaWFibGUsZ3JvdXA9dmFyaWFibGUpKSArIGdlb21fbGluZSgpCmBgYAoKI1B1bmdnb2wgRmllbGQnczogWW91bmdlciBBZ2UgR3JvdXAgQW5hbHlzaXMKYGBge3J9Cm1lbHRkZiA8LSBtZWx0KHJldmVyc2VbLCBjKDE3OjIwLDI5KV0saWQ9IlllYXIiKQpnZ3Bsb3QobWVsdGRmLGFlcyh4PVllYXIseT12YWx1ZSxjb2xvdXI9dmFyaWFibGUsZ3JvdXA9dmFyaWFibGUpKSArIGdlb21fbGluZSgpCmBgYAoKI1B1bmdnb2wgVG93biBDZW50cmU6IFlvdW5nZXIgQWdlIEdyb3VwIEFuYWx5c2lzCmBgYHtyfQptZWx0ZGYgPC0gbWVsdChyZXZlcnNlWywgYygyMToyNCwyOSldLGlkPSJZZWFyIikKZ2dwbG90KG1lbHRkZixhZXMoeD1ZZWFyLHk9dmFsdWUsY29sb3VyPXZhcmlhYmxlLGdyb3VwPXZhcmlhYmxlKSkgKyBnZW9tX2xpbmUoKQpgYGAKCiNXYXRlcndheSBFYXN0OiBZb3VuZ2VyIEFnZSBHcm91cCBBbmFseXNpcwpgYGB7cn0KbWVsdGRmIDwtIG1lbHQocmV2ZXJzZVssIGMoMjU6MjgsMjkpXSxpZD0iWWVhciIpCmdncGxvdChtZWx0ZGYsYWVzKHg9WWVhcix5PXZhbHVlLGNvbG91cj12YXJpYWJsZSxncm91cD12YXJpYWJsZSkpICsgZ2VvbV9saW5lKCkKYGBgCgoKCmBgYHtyfQpwdW5nZ29sX1BBX2FnZ3JlZ2F0ZWQgPC1wdW5nZ29sX1BBX2FnZ3JlZ2F0ZWRbICwgYygyLDEzLDQ6MTIpXQpwdW5nZ29sX1BBX2FnZ3JlZ2F0ZWQgPC0gcHVuZ2dvbF9QQV9hZ2dyZWdhdGVkICU+JSAKICBncm91cF9ieShgU3Viem9uZWAsIGBFY29ub21pYyBHcm91cGApICU+JSAKICBzdW1tYXJpemVfYWxsKHN1bSkKCmBgYAoKYGBge3J9CgpyZXZlcnNlPC1kYXRhLmZyYW1lKHQocHVuZ2dvbF9QQV9hZ2dyZWdhdGVkKSkKcmV2ZXJzZQoKI0Nvbm5leQpjb25uZXlfZ3JwPC1yZXZlcnNlWzE6M10KY29ubmV5X2dycDwtY29ubmV5X2dycFstMSxdCmNvbG5hbWVzKGNvbm5leV9ncnApIDwtIHVubGlzdChjb25uZXlfZ3JwW3Jvdy5uYW1lcyhjb25uZXlfZ3JwKT09J0Vjb25vbWljIEdyb3VwJyxdKQpjb25uZXlfZ3JwJFllYXIgPC0gcm93bmFtZXMoY29ubmV5X2dycCkKY29ubmV5X2dycDwtY29ubmV5X2dycFstMSxdCnJvd25hbWVzKGNvbm5leV9ncnApIDwtIE5VTEwKCmNvbm5leV9ncnAkYEFnZWQgR3JvdXBgPC1hcy5udW1lcmljKGxldmVscyhjb25uZXlfZ3JwJGBBZ2VkIEdyb3VwYClbY29ubmV5X2dycCRgQWdlZCBHcm91cGBdKQpjb25uZXlfZ3JwJGBFY29ub21pYyAgQWN0aXZlYDwtYXMubnVtZXJpYyhsZXZlbHMoY29ubmV5X2dycCRgRWNvbm9taWMgIEFjdGl2ZWApW2Nvbm5leV9ncnAkYEVjb25vbWljICBBY3RpdmVgXSkKY29ubmV5X2dycCRgWW91bmdlciBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKGNvbm5leV9ncnAkYFlvdW5nZXIgR3JvdXBgKVtjb25uZXlfZ3JwJGBZb3VuZ2VyIEdyb3VwYF0pCmBgYAoKCgpgYGB7cn0KI01hdGlsZGEKbWF0aWxkYV9ncnA8LXJldmVyc2VbNDo2XQptYXRpbGRhX2dycDwtbWF0aWxkYV9ncnBbLTEsXQoKY29sbmFtZXMobWF0aWxkYV9ncnApIDwtIHVubGlzdChtYXRpbGRhX2dycFtyb3cubmFtZXMobWF0aWxkYV9ncnApPT0nRWNvbm9taWMgR3JvdXAnLF0pCm1hdGlsZGFfZ3JwJFllYXIgPC0gcm93bmFtZXMobWF0aWxkYV9ncnApCm1hdGlsZGFfZ3JwPC1tYXRpbGRhX2dycFstMSxdCnJvd25hbWVzKG1hdGlsZGFfZ3JwKSA8LSBOVUxMCgptYXRpbGRhX2dycCRgQWdlZCBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKG1hdGlsZGFfZ3JwJGBBZ2VkIEdyb3VwYClbbWF0aWxkYV9ncnAkYEFnZWQgR3JvdXBgXSkKbWF0aWxkYV9ncnAkYEVjb25vbWljICBBY3RpdmVgPC1hcy5udW1lcmljKGxldmVscyhtYXRpbGRhX2dycCRgRWNvbm9taWMgIEFjdGl2ZWApW21hdGlsZGFfZ3JwJGBFY29ub21pYyAgQWN0aXZlYF0pCm1hdGlsZGFfZ3JwJGBZb3VuZ2VyIEdyb3VwYDwtYXMubnVtZXJpYyhsZXZlbHMobWF0aWxkYV9ncnAkYFlvdW5nZXIgR3JvdXBgKVttYXRpbGRhX2dycCRgWW91bmdlciBHcm91cGBdKQpgYGAKCmBgYHtyfQojTm9ydGhzaG9yZQpub3J0aHNvcmVfZ3JvdXA8LXJldmVyc2VbNzo5XQpub3J0aHNvcmVfZ3JvdXA8LW5vcnRoc29yZV9ncm91cFstMSxdCgpjb2xuYW1lcyhub3J0aHNvcmVfZ3JvdXApIDwtIHVubGlzdChub3J0aHNvcmVfZ3JvdXBbcm93Lm5hbWVzKG5vcnRoc29yZV9ncm91cCk9PSdFY29ub21pYyBHcm91cCcsXSkKbm9ydGhzb3JlX2dyb3VwJFllYXIgPC0gcm93bmFtZXMobm9ydGhzb3JlX2dyb3VwKQpub3J0aHNvcmVfZ3JvdXA8LW5vcnRoc29yZV9ncm91cFstMSxdCnJvd25hbWVzKG5vcnRoc29yZV9ncm91cCkgPC0gTlVMTAoKbm9ydGhzb3JlX2dyb3VwJGBBZ2VkIEdyb3VwYDwtYXMubnVtZXJpYyhsZXZlbHMobm9ydGhzb3JlX2dyb3VwJGBBZ2VkIEdyb3VwYClbbm9ydGhzb3JlX2dyb3VwJGBBZ2VkIEdyb3VwYF0pCm5vcnRoc29yZV9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWA8LWFzLm51bWVyaWMobGV2ZWxzKG5vcnRoc29yZV9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWApW25vcnRoc29yZV9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWBdKQpub3J0aHNvcmVfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgPC1hcy5udW1lcmljKGxldmVscyhub3J0aHNvcmVfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgKVtub3J0aHNvcmVfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgXSkKYGBgCgoKYGBge3J9CiNQdW5nZ29sIENhbmFsCnB1bmdnb2xfY2FuYWxfZ3JvdXA8LXJldmVyc2VbMTA6MTJdCnB1bmdnb2xfY2FuYWxfZ3JvdXA8LXB1bmdnb2xfY2FuYWxfZ3JvdXBbLTEsXQoKY29sbmFtZXMocHVuZ2dvbF9jYW5hbF9ncm91cCkgPC0gdW5saXN0KHB1bmdnb2xfY2FuYWxfZ3JvdXBbcm93Lm5hbWVzKHB1bmdnb2xfY2FuYWxfZ3JvdXApPT0nRWNvbm9taWMgR3JvdXAnLF0pCnB1bmdnb2xfY2FuYWxfZ3JvdXAkWWVhciA8LSByb3duYW1lcyhwdW5nZ29sX2NhbmFsX2dyb3VwKQpwdW5nZ29sX2NhbmFsX2dyb3VwPC1wdW5nZ29sX2NhbmFsX2dyb3VwWy0xLF0Kcm93bmFtZXMocHVuZ2dvbF9jYW5hbF9ncm91cCkgPC0gTlVMTAoKcHVuZ2dvbF9jYW5hbF9ncm91cCRgQWdlZCBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKHB1bmdnb2xfY2FuYWxfZ3JvdXAkYEFnZWQgR3JvdXBgKVtwdW5nZ29sX2NhbmFsX2dyb3VwJGBBZ2VkIEdyb3VwYF0pCnB1bmdnb2xfY2FuYWxfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgPC1hcy5udW1lcmljKGxldmVscyhwdW5nZ29sX2NhbmFsX2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYClbcHVuZ2dvbF9jYW5hbF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWBdKQpwdW5nZ29sX2NhbmFsX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYDwtYXMubnVtZXJpYyhsZXZlbHMocHVuZ2dvbF9jYW5hbF9ncm91cCRgWW91bmdlciBHcm91cGApW3B1bmdnb2xfY2FuYWxfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgXSkKYGBgCgpgYGB7cn0KI1B1bmdnb2wgRmllbGQKcHVuZ2dvbF9maWVsZF9ncm91cCA8LXJldmVyc2VbMTM6MTVdCnB1bmdnb2xfZmllbGRfZ3JvdXA8LXB1bmdnb2xfZmllbGRfZ3JvdXBbLTEsXQoKY29sbmFtZXMocHVuZ2dvbF9maWVsZF9ncm91cCkgPC0gdW5saXN0KHB1bmdnb2xfZmllbGRfZ3JvdXBbcm93Lm5hbWVzKHB1bmdnb2xfZmllbGRfZ3JvdXApPT0nRWNvbm9taWMgR3JvdXAnLF0pCnB1bmdnb2xfZmllbGRfZ3JvdXAkWWVhciA8LSByb3duYW1lcyhwdW5nZ29sX2ZpZWxkX2dyb3VwKQpwdW5nZ29sX2ZpZWxkX2dyb3VwPC1wdW5nZ29sX2ZpZWxkX2dyb3VwWy0xLF0Kcm93bmFtZXMocHVuZ2dvbF9maWVsZF9ncm91cCkgPC0gTlVMTAoKcHVuZ2dvbF9maWVsZF9ncm91cCRgQWdlZCBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKHB1bmdnb2xfZmllbGRfZ3JvdXAkYEFnZWQgR3JvdXBgKVtwdW5nZ29sX2ZpZWxkX2dyb3VwJGBBZ2VkIEdyb3VwYF0pCnB1bmdnb2xfZmllbGRfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgPC1hcy5udW1lcmljKGxldmVscyhwdW5nZ29sX2ZpZWxkX2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYClbcHVuZ2dvbF9maWVsZF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWBdKQpwdW5nZ29sX2ZpZWxkX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYDwtYXMubnVtZXJpYyhsZXZlbHMocHVuZ2dvbF9maWVsZF9ncm91cCRgWW91bmdlciBHcm91cGApW3B1bmdnb2xfZmllbGRfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgXSkKCmBgYAoKYGBge3J9CiNQdW5nZ29sIFRvd24gQ2VudHJlCnB1bmdnb2xfdGNfZ3JvdXAgPC1yZXZlcnNlWzE2OjE4XQpwdW5nZ29sX3RjX2dyb3VwPC1wdW5nZ29sX3RjX2dyb3VwWy0xLF0KCmNvbG5hbWVzKHB1bmdnb2xfdGNfZ3JvdXApIDwtIHVubGlzdChwdW5nZ29sX3RjX2dyb3VwW3Jvdy5uYW1lcyhwdW5nZ29sX3RjX2dyb3VwKT09J0Vjb25vbWljIEdyb3VwJyxdKQpwdW5nZ29sX3RjX2dyb3VwJFllYXIgPC0gcm93bmFtZXMocHVuZ2dvbF90Y19ncm91cCkKcHVuZ2dvbF90Y19ncm91cDwtcHVuZ2dvbF90Y19ncm91cFstMSxdCnJvd25hbWVzKHB1bmdnb2xfdGNfZ3JvdXApIDwtIE5VTEwKCnB1bmdnb2xfdGNfZ3JvdXAkYEFnZWQgR3JvdXBgPC1hcy5udW1lcmljKGxldmVscyhwdW5nZ29sX3RjX2dyb3VwJGBBZ2VkIEdyb3VwYClbcHVuZ2dvbF90Y19ncm91cCRgQWdlZCBHcm91cGBdKQpwdW5nZ29sX3RjX2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYDwtYXMubnVtZXJpYyhsZXZlbHMocHVuZ2dvbF90Y19ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWApW3B1bmdnb2xfdGNfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgXSkKcHVuZ2dvbF90Y19ncm91cCRgWW91bmdlciBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKHB1bmdnb2xfdGNfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgKVtwdW5nZ29sX3RjX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYF0pCgoKYGBgCgpgYGB7cn0KI1dhdGVyd2F5IEVhc3QKd2F0ZXJ3YXlfZWFzdF9ncm91cCA8LXJldmVyc2VbMTk6MjFdCndhdGVyd2F5X2Vhc3RfZ3JvdXA8LXdhdGVyd2F5X2Vhc3RfZ3JvdXBbLTEsXQoKY29sbmFtZXMod2F0ZXJ3YXlfZWFzdF9ncm91cCkgPC0gdW5saXN0KHdhdGVyd2F5X2Vhc3RfZ3JvdXBbcm93Lm5hbWVzKHdhdGVyd2F5X2Vhc3RfZ3JvdXApPT0nRWNvbm9taWMgR3JvdXAnLF0pCndhdGVyd2F5X2Vhc3RfZ3JvdXAkWWVhciA8LSByb3duYW1lcyh3YXRlcndheV9lYXN0X2dyb3VwKQp3YXRlcndheV9lYXN0X2dyb3VwPC13YXRlcndheV9lYXN0X2dyb3VwWy0xLF0Kcm93bmFtZXMod2F0ZXJ3YXlfZWFzdF9ncm91cCkgPC0gTlVMTAoKd2F0ZXJ3YXlfZWFzdF9ncm91cCRgQWdlZCBHcm91cGA8LWFzLm51bWVyaWMobGV2ZWxzKHdhdGVyd2F5X2Vhc3RfZ3JvdXAkYEFnZWQgR3JvdXBgKVt3YXRlcndheV9lYXN0X2dyb3VwJGBBZ2VkIEdyb3VwYF0pCndhdGVyd2F5X2Vhc3RfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgPC1hcy5udW1lcmljKGxldmVscyh3YXRlcndheV9lYXN0X2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYClbd2F0ZXJ3YXlfZWFzdF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWBdKQp3YXRlcndheV9lYXN0X2dyb3VwJGBZb3VuZ2VyIEdyb3VwYDwtYXMubnVtZXJpYyhsZXZlbHMod2F0ZXJ3YXlfZWFzdF9ncm91cCRgWW91bmdlciBHcm91cGApW3dhdGVyd2F5X2Vhc3RfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgXSkKCgpgYGAKCgpNYXRpbGRhJ3MgQ3VycmVudCBQb3B1bGF0aW9uCmBgYHtyfQpnZ3Bsb3QobWF0aWxkYV9ncnAsIGFlcyh4PW1hdGlsZGFfZ3JwJFllYXIpKSArIAogIGdlb21fbGluZShhZXMoIHk9bWF0aWxkYV9ncnAkYFlvdW5nZXIgR3JvdXBgLCBjb2xvcj0ic3RlZWxibHVlIixncm91cD0xKSkrCiAgICBnZW9tX2xpbmUoYWVzKCB5PW1hdGlsZGFfZ3JwJGBFY29ub21pYyAgQWN0aXZlYCwgY29sb3I9ImdyZWVuIixncm91cD0xKSkrCiAgZ2VvbV9saW5lKGFlcyh5PW1hdGlsZGFfZ3JwJGBBZ2VkIEdyb3VwYCwgY29sb3IgPSAiZGFya3JlZCIsIGdyb3VwPTEpKSArIAogICAgICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShuYW1lID0gIlBvcHVsYXRpb24gR3JvdXAiLCBsYWJlbHMgPSBjKCJZb3VuZ2VyIEdyb3VwIChCZWxvdyAyNSkiLCJFY29ub21pYyBBY3RpdmUgKDI1LTY0KSIsICAiQWdlZCBHcm91cCAoQWJvdmUgNjQpIikpKwogIGxhYnModGl0bGU9Ik1hdGlsZGEncyBDdXJyZW50IFBvcHVsYXRpb24iLAogICAgICAgIHggPSJZZWFyIiwgeSA9ICJUb3RhbCBQb3B1bGF0aW9uIikKCmBgYAoKCk5vcnRoc2hvcmUncyBDdXJyZW50IFBvcHVsYXRpb24KYGBge3J9CmdncGxvdChub3J0aHNvcmVfZ3JvdXAsIGFlcyh4PW5vcnRoc29yZV9ncm91cCRZZWFyKSkgKyAKICBnZW9tX2xpbmUoYWVzKCB5PW5vcnRoc29yZV9ncm91cCRgWW91bmdlciBHcm91cGAsIGNvbG9yPSJzdGVlbGJsdWUiLGdyb3VwPTEpKSsKICAgIGdlb21fbGluZShhZXMoIHk9bm9ydGhzb3JlX2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYCwgY29sb3I9ImdyZWVuIixncm91cD0xKSkrCiAgZ2VvbV9saW5lKGFlcyh5PW5vcnRoc29yZV9ncm91cCRgQWdlZCBHcm91cGAsIGNvbG9yID0gImRhcmtyZWQiLCBncm91cD0xKSkgKyAKICAgICAgc2NhbGVfY29sb3JfZGlzY3JldGUobmFtZSA9ICJQb3B1bGF0aW9uIEdyb3VwIiwgbGFiZWxzID0gYygiWW91bmdlciBHcm91cCAoQmVsb3cgMjUpIiwiRWNvbm9taWMgQWN0aXZlICgyNS02NCkiLCAgIkFnZWQgR3JvdXAgKEFib3ZlIDY0KSIpKSsKICBsYWJzKHRpdGxlPSJOb3J0aHNob3JlJ3MgQ3VycmVudCBQb3B1bGF0aW9uIiwKICAgICAgICB4ID0iWWVhciIsIHkgPSAiVG90YWwgUG9wdWxhdGlvbiIpCmBgYAoKUHVuZ2dvbCBDYW5hbCdzIEN1cnJlbnQgUG9wdWxhdGlvbgpgYGB7cn0KZ2dwbG90KHB1bmdnb2xfY2FuYWxfZ3JvdXAsIGFlcyh4PXB1bmdnb2xfY2FuYWxfZ3JvdXAkWWVhcikpICsgCiAgZ2VvbV9saW5lKGFlcyggeT1wdW5nZ29sX2NhbmFsX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYCwgY29sb3I9InN0ZWVsYmx1ZSIsZ3JvdXA9MSkpKwogICAgZ2VvbV9saW5lKGFlcyggeT1wdW5nZ29sX2NhbmFsX2dyb3VwJGBFY29ub21pYyAgQWN0aXZlYCwgY29sb3I9ImdyZWVuIixncm91cD0xKSkrCiAgZ2VvbV9saW5lKGFlcyh5PXB1bmdnb2xfY2FuYWxfZ3JvdXAkYEFnZWQgR3JvdXBgLCBjb2xvciA9ICJkYXJrcmVkIiwgZ3JvdXA9MSkpICsgCiAgICAgIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKG5hbWUgPSAiUG9wdWxhdGlvbiBHcm91cCIsIGxhYmVscyA9IGMoIllvdW5nZXIgR3JvdXAgKEJlbG93IDI1KSIsIkVjb25vbWljIEFjdGl2ZSAoMjUtNjQpIiwgICJBZ2VkIEdyb3VwIChBYm92ZSA2NCkiKSkrCiAgbGFicyh0aXRsZT0iUHVuZ2dvbCBDYW5hbCdzIEN1cnJlbnQgUG9wdWxhdGlvbiIsCiAgICAgICAgeCA9IlllYXIiLCB5ID0gIlRvdGFsIFBvcHVsYXRpb24iKQpgYGAKClB1bmdnb2wgRmllbGQncyBDdXJyZW50IFBvcHVsYXRpb24KYGBge3J9CmdncGxvdChwdW5nZ29sX2ZpZWxkX2dyb3VwLCBhZXMoeD1wdW5nZ29sX2ZpZWxkX2dyb3VwJFllYXIpKSArIAogIGdlb21fbGluZShhZXMoIHk9cHVuZ2dvbF9maWVsZF9ncm91cCRgWW91bmdlciBHcm91cGAsIGNvbG9yPSJzdGVlbGJsdWUiLGdyb3VwPTEpKSsKICAgIGdlb21fbGluZShhZXMoIHk9cHVuZ2dvbF9maWVsZF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAsIGNvbG9yPSJncmVlbiIsZ3JvdXA9MSkpKwogIGdlb21fbGluZShhZXMoeT1wdW5nZ29sX2ZpZWxkX2dyb3VwJGBBZ2VkIEdyb3VwYCwgY29sb3IgPSAiZGFya3JlZCIsIGdyb3VwPTEpKSArIAogICAgICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShuYW1lID0gIlBvcHVsYXRpb24gR3JvdXAiLCBsYWJlbHMgPSBjKCJZb3VuZ2VyIEdyb3VwIChCZWxvdyAyNSkiLCJFY29ub21pYyBBY3RpdmUgKDI1LTY0KSIsICAiQWdlZCBHcm91cCAoQWJvdmUgNjQpIikpKwogIGxhYnModGl0bGU9IlB1bmdnb2wgRmllbGQncyBDdXJyZW50IFBvcHVsYXRpb24iLAogICAgICAgIHggPSJZZWFyIiwgeSA9ICJUb3RhbCBQb3B1bGF0aW9uIikKYGBgCgpQdW5nZ29sIFRvd24gQ2VudHJlJ3MgQ3VycmVudCBQb3B1bGF0aW9uCmBgYHtyfQpnZ3Bsb3QocHVuZ2dvbF90Y19ncm91cCwgYWVzKHg9cHVuZ2dvbF90Y19ncm91cCRZZWFyKSkgKyAKICBnZW9tX2xpbmUoYWVzKCB5PXB1bmdnb2xfdGNfZ3JvdXAkYFlvdW5nZXIgR3JvdXBgLCBjb2xvcj0ic3RlZWxibHVlIixncm91cD0xKSkrCiAgICBnZW9tX2xpbmUoYWVzKCB5PXB1bmdnb2xfdGNfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgLCBjb2xvcj0iZ3JlZW4iLGdyb3VwPTEpKSsKICBnZW9tX2xpbmUoYWVzKHk9cHVuZ2dvbF90Y19ncm91cCRgQWdlZCBHcm91cGAsIGNvbG9yID0gImRhcmtyZWQiLCBncm91cD0xKSkgKyAKICAgICAgc2NhbGVfY29sb3JfZGlzY3JldGUobmFtZSA9ICJQb3B1bGF0aW9uIEdyb3VwIiwgbGFiZWxzID0gYygiWW91bmdlciBHcm91cCAoQmVsb3cgMjUpIiwiRWNvbm9taWMgQWN0aXZlICgyNS02NCkiLCAgIkFnZWQgR3JvdXAgKEFib3ZlIDY0KSIpKSsKICBsYWJzKHRpdGxlPSJQdW5nZ29sIFRvd24gQ2VudHJlJ3MgQ3VycmVudCBQb3B1bGF0aW9uIiwKICAgICAgICB4ID0iWWVhciIsIHkgPSAiVG90YWwgUG9wdWxhdGlvbiIpCgpgYGAKCldhdGVyd2F5IEVhc3QncyBDdXJyZW50IFBvcHVsYXRpb24KYGBge3J9CmdncGxvdCh3YXRlcndheV9lYXN0X2dyb3VwLCBhZXMoeD13YXRlcndheV9lYXN0X2dyb3VwJFllYXIpKSArIAogIGdlb21fbGluZShhZXMoIHk9d2F0ZXJ3YXlfZWFzdF9ncm91cCRgWW91bmdlciBHcm91cGAsIGNvbG9yPSJzdGVlbGJsdWUiLGdyb3VwPTEpKSsKICAgIGdlb21fbGluZShhZXMoIHk9d2F0ZXJ3YXlfZWFzdF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAsIGNvbG9yPSJncmVlbiIsZ3JvdXA9MSkpKwogIGdlb21fbGluZShhZXMoeT13YXRlcndheV9lYXN0X2dyb3VwJGBBZ2VkIEdyb3VwYCwgY29sb3IgPSAiZGFya3JlZCIsIGdyb3VwPTEpKSArIAogICAgICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShuYW1lID0gIlBvcHVsYXRpb24gR3JvdXAiLCBsYWJlbHMgPSBjKCJZb3VuZ2VyIEdyb3VwIChCZWxvdyAyNSkiLCJFY29ub21pYyBBY3RpdmUgKDI1LTY0KSIsICAiQWdlZCBHcm91cCAoQWJvdmUgNjQpIikpKwogIGxhYnModGl0bGU9IldhdGVyd2F5IEVhc3QncyBDdXJyZW50IFBvcHVsYXRpb24iLAogICAgICAgIHggPSJZZWFyIiwgeSA9ICJUb3RhbCBQb3B1bGF0aW9uIikKCmBgYAoKCgoKI1doeSBBUklNQT8KaHR0cHM6Ly93d3cucmVzZWFyY2hnYXRlLm5ldC9wb3N0L0RvX0FSSU1BX21vZGVsc19oYXZlX2FuX3RoZW9yZXRpY2FsX2ludGVycHJldGF0aW9uX2luX3BvcHVsYXRpb25fZm9yZWNhc3RpbmcgCmh0dHBzOi8vbGluay5zcHJpbmdlci5jb20vYXJ0aWNsZS8xMC4xMDA3L0JGMDEwNjY1MjkKaHR0cHM6Ly93d3cucmVzZWFyY2hnYXRlLm5ldC9wdWJsaWNhdGlvbi8yMjg0NjgyNTRfRm9yZWNhc3RpbmdfdGhlX3BvcHVsYXRpb25fb2ZfUGFraXN0YW5fdXNpbmdfQVJJTUFfbW9kZWxzCgojRm9yZWNhc3RpbmcgTWF0aWxkYSdzIFBvcHVsYXRpb24KaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDc4NTI1NjcvYXJpbWEtZm9yZWNhc3Qta2VlcC1nZXR0aW5nLWVycm9yLWRhdGEtbXVzdC1iZS1vZi1hLXZlY3Rvci10eXBlLXdhcy1udWxsCmh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzUzMDk5Mjg5L2Vycm9yLWluLWFycmF5LWRhdGEtbXVzdC1iZS1vZi1hLXZlY3Rvci10eXBlLXdhcy1udWxsLWluLXIKCkRldmVsb3BpbmcgYSBBUklNQSBNb2RlbCB0byBNYXRpbGRhJ3MgUG9wdWxhdGlvbiBGb3JlY2FzdApQcmVhc3N1bXB0aW9uIHRoYXQgdGhlIGRhdGEgaXMgc3RhdGlvbmFyeSwgd2hpY2ggbWVhbnMgdHJlbmRzIGFuZCBzZWFzb25hbGl0eSBoYXMgYmVlbiByZW1vdmVkIGR1ZSB0byBhIGNvbnNpc3RlbnQgZGVtYW5kLgpgYGB7cn0KCiNwcmVkaWN0IGFnZWQgZ3JvdXAKbWF0aWxkYV9ncnAkYEFnZWQgR3JvdXBgCm1hdGlsZGFfZm9yZWNhc3RfQUcgPC0gdHMobWF0aWxkYV9ncnAkYEFnZWQgR3JvdXBgLHN0YXJ0ID0gYygyMDExLDEpLCAgZW5kPWMoMjAxOSwgMSksZnJlcXVlbmN5ID0gMSkKcGxvdChtYXRpbGRhX2ZvcmVjYXN0X0FHKQptYXRpbGRhX0FSSU1BZml0X0FHIDwtIGF1dG8uYXJpbWEobWF0aWxkYV9mb3JlY2FzdF9BRykKcHJlZF9BRyA8LSBmb3JlY2FzdChtYXRpbGRhX0FSSU1BZml0X0FHLCBoID0gNSkKcGxvdChwcmVkX0FHKQpwcmVkX0FHX2RmIDwtIGRhdGEuZnJhbWUocHJlZF9BRykKCmBgYAoKYGBge3J9CiNwcmVkaWN0IGVjb25vbWljIGFjdGl2ZQptYXRpbGRhX2dycCRgRWNvbm9taWMgIEFjdGl2ZWAKbWF0aWxkYV9mb3JlY2FzdF9FQSA8LSB0cyhtYXRpbGRhX2dycCRgRWNvbm9taWMgIEFjdGl2ZWAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQpwbG90KG1hdGlsZGFfZm9yZWNhc3RfRUEpCm1hdGlsZGFfQVJJTUFmaXRfRUEgPC0gYXV0by5hcmltYShtYXRpbGRhX2ZvcmVjYXN0X0VBKQpwcmVkX0VBIDwtIGZvcmVjYXN0KG1hdGlsZGFfQVJJTUFmaXRfRUEsIGggPSA1KQoKcGxvdChwcmVkX0VBKQoKcHJlZF9FQV9kZiA8LSBkYXRhLmZyYW1lKHByZWRfRUEpCgpgYGAKCiMjTWF0aWxkYSdzIEZvcmVjYXN0IERhdGEgVGFibGUKYGBge3J9CiNwcmVkaWN0IHlvdW5nZXIgZ2VuCm1hdGlsZGFfZ3JwJGBZb3VuZ2VyIEdyb3VwYAptYXRpbGRhX2ZvcmVjYXN0X1lHIDwtIHRzKG1hdGlsZGFfZ3JwJGBZb3VuZ2VyIEdyb3VwYCxzdGFydCA9IGMoMjAxMSwxKSwgIGVuZD1jKDIwMTksIDEpLGZyZXF1ZW5jeSA9IDEpCnBsb3QobWF0aWxkYV9mb3JlY2FzdF9ZRykKbWF0aWxkYV9BUklNQWZpdF9ZRyA8LSBhdXRvLmFyaW1hKG1hdGlsZGFfZm9yZWNhc3RfWUcpCnByZWRfWUcgPC0gZm9yZWNhc3QobWF0aWxkYV9BUklNQWZpdF9ZRywgaCA9IDUpCnBsb3QocHJlZF9ZRykKCnByZWRfWUdfZGYgPC0gZGF0YS5mcmFtZShwcmVkX1lHKQoKCiNhZGQgQVJJTUEgcHJlZGljdGlvbiB0byBjdXJyZW50IAoKCm1hdGlsZGFfZ3JwW25yb3cobWF0aWxkYV9ncnApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzEsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlsxLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjApCm1hdGlsZGFfZ3JwW25yb3cobWF0aWxkYV9ncnApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMixdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzIsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlsyLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjEpCm1hdGlsZGFfZ3JwW25yb3cobWF0aWxkYV9ncnApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMyxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzMsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlszLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjIpCm1hdGlsZGFfZ3JwW25yb3cobWF0aWxkYV9ncnApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbNCxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzQsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZls0LF0kUG9pbnQuRm9yZWNhc3QsIDIwMjMpCm1hdGlsZGFfZ3JwW25yb3cobWF0aWxkYV9ncnApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbNSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzUsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZls1LF0kUG9pbnQuRm9yZWNhc3QsIDIwMjQpCgptYXRpbGRhX2dycAoKYGBgCgojRm9yZWNhc3RpbmcgTm9ydGhzb3JlJ3MgUG9wdWxhdGlvbgpBbiBBUklNQSgwLDAsMCkgbW9kZWwgd2l0aCB6ZXJvIG1lYW4gaXMgd2hpdGUgbm9pc2UsIG1lYW5zIHRoYXQgdGhlIGVycm9ycyBhcmUgdW5jb3JyZWxhdGVkIGFjcm9zcyB0aW1lLgpgYGB7cn0KCiNwcmVkaWN0IGFnZWQgZ3JvdXAKbm9ydGhzb3JlX2dyb3VwJGBBZ2VkIEdyb3VwYApub3J0aHNvcmVfZm9yZWNhc3RfQUcgPC0gdHMobm9ydGhzb3JlX2dyb3VwJGBBZ2VkIEdyb3VwYCxzdGFydCA9IGMoMjAxMSwxKSwgIGVuZD1jKDIwMTksIDEpLGZyZXF1ZW5jeSA9IDEpCnBsb3Qobm9ydGhzb3JlX2ZvcmVjYXN0X0FHKQpub3J0aHNvcmVfQVJJTUFmaXRfQUcgPC0gYXV0by5hcmltYShub3J0aHNvcmVfZm9yZWNhc3RfQUcpCnByZWRfQUcgPC0gZm9yZWNhc3Qobm9ydGhzb3JlX0FSSU1BZml0X0FHLCBoID0gNSkKcGxvdChwcmVkX0FHKQoKcHJlZF9BR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfQUcpCgoKI3ByZWRpY3QgZWNvbm9taWMgYWN0aXZlCm5vcnRoc29yZV9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAKbm9ydGhzb3JlX2ZvcmVjYXN0X0VBIDwtIHRzKG5vcnRoc29yZV9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQpwbG90KG5vcnRoc29yZV9mb3JlY2FzdF9FQSkKbm9ydGhzb3JlX0FSSU1BZml0X0VBIDwtIGF1dG8uYXJpbWEobm9ydGhzb3JlX2ZvcmVjYXN0X0VBKQpwcmVkX0VBIDwtIGZvcmVjYXN0KG5vcnRoc29yZV9BUklNQWZpdF9FQSwgaCA9IDUpCnBsb3QocHJlZF9FQSkKCnByZWRfRUFfZGYgPC0gZGF0YS5mcmFtZShwcmVkX0VBKQoKI3ByZWRpY3QgeW91bmdlciBnZW4Kbm9ydGhzb3JlX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYApub3J0aHNvcmVfZm9yZWNhc3RfWUcgPC0gdHMobm9ydGhzb3JlX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYCxzdGFydCA9IGMoMjAxMSwxKSwgIGVuZD1jKDIwMTksIDEpLGZyZXF1ZW5jeSA9IDEpCnBsb3Qobm9ydGhzb3JlX2ZvcmVjYXN0X1lHKQpub3J0aHNvcmVfQVJJTUFmaXRfWUcgPC0gYXV0by5hcmltYShub3J0aHNvcmVfZm9yZWNhc3RfWUcpCnByZWRfWUcgPC0gZm9yZWNhc3Qobm9ydGhzb3JlX0FSSU1BZml0X1lHLCBoID0gNSkKcGxvdChwcmVkX1lHKQoKcHJlZF9ZR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfWUcpCgpgYGAKCiMjTm9ydGhzb3JlJ3MgRm9yZWNhc3QgRGF0YSBUYWJsZQpgYGB7cn0Kbm9ydGhzb3JlX2dyb3VwW25yb3cobm9ydGhzb3JlX2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzEsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZlsxLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbMSxdJFBvaW50LkZvcmVjYXN0LCAyMDIwKQpub3J0aHNvcmVfZ3JvdXBbbnJvdyhub3J0aHNvcmVfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMixdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzIsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlsyLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjEpCm5vcnRoc29yZV9ncm91cFtucm93KG5vcnRoc29yZV9ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZlszLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbMyxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzMsXSRQb2ludC5Gb3JlY2FzdCwgMjAyMikKbm9ydGhzb3JlX2dyb3VwW25yb3cobm9ydGhzb3JlX2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzQsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZls0LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbNCxdJFBvaW50LkZvcmVjYXN0LCAyMDIzKQpub3J0aHNvcmVfZ3JvdXBbbnJvdyhub3J0aHNvcmVfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbNSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzUsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZls1LF0kUG9pbnQuRm9yZWNhc3QsIDIwMjQpCgoKbm9ydGhzb3JlX2dyb3VwCmBgYAoKI0ZvcmVjYXN0aW5nIFB1bmdnb2wgRmllbGQncyBQb3B1bGF0aW9uCmBgYHtyfQoKI3ByZWRpY3QgYWdlZCBncm91cApwdW5nZ29sX2ZpZWxkX2dyb3VwJGBBZ2VkIEdyb3VwYApwZl9mb3JlY2FzdF9BRyA8LSB0cyhwdW5nZ29sX2ZpZWxkX2dyb3VwJGBBZ2VkIEdyb3VwYCxzdGFydCA9IGMoMjAxMSwxKSwgIGVuZD1jKDIwMTksIDEpLGZyZXF1ZW5jeSA9IDEpCnBsb3QocGZfZm9yZWNhc3RfQUcpCnBmX0FSSU1BZml0X0FHIDwtIGF1dG8uYXJpbWEocGZfZm9yZWNhc3RfQUcpCnByZWRfQUcgPC0gZm9yZWNhc3QocGZfQVJJTUFmaXRfQUcsIGggPSA1KQpwbG90KHByZWRfQUcpCgpwcmVkX0FHX2RmIDwtIGRhdGEuZnJhbWUocHJlZF9BRykKCgojcHJlZGljdCBlY29ub21pYyBhY3RpdmUKcHVuZ2dvbF9maWVsZF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAKcGZfZm9yZWNhc3RfRUEgPC0gdHMocHVuZ2dvbF9maWVsZF9ncm91cCRgRWNvbm9taWMgIEFjdGl2ZWAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQpwbG90KHBmX2ZvcmVjYXN0X0VBKQpwZl9BUklNQWZpdF9FQSA8LSBhdXRvLmFyaW1hKHBmX2ZvcmVjYXN0X0VBKQpwcmVkX0VBIDwtIGZvcmVjYXN0KHBmX0FSSU1BZml0X0VBLCBoID0gNSkKcGxvdChwcmVkX0VBKQoKcHJlZF9FQV9kZiA8LSBkYXRhLmZyYW1lKHByZWRfRUEpCgojcHJlZGljdCB5b3VuZ2VyIGdlbgpwdW5nZ29sX2ZpZWxkX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYApwZl9mb3JlY2FzdF9ZRyA8LSB0cyhwdW5nZ29sX2ZpZWxkX2dyb3VwJGBZb3VuZ2VyIEdyb3VwYCxzdGFydCA9IGMoMjAxMSwxKSwgIGVuZD1jKDIwMTksIDEpLGZyZXF1ZW5jeSA9IDEpCnBsb3QocGZfZm9yZWNhc3RfWUcpCnBmX0FSSU1BZml0X1lHIDwtIGF1dG8uYXJpbWEocGZfZm9yZWNhc3RfWUcpCnByZWRfWUcgPC0gZm9yZWNhc3QocGZfQVJJTUFmaXRfWUcsIGggPSA1KQpwbG90KHByZWRfWUcpCgpwcmVkX1lHX2RmIDwtIGRhdGEuZnJhbWUocHJlZF9ZRykKYGBgCgojI1B1bmdnb2wgRmllbGQncyBGb3JlY2FzdCBEYXRhIFRhYmxlCmBgYHtyfQpwdW5nZ29sX2ZpZWxkX2dyb3VwW25yb3cocHVuZ2dvbF9maWVsZF9ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZlsxLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbMSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzEsXSRQb2ludC5Gb3JlY2FzdCwgMjAyMCkKcHVuZ2dvbF9maWVsZF9ncm91cFtucm93KHB1bmdnb2xfZmllbGRfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMixdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzIsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlsyLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjEpCnB1bmdnb2xfZmllbGRfZ3JvdXBbbnJvdyhwdW5nZ29sX2ZpZWxkX2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzMsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZlszLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbMyxdJFBvaW50LkZvcmVjYXN0LCAyMDIyKQpwdW5nZ29sX2ZpZWxkX2dyb3VwW25yb3cocHVuZ2dvbF9maWVsZF9ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZls0LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbNCxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzQsXSRQb2ludC5Gb3JlY2FzdCwgMjAyMykKcHVuZ2dvbF9maWVsZF9ncm91cFtucm93KHB1bmdnb2xfZmllbGRfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbNSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzUsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZls1LF0kUG9pbnQuRm9yZWNhc3QsIDIwMjQpCgpwdW5nZ29sX2ZpZWxkX2dyb3VwCmBgYAoKI0ZvcmVjYXN0aW5nIFB1bmdnb2wgVG93biBDZW50cmUncyAgUG9wdWxhdGlvbgpgYGB7cn0KCiNwcmVkaWN0IGFnZWQgZ3JvdXAKcHVuZ2dvbF90Y19ncm91cCRgQWdlZCBHcm91cGAKdGNfZm9yZWNhc3RfQUcgPC0gdHMocHVuZ2dvbF90Y19ncm91cCRgQWdlZCBHcm91cGAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQpwbG90KHRjX2ZvcmVjYXN0X0FHKQp0Y19BUklNQWZpdF9BRyA8LSBhdXRvLmFyaW1hKHRjX2ZvcmVjYXN0X0FHKQpwcmVkX0FHIDwtIGZvcmVjYXN0KHRjX0FSSU1BZml0X0FHLCBoID0gNSkKcGxvdChwcmVkX0FHKQoKcHJlZF9BR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfQUcpCgoKI3ByZWRpY3QgZWNvbm9taWMgYWN0aXZlCnB1bmdnb2xfdGNfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgCnRjX2ZvcmVjYXN0X0VBIDwtIHRzKHB1bmdnb2xfdGNfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgLHN0YXJ0ID0gYygyMDExLDEpLCAgZW5kPWMoMjAxOSwgMSksZnJlcXVlbmN5ID0gMSkKcGxvdCh0Y19mb3JlY2FzdF9FQSkKdGNfQVJJTUFmaXRfRUEgPC0gYXV0by5hcmltYSh0Y19mb3JlY2FzdF9FQSkKcHJlZF9FQSA8LSBmb3JlY2FzdCh0Y19BUklNQWZpdF9FQSwgaCA9IDUpCnBsb3QocHJlZF9FQSkKCnByZWRfRUFfZGYgPC0gZGF0YS5mcmFtZShwcmVkX0VBKQoKI3ByZWRpY3QgeW91bmdlciBnZW4KcHVuZ2dvbF90Y19ncm91cCRgWW91bmdlciBHcm91cGAKdGNfZm9yZWNhc3RfWUcgPC0gdHMocHVuZ2dvbF90Y19ncm91cCRgWW91bmdlciBHcm91cGAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQpwbG90KHRjX2ZvcmVjYXN0X1lHKQp0Y19BUklNQWZpdF9ZRyA8LSBhdXRvLmFyaW1hKHRjX2ZvcmVjYXN0X1lHKQpwcmVkX1lHIDwtIGZvcmVjYXN0KHRjX0FSSU1BZml0X1lHLCBoID0gNSkKcGxvdChwcmVkX1lHKQoKcHJlZF9ZR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfWUcpCgpgYGAKCiMjUHVuZ2dvbCBUb3duIENlbnRyZSdzIEZvcmVjYXN0IERhdGEgVGFibGUKYGBge3J9CnB1bmdnb2xfdGNfZ3JvdXBbbnJvdyhwdW5nZ29sX3RjX2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzEsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZlsxLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbMSxdJFBvaW50LkZvcmVjYXN0LCAyMDIwKQpwdW5nZ29sX3RjX2dyb3VwW25yb3cocHVuZ2dvbF90Y19ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZlsyLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbMixdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzIsXSRQb2ludC5Gb3JlY2FzdCwgMjAyMSkKcHVuZ2dvbF90Y19ncm91cFtucm93KHB1bmdnb2xfdGNfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMyxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzMsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlszLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjIpCnB1bmdnb2xfdGNfZ3JvdXBbbnJvdyhwdW5nZ29sX3RjX2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzQsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZls0LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbNCxdJFBvaW50LkZvcmVjYXN0LCAyMDIzKQpwdW5nZ29sX3RjX2dyb3VwW25yb3cocHVuZ2dvbF90Y19ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZls1LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbNSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzUsXSRQb2ludC5Gb3JlY2FzdCwgMjAyNCkKcHVuZ2dvbF90Y19ncm91cApgYGAKCiNGb3JlY2FzdGluZyBXYXRlcndheSBFYXN0J3MgIFBvcHVsYXRpb24KCmBgYHtyfQoKCiNwcmVkaWN0IGFnZWQgZ3JvdXAKd2VfZm9yZWNhc3RfQUcgPC0gdHMod2F0ZXJ3YXlfZWFzdF9ncm91cCRgQWdlZCBHcm91cGAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQp3ZV9BUklNQWZpdF9BRyA8LSBhdXRvLmFyaW1hKHdlX2ZvcmVjYXN0X0FHKQpwcmVkX0FHIDwtIGZvcmVjYXN0KHdlX0FSSU1BZml0X0FHLCBoID0gNSkKcGxvdChwcmVkX0FHKQoKcHJlZF9BR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfQUcpCgoKI3ByZWRpY3QgZWNvbm9taWMgYWN0aXZlCndhdGVyd2F5X2Vhc3RfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgCndlX2ZvcmVjYXN0X0VBIDwtIHRzKHdhdGVyd2F5X2Vhc3RfZ3JvdXAkYEVjb25vbWljICBBY3RpdmVgLHN0YXJ0ID0gYygyMDExLDEpLCAgZW5kPWMoMjAxOSwgMSksZnJlcXVlbmN5ID0gMSkKd2VfQVJJTUFmaXRfRUEgPC0gYXV0by5hcmltYSh3ZV9mb3JlY2FzdF9FQSkKcHJlZF9FQSA8LSBmb3JlY2FzdCh3ZV9BUklNQWZpdF9FQSwgaCA9IDUpCnBsb3QocHJlZF9FQSkKCnByZWRfRUFfZGYgPC0gZGF0YS5mcmFtZShwcmVkX0VBKQoKI3ByZWRpY3QgeW91bmdlciBnZW4Kd2F0ZXJ3YXlfZWFzdF9ncm91cCRgWW91bmdlciBHcm91cGAKd2VfZm9yZWNhc3RfWUcgPC0gdHMod2F0ZXJ3YXlfZWFzdF9ncm91cCRgWW91bmdlciBHcm91cGAsc3RhcnQgPSBjKDIwMTEsMSksICBlbmQ9YygyMDE5LCAxKSxmcmVxdWVuY3kgPSAxKQp3ZV9BUklNQWZpdF9ZRyA8LSBhdXRvLmFyaW1hKHdlX2ZvcmVjYXN0X1lHKQpwcmVkX1lHIDwtIGZvcmVjYXN0KHdlX0FSSU1BZml0X1lHLCBoID0gNSkKcGxvdChwcmVkX1lHKQoKcHJlZF9ZR19kZiA8LSBkYXRhLmZyYW1lKHByZWRfWUcpCmBgYAoKYGBge3J9CndhdGVyd2F5X2Vhc3RfZ3JvdXBbbnJvdyh3YXRlcndheV9lYXN0X2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzEsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZlsxLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbMSxdJFBvaW50LkZvcmVjYXN0LCAyMDIwKQp3YXRlcndheV9lYXN0X2dyb3VwW25yb3cod2F0ZXJ3YXlfZWFzdF9ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZlsyLF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbMixdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzIsXSRQb2ludC5Gb3JlY2FzdCwgMjAyMSkKd2F0ZXJ3YXlfZWFzdF9ncm91cFtucm93KHdhdGVyd2F5X2Vhc3RfZ3JvdXApICsgMSxdIDwtICBjKHByZWRfQUdfZGZbMyxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX0VBX2RmWzMsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9ZR19kZlszLF0kUG9pbnQuRm9yZWNhc3QsIDIwMjIpCndhdGVyd2F5X2Vhc3RfZ3JvdXBbbnJvdyh3YXRlcndheV9lYXN0X2dyb3VwKSArIDEsXSA8LSAgYyhwcmVkX0FHX2RmWzQsXSRQb2ludC5Gb3JlY2FzdCwgcHJlZF9FQV9kZls0LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfWUdfZGZbNCxdJFBvaW50LkZvcmVjYXN0LCAyMDIzKQp3YXRlcndheV9lYXN0X2dyb3VwW25yb3cod2F0ZXJ3YXlfZWFzdF9ncm91cCkgKyAxLF0gPC0gIGMocHJlZF9BR19kZls1LF0kUG9pbnQuRm9yZWNhc3QsIHByZWRfRUFfZGZbNSxdJFBvaW50LkZvcmVjYXN0LCBwcmVkX1lHX2RmWzUsXSRQb2ludC5Gb3JlY2FzdCwgMjAyNCkKd2F0ZXJ3YXlfZWFzdF9ncm91cAoKd2F0ZXJ3YXlfZWFzdF9ncm91cApgYGAKCiMjQXNzdW1wdGlvbjogQXJlYXMgbGlrZSBDb25uZXkgSXNsYW5kICYgUHVuZ2dvbCBDYW5hbCB3aWxsIGJlIHRyZWF0ZWQgYXMgYW4gZW1wdHkgcmVnaW9uLgpgYGB7cn0KcHVuZ2dvbF9jYW5hbF9ncm91cFtucm93KHB1bmdnb2xfY2FuYWxfZ3JvdXApICsgMSxdIDwtICBjKDAsMCwwLCAyMDIwKQpwdW5nZ29sX2NhbmFsX2dyb3VwW25yb3cocHVuZ2dvbF9jYW5hbF9ncm91cCkgKyAxLF0gPC0gIGMoMCwwLDAsIDIwMjEpCnB1bmdnb2xfY2FuYWxfZ3JvdXBbbnJvdyhwdW5nZ29sX2NhbmFsX2dyb3VwKSArIDEsXSA8LSAgYygwLDAsMCwgMjAyMikKcHVuZ2dvbF9jYW5hbF9ncm91cFtucm93KHB1bmdnb2xfY2FuYWxfZ3JvdXApICsgMSxdIDwtICBjKDAsMCwwLCAyMDIzKQpwdW5nZ29sX2NhbmFsX2dyb3VwW25yb3cocHVuZ2dvbF9jYW5hbF9ncm91cCkgKyAxLF0gPC0gIGMoMCwwLDAsIDIwMjQpCgoKY29ubmV5X2dycFtucm93KGNvbm5leV9ncnApICsgMSxdIDwtICBjKDAsMCwwLCAyMDIwKQpjb25uZXlfZ3JwW25yb3coY29ubmV5X2dycCkgKyAxLF0gPC0gIGMoMCwwLDAsIDIwMjEpCmNvbm5leV9ncnBbbnJvdyhjb25uZXlfZ3JwKSArIDEsXSA8LSAgYygwLDAsMCwgMjAyMikKY29ubmV5X2dycFtucm93KGNvbm5leV9ncnApICsgMSxdIDwtICBjKDAsMCwwLCAyMDIzKQpjb25uZXlfZ3JwW25yb3coY29ubmV5X2dycCkgKyAxLF0gPC0gIGMoMCwwLDAsIDIwMjQpCmBgYAoKCiNNZXJnaW5nIGRhdGFmcmFtZXMgYW5kIGFkZGluZyBiYWNrIHN1YnpvbmUgdmFsdWVzIGZvciBkYXRhIGFnZ3JlZ2F0aW9uIHRvIGJlIGRvbmUgb24gUUdJUwpgYGB7cn0KY29ubmV5X2dycCRTdWJ6b25lIDwtICJDb25leSBJc2xhbmQiCnB1bmdnb2xfY2FuYWxfZ3JvdXAkU3Viem9uZSA8LSAiUHVuZ2dvbCBDYW5hbCIKbWF0aWxkYV9ncnAkU3Viem9uZSA8LSAiTWF0aWxkYSIKcHVuZ2dvbF9maWVsZF9ncm91cCRTdWJ6b25lIDwtIlB1bmdnb2wgRmllbGQiCndhdGVyd2F5X2Vhc3RfZ3JvdXAkU3Viem9uZSA8LSAiV2F0ZXJ3YXkgRWFzdCIKcHVuZ2dvbF90Y19ncm91cCRTdWJ6b25lIDwtICJQdW5nZ29sIFRvd24gQ2VudHJlIgpub3J0aHNvcmVfZ3JvdXAkU3Viem9uZSA8LSAgIk5vcnRoc2hvcmUiCgpjb21iaW5lZF9mb3JlY2FzdCA8LSByYmluZChwdW5nZ29sX3RjX2dyb3VwLCB3YXRlcndheV9lYXN0X2dyb3VwLHB1bmdnb2xfZmllbGRfZ3JvdXAsbWF0aWxkYV9ncnAscHVuZ2dvbF9jYW5hbF9ncm91cCxjb25uZXlfZ3JwLCBub3J0aHNvcmVfZ3JvdXApCmNvbWJpbmVkX2ZvcmVjYXN0CmBgYAoKI1dyaXRlIGRhdGEgdG8gQ1NWCmBgYHtyfQp3cml0ZS5jc3YoY29tYmluZWRfZm9yZWNhc3QsJ3B1bmdnb2xfcG9wX3ByZWRpY3RlZC5jc3YnKQpgYGAKCgoK