Analise da Assiduidade dos Alunos por Grupo e Distrito no Ano Letivo de 2021-2022 📚🏫

Problema

A assiduidade dos alunos em escolas públicas é essencial para o sucesso acadêmico, mas diferentes grupos de alunos podem enfrentar desafios únicos que afetam sua frequência escolar. Este estudo visa investigar e compreender a assiduidade dos alunos por grupo e distrito durante o ano letivo de 2021-2022. O problema central é identificar os fatores que influenciam a assiduidade dos alunos, como situação de rua, deficiência, elegibilidade para almoço grátis/a preço reduzido, status de inglês e raça/etnia, e analisar como esses fatores variam entre os diferentes grupos de alunos e distritos escolares.

Justificativa da Análise

A compreensão dos fatores que influenciam a assiduidade dos alunos é fundamental para desenvolver estratégias e políticas educacionais eficazes que promovam a igualdade de oportunidades e o sucesso acadêmico para todos os alunos. Ao identificar os desafios específicos enfrentados por diferentes grupos de alunos e distritos, podemos direcionar recursos e intervenções de forma mais precisa, visando melhorar a assiduidade e, consequentemente, o desempenho acadêmico.

Objectivos da Análise

  1. Identificar padrões de assiduidade: Analisar os dados para ver se alguns grupos de alunos ou distritos têm taxas de frequência consistentemente altas ou baixas.

  2. Comparar grupos e distritos: Verificar se a assiduidade varia entre os grupos de alunos (por exemplo, alunos com deficiência, alunos de inglês) e entre os distritos escolares.

  3. Identificar fatores importantes: Descobrir quais fatores, como situação de rua, deficiência ou elegibilidade para almoço grátis, têm o maior impacto na assiduidade dos alunos.

  4. Avaliar políticas existentes: Verificar se as políticas atuais estão ajudando a melhorar a assiduidade dos alunos ou se precisam ser ajustadas.

  5. Sugerir melhorias futuras: Usar as descobertas para sugerir maneiras de melhorar a assiduidade dos alunos e o desempenho acadêmico.


PREPARAÇÃO DE DADOS

Carragemento de pactotes

library(tidyverse)
library(stats)
library(janitor) #
library(sgeostat)
library(mvoutlier)
library(summarytools)
library(conflicted)
library(outliers)
conflict_prefer("filter", "dplyr") 
[conflicted] Removing existing preference.
[conflicted] Will prefer dplyr::filter over any other package.
conflict_prefer("lag", "dplyr")
[conflicted] Removing existing preference.
[conflicted] Will prefer dplyr::lag over any other package.

Importação do Dataset

escola <- readr::read_csv("School_Attendance_by_Student_Group.csv", show_col_types = FALSE) |> 
  janitor::clean_names() # Padronizar os nomes das colunas 

Descrição do dataset

Este conjunto de dados inclui a taxa de frequência de alunos de escolas públicas PK-12 por grupo de alunos e por distrito durante o ano letivo de 2021-2022. Os grupos de estudantes (Alunos em situação de rua, Alunos com deficiência, Alunos que se qualificam para almoço grátis/a preço reduzido, Alunos de inglês, Todos os alunos com altas necessidades, Alunos com necessidades não altas, Alunos por raça/etnia (hispânicos/latinos de qualquer raça, negros ou afro-americanos, brancos, todas as outras raças)

As taxas de frequência são fornecidas para cada grupo de estudantes por distrito e por estado. Os alunos considerados de alta necessidade incluem alunos que estão aprendendo a língua inglesa, que recebem educação especial ou que se qualificam para almoço grátis e com preço reduzido.

Quando nenhum dado de frequência é exibido em uma célula, os dados foram suprimidos para salvaguardar a confidencialidade do aluno ou para garantir que as estatísticas baseadas em um tamanho de amostra muito pequeno não sejam interpretadas como igualmente representativas como aquelas baseadas em um tamanho de amostra suficientemente maior.

Download

visualizar as primeiras linhas

utils::head(escola) # Exibir as primeiras linhas do dataset

Estrutura do dataset

dplyr::glimpse(escola) # Visualizar a estrutura do dataset
Rows: 2,019
Columns: 12
$ district_code                           <chr> "00000CT", "00000CT", "00000CT", "000…
$ district_name                           <chr> "Connecticut", "Connecticut", "Connec…
$ category                                <chr> NA, "Homelessness", "Students With Di…
$ student_group                           <chr> "All Students", "Students Experiencin…
$ x2021_2022_student_count_year_to_date   <dbl> 500285, 1814, 78417, 168984, 29905, 1…
$ x2021_2022_attendance_rate_year_to_date <dbl> 0.9169, 0.8348, 0.8899, 0.8851, 0.918…
$ x2020_2021_student_count                <dbl> 496092, 1735, 76487, 176225, 30886, 2…
$ x2020_2021_attendance_rate              <dbl> 0.9294, 0.8155, 0.8946, 0.8861, 0.929…
$ x2019_2020_student_count                <dbl> 508346, 3916, 80365, 193706, 27507, 2…
$ x2019_2020_attendance_rate              <dbl> 0.9479, 0.8884, 0.9277, 0.9314, 0.951…
$ reporting_period                        <chr> "June 2022", "June 2022", "June 2022"…
$ date_update                             <chr> "07/22/2022", "07/22/2022", "07/22/20…

Limpeza de dados

Valores ausentes (NA)

Identificar NA
escola |> 
  dplyr::summarise_all(~sum(is.na(.))) # Indetificar o numero de NA por coluna

Os resultados mostram que há NA no dataset, na coluna Category foram encontrados 201 NA, x2020_2021_student_count apresentou 56 NA, x2020_2021_attendance_rate tem 56 NA, x2019_2020_student_count, x2019_2020_attendance_rate e x2019_2020_attendance tem 62 cada.

Há varias formas de tratamento de valores ausentes (NA), mas para esta análise irei optar pela remoção

Remoção de NA
escola_sem_na <- escola |>
  tidyr::drop_na()      # remover NA
head(escola_sem_na)     # visualizar primeiras linhas do dataset sem NA

Linhas duplicadas

Identificar Linhas Duplicadas
escola_sem_na |> 
   janitor::get_dupes()
No variable names specified - using all columns.

No duplicate combinations found of: district_code, district_name, category, student_group, x2021_2022_student_count_year_to_date, x2021_2022_attendance_rate_year_to_date, x2020_2021_student_count, x2020_2021_attendance_rate, x2019_2020_student_count, ... and 3 other variables

Os resultados mostram que não há linhas duplicadas no dataset. Caso haja linhas duplicadas usa-se a seguinte codigo

Remocão de linhas duplicadas
escola_sem_na |> 
  dplyr::distinct()

Valores discripantes (Outliers)

Identificar Outliers
# Indentificar outlieres em todo dataframe
 escola_sem_na |> 
select_if(is.numeric) |>
  outlier()
  x2021_2022_student_count_year_to_date x2021_2022_attendance_rate_year_to_date 
                            248239.0000                                  0.7152 
               x2020_2021_student_count              x2020_2021_attendance_rate 
                            251220.0000                                  0.6882 
               x2019_2020_student_count              x2019_2020_attendance_rate 
                            266736.0000                                  0.8196 

Os resultados mostram que há outliers no Dataset. Vamos remover os outliers

Remover outliers
# Filtrando outliers na coluna x2021_2022_attendance_rate_year_to_date
escola_sem_outliers <- escola_sem_na |> 
  filter(!is.na(x2021_2022_attendance_rate_year_to_date) & x2021_2022_attendance_rate_year_to_date >= quantile(x2021_2022_attendance_rate_year_to_date, 0.25) - 1.5 * IQR(x2021_2022_attendance_rate_year_to_date) & x2021_2022_attendance_rate_year_to_date <= quantile(x2021_2022_attendance_rate_year_to_date, 0.75) + 1.5 * IQR(x2021_2022_attendance_rate_year_to_date))

escola_sem_outliers

Manipulacção de Dados

Selecção de variáveis para a Análise
escola_sel <- escola_sem_outliers |> 
  select(district_name, category, student_group, x2021_2022_student_count_year_to_date, x2021_2022_attendance_rate_year_to_date, x2021_2022_attendance_rate_year_to_date)

head(escola_sel)
Alterar nomes de variaveis
escola_limpa <- escola_sel |> 
  dplyr::rename(nome_distrito=district_name, 
               categoria =category,
               grupo_estudante = student_group,
            contagem_anual_estudantes=x2021_2022_student_count_year_to_date,
              taxa_assiduidade=x2021_2022_attendance_rate_year_to_date)

head(escola_limpa)

Visualização de Dados

Histogram

hist_original <- ggplot(escola_limpa, aes(x = taxa_assiduidade)) + geom_histogram(bins = 20,
                                                    fill = "skyblue",
                                                    color = "black") + ggtitle("Distribuição da taxa de asseduidade")
hist_original

Um histograma é um gráfico de barras usado para representar a distribuição de uma variável quantitativa. Ele mostra a frequência de valores dentro de intervalos de valores, chamados de “bins” ou “classes”. Cada barra no histograma representa a frequência (ou contagem) de observações que caem dentro de um determinado intervalo.

Boxplot

# Criar o boxplot com ggplot2
ggplot(escola_limpa, aes(y = taxa_assiduidade)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  labs(title = "Boxplot da Taxa de Assiduidade", y = "Taxa de Assiduidade")

Foi possivel encontrar outliers nesse boxplot, por isso terei de os remove-los novamente.

Remoção de outliers usando o metodo de calculos de limites dos bigodes

# Calcular os limites dos bigodes
Q1 <- quantile(escola_limpa$taxa_assiduidade, 0.25)
Q3 <- quantile(escola_limpa$taxa_assiduidade, 0.75)
IQR <- Q3 - Q1
limite_inferior <- Q1 - 1.5 * IQR
limite_superior <- Q3 + 1.5 * IQR

# Remover outliers
escola_sem_outliers <- escola_limpa[escola_limpa$taxa_assiduidade >= limite_inferior & escola_limpa$taxa_assiduidade <= limite_superior, ]
escola_sem_outliers

Novo Boxplot

# Criar o boxplot com ggplot2
ggplot(escola_sem_outliers
, aes(y = taxa_assiduidade)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  labs(title = "Boxplot da Taxa de Assiduidade", y = "Taxa de Assiduidade")

Novo Histogram

segundo_hist <- ggplot(escola_sem_outliers, aes(x = taxa_assiduidade)) + geom_histogram(bins = 20,
                                                    fill = "skyblue",
                                                    color = "black") + ggtitle("Distribuição da taxa de asseduidade")
segundo_hist

Gráfico Q-Q normal

# Criar o gráfico Q-Q normal
ggplot(escola_sem_outliers, aes(sample = taxa_assiduidade)) +
  geom_qq() +
  geom_qq_line() +
  labs(title = "Gráfico Q-Q Normal",
       x = "Quantis teóricos da distribuição normal",
       y = "Quantis observados da variável")

Gráfico de densidade

# Criar o gráfico de densidade Q-Q
ggplot(escola_sem_outliers, aes(sample = taxa_assiduidade)) +
  stat_qq(color = "red") +
  geom_abline(slope = 1, intercept = 0, color = "green") +
  labs(title = "Gráfico de Densidade Q-Q",
       x = "Quantis teóricos da distribuição normal",
       y = "Quantis observados da variável") +
  theme_minimal()


Exploração de Dados

Resumo Estatítistico

resumo_estatistico <- escola_sem_outliers |> 
  summarytools::descr() |> 
  base::data.frame()
resumo_estatistico

Agregação

Agregação por Distrito

#Agregacao por Distrito
agregado_escola_distrito <- escola_sem_outliers |> 
  group_by(nome_distrito) |> 
  summarise(media_distrito = mean(taxa_assiduidade))
agregado_escola_distrito

Visualizacao do agregado por distrito

# Criar o gráfico de barras horizontal com cores
ggplot(agregado_escola_distrito, aes(x = media_distrito, y = nome_distrito, fill = nome_distrito)) +
  geom_bar(stat = "identity") +
  scale_fill_viridis_d(option = "D") +  # Aplicar as cores manualmente
  labs(title = "Asseduidade dos estudantes",
       x = "Total de Estudantes",
       y = "Categoria") +
  theme_minimal()

Agregação por Categoria

#Agregacao - Media de taxa de asseduidade por categoria
agregado_escola_categoria <- escola_limpa |> 
  group_by(categoria) |> 
  summarise(media_categoria = mean(taxa_assiduidade))
agregado_escola_categoria

Visualizacao de agregado por categoria

Grafico de barras Horizontal

# Criar o gráfico de barras horizontal com cores
ggplot(agregado_escola_categoria , aes(x = media_categoria, y = categoria, fill = categoria)) +
  geom_bar(stat = "identity") +
  scale_fill_viridis_d(option = "D") +  # Aplicar as cores manualmente
  labs(title = "Assiduidade dos estudantes",
       x = "Total de Estudantes",
       y = "Categoria") +
  theme_minimal()

Grafico Pizza

# Gráfico de setores
ggplot(agregado_escola_categoria, aes(x = "", y = media_categoria, fill = categoria)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  scale_fill_viridis_d(option = "D") +
  labs(title = "Assiduidade dos estudantes",
       fill = "Categoria",
       x = NULL,
       y = NULL) +
  theme_void()


Analide Estatística

Utilizarei métodos estatísticos, como ANOVA, regressão linear ou regressão logística, para avaliar a relação entre as categorias e a taxa de assiduidade.

ANOVA

Pressupostos da ANOVA

Analise de Normalidade

  1. Texte de Shapiro Wilk
# Teste de Shapiro Wilk
shapiro_asseduidade <- stats::shapiro.test(escola_sem_outliers$taxa_assiduidade)
shapiro_asseduidade

    Shapiro-Wilk normality test

data:  escola_sem_outliers$taxa_assiduidade
W = 0.97441, p-value < 2.2e-16

O teste de normalidade de Shapiro-Wilk para a variável taxa_assiduidade resultou em um valor de estatística de teste (W) de aproximadamente 0.886 e um valor p muito pequeno (menor que 2.2e-16). Isso indica que há evidências estatisticamente significativas para rejeitar a hipótese nula de que os dados seguem uma distribuição normal. Ou seja, a taxa_assiduidade não segue uma distribuição normal. Logo não se pode fazer Análise de Variaça com amostras que não seguem uma distribuíção normal, uma das possiveis soluções é realizar a transformação dos dados

Transformacao logaritimica para normalizar a distribuicao dos dados

asseduidade_log <- sqrt(escola_sem_outliers$taxa_assiduidade)
asseduidade_transf <- data.frame(escola_sem_outliers$categoria, asseduidade_log)
head(asseduidade_transf)

CONTINUA…

LS0tDQp0aXRsZTogIlJhc2N1bmhvIGRlIExpbXBlemEgZGUgRGFkb3MgY29tIFIiDQphdXRob3I6ICJCZWxvdGUgTWF0c2luaGUiDQpkYXRlOiAiMDUgZGUgTWFpbyBkZSAyMDI0Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIEFuYWxpc2UgZGEgQXNzaWR1aWRhZGUgZG9zIEFsdW5vcyBwb3IgR3J1cG8gZSBEaXN0cml0byBubyBBbm8gTGV0aXZvIGRlIDIwMjEtMjAyMiDwn5Oa8J+Pqw0KDQojIyMgKioqUHJvYmxlbWEqKioNCg0KQSBhc3NpZHVpZGFkZSBkb3MgYWx1bm9zIGVtIGVzY29sYXMgcMO6YmxpY2FzIMOpIGVzc2VuY2lhbCBwYXJhIG8gc3VjZXNzbyBhY2Fkw6ptaWNvLCBtYXMgZGlmZXJlbnRlcyBncnVwb3MgZGUgYWx1bm9zIHBvZGVtIGVuZnJlbnRhciBkZXNhZmlvcyDDum5pY29zIHF1ZSBhZmV0YW0gc3VhIGZyZXF1w6puY2lhIGVzY29sYXIuIEVzdGUgZXN0dWRvIHZpc2EgaW52ZXN0aWdhciBlIGNvbXByZWVuZGVyIGEgYXNzaWR1aWRhZGUgZG9zIGFsdW5vcyBwb3IgZ3J1cG8gZSBkaXN0cml0byBkdXJhbnRlIG8gYW5vIGxldGl2byBkZSAyMDIxLTIwMjIuIE8gcHJvYmxlbWEgY2VudHJhbCDDqSBpZGVudGlmaWNhciBvcyBmYXRvcmVzIHF1ZSBpbmZsdWVuY2lhbSBhIGFzc2lkdWlkYWRlIGRvcyBhbHVub3MsIGNvbW8gc2l0dWHDp8OjbyBkZSBydWEsIGRlZmljacOqbmNpYSwgZWxlZ2liaWxpZGFkZSBwYXJhIGFsbW/Dp28gZ3LDoXRpcy9hIHByZcOnbyByZWR1emlkbywgc3RhdHVzIGRlIGluZ2zDqnMgZSByYcOnYS9ldG5pYSwgZSBhbmFsaXNhciBjb21vIGVzc2VzIGZhdG9yZXMgdmFyaWFtIGVudHJlIG9zIGRpZmVyZW50ZXMgZ3J1cG9zIGRlIGFsdW5vcyBlIGRpc3RyaXRvcyBlc2NvbGFyZXMuDQoNCiMjIyAqKipKdXN0aWZpY2F0aXZhIGRhIEFuw6FsaXNlKioqDQoNCkEgY29tcHJlZW5zw6NvIGRvcyBmYXRvcmVzIHF1ZSBpbmZsdWVuY2lhbSBhIGFzc2lkdWlkYWRlIGRvcyBhbHVub3Mgw6kgZnVuZGFtZW50YWwgcGFyYSBkZXNlbnZvbHZlciBlc3RyYXTDqWdpYXMgZSBwb2zDrXRpY2FzIGVkdWNhY2lvbmFpcyBlZmljYXplcyBxdWUgcHJvbW92YW0gYSBpZ3VhbGRhZGUgZGUgb3BvcnR1bmlkYWRlcyBlIG8gc3VjZXNzbyBhY2Fkw6ptaWNvIHBhcmEgdG9kb3Mgb3MgYWx1bm9zLiBBbyBpZGVudGlmaWNhciBvcyBkZXNhZmlvcyBlc3BlY8OtZmljb3MgZW5mcmVudGFkb3MgcG9yIGRpZmVyZW50ZXMgZ3J1cG9zIGRlIGFsdW5vcyBlIGRpc3RyaXRvcywgcG9kZW1vcyBkaXJlY2lvbmFyIHJlY3Vyc29zIGUgaW50ZXJ2ZW7Dp8O1ZXMgZGUgZm9ybWEgbWFpcyBwcmVjaXNhLCB2aXNhbmRvIG1lbGhvcmFyIGEgYXNzaWR1aWRhZGUgZSwgY29uc2VxdWVudGVtZW50ZSwgbyBkZXNlbXBlbmhvIGFjYWTDqm1pY28uDQoNCiMjIyAqKipPYmplY3Rpdm9zIGRhIEFuw6FsaXNlKioqDQoNCjEuICAqKklkZW50aWZpY2FyIHBhZHLDtWVzIGRlIGFzc2lkdWlkYWRlOioqIEFuYWxpc2FyIG9zIGRhZG9zIHBhcmEgdmVyIHNlIGFsZ3VucyBncnVwb3MgZGUgYWx1bm9zIG91IGRpc3RyaXRvcyB0w6ptIHRheGFzIGRlIGZyZXF1w6puY2lhIGNvbnNpc3RlbnRlbWVudGUgYWx0YXMgb3UgYmFpeGFzLg0KDQoyLiAgKipDb21wYXJhciBncnVwb3MgZSBkaXN0cml0b3M6KiogVmVyaWZpY2FyIHNlIGEgYXNzaWR1aWRhZGUgdmFyaWEgZW50cmUgb3MgZ3J1cG9zIGRlIGFsdW5vcyAocG9yIGV4ZW1wbG8sIGFsdW5vcyBjb20gZGVmaWNpw6puY2lhLCBhbHVub3MgZGUgaW5nbMOqcykgZSBlbnRyZSBvcyBkaXN0cml0b3MgZXNjb2xhcmVzLg0KDQozLiAgKipJZGVudGlmaWNhciBmYXRvcmVzIGltcG9ydGFudGVzOioqIERlc2NvYnJpciBxdWFpcyBmYXRvcmVzLCBjb21vIHNpdHVhw6fDo28gZGUgcnVhLCBkZWZpY2nDqm5jaWEgb3UgZWxlZ2liaWxpZGFkZSBwYXJhIGFsbW/Dp28gZ3LDoXRpcywgdMOqbSBvIG1haW9yIGltcGFjdG8gbmEgYXNzaWR1aWRhZGUgZG9zIGFsdW5vcy4NCg0KNC4gICoqQXZhbGlhciBwb2zDrXRpY2FzIGV4aXN0ZW50ZXM6KiogVmVyaWZpY2FyIHNlIGFzIHBvbMOtdGljYXMgYXR1YWlzIGVzdMOjbyBhanVkYW5kbyBhIG1lbGhvcmFyIGEgYXNzaWR1aWRhZGUgZG9zIGFsdW5vcyBvdSBzZSBwcmVjaXNhbSBzZXIgYWp1c3RhZGFzLg0KDQo1LiAgKipTdWdlcmlyIG1lbGhvcmlhcyBmdXR1cmFzOioqIFVzYXIgYXMgZGVzY29iZXJ0YXMgcGFyYSBzdWdlcmlyIG1hbmVpcmFzIGRlIG1lbGhvcmFyIGEgYXNzaWR1aWRhZGUgZG9zIGFsdW5vcyBlIG8gZGVzZW1wZW5obyBhY2Fkw6ptaWNvLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgKioqUFJFUEFSQcOHw4NPIERFIERBRE9TKioqDQoNCiMjIyAqKipDYXJyYWdlbWVudG8gZGUgcGFjdG90ZXMqKioNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc3RhdHMpDQpsaWJyYXJ5KGphbml0b3IpICMNCmxpYnJhcnkoc2dlb3N0YXQpDQpsaWJyYXJ5KG12b3V0bGllcikNCmxpYnJhcnkoc3VtbWFyeXRvb2xzKQ0KbGlicmFyeShjb25mbGljdGVkKQ0KbGlicmFyeShvdXRsaWVycykNCmNvbmZsaWN0X3ByZWZlcigiZmlsdGVyIiwgImRwbHlyIikgDQpjb25mbGljdF9wcmVmZXIoImxhZyIsICJkcGx5ciIpDQoNCmBgYA0KDQojIyMgKioqSW1wb3J0YcOnw6NvIGRvIERhdGFzZXQqKioNCg0KYGBge3J9DQplc2NvbGEgPC0gcmVhZHI6OnJlYWRfY3N2KCJTY2hvb2xfQXR0ZW5kYW5jZV9ieV9TdHVkZW50X0dyb3VwLmNzdiIsIHNob3dfY29sX3R5cGVzID0gRkFMU0UpIHw+IA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICMgUGFkcm9uaXphciBvcyBub21lcyBkYXMgY29sdW5hcyANCmBgYA0KDQojIyMjICoqKkRlc2NyacOnw6NvIGRvIGRhdGFzZXQqKioNCg0KRXN0ZSBjb25qdW50byBkZSBkYWRvcyBpbmNsdWkgYSB0YXhhIGRlIGZyZXF1w6puY2lhIGRlIGFsdW5vcyBkZSBlc2NvbGFzIHDDumJsaWNhcyBQSy0xMiBwb3IgZ3J1cG8gZGUgYWx1bm9zIGUgcG9yIGRpc3RyaXRvIGR1cmFudGUgbyBhbm8gbGV0aXZvIGRlIDIwMjEtMjAyMi4gT3MgZ3J1cG9zIGRlIGVzdHVkYW50ZXMgKEFsdW5vcyBlbSBzaXR1YcOnw6NvIGRlIHJ1YSwgQWx1bm9zIGNvbSBkZWZpY2nDqm5jaWEsIEFsdW5vcyBxdWUgc2UgcXVhbGlmaWNhbSBwYXJhIGFsbW/Dp28gZ3LDoXRpcy9hIHByZcOnbyByZWR1emlkbywgQWx1bm9zIGRlIGluZ2zDqnMsIFRvZG9zIG9zIGFsdW5vcyBjb20gYWx0YXMgbmVjZXNzaWRhZGVzLCBBbHVub3MgY29tIG5lY2Vzc2lkYWRlcyBuw6NvIGFsdGFzLCBBbHVub3MgcG9yIHJhw6dhL2V0bmlhIChoaXNww6JuaWNvcy9sYXRpbm9zIGRlIHF1YWxxdWVyIHJhw6dhLCBuZWdyb3Mgb3UgYWZyby1hbWVyaWNhbm9zLCBicmFuY29zLCB0b2RhcyBhcyBvdXRyYXMgcmHDp2FzKQ0KDQpBcyB0YXhhcyBkZSBmcmVxdcOqbmNpYSBzw6NvIGZvcm5lY2lkYXMgcGFyYSBjYWRhIGdydXBvIGRlIGVzdHVkYW50ZXMgcG9yIGRpc3RyaXRvIGUgcG9yIGVzdGFkby4gT3MgYWx1bm9zIGNvbnNpZGVyYWRvcyBkZSBhbHRhIG5lY2Vzc2lkYWRlIGluY2x1ZW0gYWx1bm9zIHF1ZSBlc3TDo28gYXByZW5kZW5kbyBhIGzDrW5ndWEgaW5nbGVzYSwgcXVlIHJlY2ViZW0gZWR1Y2HDp8OjbyBlc3BlY2lhbCBvdSBxdWUgc2UgcXVhbGlmaWNhbSBwYXJhIGFsbW/Dp28gZ3LDoXRpcyBlIGNvbSBwcmXDp28gcmVkdXppZG8uDQoNClF1YW5kbyBuZW5odW0gZGFkbyBkZSBmcmVxdcOqbmNpYSDDqSBleGliaWRvIGVtIHVtYSBjw6lsdWxhLCBvcyBkYWRvcyBmb3JhbSBzdXByaW1pZG9zIHBhcmEgc2FsdmFndWFyZGFyIGEgY29uZmlkZW5jaWFsaWRhZGUgZG8gYWx1bm8gb3UgcGFyYSBnYXJhbnRpciBxdWUgYXMgZXN0YXTDrXN0aWNhcyBiYXNlYWRhcyBlbSB1bSB0YW1hbmhvIGRlIGFtb3N0cmEgbXVpdG8gcGVxdWVubyBuw6NvIHNlamFtIGludGVycHJldGFkYXMgY29tbyBpZ3VhbG1lbnRlIHJlcHJlc2VudGF0aXZhcyBjb21vIGFxdWVsYXMgYmFzZWFkYXMgZW0gdW0gdGFtYW5obyBkZSBhbW9zdHJhIHN1ZmljaWVudGVtZW50ZSBtYWlvci4NCg0KW0Rvd25sb2FkXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vZmlsZS9kLzFQV0VKOEhsekN0dTIxTjdiRFRsTmV2d0lvbDBBMC0zRC92aWV3P3VzcD1zaGFyaW5nICJTY2hvb2xfQXR0ZW5kYW5jZV9ieV9TdHVkZW50X0dyb3VwLmNzdiIpDQoNCiMjIyAqKip2aXN1YWxpemFyIGFzIHByaW1laXJhcyBsaW5oYXMqKioNCg0KYGBge3J9DQp1dGlsczo6aGVhZChlc2NvbGEpICMgRXhpYmlyIGFzIHByaW1laXJhcyBsaW5oYXMgZG8gZGF0YXNldA0KYGBgDQoNCiMjIyAqKipFc3RydXR1cmEgZG8gZGF0YXNldCoqKg0KDQpgYGB7cn0NCmRwbHlyOjpnbGltcHNlKGVzY29sYSkgIyBWaXN1YWxpemFyIGEgZXN0cnV0dXJhIGRvIGRhdGFzZXQNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjICoqKkxpbXBlemEgZGUgZGFkb3MqKioNCg0KIyMjIyAqKipWYWxvcmVzIGF1c2VudGVzIChOQSkqKioNCg0KIyMjIyMgKioqSWRlbnRpZmljYXIgTkEqKioNCg0KYGBge3J9DQplc2NvbGEgfD4gDQogIGRwbHlyOjpzdW1tYXJpc2VfYWxsKH5zdW0oaXMubmEoLikpKSAjIEluZGV0aWZpY2FyIG8gbnVtZXJvIGRlIE5BIHBvciBjb2x1bmENCmBgYA0KDQpPcyByZXN1bHRhZG9zIG1vc3RyYW0gcXVlIGjDoSBOQSBubyBkYXRhc2V0LCBuYSBjb2x1bmEgQ2F0ZWdvcnkgZm9yYW0gZW5jb250cmFkb3MgMjAxIE5BLCB4MjAyMF8yMDIxX3N0dWRlbnRfY291bnQgYXByZXNlbnRvdSA1NiBOQSwgeDIwMjBfMjAyMV9hdHRlbmRhbmNlX3JhdGUgdGVtIDU2IE5BLCB4MjAxOV8yMDIwX3N0dWRlbnRfY291bnQsIHgyMDE5XzIwMjBfYXR0ZW5kYW5jZV9yYXRlIGUgeDIwMTlfMjAyMF9hdHRlbmRhbmNlIHRlbSA2MiBjYWRhLg0KDQpIw6EgdmFyaWFzIGZvcm1hcyBkZSB0cmF0YW1lbnRvIGRlIHZhbG9yZXMgYXVzZW50ZXMgKE5BKSwgbWFzIHBhcmEgZXN0YSBhbsOhbGlzZSBpcmVpIG9wdGFyIHBlbGEgcmVtb8Onw6NvDQoNCiMjIyMjICoqKlJlbW/Dp8OjbyBkZSBOQSoqKg0KDQpgYGB7cn0NCmVzY29sYV9zZW1fbmEgPC0gZXNjb2xhIHw+DQogIHRpZHlyOjpkcm9wX25hKCkgICAgICAjIHJlbW92ZXIgTkENCmhlYWQoZXNjb2xhX3NlbV9uYSkgICAgICMgdmlzdWFsaXphciBwcmltZWlyYXMgbGluaGFzIGRvIGRhdGFzZXQgc2VtIE5BDQpgYGANCg0KIyMjIyAqKipMaW5oYXMgZHVwbGljYWRhcyoqKg0KDQojIyMjIyAqKipJZGVudGlmaWNhciBMaW5oYXMgRHVwbGljYWRhcyoqKg0KDQpgYGB7cn0NCmVzY29sYV9zZW1fbmEgfD4gDQogICBqYW5pdG9yOjpnZXRfZHVwZXMoKQ0KYGBgDQoNCk9zIHJlc3VsdGFkb3MgbW9zdHJhbSBxdWUgbsOjbyBow6EgbGluaGFzIGR1cGxpY2FkYXMgbm8gZGF0YXNldC4gQ2FzbyBoYWphIGxpbmhhcyBkdXBsaWNhZGFzIHVzYS1zZSBhIHNlZ3VpbnRlIGNvZGlnbw0KDQojIyMjIyAqKipSZW1vY8OjbyBkZSBsaW5oYXMgZHVwbGljYWRhcyoqKg0KDQpgYGB7cn0NCmVzY29sYV9zZW1fbmEgfD4gDQogIGRwbHlyOjpkaXN0aW5jdCgpDQpgYGANCg0KIyMjIyAqKipWYWxvcmVzIGRpc2NyaXBhbnRlcyAoT3V0bGllcnMpKioqDQoNCiMjIyMjICoqKklkZW50aWZpY2FyIE91dGxpZXJzKioqDQoNCmBgYHtyfQ0KIyBJbmRlbnRpZmljYXIgb3V0bGllcmVzIGVtIHRvZG8gZGF0YWZyYW1lDQogZXNjb2xhX3NlbV9uYSB8PiANCnNlbGVjdF9pZihpcy5udW1lcmljKSB8Pg0KICBvdXRsaWVyKCkNCmBgYA0KDQpPcyByZXN1bHRhZG9zIG1vc3RyYW0gcXVlIGjDoSBvdXRsaWVycyBubyBEYXRhc2V0LiBWYW1vcyByZW1vdmVyIG9zIG91dGxpZXJzDQoNCiMjIyMjICoqKlJlbW92ZXIgb3V0bGllcnMqKioNCg0KYGBge3J9DQojIEZpbHRyYW5kbyBvdXRsaWVycyBuYSBjb2x1bmEgeDIwMjFfMjAyMl9hdHRlbmRhbmNlX3JhdGVfeWVhcl90b19kYXRlDQplc2NvbGFfc2VtX291dGxpZXJzIDwtIGVzY29sYV9zZW1fbmEgfD4gDQogIGZpbHRlcighaXMubmEoeDIwMjFfMjAyMl9hdHRlbmRhbmNlX3JhdGVfeWVhcl90b19kYXRlKSAmIHgyMDIxXzIwMjJfYXR0ZW5kYW5jZV9yYXRlX3llYXJfdG9fZGF0ZSA+PSBxdWFudGlsZSh4MjAyMV8yMDIyX2F0dGVuZGFuY2VfcmF0ZV95ZWFyX3RvX2RhdGUsIDAuMjUpIC0gMS41ICogSVFSKHgyMDIxXzIwMjJfYXR0ZW5kYW5jZV9yYXRlX3llYXJfdG9fZGF0ZSkgJiB4MjAyMV8yMDIyX2F0dGVuZGFuY2VfcmF0ZV95ZWFyX3RvX2RhdGUgPD0gcXVhbnRpbGUoeDIwMjFfMjAyMl9hdHRlbmRhbmNlX3JhdGVfeWVhcl90b19kYXRlLCAwLjc1KSArIDEuNSAqIElRUih4MjAyMV8yMDIyX2F0dGVuZGFuY2VfcmF0ZV95ZWFyX3RvX2RhdGUpKQ0KDQplc2NvbGFfc2VtX291dGxpZXJzDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIyMgKioqTWFuaXB1bGFjw6fDo28gZGUgRGFkb3MqKioNCg0KIyMjIyMgKioqU2VsZWPDp8OjbyBkZSB2YXJpw6F2ZWlzIHBhcmEgYSBBbsOhbGlzZSoqKg0KDQpgYGB7cn0NCmVzY29sYV9zZWwgPC0gZXNjb2xhX3NlbV9vdXRsaWVycyB8PiANCiAgc2VsZWN0KGRpc3RyaWN0X25hbWUsIGNhdGVnb3J5LCBzdHVkZW50X2dyb3VwLCB4MjAyMV8yMDIyX3N0dWRlbnRfY291bnRfeWVhcl90b19kYXRlLCB4MjAyMV8yMDIyX2F0dGVuZGFuY2VfcmF0ZV95ZWFyX3RvX2RhdGUsIHgyMDIxXzIwMjJfYXR0ZW5kYW5jZV9yYXRlX3llYXJfdG9fZGF0ZSkNCg0KaGVhZChlc2NvbGFfc2VsKQ0KYGBgDQoNCiMjIyMjICoqKkFsdGVyYXIgbm9tZXMgZGUgdmFyaWF2ZWlzKioqDQoNCmBgYHtyfQ0KZXNjb2xhX2xpbXBhIDwtIGVzY29sYV9zZWwgfD4gDQogIGRwbHlyOjpyZW5hbWUobm9tZV9kaXN0cml0bz1kaXN0cmljdF9uYW1lLCANCiAgICAgICAgICAgICAgIGNhdGVnb3JpYSA9Y2F0ZWdvcnksDQogICAgICAgICAgICAgICBncnVwb19lc3R1ZGFudGUgPSBzdHVkZW50X2dyb3VwLA0KICAgICAgICAgICAgY29udGFnZW1fYW51YWxfZXN0dWRhbnRlcz14MjAyMV8yMDIyX3N0dWRlbnRfY291bnRfeWVhcl90b19kYXRlLA0KICAgICAgICAgICAgICB0YXhhX2Fzc2lkdWlkYWRlPXgyMDIxXzIwMjJfYXR0ZW5kYW5jZV9yYXRlX3llYXJfdG9fZGF0ZSkNCg0KaGVhZChlc2NvbGFfbGltcGEpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjICoqKlZpc3VhbGl6YcOnw6NvIGRlIERhZG9zKioqDQoNCiMjIyAqKipIaXN0b2dyYW0qKioNCg0KYGBge3J9DQpoaXN0X29yaWdpbmFsIDwtIGdncGxvdChlc2NvbGFfbGltcGEsIGFlcyh4ID0gdGF4YV9hc3NpZHVpZGFkZSkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDIwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAic2t5Ymx1ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArIGdndGl0bGUoIkRpc3RyaWJ1acOnw6NvIGRhIHRheGEgZGUgYXNzZWR1aWRhZGUiKQ0KaGlzdF9vcmlnaW5hbA0KYGBgDQoNClVtIGhpc3RvZ3JhbWEgw6kgdW0gZ3LDoWZpY28gZGUgYmFycmFzIHVzYWRvIHBhcmEgcmVwcmVzZW50YXIgYSBkaXN0cmlidWnDp8OjbyBkZSB1bWEgdmFyacOhdmVsIHF1YW50aXRhdGl2YS4gRWxlIG1vc3RyYSBhIGZyZXF1w6puY2lhIGRlIHZhbG9yZXMgZGVudHJvIGRlIGludGVydmFsb3MgZGUgdmFsb3JlcywgY2hhbWFkb3MgZGUg4oCcYmluc+KAnSBvdSDigJxjbGFzc2Vz4oCdLiBDYWRhIGJhcnJhIG5vIGhpc3RvZ3JhbWEgcmVwcmVzZW50YSBhIGZyZXF1w6puY2lhIChvdSBjb250YWdlbSkgZGUgb2JzZXJ2YcOnw7VlcyBxdWUgY2FlbSBkZW50cm8gZGUgdW0gZGV0ZXJtaW5hZG8gaW50ZXJ2YWxvLg0KDQojIyMgKioqQm94cGxvdCoqKg0KDQpgYGB7cn0NCiMgQ3JpYXIgbyBib3hwbG90IGNvbSBnZ3Bsb3QyDQpnZ3Bsb3QoZXNjb2xhX2xpbXBhLCBhZXMoeSA9IHRheGFfYXNzaWR1aWRhZGUpKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IGRhIFRheGEgZGUgQXNzaWR1aWRhZGUiLCB5ID0gIlRheGEgZGUgQXNzaWR1aWRhZGUiKQ0KYGBgDQoNCkZvaSBwb3NzaXZlbCBlbmNvbnRyYXIgb3V0bGllcnMgbmVzc2UgYm94cGxvdCwgcG9yIGlzc28gdGVyZWkgZGUgb3MgcmVtb3ZlLWxvcyBub3ZhbWVudGUuDQoNCiMjIyMgKioqUmVtb8Onw6NvIGRlIG91dGxpZXJzIHVzYW5kbyBvIG1ldG9kbyBkZSBjYWxjdWxvcyBkZSBsaW1pdGVzIGRvcyBiaWdvZGVzKioqDQoNCmBgYHtyfQ0KIyBDYWxjdWxhciBvcyBsaW1pdGVzIGRvcyBiaWdvZGVzDQpRMSA8LSBxdWFudGlsZShlc2NvbGFfbGltcGEkdGF4YV9hc3NpZHVpZGFkZSwgMC4yNSkNClEzIDwtIHF1YW50aWxlKGVzY29sYV9saW1wYSR0YXhhX2Fzc2lkdWlkYWRlLCAwLjc1KQ0KSVFSIDwtIFEzIC0gUTENCmxpbWl0ZV9pbmZlcmlvciA8LSBRMSAtIDEuNSAqIElRUg0KbGltaXRlX3N1cGVyaW9yIDwtIFEzICsgMS41ICogSVFSDQoNCiMgUmVtb3ZlciBvdXRsaWVycw0KZXNjb2xhX3NlbV9vdXRsaWVycyA8LSBlc2NvbGFfbGltcGFbZXNjb2xhX2xpbXBhJHRheGFfYXNzaWR1aWRhZGUgPj0gbGltaXRlX2luZmVyaW9yICYgZXNjb2xhX2xpbXBhJHRheGFfYXNzaWR1aWRhZGUgPD0gbGltaXRlX3N1cGVyaW9yLCBdDQplc2NvbGFfc2VtX291dGxpZXJzDQpgYGANCg0KIyMjIyAqKipOb3ZvIEJveHBsb3QqKioNCg0KYGBge3J9DQojIENyaWFyIG8gYm94cGxvdCBjb20gZ2dwbG90Mg0KZ2dwbG90KGVzY29sYV9zZW1fb3V0bGllcnMNCiwgYWVzKHkgPSB0YXhhX2Fzc2lkdWlkYWRlKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICJza3libHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQm94cGxvdCBkYSBUYXhhIGRlIEFzc2lkdWlkYWRlIiwgeSA9ICJUYXhhIGRlIEFzc2lkdWlkYWRlIikNCmBgYA0KDQojIyMjICoqKk5vdm8gSGlzdG9ncmFtKioqDQoNCmBgYHtyfQ0Kc2VndW5kb19oaXN0IDwtIGdncGxvdChlc2NvbGFfc2VtX291dGxpZXJzLCBhZXMoeCA9IHRheGFfYXNzaWR1aWRhZGUpKSArIGdlb21faGlzdG9ncmFtKGJpbnMgPSAyMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsID0gInNreWJsdWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikgKyBnZ3RpdGxlKCJEaXN0cmlidWnDp8OjbyBkYSB0YXhhIGRlIGFzc2VkdWlkYWRlIikNCnNlZ3VuZG9faGlzdA0KYGBgDQoNCiMjIyMgR3LDoWZpY28gUS1RIG5vcm1hbA0KDQpgYGB7cn0NCiMgQ3JpYXIgbyBncsOhZmljbyBRLVEgbm9ybWFsDQpnZ3Bsb3QoZXNjb2xhX3NlbV9vdXRsaWVycywgYWVzKHNhbXBsZSA9IHRheGFfYXNzaWR1aWRhZGUpKSArDQogIGdlb21fcXEoKSArDQogIGdlb21fcXFfbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJHcsOhZmljbyBRLVEgTm9ybWFsIiwNCiAgICAgICB4ID0gIlF1YW50aXMgdGXDs3JpY29zIGRhIGRpc3RyaWJ1acOnw6NvIG5vcm1hbCIsDQogICAgICAgeSA9ICJRdWFudGlzIG9ic2VydmFkb3MgZGEgdmFyacOhdmVsIikNCg0KYGBgDQoNCiMjIyMgKioqR3LDoWZpY28gZGUgZGVuc2lkYWRlKioqDQoNCmBgYHtyfQ0KIyBDcmlhciBvIGdyw6FmaWNvIGRlIGRlbnNpZGFkZSBRLVENCmdncGxvdChlc2NvbGFfc2VtX291dGxpZXJzLCBhZXMoc2FtcGxlID0gdGF4YV9hc3NpZHVpZGFkZSkpICsNCiAgc3RhdF9xcShjb2xvciA9ICJyZWQiKSArDQogIGdlb21fYWJsaW5lKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCwgY29sb3IgPSAiZ3JlZW4iKSArDQogIGxhYnModGl0bGUgPSAiR3LDoWZpY28gZGUgRGVuc2lkYWRlIFEtUSIsDQogICAgICAgeCA9ICJRdWFudGlzIHRlw7NyaWNvcyBkYSBkaXN0cmlidWnDp8OjbyBub3JtYWwiLA0KICAgICAgIHkgPSAiUXVhbnRpcyBvYnNlcnZhZG9zIGRhIHZhcmnDoXZlbCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjICoqKkV4cGxvcmHDp8OjbyBkZSBEYWRvcyoqKg0KDQojIyMgKioqUmVzdW1vIEVzdGF0w610aXN0aWNvKioqDQoNCmBgYHtyfQ0KcmVzdW1vX2VzdGF0aXN0aWNvIDwtIGVzY29sYV9zZW1fb3V0bGllcnMgfD4gDQogIHN1bW1hcnl0b29sczo6ZGVzY3IoKSB8PiANCiAgYmFzZTo6ZGF0YS5mcmFtZSgpDQpyZXN1bW9fZXN0YXRpc3RpY28NCmBgYA0KDQojIyMgKioqQWdyZWdhw6fDo28qKioNCg0KIyMjIyAqKipBZ3JlZ2HDp8OjbyBwb3IgRGlzdHJpdG8qKioNCg0KYGBge3J9DQojQWdyZWdhY2FvIHBvciBEaXN0cml0bw0KYWdyZWdhZG9fZXNjb2xhX2Rpc3RyaXRvIDwtIGVzY29sYV9zZW1fb3V0bGllcnMgfD4gDQogIGdyb3VwX2J5KG5vbWVfZGlzdHJpdG8pIHw+IA0KICBzdW1tYXJpc2UobWVkaWFfZGlzdHJpdG8gPSBtZWFuKHRheGFfYXNzaWR1aWRhZGUpKQ0KYWdyZWdhZG9fZXNjb2xhX2Rpc3RyaXRvDQpgYGANCg0KIyMjIyAqKipWaXN1YWxpemFjYW8gZG8gYWdyZWdhZG8gcG9yIGRpc3RyaXRvKioqDQoNCmBgYHtyfQ0KIyBDcmlhciBvIGdyw6FmaWNvIGRlIGJhcnJhcyBob3Jpem9udGFsIGNvbSBjb3Jlcw0KZ2dwbG90KGFncmVnYWRvX2VzY29sYV9kaXN0cml0bywgYWVzKHggPSBtZWRpYV9kaXN0cml0bywgeSA9IG5vbWVfZGlzdHJpdG8sIGZpbGwgPSBub21lX2Rpc3RyaXRvKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIpICsgICMgQXBsaWNhciBhcyBjb3JlcyBtYW51YWxtZW50ZQ0KICBsYWJzKHRpdGxlID0gIkFzc2VkdWlkYWRlIGRvcyBlc3R1ZGFudGVzIiwNCiAgICAgICB4ID0gIlRvdGFsIGRlIEVzdHVkYW50ZXMiLA0KICAgICAgIHkgPSAiQ2F0ZWdvcmlhIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQojIyMjICoqKkFncmVnYcOnw6NvIHBvciBDYXRlZ29yaWEqKioNCg0KYGBge3J9DQojQWdyZWdhY2FvIC0gTWVkaWEgZGUgdGF4YSBkZSBhc3NlZHVpZGFkZSBwb3IgY2F0ZWdvcmlhDQphZ3JlZ2Fkb19lc2NvbGFfY2F0ZWdvcmlhIDwtIGVzY29sYV9saW1wYSB8PiANCiAgZ3JvdXBfYnkoY2F0ZWdvcmlhKSB8PiANCiAgc3VtbWFyaXNlKG1lZGlhX2NhdGVnb3JpYSA9IG1lYW4odGF4YV9hc3NpZHVpZGFkZSkpDQphZ3JlZ2Fkb19lc2NvbGFfY2F0ZWdvcmlhDQpgYGANCg0KIyMjICoqKlZpc3VhbGl6YWNhbyBkZSBhZ3JlZ2FkbyBwb3IgY2F0ZWdvcmlhKioqDQoNCiMjIyMgKioqR3JhZmljbyBkZSBiYXJyYXMgSG9yaXpvbnRhbCoqKg0KDQpgYGB7cn0NCiMgQ3JpYXIgbyBncsOhZmljbyBkZSBiYXJyYXMgaG9yaXpvbnRhbCBjb20gY29yZXMNCmdncGxvdChhZ3JlZ2Fkb19lc2NvbGFfY2F0ZWdvcmlhICwgYWVzKHggPSBtZWRpYV9jYXRlZ29yaWEsIHkgPSBjYXRlZ29yaWEsIGZpbGwgPSBjYXRlZ29yaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKG9wdGlvbiA9ICJEIikgKyAgIyBBcGxpY2FyIGFzIGNvcmVzIG1hbnVhbG1lbnRlDQogIGxhYnModGl0bGUgPSAiQXNzaWR1aWRhZGUgZG9zIGVzdHVkYW50ZXMiLA0KICAgICAgIHggPSAiTWVkaWEgZGUgQXNzaWR1aWRhZGUiLA0KICAgICAgIHkgPSAiQ2F0ZWdvcmlhIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpHcmFmaWNvIFBpenphDQoNCmBgYHtyfQ0KIyBHcsOhZmljbyBkZSBzZXRvcmVzDQpnZ3Bsb3QoYWdyZWdhZG9fZXNjb2xhX2NhdGVnb3JpYSwgYWVzKHggPSAiIiwgeSA9IG1lZGlhX2NhdGVnb3JpYSwgZmlsbCA9IGNhdGVnb3JpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMSkgKw0KICBjb29yZF9wb2xhcigieSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIkQiKSArDQogIGxhYnModGl0bGUgPSAiQXNzaWR1aWRhZGUgZG9zIGVzdHVkYW50ZXMiLA0KICAgICAgIGZpbGwgPSAiQ2F0ZWdvcmlhIiwNCiAgICAgICB4ID0gTlVMTCwNCiAgICAgICB5ID0gTlVMTCkgKw0KICB0aGVtZV92b2lkKCkNCmBgYA0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgKioqQW5hbGlkZSBFc3RhdMOtc3RpY2EqKioNCg0KVXRpbGl6YXJlaSBtw6l0b2RvcyBlc3RhdMOtc3RpY29zLCBjb21vIEFOT1ZBLCByZWdyZXNzw6NvIGxpbmVhciBvdSByZWdyZXNzw6NvIGxvZ8Otc3RpY2EsIHBhcmEgYXZhbGlhciBhIHJlbGHDp8OjbyBlbnRyZSBhcyBjYXRlZ29yaWFzIGUgYSB0YXhhIGRlIGFzc2lkdWlkYWRlLg0KDQoqKkFOT1ZBKioNCg0KKipQcmVzc3Vwb3N0b3MgZGEgQU5PVkEqKg0KDQoqKkFuYWxpc2UgZGUgTm9ybWFsaWRhZGUqKg0KDQoxLiAgKlRleHRlIGRlIFNoYXBpcm8gV2lsayoNCg0KLSAgICoqKkhpcMOzdGVzZSBudWxhIChIMCk6KioqIE9zIGRhZG9zIHNlZ3VlbSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiAoUC12YWx1ZSDiiaUgMC41KQ0KDQotICAgKioqSGlww7N0ZXNlIGFsdGVybmF0aXZhIChIMSkqKioqKjoqKiBPcyBkYWRvcyBuw6NvIHNlZ3VlbSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiAoUC12YWx1ZSBcPCAwLjUpDQoNCmBgYHtyfQ0KIyBUZXN0ZSBkZSBTaGFwaXJvIFdpbGsNCnNoYXBpcm9fYXNzZWR1aWRhZGUgPC0gc3RhdHM6OnNoYXBpcm8udGVzdChlc2NvbGFfc2VtX291dGxpZXJzJHRheGFfYXNzaWR1aWRhZGUpDQpzaGFwaXJvX2Fzc2VkdWlkYWRlDQpgYGANCg0KTyB0ZXN0ZSBkZSBub3JtYWxpZGFkZSBkZSBTaGFwaXJvLVdpbGsgcGFyYSBhIHZhcmnDoXZlbCAqKmB0YXhhX2Fzc2lkdWlkYWRlYCoqIHJlc3VsdG91IGVtIHVtIHZhbG9yIGRlIGVzdGF0w61zdGljYSBkZSB0ZXN0ZSAoVykgZGUgYXByb3hpbWFkYW1lbnRlIDAuODg2IGUgdW0gdmFsb3IgcCBtdWl0byBwZXF1ZW5vIChtZW5vciBxdWUgMi4yZS0xNikuIElzc28gaW5kaWNhIHF1ZSBow6EgZXZpZMOqbmNpYXMgZXN0YXRpc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhcyBwYXJhIHJlamVpdGFyIGEgaGlww7N0ZXNlIG51bGEgZGUgcXVlIG9zIGRhZG9zIHNlZ3VlbSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiBPdSBzZWphLCBhICoqYHRheGFfYXNzaWR1aWRhZGVgKiogbsOjbyBzZWd1ZSB1bWEgZGlzdHJpYnVpw6fDo28gbm9ybWFsLiBMb2dvIG7Do28gc2UgcG9kZSBmYXplciBBbsOhbGlzZSBkZSBWYXJpYcOnYSBjb20gYW1vc3RyYXMgcXVlIG7Do28gc2VndWVtIHVtYSBkaXN0cmlidcOtw6fDo28gbm9ybWFsLCB1bWEgZGFzIHBvc3NpdmVpcyBzb2x1w6fDtWVzIMOpIHJlYWxpemFyIGEgdHJhbnNmb3JtYcOnw6NvIGRvcyBkYWRvcw0KDQoqKipUcmFuc2Zvcm1hY2FvIGxvZ2FyaXRpbWljYSBwYXJhIG5vcm1hbGl6YXIgYSBkaXN0cmlidWljYW8gZG9zIGRhZG9zKioqDQoNCmBgYHtyfQ0KYXNzZWR1aWRhZGVfbG9nIDwtIHNxcnQoZXNjb2xhX3NlbV9vdXRsaWVycyR0YXhhX2Fzc2lkdWlkYWRlKQ0KYXNzZWR1aWRhZGVfdHJhbnNmIDwtIGRhdGEuZnJhbWUoZXNjb2xhX3NlbV9vdXRsaWVycyRjYXRlZ29yaWEsIGFzc2VkdWlkYWRlX2xvZykNCmhlYWQoYXNzZWR1aWRhZGVfdHJhbnNmKQ0KYGBgDQoNCiMgKioqQ09OVElOVUHigKYqKioNCg==