O presente post refere-se a um trabalho de análise da complexidade
econômica do MS a partir dos dados do emprego. Este trabalho foi
desenvolvido na disciplina de Economia Regional e Urbana com a
orientação do Prof. Dr. Adriano Figueiredo (e-mail: adriano.figueiredo@ufms.br)
Os dados usados e os resultados obtidos podem ser encontrados
e baixados em um repositório no GitHub
(caso o link dê algum erro tente clicar nele com o botão direito do
mouse para, em seguida, clicar em “Abrir link em nova
guia”).
1 Introdução
Diversos teóricos clássicos do desenvolvimento ressaltam o papel
importante da estrutura produtiva no processo de desenvolvimento
econômico (ROSENSTEIN-RODAN, 1943; LEWIS, 1955; HIRSCHMAN, 1958;
PREBISCH, 1962; KUZNETS, 1966; KALDOR, 1966; FURTADO, 1964). Em outras
palavras, na academia, há uma literatura madura que descreve como que a
mudança das dinâmicas inter e intra setoriais afetam qualitativamente o
plano econômico. Nesse sentido, o trabalho dos pesquisadores Hausmann
et al. (2013) sintetizaram tal bagagem teórica em um métodolo
de cálculo do que eles passaram a chamar de complexidade econômica.
Assim, criou-se, a partir do índice de vatagens comparativas reveladas
(VCR) desenvolvido por Balassa (1965), métricas de complexidade e de
análise do produto-espaço, como por exeplo o índice de complexisdade
econômica (ICE) (HIDALGO; HAUSMANN, 2009; HAUSMANN et al.,
2013). Em suma, segundo Hausmann et al.(2013) a complexidade
econômica provou ser uma métrica importante para compreender a
disparidade no nível de renda entre diversas economias e, em alguns
casos, até provou ser um forte preditor do futuro crescimento do
PIB.
Originalmente, Hausmann et al.(2013) propõem esta
metodologia de análise da complexidade em um âmbito global a partir de
dados do comércio internacional. Não obstante, o presente trabalho
apoia-se na proposta de Silva Junior et al. (2019), a qual
adapta os indicadores de complexidade para a análise regional ao usar
dados do emprego. Diante dsso, utilizou-se, para a análise da
complexidade econômica do MS, dados da RAIS vincúlo distribuídos entre
os setores delimitados pelas classes CNAE 2.0 entre o ano de 2006 e
2022.
2 Puxando os pacotes
#PACOTES USADOS
{
library(readxl) # para ler excel xlsx e xls
library(psych)
library(knitr)
library(tidyverse) # para trabalhar dados com tibble
library(ggplot2) # para fazer plots e mapas
library(writexl) # para gerar xlsx ou xls
library(EconGeo) # para a maioria dos indicadores regionais
library(REAT) # para alguns indicadores regionais
library(inspectdf) # para inspecionar dataframes
library(geobr) # para baixar shapes brasileiros, para mapas
library(ggspatial) # para colocar norte e escala nos mapas
library(sf) # para fazer mapas
library(DT) #para exposição dos dados
}
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.1.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ ggplot2::%+%() masks psych::%+%()
## ✖ ggplot2::alpha() masks psych::alpha()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
##
## Please cite EconGeo in publications as:
##
##
## Balland, P.A. (2017) Economic Geography in R: Introduction to the EconGeo Package, Papers in Evolutionary Economic Geography, 17 (09): 1-75
##
##
##
## Anexando pacote: 'REAT'
##
##
## Os seguintes objetos são mascarados por 'package:EconGeo':
##
## gini, rca
##
##
## O seguinte objeto é mascarado por 'package:readr':
##
## spec
##
##
## O seguinte objeto é mascarado por 'package:psych':
##
## mssd
##
##
## Carregando namespace exigido: sf
##
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
3 Criando funções
Devido ao grande número de datasets usados, visto que para cada ano
entre 2006 e 2022 há um dataset diferente, foram construídas 6 funções
para otimizar o script. Vale ressaltar que a função 2 corrigir_CNAE()
foi criada para resolver um problema atrelado ao painel de dados. Em
suma, entre os 79 municípios do MS, o município Paríso das Águas surgiu
em 2013 a partir de 3 outros municípios, isto é Água Clara, Chapadão do
Sul e Costa Rica. Assim, no dataset original não há o município Paraíso
das Águas antes de 2013, mas, para padronizar o painel de dados, este
município foi simulado nos períodos ausentes.
###############################Funções Utilizadas###############################
# 1. Função para ler os CNAEs de 2006 a 2022 e armazenar em uma lista
ler_dados_CNAE <- function(arquivo, anos) {
lista_dados <- list() # Inicializando uma lista vazia para armazenar cada dataframe
for (ano in anos) { # Loop pelos anos especificados
nome_sheet <- paste0("CNAE_", ano) # Definindo o nome do sheet com base no ano atual
lista_dados[[nome_sheet]] <- read_excel(arquivo, sheet = nome_sheet) # Lendo o sheet e armazenando na lista
}
return(lista_dados) # Retornando a lista com todos os dataframes
}
# 2. Função para corrigir dados de Paraiso das Aguas, Agua Clara, Costa Rica e Chapadao do Sul
corrigir_CNAE <- function(lista_dados, anos) {
lista_dados_corrigidos <- list() # Inicializando uma lista vazia para armazenar os dataframes corrigidos com seus nomes
for (i in 1:length(lista_dados)) { # Loop pelos dataframes na lista
df <- lista_dados[[i]] # Selecionando o dataframe atual
if (i <= 7) { # Verifica se i é menor ou igual a 7
df_correcao <- df[1:79, 2:677] # Selecionando as linhas e colunas conforme o código original
df_novo <- df_correcao
df_novo[1, ] <- (1 - 0.335) * df_correcao[1, ] # Modificar a linha 1 com o fator (1 - 0.335)
df_novo[23, ] <- (1 - 0.186) * df_correcao[23, ] # Modificar a linha 23 com o fator (1 - 0.186)
df_novo[27, ] <- (1 - 0.479) * df_correcao[27, ] # Modificar a linha 27 com o fator (1 - 0.479)
df_novo[58, ] <- 0.335 * df_correcao[1, ] + 0.186 * df_correcao[23, ] + 0.479 * df_correcao[27, ] # Calcular a combinação ponderada para a linha 58
} else {
df_novo <- df[1:79, 2:677] # Se i for maior que 7, apenas copia o dataframe original
}
nome_dataframe <- paste0("CNAE_", anos[i]) # Gerar um nome para o dataframe
lista_dados_corrigidos[[nome_dataframe]] <- df_novo # Armazenando o dataframe (corrigido ou original) na lista com o nome gerado
}
return(lista_dados_corrigidos) # Retornando a lista com os dataframes corrigidos ou originais
}
# 3. Função para calcular Diversidade para os estados do MS de 2006 a 2022
calcular_Diversidade <- function(lista_dados, anos, mun) {
lista_Div <- list()
for (i in 1:length(lista_dados)) {
df <- lista_dados[[i]] # Selecionando o dataframe atual
nome_df <- paste0("Div_MS_", anos[i]) # Gerar um nome para o dataframe usando o ano correspondente
lista_Div[[nome_df]] <- as.data.frame(diversity(df, rca = TRUE)) # Aplicar a função 'diversity' ao dataframe, calculando o Diversidade
lista_Div[[nome_df]] <- cbind(mun, lista_Div[[nome_df]]) # Adicionar a variável 'mun' como uma nova coluna ao dataframe resultante
colnames(lista_Div[[nome_df]])[2] <- "Diversidade" # Renomeando apenas a segunda coluna
}
return(lista_Div) # Retornando a lista com os dataframes corrigidos
}
# 4. Função para calcular Ubiquidade para os estados do MS de 2006 a 2022
calcular_Ubiquidade <- function(lista_dados, anos) {
lista_Ubi <- list()
for (i in 1:length(lista_dados)) {
df <- lista_dados[[i]] # Selecionando o dataframe atual
nome_df <- paste0("Ubi_MS_", anos[i]) # Gerar um nome para o dataframe usando o ano correspondente
lista_Ubi[[nome_df]] <- as.data.frame(ubiquity(df, rca = TRUE)) # Aplicar a função 'ubiquity' ao dataframe, calculando o Ubiquidade
colnames(lista_Ubi[[nome_df]])[1] <- "Ubiquidade" # Renomeando apenas a segunda coluna
}
return(lista_Ubi) # Retornando a lista com os dataframes corrigidos
}
# 5. Função para criar o Indice de Complexidade Economica Para os estados do MS de 2006 a 2022
calcular_ICE <- function(lista_dados, anos, mun) {
lista_ICE <- list()
for (i in 1:length(lista_dados)) {
df <- lista_dados[[i]] # Selecionando o dataframe atual
nome_df <- paste0("ICE_MS_", anos[i]) # Gerar um nome para o dataframe usando o ano correspondente
lista_ICE[[nome_df]] <- as.data.frame(morc(df, rca = TRUE)) # Aplicar a função 'morc' ao dataframe, calculando o ICE
lista_ICE[[nome_df]] <- cbind(mun, lista_ICE[[nome_df]]) # Adicionar a variável 'mun' como uma nova coluna ao dataframe resultante
colnames(lista_ICE[[nome_df]])[2] <- "ICE" # Renomeando apenas a segunda coluna
}
return(lista_ICE) # Retornando a lista com os dataframes corrigidos
}
# 6. Função para consolidar dados de ICE de diferentes anos em um único DataFrame
consolidar_ICE <- function(lista_ICE, anos) {
dados_ICE <- list() # Inicializando uma lista vazia para armazenar os dados de ICE de cada ano
for (i in seq_along(lista_ICE)) {
dados_ICE[[i]] <- lista_ICE[[i]][, "ICE"] # Extrai a coluna "ICE" do DataFrame atual e adiciona à lista de dados_ICE
}
df_ICE_consolidado <- do.call(cbind, dados_ICE) # Combina os dados em um único DataFrame e define os nomes das colunas como os anos
colnames(df_ICE_consolidado) <- anos # Define os nomes das colunas como os anos fornecidos
return(df_ICE_consolidado)
}
5 Calculando os indicadores
Neste trabalho serão calculados três indicadores. Serão eles a
diversidade, a ubiquidade e o índice de complexidade econômica.
5.1 Diversidade
A diversidade equivale ao número de setores em que o município possui
vantagem comparativas reveladas (VCR). Em suma, as economias mais
diversificadas tendem a ser mais complexas.
# Chamando a função para calcular o Diversidade
Div <- calcular_Diversidade(CNAE_corrigido, anos, Mun)
Diversidade - 2006
DT::datatable(Div$Div_MS_2006, options = list(pageLength = 5))
Diversidade - 2014
DT::datatable(Div$Div_MS_2014, options = list(pageLength = 5))
Diversidade - 2022
DT::datatable(Div$Div_MS_2022, options = list(pageLength = 5))
A partir destes três anos é possível verificar a evolução da
diversidade dos municípios.
5.2 Ubiquidade
A ubiquidade é uma medidade de quantas cidades possuem cada setor. Em
outras palavras, a ubiqidade mede o quão comum é cada setor. Em geral,
economias que possuem dotação em setores poucos ubiquos são mais
complexos.
# Chamando a função para calcular o Ubiquidade
Ubi <- calcular_Ubiquidade(CNAE_corrigido, anos)
Ubiquidade - 2006
DT::datatable(Ubi$Ubi_MS_2006, options = list(pageLength = 5))
Ubiquidade - 2014
DT::datatable(Ubi$Ubi_MS_2014, options = list(pageLength = 5))
Ubiquidade - 2022
DT::datatable(Ubi$Ubi_MS_2022, options = list(pageLength = 5))
A partir deste três anos é possível observar a evonlução da
ubiquidade dos setores.
5.3 Índice de Complexidade Econômica
Para calcular a complexidade são usados os dados da diversidade e da
ubiquidade, mas o R possui rotinas especializadas para calcular este
indicador automaticamente.
# Chamando a função para calcular o ICE
ICE <- calcular_ICE(CNAE_corrigido, anos, Mun)
# Chamando a função para consolidar os ICEs de todos os anos em apenas um dataframe
ICE_consolidado <- consolidar_ICE(ICE, anos)
ICE_consolidado <- cbind(Mun,ICE_consolidado)
# Baixar o ICE_consolidade em uma planilha
writexl::write_xlsx(as.data.frame(ICE_consolidado),path = "ICE.xlsx")
# Visualizar os ICEs
DT::datatable(ICE_consolidado, options = list(pageLength = 5))
Vale ressaltar que foram calculados Índice de Complexidade Econômica
normalizadas, em uma escala em que o valor máximo é 100 e o valor mínimo
é 0. Desssa forma, tem-se a complexidade relativa dos municípios para
cada ano.
6 Análise da complexidade
6.1 Estatística descritiva
# Estatísticas descritivas
tabela_descr <- describe(ICE_consolidado)
# Mostrando a tabela no R Markdown
kable(tabela_descr, digits = 2, caption = "Estatísticas Descritivas por Ano")
Estatísticas Descritivas por Ano
| Municípios do MS* |
1 |
79 |
40.00 |
22.95 |
40.00 |
40.00 |
29.65 |
1 |
79 |
78 |
0.00 |
-1.25 |
2.58 |
| 2006 |
2 |
79 |
13.40 |
11.96 |
11.90 |
12.08 |
5.75 |
0 |
100 |
100 |
4.84 |
32.16 |
1.35 |
| 2007 |
3 |
79 |
12.73 |
12.01 |
10.75 |
11.41 |
6.45 |
0 |
100 |
100 |
4.85 |
32.54 |
1.35 |
| 2008 |
4 |
79 |
12.40 |
11.84 |
10.52 |
10.93 |
5.56 |
0 |
100 |
100 |
5.19 |
35.27 |
1.33 |
| 2009 |
5 |
79 |
19.49 |
11.83 |
18.72 |
18.22 |
7.13 |
0 |
100 |
100 |
4.02 |
24.74 |
1.33 |
| 2010 |
6 |
79 |
13.98 |
12.15 |
11.31 |
12.53 |
6.30 |
0 |
100 |
100 |
4.54 |
29.10 |
1.37 |
| 2011 |
7 |
79 |
15.63 |
12.49 |
13.54 |
14.12 |
5.55 |
0 |
100 |
100 |
4.05 |
24.03 |
1.41 |
| 2012 |
8 |
79 |
22.36 |
13.93 |
19.95 |
20.66 |
8.53 |
0 |
100 |
100 |
2.61 |
11.05 |
1.57 |
| 2013 |
9 |
79 |
31.14 |
13.87 |
29.38 |
29.61 |
10.20 |
0 |
100 |
100 |
1.95 |
6.98 |
1.56 |
| 2014 |
10 |
79 |
21.03 |
15.66 |
18.23 |
19.21 |
11.82 |
0 |
100 |
100 |
2.10 |
7.32 |
1.76 |
| 2015 |
11 |
79 |
20.16 |
14.00 |
17.69 |
18.54 |
8.65 |
0 |
100 |
100 |
2.73 |
12.07 |
1.58 |
| 2016 |
12 |
79 |
20.17 |
14.34 |
18.48 |
18.55 |
9.99 |
0 |
100 |
100 |
2.54 |
10.87 |
1.61 |
| 2017 |
13 |
79 |
20.79 |
16.04 |
17.83 |
19.10 |
13.01 |
0 |
100 |
100 |
1.97 |
6.55 |
1.80 |
| 2018 |
14 |
79 |
18.30 |
14.42 |
16.29 |
16.65 |
10.40 |
0 |
100 |
100 |
2.58 |
11.31 |
1.62 |
| 2019 |
15 |
79 |
20.59 |
15.83 |
17.32 |
18.61 |
13.19 |
0 |
100 |
100 |
2.20 |
7.45 |
1.78 |
| 2020 |
16 |
79 |
19.18 |
14.51 |
16.29 |
17.35 |
11.41 |
0 |
100 |
100 |
2.59 |
10.84 |
1.63 |
| 2021 |
17 |
79 |
20.91 |
14.16 |
18.16 |
19.14 |
10.95 |
0 |
100 |
100 |
2.63 |
11.07 |
1.59 |
| 2022 |
18 |
79 |
21.13 |
13.32 |
18.08 |
19.52 |
8.73 |
0 |
100 |
100 |
2.95 |
13.97 |
1.50 |
6.2 Histogramas
Os dados podem ser visualizados graficamente por meio de histogramas,
essa forma de visualização é interessante para mostrar a dispersão dos
dados. A partir destes gráficos, percebe-se que ao longo do período
observado houve uma tendência de convergência da complexidade, visto que
a disparidade de complexidade entre a capital Campo Grande, que possui a
máxima complexidade relativa, diminuiu em relação ao resto do
estado.
Histograma de 2006
##visualização gráfica dos dados
hist(ICE$ICE_MS_2006$ICE,
main = "Histograma do ICE de 2006",
xlab = "Valores de ICE",
ylab = "Frequência",
col = "lightblue",
breaks = seq(min(ICE$ICE_MS_2006$ICE), max(ICE$ICE_MS_2006$ICE), length.out = 20), # opcional
freq = TRUE) # freq=FALSE para densidade relativa

Histograma de 2014
##visualização gráfica dos dados
hist(ICE$ICE_MS_2014$ICE,
main = "Histograma do ICE de 2014",
xlab = "Valores de ICE",
ylab = "Frequência",
col = "lightblue",
breaks = seq(min(ICE$ICE_MS_2014$ICE), max(ICE$ICE_MS_2014$ICE), length.out = 20), # opcional
freq = TRUE) # freq=FALSE para densidade relativa

Histograma de 2022
##visualização gráfica dos dados
hist(ICE$ICE_MS_2022$ICE,
main = "Histograma do ICE de 2022",
xlab = "Valores de ICE",
ylab = "Frequência",
col = "lightblue",
breaks = seq(min(ICE$ICE_MS_2022$ICE), max(ICE$ICE_MS_2022$ICE), length.out = 20), # opcional
freq = TRUE) # freq=FALSE para densidade relativa

6.3 Mapas do MS
Por último, pode-se visualizar a complexidade do MS por meio do uso
de mapas.
Primeiro, para tal, é necessário ter um objeto com os municípios e as
suas respectivas coordenadas.
all_mun_ms <- read_municipality(code_muni=50, year=2022)
## Using year/date 2022
Em seguida, é necessário juntar as coordenadas dos municípios com os
seus respectivos Índices de Complexidade Econômica em um único objeto.
Como a ordem dos municípios é coincidentemente a mesma nos dois objetos,
pode-se apenas fazer isso apenas usando a rotina cbind()
ICE_mapas <- cbind(all_mun_ms,ICE_consolidado)
Mapa de 2006
ggplot() +
geom_sf(data=ICE_mapas, aes(fill=X2006), color= "black", size=0.01)+
labs(title="ICE dos Municípios do MS - 2006",
caption='Fonte: Elaboração própria', size=8)+
scale_fill_gradient(low = "red",
high = "blue", limits=c(0, 100),
name="ICE")+
theme_minimal()

Mapa de 2014
ggplot() +
geom_sf(data=ICE_mapas, aes(fill=X2014), color= "black", size=0.01)+
labs(title="ICE dos Municípios do MS - 2014",
caption='Fonte: Elaboração própria', size=8)+
scale_fill_gradient(low = "red",
high = "blue", limits=c(0, 100),
name="ICE")+
theme_minimal()

Mapa de 2022
ggplot() +
geom_sf(data=ICE_mapas, aes(fill=X2022), color= "black", size=0.01)+
labs(title="ICE dos Municípios do MS - 2022",
caption='Fonte: Elaboração própria', size=8)+
scale_fill_gradient(low = "red",
high = "blue", limits=c(0, 100),
name="ICE")+
theme_minimal()

7 Conclusão
Com todos os indicadores e dados à disposição percebe-se uma grande
discrepância entre a capital Campo Grande, que permanece como o
município mais complexo, e o resto do estado. Todavia, percebe-se que ao
longo dos anos analisados, isto é entre 2006 e 2022, houve uma tendência
de convergência da estrutura produtiva do MS que está atrelado a um
aumneto da média do Índice de Complexidade Econômica, indo de 13,40 em
2006 para 21,13 em 2022. Outrossim, a importância destes dados está no
seu poder de evidenciar quais são os municípios que estão relativamente
mais atrasados estruturalmente. Informações como esta, são importantes
istrumentos para a análise e para o desenho do desenvolvimento da
economia regional.
8 Referências
SILVA JUNIOR, Ernani de Almeida; FAGUNDES, Mayra Batista Bitencourt;
FIGUEIREDO, Adriano Marcos Rodrigues; MACHADO, João Victor. Complexidade
econômica regional: uma abordagem a partir de dados de emprego regional.
In: CONGRESSO DA SOBER, 57., 2019, Ilhéus. Anais […]. Ilhéus: SOBER,
2019.
ROSENSTEIN‑RODAN, P. N. Problemas de industrialização da Europa
oriental e sud-oriental. In: AGARWALA, A. N.; SINGH, S. P. (Orgs.). A
economia do subdesenvolvimento. [S.l.]: [s.n.], 1943.
LEWIS, W. A. The Theory of Economic Growth. London: Allen & Unwin
Ltd., 1955.
HIRSCHMAN, A. O. The Strategy of Economic Development. New Haven
(CT): Yale University Press, 1958.
PREBISCH, R. The Economic Development of Latin America and Its
Principal Problems. Economic Bulletin for Latin America, n. 7, p. 1–22,
1962.
KUZNETS, S. Modern Economic Growth: Rate, Structure, and Spread. New
Haven and London: Yale University Press, 1966.
KALDOR, N. Causes of the Slow Rate of Economic Growth of the United
Kingdom. Cambridge: Cambridge University Press, 1966.
FURTADO, C. Dialética do desenvolvimento. Rio de Janeiro: Fundo de
Cultura, 1964.
HAUSMANN, Ricardo et al. The Atlas of Economic Complexity: Mapping
Paths to Prosperity. Cambridge: The MIT Press, 2013. Disponível em: http://www.jstor.org/stable/j.ctt9qf8jp. Acesso em: 24
jul. 2025.
HIDALGO, César A.; HAUSMANN, Ricardo. The Building Blocks of Economic
Complexity. Proceedings of the National Academy of Sciences of the
United States of America, v. 106, n. 26, p. 10570–10575, 30 jun. 2009.
DOI: 10.1073/pnas.0900943106.
BALASSA, B. Trade liberalisation and “revealed” comparative
advantage. The Manchester School, v. 33, n. 2, p. 99–123, 1965.
FIGUEIREDO, Adriano Marcos Rodrigues. Mapas em R com
geobr. Campo Grande-MS,Brasil: RStudio/Rpubs, 2020.
Disponível em https://adrianofigueiredo.netlify.com/post/mapas-em-r-com-geobr/.
LS0tDQp0aXRsZTogIkPDoWxjdWxvIGRhIGNvbXBsZXhpZGFkZSBlY29uw7RtaWNhIGRvIE1TIGVtIFIiDQphdXRob3I6ICJWaWN0b3IgWS4gWWFoaXJvIGUgTHVpeiBHdWlsaGVybWUgRy4gUi4gUGVyZWlyYSINCmRhdGU6ICIyMDI1LTA3LTIzIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHRvYzogdHJ1ZSAgICAgICAgIyBhdGl2YSBvIHN1bcOhcmlvDQogICAgdG9jX2RlcHRoOiAyICAgICAjIHByb2Z1bmRpZGFkZQ0KICAgIHRvY19mbG9hdDogdHJ1ZSAgIyBmYXogbyBzdW3DoXJpbyBmbHV0dWFyIG5hIGxhdGVyYWwNCi0tLQ0KDQpPIHByZXNlbnRlIHBvc3QgcmVmZXJlLXNlIGEgdW0gdHJhYmFsaG8gZGUgYW7DoWxpc2UgZGEgY29tcGxleGlkYWRlIGVjb27DtG1pY2EgZG8gTVMgYSBwYXJ0aXIgZG9zIGRhZG9zIGRvIGVtcHJlZ28uIEVzdGUgdHJhYmFsaG8gZm9pIGRlc2Vudm9sdmlkbyBuYSBkaXNjaXBsaW5hIGRlIEVjb25vbWlhIFJlZ2lvbmFsIGUgVXJiYW5hIGNvbSBhIG9yaWVudGHDp8OjbyBkbyBQcm9mLiBEci4gQWRyaWFubyBGaWd1ZWlyZWRvICgqZS1tYWlsOiBhZHJpYW5vLmZpZ3VlaXJlZG9AdWZtcy5iciopDQoNCioqT3MgZGFkb3MgdXNhZG9zIGUgb3MgcmVzdWx0YWRvcyBvYnRpZG9zIHBvZGVtIHNlciBlbmNvbnRyYWRvcyBlIGJhaXhhZG9zIGVtIHVtIHJlcG9zaXTDs3JpbyBubyBbR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vVmljdG9yWWFoaXJvL2RhZG9zX2NvbXBsZXhpZGFkZSkgKGNhc28gbyBsaW5rIGTDqiBhbGd1bSBlcnJvIHRlbnRlIGNsaWNhciBuZWxlIGNvbSBvIGJvdMOjbyBkaXJlaXRvIGRvIG1vdXNlIHBhcmEsIGVtIHNlZ3VpZGEsIGNsaWNhciBlbSAiQWJyaXIgbGluayBlbSBub3ZhIGd1aWEiKS4qKg0KDQojIDEgSW50cm9kdcOnw6NvDQoNCkRpdmVyc29zIHRlw7NyaWNvcyBjbMOhc3NpY29zIGRvIGRlc2Vudm9sdmltZW50byByZXNzYWx0YW0gbyBwYXBlbCBpbXBvcnRhbnRlIGRhIGVzdHJ1dHVyYSBwcm9kdXRpdmEgbm8gcHJvY2Vzc28gZGUgZGVzZW52b2x2aW1lbnRvIGVjb27DtG1pY28gKFJPU0VOU1RFSU4tUk9EQU4sIDE5NDM7IExFV0lTLCAxOTU1OyBISVJTQ0hNQU4sIDE5NTg7IFBSRUJJU0NILCAxOTYyOyBLVVpORVRTLCAxOTY2OyBLQUxET1IsIDE5NjY7IEZVUlRBRE8sIDE5NjQpLiBFbSBvdXRyYXMgcGFsYXZyYXMsIG5hIGFjYWRlbWlhLCBow6EgdW1hIGxpdGVyYXR1cmEgbWFkdXJhIHF1ZSBkZXNjcmV2ZSBjb21vIHF1ZSBhIG11ZGFuw6dhIGRhcyBkaW7Dom1pY2FzIGludGVyIGUgaW50cmEgc2V0b3JpYWlzIGFmZXRhbSBxdWFsaXRhdGl2YW1lbnRlIG8gcGxhbm8gZWNvbsO0bWljby4gTmVzc2Ugc2VudGlkbywgbyB0cmFiYWxobyBkb3MgcGVzcXVpc2Fkb3JlcyBIYXVzbWFubiAqZXQgYWwuKiAoMjAxMykgc2ludGV0aXphcmFtIHRhbCBiYWdhZ2VtIHRlw7NyaWNhIGVtIHVtIG3DqXRvZG9sbyBkZSBjw6FsY3VsbyBkbyBxdWUgZWxlcyBwYXNzYXJhbSBhIGNoYW1hciBkZSBjb21wbGV4aWRhZGUgZWNvbsO0bWljYS4gQXNzaW0sIGNyaW91LXNlLCBhIHBhcnRpciBkbyDDrW5kaWNlIGRlIHZhdGFnZW5zIGNvbXBhcmF0aXZhcyByZXZlbGFkYXMgKFZDUikgZGVzZW52b2x2aWRvIHBvciBCYWxhc3NhICgxOTY1KSwgbcOpdHJpY2FzIGRlIGNvbXBsZXhpZGFkZSBlIGRlIGFuw6FsaXNlIGRvIHByb2R1dG8tZXNwYcOnbywgY29tbyBwb3IgZXhlcGxvIG8gw61uZGljZSBkZSBjb21wbGV4aXNkYWRlIGVjb27DtG1pY2EgKElDRSkgKEhJREFMR087IEhBVVNNQU5OLCAyMDA5OyBIQVVTTUFOTiAqZXQgYWwuKiwgMjAxMykuIEVtIHN1bWEsIHNlZ3VuZG8gSGF1c21hbm4gKmV0IGFsLiooMjAxMykgYSBjb21wbGV4aWRhZGUgZWNvbsO0bWljYSBwcm92b3Ugc2VyIHVtYSBtw6l0cmljYSBpbXBvcnRhbnRlIHBhcmEgY29tcHJlZW5kZXIgYSBkaXNwYXJpZGFkZSBubyBuw612ZWwgZGUgcmVuZGEgZW50cmUgZGl2ZXJzYXMgZWNvbm9taWFzIGUsIGVtIGFsZ3VucyBjYXNvcywgYXTDqSBwcm92b3Ugc2VyIHVtIGZvcnRlIHByZWRpdG9yIGRvIGZ1dHVybyBjcmVzY2ltZW50byBkbyBQSUIuDQoNCk9yaWdpbmFsbWVudGUsIEhhdXNtYW5uICpldCBhbC4qKDIwMTMpIHByb3DDtWVtIGVzdGEgbWV0b2RvbG9naWEgZGUgYW7DoWxpc2UgZGEgY29tcGxleGlkYWRlIGVtIHVtIMOibWJpdG8gZ2xvYmFsIGEgcGFydGlyIGRlIGRhZG9zIGRvIGNvbcOpcmNpbyBpbnRlcm5hY2lvbmFsLiBOw6NvIG9ic3RhbnRlLCBvIHByZXNlbnRlIHRyYWJhbGhvIGFwb2lhLXNlIG5hIHByb3Bvc3RhIGRlIFNpbHZhIEp1bmlvciAqZXQgYWwuKiAoMjAxOSksIGEgcXVhbCBhZGFwdGEgb3MgaW5kaWNhZG9yZXMgZGUgY29tcGxleGlkYWRlIHBhcmEgYSBhbsOhbGlzZSByZWdpb25hbCBhbyB1c2FyIGRhZG9zIGRvIGVtcHJlZ28uIERpYW50ZSBkc3NvLCB1dGlsaXpvdS1zZSwgcGFyYSBhIGFuw6FsaXNlIGRhIGNvbXBsZXhpZGFkZSBlY29uw7RtaWNhIGRvIE1TLCBkYWRvcyBkYSBSQUlTIHZpbmPDumxvIGRpc3RyaWJ1w61kb3MgZW50cmUgb3Mgc2V0b3JlcyBkZWxpbWl0YWRvcyBwZWxhcyBjbGFzc2VzIENOQUUgMi4wIGVudHJlIG8gYW5vIGRlIDIwMDYgZSAyMDIyLg0KDQojIDIgUHV4YW5kbyBvcyBwYWNvdGVzDQoNCmBgYHtSfQ0KI1BBQ09URVMgVVNBRE9TIA0Kew0KICBsaWJyYXJ5KHJlYWR4bCkgICMgcGFyYSBsZXIgZXhjZWwgeGxzeCBlIHhscw0KICBsaWJyYXJ5KHBzeWNoKQ0KICBsaWJyYXJ5KGtuaXRyKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkgICMgcGFyYSB0cmFiYWxoYXIgZGFkb3MgY29tIHRpYmJsZQ0KICBsaWJyYXJ5KGdncGxvdDIpICAjIHBhcmEgZmF6ZXIgcGxvdHMgZSBtYXBhcw0KICBsaWJyYXJ5KHdyaXRleGwpICMgcGFyYSBnZXJhciB4bHN4IG91IHhscw0KICBsaWJyYXJ5KEVjb25HZW8pICAjIHBhcmEgYSBtYWlvcmlhIGRvcyBpbmRpY2Fkb3JlcyByZWdpb25haXMNCiAgbGlicmFyeShSRUFUKSAgIyBwYXJhIGFsZ3VucyBpbmRpY2Fkb3JlcyByZWdpb25haXMNCiAgbGlicmFyeShpbnNwZWN0ZGYpICAjIHBhcmEgaW5zcGVjaW9uYXIgZGF0YWZyYW1lcw0KICBsaWJyYXJ5KGdlb2JyKSAgIyBwYXJhIGJhaXhhciBzaGFwZXMgYnJhc2lsZWlyb3MsIHBhcmEgbWFwYXMNCiAgbGlicmFyeShnZ3NwYXRpYWwpICMgcGFyYSBjb2xvY2FyIG5vcnRlIGUgZXNjYWxhIG5vcyBtYXBhcw0KICBsaWJyYXJ5KHNmKSAgICMgcGFyYSBmYXplciBtYXBhcw0KICBsaWJyYXJ5KERUKSAgICNwYXJhIGV4cG9zacOnw6NvIGRvcyBkYWRvcw0KfQ0KYGBgDQoNCiMgMyBDcmlhbmRvIGZ1bsOnw7Vlcw0KRGV2aWRvIGFvIGdyYW5kZSBuw7ptZXJvIGRlIGRhdGFzZXRzIHVzYWRvcywgdmlzdG8gcXVlIHBhcmEgY2FkYSBhbm8gZW50cmUgMjAwNiBlIDIwMjIgaMOhIHVtIGRhdGFzZXQgZGlmZXJlbnRlLCBmb3JhbSBjb25zdHJ1w61kYXMgNiBmdW7Dp8O1ZXMgcGFyYSBvdGltaXphciBvIHNjcmlwdC4gVmFsZSByZXNzYWx0YXIgcXVlIGEgZnVuw6fDo28gMiBjb3JyaWdpcl9DTkFFKCkgZm9pIGNyaWFkYSBwYXJhIHJlc29sdmVyIHVtIHByb2JsZW1hIGF0cmVsYWRvIGFvIHBhaW5lbCBkZSBkYWRvcy4gRW0gc3VtYSwgZW50cmUgb3MgNzkgbXVuaWPDrXBpb3MgZG8gTVMsIG8gbXVuaWPDrXBpbyBQYXLDrXNvIGRhcyDDgWd1YXMgc3VyZ2l1IGVtIDIwMTMgYSBwYXJ0aXIgZGUgMyBvdXRyb3MgbXVuaWPDrXBpb3MsIGlzdG8gw6kgw4FndWEgQ2xhcmEsIENoYXBhZMOjbyBkbyBTdWwgZSBDb3N0YSBSaWNhLiBBc3NpbSwgbm8gZGF0YXNldCBvcmlnaW5hbCBuw6NvIGjDoSBvIG11bmljw61waW8gUGFyYcOtc28gZGFzIMOBZ3VhcyBhbnRlcyBkZSAyMDEzLCBtYXMsIHBhcmEgcGFkcm9uaXphciBvIHBhaW5lbCBkZSBkYWRvcywgZXN0ZSBtdW5pY8OtcGlvIGZvaSBzaW11bGFkbyBub3MgcGVyw61vZG9zIGF1c2VudGVzLg0KDQpgYGB7Un0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNGdW7Dp8O1ZXMgVXRpbGl6YWRhcyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyAxLiBGdW7Dp8OjbyBwYXJhIGxlciBvcyBDTkFFcyBkZSAyMDA2IGEgMjAyMiBlIGFybWF6ZW5hciBlbSB1bWEgbGlzdGENCmxlcl9kYWRvc19DTkFFIDwtIGZ1bmN0aW9uKGFycXVpdm8sIGFub3MpIHsNCiAgbGlzdGFfZGFkb3MgPC0gbGlzdCgpICAjIEluaWNpYWxpemFuZG8gdW1hIGxpc3RhIHZhemlhIHBhcmEgYXJtYXplbmFyIGNhZGEgZGF0YWZyYW1lDQogIGZvciAoYW5vIGluIGFub3MpIHsgICMgTG9vcCBwZWxvcyBhbm9zIGVzcGVjaWZpY2Fkb3MNCiAgICBub21lX3NoZWV0IDwtIHBhc3RlMCgiQ05BRV8iLCBhbm8pICAjIERlZmluaW5kbyBvIG5vbWUgZG8gc2hlZXQgY29tIGJhc2Ugbm8gYW5vIGF0dWFsDQogICAgbGlzdGFfZGFkb3NbW25vbWVfc2hlZXRdXSA8LSByZWFkX2V4Y2VsKGFycXVpdm8sIHNoZWV0ID0gbm9tZV9zaGVldCkgICMgTGVuZG8gbyBzaGVldCBlIGFybWF6ZW5hbmRvIG5hIGxpc3RhDQogIH0NCiAgcmV0dXJuKGxpc3RhX2RhZG9zKSAgIyBSZXRvcm5hbmRvIGEgbGlzdGEgY29tIHRvZG9zIG9zIGRhdGFmcmFtZXMNCn0NCg0KIyAyLiBGdW7Dp8OjbyBwYXJhIGNvcnJpZ2lyIGRhZG9zIGRlIFBhcmFpc28gZGFzIEFndWFzLCBBZ3VhIENsYXJhLCBDb3N0YSBSaWNhIGUgQ2hhcGFkYW8gZG8gU3VsDQpjb3JyaWdpcl9DTkFFIDwtIGZ1bmN0aW9uKGxpc3RhX2RhZG9zLCBhbm9zKSB7DQogIGxpc3RhX2RhZG9zX2NvcnJpZ2lkb3MgPC0gbGlzdCgpICAjIEluaWNpYWxpemFuZG8gdW1hIGxpc3RhIHZhemlhIHBhcmEgYXJtYXplbmFyIG9zIGRhdGFmcmFtZXMgY29ycmlnaWRvcyBjb20gc2V1cyBub21lcw0KICBmb3IgKGkgaW4gMTpsZW5ndGgobGlzdGFfZGFkb3MpKSB7ICAjIExvb3AgcGVsb3MgZGF0YWZyYW1lcyBuYSBsaXN0YQ0KICAgIGRmIDwtIGxpc3RhX2RhZG9zW1tpXV0gICMgU2VsZWNpb25hbmRvIG8gZGF0YWZyYW1lIGF0dWFsDQogICAgDQogICAgaWYgKGkgPD0gNykgeyAgIyBWZXJpZmljYSBzZSBpIMOpIG1lbm9yIG91IGlndWFsIGEgNw0KICAgICAgZGZfY29ycmVjYW8gPC0gZGZbMTo3OSwgMjo2NzddICAjIFNlbGVjaW9uYW5kbyBhcyBsaW5oYXMgZSBjb2x1bmFzIGNvbmZvcm1lIG8gY8OzZGlnbyBvcmlnaW5hbA0KICAgICAgZGZfbm92byA8LSBkZl9jb3JyZWNhbw0KICAgICAgZGZfbm92b1sxLCBdIDwtICgxIC0gMC4zMzUpICogZGZfY29ycmVjYW9bMSwgXSAgIyBNb2RpZmljYXIgYSBsaW5oYSAxIGNvbSBvIGZhdG9yICgxIC0gMC4zMzUpDQogICAgICBkZl9ub3ZvWzIzLCBdIDwtICgxIC0gMC4xODYpICogZGZfY29ycmVjYW9bMjMsIF0gICMgTW9kaWZpY2FyIGEgbGluaGEgMjMgY29tIG8gZmF0b3IgKDEgLSAwLjE4NikNCiAgICAgIGRmX25vdm9bMjcsIF0gPC0gKDEgLSAwLjQ3OSkgKiBkZl9jb3JyZWNhb1syNywgXSAgIyBNb2RpZmljYXIgYSBsaW5oYSAyNyBjb20gbyBmYXRvciAoMSAtIDAuNDc5KQ0KICAgICAgZGZfbm92b1s1OCwgXSA8LSAwLjMzNSAqIGRmX2NvcnJlY2FvWzEsIF0gKyAwLjE4NiAqIGRmX2NvcnJlY2FvWzIzLCBdICsgMC40NzkgKiBkZl9jb3JyZWNhb1syNywgXSAgIyBDYWxjdWxhciBhIGNvbWJpbmHDp8OjbyBwb25kZXJhZGEgcGFyYSBhIGxpbmhhIDU4DQogICAgfSBlbHNlIHsNCiAgICAgIGRmX25vdm8gPC0gZGZbMTo3OSwgMjo2NzddICAgIyBTZSBpIGZvciBtYWlvciBxdWUgNywgYXBlbmFzIGNvcGlhIG8gZGF0YWZyYW1lIG9yaWdpbmFsDQogICAgfQ0KICAgIA0KICAgIG5vbWVfZGF0YWZyYW1lIDwtIHBhc3RlMCgiQ05BRV8iLCBhbm9zW2ldKSAgIyBHZXJhciB1bSBub21lIHBhcmEgbyBkYXRhZnJhbWUNCiAgICBsaXN0YV9kYWRvc19jb3JyaWdpZG9zW1tub21lX2RhdGFmcmFtZV1dIDwtIGRmX25vdm8gICMgQXJtYXplbmFuZG8gbyBkYXRhZnJhbWUgKGNvcnJpZ2lkbyBvdSBvcmlnaW5hbCkgbmEgbGlzdGEgY29tIG8gbm9tZSBnZXJhZG8NCiAgfQ0KICByZXR1cm4obGlzdGFfZGFkb3NfY29ycmlnaWRvcykgICMgUmV0b3JuYW5kbyBhIGxpc3RhIGNvbSBvcyBkYXRhZnJhbWVzIGNvcnJpZ2lkb3Mgb3Ugb3JpZ2luYWlzDQp9DQoNCiMgMy4gRnVuw6fDo28gcGFyYSBjYWxjdWxhciBEaXZlcnNpZGFkZSBwYXJhIG9zIGVzdGFkb3MgZG8gTVMgZGUgMjAwNiBhIDIwMjINCmNhbGN1bGFyX0RpdmVyc2lkYWRlIDwtIGZ1bmN0aW9uKGxpc3RhX2RhZG9zLCBhbm9zLCBtdW4pIHsNCiAgbGlzdGFfRGl2IDwtIGxpc3QoKQ0KICBmb3IgKGkgaW4gMTpsZW5ndGgobGlzdGFfZGFkb3MpKSB7DQogICAgZGYgPC0gbGlzdGFfZGFkb3NbW2ldXSAgIyBTZWxlY2lvbmFuZG8gbyBkYXRhZnJhbWUgYXR1YWwNCiAgICBub21lX2RmIDwtIHBhc3RlMCgiRGl2X01TXyIsIGFub3NbaV0pICAjIEdlcmFyIHVtIG5vbWUgcGFyYSBvIGRhdGFmcmFtZSB1c2FuZG8gbyBhbm8gY29ycmVzcG9uZGVudGUNCiAgICBsaXN0YV9EaXZbW25vbWVfZGZdXSA8LSBhcy5kYXRhLmZyYW1lKGRpdmVyc2l0eShkZiwgcmNhID0gVFJVRSkpICAjIEFwbGljYXIgYSBmdW7Dp8OjbyAnZGl2ZXJzaXR5JyBhbyBkYXRhZnJhbWUsIGNhbGN1bGFuZG8gbyBEaXZlcnNpZGFkZQ0KICAgIGxpc3RhX0Rpdltbbm9tZV9kZl1dIDwtIGNiaW5kKG11biwgbGlzdGFfRGl2W1tub21lX2RmXV0pICAjIEFkaWNpb25hciBhIHZhcmnDoXZlbCAnbXVuJyBjb21vIHVtYSBub3ZhIGNvbHVuYSBhbyBkYXRhZnJhbWUgcmVzdWx0YW50ZQ0KICAgIGNvbG5hbWVzKGxpc3RhX0Rpdltbbm9tZV9kZl1dKVsyXSA8LSAiRGl2ZXJzaWRhZGUiICMgUmVub21lYW5kbyBhcGVuYXMgYSBzZWd1bmRhIGNvbHVuYQ0KICB9DQogIHJldHVybihsaXN0YV9EaXYpICAjIFJldG9ybmFuZG8gYSBsaXN0YSBjb20gb3MgZGF0YWZyYW1lcyBjb3JyaWdpZG9zDQp9DQoNCiMgNC4gRnVuw6fDo28gcGFyYSBjYWxjdWxhciBVYmlxdWlkYWRlIHBhcmEgb3MgZXN0YWRvcyBkbyBNUyBkZSAyMDA2IGEgMjAyMg0KY2FsY3VsYXJfVWJpcXVpZGFkZSA8LSBmdW5jdGlvbihsaXN0YV9kYWRvcywgYW5vcykgew0KICBsaXN0YV9VYmkgPC0gbGlzdCgpDQogIGZvciAoaSBpbiAxOmxlbmd0aChsaXN0YV9kYWRvcykpIHsNCiAgICBkZiA8LSBsaXN0YV9kYWRvc1tbaV1dICAjIFNlbGVjaW9uYW5kbyBvIGRhdGFmcmFtZSBhdHVhbA0KICAgIG5vbWVfZGYgPC0gcGFzdGUwKCJVYmlfTVNfIiwgYW5vc1tpXSkgICMgR2VyYXIgdW0gbm9tZSBwYXJhIG8gZGF0YWZyYW1lIHVzYW5kbyBvIGFubyBjb3JyZXNwb25kZW50ZQ0KICAgIGxpc3RhX1ViaVtbbm9tZV9kZl1dIDwtIGFzLmRhdGEuZnJhbWUodWJpcXVpdHkoZGYsIHJjYSA9IFRSVUUpKSAgIyBBcGxpY2FyIGEgZnVuw6fDo28gJ3ViaXF1aXR5JyBhbyBkYXRhZnJhbWUsIGNhbGN1bGFuZG8gbyBVYmlxdWlkYWRlDQogICAgY29sbmFtZXMobGlzdGFfVWJpW1tub21lX2RmXV0pWzFdIDwtICJVYmlxdWlkYWRlIiAjIFJlbm9tZWFuZG8gYXBlbmFzIGEgc2VndW5kYSBjb2x1bmENCiAgfQ0KICByZXR1cm4obGlzdGFfVWJpKSAgIyBSZXRvcm5hbmRvIGEgbGlzdGEgY29tIG9zIGRhdGFmcmFtZXMgY29ycmlnaWRvcw0KfQ0KDQojIDUuIEZ1bsOnw6NvIHBhcmEgY3JpYXIgbyBJbmRpY2UgZGUgQ29tcGxleGlkYWRlIEVjb25vbWljYSBQYXJhIG9zIGVzdGFkb3MgZG8gTVMgZGUgMjAwNiBhIDIwMjINCmNhbGN1bGFyX0lDRSA8LSBmdW5jdGlvbihsaXN0YV9kYWRvcywgYW5vcywgbXVuKSB7DQogIGxpc3RhX0lDRSA8LSBsaXN0KCkNCiAgZm9yIChpIGluIDE6bGVuZ3RoKGxpc3RhX2RhZG9zKSkgew0KICAgIGRmIDwtIGxpc3RhX2RhZG9zW1tpXV0gICMgU2VsZWNpb25hbmRvIG8gZGF0YWZyYW1lIGF0dWFsDQogICAgbm9tZV9kZiA8LSBwYXN0ZTAoIklDRV9NU18iLCBhbm9zW2ldKSAgIyBHZXJhciB1bSBub21lIHBhcmEgbyBkYXRhZnJhbWUgdXNhbmRvIG8gYW5vIGNvcnJlc3BvbmRlbnRlDQogICAgbGlzdGFfSUNFW1tub21lX2RmXV0gPC0gYXMuZGF0YS5mcmFtZShtb3JjKGRmLCByY2EgPSBUUlVFKSkgICMgQXBsaWNhciBhIGZ1bsOnw6NvICdtb3JjJyBhbyBkYXRhZnJhbWUsIGNhbGN1bGFuZG8gbyBJQ0UNCiAgICBsaXN0YV9JQ0VbW25vbWVfZGZdXSA8LSBjYmluZChtdW4sIGxpc3RhX0lDRVtbbm9tZV9kZl1dKSAgIyBBZGljaW9uYXIgYSB2YXJpw6F2ZWwgJ211bicgY29tbyB1bWEgbm92YSBjb2x1bmEgYW8gZGF0YWZyYW1lIHJlc3VsdGFudGUNCiAgICBjb2xuYW1lcyhsaXN0YV9JQ0VbW25vbWVfZGZdXSlbMl0gPC0gIklDRSIgIyBSZW5vbWVhbmRvIGFwZW5hcyBhIHNlZ3VuZGEgY29sdW5hDQogIH0NCiAgcmV0dXJuKGxpc3RhX0lDRSkgICMgUmV0b3JuYW5kbyBhIGxpc3RhIGNvbSBvcyBkYXRhZnJhbWVzIGNvcnJpZ2lkb3MNCn0NCg0KIyA2LiBGdW7Dp8OjbyBwYXJhIGNvbnNvbGlkYXIgZGFkb3MgZGUgSUNFIGRlIGRpZmVyZW50ZXMgYW5vcyBlbSB1bSDDum5pY28gRGF0YUZyYW1lDQpjb25zb2xpZGFyX0lDRSA8LSBmdW5jdGlvbihsaXN0YV9JQ0UsIGFub3MpIHsNCiAgZGFkb3NfSUNFIDwtIGxpc3QoKSAgIyBJbmljaWFsaXphbmRvIHVtYSBsaXN0YSB2YXppYSBwYXJhIGFybWF6ZW5hciBvcyBkYWRvcyBkZSBJQ0UgZGUgY2FkYSBhbm8NCiAgZm9yIChpIGluIHNlcV9hbG9uZyhsaXN0YV9JQ0UpKSB7DQogICAgZGFkb3NfSUNFW1tpXV0gPC0gbGlzdGFfSUNFW1tpXV1bLCAiSUNFIl0gICMgRXh0cmFpIGEgY29sdW5hICJJQ0UiIGRvIERhdGFGcmFtZSBhdHVhbCBlIGFkaWNpb25hIMOgIGxpc3RhIGRlIGRhZG9zX0lDRQ0KICB9DQogIGRmX0lDRV9jb25zb2xpZGFkbyA8LSBkby5jYWxsKGNiaW5kLCBkYWRvc19JQ0UpICAjIENvbWJpbmEgb3MgZGFkb3MgZW0gdW0gw7puaWNvIERhdGFGcmFtZSBlIGRlZmluZSBvcyBub21lcyBkYXMgY29sdW5hcyBjb21vIG9zIGFub3MNCiAgY29sbmFtZXMoZGZfSUNFX2NvbnNvbGlkYWRvKSA8LSBhbm9zICAjIERlZmluZSBvcyBub21lcyBkYXMgY29sdW5hcyBjb21vIG9zIGFub3MgZm9ybmVjaWRvcw0KICByZXR1cm4oZGZfSUNFX2NvbnNvbGlkYWRvKQ0KfQ0KYGBgDQoNCg0KIyA0IEV4dHJhw6fDo28gZSBvcmdhbml6YcOnw6NvIGRvcyBkYWRvcw0KDQpPcyBkYWRvcyB1c2Fkb3MgZm9yYW0gZXh0cmHDrWRvcyBhIHBhcnRpciBkbyBQcm9ncmFtYSBkZSBEaXNzZW1pbmHDp8OjbyBkYXMgRXN0YXTDrXN0aWNhcyBkbyBUcmFiYWxobyAoUERFVCkgZG8gTWluaXN0w6lyaW8gZG8gVHJhYmFsaG8gZSBFbXByZWdvIGUgZm9yYW0gYWdydXBhZG9zIGVtIHVtYSBwbGFuaWxoYSBFeGNlbCBlbSBxdWUgY2FkYSBhYmEgZG8gYXJxdWl2byAueGxzeCBmb2kgcmVzZXJ2YWRvIGNvbSB1bSBkYWRvIGFubyBkYSBiYXNlIGRlIGRhZG9zLg0KDQpgYGB7Un0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjQ29tcGxleGlkYWRlIEVjb25vbWlhIGRvIE1TIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCiMgRGVmaW5pbmRvIG8gYXJxdWl2byBlIG9zIGFub3MNCmFycXVpdm8gPC0gIkRBRE9TX0NOQUUueGxzeCINCmFub3MgPC0gMjAwNjoyMDIyDQoNCiMgQ2hhbWFuZG8gYSBmdW7Dp8OjbyBwYXJhIGxlciBvIGV4Y2VsDQpDTkFFIDwtIGxlcl9kYWRvc19DTkFFKGFycXVpdm8sIGFub3MpDQoNCiNWaXN1YWxpemFjYW8gZGFzIHRhYmVsYXMNCnByaW50KENOQUUkQ05BRV8yMDA2KQ0KYGBgDQoNCkFww7NzIGEgZXh0cmHDp8OjbyBkb3MgZGFkb3MsIGZhei1zZSBuZWNlc3PDoXJpYSBhIGNvcnJlw6fDo28gZGEgbGluaGEgY29tIG8gbXVuaWPDrXBpb3MgUGFyYcOtc28gZGFzIMOBZ3VhcywgcXVlIGZvaSBjcmlhZG8gb2ZpY2lhbG1lbnRlIGVtIDIwMTMuDQoNCmBgYHtSfQ0KIyBTYWx2YW5kbyBvIG5vbWUgZG9zIE11bmljaXBpb3MNCk11biA8LSBDTkFFJENOQUVfMjAwNlsxOjc5LCAxXSAlPiUNCiAgc2VwYXJhdGUoIk11bmljw61waW8tTWF0byBHcm9zc28gZG8gU3VsIiwgaW50byA9IGMoIkVzdGFkbyIsICJNdW5pY8OtcGlvcyBkbyBNUyIpLCBzZXAgPSAiLSIpICU+JQ0KICBzZWxlY3QoIk11bmljw61waW9zIGRvIE1TIikNCg0KIyBWaXN1YWxpemFyY2FvIGRvcyBub21lcyBkbyBtdW5pY2lwaW9zDQpwcmludChNdW4pDQoNCiNDaGFtYW5kbyBmdW5jYW8gcGFyYSBjb3JyaWdpciBhcyB0YWJlbGFzDQpDTkFFX2NvcnJpZ2lkbyA8LSBjb3JyaWdpcl9DTkFFKENOQUUsYW5vcykNCg0KI1Zpc3VhbGl6YWNhbyBkbyBDTkFFX2NvcnJpZ2lkbw0KRFQ6OmRhdGF0YWJsZShDTkFFX2NvcnJpZ2lkbyRDTkFFXzIwMDYsIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSA1KSkNCmBgYA0KDQojIDUgQ2FsY3VsYW5kbyBvcyBpbmRpY2Fkb3Jlcw0KTmVzdGUgdHJhYmFsaG8gc2Vyw6NvIGNhbGN1bGFkb3MgdHLDqnMgaW5kaWNhZG9yZXMuIFNlcsOjbyBlbGVzIGEgZGl2ZXJzaWRhZGUsIGEgdWJpcXVpZGFkZSBlIG8gw61uZGljZSBkZSBjb21wbGV4aWRhZGUgZWNvbsO0bWljYS4NCg0KIyMgNS4xIERpdmVyc2lkYWRlDQpBIGRpdmVyc2lkYWRlIGVxdWl2YWxlIGFvIG7Dum1lcm8gZGUgc2V0b3JlcyBlbSBxdWUgbyBtdW5pY8OtcGlvIHBvc3N1aSB2YW50YWdlbSBjb21wYXJhdGl2YXMgcmV2ZWxhZGFzIChWQ1IpLiBFbSBzdW1hLCBhcyBlY29ub21pYXMgbWFpcyBkaXZlcnNpZmljYWRhcyB0ZW5kZW0gYSBzZXIgbWFpcyBjb21wbGV4YXMuDQpgYGB7Un0NCiMgQ2hhbWFuZG8gYSBmdW7Dp8OjbyBwYXJhIGNhbGN1bGFyIG8gRGl2ZXJzaWRhZGUNCkRpdiA8LSBjYWxjdWxhcl9EaXZlcnNpZGFkZShDTkFFX2NvcnJpZ2lkbywgYW5vcywgTXVuKQ0KYGBgDQoNCiMjIyBEaXZlcnNpZGFkZSAtIDIwMDYNCg0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKERpdiREaXZfTVNfMjAwNiwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCiMjIyBEaXZlcnNpZGFkZSAtIDIwMTQNCg0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKERpdiREaXZfTVNfMjAxNCwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCiMjIyBEaXZlcnNpZGFkZSAtIDIwMjINCg0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKERpdiREaXZfTVNfMjAyMiwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQpBIHBhcnRpciBkZXN0ZXMgdHLDqnMgYW5vcyDDqSBwb3Nzw612ZWwgdmVyaWZpY2FyIGEgZXZvbHXDp8OjbyBkYSBkaXZlcnNpZGFkZSBkb3MgbXVuaWPDrXBpb3MuDQoNCiMjIDUuMiBVYmlxdWlkYWRlDQpBIHViaXF1aWRhZGUgw6kgdW1hIG1lZGlkYWRlIGRlIHF1YW50YXMgY2lkYWRlcyBwb3NzdWVtIGNhZGEgc2V0b3IuIEVtIG91dHJhcyBwYWxhdnJhcywgYSB1YmlxaWRhZGUgbWVkZSBvIHF1w6NvIGNvbXVtIMOpIGNhZGEgc2V0b3IuIEVtIGdlcmFsLCBlY29ub21pYXMgcXVlIHBvc3N1ZW0gZG90YcOnw6NvIGVtIHNldG9yZXMgcG91Y29zIHViaXF1b3Mgc8OjbyBtYWlzIGNvbXBsZXhvcy4NCg0KYGBge1J9DQojIENoYW1hbmRvIGEgZnVuw6fDo28gcGFyYSBjYWxjdWxhciBvIFViaXF1aWRhZGUNClViaSA8LSBjYWxjdWxhcl9VYmlxdWlkYWRlKENOQUVfY29ycmlnaWRvLCBhbm9zKQ0KYGBgDQoNCiMjIyBVYmlxdWlkYWRlIC0gMjAwNg0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKFViaSRVYmlfTVNfMjAwNiwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCiMjIyBVYmlxdWlkYWRlIC0gMjAxNA0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKFViaSRVYmlfTVNfMjAxNCwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQoNCiMjIyBVYmlxdWlkYWRlIC0gMjAyMg0KYGBge3J9DQpEVDo6ZGF0YXRhYmxlKFViaSRVYmlfTVNfMjAyMiwgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUpKQ0KYGBgDQpBIHBhcnRpciBkZXN0ZSB0csOqcyBhbm9zIMOpIHBvc3PDrXZlbCBvYnNlcnZhciBhIGV2b25sdcOnw6NvIGRhIHViaXF1aWRhZGUgZG9zIHNldG9yZXMuDQoNCiMjIDUuMyDDjW5kaWNlIGRlIENvbXBsZXhpZGFkZSBFY29uw7RtaWNhDQpQYXJhIGNhbGN1bGFyIGEgY29tcGxleGlkYWRlIHPDo28gdXNhZG9zIG9zIGRhZG9zIGRhIGRpdmVyc2lkYWRlIGUgZGEgdWJpcXVpZGFkZSwgbWFzIG8gUiBwb3NzdWkgcm90aW5hcyBlc3BlY2lhbGl6YWRhcyBwYXJhIGNhbGN1bGFyIGVzdGUgaW5kaWNhZG9yIGF1dG9tYXRpY2FtZW50ZS4gDQoNCmBgYHtSfQ0KIyBDaGFtYW5kbyBhIGZ1bsOnw6NvIHBhcmEgY2FsY3VsYXIgbyBJQ0UgDQpJQ0UgPC0gY2FsY3VsYXJfSUNFKENOQUVfY29ycmlnaWRvLCBhbm9zLCBNdW4pDQoNCiMgQ2hhbWFuZG8gYSBmdW7Dp8OjbyBwYXJhIGNvbnNvbGlkYXIgb3MgSUNFcyBkZSB0b2RvcyBvcyBhbm9zIGVtIGFwZW5hcyB1bSBkYXRhZnJhbWUNCklDRV9jb25zb2xpZGFkbyA8LSBjb25zb2xpZGFyX0lDRShJQ0UsIGFub3MpDQpJQ0VfY29uc29saWRhZG8gPC0gY2JpbmQoTXVuLElDRV9jb25zb2xpZGFkbykNCg0KIyBCYWl4YXIgbyBJQ0VfY29uc29saWRhZGUgZW0gdW1hIHBsYW5pbGhhDQp3cml0ZXhsOjp3cml0ZV94bHN4KGFzLmRhdGEuZnJhbWUoSUNFX2NvbnNvbGlkYWRvKSxwYXRoID0gIklDRS54bHN4IikNCg0KIyBWaXN1YWxpemFyIG9zIElDRXMNCkRUOjpkYXRhdGFibGUoSUNFX2NvbnNvbGlkYWRvLCBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gNSkpDQpgYGANCg0KVmFsZSByZXNzYWx0YXIgcXVlIGZvcmFtIGNhbGN1bGFkb3Mgw41uZGljZSBkZSBDb21wbGV4aWRhZGUgRWNvbsO0bWljYSBub3JtYWxpemFkYXMsIGVtIHVtYSBlc2NhbGEgZW0gcXVlIG8gdmFsb3IgbcOheGltbyDDqSAxMDAgZSBvIHZhbG9yIG3DrW5pbW8gw6kgMC4gRGVzc3NhIGZvcm1hLCB0ZW0tc2UgYSBjb21wbGV4aWRhZGUgcmVsYXRpdmEgZG9zIG11bmljw61waW9zIHBhcmEgY2FkYSBhbm8uDQoNCiMgNiBBbsOhbGlzZSBkYSBjb21wbGV4aWRhZGUNCg0KIyMgNi4xIEVzdGF0w61zdGljYSBkZXNjcml0aXZhDQoNCmBgYHtSfQ0KIyBFc3RhdMOtc3RpY2FzIGRlc2NyaXRpdmFzDQp0YWJlbGFfZGVzY3IgPC0gZGVzY3JpYmUoSUNFX2NvbnNvbGlkYWRvKQ0KDQojIE1vc3RyYW5kbyBhIHRhYmVsYSBubyBSIE1hcmtkb3duDQprYWJsZSh0YWJlbGFfZGVzY3IsIGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAiRXN0YXTDrXN0aWNhcyBEZXNjcml0aXZhcyBwb3IgQW5vIikNCmBgYA0KDQojIyA2LjIgSGlzdG9ncmFtYXMNCk9zIGRhZG9zIHBvZGVtIHNlciB2aXN1YWxpemFkb3MgZ3JhZmljYW1lbnRlIHBvciBtZWlvIGRlIGhpc3RvZ3JhbWFzLCBlc3NhIGZvcm1hIGRlIHZpc3VhbGl6YcOnw6NvIMOpIGludGVyZXNzYW50ZSBwYXJhIG1vc3RyYXIgYSBkaXNwZXJzw6NvIGRvcyBkYWRvcy4gQSBwYXJ0aXIgZGVzdGVzIGdyw6FmaWNvcywgcGVyY2ViZS1zZSBxdWUgYW8gbG9uZ28gZG8gcGVyw61vZG8gb2JzZXJ2YWRvIGhvdXZlIHVtYSB0ZW5kw6puY2lhIGRlIGNvbnZlcmfDqm5jaWEgZGEgY29tcGxleGlkYWRlLCB2aXN0byBxdWUgYSBkaXNwYXJpZGFkZSBkZSBjb21wbGV4aWRhZGUgZW50cmUgYSBjYXBpdGFsIENhbXBvIEdyYW5kZSwgcXVlIHBvc3N1aSBhIG3DoXhpbWEgY29tcGxleGlkYWRlIHJlbGF0aXZhLCBkaW1pbnVpdSBlbSByZWxhw6fDo28gYW8gcmVzdG8gZG8gZXN0YWRvLiANCg0KIyMjIEhpc3RvZ3JhbWEgZGUgMjAwNg0KYGBge1J9DQojI3Zpc3VhbGl6YcOnw6NvIGdyw6FmaWNhIGRvcyBkYWRvcw0KaGlzdChJQ0UkSUNFX01TXzIwMDYkSUNFLA0KICAgICBtYWluID0gIkhpc3RvZ3JhbWEgZG8gSUNFIGRlIDIwMDYiLA0KICAgICB4bGFiID0gIlZhbG9yZXMgZGUgSUNFIiwNCiAgICAgeWxhYiA9ICJGcmVxdcOqbmNpYSIsDQogICAgIGNvbCA9ICJsaWdodGJsdWUiLA0KICAgICBicmVha3MgPSBzZXEobWluKElDRSRJQ0VfTVNfMjAwNiRJQ0UpLCBtYXgoSUNFJElDRV9NU18yMDA2JElDRSksIGxlbmd0aC5vdXQgPSAyMCksICMgb3BjaW9uYWwNCiAgICAgZnJlcSA9IFRSVUUpICAjIGZyZXE9RkFMU0UgcGFyYSBkZW5zaWRhZGUgcmVsYXRpdmENCmBgYA0KDQojIyMgSGlzdG9ncmFtYSBkZSAyMDE0DQpgYGB7Un0NCiMjdmlzdWFsaXphw6fDo28gZ3LDoWZpY2EgZG9zIGRhZG9zDQpoaXN0KElDRSRJQ0VfTVNfMjAxNCRJQ0UsDQogICAgIG1haW4gPSAiSGlzdG9ncmFtYSBkbyBJQ0UgZGUgMjAxNCIsDQogICAgIHhsYWIgPSAiVmFsb3JlcyBkZSBJQ0UiLA0KICAgICB5bGFiID0gIkZyZXF1w6puY2lhIiwNCiAgICAgY29sID0gImxpZ2h0Ymx1ZSIsDQogICAgIGJyZWFrcyA9IHNlcShtaW4oSUNFJElDRV9NU18yMDE0JElDRSksIG1heChJQ0UkSUNFX01TXzIwMTQkSUNFKSwgbGVuZ3RoLm91dCA9IDIwKSwgIyBvcGNpb25hbA0KICAgICBmcmVxID0gVFJVRSkgICMgZnJlcT1GQUxTRSBwYXJhIGRlbnNpZGFkZSByZWxhdGl2YQ0KYGBgDQoNCiMjIyBIaXN0b2dyYW1hIGRlIDIwMjINCmBgYHtSfQ0KIyN2aXN1YWxpemHDp8OjbyBncsOhZmljYSBkb3MgZGFkb3MNCmhpc3QoSUNFJElDRV9NU18yMDIyJElDRSwNCiAgICAgbWFpbiA9ICJIaXN0b2dyYW1hIGRvIElDRSBkZSAyMDIyIiwNCiAgICAgeGxhYiA9ICJWYWxvcmVzIGRlIElDRSIsDQogICAgIHlsYWIgPSAiRnJlcXXDqm5jaWEiLA0KICAgICBjb2wgPSAibGlnaHRibHVlIiwNCiAgICAgYnJlYWtzID0gc2VxKG1pbihJQ0UkSUNFX01TXzIwMjIkSUNFKSwgbWF4KElDRSRJQ0VfTVNfMjAyMiRJQ0UpLCBsZW5ndGgub3V0ID0gMjApLCAjIG9wY2lvbmFsDQogICAgIGZyZXEgPSBUUlVFKSAgIyBmcmVxPUZBTFNFIHBhcmEgZGVuc2lkYWRlIHJlbGF0aXZhDQpgYGANCg0KIyMgNi4zIE1hcGFzIGRvIE1TDQpQb3Igw7psdGltbywgcG9kZS1zZSB2aXN1YWxpemFyIGEgY29tcGxleGlkYWRlIGRvIE1TIHBvciBtZWlvIGRvIHVzbyBkZSBtYXBhcy4NCg0KUHJpbWVpcm8sIHBhcmEgdGFsLCDDqSBuZWNlc3PDoXJpbyB0ZXIgdW0gb2JqZXRvIGNvbSBvcyBtdW5pY8OtcGlvcyBlIGFzIHN1YXMgcmVzcGVjdGl2YXMgY29vcmRlbmFkYXMuDQpgYGB7Un0NCmFsbF9tdW5fbXMgPC0gcmVhZF9tdW5pY2lwYWxpdHkoY29kZV9tdW5pPTUwLCB5ZWFyPTIwMjIpDQpgYGANCg0KRW0gc2VndWlkYSwgw6kgbmVjZXNzw6FyaW8ganVudGFyIGFzIGNvb3JkZW5hZGFzIGRvcyBtdW5pY8OtcGlvcyBjb20gb3Mgc2V1cyByZXNwZWN0aXZvcyDDjW5kaWNlcyBkZSBDb21wbGV4aWRhZGUgRWNvbsO0bWljYSBlbSB1bSDDum5pY28gb2JqZXRvLiBDb21vIGEgb3JkZW0gZG9zIG11bmljw61waW9zIMOpIGNvaW5jaWRlbnRlbWVudGUgYSBtZXNtYSBub3MgZG9pcyBvYmpldG9zLCBwb2RlLXNlIGFwZW5hcyBmYXplciBpc3NvIGFwZW5hcyB1c2FuZG8gYSByb3RpbmEgY2JpbmQoKQ0KYGBge1J9DQpJQ0VfbWFwYXMgPC0gY2JpbmQoYWxsX211bl9tcyxJQ0VfY29uc29saWRhZG8pDQpgYGANCg0KIyMjIE1hcGEgZGUgMjAwNg0KYGBge1J9DQpnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YT1JQ0VfbWFwYXMsIGFlcyhmaWxsPVgyMDA2KSwgY29sb3I9ICJibGFjayIsIHNpemU9MC4wMSkrDQogIGxhYnModGl0bGU9IklDRSBkb3MgTXVuaWPDrXBpb3MgZG8gTVMgLSAyMDA2IiwNCiAgICAgICBjYXB0aW9uPSdGb250ZTogRWxhYm9yYcOnw6NvIHByw7NwcmlhJywgc2l6ZT04KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAicmVkIiwgDQogICAgICAgICAgICAgICAgICAgICAgIGhpZ2ggPSAiYmx1ZSIsIGxpbWl0cz1jKDAsIDEwMCksDQogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IklDRSIpKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyMgTWFwYSBkZSAyMDE0DQpgYGB7Un0NCmdncGxvdCgpICsNCiAgZ2VvbV9zZihkYXRhPUlDRV9tYXBhcywgYWVzKGZpbGw9WDIwMTQpLCBjb2xvcj0gImJsYWNrIiwgc2l6ZT0wLjAxKSsNCiAgbGFicyh0aXRsZT0iSUNFIGRvcyBNdW5pY8OtcGlvcyBkbyBNUyAtIDIwMTQiLA0KICAgICAgIGNhcHRpb249J0ZvbnRlOiBFbGFib3Jhw6fDo28gcHLDs3ByaWEnLCBzaXplPTgpKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJyZWQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICJibHVlIiwgbGltaXRzPWMoMCwgMTAwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iSUNFIikrDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjIyBNYXBhIGRlIDIwMjINCmBgYHtSfQ0KZ2dwbG90KCkgKw0KICBnZW9tX3NmKGRhdGE9SUNFX21hcGFzLCBhZXMoZmlsbD1YMjAyMiksIGNvbG9yPSAiYmxhY2siLCBzaXplPTAuMDEpKw0KICBsYWJzKHRpdGxlPSJJQ0UgZG9zIE11bmljw61waW9zIGRvIE1TIC0gMjAyMiIsDQogICAgICAgY2FwdGlvbj0nRm9udGU6IEVsYWJvcmHDp8OjbyBwcsOzcHJpYScsIHNpemU9OCkrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInJlZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICBoaWdoID0gImJsdWUiLCBsaW1pdHM9YygwLCAxMDApLA0KICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJJQ0UiKSsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIDcgQ29uY2x1c8Ojbw0KDQpDb20gdG9kb3Mgb3MgaW5kaWNhZG9yZXMgZSBkYWRvcyDDoCBkaXNwb3Npw6fDo28gcGVyY2ViZS1zZSB1bWEgZ3JhbmRlIGRpc2NyZXDDom5jaWEgZW50cmUgYSBjYXBpdGFsIENhbXBvIEdyYW5kZSwgcXVlIHBlcm1hbmVjZSBjb21vIG8gbXVuaWPDrXBpbyBtYWlzIGNvbXBsZXhvLCBlIG8gcmVzdG8gZG8gZXN0YWRvLiBUb2RhdmlhLCBwZXJjZWJlLXNlIHF1ZSBhbyBsb25nbyBkb3MgYW5vcyBhbmFsaXNhZG9zLCBpc3RvIMOpIGVudHJlIDIwMDYgZSAyMDIyLCBob3V2ZSB1bWEgdGVuZMOqbmNpYSBkZSBjb252ZXJnw6puY2lhIGRhIGVzdHJ1dHVyYSBwcm9kdXRpdmEgZG8gTVMgcXVlIGVzdMOhIGF0cmVsYWRvIGEgdW0gYXVtbmV0byBkYSBtw6lkaWEgZG8gw41uZGljZSBkZSBDb21wbGV4aWRhZGUgRWNvbsO0bWljYSwgaW5kbyBkZSAxMyw0MCBlbSAyMDA2IHBhcmEgMjEsMTMgZW0gMjAyMi4gT3V0cm9zc2ltLCBhIGltcG9ydMOibmNpYSBkZXN0ZXMgZGFkb3MgZXN0w6Egbm8gc2V1IHBvZGVyIGRlIGV2aWRlbmNpYXIgcXVhaXMgc8OjbyBvcyBtdW5pY8OtcGlvcyBxdWUgZXN0w6NvIHJlbGF0aXZhbWVudGUgbWFpcyBhdHJhc2Fkb3MgZXN0cnV0dXJhbG1lbnRlLiBJbmZvcm1hw6fDtWVzIGNvbW8gZXN0YSwgc8OjbyBpbXBvcnRhbnRlcyBpc3RydW1lbnRvcyBwYXJhIGEgYW7DoWxpc2UgZSBwYXJhIG8gZGVzZW5obyBkbyBkZXNlbnZvbHZpbWVudG8gZGEgZWNvbm9taWEgcmVnaW9uYWwuDQoNCiMgOCBSZWZlcsOqbmNpYXMNCg0KU0lMVkEgSlVOSU9SLCBFcm5hbmkgZGUgQWxtZWlkYTsgRkFHVU5ERVMsIE1heXJhIEJhdGlzdGEgQml0ZW5jb3VydDsgRklHVUVJUkVETywgQWRyaWFubyBNYXJjb3MgUm9kcmlndWVzOyBNQUNIQURPLCBKb8OjbyBWaWN0b3IuIENvbXBsZXhpZGFkZSBlY29uw7RtaWNhIHJlZ2lvbmFsOiB1bWEgYWJvcmRhZ2VtIGEgcGFydGlyIGRlIGRhZG9zIGRlIGVtcHJlZ28gcmVnaW9uYWwuIEluOiBDT05HUkVTU08gREEgU09CRVIsIDU3LiwgMjAxOSwgSWxow6l1cy4gQW5haXMgWy4uLl0uIElsaMOpdXM6IFNPQkVSLCAyMDE5Lg0KDQpST1NFTlNURUlO4oCRUk9EQU4sIFAuIE4uIFByb2JsZW1hcyBkZSBpbmR1c3RyaWFsaXphw6fDo28gZGEgRXVyb3BhIG9yaWVudGFsIGUgc3VkLW9yaWVudGFsLiBJbjogQUdBUldBTEEsIEEu4oCvTi47IFNJTkdILCBTLuKAr1AuIChPcmdzLikuIEEgZWNvbm9taWEgZG8gc3ViZGVzZW52b2x2aW1lbnRvLiBbUy5sLl06IFtzLm4uXSwgMTk0My4gDQoNCkxFV0lTLCBXLuKAr0EuIFRoZSBUaGVvcnkgb2YgRWNvbm9taWMgR3Jvd3RoLiBMb25kb246IEFsbGVuICYgVW53aW4gTHRkLiwgMTk1NS4gDQoNCkhJUlNDSE1BTiwgQS7igK9PLiBUaGUgU3RyYXRlZ3kgb2YgRWNvbm9taWMgRGV2ZWxvcG1lbnQuIE5ldyBIYXZlbiAoQ1QpOiBZYWxlIFVuaXZlcnNpdHkgUHJlc3MsIDE5NTguIA0KDQpQUkVCSVNDSCwgUi4gVGhlIEVjb25vbWljIERldmVsb3BtZW50IG9mIExhdGluIEFtZXJpY2EgYW5kIEl0cyBQcmluY2lwYWwgUHJvYmxlbXMuIEVjb25vbWljIEJ1bGxldGluIGZvciBMYXRpbiBBbWVyaWNhLCBuLuKArzcsIHAu4oCvMeKAkzIyLCAxOTYyLiANCg0KS1VaTkVUUywgUy4gTW9kZXJuIEVjb25vbWljIEdyb3d0aDogUmF0ZSwgU3RydWN0dXJlLCBhbmQgU3ByZWFkLiBOZXcgSGF2ZW4gYW5kIExvbmRvbjogWWFsZSBVbml2ZXJzaXR5IFByZXNzLCAxOTY2LiANCg0KS0FMRE9SLCBOLiBDYXVzZXMgb2YgdGhlIFNsb3cgUmF0ZSBvZiBFY29ub21pYyBHcm93dGggb2YgdGhlIFVuaXRlZCBLaW5nZG9tLiBDYW1icmlkZ2U6IENhbWJyaWRnZSBVbml2ZXJzaXR5IFByZXNzLCAxOTY2Lg0KDQpGVVJUQURPLCBDLiBEaWFsw6l0aWNhIGRvIGRlc2Vudm9sdmltZW50by4gUmlvIGRlIEphbmVpcm86IEZ1bmRvIGRlIEN1bHR1cmEsIDE5NjQuIA0KDQpIQVVTTUFOTiwgUmljYXJkbyBldCBhbC4gVGhlIEF0bGFzIG9mIEVjb25vbWljIENvbXBsZXhpdHk6IE1hcHBpbmcgUGF0aHMgdG8gUHJvc3Blcml0eS4gQ2FtYnJpZGdlOiBUaGUgTUlUIFByZXNzLCAyMDEzLiBEaXNwb27DrXZlbCBlbTogaHR0cDovL3d3dy5qc3Rvci5vcmcvc3RhYmxlL2ouY3R0OXFmOGpwLiBBY2Vzc28gZW06IDI0IGp1bC4gMjAyNS4NCg0KSElEQUxHTywgQ8Opc2FyIEEuOyBIQVVTTUFOTiwgUmljYXJkby4gVGhlIEJ1aWxkaW5nIEJsb2NrcyBvZiBFY29ub21pYyBDb21wbGV4aXR5LiBQcm9jZWVkaW5ncyBvZiB0aGUgTmF0aW9uYWwgQWNhZGVteSBvZiBTY2llbmNlcyBvZiB0aGUgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhLCB2LuKArzEwNiwgbi7igK8yNiwgcC7igK8xMDU3MOKAkzEwNTc1LCAzMCBqdW4uIDIwMDkuIERPSTogMTAuMTA3My9wbmFzLjA5MDA5NDMxMDYuDQoNCkJBTEFTU0EsIEIuIFRyYWRlIGxpYmVyYWxpc2F0aW9uIGFuZCAicmV2ZWFsZWQiIGNvbXBhcmF0aXZlIGFkdmFudGFnZS4gVGhlIE1hbmNoZXN0ZXIgU2Nob29sLCB2LiAzMywgbi4gMiwgcC4gOTnigJMxMjMsIDE5NjUuDQoNCkZJR1VFSVJFRE8sIEFkcmlhbm8gTWFyY29zIFJvZHJpZ3Vlcy4gTWFwYXMgZW0gUiBjb20gYGdlb2JyYC4gQ2FtcG8gR3JhbmRlLU1TLEJyYXNpbDogUlN0dWRpby9ScHVicywgMjAyMC4gRGlzcG9uw612ZWwgZW0gPGh0dHBzOi8vYWRyaWFub2ZpZ3VlaXJlZG8ubmV0bGlmeS5jb20vcG9zdC9tYXBhcy1lbS1yLWNvbS1nZW9ici8+Lg==