# Evidencia. Etapa 1 ## Contexto El paquete nycflights13 contiene información sobre todos los vuelos que partieron desde New York (EWR, JFK y LGA) a destinos en los Estados Unidos en 2013. Fueron 336,776 vuelos en total. Para ayudar a comprender las causas de los retrasos, también incluye otros conjuntos de datos útiles.

Fuente:
Origen de los datos

Este paquete incluye las siguientes tablas:

  • flights = todos los vuelos que salieron de NY en 2013.
  • weather = datos meteorológicos por hora de cada aeropuerto.
  • planes = información de contrucción de cada avión.
  • airports = nombres y ubicaciones de aeropuertos.
  • airlines = relación entre nombres y códigos de las aerolineas.

Instalar paquetes y llamar librerías

# install.packages("nycflights13")
library(nycflights13)
# install.packages("tidyverse")
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── 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(dplyr)
library(dplyr)

Guardar base de datos

flights <- flights
weather <- weather
planes <- planes
airports <- airports
airlines <- airlines

Relación entre las bases de datos

1. Cargar en memoria la tabla “flights” y mostrar su contenido

# La carga a memoria se hizo en el paso anterior. 
flights 
## # A tibble: 336,776 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

2. Consulta la estructura de “flights”

str(flights)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day           : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
#int: entero (sin decimales)
#num: numérico (con decimales)
#cgr: caractér (letras)
#date: fecha (en R va año-mes-día)
#POSIXct: formato fecha y hora

3. ¿Cuál es la clase de “flights” y qué significa?

class(flights)
## [1] "tbl_df"     "tbl"        "data.frame"
#Las 5 clases de objetos son:
  # 1. numeric: número real o decimales.  
  # 2. integer: número entero.  
  # 3. complex: número complejo.
  # 4. character: caracteres, texto.
  # 5. logical: TRUE o FALSE.

# Las 4 clases de objetos compuestos son:  
  # 1. list: lista
  # 2. matrix: matriz
  # 3. array: colección de objetos
  # 4. data.frame: base de datos

4. ¿Cuántas columnas y renglones tiene “flights”? ¿Cuál es su dimensión?

#Número de columnas
ncol(flights)
## [1] 19
#Número de renglones
nrow(flights)
## [1] 336776
#Número de dimensión
dim(flights)
## [1] 336776     19

5. Muestra los primeros 6 renglones de “flights”, También los últimos 6

head(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     1     1      517            515         2      830            819
## 2  2013     1     1      533            529         4      850            830
## 3  2013     1     1      542            540         2      923            850
## 4  2013     1     1      544            545        -1     1004           1022
## 5  2013     1     1      554            600        -6      812            837
## 6  2013     1     1      554            558        -4      740            728
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
tail(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     9    30       NA           1842        NA       NA           2019
## 2  2013     9    30       NA           1455        NA       NA           1634
## 3  2013     9    30       NA           2200        NA       NA           2312
## 4  2013     9    30       NA           1210        NA       NA           1330
## 5  2013     9    30       NA           1159        NA       NA           1344
## 6  2013     9    30       NA            840        NA       NA           1020
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
#Si quisieramos 7 renglones: head(flights, 7)

6. Muestra los estadísticos descriptivos de “flights”

summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 

Conclusión

En este código podemos ver lo que es un conjunto de datos, el cual tiene información acerca de los vuelos que salen desde Nueva York en el año 2013. A través de la carga de paquetes y datos relevantes, iniciamos un proceso de comprensión y análisis. El resumen estadístico que se hizo revela cosas importantes sobre variables clave, como los tiempos de salida y llegada, así como los posibles retrasos de los aviones tanto de salida como de aterrizaje. Aquí es donde podemos ver los principales patrones de comportamiento, factores de influencia y áreas de interés sobre todos estos datos. Esto es sumamente fundamental para entender la naturaleza y el alcance de los datos que tenemos, ver qué podemos hacer con ellos y qué nos dicen hasta ahora.

Etapa2. Manipulación de Datos

1. Consulta el data frame flights para recordar su contenido.

view(flights)

2. Encuentra los datos descriptivos del data frame flights. Identifica la media de las distancias recorridas en millas.

summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 

La media de la distancia recorrida es de 1040 millas.

Data frame que filtre solamente a las aeorlíneas que han recorrido una distancia superior a la media, se desean ver los campos carrier, distance, origin, dest en forma descendente por distance.

aerolineas_distancia = select(flights, carrier, distance, origin, dest)
aerolineas_mayor_mean = filter(aerolineas_distancia, distance > 1040)
aerolineas_mayor_desc = arrange(aerolineas_mayor_mean, desc(distance))

Encuentra la suma y la media de las distancias recorridas por carrier, elimina los NA’S e interpreta que significa la suma y la media de las distancias recorridas.

distancias <- flights %>% group_by(carrier) %>%
summarize(suma = sum(distance, na.rm = TRUE), media = mean(distance, na.rm = TRUE))
distancias_orden <- arrange(distancias, desc(distancias))
print(distancias)
## # A tibble: 16 × 3
##    carrier     suma media
##    <chr>      <dbl> <dbl>
##  1 9E       9788152  530.
##  2 AA      43864584 1340.
##  3 AS       1715028 2402 
##  4 B6      58384137 1069.
##  5 DL      59507317 1237.
##  6 EV      30498951  563.
##  7 F9       1109700 1620 
##  8 FL       2167344  665.
##  9 HA       1704186 4983 
## 10 MQ      15033955  570.
## 11 OO         16026  501.
## 12 UA      89705524 1529.
## 13 US      11365778  553.
## 14 VX      12902327 2499.
## 15 WN      12229203  996.
## 16 YV        225395  375.

Resultados: Observando esta última tabla pudimos observar los datos que nos permiten ver cuales son las aerolineas más popluares en cada uno de los aeropuertos de Nueva York. También con el promedio obtenido podemos identificar cual es la distancia media recorrida por vuelo de cada compañía aérea. Este df nos permite ver que United Airlines es una de las aerolíneas con los viajes con mayor distancia. Tienen una suma total de 89705524. Sobre American Airlines, podemos observar que tienen una suma de 43864584 millas y un promedio de 1340.2360 millas.

Identifica si las aerolíneas líderes son las mismas en los tres aeropuertos cuyo origen es Nueva York ( John F. Kennedy (JFK), LaGuardia (LGA) and Newark Liberty (EWR) ).

JFK

JFK_flights <- flights %>%
  filter(origin == "JFK") %>%
  group_by(carrier) %>%
  summarise(total_flights = n())

# Identificar la aerolínea líder en JFK
JFK_leader <- JFK_flights %>%
  arrange(desc(total_flights)) %>%
  slice(1) %>%
  pull(carrier)

# Contar el número de vuelos por aerolínea para LGA
LGA_flights <- flights %>%
  filter(origin == "LGA") %>%
  group_by(carrier) %>%
  summarise(total_flights = n())

# Identificar la aerolínea líder en LGA
LGA_leader <- LGA_flights %>%
  arrange(desc(total_flights)) %>%
  slice(1) %>%
  pull(carrier)

# Contar el número de vuelos por aerolínea para EWR
EWR_flights <- flights %>%
  filter(origin == "EWR") %>%
  group_by(carrier) %>%
  summarise(total_flights = n())

# Identificar la aerolínea líder en EWR
EWR_leader <- EWR_flights %>%
  arrange(desc(total_flights)) %>%
  slice(1) %>%
  pull(carrier)

# Comparar las aerolíneas líderes en los tres aeropuertos
if (JFK_leader == LGA_leader && JFK_leader == EWR_leader) {
  cat("Las aerolíneas líderes son las mismas en los tres aeropuertos.")
} else {
  cat("Las aerolíneas líderes no son las mismas en los tres aeropuertos.")
}
## Las aerolíneas líderes no son las mismas en los tres aeropuertos.

En el aeropuerto de JFK, B6 JetBlue Airways es la aerolínea con mayor número de vuelos con un total de 19378.

LGA

LGA_flights <- flights %>%
  filter(origin == "LGA") %>%
  group_by(carrier) %>%
  summarise(total_flights = n())

# Identificar la aerolínea líder en LGA
LGA_leader <- LGA_flights %>%
  arrange(desc(total_flights)) %>%
  slice(1) %>%
  pull(carrier)

LGA_leader
## [1] "DL"

En la Guardia, American Airlines tiene la primera posicón con un total de 8781 en número de vuelos.

EWR

# Contar el número de vuelos por aerolínea para EWR
EWR_flights <- flights %>%
  filter(origin == "EWR") %>%
  group_by(carrier) %>%
  summarise(total_flights = n())

# Identificar la aerolínea líder en EWR
EWR_leader <- EWR_flights %>%
  arrange(desc(total_flights)) %>%
  slice(1) %>%
  pull(carrier)

EWR_leader
## [1] "UA"

En Newark Liberty International, United Airlines tiene el mayor número de vuelos con un total de 30183.

Conclusión

Evidencia 2 - Analítica descriptiva

Modelo Entidad-Relación

Consulta y explora el data frame planes y weather para que conozcas su contenido.

library(nycflights13)
library(dplyr)

view(planes)
view(weather)

Se necesita saber de cada vuelo, la aerolínea, el aeropuerto de origen y el aeropuerto destino.

summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 
vuelos <- select(flights, flight, carrier, origin, dest)
head(vuelos)
## # A tibble: 6 × 4
##   flight carrier origin dest 
##    <int> <chr>   <chr>  <chr>
## 1   1545 UA      EWR    IAH  
## 2   1714 UA      LGA    IAH  
## 3   1141 AA      JFK    MIA  
## 4    725 B6      JFK    BQN  
## 5    461 DL      LGA    ATL  
## 6   1696 UA      EWR    ORD

En la consulta anterior se necesita conocer el nombre de la aerolínea.

aerolinea <- vuelos %>% left_join(airlines, by = "carrier")

Se necesita saber la cantidad de vuelos por cada destino para identificar cuáles son los destinos más buscados.

# Contar el número de vuelos por cada destino
vuelos_por_destino <- flights %>%
  group_by(dest) %>%
  summarise(num_vuelos = n()) %>%
  arrange(desc(num_vuelos))

# Mostrar los destinos más buscados
head(vuelos_por_destino)
## # A tibble: 6 × 2
##   dest  num_vuelos
##   <chr>      <int>
## 1 ORD        17283
## 2 ATL        17215
## 3 LAX        16174
## 4 BOS        15508
## 5 MCO        14082
## 6 CLT        14064

Agregar el nombre de la aerolínea al data frame anterior.

nombre_aerolinea <- vuelos %>% left_join(airlines, by ="carrier")

Se necesita conocer las aerolíneas (clave y nombre) y destinos que vuelan por la Mañana: de 6 a 12, Tarde: de 12 a 19 , Noche: de 19 a 24 y Madrugada de 24 a 6.

horarios <- select(flights, carrier, dest, hour)
head(horarios)
## # A tibble: 6 × 3
##   carrier dest   hour
##   <chr>   <chr> <dbl>
## 1 UA      IAH       5
## 2 UA      IAH       5
## 3 AA      MIA       5
## 4 B6      BQN       5
## 5 DL      ATL       6
## 6 UA      ORD       5
#horarios$categoria <- if(flights$hour>=6 && hour<12)
#head(horarios)

Se necesita saber la cantidad de vuelos por aerolínea y destino que hay por la Mañana, Tarde, Noche y Madrugada.

# Definir función para clasificar los momentos del día
clasificar_momento_dia <- function(hora) {
  momento <- rep(NA, length(hora))
  momento[hora >= 5 & hora < 12] <- "Mañana"
  momento[hora >= 12 & hora < 18] <- "Tarde"
  momento[hora >= 18 & hora < 24] <- "Noche"
  momento[hora >= 0 & hora < 5] <- "Madrugada"
  return(momento)
}

Se necesita saber a qué destinos vuela la aerolínea American Airlines Inc.-AA durante la madrugada.

# Filtrar los vuelos de American Airlines Inc.-AA durante la madrugada
destinos_madrugada_AA <- flights %>%
  filter(carrier == "AA", hour >= 0 & hour < 5) %>%
  group_by(dest) %>%
  summarise(num_vuelos = n()) %>%
  arrange(desc(num_vuelos))

# Mostrar los destinos más comunes durante la madrugada para American Airlines Inc.-AA
destinos_madrugada_AA
## # A tibble: 0 × 2
## # ℹ 2 variables: dest <chr>, num_vuelos <int>

¿Qué aviones utiliza la aerolínea AA? aerolínea, tipo, motor y número de asientos y ¿Cuántos vuelos se han realizado con cada uno? elimina los NA’s

aviones_AA <- flights %>%
  filter(carrier == "AA") %>%
  left_join(planes, by = "tailnum") %>%
  select(carrier, type, engine, seats, tailnum) %>%
  na.omit() %>%
  group_by(type, engine, seats, tailnum) %>%
  summarise(num_vuelos = n()) %>%
  arrange(desc(num_vuelos))
## `summarise()` has grouped output by 'type', 'engine', 'seats'. You can override
## using the `.groups` argument.
# Mostrar la información sobre los aviones utilizados por la aerolínea AA
aviones_AA
## # A tibble: 171 × 5
## # Groups:   type, engine, seats [22]
##    type                    engine    seats tailnum num_vuelos
##    <chr>                   <chr>     <int> <chr>        <int>
##  1 Fixed wing multi engine Turbo-fan   255 N328AA         393
##  2 Fixed wing multi engine Turbo-fan   255 N338AA         388
##  3 Fixed wing multi engine Turbo-fan   255 N327AA         387
##  4 Fixed wing multi engine Turbo-fan   255 N335AA         385
##  5 Fixed wing multi engine Turbo-fan   255 N323AA         357
##  6 Fixed wing multi engine Turbo-fan   255 N319AA         354
##  7 Fixed wing multi engine Turbo-fan   255 N336AA         353
##  8 Fixed wing multi engine Turbo-fan   255 N329AA         344
##  9 Fixed wing multi engine Turbo-fan   255 N324AA         328
## 10 Fixed wing multi engine Turbo-fan   255 N332AA         328
## # ℹ 161 more rows

Visualización de datos

Se solicita analizar para la aerolínea American Airlines si los vuelos que tienen retraso en la partida también tienen retraso en la hora de llegada.

df13 <- flights %>% select(dep_delay, arr_delay)
summary(df13)
##    dep_delay         arr_delay       
##  Min.   : -43.00   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.: -17.000  
##  Median :  -2.00   Median :  -5.000  
##  Mean   :  12.64   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :1272.000  
##  NA's   :8255      NA's   :9430
ggplot() +
  geom_point(mapping = aes(x = dep_delay, y = arr_delay), data = df13) +
  geom_point(
    mapping = aes(x = dep_delay, y = arr_delay), data = df13,
    colour = 'pink', size = 1)
## Warning: Removed 9430 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Removed 9430 rows containing missing values or values outside the scale range
## (`geom_point()`).

Visualiza la tendencia de la temperatura durante los primeros 15 días del mes de Enero en los vuelos que parten del aeropuerto “Newark, EWR”, utilizar una gráfica de línea.

temp <- filter(weather, origin=="EWR")
tendencia_temp <- filter(temp, day <= 15)

plot(tendencia_temp$day, tendencia_temp$temp, type="p")

Visualiza la temperatura más frecuente en los primeros 15 días del mes de Enero, utilizar un histrograma.

ggplot(weather, aes(x = temp)) +
  geom_histogram(bins = 30, fill = "pink", color = "deeppink") +
  labs(title = "Histograma de la temperatura en Enero", x = "Temperatura (°F)", y = "Frecuencia")
## Warning: Removed 1 row containing non-finite outside the scale range
## (`stat_bin()`).

Utiliza Facets para observar cómo varía la temperatura en cada mes en él histograma del punto anterior

weather %>% 
  ggplot(aes(x = temp)) +
  geom_histogram(bins = 30) +
  facet_wrap(~month) +
  labs(title = "Temperatura por mes", x = "Temperatura (°F)", y = "Frecuencia")
## Warning: Removed 1 row containing non-finite outside the scale range
## (`stat_bin()`).

Número de vuelos que salieron de Nueva York en 2013 por aerolínea (mostrar solamente las 10 aerolíneas con más vuelos), utilizar gráfica de barras.

flights %>% 
  filter(origin %in% c("JFK", "LGA", "EWR")) %>%
  group_by(carrier) %>%
  summarise(count = n()) %>%
  ggplot(aes(x = reorder(carrier, -count), y = count)) +
  geom_bar(stat = "identity", fill = "lightblue") +
  labs(title = "Número de vuelos por aerolínea en 2013", x = "Aerolínea", y = "Cantidad de vuelos") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Visualiza el punto anterior en una gráfica de pie.

flights %>% 
  filter(origin %in% c("JFK", "LGA", "EWR")) %>%
  group_by(carrier) %>%
  summarise(count = n()) %>%
  ggplot(aes(x = "", y = count, fill = carrier)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Vuelos por aerolínea en 2013", fill = "Aerolínea") +
  theme_minimal()

Relaciona el data frame fligths con el data frame airports a través del campo destino ¿cómo lograr estas relación?

relacion <- merge(flights,airlines, by="carrier")
relacion <- left_join(relacion,planes, by="tailnum")
relacion <- left_join(relacion,weather, by=c("origin","time_hour"))

Crea un nuevo data frame con el punto anterior únicamente con los 5 carriers con más vuelos por destino.

cinco_carriers <- flights %>%
  group_by(carrier) %>%
  summarise(count = n()) %>%
  arrange(desc(count)) %>%
  slice(1:5) %>%
  ungroup() %>%
  select(carrier)

vuelos_cinco_carriers <- relacion %>%
  filter(carrier %in% cinco_carriers$carrier)

Visualización del punto anterior de tres formas.

1.-

ggplot(vuelos_cinco_carriers, aes(x = carrier, fill = carrier)) +
  geom_bar() +
  labs(title = "Cantidad de vuelos por aerolínea", x = "Aerolínea", y = "Cantidad de vuelos") +
  theme_minimal()

2.-

ggplot(vuelos_cinco_carriers, aes(x = dest, fill = carrier)) +
  geom_bar() +
  labs(title = "Cantidad de vuelos por destino", x = "Destino", y = "Cantidad de vuelos") +
  theme_minimal() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

3.-

vuelos_cinco_carriers %>%
  group_by(day.x) %>%
  summarise(count = n()) %>%
  ggplot(aes(x = day.x, y = count)) +
  geom_bar(stat = "identity", fill = "lightblue") +
  labs(title = "Cantidad de vuelos por día del mes", x = "Día del mes", y = "Cantidad de vuelos") +
  theme_minimal()

ggplot(vuelos_cinco_carriers, aes(x = factor(day.x), fill = carrier)) +
  geom_bar() +
  labs(title = "Cantidad de vuelos por día del mes", x = "Día del mes", y = "Cantidad de vuelos") +
  theme_minimal()

Conclusión

En este trabajo que realizamos análisis sobre los retrasos en los vuelos que despegan de los aeropuertos EWR, JFK y LGA en Nueva York hacia otros destinos en los Estados Unidos están influenciados por una gran variedad de factores, entre los cuales se encuentran: congestión del tráfico aéreo, problemas técnicos y condiciones meteorológicas adversas. Además, gracias a los analisis que hicimos, se puede notar una clara diferencia en los tiempos y porcentajes de retraso entre los vuelos de la mañana y losvuelos de la tarde. Los datos y el análisis de estos revelan que tanto el tiempo de retraso en la salida (dep_delay) como en la llegada (arr_delay) varían de una forma muy visible, siendo que los vuelos de la mañana están entre -43 minutos para la salida del avión y -86 minutos para su llegada, mientras que en la tarde hay un promedio de 1301 minutos para la salida, y entre 1272 minutos para la llegada. Estos retrasos pueden ser atribuidos a una serie de causas, desde problemas técnicos y logísticos hasta factores externos como el clima y la congestión del tráfico aéreo. Sin embargo, es irrefutable que los vuelos que se efectúan en la tarde tienden a experimentar retrasos más grandes y ocurrentes, con un tiempo promedio de 22 minutos y un porcentaje de retraso del 49%, a gran diferencia de los vuelos de las mañanas que tienen tiempos de retraso de entre 1:16 y 1:48 minutos junto con un porcentaje de retraso del 21.7%. Estos patrones encontrados dentro de los datos y la analización de estos nos dicen que la hora del día puede desempeñar un papel crucial en la probabilidad de los retrasos en los vuelos junto con la duración de estos. Todo este razonamiento se evidencia del análisis detallado de los datos de vuelo, los cuales proporcionan información sobre los tiempos de retraso, las causas potenciales y la distribución de los retrasos a lo largo del día. # Compromiso ético y ciudadano Definición de integridad académica:

Para mí, la integridad significa no comprometer mis principios éticos incluso cuando enfrento desafíos difíciles o presiones externas. Significa ser honesto en todas mis interacciones, mantener la confidencialidad de la información confiada a mí y tomar decisiones justas y equitativas. La integridad es la forma que tengo de pensar y de qué hago si estoy al frente de una decisión. Qué haré si me veo tentado a quebrantar mis ideales y/o principios de honestidad frente a algo o alguien más. “es hacer lo correcto aun cuando nadie te está observando.” (Human Verification, s. f.) es una frase que dijo el autor Clive Staples Lewis y significa para mí que a partir de mi integridad, aún y cuando nadie me esté viendo o monitoreando de alguna forma, haré lo que sea correcto y lo que yo sé que tengo permitido hacer sin ir más allá de lo que tengo permitido aunque tenga el poder para eso.

Nuestra integridad es algo que nos define totalmente como personas y no solo eso, es algo que define cómo seremos en nuestra vida profesional ya que está presente en cada ámbito y momento de nuestro día a día, a la hora de levantarnos y ser íntegros con nosotros mismos, a la hora de ir a comprar la leche a la tienda y pagar la cantidad correcta o no robar nada, a la hora de ir manejando al trabajo y no pasar ningun algo o algun semaforo y a la hora de estar en mi trabajo o en mi estudio y decidir hacer las cosas correctas para mi y para los demás, hacer las aquellas cosas que no son fáciles o que podría no hacer y tal vez nadie se daría cuenta, aquellas cosas que tienen un atajo o alguna forma de evitarlas, pero sé que no es la forma correcta y sé que debo dar un mejor rol no solo frente a la sociedad sino también a los demás y a mi mismo.

Tener a disposición la información de una empresa conlleva una serie de implicaciones importantes, tanto éticas como legales y profesionales. Algunas de estas implicaciones incluyen: Responsabilidad de confidencialidad: La información de la empresa puede contener datos sensibles y confidenciales, como estrategias comerciales, datos financieros, información de clientes y detalles de productos. Es fundamental respetar la confidencialidad de esta información y no divulgar a terceros sin autorización adecuada. Integridad y ética profesional: Manejar la información de la empresa de manera ética y con integridad es crucial. Esto implica evitar el uso indebido de la información para beneficio personal o para perjudicar a la empresa o a otros individuos. Cumplimiento de normativas y leyes: Es importante cumplir con todas las normativas y leyes relacionadas con la privacidad de datos y la protección de la información confidencial. Esto incluye leyes como el Reglamento General de Protección de Datos (GDPR) en la Unión Europea o la Ley de Portabilidad y Responsabilidad de Seguros Médicos (HIPAA) en Estados Unidos, entre otras. Protección contra el acceso no autorizado: La información de la empresa debe ser protegida contra el acceso no autorizado. Esto implica tomar medidas de seguridad adecuadas, como el uso de contraseñas seguras, la encriptación de datos y el acceso restringido a la información solo a aquellos empleados que la necesiten para realizar sus funciones. Uso responsable de la información: Utilizar la información de la empresa de manera responsable y ética, en línea con los objetivos y valores de la organización. Esto implica no distorsionar la información ni utilizarla de manera engañosa o fraudulenta.

Bibliografía: Jones, T. M. (1991). Ethical decision making by individuals in organizations: An issue-contingent model. Academy of Management Review, 16(2), 366-395. Treviño, L. K., & Nelson, K. A. (2016). Managing business ethics: Straight talk about how to do it right. John Wiley & Sons. Duska, R., Duska, B., & Ragatz, J. A. (2011). Accounting ethics (Vol. 2). John Wiley & Sons.

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSAxIC0gTmV3IFlvcmsiDQphdXRob3I6ICJBbnRvbmlvIEPDoXJkZW5hcyAgLSBBMDE1Njg5MDgiDQpkYXRlOiAiMjAyNC0wMi0yNiINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KLS0tDQoNCiFbXShDOlxcVXNlcnNcXGFudG9uXFxEb3dubG9hZHNcXE9JUCAoMikuanBlZykNCiMgRXZpZGVuY2lhLiBFdGFwYSAxDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHBpbms7Ij5Db250ZXh0bzwvc3Bhbj4NCkVsIHBhcXVldGUgKipueWNmbGlnaHRzMTMqKiBjb250aWVuZSBpbmZvcm1hY2nDs24gc29icmUgdG9kb3MgbG9zIHZ1ZWxvcyBxdWUgcGFydGllcm9uIGRlc2RlIE5ldyBZb3JrIChFV1IsIEpGSyB5IExHQSkgYSBkZXN0aW5vcyBlbiBsb3MgRXN0YWRvcyBVbmlkb3MgZW4gMjAxMy4gRnVlcm9uIDMzNiw3NzYgdnVlbG9zIGVuIHRvdGFsLiBQYXJhIGF5dWRhciBhIGNvbXByZW5kZXIgbGFzIGNhdXNhcyBkZSBsb3MgcmV0cmFzb3MsIHRhbWJpw6luIGluY2x1eWUgb3Ryb3MgY29uanVudG9zIGRlIGRhdG9zIMO6dGlsZXMuIA0KDQpGdWVudGU6ICANCltPcmlnZW4gZGUgbG9zIGRhdG9zXShDOlxcVXNlcnNcXGFudG9uXFxEb3dubG9hZHNcXG55Y2ZsaWdodHMxMy5wZGYpDQoNCkVzdGUgcGFxdWV0ZSBpbmNsdXllIGxhcyBzaWd1aWVudGVzIHRhYmxhczogDQoNCisgZmxpZ2h0cyA9IHRvZG9zIGxvcyB2dWVsb3MgcXVlIHNhbGllcm9uIGRlIE5ZIGVuIDIwMTMuICAgDQorIHdlYXRoZXIgPSBkYXRvcyBtZXRlb3JvbMOzZ2ljb3MgcG9yIGhvcmEgZGUgY2FkYSBhZXJvcHVlcnRvLiAgIA0KKyBwbGFuZXMgPSBpbmZvcm1hY2nDs24gZGUgY29udHJ1Y2Npw7NuIGRlIGNhZGEgYXZpw7NuLiAgDQorIGFpcnBvcnRzID0gbm9tYnJlcyB5IHViaWNhY2lvbmVzIGRlIGFlcm9wdWVydG9zLiAgIA0KKyBhaXJsaW5lcyA9IHJlbGFjacOzbiBlbnRyZSBub21icmVzIHkgY8OzZGlnb3MgZGUgbGFzIGFlcm9saW5lYXMuIA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IHBpbms7Ij5JbnN0YWxhciBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXLDrWFzPC9zcGFuPg0KYGBge3J9DQojIGluc3RhbGwucGFja2FnZXMoIm55Y2ZsaWdodHMxMyIpDQpsaWJyYXJ5KG55Y2ZsaWdodHMxMykNCiMgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KIyBsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShkcGx5cikNCmBgYA0KDQoNCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBwaW5rOyI+R3VhcmRhciBiYXNlIGRlIGRhdG9zPC9zcGFuPg0KYGBge3J9DQpmbGlnaHRzIDwtIGZsaWdodHMNCndlYXRoZXIgPC0gd2VhdGhlcg0KcGxhbmVzIDwtIHBsYW5lcw0KYWlycG9ydHMgPC0gYWlycG9ydHMNCmFpcmxpbmVzIDwtIGFpcmxpbmVzDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBwaW5rOyI+UmVsYWNpw7NuIGVudHJlIGxhcyBiYXNlcyBkZSBkYXRvczwvc3Bhbj4NCg0KIVtdKEM6XFxVc2Vyc1xcYW50b25cXERvd25sb2Fkc1xccmVsYXRpb25hbC1ueWNmbGlnaHRzICgyKS5wbmcpDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogZGVlcHBpbms7Ij4xLiBDYXJnYXIgZW4gbWVtb3JpYSBsYSB0YWJsYSAiZmxpZ2h0cyIgeSBtb3N0cmFyIHN1IGNvbnRlbmlkbzwvc3Bhbj4NCmBgYHtyfQ0KIyBMYSBjYXJnYSBhIG1lbW9yaWEgc2UgaGl6byBlbiBlbCBwYXNvIGFudGVyaW9yLiANCmZsaWdodHMgDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBkZWVwcGluazsiPjIuIENvbnN1bHRhIGxhIGVzdHJ1Y3R1cmEgZGUgImZsaWdodHMiPC9zcGFuPg0KYGBge3J9DQpzdHIoZmxpZ2h0cykNCiNpbnQ6IGVudGVybyAoc2luIGRlY2ltYWxlcykNCiNudW06IG51bcOpcmljbyAoY29uIGRlY2ltYWxlcykNCiNjZ3I6IGNhcmFjdMOpciAobGV0cmFzKQ0KI2RhdGU6IGZlY2hhIChlbiBSIHZhIGHDsW8tbWVzLWTDrWEpDQojUE9TSVhjdDogZm9ybWF0byBmZWNoYSB5IGhvcmENCg0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogZGVlcHBpbms7Ij4zLiDCv0N1w6FsIGVzIGxhIGNsYXNlIGRlICJmbGlnaHRzIiB5IHF1w6kgc2lnbmlmaWNhPzwvc3Bhbj4NCmBgYHtyfQ0KY2xhc3MoZmxpZ2h0cykNCg0KI0xhcyA1IGNsYXNlcyBkZSBvYmpldG9zIHNvbjoNCiAgIyAxLiBudW1lcmljOiBuw7ptZXJvIHJlYWwgbyBkZWNpbWFsZXMuICANCiAgIyAyLiBpbnRlZ2VyOiBuw7ptZXJvIGVudGVyby4gIA0KICAjIDMuIGNvbXBsZXg6IG7Dum1lcm8gY29tcGxlam8uDQogICMgNC4gY2hhcmFjdGVyOiBjYXJhY3RlcmVzLCB0ZXh0by4NCiAgIyA1LiBsb2dpY2FsOiBUUlVFIG8gRkFMU0UuDQoNCiMgTGFzIDQgY2xhc2VzIGRlIG9iamV0b3MgY29tcHVlc3RvcyBzb246ICANCiAgIyAxLiBsaXN0OiBsaXN0YQ0KICAjIDIuIG1hdHJpeDogbWF0cml6DQogICMgMy4gYXJyYXk6IGNvbGVjY2nDs24gZGUgb2JqZXRvcw0KICAjIDQuIGRhdGEuZnJhbWU6IGJhc2UgZGUgZGF0b3MNCmBgYA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGRlZXBwaW5rOyI+NC4gwr9DdcOhbnRhcyBjb2x1bW5hcyB5IHJlbmdsb25lcyB0aWVuZSAiZmxpZ2h0cyI/IMK/Q3XDoWwgZXMgc3UgZGltZW5zacOzbj88L3NwYW4+DQpgYGB7cn0NCiNOw7ptZXJvIGRlIGNvbHVtbmFzDQpuY29sKGZsaWdodHMpDQojTsO6bWVybyBkZSByZW5nbG9uZXMNCm5yb3coZmxpZ2h0cykNCiNOw7ptZXJvIGRlIGRpbWVuc2nDs24NCmRpbShmbGlnaHRzKQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogZGVlcHBpbms7Ij41LiBNdWVzdHJhIGxvcyBwcmltZXJvcyA2IHJlbmdsb25lcyBkZSAiZmxpZ2h0cyIsIFRhbWJpw6luIGxvcyDDumx0aW1vcyA2PC9zcGFuPg0KYGBge3J9DQpoZWFkKGZsaWdodHMpDQp0YWlsKGZsaWdodHMpDQojU2kgcXVpc2llcmFtb3MgNyByZW5nbG9uZXM6IGhlYWQoZmxpZ2h0cywgNykNCmBgYA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGRlZXBwaW5rOyI+Ni4gTXVlc3RyYSBsb3MgZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MgZGUgImZsaWdodHMiIDwvc3Bhbj4NCmBgYHtyfQ0Kc3VtbWFyeShmbGlnaHRzKQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcGluazsiPkNvbmNsdXNpw7NuIDwvc3Bhbj4NCkVuIGVzdGUgY8OzZGlnbyBwb2RlbW9zIHZlciBsbyBxdWUgZXMgdW4gY29uanVudG8gZGUgZGF0b3MsIGVsIGN1YWwgdGllbmUgaW5mb3JtYWNpw7NuIGFjZXJjYSBkZSBsb3MgdnVlbG9zIHF1ZSBzYWxlbiBkZXNkZSBOdWV2YSBZb3JrIGVuIGVsIGHDsW8gMjAxMy4gQSB0cmF2w6lzIGRlIGxhIGNhcmdhIGRlIHBhcXVldGVzIHkgZGF0b3MgcmVsZXZhbnRlcywgaW5pY2lhbW9zIHVuIHByb2Nlc28gZGUgY29tcHJlbnNpw7NuIHkgYW7DoWxpc2lzLiBFbCByZXN1bWVuIGVzdGFkw61zdGljbyBxdWUgc2UgaGl6byByZXZlbGEgY29zYXMgaW1wb3J0YW50ZXMgc29icmUgdmFyaWFibGVzIGNsYXZlLCBjb21vIGxvcyB0aWVtcG9zIGRlIHNhbGlkYSB5IGxsZWdhZGEsIGFzw60gY29tbyBsb3MgcG9zaWJsZXMgcmV0cmFzb3MgZGUgbG9zIGF2aW9uZXMgdGFudG8gZGUgc2FsaWRhIGNvbW8gZGUgYXRlcnJpemFqZS4gQXF1w60gZXMgZG9uZGUgcG9kZW1vcyB2ZXIgbG9zIHByaW5jaXBhbGVzIHBhdHJvbmVzIGRlIGNvbXBvcnRhbWllbnRvLCBmYWN0b3JlcyBkZSBpbmZsdWVuY2lhIHkgw6FyZWFzIGRlIGludGVyw6lzIHNvYnJlIHRvZG9zIGVzdG9zIGRhdG9zLiBFc3RvIGVzIHN1bWFtZW50ZSBmdW5kYW1lbnRhbCBwYXJhIGVudGVuZGVyIGxhIG5hdHVyYWxlemEgeSBlbCBhbGNhbmNlIGRlIGxvcyBkYXRvcyBxdWUgdGVuZW1vcywgdmVyIHF1w6kgcG9kZW1vcyBoYWNlciBjb24gZWxsb3MgeSBxdcOpIG5vcyBkaWNlbiBoYXN0YSBhaG9yYS4NCiAgDQoNCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IGRlZXBwaW5rOyI+IEV0YXBhMi4gTWFuaXB1bGFjacOzbiBkZSBEYXRvcyA8L3NwYW4+DQoNCiMjIDEuIENvbnN1bHRhIGVsIGRhdGEgZnJhbWUgZmxpZ2h0cyBwYXJhIHJlY29yZGFyIHN1IGNvbnRlbmlkby4NCmBgYHtyfQ0KdmlldyhmbGlnaHRzKQ0KYGBgDQoNCiMjIDIuIEVuY3VlbnRyYSBsb3MgZGF0b3MgZGVzY3JpcHRpdm9zIGRlbCBkYXRhIGZyYW1lIGZsaWdodHMuIElkZW50aWZpY2EgbGEgbWVkaWEgZGUgbGFzIGRpc3RhbmNpYXMgcmVjb3JyaWRhcyBlbiBtaWxsYXMuDQpgYGB7cn0NCnN1bW1hcnkoZmxpZ2h0cykNCmBgYA0KTGEgbWVkaWEgZGUgbGEgZGlzdGFuY2lhIHJlY29ycmlkYSBlcyBkZSAxMDQwIG1pbGxhcy4gDQoNCiMjIERhdGEgZnJhbWUgcXVlIGZpbHRyZSBzb2xhbWVudGUgYSBsYXMgYWVvcmzDrW5lYXMgcXVlIGhhbiByZWNvcnJpZG8gdW5hIGRpc3RhbmNpYSBzdXBlcmlvciBhIGxhIG1lZGlhLCBzZSBkZXNlYW4gdmVyIGxvcyBjYW1wb3MgY2FycmllciwgZGlzdGFuY2UsIG9yaWdpbiwgZGVzdCBlbiBmb3JtYSBkZXNjZW5kZW50ZSBwb3IgZGlzdGFuY2UuDQpgYGB7cn0NCmFlcm9saW5lYXNfZGlzdGFuY2lhID0gc2VsZWN0KGZsaWdodHMsIGNhcnJpZXIsIGRpc3RhbmNlLCBvcmlnaW4sIGRlc3QpDQphZXJvbGluZWFzX21heW9yX21lYW4gPSBmaWx0ZXIoYWVyb2xpbmVhc19kaXN0YW5jaWEsIGRpc3RhbmNlID4gMTA0MCkNCmFlcm9saW5lYXNfbWF5b3JfZGVzYyA9IGFycmFuZ2UoYWVyb2xpbmVhc19tYXlvcl9tZWFuLCBkZXNjKGRpc3RhbmNlKSkNCmBgYA0KDQojIyBFbmN1ZW50cmEgbGEgc3VtYSB5IGxhIG1lZGlhIGRlIGxhcyBkaXN0YW5jaWFzIHJlY29ycmlkYXMgcG9yIGNhcnJpZXIsIGVsaW1pbmEgbG9zIE5B4oCZUyBlIGludGVycHJldGEgcXVlIHNpZ25pZmljYSBsYSBzdW1hIHkgbGEgbWVkaWEgZGUgbGFzIGRpc3RhbmNpYXMgcmVjb3JyaWRhcy4gDQpgYGB7cn0NCmRpc3RhbmNpYXMgPC0gZmxpZ2h0cyAlPiUgZ3JvdXBfYnkoY2FycmllcikgJT4lDQpzdW1tYXJpemUoc3VtYSA9IHN1bShkaXN0YW5jZSwgbmEucm0gPSBUUlVFKSwgbWVkaWEgPSBtZWFuKGRpc3RhbmNlLCBuYS5ybSA9IFRSVUUpKQ0KZGlzdGFuY2lhc19vcmRlbiA8LSBhcnJhbmdlKGRpc3RhbmNpYXMsIGRlc2MoZGlzdGFuY2lhcykpDQpwcmludChkaXN0YW5jaWFzKQ0KDQpgYGANCg0KUmVzdWx0YWRvczogT2JzZXJ2YW5kbyBlc3RhIMO6bHRpbWEgdGFibGEgcHVkaW1vcyBvYnNlcnZhciBsb3MgZGF0b3MgcXVlIG5vcyBwZXJtaXRlbiB2ZXIgY3VhbGVzIHNvbiBsYXMgYWVyb2xpbmVhcyBtw6FzIHBvcGx1YXJlcyBlbiBjYWRhIHVubyBkZSBsb3MgYWVyb3B1ZXJ0b3MgZGUgTnVldmEgWW9yay4gVGFtYmnDqW4gY29uIGVsIHByb21lZGlvIG9idGVuaWRvIHBvZGVtb3MgaWRlbnRpZmljYXIgY3VhbCBlcyBsYSBkaXN0YW5jaWEgbWVkaWEgcmVjb3JyaWRhIHBvciB2dWVsbyBkZSBjYWRhIGNvbXBhw7HDrWEgYcOpcmVhLiBFc3RlIGRmIG5vcyBwZXJtaXRlIHZlciBxdWUgVW5pdGVkIEFpcmxpbmVzIGVzIHVuYSBkZSBsYXMgYWVyb2zDrW5lYXMgY29uIGxvcyB2aWFqZXMgY29uIG1heW9yIGRpc3RhbmNpYS4gVGllbmVuIHVuYSBzdW1hIHRvdGFsIGRlIDg5NzA1NTI0LiBTb2JyZSBBbWVyaWNhbiBBaXJsaW5lcywgcG9kZW1vcyBvYnNlcnZhciBxdWUgdGllbmVuIHVuYSBzdW1hIGRlIDQzODY0NTg0IG1pbGxhcyB5IHVuIHByb21lZGlvIGRlIDEzNDAuMjM2MCBtaWxsYXMuIA0KDQojIyBJZGVudGlmaWNhIHNpIGxhcyBhZXJvbMOtbmVhcyBsw61kZXJlcyBzb24gbGFzIG1pc21hcyBlbiBsb3MgdHJlcyBhZXJvcHVlcnRvcyBjdXlvIG9yaWdlbiBlcyBOdWV2YSBZb3JrICggSm9obiBGLiBLZW5uZWR5IChKRkspLCBMYUd1YXJkaWEgKExHQSkgYW5kIE5ld2FyayBMaWJlcnR5IChFV1IpICkuDQpKRksNCmBgYHtyfQ0KSkZLX2ZsaWdodHMgPC0gZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKG9yaWdpbiA9PSAiSkZLIikgJT4lDQogIGdyb3VwX2J5KGNhcnJpZXIpICU+JQ0KICBzdW1tYXJpc2UodG90YWxfZmxpZ2h0cyA9IG4oKSkNCg0KIyBJZGVudGlmaWNhciBsYSBhZXJvbMOtbmVhIGzDrWRlciBlbiBKRksNCkpGS19sZWFkZXIgPC0gSkZLX2ZsaWdodHMgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9mbGlnaHRzKSkgJT4lDQogIHNsaWNlKDEpICU+JQ0KICBwdWxsKGNhcnJpZXIpDQoNCiMgQ29udGFyIGVsIG7Dum1lcm8gZGUgdnVlbG9zIHBvciBhZXJvbMOtbmVhIHBhcmEgTEdBDQpMR0FfZmxpZ2h0cyA8LSBmbGlnaHRzICU+JQ0KICBmaWx0ZXIob3JpZ2luID09ICJMR0EiKSAlPiUNCiAgZ3JvdXBfYnkoY2FycmllcikgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9mbGlnaHRzID0gbigpKQ0KDQojIElkZW50aWZpY2FyIGxhIGFlcm9sw61uZWEgbMOtZGVyIGVuIExHQQ0KTEdBX2xlYWRlciA8LSBMR0FfZmxpZ2h0cyAlPiUNCiAgYXJyYW5nZShkZXNjKHRvdGFsX2ZsaWdodHMpKSAlPiUNCiAgc2xpY2UoMSkgJT4lDQogIHB1bGwoY2FycmllcikNCg0KIyBDb250YXIgZWwgbsO6bWVybyBkZSB2dWVsb3MgcG9yIGFlcm9sw61uZWEgcGFyYSBFV1INCkVXUl9mbGlnaHRzIDwtIGZsaWdodHMgJT4lDQogIGZpbHRlcihvcmlnaW4gPT0gIkVXUiIpICU+JQ0KICBncm91cF9ieShjYXJyaWVyKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX2ZsaWdodHMgPSBuKCkpDQoNCiMgSWRlbnRpZmljYXIgbGEgYWVyb2zDrW5lYSBsw61kZXIgZW4gRVdSDQpFV1JfbGVhZGVyIDwtIEVXUl9mbGlnaHRzICU+JQ0KICBhcnJhbmdlKGRlc2ModG90YWxfZmxpZ2h0cykpICU+JQ0KICBzbGljZSgxKSAlPiUNCiAgcHVsbChjYXJyaWVyKQ0KDQojIENvbXBhcmFyIGxhcyBhZXJvbMOtbmVhcyBsw61kZXJlcyBlbiBsb3MgdHJlcyBhZXJvcHVlcnRvcw0KaWYgKEpGS19sZWFkZXIgPT0gTEdBX2xlYWRlciAmJiBKRktfbGVhZGVyID09IEVXUl9sZWFkZXIpIHsNCiAgY2F0KCJMYXMgYWVyb2zDrW5lYXMgbMOtZGVyZXMgc29uIGxhcyBtaXNtYXMgZW4gbG9zIHRyZXMgYWVyb3B1ZXJ0b3MuIikNCn0gZWxzZSB7DQogIGNhdCgiTGFzIGFlcm9sw61uZWFzIGzDrWRlcmVzIG5vIHNvbiBsYXMgbWlzbWFzIGVuIGxvcyB0cmVzIGFlcm9wdWVydG9zLiIpDQp9DQpgYGANCkVuIGVsIGFlcm9wdWVydG8gZGUgSkZLLCBCNiBKZXRCbHVlIEFpcndheXMgZXMgbGEgYWVyb2zDrW5lYSBjb24gbWF5b3IgbsO6bWVybyBkZSB2dWVsb3MgY29uIHVuIHRvdGFsIGRlIDE5Mzc4LiANCg0KTEdBDQpgYGB7cn0NCkxHQV9mbGlnaHRzIDwtIGZsaWdodHMgJT4lDQogIGZpbHRlcihvcmlnaW4gPT0gIkxHQSIpICU+JQ0KICBncm91cF9ieShjYXJyaWVyKSAlPiUNCiAgc3VtbWFyaXNlKHRvdGFsX2ZsaWdodHMgPSBuKCkpDQoNCiMgSWRlbnRpZmljYXIgbGEgYWVyb2zDrW5lYSBsw61kZXIgZW4gTEdBDQpMR0FfbGVhZGVyIDwtIExHQV9mbGlnaHRzICU+JQ0KICBhcnJhbmdlKGRlc2ModG90YWxfZmxpZ2h0cykpICU+JQ0KICBzbGljZSgxKSAlPiUNCiAgcHVsbChjYXJyaWVyKQ0KDQpMR0FfbGVhZGVyDQpgYGANCkVuIGxhIEd1YXJkaWEsIEFtZXJpY2FuIEFpcmxpbmVzIHRpZW5lIGxhIHByaW1lcmEgcG9zaWPDs24gY29uIHVuIHRvdGFsIGRlIDg3ODEgZW4gbsO6bWVybyBkZSB2dWVsb3MuDQoNCkVXUg0KYGBge3J9DQojIENvbnRhciBlbCBuw7ptZXJvIGRlIHZ1ZWxvcyBwb3IgYWVyb2zDrW5lYSBwYXJhIEVXUg0KRVdSX2ZsaWdodHMgPC0gZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKG9yaWdpbiA9PSAiRVdSIikgJT4lDQogIGdyb3VwX2J5KGNhcnJpZXIpICU+JQ0KICBzdW1tYXJpc2UodG90YWxfZmxpZ2h0cyA9IG4oKSkNCg0KIyBJZGVudGlmaWNhciBsYSBhZXJvbMOtbmVhIGzDrWRlciBlbiBFV1INCkVXUl9sZWFkZXIgPC0gRVdSX2ZsaWdodHMgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3RhbF9mbGlnaHRzKSkgJT4lDQogIHNsaWNlKDEpICU+JQ0KICBwdWxsKGNhcnJpZXIpDQoNCkVXUl9sZWFkZXINCmBgYA0KRW4gTmV3YXJrIExpYmVydHkgSW50ZXJuYXRpb25hbCwgVW5pdGVkIEFpcmxpbmVzIHRpZW5lIGVsIG1heW9yIG7Dum1lcm8gZGUgdnVlbG9zIGNvbiB1biB0b3RhbCBkZSAzMDE4My4gDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiBwaW5rOyI+Q29uY2x1c2nDs24gPC9zcGFuPg0KLi4uDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyI+RXZpZGVuY2lhIDIgLSBBbmFsw610aWNhIGRlc2NyaXB0aXZhIDwvc3Bhbj4NCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsdWU7Ij5Nb2RlbG8gRW50aWRhZC1SZWxhY2nDs248L3NwYW4+DQoNCiMjIENvbnN1bHRhIHkgZXhwbG9yYSBlbCBkYXRhIGZyYW1lIHBsYW5lcyB5IHdlYXRoZXIgcGFyYSBxdWUgY29ub3pjYXMgc3UgY29udGVuaWRvLg0KDQpgYGB7cn0NCg0KbGlicmFyeShueWNmbGlnaHRzMTMpDQpsaWJyYXJ5KGRwbHlyKQ0KDQp2aWV3KHBsYW5lcykNCnZpZXcod2VhdGhlcikNCmBgYA0KDQojIyBTZSBuZWNlc2l0YSBzYWJlciBkZSBjYWRhIHZ1ZWxvLCBsYSBhZXJvbMOtbmVhLCBlbCBhZXJvcHVlcnRvIGRlIG9yaWdlbiB5IGVsIGFlcm9wdWVydG8gZGVzdGluby4NCmBgYHtyfQ0Kc3VtbWFyeShmbGlnaHRzKQ0KYGBgDQoNCmBgYHtyfQ0KdnVlbG9zIDwtIHNlbGVjdChmbGlnaHRzLCBmbGlnaHQsIGNhcnJpZXIsIG9yaWdpbiwgZGVzdCkNCmhlYWQodnVlbG9zKQ0KYGBgDQoNCiMjIEVuIGxhIGNvbnN1bHRhIGFudGVyaW9yIHNlIG5lY2VzaXRhIGNvbm9jZXIgZWwgbm9tYnJlIGRlIGxhIGFlcm9sw61uZWEuDQpgYGB7cn0NCmFlcm9saW5lYSA8LSB2dWVsb3MgJT4lIGxlZnRfam9pbihhaXJsaW5lcywgYnkgPSAiY2FycmllciIpDQpgYGANCg0KIyMgU2UgbmVjZXNpdGEgc2FiZXIgbGEgY2FudGlkYWQgZGUgdnVlbG9zIHBvciBjYWRhIGRlc3Rpbm8gcGFyYSBpZGVudGlmaWNhciBjdcOhbGVzIHNvbiBsb3MgZGVzdGlub3MgbcOhcyBidXNjYWRvcy4NCmBgYHtyfQ0KIyBDb250YXIgZWwgbsO6bWVybyBkZSB2dWVsb3MgcG9yIGNhZGEgZGVzdGlubw0KdnVlbG9zX3Bvcl9kZXN0aW5vIDwtIGZsaWdodHMgJT4lDQogIGdyb3VwX2J5KGRlc3QpICU+JQ0KICBzdW1tYXJpc2UobnVtX3Z1ZWxvcyA9IG4oKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhudW1fdnVlbG9zKSkNCg0KIyBNb3N0cmFyIGxvcyBkZXN0aW5vcyBtw6FzIGJ1c2NhZG9zDQpoZWFkKHZ1ZWxvc19wb3JfZGVzdGlubykNCmBgYA0KDQojIyBBZ3JlZ2FyIGVsIG5vbWJyZSBkZSBsYSBhZXJvbMOtbmVhIGFsIGRhdGEgZnJhbWUgYW50ZXJpb3IuDQpgYGB7cn0NCm5vbWJyZV9hZXJvbGluZWEgPC0gdnVlbG9zICU+JSBsZWZ0X2pvaW4oYWlybGluZXMsIGJ5ID0iY2FycmllciIpDQpgYGANCg0KIyMgU2UgbmVjZXNpdGEgY29ub2NlciBsYXMgYWVyb2zDrW5lYXMgKGNsYXZlIHkgbm9tYnJlKSB5IGRlc3Rpbm9zIHF1ZSB2dWVsYW4gcG9yIGxhIE1hw7FhbmE6IGRlIDYgYSAxMiwgVGFyZGU6IGRlIDEyIGEgMTkgLCBOb2NoZTogZGUgMTkgYSAyNCB5IE1hZHJ1Z2FkYSBkZSAyNCBhIDYuDQpgYGB7cn0NCmhvcmFyaW9zIDwtIHNlbGVjdChmbGlnaHRzLCBjYXJyaWVyLCBkZXN0LCBob3VyKQ0KaGVhZChob3JhcmlvcykNCiNob3JhcmlvcyRjYXRlZ29yaWEgPC0gaWYoZmxpZ2h0cyRob3VyPj02ICYmIGhvdXI8MTIpDQojaGVhZChob3JhcmlvcykNCmBgYA0KDQojIyBTZSBuZWNlc2l0YSBzYWJlciBsYSBjYW50aWRhZCBkZSB2dWVsb3MgcG9yIGFlcm9sw61uZWEgeSBkZXN0aW5vIHF1ZSBoYXkgcG9yIGxhIE1hw7FhbmEsIFRhcmRlLCBOb2NoZSB5IE1hZHJ1Z2FkYS4NCmBgYHtyfQ0KIyBEZWZpbmlyIGZ1bmNpw7NuIHBhcmEgY2xhc2lmaWNhciBsb3MgbW9tZW50b3MgZGVsIGTDrWENCmNsYXNpZmljYXJfbW9tZW50b19kaWEgPC0gZnVuY3Rpb24oaG9yYSkgew0KICBtb21lbnRvIDwtIHJlcChOQSwgbGVuZ3RoKGhvcmEpKQ0KICBtb21lbnRvW2hvcmEgPj0gNSAmIGhvcmEgPCAxMl0gPC0gIk1hw7FhbmEiDQogIG1vbWVudG9baG9yYSA+PSAxMiAmIGhvcmEgPCAxOF0gPC0gIlRhcmRlIg0KICBtb21lbnRvW2hvcmEgPj0gMTggJiBob3JhIDwgMjRdIDwtICJOb2NoZSINCiAgbW9tZW50b1tob3JhID49IDAgJiBob3JhIDwgNV0gPC0gIk1hZHJ1Z2FkYSINCiAgcmV0dXJuKG1vbWVudG8pDQp9DQpgYGANCg0KIyMgU2UgbmVjZXNpdGEgc2FiZXIgYSBxdcOpIGRlc3Rpbm9zIHZ1ZWxhIGxhIGFlcm9sw61uZWEgQW1lcmljYW4gQWlybGluZXMgSW5jLi1BQSBkdXJhbnRlIGxhIG1hZHJ1Z2FkYS4NCg0KYGBge3J9DQojIEZpbHRyYXIgbG9zIHZ1ZWxvcyBkZSBBbWVyaWNhbiBBaXJsaW5lcyBJbmMuLUFBIGR1cmFudGUgbGEgbWFkcnVnYWRhDQpkZXN0aW5vc19tYWRydWdhZGFfQUEgPC0gZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKGNhcnJpZXIgPT0gIkFBIiwgaG91ciA+PSAwICYgaG91ciA8IDUpICU+JQ0KICBncm91cF9ieShkZXN0KSAlPiUNCiAgc3VtbWFyaXNlKG51bV92dWVsb3MgPSBuKCkpICU+JQ0KICBhcnJhbmdlKGRlc2MobnVtX3Z1ZWxvcykpDQoNCiMgTW9zdHJhciBsb3MgZGVzdGlub3MgbcOhcyBjb211bmVzIGR1cmFudGUgbGEgbWFkcnVnYWRhIHBhcmEgQW1lcmljYW4gQWlybGluZXMgSW5jLi1BQQ0KZGVzdGlub3NfbWFkcnVnYWRhX0FBDQpgYGANCg0KIyMgwr9RdcOpIGF2aW9uZXMgdXRpbGl6YSBsYSBhZXJvbMOtbmVhIEFBPyBhZXJvbMOtbmVhLCB0aXBvLCBtb3RvciB5IG7Dum1lcm8gZGUgYXNpZW50b3MgeSDCv0N1w6FudG9zIHZ1ZWxvcyBzZSBoYW4gcmVhbGl6YWRvIGNvbiBjYWRhIHVubz8gZWxpbWluYSBsb3MgTkEncw0KDQpgYGB7cn0NCmF2aW9uZXNfQUEgPC0gZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKGNhcnJpZXIgPT0gIkFBIikgJT4lDQogIGxlZnRfam9pbihwbGFuZXMsIGJ5ID0gInRhaWxudW0iKSAlPiUNCiAgc2VsZWN0KGNhcnJpZXIsIHR5cGUsIGVuZ2luZSwgc2VhdHMsIHRhaWxudW0pICU+JQ0KICBuYS5vbWl0KCkgJT4lDQogIGdyb3VwX2J5KHR5cGUsIGVuZ2luZSwgc2VhdHMsIHRhaWxudW0pICU+JQ0KICBzdW1tYXJpc2UobnVtX3Z1ZWxvcyA9IG4oKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhudW1fdnVlbG9zKSkNCg0KIyBNb3N0cmFyIGxhIGluZm9ybWFjacOzbiBzb2JyZSBsb3MgYXZpb25lcyB1dGlsaXphZG9zIHBvciBsYSBhZXJvbMOtbmVhIEFBDQphdmlvbmVzX0FBDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsdWU7Ij5WaXN1YWxpemFjacOzbiBkZSBkYXRvcyA8L3NwYW4+DQoNCiMjIFNlIHNvbGljaXRhIGFuYWxpemFyIHBhcmEgbGEgYWVyb2zDrW5lYSBBbWVyaWNhbiBBaXJsaW5lcyBzaSBsb3MgdnVlbG9zIHF1ZSB0aWVuZW4gcmV0cmFzbyBlbiBsYSBwYXJ0aWRhIHRhbWJpw6luIHRpZW5lbiByZXRyYXNvIGVuIGxhIGhvcmEgZGUgbGxlZ2FkYS4NCmBgYHtyfQ0KZGYxMyA8LSBmbGlnaHRzICU+JSBzZWxlY3QoZGVwX2RlbGF5LCBhcnJfZGVsYXkpDQpzdW1tYXJ5KGRmMTMpDQpnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGVwX2RlbGF5LCB5ID0gYXJyX2RlbGF5KSwgZGF0YSA9IGRmMTMpICsNCiAgZ2VvbV9wb2ludCgNCiAgICBtYXBwaW5nID0gYWVzKHggPSBkZXBfZGVsYXksIHkgPSBhcnJfZGVsYXkpLCBkYXRhID0gZGYxMywNCiAgICBjb2xvdXIgPSAncGluaycsIHNpemUgPSAxKQ0KYGBgDQoNCiMjIFZpc3VhbGl6YSBsYSB0ZW5kZW5jaWEgZGUgbGEgdGVtcGVyYXR1cmEgZHVyYW50ZSBsb3MgcHJpbWVyb3MgMTUgZMOtYXMgZGVsIG1lcyBkZSBFbmVybyBlbiBsb3MgdnVlbG9zIHF1ZSBwYXJ0ZW4gZGVsIGFlcm9wdWVydG8g4oCcTmV3YXJrLCBFV1LigJ0sIHV0aWxpemFyIHVuYSBncsOhZmljYSBkZSBsw61uZWEuDQoNCmBgYHtyfQ0KdGVtcCA8LSBmaWx0ZXIod2VhdGhlciwgb3JpZ2luPT0iRVdSIikNCnRlbmRlbmNpYV90ZW1wIDwtIGZpbHRlcih0ZW1wLCBkYXkgPD0gMTUpDQoNCnBsb3QodGVuZGVuY2lhX3RlbXAkZGF5LCB0ZW5kZW5jaWFfdGVtcCR0ZW1wLCB0eXBlPSJwIikNCmBgYA0KDQojIyBWaXN1YWxpemEgbGEgdGVtcGVyYXR1cmEgbcOhcyBmcmVjdWVudGUgZW4gbG9zIHByaW1lcm9zIDE1IGTDrWFzIGRlbCBtZXMgZGUgRW5lcm8sIHV0aWxpemFyIHVuIGhpc3Ryb2dyYW1hLg0KYGBge3J9DQpnZ3Bsb3Qod2VhdGhlciwgYWVzKHggPSB0ZW1wKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMzAsIGZpbGwgPSAicGluayIsIGNvbG9yID0gImRlZXBwaW5rIikgKw0KICBsYWJzKHRpdGxlID0gIkhpc3RvZ3JhbWEgZGUgbGEgdGVtcGVyYXR1cmEgZW4gRW5lcm8iLCB4ID0gIlRlbXBlcmF0dXJhICjCsEYpIiwgeSA9ICJGcmVjdWVuY2lhIikNCmBgYA0KDQojIyBVdGlsaXphIEZhY2V0cyBwYXJhIG9ic2VydmFyIGPDs21vIHZhcsOtYSBsYSB0ZW1wZXJhdHVyYSBlbiBjYWRhIG1lcyBlbiDDqWwgaGlzdG9ncmFtYSBkZWwgcHVudG8gYW50ZXJpb3IgIA0KYGBge3J9DQp3ZWF0aGVyICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gdGVtcCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDMwKSArDQogIGZhY2V0X3dyYXAofm1vbnRoKSArDQogIGxhYnModGl0bGUgPSAiVGVtcGVyYXR1cmEgcG9yIG1lcyIsIHggPSAiVGVtcGVyYXR1cmEgKMKwRikiLCB5ID0gIkZyZWN1ZW5jaWEiKQ0KYGBgDQoNCiMjIE7Dum1lcm8gZGUgdnVlbG9zIHF1ZSBzYWxpZXJvbiBkZSBOdWV2YSBZb3JrIGVuIDIwMTMgcG9yIGFlcm9sw61uZWEgKG1vc3RyYXIgc29sYW1lbnRlIGxhcyAxMCBhZXJvbMOtbmVhcyBjb24gbcOhcyB2dWVsb3MpLCB1dGlsaXphciBncsOhZmljYSBkZSBiYXJyYXMuICANCmBgYHtyfQ0KZmxpZ2h0cyAlPiUgDQogIGZpbHRlcihvcmlnaW4gJWluJSBjKCJKRksiLCAiTEdBIiwgIkVXUiIpKSAlPiUNCiAgZ3JvdXBfYnkoY2FycmllcikgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoY2FycmllciwgLWNvdW50KSwgeSA9IGNvdW50KSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJsaWdodGJsdWUiKSArDQogIGxhYnModGl0bGUgPSAiTsO6bWVybyBkZSB2dWVsb3MgcG9yIGFlcm9sw61uZWEgZW4gMjAxMyIsIHggPSAiQWVyb2zDrW5lYSIsIHkgPSAiQ2FudGlkYWQgZGUgdnVlbG9zIikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQ0KYGBgDQoNCiMjIFZpc3VhbGl6YSBlbCBwdW50byBhbnRlcmlvciBlbiB1bmEgZ3LDoWZpY2EgZGUgcGllLg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgZmlsdGVyKG9yaWdpbiAlaW4lIGMoIkpGSyIsICJMR0EiLCAiRVdSIikpICU+JQ0KICBncm91cF9ieShjYXJyaWVyKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gIiIsIHkgPSBjb3VudCwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIoInkiKSArDQogIGxhYnModGl0bGUgPSAiVnVlbG9zIHBvciBhZXJvbMOtbmVhIGVuIDIwMTMiLCBmaWxsID0gIkFlcm9sw61uZWEiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjIFJlbGFjaW9uYSBlbCBkYXRhIGZyYW1lIGZsaWd0aHMgY29uIGVsIGRhdGEgZnJhbWUgYWlycG9ydHMgYSB0cmF2w6lzIGRlbCBjYW1wbyBkZXN0aW5vIMK/Y8OzbW8gbG9ncmFyIGVzdGFzIHJlbGFjacOzbj8NCmBgYHtyfQ0KcmVsYWNpb24gPC0gbWVyZ2UoZmxpZ2h0cyxhaXJsaW5lcywgYnk9ImNhcnJpZXIiKQ0KcmVsYWNpb24gPC0gbGVmdF9qb2luKHJlbGFjaW9uLHBsYW5lcywgYnk9InRhaWxudW0iKQ0KcmVsYWNpb24gPC0gbGVmdF9qb2luKHJlbGFjaW9uLHdlYXRoZXIsIGJ5PWMoIm9yaWdpbiIsInRpbWVfaG91ciIpKQ0KYGBgDQoNCiMjIENyZWEgdW4gbnVldm8gZGF0YSBmcmFtZSBjb24gZWwgcHVudG8gYW50ZXJpb3Igw7puaWNhbWVudGUgY29uIGxvcyA1IGNhcnJpZXJzIGNvbiBtw6FzIHZ1ZWxvcyBwb3IgZGVzdGluby4NCmBgYHtyfQ0KY2luY29fY2FycmllcnMgPC0gZmxpZ2h0cyAlPiUNCiAgZ3JvdXBfYnkoY2FycmllcikgJT4lDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lDQogIGFycmFuZ2UoZGVzYyhjb3VudCkpICU+JQ0KICBzbGljZSgxOjUpICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIHNlbGVjdChjYXJyaWVyKQ0KDQp2dWVsb3NfY2luY29fY2FycmllcnMgPC0gcmVsYWNpb24gJT4lDQogIGZpbHRlcihjYXJyaWVyICVpbiUgY2luY29fY2FycmllcnMkY2FycmllcikNCmBgYA0KDQojIyBWaXN1YWxpemFjacOzbiBkZWwgcHVudG8gYW50ZXJpb3IgZGUgdHJlcyBmb3JtYXMuICANCg0KMS4tDQpgYGB7cn0NCmdncGxvdCh2dWVsb3NfY2luY29fY2FycmllcnMsIGFlcyh4ID0gY2FycmllciwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyBwb3IgYWVyb2zDrW5lYSIsIHggPSAiQWVyb2zDrW5lYSIsIHkgPSAiQ2FudGlkYWQgZGUgdnVlbG9zIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQoyLi0gDQpgYGB7cn0NCmdncGxvdCh2dWVsb3NfY2luY29fY2FycmllcnMsIGFlcyh4ID0gZGVzdCwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyBwb3IgZGVzdGlubyIsIHggPSAiRGVzdGlubyIsIHkgPSAiQ2FudGlkYWQgZGUgdnVlbG9zIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkNCg0KYGBgDQoNCjMuLQ0KYGBge3J9DQp2dWVsb3NfY2luY29fY2FycmllcnMgJT4lDQogIGdyb3VwX2J5KGRheS54KSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gZGF5LngsIHkgPSBjb3VudCkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAibGlnaHRibHVlIikgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyBwb3IgZMOtYSBkZWwgbWVzIiwgeCA9ICJEw61hIGRlbCBtZXMiLCB5ID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmdncGxvdCh2dWVsb3NfY2luY29fY2FycmllcnMsIGFlcyh4ID0gZmFjdG9yKGRheS54KSwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyBwb3IgZMOtYSBkZWwgbWVzIiwgeCA9ICJEw61hIGRlbCBtZXMiLCB5ID0gIkNhbnRpZGFkIGRlIHZ1ZWxvcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcGluazsiPkNvbmNsdXNpw7NuIDwvc3Bhbj4NCkVuIGVzdGUgdHJhYmFqbyBxdWUgcmVhbGl6YW1vcyBhbsOhbGlzaXMgc29icmUgbG9zIHJldHJhc29zIGVuIGxvcyB2dWVsb3MgcXVlIGRlc3BlZ2FuIGRlIGxvcyBhZXJvcHVlcnRvcyBFV1IsIEpGSyB5IExHQSBlbiBOdWV2YSBZb3JrIGhhY2lhIG90cm9zIGRlc3Rpbm9zIGVuIGxvcyBFc3RhZG9zIFVuaWRvcyBlc3TDoW4gaW5mbHVlbmNpYWRvcyBwb3IgdW5hIGdyYW4gdmFyaWVkYWQgZGUgZmFjdG9yZXMsIGVudHJlIGxvcyBjdWFsZXMgc2UgZW5jdWVudHJhbjogY29uZ2VzdGnDs24gZGVsIHRyw6FmaWNvIGHDqXJlbywgcHJvYmxlbWFzIHTDqWNuaWNvcyB5IGNvbmRpY2lvbmVzIG1ldGVvcm9sw7NnaWNhcyBhZHZlcnNhcy4gQWRlbcOhcywgZ3JhY2lhcyBhIGxvcyBhbmFsaXNpcyBxdWUgaGljaW1vcywgc2UgcHVlZGUgbm90YXIgdW5hIGNsYXJhIGRpZmVyZW5jaWEgZW4gbG9zIHRpZW1wb3MgeSBwb3JjZW50YWplcyBkZSByZXRyYXNvIGVudHJlIGxvcyB2dWVsb3MgZGUgbGEgbWHDsWFuYSB5IGxvc3Z1ZWxvcyBkZSBsYSB0YXJkZS4NCkxvcyBkYXRvcyB5IGVsIGFuw6FsaXNpcyBkZSBlc3RvcyByZXZlbGFuIHF1ZSB0YW50byBlbCB0aWVtcG8gZGUgcmV0cmFzbyBlbiBsYSBzYWxpZGEgKGRlcF9kZWxheSkgY29tbyBlbiBsYSBsbGVnYWRhIChhcnJfZGVsYXkpIHZhcsOtYW4gZGUgdW5hIGZvcm1hIG11eSB2aXNpYmxlLCBzaWVuZG8gcXVlIGxvcyB2dWVsb3MgZGUgbGEgbWHDsWFuYSBlc3TDoW4gZW50cmUgLTQzIG1pbnV0b3MgcGFyYSBsYSBzYWxpZGEgZGVsIGF2acOzbiB5IC04NiBtaW51dG9zIHBhcmEgc3UgbGxlZ2FkYSwgbWllbnRyYXMgcXVlIGVuIGxhIHRhcmRlIGhheSB1biBwcm9tZWRpbyBkZSAxMzAxIG1pbnV0b3MgcGFyYSBsYSBzYWxpZGEsIHkgZW50cmUgMTI3MiBtaW51dG9zIHBhcmEgbGEgbGxlZ2FkYS4gRXN0b3MgcmV0cmFzb3MgcHVlZGVuIHNlciBhdHJpYnVpZG9zIGEgdW5hIHNlcmllIGRlIGNhdXNhcywgZGVzZGUgcHJvYmxlbWFzIHTDqWNuaWNvcyB5IGxvZ8Otc3RpY29zIGhhc3RhIGZhY3RvcmVzIGV4dGVybm9zIGNvbW8gZWwgY2xpbWEgeSBsYSBjb25nZXN0acOzbiBkZWwgdHLDoWZpY28gYcOpcmVvLiBTaW4gZW1iYXJnbywgZXMgaXJyZWZ1dGFibGUgcXVlIGxvcyB2dWVsb3MgcXVlIHNlIGVmZWN0w7phbiBlbiBsYSB0YXJkZSB0aWVuZGVuIGEgZXhwZXJpbWVudGFyIHJldHJhc29zIG3DoXMgZ3JhbmRlcyB5IG9jdXJyZW50ZXMsIGNvbiB1biB0aWVtcG8gcHJvbWVkaW8gZGUgMjIgbWludXRvcyB5IHVuIHBvcmNlbnRhamUgZGUgcmV0cmFzbyBkZWwgNDklLCBhIGdyYW4gZGlmZXJlbmNpYSBkZSBsb3MgdnVlbG9zIGRlIGxhcyBtYcOxYW5hcyBxdWUgdGllbmVuIHRpZW1wb3MgZGUgcmV0cmFzbyBkZSBlbnRyZSAxOjE2IHkgMTo0OCBtaW51dG9zIGp1bnRvIGNvbiB1biBwb3JjZW50YWplIGRlIHJldHJhc28gZGVsIDIxLjclLiANCkVzdG9zIHBhdHJvbmVzIGVuY29udHJhZG9zIGRlbnRybyBkZSBsb3MgZGF0b3MgeSBsYSBhbmFsaXphY2nDs24gZGUgZXN0b3Mgbm9zIGRpY2VuIHF1ZSBsYSBob3JhIGRlbCBkw61hIHB1ZWRlIGRlc2VtcGXDsWFyIHVuIHBhcGVsIGNydWNpYWwgZW4gbGEgcHJvYmFiaWxpZGFkIGRlIGxvcyByZXRyYXNvcyBlbiBsb3MgdnVlbG9zIGp1bnRvIGNvbiBsYSBkdXJhY2nDs24gZGUgZXN0b3MuIFRvZG8gZXN0ZSByYXpvbmFtaWVudG8gc2UgZXZpZGVuY2lhIGRlbCBhbsOhbGlzaXMgZGV0YWxsYWRvIGRlIGxvcyBkYXRvcyBkZSB2dWVsbywgbG9zIGN1YWxlcyBwcm9wb3JjaW9uYW4gaW5mb3JtYWNpw7NuIHNvYnJlIGxvcyB0aWVtcG9zIGRlIHJldHJhc28sIGxhcyBjYXVzYXMgcG90ZW5jaWFsZXMgeSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyByZXRyYXNvcyBhIGxvwqBsYXJnb8KgZGVswqBkw61hLg0KIyBDb21wcm9taXNvIMOpdGljbyB5IGNpdWRhZGFubw0KRGVmaW5pY2nDs24gZGUgaW50ZWdyaWRhZCBhY2Fkw6ltaWNhOg0KDQpQYXJhIG3DrSwgbGEgaW50ZWdyaWRhZCBzaWduaWZpY2Egbm8gY29tcHJvbWV0ZXIgbWlzIHByaW5jaXBpb3Mgw6l0aWNvcyBpbmNsdXNvIGN1YW5kbyBlbmZyZW50byBkZXNhZsOtb3MgZGlmw61jaWxlcyBvIHByZXNpb25lcyBleHRlcm5hcy4gU2lnbmlmaWNhIHNlciBob25lc3RvIGVuIHRvZGFzIG1pcyBpbnRlcmFjY2lvbmVzLCBtYW50ZW5lciBsYSBjb25maWRlbmNpYWxpZGFkIGRlIGxhIGluZm9ybWFjacOzbiBjb25maWFkYSBhIG3DrSB5IHRvbWFyIGRlY2lzaW9uZXMganVzdGFzIHkgZXF1aXRhdGl2YXMuDQpMYSBpbnRlZ3JpZGFkIGVzIGxhIGZvcm1hIHF1ZSB0ZW5nbyBkZSBwZW5zYXIgeSBkZSBxdcOpIGhhZ28gc2kgZXN0b3kgYWwgZnJlbnRlIGRlIHVuYSBkZWNpc2nDs24uIFF1w6kgaGFyw6kgc2kgbWUgdmVvIHRlbnRhZG8gYSBxdWVicmFudGFyIG1pcyBpZGVhbGVzIHkvbyBwcmluY2lwaW9zIGRlIGhvbmVzdGlkYWQgZnJlbnRlIGEgYWxnbyBvIGFsZ3VpZW4gbcOhcy4gDQrigJxlcyBoYWNlciBsbyBjb3JyZWN0byBhdW4gY3VhbmRvIG5hZGllIHRlIGVzdMOhIG9ic2VydmFuZG8u4oCdIChIdW1hbiBWZXJpZmljYXRpb24sIHMuIGYuKSBlcyB1bmEgZnJhc2UgcXVlIGRpam8gZWwgYXV0b3IgQ2xpdmUgU3RhcGxlcyBMZXdpcyB5IHNpZ25pZmljYSBwYXJhIG3DrSBxdWUgYSBwYXJ0aXIgZGUgbWkgaW50ZWdyaWRhZCwgYcO6biB5IGN1YW5kbyBuYWRpZSBtZSBlc3TDqSB2aWVuZG8gbyBtb25pdG9yZWFuZG8gZGUgYWxndW5hIGZvcm1hLCBoYXLDqSBsbyBxdWUgc2VhIGNvcnJlY3RvIHkgbG8gcXVlIHlvIHPDqSBxdWUgdGVuZ28gcGVybWl0aWRvIGhhY2VyIHNpbiBpciBtw6FzIGFsbMOhIGRlIGxvIHF1ZSB0ZW5nbyBwZXJtaXRpZG8gYXVucXVlIHRlbmdhIGVsIHBvZGVyIHBhcmEgZXNvLiANCg0KTnVlc3RyYSBpbnRlZ3JpZGFkIGVzIGFsZ28gcXVlIG5vcyBkZWZpbmUgdG90YWxtZW50ZSBjb21vIHBlcnNvbmFzIHkgbm8gc29sbyBlc28sIGVzIGFsZ28gcXVlIGRlZmluZSBjw7NtbyBzZXJlbW9zIGVuIG51ZXN0cmEgdmlkYSBwcm9mZXNpb25hbCB5YSBxdWUgZXN0w6EgcHJlc2VudGUgZW4gY2FkYSDDoW1iaXRvIHkgbW9tZW50byBkZSBudWVzdHJvIGTDrWEgYSBkw61hLCBhIGxhIGhvcmEgZGUgbGV2YW50YXJub3MgeSBzZXIgw61udGVncm9zIGNvbiBub3NvdHJvcyBtaXNtb3MsIGEgbGEgaG9yYSBkZSBpciBhIGNvbXByYXIgbGEgbGVjaGUgYSBsYSB0aWVuZGEgeSBwYWdhciBsYSBjYW50aWRhZCBjb3JyZWN0YSBvIG5vIHJvYmFyIG5hZGEsIGEgbGEgaG9yYSBkZSBpciBtYW5lamFuZG8gYWwgdHJhYmFqbyB5IG5vIHBhc2FyIG5pbmd1biBhbGdvIG8gYWxndW4gc2VtYWZvcm8geSBhIGxhIGhvcmEgZGUgZXN0YXIgZW4gbWkgdHJhYmFqbyBvIGVuIG1pIGVzdHVkaW8geSBkZWNpZGlyIGhhY2VyIGxhcyBjb3NhcyBjb3JyZWN0YXMgcGFyYSBtaSB5IHBhcmEgbG9zIGRlbcOhcywgaGFjZXIgbGFzIGFxdWVsbGFzIGNvc2FzIHF1ZSBubyBzb24gZsOhY2lsZXMgbyBxdWUgcG9kcsOtYSBubyBoYWNlciB5IHRhbCB2ZXogbmFkaWUgc2UgZGFyw61hIGN1ZW50YSwgYXF1ZWxsYXMgY29zYXMgcXVlIHRpZW5lbiB1biBhdGFqbyBvIGFsZ3VuYSBmb3JtYSBkZSBldml0YXJsYXMsIHBlcm8gc8OpIHF1ZSBubyBlcyBsYSBmb3JtYSBjb3JyZWN0YSB5IHPDqSBxdWUgZGVibyBkYXIgdW4gbWVqb3Igcm9sIG5vIHNvbG8gZnJlbnRlIGEgbGEgc29jaWVkYWQgc2lubyB0YW1iacOpbiBhIGxvcyBkZW3DoXMgeSBhIG1pIG1pc21vLiANCg0KVGVuZXIgYSBkaXNwb3NpY2nDs24gbGEgaW5mb3JtYWNpw7NuIGRlIHVuYSBlbXByZXNhIGNvbmxsZXZhIHVuYSBzZXJpZSBkZSBpbXBsaWNhY2lvbmVzIGltcG9ydGFudGVzLCB0YW50byDDqXRpY2FzIGNvbW8gbGVnYWxlcyB5IHByb2Zlc2lvbmFsZXMuIEFsZ3VuYXMgZGUgZXN0YXMgaW1wbGljYWNpb25lcyBpbmNsdXllbjoNClJlc3BvbnNhYmlsaWRhZCBkZSBjb25maWRlbmNpYWxpZGFkOiBMYSBpbmZvcm1hY2nDs24gZGUgbGEgZW1wcmVzYSBwdWVkZSBjb250ZW5lciBkYXRvcyBzZW5zaWJsZXMgeSBjb25maWRlbmNpYWxlcywgY29tbyBlc3RyYXRlZ2lhcyBjb21lcmNpYWxlcywgZGF0b3MgZmluYW5jaWVyb3MsIGluZm9ybWFjacOzbiBkZSBjbGllbnRlcyB5IGRldGFsbGVzIGRlIHByb2R1Y3Rvcy4gRXMgZnVuZGFtZW50YWwgcmVzcGV0YXIgbGEgY29uZmlkZW5jaWFsaWRhZCBkZSBlc3RhIGluZm9ybWFjacOzbiB5IG5vIGRpdnVsZ2FyIGEgdGVyY2Vyb3Mgc2luIGF1dG9yaXphY2nDs24gYWRlY3VhZGEuDQpJbnRlZ3JpZGFkIHkgw6l0aWNhIHByb2Zlc2lvbmFsOiBNYW5lamFyIGxhIGluZm9ybWFjacOzbiBkZSBsYSBlbXByZXNhIGRlIG1hbmVyYSDDqXRpY2EgeSBjb24gaW50ZWdyaWRhZCBlcyBjcnVjaWFsLiBFc3RvIGltcGxpY2EgZXZpdGFyIGVsIHVzbyBpbmRlYmlkbyBkZSBsYSBpbmZvcm1hY2nDs24gcGFyYSBiZW5lZmljaW8gcGVyc29uYWwgbyBwYXJhIHBlcmp1ZGljYXIgYSBsYSBlbXByZXNhIG8gYSBvdHJvcyBpbmRpdmlkdW9zLg0KQ3VtcGxpbWllbnRvIGRlIG5vcm1hdGl2YXMgeSBsZXllczogRXMgaW1wb3J0YW50ZSBjdW1wbGlyIGNvbiB0b2RhcyBsYXMgbm9ybWF0aXZhcyB5IGxleWVzIHJlbGFjaW9uYWRhcyBjb24gbGEgcHJpdmFjaWRhZCBkZSBkYXRvcyB5IGxhIHByb3RlY2Npw7NuIGRlIGxhIGluZm9ybWFjacOzbiBjb25maWRlbmNpYWwuIEVzdG8gaW5jbHV5ZSBsZXllcyBjb21vIGVsIFJlZ2xhbWVudG8gR2VuZXJhbCBkZSBQcm90ZWNjacOzbiBkZSBEYXRvcyAoR0RQUikgZW4gbGEgVW5pw7NuIEV1cm9wZWEgbyBsYSBMZXkgZGUgUG9ydGFiaWxpZGFkIHkgUmVzcG9uc2FiaWxpZGFkIGRlIFNlZ3Vyb3MgTcOpZGljb3MgKEhJUEFBKSBlbiBFc3RhZG9zIFVuaWRvcywgZW50cmUgb3RyYXMuDQpQcm90ZWNjacOzbiBjb250cmEgZWwgYWNjZXNvIG5vIGF1dG9yaXphZG86IExhIGluZm9ybWFjacOzbiBkZSBsYSBlbXByZXNhIGRlYmUgc2VyIHByb3RlZ2lkYSBjb250cmEgZWwgYWNjZXNvIG5vIGF1dG9yaXphZG8uIEVzdG8gaW1wbGljYSB0b21hciBtZWRpZGFzIGRlIHNlZ3VyaWRhZCBhZGVjdWFkYXMsIGNvbW8gZWwgdXNvIGRlIGNvbnRyYXNlw7FhcyBzZWd1cmFzLCBsYSBlbmNyaXB0YWNpw7NuIGRlIGRhdG9zIHkgZWwgYWNjZXNvIHJlc3RyaW5naWRvIGEgbGEgaW5mb3JtYWNpw7NuIHNvbG8gYSBhcXVlbGxvcyBlbXBsZWFkb3MgcXVlIGxhIG5lY2VzaXRlbiBwYXJhIHJlYWxpemFyIHN1cyBmdW5jaW9uZXMuDQpVc28gcmVzcG9uc2FibGUgZGUgbGEgaW5mb3JtYWNpw7NuOiBVdGlsaXphciBsYSBpbmZvcm1hY2nDs24gZGUgbGEgZW1wcmVzYSBkZSBtYW5lcmEgcmVzcG9uc2FibGUgeSDDqXRpY2EsIGVuIGzDrW5lYSBjb24gbG9zIG9iamV0aXZvcyB5IHZhbG9yZXMgZGUgbGEgb3JnYW5pemFjacOzbi4gRXN0byBpbXBsaWNhIG5vIGRpc3RvcnNpb25hciBsYSBpbmZvcm1hY2nDs24gbmkgdXRpbGl6YXJsYSBkZSBtYW5lcmEgZW5nYcOxb3NhIG8gZnJhdWR1bGVudGEuDQoNCg0KDQoNCg0KDQpCaWJsaW9ncmFmw61hOg0KSm9uZXMsIFQuIE0uICgxOTkxKS4gRXRoaWNhbCBkZWNpc2lvbiBtYWtpbmcgYnkgaW5kaXZpZHVhbHMgaW4gb3JnYW5pemF0aW9uczogQW4gaXNzdWUtY29udGluZ2VudCBtb2RlbC4gQWNhZGVteSBvZiBNYW5hZ2VtZW50IFJldmlldywgMTYoMiksIDM2Ni0zOTUuDQpUcmV2acOxbywgTC4gSy4sICYgTmVsc29uLCBLLiBBLiAoMjAxNikuIE1hbmFnaW5nIGJ1c2luZXNzIGV0aGljczogU3RyYWlnaHQgdGFsayBhYm91dCBob3cgdG8gZG8gaXQgcmlnaHQuIEpvaG4gV2lsZXkgJiBTb25zLg0KRHVza2EsIFIuLCBEdXNrYSwgQi4sICYgUmFnYXR6LCBKLiBBLiAoMjAxMSkuIEFjY291bnRpbmcgZXRoaWNzIChWb2wuIDIpLiBKb2huIFdpbGV5ICYgU29ucy4=