Entregable 1

Antecedentes de la empresa

Visión: “En 2033 seremos una de las cinco mejores compañías de México que generan valor dentro de la cadena de suministro de las industrias que más valoran la forma en la que se protegen y trasladan las cosas.” (Form, 2023).

Misión: “Transformar nuestro entorno y resolver retos industriales de nuestros clientes a través de la colaboración, provocando nuevas oportunidades que potencian nuestro modelo de negocio, para alcanzar nuestros ideales.” (Form, 2023).

Contexto de la industria:

La industria de empaque y embalaje representa una parte esencial del sector automotriz y de autopartes, ya que esta industria es pieza clave para garantizar la protección y entrega eficiente de los componentes automotrices en sus diferentes fases dentro de la cadena de suministro del sector automotriz.

En el 2022, la producción de automóviles en el mundo mantiene a Estados Unidos como el segundo mayor productor de automóviles abarcando el 13.4% de la industria y México como 7mo mayor productor con el 4.6%. (VDA,2023)

Tomando ésto en cuenta sabemos que el rol de México en la industria automotriz es de suma relevancia para el mundo y por consiguiente para nuestro país, representando el 2.77% del Producto Interno Bruto (PIB) de México en el 2022. (INEGI,2023)

La pandemia tuvo un impacto fuerte en la inversión extranjera directa de la industria automotriz con una reducción de 2.17 mil millones de dólares del 2020 al 2021 y naturalmente se vio afectada la producción de vehículos con una disminución de producción de 3.8 millones de unidades a 2.9 millones de unidades al año 2020. Sin embargo, se estima que la recuperación de la producción de la industria automotriz será hasta el 2026 con 3.8 millones de unidades a producir, igualando la producción del 2019. (IHS Market, 2020)

Socio Formador Form

Introducción de la Empresa

FORM es una empresa con sede principal en Nuevo León, ésta se dedica al empaque y embalaje de autopartes específicamente de partes interiores y eléctricas de los vehículos, las cuales es de suma importancia que no reciban ningún tipo de daño estético en su proceso de transportación para su ensamblaje.

FORM se centra en abastecer las necesidades de los proveedores Tier 1 (planta automotriz) y Tier 2 (proveen partes a las plantas) de la industria automotriz, por lo que estos son sus principales clientes.

Productos o Servicios - Propuesta de Valor

La empresa no ofrece un portafolio de productos fijos o estandarizados para la industria automotriz. FORM busca generar soluciones a las necesidades y problemas de sus clientes dentro de la cadena de suministro, por medio de la innovación ingenieril en el empaque de las autopartes.

Además, FORM ofrece un servicio de acompañamiento el cual funciona como un soporte de comunicación en el que empleados de FORM, pueden asistir directamente en la planta de los clientes para la entrega de los empaques y ensamblaje hasta tener comunicación continua con la empresa en caso de cualquier situación.

Las cosas antes mencionadas forman parte de la propuesta de valor de la empresa, apalancando de la innovación y el servicio al cliente se busca asegurar la calidad la cual los clientes de FORM están buscando debido a la importancia y delicadeza que toman las autopartes interiores y eléctricas dentro de la industria automotriz.

Aunque los productos que ofrece FORM dentro de la industria automotriz fungen parecido a un commodity, el empaque se llega a producir en grandes cantidades, estos no entran como tal en la definición de commodity ya que en el caso de FORM entra una parte clave la cual es la personalización.

Perspectivas Futuras

Actualmente FORM busca equipar con tecnología para automatizar y desarrollar todo un ambiente de datos el cual les pueda ayudar a agilizar procesos y dar certeza a la toma de decisiones en base a datos. Con esto buscan poder realizar pronósticos para anticipar la demanda de sus clientes y diversificar dentro de EUA, esto por mencionar alguno de los ejemplos. En cuanto a temas de cultura organizacional se busca medir sistemáticamente diferentes KPI´s.

Además de esto, se busca crear un sentido de pertenencia y lealtad de los empleados hacia la empresa. Buscando continuar con la cultura organizacional actual, la cual está enfocada en la horizontalidad, la construcción de equipos y divisiones autónomas a niveles inferiores dentro de la empresa. Esto, con el fin de permitir una comunicación más efectiva y fluida entre departamentos.

Expansión

Actualmente FORM busca un crecimiento, desea continuar con la industria de autopartes, por lo que su principal enfoque se encuentra en crecer a lo largo de la línea de la industria automotriz que se encuentra ubicada en el territorio mexicano y estadounidense. Específicamente, busca crecer en el bajío mexicano y en San Antonio Texas en el extranjero. Por otra parte, busca explorar otras industrias las cuales se alineen a su misión, como lo puede ser la aeroespacial y de equipos médicos.

Además busca expandir sus inversiones en el extranjero tomando como opción principal a Estados Unidos. Buscando crecer a cualquier parte de Texas debido a el costo de oportunidad que se tiene, si se busca crecer más allá de Texas aumenta los costos de fletes y el negocio no sale con buen margen. FORM no busca ser la empresa mas grande, se concentra en negocios de PYME con grandes margenes de ganancia

Cultura organizacional y Recursos Humanos

Hoy en día cuentan con 130 colaboradores dentro de la empresa, sin embargo existe un tema de rotación de personal por diversas razones, uno de sus enfoques es crear una cultura organizacional la cual retenga al capital humano.

Actualmente ofrecen diversas compensaciones y beneficios para incitar la activa participación de sus colaboradores. Se cuentan con bases de datos enfocadas al tema de capital humano con las cuales se buscan identificar las razones de la rotación, sin embargo aún no han logrado ver un decremento en los porcentajes anuales de rotación.

FORM cuenta con 6 pilares principales, dentro de la empresa se vive una actitud de honestidad y transparencia dentro de todos los procesos, se busca cuidar detalladamente los espacios de trabajo con planes para implementar nuevos baños en el piso.

Análisis de las áreas de la empresa

Cargar librerias

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(stringr)
library(readr)
library(dplyr)
library(tidyr)
library(grid)
library(psych)
## 
## Attaching package: 'psych'
## 
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(gplots)
## 
## Attaching package: 'gplots'
## 
## The following object is masked from 'package:stats':
## 
##     lowess
library(knitr)

Cargar bases de datos

#file.choose()
Ventas_1 <- read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/Ventas_1.csv")

#file.choose()
Bajas <-read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/Bajas.csv")

#file.choose()
FDI_df <- read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/FDI_Mexico.csv")

Bajas por Puesto y Genero (2021) - Gráfico 1

Los ayudantes generales son los que cuentan mayor baja por un margén altamente considerable, como se puede observar en la grafíca 1. Además de esto se puede observar que de igual forma la mayoría de personas de está posición a las que se les da de baja son mujeres.

Por lo que se podría plantear una primer hipótesis la cual es que esto se puede deber a que la gran parte de personas que se contratan son para el puesto de ayudante general y de sexo femenino, sin embargo todavía no se ha realizado el análisis para comprobar la hipótesis antes mencionada.

options(scipen = 999) 
Bajas$PUESTO <- as.factor(Bajas$PUESTO)

ggplot(Bajas, aes(PUESTO)) +
  geom_bar(aes(fill=GENERO)) +
  theme(axis.text.x = element_text(angle = 90)) +
  labs(x = "Puesto", y = "Cantidad", title = "Bajas por puesto ") +
  theme(panel.background = element_rect(fill = "gray98"))

Ventas por Línea de Negocio (2021)

Dentro de las ventas por linea de negocio, es decir retornable y cartón. Se puede observar como la linea de negocios que liderá es la del cartón, sin embargo se observa como las ventas de retornables y cartón en los primeros 2 quartiles del año son altamente superiores al resto del año.

as.Date(Ventas_1$Mes)
##  [1] "0028-01-21" "0028-01-21" "0028-02-21" "0028-02-21" "0028-03-21"
##  [6] "0028-03-21" "0028-04-21" "0028-04-21" "0028-05-21" "0028-05-21"
## [11] "0028-06-21" "0028-06-21" "0028-07-21" "0028-07-21" "0028-08-21"
## [16] "0028-08-21" "0028-09-21" "0028-09-21" "0028-10-21" "0028-10-21"
## [21] "0028-11-21" "0028-11-21" "0028-12-21" "0028-12-21"
col_per <- c("coral", "orange")

ggplot(Ventas_1, aes(x = Mes, y = Venta, fill = Producto)) +
  geom_bar(stat = "identity") +
  labs(x = "Mes", y = "Venta", title = "Ventas Mensuales por Producto") +
  scale_fill_manual(values = col_per) + 
  theme(panel.background = element_rect(fill = "gray98") )+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Inversión Extranjera Directa a través de los Años

La Inversión Extranjera Directa en el mismo año (2021), tuvo fuertes afectaciones debido al COVID-19, por lo que podría ser una de las razones por las cuales en la Grafíca 2 las ventas de los ultímos 2 cuartiles del año hayan caído de manera considerable a comparación del inicio del año.

df_FDI = FDI_df

#Separar Columnas
df_FDI <- separate(df_FDI, Quartil, into = c("Quartil", "Año"), sep = " ")

#FDI sumado por Año
año_sum <- df_FDI %>% group_by(Año) %>% summarize(suma=sum(Mil.Millones.de.Dolares))

año_sum$Año <- as.numeric(año_sum$Año)

grafico_año = ggplot(año_sum, aes(x = Año, y = suma)) +
  geom_line( color = "#F46C22") +
  geom_point(color = "#F46C22") +
  geom_text(aes(label = suma), hjust = -0.2, vjust = 0.5, color = "#505050", size = 4) +  
  labs(title = "Inversión Extranjera Directa por Año",subtitle = "Mil Millones de Dólares", x = "Año", y = "Inversión", caption = "Fuente: INEGI") + 
  theme_minimal() + 
  theme(plot.title = element_text(hjust = 0.5, face = "bold", color = "#505050"), panel.grid.major =      element_blank(), plot.subtitle = element_text(hjust = .5, size = 7)) 

grafico_año + scale_x_continuous(breaks = año_sum$Año)

FODA Cruzado

El objetivo del análisis FODA para FORM es evaluar de manera integral sus Fortalezas, Oportunidades, Debilidades y Amenazas con el fin de obtener una comprensión estratégica de su posición en el mercado y proporcionar una base sólida para la toma de decisiones que potencien su competitividad y crecimiento en la industria de empaques y embalajes.

Entregable 2

¿Cuál es el Estado Civil con Mayores Bajas?

Con está pregunta se busca conocer un poco más acerca de los ex-empleados de FORM y buscar algunas

Abrir base de datos
# file.choose()
BDD_FORM_BAJAS_2023 <- read_csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/BDD_FORM_BAJAS_2023.csv")
## Rows: 279 Columns: 28
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (24): Apellidos, Nombre, Fecha de Nacimiento, Género, RFC, Fecha de Alta...
## dbl  (4): No., SD, CP, Número de Télefono
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
### Seleccionar las variables de Motivo de baja y Estado Civil en un nuevo data frame.

mbaja <- select(BDD_FORM_BAJAS_2023,`Motivo de Baja`,`Estado Civil`) %>% na.omit(mbaja)
Agrupar la categoría con diferentes nombres cambiando a el mismo nombre
mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida."] <- "Inducida"

mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida (Faltas)"] <- "Inducida por faltas"

mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida (Faltas no dio los tiempos)"] <- "Inducida"
Calcular los porcentajes por categoría y estado civil
porcentajes <- mbaja %>%
  group_by(`Estado Civil`, `Motivo de Baja`) %>%
  summarise(Frecuencia = n()) %>%
  group_by(`Estado Civil`) %>%
  mutate(Pct = scales::percent(Frecuencia / sum(Frecuencia)))
## `summarise()` has grouped output by 'Estado Civil'. You can override using the
## `.groups` argument.

Relación entre Motivo de Baja y Estado Civil

plot <- ggplot(porcentajes, aes(x = `Estado Civil`, y = Frecuencia, fill = `Motivo de Baja`)) +
  geom_bar(stat = "identity") +
  theme_minimal() +
  theme(
    panel.grid.major = element_line(color = "grey", linewidth = 0.4, linetype = "dotted"),  # Líneas verticales
    panel.grid.minor = element_line(color = "grey", linewidth = 0.4, linetype = "dotted")  # Líneas horizontales
  )+
  ggtitle("Relación entre Motivo de Baja y Estado Civil")
Agregar etiquetas de porcentaje
plot + geom_text(aes(label = Pct), position = position_stack(vjust = 0.5),size=2)

Resultados - Estados Civiles con Mayores Bajas

Por lo que podemos ver en la gráfica, la gran mayoría de las bajas en todas las categorías son por separación voluntaria y realmente no se logra ver una correlación entre el estado civil de la persona y el motivo de baja, lo que podría indicar una alta rotación de empleados en los trabajos de maquila en general o podría ser un indicador de que hay varias áreas de oportunidad en cuestión de amenidades, salarios, bonos, oportunidades de crecimiento en la empresa, traslado o prestaciones que la empresa ofrece además de las básicas dictadas por la ley.

¿Cuál es la relación entre la edad y las bajas?

Pregunta 2

Carga de datos
#file.choose()
bajas<-read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/form_bajas_22.csv")
Modificación de base de datos
#Estoy creando un data frame nuevo con las columnas necesarias para hacer la gráfica

bajas1 <- select(bajas,"NOMBRE","APELLIDOS","FECHA.DE.NACIMIENTO","DIAS.LABORADOS","SALARIO.DIARIO.IMSS") %>% na.omit(bajas1)
#view(bajas1)

Estadísiticos Descriptivos

Dias Laborados
summary(bajas1$`DIAS LABORADOS`)
## Length  Class   Mode 
##      0   NULL   NULL
Salario
summary(bajas1$`SALARIO DIARIO IMSS`)
## Length  Class   Mode 
##      0   NULL   NULL
Edad de colaboradores
#Aquí reviso que formato tienen las columnas 

str(bajas1)
## 'data.frame':    212 obs. of  5 variables:
##  $ NOMBRE             : chr  "MARIA FERNANDA" "EMANUEL" "TRINIDAD" "WILMAR" ...
##  $ APELLIDOS          : chr  "JIMENEZ ALANIS" "JAUREGUI SANCHEZ" "GARCIA CAZARES" "LOPEZ ROMERO" ...
##  $ FECHA.DE.NACIMIENTO: chr  "7/10/1998" "10/3/1998" "5/25/1997" "9/4/2001" ...
##  $ DIAS.LABORADOS     : int  423 35 102 63 34 23 30 6 0 141 ...
##  $ SALARIO.DIARIO.IMSS: num  177 181 181 177 181 ...
##  - attr(*, "na.action")= 'omit' Named int [1:26] 8 27 28 58 67 110 135 136 137 141 ...
##   ..- attr(*, "names")= chr [1:26] "8" "27" "28" "58" ...
#Aquí estoy haciendo una extracción del año de nacimiento excluyendo los días y meses. 

#Decidí hacer esto porque hay filas en las que está escrito M/D/A y otras D/M/A


bajas1$ANIO<-str_sub(bajas1$`FECHA.DE.NACIMIENTO`,-4,-1)

#Convirtiendo la columna de "ANIO" en integer

bajas1$ANIO <- as.integer(bajas1$ANIO)

str(bajas1)
## 'data.frame':    212 obs. of  6 variables:
##  $ NOMBRE             : chr  "MARIA FERNANDA" "EMANUEL" "TRINIDAD" "WILMAR" ...
##  $ APELLIDOS          : chr  "JIMENEZ ALANIS" "JAUREGUI SANCHEZ" "GARCIA CAZARES" "LOPEZ ROMERO" ...
##  $ FECHA.DE.NACIMIENTO: chr  "7/10/1998" "10/3/1998" "5/25/1997" "9/4/2001" ...
##  $ DIAS.LABORADOS     : int  423 35 102 63 34 23 30 6 0 141 ...
##  $ SALARIO.DIARIO.IMSS: num  177 181 181 177 181 ...
##  $ ANIO               : int  1998 1998 1997 2001 2002 2000 2000 1999 2002 1994 ...
##  - attr(*, "na.action")= 'omit' Named int [1:26] 8 27 28 58 67 110 135 136 137 141 ...
##   ..- attr(*, "names")= chr [1:26] "8" "27" "28" "58" ...
#Aquí creó una nueva columna llamada "EDAD" restando el año actual con el de "ANIO

bajas1$EDAD <- 2023-bajas1$ANIO

#Había un error en el cual existían tres filas que tenían edad de 1 por lo cual le pedí que solo mostrara los que son mayor a 18.

bajas1 <- bajas1[bajas1$EDAD >18,]

Bajas por Edad

hist(bajas1$EDAD,col = blues9,xlab = "Edad",ylab ="Frecuencia" ,main = "Bajas por Edad")

Relación entre la Edad y las Bajas

Nos damos cuenta de que la rotación de personal se ve más alta en los colaboradores más jóvenes. Esto es información útil ya que nos permite tomar decisiones adecuadas para mejorar la satisfacción laboral en específico para estos rangos de edades. Con esta gráfica podemos entrar más a detalle en el área de oportunidad y así entender las razones de la alta rotación. Nos damos cuenta de que se tiene que hacer un esfuerzo por mejorar la relación con las nuevas generaciones o contratar a personas mayores.

¿De qué edad frecuentan ingresar los empleados a FORM?

Pregunta 3

Carga de datos
rh <- read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/form_rh_datos.csv")

#View(rh)

edad <- select(rh,"FECHA.DE.ALTA", "FECHA.DE.NACIMIENTO") 

#str(rh)
Modificacion de Datos
rh$año_alta <- str_sub(rh$FECHA.DE.ALTA, -4, -1) 
rh$año_nac <- str_sub(rh$FECHA.DE.NACIMIENTO, -4, -1)
rh$año_alta <- as.integer(rh$año_alta)
rh$año_nac <- as.integer(rh$año_nac)

rh <- rh[rh$año_alta > 2013,]
rh <- rh[-30,]
Calcular la edad de ingreso y Medidas de Dispersion
rh$edad_ingreso <- rh$año_alta - rh$año_nac
rh <- rh[rh$edad_ingreso > 18,]

edad_de_ingreso_max <- max(rh$edad_ingreso)
print(edad_de_ingreso_max)
## [1] 60
edad_de_ingreso_min <- min(rh$edad_ingreso)
print(edad_de_ingreso_min)
## [1] 19
edad_de_ingreso_mean <- mean(rh$edad_ingreso)
print(edad_de_ingreso_mean)
## [1] 34.92308

Altas por Edad

hist(rh$edad_ingreso,col = "#009E73" ,xlab = "Edad",main = "Alta por Edad")

Cantidad de Hombres o Mujeres dados de Alta

ggplot(rh, aes(edad_ingreso, fill = GENERO)) + 
  geom_histogram(bins=10) + 
  labs(y="") 

Resultados - Relación Edad y genero en las Bajas de Empleados

Podemos analizar en las gráficas que la edad más común para ingresar a trabajar a FORM es entre los 25 - 30 lo que nos puede ayudar a crear campañas de reclutamiento enfocadas en el mercado de edad al que los empleados de FORM están enfocados, FORM cuenta con un gran rango de edades comenzando desde los 19 y llegando hasta los 60. Este último siendo el grupo más pequeño dentro de la empresa mientras que los jóvenes de 18 - 20 tienden a ser un porcentaje más alto de hombres. Nos damos cuenta con la gráfica que FORM le abre las puertas a muchas personas y ofrece oportunidades de trabajo para nuevas generaciones y personas con experiencia.

¿Existen tendencias de bajas?

Pregunta 3

Importar datasets

bajas = read.csv("C:/Users/lynet/OneDrive/Documents/Analítica 2023/form_bajas_22.csv")
dfbajas = bajas 

#Limpieza Dataset
bajas$ESTADO.CIVIL = gsub("MATRIOMONIO", "MATRIMONIO", bajas$ESTADO.CIVIL)

Frecuencia de Días Laborados

hist(bajas$DIAS.LABORADOS, col = blues9, xlab = "DIAS LABORADOS", ylab = "Frecuencia", main = "Días Laborados", xlim = c(0, 1000))

Separación de Fechas - Bajas

df_rotacion = bajas %>% select(GENERO, FECHA.DE.ALTA,BAJA, MOTIVO.DE.BAJA, DIAS.LABORADOS, PUESTO)
df_rotacion = df_rotacion %>% separate(BAJA, into = c("MONTH_BAJA", "DAY_BAJA", "YEAR_BAJA"), sep = "/")
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 15 rows [27, 28, 58, 135,
## 137, 141, 151, 178, 179, 198, 203, 205, 207, 212, 238].
Separación de Fechas - Altas
df_rotacion = df_rotacion %>% separate(FECHA.DE.ALTA, into = c("MONTH_ALTA", "DAY_ALTA", "YEAR_ALTA"), sep = "/")
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 1 rows [238].
Asignación Meses
df_months <- df_rotacion %>%
  mutate(NAME_MONTH = case_when(
    MONTH_BAJA == 1 ~ "Enero",
    MONTH_BAJA == 2 ~ "Febrero",
    MONTH_BAJA == 3 ~ "Marzo",
    MONTH_BAJA == 4 ~ "Abril",
    MONTH_BAJA == 5 ~ "Mayo",
    MONTH_BAJA == 6 ~ "Junio",
    MONTH_BAJA == 7 ~ "Julio",
    MONTH_BAJA == 8 ~ "Agosto",
    MONTH_BAJA == 9 ~ "Septiembre",
    MONTH_BAJA == 10 ~ "Octubre",
    MONTH_BAJA == 11 ~ "Noviembre",
    MONTH_BAJA == 12 ~ "Diciembre"
  )) %>%
  filter(NAME_MONTH %in% c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")) %>%
  select(GENERO, MONTH_BAJA, DAY_ALTA, YEAR_ALTA, MOTIVO.DE.BAJA, NAME_MONTH, PUESTO)

Cantidad de Bajas por Mes

barplot_subcategory <- ggplot(df_months, aes(x = NAME_MONTH)) +
  geom_bar(fill = "#F46C22", width = 0.5) +
  ggtitle("Bajas por Mes")

barplot_subcategory +
  labs(title = "Bajas por Mes") +
  theme(panel.grid = element_blank(),panel.background = element_blank(), plot.title = element_text(hjust = 0.5, face = "bold")) + xlab("Meses") +
  ylab("Cantidad de Bajas")

Cantidad de Bajas por Puesto

frequency_puesto = table(df_months$PUESTO)
df_frequency_puesto = as.data.frame(frequency_puesto)
colnames(df_frequency_puesto) <- c("Puesto", "Cantidad")

df_frequency_puesto <- df_frequency_puesto %>%
  arrange(desc(Cantidad))

kable(df_frequency_puesto, format = "html", escape = FALSE, 
      table.attr = 'style="font-family: Arial, sans-serif;"')
Puesto Cantidad
AYUDANTE GENERAL 170
SOLDADOR 12
COSTURA 10
AYUDANTE DE EMBARQUES 7
MONTACARGUISTA 5
INSPECTOR CALIDAD 3
RESIDENTE 3
MATERIALISTA 2
ANALISTA DE NOMINAS 1
CHOFER 1
CORTADOR 1
DISEÑO 1
FACTURACION 1
GUARDIA SEGURIDAD 1
JEFE DE SEGURIDAD E HIGIENE 1
LIMPIEZA 1
MANTENIMIENTO 1
MARCADORA 1
SERVICIO AL CLIENTE 1

Resultados - Tendencias de Baja de Empleados

Analizando directamente la cantidad de bajas por mes podemos ver que existe una alta inclinación de bajas de empleados en su en el mes de Enero y en su contraparte Noviembre es el mes con menor número de bajas, al excluir el mes de Diciembre que no cuenta con ninguna baja registrada. Por lo que se plantea la hipótesis la cual FORM mencionó durante las sesiones de información general de la empresa, “Los empleados se quedan para recibir su aguinaldo/bono y después se van”, por lo que se puede mencionar una asociación de los datos pero todavía no una causalidad de los mismos.

Evidencia 1

Resumen de conferencia

Los conferenciantes que asistieron al aula compartieron sus experiencias sobre cómo la concentración en sus estudios fue de gran utilidad al iniciar la búsqueda de empleo. Lograron aplicar lo aprendido en la vida real, lo que añadió valor a sus currículums como recién egresados. Un ejemplo que presentaron fue el caso de la empresa “Envía Flores”, donde continuaron su desarrollo profesional mediante la realización de una maestría en el campo de la analítica de datos, lo que les permitió aportar más conocimiento a la empresa que los contrató.

Esta información se traduce en la importancia de tener un enfoque profesional claro, en el que desees seguir creciendo y desarrollándote como profesional, el cual permitirá mantenerte actualizado y evolucionar junto con tu área de interés en constante desarrollo y en constante cambio.

Análisis de gráficas

1:¿Cuál es el Estado Civil con Mayores Bajas?

Se observa que la mayoría significativa de las salidas de empleados en todas las categorías se deben a renuncias voluntarias. No se aprecia una correlación discernible entre el estado civil de los individuos y la razón de su partida. Este fenómeno podría sugerir una alta rotación de personal en el sector manufacturero en general, o bien, podría indicar la presencia de diversas áreas de mejora en términos de comodidades laborales, salarios, incentivos, oportunidades de desarrollo profesional, reubicación o beneficios adicionales proporcionados por la empresa, más allá de los requisitos legales establecidos.

2: ¿Cuál es la relación entre la edad y las bajas?

Observamos que la tasa de rotación de personal es más elevada entre los colaboradores más jóvenes. Esta información es de gran utilidad, ya que nos brinda la oportunidad de tomar decisiones pertinentes para mejorar la satisfacción laboral, especialmente en estos grupos de edad. A través de este gráfico, podemos profundizar en el análisis de las áreas que requieren mejoras y comprender las razones detrás de esta alta rotación. Es evidente que debemos esforzarnos en fortalecer las relaciones con las nuevas generaciones o considerar la contratación de empleados de mayor experiencia.

3: ¿De qué edad frecuentan ingresar los empleados a FORM?

La edad más frecuente para ingresar a trabajar en la empresa FORM se sitúa en el rango de 25 a 30 años. Esta información nos brinda la base para desarrollar campañas de reclutamiento dirigidas específicamente al segmento de edad al que se orientan los empleados de FORM. Cabe mencionar que la fuerza laboral de FORM abarca un amplio espectro de edades, desde los 19 hasta los 60 años. Sin embargo, el grupo de empleados mayores de 60 años constituye la minoría en la empresa, mientras que los jóvenes de 18 a 20 años representan un porcentaje significativamente mayor en el segmento masculino. Estos datos reflejan que FORM brinda oportunidades de empleo tanto a las nuevas generaciones como a personas con experiencia, lo que subraya su apertura a una diversidad de perfiles laborales.

4: ¿Existen tendencias de bajas?

Al analizar la cantidad de bajas por mes, se observa una marcada tendencia de disminución de empleados en enero, mientras que noviembre muestra el menor número de bajas, excluyendo diciembre, que no registra ninguna baja. En este contexto, surge la hipótesis mencionada por FORM durante las sesiones de información general de la empresa, que sugiere que los empleados permanecen en sus puestos para recibir su aguinaldo o bono antes de partir. Sin embargo, es importante destacar que esto implica una asociación de datos, pero aún no establece una causalidad definitiva.

Gráfica extra: ¿Qué relación existe entre las bajas de los colaboradores con su lugar de residencia?

Librerías

library(ggplot2)
library(tidyverse)
library(readxl)
library(dplyr)

Base de datos

Bajasform <- read_xlsx("C:\\Users\\lynet\\OneDrive\\Documents\\Analítica 2023\\Bajasform.xlsx")
bajascolab<-select(Bajasform,"Género", "Colonia", "Municipio")%>% na.omit(Bajasform)

#View(bajascolab)
str(bajascolab)
## tibble [279 × 3] (S3: tbl_df/tbl/data.frame)
##  $ Género   : chr [1:279] "Femenino" "Femenino" "Masculino" "Femenino" ...
##  $ Colonia  : chr [1:279] "Vivienda Digna" "Pueblo Nuevo" "Loma Linda" "Policia Auxiliar" ...
##  $ Municipio: chr [1:279] "Apodaca" "Apodaca" "Monterrey" "Guadalupe" ...

Gráfica barras

#plot(bajascolab$Colonia, col=pink,xlab="Municipio", ylab="Género",main="Bajas por localidad")

count(bajascolab, Género, sort = TRUE)
## # A tibble: 2 × 2
##   Género        n
##   <chr>     <int>
## 1 Femenino    149
## 2 Masculino   130
ggplot(bajascolab, aes(x=Municipio)) + 
  geom_bar(aes(fill= Género, colour=Género)) + 
  geom_text(stat="count", aes(label=..count..), vjust=-1)+ 
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Relación entre las bajas y su lugar de residencia.

Se analiza la relación entre las bajas y los municipios de residencia de los colaboradores. Esto podría ayudar a identificar si hay algún municipio en particular que tiene tasas de bajas más altas o más bajas en comparación con otros. En este caso, se observa que el 69.5% de las bajas son del municipio de Apodaca, lo cual representa una cantidad considerable al tomar en cuenta que al igual que representar su mayor cantidad de bajas, en el municipio con mayor cantidad de contrataciones. Por lo que FORM al implementar diversas estrategias, como lo es la consideración de que sus empleados no se encuentren a más de una toma de camión de distancia, no es lo suficiente para la retención del capital humano de este municipio.

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSAxIg0KYXV0aG9yOiAiTHluZXR0ZSBTb2xpcyBBMDE1NjIzODkiDQpkYXRlOiAiMjAyMy0wOS0xMiINCm91dHB1dDogDQogaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6ICJ5ZXRpIg0KLS0tDQoNCiFbIF0oQzovVXNlcnMvbHluZXQvT25lRHJpdmUvRG9jdW1lbnRzL0FuYWzDrXRpY2EgMjAyMy9sb2dvZm9ybS5wbmcpDQoNCiMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipFbnRyZWdhYmxlIDEqKg0KDQojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkFudGVjZWRlbnRlcyBkZSBsYSBlbXByZXNhKioNCg0KKipWaXNpw7NuOioqICDigJxFbiAyMDMzIHNlcmVtb3MgdW5hIGRlIGxhcyBjaW5jbyBtZWpvcmVzIGNvbXBhw7HDrWFzIGRlIE3DqXhpY28gcXVlIGdlbmVyYW4gdmFsb3IgZGVudHJvIGRlIGxhIGNhZGVuYSBkZSBzdW1pbmlzdHJvIGRlIGxhcyBpbmR1c3RyaWFzIHF1ZSBtw6FzIHZhbG9yYW4gbGEgZm9ybWEgZW4gbGEgcXVlIHNlIHByb3RlZ2VuIHkgdHJhc2xhZGFuIGxhcyBjb3Nhcy7igJ0gKEZvcm0sIDIwMjMpLg0KDQoqKk1pc2nDs246Kiog4oCcVHJhbnNmb3JtYXIgbnVlc3RybyBlbnRvcm5vIHkgcmVzb2x2ZXIgcmV0b3MgaW5kdXN0cmlhbGVzIGRlIG51ZXN0cm9zIGNsaWVudGVzIGEgdHJhdsOpcyBkZSBsYSBjb2xhYm9yYWNpw7NuLCBwcm92b2NhbmRvIG51ZXZhcyBvcG9ydHVuaWRhZGVzIHF1ZSBwb3RlbmNpYW4gbnVlc3RybyBtb2RlbG8gZGUgbmVnb2NpbywgcGFyYSBhbGNhbnphciBudWVzdHJvcyBpZGVhbGVzLuKAnSAoRm9ybSwgMjAyMykuIA0KDQojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkNvbnRleHRvIGRlIGxhIGluZHVzdHJpYSoqOg0KTGEgaW5kdXN0cmlhIGRlIGVtcGFxdWUgeSBlbWJhbGFqZSByZXByZXNlbnRhIHVuYSBwYXJ0ZSBlc2VuY2lhbCBkZWwgc2VjdG9yIGF1dG9tb3RyaXogeSBkZSBhdXRvcGFydGVzLCB5YSBxdWUgZXN0YSBpbmR1c3RyaWEgZXMgcGllemEgY2xhdmUgcGFyYSBnYXJhbnRpemFyIGxhIHByb3RlY2Npw7NuIHkgZW50cmVnYSBlZmljaWVudGUgZGUgbG9zIGNvbXBvbmVudGVzIGF1dG9tb3RyaWNlcyBlbiBzdXMgZGlmZXJlbnRlcyBmYXNlcyBkZW50cm8gZGUgbGEgY2FkZW5hIGRlIHN1bWluaXN0cm8gZGVsIHNlY3RvciBhdXRvbW90cml6LiANCg0KRW4gZWwgMjAyMiwgbGEgcHJvZHVjY2nDs24gZGUgYXV0b23Ds3ZpbGVzIGVuIGVsIG11bmRvIG1hbnRpZW5lIGEgRXN0YWRvcyBVbmlkb3MgY29tbyBlbCBzZWd1bmRvIG1heW9yIHByb2R1Y3RvciBkZSBhdXRvbcOzdmlsZXMgYWJhcmNhbmRvIGVsIDEzLjQlIGRlIGxhIGluZHVzdHJpYSAgeSBNw6l4aWNvIGNvbW8gN21vIG1heW9yIHByb2R1Y3RvciBjb24gZWwgNC42JS4gKFZEQSwyMDIzKSANCg0KVG9tYW5kbyDDqXN0byBlbiBjdWVudGEgc2FiZW1vcyBxdWUgZWwgcm9sIGRlIE3DqXhpY28gZW4gbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXogZXMgZGUgc3VtYSByZWxldmFuY2lhIHBhcmEgZWwgbXVuZG8geSBwb3IgY29uc2lndWllbnRlIHBhcmEgbnVlc3RybyBwYcOtcywgcmVwcmVzZW50YW5kbyBlbCAyLjc3JSBkZWwgUHJvZHVjdG8gSW50ZXJubyBCcnV0byAoUElCKSBkZSBNw6l4aWNvIGVuIGVsIDIwMjIuIChJTkVHSSwyMDIzKQ0KDQpMYSBwYW5kZW1pYSB0dXZvIHVuIGltcGFjdG8gZnVlcnRlIGVuIGxhIGludmVyc2nDs24gZXh0cmFuamVyYSBkaXJlY3RhIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IGNvbiB1bmEgcmVkdWNjacOzbiBkZSAyLjE3IG1pbCBtaWxsb25lcyBkZSBkw7NsYXJlcyBkZWwgMjAyMCBhbCAyMDIxIHkgbmF0dXJhbG1lbnRlIHNlIHZpbyBhZmVjdGFkYSBsYSBwcm9kdWNjacOzbiBkZSB2ZWjDrWN1bG9zIGNvbiB1bmEgZGlzbWludWNpw7NuIGRlIHByb2R1Y2Npw7NuIGRlICAzLjggbWlsbG9uZXMgZGUgdW5pZGFkZXMgYSAyLjkgbWlsbG9uZXMgZGUgdW5pZGFkZXMgYWwgYcOxbyAyMDIwLiBTaW4gZW1iYXJnbywgc2UgZXN0aW1hIHF1ZSBsYSByZWN1cGVyYWNpw7NuIGRlIGxhIHByb2R1Y2Npw7NuIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IHNlcsOhIGhhc3RhIGVsIDIwMjYgY29uIDMuOCBtaWxsb25lcyBkZSB1bmlkYWRlcyBhIHByb2R1Y2lyLCBpZ3VhbGFuZG8gbGEgcHJvZHVjY2nDs24gZGVsIDIwMTkuIChJSFMgTWFya2V0LCAyMDIwKSANCg0KIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipTb2NpbyBGb3JtYWRvciBGb3JtKioNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IEludHJvZHVjY2nDs24gZGUgbGEgRW1wcmVzYQ0KDQpGT1JNIGVzIHVuYSBlbXByZXNhIGNvbiBzZWRlIHByaW5jaXBhbCBlbiBOdWV2byBMZcOzbiwgw6lzdGEgc2UgZGVkaWNhIGFsIGVtcGFxdWUgeSBlbWJhbGFqZSBkZSBhdXRvcGFydGVzIGVzcGVjw61maWNhbWVudGUgZGUgcGFydGVzIGludGVyaW9yZXMgeSBlbMOpY3RyaWNhcyBkZSBsb3MgdmVow61jdWxvcywgbGFzIGN1YWxlcyBlcyBkZSBzdW1hIGltcG9ydGFuY2lhIHF1ZSBubyByZWNpYmFuIG5pbmfDum4gdGlwbyBkZSBkYcOxbyBlc3TDqXRpY28gZW4gc3UgcHJvY2VzbyBkZSB0cmFuc3BvcnRhY2nDs24gcGFyYSBzdSBlbnNhbWJsYWplLiANCg0KRk9STSBzZSBjZW50cmEgZW4gYWJhc3RlY2VyIGxhcyBuZWNlc2lkYWRlcyBkZSBsb3MgcHJvdmVlZG9yZXMgVGllciAxIChwbGFudGEgYXV0b21vdHJpeikgeSBUaWVyIDIgKHByb3ZlZW4gcGFydGVzIGEgbGFzIHBsYW50YXMpIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6LCBwb3IgbG8gcXVlIGVzdG9zIHNvbiBzdXMgcHJpbmNpcGFsZXMgY2xpZW50ZXMuDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqUHJvZHVjdG9zIG8gU2VydmljaW9zIC0gUHJvcHVlc3RhIGRlIFZhbG9yKg0KDQpMYSBlbXByZXNhIG5vIG9mcmVjZSB1biBwb3J0YWZvbGlvIGRlIHByb2R1Y3RvcyBmaWpvcyBvIGVzdGFuZGFyaXphZG9zIHBhcmEgbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXouIEZPUk0gYnVzY2EgZ2VuZXJhciBzb2x1Y2lvbmVzIGEgbGFzIG5lY2VzaWRhZGVzIHkgcHJvYmxlbWFzIGRlIHN1cyBjbGllbnRlcyBkZW50cm8gZGUgbGEgY2FkZW5hIGRlIHN1bWluaXN0cm8sIHBvciBtZWRpbyBkZSBsYSBpbm5vdmFjacOzbiBpbmdlbmllcmlsICBlbiBlbCBlbXBhcXVlIGRlIGxhcyBhdXRvcGFydGVzLiANCg0KQWRlbcOhcywgRk9STSBvZnJlY2UgdW4gc2VydmljaW8gZGUgYWNvbXBhw7FhbWllbnRvIGVsIGN1YWwgZnVuY2lvbmEgY29tbyB1biBzb3BvcnRlIGRlIGNvbXVuaWNhY2nDs24gZW4gZWwgcXVlIGVtcGxlYWRvcyBkZSBGT1JNLCAgcHVlZGVuIGFzaXN0aXIgZGlyZWN0YW1lbnRlIGVuIGxhIHBsYW50YSBkZSBsb3MgY2xpZW50ZXMgcGFyYSBsYSBlbnRyZWdhIGRlIGxvcyBlbXBhcXVlcyB5IGVuc2FtYmxhamUgaGFzdGEgdGVuZXIgY29tdW5pY2FjacOzbiBjb250aW51YSBjb24gbGEgZW1wcmVzYSBlbiBjYXNvIGRlIGN1YWxxdWllciBzaXR1YWNpw7NuLiANCg0KTGFzIGNvc2FzIGFudGVzIG1lbmNpb25hZGFzIGZvcm1hbiBwYXJ0ZSBkZSBsYSBwcm9wdWVzdGEgZGUgdmFsb3IgZGUgbGEgZW1wcmVzYSwgYXBhbGFuY2FuZG8gZGUgbGEgaW5ub3ZhY2nDs24geSBlbCBzZXJ2aWNpbyBhbCBjbGllbnRlIHNlIGJ1c2NhIGFzZWd1cmFyIGxhIGNhbGlkYWQgbGEgY3VhbCBsb3MgY2xpZW50ZXMgZGUgRk9STSBlc3TDoW4gYnVzY2FuZG8gZGViaWRvIGEgbGEgaW1wb3J0YW5jaWEgeSBkZWxpY2FkZXphIHF1ZSB0b21hbiBsYXMgYXV0b3BhcnRlcyBpbnRlcmlvcmVzIHkgZWzDqWN0cmljYXMgZGVudHJvIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6Lg0KDQpBdW5xdWUgbG9zIHByb2R1Y3RvcyBxdWUgb2ZyZWNlIEZPUk0gZGVudHJvIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IGZ1bmdlbiBwYXJlY2lkbyBhIHVuIGNvbW1vZGl0eSwgZWwgZW1wYXF1ZSBzZSBsbGVnYSBhIHByb2R1Y2lyIGVuIGdyYW5kZXMgY2FudGlkYWRlcywgZXN0b3Mgbm8gZW50cmFuIGNvbW8gdGFsIGVuIGxhIGRlZmluaWNpw7NuIGRlIGNvbW1vZGl0eSB5YSBxdWUgZW4gZWwgY2FzbyBkZSBGT1JNIGVudHJhIHVuYSBwYXJ0ZSBjbGF2ZSBsYSBjdWFsIGVzIGxhIHBlcnNvbmFsaXphY2nDs24uDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqUGVyc3BlY3RpdmFzIEZ1dHVyYXMqDQoNCkFjdHVhbG1lbnRlIEZPUk0gYnVzY2EgZXF1aXBhciBjb24gdGVjbm9sb2fDrWEgcGFyYSBhdXRvbWF0aXphciB5IGRlc2Fycm9sbGFyIHRvZG8gdW4gYW1iaWVudGUgZGUgZGF0b3MgZWwgY3VhbCBsZXMgcHVlZGEgYXl1ZGFyIGEgYWdpbGl6YXIgcHJvY2Vzb3MgeSBkYXIgY2VydGV6YSBhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyBlbiBiYXNlIGEgZGF0b3MuIENvbiBlc3RvIGJ1c2NhbiBwb2RlciByZWFsaXphciBwcm9uw7NzdGljb3MgcGFyYSBhbnRpY2lwYXIgbGEgZGVtYW5kYSBkZSBzdXMgY2xpZW50ZXMgeSBkaXZlcnNpZmljYXIgZGVudHJvIGRlIEVVQSwgZXN0byBwb3IgbWVuY2lvbmFyIGFsZ3VubyBkZSBsb3MgZWplbXBsb3MuICBFbiBjdWFudG8gYSB0ZW1hcyBkZSBjdWx0dXJhIG9yZ2FuaXphY2lvbmFsIHNlIGJ1c2NhIG1lZGlyIHNpc3RlbcOhdGljYW1lbnRlIGRpZmVyZW50ZXMgS1BJwrRzLiANCg0KDQpBZGVtw6FzIGRlIGVzdG8sIHNlIGJ1c2NhIGNyZWFyIHVuIHNlbnRpZG8gZGUgcGVydGVuZW5jaWEgeSBsZWFsdGFkIGRlIGxvcyBlbXBsZWFkb3MgaGFjaWEgbGEgZW1wcmVzYS4gQnVzY2FuZG8gY29udGludWFyIGNvbiBsYSBjdWx0dXJhIG9yZ2FuaXphY2lvbmFsIGFjdHVhbCwgbGEgY3VhbCBlc3TDoSBlbmZvY2FkYSBlbiBsYSBob3Jpem9udGFsaWRhZCwgbGEgY29uc3RydWNjacOzbiBkZSBlcXVpcG9zIHkgZGl2aXNpb25lcyBhdXTDs25vbWFzIGEgbml2ZWxlcyBpbmZlcmlvcmVzIGRlbnRybyBkZSBsYSBlbXByZXNhLiBFc3RvLCBjb24gZWwgZmluIGRlIHBlcm1pdGlyIHVuYSBjb211bmljYWNpw7NuIG3DoXMgZWZlY3RpdmEgeSBmbHVpZGEgZW50cmUgZGVwYXJ0YW1lbnRvcy4NCiANCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqRXhwYW5zacOzbioNCg0KQWN0dWFsbWVudGUgRk9STSBidXNjYSB1biBjcmVjaW1pZW50bywgZGVzZWEgY29udGludWFyIGNvbiBsYSBpbmR1c3RyaWEgZGUgYXV0b3BhcnRlcywgcG9yIGxvIHF1ZSBzdSBwcmluY2lwYWwgZW5mb3F1ZSBzZSBlbmN1ZW50cmEgZW4gY3JlY2VyIGEgbG8gbGFyZ28gZGUgbGEgbMOtbmVhIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IHF1ZSBzZSBlbmN1ZW50cmEgdWJpY2FkYSBlbiBlbCB0ZXJyaXRvcmlvIG1leGljYW5vIHkgZXN0YWRvdW5pZGVuc2UuIEVzcGVjw61maWNhbWVudGUsIGJ1c2NhIGNyZWNlciBlbiBlbCBiYWrDrW8gbWV4aWNhbm8geSBlbiBTYW4gQW50b25pbyBUZXhhcyBlbiBlbCBleHRyYW5qZXJvLiBQb3Igb3RyYSBwYXJ0ZSwgYnVzY2EgZXhwbG9yYXIgb3RyYXMgaW5kdXN0cmlhcyBsYXMgY3VhbGVzIHNlIGFsaW5lZW4gYSBzdSBtaXNpw7NuLCBjb21vIGxvIHB1ZWRlIHNlciAgbGEgYWVyb2VzcGFjaWFsIHkgZGUgZXF1aXBvcyBtw6lkaWNvcy4gDQoNCkFkZW3DoXMgYnVzY2EgZXhwYW5kaXIgc3VzIGludmVyc2lvbmVzIGVuIGVsIGV4dHJhbmplcm8gdG9tYW5kbyBjb21vIG9wY2nDs24gcHJpbmNpcGFsIGEgRXN0YWRvcyBVbmlkb3MuIEJ1c2NhbmRvIGNyZWNlciBhIGN1YWxxdWllciBwYXJ0ZSBkZSBUZXhhcyBkZWJpZG8gYSBlbCBjb3N0byBkZSBvcG9ydHVuaWRhZCBxdWUgc2UgdGllbmUsIHNpIHNlIGJ1c2NhIGNyZWNlciBtw6FzIGFsbMOhIGRlIFRleGFzIGF1bWVudGEgbG9zIGNvc3RvcyBkZSBmbGV0ZXMgeSBlbCBuZWdvY2lvIG5vIHNhbGUgY29uIGJ1ZW4gbWFyZ2VuLiBGT1JNIG5vIGJ1c2NhIHNlciBsYSBlbXByZXNhIG1hcyBncmFuZGUsIHNlIGNvbmNlbnRyYSBlbiBuZWdvY2lvcyBkZSBQWU1FIGNvbiBncmFuZGVzIG1hcmdlbmVzIGRlIGdhbmFuY2lhDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqQ3VsdHVyYSBvcmdhbml6YWNpb25hbCB5IFJlY3Vyc29zIEh1bWFub3MqDQoNCkhveSBlbiBkw61hIGN1ZW50YW4gY29uIDEzMCBjb2xhYm9yYWRvcmVzIGRlbnRybyBkZSBsYSBlbXByZXNhLCBzaW4gZW1iYXJnbyBleGlzdGUgdW4gdGVtYSBkZSByb3RhY2nDs24gZGUgcGVyc29uYWwgcG9yIGRpdmVyc2FzIHJhem9uZXMsIHVubyBkZSBzdXMgZW5mb3F1ZXMgZXMgY3JlYXIgdW5hIGN1bHR1cmEgb3JnYW5pemFjaW9uYWwgbGEgY3VhbCByZXRlbmdhIGFsIGNhcGl0YWwgaHVtYW5vLiANCg0KQWN0dWFsbWVudGUgb2ZyZWNlbiBkaXZlcnNhcyBjb21wZW5zYWNpb25lcyB5IGJlbmVmaWNpb3MgcGFyYSBpbmNpdGFyIGxhIGFjdGl2YSBwYXJ0aWNpcGFjacOzbiBkZSBzdXMgY29sYWJvcmFkb3Jlcy4gU2UgY3VlbnRhbiBjb24gYmFzZXMgZGUgZGF0b3MgZW5mb2NhZGFzIGFsIHRlbWEgZGUgY2FwaXRhbCBodW1hbm8gY29uIGxhcyBjdWFsZXMgc2UgYnVzY2FuIGlkZW50aWZpY2FyIGxhcyByYXpvbmVzIGRlIGxhIHJvdGFjacOzbiwgc2luIGVtYmFyZ28gYcO6biBubyBoYW4gbG9ncmFkbyB2ZXIgdW4gZGVjcmVtZW50byBlbiBsb3MgcG9yY2VudGFqZXMgYW51YWxlcyBkZSByb3RhY2nDs24uDQoNCkZPUk0gY3VlbnRhIGNvbiA2IHBpbGFyZXMgcHJpbmNpcGFsZXMsIGRlbnRybyBkZSBsYSBlbXByZXNhIHNlIHZpdmUgdW5hIGFjdGl0dWQgZGUgaG9uZXN0aWRhZCB5IHRyYW5zcGFyZW5jaWEgZGVudHJvIGRlIHRvZG9zIGxvcyBwcm9jZXNvcywgc2UgYnVzY2EgY3VpZGFyIGRldGFsbGFkYW1lbnRlIGxvcyBlc3BhY2lvcyBkZSB0cmFiYWpvIGNvbiBwbGFuZXMgcGFyYSBpbXBsZW1lbnRhciBudWV2b3MgYmHDsW9zIGVuIGVsIHBpc28uDQoNCiMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqQW7DoWxpc2lzIGRlIGxhcyDDoXJlYXMgZGUgbGEgZW1wcmVzYSoqDQoNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICpDYXJnYXIgbGlicmVyaWFzKg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoZ3JpZCkNCmxpYnJhcnkocHN5Y2gpDQpsaWJyYXJ5KGdwbG90cykNCmxpYnJhcnkoa25pdHIpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICpDYXJnYXIgYmFzZXMgZGUgZGF0b3MqDQpgYGB7cn0NCg0KI2ZpbGUuY2hvb3NlKCkNClZlbnRhc18xIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL1ZlbnRhc18xLmNzdiIpDQoNCiNmaWxlLmNob29zZSgpDQpCYWphcyA8LXJlYWQuY3N2KCJDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL0JhamFzLmNzdiIpDQoNCiNmaWxlLmNob29zZSgpDQpGRElfZGYgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL2x5bmV0L09uZURyaXZlL0RvY3VtZW50cy9BbmFsw610aWNhIDIwMjMvRkRJX01leGljby5jc3YiKQ0KDQpgYGANCg0KDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqQmFqYXMgcG9yIFB1ZXN0byB5IEdlbmVybyAoMjAyMSkgLSBHcsOhZmljbyAxKg0KTG9zIGF5dWRhbnRlcyBnZW5lcmFsZXMgc29uIGxvcyBxdWUgY3VlbnRhbiBtYXlvciBiYWphIHBvciB1biBtYXJnw6luIGFsdGFtZW50ZSBjb25zaWRlcmFibGUsIGNvbW8gc2UgcHVlZGUgb2JzZXJ2YXIgZW4gbGEgZ3JhZsOtY2EgMS4gQWRlbcOhcyBkZSBlc3RvIHNlIHB1ZWRlIG9ic2VydmFyIHF1ZSBkZSBpZ3VhbCBmb3JtYSBsYSBtYXlvcsOtYSBkZSBwZXJzb25hcyBkZSBlc3TDoSBwb3NpY2nDs24gYSBsYXMgcXVlIHNlIGxlcyBkYSBkZSBiYWphIHNvbiBtdWplcmVzLiANCg0KUG9yIGxvIHF1ZSBzZSBwb2Ryw61hIHBsYW50ZWFyIHVuYSBwcmltZXIgaGlww7N0ZXNpcyBsYSBjdWFsIGVzIHF1ZSBlc3RvIHNlIHB1ZWRlIGRlYmVyIGEgcXVlIGxhIGdyYW4gcGFydGUgZGUgcGVyc29uYXMgcXVlIHNlIGNvbnRyYXRhbiBzb24gcGFyYSBlbCBwdWVzdG8gZGUgYXl1ZGFudGUgZ2VuZXJhbCB5IGRlIHNleG8gZmVtZW5pbm8sIHNpbiBlbWJhcmdvIHRvZGF2w61hIG5vIHNlIGhhIHJlYWxpemFkbyBlbCBhbsOhbGlzaXMgcGFyYSBjb21wcm9iYXIgbGEgaGlww7N0ZXNpcyBhbnRlcyBtZW5jaW9uYWRhLiANCg0KYGBge3J9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgDQpCYWphcyRQVUVTVE8gPC0gYXMuZmFjdG9yKEJhamFzJFBVRVNUTykNCg0KZ2dwbG90KEJhamFzLCBhZXMoUFVFU1RPKSkgKw0KICBnZW9tX2JhcihhZXMoZmlsbD1HRU5FUk8pKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnMoeCA9ICJQdWVzdG8iLCB5ID0gIkNhbnRpZGFkIiwgdGl0bGUgPSAiQmFqYXMgcG9yIHB1ZXN0byAiKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmF5OTgiKSkNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKlZlbnRhcyBwb3IgTMOtbmVhIGRlIE5lZ29jaW8gKDIwMjEpKg0KRGVudHJvIGRlIGxhcyB2ZW50YXMgcG9yIGxpbmVhIGRlIG5lZ29jaW8sIGVzIGRlY2lyIHJldG9ybmFibGUgeSBjYXJ0w7NuLiBTZSBwdWVkZSBvYnNlcnZhciBjb21vIGxhIGxpbmVhIGRlIG5lZ29jaW9zIHF1ZSBsaWRlcsOhIGVzIGxhIGRlbCBjYXJ0w7NuLCBzaW4gZW1iYXJnbyBzZSBvYnNlcnZhIGNvbW8gbGFzIHZlbnRhcyBkZSByZXRvcm5hYmxlcyB5IGNhcnTDs24gZW4gbG9zIHByaW1lcm9zIDIgcXVhcnRpbGVzIGRlbCBhw7FvIHNvbiBhbHRhbWVudGUgc3VwZXJpb3JlcyBhbCByZXN0byBkZWwgYcOxby4gDQoNCmBgYHtyfQ0KYXMuRGF0ZShWZW50YXNfMSRNZXMpDQoNCmNvbF9wZXIgPC0gYygiY29yYWwiLCAib3JhbmdlIikNCg0KZ2dwbG90KFZlbnRhc18xLCBhZXMoeCA9IE1lcywgeSA9IFZlbnRhLCBmaWxsID0gUHJvZHVjdG8pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIGxhYnMoeCA9ICJNZXMiLCB5ID0gIlZlbnRhIiwgdGl0bGUgPSAiVmVudGFzIE1lbnN1YWxlcyBwb3IgUHJvZHVjdG8iKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbF9wZXIpICsgDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJncmF5OTgiKSApKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgYSB0cmF2w6lzIGRlIGxvcyBBw7FvcyoNCkxhIEludmVyc2nDs24gRXh0cmFuamVyYSAgRGlyZWN0YSBlbiBlbCBtaXNtbyBhw7FvICgyMDIxKSwgdHV2byBmdWVydGVzIGFmZWN0YWNpb25lcyBkZWJpZG8gYWwgQ09WSUQtMTksIHBvciBsbyBxdWUgcG9kcsOtYSBzZXIgdW5hIGRlIGxhcyByYXpvbmVzIHBvciBsYXMgY3VhbGVzIGVuIGxhIEdyYWbDrWNhIDIgbGFzIHZlbnRhcyBkZSBsb3MgdWx0w61tb3MgMiBjdWFydGlsZXMgZGVsIGHDsW8gaGF5YW4gY2HDrWRvIGRlIG1hbmVyYSBjb25zaWRlcmFibGUgYSBjb21wYXJhY2nDs24gZGVsIGluaWNpbyBkZWwgYcOxby4gDQoNCmBgYHtyfQ0KZGZfRkRJID0gRkRJX2RmDQoNCiNTZXBhcmFyIENvbHVtbmFzDQpkZl9GREkgPC0gc2VwYXJhdGUoZGZfRkRJLCBRdWFydGlsLCBpbnRvID0gYygiUXVhcnRpbCIsICJBw7FvIiksIHNlcCA9ICIgIikNCg0KI0ZESSBzdW1hZG8gcG9yIEHDsW8NCmHDsW9fc3VtIDwtIGRmX0ZESSAlPiUgZ3JvdXBfYnkoQcOxbykgJT4lIHN1bW1hcml6ZShzdW1hPXN1bShNaWwuTWlsbG9uZXMuZGUuRG9sYXJlcykpDQoNCmHDsW9fc3VtJEHDsW8gPC0gYXMubnVtZXJpYyhhw7FvX3N1bSRBw7FvKQ0KDQpncmFmaWNvX2HDsW8gPSBnZ3Bsb3QoYcOxb19zdW0sIGFlcyh4ID0gQcOxbywgeSA9IHN1bWEpKSArDQogIGdlb21fbGluZSggY29sb3IgPSAiI0Y0NkMyMiIpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICIjRjQ2QzIyIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3VtYSksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjUsIGNvbG9yID0gIiM1MDUwNTAiLCBzaXplID0gNCkgKyAgDQogIGxhYnModGl0bGUgPSAiSW52ZXJzacOzbiBFeHRyYW5qZXJhIERpcmVjdGEgcG9yIEHDsW8iLHN1YnRpdGxlID0gIk1pbCBNaWxsb25lcyBkZSBEw7NsYXJlcyIsIHggPSAiQcOxbyIsIHkgPSAiSW52ZXJzacOzbiIsIGNhcHRpb24gPSAiRnVlbnRlOiBJTkVHSSIpICsgDQogIHRoZW1lX21pbmltYWwoKSArIA0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiLCBjb2xvciA9ICIjNTA1MDUwIiksIHBhbmVsLmdyaWQubWFqb3IgPSAgICAgIGVsZW1lbnRfYmxhbmsoKSwgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41LCBzaXplID0gNykpIA0KDQpncmFmaWNvX2HDsW8gKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYcOxb19zdW0kQcOxbykNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqRk9EQSBDcnV6YWRvKg0KRWwgb2JqZXRpdm8gZGVsIGFuw6FsaXNpcyBGT0RBIHBhcmEgRk9STSBlcyBldmFsdWFyIGRlIG1hbmVyYSBpbnRlZ3JhbCBzdXMgRm9ydGFsZXphcywgT3BvcnR1bmlkYWRlcywgRGViaWxpZGFkZXMgeSBBbWVuYXphcyBjb24gZWwgZmluIGRlIG9idGVuZXIgdW5hIGNvbXByZW5zacOzbiBlc3RyYXTDqWdpY2EgZGUgc3UgcG9zaWNpw7NuIGVuIGVsIG1lcmNhZG8geSBwcm9wb3JjaW9uYXIgdW5hIGJhc2Ugc8OzbGlkYSBwYXJhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyBxdWUgcG90ZW5jaWVuIHN1IGNvbXBldGl0aXZpZGFkIHkgY3JlY2ltaWVudG8gZW4gbGEgaW5kdXN0cmlhIGRlIGVtcGFxdWVzIHkgZW1iYWxhamVzLg0KDQohW10oQzovVXNlcnMvbHluZXQvT25lRHJpdmUvRG9jdW1lbnRzL0FuYWzDrXRpY2EgMjAyMy9mb2RhIGZvcm0ucG5nKQ0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKlBFU1RMRSoNCkVsIG9iamV0aXZvIGRlbCBhbsOhbGlzaXMgUEVTVExFIHBhcmEgRk9STSBlcyBleGFtaW5hciBsb3MgZmFjdG9yZXMgcXVlIGltcGFjdGFuIHN1IG9wZXJhY2nDs24geSBlbnRvcm5vIGVtcHJlc2FyaWFsLiBFc3RvIHBlcm1pdGlyw6EgYSBsYSBlbXByZXNhIGNvbXByZW5kZXIgbWVqb3IgZWwgY29udGV4dG8gZW4gZWwgcXVlIG9wZXJhLCBhbnRpY2lwYXIgcG9zaWJsZXMgY2FtYmlvcyB5IGFqdXN0YXIgc3UgZXN0cmF0ZWdpYSBwYXJhIG1heGltaXphciBvcG9ydHVuaWRhZGVzIHkgbWl0aWdhciByaWVzZ29zLg0KDQohWyBdKEM6L1VzZXJzL2x5bmV0L09uZURyaXZlL0RvY3VtZW50cy9BbmFsw610aWNhIDIwMjMvcGVzdGxlIGZvcm0ucG5nKQ0KIVsgXShDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL3Blc3RsZSBmb3JtMi5wbmcpDQoNCmh0dHBzOi8vd3d3LmVjb25vbWlhLmdvYi5teC9kYXRhbWV4aWNvL2VzL3Byb2ZpbGUvaW5kdXN0cnkvY29udmVydGVkLXBhcGVyLXByb2R1Y3QtbWFudWZhY3R1cmluZw0KDQpodHRwczovL3d3dy5lbGVjb25vbWlzdGEuY29tLm14L2VzdGFkb3MvSW5kdXN0cmlhLWRlLWF1dG9wYXJ0ZXMtcHJldmUtY3JlY2ltaWVudG8tZGUtNS1lbi0yMDIzLTIwMjMwNTMxLTAwODEuaHRtbCANCg0KaHR0cHM6Ly8wLXd3dy1zdGF0aXN0YS1jb20uYmlibGlvdGVjYS1pbHMudGVjLm14L3N0YXRpc3RpY3MvMjc3MDU1L2dsb2JhbC1tYXJrZXQtc2hhcmUtb2YtcmVnaW9ucy1vbi1hdXRvLXByb2R1Y3Rpb24vDQoNCmh0dHBzOi8vd3d3LnN0YXRpc3RhLmNvbS9zdGF0aXN0aWNzLzg5ODk1NS9tZXhpY28tbW90b3ItdmVoaWNsZS1wcm9kdWN0aW9uLWJyYW5kLw0KDQpodHRwczovL3d3dy52ZGEuZGUvZW4vbmV3cy9mYWN0cy1hbmQtZmlndXJlcy9hbm51YWwtZmlndXJlcy9hdXRvbW9iaWxlLXByb2R1Y3Rpb24pDQoNCmh0dHBzOi8vd3d3LmVjb25vbWlhLmdvYi5teC9kYXRhbWV4aWNvL2VzL3Byb2ZpbGUvcHJvZHVjdC9ib3hlcy1jb3JydWdhdGVkLXBhcGVyYm9hcmQNCg0KIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkVudHJlZ2FibGUgMioqDQoNCiMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqwr9DdcOhbCBlcyBlbCBFc3RhZG8gQ2l2aWwgY29uIE1heW9yZXMgQmFqYXM/KiogDQoNCioqQ29uIGVzdMOhIHByZWd1bnRhIHNlIGJ1c2NhIGNvbm9jZXIgdW4gcG9jbyBtw6FzIGFjZXJjYSBkZSBsb3MgZXgtZW1wbGVhZG9zIGRlIEZPUk0geSBidXNjYXIgYWxndW5hcyAgKioNCg0KIyMjIyMgQWJyaXIgYmFzZSBkZSBkYXRvcw0KDQpgYGB7cn0NCiMgZmlsZS5jaG9vc2UoKQ0KQkREX0ZPUk1fQkFKQVNfMjAyMyA8LSByZWFkX2NzdigiQzovVXNlcnMvbHluZXQvT25lRHJpdmUvRG9jdW1lbnRzL0FuYWzDrXRpY2EgMjAyMy9CRERfRk9STV9CQUpBU18yMDIzLmNzdiIpDQoNCiMjIyBTZWxlY2Npb25hciBsYXMgdmFyaWFibGVzIGRlIE1vdGl2byBkZSBiYWphIHkgRXN0YWRvIENpdmlsIGVuIHVuIG51ZXZvIGRhdGEgZnJhbWUuDQoNCm1iYWphIDwtIHNlbGVjdChCRERfRk9STV9CQUpBU18yMDIzLGBNb3Rpdm8gZGUgQmFqYWAsYEVzdGFkbyBDaXZpbGApICU+JSBuYS5vbWl0KG1iYWphKQ0KYGBgDQoNCiMjIyMjIEFncnVwYXIgbGEgY2F0ZWdvcsOtYSBjb24gZGlmZXJlbnRlcyBub21icmVzIGNhbWJpYW5kbyBhIGVsIG1pc21vIG5vbWJyZQ0KYGBge3J9DQoNCm1iYWphJCJNb3Rpdm8gZGUgQmFqYSJbbWJhamEkIk1vdGl2byBkZSBCYWphIiA9PSAiSW5kdWNpZGEuIl0gPC0gIkluZHVjaWRhIg0KDQptYmFqYSQiTW90aXZvIGRlIEJhamEiW21iYWphJCJNb3Rpdm8gZGUgQmFqYSIgPT0gIkluZHVjaWRhIChGYWx0YXMpIl0gPC0gIkluZHVjaWRhIHBvciBmYWx0YXMiDQoNCm1iYWphJCJNb3Rpdm8gZGUgQmFqYSJbbWJhamEkIk1vdGl2byBkZSBCYWphIiA9PSAiSW5kdWNpZGEgKEZhbHRhcyBubyBkaW8gbG9zIHRpZW1wb3MpIl0gPC0gIkluZHVjaWRhIg0KYGBgDQoNCiMjIyMjIENhbGN1bGFyIGxvcyBwb3JjZW50YWplcyBwb3IgY2F0ZWdvcsOtYSB5IGVzdGFkbyBjaXZpbA0KYGBge3J9DQpwb3JjZW50YWplcyA8LSBtYmFqYSAlPiUNCiAgZ3JvdXBfYnkoYEVzdGFkbyBDaXZpbGAsIGBNb3Rpdm8gZGUgQmFqYWApICU+JQ0KICBzdW1tYXJpc2UoRnJlY3VlbmNpYSA9IG4oKSkgJT4lDQogIGdyb3VwX2J5KGBFc3RhZG8gQ2l2aWxgKSAlPiUNCiAgbXV0YXRlKFBjdCA9IHNjYWxlczo6cGVyY2VudChGcmVjdWVuY2lhIC8gc3VtKEZyZWN1ZW5jaWEpKSkNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gUmVsYWNpw7NuIGVudHJlIE1vdGl2byBkZSBCYWphIHkgRXN0YWRvIENpdmlsDQoNCmBgYHtyfQ0KcGxvdCA8LSBnZ3Bsb3QocG9yY2VudGFqZXMsIGFlcyh4ID0gYEVzdGFkbyBDaXZpbGAsIHkgPSBGcmVjdWVuY2lhLCBmaWxsID0gYE1vdGl2byBkZSBCYWphYCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5IiwgbGluZXdpZHRoID0gMC40LCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSwgICMgTMOtbmVhcyB2ZXJ0aWNhbGVzDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmV5IiwgbGluZXdpZHRoID0gMC40LCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSAgIyBMw61uZWFzIGhvcml6b250YWxlcw0KICApKw0KICBnZ3RpdGxlKCJSZWxhY2nDs24gZW50cmUgTW90aXZvIGRlIEJhamEgeSBFc3RhZG8gQ2l2aWwiKQ0KDQpgYGANCg0KIyMjIyMgQWdyZWdhciBldGlxdWV0YXMgZGUgcG9yY2VudGFqZQ0KYGBge3J9DQpwbG90ICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFBjdCksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLHNpemU9MikNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gUmVzdWx0YWRvcyAtIEVzdGFkb3MgQ2l2aWxlcyBjb24gTWF5b3JlcyBCYWphcw0KDQpQb3IgbG8gcXVlIHBvZGVtb3MgdmVyIGVuIGxhIGdyw6FmaWNhLCBsYSBncmFuIG1heW9yw61hIGRlIGxhcyBiYWphcyBlbiB0b2RhcyBsYXMgY2F0ZWdvcsOtYXMgc29uIHBvciBzZXBhcmFjacOzbiB2b2x1bnRhcmlhIHkgcmVhbG1lbnRlIG5vIHNlIGxvZ3JhIHZlciB1bmEgY29ycmVsYWNpw7NuIGVudHJlIGVsIGVzdGFkbyBjaXZpbCBkZSBsYSBwZXJzb25hIHkgZWwgbW90aXZvIGRlIGJhamEsIGxvIHF1ZSBwb2Ryw61hIGluZGljYXIgdW5hIGFsdGEgcm90YWNpw7NuIGRlIGVtcGxlYWRvcyBlbiBsb3MgdHJhYmFqb3MgZGUgbWFxdWlsYSBlbiBnZW5lcmFsIG8gcG9kcsOtYSBzZXIgdW4gaW5kaWNhZG9yIGRlIHF1ZSBoYXkgdmFyaWFzIMOhcmVhcyBkZSBvcG9ydHVuaWRhZCBlbiBjdWVzdGnDs24gZGUgYW1lbmlkYWRlcywgc2FsYXJpb3MsIGJvbm9zLCBvcG9ydHVuaWRhZGVzIGRlIGNyZWNpbWllbnRvIGVuIGxhIGVtcHJlc2EsIHRyYXNsYWRvIG8gcHJlc3RhY2lvbmVzIHF1ZSBsYSBlbXByZXNhIG9mcmVjZSBhZGVtw6FzIGRlIGxhcyBiw6FzaWNhcyBkaWN0YWRhcyBwb3IgbGEgbGV5Lg0KDQojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKsK/Q3XDoWwgZXMgbGEgcmVsYWNpw7NuIGVudHJlIGxhIGVkYWQgeSBsYXMgYmFqYXM/KioNCg0KKipQcmVndW50YSAyKioNCg0KIyMjIyMgQ2FyZ2EgZGUgZGF0b3MNCg0KYGBge3J9DQojZmlsZS5jaG9vc2UoKQ0KYmFqYXM8LXJlYWQuY3N2KCJDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL2Zvcm1fYmFqYXNfMjIuY3N2IikNCmBgYA0KDQoNCiMjIyMjICoqTW9kaWZpY2FjacOzbiBkZSBiYXNlIGRlIGRhdG9zKioNCg0KYGBge3J9DQoNCiNFc3RveSBjcmVhbmRvIHVuIGRhdGEgZnJhbWUgbnVldm8gY29uIGxhcyBjb2x1bW5hcyBuZWNlc2FyaWFzIHBhcmEgaGFjZXIgbGEgZ3LDoWZpY2ENCg0KYmFqYXMxIDwtIHNlbGVjdChiYWphcywiTk9NQlJFIiwiQVBFTExJRE9TIiwiRkVDSEEuREUuTkFDSU1JRU5UTyIsIkRJQVMuTEFCT1JBRE9TIiwiU0FMQVJJTy5ESUFSSU8uSU1TUyIpICU+JSBuYS5vbWl0KGJhamFzMSkNCiN2aWV3KGJhamFzMSkNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gRXN0YWTDrXNpdGljb3MgRGVzY3JpcHRpdm9zDQoNCiMjIyMjIERpYXMgTGFib3JhZG9zDQpgYGB7cn0NCnN1bW1hcnkoYmFqYXMxJGBESUFTIExBQk9SQURPU2ApDQpgYGANCiMjIyMjIFNhbGFyaW8NCmBgYHtyfQ0Kc3VtbWFyeShiYWphczEkYFNBTEFSSU8gRElBUklPIElNU1NgKQ0KYGBgDQoNCiMjIyMjIEVkYWQgZGUgY29sYWJvcmFkb3Jlcw0KDQpgYGB7cn0NCg0KI0FxdcOtIHJldmlzbyBxdWUgZm9ybWF0byB0aWVuZW4gbGFzIGNvbHVtbmFzIA0KDQpzdHIoYmFqYXMxKQ0KDQpgYGANCg0KYGBge3J9DQoNCiNBcXXDrSBlc3RveSBoYWNpZW5kbyB1bmEgZXh0cmFjY2nDs24gZGVsIGHDsW8gZGUgbmFjaW1pZW50byBleGNsdXllbmRvIGxvcyBkw61hcyB5IG1lc2VzLiANCg0KI0RlY2lkw60gaGFjZXIgZXN0byBwb3JxdWUgaGF5IGZpbGFzIGVuIGxhcyBxdWUgZXN0w6EgZXNjcml0byBNL0QvQSB5IG90cmFzIEQvTS9BDQoNCg0KYmFqYXMxJEFOSU88LXN0cl9zdWIoYmFqYXMxJGBGRUNIQS5ERS5OQUNJTUlFTlRPYCwtNCwtMSkNCg0KI0NvbnZpcnRpZW5kbyBsYSBjb2x1bW5hIGRlICJBTklPIiBlbiBpbnRlZ2VyDQoNCmJhamFzMSRBTklPIDwtIGFzLmludGVnZXIoYmFqYXMxJEFOSU8pDQoNCnN0cihiYWphczEpDQpgYGANCmBgYHtyfQ0KDQoNCiNBcXXDrSBjcmXDsyB1bmEgbnVldmEgY29sdW1uYSBsbGFtYWRhICJFREFEIiByZXN0YW5kbyBlbCBhw7FvIGFjdHVhbCBjb24gZWwgZGUgIkFOSU8NCg0KYmFqYXMxJEVEQUQgPC0gMjAyMy1iYWphczEkQU5JTw0KDQojSGFiw61hIHVuIGVycm9yIGVuIGVsIGN1YWwgZXhpc3TDrWFuIHRyZXMgZmlsYXMgcXVlIHRlbsOtYW4gZWRhZCBkZSAxIHBvciBsbyBjdWFsIGxlIHBlZMOtIHF1ZSBzb2xvIG1vc3RyYXJhIGxvcyBxdWUgc29uIG1heW9yIGEgMTguDQoNCmJhamFzMSA8LSBiYWphczFbYmFqYXMxJEVEQUQgPjE4LF0NCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gQmFqYXMgcG9yIEVkYWQNCg0KYGBge3J9DQpoaXN0KGJhamFzMSRFREFELGNvbCA9IGJsdWVzOSx4bGFiID0gIkVkYWQiLHlsYWIgPSJGcmVjdWVuY2lhIiAsbWFpbiA9ICJCYWphcyBwb3IgRWRhZCIpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IFJlbGFjacOzbiBlbnRyZSBsYSBFZGFkIHkgbGFzIEJhamFzDQoNCk5vcyBkYW1vcyBjdWVudGEgZGUgcXVlIGxhIHJvdGFjacOzbiBkZSBwZXJzb25hbCBzZSB2ZSBtw6FzIGFsdGEgZW4gbG9zIGNvbGFib3JhZG9yZXMgbcOhcyBqw7N2ZW5lcy4gRXN0byBlcyBpbmZvcm1hY2nDs24gw7p0aWwgeWEgcXVlIG5vcyBwZXJtaXRlIHRvbWFyIGRlY2lzaW9uZXMgYWRlY3VhZGFzIHBhcmEgbWVqb3JhciBsYSBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwgZW4gZXNwZWPDrWZpY28gcGFyYSBlc3RvcyByYW5nb3MgZGUgZWRhZGVzLiBDb24gZXN0YSBncsOhZmljYSBwb2RlbW9zIGVudHJhciBtw6FzIGEgZGV0YWxsZSBlbiBlbCDDoXJlYSBkZSBvcG9ydHVuaWRhZCB5IGFzw60gZW50ZW5kZXIgbGFzIHJhem9uZXMgZGUgbGEgYWx0YSByb3RhY2nDs24uIE5vcyBkYW1vcyBjdWVudGEgZGUgcXVlIHNlIHRpZW5lIHF1ZSBoYWNlciB1biBlc2Z1ZXJ6byBwb3IgbWVqb3JhciBsYSByZWxhY2nDs24gY29uIGxhcyBudWV2YXMgZ2VuZXJhY2lvbmVzIG8gY29udHJhdGFyIGEgcGVyc29uYXMgbWF5b3Jlcy4gDQoNCiMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqwr9EZSBxdcOpIGVkYWQgZnJlY3VlbnRhbiBpbmdyZXNhciBsb3MgZW1wbGVhZG9zIGEgRk9STT8qKg0KDQoqKlByZWd1bnRhIDMqKg0KDQojIyMjIyBDYXJnYSBkZSBkYXRvcw0KYGBge3J9DQoNCnJoIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL2Zvcm1fcmhfZGF0b3MuY3N2IikNCg0KI1ZpZXcocmgpDQoNCmVkYWQgPC0gc2VsZWN0KHJoLCJGRUNIQS5ERS5BTFRBIiwgIkZFQ0hBLkRFLk5BQ0lNSUVOVE8iKSANCg0KI3N0cihyaCkNCmBgYA0KDQojIyMjIyBNb2RpZmljYWNpb24gZGUgRGF0b3MNCg0KYGBge3J9DQpyaCRhw7FvX2FsdGEgPC0gc3RyX3N1YihyaCRGRUNIQS5ERS5BTFRBLCAtNCwgLTEpIA0KcmgkYcOxb19uYWMgPC0gc3RyX3N1YihyaCRGRUNIQS5ERS5OQUNJTUlFTlRPLCAtNCwgLTEpDQpyaCRhw7FvX2FsdGEgPC0gYXMuaW50ZWdlcihyaCRhw7FvX2FsdGEpDQpyaCRhw7FvX25hYyA8LSBhcy5pbnRlZ2VyKHJoJGHDsW9fbmFjKQ0KDQpyaCA8LSByaFtyaCRhw7FvX2FsdGEgPiAyMDEzLF0NCnJoIDwtIHJoWy0zMCxdDQoNCmBgYA0KDQojIyMjIyBDYWxjdWxhciBsYSBlZGFkIGRlIGluZ3Jlc28geSBNZWRpZGFzIGRlIERpc3BlcnNpb24NCg0KYGBge3J9DQpyaCRlZGFkX2luZ3Jlc28gPC0gcmgkYcOxb19hbHRhIC0gcmgkYcOxb19uYWMNCnJoIDwtIHJoW3JoJGVkYWRfaW5ncmVzbyA+IDE4LF0NCg0KZWRhZF9kZV9pbmdyZXNvX21heCA8LSBtYXgocmgkZWRhZF9pbmdyZXNvKQ0KcHJpbnQoZWRhZF9kZV9pbmdyZXNvX21heCkNCg0KZWRhZF9kZV9pbmdyZXNvX21pbiA8LSBtaW4ocmgkZWRhZF9pbmdyZXNvKQ0KcHJpbnQoZWRhZF9kZV9pbmdyZXNvX21pbikNCg0KZWRhZF9kZV9pbmdyZXNvX21lYW4gPC0gbWVhbihyaCRlZGFkX2luZ3Jlc28pDQpwcmludChlZGFkX2RlX2luZ3Jlc29fbWVhbikNCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiBBbHRhcyBwb3IgRWRhZA0KYGBge3J9DQpoaXN0KHJoJGVkYWRfaW5ncmVzbyxjb2wgPSAiIzAwOUU3MyIgLHhsYWIgPSAiRWRhZCIsbWFpbiA9ICJBbHRhIHBvciBFZGFkIikNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gQ2FudGlkYWQgZGUgSG9tYnJlcyBvIE11amVyZXMgZGFkb3MgZGUgQWx0YQ0KYGBge3J9DQpnZ3Bsb3QocmgsIGFlcyhlZGFkX2luZ3Jlc28sIGZpbGwgPSBHRU5FUk8pKSArIA0KICBnZW9tX2hpc3RvZ3JhbShiaW5zPTEwKSArIA0KICBsYWJzKHk9IiIpIA0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiBSZXN1bHRhZG9zIC0gUmVsYWNpw7NuIEVkYWQgeSBnZW5lcm8gZW4gbGFzIEJhamFzIGRlIEVtcGxlYWRvcw0KDQpQb2RlbW9zIGFuYWxpemFyIGVuIGxhcyBncsOhZmljYXMgcXVlIGxhIGVkYWQgbcOhcyBjb23Dum4gcGFyYSBpbmdyZXNhciBhIHRyYWJhamFyIGEgRk9STSBlcyBlbnRyZSBsb3MgMjUgLSAzMCBsbyBxdWUgbm9zIHB1ZWRlIGF5dWRhciBhIGNyZWFyIGNhbXBhw7FhcyBkZSByZWNsdXRhbWllbnRvIGVuZm9jYWRhcyBlbiBlbCBtZXJjYWRvIGRlIGVkYWQgYWwgcXVlIGxvcyBlbXBsZWFkb3MgZGUgRk9STSBlc3TDoW4gZW5mb2NhZG9zLCBGT1JNIGN1ZW50YSBjb24gdW4gZ3JhbiByYW5nbyBkZSBlZGFkZXMgY29tZW56YW5kbyBkZXNkZSBsb3MgMTkgeSBsbGVnYW5kbyBoYXN0YSBsb3MgNjAuIEVzdGUgw7psdGltbyBzaWVuZG8gZWwgZ3J1cG8gbcOhcyBwZXF1ZcOxbyBkZW50cm8gZGUgbGEgZW1wcmVzYSBtaWVudHJhcyBxdWUgbG9zIGrDs3ZlbmVzIGRlIDE4IC0gMjAgdGllbmRlbiBhIHNlciB1biBwb3JjZW50YWplIG3DoXMgYWx0byBkZSBob21icmVzLiBOb3MgZGFtb3MgY3VlbnRhIGNvbiBsYSBncsOhZmljYSBxdWUgRk9STSBsZSBhYnJlIGxhcyBwdWVydGFzIGEgbXVjaGFzIHBlcnNvbmFzIHkgb2ZyZWNlIG9wb3J0dW5pZGFkZXMgZGUgdHJhYmFqbyBwYXJhIG51ZXZhcyBnZW5lcmFjaW9uZXMgeSBwZXJzb25hcyBjb24gZXhwZXJpZW5jaWEuICANCg0KIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKirCv0V4aXN0ZW4gdGVuZGVuY2lhcyBkZSBiYWphcz8qKg0KDQoqUHJlZ3VudGEgMyoNCg0KIyMjIyBJbXBvcnRhciBkYXRhc2V0cw0KYGBge3J9DQpiYWphcyA9IHJlYWQuY3N2KCJDOi9Vc2Vycy9seW5ldC9PbmVEcml2ZS9Eb2N1bWVudHMvQW5hbMOtdGljYSAyMDIzL2Zvcm1fYmFqYXNfMjIuY3N2IikNCmRmYmFqYXMgPSBiYWphcyANCg0KI0xpbXBpZXphIERhdGFzZXQNCmJhamFzJEVTVEFETy5DSVZJTCA9IGdzdWIoIk1BVFJJT01PTklPIiwgIk1BVFJJTU9OSU8iLCBiYWphcyRFU1RBRE8uQ0lWSUwpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICpGcmVjdWVuY2lhIGRlIETDrWFzIExhYm9yYWRvcyoNCmBgYHtyfQ0KaGlzdChiYWphcyRESUFTLkxBQk9SQURPUywgY29sID0gYmx1ZXM5LCB4bGFiID0gIkRJQVMgTEFCT1JBRE9TIiwgeWxhYiA9ICJGcmVjdWVuY2lhIiwgbWFpbiA9ICJEw61hcyBMYWJvcmFkb3MiLCB4bGltID0gYygwLCAxMDAwKSkNCmBgYA0KDQojIyMjIFNlcGFyYWNpw7NuIGRlIEZlY2hhcyAtIEJhamFzDQpgYGB7cn0NCmRmX3JvdGFjaW9uID0gYmFqYXMgJT4lIHNlbGVjdChHRU5FUk8sIEZFQ0hBLkRFLkFMVEEsQkFKQSwgTU9USVZPLkRFLkJBSkEsIERJQVMuTEFCT1JBRE9TLCBQVUVTVE8pDQpkZl9yb3RhY2lvbiA9IGRmX3JvdGFjaW9uICU+JSBzZXBhcmF0ZShCQUpBLCBpbnRvID0gYygiTU9OVEhfQkFKQSIsICJEQVlfQkFKQSIsICJZRUFSX0JBSkEiKSwgc2VwID0gIi8iKQ0KYGBgDQoNCiMjIyMjIFNlcGFyYWNpw7NuIGRlIEZlY2hhcyAtIEFsdGFzDQpgYGB7cn0NCmRmX3JvdGFjaW9uID0gZGZfcm90YWNpb24gJT4lIHNlcGFyYXRlKEZFQ0hBLkRFLkFMVEEsIGludG8gPSBjKCJNT05USF9BTFRBIiwgIkRBWV9BTFRBIiwgIllFQVJfQUxUQSIpLCBzZXAgPSAiLyIpDQpgYGANCg0KIyMjIyMgQXNpZ25hY2nDs24gTWVzZXMNCmBgYHtyfQ0KZGZfbW9udGhzIDwtIGRmX3JvdGFjaW9uICU+JQ0KICBtdXRhdGUoTkFNRV9NT05USCA9IGNhc2Vfd2hlbigNCiAgICBNT05USF9CQUpBID09IDEgfiAiRW5lcm8iLA0KICAgIE1PTlRIX0JBSkEgPT0gMiB+ICJGZWJyZXJvIiwNCiAgICBNT05USF9CQUpBID09IDMgfiAiTWFyem8iLA0KICAgIE1PTlRIX0JBSkEgPT0gNCB+ICJBYnJpbCIsDQogICAgTU9OVEhfQkFKQSA9PSA1IH4gIk1heW8iLA0KICAgIE1PTlRIX0JBSkEgPT0gNiB+ICJKdW5pbyIsDQogICAgTU9OVEhfQkFKQSA9PSA3IH4gIkp1bGlvIiwNCiAgICBNT05USF9CQUpBID09IDggfiAiQWdvc3RvIiwNCiAgICBNT05USF9CQUpBID09IDkgfiAiU2VwdGllbWJyZSIsDQogICAgTU9OVEhfQkFKQSA9PSAxMCB+ICJPY3R1YnJlIiwNCiAgICBNT05USF9CQUpBID09IDExIH4gIk5vdmllbWJyZSIsDQogICAgTU9OVEhfQkFKQSA9PSAxMiB+ICJEaWNpZW1icmUiDQogICkpICU+JQ0KICBmaWx0ZXIoTkFNRV9NT05USCAlaW4lIGMoIkVuZXJvIiwgIkZlYnJlcm8iLCAiTWFyem8iLCAiQWJyaWwiLCAiTWF5byIsICJKdW5pbyIsICJKdWxpbyIsICJBZ29zdG8iLCAiU2VwdGllbWJyZSIsICJPY3R1YnJlIiwgIk5vdmllbWJyZSIsICJEaWNpZW1icmUiKSkgJT4lDQogIHNlbGVjdChHRU5FUk8sIE1PTlRIX0JBSkEsIERBWV9BTFRBLCBZRUFSX0FMVEEsIE1PVElWTy5ERS5CQUpBLCBOQU1FX01PTlRILCBQVUVTVE8pDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICpDYW50aWRhZCBkZSBCYWphcyBwb3IgTWVzKg0KYGBge3J9DQpiYXJwbG90X3N1YmNhdGVnb3J5IDwtIGdncGxvdChkZl9tb250aHMsIGFlcyh4ID0gTkFNRV9NT05USCkpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICIjRjQ2QzIyIiwgd2lkdGggPSAwLjUpICsNCiAgZ2d0aXRsZSgiQmFqYXMgcG9yIE1lcyIpDQoNCmJhcnBsb3Rfc3ViY2F0ZWdvcnkgKw0KICBsYWJzKHRpdGxlID0gIkJhamFzIHBvciBNZXMiKSArDQogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkscGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgZmFjZSA9ICJib2xkIikpICsgeGxhYigiTWVzZXMiKSArDQogIHlsYWIoIkNhbnRpZGFkIGRlIEJhamFzIikNCg0KYGBgDQoNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICpDYW50aWRhZCBkZSBCYWphcyBwb3IgUHVlc3RvKg0KYGBge3J9DQpmcmVxdWVuY3lfcHVlc3RvID0gdGFibGUoZGZfbW9udGhzJFBVRVNUTykNCmRmX2ZyZXF1ZW5jeV9wdWVzdG8gPSBhcy5kYXRhLmZyYW1lKGZyZXF1ZW5jeV9wdWVzdG8pDQpjb2xuYW1lcyhkZl9mcmVxdWVuY3lfcHVlc3RvKSA8LSBjKCJQdWVzdG8iLCAiQ2FudGlkYWQiKQ0KDQpkZl9mcmVxdWVuY3lfcHVlc3RvIDwtIGRmX2ZyZXF1ZW5jeV9wdWVzdG8gJT4lDQogIGFycmFuZ2UoZGVzYyhDYW50aWRhZCkpDQoNCmthYmxlKGRmX2ZyZXF1ZW5jeV9wdWVzdG8sIGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRkFMU0UsIA0KICAgICAgdGFibGUuYXR0ciA9ICdzdHlsZT0iZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOyInKQ0KDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IFJlc3VsdGFkb3MgLSBUZW5kZW5jaWFzIGRlIEJhamEgZGUgRW1wbGVhZG9zDQoNCkFuYWxpemFuZG8gZGlyZWN0YW1lbnRlIGxhIGNhbnRpZGFkIGRlIGJhamFzIHBvciBtZXMgcG9kZW1vcyB2ZXIgcXVlIGV4aXN0ZSB1bmEgYWx0YSBpbmNsaW5hY2nDs24gZGUgYmFqYXMgZGUgZW1wbGVhZG9zIGVuIHN1IGVuIGVsIG1lcyBkZSBFbmVybyB5IGVuIHN1IGNvbnRyYXBhcnRlIE5vdmllbWJyZSBlcyBlbCBtZXMgY29uIG1lbm9yIG7Dum1lcm8gZGUgYmFqYXMsIGFsIGV4Y2x1aXIgZWwgbWVzIGRlIERpY2llbWJyZSBxdWUgbm8gY3VlbnRhIGNvbiBuaW5ndW5hIGJhamEgcmVnaXN0cmFkYS4gUG9yIGxvIHF1ZSBzZSBwbGFudGVhIGxhIGhpcMOzdGVzaXMgbGEgY3VhbCBGT1JNIG1lbmNpb27DsyBkdXJhbnRlIGxhcyBzZXNpb25lcyBkZSBpbmZvcm1hY2nDs24gZ2VuZXJhbCBkZSBsYSBlbXByZXNhLCDigJxMb3MgZW1wbGVhZG9zIHNlIHF1ZWRhbiBwYXJhIHJlY2liaXIgc3UgYWd1aW5hbGRvL2Jvbm8geSBkZXNwdcOpcyBzZSB2YW7igJ0sIHBvciBsbyBxdWUgc2UgcHVlZGUgbWVuY2lvbmFyIHVuYSBhc29jaWFjacOzbiBkZSBsb3MgZGF0b3MgcGVybyB0b2RhdsOtYSBubyB1bmEgY2F1c2FsaWRhZCBkZSBsb3MgbWlzbW9zLiANCg0KIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkV2aWRlbmNpYSAxKioNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqUmVzdW1lbiBkZSBjb25mZXJlbmNpYSoqDQoNCkxvcyBjb25mZXJlbmNpYW50ZXMgcXVlIGFzaXN0aWVyb24gYWwgYXVsYSBjb21wYXJ0aWVyb24gc3VzIGV4cGVyaWVuY2lhcyBzb2JyZSBjw7NtbyBsYSBjb25jZW50cmFjacOzbiBlbiBzdXMgZXN0dWRpb3MgZnVlIGRlIGdyYW4gdXRpbGlkYWQgYWwgaW5pY2lhciBsYSBiw7pzcXVlZGEgZGUgZW1wbGVvLiBMb2dyYXJvbiBhcGxpY2FyIGxvIGFwcmVuZGlkbyBlbiBsYSB2aWRhIHJlYWwsIGxvIHF1ZSBhw7FhZGnDsyB2YWxvciBhIHN1cyBjdXJyw61jdWx1bXMgY29tbyByZWNpw6luIGVncmVzYWRvcy4gVW4gZWplbXBsbyBxdWUgcHJlc2VudGFyb24gZnVlIGVsIGNhc28gZGUgbGEgZW1wcmVzYSAiRW52w61hIEZsb3JlcyIsIGRvbmRlIGNvbnRpbnVhcm9uIHN1IGRlc2Fycm9sbG8gcHJvZmVzaW9uYWwgbWVkaWFudGUgbGEgcmVhbGl6YWNpw7NuIGRlIHVuYSBtYWVzdHLDrWEgZW4gZWwgY2FtcG8gZGUgbGEgYW5hbMOtdGljYSBkZSBkYXRvcywgbG8gcXVlIGxlcyBwZXJtaXRpw7MgYXBvcnRhciBtw6FzIGNvbm9jaW1pZW50byBhIGxhIGVtcHJlc2EgcXVlIGxvcyBjb250cmF0w7MuDQoNCkVzdGEgaW5mb3JtYWNpw7NuIHNlIHRyYWR1Y2UgZW4gbGEgaW1wb3J0YW5jaWEgZGUgdGVuZXIgdW4gZW5mb3F1ZSBwcm9mZXNpb25hbCBjbGFybywgZW4gZWwgcXVlIGRlc2VlcyBzZWd1aXIgY3JlY2llbmRvIHkgZGVzYXJyb2xsw6FuZG90ZSBjb21vIHByb2Zlc2lvbmFsLCBlbCBjdWFsIHBlcm1pdGlyw6EgbWFudGVuZXJ0ZSBhY3R1YWxpemFkbyB5IGV2b2x1Y2lvbmFyIGp1bnRvIGNvbiB0dSDDoXJlYSBkZSBpbnRlcsOpcyBlbiBjb25zdGFudGUgZGVzYXJyb2xsbyB5IGVuIGNvbnN0YW50ZSBjYW1iaW8uDQoNCg0KIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipBbsOhbGlzaXMgZGUgZ3LDoWZpY2FzKioNCg0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKioxOsK/Q3XDoWwgZXMgZWwgRXN0YWRvIENpdmlsIGNvbiBNYXlvcmVzIEJhamFzPyAqKg0KDQpTZSBvYnNlcnZhIHF1ZSBsYSBtYXlvcsOtYSBzaWduaWZpY2F0aXZhIGRlIGxhcyBzYWxpZGFzIGRlIGVtcGxlYWRvcyBlbiB0b2RhcyBsYXMgY2F0ZWdvcsOtYXMgc2UgZGViZW4gYSByZW51bmNpYXMgdm9sdW50YXJpYXMuIE5vIHNlIGFwcmVjaWEgdW5hIGNvcnJlbGFjacOzbiBkaXNjZXJuaWJsZSBlbnRyZSBlbCBlc3RhZG8gY2l2aWwgZGUgbG9zIGluZGl2aWR1b3MgeSBsYSByYXrDs24gZGUgc3UgcGFydGlkYS4gRXN0ZSBmZW7Ds21lbm8gcG9kcsOtYSBzdWdlcmlyIHVuYSBhbHRhIHJvdGFjacOzbiBkZSBwZXJzb25hbCBlbiBlbCBzZWN0b3IgbWFudWZhY3R1cmVybyBlbiBnZW5lcmFsLCBvIGJpZW4sIHBvZHLDrWEgaW5kaWNhciBsYSBwcmVzZW5jaWEgZGUgZGl2ZXJzYXMgw6FyZWFzIGRlIG1lam9yYSBlbiB0w6lybWlub3MgZGUgY29tb2RpZGFkZXMgbGFib3JhbGVzLCBzYWxhcmlvcywgaW5jZW50aXZvcywgb3BvcnR1bmlkYWRlcyBkZSBkZXNhcnJvbGxvIHByb2Zlc2lvbmFsLCByZXViaWNhY2nDs24gbyBiZW5lZmljaW9zIGFkaWNpb25hbGVzIHByb3BvcmNpb25hZG9zIHBvciBsYSBlbXByZXNhLCBtw6FzIGFsbMOhIGRlIGxvcyByZXF1aXNpdG9zIGxlZ2FsZXMgZXN0YWJsZWNpZG9zLg0KDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKjI6IMK/Q3XDoWwgZXMgbGEgcmVsYWNpw7NuIGVudHJlIGxhIGVkYWQgeSBsYXMgYmFqYXM/ICoqDQoNCk9ic2VydmFtb3MgcXVlIGxhIHRhc2EgZGUgcm90YWNpw7NuIGRlIHBlcnNvbmFsIGVzIG3DoXMgZWxldmFkYSBlbnRyZSBsb3MgY29sYWJvcmFkb3JlcyBtw6FzIGrDs3ZlbmVzLiBFc3RhIGluZm9ybWFjacOzbiBlcyBkZSBncmFuIHV0aWxpZGFkLCB5YSBxdWUgbm9zIGJyaW5kYSBsYSBvcG9ydHVuaWRhZCBkZSB0b21hciBkZWNpc2lvbmVzIHBlcnRpbmVudGVzIHBhcmEgbWVqb3JhciBsYSBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwsIGVzcGVjaWFsbWVudGUgZW4gZXN0b3MgZ3J1cG9zIGRlIGVkYWQuIEEgdHJhdsOpcyBkZSBlc3RlIGdyw6FmaWNvLCBwb2RlbW9zIHByb2Z1bmRpemFyIGVuIGVsIGFuw6FsaXNpcyBkZSBsYXMgw6FyZWFzIHF1ZSByZXF1aWVyZW4gbWVqb3JhcyB5IGNvbXByZW5kZXIgbGFzIHJhem9uZXMgZGV0csOhcyBkZSBlc3RhIGFsdGEgcm90YWNpw7NuLiBFcyBldmlkZW50ZSBxdWUgZGViZW1vcyBlc2Zvcnphcm5vcyBlbiBmb3J0YWxlY2VyIGxhcyByZWxhY2lvbmVzIGNvbiBsYXMgbnVldmFzIGdlbmVyYWNpb25lcyBvIGNvbnNpZGVyYXIgbGEgY29udHJhdGFjacOzbiBkZSBlbXBsZWFkb3MgZGUgbWF5b3IgZXhwZXJpZW5jaWEuDQoNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqMzogwr9EZSBxdcOpIGVkYWQgZnJlY3VlbnRhbiBpbmdyZXNhciBsb3MgZW1wbGVhZG9zIGEgRk9STT8gKioNCg0KTGEgZWRhZCBtw6FzIGZyZWN1ZW50ZSBwYXJhIGluZ3Jlc2FyIGEgdHJhYmFqYXIgZW4gbGEgZW1wcmVzYSBGT1JNIHNlIHNpdMO6YSBlbiBlbCByYW5nbyBkZSAyNSBhIDMwIGHDsW9zLiBFc3RhIGluZm9ybWFjacOzbiBub3MgYnJpbmRhIGxhIGJhc2UgcGFyYSBkZXNhcnJvbGxhciBjYW1wYcOxYXMgZGUgcmVjbHV0YW1pZW50byBkaXJpZ2lkYXMgZXNwZWPDrWZpY2FtZW50ZSBhbCBzZWdtZW50byBkZSBlZGFkIGFsIHF1ZSBzZSBvcmllbnRhbiBsb3MgZW1wbGVhZG9zIGRlIEZPUk0uIENhYmUgbWVuY2lvbmFyIHF1ZSBsYSBmdWVyemEgbGFib3JhbCBkZSBGT1JNIGFiYXJjYSB1biBhbXBsaW8gZXNwZWN0cm8gZGUgZWRhZGVzLCBkZXNkZSBsb3MgMTkgaGFzdGEgbG9zIDYwIGHDsW9zLiBTaW4gZW1iYXJnbywgZWwgZ3J1cG8gZGUgZW1wbGVhZG9zIG1heW9yZXMgZGUgNjAgYcOxb3MgY29uc3RpdHV5ZSBsYSBtaW5vcsOtYSBlbiBsYSBlbXByZXNhLCBtaWVudHJhcyBxdWUgbG9zIGrDs3ZlbmVzIGRlIDE4IGEgMjAgYcOxb3MgcmVwcmVzZW50YW4gdW4gcG9yY2VudGFqZSBzaWduaWZpY2F0aXZhbWVudGUgbWF5b3IgZW4gZWwgc2VnbWVudG8gbWFzY3VsaW5vLiBFc3RvcyBkYXRvcyByZWZsZWphbiBxdWUgRk9STSBicmluZGEgb3BvcnR1bmlkYWRlcyBkZSBlbXBsZW8gdGFudG8gYSBsYXMgbnVldmFzIGdlbmVyYWNpb25lcyBjb21vIGEgcGVyc29uYXMgY29uIGV4cGVyaWVuY2lhLCBsbyBxdWUgc3VicmF5YSBzdSBhcGVydHVyYSBhIHVuYSBkaXZlcnNpZGFkIGRlIHBlcmZpbGVzIGxhYm9yYWxlcy4NCg0KDQojIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKio0OiDCv0V4aXN0ZW4gdGVuZGVuY2lhcyBkZSBiYWphcz8gKioNCg0KQWwgYW5hbGl6YXIgbGEgY2FudGlkYWQgZGUgYmFqYXMgcG9yIG1lcywgc2Ugb2JzZXJ2YSB1bmEgbWFyY2FkYSB0ZW5kZW5jaWEgZGUgZGlzbWludWNpw7NuIGRlIGVtcGxlYWRvcyBlbiBlbmVybywgbWllbnRyYXMgcXVlIG5vdmllbWJyZSBtdWVzdHJhIGVsIG1lbm9yIG7Dum1lcm8gZGUgYmFqYXMsIGV4Y2x1eWVuZG8gZGljaWVtYnJlLCBxdWUgbm8gcmVnaXN0cmEgbmluZ3VuYSBiYWphLiBFbiBlc3RlIGNvbnRleHRvLCBzdXJnZSBsYSBoaXDDs3Rlc2lzIG1lbmNpb25hZGEgcG9yIEZPUk0gZHVyYW50ZSBsYXMgc2VzaW9uZXMgZGUgaW5mb3JtYWNpw7NuIGdlbmVyYWwgZGUgbGEgZW1wcmVzYSwgcXVlIHN1Z2llcmUgcXVlIGxvcyBlbXBsZWFkb3MgcGVybWFuZWNlbiBlbiBzdXMgcHVlc3RvcyBwYXJhIHJlY2liaXIgc3UgYWd1aW5hbGRvIG8gYm9ubyBhbnRlcyBkZSBwYXJ0aXIuIFNpbiBlbWJhcmdvLCBlcyBpbXBvcnRhbnRlIGRlc3RhY2FyIHF1ZSBlc3RvIGltcGxpY2EgdW5hIGFzb2NpYWNpw7NuIGRlIGRhdG9zLCBwZXJvIGHDum4gbm8gZXN0YWJsZWNlIHVuYSBjYXVzYWxpZGFkIGRlZmluaXRpdmEuDQoNCg0KIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqR3LDoWZpY2EgZXh0cmE6IMK/UXXDqSByZWxhY2nDs24gZXhpc3RlIGVudHJlIGxhcyBiYWphcyBkZSBsb3MgY29sYWJvcmFkb3JlcyBjb24gc3UgbHVnYXIgZGUgcmVzaWRlbmNpYT8gKioNCg0KDQojIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IExpYnJlcsOtYXMNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KDQojIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IEJhc2UgZGUgZGF0b3MNCmBgYHtyfQ0KQmFqYXNmb3JtIDwtIHJlYWRfeGxzeCgiQzpcXFVzZXJzXFxseW5ldFxcT25lRHJpdmVcXERvY3VtZW50c1xcQW5hbMOtdGljYSAyMDIzXFxCYWphc2Zvcm0ueGxzeCIpDQpgYGANCg0KYGBge3J9DQpiYWphc2NvbGFiPC1zZWxlY3QoQmFqYXNmb3JtLCJHw6luZXJvIiwgIkNvbG9uaWEiLCAiTXVuaWNpcGlvIiklPiUgbmEub21pdChCYWphc2Zvcm0pDQoNCiNWaWV3KGJhamFzY29sYWIpDQpgYGANCg0KYGBge3J9DQpzdHIoYmFqYXNjb2xhYikNCmBgYA0KDQojIyMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+IEdyw6FmaWNhIGJhcnJhcw0KYGBge3J9DQojcGxvdChiYWphc2NvbGFiJENvbG9uaWEsIGNvbD1waW5rLHhsYWI9Ik11bmljaXBpbyIsIHlsYWI9IkfDqW5lcm8iLG1haW49IkJhamFzIHBvciBsb2NhbGlkYWQiKQ0KDQpjb3VudChiYWphc2NvbGFiLCBHw6luZXJvLCBzb3J0ID0gVFJVRSkNCg0KZ2dwbG90KGJhamFzY29sYWIsIGFlcyh4PU11bmljaXBpbykpICsgDQogIGdlb21fYmFyKGFlcyhmaWxsPSBHw6luZXJvLCBjb2xvdXI9R8OpbmVybykpICsgDQogIGdlb21fdGV4dChzdGF0PSJjb3VudCIsIGFlcyhsYWJlbD0uLmNvdW50Li4pLCB2anVzdD0tMSkrIA0KdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiBSZWxhY2nDs24gZW50cmUgbGFzIGJhamFzIHkgc3UgbHVnYXIgZGUgcmVzaWRlbmNpYS4gDQoNClNlIGFuYWxpemEgbGEgcmVsYWNpw7NuIGVudHJlIGxhcyBiYWphcyB5IGxvcyBtdW5pY2lwaW9zIGRlIHJlc2lkZW5jaWEgZGUgbG9zIGNvbGFib3JhZG9yZXMuIEVzdG8gcG9kcsOtYSBheXVkYXIgYSBpZGVudGlmaWNhciBzaSBoYXkgYWxnw7puIG11bmljaXBpbyBlbiBwYXJ0aWN1bGFyIHF1ZSB0aWVuZSB0YXNhcyBkZSBiYWphcyBtw6FzIGFsdGFzIG8gbcOhcyBiYWphcyBlbiBjb21wYXJhY2nDs24gY29uIG90cm9zLiBFbiBlc3RlIGNhc28sIHNlIG9ic2VydmEgcXVlIGVsIDY5LjUlIGRlIGxhcyBiYWphcyBzb24gZGVsIG11bmljaXBpbyBkZSBBcG9kYWNhLCBsbyBjdWFsIHJlcHJlc2VudGEgdW5hIGNhbnRpZGFkIGNvbnNpZGVyYWJsZSBhbCB0b21hciBlbiBjdWVudGEgcXVlIGFsIGlndWFsIHF1ZSByZXByZXNlbnRhciBzdSBtYXlvciBjYW50aWRhZCBkZSBiYWphcywgZW4gZWwgbXVuaWNpcGlvIGNvbiBtYXlvciBjYW50aWRhZCBkZSBjb250cmF0YWNpb25lcy4gUG9yIGxvIHF1ZSBGT1JNIGFsIGltcGxlbWVudGFyIGRpdmVyc2FzIGVzdHJhdGVnaWFzLCBjb21vIGxvIGVzIGxhIGNvbnNpZGVyYWNpw7NuIGRlIHF1ZSBzdXMgZW1wbGVhZG9zIG5vIHNlIGVuY3VlbnRyZW4gYSBtw6FzIGRlIHVuYSB0b21hIGRlIGNhbWnDs24gZGUgZGlzdGFuY2lhLCBubyBlcyBsbyBzdWZpY2llbnRlIHBhcmEgbGEgcmV0ZW5jacOzbiBkZWwgY2FwaXRhbCBodW1hbm8gZGUgZXN0ZSBtdW5pY2lwaW8uDQoNCiFbIF0oQzovVXNlcnMvbHluZXQvT25lRHJpdmUvRG9jdW1lbnRzL0FuYWzDrXRpY2EgMjAyMy9jb25jbHVzaW9uZXMucG5nKQ0KDQohWyBdKEM6L1VzZXJzL2x5bmV0L09uZURyaXZlL0RvY3VtZW50cy9BbmFsw610aWNhIDIwMjMvcmVjb21lbmRhY2lvbmVzLnBuZykNCg0KDQo=