Nigerian Deposit Money Banks Monthly Loan to Deposit Ratio (Jan. 2007 - April 2017) The data source is from the Central Bank of Nigeria Statistics Database

#check for seasonality
seasonplot(loan_to_deposit,main = "Season Plot: Nigerian Deposit Money Banks loan-to-Deposit Ratio ", year.labels = TRUE,col=1:20,ylab="Percentage(%)",year.labels.left=TRUE,pch=19)

Observing the graph above it does not seem there seems to have a strong seasonal observable pattern between the yearly season. Apart from 2008,2014 & 2015 all other years had the loan-to-deposit ratio drop from January to February.
#check for seasonality
plot(decompose ,main="Plot of Decomposition of Time Series - loan-to-deposit ratio")

monthplot(loan_to_deposit, ylab = "data", cex.axis = 0.8, main="Monthly plot of Data")

monthplot(decompose, choice = "seasonal", cex.axis = 0.8, main="Monthly plot of Seasonal ")

monthplot(decompose, choice = "trend", cex.axis = 0.8, main="Monthly plot of Trend")

monthplot(decompose, choice = "remainder", type = "h", cex.axis = 0.8, , main="Monthly plot of Remainder")

#check for seasonality
quarter <- (cycle(loan_to_deposit)-1 ) %/% 3
monthplot(loan_to_deposit, phase = quarter, main="Quarterly Plot: Loan-to-deposit Ratio")

The quarterly plot reveal a strong quarterly seasonality.
Determining if the Time Series is Stationary
Using the R tsdisplay method, I generated the ACF and PACF plots. The ACF plots show a gradual decrease which implies that the time series is not stationary
tsdisplay(loan_to_deposit)

Determining the Differencing Order to Make Time Series Stationary
The original data contains trends. To convert the time series to a stationary time series I made use of the R diffs method. To determine the order of difference to apply I made use of the R forecast package method ndiffs, ndiffs(loan_to_deposit) = 1
To determine the need for order of seasonality difference to apply I made use of nsdiffs, nsdiffs(loan_to_deposit) = 0
The result show that only first order differencing of the time series is required to make the series stationary
level_of_difference <- ndiffs(loan_to_deposit)
diff_data <- diff(loan_to_deposit, level_of_difference)
plot(diff_data, ylab="first order difference loans-to-deposit")

tsdisplay(diff_data, main="first order differencing of loans-to-deposit ratio time series")

The ACF above shows that there is only one autocorrelation that is outside the 95% limit.
Investigating Other time series dataset
The Nigerian Air total passengers travel time series dataset
The dataset is from the World bank website
plot.ts(nigeria,ylab="Number of Passengers per 1000", main = "Nigeria Yearly Air Passengers 1970 - 2015 ")

Investigating Time Series Stationarity: Nigerian Air Travel Passengers
The yearly time series plot above does not contain seasonality. The plot show evidence of a trend, hence this series is not stationary
Inspecting the ACF and PACF graph and determining the order of differencing the time series also confirms this.
Required order for differencing , ndiffs(nigeria)= 1
Using the ADF test, the p value of 0.7408 also confirms that the plot is not stationary
tsdisplay(nigeria)

adf.test(nigeria)
Augmented Dickey-Fuller Test
data: nigeria
Dickey-Fuller = -1.5803, Lag order = 3, p-value = 0.7408
alternative hypothesis: stationary
First Order Differenced Time Series
tsdisplay(diff(nigeria), main="First Order Difference Time Series ")

adf.test(diff(nigeria))
Augmented Dickey-Fuller Test
data: diff(nigeria)
Dickey-Fuller = -2.4792, Lag order = 3, p-value = 0.3837
alternative hypothesis: stationary
The graph above shows the first order differenced time series. The adf.test small p value indicates that the time series is now stationary. However it would be observed that the outlier points can still be observed in the differenced time series. ###Using AUTO.ARIMA to determine the best model for the Air Travel Time series
nigeria_fit <- auto.arima(nigeria)
summary(nigeria_fit)
Series: nigeria
ARIMA(0,1,0)
sigma^2 estimated as 260917: log likelihood=-344.47
AIC=690.94 AICc=691.04 BIC=692.75
Training set error measures:
ME RMSE MAE MPE MAPE MASE
Training set 66.3181 505.2179 267.8018 1.934564 20.54023 0.9782746
ACF1
Training set 0.1964641
Using ETS(SES) to determine the best model for the Air Travel Time series
nigeria_fit_ses <- ses(nigeria, initial = "simple")
summary(nigeria_fit_ses)
Forecast method: Simple exponential smoothing
Model Information:
Call:
ses(x = nigeria, initial = "simple")
Smoothing parameters:
alpha = 1
Initial states:
l = 173
sigma: 505.2179
Error measures:
ME RMSE MAE MPE MAPE MASE
Training set 66.31434 505.2179 267.7981 1.93239 20.53805 0.9782609
ACF1
Training set 0.1964642
Forecasts:
Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
2016 3223.46 2575.997 3870.923 2233.25090 4213.669
2017 3223.46 2307.809 4139.110 1823.09295 4623.827
2018 3223.46 2102.021 4344.898 1508.36769 4938.552
2019 3223.46 1928.534 4518.385 1243.04202 5203.878
2020 3223.46 1775.689 4671.231 1009.28542 5437.634
2021 3223.46 1637.506 4809.413 797.95329 5648.966
2022 3223.46 1510.434 4936.485 603.61334 5843.306
2023 3223.46 1392.158 5054.761 422.72613 6024.193
2024 3223.46 1281.071 5165.848 252.83315 6194.086
2025 3223.46 1176.003 5270.917 92.14437 6354.775
plot(nigeria, main= "ARIMA (0,1,0) & SES (alpha=1) Model Plot",ylab="Number of Passengers per 1000")
lines(fitted(nigeria_fit), col="red")
lines(fitted(nigeria_fit_ses), col="blue")
legend("topleft",lty=1, col=c("black","blue","red"),
c("Data","ARIMA Model","SES Model"),cex=0.80)

In the plot above the SES model is not noticable because it returns the same value as ARIMA(0,1,0) model.
Comparing the ARIMA and SES Models Fit Values
#Comparing ARIMA and SES models fit values
arima_model<- window(fitted(nigeria_fit),1970,1990)
ses_model<- window(fitted(nigeria_fit_ses),1970,1990)
ts.union(arima_model,ses_model)
Time Series:
Start = 1970
End = 1990
Frequency = 1
arima_model ses_model
1970 172.827 173.0
1971 173.000 173.0
1972 227.100 227.1
1973 286.800 286.8
1974 314.100 314.1
1975 430.300 430.3
1976 590.400 590.4
1977 800.800 800.8
1978 1093.900 1093.9
1979 1441.000 1441.0
1980 1581.300 1581.3
1981 1938.500 1938.5
1982 2300.200 2300.2
1983 2138.400 2138.4
1984 2221.300 2221.3
1985 1945.900 1945.9
1986 2575.000 2575.0
1987 2134.000 2134.0
1988 1614.400 1614.4
1989 995.000 995.0
1990 848.900 848.9
#last 15 values
arima_model2<- window(fitted(nigeria_fit),2000,2015)
ses_model2<- window(fitted(nigeria_fit_ses),2000,2015)
ts.union(arima_model2,ses_model2)
Time Series:
Start = 2000
End = 2015
Frequency = 1
arima_model2 ses_model2
2000 419.700 419.700
2001 507.396 507.396
2002 519.453 519.453
2003 520.278 520.278
2004 520.263 520.263
2005 540.461 540.461
2006 747.648 747.648
2007 1307.541 1307.541
2008 1363.435 1363.435
2009 1460.900 1460.900
2010 1365.343 1365.343
2011 4197.375 4197.375
2012 4793.913 4793.913
2013 4716.148 4716.148
2014 4209.624 4209.624
2015 3857.424 3857.424
Investigating the Model Residuals and Outlier impact
nigeria_outliers <-tso(nigeria,types=c("AO","LS","TC","IO"))
plot(residuals(nigeria_fit), main="ARIMA(0,1,0) & SES (alpha = 1) residuals", col="blue", ylab="Residual: Number of Passengers per 1000")
lines(residuals(nigeria_fit_ses), col="red")
legend("topleft",lty=1, col=c("blue","red"),
c("ARIMA Residual","SES Residual"),cex=0.80)

#ploting the outliers
plot(nigeria_outliers)

Box Plot to Verify Outliers
boxplot(nigeria, main="Box Plot of Nigeria Yearly Air Passengers 1970 - 2015 ")

Reviewing the outlier plot and model residual plot, it would be observed that the outliers had poor model representation compared to other data points in the time series. SES and ARIMA model for this time series returned the same value.
LS0tDQp0aXRsZTogIkludmVzdGlnYXRpbmcgVGltZSBTZXJpZXMgU3RhdGlvbmFyaXR5Ig0KYXV0aG9yOiAiQWRlYmF5byBBZGVyaWJpZ2JlIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgZ2l0aHViX2RvY3VtZW50OiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHRvYzogeWVzDQotLS0NCg0KDQoNCg0KYGBge3IgIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KCJmb3JlY2FzdCIpDQpsaWJyYXJ5KCJmcHAiKQ0KDQpgYGANCg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiNkYXRhIHNvdXJjZQ0KZG1iX2RhdGEgPC0gcmVhZC5jc3YoIkRNQl9kYXRhLmNzdiIpDQoNCiNjb252ZXJ0IGRhdGEgdG8gdGltZSBzZXJpZXMNCnRzX2RhdGEgPC0gdHMoZG1iX2RhdGFbLCgzOjUpXSxmcmVxdWVuY3k9MTIsc3RhcnQ9YygyMDA3LDEpKQ0KDQojbG9hbl90b19kZXBvc2l0DQpsb2FuX3RvX2RlcG9zaXQgPC0gdHNfZGF0YVssMV0NCg0KZGVjb21wb3NlIDwtIHN0bChsb2FuX3RvX2RlcG9zaXQsIHMud2luZG93PTEyKQ0KYGBgDQogIA0KICAgIA0KDQpOaWdlcmlhbiBEZXBvc2l0IE1vbmV5IEJhbmtzIE1vbnRobHkgTG9hbiB0byBEZXBvc2l0IFJhdGlvIChKYW4uIDIwMDcgLSBBcHJpbCAyMDE3KSANClRoZSBkYXRhIHNvdXJjZSBpcyBmcm9tIHRoZSBbQ2VudHJhbCBCYW5rIG9mIE5pZ2VyaWEgU3RhdGlzdGljcyAgRGF0YWJhc2VdKGh0dHA6Ly9zdGF0aXN0aWNzLmNibi5nb3YubmcvY2JuLW9ubGluZXN0YXRzL0RhdGFCcm93c2VyLmFzcHgpDQoNCmBgYHtyICBlY2hvPUZBTFNFfQ0KI3BhcihjZXguYXhpcz0xLjUsIGNleC5sYWI9MS41KQ0KdHMucGxvdChsb2FuX3RvX2RlcG9zaXQseGxhYj0iWWVhciIseWxhYj0iTG9hbnMtdG8tRGVwb3NpdCBSYXRpbyIsbWFpbj0iTW9udGhseSBMb2FuLXRvLURlcG9zaXQgUmF0aW8gIFxuZm9yIE5pZ2VyaWEgRGVwb3NpdCBNb25leSBCYW5rcyBKYW4uIDIwMDcgLSBBcHIuIDIwMTciKQ0KbGluZXMoZGVjb21wb3NlJHRpbWUuc2VyaWVzWywyXSxjb2w9InJlZCIseWxhYj0iVHJlbmQiKQ0KbGVnZW5kKCJib3R0b21yaWdodCIsYygiZGF0YSIsInRyZW5kIiksY29sPWMoImJsYWNrIiwicmVkIiksbHR5PWMoMSwxKSkNCmBgYA0KDQpgYGB7ciwgfQ0KI2NoZWNrIGZvciBzZWFzb25hbGl0eQ0Kc2Vhc29ucGxvdChsb2FuX3RvX2RlcG9zaXQsbWFpbiA9ICJTZWFzb24gUGxvdDogTmlnZXJpYW4gRGVwb3NpdCBNb25leSBCYW5rcyBsb2FuLXRvLURlcG9zaXQgUmF0aW8gIiwgeWVhci5sYWJlbHMgPSBUUlVFLGNvbD0xOjIwLHlsYWI9IlBlcmNlbnRhZ2UoJSkiLHllYXIubGFiZWxzLmxlZnQ9VFJVRSxwY2g9MTkpDQoNCmBgYA0KT2JzZXJ2aW5nIHRoZSBncmFwaCBhYm92ZSBpdCBkb2VzIG5vdCBzZWVtIHRoZXJlIHNlZW1zIHRvIGhhdmUgYSBzdHJvbmcgc2Vhc29uYWwgb2JzZXJ2YWJsZSBwYXR0ZXJuIGJldHdlZW4gdGhlIHllYXJseSBzZWFzb24uIEFwYXJ0IGZyb20gMjAwOCwyMDE0ICYgMjAxNSBhbGwgb3RoZXIgeWVhcnMgaGFkIHRoZSBsb2FuLXRvLWRlcG9zaXQgcmF0aW8gZHJvcCBmcm9tIEphbnVhcnkgdG8gRmVicnVhcnkuDQoNCmBgYHtyLCB9DQojY2hlY2sgZm9yIHNlYXNvbmFsaXR5DQpwbG90KGRlY29tcG9zZSAsbWFpbj0iUGxvdCBvZiBEZWNvbXBvc2l0aW9uIG9mIFRpbWUgU2VyaWVzIC0gbG9hbi10by1kZXBvc2l0IHJhdGlvIikNCg0KYGBgDQoNCmBgYHtyLCB9DQptb250aHBsb3QobG9hbl90b19kZXBvc2l0LCB5bGFiID0gImRhdGEiLCBjZXguYXhpcyA9IDAuOCwgbWFpbj0iTW9udGhseSBwbG90IG9mIERhdGEiKQ0KbW9udGhwbG90KGRlY29tcG9zZSwgY2hvaWNlID0gInNlYXNvbmFsIiwgY2V4LmF4aXMgPSAwLjgsIG1haW49Ik1vbnRobHkgcGxvdCBvZiBTZWFzb25hbCAiKQ0KbW9udGhwbG90KGRlY29tcG9zZSwgY2hvaWNlID0gInRyZW5kIiwgY2V4LmF4aXMgPSAwLjgsIG1haW49Ik1vbnRobHkgcGxvdCBvZiBUcmVuZCIpDQptb250aHBsb3QoZGVjb21wb3NlLCBjaG9pY2UgPSAicmVtYWluZGVyIiwgdHlwZSA9ICJoIiwgY2V4LmF4aXMgPSAwLjgsICwgbWFpbj0iTW9udGhseSBwbG90IG9mIFJlbWFpbmRlciIpDQpgYGANCg0KYGBge3IsIH0NCiNjaGVjayBmb3Igc2Vhc29uYWxpdHkNCnF1YXJ0ZXIgPC0gKGN5Y2xlKGxvYW5fdG9fZGVwb3NpdCktMSApICUvJSAzDQptb250aHBsb3QobG9hbl90b19kZXBvc2l0LCBwaGFzZSA9IHF1YXJ0ZXIsIG1haW49IlF1YXJ0ZXJseSBQbG90OiBMb2FuLXRvLWRlcG9zaXQgUmF0aW8iKQ0KYGBgDQpUaGUgcXVhcnRlcmx5IHBsb3QgcmV2ZWFsIGEgc3Ryb25nIHF1YXJ0ZXJseSBzZWFzb25hbGl0eS4NCg0KDQojIyNEZXRlcm1pbmluZyBpZiB0aGUgVGltZSBTZXJpZXMgaXMgU3RhdGlvbmFyeQ0KDQpVc2luZyB0aGUgUiAqKnRzZGlzcGxheSoqIG1ldGhvZCwgSSBnZW5lcmF0ZWQgdGhlIEFDRiBhbmQgUEFDRiBwbG90cy4gVGhlIEFDRiBwbG90cyBzaG93IGEgZ3JhZHVhbCBkZWNyZWFzZSB3aGljaCBpbXBsaWVzIHRoYXQgdGhlIHRpbWUgc2VyaWVzIGlzIG5vdCBzdGF0aW9uYXJ5DQoNCg0KYGBge3IgfQ0KdHNkaXNwbGF5KGxvYW5fdG9fZGVwb3NpdCkNCmBgYA0KDQoNCiMjI0RldGVybWluaW5nIHRoZSBEaWZmZXJlbmNpbmcgT3JkZXIgdG8gTWFrZSBUaW1lIFNlcmllcyBTdGF0aW9uYXJ5DQoNCg0KVGhlIG9yaWdpbmFsIGRhdGEgY29udGFpbnMgdHJlbmRzLiBUbyBjb252ZXJ0IHRoZSB0aW1lIHNlcmllcyB0byBhIHN0YXRpb25hcnkgdGltZSBzZXJpZXMgSSBtYWRlIHVzZSBvZiB0aGUgIFIgICoqZGlmZnMqKiAgbWV0aG9kLiANClRvIGRldGVybWluZSB0aGUgb3JkZXIgb2YgZGlmZmVyZW5jZSB0byBhcHBseSBJIG1hZGUgIHVzZSBvZiB0aGUgUiBmb3JlY2FzdCBwYWNrYWdlIG1ldGhvZCBuZGlmZnMsIG5kaWZmcyhsb2FuX3RvX2RlcG9zaXQpID0gYHIgbmRpZmZzKGxvYW5fdG9fZGVwb3NpdCkgYCAgDQpUbyBkZXRlcm1pbmUgdGhlIG5lZWQgZm9yIG9yZGVyIG9mIHNlYXNvbmFsaXR5IGRpZmZlcmVuY2UgdG8gYXBwbHkgSSBtYWRlIHVzZSBvZiBuc2RpZmZzLCBuc2RpZmZzKGxvYW5fdG9fZGVwb3NpdCkgPSBgciBuc2RpZmZzKGxvYW5fdG9fZGVwb3NpdCkgYCAgDQpUaGUgcmVzdWx0IHNob3cgdGhhdCBvbmx5IGZpcnN0IG9yZGVyIGRpZmZlcmVuY2luZyBvZiB0aGUgdGltZSBzZXJpZXMgaXMgcmVxdWlyZWQgdG8gbWFrZSB0aGUgc2VyaWVzIHN0YXRpb25hcnkNCg0KDQpgYGB7ciB9DQpsZXZlbF9vZl9kaWZmZXJlbmNlIDwtIG5kaWZmcyhsb2FuX3RvX2RlcG9zaXQpDQpkaWZmX2RhdGEgPC0gZGlmZihsb2FuX3RvX2RlcG9zaXQsIGxldmVsX29mX2RpZmZlcmVuY2UpDQoNCnBsb3QoZGlmZl9kYXRhLCB5bGFiPSJmaXJzdCBvcmRlciBkaWZmZXJlbmNlIGxvYW5zLXRvLWRlcG9zaXQiKQ0KdHNkaXNwbGF5KGRpZmZfZGF0YSwgbWFpbj0iZmlyc3Qgb3JkZXIgZGlmZmVyZW5jaW5nIG9mIGxvYW5zLXRvLWRlcG9zaXQgcmF0aW8gdGltZSBzZXJpZXMiKQ0KDQpgYGANCg0KVGhlIEFDRiBhYm92ZSBzaG93cyB0aGF0IHRoZXJlIGlzIG9ubHkgb25lIGF1dG9jb3JyZWxhdGlvbiB0aGF0IGlzIG91dHNpZGUgdGhlIDk1JSBsaW1pdC4NCg0KDQojIyNJbnZlc3RpZ2F0aW5nIE90aGVyIHRpbWUgc2VyaWVzIGRhdGFzZXQNCiMjIyMgVGhlIE5pZ2VyaWFuIEFpciB0b3RhbCBwYXNzZW5nZXJzIHRyYXZlbCB0aW1lIHNlcmllcyBkYXRhc2V0ICANClRoZSBkYXRhc2V0ICBpcyBmcm9tIHRoZSAgW1dvcmxkIGJhbmsgd2Vic2l0ZV0oaHR0cDovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvSVMuQUlSLlBTR1IpDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KDQphaXJfdHJhdmVsIDwtIHJlYWQuY3N2KCJBUElfSVMuQUlSLlBTR1JfRFMyX2VuX2Nzdl92Mi9BUElfSVMuQUlSLlBTR1JfRFMyX2VuX2Nzdl92Mi5DU1YiLCBoZWFkZXIgPSBUUlVFLHNraXAgPSA0LGNvbW1lbnQuY2hhcj0iIikNCg0KaGVhZChhaXJfdHJhdmVsLDUpDQoNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeSh0c291dGxpZXJzKQ0KDQphaXJfdHJhdmVsX2RmIDwtIGFzLmRhdGEuZnJhbWUoYWlyX3RyYXZlbCkNCg0KZ2hhbmFfbmlnZXJpYSA8LSBmaWx0ZXIoYWlyX3RyYXZlbF9kZiwgQ291bnRyeS5OYW1lID09Ik5pZ2VyaWEiIHwgQ291bnRyeS5OYW1lPT0iR2hhbmEiKQ0KDQpnaGFuYV9uaWdlcmlhX3RoaW4gPC0gZ2F0aGVyKGdoYW5hX25pZ2VyaWEsInllYXIiLCJuIiw1OjYyKQ0KDQpjbGVhbl9kYXRhIDwtIHNlbGVjdChnaGFuYV9uaWdlcmlhX3RoaW4sQ291bnRyeS5Db2RlLHllYXIsbikNCmNsZWFuX2RhdGEkeWVhciA8LSBzdHJfc3ViKGNsZWFuX2RhdGEkeWVhciwyKQ0KDQpjbGVhbl9kYXRhIDwtIGZpbHRlcihjbGVhbl9kYXRhLCB5ZWFyPj0xOTcwICYgeWVhcjwyMDE2KSAlPiUgc3ByZWFkKENvdW50cnkuQ29kZSxuKSU+JSANCiAgICAgICAgICAgIG11dGF0ZShHSEE9R0hBLzEwMDAsTkdBPU5HQS8xMDAwICkNCg0KDQoNCnRzX2NsZWFuX2RhdGEgPC0gdHMoY2xlYW5fZGF0YVssYygiR0hBIiwiTkdBIildLCBlbmQ9MjAxNSwgZnJlcXVlbmN5PTEpDQoNCm5pZ2VyaWEgPC0gdHNfY2xlYW5fZGF0YVssMl0NCmBgYA0KDQpgYGB7cn0NCnBsb3QudHMobmlnZXJpYSx5bGFiPSJOdW1iZXIgb2YgUGFzc2VuZ2VycyBwZXIgMTAwMCIsIG1haW4gPSAiTmlnZXJpYSAgWWVhcmx5IEFpciBQYXNzZW5nZXJzIDE5NzAgLSAyMDE1ICIpDQpgYGANCg0KIyMjSW52ZXN0aWdhdGluZyBUaW1lIFNlcmllcyBTdGF0aW9uYXJpdHk6IE5pZ2VyaWFuIEFpciBUcmF2ZWwgUGFzc2VuZ2Vycw0KVGhlIHllYXJseSAgdGltZSBzZXJpZXMgcGxvdCBhYm92ZSBkb2VzIG5vdCBjb250YWluIHNlYXNvbmFsaXR5LiBUaGUgcGxvdCBzaG93IGV2aWRlbmNlIG9mIGEgdHJlbmQsIGhlbmNlIHRoaXMgc2VyaWVzIGlzIG5vdCBzdGF0aW9uYXJ5ICANCkluc3BlY3RpbmcgdGhlIEFDRiBhbmQgUEFDRiBncmFwaCBhbmQgZGV0ZXJtaW5pbmcgdGhlIG9yZGVyIG9mIGRpZmZlcmVuY2luZyB0aGUgdGltZSBzZXJpZXMgYWxzbyBjb25maXJtcyB0aGlzLiAgDQpSZXF1aXJlZCBvcmRlciBmb3IgZGlmZmVyZW5jaW5nICwgbmRpZmZzKG5pZ2VyaWEpPSBgciBuZGlmZnMobmlnZXJpYSkgYCAgDQpVc2luZyB0aGUgQURGIHRlc3QsIHRoZSBwIHZhbHVlIG9mIDAuNzQwOCBhbHNvIGNvbmZpcm1zIHRoYXQgdGhlIHBsb3QgaXMgbm90IHN0YXRpb25hcnkNCg0KYGBge3J9DQp0c2Rpc3BsYXkobmlnZXJpYSkNCmFkZi50ZXN0KG5pZ2VyaWEpDQpgYGANCg0KRmlyc3QgT3JkZXIgRGlmZmVyZW5jZWQgVGltZSBTZXJpZXMgDQpgYGB7cn0NCnRzZGlzcGxheShkaWZmKG5pZ2VyaWEpLCBtYWluPSJGaXJzdCBPcmRlciBEaWZmZXJlbmNlIFRpbWUgU2VyaWVzICIpDQphZGYudGVzdChkaWZmKG5pZ2VyaWEpKQ0KYGBgDQpUaGUgZ3JhcGggYWJvdmUgc2hvd3MgdGhlIGZpcnN0IG9yZGVyIGRpZmZlcmVuY2VkIHRpbWUgc2VyaWVzLiAgVGhlIGFkZi50ZXN0IHNtYWxsIHAgdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIHRpbWUgc2VyaWVzIGlzIG5vdyBzdGF0aW9uYXJ5LiAgSG93ZXZlciBpdCB3b3VsZCBiZSBvYnNlcnZlZCB0aGF0IHRoZSBvdXRsaWVyIHBvaW50cyBjYW4gc3RpbGwgYmUgb2JzZXJ2ZWQgaW4gdGhlIGRpZmZlcmVuY2VkIHRpbWUgc2VyaWVzLg0KIyMjVXNpbmcgQVVUTy5BUklNQSB0byBkZXRlcm1pbmUgdGhlIGJlc3QgbW9kZWwgZm9yIHRoZSBBaXIgVHJhdmVsIFRpbWUgc2VyaWVzDQpgYGB7ciwgfQ0KbmlnZXJpYV9maXQgPC0gYXV0by5hcmltYShuaWdlcmlhKQ0KDQpzdW1tYXJ5KG5pZ2VyaWFfZml0KQ0KDQoNCmBgYA0KDQojIyNVc2luZyBFVFMoU0VTKSB0byBkZXRlcm1pbmUgdGhlIGJlc3QgbW9kZWwgZm9yIHRoZSBBaXIgVHJhdmVsIFRpbWUgc2VyaWVzDQpgYGB7ciwgfQ0KbmlnZXJpYV9maXRfc2VzIDwtIHNlcyhuaWdlcmlhLCBpbml0aWFsID0gInNpbXBsZSIpDQoNCnN1bW1hcnkobmlnZXJpYV9maXRfc2VzKQ0KYGBgDQpgYGB7cn0NCnBsb3QobmlnZXJpYSwgbWFpbj0gIkFSSU1BICgwLDEsMCkgJiBTRVMgKGFscGhhPTEpIE1vZGVsIFBsb3QiLHlsYWI9Ik51bWJlciBvZiBQYXNzZW5nZXJzIHBlciAxMDAwIikNCmxpbmVzKGZpdHRlZChuaWdlcmlhX2ZpdCksIGNvbD0icmVkIikNCmxpbmVzKGZpdHRlZChuaWdlcmlhX2ZpdF9zZXMpLCBjb2w9ImJsdWUiKQ0KbGVnZW5kKCJ0b3BsZWZ0IixsdHk9MSwgY29sPWMoImJsYWNrIiwiYmx1ZSIsInJlZCIpLCANCiAgICAgICBjKCJEYXRhIiwiQVJJTUEgTW9kZWwiLCJTRVMgTW9kZWwiKSxjZXg9MC44MCkNCg0KYGBgDQpJbiB0aGUgcGxvdCBhYm92ZSB0aGUgU0VTIG1vZGVsIGlzIG5vdCBub3RpY2FibGUgYmVjYXVzZSBpdCByZXR1cm5zIHRoZSBzYW1lIHZhbHVlIGFzIEFSSU1BKDAsMSwwKSBtb2RlbC4gICAgDQoNCiMjIyNDb21wYXJpbmcgdGhlIEFSSU1BIGFuZCBTRVMgTW9kZWxzIEZpdCBWYWx1ZXMNCmBgYHtyfQ0KI0NvbXBhcmluZyBBUklNQSBhbmQgU0VTIG1vZGVscyBmaXQgdmFsdWVzDQphcmltYV9tb2RlbDwtIHdpbmRvdyhmaXR0ZWQobmlnZXJpYV9maXQpLDE5NzAsMTk5MCkNCnNlc19tb2RlbDwtIHdpbmRvdyhmaXR0ZWQobmlnZXJpYV9maXRfc2VzKSwxOTcwLDE5OTApDQp0cy51bmlvbihhcmltYV9tb2RlbCxzZXNfbW9kZWwpDQoNCiNsYXN0IDE1IHZhbHVlcw0KYXJpbWFfbW9kZWwyPC0gd2luZG93KGZpdHRlZChuaWdlcmlhX2ZpdCksMjAwMCwyMDE1KQ0Kc2VzX21vZGVsMjwtIHdpbmRvdyhmaXR0ZWQobmlnZXJpYV9maXRfc2VzKSwyMDAwLDIwMTUpDQp0cy51bmlvbihhcmltYV9tb2RlbDIsc2VzX21vZGVsMikNCmBgYA0KDQogICAgDQojIyMjSW52ZXN0aWdhdGluZyB0aGUgTW9kZWwgUmVzaWR1YWxzIGFuZCBPdXRsaWVyIGltcGFjdCAgDQoNCmBgYHtyLCB9DQoNCm5pZ2VyaWFfb3V0bGllcnMgPC10c28obmlnZXJpYSx0eXBlcz1jKCJBTyIsIkxTIiwiVEMiLCJJTyIpKQ0KDQpwbG90KHJlc2lkdWFscyhuaWdlcmlhX2ZpdCksIG1haW49IkFSSU1BKDAsMSwwKSAmIFNFUyAoYWxwaGEgPSAxKSByZXNpZHVhbHMiLCBjb2w9ImJsdWUiLCB5bGFiPSJSZXNpZHVhbDogTnVtYmVyIG9mIFBhc3NlbmdlcnMgcGVyIDEwMDAiKQ0KbGluZXMocmVzaWR1YWxzKG5pZ2VyaWFfZml0X3NlcyksIGNvbD0icmVkIikNCmxlZ2VuZCgidG9wbGVmdCIsbHR5PTEsIGNvbD1jKCJibHVlIiwicmVkIiksIA0KICAgICAgIGMoIkFSSU1BIFJlc2lkdWFsIiwiU0VTIFJlc2lkdWFsIiksY2V4PTAuODApDQoNCiNwbG90aW5nIHRoZSBvdXRsaWVycw0KcGxvdChuaWdlcmlhX291dGxpZXJzKQ0KDQpgYGANCg0KIyMjIEJveCBQbG90IHRvIFZlcmlmeSBPdXRsaWVycw0KYGBge3J9DQpib3hwbG90KG5pZ2VyaWEsIG1haW49IkJveCBQbG90IG9mIE5pZ2VyaWEgIFllYXJseSBBaXIgUGFzc2VuZ2VycyAxOTcwIC0gMjAxNSAgIikNCmBgYA0KDQpSZXZpZXdpbmcgdGhlIG91dGxpZXIgcGxvdCBhbmQgbW9kZWwgcmVzaWR1YWwgcGxvdCwgaXQgd291bGQgYmUgb2JzZXJ2ZWQgdGhhdCB0aGUgb3V0bGllcnMgaGFkIHBvb3IgbW9kZWwgcmVwcmVzZW50YXRpb24gY29tcGFyZWQgdG8gb3RoZXIgZGF0YSBwb2ludHMgaW4gdGhlIHRpbWUgc2VyaWVzLiBTRVMgYW5kIEFSSU1BIG1vZGVsIGZvciB0aGlzIHRpbWUgc2VyaWVzIHJldHVybmVkIHRoZSBzYW1lIHZhbHVlLg==