hllinas2023

1 Librerías

1.0.1 Para SEM

El software R dispone de varias funciones de diferentes paquetes para calcular EFA:

library(sem)
library(lavaan)
library(blavaan)
library(semPlot)

1.0.2 Para otros análisis

library(psych)         #Para realizar un EFA
library(aplore3)       #Base de datos para los ejemplos
library(lsm)           #Base de datos para ejemplos y estimaciones del Log-verosimilitud
library(tidyverse)     #Incluye a dplyr y ggplot2
library(stringr)       #Reemplazar caracteres en un data frame
library(outliers)      #outliers::grubbs.test
library(EnvStats)      #EnvStats::rosnerTest
library(DMwR2)         #LOF (Local Outlier Factor)
library(rgl)           #rgl::plot3d
library(corrplot)      #Matriz de correlaciones
library(textshape)     #column_to_rownames
library(openxlsx)  # Librería para escribir archivos de Excel
library(knitr)      #crear tablas con estilo
library(kableExtra) #crear tablas con estilo, pero para html

2 Sintáxis con lavaan

2.0.1 Tipos de fórmulas

Utilizando cuatro tipos de fórmulas, se puede describir una gran variedad de modelos de variables latentes. El conjunto actual de tipos de fórmulas se resume en la figura 2.1.

**Tipos de fórmulas**

Figure 2.1: Tipos de fórmulas

2.0.2 Sintáxis de los modelos

  1. En lavaan, los modelos SEM pueden especificarse mediante fórmulas de modelo similares a las utilizadas en las funciones lm y glm.

  2. Sin embargo, hay algunos operadores nuevos (símbolos relacionales) que se utilizan para definir covarianzas (residuales) y variables latentes.

  3. La figura 2.2 enumera algunas expresiones comunes en la sintaxis de lavaan.

**Sintáxis de los modelos**

Figure 2.2: Sintáxis de los modelos

3 Ejemplo: Enunciado

3.0.1 Descripción del datasets

  1. Vamos a utilizar un conjunto de datos llamado HolzingerSwineford1939 para llevar a cabo un SEM el cual proviene del paquete lavaan.

  2. El conjunto de datos clásico de Holzinger y Swineford (1939) consiste en puntuaciones de pruebas de capacidad mental de niños de séptimo y octavo curso de dos grupos de colegios diferentes (Pasteur y Grant-White).

  3. En el conjunto de datos original (disponible en el paquete MBESS), hay puntuaciones para 26 pruebas.

  4. Sin embargo, en la bibliografía se utiliza más un subconjunto más pequeño con 9 variables (por ejemplo, en el trabajo de Joreskog de 1969, que también utiliza sólo los 145 sujetos de la escuela Grant-White).

3.0.2 Descripción de las variables del datasets

Nosotros utilizaremos un data frame con 301 observaciones (Pasteur=156, Grant-White=145) y 15 variables:

  1. id: Identificador.

  2. sex: Género.

  3. ageyr: Edad (parte en años).

  4. agemo: Edad (parte en meses).

  5. school: Escuela (Pasteur or Grant-White).

  6. grade: Grado.

  7. x1: Visual perception (percepción visual).

  8. x2: Cubes (cubos).

  9. x3: Lozenges (pastillas).

  10. x4: Paragraph comprehension (comprensión de parágrafos).

  11. x5: Sentence completion (completar oraciones).

  12. x6: Word meaning (significado de palabras).

  13. x7: Speeded addition (adición con velocidad).

  14. x8: Speeded counting of dots (conteo de puntos con velocidad).

  15. x9: Speeded discrimination straight and curved capitals (discriminación acelerada de letras mayúsculas rectas y curvas). Por ejemplo:

    • Letras con trazos rectos: A, E, F, H, I, K, L, M, N, T, V, W, X, Y, Z

    • Letras con trazos curvos: B, C, D, G, J, O, P, Q, R, S, U

Aquí x1, x2, …, x9 fueron calculadas a través de funciones de pruebas cognitivas.

3.0.3 Nuestro data frame en R

datosCompleto <- lavaan::HolzingerSwineford1939
attach(datosCompleto)
names(datosCompleto)
##  [1] "id"     "sex"    "ageyr"  "agemo"  "school" "grade"  "x1"     "x2"    
##  [9] "x3"     "x4"     "x5"     "x6"     "x7"     "x8"     "x9"

Se resalta que sólo algunas de estas variables se utilizarán para realizar el SEM.

dat <- datosCompleto[7:15]
attach(dat)
head(dat,4) 
x1 x2 x3 x4 x5 x6 x7 x8 x9
3.333333 7.75 0.375 2.333333 5.75 1.2857143 3.391304 5.75 6.361111
5.333333 5.25 2.125 1.666667 3.00 1.2857143 3.782609 6.25 7.916667
4.500000 5.25 1.875 1.000000 1.75 0.4285714 3.260870 3.90 4.416667
5.333333 7.75 3.000 2.666667 4.50 2.4285714 3.000000 5.30 4.861111

4 Ejemplo: Solución

4.0.1 Estadísticos descriptivos básicos

Primero, es recomendable examinar los datos antes de realizar cualquier análisis. Cualquier participante que tenga algún dato faltante será excluido por completo del análisis. Se pueden utilizar diversas funciones (como se muestra a continuación).

describe(dat)
##    vars   n mean   sd median trimmed  mad  min   max range  skew kurtosis   se
## x1    1 301 4.94 1.17   5.00    4.96 1.24 0.67  8.50  7.83 -0.25     0.31 0.07
## x2    2 301 6.09 1.18   6.00    6.02 1.11 2.25  9.25  7.00  0.47     0.33 0.07
## x3    3 301 2.25 1.13   2.12    2.20 1.30 0.25  4.50  4.25  0.38    -0.91 0.07
## x4    4 301 3.06 1.16   3.00    3.02 0.99 0.00  6.33  6.33  0.27     0.08 0.07
## x5    5 301 4.34 1.29   4.50    4.40 1.48 1.00  7.00  6.00 -0.35    -0.55 0.07
## x6    6 301 2.19 1.10   2.00    2.09 1.06 0.14  6.14  6.00  0.86     0.82 0.06
## x7    7 301 4.19 1.09   4.09    4.16 1.10 1.30  7.43  6.13  0.25    -0.31 0.06
## x8    8 301 5.53 1.01   5.50    5.49 0.96 3.05 10.00  6.95  0.53     1.17 0.06
## x9    9 301 5.37 1.01   5.42    5.37 0.99 2.78  9.25  6.47  0.20     0.29 0.06

Se resalta que, la función describe de la librería psych, el output:

  • timmed se refiere a la mediana truncada, que es una medida de tendencia central robusta que calcula la mediana de un conjunto de datos después de eliminar un cierto porcentaje de observaciones más extremas.

  • mad significa desviación absoluta mediana, que es una medida de dispersión que indica la variabilidad de los datos en relación con la mediana.

  • skew se refiere a la asimetría de los datos, que indica si la distribución de los datos es simétrica o si está sesgada hacia un lado. Un valor positivo indica sesgo hacia la derecha, mientras que un valor negativo indica sesgo hacia la izquierda.

  • kurtosis se refiere a la curtosis de los datos, que indica la forma de la distribución de los datos en relación con una distribución normal. Un valor de kurtosis mayor que cero indica una distribución más puntiaguda (más picos) que la distribución normal, mientras que un valor menor que cero indica una distribución más achatada (menos picos) que la distribución normal.

  • se se refiere al error estándar, que es una medida de la precisión de la estimación de una estadística de la muestra. Indica la variabilidad esperada en la estimación de la estadística si se muestrea repetidamente de la misma población. Un error estándar más pequeño indica una estimación más precisa de la estadística de interés.

summary(dat)
##        x1               x2              x3              x4       
##  Min.   :0.6667   Min.   :2.250   Min.   :0.250   Min.   :0.000  
##  1st Qu.:4.1667   1st Qu.:5.250   1st Qu.:1.375   1st Qu.:2.333  
##  Median :5.0000   Median :6.000   Median :2.125   Median :3.000  
##  Mean   :4.9358   Mean   :6.088   Mean   :2.250   Mean   :3.061  
##  3rd Qu.:5.6667   3rd Qu.:6.750   3rd Qu.:3.125   3rd Qu.:3.667  
##  Max.   :8.5000   Max.   :9.250   Max.   :4.500   Max.   :6.333  
##        x5              x6               x7              x8        
##  Min.   :1.000   Min.   :0.1429   Min.   :1.304   Min.   : 3.050  
##  1st Qu.:3.500   1st Qu.:1.4286   1st Qu.:3.478   1st Qu.: 4.850  
##  Median :4.500   Median :2.0000   Median :4.087   Median : 5.500  
##  Mean   :4.341   Mean   :2.1856   Mean   :4.186   Mean   : 5.527  
##  3rd Qu.:5.250   3rd Qu.:2.7143   3rd Qu.:4.913   3rd Qu.: 6.100  
##  Max.   :7.000   Max.   :6.1429   Max.   :7.435   Max.   :10.000  
##        x9       
##  Min.   :2.778  
##  1st Qu.:4.750  
##  Median :5.417  
##  Mean   :5.374  
##  3rd Qu.:6.083  
##  Max.   :9.250

Otra tabla de frecuencias:

# Genera la tablas usando dplyr and tidyr y kable
dat %>% 
  select(x1:x9) %>% 
  gather("Variable", "value") %>% 
  group_by(Variable) %>% 
  summarise(Mean=mean(value, na.rm=TRUE), 
            SD=sd(value, na.rm=TRUE), 
            min=min(value, na.rm=TRUE), 
            max=max(value, na.rm=TRUE), 
            '% Perdidos'=100*length(which(is.na(value)))/n()) %>% 
  kable(digits=2, format="pandoc", caption="Tabla 1: Estadisticos descriptivos para las variables observadas")
Table 4.1: Tabla 1: Estadisticos descriptivos para las variables observadas
Variable Mean SD min max % Perdidos
x1 4.94 1.17 0.67 8.50 0
x2 6.09 1.18 2.25 9.25 0
x3 2.25 1.13 0.25 4.50 0
x4 3.06 1.16 0.00 6.33 0
x5 4.34 1.29 1.00 7.00 0
x6 2.19 1.10 0.14 6.14 0
x7 4.19 1.09 1.30 7.43 0
x8 5.53 1.01 3.05 10.00 0
x9 5.37 1.01 2.78 9.25 0

4.0.2 Datos faltantes

La mayoría de los elementos solo carecen de datos equivalentes a 20 o 30 participantes, lo cual no representa un gran problema en un conjunto de datos con 2800 observaciones. Sin embargo, es posible que algunos de estos valores faltantes no se superpongan, lo que significa que podrían faltar 20 o 30 individuos diferentes en cada una de las variables.

4.0.3 Datos perdidos por columna

missings <- colSums(is.na(dat)) 
missings
## x1 x2 x3 x4 x5 x6 x7 x8 x9 
##  0  0  0  0  0  0  0  0  0
summary(missings) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0       0       0       0

Alternativamente, podemos mirar algunas variables con alguna condición para el número de datos perdidos.

mydata <- dat[ , missings<15]
names(mydata)
## [1] "x1" "x2" "x3" "x4" "x5" "x6" "x7" "x8" "x9"

4.0.4 Función complete.cases

No obstante, podemos determinar el número de “casos completos” dentro de los datos, que son individuos que no tienen datos faltantes en absoluto en el cuestionario.

faltante <- complete.cases(dat);tail(faltante)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE
sum(faltante)
## [1] 301

La función complete.cases produce un vector de valores booleanos, donde TRUE indica un caso completo y FALSE indica un caso con valores faltantes. La suma de este vector nos da el total de casos completos, que en este caso es 301. El porcentaje de datos ausentes es 0%:

(1 - (sum(faltante)/nrow(dat)))*100
## [1] 0

Aunque no existe un valor exacto que determine qué cantidad de datos faltantes es aceptable, la importancia del tamaño de la muestra en el análisis factorial es innegable. Según algunos expertos, se recomienda contar con al menos 10 observaciones por cada variable en dicho análisis, lo que sugiere que nuestro tamaño de muestra es apropiado para nuestros objetivos.

5 Especificación del modelo

5.0.1 El modelo teórico

Un modelo CFA que se suele propuesto para estas 9 variables consta de tres variables latentes (o factores), cada una con tres indicadores:

  1. Un factor visual (visual) medido por 3 variables: x1, x2 y x3.

  2. Un factor textual (textual) medido por 3 variables: x4, x5 y x6.

  3. Un factor de velocidad (speed) medido por 3 variables: x7, x8 y x9.

La Figura 5.1 contiene una representación gráfica del modelo de tres factores.

**Modelo CFA para los datos `HolzingerSwineford1939`**

Figure 5.1: Modelo CFA para los datos HolzingerSwineford1939

5.0.2 El modelo en R

Una sintaxis de modelo lavaan completa es simplemente una combinación de estos tipos de fórmulas, encerradas entre comillas simples.

modelo <- ' 
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9 
'

En este ejemplo, la sintaxis del modelo sólo contiene tres definiciones de variables latentes.

6 Tipos de parámetros del modelo

6.0.1 Explicación

  1. En el contexto del análisis factorial confirmatorio (CFA) con el paquete lavaan en R, el número de parámetros en el output del modelo depende de las especificaciones del modelo y los datos utilizados.

  2. El modelo que se ha indicado para los datos HolzingerSwineford1939 especifica tres factores latentes (Visual, Textual, Speed) cada uno con tres indicadores.

  3. En este sentido, identificamos dos tipos de parámetros:

  • Parámetros de medidas.

  • Parámetros estructurales.

  1. En las siguientes secciones explicaremos cada uno de estos tipos.

6.0.2 Parámetros de medidas

En un modelo CFA típico, los parámetros de medidas que se quieren estimar incluyen (véase la Figura 6.1):

1. Cargas Factoriales.

Las relaciones entre los factores latentes y sus indicadores.

\[\lambda_1, \quad \lambda_2, \quad \lambda_3, \quad \lambda_4, \quad \lambda_5, \quad \lambda_6, \quad \lambda_7, \quad \lambda_8, \quad \lambda_9\]

2. Interceptos de los Factores Latentes.

\[\tau_1, \quad \tau_2, \quad \tau_3, \quad \tau_4, \quad \tau_5, \quad \tau_6, \quad \tau_7, \quad \tau_8, \quad \tau_9\] 3. Varianzas de los Errores de Medición.

Varianzas de los términos de error asociados a cada indicador.

\[V(\varepsilon_1), \quad V(\varepsilon_2), \quad V(\varepsilon_3), \quad V(\varepsilon_4), \quad V(\varepsilon_5), \quad V(\varepsilon_6), \quad V(\varepsilon_7), \quad V(\varepsilon_8), \quad V(\varepsilon_9)\]

6.0.3 Parámetros estructurales

En un modelo CFA típico, los parámetros estructurales que se quieren estimar incluyen (véase la Figura 6.1):

4. La media de los factores.

\[\alpha_1, \quad \alpha_2, \quad \alpha_3\]

5. Varianzas de los Factores Latentes.

Varianzas de cada factor.

\[\psi_{11}, \quad \psi_{22}, \quad \psi_{33}\]

6. Covarianzas de los Factores Latentes.

Covarianzas entre los factores.

\[\psi_{12}, \quad \psi_{13}, \quad \psi_{23}\]

6.0.4 Resumen gráfico de los tipos de parámetros

**Tipos de parámetros del modelo CFA**

Figure 6.1: Tipos de parámetros del modelo CFA

7 Estimación del modelo con lavaan::cfa

7.0.1 Output de cfa: ejecución

Podemos ajustar el modelo como sigue:

CFA <- lavaan::cfa(modelo, data=dat)
CFA
## lavaan 0.6.17 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000

7.0.2 Output de cfa: gráfico del modelo con R

1. El diagrama básico.

semPaths(CFA, 
         what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         #what = "eq",     #Muestra las ecuaciones estructurales del modelo 
         
         layout = "circle",   #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         
         title = FALSE,       #No muestra el título del gráfico
         
         edge.color = "red",  #Establece el color de los bordes (aristas) en negro
         edge.label.cex = 1   #Tamaño de las cargas factoriales
         )

2. Se puede visualizar el modelo con nodos personalizados.

semPaths(CFA, 
        what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
        #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
        #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
        #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
        #what = "model",  #Muestra una representación gral del modelo
        #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
        #what = "par",    #Muestra todos los parámetros estimados del modelo
        #what = "eq",     #Muestra las ecuaciones estructurales del modelo
        
        style = "lisrel", #Usa un estilo predefinido similar al estilo LISREL
         #style = "ram":   #Estilo de RAM (Reticular Action Model), común en gráficos SEM
         #style = "mx":    #Estilo de Mx,  herramienta de SEM
         #style = "eqs":   #Estilo similar al software EQS

         #layout = "tree",   #Dispone nodos en una estructura jerárquica similar a un árbol
         #layout="tree2",    #Parecida a la anterior
         layout="circle",    #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         #layout = "spring", #Minimiza fuerzas de repulsión y atracción entre nodos
         #layout = "lgl",    #Algoritmo "Large Graph Layout" (útil para gráficos grandes)
         #layout = "kamada",      #Algorit. Kamada-Kawai para disposición basada en energía
         #layout = "fruchterman", #Algoritmo Fruchterman-Reingold (disposición por fuerzas)
        
        title = FALSE,             #No muestra el título del gráfico
        
        edge.color = "black",      #Establece el color de los bordes (aristas) en negro
        edge.label.cex = 1,        #Tamaño de las cargas factoriales
        
        #node.color = "blue",       #Establece el color de fondo de los nodos
        node.label.cex = 1.5,      #Tamaño del texto de las etiquetas dentro de los nodos.
        #node.shape = "rectangle", #Establece la forma de los nodos como rectángulos
        
        curvePivot=TRUE,           #Conexiones entre las variables observadas
        label.prop = 1,
        
        color = list(
                     lat = "orange",    #Color de las variables latentes
                     man = "lightgreen" #Color de las variables observadas
                     )
        )

3. Se puede visualizar el modelo con otras opciones personalizadas.

semPaths(CFA,
         #what = "path",   #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         what = "eq",      #Muestra las ecuaciones estructurales del modelo 
         
         whatLabels ="est",   #Muestra estimaciones no estandarizadas de los parámetros
         #whatLabels ="std":  #Muestra estimaciones estandarizadas de los parámetros
         #whatLabels ="name": #Muestra los nombres de las relaciones o parámetros
         #whatLabels ="none": #No muestra ninguna etiqueta en las aristas
         #whatLabels ="eq":   #Muestra etiquetas de ecuaciones (usualmente en SEM).
         #whatLabels ="both": #Muestra estimaciones estandarizadas y no estandarizadas
          
         style = "lisrel", #Usa un estilo predefinido similar al estilo LISREL
         #style = "ram":   #Estilo de RAM (Reticular Action Model), común en gráficos SEM
         #style = "mx":    #Estilo de Mx,  herramienta de SEM
         #style = "eqs":   #Estilo similar al software EQS

         #layout = "tree",   #Dispone nodos en una estructura jerárquica similar a un árbol
         layout="tree2",     #Parecida a la anterior
         #layout="circle",   #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         #layout = "spring", #Minimiza fuerzas de repulsión y atracción entre nodos
         #layout = "lgl",    #Algorit. "Large Graph Layout" (útil para gráficos grandes)
         #layout = "kamada",      #Algorit. Kamada-Kawai para disposición basada en energía
         #layout = "fruchterman", #Algoritmo Fruchterman-Reingold (disposición por fuerzas)

         #rotation = 1, #Rotación de todo el diagrama
         rotation=2, 
         #rotation=3,
         
         nCharNodes = 0, #0=ajustar al número máximo de caracteres dentro de las latentes
         sizeMan = 8,    #Tamaño de los nodos que representan variables manifiestas
         sizeLat = 9,    #Tamaño de los nodos que representan variables latentes
         sizeInt = 1,    #Tamaño de los nodos que representan variables interiores
         nCharEdges = 3, #Número máximo de caracteres para etiquetas de cargas factoriales
         
         edge.label.cex = 1,      #Tamaño de las cargas factoriales
         
         #freeStyle = "blue",     #Parámetros fijos son azules
         fixedStyle = c("red",3), #Parámetros fijos son rojos y de tamaño 3
   
         #curvePivot=TRUE,    #Conexiones entre las variables observada
         intercepts=TRUE,     #Se muestran o no los interceptos de variables latentes
         residuals=FALSE,     #Así no aparecen flechas de var. observadas
         exoCov=FALSE,        #Así no aparecen flechas de covarianzas de var. latentes
         
         color = list(
           lat = "orange",    #Color de las variables latentes
           man = "lightgreen" #Color de las variables observadas
           ) 
         )

7.0.3 Output de cfa: observaciones

  1. La función cfa es una función específica para establecer modelos de análisis factorial confirmatorio.

  2. El primer argumento es el modelo especificado por el usuario.

  3. El segundo argumento es el conjunto de datos que contiene las variables observadas.

  4. Los interceptos \(\tau\) de los factores representan las medias de las variables observadas (x1, x2, x3, x4, x5, x6, x7, x8, x9) cuando los factores latentes (Visual, Textual, Speed) tienen un valor de cero.

8 Output de cfa: primera parte

8.0.1 Gráfica de la primera parte

En la Figura 8.1 se resalta la primera parte del output de `lavaan.

**Primera parte del output de `lavaan` (información general)**

Figure 8.1: Primera parte del output de lavaan (información general)

8.0.2 Información general del output

1. El modelo finalizó normalmente después de 35 iteraciones.

Este mensaje indica que el proceso de estimación del modelo finalizó correctamente después de 35 iteraciones. Esto significa que el algoritmo de optimización alcanzó una solución estable dentro del número especificado de iteraciones.

2. El estimador utilizado fue el máximo verosimilitud (ML).

ML significa Maximum Likelihood (Máxima Verosimilitud). Es el estimador utilizado para ajustar el modelo. El estimador de máxima verosimilitud es uno de los métodos más comunes para estimar los parámetros del modelo en análisis factorial confirmatorio, ya que se basa en la suposición de que los datos siguen una distribución normal multivariada.

3. El método de optimización fue NLMINB.

  • La abreviatura NLMINB se refiere a “Nonlinear MINimization using Bounds”, que significa “Minimización no lineal usando límites”.

  • Específicamente, NLMINB se refiere al método de optimización usado para encontrar los valores óptimos de los parámetros del modelo.

  • NLMINB es un algoritmo de optimización que es robusto y eficiente, especialmente para problemas de minimización no linealque tienen restricciones en los parámetros o son de naturaleza no lineal.

  • En secciones siguientes, se describirán brevemente otros métodos alternativos de optimización.

4. El modelo tiene 21 parámetros.

Esta línea indica que el modelo tiene un total de 21 parámetros a estimar. Esto incluye cargas factoriales, varianzas, covarianzas y términos de error, entre otros. En secciones siguientes se va a detallar más al respecto.

5. Se utilizaron 301 observaciones en el ajuste del modelo.

Esta sección muestra que se utilizaron 301 observaciones (o casos) para ajustar el modelo. Es el tamaño de la muestra de datos.

9 Output de cfa: estimadores

9.0.1 Otros estimadores en lavaan (aparte de ML)

1. MLR (Maximum Likelihood with Robust Standard Errors).

  • Proporciona errores estándar robustos y una prueba chi-cuadrado robusta.

  • Es útil cuando los datos no cumplen con la suposición de normalidad multivariada.

2. MLM (Maximum Likelihood with Robust Standard Errors).

  • Similar a MLR pero usa la corrección de Satorra-Bentler para el estadístico chi-cuadrado.

  • Es adecuado para datos que no son normales pero que tienen desviaciones leves de la normalidad.

3. MLF (Maximum Likelihood with Robust Standard Errors and a Scaling Factor).

Similar a MLR pero incluye un factor de escalado adicional para ajustar los errores estándar.

4. WLS (Weighted Least Squares).

Utiliza las matrices de covarianza y asimetría para estimar los parámetros. Es especialmente útil para datos categóricos y ordinales.

5. WLSM (Weighted Least Squares Mean and Variance adjusted).

  • Una variante del WLS que ajusta tanto la media como la varianza, proporcionando una corrección robusta.

  • También es adecuado para datos categóricos y ordinales.

6. WLSMV (Weighted Least Squares Mean and Variance adjusted).

  • Similar a WLSM pero con una corrección adicional para la media y la varianza.

  • Es ampliamente utilizado para modelos con datos categóricos.

7. ULS (Unweighted Least Squares).

  • Minimiza las discrepancias sin ponderar las observaciones.

  • Puede ser útil en casos donde se prefieren métodos no ponderados.

8. ULSM (Unweighted Least Squares Mean and Variance adjusted).

Similar a ULS pero ajusta la media y la varianza.

9. DWLS (Diagonally Weighted Least Squares).

  • Similar a WLS pero usa solo los elementos diagonales de la matriz de covarianza.

  • Es más eficiente computacionalmente y adecuado para datos con variables categóricas.

10. PML (Pseudomaximum Likelihood).

Utilizado principalmente para datos de conteo o cuando se tiene información incompleta.

11. Bayes (Bayesian Estimation).

  • Utiliza métodos bayesianos para la estimación de parámetros.

  • Es útil cuando se desea incorporar información a priori o cuando los modelos son complejos y otros métodos fallan en converger.

9.0.2 Otros estimadores en lavaan (ejemplos)

1. A manera de ejemplo, para ajustar el modelo utilizando el estimador WLSMV, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, estimator = "WLSMV")
fit
## lavaan 0.6.17 ended normally after 44 iterations
## 
##   Estimator                                       DWLS
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                                43.902      79.342
##   Degrees of freedom                                24          24
##   P-value (Chi-square)                           0.008       0.000
##   Scaling correction factor                                  0.598
##   Shift parameter                                            5.867
##     simple second-order correction

2. A manera de ejemplo, para ajustar el modelo utilizando el estimador Bayes, se ejecuta:

fit <- blavaan::bcfa(modelo, data = dat, estimator = "Bayes", burnin = 100, sample = 1000)
fit
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 1).
## Chain 1: 
## Chain 1: Gradient evaluation took 0.001176 seconds
## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 11.76 seconds.
## Chain 1: Adjust your expectations accordingly!
## Chain 1: 
## Chain 1: 
## Chain 1: WARNING: There aren't enough warmup iterations to fit the
## Chain 1:          three stages of adaptation as currently configured.
## Chain 1:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 1:          the given number of warmup iterations:
## Chain 1:            init_buffer = 15
## Chain 1:            adapt_window = 75
## Chain 1:            term_buffer = 10
## Chain 1: 
## Chain 1: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 1: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 1: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 1: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 1: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 1: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 1: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 1: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 1: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 1: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 1: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 1: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 1: 
## Chain 1:  Elapsed Time: 0.363 seconds (Warm-up)
## Chain 1:                3.793 seconds (Sampling)
## Chain 1:                4.156 seconds (Total)
## Chain 1: 
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 2).
## Chain 2: 
## Chain 2: Gradient evaluation took 0.000389 seconds
## Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 3.89 seconds.
## Chain 2: Adjust your expectations accordingly!
## Chain 2: 
## Chain 2: 
## Chain 2: WARNING: There aren't enough warmup iterations to fit the
## Chain 2:          three stages of adaptation as currently configured.
## Chain 2:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 2:          the given number of warmup iterations:
## Chain 2:            init_buffer = 15
## Chain 2:            adapt_window = 75
## Chain 2:            term_buffer = 10
## Chain 2: 
## Chain 2: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 2: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 2: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 2: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 2: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 2: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 2: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 2: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 2: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 2: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 2: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 2: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 2: 
## Chain 2:  Elapsed Time: 0.418 seconds (Warm-up)
## Chain 2:                3.835 seconds (Sampling)
## Chain 2:                4.253 seconds (Total)
## Chain 2: 
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 3).
## Chain 3: 
## Chain 3: Gradient evaluation took 0.00046 seconds
## Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 4.6 seconds.
## Chain 3: Adjust your expectations accordingly!
## Chain 3: 
## Chain 3: 
## Chain 3: WARNING: There aren't enough warmup iterations to fit the
## Chain 3:          three stages of adaptation as currently configured.
## Chain 3:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 3:          the given number of warmup iterations:
## Chain 3:            init_buffer = 15
## Chain 3:            adapt_window = 75
## Chain 3:            term_buffer = 10
## Chain 3: 
## Chain 3: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 3: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 3: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 3: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 3: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 3: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 3: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 3: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 3: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 3: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 3: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 3: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 3: 
## Chain 3:  Elapsed Time: 0.409 seconds (Warm-up)
## Chain 3:                3.713 seconds (Sampling)
## Chain 3:                4.122 seconds (Total)
## Chain 3: 
## Computing post-estimation metrics (including lvs if requested)...
## blavaan 0.5.4 ended normally after 1000 iterations
## 
##   Estimator                                      BAYES
##   Optimization method                             MCMC
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
##   Statistic                                 MargLogLik         PPP
##   Value                                      -3805.472       0.000

9.0.3 Elección del Estimador

La elección del estimador depende de las características de nuestros datos y de las hipótesis subyacentes en tu modelo. Aquí hay algunas pautas generales:

  1. ML (Maximum Likelihood): Utilizado comúnmente cuando se asume que los datos siguen una distribución normal multivariada.

  2. MLR, MLM, MLF: Utilizados cuando los datos no cumplen con la normalidad multivariada.

  3. WLS, WLSM, WLSMV, DWLS: Preferidos para datos categóricos u ordinales.

  4. ULS, ULSM: Utilizados cuando se prefieren métodos no ponderados.

  5. Bayes: Útil para modelos complejos o cuando se desea incorporar información a priori.

Cada estimador tiene sus propias ventajas y desventajas, por lo que es importante considerar las características de tus datos y el objetivo de tu análisis al seleccionar el estimador adecuado.

10 Output de cfa: métodos de optimización

10.0.1 Características de NLMINB

1. Manejo de Restricciones.

NLMINB puede manejar tanto restricciones de igualdad como de desigualdad en los parámetros, lo cual es útil en muchos problemas prácticos donde ciertos parámetros deben mantenerse dentro de ciertos límites.

2. Robustez.

Es un algoritmo robusto, lo que significa que puede converger en una solución óptima en una amplia variedad de problemas, incluyendo aquellos que son difíciles de resolver para otros algoritmos de optimización.

3. Convergencia.

Funciona bien en problemas de optimización donde otros métodos podrían no converger, especialmente en presencia de restricciones complicadas.

10.0.2 Otros método de optimización en lavaan (aparte de NLMINB)

Además de NLMINB, lavaan ofrece otros métodos de optimización. Aquí hay una lista de algunas de las opciones y sus características principales:

  1. BFGS: Método Broyden-Fletcher-Goldfarb-Shanno, un algoritmo quasi-Newton que es adecuado para problemas suaves y bien comportados. No maneja restricciones explícitas tan fácilmente como NLMINB.

  2. L-BFGS-B: Una variante del BFGS que permite restricciones en los parámetros (cotas inferiores y superiores), útil en problemas donde los parámetros necesitan estar dentro de ciertos rangos.

  3. CG: Gradiente conjugado, adecuado para problemas grandes y dispersos. Es menos intensivo en memoria comparado con BFGS.

  4. SANN: Recocido simulado (Simulated Annealing), un algoritmo de optimización global que puede evitar mínimos locales, aunque es menos eficiente para encontrar soluciones precisas.

  5. Nelder-Mead: Método simplex, útil para problemas sin restricciones no lineales. Es robusto, pero puede ser menos eficiente en problemas de gran escala.

  6. solnp: Método de optimización no lineal con restricciones, útil en problemas que tienen tanto restricciones lineales como no lineales.

10.0.3 Otros método de optimización en lavaan (ejemplos)

1. A manera de ejemplo, para ajustar el modelo utilizando el método BFGS, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, optim.method = "BFGS")
fit
## lavaan 0.6.17 ended normally after 86 iterations
## 
##   Estimator                                         ML
##   Optimization method                             BFGS
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000

2. A manera de ejemplo, para ajustar el modelo utilizando el método solnp, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, optim.method = "solnp")
fit
## lavaan 0.6.17 did not run (perhaps do.fit = FALSE)?
## ** WARNING ** Estimates below are simply the starting values
## 
##   Estimator                                         ML
##   Optimization method                            SOLNP
##   Number of model parameters                        21
## 
##   Number of observations                           301

11 Output de cfa: interceptos

11.0.1 Interpretación de los interceptos en lavaan

El paquete lavaan sigue ciertas convenciones y suposiciones en el análisis CFA que afectan la estimación y conteo de los parámetros:

1. Modelo en Escala Estándar (Standardized Solution).

  • En la solución estándar, las medias de los factores latentes se fijan a cero (\(\alpha_1=0\), \(\alpha_2=0\), \(\alpha_3=0\)).

  • Esto implica que las medias de las variables observadas se explican únicamente en términos de sus interceptos y no se requieren estimaciones adicionales de los interceptos.

2. Identificación del Modelo.

  • Para asegurar que el modelo sea identificable, a menudo se fijan ciertos parámetros a valores conocidos (por ejemplo, fijar una carga factorial a 1 y los interceptos de los factores a cero).

  • En consecuencia, los interceptos de los factores no se estiman de manera explícita en el modelo porque ya se asumen como parte del ajuste global del modelo.

11.0.2 Total de parámetros en cada grupo

Para explicar por qué el output de lavaan::cfa muestra 21 parámetros, debemos desglosar los componentes del modelo y los parámetros que se estiman.

Vamos a enumerar los parámetros para el modelo especificado:

1. Cargas Factoriales.

Cada indicador tiene una carga factorial para el factor al que está asignado:

  • Visual: x1, x2, x3.

  • Textual: x4, x5, x6.

  • Speed: x7, x8, x9.

Cada uno de estos indicadores tiene una carga factorial, sumando un total de 9 cargas factoriales.

2. Interceptos de los Factores Latentes.

Cada indicador tiene asociado un intecepto para x1, x2, x3, x4, x5, x6, x7, x8 y x9. Entonces, en total serían 9 interceptos.

3. Varianzas de los Errores de Medición:

Cada indicador tiene una varianza de error asociada para x1, x2, x3, x4, x5, x6, x7, x8 y x9. Esto suma 9 parámetros.

4. Medias de los factores.

Cada factor tiene asociada una media:

  • Media de Visual.

  • Media de Textual.

  • media de Speed.

Es decir, serían 3 parámetros.

5. Varianzas de los Factores Latentes.

Hay tres factores latentes (Visual, Textual, Speed), y se estima una varianza para cada uno:

  • Varianza de Visual.

  • Varianza de Textual.

  • Varianza de Speed.

Esto suma 3 parámetros.

6. Covarianzas entre los Factores Latentes.

Hay covarianzas entre cada par de factores latentes. Para tres factores, esto se calcula como \({3 \choose 2}=3\) covarianzas:

  • Covarianza de Visual-Textual.

  • Covarianza de Visual-Speed.

  • Covarianza de Textual-Speed.

Esto suma 3 parámetros.

11.0.3 Suma Total de Parámetros

Sumando todos los valores anteriores, tenemos (véase la Figura 11.1):

  1. Cargas factoriales: 9

  2. Interceptos de los Factores Latentes: 9

  3. Varianzas de los errores de medición: 9

  4. Medias de los factores: 3

  5. Varianzas de los factores: 3

  6. Covarianzas entre factores: 3

\[9 \;+\; 9\; +\; 9\; + \;3\; + \;3 \;+ \;3 \;=\; 36\]

En la Figura 11.1 se visualiza lo anterior.

**Total de parámetros en el modelo CFA no estándar**

Figure 11.1: Total de parámetros en el modelo CFA no estándar

11.0.4 Consideración de parámetros conocidos

  1. En muchos casos, uno de los indicadores para cada factor se fija a 1 para que el modelo sea identificable: \[\lambda_1\;=\; \lambda_4\;=\; \lambda_7\;=\; 1\]

  2. Esto significa que para cada factor, una de las cargas factoriales no se estima (ya que se fija). Dado que hay 3 factores, esto resta 3 parámetros del total

  3. Por defecto, el paquete lavaan estima un modelo en Escala Estándar. Por esta razón:

  • Las medias de los tres factores latentes se fijan a cero (o sea, debe restarse 3 parámetros del total):

\[\alpha_1 \;=\; \alpha_2 \;=\; \alpha_3 \;=\; 0\]

  • Las medias de las variables observadas se explican únicamente en términos de sus interceptos y no se requieren estimaciones adicionales de los interceptos (o sea, también debe restarse 9 parámetros del total):

\[\tau_1 \;=\; \tau_2 \;=\; \tau_3 \;=\; \tau_4 \;=\; \tau_5 \;=\; \tau_6 \;=\; \tau_7 \;=\; \tau_8 \;=\; \tau_9 \;=\; 0\]

  1. Entonces, restando estos 15 parámetros fijos, tenemos:

\[36\;−\;15\; =\; 21\]

  1. En la Figura 11.2 se visualiza lo anterior.
**Total de parámetros según `lavaan` (eliminando parámetros fijos)**

Figure 11.2: Total de parámetros según lavaan (eliminando parámetros fijos)

11.0.5 Conclusión: total definitivo de parámetros

  1. Los 21 parámetros en el output del modelo se distribuyen de la siguiente manera:
  • 6 cargas factoriales estimadas (3 factores x 3 indicadores, menos 3 fijas).

  • 0 interceptos.

  • 9 varianzas de los errores de medición.

  • 0 medias de los factores latentes.

  • 3 varianzas de los factores latentes.

  • 3 covarianzas entre los factores latentes.

  1. Esto da un total de 21 parámetros estimados en el modelo CFA utilizando los datos HolzingerSwineford1939 y el modelo especificado.

  2. En la Figura 11.3 se visualiza lo anterior.

**Número de parámetros según `lavaan`**

Figure 11.3: Número de parámetros según lavaan

12 Output de cfa: segunda parte

12.0.1 Model Test User Model en lavaan

En la Figura 11.3 se resalta la segunda parte del output de lavaan.

**Segunda parte del output de `lavaan` (`cfa`)**

Figure 12.1: Segunda parte del output de lavaan (cfa)

Estos resultados corresponden a una prueba de ajuste del modelo (Model Test). En el contexto de la prueba de ajuste del modelo (Model Test) en lavaan, las hipótesis nula y alternativa son las siguientes:

  • Hipótesis nula (H0): La hipótesis nula en este caso sería que el modelo propuesto se ajusta bien a los datos observados en la muestra. Esto significa que no hay diferencias significativas entre los datos observados y los datos esperados según el modelo.

  • Hipótesis alternativa (H1): La hipótesis alternativa sería que el modelo propuesto no se ajusta bien a los datos observados en la muestra. Esto implica que hay diferencias significativas entre los datos observados y los datos esperados según el modelo, lo que se traduce en un mal ajuste del modelo.

12.0.2 Intepretación: segunda parte

Aquí está el significado de cada uno de los elementos de la salida:

1. Test statistic (Estadístico de prueba).

Es el valor del estadístico de prueba (que tiene distribución chi-cuadrada) y calculado para evaluar el ajuste del modelo. Un valor alto generalmente indica un mal ajuste del modelo a los datos observados. En este caso, el valor es 85.306.

2.Degrees of freedom (Grados de libertad).

Representa el número de valores que son libres de variar una vez que ciertas restricciones son impuestas. En CFA, los grados de libertad se calculan como la diferencia entre el número de observaciones independientes (generalmente el número de entradas en la matriz de covarianza) y el número de parámetros estimados. En este caso, hay 24 grados de libertad.

3. P-value (Chi-square) (Valor p obtenido con la chi-cuadrada).

Es la probabilidad de obtener un valor del estadístico de prueba igual o más extremo que el valor observado, asumiendo que la hipótesis nula es verdadera. En el contexto de lavaan, un valor \(p\) bajo (\(< 0.05\)) generalmente indica un mal ajuste del modelo, lo que significa que los datos observados difieren significativamente de los datos esperados según el modelo. En este caso, el valor p es 0.000, lo que indica que el modelo no se ajusta bien a los datos, ya que la probabilidad de obtener un valor de estadístico de prueba igual o más extremo es muy baja.

13 Función summary de lavaan

13.0.1 summary: descripción

  1. Una vez que el modelo ha sido ajustado, la función summary proporciona un buen resumen del modelo ajustado.

  2. El argumento fit.measures=TRUE en la función summary indica que se desean incluir medidas de ajuste del modelo en el resumen del modelo.

13.0.2 summary: ejecución y output

Se ejecuta así:

summary(CFA, fit.measures=TRUE)
## lavaan 0.6.17 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.931
##   Tucker-Lewis Index (TLI)                       0.896
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3737.745
##   Loglikelihood unrestricted model (H1)      -3695.092
##                                                       
##   Akaike (AIC)                                7517.490
##   Bayesian (BIC)                              7595.339
##   Sample-size adjusted Bayesian (SABIC)       7528.739
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.092
##   90 Percent confidence interval - lower         0.071
##   90 Percent confidence interval - upper         0.114
##   P-value H_0: RMSEA <= 0.050                    0.001
##   P-value H_0: RMSEA >= 0.080                    0.840
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.065
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                0.554    0.100    5.554    0.000
##     x3                0.729    0.109    6.685    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.113    0.065   17.014    0.000
##     x6                0.926    0.055   16.703    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.180    0.165    7.152    0.000
##     x9                1.082    0.151    7.155    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual           0.408    0.074    5.552    0.000
##     speed             0.262    0.056    4.660    0.000
##   textual ~~                                          
##     speed             0.173    0.049    3.518    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.549    0.114    4.833    0.000
##    .x2                1.134    0.102   11.146    0.000
##    .x3                0.844    0.091    9.317    0.000
##    .x4                0.371    0.048    7.779    0.000
##    .x5                0.446    0.058    7.642    0.000
##    .x6                0.356    0.043    8.277    0.000
##    .x7                0.799    0.081    9.823    0.000
##    .x8                0.488    0.074    6.573    0.000
##    .x9                0.566    0.071    8.003    0.000
##     visual            0.809    0.145    5.564    0.000
##     textual           0.979    0.112    8.737    0.000
##     speed             0.384    0.086    4.451    0.000

14 Output de summary: partes 1 y 2

14.0.1 Información general del modelo

  1. El modelo finalizó normalmente después de 35 iteraciones.

  2. El estimador utilizado fue el máximo verosimilitud (ML).

  3. El método de optimización fue NLMINB.

  4. El modelo tiene 21 parámetros.

  5. Se utilizaron 301 observaciones en el ajuste del modelo.

  6. En la Figura 15.1 se puede visualizar la parte No. 1 del output de lavaan::summary (es la misma que aparece en la Figura 8.1).

14.0.2 Prueba de ajuste del modelo (Model Test User Model)

  1. El estadístico de prueba es 85.306.

  2. El modelo tiene 24 grados de libertad.

  3. El valor p asociado al Chi-cuadrado es 0.000, lo que indica que el modelo no se ajusta bien a los datos (valor p significativamente menor que 0.05).

  4. En la Figura 15.1 se puede visualizar la parte No. 2 del output de lavaan::summary (es la misma que aparece en la Figura 12.1).

15 Output de summary: test modelo nulo

15.0.1 Test Baseline Model: Modelo nulo (Baseline Model)

  1. El Modelo Baseline (o modelo nulo) es un modelo muy restringido que asume que todas las variables observadas son independientes entre sí.

  2. Es decir, no hay correlaciones entre las variables.

  3. En este modelo, todas las covarianzas entre las variables observadas se establecen a cero.

15.0.2 Test Baseline Model: modelo nulo en R

Para ello se ejecuta el siguiente código:

model_null <- '
  x1 ~~ x1
  x2 ~~ x2
  x3 ~~ x3
  x4 ~~ x4
  x5 ~~ x5
  x6 ~~ x6
  x7 ~~ x7
  x8 ~~ x8
  x9 ~~ x9
'

# Ajustar el modelo nulo
fit_null <- cfa(model_null, data = dat)
fit_null
## lavaan 0.6.17 ended normally after 16 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         9
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value (Chi-square)                           0.000

15.0.3 Test Baseline Model: gráficar modelo nulo en R

Para ello, se puede ejecutar el siguiente código:

semPaths(fit_null, 
         what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         #what = "eq",     #Muestra las ecuaciones estructurales del modelo 
         
         layout = "tree",    #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         
         title = FALSE,        #No muestra el título del gráfico
         
         edge.color = "Red", #Establece el color de los bordes (aristas) en negro
         sizeMan = 8,    #Tamaño de los nodos que representan variables manifiestas
         color = list(man = "lightgreen" #Color de las variables observadas
                     ) 
         )

15.0.4 Test Baseline Model: gráfico de parte No. 3

En la Figura 15.1 se resalta la parte No. 3 del output de lavaan::summary.
**Parte No. 3 del output de `lavaan::summary` (`Test Baseline Model`)**

Figure 15.1: Parte No. 3 del output de lavaan::summary (Test Baseline Model)

15.0.5 Test Baseline Model: hipótesis

1. La hipótesis nula (\(H_0\)) para el Model Test Baseline Model

Viene dada por:

\[H0: \;\text{El modelo nulo se ajusta bien a los datos}\]

Esto implica que las covarianzas entre las variables observadas no son significativamente diferentes de cero, es decir, que todas las variables observadas son independientes entre sí.

2. La hipótesis alternativa (\(H_1\))

Viene dad por:

\[H_1: \;\text{El modelo nulo no se ajusta bien a los datos}\] Esto implica que hay relaciones significativas entre las variables observadas, es decir, que las covarianzas entre las variables observadas son diferentes de cero.

15.0.6 Test Baseline Model: interpretaciones

1. Estadístico de Chi-Cuadrado (\(\chi^2\)).

Mide la discrepancia entre la matriz de covarianza observada y la matriz de covarianza estimada bajo el modelo nulo. En este caso, el valor del estadístico es de 918.852.

2. Grados de Libertad (df).

La distribución se ajsuta con 36 grados de libertad.

3. Valor P.

Indica si la discrepancia observada (estadístico \(\chi^2\)) es significativa. Dado que el valor \(p\) es menor que 0.05, se rechaza la hipótesis nula (\(H_0\)), indicando que el modelo nulo no se ajusta bien a los datos y que existen relaciones significativas entre las variables observadas.

16 Output de summary: user vs baseline

16.0.1 User vs Baseline: output de summary

En la Figura 16.1 se resalta la parte No. 4 del output de lavaan::summary.
**Parte No. 4 del output de `lavaan::summary` (`User vs Baseline`)**

Figure 16.1: Parte No. 4 del output de lavaan::summary (User vs Baseline)

16.0.2 User vs Baseline: descripción

  1. El User Model se refiere al modelo que el usuario ha especificado y que lavaan está analizando.

  2. El output User Model versus Baseline Model se refiere a la comparación entre el modelo especificado por el usuario (User Model) y el modelo de referencia, también conocido como modelo baseline o nulo (Baseline Model).

16.0.3 User vs Baseline: hipótesis

1. Hipótesis Nula (\(H_0\)).

  • La hipótesis nula (\(H_0\)) es que el modelo especificado por el usuario no se ajusta significativamente mejor que el modelo de referencia.

  • Es decir, no hay diferencia significativa entre el ajuste del modelo del usuario y el modelo nulo.

  • Matemáticamente, esto se podría expresar como:

\[H_0: \text{El User Model se ajusta significativamente mejor que el Baseline Model}\]

2. Hipótesis Alternativa (\(H_1\)).

  • La hipótesis alternativa (\(H_1\)) es que el modelo especificado por el usuario se ajusta significativamente mejor que el modelo de referencia.

  • Es decir, hay una diferencia significativa entre el ajuste del modelo del usuario y el modelo nulo.

  • Matemáticamente, esto se podría expresar como:

\[H_1: \text{El User Model se ajusta significativamente mejor que el Baseline Model}\]

16.0.4 User vs Baseline: CFI y TLI (generalidades)

  1. Esta comparación permite evaluar qué tan bien se ajusta el modelo propuesto por el usuario en comparación con un modelo muy simple que asume independencia completa entre las variables observadas.

  2. La comparación entre el User Model y el Baseline Model proporciona información valiosa sobre la adecuación del modelo propuesto por el usuario en relación con un modelo extremadamente simple.

  3. Esto se realiza utilizando diversos criterios de ajuste, como el Chi-cuadrado (\(\chi^2\)), el Comparative Fit Index (CFI), el Tucker-Lewis Index (TLI), entre otros.

  4. Si el modelo propuesto por el usuario se ajusta significativamente mejor que el modelo de referencia (por ejemplo, un Chi-cuadrado significativamente más bajo y/o valores más altos de CFI y TLI), indica que el modelo propuesto proporciona un mejor ajuste a los datos en comparación con el modelo de referencia.

  5. Esto sugiere que la estructura propuesta en el modelo del usuario es válida y representa la relación entre las variables de manera más precisa que el modelo nulo.

  6. Por otro lado, si el modelo propuesto por el usuario no se ajusta significativamente mejor que el modelo de referencia, podría indicar que el modelo propuesto no proporciona un mejor ajuste a los datos en comparación con el modelo nulo, lo que sugiere que la estructura propuesta puede no ser adecuada o que se necesitan ajustes adicionales para mejorar la adecuación del modelo.

16.0.5 User vs Baseline: CFI y TLI (interpretaciones)

1. Generalidad.

El Comparative Fit Index (CFI) y el Tucker-Lewis Index (TLI) son dos índices de ajuste comúnmente utilizados en el análisis factorial confirmatorio (CFA) para evaluar qué tan bien se ajusta un modelo especificado por el usuario a los datos observados en comparación con un modelo de referencia, como el modelo nulo o baseline. BAsado en los resultados encontrados (parte No. 4 del output), estos valores se puden interpretar de la siguiente manera:

2. Comparative Fit Index (CFI).

  • El CFI es un índice que evalúa qué tan bien se ajusta el modelo especificado por el usuario en comparación con el modelo nulo.

  • Un CFI cercano a 1 indica un buen ajuste del modelo, donde un valor de 1 indica un ajuste perfecto.

  • En general, un valor de CFI mayor a 0.90 se considera aceptable, aunque valores más cercanos a 0.95 o mayores indican un mejor ajuste.

  • Interpretación: Un CFI de 0.931 sugiere que el modelo especificado por el usuario explica aproximadamente el 93.1% de la varianza y la covarianza observada en los datos, en comparación con el modelo nulo.

3. Tucker-Lewis Index (TLI).

  • El TLI, también conocido como Non-Normed Fit Index (NNFI), es otro índice de ajuste que evalúa qué tan bien se ajusta el modelo especificado por el usuario en comparación con el modelo nulo.

  • Al igual que con el CFI, un valor de TLI mayor a 0.90 se considera aceptable, aunque valores más cercanos a 0.95 o mayores indican un mejor ajuste.

  • Interpretación: Un TLI de 0.896 sugiere que el modelo especificado por el usuario explica aproximadamente el 89.6% de la varianza y la covarianza observada en los datos, en comparación con el modelo nulo.

17 Output de summary: loglik and criterios

17.0.1 Loglik and Criteria: output gráfico

En la Figura 17.1 se resalta la parte No. 5 del output de lavaan::summary.
**Parte No. 5 del output de `lavaan::summary` (`Loglikelihood and Information Criteria`)**

Figure 17.1: Parte No. 5 del output de lavaan::summary (Loglikelihood and Information Criteria)

17.0.2 Loglik and Criteria: log-verosimilitud

Estos resultados pertenecen a la comparación del modelo del usuario (modelo especificado) con el modelo de referencia (modelo nulo) en términos de la función de verosimilitud logarítmica. Aquí está su interpretación:

1. Loglikelihood del modelo del usuario (\(H_0\)).

El valor de la log-verosimilitud (loglikelihood) para el modelo del usuario, que es el modelo especificado por el usuario. En este caso, el loglikelihood del modelo del usuario es -3737.745.

2. Loglikelihood del modelo no restringido (\(H_1\)).

El valor de la log-verosimilitud para el modelo no restringido, que es un modelo donde no se imponen restricciones (es decir, un modelo donde todas las covarianzas son libres de ser estimadas). En este caso, el loglikelihood del modelo no restringido es -3695.092.

17.0.3 Loglik and Criteria: criterios de Información

Estos resultados pertenecen a la comparación del modelo del usuario (modelo especificado) con el modelo de referencia (modelo nulo) en términos de varios criterios de información. Aquí está su interpretación:

1. Criterio de Información de Akaike (AIC).

Un criterio de selección de modelo que penaliza el sobreajuste del modelo al tener en cuenta el número de parámetros estimados. Se prefiere un valor de AIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo. En este caso, el valor del AIC es 7517.490.

2. Criterio de Información Bayesiana (BIC).

Similar al AIC pero con una penalización más fuerte por el número de parámetros. Se prefiere un valor de BIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo. En este caso, el valor del BIC es 7595.339.

3. Criterio de Información Bayesiana Ajustado por el Tamaño de la Muestra (SABIC).

Una variante del BIC que también tiene en cuenta el tamaño de la muestra. Se prefiere un valor de SABIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo, la complejidad del modelo y el tamaño de la muestra. En este caso, el valor del SABIC es 7528.739.

17.0.4 Loglik and Criteria: Interpretaciones generales

  1. En general, se prefiere un loglikelihood más alto, ya que indica un mejor ajuste del modelo a los datos.

  2. Para los criterios de información (AIC, BIC, SABIC), se prefieren valores más bajos, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo.

  3. En este caso, el modelo no restringido (\(H_1\)) tiene un loglikelihood más alto y valores más bajos para los criterios de información en comparación con el modelo del usuario (\(H_0\)).

  4. Esto sugiere que el modelo no restringido proporciona un mejor ajuste a los datos en comparación con el modelo del usuario.

  5. Sin embargo, la elección del modelo final debe basarse en una evaluación completa que considere tanto el ajuste del modelo como la teoría subyacente y los objetivos de investigación.

18 Output de summary: RMSEA

18.0.1 Root Mean Square: output gráfico

En la Figura 18.1 se resalta la parte No. 3 del output de lavaan::summary.
**Parte No. 6 del output de `lavaan::summary` (`Root Mean Square`)**

Figure 18.1: Parte No. 6 del output de lavaan::summary (Root Mean Square)

18.0.2 Root Mean Square: generalidades

Para interpretar el Root Mean Square Error of Approximation (RMSEA) y el Standardized Root Mean Square Residual (SRMR), se necesitan algunos detalles adicionales sobre el contexto del análisis factorial confirmatorio (CFA) y los criterios de ajuste utilizados. Estos valores se utilizan para evaluar el ajuste del modelo propuesto a los datos observados. Aquí está la interpretación:

18.0.3 Root Mean Square: RMSEA (interpretación)

  1. El RMSEA (Raíz del Error Cuadrático Medio de Aproximación) es una medida de ajuste del modelo que indica cuánto se espera que el modelo se desvíe de los datos poblacionales en términos de la medida de error cuadrático medio.

  2. Generalmente, se considera que un valor de RMSEA menor o igual a 0.05 indica un buen ajuste, valores entre 0.05 y 0.08 indican un ajuste moderado y valores superiores a 0.1 indican un ajuste deficiente.

  3. En nuestro output, \(RMSEA = 0.092\).

  4. Este valor indica que el modelo propuesto tiene un ajuste moderado a los datos.

18.0.4 Root Mean Square: RMSEA (90% IC)

  1. El intervalo de Confianza del 90% (90 Percent confidence interval) Proporciona una estimación de la precisión del RMSEA.

  2. Los límites inferior y superior del intervalo de confianza indican el rango plausible de valores de RMSEA.

  3. En este caso, el IC 90% va desde 0.071 hasta 0.114.

18.0.5 Root Mean Square: RMSEA (P-value)

1. P-value H0: RMSEA <= 0.050 = 0.001.

  • Este valor \(p\) es el resultado de una prueba de hipótesis sobre si el RMSEA es menor o igual a 0.05.

  • Un valor p bajo (por debajo del nivel de significancia común de 0.05) sugiere que el modelo no se ajusta bien a los datos, ya que el RMSEA es significativamente mayor que 0.05.

2. P-value H0: RMSEA >= 0.080 = 0.840.

  • Este valor p es el resultado de una prueba de hipótesis sobre si el RMSEA es mayor o igual a 0.08.

  • Un valor p alto (por encima del nivel de significancia común de 0.05) sugiere que el modelo se ajusta bien a los datos, ya que el RMSEA no es significativamente mayor que 0.08.

18.0.6 Root Mean Square: SRMR (interpretación)

  1. El SRMR (Residual Estandarizado del Error Cuadrático Medio de Aproximación) es una medida de ajuste del modelo que indica cuánto se espera que la matriz de covarianza de los residuos estandarizados se desvíe de la matriz de covarianza de residuos poblacionales.

  2. Generalmente, se considera que un valor de SRMR menor o igual a 0.08 indica un buen ajuste, mientras que valores superiores a 0.1 indican un ajuste deficiente.

  3. En nuestro output, \(SRMR = 0.065\).

  4. Este valor indica que el modelo propuesto tiene un ajuste moderado a los datos.

18.0.7 Root Mean Square: RMSEA y SRMR (conclusiones)

  1. En resumen, estos valores de ajuste (RMSEA y SRMR) sugieren que el modelo propuesto tiene un ajuste moderado a los datos.

  2. A pesar de lo anterior:

  • El RMSEA sugiere un ajuste algo deficiente debido a su valor cercano a 0.1.

  • Y el valor \(p\) asociado con \(RMSEA \leq 0.050\) también sugiere una mala adaptación.

19 Output de summary: estimación de parámetros

19.0.1 Estimates: output gráfico

  1. Se proporcionan estimaciones de los parámetros del modelo, como las cargas factoriales, covarianzas entre variables latentes y varianzas de las variables observadas y latentes, entre otros.

  2. Cada fila representa una relación entre variables observadas y latentes o entre variables latentes, mostrando el estimado de la relación, su error estándar, valor \(z\) y valor \(p\) asociado.

  3. En la Figura 19.1 se resalta la parte No. 6 del output de lavaan::summary.

    **Parte No. 6 del output de `lavaan::summary` (`Parameter Estimates`)**

    Figure 19.1: Parte No. 6 del output de lavaan::summary (Parameter Estimates)

19.0.2 Estimates: output gráfico (explicaciones)

En el gráfico anterior, vemos cuatro partes (explicaremos cada una de ellas en secciones siguientes):

  1. Parte 6a: Información general.

  2. Parte 6b: Estimaciones de las cargas factoriales de las variables latentes (visual, textual, speed) en las variables observadas (x1, …,x9).

  3. Parte 6c: Estimaciones de las covarianzas entre las variables latentes.

  4. Parte 6d: Estimaciones de las varianzas de las variables observadas y latentes.

20 Output de Estimate: 6a (información general)

20.0.1 Estimate: parte 6a (output gráfico)

En la Figura 20.1 se resalta la parte No. 6a del output de lavaan::summary.
**Parte No. 6a del output de `lavaan::summary` (`General information`)**

Figure 20.1: Parte No. 6a del output de lavaan::summary (General information)

21 Output de Estimate: 6a (información general)

21.0.1 Estimate: parte 6a (interpretaciones)

La sección de Parameter Estimates en el resumen de resultados de lavaan contiene información importante sobre los errores estándar y la información utilizada para calcularlos. Aquí hay una interpretación detallada de las líneas específicas que se han mencionado:

1. Standard Errors (Errores Estándar).

  • Indica que los errores estándar han sido calculados.

  • Los errores estándar son medidas de la precisión de las estimaciones de los parámetros; valores más pequeños indican estimaciones más precisas.

2. Information (Información).

  • Esta línea describe el tipo de información que se utilizó para calcular los errores estándar.

  • Existen diferentes métodos para calcular la matriz de información.

  • La elección del método puede influir en los errores estándar y, por lo tanto, en las pruebas de significancia.

3. Information Saturated (H1) Model.

  • La matriz de información del modelo saturado (también conocido como el modelo “h1”) se utiliza para calcular los errores estándar.

  • Un modelo saturado es un modelo que tiene tantos parámetros como sea posible para ajustarse perfectamente a los datos.

  • En otras palabras, es un modelo que asume que todas las variables están correlacionadas libremente.

  • La matriz de información del modelo saturado puede proporcionar una estimación robusta de la variabilidad de los parámetros del modelo.

4. Structured Information.

  • La información estructurada se refiere a la matriz de información derivada del modelo específico que se está evaluando (el modelo del usuario).

  • Esta matriz se basa en las restricciones y especificaciones del modelo del usuario. Proporciona una visión de la variabilidad de los parámetros tal como se estructura en el modelo especificado.

21.0.2 Estimate: parte 6a (interpretación general)

  1. Standard errors: Especifica que se han calculado los errores estándar para las estimaciones de los parámetros del modelo.

  2. Information: Describe que la matriz de información ha sido utilizada para calcular estos errores estándar.

  3. Information saturated (h1) model: Indica que la matriz de información del modelo saturado se ha utilizado para calcular los errores estándar. Este enfoque puede ser más robusto porque no depende de las restricciones del modelo específico.

  4. Structured Information: Se refiere a la matriz de información calculada directamente a partir del modelo del usuario, que incluye todas las especificaciones y restricciones impuestas por el usuario en el modelo.

21.0.3 Estimate: parte 6a (conclución general)

  1. En resumen, esta sección del resumen de resultados de lavaan nos informa que los errores estándar se han calculado utilizando tanto la matriz de información del modelo saturado (h1) como la matriz de información estructurada del modelo del usuario.

  2. Este enfoque proporciona una visión robusta y estructurada de la variabilidad de los parámetros del modelo y de la precisión de las estimaciones de los parámetros.

22 Output de Estimate: 6b (latent variables)

22.0.1 Estimates: parte 6b (output gráfico)

En la Figura 22.1 se resalta la parte No. 6b del output de lavaan::summary.
**Parte No. 6 del output de `lavaan::summary` (`Latent variables`)**

Figure 22.1: Parte No. 6 del output de lavaan::summary (Latent variables)

22.0.2 Estimates: parte 6b (generalidades)

  1. Se presentan las estimaciones de las cargas factoriales de las variables latentes (visual, textual, speed) en las variables observadas (x1, …,x9).

  2. Para cada relación entre una variable latente y sus variables observadas, se muestra la estimación de la carga, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{\lambda}\) de la carga factorial (factor loading) \(\lambda\) para cada indicador en relación con su variable latente correspondiente.

  • Std.Err: Es el error estándar \(S_{\widehat{\lambda}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \(\lambda\) es la carga factorial correspondiente, entonces, las hipótesis que se contrastan son:

\[H_0: \; \lambda = 0 \quad \text{versus} \quad H_1: \; \lambda \ne 0\]

22.0.3 Estimates: parte 6b (ejemplo)

  1. Para la variable latente visual:
  • El indicador x1 tiene una carga factorial fija en \(\widehat{\lambda}_1=1\) (por convención).

  • Mientras que x2 y x3, respectivamente, tienen cargas factoriales estimadas de

\[\widehat{\lambda}_2=0.554, \quad \widehat{\lambda}_3=0.729\]

  • Además, los errores estándares correspondientes son:

\[S_{\widehat{\lambda}_2} = 0.100, \quad S_{\widehat{\lambda}_3} = 0.109\] 3. Los valores \(z\) correspondientes a x2 y x3 son:

\[z_2= \frac{\widehat{\lambda}_2 - 0}{S_{\widehat{\lambda}_2}} = \frac{0.554 - 0}{0.100} = 5.554, \qquad z_2= \frac{\widehat{\lambda}_3 - 0}{S_{\widehat{\lambda}_3}} = \frac{0.729 - 0}{0.109} = 6.685\]

  1. Todos estos valores son significativos (P < 0.05), lo que indica que los indicadores están bien asociados con la variable latente visual:

\[\text{valor}\; p_2 = P(Z_2 > 5.554) = 0, \qquad \text{valor}\; p_3 = P(Z_3 > 6.685) = 0\]

  1. De manera similar, para las variables latentes textual y speed, los indicadores están bien asociados con sus variables latentes correspondientes, ya que todas las cargas factoriales son significativas.

23 Output de Estimate: 6c (covariances)

23.0.1 Estimates: parte 6c (output gráfico)

En la Figura 23.1 se resalta la parte No. 6c del output de lavaan::summary.
**Parte No. 6c del output de `lavaan::summary` (`Covariances`)**

Figure 23.1: Parte No. 6c del output de lavaan::summary (Covariances)

23.0.2 Estimates: parte 6c (generalidades)

  1. Se proporcionan las estimaciones de las covarianzas entre las variables latentes (visual, textual, speed).

  2. Para cada covarianza, se muestra la estimación, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{C}_{ij} = \widehat{Cov}(F_i,F_j)\) de la covarianza \(C_{ij}\) entre las variables latentes \(F_i\) y \(F_j\).

  • Std.Err: Es el error estándar \(S_{\widehat{C}_{ij}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \({C}_{ij}\) es la covarianza correspondiente entre \(F_i\) y \(F_j\), entonces, las hipótesis que se contrastan son:

\[H_0: \; {C}_{ij} = 0 \quad \text{versus} \quad H_1: \; {C}_{ij} \ne 0\]

23.0.3 Estimates: parte 6c (ejemplo)

  1. La covarianza entre visual y textual es de 0.408, lo que indica que estas dos variables latentes están moderadamente correlacionadas.

  2. Esta covarianza es significativa (\(P < 0.05\)), lo que sugiere una relación significativa entre las habilidades visuales y textuales.

  3. Los cálculos correspondientes son muy similares a los realizados en la parte 6b.

24 Output de Estimate: 6d (variances)

24.0.1 Estimates: parte 6d (output gráfico)

En la Figura 24.1 se resalta la parte No. 6d del output de lavaan::summary.
**Parte No. 6d del output de `lavaan::summary` (`Variances`)**

Figure 24.1: Parte No. 6d del output de lavaan::summary (Variances)

24.0.2 Estimates: parte 6c (generalidades)

  1. Se presentan las estimaciones de las varianzas de las variables observadas (x1, …, x9) y latentes (visual, textual, speed).

  2. Para cada varianza, se muestra la estimación, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{C}_{ii}\) de la varianza \(C_{ii}\) entre las variables de interés.

  • Std.Err: Es el error estándar \(S_{\widehat{C}_{ii}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \({C}_{ii}\) es la varianza correspondiente de la variable de interés, entonces, las hipótesis que se contrastan son:

\[H_0: \; {C}_{ii} = 0 \quad \text{versus} \quad H_1: \; {C}_{ii} \ne 0\]

24.0.3 Estimates: parte 6c (ejemplo)

  1. La varianza de la variable latente visual es de 0.809.

  2. Esto indica cuánta varianza en visual no está explicada por sus indicadores.

  3. Esta varianza es significativa (\(P < 0.05\)), lo que sugiere que la variable latente visual contribuye significativamente a la variabilidad en los datos observados.

  4. Los cálculos correspondientes son muy similares a los realizados en la parte 6b.

25 Extrayendo elementos: con inspect

25.0.1 inspect: descripción

  1. El código de abajo proporcionará una tabla que muestra los estimados de los parámetros del modelo CFA.

  2. El output incluye las cargas factoriales (\(\Lambda\)), las varianzas residuales (\(\Theta\)) y las covarianzas entre los factores (\(\Psi\)).

  3. En secciones siguientes se describirán cada uno de ellos.

25.0.2 inspect: ejecución

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

lambda #cargas factoriales
theta  #varianzas residuales (de los errores de las var. observadas)
psi    #covarianzas entre los factores

El output de inspect.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566
## 
## $psi
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

El output de inspect: cargas factoriales.

lambda #cargas factoriales
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082

El output de inspect: varianzas residuales.

theta  #varianzas residuales (de los errores de las var. observadas)
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566

El output de inspect: covarianzas entre los factores.

psi  #varianzas residuales (de los errores de las var. observadas)
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

25.0.3 inspect: argumento what

Para ver cómo lavaan representa internamente un modelo, puede escribir:

El código.

inspect(fit, what="list")

El output.

##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est se
## 1  1.000  0
## 2  0.778 NA
## 3  1.107 NA
## 4  1.000  0
## 5  1.133 NA
## 6  0.924 NA
## 7  1.000  0
## 8  1.225 NA
## 9  0.854 NA
## 10 0.679 NA
## 11 0.691 NA
## 12 0.637 NA
## 13 0.675 NA
## 14 0.830 NA
## 15 0.598 NA
## 16 0.592 NA
## 17 0.511 NA
## 18 0.508 NA
## 19 0.050 NA
## 20 0.050 NA
## 21 0.050 NA
## 22 0.000 NA
## 23 0.000 NA
## 24 0.000 NA

Esto es equivalente a la función parTable. La tabla que se devuelve aquí se denomina tabla de parámetros. Se explicará en secciones siguientes.

26 Extrayendo elementos: con lavInspect

26.0.1 lavInspect: explicación

La función lavInspect acepta varios argumentos para especificar qué aspecto del modelo se desea inspeccionar. Algunos de los argumentos comunes incluyen:

1. object.

El modelo ajustado del cual se desean inspeccionar las propiedades.

2. what.

especifica qué propiedad del modelo se desea inspeccionar. Esto puede ser “est” para los parámetros estimados, “residuals” para los residuos, “cov” para las covarianzas, entre otros.

3. label.

Opcionalmente, permite especificar un nombre para etiquetar el resultado.

26.0.2 lavInspect: ejecución

  1. Por ejemplo, para inspeccionar los parámetros estimados de un modelo ajustado CFA, puedes usar lavInspect(fit, "est").

  2. Esto devolverá una tabla que muestra los parámetros estimados del modelo, incluyendo las cargas factoriales, las varianzas residuales y las covarianzas entre los factores.

  3. El output es exactamente el mismo que se obtiene con inspect.

27 lavInspect: ejemplos

27.0.1 lavInspect: ejemplo 1

Por defecto, al llamar a lavInspect sobre un objeto lavaan ajustado se obtiene una lista de las matrices del modelo que se utilizan internamente para representar el modelo. Los parámetros libres son enteros distintos de cero.

El código.

lavInspect(fit)

El output.

## $lambda
##    visual textul speed
## x1      0      0     0
## x2      1      0     0
## x3      2      0     0
## x4      0      0     0
## x5      0      3     0
## x6      0      4     0
## x7      0      0     0
## x8      0      0     5
## x9      0      0     6
## 
## $theta
##    x1 x2 x3 x4 x5 x6 x7 x8 x9
## x1  7                        
## x2  0  8                     
## x3  0  0  9                  
## x4  0  0  0 10               
## x5  0  0  0  0 11            
## x6  0  0  0  0  0 12         
## x7  0  0  0  0  0  0 13      
## x8  0  0  0  0  0  0  0 14   
## x9  0  0  0  0  0  0  0  0 15
## 
## $psi
##         visual textul speed
## visual      16             
## textual     19     17      
## speed       20     21    18

27.0.2 lavInspect: ejemplo 2

Para ver cómo lavaan representa internamente un modelo, puede escribir:

lavInspect(CFA, what = "list")
##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est    se
## 1  1.000 0.000
## 2  0.554 0.100
## 3  0.729 0.109
## 4  1.000 0.000
## 5  1.113 0.065
## 6  0.926 0.055
## 7  1.000 0.000
## 8  1.180 0.165
## 9  1.082 0.151
## 10 0.549 0.114
## 11 1.134 0.102
## 12 0.844 0.091
## 13 0.371 0.048
## 14 0.446 0.058
## 15 0.356 0.043
## 16 0.799 0.081
## 17 0.488 0.074
## 18 0.566 0.071
## 19 0.809 0.145
## 20 0.979 0.112
## 21 0.384 0.086
## 22 0.408 0.074
## 23 0.262 0.056
## 24 0.173 0.049

Esto es equivalente a la función parTable. La tabla que se devuelve aquí se denomina tabla de parámetros. Se explicará en secciones siguientes.

27.0.3 lavInspect: ejemplo 3

Estimar las cargas factoriales, las varianzas residuales y las covarianzas entre los factores carga factorial, varianza residual y covarianza entre factores.

El código.

lavInspect(fit, "est")

El output.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.778  0.000 0.000
## x3  1.107  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.133 0.000
## x6  0.000  0.924 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.225
## x9  0.000  0.000 0.854
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.679                                                
## x2 0.000 0.691                                          
## x3 0.000 0.000 0.637                                    
## x4 0.000 0.000 0.000 0.675                              
## x5 0.000 0.000 0.000 0.000 0.830                        
## x6 0.000 0.000 0.000 0.000 0.000 0.598                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.592            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.511      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.508
## 
## $psi
##         visual textul speed
## visual    0.05             
## textual   0.00   0.05      
## speed     0.00   0.00  0.05

27.0.4 lavInspect: ejemplo 4

Estimar la matriz de covarianzas implicada.

El código.

lavInspect(CFA, "sigma")

El output.

##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

28 Extrayendo con parTable

  1. La función se utiliza para generar una tabla que resume los parámetros estimados de un modelo ajustado.

  2. Esta tabla proporciona una visión general de los parámetros del modelo, incluyendo las cargas factoriales, las varianzas residuales, las covarianzas entre los factores y otras estadísticas relevantes.

El código.

parTable(CFA)

El output.

##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est    se
## 1  1.000 0.000
## 2  0.554 0.100
## 3  0.729 0.109
## 4  1.000 0.000
## 5  1.113 0.065
## 6  0.926 0.055
## 7  1.000 0.000
## 8  1.180 0.165
## 9  1.082 0.151
## 10 0.549 0.114
## 11 1.134 0.102
## 12 0.844 0.091
## 13 0.371 0.048
## 14 0.446 0.058
## 15 0.356 0.043
## 16 0.799 0.081
## 17 0.488 0.074
## 18 0.566 0.071
## 19 0.809 0.145
## 20 0.979 0.112
## 21 0.384 0.086
## 22 0.408 0.074
## 23 0.262 0.056
## 24 0.173 0.049

29 Extrayendo cargas factoriales

29.0.1 Cargas: solo estimados (con inspect)

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

lambda #cargas factoriales
#theta  #varianzas residuales
#psi    #covarianzas entre los factores

El otuput.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566
## 
## $psi
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082

29.0.2 Cargas: sin significancia

  1. En el output de abajo, el argumento standardized=TRUE indica que se deben devolver las estimaciones estandarizadas.

  2. La estimación estandarizada se ajusta por el error estándar de la variable implicada, permitiendo así la comparación entre diferentes parámetros en una escala común.

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  filter(op == "=~") %>%
  select('Factor'=lhs, 
         'Indicador'=rhs, 
         'Estimación'=est, 
         'Error std.'=se, 
         'Estimación std.'=std.all, #Estimaciones estandarizadas
         'Z'=z, 
         'p valor'= pvalue
         ) %>%
  
kable(digits = 3, align="c", format="pandoc", caption="Factor Loadings")

El output.

Table 29.1: Factor Loadings
Factor Indicador Estimación Error std. Estimación std. Z p valor
visual x1 1.000 0.000 0.772 NA NA
visual x2 0.554 0.100 0.424 5.554 0
visual x3 0.729 0.109 0.581 6.685 0
textual x4 1.000 0.000 0.852 NA NA
textual x5 1.113 0.065 0.855 17.014 0
textual x6 0.926 0.055 0.838 16.703 0
speed x7 1.000 0.000 0.570 NA NA
speed x8 1.180 0.165 0.723 7.152 0
speed x9 1.082 0.151 0.665 7.155 0

29.0.3 Cargas: con significancia

En la salida de abajo, los asteriscos indican la significancia de la estimación basada en los valores \(p\) (*** para \(p < .001\), ** para \(p < .01\), * para \(p < .05\)).

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  
  filter(op == "=~") %>%
  mutate(stars = ifelse(pvalue < .001, "***",
                        ifelse(pvalue < .01, "**",
                               ifelse(pvalue < .05, "*", "")))) %>%
  select('Factor'=lhs,
         'Indicador'=rhs,
         'Estimación'=est,
         'Error std.'=se, 
         'Z'=z,
         'Estimación std.'=std.all, #Estimaciones estandarizadas
         'p valor'= pvalue, 
         'Sig.'=stars) %>%
  
kable(digits = 3, align="c", format="pandoc", caption="Cargas factoriales")

El output.

Table 29.2: Cargas factoriales
Factor Indicador Estimación Error std. Z Estimación std. p valor Sig.
visual x1 1.000 0.000 NA 0.772 NA NA
visual x2 0.554 0.100 5.554 0.424 0 ***
visual x3 0.729 0.109 6.685 0.581 0 ***
textual x4 1.000 0.000 NA 0.852 NA NA
textual x5 1.113 0.065 17.014 0.855 0 ***
textual x6 0.926 0.055 16.703 0.838 0 ***
speed x7 1.000 0.000 NA 0.570 NA NA
speed x8 1.180 0.165 7.152 0.723 0 ***
speed x9 1.082 0.151 7.155 0.665 0 ***

30 Extrayendo varianzas residuales

30.0.1 Varianza residual (de los errores): con inspect

Estos valores representan las desviaciones de los ítems observados de sus valores esperados basados en las cargas factoriales y la media latente del factor.

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

#lambda #cargas factoriales
theta  #varianzas residuales (de los errores de las var. observadas)
#psi    #covarianzas entre los factores

El otuput.

##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566

31 Extrayendo matriz de covarianzas observadas

31.0.1 Covarianza observada: explicación

  1. La matriz de covarianzas observadas es una matriz que muestra las covarianzas entre las variables observadas en tus datos.

  2. Esta matriz es una representación directa de la relación entre las variables tal como se presenta en tus datos reales, sin ninguna suposición adicional o modelado.

31.0.2 Covarianza observada: con cov

El código.

# Calcular la matriz de covarianzas observadas
cov_matrix_observed <- round(cov(dat),3)

# Mostrar la matriz de covarianzas observadas
print(cov_matrix_observed)

El output.

##            x1          x2         x3        x4        x5        x6          x7
## x1 1.36289774  0.40872923 0.58183232 0.5065178 0.4420843 0.4563242  0.08504799
## x2 0.40872923  1.38638981 0.45256748 0.2096198 0.2117947 0.2483697 -0.09707352
## x3 0.58183232  0.45256748 1.27911441 0.2088635 0.1126706 0.2449227  0.08863631
## x4 0.50651778  0.20961978 0.20886351 1.3551667 1.1014120 0.8985008  0.22047507
## x5 0.44208426  0.21179471 0.11267061 1.1014120 1.6653184 1.0179058  0.14347621
## x6 0.45632416  0.24836972 0.24492268 0.8985008 1.0179058 1.2003462  0.14455865
## x7 0.08504799 -0.09707352 0.08863631 0.2204751 0.1434762 0.1445587  1.18708326
## x8 0.26471714  0.11002492 0.21303038 0.1260120 0.1812072 0.1659824  0.53702937
## x9 0.45986634  0.24482282 0.37509875 0.2441739 0.2962255 0.2367836  0.37454154
##           x8        x9
## x1 0.2647171 0.4598663
## x2 0.1100249 0.2448228
## x3 0.2130304 0.3750987
## x4 0.1260120 0.2441739
## x5 0.1812072 0.2962255
## x6 0.1659824 0.2367836
## x7 0.5370294 0.3745415
## x8 1.0253894 0.4588409
## x9 0.4588409 1.0183872

31.0.3 Covarianza observada: con lavTech

El código.

obs <- lavTech(CFA, "sampstat")[[1]]$cov
obs

El output.

##             [,1]        [,2]       [,3]      [,4]      [,5]      [,6]
##  [1,] 1.35836985  0.40737133 0.57989932 0.5048350 0.4406155 0.4548081
##  [2,] 0.40737133  1.38178387 0.45106394 0.2089234 0.2110911 0.2475446
##  [3,] 0.57989932  0.45106394 1.27486486 0.2081696 0.1122963 0.2441090
##  [4,] 0.50483500  0.20892337 0.20816961 1.3506645 1.0977528 0.8955157
##  [5,] 0.44061554  0.21109108 0.11229629 1.0977528 1.6597858 1.0145240
##  [6,] 0.45480813  0.24754457 0.24410898 0.8955157 1.0145240 1.1963584
##  [7,] 0.08476543 -0.09675102 0.08834184 0.2197426 0.1429995 0.1440784
##  [8,] 0.26383768  0.10965939 0.21232264 0.1255933 0.1806052 0.1654310
##  [9,] 0.45833855  0.24400945 0.37385257 0.2433627 0.2952413 0.2359969
##              [,7]      [,8]      [,9]
##  [1,]  0.08476543 0.2638377 0.4583385
##  [2,] -0.09675102 0.1096594 0.2440095
##  [3,]  0.08834184 0.2123226 0.3738526
##  [4,]  0.21974259 0.1255933 0.2433627
##  [5,]  0.14299955 0.1806052 0.2952413
##  [6,]  0.14407839 0.1654310 0.2359969
##  [7,]  1.18313946 0.5352452 0.3732972
##  [8,]  0.53524522 1.0219828 0.4573166
##  [9,]  0.37329722 0.4573166 1.0150039

32 Extrayendo matriz de covarianzas implicada

32.0.1 Implicada: definición

  1. La matriz de covarianzas implicada en un modelo de análisis factorial confirmatorio (CFA) es la matriz de covarianzas predicha por el modelo ajustado.

  2. Esta matriz muestra las covarianzas entre las variables observadas que el modelo supone que existirían, basado en las relaciones especificadas entre las variables latentes y observadas.

  3. Interpretación de la Matriz de Covarianzas Implicada.

  • La matriz de covarianzas implicada refleja cómo el modelo ajustado espera que las variables observadas se relacionen entre sí.

  • Es una representación matemática de las suposiciones del modelo.

  1. Comparar esta matriz con la matriz de covarianzas observada (las covarianzas reales de los datos) permite evaluar la calidad del ajuste del modelo.

32.0.2 Implicada: con producto de matrices

1. Recordar teoría

Recordemos que

\[\widehat{\Sigma} \;=\; \Lambda \;\Psi\; \Lambda^{\top} \;+\; \Theta\]

Donde:

  • \(\widehat{\Sigma}\) representa la matriz de covarianzas estimada de las variables observadas (la llamada matriz de covarianzas implicada).

  • \(\Lambda\) es la matriz de cargas factoriales.

  • \(\Psi\) es la matriz de varianzas-covarianzas de los factores latentes.

  • \(\Theta\) es la matriz de varianzas residuales.

1. Cálculo en R

Sigma.hat <- lambda %*%  psi %*% t(lambda) + theta
round(Sigma.hat, 3)

32.0.3 Implicada: con fitted (primera forma)

El código.

# Obtener la matriz de covarianzas implicadas
fitted_values <- fitted(CFA)

# Extraer la matriz de covarianzas implicadas
implied_cov_matrix <- fitted_values$cov

# Mostrar la matriz de covarianzas implicadas
print(implied_cov_matrix)

Explicación del código.

  1. Se usa la función fitted(CFA) para obtener las matrices implicadas del modelo ajustado.

  2. Se extrae la matriz de covarianzas implicada con ...$cov.

El output.

##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

32.0.4 Implicada: con fitted (segunda forma)

implied_cov_matrix <- round(unclass(fitted(CFA)$cov),3)
implied_cov_matrix
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358 0.448 0.590 0.408 0.454 0.378 0.262 0.309 0.284
## x2 0.448 1.382 0.327 0.226 0.252 0.209 0.145 0.171 0.157
## x3 0.590 0.327 1.275 0.298 0.331 0.276 0.191 0.226 0.207
## x4 0.408 0.226 0.298 1.351 1.090 0.907 0.173 0.205 0.188
## x5 0.454 0.252 0.331 1.090 1.660 1.010 0.193 0.228 0.209
## x6 0.378 0.209 0.276 0.907 1.010 1.196 0.161 0.190 0.174
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183 0.453 0.415
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022 0.490
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

32.0.5 Implicada: con lavInspect

implied_cov_matrix <- lavInspect(CFA, "sigma")
implied_cov_matrix
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

33 Extrayendo matriz de covarianzas residuales

La matriz de covarianzas residuales muestra las diferencias entre las covarianzas observadas en los datos y las covarianzas implicadas por el modelo ajustado.

El código.

cov_table <- residuals(CFA, type = "cor")$cov  #Extraer matriz de covarianzas residuales
cov_table

Explicación.

  1. El código usa la función residuals del paquete lavaan para calcular las covarianzas residuales del modelo ajustado (CFA).

  2. La opción type = "cor" indica que se desea obtener las residuales basadas en correlaciones (covarianzas estandarizadas).

  3. La opción ...$cov extrae la matriz de covarianzas de estas residuales.

El output.

##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.030  0.000                                                 
## x3 -0.008  0.094  0.000                                          
## x4  0.071 -0.012 -0.068  0.000                                   
## x5 -0.009 -0.027 -0.151  0.005  0.000                            
## x6  0.060  0.030 -0.026 -0.009  0.003  0.000                     
## x7 -0.140 -0.189 -0.084  0.037 -0.036 -0.014  0.000              
## x8 -0.039 -0.052 -0.012 -0.067 -0.036 -0.022  0.075  0.000       
## x9  0.149  0.073  0.147  0.048  0.067  0.056 -0.038 -0.032  0.000

34 Extrayendo covarianzas entre factores

34.0.1 Covarianza entre los factores (con inspect)

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

#lambda #cargas factoriales
#theta  #varianzas residuales
psi    #covarianzas entre los factores

El otuput.

##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

34.0.2 Covarianza entre los factores (otra forma)

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  filter(op == "~~",
         lhs %in% c("visual", "textual", "speed"),
         !is.na(pvalue)) %>%
  mutate(stars = ifelse(pvalue < .001, "***",
                        ifelse(pvalue < .01, "**",
                               ifelse(pvalue < .05, "*", "")))) %>%
  select('Factor 1'=lhs,
         'Factor 2'=rhs,
         'Correlación'=est,
         'Sig.'=stars) %>%
  
  kable(digits = 3,  align="c", format="pandoc", caption="Covarianzas entre los factores")

El output.

Table 34.1: Covarianzas entre los factores
Factor 1 Factor 2 Correlación Sig.
visual visual 0.809 ***
textual textual 0.979 ***
speed speed 0.384 ***
visual textual 0.408 ***
visual speed 0.262 ***
textual speed 0.173 ***

35 Extrayendo medidas de ajuste

35.0.1 Medidas de ajuste: todas

El código.

m <- inspect(CFA, 'fit.measures'); m #1. Todas las medidas
m <- fitMeasures(CFA); m             #2. Igual que el anterior

El output.

##                  npar                  fmin                 chisq 
##                21.000                 0.142                85.306 
##                    df                pvalue        baseline.chisq 
##                24.000                 0.000               918.852 
##           baseline.df       baseline.pvalue                   cfi 
##                36.000                 0.000                 0.931 
##                   tli                  nnfi                   rfi 
##                 0.896                 0.896                 0.861 
##                   nfi                  pnfi                   ifi 
##                 0.907                 0.605                 0.931 
##                   rni                  logl     unrestricted.logl 
##                 0.931             -3737.745             -3695.092 
##                   aic                   bic                ntotal 
##              7517.490              7595.339               301.000 
##                  bic2                 rmsea        rmsea.ci.lower 
##              7528.739                 0.092                 0.071 
##        rmsea.ci.upper        rmsea.ci.level          rmsea.pvalue 
##                 0.114                 0.900                 0.001 
##        rmsea.close.h0 rmsea.notclose.pvalue     rmsea.notclose.h0 
##                 0.050                 0.840                 0.080 
##                   rmr            rmr_nomean                  srmr 
##                 0.082                 0.082                 0.065 
##          srmr_bentler   srmr_bentler_nomean                  crmr 
##                 0.065                 0.065                 0.073 
##           crmr_nomean            srmr_mplus     srmr_mplus_nomean 
##                 0.073                 0.065                 0.065 
##                 cn_05                 cn_01                   gfi 
##               129.490               152.654                 0.943 
##                  agfi                  pgfi                   mfi 
##                 0.894                 0.503                 0.903 
##                  ecvi 
##                 0.423

35.0.2 Medidas de ajuste: desde una lista

El código.

lista <- c("chisq", "df", "cfi", "rmsea", "srmr", "mfi", "bic", "nfi")
lista

ms<-fitMeasures(CFA)[lista]; ms      #3. Lista específica de medidas
ms<-fitMeasures(CFA, lista); ms      #4. Igual que el anterior
ms<-round(ms,3); ms

El output.

## [1] "chisq" "df"    "cfi"   "rmsea" "srmr"  "mfi"   "bic"   "nfi"
##    chisq       df      cfi    rmsea     srmr      mfi      bic      nfi 
##   85.306   24.000    0.931    0.092    0.065    0.903 7595.339    0.907

36 Extrayendo las medias

36.0.1 medias: explicación

  1. En general, los modelos de ecuaciones estructurales se utilizan para modelar la matriz de covarianza de las variables observadas en un conjunto de datos.

  2. No obstante, en algunas aplicaciones, es útil incluir también las medias de las variables observadas.

  3. Para lograr esto, se pueden especificar explícitamente los interceptos en la sintaxis de lavaan.

  4. Esto se realiza incluyendo “fórmulas de intercepto” en la sintaxis del modelo. Una fórmula de intercepto tiene el siguiente formato:

\[\text{variable ~ 1}\]

  1. En esta expresión, la parte izquierda contiene el nombre de la variable observada o latente, y la parte derecha contiene el número 1, que representa el intercepto.

36.0.2 medias: ejemplo

Por ejemplo, en el modelo de análisis factorial confirmatorio (CFA) de tres factores de Holzinger y Swineford, podemos añadir los interceptos de las variables observadas de la siguiente manera:

El modelo.

# Ejemplo de sintaxis en lavaan con interceptos
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9

x1 ~ 1
x2 ~ 1
x3 ~ 1
x4 ~ 1
x5 ~ 1
x6 ~ 1
x7 ~ 1
x8 ~ 1
x9 ~ 1

36.0.3 Extrayendo con meanstructure

36.0.4 meanstructure: explicación

A veces, es más conveniente omitir las fórmulas de intercepto en la sintaxis del modelo (a menos que desee sus valores), y añadir el argumento meanstructure = TRUE en las llamadas a las funciones cfa y sem.

36.0.5 meanstructure: ejemplo

El código.

fit <- cfa(modelo, data=dat, meanstructure=TRUE)
summary(fit)

El output.

## lavaan 0.6.17 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        30
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                0.554    0.100    5.554    0.000
##     x3                0.729    0.109    6.685    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.113    0.065   17.014    0.000
##     x6                0.926    0.055   16.703    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.180    0.165    7.152    0.000
##     x9                1.082    0.151    7.155    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual           0.408    0.074    5.552    0.000
##     speed             0.262    0.056    4.660    0.000
##   textual ~~                                          
##     speed             0.173    0.049    3.518    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                4.936    0.067   73.473    0.000
##    .x2                6.088    0.068   89.855    0.000
##    .x3                2.250    0.065   34.579    0.000
##    .x4                3.061    0.067   45.694    0.000
##    .x5                4.341    0.074   58.452    0.000
##    .x6                2.186    0.063   34.667    0.000
##    .x7                4.186    0.063   66.766    0.000
##    .x8                5.527    0.058   94.854    0.000
##    .x9                5.374    0.058   92.546    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.549    0.114    4.833    0.000
##    .x2                1.134    0.102   11.146    0.000
##    .x3                0.844    0.091    9.317    0.000
##    .x4                0.371    0.048    7.779    0.000
##    .x5                0.446    0.058    7.642    0.000
##    .x6                0.356    0.043    8.277    0.000
##    .x7                0.799    0.081    9.823    0.000
##    .x8                0.488    0.074    6.573    0.000
##    .x9                0.566    0.071    8.003    0.000
##     visual            0.809    0.145    5.564    0.000
##     textual           0.979    0.112    8.737    0.000
##     speed             0.384    0.086    4.451    0.000

36.0.6 meanstructure: Interpretación

  1. Como puede observar en el resultado, el modelo incluye parámetros de intercepción tanto para las variables observadas como para las latentes.

  2. Por defecto, las funciones cfa y sem fijan los interceptos de las variables latentes (que en este caso corresponden a las medias latentes) a cero.

  3. De otro modo, el modelo no sería estimable.

  4. Cabe destacar que el estadístico chi-cuadrado y el número de grados de libertad son los mismos que en el modelo original (sin estructura de medias).

  5. Esto se debe a que, aunque hemos añadido nuevos datos (un valor medio para cada una de las 9 variables observadas), también hemos introducido 9 parámetros adicionales al modelo (un intercepto para cada una de las 9 variables observadas).

  6. El resultado final es un ajuste idéntico.

  7. En la práctica, la única razón para que un usuario añada fórmulas de intercepción en la sintaxis del modelo es para especificar ciertas restricciones necesarias en el modelo.

  8. Por ejemplo, revise la situación que se indica a continuación.

36.0.7 meanstructure: fijando interceptos

Por ejemplo, supongamos que deseamos x los interceptos de las variables x1, x2, x3 y x4 a, digamos, 0,5. Escribiríamos la sintaxis del modelo como sigue:

El modelo.

# Modelo de tres factores

modelo.fix <- '
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9

# Interceptos con valores fijos
x1 + x2 + x3 + x4 ~ 0.5*1
'

Observación.

Arriba hemos utilizado el lado izquierdo de la fórmula para «repetir» el lado derecho para cada elemento del lado izquierdo.

Ejecutando CFA.

## lavaan 0.6.17 ended normally after 113 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        26
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                              1120.542
##   Degrees of freedom                                28
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                1.224    0.020   59.759    0.000
##     x3                0.405    0.013   30.933    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.065    0.020   53.504    0.000
##     x6                0.890    0.017   51.989    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.183    0.061   19.433    0.000
##     x9                1.050    0.058   18.154    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual          11.800    1.007   11.720    0.000
##     speed             5.152    0.500   10.296    0.000
##   textual ~~                                          
##     speed             2.995    0.298   10.040    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.500                           
##    .x2                0.500                           
##    .x3                0.500                           
##    .x4                0.500                           
##    .x5                1.625    0.050   32.530    0.000
##    .x6               -0.083    0.043   -1.932    0.053
##    .x7                3.083    0.061   50.440    0.000
##    .x8                4.222    0.056   75.567    0.000
##    .x9                4.216    0.056   75.038    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.442    0.105    4.214    0.000
##    .x2                1.757    0.208    8.439    0.000
##    .x3                0.964    0.083   11.677    0.000
##    .x4                0.355    0.045    7.915    0.000
##    .x5                0.463    0.055    8.479    0.000
##    .x6                0.361    0.041    8.891    0.000
##    .x7                0.791    0.076   10.380    0.000
##    .x8                0.473    0.061    7.730    0.000
##    .x9                0.582    0.062    9.389    0.000
##     visual           20.593    1.717   11.993    0.000
##     textual           7.554    0.645   11.713    0.000
##     speed             1.610    0.189    8.510    0.000

37 Extrayendo otros elementos

37.0.1 Otros: vcov

La función vcov retorna la matriz de covarianzas estimada de los parámetros estimados.

El código.

vcov(CFA)

El output.

##                  vsl=~2 vsl=~3 txt=~5 txt=~6 spd=~8 spd=~9 x1~~x1 x2~~x2 x3~~x3
## visual=~x2        0.010                                                        
## visual=~x3        0.004  0.012                                                 
## textual=~x5       0.000  0.000  0.004                                          
## textual=~x6       0.000  0.000  0.002  0.003                                   
## speed=~x8         0.000  0.000  0.000  0.000  0.027                            
## speed=~x9         0.000  0.000  0.000  0.000  0.014  0.023                     
## x1~~x1            0.005  0.008  0.000  0.000  0.000  0.000  0.013              
## x2~~x2           -0.002 -0.001  0.000  0.000  0.000  0.000 -0.001  0.010       
## x3~~x3           -0.001 -0.004  0.000  0.000  0.000  0.000 -0.003  0.000  0.008
## x4~~x4            0.000  0.000  0.001  0.001  0.000  0.000  0.000  0.000  0.000
## x5~~x5            0.000  0.000 -0.001  0.000  0.000  0.000  0.000  0.000  0.000
## x6~~x6            0.000  0.000  0.000 -0.001  0.000  0.000  0.000  0.000  0.000
## x7~~x7            0.000  0.000  0.000  0.000  0.005  0.004  0.000  0.000  0.000
## x8~~x8            0.000  0.000  0.000  0.000 -0.006  0.001  0.000  0.000  0.000
## x9~~x9            0.000  0.000  0.000  0.000  0.001 -0.004  0.000  0.000  0.000
## visual~~visual   -0.007 -0.010  0.000  0.000  0.000  0.000 -0.011  0.001  0.003
## textual~~textual  0.000  0.000 -0.004 -0.003  0.000  0.000  0.000  0.000  0.000
## speed~~speed      0.000  0.000  0.000  0.000 -0.011 -0.009  0.000  0.000  0.000
## visual~~textual  -0.001 -0.002 -0.001 -0.001  0.000  0.000 -0.001  0.000  0.001
## visual~~speed    -0.001 -0.001  0.000  0.000 -0.004 -0.003 -0.001  0.000  0.000
## textual~~speed    0.000  0.000  0.000  0.000 -0.003 -0.002  0.000  0.000  0.000
##                  x4~~x4 x5~~x5 x6~~x6 x7~~x7 x8~~x8 x9~~x9 vsl~~v txtl~~t
## visual=~x2                                                               
## visual=~x3                                                               
## textual=~x5                                                              
## textual=~x6                                                              
## speed=~x8                                                                
## speed=~x9                                                                
## x1~~x1                                                                   
## x2~~x2                                                                   
## x3~~x3                                                                   
## x4~~x4            0.002                                                  
## x5~~x5           -0.001  0.003                                           
## x6~~x6            0.000  0.000  0.002                                    
## x7~~x7            0.000  0.000  0.000  0.007                             
## x8~~x8            0.000  0.000  0.000 -0.001  0.006                      
## x9~~x9            0.000  0.000  0.000  0.000 -0.002  0.005               
## visual~~visual    0.000  0.000  0.000  0.000  0.000  0.000  0.021        
## textual~~textual -0.001  0.001  0.000  0.000  0.000  0.000  0.001   0.013
## speed~~speed      0.000  0.000  0.000 -0.002  0.001  0.000  0.000   0.000
## visual~~textual   0.000  0.000  0.000  0.000  0.000  0.000  0.005   0.004
## visual~~speed     0.000  0.000  0.000 -0.001  0.001  0.000  0.003   0.000
## textual~~speed    0.000  0.000  0.000 -0.001  0.000  0.000  0.001   0.002
##                  spd~~s vsl~~t vsl~~s txtl~~s
## visual=~x2                                   
## visual=~x3                                   
## textual=~x5                                  
## textual=~x6                                  
## speed=~x8                                    
## speed=~x9                                    
## x1~~x1                                       
## x2~~x2                                       
## x3~~x3                                       
## x4~~x4                                       
## x5~~x5                                       
## x6~~x6                                       
## x7~~x7                                       
## x8~~x8                                       
## x9~~x9                                       
## visual~~visual                               
## textual~~textual                             
## speed~~speed      0.007                      
## visual~~textual   0.000  0.005               
## visual~~speed     0.003  0.001  0.003        
## textual~~speed    0.002  0.001  0.001   0.002

37.0.2 Otros: AIC y BIC

El código.

cbind(AIC(CFA), BIC(CFA))

El output.

##         [,1]     [,2]
## [1,] 7517.49 7595.339

37.0.3 Otros: parameterEstimates

El código.

parameterEstimates(CFA)

El output.

##        lhs op     rhs   est    se      z pvalue ci.lower ci.upper
## 1   visual =~      x1 1.000 0.000     NA     NA    1.000    1.000
## 2   visual =~      x2 0.554 0.100  5.554      0    0.358    0.749
## 3   visual =~      x3 0.729 0.109  6.685      0    0.516    0.943
## 4  textual =~      x4 1.000 0.000     NA     NA    1.000    1.000
## 5  textual =~      x5 1.113 0.065 17.014      0    0.985    1.241
## 6  textual =~      x6 0.926 0.055 16.703      0    0.817    1.035
## 7    speed =~      x7 1.000 0.000     NA     NA    1.000    1.000
## 8    speed =~      x8 1.180 0.165  7.152      0    0.857    1.503
## 9    speed =~      x9 1.082 0.151  7.155      0    0.785    1.378
## 10      x1 ~~      x1 0.549 0.114  4.833      0    0.326    0.772
## 11      x2 ~~      x2 1.134 0.102 11.146      0    0.934    1.333
## 12      x3 ~~      x3 0.844 0.091  9.317      0    0.667    1.022
## 13      x4 ~~      x4 0.371 0.048  7.779      0    0.278    0.465
## 14      x5 ~~      x5 0.446 0.058  7.642      0    0.332    0.561
## 15      x6 ~~      x6 0.356 0.043  8.277      0    0.272    0.441
## 16      x7 ~~      x7 0.799 0.081  9.823      0    0.640    0.959
## 17      x8 ~~      x8 0.488 0.074  6.573      0    0.342    0.633
## 18      x9 ~~      x9 0.566 0.071  8.003      0    0.427    0.705
## 19  visual ~~  visual 0.809 0.145  5.564      0    0.524    1.094
## 20 textual ~~ textual 0.979 0.112  8.737      0    0.760    1.199
## 21   speed ~~   speed 0.384 0.086  4.451      0    0.215    0.553
## 22  visual ~~ textual 0.408 0.074  5.552      0    0.264    0.552
## 23  visual ~~   speed 0.262 0.056  4.660      0    0.152    0.373
## 24 textual ~~   speed 0.173 0.049  3.518      0    0.077    0.270

37.0.4 Otros: standardizedSolution

La función standardizedSolution es similar a la función parameterEstimates pero sólo muestra las estimaciones de parámetros estandarizadas y no estandarizadas.

El código.

standardizedSolution(CFA)

El output.

##        lhs op     rhs est.std    se      z pvalue ci.lower ci.upper
## 1   visual =~      x1   0.772 0.055 14.041      0    0.664    0.880
## 2   visual =~      x2   0.424 0.060  7.105      0    0.307    0.540
## 3   visual =~      x3   0.581 0.055 10.539      0    0.473    0.689
## 4  textual =~      x4   0.852 0.023 37.776      0    0.807    0.896
## 5  textual =~      x5   0.855 0.022 38.273      0    0.811    0.899
## 6  textual =~      x6   0.838 0.023 35.881      0    0.792    0.884
## 7    speed =~      x7   0.570 0.053 10.714      0    0.465    0.674
## 8    speed =~      x8   0.723 0.051 14.309      0    0.624    0.822
## 9    speed =~      x9   0.665 0.051 13.015      0    0.565    0.765
## 10      x1 ~~      x1   0.404 0.085  4.763      0    0.238    0.571
## 11      x2 ~~      x2   0.821 0.051 16.246      0    0.722    0.920
## 12      x3 ~~      x3   0.662 0.064 10.334      0    0.537    0.788
## 13      x4 ~~      x4   0.275 0.038  7.157      0    0.200    0.350
## 14      x5 ~~      x5   0.269 0.038  7.037      0    0.194    0.344
## 15      x6 ~~      x6   0.298 0.039  7.606      0    0.221    0.374
## 16      x7 ~~      x7   0.676 0.061 11.160      0    0.557    0.794
## 17      x8 ~~      x8   0.477 0.073  6.531      0    0.334    0.620
## 18      x9 ~~      x9   0.558 0.068  8.208      0    0.425    0.691
## 19  visual ~~  visual   1.000 0.000     NA     NA    1.000    1.000
## 20 textual ~~ textual   1.000 0.000     NA     NA    1.000    1.000
## 21   speed ~~   speed   1.000 0.000     NA     NA    1.000    1.000
## 22  visual ~~ textual   0.459 0.064  7.189      0    0.334    0.584
## 23  visual ~~   speed   0.471 0.073  6.461      0    0.328    0.613
## 24 textual ~~   speed   0.283 0.069  4.117      0    0.148    0.418

37.0.5 Otros: fitted.values

Las funciones fitted y fitted.values devuelven la matriz de covarianza implícita en el modelo (ajustado) y el vector de medias de un modelo ajustado:

El código.

fitted.values(CFA)

El output.

## $cov
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

37.0.6 Otros: resid

  1. Las funciones resid o residuals devuelven los residuos (no estandarizados) de un modelo ajustado.

  2. Este es simplemente la diferencia entre la matriz de covarianza y el vector de media observados e implícitos.

  3. Si el estimador es de máxima verosimilitud, también es posible obtener los residuos normalizados y estandarizados (nota: es posible que observe varios valores de NA, pero no son los mismos):

El código.

resid(CFA, type="standardized")

El output.

## $type
## [1] "standardized"
## 
## $cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -1.996  0.000                                                 
## x3 -0.997  2.689  0.000                                          
## x4  2.679 -0.284 -1.899  0.000                                   
## x5 -0.359 -0.591 -4.157  1.545  0.000                            
## x6  2.155  0.681 -0.711 -2.588  0.942  0.000                     
## x7 -3.773 -3.654 -1.858  0.865 -0.842 -0.326  0.000              
## x8 -1.380 -1.119 -0.300 -2.021 -1.099 -0.641  4.823  0.000       
## x9  4.077  1.606  3.518  1.225  1.701  1.423 -2.325 -4.132  0.000

38 Funciones especiales

38.0.1 Funciones de extracción para inspeccionar modelos ajustados

En la Figura 38.1 se muestra una lista de funciones para inspeccionar modelos ajustados.

**Funciones de extracción para inspeccionar modelos ajustados**

Figure 38.1: Funciones de extracción para inspeccionar modelos ajustados

38.0.2 Otras funciones especiales

En la Figura 38.2 se muestra una lista de funciones para inspeccionar modelos ajustados.

**Otras funciones especiales**

Figure 38.2: Otras funciones especiales

39 Tópicos suplementarios

No hacer click aquí: Pendiente

40 Ejercicios

40.0.1 Ejercicio 1

Considere el siguiente conjunto de datos que contiene 100 observaciones y 2 variables:

  • El número de horas que se suelen dedicar a las matemáticas (MathHomework)

  • La puntuación en un test estandarizado de rendimiento de matemática (MathAchievement).

# Crear el dataframe en R
MathHmwk.data <- data.frame(
  MathHomework = c(2, 0, 4, 0, 2, 0, 1, 0, 3, 0, 4, 7, 3, 1, 1, 0, 3, 0, 1, 3, 3, 0, 2, 0, 1, 4, 1, 4, 3, 1, 1, 3, 3, 5, 2, 5, 1, 3, 2, 2, 0, 2, 5, 0, 2, 2, 1, 2, 1, 4, 0, 0, 4, 10, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 3, 2, 0, 0, 3, 2, 5, 5, 1, 0, 0, 2, 2, 3, 0, 2, 4, 0, 3, 1, 2, 3, 4, 4, 4, 2, 1, 6, 3, 5, 6, 4, 3, 2, 2, 1),
  MathAchievement = c(54, 53, 53, 56, 59, 30, 49, 54, 37, 49, 55, 50, 45, 44, 60, 36, 53, 22, 56, 54, 75, 37, 42, 64, 61, 57, 53, 63, 75, 53, 54, 64, 54, 59, 48, 65, 57, 48, 54, 62, 53, 61, 56, 32, 50, 44, 62, 39, 61, 51, 36, 38, 38, 59, 46, 55, 48, 54, 41, 61, 52, 63, 25, 64, 72, 65, 41, 29, 39, 70, 68, 38, 59, 29, 49, 39, 45, 74, 41, 53, 71, 41, 63, 34, 61, 51, 62, 55, 64, 47, 48, 47, 44, 52, 50, 48, 58, 39, 41, 51)
)
# Ver el dataframe
head(MathHmwk.data)
##   MathHomework MathAchievement
## 1            2              54
## 2            0              53
## 3            4              53
## 4            0              56
## 5            2              59
## 6            0              30

La pregunta de interés es: ¿El tiempo dedicado a los deberes de matemáticas está directamente relacionado con el rendimiento en matemáticas?

  1. Dibuje un diagrama de dispersión entre ambas variables.

  2. Realice una regresión típica estandarizado y no estandarizado, utilizando la función lm. Sugerencia: Para la no estandarizada aplique la función scale a ambos conjuntos de datos y haga la regresión.

  3. Dibuje un path model estandarizado y no estandarizado de la regresión.

  4. Realice el análisis como un path model en lavaan utilizando la función sem. Obtenga tanto los coeficientes estandarizados como los no estandarizados. Sugerencia: Para no estandarizado use el argumento meanstructure = TRUE.

  5. ¿Cómo se relacionan los resultados de los incisos (b) y (d)?

40.0.2 Ejercicio 2

Page y Keith (1981) utilizaron encuestados de los datos de 1980 High School and Beyond para investigar la siguiente pregunta: ¿Cuál es la relación entre el tipo de escuela y el rendimiento académico? Los datos aparecen en la Figura 40.1 en forma de matriz de correlaciones. En la Figura 40.2 se muestra un path model para los análisis.

El código R para la matriz es:

library(lavaan)
privSchool.cor <- c(1, 0.178, 0.23, 0.106, 0.195, 1, 0.327, 0.245, 0.356, 1, 0.183, 0.721, 1, 0.178, 1)
privSchool.cor <- lav_matrix_upper2full(privSchool.cor)
#privSchool.cor <- lav_matrix_lower2full(privSchool.cor)
dimnames(privSchool.cor) <- list(c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"), c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"))
privSchool.cor
##          Race   SES CogAbil SchTyp AcadAch
## Race    1.000 0.178   0.230  0.106   0.195
## SES     0.178 1.000   0.327  0.245   0.356
## CogAbil 0.230 0.327   1.000  0.183   0.721
## SchTyp  0.106 0.245   0.183  1.000   0.178
## AcadAch 0.195 0.356   0.721  0.178   1.000
**Correlaciones (n = 18,058)**

Figure 40.1: Correlaciones (n = 18,058)

El path model es:

**Path model**

Figure 40.2: Path model

  1. Crear el modelo de trayectorias utilizando lavaan. Asegúrese de etiquetar los mismos parámetros que en la Figura 40.2.

  2. Realizar el análisis de path model correspondiente. Interprete todos los resultados posibles.

  3. ¿Cuál es la relación entre el tipo de escuela y el rendimiento académico (es decir, camino j)?

40.0.3 Ejercicio 3

MacKinnon (2008, p. 113) proporciona un conjunto de datos de un estudio hipotético sobre las expectativas de los profesores respecto al rendimiento de los alumnos. y el rendimiento de los alumnos. Su modelo de trayectoria se muestra en la Figura Figura 40.3 y las covarianzas del modelo se indican en la Figura 40.4.

El path model es:

**Path model**

Figure 40.3: Path model

El código R para la matriz de covarianzas es:

library(lavaan)
privSchool.cor <- c(1, 0.178, 0.23, 0.106, 0.195, 1, 0.327, 0.245, 0.356, 1, 0.183, 0.721, 1, 0.178, 1)
privSchool.cor <- lav_matrix_upper2full(privSchool.cor)
#privSchool.cor <- lav_matrix_lower2full(privSchool.cor)
dimnames(privSchool.cor) <- list(c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"), c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"))
privSchool.cor
##          Race   SES CogAbil SchTyp AcadAch
## Race    1.000 0.178   0.230  0.106   0.195
## SES     0.178 1.000   0.327  0.245   0.356
## CogAbil 0.230 0.327   1.000  0.183   0.721
## SchTyp  0.106 0.245   0.183  1.000   0.178
## AcadAch 0.195 0.356   0.721  0.178   1.000
**Covarianzas (n = 40)**

Figure 40.4: Covarianzas (n = 40)

  1. Introduzca las covarianzas en R.

  2. Escriba la sintaxis del modelo. Utilice el operador := para definir los dos efectos indirectos de las expectativas del profesor sobre el rendimiento del alumno: (a1)(b1) y (a2)(b2).

  3. ¿Cuáles son los efectos indirectos?

  4. Realice el análisis de path model correspondiente.

  5. Interprete todos los resultados posibles.

40.0.4 Ejercicio 4

Umstattd-Meyer, Janke y Beaujean (2013) midieron la salud psicosocial deficiente como un modelo de factor único utilizando tres facetas de ítems de un cuestionario de depresión y una medida de la actividad social. La matriz de covarianza se muestra en la Figura 40.5.

**Covarianzas (n = 6053)**

Figure 40.5: Covarianzas (n = 6053)

Además, considere el siguiente modelo.

Modelo 1.

marker.model <- '
PsychSocLV =~ Dep.1 + Dep.2 + Dep.3 + SocActivity
'

Realizar los siguientes incisos:

  1. Introduzca la matriz de covarianzas en R.

  2. Con la función cfa de lavaan (sin agregar el argumento std.lv=...) y utilizando variables latentes no estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa.

  3. Con la función cfa de lavaan (agregando el argumento std.lv=FALSE) y utilizando variables latentes no estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa con el argumento mencionado.

  4. Con la función cfa de lavaan y utilizando variables latentes estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa agregando el argumento std.lv=TRUE.

  5. Verifique que los valores resultantes de \(\chi^2\) y \(df\) son idénticos para todos los métodos. Investigue la razón.

  6. ¿Y el número de parámetros del model? ¿Son iguales en todos los modelos? Identifíquelos en cada uno de ellos.

40.0.5 Ejercicio 5

Continuación del ejercicio 4. Considere la situación del ejercicio 4 y los siguientes dos modelos (modelos 2 y 3).

Modelo 2.

Observe que, en este modelo, se utiliza Depression 1 como variable marcadora.

stdLV.model <- '
PsychSocLV =~ NA*Dep.1 + Dep.1 + Dep.2 + Dep.3 + SocActivity
PsychSocLV~~1*PsychSocLV
'

Modelo 3.

Observe que, en este modelo, se utiliza:

  • Como variable marcadora a Depression 1.

  • El método de la codificación de efectos (porque la suma de las cargas factoriales es igual al número de variables indicadoras únicas).

ec.model <- '
PsychSocLV =~ NA*Dep.1 + a*Dep.1 + b*Dep.2 + c*Dep.3 + d*SocActivity
a+b+c+d==4
'

Realizar los siguientes incisos:

  1. Con la función cfa de lavaan (sin agregar el argumento std.lv=...), ajuste el modelo 2. Sugerencia: use el código habitual de cfa.

  2. Con la función cfa de lavaan (sin agregar el argumento std.lv=...), ajuste el modelo 3. Sugerencia: use el código habitual de cfa.

  3. Verifique que los valores resultantes de \(\chi^2\) y \(df\) son idénticos para todos los métodos evaluados tanto en el ejercicio 4 como en el 5. Investigue la razón.

  4. ¿Y el número de parámetros del modelo? ¿Son iguales en todos los modelos? Identifíquelos en cada uno de ellos.

40.0.6 Ejercicio 6

El modelo del Ejercicio anterior formaba parte de un SEM más amplio, parte del cual se muestra en la Figura 40.6. La matriz de covarianza completa se muestra en la Figura 40.7.

**Path model**

Figure 40.6: Path model

La matriz de covarianzas es:

**Covarianzas (n = 6053)**

Figure 40.7: Covarianzas (n = 6053)

  1. Introduzca la matriz de covarianza en R.

  2. Ajuste el modelo SEM a los datos. ¿La salud psicosocial y la salud física predicen la movilidad personal? Sugerencia: aplique la función sem de lavaan.

40.0.7 Ejercicio 7

Graham (2008) mostró cómo el SEM puede utilizarse para analizar una variedad de modelos lineales generales. lineales generales. Su ejemplo de análisis descriptivo discriminante (DDA) utiliza variables latentes formativas. El DDA es un procedimiento que describe las diferencias entre múltiples grupos en múltiples descriptores continuos: una regresión múltiple entre dos o más grupos. En DDA, la variable latente de interés se denomina función discriminante. Un path model del DDA se muestra en la Figura 40.8 y los datos para el modelo se dan en la Figura 40.9.

El path model es:

**Path model del DDA**

Figure 40.8: Path model del DDA

La matriz de covarianzas es:

**Covarianzas (n = 288)**

Figure 40.9: Covarianzas (n = 288)

Realizar los siguientes incisos:

  1. Importe a R la matriz de covarianzas y el vector de medias.

  2. Escriba la sintaxis lavaan para la Figura 40.8. Sugerencia: el path a=1 se escribe como 1*DV1 + a*DV1 en la sintaxis de lavaan.

  3. Obtenga los coeficientes de función (coeficientes estandarizados para a y b), correlación canónica (coeficiente estandarizado para c), y \(R^2\) (coeficiente normalizado para d). Sugerencia: aplique la función sem de lavaan.

Bibliografía

Consultar el documento RPubs :: Análisis multivariado (bibliografía).

Referencias

Graham, J. M. (2008). The general linear model as structural equation modeling. Journal of Educational and Behavioral Statistics, 33 , 485-506. doi: 10.3102/1076998607306151.

MacKinnon, D. P. (2008). Introduction to statistical mediation analysis. Mahwah, NJ: Erlbaum.

Page, E. B., & Keith, T. Z. (1981). Effects of U.S. private schools: A technical analysis of two recent claims. Educational Researcher, 10 , 7-17. doi: 10.2307/1174256.

Umstattd-Meyer, M. R., Janke, M. C., & Beaujean, A. A. (2013). Predictors of older adults’ personal and community mobility: Using a comprehensive theoretical mobility framework. The Gerontologist, Advance online publication. doi: 10.1093/geront/gnt054.

 

 
If you found any ERRORS or have SUGGESTIONS, please report them to my email. Thanks.  
LS0tDQp0aXRsZTogIk1PREVMT1MgREUgRUNVQUNJT05FUyBFU1RSVUNUVVJBTEVTIChTRU0pIg0Kc3VidGl0bGU6IDxoMT4qKkFwbGljYWNpw7NuKio8L2gxPg0KDQphdXRob3I6IA0KICAtIG5hbWUgICAgICAgICAgOiAiRHIuIHJlci4gbmF0LiBIdW1iZXJ0byBMTGluw6FzIFNvbGFubyINCiAgICBhZmZpbGlhdGlvbiAgIDogIkRlcGFydGFtZW50byBkZSBNYXRlbcOhdGljYXMgeSBFc3RhZMOtc3RpY2EsIFVuaXZlcnNpZGFkIGRlbCBOb3J0ZSAoQmFycmFucXVpbGxhLCBDb2xvbWJpYSkiDQogICAgICNjb3JyZXNwb25kaW5nIDogeWVzICAgICMgRGVmaW5lIG9ubHkgb25lIGNvcnJlc3BvbmRpbmcgYXV0aG9yDQogICAgICNhZGRyZXNzICAgICAgIDogIkRlcGFydGFtZW50byBkZSBNYXRlbcOhdGljYXMgeSBFc3RhZMOtc3RpY2EiDQogICAgZW1haWwgICAgICAgICA6IHwNCiAgICAgIGhsbGluYXNAdW5pbm9ydGUuZWR1LmNvDQogICAgICANCiAgICAgIFtCaW9ncmFwaGljYWwgc2tldGNoXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL0Jpb19Ta2V0Y2gpDQogICAgICANCiAgICAgIGByIGZvcm1hdChTeXMudGltZSgpLCAiJWQvJW0vJXkiKWAgDQogICAgICANCiAgICAgI3JvbGU6ICAgICAgICAgIyBDb250cmlidXRvcnNoaXAgcm9sZXMgKGUuZy4sIENSZWRpVCwgaHR0cHM6Ly9jYXNyYWkub3JnL2NyZWRpdC8pDQogICMgICAgLSBDb25jZXB0dWFsaXphdGlvbg0KICAjICAgIC0gV3JpdGluZyAtIE9yaWdpbmFsIERyYWZ0IFByZXBhcmF0aW9uDQogICMgICAgLSBXcml0aW5nIC0gUmV2aWV3ICYgRWRpdGluZw0KICMgLSBuYW1lICAgICAgICAgIDogIkF1dG9yIG51bWVybyAyIg0KICMgICBhZmZpbGlhdGlvbiAgIDogIjEsMiINCiAjICAgcm9sZToNCiAjICAgICAtIFdyaXRpbmcgLSBSZXZpZXcgJiBFZGl0aW5nDQogICAgICNhZmZpbGlhdGlvbjoNCiAgIy0gaWQgICAgICAgICAgICA6ICIxIg0KICAjICBpbnN0aXR1dGlvbiAgIDogIlVuaXZlcnNpZGFkIGRlbCBOb3J0ZSAoQmFycmFucXVpbGxhLCBDb2xvbWJpYSkiDQogICMhW10oaGxsaW5hcy5qcGcpe3dpZHRoPTFpbn0gDQogIA0KI2RhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVkLyVtLyV5IilgJyAgIyB2ZXIgaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLWNvb2tib29rL3VwZGF0ZS1kYXRlLmh0bWwNCm91dHB1dDogDQogICAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOiANCiAgICAgICAgICAjT0pPIFNhbGVuIGNhcGl0dWxvcywgc2VjY2lvbmVzIHkgVGVvcmVtYXMNCiAgICAjYm9va2Rvd246Omh0bWxfYm9vazoNCiAgICAgICAgICAjT0pPIEVSUk9SIFNhbGVuIHRlb3JlbWFzLCBwZXJvIG5vIHNhbGVuIGxvcyBjYXBpdHVsb3MgDQogICAgI2h0bWxfZG9jdW1lbnQ6DQogICAgICAgICAgdG9jOiB0cnVlICAgICAgIyB0YWJsZSBvZiBjb250ZW50IHRydWUNCiAgICAgICAgICB0b2NfZGVwdGg6IDQgICAjIHVwdG8gdGhyZWUgZGVwdGhzIG9mIGhlYWRpbmdzIChzcGVjaWZpZWQgYnkgIywgIyMgYW5kICMjIykNCiAgICAgICAgICB0b2NfZmxvYXQ6IHRydWUgI0NvbiB0cnVlLCB0b2Mgc2FsZSBhbCBtYXJnZW4gaXpxdWllcmRvIGRlIGxhIHDDoWdpbmE7IGRlIGxvIGNvbnRyYXJpbywgYXJyaWJhDQogICAgICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgICAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQogICAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlICAgIyBpZiB5b3Ugd2FudCBudW1iZXIgc2VjdGlvbnMgYXQgZWFjaCB0YWJsZSBoZWFkZXINCiAgICAgICAgICAjdGhlbWU6IHNhbmRzdG9uZQ0KICAgICAgICAgICN0aGVtZTogdW5pdGVkICAjIG1hbnkgb3B0aW9ucyBmb3IgdGhlbWUsIHRoaXMgb25lIGlzIG15IGZhdm9yaXRlLg0KICAgICAgICAgICN0aGVtZTogZmxhdGx5ICAjIA0KICAgICAgICAgICN0aGVtZTogY2VydWxlYW4gICMgDQogICAgICAgICAgI2hpZ2hsaWdodDogdGFuZ28gICMgc3BlY2lmaWVzIHRoZSBzeW50YXggaGlnaGxpZ2h0aW5nIHN0eWxlDQogICAgICAgICAgI2NzczogU2NyaXB0cyBhY2Nlc29yaW9zL2VzdGlsb2JvdG9uLmNzcw0KICAgICAgICAgICNjc3M6IG15LmNzcyAgICMgeW91IGNhbiBhZGQgeW91ciBjdXN0b20gY3NzLCBzaG91bGQgYmUgaW4gc2FtZSBmb2xkZXINCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgICAgICAgI2hpZ2hsaWdodDogdGFuZ28gICMgY2FtYmlhciBjb2xvciBkZSBsaWJyYXJ5IGVuIGF6dWwNCiAgICAjIGJvb2tkb3duOjpnaXRib29rOg0KICAgICMgICAgICBpbmNsdWRlczoNCiAgICAjICAgICAgICBpbl9oZWFkZXI6IGhlYWRlci5odG1sDQogICAgIyBib29rZG93bjo6cGRmX2Jvb2s6DQogICAgIyAgICAgICBrZWVwX3RleDogeWVzDQogICAgIyBib29rZG93bjo6aHRtbF9ib29rOg0KICAgICMgICAgICAgY3NzOiB0b2MuY3NzDQogICAgIyBib29rZG93bjo6aHRtbF9ib29rOg0KICAgICMgICAgICAgICBpbmNsdWRlczoNCiAgICAjICAgICAgICAgICBpbl9oZWFkZXI6IHN0eWxlLmNzcw0KICAgICNib29rZG93bjo6aHRtbF9kb2N1bWVudDI6IGRlZmF1bHQNCiAgICAjIGJvb2tkb3duOjpwZGZfZG9jdW1lbnQyOg0KICAgICMgICAgICBrZWVwX3RleDogdHJ1ZQ0KICAgICNiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliDQogICAgbWF0aGpheDogImh0dHA6Ly9leGFtcGxlLmNvbS9tYXRoamF4L01hdGhKYXguanM/Y29uZmlnPVRlWC1BTVMtTU1MX0hUTUxvck1NTCINCmhlYWRlci1pbmNsdWRlczoNCiAgICBcdXNlcGFja2FnZVt4MTFuYW1lc117eGNvbG9yfSANCiAgICANCmNzbDogc2NpZW5jZS5jc2wNCiNPam86IFNlIHV0aWxpemEgbGVuZ3VhamUgWUFNTA0KDQphYnN0cmFjdDogfA0KICoqRW4gW1JwdWJzOjogdG9jXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL3RvYykgc2UgcHVlZGVuIHZlciBvdHJvcyBkb2N1bWVudG9zIGRlIHBvc2libGUgaW50ZXLDqXMuKioNCiAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0iY2VudGVyIiwgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UjLA0KICAgICAgICAgICAgICAgICAgICAgICNzdHlsZSA9ICJjb2xvcjpkYXJrYmx1ZSINCiAgICAgICAgICAgICAgICAgICAgIyBjbGFzcy5zb3VyY2U9ImJnLWRhbmdlciIsIGNsYXNzLm91dHB1dD0iYmctd2FybmluZyIgICAjQ29sb3JlcyBkZW50cm8gZGVsIGNodW5rDQogICAgICAgICAgICAgICAgICAgICApDQpsaWJyYXJ5KHJnbCkNCmtuaXRyOjprbml0X2hvb2tzJHNldCh3ZWJnbCA9IGhvb2tfd2ViZ2wpDQpgYGANCg0KDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ybWFya2Rvd24vbGFuZ3VhZ2UtZW5naW5lcy5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL21hcmtkb3duLXN5bnRheC5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL2Etc2luZ2xlLWRvY3VtZW50Lmh0bWwNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vbWFya2Rvd24tZXh0ZW5zaW9ucy1ieS1ib29rZG93bi5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9ib29rZG93bi1tYXJrZG93bi5odG1sICAjIFRlb3JlbXMgYW5kIHByb29mcw0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9tYXJrZG93bi1leHRlbnNpb25zLWJ5LWJvb2tkb3duLmh0bWwjdGhlb3JlbXMNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vaHRtbC5odG1sDQoNCmh0dHBzOi8vd3d3LmRhdGEtdG8tdml6LmNvbS8NCiAgDQpbUnB1YnNdKGxpbmspDQogIA0KKFwjZXE6ZWMtKSwgIEVjdWFjaW9uIFxAcmVmKGVxOmVjLSksIEZpZ3VyYSBcQHJlZihmaWc6RmlnLSksIFRhYmxlIFxAcmVmKHRhYjptdGNhcnMpLCBUaGVvcmVtIFxAcmVmKHRobTpib3JpbmcpDQoNCg0KIyBUaXR1bG8geyNUaXR1bG9TZWNjaW9ufSAgIFxAcmVmKFRpdHVsb1NlY2Npb24pDQogIA0KIyBGb3IgSFRNTCwgd2UgY2FuIHNldCBjb2xvciB3aXRoIENTUywgZS5nLiwgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij50ZXh0PC9zcGFuPg0KICANCiMgaHR0cHM6Ly9yYWRpYW50LXJzdGF0cy5naXRodWIuaW8vZG9jcy9tb2RlbC9sb2dpc3RpYy5odG1sIFNoaW5ueSBMb2dpdCAgDQogIA0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KI0xhIGZvdG8gdGFtYcOxbyBjw6lkdWxhDQoNCmh0bWx0b29sczo6aW1nKHNyYyA9IGtuaXRyOjppbWFnZV91cmkoZmlsZS5wYXRoKFIuaG9tZSgiZG9jIiksICJodG1sIiwgImxvZ28uanBnIikpLCANCiAgICAgICAgICAgICAgIGFsdCA9ICdobGxpbmFzJywgDQogICAgICAgICAgICAgICBzdHlsZSA9ICdwb3NpdGlvbjphYnNvbHV0ZTsgdG9wOjA7IHJpZ2h0OjA7IHBhZGRpbmc6MTBweDsnICMsDQogICAgICAgICAgICAgICB3aWR0aCA9ICIyMDBweCIpICAjIEFxdcOtIGVzcGVjaWZpY2FzIGVsIGFuY2hvIGRlc2VhZG8gZW4gcMOteGVsZXMgbyBwb3JjZW50YWplDQpgYGANCg0KDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIH0NCiMgTGEgZm90byBncmFuZGUNCg0KaHRtbHRvb2xzOjppbWcoc3JjID0ga25pdHI6OmltYWdlX3VyaSgiaGxsaW5hczIwMjMuanBnIiksIA0KICAgICAgICAgICAgICAgYWx0ID0gJ2hsbGluYXMyMDIzJywgDQogICAgICAgICAgICAgICBzdHlsZSA9ICdwb3NpdGlvbjphYnNvbHV0ZTsgdG9wOjA7IHJpZ2h0OjA7IHBhZGRpbmc6MXB4OycsDQogICAgICAgICAgICAgICB3aWR0aD0iMTUlIikNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KYGBge2NzcywgZWNobz1GQUxTRX0NCi5jb2x1bW5zIHtkaXNwbGF5OiBmbGV4O30NCmgxIHtjb2xvcjogZGFya2JsdWU7fQ0KaDMge2NvbG9yOiBkYXJrZ3JlZW47fQ0KaDQge2NvbG9yOiBncmVlbjt9DQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgIC0tPg0KDQojIExpYnJlcsOtYXMNCg0KIyMjIFBhcmEgU0VNDQoNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojICBodHRwczovL3JwdWJzLmNvbS9BbGVtYS8xMDAwNTgyDQoNCiMgaHR0cHM6Ly93d3cuZ2Vla3Nmb3JnZWVrcy5vcmcvY29udGV4dHVhbC1vdXRsaWVycy8NCmBgYA0KDQpFbCBzb2Z0d2FyZSBSIGRpc3BvbmUgZGUgdmFyaWFzIGZ1bmNpb25lcyBkZSBkaWZlcmVudGVzIHBhcXVldGVzIHBhcmEgY2FsY3VsYXIgRUZBOg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShzZW0pDQpsaWJyYXJ5KGxhdmFhbikNCmxpYnJhcnkoYmxhdmFhbikNCmxpYnJhcnkoc2VtUGxvdCkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgIC0tPg0KDQojIyMgUGFyYSBvdHJvcyBhbsOhbGlzaXMNCg0KYGBge3IsICBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShwc3ljaCkgICAgICAgICAjUGFyYSByZWFsaXphciB1biBFRkENCmxpYnJhcnkoYXBsb3JlMykgICAgICAgI0Jhc2UgZGUgZGF0b3MgcGFyYSBsb3MgZWplbXBsb3MNCmxpYnJhcnkobHNtKSAgICAgICAgICAgI0Jhc2UgZGUgZGF0b3MgcGFyYSBlamVtcGxvcyB5IGVzdGltYWNpb25lcyBkZWwgTG9nLXZlcm9zaW1pbGl0dWQNCmxpYnJhcnkoa25pdHIpICAgICAgICAgI0VkaXRhciB0YWJsYXMgY29uIGthYmxlKCkNCmxpYnJhcnkoa2FibGVFeHRyYSkgICAgI0VkaXRhciB0YWJsYXMgbcOhcyBlc3RpbGl6YWRhcw0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAjSW5jbHV5ZSBhIGRwbHlyIHkgZ2dwbG90Mg0KbGlicmFyeShzdHJpbmdyKSAgICAgICAjUmVlbXBsYXphciBjYXJhY3RlcmVzIGVuIHVuIGRhdGEgZnJhbWUNCmxpYnJhcnkob3V0bGllcnMpICAgICAgI291dGxpZXJzOjpncnViYnMudGVzdA0KbGlicmFyeShFbnZTdGF0cykgICAgICAjRW52U3RhdHM6OnJvc25lclRlc3QNCmxpYnJhcnkoRE13UjIpICAgICAgICAgI0xPRiAoTG9jYWwgT3V0bGllciBGYWN0b3IpDQpsaWJyYXJ5KHJnbCkgICAgICAgICAgICNyZ2w6OnBsb3QzZGANCmxpYnJhcnkoY29ycnBsb3QpICAgICAgI01hdHJpeiBkZSBjb3JyZWxhY2lvbmVzDQpsaWJyYXJ5KHRleHRzaGFwZSkgICAgICNjb2x1bW5fdG9fcm93bmFtZXMNCmxpYnJhcnkob3Blbnhsc3gpICAjIExpYnJlcsOtYSBwYXJhIGVzY3JpYmlyIGFyY2hpdm9zIGRlIEV4Y2VsDQpsaWJyYXJ5KGtuaXRyKSAgICAgICNjcmVhciB0YWJsYXMgY29uIGVzdGlsbw0KbGlicmFyeShrYWJsZUV4dHJhKSAjY3JlYXIgdGFibGFzIGNvbiBlc3RpbG8sIHBlcm8gcGFyYSBodG1sDQojb3B0c19rbml0JHNldChldmFsLmFmdGVyID0gJ2ZpZy5jYXAnKQ0KYGBgDQoNCmBgYHtjc3MsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDEwMzA0NzcvY2hhbmdpbmctY2h1bmstYmFja2dyb3VuZC1jb2xvci1pbi1ybWFya2Rvd24NCg0KLmJhZENvZGUgew0KYmFja2dyb3VuZC1jb2xvcjogcmVkOw0KfQ0KYGBgDQoNCmBgYHtyLCAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRX0NCmxpYnJhcnkocHN5Y2gpICAgICAgICAgI1BhcmEgcmVhbGl6YXIgdW4gRUZBDQpsaWJyYXJ5KGFwbG9yZTMpICAgICAgICNCYXNlIGRlIGRhdG9zIHBhcmEgbG9zIGVqZW1wbG9zDQpsaWJyYXJ5KGxzbSkgICAgICAgICAgICNCYXNlIGRlIGRhdG9zIHBhcmEgZWplbXBsb3MgeSBlc3RpbWFjaW9uZXMgZGVsIExvZy12ZXJvc2ltaWxpdHVkDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICNJbmNsdXllIGEgZHBseXIgeSBnZ3Bsb3QyDQpsaWJyYXJ5KHN0cmluZ3IpICAgICAgICNSZWVtcGxhemFyIGNhcmFjdGVyZXMgZW4gdW4gZGF0YSBmcmFtZQ0KbGlicmFyeShvdXRsaWVycykgICAgICAjb3V0bGllcnM6OmdydWJicy50ZXN0DQpsaWJyYXJ5KEVudlN0YXRzKSAgICAgICNFbnZTdGF0czo6cm9zbmVyVGVzdA0KbGlicmFyeShETXdSMikgICAgICAgICAjTE9GIChMb2NhbCBPdXRsaWVyIEZhY3RvcikNCmxpYnJhcnkocmdsKSAgICAgICAgICAgI3JnbDo6cGxvdDNkDQpsaWJyYXJ5KGNvcnJwbG90KSAgICAgICNNYXRyaXogZGUgY29ycmVsYWNpb25lcw0KbGlicmFyeSh0ZXh0c2hhcGUpICAgICAjY29sdW1uX3RvX3Jvd25hbWVzDQpsaWJyYXJ5KG9wZW54bHN4KSAgIyBMaWJyZXLDrWEgcGFyYSBlc2NyaWJpciBhcmNoaXZvcyBkZSBFeGNlbA0KbGlicmFyeShrbml0cikgICAgICAjY3JlYXIgdGFibGFzIGNvbiBlc3RpbG8NCmxpYnJhcnkoa2FibGVFeHRyYSkgI2NyZWFyIHRhYmxhcyBjb24gZXN0aWxvLCBwZXJvIHBhcmEgaHRtbA0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBTaW50w6F4aXMgY29uIGBsYXZhYW5gDQoNCiMjIyBUaXBvcyBkZSBmw7NybXVsYXMNCg0KVXRpbGl6YW5kbyBjdWF0cm8gdGlwb3MgZGUgZsOzcm11bGFzLCBzZSBwdWVkZSBkZXNjcmliaXIgdW5hIGdyYW4gdmFyaWVkYWQgZGUgbW9kZWxvcyBkZSB2YXJpYWJsZXMgbGF0ZW50ZXMuIEVsIGNvbmp1bnRvIGFjdHVhbCBkZSB0aXBvcyBkZSBmw7NybXVsYXMgc2UgcmVzdW1lIGVuIGxhIGZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMSkuDQoNCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqVGlwb3MgZGUgZsOzcm11bGFzKioiLCBvdXQud2lkdGggPSAiNjAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjEucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBTaW50w6F4aXMgZGUgbG9zIG1vZGVsb3MNCg0KMS4gRW4gYGxhdmFhbmAsIGxvcyBtb2RlbG9zIFNFTSBwdWVkZW4gZXNwZWNpZmljYXJzZSBtZWRpYW50ZSBmw7NybXVsYXMgZGUgbW9kZWxvIHNpbWlsYXJlcyBhIGxhcyB1dGlsaXphZGFzIGVuIGxhcyBmdW5jaW9uZXMgYGxtYCB5IGBnbG1gLiANCg0KMi4gU2luIGVtYmFyZ28sIGhheSBhbGd1bm9zIG9wZXJhZG9yZXMgbnVldm9zIChzw61tYm9sb3MgcmVsYWNpb25hbGVzKSBxdWUgc2UgdXRpbGl6YW4gcGFyYSBkZWZpbmlyIGNvdmFyaWFuemFzIChyZXNpZHVhbGVzKSB5IHZhcmlhYmxlcyBsYXRlbnRlcy4gDQoNCjMuIExhIGZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMikgZW51bWVyYSBhbGd1bmFzIGV4cHJlc2lvbmVzIGNvbXVuZXMgZW4gbGEgc2ludGF4aXMgZGUgYGxhdmFhbmAuDQoNCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4yLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqU2ludMOheGlzIGRlIGxvcyBtb2RlbG9zKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4yLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEVqZW1wbG86IEVudW5jaWFkbw0KDQojIyMgRGVzY3JpcGNpw7NuIGRlbCBkYXRhc2V0cw0KDQoxLiBWYW1vcyBhIHV0aWxpemFyIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGxsYW1hZG8gYEhvbHppbmdlclN3aW5lZm9yZDE5MzlgIHBhcmEgbGxldmFyIGEgY2FibyB1biBTRU0gZWwgY3VhbCBwcm92aWVuZSBkZWwgcGFxdWV0ZSBgbGF2YWFuYC4gDQoNCjIuIEVsIGNvbmp1bnRvIGRlIGRhdG9zIGNsw6FzaWNvIGRlIEhvbHppbmdlciB5IFN3aW5lZm9yZCAoMTkzOSkgY29uc2lzdGUgZW4gcHVudHVhY2lvbmVzIGRlIHBydWViYXMgZGUgY2FwYWNpZGFkIG1lbnRhbCBkZSBuacOxb3MgZGUgc8OpcHRpbW8geSBvY3Rhdm8gY3Vyc28gZGUgZG9zIGdydXBvcyBkZSBjb2xlZ2lvcyBkaWZlcmVudGVzIChQYXN0ZXVyIHkgR3JhbnQtV2hpdGUpLiANCg0KMy4gRW4gZWwgY29uanVudG8gZGUgZGF0b3Mgb3JpZ2luYWwgKGRpc3BvbmlibGUgZW4gZWwgcGFxdWV0ZSBgTUJFU1NgKSwgaGF5IHB1bnR1YWNpb25lcyBwYXJhIDI2IHBydWViYXMuIA0KDQo0LiBTaW4gZW1iYXJnbywgZW4gbGEgYmlibGlvZ3JhZsOtYSBzZSB1dGlsaXphIG3DoXMgdW4gc3ViY29uanVudG8gbcOhcyBwZXF1ZcOxbyBjb24gOSB2YXJpYWJsZXMgKHBvciBlamVtcGxvLCBlbiBlbCB0cmFiYWpvIGRlIEpvcmVza29nIGRlIDE5NjksIHF1ZSB0YW1iacOpbiB1dGlsaXphIHPDs2xvIGxvcyAxNDUgc3VqZXRvcyBkZSBsYSBlc2N1ZWxhIEdyYW50LVdoaXRlKS4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRGVzY3JpcGNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgZGVsIGRhdGFzZXRzDQoNCk5vc290cm9zIHV0aWxpemFyZW1vcyB1biBkYXRhIGZyYW1lIGNvbiAzMDEgb2JzZXJ2YWNpb25lcyAoUGFzdGV1cj0xNTYsIEdyYW50LVdoaXRlPTE0NSkgIHkgMTUgdmFyaWFibGVzOg0KICANCiAgMS4gYGlkYDogSWRlbnRpZmljYWRvci4NCiAgDQogIDIuIGBzZXhgOiBHw6luZXJvLg0KICANCiAgMy4gYGFnZXlyYDogRWRhZCAocGFydGUgZW4gYcOxb3MpLg0KICANCiAgNC4gYGFnZW1vYDogRWRhZCAocGFydGUgZW4gbWVzZXMpLg0KICANCiAgNS4gYHNjaG9vbGA6IEVzY3VlbGEgKFBhc3RldXIgb3IgR3JhbnQtV2hpdGUpLg0KICANCiAgNi4gYGdyYWRlYDogR3JhZG8uDQogIA0KICA3LiBgeDFgOiBWaXN1YWwgcGVyY2VwdGlvbiAocGVyY2VwY2nDs24gdmlzdWFsKS4NCiAgDQogIDguIGB4MmA6IEN1YmVzIChjdWJvcykuDQogIA0KICA5LiBgeDNgOiBMb3plbmdlcyAocGFzdGlsbGFzKS4NCiAgDQogIDEwLiBgeDRgOiBQYXJhZ3JhcGggY29tcHJlaGVuc2lvbiAoY29tcHJlbnNpw7NuIGRlIHBhcsOhZ3JhZm9zKS4NCiAgDQogIDExLiBgeDVgOiBTZW50ZW5jZSBjb21wbGV0aW9uIChjb21wbGV0YXIgb3JhY2lvbmVzKS4NCiAgDQogIDEyLiBgeDZgOiBXb3JkIG1lYW5pbmcgKHNpZ25pZmljYWRvIGRlIHBhbGFicmFzKS4NCiAgDQogIDEzLiBgeDdgOiBTcGVlZGVkIGFkZGl0aW9uIChhZGljacOzbiBjb24gdmVsb2NpZGFkKS4NCiAgDQogIDE0LiBgeDhgOiBTcGVlZGVkIGNvdW50aW5nIG9mIGRvdHMgKGNvbnRlbyBkZSBwdW50b3MgY29uIHZlbG9jaWRhZCkuDQogIA0KICAxNS4gYHg5YDogU3BlZWRlZCBkaXNjcmltaW5hdGlvbiBzdHJhaWdodCBhbmQgY3VydmVkIGNhcGl0YWxzIChkaXNjcmltaW5hY2nDs24gYWNlbGVyYWRhIGRlIGxldHJhcyBtYXnDunNjdWxhcyByZWN0YXMgeSBjdXJ2YXMpLiBQb3IgZWplbXBsbzoNCiAgICAgIA0KICAgICAgKyBMZXRyYXMgY29uIHRyYXpvcyByZWN0b3M6IEEsIEUsIEYsIEgsIEksIEssIEwsIE0sIE4sIFQsIFYsIFcsIFgsIFksIFoNCiAgICAgIA0KICAgICAgKyBMZXRyYXMgY29uIHRyYXpvcyBjdXJ2b3M6IEIsIEMsIEQsIEcsIEosIE8sIFAsIFEsIFIsIFMsIFUNCg0KQXF1w60geDEsIHgyLCAuLi4sIHg5IGZ1ZXJvbiBjYWxjdWxhZGFzIGEgdHJhdsOpcyBkZSBmdW5jaW9uZXMgZGUgcHJ1ZWJhcyBjb2duaXRpdmFzLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBOdWVzdHJvIGRhdGEgZnJhbWUgZW4gUg0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3NDb21wbGV0byA8LSBsYXZhYW46OkhvbHppbmdlclN3aW5lZm9yZDE5MzkNCmF0dGFjaChkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNClNlIHJlc2FsdGEgcXVlIHPDs2xvIGFsZ3VuYXMgZGUgZXN0YXMgdmFyaWFibGVzIHNlIHV0aWxpemFyw6FuIHBhcmEgcmVhbGl6YXIgZWwgU0VNLiANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0IDwtIGRhdG9zQ29tcGxldG9bNzoxNV0NCmF0dGFjaChkYXQpDQpoZWFkKGRhdCw0KSANCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzc6MTVdDQphdHRhY2goZGF0KQ0KDQprYWJsZShoZWFkKGRhdCw0KSxhbGlnbiA9ICJjY2MiKSAlPiUjIFNlIG5lY2VzaXRhIGxpYnJhcnkoa25pdHIpIA0Ka2FibGVfc3R5bGluZygpICU+JSAgICAgICAgICAgICAgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi4gU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0Ka2FibGVfY2xhc3NpY18yKGZ1bGxfd2lkdGggPSBGKSAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLlNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuDQoNCiMjIyBFc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcyBiw6FzaWNvcw0KDQpQcmltZXJvLCBlcyByZWNvbWVuZGFibGUgZXhhbWluYXIgbG9zIGRhdG9zIGFudGVzIGRlIHJlYWxpemFyIGN1YWxxdWllciBhbsOhbGlzaXMuIEN1YWxxdWllciBwYXJ0aWNpcGFudGUgcXVlIHRlbmdhIGFsZ8O6biBkYXRvIGZhbHRhbnRlIHNlcsOhIGV4Y2x1aWRvIHBvciBjb21wbGV0byBkZWwgYW7DoWxpc2lzLiAgU2UgcHVlZGVuIHV0aWxpemFyIGRpdmVyc2FzIGZ1bmNpb25lcyAoY29tbyBzZSBtdWVzdHJhIGEgY29udGludWFjacOzbikuDQoNCg0KYGBge3J9DQpkZXNjcmliZShkYXQpDQpgYGANCg0KU2UgcmVzYWx0YSBxdWUsIGxhIGZ1bmNpw7NuIGBkZXNjcmliZWAgZGUgbGEgbGlicmVyw61hIGBwc3ljaGAsIGVsIG91dHB1dDoNCiAgDQogICsgYHRpbW1lZGAgc2UgcmVmaWVyZSBhIGxhIG1lZGlhbmEgdHJ1bmNhZGEsIHF1ZSBlcyB1bmEgbWVkaWRhIGRlIHRlbmRlbmNpYSBjZW50cmFsIHJvYnVzdGEgcXVlIGNhbGN1bGEgbGEgbWVkaWFuYSBkZSB1biBjb25qdW50byBkZSBkYXRvcyBkZXNwdcOpcyBkZSBlbGltaW5hciB1biBjaWVydG8gcG9yY2VudGFqZSBkZSBvYnNlcnZhY2lvbmVzIG3DoXMgZXh0cmVtYXMuIA0KICANCiAgKyBgbWFkYCBzaWduaWZpY2EgZGVzdmlhY2nDs24gYWJzb2x1dGEgbWVkaWFuYSwgcXVlIGVzIHVuYSBtZWRpZGEgZGUgZGlzcGVyc2nDs24gcXVlIGluZGljYSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIGRhdG9zIGVuIHJlbGFjacOzbiBjb24gbGEgbWVkaWFuYS4NCiAgDQogICsgYHNrZXdgIHNlIHJlZmllcmUgYSBsYSBhc2ltZXRyw61hIGRlIGxvcyBkYXRvcywgcXVlIGluZGljYSBzaSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcyBlcyBzaW3DqXRyaWNhIG8gc2kgZXN0w6Egc2VzZ2FkYSBoYWNpYSB1biBsYWRvLiBVbiB2YWxvciBwb3NpdGl2byBpbmRpY2Egc2VzZ28gaGFjaWEgbGEgZGVyZWNoYSwgbWllbnRyYXMgcXVlIHVuIHZhbG9yIG5lZ2F0aXZvIGluZGljYSBzZXNnbyBoYWNpYSBsYSBpenF1aWVyZGEuDQogIA0KICArIGBrdXJ0b3Npc2Agc2UgcmVmaWVyZSBhIGxhIGN1cnRvc2lzIGRlIGxvcyBkYXRvcywgcXVlIGluZGljYSBsYSBmb3JtYSBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcyBlbiByZWxhY2nDs24gY29uIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbC4gVW4gdmFsb3IgZGUga3VydG9zaXMgbWF5b3IgcXVlIGNlcm8gaW5kaWNhIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgcHVudGlhZ3VkYSAobcOhcyBwaWNvcykgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLCBtaWVudHJhcyBxdWUgdW4gdmFsb3IgbWVub3IgcXVlIGNlcm8gaW5kaWNhIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgYWNoYXRhZGEgKG1lbm9zIHBpY29zKSBxdWUgbGEgZGlzdHJpYnVjacOzbiBub3JtYWwuDQogIA0KICArIGBzZWAgc2UgcmVmaWVyZSBhbCBlcnJvciBlc3TDoW5kYXIsIHF1ZSBlcyB1bmEgbWVkaWRhIGRlIGxhIHByZWNpc2nDs24gZGUgbGEgZXN0aW1hY2nDs24gZGUgdW5hIGVzdGFkw61zdGljYSBkZSBsYSBtdWVzdHJhLiBJbmRpY2EgbGEgdmFyaWFiaWxpZGFkIGVzcGVyYWRhIGVuIGxhIGVzdGltYWNpw7NuIGRlIGxhIGVzdGFkw61zdGljYSBzaSBzZSBtdWVzdHJlYSByZXBldGlkYW1lbnRlIGRlIGxhIG1pc21hIHBvYmxhY2nDs24uIFVuIGVycm9yIGVzdMOhbmRhciBtw6FzIHBlcXVlw7FvIGluZGljYSB1bmEgZXN0aW1hY2nDs24gbcOhcyBwcmVjaXNhIGRlIGxhIGVzdGFkw61zdGljYSBkZSBpbnRlcsOpcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQpgYGB7cn0NCnN1bW1hcnkoZGF0KQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQpPdHJhIHRhYmxhIGRlIGZyZWN1ZW5jaWFzOiANCg0KYGBge3J9DQojIEdlbmVyYSBsYSB0YWJsYXMgdXNhbmRvIGRwbHlyIGFuZCB0aWR5ciB5IGthYmxlDQpkYXQgJT4lIA0KICBzZWxlY3QoeDE6eDkpICU+JSANCiAgZ2F0aGVyKCJWYXJpYWJsZSIsICJ2YWx1ZSIpICU+JSANCiAgZ3JvdXBfYnkoVmFyaWFibGUpICU+JSANCiAgc3VtbWFyaXNlKE1lYW49bWVhbih2YWx1ZSwgbmEucm09VFJVRSksIA0KICAgICAgICAgICAgU0Q9c2QodmFsdWUsIG5hLnJtPVRSVUUpLCANCiAgICAgICAgICAgIG1pbj1taW4odmFsdWUsIG5hLnJtPVRSVUUpLCANCiAgICAgICAgICAgIG1heD1tYXgodmFsdWUsIG5hLnJtPVRSVUUpLCANCiAgICAgICAgICAgICclIFBlcmRpZG9zJz0xMDAqbGVuZ3RoKHdoaWNoKGlzLm5hKHZhbHVlKSkpL24oKSkgJT4lIA0KICBrYWJsZShkaWdpdHM9MiwgZm9ybWF0PSJwYW5kb2MiLCBjYXB0aW9uPSJUYWJsYSAxOiBFc3RhZGlzdGljb3MgZGVzY3JpcHRpdm9zIHBhcmEgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIikNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgRGF0b3MgZmFsdGFudGVzDQoNCkxhIG1heW9yw61hIGRlIGxvcyBlbGVtZW50b3Mgc29sbyBjYXJlY2VuIGRlIGRhdG9zIGVxdWl2YWxlbnRlcyBhIDIwIG8gMzAgcGFydGljaXBhbnRlcywgbG8gY3VhbCBubyByZXByZXNlbnRhIHVuIGdyYW4gcHJvYmxlbWEgZW4gdW4gY29uanVudG8gZGUgZGF0b3MgY29uIDI4MDAgb2JzZXJ2YWNpb25lcy4gU2luIGVtYmFyZ28sIGVzIHBvc2libGUgcXVlIGFsZ3Vub3MgZGUgZXN0b3MgdmFsb3JlcyBmYWx0YW50ZXMgbm8gc2Ugc3VwZXJwb25nYW4sIGxvIHF1ZSBzaWduaWZpY2EgcXVlIHBvZHLDrWFuIGZhbHRhciAyMCBvIDMwIGluZGl2aWR1b3MgZGlmZXJlbnRlcyBlbiBjYWRhIHVuYSBkZSBsYXMgdmFyaWFibGVzLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgRGF0b3MgcGVyZGlkb3MgcG9yIGNvbHVtbmENCg0KYGBge3J9DQptaXNzaW5ncyA8LSBjb2xTdW1zKGlzLm5hKGRhdCkpIA0KbWlzc2luZ3MNCg0Kc3VtbWFyeShtaXNzaW5ncykgDQpgYGANCg0KQWx0ZXJuYXRpdmFtZW50ZSwgcG9kZW1vcyBtaXJhciBhbGd1bmFzIHZhcmlhYmxlcyBjb24gYWxndW5hIGNvbmRpY2nDs24gcGFyYSBlbCBuw7ptZXJvIGRlIGRhdG9zIHBlcmRpZG9zLiANCg0KYGBge3J9DQpteWRhdGEgPC0gZGF0WyAsIG1pc3NpbmdzPDE1XQ0KbmFtZXMobXlkYXRhKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIEZ1bmNpw7NuIGBjb21wbGV0ZS5jYXNlc2ANCg0KDQpObyBvYnN0YW50ZSwgcG9kZW1vcyBkZXRlcm1pbmFyIGVsIG7Dum1lcm8gZGUgImNhc29zIGNvbXBsZXRvcyIgZGVudHJvIGRlIGxvcyBkYXRvcywgcXVlIHNvbiBpbmRpdmlkdW9zIHF1ZSBubyB0aWVuZW4gZGF0b3MgZmFsdGFudGVzIGVuIGFic29sdXRvIGVuIGVsIGN1ZXN0aW9uYXJpby4NCg0KDQpgYGB7cn0NCmZhbHRhbnRlIDwtIGNvbXBsZXRlLmNhc2VzKGRhdCk7dGFpbChmYWx0YW50ZSkNCg0Kc3VtKGZhbHRhbnRlKQ0KDQpgYGANCg0KTGEgZnVuY2nDs24gYGNvbXBsZXRlLmNhc2VzYCBwcm9kdWNlIHVuIHZlY3RvciBkZSB2YWxvcmVzIGJvb2xlYW5vcywgZG9uZGUgYFRSVUVgIGluZGljYSB1biBjYXNvIGNvbXBsZXRvIHkgYEZBTFNFYCBpbmRpY2EgdW4gY2FzbyBjb24gdmFsb3JlcyBmYWx0YW50ZXMuIExhIHN1bWEgZGUgZXN0ZSB2ZWN0b3Igbm9zIGRhIGVsIHRvdGFsIGRlIGNhc29zIGNvbXBsZXRvcywgcXVlIGVuIGVzdGUgY2FzbyBlcyBgciBzdW0oZmFsdGFudGUpYC4gRWwgcG9yY2VudGFqZSBkZSBkYXRvcyBhdXNlbnRlcyBlcyBgciAoMSAtIChzdW0oZmFsdGFudGUpL25yb3coZGF0KSkpKjEwMGAlOiANCg0KDQpgYGB7cn0NCigxIC0gKHN1bShmYWx0YW50ZSkvbnJvdyhkYXQpKSkqMTAwDQoNCmBgYA0KDQoNCkF1bnF1ZSBubyBleGlzdGUgdW4gdmFsb3IgZXhhY3RvIHF1ZSBkZXRlcm1pbmUgcXXDqSBjYW50aWRhZCBkZSBkYXRvcyBmYWx0YW50ZXMgZXMgYWNlcHRhYmxlLCBsYSBpbXBvcnRhbmNpYSBkZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIGVuIGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgZXMgaW5uZWdhYmxlLiBTZWfDum4gYWxndW5vcyBleHBlcnRvcywgc2UgcmVjb21pZW5kYSBjb250YXIgY29uIGFsIG1lbm9zIDEwIG9ic2VydmFjaW9uZXMgcG9yIGNhZGEgdmFyaWFibGUgZW4gZGljaG8gYW7DoWxpc2lzLCBsbyBxdWUgc3VnaWVyZSBxdWUgbnVlc3RybyB0YW1hw7FvIGRlIG11ZXN0cmEgZXMgYXByb3BpYWRvIHBhcmEgbnVlc3Ryb3Mgb2JqZXRpdm9zLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEVzcGVjaWZpY2FjacOzbiBkZWwgbW9kZWxvDQoNCiMjIyBFbCBtb2RlbG8gdGXDs3JpY28NCg0KVW4gbW9kZWxvIENGQSBxdWUgc2Ugc3VlbGUgcHJvcHVlc3RvIHBhcmEgZXN0YXMgOSB2YXJpYWJsZXMgY29uc3RhIGRlIHRyZXMgdmFyaWFibGVzIGxhdGVudGVzIChvIGZhY3RvcmVzKSwgY2FkYSB1bmEgY29uIHRyZXMgaW5kaWNhZG9yZXM6DQoNCjEuIFVuIGZhY3RvciAqdmlzdWFsKiAoYHZpc3VhbGApIG1lZGlkbyBwb3IgMyB2YXJpYWJsZXM6IHgxLCB4MiB5IHgzLg0KDQoyLiBVbiBmYWN0b3IgKnRleHR1YWwqIChgdGV4dHVhbGApIG1lZGlkbyBwb3IgMyB2YXJpYWJsZXM6IHg0LCB4NSB5IHg2Lg0KDQozLiBVbiBmYWN0b3IgZGUgKnZlbG9jaWRhZCogKGBzcGVlZGApIG1lZGlkbyBwb3IgMyB2YXJpYWJsZXM6IHg3LCB4OCB5IHg5Lg0KIA0KTGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4zKSBjb250aWVuZSB1bmEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGRlbCBtb2RlbG8gZGUgdHJlcyBmYWN0b3Jlcy4NCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMywgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKk1vZGVsbyBDRkEgcGFyYSBsb3MgZGF0b3MgYEhvbHppbmdlclN3aW5lZm9yZDE5MzlgKioiLCBvdXQud2lkdGggPSAiNjAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjMucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFbCBtb2RlbG8gZW4gUg0KDQpVbmEgc2ludGF4aXMgZGUgbW9kZWxvIGxhdmFhbiBjb21wbGV0YSBlcyBzaW1wbGVtZW50ZSB1bmEgY29tYmluYWNpw7NuIGRlIGVzdG9zIHRpcG9zIGRlIGbDs3JtdWxhcywgZW5jZXJyYWRhcyBlbnRyZSBjb21pbGxhcyBzaW1wbGVzLg0KDQoNCmBgYHtyfQ0KbW9kZWxvIDwtICcgDQp2aXN1YWwgPX4geDEgKyB4MiArIHgzDQp0ZXh0dWFsID1+IHg0ICsgeDUgKyB4Ng0Kc3BlZWQgPX4geDcgKyB4OCArIHg5IA0KJw0KYGBgDQoNCkVuIGVzdGUgZWplbXBsbywgbGEgc2ludGF4aXMgZGVsIG1vZGVsbyBzw7NsbyBjb250aWVuZSB0cmVzICpkZWZpbmljaW9uZXMgZGUgdmFyaWFibGVzIGxhdGVudGVzKi4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBUaXBvcyBkZSBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvDQoNCiMjIyBFeHBsaWNhY2nDs24NCg0KMS4gRW4gZWwgY29udGV4dG8gZGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbyAoQ0ZBKSBjb24gZWwgcGFxdWV0ZSBgbGF2YWFuYCBlbiBSLCBlbCBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zIGVuIGVsIG91dHB1dCBkZWwgbW9kZWxvIGRlcGVuZGUgZGUgbGFzIGVzcGVjaWZpY2FjaW9uZXMgZGVsIG1vZGVsbyB5IGxvcyBkYXRvcyB1dGlsaXphZG9zLiANCg0KMi4gRWwgbW9kZWxvIHF1ZSBzZSBoYSBpbmRpY2FkbyBwYXJhIGxvcyBkYXRvcyBgSG9semluZ2VyU3dpbmVmb3JkMTkzOWAgZXNwZWNpZmljYSB0cmVzIGZhY3RvcmVzIGxhdGVudGVzIChgVmlzdWFsYCwgIGBUZXh0dWFsYCwgIGBTcGVlZGApIGNhZGEgdW5vIGNvbiB0cmVzIGluZGljYWRvcmVzLiANCg0KMy4gRW4gZXN0ZSBzZW50aWRvLCBpZGVudGlmaWNhbW9zIGRvcyB0aXBvcyBkZSBwYXLDoW1ldHJvczogDQogIA0KICArIFBhcsOhbWV0cm9zIGRlIG1lZGlkYXMuDQogIA0KICArIFBhcsOhbWV0cm9zIGVzdHJ1Y3R1cmFsZXMuIA0KICANCjQuIEVuIGxhcyBzaWd1aWVudGVzIHNlY2Npb25lcyBleHBsaWNhcmVtb3MgY2FkYSB1bm8gZGUgZXN0b3MgdGlwb3MuIA0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0Ke1xjb2xvcntUZWFsfSBcbGFtYmRhXzIsIFw7ICAgXGxhbWJkYV8zLCBcOyAgIFxsYW1iZGFfNCwgXDsgICBcbGFtYmRhXzUsIFw7ICAgXGxhbWJkYV82LCBcOyAgIFxsYW1iZGFfN31cXA0KXFwNCntcY29sb3J7VGVhbH0gXHRhdV8xLCBcOyAgIFx0YXVfMiwgXDsgICBcdGF1XzMsIFw7ICAgXHRhdV80LCBcOyAgIFx0YXVfNSwgXDsgICBcdGF1XzYsIFw7ICAgXHRhdV83LCBcOyAgIFx0YXVfOCwgXDsgICBcdGF1Xzl9XFwNClxcDQp7XGNvbG9ye1RlYWx9IFx2YXJlcHNpbG9uXzEsIFw7ICAgXHZhcmVwc2lsb25fMiwgXDsgICBcdmFyZXBzaWxvbl8zLCBcOyAgIFx2YXJlcHNpbG9uXzQsIFw7ICAgXHZhcmVwc2lsb25fNSwgXDsgICBcdmFyZXBzaWxvbl82LCBcOyAgIFx2YXJlcHNpbG9uXzcsIFw7ICAgXHZhcmVwc2lsb25fOCwgXDsgICBcdmFyZXBzaWxvbl85fVxcDQpcXA0Ke1xjb2xvcntUZWFsfSBcYWxwaGFfMSwgXDsgICBcYWxwaGFfMiwgXDsgICBcYWxwaGFfM31cXA0KXFwNCntcY29sb3J7VGVhbH0gXHBzaV97MTF9LCBcOyAgIFxwc2lfezIyfSwgXDsgICBccHNpX3szM319XFwNClxcDQp7XGNvbG9ye1RlYWx9IFxwc2lfezEyfSwgXDsgICBccHNpX3sxM30sIFw7ICAgXHBzaV97MjN9fQ0KDQpodHRwczovL3JwdWJzLmNvbS9Kb18vbGF2YWFuX2VmZWN0b3NfZGlyZWN0b3MNCmh0dHBzOi8vc3RhdHMub2FyYy51Y2xhLmVkdS9yL3NlbWluYXJzL3JzZW0vDQpodHRwczovL21zcGVla2VuYnJpbmsuZ2l0aHViLmlvL3NkYW0tci1jb21wYW5pb24vc3RydWN0dXJhbC1lcXVhdGlvbi1tb2RlbGxpbmctd2l0aC1sYXZhYW4uaHRtbA0KDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBQYXLDoW1ldHJvcyBkZSBtZWRpZGFzDQoNCkVuIHVuIG1vZGVsbyBDRkEgdMOtcGljbywgbG9zICpwYXLDoW1ldHJvcyBkZSBtZWRpZGFzKiBxdWUgc2UgcXVpZXJlbiBlc3RpbWFyIGluY2x1eWVuICh2w6lhc2UgbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW40KSk6DQoNCioqMS4gQ2FyZ2FzIEZhY3RvcmlhbGVzLioqIA0KDQpMYXMgcmVsYWNpb25lcyBlbnRyZSBsb3MgZmFjdG9yZXMgbGF0ZW50ZXMgeSBzdXMgaW5kaWNhZG9yZXMuDQoNCiQkXGxhbWJkYV8xLCBccXVhZCAgXGxhbWJkYV8yLCBccXVhZCAgXGxhbWJkYV8zLCBccXVhZCAgXGxhbWJkYV80LCBccXVhZCAgXGxhbWJkYV81LCBccXVhZCAgXGxhbWJkYV82LCBccXVhZCAgXGxhbWJkYV83LCBccXVhZCAgXGxhbWJkYV84LCBccXVhZCAgXGxhbWJkYV85JCQNCg0KKioyLiBJbnRlcmNlcHRvcyBkZSBsb3MgRmFjdG9yZXMgTGF0ZW50ZXMuKiogDQoNCiQkXHRhdV8xLCBccXVhZCAgXHRhdV8yLCBccXVhZCAgXHRhdV8zLCBccXVhZCAgXHRhdV80LCBccXVhZCAgXHRhdV81LCBccXVhZCAgXHRhdV82LCBccXVhZCAgXHRhdV83LCBccXVhZCAgXHRhdV84LCBccXVhZCAgXHRhdV85JCQNCioqMy4gVmFyaWFuemFzIGRlIGxvcyBFcnJvcmVzIGRlIE1lZGljacOzbi4qKg0KDQpWYXJpYW56YXMgZGUgbG9zIHTDqXJtaW5vcyBkZSBlcnJvciBhc29jaWFkb3MgYSBjYWRhIGluZGljYWRvci4gDQoNCiQkVihcdmFyZXBzaWxvbl8xKSwgXHF1YWQgVihcdmFyZXBzaWxvbl8yKSwgXHF1YWQgVihcdmFyZXBzaWxvbl8zKSwgXHF1YWQgVihcdmFyZXBzaWxvbl80KSwgXHF1YWQgVihcdmFyZXBzaWxvbl81KSwgXHF1YWQgVihcdmFyZXBzaWxvbl82KSwgXHF1YWQgVihcdmFyZXBzaWxvbl83KSwgXHF1YWQgVihcdmFyZXBzaWxvbl84KSwgXHF1YWQgVihcdmFyZXBzaWxvbl85KSQkDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFBhcsOhbWV0cm9zIGVzdHJ1Y3R1cmFsZXMNCg0KRW4gdW4gbW9kZWxvIENGQSB0w61waWNvLCBsb3MgKnBhcsOhbWV0cm9zIGVzdHJ1Y3R1cmFsZXMqIHF1ZSBzZSBxdWllcmVuIGVzdGltYXIgaW5jbHV5ZW4gKHbDqWFzZSBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjQpKToNCg0KKio0LiBMYSBtZWRpYSBkZSBsb3MgZmFjdG9yZXMuKioNCg0KJCRcYWxwaGFfMSwgXHF1YWQgIFxhbHBoYV8yLCBccXVhZCAgXGFscGhhXzMkJA0KDQoqKjUuIFZhcmlhbnphcyBkZSBsb3MgRmFjdG9yZXMgTGF0ZW50ZXMuKioNCg0KVmFyaWFuemFzIGRlIGNhZGEgZmFjdG9yLg0KDQokJFxwc2lfezExfSwgXHF1YWQgIFxwc2lfezIyfSwgXHF1YWQgIFxwc2lfezMzfSQkDQoNCioqNi4gQ292YXJpYW56YXMgZGUgbG9zIEZhY3RvcmVzIExhdGVudGVzLioqDQoNCkNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcy4NCg0KJCRccHNpX3sxMn0sIFxxdWFkICBccHNpX3sxM30sIFxxdWFkICBccHNpX3syM30kJA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFJlc3VtZW4gZ3LDoWZpY28gZGUgbG9zIHRpcG9zIGRlIHBhcsOhbWV0cm9zDQoNCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjQsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipUaXBvcyBkZSBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvIENGQSoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuNC5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFc3RpbWFjacOzbiBkZWwgbW9kZWxvIGNvbiBgbGF2YWFuOjpjZmFgDQoNCiMjIyBPdXRwdXQgZGUgYGNmYWA6IGVqZWN1Y2nDs24NCg0KUG9kZW1vcyBhanVzdGFyIGVsIG1vZGVsbyBjb21vIHNpZ3VlOiANCg0KYGBge3J9DQpDRkEgPC0gbGF2YWFuOjpjZmEobW9kZWxvLCBkYXRhPWRhdCkNCkNGQQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgT3V0cHV0IGRlIGBjZmFgOiBncsOhZmljbyBkZWwgbW9kZWxvIGNvbiBSDQoNCioqMS4gRWwgZGlhZ3JhbWEgYsOhc2ljby4qKg0KDQpgYGB7cn0NCnNlbVBhdGhzKENGQSwgDQogICAgICAgICB3aGF0ID0gInBhdGgiLCAgICAjTXVlc3RyYSBsYXMgcnV0YXMgY29uIGNhcmdhcywgcmVncmVzaW9uZXMsIGNvdmFyaWFuemFzICAgICANCiAgICAgICAgICN3aGF0ID0gInN0ZCIsICAgICNNdWVzdHJhIGxhcyBlc3RpbWFjaW9uZXMgZXN0YW5kYXJpemFkYXMgZGUgbGFzIHJ1dGFzIA0KICAgICAgICAgI3doYXQgPSAiY29sIiwgICAgI011ZXN0cmEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBkZSB2YXIuIG9ic2VydmFkYXMNCiAgICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAgI3doYXQgPSAibW9kZWwiLCAgI011ZXN0cmEgdW5hIHJlcHJlc2VudGFjacOzbiBncmFsIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImFsbCIsICAgICNNdWVzdHJhIHRvZG9zIGVsZW1lbnRvcyBwb3NpYmxlcyAocnV0YXMgeSBlc3RpbWFjaW9uZXMpDQogICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImVxIiwgICAgICNNdWVzdHJhIGxhcyBlY3VhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgZGVsIG1vZGVsbyANCiAgICAgICAgIA0KICAgICAgICAgbGF5b3V0ID0gImNpcmNsZSIsICAgI0Rpc3BvbmUgbm9kb3MgZW4gY8OtcmN1bG8gKHNvbG8gcGVybWl0aWRvIHNpIHJvdGF0aW9uPSAxIG8gMykNCiAgICAgICAgIA0KICAgICAgICAgdGl0bGUgPSBGQUxTRSwgICAgICAgI05vIG11ZXN0cmEgZWwgdMOtdHVsbyBkZWwgZ3LDoWZpY28NCiAgICAgICAgIA0KICAgICAgICAgZWRnZS5jb2xvciA9ICJyZWQiLCAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBsb3MgYm9yZGVzIChhcmlzdGFzKSBlbiBuZWdybw0KICAgICAgICAgZWRnZS5sYWJlbC5jZXggPSAxICAgI1RhbWHDsW8gZGUgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcw0KICAgICAgICAgKQ0KYGBgDQoNCiAqKjIuIFNlIHB1ZWRlIHZpc3VhbGl6YXIgZWwgbW9kZWxvICBjb24gbm9kb3MgcGVyc29uYWxpemFkb3MuKioNCg0KYGBge3J9DQpzZW1QYXRocyhDRkEsIA0KICAgICAgICB3aGF0ID0gInBhdGgiLCAgICAjTXVlc3RyYSBsYXMgcnV0YXMgY29uIGNhcmdhcywgcmVncmVzaW9uZXMsIGNvdmFyaWFuemFzICAgICANCiAgICAgICAgI3doYXQgPSAic3RkIiwgICAgI011ZXN0cmEgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcyBkZSBsYXMgcnV0YXMgDQogICAgICAgICN3aGF0ID0gImNvbCIsICAgICNNdWVzdHJhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZGUgdmFyLiBvYnNlcnZhZGFzDQogICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAjd2hhdCA9ICJtb2RlbCIsICAjTXVlc3RyYSB1bmEgcmVwcmVzZW50YWNpw7NuIGdyYWwgZGVsIG1vZGVsbw0KICAgICAgICAjd2hhdCA9ICJhbGwiLCAgICAjTXVlc3RyYSB0b2RvcyBlbGVtZW50b3MgcG9zaWJsZXMgKHJ1dGFzIHkgZXN0aW1hY2lvbmVzKQ0KICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgI3doYXQgPSAiZXEiLCAgICAgI011ZXN0cmEgbGFzIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyBkZWwgbW9kZWxvDQogICAgICAgIA0KICAgICAgICBzdHlsZSA9ICJsaXNyZWwiLCAjVXNhIHVuIGVzdGlsbyBwcmVkZWZpbmlkbyBzaW1pbGFyIGFsIGVzdGlsbyBMSVNSRUwNCiAgICAgICAgICNzdHlsZSA9ICJyYW0iOiAgICNFc3RpbG8gZGUgUkFNIChSZXRpY3VsYXIgQWN0aW9uIE1vZGVsKSwgY29tw7puIGVuIGdyw6FmaWNvcyBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJteCI6ICAgICNFc3RpbG8gZGUgTXgsICBoZXJyYW1pZW50YSBkZSBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJlcXMiOiAgICNFc3RpbG8gc2ltaWxhciBhbCBzb2Z0d2FyZSBFUVMNCg0KICAgICAgICAgI2xheW91dCA9ICJ0cmVlIiwgICAjRGlzcG9uZSBub2RvcyBlbiB1bmEgZXN0cnVjdHVyYSBqZXLDoXJxdWljYSBzaW1pbGFyIGEgdW4gw6FyYm9sDQogICAgICAgICAjbGF5b3V0PSJ0cmVlMiIsICAgICNQYXJlY2lkYSBhIGxhIGFudGVyaW9yDQogICAgICAgICBsYXlvdXQ9ImNpcmNsZSIsICAgICNEaXNwb25lIG5vZG9zIGVuIGPDrXJjdWxvIChzb2xvIHBlcm1pdGlkbyBzaSByb3RhdGlvbj0gMSBvIDMpDQogICAgICAgICAjbGF5b3V0ID0gInNwcmluZyIsICNNaW5pbWl6YSBmdWVyemFzIGRlIHJlcHVsc2nDs24geSBhdHJhY2Npw7NuIGVudHJlIG5vZG9zDQogICAgICAgICAjbGF5b3V0ID0gImxnbCIsICAgICNBbGdvcml0bW8gIkxhcmdlIEdyYXBoIExheW91dCIgKMO6dGlsIHBhcmEgZ3LDoWZpY29zIGdyYW5kZXMpDQogICAgICAgICAjbGF5b3V0ID0gImthbWFkYSIsICAgICAgI0FsZ29yaXQuIEthbWFkYS1LYXdhaSBwYXJhIGRpc3Bvc2ljacOzbiBiYXNhZGEgZW4gZW5lcmfDrWENCiAgICAgICAgICNsYXlvdXQgPSAiZnJ1Y2h0ZXJtYW4iLCAjQWxnb3JpdG1vIEZydWNodGVybWFuLVJlaW5nb2xkIChkaXNwb3NpY2nDs24gcG9yIGZ1ZXJ6YXMpDQogICAgICAgIA0KICAgICAgICB0aXRsZSA9IEZBTFNFLCAgICAgICAgICAgICAjTm8gbXVlc3RyYSBlbCB0w610dWxvIGRlbCBncsOhZmljbw0KICAgICAgICANCiAgICAgICAgZWRnZS5jb2xvciA9ICJibGFjayIsICAgICAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBsb3MgYm9yZGVzIChhcmlzdGFzKSBlbiBuZWdybw0KICAgICAgICBlZGdlLmxhYmVsLmNleCA9IDEsICAgICAgICAjVGFtYcOxbyBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzDQogICAgICAgIA0KICAgICAgICAjbm9kZS5jb2xvciA9ICJibHVlIiwgICAgICAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBmb25kbyBkZSBsb3Mgbm9kb3MNCiAgICAgICAgbm9kZS5sYWJlbC5jZXggPSAxLjUsICAgICAgI1RhbWHDsW8gZGVsIHRleHRvIGRlIGxhcyBldGlxdWV0YXMgZGVudHJvIGRlIGxvcyBub2Rvcy4NCiAgICAgICAgI25vZGUuc2hhcGUgPSAicmVjdGFuZ2xlIiwgI0VzdGFibGVjZSBsYSBmb3JtYSBkZSBsb3Mgbm9kb3MgY29tbyByZWN0w6FuZ3Vsb3MNCiAgICAgICAgDQogICAgICAgIGN1cnZlUGl2b3Q9VFJVRSwgICAgICAgICAgICNDb25leGlvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcw0KICAgICAgICBsYWJlbC5wcm9wID0gMSwNCiAgICAgICAgDQogICAgICAgIGNvbG9yID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgIGxhdCA9ICJvcmFuZ2UiLCAgICAjQ29sb3IgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgICAgICAgICAgICAgbWFuID0gImxpZ2h0Z3JlZW4iICNDb2xvciBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMNCiAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgKQ0KYGBgDQoNCg0KKiozLiBTZSBwdWVkZSB2aXN1YWxpemFyIGVsIG1vZGVsbyAgY29uIG90cmFzIG9wY2lvbmVzIHBlcnNvbmFsaXphZGFzLioqDQoNCg0KDQoNCmBgYHtyLCAgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCnNlbVBhdGhzKENGQSwNCiAgICAgICAgICN3aGF0ID0gInBhdGgiLCAgICNNdWVzdHJhIGxhcyBydXRhcyBjb24gY2FyZ2FzLCByZWdyZXNpb25lcywgY292YXJpYW56YXMgICAgIA0KICAgICAgICAgI3doYXQgPSAic3RkIiwgICAgI011ZXN0cmEgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcyBkZSBsYXMgcnV0YXMgDQogICAgICAgICAjd2hhdCA9ICJjb2wiLCAgICAjTXVlc3RyYSBtYXRyaXogZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzIGRlIHZhci4gb2JzZXJ2YWRhcw0KICAgICAgICAgI3doYXQgPSAibW9kIiwgICAgI011ZXN0cmEgY2FtaW5vIGFkaWNpb25hbCBxdWUgcG9kcsOtYSBtZWpvcmFyIGFqdXN0ZSBkZWwgbW9kZWxvDQogICAgICAgICAjd2hhdCA9ICJtb2RlbCIsICAjTXVlc3RyYSB1bmEgcmVwcmVzZW50YWNpw7NuIGdyYWwgZGVsIG1vZGVsbw0KICAgICAgICAgI3doYXQgPSAiYWxsIiwgICAgI011ZXN0cmEgdG9kb3MgZWxlbWVudG9zIHBvc2libGVzIChydXRhcyB5IGVzdGltYWNpb25lcykNCiAgICAgICAgICN3aGF0ID0gInBhciIsICAgICNNdWVzdHJhIHRvZG9zIGxvcyBwYXLDoW1ldHJvcyBlc3RpbWFkb3MgZGVsIG1vZGVsbw0KICAgICAgICAgd2hhdCA9ICJlcSIsICAgICAgI011ZXN0cmEgbGFzIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyBkZWwgbW9kZWxvIA0KICAgICAgICAgDQogICAgICAgICB3aGF0TGFiZWxzID0iZXN0IiwgICAjTXVlc3RyYSBlc3RpbWFjaW9uZXMgbm8gZXN0YW5kYXJpemFkYXMgZGUgbG9zIHBhcsOhbWV0cm9zDQogICAgICAgICAjd2hhdExhYmVscyA9InN0ZCI6ICAjTXVlc3RyYSBlc3RpbWFjaW9uZXMgZXN0YW5kYXJpemFkYXMgZGUgbG9zIHBhcsOhbWV0cm9zDQogICAgICAgICAjd2hhdExhYmVscyA9Im5hbWUiOiAjTXVlc3RyYSBsb3Mgbm9tYnJlcyBkZSBsYXMgcmVsYWNpb25lcyBvIHBhcsOhbWV0cm9zDQogICAgICAgICAjd2hhdExhYmVscyA9Im5vbmUiOiAjTm8gbXVlc3RyYSBuaW5ndW5hIGV0aXF1ZXRhIGVuIGxhcyBhcmlzdGFzDQogICAgICAgICAjd2hhdExhYmVscyA9ImVxIjogICAjTXVlc3RyYSBldGlxdWV0YXMgZGUgZWN1YWNpb25lcyAodXN1YWxtZW50ZSBlbiBTRU0pLg0KICAgICAgICAgI3doYXRMYWJlbHMgPSJib3RoIjogI011ZXN0cmEgZXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzIHkgbm8gZXN0YW5kYXJpemFkYXMNCiAgICAgICAgICANCiAgICAgICAgIHN0eWxlID0gImxpc3JlbCIsICNVc2EgdW4gZXN0aWxvIHByZWRlZmluaWRvIHNpbWlsYXIgYWwgZXN0aWxvIExJU1JFTA0KICAgICAgICAgI3N0eWxlID0gInJhbSI6ICAgI0VzdGlsbyBkZSBSQU0gKFJldGljdWxhciBBY3Rpb24gTW9kZWwpLCBjb23Dum4gZW4gZ3LDoWZpY29zIFNFTQ0KICAgICAgICAgI3N0eWxlID0gIm14IjogICAgI0VzdGlsbyBkZSBNeCwgIGhlcnJhbWllbnRhIGRlIFNFTQ0KICAgICAgICAgI3N0eWxlID0gImVxcyI6ICAgI0VzdGlsbyBzaW1pbGFyIGFsIHNvZnR3YXJlIEVRUw0KDQogICAgICAgICAjbGF5b3V0ID0gInRyZWUiLCAgICNEaXNwb25lIG5vZG9zIGVuIHVuYSBlc3RydWN0dXJhIGplcsOhcnF1aWNhIHNpbWlsYXIgYSB1biDDoXJib2wNCiAgICAgICAgIGxheW91dD0idHJlZTIiLCAgICAgI1BhcmVjaWRhIGEgbGEgYW50ZXJpb3INCiAgICAgICAgICNsYXlvdXQ9ImNpcmNsZSIsICAgI0Rpc3BvbmUgbm9kb3MgZW4gY8OtcmN1bG8gKHNvbG8gcGVybWl0aWRvIHNpIHJvdGF0aW9uPSAxIG8gMykNCiAgICAgICAgICNsYXlvdXQgPSAic3ByaW5nIiwgI01pbmltaXphIGZ1ZXJ6YXMgZGUgcmVwdWxzacOzbiB5IGF0cmFjY2nDs24gZW50cmUgbm9kb3MNCiAgICAgICAgICNsYXlvdXQgPSAibGdsIiwgICAgI0FsZ29yaXQuICJMYXJnZSBHcmFwaCBMYXlvdXQiICjDunRpbCBwYXJhIGdyw6FmaWNvcyBncmFuZGVzKQ0KICAgICAgICAgI2xheW91dCA9ICJrYW1hZGEiLCAgICAgICNBbGdvcml0LiBLYW1hZGEtS2F3YWkgcGFyYSBkaXNwb3NpY2nDs24gYmFzYWRhIGVuIGVuZXJnw61hDQogICAgICAgICAjbGF5b3V0ID0gImZydWNodGVybWFuIiwgI0FsZ29yaXRtbyBGcnVjaHRlcm1hbi1SZWluZ29sZCAoZGlzcG9zaWNpw7NuIHBvciBmdWVyemFzKQ0KDQogICAgICAgICAjcm90YXRpb24gPSAxLCAjUm90YWNpw7NuIGRlIHRvZG8gZWwgZGlhZ3JhbWENCiAgICAgICAgIHJvdGF0aW9uPTIsIA0KICAgICAgICAgI3JvdGF0aW9uPTMsDQogICAgICAgICANCiAgICAgICAgIG5DaGFyTm9kZXMgPSAwLCAjMD1hanVzdGFyIGFsIG7Dum1lcm8gbcOheGltbyBkZSBjYXJhY3RlcmVzIGRlbnRybyBkZSBsYXMgbGF0ZW50ZXMNCiAgICAgICAgIHNpemVNYW4gPSA4LCAgICAjVGFtYcOxbyBkZSBsb3Mgbm9kb3MgcXVlIHJlcHJlc2VudGFuIHZhcmlhYmxlcyBtYW5pZmllc3Rhcw0KICAgICAgICAgc2l6ZUxhdCA9IDksICAgICNUYW1hw7FvIGRlIGxvcyBub2RvcyBxdWUgcmVwcmVzZW50YW4gdmFyaWFibGVzIGxhdGVudGVzDQogICAgICAgICBzaXplSW50ID0gMSwgICAgI1RhbWHDsW8gZGUgbG9zIG5vZG9zIHF1ZSByZXByZXNlbnRhbiB2YXJpYWJsZXMgaW50ZXJpb3Jlcw0KICAgICAgICAgbkNoYXJFZGdlcyA9IDMsICNOw7ptZXJvIG3DoXhpbW8gZGUgY2FyYWN0ZXJlcyBwYXJhIGV0aXF1ZXRhcyBkZSBjYXJnYXMgZmFjdG9yaWFsZXMNCiAgICAgICAgIA0KICAgICAgICAgZWRnZS5sYWJlbC5jZXggPSAxLCAgICAgICNUYW1hw7FvIGRlIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMNCiAgICAgICAgIA0KICAgICAgICAgI2ZyZWVTdHlsZSA9ICJibHVlIiwgICAgICNQYXLDoW1ldHJvcyBmaWpvcyBzb24gYXp1bGVzDQogICAgICAgICBmaXhlZFN0eWxlID0gYygicmVkIiwzKSwgI1BhcsOhbWV0cm9zIGZpam9zIHNvbiByb2pvcyB5IGRlIHRhbWHDsW8gMw0KICAgDQogICAgICAgICAjY3VydmVQaXZvdD1UUlVFLCAgICAjQ29uZXhpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYQ0KICAgICAgICAgaW50ZXJjZXB0cz1UUlVFLCAgICAgI1NlIG11ZXN0cmFuIG8gbm8gbG9zIGludGVyY2VwdG9zIGRlIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgcmVzaWR1YWxzPUZBTFNFLCAgICAgI0Fzw60gbm8gYXBhcmVjZW4gZmxlY2hhcyBkZSB2YXIuIG9ic2VydmFkYXMNCiAgICAgICAgIGV4b0Nvdj1GQUxTRSwgICAgICAgICNBc8OtIG5vIGFwYXJlY2VuIGZsZWNoYXMgZGUgY292YXJpYW56YXMgZGUgdmFyLiBsYXRlbnRlcw0KICAgICAgICAgDQogICAgICAgICBjb2xvciA9IGxpc3QoDQogICAgICAgICAgIGxhdCA9ICJvcmFuZ2UiLCAgICAjQ29sb3IgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgICBtYW4gPSAibGlnaHRncmVlbiIgI0NvbG9yIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcw0KICAgICAgICAgICApIA0KICAgICAgICAgKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdXRwdXQgZGUgYGNmYWA6IG9ic2VydmFjaW9uZXMNCg0KMS4gTGEgZnVuY2nDs24gYGNmYWAgZXMgdW5hIGZ1bmNpw7NuIGVzcGVjw61maWNhIHBhcmEgZXN0YWJsZWNlciBtb2RlbG9zIGRlIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3Jpby4gDQoNCjIuIEVsIHByaW1lciBhcmd1bWVudG8gZXMgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpby4gDQoNCjMuIEVsIHNlZ3VuZG8gYXJndW1lbnRvIGVzIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHF1ZSBjb250aWVuZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMuDQoNCjQuIExvcyBpbnRlcmNlcHRvcyAkXHRhdSQgZGUgbG9zIGZhY3RvcmVzIHJlcHJlc2VudGFuIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIChgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgLCBgeDlgKSBjdWFuZG8gbG9zIGZhY3RvcmVzIGxhdGVudGVzIChgVmlzdWFsYCwgIGBUZXh0dWFsYCwgIGBTcGVlZGApIHRpZW5lbiB1biB2YWxvciBkZSBjZXJvLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYGNmYWA6IHByaW1lcmEgcGFydGUNCg0KIyMjIEdyw6FmaWNhIGRlIGxhIHByaW1lcmEgcGFydGUNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW41KSBzZSByZXNhbHRhIGxhIHByaW1lcmEgcGFydGUgZGVsIG91dHB1dCBkZSBgbGF2YWFuLiANCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjUsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQcmltZXJhIHBhcnRlIGRlbCBvdXRwdXQgZGUgYGxhdmFhbmAgKGluZm9ybWFjacOzbiBnZW5lcmFsKSoqIiAsIG91dC53aWR0aCA9ICI3MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuNS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbmZvcm1hY2nDs24gZ2VuZXJhbCBkZWwgb3V0cHV0DQoNCioqMS4gRWwgbW9kZWxvIGZpbmFsaXrDsyBub3JtYWxtZW50ZSBkZXNwdcOpcyBkZSAzNSBpdGVyYWNpb25lcy4qKg0KDQpFc3RlIG1lbnNhamUgaW5kaWNhIHF1ZSBlbCBwcm9jZXNvIGRlIGVzdGltYWNpw7NuIGRlbCBtb2RlbG8gZmluYWxpesOzIGNvcnJlY3RhbWVudGUgZGVzcHXDqXMgZGUgMzUgaXRlcmFjaW9uZXMuIEVzdG8gc2lnbmlmaWNhIHF1ZSBlbCBhbGdvcml0bW8gZGUgb3B0aW1pemFjacOzbiBhbGNhbnrDsyB1bmEgc29sdWNpw7NuIGVzdGFibGUgZGVudHJvIGRlbCBuw7ptZXJvIGVzcGVjaWZpY2FkbyBkZSBpdGVyYWNpb25lcy4NCg0KKioyLiBFbCBlc3RpbWFkb3IgdXRpbGl6YWRvIGZ1ZSBlbCBtw6F4aW1vIHZlcm9zaW1pbGl0dWQgKE1MKS4qKg0KDQpgTUxgIHNpZ25pZmljYSAqTWF4aW11bSBMaWtlbGlob29kKiAoKk3DoXhpbWEgVmVyb3NpbWlsaXR1ZCopLiBFcyBlbCBlc3RpbWFkb3IgdXRpbGl6YWRvIHBhcmEgYWp1c3RhciBlbCBtb2RlbG8uIEVsIGVzdGltYWRvciBkZSBtw6F4aW1hIHZlcm9zaW1pbGl0dWQgZXMgdW5vIGRlIGxvcyBtw6l0b2RvcyBtw6FzIGNvbXVuZXMgcGFyYSBlc3RpbWFyIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvIGVuIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbywgeWEgcXVlIHNlIGJhc2EgZW4gbGEgc3Vwb3NpY2nDs24gZGUgcXVlIGxvcyBkYXRvcyBzaWd1ZW4gdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KDQoqKjMuIEVsIG3DqXRvZG8gZGUgb3B0aW1pemFjacOzbiBmdWUgTkxNSU5CLioqDQoNCiAgKyBMYSBhYnJldmlhdHVyYSBgTkxNSU5CYCBzZSByZWZpZXJlIGEgIk5vbmxpbmVhciBNSU5pbWl6YXRpb24gdXNpbmcgQm91bmRzIiwgcXVlIHNpZ25pZmljYSAiTWluaW1pemFjacOzbiBubyBsaW5lYWwgdXNhbmRvIGzDrW1pdGVzIi4gDQogIA0KICArIEVzcGVjw61maWNhbWVudGUsIGBOTE1JTkJgIHNlIHJlZmllcmUgYWwgbcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIHVzYWRvIHBhcmEgZW5jb250cmFyIGxvcyB2YWxvcmVzIMOzcHRpbW9zIGRlIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvLiANCiAgDQogICsgYE5MTUlOQmAgZXMgdW4gYWxnb3JpdG1vIGRlIG9wdGltaXphY2nDs24gcXVlIGVzIHJvYnVzdG8geSBlZmljaWVudGUsIGVzcGVjaWFsbWVudGUgcGFyYSBwcm9ibGVtYXMgIGRlIG1pbmltaXphY2nDs24gbm8gbGluZWFscXVlIHRpZW5lbiByZXN0cmljY2lvbmVzIGVuIGxvcyBwYXLDoW1ldHJvcyBvIHNvbiBkZSBuYXR1cmFsZXphIG5vIGxpbmVhbC4NCiAgDQogICsgRW4gc2VjY2lvbmVzIHNpZ3VpZW50ZXMsIHNlIGRlc2NyaWJpcsOhbiBicmV2ZW1lbnRlIG90cm9zIG3DqXRvZG9zIGFsdGVybmF0aXZvcyBkZSBvcHRpbWl6YWNpw7NuLiANCg0KKio0LiBFbCBtb2RlbG8gdGllbmUgMjEgcGFyw6FtZXRyb3MuKioNCg0KRXN0YSBsw61uZWEgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gdGllbmUgdW4gdG90YWwgZGUgMjEgcGFyw6FtZXRyb3MgYSBlc3RpbWFyLiBFc3RvIGluY2x1eWUgY2FyZ2FzIGZhY3RvcmlhbGVzLCB2YXJpYW56YXMsIGNvdmFyaWFuemFzIHkgdMOpcm1pbm9zIGRlIGVycm9yLCBlbnRyZSBvdHJvcy4gRW4gc2VjY2lvbmVzIHNpZ3VpZW50ZXMgc2UgdmEgYSBkZXRhbGxhciBtw6FzIGFsIHJlc3BlY3RvLiANCg0KKio1LiBTZSB1dGlsaXphcm9uIDMwMSBvYnNlcnZhY2lvbmVzIGVuIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLioqDQoNCkVzdGEgc2VjY2nDs24gbXVlc3RyYSBxdWUgc2UgdXRpbGl6YXJvbiAzMDEgb2JzZXJ2YWNpb25lcyAobyBjYXNvcykgcGFyYSBhanVzdGFyIGVsIG1vZGVsby4gRXMgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIGRlIGRhdG9zLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgY2ZhYDogZXN0aW1hZG9yZXMNCg0KIyMjIE90cm9zIGVzdGltYWRvcmVzIGVuIGBsYXZhYW5gIChhcGFydGUgZGUgYE1MYCkNCg0KKioxLiBgTUxSYCAoTWF4aW11bSBMaWtlbGlob29kIHdpdGggUm9idXN0IFN0YW5kYXJkIEVycm9ycykuKioNCiAgDQogICsgUHJvcG9yY2lvbmEgZXJyb3JlcyBlc3TDoW5kYXIgcm9idXN0b3MgeSB1bmEgcHJ1ZWJhIGNoaS1jdWFkcmFkbyByb2J1c3RhLg0KICANCiAgKyBFcyDDunRpbCBjdWFuZG8gbG9zIGRhdG9zIG5vIGN1bXBsZW4gY29uIGxhIHN1cG9zaWNpw7NuIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLg0KDQoqKjIuIGBNTE1gIChNYXhpbXVtIExpa2VsaWhvb2Qgd2l0aCBSb2J1c3QgU3RhbmRhcmQgRXJyb3JzKS4qKg0KICANCiAgKyBTaW1pbGFyIGEgTUxSIHBlcm8gdXNhIGxhIGNvcnJlY2Npw7NuIGRlIFNhdG9ycmEtQmVudGxlciBwYXJhIGVsIGVzdGFkw61zdGljbyBjaGktY3VhZHJhZG8uDQogIA0KICArIEVzIGFkZWN1YWRvIHBhcmEgZGF0b3MgcXVlIG5vIHNvbiBub3JtYWxlcyBwZXJvIHF1ZSB0aWVuZW4gZGVzdmlhY2lvbmVzIGxldmVzIGRlIGxhIG5vcm1hbGlkYWQuDQoNCioqMy4gYE1MRmAgKE1heGltdW0gTGlrZWxpaG9vZCB3aXRoIFJvYnVzdCBTdGFuZGFyZCBFcnJvcnMgYW5kIGEgU2NhbGluZyBGYWN0b3IpLioqDQoNClNpbWlsYXIgYSBNTFIgcGVybyBpbmNsdXllIHVuIGZhY3RvciBkZSBlc2NhbGFkbyBhZGljaW9uYWwgcGFyYSBhanVzdGFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhci4NCg0KDQoqKjQuIGBXTFNgIChXZWlnaHRlZCBMZWFzdCBTcXVhcmVzKS4qKg0KDQpVdGlsaXphIGxhcyBtYXRyaWNlcyBkZSBjb3ZhcmlhbnphIHkgYXNpbWV0csOtYSBwYXJhIGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zLg0KRXMgZXNwZWNpYWxtZW50ZSDDunRpbCBwYXJhIGRhdG9zIGNhdGVnw7NyaWNvcyB5IG9yZGluYWxlcy4NCg0KDQoqKjUuIGBXTFNNYCAoV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcyBNZWFuIGFuZCBWYXJpYW5jZSBhZGp1c3RlZCkuKioNCiAgDQogICsgVW5hIHZhcmlhbnRlIGRlbCBXTFMgcXVlIGFqdXN0YSB0YW50byBsYSBtZWRpYSBjb21vIGxhIHZhcmlhbnphLCBwcm9wb3JjaW9uYW5kbyB1bmEgY29ycmVjY2nDs24gcm9idXN0YS4NCiAgDQogICsgVGFtYmnDqW4gZXMgYWRlY3VhZG8gcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MgeSBvcmRpbmFsZXMuDQoNCioqNi4gYFdMU01WYCAoV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcyBNZWFuIGFuZCBWYXJpYW5jZSBhZGp1c3RlZCkuKioNCiAgDQogICsgU2ltaWxhciBhIGBXTFNNYCBwZXJvIGNvbiB1bmEgY29ycmVjY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgbWVkaWEgeSBsYSB2YXJpYW56YS4NCiAgDQogICsgRXMgYW1wbGlhbWVudGUgdXRpbGl6YWRvIHBhcmEgbW9kZWxvcyBjb24gZGF0b3MgY2F0ZWfDs3JpY29zLg0KDQoNCioqNy4gYFVMU2AgKFVud2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcykuKioNCiAgDQogICsgTWluaW1pemEgbGFzIGRpc2NyZXBhbmNpYXMgc2luIHBvbmRlcmFyIGxhcyBvYnNlcnZhY2lvbmVzLg0KICANCiAgKyBQdWVkZSBzZXIgw7p0aWwgZW4gY2Fzb3MgZG9uZGUgc2UgcHJlZmllcmVuIG3DqXRvZG9zIG5vIHBvbmRlcmFkb3MuDQoNCioqOC4gYFVMU01gIChVbndlaWdodGVkIExlYXN0IFNxdWFyZXMgTWVhbiBhbmQgVmFyaWFuY2UgYWRqdXN0ZWQpLioqDQoNClNpbWlsYXIgYSBVTFMgcGVybyBhanVzdGEgbGEgbWVkaWEgeSBsYSB2YXJpYW56YS4NCg0KKio5LiBgRFdMU2AgKERpYWdvbmFsbHkgV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcykuKioNCiAgDQogICsgU2ltaWxhciBhIFdMUyBwZXJvIHVzYSBzb2xvIGxvcyBlbGVtZW50b3MgZGlhZ29uYWxlcyBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YS4NCiAgDQogICsgRXMgbcOhcyBlZmljaWVudGUgY29tcHV0YWNpb25hbG1lbnRlIHkgYWRlY3VhZG8gcGFyYSBkYXRvcyBjb24gdmFyaWFibGVzIGNhdGVnw7NyaWNhcy4NCg0KKioxMC4gYFBNTGAgKFBzZXVkb21heGltdW0gTGlrZWxpaG9vZCkuKioNCg0KVXRpbGl6YWRvIHByaW5jaXBhbG1lbnRlIHBhcmEgZGF0b3MgZGUgY29udGVvIG8gY3VhbmRvIHNlIHRpZW5lIGluZm9ybWFjacOzbiBpbmNvbXBsZXRhLg0KDQoqKjExLiBgQmF5ZXNgIChCYXllc2lhbiBFc3RpbWF0aW9uKS4qKg0KICANCiAgKyBVdGlsaXphIG3DqXRvZG9zIGJheWVzaWFub3MgcGFyYSBsYSBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcy4NCiAgDQogICsgRXMgw7p0aWwgY3VhbmRvIHNlIGRlc2VhIGluY29ycG9yYXIgaW5mb3JtYWNpw7NuIGEgcHJpb3JpIG8gY3VhbmRvIGxvcyBtb2RlbG9zIHNvbiBjb21wbGVqb3MgeSBvdHJvcyBtw6l0b2RvcyBmYWxsYW4gZW4gY29udmVyZ2VyLg0KICANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvcyBlc3RpbWFkb3JlcyBlbiBgbGF2YWFuYCAoZWplbXBsb3MpDQoNCg0KKioxLiBBIG1hbmVyYSBkZSBlamVtcGxvLCBwYXJhIGFqdXN0YXIgZWwgbW9kZWxvIHV0aWxpemFuZG8gZWwgZXN0aW1hZG9yIGBXTFNNVmAsIHNlIGVqZWN1dGE6KioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpmaXQgPC0gbGF2YWFuOjpjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBlc3RpbWF0b3IgPSAiV0xTTVYiKQ0KZml0DQpgYGANCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIGVzdGltYXRvciA9ICJXTFNNViIpDQpmaXQNCmBgYA0KDQoNCioqMi4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIGVzdGltYWRvciBgQmF5ZXNgLCBzZSBlamVjdXRhOioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KZml0IDwtIGJsYXZhYW46OmJjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBlc3RpbWF0b3IgPSAiQmF5ZXMiLCBidXJuaW4gPSAxMDAsIHNhbXBsZSA9IDEwMDApDQpmaXQNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBibGF2YWFuOjpiY2ZhKG1vZGVsbywgZGF0YSA9IGRhdCwgZXN0aW1hdG9yID0gIkJheWVzIiwgYnVybmluID0gMTAwLCBzYW1wbGUgPSAxMDAwKQ0KZml0DQpgYGANCg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVsZWNjacOzbiBkZWwgRXN0aW1hZG9yDQoNCkxhIGVsZWNjacOzbiBkZWwgZXN0aW1hZG9yIGRlcGVuZGUgZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgbnVlc3Ryb3MgZGF0b3MgeSBkZSBsYXMgaGlww7N0ZXNpcyBzdWJ5YWNlbnRlcyBlbiB0dSBtb2RlbG8uIEFxdcOtIGhheSBhbGd1bmFzIHBhdXRhcyBnZW5lcmFsZXM6DQogIA0KICAxLiBgTUxgIChNYXhpbXVtIExpa2VsaWhvb2QpOiBVdGlsaXphZG8gY29tw7pubWVudGUgY3VhbmRvIHNlIGFzdW1lIHF1ZSBsb3MgZGF0b3Mgc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuDQogIA0KICAyLiBgTUxSYCwgYE1MTWAsIGBNTEZgOiBVdGlsaXphZG9zIGN1YW5kbyBsb3MgZGF0b3Mgbm8gY3VtcGxlbiBjb24gbGEgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEuDQogIA0KICAzLiBgV0xTYCwgYFdMU01gLCBgV0xTTVZgLCBgRFdMU2A6IFByZWZlcmlkb3MgcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MgdSBvcmRpbmFsZXMuDQogIA0KICA0LiBgVUxTYCwgYFVMU01gOiBVdGlsaXphZG9zIGN1YW5kbyBzZSBwcmVmaWVyZW4gbcOpdG9kb3Mgbm8gcG9uZGVyYWRvcy4NCiAgDQogIDUuIGBCYXllc2A6IMOadGlsIHBhcmEgbW9kZWxvcyBjb21wbGVqb3MgbyBjdWFuZG8gc2UgZGVzZWEgaW5jb3Jwb3JhciBpbmZvcm1hY2nDs24gYSBwcmlvcmkuDQoNCkNhZGEgZXN0aW1hZG9yIHRpZW5lIHN1cyBwcm9waWFzIHZlbnRhamFzIHkgZGVzdmVudGFqYXMsIHBvciBsbyBxdWUgZXMgaW1wb3J0YW50ZSBjb25zaWRlcmFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRlIHR1cyBkYXRvcyB5IGVsIG9iamV0aXZvIGRlIHR1IGFuw6FsaXNpcyBhbCBzZWxlY2Npb25hciBlbCBlc3RpbWFkb3IgYWRlY3VhZG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBjZmFgOiBtw6l0b2RvcyBkZSBvcHRpbWl6YWNpw7NuDQoNCiMjIyAgQ2FyYWN0ZXLDrXN0aWNhcyBkZSBgTkxNSU5CYA0KDQoqKjEuIE1hbmVqbyBkZSBSZXN0cmljY2lvbmVzLioqDQoNCmBOTE1JTkJgIHB1ZWRlIG1hbmVqYXIgdGFudG8gcmVzdHJpY2Npb25lcyBkZSBpZ3VhbGRhZCBjb21vIGRlIGRlc2lndWFsZGFkIGVuIGxvcyBwYXLDoW1ldHJvcywgbG8gY3VhbCBlcyDDunRpbCBlbiBtdWNob3MgcHJvYmxlbWFzIHByw6FjdGljb3MgZG9uZGUgY2llcnRvcyBwYXLDoW1ldHJvcyBkZWJlbiBtYW50ZW5lcnNlIGRlbnRybyBkZSBjaWVydG9zIGzDrW1pdGVzLg0KDQoqKjIuIFJvYnVzdGV6LioqIA0KDQpFcyB1biBhbGdvcml0bW8gcm9idXN0bywgbG8gcXVlIHNpZ25pZmljYSBxdWUgcHVlZGUgY29udmVyZ2VyIGVuIHVuYSBzb2x1Y2nDs24gw7NwdGltYSBlbiB1bmEgYW1wbGlhIHZhcmllZGFkIGRlIHByb2JsZW1hcywgaW5jbHV5ZW5kbyBhcXVlbGxvcyBxdWUgc29uIGRpZsOtY2lsZXMgZGUgcmVzb2x2ZXIgcGFyYSBvdHJvcyBhbGdvcml0bW9zIGRlIG9wdGltaXphY2nDs24uDQoNCioqMy4gQ29udmVyZ2VuY2lhLioqDQoNCkZ1bmNpb25hIGJpZW4gZW4gcHJvYmxlbWFzIGRlIG9wdGltaXphY2nDs24gZG9uZGUgb3Ryb3MgbcOpdG9kb3MgcG9kcsOtYW4gbm8gY29udmVyZ2VyLCBlc3BlY2lhbG1lbnRlIGVuIHByZXNlbmNpYSBkZSByZXN0cmljY2lvbmVzIGNvbXBsaWNhZGFzLg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvcyBtw6l0b2RvIGRlIG9wdGltaXphY2nDs24gZW4gYGxhdmFhbmAgKGFwYXJ0ZSBkZSBgTkxNSU5CYCkNCg0KQWRlbcOhcyBkZSBgTkxNSU5CYCwgYGxhdmFhbmAgb2ZyZWNlIG90cm9zIG3DqXRvZG9zIGRlIG9wdGltaXphY2nDs24uIEFxdcOtIGhheSB1bmEgbGlzdGEgZGUgYWxndW5hcyBkZSBsYXMgb3BjaW9uZXMgeSBzdXMgY2FyYWN0ZXLDrXN0aWNhcyBwcmluY2lwYWxlczoNCg0KMS4gYEJGR1NgOiBNw6l0b2RvIEJyb3lkZW4tRmxldGNoZXItR29sZGZhcmItU2hhbm5vLCB1biBhbGdvcml0bW8gcXVhc2ktTmV3dG9uIHF1ZSBlcyBhZGVjdWFkbyBwYXJhIHByb2JsZW1hcyBzdWF2ZXMgeSBiaWVuIGNvbXBvcnRhZG9zLiBObyBtYW5lamEgcmVzdHJpY2Npb25lcyBleHBsw61jaXRhcyB0YW4gZsOhY2lsbWVudGUgY29tbyBOTE1JTkIuIA0KDQoyLiBgTC1CRkdTLUJgOiBVbmEgdmFyaWFudGUgZGVsIEJGR1MgcXVlIHBlcm1pdGUgcmVzdHJpY2Npb25lcyBlbiBsb3MgcGFyw6FtZXRyb3MgKGNvdGFzIGluZmVyaW9yZXMgeSBzdXBlcmlvcmVzKSwgw7p0aWwgZW4gcHJvYmxlbWFzIGRvbmRlIGxvcyBwYXLDoW1ldHJvcyBuZWNlc2l0YW4gZXN0YXIgZGVudHJvIGRlIGNpZXJ0b3MgcmFuZ29zLg0KDQozLiBgQ0dgOiBHcmFkaWVudGUgY29uanVnYWRvLCBhZGVjdWFkbyBwYXJhIHByb2JsZW1hcyBncmFuZGVzIHkgZGlzcGVyc29zLiBFcyBtZW5vcyBpbnRlbnNpdm8gZW4gbWVtb3JpYSBjb21wYXJhZG8gY29uIGBCRkdTYC4NCg0KNC4gYFNBTk5gOiBSZWNvY2lkbyBzaW11bGFkbyAoU2ltdWxhdGVkIEFubmVhbGluZyksIHVuIGFsZ29yaXRtbyBkZSBvcHRpbWl6YWNpw7NuIGdsb2JhbCBxdWUgcHVlZGUgZXZpdGFyIG3DrW5pbW9zIGxvY2FsZXMsIGF1bnF1ZSBlcyBtZW5vcyBlZmljaWVudGUgcGFyYSBlbmNvbnRyYXIgc29sdWNpb25lcyBwcmVjaXNhcy4NCg0KNS4gYE5lbGRlci1NZWFkYDogTcOpdG9kbyBzaW1wbGV4LCDDunRpbCBwYXJhIHByb2JsZW1hcyBzaW4gcmVzdHJpY2Npb25lcyBubyBsaW5lYWxlcy4gRXMgcm9idXN0bywgcGVybyBwdWVkZSBzZXIgbWVub3MgZWZpY2llbnRlIGVuIHByb2JsZW1hcyBkZSBncmFuIGVzY2FsYS4NCg0KNi4gYHNvbG5wYDogTcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIG5vIGxpbmVhbCBjb24gcmVzdHJpY2Npb25lcywgw7p0aWwgZW4gcHJvYmxlbWFzIHF1ZSB0aWVuZW4gdGFudG8gcmVzdHJpY2Npb25lcyBsaW5lYWxlcyBjb21vIG5vIGxpbmVhbGVzLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIE90cm9zIG3DqXRvZG8gZGUgb3B0aW1pemFjacOzbiBlbiBgbGF2YWFuYCAoZWplbXBsb3MpDQoNCioqMS4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIG3DqXRvZG8gYEJGR1NgLCBzZSBlamVjdXRhOioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KZml0IDwtIGxhdmFhbjo6Y2ZhKG1vZGVsbywgZGF0YSA9IGRhdCwgb3B0aW0ubWV0aG9kID0gIkJGR1MiKQ0KZml0DQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpmaXQgPC0gbGF2YWFuOjpjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBvcHRpbS5tZXRob2QgPSAiQkZHUyIpDQpmaXQNCmBgYA0KDQoNCioqMi4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIG3DqXRvZG8gYHNvbG5wYCwgc2UgZWplY3V0YToqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIG9wdGltLm1ldGhvZCA9ICJzb2xucCIpDQpmaXQNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIG9wdGltLm1ldGhvZCA9ICJzb2xucCIpDQpmaXQNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYGNmYWA6IGludGVyY2VwdG9zIA0KDQojIyMgSW50ZXJwcmV0YWNpw7NuIGRlIGxvcyBpbnRlcmNlcHRvcyBlbiBgbGF2YWFuYA0KDQpFbCBwYXF1ZXRlIGxhdmFhbiBzaWd1ZSBjaWVydGFzIGNvbnZlbmNpb25lcyB5IHN1cG9zaWNpb25lcyBlbiBlbCBhbsOhbGlzaXMgQ0ZBIHF1ZSBhZmVjdGFuIGxhIGVzdGltYWNpw7NuIHkgY29udGVvIGRlIGxvcyBwYXLDoW1ldHJvczoNCg0KKioxLiBNb2RlbG8gZW4gRXNjYWxhIEVzdMOhbmRhciAoU3RhbmRhcmRpemVkIFNvbHV0aW9uKS4qKg0KICANCiAgKyBFbiBsYSBzb2x1Y2nDs24gZXN0w6FuZGFyLCBsYXMgbWVkaWFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcyBzZSBmaWphbiBhIGNlcm8gKCRcYWxwaGFfMT0wJCwgJFxhbHBoYV8yPTAkLCAkXGFscGhhXzM9MCQpLg0KICANCiAgKyBFc3RvIGltcGxpY2EgcXVlIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNlIGV4cGxpY2FuIMO6bmljYW1lbnRlIGVuIHTDqXJtaW5vcyBkZSBzdXMgaW50ZXJjZXB0b3MgeSBubyBzZSByZXF1aWVyZW4gZXN0aW1hY2lvbmVzIGFkaWNpb25hbGVzIGRlIGxvcyBpbnRlcmNlcHRvcy4NCiAgDQoNCioqMi4gSWRlbnRpZmljYWNpw7NuIGRlbCBNb2RlbG8uKioNCiAgDQogICsgUGFyYSBhc2VndXJhciBxdWUgZWwgbW9kZWxvIHNlYSBpZGVudGlmaWNhYmxlLCBhIG1lbnVkbyBzZSBmaWphbiBjaWVydG9zIHBhcsOhbWV0cm9zIGEgdmFsb3JlcyBjb25vY2lkb3MgKHBvciBlamVtcGxvLCBmaWphciB1bmEgY2FyZ2EgZmFjdG9yaWFsIGEgMSB5IGxvcyBpbnRlcmNlcHRvcyBkZSBsb3MgZmFjdG9yZXMgYSBjZXJvKS4NCiAgDQogICsgRW4gY29uc2VjdWVuY2lhLCBsb3MgaW50ZXJjZXB0b3MgZGUgbG9zIGZhY3RvcmVzIG5vIHNlIGVzdGltYW4gZGUgbWFuZXJhIGV4cGzDrWNpdGEgZW4gZWwgbW9kZWxvIHBvcnF1ZSB5YSBzZSBhc3VtZW4gY29tbyBwYXJ0ZSBkZWwgYWp1c3RlIGdsb2JhbCBkZWwgbW9kZWxvLg0KICANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFRvdGFsIGRlIHBhcsOhbWV0cm9zIGVuIGNhZGEgZ3J1cG8NCg0KUGFyYSBleHBsaWNhciBwb3IgcXXDqSBlbCBvdXRwdXQgZGUgYGxhdmFhbjo6Y2ZhYCAgbXVlc3RyYSAyMSBwYXLDoW1ldHJvcywgZGViZW1vcyBkZXNnbG9zYXIgbG9zIGNvbXBvbmVudGVzIGRlbCBtb2RlbG8geSBsb3MgcGFyw6FtZXRyb3MgcXVlIHNlIGVzdGltYW4uDQoNClZhbW9zIGEgZW51bWVyYXIgbG9zIHBhcsOhbWV0cm9zIHBhcmEgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbzoNCg0KICoqMS4gQ2FyZ2FzIEZhY3RvcmlhbGVzLioqDQoNCkNhZGEgaW5kaWNhZG9yIHRpZW5lIHVuYSBjYXJnYSBmYWN0b3JpYWwgcGFyYSBlbCBmYWN0b3IgYWwgcXVlIGVzdMOhIGFzaWduYWRvOg0KICAgIA0KICArIGBWaXN1YWxgOiBgeDFgLCBgeDJgLCBgeDNgLg0KICAgIA0KICArIGBUZXh0dWFsYDogYHg0YCwgYHg1YCwgYHg2YC4NCiAgICANCiAgKyBgU3BlZWRgOiAgYHg3YCwgYHg4YCwgYHg5YC4NCiAgICANCkNhZGEgdW5vIGRlIGVzdG9zIGluZGljYWRvcmVzIHRpZW5lIHVuYSBjYXJnYSBmYWN0b3JpYWwsIHN1bWFuZG8gdW4gdG90YWwgZGUgOSBjYXJnYXMgZmFjdG9yaWFsZXMuDQoNCg0KDQoqKjIuIEludGVyY2VwdG9zIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKg0KDQpDYWRhIGluZGljYWRvciB0aWVuZSBhc29jaWFkbyB1biBpbnRlY2VwdG8gcGFyYSBgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgIHkgYHg5YC4gRW50b25jZXMsIGVuIHRvdGFsIHNlcsOtYW4gOSBpbnRlcmNlcHRvcy4NCg0KKiozLiBWYXJpYW56YXMgZGUgbG9zIEVycm9yZXMgZGUgTWVkaWNpw7NuKio6IA0KDQpDYWRhIGluZGljYWRvciB0aWVuZSB1bmEgdmFyaWFuemEgZGUgZXJyb3IgYXNvY2lhZGEgcGFyYSBgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgIHkgYHg5YC4gRXN0byBzdW1hIDkgcGFyw6FtZXRyb3MuDQoNCioqNC4gTWVkaWFzIGRlIGxvcyBmYWN0b3Jlcy4qKg0KDQpDYWRhIGZhY3RvciB0aWVuZSBhc29jaWFkYSB1bmEgbWVkaWE6IA0KDQogDQogICsgTWVkaWEgZGUgYFZpc3VhbGAuDQogIA0KICArIE1lZGlhIGRlIGBUZXh0dWFsYC4NCiAgDQogICsgbWVkaWEgZGUgYFNwZWVkYC4NCg0KRXMgZGVjaXIsIHNlcsOtYW4gMyBwYXLDoW1ldHJvcy4gDQoNCg0KKio1LiBWYXJpYW56YXMgZGUgbG9zIEZhY3RvcmVzIExhdGVudGVzLioqDQogDQpIYXkgdHJlcyBmYWN0b3JlcyBsYXRlbnRlcyAoYFZpc3VhbGAsICBgVGV4dHVhbGAsICBgU3BlZWRgKSwgeSBzZSBlc3RpbWEgdW5hIHZhcmlhbnphIHBhcmEgY2FkYSB1bm86DQogIA0KICArIFZhcmlhbnphIGRlIGBWaXN1YWxgLg0KICANCiAgKyBWYXJpYW56YSBkZSBgVGV4dHVhbGAuDQogIA0KICArIFZhcmlhbnphIGRlIGBTcGVlZGAuDQoNCkVzdG8gc3VtYSAzIHBhcsOhbWV0cm9zLg0KDQoqKjYuIENvdmFyaWFuemFzIGVudHJlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKg0KDQpIYXkgY292YXJpYW56YXMgZW50cmUgY2FkYSBwYXIgZGUgZmFjdG9yZXMgbGF0ZW50ZXMuIFBhcmEgdHJlcyBmYWN0b3JlcywgZXN0byBzZSBjYWxjdWxhIGNvbW8gDQokezMgXGNob29zZSAyfT0zJCBjb3ZhcmlhbnphczoNCg0KICANCiAgKyBDb3ZhcmlhbnphIGRlIGBWaXN1YWxgLWBUZXh0dWFsYC4NCiAgDQogICsgQ292YXJpYW56YSBkZSBgVmlzdWFsYC1gU3BlZWRgLg0KICANCiAgKyBDb3ZhcmlhbnphIGRlIGBUZXh0dWFsYC1gU3BlZWRgLg0KDQpFc3RvIHN1bWEgMyBwYXLDoW1ldHJvcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFN1bWEgVG90YWwgZGUgUGFyw6FtZXRyb3MNCg0KU3VtYW5kbyB0b2RvcyBsb3MgdmFsb3JlcyBhbnRlcmlvcmVzLCB0ZW5lbW9zICh2w6lhc2UgbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW42KSk6DQogIA0KICAxLiBDYXJnYXMgZmFjdG9yaWFsZXM6IDkNCiAgDQogIDIuIEludGVyY2VwdG9zIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlczogOQ0KICANCiAgMy4gVmFyaWFuemFzIGRlIGxvcyBlcnJvcmVzIGRlIG1lZGljacOzbjogOQ0KICANCiAgNC4gTWVkaWFzIGRlIGxvcyBmYWN0b3JlczogMw0KICANCiAgNS4gVmFyaWFuemFzIGRlIGxvcyBmYWN0b3JlczogMw0KICANCiAgNi4gQ292YXJpYW56YXMgZW50cmUgZmFjdG9yZXM6IDMNCiAgDQoNCiQkOSBcOytcOyA5XDsgK1w7IDlcOyArIFw7M1w7ICsgXDszIFw7KyBcOzMgXDs9XDsgMzYkJA0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjYpIHNlIHZpc3VhbGl6YSBsbyBhbnRlcmlvci4NCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuNiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlRvdGFsIGRlIHBhcsOhbWV0cm9zIGVuIGVsIG1vZGVsbyBDRkEgbm8gZXN0w6FuZGFyKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW42LnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb25zaWRlcmFjacOzbiBkZSBwYXLDoW1ldHJvcyBjb25vY2lkb3MNCg0KMS4gRW4gbXVjaG9zIGNhc29zLCB1bm8gZGUgbG9zIGluZGljYWRvcmVzIHBhcmEgY2FkYSBmYWN0b3Igc2UgZmlqYSBhIDEgcGFyYSBxdWUgZWwgbW9kZWxvIHNlYSBpZGVudGlmaWNhYmxlOg0KJCRcbGFtYmRhXzFcOz1cOyAgXGxhbWJkYV80XDs9XDsgIFxsYW1iZGFfN1w7PVw7ICAxJCQNCg0KDQoyLiBFc3RvIHNpZ25pZmljYSBxdWUgcGFyYSBjYWRhIGZhY3RvciwgdW5hIGRlIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgbm8gc2UgZXN0aW1hICh5YSBxdWUgc2UgZmlqYSkuIERhZG8gcXVlIGhheSAzIGZhY3RvcmVzLCBlc3RvIHJlc3RhIDMgcGFyw6FtZXRyb3MgZGVsIHRvdGFsDQoNCg0KMy4gUG9yIGRlZmVjdG8sIGVsIHBhcXVldGUgYGxhdmFhbmAgZXN0aW1hIHVuICptb2RlbG8gZW4gRXNjYWxhIEVzdMOhbmRhciouIFBvciBlc3RhIHJhesOzbjogDQogIA0KICArIExhcyBtZWRpYXMgZGUgbG9zIHRyZXMgZmFjdG9yZXMgbGF0ZW50ZXMgc2UgZmlqYW4gYSBjZXJvIChvIHNlYSwgZGViZSByZXN0YXJzZSAzIHBhcsOhbWV0cm9zIGRlbCB0b3RhbCk6DQogIA0KJCRcYWxwaGFfMSBcOz1cOyAgXGFscGhhXzIgXDs9XDsgIFxhbHBoYV8zIFw7PVw7ICAwJCQNCiAgDQogICsgTGFzIG1lZGlhcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgc2UgZXhwbGljYW4gw7puaWNhbWVudGUgZW4gdMOpcm1pbm9zIGRlIHN1cyBpbnRlcmNlcHRvcyB5IG5vIHNlIHJlcXVpZXJlbiBlc3RpbWFjaW9uZXMgYWRpY2lvbmFsZXMgZGUgbG9zIGludGVyY2VwdG9zIChvIHNlYSwgdGFtYmnDqW4gZGViZSByZXN0YXJzZSA5IHBhcsOhbWV0cm9zIGRlbCB0b3RhbCk6DQogIA0KIA0KJCRcdGF1XzEgXDs9XDsgIFx0YXVfMiBcOz1cOyAgXHRhdV8zIFw7PVw7ICBcdGF1XzQgXDs9XDsgIFx0YXVfNSBcOz1cOyAgXHRhdV82IFw7PVw7ICBcdGF1XzcgXDs9XDsgIFx0YXVfOCBcOz1cOyAgXHRhdV85IFw7PVw7ICAwJCQgDQoNCjQuIEVudG9uY2VzLCByZXN0YW5kbyBlc3RvcyAxNSBwYXLDoW1ldHJvcyBmaWpvcywgdGVuZW1vczoNCg0KJCQzNlw74oiSXDsxNVw7ID1cOyAyMSQkDQoNCjUuIEVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuNykgc2UgdmlzdWFsaXphIGxvIGFudGVyaW9yLg0KDQoNCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW43LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqVG90YWwgZGUgcGFyw6FtZXRyb3Mgc2Vnw7puIGBsYXZhYW5gIChlbGltaW5hbmRvIHBhcsOhbWV0cm9zIGZpam9zKSoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuNy5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb25jbHVzacOzbjogdG90YWwgZGVmaW5pdGl2byBkZSBwYXLDoW1ldHJvcw0KDQoxLiBMb3MgMjEgcGFyw6FtZXRyb3MgZW4gZWwgb3V0cHV0IGRlbCBtb2RlbG8gc2UgZGlzdHJpYnV5ZW4gZGUgbGEgc2lndWllbnRlIG1hbmVyYToNCiAgDQogICsgNiBjYXJnYXMgZmFjdG9yaWFsZXMgZXN0aW1hZGFzICgzIGZhY3RvcmVzIHggMyBpbmRpY2Fkb3JlcywgIG1lbm9zIDMgZmlqYXMpLg0KICANCiAgKyAwIGludGVyY2VwdG9zLg0KICANCiAgKyA5IHZhcmlhbnphcyBkZSBsb3MgZXJyb3JlcyBkZSBtZWRpY2nDs24uDQogIA0KICArIDAgbWVkaWFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcy4gDQogIA0KICArIDMgdmFyaWFuemFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcy4NCiAgDQogICsgMyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgbGF0ZW50ZXMuDQogIA0KDQoyLiBFc3RvIGRhIHVuIHRvdGFsIGRlIDIxIHBhcsOhbWV0cm9zIGVzdGltYWRvcyBlbiBlbCBtb2RlbG8gQ0ZBIHV0aWxpemFuZG8gbG9zIGRhdG9zIGBIb2x6aW5nZXJTd2luZWZvcmQxOTM5YCB5IGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8uDQoNCg0KMy4gRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW44KSBzZSB2aXN1YWxpemEgbG8gYW50ZXJpb3IuDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQp7XGNvbG9ye1RlYWx9IFxsYW1iZGFfMiwgXGxhbWJkYV8zLCBcbGFtYmRhXzUsIFxsYW1iZGFfNiwgXGxhbWJkYV84LFxsYW1iZGFfOX1cXA0KXFwNCntcY29sb3J7VGVhbH0gVihcdmFyZXBzaWxvbl8xKSwgVihcdmFyZXBzaWxvbl8yKSwgVihcdmFyZXBzaWxvbl8zKSwgVihcdmFyZXBzaWxvbl80KSwgVihcdmFyZXBzaWxvbl81KSwgVihcdmFyZXBzaWxvbl82KSwgVihcdmFyZXBzaWxvbl83KSwgVihcdmFyZXBzaWxvbl84KSwgVihcdmFyZXBzaWxvbl85KX0NCmBgYA0KDQoNCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjgsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipOw7ptZXJvIGRlIHBhcsOhbWV0cm9zIHNlZ8O6biBgbGF2YWFuYCoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KDQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW44LnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgY2ZhYDogc2VndW5kYSBwYXJ0ZQ0KDQojIyMgTW9kZWwgVGVzdCBVc2VyIE1vZGVsIGVuIGBsYXZhYW5gDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuOCkgc2UgcmVzYWx0YSBsYSBzZWd1bmRhIHBhcnRlIGRlbCBvdXRwdXQgZGUgYGxhdmFhbmAuICANCiAgDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuOSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlNlZ3VuZGEgcGFydGUgZGVsIG91dHB1dCBkZSBgbGF2YWFuYCAoYGNmYWApKioiLCBvdXQud2lkdGggPSAiNzAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjkucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gIA0KICANCg0KRXN0b3MgcmVzdWx0YWRvcyBjb3JyZXNwb25kZW4gYSB1bmEgcHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0KS4gRW4gZWwgY29udGV4dG8gZGUgbGEgcHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0KSBlbiBgbGF2YWFuYCwgbGFzIGhpcMOzdGVzaXMgbnVsYSB5IGFsdGVybmF0aXZhIHNvbiBsYXMgc2lndWllbnRlczoNCiAgICANCiAgKyAqSGlww7N0ZXNpcyBudWxhIChIMCk6KiBMYSBoaXDDs3Rlc2lzIG51bGEgZW4gZXN0ZSBjYXNvIHNlcsOtYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGVuIGxhIG11ZXN0cmEuIEVzdG8gc2lnbmlmaWNhIHF1ZSBubyBoYXkgZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW50cmUgbG9zIGRhdG9zIG9ic2VydmFkb3MgeSBsb3MgZGF0b3MgZXNwZXJhZG9zIHNlZ8O6biBlbCBtb2RlbG8uIA0KICAgIA0KICArICpIaXDDs3Rlc2lzIGFsdGVybmF0aXZhIChIMSk6KiBMYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhIHNlcsOtYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBubyBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGVuIGxhIG11ZXN0cmEuIEVzdG8gaW1wbGljYSBxdWUgaGF5IGRpZmVyZW5jaWFzIHNpZ25pZmljYXRpdmFzIGVudHJlIGxvcyBkYXRvcyBvYnNlcnZhZG9zIHkgbG9zIGRhdG9zIGVzcGVyYWRvcyBzZWfDum4gZWwgbW9kZWxvLCBsbyBxdWUgc2UgdHJhZHVjZSBlbiB1biBtYWwgYWp1c3RlIGRlbCBtb2RlbG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbnRlcHJldGFjacOzbjogc2VndW5kYSBwYXJ0ZQ0KDQpBcXXDrSBlc3TDoSBlbCBzaWduaWZpY2FkbyBkZSBjYWRhIHVubyBkZSBsb3MgZWxlbWVudG9zIGRlIGxhIHNhbGlkYToNCg0KICoqMS4gVGVzdCBzdGF0aXN0aWMgKEVzdGFkw61zdGljbyBkZSBwcnVlYmEpLioqIA0KDQpFcyBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvIGRlIHBydWViYSAocXVlIHRpZW5lIGRpc3RyaWJ1Y2nDs24gY2hpLWN1YWRyYWRhKSB5ICBjYWxjdWxhZG8gcGFyYSBldmFsdWFyIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLiBVbiB2YWxvciBhbHRvIGdlbmVyYWxtZW50ZSBpbmRpY2EgdW4gbWFsIGFqdXN0ZSBkZWwgbW9kZWxvIGEgbG9zIGRhdG9zIG9ic2VydmFkb3MuIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgZXMgODUuMzA2Lg0KDQoqKjIuRGVncmVlcyBvZiBmcmVlZG9tIChHcmFkb3MgZGUgbGliZXJ0YWQpLioqDQoNClJlcHJlc2VudGEgZWwgbsO6bWVybyBkZSB2YWxvcmVzIHF1ZSBzb24gbGlicmVzIGRlIHZhcmlhciB1bmEgdmV6IHF1ZSBjaWVydGFzIHJlc3RyaWNjaW9uZXMgc29uIGltcHVlc3Rhcy4gRW4gQ0ZBLCBsb3MgZ3JhZG9zIGRlIGxpYmVydGFkIHNlIGNhbGN1bGFuIGNvbW8gbGEgZGlmZXJlbmNpYSBlbnRyZSBlbCBuw7ptZXJvIGRlIG9ic2VydmFjaW9uZXMgaW5kZXBlbmRpZW50ZXMgKGdlbmVyYWxtZW50ZSBlbCBuw7ptZXJvIGRlIGVudHJhZGFzIGVuIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphKSB5IGVsIG7Dum1lcm8gZGUgcGFyw6FtZXRyb3MgZXN0aW1hZG9zLiBFbiBlc3RlIGNhc28sIGhheSAyNCBncmFkb3MgZGUgbGliZXJ0YWQuDQoNCg0KKiozLiBQLXZhbHVlIChDaGktc3F1YXJlKSAoVmFsb3IgcCBvYnRlbmlkbyBjb24gbGEgY2hpLWN1YWRyYWRhKS4qKiANCg0KRXMgbGEgcHJvYmFiaWxpZGFkIGRlIG9idGVuZXIgdW4gdmFsb3IgZGVsIGVzdGFkw61zdGljbyBkZSBwcnVlYmEgaWd1YWwgbyBtw6FzIGV4dHJlbW8gcXVlIGVsIHZhbG9yIG9ic2VydmFkbywgYXN1bWllbmRvIHF1ZSBsYSBoaXDDs3Rlc2lzIG51bGEgZXMgdmVyZGFkZXJhLiBFbiBlbCBjb250ZXh0byBkZSBsYXZhYW4sIHVuIHZhbG9yICRwJCBiYWpvICgkPCAwLjA1JCkgZ2VuZXJhbG1lbnRlIGluZGljYSB1biBtYWwgYWp1c3RlIGRlbCBtb2RlbG8sIGxvIHF1ZSBzaWduaWZpY2EgcXVlIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGRpZmllcmVuIHNpZ25pZmljYXRpdmFtZW50ZSBkZSBsb3MgZGF0b3MgZXNwZXJhZG9zIHNlZ8O6biBlbCBtb2RlbG8uIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgcCBlcyAwLjAwMCwgbG8gcXVlIGluZGljYSBxdWUgZWwgbW9kZWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zLCB5YSBxdWUgbGEgcHJvYmFiaWxpZGFkIGRlIG9idGVuZXIgdW4gdmFsb3IgZGUgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBpZ3VhbCBvIG3DoXMgZXh0cmVtbyBlcyBtdXkgYmFqYS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRnVuY2nDs24gYHN1bW1hcnlgIGRlIGBsYXZhYW5gDQoNCiMjIyBgc3VtbWFyeWA6IGRlc2NyaXBjacOzbg0KDQoxLiBVbmEgdmV6IHF1ZSBlbCBtb2RlbG8gaGEgc2lkbyBhanVzdGFkbywgbGEgZnVuY2nDs24gYHN1bW1hcnlgIHByb3BvcmNpb25hIHVuIGJ1ZW4gcmVzdW1lbiBkZWwgbW9kZWxvIGFqdXN0YWRvLiANCg0KMi4gRWwgYXJndW1lbnRvIGBmaXQubWVhc3VyZXM9VFJVRWAgZW4gbGEgZnVuY2nDs24gYHN1bW1hcnlgICBpbmRpY2EgcXVlIHNlIGRlc2VhbiBpbmNsdWlyIG1lZGlkYXMgZGUgYWp1c3RlIGRlbCBtb2RlbG8gZW4gZWwgcmVzdW1lbiBkZWwgbW9kZWxvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHN1bW1hcnlgOiBlamVjdWNpw7NuIHkgb3V0cHV0DQoNClNlIGVqZWN1dGEgYXPDrTogDQoNCmBgYHtyfQ0Kc3VtbWFyeShDRkEsIGZpdC5tZWFzdXJlcz1UUlVFKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBzdW1tYXJ5YDogcGFydGVzIDEgeSAyIA0KDQojIyMgSW5mb3JtYWNpw7NuIGdlbmVyYWwgZGVsIG1vZGVsbyANCg0KMS4gRWwgbW9kZWxvIGZpbmFsaXrDsyBub3JtYWxtZW50ZSBkZXNwdcOpcyBkZSAzNSBpdGVyYWNpb25lcy4NCg0KMi4gRWwgZXN0aW1hZG9yIHV0aWxpemFkbyBmdWUgZWwgbcOheGltbyB2ZXJvc2ltaWxpdHVkIChgTUxgKS4NCg0KMy4gRWwgbcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIGZ1ZSBgTkxNSU5CYC4NCg0KNC4gRWwgbW9kZWxvIHRpZW5lIDIxIHBhcsOhbWV0cm9zLg0KDQo1LiBTZSB1dGlsaXphcm9uIDMwMSBvYnNlcnZhY2lvbmVzIGVuIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLg0KDQo2LiBFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjEwKSBzZSBwdWVkZSB2aXN1YWxpemFyIGxhIHBhcnRlIE5vLiAxIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGVzIGxhIG1pc21hIHF1ZSBhcGFyZWNlIGVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuNSkpLiAgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgUHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0IFVzZXIgTW9kZWwpDQoNCjEuIEVsIGVzdGFkw61zdGljbyBkZSBwcnVlYmEgZXMgODUuMzA2Lg0KDQoyLiBFbCBtb2RlbG8gdGllbmUgMjQgZ3JhZG9zIGRlIGxpYmVydGFkLg0KDQozLiBFbCB2YWxvciBwIGFzb2NpYWRvIGFsIENoaS1jdWFkcmFkbyBlcyAwLjAwMCwgbG8gcXVlIGluZGljYSBxdWUgZWwgbW9kZWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zICh2YWxvciBwIHNpZ25pZmljYXRpdmFtZW50ZSBtZW5vciBxdWUgMC4wNSkuDQoNCjQuIEVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTApIHNlIHB1ZWRlIHZpc3VhbGl6YXIgbGEgcGFydGUgTm8uIDIgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoZXMgbGEgbWlzbWEgcXVlIGFwYXJlY2UgZW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW45KSkuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgc3VtbWFyeWA6IHRlc3QgbW9kZWxvIG51bG8gIA0KDQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IE1vZGVsbyBudWxvIChCYXNlbGluZSBNb2RlbCkNCg0KMS4gRWwgKk1vZGVsbyBCYXNlbGluZSogKG8gKm1vZGVsbyBudWxvKikgZXMgdW4gbW9kZWxvIG11eSByZXN0cmluZ2lkbyBxdWUgYXN1bWUgcXVlIHRvZGFzIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzb24gaW5kZXBlbmRpZW50ZXMgZW50cmUgc8OtLiANCg0KMi4gRXMgZGVjaXIsIG5vIGhheSBjb3JyZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMuIA0KDQozLiBFbiBlc3RlIG1vZGVsbywgdG9kYXMgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzZSBlc3RhYmxlY2VuIGEgY2Vyby4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IG1vZGVsbyBudWxvIGVuIFINCg0KUGFyYSBlbGxvIHNlIGVqZWN1dGEgZWwgc2lndWllbnRlIGPDs2RpZ286IA0KDQpgYGB7cn0NCm1vZGVsX251bGwgPC0gJw0KICB4MSB+fiB4MQ0KICB4MiB+fiB4Mg0KICB4MyB+fiB4Mw0KICB4NCB+fiB4NA0KICB4NSB+fiB4NQ0KICB4NiB+fiB4Ng0KICB4NyB+fiB4Nw0KICB4OCB+fiB4OA0KICB4OSB+fiB4OQ0KJw0KDQojIEFqdXN0YXIgZWwgbW9kZWxvIG51bG8NCmZpdF9udWxsIDwtIGNmYShtb2RlbF9udWxsLCBkYXRhID0gZGF0KQ0KZml0X251bGwNCmBgYA0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBUZXN0IEJhc2VsaW5lIE1vZGVsYDogZ3LDoWZpY2FyIG1vZGVsbyBudWxvIGVuIFINCg0KUGFyYSBlbGxvLCBzZSBwdWVkZSBlamVjdXRhciBlbCBzaWd1aWVudGUgY8OzZGlnbzogDQoNCmBgYHtyfQ0Kc2VtUGF0aHMoZml0X251bGwsIA0KICAgICAgICAgd2hhdCA9ICJwYXRoIiwgICAgI011ZXN0cmEgbGFzIHJ1dGFzIGNvbiBjYXJnYXMsIHJlZ3Jlc2lvbmVzLCBjb3ZhcmlhbnphcyAgICAgDQogICAgICAgICAjd2hhdCA9ICJzdGQiLCAgICAjTXVlc3RyYSBsYXMgZXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzIGRlIGxhcyBydXRhcyANCiAgICAgICAgICN3aGF0ID0gImNvbCIsICAgICNNdWVzdHJhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZGUgdmFyLiBvYnNlcnZhZGFzDQogICAgICAgICAjd2hhdCA9ICJtb2QiLCAgICAjTXVlc3RyYSBjYW1pbm8gYWRpY2lvbmFsIHF1ZSBwb2Ryw61hIG1lam9yYXIgYWp1c3RlIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gIm1vZGVsIiwgICNNdWVzdHJhIHVuYSByZXByZXNlbnRhY2nDs24gZ3JhbCBkZWwgbW9kZWxvDQogICAgICAgICAjd2hhdCA9ICJhbGwiLCAgICAjTXVlc3RyYSB0b2RvcyBlbGVtZW50b3MgcG9zaWJsZXMgKHJ1dGFzIHkgZXN0aW1hY2lvbmVzKQ0KICAgICAgICAgI3doYXQgPSAicGFyIiwgICAgI011ZXN0cmEgdG9kb3MgbG9zIHBhcsOhbWV0cm9zIGVzdGltYWRvcyBkZWwgbW9kZWxvDQogICAgICAgICAjd2hhdCA9ICJlcSIsICAgICAjTXVlc3RyYSBsYXMgZWN1YWNpb25lcyBlc3RydWN0dXJhbGVzIGRlbCBtb2RlbG8gDQogICAgICAgICANCiAgICAgICAgIGxheW91dCA9ICJ0cmVlIiwgICAgI0Rpc3BvbmUgbm9kb3MgZW4gY8OtcmN1bG8gKHNvbG8gcGVybWl0aWRvIHNpIHJvdGF0aW9uPSAxIG8gMykNCiAgICAgICAgIA0KICAgICAgICAgdGl0bGUgPSBGQUxTRSwgICAgICAgICNObyBtdWVzdHJhIGVsIHTDrXR1bG8gZGVsIGdyw6FmaWNvDQogICAgICAgICANCiAgICAgICAgIGVkZ2UuY29sb3IgPSAiUmVkIiwgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBsb3MgYm9yZGVzIChhcmlzdGFzKSBlbiBuZWdybw0KICAgICAgICAgc2l6ZU1hbiA9IDgsICAgICNUYW1hw7FvIGRlIGxvcyBub2RvcyBxdWUgcmVwcmVzZW50YW4gdmFyaWFibGVzIG1hbmlmaWVzdGFzDQogICAgICAgICBjb2xvciA9IGxpc3QobWFuID0gImxpZ2h0Z3JlZW4iICNDb2xvciBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMNCiAgICAgICAgICAgICAgICAgICAgICkgDQogICAgICAgICApDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFRlc3QgQmFzZWxpbmUgTW9kZWxgOiBncsOhZmljbyBkZSBwYXJ0ZSBOby4gMw0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjEwKSBzZSByZXNhbHRhIGxhIHBhcnRlIE5vLiAzIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xMCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiAzIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBUZXN0IEJhc2VsaW5lIE1vZGVsYCkqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjEwLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+ICANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IGhpcMOzdGVzaXMNCg0KKioxLiBMYSBoaXDDs3Rlc2lzIG51bGEgKCRIXzAkKSBwYXJhIGVsIGBNb2RlbCBUZXN0IEJhc2VsaW5lIE1vZGVsYCoqDQoNClZpZW5lIGRhZGEgcG9yOg0KDQokJEgwOiBcO1x0ZXh0e0VsIG1vZGVsbyBudWxvIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zfSQkDQogIA0KRXN0byBpbXBsaWNhIHF1ZSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIG5vIHNvbiBzaWduaWZpY2F0aXZhbWVudGUgZGlmZXJlbnRlcyBkZSBjZXJvLCBlcyBkZWNpciwgcXVlIHRvZGFzIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzb24gaW5kZXBlbmRpZW50ZXMgZW50cmUgc8OtLg0KDQoqKjIuIExhIGhpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgKCRIXzEkKSoqIA0KDQpWaWVuZSBkYWQgcG9yOg0KDQokJEhfMTogXDtcdGV4dHtFbCBtb2RlbG8gbnVsbyBubyBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvc30kJA0KRXN0byBpbXBsaWNhIHF1ZSBoYXkgcmVsYWNpb25lcyBzaWduaWZpY2F0aXZhcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMsIGVzIGRlY2lyLCBxdWUgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzb24gZGlmZXJlbnRlcyBkZSBjZXJvLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBUZXN0IEJhc2VsaW5lIE1vZGVsYDogaW50ZXJwcmV0YWNpb25lcyANCg0KKioxLiBFc3RhZMOtc3RpY28gZGUgQ2hpLUN1YWRyYWRvICgkXGNoaV4yJCkuICoqDQoNCk1pZGUgbGEgZGlzY3JlcGFuY2lhIGVudHJlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIG9ic2VydmFkYSB5IGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIGVzdGltYWRhIGJham8gZWwgbW9kZWxvIG51bG8uIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgZGVsIGVzdGFkw61zdGljbyBlcyBkZSA5MTguODUyLg0KDQoNCioqMi4gR3JhZG9zIGRlIExpYmVydGFkIChkZikuKioNCg0KTGEgZGlzdHJpYnVjacOzbiBzZSBhanN1dGEgY29uIDM2IGdyYWRvcyBkZSBsaWJlcnRhZC4NCg0KDQoqKjMuIFZhbG9yIFAuKioNCg0KSW5kaWNhIHNpIGxhIGRpc2NyZXBhbmNpYSBvYnNlcnZhZGEgKGVzdGFkw61zdGljbyAkXGNoaV4yJCkgZXMgc2lnbmlmaWNhdGl2YS4gRGFkbyBxdWUgZWwgdmFsb3IgJHAkIGVzIG1lbm9yIHF1ZSAwLjA1LCBzZSByZWNoYXphIGxhIGhpcMOzdGVzaXMgbnVsYSAoJEhfMCQpLCBpbmRpY2FuZG8gcXVlIGVsIG1vZGVsbyBudWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zIHkgcXVlIGV4aXN0ZW4gcmVsYWNpb25lcyBzaWduaWZpY2F0aXZhcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgc3VtbWFyeWA6IHVzZXIgdnMgYmFzZWxpbmUNCg0KIyMjIGBVc2VyIHZzIEJhc2VsaW5lYDogb3V0cHV0IGRlIGBzdW1tYXJ5YA0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjExKSBzZSByZXNhbHRhIGxhIHBhcnRlIE5vLiA0IGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xMSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiA0IGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBVc2VyIHZzIEJhc2VsaW5lYCkqKiIsIG91dC53aWR0aCA9ICI4MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTEucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFVzZXIgdnMgQmFzZWxpbmVgOiBkZXNjcmlwY2nDs24NCg0KMS4gRWwgYFVzZXIgTW9kZWxgIHNlIHJlZmllcmUgYWwgbW9kZWxvIHF1ZSBlbCB1c3VhcmlvIGhhIGVzcGVjaWZpY2FkbyB5IHF1ZSBgbGF2YWFuYCBlc3TDoSBhbmFsaXphbmRvLg0KDQoyLiBFbCBvdXRwdXQgYFVzZXIgTW9kZWwgdmVyc3VzIEJhc2VsaW5lIE1vZGVsYCBzZSByZWZpZXJlIGEgbGEgY29tcGFyYWNpw7NuIGVudHJlIGVsICptb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvKiAoYFVzZXIgTW9kZWxgKSB5IGVsICptb2RlbG8gZGUgcmVmZXJlbmNpYSosIHRhbWJpw6luIGNvbm9jaWRvIGNvbW8gKm1vZGVsbyBiYXNlbGluZSBvIG51bG8qIChgQmFzZWxpbmUgTW9kZWxgKS4gDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBVc2VyIHZzIEJhc2VsaW5lYDogaGlww7N0ZXNpcw0KDQoqKjEuIEhpcMOzdGVzaXMgTnVsYSAoJEhfMCQpLioqDQogIA0KICArIExhIGhpcMOzdGVzaXMgbnVsYSAoJEhfMCQpIGVzIHF1ZSBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIG5vIHNlIGFqdXN0YSBzaWduaWZpY2F0aXZhbWVudGUgbWVqb3IgcXVlIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhLiANCiAgDQogICsgRXMgZGVjaXIsIG5vIGhheSBkaWZlcmVuY2lhIHNpZ25pZmljYXRpdmEgZW50cmUgZWwgYWp1c3RlIGRlbCBtb2RlbG8gZGVsIHVzdWFyaW8geSBlbCBtb2RlbG8gbnVsby4gDQogIA0KICArIE1hdGVtw6F0aWNhbWVudGUsIGVzdG8gc2UgcG9kcsOtYSBleHByZXNhciBjb21vOg0KICANCiQkSF8wOiBcdGV4dHtFbCBVc2VyIE1vZGVsIHNlIGFqdXN0YSBzaWduaWZpY2F0aXZhbWVudGUgbWVqb3IgcXVlIGVsIEJhc2VsaW5lIE1vZGVsfSQkDQoNCioqMi4gSGlww7N0ZXNpcyBBbHRlcm5hdGl2YSAoJEhfMSQpLioqDQogIA0KICArIExhIGhpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgKCRIXzEkKSBlcyBxdWUgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpbyBzZSBhanVzdGEgc2lnbmlmaWNhdGl2YW1lbnRlIG1lam9yIHF1ZSBlbCBtb2RlbG8gZGUgcmVmZXJlbmNpYS4gDQogIA0KICArIEVzIGRlY2lyLCBoYXkgdW5hIGRpZmVyZW5jaWEgc2lnbmlmaWNhdGl2YSBlbnRyZSBlbCBhanVzdGUgZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyB5IGVsIG1vZGVsbyBudWxvLiANCiAgDQogICsgTWF0ZW3DoXRpY2FtZW50ZSwgZXN0byBzZSBwb2Ryw61hIGV4cHJlc2FyIGNvbW86DQoNCiQkSF8xOiBcdGV4dHtFbCBVc2VyIE1vZGVsIHNlIGFqdXN0YSBzaWduaWZpY2F0aXZhbWVudGUgbWVqb3IgcXVlIGVsIEJhc2VsaW5lIE1vZGVsfSQkDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFVzZXIgdnMgQmFzZWxpbmVgOiBDRkkgeSBUTEkgKGdlbmVyYWxpZGFkZXMpDQoNCjEuIEVzdGEgY29tcGFyYWNpw7NuIHBlcm1pdGUgZXZhbHVhciBxdcOpIHRhbiBiaWVuIHNlIGFqdXN0YSBlbCBtb2RlbG8gcHJvcHVlc3RvIHBvciBlbCB1c3VhcmlvIGVuIGNvbXBhcmFjacOzbiBjb24gdW4gbW9kZWxvIG11eSBzaW1wbGUgcXVlIGFzdW1lIGluZGVwZW5kZW5jaWEgY29tcGxldGEgZW50cmUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzLg0KDQoyLiBMYSBjb21wYXJhY2nDs24gZW50cmUgZWwgYFVzZXIgTW9kZWxgIHkgZWwgYEJhc2VsaW5lIE1vZGVsYCBwcm9wb3JjaW9uYSBpbmZvcm1hY2nDs24gdmFsaW9zYSBzb2JyZSBsYSBhZGVjdWFjacOzbiBkZWwgbW9kZWxvIHByb3B1ZXN0byBwb3IgZWwgdXN1YXJpbyBlbiByZWxhY2nDs24gY29uIHVuIG1vZGVsbyBleHRyZW1hZGFtZW50ZSBzaW1wbGUuIA0KDQozLiBFc3RvIHNlIHJlYWxpemEgdXRpbGl6YW5kbyBkaXZlcnNvcyBjcml0ZXJpb3MgZGUgYWp1c3RlLCBjb21vIGVsIENoaS1jdWFkcmFkbyAoJFxjaGleMiQpLCBlbCBDb21wYXJhdGl2ZSBGaXQgSW5kZXggKGBDRklgKSwgZWwgVHVja2VyLUxld2lzIEluZGV4IChgVExJYCksIGVudHJlIG90cm9zLg0KDQo0LiBTaSBlbCBtb2RlbG8gcHJvcHVlc3RvIHBvciBlbCB1c3VhcmlvIHNlIGFqdXN0YSBzaWduaWZpY2F0aXZhbWVudGUgbWVqb3IgcXVlIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhIChwb3IgZWplbXBsbywgdW4gQ2hpLWN1YWRyYWRvIHNpZ25pZmljYXRpdmFtZW50ZSBtw6FzIGJham8geS9vIHZhbG9yZXMgbcOhcyBhbHRvcyBkZSBgQ0ZJYCB5IGBUTElgKSwgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gcHJvcHVlc3RvIHByb3BvcmNpb25hIHVuIG1lam9yIGFqdXN0ZSBhIGxvcyBkYXRvcyBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhLiANCg0KNS4gRXN0byBzdWdpZXJlIHF1ZSBsYSBlc3RydWN0dXJhIHByb3B1ZXN0YSBlbiBlbCBtb2RlbG8gZGVsIHVzdWFyaW8gZXMgdsOhbGlkYSB5IHJlcHJlc2VudGEgbGEgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMgZGUgbWFuZXJhIG3DoXMgcHJlY2lzYSBxdWUgZWwgbW9kZWxvIG51bG8uDQoNCjYuIFBvciBvdHJvIGxhZG8sIHNpIGVsIG1vZGVsbyBwcm9wdWVzdG8gcG9yIGVsIHVzdWFyaW8gbm8gc2UgYWp1c3RhIHNpZ25pZmljYXRpdmFtZW50ZSBtZWpvciBxdWUgZWwgbW9kZWxvIGRlIHJlZmVyZW5jaWEsIHBvZHLDrWEgaW5kaWNhciBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBubyBwcm9wb3JjaW9uYSB1biBtZWpvciBhanVzdGUgYSBsb3MgZGF0b3MgZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gbnVsbywgbG8gcXVlIHN1Z2llcmUgcXVlIGxhIGVzdHJ1Y3R1cmEgcHJvcHVlc3RhIHB1ZWRlIG5vIHNlciBhZGVjdWFkYSBvIHF1ZSBzZSBuZWNlc2l0YW4gYWp1c3RlcyBhZGljaW9uYWxlcyBwYXJhIG1lam9yYXIgbGEgYWRlY3VhY2nDs24gZGVsIG1vZGVsby4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBVc2VyIHZzIEJhc2VsaW5lYDogQ0ZJIHkgVExJIChpbnRlcnByZXRhY2lvbmVzKQ0KDQoqKjEuIEdlbmVyYWxpZGFkLioqDQoNCkVsIENvbXBhcmF0aXZlIEZpdCBJbmRleCAoQ0ZJKSB5IGVsIFR1Y2tlci1MZXdpcyBJbmRleCAoVExJKSBzb24gZG9zIMOtbmRpY2VzIGRlIGFqdXN0ZSBjb23Dum5tZW50ZSB1dGlsaXphZG9zIGVuIGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbyAoQ0ZBKSBwYXJhIGV2YWx1YXIgcXXDqSB0YW4gYmllbiBzZSBhanVzdGEgdW4gbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpbyBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGVuIGNvbXBhcmFjacOzbiBjb24gdW4gbW9kZWxvIGRlIHJlZmVyZW5jaWEsIGNvbW8gZWwgbW9kZWxvIG51bG8gbyBiYXNlbGluZS4gQkFzYWRvIGVuIGxvcyByZXN1bHRhZG9zIGVuY29udHJhZG9zIChwYXJ0ZSBOby4gNCBkZWwgb3V0cHV0KSwgZXN0b3MgdmFsb3JlcyBzZSBwdWRlbiBpbnRlcnByZXRhciBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOg0KDQoqKjIuIENvbXBhcmF0aXZlIEZpdCBJbmRleCAoYENGSWApLioqDQogIA0KICArIEVsIENGSSBlcyB1biDDrW5kaWNlIHF1ZSBldmFsw7phIHF1w6kgdGFuIGJpZW4gc2UgYWp1c3RhIGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8gcG9yIGVsIHVzdWFyaW8gZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gbnVsby4gDQogIA0KICArIFVuIENGSSBjZXJjYW5vIGEgMSBpbmRpY2EgdW4gYnVlbiBhanVzdGUgZGVsIG1vZGVsbywgZG9uZGUgdW4gdmFsb3IgZGUgMSBpbmRpY2EgdW4gYWp1c3RlIHBlcmZlY3RvLg0KICANCiAgKyBFbiBnZW5lcmFsLCB1biB2YWxvciBkZSBDRkkgbWF5b3IgYSAwLjkwIHNlIGNvbnNpZGVyYSBhY2VwdGFibGUsIGF1bnF1ZSB2YWxvcmVzIG3DoXMgY2VyY2Fub3MgYSAwLjk1IG8gbWF5b3JlcyBpbmRpY2FuIHVuIG1lam9yIGFqdXN0ZS4NCiAgDQogICsgKkludGVycHJldGFjacOzbjoqIFVuIENGSSBkZSAwLjkzMSBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIGV4cGxpY2EgYXByb3hpbWFkYW1lbnRlIGVsIDkzLjElIGRlIGxhIHZhcmlhbnphIHkgbGEgY292YXJpYW56YSBvYnNlcnZhZGEgZW4gbG9zIGRhdG9zLCBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBudWxvLiANCiAgDQoNCioqMy4gVHVja2VyLUxld2lzIEluZGV4IChgVExJYCkuKioNCiAgDQogICsgRWwgVExJLCB0YW1iacOpbiBjb25vY2lkbyBjb21vIE5vbi1Ob3JtZWQgRml0IEluZGV4IChOTkZJKSwgZXMgb3RybyDDrW5kaWNlIGRlIGFqdXN0ZSBxdWUgZXZhbMO6YSBxdcOpIHRhbiBiaWVuIHNlIGFqdXN0YSBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgbW9kZWxvIG51bG8uIA0KICANCiAgKyBBbCBpZ3VhbCBxdWUgY29uIGVsIENGSSwgdW4gdmFsb3IgZGUgVExJIG1heW9yIGEgMC45MCBzZSBjb25zaWRlcmEgYWNlcHRhYmxlLCBhdW5xdWUgdmFsb3JlcyBtw6FzIGNlcmNhbm9zIGEgMC45NSBvIG1heW9yZXMgaW5kaWNhbiB1biBtZWpvciBhanVzdGUuDQogIA0KICArICpJbnRlcnByZXRhY2nDs246KiBVbiBUTEkgZGUgMC44OTYgc3VnaWVyZSBxdWUgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpbyBleHBsaWNhIGFwcm94aW1hZGFtZW50ZSBlbCA4OS42JSBkZSBsYSB2YXJpYW56YSB5IGxhIGNvdmFyaWFuemEgb2JzZXJ2YWRhIGVuIGxvcyBkYXRvcywgZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gbnVsby4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgc3VtbWFyeWA6IGxvZ2xpayBhbmQgY3JpdGVyaW9zDQoNCiMjIyBgTG9nbGlrIGFuZCBDcml0ZXJpYWA6IG91dHB1dCBncsOhZmljbw0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjEyKSBzZSByZXNhbHRhIGxhIHBhcnRlIE5vLiA1IGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xMiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiA1IGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBMb2dsaWtlbGlob29kIGFuZCBJbmZvcm1hdGlvbiBDcml0ZXJpYWApKioiLCBvdXQud2lkdGggPSAiOTAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjEyLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+IA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBMb2dsaWsgYW5kIENyaXRlcmlhYDogbG9nLXZlcm9zaW1pbGl0dWQNCg0KRXN0b3MgcmVzdWx0YWRvcyBwZXJ0ZW5lY2VuIGEgbGEgY29tcGFyYWNpw7NuIGRlbCBtb2RlbG8gZGVsIHVzdWFyaW8gKG1vZGVsbyBlc3BlY2lmaWNhZG8pIGNvbiBlbCBtb2RlbG8gZGUgcmVmZXJlbmNpYSAobW9kZWxvIG51bG8pIGVuIHTDqXJtaW5vcyBkZSBsYSBmdW5jacOzbiBkZSB2ZXJvc2ltaWxpdHVkIGxvZ2Fyw610bWljYS4gQXF1w60gZXN0w6Egc3UgaW50ZXJwcmV0YWNpw7NuOg0KDQoqKjEuIExvZ2xpa2VsaWhvb2QgZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyAoJEhfMCQpLioqDQoNCkVsIHZhbG9yIGRlIGxhIGxvZy12ZXJvc2ltaWxpdHVkIChgbG9nbGlrZWxpaG9vZGApIHBhcmEgZWwgbW9kZWxvIGRlbCB1c3VhcmlvLCBxdWUgZXMgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpby4gRW4gZXN0ZSBjYXNvLCBlbCBsb2dsaWtlbGlob29kIGRlbCBtb2RlbG8gZGVsIHVzdWFyaW8gZXMgLTM3MzcuNzQ1Lg0KDQoqKjIuIExvZ2xpa2VsaWhvb2QgZGVsIG1vZGVsbyBubyByZXN0cmluZ2lkbyAoJEhfMSQpLioqDQoNCkVsIHZhbG9yIGRlIGxhIGxvZy12ZXJvc2ltaWxpdHVkIHBhcmEgZWwgbW9kZWxvIG5vIHJlc3RyaW5naWRvLCBxdWUgZXMgdW4gbW9kZWxvIGRvbmRlIG5vIHNlIGltcG9uZW4gcmVzdHJpY2Npb25lcyAoZXMgZGVjaXIsIHVuIG1vZGVsbyBkb25kZSB0b2RhcyBsYXMgY292YXJpYW56YXMgc29uIGxpYnJlcyBkZSBzZXIgZXN0aW1hZGFzKS4gRW4gZXN0ZSBjYXNvLCBlbCBsb2dsaWtlbGlob29kIGRlbCBtb2RlbG8gbm8gcmVzdHJpbmdpZG8gZXMgLTM2OTUuMDkyLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBMb2dsaWsgYW5kIENyaXRlcmlhYDogY3JpdGVyaW9zIGRlIEluZm9ybWFjacOzbg0KDQpFc3RvcyByZXN1bHRhZG9zIHBlcnRlbmVjZW4gYSBsYSBjb21wYXJhY2nDs24gZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyAobW9kZWxvIGVzcGVjaWZpY2FkbykgY29uIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhIChtb2RlbG8gbnVsbykgZW4gdMOpcm1pbm9zIGRlICB2YXJpb3MgY3JpdGVyaW9zIGRlIGluZm9ybWFjacOzbi4gQXF1w60gZXN0w6Egc3UgaW50ZXJwcmV0YWNpw7NuOg0KDQoqKjEuIENyaXRlcmlvIGRlIEluZm9ybWFjacOzbiBkZSBBa2Fpa2UgKEFJQykuKioNCg0KVW4gY3JpdGVyaW8gZGUgc2VsZWNjacOzbiBkZSBtb2RlbG8gcXVlIHBlbmFsaXphIGVsIHNvYnJlYWp1c3RlIGRlbCBtb2RlbG8gYWwgdGVuZXIgZW4gY3VlbnRhIGVsIG7Dum1lcm8gZGUgcGFyw6FtZXRyb3MgZXN0aW1hZG9zLiBTZSBwcmVmaWVyZSB1biB2YWxvciBkZSBBSUMgbcOhcyBiYWpvLCBsbyBxdWUgaW5kaWNhIHVuIG1lam9yIGVxdWlsaWJyaW8gZW50cmUgZWwgYWp1c3RlIGRlbCBtb2RlbG8geSBsYSBjb21wbGVqaWRhZCBkZWwgbW9kZWxvLiBFbiBlc3RlIGNhc28sIGVsIHZhbG9yIGRlbCBBSUMgZXMgNzUxNy40OTAuDQoNCioqMi4gQ3JpdGVyaW8gZGUgSW5mb3JtYWNpw7NuIEJheWVzaWFuYSAoQklDKS4qKg0KDQpTaW1pbGFyIGFsIEFJQyBwZXJvIGNvbiB1bmEgcGVuYWxpemFjacOzbiBtw6FzIGZ1ZXJ0ZSBwb3IgZWwgbsO6bWVybyBkZSBwYXLDoW1ldHJvcy4gU2UgcHJlZmllcmUgdW4gdmFsb3IgZGUgQklDIG3DoXMgYmFqbywgbG8gcXVlIGluZGljYSB1biBtZWpvciBlcXVpbGlicmlvIGVudHJlIGVsIGFqdXN0ZSBkZWwgbW9kZWxvIHkgbGEgY29tcGxlamlkYWQgZGVsIG1vZGVsby4gRW4gZXN0ZSBjYXNvLCBlbCB2YWxvciBkZWwgQklDIGVzIDc1OTUuMzM5Lg0KDQoqKjMuIENyaXRlcmlvIGRlIEluZm9ybWFjacOzbiBCYXllc2lhbmEgQWp1c3RhZG8gcG9yIGVsIFRhbWHDsW8gZGUgbGEgTXVlc3RyYSAoU0FCSUMpLioqDQoNClVuYSB2YXJpYW50ZSBkZWwgQklDIHF1ZSB0YW1iacOpbiB0aWVuZSBlbiBjdWVudGEgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhLiBTZSBwcmVmaWVyZSB1biB2YWxvciBkZSBTQUJJQyBtw6FzIGJham8sIGxvIHF1ZSBpbmRpY2EgdW4gbWVqb3IgZXF1aWxpYnJpbyBlbnRyZSBlbCBhanVzdGUgZGVsIG1vZGVsbywgbGEgY29tcGxlamlkYWQgZGVsIG1vZGVsbyB5IGVsIHRhbWHDsW8gZGUgbGEgbXVlc3RyYS4gRW4gZXN0ZSBjYXNvLCBlbCB2YWxvciBkZWwgU0FCSUMgZXMgNzUyOC43MzkuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYExvZ2xpayBhbmQgQ3JpdGVyaWFgOiBJbnRlcnByZXRhY2lvbmVzIGdlbmVyYWxlcw0KDQoxLiBFbiBnZW5lcmFsLCBzZSBwcmVmaWVyZSB1biBgbG9nbGlrZWxpaG9vZGAgbcOhcyBhbHRvLCB5YSBxdWUgaW5kaWNhIHVuIG1lam9yIGFqdXN0ZSBkZWwgbW9kZWxvIGEgbG9zIGRhdG9zLg0KDQoyLiBQYXJhIGxvcyBjcml0ZXJpb3MgZGUgaW5mb3JtYWNpw7NuIChgQUlDYCwgYEJJQ2AsIGBTQUJJQ2ApLCBzZSBwcmVmaWVyZW4gdmFsb3JlcyBtw6FzIGJham9zLCBsbyBxdWUgaW5kaWNhIHVuIG1lam9yIGVxdWlsaWJyaW8gZW50cmUgZWwgYWp1c3RlIGRlbCBtb2RlbG8geSBsYSBjb21wbGVqaWRhZCBkZWwgbW9kZWxvLg0KDQozLiBFbiBlc3RlIGNhc28sIGVsIG1vZGVsbyBubyByZXN0cmluZ2lkbyAoJEhfMSQpIHRpZW5lIHVuIGxvZ2xpa2VsaWhvb2QgbcOhcyBhbHRvIHkgdmFsb3JlcyBtw6FzIGJham9zIHBhcmEgbG9zIGNyaXRlcmlvcyBkZSBpbmZvcm1hY2nDs24gZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gZGVsIHVzdWFyaW8gKCRIXzAkKS4gDQoNCjQuIEVzdG8gc3VnaWVyZSBxdWUgZWwgbW9kZWxvIG5vIHJlc3RyaW5naWRvIHByb3BvcmNpb25hIHVuIG1lam9yIGFqdXN0ZSBhIGxvcyBkYXRvcyBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBkZWwgdXN1YXJpby4NCg0KNS4gU2luIGVtYmFyZ28sIGxhIGVsZWNjacOzbiBkZWwgbW9kZWxvIGZpbmFsIGRlYmUgYmFzYXJzZSBlbiB1bmEgZXZhbHVhY2nDs24gY29tcGxldGEgcXVlIGNvbnNpZGVyZSB0YW50byBlbCBhanVzdGUgZGVsIG1vZGVsbyBjb21vIGxhIHRlb3LDrWEgc3VieWFjZW50ZSB5IGxvcyBvYmpldGl2b3MgZGUgaW52ZXN0aWdhY2nDs24uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBzdW1tYXJ5YDogUk1TRUENCg0KIyMjIGBSb290IE1lYW4gU3F1YXJlYDogb3V0cHV0IGdyw6FmaWNvDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTMpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDMgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjEzLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDYgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYFJvb3QgTWVhbiBTcXVhcmVgKSoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTMucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFJvb3QgTWVhbiBTcXVhcmVgOiBnZW5lcmFsaWRhZGVzDQoNClBhcmEgaW50ZXJwcmV0YXIgZWwgUm9vdCBNZWFuIFNxdWFyZSBFcnJvciBvZiBBcHByb3hpbWF0aW9uIChSTVNFQSkgeSBlbCBTdGFuZGFyZGl6ZWQgUm9vdCBNZWFuIFNxdWFyZSBSZXNpZHVhbCAoU1JNUiksIHNlIG5lY2VzaXRhbiBhbGd1bm9zIGRldGFsbGVzIGFkaWNpb25hbGVzIHNvYnJlIGVsIGNvbnRleHRvIGRlbCBhbsOhbGlzaXMgZmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSkgeSBsb3MgY3JpdGVyaW9zIGRlIGFqdXN0ZSB1dGlsaXphZG9zLiBFc3RvcyB2YWxvcmVzIHNlIHV0aWxpemFuIHBhcmEgZXZhbHVhciBlbCBhanVzdGUgZGVsIG1vZGVsbyBwcm9wdWVzdG8gYSBsb3MgZGF0b3Mgb2JzZXJ2YWRvcy4gQXF1w60gZXN0w6EgbGEgaW50ZXJwcmV0YWNpw7NuOg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBSb290IE1lYW4gU3F1YXJlYDogUk1TRUEgKGludGVycHJldGFjacOzbikNCg0KMS4gRWwgYFJNU0VBYCAoKlJhw616IGRlbCBFcnJvciBDdWFkcsOhdGljbyBNZWRpbyBkZSBBcHJveGltYWNpw7NuKikgZXMgdW5hIG1lZGlkYSBkZSBhanVzdGUgZGVsIG1vZGVsbyBxdWUgaW5kaWNhIGN1w6FudG8gc2UgZXNwZXJhIHF1ZSBlbCBtb2RlbG8gc2UgZGVzdsOtZSBkZSBsb3MgZGF0b3MgcG9ibGFjaW9uYWxlcyBlbiB0w6lybWlub3MgZGUgbGEgbWVkaWRhIGRlIGVycm9yIGN1YWRyw6F0aWNvIG1lZGlvLg0KDQoyLiBHZW5lcmFsbWVudGUsIHNlIGNvbnNpZGVyYSBxdWUgdW4gdmFsb3IgZGUgUk1TRUEgbWVub3IgbyBpZ3VhbCBhIDAuMDUgaW5kaWNhIHVuIGJ1ZW4gYWp1c3RlLCB2YWxvcmVzIGVudHJlIDAuMDUgeSAwLjA4IGluZGljYW4gdW4gYWp1c3RlIG1vZGVyYWRvIHkgdmFsb3JlcyBzdXBlcmlvcmVzIGEgMC4xIGluZGljYW4gdW4gYWp1c3RlIGRlZmljaWVudGUuDQoNCjMuIEVuIG51ZXN0cm8gb3V0cHV0LCAkUk1TRUEgPSAwLjA5MiQuDQoNCjQuIEVzdGUgdmFsb3IgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gcHJvcHVlc3RvIHRpZW5lIHVuIGFqdXN0ZSBtb2RlcmFkbyBhIGxvcyBkYXRvcy4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgUm9vdCBNZWFuIFNxdWFyZWA6IFJNU0VBIChgOTAlIElDYCkNCg0KMS4gRWwgaW50ZXJ2YWxvIGRlIENvbmZpYW56YSBkZWwgOTAlIChgOTAgUGVyY2VudCBjb25maWRlbmNlIGludGVydmFsYCkgIFByb3BvcmNpb25hIHVuYSBlc3RpbWFjacOzbiBkZSBsYSBwcmVjaXNpw7NuIGRlbCBSTVNFQS4gDQoNCjIuIExvcyBsw61taXRlcyBpbmZlcmlvciB5IHN1cGVyaW9yIGRlbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGluZGljYW4gZWwgcmFuZ28gcGxhdXNpYmxlIGRlIHZhbG9yZXMgZGUgUk1TRUEuIA0KDQozLiBFbiBlc3RlIGNhc28sIGVsIElDIDkwJSB2YSBkZXNkZSAwLjA3MSBoYXN0YSAwLjExNC4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgUm9vdCBNZWFuIFNxdWFyZWA6IFJNU0VBIChgUC12YWx1ZWApDQoNCioqMS4gUC12YWx1ZSBIMDogUk1TRUEgPD0gMC4wNTAgPSAwLjAwMS4qKg0KICANCiAgKyBFc3RlIHZhbG9yICRwJCBlcyBlbCByZXN1bHRhZG8gZGUgdW5hIHBydWViYSBkZSBoaXDDs3Rlc2lzIHNvYnJlIHNpIGVsIFJNU0VBIGVzIG1lbm9yIG8gaWd1YWwgYSAwLjA1LiANCiAgDQogICsgVW4gdmFsb3IgcCBiYWpvIChwb3IgZGViYWpvIGRlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIGNvbcO6biBkZSAwLjA1KSBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gbm8gc2UgYWp1c3RhIGJpZW4gYSBsb3MgZGF0b3MsIHlhIHF1ZSBlbCBSTVNFQSBlcyBzaWduaWZpY2F0aXZhbWVudGUgbWF5b3IgcXVlIDAuMDUuDQoNCioqMi4gUC12YWx1ZSBIMDogUk1TRUEgPj0gMC4wODAgPSAwLjg0MC4qKg0KICANCiAgKyBFc3RlIHZhbG9yIHAgZXMgZWwgcmVzdWx0YWRvIGRlIHVuYSBwcnVlYmEgZGUgaGlww7N0ZXNpcyBzb2JyZSBzaSBlbCBSTVNFQSBlcyBtYXlvciBvIGlndWFsIGEgMC4wOC4gDQogIA0KICArIFVuIHZhbG9yIHAgYWx0byAocG9yIGVuY2ltYSBkZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBjb23Dum4gZGUgMC4wNSkgc3VnaWVyZSBxdWUgZWwgbW9kZWxvIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zLCB5YSBxdWUgZWwgUk1TRUEgbm8gZXMgc2lnbmlmaWNhdGl2YW1lbnRlIG1heW9yIHF1ZSAwLjA4Lg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFJvb3QgTWVhbiBTcXVhcmVgOiBTUk1SICAoaW50ZXJwcmV0YWNpw7NuKQ0KDQoxLiBFbCBgU1JNUmAgKCpSZXNpZHVhbCBFc3RhbmRhcml6YWRvIGRlbCBFcnJvciBDdWFkcsOhdGljbyBNZWRpbyBkZSBBcHJveGltYWNpw7NuKikgZXMgdW5hIG1lZGlkYSBkZSBhanVzdGUgZGVsIG1vZGVsbyBxdWUgaW5kaWNhIGN1w6FudG8gc2UgZXNwZXJhIHF1ZSBsYSBtYXRyaXogZGUgY292YXJpYW56YSBkZSBsb3MgcmVzaWR1b3MgZXN0YW5kYXJpemFkb3Mgc2UgZGVzdsOtZSBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YSBkZSByZXNpZHVvcyBwb2JsYWNpb25hbGVzLg0KDQoyLiBHZW5lcmFsbWVudGUsIHNlIGNvbnNpZGVyYSBxdWUgdW4gdmFsb3IgZGUgU1JNUiBtZW5vciBvIGlndWFsIGEgMC4wOCBpbmRpY2EgdW4gYnVlbiBhanVzdGUsIG1pZW50cmFzIHF1ZSB2YWxvcmVzIHN1cGVyaW9yZXMgYSAwLjEgaW5kaWNhbiB1biBhanVzdGUgZGVmaWNpZW50ZS4NCg0KMy4gRW4gbnVlc3RybyBvdXRwdXQsICRTUk1SID0gMC4wNjUkLiANCg0KNC4gRXN0ZSB2YWxvciBpbmRpY2EgcXVlIGVsIG1vZGVsbyBwcm9wdWVzdG8gdGllbmUgdW4gYWp1c3RlIG1vZGVyYWRvIGEgbG9zIGRhdG9zLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBSb290IE1lYW4gU3F1YXJlYDogUk1TRUEgeSBTUk1SIChjb25jbHVzaW9uZXMpIA0KDQoxLiBFbiByZXN1bWVuLCBlc3RvcyB2YWxvcmVzIGRlIGFqdXN0ZSAoUk1TRUEgeSBTUk1SKSBzdWdpZXJlbiBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byB0aWVuZSB1biBhanVzdGUgbW9kZXJhZG8gYSBsb3MgZGF0b3MuIA0KDQoyLiBBIHBlc2FyIGRlIGxvIGFudGVyaW9yOg0KICANCiAgKyBFbCBSTVNFQSBzdWdpZXJlIHVuIGFqdXN0ZSBhbGdvIGRlZmljaWVudGUgZGViaWRvIGEgc3UgdmFsb3IgY2VyY2FubyBhIDAuMS4gDQogIA0KICArIFkgZWwgdmFsb3IgJHAkIGFzb2NpYWRvIGNvbiAkUk1TRUEgXGxlcSAwLjA1MCQgdGFtYmnDqW4gc3VnaWVyZSB1bmEgbWFsYSBhZGFwdGFjacOzbi4NCiAgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYHN1bW1hcnlgOiBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcw0KDQojIyMgYEVzdGltYXRlc2A6IG91dHB1dCBncsOhZmljbw0KDQoxLiBTZSBwcm9wb3JjaW9uYW4gZXN0aW1hY2lvbmVzIGRlIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvLCBjb21vIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMsIGNvdmFyaWFuemFzIGVudHJlIHZhcmlhYmxlcyBsYXRlbnRlcyB5IHZhcmlhbnphcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgeSBsYXRlbnRlcywgZW50cmUgb3Ryb3MuDQoNCjIuIENhZGEgZmlsYSByZXByZXNlbnRhIHVuYSByZWxhY2nDs24gZW50cmUgdmFyaWFibGVzIG9ic2VydmFkYXMgeSBsYXRlbnRlcyBvIGVudHJlIHZhcmlhYmxlcyBsYXRlbnRlcywgbW9zdHJhbmRvIGVsIGVzdGltYWRvIGRlIGxhIHJlbGFjacOzbiwgc3UgZXJyb3IgZXN0w6FuZGFyLCB2YWxvciAkeiQgeSB2YWxvciAkcCQgYXNvY2lhZG8uDQoNCjMuIEVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTQpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDYgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE0LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDYgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYFBhcmFtZXRlciBFc3RpbWF0ZXNgKSoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTQucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogb3V0cHV0IGdyw6FmaWNvIChleHBsaWNhY2lvbmVzKQ0KDQpFbiBlbCBncsOhZmljbyBhbnRlcmlvciwgdmVtb3MgY3VhdHJvIHBhcnRlcyAoZXhwbGljYXJlbW9zIGNhZGEgdW5hIGRlIGVsbGFzIGVuIHNlY2Npb25lcyBzaWd1aWVudGVzKToNCg0KMS4gKipQYXJ0ZSA2YToqKiBJbmZvcm1hY2nDs24gZ2VuZXJhbC4NCg0KMi4gKipQYXJ0ZSA2YjoqKiBFc3RpbWFjaW9uZXMgZGUgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcyBkZSBsYXMgdmFyaWFibGVzIGxhdGVudGVzIChgdmlzdWFsYCwgYHRleHR1YWxgLCBgc3BlZWRgKSBlbiBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgKGB4MWAsIC4uLixgeDlgKS4NCg0KMi4gKipQYXJ0ZSA2YzoqKiBFc3RpbWFjaW9uZXMgZGUgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMuDQoNCjIuICoqUGFydGUgNmQ6KiogRXN0aW1hY2lvbmVzIGRlIGxhcyB2YXJpYW56YXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzICB5IGxhdGVudGVzLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgRXN0aW1hdGVgOiA2YSAoaW5mb3JtYWNpw7NuIGdlbmVyYWwpDQoNCiMjIyBgRXN0aW1hdGVgOiBwYXJ0ZSA2YSAob3V0cHV0IGdyw6FmaWNvKQ0KDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTUpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDZhIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xNSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiA2YSBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgR2VuZXJhbCBpbmZvcm1hdGlvbmApKioiLCBvdXQud2lkdGggPSAiODAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjE1LnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+IA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYEVzdGltYXRlYDogNmEgKGBpbmZvcm1hY2nDs24gZ2VuZXJhbGApDQoNCiMjIyBgRXN0aW1hdGVgOiBwYXJ0ZSA2YSAoaW50ZXJwcmV0YWNpb25lcykNCg0KTGEgc2VjY2nDs24gZGUgYFBhcmFtZXRlciBFc3RpbWF0ZXNgIGVuIGVsIHJlc3VtZW4gZGUgcmVzdWx0YWRvcyBkZSBsYXZhYW4gY29udGllbmUgaW5mb3JtYWNpw7NuIGltcG9ydGFudGUgc29icmUgbG9zIGVycm9yZXMgZXN0w6FuZGFyIHkgbGEgaW5mb3JtYWNpw7NuIHV0aWxpemFkYSBwYXJhIGNhbGN1bGFybG9zLiBBcXXDrSBoYXkgdW5hIGludGVycHJldGFjacOzbiBkZXRhbGxhZGEgZGUgbGFzIGzDrW5lYXMgZXNwZWPDrWZpY2FzIHF1ZSBzZSBoYW4gbWVuY2lvbmFkbzoNCg0KKioxLiBTdGFuZGFyZCBFcnJvcnMgKEVycm9yZXMgRXN0w6FuZGFyKS4qKg0KICANCiAgKyBJbmRpY2EgcXVlIGxvcyBlcnJvcmVzIGVzdMOhbmRhciBoYW4gc2lkbyBjYWxjdWxhZG9zLg0KICANCiAgKyBMb3MgZXJyb3JlcyBlc3TDoW5kYXIgc29uIG1lZGlkYXMgZGUgbGEgcHJlY2lzacOzbiBkZSBsYXMgZXN0aW1hY2lvbmVzIGRlIGxvcyBwYXLDoW1ldHJvczsgdmFsb3JlcyBtw6FzIHBlcXVlw7FvcyBpbmRpY2FuIGVzdGltYWNpb25lcyBtw6FzIHByZWNpc2FzLg0KDQoqKjIuIEluZm9ybWF0aW9uIChJbmZvcm1hY2nDs24pLioqDQogIA0KICArIEVzdGEgbMOtbmVhIGRlc2NyaWJlIGVsIHRpcG8gZGUgaW5mb3JtYWNpw7NuIHF1ZSBzZSB1dGlsaXrDsyBwYXJhIGNhbGN1bGFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhci4gDQogIA0KICArIEV4aXN0ZW4gZGlmZXJlbnRlcyBtw6l0b2RvcyBwYXJhIGNhbGN1bGFyIGxhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24uDQogIA0KICArIExhIGVsZWNjacOzbiBkZWwgbcOpdG9kbyBwdWVkZSBpbmZsdWlyIGVuIGxvcyBlcnJvcmVzIGVzdMOhbmRhciB5LCBwb3IgbG8gdGFudG8sIGVuIGxhcyBwcnVlYmFzIGRlIHNpZ25pZmljYW5jaWEuDQogIA0KDQoqKjMuIEluZm9ybWF0aW9uIFNhdHVyYXRlZCAoSDEpIE1vZGVsLioqDQogIA0KICArIExhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gZGVsICptb2RlbG8gc2F0dXJhZG8qICh0YW1iacOpbiBjb25vY2lkbyBjb21vIGVsICptb2RlbG8gImgxIiopIHNlIHV0aWxpemEgcGFyYSBjYWxjdWxhciBsb3MgZXJyb3JlcyBlc3TDoW5kYXIuIA0KICANCiAgKyBVbiBtb2RlbG8gc2F0dXJhZG8gZXMgdW4gbW9kZWxvIHF1ZSB0aWVuZSB0YW50b3MgcGFyw6FtZXRyb3MgY29tbyBzZWEgcG9zaWJsZSBwYXJhIGFqdXN0YXJzZSBwZXJmZWN0YW1lbnRlIGEgbG9zIGRhdG9zLiANCiAgDQogICsgRW4gb3RyYXMgcGFsYWJyYXMsIGVzIHVuIG1vZGVsbyBxdWUgYXN1bWUgcXVlIHRvZGFzIGxhcyB2YXJpYWJsZXMgZXN0w6FuIGNvcnJlbGFjaW9uYWRhcyBsaWJyZW1lbnRlLiANCiAgDQogICsgTGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBkZWwgbW9kZWxvIHNhdHVyYWRvIHB1ZWRlIHByb3BvcmNpb25hciB1bmEgZXN0aW1hY2nDs24gcm9idXN0YSBkZSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8uDQoNCioqNC4gU3RydWN0dXJlZCBJbmZvcm1hdGlvbi4qKg0KICANCiAgKyBMYSBpbmZvcm1hY2nDs24gZXN0cnVjdHVyYWRhIHNlIHJlZmllcmUgYSBsYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGRlcml2YWRhIGRlbCBtb2RlbG8gZXNwZWPDrWZpY28gcXVlIHNlIGVzdMOhIGV2YWx1YW5kbyAoZWwgbW9kZWxvIGRlbCB1c3VhcmlvKS4gDQogIA0KICArIEVzdGEgbWF0cml6IHNlIGJhc2EgZW4gbGFzIHJlc3RyaWNjaW9uZXMgeSBlc3BlY2lmaWNhY2lvbmVzIGRlbCBtb2RlbG8gZGVsIHVzdWFyaW8uIFByb3BvcmNpb25hIHVuYSB2aXNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgcGFyw6FtZXRyb3MgdGFsIGNvbW8gc2UgZXN0cnVjdHVyYSBlbiBlbCBtb2RlbG8gZXNwZWNpZmljYWRvLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZWA6IHBhcnRlIDZhIChpbnRlcnByZXRhY2nDs24gZ2VuZXJhbCkNCg0KMS4gU3RhbmRhcmQgZXJyb3JzOiBFc3BlY2lmaWNhIHF1ZSBzZSBoYW4gY2FsY3VsYWRvIGxvcyBlcnJvcmVzIGVzdMOhbmRhciBwYXJhIGxhcyBlc3RpbWFjaW9uZXMgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8uDQoNCjIuIEluZm9ybWF0aW9uOiBEZXNjcmliZSBxdWUgbGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBoYSBzaWRvIHV0aWxpemFkYSBwYXJhIGNhbGN1bGFyIGVzdG9zIGVycm9yZXMgZXN0w6FuZGFyLg0KDQoNCjMuIEluZm9ybWF0aW9uIHNhdHVyYXRlZCAoaDEpIG1vZGVsOiBJbmRpY2EgcXVlIGxhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gZGVsIG1vZGVsbyBzYXR1cmFkbyBzZSBoYSB1dGlsaXphZG8gcGFyYSBjYWxjdWxhciBsb3MgZXJyb3JlcyBlc3TDoW5kYXIuIEVzdGUgZW5mb3F1ZSBwdWVkZSBzZXIgbcOhcyByb2J1c3RvIHBvcnF1ZSBubyBkZXBlbmRlIGRlIGxhcyByZXN0cmljY2lvbmVzIGRlbCBtb2RlbG8gZXNwZWPDrWZpY28uDQoNCjQuIFN0cnVjdHVyZWQgSW5mb3JtYXRpb246IFNlIHJlZmllcmUgYSBsYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGNhbGN1bGFkYSBkaXJlY3RhbWVudGUgYSBwYXJ0aXIgZGVsIG1vZGVsbyBkZWwgdXN1YXJpbywgcXVlIGluY2x1eWUgdG9kYXMgbGFzIGVzcGVjaWZpY2FjaW9uZXMgeSByZXN0cmljY2lvbmVzIGltcHVlc3RhcyBwb3IgZWwgdXN1YXJpbyBlbiBlbCBtb2RlbG8uDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYEVzdGltYXRlYDogcGFydGUgNmEgKGNvbmNsdWNpw7NuIGdlbmVyYWwpDQoNCjEuIEVuIHJlc3VtZW4sIGVzdGEgc2VjY2nDs24gZGVsIHJlc3VtZW4gZGUgcmVzdWx0YWRvcyBkZSBsYXZhYW4gbm9zIGluZm9ybWEgcXVlIGxvcyBlcnJvcmVzIGVzdMOhbmRhciBzZSBoYW4gY2FsY3VsYWRvIHV0aWxpemFuZG8gdGFudG8gbGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBkZWwgbW9kZWxvIHNhdHVyYWRvIChoMSkgY29tbyBsYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGVzdHJ1Y3R1cmFkYSBkZWwgbW9kZWxvIGRlbCB1c3VhcmlvLiANCg0KMi4gRXN0ZSBlbmZvcXVlIHByb3BvcmNpb25hIHVuYSB2aXNpw7NuIHJvYnVzdGEgeSBlc3RydWN0dXJhZGEgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvIHkgZGUgbGEgcHJlY2lzacOzbiBkZSBsYXMgZXN0aW1hY2lvbmVzIGRlIGxvcyBwYXLDoW1ldHJvcy4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBFc3RpbWF0ZWA6IDZiIChgbGF0ZW50IHZhcmlhYmxlc2ApDQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmIgKG91dHB1dCBncsOhZmljbykNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xNikgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gNmIgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE2LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDYgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYExhdGVudCB2YXJpYWJsZXNgKSoqIiwgb3V0LndpZHRoID0gIjkwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xNi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYEVzdGltYXRlc2A6IHBhcnRlIDZiIChnZW5lcmFsaWRhZGVzKQ0KDQoxLiBTZSBwcmVzZW50YW4gbGFzIGVzdGltYWNpb25lcyBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIGRlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgKGB2aXN1YWxgLCBgdGV4dHVhbGAsIGBzcGVlZGApIGVuIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyAoYHgxYCwgLi4uLGB4OWApLg0KDQoyLiBQYXJhIGNhZGEgcmVsYWNpw7NuIGVudHJlIHVuYSB2YXJpYWJsZSBsYXRlbnRlIHkgc3VzIHZhcmlhYmxlcyBvYnNlcnZhZGFzLCBzZSBtdWVzdHJhIGxhIGVzdGltYWNpw7NuIGRlIGxhIGNhcmdhLCBzdSBlcnJvciBlc3TDoW5kYXIsIHZhbG9yICR6JCB5IHZhbG9yICRwJCBhc29jaWFkbzoNCiAgDQogICsgYEVzdGltYXRlYDogSW5kaWNhIGxhIGVzdGltYWNpw7NuICRcd2lkZWhhdHtcbGFtYmRhfSQgZGUgbGEgY2FyZ2EgZmFjdG9yaWFsICAoZmFjdG9yIGxvYWRpbmcpICRcbGFtYmRhJCBwYXJhIGNhZGEgaW5kaWNhZG9yIGVuIHJlbGFjacOzbiBjb24gc3UgdmFyaWFibGUgbGF0ZW50ZSBjb3JyZXNwb25kaWVudGUuDQogIA0KICArIGBTdGQuRXJyYDogRXMgZWwgZXJyb3IgZXN0w6FuZGFyICRTX3tcd2lkZWhhdHtcbGFtYmRhfX0kIGRlIGxhIGVzdGltYWNpw7NuLiANCiAgDQogICsgYHotdmFsdWVgOiBFbCB2YWxvciAkeiQgaW5kaWNhIGN1w6FudGFzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgZXN0w6EgbGEgZXN0aW1hY2nDs24gcG9yIGVuY2ltYSBvIHBvciBkZWJham8gZGUgY2Vyby4gVmFsb3JlcyBhYnNvbHV0b3MgbcOhcyBncmFuZGVzIGluZGljYW4gdW5hIG1heW9yIHNpZ25pZmljYW5jaWEgZXN0YWTDrXN0aWNhLg0KICANCiAgKyBgUCg+fHp8KWA6IEVzIGVsIHZhbG9yICRwJCBhc29jaWFkbyBjb24gZWwgdmFsb3IgJHokLiBVbiB2YWxvciAkcCQgYmFqbyAocG9yIGVqZW1wbG8sIDwwLjA1KSBzdWdpZXJlIHF1ZSBsYSBlc3RpbWFjacOzbiBlcyBzaWduaWZpY2F0aXZhbWVudGUgZGlmZXJlbnRlIGRlIGNlcm8uDQogIA0KICArIFNpICRcbGFtYmRhJCBlcyBsYSBjYXJnYSBmYWN0b3JpYWwgY29ycmVzcG9uZGllbnRlLCBlbnRvbmNlcywgbGFzIGhpcMOzdGVzaXMgcXVlIHNlIGNvbnRyYXN0YW4gc29uOiANCiAgDQogICQkSF8wOiBcOyBcbGFtYmRhID0gMCBccXVhZCBcdGV4dHt2ZXJzdXN9IFxxdWFkIEhfMTogXDsgXGxhbWJkYSBcbmUgMCQkDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYEVzdGltYXRlc2A6IHBhcnRlIDZiIChlamVtcGxvKQ0KDQoxLiBQYXJhIGxhIHZhcmlhYmxlIGxhdGVudGUgYHZpc3VhbGA6IA0KICANCiAgKyBFbCBpbmRpY2Fkb3IgYHgxYCB0aWVuZSB1bmEgY2FyZ2EgZmFjdG9yaWFsIGZpamEgZW4gJFx3aWRlaGF0e1xsYW1iZGF9XzE9MSQgKHBvciBjb252ZW5jacOzbikuIA0KICANCiAgKyBNaWVudHJhcyBxdWUgYHgyYCB5IGB4M2AsIHJlc3BlY3RpdmFtZW50ZSwgdGllbmVuIGNhcmdhcyBmYWN0b3JpYWxlcyBlc3RpbWFkYXMgZGUNCiAgDQogICQkXHdpZGVoYXR7XGxhbWJkYX1fMj0wLjU1NCwgXHF1YWQgXHdpZGVoYXR7XGxhbWJkYX1fMz0wLjcyOSQkIA0KICANCiAgKyBBZGVtw6FzLCBsb3MgZXJyb3JlcyBlc3TDoW5kYXJlcyBjb3JyZXNwb25kaWVudGVzIHNvbjoNCiAgDQogICQkU197XHdpZGVoYXR7XGxhbWJkYX1fMn0gPSAwLjEwMCwgXHF1YWQgU197XHdpZGVoYXR7XGxhbWJkYX1fM30gPSAwLjEwOSQkDQozLiBMb3MgdmFsb3JlcyAkeiQgIGNvcnJlc3BvbmRpZW50ZXMgYSAgYHgyYCB5IGB4M2Agc29uOiANCg0KJCR6XzI9IFxmcmFje1x3aWRlaGF0e1xsYW1iZGF9XzIgLSAwfXtTX3tcd2lkZWhhdHtcbGFtYmRhfV8yfX0gPSBcZnJhY3swLjU1NCAtIDB9ezAuMTAwfSA9IDUuNTU0LCBccXF1YWQgel8yPSBcZnJhY3tcd2lkZWhhdHtcbGFtYmRhfV8zIC0gMH17U197XHdpZGVoYXR7XGxhbWJkYX1fM319ID0gXGZyYWN7MC43MjkgLSAwfXswLjEwOX0gPSA2LjY4NSQkDQoNCjMuIFRvZG9zIGVzdG9zIHZhbG9yZXMgc29uIHNpZ25pZmljYXRpdm9zIChQIDwgMC4wNSksIGxvIHF1ZSBpbmRpY2EgcXVlIGxvcyBpbmRpY2Fkb3JlcyBlc3TDoW4gYmllbiBhc29jaWFkb3MgY29uIGxhIHZhcmlhYmxlIGxhdGVudGUgYHZpc3VhbGA6DQoNCiQkXHRleHR7dmFsb3J9XDsgcF8yID0gUChaXzIgPiA1LjU1NCkgPSAwLCBccXF1YWQgXHRleHR7dmFsb3J9XDsgIHBfMyA9IFAoWl8zID4gNi42ODUpID0gMCQkDQoNCjQuIERlIG1hbmVyYSBzaW1pbGFyLCBwYXJhIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgYHRleHR1YWxgIHkgYHNwZWVkYCwgbG9zIGluZGljYWRvcmVzIGVzdMOhbiBiaWVuIGFzb2NpYWRvcyBjb24gc3VzIHZhcmlhYmxlcyBsYXRlbnRlcyBjb3JyZXNwb25kaWVudGVzLCB5YSBxdWUgdG9kYXMgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcyBzb24gc2lnbmlmaWNhdGl2YXMuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBFc3RpbWF0ZWA6IDZjIChgY292YXJpYW5jZXNgKQ0KDQojIyMgYEVzdGltYXRlc2A6IHBhcnRlIDZjIChvdXRwdXQgZ3LDoWZpY28pDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTcpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDZjIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xNywgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiA2YyBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgQ292YXJpYW5jZXNgKSoqIiwgb3V0LndpZHRoID0gIjkwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xNy5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZXNgOiBwYXJ0ZSA2YyAoZ2VuZXJhbGlkYWRlcykNCg0KMS4gU2UgcHJvcG9yY2lvbmFuIGxhcyBlc3RpbWFjaW9uZXMgZGUgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgKGB2aXN1YWxgLCBgdGV4dHVhbGAsIGBzcGVlZGApLg0KDQoyLiBQYXJhIGNhZGEgY292YXJpYW56YSwgc2UgbXVlc3RyYSBsYSBlc3RpbWFjacOzbiwgc3UgZXJyb3IgZXN0w6FuZGFyLCB2YWxvciAkeiQgeSB2YWxvciAkcCQgYXNvY2lhZG86DQoNCiAgKyBgRXN0aW1hdGVgOiBJbmRpY2EgbGEgZXN0aW1hY2nDs24gJFx3aWRlaGF0e0N9X3tpan0gPSBcd2lkZWhhdHtDb3Z9KEZfaSxGX2opJCBkZSBsYSBjb3ZhcmlhbnphICRDX3tpan0kIGVudHJlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgJEZfaSQgeSAkRl9qJC4NCiAgDQogICsgYFN0ZC5FcnJgOiBFcyBlbCBlcnJvciBlc3TDoW5kYXIgJFNfe1x3aWRlaGF0e0N9X3tpan19JCBkZSBsYSBlc3RpbWFjacOzbi4gDQogIA0KICArIGB6LXZhbHVlYDogRWwgdmFsb3IgJHokIGluZGljYSBjdcOhbnRhcyBkZXN2aWFjaW9uZXMgZXN0w6FuZGFyIGVzdMOhIGxhIGVzdGltYWNpw7NuIHBvciBlbmNpbWEgbyBwb3IgZGViYWpvIGRlIGNlcm8uIFZhbG9yZXMgYWJzb2x1dG9zIG3DoXMgZ3JhbmRlcyBpbmRpY2FuIHVuYSBtYXlvciBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYS4NCiAgDQogICsgYFAoPnx6fClgOiBFcyBlbCB2YWxvciAkcCQgYXNvY2lhZG8gY29uIGVsIHZhbG9yICR6JC4gVW4gdmFsb3IgJHAkIGJham8gKHBvciBlamVtcGxvLCA8MC4wNSkgc3VnaWVyZSBxdWUgbGEgZXN0aW1hY2nDs24gZXMgc2lnbmlmaWNhdGl2YW1lbnRlIGRpZmVyZW50ZSBkZSBjZXJvLg0KICANCiAgKyBTaSAke0N9X3tpan0kIGVzIGxhIGNvdmFyaWFuemEgY29ycmVzcG9uZGllbnRlIGVudHJlICRGX2kkIHkgJEZfaiQsIGVudG9uY2VzLCBsYXMgaGlww7N0ZXNpcyBxdWUgc2UgY29udHJhc3RhbiAgc29uOiANCiAgDQogICQkSF8wOiBcOyB7Q31fe2lqfSA9IDAgXHF1YWQgXHRleHR7dmVyc3VzfSBccXVhZCBIXzE6IFw7IHtDfV97aWp9IFxuZSAwJCQNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmMgKGVqZW1wbG8pDQoNCjEuIExhIGNvdmFyaWFuemEgZW50cmUgYHZpc3VhbGAgeSBgdGV4dHVhbGAgZXMgZGUgMC40MDgsIGxvIHF1ZSBpbmRpY2EgcXVlIGVzdGFzIGRvcyB2YXJpYWJsZXMgbGF0ZW50ZXMgZXN0w6FuIG1vZGVyYWRhbWVudGUgY29ycmVsYWNpb25hZGFzLiANCg0KMi4gRXN0YSBjb3ZhcmlhbnphIGVzIHNpZ25pZmljYXRpdmEgKCRQIDwgMC4wNSQpLCBsbyBxdWUgc3VnaWVyZSB1bmEgcmVsYWNpw7NuIHNpZ25pZmljYXRpdmEgZW50cmUgbGFzIGhhYmlsaWRhZGVzIHZpc3VhbGVzIHkgdGV4dHVhbGVzLg0KDQozLiBMb3MgY8OhbGN1bG9zIGNvcnJlc3BvbmRpZW50ZXMgc29uIG11eSBzaW1pbGFyZXMgYSBsb3MgcmVhbGl6YWRvcyBlbiBsYSBwYXJ0ZSA2Yi4gDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYEVzdGltYXRlYDogNmQgKGB2YXJpYW5jZXNgKQ0KDQojIyMgYEVzdGltYXRlc2A6IHBhcnRlIDZkIChvdXRwdXQgZ3LDoWZpY28pDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTgpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDZkIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAuICANCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4xOCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhcnRlIE5vLiA2ZCBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgVmFyaWFuY2VzYCkqKiIsIG91dC53aWR0aCA9ICI5MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTgucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmMgKGdlbmVyYWxpZGFkZXMpDQoNCjEuIFNlIHByZXNlbnRhbiBsYXMgZXN0aW1hY2lvbmVzIGRlIGxhcyB2YXJpYW56YXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIChgeDFgLCAuLi4sIGB4OWApIHkgbGF0ZW50ZXMgKGB2aXN1YWxgLCBgdGV4dHVhbGAsIGBzcGVlZGApLg0KDQoyLiBQYXJhIGNhZGEgdmFyaWFuemEsIHNlIG11ZXN0cmEgbGEgZXN0aW1hY2nDs24sIHN1IGVycm9yIGVzdMOhbmRhciwgdmFsb3IgJHokIHkgdmFsb3IgJHAkIGFzb2NpYWRvOg0KDQogICsgYEVzdGltYXRlYDogSW5kaWNhIGxhIGVzdGltYWNpw7NuICRcd2lkZWhhdHtDfV97aWl9JCBkZSBsYSB2YXJpYW56YSAkQ197aWl9JCBlbnRyZSBsYXMgdmFyaWFibGVzIGRlIGludGVyw6lzLg0KICANCiAgKyBgU3RkLkVycmA6IEVzIGVsIGVycm9yIGVzdMOhbmRhciAkU197XHdpZGVoYXR7Q31fe2lpfX0kIGRlIGxhIGVzdGltYWNpw7NuLg0KICANCiAgKyBgei12YWx1ZWA6IEVsIHZhbG9yICR6JCBpbmRpY2EgY3XDoW50YXMgZGVzdmlhY2lvbmVzIGVzdMOhbmRhciBlc3TDoSBsYSBlc3RpbWFjacOzbiBwb3IgZW5jaW1hIG8gcG9yIGRlYmFqbyBkZSBjZXJvLiBWYWxvcmVzIGFic29sdXRvcyBtw6FzIGdyYW5kZXMgaW5kaWNhbiB1bmEgbWF5b3Igc2lnbmlmaWNhbmNpYSBlc3RhZMOtc3RpY2EuDQogIA0KICArIGBQKD58enwpYDogRXMgZWwgdmFsb3IgJHAkIGFzb2NpYWRvIGNvbiBlbCB2YWxvciAkeiQuIFVuIHZhbG9yICRwJCBiYWpvIChwb3IgZWplbXBsbywgPDAuMDUpIHN1Z2llcmUgcXVlIGxhIGVzdGltYWNpw7NuIGVzIHNpZ25pZmljYXRpdmFtZW50ZSBkaWZlcmVudGUgZGUgY2Vyby4NCiAgDQogICsgU2kgJHtDfV97aWl9JCBlcyBsYSB2YXJpYW56YSBjb3JyZXNwb25kaWVudGUgZGUgbGEgdmFyaWFibGUgZGUgaW50ZXLDqXMsIGVudG9uY2VzLCBsYXMgaGlww7N0ZXNpcyBxdWUgc2UgY29udHJhc3RhbiAgc29uOiANCiAgDQogICQkSF8wOiBcOyB7Q31fe2lpfSA9IDAgXHF1YWQgXHRleHR7dmVyc3VzfSBccXVhZCBIXzE6IFw7IHtDfV97aWl9IFxuZSAwJCQNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmMgKGVqZW1wbG8pDQoNCjEuIExhIHZhcmlhbnphIGRlIGxhIHZhcmlhYmxlIGxhdGVudGUgYHZpc3VhbGAgZXMgZGUgMC44MDkuIA0KDQoyLiBFc3RvIGluZGljYSBjdcOhbnRhIHZhcmlhbnphIGVuIGB2aXN1YWxgIG5vIGVzdMOhIGV4cGxpY2FkYSBwb3Igc3VzIGluZGljYWRvcmVzLiANCg0KMy4gRXN0YSB2YXJpYW56YSBlcyBzaWduaWZpY2F0aXZhICgkUCA8IDAuMDUkKSwgbG8gcXVlIHN1Z2llcmUgcXVlIGxhIHZhcmlhYmxlIGxhdGVudGUgYHZpc3VhbGAgY29udHJpYnV5ZSBzaWduaWZpY2F0aXZhbWVudGUgYSBsYSB2YXJpYWJpbGlkYWQgZW4gbG9zIGRhdG9zIG9ic2VydmFkb3MuDQoNCjMuIExvcyBjw6FsY3Vsb3MgY29ycmVzcG9uZGllbnRlcyBzb24gbXV5IHNpbWlsYXJlcyBhIGxvcyByZWFsaXphZG9zIGVuIGxhIHBhcnRlIDZiLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIGVsZW1lbnRvczogY29uIGBpbnNwZWN0YA0KDQojIyMgYGluc3BlY3RgOiBkZXNjcmlwY2nDs24NCg0KMS4gRWwgY8OzZGlnbyBkZSBhYmFqbyAgcHJvcG9yY2lvbmFyw6EgdW5hIHRhYmxhIHF1ZSBtdWVzdHJhIGxvcyBlc3RpbWFkb3MgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8gQ0ZBLg0KDQoyLiBFbCBvdXRwdXQgaW5jbHV5ZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzICgkXExhbWJkYSQpLCBsYXMgdmFyaWFuemFzIHJlc2lkdWFsZXMgKCRcVGhldGEkKSB5IGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgKCRcUHNpJCkuIA0KDQozLiBFbiBzZWNjaW9uZXMgc2lndWllbnRlcyBzZSBkZXNjcmliaXLDoW4gY2FkYSB1bm8gZGUgZWxsb3MuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGluc3BlY3RgOiBlamVjdWNpw7NuDQoNCioqRWwgY8OzZGlnby4qKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmluc3BlY3QoQ0ZBLCAiZXN0IikNCmF0dGFjaChpbnNwZWN0KENGQSwgImVzdCIpKQ0KDQpsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCnBzaSAgICAjY292YXJpYW56YXMgZW50cmUgbG9zIGZhY3RvcmVzDQpgYGANCg0KDQoqKkVsIG91dHB1dCBkZSBpbnNwZWN0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KaW5zcGVjdChDRkEsICJlc3QiKQ0KYXR0YWNoKGluc3BlY3QoQ0ZBLCAiZXN0IikpDQpgYGANCg0KKipFbCBvdXRwdXQgZGUgaW5zcGVjdDogY2FyZ2FzIGZhY3RvcmlhbGVzLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxhbWJkYSAjY2FyZ2FzIGZhY3RvcmlhbGVzDQojdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCg0KKipFbCBvdXRwdXQgZGUgaW5zcGVjdDogdmFyaWFuemFzIHJlc2lkdWFsZXMuKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQp0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzIChkZSBsb3MgZXJyb3JlcyBkZSBsYXMgdmFyLiBvYnNlcnZhZGFzKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KI2xhbWJkYSAjY2FyZ2FzIGZhY3RvcmlhbGVzDQp0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzIChkZSBsb3MgZXJyb3JlcyBkZSBsYXMgdmFyLiBvYnNlcnZhZGFzKQ0KI3BzaSAgICAjY292YXJpYW56YXMgZW50cmUgbG9zIGZhY3RvcmVzDQpgYGANCg0KDQoqKkVsIG91dHB1dCBkZSBpbnNwZWN0OiBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMuKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpwc2kgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KI3RoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMgKGRlIGxvcyBlcnJvcmVzIGRlIGxhcyB2YXIuIG9ic2VydmFkYXMpDQpwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGluc3BlY3RgOiBhcmd1bWVudG8gYHdoYXRgDQoNClBhcmEgdmVyIGPDs21vIGxhdmFhbiByZXByZXNlbnRhIGludGVybmFtZW50ZSB1biBtb2RlbG8sIHB1ZWRlIGVzY3JpYmlyOiANCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KaW5zcGVjdChmaXQsIHdoYXQ9Imxpc3QiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KaW5zcGVjdChmaXQsIHdoYXQ9Imxpc3QiKQ0KYGBgDQoNCg0KRXN0byBlcyBlcXVpdmFsZW50ZSBhIGxhIGZ1bmNpw7NuIGBwYXJUYWJsZWAuIExhIHRhYmxhIHF1ZSBzZSBkZXZ1ZWx2ZSBhcXXDrSBzZSBkZW5vbWluYSAqdGFibGEgZGUgcGFyw6FtZXRyb3MqLiBTZSBleHBsaWNhcsOhIGVuIHNlY2Npb25lcyBzaWd1aWVudGVzLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBlbGVtZW50b3M6IGNvbiBgbGF2SW5zcGVjdGANCg0KIyMjIGBsYXZJbnNwZWN0YDogZXhwbGljYWNpw7NuDQoNCkxhIGZ1bmNpw7NuIGBsYXZJbnNwZWN0YCBhY2VwdGEgdmFyaW9zIGFyZ3VtZW50b3MgcGFyYSBlc3BlY2lmaWNhciBxdcOpIGFzcGVjdG8gZGVsIG1vZGVsbyBzZSBkZXNlYSBpbnNwZWNjaW9uYXIuIEFsZ3Vub3MgZGUgbG9zIGFyZ3VtZW50b3MgY29tdW5lcyBpbmNsdXllbjoNCg0KKioxLiBgb2JqZWN0YC4qKg0KDQpFbCBtb2RlbG8gYWp1c3RhZG8gZGVsIGN1YWwgc2UgZGVzZWFuIGluc3BlY2Npb25hciBsYXMgcHJvcGllZGFkZXMuDQoNCioqMi4gYHdoYXRgLioqIA0KDQplc3BlY2lmaWNhIHF1w6kgcHJvcGllZGFkIGRlbCBtb2RlbG8gc2UgZGVzZWEgaW5zcGVjY2lvbmFyLiBFc3RvIHB1ZWRlIHNlciAiZXN0IiBwYXJhIGxvcyBwYXLDoW1ldHJvcyBlc3RpbWFkb3MsICJyZXNpZHVhbHMiIHBhcmEgbG9zIHJlc2lkdW9zLCAiY292IiBwYXJhIGxhcyBjb3ZhcmlhbnphcywgZW50cmUgb3Ryb3MuDQoNCioqMy4gYGxhYmVsYC4qKiANCg0KT3BjaW9uYWxtZW50ZSwgcGVybWl0ZSBlc3BlY2lmaWNhciB1biBub21icmUgcGFyYSBldGlxdWV0YXIgZWwgcmVzdWx0YWRvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGxhdkluc3BlY3RgOiBlamVjdWNpw7NuDQoNCjEuIFBvciBlamVtcGxvLCBwYXJhIGluc3BlY2Npb25hciBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlIHVuIG1vZGVsbyBhanVzdGFkbyBgQ0ZBYCwgcHVlZGVzIHVzYXIgYGxhdkluc3BlY3QoZml0LCAiZXN0IilgLiANCg0KMi4gRXN0byBkZXZvbHZlcsOhIHVuYSB0YWJsYSBxdWUgbXVlc3RyYSBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8sIGluY2x1eWVuZG8gbGFzIGNhcmdhcyBmYWN0b3JpYWxlcywgbGFzIHZhcmlhbnphcyByZXNpZHVhbGVzIHkgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcy4NCg0KDQozLiBFbCBvdXRwdXQgZXMgZXhhY3RhbWVudGUgZWwgbWlzbW8gcXVlIHNlIG9idGllbmUgY29uIGBpbnNwZWN0YC4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgYGxhdkluc3BlY3RgOiBlamVtcGxvcw0KDQojIyMgYGxhdkluc3BlY3RgOiBlamVtcGxvIDENCg0KUG9yIGRlZmVjdG8sIGFsIGxsYW1hciBhIGBsYXZJbnNwZWN0YCAgc29icmUgdW4gb2JqZXRvIGBsYXZhYW5gIGFqdXN0YWRvIHNlIG9idGllbmUgdW5hIGxpc3RhIGRlIGxhcyBtYXRyaWNlcyBkZWwgbW9kZWxvIHF1ZSBzZSB1dGlsaXphbiBpbnRlcm5hbWVudGUgcGFyYSByZXByZXNlbnRhciBlbCBtb2RlbG8uIExvcyBwYXLDoW1ldHJvcyBsaWJyZXMgc29uIGVudGVyb3MgZGlzdGludG9zIGRlIGNlcm8uDQoNCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KbGF2SW5zcGVjdChmaXQpDQpgYGANCg0KKipFbCBvdXRwdXQuKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsYXZJbnNwZWN0KGZpdCkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGxhdkluc3BlY3RgOiBlamVtcGxvIDINCg0KUGFyYSB2ZXIgY8OzbW8gYGxhdmFhbmAgcmVwcmVzZW50YSBpbnRlcm5hbWVudGUgdW4gbW9kZWxvLCBwdWVkZSBlc2NyaWJpcjoNCg0KYGBge3J9DQpsYXZJbnNwZWN0KENGQSwgd2hhdCA9ICJsaXN0IikNCmBgYA0KRXN0byBlcyBlcXVpdmFsZW50ZSBhIGxhIGZ1bmNpw7NuIGBwYXJUYWJsZWAuIExhIHRhYmxhIHF1ZSBzZSBkZXZ1ZWx2ZSBhcXXDrSBzZSBkZW5vbWluYSAqdGFibGEgZGUgcGFyw6FtZXRyb3MqLiBTZSBleHBsaWNhcsOhIGVuIHNlY2Npb25lcyBzaWd1aWVudGVzLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbGF2SW5zcGVjdGA6IGVqZW1wbG8gMw0KDQpFc3RpbWFyIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMsIGxhcyB2YXJpYW56YXMgcmVzaWR1YWxlcyB5IGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgY2FyZ2EgZmFjdG9yaWFsLCB2YXJpYW56YSByZXNpZHVhbCB5IGNvdmFyaWFuemEgZW50cmUgZmFjdG9yZXMuDQoNCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KbGF2SW5zcGVjdChmaXQsICJlc3QiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbGF2SW5zcGVjdChmaXQsICJlc3QiKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbGF2SW5zcGVjdGA6IGVqZW1wbG8gNA0KDQpFc3RpbWFyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEuDQoNCioqRWwgY8OzZGlnby4qKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmxhdkluc3BlY3QoQ0ZBLCAic2lnbWEiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbGF2SW5zcGVjdChDRkEsICJzaWdtYSIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBjb24gYHBhclRhYmxlYA0KDQoxLiBMYSBmdW5jacOzbiBzZSB1dGlsaXphIHBhcmEgZ2VuZXJhciB1bmEgdGFibGEgcXVlIHJlc3VtZSBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlIHVuIG1vZGVsbyBhanVzdGFkby4gDQoNCjIuIEVzdGEgdGFibGEgcHJvcG9yY2lvbmEgdW5hIHZpc2nDs24gZ2VuZXJhbCBkZSBsb3MgcGFyw6FtZXRyb3MgZGVsIG1vZGVsbywgaW5jbHV5ZW5kbyBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzLCBsYXMgdmFyaWFuemFzIHJlc2lkdWFsZXMsIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgeSBvdHJhcyBlc3RhZMOtc3RpY2FzIHJlbGV2YW50ZXMuDQoNCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcGFyVGFibGUoQ0ZBKQ0KYGBgDQoNCioqRWwgb3V0cHV0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KcGFyVGFibGUoQ0ZBKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBjYXJnYXMgZmFjdG9yaWFsZXMNCg0KDQojIyMgQ2FyZ2FzOiBzb2xvIGVzdGltYWRvcyAoY29uIGBpbnNwZWN0YCkNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmluc3BlY3QoQ0ZBLCAiZXN0IikNCmF0dGFjaChpbnNwZWN0KENGQSwgImVzdCIpKQ0KDQpsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KI3RoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCioqRWwgb3R1cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmluc3BlY3QoQ0ZBLCAiZXN0IikNCmF0dGFjaChpbnNwZWN0KENGQSwgImVzdCIpKQ0KDQpsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KI3RoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ2FyZ2FzOiBzaW4gc2lnbmlmaWNhbmNpYQ0KDQoxLiBFbiBlbCBvdXRwdXQgZGUgYWJham8sIGVsIGFyZ3VtZW50byBgc3RhbmRhcmRpemVkPVRSVUVgIGluZGljYSBxdWUgc2UgZGViZW4gZGV2b2x2ZXIgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcy4gDQoNCjIuIExhIGVzdGltYWNpw7NuIGVzdGFuZGFyaXphZGEgc2UgYWp1c3RhIHBvciBlbCBlcnJvciBlc3TDoW5kYXIgZGUgbGEgdmFyaWFibGUgaW1wbGljYWRhLCBwZXJtaXRpZW5kbyBhc8OtIGxhIGNvbXBhcmFjacOzbiBlbnRyZSBkaWZlcmVudGVzIHBhcsOhbWV0cm9zIGVuIHVuYSBlc2NhbGEgY29tw7puLg0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcGFyYW1ldGVyRXN0aW1hdGVzKENGQSwgc3RhbmRhcmRpemVkPVRSVUUpICU+JQ0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsIA0KICAgICAgICAgJ0luZGljYWRvcic9cmhzLCANCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LCANCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnRXN0aW1hY2nDs24gc3RkLic9c3RkLmFsbCwgI0VzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcw0KICAgICAgICAgJ1onPXosIA0KICAgICAgICAgJ3AgdmFsb3InPSBwdmFsdWUNCiAgICAgICAgICkgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkZhY3RvciBMb2FkaW5ncyIpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KcGFyYW1ldGVyRXN0aW1hdGVzKENGQSwgc3RhbmRhcmRpemVkPVRSVUUpICU+JQ0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsIA0KICAgICAgICAgJ0luZGljYWRvcic9cmhzLCANCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LCANCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnRXN0aW1hY2nDs24gc3RkLic9c3RkLmFsbCwgI0VzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcw0KICAgICAgICAgJ1onPXosIA0KICAgICAgICAgJ3AgdmFsb3InPSBwdmFsdWUNCiAgICAgICAgICkgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkZhY3RvciBMb2FkaW5ncyIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDYXJnYXM6IGNvbiBzaWduaWZpY2FuY2lhDQoNCkVuIGxhIHNhbGlkYSBkZSBhYmFqbywgbG9zIGFzdGVyaXNjb3MgIGluZGljYW4gbGEgc2lnbmlmaWNhbmNpYSBkZSBsYSBlc3RpbWFjacOzbiBiYXNhZGEgZW4gbG9zIHZhbG9yZXMgJHAkICgqKiogcGFyYSAkcCA8IC4wMDEkLCAqKiBwYXJhICRwIDwgLjAxJCwgKiBwYXJhICRwIDwgLjA1JCkuDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpwYXJhbWV0ZXJFc3RpbWF0ZXMoQ0ZBLCBzdGFuZGFyZGl6ZWQ9VFJVRSkgJT4lDQogIA0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIG11dGF0ZShzdGFycyA9IGlmZWxzZShwdmFsdWUgPCAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB2YWx1ZSA8IC4wNSwgIioiLCAiIikpKSkgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsDQogICAgICAgICAnSW5kaWNhZG9yJz1yaHMsDQogICAgICAgICAnRXN0aW1hY2nDs24nPWVzdCwNCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnWic9eiwNCiAgICAgICAgICdFc3RpbWFjacOzbiBzdGQuJz1zdGQuYWxsLCAjRXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzDQogICAgICAgICAncCB2YWxvcic9IHB2YWx1ZSwgDQogICAgICAgICAnU2lnLic9c3RhcnMpICU+JQ0KICANCmthYmxlKGRpZ2l0cyA9IDMsIGFsaWduPSJjIiwgZm9ybWF0PSJwYW5kb2MiLCBjYXB0aW9uPSJDYXJnYXMgZmFjdG9yaWFsZXMiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgDQogIGZpbHRlcihvcCA9PSAiPX4iKSAlPiUNCiAgbXV0YXRlKHN0YXJzID0gaWZlbHNlKHB2YWx1ZSA8IC4wMDEsICIqKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB2YWx1ZSA8IC4wMSwgIioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjA1LCAiKiIsICIiKSkpKSAlPiUNCiAgc2VsZWN0KCdGYWN0b3InPWxocywNCiAgICAgICAgICdJbmRpY2Fkb3InPXJocywNCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LA0KICAgICAgICAgJ0Vycm9yIHN0ZC4nPXNlLCANCiAgICAgICAgICdaJz16LA0KICAgICAgICAgJ0VzdGltYWNpw7NuIHN0ZC4nPXN0ZC5hbGwsICNFc3RpbWFjaW9uZXMgZXN0YW5kYXJpemFkYXMNCiAgICAgICAgICdwIHZhbG9yJz0gcHZhbHVlLCANCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNhcmdhcyBmYWN0b3JpYWxlcyIpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIEV4dHJheWVuZG8gdmFyaWFuemFzIHJlc2lkdWFsZXMNCg0KIyMjIFZhcmlhbnphIHJlc2lkdWFsIChkZSBsb3MgZXJyb3Jlcyk6IGNvbiBgaW5zcGVjdGANCg0KRXN0b3MgdmFsb3JlcyByZXByZXNlbnRhbiBsYXMgZGVzdmlhY2lvbmVzIGRlIGxvcyDDrXRlbXMgb2JzZXJ2YWRvcyBkZSBzdXMgdmFsb3JlcyBlc3BlcmFkb3MgYmFzYWRvcyBlbiBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIHkgbGEgbWVkaWEgbGF0ZW50ZSBkZWwgZmFjdG9yLg0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KaW5zcGVjdChDRkEsICJlc3QiKQ0KYXR0YWNoKGluc3BlY3QoQ0ZBLCAiZXN0IikpDQoNCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCioqRWwgb3R1cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNpbnNwZWN0KENGQSwgImVzdCIpDQojYXR0YWNoKGluc3BlY3QoQ0ZBLCAiZXN0IikpDQoNCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGFzDQoNCiMjIyBDb3ZhcmlhbnphIG9ic2VydmFkYTogZXhwbGljYWNpw7NuDQoNCjEuIExhICptYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcyogZXMgdW5hIG1hdHJpeiBxdWUgbXVlc3RyYSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGVuIHR1cyBkYXRvcy4gDQoNCjIuIEVzdGEgbWF0cml6IGVzIHVuYSByZXByZXNlbnRhY2nDs24gZGlyZWN0YSBkZSBsYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcyB0YWwgY29tbyBzZSBwcmVzZW50YSBlbiB0dXMgZGF0b3MgcmVhbGVzLCBzaW4gbmluZ3VuYSBzdXBvc2ljacOzbiBhZGljaW9uYWwgbyBtb2RlbGFkby4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQoNCiMjIyBDb3ZhcmlhbnphIG9ic2VydmFkYTogY29uIGBjb3ZgIA0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcw0KY292X21hdHJpeF9vYnNlcnZlZCA8LSByb3VuZChjb3YoZGF0KSwzKQ0KDQojIE1vc3RyYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIG9ic2VydmFkYXMNCnByaW50KGNvdl9tYXRyaXhfb2JzZXJ2ZWQpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcw0KY292X21hdHJpeF9vYnNlcnZlZCA8LSBjb3YoZGF0KQ0KDQojIE1vc3RyYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIG9ic2VydmFkYXMNCnByaW50KGNvdl9tYXRyaXhfb2JzZXJ2ZWQpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQoNCiMjIyBDb3ZhcmlhbnphIG9ic2VydmFkYTogY29uIGBsYXZUZWNoYCANCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCm9icyA8LSBsYXZUZWNoKENGQSwgInNhbXBzdGF0IilbWzFdXSRjb3YNCm9icw0KYGBgDQoNCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kb2JzIDwtIGxhdlRlY2goQ0ZBLCAic2FtcHN0YXQiKVtbMV1dJGNvdg0Kb2JzDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGENCg0KIyMjIEltcGxpY2FkYTogZGVmaW5pY2nDs24NCg0KMS4gTGEgKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEqIGVuIHVuIG1vZGVsbyBkZSBhbsOhbGlzaXMgZmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSkgZXMgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIHByZWRpY2hhIHBvciBlbCBtb2RlbG8gYWp1c3RhZG8uIA0KDQoyLiBFc3RhIG1hdHJpeiBtdWVzdHJhIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgcXVlIGVsIG1vZGVsbyBzdXBvbmUgcXVlIGV4aXN0aXLDrWFuLCBiYXNhZG8gZW4gbGFzIHJlbGFjaW9uZXMgZXNwZWNpZmljYWRhcyBlbnRyZSBsYXMgdmFyaWFibGVzIGxhdGVudGVzIHkgb2JzZXJ2YWRhcy4NCg0KMy4gKkludGVycHJldGFjacOzbiBkZSBsYSBNYXRyaXogZGUgQ292YXJpYW56YXMgSW1wbGljYWRhLiogDQogIA0KICArIExhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEgcmVmbGVqYSBjw7NtbyBlbCBtb2RlbG8gYWp1c3RhZG8gZXNwZXJhIHF1ZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgc2UgcmVsYWNpb25lbiBlbnRyZSBzw60uIA0KICANCiAgKyBFcyB1bmEgcmVwcmVzZW50YWNpw7NuIG1hdGVtw6F0aWNhIGRlIGxhcyBzdXBvc2ljaW9uZXMgZGVsIG1vZGVsby4gDQogIA0KNC4gQ29tcGFyYXIgZXN0YSBtYXRyaXogY29uIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGEgKGxhcyBjb3ZhcmlhbnphcyByZWFsZXMgZGUgbG9zIGRhdG9zKSBwZXJtaXRlIGV2YWx1YXIgbGEgY2FsaWRhZCBkZWwgYWp1c3RlIGRlbCBtb2RlbG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbXBsaWNhZGE6IGNvbiBwcm9kdWN0byBkZSBtYXRyaWNlcw0KDQoqKjEuIFJlY29yZGFyIHRlb3LDrWEqKg0KDQpSZWNvcmRlbW9zIHF1ZQ0KDQokJFx3aWRlaGF0e1xTaWdtYX0gXDs9XDsgXExhbWJkYSBcO1xQc2lcOyBcTGFtYmRhXntcdG9wfSBcOytcOyBcVGhldGEkJA0KDQpEb25kZToNCiAgDQogICsgJFx3aWRlaGF0e1xTaWdtYX0kIHJlcHJlc2VudGEgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVzdGltYWRhIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyAobGEgbGxhbWFkYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhKS4NCiAgIA0KICArICRcTGFtYmRhJCBlcyBsYSBtYXRyaXogZGUgY2FyZ2FzIGZhY3RvcmlhbGVzLg0KICAgIA0KICArICRcUHNpJCBlcyBsYSBtYXRyaXogZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcy4NCiAgICANCiAgKyAkXFRoZXRhJCBlcyBsYSBtYXRyaXogZGUgdmFyaWFuemFzIHJlc2lkdWFsZXMuDQogICANCg0KKioxLiBDw6FsY3VsbyBlbiBSKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpTaWdtYS5oYXQgPC0gbGFtYmRhICUqJSAgcHNpICUqJSB0KGxhbWJkYSkgKyB0aGV0YQ0Kcm91bmQoU2lnbWEuaGF0LCAzKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbXBsaWNhZGE6IGNvbiBgZml0dGVkYCAgKHByaW1lcmEgZm9ybWEpDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojIE9idGVuZXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCmZpdHRlZF92YWx1ZXMgPC0gZml0dGVkKENGQSkNCg0KIyBFeHRyYWVyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzDQppbXBsaWVkX2Nvdl9tYXRyaXggPC0gZml0dGVkX3ZhbHVlcyRjb3YNCg0KIyBNb3N0cmFyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzDQpwcmludChpbXBsaWVkX2Nvdl9tYXRyaXgpDQpgYGANCg0KDQoNCg0KKipFeHBsaWNhY2nDs24gZGVsIGPDs2RpZ28uKioNCg0KMS4gU2UgdXNhIGxhIGZ1bmNpw7NuIGBmaXR0ZWQoQ0ZBKWAgcGFyYSBvYnRlbmVyIGxhcyBtYXRyaWNlcyBpbXBsaWNhZGFzIGRlbCBtb2RlbG8gYWp1c3RhZG8uDQoNCjIuIFNlIGV4dHJhZSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhIGNvbiBgLi4uJGNvdmAuDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgT2J0ZW5lciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhcw0KZml0dGVkX3ZhbHVlcyA8LSBmaXR0ZWQoQ0ZBKQ0KDQojIEV4dHJhZXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCmltcGxpZWRfY292X21hdHJpeCA8LSBmaXR0ZWRfdmFsdWVzJGNvdg0KDQojIE1vc3RyYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCnByaW50KGltcGxpZWRfY292X21hdHJpeCkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgSW1wbGljYWRhOiBjb24gYGZpdHRlZGAgKHNlZ3VuZGEgZm9ybWEpDQoNCmBgYHtyfQ0KaW1wbGllZF9jb3ZfbWF0cml4IDwtIHJvdW5kKHVuY2xhc3MoZml0dGVkKENGQSkkY292KSwzKQ0KaW1wbGllZF9jb3ZfbWF0cml4DQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbXBsaWNhZGE6IGNvbiBgbGF2SW5zcGVjdGANCg0KYGBge3J9DQppbXBsaWVkX2Nvdl9tYXRyaXggPC0gbGF2SW5zcGVjdChDRkEsICJzaWdtYSIpDQppbXBsaWVkX2Nvdl9tYXRyaXgNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEV4dHJheWVuZG8gbWF0cml6IGRlIGNvdmFyaWFuemFzIHJlc2lkdWFsZXMNCg0KTGEgKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyByZXNpZHVhbGVzKiBtdWVzdHJhIGxhcyBkaWZlcmVuY2lhcyBlbnRyZSBsYXMgY292YXJpYW56YXMgb2JzZXJ2YWRhcyBlbiBsb3MgZGF0b3MgeSBsYXMgY292YXJpYW56YXMgaW1wbGljYWRhcyBwb3IgZWwgbW9kZWxvIGFqdXN0YWRvLg0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KY292X3RhYmxlIDwtIHJlc2lkdWFscyhDRkEsIHR5cGUgPSAiY29yIikkY292ICAjRXh0cmFlciBtYXRyaXogZGUgY292YXJpYW56YXMgcmVzaWR1YWxlcw0KY292X3RhYmxlDQpgYGANCg0KKipFeHBsaWNhY2nDs24uKioNCg0KMS4gRWwgY8OzZGlnbyAgdXNhIGxhIGZ1bmNpw7NuIGByZXNpZHVhbHNgIGRlbCBwYXF1ZXRlIGBsYXZhYW5gIHBhcmEgY2FsY3VsYXIgbGFzIGNvdmFyaWFuemFzIHJlc2lkdWFsZXMgZGVsIG1vZGVsbyBhanVzdGFkbyAoQ0ZBKS4gDQoNCjIuIExhIG9wY2nDs24gYHR5cGUgPSAiY29yImAgaW5kaWNhIHF1ZSBzZSBkZXNlYSBvYnRlbmVyIGxhcyByZXNpZHVhbGVzIGJhc2FkYXMgZW4gY29ycmVsYWNpb25lcyAoY292YXJpYW56YXMgZXN0YW5kYXJpemFkYXMpLg0KDQozLiBMYSBvcGNpw7NuICBgLi4uJGNvdmAgZXh0cmFlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBkZSBlc3RhcyByZXNpZHVhbGVzLg0KDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmNvdl90YWJsZSA8LSByZXNpZHVhbHMoQ0ZBLCB0eXBlID0gImNvciIpJGNvdiAgI0V4dHJhZXIgbWF0cml6IGRlIGNvdmFyaWFuemFzIHJlc2lkdWFsZXMNCmNvdl90YWJsZQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBjb3ZhcmlhbnphcyBlbnRyZSBmYWN0b3Jlcw0KDQojIyMgQ292YXJpYW56YSBlbnRyZSBsb3MgZmFjdG9yZXMgKGNvbiBgaW5zcGVjdGApDQoNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmluc3BlY3QoQ0ZBLCAiZXN0IikNCmF0dGFjaChpbnNwZWN0KENGQSwgImVzdCIpKQ0KDQojbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCiN0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzDQpwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCioqRWwgb3R1cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KI3RoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMNCnBzaSAgICAjY292YXJpYW56YXMgZW50cmUgbG9zIGZhY3RvcmVzDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb3ZhcmlhbnphIGVudHJlIGxvcyBmYWN0b3JlcyAob3RyYSBmb3JtYSkNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgZmlsdGVyKG9wID09ICJ+fiIsDQogICAgICAgICBsaHMgJWluJSBjKCJ2aXN1YWwiLCAidGV4dHVhbCIsICJzcGVlZCIpLA0KICAgICAgICAgIWlzLm5hKHB2YWx1ZSkpICU+JQ0KICBtdXRhdGUoc3RhcnMgPSBpZmVsc2UocHZhbHVlIDwgLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDUsICIqIiwgIiIpKSkpICU+JQ0KICBzZWxlY3QoJ0ZhY3RvciAxJz1saHMsDQogICAgICAgICAnRmFjdG9yIDInPXJocywNCiAgICAgICAgICdDb3JyZWxhY2nDs24nPWVzdCwNCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0KICBrYWJsZShkaWdpdHMgPSAzLCAgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyIpDQpgYGANCg0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgZmlsdGVyKG9wID09ICJ+fiIsDQogICAgICAgICBsaHMgJWluJSBjKCJ2aXN1YWwiLCAidGV4dHVhbCIsICJzcGVlZCIpLA0KICAgICAgICAgIWlzLm5hKHB2YWx1ZSkpICU+JQ0KICBtdXRhdGUoc3RhcnMgPSBpZmVsc2UocHZhbHVlIDwgLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDUsICIqIiwgIiIpKSkpICU+JQ0KICBzZWxlY3QoJ0ZhY3RvciAxJz1saHMsDQogICAgICAgICAnRmFjdG9yIDInPXJocywNCiAgICAgICAgICdDb3JyZWxhY2nDs24nPWVzdCwNCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0KICBrYWJsZShkaWdpdHMgPSAzLCAgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBtZWRpZGFzIGRlIGFqdXN0ZQ0KDQojIyMgTWVkaWRhcyBkZSBhanVzdGU6IHRvZGFzDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQptIDwtIGluc3BlY3QoQ0ZBLCAnZml0Lm1lYXN1cmVzJyk7IG0gIzEuIFRvZGFzIGxhcyBtZWRpZGFzDQptIDwtIGZpdE1lYXN1cmVzKENGQSk7IG0gICAgICAgICAgICAgIzIuIElndWFsIHF1ZSBlbCBhbnRlcmlvcg0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCm0gPC0gaW5zcGVjdChDRkEsICdmaXQubWVhc3VyZXMnKTsgbSAjRml0IG1lYXN1cmVzDQptIDwtIGZpdE1lYXN1cmVzKENGQSkgI0ZpdCBtZWFzdXJlcyAoaWd1YWwgcXVlIGxhIGFudGVyaW9yKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgKE5vIG1vZGlmaWNhcikgLS0+DQoNCiMjIyBNZWRpZGFzIGRlIGFqdXN0ZTogZGVzZGUgdW5hIGxpc3RhDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsaXN0YSA8LSBjKCJjaGlzcSIsICJkZiIsICJjZmkiLCAicm1zZWEiLCAic3JtciIsICJtZmkiLCAiYmljIiwgIm5maSIpDQpsaXN0YQ0KDQptczwtZml0TWVhc3VyZXMoQ0ZBKVtsaXN0YV07IG1zICAgICAgIzMuIExpc3RhIGVzcGVjw61maWNhIGRlIG1lZGlkYXMNCm1zPC1maXRNZWFzdXJlcyhDRkEsIGxpc3RhKTsgbXMgICAgICAjNC4gSWd1YWwgcXVlIGVsIGFudGVyaW9yDQptczwtcm91bmQobXMsMyk7IG1zDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbGlzdGEgPC0gYygiY2hpc3EiLCAiZGYiLCAiY2ZpIiwgInJtc2VhIiwgInNybXIiLCAibWZpIiwgImJpYyIsICJuZmkiKQ0KbGlzdGENCg0KbXM8LWZpdE1lYXN1cmVzKENGQSlbbGlzdGFdICAjU3BlY2lmaWMgZml0IG1lYXN1cmVzDQptczwtZml0TWVhc3VyZXMoQ0ZBLCBsaXN0YSkgICNJZ3VhbCBxdWUgZWwgYW50ZXJpb3INCm1zPC1yb3VuZChtcywzKTsgbXMNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIGxhcyBtZWRpYXMNCg0KIyMjIG1lZGlhczogZXhwbGljYWNpw7NuDQoNCjEuIEVuIGdlbmVyYWwsIGxvcyBtb2RlbG9zIGRlIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyBzZSB1dGlsaXphbiBwYXJhIG1vZGVsYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemEgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGVuIHVuIGNvbmp1bnRvIGRlIGRhdG9zLiANCg0KMi4gTm8gb2JzdGFudGUsIGVuIGFsZ3VuYXMgYXBsaWNhY2lvbmVzLCBlcyDDunRpbCBpbmNsdWlyIHRhbWJpw6luIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzLiANCg0KMy4gUGFyYSBsb2dyYXIgZXN0bywgc2UgcHVlZGVuIGVzcGVjaWZpY2FyIGV4cGzDrWNpdGFtZW50ZSBsb3MgaW50ZXJjZXB0b3MgZW4gbGEgc2ludGF4aXMgZGUgYGxhdmFhbmAuIA0KDQozLiBFc3RvIHNlIHJlYWxpemEgaW5jbHV5ZW5kbyAiZsOzcm11bGFzIGRlIGludGVyY2VwdG8iIGVuIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8uIFVuYSBmw7NybXVsYSBkZSBpbnRlcmNlcHRvIHRpZW5lIGVsIHNpZ3VpZW50ZSBmb3JtYXRvOg0KDQokJFx0ZXh0e3ZhcmlhYmxlIH4gMX0kJA0KDQo0LiBFbiBlc3RhIGV4cHJlc2nDs24sIGxhIHBhcnRlIGl6cXVpZXJkYSBjb250aWVuZSBlbCBub21icmUgZGUgbGEgdmFyaWFibGUgb2JzZXJ2YWRhIG8gbGF0ZW50ZSwgeSBsYSBwYXJ0ZSBkZXJlY2hhIGNvbnRpZW5lIGVsIG7Dum1lcm8gMSwgcXVlIHJlcHJlc2VudGEgZWwgaW50ZXJjZXB0by4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBtZWRpYXM6IGVqZW1wbG8NCg0KUG9yIGVqZW1wbG8sIGVuIGVsIG1vZGVsbyBkZSBhbsOhbGlzaXMgZmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSkgZGUgdHJlcyBmYWN0b3JlcyBkZSBIb2x6aW5nZXIgeSBTd2luZWZvcmQsIHBvZGVtb3MgYcOxYWRpciBsb3MgaW50ZXJjZXB0b3MgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCioqRWwgbW9kZWxvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyBFamVtcGxvIGRlIHNpbnRheGlzIGVuIGxhdmFhbiBjb24gaW50ZXJjZXB0b3MNCnZpc3VhbCA9fiB4MSArIHgyICsgeDMNCnRleHR1YWwgPX4geDQgKyB4NSArIHg2DQpzcGVlZCA9fiB4NyArIHg4ICsgeDkNCg0KeDEgfiAxDQp4MiB+IDENCngzIH4gMQ0KeDQgfiAxDQp4NSB+IDENCng2IH4gMQ0KeDcgfiAxDQp4OCB+IDENCng5IH4gMQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFeHRyYXllbmRvIGNvbiBgbWVhbnN0cnVjdHVyZWAgDQoNCiMjIyBgbWVhbnN0cnVjdHVyZWA6IGV4cGxpY2FjacOzbg0KDQpBIHZlY2VzLCBlcyBtw6FzIGNvbnZlbmllbnRlIG9taXRpciBsYXMgZsOzcm11bGFzIGRlIGludGVyY2VwdG8gZW4gbGEgc2ludGF4aXMgZGVsIG1vZGVsbyAoYSBtZW5vcyBxdWUgZGVzZWUgc3VzIHZhbG9yZXMpLCB5IGHDsWFkaXIgZWwgYXJndW1lbnRvIGBtZWFuc3RydWN0dXJlID0gVFJVRWAgZW4gbGFzIGxsYW1hZGFzIGEgbGFzIGZ1bmNpb25lcyBgY2ZhYCB5IGBzZW1gLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbWVhbnN0cnVjdHVyZWA6IGVqZW1wbG8NCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmZpdCA8LSBjZmEobW9kZWxvLCBkYXRhPWRhdCwgbWVhbnN0cnVjdHVyZT1UUlVFKQ0Kc3VtbWFyeShmaXQpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KZml0IDwtIGNmYShtb2RlbG8sIGRhdGE9ZGF0LCBtZWFuc3RydWN0dXJlPVRSVUUpDQpzdW1tYXJ5KGZpdCkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBtZWFuc3RydWN0dXJlYDogSW50ZXJwcmV0YWNpw7NuDQoNCjEuIENvbW8gcHVlZGUgb2JzZXJ2YXIgZW4gZWwgcmVzdWx0YWRvLCBlbCBtb2RlbG8gaW5jbHV5ZSBwYXLDoW1ldHJvcyBkZSBpbnRlcmNlcGNpw7NuIHRhbnRvIHBhcmEgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGNvbW8gcGFyYSBsYXMgbGF0ZW50ZXMuIA0KDQoyLiBQb3IgZGVmZWN0bywgbGFzIGZ1bmNpb25lcyBjZmEgeSBzZW0gZmlqYW4gbG9zIGludGVyY2VwdG9zIGRlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgKHF1ZSBlbiBlc3RlIGNhc28gY29ycmVzcG9uZGVuIGEgbGFzIG1lZGlhcyBsYXRlbnRlcykgYSBjZXJvLiANCg0KMy4gRGUgb3RybyBtb2RvLCBlbCBtb2RlbG8gbm8gc2Vyw61hIGVzdGltYWJsZS4gDQoNCjQuIENhYmUgZGVzdGFjYXIgcXVlIGVsIGVzdGFkw61zdGljbyBjaGktY3VhZHJhZG8geSBlbCBuw7ptZXJvIGRlIGdyYWRvcyBkZSBsaWJlcnRhZCBzb24gbG9zIG1pc21vcyBxdWUgZW4gZWwgbW9kZWxvIG9yaWdpbmFsIChzaW4gZXN0cnVjdHVyYSBkZSBtZWRpYXMpLiANCg0KNS4gRXN0byBzZSBkZWJlIGEgcXVlLCBhdW5xdWUgaGVtb3MgYcOxYWRpZG8gbnVldm9zIGRhdG9zICh1biB2YWxvciBtZWRpbyBwYXJhIGNhZGEgdW5hIGRlIGxhcyA5IHZhcmlhYmxlcyBvYnNlcnZhZGFzKSwgdGFtYmnDqW4gaGVtb3MgaW50cm9kdWNpZG8gOSBwYXLDoW1ldHJvcyBhZGljaW9uYWxlcyBhbCBtb2RlbG8gKHVuIGludGVyY2VwdG8gcGFyYSBjYWRhIHVuYSBkZSBsYXMgOSB2YXJpYWJsZXMgb2JzZXJ2YWRhcykuIA0KDQo2LiBFbCByZXN1bHRhZG8gZmluYWwgZXMgdW4gYWp1c3RlIGlkw6ludGljby4gDQoNCjcuIEVuIGxhIHByw6FjdGljYSwgbGEgw7puaWNhIHJhesOzbiBwYXJhIHF1ZSB1biB1c3VhcmlvIGHDsWFkYSBmw7NybXVsYXMgZGUgaW50ZXJjZXBjacOzbiBlbiBsYSBzaW50YXhpcyBkZWwgbW9kZWxvIGVzIHBhcmEgZXNwZWNpZmljYXIgY2llcnRhcyByZXN0cmljY2lvbmVzIG5lY2VzYXJpYXMgZW4gZWwgbW9kZWxvLg0KDQo4LiBQb3IgZWplbXBsbywgcmV2aXNlIGxhIHNpdHVhY2nDs24gcXVlIHNlIGluZGljYSBhIGNvbnRpbnVhY2nDs24uIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYG1lYW5zdHJ1Y3R1cmVgOiBmaWphbmRvIGludGVyY2VwdG9zDQoNClBvciBlamVtcGxvLCBzdXBvbmdhbW9zIHF1ZSBkZXNlYW1vcyB4IGxvcyBpbnRlcmNlcHRvcyBkZSBsYXMgdmFyaWFibGVzIHgxLCB4MiwgeDMgeSB4NCBhLCBkaWdhbW9zLCAwLDUuIEVzY3JpYmlyw61hbW9zIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8gY29tbyBzaWd1ZToNCg0KKipFbCBtb2RlbG8uICoqDQoNCmBgYHtyfQ0KIyBNb2RlbG8gZGUgdHJlcyBmYWN0b3Jlcw0KDQptb2RlbG8uZml4IDwtICcNCnZpc3VhbCA9fiB4MSArIHgyICsgeDMNCnRleHR1YWwgPX4geDQgKyB4NSArIHg2DQpzcGVlZCA9fiB4NyArIHg4ICsgeDkNCg0KIyBJbnRlcmNlcHRvcyBjb24gdmFsb3JlcyBmaWpvcw0KeDEgKyB4MiArIHgzICsgeDQgfiAwLjUqMQ0KJw0KYGBgDQoNCioqT2JzZXJ2YWNpw7NuLiAqKg0KDQpBcnJpYmEgIGhlbW9zIHV0aWxpemFkbyBlbCBsYWRvIGl6cXVpZXJkbyBkZSBsYSBmw7NybXVsYSBwYXJhIMKrcmVwZXRpcsK7IGVsIGxhZG8gZGVyZWNobyBwYXJhIGNhZGEgZWxlbWVudG8gZGVsIGxhZG8gaXpxdWllcmRvLg0KDQoNCioqRWplY3V0YW5kbyBDRkEuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KQ0ZBLmZpeCA8LSBjZmEobW9kZWxvLmZpeCwgZGF0YT1kYXQpDQpzdW1tYXJ5KENGQS5maXgpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBvdHJvcyBlbGVtZW50b3MNCg0KIyMjIE90cm9zOiBgdmNvdmANCg0KTGEgZnVuY2nDs24gYHZjb3ZgIHJldG9ybmEgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVzdGltYWRhIGRlIGxvcyBwYXLDoW1ldHJvcyBlc3RpbWFkb3MuIA0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmNvdihDRkEpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KdmNvdihDRkEpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvczogYEFJQ2AgeSBgQklDYA0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KY2JpbmQoQUlDKENGQSksIEJJQyhDRkEpKQ0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmNiaW5kKEFJQyhDRkEpLCBCSUMoQ0ZBKSkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIE90cm9zOiBgcGFyYW1ldGVyRXN0aW1hdGVzYA0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcGFyYW1ldGVyRXN0aW1hdGVzKENGQSkNCmBgYA0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpwYXJhbWV0ZXJFc3RpbWF0ZXMoQ0ZBKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvczogYHN0YW5kYXJkaXplZFNvbHV0aW9uYA0KDQpMYSBmdW5jacOzbiBgc3RhbmRhcmRpemVkU29sdXRpb25gIGVzIHNpbWlsYXIgYSBsYSBmdW5jacOzbiBgcGFyYW1ldGVyRXN0aW1hdGVzYA0KcGVybyBzw7NsbyBtdWVzdHJhIGxhcyBlc3RpbWFjaW9uZXMgZGUgcGFyw6FtZXRyb3MgZXN0YW5kYXJpemFkYXMgeSBubyBlc3RhbmRhcml6YWRhcy4NCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnN0YW5kYXJkaXplZFNvbHV0aW9uKENGQSkNCmBgYA0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpzdGFuZGFyZGl6ZWRTb2x1dGlvbihDRkEpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvczogYGZpdHRlZC52YWx1ZXNgDQoNCkxhcyBmdW5jaW9uZXMgYGZpdHRlZGAgeSBgZml0dGVkLnZhbHVlc2AgZGV2dWVsdmVuIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphICBpbXBsw61jaXRhIGVuIGVsIG1vZGVsbyAoYWp1c3RhZG8pIHkgZWwgdmVjdG9yIGRlIG1lZGlhcyBkZSB1biBtb2RlbG8gYWp1c3RhZG86DQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpmaXR0ZWQudmFsdWVzKENGQSkNCmBgYA0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpmaXR0ZWQudmFsdWVzKENGQSkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgT3Ryb3M6IGByZXNpZGANCg0KMS4gTGFzIGZ1bmNpb25lcyBgcmVzaWRgIG8gYHJlc2lkdWFsc2AgZGV2dWVsdmVuIGxvcyByZXNpZHVvcyAobm8gZXN0YW5kYXJpemFkb3MpIGRlIHVuIG1vZGVsbyBhanVzdGFkby4gDQoNCjIuIEVzdGUgZXMgc2ltcGxlbWVudGUgbGEgZGlmZXJlbmNpYSBlbnRyZSBsYSBtYXRyaXogZGUgY292YXJpYW56YSB5IGVsIHZlY3RvciBkZSBtZWRpYSBvYnNlcnZhZG9zIGUgaW1wbMOtY2l0b3MuIA0KDQozLiBTaSBlbCBlc3RpbWFkb3IgZXMgZGUgbcOheGltYSB2ZXJvc2ltaWxpdHVkLCB0YW1iacOpbiBlcyBwb3NpYmxlIG9idGVuZXIgbG9zIHJlc2lkdW9zIG5vcm1hbGl6YWRvcyB5IGVzdGFuZGFyaXphZG9zIChub3RhOiBlcyBwb3NpYmxlIHF1ZSBvYnNlcnZlIHZhcmlvcyB2YWxvcmVzIGRlIE5BLCBwZXJvIG5vIHNvbiBsb3MgbWlzbW9zKToNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnJlc2lkKENGQSwgdHlwZT0ic3RhbmRhcmRpemVkIikNCmBgYA0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpyZXNpZChDRkEsIHR5cGU9InN0YW5kYXJkaXplZCIpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBGdW5jaW9uZXMgZXNwZWNpYWxlcw0KDQojIyMgRnVuY2lvbmVzIGRlIGV4dHJhY2Npw7NuIHBhcmEgaW5zcGVjY2lvbmFyIG1vZGVsb3MgYWp1c3RhZG9zDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTkpIHNlIG11ZXN0cmEgdW5hIGxpc3RhIGRlIGZ1bmNpb25lcyBwYXJhIGluc3BlY2Npb25hciBtb2RlbG9zIGFqdXN0YWRvcy4NCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE5LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqRnVuY2lvbmVzIGRlIGV4dHJhY2Npw7NuIHBhcmEgaW5zcGVjY2lvbmFyIG1vZGVsb3MgYWp1c3RhZG9zKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xOS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBPdHJhcyBmdW5jaW9uZXMgZXNwZWNpYWxlcw0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjIwKSBzZSBtdWVzdHJhIHVuYSBsaXN0YSBkZSBmdW5jaW9uZXMgcGFyYSBpbnNwZWNjaW9uYXIgbW9kZWxvcyBhanVzdGFkb3MuDQoNCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4yMCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKk90cmFzIGZ1bmNpb25lcyBlc3BlY2lhbGVzKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4yMC5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIFTDs3BpY29zIHN1cGxlbWVudGFyaW9zIA0KDQoNCg0KW05vIGhhY2VyIGNsaWNrIGFxdcOtXShPSk9KT0pPKTogUGVuZGllbnRlDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gQ2Fww610dWxvIEVqZXJjaWNpb3MgLS0+DQoNCiMgRWplcmNpY2lvcw0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpodHRwczovL2xhdmFhbi51Z2VudC5iZS90dXRvcmlhbC9pbnNwZWN0Lmh0bWwNCmh0dHBzOi8vbXNwZWVrZW5icmluay5naXRodWIuaW8vc2RhbS1yLWNvbXBhbmlvbi9zdHJ1Y3R1cmFsLWVxdWF0aW9uLW1vZGVsbGluZy13aXRoLWxhdmFhbi5odG1sDQpodHRwczovL3JwdWJzLmNvbS9Kb18vbGF2YWFuX2VmZWN0b3NfZGlyZWN0b3MNCmh0dHBzOi8vc3RhdHMub2FyYy51Y2xhLmVkdS9yL3NlbWluYXJzL3JzZW0vDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyAxDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIEVzIHVuIGRhdGEgc2V0cyANCiNodHRwczovL2Jsb2dzLmJheWxvci5lZHUvcmxhdGVudHZhcmlhYmxlL3NhbXBsZS1wYWdlL2RhdGEvDQojDQojQmVhdWplYW4sIGVqZXJjaWNpbyAyLjEsIHBhZ2luYSAzNC4gU29sdWNpb24gZW4gcGFnaW5hIDE3MQ0KYGBgDQoNCg0KQ29uc2lkZXJlIGVsIHNpZ3VpZW50ZSBjb25qdW50byBkZSBkYXRvcyBxdWUgY29udGllbmUgMTAwIG9ic2VydmFjaW9uZXMgeSAyIHZhcmlhYmxlczogDQogIA0KICArIEVsIG7Dum1lcm8gZGUgaG9yYXMgcXVlIHNlIHN1ZWxlbiBkZWRpY2FyIGEgbGFzIG1hdGVtw6F0aWNhcyAoYE1hdGhIb21ld29ya2ApDQogIA0KICArIExhIHB1bnR1YWNpw7NuIGVuIHVuIHRlc3QgZXN0YW5kYXJpemFkbyBkZSByZW5kaW1pZW50byBkZSBtYXRlbcOhdGljYSAoYE1hdGhBY2hpZXZlbWVudGApLg0KDQpgYGB7cn0NCiMgQ3JlYXIgZWwgZGF0YWZyYW1lIGVuIFINCk1hdGhIbXdrLmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAgTWF0aEhvbWV3b3JrID0gYygyLCAwLCA0LCAwLCAyLCAwLCAxLCAwLCAzLCAwLCA0LCA3LCAzLCAxLCAxLCAwLCAzLCAwLCAxLCAzLCAzLCAwLCAyLCAwLCAxLCA0LCAxLCA0LCAzLCAxLCAxLCAzLCAzLCA1LCAyLCA1LCAxLCAzLCAyLCAyLCAwLCAyLCA1LCAwLCAyLCAyLCAxLCAyLCAxLCA0LCAwLCAwLCA0LCAxMCwgMSwgMSwgMiwgMiwgMSwgMiwgMiwgMSwgMiwgMiwgMywgMiwgMCwgMCwgMywgMiwgNSwgNSwgMSwgMCwgMCwgMiwgMiwgMywgMCwgMiwgNCwgMCwgMywgMSwgMiwgMywgNCwgNCwgNCwgMiwgMSwgNiwgMywgNSwgNiwgNCwgMywgMiwgMiwgMSksDQogIE1hdGhBY2hpZXZlbWVudCA9IGMoNTQsIDUzLCA1MywgNTYsIDU5LCAzMCwgNDksIDU0LCAzNywgNDksIDU1LCA1MCwgNDUsIDQ0LCA2MCwgMzYsIDUzLCAyMiwgNTYsIDU0LCA3NSwgMzcsIDQyLCA2NCwgNjEsIDU3LCA1MywgNjMsIDc1LCA1MywgNTQsIDY0LCA1NCwgNTksIDQ4LCA2NSwgNTcsIDQ4LCA1NCwgNjIsIDUzLCA2MSwgNTYsIDMyLCA1MCwgNDQsIDYyLCAzOSwgNjEsIDUxLCAzNiwgMzgsIDM4LCA1OSwgNDYsIDU1LCA0OCwgNTQsIDQxLCA2MSwgNTIsIDYzLCAyNSwgNjQsIDcyLCA2NSwgNDEsIDI5LCAzOSwgNzAsIDY4LCAzOCwgNTksIDI5LCA0OSwgMzksIDQ1LCA3NCwgNDEsIDUzLCA3MSwgNDEsIDYzLCAzNCwgNjEsIDUxLCA2MiwgNTUsIDY0LCA0NywgNDgsIDQ3LCA0NCwgNTIsIDUwLCA0OCwgNTgsIDM5LCA0MSwgNTEpDQopDQojIFZlciBlbCBkYXRhZnJhbWUNCmhlYWQoTWF0aEhtd2suZGF0YSkNCmBgYA0KDQpMYSBwcmVndW50YSBkZSBpbnRlcsOpcyBlczogKsK/RWwgdGllbXBvIGRlZGljYWRvIGEgbG9zIGRlYmVyZXMgZGUgbWF0ZW3DoXRpY2FzIGVzdMOhIGRpcmVjdGFtZW50ZSByZWxhY2lvbmFkbyBjb24gZWwgcmVuZGltaWVudG8gZW4gbWF0ZW3DoXRpY2FzPyoNCg0KKGEpIERpYnVqZSB1biBkaWFncmFtYSBkZSBkaXNwZXJzacOzbiBlbnRyZSBhbWJhcyB2YXJpYWJsZXMuIA0KDQooYikgUmVhbGljZSB1bmEgcmVncmVzacOzbiB0w61waWNhIGVzdGFuZGFyaXphZG8geSBubyBlc3RhbmRhcml6YWRvLCAgdXRpbGl6YW5kbyBsYSBmdW5jacOzbiBgbG1gLiAqU3VnZXJlbmNpYSo6IFBhcmEgbGEgbm8gZXN0YW5kYXJpemFkYSBhcGxpcXVlIGxhIGZ1bmNpw7NuIGBzY2FsZWAgYSBhbWJvcyBjb25qdW50b3MgZGUgZGF0b3MgeSBoYWdhIGxhIHJlZ3Jlc2nDs24uIA0KDQooYykgRGlidWplIHVuIHBhdGggbW9kZWwgZXN0YW5kYXJpemFkbyB5IG5vIGVzdGFuZGFyaXphZG8gZGUgbGEgcmVncmVzacOzbi4gDQoNCihkKSBSZWFsaWNlIGVsIGFuw6FsaXNpcyBjb21vIHVuIHBhdGggbW9kZWwgZW4gYGxhdmFhbmAgdXRpbGl6YW5kbyBsYSBmdW5jacOzbiBgc2VtYC4gT2J0ZW5nYSB0YW50byBsb3MgY29lZmljaWVudGVzIGVzdGFuZGFyaXphZG9zIGNvbW8gbG9zIG5vIGVzdGFuZGFyaXphZG9zLiAqU3VnZXJlbmNpYSo6IFBhcmEgbm8gZXN0YW5kYXJpemFkbyB1c2UgZWwgYXJndW1lbnRvIGBtZWFuc3RydWN0dXJlID0gVFJVRWAuIA0KDQoNCihlKSDCv0PDs21vIHNlIHJlbGFjaW9uYW4gbG9zIHJlc3VsdGFkb3MgZGUgbG9zIGluY2lzb3MgKGIpIHkgKGQpPw0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojRXhlcmNpc2UgMi4xLmINCiMgdW5zdGFuZGFyZGl6ZWQgcmVncmVzc2lvbg0KbWF0aC5sbSA8LSBsbShNYXRoQWNoaWV2ZW1lbnQgfiBNYXRoSG9tZXdvcmssIGRhdGEgPSBNYXRoSG13ay5kYXRhKQ0Kc3VtbWFyeShtYXRoLmxtKQ0KIyBzdGFuZGFyZGl6ZWQgcmVncmVzc2lvbg0KbWF0aDIubG0gPC0gbG0oc2NhbGUoTWF0aEFjaGlldmVtZW50KSB+IHNjYWxlKE1hdGhIb21ld29yayksIGRhdGEgPSBNYXRoSG13ay5kYXRhKQ0Kc3VtbWFyeShtYXRoMi5sbSkNCg0KI0V4ZXJjaXNlIDIuMS5jDQojVGhlIHBhdGggbW9kZWxzIGFyZSBzaG93biBpbiBGaWd1cmUgQy4xLg0KDQojRXhlcmNpc2UgMi4xLmQNCiMgcGF0aCBtb2RlbA0KbGlicmFyeShsYXZhYW4pDQptYXRoLm1vZGVsIDwtICcNCk1hdGhBY2hpZXZlbWVudCB+IE1hdGhIb21ld29yaw0KJw0KIyB1bnN0YW5kYXJkaXplZCByZXN1bHRzIHdpdGggYW4gaW50ZXJjZXB0DQptYXRoLmZpdCA8LSBzZW0obWF0aC5tb2RlbCwgZGF0YSA9IE1hdGhIbXdrLmRhdGEsIG1lYW5zdHJ1Y3R1cmUgPSBUUlVFKQ0Kc3VtbWFyeShtYXRoLmZpdCkNCg0KIyBzdGFuZGFyZGl6ZWQgcmVzdWx0cyB3aXRob3V0IGFuIGludGVyY2VwdCANCiMgKHN0YW5kYXJkaXplZCByZXN1bHRzIGFyZSBpbiB0aGUgU3RkLmFsbCBjb2x1bW4pDQptYXRoMi5maXQgPC0gc2VtKG1hdGgubW9kZWwsIGRhdGEgPSBNYXRoSG13ay5kYXRhKQ0Kc3VtbWFyeShtYXRoMi5maXQsIHN0YW5kYXJkaXplZCA9IFRSVUUpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gMg0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDIuMiwgcGFnaW5hIDM0LiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTcyDQpgYGANCg0KUGFnZSB5IEtlaXRoICgxOTgxKSB1dGlsaXphcm9uIGVuY3Vlc3RhZG9zIGRlIGxvcyBkYXRvcyBkZSAxOTgwIEhpZ2ggU2Nob29sIGFuZCBCZXlvbmQgcGFyYSBpbnZlc3RpZ2FyIGxhIHNpZ3VpZW50ZSBwcmVndW50YTogKsK/Q3XDoWwgZXMgbGEgcmVsYWNpw7NuIGVudHJlIGVsIHRpcG8gZGUgZXNjdWVsYSB5IGVsIHJlbmRpbWllbnRvIGFjYWTDqW1pY28/KiBMb3MgZGF0b3MgYXBhcmVjZW4gZW4gbGEgRmlndXJhIFxAcmVmKGZpZzpCZWF1amVhbkNhcDJFeDJhKSBlbiBmb3JtYSBkZSBtYXRyaXogZGUgY29ycmVsYWNpb25lcy4gRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpCZWF1amVhbkNhcDJFeDJiKSBzZSBtdWVzdHJhIHVuIHBhdGggbW9kZWwgcGFyYSBsb3MgYW7DoWxpc2lzLiANCg0KDQpFbCBjw7NkaWdvIFIgcGFyYSBsYSBtYXRyaXogZXM6IA0KDQpgYGB7cn0NCmxpYnJhcnkobGF2YWFuKQ0KcHJpdlNjaG9vbC5jb3IgPC0gYygxLCAwLjE3OCwgMC4yMywgMC4xMDYsIDAuMTk1LCAxLCAwLjMyNywgMC4yNDUsIDAuMzU2LCAxLCAwLjE4MywgMC43MjEsIDEsIDAuMTc4LCAxKQ0KcHJpdlNjaG9vbC5jb3IgPC0gbGF2X21hdHJpeF91cHBlcjJmdWxsKHByaXZTY2hvb2wuY29yKQ0KI3ByaXZTY2hvb2wuY29yIDwtIGxhdl9tYXRyaXhfbG93ZXIyZnVsbChwcml2U2Nob29sLmNvcikNCmRpbW5hbWVzKHByaXZTY2hvb2wuY29yKSA8LSBsaXN0KGMoIlJhY2UiLCAiU0VTIiwgIkNvZ0FiaWwiLCAiU2NoVHlwIiwgIkFjYWRBY2giKSwgYygiUmFjZSIsICJTRVMiLCAiQ29nQWJpbCIsICJTY2hUeXAiLCAiQWNhZEFjaCIpKQ0KcHJpdlNjaG9vbC5jb3INCmBgYA0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAyRXgyYSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKkNvcnJlbGFjaW9uZXMgKG4gPSAxOCwwNTgpKioiLCBvdXQud2lkdGggPSAiODAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwMkV4MmEucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KDQoNCkVsIHBhdGggbW9kZWwgZXM6IA0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAyRXgyYiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhdGggbW9kZWwqKiIsIG91dC53aWR0aCA9ICI4MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQmVhdWplYW5DYXAyRXgyYi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQooYSkgQ3JlYXIgZWwgbW9kZWxvIGRlIHRyYXllY3RvcmlhcyB1dGlsaXphbmRvIGBsYXZhYW5gLiBBc2Vnw7pyZXNlIGRlIGV0aXF1ZXRhciBsb3MgbWlzbW9zIHBhcsOhbWV0cm9zIHF1ZSBlbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwMkV4MmIpLg0KDQooYikgUmVhbGl6YXIgZWwgYW7DoWxpc2lzIGRlIHBhdGggbW9kZWwgY29ycmVzcG9uZGllbnRlLiBJbnRlcnByZXRlIHRvZG9zIGxvcyByZXN1bHRhZG9zIHBvc2libGVzLg0KDQooYykgwr9DdcOhbCBlcyBsYSByZWxhY2nDs24gZW50cmUgZWwgdGlwbyBkZSBlc2N1ZWxhIHkgZWwgcmVuZGltaWVudG8gYWNhZMOpbWljbyAoZXMgZGVjaXIsDQpjYW1pbm8gaik/DQoNCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KI0V4ZXJjaXNlIDIuMi5hDQpmdWxsLm1vZGVsIDwtICcNCkFjYWRBY2ggfiBqKlNjaFR5cCArIGcqU0VTICsgZCpSYWNlICsgaSpDb2dBYmlsDQpTY2hUeXAgfiBmKlNFUyArIGIqUmFjZSArIGgqQ29nQWJpbA0KQ29nQWJpbCB+IGUqU0VTICsgYypSYWNlDQpTRVMgfiBhKlJhY2UNCicNCg0KI0V4ZXJjaXNlIDIuMi5iDQpmdWxsLmZpdCA8LSBzZW0oZnVsbC5tb2RlbCwgc2FtcGxlLmNvdj1wcml2U2Nob29sLmNvciwgc2FtcGxlLm5vYnM9MTgwNTgpDQpzdW1tYXJ5KGZ1bGwuZml0KQ0KDQojRXhlcmNpc2UgMi4yLmMNCnBhcmFtZXRlckVzdGltYXRlcyhmdWxsLmZpdCkNCg0KI0VsIGNhbWlubyBqIHRpZW5lIHVuIHZhbG9yIGRlIDAsMDIyLiBEYWRvIHF1ZSBsYSBlbnRyYWRhIGVyYSB1bmEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMsIGVzdG8gaW5kaWNhIHF1ZSwgcG9yIHTDqXJtaW5vIG1lZGlvLCBsb3MgcmVzdWx0YWRvcyBhY2Fkw6ltaWNvcyBkZSBsYXMgZXNjdWVsYXMgcHJpdmFkYXMgc29uIGFwcm94aW1hZGFtZW50ZSAwLDAyMiBkZXN2aWFjaW9uZXMgZXN0w6FuZGFyIG3DoXMgYWx0b3MgcXVlIGxvcyBkZSBsYXMgZXNjdWVsYXMgcMO6YmxpY2FzLg0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gMw0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDIuMywgcGFnaW5hIDM0LiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTcyDQpgYGANCg0KTWFjS2lubm9uICgyMDA4LCBwLiAxMTMpIHByb3BvcmNpb25hIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHVuIGVzdHVkaW8gaGlwb3TDqXRpY28gc29icmUgbGFzIGV4cGVjdGF0aXZhcyBkZSBsb3MgcHJvZmVzb3JlcyByZXNwZWN0byBhbCByZW5kaW1pZW50byBkZSBsb3MgYWx1bW5vcy4NCnkgZWwgcmVuZGltaWVudG8gZGUgbG9zIGFsdW1ub3MuIFN1IG1vZGVsbyBkZSB0cmF5ZWN0b3JpYSBzZSBtdWVzdHJhIGVuIGxhIEZpZ3VyYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwMkV4M2EpICB5IGxhcyBjb3ZhcmlhbnphcyBkZWwgbW9kZWxvIHNlIGluZGljYW4gZW4gbGEgRmlndXJhICBcQHJlZihmaWc6QmVhdWplYW5DYXAyRXgzYikuDQoNCkVsIHBhdGggbW9kZWwgZXM6DQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDJFeDNhLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGF0aCBtb2RlbCoqIiwgb3V0LndpZHRoID0gIjgwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDJFeDNhLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCkVsIGPDs2RpZ28gUiBwYXJhIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBlczogDQoNCmBgYHtyfQ0KbGlicmFyeShsYXZhYW4pDQpwcml2U2Nob29sLmNvciA8LSBjKDEsIDAuMTc4LCAwLjIzLCAwLjEwNiwgMC4xOTUsIDEsIDAuMzI3LCAwLjI0NSwgMC4zNTYsIDEsIDAuMTgzLCAwLjcyMSwgMSwgMC4xNzgsIDEpDQpwcml2U2Nob29sLmNvciA8LSBsYXZfbWF0cml4X3VwcGVyMmZ1bGwocHJpdlNjaG9vbC5jb3IpDQojcHJpdlNjaG9vbC5jb3IgPC0gbGF2X21hdHJpeF9sb3dlcjJmdWxsKHByaXZTY2hvb2wuY29yKQ0KZGltbmFtZXMocHJpdlNjaG9vbC5jb3IpIDwtIGxpc3QoYygiUmFjZSIsICJTRVMiLCAiQ29nQWJpbCIsICJTY2hUeXAiLCAiQWNhZEFjaCIpLCBjKCJSYWNlIiwgIlNFUyIsICJDb2dBYmlsIiwgIlNjaFR5cCIsICJBY2FkQWNoIikpDQpwcml2U2Nob29sLmNvcg0KYGBgDQoNCg0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAyRXgzYiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKkNvdmFyaWFuemFzIChuID0gNDApKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDJFeDNiLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCihhKSBJbnRyb2R1emNhIGxhcyBjb3ZhcmlhbnphcyBlbiBSLg0KDQooYikgRXNjcmliYSBsYSBzaW50YXhpcyBkZWwgbW9kZWxvLiBVdGlsaWNlIGVsIG9wZXJhZG9yIGA6PWAgcGFyYSBkZWZpbmlyIGxvcyBkb3MgZWZlY3RvcyBpbmRpcmVjdG9zIGRlIGxhcyBleHBlY3RhdGl2YXMgZGVsIHByb2Zlc29yIHNvYnJlIGVsIHJlbmRpbWllbnRvIGRlbCBhbHVtbm86IGAoYTEpKGIxKWAgeSBgKGEyKShiMilgLiANCg0KKGMpIMK/Q3XDoWxlcyBzb24gbG9zIGVmZWN0b3MgaW5kaXJlY3Rvcz8NCg0KKGMpIFJlYWxpY2UgZWwgYW7DoWxpc2lzIGRlIHBhdGggbW9kZWwgY29ycmVzcG9uZGllbnRlLiANCg0KKGQpIEludGVycHJldGUgdG9kb3MgbG9zIHJlc3VsdGFkb3MgcG9zaWJsZXMuDQoNCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShsYXZhYW4pDQoNCiNFeGVyY2lzZSAyLjMuYQ0KbWFja2lubm9uLmNvdiA8LSBsYXZfbWF0cml4X2xvd2VyMmZ1bGwoYyg4NC44NSw3MS4yOCwxNDAuMzQsMTguODMsLTYuMjUsNzIuOTIsNjAuMDUsODQuNTQsMzcuMTgsIDEzOS40OCkpDQpyb3duYW1lcyhtYWNraW5ub24uY292KSA8LSBjb2xuYW1lcyhtYWNraW5ub24uY292KSA8LQ0KYygiVGVhY2hFeHAiLCAiU29jQ2xpbSIsICJNYXRDb3YiLCAiU3RBY2giKQ0KDQojRXhlcmNpc2UgMi4zLmINCm1hY2tpbm5vbi5tb2RlbCA8LSAnDQpTdEFjaCB+IGIxKlNvY0NsaW0gKyBiMipNYXRDb3YgKyBjKlRlYWNoRXhwDQpNYXRDb3YgfiBhMipUZWFjaEV4cA0KU29jQ2xpbSB+IGExKlRlYWNoRXhwDQppbmQxIDo9IGExKmIxDQppbmQyIDo9IGEyKmIyDQonDQojRXhlcmNpc2UgMi4zLmMNCm1hY2tpbm5vbi5maXQgPC0gc2VtKG1hY2tpbm5vbi5tb2RlbCwgc2FtcGxlLmNvdiA9IG1hY2tpbm5vbi5jb3YsIHNhbXBsZS5ub2JzID0gNDApDQpzdW1tYXJ5KG1hY2tpbm5vbi5maXQsIHN0YW5kYXJkaXplZCA9IFRSVUUpDQoNCiNFbCBlZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgY2xpbWEgc29jaWFsIGVzIGRlIDAsNDc4LiBFbCBlZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgbWF0ZXJpYWwgY3ViaWVydG8gZXMgZGUgMCwxMTguDQojDQojRWZlY3RvIGluZGlyZWN0byBhIHRyYXbDqXMgZGVsIGNsaW1hIHNvY2lhbCAoU29jQ2xpbSk6DQoNCiNFbCBlZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgY2xpbWEgc29jaWFsIGVzIGRlIDAuNDc4LiBFc3RvIHNpZ25pZmljYSBxdWUgbGEgZXhwZXJpZW5jaWEgZGVsIG1hZXN0cm8gdGllbmUgdW4gaW1wYWN0byBwb3NpdGl2byBzaWduaWZpY2F0aXZvIGVuIGVsIGNsaW1hIHNvY2lhbCBkZSBsYSBjbGFzZSwgeSBlc3RlIGNsaW1hIHNvY2lhbCwgYSBzdSB2ZXosIG1lam9yYSBzaWduaWZpY2F0aXZhbWVudGUgZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUuIEVuIHTDqXJtaW5vcyBtw6FzIGNvbmNyZXRvcywgcG9yIGNhZGEgdW5pZGFkIGRlIGF1bWVudG8gZW4gbGEgZXhwZXJpZW5jaWEgZGVsIG1hZXN0cm8sIGhheSB1biBpbmNyZW1lbnRvIGVzcGVyYWRvIGRlIDAuNDc4IHVuaWRhZGVzIGVuIGVsIGxvZ3JvIGRlbCBlc3R1ZGlhbnRlLCBtZWRpYWRvIHBvciBlbCBjbGltYSBzb2NpYWwuDQoNCiNFZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgbWF0ZXJpYWwgY3ViaWVydG8gKE1hdENvdik6DQoNCiNFbCBlZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgbWF0ZXJpYWwgY3ViaWVydG8gZXMgZGUgMC4xMTguIEVzdG8gc3VnaWVyZSBxdWUgbGEgZXhwZXJpZW5jaWEgZGVsIG1hZXN0cm8gdGFtYmnDqW4gY29udHJpYnV5ZSBhIGxhIGNhbnRpZGFkIGRlIG1hdGVyaWFsIGN1YmllcnRvIGVuIGNsYXNlLCB5IGVzdGUgbWF0ZXJpYWwgY3ViaWVydG8gYWRpY2lvbmFsbWVudGUgbWVqb3JhIGVsIGxvZ3JvIGRlbCBlc3R1ZGlhbnRlLiBBc8OtLCBwb3IgY2FkYSB1bmlkYWQgZGUgYXVtZW50byBlbiBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybywgaGF5IHVuIGluY3JlbWVudG8gZXNwZXJhZG8gZGUgMC4xMTggdW5pZGFkZXMgZW4gZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUsIG1lZGlhZG8gcG9yIGxhIGNhbnRpZGFkIGRlIG1hdGVyaWFsIGN1YmllcnRvLg0KDQojSW50ZXJwcmV0YWNpw7NuIGRlbCBtb2RlbG8gY29tcGxldG86DQoNCiNFbCBtb2RlbG8gZXNwZWNpZmljYSBxdWUgZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUgKFN0QWNoKSBlcyBkaXJlY3RhbWVudGUgaW5mbHVlbmNpYWRvIHBvciBlbCBjbGltYSBzb2NpYWwgKFNvY0NsaW0pLCBsYSBjYW50aWRhZCBkZSBtYXRlcmlhbCBjdWJpZXJ0byAoTWF0Q292KSB5IGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvIChUZWFjaEV4cCkuIEFkZW3DoXMsIGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvIHRhbWJpw6luIGluZmx1eWUgaW5kaXJlY3RhbWVudGUgZW4gZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUgYSB0cmF2w6lzIGRlbCBjbGltYSBzb2NpYWwgeSBlbCBtYXRlcmlhbCBjdWJpZXJ0by4NCg0KI0xvcyBlZmVjdG9zIGluZGlyZWN0b3MgcHJvcG9yY2lvbmFuIHVuIGVudGVuZGltaWVudG8gbcOhcyBjb21wbGV0byBkZSBjw7NtbyBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybyBpbXBhY3RhIGVsIGxvZ3JvIGRlbCBlc3R1ZGlhbnRlLCBkZXN0YWNhbmRvIGxhIGltcG9ydGFuY2lhIGRlIGNyZWFyIHVuIGJ1ZW4gY2xpbWEgc29jaWFsIHkgY3VicmlyIGFkZWN1YWRhbWVudGUgZWwgbWF0ZXJpYWwuDQoNCiNFbiByZXN1bWVuLCBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybyBubyBzb2xvIHRpZW5lIHVuIGVmZWN0byBkaXJlY3RvIHNvYnJlIGVsIGxvZ3JvIGRlbCBlc3R1ZGlhbnRlLCBzaW5vIHF1ZSB0YW1iacOpbiB0aWVuZSBlZmVjdG9zIGluZGlyZWN0b3Mgc2lnbmlmaWNhdGl2b3MgYSB0cmF2w6lzIGRlIHN1IGluZmx1ZW5jaWEgZW4gZWwgY2xpbWEgc29jaWFsIGRlIGxhIGNsYXNlIHkgbGEgY2FudGlkYWQgZGUgbWF0ZXJpYWwgY3ViaWVydG8uIEVzdG9zIGhhbGxhemdvcyBzdWJyYXlhbiBsYSBpbXBvcnRhbmNpYSBkZSBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybyBlbiBtZWpvcmFyIGVsIGFtYmllbnRlIGRlIGFwcmVuZGl6YWplIHkgZWwgY29udGVuaWRvIGVkdWNhdGl2bywgbG8gcXVlIGVuIMO6bHRpbWEgaW5zdGFuY2lhIGNvbmR1Y2UgYSBtZWpvcmVzIHJlc3VsdGFkb3MgYWNhZMOpbWljb3MgcGFyYSBsb3MgZXN0dWRpYW50ZXMuDQoNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRWplcmNpY2lvIDQNCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiNodHRwczovL2Jsb2dzLmJheWxvci5lZHUvcmxhdGVudHZhcmlhYmxlL3NhbXBsZS1wYWdlL2RhdGEvDQojDQojQmVhdWplYW4sIGVqZXJjaWNpbyAzLjEsIHBhZ2luYSA1Mi4gU29sdWNpb24gZW4gcGFnaW5hIDE3Mw0KYGBgDQoNCg0KVW1zdGF0dGQtTWV5ZXIsIEphbmtlIHkgQmVhdWplYW4gKDIwMTMpIG1pZGllcm9uIGxhIHNhbHVkIHBzaWNvc29jaWFsIGRlZmljaWVudGUgY29tbyB1biBtb2RlbG8gZGUgZmFjdG9yIMO6bmljbyB1dGlsaXphbmRvIHRyZXMgZmFjZXRhcyBkZSDDrXRlbXMgZGUgdW4gY3Vlc3Rpb25hcmlvIGRlIGRlcHJlc2nDs24geSB1bmEgbWVkaWRhIGRlIGxhIGFjdGl2aWRhZCBzb2NpYWwuIExhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIHNlIG11ZXN0cmEgZW4gbGEgRmlndXJhIFxAcmVmKGZpZzpCZWF1amVhbkNhcDNFeDEpLg0KDQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDNFeDEsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipDb3ZhcmlhbnphcyAobiA9IDYwNTMpKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDNFeDEucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KQWRlbcOhcywgY29uc2lkZXJlIGVsIHNpZ3VpZW50ZSBtb2RlbG8uDQoNCioqTW9kZWxvIDEuKiogDQoNCmBgYHtyfQ0KbWFya2VyLm1vZGVsIDwtICcNClBzeWNoU29jTFYgPX4gRGVwLjEgKyBEZXAuMiArIERlcC4zICsgU29jQWN0aXZpdHkNCicNCmBgYA0KDQpSZWFsaXphciBsb3Mgc2lndWllbnRlcyBpbmNpc29zOg0KDQphKSBJbnRyb2R1emNhIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBlbiBSLg0KDQpiKSBDb24gbGEgZnVuY2nDs24gYGNmYWAgZGUgYGxhdmFhbmAgKHNpbiBhZ3JlZ2FyIGVsIGFyZ3VtZW50byBgc3RkLmx2PS4uLmApIHkgdXRpbGl6YW5kbyB2YXJpYWJsZXMgbGF0ZW50ZXMgbm8gZXN0YW5kYXJpemFkYXMsIGFqdXN0ZSBlbCBtb2RlbG8gMS4gU3VnZXJlbmNpYTogdXNlIGVsIGPDs2RpZ28gaGFiaXR1YWwgZGUgYGNmYWAuDQoNCg0KYykgQ29uIGxhIGZ1bmNpw7NuIGBjZmFgIGRlIGBsYXZhYW5gIChhZ3JlZ2FuZG8gZWwgYXJndW1lbnRvIGBzdGQubHY9RkFMU0VgKSB5IHV0aWxpemFuZG8gIHZhcmlhYmxlcyBsYXRlbnRlcyBubyBlc3RhbmRhcml6YWRhcywgYWp1c3RlIGVsIG1vZGVsbyAxLiAgU3VnZXJlbmNpYTogdXNlIGVsIGPDs2RpZ28gaGFiaXR1YWwgZGUgYGNmYWAgY29uIGVsIGFyZ3VtZW50byBtZW5jaW9uYWRvLg0KDQpkKSBDb24gbGEgZnVuY2nDs24gYGNmYWAgZGUgYGxhdmFhbmAgIHkgdXRpbGl6YW5kbyB2YXJpYWJsZXMgbGF0ZW50ZXMgZXN0YW5kYXJpemFkYXMsIGFqdXN0ZSBlbCBtb2RlbG8gMS4gU3VnZXJlbmNpYTogdXNlIGVsIGPDs2RpZ28gaGFiaXR1YWwgZGUgYGNmYWAgYWdyZWdhbmRvIGVsIGFyZ3VtZW50byBgc3RkLmx2PVRSVUVgLg0KDQplKSBWZXJpZmlxdWUgcXVlIGxvcyB2YWxvcmVzIHJlc3VsdGFudGVzIGRlICRcY2hpXjIkIHkgJGRmJCBzb24gaWTDqW50aWNvcyBwYXJhIHRvZG9zIGxvcyBtw6l0b2Rvcy4gSW52ZXN0aWd1ZSBsYSByYXrDs24uIA0KDQpmKSDCv1kgZWwgbsO6bWVybyBkZSBwYXLDoW1ldHJvcyBkZWwgbW9kZWw/IMK/U29uIGlndWFsZXMgZW4gdG9kb3MgbG9zIG1vZGVsb3M/IElkZW50aWbDrXF1ZWxvcyBlbiBjYWRhIHVubyBkZSBlbGxvcy4NCg0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGxhdmFhbikNCg0KI0V4ZXJjaXNlIDMuMS5hDQpwc3ljaFNvYy5jb3YgPC0gYygwLjc3LCAwLjM4LCAwLjY1LCAwLjM5LCAwLjM5LCAwLjYyLCAtMC4yNSwgLTAuMzIsIC0wLjI3LCA2LjA5KQ0KcHN5Y2hTb2MuY292IDwtIGxhdl9tYXRyaXhfbG93ZXIyZnVsbChwc3ljaFNvYy5jb3YpDQpyb3duYW1lcyhwc3ljaFNvYy5jb3YpIDwtIGNvbG5hbWVzKHBzeWNoU29jLmNvdikgPC0gYygiRGVwLjEiLCAiRGVwLjIiLCAiRGVwLjMiLCAiU29jQWN0aXZpdHkiKQ0KDQojRXhlcmNpc2UgMy4xLmINCiMgbWFya2VyIHZhcmlhYmxlDQptYXJrZXIubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBEZXAuMSArIERlcC4yICsgRGVwLjMgKyBTb2NBY3Rpdml0eQ0KJw0KbWFya2VyLmZpdEEgPC0gY2ZhKG1hcmtlci5tb2RlbCwgc2FtcGxlLmNvdj1wc3ljaFNvYy5jb3YsIHNhbXBsZS5ub2JzPTYwNTMpDQpzdW1tYXJ5KG1hcmtlci5maXRBKQ0KDQojRXhlcmNpc2UgMy4xLmMNCiMgbWFya2VyIHZhcmlhYmxlDQoNCm1hcmtlci5maXRCPC0gY2ZhKG1hcmtlci5tb2RlbCwgc3RkLmx2PUZBTFNFLCBzYW1wbGUuY292PXBzeWNoU29jLmNvdiwgc2FtcGxlLm5vYnM9NjA1MykNCnN1bW1hcnkobWFya2VyLmZpdEIpDQoNCg0KI0V4ZXJjaXNlIDMuMS5kDQojIHN0YW5kYXJkaXplZCBsYXRlbnQgdmFyaWFibGUNCiMgbWV0aG9kIDENCnN0ZExWLmZpdDEgPC0gY2ZhKG1hcmtlci5tb2RlbCwgc2FtcGxlLmNvdj1wc3ljaFNvYy5jb3YsIHN0ZC5sdj1UUlVFLCBzYW1wbGUubm9icz02MDUzKQ0Kc3VtbWFyeShzdGRMVi5maXQxKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gNQ0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KIw0KI0JlYXVqZWFuLCBlamVyY2ljaW8gMy4xLCBwYWdpbmEgNTIuIFNvbHVjaW9uIGVuIHBhZ2luYSAxNzMNCmBgYA0KDQoqKkNvbnRpbnVhY2nDs24gZGVsIGVqZXJjaWNpbyA0KiouIENvbnNpZGVyZSBsYSBzaXR1YWNpw7NuIGRlbCBlamVyY2ljaW8gNCB5IGxvcyBzaWd1aWVudGVzIGRvcyBtb2RlbG9zIChtb2RlbG9zIDIgeSAzKS4NCg0KKipNb2RlbG8gMi4qKiANCg0KT2JzZXJ2ZSBxdWUsIGVuIGVzdGUgbW9kZWxvLCBzZSB1dGlsaXphIGBEZXByZXNzaW9uIDFgIGNvbW8gdmFyaWFibGUgbWFyY2Fkb3JhLg0KDQpgYGB7cn0NCnN0ZExWLm1vZGVsIDwtICcNClBzeWNoU29jTFYgPX4gTkEqRGVwLjEgKyBEZXAuMSArIERlcC4yICsgRGVwLjMgKyBTb2NBY3Rpdml0eQ0KUHN5Y2hTb2NMVn5+MSpQc3ljaFNvY0xWDQonDQpgYGANCg0KKipNb2RlbG8gMy4qKiANCg0KT2JzZXJ2ZSBxdWUsIGVuIGVzdGUgbW9kZWxvLCBzZSB1dGlsaXphOg0KICANCiAgKyBDb21vIHZhcmlhYmxlIG1hcmNhZG9yYSBhIGBEZXByZXNzaW9uIDFgLiANCiAgDQogICsgRWwgbcOpdG9kbyBkZSBsYSBjb2RpZmljYWNpw7NuIGRlIGVmZWN0b3MgKHBvcnF1ZSBsYSBzdW1hIGRlIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgZXMgaWd1YWwgYWwgbsO6bWVybyBkZSB2YXJpYWJsZXMgaW5kaWNhZG9yYXMgw7puaWNhcykuDQoNCmBgYHtyfQ0KZWMubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBOQSpEZXAuMSArIGEqRGVwLjEgKyBiKkRlcC4yICsgYypEZXAuMyArIGQqU29jQWN0aXZpdHkNCmErYitjK2Q9PTQNCicNCmBgYA0KDQpSZWFsaXphciBsb3Mgc2lndWllbnRlcyBpbmNpc29zOg0KDQpnKSBDb24gbGEgZnVuY2nDs24gYGNmYWAgZGUgYGxhdmFhbmAgKHNpbiBhZ3JlZ2FyIGVsIGFyZ3VtZW50byBgc3RkLmx2PS4uLmApLCBhanVzdGUgZWwgbW9kZWxvIDIuICBTdWdlcmVuY2lhOiB1c2UgZWwgY8OzZGlnbyBoYWJpdHVhbCBkZSBgY2ZhYC4NCg0KDQpoKSBDb24gbGEgZnVuY2nDs24gYGNmYWAgZGUgYGxhdmFhbmAgKHNpbiBhZ3JlZ2FyIGVsIGFyZ3VtZW50byBgc3RkLmx2PS4uLmApLCBhanVzdGUgZWwgbW9kZWxvIDMuICBTdWdlcmVuY2lhOiB1c2UgZWwgY8OzZGlnbyBoYWJpdHVhbCBkZSBgY2ZhYC4NCg0KaSkgVmVyaWZpcXVlIHF1ZSBsb3MgdmFsb3JlcyByZXN1bHRhbnRlcyBkZSAkXGNoaV4yJCB5ICRkZiQgc29uIGlkw6ludGljb3MgcGFyYSB0b2RvcyBsb3MgbcOpdG9kb3MgZXZhbHVhZG9zIHRhbnRvIGVuIGVsIGVqZXJjaWNpbyA0IGNvbW8gZW4gZWwgNS4gSW52ZXN0aWd1ZSBsYSByYXrDs24uIA0KDQpqKSDCv1kgZWwgbsO6bWVybyBkZSBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvPyDCv1NvbiBpZ3VhbGVzIGVuIHRvZG9zIGxvcyBtb2RlbG9zPyBJZGVudGlmw61xdWVsb3MgZW4gY2FkYSB1bm8gZGUgZWxsb3MuIA0KDQpgYGB7ciBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShsYXZhYW4pDQoNCiNFeGVyY2lzZSAzLjEuYQ0KcHN5Y2hTb2MuY292IDwtIGMoMC43NywgMC4zOCwgMC42NSwgMC4zOSwgMC4zOSwgMC42MiwgLTAuMjUsIC0wLjMyLCAtMC4yNywgNi4wOSkNCnBzeWNoU29jLmNvdiA8LSBsYXZfbWF0cml4X2xvd2VyMmZ1bGwocHN5Y2hTb2MuY292KQ0Kcm93bmFtZXMocHN5Y2hTb2MuY292KSA8LSBjb2xuYW1lcyhwc3ljaFNvYy5jb3YpIDwtIGMoIkRlcC4xIiwgIkRlcC4yIiwgIkRlcC4zIiwgIlNvY0FjdGl2aXR5IikNCg0KDQojRXhlcmNpc2UgMy4xLmcNCiMgc3RhbmRhcmRpemVkIGxhdGVudCB2YXJpYWJsZQ0KIyMgbWV0aG9kIDINCnN0ZExWLm1vZGVsIDwtICcNClBzeWNoU29jTFYgPX4gTkEqRGVwLjEgKyBEZXAuMSArIERlcC4yICsgRGVwLjMgKyBTb2NBY3Rpdml0eQ0KUHN5Y2hTb2NMVn5+MSpQc3ljaFNvY0xWDQonDQpzdGRMVi5maXQyIDwtIGNmYShzdGRMVi5tb2RlbCwgc2FtcGxlLmNvdj1wc3ljaFNvYy5jb3YsIHNhbXBsZS5ub2JzPTYwNTMpDQpzdW1tYXJ5KHN0ZExWLmZpdDIpDQoNCiNFeGVyY2lzZSAzLjEuaA0KIyBlZmZlY3RzLWNvZGluZw0KZWMubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBOQSpEZXAuMSArIGEqRGVwLjEgKyBiKkRlcC4yICsgYypEZXAuMyArIGQqU29jQWN0aXZpdHkNCmErYitjK2Q9PTQNCicNCmVjLmZpdCA8LSBjZmEoZWMubW9kZWwsIHNhbXBsZS5jb3Y9cHN5Y2hTb2MuY292LCBzYW1wbGUubm9icz02MDUzKQ0Kc3VtbWFyeShlYy5maXQpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gNg0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDMuMiwgcGFnaW5hIDUyLiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTczDQpgYGANCg0KRWwgbW9kZWxvIGRlbCBFamVyY2ljaW8gYW50ZXJpb3IgZm9ybWFiYSBwYXJ0ZSBkZSB1biBTRU0gbcOhcyBhbXBsaW8sIHBhcnRlIGRlbCBjdWFsIHNlIG11ZXN0cmEgZW4gbGEgRmlndXJhIFxAcmVmKGZpZzpCZWF1amVhbkNhcDNFeDJhKS4gTGEgbWF0cml6IGRlIGNvdmFyaWFuemEgY29tcGxldGEgc2UgbXVlc3RyYSBlbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwM0V4MmIpLg0KDQoNCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwM0V4MmEsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXRoIG1vZGVsKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDNFeDJhLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCg0KTGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVzOiANCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwM0V4MmIsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipDb3ZhcmlhbnphcyAobiA9IDYwNTMpKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDNFeDJiLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCihhKSBJbnRyb2R1emNhIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIGVuIFIuDQoNCihiKSBBanVzdGUgZWwgbW9kZWxvIFNFTSBhIGxvcyBkYXRvcy4gwr9MYSBzYWx1ZCBwc2ljb3NvY2lhbCB5IGxhIHNhbHVkIGbDrXNpY2EgcHJlZGljZW4gbGEgbW92aWxpZGFkIHBlcnNvbmFsPyBTdWdlcmVuY2lhOiBhcGxpcXVlIGxhIGZ1bmNpw7NuIGBzZW1gIGRlIGBsYXZhYW5gLiANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShsYXZhYW4pDQoNCiNFeGVyY2lzZSAzLjIuYQ0KbW9iaWxpdHkuY292IDwtIGMoMC43NyAsIDAuMzggLCAwLjY1ICwgMC4zOSAsIDAuMzkgLCAwLjYyLCAtMC4yNSwgLTAuMzIsIC0wLjI3ICwgNi4wOSwgMC4zMSwgMC4yOSAsIDAuMjYsIC0wLjM2ICwgNy42NyAsIDAuMjQgLCAwLjI1ICwgMC4xOSwgLTAuMTgsIDAuNTEsIDEuNjksIC0zLjE2LCAtMy41NiwgLTIuNjMgLCA2LjA5LCAtMy4xMiwgLTQuNTgsIDIwNC43OSwgLTAuOTIsIC0wLjg4LCAtMC43MiAsIDAuODgsIC0xLjQ5LCAtMS40MSwgMTYuNTMsIDcuMjQpDQptb2JpbGl0eS5jb3YgPC0gbGF2X21hdHJpeF9sb3dlcjJmdWxsKG1vYmlsaXR5LmNvdikNCnJvd25hbWVzKG1vYmlsaXR5LmNvdikgPC0gY29sbmFtZXMobW9iaWxpdHkuY292KSA8LSBjKCJEZXAuMSIsICJEZXAuMiIsICJEZXAuMyIsICJTb2NBY3Rpdml0eSIsICJGYWxscyIsICJDaHJvbmljIiwgIlRvdEFjdGl2aXR5IiwgIlBlcnNNb2JpbGl0eSIpDQoNCiNFeGVyY2lzZSAzLjIuYg0KbW9iaWxpdHkubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBEZXAuMSArIERlcC4yICsgRGVwLjMgKyBTb2NBY3Rpdml0eQ0KUHN5SGVhbHRoTFYgPX4gRmFsbHMgKyBDaHJvbmljICsgVG90QWN0aXZpdHkNClBlcnNNb2JpbGl0eSB+IFBzeWNoU29jTFYgKyBQc3lIZWFsdGhMVg0KJw0KbW9iaWxpdHkuZml0IDwtIHNlbShtb2JpbGl0eS5tb2RlbCwgc2FtcGxlLmNvdj1tb2JpbGl0eS5jb3YsIHNhbXBsZS5ub2JzPTYwNTMpDQpzdW1tYXJ5KG1vYmlsaXR5LmZpdCwgZml0Lm1lYXN1cmVzPVRSVUUsIHN0YW5kYXJkaXplZD1UUlVFKQ0KDQojUGh5c2ljYWwgaGVhbHRoICgtMC45MTQpIGFwcGVhcnMgdG8gYmUgYSBzdHJvbmdlciBwcmVkaWN0b3Igb2YgcGVyc29uYWwgbW9iaWxpdHkgdGhhbiBwc3ljaG9zb2NpYWwgaGVhbHRoICgwLjEwMSkuDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRWplcmNpY2lvIDcNCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkobGF2YWFuKQ0KbGF2X21hdHJpeF8NCg0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDMuMywgcGFnaW5hIDU0LiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTc0DQpgYGANCg0KDQpHcmFoYW0gKDIwMDgpIG1vc3Ryw7MgY8OzbW8gZWwgU0VNIHB1ZWRlIHV0aWxpemFyc2UgcGFyYSBhbmFsaXphciB1bmEgdmFyaWVkYWQgZGUgbW9kZWxvcyBsaW5lYWxlcyBnZW5lcmFsZXMuIGxpbmVhbGVzIGdlbmVyYWxlcy4gU3UgZWplbXBsbyBkZSBhbsOhbGlzaXMgZGVzY3JpcHRpdm8gZGlzY3JpbWluYW50ZSAoRERBKSB1dGlsaXphIHZhcmlhYmxlcyBsYXRlbnRlcyBmb3JtYXRpdmFzLiBFbCBEREEgZXMgdW4gcHJvY2VkaW1pZW50byBxdWUgZGVzY3JpYmUgbGFzIGRpZmVyZW5jaWFzIGVudHJlIG3Dumx0aXBsZXMgZ3J1cG9zIGVuIG3Dumx0aXBsZXMgZGVzY3JpcHRvcmVzIGNvbnRpbnVvczogdW5hIHJlZ3Jlc2nDs24gbcO6bHRpcGxlIGVudHJlIGRvcyBvIG3DoXMgZ3J1cG9zLiBFbiBEREEsIGxhIHZhcmlhYmxlIGxhdGVudGUgZGUgaW50ZXLDqXMgc2UgZGVub21pbmEgZnVuY2nDs24gZGlzY3JpbWluYW50ZS4gVW4gcGF0aCBtb2RlbCBkZWwgRERBIHNlIG11ZXN0cmEgZW4gbGEgRmlndXJhICBcQHJlZihmaWc6QmVhdWplYW5DYXAzRXgzYSkgeSBsb3MgZGF0b3MgcGFyYSBlbCBtb2RlbG8gc2UgZGFuIGVuIGxhIEZpZ3VyYSAgIFxAcmVmKGZpZzpCZWF1amVhbkNhcDNFeDNiKS4NCg0KRWwgcGF0aCBtb2RlbCBlczoNCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwM0V4M2EsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXRoIG1vZGVsIGRlbCBEREEqKiIsIG91dC53aWR0aCA9ICI3MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQmVhdWplYW5DYXAzRXgzYS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCkxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBlczogDQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDNFeDNiLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqQ292YXJpYW56YXMgKG4gPSAyODgpKioiLCBvdXQud2lkdGggPSAiNDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwM0V4M2IucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KUmVhbGl6YXIgbG9zIHNpZ3VpZW50ZXMgaW5jaXNvczoNCg0KKGEpIEltcG9ydGUgYSBSIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyB5IGVsIHZlY3RvciBkZSBtZWRpYXMuDQoNCihiKSBFc2NyaWJhIGxhIHNpbnRheGlzIGBsYXZhYW5gIHBhcmEgbGEgRmlndXJhIFxAcmVmKGZpZzpCZWF1amVhbkNhcDNFeDNhKS4gU3VnZXJlbmNpYTogZWwgcGF0aCBgYT0xYCBzZSBlc2NyaWJlIGNvbW8gYDEqRFYxICsgYSpEVjFgIGVuIGxhIHNpbnRheGlzIGRlIGBsYXZhYW5gLg0KDQooYykgT2J0ZW5nYSBsb3MgY29lZmljaWVudGVzIGRlIGZ1bmNpw7NuIChjb2VmaWNpZW50ZXMgZXN0YW5kYXJpemFkb3MgcGFyYSBhIHkgYiksIGNvcnJlbGFjacOzbiBjYW7Ds25pY2EgKGNvZWZpY2llbnRlIGVzdGFuZGFyaXphZG8gcGFyYSBjKSwgeSAkUl4yJCAoY29lZmljaWVudGUgbm9ybWFsaXphZG8gcGFyYSBkKS4gU3VnZXJlbmNpYTogYXBsaXF1ZSBsYSBmdW5jacOzbiBgc2VtYCBkZSBgbGF2YWFuYC4gDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCmxpYnJhcnkobGF2YWFuKQ0KDQojRXhlcmNpc2UgMy4zLmENCmRkYS5jb3YgPC0gbGF2X21hdHJpeF9sb3dlcjJmdWxsKGMoNTkuNjYsIDExLjE4LCAyMi4zLCAyLjYzLCAwLjQxLCAxKSwgZGlhZ29uYWwgPSBUUlVFKQ0Kcm93bmFtZXMoZGRhLmNvdikgPC0gY29sbmFtZXMoZGRhLmNvdikgPC0gYygiRFYxIiwgIkRWMiIsICJDYXQxIikNCmRkYS5jb3YNCg0KI0V4ZXJjaXNlIDMuMy5iDQpkZGEubW9kZWw8LScNCkYxIDx+IDEqRFYxICsgYSpEVjEgKyBiKkRWMg0KDQojUmVncmVzacOzbiBkZSBDYXQxIHNvYnJlIEYxOg0KQ2F0MSB+IGMqRjENCg0KI1ZhcmlhbnphIGRlIENhdDE6DQpDYXQxfn5kKkNhdDENCicNCiNFeGVyY2lzZSAzLjMuYw0KZGRhLmZpdCA8LSBzZW0oZGRhLm1vZGVsLCBzYW1wbGUuY292ID0gZGRhLmNvdiwgc2FtcGxlLm5vYnMgPSAyODgpDQpwYXJhbWV0ZXJFc3RpbWF0ZXMoZGRhLmZpdCwgc3RhbmRhcmRpemVkID0gVFJVRSkNCg0KI1RoZSBmdW5jdGlvbiBjb2VmZmljaWVudHMgYXJlIGE9MS4wMTYgIGFuZCBiPS0wLjA1NywgdGhlIGNhbm9uaWNhbCBjb3JyZWxhdGlvbiBpcyBjPTAuMzQxLCBhbmQgUjIgaXMgMC4xMTYgKGkuZS4sIDEg4oiSIDAuODg0KQ0KYGBgDQoNCg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gQ2Fww610dWxvIEJpYmxpb2dyYWbDrWEtLT4NCg0KDQojIEJpYmxpb2dyYWbDrWEgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCiAgDQpDb25zdWx0YXIgZWwgZG9jdW1lbnRvIFtSUHVicyA6OiBBbsOhbGlzaXMgbXVsdGl2YXJpYWRvIChiaWJsaW9ncmFmw61hKV0oaHR0cHM6Ly9ycHVicy5jb20vaGxsaW5hcy9SX011bHRpdmFyaWFkb19CaWJsaW9ncmFmaWEpLg0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KIyBQYWdpbiBXZWIgZGUgQmVhdWplYW4NCiMgDQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gQ2Fww610dWxvIEJpYmxpb2dyYWbDrWEtLT4NCg0KIyBSZWZlcmVuY2lhcyB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpHcmFoYW0sIEouIE0uICgyMDA4KS4gVGhlIGdlbmVyYWwgbGluZWFyIG1vZGVsIGFzIHN0cnVjdHVyYWwgZXF1YXRpb24gbW9kZWxpbmcuIEpvdXJuYWwgb2YgRWR1Y2F0aW9uYWwgYW5kIEJlaGF2aW9yYWwgU3RhdGlzdGljcywgMzMgLCA0ODUtNTA2LiBkb2k6IDEwLjMxMDIvMTA3Njk5ODYwNzMwNjE1MS4NCg0KTWFjS2lubm9uLCBELiBQLiAoMjAwOCkuIEludHJvZHVjdGlvbiB0byBzdGF0aXN0aWNhbCBtZWRpYXRpb24gYW5hbHlzaXMuIE1haHdhaCwgTko6DQpFcmxiYXVtLg0KDQpQYWdlLCBFLiBCLiwgJiBLZWl0aCwgVC4gWi4gKDE5ODEpLiBFZmZlY3RzIG9mIFUuUy4gcHJpdmF0ZSBzY2hvb2xzOiBBIHRlY2huaWNhbCBhbmFseXNpcyBvZiB0d28gcmVjZW50IGNsYWltcy4gRWR1Y2F0aW9uYWwgUmVzZWFyY2hlciwgMTAgLCA3LTE3LiBkb2k6IDEwLjIzMDcvMTE3NDI1Ni4NCg0KVW1zdGF0dGQtTWV5ZXIsIE0uIFIuLCBKYW5rZSwgTS4gQy4sICYgQmVhdWplYW4sIEEuIEEuICgyMDEzKS4gUHJlZGljdG9ycyBvZiBvbGRlciBhZHVsdHPigJkgcGVyc29uYWwgYW5kIGNvbW11bml0eSBtb2JpbGl0eTogVXNpbmcgYSBjb21wcmVoZW5zaXZlIHRoZW9yZXRpY2FsIG1vYmlsaXR5DQpmcmFtZXdvcmsuIFRoZSBHZXJvbnRvbG9naXN0LCBBZHZhbmNlIG9ubGluZSBwdWJsaWNhdGlvbi4gZG9pOiAxMC4xMDkzL2dlcm9udC9nbnQwNTQuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQoNCiZuYnNwOw0KDQoNCiZuYnNwOw0KPGNlbnRlcj4NCn5+fg0KSWYgeW91IGZvdW5kIGFueSBFUlJPUlMgb3IgaGF2ZSBTVUdHRVNUSU9OUywgcGxlYXNlIHJlcG9ydCB0aGVtIHRvIG15IGVtYWlsLiBUaGFua3MuICANCn5+fg0KPC9jZW50ZXI+DQoNCg0K