Contexto

Hershey’s México empresa chocolatera con más de 100 años de historia a nivel global (fundación 1903) y establecida en México desde 1969, como una de confitería entre Hershey Food Corporation y Anderson Clayton & Co. S.A. formando Nacional de Dulces S.A. de C.V. en el Distrito Federal y después de 12 años cambiando sus instalaciones a El Salto, Jalisco e iniciando operaciones en el mes de febrero de 1981.

En 2022 Hershey´s México se consolidó como una de las empresas chocolateras del país, y con más fuerza en la venta de sus lechitas y ha sumado esfuerzos para que a pesar de la pandemia de la Covid-19 ofrezca el mejor y disponibilidad de productos a sus clientes.

Hershey México comercializa más de 20 marcas, entre éstas: Kisses, Reeses, Pelón Pelo Rico, Chocoyogo, entre otras. Incluye dentro de su portafolio de productos la leche saborizada, conocida coloquialmente como las lechitas de Hershey´s. Ante el crecimiento experimentado entre el año 2017 y 2019 Hershey´s tiene que reaccionar a las necesidades del abasto y evitar que no falte su en los anaqueles. Aunque Hershey´s ha crecido en participación de mercado durante este periodo en la categoría, se han presentado problemas de abasto de sus productos, en concreto, ha habido demanda no satisfecha y la compañía desea maximizar su y aprovechar las oportunidades mediante una mejor proyección de sus ventas.

La compañía ha definido como una de sus principales estrategias mejorar el nivel de servicio al cliente, esto quiere decir, entregar en tiempo y forma sus productos, es decir reducir al mínimo la falta de disponibilidad, esto es posible con modelos adecuados de planificación (Gil, et al, 2020).

Para esto se tiene que trabajar con enfoque en la estimación de la demanda de la compañía a nivel nacional y sus principales regiones (Guadalajara, CDMX, Monterrey y Tijuana). Estimar la demanda es un proceso complejo que merece la pena ejecutarlo de la mejor manera (Rodríguez, 2021), ese es precisamente el planteamiento del problema. La alternativa es realizar proyecciones con datos históricos aplicando herramientas econométricas, que permitan predecir con menor margen de error las ventas (Zhao, et al, 2007), en concreto el objetivo general es modelar las ventas obtener un pronóstico estadístico de la demanda para mejorar la disponibilidad en el futuro de los productos de Hershey´s particularmente las leches saborizadas, ya que se considera un nicho de mercado que Hershey ha capitalizado muy bien desde hace años. Se trata de solucionar una problemática real del sector de leches saborizadas en .

Para proceder a proporcionar una proyección estadística de la venta de la leche saborizada Hershey´s México en valor monetario (miles de dólares) a través de modelos de series de tiempo (ARIMA, SARIMA, etc.) , se deben realizar pruebas de la construcción del modelo con los datos de la serie de tiempo o datos de sección cruzada. Adicionalmente se pueden tomar otras variables y datos a nivel mundial con datos primarios y secundarios. Con respecto a las herramientas computacionales de analítica de datos en este caso usaremos el lenguaje de R.

Con la modelación adecuada de las ventas de Lechitas se tomará la decisión de planificarlo y producirlo según las proyecciones estadísticas. Esto ha demostrado en muchos corporativos que mejora la eficiencia, productividad y eleva el nivel de servicio (Min, et al. 2008).

Exploración y creación

Importación de base de datos

Se utiliza la función read_excel para importar los datos históricos de ventas.

Las ventas de 2017 a 2019 graficadas se muestran a continuación:

ggplot(bd, aes(x=Mes,y=Ventas)) + 
  geom_line() +
  geom_point() +
  xlab('Tiempo') +
  ylab('Ventas (en miles de USD)') +
  ggtitle('Ventas de leche saborizada de 2017 a 2019')

Creación de serie de tiempo

hersheys_ts <- ts(data=bd$Ventas,start=c(2017,1),frequency=12)
hersheys_ts
##           Jan      Feb      Mar      Apr      May      Jun      Jul      Aug
## 2017 25520.51 23740.11 26253.58 25868.43 27072.87 27150.50 27067.10 28145.25
## 2018 28463.69 26996.11 29768.20 29292.51 29950.68 30099.17 30851.26 32271.76
## 2019 32496.44 31287.28 33376.02 32949.77 34004.11 33757.89 32927.30 34324.12
##           Sep      Oct      Nov      Dec
## 2017 27546.29 28400.37 27441.98 27852.47
## 2018 31940.74 32995.93 32197.12 31984.82
## 2019 35151.28 36133.07 34799.91 34846.17
plot(hersheys_ts, main = 'Serie de tiempo de ventas de leche saborizada de 2017 a 2019', xlab = 'Tiempo', ylab = 'Ventas (en miles de USD)')

Preguntas a responder

1.- Utilizando modelos ARIMA (Box-Jenkins, ARMA, SARIMA) y los datos históricos de las ventas de leche saborizada ¿Cuál es el modelo que mejor se adapta a la serie?

SARIMA

h_sarima <- arima(hersheys_ts, order=c(1,1,2), seasonal=c(1,1,1)) #sarima modificado manualmente para encontrar el menor error
h_sarima # Justificar con el AIC
## 
## Call:
## arima(x = hersheys_ts, order = c(1, 1, 2), seasonal = c(1, 1, 1))
## 
## Coefficients:
##          ar1     ma1      ma2    sar1     sma1
##       0.1491  0.2688  -0.7311  0.0979  -0.9413
## s.e.  0.3721  0.4195   0.3687  0.6206   4.8694
## 
## sigma^2 estimated as 98894:  log likelihood = -171.55,  aic = 355.1

El criterio de información de Akaike (AIC) es una medida ampliamente utilizada para modelos estadísticos. Básicamente cuantifica la bondad de ajuste y la simplicidad/parsimonia del modelo en una sola estadística. Al comparar dos modelos, el que tiene el AIC más bajo es generalmente “mejor” (Keshvani, 2013).

Conseguir el AIC más bajo se hicieron cambios los modelos y de los parametros manualmente, hasta llegar a una combinación favorable.

2.- ¿Qué modelo de regresión ofrece mejor exactitud predictiva?

regresion <- lm(Ventas ~ Mes, data=bd) #regresion lineal simple
summary(regresion)
## 
## Call:
## lm(formula = Ventas ~ Mes, data = bd)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2089.63  -331.48    40.99   466.38  1536.91 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -1.432e+05  7.573e+03  -18.90   <2e-16 ***
## Mes          1.135e-04  4.952e-06   22.92   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 811.1 on 34 degrees of freedom
## Multiple R-squared:  0.9392, Adjusted R-squared:  0.9374 
## F-statistic: 525.4 on 1 and 34 DF,  p-value: < 2.2e-16

El modelo de regresión escogido fue el de regresión lineal simple. Podemos decir que es un buen modelo por el resultado de la R-squared.La R-squared muestra qué tan bien se ajusta el modelo a los datos reales. Toma la forma de una proporción de la varianza, siendo una medida de la relación lineal entre nuestra variable de predicción y nuestra variable de respuesta/objetivo (Rego, 2015). En nuestro caso, podemos decir que aproximadamente el 93% de la varianza encontrada en la variable de respuesta puede explicarse por la variable predictora. Igual con un p-value menor a 0.05 podemos decir que es una respuesta significativa.

3.-Según su mejor modelo ¿Cuál es la proyección de ventas en valor monetario para el siguiente a total de Hershey´s?

pronostico <- forecast(h_sarima, level = c(95), h = 12) #Pronostico de los siguientes 12 meses
accuracy(pronostico) # Justificar con el MAPE
##                    ME     RMSE      MAE        MPE      MAPE       MASE
## Training set 8.107152 251.7663 157.1975 0.03012748 0.4888355 0.04491683
##                      ACF1
## Training set -0.007655195
plot(pronostico, main = 'Pronóstico de ventas de leche saborizada para 2020', ylab='Ventas (en miles de USD)', xlab='Año')

Se realizó una proyección a 12 meses, o sea un año, de las ventas, teniendo en cuenta el pronóstico ofrecido con SARIMA con un nivel del cofianza del 95%. Justificamos la elección del modelo y su accuracy con el resultado del MAPE. Si nos fijamos en la gráfica vemos que sigue un vemos un patrón donde a inicio de año caen siginificativamente las ventas y luego van a la alza, con ciertas caídas, pero a la alza. En el pronóstico se muestra el mismo comportamiento.

4.- Considerando algunos imponderables establezca con los modelos construidos tres escenarios futuros ( proyecciones) A (escenario esperado) , B (escenario optimista) y C (escenario pesimista).

pronostico
##          Point Forecast    Lo 95    Hi 95
## Jan 2020       35475.83 34741.54 36210.11
## Feb 2020       34028.58 32812.06 35245.10
## Mar 2020       36441.48 35119.48 37763.49
## Apr 2020       36014.35 34619.04 37409.66
## May 2020       37004.23 35542.53 38465.92
## Jun 2020       36968.60 35443.86 38493.34
## Jul 2020       36811.98 35226.77 38397.19
## Aug 2020       38116.99 36473.53 39760.45
## Sep 2020       38179.41 36479.66 39879.16
## Oct 2020       39143.51 37388.98 40898.05
## Nov 2020       38083.90 36274.41 39893.39
## Dec 2020       38224.84 36353.24 40096.45
# Point Forecast es el escenario esperado
# Lo 95 es el escenario pesimista
# Hi 95 es el escenario optimista

pronostico_df <- pronostico %>% # se convierte el forecast data con los intervalos en un dataframe
  sweep::sw_sweep(.) %>% 
  filter(key == "forecast") %>% 
  select(-key)

colnames(pronostico_df) <- c('Mes','Escenario esperado','Escenario pesimista','Escenario optimista')

pronostico_df
## # A tibble: 12 × 4
##    Mes       `Escenario esperado` `Escenario pesimista` `Escenario optimista`
##    <yearmon>                <dbl>                 <dbl>                 <dbl>
##  1 ene. 2020               35476.                34742.                36210.
##  2 feb. 2020               34029.                32812.                35245.
##  3 mar. 2020               36441.                35119.                37763.
##  4 abr. 2020               36014.                34619.                37410.
##  5 may. 2020               37004.                35543.                38466.
##  6 jun. 2020               36969.                35444.                38493.
##  7 jul. 2020               36812.                35227.                38397.
##  8 ago. 2020               38117.                36474.                39760.
##  9 sep. 2020               38179.                36480.                39879.
## 10 oct. 2020               39144.                37389.                40898.
## 11 nov. 2020               38084.                36274.                39893.
## 12 dic. 2020               38225.                36353.                40096.
ggplot(pronostico_df, aes(x = Mes)) +
  geom_line(aes(y = `Escenario esperado`), color = "blue") +
  geom_line(aes(y = `Escenario pesimista`), color = "red") +
  geom_line(aes(y = `Escenario optimista`), color = "green") +
  geom_point(aes(y = `Escenario esperado`), color = "blue") +
  geom_point(aes(y = `Escenario pesimista`), color = "red") +
  geom_point(aes(y = `Escenario optimista`), color = "green") +
  labs(title = "Escenarios Hersheys", x = "Fecha", y = "Valor de escenarios")

Utilizando nuestro mejor modelo SARIMA, calcularon 3 escenarios: - Pesimista: Se calculó a partir de low confidence level - Realista: Es el pronóstico obtenido - Optimista: Se calculó a partir del high confidence level

Para una mejor visualización, se graficaron los 3 modelos observando que todos tienen el mismo comportamiento (una endencia en su mayoría positiva) ya que el pesimista y optimista parten del realista o pronóstico original.

5.- Con este análisis descriptivo, predictivo ¿Qué recomendaciones y medidas prescriptivas le puede dar a la compañía Hershey´s?

A partir de los pronosticos realizados, la empresa puede calcular el inventario necesario para producir dicha cantidad de ventas para poder producir en función de esto y cumplir con la demanda.

Así mismo, puede utilizar esta información para adaptar sus procesos a dicha demanda. Es decir, utilizar estos datos como justificación para expansiones y/o contrataciones.

Finalmente, desde un punto de vista de mercadotecnia, se puede generar publicidad y promociones para los meses donde se esperan disminuciones de las ventas para evitar estos picos negativos. Por ejemplo, en febrero y diciembre se puede realizar estrategias alrededor del día de San Valentín y Navidad respectivamente.

Referencias

LS0tDQp0aXRsZTogIkFjdGl2aWRhZCAyIC0gSGVyc2hleSdzIg0KYXV0aG9yOiAiRGFuaWVsLCBFcmljaywgQ2hhcml2ZWwsIEFuZ2VsYSINCmRhdGU6ICIyMDIzLTAyLTIyIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCiAgDQoNCiMgQ29udGV4dG8NCg0KSGVyc2hleeKAmXMgTcOpeGljbyBlbXByZXNhIGNob2NvbGF0ZXJhIGNvbiBtw6FzIGRlIDEwMCBhw7FvcyBkZSBoaXN0b3JpYSBhIG5pdmVsIGdsb2JhbCAoZnVuZGFjacOzbiAxOTAzKSB5IGVzdGFibGVjaWRhIGVuIE3DqXhpY28gZGVzZGUgMTk2OSwgY29tbyB1bmEgZGUgY29uZml0ZXLDrWEgZW50cmUgSGVyc2hleSBGb29kIENvcnBvcmF0aW9uIHkgQW5kZXJzb24gQ2xheXRvbiAmIENvLiBTLkEuIGZvcm1hbmRvIE5hY2lvbmFsIGRlIER1bGNlcyBTLkEuICBkZSBDLlYuIGVuIGVsIERpc3RyaXRvIEZlZGVyYWwgeSBkZXNwdcOpcyBkZSAxMiBhw7FvcyBjYW1iaWFuZG8gc3VzIGluc3RhbGFjaW9uZXMgYSBFbCBTYWx0bywgSmFsaXNjbyBlIGluaWNpYW5kbyBvcGVyYWNpb25lcyBlbiBlbCBtZXMgZGUgZmVicmVybyBkZSAxOTgxLg0KDQpFbiAyMDIyIEhlcnNoZXnCtHMgTcOpeGljbyBzZSBjb25zb2xpZMOzIGNvbW8gdW5hIGRlIGxhcyBlbXByZXNhcyBjaG9jb2xhdGVyYXMgZGVsIHBhw61zLCB5IGNvbiBtw6FzIGZ1ZXJ6YSBlbiBsYSB2ZW50YSBkZSBzdXMgbGVjaGl0YXMgeSBoYSBzdW1hZG8gZXNmdWVyem9zIHBhcmEgcXVlIGEgcGVzYXIgZGUgbGEgcGFuZGVtaWEgZGUgbGEgQ292aWQtMTkgb2ZyZXpjYSBlbCBtZWpvciB5IGRpc3BvbmliaWxpZGFkIGRlIHByb2R1Y3RvcyBhIHN1cyBjbGllbnRlcy4NCg0KSGVyc2hleSBNw6l4aWNvIGNvbWVyY2lhbGl6YSBtw6FzIGRlIDIwIG1hcmNhcywgZW50cmUgw6lzdGFzOiBLaXNzZXMsIFJlZXNlcywgUGVsw7NuIFBlbG8gUmljbywgQ2hvY295b2dvLCBlbnRyZSBvdHJhcy4gSW5jbHV5ZSBkZW50cm8gZGUgc3UgcG9ydGFmb2xpbyBkZSBwcm9kdWN0b3MgbGEgbGVjaGUgc2Fib3JpemFkYSwgY29ub2NpZGEgY29sb3F1aWFsbWVudGUgY29tbyBsYXMgbGVjaGl0YXMgZGUgSGVyc2hlecK0cy4gIEFudGUgZWwgY3JlY2ltaWVudG8gZXhwZXJpbWVudGFkbyBlbnRyZSBlbCBhw7FvIDIwMTcgeSAyMDE5IEhlcnNoZXnCtHMgdGllbmUgcXVlIHJlYWNjaW9uYXIgYSBsYXMgbmVjZXNpZGFkZXMgZGVsIGFiYXN0byB5IGV2aXRhciBxdWUgbm8gZmFsdGUgc3UgZW4gbG9zIGFuYXF1ZWxlcy4gQXVucXVlIEhlcnNoZXnCtHMgaGEgY3JlY2lkbyBlbiBwYXJ0aWNpcGFjacOzbiBkZSBtZXJjYWRvIGR1cmFudGUgZXN0ZSBwZXJpb2RvIGVuIGxhIGNhdGVnb3LDrWEsIHNlIGhhbiBwcmVzZW50YWRvIHByb2JsZW1hcyBkZSBhYmFzdG8gZGUgc3VzIHByb2R1Y3RvcywgZW4gY29uY3JldG8sIGhhIGhhYmlkbyBkZW1hbmRhIG5vIHNhdGlzZmVjaGEgeSBsYSBjb21wYcOxw61hIGRlc2VhIG1heGltaXphciBzdSB5IGFwcm92ZWNoYXIgbGFzIG9wb3J0dW5pZGFkZXMgbWVkaWFudGUgdW5hIG1lam9yIHByb3llY2Npw7NuIGRlIHN1cyB2ZW50YXMuDQoNCkxhIGNvbXBhw7HDrWEgaGEgZGVmaW5pZG8gY29tbyB1bmEgZGUgc3VzIHByaW5jaXBhbGVzIGVzdHJhdGVnaWFzIG1lam9yYXIgZWwgbml2ZWwgZGUgc2VydmljaW8gYWwgY2xpZW50ZSwgZXN0byBxdWllcmUgZGVjaXIsIGVudHJlZ2FyIGVuIHRpZW1wbyB5IGZvcm1hIHN1cyBwcm9kdWN0b3MsIGVzIGRlY2lyIHJlZHVjaXIgYWwgbcOtbmltbyBsYSBmYWx0YSBkZSBkaXNwb25pYmlsaWRhZCwgZXN0byBlcyBwb3NpYmxlIGNvbiBtb2RlbG9zIGFkZWN1YWRvcyBkZSBwbGFuaWZpY2FjacOzbiAoR2lsLCBldCBhbCwgMjAyMCkuDQoNClBhcmEgZXN0byBzZSB0aWVuZSBxdWUgdHJhYmFqYXIgY29uIGVuZm9xdWUgZW4gbGEgZXN0aW1hY2nDs24gZGUgbGEgZGVtYW5kYSBkZSBsYSBjb21wYcOxw61hIGEgbml2ZWwgbmFjaW9uYWwgeSBzdXMgcHJpbmNpcGFsZXMgcmVnaW9uZXMgKEd1YWRhbGFqYXJhLCBDRE1YLCBNb250ZXJyZXkgeSBUaWp1YW5hKS4gRXN0aW1hciBsYSBkZW1hbmRhIGVzIHVuIHByb2Nlc28gY29tcGxlam8gcXVlIG1lcmVjZSBsYSBwZW5hIGVqZWN1dGFybG8gZGUgbGEgbWVqb3IgbWFuZXJhIChSb2Ryw61ndWV6LCAyMDIxKSwgZXNlIGVzIHByZWNpc2FtZW50ZSBlbCBwbGFudGVhbWllbnRvIGRlbCBwcm9ibGVtYS4gTGEgYWx0ZXJuYXRpdmEgZXMgcmVhbGl6YXIgcHJveWVjY2lvbmVzIGNvbiBkYXRvcyBoaXN0w7NyaWNvcyBhcGxpY2FuZG8gaGVycmFtaWVudGFzIGVjb25vbcOpdHJpY2FzLCBxdWUgcGVybWl0YW4gcHJlZGVjaXIgY29uIG1lbm9yIG1hcmdlbiBkZSBlcnJvciBsYXMgdmVudGFzIChaaGFvLCBldCBhbCwgMjAwNyksIGVuIGNvbmNyZXRvIGVsIG9iamV0aXZvIGdlbmVyYWwgZXMgbW9kZWxhciBsYXMgdmVudGFzIG9idGVuZXIgdW4gcHJvbsOzc3RpY28gZXN0YWTDrXN0aWNvIGRlIGxhIGRlbWFuZGEgcGFyYSBtZWpvcmFyIGxhIGRpc3BvbmliaWxpZGFkIGVuIGVsIGZ1dHVybyBkZSBsb3MgcHJvZHVjdG9zIGRlIEhlcnNoZXnCtHMgcGFydGljdWxhcm1lbnRlIGxhcyBsZWNoZXMgc2Fib3JpemFkYXMsIHlhIHF1ZSBzZSBjb25zaWRlcmEgdW4gbmljaG8gZGUgbWVyY2FkbyBxdWUgSGVyc2hleSBoYSBjYXBpdGFsaXphZG8gbXV5IGJpZW4gZGVzZGUgaGFjZSBhw7Fvcy4gU2UgdHJhdGEgZGUgc29sdWNpb25hciB1bmEgcHJvYmxlbcOhdGljYSByZWFsIGRlbCBzZWN0b3IgZGUgbGVjaGVzIHNhYm9yaXphZGFzIGVuIC4NCg0KUGFyYSBwcm9jZWRlciBhIHByb3BvcmNpb25hciB1bmEgcHJveWVjY2nDs24gZXN0YWTDrXN0aWNhIGRlIGxhIHZlbnRhIGRlIGxhIGxlY2hlIHNhYm9yaXphZGEgSGVyc2hlecK0cyBNw6l4aWNvIGVuIHZhbG9yIG1vbmV0YXJpbyAobWlsZXMgZGUgZMOzbGFyZXMpIGEgdHJhdsOpcyBkZSBtb2RlbG9zIGRlIHNlcmllcyBkZSB0aWVtcG8gKEFSSU1BLCBTQVJJTUEsIGV0Yy4pICwgc2UgZGViZW4gcmVhbGl6YXIgcHJ1ZWJhcyBkZSBsYSBjb25zdHJ1Y2Npw7NuIGRlbCBtb2RlbG8gY29uIGxvcyBkYXRvcyBkZSBsYSBzZXJpZSBkZSB0aWVtcG8gbyBkYXRvcyBkZSBzZWNjacOzbiBjcnV6YWRhLiAgQWRpY2lvbmFsbWVudGUgc2UgcHVlZGVuIHRvbWFyIG90cmFzIHZhcmlhYmxlcyB5IGRhdG9zIGEgbml2ZWwgbXVuZGlhbCBjb24gZGF0b3MgcHJpbWFyaW9zIHkgc2VjdW5kYXJpb3MuIENvbiByZXNwZWN0byBhIGxhcyBoZXJyYW1pZW50YXMgY29tcHV0YWNpb25hbGVzIGRlIGFuYWzDrXRpY2EgZGUgZGF0b3MgZW4gZXN0ZSBjYXNvIHVzYXJlbW9zIGVsIGxlbmd1YWplIGRlIFIuDQoNCkNvbiBsYSBtb2RlbGFjacOzbiBhZGVjdWFkYSBkZSBsYXMgdmVudGFzIGRlIExlY2hpdGFzIHNlIHRvbWFyw6EgbGEgZGVjaXNpw7NuIGRlIHBsYW5pZmljYXJsbyB5IHByb2R1Y2lybG8gc2Vnw7puIGxhcyBwcm95ZWNjaW9uZXMgZXN0YWTDrXN0aWNhcy4gRXN0byBoYSBkZW1vc3RyYWRvIGVuIG11Y2hvcyBjb3Jwb3JhdGl2b3MgcXVlIG1lam9yYSBsYSBlZmljaWVuY2lhLCBwcm9kdWN0aXZpZGFkIHkgZWxldmEgZWwgbml2ZWwgZGUgc2VydmljaW8gKE1pbiwgZXQgYWwuIDIwMDgpLg0KDQoNCiMgRXhwbG9yYWNpw7NuIHkgY3JlYWNpw7NuDQoNCiMjIEltcG9ydGFjacOzbiBkZSBiYXNlIGRlIGRhdG9zDQogIA0KU2UgdXRpbGl6YSBsYSBmdW5jacOzbiByZWFkX2V4Y2VsIHBhcmEgaW1wb3J0YXIgbG9zIGRhdG9zIGhpc3TDs3JpY29zIGRlIHZlbnRhcy4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KHNhcmltYSkNCmxpYnJhcnkoc3dlZXApDQoNCiN+L0Rvd25sb2Fkcy9WZW50YXNfSGVyc2hleXMueGxzeA0KDQpiZCA8LSByZWFkX2V4Y2VsKCJWZW50YXNfSGVyc2hleXMueGxzeCIpDQpgYGANCiANCg0KTGFzIHZlbnRhcyBkZSAyMDE3IGEgMjAxOSBncmFmaWNhZGFzIHNlIG11ZXN0cmFuIGEgY29udGludWFjacOzbjoNCmBgYHtyfQ0KZ2dwbG90KGJkLCBhZXMoeD1NZXMseT1WZW50YXMpKSArIA0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fcG9pbnQoKSArDQogIHhsYWIoJ1RpZW1wbycpICsNCiAgeWxhYignVmVudGFzIChlbiBtaWxlcyBkZSBVU0QpJykgKw0KICBnZ3RpdGxlKCdWZW50YXMgZGUgbGVjaGUgc2Fib3JpemFkYSBkZSAyMDE3IGEgMjAxOScpDQpgYGANCiAgDQojIyBDcmVhY2nDs24gZGUgc2VyaWUgZGUgdGllbXBvDQogIA0KYGBge3J9DQpoZXJzaGV5c190cyA8LSB0cyhkYXRhPWJkJFZlbnRhcyxzdGFydD1jKDIwMTcsMSksZnJlcXVlbmN5PTEyKQ0KaGVyc2hleXNfdHMNCnBsb3QoaGVyc2hleXNfdHMsIG1haW4gPSAnU2VyaWUgZGUgdGllbXBvIGRlIHZlbnRhcyBkZSBsZWNoZSBzYWJvcml6YWRhIGRlIDIwMTcgYSAyMDE5JywgeGxhYiA9ICdUaWVtcG8nLCB5bGFiID0gJ1ZlbnRhcyAoZW4gbWlsZXMgZGUgVVNEKScpDQpgYGANCiAgDQojIFByZWd1bnRhcyBhIHJlc3BvbmRlcg0KICANCiMjIDEuLSBVdGlsaXphbmRvIG1vZGVsb3MgQVJJTUEgKEJveC1KZW5raW5zLCBBUk1BLCBTQVJJTUEpIHkgIGxvcyBkYXRvcyBoaXN0w7NyaWNvcyBkZSBsYXMgdmVudGFzIGRlIGxlY2hlIHNhYm9yaXphZGEgwr9DdcOhbCBlcyBlbCBtb2RlbG8gcXVlIG1lam9yIHNlIGFkYXB0YSBhIGxhIHNlcmllPyAgDQogIA0KU0FSSU1BDQpgYGB7cn0NCmhfc2FyaW1hIDwtIGFyaW1hKGhlcnNoZXlzX3RzLCBvcmRlcj1jKDEsMSwyKSwgc2Vhc29uYWw9YygxLDEsMSkpICNzYXJpbWEgbW9kaWZpY2FkbyBtYW51YWxtZW50ZSBwYXJhIGVuY29udHJhciBlbCBtZW5vciBlcnJvcg0KaF9zYXJpbWEgIyBKdXN0aWZpY2FyIGNvbiBlbCBBSUMNCmBgYA0KRWwgY3JpdGVyaW8gZGUgaW5mb3JtYWNpw7NuIGRlIEFrYWlrZSAoQUlDKSBlcyB1bmEgbWVkaWRhIGFtcGxpYW1lbnRlIHV0aWxpemFkYSBwYXJhIG1vZGVsb3MgZXN0YWTDrXN0aWNvcy4gQsOhc2ljYW1lbnRlIGN1YW50aWZpY2EgbGEgYm9uZGFkIGRlIGFqdXN0ZSB5IGxhIHNpbXBsaWNpZGFkL3BhcnNpbW9uaWEgZGVsIG1vZGVsbyBlbiB1bmEgc29sYSBlc3RhZMOtc3RpY2EuIEFsIGNvbXBhcmFyIGRvcyBtb2RlbG9zLCBlbCBxdWUgdGllbmUgZWwgQUlDIG3DoXMgYmFqbyBlcyBnZW5lcmFsbWVudGUgIm1lam9yIiAoS2VzaHZhbmksIDIwMTMpLg0KDQpDb25zZWd1aXIgZWwgQUlDIG3DoXMgYmFqbyBzZSBoaWNpZXJvbiBjYW1iaW9zIGxvcyBtb2RlbG9zIHkgZGUgbG9zIHBhcmFtZXRyb3MgbWFudWFsbWVudGUsIGhhc3RhIGxsZWdhciBhIHVuYSBjb21iaW5hY2nDs24gZmF2b3JhYmxlLg0KDQojIyAyLi0gwr9RdcOpIG1vZGVsbyBkZSByZWdyZXNpw7NuIG9mcmVjZSBtZWpvciBleGFjdGl0dWQgcHJlZGljdGl2YT8NCmBgYHtyfQ0KcmVncmVzaW9uIDwtIGxtKFZlbnRhcyB+IE1lcywgZGF0YT1iZCkgI3JlZ3Jlc2lvbiBsaW5lYWwgc2ltcGxlDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCmBgYA0KRWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gZXNjb2dpZG8gZnVlIGVsIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZS4gDQpQb2RlbW9zIGRlY2lyIHF1ZSBlcyB1biBidWVuIG1vZGVsbyBwb3IgZWwgcmVzdWx0YWRvIGRlIGxhIFItc3F1YXJlZC5MYSBSLXNxdWFyZWQgbXVlc3RyYSBxdcOpIHRhbiBiaWVuIHNlIGFqdXN0YSBlbCBtb2RlbG8gYSBsb3MgZGF0b3MgcmVhbGVzLiBUb21hIGxhIGZvcm1hIGRlIHVuYSBwcm9wb3JjacOzbiBkZSBsYSB2YXJpYW56YSwgc2llbmRvICB1bmEgbWVkaWRhIGRlIGxhIHJlbGFjacOzbiBsaW5lYWwgZW50cmUgbnVlc3RyYSB2YXJpYWJsZSBkZSBwcmVkaWNjacOzbiB5IG51ZXN0cmEgdmFyaWFibGUgZGUgcmVzcHVlc3RhL29iamV0aXZvIChSZWdvLCAyMDE1KS4gRW4gbnVlc3RybyBjYXNvLCBwb2RlbW9zIGRlY2lyIHF1ZSBhcHJveGltYWRhbWVudGUgZWwgOTMlIGRlIGxhIHZhcmlhbnphIGVuY29udHJhZGEgZW4gbGEgdmFyaWFibGUgZGUgcmVzcHVlc3RhIHB1ZWRlIGV4cGxpY2Fyc2UgcG9yIGxhIHZhcmlhYmxlIHByZWRpY3RvcmEuIElndWFsIGNvbiB1biBwLXZhbHVlIG1lbm9yIGEgMC4wNSBwb2RlbW9zIGRlY2lyIHF1ZSBlcyB1bmEgcmVzcHVlc3RhIHNpZ25pZmljYXRpdmEuDQogIA0KIyMgMy4tU2Vnw7puIHN1IG1lam9yIG1vZGVsbyAgwr9DdcOhbCBlcyBsYSBwcm95ZWNjacOzbiBkZSB2ZW50YXMgZW4gdmFsb3IgbW9uZXRhcmlvIHBhcmEgZWwgc2lndWllbnRlIGEgdG90YWwgZGUgSGVyc2hlecK0cz8NCmBgYHtyfQ0KcHJvbm9zdGljbyA8LSBmb3JlY2FzdChoX3NhcmltYSwgbGV2ZWwgPSBjKDk1KSwgaCA9IDEyKSAjUHJvbm9zdGljbyBkZSBsb3Mgc2lndWllbnRlcyAxMiBtZXNlcw0KYWNjdXJhY3kocHJvbm9zdGljbykgIyBKdXN0aWZpY2FyIGNvbiBlbCBNQVBFDQpwbG90KHByb25vc3RpY28sIG1haW4gPSAnUHJvbsOzc3RpY28gZGUgdmVudGFzIGRlIGxlY2hlIHNhYm9yaXphZGEgcGFyYSAyMDIwJywgeWxhYj0nVmVudGFzIChlbiBtaWxlcyBkZSBVU0QpJywgeGxhYj0nQcOxbycpDQpgYGANClNlIHJlYWxpesOzIHVuYSBwcm95ZWNjacOzbiBhIDEyIG1lc2VzLCBvIHNlYSB1biBhw7FvLCBkZSBsYXMgdmVudGFzLCB0ZW5pZW5kbyBlbiBjdWVudGEgZWwgcHJvbsOzc3RpY28gb2ZyZWNpZG8gY29uIFNBUklNQSBjb24gdW4gbml2ZWwgZGVsIGNvZmlhbnphIGRlbCA5NSUuDQpKdXN0aWZpY2Ftb3MgbGEgZWxlY2Npw7NuIGRlbCBtb2RlbG8geSBzdSBhY2N1cmFjeSBjb24gZWwgcmVzdWx0YWRvIGRlbCBNQVBFLiBTaSBub3MgZmlqYW1vcyBlbiBsYSBncsOhZmljYSB2ZW1vcyBxdWUgc2lndWUgdW4gdmVtb3MgdW4gcGF0csOzbiBkb25kZSBhIGluaWNpbyBkZSBhw7FvIGNhZW4gc2lnaW5pZmljYXRpdmFtZW50ZSBsYXMgdmVudGFzIHkgbHVlZ28gdmFuIGEgbGEgYWx6YSwgY29uIGNpZXJ0YXMgY2HDrWRhcywgcGVybyBhIGxhIGFsemEuIEVuIGVsIHByb27Ds3N0aWNvIHNlIG11ZXN0cmEgZWwgbWlzbW8gY29tcG9ydGFtaWVudG8uIA0KICANCiAgDQojIyA0Li0gQ29uc2lkZXJhbmRvIGFsZ3Vub3MgaW1wb25kZXJhYmxlcyBlc3RhYmxlemNhIGNvbiBsb3MgbW9kZWxvcyBjb25zdHJ1aWRvcyB0cmVzIGVzY2VuYXJpb3MgZnV0dXJvcyAoIHByb3llY2Npb25lcykgIEEgKGVzY2VuYXJpbyBlc3BlcmFkbykgLCBCIChlc2NlbmFyaW8gb3B0aW1pc3RhKSAgeSBDIChlc2NlbmFyaW8gcGVzaW1pc3RhKS4NCg0KYGBge3J9DQpwcm9ub3N0aWNvDQojIFBvaW50IEZvcmVjYXN0IGVzIGVsIGVzY2VuYXJpbyBlc3BlcmFkbw0KIyBMbyA5NSBlcyBlbCBlc2NlbmFyaW8gcGVzaW1pc3RhDQojIEhpIDk1IGVzIGVsIGVzY2VuYXJpbyBvcHRpbWlzdGENCg0KcHJvbm9zdGljb19kZiA8LSBwcm9ub3N0aWNvICU+JSAjIHNlIGNvbnZpZXJ0ZSBlbCBmb3JlY2FzdCBkYXRhIGNvbiBsb3MgaW50ZXJ2YWxvcyBlbiB1biBkYXRhZnJhbWUNCiAgc3dlZXA6OnN3X3N3ZWVwKC4pICU+JSANCiAgZmlsdGVyKGtleSA9PSAiZm9yZWNhc3QiKSAlPiUgDQogIHNlbGVjdCgta2V5KQ0KDQpjb2xuYW1lcyhwcm9ub3N0aWNvX2RmKSA8LSBjKCdNZXMnLCdFc2NlbmFyaW8gZXNwZXJhZG8nLCdFc2NlbmFyaW8gcGVzaW1pc3RhJywnRXNjZW5hcmlvIG9wdGltaXN0YScpDQoNCnByb25vc3RpY29fZGYNCg0KDQpnZ3Bsb3QocHJvbm9zdGljb19kZiwgYWVzKHggPSBNZXMpKSArDQogIGdlb21fbGluZShhZXMoeSA9IGBFc2NlbmFyaW8gZXNwZXJhZG9gKSwgY29sb3IgPSAiYmx1ZSIpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0gYEVzY2VuYXJpbyBwZXNpbWlzdGFgKSwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBgRXNjZW5hcmlvIG9wdGltaXN0YWApLCBjb2xvciA9ICJncmVlbiIpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IGBFc2NlbmFyaW8gZXNwZXJhZG9gKSwgY29sb3IgPSAiYmx1ZSIpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IGBFc2NlbmFyaW8gcGVzaW1pc3RhYCksIGNvbG9yID0gInJlZCIpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IGBFc2NlbmFyaW8gb3B0aW1pc3RhYCksIGNvbG9yID0gImdyZWVuIikgKw0KICBsYWJzKHRpdGxlID0gIkVzY2VuYXJpb3MgSGVyc2hleXMiLCB4ID0gIkZlY2hhIiwgeSA9ICJWYWxvciBkZSBlc2NlbmFyaW9zIikNCmBgYA0KDQpVdGlsaXphbmRvIG51ZXN0cm8gbWVqb3IgbW9kZWxvIFNBUklNQSwgY2FsY3VsYXJvbiAzIGVzY2VuYXJpb3M6DQotIFBlc2ltaXN0YTogU2UgY2FsY3Vsw7MgYSBwYXJ0aXIgZGUgbG93IGNvbmZpZGVuY2UgbGV2ZWwNCi0gUmVhbGlzdGE6IEVzIGVsIHByb27Ds3N0aWNvIG9idGVuaWRvIA0KLSBPcHRpbWlzdGE6IFNlIGNhbGN1bMOzIGEgcGFydGlyIGRlbCBoaWdoIGNvbmZpZGVuY2UgbGV2ZWwNCg0KUGFyYSB1bmEgbWVqb3IgdmlzdWFsaXphY2nDs24sIHNlIGdyYWZpY2Fyb24gbG9zIDMgbW9kZWxvcyBvYnNlcnZhbmRvIHF1ZSB0b2RvcyB0aWVuZW4gZWwgbWlzbW8gY29tcG9ydGFtaWVudG8gKHVuYSBlbmRlbmNpYSBlbiBzdSBtYXlvcsOtYSBwb3NpdGl2YSkgeWEgcXVlIGVsIHBlc2ltaXN0YSB5IG9wdGltaXN0YSBwYXJ0ZW4gZGVsIHJlYWxpc3RhIG8gcHJvbsOzc3RpY28gb3JpZ2luYWwuIA0KDQogIA0KIyMgNS4tIENvbiBlc3RlIGFuw6FsaXNpcyBkZXNjcmlwdGl2bywgIHByZWRpY3Rpdm8gwr9RdcOpIHJlY29tZW5kYWNpb25lcyB5IG1lZGlkYXMgcHJlc2NyaXB0aXZhcyBsZSBwdWVkZSBkYXIgYSBsYSBjb21wYcOxw61hIEhlcnNoZXnCtHM/IA0KDQpBIHBhcnRpciBkZSBsb3MgcHJvbm9zdGljb3MgcmVhbGl6YWRvcywgbGEgZW1wcmVzYSBwdWVkZSBjYWxjdWxhciBlbCBpbnZlbnRhcmlvIG5lY2VzYXJpbyBwYXJhIHByb2R1Y2lyIGRpY2hhIGNhbnRpZGFkIGRlIHZlbnRhcyBwYXJhIHBvZGVyIHByb2R1Y2lyIGVuIGZ1bmNpw7NuIGRlIGVzdG8geSBjdW1wbGlyIGNvbiBsYSBkZW1hbmRhLiANCg0KQXPDrSBtaXNtbywgcHVlZGUgdXRpbGl6YXIgZXN0YSBpbmZvcm1hY2nDs24gcGFyYSBhZGFwdGFyIHN1cyBwcm9jZXNvcyBhIGRpY2hhIGRlbWFuZGEuIEVzIGRlY2lyLCB1dGlsaXphciBlc3RvcyBkYXRvcyBjb21vIGp1c3RpZmljYWNpw7NuIHBhcmEgZXhwYW5zaW9uZXMgeS9vIGNvbnRyYXRhY2lvbmVzLg0KDQpGaW5hbG1lbnRlLCBkZXNkZSB1biBwdW50byBkZSB2aXN0YSBkZSBtZXJjYWRvdGVjbmlhLCBzZSBwdWVkZSBnZW5lcmFyIHB1YmxpY2lkYWQgeSBwcm9tb2Npb25lcyBwYXJhIGxvcyBtZXNlcyBkb25kZSBzZSBlc3BlcmFuIGRpc21pbnVjaW9uZXMgZGUgbGFzIHZlbnRhcyBwYXJhIGV2aXRhciBlc3RvcyBwaWNvcyBuZWdhdGl2b3MuIFBvciBlamVtcGxvLCBlbiBmZWJyZXJvIHkgZGljaWVtYnJlIHNlIHB1ZWRlIHJlYWxpemFyIGVzdHJhdGVnaWFzIGFscmVkZWRvciBkZWwgZMOtYSBkZSBTYW4gVmFsZW50w61uIHkgTmF2aWRhZCByZXNwZWN0aXZhbWVudGUuIA0KICANCiMgUmVmZXJlbmNpYXMNCiogR2lsLCBNLiwgUm9kcmlndWV6LCBNIHkgTW9udG95YSwgTS4gKDIwMjApLiBUaGUgaW1wYWN0IG9mIGRlbWFuZCBwbGFubmluZyBvbiB0aGUgcGVyZm9ybWFuY2Ugb2Ygc21hbGwgYW5kIG1lZGl1bS1zaXplZCBlbnRlcnByaXNlcyAoU01FcykgaW4gTWV4aWNvLiBBZHZhbmNlcyBpbiBCdXNpbmVzcyBSZWxhdGVkIFNjaWVudGlmaWMgUmVzZWFyY2ggSm91cm5hbC4gVm9sIDExICgyKTogNTYtNzIuIGh0dHBzOi8vd3d3LmFic3JjLm9yZy9wdWJsaWNhdGlvbnMvYWJzcmotMjAyMC12b2x1bWUtMTEtbnVtYmVyLTItZ2lsLw0KKiBNaW4sIEguLCAmIFl1LCBXLiBCLiBWLiAoMjAwOCkuIENvbGxhYm9yYXRpdmUgcGxhbm5pbmcsIGZvcmVjYXN0aW5nIGFuZCByZXBsZW5pc2htZW50OiBkZW1hbmQgcGxhbm5pbmcgaW4gc3VwcGx5IGNoYWluIG1hbmFnZW1lbnQuIEludGVybmF0aW9uYWwgSm91cm5hbCBvZiBJbmZvcm1hdGlvbiBUZWNobm9sb2d5IGFuZCBNYW5hZ2VtZW50LCA3KDEpLCA0LTIwLg0KKiBSZWdvLCBGLiAoMjAxNSwgT2N0dWJyZSAyMykuIFF1aWNrIEd1aWRlOiBJbnRlcnByZXRpbmcgU2ltcGxlIExpbmVhciBNb2RlbCBPdXRwdXQgaW4gUi4gR2l0aHViLmlvLiBodHRwczovL2ZlbGlwZXJlZ28uZ2l0aHViLmlvL2Jsb2cvMjAxNS8xMC8yMy9JbnRlcnByZXRpbmctTW9kZWwtT3V0cHV0LUluLVINCiogUm9kcsOtZ3VleiwgTS4gKDIwMjEpLiBJbXBhY3RvIGRlIEFkbWluaXN0cmFjacOzbiBkZSBsYSBkZW1hbmRhIGVuIG1lcmNhZG9zIGVtZXJnZW50ZXMuIE11bHRpZGlzY2lwbGluYXJ5IEJ1c2luZXNzIFJldmlldywgMTQgKDEpOiBYWC1YWC4gW0lTU04gMDcxOC00MDBYIChPbmxpbmUpXS4gaHR0cHM6Ly9qb3VybmFsbWJyLm5ldC9pbmRleC5waHAvbWJyL2FydGljbGUvdmlldy83NTBMaW5rcyB0byBhbiBleHRlcm5hbCBzaXRlLg0KKiBLZXNodmFuaSwgQS4gKDIwMTMsIEFnb3N0byAxNCkuIFVzaW5nIEFJQyB0byBUZXN0IEFSSU1BIE1vZGVscy4gQ29vbFN0YXRzQmxvZzsgQ29vbFN0YXRzQmxvZy4gaHR0cHM6Ly9jb29sc3RhdHNibG9nLmNvbS8yMDEzLzA4LzE0L3VzaW5nLWFpYy10by10ZXN0LWFyaW1hLW1vZGVscy0yLw0KKiBaaGFvLCBYLCBYaWUgSi4sIFdlaSBKICgyMDA3KS4gVGhlIEltcGFjdCBvZiBGb3JlY2FzdCBFcnJvcnMgb24gRWFybHkgT3JkZXIgQ29tbWl0bWVudCBpbiBhIFN1cHBseSBDaGFpbg0KDQoNCg0KDQoNCg0KDQo=