Capítulo 2: Modelos de Markov ocultos: definición y propiedades

2.1. Un modelo de Markov oculto simple

Considérese nuevamente la serie de terremotos mostrada en el capitulo anterior. Las observaciones son cuentas ilimitadas, haciendo la distribución de Poisson una elección natural para describirlas, pero su distribución es claramente relativa sobre dispersa a la de Poisson. Observamos en el capítulo anterior que este hecho puede ser acomodado al usar una mezcla de distribuciones de Poisson con medias \(λ_1,λ_2,…,λ_m\). La elección de la media esta hecha por un segundo proceso aleatorio, el proceso de parámetro. La media \(λ_i\) es seleccionada con probabilidad \(δ_i\), donde \(i=1,2,…,m\) y \(\sum_{i=1}^mδ_i=1\).

Un modelo de mezcla independiente no resultara con la serie de terremotos porque, por definición, no permite la dependencia serial en las observaciones. La muestra de función de autocorrelación (ACF), desplegada en la Figura 2.1, claramente indica que las observaciones son dependientes en serie. Una manera de permitir la dependencia serial en las observaciones es relajar la suposición que el proceso de parámetro es independiente en serie. Una manera simple y matemáticamente conveniente para hacer esto es asumir que es una cadena de Markov. El modelo resultante para las observaciones es llamado un modelo de Markov oculto de Poisson.

library(forecast)
library(readr)
#leer la data 
data_terremotos_ch2 <- read.table("/Users/bracruz/Documents/8vo. Trimestre IO/Sist. Expertos y Redes Prob./earthquakes.txt")
#Obtener la ACF de la data anterior
ACF_ch2 <- acf(data_terremotos_ch2, plot=TRUE)

Figura 2.1

2.2 Lo básico

2.2.1 Definición y notación

Figura 2.2

Figura 2.2

Un modelo de Markov oculto \({X_t:t ∈N}\) es un tipo particular de mezcla dependiente. Con \(X^t\) y \(C^t\) representando las historias del tiempo 1 al tiempo t, uno puede resumir el modelo más simple de este tipo por:

\[ Pr(C_t | C^{t-1}) = Pr(C_t | C_{t-1}), t=2,3,... \\ Pr(X_t | X^{t-1},C^t) = Pr(X_t | C_t), t ∈ N \] El modelo consiste de dos partes: primero, un “proceso de parámetro” no observado \({C_t:t=1,2,…}\) satisfaciendo la propiedad de Markov; y como segundo, el “proceso estado-dependiente” \({X_t:t=1,2,…}\), en el cual la distribución de \(X_t\) depende solamente en el estado actual \(C_t\) y no de estados u observaciones previas. La estructura se representa en la Figura 2.2

Si la cadena de Markov \({C_t}\) tiene m estados, llamamos \({X_t}\) una HMM de m-estados. Aunque es la terminología usual en aplicaciones de procesamiento del habla, el nombre “modelo de Markov oculto” es por ningún medio el único usado para tales o similares.

Figura 2.3 - Proceso gerenando las observaciones en un estado doble de HMM. Siguiendo la cadena 2,1,1,1,2,1

Figura 2.3 - Proceso gerenando las observaciones en un estado doble de HMM. Siguiendo la cadena 2,1,1,1,2,1

El proceso generando las observaciones es nuevamente demostrado en la Figura anterior, para distribuciones estado-dependientes \(p_1\) y \(p_2\), distribución estacionaria \(δ=(0.75,0.25)\), y t.p.m. \(\Gamma= \left(\begin{array}{cc} 0.9 & 0.1\\ 0.3 & 0.7 \end{array}\right)\). En contraste al caso de una mezcla independiente, aquí la distribución de \(C_t\), el estado en tiempo t, sí depende de \(C_(t-1)\). También es cierto de las mezclas independientes, hay para cada estado una distribución diferente, discreta o continua. Ahora introduciremos una notación la cual cubrirá tanto observaciones valuadas discretas como continuas. En el caso de observaciones discretas, definimos, para \(i=1,2,…,m\)

\[p_i(x) = Pr(X_t = x | C_t = i)\] Esto es, \(p_i\), es la función de probabilidad en masa de \(X_t\) si la cadena de Markov está en el estado i en el tiempo t. El caso continuo es tratado de manera similar: aquí definimos \(p_i\) como la función de densidad de probabilidad de \(X_t\) asociada con el estado i. Nos referimos a las m distribuciones \(p_i\) como la distribución estado-dependiente del modelo.

2.2.2 Distribuciones marginales

A menudo necesitamos las distribuciones marginales de \(X_t\) y también distribuciones marginales de orden superior, tales como \((X_t,X_{t+k})\). Derivaremos los resultados para el caso en el cual la cadena de Markov es homogénea pero no necesariamente estacionaria, y luego veremos para el caso especial en donde la cadena de Markov es estacionaria. Por conveniencia la derivación es dada solo para las distribuciones estado-dependientes discretas; el caso continuo puede ser derivado análogamente.

Distribuciones de una variable

Para observaciones de valores discretos \(X_t\), definimos \(u_i(t)=Pra(C_t=i)\quad para\quad t=1,…,T\), tenemos

\[ Pr(X_t = x) = \sum_{i=1}^m Pr(C_t = i) Pr(X_t = x |C_t = i) \\ = \sum_{i=1}^m u_i(t)p_i(x) \] La expresión puede ser convenientemente rescrita en notacion de matriz

\[ Pr(X_t = x) = (u_1(t),...,u_m(t)) \left(\begin{array}{cc} p_1(x) & 0\\ 0 & p_m(x) \end{array}\right) \left(\begin{array}{cc} 1\\ 1 \end{array}\right) \\ =u(t) P(x)1' \] Donde \(P(x)\) es definida como la matriz diagonal con su i-esimo elemento diagonal \(p_i (x)\). Tomando en cuenta la ecuación del capítulo anterior que dicta que \(u(t)=u(1) Γ^{t-1}\), y por lo tanto

\[Pr(X_t = x) = u(1)\Gamma^{t-1} P(x)1'\] Esta ecuación funciona solamente si la cadena de Markov es puramente homogénea, y no necesariamente estacionaria. Si, como lo asumiremos usualmente, la cadena de Markov es estacionaria, con distribución estacionaria \(δ\), el resultado es aún más simple: en ese caso \(δΓ^{(t-1)}=δ\) para todo \(t∈N\), y entonces

\[Pr(X_t = x) = \delta P(x)1'\]

Distribuciones de dos variables

El cálculo de muchas de las distribuciones relacionadas a un HMM es realizado más fácilmente al notar de primero que, para un modelo grafico dirigido, la distribución conjunta de un set de variables aleatorias \(V_i\) esta dada por

\[Pr(V_1,V_2,...,V_n) = \prod_{i=1}^n Pr(V_i |pa(V_i))\]

Donde \(pa(V_i )\) denota el set de todos los “parientes” de \(V_i\) en el set \(V_1,V_2,…,V_n\). En el grafico dirigido de las cuatro variables aleatorias \(X_t,X_{(t+k)},C_t,C_{(t+k)}\) (para enteros positivos k), \(C_t\) no tiene parientes, \(pa(X_t )={C_t },pa(C_{(t+k)} )={C_t}\) y \(pa(X_{(t+k)} )={C_{(t+k)}}\). Y por tanto sigue que

\[ Pr(X_t,X_{t+k},C_t,C_{t+k}) = Pr(C_t)Pr(X_t|C_t) Pr(C_{t+k}|C_t) Pr(X_{t+k}|C_{t+k}) \] Y por lo tanto dicta que:

\[ Pr(X_t = v, X_{t+k}=w) = \sum_{i=1}^m \sum_{j=1}^m u_i(t)p_i(v)\gamma_{ij}(k)p_j(w) \]

(Aquí y en cualquier otro lado, \(γ_{ij} (k)\) denota los (i,j) elementos de \(Γ^k\).) Escribiendo la suma doble superior como el productor de matrices obtenemos

\[ Pr(X_t = v, X_{t+k}=w) = u(t) P(v)\Gamma^k P(w)1' \] Si la cadena de Markov es estacionaria, esto se reduce a

\[ Pr(X_t = v, X_{t+k}=w) = \delta P(v) \Gamma^k P(w)1' \]

Similarmente, uno puede obtener expresiones para las distribuciones marginales de orden superior; en el caso estacionario, la formula para una distribución de tres variables es, para enteros positivos k y l

\[ Pr(X_t=v, X_{t+k}=w, X_{t+k+l} =z) = \delta P(v) \Gamma^k P(w) \Gamma^l P(z)1' \]

2.2.3 Momentos

Primero notemos que

\[ E(X_t) = \sum_{i=1}^m E(X_t | C_t=i ) Pr(C_t = i) = \sum_{i=1}^m u_i(t) E(X_t|C_t = i) \] En el cual, el caso estacionario se reduce a

\[ E(X_t) = \sum_{i=1}^m \delta_i E(X_t| C_t = i) \] Mas generalmente, resultados analogos aguardan para \(E(g(X_t ))\) y \(E(g(X_t,X_{t+k} ))\), para cualquier función \(g\) para las cuales expectativas estado-dependientes relevantes existen. En el caso estacionario

\[ E(g(X_t)) = \sum_{i=1}^m \delta_i E(g(X_t) | C_t =i) \] y además

\[ E(g(X_t,X_{t+k})) = \sum_{i,j=1}^m E(g(X_t,X_{t+k})|C_t = i, C_{t+k} = j) \delta_i \gamma_{ij}(k) \] A menudo también estaremos interesados en una función g la cual factoriza a

\[g(X_t, X_{t+k}) = g_1(X_t) g_2(X_{t+k})\] En cual caso la ecuación resultante termina siendo

\[ E(g(X_t,X_{t+k})) = \sum_{i,j=1}^m E(g_1(X_t)| C_t = i) E(g_2(X_{t+k})|C_{t+k}=j) \delta_i \gamma_{ij}(k) \] Estas expresiones nos permiten encontrar covarianzas y correlaciones; expresiones explicitas convenientes existen para muchos casos. Para el caso de un HMM de Poisson estacionario de dos estados:

\[ E(X_t) = \delta_1 \lambda_1 + \delta_2 \lambda_2 \\ Var(X_t) = E(X_t) + \delta_1 \delta_2(\lambda_2 - \lambda_1)^2 \geq E(X_t) \\ Cov(X_t, X_{t+k}) = \delta_1 \delta_2(\lambda_2 - \lambda_1)^2 (1 - \gamma_{12} - \gamma_{21})^k, para \quad k \in N \]

Notese que la formula resultante para la correlación de \(X_t\) y \(X_{t+k}\) es de la forma \(ρ(k)=A(1-γ_{12}-γ_{21} )^k\) con \(A∈[0,1)\), y que A=0 si \(λ_1=λ_2\).

2.3. La Posibilidad

El objetivo de esta sección es desarrollar una formula conveniente para la posibilidad de \(L_T\) de T observaciones continuas \(x_1,x_2,…,x_T\) asumida a ser generada por un HMM de m-estados. Veremos que la computación de la posibilidad, consiste de la suma de \(m^T\) términos, cada cual es un producto de 2T factores, parece requerir O(Tm^T) operaciones. Nuestro propósito aquí es demostrar que \(L^T\) puede ser en general computado simplemente relacionado en \(O(Tm^2 )\) operaciones. La manera luego será ampliada para estimar parámetros por maximización numéricas de la posibilidad. Primero, la posibilidad de modelos de dos estados será explorada, y entonces la formula general será presentada.

2.3.1. La posibilidad de un HMM de Bernoulli de dos estados

Considere el HMM estacionario de dos estados con t.p.m.

\[ \Gamma = \left(\begin{array}{cc} 1/2 & 1/2\\ 1/4 & 3/4 \end{array}\right) \quad y \quad \delta = \left(\begin{array}{cc} 1/3, 2/3 \end{array}\right) \]

Y distribuciones estado-dependientes dadas por

\[ Pr(X-t =x | C_t = 1) = 1/2 \quad(para\quad x =0,1) \\ Pr(X-t =1 | C_t = 2) = 1 \]

Llamaremos un modelo de este tipo un HMM de Bernoulli. . Considere la probabilidad \(Pra(X_1=X_2=X_3=1\). Primero, note que, por ecuaciones anteriores,

\[ Pra(X_1,X_2,X_3,C_1,C_2,C_3 )=Pra(C_1 ) Pra(X_1│C_1 ) Pra(C_2│C_1 ) Pra(X_2│C_2 ) Pra(C_3│C_2 ) Pra(X_3 |C_3); \] luego sumarmos los valores asumidos por \(C_1,C_2,C_3\). El resultado es:

\[ Pr(X_1=1, X_2 = 1, X3=1) \\ = \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2 Pr(X_1 = 1,X_2=1,X_3=1, C_1 =i, C_2=j, C_3=k) \\ = \sum_{i=1}^2 \sum_{j=1}^2 \sum_{k=1}^2 \delta_i p_i(1) \gamma_{ij} p_j(1) \gamma_{jk} p_k(1) \] Note que la triple suma de la ecuación anterior tiene \(m^T=2^3\) términos, cada del cual es producto de \(2T=2 x 3 \)factores. Para evaluar la probabilidad requerida, las diferentes posibilidades para los valores de i,j y k pueden ser listados y la suma calculada como en la siguiente tabla

Probabilidad de la probabilidad de una HMM Bernoulli

Probabilidad de la probabilidad de una HMM Bernoulli

La suma de la última columna de la tabla anterior nos dice que \(Pra(X_1=1,X_2=1,X_3=1)=29/48\) . Al observar notamos que el elemento más grande en esa columna es 3/8; la secuencia de estados que maximiza la probabilidad conjunta

\[Pr(X_1 = 1,X_2=1,X_3=1, C_1 =i, C_2=j, C_3=k)\] Es entonces la secuencia \(i=2,j=2,k=2\). Equivalentemente, maximiza la probabilidad condicional \(Pra(C_1=i,C_2=j,C_3=k| X_1=1,X_2=1,X_3=1)\). Pero una manera mas conveniente de presentar la sumar es utilizar notación de matriz. Definamos P(u) como \(diag(p_1 (u),p_2 (u))\). Entonces

\[ P(0) = \left(\begin{array}{cc} 1/2 & 0\\ 0 & 0 \end{array}\right) \quad y \quad P(1)= \left(\begin{array}{cc} 1/2 & 0\\ 0 & 1 \end{array}\right) \] Y la triple suma anterior puede ser escrita como el producto de una matriz

\[ δP(1)ΓP(1)ΓP(1)1' \]

2.3.2. La posibilidad en general

Aquí consideramos la posibilidad de un HMM en general. Suponemos hay una secuencia de observación \(x_1,x_2,…,x_T \)generada por tal modelo. Buscamos la probabilidad \(L_T\) de observar esa secuencia, según lo calculado bajo un HMM de m-estados el cual tiene una distribución inicial \(δ\) y t.p.m. \(Γ\) para la cadena de Markov, funciones de probabilidad estado-dependientes \(p_i\).

Proposicion 1: La probabilidad es dada por

\[ L_T = \delta P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_T)1' \] si \(\delta\), la distribucioón de \(C_1\), si es una distribucion estacionaria de la cadena de Markov, entonces:

\[ L_T = \delta \Gamma P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_T)1' \]

Una simple pero crucial consecuencia de la expresión matricial para la posibilidad es el “algoritmo de avance” para computación recursiva de la posibilidad. Tal computación recursiva juega un rol clave, no solo en evaluación de la posibilidad y por tanto estimación de parámetros, pero también en predecir, decodificar y revisar modelos. La naturaleza recursiva de tal evaluación de posibilidad vía la Proposición 1 es computacionalmente mucho mas efectivo que suma de fuerza bruta sobre todas las secuencias de estado posible. El hecho que tales esquemas computacionales recursivos no costosos pueden ser utilizados para abordar varias preguntas de interés es una característica clave de los HMMs. Para definir el algoritmo de avance, definimos el vector \(α_t\) para \(t=1,2,…,T\), por

\[ \alpha_t = \delta P(x_1)\Gamma P(x_2) \Gamma P(x_3) \quad ... \quad \Gamma P(x_t) = \delta P(x_1) \prod_{s=2}^t \Gamma P(x_s) \] Con la convención que un producto vacío es la matriz identidad. Sigue inmediatamente de esta definición que

\[ L_T = \alpha_T 1' \quad y \quad \alpha_t = \alpha_{t-1} \Gamma P(x_t) \quad para \quad t \ge 2 \] Acordemente, podemos convenientemente fijar como sigue las computaciones involucradas en la fórmula de posibilidad

\[ \alpha_1 = \delta P(x_1) \\ \alpha_t = \alpha_{t-1} \Gamma P(x_t) \quad para \quad t =2,3,...,T \\ L_T = \alpha_T 1' \]

El número de operaciones involucradas es de orden \(Tm^2\) puede ser deducido así. Para cada uno de los valores de t en el ciclo, hay m elementos de \(α_t\) por ser computados, y cada uno de esos elementos es una suma de m productos de tres cantidades: un elemento de \(α_{t-1}\), una probabilidad de transición \(γ_{ij}\), y una probabilidad (o densidad) estado-dependiente \(p_j (x_t)\).

El esquema de correspondiente para la computación de la Propuesta 1 es

\[ \alpha_0 = \delta \\ \alpha_t = \alpha_{t-1} \Gamma P(x_t) \quad para \quad t =1,2,...,T \\ L_T = \alpha_T 1' \] Los elementos del vector \(α_t\) son usualmente referidos como probabilidades de avance; donde mostramos que el j-esimo elemento de \(α_t\) es \(Pra(X^{(t)}=x^{(t)},C_t=j\). A continuación, mostramos código de R que utiliza el algoritmo de avance para evaluar la posibilidad de observaciones \(x_1,…x_T\) bajo un HMM de Poisson con por lo menos dos estados, t.p.m. \(Γ\), vector de medias estado-dependientes \(λ\), y distribución inicial \(δ\).

alpha <- delta*dpois(x[1], lambda)
for(i in 2:T) 
  alpha <- %*% Gamma*dpois(x[i],lambda)
sum(alpha)

En la discusión superior hemos utilizado la expresión de múltiples sumas para la posibilidad para así llegar a la expresión matricial, y luego utilizado la expresión matricial para llegar a la recursión de avance. Una ruta alternativa es definir el vector de avance de probabilidades \(α_t\) por

\[ \alpha_t(j) = Pr(X^{(t)} = x^{(t)}, C_t = j), j=1,2,...,m \] Y luego deducir la recursión de avance

\[ \alpha_t = \alpha_{t-1} \Gamma P(x_t) \] La expresión matricial es entonces una simple consecuencia de la recursión de avance.

2.3.3 HMMs no son procesos de Markov

HMMs no satisfacen en general la propiedad de Markov. Esto lo podemos demostrar mediante un simple contrajemplo. Basado en la seccion 2.3.1 sabemos que:

\[ Pr(X_1=1,X_2=1,X_3=1) = \frac{29}{48} \\ Pr(X_2=1) = \frac{5}{6} \\ entonces \\ Pr(X_1,X_2=1) = Pr(X_2=1,X_3=1) = \frac{17}{24} \\ por \quad tanto \quad se\quad deduce\quad que \\ Pr(X_3=1 | X_1=1,X_2=1) = \frac{Pr(X_1=1,X_2=1,X_3=1)}{Pr(X_1=1,X_2=1)} = \frac{29/48}{17/24} \\ y \quad eso \\ Pr(X_3=1|X_2=1) = \frac{Pr(X_2=1,X_3=1)}{Pr(X_2=1)} = \frac{17/24}{5/6} = 17/20 \]

Por lo tanto \(Pra(X_3=1|X_2=1)≠Pra(X_3=1|X_1=1,X_2=1\); este HMM no satisface la propiedad de Markov. Para las condiciones bajo las cuales un HMM si satisface la propiedad de Markov.

2.3.4. La posibilidad cuando hay datos faltantes

En el contexto de una serie de tiempo es potencialmente raro si algunos de los datos faltan. En el caso de series de tiempo de modelos ocultos de Markov, sin embargo, el ajuste que se necesita ser realizado para la computación de la posibilidad si hay datos faltantes resulta ser uno fácil. Suponga, por ejemplo, que uno tiene disponible las observaciones \(x_1,x_2,x_4,x_7,x_8,…,x_T\) de un HMM pero \(x_3,x_5 \quad y \quad x_6 \)hacen falta. Entonces la posibilidad de las observaciones esta dada por

\[ Pr(X_1=x1,X_2=x2,X_4=x_4,X_7=x_7,X_8=x_8,...,,X_T=x_T) = \\ \sum \delta_{c_1}\gamma_{c1,c2}\gamma_{c2,c4}(2) \gamma_{c4,c7} (3) \gamma_{c7,c8} \quad ... \quad \gamma_{c_{T-1},c_T} \\ \times p_{c_1} (x_1) p_{c2}(x_2) p_{c4}(x_4) p_{c7}(x_7)\quad ... \quad p_{c_T}(x_T) \]

Donde (como antes) \(γ_{ij} (k)\) denota una probabilidad de transición de paso k, y la suma se toma sobre todos los índices \(c_t\) diferentes de \(c_3,c_5 y c_6\). Pero esto es solamente

\[ \sum \delta_{c_1} p_{c_1} (x_1) \gamma_{c_1},c_2p_{c_2} (x_2) \gamma_{c_2},c_4(2)p_{c_4} (x_4) \gamma_{c_4},c_7(3)p_{c_7} (x_7) \gamma_{c_7} \quad \times...\times \quad \gamma_{c_T-1}, c_T p_{c_T}(x_T)= \\ \delta P(x_1) \Gamma P(x_2)\Gamma^2 P(x_4) \Gamma^3 P(x_7)...\Gamma P(x_T)1' \]

Con \(L_T^{-(3,5,6)}\) denotando la posibilidad de las observaciones (diferentes de las faltantes), se declara que

\[ L_T^{-(3,5,6)} = P(x_1) \Gamma P(x_2)\Gamma^2 P(x_4) \Gamma^3 P(x_7)...\Gamma P(x_T)1' \]

En general, la expresión para la posibilidad de matrices diagonales \(P(x_t)\) correspondiente a las observaciones faltantes \(x_t\) son remplazadas por la matriz identidad; eso es, las probabilidades estado-dependientes correspondientes \(p_i (x_t )\) son remplazadas por 1 para todos los estados i.

2.3.5. La posibilidad cuando las observaciones son censoradas por intervalo

Suponga que deseamos ajustar un HMM de Poisson a una serie de cuentas, algunas de las cuales son censoradas por intervalo. Por ejemplo, el valor de \(x_t\) puede ser conocido para \(4≤t≤T\), con la información \(x_1≤5,2≤x_2≤3\) y \(x_3>10\) disponible acerca de las observaciones restantes. Para simplificar, asumamos de primero que la cadena de Markov solo tiene dos estados. En ese caso, uno remplaza las matrices diagonales \(P(x_i )(i=1,2,3)\) en la expresión de posibilidad por las matrices

\[ diag(Pr(X_1 \le |C_1 =1), Pr(X_1 \le 5| C_1=2)), \\ diag(Pr(2 \le X_2 \le 3 | C_2=1),Pr(2 \le X_2 \le 3 | C_2=2)) \\ diag(Pr(X_3 \gt 10 | C_3 = 1), Pr(X_3 \gt 10 | C_3 = 2)) \]

Mas generalmente, suponga que \(a≤x_t≤b\) donde a puede ser \(-∞\) (aunque eso no es relevante para el caso de Poisson), b puede ser \(∞\), y la cadena de Markov tiene m estados. Uno remplaza \(P(x_t)\) en la posibilidad por la matriz diagonal \(m×m\) de la cual el elemento diagonal i-esimo es \(Pra(a≤X_t≤b|C_t=i)\)

LS0tCnRpdGxlOiAiSGlkZGVuIE1hcmtvdiBNb2RlbHM6IGRlZmluaXRpb24gYW5kIFByb3BlcnRpZXMiCmF1dGhvcjogIkJyYXlhbiBJdmFuIENydXogQ29yb25hIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojI0NhcMOtdHVsbyAyOiBNb2RlbG9zIGRlIE1hcmtvdiBvY3VsdG9zOiBkZWZpbmljacOzbiB5IHByb3BpZWRhZGVzCgojIyMyLjEuIFVuIG1vZGVsbyBkZSBNYXJrb3Ygb2N1bHRvIHNpbXBsZQoKCkNvbnNpZMOpcmVzZSBudWV2YW1lbnRlIGxhIHNlcmllIGRlIHRlcnJlbW90b3MgbW9zdHJhZGEgZW4gZWwgY2FwaXR1bG8gYW50ZXJpb3IuIExhcyBvYnNlcnZhY2lvbmVzIHNvbiBjdWVudGFzIGlsaW1pdGFkYXMsIGhhY2llbmRvIGxhIGRpc3RyaWJ1Y2nDs24gZGUgUG9pc3NvbiB1bmEgZWxlY2Npw7NuIG5hdHVyYWwgcGFyYSBkZXNjcmliaXJsYXMsIHBlcm8gc3UgZGlzdHJpYnVjacOzbiBlcyBjbGFyYW1lbnRlIHJlbGF0aXZhIHNvYnJlIGRpc3BlcnNhIGEgbGEgZGUgUG9pc3Nvbi4gT2JzZXJ2YW1vcyBlbiBlbCBjYXDDrXR1bG8gYW50ZXJpb3IgcXVlIGVzdGUgaGVjaG8gcHVlZGUgc2VyIGFjb21vZGFkbyBhbCB1c2FyIHVuYSBtZXpjbGEgZGUgZGlzdHJpYnVjaW9uZXMgZGUgUG9pc3NvbiBjb24gbWVkaWFzIFwozrtfMSzOu18yLOKApizOu19tXCkuIExhIGVsZWNjacOzbiBkZSBsYSBtZWRpYSBlc3RhIGhlY2hhIHBvciB1biBzZWd1bmRvIHByb2Nlc28gYWxlYXRvcmlvLCBlbCBwcm9jZXNvIGRlIHBhcsOhbWV0cm8uIExhIG1lZGlhIFwozrtfaVwpIGVzIHNlbGVjY2lvbmFkYSBjb24gcHJvYmFiaWxpZGFkIFwozrRfaVwpLCBkb25kZSBcKGk9MSwyLOKApixtXCkgeSBcKFxzdW1fe2k9MX1ebc60X2k9MVwpLgoKVW4gbW9kZWxvIGRlIG1lemNsYSBpbmRlcGVuZGllbnRlIG5vIHJlc3VsdGFyYSBjb24gbGEgc2VyaWUgZGUgdGVycmVtb3RvcyBwb3JxdWUsIHBvciBkZWZpbmljacOzbiwgbm8gcGVybWl0ZSBsYSBkZXBlbmRlbmNpYSBzZXJpYWwgZW4gbGFzIG9ic2VydmFjaW9uZXMuIExhIG11ZXN0cmEgZGUgZnVuY2nDs24gZGUgYXV0b2NvcnJlbGFjacOzbiAoQUNGKSwgZGVzcGxlZ2FkYSBlbiBsYSBGaWd1cmEgMi4xLCBjbGFyYW1lbnRlIGluZGljYSBxdWUgbGFzIG9ic2VydmFjaW9uZXMgc29uIGRlcGVuZGllbnRlcyBlbiBzZXJpZS4gVW5hIG1hbmVyYSBkZSBwZXJtaXRpciBsYSBkZXBlbmRlbmNpYSBzZXJpYWwgZW4gbGFzIG9ic2VydmFjaW9uZXMgZXMgcmVsYWphciBsYSBzdXBvc2ljacOzbiBxdWUgZWwgcHJvY2VzbyBkZSBwYXLDoW1ldHJvIGVzIGluZGVwZW5kaWVudGUgZW4gc2VyaWUuIFVuYSBtYW5lcmEgc2ltcGxlIHkgbWF0ZW3DoXRpY2FtZW50ZSBjb252ZW5pZW50ZSBwYXJhIGhhY2VyIGVzdG8gZXMgYXN1bWlyIHF1ZSBlcyB1bmEgY2FkZW5hIGRlIE1hcmtvdi4gRWwgbW9kZWxvIHJlc3VsdGFudGUgcGFyYSBsYXMgb2JzZXJ2YWNpb25lcyBlcyBsbGFtYWRvIHVuIG1vZGVsbyBkZSBNYXJrb3Ygb2N1bHRvIGRlIFBvaXNzb24uCgpgYGB7cn0KbGlicmFyeShmb3JlY2FzdCkKbGlicmFyeShyZWFkcikKI2xlZXIgbGEgZGF0YSAKZGF0YV90ZXJyZW1vdG9zX2NoMiA8LSByZWFkLnRhYmxlKCIvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9lYXJ0aHF1YWtlcy50eHQiKQojT2J0ZW5lciBsYSBBQ0YgZGUgbGEgZGF0YSBhbnRlcmlvcgpBQ0ZfY2gyIDwtIGFjZihkYXRhX3RlcnJlbW90b3NfY2gyLCBwbG90PVRSVUUpCgpgYGAKRmlndXJhIDIuMQoKCgojIyMyLjIgTG8gYsOhc2ljbwojIyMjMi4yLjEgRGVmaW5pY2nDs24geSBub3RhY2nDs24KCiFbRmlndXJhIDIuMl0oL1VzZXJzL2JyYWNydXovRG9jdW1lbnRzLzh2by4gVHJpbWVzdHJlIElPL1Npc3QuIEV4cGVydG9zIHkgUmVkZXMgUHJvYi4vQ0gyL0ZpZ3VyYTItMi5wbmcpCgpVbiBtb2RlbG8gZGUgTWFya292IG9jdWx0byBcKHtYX3Q6dCDiiIhOfVwpIGVzIHVuIHRpcG8gcGFydGljdWxhciBkZSBtZXpjbGEgZGVwZW5kaWVudGUuIENvbiBcKFhedFwpIHkgXChDXnRcKSByZXByZXNlbnRhbmRvIGxhcyBoaXN0b3JpYXMgZGVsIHRpZW1wbyAxIGFsIHRpZW1wbyB0LCB1bm8gcHVlZGUgcmVzdW1pciBlbCBtb2RlbG8gbcOhcyBzaW1wbGUgZGUgZXN0ZSB0aXBvIHBvcjoKCiQkClByKENfdCB8IENee3QtMX0pID0gUHIoQ190IHwgQ197dC0xfSksIHQ9MiwzLC4uLiBcXApQcihYX3QgfCBYXnt0LTF9LENedCkgPSBQcihYX3QgfCBDX3QpLCB0IOKIiCBOCiQkCkVsIG1vZGVsbyBjb25zaXN0ZSBkZSBkb3MgcGFydGVzOiBwcmltZXJvLCB1biDigJxwcm9jZXNvIGRlIHBhcsOhbWV0cm/igJ0gbm8gb2JzZXJ2YWRvIFwoe0NfdDp0PTEsMizigKZ9XCkgc2F0aXNmYWNpZW5kbyBsYSBwcm9waWVkYWQgZGUgTWFya292OyB5IGNvbW8gc2VndW5kbywgZWwg4oCccHJvY2VzbyBlc3RhZG8tZGVwZW5kaWVudGXigJ0gXCh7WF90OnQ9MSwyLOKApn1cKSwgZW4gZWwgY3VhbCBsYSBkaXN0cmlidWNpw7NuIGRlIFwoWF90XCkgZGVwZW5kZSBzb2xhbWVudGUgZW4gZWwgZXN0YWRvIGFjdHVhbCBcKENfdFwpIHkgbm8gZGUgZXN0YWRvcyB1IG9ic2VydmFjaW9uZXMgcHJldmlhcy4gTGEgZXN0cnVjdHVyYSBzZSByZXByZXNlbnRhIGVuIGxhIEZpZ3VyYSAyLjIKCgpTaSBsYSBjYWRlbmEgZGUgTWFya292IFwoe0NfdH1cKSB0aWVuZSBtIGVzdGFkb3MsIGxsYW1hbW9zIFwoe1hfdH1cKSB1bmEgSE1NIGRlIG0tZXN0YWRvcy4gQXVucXVlIGVzIGxhIHRlcm1pbm9sb2fDrWEgdXN1YWwgZW4gYXBsaWNhY2lvbmVzIGRlIHByb2Nlc2FtaWVudG8gZGVsIGhhYmxhLCBlbCBub21icmUg4oCcbW9kZWxvIGRlIE1hcmtvdiBvY3VsdG/igJ0gZXMgcG9yIG5pbmfDum4gbWVkaW8gZWwgw7puaWNvIHVzYWRvIHBhcmEgdGFsZXMgbyBzaW1pbGFyZXMuCgohW0ZpZ3VyYSAyLjMgLSBQcm9jZXNvIGdlcmVuYW5kbyBsYXMgb2JzZXJ2YWNpb25lcyBlbiB1biBlc3RhZG8gZG9ibGUgZGUgSE1NLiBTaWd1aWVuZG8gbGEgY2FkZW5hIDIsMSwxLDEsMiwxXSgvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9DSDIvRmlndXJhMi0zLnBuZykKCkVsIHByb2Nlc28gZ2VuZXJhbmRvIGxhcyBvYnNlcnZhY2lvbmVzIGVzIG51ZXZhbWVudGUgZGVtb3N0cmFkbyBlbiBsYSBGaWd1cmEgYW50ZXJpb3IsIHBhcmEgZGlzdHJpYnVjaW9uZXMgZXN0YWRvLWRlcGVuZGllbnRlcyBcKHBfMVwpIHkgXChwXzJcKSwgZGlzdHJpYnVjacOzbiBlc3RhY2lvbmFyaWEgXCjOtD0oMC43NSwwLjI1KVwpLCB5IHQucC5tLiBcKFxHYW1tYT0gXGxlZnQoXGJlZ2lue2FycmF5fXtjY30gCjAuOSAmIDAuMVxcIAowLjMgJiAwLjcKXGVuZHthcnJheX1ccmlnaHQpXCkuIEVuIGNvbnRyYXN0ZSBhbCBjYXNvIGRlIHVuYSBtZXpjbGEgaW5kZXBlbmRpZW50ZSwgYXF1w60gbGEgZGlzdHJpYnVjacOzbiBkZSBcKENfdFwpLCBlbCBlc3RhZG8gZW4gdGllbXBvIHQsIHPDrSBkZXBlbmRlIGRlIFwoQ18odC0xKVwpLiBUYW1iacOpbiBlcyBjaWVydG8gZGUgbGFzIG1lemNsYXMgaW5kZXBlbmRpZW50ZXMsIGhheSBwYXJhIGNhZGEgZXN0YWRvIHVuYSBkaXN0cmlidWNpw7NuIGRpZmVyZW50ZSwgZGlzY3JldGEgbyBjb250aW51YS4KQWhvcmEgaW50cm9kdWNpcmVtb3MgdW5hIG5vdGFjacOzbiBsYSBjdWFsIGN1YnJpcsOhIHRhbnRvIG9ic2VydmFjaW9uZXMgdmFsdWFkYXMgZGlzY3JldGFzIGNvbW8gY29udGludWFzLiBFbiBlbCBjYXNvIGRlIG9ic2VydmFjaW9uZXMgZGlzY3JldGFzLCBkZWZpbmltb3MsIHBhcmEgXChpPTEsMizigKYsbVwpCgokJHBfaSh4KSA9IFByKFhfdCA9IHggfCBDX3QgPSBpKSQkCkVzdG8gZXMsIFwocF9pXCksIGVzIGxhIGZ1bmNpw7NuIGRlIHByb2JhYmlsaWRhZCBlbiBtYXNhIGRlIFwoWF90XCkgc2kgbGEgY2FkZW5hIGRlIE1hcmtvdiBlc3TDoSBlbiBlbCBlc3RhZG8gaSBlbiBlbCB0aWVtcG8gdC4gRWwgY2FzbyBjb250aW51byBlcyB0cmF0YWRvIGRlIG1hbmVyYSBzaW1pbGFyOiBhcXXDrSBkZWZpbmltb3MgXChwX2lcKSBjb21vIGxhIGZ1bmNpw7NuIGRlIGRlbnNpZGFkIGRlIHByb2JhYmlsaWRhZCBkZSBcKFhfdFwpIGFzb2NpYWRhIGNvbiBlbCBlc3RhZG8gaS4gTm9zIHJlZmVyaW1vcyBhIGxhcyBtIGRpc3RyaWJ1Y2lvbmVzIFwocF9pXCkgY29tbyBsYSBkaXN0cmlidWNpw7NuIGVzdGFkby1kZXBlbmRpZW50ZSBkZWwgbW9kZWxvLgoKCiMjIyMyLjIuMiBEaXN0cmlidWNpb25lcyBtYXJnaW5hbGVzCgpBIG1lbnVkbyBuZWNlc2l0YW1vcyBsYXMgZGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcyBkZSBcKFhfdFwpIHkgdGFtYmnDqW4gZGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcyBkZSBvcmRlbiBzdXBlcmlvciwgdGFsZXMgY29tbyBcKChYX3QsWF97dCtrfSlcKS4gRGVyaXZhcmVtb3MgbG9zIHJlc3VsdGFkb3MgcGFyYSBlbCBjYXNvIGVuIGVsIGN1YWwgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBob21vZ8OpbmVhIHBlcm8gbm8gbmVjZXNhcmlhbWVudGUgZXN0YWNpb25hcmlhLCB5IGx1ZWdvIHZlcmVtb3MgcGFyYSBlbCBjYXNvIGVzcGVjaWFsIGVuIGRvbmRlIGxhIGNhZGVuYSBkZSBNYXJrb3YgZXMgZXN0YWNpb25hcmlhLiBQb3IgY29udmVuaWVuY2lhIGxhIGRlcml2YWNpw7NuIGVzIGRhZGEgc29sbyBwYXJhIGxhcyBkaXN0cmlidWNpb25lcyBlc3RhZG8tZGVwZW5kaWVudGVzIGRpc2NyZXRhczsgZWwgY2FzbyBjb250aW51byBwdWVkZSBzZXIgZGVyaXZhZG8gYW7DoWxvZ2FtZW50ZS4KCiMjIyMjRGlzdHJpYnVjaW9uZXMgZGUgdW5hIHZhcmlhYmxlClBhcmEgb2JzZXJ2YWNpb25lcyBkZSB2YWxvcmVzIGRpc2NyZXRvcyBcKFhfdFwpLCBkZWZpbmltb3MgXCh1X2kodCk9UHJhKENfdD1pKVxxdWFkIHBhcmFccXVhZCB0PTEs4oCmLFRcKSwgdGVuZW1vcwoKJCQKUHIoWF90ID0geCkgPSBcc3VtX3tpPTF9Xm0gUHIoQ190ID0gaSkgUHIoWF90ID0geCB8Q190ID0gaSkgXFwKPSBcc3VtX3tpPTF9Xm0gdV9pKHQpcF9pKHgpCiQkCkxhIGV4cHJlc2nDs24gcHVlZGUgc2VyIGNvbnZlbmllbnRlbWVudGUgcmVzY3JpdGEgZW4gbm90YWNpb24gZGUgbWF0cml6CgokJApQcihYX3QgPSB4KSA9ICh1XzEodCksLi4uLHVfbSh0KSkgClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IApwXzEoeCkgJiAwXFwgCjAgJiBwX20oeCkKXGVuZHthcnJheX1ccmlnaHQpClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAoxXFwgCjEgClxlbmR7YXJyYXl9XHJpZ2h0KSBcXAo9dSh0KSBQKHgpMScKJCQKRG9uZGUgXChQKHgpXCkgZXMgZGVmaW5pZGEgY29tbyBsYSBtYXRyaXogZGlhZ29uYWwgY29uIHN1IGktZXNpbW8gZWxlbWVudG8gZGlhZ29uYWwgXChwX2kgKHgpXCkuIFRvbWFuZG8gZW4gY3VlbnRhIGxhIGVjdWFjacOzbiBkZWwgY2Fww610dWxvIGFudGVyaW9yIHF1ZSBkaWN0YSBxdWUgXCh1KHQpPXUoMSkgzpNee3QtMX1cKSwgeSBwb3IgbG8gdGFudG8KCgokJFByKFhfdCA9IHgpID0gdSgxKVxHYW1tYV57dC0xfSBQKHgpMSckJApFc3RhIGVjdWFjacOzbiBmdW5jaW9uYSBzb2xhbWVudGUgc2kgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBwdXJhbWVudGUgaG9tb2fDqW5lYSwgeSBubyBuZWNlc2FyaWFtZW50ZSBlc3RhY2lvbmFyaWEuIFNpLCBjb21vIGxvIGFzdW1pcmVtb3MgdXN1YWxtZW50ZSwgbGEgY2FkZW5hIGRlIE1hcmtvdiBlcyBlc3RhY2lvbmFyaWEsIGNvbiBkaXN0cmlidWNpw7NuIGVzdGFjaW9uYXJpYSBcKM60XCksIGVsIHJlc3VsdGFkbyBlcyBhw7puIG3DoXMgc2ltcGxlOiBlbiBlc2UgY2FzbyBcKM60zpNeeyh0LTEpfT3OtFwpIHBhcmEgdG9kbyBcKHTiiIhOXCksIHkgZW50b25jZXMgCgokJFByKFhfdCA9IHgpID0gXGRlbHRhIFAoeCkxJyQkCgojIyMjI0Rpc3RyaWJ1Y2lvbmVzIGRlIGRvcyB2YXJpYWJsZXMKCkVsIGPDoWxjdWxvIGRlIG11Y2hhcyBkZSBsYXMgZGlzdHJpYnVjaW9uZXMgcmVsYWNpb25hZGFzIGEgdW4gSE1NIGVzIHJlYWxpemFkbyBtw6FzIGbDoWNpbG1lbnRlIGFsIG5vdGFyIGRlIHByaW1lcm8gcXVlLCBwYXJhIHVuIG1vZGVsbyBncmFmaWNvIGRpcmlnaWRvLCBsYSBkaXN0cmlidWNpw7NuIGNvbmp1bnRhIGRlIHVuIHNldCBkZSB2YXJpYWJsZXMgYWxlYXRvcmlhcyBcKFZfaVwpIGVzdGEgZGFkYSBwb3IKCiQkUHIoVl8xLFZfMiwuLi4sVl9uKSA9IFxwcm9kX3tpPTF9Xm4gUHIoVl9pIHxwYShWX2kpKSQkCgpEb25kZSBcKHBhKFZfaSApXCkgZGVub3RhIGVsIHNldCBkZSB0b2RvcyBsb3Mg4oCccGFyaWVudGVz4oCdIGRlIFwoVl9pXCkgZW4gZWwgc2V0IFwoVl8xLFZfMizigKYsVl9uXCkuCkVuIGVsIGdyYWZpY28gZGlyaWdpZG8gZGUgbGFzIGN1YXRybyB2YXJpYWJsZXMgYWxlYXRvcmlhcyBcKFhfdCxYX3sodCtrKX0sQ190LENfeyh0K2spfVwpIChwYXJhIGVudGVyb3MgcG9zaXRpdm9zIGspLCBcKENfdFwpIG5vIHRpZW5lIHBhcmllbnRlcywgXChwYShYX3QgKT17Q190IH0scGEoQ197KHQrayl9ICk9e0NfdH1cKSB5IFwocGEoWF97KHQrayl9ICk9e0Nfeyh0K2spfX1cKS4gWSBwb3IgdGFudG8gc2lndWUgcXVlCgokJApQcihYX3QsWF97dCtrfSxDX3QsQ197dCtrfSkgPSBQcihDX3QpUHIoWF90fENfdCkgUHIoQ197dCtrfXxDX3QpIFByKFhfe3Qra318Q197dCtrfSkKJCQKWSBwb3IgbG8gdGFudG8gZGljdGEgcXVlOgoKJCQKUHIoWF90ID0gdiwgWF97dCtrfT13KSA9IFxzdW1fe2k9MX1ebSBcc3VtX3tqPTF9Xm0gdV9pKHQpcF9pKHYpXGdhbW1hX3tpan0oaylwX2oodykKJCQKCihBcXXDrSB5IGVuIGN1YWxxdWllciBvdHJvIGxhZG8sIFwozrNfe2lqfSAoaylcKSBkZW5vdGEgbG9zIChpLGopIGVsZW1lbnRvcyBkZSBcKM6TXmtcKS4pIEVzY3JpYmllbmRvIGxhIHN1bWEgZG9ibGUgc3VwZXJpb3IgY29tbyBlbCBwcm9kdWN0b3IgZGUgbWF0cmljZXMgb2J0ZW5lbW9zCgoKJCQKUHIoWF90ID0gdiwgWF97dCtrfT13KSA9IHUodCkgUCh2KVxHYW1tYV5rIFAodykxJwokJApTaSBsYSBjYWRlbmEgZGUgTWFya292IGVzIGVzdGFjaW9uYXJpYSwgZXN0byBzZSByZWR1Y2UgYQoKJCQKUHIoWF90ID0gdiwgWF97dCtrfT13KSA9IFxkZWx0YSBQKHYpIFxHYW1tYV5rIFAodykxJwokJAoKU2ltaWxhcm1lbnRlLCB1bm8gcHVlZGUgb2J0ZW5lciBleHByZXNpb25lcyBwYXJhIGxhcyBkaXN0cmlidWNpb25lcyBtYXJnaW5hbGVzIGRlIG9yZGVuIHN1cGVyaW9yOyBlbiBlbCBjYXNvIGVzdGFjaW9uYXJpbywgbGEgZm9ybXVsYSBwYXJhIHVuYSBkaXN0cmlidWNpw7NuIGRlIHRyZXMgdmFyaWFibGVzIGVzLCBwYXJhIGVudGVyb3MgcG9zaXRpdm9zIGsgeSAgbAoKJCQKUHIoWF90PXYsIFhfe3Qra309dywgWF97dCtrK2x9ID16KSA9IFxkZWx0YSBQKHYpIFxHYW1tYV5rIFAodykgXEdhbW1hXmwgUCh6KTEnCiQkCgojIyMjMi4yLjMgTW9tZW50b3MKClByaW1lcm8gbm90ZW1vcyBxdWUKCiQkCkUoWF90KSA9IFxzdW1fe2k9MX1ebSBFKFhfdCB8IENfdD1pICkgUHIoQ190ID0gaSkgID0gXHN1bV97aT0xfV5tIHVfaSh0KSBFKFhfdHxDX3QgPSBpKQokJApFbiBlbCBjdWFsLCBlbCBjYXNvIGVzdGFjaW9uYXJpbyBzZSByZWR1Y2UgYQoKJCQKRShYX3QpID0gXHN1bV97aT0xfV5tIFxkZWx0YV9pIEUoWF90fCBDX3QgPSBpKQokJApNYXMgZ2VuZXJhbG1lbnRlLCByZXN1bHRhZG9zIGFuYWxvZ29zIGFndWFyZGFuIHBhcmEgXChFKGcoWF90ICkpXCkgeSBcKEUoZyhYX3QsWF97dCtrfSApKVwpLCBwYXJhIGN1YWxxdWllciBmdW5jacOzbiBcKGdcKSBwYXJhIGxhcyBjdWFsZXMgZXhwZWN0YXRpdmFzIGVzdGFkby1kZXBlbmRpZW50ZXMgcmVsZXZhbnRlcyBleGlzdGVuLiBFbiBlbCBjYXNvIGVzdGFjaW9uYXJpbwoKJCQKRShnKFhfdCkpID0gXHN1bV97aT0xfV5tIFxkZWx0YV9pIEUoZyhYX3QpIHwgQ190ID1pKQokJAp5IGFkZW3DoXMKCiQkCkUoZyhYX3QsWF97dCtrfSkpID0gXHN1bV97aSxqPTF9Xm0gRShnKFhfdCxYX3t0K2t9KXxDX3QgPSBpLCBDX3t0K2t9ID0gaikgXGRlbHRhX2kgXGdhbW1hX3tpan0oaykKJCQKQSBtZW51ZG8gdGFtYmnDqW4gZXN0YXJlbW9zIGludGVyZXNhZG9zIGVuIHVuYSBmdW5jacOzbiBnIGxhIGN1YWwgZmFjdG9yaXphIGEKCiQkZyhYX3QsIFhfe3Qra30pID0gZ18xKFhfdCkgZ18yKFhfe3Qra30pJCQKRW4gY3VhbCBjYXNvIGxhIGVjdWFjacOzbiByZXN1bHRhbnRlIHRlcm1pbmEgc2llbmRvCgokJApFKGcoWF90LFhfe3Qra30pKSA9IFxzdW1fe2ksaj0xfV5tIEUoZ18xKFhfdCl8IENfdCA9IGkpIEUoZ18yKFhfe3Qra30pfENfe3Qra309aikgXGRlbHRhX2kgXGdhbW1hX3tpan0oaykKJCQKRXN0YXMgZXhwcmVzaW9uZXMgbm9zIHBlcm1pdGVuIGVuY29udHJhciBjb3ZhcmlhbnphcyB5IGNvcnJlbGFjaW9uZXM7IGV4cHJlc2lvbmVzIGV4cGxpY2l0YXMgY29udmVuaWVudGVzIGV4aXN0ZW4gcGFyYSBtdWNob3MgY2Fzb3MuIFBhcmEgZWwgY2FzbyBkZSB1biBITU0gZGUgUG9pc3NvbiBlc3RhY2lvbmFyaW8gZGUgZG9zIGVzdGFkb3M6CgokJApFKFhfdCkgPSBcZGVsdGFfMSBcbGFtYmRhXzEgKyBcZGVsdGFfMiBcbGFtYmRhXzIgXFwKVmFyKFhfdCkgPSBFKFhfdCkgKyBcZGVsdGFfMSBcZGVsdGFfMihcbGFtYmRhXzIgLSBcbGFtYmRhXzEpXjIgXGdlcSBFKFhfdCkgXFwKQ292KFhfdCwgWF97dCtrfSkgPSAgXGRlbHRhXzEgXGRlbHRhXzIoXGxhbWJkYV8yIC0gXGxhbWJkYV8xKV4yICgxIC0gXGdhbW1hX3sxMn0gLSBcZ2FtbWFfezIxfSleaywgcGFyYSBccXVhZCBrIFxpbiBOCiQkCgpOb3Rlc2UgcXVlIGxhIGZvcm11bGEgcmVzdWx0YW50ZSBwYXJhIGxhIGNvcnJlbGFjacOzbiBkZSBcKFhfdFwpIHkgXChYX3t0K2t9XCkgZXMgZGUgbGEgZm9ybWEgXCjPgShrKT1BKDEtzrNfezEyfS3Os197MjF9IClea1wpIGNvbiBcKEHiiIhbMCwxKVwpLCB5IHF1ZSBBPTAgc2kgXCjOu18xPc67XzJcKS4KCiMjIyMyLjMuIExhIFBvc2liaWxpZGFkCgpFbCBvYmpldGl2byBkZSBlc3RhIHNlY2Npw7NuIGVzIGRlc2Fycm9sbGFyIHVuYSBmb3JtdWxhIGNvbnZlbmllbnRlIHBhcmEgbGEgcG9zaWJpbGlkYWQgZGUgXChMX1RcKSBkZSBUIG9ic2VydmFjaW9uZXMgY29udGludWFzIFwoeF8xLHhfMizigKYseF9UXCkgYXN1bWlkYSBhIHNlciBnZW5lcmFkYSBwb3IgdW4gSE1NIGRlIG0tZXN0YWRvcy4gVmVyZW1vcyBxdWUgbGEgY29tcHV0YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkLCBjb25zaXN0ZSBkZSBsYSBzdW1hIGRlIFwobV5UXCkgdMOpcm1pbm9zLCBjYWRhIGN1YWwgZXMgdW4gcHJvZHVjdG8gZGUgMlQgZmFjdG9yZXMsIHBhcmVjZSByZXF1ZXJpciBPKFRtXlQpIG9wZXJhY2lvbmVzLgpOdWVzdHJvIHByb3DDs3NpdG8gYXF1w60gZXMgZGVtb3N0cmFyIHF1ZSBcKExeVFwpIHB1ZWRlIHNlciBlbiBnZW5lcmFsIGNvbXB1dGFkbyBzaW1wbGVtZW50ZSByZWxhY2lvbmFkbyBlbiBcKE8oVG1eMiApXCkgb3BlcmFjaW9uZXMuIExhIG1hbmVyYSBsdWVnbyBzZXLDoSBhbXBsaWFkYSBwYXJhIGVzdGltYXIgcGFyw6FtZXRyb3MgcG9yIG1heGltaXphY2nDs24gbnVtw6lyaWNhcyBkZSBsYSBwb3NpYmlsaWRhZC4gUHJpbWVybywgbGEgcG9zaWJpbGlkYWQgZGUgbW9kZWxvcyBkZSBkb3MgZXN0YWRvcyBzZXLDoSBleHBsb3JhZGEsIHkgZW50b25jZXMgbGEgZm9ybXVsYSBnZW5lcmFsIHNlcsOhIHByZXNlbnRhZGEuCgojIyMjIzIuMy4xLiBMYSBwb3NpYmlsaWRhZCBkZSB1biBITU0gZGUgQmVybm91bGxpIGRlIGRvcyBlc3RhZG9zCgpDb25zaWRlcmUgZWwgSE1NIGVzdGFjaW9uYXJpbyBkZSBkb3MgZXN0YWRvcyBjb24gdC5wLm0uCgokJApcR2FtbWEgPSAKXGxlZnQoXGJlZ2lue2FycmF5fXtjY30gCjEvMiAmIDEvMlxcIAoxLzQgJiAzLzQKXGVuZHthcnJheX1ccmlnaHQpClxxdWFkIHkgXHF1YWQKXGRlbHRhID0KXGxlZnQoXGJlZ2lue2FycmF5fXtjY30gCjEvMywgCjIvMyAKXGVuZHthcnJheX1ccmlnaHQpCiQkCgpZIGRpc3RyaWJ1Y2lvbmVzIGVzdGFkby1kZXBlbmRpZW50ZXMgZGFkYXMgcG9yCgokJApQcihYLXQgPXggfCBDX3QgPSAxKSA9IDEvMiBccXVhZChwYXJhXHF1YWQgeCA9MCwxKSBcXApQcihYLXQgPTEgfCBDX3QgPSAyKSA9IDEKJCQKCkxsYW1hcmVtb3MgdW4gbW9kZWxvIGRlIGVzdGUgdGlwbyB1biBITU0gZGUgQmVybm91bGxpLiAuIENvbnNpZGVyZSBsYSBwcm9iYWJpbGlkYWQgXChQcmEoWF8xPVhfMj1YXzM9MVwpLiBQcmltZXJvLCBub3RlIHF1ZSwgcG9yIGVjdWFjaW9uZXMgYW50ZXJpb3JlcywKCiQkClByYShYXzEsWF8yLFhfMyxDXzEsQ18yLENfMyApPVByYShDXzEgKSAgUHJhKFhfMeKUgkNfMSApICBQcmEoQ18y4pSCQ18xICkgIFByYShYXzLilIJDXzIgKSAgUHJhKENfM+KUgkNfMiApIFByYShYXzMgfENfMyk7CiQkCmx1ZWdvIHN1bWFybW9zIGxvcyB2YWxvcmVzIGFzdW1pZG9zIHBvciBcKENfMSxDXzIsQ18zXCkuIEVsIHJlc3VsdGFkbyBlczoKCiQkClByKFhfMT0xLCBYXzIgPSAxLCBYMz0xKSBcXAo9IFxzdW1fe2k9MX1eMiBcc3VtX3tqPTF9XjIgXHN1bV97az0xfV4yIFByKFhfMSA9IDEsWF8yPTEsWF8zPTEsIENfMSA9aSwgQ18yPWosIENfMz1rKSBcXAo9IFxzdW1fe2k9MX1eMiBcc3VtX3tqPTF9XjIgXHN1bV97az0xfV4yIFxkZWx0YV9pIHBfaSgxKSBcZ2FtbWFfe2lqfSBwX2ooMSkgXGdhbW1hX3tqa30gcF9rKDEpCiQkCk5vdGUgcXVlIGxhIHRyaXBsZSBzdW1hIGRlIGxhIGVjdWFjacOzbiBhbnRlcmlvciB0aWVuZSBcKG1eVD0yXjNcKSB0w6lybWlub3MsIGNhZGEgZGVsIGN1YWwgZXMgcHJvZHVjdG8gZGUgXCgyVD0yIHggMyBcKWZhY3RvcmVzLiBQYXJhIGV2YWx1YXIgbGEgcHJvYmFiaWxpZGFkIHJlcXVlcmlkYSwgbGFzIGRpZmVyZW50ZXMgcG9zaWJpbGlkYWRlcyBwYXJhIGxvcyB2YWxvcmVzIGRlIGksaiB5IGsgcHVlZGVuIHNlciBsaXN0YWRvcyB5IGxhIHN1bWEgY2FsY3VsYWRhIGNvbW8gZW4gbGEgc2lndWllbnRlIHRhYmxhCgoKIVtQcm9iYWJpbGlkYWQgZGUgbGEgcHJvYmFiaWxpZGFkIGRlIHVuYSBITU0gQmVybm91bGxpXSgvVXNlcnMvYnJhY3J1ei9Eb2N1bWVudHMvOHZvLiBUcmltZXN0cmUgSU8vU2lzdC4gRXhwZXJ0b3MgeSBSZWRlcyBQcm9iLi9DSDIvVGFibGEyLTEucG5nKQoKTGEgc3VtYSBkZSBsYSDDumx0aW1hIGNvbHVtbmEgZGUgbGEgdGFibGEgYW50ZXJpb3Igbm9zIGRpY2UgcXVlIFwoUHJhKFhfMT0xLFhfMj0xLFhfMz0xKT0yOS80OFwpICAuIEFsIG9ic2VydmFyIG5vdGFtb3MgcXVlIGVsIGVsZW1lbnRvIG3DoXMgZ3JhbmRlIGVuIGVzYSBjb2x1bW5hIGVzIDMvODsgbGEgc2VjdWVuY2lhIGRlIGVzdGFkb3MgcXVlIG1heGltaXphIGxhIHByb2JhYmlsaWRhZCBjb25qdW50YQoKJCRQcihYXzEgPSAxLFhfMj0xLFhfMz0xLCBDXzEgPWksIENfMj1qLCBDXzM9aykkJApFcyBlbnRvbmNlcyBsYSBzZWN1ZW5jaWEgXChpPTIsaj0yLGs9MlwpLiBFcXVpdmFsZW50ZW1lbnRlLCBtYXhpbWl6YSBsYSBwcm9iYWJpbGlkYWQgY29uZGljaW9uYWwgXChQcmEoQ18xPWksQ18yPWosQ18zPWt8IFhfMT0xLFhfMj0xLFhfMz0xKVwpLgpQZXJvIHVuYSBtYW5lcmEgbWFzIGNvbnZlbmllbnRlIGRlIHByZXNlbnRhciBsYSBzdW1hciBlcyB1dGlsaXphciBub3RhY2nDs24gZGUgbWF0cml6LiBEZWZpbmFtb3MgUCh1KSBjb21vIFwoZGlhZyhwXzEgKHUpLHBfMiAodSkpXCkuIEVudG9uY2VzCgokJApQKDApID0gClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAoxLzIgJiAwXFwgCjAgJiAwClxlbmR7YXJyYXl9XHJpZ2h0KQpccXVhZCB5IFxxdWFkClAoMSk9ClxsZWZ0KFxiZWdpbnthcnJheX17Y2N9IAoxLzIgJiAwXFwgCjAgJiAxClxlbmR7YXJyYXl9XHJpZ2h0KQokJApZIGxhIHRyaXBsZSBzdW1hIGFudGVyaW9yIHB1ZWRlIHNlciBlc2NyaXRhIGNvbW8gZWwgcHJvZHVjdG8gZGUgdW5hIG1hdHJpegoKJCQKzrRQKDEpzpNQKDEpzpNQKDEpMScKJCQKCiMjIyMjMi4zLjIuIExhIHBvc2liaWxpZGFkIGVuIGdlbmVyYWwKCkFxdcOtIGNvbnNpZGVyYW1vcyBsYSBwb3NpYmlsaWRhZCBkZSB1biBITU0gZW4gZ2VuZXJhbC4gU3Vwb25lbW9zIGhheSB1bmEgc2VjdWVuY2lhIGRlIG9ic2VydmFjacOzbiBcKHhfMSx4XzIs4oCmLHhfVCBcKWdlbmVyYWRhIHBvciB0YWwgbW9kZWxvLiBCdXNjYW1vcyBsYSBwcm9iYWJpbGlkYWQgXChMX1RcKSBkZSBvYnNlcnZhciBlc2Egc2VjdWVuY2lhLCBzZWfDum4gbG8gY2FsY3VsYWRvIGJham8gdW4gSE1NIGRlIG0tZXN0YWRvcyBlbCBjdWFsIHRpZW5lIHVuYSBkaXN0cmlidWNpw7NuIGluaWNpYWwgXCjOtFwpIHkgdC5wLm0uIFwozpNcKSBwYXJhIGxhIGNhZGVuYSBkZSBNYXJrb3YsIGZ1bmNpb25lcyBkZSBwcm9iYWJpbGlkYWQgZXN0YWRvLWRlcGVuZGllbnRlcyBcKHBfaVwpLgoKIyMjIyMjUHJvcG9zaWNpb24gMTogTGEgcHJvYmFiaWxpZGFkIGVzIGRhZGEgcG9yCiQkCkxfVCA9IFxkZWx0YSBQKHhfMSlcR2FtbWEgUCh4XzIpIFxHYW1tYSBQKHhfMykgXHF1YWQgLi4uIFxxdWFkIFxHYW1tYSBQKHhfVCkxJwokJApzaSBcKFxkZWx0YVwpLCBsYSBkaXN0cmlidWNpb8OzbiBkZSBcKENfMVwpLCBzaSBlcyB1bmEgZGlzdHJpYnVjaW9uIGVzdGFjaW9uYXJpYSBkZSBsYSBjYWRlbmEgZGUgTWFya292LCBlbnRvbmNlczoKCiQkCkxfVCA9IFxkZWx0YSBcR2FtbWEgUCh4XzEpXEdhbW1hIFAoeF8yKSBcR2FtbWEgUCh4XzMpIFxxdWFkIC4uLiBccXVhZCBcR2FtbWEgUCh4X1QpMScKJCQKCgpVbmEgc2ltcGxlIHBlcm8gY3J1Y2lhbCBjb25zZWN1ZW5jaWEgZGUgbGEgZXhwcmVzacOzbiBtYXRyaWNpYWwgcGFyYSBsYSBwb3NpYmlsaWRhZCBlcyBlbCDigJxhbGdvcml0bW8gZGUgYXZhbmNl4oCdIHBhcmEgY29tcHV0YWNpw7NuIHJlY3Vyc2l2YSBkZSBsYSBwb3NpYmlsaWRhZC4gVGFsIGNvbXB1dGFjacOzbiByZWN1cnNpdmEganVlZ2EgdW4gcm9sIGNsYXZlLCBubyBzb2xvIGVuIGV2YWx1YWNpw7NuIGRlIGxhIHBvc2liaWxpZGFkIHkgcG9yIHRhbnRvIGVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zLCBwZXJvIHRhbWJpw6luIGVuIHByZWRlY2lyLCBkZWNvZGlmaWNhciB5IHJldmlzYXIgbW9kZWxvcy4gTGEgbmF0dXJhbGV6YSByZWN1cnNpdmEgZGUgdGFsIGV2YWx1YWNpw7NuIGRlIHBvc2liaWxpZGFkIHbDrWEgbGEgUHJvcG9zaWNpw7NuIDEgZXMgY29tcHV0YWNpb25hbG1lbnRlIG11Y2hvIG1hcyBlZmVjdGl2byBxdWUgc3VtYSBkZSBmdWVyemEgYnJ1dGEgc29icmUgdG9kYXMgbGFzIHNlY3VlbmNpYXMgZGUgZXN0YWRvIHBvc2libGUuIEVsIGhlY2hvIHF1ZSB0YWxlcyBlc3F1ZW1hcyBjb21wdXRhY2lvbmFsZXMgcmVjdXJzaXZvcyBubyBjb3N0b3NvcyBwdWVkZW4gc2VyIHV0aWxpemFkb3MgcGFyYSBhYm9yZGFyIHZhcmlhcyBwcmVndW50YXMgZGUgaW50ZXLDqXMgZXMgdW5hIGNhcmFjdGVyw61zdGljYSBjbGF2ZSBkZSBsb3MgSE1Ncy4KUGFyYSBkZWZpbmlyIGVsIGFsZ29yaXRtbyBkZSBhdmFuY2UsIGRlZmluaW1vcyBlbCB2ZWN0b3IgXCjOsV90XCkgcGFyYSBcKHQ9MSwyLOKApixUXCksIHBvcgoKJCQKXGFscGhhX3QgPSBcZGVsdGEgUCh4XzEpXEdhbW1hIFAoeF8yKSBcR2FtbWEgUCh4XzMpIFxxdWFkIC4uLiBccXVhZCBcR2FtbWEgUCh4X3QpID0gXGRlbHRhIFAoeF8xKSBccHJvZF97cz0yfV50IFxHYW1tYSBQKHhfcykKJCQKQ29uIGxhIGNvbnZlbmNpw7NuIHF1ZSB1biBwcm9kdWN0byB2YWPDrW8gZXMgbGEgbWF0cml6IGlkZW50aWRhZC4gU2lndWUgaW5tZWRpYXRhbWVudGUgZGUgZXN0YSBkZWZpbmljacOzbiBxdWUKCiQkCkxfVCA9IFxhbHBoYV9UIDEnIFxxdWFkIHkgXHF1YWQgXGFscGhhX3QgPSBcYWxwaGFfe3QtMX0gXEdhbW1hIFAoeF90KSBccXVhZCBwYXJhIFxxdWFkIHQgXGdlIDIKJCQKQWNvcmRlbWVudGUsIHBvZGVtb3MgY29udmVuaWVudGVtZW50ZSBmaWphciBjb21vIHNpZ3VlIGxhcyBjb21wdXRhY2lvbmVzIGludm9sdWNyYWRhcyBlbiBsYSBmw7NybXVsYSBkZSBwb3NpYmlsaWRhZAoKJCQKXGFscGhhXzEgPSBcZGVsdGEgUCh4XzEpIFxcClxhbHBoYV90ID0gXGFscGhhX3t0LTF9IFxHYW1tYSBQKHhfdCkgXHF1YWQgcGFyYSBccXVhZCB0ID0yLDMsLi4uLFQgXFwKTF9UID0gXGFscGhhX1QgMScKJCQKCkVsIG7Dum1lcm8gZGUgb3BlcmFjaW9uZXMgaW52b2x1Y3JhZGFzIGVzIGRlIG9yZGVuIFwoVG1eMlwpIHB1ZWRlIHNlciBkZWR1Y2lkbyBhc8OtLiBQYXJhIGNhZGEgdW5vIGRlIGxvcyB2YWxvcmVzIGRlIHQgZW4gZWwgY2ljbG8sIGhheSBtIGVsZW1lbnRvcyBkZSBcKM6xX3RcKSBwb3Igc2VyIGNvbXB1dGFkb3MsIHkgY2FkYSB1bm8gZGUgZXNvcyBlbGVtZW50b3MgZXMgdW5hIHN1bWEgZGUgbSBwcm9kdWN0b3MgZGUgdHJlcyBjYW50aWRhZGVzOiB1biBlbGVtZW50byBkZSBcKM6xX3t0LTF9XCksIHVuYSBwcm9iYWJpbGlkYWQgZGUgdHJhbnNpY2nDs24gXCjOs197aWp9XCksIHkgdW5hIHByb2JhYmlsaWRhZCAobyBkZW5zaWRhZCkgZXN0YWRvLWRlcGVuZGllbnRlIFwocF9qICh4X3QpXCkuCgpFbCBlc3F1ZW1hIGRlIGNvcnJlc3BvbmRpZW50ZSBwYXJhIGxhIGNvbXB1dGFjacOzbiBkZSBsYSBQcm9wdWVzdGEgMSBlcwoKJCQKXGFscGhhXzAgPSBcZGVsdGEgXFwKXGFscGhhX3QgPSBcYWxwaGFfe3QtMX0gXEdhbW1hIFAoeF90KSBccXVhZCBwYXJhIFxxdWFkIHQgPTEsMiwuLi4sVCBcXApMX1QgPSBcYWxwaGFfVCAxJwokJApMb3MgZWxlbWVudG9zIGRlbCB2ZWN0b3IgXCjOsV90XCkgc29uIHVzdWFsbWVudGUgcmVmZXJpZG9zIGNvbW8gcHJvYmFiaWxpZGFkZXMgZGUgYXZhbmNlOyBkb25kZSBtb3N0cmFtb3MgcXVlIGVsIGotZXNpbW8gZWxlbWVudG8gZGUgXCjOsV90XCkgZXMgXChQcmEoWF57KHQpfT14XnsodCl9LENfdD1qXCkuCkEgY29udGludWFjacOzbiwgbW9zdHJhbW9zIGPDs2RpZ28gZGUgUiBxdWUgdXRpbGl6YSBlbCBhbGdvcml0bW8gZGUgYXZhbmNlIHBhcmEgZXZhbHVhciBsYSBwb3NpYmlsaWRhZCBkZSBvYnNlcnZhY2lvbmVzIFwoeF8xLOKApnhfVFwpIGJham8gdW4gSE1NIGRlIFBvaXNzb24gY29uIHBvciBsbyBtZW5vcyBkb3MgZXN0YWRvcywgdC5wLm0uIFwozpNcKSwgdmVjdG9yIGRlIG1lZGlhcyBlc3RhZG8tZGVwZW5kaWVudGVzIFwozrtcKSwgeSBkaXN0cmlidWNpw7NuIGluaWNpYWwgXCjOtFwpLgoKCmBgYHtyfQphbHBoYSA8LSBkZWx0YSpkcG9pcyh4WzFdLCBsYW1iZGEpCmZvcihpIGluIDI6VCkgCiAgYWxwaGEgPC0gJSolIEdhbW1hKmRwb2lzKHhbaV0sbGFtYmRhKQpzdW0oYWxwaGEpCmBgYAoKCkVuIGxhIGRpc2N1c2nDs24gc3VwZXJpb3IgaGVtb3MgdXRpbGl6YWRvIGxhIGV4cHJlc2nDs24gZGUgbcO6bHRpcGxlcyBzdW1hcyBwYXJhIGxhIHBvc2liaWxpZGFkIHBhcmEgYXPDrSBsbGVnYXIgYSBsYSBleHByZXNpw7NuIG1hdHJpY2lhbCwgeSBsdWVnbyB1dGlsaXphZG8gbGEgZXhwcmVzacOzbiBtYXRyaWNpYWwgcGFyYSBsbGVnYXIgYSBsYSByZWN1cnNpw7NuIGRlIGF2YW5jZS4gVW5hIHJ1dGEgYWx0ZXJuYXRpdmEgZXMgZGVmaW5pciBlbCB2ZWN0b3IgZGUgYXZhbmNlIGRlIHByb2JhYmlsaWRhZGVzIFwozrFfdFwpIHBvcgoKJCQKXGFscGhhX3QoaikgPSBQcihYXnsodCl9ID0geF57KHQpfSwgQ190ID0gaiksIGo9MSwyLC4uLixtCiQkClkgbHVlZ28gZGVkdWNpciBsYSByZWN1cnNpw7NuIGRlIGF2YW5jZQoKJCQKXGFscGhhX3QgPSBcYWxwaGFfe3QtMX0gXEdhbW1hIFAoeF90KQokJApMYSBleHByZXNpw7NuIG1hdHJpY2lhbCBlcyBlbnRvbmNlcyB1bmEgc2ltcGxlIGNvbnNlY3VlbmNpYSBkZSBsYSByZWN1cnNpw7NuIGRlIGF2YW5jZS4KCiMjIyMjMi4zLjMgSE1NcyBubyBzb24gcHJvY2Vzb3MgZGUgTWFya292CkhNTXMgbm8gc2F0aXNmYWNlbiBlbiBnZW5lcmFsIGxhIHByb3BpZWRhZCBkZSBNYXJrb3YuIEVzdG8gbG8gcG9kZW1vcyBkZW1vc3RyYXIgbWVkaWFudGUgdW4gc2ltcGxlIGNvbnRyYWplbXBsby4KQmFzYWRvIGVuIGxhIHNlY2Npb24gMi4zLjEgc2FiZW1vcyBxdWU6CgokJApQcihYXzE9MSxYXzI9MSxYXzM9MSkgPSBcZnJhY3syOX17NDh9IFxcClByKFhfMj0xKSA9IFxmcmFjezV9ezZ9IFxcIGVudG9uY2VzIFxcClByKFhfMSxYXzI9MSkgPSBQcihYXzI9MSxYXzM9MSkgPSBcZnJhY3sxN317MjR9IFxcCnBvciBccXVhZCB0YW50byBccXVhZCBzZVxxdWFkICBkZWR1Y2VccXVhZCAgcXVlIFxcClByKFhfMz0xIHwgWF8xPTEsWF8yPTEpID0gXGZyYWN7UHIoWF8xPTEsWF8yPTEsWF8zPTEpfXtQcihYXzE9MSxYXzI9MSl9ID0gXGZyYWN7MjkvNDh9ezE3LzI0fSBcXCAKeSBccXVhZCBlc28gXFwKUHIoWF8zPTF8WF8yPTEpID0gXGZyYWN7UHIoWF8yPTEsWF8zPTEpfXtQcihYXzI9MSl9ID0gXGZyYWN7MTcvMjR9ezUvNn0gPSAxNy8yMAokJAoKUG9yIGxvIHRhbnRvIFwoUHJhKFhfMz0xfFhfMj0xKeKJoFByYShYXzM9MXxYXzE9MSxYXzI9MVwpOyBlc3RlIEhNTSBubyBzYXRpc2ZhY2UgbGEgcHJvcGllZGFkIGRlIE1hcmtvdi4gUGFyYSBsYXMgY29uZGljaW9uZXMgYmFqbyBsYXMgY3VhbGVzIHVuIEhNTSBzaSBzYXRpc2ZhY2UgbGEgcHJvcGllZGFkIGRlIE1hcmtvdi4KCgojIyMjIzIuMy40LiBMYSBwb3NpYmlsaWRhZCBjdWFuZG8gaGF5IGRhdG9zIGZhbHRhbnRlcwoKRW4gZWwgY29udGV4dG8gZGUgdW5hIHNlcmllIGRlIHRpZW1wbyBlcyBwb3RlbmNpYWxtZW50ZSByYXJvIHNpIGFsZ3Vub3MgZGUgbG9zIGRhdG9zIGZhbHRhbi4gRW4gZWwgY2FzbyBkZSBzZXJpZXMgZGUgdGllbXBvIGRlIG1vZGVsb3Mgb2N1bHRvcyBkZSBNYXJrb3YsIHNpbiBlbWJhcmdvLCBlbCBhanVzdGUgcXVlIHNlIG5lY2VzaXRhIHNlciByZWFsaXphZG8gcGFyYSBsYSBjb21wdXRhY2nDs24gZGUgbGEgcG9zaWJpbGlkYWQgc2kgaGF5IGRhdG9zIGZhbHRhbnRlcyByZXN1bHRhIHNlciB1bm8gZsOhY2lsLgpTdXBvbmdhLCBwb3IgZWplbXBsbywgcXVlIHVubyB0aWVuZSBkaXNwb25pYmxlIGxhcyBvYnNlcnZhY2lvbmVzIFwoeF8xLHhfMix4XzQseF83LHhfOCzigKYseF9UXCkgZGUgdW4gSE1NIHBlcm8gXCh4XzMseF81IFxxdWFkIHkgXHF1YWQgeF82IFwpaGFjZW4gZmFsdGEuIEVudG9uY2VzIGxhIHBvc2liaWxpZGFkIGRlIGxhcyBvYnNlcnZhY2lvbmVzIGVzdGEgZGFkYSBwb3IKCiQkClByKFhfMT14MSxYXzI9eDIsWF80PXhfNCxYXzc9eF83LFhfOD14XzgsLi4uLCxYX1Q9eF9UKSA9IFxcClxzdW0gXGRlbHRhX3tjXzF9XGdhbW1hX3tjMSxjMn1cZ2FtbWFfe2MyLGM0fSgyKSAgXGdhbW1hX3tjNCxjN30gKDMpIFxnYW1tYV97YzcsYzh9IFxxdWFkIC4uLiBccXVhZCBcZ2FtbWFfe2Nfe1QtMX0sY19UfSBcXApcdGltZXMgcF97Y18xfSAoeF8xKSBwX3tjMn0oeF8yKSBwX3tjNH0oeF80KSBwX3tjN30oeF83KVxxdWFkIC4uLiBccXVhZCAgcF97Y19UfSh4X1QpCiQkCgpEb25kZSAoY29tbyBhbnRlcykgIFwozrNfe2lqfSAoaylcKSBkZW5vdGEgdW5hIHByb2JhYmlsaWRhZCBkZSB0cmFuc2ljacOzbiBkZSBwYXNvIGssIHkgbGEgc3VtYSBzZSB0b21hIHNvYnJlIHRvZG9zIGxvcyDDrW5kaWNlcyBcKGNfdFwpIGRpZmVyZW50ZXMgZGUgXChjXzMsY181IHkgY182XCkuIFBlcm8gZXN0byBlcyBzb2xhbWVudGUKCiQkClxzdW0gXGRlbHRhX3tjXzF9IHBfe2NfMX0gKHhfMSkgXGdhbW1hX3tjXzF9LGNfMnBfe2NfMn0gKHhfMikgXGdhbW1hX3tjXzJ9LGNfNCgyKXBfe2NfNH0gKHhfNCkgXGdhbW1hX3tjXzR9LGNfNygzKXBfe2NfN30gKHhfNykgXGdhbW1hX3tjXzd9IFxxdWFkIFx0aW1lcy4uLlx0aW1lcyBccXVhZCBcZ2FtbWFfe2NfVC0xfSwgY19UIHBfe2NfVH0oeF9UKT0gXFwKXGRlbHRhIFAoeF8xKSBcR2FtbWEgUCh4XzIpXEdhbW1hXjIgUCh4XzQpIFxHYW1tYV4zIFAoeF83KS4uLlxHYW1tYSBQKHhfVCkxJwokJAoKQ29uIFwoTF9UXnstKDMsNSw2KX1cKSBkZW5vdGFuZG8gbGEgcG9zaWJpbGlkYWQgZGUgbGFzIG9ic2VydmFjaW9uZXMgKGRpZmVyZW50ZXMgZGUgbGFzIGZhbHRhbnRlcyksIHNlIGRlY2xhcmEgcXVlCgokJApMX1Reey0oMyw1LDYpfSA9IFAoeF8xKSBcR2FtbWEgUCh4XzIpXEdhbW1hXjIgUCh4XzQpIFxHYW1tYV4zIFAoeF83KS4uLlxHYW1tYSBQKHhfVCkxJwokJAoKRW4gZ2VuZXJhbCwgbGEgZXhwcmVzacOzbiBwYXJhIGxhIHBvc2liaWxpZGFkIGRlIG1hdHJpY2VzIGRpYWdvbmFsZXMgXChQKHhfdClcKSBjb3JyZXNwb25kaWVudGUgYSBsYXMgb2JzZXJ2YWNpb25lcyBmYWx0YW50ZXMgXCh4X3RcKSBzb24gcmVtcGxhemFkYXMgcG9yIGxhIG1hdHJpeiBpZGVudGlkYWQ7IGVzbyBlcywgbGFzIHByb2JhYmlsaWRhZGVzIGVzdGFkby1kZXBlbmRpZW50ZXMgY29ycmVzcG9uZGllbnRlcyBcKHBfaSAoeF90IClcKSBzb24gcmVtcGxhemFkYXMgcG9yIDEgcGFyYSB0b2RvcyBsb3MgZXN0YWRvcyBpLgoKCiMjIyMjMi4zLjUuIExhIHBvc2liaWxpZGFkIGN1YW5kbyBsYXMgb2JzZXJ2YWNpb25lcyBzb24gY2Vuc29yYWRhcyBwb3IgaW50ZXJ2YWxvCgpTdXBvbmdhIHF1ZSBkZXNlYW1vcyBhanVzdGFyIHVuIEhNTSBkZSBQb2lzc29uIGEgdW5hIHNlcmllIGRlIGN1ZW50YXMsIGFsZ3VuYXMgZGUgbGFzIGN1YWxlcyBzb24gY2Vuc29yYWRhcyBwb3IgaW50ZXJ2YWxvLiBQb3IgZWplbXBsbywgZWwgdmFsb3IgZGUgXCh4X3RcKSBwdWVkZSBzZXIgY29ub2NpZG8gcGFyYSBcKDTiiaR04omkVFwpLCBjb24gbGEgaW5mb3JtYWNpw7NuIFwoeF8x4omkNSwy4omkeF8y4omkM1wpIHkgXCh4XzM+MTBcKSBkaXNwb25pYmxlIGFjZXJjYSBkZSBsYXMgb2JzZXJ2YWNpb25lcyByZXN0YW50ZXMuIFBhcmEgc2ltcGxpZmljYXIsIGFzdW1hbW9zIGRlIHByaW1lcm8gcXVlIGxhIGNhZGVuYSBkZSBNYXJrb3Ygc29sbyB0aWVuZSBkb3MgZXN0YWRvcy4gRW4gZXNlIGNhc28sIHVubyByZW1wbGF6YSBsYXMgbWF0cmljZXMgZGlhZ29uYWxlcyBcKFAoeF9pICkoaT0xLDIsMylcKSBlbiBsYSBleHByZXNpw7NuIGRlIHBvc2liaWxpZGFkIHBvciBsYXMgbWF0cmljZXMKCiQkCmRpYWcoUHIoWF8xIFxsZSB8Q18xID0xKSwgUHIoWF8xIFxsZSA1fCBDXzE9MikpLCBcXApkaWFnKFByKDIgXGxlIFhfMiBcbGUgMyB8IENfMj0xKSxQcigyIFxsZSBYXzIgXGxlIDMgfCBDXzI9MikpIFxcCmRpYWcoUHIoWF8zIFxndCAxMCB8IENfMyA9IDEpLCBQcihYXzMgXGd0IDEwIHwgQ18zID0gMikpCiQkCgoKTWFzIGdlbmVyYWxtZW50ZSwgc3Vwb25nYSBxdWUgXChh4omkeF904omkYlwpIGRvbmRlIGEgcHVlZGUgc2VyIFwoLeKInlwpIChhdW5xdWUgZXNvIG5vIGVzIHJlbGV2YW50ZSBwYXJhIGVsIGNhc28gZGUgUG9pc3NvbiksIGIgcHVlZGUgc2VyIFwo4oieXCksIHkgbGEgY2FkZW5hIGRlIE1hcmtvdiB0aWVuZSBtIGVzdGFkb3MuIFVubyByZW1wbGF6YSBcKFAoeF90KVwpIGVuIGxhIHBvc2liaWxpZGFkIHBvciBsYSBtYXRyaXogZGlhZ29uYWwgXChtw5dtXCkgZGUgbGEgY3VhbCBlbCBlbGVtZW50byBkaWFnb25hbCBpLWVzaW1vIGVzIFwoUHJhKGHiiaRYX3TiiaRifENfdD1pKVwpCgo=