Alexander Bactat

Introduction: We often hear that Americans live in different realities-that our experiences are worlds apart. Here, we see if the forecasts for these different worlds are different as well.

income_data_share_of_income <- read_excel("income data share of income.xlsx")
View(income_data_share_of_income)
library(ggplot2)
Use suppressPackageStartupMessages() to eliminate package startup messages

Attaching package: 㤼㸱ggplot2㤼㸲

The following object is masked _by_ 㤼㸱.GlobalEnv㤼㸲:

    diamonds
library(forecast)
This is forecast 8.12 
  Crossvalidated is a great place to get help on forecasting issues:
  http://stats.stackexchange.com/tags/forecasting.
library(corrplot)
lowest.share <- income_data_share_of_income$`Lowest Quintile`
second.share <- income_data_share_of_income$`Second Quintile`
middle.share <- income_data_share_of_income$`Middle Quintile`
fourth.share <- income_data_share_of_income$`Fourth Quintile`
highest.share <- income_data_share_of_income$`Highest Quintile`
top.share <- income_data_share_of_income$`Top 1%`
lowest.share.ts <- ts(lowest.share, start=1979, frequency=1)
second.share.ts <- ts(second.share, start=1979, frequency=1)
middle.share.ts <- ts(middle.share, start=1979, frequency=1)
fourth.share.ts <- ts(fourth.share, start=1979, frequency=1)
highest.share.ts <- ts(highest.share, start=1979, frequency=1)
top.share.ts <- ts(top.share, start=1979, frequency=1)

Share over time

autoplot(lowest.share.ts/100, main = "Income Share Over Time") + autolayer(second.share.ts/100) + autolayer(middle.share.ts/100) + autolayer(fourth.share.ts/100) + autolayer(highest.share.ts/100)

Correlation

corr.share <- cor(income_data_share_of_income)
corrplot(corr.share, method=c("number"))

Historic Share of Income

historic.share <- cbind(lowest.share.ts, second.share.ts, middle.share.ts, fourth.share.ts, highest.share.ts)
autoplot(historic.share)

income_data <- read_excel("income_data.xlsx")
Error in read_excel("income_data.xlsx") : 
  could not find function "read_excel"
lowest.income <- income_data$`Lowest Quintile`
second.income <- income_data$`Second Quintile`
middle.income <- income_data$`Middle Quintile`
fourth.income <- income_data$`Fourth Quintile`
highest.income <- income_data$`Highest Quintile`
top.income <- income_data$`Top 1%`
lowest.income.ts <- ts(lowest.income, start=1979, frequency=1)
second.income.ts <- ts(second.income, start=1979, frequency=1)
middle.income.ts <- ts(middle.income, start=1979, frequency=1)
fourth.income.ts <- ts(fourth.income, start=1979, frequency=1)
highest.income.ts <- ts(highest.income, start=1979, frequency=1)
top.income.ts <- ts(top.income, start=1979, frequency=1)
tni <- lowest.income.ts + second.income.ts + middle.income.ts + fourth.income.ts + highest.income.ts

lowest.tni.share <- lowest.income.ts/tni
second.tni.share <- second.income.ts/tni
middle.tni.share <- middle.income.ts/tni
fourth.tni.share <- fourth.income.ts/tni
highest.tni.share <- highest.income.ts/tni

autoplot(lowest.tni.share, main = "TNI Share") + autolayer(second.tni.share) + autolayer(middle.tni.share) + autolayer(fourth.tni.share) + autolayer(highest.tni.share)

Visualization

corr.income <- cor(income_data)
corrplot(corr.income, main = "Figure 1", method=c("number"))

income.ts <- ts(income_data, start=1979, frequency=1)
autoplot(income.ts, main = "Income Data Over Time, 1%")

income.quintile.ts <- ts(income_data_quintile, start=1979, end=2017)
income.ts.quintile <- ts(income_data_quintile, start=1979, end=2017)
autoplot(income.ts.quintile, main = "Quintile Income Over Time")

Separate into training and test data

tr.lowest.income <- ts(c(lowest.income.ts), start=1979, end=2013)
tr.second.income <- ts(c(second.income.ts), start=1979, end=2013)
tr.middle.income <- ts(c(middle.income.ts), start=1979, end=2013)
tr.fourth.income <- ts(c(fourth.income.ts), start=1979, end=2013)
tr.highest.income <- ts(c(highest.income.ts), start=1979, end=2013)
tr.top.income <- ts(c(top.income.ts), start=1979, end=2013)

test.lowest.income <- tail(lowest.income.ts, n=4L)
test.second.income <- tail(second.income.ts, n=4L)
test.middle.income <- tail(middle.income.ts, n=4L)
test.fourth.income <- tail(fourth.income.ts, n=4L)
test.highest.income <- tail(highest.income.ts, n=4L)
test.top.income <- tail(top.income.ts, n=4L)

BoxCox transformation

lambda.lowest<-BoxCox.lambda(lowest.income.ts)
lowest.ts.bc<-BoxCox(lowest.income.ts, lambda.lowest)   
lambda.second<-BoxCox.lambda(second.income.ts)
second.ts.bc<-BoxCox(second.income.ts, lambda.second)
lambda.middle<-BoxCox.lambda(middle.income.ts)
middle.ts.bc<-BoxCox(middle.income.ts, lambda.middle)
lambda.fourth<-BoxCox.lambda(fourth.income.ts)
fourth.ts.bc<-BoxCox(fourth.income.ts, lambda.fourth)
lambda.highest<-BoxCox.lambda(highest.income.ts)
highest.ts.bc<-BoxCox(highest.income.ts, lambda.highest)
lambda.top<-BoxCox.lambda(top.income.ts)
top.ts.bc<-BoxCox(top.income.ts, lambda.top)

lambda.income<-BoxCox.lambda(income.ts)
income.ts.bc<-BoxCox(income.ts, lambda.income)

lambda.income.quintile<-BoxCox.lambda(income.quintile.ts)
income.quintile.ts.bc<-BoxCox(income.quintile.ts, lambda.income.quintile)

autoplot(lowest.ts.bc) + autolayer(second.ts.bc) + autolayer(middle.ts.bc) + autolayer(fourth.ts.bc) + autolayer(highest.ts.bc) + autolayer(top.ts.bc)


tr.lowest.income.bc <- ts(c(lowest.ts.bc), start=1979, end=2013)
tr.second.income.bc <- ts(c(second.ts.bc), start=1979, end=2013)
tr.middle.income.bc <- ts(c(middle.ts.bc), start=1979, end=2013)
tr.fourth.income.bc <- ts(c(fourth.ts.bc), start=1979, end=2013)
tr.highest.income.bc <- ts(c(highest.ts.bc), start=1979, end=2013)
tr.top.income.bc <- ts(c(top.ts.bc), start=1979, end=2013)

test.lowest.income.bc <- tail(lowest.ts.bc, n=4L)
test.second.income.bc <- tail(second.ts.bc, n=4L)
test.middle.income.bc <- tail(middle.ts.bc, n=4L)
test.fourth.income.bc <- tail(fourth.ts.bc, n=4L)
test.highest.income.bc <- tail(highest.ts.bc, n=4L)
test.top.income.bc <- tail(top.ts.bc, n=4L)

autoplot(lowest.ts.bc) + autolayer(second.ts.bc) + autolayer(middle.ts.bc) + autolayer(fourth.ts.bc) + autolayer(highest.ts.bc)

ARIMA Prediction

arima.lowest.tr <- auto.arima(tr.lowest.income, seasonal = FALSE)
arima.second.tr <- auto.arima(tr.second.income, seasonal = FALSE)
arima.middle.tr <- auto.arima(tr.middle.income, seasonal = FALSE)
arima.fourth.tr <- auto.arima(tr.fourth.income, seasonal = FALSE)
arima.highest.tr <- auto.arima(tr.highest.income, seasonal = FALSE)
arima.top.tr <- auto.arima(tr.top.income, seasonal = FALSE)

arima.lowest.pred <- forecast(arima.lowest.tr, h=4)
arima.second.pred <- forecast(arima.second.tr, h=4)
arima.middle.pred <- forecast(arima.middle.tr, h=4)
arima.fourth.pred <- forecast(arima.fourth.tr, h=4)
arima.highest.pred <- forecast(arima.highest.tr, h=4)
arima.top.pred <- forecast(arima.top.tr, h=4)

accuracy(arima.lowest.pred, test.lowest.income)
                      ME      RMSE       MAE         MPE     MAPE      MASE         ACF1 Theil's U
Training set    7.272219  462.4844  383.0312 -0.03105167 1.551573 0.7399466  0.004875264        NA
Test set     1498.156179 1597.2478 1498.1562  4.22661959 4.226620 2.8941653 -0.274204665  1.582799
accuracy(arima.second.pred, test.second.income)
                       ME      RMSE       MAE         MPE     MAPE      MASE       ACF1 Theil's U
Training set    0.9326046  757.8808  598.5797 -0.06006521 1.618504 0.9085584 0.18145044        NA
Test set     2002.9411765 2181.6909 2002.9412  4.12030216 4.120302 3.0401786 0.08682013  1.917735
accuracy(arima.middle.pred, test.middle.income)
                      ME      RMSE      MAE         MPE     MAPE      MASE       ACF1 Theil's U
Training set    1.338739  926.5299  712.095 -0.02885476 1.322278 0.9136314 0.21214719        NA
Test set     2764.705882 2969.9046 2764.706  4.13520057 4.135201 3.5471698 0.04459294  2.057399
accuracy(arima.fourth.pred, test.fourth.income)
                     ME     RMSE      MAE        MPE     MAPE      MASE        ACF1 Theil's U
Training set   28.08586 1099.501  871.381 0.02343413 1.188251 0.7879509 -0.05602955        NA
Test set     2441.57350 2641.248 2441.573 2.61275906 2.612759 2.2078058 -0.18847282  1.528457
accuracy(arima.highest.pred, test.highest.income)
                       ME      RMSE       MAE        MPE     MAPE      MASE       ACF1 Theil's U
Training set     3.029746  9319.586  7467.231 -0.1120896 4.450155 0.8877128  0.1024052        NA
Test set     11102.941177 11646.891 11102.941  4.9978237 4.997824 1.3199301 -0.5640736  1.600023
accuracy(arima.top.pred, test.top.income)
                    ME     RMSE      MAE       MPE     MAPE      MASE        ACF1 Theil's U
Training set  20176.34 140768.7 110627.8  1.933046 12.46039 0.9715219 -0.03039196        NA
Test set     183550.00 191028.1 183550.0 14.405772 14.40577 1.6119176 -0.43643777  2.340302
arima.lowest <- auto.arima(lowest.income.ts, seasonal = FALSE)
arima.second <- auto.arima(second.income.ts, seasonal = FALSE)
arima.middle <- auto.arima(middle.income.ts, seasonal = FALSE)
arima.fourth <- auto.arima(fourth.income.ts, seasonal = FALSE)
arima.highest <- auto.arima(highest.income.ts, seasonal = FALSE)
arima.top <- auto.arima(top.income.ts, seasonal = FALSE)

arima.lowest.forecast <- forecast(arima.lowest, h=6)
arima.second.forecast <- forecast(arima.second, h=6)
arima.middle.forecast <- forecast(arima.middle, h=6)
arima.fourth.forecast <- forecast(arima.fourth, h=6)
arima.highest.forecast <- forecast(arima.highest, h=6)
arima.top.forecast <- forecast(arima.top, h=6)

autoplot(income.ts) + autolayer(arima.lowest.forecast) + autolayer(arima.second.forecast) + autolayer(arima.middle.forecast) + autolayer(arima.fourth.forecast) + autolayer(arima.highest.forecast) + autolayer(arima.top.forecast)


autoplot(income.quintile.ts) + autolayer(arima.lowest.forecast) + autolayer(arima.second.forecast) + autolayer(arima.middle.forecast) + autolayer(arima.fourth.forecast) + autolayer(arima.highest.forecast)


arima.lowest$var.coef
              ar1        drift
ar1    0.02359604    -1.009667
drift -1.00966732 15031.631266
arima.second$var.coef
      drift
drift 15996
arima.middle$var.coef
             ar1        drift
ar1    0.0276232    -2.181023
drift -2.1810228 41457.525051
arima.fourth$var.coef
         drift
drift 36123.44
arima.highest$var.coef
        drift
drift 2225887
arima.top$var.coef
numeric(0)

ARIMA BoxCox

arima.lowest.tr.bc <- auto.arima(tr.lowest.income.bc, seasonal = FALSE)
arima.second.tr.bc <- auto.arima(tr.second.income.bc, seasonal = FALSE)
arima.middle.tr.bc <- auto.arima(tr.middle.income.bc, seasonal = FALSE)
arima.fourth.tr.bc <- auto.arima(tr.fourth.income.bc, seasonal = FALSE)
arima.highest.tr.bc <- auto.arima(tr.highest.income.bc, seasonal = FALSE)
arima.top.tr.bc <- auto.arima(tr.top.income.bc, seasonal = FALSE)

arima.lowest.pred.bc <- forecast(arima.lowest.tr.bc, h=4)
arima.second.pred.bc <- forecast(arima.second.tr.bc, h=4)
arima.middle.pred.bc <- forecast(arima.middle.tr.bc, h=4)
arima.fourth.pred.bc <- forecast(arima.fourth.tr.bc, h=4)
arima.highest.pred.bc <- forecast(arima.highest.tr.bc, h=4)
arima.top.pred.bc <- forecast(arima.top.tr.bc, h=4)

accuracy(arima.lowest.pred.bc, test.lowest.income.bc)
                       ME        RMSE         MAE         MPE      MAPE      MASE        ACF1 Theil's U
Training set 0.0002558375 0.006689416 0.005673231 0.003956481 0.0894611 0.7564037 -0.02981167        NA
Test set     0.0101396767 0.011289693 0.010139677 0.156423254 0.1564233 1.3519085 -0.37363327  1.146522
accuracy(arima.second.pred.bc, test.second.income.bc)
                       ME         RMSE          MAE          MPE         MAPE      MASE         ACF1 Theil's U
Training set 3.290109e-05 1.946594e-04 3.468072e-05 0.0028571386 0.0030116812 17.763066 -0.005726159        NA
Test set     3.026644e-06 3.290209e-06 3.026644e-06 0.0002628256 0.0002628256  1.550212  0.003398595  1.617547
accuracy(arima.middle.pred.bc, test.middle.income.bc)
                       ME         RMSE          MAE          MPE         MAPE     MASE         ACF1 Theil's U
Training set 2.857297e-05 1.690403e-04 2.882196e-05 2.857141e-03 2.882039e-03 105.3707 -0.001761018        NA
Test set     5.528845e-07 5.897093e-07 5.528845e-07 5.528509e-05 5.528509e-05   2.0213 -0.040482579  1.786731
accuracy(arima.fourth.pred.bc, test.fourth.income.bc)
                       ME         RMSE          MAE          MPE         MAPE        MASE         ACF1 Theil's U
Training set 2.857311e-05 1.690410e-04 2.874214e-05 2.857141e-03 2.874043e-03 140.0288313 -0.001491237        NA
Test set     1.443101e-07 1.633884e-07 1.443101e-07 1.443008e-05 1.443008e-05   0.7030645 -0.527666553 0.8164317
accuracy(arima.highest.pred.bc, test.highest.income.bc)
                       ME         RMSE          MAE         MPE       MAPE      MASE        ACF1 Theil's U
Training set 6.295487e-05 0.0004407647 0.0002575512 0.002856977 0.01168085 1.1552661 -0.07259585        NA
Test set     1.215947e-04 0.0001306268 0.0001215947 0.005510140 0.00551014 0.5454227 -0.68093091 0.9760904
accuracy(arima.top.pred.bc, test.top.income.bc)
                       ME         RMSE          MAE         MPE        MAPE     MASE        ACF1 Theil's U
Training set 0.0001039776 0.0003969834 0.0002227265 0.005079834 0.010879522 1.317200 -0.07330695        NA
Test set     0.0001715479 0.0001770203 0.0001715479 0.008375898 0.008375898 1.014531 -0.45198422  2.585902
arima.lowest.bc <- auto.arima(lowest.ts.bc, seasonal = FALSE)
arima.second.bc <- auto.arima(second.ts.bc, seasonal = FALSE)
arima.middle.bc <- auto.arima(middle.ts.bc, seasonal = FALSE)
arima.fourth.bc <- auto.arima(fourth.ts.bc, seasonal = FALSE)
arima.highest.bc <- auto.arima(highest.ts.bc, seasonal = FALSE)
arima.top.bc <- auto.arima(top.ts.bc, seasonal = FALSE)

arima.lowest.forecast.bc <- forecast(arima.lowest.bc, h=6)
arima.second.forecast.bc <- forecast(arima.second.bc, h=6)
arima.middle.forecast.bc <- forecast(arima.middle.bc, h=6)
arima.fourth.forecast.bc <- forecast(arima.fourth.bc, h=6)
arima.highest.forecast.bc <- forecast(arima.highest.bc, h=6)
arima.top.forecast.bc <- forecast(arima.top.bc, h=6)

arima.lowest.bc$var.coef
                ma1         drift
ma1    1.999394e-02 -1.113626e-06
drift -1.113626e-06  2.261588e-06
arima.second.bc$var.coef
             drift
drift 2.631593e-08
arima.middle.bc$var.coef
             drift
drift 2.631579e-08
arima.fourth.bc$var.coef
             drift
drift 2.631579e-08
arima.highest.bc$var.coef
            drift
drift 2.76922e-08
arima.top.bc$var.coef
             drift
drift 2.719784e-08

ARIMA Distribution Forecast


arima.total.forecast <- arima.lowest.forecast$mean + arima.second.forecast$mean + arima.middle.forecast$mean + arima.fourth.forecast$mean + arima.highest.forecast$mean

arima.lowest.forecast.share <- arima.lowest.forecast$mean/arima.total.forecast
arima.second.forecast.share <- arima.second.forecast$mean/arima.total.forecast
arima.middle.forecast.share <- arima.middle.forecast$mean/arima.total.forecast
arima.fourth.forecast.share <- arima.fourth.forecast$mean/arima.total.forecast
arima.highest.forecast.share <- arima.highest.forecast$mean/arima.total.forecast

autoplot(arima.lowest.forecast.share) + autolayer(arima.second.forecast.share) + autolayer(arima.middle.forecast.share) + autolayer(arima.fourth.forecast.share) + autolayer(arima.highest.forecast.share)

Holt Trend

holt.lowest.pred <- holt(tr.lowest.income,  h=4)
holt.second.pred <- holt(tr.second.income,  h=4)
holt.middle.pred <- holt(tr.middle.income,  h=4)
holt.fourth.pred <- holt(tr.fourth.income,  h=4)
holt.highest.pred <- holt(tr.highest.income,  h=4)
holt.top.pred <- holt(tr.top.income,  h=4)

accuracy(holt.lowest.pred, test.lowest.income)
                     ME      RMSE       MAE         MPE     MAPE      MASE       ACF1 Theil's U
Training set  -12.32408  501.8952  406.0495 -0.02202577 1.643612 0.7844137  0.1795881        NA
Test set     2013.10446 2123.7603 2013.1045  5.68107557 5.681076 3.8889518 -0.1555581  2.088794
accuracy(holt.second.pred, test.second.income)
                     ME      RMSE       MAE        MPE     MAPE      MASE       ACF1 Theil's U
Training set   26.01141  772.0958  622.5127 0.01548649 1.690866 0.9448854 0.11402772        NA
Test set     2005.22172 2184.2038 2005.2217 4.12498532 4.124985 3.0436401 0.08714682  1.919919
accuracy(holt.middle.pred, test.middle.income)
                    ME      RMSE       MAE        MPE     MAPE      MASE       ACF1 Theil's U
Training set   23.0981  977.0469  766.3832 0.02440584 1.437048 0.9832841 0.07965205        NA
Test set     2689.8084 2889.0496 2689.8084 4.02327361 4.023274 3.4510750 0.03608074  2.001999
accuracy(holt.fourth.pred, test.fourth.income)
                      ME     RMSE       MAE         MPE     MAPE      MASE       ACF1 Theil's U
Training set    7.510388 1220.524  999.1519 0.001063871 1.364005 0.9034885  0.1221030        NA
Test set     2049.719871 2238.851 2049.7199 2.192779432 2.192779 1.8534701 -0.2573818  1.300647
accuracy(holt.highest.pred, test.highest.income)
                    ME     RMSE      MAE        MPE     MAPE      MASE        ACF1 Theil's U
Training set -1248.955 9447.836 7401.222 -0.8913465 4.484089 0.8798655  0.09106555        NA
Test set      7593.992 8100.949 7593.992  3.4229277 3.422928 0.9027822 -0.75824994  1.088374
accuracy(holt.top.pred, test.top.income)
                    ME      RMSE       MAE       MPE      MAPE      MASE         ACF1 Theil's U
Training set -17824.56 140435.66 102952.43 -3.273117 11.821547 0.9041179 -0.008082532        NA
Test set      75479.75  84812.76  75479.75  5.920543  5.920543 0.6628555 -0.538230986 0.9612686

Holt Damped trend

holt.lowest.damp.pred <- holt(tr.lowest.income, damped=TRUE, h=4)
holt.second.damp.pred <- holt(tr.second.income, damped=TRUE, h=4)
holt.middle.damp.pred <- holt(tr.middle.income, damped=TRUE, h=4)
holt.fourth.damp.pred <- holt(tr.fourth.income, damped=TRUE, h=4)
holt.highest.damp.pred <- holt(tr.highest.income, damped=TRUE, h=4)
holt.top.damp.pred <- holt(tr.top.income, damped=TRUE, h=4)

accuracy(holt.lowest.damp.pred, test.lowest.income)
                     ME      RMSE       MAE       MPE     MAPE     MASE        ACF1 Theil's U
Training set   83.51819  493.0921  399.1551 0.3405908 1.599664 0.771095  0.03053898        NA
Test set     2300.82791 2431.7834 2300.8279 6.4909182 6.490918 4.444781 -0.07100652  2.389076
accuracy(holt.second.damp.pred, test.second.income)
                    ME      RMSE       MAE       MPE     MAPE      MASE          ACF1 Theil's U
Training set  163.3489  771.4854  589.1744 0.4644494 1.585256 0.8942825 -0.0003128137        NA
Test set     2912.8488 3163.4926 2912.8488 5.9927338 5.992734 4.4212884  0.1580220240  2.766222
accuracy(holt.middle.damp.pred, test.middle.income)
                   ME      RMSE       MAE       MPE     MAPE      MASE       ACF1 Theil's U
Training set  128.214  988.2337  764.2017 0.2049618 1.435785 0.9804852 0.09440196        NA
Test set     3258.861 3506.4420 3258.8611 4.8734970 4.873497 4.1811803 0.09036667   2.42528
accuracy(holt.fourth.damp.pred, test.fourth.income)
                    ME     RMSE       MAE       MPE     MAPE      MASE        ACF1 Theil's U
Training set  167.2705 1235.066  993.0851 0.1936469 1.361649 0.8980024  0.13997329        NA
Test set     3022.2565 3279.815 3022.2565 3.2328751 3.232875 2.7328915 -0.06228371  1.894919
accuracy(holt.highest.damp.pred, test.highest.income)
                      ME      RMSE       MAE        MPE     MAPE      MASE        ACF1 Theil's U
Training set    29.49519  9380.064  7722.461 -0.1233526 4.665533 0.9180547  0.08719802        NA
Test set     13073.75856 13720.491 13073.759  5.8818537 5.881854 1.5542230 -0.40221205  1.898821
accuracy(holt.top.damp.pred, test.top.income)
                      ME     RMSE      MAE       MPE     MAPE      MASE         ACF1 Theil's U
Training set   -292.2801 139060.1 106702.4 -1.163883 12.18184 0.9370495  0.001575588        NA
Test set     142149.6391 149177.4 142149.6 11.145223 11.14522 1.2483438 -0.587766313  1.817446
holt.lowest <- holt(lowest.income.ts, damped=TRUE, h=6)
holt.second <- holt(second.income.ts, damped=TRUE, h=6)
holt.middle <- holt(middle.income.ts, damped=TRUE, h=6)
holt.fourth <- holt(fourth.income.ts, damped=TRUE, h=6)
holt.highest <- holt(highest.income.ts, damped=TRUE, h=6)
holt.top <- holt(top.income.ts, damped=TRUE, h=6)

autoplot(income.ts) + autolayer(holt.lowest) + autolayer(holt.second) + autolayer(holt.middle) + autolayer(holt.fourth) + autolayer(holt.highest) + autolayer(holt.top)


autoplot(income.quintile.ts) + autolayer(holt.lowest) + autolayer(holt.second) + autolayer(holt.middle) + autolayer(holt.fourth) + autolayer(holt.highest)

holt.lowest$model
Damped Holt's method 

Call:
 holt(y = lowest.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.6115 
    phi   = 0.8 

  Initial states:
    l = 18919.9259 
    b = 370.4366 

  sigma:  594.5683

     AIC     AICc      BIC 
647.7792 650.4042 657.7606 
holt.second$model
Damped Holt's method 

Call:
 holt(y = second.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.0901 
    phi   = 0.98 

  Initial states:
    l = 31813.2089 
    b = 300.3689 

  sigma:  856.6333

     AIC     AICc      BIC 
676.2628 678.8878 686.2442 
holt.middle$model
Damped Holt's method 

Call:
 holt(y = middle.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.0414 
    phi   = 0.98 

  Initial states:
    l = 44999.873 
    b = 517.323 

  sigma:  1094.925

     AIC     AICc      BIC 
695.4065 698.0315 705.3879 
holt.fourth$model
Damped Holt's method 

Call:
 holt(y = fourth.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.0282 
    phi   = 0.98 

  Initial states:
    l = 58580.0094 
    b = 971.4121 

  sigma:  1343.881

     AIC     AICc      BIC 
711.3868 714.0118 721.3681 
holt.highest$model
Damped Holt's method 

Call:
 holt(y = highest.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 1e-04 
    phi   = 0.98 

  Initial states:
    l = 98159.7306 
    b = 4165.0621 

  sigma:  9834.965

     AIC     AICc      BIC 
866.6366 869.2616 876.6180 
holt.top$model
Damped Holt's method 

Call:
 holt(y = top.income.ts, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.8913 
    beta  = 1e-04 
    phi   = 0.98 

  Initial states:
    l = 300891.4257 
    b = 39277.1803 

  sigma:  144041.6

     AIC     AICc      BIC 
1076.001 1078.626 1085.982 

Holt BoxCox

holt.lowest.pred.bc <- holt(tr.lowest.income.bc, h=4)
holt.second.pred.bc <- holt(tr.lowest.income.bc, h=4)
holt.middle.pred.bc <- holt(tr.lowest.income.bc, h=4)
holt.fourth.pred.bc <- holt(tr.lowest.income.bc, h=4)
holt.highest.pred.bc <- holt(tr.lowest.income.bc, h=4)
holt.top.pred.bc <- holt(tr.lowest.income.bc, h=4)

accuracy(holt.lowest.pred.bc, test.lowest.income.bc)
                       ME        RMSE         MAE         MPE       MAPE      MASE       ACF1 Theil's U
Training set 0.0003309153 0.006978332 0.005448753 0.005482289 0.08578308 0.7264745  0.0853722        NA
Test set     0.0218306926 0.022968176 0.021830693 0.336805453 0.33680545 2.9106548 -0.1340803  2.298368
accuracy(holt.second.pred.bc, test.second.income.bc)
                        ME        RMSE         MAE           MPE         MAPE        MASE      ACF1 Theil's U
Training set  0.0003309153 0.006978332 0.005448753  5.482289e-03   0.08578308   0.7264745 0.0853722        NA
Test set     -5.3053409207 5.305341503 5.305340921 -4.607018e+02 460.70178256 707.3534727 0.2500358   2276525
accuracy(holt.middle.pred.bc, test.middle.income.bc)
                        ME        RMSE         MAE           MPE         MAPE        MASE      ACF1 Theil's U
Training set  0.0003309153 0.006978332 0.005448753  5.482289e-03   0.08578308   0.7264745 0.0853722        NA
Test set     -5.4568583918 5.456858959 5.456858392 -5.456527e+02 545.65274707 727.5550791 0.2500111  14534716
accuracy(holt.fourth.pred.bc, test.fourth.income.bc)
                        ME        RMSE         MAE           MPE         MAPE        MASE      ACF1 Theil's U
Training set  0.0003309153 0.006978332 0.005448753  5.482289e-03   0.08578308   0.7264745 0.0853722        NA
Test set     -5.4568540737 5.456854640 5.456854074 -5.456500e+02 545.64995928 727.5545034 0.2500103  23730445
accuracy(holt.highest.pred.bc, test.highest.income.bc)
                        ME        RMSE         MAE           MPE         MAPE        MASE      ACF1 Theil's U
Training set  0.0003309153 0.006978332 0.005448753  5.482289e-03   0.08578308   0.7264745 0.0853722        NA
Test set     -4.2501911122 4.250191787 4.250191112 -1.926015e+02 192.60149708 566.6718667 0.2591839  30828.02
accuracy(holt.top.pred.bc, test.top.income.bc)
                        ME        RMSE         MAE           MPE         MAPE        MASE      ACF1 Theil's U
Training set  0.0003309153 0.006978332 0.005448753  5.482289e-03   0.08578308   0.7264745 0.0853722        NA
Test set     -4.4088162627 4.408816948 4.408816263 -2.152634e+02 215.26342726 587.8211298 0.2556618  60127.98
holt.lowest.bc <- holt(lowest.ts.bc, damped=TRUE, h=6)
holt.second.bc <- holt(second.ts.bc, damped=TRUE, h=6)
holt.middle.bc <- holt(middle.ts.bc, damped=TRUE, h=6)
holt.fourth.bc <- holt(fourth.ts.bc, damped=TRUE, h=6)
holt.highest.bc <- holt(highest.ts.bc, damped=TRUE, h=6)
holt.top.bc <- holt(top.ts.bc, damped=TRUE, h=6)

holt.lowest.bc$model
Damped Holt's method 

Call:
 holt(y = lowest.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.3546 
    phi   = 0.936 

  Initial states:
    l = 6.2669 
    b = -0.0041 

  sigma:  0.0077

      AIC      AICc       BIC 
-229.8235 -227.1985 -219.8421 
holt.second.bc$model
Damped Holt's method 

Call:
 holt(y = second.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.8119 
    beta  = 1e-04 
    phi   = 0.9779 

  Initial states:
    l = 1.1515 
    b = 0 

  sigma:  0

      AIC      AICc       BIC 
-853.9775 -851.3525 -843.9962 
holt.middle.bc$model
Damped Holt's method 

Call:
 holt(y = middle.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9965 
    beta  = 0.0778 
    phi   = 0.9781 

  Initial states:
    l = 1.0001 
    b = 0 

  sigma:  0

       AIC       AICc        BIC 
-1006.9280 -1004.3030  -996.9467 
holt.fourth.bc$model
Damped Holt's method 

Call:
 holt(y = fourth.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9923 
    beta  = 7e-04 
    phi   = 0.9782 

  Initial states:
    l = 1.0001 
    b = 0 

  sigma:  0

      AIC      AICc       BIC 
-1040.381 -1037.756 -1030.399 
holt.highest.bc$model
Damped Holt's method 

Call:
 holt(y = highest.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.9954 
    beta  = 1e-04 
    phi   = 0.9769 

  Initial states:
    l = 2.2034 
    b = 1e-04 

  sigma:  2e-04

      AIC      AICc       BIC 
-500.2277 -497.6027 -490.2463 
holt.top.bc$model
Damped Holt's method 

Call:
 holt(y = top.ts.bc, h = 6, damped = TRUE) 

  Smoothing parameters:
    alpha = 0.8066 
    beta  = 1e-04 
    phi   = 0.9771 

  Initial states:
    l = 2.0462 
    b = 1e-04 

  sigma:  2e-04

      AIC      AICc       BIC 
-519.5355 -516.9105 -509.5542 

Holt Distribution Forecast

holt.total <- holt.lowest$mean + holt.second$mean + holt.middle$mean + holt.fourth$mean + holt.highest$mean

holt.lowest.share <- holt.lowest$mean/holt.total
holt.second.share <- holt.second$mean/holt.total
holt.middle.share <- holt.middle$mean/holt.total
holt.fourth.share <- holt.fourth$mean/holt.total
holt.highest.share <- holt.highest$mean/holt.total

autoplot(holt.lowest.share) + autolayer(holt.second.share) + autolayer(holt.middle.share) + autolayer(holt.fourth.share) + autolayer(holt.highest.share)

Neural Net Prediction

nnar.lowest.tr <- nnetar(tr.lowest.income, lambda=0, boostrap=TRUE)
nnar.second.tr <- nnetar(tr.second.income, lambda=0, boostrap=TRUE)
nnar.middle.tr <- nnetar(tr.middle.income, lambda=0, boostrap=TRUE)
nnar.fourth.tr <- nnetar(tr.fourth.income, lambda=0, boostrap=TRUE)
nnar.highest.tr <- nnetar(tr.highest.income, lambda=0, boostrap=TRUE)
nnar.top.tr <- nnetar(tr.top.income, lambda=0, boostrap=TRUE)

nnar.lowest.pred <- forecast(nnar.lowest.tr, h=4)
nnar.second.pred <- forecast(nnar.second.tr, h=4)
nnar.middle.pred <- forecast(nnar.middle.tr, h=4)
nnar.fourth.pred <- forecast(nnar.fourth.tr, h=4)
nnar.highest.pred <- forecast(nnar.highest.tr, h=4)
nnar.top.pred <- forecast(nnar.top.tr, h=4)
accuracy(nnar.lowest.pred$mean, test.lowest.income)
               ME    RMSE      MAE      MPE     MAPE        ACF1 Theil's U
Test set 2462.223 2603.78 2462.223 6.945758 6.945758 -0.03887182  2.556189
accuracy(nnar.second.pred$mean, test.second.income)
               ME     RMSE      MAE      MPE     MAPE      ACF1 Theil's U
Test set 2783.702 3031.126 2783.702 5.725936 5.725936 0.1557105  2.652865
accuracy(nnar.middle.pred$mean, test.middle.income)
               ME     RMSE      MAE      MPE     MAPE      ACF1 Theil's U
Test set 3502.677 3791.374 3502.677 5.235919 5.235919 0.1179643  2.623366
accuracy(nnar.fourth.pred$mean, test.fourth.income)
               ME     RMSE      MAE      MPE     MAPE       ACF1 Theil's U
Test set 4023.068 4366.748 4023.068 4.303146 4.303146 0.04015834  2.515797
accuracy(nnar.highest.pred$mean, test.highest.income)
               ME     RMSE      MAE      MPE     MAPE       ACF1 Theil's U
Test set 15890.22 16793.13 15890.22 7.142739 7.142739 -0.2020195  2.345393
accuracy(nnar.top.pred$mean, test.top.income)
               ME     RMSE      MAE      MPE     MAPE       ACF1 Theil's U
Test set 161698.9 168829.4 161698.9 12.68541 12.68541 -0.5196279  2.058787
nnar.lowest <- nnetar(lowest.income.ts, lambda=0)
nnar.second <- nnetar(second.income.ts, lambda=0)
nnar.middle <- nnetar(middle.income.ts, lambda=0)
nnar.fourth <- nnetar(fourth.income.ts, lambda=0)
nnar.highest <- nnetar(highest.income.ts, lambda=0)
nnar.top <- nnetar(top.income.ts, lambda=0)

nnar.lowest.forecast <- forecast(nnar.lowest, h=6)
nnar.second.forecast <- forecast(nnar.second, h=6)
nnar.middle.forecast <- forecast(nnar.middle, h=6)
nnar.fourth.forecast <- forecast(nnar.fourth, h=6)
nnar.highest.forecast <- forecast(nnar.highest, h=6)
nnar.top.forecast <- forecast(nnar.top, h=6)

autoplot(income.ts) + autolayer(nnar.lowest.forecast) + autolayer(nnar.second.forecast) + autolayer(nnar.middle.forecast) + autolayer(nnar.fourth.forecast) + autolayer(nnar.highest.forecast) + autolayer(nnar.top.forecast)


autoplot(income.quintile.ts) + autolayer(nnar.lowest.forecast) + autolayer(nnar.second.forecast) + autolayer(nnar.middle.forecast) + autolayer(nnar.fourth.forecast) + autolayer(nnar.highest.forecast)

nnar.lowest$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 
nnar.second$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 
nnar.middle$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 
nnar.fourth$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 
nnar.highest$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 
nnar.top$model

Average of 20 networks, each of which is
a 1-1-1 network with 4 weights
options were - linear output units 

ETS Model Prediction

ets.lowest.tr <- ets(tr.lowest.income, model = "ZZZ", damped = TRUE)
ets.second.tr <- ets(tr.second.income, model = "ZZZ", damped = TRUE)
ets.middle.tr <- ets(tr.middle.income, model = "ZZZ", damped = TRUE)
ets.fourth.tr <- ets(tr.fourth.income, model = "ZZZ", damped = TRUE)
ets.highest.tr <- ets(tr.highest.income, model = "ZZZ", damped = TRUE)
ets.top.tr <- ets(tr.top.income, model = "ZZZ", damped = TRUE)

ets.lowest.pred <- forecast(ets.lowest.tr, h=4)
ets.second.pred <- forecast(ets.second.tr, h=4)
ets.middle.pred <- forecast(ets.middle.tr, h=4)
ets.fourth.pred <- forecast(ets.fourth.tr, h=4)
ets.highest.pred <- forecast(ets.highest.tr, h=4)
ets.top.pred <- forecast(ets.top.tr, h=4)

accuracy(ets.lowest.pred, test.lowest.income)
                     ME      RMSE       MAE       MPE     MAPE      MASE        ACF1 Theil's U
Training set   67.69353  493.0479  395.2248 0.2834461 1.584492 0.7635025  0.02005544        NA
Test set     2273.62567 2402.3208 2273.6257 6.4143967 6.414397 4.3922314 -0.07855079  2.360285
accuracy(ets.second.pred, test.second.income)
                     ME      RMSE       MAE       MPE     MAPE      MASE       ACF1 Theil's U
Training set   74.66658  783.9019  630.9533 0.1992818 1.716390 0.9576969 0.01805541        NA
Test set     2561.35885 2786.2351 2561.3589 5.2689875 5.268987 3.8877768 0.13997401  2.440644
accuracy(ets.middle.pred, test.middle.income)
                    ME      RMSE       MAE      MPE     MAPE      MASE       ACF1 Theil's U
Training set  128.2127  988.2339  764.2019 0.204960 1.435785 0.9804855 0.09440160        NA
Test set     3258.8539 3506.4342 3258.8539 4.873486 4.873486 4.1811711 0.09036617  2.425274
accuracy(ets.fourth.pred, test.fourth.income)
                    ME     RMSE       MAE      MPE     MAPE      MASE        ACF1 Theil's U
Training set  167.1984 1235.070  993.1037 0.193567 1.361671 0.8980193  0.13995767        NA
Test set     3021.8692 3279.399 3021.8692 3.232461 3.232461 2.7325413 -0.06233516  1.894682
accuracy(ets.highest.pred, test.highest.income)
                      ME      RMSE       MAE        MPE     MAPE     MASE        ACF1 Theil's U
Training set    11.99119  9369.749  7706.573 -0.1387739 4.651156 0.916166  0.08861028        NA
Test set     13066.12594 13712.441 13066.126  5.8784281 5.878428 1.553316 -0.40275691  1.897666
accuracy(ets.top.pred, test.top.income)
                     ME     RMSE      MAE       MPE      MAPE      MASE        ACF1 Theil's U
Training set  -5172.071 139396.3 105822.4 -1.786354 12.101286 0.9293220  0.04859916        NA
Test set     107175.498 114933.6 107175.5  8.385228  8.385228 0.9412044 -0.66724907  1.399752
ets.lowest <- ets(lowest.income.ts, model = "ZZZ", damped = TRUE)
ets.second <- ets(second.income.ts, model = "ZZZ", damped = TRUE)
ets.middle <- ets(middle.income.ts, model = "ZZZ", damped = TRUE)
ets.fourth <- ets(fourth.income.ts, model = "ZZZ", damped = TRUE)
ets.highest <- ets(highest.income.ts, model = "ZZZ", damped = TRUE)
ets.top <- ets(top.income.ts, model = "ZZZ", damped = TRUE)

ets.lowest.forecast <- forecast(ets.lowest, h=6)
ets.second.forecast <- forecast(ets.second, h=6)
ets.middle.forecast <- forecast(ets.middle, h=6)
ets.fourth.forecast <- forecast(ets.fourth, h=6)
ets.highest.forecast <- forecast(ets.highest, h=6)
ets.top.forecast <- forecast(ets.top, h=6)

autoplot(income.ts) + autolayer(ets.lowest.forecast) + autolayer(ets.second.forecast) + autolayer(ets.middle.forecast) + autolayer(ets.fourth.forecast) + autolayer(ets.highest.forecast) + autolayer(ets.top.forecast)


autoplot(income.quintile.ts) + autolayer(ets.lowest.forecast) + autolayer(ets.second.forecast) + autolayer(ets.middle.forecast) + autolayer(ets.fourth.forecast) + autolayer(ets.highest.forecast)

ETS BoxCox Model Prediction

ets.lowest.tr.bc <- ets(tr.lowest.income.bc, model = "ZZZ", damped = TRUE)
ets.second.tr.bc <- ets(tr.second.income.bc, model = "ZZZ", damped = TRUE)
ets.middle.tr.bc <- ets(tr.middle.income.bc, model = "ZZZ", damped = TRUE)
ets.fourth.tr.bc <- ets(tr.fourth.income.bc, model = "ZZZ", damped = TRUE)
ets.highest.tr.bc <- ets(tr.highest.income.bc, model = "ZZZ", damped = TRUE)
ets.top.tr.bc <- ets(tr.top.income.bc, model = "ZZZ", damped = TRUE)

ets.lowest.pred.bc <- forecast(ets.lowest.tr.bc, h=4)
ets.second.pred.bc <- forecast(ets.second.tr.bc, h=4)
ets.middle.pred.bc <- forecast(ets.middle.tr.bc, h=4)
ets.fourth.pred.bc <- forecast(ets.fourth.tr.bc, h=4)
ets.highest.pred.bc <- forecast(ets.highest.tr.bc, h=4)
ets.top.pred.bc <- forecast(ets.top.tr.bc, h=4)

accuracy(ets.lowest.pred.bc, test.lowest.income.bc)
                      ME        RMSE         MAE        MPE       MAPE      MASE        ACF1 Theil's U
Training set 0.001434809 0.006837343 0.005397466 0.02275123 0.08497752 0.7196364  0.01515251        NA
Test set     0.023360297 0.024619885 0.023360297 0.36039952 0.36039952 3.1145948 -0.08478199  2.466026
accuracy(ets.second.pred.bc, test.second.income.bc)
                       ME         RMSE          MAE          MPE         MAPE      MASE        ACF1 Theil's U
Training set 2.675884e-07 2.311370e-06 1.729327e-06 0.0000232377 0.0001501737 0.8857415 -0.01774253        NA
Test set     5.104369e-06 5.523659e-06 5.104369e-06 0.0004432496 0.0004432496 2.6143990  0.13950998  2.706167
accuracy(ets.middle.pred.bc, test.middle.income.bc)
                       ME         RMSE          MAE          MPE         MAPE      MASE       ACF1 Theil's U
Training set 2.833987e-08 3.439899e-07 2.296451e-07 2.833839e-06 2.296321e-05 0.8395635 0.01333967        NA
Test set     8.958193e-07 9.600636e-07 8.958193e-07 8.957648e-05 8.957648e-05 3.2750405 0.11187922  2.906027
accuracy(ets.fourth.pred.bc, test.fourth.income.bc)
                       ME         RMSE          MAE          MPE         MAPE      MASE       ACF1 Theil's U
Training set 5.917907e-09 2.277304e-07 1.697673e-07 5.917476e-07 1.697568e-05 0.8270893  0.1269625        NA
Test set     2.809025e-07 3.044669e-07 2.809025e-07 2.808842e-05 2.808842e-05 1.3685286 -0.1954513  1.513859
accuracy(ets.highest.pred.bc, test.highest.income.bc)
                        ME         RMSE          MAE           MPE        MAPE      MASE          ACF1 Theil's U
Training set -5.764992e-07 0.0002342864 0.0001977486 -2.669651e-05 0.008966746 0.8870168  0.0007019257        NA
Test set      2.188484e-04 0.0002279673 0.0002188484  9.917201e-03 0.009917201 0.9816620 -0.5262543553  1.794629
accuracy(ets.top.pred.bc, test.top.income.bc)
                        ME         RMSE          MAE           MPE        MAPE      MASE        ACF1 Theil's U
Training set -5.659374e-06 1.845866e-04 1.513110e-04 -0.0002766285 0.007389997 0.8948504 -0.01561312        NA
Test set      3.964055e-05 5.132096e-05 4.757256e-05  0.0019354579 0.002322751 0.2813432 -0.51602528 0.7041449
ets.lowest.bc <- ets(lowest.ts.bc, model = "ZZZ", damped = TRUE)
ets.second.bc <- ets(second.ts.bc, model = "ZZZ", damped = TRUE)
ets.middle.bc <- ets(middle.ts.bc, model = "ZZZ", damped = TRUE)
ets.fourth.bc <- ets(fourth.ts.bc, model = "ZZZ", damped = TRUE)
ets.highest.bc <- ets(highest.ts.bc, model = "ZZZ", damped = TRUE)
ets.top.bc <- ets(top.ts.bc, model = "ZZZ", damped = TRUE)

ets.lowest.forecast.bc <- forecast(ets.lowest.bc, h=6)
ets.second.forecast.bc <- forecast(ets.second.bc, h=6)
ets.middle.forecast.bc <- forecast(ets.middle.bc, h=6)
ets.fourth.forecast.bc <- forecast(ets.fourth.bc, h=6)
ets.highest.forecast.bc <- forecast(ets.highest.bc, h=6)
ets.top.forecast.bc <- forecast(ets.top.bc, h=6)

accuracy(ets.lowest.bc)
                     ME       RMSE         MAE        MPE       MAPE     MASE       ACF1
Training set 0.00156607 0.00720561 0.005766345 0.02475689 0.09050821 0.755832 0.07646825
accuracy(ets.second.bc)
                       ME        RMSE          MAE          MPE         MAPE     MASE       ACF1
Training set 7.232454e-07 2.22369e-06 1.631265e-06 6.280604e-05 0.0001416578 0.837977 -0.1018189
accuracy(ets.middle.bc)
                       ME         RMSE          MAE          MPE         MAPE     MASE      ACF1
Training set 4.893851e-08 3.395959e-07 2.394733e-07 4.893567e-06 2.394596e-05 0.856803 0.1096092
accuracy(ets.fourth.bc)
                       ME         RMSE          MAE          MPE         MAPE     MASE      ACF1
Training set 8.941874e-09 2.208425e-07 1.652104e-07 8.941233e-07 1.652001e-05 0.813465 0.1152623
accuracy(ets.highest.bc)
                       ME        RMSE          MAE          MPE        MAPE      MASE         ACF1
Training set 1.994842e-06 0.000225105 0.0001878442 8.980116e-05 0.008517329 0.8756187 -0.001696444
accuracy(ets.top.bc)
                        ME        RMSE          MAE           MPE        MAPE      MASE        ACF1
Training set -4.643829e-06 0.000175768 0.0001410983 -0.0002270292 0.006891139 0.8808617 -0.01285064

After looking at the accuracy of all the models, we determine the ARIMA model to be the best at forecasting the bottom two distributions and the linear holt model to bet the best at forecasting the rest. While the ETS model was better at capturing the existing data, the ARIMA model had lower RMSE scores regarding the test set. As the purpose of this project is to forecast distribution rather than understand previous income distributions, we will use the ARIMA model. Going off of this, the Holt model had better test set RMSE than the ARIMA model from the middle quintile onward. It should be noted that the non-damped linear Holt method has the tendency to over-cast. That said, it should be no surprise to find that the increase in trend for the highest quintile or the top 1% overperforms any model. It is also interesting to note that the ARIMA model works best on the two quintiles with the most obvious and steady trend, where the forecast for time T is usually highly correlated with the observation at time T-1 as the ARIMA model does, while the higher income quintiles are more accurately forecast using an underlying trend shown by the Linear Holt model. (ARIMA was used across the board in the first draft, so downloaded data names reflect this. I will attempt to fix this going forward)

Full Data Set

arima_income_data <- read_excel("arima_income_data.xlsx")
Error in read_excel("arima_income_data.xlsx") : 
  could not find function "read_excel"
final.lowest.income <- arima_income_data$`Lowest Quantile`
final.second.income <- arima_income_data$`Second Quantile`
final.middle.income <- arima_income_data$`Middle Quantile`
final.fourth.income <- arima_income_data$`Fourth Quantile`
final.highest.income <- arima_income_data$`Highest Quantile`
final.80.income <- arima_income_data$`0.8`
final.90.income <- arima_income_data$`0.9`
final.96.income <- arima_income_data$`0.96`

final.top.income <- arima_income_data$`Top Quantile`


final.lowest.income.ts <- ts(final.lowest.income, start=1979, frequency=1)
final.second.income.ts <- ts(final.second.income, start=1979, frequency=1)
final.middle.income.ts <- ts(final.middle.income, start=1979, frequency=1)
final.fourth.income.ts <- ts(final.fourth.income, start=1979, frequency=1)
final.highest.income.ts <- ts(final.highest.income, start=1979, frequency=1)
final.80.income.ts <- ts(final.80.income, start=1979, frequency=1)
final.90.income.ts <- ts(final.90.income, start=1979, frequency=1)
final.96.income.ts <- ts(final.96.income, start=1979, frequency=1)
final.top.income.ts <- ts(final.top.income, start=1979, frequency=1)
corr.arima.income <- cor(arima_income_data)
corrplot(corr.arima.income, method=c("number"))

income.final.ts <- ts(arima_income_data, start=1979, frequency=1)
autoplot(income.final.ts)

Best Model

final.lowest <- auto.arima(final.lowest.income.ts, seasonal = FALSE)
final.second <- auto.arima(final.second.income.ts, seasonal = FALSE)
final.middle <- auto.arima(final.middle.income.ts, seasonal = FALSE)
final.fourth <- auto.arima(final.fourth.income.ts, seasonal = FALSE)
final.highest <- auto.arima(final.highest.income.ts, seasonal = FALSE)
final.80 <- auto.arima(final.80.income.ts, seasonal = FALSE)
final.90 <- auto.arima(final.90.income.ts, seasonal = FALSE)
final.96 <- auto.arima(final.96.income.ts, seasonal = FALSE)
final.top <- auto.arima(final.top.income.ts, seasonal = FALSE)

final.lowest.forecast <- forecast(final.lowest, h=6)
final.second.forecast <- forecast(final.second, h=6)
final.middle.forecast <- forecast(final.middle, h=6)
final.fourth.forecast <- forecast(final.fourth, h=6)
final.highest.forecast <- forecast(final.highest, h=6)
final.80.forecast <- forecast(final.80, h=6)
final.90.forecast <- forecast(final.90, h=6)
final.96.forecast <- forecast(final.96, h=6)
final.top.forecast <- forecast(final.top, h=6)


autoplot(income.final.ts, main = "Best Quantile Forecast") + autolayer(final.lowest.forecast) + autolayer(final.second.forecast) + autolayer(final.middle.forecast) + autolayer(final.fourth.forecast) + autolayer(final.80.forecast) + autolayer(final.90.forecast) + autolayer(final.96.forecast) + autolayer(final.top.forecast)


autoplot(income.quintile.ts, main = "Best Quintile Forecast") + autolayer(final.lowest.forecast) + autolayer(final.second.forecast) + autolayer(final.middle.forecast) + autolayer(final.fourth.forecast) + autolayer(final.highest.forecast)

NA
NA

ARIMA Distribution Forecast

final.total.forecast <- final.lowest.forecast$mean + final.second.forecast$mean + final.middle.forecast$mean + final.fourth.forecast$mean + final.80.forecast$mean + final.90.forecast$mean + final.96.forecast$mean + final.top.forecast$mean

final.lowest.forecast.share <- final.lowest.forecast$mean/final.total.forecast
final.second.forecast.share <- final.second.forecast$mean/final.total.forecast
final.middle.forecast.share <- final.middle.forecast$mean/final.total.forecast
final.fourth.forecast.share <- final.fourth.forecast$mean/final.total.forecast
final.80.forecast.share <- final.80.forecast$mean/final.total.forecast
final.90.forecast.share <- final.90.forecast$mean/final.total.forecast
final.96.forecast.share <- final.96.forecast$mean/final.total.forecast
final.top.forecast.share <- final.top.forecast$mean/final.total.forecast

autoplot(final.lowest.forecast.share) + autolayer(final.second.forecast.share) + autolayer(final.middle.forecast.share) + autolayer(final.fourth.forecast.share) + autolayer(final.80.forecast.share) + autolayer(final.90.forecast.share) + autolayer(final.96.forecast.share) + autolayer(final.top.forecast.share)


final.total.forecast.quintile <- final.lowest.forecast$mean + final.second.forecast$mean + final.middle.forecast$mean + final.fourth.forecast$mean + final.highest.forecast$mean

final.lowest.forecast.share.quintile <- final.lowest.forecast$mean/final.total.forecast.quintile
final.second.forecast.share.quintile <- final.second.forecast$mean/final.total.forecast.quintile
final.middle.forecast.share.quintile <- final.middle.forecast$mean/final.total.forecast.quintile
final.fourth.forecast.share.quintile <- final.fourth.forecast$mean/final.total.forecast.quintile
final.highest.forecast.share.quintile <- final.highest.forecast$mean/final.total.forecast.quintile

autoplot(final.lowest.forecast.share.quintile, main = "Quintile Share Forecast") + autolayer(final.second.forecast.share.quintile) + autolayer(final.middle.forecast.share.quintile) + autolayer(final.fourth.forecast.share.quintile) + autolayer(final.highest.forecast.share.quintile)

With the most accurate forecasts of income in the future, we see that the highest quintile will only capture a larger and larger share of total GDP in the US, with all other quintiles decreasing over time. This trend is further worrying given that the decomposed highest quintile forecast shows that all of this positive relative trend is associated with the top 1% of incomes. We even see the top 1% outclassing the gains in every other quantile including that which makes up the rest of the highest quantile such that even those will decrease as a share of total income over time.


holt.80 <- forecast(final.80.income.ts, h=6)
holt.90 <- forecast(final.90.income.ts, h=6)
holt.96 <- forecast(final.96.income.ts, h=6)

holt.total <- final.lowest.forecast$mean + final.second.forecast$mean + final.middle.forecast$mean + holt.fourth$mean + holt.80$mean + holt.90$mean + holt.96$mean + holt.top$mean

holt.lowest.share <- final.lowest.forecast$mean/holt.total
holt.second.share <- final.second.forecast$mean/holt.total
holt.middle.share <- final.middle.forecast$mean/holt.total
holt.fourth.share <- holt.fourth$mean/holt.total
holt.80.share <- holt.80$mean/holt.total
holt.90.share <- holt.90$mean/holt.total
holt.96.share <- holt.96$mean/holt.total
holt.top.share <- holt.top$mean/holt.total

autoplot(holt.lowest.share) + autolayer(holt.second.share) + autolayer(holt.middle.share) + autolayer(holt.fourth.share) + autolayer(holt.80.share) + autolayer(holt.90.share) + autolayer(holt.96.share) + autolayer(holt.top.share)

Using the linear Holt model, which was the best at forecasting over the short-term horizon for the fourth quantile and above, we see that while the increase in the share of total income is not felt by the top 1%, the middle quintiles and lower are all losing total GDP share. We see that decomposing the top 1% alters the share chart wildly.

final.total <- final.lowest.forecast$mean + final.second.forecast$mean + final.middle.forecast$mean + holt.fourth$mean + holt.highest$mean

holt.lowest.share <- final.lowest.forecast$mean/final.total
holt.second.share <- final.second.forecast$mean/final.total
holt.middle.share <- final.middle.forecast$mean/final.total
holt.fourth.share <- holt.fourth$mean/final.total
holt.highest.share <- holt.highest$mean/final.total

autoplot(holt.lowest.share) + autolayer(holt.second.share) + autolayer(holt.middle.share) + autolayer(holt.fourth.share) + autolayer(holt.highest.share)

UBI Analysis

Data Preparation

ubi.add <- c(3554.18, 3554.18, 4450.07, 4450.07, 4875.98, 4875.98, 5267.62, 5267.62, 5561.36, 5561.36, 6070.50, 6070.50, 6667.75, 6667.75, 7074.09, 7074.09, 7460.84, 7460.84, 7857.38, 7857.38, 8156.01, 8156.01, 8665.14, 8665.14, 9007.83, 9007.83, 9561.03, 9561.03, 10150.55, 10150.55, 10502.79, 10502.79, 11012.03, 11012.03, 11404.55, 11404.55, 11603.31, 11603.31, 12000)

ubi.income <- income_data + ubi.add

This is based off of Democratic 2020 Candidate Andrew Yang’s proposed $1,000 a month proposal for a Universal Basic Income.

ubi.lowest.income <- ubi.income$`Lowest Quintile`
ubi.second.income <- ubi.income$`Second Quintile`
ubi.middle.income <- ubi.income$`Middle Quintile`
ubi.fourth.income <- ubi.income$`Fourth Quintile`
ubi.highest.income <- ubi.income$`Highest Quintile`
ubi.top.income <- ubi.income$`Top 1%`

ubi.income.ts <- ts(ubi.income, start=1979, end=2017, frequency = 1)
ubi.income.quintile.ts <- ts(ubi.income[1:5], start=1979, end=2017, frequency = 1)

lowest.ts.ubi <- ts(ubi.lowest.income, start=1979, frequency=1)
second.ts.ubi <- ts(ubi.second.income, start=1979, frequency=1)
middle.ts.ubi <- ts(ubi.middle.income, start=1979, frequency=1)
fourth.ts.ubi <- ts(ubi.fourth.income, start=1979, frequency=1)
highest.ts.ubi <- ts(ubi.highest.income, start=1979, frequency=1)
top.ts.ubi <- ts(ubi.top.income, start=1979, frequency=1)
ubi.lowest <- auto.arima(lowest.ts.ubi, seasonal = FALSE)
ubi.second <- auto.arima(second.ts.ubi, seasonal = FALSE)
ubi.middle <- auto.arima(middle.ts.ubi, seasonal = FALSE)
ubi.fourth <- auto.arima(fourth.ts.ubi, seasonal = FALSE)
ubi.highest <- auto.arima(highest.ts.ubi, seasonal = FALSE)
ubi.top <- auto.arima(top.ts.ubi, seasonal = FALSE)


ubi.lowest.forecast <- forecast(ubi.lowest, h=6)
ubi.second.forecast <- forecast(ubi.second, h=6)
ubi.middle.forecast <- forecast(ubi.middle, h=6)
ubi.fourth.forecast <- forecast(ubi.fourth, h=6)
ubi.highest.forecast <- forecast(ubi.highest, h=6)
ubi.top.forecast <- forecast(ubi.top, h=6)

autoplot(ubi.income.quintile.ts) + autolayer(ubi.lowest.forecast) + autolayer(ubi.second.forecast) + autolayer(ubi.middle.forecast) + autolayer(ubi.fourth.forecast) + autolayer(ubi.highest.forecast)

total.forecast.ubi <- ubi.lowest.forecast$mean + ubi.second.forecast$mean + ubi.middle.forecast$mean + ubi.fourth.forecast$mean + ubi.highest.forecast$mean

lowest.share <- ubi.lowest.forecast$mean/total.forecast.ubi
second.share <- ubi.second.forecast$mean/total.forecast.ubi
middle.share <- ubi.middle.forecast$mean/total.forecast.ubi
fourth.share <- ubi.fourth.forecast$mean/total.forecast.ubi
highest.share <- ubi.highest.forecast$mean/total.forecast.ubi

autoplot(lowest.share, main = "UBI Share Forecast") + autolayer(second.share) + autolayer(middle.share) + autolayer(fourth.share) + autolayer(highest.share)

We see that the gains in the highest quintile still outclass those of the other four combined. Thus, by quantitative standards, we can assume that while the UBI may address immediate shortcomings in the minimum required income to survive, it will not address income inequality over the long term, given the gains by the highest quintile.

arima.lowest.forecast.ubi.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.08906718 0.08905152 0.08903628 0.08902145 0.08900700 0.08899292
arima.second.forecast.ubi.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1136310 0.1132679 0.1129144 0.1125703 0.1122352 0.1119087
middle.forecast.ubi.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1480268 0.1472922 0.1465772 0.1458811 0.1452032 0.1445427
fourth.forecast.ubi.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1978855 0.1971670 0.1964678 0.1957870 0.1951240 0.1944781
highest.forecast.ubi.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.4513895 0.4532214 0.4550043 0.4567401 0.4584306 0.4600776

Targeted UBI Analysis

ubi.lowest.income <- ubi.income$`Lowest Quintile`
ubi.second.income <- ubi.income$`Second Quintile`
ubi.middle.income <- ubi.income$`Middle Quintile`

ubi.income.ts <- ts(ubi.income, start=1979, end=2017, frequency = 1)
ubi.income.quintile.ts <- ts(ubi.income, start=1979, end=2017, frequency = 1)

lowest.ts.ubi <- ts(ubi.lowest.income, start=1979, frequency=1)
second.ts.ubi <- ts(ubi.second.income, start=1979, frequency=1)
middle.ts.ubi <- ts(ubi.middle.income, start=1979, frequency=1)

ubi.income.target.ts <- cbind(ubi.income.quintile.ts, fourth.income.ts, highest.income.ts)

ubi.lowest <- auto.arima(lowest.ts.ubi, seasonal = FALSE)
ubi.second <- auto.arima(second.ts.ubi, seasonal = FALSE)
ubi.middle <- auto.arima(middle.ts.ubi, seasonal = FALSE)

ubi.lowest.forecast <- forecast(ubi.lowest, h=6)
ubi.second.forecast <- forecast(ubi.second, h=6)
ubi.middle.forecast <- forecast(ubi.middle, h=6)

autoplot(ubi.income.quintile.ts) + autolayer(ubi.lowest.forecast) + autolayer(ubi.second.forecast) + autolayer(ubi.middle.forecast) + autolayer(holt.fourth) + autolayer(holt.highest) + autolayer(holt.top)


total.forecast.ubi <- ubi.lowest.forecast$mean + ubi.second.forecast$mean + ubi.middle.forecast$mean + holt.fourth$mean + holt.highest$mean

lowest.share <- ubi.lowest.forecast$mean/total.forecast.ubi
second.share <- ubi.second.forecast$mean/total.forecast.ubi
middle.share <- ubi.middle.forecast$mean/total.forecast.ubi
fourth.share <- holt.fourth$mean/total.forecast.ubi
highest.share <- holt.highest$mean/total.forecast.ubi

autoplot(lowest.share, main = "UBI Share Forecast") + autolayer(second.share) + autolayer(middle.share) + autolayer(fourth.share) + autolayer(highest.share)

lowest.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.09369943 0.09415455 0.09461059 0.09506748 0.09552515 0.09598353
second.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1195408 0.1197586 0.1199837 0.1202157 0.1204544 0.1206994
middle.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1558476 0.1559747 0.1561140 0.1562649 0.1564268 0.1565993
fourth.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1841021 0.1836621 0.1832237 0.1827869 0.1823517 0.1819181
highest.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.4468101 0.4464501 0.4460680 0.4456650 0.4452419 0.4447997

A targeted UBI does in fact assist income inequality, but still at a reduced speed. The gains made by the highest quantile are still statistically significant.

We can also see what would have happened between 1979-2017 had a UBI been implemented.

total.time.ubi <- ubi.lowest.income + ubi.second.income + ubi.middle.income + fourth.income.ts + highest.income.ts

lowest.share.time <- ubi.lowest.income/total.time.ubi
second.share.time <- ubi.second.income/total.time.ubi
middle.share.time <- ubi.middle.income/total.time.ubi
fourth.share.time <- fourth.income.ts/total.time.ubi
highest.share.time <- highest.income.ts/total.time.ubi

autoplot(lowest.share.time, main = "UBI Share Forecast") + autolayer(second.share.time) + autolayer(middle.share.time) + autolayer(fourth.share.time) + autolayer(highest.share.time)

Wall Street Hypothesis

We often also hear that higher-income individuals are better able to utilize savings and capital to earn income thanks to their ability to tap into the growth in the stock market. Here, we check if the S&P 500 data can be used as an indicator for the higher income quantiles’ time series.

S_P_income <- read_excel("S&P_income.xlsx")
Error in read_excel("S&P_income.xlsx") : 
  could not find function "read_excel"

Data Preparation

wall.lowest.income <- S_P_income$`Lowest Quantile`
wall.second.income <- S_P_income$`Second Quantile`
wall.middle.income <- S_P_income$`Middle Quantile`
wall.fourth.income <- S_P_income$`Fourth Quantile`
wall.highest.income <- S_P_income$`Highest Quantile`
wall.top.income <- S_P_income$`Top Quantile`
wall.data <- S_P_income$`S&P`

lowest.ts.wall <- ts(wall.lowest.income, start=1979, frequency=1)
second.ts.wall <- ts(wall.second.income, start=1979, frequency=1)
middle.ts.wall <- ts(wall.middle.income, start=1979, frequency=1)
fourth.ts.wall <- ts(wall.fourth.income, start=1979, frequency=1)
highest.ts.wall <- ts(wall.highest.income, start=1979, frequency=1)
top.ts.wall <- ts(wall.top.income, start=1979, frequency=1)
wall.ts <- ts(wall.data, start=1979, frequency=1)
corr.fin.income <- cor(S_P_income)
corrplot(corr.fin.income, method=c("number"))

arima.wall.lowest <- auto.arima(lowest.ts.wall, xreg = wall.data, seasonal = FALSE)
arima.wall.second <- auto.arima(second.ts.wall, xreg = wall.data, seasonal = FALSE)
arima.wall.middle <- auto.arima(middle.ts.wall, xreg = wall.data, seasonal = FALSE)
arima.wall.fourth <- auto.arima(fourth.ts.wall, xreg = wall.data, seasonal = FALSE)
arima.wall.highest <- auto.arima(highest.ts.wall, xreg = wall.data, seasonal = FALSE)
arima.wall.top <- auto.arima(top.ts.wall, xreg = wall.data, seasonal = FALSE)

accuracy(arima.wall.lowest)
                   ME     RMSE      MAE       MPE     MAPE      MASE        ACF1
Training set 175.0316 560.7516 461.7201 0.6081286 1.758627 0.8354935 -0.07548672
accuracy(arima.wall.second)
                   ME     RMSE     MAE       MPE     MAPE     MASE        ACF1
Training set 217.9078 804.8531 659.767 0.4838463 1.752184 0.946081 -0.03433632
accuracy(arima.wall.middle)
                   ME     RMSE      MAE       MPE     MAPE      MASE      ACF1
Training set 219.9965 964.7754 701.5357 0.3490868 1.280456 0.8304785 -0.101025
accuracy(arima.wall.fourth)
                   ME     RMSE      MAE       MPE     MAPE      MASE       ACF1
Training set 302.6678 1086.335 868.7847 0.3721168 1.153087 0.7537401 0.08575985
accuracy(arima.wall.highest)
                  ME     RMSE      MAE      MPE     MAPE      MASE       ACF1
Training set 1293.82 8685.012 6684.117 0.479861 3.982206 0.7994852 -0.1074442
accuracy(arima.wall.top)
                   ME     RMSE      MAE       MPE     MAPE      MASE        ACF1
Training set 4856.026 122223.1 89124.74 -1.900682 10.38019 0.7962992 -0.09829954
accuracy(arima.lowest)
                  ME     RMSE      MAE       MPE     MAPE      MASE       ACF1
Training set 6.63326 507.5138 409.2322 -0.059196 1.582477 0.7405154 0.02734329
accuracy(arima.second)
                    ME     RMSE      MAE         MPE     MAPE      MASE      ACF1
Training set 0.8351548 769.6023 607.8527 -0.09022095 1.607966 0.8716378 0.2094412
accuracy(arima.middle)
                   ME     RMSE      MAE         MPE     MAPE     MASE        ACF1
Training set 17.50649 919.0583 709.7766 -0.01022993 1.291981 0.840234 -0.05041771
accuracy(arima.fourth)
                   ME    RMSE      MAE         MPE     MAPE      MASE      ACF1
Training set 1.562347 1156.54 938.4045 -0.04101257 1.237995 0.8141408 0.2263137
accuracy(arima.highest)
                   ME     RMSE      MAE        MPE     MAPE      MASE       ACF1
Training set 2.708163 9078.275 7290.158 -0.1733283 4.262883 0.8719735 0.04509386
accuracy(arima.top)
                   ME     RMSE      MAE     MPE     MAPE      MASE        ACF1
Training set 24909.54 137315.7 109063.4 2.26348 11.95632 0.9744442 -0.09189933

Interestingly, using historical S&P 500 data as contributing factor only helps the accuracy of the model for the fourth distribution and higher.

wall.data.arima <- auto.arima(wall.data, seasonal = FALSE)
wall.data.forecast <- forecast(wall.data.arima, h=6)
wall.data.pred <- wall.data.forecast$mean

arima.wall.fourth.forecast <- forecast(arima.wall.fourth, xreg = wall.data.pred, h=6)
arima.wall.highest.forecast <- forecast(arima.wall.highest, xreg = wall.data.pred, h=6)
arima.wall.top.forecast <- forecast(arima.wall.top, xreg = wall.data.pred, h=6)

autoplot(income.ts) + autolayer(arima.lowest.forecast) + autolayer(arima.second.forecast) + autolayer(arima.middle.forecast) + autolayer(arima.wall.fourth.forecast) + autolayer(arima.wall.highest.forecast) + autolayer(arima.wall.top.forecast)


autoplot(income.quintile.ts) + autolayer(arima.lowest.forecast) + autolayer(arima.second.forecast) + autolayer(arima.middle.forecast) + autolayer(arima.wall.fourth.forecast) + autolayer(arima.wall.highest.forecast)

Share of Total GDP after S&P Regression

arima.total.forecast.wall <- arima.lowest.forecast$mean + arima.second.forecast$mean + arima.middle.forecast$mean + arima.wall.fourth.forecast$mean + arima.wall.highest.forecast$mean

arima.lowest.forecast.wall.share <- arima.lowest.forecast$mean/arima.total.forecast.wall
arima.second.forecast.wall.share <- arima.second.forecast$mean/arima.total.forecast.wall
arima.middle.forecast.wall.share <- arima.middle.forecast$mean/arima.total.forecast.wall
arima.fourth.forecast.wall.share <- arima.wall.fourth.forecast$mean/arima.total.forecast.wall
arima.highest.forecast.wall.share <- arima.wall.highest.forecast$mean/arima.total.forecast.wall

autoplot(arima.lowest.forecast.wall.share) + autolayer(arima.second.forecast.wall.share) + autolayer(arima.middle.forecast.wall.share) + autolayer(arima.fourth.forecast.wall.share) + autolayer(arima.highest.forecast.wall.share)

UBO Hypothesis

earnings <- S_P_income$`S&P Earnings`
n.shares <- 3554.18/wall.ts[1]
n.shares
[1] 32.92737

Using Andrew Yang’s $12,000/year initial offer, we assume the equivalent amount of buying power for the 1979 and calculate earnings per year based on the number of shares bought, assuming the entire portfolio is purely in the S&P 500.

ubo.ts <- earnings*32.92737
snp.difference <- tail(ubo.ts, n=38L)
ubo <- c(3554.18, snp.difference)

Data Preparation

lowest.ts.ubo <- lowest.income.ts + ubo
second.ts.ubo <- second.income.ts + ubo
middle.ts.ubo <- middle.income.ts + ubo

ubo.income <- cbind(lowest.ts.ubo, second.ts.ubo, middle.ts.ubo, fourth.income.ts, final.80.income.ts, final.90.income.ts, final.96.income.ts, final.top.income.ts)
ubo.income.quintile <- cbind(lowest.ts.ubo, second.ts.ubo, middle.ts.ubo, fourth.income.ts, highest.income.ts)

arima.ubo.lowest <- auto.arima(lowest.ts.ubo, xreg = wall.data, seasonal = FALSE)
arima.ubo.second <- auto.arima(second.ts.ubo, xreg = wall.data, seasonal = FALSE)
arima.ubo.middle <- auto.arima(middle.ts.ubo, xreg = wall.data, seasonal = FALSE)
arima.ubo.lowest.forecast <- forecast(arima.ubo.lowest, xreg = wall.data.pred, h=6)
arima.ubo.second.forecast <- forecast(arima.ubo.second, xreg = wall.data.pred, h=6)
arima.ubo.middle.forecast <- forecast(arima.ubo.middle, xreg = wall.data.pred, h=6)

autoplot(ubo.income) + autolayer(arima.ubo.lowest.forecast) + autolayer(arima.ubo.second.forecast) + autolayer(arima.ubo.middle.forecast) + autolayer(final.fourth.forecast) + autolayer(final.80.forecast) + autolayer(final.90.forecast) + autolayer(final.96.forecast) + autolayer(final.top.forecast)


autoplot(ubo.income.quintile, main = "UBO Quantile Forecast") + autolayer(arima.ubo.lowest.forecast) + autolayer(arima.ubo.second.forecast) + autolayer(arima.ubo.middle.forecast) + autolayer(final.fourth.forecast) + autolayer(final.highest.forecast)

Summary of UBO Models

summary(arima.ubo.lowest)
Series: lowest.ts.ubo 
Regression with ARIMA(0,0,0) errors 

Coefficients:
      intercept     xreg
      18072.522  11.1674
s.e.   1278.944   1.1246

sigma^2 estimated as 23103318:  log likelihood=-384.94
AIC=775.89   AICc=776.57   BIC=780.88

Training set error measures:
                      ME     RMSE      MAE       MPE     MAPE      MASE      ACF1
Training set 2.47765e-09 4681.723 3149.849 -3.416752 12.76711 0.6796663 0.1692944
summary(arima.ubo.second)
Series: second.ts.ubo 
Regression with ARIMA(0,0,0) errors 

Coefficients:
      intercept     xreg
      30315.487  11.7775
s.e.   1197.411   1.0529

sigma^2 estimated as 20251536:  log likelihood=-382.38
AIC=770.75   AICc=771.44   BIC=775.74

Training set error measures:
                       ME     RMSE      MAE       MPE    MAPE      MASE       ACF1
Training set 1.036796e-08 4383.263 2966.502 -1.188202 7.45201 0.6295592 0.08259339
summary(arima.ubo.middle)
Series: middle.ts.ubo 
Regression with ARIMA(0,0,0) errors 

Coefficients:
      intercept     xreg
      45306.898  13.4287
s.e.   1171.823   1.0304

sigma^2 estimated as 19395276:  log likelihood=-381.53
AIC=769.07   AICc=769.75   BIC=774.06

Training set error measures:
                       ME     RMSE      MAE        MPE     MAPE      MASE      ACF1
Training set 1.015201e-08 4289.597 3017.454 -0.5519901 5.259434 0.6429931 0.1093753

What we can unfortunately see from the models, which has positives and negatives, is that the best model to capture the distributions exposed to the proposed UBO is an ARIMA(0, 0, 0), a white noise model with the only meaningful variable being the stock market data. The obvious negative is that any individual’s income is more closely tied to the stock market(S&P 500, for our purposes) than their own earned income. On the other hand, this was always true for the higher-income quintiles, as we see that the standard ARIMA model increases accuracy when S&P 500 data is included as a independent variable for the fourth income distribution and higher. While the means by which the higher income distributions utilize the stock market to increase wealth is beyond the scope of this paper, the correlation between market gains and the highest income distributions is noticed.

UBO Share Forecast

total.forecast.ubo <- arima.ubo.lowest.forecast$mean + arima.ubo.second.forecast$mean + arima.ubo.middle.forecast$mean + final.fourth.forecast$mean + final.highest.forecast$mean

arima.ubo.lowest.forecast.wall.share <- arima.ubo.lowest.forecast$mean/total.forecast.ubo
arima.ubo.second.forecast.wall.share <- arima.ubo.second.forecast$mean/total.forecast.ubo
arima.ubo.middle.share <- arima.ubo.middle.forecast$mean/total.forecast.ubo
final.ubo.fourth.share <- final.fourth.forecast$mean/total.forecast.ubo
final.ubo.highest.share <- final.highest.forecast$mean/total.forecast.ubo

autoplot(arima.ubo.lowest.forecast.wall.share) + autolayer(arima.ubo.second.forecast.wall.share) + autolayer(arima.ubo.middle.share) + autolayer(final.ubo.fourth.share) + autolayer(final.ubo.highest.share)

This may indicate that the gains made by the highest quintile still outperform the lower quintile’s exposure to the market. That said, the assumption is purely based on the return of the S&P, and the model may change after taking into account the increased taxes proposed by progressive aimed at the highest income distributions.

total.forecast.ubo <- arima.ubo.lowest.forecast$mean + arima.ubo.second.forecast$mean + arima.ubo.middle.forecast$mean + holt.fourth$mean + holt.highest$mean

lowest.ubo.share <- arima.ubo.lowest.forecast$mean/total.forecast.ubo
second.ubo.share <- arima.ubo.second.forecast$mean/total.forecast.ubo
middle.ubo.share <- arima.ubo.middle.forecast$mean/total.forecast.ubo
fourth.ubo.share <- holt.fourth$mean/total.forecast.ubo
highest.ubo.share <- holt.highest$mean/total.forecast.ubo

autoplot(lowest.ubo.share, main = "UBO Share Forecast") + autolayer(second.ubo.share) + autolayer(middle.ubo.share) + autolayer(fourth.ubo.share) + autolayer(highest.ubo.share)

It should be noted that depending on the model used for the highest quintile, the effect of the UBO on income mobility changes. Further, reating the top 1% as its own quantile separate from the others including the highest quintile shows that every quantile would steadily move towards hire shares of total income over time despite the large gains made by the top 1%, though the change is minimal. And again, the UBO model under consideration can be considered a minimum value, as this is the value used for immediate income substitution and is far cheaper than Andrew Yang’s proposed UBI.

lowest.ubo.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.09355706 0.09412448 0.09469011 0.09525397 0.09581610 0.09637651
second.ubo.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1202985 0.1206962 0.1210977 0.1215027 0.1219110 0.1223224
middle.ubo.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1578057 0.1580676 0.1583392 0.1586199 0.1589093 0.1592070
fourth.ubo.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1833511 0.1827875 0.1822283 0.1816734 0.1811227 0.1805759
highest.ubo.share
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.4449876 0.4443242 0.4436447 0.4429501 0.4422409 0.4415181

The targeted UBO does a comparable job of shifting income inequality as the targeted UBO does, but I show that it costs a fraction of the price of the UBI.

We can also view the change in total share over the time period of 1979-2017.

ubo.time.total <- lowest.ts.ubo + second.ts.ubo + middle.ts.ubo + fourth.income.ts + highest.income.ts

lowest.ubo.time.share <- lowest.ts.ubo/ubo.time.total
second.ubo.time.share <- second.ts.ubo/ubo.time.total
middle.ubo.time.share <- middle.ts.ubo/ubo.time.total
fourth.ubo.time.share <- fourth.income.ts/ubo.time.total
highest.ubo.time.share <- highest.income.ts/ubo.time.total

autoplot(lowest.ubo.time.share, main = "UBO Share Forecast Over 1979-2017") + autolayer(second.ubo.time.share) + autolayer(middle.ubo.time.share) +  autolayer(fourth.ubo.time.share) + autolayer(fourth.ubo.time.share) + autolayer(highest.ubo.time.share)

Individual UBO Proposal

ubo.ts.2 <- earnings*32.92737*1.9
snp.difference.2 <- tail(ubo.ts.2, n=38L)
ubo.2 <- c(2961.81, snp.difference.2)

Based off the average number of children per household in the US. The previous example was that of a single child born to certain income quantiles–the assumption being that every household has a single child. This proposal will be based off of the average number of children born per household (1.9) in 1979. Thus, we will be calculating that each benefitting household will receive 1.9 times the benefits of a UBO.

lowest.ts.ubo.2 <- lowest.income.ts + ubo.2
second.ts.ubo.2 <- second.income.ts + ubo.2
middle.ts.ubo.2 <- middle.income.ts + ubo.2

ubo.income.quintile.2 <- cbind(lowest.ts.ubo.2, second.ts.ubo.2, middle.ts.ubo.2, fourth.income.ts, highest.income.ts)

arima.ubo.lowest.2 <- auto.arima(lowest.ts.ubo.2, xreg = wall.data, seasonal = FALSE)
arima.ubo.second.2 <- auto.arima(second.ts.ubo.2, xreg = wall.data, seasonal = FALSE)
arima.ubo.middle.2 <- auto.arima(middle.ts.ubo.2, xreg = wall.data, seasonal = FALSE)
arima.ubo.lowest.forecast.2 <- forecast(arima.ubo.lowest.2, xreg = wall.data.pred, h=6)
arima.ubo.second.forecast.2 <- forecast(arima.ubo.second.2, xreg = wall.data.pred, h=6)
arima.ubo.middle.forecast.2 <- forecast(arima.ubo.middle.2, xreg = wall.data.pred, h=6)

autoplot(ubo.income.quintile.2, main = "UBO Quantile Forecast Times 2") + autolayer(arima.ubo.lowest.forecast.2) + autolayer(arima.ubo.second.forecast.2) + autolayer(arima.ubo.middle.forecast.2) + autolayer(final.fourth.forecast) + autolayer(final.highest.forecast)

Individual UBO Proposal Share Projection

total.forecast.ubo.2 <- arima.ubo.lowest.forecast.2$mean + arima.ubo.second.forecast.2$mean + arima.ubo.middle.forecast.2$mean + holt.fourth$mean + holt.highest$mean

arima.ubo.lowest.forecast.wall.share.2 <- arima.ubo.lowest.forecast$mean/total.forecast.ubo.2
arima.ubo.second.forecast.wall.share.2 <- arima.ubo.second.forecast$mean/total.forecast.ubo.2
arima.ubo.middle.share.2 <- arima.ubo.middle.forecast.2$mean/total.forecast.ubo.2
final.ubo.fourth.share.2 <- holt.fourth$mean/total.forecast.ubo.2
final.ubo.highest.share.2 <- holt.highest$mean/total.forecast.ubo.2

autoplot(arima.ubo.lowest.forecast.wall.share.2) + autolayer(arima.ubo.second.forecast.wall.share.2) + autolayer(arima.ubo.middle.share.2) + autolayer(final.ubo.fourth.share.2) + autolayer(final.ubo.highest.share.2)

arima.ubo.lowest.forecast.wall.share.2
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.08953717 0.09000925 0.09047980 0.09094886 0.09141641 0.09188248
arima.ubo.second.forecast.wall.share.2
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1151296 0.1154192 0.1157132 0.1160112 0.1163130 0.1166185
arima.ubo.middle.share.2
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1653476 0.1657304 0.1661201 0.1665163 0.1669185 0.1673265
final.ubo.fourth.share.2
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.1754730 0.1747958 0.1741257 0.1734625 0.1728059 0.1721557
final.ubo.highest.share.2
Time Series:
Start = 2018 
End = 2023 
Frequency = 1 
[1] 0.4258677 0.4248978 0.4239185 0.4229304 0.4219341 0.4209302

How to pay for it

Distribution_population <- read_excel("Distribution population.xlsx")
Error in read_excel("Distribution population.xlsx") : 
  could not find function "read_excel"
dist.pop.ts <- ts(Distribution_population, start=1979, end=2017, frequency=1)

lowest.pop <- Distribution_population$`Lowest Quantile`
second.pop <- Distribution_population$`Second Quantile`
middle.pop <- Distribution_population$`Middle Quantile`

lowest.pop.ts <- ts(lowest.pop, start=1979, end=2017, frequency = 1)
second.pop.ts <- ts(second.pop, start=1979, end=2017, frequency = 1)
middle.pop.ts <- ts(middle.pop, start=1979, end=2017, frequency = 1)
lowest.pop.pred <- rwf(lowest.pop.ts, h = 6, drift=TRUE)
second.pop.pred <- rwf(second.pop.ts, h = 6, drift=TRUE)
middle.pop.pred <- rwf(middle.pop.ts, h = 6, drift=TRUE)

lowest.pop.pred$model
second.pop.pred$model
middle.pop.pred$model

autoplot(dist.pop.ts) + autolayer(lowest.pop.pred) + autolayer(second.pop.pred) + autolayer(middle.pop.pred)
ubo.cost <- c(12000, 12000, 12000, 12000, 12000, 12000)
inflation <- c(1.00, 1.014, 1.028, 1.042, 1.056, 1.070)

ubo.inf.cost <- ubo.cost*inflation

lowest.pop.inc <- c(192100, 192100, 192100, 192100, 192100, 192100)
second.pop.inc <- c(240600, 240600, 240600, 240600, 240600, 240600)
middle.pop.inc <- c(271100, 271100, 271100, 271100, 271100, 271100)

lowest.cost <- lowest.pop.inc*ubo.inf.cost
second.cost <- second.pop.inc*ubo.inf.cost
middle.cost <- middle.pop.inc*ubo.inf.cost

lowest.cost <- ts(lowest.cost, start=2018, end=2023, frequency=1)
second.cost <- ts(second.cost, start=2018, end=2023, frequency=1)
middle.cost <- ts(middle.cost, start=2018, end=2023, frequency=1)

total.cost <- lowest.cost + second.cost + middle.cost

autoplot(total.cost) + autolayer(lowest.cost) + autolayer(second.cost) + autolayer(middle.cost)

total.cost
summary(final.highest)

This estimates a roughly $3,181,579,000 cost a year. This is no trifling amount, but is minimal compared to the $2.8 trillion a year for Andrew Yang’s UBI proposal. This is not a proposal for an immediate difference between the minimum required income for an individual living in America. But for attempting to move a family toward a higher income quintile, I believe that the cost is worth it.

holt.top$model
3181579000/39277180300

As we can see, even with only the top 1% paying for the entirety of this program without any federal assistance and only out of their gains per year according to the most accurate model, the cost for the UBI would only be roughly 8.10% of the gains in the top 1% in a year.

LS0tDQp0aXRsZTogIkxpdmluZyBpbiBEaWZmZXJlbnQgV29ybGRzOiBGb3JlY2FzdGluZyBpbmNvbWUgaW5lcXVhbGl0eSAtIEFsZXhhbmRlciBCYWN0YXQiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpBbGV4YW5kZXIgQmFjdGF0DQoNCkludHJvZHVjdGlvbjoNCldlIG9mdGVuIGhlYXIgdGhhdCBBbWVyaWNhbnMgbGl2ZSBpbiBkaWZmZXJlbnQgcmVhbGl0aWVzLXRoYXQgb3VyIGV4cGVyaWVuY2VzIGFyZSB3b3JsZHMgYXBhcnQuIEhlcmUsIHdlIHNlZSBpZiB0aGUgZm9yZWNhc3RzIGZvciB0aGVzZSBkaWZmZXJlbnQgd29ybGRzIGFyZSBkaWZmZXJlbnQgYXMgd2VsbC4NCg0KDQpgYGB7cn0NCmluY29tZV9kYXRhX3NoYXJlX29mX2luY29tZSA8LSByZWFkX2V4Y2VsKCJpbmNvbWUgZGF0YSBzaGFyZSBvZiBpbmNvbWUueGxzeCIpDQpWaWV3KGluY29tZV9kYXRhX3NoYXJlX29mX2luY29tZSkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmxvd2VzdC5zaGFyZSA8LSBpbmNvbWVfZGF0YV9zaGFyZV9vZl9pbmNvbWUkYExvd2VzdCBRdWludGlsZWANCnNlY29uZC5zaGFyZSA8LSBpbmNvbWVfZGF0YV9zaGFyZV9vZl9pbmNvbWUkYFNlY29uZCBRdWludGlsZWANCm1pZGRsZS5zaGFyZSA8LSBpbmNvbWVfZGF0YV9zaGFyZV9vZl9pbmNvbWUkYE1pZGRsZSBRdWludGlsZWANCmZvdXJ0aC5zaGFyZSA8LSBpbmNvbWVfZGF0YV9zaGFyZV9vZl9pbmNvbWUkYEZvdXJ0aCBRdWludGlsZWANCmhpZ2hlc3Quc2hhcmUgPC0gaW5jb21lX2RhdGFfc2hhcmVfb2ZfaW5jb21lJGBIaWdoZXN0IFF1aW50aWxlYA0KdG9wLnNoYXJlIDwtIGluY29tZV9kYXRhX3NoYXJlX29mX2luY29tZSRgVG9wIDElYA0KbG93ZXN0LnNoYXJlLnRzIDwtIHRzKGxvd2VzdC5zaGFyZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpzZWNvbmQuc2hhcmUudHMgPC0gdHMoc2Vjb25kLnNoYXJlLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCm1pZGRsZS5zaGFyZS50cyA8LSB0cyhtaWRkbGUuc2hhcmUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZm91cnRoLnNoYXJlLnRzIDwtIHRzKGZvdXJ0aC5zaGFyZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpoaWdoZXN0LnNoYXJlLnRzIDwtIHRzKGhpZ2hlc3Quc2hhcmUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KdG9wLnNoYXJlLnRzIDwtIHRzKHRvcC5zaGFyZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpgYGANCg0KU2hhcmUgb3ZlciB0aW1lDQpgYGB7cn0NCmF1dG9wbG90KGxvd2VzdC5zaGFyZS50cy8xMDAsIG1haW4gPSAiSW5jb21lIFNoYXJlIE92ZXIgVGltZSIpICsgYXV0b2xheWVyKHNlY29uZC5zaGFyZS50cy8xMDApICsgYXV0b2xheWVyKG1pZGRsZS5zaGFyZS50cy8xMDApICsgYXV0b2xheWVyKGZvdXJ0aC5zaGFyZS50cy8xMDApICsgYXV0b2xheWVyKGhpZ2hlc3Quc2hhcmUudHMvMTAwKQ0KYGBgDQoNCg0KDQpDb3JyZWxhdGlvbg0KDQpgYGB7cn0NCmNvcnIuc2hhcmUgPC0gY29yKGluY29tZV9kYXRhX3NoYXJlX29mX2luY29tZSkNCmNvcnJwbG90KGNvcnIuc2hhcmUsIG1ldGhvZD1jKCJudW1iZXIiKSkNCmBgYA0KDQoNCkhpc3RvcmljIFNoYXJlIG9mIEluY29tZQ0KYGBge3J9DQpoaXN0b3JpYy5zaGFyZSA8LSBjYmluZChsb3dlc3Quc2hhcmUudHMsIHNlY29uZC5zaGFyZS50cywgbWlkZGxlLnNoYXJlLnRzLCBmb3VydGguc2hhcmUudHMsIGhpZ2hlc3Quc2hhcmUudHMpDQphdXRvcGxvdChoaXN0b3JpYy5zaGFyZSkNCmBgYA0KDQoNCmBgYHtyfQ0KaW5jb21lX2RhdGEgPC0gcmVhZF9leGNlbCgiaW5jb21lX2RhdGEueGxzeCIpDQppbmNvbWVfZGF0YV9xdWludGlsZSA8LSByZWFkX2V4Y2VsKCJpbmNvbWVfZGF0YV9xdWludGlsZS54bHN4IikNCmBgYA0KDQpgYGB7cn0NCmxvd2VzdC5pbmNvbWUgPC0gaW5jb21lX2RhdGEkYExvd2VzdCBRdWludGlsZWANCnNlY29uZC5pbmNvbWUgPC0gaW5jb21lX2RhdGEkYFNlY29uZCBRdWludGlsZWANCm1pZGRsZS5pbmNvbWUgPC0gaW5jb21lX2RhdGEkYE1pZGRsZSBRdWludGlsZWANCmZvdXJ0aC5pbmNvbWUgPC0gaW5jb21lX2RhdGEkYEZvdXJ0aCBRdWludGlsZWANCmhpZ2hlc3QuaW5jb21lIDwtIGluY29tZV9kYXRhJGBIaWdoZXN0IFF1aW50aWxlYA0KdG9wLmluY29tZSA8LSBpbmNvbWVfZGF0YSRgVG9wIDElYA0KbG93ZXN0LmluY29tZS50cyA8LSB0cyhsb3dlc3QuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCnNlY29uZC5pbmNvbWUudHMgPC0gdHMoc2Vjb25kLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQptaWRkbGUuaW5jb21lLnRzIDwtIHRzKG1pZGRsZS5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZm91cnRoLmluY29tZS50cyA8LSB0cyhmb3VydGguaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmhpZ2hlc3QuaW5jb21lLnRzIDwtIHRzKGhpZ2hlc3QuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCnRvcC5pbmNvbWUudHMgPC0gdHModG9wLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpgYGANCg0KYGBge3J9DQp0bmkgPC0gbG93ZXN0LmluY29tZS50cyArIHNlY29uZC5pbmNvbWUudHMgKyBtaWRkbGUuaW5jb21lLnRzICsgZm91cnRoLmluY29tZS50cyArIGhpZ2hlc3QuaW5jb21lLnRzDQoNCmxvd2VzdC50bmkuc2hhcmUgPC0gbG93ZXN0LmluY29tZS50cy90bmkNCnNlY29uZC50bmkuc2hhcmUgPC0gc2Vjb25kLmluY29tZS50cy90bmkNCm1pZGRsZS50bmkuc2hhcmUgPC0gbWlkZGxlLmluY29tZS50cy90bmkNCmZvdXJ0aC50bmkuc2hhcmUgPC0gZm91cnRoLmluY29tZS50cy90bmkNCmhpZ2hlc3QudG5pLnNoYXJlIDwtIGhpZ2hlc3QuaW5jb21lLnRzL3RuaQ0KDQphdXRvcGxvdChsb3dlc3QudG5pLnNoYXJlLCBtYWluID0gIlROSSBTaGFyZSIpICsgYXV0b2xheWVyKHNlY29uZC50bmkuc2hhcmUpICsgYXV0b2xheWVyKG1pZGRsZS50bmkuc2hhcmUpICsgYXV0b2xheWVyKGZvdXJ0aC50bmkuc2hhcmUpICsgYXV0b2xheWVyKGhpZ2hlc3QudG5pLnNoYXJlKQ0KYGBgDQoNCg0KDQpWaXN1YWxpemF0aW9uDQoNCmBgYHtyfQ0KY29yci5pbmNvbWUgPC0gY29yKGluY29tZV9kYXRhKQ0KY29ycnBsb3QoY29yci5pbmNvbWUsIG1ldGhvZD1jKCJudW1iZXIiKSkNCmluY29tZS50cyA8LSB0cyhpbmNvbWVfZGF0YSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQphdXRvcGxvdChpbmNvbWUudHMsIG1haW4gPSAiSW5jb21lIERhdGEgT3ZlciBUaW1lLCAxJSIpDQppbmNvbWUucXVpbnRpbGUudHMgPC0gdHMoaW5jb21lX2RhdGFfcXVpbnRpbGUsIHN0YXJ0PTE5NzksIGVuZD0yMDE3KQ0KaW5jb21lLnRzLnF1aW50aWxlIDwtIHRzKGluY29tZV9kYXRhX3F1aW50aWxlLCBzdGFydD0xOTc5LCBlbmQ9MjAxNykNCmF1dG9wbG90KGluY29tZS50cy5xdWludGlsZSwgbWFpbiA9ICJRdWludGlsZSBJbmNvbWUgT3ZlciBUaW1lIikNCmBgYA0KDQpTZXBhcmF0ZSBpbnRvIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGENCg0KYGBge3J9DQp0ci5sb3dlc3QuaW5jb21lIDwtIHRzKGMobG93ZXN0LmluY29tZS50cyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIuc2Vjb25kLmluY29tZSA8LSB0cyhjKHNlY29uZC5pbmNvbWUudHMpLCBzdGFydD0xOTc5LCBlbmQ9MjAxMykNCnRyLm1pZGRsZS5pbmNvbWUgPC0gdHMoYyhtaWRkbGUuaW5jb21lLnRzKSwgc3RhcnQ9MTk3OSwgZW5kPTIwMTMpDQp0ci5mb3VydGguaW5jb21lIDwtIHRzKGMoZm91cnRoLmluY29tZS50cyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIuaGlnaGVzdC5pbmNvbWUgPC0gdHMoYyhoaWdoZXN0LmluY29tZS50cyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIudG9wLmluY29tZSA8LSB0cyhjKHRvcC5pbmNvbWUudHMpLCBzdGFydD0xOTc5LCBlbmQ9MjAxMykNCg0KdGVzdC5sb3dlc3QuaW5jb21lIDwtIHRhaWwobG93ZXN0LmluY29tZS50cywgbj00TCkNCnRlc3Quc2Vjb25kLmluY29tZSA8LSB0YWlsKHNlY29uZC5pbmNvbWUudHMsIG49NEwpDQp0ZXN0Lm1pZGRsZS5pbmNvbWUgPC0gdGFpbChtaWRkbGUuaW5jb21lLnRzLCBuPTRMKQ0KdGVzdC5mb3VydGguaW5jb21lIDwtIHRhaWwoZm91cnRoLmluY29tZS50cywgbj00TCkNCnRlc3QuaGlnaGVzdC5pbmNvbWUgPC0gdGFpbChoaWdoZXN0LmluY29tZS50cywgbj00TCkNCnRlc3QudG9wLmluY29tZSA8LSB0YWlsKHRvcC5pbmNvbWUudHMsIG49NEwpDQpgYGANCg0KQm94Q294IHRyYW5zZm9ybWF0aW9uDQpgYGB7cn0NCmxhbWJkYS5sb3dlc3Q8LUJveENveC5sYW1iZGEobG93ZXN0LmluY29tZS50cykNCmxvd2VzdC50cy5iYzwtQm94Q294KGxvd2VzdC5pbmNvbWUudHMsIGxhbWJkYS5sb3dlc3QpCQ0KbGFtYmRhLnNlY29uZDwtQm94Q294LmxhbWJkYShzZWNvbmQuaW5jb21lLnRzKQ0Kc2Vjb25kLnRzLmJjPC1Cb3hDb3goc2Vjb25kLmluY29tZS50cywgbGFtYmRhLnNlY29uZCkNCmxhbWJkYS5taWRkbGU8LUJveENveC5sYW1iZGEobWlkZGxlLmluY29tZS50cykNCm1pZGRsZS50cy5iYzwtQm94Q294KG1pZGRsZS5pbmNvbWUudHMsIGxhbWJkYS5taWRkbGUpDQpsYW1iZGEuZm91cnRoPC1Cb3hDb3gubGFtYmRhKGZvdXJ0aC5pbmNvbWUudHMpDQpmb3VydGgudHMuYmM8LUJveENveChmb3VydGguaW5jb21lLnRzLCBsYW1iZGEuZm91cnRoKQ0KbGFtYmRhLmhpZ2hlc3Q8LUJveENveC5sYW1iZGEoaGlnaGVzdC5pbmNvbWUudHMpDQpoaWdoZXN0LnRzLmJjPC1Cb3hDb3goaGlnaGVzdC5pbmNvbWUudHMsIGxhbWJkYS5oaWdoZXN0KQ0KbGFtYmRhLnRvcDwtQm94Q294LmxhbWJkYSh0b3AuaW5jb21lLnRzKQ0KdG9wLnRzLmJjPC1Cb3hDb3godG9wLmluY29tZS50cywgbGFtYmRhLnRvcCkNCg0KbGFtYmRhLmluY29tZTwtQm94Q294LmxhbWJkYShpbmNvbWUudHMpDQppbmNvbWUudHMuYmM8LUJveENveChpbmNvbWUudHMsIGxhbWJkYS5pbmNvbWUpDQoNCmxhbWJkYS5pbmNvbWUucXVpbnRpbGU8LUJveENveC5sYW1iZGEoaW5jb21lLnF1aW50aWxlLnRzKQ0KaW5jb21lLnF1aW50aWxlLnRzLmJjPC1Cb3hDb3goaW5jb21lLnF1aW50aWxlLnRzLCBsYW1iZGEuaW5jb21lLnF1aW50aWxlKQ0KDQphdXRvcGxvdChsb3dlc3QudHMuYmMpICsgYXV0b2xheWVyKHNlY29uZC50cy5iYykgKyBhdXRvbGF5ZXIobWlkZGxlLnRzLmJjKSArIGF1dG9sYXllcihmb3VydGgudHMuYmMpICsgYXV0b2xheWVyKGhpZ2hlc3QudHMuYmMpICsgYXV0b2xheWVyKHRvcC50cy5iYykNCg0KdHIubG93ZXN0LmluY29tZS5iYyA8LSB0cyhjKGxvd2VzdC50cy5iYyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIuc2Vjb25kLmluY29tZS5iYyA8LSB0cyhjKHNlY29uZC50cy5iYyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIubWlkZGxlLmluY29tZS5iYyA8LSB0cyhjKG1pZGRsZS50cy5iYyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIuZm91cnRoLmluY29tZS5iYyA8LSB0cyhjKGZvdXJ0aC50cy5iYyksIHN0YXJ0PTE5NzksIGVuZD0yMDEzKQ0KdHIuaGlnaGVzdC5pbmNvbWUuYmMgPC0gdHMoYyhoaWdoZXN0LnRzLmJjKSwgc3RhcnQ9MTk3OSwgZW5kPTIwMTMpDQp0ci50b3AuaW5jb21lLmJjIDwtIHRzKGModG9wLnRzLmJjKSwgc3RhcnQ9MTk3OSwgZW5kPTIwMTMpDQoNCnRlc3QubG93ZXN0LmluY29tZS5iYyA8LSB0YWlsKGxvd2VzdC50cy5iYywgbj00TCkNCnRlc3Quc2Vjb25kLmluY29tZS5iYyA8LSB0YWlsKHNlY29uZC50cy5iYywgbj00TCkNCnRlc3QubWlkZGxlLmluY29tZS5iYyA8LSB0YWlsKG1pZGRsZS50cy5iYywgbj00TCkNCnRlc3QuZm91cnRoLmluY29tZS5iYyA8LSB0YWlsKGZvdXJ0aC50cy5iYywgbj00TCkNCnRlc3QuaGlnaGVzdC5pbmNvbWUuYmMgPC0gdGFpbChoaWdoZXN0LnRzLmJjLCBuPTRMKQ0KdGVzdC50b3AuaW5jb21lLmJjIDwtIHRhaWwodG9wLnRzLmJjLCBuPTRMKQ0KDQphdXRvcGxvdChsb3dlc3QudHMuYmMpICsgYXV0b2xheWVyKHNlY29uZC50cy5iYykgKyBhdXRvbGF5ZXIobWlkZGxlLnRzLmJjKSArIGF1dG9sYXllcihmb3VydGgudHMuYmMpICsgYXV0b2xheWVyKGhpZ2hlc3QudHMuYmMpDQoNCmBgYA0KDQoNCg0KQVJJTUEgUHJlZGljdGlvbg0KDQpgYGB7cn0NCmFyaW1hLmxvd2VzdC50ciA8LSBhdXRvLmFyaW1hKHRyLmxvd2VzdC5pbmNvbWUsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS5zZWNvbmQudHIgPC0gYXV0by5hcmltYSh0ci5zZWNvbmQuaW5jb21lLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEubWlkZGxlLnRyIDwtIGF1dG8uYXJpbWEodHIubWlkZGxlLmluY29tZSwgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLmZvdXJ0aC50ciA8LSBhdXRvLmFyaW1hKHRyLmZvdXJ0aC5pbmNvbWUsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS5oaWdoZXN0LnRyIDwtIGF1dG8uYXJpbWEodHIuaGlnaGVzdC5pbmNvbWUsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS50b3AudHIgPC0gYXV0by5hcmltYSh0ci50b3AuaW5jb21lLCBzZWFzb25hbCA9IEZBTFNFKQ0KDQphcmltYS5sb3dlc3QucHJlZCA8LSBmb3JlY2FzdChhcmltYS5sb3dlc3QudHIsIGg9NCkNCmFyaW1hLnNlY29uZC5wcmVkIDwtIGZvcmVjYXN0KGFyaW1hLnNlY29uZC50ciwgaD00KQ0KYXJpbWEubWlkZGxlLnByZWQgPC0gZm9yZWNhc3QoYXJpbWEubWlkZGxlLnRyLCBoPTQpDQphcmltYS5mb3VydGgucHJlZCA8LSBmb3JlY2FzdChhcmltYS5mb3VydGgudHIsIGg9NCkNCmFyaW1hLmhpZ2hlc3QucHJlZCA8LSBmb3JlY2FzdChhcmltYS5oaWdoZXN0LnRyLCBoPTQpDQphcmltYS50b3AucHJlZCA8LSBmb3JlY2FzdChhcmltYS50b3AudHIsIGg9NCkNCg0KYWNjdXJhY3koYXJpbWEubG93ZXN0LnByZWQsIHRlc3QubG93ZXN0LmluY29tZSkNCmFjY3VyYWN5KGFyaW1hLnNlY29uZC5wcmVkLCB0ZXN0LnNlY29uZC5pbmNvbWUpDQphY2N1cmFjeShhcmltYS5taWRkbGUucHJlZCwgdGVzdC5taWRkbGUuaW5jb21lKQ0KYWNjdXJhY3koYXJpbWEuZm91cnRoLnByZWQsIHRlc3QuZm91cnRoLmluY29tZSkNCmFjY3VyYWN5KGFyaW1hLmhpZ2hlc3QucHJlZCwgdGVzdC5oaWdoZXN0LmluY29tZSkNCmFjY3VyYWN5KGFyaW1hLnRvcC5wcmVkLCB0ZXN0LnRvcC5pbmNvbWUpDQpgYGANCg0KYGBge3J9DQphcmltYS5sb3dlc3QgPC0gYXV0by5hcmltYShsb3dlc3QuaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEuc2Vjb25kIDwtIGF1dG8uYXJpbWEoc2Vjb25kLmluY29tZS50cywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLm1pZGRsZSA8LSBhdXRvLmFyaW1hKG1pZGRsZS5pbmNvbWUudHMsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS5mb3VydGggPC0gYXV0by5hcmltYShmb3VydGguaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEuaGlnaGVzdCA8LSBhdXRvLmFyaW1hKGhpZ2hlc3QuaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEudG9wIDwtIGF1dG8uYXJpbWEodG9wLmluY29tZS50cywgc2Vhc29uYWwgPSBGQUxTRSkNCg0KYXJpbWEubG93ZXN0LmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLmxvd2VzdCwgaD02KQ0KYXJpbWEuc2Vjb25kLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLnNlY29uZCwgaD02KQ0KYXJpbWEubWlkZGxlLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLm1pZGRsZSwgaD02KQ0KYXJpbWEuZm91cnRoLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLmZvdXJ0aCwgaD02KQ0KYXJpbWEuaGlnaGVzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdChhcmltYS5oaWdoZXN0LCBoPTYpDQphcmltYS50b3AuZm9yZWNhc3QgPC0gZm9yZWNhc3QoYXJpbWEudG9wLCBoPTYpDQoNCmF1dG9wbG90KGluY29tZS50cykgKyBhdXRvbGF5ZXIoYXJpbWEubG93ZXN0LmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLm1pZGRsZS5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEuZm91cnRoLmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS5oaWdoZXN0LmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS50b3AuZm9yZWNhc3QpDQoNCmF1dG9wbG90KGluY29tZS5xdWludGlsZS50cykgKyBhdXRvbGF5ZXIoYXJpbWEubG93ZXN0LmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLm1pZGRsZS5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEuZm91cnRoLmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS5oaWdoZXN0LmZvcmVjYXN0KQ0KYGBgDQoNCmBgYHtyfQ0KDQphcmltYS5sb3dlc3QkdmFyLmNvZWYNCmFyaW1hLnNlY29uZCR2YXIuY29lZg0KYXJpbWEubWlkZGxlJHZhci5jb2VmDQphcmltYS5mb3VydGgkdmFyLmNvZWYNCmFyaW1hLmhpZ2hlc3QkdmFyLmNvZWYNCmFyaW1hLnRvcCR2YXIuY29lZg0KDQpgYGANCg0KQVJJTUEgQm94Q294DQpgYGB7cn0NCmFyaW1hLmxvd2VzdC50ci5iYyA8LSBhdXRvLmFyaW1hKHRyLmxvd2VzdC5pbmNvbWUuYmMsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS5zZWNvbmQudHIuYmMgPC0gYXV0by5hcmltYSh0ci5zZWNvbmQuaW5jb21lLmJjLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEubWlkZGxlLnRyLmJjIDwtIGF1dG8uYXJpbWEodHIubWlkZGxlLmluY29tZS5iYywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLmZvdXJ0aC50ci5iYyA8LSBhdXRvLmFyaW1hKHRyLmZvdXJ0aC5pbmNvbWUuYmMsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS5oaWdoZXN0LnRyLmJjIDwtIGF1dG8uYXJpbWEodHIuaGlnaGVzdC5pbmNvbWUuYmMsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS50b3AudHIuYmMgPC0gYXV0by5hcmltYSh0ci50b3AuaW5jb21lLmJjLCBzZWFzb25hbCA9IEZBTFNFKQ0KDQphcmltYS5sb3dlc3QucHJlZC5iYyA8LSBmb3JlY2FzdChhcmltYS5sb3dlc3QudHIuYmMsIGg9NCkNCmFyaW1hLnNlY29uZC5wcmVkLmJjIDwtIGZvcmVjYXN0KGFyaW1hLnNlY29uZC50ci5iYywgaD00KQ0KYXJpbWEubWlkZGxlLnByZWQuYmMgPC0gZm9yZWNhc3QoYXJpbWEubWlkZGxlLnRyLmJjLCBoPTQpDQphcmltYS5mb3VydGgucHJlZC5iYyA8LSBmb3JlY2FzdChhcmltYS5mb3VydGgudHIuYmMsIGg9NCkNCmFyaW1hLmhpZ2hlc3QucHJlZC5iYyA8LSBmb3JlY2FzdChhcmltYS5oaWdoZXN0LnRyLmJjLCBoPTQpDQphcmltYS50b3AucHJlZC5iYyA8LSBmb3JlY2FzdChhcmltYS50b3AudHIuYmMsIGg9NCkNCg0KYWNjdXJhY3koYXJpbWEubG93ZXN0LnByZWQuYmMsIHRlc3QubG93ZXN0LmluY29tZS5iYykNCmFjY3VyYWN5KGFyaW1hLnNlY29uZC5wcmVkLmJjLCB0ZXN0LnNlY29uZC5pbmNvbWUuYmMpDQphY2N1cmFjeShhcmltYS5taWRkbGUucHJlZC5iYywgdGVzdC5taWRkbGUuaW5jb21lLmJjKQ0KYWNjdXJhY3koYXJpbWEuZm91cnRoLnByZWQuYmMsIHRlc3QuZm91cnRoLmluY29tZS5iYykNCmFjY3VyYWN5KGFyaW1hLmhpZ2hlc3QucHJlZC5iYywgdGVzdC5oaWdoZXN0LmluY29tZS5iYykNCmFjY3VyYWN5KGFyaW1hLnRvcC5wcmVkLmJjLCB0ZXN0LnRvcC5pbmNvbWUuYmMpDQoNCmBgYA0KDQpgYGB7cn0NCmFyaW1hLmxvd2VzdC5iYyA8LSBhdXRvLmFyaW1hKGxvd2VzdC50cy5iYywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLnNlY29uZC5iYyA8LSBhdXRvLmFyaW1hKHNlY29uZC50cy5iYywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLm1pZGRsZS5iYyA8LSBhdXRvLmFyaW1hKG1pZGRsZS50cy5iYywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLmZvdXJ0aC5iYyA8LSBhdXRvLmFyaW1hKGZvdXJ0aC50cy5iYywgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLmhpZ2hlc3QuYmMgPC0gYXV0by5hcmltYShoaWdoZXN0LnRzLmJjLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEudG9wLmJjIDwtIGF1dG8uYXJpbWEodG9wLnRzLmJjLCBzZWFzb25hbCA9IEZBTFNFKQ0KDQphcmltYS5sb3dlc3QuZm9yZWNhc3QuYmMgPC0gZm9yZWNhc3QoYXJpbWEubG93ZXN0LmJjLCBoPTYpDQphcmltYS5zZWNvbmQuZm9yZWNhc3QuYmMgPC0gZm9yZWNhc3QoYXJpbWEuc2Vjb25kLmJjLCBoPTYpDQphcmltYS5taWRkbGUuZm9yZWNhc3QuYmMgPC0gZm9yZWNhc3QoYXJpbWEubWlkZGxlLmJjLCBoPTYpDQphcmltYS5mb3VydGguZm9yZWNhc3QuYmMgPC0gZm9yZWNhc3QoYXJpbWEuZm91cnRoLmJjLCBoPTYpDQphcmltYS5oaWdoZXN0LmZvcmVjYXN0LmJjIDwtIGZvcmVjYXN0KGFyaW1hLmhpZ2hlc3QuYmMsIGg9NikNCmFyaW1hLnRvcC5mb3JlY2FzdC5iYyA8LSBmb3JlY2FzdChhcmltYS50b3AuYmMsIGg9NikNCg0KYXJpbWEubG93ZXN0LmJjJHZhci5jb2VmDQphcmltYS5zZWNvbmQuYmMkdmFyLmNvZWYNCmFyaW1hLm1pZGRsZS5iYyR2YXIuY29lZg0KYXJpbWEuZm91cnRoLmJjJHZhci5jb2VmDQphcmltYS5oaWdoZXN0LmJjJHZhci5jb2VmDQphcmltYS50b3AuYmMkdmFyLmNvZWYNCg0KYGBgDQoNCkFSSU1BIERpc3RyaWJ1dGlvbiBGb3JlY2FzdA0KYGBge3J9DQoNCmFyaW1hLnRvdGFsLmZvcmVjYXN0IDwtIGFyaW1hLmxvd2VzdC5mb3JlY2FzdCRtZWFuICsgYXJpbWEuc2Vjb25kLmZvcmVjYXN0JG1lYW4gKyBhcmltYS5taWRkbGUuZm9yZWNhc3QkbWVhbiArIGFyaW1hLmZvdXJ0aC5mb3JlY2FzdCRtZWFuICsgYXJpbWEuaGlnaGVzdC5mb3JlY2FzdCRtZWFuDQoNCmFyaW1hLmxvd2VzdC5mb3JlY2FzdC5zaGFyZSA8LSBhcmltYS5sb3dlc3QuZm9yZWNhc3QkbWVhbi9hcmltYS50b3RhbC5mb3JlY2FzdA0KYXJpbWEuc2Vjb25kLmZvcmVjYXN0LnNoYXJlIDwtIGFyaW1hLnNlY29uZC5mb3JlY2FzdCRtZWFuL2FyaW1hLnRvdGFsLmZvcmVjYXN0DQphcmltYS5taWRkbGUuZm9yZWNhc3Quc2hhcmUgPC0gYXJpbWEubWlkZGxlLmZvcmVjYXN0JG1lYW4vYXJpbWEudG90YWwuZm9yZWNhc3QNCmFyaW1hLmZvdXJ0aC5mb3JlY2FzdC5zaGFyZSA8LSBhcmltYS5mb3VydGguZm9yZWNhc3QkbWVhbi9hcmltYS50b3RhbC5mb3JlY2FzdA0KYXJpbWEuaGlnaGVzdC5mb3JlY2FzdC5zaGFyZSA8LSBhcmltYS5oaWdoZXN0LmZvcmVjYXN0JG1lYW4vYXJpbWEudG90YWwuZm9yZWNhc3QNCg0KYXV0b3Bsb3QoYXJpbWEubG93ZXN0LmZvcmVjYXN0LnNoYXJlKSArIGF1dG9sYXllcihhcmltYS5zZWNvbmQuZm9yZWNhc3Quc2hhcmUpICsgYXV0b2xheWVyKGFyaW1hLm1pZGRsZS5mb3JlY2FzdC5zaGFyZSkgKyBhdXRvbGF5ZXIoYXJpbWEuZm91cnRoLmZvcmVjYXN0LnNoYXJlKSArIGF1dG9sYXllcihhcmltYS5oaWdoZXN0LmZvcmVjYXN0LnNoYXJlKQ0KDQpgYGANCg0KDQpIb2x0IFRyZW5kDQpgYGB7cn0NCmhvbHQubG93ZXN0LnByZWQgPC0gaG9sdCh0ci5sb3dlc3QuaW5jb21lLCAgaD00KQ0KaG9sdC5zZWNvbmQucHJlZCA8LSBob2x0KHRyLnNlY29uZC5pbmNvbWUsICBoPTQpDQpob2x0Lm1pZGRsZS5wcmVkIDwtIGhvbHQodHIubWlkZGxlLmluY29tZSwgIGg9NCkNCmhvbHQuZm91cnRoLnByZWQgPC0gaG9sdCh0ci5mb3VydGguaW5jb21lLCAgaD00KQ0KaG9sdC5oaWdoZXN0LnByZWQgPC0gaG9sdCh0ci5oaWdoZXN0LmluY29tZSwgIGg9NCkNCmhvbHQudG9wLnByZWQgPC0gaG9sdCh0ci50b3AuaW5jb21lLCAgaD00KQ0KDQphY2N1cmFjeShob2x0Lmxvd2VzdC5wcmVkLCB0ZXN0Lmxvd2VzdC5pbmNvbWUpDQphY2N1cmFjeShob2x0LnNlY29uZC5wcmVkLCB0ZXN0LnNlY29uZC5pbmNvbWUpDQphY2N1cmFjeShob2x0Lm1pZGRsZS5wcmVkLCB0ZXN0Lm1pZGRsZS5pbmNvbWUpDQphY2N1cmFjeShob2x0LmZvdXJ0aC5wcmVkLCB0ZXN0LmZvdXJ0aC5pbmNvbWUpDQphY2N1cmFjeShob2x0LmhpZ2hlc3QucHJlZCwgdGVzdC5oaWdoZXN0LmluY29tZSkNCmFjY3VyYWN5KGhvbHQudG9wLnByZWQsIHRlc3QudG9wLmluY29tZSkNCg0KYGBgDQoNCg0KDQoNCkhvbHQgRGFtcGVkIHRyZW5kDQoNCmBgYHtyfQ0KaG9sdC5sb3dlc3QuZGFtcC5wcmVkIDwtIGhvbHQodHIubG93ZXN0LmluY29tZSwgZGFtcGVkPVRSVUUsIGg9NCkNCmhvbHQuc2Vjb25kLmRhbXAucHJlZCA8LSBob2x0KHRyLnNlY29uZC5pbmNvbWUsIGRhbXBlZD1UUlVFLCBoPTQpDQpob2x0Lm1pZGRsZS5kYW1wLnByZWQgPC0gaG9sdCh0ci5taWRkbGUuaW5jb21lLCBkYW1wZWQ9VFJVRSwgaD00KQ0KaG9sdC5mb3VydGguZGFtcC5wcmVkIDwtIGhvbHQodHIuZm91cnRoLmluY29tZSwgZGFtcGVkPVRSVUUsIGg9NCkNCmhvbHQuaGlnaGVzdC5kYW1wLnByZWQgPC0gaG9sdCh0ci5oaWdoZXN0LmluY29tZSwgZGFtcGVkPVRSVUUsIGg9NCkNCmhvbHQudG9wLmRhbXAucHJlZCA8LSBob2x0KHRyLnRvcC5pbmNvbWUsIGRhbXBlZD1UUlVFLCBoPTQpDQoNCmFjY3VyYWN5KGhvbHQubG93ZXN0LmRhbXAucHJlZCwgdGVzdC5sb3dlc3QuaW5jb21lKQ0KYWNjdXJhY3koaG9sdC5zZWNvbmQuZGFtcC5wcmVkLCB0ZXN0LnNlY29uZC5pbmNvbWUpDQphY2N1cmFjeShob2x0Lm1pZGRsZS5kYW1wLnByZWQsIHRlc3QubWlkZGxlLmluY29tZSkNCmFjY3VyYWN5KGhvbHQuZm91cnRoLmRhbXAucHJlZCwgdGVzdC5mb3VydGguaW5jb21lKQ0KYWNjdXJhY3koaG9sdC5oaWdoZXN0LmRhbXAucHJlZCwgdGVzdC5oaWdoZXN0LmluY29tZSkNCmFjY3VyYWN5KGhvbHQudG9wLmRhbXAucHJlZCwgdGVzdC50b3AuaW5jb21lKQ0KYGBgDQoNCmBgYHtyfQ0KaG9sdC5sb3dlc3QgPC0gaG9sdChsb3dlc3QuaW5jb21lLnRzLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC5zZWNvbmQgPC0gaG9sdChzZWNvbmQuaW5jb21lLnRzLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC5taWRkbGUgPC0gaG9sdChtaWRkbGUuaW5jb21lLnRzLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC5mb3VydGggPC0gaG9sdChmb3VydGguaW5jb21lLnRzLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC5oaWdoZXN0IDwtIGhvbHQoaGlnaGVzdC5pbmNvbWUudHMsIGRhbXBlZD1UUlVFLCBoPTYpDQpob2x0LnRvcCA8LSBob2x0KHRvcC5pbmNvbWUudHMsIGRhbXBlZD1UUlVFLCBoPTYpDQoNCmF1dG9wbG90KGluY29tZS50cykgKyBhdXRvbGF5ZXIoaG9sdC5sb3dlc3QpICsgYXV0b2xheWVyKGhvbHQuc2Vjb25kKSArIGF1dG9sYXllcihob2x0Lm1pZGRsZSkgKyBhdXRvbGF5ZXIoaG9sdC5mb3VydGgpICsgYXV0b2xheWVyKGhvbHQuaGlnaGVzdCkgKyBhdXRvbGF5ZXIoaG9sdC50b3ApDQoNCmF1dG9wbG90KGluY29tZS5xdWludGlsZS50cykgKyBhdXRvbGF5ZXIoaG9sdC5sb3dlc3QpICsgYXV0b2xheWVyKGhvbHQuc2Vjb25kKSArIGF1dG9sYXllcihob2x0Lm1pZGRsZSkgKyBhdXRvbGF5ZXIoaG9sdC5mb3VydGgpICsgYXV0b2xheWVyKGhvbHQuaGlnaGVzdCkNCg0KYGBgDQoNCmBgYHtyfQ0KaG9sdC5sb3dlc3QkbW9kZWwNCmhvbHQuc2Vjb25kJG1vZGVsDQpob2x0Lm1pZGRsZSRtb2RlbA0KaG9sdC5mb3VydGgkbW9kZWwNCmhvbHQuaGlnaGVzdCRtb2RlbA0KaG9sdC50b3AkbW9kZWwNCmBgYA0KDQpIb2x0IEJveENveA0KYGBge3J9DQpob2x0Lmxvd2VzdC5wcmVkLmJjIDwtIGhvbHQodHIubG93ZXN0LmluY29tZS5iYywgaD00KQ0KaG9sdC5zZWNvbmQucHJlZC5iYyA8LSBob2x0KHRyLmxvd2VzdC5pbmNvbWUuYmMsIGg9NCkNCmhvbHQubWlkZGxlLnByZWQuYmMgPC0gaG9sdCh0ci5sb3dlc3QuaW5jb21lLmJjLCBoPTQpDQpob2x0LmZvdXJ0aC5wcmVkLmJjIDwtIGhvbHQodHIubG93ZXN0LmluY29tZS5iYywgaD00KQ0KaG9sdC5oaWdoZXN0LnByZWQuYmMgPC0gaG9sdCh0ci5sb3dlc3QuaW5jb21lLmJjLCBoPTQpDQpob2x0LnRvcC5wcmVkLmJjIDwtIGhvbHQodHIubG93ZXN0LmluY29tZS5iYywgaD00KQ0KDQphY2N1cmFjeShob2x0Lmxvd2VzdC5wcmVkLmJjLCB0ZXN0Lmxvd2VzdC5pbmNvbWUuYmMpDQphY2N1cmFjeShob2x0LnNlY29uZC5wcmVkLmJjLCB0ZXN0LnNlY29uZC5pbmNvbWUuYmMpDQphY2N1cmFjeShob2x0Lm1pZGRsZS5wcmVkLmJjLCB0ZXN0Lm1pZGRsZS5pbmNvbWUuYmMpDQphY2N1cmFjeShob2x0LmZvdXJ0aC5wcmVkLmJjLCB0ZXN0LmZvdXJ0aC5pbmNvbWUuYmMpDQphY2N1cmFjeShob2x0LmhpZ2hlc3QucHJlZC5iYywgdGVzdC5oaWdoZXN0LmluY29tZS5iYykNCmFjY3VyYWN5KGhvbHQudG9wLnByZWQuYmMsIHRlc3QudG9wLmluY29tZS5iYykNCg0KYGBgDQoNCmBgYHtyfQ0KaG9sdC5sb3dlc3QuYmMgPC0gaG9sdChsb3dlc3QudHMuYmMsIGRhbXBlZD1UUlVFLCBoPTYpDQpob2x0LnNlY29uZC5iYyA8LSBob2x0KHNlY29uZC50cy5iYywgZGFtcGVkPVRSVUUsIGg9NikNCmhvbHQubWlkZGxlLmJjIDwtIGhvbHQobWlkZGxlLnRzLmJjLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC5mb3VydGguYmMgPC0gaG9sdChmb3VydGgudHMuYmMsIGRhbXBlZD1UUlVFLCBoPTYpDQpob2x0LmhpZ2hlc3QuYmMgPC0gaG9sdChoaWdoZXN0LnRzLmJjLCBkYW1wZWQ9VFJVRSwgaD02KQ0KaG9sdC50b3AuYmMgPC0gaG9sdCh0b3AudHMuYmMsIGRhbXBlZD1UUlVFLCBoPTYpDQoNCmhvbHQubG93ZXN0LmJjJG1vZGVsDQpob2x0LnNlY29uZC5iYyRtb2RlbA0KaG9sdC5taWRkbGUuYmMkbW9kZWwNCmhvbHQuZm91cnRoLmJjJG1vZGVsDQpob2x0LmhpZ2hlc3QuYmMkbW9kZWwNCmhvbHQudG9wLmJjJG1vZGVsDQoNCmBgYA0KDQpIb2x0IERpc3RyaWJ1dGlvbiBGb3JlY2FzdA0KYGBge3J9DQpob2x0LnRvdGFsIDwtIGhvbHQubG93ZXN0JG1lYW4gKyBob2x0LnNlY29uZCRtZWFuICsgaG9sdC5taWRkbGUkbWVhbiArIGhvbHQuZm91cnRoJG1lYW4gKyBob2x0LmhpZ2hlc3QkbWVhbg0KDQpob2x0Lmxvd2VzdC5zaGFyZSA8LSBob2x0Lmxvd2VzdCRtZWFuL2hvbHQudG90YWwNCmhvbHQuc2Vjb25kLnNoYXJlIDwtIGhvbHQuc2Vjb25kJG1lYW4vaG9sdC50b3RhbA0KaG9sdC5taWRkbGUuc2hhcmUgPC0gaG9sdC5taWRkbGUkbWVhbi9ob2x0LnRvdGFsDQpob2x0LmZvdXJ0aC5zaGFyZSA8LSBob2x0LmZvdXJ0aCRtZWFuL2hvbHQudG90YWwNCmhvbHQuaGlnaGVzdC5zaGFyZSA8LSBob2x0LmhpZ2hlc3QkbWVhbi9ob2x0LnRvdGFsDQoNCmF1dG9wbG90KGhvbHQubG93ZXN0LnNoYXJlKSArIGF1dG9sYXllcihob2x0LnNlY29uZC5zaGFyZSkgKyBhdXRvbGF5ZXIoaG9sdC5taWRkbGUuc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuZm91cnRoLnNoYXJlKSArIGF1dG9sYXllcihob2x0LmhpZ2hlc3Quc2hhcmUpDQoNCmBgYA0KDQoNCg0KTmV1cmFsIE5ldCBQcmVkaWN0aW9uDQpgYGB7cn0NCm5uYXIubG93ZXN0LnRyIDwtIG5uZXRhcih0ci5sb3dlc3QuaW5jb21lLCBsYW1iZGE9MCwgYm9vc3RyYXA9VFJVRSkNCm5uYXIuc2Vjb25kLnRyIDwtIG5uZXRhcih0ci5zZWNvbmQuaW5jb21lLCBsYW1iZGE9MCwgYm9vc3RyYXA9VFJVRSkNCm5uYXIubWlkZGxlLnRyIDwtIG5uZXRhcih0ci5taWRkbGUuaW5jb21lLCBsYW1iZGE9MCwgYm9vc3RyYXA9VFJVRSkNCm5uYXIuZm91cnRoLnRyIDwtIG5uZXRhcih0ci5mb3VydGguaW5jb21lLCBsYW1iZGE9MCwgYm9vc3RyYXA9VFJVRSkNCm5uYXIuaGlnaGVzdC50ciA8LSBubmV0YXIodHIuaGlnaGVzdC5pbmNvbWUsIGxhbWJkYT0wLCBib29zdHJhcD1UUlVFKQ0Kbm5hci50b3AudHIgPC0gbm5ldGFyKHRyLnRvcC5pbmNvbWUsIGxhbWJkYT0wLCBib29zdHJhcD1UUlVFKQ0KDQpubmFyLmxvd2VzdC5wcmVkIDwtIGZvcmVjYXN0KG5uYXIubG93ZXN0LnRyLCBoPTQpDQpubmFyLnNlY29uZC5wcmVkIDwtIGZvcmVjYXN0KG5uYXIuc2Vjb25kLnRyLCBoPTQpDQpubmFyLm1pZGRsZS5wcmVkIDwtIGZvcmVjYXN0KG5uYXIubWlkZGxlLnRyLCBoPTQpDQpubmFyLmZvdXJ0aC5wcmVkIDwtIGZvcmVjYXN0KG5uYXIuZm91cnRoLnRyLCBoPTQpDQpubmFyLmhpZ2hlc3QucHJlZCA8LSBmb3JlY2FzdChubmFyLmhpZ2hlc3QudHIsIGg9NCkNCm5uYXIudG9wLnByZWQgPC0gZm9yZWNhc3Qobm5hci50b3AudHIsIGg9NCkNCg0KYGBgDQoNCg0KYGBge3J9DQphY2N1cmFjeShubmFyLmxvd2VzdC5wcmVkJG1lYW4sIHRlc3QubG93ZXN0LmluY29tZSkNCmFjY3VyYWN5KG5uYXIuc2Vjb25kLnByZWQkbWVhbiwgdGVzdC5zZWNvbmQuaW5jb21lKQ0KYWNjdXJhY3kobm5hci5taWRkbGUucHJlZCRtZWFuLCB0ZXN0Lm1pZGRsZS5pbmNvbWUpDQphY2N1cmFjeShubmFyLmZvdXJ0aC5wcmVkJG1lYW4sIHRlc3QuZm91cnRoLmluY29tZSkNCmFjY3VyYWN5KG5uYXIuaGlnaGVzdC5wcmVkJG1lYW4sIHRlc3QuaGlnaGVzdC5pbmNvbWUpDQphY2N1cmFjeShubmFyLnRvcC5wcmVkJG1lYW4sIHRlc3QudG9wLmluY29tZSkNCmBgYA0KDQpgYGB7cn0NCm5uYXIubG93ZXN0IDwtIG5uZXRhcihsb3dlc3QuaW5jb21lLnRzLCBsYW1iZGE9MCkNCm5uYXIuc2Vjb25kIDwtIG5uZXRhcihzZWNvbmQuaW5jb21lLnRzLCBsYW1iZGE9MCkNCm5uYXIubWlkZGxlIDwtIG5uZXRhcihtaWRkbGUuaW5jb21lLnRzLCBsYW1iZGE9MCkNCm5uYXIuZm91cnRoIDwtIG5uZXRhcihmb3VydGguaW5jb21lLnRzLCBsYW1iZGE9MCkNCm5uYXIuaGlnaGVzdCA8LSBubmV0YXIoaGlnaGVzdC5pbmNvbWUudHMsIGxhbWJkYT0wKQ0Kbm5hci50b3AgPC0gbm5ldGFyKHRvcC5pbmNvbWUudHMsIGxhbWJkYT0wKQ0KDQpubmFyLmxvd2VzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdChubmFyLmxvd2VzdCwgaD02KQ0Kbm5hci5zZWNvbmQuZm9yZWNhc3QgPC0gZm9yZWNhc3Qobm5hci5zZWNvbmQsIGg9NikNCm5uYXIubWlkZGxlLmZvcmVjYXN0IDwtIGZvcmVjYXN0KG5uYXIubWlkZGxlLCBoPTYpDQpubmFyLmZvdXJ0aC5mb3JlY2FzdCA8LSBmb3JlY2FzdChubmFyLmZvdXJ0aCwgaD02KQ0Kbm5hci5oaWdoZXN0LmZvcmVjYXN0IDwtIGZvcmVjYXN0KG5uYXIuaGlnaGVzdCwgaD02KQ0Kbm5hci50b3AuZm9yZWNhc3QgPC0gZm9yZWNhc3Qobm5hci50b3AsIGg9NikNCg0KYXV0b3Bsb3QoaW5jb21lLnRzKSArIGF1dG9sYXllcihubmFyLmxvd2VzdC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIobm5hci5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKG5uYXIubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihubmFyLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIobm5hci5oaWdoZXN0LmZvcmVjYXN0KSArIGF1dG9sYXllcihubmFyLnRvcC5mb3JlY2FzdCkNCg0KYXV0b3Bsb3QoaW5jb21lLnF1aW50aWxlLnRzKSArIGF1dG9sYXllcihubmFyLmxvd2VzdC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIobm5hci5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKG5uYXIubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihubmFyLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIobm5hci5oaWdoZXN0LmZvcmVjYXN0KQ0KYGBgDQoNCmBgYHtyfQ0Kbm5hci5sb3dlc3QkbW9kZWwNCm5uYXIuc2Vjb25kJG1vZGVsDQpubmFyLm1pZGRsZSRtb2RlbA0Kbm5hci5mb3VydGgkbW9kZWwNCm5uYXIuaGlnaGVzdCRtb2RlbA0Kbm5hci50b3AkbW9kZWwNCmBgYA0KDQpFVFMgTW9kZWwgUHJlZGljdGlvbg0KYGBge3J9DQpldHMubG93ZXN0LnRyIDwtIGV0cyh0ci5sb3dlc3QuaW5jb21lLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLnNlY29uZC50ciA8LSBldHModHIuc2Vjb25kLmluY29tZSwgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5taWRkbGUudHIgPC0gZXRzKHRyLm1pZGRsZS5pbmNvbWUsIG1vZGVsID0gIlpaWiIsIGRhbXBlZCA9IFRSVUUpDQpldHMuZm91cnRoLnRyIDwtIGV0cyh0ci5mb3VydGguaW5jb21lLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLmhpZ2hlc3QudHIgPC0gZXRzKHRyLmhpZ2hlc3QuaW5jb21lLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLnRvcC50ciA8LSBldHModHIudG9wLmluY29tZSwgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCg0KZXRzLmxvd2VzdC5wcmVkIDwtIGZvcmVjYXN0KGV0cy5sb3dlc3QudHIsIGg9NCkNCmV0cy5zZWNvbmQucHJlZCA8LSBmb3JlY2FzdChldHMuc2Vjb25kLnRyLCBoPTQpDQpldHMubWlkZGxlLnByZWQgPC0gZm9yZWNhc3QoZXRzLm1pZGRsZS50ciwgaD00KQ0KZXRzLmZvdXJ0aC5wcmVkIDwtIGZvcmVjYXN0KGV0cy5mb3VydGgudHIsIGg9NCkNCmV0cy5oaWdoZXN0LnByZWQgPC0gZm9yZWNhc3QoZXRzLmhpZ2hlc3QudHIsIGg9NCkNCmV0cy50b3AucHJlZCA8LSBmb3JlY2FzdChldHMudG9wLnRyLCBoPTQpDQoNCmFjY3VyYWN5KGV0cy5sb3dlc3QucHJlZCwgdGVzdC5sb3dlc3QuaW5jb21lKQ0KYWNjdXJhY3koZXRzLnNlY29uZC5wcmVkLCB0ZXN0LnNlY29uZC5pbmNvbWUpDQphY2N1cmFjeShldHMubWlkZGxlLnByZWQsIHRlc3QubWlkZGxlLmluY29tZSkNCmFjY3VyYWN5KGV0cy5mb3VydGgucHJlZCwgdGVzdC5mb3VydGguaW5jb21lKQ0KYWNjdXJhY3koZXRzLmhpZ2hlc3QucHJlZCwgdGVzdC5oaWdoZXN0LmluY29tZSkNCmFjY3VyYWN5KGV0cy50b3AucHJlZCwgdGVzdC50b3AuaW5jb21lKQ0KDQpgYGANCg0KYGBge3J9DQpldHMubG93ZXN0IDwtIGV0cyhsb3dlc3QuaW5jb21lLnRzLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLnNlY29uZCA8LSBldHMoc2Vjb25kLmluY29tZS50cywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5taWRkbGUgPC0gZXRzKG1pZGRsZS5pbmNvbWUudHMsIG1vZGVsID0gIlpaWiIsIGRhbXBlZCA9IFRSVUUpDQpldHMuZm91cnRoIDwtIGV0cyhmb3VydGguaW5jb21lLnRzLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLmhpZ2hlc3QgPC0gZXRzKGhpZ2hlc3QuaW5jb21lLnRzLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLnRvcCA8LSBldHModG9wLmluY29tZS50cywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCg0KZXRzLmxvd2VzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdChldHMubG93ZXN0LCBoPTYpDQpldHMuc2Vjb25kLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGV0cy5zZWNvbmQsIGg9NikNCmV0cy5taWRkbGUuZm9yZWNhc3QgPC0gZm9yZWNhc3QoZXRzLm1pZGRsZSwgaD02KQ0KZXRzLmZvdXJ0aC5mb3JlY2FzdCA8LSBmb3JlY2FzdChldHMuZm91cnRoLCBoPTYpDQpldHMuaGlnaGVzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdChldHMuaGlnaGVzdCwgaD02KQ0KZXRzLnRvcC5mb3JlY2FzdCA8LSBmb3JlY2FzdChldHMudG9wLCBoPTYpDQoNCmF1dG9wbG90KGluY29tZS50cykgKyBhdXRvbGF5ZXIoZXRzLmxvd2VzdC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLm1pZGRsZS5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLmhpZ2hlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGV0cy50b3AuZm9yZWNhc3QpDQoNCmF1dG9wbG90KGluY29tZS5xdWludGlsZS50cykgKyBhdXRvbGF5ZXIoZXRzLmxvd2VzdC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLm1pZGRsZS5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZXRzLmhpZ2hlc3QuZm9yZWNhc3QpDQpgYGANCg0KRVRTIEJveENveCBNb2RlbCBQcmVkaWN0aW9uDQpgYGB7cn0NCmV0cy5sb3dlc3QudHIuYmMgPC0gZXRzKHRyLmxvd2VzdC5pbmNvbWUuYmMsIG1vZGVsID0gIlpaWiIsIGRhbXBlZCA9IFRSVUUpDQpldHMuc2Vjb25kLnRyLmJjIDwtIGV0cyh0ci5zZWNvbmQuaW5jb21lLmJjLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLm1pZGRsZS50ci5iYyA8LSBldHModHIubWlkZGxlLmluY29tZS5iYywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5mb3VydGgudHIuYmMgPC0gZXRzKHRyLmZvdXJ0aC5pbmNvbWUuYmMsIG1vZGVsID0gIlpaWiIsIGRhbXBlZCA9IFRSVUUpDQpldHMuaGlnaGVzdC50ci5iYyA8LSBldHModHIuaGlnaGVzdC5pbmNvbWUuYmMsIG1vZGVsID0gIlpaWiIsIGRhbXBlZCA9IFRSVUUpDQpldHMudG9wLnRyLmJjIDwtIGV0cyh0ci50b3AuaW5jb21lLmJjLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KDQpldHMubG93ZXN0LnByZWQuYmMgPC0gZm9yZWNhc3QoZXRzLmxvd2VzdC50ci5iYywgaD00KQ0KZXRzLnNlY29uZC5wcmVkLmJjIDwtIGZvcmVjYXN0KGV0cy5zZWNvbmQudHIuYmMsIGg9NCkNCmV0cy5taWRkbGUucHJlZC5iYyA8LSBmb3JlY2FzdChldHMubWlkZGxlLnRyLmJjLCBoPTQpDQpldHMuZm91cnRoLnByZWQuYmMgPC0gZm9yZWNhc3QoZXRzLmZvdXJ0aC50ci5iYywgaD00KQ0KZXRzLmhpZ2hlc3QucHJlZC5iYyA8LSBmb3JlY2FzdChldHMuaGlnaGVzdC50ci5iYywgaD00KQ0KZXRzLnRvcC5wcmVkLmJjIDwtIGZvcmVjYXN0KGV0cy50b3AudHIuYmMsIGg9NCkNCg0KYWNjdXJhY3koZXRzLmxvd2VzdC5wcmVkLmJjLCB0ZXN0Lmxvd2VzdC5pbmNvbWUuYmMpDQphY2N1cmFjeShldHMuc2Vjb25kLnByZWQuYmMsIHRlc3Quc2Vjb25kLmluY29tZS5iYykNCmFjY3VyYWN5KGV0cy5taWRkbGUucHJlZC5iYywgdGVzdC5taWRkbGUuaW5jb21lLmJjKQ0KYWNjdXJhY3koZXRzLmZvdXJ0aC5wcmVkLmJjLCB0ZXN0LmZvdXJ0aC5pbmNvbWUuYmMpDQphY2N1cmFjeShldHMuaGlnaGVzdC5wcmVkLmJjLCB0ZXN0LmhpZ2hlc3QuaW5jb21lLmJjKQ0KYWNjdXJhY3koZXRzLnRvcC5wcmVkLmJjLCB0ZXN0LnRvcC5pbmNvbWUuYmMpDQoNCmBgYA0KDQpgYGB7cn0NCmV0cy5sb3dlc3QuYmMgPC0gZXRzKGxvd2VzdC50cy5iYywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5zZWNvbmQuYmMgPC0gZXRzKHNlY29uZC50cy5iYywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5taWRkbGUuYmMgPC0gZXRzKG1pZGRsZS50cy5iYywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5mb3VydGguYmMgPC0gZXRzKGZvdXJ0aC50cy5iYywgbW9kZWwgPSAiWlpaIiwgZGFtcGVkID0gVFJVRSkNCmV0cy5oaWdoZXN0LmJjIDwtIGV0cyhoaWdoZXN0LnRzLmJjLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KZXRzLnRvcC5iYyA8LSBldHModG9wLnRzLmJjLCBtb2RlbCA9ICJaWloiLCBkYW1wZWQgPSBUUlVFKQ0KDQpldHMubG93ZXN0LmZvcmVjYXN0LmJjIDwtIGZvcmVjYXN0KGV0cy5sb3dlc3QuYmMsIGg9NikNCmV0cy5zZWNvbmQuZm9yZWNhc3QuYmMgPC0gZm9yZWNhc3QoZXRzLnNlY29uZC5iYywgaD02KQ0KZXRzLm1pZGRsZS5mb3JlY2FzdC5iYyA8LSBmb3JlY2FzdChldHMubWlkZGxlLmJjLCBoPTYpDQpldHMuZm91cnRoLmZvcmVjYXN0LmJjIDwtIGZvcmVjYXN0KGV0cy5mb3VydGguYmMsIGg9NikNCmV0cy5oaWdoZXN0LmZvcmVjYXN0LmJjIDwtIGZvcmVjYXN0KGV0cy5oaWdoZXN0LmJjLCBoPTYpDQpldHMudG9wLmZvcmVjYXN0LmJjIDwtIGZvcmVjYXN0KGV0cy50b3AuYmMsIGg9NikNCg0KYWNjdXJhY3koZXRzLmxvd2VzdC5iYykNCmFjY3VyYWN5KGV0cy5zZWNvbmQuYmMpDQphY2N1cmFjeShldHMubWlkZGxlLmJjKQ0KYWNjdXJhY3koZXRzLmZvdXJ0aC5iYykNCmFjY3VyYWN5KGV0cy5oaWdoZXN0LmJjKQ0KYWNjdXJhY3koZXRzLnRvcC5iYykNCg0KYGBgDQoNCg0KDQpBZnRlciBsb29raW5nIGF0IHRoZSBhY2N1cmFjeSBvZiBhbGwgdGhlIG1vZGVscywgd2UgZGV0ZXJtaW5lIHRoZSBBUklNQSBtb2RlbCB0byBiZSB0aGUgYmVzdCBhdCBmb3JlY2FzdGluZyB0aGUgYm90dG9tIHR3byBkaXN0cmlidXRpb25zIGFuZCB0aGUgbGluZWFyIGhvbHQgbW9kZWwgdG8gYmV0IHRoZSBiZXN0IGF0IGZvcmVjYXN0aW5nIHRoZSByZXN0LiBXaGlsZSB0aGUgRVRTIG1vZGVsIHdhcyBiZXR0ZXIgYXQgY2FwdHVyaW5nIHRoZSBleGlzdGluZyBkYXRhLCB0aGUgQVJJTUEgbW9kZWwgaGFkIGxvd2VyIFJNU0Ugc2NvcmVzIHJlZ2FyZGluZyB0aGUgdGVzdCBzZXQuIEFzIHRoZSBwdXJwb3NlIG9mIHRoaXMgcHJvamVjdCBpcyB0byBmb3JlY2FzdCBkaXN0cmlidXRpb24gcmF0aGVyIHRoYW4gdW5kZXJzdGFuZCBwcmV2aW91cyBpbmNvbWUgZGlzdHJpYnV0aW9ucywgd2Ugd2lsbCB1c2UgdGhlIEFSSU1BIG1vZGVsLiBHb2luZyBvZmYgb2YgdGhpcywgdGhlIEhvbHQgbW9kZWwgaGFkIGJldHRlciB0ZXN0IHNldCBSTVNFIHRoYW4gdGhlIEFSSU1BIG1vZGVsIGZyb20gdGhlIG1pZGRsZSBxdWludGlsZSBvbndhcmQuIEl0IHNob3VsZCBiZSBub3RlZCB0aGF0IHRoZSBub24tZGFtcGVkIGxpbmVhciBIb2x0IG1ldGhvZCBoYXMgdGhlIHRlbmRlbmN5IHRvIG92ZXItY2FzdC4gVGhhdCBzYWlkLCBpdCBzaG91bGQgYmUgbm8gc3VycHJpc2UgdG8gZmluZCB0aGF0IHRoZSBpbmNyZWFzZSBpbiB0cmVuZCBmb3IgdGhlIGhpZ2hlc3QgcXVpbnRpbGUgb3IgdGhlIHRvcCAxJSBvdmVycGVyZm9ybXMgYW55IG1vZGVsLiBJdCBpcyBhbHNvIGludGVyZXN0aW5nIHRvIG5vdGUgdGhhdCB0aGUgQVJJTUEgbW9kZWwgd29ya3MgYmVzdCBvbiB0aGUgdHdvIHF1aW50aWxlcyB3aXRoIHRoZSBtb3N0IG9idmlvdXMgYW5kIHN0ZWFkeSB0cmVuZCwgd2hlcmUgdGhlIGZvcmVjYXN0IGZvciB0aW1lIFQgaXMgdXN1YWxseSBoaWdobHkgY29ycmVsYXRlZCB3aXRoIHRoZSBvYnNlcnZhdGlvbiBhdCB0aW1lIFQtMSBhcyB0aGUgQVJJTUEgbW9kZWwgZG9lcywgd2hpbGUgdGhlIGhpZ2hlciBpbmNvbWUgcXVpbnRpbGVzIGFyZSBtb3JlIGFjY3VyYXRlbHkgZm9yZWNhc3QgdXNpbmcgYW4gdW5kZXJseWluZyB0cmVuZCBzaG93biBieSB0aGUgTGluZWFyIEhvbHQgbW9kZWwuDQooQVJJTUEgd2FzIHVzZWQgYWNyb3NzIHRoZSBib2FyZCBpbiB0aGUgZmlyc3QgZHJhZnQsIHNvIGRvd25sb2FkZWQgZGF0YSBuYW1lcyByZWZsZWN0IHRoaXMuIEkgd2lsbCBhdHRlbXB0IHRvIGZpeCB0aGlzIGdvaW5nIGZvcndhcmQpDQoNCkZ1bGwgRGF0YSBTZXQNCmBgYHtyfQ0KYXJpbWFfaW5jb21lX2RhdGEgPC0gcmVhZF9leGNlbCgiYXJpbWFfaW5jb21lX2RhdGEueGxzeCIpDQpgYGANCg0KYGBge3J9DQpmaW5hbC5sb3dlc3QuaW5jb21lIDwtIGFyaW1hX2luY29tZV9kYXRhJGBMb3dlc3QgUXVhbnRpbGVgDQpmaW5hbC5zZWNvbmQuaW5jb21lIDwtIGFyaW1hX2luY29tZV9kYXRhJGBTZWNvbmQgUXVhbnRpbGVgDQpmaW5hbC5taWRkbGUuaW5jb21lIDwtIGFyaW1hX2luY29tZV9kYXRhJGBNaWRkbGUgUXVhbnRpbGVgDQpmaW5hbC5mb3VydGguaW5jb21lIDwtIGFyaW1hX2luY29tZV9kYXRhJGBGb3VydGggUXVhbnRpbGVgDQpmaW5hbC5oaWdoZXN0LmluY29tZSA8LSBhcmltYV9pbmNvbWVfZGF0YSRgSGlnaGVzdCBRdWFudGlsZWANCmZpbmFsLjgwLmluY29tZSA8LSBhcmltYV9pbmNvbWVfZGF0YSRgMC44YA0KZmluYWwuOTAuaW5jb21lIDwtIGFyaW1hX2luY29tZV9kYXRhJGAwLjlgDQpmaW5hbC45Ni5pbmNvbWUgPC0gYXJpbWFfaW5jb21lX2RhdGEkYDAuOTZgDQoNCmZpbmFsLnRvcC5pbmNvbWUgPC0gYXJpbWFfaW5jb21lX2RhdGEkYFRvcCBRdWFudGlsZWANCg0KDQpmaW5hbC5sb3dlc3QuaW5jb21lLnRzIDwtIHRzKGZpbmFsLmxvd2VzdC5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZmluYWwuc2Vjb25kLmluY29tZS50cyA8LSB0cyhmaW5hbC5zZWNvbmQuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmZpbmFsLm1pZGRsZS5pbmNvbWUudHMgPC0gdHMoZmluYWwubWlkZGxlLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpmaW5hbC5mb3VydGguaW5jb21lLnRzIDwtIHRzKGZpbmFsLmZvdXJ0aC5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZmluYWwuaGlnaGVzdC5pbmNvbWUudHMgPC0gdHMoZmluYWwuaGlnaGVzdC5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZmluYWwuODAuaW5jb21lLnRzIDwtIHRzKGZpbmFsLjgwLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpmaW5hbC45MC5pbmNvbWUudHMgPC0gdHMoZmluYWwuOTAuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmZpbmFsLjk2LmluY29tZS50cyA8LSB0cyhmaW5hbC45Ni5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZmluYWwudG9wLmluY29tZS50cyA8LSB0cyhmaW5hbC50b3AuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCg0KYGBgDQoNCg0KYGBge3J9DQpjb3JyLmFyaW1hLmluY29tZSA8LSBjb3IoYXJpbWFfaW5jb21lX2RhdGEpDQpjb3JycGxvdChjb3JyLmFyaW1hLmluY29tZSwgbWV0aG9kPWMoIm51bWJlciIpKQ0KaW5jb21lLmZpbmFsLnRzIDwtIHRzKGFyaW1hX2luY29tZV9kYXRhLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmF1dG9wbG90KGluY29tZS5maW5hbC50cykNCmBgYA0KDQoNCkJlc3QgTW9kZWwNCg0KYGBge3J9DQpmaW5hbC5sb3dlc3QgPC0gYXV0by5hcmltYShmaW5hbC5sb3dlc3QuaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KZmluYWwuc2Vjb25kIDwtIGF1dG8uYXJpbWEoZmluYWwuc2Vjb25kLmluY29tZS50cywgc2Vhc29uYWwgPSBGQUxTRSkNCmZpbmFsLm1pZGRsZSA8LSBhdXRvLmFyaW1hKGZpbmFsLm1pZGRsZS5pbmNvbWUudHMsIHNlYXNvbmFsID0gRkFMU0UpDQpmaW5hbC5mb3VydGggPC0gYXV0by5hcmltYShmaW5hbC5mb3VydGguaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KZmluYWwuaGlnaGVzdCA8LSBhdXRvLmFyaW1hKGZpbmFsLmhpZ2hlc3QuaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KZmluYWwuODAgPC0gYXV0by5hcmltYShmaW5hbC44MC5pbmNvbWUudHMsIHNlYXNvbmFsID0gRkFMU0UpDQpmaW5hbC45MCA8LSBhdXRvLmFyaW1hKGZpbmFsLjkwLmluY29tZS50cywgc2Vhc29uYWwgPSBGQUxTRSkNCmZpbmFsLjk2IDwtIGF1dG8uYXJpbWEoZmluYWwuOTYuaW5jb21lLnRzLCBzZWFzb25hbCA9IEZBTFNFKQ0KZmluYWwudG9wIDwtIGF1dG8uYXJpbWEoZmluYWwudG9wLmluY29tZS50cywgc2Vhc29uYWwgPSBGQUxTRSkNCg0KZmluYWwubG93ZXN0LmZvcmVjYXN0IDwtIGZvcmVjYXN0KGZpbmFsLmxvd2VzdCwgaD02KQ0KZmluYWwuc2Vjb25kLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGZpbmFsLnNlY29uZCwgaD02KQ0KZmluYWwubWlkZGxlLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGZpbmFsLm1pZGRsZSwgaD02KQ0KZmluYWwuZm91cnRoLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGZpbmFsLmZvdXJ0aCwgaD02KQ0KZmluYWwuaGlnaGVzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdChmaW5hbC5oaWdoZXN0LCBoPTYpDQpmaW5hbC44MC5mb3JlY2FzdCA8LSBmb3JlY2FzdChmaW5hbC44MCwgaD02KQ0KZmluYWwuOTAuZm9yZWNhc3QgPC0gZm9yZWNhc3QoZmluYWwuOTAsIGg9NikNCmZpbmFsLjk2LmZvcmVjYXN0IDwtIGZvcmVjYXN0KGZpbmFsLjk2LCBoPTYpDQpmaW5hbC50b3AuZm9yZWNhc3QgPC0gZm9yZWNhc3QoZmluYWwudG9wLCBoPTYpDQoNCg0KYXV0b3Bsb3QoaW5jb21lLmZpbmFsLnRzLCBtYWluID0gIkJlc3QgUXVhbnRpbGUgRm9yZWNhc3QiKSArIGF1dG9sYXllcihmaW5hbC5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihmaW5hbC5mb3VydGguZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLjgwLmZvcmVjYXN0KSArIGF1dG9sYXllcihmaW5hbC45MC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwuOTYuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLnRvcC5mb3JlY2FzdCkNCg0KYXV0b3Bsb3QoaW5jb21lLnF1aW50aWxlLnRzLCBtYWluID0gIkJlc3QgUXVpbnRpbGUgRm9yZWNhc3QiKSArIGF1dG9sYXllcihmaW5hbC5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihmaW5hbC5mb3VydGguZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLmhpZ2hlc3QuZm9yZWNhc3QpDQoNCg0KYGBgDQoNCkFSSU1BIERpc3RyaWJ1dGlvbiBGb3JlY2FzdA0KYGBge3J9DQpmaW5hbC50b3RhbC5mb3JlY2FzdCA8LSBmaW5hbC5sb3dlc3QuZm9yZWNhc3QkbWVhbiArIGZpbmFsLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgZmluYWwubWlkZGxlLmZvcmVjYXN0JG1lYW4gKyBmaW5hbC5mb3VydGguZm9yZWNhc3QkbWVhbiArIGZpbmFsLjgwLmZvcmVjYXN0JG1lYW4gKyBmaW5hbC45MC5mb3JlY2FzdCRtZWFuICsgZmluYWwuOTYuZm9yZWNhc3QkbWVhbiArIGZpbmFsLnRvcC5mb3JlY2FzdCRtZWFuDQoNCmZpbmFsLmxvd2VzdC5mb3JlY2FzdC5zaGFyZSA8LSBmaW5hbC5sb3dlc3QuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdA0KZmluYWwuc2Vjb25kLmZvcmVjYXN0LnNoYXJlIDwtIGZpbmFsLnNlY29uZC5mb3JlY2FzdCRtZWFuL2ZpbmFsLnRvdGFsLmZvcmVjYXN0DQpmaW5hbC5taWRkbGUuZm9yZWNhc3Quc2hhcmUgPC0gZmluYWwubWlkZGxlLmZvcmVjYXN0JG1lYW4vZmluYWwudG90YWwuZm9yZWNhc3QNCmZpbmFsLmZvdXJ0aC5mb3JlY2FzdC5zaGFyZSA8LSBmaW5hbC5mb3VydGguZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdA0KZmluYWwuODAuZm9yZWNhc3Quc2hhcmUgPC0gZmluYWwuODAuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdA0KZmluYWwuOTAuZm9yZWNhc3Quc2hhcmUgPC0gZmluYWwuOTAuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdA0KZmluYWwuOTYuZm9yZWNhc3Quc2hhcmUgPC0gZmluYWwuOTYuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdA0KZmluYWwudG9wLmZvcmVjYXN0LnNoYXJlIDwtIGZpbmFsLnRvcC5mb3JlY2FzdCRtZWFuL2ZpbmFsLnRvdGFsLmZvcmVjYXN0DQoNCmF1dG9wbG90KGZpbmFsLmxvd2VzdC5mb3JlY2FzdC5zaGFyZSkgKyBhdXRvbGF5ZXIoZmluYWwuc2Vjb25kLmZvcmVjYXN0LnNoYXJlKSArIGF1dG9sYXllcihmaW5hbC5taWRkbGUuZm9yZWNhc3Quc2hhcmUpICsgYXV0b2xheWVyKGZpbmFsLmZvdXJ0aC5mb3JlY2FzdC5zaGFyZSkgKyBhdXRvbGF5ZXIoZmluYWwuODAuZm9yZWNhc3Quc2hhcmUpICsgYXV0b2xheWVyKGZpbmFsLjkwLmZvcmVjYXN0LnNoYXJlKSArIGF1dG9sYXllcihmaW5hbC45Ni5mb3JlY2FzdC5zaGFyZSkgKyBhdXRvbGF5ZXIoZmluYWwudG9wLmZvcmVjYXN0LnNoYXJlKQ0KDQpmaW5hbC50b3RhbC5mb3JlY2FzdC5xdWludGlsZSA8LSBmaW5hbC5sb3dlc3QuZm9yZWNhc3QkbWVhbiArIGZpbmFsLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgZmluYWwubWlkZGxlLmZvcmVjYXN0JG1lYW4gKyBmaW5hbC5mb3VydGguZm9yZWNhc3QkbWVhbiArIGZpbmFsLmhpZ2hlc3QuZm9yZWNhc3QkbWVhbg0KDQpmaW5hbC5sb3dlc3QuZm9yZWNhc3Quc2hhcmUucXVpbnRpbGUgPC0gZmluYWwubG93ZXN0LmZvcmVjYXN0JG1lYW4vZmluYWwudG90YWwuZm9yZWNhc3QucXVpbnRpbGUNCmZpbmFsLnNlY29uZC5mb3JlY2FzdC5zaGFyZS5xdWludGlsZSA8LSBmaW5hbC5zZWNvbmQuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbC5mb3JlY2FzdC5xdWludGlsZQ0KZmluYWwubWlkZGxlLmZvcmVjYXN0LnNoYXJlLnF1aW50aWxlIDwtIGZpbmFsLm1pZGRsZS5mb3JlY2FzdCRtZWFuL2ZpbmFsLnRvdGFsLmZvcmVjYXN0LnF1aW50aWxlDQpmaW5hbC5mb3VydGguZm9yZWNhc3Quc2hhcmUucXVpbnRpbGUgPC0gZmluYWwuZm91cnRoLmZvcmVjYXN0JG1lYW4vZmluYWwudG90YWwuZm9yZWNhc3QucXVpbnRpbGUNCmZpbmFsLmhpZ2hlc3QuZm9yZWNhc3Quc2hhcmUucXVpbnRpbGUgPC0gZmluYWwuaGlnaGVzdC5mb3JlY2FzdCRtZWFuL2ZpbmFsLnRvdGFsLmZvcmVjYXN0LnF1aW50aWxlDQoNCmF1dG9wbG90KGZpbmFsLmxvd2VzdC5mb3JlY2FzdC5zaGFyZS5xdWludGlsZSwgbWFpbiA9ICJRdWludGlsZSBTaGFyZSBGb3JlY2FzdCIpICsgYXV0b2xheWVyKGZpbmFsLnNlY29uZC5mb3JlY2FzdC5zaGFyZS5xdWludGlsZSkgKyBhdXRvbGF5ZXIoZmluYWwubWlkZGxlLmZvcmVjYXN0LnNoYXJlLnF1aW50aWxlKSArIGF1dG9sYXllcihmaW5hbC5mb3VydGguZm9yZWNhc3Quc2hhcmUucXVpbnRpbGUpICsgYXV0b2xheWVyKGZpbmFsLmhpZ2hlc3QuZm9yZWNhc3Quc2hhcmUucXVpbnRpbGUpDQoNCmBgYA0KDQpXaXRoIHRoZSBtb3N0IGFjY3VyYXRlIGZvcmVjYXN0cyBvZiBpbmNvbWUgaW4gdGhlIGZ1dHVyZSwgd2Ugc2VlIHRoYXQgdGhlIGhpZ2hlc3QgcXVpbnRpbGUgd2lsbCBvbmx5IGNhcHR1cmUgYSBsYXJnZXIgYW5kIGxhcmdlciBzaGFyZSBvZiB0b3RhbCBHRFAgaW4gdGhlIFVTLCB3aXRoIGFsbCBvdGhlciBxdWludGlsZXMgZGVjcmVhc2luZyBvdmVyIHRpbWUuIFRoaXMgdHJlbmQgaXMgZnVydGhlciB3b3JyeWluZyBnaXZlbiB0aGF0IHRoZSBkZWNvbXBvc2VkIGhpZ2hlc3QgcXVpbnRpbGUgZm9yZWNhc3Qgc2hvd3MgdGhhdCBhbGwgb2YgdGhpcyBwb3NpdGl2ZSByZWxhdGl2ZSB0cmVuZCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIHRvcCAxJSBvZiBpbmNvbWVzLiBXZSBldmVuIHNlZSB0aGUgdG9wIDElIG91dGNsYXNzaW5nIHRoZSBnYWlucyBpbiBldmVyeSBvdGhlciBxdWFudGlsZSBpbmNsdWRpbmcgdGhhdCB3aGljaCBtYWtlcyB1cCB0aGUgcmVzdCBvZiB0aGUgaGlnaGVzdCBxdWFudGlsZSBzdWNoIHRoYXQgZXZlbiB0aG9zZSB3aWxsIGRlY3JlYXNlIGFzIGEgc2hhcmUgb2YgdG90YWwgaW5jb21lIG92ZXIgdGltZS4gDQoNCmBgYHtyfQ0KDQpob2x0LjgwIDwtIGZvcmVjYXN0KGZpbmFsLjgwLmluY29tZS50cywgaD02KQ0KaG9sdC45MCA8LSBmb3JlY2FzdChmaW5hbC45MC5pbmNvbWUudHMsIGg9NikNCmhvbHQuOTYgPC0gZm9yZWNhc3QoZmluYWwuOTYuaW5jb21lLnRzLCBoPTYpDQoNCmhvbHQudG90YWwgPC0gZmluYWwubG93ZXN0LmZvcmVjYXN0JG1lYW4gKyBmaW5hbC5zZWNvbmQuZm9yZWNhc3QkbWVhbiArIGZpbmFsLm1pZGRsZS5mb3JlY2FzdCRtZWFuICsgaG9sdC5mb3VydGgkbWVhbiArIGhvbHQuODAkbWVhbiArIGhvbHQuOTAkbWVhbiArIGhvbHQuOTYkbWVhbiArIGhvbHQudG9wJG1lYW4NCg0KaG9sdC5sb3dlc3Quc2hhcmUgPC0gZmluYWwubG93ZXN0LmZvcmVjYXN0JG1lYW4vaG9sdC50b3RhbA0KaG9sdC5zZWNvbmQuc2hhcmUgPC0gZmluYWwuc2Vjb25kLmZvcmVjYXN0JG1lYW4vaG9sdC50b3RhbA0KaG9sdC5taWRkbGUuc2hhcmUgPC0gZmluYWwubWlkZGxlLmZvcmVjYXN0JG1lYW4vaG9sdC50b3RhbA0KaG9sdC5mb3VydGguc2hhcmUgPC0gaG9sdC5mb3VydGgkbWVhbi9ob2x0LnRvdGFsDQpob2x0LjgwLnNoYXJlIDwtIGhvbHQuODAkbWVhbi9ob2x0LnRvdGFsDQpob2x0LjkwLnNoYXJlIDwtIGhvbHQuOTAkbWVhbi9ob2x0LnRvdGFsDQpob2x0Ljk2LnNoYXJlIDwtIGhvbHQuOTYkbWVhbi9ob2x0LnRvdGFsDQpob2x0LnRvcC5zaGFyZSA8LSBob2x0LnRvcCRtZWFuL2hvbHQudG90YWwNCg0KYXV0b3Bsb3QoaG9sdC5sb3dlc3Quc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuc2Vjb25kLnNoYXJlKSArIGF1dG9sYXllcihob2x0Lm1pZGRsZS5zaGFyZSkgKyBhdXRvbGF5ZXIoaG9sdC5mb3VydGguc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuODAuc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuOTAuc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuOTYuc2hhcmUpICsgYXV0b2xheWVyKGhvbHQudG9wLnNoYXJlKQ0KDQpgYGANCg0KVXNpbmcgdGhlIGxpbmVhciBIb2x0IG1vZGVsLCB3aGljaCB3YXMgdGhlIGJlc3QgYXQgZm9yZWNhc3Rpbmcgb3ZlciB0aGUgc2hvcnQtdGVybSBob3Jpem9uIGZvciB0aGUgZm91cnRoIHF1YW50aWxlIGFuZCBhYm92ZSwgd2Ugc2VlIHRoYXQgd2hpbGUgdGhlIGluY3JlYXNlIGluIHRoZSBzaGFyZSBvZiB0b3RhbCBpbmNvbWUgaXMgbm90IGZlbHQgYnkgdGhlIHRvcCAxJSwgdGhlIG1pZGRsZSBxdWludGlsZXMgYW5kIGxvd2VyIGFyZSBhbGwgbG9zaW5nIHRvdGFsIEdEUCBzaGFyZS4gV2Ugc2VlIHRoYXQgZGVjb21wb3NpbmcgdGhlIHRvcCAxJSBhbHRlcnMgdGhlIHNoYXJlIGNoYXJ0IHdpbGRseS4NCg0KYGBge3J9DQpmaW5hbC50b3RhbCA8LSBmaW5hbC5sb3dlc3QuZm9yZWNhc3QkbWVhbiArIGZpbmFsLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgZmluYWwubWlkZGxlLmZvcmVjYXN0JG1lYW4gKyBob2x0LmZvdXJ0aCRtZWFuICsgaG9sdC5oaWdoZXN0JG1lYW4NCg0KaG9sdC5sb3dlc3Quc2hhcmUgPC0gZmluYWwubG93ZXN0LmZvcmVjYXN0JG1lYW4vZmluYWwudG90YWwNCmhvbHQuc2Vjb25kLnNoYXJlIDwtIGZpbmFsLnNlY29uZC5mb3JlY2FzdCRtZWFuL2ZpbmFsLnRvdGFsDQpob2x0Lm1pZGRsZS5zaGFyZSA8LSBmaW5hbC5taWRkbGUuZm9yZWNhc3QkbWVhbi9maW5hbC50b3RhbA0KaG9sdC5mb3VydGguc2hhcmUgPC0gaG9sdC5mb3VydGgkbWVhbi9maW5hbC50b3RhbA0KaG9sdC5oaWdoZXN0LnNoYXJlIDwtIGhvbHQuaGlnaGVzdCRtZWFuL2ZpbmFsLnRvdGFsDQoNCmF1dG9wbG90KGhvbHQubG93ZXN0LnNoYXJlKSArIGF1dG9sYXllcihob2x0LnNlY29uZC5zaGFyZSkgKyBhdXRvbGF5ZXIoaG9sdC5taWRkbGUuc2hhcmUpICsgYXV0b2xheWVyKGhvbHQuZm91cnRoLnNoYXJlKSArIGF1dG9sYXllcihob2x0LmhpZ2hlc3Quc2hhcmUpDQpgYGANCg0KDQoNCg0KVUJJIEFuYWx5c2lzDQoNCkRhdGEgUHJlcGFyYXRpb24NCmBgYHtyfQ0KdWJpLmFkZCA8LSBjKDM1NTQuMTgsIDM1NTQuMTgsIDQ0NTAuMDcsIDQ0NTAuMDcsIDQ4NzUuOTgsIDQ4NzUuOTgsIDUyNjcuNjIsIDUyNjcuNjIsIDU1NjEuMzYsIDU1NjEuMzYsIDYwNzAuNTAsIDYwNzAuNTAsIDY2NjcuNzUsIDY2NjcuNzUsIDcwNzQuMDksIDcwNzQuMDksIDc0NjAuODQsIDc0NjAuODQsIDc4NTcuMzgsIDc4NTcuMzgsIDgxNTYuMDEsIDgxNTYuMDEsIDg2NjUuMTQsIDg2NjUuMTQsIDkwMDcuODMsIDkwMDcuODMsIDk1NjEuMDMsIDk1NjEuMDMsIDEwMTUwLjU1LCAxMDE1MC41NSwgMTA1MDIuNzksIDEwNTAyLjc5LCAxMTAxMi4wMywgMTEwMTIuMDMsIDExNDA0LjU1LCAxMTQwNC41NSwgMTE2MDMuMzEsIDExNjAzLjMxLCAxMjAwMCkNCg0KdWJpLmluY29tZSA8LSBpbmNvbWVfZGF0YSArIHViaS5hZGQNCmBgYA0KDQpUaGlzIGlzIGJhc2VkIG9mZiBvZiBEZW1vY3JhdGljIDIwMjAgQ2FuZGlkYXRlIEFuZHJldyBZYW5nJ3MgcHJvcG9zZWQgJDEsMDAwIGEgbW9udGggcHJvcG9zYWwgZm9yIGEgVW5pdmVyc2FsIEJhc2ljIEluY29tZS4NCg0KDQpgYGB7cn0NCnViaS5sb3dlc3QuaW5jb21lIDwtIHViaS5pbmNvbWUkYExvd2VzdCBRdWludGlsZWANCnViaS5zZWNvbmQuaW5jb21lIDwtIHViaS5pbmNvbWUkYFNlY29uZCBRdWludGlsZWANCnViaS5taWRkbGUuaW5jb21lIDwtIHViaS5pbmNvbWUkYE1pZGRsZSBRdWludGlsZWANCnViaS5mb3VydGguaW5jb21lIDwtIHViaS5pbmNvbWUkYEZvdXJ0aCBRdWludGlsZWANCnViaS5oaWdoZXN0LmluY29tZSA8LSB1YmkuaW5jb21lJGBIaWdoZXN0IFF1aW50aWxlYA0KdWJpLnRvcC5pbmNvbWUgPC0gdWJpLmluY29tZSRgVG9wIDElYA0KDQp1YmkuaW5jb21lLnRzIDwtIHRzKHViaS5pbmNvbWUsIHN0YXJ0PTE5NzksIGVuZD0yMDE3LCBmcmVxdWVuY3kgPSAxKQ0KdWJpLmluY29tZS5xdWludGlsZS50cyA8LSB0cyh1YmkuaW5jb21lWzE6NV0sIHN0YXJ0PTE5NzksIGVuZD0yMDE3LCBmcmVxdWVuY3kgPSAxKQ0KDQpsb3dlc3QudHMudWJpIDwtIHRzKHViaS5sb3dlc3QuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCnNlY29uZC50cy51YmkgPC0gdHModWJpLnNlY29uZC5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KbWlkZGxlLnRzLnViaSA8LSB0cyh1YmkubWlkZGxlLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpmb3VydGgudHMudWJpIDwtIHRzKHViaS5mb3VydGguaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmhpZ2hlc3QudHMudWJpIDwtIHRzKHViaS5oaWdoZXN0LmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQp0b3AudHMudWJpIDwtIHRzKHViaS50b3AuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCg0KYGBgDQoNCmBgYHtyfQ0KdWJpLmxvd2VzdCA8LSBhdXRvLmFyaW1hKGxvd2VzdC50cy51YmksIHNlYXNvbmFsID0gRkFMU0UpDQp1Ymkuc2Vjb25kIDwtIGF1dG8uYXJpbWEoc2Vjb25kLnRzLnViaSwgc2Vhc29uYWwgPSBGQUxTRSkNCnViaS5taWRkbGUgPC0gYXV0by5hcmltYShtaWRkbGUudHMudWJpLCBzZWFzb25hbCA9IEZBTFNFKQ0KdWJpLmZvdXJ0aCA8LSBhdXRvLmFyaW1hKGZvdXJ0aC50cy51YmksIHNlYXNvbmFsID0gRkFMU0UpDQp1YmkuaGlnaGVzdCA8LSBhdXRvLmFyaW1hKGhpZ2hlc3QudHMudWJpLCBzZWFzb25hbCA9IEZBTFNFKQ0KdWJpLnRvcCA8LSBhdXRvLmFyaW1hKHRvcC50cy51YmksIHNlYXNvbmFsID0gRkFMU0UpDQoNCg0KdWJpLmxvd2VzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdCh1YmkubG93ZXN0LCBoPTYpDQp1Ymkuc2Vjb25kLmZvcmVjYXN0IDwtIGZvcmVjYXN0KHViaS5zZWNvbmQsIGg9NikNCnViaS5taWRkbGUuZm9yZWNhc3QgPC0gZm9yZWNhc3QodWJpLm1pZGRsZSwgaD02KQ0KdWJpLmZvdXJ0aC5mb3JlY2FzdCA8LSBmb3JlY2FzdCh1YmkuZm91cnRoLCBoPTYpDQp1YmkuaGlnaGVzdC5mb3JlY2FzdCA8LSBmb3JlY2FzdCh1YmkuaGlnaGVzdCwgaD02KQ0KdWJpLnRvcC5mb3JlY2FzdCA8LSBmb3JlY2FzdCh1YmkudG9wLCBoPTYpDQoNCmF1dG9wbG90KHViaS5pbmNvbWUucXVpbnRpbGUudHMpICsgYXV0b2xheWVyKHViaS5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5taWRkbGUuZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5mb3VydGguZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5oaWdoZXN0LmZvcmVjYXN0KQ0KDQpgYGANCg0KYGBge3J9DQp0b3RhbC5mb3JlY2FzdC51YmkgPC0gdWJpLmxvd2VzdC5mb3JlY2FzdCRtZWFuICsgdWJpLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgdWJpLm1pZGRsZS5mb3JlY2FzdCRtZWFuICsgdWJpLmZvdXJ0aC5mb3JlY2FzdCRtZWFuICsgdWJpLmhpZ2hlc3QuZm9yZWNhc3QkbWVhbg0KDQpsb3dlc3Quc2hhcmUgPC0gdWJpLmxvd2VzdC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnViaQ0Kc2Vjb25kLnNoYXJlIDwtIHViaS5zZWNvbmQuZm9yZWNhc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51YmkNCm1pZGRsZS5zaGFyZSA8LSB1YmkubWlkZGxlLmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJpDQpmb3VydGguc2hhcmUgPC0gdWJpLmZvdXJ0aC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnViaQ0KaGlnaGVzdC5zaGFyZSA8LSB1YmkuaGlnaGVzdC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnViaQ0KDQphdXRvcGxvdChsb3dlc3Quc2hhcmUsIG1haW4gPSAiVUJJIFNoYXJlIEZvcmVjYXN0IikgKyBhdXRvbGF5ZXIoc2Vjb25kLnNoYXJlKSArIGF1dG9sYXllcihtaWRkbGUuc2hhcmUpICsgYXV0b2xheWVyKGZvdXJ0aC5zaGFyZSkgKyBhdXRvbGF5ZXIoaGlnaGVzdC5zaGFyZSkNCg0KYGBgDQoNCldlIHNlZSB0aGF0IHRoZSBnYWlucyBpbiB0aGUgaGlnaGVzdCBxdWludGlsZSBzdGlsbCBvdXRjbGFzcyB0aG9zZSBvZiB0aGUgb3RoZXIgZm91ciBjb21iaW5lZC4gVGh1cywgYnkgcXVhbnRpdGF0aXZlIHN0YW5kYXJkcywgd2UgY2FuIGFzc3VtZSB0aGF0IHdoaWxlIHRoZSBVQkkgbWF5IGFkZHJlc3MgaW1tZWRpYXRlIHNob3J0Y29taW5ncyBpbiB0aGUgbWluaW11bSByZXF1aXJlZCBpbmNvbWUgdG8gc3Vydml2ZSwgaXQgd2lsbCBub3QgYWRkcmVzcyBpbmNvbWUgaW5lcXVhbGl0eSBvdmVyIHRoZSBsb25nIHRlcm0sIGdpdmVuIHRoZSBnYWlucyBieSB0aGUgaGlnaGVzdCBxdWludGlsZS4NCg0KYGBge3J9DQphcmltYS5sb3dlc3QuZm9yZWNhc3QudWJpLnNoYXJlDQphcmltYS5zZWNvbmQuZm9yZWNhc3QudWJpLnNoYXJlDQptaWRkbGUuZm9yZWNhc3QudWJpLnNoYXJlDQpmb3VydGguZm9yZWNhc3QudWJpLnNoYXJlDQpoaWdoZXN0LmZvcmVjYXN0LnViaS5zaGFyZQ0KYGBgDQoNCg0KVGFyZ2V0ZWQgVUJJIEFuYWx5c2lzDQoNCmBgYHtyfQ0KdWJpLmxvd2VzdC5pbmNvbWUgPC0gdWJpLmluY29tZSRgTG93ZXN0IFF1aW50aWxlYA0KdWJpLnNlY29uZC5pbmNvbWUgPC0gdWJpLmluY29tZSRgU2Vjb25kIFF1aW50aWxlYA0KdWJpLm1pZGRsZS5pbmNvbWUgPC0gdWJpLmluY29tZSRgTWlkZGxlIFF1aW50aWxlYA0KDQp1YmkuaW5jb21lLnRzIDwtIHRzKHViaS5pbmNvbWUsIHN0YXJ0PTE5NzksIGVuZD0yMDE3LCBmcmVxdWVuY3kgPSAxKQ0KdWJpLmluY29tZS5xdWludGlsZS50cyA8LSB0cyh1YmkuaW5jb21lLCBzdGFydD0xOTc5LCBlbmQ9MjAxNywgZnJlcXVlbmN5ID0gMSkNCg0KbG93ZXN0LnRzLnViaSA8LSB0cyh1YmkubG93ZXN0LmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQpzZWNvbmQudHMudWJpIDwtIHRzKHViaS5zZWNvbmQuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCm1pZGRsZS50cy51YmkgPC0gdHModWJpLm1pZGRsZS5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KDQp1YmkuaW5jb21lLnRhcmdldC50cyA8LSBjYmluZCh1YmkuaW5jb21lLnF1aW50aWxlLnRzLCBmb3VydGguaW5jb21lLnRzLCBoaWdoZXN0LmluY29tZS50cykNCg0KdWJpLmxvd2VzdCA8LSBhdXRvLmFyaW1hKGxvd2VzdC50cy51YmksIHNlYXNvbmFsID0gRkFMU0UpDQp1Ymkuc2Vjb25kIDwtIGF1dG8uYXJpbWEoc2Vjb25kLnRzLnViaSwgc2Vhc29uYWwgPSBGQUxTRSkNCnViaS5taWRkbGUgPC0gYXV0by5hcmltYShtaWRkbGUudHMudWJpLCBzZWFzb25hbCA9IEZBTFNFKQ0KDQp1YmkubG93ZXN0LmZvcmVjYXN0IDwtIGZvcmVjYXN0KHViaS5sb3dlc3QsIGg9NikNCnViaS5zZWNvbmQuZm9yZWNhc3QgPC0gZm9yZWNhc3QodWJpLnNlY29uZCwgaD02KQ0KdWJpLm1pZGRsZS5mb3JlY2FzdCA8LSBmb3JlY2FzdCh1YmkubWlkZGxlLCBoPTYpDQoNCmF1dG9wbG90KHViaS5pbmNvbWUucXVpbnRpbGUudHMpICsgYXV0b2xheWVyKHViaS5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKHViaS5taWRkbGUuZm9yZWNhc3QpICsgYXV0b2xheWVyKGhvbHQuZm91cnRoKSArIGF1dG9sYXllcihob2x0LmhpZ2hlc3QpICsgYXV0b2xheWVyKGhvbHQudG9wKQ0KDQp0b3RhbC5mb3JlY2FzdC51YmkgPC0gdWJpLmxvd2VzdC5mb3JlY2FzdCRtZWFuICsgdWJpLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgdWJpLm1pZGRsZS5mb3JlY2FzdCRtZWFuICsgaG9sdC5mb3VydGgkbWVhbiArIGhvbHQuaGlnaGVzdCRtZWFuDQoNCmxvd2VzdC5zaGFyZSA8LSB1YmkubG93ZXN0LmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJpDQpzZWNvbmQuc2hhcmUgPC0gdWJpLnNlY29uZC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnViaQ0KbWlkZGxlLnNoYXJlIDwtIHViaS5taWRkbGUuZm9yZWNhc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51YmkNCmZvdXJ0aC5zaGFyZSA8LSBob2x0LmZvdXJ0aCRtZWFuL3RvdGFsLmZvcmVjYXN0LnViaQ0KaGlnaGVzdC5zaGFyZSA8LSBob2x0LmhpZ2hlc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51YmkNCg0KYXV0b3Bsb3QobG93ZXN0LnNoYXJlLCBtYWluID0gIlVCSSBTaGFyZSBGb3JlY2FzdCIpICsgYXV0b2xheWVyKHNlY29uZC5zaGFyZSkgKyBhdXRvbGF5ZXIobWlkZGxlLnNoYXJlKSArIGF1dG9sYXllcihmb3VydGguc2hhcmUpICsgYXV0b2xheWVyKGhpZ2hlc3Quc2hhcmUpDQpgYGANCg0KYGBge3J9DQpsb3dlc3Quc2hhcmUNCnNlY29uZC5zaGFyZQ0KbWlkZGxlLnNoYXJlDQpmb3VydGguc2hhcmUNCmhpZ2hlc3Quc2hhcmUNCmBgYA0KDQpBIHRhcmdldGVkIFVCSSBkb2VzIGluIGZhY3QgYXNzaXN0IGluY29tZSBpbmVxdWFsaXR5LCBidXQgc3RpbGwgYXQgYSByZWR1Y2VkIHNwZWVkLiBUaGUgZ2FpbnMgbWFkZSBieSB0aGUgaGlnaGVzdCBxdWFudGlsZSBhcmUgc3RpbGwgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4NCg0KDQpXZSBjYW4gYWxzbyBzZWUgd2hhdCB3b3VsZCBoYXZlIGhhcHBlbmVkIGJldHdlZW4gMTk3OS0yMDE3IGhhZCBhIFVCSSBiZWVuIGltcGxlbWVudGVkLg0KYGBge3J9DQp0b3RhbC50aW1lLnViaSA8LSB1YmkubG93ZXN0LmluY29tZSArIHViaS5zZWNvbmQuaW5jb21lICsgdWJpLm1pZGRsZS5pbmNvbWUgKyBmb3VydGguaW5jb21lLnRzICsgaGlnaGVzdC5pbmNvbWUudHMNCg0KbG93ZXN0LnNoYXJlLnRpbWUgPC0gdWJpLmxvd2VzdC5pbmNvbWUvdG90YWwudGltZS51YmkNCnNlY29uZC5zaGFyZS50aW1lIDwtIHViaS5zZWNvbmQuaW5jb21lL3RvdGFsLnRpbWUudWJpDQptaWRkbGUuc2hhcmUudGltZSA8LSB1YmkubWlkZGxlLmluY29tZS90b3RhbC50aW1lLnViaQ0KZm91cnRoLnNoYXJlLnRpbWUgPC0gZm91cnRoLmluY29tZS50cy90b3RhbC50aW1lLnViaQ0KaGlnaGVzdC5zaGFyZS50aW1lIDwtIGhpZ2hlc3QuaW5jb21lLnRzL3RvdGFsLnRpbWUudWJpDQoNCmF1dG9wbG90KGxvd2VzdC5zaGFyZS50aW1lLCBtYWluID0gIlVCSSBTaGFyZSBGb3JlY2FzdCIpICsgYXV0b2xheWVyKHNlY29uZC5zaGFyZS50aW1lKSArIGF1dG9sYXllcihtaWRkbGUuc2hhcmUudGltZSkgKyBhdXRvbGF5ZXIoZm91cnRoLnNoYXJlLnRpbWUpICsgYXV0b2xheWVyKGhpZ2hlc3Quc2hhcmUudGltZSkNCmBgYA0KDQoNCg0KDQpXYWxsIFN0cmVldCBIeXBvdGhlc2lzDQoNCldlIG9mdGVuIGFsc28gaGVhciB0aGF0IGhpZ2hlci1pbmNvbWUgaW5kaXZpZHVhbHMgYXJlIGJldHRlciBhYmxlIHRvIHV0aWxpemUgc2F2aW5ncyBhbmQgY2FwaXRhbCB0byBlYXJuIGluY29tZSB0aGFua3MgdG8gdGhlaXIgYWJpbGl0eSB0byB0YXAgaW50byB0aGUgZ3Jvd3RoIGluIHRoZSBzdG9jayBtYXJrZXQuIEhlcmUsIHdlIGNoZWNrIGlmIHRoZSBTJlAgNTAwIGRhdGEgY2FuIGJlIHVzZWQgYXMgYW4gaW5kaWNhdG9yIGZvciB0aGUgaGlnaGVyIGluY29tZSBxdWFudGlsZXMnIHRpbWUgc2VyaWVzLg0KDQpgYGB7cn0NClNfUF9pbmNvbWUgPC0gcmVhZF9leGNlbCgiUyZQX2luY29tZS54bHN4IikNCmBgYA0KDQpEYXRhIFByZXBhcmF0aW9uDQpgYGB7cn0NCndhbGwubG93ZXN0LmluY29tZSA8LSBTX1BfaW5jb21lJGBMb3dlc3QgUXVhbnRpbGVgDQp3YWxsLnNlY29uZC5pbmNvbWUgPC0gU19QX2luY29tZSRgU2Vjb25kIFF1YW50aWxlYA0Kd2FsbC5taWRkbGUuaW5jb21lIDwtIFNfUF9pbmNvbWUkYE1pZGRsZSBRdWFudGlsZWANCndhbGwuZm91cnRoLmluY29tZSA8LSBTX1BfaW5jb21lJGBGb3VydGggUXVhbnRpbGVgDQp3YWxsLmhpZ2hlc3QuaW5jb21lIDwtIFNfUF9pbmNvbWUkYEhpZ2hlc3QgUXVhbnRpbGVgDQp3YWxsLnRvcC5pbmNvbWUgPC0gU19QX2luY29tZSRgVG9wIFF1YW50aWxlYA0Kd2FsbC5kYXRhIDwtIFNfUF9pbmNvbWUkYFMmUGANCg0KbG93ZXN0LnRzLndhbGwgPC0gdHMod2FsbC5sb3dlc3QuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCnNlY29uZC50cy53YWxsIDwtIHRzKHdhbGwuc2Vjb25kLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQptaWRkbGUudHMud2FsbCA8LSB0cyh3YWxsLm1pZGRsZS5pbmNvbWUsIHN0YXJ0PTE5NzksIGZyZXF1ZW5jeT0xKQ0KZm91cnRoLnRzLndhbGwgPC0gdHMod2FsbC5mb3VydGguaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCmhpZ2hlc3QudHMud2FsbCA8LSB0cyh3YWxsLmhpZ2hlc3QuaW5jb21lLCBzdGFydD0xOTc5LCBmcmVxdWVuY3k9MSkNCnRvcC50cy53YWxsIDwtIHRzKHdhbGwudG9wLmluY29tZSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQp3YWxsLnRzIDwtIHRzKHdhbGwuZGF0YSwgc3RhcnQ9MTk3OSwgZnJlcXVlbmN5PTEpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KY29yci5maW4uaW5jb21lIDwtIGNvcihTX1BfaW5jb21lKQ0KY29ycnBsb3QoY29yci5maW4uaW5jb21lLCBtZXRob2Q9YygibnVtYmVyIikpDQpgYGANCg0KYGBge3J9DQphcmltYS53YWxsLmxvd2VzdCA8LSBhdXRvLmFyaW1hKGxvd2VzdC50cy53YWxsLCB4cmVnID0gd2FsbC5kYXRhLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEud2FsbC5zZWNvbmQgPC0gYXV0by5hcmltYShzZWNvbmQudHMud2FsbCwgeHJlZyA9IHdhbGwuZGF0YSwgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLndhbGwubWlkZGxlIDwtIGF1dG8uYXJpbWEobWlkZGxlLnRzLndhbGwsIHhyZWcgPSB3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS53YWxsLmZvdXJ0aCA8LSBhdXRvLmFyaW1hKGZvdXJ0aC50cy53YWxsLCB4cmVnID0gd2FsbC5kYXRhLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEud2FsbC5oaWdoZXN0IDwtIGF1dG8uYXJpbWEoaGlnaGVzdC50cy53YWxsLCB4cmVnID0gd2FsbC5kYXRhLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEud2FsbC50b3AgPC0gYXV0by5hcmltYSh0b3AudHMud2FsbCwgeHJlZyA9IHdhbGwuZGF0YSwgc2Vhc29uYWwgPSBGQUxTRSkNCg0KYWNjdXJhY3koYXJpbWEud2FsbC5sb3dlc3QpDQphY2N1cmFjeShhcmltYS53YWxsLnNlY29uZCkNCmFjY3VyYWN5KGFyaW1hLndhbGwubWlkZGxlKQ0KYWNjdXJhY3koYXJpbWEud2FsbC5mb3VydGgpDQphY2N1cmFjeShhcmltYS53YWxsLmhpZ2hlc3QpDQphY2N1cmFjeShhcmltYS53YWxsLnRvcCkNCg0KYWNjdXJhY3koYXJpbWEubG93ZXN0KQ0KYWNjdXJhY3koYXJpbWEuc2Vjb25kKQ0KYWNjdXJhY3koYXJpbWEubWlkZGxlKQ0KYWNjdXJhY3koYXJpbWEuZm91cnRoKQ0KYWNjdXJhY3koYXJpbWEuaGlnaGVzdCkNCmFjY3VyYWN5KGFyaW1hLnRvcCkNCg0KYGBgDQoNCkludGVyZXN0aW5nbHksIHVzaW5nIGhpc3RvcmljYWwgUyZQIDUwMCBkYXRhIGFzIGNvbnRyaWJ1dGluZyBmYWN0b3Igb25seSBoZWxwcyB0aGUgYWNjdXJhY3kgb2YgdGhlIG1vZGVsIGZvciB0aGUgZm91cnRoIGRpc3RyaWJ1dGlvbiBhbmQgaGlnaGVyLg0KDQoNCg0KYGBge3J9DQp3YWxsLmRhdGEuYXJpbWEgPC0gYXV0by5hcmltYSh3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQp3YWxsLmRhdGEuZm9yZWNhc3QgPC0gZm9yZWNhc3Qod2FsbC5kYXRhLmFyaW1hLCBoPTYpDQp3YWxsLmRhdGEucHJlZCA8LSB3YWxsLmRhdGEuZm9yZWNhc3QkbWVhbg0KDQphcmltYS53YWxsLmZvdXJ0aC5mb3JlY2FzdCA8LSBmb3JlY2FzdChhcmltYS53YWxsLmZvdXJ0aCwgeHJlZyA9IHdhbGwuZGF0YS5wcmVkLCBoPTYpDQphcmltYS53YWxsLmhpZ2hlc3QuZm9yZWNhc3QgPC0gZm9yZWNhc3QoYXJpbWEud2FsbC5oaWdoZXN0LCB4cmVnID0gd2FsbC5kYXRhLnByZWQsIGg9NikNCmFyaW1hLndhbGwudG9wLmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLndhbGwudG9wLCB4cmVnID0gd2FsbC5kYXRhLnByZWQsIGg9NikNCg0KYXV0b3Bsb3QoaW5jb21lLnRzKSArIGF1dG9sYXllcihhcmltYS5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS53YWxsLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEud2FsbC5oaWdoZXN0LmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS53YWxsLnRvcC5mb3JlY2FzdCkNCg0KYXV0b3Bsb3QoaW5jb21lLnF1aW50aWxlLnRzKSArIGF1dG9sYXllcihhcmltYS5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnNlY29uZC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEubWlkZGxlLmZvcmVjYXN0KSArIGF1dG9sYXllcihhcmltYS53YWxsLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoYXJpbWEud2FsbC5oaWdoZXN0LmZvcmVjYXN0KQ0KDQpgYGANCg0KU2hhcmUgb2YgVG90YWwgR0RQIGFmdGVyIFMmUCBSZWdyZXNzaW9uDQpgYGB7cn0NCmFyaW1hLnRvdGFsLmZvcmVjYXN0LndhbGwgPC0gYXJpbWEubG93ZXN0LmZvcmVjYXN0JG1lYW4gKyBhcmltYS5zZWNvbmQuZm9yZWNhc3QkbWVhbiArIGFyaW1hLm1pZGRsZS5mb3JlY2FzdCRtZWFuICsgYXJpbWEud2FsbC5mb3VydGguZm9yZWNhc3QkbWVhbiArIGFyaW1hLndhbGwuaGlnaGVzdC5mb3JlY2FzdCRtZWFuDQoNCmFyaW1hLmxvd2VzdC5mb3JlY2FzdC53YWxsLnNoYXJlIDwtIGFyaW1hLmxvd2VzdC5mb3JlY2FzdCRtZWFuL2FyaW1hLnRvdGFsLmZvcmVjYXN0LndhbGwNCmFyaW1hLnNlY29uZC5mb3JlY2FzdC53YWxsLnNoYXJlIDwtIGFyaW1hLnNlY29uZC5mb3JlY2FzdCRtZWFuL2FyaW1hLnRvdGFsLmZvcmVjYXN0LndhbGwNCmFyaW1hLm1pZGRsZS5mb3JlY2FzdC53YWxsLnNoYXJlIDwtIGFyaW1hLm1pZGRsZS5mb3JlY2FzdCRtZWFuL2FyaW1hLnRvdGFsLmZvcmVjYXN0LndhbGwNCmFyaW1hLmZvdXJ0aC5mb3JlY2FzdC53YWxsLnNoYXJlIDwtIGFyaW1hLndhbGwuZm91cnRoLmZvcmVjYXN0JG1lYW4vYXJpbWEudG90YWwuZm9yZWNhc3Qud2FsbA0KYXJpbWEuaGlnaGVzdC5mb3JlY2FzdC53YWxsLnNoYXJlIDwtIGFyaW1hLndhbGwuaGlnaGVzdC5mb3JlY2FzdCRtZWFuL2FyaW1hLnRvdGFsLmZvcmVjYXN0LndhbGwNCg0KYXV0b3Bsb3QoYXJpbWEubG93ZXN0LmZvcmVjYXN0LndhbGwuc2hhcmUpICsgYXV0b2xheWVyKGFyaW1hLnNlY29uZC5mb3JlY2FzdC53YWxsLnNoYXJlKSArIGF1dG9sYXllcihhcmltYS5taWRkbGUuZm9yZWNhc3Qud2FsbC5zaGFyZSkgKyBhdXRvbGF5ZXIoYXJpbWEuZm91cnRoLmZvcmVjYXN0LndhbGwuc2hhcmUpICsgYXV0b2xheWVyKGFyaW1hLmhpZ2hlc3QuZm9yZWNhc3Qud2FsbC5zaGFyZSkNCg0KYGBgDQoNClVCTyBIeXBvdGhlc2lzDQoNCmBgYHtyfQ0KZWFybmluZ3MgPC0gU19QX2luY29tZSRgUyZQIEVhcm5pbmdzYA0Kbi5zaGFyZXMgPC0gMzU1NC4xOC93YWxsLnRzWzFdDQpuLnNoYXJlcw0KDQpgYGANCg0KVXNpbmcgQW5kcmV3IFlhbmcncyAkMTIsMDAwL3llYXIgaW5pdGlhbCBvZmZlciwgd2UgYXNzdW1lIHRoZSBlcXVpdmFsZW50IGFtb3VudCBvZiBidXlpbmcgcG93ZXIgZm9yIHRoZSAxOTc5IGFuZCBjYWxjdWxhdGUgZWFybmluZ3MgcGVyIHllYXIgYmFzZWQgb24gdGhlIG51bWJlciBvZiBzaGFyZXMgYm91Z2h0LCBhc3N1bWluZyB0aGUgZW50aXJlIHBvcnRmb2xpbyBpcyBwdXJlbHkgaW4gdGhlIFMmUCA1MDAuDQoNCmBgYHtyfQ0KdWJvLnRzIDwtIGVhcm5pbmdzKjMyLjkyNzM3DQpzbnAuZGlmZmVyZW5jZSA8LSB0YWlsKHViby50cywgbj0zOEwpDQp1Ym8gPC0gYygzNTU0LjE4LCBzbnAuZGlmZmVyZW5jZSkNCmBgYA0KDQoNCkRhdGEgUHJlcGFyYXRpb24NCmBgYHtyfQ0KbG93ZXN0LnRzLnVibyA8LSBsb3dlc3QuaW5jb21lLnRzICsgdWJvDQpzZWNvbmQudHMudWJvIDwtIHNlY29uZC5pbmNvbWUudHMgKyB1Ym8NCm1pZGRsZS50cy51Ym8gPC0gbWlkZGxlLmluY29tZS50cyArIHVibw0KDQp1Ym8uaW5jb21lIDwtIGNiaW5kKGxvd2VzdC50cy51Ym8sIHNlY29uZC50cy51Ym8sIG1pZGRsZS50cy51Ym8sIGZvdXJ0aC5pbmNvbWUudHMsIGZpbmFsLjgwLmluY29tZS50cywgZmluYWwuOTAuaW5jb21lLnRzLCBmaW5hbC45Ni5pbmNvbWUudHMsIGZpbmFsLnRvcC5pbmNvbWUudHMpDQp1Ym8uaW5jb21lLnF1aW50aWxlIDwtIGNiaW5kKGxvd2VzdC50cy51Ym8sIHNlY29uZC50cy51Ym8sIG1pZGRsZS50cy51Ym8sIGZvdXJ0aC5pbmNvbWUudHMsIGhpZ2hlc3QuaW5jb21lLnRzKQ0KDQphcmltYS51Ym8ubG93ZXN0IDwtIGF1dG8uYXJpbWEobG93ZXN0LnRzLnVibywgeHJlZyA9IHdhbGwuZGF0YSwgc2Vhc29uYWwgPSBGQUxTRSkNCmFyaW1hLnViby5zZWNvbmQgPC0gYXV0by5hcmltYShzZWNvbmQudHMudWJvLCB4cmVnID0gd2FsbC5kYXRhLCBzZWFzb25hbCA9IEZBTFNFKQ0KYXJpbWEudWJvLm1pZGRsZSA8LSBhdXRvLmFyaW1hKG1pZGRsZS50cy51Ym8sIHhyZWcgPSB3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0IDwtIGZvcmVjYXN0KGFyaW1hLnViby5sb3dlc3QsIHhyZWcgPSB3YWxsLmRhdGEucHJlZCwgaD02KQ0KYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdCA8LSBmb3JlY2FzdChhcmltYS51Ym8uc2Vjb25kLCB4cmVnID0gd2FsbC5kYXRhLnByZWQsIGg9NikNCmFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QgPC0gZm9yZWNhc3QoYXJpbWEudWJvLm1pZGRsZSwgeHJlZyA9IHdhbGwuZGF0YS5wcmVkLCBoPTYpDQoNCmF1dG9wbG90KHViby5pbmNvbWUpICsgYXV0b2xheWVyKGFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwuODAuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLjkwLmZvcmVjYXN0KSArIGF1dG9sYXllcihmaW5hbC45Ni5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwudG9wLmZvcmVjYXN0KQ0KDQphdXRvcGxvdCh1Ym8uaW5jb21lLnF1aW50aWxlLCBtYWluID0gIlVCTyBRdWFudGlsZSBGb3JlY2FzdCIpICsgYXV0b2xheWVyKGFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3QpICsgYXV0b2xheWVyKGFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QpICsgYXV0b2xheWVyKGZpbmFsLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwuaGlnaGVzdC5mb3JlY2FzdCkNCmBgYA0KDQpTdW1tYXJ5IG9mIFVCTyBNb2RlbHMNCmBgYHtyfQ0Kc3VtbWFyeShhcmltYS51Ym8ubG93ZXN0KQ0Kc3VtbWFyeShhcmltYS51Ym8uc2Vjb25kKQ0Kc3VtbWFyeShhcmltYS51Ym8ubWlkZGxlKQ0KYGBgDQoNCldoYXQgd2UgY2FuIHVuZm9ydHVuYXRlbHkgc2VlIGZyb20gdGhlIG1vZGVscywgd2hpY2ggaGFzIHBvc2l0aXZlcyBhbmQgbmVnYXRpdmVzLCBpcyB0aGF0IHRoZSBiZXN0IG1vZGVsIHRvIGNhcHR1cmUgdGhlIGRpc3RyaWJ1dGlvbnMgZXhwb3NlZCB0byB0aGUgcHJvcG9zZWQgVUJPIGlzIGFuIEFSSU1BKDAsIDAsIDApLCBhIHdoaXRlIG5vaXNlIG1vZGVsIHdpdGggdGhlIG9ubHkgbWVhbmluZ2Z1bCB2YXJpYWJsZSBiZWluZyB0aGUgc3RvY2sgbWFya2V0IGRhdGEuIFRoZSBvYnZpb3VzIG5lZ2F0aXZlIGlzIHRoYXQgYW55IGluZGl2aWR1YWwncyBpbmNvbWUgaXMgbW9yZSBjbG9zZWx5IHRpZWQgdG8gdGhlIHN0b2NrIG1hcmtldChTJlAgNTAwLCBmb3Igb3VyIHB1cnBvc2VzKSB0aGFuIHRoZWlyIG93biBlYXJuZWQgaW5jb21lLiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhpcyB3YXMgYWx3YXlzIHRydWUgZm9yIHRoZSBoaWdoZXItaW5jb21lIHF1aW50aWxlcywgYXMgd2Ugc2VlIHRoYXQgdGhlIHN0YW5kYXJkIEFSSU1BIG1vZGVsIGluY3JlYXNlcyBhY2N1cmFjeSB3aGVuIFMmUCA1MDAgZGF0YSBpcyBpbmNsdWRlZCBhcyBhIGluZGVwZW5kZW50IHZhcmlhYmxlIGZvciB0aGUgZm91cnRoIGluY29tZSBkaXN0cmlidXRpb24gYW5kIGhpZ2hlci4gV2hpbGUgdGhlIG1lYW5zIGJ5IHdoaWNoIHRoZSBoaWdoZXIgaW5jb21lIGRpc3RyaWJ1dGlvbnMgdXRpbGl6ZSB0aGUgc3RvY2sgbWFya2V0IHRvIGluY3JlYXNlIHdlYWx0aCBpcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMgcGFwZXIsIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIG1hcmtldCBnYWlucyBhbmQgdGhlIGhpZ2hlc3QgaW5jb21lIGRpc3RyaWJ1dGlvbnMgaXMgbm90aWNlZC4NCg0KDQpVQk8gU2hhcmUgRm9yZWNhc3QNCmBgYHtyfQ0KdG90YWwuZm9yZWNhc3QudWJvIDwtIGFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3QkbWVhbiArIGFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3QkbWVhbiArIGFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QkbWVhbiArIGZpbmFsLmZvdXJ0aC5mb3JlY2FzdCRtZWFuICsgZmluYWwuaGlnaGVzdC5mb3JlY2FzdCRtZWFuDQoNCmFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3Qud2FsbC5zaGFyZSA8LSBhcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJvDQphcmltYS51Ym8uc2Vjb25kLmZvcmVjYXN0LndhbGwuc2hhcmUgPC0gYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnVibw0KYXJpbWEudWJvLm1pZGRsZS5zaGFyZSA8LSBhcmltYS51Ym8ubWlkZGxlLmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJvDQpmaW5hbC51Ym8uZm91cnRoLnNoYXJlIDwtIGZpbmFsLmZvdXJ0aC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnVibw0KZmluYWwudWJvLmhpZ2hlc3Quc2hhcmUgPC0gZmluYWwuaGlnaGVzdC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnVibw0KDQphdXRvcGxvdChhcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0LndhbGwuc2hhcmUpICsgYXV0b2xheWVyKGFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3Qud2FsbC5zaGFyZSkgKyBhdXRvbGF5ZXIoYXJpbWEudWJvLm1pZGRsZS5zaGFyZSkgKyBhdXRvbGF5ZXIoZmluYWwudWJvLmZvdXJ0aC5zaGFyZSkgKyBhdXRvbGF5ZXIoZmluYWwudWJvLmhpZ2hlc3Quc2hhcmUpDQpgYGANCg0KVGhpcyBtYXkgaW5kaWNhdGUgdGhhdCB0aGUgZ2FpbnMgbWFkZSBieSB0aGUgaGlnaGVzdCBxdWludGlsZSBzdGlsbCBvdXRwZXJmb3JtIHRoZSBsb3dlciBxdWludGlsZSdzIGV4cG9zdXJlIHRvIHRoZSBtYXJrZXQuIFRoYXQgc2FpZCwgdGhlIGFzc3VtcHRpb24gaXMgcHVyZWx5IGJhc2VkIG9uIHRoZSByZXR1cm4gb2YgdGhlIFMmUCwgYW5kIHRoZSBtb2RlbCBtYXkgY2hhbmdlIGFmdGVyIHRha2luZyBpbnRvIGFjY291bnQgdGhlIGluY3JlYXNlZCB0YXhlcyBwcm9wb3NlZCBieSBwcm9ncmVzc2l2ZSBhaW1lZCBhdCB0aGUgaGlnaGVzdCBpbmNvbWUgZGlzdHJpYnV0aW9ucy4NCg0KYGBge3J9DQp0b3RhbC5mb3JlY2FzdC51Ym8gPC0gYXJpbWEudWJvLmxvd2VzdC5mb3JlY2FzdCRtZWFuICsgYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdCRtZWFuICsgYXJpbWEudWJvLm1pZGRsZS5mb3JlY2FzdCRtZWFuICsgaG9sdC5mb3VydGgkbWVhbiArIGhvbHQuaGlnaGVzdCRtZWFuDQoNCmxvd2VzdC51Ym8uc2hhcmUgPC0gYXJpbWEudWJvLmxvd2VzdC5mb3JlY2FzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnVibw0Kc2Vjb25kLnViby5zaGFyZSA8LSBhcmltYS51Ym8uc2Vjb25kLmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJvDQptaWRkbGUudWJvLnNoYXJlIDwtIGFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51Ym8NCmZvdXJ0aC51Ym8uc2hhcmUgPC0gaG9sdC5mb3VydGgkbWVhbi90b3RhbC5mb3JlY2FzdC51Ym8NCmhpZ2hlc3QudWJvLnNoYXJlIDwtIGhvbHQuaGlnaGVzdCRtZWFuL3RvdGFsLmZvcmVjYXN0LnVibw0KDQphdXRvcGxvdChsb3dlc3QudWJvLnNoYXJlLCBtYWluID0gIlVCTyBTaGFyZSBGb3JlY2FzdCIpICsgYXV0b2xheWVyKHNlY29uZC51Ym8uc2hhcmUpICsgYXV0b2xheWVyKG1pZGRsZS51Ym8uc2hhcmUpICsgYXV0b2xheWVyKGZvdXJ0aC51Ym8uc2hhcmUpICsgYXV0b2xheWVyKGhpZ2hlc3QudWJvLnNoYXJlKQ0KYGBgDQoNCkl0IHNob3VsZCBiZSBub3RlZCB0aGF0IGRlcGVuZGluZyBvbiB0aGUgbW9kZWwgdXNlZCBmb3IgdGhlIGhpZ2hlc3QgcXVpbnRpbGUsIHRoZSBlZmZlY3Qgb2YgdGhlIFVCTyBvbiBpbmNvbWUgbW9iaWxpdHkgY2hhbmdlcy4gRnVydGhlciwgcmVhdGluZyB0aGUgdG9wIDElIGFzIGl0cyBvd24gcXVhbnRpbGUgc2VwYXJhdGUgZnJvbSB0aGUgb3RoZXJzIGluY2x1ZGluZyB0aGUgaGlnaGVzdCBxdWludGlsZSBzaG93cyB0aGF0IGV2ZXJ5IHF1YW50aWxlIHdvdWxkIHN0ZWFkaWx5IG1vdmUgdG93YXJkcyBoaXJlIHNoYXJlcyBvZiB0b3RhbCBpbmNvbWUgb3ZlciB0aW1lIGRlc3BpdGUgdGhlIGxhcmdlIGdhaW5zIG1hZGUgYnkgdGhlIHRvcCAxJSwgdGhvdWdoIHRoZSBjaGFuZ2UgaXMgbWluaW1hbC4gQW5kIGFnYWluLCB0aGUgVUJPIG1vZGVsIHVuZGVyIGNvbnNpZGVyYXRpb24gY2FuIGJlIGNvbnNpZGVyZWQgYSBtaW5pbXVtIHZhbHVlLCBhcyB0aGlzIGlzIHRoZSB2YWx1ZSB1c2VkIGZvciBpbW1lZGlhdGUgaW5jb21lIHN1YnN0aXR1dGlvbiBhbmQgaXMgZmFyIGNoZWFwZXIgdGhhbiBBbmRyZXcgWWFuZydzIHByb3Bvc2VkIFVCSS4NCg0KYGBge3J9DQpsb3dlc3QudWJvLnNoYXJlDQpzZWNvbmQudWJvLnNoYXJlDQptaWRkbGUudWJvLnNoYXJlDQpmb3VydGgudWJvLnNoYXJlDQpoaWdoZXN0LnViby5zaGFyZQ0KYGBgDQoNClRoZSB0YXJnZXRlZCBVQk8gZG9lcyBhIGNvbXBhcmFibGUgam9iIG9mIHNoaWZ0aW5nIGluY29tZSBpbmVxdWFsaXR5IGFzIHRoZSB0YXJnZXRlZCBVQk8gZG9lcywgYnV0IEkgc2hvdyB0aGF0IGl0IGNvc3RzIGEgZnJhY3Rpb24gb2YgdGhlIHByaWNlIG9mIHRoZSBVQkkuDQoNCg0KV2UgY2FuIGFsc28gdmlldyB0aGUgY2hhbmdlIGluIHRvdGFsIHNoYXJlIG92ZXIgdGhlIHRpbWUgcGVyaW9kIG9mIDE5NzktMjAxNy4NCmBgYHtyfQ0KdWJvLnRpbWUudG90YWwgPC0gbG93ZXN0LnRzLnVibyArIHNlY29uZC50cy51Ym8gKyBtaWRkbGUudHMudWJvICsgZm91cnRoLmluY29tZS50cyArIGhpZ2hlc3QuaW5jb21lLnRzDQoNCmxvd2VzdC51Ym8udGltZS5zaGFyZSA8LSBsb3dlc3QudHMudWJvL3Viby50aW1lLnRvdGFsDQpzZWNvbmQudWJvLnRpbWUuc2hhcmUgPC0gc2Vjb25kLnRzLnViby91Ym8udGltZS50b3RhbA0KbWlkZGxlLnViby50aW1lLnNoYXJlIDwtIG1pZGRsZS50cy51Ym8vdWJvLnRpbWUudG90YWwNCmZvdXJ0aC51Ym8udGltZS5zaGFyZSA8LSBmb3VydGguaW5jb21lLnRzL3Viby50aW1lLnRvdGFsDQpoaWdoZXN0LnViby50aW1lLnNoYXJlIDwtIGhpZ2hlc3QuaW5jb21lLnRzL3Viby50aW1lLnRvdGFsDQoNCmF1dG9wbG90KGxvd2VzdC51Ym8udGltZS5zaGFyZSwgbWFpbiA9ICJVQk8gU2hhcmUgRm9yZWNhc3QgT3ZlciAxOTc5LTIwMTciKSArIGF1dG9sYXllcihzZWNvbmQudWJvLnRpbWUuc2hhcmUpICsgYXV0b2xheWVyKG1pZGRsZS51Ym8udGltZS5zaGFyZSkgKyAgYXV0b2xheWVyKGZvdXJ0aC51Ym8udGltZS5zaGFyZSkgKyBhdXRvbGF5ZXIoZm91cnRoLnViby50aW1lLnNoYXJlKSArIGF1dG9sYXllcihoaWdoZXN0LnViby50aW1lLnNoYXJlKQ0KYGBgDQoNCg0KDQpJbmRpdmlkdWFsIFVCTyBQcm9wb3NhbA0KYGBge3J9DQp1Ym8udHMuMiA8LSBlYXJuaW5ncyozMi45MjczNyoxLjkNCnNucC5kaWZmZXJlbmNlLjIgPC0gdGFpbCh1Ym8udHMuMiwgbj0zOEwpDQp1Ym8uMiA8LSBjKDI5NjEuODEsIHNucC5kaWZmZXJlbmNlLjIpDQpgYGANCg0KQmFzZWQgb2ZmIHRoZSBhdmVyYWdlIG51bWJlciBvZiBjaGlsZHJlbiBwZXIgaG91c2Vob2xkIGluIHRoZSBVUy4gVGhlIHByZXZpb3VzIGV4YW1wbGUgd2FzIHRoYXQgb2YgYSBzaW5nbGUgY2hpbGQgYm9ybiB0byBjZXJ0YWluIGluY29tZSBxdWFudGlsZXMtLXRoZSBhc3N1bXB0aW9uIGJlaW5nIHRoYXQgZXZlcnkgaG91c2Vob2xkIGhhcyBhIHNpbmdsZSBjaGlsZC4gVGhpcyBwcm9wb3NhbCB3aWxsIGJlIGJhc2VkIG9mZiBvZiB0aGUgYXZlcmFnZSBudW1iZXIgb2YgY2hpbGRyZW4gYm9ybiBwZXIgaG91c2Vob2xkICgxLjkpIGluIDE5NzkuIFRodXMsIHdlIHdpbGwgYmUgY2FsY3VsYXRpbmcgdGhhdCBlYWNoIGJlbmVmaXR0aW5nIGhvdXNlaG9sZCB3aWxsIHJlY2VpdmUgMS45IHRpbWVzIHRoZSBiZW5lZml0cyBvZiBhIFVCTy4NCg0KDQpgYGB7cn0NCmxvd2VzdC50cy51Ym8uMiA8LSBsb3dlc3QuaW5jb21lLnRzICsgdWJvLjINCnNlY29uZC50cy51Ym8uMiA8LSBzZWNvbmQuaW5jb21lLnRzICsgdWJvLjINCm1pZGRsZS50cy51Ym8uMiA8LSBtaWRkbGUuaW5jb21lLnRzICsgdWJvLjINCg0KdWJvLmluY29tZS5xdWludGlsZS4yIDwtIGNiaW5kKGxvd2VzdC50cy51Ym8uMiwgc2Vjb25kLnRzLnViby4yLCBtaWRkbGUudHMudWJvLjIsIGZvdXJ0aC5pbmNvbWUudHMsIGhpZ2hlc3QuaW5jb21lLnRzKQ0KDQphcmltYS51Ym8ubG93ZXN0LjIgPC0gYXV0by5hcmltYShsb3dlc3QudHMudWJvLjIsIHhyZWcgPSB3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS51Ym8uc2Vjb25kLjIgPC0gYXV0by5hcmltYShzZWNvbmQudHMudWJvLjIsIHhyZWcgPSB3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS51Ym8ubWlkZGxlLjIgPC0gYXV0by5hcmltYShtaWRkbGUudHMudWJvLjIsIHhyZWcgPSB3YWxsLmRhdGEsIHNlYXNvbmFsID0gRkFMU0UpDQphcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0LjIgPC0gZm9yZWNhc3QoYXJpbWEudWJvLmxvd2VzdC4yLCB4cmVnID0gd2FsbC5kYXRhLnByZWQsIGg9NikNCmFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3QuMiA8LSBmb3JlY2FzdChhcmltYS51Ym8uc2Vjb25kLjIsIHhyZWcgPSB3YWxsLmRhdGEucHJlZCwgaD02KQ0KYXJpbWEudWJvLm1pZGRsZS5mb3JlY2FzdC4yIDwtIGZvcmVjYXN0KGFyaW1hLnViby5taWRkbGUuMiwgeHJlZyA9IHdhbGwuZGF0YS5wcmVkLCBoPTYpDQoNCmF1dG9wbG90KHViby5pbmNvbWUucXVpbnRpbGUuMiwgbWFpbiA9ICJVQk8gUXVhbnRpbGUgRm9yZWNhc3QgVGltZXMgMiIpICsgYXV0b2xheWVyKGFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3QuMikgKyBhdXRvbGF5ZXIoYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdC4yKSArIGF1dG9sYXllcihhcmltYS51Ym8ubWlkZGxlLmZvcmVjYXN0LjIpICsgYXV0b2xheWVyKGZpbmFsLmZvdXJ0aC5mb3JlY2FzdCkgKyBhdXRvbGF5ZXIoZmluYWwuaGlnaGVzdC5mb3JlY2FzdCkNCmBgYA0KDQpJbmRpdmlkdWFsIFVCTyBQcm9wb3NhbCBTaGFyZSBQcm9qZWN0aW9uDQpgYGB7cn0NCnRvdGFsLmZvcmVjYXN0LnViby4yIDwtIGFyaW1hLnViby5sb3dlc3QuZm9yZWNhc3QuMiRtZWFuICsgYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdC4yJG1lYW4gKyBhcmltYS51Ym8ubWlkZGxlLmZvcmVjYXN0LjIkbWVhbiArIGhvbHQuZm91cnRoJG1lYW4gKyBob2x0LmhpZ2hlc3QkbWVhbg0KDQphcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0LndhbGwuc2hhcmUuMiA8LSBhcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0JG1lYW4vdG90YWwuZm9yZWNhc3QudWJvLjINCmFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3Qud2FsbC5zaGFyZS4yIDwtIGFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51Ym8uMg0KYXJpbWEudWJvLm1pZGRsZS5zaGFyZS4yIDwtIGFyaW1hLnViby5taWRkbGUuZm9yZWNhc3QuMiRtZWFuL3RvdGFsLmZvcmVjYXN0LnViby4yDQpmaW5hbC51Ym8uZm91cnRoLnNoYXJlLjIgPC0gaG9sdC5mb3VydGgkbWVhbi90b3RhbC5mb3JlY2FzdC51Ym8uMg0KZmluYWwudWJvLmhpZ2hlc3Quc2hhcmUuMiA8LSBob2x0LmhpZ2hlc3QkbWVhbi90b3RhbC5mb3JlY2FzdC51Ym8uMg0KDQphdXRvcGxvdChhcmltYS51Ym8ubG93ZXN0LmZvcmVjYXN0LndhbGwuc2hhcmUuMikgKyBhdXRvbGF5ZXIoYXJpbWEudWJvLnNlY29uZC5mb3JlY2FzdC53YWxsLnNoYXJlLjIpICsgYXV0b2xheWVyKGFyaW1hLnViby5taWRkbGUuc2hhcmUuMikgKyBhdXRvbGF5ZXIoZmluYWwudWJvLmZvdXJ0aC5zaGFyZS4yKSArIGF1dG9sYXllcihmaW5hbC51Ym8uaGlnaGVzdC5zaGFyZS4yKQ0KYGBgDQoNCmBgYHtyfQ0KYXJpbWEudWJvLmxvd2VzdC5mb3JlY2FzdC53YWxsLnNoYXJlLjINCmFyaW1hLnViby5zZWNvbmQuZm9yZWNhc3Qud2FsbC5zaGFyZS4yDQphcmltYS51Ym8ubWlkZGxlLnNoYXJlLjINCmZpbmFsLnViby5mb3VydGguc2hhcmUuMg0KZmluYWwudWJvLmhpZ2hlc3Quc2hhcmUuMg0KYGBgDQoNCg0KDQoNCkhvdyB0byBwYXkgZm9yIGl0DQpgYGB7cn0NCkRpc3RyaWJ1dGlvbl9wb3B1bGF0aW9uIDwtIHJlYWRfZXhjZWwoIkRpc3RyaWJ1dGlvbiBwb3B1bGF0aW9uLnhsc3giKQ0KYGBgDQoNCg0KYGBge3J9DQpkaXN0LnBvcC50cyA8LSB0cyhEaXN0cmlidXRpb25fcG9wdWxhdGlvbiwgc3RhcnQ9MTk3OSwgZW5kPTIwMTcsIGZyZXF1ZW5jeT0xKQ0KDQpsb3dlc3QucG9wIDwtIERpc3RyaWJ1dGlvbl9wb3B1bGF0aW9uJGBMb3dlc3QgUXVhbnRpbGVgDQpzZWNvbmQucG9wIDwtIERpc3RyaWJ1dGlvbl9wb3B1bGF0aW9uJGBTZWNvbmQgUXVhbnRpbGVgDQptaWRkbGUucG9wIDwtIERpc3RyaWJ1dGlvbl9wb3B1bGF0aW9uJGBNaWRkbGUgUXVhbnRpbGVgDQoNCmxvd2VzdC5wb3AudHMgPC0gdHMobG93ZXN0LnBvcCwgc3RhcnQ9MTk3OSwgZW5kPTIwMTcsIGZyZXF1ZW5jeSA9IDEpDQpzZWNvbmQucG9wLnRzIDwtIHRzKHNlY29uZC5wb3AsIHN0YXJ0PTE5NzksIGVuZD0yMDE3LCBmcmVxdWVuY3kgPSAxKQ0KbWlkZGxlLnBvcC50cyA8LSB0cyhtaWRkbGUucG9wLCBzdGFydD0xOTc5LCBlbmQ9MjAxNywgZnJlcXVlbmN5ID0gMSkNCmBgYA0KDQpgYGB7cn0NCmxvd2VzdC5wb3AucHJlZCA8LSByd2YobG93ZXN0LnBvcC50cywgaCA9IDYsIGRyaWZ0PVRSVUUpDQpzZWNvbmQucG9wLnByZWQgPC0gcndmKHNlY29uZC5wb3AudHMsIGggPSA2LCBkcmlmdD1UUlVFKQ0KbWlkZGxlLnBvcC5wcmVkIDwtIHJ3ZihtaWRkbGUucG9wLnRzLCBoID0gNiwgZHJpZnQ9VFJVRSkNCg0KbG93ZXN0LnBvcC5wcmVkJG1vZGVsDQpzZWNvbmQucG9wLnByZWQkbW9kZWwNCm1pZGRsZS5wb3AucHJlZCRtb2RlbA0KDQphdXRvcGxvdChkaXN0LnBvcC50cykgKyBhdXRvbGF5ZXIobG93ZXN0LnBvcC5wcmVkKSArIGF1dG9sYXllcihzZWNvbmQucG9wLnByZWQpICsgYXV0b2xheWVyKG1pZGRsZS5wb3AucHJlZCkNCmBgYA0KYGBge3J9DQp1Ym8uY29zdCA8LSBjKDEyMDAwLCAxMjAwMCwgMTIwMDAsIDEyMDAwLCAxMjAwMCwgMTIwMDApDQppbmZsYXRpb24gPC0gYygxLjAwLCAxLjAxNCwgMS4wMjgsIDEuMDQyLCAxLjA1NiwgMS4wNzApDQoNCnViby5pbmYuY29zdCA8LSB1Ym8uY29zdCppbmZsYXRpb24NCg0KbG93ZXN0LnBvcC5pbmMgPC0gYygxOTIxMDAsIDE5MjEwMCwgMTkyMTAwLCAxOTIxMDAsIDE5MjEwMCwgMTkyMTAwKQ0Kc2Vjb25kLnBvcC5pbmMgPC0gYygyNDA2MDAsIDI0MDYwMCwgMjQwNjAwLCAyNDA2MDAsIDI0MDYwMCwgMjQwNjAwKQ0KbWlkZGxlLnBvcC5pbmMgPC0gYygyNzExMDAsIDI3MTEwMCwgMjcxMTAwLCAyNzExMDAsIDI3MTEwMCwgMjcxMTAwKQ0KDQpsb3dlc3QuY29zdCA8LSBsb3dlc3QucG9wLmluYyp1Ym8uaW5mLmNvc3QNCnNlY29uZC5jb3N0IDwtIHNlY29uZC5wb3AuaW5jKnViby5pbmYuY29zdA0KbWlkZGxlLmNvc3QgPC0gbWlkZGxlLnBvcC5pbmMqdWJvLmluZi5jb3N0DQoNCmxvd2VzdC5jb3N0IDwtIHRzKGxvd2VzdC5jb3N0LCBzdGFydD0yMDE4LCBlbmQ9MjAyMywgZnJlcXVlbmN5PTEpDQpzZWNvbmQuY29zdCA8LSB0cyhzZWNvbmQuY29zdCwgc3RhcnQ9MjAxOCwgZW5kPTIwMjMsIGZyZXF1ZW5jeT0xKQ0KbWlkZGxlLmNvc3QgPC0gdHMobWlkZGxlLmNvc3QsIHN0YXJ0PTIwMTgsIGVuZD0yMDIzLCBmcmVxdWVuY3k9MSkNCg0KdG90YWwuY29zdCA8LSBsb3dlc3QuY29zdCArIHNlY29uZC5jb3N0ICsgbWlkZGxlLmNvc3QNCg0KYXV0b3Bsb3QodG90YWwuY29zdCkgKyBhdXRvbGF5ZXIobG93ZXN0LmNvc3QpICsgYXV0b2xheWVyKHNlY29uZC5jb3N0KSArIGF1dG9sYXllcihtaWRkbGUuY29zdCkNCg0KdG90YWwuY29zdA0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShmaW5hbC5oaWdoZXN0KQ0KYGBgDQoNClRoaXMgZXN0aW1hdGVzIGEgcm91Z2hseSAkMywxODEsNTc5LDAwMCBjb3N0IGEgeWVhci4gVGhpcyBpcyBubyB0cmlmbGluZyBhbW91bnQsIGJ1dCBpcyBtaW5pbWFsIGNvbXBhcmVkIHRvIHRoZSAkMi44IHRyaWxsaW9uIGEgeWVhciBmb3IgQW5kcmV3IFlhbmcncyBVQkkgcHJvcG9zYWwuIFRoaXMgaXMgbm90IGEgcHJvcG9zYWwgZm9yIGFuIGltbWVkaWF0ZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIG1pbmltdW0gcmVxdWlyZWQgaW5jb21lIGZvciBhbiBpbmRpdmlkdWFsIGxpdmluZyBpbiBBbWVyaWNhLiBCdXQgZm9yIGF0dGVtcHRpbmcgdG8gbW92ZSBhIGZhbWlseSB0b3dhcmQgYSBoaWdoZXIgaW5jb21lIHF1aW50aWxlLCBJIGJlbGlldmUgdGhhdCB0aGUgY29zdCBpcyB3b3J0aCBpdC4NCg0KYGBge3J9DQpob2x0LnRvcCRtb2RlbA0KYGBgDQoNCmBgYHtyfQ0KMzE4MTU3OTAwMC8zOTI3NzE4MDMwMA0KYGBgDQpBcyB3ZSBjYW4gc2VlLCBldmVuIHdpdGggb25seSB0aGUgdG9wIDElIHBheWluZyBmb3IgdGhlIGVudGlyZXR5IG9mIHRoaXMgcHJvZ3JhbSB3aXRob3V0IGFueSBmZWRlcmFsIGFzc2lzdGFuY2UgYW5kIG9ubHkgb3V0IG9mIHRoZWlyIGdhaW5zIHBlciB5ZWFyIGFjY29yZGluZyB0byB0aGUgbW9zdCBhY2N1cmF0ZSBtb2RlbCwgdGhlIGNvc3QgZm9yIHRoZSBVQkkgd291bGQgb25seSBiZSByb3VnaGx5IDguMTAlIG9mIHRoZSBnYWlucyBpbiB0aGUgdG9wIDElIGluIGEgeWVhci4NCg0KDQoNCg0KDQo=