Planeación estratégica basada en analítica prescriptiva

Grupo 503

Profesor Rodolfo Miguel Gameros

Equipo 7:

A00833113 - Avril Lobato

A01771127 - Lesly Darian Romero Vázquez

A00831105 - Jazmín del Carmen Cortez Mendoza

A01284611 - Lisset Hernández

Actividad - Series de Tiempo

Análisis Exploratorio

Carga de base de datos

Aplica la metodología Box-Jenkins a la serie de precios ajustados de la empresa Meta (META) del día 01/Enero/2013 al 31/Marzo/2024; además se convierte a serie de tiempo.

getSymbols("META", src = "yahoo", from = "2013-01-01", to = "2025-02-28")
## [1] "META"
df <- data.frame(Date = index(META), coredata(META))
colnames(df) <- c("Date", "Open", "High", "Low", "Close", "Volume", "Adjusted")

df <- df %>% select(Date, Adjusted)

ts_meta <- ts(df$Adjusted, frequency = 252, start = c(2013, 1))
head(ts_meta)
## Time Series:
## Start = c(2013, 1) 
## End = c(2013, 6) 
## Frequency = 252 
## [1] 27.86865 27.63973 28.62509 29.28200 28.92368 30.44651

Revisión de valores nulos

La base de datos está compuesta por dos variables: Date, que representa la fecha de emisión del precio de la acción, y Adjusted, que corresponde al precio ajustado de la acción, siendo esta última nuestra variable de interés.

Tras la revisión, se confirma que no existen valores nulos en la base de datos.

# Nulos Totales
sum(is.na(df))
## [1] 0
# Nulos por Columna
gg_miss_var(df)

Conversión de tipo de datos

Se realiza conversión de variables a los tipos de datos correspondientes para garantizar un adecuado procesamiento y análisis de los datos:

  • Date se transformó en una variable de tipo fecha (Date), permitiendo su correcta manipulación en análisis temporales.

  • Adjusted se convirtió en una variable de tipo numérico (numeric), asegurando que pueda ser utilizada en cálculos estadísticos y modelos de predicción.

df$Adjusted<-as.numeric(df$Adjusted) 
df$Date<-as.Date(df$Date) 

clases2 <- sapply(df, class)
clases2
##      Date  Adjusted 
##    "Date" "numeric"

Distribución de variable “Adjusted”

La mayoría de los datos se encuentran en un rango aproximado de 100 a 300, concentrándose dentro de la caja del diagrama de caja y bigotes.

El precio ajustado de META ha seguido una clara tendencia alcista, con un incremento significativo en los valores recientes. Lo anterior, se evidencia en la presencia de múltiples outliers por encima del bigote superior, lo que indica que los precios de las acciones han sido significativamente más altos que el resto de la distribución en ciertos periodos. Dicho comportamiento podría estar asociado con factores como inversiones en nuevas tecnologías, cambios estratégicos dentro de la empresa o un auge en el sector tecnológico.

En general, los datos reflejan un crecimiento sostenido en los últimos años, acompañado de episodios de valorización abrupta que se apartan de la tendencia típica.

boxplot(df$Adjusted, main = "Price_Adjusted", col = "lightblue")

Estadísticos descriptivos

El análisis muestra una tendencia de crecimiento sostenido en el precio de la acción de META, con valores significativamente más altos en los últimos años. La diferencia entre la mediana y la media sugiere la presencia de valores extremos o outliers, lo que podría estar relacionado con eventos clave en la empresa o en el mercado.

Variable: Date (Fecha) * Rango de fechas: La base de datos abarca desde el 2 de enero de 2013 hasta el 27 de febrero de 2025, proporcionando más de 12 años de información histórica sobre el precio ajustado de las acciones.

  • Mediana (2019-01-29) y media (2019-01-27): Indican que la distribución de datos es bastante equilibrada en términos de tiempo, con un punto central cercano a 2019.

Variable: Adjusted (Precio Ajustado de la Acción) * Primer cuartil (Q1 - 104.42): El 25% de los valores están por debajo de este precio, es decir, en los primeros años o en momentos específicos, el precio de la acción estuvo en un rango relativamente bajo.

  • Mediana (170.31): La mitad de los valores de la serie están por debajo de este precio, lo que sugiere que durante gran parte del período el precio ajustado se mantuvo en un rango moderado.

  • Tercer cuartil (Q3 - 263.61): Indica que el 75% de los valores están por debajo de este umbral, con el 25% restante superando dicho valor.

  • Valor máximo (736.02) y Valor mínimo (22.79): Representa el punto más bajo y alto alcanzado por el precio ajustado, lo que podría indicar un fuerte crecimiento en el valor de la acción en los últimos años.

summary(df)
##       Date               Adjusted     
##  Min.   :2013-01-02   Min.   : 22.79  
##  1st Qu.:2016-01-14   1st Qu.:104.42  
##  Median :2019-01-29   Median :170.31  
##  Mean   :2019-01-27   Mean   :198.88  
##  3rd Qu.:2022-02-08   3rd Qu.:263.61  
##  Max.   :2025-02-27   Max.   :736.02

Estadísticos de dispersión y normalidad

Se muestra la distribución de la variable Adjusted”, que representa el precio ajustado de las acciones de META de 2013 a 2025. Se observa una distribución sesgada a la derecha con una acumulación de valores en el rango de 0 a 300 y una cola larga extendiéndose más allá de los 600. Ante lo cual según el gráfico de normalidad se recomienda realizar una transformación logarítmica para tener una distirbución normal. Sin embargo, enn este caso, no se llevará a cabo alguna transformación ya que, en el contexto del análisis de acciones, los valores ajustados deben interpretarse en su escala original para mantener la relación con los precios reales del mercado. También, modificar la escala afectaría la interpretación y comparación con otros activos financieros o períodos de tiempo.

desviacion <- sd(df$Adjusted, na.rm = TRUE)
print(desviacion)
## [1] 137.3567
plot_histogram(df)

plot_normality(df)

Paso 1: Visualizar

La serie de tiempo del precio ajustado de las acciones de META de 2013 a 2025 muestra una clara tendencia alcista con períodos de volatilidad. A partir del gráfico:

  • Tendencia general: Se observa un crecimiento sostenido en el precio de las acciones de META a lo largo del tiempo. Desde 2013, el precio ha aumentado de manera constante, con aceleraciones notables a partir de 2020 y especialmente después de 2023. Sin embargo, en 2021-2022 hay una disminución temporal, posiblemente por factores externos como caídas del mercado o problemas internos de la empresa.

  • Volatilidad: Hay fluctuaciones significativas en 2021 y 2022, reflejando momentos de incertidumbre en el mercado.

  • Crecimiento acelerado reciente: A partir de 2023, la acción muestra un crecimiento exponencial, lo que podría estar relacionado con factores como innovaciones tecnológicas, incremento de ingresos o confianza del mercado.

En relación a la descomposición de la serie, se observa:

  • Tendencia: Desde 2013, el precio ha aumentado de manera constante, con aceleraciones notables a partir de 2020 y especialmente después de 2023.

  • Estacionalidad: Se aprecian fluctuaciones repetitivas a lo largo del tiempo, lo que indica patrones estacionales en el precio de la acción. Estas oscilaciones pueden deberse a eventos recurrentes como anuncios de ganancias trimestrales, lanzamientos de productos o tendencias macroeconómicas que afectan la valoración de META de manera cíclica.

  • Componente aleatorio: Se observa una mayor volatilidad en ciertos períodos, particularmente alrededor de 2021-2022 y 2023-2024, lo cual podría estar relacionado con eventos inesperados como cambios regulatorios, crisis económicas o movimientos especulativos en el mercado.

Con base en lo anterior, la acción de META ha tenido un crecimiento fuerte, con algunas correcciones en el camino, pero su tendencia a largo plazo es claramente alcista.

plot(ts_meta, main="META de 2013 a 2025", ylab="Adjusted Price", xlab="Fecha")

meta.decomp = decompose(ts_meta, type = "additive")
plot(meta.decomp)

Paso 2: Estacionariza la serie

Se realizó un test de tendencia determinística mediante regresión, en el cual se obtuvo que el coeficiente de la variable tiempo (t) es significativo, lo cual indica que hay una relación lineal fuerte entre el tiempo y los valores de la serie, lo que confirma la presencia de una tendencia determinística. Además, el p-value obtenido (2.2e-16) es menor a 0.05, lo que refuerza la alta significancia del modelo y la existencia de dicha tendencia.

Asimismo, de acuerdo a la prueba de Dickey-Fuller, se obtuvo un p-value de 0.99, es decir mayor a 0.05, por ende, se determina que la serie no es estacionaria. Acorde al resultado de la función ndiffs, se sugiere realizar una diferencia de 1 para que la serie sea estacionaria.

# Identificación de Tendencia Dterminística
t <- 1:length(ts_meta)
modelo_trend <- lm(ts_meta ~ t)
summary(modelo_trend)
## 
## Call:
## lm(formula = ts_meta ~ t)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -233.75  -26.77    6.35   19.83  339.59 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 0.162165   2.733683   0.059    0.953    
## t           0.129922   0.001548  83.930   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 75.57 on 3056 degrees of freedom
## Multiple R-squared:  0.6974, Adjusted R-squared:  0.6973 
## F-statistic:  7044 on 1 and 3056 DF,  p-value: < 2.2e-16
# Diferenciación
ndiffs(ts_meta) # Según ndiffs necesitamos diferenciar 1 vez
## [1] 1
tseries::adf.test(ts_meta) # ES MAYOR A 0.05 = NO ES STATIONARITY
## 
##  Augmented Dickey-Fuller Test
## 
## data:  ts_meta
## Dickey-Fuller = -0.064367, Lag order = 14, p-value = 0.99
## alternative hypothesis: stationary

Se aplica la diferenciación sugerida de d=1, ante lo cual se vuelve a realizar la prueba de Dickey-Fuller, y con base al resultado de pvalue = 0.01 (es menor a 0.05), se determina que la serie ya es estacionaria.

# Diferenciacion
dif_meta <- diff(ts_meta, differences=1)
adf.test(dif_meta) #AL SER MENOR A 0.05 = ES STATIONARITY
## Augmented Dickey-Fuller Test 
## alternative: stationary 
##  
## Type 1: no drift no trend 
##       lag   ADF p.value
##  [1,]   0 -57.1    0.01
##  [2,]   1 -40.3    0.01
##  [3,]   2 -32.1    0.01
##  [4,]   3 -28.1    0.01
##  [5,]   4 -25.4    0.01
##  [6,]   5 -23.4    0.01
##  [7,]   6 -21.1    0.01
##  [8,]   7 -19.8    0.01
##  [9,]   8 -17.7    0.01
## Type 2: with drift no trend 
##       lag   ADF p.value
##  [1,]   0 -57.2    0.01
##  [2,]   1 -40.4    0.01
##  [3,]   2 -32.2    0.01
##  [4,]   3 -28.2    0.01
##  [5,]   4 -25.5    0.01
##  [6,]   5 -23.5    0.01
##  [7,]   6 -21.2    0.01
##  [8,]   7 -20.0    0.01
##  [9,]   8 -17.9    0.01
## Type 3: with drift and trend 
##       lag   ADF p.value
##  [1,]   0 -57.3    0.01
##  [2,]   1 -40.4    0.01
##  [3,]   2 -32.3    0.01
##  [4,]   3 -28.2    0.01
##  [5,]   4 -25.6    0.01
##  [6,]   5 -23.6    0.01
##  [7,]   6 -21.3    0.01
##  [8,]   7 -20.1    0.01
##  [9,]   8 -17.9    0.01
## ---- 
## Note: in fact, p.value = 0.01 means p.value <= 0.01
# Se determina que el valor de d = 1

Paso 3: Identifica los valor \(p\) y \(q\)

Observando las funciones pacf para Autocorrelación Parcial, y acf para Autocorrelación Serial, pacf nos muestra una p= de 9 o 0, y acf nos muestra una q= de 0.

pacf(dif_meta) # p = 9 o 0

acf(dif_meta) #q = 0

Paso 4: Ajusta el Modelo ARIMA

Con base en los resultados de los valores de p, d y q; se generaron tres modelos ARIMA ante los cuales se revisará sus residuales, su valor AIC y su comparativa con el proceso estacionario (ruido blanco).

Modelo 1 - ARIMA(0,1,0)

  • Evaluación de los Residuales en el Tiempo: La evolución de los residuales oscilan en torno a cero, pero presentan valores atípicos y posible heterocedasticidad (varianza no constante). Idealmente, los residuales deben distribuirse de manera uniforme y aleatoria. La presencia de fluctuaciones sugiere que el modelo no captura completamente la estructura de los datos.

  • Función de Autocorrelación de los Residuales: El gráfico de la función de autocorrelación (ACF) indica que existen correlaciones significativas en algunos rezagos, lo que implica que los errores no son puramente aleatorios. Esto sugiere que el modelo podría mejorarse, ya que aún hay patrones predecibles en la serie.

  • Distribución de los Residuales: El histograma muestra que los residuales tienen colas más pesadas que una distribución normal, lo que implica la presencia de eventos extremos más frecuentes de lo esperado. Aunque la normalidad no es un requisito estricto, su ausencia puede afectar la confiabilidad de las predicciones.

  • Prueba de Ljung-Box: El p-valor (5.107e−15) indica que los residuales no son ruido blanco, lo que confirma la presencia de dependencia temporal no capturada.

Por lo tanto, se determina que el modelo ARIMA(0,1,0) es bueno pero presenta áreas de oportunidad en términos de heterocedasticidad ante lo cual se debe considerar transformaciones para mejorar la estabilidad de la serie.

#P=0, D=1, Q=0
arima_meta <- arima(ts_meta, order=c(0,1,0)) #pdq
arima_meta$aic
## [1] 18948.82
bic_meta <- arima_meta$aic + log(length(df)) * (length(arima_meta$coef) - 1)
print(bic_meta)
## [1] 18948.13
checkresiduals(arima_meta)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,0)
## Q* = 790.18, df = 504, p-value = 5.107e-15
## 
## Model df: 0.   Total lags used: 504
print("Coeficientes del modelo ARIMA (0,1,0):")
## [1] "Coeficientes del modelo ARIMA (0,1,0):"
print(arima_meta$coef)
## numeric(0)

Modelo 2 - ARIMA(9,1,0)

  • Evaluación de los Residuales en el Tiempo: El gráfico muestra que los residuales siguen centrados en torno a cero, pero persisten valores atípicos y una posible heterocedasticidad. En comparación con el modelo ARIMA(0,1,0), la dispersión de los residuales no parece haber mejorado significativamente, lo que sugiere que el modelo no ha reducido considerablemente los errores.

  • Función de Autocorrelación de los Residuales: Se observa que la autocorrelación sigue presente en varios rezagos. Aunque el modelo ARIMA(9,1,0) incorpora más términos autorregresivos, los residuales aún muestran dependencia temporal, por ende, el modelo no ha eliminado por completo los patrones en los datos.

  • Distribución de los Residuales: Los residuales siguen una distribución con colas más pesadas que la normal, similar al modelo anterior. Por lo tanto, los errores extremos siguen ocurriendo con mayor frecuencia de lo esperado, lo que puede afectar la estabilidad de las predicciones.

  • Prueba de Ljung-Box: El p-value de la prueba de Ljung-Box (7.105e−15) sigue siendo extremadamente bajo, confirmando que los residuales no son ruido blanco y que hay dependencia no capturada.

El modelo ARIMA(9,1,0) no ha mejorado significativamente el ajuste en comparación con ARIMA(0,1,0). Por lo tanto, el modelo es bueno pero no lo suficiente para mejorar heterocedasticidad y estabilidad de la serie.

#P=9, D=1, Q=0
arima_meta2 <- arima(ts_meta, order=c(9,1,0))
arima_meta2$aic
## [1] 18952.03
bic_meta2 <- arima_meta2$aic + log(length(df)) * (length(arima_meta2$coef) - 1)
print(bic_meta2)
## [1] 18957.58
checkresiduals(arima_meta2)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(9,1,0)
## Q* = 777.25, df = 495, p-value = 7.105e-15
## 
## Model df: 9.   Total lags used: 504
print("Coeficientes del modelo ARIMA (9,1,0):")
## [1] "Coeficientes del modelo ARIMA (9,1,0):"
print(arima_meta2$coef)
##          ar1          ar2          ar3          ar4          ar5          ar6 
## -0.034046631 -0.015043424  0.013323440 -0.012179738 -0.014704041 -0.017200556 
##          ar7          ar8          ar9 
##  0.016741582 -0.009390534  0.047534235

Modelo 3 - ARIMA(0,1,1)

El presente modelo se realizó utilizando la función AutoARIMA con el fin de verificar la tendencia, la estacionalidad y posibles patrones en los datos; así como el comportamiento de la serie temporal en comparación con los valores de p, d y q de los dos modelos anteriores, también generados manualmente.

  • Evaluación de los Residuales en el Tiempo: Los residuales están centrados en torno a cero, pero con algunos valores atípicos significativos, similares a los observados en modelos previos. Aunque la dispersión de los errores no parece haber aumentado drásticamente, sigue habiendo picos que pueden impactar la precisión del modelo.

  • Función de Autocorrelación de los Residuales: La ACF muestra que la mayoría de los rezagos caen dentro de los intervalos de confianza (líneas azules), lo que indica una reducción en la autocorrelación respecto a modelos anteriores. Sin embargo, aún persisten algunos valores fuera del rango esperado, sugiriendo que la estructura del modelo podría mejorarse.

  • Distribución de los Residuales: Muestra una distribución sesgada con colas más pesadas que la normal. Esto indica que los errores extremos ocurren con mayor frecuencia de lo esperado, lo que podría afectar la robustez de las predicciones.

  • Prueba de Ljung-Box: El p-value de la prueba de Ljung-Box (8.771e−15) sigue siendo bajo, lo que indica que los residuales aún presentan autocorrelación y no se comportan completamente como ruido blanco.

El modelo ARIMA(0,1,1) muestra una ligera mejora en comparación con modelos anteriores, con menor autocorrelación en los residuales. Sin embargo, la presencia de valores atípicos y colas pesadas sugiere que podrían explorarse modelos alternativos como SARIMA o modelos híbridos con ML para mejorar la precisión y robustez de las predicciones.

# auto.arima(Y)
auto_meta <- auto.arima(ts_meta) #(0,1,1)
auto_meta$aic
## [1] 18944.25
bic_auto <- auto_meta$aic + log(length(df)) * (length(auto_meta$coef) - 1)
print(bic_auto)
## [1] 18944.94
checkresiduals(auto_meta)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,1) with drift
## Q* = 789.23, df = 503, p-value = 4.885e-15
## 
## Model df: 1.   Total lags used: 504
print("Coeficientes del modelo ARIMA (0,1,1):")
## [1] "Coeficientes del modelo ARIMA (0,1,1):"
print(auto_meta$coef)
##         ma1       drift 
## -0.03702498  0.20603978
auto_meta
## Series: ts_meta 
## ARIMA(0,1,1) with drift 
## 
## Coefficients:
##           ma1   drift
##       -0.0370  0.2060
## s.e.   0.0183  0.0933
## 
## sigma^2 = 28.73:  log likelihood = -9469.13
## AIC=18944.25   AICc=18944.26   BIC=18962.33

Modelo seleccionado

La selección del modelo ARIMA(0,1,0) con un AIC de 18948.82 se justifica por varias razones, a pesar de que los modelos ARIMA(9,1,0) con un AIC de 18952.03 y ARIMA(0,1,1) con un AIC de 18944.25 tienen AICs ligeramente más altos o más bajos, respectivamente.

  • Simplicidad del Modelo: El modelo ARIMA(0,1,0) es el más simple y, por lo tanto, más interpretativo.Según, la regla de parsimony se sugiere que, cuando los modelos tienen un rendimiento similar, es preferible seleccionar el más simple, ya que minimiza el riesgo de sobreajuste (overfitting). Un modelo más complejo puede ajustarse excesivamente a los ruidos o variaciones aleatorias en los datos, lo cual puede resultar en un peor desempeño predictivo a largo plazo.

  • Leve diferencia en AIC: Aunque el AIC de los modelos ARIMA(9,1,0) y ARIMA(0,1,1) es ligeramente más alto que el de ARIMA(0,1,0), las diferencias en los valores del AIC son muy pequeñas. En este caso, la diferencia en AIC entre los tres modelos es de solo 4 puntos, lo que sugiere que no hay una mejora significativa en el ajuste del modelo con modelos más complejos.

  • Comportamiento de los Parámetros: El modelo ARIMA(0,1,0) es el que presenta los parámetros más sencillos y no incluye términos de autorregresión ni de media móvil, lo cual es adecuado cuando los datos muestran una tendencia a ser estacionarios en la primera diferencia y no requieren ajustes adicionales de complejidad para capturar patrones estacionales o dependencias más complejas.

En conclusión, el modelo ARIMA(0,1,0) es el más adecuado debido a su simplicidad, la mínima diferencia en el AIC con respecto a los otros modelos y su capacidad para generalizar sin sobreajustarse a los datos.

Paso 5: Proyecciones

Con base al modelo seleccionado de ARIMA(0,1,0) a causa de su simplicidad y poca diferencia en relación al valor de AIC, se realizaron los siguientes escenarios a futuro.

Pronósticos para próximos dos años

Se generaron proyecciones para los próximos dos años, con frecuencia diaria. El rango de fechas es del día hábil número de 35 del 2025 al día 8 del 2028.

h <- 730 

# Generar predicciones
preds <- predict(arima_meta, n.ahead=h)

# Obtener inicio y fin de la predicción
start(preds$pred)
## [1] 2025   35
end(preds$pred)
## [1] 2028    8
# Graficar predicciones
plot.ts(cbind(ts_meta, preds$pred), lty=c(1,3), col=c("black", "blue"), main="Proyección ARIMA(0,1,0)")

Visualizamos ambas series de tiempo, en la parte superior y la proyección en la parte baja.

# Simulación de pronósticos con ruido
proys <- preds$pred + rnorm(h, 0, sqrt(arima_meta$sigma2))
ts.plot(cbind(tail(ts_meta, 169), proys), lty=c(1,3), col=c("black", "blue"))

Generamos una simulación de las predicciones con ruido. Se generaron 730 valores aleatorios con una distribución normal con media 0 y utilizando como desviación estándar, la varianza del error del modelo. Y se suma a la predicción para simular la incertidumbre en el pronósticos. De esta manera no tenemos solamente la predicción suavizada, sino una proyección que toma en cuenta más de la incertidumbre.

# Usando forecast para pronósticos y graficación
prons <- forecast::forecast(arima_meta, level=90, h=h)
plot(prons, main="Pronósticos ARIMA para 2 años")

Pronósticos para próximos dos años con escenario optimista y pesimista (intervalos)

También, se presenta la proyección con intervalos de escenarios optimistas y pesimistas, utilizando un intervalo de confianza de 90%. El escenario pesimista siendo el límite inferior del intervalo y el escenario optimista siendo el límite superior, en el cual se observa que el comportamiento del Escenario_Real, que se mantiene constante en 657.6549 en todos los periodos, se debe a la estructura del modelo ARIMA(0,1,0). Dicho modelo es equivalente a un random walk (caminata aleatoria), lo que implica que la mejor estimación de la siguiente observación es simplemente el último valor observado.

# Generar predicciones con intervalos de confianza
prons <- forecast::forecast(arima_meta, level=90, h=h)

# Crear un data frame con los escenarios
escenarios_df <- data.frame(
  Periodo = 1:h,
  Escenario_Pesimista = prons$lower[,1],  # Límite inferior
  Escenario_Real = prons$mean,            # Predicción central
  Escenario_Optimo = prons$upper[,1]      # Límite superior
)

# Imprimir los escenarios
head(escenarios_df)
##   Periodo Escenario_Pesimista Escenario_Real Escenario_Optimo
## 1       1            648.8295       657.6549         666.4803
## 2       2            645.1739       657.6549         670.1359
## 3       3            642.3688       657.6549         672.9410
## 4       4            640.0041       657.6549         675.3058
## 5       5            637.9207       657.6549         677.3892
## 6       6            636.0371       657.6549         679.2727
# Graficar los escenarios
ggplot(escenarios_df, aes(x = Periodo)) +
  geom_line(aes(y = Escenario_Pesimista, color = "Pesimista"), size = 1, linetype = "dashed") +
  geom_line(aes(y = Escenario_Real, color = "Real"), size = 1) +
  geom_line(aes(y = Escenario_Optimo, color = "Óptimo"), size = 1, linetype = "dashed") +
  labs(title = "Escenarios de Predicción ARIMA(0,1,0)",
       x = "Periodo", y = "Valor Predicho") +
  scale_color_manual(values = c("Pesimista" = "red", "Real" = "blue", "Óptimo" = "green")) +
  theme_minimal()

# Bandas de confianza
lowband <- preds$pred - 1.65 * preds$se
upband <- preds$pred + 1.65 * preds$se

ts.plot(cbind(ts_meta, preds$pred, lowband, upband), lty=c(1,3,3,3), col=c("black", "blue", "red", "red"), main="Predicción con Intervalos de Confianza")

ts.plot(cbind(tail(ts_meta, 169), preds$pred, lowband, upband), lty=c(1,3,3,3), col=c("black", "blue", "red", "red"), main="Predicción con Intervalos de Confianza (Zoom)")

Conclusiones

En conclusión, dado que nuestro modelo ARIMA(0,1,0) sigue un comportamiento de random walk, la proyección del precio de las acciones de Meta se representa como una línea recta, lo que refleja su impredecibilidad a largo plazo.

La metodología Box-Jenkins permitió capturar patrones históricos y generar pronósticos basados en tendencias pasadas, incorporando un margen de incertidumbre mediante ruido aleatorio y bandas de confianza. Sin embargo, dado que este enfoque se basa únicamente en datos pasados, resaltamos la importancia de complementarlo con otros métodos de análisis, como el análisis fundamental y el estudio de factores macroeconómicos, para mejorar la precisión en la toma de decisiones y obtener una visión más completa del comportamiento futuro de la acción.

LS0tDQp0aXRsZTogIlNlcmllcyBkZSBUaWVtcG8iDQpzdWJ0aXRsZTogIkFjdGl2aWRhZCAwMSINCmF1dGhvcjogIkVxdWlwbyA3Ig0KZGF0ZTogIjIwMjUtMDMtMjgiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIGhpZ2hsaWdodDogcHlnbWVudHMNCi0tLQ0KDQohW10oaHR0cHM6Ly9jaXRyaXMtdWMub3JnL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE5LzEwL1RlYy1kZS1Nb250ZXJyZXktbG9nby1ob3Jpem9udGFsLWJsdWUucG5nKQ0KDQo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPg0KICA8cD48c3Ryb25nPlBsYW5lYWNpw7NuIGVzdHJhdMOpZ2ljYSBiYXNhZGEgZW4gYW5hbMOtdGljYSBwcmVzY3JpcHRpdmE8L3N0cm9uZz48L3A+DQogIDxwPjxzdHJvbmc+R3J1cG8gNTAzPC9zdHJvbmc+PC9wPg0KICA8cD48c3Ryb25nPlByb2Zlc29yIFJvZG9sZm8gTWlndWVsIEdhbWVyb3M8L3N0cm9uZz48L3A+DQo8L2Rpdj4NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj4NCiAgPHA+PHN0cm9uZz5FcXVpcG8gNzo8L3N0cm9uZz48L3A+DQogIDxwPkEwMDgzMzExMyAtIEF2cmlsIExvYmF0bzwvcD4NCiAgPHA+QTAxNzcxMTI3IC0gTGVzbHkgRGFyaWFuIFJvbWVybyBWw6F6cXVlejwvcD4NCiAgPHA+QTAwODMxMTA1IC0gSmF6bcOtbiBkZWwgQ2FybWVuIENvcnRleiBNZW5kb3phPC9wPg0KICA8cD5BMDEyODQ2MTEgLSBMaXNzZXQgSGVybsOhbmRlejwvcD4NCjwvZGl2Pg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCgllY2hvID0gVFJVRSwNCgltZXNzYWdlID0gRkFMU0UsDQoJd2FybmluZyA9IEZBTFNFDQopDQojaW5zdGFsbC5wYWNrYWdlcygicm5hdHVyYWxlYXJ0aGhpcmVzIiwgcmVwb3MgPSAiaHR0cHM6Ly9wYWNrYWdlcy5yb3BlbnNjaS5vcmciKQ0KI2luc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikNCnBhY21hbjo6cF9sb2FkKGRwbHlyLCBnZ3Bsb3QyLCBjYXIsIHRzZXJpZXMsIGNvcnJwbG90LCBwYXRjaHdvcmssIHJlYWR4bCwgcHN5Y2gsIG1hcHMsIE1BU1MsIEFFUiwgcXVhbnRtb2QsIHN0YXRzLCBzY2FsZXMsIGRsb29rciwgRGF0YUV4cGxvcmVyLCB0aWR5ciwga25pdHIsIFJDb2xvckJyZXdlciwgcGxvdGx5LCBmb3JlY2FzdCwgdHNlcmllcywgb3Blbnhsc3gsIHZhcnMsIHRpZHl2ZXJzZSwgbG10ZXN0LCB1cmNhLCBhVFNBLCBkcGx5ciwgZ2dwbG90MiwgbmFuaWFyLCB0c2VyaWVzLCBjb3JycGxvdCwgcGF0Y2h3b3JrLCByZWFkeGwsIHBzeWNoLCBtYXBzLCBzZiwgcm5hdHVyYWxlYXJ0aCwgcm5hdHVyYWxlYXJ0aGRhdGEsIHN0cmluZ2ksIHNjYWxlcywgZGxvb2tyLCBEYXRhRXhwbG9yZXIsIHRpZHlyLCBrbml0ciwgUkNvbG9yQnJld2VyLCBwbG90bHksIGZvcmVjYXN0LCB0c2VyaWVzLCBvcGVueGxzeCwgdmFycywgbG10ZXN0KQ0KYGBgDQoNCiMgKipBY3RpdmlkYWQgLSBTZXJpZXMgZGUgVGllbXBvKioNCg0KDQojIEFuw6FsaXNpcyBFeHBsb3JhdG9yaW8NCg0KIyMgQ2FyZ2EgZGUgYmFzZSBkZSBkYXRvcw0KDQpBcGxpY2EgbGEgbWV0b2RvbG9nw61hIEJveC1KZW5raW5zIGEgbGEgc2VyaWUgZGUgcHJlY2lvcyBhanVzdGFkb3MgZGUgbGEgZW1wcmVzYSAqKk1ldGEgIChNRVRBKSoqIGRlbCBkw61hIDAxL0VuZXJvLzIwMTMgYWwgMzEvTWFyem8vMjAyNDsgYWRlbcOhcyBzZSBjb252aWVydGUgYSBzZXJpZSBkZSB0aWVtcG8uDQoNCmBgYHtyfQ0KZ2V0U3ltYm9scygiTUVUQSIsIHNyYyA9ICJ5YWhvbyIsIGZyb20gPSAiMjAxMy0wMS0wMSIsIHRvID0gIjIwMjUtMDItMjgiKQ0KDQpkZiA8LSBkYXRhLmZyYW1lKERhdGUgPSBpbmRleChNRVRBKSwgY29yZWRhdGEoTUVUQSkpDQpjb2xuYW1lcyhkZikgPC0gYygiRGF0ZSIsICJPcGVuIiwgIkhpZ2giLCAiTG93IiwgIkNsb3NlIiwgIlZvbHVtZSIsICJBZGp1c3RlZCIpDQoNCmRmIDwtIGRmICU+JSBzZWxlY3QoRGF0ZSwgQWRqdXN0ZWQpDQoNCnRzX21ldGEgPC0gdHMoZGYkQWRqdXN0ZWQsIGZyZXF1ZW5jeSA9IDI1Miwgc3RhcnQgPSBjKDIwMTMsIDEpKQ0KaGVhZCh0c19tZXRhKQ0KYGBgDQoNCg0KIyMgUmV2aXNpw7NuIGRlIHZhbG9yZXMgbnVsb3MNCg0KTGEgYmFzZSBkZSBkYXRvcyBlc3TDoSBjb21wdWVzdGEgcG9yIGRvcyB2YXJpYWJsZXM6IERhdGUsIHF1ZSByZXByZXNlbnRhIGxhIGZlY2hhIGRlIGVtaXNpw7NuIGRlbCBwcmVjaW8gZGUgbGEgYWNjacOzbiwgeSBBZGp1c3RlZCwgcXVlIGNvcnJlc3BvbmRlIGFsIHByZWNpbyBhanVzdGFkbyBkZSBsYSBhY2Npw7NuLCBzaWVuZG8gZXN0YSDDumx0aW1hIG51ZXN0cmEgdmFyaWFibGUgZGUgaW50ZXLDqXMuDQoNClRyYXMgbGEgcmV2aXNpw7NuLCBzZSBjb25maXJtYSBxdWUgbm8gZXhpc3RlbiB2YWxvcmVzIG51bG9zIGVuIGxhIGJhc2UgZGUgZGF0b3MuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIE51bG9zIFRvdGFsZXMNCnN1bShpcy5uYShkZikpDQoNCiMgTnVsb3MgcG9yIENvbHVtbmENCmdnX21pc3NfdmFyKGRmKQ0KYGBgDQoNCg0KIyMgQ29udmVyc2nDs24gZGUgdGlwbyBkZSBkYXRvcw0KDQpTZSByZWFsaXphIGNvbnZlcnNpw7NuIGRlIHZhcmlhYmxlcyBhIGxvcyB0aXBvcyBkZSBkYXRvcyBjb3JyZXNwb25kaWVudGVzIHBhcmEgZ2FyYW50aXphciB1biBhZGVjdWFkbyBwcm9jZXNhbWllbnRvIHkgYW7DoWxpc2lzIGRlIGxvcyBkYXRvczoNCg0KKiBEYXRlIHNlIHRyYW5zZm9ybcOzIGVuIHVuYSB2YXJpYWJsZSBkZSB0aXBvIGZlY2hhIChEYXRlKSwgcGVybWl0aWVuZG8gc3UgY29ycmVjdGEgbWFuaXB1bGFjacOzbiBlbiBhbsOhbGlzaXMgdGVtcG9yYWxlcy4NCg0KKiBBZGp1c3RlZCBzZSBjb252aXJ0acOzIGVuIHVuYSB2YXJpYWJsZSBkZSB0aXBvIG51bcOpcmljbyAobnVtZXJpYyksIGFzZWd1cmFuZG8gcXVlIHB1ZWRhIHNlciB1dGlsaXphZGEgZW4gY8OhbGN1bG9zIGVzdGFkw61zdGljb3MgeSBtb2RlbG9zIGRlIHByZWRpY2Npw7NuLg0KDQpgYGB7cn0NCmRmJEFkanVzdGVkPC1hcy5udW1lcmljKGRmJEFkanVzdGVkKSANCmRmJERhdGU8LWFzLkRhdGUoZGYkRGF0ZSkgDQoNCmNsYXNlczIgPC0gc2FwcGx5KGRmLCBjbGFzcykNCmNsYXNlczINCmBgYA0KDQojIyBEaXN0cmlidWNpw7NuIGRlIHZhcmlhYmxlICJBZGp1c3RlZCINCg0KTGEgbWF5b3LDrWEgZGUgbG9zIGRhdG9zIHNlIGVuY3VlbnRyYW4gZW4gdW4gcmFuZ28gYXByb3hpbWFkbyBkZSAxMDAgYSAzMDAsIGNvbmNlbnRyw6FuZG9zZSBkZW50cm8gZGUgbGEgY2FqYSBkZWwgZGlhZ3JhbWEgZGUgY2FqYSB5IGJpZ290ZXMuDQoNCkVsIHByZWNpbyBhanVzdGFkbyBkZSBNRVRBIGhhIHNlZ3VpZG8gdW5hIGNsYXJhIHRlbmRlbmNpYSBhbGNpc3RhLCBjb24gdW4gaW5jcmVtZW50byBzaWduaWZpY2F0aXZvIGVuIGxvcyB2YWxvcmVzIHJlY2llbnRlcy4gTG8gYW50ZXJpb3IsIHNlIGV2aWRlbmNpYSBlbiBsYSBwcmVzZW5jaWEgZGUgbcO6bHRpcGxlcyBvdXRsaWVycyBwb3IgZW5jaW1hIGRlbCBiaWdvdGUgc3VwZXJpb3IsIGxvIHF1ZSBpbmRpY2EgcXVlIGxvcyBwcmVjaW9zIGRlIGxhcyBhY2Npb25lcyBoYW4gc2lkbyBzaWduaWZpY2F0aXZhbWVudGUgbcOhcyBhbHRvcyBxdWUgZWwgcmVzdG8gZGUgbGEgZGlzdHJpYnVjacOzbiBlbiBjaWVydG9zIHBlcmlvZG9zLiBEaWNobyAgY29tcG9ydGFtaWVudG8gcG9kcsOtYSBlc3RhciBhc29jaWFkbyBjb24gZmFjdG9yZXMgY29tbyBpbnZlcnNpb25lcyBlbiBudWV2YXMgdGVjbm9sb2fDrWFzLCBjYW1iaW9zIGVzdHJhdMOpZ2ljb3MgZGVudHJvIGRlIGxhIGVtcHJlc2EgbyB1biBhdWdlIGVuIGVsIHNlY3RvciB0ZWNub2zDs2dpY28uDQoNCkVuIGdlbmVyYWwsIGxvcyBkYXRvcyByZWZsZWphbiB1biBjcmVjaW1pZW50byBzb3N0ZW5pZG8gZW4gbG9zIMO6bHRpbW9zIGHDsW9zLCBhY29tcGHDsWFkbyBkZSBlcGlzb2Rpb3MgZGUgdmFsb3JpemFjacOzbiBhYnJ1cHRhIHF1ZSBzZSBhcGFydGFuIGRlIGxhIHRlbmRlbmNpYSB0w61waWNhLg0KDQpgYGB7cn0NCmJveHBsb3QoZGYkQWRqdXN0ZWQsIG1haW4gPSAiUHJpY2VfQWRqdXN0ZWQiLCBjb2wgPSAibGlnaHRibHVlIikNCmBgYA0KDQojIyBFc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcw0KDQpFbCBhbsOhbGlzaXMgbXVlc3RyYSB1bmEgdGVuZGVuY2lhIGRlIGNyZWNpbWllbnRvIHNvc3RlbmlkbyBlbiBlbCBwcmVjaW8gZGUgbGEgYWNjacOzbiBkZSBNRVRBLCBjb24gdmFsb3JlcyBzaWduaWZpY2F0aXZhbWVudGUgbcOhcyBhbHRvcyBlbiBsb3Mgw7psdGltb3MgYcOxb3MuIExhIGRpZmVyZW5jaWEgZW50cmUgbGEgbWVkaWFuYSB5IGxhIG1lZGlhIHN1Z2llcmUgbGEgcHJlc2VuY2lhIGRlIHZhbG9yZXMgZXh0cmVtb3MgbyBvdXRsaWVycywgbG8gcXVlIHBvZHLDrWEgZXN0YXIgcmVsYWNpb25hZG8gY29uIGV2ZW50b3MgY2xhdmUgZW4gbGEgZW1wcmVzYSBvIGVuIGVsIG1lcmNhZG8uDQoNCioqVmFyaWFibGU6IERhdGUgKEZlY2hhKSoqDQoqIFJhbmdvIGRlIGZlY2hhczogTGEgYmFzZSBkZSBkYXRvcyBhYmFyY2EgZGVzZGUgZWwgMiBkZSBlbmVybyBkZSAyMDEzIGhhc3RhIGVsIDI3IGRlIGZlYnJlcm8gZGUgMjAyNSwgcHJvcG9yY2lvbmFuZG8gbcOhcyBkZSAxMiBhw7FvcyBkZSBpbmZvcm1hY2nDs24gaGlzdMOzcmljYSBzb2JyZSBlbCBwcmVjaW8gYWp1c3RhZG8gZGUgbGFzIGFjY2lvbmVzLg0KDQoqIE1lZGlhbmEgKDIwMTktMDEtMjkpIHkgbWVkaWEgKDIwMTktMDEtMjcpOiBJbmRpY2FuIHF1ZSBsYSBkaXN0cmlidWNpw7NuIGRlIGRhdG9zIGVzIGJhc3RhbnRlIGVxdWlsaWJyYWRhIGVuIHTDqXJtaW5vcyBkZSB0aWVtcG8sIGNvbiB1biBwdW50byBjZW50cmFsIGNlcmNhbm8gYSAyMDE5Lg0KDQoNCioqVmFyaWFibGU6IEFkanVzdGVkIChQcmVjaW8gQWp1c3RhZG8gZGUgbGEgQWNjacOzbikqKg0KKiBQcmltZXIgY3VhcnRpbCAoUTEgLSAxMDQuNDIpOiBFbCAyNSUgZGUgbG9zIHZhbG9yZXMgZXN0w6FuIHBvciBkZWJham8gZGUgZXN0ZSBwcmVjaW8sIGVzIGRlY2lyLCBlbiBsb3MgcHJpbWVyb3MgYcOxb3MgbyBlbiBtb21lbnRvcyBlc3BlY8OtZmljb3MsIGVsIHByZWNpbyBkZSBsYSBhY2Npw7NuIGVzdHV2byBlbiB1biByYW5nbyByZWxhdGl2YW1lbnRlIGJham8uDQoNCiogTWVkaWFuYSAoMTcwLjMxKTogTGEgbWl0YWQgZGUgbG9zIHZhbG9yZXMgZGUgbGEgc2VyaWUgZXN0w6FuIHBvciBkZWJham8gZGUgZXN0ZSBwcmVjaW8sIGxvIHF1ZSBzdWdpZXJlIHF1ZSBkdXJhbnRlIGdyYW4gcGFydGUgZGVsIHBlcsOtb2RvIGVsIHByZWNpbyBhanVzdGFkbyBzZSBtYW50dXZvIGVuIHVuIHJhbmdvIG1vZGVyYWRvLg0KDQoqIFRlcmNlciBjdWFydGlsIChRMyAtIDI2My42MSk6IEluZGljYSBxdWUgZWwgNzUlIGRlIGxvcyB2YWxvcmVzIGVzdMOhbiBwb3IgZGViYWpvIGRlIGVzdGUgdW1icmFsLCBjb24gZWwgMjUlIHJlc3RhbnRlIHN1cGVyYW5kbyBkaWNobyB2YWxvci4NCg0KKiBWYWxvciBtw6F4aW1vICg3MzYuMDIpIHkgVmFsb3IgbcOtbmltbyAoMjIuNzkpOiBSZXByZXNlbnRhIGVsIHB1bnRvIG3DoXMgYmFqbyB5IGFsdG8gYWxjYW56YWRvIHBvciBlbCBwcmVjaW8gYWp1c3RhZG8sIGxvIHF1ZSBwb2Ryw61hIGluZGljYXIgdW4gZnVlcnRlIGNyZWNpbWllbnRvIGVuIGVsIHZhbG9yIGRlIGxhIGFjY2nDs24gZW4gbG9zIMO6bHRpbW9zIGHDsW9zLg0KDQpgYGB7cn0NCnN1bW1hcnkoZGYpDQpgYGANCg0KIyMgRXN0YWTDrXN0aWNvcyBkZSBkaXNwZXJzacOzbiB5IG5vcm1hbGlkYWQNCg0KU2UgbXVlc3RyYSBsYSBkaXN0cmlidWNpw7NuIGRlIGxhIHZhcmlhYmxlIEFkanVzdGVkIiwgcXVlIHJlcHJlc2VudGEgZWwgcHJlY2lvIGFqdXN0YWRvIGRlIGxhcyBhY2Npb25lcyBkZSBNRVRBIGRlIDIwMTMgYSAyMDI1LiBTZSBvYnNlcnZhIHVuYSBkaXN0cmlidWNpw7NuIHNlc2dhZGEgYSBsYSBkZXJlY2hhIGNvbiB1bmEgYWN1bXVsYWNpw7NuIGRlIHZhbG9yZXMgZW4gZWwgcmFuZ28gZGUgMCBhIDMwMCB5IHVuYSBjb2xhIGxhcmdhIGV4dGVuZGnDqW5kb3NlIG3DoXMgYWxsw6EgZGUgbG9zIDYwMC4gQW50ZSBsbyBjdWFsIHNlZ8O6biBlbCBncsOhZmljbyBkZSBub3JtYWxpZGFkIHNlIHJlY29taWVuZGEgcmVhbGl6YXIgdW5hIHRyYW5zZm9ybWFjacOzbiBsb2dhcsOtdG1pY2EgcGFyYSB0ZW5lciB1bmEgZGlzdGlyYnVjacOzbiBub3JtYWwuIFNpbiBlbWJhcmdvLCBlbm4gZXN0ZSBjYXNvLCBubyBzZSBsbGV2YXLDoSBhIGNhYm8gYWxndW5hIHRyYW5zZm9ybWFjacOzbiB5YSBxdWUsIGVuIGVsIGNvbnRleHRvIGRlbCBhbsOhbGlzaXMgZGUgYWNjaW9uZXMsIGxvcyB2YWxvcmVzIGFqdXN0YWRvcyBkZWJlbiBpbnRlcnByZXRhcnNlIGVuIHN1IGVzY2FsYSBvcmlnaW5hbCBwYXJhIG1hbnRlbmVyIGxhIHJlbGFjacOzbiBjb24gbG9zIHByZWNpb3MgcmVhbGVzIGRlbCBtZXJjYWRvLiBUYW1iacOpbiwgbW9kaWZpY2FyIGxhIGVzY2FsYSBhZmVjdGFyw61hIGxhIGludGVycHJldGFjacOzbiB5IGNvbXBhcmFjacOzbiBjb24gb3Ryb3MgYWN0aXZvcyBmaW5hbmNpZXJvcyBvIHBlcsOtb2RvcyBkZSB0aWVtcG8uDQoNCmBgYHtyfQ0KZGVzdmlhY2lvbiA8LSBzZChkZiRBZGp1c3RlZCwgbmEucm0gPSBUUlVFKQ0KcHJpbnQoZGVzdmlhY2lvbikNCg0KcGxvdF9oaXN0b2dyYW0oZGYpDQpwbG90X25vcm1hbGl0eShkZikNCmBgYA0KDQoNCiMgKipQYXNvIDE6KiogVmlzdWFsaXphciANCg0KTGEgc2VyaWUgZGUgdGllbXBvIGRlbCBwcmVjaW8gYWp1c3RhZG8gZGUgbGFzIGFjY2lvbmVzIGRlIE1FVEEgZGUgMjAxMyBhIDIwMjUgbXVlc3RyYSB1bmEgY2xhcmEgdGVuZGVuY2lhIGFsY2lzdGEgY29uIHBlcsOtb2RvcyBkZSB2b2xhdGlsaWRhZC4gQSBwYXJ0aXIgZGVsIGdyw6FmaWNvOg0KDQoqIFRlbmRlbmNpYSBnZW5lcmFsOiBTZSBvYnNlcnZhIHVuIGNyZWNpbWllbnRvIHNvc3RlbmlkbyBlbiBlbCBwcmVjaW8gZGUgbGFzIGFjY2lvbmVzIGRlIE1FVEEgYSBsbyBsYXJnbyBkZWwgdGllbXBvLiBEZXNkZSAyMDEzLCBlbCBwcmVjaW8gaGEgYXVtZW50YWRvIGRlIG1hbmVyYSBjb25zdGFudGUsIGNvbiBhY2VsZXJhY2lvbmVzIG5vdGFibGVzIGEgcGFydGlyIGRlIDIwMjAgeSBlc3BlY2lhbG1lbnRlIGRlc3B1w6lzIGRlIDIwMjMuIFNpbiBlbWJhcmdvLCBlbiAyMDIxLTIwMjIgaGF5IHVuYSBkaXNtaW51Y2nDs24gdGVtcG9yYWwsIHBvc2libGVtZW50ZSBwb3IgZmFjdG9yZXMgZXh0ZXJub3MgY29tbyBjYcOtZGFzIGRlbCBtZXJjYWRvIG8gcHJvYmxlbWFzIGludGVybm9zIGRlIGxhIGVtcHJlc2EuDQoNCiogVm9sYXRpbGlkYWQ6IEhheSBmbHVjdHVhY2lvbmVzIHNpZ25pZmljYXRpdmFzIGVuIDIwMjEgeSAyMDIyLCByZWZsZWphbmRvIG1vbWVudG9zIGRlIGluY2VydGlkdW1icmUgZW4gZWwgbWVyY2Fkby4NCg0KKiBDcmVjaW1pZW50byBhY2VsZXJhZG8gcmVjaWVudGU6IEEgcGFydGlyIGRlIDIwMjMsIGxhIGFjY2nDs24gbXVlc3RyYSB1biBjcmVjaW1pZW50byBleHBvbmVuY2lhbCwgbG8gcXVlIHBvZHLDrWEgZXN0YXIgcmVsYWNpb25hZG8gY29uIGZhY3RvcmVzIGNvbW8gaW5ub3ZhY2lvbmVzIHRlY25vbMOzZ2ljYXMsIGluY3JlbWVudG8gZGUgaW5ncmVzb3MgbyBjb25maWFuemEgZGVsIG1lcmNhZG8uDQoNCkVuIHJlbGFjacOzbiBhIGxhIGRlc2NvbXBvc2ljacOzbiBkZSBsYSBzZXJpZSwgc2Ugb2JzZXJ2YToNCg0KKiBUZW5kZW5jaWE6IERlc2RlIDIwMTMsIGVsIHByZWNpbyBoYSBhdW1lbnRhZG8gZGUgbWFuZXJhIGNvbnN0YW50ZSwgY29uIGFjZWxlcmFjaW9uZXMgbm90YWJsZXMgYSBwYXJ0aXIgZGUgMjAyMCB5IGVzcGVjaWFsbWVudGUgZGVzcHXDqXMgZGUgMjAyMy4NCg0KKiBFc3RhY2lvbmFsaWRhZDogU2UgYXByZWNpYW4gZmx1Y3R1YWNpb25lcyByZXBldGl0aXZhcyBhIGxvIGxhcmdvIGRlbCB0aWVtcG8sIGxvIHF1ZSBpbmRpY2EgcGF0cm9uZXMgZXN0YWNpb25hbGVzIGVuIGVsIHByZWNpbyBkZSBsYSBhY2Npw7NuLiBFc3RhcyBvc2NpbGFjaW9uZXMgcHVlZGVuIGRlYmVyc2UgYSBldmVudG9zIHJlY3VycmVudGVzIGNvbW8gYW51bmNpb3MgZGUgZ2FuYW5jaWFzIHRyaW1lc3RyYWxlcywgbGFuemFtaWVudG9zIGRlIHByb2R1Y3RvcyBvIHRlbmRlbmNpYXMgbWFjcm9lY29uw7NtaWNhcyBxdWUgYWZlY3RhbiBsYSB2YWxvcmFjacOzbiBkZSBNRVRBIGRlIG1hbmVyYSBjw61jbGljYS4NCg0KKiBDb21wb25lbnRlIGFsZWF0b3JpbzogU2Ugb2JzZXJ2YSB1bmEgbWF5b3Igdm9sYXRpbGlkYWQgZW4gY2llcnRvcyBwZXLDrW9kb3MsIHBhcnRpY3VsYXJtZW50ZSBhbHJlZGVkb3IgZGUgMjAyMS0yMDIyIHkgMjAyMy0yMDI0LCBsbyBjdWFsIHBvZHLDrWEgZXN0YXIgcmVsYWNpb25hZG8gY29uIGV2ZW50b3MgaW5lc3BlcmFkb3MgY29tbyBjYW1iaW9zIHJlZ3VsYXRvcmlvcywgY3Jpc2lzIGVjb27Ds21pY2FzIG8gbW92aW1pZW50b3MgZXNwZWN1bGF0aXZvcyBlbiBlbCBtZXJjYWRvLg0KDQpDb24gYmFzZSBlbiBsbyBhbnRlcmlvciwgbGEgYWNjacOzbiBkZSBNRVRBIGhhIHRlbmlkbyB1biBjcmVjaW1pZW50byBmdWVydGUsIGNvbiBhbGd1bmFzIGNvcnJlY2Npb25lcyBlbiBlbCBjYW1pbm8sIHBlcm8gc3UgdGVuZGVuY2lhIGEgbGFyZ28gcGxhem8gZXMgY2xhcmFtZW50ZSBhbGNpc3RhLg0KDQpgYGB7cn0NCnBsb3QodHNfbWV0YSwgbWFpbj0iTUVUQSBkZSAyMDEzIGEgMjAyNSIsIHlsYWI9IkFkanVzdGVkIFByaWNlIiwgeGxhYj0iRmVjaGEiKQ0KDQptZXRhLmRlY29tcCA9IGRlY29tcG9zZSh0c19tZXRhLCB0eXBlID0gImFkZGl0aXZlIikNCnBsb3QobWV0YS5kZWNvbXApDQpgYGANCg0KIyAqKlBhc28gMjoqKiBFc3RhY2lvbmFyaXphIGxhIHNlcmllDQoNClNlIHJlYWxpesOzIHVuIHRlc3QgZGUgdGVuZGVuY2lhIGRldGVybWluw61zdGljYSBtZWRpYW50ZSByZWdyZXNpw7NuLCBlbiBlbCBjdWFsIHNlIG9idHV2byBxdWUgZWwgY29lZmljaWVudGUgZGUgbGEgdmFyaWFibGUgdGllbXBvICh0KSBlcyBzaWduaWZpY2F0aXZvLCBsbyBjdWFsIGluZGljYSBxdWUgaGF5IHVuYSByZWxhY2nDs24gbGluZWFsIGZ1ZXJ0ZSBlbnRyZSBlbCB0aWVtcG8geSBsb3MgdmFsb3JlcyBkZSBsYSBzZXJpZSwgbG8gcXVlIGNvbmZpcm1hIGxhIHByZXNlbmNpYSBkZSB1bmEgdGVuZGVuY2lhIGRldGVybWluw61zdGljYS4gQWRlbcOhcywgZWwgcC12YWx1ZSBvYnRlbmlkbyAoMi4yZS0xNikgZXMgbWVub3IgYSAwLjA1LCBsbyBxdWUgcmVmdWVyemEgbGEgYWx0YSBzaWduaWZpY2FuY2lhIGRlbCBtb2RlbG8geSBsYSBleGlzdGVuY2lhIGRlIGRpY2hhIHRlbmRlbmNpYS4NCg0KQXNpbWlzbW8sIGRlIGFjdWVyZG8gYSBsYSBwcnVlYmEgZGUgRGlja2V5LUZ1bGxlciwgc2Ugb2J0dXZvIHVuIHAtdmFsdWUgZGUgMC45OSwgZXMgZGVjaXIgbWF5b3IgYSAwLjA1LCBwb3IgZW5kZSwgc2UgZGV0ZXJtaW5hIHF1ZSBsYSBzZXJpZSBubyBlcyBlc3RhY2lvbmFyaWEuIEFjb3JkZSBhbCByZXN1bHRhZG8gZGUgbGEgZnVuY2nDs24gbmRpZmZzLCBzZSBzdWdpZXJlIHJlYWxpemFyIHVuYSBkaWZlcmVuY2lhIGRlIDEgcGFyYSBxdWUgbGEgc2VyaWUgc2VhIGVzdGFjaW9uYXJpYS4NCg0KYGBge3J9DQojIElkZW50aWZpY2FjacOzbiBkZSBUZW5kZW5jaWEgRHRlcm1pbsOtc3RpY2ENCnQgPC0gMTpsZW5ndGgodHNfbWV0YSkNCm1vZGVsb190cmVuZCA8LSBsbSh0c19tZXRhIH4gdCkNCnN1bW1hcnkobW9kZWxvX3RyZW5kKQ0KDQojIERpZmVyZW5jaWFjacOzbg0KbmRpZmZzKHRzX21ldGEpICMgU2Vnw7puIG5kaWZmcyBuZWNlc2l0YW1vcyBkaWZlcmVuY2lhciAxIHZleg0KdHNlcmllczo6YWRmLnRlc3QodHNfbWV0YSkgIyBFUyBNQVlPUiBBIDAuMDUgPSBOTyBFUyBTVEFUSU9OQVJJVFkNCmBgYA0KDQpTZSBhcGxpY2EgbGEgZGlmZXJlbmNpYWNpw7NuIHN1Z2VyaWRhIGRlIGQ9MSwgYW50ZSBsbyBjdWFsIHNlIHZ1ZWx2ZSBhIHJlYWxpemFyIGxhIHBydWViYSBkZSBEaWNrZXktRnVsbGVyLCB5IGNvbiBiYXNlIGFsIHJlc3VsdGFkbyBkZSBwdmFsdWUgPSAwLjAxIChlcyBtZW5vciBhIDAuMDUpLCBzZSBkZXRlcm1pbmEgcXVlIGxhIHNlcmllIHlhIGVzIGVzdGFjaW9uYXJpYS4NCg0KYGBge3J9DQojIERpZmVyZW5jaWFjaW9uDQpkaWZfbWV0YSA8LSBkaWZmKHRzX21ldGEsIGRpZmZlcmVuY2VzPTEpDQphZGYudGVzdChkaWZfbWV0YSkgI0FMIFNFUiBNRU5PUiBBIDAuMDUgPSBFUyBTVEFUSU9OQVJJVFkNCg0KIyBTZSBkZXRlcm1pbmEgcXVlIGVsIHZhbG9yIGRlIGQgPSAxDQpgYGANCg0KDQojICoqUGFzbyAzOioqIElkZW50aWZpY2EgbG9zIHZhbG9yICRwJCB5ICRxJA0KDQpPYnNlcnZhbmRvIGxhcyBmdW5jaW9uZXMgcGFjZiBwYXJhIEF1dG9jb3JyZWxhY2nDs24gUGFyY2lhbCwgeSBhY2YgcGFyYSBBdXRvY29ycmVsYWNpw7NuIFNlcmlhbCwgcGFjZiBub3MgbXVlc3RyYSB1bmEgcD0gZGUgOSBvIDAsIHkgYWNmIG5vcyBtdWVzdHJhIHVuYSBxPSBkZSAwLiANCg0KYGBge3J9DQpwYWNmKGRpZl9tZXRhKSAjIHAgPSA5IG8gMA0KYWNmKGRpZl9tZXRhKSAjcSA9IDANCmBgYA0KDQoNCiMgKipQYXNvIDQ6KiogQWp1c3RhIGVsIE1vZGVsbyBBUklNQQ0KDQpDb24gYmFzZSBlbiBsb3MgcmVzdWx0YWRvcyBkZSBsb3MgdmFsb3JlcyBkZSBwLCBkIHkgcTsgc2UgZ2VuZXJhcm9uIHRyZXMgbW9kZWxvcyBBUklNQSBhbnRlIGxvcyBjdWFsZXMgc2UgcmV2aXNhcsOhIHN1cyByZXNpZHVhbGVzLCBzdSB2YWxvciBBSUMgeSBzdSBjb21wYXJhdGl2YSBjb24gZWwgcHJvY2VzbyBlc3RhY2lvbmFyaW8gKHJ1aWRvIGJsYW5jbykuDQoNCiMjIE1vZGVsbyAxIC0gQVJJTUEoMCwxLDApDQoNCiogKkV2YWx1YWNpw7NuIGRlIGxvcyBSZXNpZHVhbGVzIGVuIGVsIFRpZW1wbzoqIExhIGV2b2x1Y2nDs24gZGUgbG9zIHJlc2lkdWFsZXMgb3NjaWxhbiBlbiB0b3JubyBhIGNlcm8sIHBlcm8gcHJlc2VudGFuIHZhbG9yZXMgYXTDrXBpY29zIHkgcG9zaWJsZSBoZXRlcm9jZWRhc3RpY2lkYWQgKHZhcmlhbnphIG5vIGNvbnN0YW50ZSkuIElkZWFsbWVudGUsIGxvcyByZXNpZHVhbGVzIGRlYmVuIGRpc3RyaWJ1aXJzZSBkZSBtYW5lcmEgdW5pZm9ybWUgeSBhbGVhdG9yaWEuIExhIHByZXNlbmNpYSBkZSBmbHVjdHVhY2lvbmVzIHN1Z2llcmUgcXVlIGVsIG1vZGVsbyBubyBjYXB0dXJhIGNvbXBsZXRhbWVudGUgbGEgZXN0cnVjdHVyYSBkZSBsb3MgZGF0b3MuDQoNCiogKkZ1bmNpw7NuIGRlIEF1dG9jb3JyZWxhY2nDs24gZGUgbG9zIFJlc2lkdWFsZXM6KiBFbCBncsOhZmljbyBkZSBsYSBmdW5jacOzbiBkZSBhdXRvY29ycmVsYWNpw7NuIChBQ0YpIGluZGljYSBxdWUgZXhpc3RlbiBjb3JyZWxhY2lvbmVzIHNpZ25pZmljYXRpdmFzIGVuIGFsZ3Vub3MgcmV6YWdvcywgbG8gcXVlIGltcGxpY2EgcXVlIGxvcyBlcnJvcmVzIG5vIHNvbiBwdXJhbWVudGUgYWxlYXRvcmlvcy4gRXN0byBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gcG9kcsOtYSBtZWpvcmFyc2UsIHlhIHF1ZSBhw7puIGhheSBwYXRyb25lcyBwcmVkZWNpYmxlcyBlbiBsYSBzZXJpZS4NCg0KKiAqRGlzdHJpYnVjacOzbiBkZSBsb3MgUmVzaWR1YWxlczoqIEVsIGhpc3RvZ3JhbWEgbXVlc3RyYSBxdWUgbG9zIHJlc2lkdWFsZXMgdGllbmVuIGNvbGFzIG3DoXMgcGVzYWRhcyBxdWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLCBsbyBxdWUgaW1wbGljYSBsYSBwcmVzZW5jaWEgZGUgZXZlbnRvcyBleHRyZW1vcyBtw6FzIGZyZWN1ZW50ZXMgZGUgbG8gZXNwZXJhZG8uIEF1bnF1ZSBsYSBub3JtYWxpZGFkIG5vIGVzIHVuIHJlcXVpc2l0byBlc3RyaWN0bywgc3UgYXVzZW5jaWEgcHVlZGUgYWZlY3RhciBsYSBjb25maWFiaWxpZGFkIGRlIGxhcyBwcmVkaWNjaW9uZXMuDQoNCiogKlBydWViYSBkZSBManVuZy1Cb3g6KiBFbCBwLXZhbG9yICg1LjEwN2XiiJIxNSkgaW5kaWNhIHF1ZSBsb3MgcmVzaWR1YWxlcyBubyBzb24gcnVpZG8gYmxhbmNvLCBsbyBxdWUgY29uZmlybWEgbGEgcHJlc2VuY2lhIGRlIGRlcGVuZGVuY2lhIHRlbXBvcmFsIG5vIGNhcHR1cmFkYS4NCg0KUG9yIGxvIHRhbnRvLCBzZSBkZXRlcm1pbmEgcXVlIGVsIG1vZGVsbyBBUklNQSgwLDEsMCkgZXMgYnVlbm8gcGVybyBwcmVzZW50YSDDoXJlYXMgZGUgb3BvcnR1bmlkYWQgZW4gdMOpcm1pbm9zIGRlIGhldGVyb2NlZGFzdGljaWRhZCBhbnRlIGxvIGN1YWwgc2UgZGViZSBjb25zaWRlcmFyIHRyYW5zZm9ybWFjaW9uZXMgcGFyYSBtZWpvcmFyIGxhIGVzdGFiaWxpZGFkIGRlIGxhIHNlcmllLg0KDQpgYGB7cn0NCiNQPTAsIEQ9MSwgUT0wDQphcmltYV9tZXRhIDwtIGFyaW1hKHRzX21ldGEsIG9yZGVyPWMoMCwxLDApKSAjcGRxDQphcmltYV9tZXRhJGFpYw0KDQpiaWNfbWV0YSA8LSBhcmltYV9tZXRhJGFpYyArIGxvZyhsZW5ndGgoZGYpKSAqIChsZW5ndGgoYXJpbWFfbWV0YSRjb2VmKSAtIDEpDQpwcmludChiaWNfbWV0YSkNCg0KY2hlY2tyZXNpZHVhbHMoYXJpbWFfbWV0YSkNCg0KcHJpbnQoIkNvZWZpY2llbnRlcyBkZWwgbW9kZWxvIEFSSU1BICgwLDEsMCk6IikNCnByaW50KGFyaW1hX21ldGEkY29lZikNCmBgYA0KDQoNCiMjIE1vZGVsbyAyIC0gQVJJTUEoOSwxLDApIA0KDQoqICpFdmFsdWFjacOzbiBkZSBsb3MgUmVzaWR1YWxlcyBlbiBlbCBUaWVtcG86KiBFbCBncsOhZmljbyAgbXVlc3RyYSBxdWUgbG9zIHJlc2lkdWFsZXMgc2lndWVuIGNlbnRyYWRvcyBlbiB0b3JubyBhIGNlcm8sIHBlcm8gcGVyc2lzdGVuIHZhbG9yZXMgYXTDrXBpY29zIHkgdW5hIHBvc2libGUgaGV0ZXJvY2VkYXN0aWNpZGFkLiBFbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBBUklNQSgwLDEsMCksIGxhIGRpc3BlcnNpw7NuIGRlIGxvcyByZXNpZHVhbGVzIG5vIHBhcmVjZSBoYWJlciBtZWpvcmFkbyBzaWduaWZpY2F0aXZhbWVudGUsIGxvIHF1ZSBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gbm8gaGEgcmVkdWNpZG8gY29uc2lkZXJhYmxlbWVudGUgbG9zIGVycm9yZXMuDQoNCiogKkZ1bmNpw7NuIGRlIEF1dG9jb3JyZWxhY2nDs24gZGUgbG9zIFJlc2lkdWFsZXM6KiAgU2Ugb2JzZXJ2YSBxdWUgbGEgYXV0b2NvcnJlbGFjacOzbiBzaWd1ZSBwcmVzZW50ZSBlbiB2YXJpb3MgcmV6YWdvcy4gQXVucXVlIGVsIG1vZGVsbyBBUklNQSg5LDEsMCkgaW5jb3Jwb3JhIG3DoXMgdMOpcm1pbm9zIGF1dG9ycmVncmVzaXZvcywgbG9zIHJlc2lkdWFsZXMgYcO6biBtdWVzdHJhbiBkZXBlbmRlbmNpYSB0ZW1wb3JhbCwgcG9yIGVuZGUsIGVsIG1vZGVsbyBubyBoYSBlbGltaW5hZG8gcG9yIGNvbXBsZXRvIGxvcyBwYXRyb25lcyBlbiBsb3MgZGF0b3MuDQoNCiogKkRpc3RyaWJ1Y2nDs24gZGUgbG9zIFJlc2lkdWFsZXM6KiBMb3MgcmVzaWR1YWxlcyBzaWd1ZW4gdW5hIGRpc3RyaWJ1Y2nDs24gY29uIGNvbGFzIG3DoXMgcGVzYWRhcyBxdWUgbGEgbm9ybWFsLCBzaW1pbGFyIGFsIG1vZGVsbyBhbnRlcmlvci4gUG9yIGxvIHRhbnRvLCBsb3MgZXJyb3JlcyBleHRyZW1vcyBzaWd1ZW4gb2N1cnJpZW5kbyBjb24gbWF5b3IgZnJlY3VlbmNpYSBkZSBsbyBlc3BlcmFkbywgbG8gcXVlIHB1ZWRlIGFmZWN0YXIgbGEgZXN0YWJpbGlkYWQgZGUgbGFzIHByZWRpY2Npb25lcy4NCg0KKiAqUHJ1ZWJhIGRlIExqdW5nLUJveDoqIEVsIHAtdmFsdWUgZGUgbGEgcHJ1ZWJhIGRlIExqdW5nLUJveCAoNy4xMDVl4oiSMTUpIHNpZ3VlIHNpZW5kbyBleHRyZW1hZGFtZW50ZSBiYWpvLCBjb25maXJtYW5kbyBxdWUgbG9zIHJlc2lkdWFsZXMgbm8gc29uIHJ1aWRvIGJsYW5jbyB5IHF1ZSBoYXkgZGVwZW5kZW5jaWEgbm8gY2FwdHVyYWRhLg0KDQoNCkVsIG1vZGVsbyBBUklNQSg5LDEsMCkgbm8gaGEgbWVqb3JhZG8gc2lnbmlmaWNhdGl2YW1lbnRlIGVsIGFqdXN0ZSBlbiBjb21wYXJhY2nDs24gY29uIEFSSU1BKDAsMSwwKS4gUG9yIGxvIHRhbnRvLCBlbCBtb2RlbG8gZXMgYnVlbm8gcGVybyBubyBsbyBzdWZpY2llbnRlIHBhcmEgbWVqb3JhciBoZXRlcm9jZWRhc3RpY2lkYWQgeSBlc3RhYmlsaWRhZCBkZSBsYSBzZXJpZS4NCg0KYGBge3J9DQojUD05LCBEPTEsIFE9MA0KYXJpbWFfbWV0YTIgPC0gYXJpbWEodHNfbWV0YSwgb3JkZXI9Yyg5LDEsMCkpDQphcmltYV9tZXRhMiRhaWMNCg0KYmljX21ldGEyIDwtIGFyaW1hX21ldGEyJGFpYyArIGxvZyhsZW5ndGgoZGYpKSAqIChsZW5ndGgoYXJpbWFfbWV0YTIkY29lZikgLSAxKQ0KcHJpbnQoYmljX21ldGEyKQ0KDQpjaGVja3Jlc2lkdWFscyhhcmltYV9tZXRhMikNCg0KcHJpbnQoIkNvZWZpY2llbnRlcyBkZWwgbW9kZWxvIEFSSU1BICg5LDEsMCk6IikNCnByaW50KGFyaW1hX21ldGEyJGNvZWYpDQpgYGANCg0KIyMgTW9kZWxvIDMgLSBBUklNQSgwLDEsMSkgDQoNCkVsIHByZXNlbnRlIG1vZGVsbyBzZSByZWFsaXrDsyB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIEF1dG9BUklNQSBjb24gZWwgZmluIGRlIHZlcmlmaWNhciBsYSB0ZW5kZW5jaWEsIGxhIGVzdGFjaW9uYWxpZGFkIHkgcG9zaWJsZXMgcGF0cm9uZXMgZW4gbG9zIGRhdG9zOyBhc8OtIGNvbW8gZWwgY29tcG9ydGFtaWVudG8gZGUgbGEgc2VyaWUgdGVtcG9yYWwgZW4gY29tcGFyYWNpw7NuIGNvbiBsb3MgdmFsb3JlcyBkZSBwLCBkIHkgcSBkZSBsb3MgZG9zIG1vZGVsb3MgYW50ZXJpb3JlcywgdGFtYmnDqW4gZ2VuZXJhZG9zIG1hbnVhbG1lbnRlLiANCg0KKiAqRXZhbHVhY2nDs24gZGUgbG9zIFJlc2lkdWFsZXMgZW4gZWwgVGllbXBvOiogTG9zIHJlc2lkdWFsZXMgZXN0w6FuIGNlbnRyYWRvcyBlbiB0b3JubyBhIGNlcm8sIHBlcm8gY29uIGFsZ3Vub3MgdmFsb3JlcyBhdMOtcGljb3Mgc2lnbmlmaWNhdGl2b3MsIHNpbWlsYXJlcyBhIGxvcyBvYnNlcnZhZG9zIGVuIG1vZGVsb3MgcHJldmlvcy4gQXVucXVlIGxhIGRpc3BlcnNpw7NuIGRlIGxvcyBlcnJvcmVzIG5vIHBhcmVjZSBoYWJlciBhdW1lbnRhZG8gZHLDoXN0aWNhbWVudGUsIHNpZ3VlIGhhYmllbmRvIHBpY29zIHF1ZSBwdWVkZW4gaW1wYWN0YXIgbGEgcHJlY2lzacOzbiBkZWwgbW9kZWxvLg0KDQoqICpGdW5jacOzbiBkZSBBdXRvY29ycmVsYWNpw7NuIGRlIGxvcyBSZXNpZHVhbGVzOiogTGEgQUNGIG11ZXN0cmEgcXVlIGxhIG1heW9yw61hIGRlIGxvcyByZXphZ29zIGNhZW4gZGVudHJvIGRlIGxvcyBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSAobMOtbmVhcyBhenVsZXMpLCBsbyBxdWUgaW5kaWNhIHVuYSByZWR1Y2Npw7NuIGVuIGxhIGF1dG9jb3JyZWxhY2nDs24gcmVzcGVjdG8gYSBtb2RlbG9zIGFudGVyaW9yZXMuIFNpbiBlbWJhcmdvLCBhw7puIHBlcnNpc3RlbiBhbGd1bm9zIHZhbG9yZXMgZnVlcmEgZGVsIHJhbmdvIGVzcGVyYWRvLCBzdWdpcmllbmRvIHF1ZSBsYSBlc3RydWN0dXJhIGRlbCBtb2RlbG8gcG9kcsOtYSBtZWpvcmFyc2UuDQoNCiogKkRpc3RyaWJ1Y2nDs24gZGUgbG9zIFJlc2lkdWFsZXM6KiBNdWVzdHJhIHVuYSBkaXN0cmlidWNpw7NuIHNlc2dhZGEgY29uIGNvbGFzIG3DoXMgcGVzYWRhcyBxdWUgbGEgbm9ybWFsLiBFc3RvIGluZGljYSBxdWUgbG9zIGVycm9yZXMgZXh0cmVtb3Mgb2N1cnJlbiBjb24gbWF5b3IgZnJlY3VlbmNpYSBkZSBsbyBlc3BlcmFkbywgbG8gcXVlIHBvZHLDrWEgYWZlY3RhciBsYSByb2J1c3RleiBkZSBsYXMgcHJlZGljY2lvbmVzLg0KDQoqICpQcnVlYmEgZGUgTGp1bmctQm94OiogRWwgcC12YWx1ZSBkZSBsYSBwcnVlYmEgZGUgTGp1bmctQm94ICg4Ljc3MWXiiJIxNSkgc2lndWUgc2llbmRvIGJham8sIGxvIHF1ZSBpbmRpY2EgcXVlIGxvcyByZXNpZHVhbGVzIGHDum4gcHJlc2VudGFuIGF1dG9jb3JyZWxhY2nDs24geSBubyBzZSBjb21wb3J0YW4gY29tcGxldGFtZW50ZSBjb21vIHJ1aWRvIGJsYW5jby4NCg0KRWwgbW9kZWxvIEFSSU1BKDAsMSwxKSBtdWVzdHJhIHVuYSBsaWdlcmEgbWVqb3JhIGVuIGNvbXBhcmFjacOzbiBjb24gbW9kZWxvcyBhbnRlcmlvcmVzLCBjb24gbWVub3IgYXV0b2NvcnJlbGFjacOzbiBlbiBsb3MgcmVzaWR1YWxlcy4gU2luIGVtYmFyZ28sIGxhIHByZXNlbmNpYSBkZSB2YWxvcmVzIGF0w61waWNvcyB5IGNvbGFzIHBlc2FkYXMgc3VnaWVyZSBxdWUgcG9kcsOtYW4gZXhwbG9yYXJzZSBtb2RlbG9zIGFsdGVybmF0aXZvcyBjb21vIFNBUklNQSBvIG1vZGVsb3MgaMOtYnJpZG9zIGNvbiBNTCBwYXJhIG1lam9yYXIgbGEgcHJlY2lzacOzbiB5IHJvYnVzdGV6IGRlIGxhcyBwcmVkaWNjaW9uZXMuDQoNCmBgYHtyfQ0KIyBhdXRvLmFyaW1hKFkpDQphdXRvX21ldGEgPC0gYXV0by5hcmltYSh0c19tZXRhKSAjKDAsMSwxKQ0KYXV0b19tZXRhJGFpYw0KDQpiaWNfYXV0byA8LSBhdXRvX21ldGEkYWljICsgbG9nKGxlbmd0aChkZikpICogKGxlbmd0aChhdXRvX21ldGEkY29lZikgLSAxKQ0KcHJpbnQoYmljX2F1dG8pDQoNCmNoZWNrcmVzaWR1YWxzKGF1dG9fbWV0YSkNCg0KcHJpbnQoIkNvZWZpY2llbnRlcyBkZWwgbW9kZWxvIEFSSU1BICgwLDEsMSk6IikNCnByaW50KGF1dG9fbWV0YSRjb2VmKQ0KYXV0b19tZXRhDQpgYGANCg0KDQojIyBNb2RlbG8gc2VsZWNjaW9uYWRvDQpMYSBzZWxlY2Npw7NuIGRlbCBtb2RlbG8gQVJJTUEoMCwxLDApIGNvbiB1biBBSUMgZGUgMTg5NDguODIgc2UganVzdGlmaWNhIHBvciB2YXJpYXMgcmF6b25lcywgYSBwZXNhciBkZSBxdWUgbG9zIG1vZGVsb3MgQVJJTUEoOSwxLDApIGNvbiB1biBBSUMgZGUgMTg5NTIuMDMgeSBBUklNQSgwLDEsMSkgY29uIHVuIEFJQyBkZSAxODk0NC4yNSB0aWVuZW4gQUlDcyBsaWdlcmFtZW50ZSBtw6FzIGFsdG9zIG8gbcOhcyBiYWpvcywgcmVzcGVjdGl2YW1lbnRlLg0KDQoqIFNpbXBsaWNpZGFkIGRlbCBNb2RlbG86IEVsIG1vZGVsbyBBUklNQSgwLDEsMCkgZXMgZWwgbcOhcyBzaW1wbGUgeSwgcG9yIGxvIHRhbnRvLCBtw6FzIGludGVycHJldGF0aXZvLlNlZ8O6biwgbGEgcmVnbGEgZGUgcGFyc2ltb255IHNlIHN1Z2llcmUgcXVlLCBjdWFuZG8gbG9zIG1vZGVsb3MgdGllbmVuIHVuIHJlbmRpbWllbnRvIHNpbWlsYXIsIGVzIHByZWZlcmlibGUgc2VsZWNjaW9uYXIgZWwgbcOhcyBzaW1wbGUsIHlhIHF1ZSBtaW5pbWl6YSBlbCByaWVzZ28gZGUgc29icmVhanVzdGUgKG92ZXJmaXR0aW5nKS4gVW4gbW9kZWxvIG3DoXMgY29tcGxlam8gcHVlZGUgYWp1c3RhcnNlIGV4Y2VzaXZhbWVudGUgYSBsb3MgcnVpZG9zIG8gdmFyaWFjaW9uZXMgYWxlYXRvcmlhcyBlbiBsb3MgZGF0b3MsIGxvIGN1YWwgcHVlZGUgcmVzdWx0YXIgZW4gdW4gcGVvciBkZXNlbXBlw7FvIHByZWRpY3Rpdm8gYSBsYXJnbyBwbGF6by4NCg0KKiBMZXZlIGRpZmVyZW5jaWEgZW4gQUlDOiBBdW5xdWUgZWwgQUlDIGRlIGxvcyBtb2RlbG9zIEFSSU1BKDksMSwwKSB5IEFSSU1BKDAsMSwxKSBlcyBsaWdlcmFtZW50ZSBtw6FzIGFsdG8gcXVlIGVsIGRlIEFSSU1BKDAsMSwwKSwgbGFzIGRpZmVyZW5jaWFzIGVuIGxvcyB2YWxvcmVzIGRlbCBBSUMgc29uIG11eSBwZXF1ZcOxYXMuIEVuIGVzdGUgY2FzbywgbGEgZGlmZXJlbmNpYSBlbiBBSUMgZW50cmUgbG9zIHRyZXMgbW9kZWxvcyBlcyBkZSBzb2xvIDQgcHVudG9zLCBsbyBxdWUgc3VnaWVyZSBxdWUgbm8gaGF5IHVuYSBtZWpvcmEgc2lnbmlmaWNhdGl2YSBlbiBlbCBhanVzdGUgZGVsIG1vZGVsbyBjb24gbW9kZWxvcyBtw6FzIGNvbXBsZWpvcy4gDQoNCiogQ29tcG9ydGFtaWVudG8gZGUgbG9zIFBhcsOhbWV0cm9zOiBFbCBtb2RlbG8gQVJJTUEoMCwxLDApIGVzIGVsIHF1ZSBwcmVzZW50YSBsb3MgcGFyw6FtZXRyb3MgbcOhcyBzZW5jaWxsb3MgeSBubyBpbmNsdXllIHTDqXJtaW5vcyBkZSBhdXRvcnJlZ3Jlc2nDs24gbmkgZGUgbWVkaWEgbcOzdmlsLCBsbyBjdWFsIGVzIGFkZWN1YWRvIGN1YW5kbyBsb3MgZGF0b3MgbXVlc3RyYW4gdW5hIHRlbmRlbmNpYSBhIHNlciBlc3RhY2lvbmFyaW9zIGVuIGxhIHByaW1lcmEgZGlmZXJlbmNpYSB5IG5vIHJlcXVpZXJlbiBhanVzdGVzIGFkaWNpb25hbGVzIGRlIGNvbXBsZWppZGFkIHBhcmEgY2FwdHVyYXIgcGF0cm9uZXMgZXN0YWNpb25hbGVzIG8gZGVwZW5kZW5jaWFzIG3DoXMgY29tcGxlamFzLiANCg0KDQpFbiBjb25jbHVzacOzbiwgZWwgbW9kZWxvIEFSSU1BKDAsMSwwKSBlcyBlbCBtw6FzIGFkZWN1YWRvIGRlYmlkbyBhIHN1IHNpbXBsaWNpZGFkLCBsYSBtw61uaW1hIGRpZmVyZW5jaWEgZW4gZWwgQUlDIGNvbiByZXNwZWN0byBhIGxvcyBvdHJvcyBtb2RlbG9zIHkgc3UgY2FwYWNpZGFkIHBhcmEgZ2VuZXJhbGl6YXIgc2luIHNvYnJlYWp1c3RhcnNlIGEgbG9zIGRhdG9zLg0KDQoNCiMgKipQYXNvIDU6KiogUHJveWVjY2lvbmVzDQoNCkNvbiBiYXNlIGFsIG1vZGVsbyBzZWxlY2Npb25hZG8gZGUgQVJJTUEoMCwxLDApIGEgY2F1c2EgZGUgc3Ugc2ltcGxpY2lkYWQgeSBwb2NhIGRpZmVyZW5jaWEgZW4gcmVsYWNpw7NuIGFsIHZhbG9yIGRlIEFJQywgc2UgcmVhbGl6YXJvbiBsb3Mgc2lndWllbnRlcyBlc2NlbmFyaW9zIGEgZnV0dXJvLg0KDQojIyBQcm9uw7NzdGljb3MgcGFyYSBwcsOzeGltb3MgZG9zIGHDsW9zDQoNClNlIGdlbmVyYXJvbiBwcm95ZWNjaW9uZXMgcGFyYSBsb3MgcHLDs3hpbW9zIGRvcyBhw7FvcywgY29uIGZyZWN1ZW5jaWEgZGlhcmlhLiBFbCByYW5nbyBkZSBmZWNoYXMgZXMgZGVsIGTDrWEgaMOhYmlsIG7Dum1lcm8gZGUgMzUgZGVsIDIwMjUgYWwgZMOtYSA4IGRlbCAyMDI4Lg0KYGBge3J9DQpoIDwtIDczMCANCg0KIyBHZW5lcmFyIHByZWRpY2Npb25lcw0KcHJlZHMgPC0gcHJlZGljdChhcmltYV9tZXRhLCBuLmFoZWFkPWgpDQoNCiMgT2J0ZW5lciBpbmljaW8geSBmaW4gZGUgbGEgcHJlZGljY2nDs24NCnN0YXJ0KHByZWRzJHByZWQpDQplbmQocHJlZHMkcHJlZCkNCg0KIyBHcmFmaWNhciBwcmVkaWNjaW9uZXMNCnBsb3QudHMoY2JpbmQodHNfbWV0YSwgcHJlZHMkcHJlZCksIGx0eT1jKDEsMyksIGNvbD1jKCJibGFjayIsICJibHVlIiksIG1haW49IlByb3llY2Npw7NuIEFSSU1BKDAsMSwwKSIpDQpgYGANCg0KVmlzdWFsaXphbW9zIGFtYmFzIHNlcmllcyBkZSB0aWVtcG8sIGVuIGxhIHBhcnRlIHN1cGVyaW9yIHkgbGEgcHJveWVjY2nDs24gZW4gbGEgcGFydGUgYmFqYS4gDQoNCmBgYHtyfQ0KIyBTaW11bGFjacOzbiBkZSBwcm9uw7NzdGljb3MgY29uIHJ1aWRvDQpwcm95cyA8LSBwcmVkcyRwcmVkICsgcm5vcm0oaCwgMCwgc3FydChhcmltYV9tZXRhJHNpZ21hMikpDQp0cy5wbG90KGNiaW5kKHRhaWwodHNfbWV0YSwgMTY5KSwgcHJveXMpLCBsdHk9YygxLDMpLCBjb2w9YygiYmxhY2siLCAiYmx1ZSIpKQ0KYGBgDQoNCkdlbmVyYW1vcyB1bmEgc2ltdWxhY2nDs24gZGUgbGFzIHByZWRpY2Npb25lcyBjb24gcnVpZG8uIFNlIGdlbmVyYXJvbiA3MzAgdmFsb3JlcyBhbGVhdG9yaW9zIGNvbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgY29uIG1lZGlhIDAgeSB1dGlsaXphbmRvIGNvbW8gZGVzdmlhY2nDs24gZXN0w6FuZGFyLCBsYSB2YXJpYW56YSBkZWwgZXJyb3IgZGVsIG1vZGVsby4gWSBzZSBzdW1hIGEgbGEgcHJlZGljY2nDs24gcGFyYSBzaW11bGFyIGxhIGluY2VydGlkdW1icmUgZW4gZWwgcHJvbsOzc3RpY29zLiBEZSBlc3RhIG1hbmVyYSBubyB0ZW5lbW9zIHNvbGFtZW50ZSBsYSBwcmVkaWNjacOzbiBzdWF2aXphZGEsIHNpbm8gdW5hIHByb3llY2Npw7NuIHF1ZSB0b21hIGVuIGN1ZW50YSBtw6FzIGRlIGxhIGluY2VydGlkdW1icmUuDQoNCmBgYHtyfQ0KIyBVc2FuZG8gZm9yZWNhc3QgcGFyYSBwcm9uw7NzdGljb3MgeSBncmFmaWNhY2nDs24NCnByb25zIDwtIGZvcmVjYXN0Ojpmb3JlY2FzdChhcmltYV9tZXRhLCBsZXZlbD05MCwgaD1oKQ0KcGxvdChwcm9ucywgbWFpbj0iUHJvbsOzc3RpY29zIEFSSU1BIHBhcmEgMiBhw7FvcyIpDQpgYGANCg0KDQojIyBQcm9uw7NzdGljb3MgcGFyYSBwcsOzeGltb3MgZG9zIGHDsW9zIGNvbiBlc2NlbmFyaW8gb3B0aW1pc3RhIHkgcGVzaW1pc3RhIChpbnRlcnZhbG9zKQ0KDQpUYW1iacOpbiwgc2UgcHJlc2VudGEgbGEgcHJveWVjY2nDs24gY29uIGludGVydmFsb3MgZGUgZXNjZW5hcmlvcyBvcHRpbWlzdGFzIHkgcGVzaW1pc3RhcywgdXRpbGl6YW5kbyB1biBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlIDkwJS4gRWwgZXNjZW5hcmlvIHBlc2ltaXN0YSBzaWVuZG8gZWwgbMOtbWl0ZSBpbmZlcmlvciBkZWwgaW50ZXJ2YWxvIHkgZWwgZXNjZW5hcmlvIG9wdGltaXN0YSBzaWVuZG8gZWwgbMOtbWl0ZSBzdXBlcmlvciwgZW4gZWwgY3VhbCBzZSBvYnNlcnZhIHF1ZSAgZWwgY29tcG9ydGFtaWVudG8gZGVsIEVzY2VuYXJpb19SZWFsLCBxdWUgc2UgbWFudGllbmUgY29uc3RhbnRlIGVuIDY1Ny42NTQ5IGVuIHRvZG9zIGxvcyBwZXJpb2Rvcywgc2UgZGViZSBhIGxhIGVzdHJ1Y3R1cmEgZGVsIG1vZGVsbyBBUklNQSgwLDEsMCkuIERpY2hvIG1vZGVsbyBlcyBlcXVpdmFsZW50ZSBhIHVuIHJhbmRvbSB3YWxrIChjYW1pbmF0YSBhbGVhdG9yaWEpLCBsbyBxdWUgaW1wbGljYSBxdWUgbGEgbWVqb3IgZXN0aW1hY2nDs24gZGUgbGEgc2lndWllbnRlIG9ic2VydmFjacOzbiBlcyBzaW1wbGVtZW50ZSBlbCDDumx0aW1vIHZhbG9yIG9ic2VydmFkby4NCiAgIA0KYGBge3J9DQojIEdlbmVyYXIgcHJlZGljY2lvbmVzIGNvbiBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YQ0KcHJvbnMgPC0gZm9yZWNhc3Q6OmZvcmVjYXN0KGFyaW1hX21ldGEsIGxldmVsPTkwLCBoPWgpDQoNCiMgQ3JlYXIgdW4gZGF0YSBmcmFtZSBjb24gbG9zIGVzY2VuYXJpb3MNCmVzY2VuYXJpb3NfZGYgPC0gZGF0YS5mcmFtZSgNCiAgUGVyaW9kbyA9IDE6aCwNCiAgRXNjZW5hcmlvX1Blc2ltaXN0YSA9IHByb25zJGxvd2VyWywxXSwgICMgTMOtbWl0ZSBpbmZlcmlvcg0KICBFc2NlbmFyaW9fUmVhbCA9IHByb25zJG1lYW4sICAgICAgICAgICAgIyBQcmVkaWNjacOzbiBjZW50cmFsDQogIEVzY2VuYXJpb19PcHRpbW8gPSBwcm9ucyR1cHBlclssMV0gICAgICAjIEzDrW1pdGUgc3VwZXJpb3INCikNCg0KIyBJbXByaW1pciBsb3MgZXNjZW5hcmlvcw0KaGVhZChlc2NlbmFyaW9zX2RmKQ0KDQojIEdyYWZpY2FyIGxvcyBlc2NlbmFyaW9zDQpnZ3Bsb3QoZXNjZW5hcmlvc19kZiwgYWVzKHggPSBQZXJpb2RvKSkgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBFc2NlbmFyaW9fUGVzaW1pc3RhLCBjb2xvciA9ICJQZXNpbWlzdGEiKSwgc2l6ZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gRXNjZW5hcmlvX1JlYWwsIGNvbG9yID0gIlJlYWwiKSwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gRXNjZW5hcmlvX09wdGltbywgY29sb3IgPSAiw5NwdGltbyIpLCBzaXplID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKw0KICBsYWJzKHRpdGxlID0gIkVzY2VuYXJpb3MgZGUgUHJlZGljY2nDs24gQVJJTUEoMCwxLDApIiwNCiAgICAgICB4ID0gIlBlcmlvZG8iLCB5ID0gIlZhbG9yIFByZWRpY2hvIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiUGVzaW1pc3RhIiA9ICJyZWQiLCAiUmVhbCIgPSAiYmx1ZSIsICLDk3B0aW1vIiA9ICJncmVlbiIpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQoNCiMgQmFuZGFzIGRlIGNvbmZpYW56YQ0KbG93YmFuZCA8LSBwcmVkcyRwcmVkIC0gMS42NSAqIHByZWRzJHNlDQp1cGJhbmQgPC0gcHJlZHMkcHJlZCArIDEuNjUgKiBwcmVkcyRzZQ0KDQp0cy5wbG90KGNiaW5kKHRzX21ldGEsIHByZWRzJHByZWQsIGxvd2JhbmQsIHVwYmFuZCksIGx0eT1jKDEsMywzLDMpLCBjb2w9YygiYmxhY2siLCAiYmx1ZSIsICJyZWQiLCAicmVkIiksIG1haW49IlByZWRpY2Npw7NuIGNvbiBJbnRlcnZhbG9zIGRlIENvbmZpYW56YSIpDQp0cy5wbG90KGNiaW5kKHRhaWwodHNfbWV0YSwgMTY5KSwgcHJlZHMkcHJlZCwgbG93YmFuZCwgdXBiYW5kKSwgbHR5PWMoMSwzLDMsMyksIGNvbD1jKCJibGFjayIsICJibHVlIiwgInJlZCIsICJyZWQiKSwgbWFpbj0iUHJlZGljY2nDs24gY29uIEludGVydmFsb3MgZGUgQ29uZmlhbnphIChab29tKSIpDQpgYGANCg0KIyBDb25jbHVzaW9uZXMNCkVuIGNvbmNsdXNpw7NuLCBkYWRvIHF1ZSBudWVzdHJvIG1vZGVsbyBBUklNQSgwLDEsMCkgc2lndWUgdW4gY29tcG9ydGFtaWVudG8gZGUgcmFuZG9tIHdhbGssIGxhIHByb3llY2Npw7NuIGRlbCBwcmVjaW8gZGUgbGFzIGFjY2lvbmVzIGRlIE1ldGEgc2UgcmVwcmVzZW50YSBjb21vIHVuYSBsw61uZWEgcmVjdGEsIGxvIHF1ZSByZWZsZWphIHN1IGltcHJlZGVjaWJpbGlkYWQgYSBsYXJnbyBwbGF6by4NCg0KTGEgbWV0b2RvbG9nw61hIEJveC1KZW5raW5zIHBlcm1pdGnDsyBjYXB0dXJhciBwYXRyb25lcyBoaXN0w7NyaWNvcyB5IGdlbmVyYXIgcHJvbsOzc3RpY29zIGJhc2Fkb3MgZW4gdGVuZGVuY2lhcyBwYXNhZGFzLCBpbmNvcnBvcmFuZG8gdW4gbWFyZ2VuIGRlIGluY2VydGlkdW1icmUgbWVkaWFudGUgcnVpZG8gYWxlYXRvcmlvIHkgYmFuZGFzIGRlIGNvbmZpYW56YS4gU2luIGVtYmFyZ28sIGRhZG8gcXVlIGVzdGUgZW5mb3F1ZSBzZSBiYXNhIMO6bmljYW1lbnRlIGVuIGRhdG9zIHBhc2Fkb3MsIHJlc2FsdGFtb3MgbGEgaW1wb3J0YW5jaWEgZGUgY29tcGxlbWVudGFybG8gY29uIG90cm9zIG3DqXRvZG9zIGRlIGFuw6FsaXNpcywgY29tbyBlbCBhbsOhbGlzaXMgZnVuZGFtZW50YWwgeSBlbCBlc3R1ZGlvIGRlIGZhY3RvcmVzIG1hY3JvZWNvbsOzbWljb3MsIHBhcmEgbWVqb3JhciBsYSBwcmVjaXNpw7NuIGVuIGxhIHRvbWEgZGUgZGVjaXNpb25lcyB5IG9idGVuZXIgdW5hIHZpc2nDs24gbcOhcyBjb21wbGV0YSBkZWwgY29tcG9ydGFtaWVudG8gZnV0dXJvIGRlIGxhIGFjY2nDs24uDQo=