1 Discretización

Las discretizaciones sirven para trasnformar una variable continua en una discreta. En este caso me interesa comparar si los precios estuvieron por encima o por debajo de otro valor.

1.1 Dataset de la clase Missing por periodo

Utilizo el dataset que tenia las medias entre periodos y aún no había eliminado las mediciones originales

# Renombro las columnas de las mediciones
preciosdiscretos <- dfremplazo %>% rename("m1" ="1", "m2"="2", "m3"="3", "m4"="4","m5"="5","m6"="6","m7"="7","m8"="8","m9"="9","m10"="10")


colnames(preciosdiscretos)
 [1] "producto"            "nombre"              "Categoria"          
 [4] "marca"               "presentacion"        "sucursal"           
 [7] "sucursalTipo"        "banderaDescripcion"  "comercioRazonSocial"
[10] "direccion"           "barrio"              "m1"                 
[13] "m2"                  "m3"                  "m4"                 
[16] "m5"                  "m6"                  "m7"                 
[19] "m8"                  "m9"                  "m10"                
[22] "periodo1"            "periodo2"            "periodo3"           
[25] "periodo4"            "promedio"           

1.2 Calculo de medias

1.2.1 Media general intra periodo

Variacion intra periodo: definido en funcion de cada mes

  • Medicion 1-2-3 son de Noviembre 2018
  • Medicion 4-5 son de Diciembre 2018
  • Medicion 6-7 son de Enero 2019
  • Medicion 8-9-10 son de Febrero

Calculo la variación de datos intra periodo de todos los productos.

# Variaciones intra periodo y total
preciosdiscretos = (
preciosdiscretos %>%
dplyr::mutate(variacion1 = (m3-m1)/m1, variacion2 = (m5-m4)/m4, variacion3 = (m7-m6)/m6, variacion4 = (m10-m8)/m8, variacionT = (m10-m1)/m1)
)

Para tener un valor comparable de precios por producto en distintas sucursales

1.2.2 Media por producto

preciosdiscretos = (
preciosdiscretos %>%
 group_by(producto, nombre) %>%
 dplyr::mutate(media_prod1 = mean(periodo1), media_prod2 = mean(periodo2), media_prod3 = mean(periodo3), media_prod4 = mean(periodo4), media_prodT = mean(promedio))
) 

1.2.3 Precio Relativo

El precio relativo se calcula con la formula:

\(Precio_r = (Psucursal - P_mproducto)/P_mproducto)\)


preciosdiscretos = (
preciosdiscretos %>%
 group_by(sucursal, producto) %>%
 dplyr::mutate(precio_rel1 = (periodo1-media_prod1)/periodo1, precio_rel2 = (periodo2-media_prod2)/periodo2, precio_rel3 = (periodo3-media_prod3)/periodo3, precio_rel4 = (periodo4-media_prod4)/periodo4, precio_rel_medio = (promedio-media_prodT)/promedio)
)

1.3 Datasets Adicionales

  • Inflacion
  • Precio por metro cuadrado
  • Barrio
barrio <- read.csv("./files/Datasets adicionales/barrios.csv")
inflacion <- read.csv("./files/Datasets adicionales/inflacion.csv")
precio_metros2 <- read.csv("./files/barrios/precio_metro.csv")

Agregamos precio por metro cuadrado del barrio

# Agregamos el precio por metro cuadrado
preciosdiscretos = inner_join(preciosdiscretos, precio_metros2[1:2], by = c("barrio" = "BARRIO"))

# Renombramos la columna PRECIO
preciosdiscretos = (preciosdiscretos %>% rename(precio_m2 = PRECIO))

1.3.1 Creacion de una canasta

  • Alimentos Recomendados para la salud
  • Alimentos de consumo moderado
  • Alimentos a evitar

Agregamos una columna de “canasta”

# Armamos canasta de alimentos
target_rec = c("Agua","Infusiones","Leche", "Leche en polvo", "Arroz","Harinas","Verduras congeladas")
target_mod = c("Conservas","Quesos","Pastas","Yogur","Aceite", "Aceite de oliva", "Manteca","Endulzantes")
target_evi = c("Bebidas sin alcohol", "Bebidas deportivas", "Jugos en polvo", "Carnes congeladas", "Otros congelados", "Cereales azucarados", "Panificados","Salsas")
# Agregamos la columna "canasta"
preciosdiscretos = mutate(preciosdiscretos, canasta = ifelse(Categoria %in% target_rec, "recomendado",
                                            ifelse(Categoria %in% target_mod, "moderado",
                                            ifelse(Categoria %in% target_evi, "evitar", NA))))

2 Discretizacion 1: Etiquetar

2.1 Variaciones intra periodo:

¿Debajo o encima de la inflación?

# Agregamos columnas de inflación
preciosdiscretos = mutate(preciosdiscretos, inflacion1 = 
                      ifelse(variacion1 < 0.034, "debajo de inflación", "encima de inflación"))

preciosdiscretos = mutate(preciosdiscretos, inflacion2 = 
                      ifelse(variacion2 < 0.017, "debajo de inflación", "encima de inflación"))

preciosdiscretos = mutate(preciosdiscretos, inflacion3 = 
                      ifelse(variacion3 < 0.034, "debajo de inflación", "encima de inflación"))

preciosdiscretos = mutate(preciosdiscretos, inflacion4 = 
                      ifelse(variacion4 < 0.057, "debajo de inflación", "encima de inflación"))

preciosdiscretos = mutate(preciosdiscretos, inflacionT = 
                      ifelse(variacionT < 0.149, "debajo de inflación", "encima de inflación"))

2.2 Libreria arules:

Funcion discretize

discretize(x, method=“interval”, categories = 3, labels = , ordered=FALSE, onlycuts=FALSE, …)


Metodos

  • “interval” (equal interval width),
  • “frequency” (equal frequency),
  • “cluster” (k-means clustering) and
  • “fixed” (categories specifies interval boundaries).
library(arules)
#Hago una copia del dataframe para hacerle modificiones
df_disc <- preciosdiscretos

Creo intervalos para la variacion

# Variación
intervalos = c(-Inf, -0.05, -0.02, -0.005, 0.005, 0.05, 0.1, Inf)
etiquetas = c("disminucion fuerte", "disminucion media", "disminucion leve", "mantiene", "aumento leve", "aumento medio", "aumento fuerte")
df_disc$variacion1 = discretize(df_disc$variacion1, method = "fixed", breaks = intervalos, labels = etiquetas)
df_disc$variacion2 = discretize(df_disc$variacion2, method = "fixed", breaks = intervalos, labels = etiquetas)
df_disc$variacion3 = discretize(df_disc$variacion3, method = "fixed", breaks = intervalos, labels = etiquetas)
df_disc$variacion4 = discretize(df_disc$variacion4, method = "fixed", breaks = intervalos, labels = etiquetas)
df_disc$variacionT = discretize(df_disc$variacionT, method = "fixed", breaks = intervalos, labels = etiquetas)

Intervalos para el precio relativo

# Precio
intervalos1 = c(-Inf, -0.1, -0.05, -0.01, 0.01, 0.05, 0.1, Inf)
etiquetas1 = c("muy barato", "medianamente barato", "levemente barato", "medio", "levemente caro", "medianamente caro", "muy caro")
df_disc$precio_rel1 = discretize(df_disc$precio_rel1, method = "fixed", breaks = intervalos1, labels = etiquetas1)
df_disc$precio_rel2 = discretize(df_disc$precio_rel2, method = "fixed", breaks = intervalos1, labels = etiquetas1)
df_disc$precio_rel3 = discretize(df_disc$precio_rel3, method = "fixed", breaks = intervalos1, labels = etiquetas1)
df_disc$precio_rel4 = discretize(df_disc$precio_rel4, method = "fixed", breaks = intervalos1, labels = etiquetas1)
df_disc$precio_rel_medio = discretize(df_disc$precio_rel_medio, method = "fixed", breaks = intervalos1, labels = etiquetas1)

Intervalos para el valor del m2

# Preio m2
intervalos2 = c(-Inf, 1000, 2000, 4000, 5000, 6000, Inf)
etiquetas2 = c("barato", "medianamente barato", "medio", "medianamente caro", "caro", "muy caro")
df_disc$precio_m2 = discretize(df_disc$precio_m2, method = "fixed", breaks = intervalos2, labels = etiquetas2)
# Nos quedamos sólo con las variables discretas
df = select(df_disc,-c(12:26,32:36))
glimpse(df)
Observations: 162,630
Variables: 28
Groups: sucursal, producto [162,630]
$ producto            <chr> "7790762052364", "12-1-2800000937881"...
$ nombre              <fct> Vino Rosado Seleccion Especial Santa ...
$ Categoria           <fct> Bebidas con alcohol, Conservas, Bebid...
$ marca               <fct> SANTA ANA, COTO, NIETO SANETINER, BOD...
$ presentacion        <fct> 700.0 ml, 81.0 gr, 750.0 cc, 750.0 ml...
$ sucursal            <chr> "12-1-44", "12-1-44", "12-1-44", "12-...
$ sucursalTipo        <fct> Supermercado, Supermercado, Supermerc...
$ banderaDescripcion  <fct> COTO CICSA, COTO CICSA, COTO CICSA, C...
$ comercioRazonSocial <fct> Coto Centro Integral de Comercializac...
$ direccion           <fct> Av. Monroe 3284, Av. Monroe 3284, Av....
$ barrio              <chr> "COGHLAN", "COGHLAN", "COGHLAN", "COG...
$ variacion1          <fct> mantiene, mantiene, mantiene, mantien...
$ variacion2          <fct> mantiene, mantiene, mantiene, mantien...
$ variacion3          <fct> mantiene, aumento leve, mantiene, man...
$ variacion4          <fct> mantiene, mantiene, mantiene, mantien...
$ variacionT          <fct> mantiene, aumento leve, mantiene, aum...
$ precio_rel1         <fct> NA, medio, medianamente caro, NA, med...
$ precio_rel2         <fct> NA, medio, medianamente caro, medio, ...
$ precio_rel3         <fct> NA, medio, NA, levemente caro, medio,...
$ precio_rel4         <fct> NA, medio, NA, medio, medio, NA, NA, ...
$ precio_rel_medio    <fct> levemente caro, medio, medianamente c...
$ precio_m2           <fct> medio, medio, medio, medio, medio, me...
$ canasta             <chr> NA, "moderado", NA, NA, "evitar", "mo...
$ inflacion1          <chr> "debajo de inflación", "debajo de inf...
$ inflacion2          <chr> "debajo de inflación", "debajo de inf...
$ inflacion3          <chr> "debajo de inflación", "encima de inf...
$ inflacion4          <chr> "debajo de inflación", "debajo de inf...
$ inflacionT          <chr> "debajo de inflación", "debajo de inf...

2.3 Segmentar

Quiero un histograma con los productos que aumentaron menos que la inflación para recoleta, separado por Canasta

bajo <- df %>% filter(inflacionT=="debajo de inflación", barrio=="RECOLETA")
ggplot(bajo, aes(x = sucursalTipo, y = stat(count), fill = canasta)) + 
    geom_bar(position = "dodge") +
  labs(y = "Count", 
       fill = "Canasta",
       x = "Tipo de sucursal",
       title = 'Cant. Productos')+
  theme_grey()

Quiero un mapa donde cada punto represente aumento del precio relativo, por barrio, separado en las cuatro cadenas mas grandes y en donde pueda ver el valor de los metros cuadrados por barrio

Mapa

Mapa

LS0tDQp0aXRsZTogIkRpc2NyZXRpemFjaW9uIg0KYXV0aG9yOiAiS29ubmEiDQpkYXRlOiAiMTEvMy8yMDIwIg0KDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvY19jb2xsYXBzZWQ6IHRydWUgDQogICAgdG9jX2RlcHRoOiA0DQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgdGhlbWU6IHNwYWNlbGFiDQotLS0NCjxzdHlsZT4NCmJvZHkgew0KdGV4dC1hbGlnbjoganVzdGlmeX0NCg0KLmxpc3QtZ3JvdXAtaXRlbS5hY3RpdmUsIC5saXN0LWdyb3VwLWl0ZW0uYWN0aXZlOmZvY3VzLCAubGlzdC1ncm91cC1pdGVtLmFjdGl2ZTpob3ZlciB7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI0REOEQxOw0KfQ0KPC9zdHlsZT4NCg0KDQoNCiMgRGlzY3JldGl6YWNpw7NuDQoNCkxhcyBkaXNjcmV0aXphY2lvbmVzIHNpcnZlbiBwYXJhIHRyYXNuZm9ybWFyIHVuYSB2YXJpYWJsZSBjb250aW51YSBlbiB1bmEgZGlzY3JldGEuIEVuIGVzdGUgY2FzbyBtZSBpbnRlcmVzYSBjb21wYXJhciBzaSBsb3MgcHJlY2lvcyBlc3R1dmllcm9uIHBvciBlbmNpbWEgbyBwb3IgZGViYWpvIGRlIG90cm8gdmFsb3IuDQoNCiMjIERhdGFzZXQgZGUgbGEgY2xhc2UgTWlzc2luZyBwb3IgcGVyaW9kbw0KKipVdGlsaXpvIGVsIGRhdGFzZXQgcXVlIHRlbmlhIGxhcyBtZWRpYXMgZW50cmUgcGVyaW9kb3MgeSBhw7puIG5vIGhhYsOtYSBlbGltaW5hZG8gbGFzIG1lZGljaW9uZXMgb3JpZ2luYWxlcyoqDQoNCmBgYHtyfQ0KIyBSZW5vbWJybyBsYXMgY29sdW1uYXMgZGUgbGFzIG1lZGljaW9uZXMNCnByZWNpb3NkaXNjcmV0b3MgPC0gZGZyZW1wbGF6byAlPiUgcmVuYW1lKCJtMSIgPSIxIiwgIm0yIj0iMiIsICJtMyI9IjMiLCAibTQiPSI0IiwibTUiPSI1IiwibTYiPSI2IiwibTciPSI3IiwibTgiPSI4IiwibTkiPSI5IiwibTEwIj0iMTAiKQ0KDQoNCmNvbG5hbWVzKHByZWNpb3NkaXNjcmV0b3MpDQoNCmBgYA0KIyMgQ2FsY3VsbyBkZSBtZWRpYXMNCg0KIyMjIE1lZGlhIGdlbmVyYWwgaW50cmEgcGVyaW9kbw0KDQo+VmFyaWFjaW9uIGludHJhIHBlcmlvZG86IGRlZmluaWRvIGVuIGZ1bmNpb24gZGUgY2FkYSBtZXMNCg0KKiBNZWRpY2lvbiAxLTItMyBzb24gZGUgTm92aWVtYnJlIDIwMTgNCiogTWVkaWNpb24gNC01IHNvbiBkZSBEaWNpZW1icmUgMjAxOA0KKiBNZWRpY2lvbiA2LTcgc29uIGRlICBFbmVybyAyMDE5DQoqIE1lZGljaW9uIDgtOS0xMCBzb24gZGUgRmVicmVybw0KDQpDYWxjdWxvIGxhIHZhcmlhY2nDs24gZGUgZGF0b3MgaW50cmEgcGVyaW9kbyBkZSB0b2RvcyBsb3MgcHJvZHVjdG9zLg0KYGBge3IgVmFyaWFjacOzbiBpbnRyYSBwZXJpb2RvIHkgdG90YWx9DQojIFZhcmlhY2lvbmVzIGludHJhIHBlcmlvZG8geSB0b3RhbA0KcHJlY2lvc2Rpc2NyZXRvcyA9ICgNCnByZWNpb3NkaXNjcmV0b3MgJT4lDQpkcGx5cjo6bXV0YXRlKHZhcmlhY2lvbjEgPSAobTMtbTEpL20xLCB2YXJpYWNpb24yID0gKG01LW00KS9tNCwgdmFyaWFjaW9uMyA9IChtNy1tNikvbTYsIHZhcmlhY2lvbjQgPSAobTEwLW04KS9tOCwgdmFyaWFjaW9uVCA9IChtMTAtbTEpL20xKQ0KKQ0KYGBgDQoNClBhcmEgdGVuZXIgdW4gdmFsb3IgY29tcGFyYWJsZSBkZSBwcmVjaW9zIHBvciBwcm9kdWN0byBlbiBkaXN0aW50YXMgc3VjdXJzYWxlcw0KDQojIyMgTWVkaWEgcG9yIHByb2R1Y3RvDQogDQpgYGB7ciBNZWRpYSBwb3IgcHJvZHVjdG99DQpwcmVjaW9zZGlzY3JldG9zID0gKA0KcHJlY2lvc2Rpc2NyZXRvcyAlPiUNCiBncm91cF9ieShwcm9kdWN0bywgbm9tYnJlKSAlPiUNCiBkcGx5cjo6bXV0YXRlKG1lZGlhX3Byb2QxID0gbWVhbihwZXJpb2RvMSksIG1lZGlhX3Byb2QyID0gbWVhbihwZXJpb2RvMiksIG1lZGlhX3Byb2QzID0gbWVhbihwZXJpb2RvMyksIG1lZGlhX3Byb2Q0ID0gbWVhbihwZXJpb2RvNCksIG1lZGlhX3Byb2RUID0gbWVhbihwcm9tZWRpbykpDQopIA0KYGBgDQoNCiMjIyBQcmVjaW8gUmVsYXRpdm8NCg0KRWwgcHJlY2lvIHJlbGF0aXZvIHNlIGNhbGN1bGEgY29uIGxhIGZvcm11bGE6IA0KPGJyPg0KDQokUHJlY2lvX3IgPSAoUHN1Y3Vyc2FsIC0gUF9tcHJvZHVjdG8pL1BfbXByb2R1Y3RvKSQNCg0KPGJyPg0KYGBge3IgUHJlY2lvIHJlbGF0aXZvfQ0KcHJlY2lvc2Rpc2NyZXRvcyA9ICgNCnByZWNpb3NkaXNjcmV0b3MgJT4lDQogZ3JvdXBfYnkoc3VjdXJzYWwsIHByb2R1Y3RvKSAlPiUNCiBkcGx5cjo6bXV0YXRlKHByZWNpb19yZWwxID0gKHBlcmlvZG8xLW1lZGlhX3Byb2QxKS9wZXJpb2RvMSwgcHJlY2lvX3JlbDIgPSAocGVyaW9kbzItbWVkaWFfcHJvZDIpL3BlcmlvZG8yLCBwcmVjaW9fcmVsMyA9IChwZXJpb2RvMy1tZWRpYV9wcm9kMykvcGVyaW9kbzMsIHByZWNpb19yZWw0ID0gKHBlcmlvZG80LW1lZGlhX3Byb2Q0KS9wZXJpb2RvNCwgcHJlY2lvX3JlbF9tZWRpbyA9IChwcm9tZWRpby1tZWRpYV9wcm9kVCkvcHJvbWVkaW8pDQopDQpgYGANCg0KIyMgRGF0YXNldHMgQWRpY2lvbmFsZXMNCisgSW5mbGFjaW9uDQorIFByZWNpbyBwb3IgbWV0cm8gY3VhZHJhZG8NCisgQmFycmlvDQo8YnI+DQpgYGB7ciBJbXBvcnRhY2nDs24gZGUgYXJjaGl2b3MgY3N2fQ0KYmFycmlvIDwtIHJlYWQuY3N2KCIuL2ZpbGVzL0RhdGFzZXRzIGFkaWNpb25hbGVzL2JhcnJpb3MuY3N2IikNCmluZmxhY2lvbiA8LSByZWFkLmNzdigiLi9maWxlcy9EYXRhc2V0cyBhZGljaW9uYWxlcy9pbmZsYWNpb24uY3N2IikNCnByZWNpb19tZXRyb3MyIDwtIHJlYWQuY3N2KCIuL2ZpbGVzL2JhcnJpb3MvcHJlY2lvX21ldHJvLmNzdiIpDQpgYGANCg0KDQpBZ3JlZ2Ftb3MgcHJlY2lvIHBvciBtZXRybyBjdWFkcmFkbyBkZWwgYmFycmlvPGJyPg0KYGBge3IgUHJlY2lvIG1ldHJvIGN1YWRyYWRvLCB3YXJuaW5nPUZBTFNFfQ0KIyBBZ3JlZ2Ftb3MgZWwgcHJlY2lvIHBvciBtZXRybyBjdWFkcmFkbw0KcHJlY2lvc2Rpc2NyZXRvcyA9IGlubmVyX2pvaW4ocHJlY2lvc2Rpc2NyZXRvcywgcHJlY2lvX21ldHJvczJbMToyXSwgYnkgPSBjKCJiYXJyaW8iID0gIkJBUlJJTyIpKQ0KDQojIFJlbm9tYnJhbW9zIGxhIGNvbHVtbmEgUFJFQ0lPDQpwcmVjaW9zZGlzY3JldG9zID0gKHByZWNpb3NkaXNjcmV0b3MgJT4lIHJlbmFtZShwcmVjaW9fbTIgPSBQUkVDSU8pKQ0KYGBgDQoNCiMjIyBDcmVhY2lvbiBkZSB1bmEgY2FuYXN0YQ0KKyAqKkFsaW1lbnRvcyBSZWNvbWVuZGFkb3MgcGFyYSBsYSBzYWx1ZCoqDQorICoqQWxpbWVudG9zIGRlIGNvbnN1bW8gbW9kZXJhZG8qKg0KKyAqKkFsaW1lbnRvcyBhIGV2aXRhcioqPGJyPg0KDQpBZ3JlZ2Ftb3MgdW5hIGNvbHVtbmEgZGUgImNhbmFzdGEiPGJyPg0KYGBge3IgVGFyZ2V0IGNhbmFzdGFzfQ0KIyBBcm1hbW9zIGNhbmFzdGEgZGUgYWxpbWVudG9zDQp0YXJnZXRfcmVjID0gYygiQWd1YSIsIkluZnVzaW9uZXMiLCJMZWNoZSIsICJMZWNoZSBlbiBwb2x2byIsICJBcnJveiIsIkhhcmluYXMiLCJWZXJkdXJhcyBjb25nZWxhZGFzIikNCnRhcmdldF9tb2QgPSBjKCJDb25zZXJ2YXMiLCJRdWVzb3MiLCJQYXN0YXMiLCJZb2d1ciIsIkFjZWl0ZSIsICJBY2VpdGUgZGUgb2xpdmEiLCAiTWFudGVjYSIsIkVuZHVsemFudGVzIikNCnRhcmdldF9ldmkgPSBjKCJCZWJpZGFzIHNpbiBhbGNvaG9sIiwgIkJlYmlkYXMgZGVwb3J0aXZhcyIsICJKdWdvcyBlbiBwb2x2byIsICJDYXJuZXMgY29uZ2VsYWRhcyIsICJPdHJvcyBjb25nZWxhZG9zIiwgIkNlcmVhbGVzIGF6dWNhcmFkb3MiLCAiUGFuaWZpY2Fkb3MiLCJTYWxzYXMiKQ0KYGBgDQoNCmBgYHtyIENhbmFzdGEgZGUgcHJvZHVjdG9zfQ0KIyBBZ3JlZ2Ftb3MgbGEgY29sdW1uYSAiY2FuYXN0YSINCnByZWNpb3NkaXNjcmV0b3MgPSBtdXRhdGUocHJlY2lvc2Rpc2NyZXRvcywgY2FuYXN0YSA9IGlmZWxzZShDYXRlZ29yaWEgJWluJSB0YXJnZXRfcmVjLCAicmVjb21lbmRhZG8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoQ2F0ZWdvcmlhICVpbiUgdGFyZ2V0X21vZCwgIm1vZGVyYWRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKENhdGVnb3JpYSAlaW4lIHRhcmdldF9ldmksICJldml0YXIiLCBOQSkpKSkNCmBgYA0KDQoNCiMgRGlzY3JldGl6YWNpb24gMTogRXRpcXVldGFyPGJyPg0KDQojIyBWYXJpYWNpb25lcyBpbnRyYSBwZXJpb2RvOiANCg0Kwr9EZWJham8gbyBlbmNpbWEgZGUgbGEgaW5mbGFjacOzbj88YnI+DQpgYGB7ciBJbmZsYWNpw7NufQ0KIyBBZ3JlZ2Ftb3MgY29sdW1uYXMgZGUgaW5mbGFjacOzbg0KcHJlY2lvc2Rpc2NyZXRvcyA9IG11dGF0ZShwcmVjaW9zZGlzY3JldG9zLCBpbmZsYWNpb24xID0gDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHZhcmlhY2lvbjEgPCAwLjAzNCwgImRlYmFqbyBkZSBpbmZsYWNpw7NuIiwgImVuY2ltYSBkZSBpbmZsYWNpw7NuIikpDQoNCnByZWNpb3NkaXNjcmV0b3MgPSBtdXRhdGUocHJlY2lvc2Rpc2NyZXRvcywgaW5mbGFjaW9uMiA9IA0KICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh2YXJpYWNpb24yIDwgMC4wMTcsICJkZWJham8gZGUgaW5mbGFjacOzbiIsICJlbmNpbWEgZGUgaW5mbGFjacOzbiIpKQ0KDQpwcmVjaW9zZGlzY3JldG9zID0gbXV0YXRlKHByZWNpb3NkaXNjcmV0b3MsIGluZmxhY2lvbjMgPSANCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UodmFyaWFjaW9uMyA8IDAuMDM0LCAiZGViYWpvIGRlIGluZmxhY2nDs24iLCAiZW5jaW1hIGRlIGluZmxhY2nDs24iKSkNCg0KcHJlY2lvc2Rpc2NyZXRvcyA9IG11dGF0ZShwcmVjaW9zZGlzY3JldG9zLCBpbmZsYWNpb240ID0gDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHZhcmlhY2lvbjQgPCAwLjA1NywgImRlYmFqbyBkZSBpbmZsYWNpw7NuIiwgImVuY2ltYSBkZSBpbmZsYWNpw7NuIikpDQoNCnByZWNpb3NkaXNjcmV0b3MgPSBtdXRhdGUocHJlY2lvc2Rpc2NyZXRvcywgaW5mbGFjaW9uVCA9IA0KICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh2YXJpYWNpb25UIDwgMC4xNDksICJkZWJham8gZGUgaW5mbGFjacOzbiIsICJlbmNpbWEgZGUgaW5mbGFjacOzbiIpKQ0KYGBgDQoNCiMjIExpYnJlcmlhIGFydWxlczoNCg0KKipGdW5jaW9uIGRpc2NyZXRpemUqKg0KDQoqZGlzY3JldGl6ZSh4LCBtZXRob2Q9ImludGVydmFsIiwgY2F0ZWdvcmllcyA9IDMsIGxhYmVscyA9ICwgICAgICBvcmRlcmVkPUZBTFNFLCBvbmx5Y3V0cz1GQUxTRSwgLi4uKSo8YnI+DQoNCjxicj4NCioqTWV0b2RvcyoqDQoNCisgImludGVydmFsIiAoZXF1YWwgaW50ZXJ2YWwgd2lkdGgpLA0KKyAiZnJlcXVlbmN5IiAoZXF1YWwgZnJlcXVlbmN5KSwgDQorICJjbHVzdGVyIiAoay1tZWFucyBjbHVzdGVyaW5nKSBhbmQNCisgImZpeGVkIiAoY2F0ZWdvcmllcyBzcGVjaWZpZXMgaW50ZXJ2YWwgYm91bmRhcmllcykuPGJyPg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGFydWxlcykNCiNIYWdvIHVuYSBjb3BpYSBkZWwgZGF0YWZyYW1lIHBhcmEgaGFjZXJsZSBtb2RpZmljaW9uZXMNCmRmX2Rpc2MgPC0gcHJlY2lvc2Rpc2NyZXRvcw0KYGBgDQoNCioqQ3JlbyBpbnRlcnZhbG9zIHBhcmEgbGEgdmFyaWFjaW9uKioNCmBgYHtyfQ0KIyBWYXJpYWNpw7NuDQppbnRlcnZhbG9zID0gYygtSW5mLCAtMC4wNSwgLTAuMDIsIC0wLjAwNSwgMC4wMDUsIDAuMDUsIDAuMSwgSW5mKQ0KZXRpcXVldGFzID0gYygiZGlzbWludWNpb24gZnVlcnRlIiwgImRpc21pbnVjaW9uIG1lZGlhIiwgImRpc21pbnVjaW9uIGxldmUiLCAibWFudGllbmUiLCAiYXVtZW50byBsZXZlIiwgImF1bWVudG8gbWVkaW8iLCAiYXVtZW50byBmdWVydGUiKQ0KYGBgDQoNCmBgYHtyfQ0KZGZfZGlzYyR2YXJpYWNpb24xID0gZGlzY3JldGl6ZShkZl9kaXNjJHZhcmlhY2lvbjEsIG1ldGhvZCA9ICJmaXhlZCIsIGJyZWFrcyA9IGludGVydmFsb3MsIGxhYmVscyA9IGV0aXF1ZXRhcykNCmRmX2Rpc2MkdmFyaWFjaW9uMiA9IGRpc2NyZXRpemUoZGZfZGlzYyR2YXJpYWNpb24yLCBtZXRob2QgPSAiZml4ZWQiLCBicmVha3MgPSBpbnRlcnZhbG9zLCBsYWJlbHMgPSBldGlxdWV0YXMpDQpkZl9kaXNjJHZhcmlhY2lvbjMgPSBkaXNjcmV0aXplKGRmX2Rpc2MkdmFyaWFjaW9uMywgbWV0aG9kID0gImZpeGVkIiwgYnJlYWtzID0gaW50ZXJ2YWxvcywgbGFiZWxzID0gZXRpcXVldGFzKQ0KZGZfZGlzYyR2YXJpYWNpb240ID0gZGlzY3JldGl6ZShkZl9kaXNjJHZhcmlhY2lvbjQsIG1ldGhvZCA9ICJmaXhlZCIsIGJyZWFrcyA9IGludGVydmFsb3MsIGxhYmVscyA9IGV0aXF1ZXRhcykNCmRmX2Rpc2MkdmFyaWFjaW9uVCA9IGRpc2NyZXRpemUoZGZfZGlzYyR2YXJpYWNpb25ULCBtZXRob2QgPSAiZml4ZWQiLCBicmVha3MgPSBpbnRlcnZhbG9zLCBsYWJlbHMgPSBldGlxdWV0YXMpDQpgYGANCg0KDQoqKkludGVydmFsb3MgcGFyYSBlbCBwcmVjaW8gcmVsYXRpdm8qKg0KYGBge3J9DQojIFByZWNpbw0KaW50ZXJ2YWxvczEgPSBjKC1JbmYsIC0wLjEsIC0wLjA1LCAtMC4wMSwgMC4wMSwgMC4wNSwgMC4xLCBJbmYpDQpldGlxdWV0YXMxID0gYygibXV5IGJhcmF0byIsICJtZWRpYW5hbWVudGUgYmFyYXRvIiwgImxldmVtZW50ZSBiYXJhdG8iLCAibWVkaW8iLCAibGV2ZW1lbnRlIGNhcm8iLCAibWVkaWFuYW1lbnRlIGNhcm8iLCAibXV5IGNhcm8iKQ0KYGBgDQoNCmBgYHtyfQ0KZGZfZGlzYyRwcmVjaW9fcmVsMSA9IGRpc2NyZXRpemUoZGZfZGlzYyRwcmVjaW9fcmVsMSwgbWV0aG9kID0gImZpeGVkIiwgYnJlYWtzID0gaW50ZXJ2YWxvczEsIGxhYmVscyA9IGV0aXF1ZXRhczEpDQpkZl9kaXNjJHByZWNpb19yZWwyID0gZGlzY3JldGl6ZShkZl9kaXNjJHByZWNpb19yZWwyLCBtZXRob2QgPSAiZml4ZWQiLCBicmVha3MgPSBpbnRlcnZhbG9zMSwgbGFiZWxzID0gZXRpcXVldGFzMSkNCmRmX2Rpc2MkcHJlY2lvX3JlbDMgPSBkaXNjcmV0aXplKGRmX2Rpc2MkcHJlY2lvX3JlbDMsIG1ldGhvZCA9ICJmaXhlZCIsIGJyZWFrcyA9IGludGVydmFsb3MxLCBsYWJlbHMgPSBldGlxdWV0YXMxKQ0KZGZfZGlzYyRwcmVjaW9fcmVsNCA9IGRpc2NyZXRpemUoZGZfZGlzYyRwcmVjaW9fcmVsNCwgbWV0aG9kID0gImZpeGVkIiwgYnJlYWtzID0gaW50ZXJ2YWxvczEsIGxhYmVscyA9IGV0aXF1ZXRhczEpDQpkZl9kaXNjJHByZWNpb19yZWxfbWVkaW8gPSBkaXNjcmV0aXplKGRmX2Rpc2MkcHJlY2lvX3JlbF9tZWRpbywgbWV0aG9kID0gImZpeGVkIiwgYnJlYWtzID0gaW50ZXJ2YWxvczEsIGxhYmVscyA9IGV0aXF1ZXRhczEpDQpgYGANCg0KKipJbnRlcnZhbG9zIHBhcmEgZWwgdmFsb3IgZGVsIG0yKioNCmBgYHtyfQ0KIyBQcmVpbyBtMg0KaW50ZXJ2YWxvczIgPSBjKC1JbmYsIDEwMDAsIDIwMDAsIDQwMDAsIDUwMDAsIDYwMDAsIEluZikNCmV0aXF1ZXRhczIgPSBjKCJiYXJhdG8iLCAibWVkaWFuYW1lbnRlIGJhcmF0byIsICJtZWRpbyIsICJtZWRpYW5hbWVudGUgY2FybyIsICJjYXJvIiwgIm11eSBjYXJvIikNCmBgYA0KDQoNCmBgYHtyfQ0KZGZfZGlzYyRwcmVjaW9fbTIgPSBkaXNjcmV0aXplKGRmX2Rpc2MkcHJlY2lvX20yLCBtZXRob2QgPSAiZml4ZWQiLCBicmVha3MgPSBpbnRlcnZhbG9zMiwgbGFiZWxzID0gZXRpcXVldGFzMikNCmBgYA0KDQpgYGB7ciBTb2xvIHZhcmlhYmxlcyBkaXNjcmV0YXN9DQojIE5vcyBxdWVkYW1vcyBzw7NsbyBjb24gbGFzIHZhcmlhYmxlcyBkaXNjcmV0YXMNCmRmID0gc2VsZWN0KGRmX2Rpc2MsLWMoMTI6MjYsMzI6MzYpKQ0KYGBgDQoNCmBgYHtyfQ0KZ2xpbXBzZShkZikNCmBgYA0KDQojIyBTZWdtZW50YXINCg0KUXVpZXJvIHVuIGhpc3RvZ3JhbWEgY29uIGxvcyBwcm9kdWN0b3MgcXVlIGF1bWVudGFyb24gbWVub3MgcXVlIGxhIGluZmxhY2nDs24gcGFyYSByZWNvbGV0YSwgc2VwYXJhZG8gcG9yIENhbmFzdGE8YnI+DQoNCmBgYHtyfQ0KYmFqbyA8LSBkZiAlPiUgZmlsdGVyKGluZmxhY2lvblQ9PSJkZWJham8gZGUgaW5mbGFjacOzbiIsIGJhcnJpbz09IlJFQ09MRVRBIikNCmBgYA0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KYmFqbyA8LSBuYS5vbWl0KGJham8pDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdChiYWpvLCBhZXMoeCA9IHN1Y3Vyc2FsVGlwbywgeSA9IHN0YXQoY291bnQpLCBmaWxsID0gY2FuYXN0YSkpICsgDQogICAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnMoeSA9ICJDb3VudCIsIA0KICAgICAgIGZpbGwgPSAiQ2FuYXN0YSIsDQogICAgICAgeCA9ICJUaXBvIGRlIHN1Y3Vyc2FsIiwNCiAgICAgICB0aXRsZSA9ICdDYW50LiBQcm9kdWN0b3MnKSsNCiAgdGhlbWVfZ3JleSgpDQoNCmBgYA0KDQoNClF1aWVybyB1biBtYXBhIGRvbmRlIGNhZGEgcHVudG8gcmVwcmVzZW50ZSBhdW1lbnRvIGRlbCBwcmVjaW8gcmVsYXRpdm8sIHBvciBiYXJyaW8sIHNlcGFyYWRvIGVuIGxhcyBjdWF0cm8gY2FkZW5hcyBtYXMgZ3JhbmRlcyB5IGVuIGRvbmRlIHB1ZWRhIHZlciBlbCB2YWxvciBkZSBsb3MgbWV0cm9zIGN1YWRyYWRvcyBwb3IgYmFycmlvPGJyPg0KDQohW01hcGFdKHByZWNpb3JlbGF0aXZvLnBuZykNCg0KDQo=