Integrantes del equipo:

  • Regina Enríquez Chapa A01721435

  • Maximiliano Carvajal A01552179

  • Guillermo Cazares Cruz A01283709

Instalar paquetes y llamar librerías

#install.packages("maps")
#install.packages("readr")
#install.packages("forecast")
#install.packages("ggplot2")
#install.packages("dplyr")

library(maps)
library(readr)
library(forecast)
library(ggplot2)
library(dplyr)

Base de datos del censo de población de USA por estado

#Importación de base de datos
green_go <- read_csv("historical_state_population_by_year.csv")
#green_go <- read_csv("D:/8vo semestre/historical_state_population_by_year.csv")
colnames(green_go) <- c("State","Year","Population")
head(green_go)
## # A tibble: 6 × 3
##   State  Year Population
##   <chr> <dbl>      <dbl>
## 1 AK     1951     158000
## 2 AK     1952     189000
## 3 AK     1953     205000
## 4 AK     1954     215000
## 5 AK     1955     222000
## 6 AK     1956     224000

Pronóstico de los estados (Series de tiempo, Modelos Arima, y Pronósticos)

Estados Seleccionados:

Abreviación Estado
PA Pensylvannia
IL Illinois
OH Ohio
NC North Carolina
GA Georgia

Pronóstico Pennsylvania

#Guardar solo los datos de Pennsylvania
PA <- subset(green_go, State == "PA")

Serie de tiempo

#Crear la serie de tiempo, empezando desde 1900 hasta 2019, por año
ts_PA <- ts(data=PA$Population, start = c(1900,1), frequency = 1)
head(ts_PA)
## Time Series:
## Start = 1900 
## End = 1905 
## Frequency = 1 
## [1] 6313000 6439000 6567000 6699000 6833000 6970000

Modelo ARIMA

#Crear el modelo ARIMA para Pennsylvania
arima_PA <- auto.arima(ts_PA)
summary(arima_PA)
## Series: ts_PA 
## ARIMA(0,2,2) 
## 
## Coefficients:
##           ma1      ma2
##       -0.5098  -0.4160
## s.e.   0.0797   0.0787
## 
## sigma^2 = 8.94e+09:  log likelihood = -1519.25
## AIC=3044.49   AICc=3044.7   BIC=3052.81
## 
## Training set error measures:
##                     ME     RMSE      MAE        MPE      MAPE      MASE
## Training set -11297.47 92964.68 48959.44 -0.1096944 0.4757895 0.6274881
##                     ACF1
## Training set 0.007469667

Pronósticos

#Pronosticar la población durante las siguientes décadas, hasta 2070
pronostico_PA <- forecast(arima_PA, level=c(95), h=51)
plot(pronostico_PA)

Se pronostica que la población incrementará conforme pasan los años y décadas, también se puede apreciar que el pronóstico se vuelve más impreciso conforme se estiman más años.

#Guardar la población de 2030, 2040, 2050, 2060, 2070
PopPA <- pronostico_PA$mean[c(11,21,31,41,51)]

Pronóstico Illinois

#Guardar solo los datos de Illinois
IL <- subset(green_go, State == "IL")

Serie de tiempo

#Crear la serie de tiempo, empezando desde 1900 hasta 2019, por año
ts_IL <- ts(data=IL$Population, start = c(1900,1), frequency = 1)
head(ts_IL)
## Time Series:
## Start = 1900 
## End = 1905 
## Frequency = 1 
## [1] 4828000 4914000 4992000 5071000 5161000 5241000

Modelo Arima

#Crear el modelo ARIMA para Illinois
arima_IL <- auto.arima(ts_IL)
summary(arima_IL)
## Series: ts_IL 
## ARIMA(3,2,1) 
## 
## Coefficients:
##          ar1     ar2      ar3      ma1
##       0.0790  0.0424  -0.3400  -0.7050
## s.e.  0.1186  0.1000   0.0925   0.1044
## 
## sigma^2 = 6.155e+09:  log likelihood = -1495.86
## AIC=3001.72   AICc=3002.26   BIC=3015.58
## 
## Training set error measures:
##                     ME     RMSE      MAE         MPE      MAPE      MASE
## Training set -3927.761 76468.62 43652.01 -0.02872944 0.4920267 0.5507371
##                    ACF1
## Training set -0.0177474

Pronósticos

#Pronosticar la población durante las siguientes décadas, hasta 2070
pronostico_IL <- forecast(arima_IL, level=c(95), h=51)
plot(pronostico_IL)

Se pronostica que la población disminuirá conforme pasan los años y décadas, y nuevamente se aprecia que el pronóstico se vuelve más impreciso conforme se estiman más años.

#Guardar la población de 2030, 2040, 2050, 2060, 2070
PopIL <- pronostico_IL$mean[c(11,21,31,41,51)]

Pronóstico Ohio

#Guardar solo los datos de Ohio
OH <- subset(green_go, State == "OH")

Serie de tiempo

#Crear la serie de tiempo, empezando desde 1900 hasta 2019, por año
ts_OH <- ts(data=OH$Population, start = c(1900,1), frequency = 1)
head(ts_OH)
## Time Series:
## Start = 1900 
## End = 1905 
## Frequency = 1 
## [1] 4161000 4216000 4322000 4386000 4458000 4530000

Modelo Arima

#Crear el modelo ARIMA para Ohio
arima_OH <- auto.arima(ts_OH)
summary(arima_OH)
## Series: ts_OH 
## ARIMA(3,2,2) 
## 
## Coefficients:
##          ar1      ar2      ar3      ma1     ma2
##       0.6508  -0.0937  -0.3696  -1.2446  0.5125
## s.e.  0.3045   0.1325   0.0988   0.3349  0.2599
## 
## sigma^2 = 4.363e+09:  log likelihood = -1474.97
## AIC=2961.94   AICc=2962.7   BIC=2978.56
## 
## Training set error measures:
##                     ME     RMSE      MAE          MPE      MAPE      MASE
## Training set -1236.664 64095.18 33364.11 0.0004268429 0.4295383 0.5017015
##                      ACF1
## Training set -0.002722796

Pronósticos

#Pronosticar la población durante las siguientes décadas, hasta 2070
pronostico_OH <- forecast(arima_OH, level=c(95), h=51)
plot(pronostico_OH)

Se pronostica que la población incrementará poco conforme pasan los años y décadas, también se puede apreciar que el pronóstico se vuelve más impreciso conforme se estiman más años.

#Guardar la población de 2030, 2040, 2050, 2060, 2070
PopOH <- pronostico_OH$mean[c(11,21,31,41,51)]

Pronóstico North Carolina

#Guardar solo los datos de North Carolina
NC <- subset(green_go, State == "NC")

Serie de tiempo

#Crear la serie de tiempo, empezando desde 1900 hasta 2019, por año
ts_NC <- ts(data=NC$Population, start = c(1900,1), frequency = 1)
head(ts_NC)
## Time Series:
## Start = 1900 
## End = 1905 
## Frequency = 1 
## [1] 1897000 1926000 1956000 1986000 2017000 2051000

Modelo Arima

#Crear el modelo ARIMA para North Carolina
arima_NC <- auto.arima(ts_NC)
summary(arima_NC)
## Series: ts_NC 
## ARIMA(0,2,2) 
## 
## Coefficients:
##           ma1      ma2
##       -0.7066  -0.1454
## s.e.   0.0928   0.0920
## 
## sigma^2 = 2.134e+09:  log likelihood = -1434.41
## AIC=2874.83   AICc=2875.04   BIC=2883.14
## 
## Training set error measures:
##                    ME     RMSE      MAE        MPE      MAPE      MASE
## Training set 4905.901 45417.83 25061.71 0.09923176 0.5388346 0.3334805
##                    ACF1
## Training set -0.0222108

Pronósticos

#Pronosticar la población durante las siguientes décadas, hasta 2070
pronostico_NC <- forecast(arima_NC, level=c(95), h=51)
plot(pronostico_NC)

Se pronostica que la población incrementará de gran manera conforme pasan los años y décadas, también se puede apreciar que el pronóstico se vuelve más impreciso conforme se estiman más años.

#Guardar la población de 2030, 2040, 2050, 2060, 2070
PopNC <- pronostico_NC$mean[c(11,21,31,41,51)]

Pronóstico Georgia

#Guardar solo los datos de Georgia
GA <- subset(green_go, State == "GA")

Serie de tiempo

#Crear la serie de tiempo, empezando desde 1900 hasta 2019, por año
ts_GA <- ts(data=GA$Population, start = c(1900,1), frequency = 1)
head(ts_GA)
## Time Series:
## Start = 1900 
## End = 1905 
## Frequency = 1 
## [1] 2220000 2263000 2305000 2346000 2387000 2427000

Modelo Arima

#Crear el modelo ARIMA para Georgia
arima_GA <- auto.arima(ts_GA)
summary(arima_GA)
## Series: ts_GA 
## ARIMA(0,2,1) 
## 
## Coefficients:
##           ma1
##       -0.7683
## s.e.   0.0599
## 
## sigma^2 = 1.943e+09:  log likelihood = -1429.24
## AIC=2862.48   AICc=2862.58   BIC=2868.02
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE      MAPE      MASE
## Training set 2364.619 43524.82 25511.15 0.0491154 0.5731293 0.3342898
##                    ACF1
## Training set 0.08456536

Pronósticos

#Pronosticar la población durante las siguientes décadas, hasta 2070
pronostico_GA <- forecast(arima_GA, level=c(95), h=51)
plot(pronostico_GA)

Se pronostica que la población incrementará conforme pasan los años y décadas, también se puede apreciar que el pronóstico se vuelve más impreciso conforme se estiman más años.

#Guardar la población de 2030, 2040, 2050, 2060, 2070
PopGA <- pronostico_GA$mean[c(11,21,31,41,51)]

Mapeo de poblaciones por décadas (2030, 2040, 2050, 2060, 2070)

#Pronóstico de población para las siguientes 5 décadas en una base datos
Population_forecast <- data.frame(region = c("pennsylvania","illinois","ohio","north carolina","georgia"),
D2030 = c(PopPA[1], PopIL[1], PopOH[1], PopNC[1], PopGA[1]),
D2040 = c(PopPA[2], PopIL[2], PopOH[2], PopNC[2], PopGA[2]),
D2050 = c(PopPA[3], PopIL[3], PopOH[3], PopNC[3], PopGA[3]),
D2060 = c(PopPA[4], PopIL[4], PopOH[4], PopNC[4], PopGA[4]),
D2070 = c(PopPA[5], PopIL[5], PopOH[5], PopNC[5], PopGA[5]))
Population_forecast
##           region    D2030    D2040    D2050    D2060    D2070
## 1   pennsylvania 13080754 13342960 13605167 13867373 14129580
## 2       illinois 12363832 12070605 11777717 11484824 11191931
## 3           ohio 11883678 12061059 12237827 12414684 12591557
## 4 north carolina 11785748 12967114 14148480 15329845 16511211
## 5        georgia 11808766 12891805 13974843 15057882 16140921
#Juntar la base del mapa con la de los pronósticos de la población
usa <- map_data("state")
mapas <- left_join(usa, Population_forecast, by = "region")
#Décadas 2030, 2040, 2050, 2060, 2070
ggplot(data = mapas) + 
  geom_polygon(aes(x = long, y = lat, fill = D2030, group = group), color = "white") + 
  coord_fixed(1.3) +
  scale_fill_gradient(low = "red", high = "green") +
  ggtitle("Población 2030")

ggplot(data = mapas) + 
  geom_polygon(aes(x = long, y = lat, fill = D2040, group = group), color = "white") + 
  coord_fixed(1.3) +
  scale_fill_gradient(low = "red", high = "green") +
  ggtitle("Población 2040")

ggplot(data = mapas) + 
  geom_polygon(aes(x = long, y = lat, fill = D2050, group = group), color = "white") + 
  coord_fixed(1.3) +
  scale_fill_gradient(low = "red", high = "green") +
  ggtitle("Población 2050")

ggplot(data = mapas) + 
  geom_polygon(aes(x = long, y = lat, fill = D2060, group = group), color = "white") + 
  coord_fixed(1.3) +
  scale_fill_gradient(low = "red", high = "green") +
  ggtitle("Población 2060")

ggplot(data = mapas) + 
  geom_polygon(aes(x = long, y = lat, fill = D2070, group = group), color = "white") + 
  coord_fixed(1.3) +
  scale_fill_gradient(low = "red", high = "green") +
  ggtitle("Población 2070")

Conclusión

Se puede observar cómo dentro de la primera década Pennsylvania lidera entre los 5 estados. Sin embargo, conforme pasan los años los estados de North Carolina y Georgia lo sobrepasan, volviéndose éstos los más poblados. Por otro lado, el estado de Illinois comienza siendo el segundo estado con mayor población, pero va decrementando hasta convertirse en el estado con menos población. Por último, el estado de Ohio mantiene su posición como uno de los estados con menor población durante los años.

LS0tDQp0aXRsZTogIkFjdGl2aWRhZCBJbnRlZ3JhZG9yYTogRGVtb2dyYWbDrWEgVVNBIg0KYXV0aG9yOiAiUmVnaW5hIEVucsOtcXVleiBDaGFwYSINCmRhdGU6ICIyMDI0LTAyLTIxIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IHVuaXRlZA0KLS0tDQoNCiFbXShpbWFnZXMvbWFwYXMuZ2lmKQ0KDQpgYGB7PWh0bWx9DQo8c3R5bGU+DQpib2R5IHsNCnRleHQtYWxpZ246IGp1c3RpZnl9DQo8L3N0eWxlPg0KYGBgDQpJbnRlZ3JhbnRlcyBkZWwgZXF1aXBvOg0KDQotICAgUmVnaW5hIEVucsOtcXVleiBDaGFwYSBBMDE3MjE0MzUNCg0KLSAgIE1heGltaWxpYW5vIENhcnZhamFsIEEwMTU1MjE3OQ0KDQotICAgR3VpbGxlcm1vIENhemFyZXMgQ3J1eiBBMDEyODM3MDkNCg0KDQojIEluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcsOtYXMNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNpbnN0YWxsLnBhY2thZ2VzKCJtYXBzIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJyZWFkciIpDQojaW5zdGFsbC5wYWNrYWdlcygiZm9yZWNhc3QiKQ0KI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KI2luc3RhbGwucGFja2FnZXMoImRwbHlyIikNCg0KbGlicmFyeShtYXBzKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCiMgQmFzZSBkZSBkYXRvcyBkZWwgY2Vuc28gZGUgcG9ibGFjacOzbiBkZSBVU0EgcG9yIGVzdGFkbw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KI0ltcG9ydGFjacOzbiBkZSBiYXNlIGRlIGRhdG9zDQpncmVlbl9nbyA8LSByZWFkX2NzdigiaGlzdG9yaWNhbF9zdGF0ZV9wb3B1bGF0aW9uX2J5X3llYXIuY3N2IikNCiNncmVlbl9nbyA8LSByZWFkX2NzdigiRDovOHZvIHNlbWVzdHJlL2hpc3RvcmljYWxfc3RhdGVfcG9wdWxhdGlvbl9ieV95ZWFyLmNzdiIpDQpjb2xuYW1lcyhncmVlbl9nbykgPC0gYygiU3RhdGUiLCJZZWFyIiwiUG9wdWxhdGlvbiIpDQpoZWFkKGdyZWVuX2dvKQ0KYGBgDQoNCiMgUHJvbsOzc3RpY28gZGUgbG9zIGVzdGFkb3MgKFNlcmllcyBkZSB0aWVtcG8sIE1vZGVsb3MgQXJpbWEsIHkgUHJvbsOzc3RpY29zKQ0KDQojIyMjIEVzdGFkb3MgU2VsZWNjaW9uYWRvczoNCg0KfCBBYnJldmlhY2nDs24gfCBFc3RhZG8gICAgICAgICB8DQp8LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfA0KfCBQQSAgICAgICAgICB8IFBlbnN5bHZhbm5pYSAgIHwNCnwgSUwgICAgICAgICAgfCBJbGxpbm9pcyAgICAgICB8DQp8IE9IICAgICAgICAgIHwgT2hpbyAgICAgICAgICAgfA0KfCBOQyAgICAgICAgICB8IE5vcnRoIENhcm9saW5hIHwNCnwgR0EgICAgICAgICAgfCBHZW9yZ2lhICAgICAgICB8DQoNCiMjIFByb27Ds3N0aWNvIFBlbm5zeWx2YW5pYQ0KDQpgYGB7cn0NCiNHdWFyZGFyIHNvbG8gbG9zIGRhdG9zIGRlIFBlbm5zeWx2YW5pYQ0KUEEgPC0gc3Vic2V0KGdyZWVuX2dvLCBTdGF0ZSA9PSAiUEEiKQ0KYGBgDQoNCiMjIyBTZXJpZSBkZSB0aWVtcG8NCg0KYGBge3J9DQojQ3JlYXIgbGEgc2VyaWUgZGUgdGllbXBvLCBlbXBlemFuZG8gZGVzZGUgMTkwMCBoYXN0YSAyMDE5LCBwb3IgYcOxbw0KdHNfUEEgPC0gdHMoZGF0YT1QQSRQb3B1bGF0aW9uLCBzdGFydCA9IGMoMTkwMCwxKSwgZnJlcXVlbmN5ID0gMSkNCmhlYWQodHNfUEEpDQpgYGANCg0KIyMjIE1vZGVsbyBBUklNQQ0KDQpgYGB7cn0NCiNDcmVhciBlbCBtb2RlbG8gQVJJTUEgcGFyYSBQZW5uc3lsdmFuaWENCmFyaW1hX1BBIDwtIGF1dG8uYXJpbWEodHNfUEEpDQpzdW1tYXJ5KGFyaW1hX1BBKQ0KYGBgDQoNCiMjIyBQcm9uw7NzdGljb3MNCg0KYGBge3J9DQojUHJvbm9zdGljYXIgbGEgcG9ibGFjacOzbiBkdXJhbnRlIGxhcyBzaWd1aWVudGVzIGTDqWNhZGFzLCBoYXN0YSAyMDcwDQpwcm9ub3N0aWNvX1BBIDwtIGZvcmVjYXN0KGFyaW1hX1BBLCBsZXZlbD1jKDk1KSwgaD01MSkNCnBsb3QocHJvbm9zdGljb19QQSkNCmBgYA0KDQpTZSBwcm9ub3N0aWNhIHF1ZSBsYSBwb2JsYWNpw7NuIGluY3JlbWVudGFyw6EgY29uZm9ybWUgcGFzYW4gbG9zIGHDsW9zIHkgZMOpY2FkYXMsIHRhbWJpw6luIHNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBlbCBwcm9uw7NzdGljbyBzZSB2dWVsdmUgbcOhcyBpbXByZWNpc28gY29uZm9ybWUgc2UgZXN0aW1hbiBtw6FzIGHDsW9zLg0KDQpgYGB7cn0NCiNHdWFyZGFyIGxhIHBvYmxhY2nDs24gZGUgMjAzMCwgMjA0MCwgMjA1MCwgMjA2MCwgMjA3MA0KUG9wUEEgPC0gcHJvbm9zdGljb19QQSRtZWFuW2MoMTEsMjEsMzEsNDEsNTEpXQ0KYGBgDQoNCiMjIFByb27Ds3N0aWNvIElsbGlub2lzDQoNCmBgYHtyfQ0KI0d1YXJkYXIgc29sbyBsb3MgZGF0b3MgZGUgSWxsaW5vaXMNCklMIDwtIHN1YnNldChncmVlbl9nbywgU3RhdGUgPT0gIklMIikNCmBgYA0KDQojIyMgU2VyaWUgZGUgdGllbXBvDQoNCmBgYHtyfQ0KI0NyZWFyIGxhIHNlcmllIGRlIHRpZW1wbywgZW1wZXphbmRvIGRlc2RlIDE5MDAgaGFzdGEgMjAxOSwgcG9yIGHDsW8NCnRzX0lMIDwtIHRzKGRhdGE9SUwkUG9wdWxhdGlvbiwgc3RhcnQgPSBjKDE5MDAsMSksIGZyZXF1ZW5jeSA9IDEpDQpoZWFkKHRzX0lMKQ0KYGBgDQoNCiMjIyBNb2RlbG8gQXJpbWENCg0KYGBge3J9DQojQ3JlYXIgZWwgbW9kZWxvIEFSSU1BIHBhcmEgSWxsaW5vaXMNCmFyaW1hX0lMIDwtIGF1dG8uYXJpbWEodHNfSUwpDQpzdW1tYXJ5KGFyaW1hX0lMKQ0KYGBgDQoNCiMjIyBQcm9uw7NzdGljb3MNCg0KYGBge3J9DQojUHJvbm9zdGljYXIgbGEgcG9ibGFjacOzbiBkdXJhbnRlIGxhcyBzaWd1aWVudGVzIGTDqWNhZGFzLCBoYXN0YSAyMDcwDQpwcm9ub3N0aWNvX0lMIDwtIGZvcmVjYXN0KGFyaW1hX0lMLCBsZXZlbD1jKDk1KSwgaD01MSkNCnBsb3QocHJvbm9zdGljb19JTCkNCmBgYA0KDQpTZSBwcm9ub3N0aWNhIHF1ZSBsYSBwb2JsYWNpw7NuIGRpc21pbnVpcsOhIGNvbmZvcm1lIHBhc2FuIGxvcyBhw7FvcyB5IGTDqWNhZGFzLCB5IG51ZXZhbWVudGUgc2UgYXByZWNpYSBxdWUgZWwgcHJvbsOzc3RpY28gc2UgdnVlbHZlIG3DoXMgaW1wcmVjaXNvIGNvbmZvcm1lIHNlIGVzdGltYW4gbcOhcyBhw7Fvcy4NCg0KYGBge3J9DQojR3VhcmRhciBsYSBwb2JsYWNpw7NuIGRlIDIwMzAsIDIwNDAsIDIwNTAsIDIwNjAsIDIwNzANClBvcElMIDwtIHByb25vc3RpY29fSUwkbWVhbltjKDExLDIxLDMxLDQxLDUxKV0NCmBgYA0KDQojIyBQcm9uw7NzdGljbyBPaGlvDQoNCmBgYHtyfQ0KI0d1YXJkYXIgc29sbyBsb3MgZGF0b3MgZGUgT2hpbw0KT0ggPC0gc3Vic2V0KGdyZWVuX2dvLCBTdGF0ZSA9PSAiT0giKQ0KYGBgDQoNCiMjIyBTZXJpZSBkZSB0aWVtcG8NCg0KYGBge3J9DQojQ3JlYXIgbGEgc2VyaWUgZGUgdGllbXBvLCBlbXBlemFuZG8gZGVzZGUgMTkwMCBoYXN0YSAyMDE5LCBwb3IgYcOxbw0KdHNfT0ggPC0gdHMoZGF0YT1PSCRQb3B1bGF0aW9uLCBzdGFydCA9IGMoMTkwMCwxKSwgZnJlcXVlbmN5ID0gMSkNCmhlYWQodHNfT0gpDQpgYGANCg0KIyMjIE1vZGVsbyBBcmltYQ0KDQpgYGB7cn0NCiNDcmVhciBlbCBtb2RlbG8gQVJJTUEgcGFyYSBPaGlvDQphcmltYV9PSCA8LSBhdXRvLmFyaW1hKHRzX09IKQ0Kc3VtbWFyeShhcmltYV9PSCkNCmBgYA0KDQojIyMgUHJvbsOzc3RpY29zDQoNCmBgYHtyfQ0KI1Byb25vc3RpY2FyIGxhIHBvYmxhY2nDs24gZHVyYW50ZSBsYXMgc2lndWllbnRlcyBkw6ljYWRhcywgaGFzdGEgMjA3MA0KcHJvbm9zdGljb19PSCA8LSBmb3JlY2FzdChhcmltYV9PSCwgbGV2ZWw9Yyg5NSksIGg9NTEpDQpwbG90KHByb25vc3RpY29fT0gpDQpgYGANCg0KU2UgcHJvbm9zdGljYSBxdWUgbGEgcG9ibGFjacOzbiBpbmNyZW1lbnRhcsOhIHBvY28gY29uZm9ybWUgcGFzYW4gbG9zIGHDsW9zIHkgZMOpY2FkYXMsIHRhbWJpw6luIHNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBlbCBwcm9uw7NzdGljbyBzZSB2dWVsdmUgbcOhcyBpbXByZWNpc28gY29uZm9ybWUgc2UgZXN0aW1hbiBtw6FzIGHDsW9zLg0KDQpgYGB7cn0NCiNHdWFyZGFyIGxhIHBvYmxhY2nDs24gZGUgMjAzMCwgMjA0MCwgMjA1MCwgMjA2MCwgMjA3MA0KUG9wT0ggPC0gcHJvbm9zdGljb19PSCRtZWFuW2MoMTEsMjEsMzEsNDEsNTEpXQ0KYGBgDQoNCiMjIFByb27Ds3N0aWNvIE5vcnRoIENhcm9saW5hDQoNCmBgYHtyfQ0KI0d1YXJkYXIgc29sbyBsb3MgZGF0b3MgZGUgTm9ydGggQ2Fyb2xpbmENCk5DIDwtIHN1YnNldChncmVlbl9nbywgU3RhdGUgPT0gIk5DIikNCmBgYA0KDQojIyMgU2VyaWUgZGUgdGllbXBvDQoNCmBgYHtyfQ0KI0NyZWFyIGxhIHNlcmllIGRlIHRpZW1wbywgZW1wZXphbmRvIGRlc2RlIDE5MDAgaGFzdGEgMjAxOSwgcG9yIGHDsW8NCnRzX05DIDwtIHRzKGRhdGE9TkMkUG9wdWxhdGlvbiwgc3RhcnQgPSBjKDE5MDAsMSksIGZyZXF1ZW5jeSA9IDEpDQpoZWFkKHRzX05DKQ0KYGBgDQoNCiMjIyBNb2RlbG8gQXJpbWENCg0KYGBge3J9DQojQ3JlYXIgZWwgbW9kZWxvIEFSSU1BIHBhcmEgTm9ydGggQ2Fyb2xpbmENCmFyaW1hX05DIDwtIGF1dG8uYXJpbWEodHNfTkMpDQpzdW1tYXJ5KGFyaW1hX05DKQ0KYGBgDQoNCiMjIyBQcm9uw7NzdGljb3MNCg0KYGBge3J9DQojUHJvbm9zdGljYXIgbGEgcG9ibGFjacOzbiBkdXJhbnRlIGxhcyBzaWd1aWVudGVzIGTDqWNhZGFzLCBoYXN0YSAyMDcwDQpwcm9ub3N0aWNvX05DIDwtIGZvcmVjYXN0KGFyaW1hX05DLCBsZXZlbD1jKDk1KSwgaD01MSkNCnBsb3QocHJvbm9zdGljb19OQykNCmBgYA0KDQpTZSBwcm9ub3N0aWNhIHF1ZSBsYSBwb2JsYWNpw7NuIGluY3JlbWVudGFyw6EgZGUgZ3JhbiBtYW5lcmEgY29uZm9ybWUgcGFzYW4gbG9zIGHDsW9zIHkgZMOpY2FkYXMsIHRhbWJpw6luIHNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBlbCBwcm9uw7NzdGljbyBzZSB2dWVsdmUgbcOhcyBpbXByZWNpc28gY29uZm9ybWUgc2UgZXN0aW1hbiBtw6FzIGHDsW9zLg0KDQpgYGB7cn0NCiNHdWFyZGFyIGxhIHBvYmxhY2nDs24gZGUgMjAzMCwgMjA0MCwgMjA1MCwgMjA2MCwgMjA3MA0KUG9wTkMgPC0gcHJvbm9zdGljb19OQyRtZWFuW2MoMTEsMjEsMzEsNDEsNTEpXQ0KYGBgDQoNCiMjIFByb27Ds3N0aWNvIEdlb3JnaWENCg0KYGBge3J9DQojR3VhcmRhciBzb2xvIGxvcyBkYXRvcyBkZSBHZW9yZ2lhDQpHQSA8LSBzdWJzZXQoZ3JlZW5fZ28sIFN0YXRlID09ICJHQSIpDQpgYGANCg0KIyMjIFNlcmllIGRlIHRpZW1wbw0KDQpgYGB7cn0NCiNDcmVhciBsYSBzZXJpZSBkZSB0aWVtcG8sIGVtcGV6YW5kbyBkZXNkZSAxOTAwIGhhc3RhIDIwMTksIHBvciBhw7FvDQp0c19HQSA8LSB0cyhkYXRhPUdBJFBvcHVsYXRpb24sIHN0YXJ0ID0gYygxOTAwLDEpLCBmcmVxdWVuY3kgPSAxKQ0KaGVhZCh0c19HQSkNCmBgYA0KDQojIyMgTW9kZWxvIEFyaW1hDQoNCmBgYHtyfQ0KI0NyZWFyIGVsIG1vZGVsbyBBUklNQSBwYXJhIEdlb3JnaWENCmFyaW1hX0dBIDwtIGF1dG8uYXJpbWEodHNfR0EpDQpzdW1tYXJ5KGFyaW1hX0dBKQ0KYGBgDQoNCiMjIyBQcm9uw7NzdGljb3MNCg0KYGBge3J9DQojUHJvbm9zdGljYXIgbGEgcG9ibGFjacOzbiBkdXJhbnRlIGxhcyBzaWd1aWVudGVzIGTDqWNhZGFzLCBoYXN0YSAyMDcwDQpwcm9ub3N0aWNvX0dBIDwtIGZvcmVjYXN0KGFyaW1hX0dBLCBsZXZlbD1jKDk1KSwgaD01MSkNCnBsb3QocHJvbm9zdGljb19HQSkNCmBgYA0KDQpTZSBwcm9ub3N0aWNhIHF1ZSBsYSBwb2JsYWNpw7NuIGluY3JlbWVudGFyw6EgY29uZm9ybWUgcGFzYW4gbG9zIGHDsW9zIHkgZMOpY2FkYXMsIHRhbWJpw6luIHNlIHB1ZWRlIGFwcmVjaWFyIHF1ZSBlbCBwcm9uw7NzdGljbyBzZSB2dWVsdmUgbcOhcyBpbXByZWNpc28gY29uZm9ybWUgc2UgZXN0aW1hbiBtw6FzIGHDsW9zLg0KDQpgYGB7cn0NCiNHdWFyZGFyIGxhIHBvYmxhY2nDs24gZGUgMjAzMCwgMjA0MCwgMjA1MCwgMjA2MCwgMjA3MA0KUG9wR0EgPC0gcHJvbm9zdGljb19HQSRtZWFuW2MoMTEsMjEsMzEsNDEsNTEpXQ0KYGBgDQoNCiMgTWFwZW8gZGUgcG9ibGFjaW9uZXMgcG9yIGTDqWNhZGFzICgyMDMwLCAyMDQwLCAyMDUwLCAyMDYwLCAyMDcwKQ0KDQpgYGB7cn0NCiNQcm9uw7NzdGljbyBkZSBwb2JsYWNpw7NuIHBhcmEgbGFzIHNpZ3VpZW50ZXMgNSBkw6ljYWRhcyBlbiB1bmEgYmFzZSBkYXRvcw0KUG9wdWxhdGlvbl9mb3JlY2FzdCA8LSBkYXRhLmZyYW1lKHJlZ2lvbiA9IGMoInBlbm5zeWx2YW5pYSIsImlsbGlub2lzIiwib2hpbyIsIm5vcnRoIGNhcm9saW5hIiwiZ2VvcmdpYSIpLA0KRDIwMzAgPSBjKFBvcFBBWzFdLCBQb3BJTFsxXSwgUG9wT0hbMV0sIFBvcE5DWzFdLCBQb3BHQVsxXSksDQpEMjA0MCA9IGMoUG9wUEFbMl0sIFBvcElMWzJdLCBQb3BPSFsyXSwgUG9wTkNbMl0sIFBvcEdBWzJdKSwNCkQyMDUwID0gYyhQb3BQQVszXSwgUG9wSUxbM10sIFBvcE9IWzNdLCBQb3BOQ1szXSwgUG9wR0FbM10pLA0KRDIwNjAgPSBjKFBvcFBBWzRdLCBQb3BJTFs0XSwgUG9wT0hbNF0sIFBvcE5DWzRdLCBQb3BHQVs0XSksDQpEMjA3MCA9IGMoUG9wUEFbNV0sIFBvcElMWzVdLCBQb3BPSFs1XSwgUG9wTkNbNV0sIFBvcEdBWzVdKSkNClBvcHVsYXRpb25fZm9yZWNhc3QNCmBgYA0KDQpgYGB7cn0NCiNKdW50YXIgbGEgYmFzZSBkZWwgbWFwYSBjb24gbGEgZGUgbG9zIHByb27Ds3N0aWNvcyBkZSBsYSBwb2JsYWNpw7NuDQp1c2EgPC0gbWFwX2RhdGEoInN0YXRlIikNCm1hcGFzIDwtIGxlZnRfam9pbih1c2EsIFBvcHVsYXRpb25fZm9yZWNhc3QsIGJ5ID0gInJlZ2lvbiIpDQpgYGANCg0KYGBge3J9DQojRMOpY2FkYXMgMjAzMCwgMjA0MCwgMjA1MCwgMjA2MCwgMjA3MA0KZ2dwbG90KGRhdGEgPSBtYXBhcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZmlsbCA9IEQyMDMwLCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAid2hpdGUiKSArIA0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgaGlnaCA9ICJncmVlbiIpICsNCiAgZ2d0aXRsZSgiUG9ibGFjacOzbiAyMDMwIikNCg0KZ2dwbG90KGRhdGEgPSBtYXBhcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZmlsbCA9IEQyMDQwLCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAid2hpdGUiKSArIA0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgaGlnaCA9ICJncmVlbiIpICsNCiAgZ2d0aXRsZSgiUG9ibGFjacOzbiAyMDQwIikNCg0KZ2dwbG90KGRhdGEgPSBtYXBhcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZmlsbCA9IEQyMDUwLCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAid2hpdGUiKSArIA0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgaGlnaCA9ICJncmVlbiIpICsNCiAgZ2d0aXRsZSgiUG9ibGFjacOzbiAyMDUwIikNCg0KZ2dwbG90KGRhdGEgPSBtYXBhcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZmlsbCA9IEQyMDYwLCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAid2hpdGUiKSArIA0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgaGlnaCA9ICJncmVlbiIpICsNCiAgZ2d0aXRsZSgiUG9ibGFjacOzbiAyMDYwIikNCg0KZ2dwbG90KGRhdGEgPSBtYXBhcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZmlsbCA9IEQyMDcwLCBncm91cCA9IGdyb3VwKSwgY29sb3IgPSAid2hpdGUiKSArIA0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgaGlnaCA9ICJncmVlbiIpICsNCiAgZ2d0aXRsZSgiUG9ibGFjacOzbiAyMDcwIikNCmBgYA0KDQojIENvbmNsdXNpw7NuDQoNClNlIHB1ZWRlIG9ic2VydmFyIGPDs21vIGRlbnRybyBkZSBsYSBwcmltZXJhIGTDqWNhZGEgKlBlbm5zeWx2YW5pYSogbGlkZXJhIGVudHJlIGxvcyA1IGVzdGFkb3MuIFNpbiBlbWJhcmdvLCBjb25mb3JtZSBwYXNhbiBsb3MgYcOxb3MgbG9zIGVzdGFkb3MgZGUgKk5vcnRoIENhcm9saW5hKiB5ICpHZW9yZ2lhKiBsbyBzb2JyZXBhc2FuLCB2b2x2acOpbmRvc2Ugw6lzdG9zIGxvcyBtw6FzIHBvYmxhZG9zLiBQb3Igb3RybyBsYWRvLCBlbCBlc3RhZG8gZGUgKklsbGlub2lzKiBjb21pZW56YSBzaWVuZG8gZWwgc2VndW5kbyBlc3RhZG8gY29uIG1heW9yIHBvYmxhY2nDs24sIHBlcm8gdmEgZGVjcmVtZW50YW5kbyBoYXN0YSBjb252ZXJ0aXJzZSBlbiBlbCBlc3RhZG8gY29uIG1lbm9zIHBvYmxhY2nDs24uIFBvciDDumx0aW1vLCBlbCBlc3RhZG8gZGUgKk9oaW8qIG1hbnRpZW5lIHN1IHBvc2ljacOzbiBjb21vIHVubyBkZSBsb3MgZXN0YWRvcyBjb24gbWVub3IgcG9ibGFjacOzbiBkdXJhbnRlIGxvcyBhw7Fvcy4NCg==