MUESTREO POR CONGLOMERADOS

DEFINICIÓN

Una muestra por conglomerados es una muestra aleatoria en la que cada unidad de muestreo es un conjunto, o conglomerado de elementos

Ejemplo de comparación gráfica de Muestreo por conglomerado y Muestreo aleatorio simple

escuelas<-read.csv("escuelas-guatemala-2020.csv")
escuelas %>% head() %>% kable()
No Codigo Departamen Municipio Latitud Longitud Nombre.Establecimiento Direccion
1 16-01-0249-43 ALTA VERAPAZ COBAN 15.76896 -90.80631 EORM COMUNIDAD CHUMILA IXILA II
2 16-01-0364-43 ALTA VERAPAZ COBAN 15.74527 -90.80307 EORM COMUNIDAD CHUMILA IXILA I
3 16-01-0592-43 ALTA VERAPAZ COBAN 15.73759 -90.78134 EOUV NO. 2 SALVADOR DE OLIVA 5A. CALLE 2-80 ZONA 3
4 16-01-0254-43 ALTA VERAPAZ COBAN 15.69186 -90.77888 EORM COMUNIDAD LA LIBERTAD XALA-ROCJA
5 16-01-0622-41 ALTA VERAPAZ COBAN 15.69186 -90.77888 COPB ANEXO A EORM COMUNIDAD CHUMILA IXILA II
6 16-01-0369-43 ALTA VERAPAZ COBAN 15.70181 -90.77606 EORM CASERIO SAPENS
muni<-sample(levels(escuelas$Municipio),30) # Muestreo de UPM

escuelas %>% 
  filter(Municipio %in% muni )->muestra_clus
escuelas %>% 
  slice_sample(n=nrow(muestra_clus))->muestra_mas

require(leaflet)     # librería  para mapas
mapa1<-muestra_mas %>% 
  leaflet() %>% 
  addTiles() %>% 
  addCircles(lng=~Longitud,lat = ~Latitud,
                   popup = ~Direccion) 

library(leaflet)
mapa2<-muestra_clus %>% 
  leaflet() %>% 
  addTiles() %>% 
  addCircles(lng=~Longitud,lat = ~Latitud,
                   popup = ~Direccion) 
mapa1
mapa2

Para explicarlo, suponga que deseamos estimar el ingreso medio por hogar en una gran ciudad. ¿Cómo debemos seleccionar la muestra? Si usamos muestreo irrestricto aleatorio, se requiere un marco que liste todos los hogares (elementos en la ciudad, y este marco puede ser muy costoso o imposible de obtener. No podemos evitar este problema al utilizar muestreo aleatorio estratificado porque incluso se requiere un marco para cada estrato de la población. En lugar de extraer una muestra aleatoria simple de elementos, podríamos dividir la ciudad en secciones tales como manzanas (o conglomerados de elementos) y seleccionar una muestra aleatoria simple de ellas. Esta tarea se realiza con facilidad mediante el uso de un marco que liste todas las manzanas de la unidad. Entonces se podría medir el ingreso de cada familia dentro de cada manzana muestreada.

Para ilustrar el segundo principio de la aplicación de muestreo por conglomerados, suponga que se cuenta con una lista de hogares de la ciudad. Podríamos seleccionar una muestra aleatoria simple de hogares, la cual probablemente estará dispersa en toda la ciudad. El coste para realizar entrevistas en los hogares dispersos va a ser grande debido al tiempo de transporte de los entrevistadores y otros gastos relacionados. El muestreo aleatorio estratificado podría reducir estos gastos, pero el uso de muestreo por conglomerados es un método más eficaz para reducir los gastos de transporte. Los elementos dentro de un conglomerado deben estar geográficamente cerca uno de otro, y entonces los gastos de transporte se reducen. Obviamente el transporte dentro de un bloque de la ciudad sería mínimo, si se comparara con el transporte asociado al muestreo aleatorio simple dentro de la ciudad. Para resumir, el muestreo por conglomerados es un diseño eficaz para obtener una cantidad especificada de información con coste mínimo, bajo las siguientes condiciones:

  1. No se encuentra disponible o es muy costoso obtener un buen marco que liste loselementos de la población, mientras que se puede lograr fácilmente un marco que liste los conglomerados.
  2. El costo para obtener observaciones se incrementa con la distancia que separa los elementos.

SELECCIÓN DE ELEMENTOS DE LA MUESTRA

La primera tarea en muestreo por conglomerados es especificar los conglomerados apropiados. Los elementos dentro de un conglomerado están con frecuencia juntos físicamente, por lo que tienden a presentar características similares. Dicho de otra manera, la medida de un elemento del conglomerado puede estar altamente correlacionada con la de otro elemento. Entonces la cantidad de información acerca de un parámetro poblacional puede no incrementarse sustancialmente al tomar nuevas medidas dentro de un conglomerado. Como las mediciones cuestan dinero, un investigador podría desperdiciar presupuesto si selecciona un conglomerado de gran tamaño. Sin embargo, pueden ocurrir situaciones en las que los elementos dentro de un conglomerado sean muy diferentes entre sí. En tales casos, una muestra que contenga pocos conglomerados grandes, puede producir una estimación muy buena de un parámetro-poblacional, tal como la media.

El problema de elegir un tamaño apropiado del conglomerado puede ser aún más complicado cuando se dispone de un número infinito de posibles tamaños de conglomerados, como en la selección de parcelas forestales para la estimación de la proporción de árboles enfermos. Si existe variabilidad en la densidad de árboles enfermos a lo largo y ancho del bosque, entonces muchas parcelas (conglomerados) pequeñas, localizadas aleatoria o sistemáticamente, pueden ser lo deseable. Aunque la localización aleatoria de una parcela en el bosque consume mucho tiempo, una vez localizada ésta, el muestreo de muchos árboles es económicamente idóneo. En este caso muchas parcelas pequeñas son adecuadas para controlar la variabilidad, pero pocas parcelas grandes son económicamente recomendables. Se debe encontrar un equilibrio entre el número y tamaño de las parcelas. No existen buenas reglas que funcionen siempre para tomar esta decisión. Cada problema debe ser estudiado de forma independiente: pero las encuestas piloto pueden ayudar al investigador a encontrar las directrices a seguir. Tenga en cuenta cuál es la principal diferencia entre la construcción óptima de estratos y la construcción de los conglomerados. Los estratos deben ser tan homogéneos (semejantes) entre ellos, como sea posible, pero un estrato debe diferir tanto como sea posible de otro con respecto a la característica que se está midiendo. Los conglomerados, por otro lado, deben ser tan heterogéneos (diferentes) entre ellos como sea posible, y un conglomerado debe ser muy similar a otro para poder aprovechar las ventajas económicas del muestreo por conglomerados.

ESTIMACIONES

El muestreo por conglomerados es muestreo aleatorio simple, con cada unidad de muestreo conteniendo un número de elementos. Por tanto, los estimadores de la media poblacional \(\mu\) y el total \(\tau\), son similares a los del muestreo aleatorio simple. En particular, la media muestral y es un buen estimador de la media poblacional \(\mu\).

Tome en cuenta lo siguiente:

  • N número de conglomerados de la población.
  • n número de conglomerados seleccionados.
  • \(m_i\) número de elementos del conglomerado i
  • \(\overline{m}=1/n\sum_{i=1}^{n}{m_i}\) tamaño medio del conglomerado en la muestra
  • \(M=\sum_{i=1}^{N}{mi}\) Número de elementos de la población.
  • \(\overline{M}=M/N\) Tamaño medio de los conglomerados
  • \(y_i\) Total de las observaciones en el i-ésimo conglomerado.
Media Proporción Total1 Total2
\({\overline y}=\frac{\sum_{i=1}^{n}y_i}{\sum_{i=1}^{n}{m_i}}\) \(\widehat{p}=\frac{\sum_{i=1}^{n}a_i}{\sum_{i=1}^{n}{m_i}}\) \(\widehat\tau=M\widehat{y}\) \(Ny_t=N/n\sum_{i=1}^{n}y_i\)

Varianzas de las estimaciones:

Media Proporción Total1 Total2
\(\widehat{V}(\overline y)=\frac{N-n}{Nn\overline{M}^2}{s_r^2}\) \(\widehat{V}(\overline p)\frac{N-n}{Nn\overline{M}^2}{s_p^2}\) \(\widehat{V}(\overline \tau)=M^2\widehat{V}(\overline y)=N ²\frac{N-n}{Nn}s_r^2\) \(\widehat{V}(\overline \tau)=N ²\frac{N-n}{Nn}s_t^2\)

con:

Media y total Proporción Total2 Total2
\(s_r^2=\frac{\sum_{i=1}^{n}(y_i-\overline{y}m_i)^2}{n-1}\) \(s_p^2=\frac{\sum_{i=1}^{n}(a_i-\overline{a}m_i)^2}{n-1}\) \(s_t^2=\frac{\sum_{i=1}^{n}(y_i-y_t)^2}{n-1}\) \(y_t=1/n\sum_{i=1}^{n}{y_i}\)

EJEMPLO

Seleccione una muestra aleatoria de 10 conglomerados para la variable Zone del conjunto de datos BigLucy, Posteriormente Realice una inferencia para la media Income, total de Employees y proporción de SPAM == si. utilizando su muestra.

library(TeachingSampling)
data("BigLucy")
set.seed(1234)
conglomerados<-sample(levels(BigLucy$Zone),10)
muestra<-BigLucy %>% 
  filter(Zone%in% conglomerados)
N<-length(levels(BigLucy$Zone))
M<-nrow(BigLucy)
n<-length(conglomerados)
muestra %>% 
  group_by(Zone) %>% 
  summarise(mi=n(),Ii=sum(Income),Ei=sum(Employees),
            ai=sum(SPAM=="yes"))->resumen
attach(resumen)
Mp=M/N            # tamaño promedio del conglomerado
Mp1=sum(mi)/10    # tamaño promedio estimado
mu_I=sum(Ii)/sum(mi)   # media del ingreso
error_m=sqrt((N-n)/(N*n*Mp1^2)*sum((Ii-mu_I*mi)^2)/(n-1)) #Error i
media<-c(v=mu_I,ee=error_m)

t_E<-N/n*sum(Ei)
mu_E=1/n*sum(Ei)    # media de número de empleados
error_t=N*sqrt((N-n)/(N*n)*sum((Ei-mu_E)^2)/(n-1)) #error t_e
total<-c(v=t_E,ee=error_t)

p_s=sum(ai)/sum(mi)    # proporción de Spam = yes
error_p=sqrt((N-n)/(N*n*Mp1^2)*sum((ai-p_s*mi)^2)/(n-1))
proporcion<-c(v=p_s,ee=error_p)

estimacion1<-cbind(media,total,proporcion)
estimacion1
##        media   total  proporcion
## v  434.72188 6869120 0.614344339
## ee  30.22362 1199281 0.003208072
g1<-ggplot(resumen,aes(mi,Ii))+
  geom_point()+
  geom_smooth(method="lm")

g2<-ggplot(resumen,aes(mi,Ei))+
  geom_point()+
  geom_smooth(method="lm")

g3<-ggplot(resumen,aes(mi,ai))+
  geom_point()+
  geom_smooth(method="lm")

g1

g2

g3

Como se puede observar existe una correlación positiva entre el tamaño del conglomerado y las tres variables a medir, condición necesaria para que la técnica de estimación de razón funcione bien (La estimación por conglomerados es prácticamente estimación de razones).

EJEMPLO CON LIBRERÍA SURVEY

Calcule las estimaciones anteriores utilizando el paquete Survey

require(survey)
muestra$fpc=100               # Tamaño de conglomerados
muestra$prob=0.1              # Probabilidad de inclusión

svydesign(data=muestra,
          ids=~Zone,
          fpc=~fpc,
          probs = ~prob)->d3        # Con corrección de pob

svymean(x=~Income,d3)->media2      # Media
svytotal(x=~Employees,d3)->total2  # Total
svymean(x=~SPAM,d3) ->proporcion2  # Proporción 
c(coef(media2),coef(total2),coef(proporcion2))->v
c(cv(media2),cv(total2),cv(proporcion2))*v->error
rbind(v,error)[,c(1,2,4)]
##          Income Employees     SPAMyes
## v     434.72188   6869120 0.614344339
## error  30.22362   1199281 0.003208072
estimacion1        # Comparación con cálculos  manuales
##        media   total  proporcion
## v  434.72188 6869120 0.614344339
## ee  30.22362 1199281 0.003208072

EJEMPLO CON MUESTREO CON LIBRERÍA SAMPLING

Tome una muestra de 3 conglomerados(Zona) de Biglucy y realice:

  • Una estimación para la para la proporción de empresas que tienen certificación ISO.
  • Una inferencia para la razón income/taxes.
library(survey)
library(sampling)
set.seed(1234)
cluster(BigLucy[order(BigLucy$Zone),],
        clustername = "Zone",
        size = 3,
        method = "srswor")->m
getdata(BigLucy,m)->muestra2

muestra2$fpc=100      #  Número de Conglomerados
svydesign(ids=~Zone,
          probs = ~Prob,
          fpc = ~fpc,
          data=muestra2)->d_clus1
svymean(~ISO,d_clus1) %>% 
  data.frame()->tabla
tabla$ISO=rownames(tabla)
  
  ggplot(tabla,aes(x=ISO,
                   y=mean,ymin=mean-SE,
                   ymax=mean+SE,
                   ymin=mean-SE,
                   fill=ISO))+
    geom_col()+
    geom_errorbar()+ggtitle("Empresas con certificación ISO")

svyratio(~Income,~Taxes,design=d_clus1)
## Ratio estimator: svyratio.survey.design2(~Income, ~Taxes, design = d_clus1)
## Ratios=
##           Taxes
## Income 39.91243
## SEs=
##          Taxes
## Income 6.98513
ggplot(muestra2,aes(x=Income,y=Taxes))+
  geom_point(shape="+",color="blue")+
  geom_smooth(method="lm",color="orange")

CÁLCULO DEL NÚMERO DE CONGLOMERADOS

La cantidad de información en una muestra por conglomerados está afectada por dos factores: el número y el tamaño relativo de los conglomerados. No se ha presentado el último factor en ninguno de los procedimientos de muestreo ya analizados. En el problema de estimación del número de casas en un estado con un seguro contra incendios insuficiente, el conglomerado puede ser un municipio, distritos electorales, distritos escolares, comunidades, o cualquier otro agrupamiento conveniente de casas. Como ya se ha visto, el tamaño del límite para el error de estimación depende fundamentalmente de la variación entre los totales de conglomerados. Entonces, al intentar obtener límites pequeños para el error de estimación, debemos seleccionar conglomerados con la menor variación posible entre estos totales. Ahora, supongamos que se ha elegido el tamaño del conglomerado (unidad de muestreo) y sólo consideraremos el problema de seleccionar el número de conglomerados.

Suponiendo que de una encuesta previa se conoce \(\sigma_r^2\) y \(\overline{M}\) y fijando el error absoluto y tomando un 95% de confianza se obtienen las siguientes formulas.

Media y Total1 Total2 Propoción
\(n=\frac{N\sigma_r^2}{ND+\sigma_r^2}\) \(n=\frac{N\sigma_t^2}{ND+\sigma_t^2}\) \(n=\frac{N\sigma_p^2}{ND+\sigma_p^2}\)

con:

Media y proporción Total1 total2
\(D=\frac{B^2\overline{M}^2}{4}\) \(D=\frac{B²}{4N^2}\)

En el caso de no conocer \(\sigma_p^2,\sigma_r^2,\sigma_t^2,\) se utiliza de forma aproximada \(S_p^2,S_r^2,S_t^2\).

EJEMPLO

Vea el ejercicio 8.9 del libro de Elementos de muestreo Se desea calcular el número de conglomerados para estimar la proporción P de residentes que viven en alquiler con un limite de error de 0.04.

conglomerados=1:25
mi=c(8,12,4,5,6,6,7,5,8,3,2,6,5,10,9,3,6,5,5,4,6,8,7,3,8)
Arendatarios=c(4,7,1,3,3,4,4,2,3,2,1,3,2,5,4,1,4,2,3,1,3,3,4,0,3)
Ingresos=c(96,121,42,65,52,40,76,65,45,50,85,43,54,49,53,50,32,22,45,37,51,30,39,47,41)
N=415
n=length(conglomerados)
P=sum(Arendatarios)/sum(mi)
Spc=sum((Arendatarios-P*mi)^2/(n-1))
error=0.04
mp=sum(mi)/n
D=error^2*(mp)^2/4
n=N*Spc/(N*D+Spc)
floor(n)
## [1] 33

Ejercicios:

8.4, 8.5, 8.11, 8.13 Experiencias con datos reales: 8.1, 8.2

BIBLIOGRARÍA

  • Cochran, W. G., & Bouclier, A. S. (1980). Técnicas de muestreo (No. 04; HA31. 2, C6 1980.). México: Compañía Editorial Continental.

  • Pérez López, C. (2005). Muestreo estadístico. Conceptos y problemas resueltos. Madrid España: Editorial Pearson Prentice Hall.

  • Mendenhall, W., Scheaffer, R. L., & Lyman Ott, R. (2006). Elementos de muestreo. Editorial Paraninfo.

  • LUMLEY, Thomas. Complex surveys: a guide to analysis using R. John Wiley & Sons, 2011.

  • Valdivieso Serrano, L. (2020). Notas de Técnicas de Muestreo.

LS0tCmF1dGhvcjogIkx1aXMgQ2FybG9zIEJvbGHDsW9zIgplbWFpbDogImxjbGJtODBAZ21haWwuY29tIgpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCkpYCcKdGl0bGU6IE1VRVNUUkVPIFBPUiBDT05HTE9NRVJBRE9TIERFIFVOQSBFVEFQQQpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgICB0b2M6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGhpZ2hsaWdodDogZXNwcmVzc28gCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKCWVjaG8gPSBUUlVFLAoJbWVzc2FnZSA9IEZBTFNFLAoJd2FybmluZyA9IEZBTFNFCikKcmVxdWlyZSh0aWR5dmVyc2UpCnJlcXVpcmUoa25pdHIpCnJlcXVpcmUoc3VydmV5KQoKCmBgYAoKIyAqKk1VRVNUUkVPIFBPUiBDT05HTE9NRVJBRE9TKioKCiMjICoqREVGSU5JQ0nDk04qKiAKCipVbmEgbXVlc3RyYSBwb3IgY29uZ2xvbWVyYWRvcyBlcyB1bmEgbXVlc3RyYSBhbGVhdG9yaWEgZW4gbGEgcXVlIGNhZGEgdW5pZGFkIGRlIG11ZXN0cmVvIGVzIHVuIGNvbmp1bnRvLCBvIGNvbmdsb21lcmFkbyBkZSBlbGVtZW50b3MqCgojIyMgRWplbXBsbyBkZSAgY29tcGFyYWNpw7NuIGdyw6FmaWNhICBkZSBNdWVzdHJlbyBwb3IgY29uZ2xvbWVyYWRvIHkgTXVlc3RyZW8gYWxlYXRvcmlvIHNpbXBsZQpgYGB7ciBNdWVzdHJvIGNvbmdsb21lcmFkbyB5IG1hc30KZXNjdWVsYXM8LXJlYWQuY3N2KCJlc2N1ZWxhcy1ndWF0ZW1hbGEtMjAyMC5jc3YiKQplc2N1ZWxhcyAlPiUgaGVhZCgpICU+JSBrYWJsZSgpCm11bmk8LXNhbXBsZShsZXZlbHMoZXNjdWVsYXMkTXVuaWNpcGlvKSwzMCkgIyBNdWVzdHJlbyBkZSBVUE0KCmVzY3VlbGFzICU+JSAKICBmaWx0ZXIoTXVuaWNpcGlvICVpbiUgbXVuaSApLT5tdWVzdHJhX2NsdXMKZXNjdWVsYXMgJT4lIAogIHNsaWNlX3NhbXBsZShuPW5yb3cobXVlc3RyYV9jbHVzKSktPm11ZXN0cmFfbWFzCgpyZXF1aXJlKGxlYWZsZXQpICAgICAjIGxpYnJlcsOtYSAgcGFyYSBtYXBhcwptYXBhMTwtbXVlc3RyYV9tYXMgJT4lIAogIGxlYWZsZXQoKSAlPiUgCiAgYWRkVGlsZXMoKSAlPiUgCiAgYWRkQ2lyY2xlcyhsbmc9fkxvbmdpdHVkLGxhdCA9IH5MYXRpdHVkLAogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+RGlyZWNjaW9uKSAKCmxpYnJhcnkobGVhZmxldCkKbWFwYTI8LW11ZXN0cmFfY2x1cyAlPiUgCiAgbGVhZmxldCgpICU+JSAKICBhZGRUaWxlcygpICU+JSAKICBhZGRDaXJjbGVzKGxuZz1+TG9uZ2l0dWQsbGF0ID0gfkxhdGl0dWQsCiAgICAgICAgICAgICAgICAgICBwb3B1cCA9IH5EaXJlY2Npb24pIAptYXBhMQptYXBhMgoKYGBgCgoKUGFyYSBleHBsaWNhcmxvLCBzdXBvbmdhIHF1ZSBkZXNlYW1vcyBlc3RpbWFyIGVsIGluZ3Jlc28gbWVkaW8gcG9yIGhvZ2FyIGVuIHVuYSBncmFuIGNpdWRhZC4gwr9Dw7NtbyBkZWJlbW9zIHNlbGVjY2lvbmFyIGxhIG11ZXN0cmE/IFNpIHVzYW1vcyBtdWVzdHJlbyBpcnJlc3RyaWN0byBhbGVhdG9yaW8sIHNlIHJlcXVpZXJlIHVuIG1hcmNvIHF1ZSBsaXN0ZSB0b2RvcyBsb3MgaG9nYXJlcyAoZWxlbWVudG9zIGVuIGxhIGNpdWRhZCwgeSBlc3RlIG1hcmNvIHB1ZWRlIHNlciBtdXkgY29zdG9zbyBvIGltcG9zaWJsZSBkZSBvYnRlbmVyLiBObyBwb2RlbW9zIGV2aXRhciBlc3RlIHByb2JsZW1hIGFsIHV0aWxpemFyIG11ZXN0cmVvIGFsZWF0b3JpbyBlc3RyYXRpZmljYWRvIHBvcnF1ZSBpbmNsdXNvIHNlIHJlcXVpZXJlIHVuIG1hcmNvIHBhcmEgY2FkYSBlc3RyYXRvIGRlIGxhIHBvYmxhY2nDs24uIEVuIGx1Z2FyIGRlIGV4dHJhZXIgdW5hIG11ZXN0cmEgYWxlYXRvcmlhIHNpbXBsZSBkZSBlbGVtZW50b3MsIHBvZHLDrWFtb3MgZGl2aWRpciBsYSBjaXVkYWQgZW4gc2VjY2lvbmVzIHRhbGVzIGNvbW8gbWFuemFuYXMgKG8gY29uZ2xvbWVyYWRvcyBkZSBlbGVtZW50b3MpIHkgc2VsZWNjaW9uYXIgdW5hIG11ZXN0cmEgYWxlYXRvcmlhIHNpbXBsZSBkZSBlbGxhcy4gRXN0YSB0YXJlYSBzZSByZWFsaXphIGNvbiBmYWNpbGlkYWQgbWVkaWFudGUgZWwgdXNvIGRlIHVuIG1hcmNvIHF1ZSBsaXN0ZSB0b2RhcyBsYXMgbWFuemFuYXMgZGUgbGEgdW5pZGFkLiBFbnRvbmNlcyBzZSBwb2Ryw61hIG1lZGlyIGVsIGluZ3Jlc28gZGUgY2FkYSBmYW1pbGlhIGRlbnRybyBkZSBjYWRhIG1hbnphbmEgbXVlc3RyZWFkYS4KClBhcmEgaWx1c3RyYXIgZWwgc2VndW5kbyBwcmluY2lwaW8gZGUgbGEgYXBsaWNhY2nDs24gZGUgbXVlc3RyZW8gcG9yIGNvbmdsb21lcmFkb3MsIHN1cG9uZ2EgcXVlIHNlIGN1ZW50YSBjb24gdW5hIGxpc3RhIGRlIGhvZ2FyZXMgZGUgbGEgY2l1ZGFkLiBQb2Ryw61hbW9zIHNlbGVjY2lvbmFyIHVuYSBtdWVzdHJhIGFsZWF0b3JpYSBzaW1wbGUgZGUgaG9nYXJlcywgbGEgY3VhbCBwcm9iYWJsZW1lbnRlIGVzdGFyw6EgZGlzcGVyc2EgZW4gdG9kYSBsYSBjaXVkYWQuIEVsIGNvc3RlIHBhcmEgcmVhbGl6YXIgZW50cmV2aXN0YXMgZW4gbG9zIGhvZ2FyZXMgZGlzcGVyc29zIHZhIGEgc2VyIGdyYW5kZSBkZWJpZG8gYWwgdGllbXBvIGRlIHRyYW5zcG9ydGUgZGUgbG9zIGVudHJldmlzdGFkb3JlcyB5IG90cm9zIGdhc3RvcyByZWxhY2lvbmFkb3MuIEVsIG11ZXN0cmVvIGFsZWF0b3JpbyBlc3RyYXRpZmljYWRvIHBvZHLDrWEgcmVkdWNpciBlc3RvcyBnYXN0b3MsIHBlcm8gZWwgdXNvIGRlIG11ZXN0cmVvIHBvciBjb25nbG9tZXJhZG9zIGVzIHVuIG3DqXRvZG8gbcOhcyBlZmljYXogcGFyYSByZWR1Y2lyIGxvcyBnYXN0b3MgZGUgdHJhbnNwb3J0ZS4gTG9zIGVsZW1lbnRvcyBkZW50cm8gZGUgdW4gY29uZ2xvbWVyYWRvIGRlYmVuIGVzdGFyIGdlb2dyw6FmaWNhbWVudGUgY2VyY2EgdW5vIGRlIG90cm8sIHkgZW50b25jZXMgbG9zIGdhc3RvcyBkZSB0cmFuc3BvcnRlIHNlIHJlZHVjZW4uIE9idmlhbWVudGUgZWwgdHJhbnNwb3J0ZSBkZW50cm8gZGUgdW4gYmxvcXVlIGRlIGxhIGNpdWRhZCBzZXLDrWEgbcOtbmltbywgc2kgc2UgY29tcGFyYXJhIGNvbiBlbCB0cmFuc3BvcnRlIGFzb2NpYWRvIGFsIG11ZXN0cmVvIGFsZWF0b3JpbyBzaW1wbGUgZGVudHJvIGRlIGxhIGNpdWRhZC4KUGFyYSByZXN1bWlyLCBlbCBtdWVzdHJlbyBwb3IgY29uZ2xvbWVyYWRvcyBlcyB1biBkaXNlw7FvIGVmaWNheiBwYXJhIG9idGVuZXIgdW5hIGNhbnRpZGFkIGVzcGVjaWZpY2FkYSBkZSBpbmZvcm1hY2nDs24gY29uIGNvc3RlIG3DrW5pbW8sIGJham8gbGFzIHNpZ3VpZW50ZXMgY29uZGljaW9uZXM6CgoxLiBObyBzZSBlbmN1ZW50cmEgZGlzcG9uaWJsZSBvIGVzIG11eSBjb3N0b3NvIG9idGVuZXIgdW4gYnVlbiBtYXJjbyBxdWUgbGlzdGUgbG9zZWxlbWVudG9zIGRlIGxhIHBvYmxhY2nDs24sIG1pZW50cmFzIHF1ZSBzZSBwdWVkZSBsb2dyYXIgZsOhY2lsbWVudGUgdW4gbWFyY28gcXVlIGxpc3RlIGxvcyBjb25nbG9tZXJhZG9zLiAKMi4gRWwgY29zdG8gcGFyYSBvYnRlbmVyIG9ic2VydmFjaW9uZXMgc2UgaW5jcmVtZW50YSBjb24gbGEgZGlzdGFuY2lhIHF1ZSBzZXBhcmEgbG9zIGVsZW1lbnRvcy4KCiMjIFNFTEVDQ0nDk04gREUgRUxFTUVOVE9TIERFIExBIE1VRVNUUkEKCkxhIHByaW1lcmEgdGFyZWEgZW4gbXVlc3RyZW8gcG9yIGNvbmdsb21lcmFkb3MgZXMgZXNwZWNpZmljYXIgbG9zIGNvbmdsb21lcmFkb3MgYXByb3BpYWRvcy4gTG9zIGVsZW1lbnRvcyBkZW50cm8gZGUgdW4gY29uZ2xvbWVyYWRvIGVzdMOhbiBjb24gZnJlY3VlbmNpYSBqdW50b3MgZsOtc2ljYW1lbnRlLCBwb3IgbG8gcXVlIHRpZW5kZW4gYSBwcmVzZW50YXIgY2FyYWN0ZXLDrXN0aWNhcyBzaW1pbGFyZXMuIERpY2hvIGRlIG90cmEgbWFuZXJhLCBsYSBtZWRpZGEgZGUgdW4gZWxlbWVudG8gZGVsIGNvbmdsb21lcmFkbyBwdWVkZSBlc3RhciBhbHRhbWVudGUgY29ycmVsYWNpb25hZGEgY29uIGxhIGRlIG90cm8gZWxlbWVudG8uIEVudG9uY2VzIGxhIGNhbnRpZGFkIGRlIGluZm9ybWFjacOzbiBhY2VyY2EgZGUgdW4gcGFyw6FtZXRybyBwb2JsYWNpb25hbCBwdWVkZSBubyBpbmNyZW1lbnRhcnNlIHN1c3RhbmNpYWxtZW50ZSBhbCB0b21hciBudWV2YXMgbWVkaWRhcyBkZW50cm8gZGUgdW4gY29uZ2xvbWVyYWRvLiBDb21vIGxhcyBtZWRpY2lvbmVzIGN1ZXN0YW4gZGluZXJvLCB1biBpbnZlc3RpZ2Fkb3IgcG9kcsOtYSBkZXNwZXJkaWNpYXIgcHJlc3VwdWVzdG8gc2kgc2VsZWNjaW9uYSB1biBjb25nbG9tZXJhZG8gZGUgZ3JhbiB0YW1hw7FvLiBTaW4gZW1iYXJnbywgcHVlZGVuIG9jdXJyaXIgc2l0dWFjaW9uZXMgZW4gbGFzIHF1ZSBsb3MgZWxlbWVudG9zIGRlbnRybyBkZSB1biBjb25nbG9tZXJhZG8gc2VhbiBtdXkgZGlmZXJlbnRlcyBlbnRyZSBzw60uIEVuIHRhbGVzIGNhc29zLCB1bmEgbXVlc3RyYSBxdWUgY29udGVuZ2EgcG9jb3MgY29uZ2xvbWVyYWRvcyBncmFuZGVzLCBwdWVkZSBwcm9kdWNpciB1bmEgZXN0aW1hY2nDs24gbXV5IGJ1ZW5hIGRlIHVuIHBhcsOhbWV0cm8tcG9ibGFjaW9uYWwsIHRhbCBjb21vIGxhIG1lZGlhLgoKRWwgcHJvYmxlbWEgZGUgZWxlZ2lyIHVuIHRhbWHDsW8gYXByb3BpYWRvIGRlbCBjb25nbG9tZXJhZG8gcHVlZGUgc2VyIGHDum4gbcOhcyBjb21wbGljYWRvIGN1YW5kbyBzZSBkaXNwb25lIGRlIHVuIG7Dum1lcm8gaW5maW5pdG8gZGUgcG9zaWJsZXMgdGFtYcOxb3MgZGUgY29uZ2xvbWVyYWRvcywgY29tbyBlbiBsYSBzZWxlY2Npw7NuIGRlIHBhcmNlbGFzIGZvcmVzdGFsZXMgcGFyYSBsYSBlc3RpbWFjacOzbiBkZSBsYSBwcm9wb3JjacOzbiBkZSDDoXJib2xlcyBlbmZlcm1vcy4gU2kgZXhpc3RlIHZhcmlhYmlsaWRhZCBlbiBsYSBkZW5zaWRhZCBkZSDDoXJib2xlcyBlbmZlcm1vcyBhIGxvIGxhcmdvIHkgYW5jaG8gZGVsIGJvc3F1ZSwgZW50b25jZXMgbXVjaGFzIHBhcmNlbGFzIChjb25nbG9tZXJhZG9zKSBwZXF1ZcOxYXMsIGxvY2FsaXphZGFzIGFsZWF0b3JpYSBvIHNpc3RlbcOhdGljYW1lbnRlLCBwdWVkZW4gc2VyIGxvIGRlc2VhYmxlLiBBdW5xdWUgbGEgbG9jYWxpemFjacOzbiBhbGVhdG9yaWEgZGUgdW5hIHBhcmNlbGEgZW4gZWwgYm9zcXVlIGNvbnN1bWUgbXVjaG8gdGllbXBvLCB1bmEgdmV6IGxvY2FsaXphZGEgw6lzdGEsIGVsIG11ZXN0cmVvIGRlIG11Y2hvcyDDoXJib2xlcyBlcyBlY29uw7NtaWNhbWVudGUgaWTDs25lby4gRW4gZXN0ZSBjYXNvIG11Y2hhcyBwYXJjZWxhcyBwZXF1ZcOxYXMgc29uIGFkZWN1YWRhcyBwYXJhIGNvbnRyb2xhciBsYSB2YXJpYWJpbGlkYWQsIHBlcm8gcG9jYXMgcGFyY2VsYXMgZ3JhbmRlcyBzb24gZWNvbsOzbWljYW1lbnRlIHJlY29tZW5kYWJsZXMuIFNlIGRlYmUgZW5jb250cmFyIHVuIGVxdWlsaWJyaW8gZW50cmUgZWwgbsO6bWVybyB5IHRhbWHDsW8gZGUgbGFzIHBhcmNlbGFzLiBObyBleGlzdGVuIGJ1ZW5hcyByZWdsYXMgcXVlIGZ1bmNpb25lbiBzaWVtcHJlIHBhcmEgdG9tYXIgZXN0YSBkZWNpc2nDs24uIENhZGEgcHJvYmxlbWEgZGViZSBzZXIgZXN0dWRpYWRvIGRlIGZvcm1hIGluZGVwZW5kaWVudGU6IHBlcm8gbGFzIGVuY3Vlc3RhcyBwaWxvdG8gcHVlZGVuIGF5dWRhciBhbCBpbnZlc3RpZ2Fkb3IgYSBlbmNvbnRyYXIgbGFzIGRpcmVjdHJpY2VzIGEgc2VndWlyLgpUZW5nYSBlbiBjdWVudGEgY3XDoWwgZXMgbGEgcHJpbmNpcGFsIGRpZmVyZW5jaWEgZW50cmUgbGEgY29uc3RydWNjacOzbiDDs3B0aW1hIGRlIGVzdHJhdG9zICB5IGxhIGNvbnN0cnVjY2nDs24gZGUgbG9zIGNvbmdsb21lcmFkb3MuIExvcyBlc3RyYXRvcyBkZWJlbiBzZXIgdGFuIGhvbW9nw6luZW9zIChzZW1lamFudGVzKSBlbnRyZSBlbGxvcywgY29tbyBzZWEgcG9zaWJsZSwgcGVybyB1biBlc3RyYXRvIGRlYmUgZGlmZXJpciB0YW50byBjb21vIHNlYSBwb3NpYmxlIGRlIG90cm8gY29uIHJlc3BlY3RvIGEgbGEgY2FyYWN0ZXLDrXN0aWNhIHF1ZSBzZSBlc3TDoSBtaWRpZW5kby4gTG9zIGNvbmdsb21lcmFkb3MsIHBvciBvdHJvIGxhZG8sIGRlYmVuIHNlciB0YW4gaGV0ZXJvZ8OpbmVvcyAoZGlmZXJlbnRlcykgZW50cmUgZWxsb3MgY29tbyBzZWEgcG9zaWJsZSwgeSB1biBjb25nbG9tZXJhZG8gZGViZSBzZXIgbXV5IHNpbWlsYXIgYSBvdHJvIHBhcmEgcG9kZXIgYXByb3ZlY2hhciBsYXMgdmVudGFqYXMgZWNvbsOzbWljYXMgZGVsIG11ZXN0cmVvIHBvciBjb25nbG9tZXJhZG9zLgoKIyMgIEVTVElNQUNJT05FUwoKRWwgbXVlc3RyZW8gcG9yIGNvbmdsb21lcmFkb3MgZXMgbXVlc3RyZW8gYWxlYXRvcmlvIHNpbXBsZSwgY29uIGNhZGEgdW5pZGFkIGRlIG11ZXN0cmVvIGNvbnRlbmllbmRvIHVuIG7Dum1lcm8gZGUgZWxlbWVudG9zLiBQb3IgdGFudG8sIGxvcyBlc3RpbWFkb3JlcyBkZSBsYSBtZWRpYSBwb2JsYWNpb25hbCAkXG11JCB5IGVsIHRvdGFsICRcdGF1JCwgc29uIHNpbWlsYXJlcyBhIGxvcyBkZWwgbXVlc3RyZW8gYWxlYXRvcmlvIHNpbXBsZS4gRW4gcGFydGljdWxhciwgbGEgbWVkaWEgbXVlc3RyYWwgeSBlcyB1biBidWVuIGVzdGltYWRvciBkZSBsYSBtZWRpYSBwb2JsYWNpb25hbCAkXG11JC4KClRvbWUgZW4gY3VlbnRhICBsbyBzaWd1aWVudGU6CgoqIE4gbsO6bWVybyBkZSBjb25nbG9tZXJhZG9zIGRlIGxhIHBvYmxhY2nDs24uCiogbiBuw7ptZXJvIGRlIGNvbmdsb21lcmFkb3Mgc2VsZWNjaW9uYWRvcy4KKiAkbV9pJCBuw7ptZXJvIGRlIGVsZW1lbnRvcyBkZWwgY29uZ2xvbWVyYWRvIGkKKiAkXG92ZXJsaW5le219PTEvblxzdW1fe2k9MX1ee259e21faX0kIHRhbWHDsW8gbWVkaW8gZGVsIGNvbmdsb21lcmFkbyAgZW4gbGEgbXVlc3RyYQoqICRNPVxzdW1fe2k9MX1ee059e21pfSQgTsO6bWVybyBkZSBlbGVtZW50b3MgZGUgbGEgcG9ibGFjacOzbi4KKiAkXG92ZXJsaW5le019PU0vTiQgIFRhbWHDsW8gbWVkaW8gZGUgbG9zIGNvbmdsb21lcmFkb3MKKiAkeV9pJCBUb3RhbCBkZSBsYXMgb2JzZXJ2YWNpb25lcyBlbiBlbCBpLcOpc2ltbyAgY29uZ2xvbWVyYWRvLgoKCnxNZWRpYXxQcm9wb3JjacOzbnxUb3RhbDF8VG90YWwyfAp8LS18LS18LS18LS18Cnwke1xvdmVybGluZSB5fT1cZnJhY3tcc3VtX3tpPTF9XntufXlfaX17XHN1bV97aT0xfV57bn17bV9pfX0kfCRcd2lkZWhhdHtwfT1cZnJhY3tcc3VtX3tpPTF9XntufWFfaX17XHN1bV97aT0xfV57bn17bV9pfX0kfCRcd2lkZWhhdFx0YXU9TVx3aWRlaGF0e3l9JHwkTnlfdD1OL25cc3VtX3tpPTF9XntufXlfaSR8CgpWYXJpYW56YXMgZGUgbGFzIGVzdGltYWNpb25lczoKCnxNZWRpYXxQcm9wb3JjacOzbnxUb3RhbDF8VG90YWwyfAp8LS18LS18LS18LS18CnwkXHdpZGVoYXR7Vn0oXG92ZXJsaW5lIHkpPVxmcmFje04tbn17Tm5cb3ZlcmxpbmV7TX1eMn17c19yXjJ9JHwkXHdpZGVoYXR7Vn0oXG92ZXJsaW5lIHApXGZyYWN7Ti1ufXtOblxvdmVybGluZXtNfV4yfXtzX3BeMn0kfCRcd2lkZWhhdHtWfShcb3ZlcmxpbmUgXHRhdSk9TV4yXHdpZGVoYXR7Vn0oXG92ZXJsaW5lIHkpPU4gwrJcZnJhY3tOLW59e05ufXNfcl4yJHwkXHdpZGVoYXR7Vn0oXG92ZXJsaW5lIFx0YXUpPU4gwrJcZnJhY3tOLW59e05ufXNfdF4yJHwKCmNvbjoKCnxNZWRpYSB5IHRvdGFsfFByb3BvcmNpw7NufFRvdGFsMnxUb3RhbDJ8CnwtLXwtLXwtLXwtLXwKfCRzX3JeMj1cZnJhY3tcc3VtX3tpPTF9XntufSh5X2ktXG92ZXJsaW5le3l9bV9pKV4yfXtuLTF9JHwkc19wXjI9XGZyYWN7XHN1bV97aT0xfV57bn0oYV9pLVxvdmVybGluZXthfW1faSleMn17bi0xfSR8JHNfdF4yPVxmcmFje1xzdW1fe2k9MX1ee259KHlfaS15X3QpXjJ9e24tMX0kfCR5X3Q9MS9uXHN1bV97aT0xfV57bn17eV9pfSQKCgoKIyMjIEVKRU1QTE8gCgpTZWxlY2Npb25lIHVuYSBtdWVzdHJhIGFsZWF0b3JpYSBkZSAxMCBjb25nbG9tZXJhZG9zIHBhcmEgbGEgdmFyaWFibGUgWm9uZSAgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGBCaWdMdWN5YCwgIFBvc3Rlcmlvcm1lbnRlICBSZWFsaWNlIHVuYSBpbmZlcmVuY2lhIHBhcmEgbGEgbWVkaWEgYEluY29tZWAsIHRvdGFsIGRlIGBFbXBsb3llZXNgIHkgcHJvcG9yY2nDs24gZGUgYFNQQU1gID09IHNpLiAgdXRpbGl6YW5kbyBzdSBtdWVzdHJhLiAKCgoKYGBge3IgZWplbXBsbyBmb3JtdWxhcyB9CmxpYnJhcnkoVGVhY2hpbmdTYW1wbGluZykKZGF0YSgiQmlnTHVjeSIpCnNldC5zZWVkKDEyMzQpCmNvbmdsb21lcmFkb3M8LXNhbXBsZShsZXZlbHMoQmlnTHVjeSRab25lKSwxMCkKbXVlc3RyYTwtQmlnTHVjeSAlPiUgCiAgZmlsdGVyKFpvbmUlaW4lIGNvbmdsb21lcmFkb3MpCk48LWxlbmd0aChsZXZlbHMoQmlnTHVjeSRab25lKSkKTTwtbnJvdyhCaWdMdWN5KQpuPC1sZW5ndGgoY29uZ2xvbWVyYWRvcykKbXVlc3RyYSAlPiUgCiAgZ3JvdXBfYnkoWm9uZSkgJT4lIAogIHN1bW1hcmlzZShtaT1uKCksSWk9c3VtKEluY29tZSksRWk9c3VtKEVtcGxveWVlcyksCiAgICAgICAgICAgIGFpPXN1bShTUEFNPT0ieWVzIikpLT5yZXN1bWVuCmF0dGFjaChyZXN1bWVuKQpNcD1NL04gICAgICAgICAgICAjIHRhbWHDsW8gcHJvbWVkaW8gZGVsIGNvbmdsb21lcmFkbwpNcDE9c3VtKG1pKS8xMCAgICAjIHRhbWHDsW8gcHJvbWVkaW8gZXN0aW1hZG8KbXVfST1zdW0oSWkpL3N1bShtaSkgICAjIG1lZGlhIGRlbCBpbmdyZXNvCmVycm9yX209c3FydCgoTi1uKS8oTipuKk1wMV4yKSpzdW0oKElpLW11X0kqbWkpXjIpLyhuLTEpKSAjRXJyb3IgaQptZWRpYTwtYyh2PW11X0ksZWU9ZXJyb3JfbSkKCnRfRTwtTi9uKnN1bShFaSkKbXVfRT0xL24qc3VtKEVpKSAgICAjIG1lZGlhIGRlIG7Dum1lcm8gZGUgZW1wbGVhZG9zCmVycm9yX3Q9TipzcXJ0KChOLW4pLyhOKm4pKnN1bSgoRWktbXVfRSleMikvKG4tMSkpICNlcnJvciB0X2UKdG90YWw8LWModj10X0UsZWU9ZXJyb3JfdCkKCnBfcz1zdW0oYWkpL3N1bShtaSkgICAgIyBwcm9wb3JjacOzbiBkZSBTcGFtID0geWVzCmVycm9yX3A9c3FydCgoTi1uKS8oTipuKk1wMV4yKSpzdW0oKGFpLXBfcyptaSleMikvKG4tMSkpCnByb3BvcmNpb248LWModj1wX3MsZWU9ZXJyb3JfcCkKCmVzdGltYWNpb24xPC1jYmluZChtZWRpYSx0b3RhbCxwcm9wb3JjaW9uKQplc3RpbWFjaW9uMQoKZzE8LWdncGxvdChyZXN1bWVuLGFlcyhtaSxJaSkpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIikKCmcyPC1nZ3Bsb3QocmVzdW1lbixhZXMobWksRWkpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpCgpnMzwtZ2dwbG90KHJlc3VtZW4sYWVzKG1pLGFpKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iKQoKZzEKZzIKZzMKYGBgCkNvbW8gc2UgcHVlZGUgb2JzZXJ2YXIgZXhpc3RlIHVuYSBjb3JyZWxhY2nDs24gcG9zaXRpdmEgZW50cmUgZWwgdGFtYcOxbyBkZWwgY29uZ2xvbWVyYWRvIHkgbGFzIHRyZXMgdmFyaWFibGVzIGEgbWVkaXIsIGNvbmRpY2nDs24gbmVjZXNhcmlhIHBhcmEgcXVlIGxhIHTDqWNuaWNhIGRlIGVzdGltYWNpw7NuICBkZSByYXrDs24gZnVuY2lvbmUgYmllbiAoTGEgZXN0aW1hY2nDs24gcG9yIGNvbmdsb21lcmFkb3MgZXMgcHLDoWN0aWNhbWVudGUgIGVzdGltYWNpw7NuIGRlIHJhem9uZXMpLiAKCiMjIyBFSkVNUExPIENPTiBMSUJSRVLDjUEgU1VSVkVZCgpDYWxjdWxlICBsYXMgZXN0aW1hY2lvbmVzIGFudGVyaW9yZXMgdXRpbGl6YW5kbyBlbCBwYXF1ZXRlIFN1cnZleQoKYGBge3IgZWplbXBsbyBzdXJ2ZXl9CnJlcXVpcmUoc3VydmV5KQptdWVzdHJhJGZwYz0xMDAgICAgICAgICAgICAgICAjIFRhbWHDsW8gZGUgY29uZ2xvbWVyYWRvcwptdWVzdHJhJHByb2I9MC4xICAgICAgICAgICAgICAjIFByb2JhYmlsaWRhZCBkZSBpbmNsdXNpw7NuCgpzdnlkZXNpZ24oZGF0YT1tdWVzdHJhLAogICAgICAgICAgaWRzPX5ab25lLAogICAgICAgICAgZnBjPX5mcGMsCiAgICAgICAgICBwcm9icyA9IH5wcm9iKS0+ZDMgICAgICAgICMgQ29uIGNvcnJlY2Npw7NuIGRlIHBvYgoKc3Z5bWVhbih4PX5JbmNvbWUsZDMpLT5tZWRpYTIgICAgICAjIE1lZGlhCnN2eXRvdGFsKHg9fkVtcGxveWVlcyxkMyktPnRvdGFsMiAgIyBUb3RhbApzdnltZWFuKHg9flNQQU0sZDMpIC0+cHJvcG9yY2lvbjIgICMgUHJvcG9yY2nDs24gCmMoY29lZihtZWRpYTIpLGNvZWYodG90YWwyKSxjb2VmKHByb3BvcmNpb24yKSktPnYKYyhjdihtZWRpYTIpLGN2KHRvdGFsMiksY3YocHJvcG9yY2lvbjIpKSp2LT5lcnJvcgpyYmluZCh2LGVycm9yKVssYygxLDIsNCldCmVzdGltYWNpb24xICAgICAgICAjIENvbXBhcmFjacOzbiBjb24gY8OhbGN1bG9zICBtYW51YWxlcwpgYGAKCiMjIyBFSkVNUExPIENPTiBNVUVTVFJFTyBDT04gTElCUkVSw41BIFNBTVBMSU5HCgpUb21lIHVuYSBtdWVzdHJhIGRlICAzIGNvbmdsb21lcmFkb3MoWm9uYSkgZGUgQmlnbHVjeSB5IHJlYWxpY2U6CgoqIFVuYSBlc3RpbWFjacOzbiBwYXJhIGxhIHBhcmEgbGEgcHJvcG9yY2nDs24gZGUgZW1wcmVzYXMgcXVlIHRpZW5lbiBjZXJ0aWZpY2FjacOzbiBJU08uCiogVW5hIGluZmVyZW5jaWEgcGFyYSBsYSAgcmF6w7NuIGBpbmNvbWVgL2B0YXhlc2AuCgoKYGBge3IgZWplbXBsbyBzdXJ2ZXkgeSBzYW1wbGluZ30KbGlicmFyeShzdXJ2ZXkpCmxpYnJhcnkoc2FtcGxpbmcpCnNldC5zZWVkKDEyMzQpCmNsdXN0ZXIoQmlnTHVjeVtvcmRlcihCaWdMdWN5JFpvbmUpLF0sCiAgICAgICAgY2x1c3Rlcm5hbWUgPSAiWm9uZSIsCiAgICAgICAgc2l6ZSA9IDMsCiAgICAgICAgbWV0aG9kID0gInNyc3dvciIpLT5tCmdldGRhdGEoQmlnTHVjeSxtKS0+bXVlc3RyYTIKCm11ZXN0cmEyJGZwYz0xMDAgICAgICAjICBOw7ptZXJvIGRlIENvbmdsb21lcmFkb3MKc3Z5ZGVzaWduKGlkcz1+Wm9uZSwKICAgICAgICAgIHByb2JzID0gflByb2IsCiAgICAgICAgICBmcGMgPSB+ZnBjLAogICAgICAgICAgZGF0YT1tdWVzdHJhMiktPmRfY2x1czEKc3Z5bWVhbih+SVNPLGRfY2x1czEpICU+JSAKICBkYXRhLmZyYW1lKCktPnRhYmxhCnRhYmxhJElTTz1yb3duYW1lcyh0YWJsYSkKICAKICBnZ3Bsb3QodGFibGEsYWVzKHg9SVNPLAogICAgICAgICAgICAgICAgICAgeT1tZWFuLHltaW49bWVhbi1TRSwKICAgICAgICAgICAgICAgICAgIHltYXg9bWVhbitTRSwKICAgICAgICAgICAgICAgICAgIHltaW49bWVhbi1TRSwKICAgICAgICAgICAgICAgICAgIGZpbGw9SVNPKSkrCiAgICBnZW9tX2NvbCgpKwogICAgZ2VvbV9lcnJvcmJhcigpK2dndGl0bGUoIkVtcHJlc2FzIGNvbiBjZXJ0aWZpY2FjacOzbiBJU08iKQogIApzdnlyYXRpbyh+SW5jb21lLH5UYXhlcyxkZXNpZ249ZF9jbHVzMSkKCmdncGxvdChtdWVzdHJhMixhZXMoeD1JbmNvbWUseT1UYXhlcykpKwogIGdlb21fcG9pbnQoc2hhcGU9IisiLGNvbG9yPSJibHVlIikrCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsY29sb3I9Im9yYW5nZSIpCgpgYGAKCiMjIEPDgUxDVUxPIERFTCBOw5pNRVJPIERFIENPTkdMT01FUkFET1MKCkxhIGNhbnRpZGFkIGRlIGluZm9ybWFjacOzbiBlbiB1bmEgbXVlc3RyYSBwb3IgY29uZ2xvbWVyYWRvcyBlc3TDoSBhZmVjdGFkYSBwb3IgZG9zIGZhY3RvcmVzOiBlbCBuw7ptZXJvIHkgZWwgdGFtYcOxbyByZWxhdGl2byBkZSBsb3MgY29uZ2xvbWVyYWRvcy4gTm8gc2UgaGEgcHJlc2VudGFkbyBlbCDDumx0aW1vIGZhY3RvciBlbiBuaW5ndW5vIGRlIGxvcyBwcm9jZWRpbWllbnRvcyBkZSBtdWVzdHJlbyB5YSBhbmFsaXphZG9zLiBFbiBlbCBwcm9ibGVtYSBkZSBlc3RpbWFjacOzbiBkZWwgbsO6bWVybyBkZSBjYXNhcyBlbiB1biBlc3RhZG8gY29uIHVuIHNlZ3VybyBjb250cmEgaW5jZW5kaW9zIGluc3VmaWNpZW50ZSwgZWwgY29uZ2xvbWVyYWRvIHB1ZWRlIHNlciB1biBtdW5pY2lwaW8sIGRpc3RyaXRvcyBlbGVjdG9yYWxlcywgZGlzdHJpdG9zIGVzY29sYXJlcywgY29tdW5pZGFkZXMsIG8gY3VhbHF1aWVyIG90cm8gYWdydXBhbWllbnRvIGNvbnZlbmllbnRlIGRlIGNhc2FzLiBDb21vIHlhIHNlIGhhIHZpc3RvLCBlbCB0YW1hw7FvIGRlbCBsw61taXRlIHBhcmEgZWwgZXJyb3IgZGUgZXN0aW1hY2nDs24gZGVwZW5kZSBmdW5kYW1lbnRhbG1lbnRlIGRlIGxhIHZhcmlhY2nDs24gZW50cmUgbG9zIHRvdGFsZXMgZGUgY29uZ2xvbWVyYWRvcy4gRW50b25jZXMsIGFsIGludGVudGFyIG9idGVuZXIgbMOtbWl0ZXMgcGVxdWXDsW9zIHBhcmEgZWwgZXJyb3IgZGUgZXN0aW1hY2nDs24sIGRlYmVtb3Mgc2VsZWNjaW9uYXIgY29uZ2xvbWVyYWRvcyBjb24gbGEgbWVub3IgdmFyaWFjacOzbiBwb3NpYmxlIGVudHJlIGVzdG9zIHRvdGFsZXMuIEFob3JhLCBzdXBvbmdhbW9zIHF1ZSBzZSBoYSBlbGVnaWRvIGVsIHRhbWHDsW8gZGVsIGNvbmdsb21lcmFkbyAodW5pZGFkIGRlIG11ZXN0cmVvKSB5IHPDs2xvIGNvbnNpZGVyYXJlbW9zIGVsIHByb2JsZW1hIGRlIHNlbGVjY2lvbmFyIGVsIG7Dum1lcm8gZGUgY29uZ2xvbWVyYWRvcy4gCgpTdXBvbmllbmRvIHF1ZSBkZSB1bmEgZW5jdWVzdGEgcHJldmlhIHNlIGNvbm9jZSAkXHNpZ21hX3JeMiQgeSAkXG92ZXJsaW5le019JCB5IGZpamFuZG8gZWwgZXJyb3IgYWJzb2x1dG8gIHkgdG9tYW5kbyB1biA5NSUgZGUgY29uZmlhbnphIHNlIG9idGllbmVuIGxhcyBzaWd1aWVudGVzIGZvcm11bGFzLgoKCnxNZWRpYSB5IFRvdGFsMXxUb3RhbDJ8UHJvcG9jacOzbnwKfC0tfC0tfC0tfAp8JG49XGZyYWN7TlxzaWdtYV9yXjJ9e05EK1xzaWdtYV9yXjJ9JHwkbj1cZnJhY3tOXHNpZ21hX3ReMn17TkQrXHNpZ21hX3ReMn0kfCRuPVxmcmFje05cc2lnbWFfcF4yfXtORCtcc2lnbWFfcF4yfSR8Cgpjb246Cgp8TWVkaWEgeSBwcm9wb3JjacOzbnxUb3RhbDEgdG90YWwyfAp8LS18LS18CnwkRD1cZnJhY3tCXjJcb3ZlcmxpbmV7TX1eMn17NH0kfCREPVxmcmFje0LCsn17NE5eMn0kfAoKRW4gZWwgY2FzbyBkZSBubyBjb25vY2VyICRcc2lnbWFfcF4yLFxzaWdtYV9yXjIsXHNpZ21hX3ReMiwkIHNlIHV0aWxpemEgZGUgZm9ybWEgYXByb3hpbWFkYSAkU19wXjIsU19yXjIsU190XjIkLgoKCgoKIyMjIEVKRU1QTE8KClZlYSBlbCBlamVyY2ljaW8gOC45IGRlbCBsaWJybyBkZSBFbGVtZW50b3MgZGUgbXVlc3RyZW8gClNlIGRlc2VhIGNhbGN1bGFyIGVsIG7Dum1lcm8gZGUgY29uZ2xvbWVyYWRvcyBwYXJhIGVzdGltYXIgbGEgcHJvcG9yY2nDs24gUCBkZSByZXNpZGVudGVzIHF1ZSB2aXZlbiBlbiBhbHF1aWxlciBjb24gdW4gbGltaXRlIGRlIGVycm9yIGRlIDAuMDQuCgoKCgpgYGB7ciBlamVtcGxvIGRlbCBsaWJyb30KY29uZ2xvbWVyYWRvcz0xOjI1Cm1pPWMoOCwxMiw0LDUsNiw2LDcsNSw4LDMsMiw2LDUsMTAsOSwzLDYsNSw1LDQsNiw4LDcsMyw4KQpBcmVuZGF0YXJpb3M9Yyg0LDcsMSwzLDMsNCw0LDIsMywyLDEsMywyLDUsNCwxLDQsMiwzLDEsMywzLDQsMCwzKQpJbmdyZXNvcz1jKDk2LDEyMSw0Miw2NSw1Miw0MCw3Niw2NSw0NSw1MCw4NSw0Myw1NCw0OSw1Myw1MCwzMiwyMiw0NSwzNyw1MSwzMCwzOSw0Nyw0MSkKTj00MTUKbj1sZW5ndGgoY29uZ2xvbWVyYWRvcykKUD1zdW0oQXJlbmRhdGFyaW9zKS9zdW0obWkpClNwYz1zdW0oKEFyZW5kYXRhcmlvcy1QKm1pKV4yLyhuLTEpKQplcnJvcj0wLjA0Cm1wPXN1bShtaSkvbgpEPWVycm9yXjIqKG1wKV4yLzQKbj1OKlNwYy8oTipEK1NwYykKZmxvb3IobikKCmBgYAoKIyMjIEVqZXJjaWNpb3M6CjguNCwgOC41LCA4LjExLCA4LjEzCkV4cGVyaWVuY2lhcyBjb24gZGF0b3MgcmVhbGVzOiA4LjEsIDguMgoKIyMgQklCTElPR1JBUsONQQoKKiBDb2NocmFuLCBXLiBHLiwgJiBCb3VjbGllciwgQS4gUy4gKDE5ODApLiBUw6ljbmljYXMgZGUgbXVlc3RyZW8gKE5vLiAwNDsgSEEzMS4gMiwgQzYgMTk4MC4pLiBNw6l4aWNvOiBDb21wYcOxw61hIEVkaXRvcmlhbCBDb250aW5lbnRhbC4KCiogUMOpcmV6IEzDs3BleiwgQy4gKDIwMDUpLiBNdWVzdHJlbyBlc3RhZMOtc3RpY28uIENvbmNlcHRvcyB5IHByb2JsZW1hcyByZXN1ZWx0b3MuIE1hZHJpZCBFc3Bhw7FhOiBFZGl0b3JpYWwgUGVhcnNvbiBQcmVudGljZSBIYWxsLgoKKiBNZW5kZW5oYWxsLCBXLiwgU2NoZWFmZmVyLCBSLiBMLiwgJiBMeW1hbiBPdHQsIFIuICgyMDA2KS4gRWxlbWVudG9zIGRlIG11ZXN0cmVvLiBFZGl0b3JpYWwgUGFyYW5pbmZvLgoKKiBMVU1MRVksIFRob21hcy4gQ29tcGxleCBzdXJ2ZXlzOiBhIGd1aWRlIHRvIGFuYWx5c2lzIHVzaW5nIFIuIEpvaG4gV2lsZXkgJiBTb25zLCAyMDExLgoKKiBWYWxkaXZpZXNvIFNlcnJhbm8sIEwuICgyMDIwKS4gTm90YXMgZGUgVMOpY25pY2FzIGRlIE11ZXN0cmVvLgoK