1. Apresentação

Este relatório estima a demanda habitacional potencial no Distrito Federal a partir da PDAD, utilizando expansão amostral com desenho complexo (estratos, conglomerados e pesos). As estimativas são apresentadas com medidas de incerteza (erro-padrão, IC e CV) e publicadas somente quando o CV ≤ 25%. Os microdados são padronizados (nomes, tipos e rótulos), harmonizamos códigos de RA/PMB/Área Rural e derivamos variáveis de interesse (idade, condição no domicílio, grupos etários, indicadores de demanda). Regras de qualidade verificam chaves (domicílio/pessoa), duplicidades e coerência do desenho amostral. Estimamos: (i) taxa de chefia por faixa etária e grupo territorial; (ii) quantidade de adultos potencialmente demandantes (24–64 anos, não responsáveis nem cônjuges, sob regras familiares); e (iii) demanda final como produto da demanda potencial pela taxa de chefia da respectiva faixa.

Resultados são estratificados por grupo territorial (DF, PMB, Área Rural) e, quando a precisão permite, por Região Administrativa (RA) e faixas etárias (24–29, 30–39, 40–64). Células com CV alto são suprimidas (NA) e, se necessário, agregadas.

2. Preparação do Ambiente

2.1 — CARREGAMENTO DE PACOTES E CONFIGURAÇÃO DO AMBIENTE

Este bloco prepara o ambiente de execução, garantindo:

  • instalação e carregamento dos pacotes necessários;
  • definição de parâmetros do projeto (ano, caminhos, limites de CV);
  • padronização de opções globais de exibição e arredondamento.


if (!requireNamespace("pacman", quietly = TRUE)) install.packages("pacman")

# Carrega os principais pacotes utilizados no relatório.

# A função pacman::p_load() instala automaticamente o pacote caso não esteja presente.

pacman::p_load(tidyverse,    # Manipulação e visualização de dados
               data.table,   # Leitura e operações eficientes com grandes bases
               janitor,      # Padronização de nomes e limpeza de tabelas
               stringr,      # Manipulação de strings (texto)
               lubridate,    # Manipulação de datas
               survey,       # Desenho e análise de dados amostrais complexos
               srvyr,        # Interface tidy para o pacote survey
               gt,           # Geração de tabelas formatadas
               scales,       # Escalas numéricas e rotulagem para gráficos
               readr,        # Leitura de arquivos CSV
               readxl,       # Leitura de planilhas Excel
               glue          # Construção dinâmica de textos e expressões
)

Define opções globais do R Markdown:



options(
scipen = 999,
dplyr.summarise.inform = FALSE
)

2.2 — DEFINIÇÃO DE PARÂMETROS GLOBAIS DO RELATÓRIO

Aqui definimos todos os parâmetros que controlam a execução:

  • caminhos de arquivos (dados e dicionários);

  • parâmetros amostrais (CV máximo permitido);

  • faixas etárias e ano de referência.

Estes parâmetros podem ser alterados sem mexer no corpo do relatório.



params <- list(
salariominimo = 1302,                  # Salário mínimo vigente
ano_pdad   = 2025,                      # Ano de referência da pesquisa
arquivo_pdad = "/data/pdad2024out.csv",    # Caminho do arquivo principal da PDAD
dic_dom    = "/data/dicionario_dom.csv", # Caminho do dicionário de domicílios
dic_mor    = "/data/dicionario_mor.csv", # Caminho do dicionário de moradores
cv_max     = 0.25                      # Coeficiente de variação máximo aceito (25%)
)
salariominimo<-1302

2.3 — CRIAÇÃO DE DIRETÓRIOS (OPCIONAL)

Este trecho cria automaticamente as pastas onde os dados e saídas do relatório serão armazenados, evitando erros de caminho inexistente.



#if (!dir.exists("data")) dir.create("data")
#if (!dir.exists("output")) dir.create("output")

2.4 — VERIFICAÇÃO INICIAL DO AMBIENTE

Verifica se os pacotes essenciais estão carregados e imprime uma mensagem de confirmação no console.

pacotes_essenciais <- c("tidyverse", "survey", "srvyr", "gt")
pacotes_faltando <- pacotes_essenciais[!sapply(pacotes_essenciais, requireNamespace, quietly = TRUE)]

2.5 — IMPORTAÇÃO DOS DADOS

Este bloco realiza a leitura dos microdados da PDAD e dos dicionários de domicílios e moradores, aplicando limpeza básica (nomes consistentes).

Leitura dos dicionários (estrutura das variáveis)

dic_dom <- readr::read_csv(params$dic_dom, show_col_types = FALSE) |>janitor::clean_names()
dic_mor <- readr::read_csv(params$dic_mor, show_col_types = FALSE) |>janitor::clean_names()
pdad2023 <- readr::read_csv(params$arquivo_pdad, show_col_types = FALSE) |>janitor::clean_names()#Leitura dos microdados da PDAD
New names:
• `` -> `...1`
Aviso: One or more parsing issues, call `problems()` on your data frame for details, e.g.:
  dat <- vroom(...)
  problems(dat)

3. Preparação dos Dados: Criação de Variáveis Derivadas

Este bloco tem por objetivo preparar e ajustar os microdados da PDAD para o cálculo da demanda habitacional com base na taxa de chefia tradicional, isto é, considerando todos os chefes de domicílio da faixa etária de 24 a 64 anos. As etapas incluem a harmonização das bases de moradores e domicílios, a criação de variáveis derivadas e a identificação dos arranjos familiares que configuram ou não demanda habitacional.

3.1 — Ajustes de Identificação e Criação de Variáveis de Contexto

Este bloco harmoniza variáveis básicas da PDAD, como UF, RA e códigos de domicílio, para permitir a classificação territorial e familiar dos registros.

pdad2023$UF[pdad2023$a01uf==52]<-"PMB"
Aviso: Unknown or uninitialised column: `UF`.
pdad2023$UF[pdad2023$a01uf==53]<-"DF"
pdad2023$UF |> table()

   DF   PMB 
50643 18899 

Inclusão de descrições de localidade a partir do dicionário de domicílios

#dic_dom |> filter(str_detect(coluna,"loca"))
pdad2023 |>
left_join(dic_dom |> filter(coluna=="localidade") |> mutate(strata_localidade=desc_valor) |> select(-coluna,-desc_coluna,-desc_valor),by=c("localidade"="valor"))->pdad2023

Criação e padronização de variáveis derivadas

pdad2023$idade<-pdad2023$idade_calculada
pdad2023$A01nficha<-pdad2023$ficha
pdad2023$RA_nome<-pdad2023$strata_localidade
pdad2023<-pdad2023 %>% mutate(grupo_pdadA=case_when(RA_nome=="Área Rural"~"Área Rural",
                                                    UF=="DF"~"DF",TRUE~UF))

contagem de pessoas no domicílio (A01npessoas)

pdad2023 %>% select(ficha,morador_id) %>%
  mutate(n_morador=as.numeric(str_remove(morador_id,paste0(ficha,"-")))) %>%
  group_by(ficha) %>%summarise(A01npessoas=max(n_morador)) %>%
  right_join(pdad2023,by=c("ficha") )->pdad2023

3.3 — Filtragem da População de Interesse

Nesta etapa, restringe-se a base apenas aos domicílios cujo responsável tem entre 24 e 64 anos, faixa considerada economicamente ativa e foco da análise da demanda habitacional.

Deixar apenas os domicílios/moradores onde o responsável tem entre 24 e 64 anos.

pdad2023_original <- pdad2023
pdad2023 <-subset(pdad2023,ficha %in% subset(pdad2023, e04 == 1 & idade_calculada %in% c(24:64))$ficha)

Caso deseja-se ignorar essa regra ordar essa alternativa:

#pdad2023_original <- pdad2023

3.4 — Identificação dos Domicílios com Demanda Habitacional

Nesta subseção inicia-se a identificação dos arranjos familiares, a partir da criação da variável matriz_familiar, que agrupa informações por tipo de membro (responsável, cônjuge, filho, etc.).

matriz_familiar <- pdad2023 %>% 
  # select(A01nficha, A01npessoas, e04, idade) %>% 
  mutate(condicao = 1, 
         e04_edit = case_when(e04 == 1 ~ 'responsavel', 
                              e04 == 2 ~ 'conjuge', 
                              e04 == 3 ~ 'conjuge', 
                              e04 == 4 & idade < 24 ~ 'filho_menor24', 
                              e04 == 5 & idade < 24 ~ 'filho_menor24',
                              e04 == 6 & idade < 24 ~ 'filho_menor24' , 
                              e04 == 4 & idade >=24 ~ 'filho_maior24', 
                              e04 == 5 & idade >=24 ~ 'filho_maior24',
                              e04 == 6 & idade >=24 ~ 'filho_maior24', 
                              e04 == 7 ~ 'genro_nora', 
                              e04 == 8 ~ 'pais', 
                              e04 == 9 ~ 'sogros', 
                              e04 == 10 ~ 'neto', 
                              e04 == 11 ~ 'bisneto', 
                              e04 == 12 ~ 'irmao', 
                              e04 == 13 ~ 'avos',
                              e04 == 14 ~ 'outro_parente', 
                              e04 == 15 ~ 'agregado',
                              e04 == 16 ~ 'convivente', 
                              e04 == 17 ~ 'pensionista',
                              e04 == 18 ~ 'empregado_domestico', 
                              e04 == 19 ~ 'parente_empregado')) %>% 
  group_by(A01nficha, A01npessoas,
           e04_edit) %>% 
  summarise(n = sum(condicao)) %>%  
  spread(e04_edit, n)

3.5 — Inclusão de Indicadores de Idosos e Adultos

Nesta fase são criadas variáveis auxiliares que indicam:

  • presença de idosos (65+) no domicílio;
  • presença de adultos (24–64);
  • e se estes são responsáveis ou cônjuges.

Essas variáveis são cruciais para determinar quando o domicílio gera ou não demanda.

Criar variável indicadora de idoso no domicílio

pdad2023$idoso <- ifelse(pdad2023$idade >= 65, 1, 0)

matriz_idosos <-
  as.data.frame(table(pdad2023$A01nficha, pdad2023$idoso))

pdad2023$idoso <- NULL

matriz_idosos$idosos <-
  as.numeric(levels(matriz_idosos$Var2))[matriz_idosos$Var2] * matriz_idosos$Freq

names(matriz_idosos)[1] <- "A01nficha"

matriz_idosos <- subset(matriz_idosos, idosos > 0)

matriz_familiar <-
  merge(matriz_familiar,
        matriz_idosos,
        by = "A01nficha",
        all.x = TRUE)

#rm(matriz_idosos)

Indicadora se o idoso é responsável ou cônjuge

matriz_familiar$idoso_conj <-
  ifelse(
    matriz_familiar$A01nficha %in% subset(pdad2023, e04 %in% c(2, 3) &
                                            idade >= 65)$A01nficha,
    1,
    0
  )

Criação de variável indicadora de adulto (24–64 anos)

pdad2023$adulto <-
  ifelse(pdad2023$idade >= 24 & pdad2023$idade < 65, 1, 0)

matriz_adulto <-
  as.data.frame(table(pdad2023$A01nficha, pdad2023$adulto))

pdad2023$adulto <- NULL

matriz_adulto$adulto <-
  as.numeric(levels(matriz_adulto$Var2))[matriz_adulto$Var2] * matriz_adulto$Freq

names(matriz_adulto)[1] <- "A01nficha"

matriz_adulto <- subset(matriz_adulto, adulto > 0)

matriz_familiar <-
  merge(matriz_familiar,
        matriz_adulto,
        by = "A01nficha",
        all.x = TRUE)

#rm(matriz_adulto)

Identificação de adultos responsáveis e cônjuges

matriz_familiar$adulto_resp <-
  ifelse(
    matriz_familiar$A01nficha %in% subset(pdad2023, e04 == 1 &
                                            idade >= 24 & idade < 65)$A01nficha,
    1,
    0
  )
matriz_familiar %>% group_by(adulto_resp) %>% summarise(n=n()) ### todos os domicilios tem adultos como responsaveis pelo domicilio
matriz_familiar$adulto_conj <-
  ifelse(
    matriz_familiar$A01nficha %in% subset(pdad2023, e04 %in% c(2, 3) &
                                            idade >= 24 & idade < 65)$A01nficha,
    1,
    0
  )

#matriz_familiar %>% group_by(adulto_conj) %>% summarise(n=n()) ### todos os domicilios tem adultos como responsaveis pelo domicilio

3.6 — Cálculo da Demanda Habitacional no Domicílio

Aqui são aplicadas as regras que determinam se o domicílio gera demanda:

não há demanda quando o domicílio contém apenas o responsável, cônjuge, filhos menores e idosos;

há demanda quando existem adultos adicionais (24–64 anos) que não são responsáveis nem cônjuges.

Identificação de domicílios sem demanda

# filhos menores de 24 anos e idosos.
matriz_familiar$demanda <- NA
matriz_familiar$demanda <-
  ifelse(((
    rowSums(matriz_familiar[, c("responsavel", "conjuge", "filho_menor24", "idosos")], na.rm =TRUE) 
    - (matriz_familiar[, c("idoso_conj")])
  ) == matriz_familiar$A01npessoas) == TRUE,
  0,
  matriz_familiar$demanda)

matriz_familiar$demanda %>% table()
.
    0 
14211 

Número de pessoas no domicílio que demandam habitação - i.e tem pessoas entre 24 e 64 anos que não são responsáveis ou cônjuges.

matriz_familiar$demanda <-
  ifelse((matriz_familiar$A01npessoas - (
    rowSums(matriz_familiar[, c("responsavel", "conjuge", "filho_menor24", "idosos")], na.rm =
              TRUE) - (matriz_familiar[, c("idoso_conj")])
  )) > 0,
  (
    matriz_familiar$adulto - rowSums(matriz_familiar[, c("adulto_resp", "adulto_conj")], na.rm =
                                       TRUE)
  ),
  matriz_familiar$demanda
  )

3.7 — Identificação de Casais Específicos

Este bloco refina os casos de casais especiais (pais, avós, sogros, genros/noras e filhos adultos), que demandam regras diferenciadas na identificação de chefes e cônjuges. O objetivo é evitar dupla contagem de demanda ou imputação indevida.

Casais de avós, pais e sogros

matriz_familiar$casal_avos <- ifelse(matriz_familiar$avos == 2, 1, NA)
matriz_familiar$casal_pais <- ifelse(matriz_familiar$pais == 2, 1, NA)
matriz_familiar$casal_sogros <- ifelse(matriz_familiar$sogros == 2, 1, NA)

3.8 — Identificação e Classificação dos Casais

Nesta etapa, identificam-se diferentes tipos de casais presentes nos domicílios (avós, sogros, pais e filhos / genros / noras). O objetivo é determinar corretamente quem é o chefe do casal e seu cônjuge, evitando dupla contagem ou atribuição incorreta de demanda.

A indicação da existência de casal de filhos é a própria variável de genro/nora. Faz-se para cada tipo de casal separado porque pode haver mais de um tipo de casal por domicílio. Separa-se os indivíduos de cada casal para calcular a idade máxima (utilizada para identificar o chefe).

idade_casal_avos <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, casal_avos == 1 &
                            demanda > 0)$A01nficha) %>%
  subset(e04 == 13)

idade_casal_sogros <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, casal_sogros == 1 &
                            demanda > 0)$A01nficha) %>%
  subset(e04 == 9)

idade_casal_pais <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, casal_pais == 1 &
                            demanda > 0)$A01nficha) %>%
  subset(e04 == 8)

3.9 — Determinação do Chefe do Casal por Tipo de Parentesco

Aqui calcula-se a idade do cônjuge mais velho para identificar o chefe de cada casal. A regra define o chefe como o indivíduo mais velho do par; em caso de empate, usa-se o menor identificador (morador_id) como critério secundário.

idade_casal_avos2 <- idade_casal_avos %>%
  group_by(A01nficha) %>%
  summarise(chefe_idade = max(idade))

idade_casal_avos <-
  merge(idade_casal_avos,
        idade_casal_avos2,
        by = "A01nficha",
        all.x = TRUE)

idade_casal_avos <- idade_casal_avos %>%
  group_by(A01nficha) %>%
  mutate(chefe_id = ifelse(sum(idade) / 2 == chefe_idade,min(morador_id),ifelse(idade == chefe_idade, morador_id, 0))) %>%
  mutate(chefe_casal = ifelse(morador_id == chefe_id, 1, 0)) %>%
  mutate(conj_casal = ifelse(morador_id != chefe_id, 1, 0))
#rm(idade_casal_avos2)

idade_casal_sogros2 <- idade_casal_sogros %>% 
  group_by(A01nficha) %>% 
  summarise(chefe_idade = max(idade))

idade_casal_sogros <-
  merge(idade_casal_sogros,
        idade_casal_sogros2,
        by = "A01nficha",
        all.x = TRUE)

idade_casal_sogros <- idade_casal_sogros %>%
  group_by(A01nficha) %>%
  mutate(chefe_id = ifelse(sum(idade) / 2 == chefe_idade,min(morador_id),ifelse(idade == chefe_idade, morador_id, 0))) %>%
  mutate(chefe_casal = ifelse(morador_id == chefe_id, 1, 0)) %>%
  mutate(conj_casal = ifelse(morador_id != chefe_id, 1, 0))
#rm(idade_casal_sogros2)

idade_casal_pais2 <- idade_casal_pais %>%
  group_by(A01nficha) %>%
  summarise(chefe_idade = max(idade))

idade_casal_pais <-
  merge(idade_casal_pais,
        idade_casal_pais2,
        by = "A01nficha",
        all.x = TRUE)

idade_casal_pais <- idade_casal_pais %>%
  group_by(A01nficha) %>%
  mutate(chefe_id = ifelse(sum(idade) / 2 == chefe_idade,min(morador_id),ifelse(idade == chefe_idade, morador_id, 0))) %>%
  mutate(chefe_casal = ifelse(morador_id == chefe_id, 1, 0)) %>%
  mutate(conj_casal = ifelse(morador_id != chefe_id, 1, 0))
#rm(idade_casal_pais2)

3.10 — Casais Formados por Filhos, Genros ou Noras

As próximas etapas lidam com arranjos em que filhos adultos e genros/noras compõem novos núcleos familiares dentro do domicílio. Cada caso é tratado separadamente, conforme a quantidade de filhos adultos e o tipo de vínculo.

# CASO 1 — Genro/nora com apenas um(a) filho(a) adulto(a) (≥24 anos)

idade_casal_filhos01 <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, genro_nora == 1 & filho_maior24 == 1, demanda > 0)$A01nficha) %>%
  subset(e04 == 7 | (e04 %in% c(4:6) & idade >= 24)) # Mantém apenas registros do genro/nora (e04==7) e dos filhos adultos (e04 4:6, idade≥24)
# Calcula a idade máxima dentro de cada domicílio para identificar o chefe do casal
idade_casal_filhos01b <- idade_casal_filhos01 %>% 
  group_by(A01nficha) %>% summarise(chefe_idade = max(idade))
# Junta o valor da idade máxima de volta à base principal
idade_casal_filhos01 <-
  merge(idade_casal_filhos01,
        idade_casal_filhos01b,
        by = "A01nficha",
        all.x = TRUE)
# Define o chefe do casal (o mais velho) e o cônjuge (o outro indivíduo)
idade_casal_filhos01 <- idade_casal_filhos01 %>%
  group_by(A01nficha) %>% 
  mutate(chefe_id = ifelse(sum(idade) / 2 == chefe_idade,min(morador_id),ifelse(idade == chefe_idade, morador_id, 0))) %>%# chefe_id = id do indivíduo mais velho; em empate, escolhe o menor morador_id
  mutate(chefe_casal = ifelse(morador_id == chefe_id, 1, 0)) %>%
  mutate(conj_casal = ifelse(morador_id != chefe_id, 1, 0))
#rm(idade_casal_filhos01b)
# CASO 2 — Genro/nora com dois ou mais filhos adultos (≥24 anos)
idade_casal_filhos02 <-
  subset(pdad2023,A01nficha %in% subset(matriz_familiar, genro_nora == 1 &filho_maior24 >= 2, demanda > 0)$A01nficha) %>% # # Domicílios com 1 genro/nora e 2 ou mais filhos adultos, com demanda positiva
  subset(e04 == 7 | (e04 %in% c(4:6) & idade >= 24)) # Mantém registros de genro/nora (e04==7) e filhos adultos (e04 4:6)
# Dentro desses domicílios, identifica o(a) filho(a) adulto(a) mais velho(a)
idade_casal_filhos02ad <- idade_casal_filhos02 %>%
  group_by(A01nficha) %>%
  filter(e04 %in% c(4:6)) %>%summarise(idade_filho = max(idade))
#Junta essa idade máxima à base principal
idade_casal_filhos02 <-
  merge(idade_casal_filhos02,
        idade_casal_filhos02ad,
        by = "A01nficha",
        all.x = TRUE) %>%   subset(e04 == 7 | idade == idade_filho) %>%
  subset(!(A01nficha == 57658 & morador_id == 4)) # Retira-se este caso específico em que os dois filhos mais velhos são gêmeos.
#rm(idade_casal_filhos02ad)

idade_casal_filhos02b <- idade_casal_filhos02 %>%
  group_by(A01nficha) %>%  summarise(chefe_idade = max(idade))

idade_casal_filhos02 <-
  merge(idade_casal_filhos02,
        idade_casal_filhos02b,
        by = "A01nficha",
        all.x = TRUE)

idade_casal_filhos02 <- idade_casal_filhos02 %>%
  group_by(A01nficha) %>%
  mutate(chefe_id = ifelse(sum(idade) / 2 == chefe_idade,min(morador_id),ifelse(idade == chefe_idade, morador_id, 0))) %>%
  mutate(chefe_casal = ifelse(morador_id == chefe_id, 1, 0)) %>%
  mutate(conj_casal = ifelse(morador_id != chefe_id, 1, 0))
#rm(idade_casal_filhos02b)

3.11 — Casais com Genros / Noras como Chefes

Trata-se dos casos em que o genro ou nora é o chefe do núcleo familiar, e o filho mais velho é identificado como cônjuge. Esses ajustes permitem representar corretamente o papel de cada indivíduo no arranjo.

# O genro/nora vai ser o chefe neste caso. Imputam-se os filhos mais velhos como cônjuge.
idade_casal_filhos03genro <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, genro_nora == 2 &
                            demanda > 0)$A01nficha
  ) %>%
  subset(e04 == 7)
  # Tem alguns casos que tem dois genros/noras, e não tem filhos com mais de 24 anos, apenas filhos menores.
idade_casal_filhos03filho <-
  subset(
    pdad2023,
    A01nficha %in% subset(matriz_familiar, genro_nora == 2 &
                            demanda > 0)$A01nficha
  ) %>%
  subset(e04 %in% c(4:6)) %>%
  arrange(desc(idade)) %>%
  group_by(A01nficha) %>%
  slice(1:2)
  # Junto os dados dos genros e filhos.
idade_casal_filhos03 <-
  rbind(idade_casal_filhos03genro, idade_casal_filhos03filho)

idade_casal_filhos03 <- idade_casal_filhos03 %>%
  group_by(A01nficha) %>%
  mutate(chefe_casal = ifelse(e04 == 7, 1, 0)) %>%
  mutate(conj_casal = ifelse(e04 != 7, 1, 0)) %>%
  mutate(chefe_id = ifelse(chefe_casal == 1, morador_id, 0))

#rm(idade_casal_filhos03genro, idade_casal_filhos03filho)

3.12 — Junção Final dos Casais e Integração com a Base

Por fim, todos os casais identificados são consolidados em um único objeto (casais) e reincorporados à base original da PDAD. Também é incorporada a variável de demanda habitacional e o estrato de renda do responsável.

casais <-
  bind_rows(
    #list(
      idade_casal_avos,
      idade_casal_pais,
      idade_casal_sogros,
      idade_casal_filhos01,
      idade_casal_filhos02,
      idade_casal_filhos03
    )

  # Apesar de o objeto ser "casais", o número de observações é ímpar porque têm casais que só tem o genro.
casais <-
  casais[, c("A01nficha",
             "morador_id",
             "chefe_casal",
             "conj_casal",
             "chefe_id")]

casais <- as.data.frame(casais)

Adição da informação sobre casais e demanda à PDAD

pdad2023_original <-
  merge(
    pdad2023_original,
    casais,
    all.x = TRUE,
    by = c("A01nficha", "morador_id")
  )

pdad2023_original$conj_casal <-
  ifelse(is.na(pdad2023_original$conj_casal) == TRUE,
         0,
         pdad2023_original$conj_casal)

#pdad2023_original$conj_casal %>% table()
  # Juntando as informações de demanda habitacional com a PDAD.
pdad2023_original <-
  merge(pdad2023_original,
        matriz_familiar[, c("A01nficha", "demanda")],
        by = "A01nficha",
        all.x = TRUE)
pdad2023_original$demanda %>% table()
.
    0     1     2     3     4     5 
40311 10229  4035  1008   163    38 

Contabilização da renda do responsável

pdad_renda <- pdad2023_original %>%
  filter(e04 == 1) %>%
  mutate(
    renda_resp = case_when(
      renda_ind_r <= 1100 ~ "ate01SM",
      renda_ind_r > 1100 &
        renda_ind_r <= 3300 ~ "1a3SM",
      renda_ind_r > 3300 &
        renda_ind_r <= 5500 ~ "3a5SM",
      renda_ind_r > 5500 &
        renda_ind_r <= 13200 ~ "5a12SM",
      renda_ind_r > 13200 ~ "maisde12SM"
    )
  ) %>%
  select(A01nficha, renda_resp)

# Junção dos dados de renda dos responsável com as demais informações da PDAD.
pdad2023_original <-
  merge(pdad2023_original,
        pdad_renda,
        by = "A01nficha",
        all.x = TRUE)

pdad2023_original$demanda %>% table()
.
    0     1     2     3     4     5 
40311 10229  4035  1008   163    38 

4. Expansão Amostral

Nesta seção, declara-se o desenho amostral complexo que será utilizado na estimação das taxas e totais expandidos. O plano considera:

amostra_mor <- 
  survey::svydesign(id = ~ficha,
                    strata = ~setor_distrito,
                    weights = ~peso_mor,
                    nest=TRUE,
                    data=pdad2023_original) 

amostra_mor <- srvyr::as_survey(amostra_mor) %>% 
  mutate(grupo_etario = case_when(idade %in% c(24:29) ~ "idade_24_29",
                                         idade %in% c(30:39) ~ "idade_30_39",
                                         idade %in% c(40:64) ~ "idade_40_64",TRUE~"Outro"))

5.Estimativa da Taxa de Chefia

Nesta seção estimamos a taxa de chefia de domicílio por faixa etária e por grupo territorial (DF, PMB, Área Rural), utilizando o desenho amostral amostra_mor já declarado. Publicamos apenas estimativas com CV ≤ params$cv_max.

5.1 Taxa de Chefia | sem faixa de idade

Calculando a população total

pop_total_total <- amostra_mor %>%
  srvyr::group_by(grupo_pdadA) %>%
  srvyr::filter(!grupo_etario=="Outro") %>%
  srvyr::summarise(pop_total = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_total=ifelse(pop_total_cv>params$cv_max,NA,pop_total))

pop_total_total

Calculando a população chefe de domicílio

pop_chefe_total <- amostra_mor %>%
  srvyr::filter(e04 == 1,!grupo_etario=="Outro") %>%
  srvyr::group_by(grupo_pdadA) %>%
  srvyr::summarise(pop_chefe = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_chefe=ifelse(pop_chefe_cv>params$cv_max,NA,pop_chefe))
pop_chefe_total

Calculando a taxa de chefia

taxa_chefia_groupo_A_total <- pop_chefe_total %>%
  left_join(pop_total_total, by = c("grupo_pdadA")) %>%
  mutate(taxa_chefia = pop_chefe / pop_total) %>% 
  select(grupo_pdadA, taxa_chefia, pop_chefe, pop_total) 
taxa_chefia_groupo_A_total %>% filter(grupo_pdadA=="DF")

5.2 Taxa de Chefia grupos PDADA | Faixa de Idade

Calculando a população total

pop_total <- amostra_mor %>%
  srvyr::group_by(grupo_etario,grupo_pdadA) %>%
  srvyr::filter(!grupo_etario=="Outro") %>%
  srvyr::summarise(pop_total = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_total=ifelse(pop_total_cv>params$cv_max,NA,pop_total))

pop_total

Calculando a população chefe de domicílio

pop_chefe <- amostra_mor %>%
  srvyr::filter(e04 == 1,!grupo_etario=="Outro") %>%
  srvyr::group_by(grupo_etario,grupo_pdadA) %>%
  srvyr::summarise(pop_chefe = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_chefe=ifelse(pop_chefe_cv>params$cv_max,NA,pop_chefe))
pop_chefe

Calculando a taxa de chefia

taxa_chefia_groupo_A <- pop_chefe %>%
  left_join(pop_total, by = c("grupo_etario", "grupo_pdadA")) %>%
  mutate(taxa_chefia = pop_chefe / pop_total) %>% 
  select(grupo_etario, grupo_pdadA, taxa_chefia, pop_chefe, pop_total) 
taxa_chefia_groupo_A %>% filter(grupo_pdadA=="DF")

5.2 Taxa de Chefia RA & Municípios | Faixa de Idade

Calculando a população total

pop_total <- amostra_mor %>%
  srvyr::group_by(grupo_etario,grupo_pdadA,strata_localidade) %>%
  srvyr::filter(!grupo_etario=="Outro") %>%
  srvyr::summarise(pop_total = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_total=ifelse(pop_total_cv>params$cv_max,NA,pop_total))

pop_total

Calculando a população chefe de domicílio

pop_chefe <- amostra_mor %>%
  srvyr::filter(e04 == 1,!grupo_etario=="Outro") %>%
  srvyr::group_by(grupo_etario,grupo_pdadA,strata_localidade) %>%
  srvyr::summarise(pop_chefe = survey_total(vartype = c("cv", "ci"))) %>% 
  mutate(pop_chefe=ifelse(pop_chefe_cv>params$cv_max,NA,pop_chefe))
pop_chefe 

Calculando a taxa de chefia

taxa_chefia_strata_localidade <- pop_chefe %>%
  left_join(pop_total, by = c("grupo_etario", "grupo_pdadA",'strata_localidade')) %>%
  mutate(taxa_chefia = pop_chefe / pop_total) %>% 
  select(grupo_etario, grupo_pdadA,strata_localidade, taxa_chefia, pop_chefe, pop_total) 
taxa_chefia_strata_localidade %>% filter(grupo_pdadA=="DF")

6. Estimação da Demanda

Estimamos a demanda, no nível do morador, adultos 24–64 que não são responsáveis nem cônjuges. É a maneira mais direta de evitar duplicações. publicamos apenas resultados com CV ≤ params$cv_max e cruzamos por faixa etária e grupo usando a mesma definição do Bloco 5. ## 6.1 DEMANDA Grupos PDAD A | sem faixa etária

Calculando a demanda potencial por faixa etária e grupo territorial.

demanda_idade <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0)) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_pdadA) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade %>% filter(grupo_pdadA=="DF")

Versão com a taxa de chefia do do

demanda_idade_groupo_A_total <-
  merge(demanda_idade, taxa_chefia_groupo_A_total,
by = c("grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_pdadA,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_groupo_A_total %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_pdadA demanda_ajustada demanda taxa_chefia pop_chefe pop_total
          DF         119792.5  256829   0.4664289  779154.9   1670469
       Total         119792.5  256829   0.4664289  779154.9   1670469

6.2 DEMANDA Grupos PDAD A | Por faixa etária

Calculando a demanda potencial por faixa etária e grupo territorial.

demanda_idade <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0)) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade %>% filter(grupo_pdadA=="DF")

Versão com a taxa de chefia do do

demanda_idade_groupo_A <-
  merge(demanda_idade, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_groupo_A %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA demanda_ajustada   demanda taxa_chefia pop_chefe pop_total
  idade_24_29          DF         32333.53 116140.53   0.2784000  75125.59  269847.7
  idade_30_39          DF         36566.39  84400.93   0.4332464 203635.50  470022.4
  idade_40_64          DF         30266.45  56287.51   0.5377117 500393.82  930598.7
        Total           -         99166.37 256828.97   1.2493581 779154.91 1670468.8

6.3 DEMANDA RA & Municípios | Por faixa etária

Calculando a demanda potencial por faixa etária e grupo territorial.


demanda_idade <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0)) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_localidade) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade %>% filter(grupo_pdadA=="DF")

Versão com a taxa de chefia do GRUPO PDAD A

demanda_idade_RA <-
  merge(demanda_idade, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,strata_localidade,grupo_pdadA,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_RA %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario         strata_localidade grupo_pdadA demanda_ajustada     demanda taxa_chefia   pop_chefe  pop_total
  idade_24_29                 Arapoanga          DF        684.38779   2458.2894   0.2784000    75125.59   269847.7
  idade_24_29                Arniqueira          DF        552.88538   1985.9388   0.2784000    75125.59   269847.7
  idade_24_29                Brazlândia          DF        528.14886   1897.0864   0.2784000    75125.59   269847.7
  idade_24_29            Candangolândia          DF        142.11927    510.4859   0.2784000    75125.59   269847.7
  idade_24_29                 Ceilândia          DF       2805.99349  10078.9992   0.2784000    75125.59   269847.7
  idade_24_29                  Cruzeiro          DF        272.94360    980.4008   0.2784000    75125.59   269847.7
  idade_24_29                    Fercal          DF         68.19922    244.9685   0.2784000    75125.59   269847.7
  idade_24_29                      Gama          DF       1357.19174   4874.9701   0.2784000    75125.59   269847.7
  idade_24_29                     Guará          DF       1011.72064   3634.0539   0.2784000    75125.59   269847.7
  idade_24_29                    Itapoã          DF        719.80971   2585.5233   0.2784000    75125.59   269847.7
  idade_24_29           Jardim Botânico          DF        876.35213   3147.8164   0.2784000    75125.59   269847.7
  idade_24_29                Lago Norte          DF        390.48697   1402.6112   0.2784000    75125.59   269847.7
  idade_24_29                  Lago Sul          DF        279.17039   1002.7672   0.2784000    75125.59   269847.7
  idade_24_29        Núcleo Bandeirante          DF        240.20248    862.7962   0.2784000    75125.59   269847.7
  idade_24_29                   Paranoá          DF        712.82892   2560.4486   0.2784000    75125.59   269847.7
  idade_24_29                  Park Way          DF        296.73303   1065.8514   0.2784000    75125.59   269847.7
  idade_24_29                Planaltina          DF       1580.36472   5676.5972   0.2784000    75125.59   269847.7
  idade_24_29              Plano Piloto          DF       1776.57709   6381.3830   0.2784000    75125.59   269847.7
  idade_24_29          Recanto Das Emas          DF       1583.53511   5687.9851   0.2784000    75125.59   269847.7
  idade_24_29              Riacho Fundo          DF        564.28372   2026.8811   0.2784000    75125.59   269847.7
  idade_24_29           Riacho Fundo II          DF        982.41699   3528.7965   0.2784000    75125.59   269847.7
  idade_24_29                      SCIA          DF        377.37604   1355.5173   0.2784000    75125.59   269847.7
  idade_24_29                       SIA          DF               NA          NA   0.2784000    75125.59   269847.7
  idade_24_29                 Samambaia          DF       3148.40127  11308.9122   0.2784000    75125.59   269847.7
  idade_24_29               Santa Maria          DF       1919.90629   6896.2149   0.2784000    75125.59   269847.7
  idade_24_29                Sobradinho          DF        929.61581   3339.1371   0.2784000    75125.59   269847.7
  idade_24_29             Sobradinho II          DF        963.73993   3461.7094   0.2784000    75125.59   269847.7
  idade_24_29 Sol Nascente / Pôr do Sol          DF       1136.92671   4083.7883   0.2784000    75125.59   269847.7
  idade_24_29      Sudoeste e Octogonal          DF        282.40469   1014.3846   0.2784000    75125.59   269847.7
  idade_24_29             São Sebastião          DF       1378.15404   4950.2658   0.2784000    75125.59   269847.7
  idade_24_29                Taguatinga          DF       2392.01768   8592.0172   0.2784000    75125.59   269847.7
  idade_24_29                    Varjão          DF        132.45404    475.7688   0.2784000    75125.59   269847.7
  idade_24_29             Vicente Pires          DF       1049.02440   3768.0473   0.2784000    75125.59   269847.7
  idade_24_29               Água Quente          DF        137.40315    493.5458   0.2784000    75125.59   269847.7
  idade_24_29              Águas Claras          DF        941.70495   3382.5608   0.2784000    75125.59   269847.7
  idade_30_39                 Arapoanga          DF        587.71993   1356.5490   0.4332464   203635.50   470022.4
  idade_30_39                Arniqueira          DF        623.32152   1438.7230   0.4332464   203635.50   470022.4
  idade_30_39                Brazlândia          DF        594.87621   1373.0668   0.4332464   203635.50   470022.4
  idade_30_39            Candangolândia          DF        151.73601    350.2303   0.4332464   203635.50   470022.4
  idade_30_39                 Ceilândia          DF       3722.65247   8592.4609   0.4332464   203635.50   470022.4
  idade_30_39                  Cruzeiro          DF        313.16883    722.8424   0.4332464   203635.50   470022.4
  idade_30_39                    Fercal          DF         72.06469    166.3365   0.4332464   203635.50   470022.4
  idade_30_39                      Gama          DF       2136.32591   4930.9725   0.4332464   203635.50   470022.4
  idade_30_39                     Guará          DF       1683.22736   3885.1506   0.4332464   203635.50   470022.4
  idade_30_39                    Itapoã          DF        572.11697   1320.5350   0.4332464   203635.50   470022.4
  idade_30_39           Jardim Botânico          DF        791.05205   1825.8712   0.4332464   203635.50   470022.4
  idade_30_39                Lago Norte          DF        413.99836    955.5726   0.4332464   203635.50   470022.4
  idade_30_39                  Lago Sul          DF               NA          NA   0.4332464   203635.50   470022.4
  idade_30_39        Núcleo Bandeirante          DF        352.21660    812.9707   0.4332464   203635.50   470022.4
  idade_30_39                   Paranoá          DF        614.49026   1418.3391   0.4332464   203635.50   470022.4
  idade_30_39                  Park Way          DF        322.55379    744.5043   0.4332464   203635.50   470022.4
  idade_30_39                Planaltina          DF       1526.61691   3523.6693   0.4332464   203635.50   470022.4
  idade_30_39              Plano Piloto          DF       1912.63450   4414.6579   0.4332464   203635.50   470022.4
  idade_30_39          Recanto Das Emas          DF       1462.18858   3374.9587   0.4332464   203635.50   470022.4
  idade_30_39              Riacho Fundo          DF        722.92712   1668.6283   0.4332464   203635.50   470022.4
  idade_30_39           Riacho Fundo II          DF       1031.14866   2380.0515   0.4332464   203635.50   470022.4
  idade_30_39                      SCIA          DF        344.78096    795.8081   0.4332464   203635.50   470022.4
  idade_30_39                       SIA          DF               NA          NA   0.4332464   203635.50   470022.4
  idade_30_39                 Samambaia          DF       3410.55410   7872.0894   0.4332464   203635.50   470022.4
  idade_30_39               Santa Maria          DF       2237.07409   5163.5150   0.4332464   203635.50   470022.4
  idade_30_39                Sobradinho          DF       1178.81595   2720.8906   0.4332464   203635.50   470022.4
  idade_30_39             Sobradinho II          DF       1119.16583   2583.2088   0.4332464   203635.50   470022.4
  idade_30_39 Sol Nascente / Pôr do Sol          DF               NA          NA   0.4332464   203635.50   470022.4
  idade_30_39      Sudoeste e Octogonal          DF               NA          NA   0.4332464   203635.50   470022.4
  idade_30_39             São Sebastião          DF       1179.17614   2721.7219   0.4332464   203635.50   470022.4
  idade_30_39                Taguatinga          DF       2640.05596   6093.6598   0.4332464   203635.50   470022.4
  idade_30_39                    Varjão          DF        115.73544    267.1354   0.4332464   203635.50   470022.4
  idade_30_39             Vicente Pires          DF       1502.23238   3467.3860   0.4332464   203635.50   470022.4
  idade_30_39               Água Quente          DF        124.70951    287.8489   0.4332464   203635.50   470022.4
  idade_30_39              Águas Claras          DF       1394.75499   3219.3115   0.4332464   203635.50   470022.4
  idade_40_64                 Arapoanga          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                Arniqueira          DF        464.98066    864.7397   0.5377117   500393.82   930598.7
  idade_40_64                Brazlândia          DF        435.93503    810.7226   0.5377117   500393.82   930598.7
  idade_40_64            Candangolândia          DF        168.80392    313.9302   0.5377117   500393.82   930598.7
  idade_40_64                 Ceilândia          DF       4395.73027   8174.8832   0.5377117   500393.82   930598.7
  idade_40_64                  Cruzeiro          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                    Fercal          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                      Gama          DF       1724.57154   3207.2421   0.5377117   500393.82   930598.7
  idade_40_64                     Guará          DF       1572.17071   2923.8173   0.5377117   500393.82   930598.7
  idade_40_64                    Itapoã          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64           Jardim Botânico          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                Lago Norte          DF        420.86819    782.7023   0.5377117   500393.82   930598.7
  idade_40_64                  Lago Sul          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64        Núcleo Bandeirante          DF        301.40361    560.5301   0.5377117   500393.82   930598.7
  idade_40_64                   Paranoá          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                  Park Way          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                Planaltina          DF       1319.14402   2453.2553   0.5377117   500393.82   930598.7
  idade_40_64              Plano Piloto          DF       1757.23865   3267.9941   0.5377117   500393.82   930598.7
  idade_40_64          Recanto Das Emas          DF        921.15376   1713.0998   0.5377117   500393.82   930598.7
  idade_40_64              Riacho Fundo          DF        530.82475    987.1921   0.5377117   500393.82   930598.7
  idade_40_64           Riacho Fundo II          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                      SCIA          DF        262.85371    488.8376   0.5377117   500393.82   930598.7
  idade_40_64                       SIA          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64                 Samambaia          DF       2297.84754   4273.3822   0.5377117   500393.82   930598.7
  idade_40_64               Santa Maria          DF       1518.67573   2824.3309   0.5377117   500393.82   930598.7
  idade_40_64                Sobradinho          DF       1008.26019   1875.0944   0.5377117   500393.82   930598.7
  idade_40_64             Sobradinho II          DF        885.40859   1646.6233   0.5377117   500393.82   930598.7
  idade_40_64 Sol Nascente / Pôr do Sol          DF        841.38622   1564.7535   0.5377117   500393.82   930598.7
  idade_40_64      Sudoeste e Octogonal          DF               NA          NA   0.5377117   500393.82   930598.7
  idade_40_64             São Sebastião          DF        964.85288   1794.3684   0.5377117   500393.82   930598.7
  idade_40_64                Taguatinga          DF       3105.84700   5776.0452   0.5377117   500393.82   930598.7
  idade_40_64                    Varjão          DF        122.14371    227.1546   0.5377117   500393.82   930598.7
  idade_40_64             Vicente Pires          DF        901.91278   1677.3167   0.5377117   500393.82   930598.7
  idade_40_64               Água Quente          DF         84.02860    156.2707   0.5377117   500393.82   930598.7
  idade_40_64              Águas Claras          DF               NA          NA   0.5377117   500393.82   930598.7
        Total                         -           -      93075.61439 244529.4719  43.7275322 27270421.89 58466408.5

Versão com a taxa de chefia do GRUPO PDAD A

demanda_idade_RA <-
  merge(demanda_idade, taxa_chefia_strata_localidade,
by = c("grupo_etario", "grupo_pdadA","strata_localidade")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,strata_localidade,grupo_pdadA,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_RA %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario         strata_localidade grupo_pdadA demanda_ajustada     demanda taxa_chefia   pop_chefe    pop_total
  idade_24_29               Água Quente          DF        186.72119    493.5458   0.3783260    439.0531    1160.5154
  idade_24_29              Águas Claras          DF       1494.67520   3382.5608   0.4418768   5039.9202   11405.7130
  idade_24_29                 Arapoanga          DF        649.36355   2458.2894   0.2641526   1451.3100    5494.2105
  idade_24_29                Arniqueira          DF        580.74496   1985.9388   0.2924284   1291.5980    4416.8004
  idade_24_29                Brazlândia          DF        513.83461   1897.0864   0.2708546   1082.9076    3998.1138
  idade_24_29            Candangolândia          DF        198.34395    510.4859   0.3885395    567.9877    1461.8530
  idade_24_29                 Ceilândia          DF       3545.52626  10078.9992   0.3517736   9781.7833   27807.0389
  idade_24_29                  Cruzeiro          DF        280.31132    980.4008   0.2859150    680.0866    2378.6321
  idade_24_29                    Fercal          DF         92.71846    244.9685   0.3784914    310.6755     820.8257
  idade_24_29                      Gama          DF       1014.84487   4874.9701   0.2081746   2453.0353   11783.5485
  idade_24_29                     Guará          DF       1184.28560   3634.0539   0.3258855   3790.6829   11631.9459
  idade_24_29                    Itapoã          DF        976.16274   2585.5233   0.3775494   2717.2840    7197.1618
  idade_24_29           Jardim Botânico          DF               NA   3147.8164          NA          NA    4946.7141
  idade_24_29                Lago Norte          DF        486.13122   1402.6112   0.3465901   1166.7856    3366.4709
  idade_24_29                  Lago Sul          DF               NA   1002.7672          NA          NA    1672.9974
  idade_24_29        Núcleo Bandeirante          DF        282.83511    862.7962   0.3278122    773.6254    2359.9654
  idade_24_29                   Paranoá          DF        736.19121   2560.4486   0.2875243   1509.2334    5249.0636
  idade_24_29                  Park Way          DF               NA   1065.8514          NA          NA    1561.0942
  idade_24_29                Planaltina          DF       1106.78211   5676.5972   0.1949728   2410.4123   12362.8126
  idade_24_29              Plano Piloto          DF       1802.47052   6381.3830   0.2824577   4337.9317   15357.8123
  idade_24_29          Recanto Das Emas          DF       1268.39624   5687.9851   0.2229957   2619.7775   11748.1073
  idade_24_29              Riacho Fundo          DF        657.56072   2026.8811   0.3244200   1541.2174    4750.6859
  idade_24_29           Riacho Fundo II          DF        808.90746   3528.7965   0.2292304   1607.7793    7013.8135
  idade_24_29                 Samambaia          DF       2518.26815  11308.9122   0.2226800   5325.5532   23915.7269
  idade_24_29               Santa Maria          DF       1825.69871   6896.2149   0.2647392   3442.1223   13001.9344
  idade_24_29             São Sebastião          DF       1783.69313   4950.2658   0.3603227   4153.8658   11528.1824
  idade_24_29                      SCIA          DF        470.78830   1355.5173   0.3473126   1442.1546    4152.3241
  idade_24_29                       SIA          DF               NA          NA          NA          NA     875.4585
  idade_24_29                Sobradinho          DF        645.15058   3339.1371   0.1932088   1240.5633    6420.8438
  idade_24_29             Sobradinho II          DF        994.83338   3461.7094   0.2873821   2123.4027    7388.7780
  idade_24_29 Sol Nascente / Pôr do Sol          DF       1223.60320   4083.7883   0.2996245   3051.0528   10182.9202
  idade_24_29      Sudoeste e Octogonal          DF        454.40657   1014.3846   0.4479628   1584.1510    3536.3450
  idade_24_29                Taguatinga          DF       1565.27873   8592.0172   0.1821783   3444.6535   18908.1479
  idade_24_29                    Varjão          DF        177.91448    475.7688   0.3739516    441.4791    1180.5783
  idade_24_29             Vicente Pires          DF        851.42775   3768.0473   0.2259599   1990.8285    8810.5370
  idade_30_39               Água Quente          DF        143.37348    287.8489   0.4980858    852.0832    1710.7155
  idade_30_39              Águas Claras          DF       1755.33200   3219.3115   0.5452508  16319.4367   29930.1499
  idade_30_39                 Arapoanga          DF        635.17135   1356.5490   0.4682259   3528.2057    7535.2643
  idade_30_39                Arniqueira          DF        648.08748   1438.7230   0.4504602   3173.5006    7045.0185
  idade_30_39                Brazlândia          DF        589.28226   1373.0668   0.4291723   2614.3319    6091.5670
  idade_30_39            Candangolândia          DF        163.19191    350.2303   0.4659560   1154.4915    2477.6836
  idade_30_39                 Ceilândia          DF       3475.53996   8592.4609   0.4044871  17775.9087   43946.7832
  idade_30_39                  Cruzeiro          DF        296.60716    722.8424   0.4103345   1865.9673    4547.4298
  idade_30_39                    Fercal          DF         77.55938    166.3365   0.4662800    675.3566    1448.3929
  idade_30_39                      Gama          DF       2025.80016   4930.9725   0.4108318   8130.6232   19790.6390
  idade_30_39                     Guará          DF       1767.99584   3885.1506   0.4550649  10616.8855   23330.4840
  idade_30_39                    Itapoã          DF        733.79213   1320.5350   0.5556779   5846.3908   10521.1860
  idade_30_39           Jardim Botânico          DF        706.22447   1825.8712   0.3867877   4634.2421   11981.3593
  idade_30_39                Lago Norte          DF        449.05125    955.5726   0.4699290   3314.1951    7052.5447
  idade_30_39                  Lago Sul          DF               NA          NA          NA          NA    2713.9318
  idade_30_39        Núcleo Bandeirante          DF        309.48578    812.9707   0.3806850   1492.0079    3919.2713
  idade_30_39                   Paranoá          DF        643.31017   1418.3391   0.4535658   4095.1607    9028.8119
  idade_30_39                  Park Way          DF        209.15205    744.5043   0.2809279    809.4543    2881.3594
  idade_30_39                Planaltina          DF       1508.34152   3523.6693   0.4280599   8128.0310   18988.0691
  idade_30_39              Plano Piloto          DF       1960.12693   4414.6579   0.4440043  16142.5251   36356.6895
  idade_30_39          Recanto Das Emas          DF       1397.41505   3374.9587   0.4140540   7034.0189   16988.1691
  idade_30_39              Riacho Fundo          DF        700.90399   1668.6283   0.4200480   3060.4287    7285.9019
  idade_30_39           Riacho Fundo II          DF        984.64152   2380.0515   0.4137060   4630.4652   11192.6478
  idade_30_39                 Samambaia          DF       3500.46707   7872.0894   0.4446681  18275.3993   41098.9657
  idade_30_39               Santa Maria          DF       1803.40220   5163.5150   0.3492586   7075.0896   20257.4507
  idade_30_39             São Sebastião          DF       1295.84458   2721.7219   0.4761120   8094.2318   17000.6871
  idade_30_39                      SCIA          DF        375.00744    795.8081   0.4712285   2945.4293    6250.5333
  idade_30_39                       SIA          DF               NA          NA   0.5828497    772.6981    1325.7243
  idade_30_39                Sobradinho          DF        825.18663   2720.8906   0.3032781   3328.7470   10975.8884
  idade_30_39             Sobradinho II          DF       1066.26385   2583.2088   0.4127672   5111.0021   12382.2876
  idade_30_39 Sol Nascente / Pôr do Sol          DF               NA          NA   0.4438060   7266.4740   16373.0880
  idade_30_39      Sudoeste e Octogonal          DF               NA          NA   0.6016848   5479.2608    9106.5297
  idade_30_39                Taguatinga          DF       2447.81698   6093.6598   0.4016990  12528.3817   31188.4821
  idade_30_39                    Varjão          DF        122.55453    267.1354   0.4587731    697.1347    1519.5631
  idade_30_39             Vicente Pires          DF       1258.51958   3467.3860   0.3629592   5727.1842   15779.1414
  idade_40_64               Água Quente          DF         91.88234    156.2707   0.5879689   1997.8922    3397.9554
  idade_40_64              Águas Claras          DF               NA          NA   0.6212638  31801.0768   51187.7192
  idade_40_64                 Arapoanga          DF               NA          NA   0.5873248   8312.7663   14153.6104
  idade_40_64                Arniqueira          DF        473.02575    864.7397   0.5470152   8425.2666   15402.2540
  idade_40_64                Brazlândia          DF        454.46840    810.7226   0.5605720   7260.6063   12952.1389
  idade_40_64            Candangolândia          DF        160.74952    313.9302   0.5120550   2311.3213    4513.8143
  idade_40_64                 Ceilândia          DF       4283.83730   8174.8832   0.5240243  47435.0722   90520.7527
  idade_40_64                  Cruzeiro          DF               NA          NA   0.5854187   5547.4271    9475.9988
  idade_40_64                    Fercal          DF               NA          NA   0.5499338   1431.8738    2603.7203
  idade_40_64                      Gama          DF       1577.08113   3207.2421   0.4917250  22553.4699   45866.0216
  idade_40_64                     Guará          DF       1426.63674   2923.8173   0.4879364  21339.6075   43734.4076
  idade_40_64                    Itapoã          DF               NA          NA   0.6304697  11889.7773   18858.6026
  idade_40_64           Jardim Botânico          DF               NA          NA   0.5344266  15346.6145   28716.0378
  idade_40_64                Lago Norte          DF        415.63408    782.7023   0.5310245   7934.7134   14942.2750
  idade_40_64                  Lago Sul          DF               NA          NA   0.3758333   3790.6966   10086.1129
  idade_40_64        Núcleo Bandeirante          DF        286.36027    560.5301   0.5108740   3776.1257    7391.5012
  idade_40_64                   Paranoá          DF               NA          NA   0.6508143  10563.6676   16231.4632
  idade_40_64                  Park Way          DF               NA          NA   0.4738657   4054.4557    8556.1281
  idade_40_64                Planaltina          DF       1328.64427   2453.2553   0.5415842  20507.7370   37866.2030
  idade_40_64              Plano Piloto          DF       1708.64239   3267.9941   0.5228413  39670.4927   75874.8222
  idade_40_64          Recanto Das Emas          DF        942.23476   1713.0998   0.5500174  17281.5239   31419.9558
  idade_40_64              Riacho Fundo          DF        554.79491    987.1921   0.5619928   7319.2545   13023.7505
  idade_40_64           Riacho Fundo II          DF               NA          NA   0.5785937  13274.3085   22942.3671
  idade_40_64                 Samambaia          DF       2186.50727   4273.3822   0.5116573  34322.8942   67081.8000
  idade_40_64               Santa Maria          DF       1451.36437   2824.3309   0.5138790  18932.8797   36843.0685
  idade_40_64             São Sebastião          DF       1044.18540   1794.3684   0.5819236  16560.1072   28457.5264
  idade_40_64                      SCIA          DF        272.30797    488.8376   0.5570520   5227.2913    9383.8485
  idade_40_64                       SIA          DF               NA          NA   0.5630630    864.7036    1535.7138
  idade_40_64                Sobradinho          DF        934.36371   1875.0944   0.4983022  11972.2450   24026.0721
  idade_40_64             Sobradinho II          DF        825.24060   1646.6233   0.5011715  13192.2095   26322.7468
  idade_40_64 Sol Nascente / Pôr do Sol          DF        958.16198   1564.7535   0.6123405  19827.5266   32379.9018
  idade_40_64      Sudoeste e Octogonal          DF               NA          NA   0.6139738  10909.6615   17768.9377
  idade_40_64                Taguatinga          DF       2979.82295   5776.0452   0.5158933  34999.0532   67841.6522
  idade_40_64                    Varjão          DF        129.58725    227.1546   0.5704803   1330.1537    2331.6383
  idade_40_64             Vicente Pires          DF        837.53290   1677.3167   0.4993290  18429.3424   36908.2137
        Total                         -           -      89576.38523 244529.4719  43.4026133 777401.4722 1670468.8157

7. Analises Estratificadas

7.1 Estado Civil

###Por grupo Etário

#pdad2023$e07#Estado civil
demanda_idade_strata1 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_estado_civil=case_when(e07==1~"Solteiro",
                                              e07==2~"Casado",
                                              e07==3~"Desquitado ou separado judicialmente",
                                              e07==4~"Desquitado ou separado judicialmente",
                                              e07==5~"Viúvo",
                                              TRUE~"Não Sabe / Não se Aplica")) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_estado_civil) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata1 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata1 <-
  merge(demanda_idade_strata1, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_estado_civil,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata1 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA                  strata_estado_civil demanda_ajustada    demanda taxa_chefia  pop_chefe pop_total
  idade_24_29          DF                               Casado         1933.748   6945.934   0.2784000   75125.59  269847.7
  idade_24_29          DF Desquitado ou separado judicialmente               NA         NA   0.2784000   75125.59  269847.7
  idade_24_29          DF                             Solteiro        29877.766 107319.558   0.2784000   75125.59  269847.7
  idade_24_29          DF                                Viúvo               NA         NA   0.2784000   75125.59  269847.7
  idade_30_39          DF                               Casado         4037.859   9320.006   0.4332464  203635.50  470022.4
  idade_30_39          DF Desquitado ou separado judicialmente         2074.316   4787.844   0.4332464  203635.50  470022.4
  idade_30_39          DF                             Solteiro        30096.832  69468.171   0.4332464  203635.50  470022.4
  idade_30_39          DF                                Viúvo               NA         NA   0.4332464  203635.50  470022.4
  idade_40_64          DF                               Casado         5030.471   9355.331   0.5377117  500393.82  930598.7
  idade_40_64          DF Desquitado ou separado judicialmente         4367.217   8121.856   0.5377117  500393.82  930598.7
  idade_40_64          DF                             Solteiro        19109.993  35539.479   0.5377117  500393.82  930598.7
  idade_40_64          DF                                Viúvo         1673.811   3112.840   0.5377117  500393.82  930598.7
        Total           -                                    -        98202.013 253971.019   4.9974323 3116619.64 6681875.3

###sem grupo etário

#pdad2023$e07#Estado civil
demanda_idade_strata1_total <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_estado_civil=case_when(e07==1~"Solteiro",
                                              e07==2~"Casado",
                                              e07==3~"Desquitado ou separado judicialmente",
                                              e07==4~"Desquitado ou separado judicialmente",
                                              e07==5~"Viúvo",
                                              TRUE~"Não Sabe / Não se Aplica")) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_pdadA,strata_estado_civil) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata1_total %>% filter(grupo_pdadA=="DF")

demanda_idade_strata1_total <-
  merge(demanda_idade_strata1_total, taxa_chefia_groupo_A_total,
by = c("grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_pdadA,strata_estado_civil,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata1_total %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_pdadA                  strata_estado_civil demanda_ajustada    demanda taxa_chefia pop_chefe pop_total
          DF                               Casado        11950.501  25621.272   0.4664289  779154.9   1670469
          DF Desquitado ou separado judicialmente         6674.296  14309.355   0.4664289  779154.9   1670469
          DF                             Solteiro        99035.543 212327.208   0.4664289  779154.9   1670469
          DF                                Viúvo         1588.339   3405.319   0.4664289  779154.9   1670469
       Total                                    -       119248.680 255663.153   1.8657155 3116619.6   6681875

7.2 Escolaridade

###Por grupo Etário

pdad2023$escolaridade#Estado civil
   [1] 5 7 7 1 1 2 5 4 2 2 5 8 2 4 6 2 1 7 7 2 5 3 4 7 7 2 2 5 8 8 8 8 7 5 2 2 2 5 7 3 3 8 2 2 5 5 4 8 2 7 7 2 2 3 4 1 1 7 7
  [60] 8 8 5 8 2 8 2 7 7 7 5 2 5 5 4 2 5 4 2 1 6 5 7 7 7 7 2 5 2 8 2 2 5 7 2 5 5 5 5 6 4 6 2 5 2 4 5 3 2 4 2 5 5 4 5 5 7 7 6
 [119] 6 4 3 8 5 4 5 7 7 7 7 5 5 5 2 2 2 3 7 6 2 4 2 6 5 5 7 5 7 7 5 7 7 5 1 2 2 2 2 5 4 2 2 8 4 2 2 2 7 5 7 7 2 8 7 4 2 7 6
 [178] 7 5 7 2 3 4 3 2 2 6 5 5 2 2 2 2 7 7 7 5 1 3 3 4 7 5 1 6 4 7 1 2 2 8 1 8 6 5 6 6 7 4 5 8 2 1 5 7 4 7 7 7 5 6 2 4 2 7 7
 [237] 6 2 5 5 2 4 2 8 2 5 2 2 2 5 5 5 2 3 2 1 7 5 8 4 3 3 7 7 5 2 2 8 7 5 8 4 5 5 2 5 5 5 2 4 4 4 2 2 1 8 5 7 6 2 5 2 1 2 1
 [296] 2 7 7 2 2 5 3 5 5 3 5 5 7 6 3 5 5 5 2 7 6 7 3 6 5 5 7 5 4 2 7 7 5 5 4 8 3 4 2 8 7 5 7 7 5 2 5 2 2 7 4 6 5 6 2 4 2 7 7
 [355] 5 6 2 5 2 2 1 8 5 7 5 8 4 4 4 1 2 2 2 2 1 8 2 2 5 7 1 5 2 2 2 8 7 5 4 2 7 7 2 2 5 3 2 1 8 8 7 2 4 4 2 2 2 3 1 8 5 2 8
 [414] 4 2 5 5 6 4 2 4 1 2 2 5 5 5 5 2 4 3 7 5 5 7 7 5 7 6 6 4 2 7 7 2 3 6 5 1 2 2 7 7 7 6 2 2 2 8 7 6 2 7 5 5 4 7 7 7 7 2 2
 [473] 2 2 5 5 6 5 1 6 7 5 5 2 2 1 2 5 2 1 2 8 2 3 4 2 8 7 7 1 7 7 1 5 3 4 7 7 4 2 5 2 5 6 2 2 2 2 6 5 8 5 5 2 8 7 6 7 7 7 2
 [532] 2 5 5 4 4 3 4 6 5 8 2 7 7 2 5 5 2 2 5 7 2 4 2 2 1 8 5 3 8 5 7 5 2 4 5 2 5 5 4 7 5 7 7 5 5 4 7 7 2 7 7 5 7 5 5 6 5 7 7
 [591] 7 7 7 1 6 7 4 7 7 2 2 5 2 8 3 3 2 8 5 5 5 1 7 2 8 7 5 7 2 2 5 2 5 7 4 5 2 2 5 2 5 7 7 5 7 7 6 5 5 4 5 5 1 3 1 5 2 3 2
 [650] 5 5 7 7 7 7 2 3 6 6 2 2 5 5 2 5 7 2 2 5 2 2 2 5 8 2 5 2 2 7 2 5 7 4 8 5 5 4 1 7 7 4 7 5 4 2 5 5 6 2 5 5 6 2 7 2 2 2 8
 [709] 6 6 2 2 2 2 2 8 8 8 3 7 6 4 7 7 2 3 1 7 6 1 8 2 2 2 1 4 2 2 2 3 5 7 2 2 2 1 5 5 5 2 7 7 2 2 1 5 2 5 5 7 5 2 6 7 7 1 7
 [768] 5 2 1 8 5 2 6 2 7 7 2 3 5 6 3 1 2 2 4 4 5 2 1 7 5 6 6 4 8 5 5 7 7 1 5 7 7 3 6 3 2 2 4 3 5 7 5 5 7 2 2 2 2 3 3 7 6 5 5
 [827] 2 8 7 4 2 4 6 8 2 2 1 8 8 1 2 5 2 2 5 5 5 5 7 2 2 5 4 2 2 2 2 5 5 6 2 3 2 3 5 5 5 1 2 2 2 2 1 8 4 4 4 5 5 2 2 7 7 7 2
 [886] 2 7 7 5 4 4 2 2 7 7 5 3 2 2 3 8 5 2 7 7 5 2 7 5 1 8 2 4 2 2 7 3 7 5 6 4 1 1 2 2 2 3 5 3 5 2 1 8 8 7 7 4 2 7 2 6 8 5 7
 [945] 7 3 4 4 2 2 1 8 7 7 4 4 5 5 5 2 5 5 4 1 5 5 2 1 7 7 7 6 2 2 2 2 5 7 1 1 4 7 3 2 5 2 2 5 5 1 5 5 5 5 5 6 7 6 4 2
 [ reached getOption("max.print") -- omitted 54784 entries ]
demanda_idade_strata2 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_escolaridade=case_when(escolaridade==1~"Sem instrução",
                                              escolaridade==2~"Fundamental incompleto ou equivalente",
                                              escolaridade==3~"Fundamental completo ou equivalente",
                                              escolaridade==4~"Médio incompleto ou equivalente",
                                              escolaridade==5~"Médio completo ou equivalente",
                                              escolaridade==6~"Superior incompleto ou equivalente",
                                              escolaridade==7~"Superior completo ",
                                              escolaridade==8~"Sem classificação",
                                              TRUE~"Não Sabe / Não se Aplica")) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_escolaridade) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata2 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata2 <-
  merge(demanda_idade_strata2, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_escolaridade,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata2 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA                   strata_escolaridade demanda_ajustada    demanda taxa_chefia  pop_chefe
  idade_24_29          DF   Fundamental completo ou equivalente         578.8574   2079.229   0.2784000   75125.59
  idade_24_29          DF Fundamental incompleto ou equivalente        1088.8655   3911.155   0.2784000   75125.59
  idade_24_29          DF         Médio completo ou equivalente        9769.7015  35092.317   0.2784000   75125.59
  idade_24_29          DF       Médio incompleto ou equivalente        1372.1906   4928.845   0.2784000   75125.59
  idade_24_29          DF                     Sem classificação         844.2503   3032.508   0.2784000   75125.59
  idade_24_29          DF                         Sem instrução               NA         NA   0.2784000   75125.59
  idade_24_29          DF                    Superior completo        12656.9003  45463.002   0.2784000   75125.59
  idade_24_29          DF    Superior incompleto ou equivalente        5766.7659  20713.957   0.2784000   75125.59
  idade_30_39          DF   Fundamental completo ou equivalente         627.0126   1447.243   0.4332464  203635.50
  idade_30_39          DF Fundamental incompleto ou equivalente        2572.0865   5936.776   0.4332464  203635.50
  idade_30_39          DF         Médio completo ou equivalente       10088.2462  23285.241   0.4332464  203635.50
  idade_30_39          DF       Médio incompleto ou equivalente        1698.8711   3921.259   0.4332464  203635.50
  idade_30_39          DF                     Sem classificação        1948.6349   4497.753   0.4332464  203635.50
  idade_30_39          DF                         Sem instrução               NA         NA   0.4332464  203635.50
  idade_30_39          DF                    Superior completo        15064.1815  34770.474   0.4332464  203635.50
  idade_30_39          DF    Superior incompleto ou equivalente        3822.4948   8822.913   0.4332464  203635.50
  idade_40_64          DF   Fundamental completo ou equivalente        1923.4800   3577.159   0.5377117  500393.82
  idade_40_64          DF Fundamental incompleto ou equivalente        5441.6096  10119.939   0.5377117  500393.82
  idade_40_64          DF         Médio completo ou equivalente        9693.2051  18026.770   0.5377117  500393.82
  idade_40_64          DF       Médio incompleto ou equivalente        1336.4272   2485.397   0.5377117  500393.82
  idade_40_64          DF                     Sem classificação        2875.4377   5347.545   0.5377117  500393.82
  idade_40_64          DF                         Sem instrução               NA         NA   0.5377117  500393.82
  idade_40_64          DF                    Superior completo         6968.6250  12959.780   0.5377117  500393.82
  idade_40_64          DF    Superior incompleto ou equivalente        1271.1049   2363.915   0.5377117  500393.82
        Total           -                                     -       97408.9486 252783.178   9.9948645 6233239.29
  pop_total
   269847.7
   269847.7
   269847.7
   269847.7
   269847.7
   269847.7
   269847.7
   269847.7
   470022.4
   470022.4
   470022.4
   470022.4
   470022.4
   470022.4
   470022.4
   470022.4
   930598.7
   930598.7
   930598.7
   930598.7
   930598.7
   930598.7
   930598.7
   930598.7
 13363750.5

###sem grupo etário

#pdad2023$e07#Estado civil
demanda_idade_strata2_total <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_escolaridade=case_when(escolaridade==1~"Sem instrução",
                                              escolaridade==2~"Fundamental incompleto ou equivalente",
                                              escolaridade==3~"Fundamental completo ou equivalente",
                                              escolaridade==4~"Médio incompleto ou equivalente",
                                              escolaridade==5~"Médio completo ou equivalente",
                                              escolaridade==6~"Superior incompleto ou equivalente",
                                              escolaridade==7~"Superior completo ",
                                              escolaridade==8~"Sem classificação",
                                              TRUE~"Não Sabe / Não se Aplica")) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_pdadA,strata_escolaridade) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata2_total %>% filter(grupo_pdadA=="DF")

demanda_idade_strata2_total <-
  merge(demanda_idade_strata2_total, taxa_chefia_groupo_A_total,
by = c("grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_pdadA,strata_escolaridade,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata2_total %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_pdadA                   strata_escolaridade demanda_ajustada    demanda taxa_chefia pop_chefe pop_total
          DF   Fundamental completo ou equivalente         3313.338   7103.630   0.4664289  779154.9   1670469
          DF Fundamental incompleto ou equivalente         9313.591  19967.870   0.4664289  779154.9   1670469
          DF         Médio completo ou equivalente        35637.186  76404.329   0.4664289  779154.9   1670469
          DF       Médio incompleto ou equivalente         5287.205  11335.501   0.4664289  779154.9   1670469
          DF                     Sem classificação         6006.581  12877.806   0.4664289  779154.9   1670469
          DF                         Sem instrução         1343.304   2879.975   0.4664289  779154.9   1670469
          DF                    Superior completo         43468.027  93193.256   0.4664289  779154.9   1670469
          DF    Superior incompleto ou equivalente        14879.448  31900.785   0.4664289  779154.9   1670469
       Total                                     -       119248.680 255663.153   3.7314311 6233239.3  13363751

7.2 salariominimo

###Por grupo Etário

pdad2023_original$renda
NULL
pdad2023$renda_ind#Estado civil
   [1]     0    NA    NA     0     0  1000    NA     0     0     0   600    NA     0 10000    NA     0     0  7000     0
  [20]   600     0     0     0    NA    NA     0     0     0    NA    NA    NA    NA    NA     0    NA     0     0    NA
  [39]    NA    NA    NA     0    NA     0    NA   800     0     0    NA    NA    NA     0     0    NA    NA     0     0
  [58]    NA     0     0     0    NA    NA     0     0  1412     0     0     0    NA  1302    NA     0     0     0    NA
  [77]    NA     0     0    NA    NA    NA    NA 18000    NA     0   600    NA     0     0     0    NA    NA     0    NA
  [96]    NA    NA     0     0    NA  1300     0  1412    NA    NA    NA   600    NA     0     0     0    NA   112  2500
 [115]  4600    NA    NA    NA     0     0     0     0   650   200    NA 14500    NA    NA    NA    NA    NA    NA     0
 [134]    NA     0    NA    NA    NA    NA     0     0    NA    NA    NA    NA  1400     0    NA    NA     0    NA     0
 [153]    NA    NA    NA     0    NA    NA     0     0     0     0   700  1320     0     0    NA     0    NA    NA     0
 [172]     0  3500    NA    NA    NA     0    NA    NA    NA     0  1320   800   800     0     0    NA     0  1650   300
 [191]     0    50     0     0     0    NA  1412    NA    NA    NA  1412    NA    NA     0    NA     0    NA    NA    NA
 [210]    NA     0     0    NA    NA    NA    NA    NA    NA  1100    NA     0     0     0    NA    NA     0    NA    NA
 [229]    NA    NA    NA   700     0     0    NA    NA     0    NA     0     0     0   800    NA     0     0    NA   300
 [248]   300     0    NA    NA     0  3130     0     0     0    NA    NA  1380     0    NA     0    NA    NA   800    NA
 [267]     0     0    NA    NA    NA     0    NA    NA     0    NA     0    NA  1412    NA    NA    NA     0     0     0
 [286]     0     0    NA     0    NA    NA     0     0     0     0     0    NA    NA     0    NA    NA    NA    NA    NA
 [305]    NA    NA  1800    NA    NA    NA    NA    NA    NA     0    NA     0    NA    NA     0     0    NA     0    NA
 [324]     0     0    NA    NA   375    NA    NA     0   800    NA     0     0     0    NA    NA    NA     0    NA     0
 [343]     0     0    NA    NA    NA    NA    NA     0     0     0 12000    NA     0    NA     0    NA  1302    NA  1302
 [362]    NA     0    NA     0     0    NA     0  4700    NA    NA   111     0     0     0     0  1100     0    NA    NA
 [381]     0    NA    NA    NA     0    NA    NA     0     0     0    NA    NA     0     0   600   750     0     0     0
 [400]     0    NA  2824    NA  1320     0    NA     0   700     0  1400    NA  2824     0    NA     0  1320     0    NA
 [419]   600     0     0     0     0     0    NA    NA     0    NA     0     0     0     0    NA    NA    NA    NA    NA
 [438]    NA    NA     0    NA     0    NA    NA     0    NA    NA   650    NA     0  1412    NA    NA  7400     0    NA
 [457]     0     0     0 10000    NA     0     0    NA    NA     0    NA    NA    NA 26000     0     0    NA    NA    NA
 [476]    NA    NA    NA     0    NA    NA    NA     0     0     0     0   400    NA     0     0    NA   650     0     0
 [495]   600     0     0    NA    NA     0   250    NA     0    NA    NA     0    NA    NA     0     0    NA     0  7000
 [514]     0    NA     0     0     0    NA    NA    NA    NA     0     0     0    NA    NA    NA    NA    NA    NA     0
 [533]     0     0     0   112    NA    NA    NA    NA    NA     0     0    NA    NA    NA    NA     0     0  1412    NA
 [552]  1284     0     0     0     0     0    NA     0     0    NA    NA     0    NA     0    NA    NA    NA    NA     0
 [571]  8000    NA    NA  3000    NA    NA    NA    NA    NA     0    NA    NA    NA  8000    NA     0    NA     0    NA
 [590]     0  7100    NA    NA     0    NA     0     0    NA    NA     0  1662    NA     0     0    NA    NA     0    NA
 [609]     0    NA   650     0   675     0     0    NA    NA    NA     0     0   650     0     0    NA  5000    NA    NA
 [628]    NA  1320     0 11000    NA  8000    NA 15000     0     0     0    NA   100     0    NA     0    NA   590    NA
 [647]     0  2000     0    NA    NA    NA    NA    NA    NA    NA    NA    NA     0     0  1320    NA    NA     0    NA
 [666] 11000     0     0   880    NA     0     0     0     0    NA    NA     0     0    NA     0    NA    NA    NA    NA
 [685]   800  3500     0     0    NA    NA     0    NA    NA     0     0    NA     0     0    NA    NA    NA   400     0
 [704]    NA     0     0    NA     0    NA    NA     0     0    NA   600   500     0   490    NA    NA    NA     0     0
 [723]    NA    NA    NA   650     0    NA   600     0     0  2000    NA    NA     0    NA     0     0     0     0    NA
 [742]  1320   800    NA     0     0  2000     0  1252     0     0     0     0    NA    NA    NA     0    NA    NA    NA
 [761]    NA    NA    NA 23600    NA     0     0    NA     0     0     0  1412  1662    NA     0    NA 15000     0     0
 [780]    NA    NA    NA     0    NA  1712    NA    NA     0     0     0    NA    NA    NA    NA     0    NA    NA    NA
 [799]    NA    NA     0    NA  2500    NA    NA    NA     0     0    NA   550     0     0    NA    NA    NA     0   800
 [818]   500     0  1320  3200     0     0    NA    NA    NA     0     0    NA    NA    NA     0     0     0   600     0
 [837]     0     0     0     0    NA    NA     0     0    NA     0    NA    NA    NA     0     0    NA    NA     0     0
 [856]     0     0    NA     0    NA     0    NA    NA     0    NA    NA    NA     0   600     0     0     0     0     0
 [875]  1400     0     0     0    NA    NA     0     0    NA    NA     0     0 21910 18300    NA     0     0     0    NA
 [894]    NA    NA    NA    NA    NA    NA   325    NA    NA  1412    NA    NA     0     0    NA    NA     0     0    NA
 [913]    NA     0     0    NA    NA    NA     0     0     0     0  2824   600     0     0   250     0  1000    NA     0
 [932]     0     0     0    NA    NA     0     0     0    NA    NA    NA    NA    NA    NA    NA    NA   250     0     0
 [951]     0     0    NA   700     0     0    NA     0    NA     0    NA    NA     0     0    NA    NA     0     0    NA
 [970]    NA    NA    NA     0     0     0  1400     0    NA     0    NA    NA    NA    NA    NA    NA     0  1320  5000
 [989]     0     0    NA     0     0     0    NA    NA    NA    NA    NA     0
 [ reached getOption("max.print") -- omitted 54784 entries ]
demanda_idade_strata3 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(#e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_renda=case_when(renda_ind<3*salariominimo~"0-3SM",
                                       renda_ind<5*salariominimo~"3-5SM",
                                       renda_ind>5*salariominimo~"5+SM",
                                       #renda_ind<salariominimo~"maior4SM",
                                       #       TRUE~"Não Sabe / Não se Aplica"
                                       )) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_renda) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata3 <-
  merge(demanda_idade_strata3, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_renda,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA strata_renda demanda_ajustada   demanda taxa_chefia  pop_chefe pop_total
  idade_24_29          DF        0-3SM         12212.96  43868.39   0.2784000   75125.59  269847.7
  idade_24_29          DF        3-5SM               NA        NA   0.2784000   75125.59  269847.7
  idade_24_29          DF         5+SM               NA        NA   0.2784000   75125.59  269847.7
  idade_24_29          DF         <NA>         19931.69  71593.70   0.2784000   75125.59  269847.7
  idade_30_39          DF        0-3SM         11984.86  27662.92   0.4332464  203635.50  470022.4
  idade_30_39          DF        3-5SM               NA        NA   0.4332464  203635.50  470022.4
  idade_30_39          DF         5+SM               NA        NA   0.4332464  203635.50  470022.4
  idade_30_39          DF         <NA>         24309.92  56111.07   0.4332464  203635.50  470022.4
  idade_40_64          DF        0-3SM         10912.93  20295.14   0.5377117  500393.82  930598.7
  idade_40_64          DF        3-5SM               NA        NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         5+SM               NA        NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         <NA>         18984.45  35306.01   0.5377117  500393.82  930598.7
        Total           -            -         98336.81 254837.22   4.9974323 3116619.64 6681875.3
demanda_idade_strata3 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(#e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_renda=case_when(renda_ind<salariominimo~"0-1SM",
                                       renda_ind<3*salariominimo~"1-3SM",
                                       renda_ind>3*salariominimo~"5+SM",
                                       #renda_ind<salariominimo~"maior4SM",
                                       #       TRUE~"Não Sabe / Não se Aplica"
                                       )) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_renda) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata3 <-
  merge(demanda_idade_strata3, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_renda,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA strata_renda demanda_ajustada    demanda taxa_chefia  pop_chefe pop_total
  idade_24_29          DF        0-1SM       11374.9619  40858.339   0.2784000   75125.59  269847.7
  idade_24_29          DF        1-3SM         837.9994   3010.055   0.2784000   75125.59  269847.7
  idade_24_29          DF         5+SM               NA         NA   0.2784000   75125.59  269847.7
  idade_24_29          DF         <NA>       19931.6857  71593.696   0.2784000   75125.59  269847.7
  idade_30_39          DF        0-1SM       11228.6490  25917.469   0.4332464  203635.50  470022.4
  idade_30_39          DF        1-3SM         756.2090   1745.448   0.4332464  203635.50  470022.4
  idade_30_39          DF         5+SM               NA         NA   0.4332464  203635.50  470022.4
  idade_30_39          DF         <NA>       24309.9170  56111.070   0.4332464  203635.50  470022.4
  idade_40_64          DF        0-1SM        7997.8674  14873.895   0.5377117  500393.82  930598.7
  idade_40_64          DF        1-3SM        2915.0652   5421.242   0.5377117  500393.82  930598.7
  idade_40_64          DF         5+SM               NA         NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         <NA>       18984.4531  35306.008   0.5377117  500393.82  930598.7
        Total           -            -       98336.8078 254837.222   4.9974323 3116619.64 6681875.3

Renda Domiciliar

pdad2023_original$renda_domiciliar
   [1]     0    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
  [20]    NA    NA    NA    NA    NA  7000  7000   600     0     0     0    NA    NA    NA     0     0    NA    NA    NA
  [39]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA     0     0   800   800   800
  [58]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
  [77]    NA  1412  1412  1412  1412    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
  [96]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  1400    NA    NA    NA
 [115]  2262    NA    NA    NA  1412    NA    NA    NA   600    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [134]    NA  7100  7100    NA    NA    NA    NA    NA     0     0    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [153]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  3600   250   250    NA  1400  1400
 [172]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  2020  2020  2020  2020
 [191]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  2824  2824  1320    NA
 [210]    NA    NA    NA    NA  1600  1600  1600  1600    NA    NA  2000  2000  2000  2000  2000    NA    NA    NA  1412
 [229]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [248]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [267]   700   700   700    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  1320    NA    NA    NA    NA    NA
 [286]    NA    NA    NA    NA    NA    NA  3130  3130  3130  3130    NA    NA    NA    NA    NA    NA   650   650  2850
 [305]  2850    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [324]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA 20000    NA    NA    NA    NA  3424  3424  3424
 [343]    NA    NA    NA    NA    NA    NA    NA  3960  3960  3960     0     0     0    NA    NA    NA    NA    NA    NA
 [362]    NA    NA    NA    NA    NA    NA  2130  2130    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA     0
 [381]    NA    NA    NA    NA    NA  5000    NA    NA  3290  3290  3290  3290    NA    NA    NA    NA    NA    NA    NA
 [400]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA     0    NA    NA    NA
 [419]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  1412  1412    NA    NA    NA    NA
 [438]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  1400  1400  1400
 [457]    NA    NA    NA    NA    NA    NA  1100  1100  1100  1100  1100  1100    NA    NA    NA    NA    NA    NA    NA
 [476]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  4686  4686  4686    NA  1350  1350  1350
 [495]  1350  1350  1350    NA    NA    NA    NA     0  2824    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [514]    NA  2100  2100  2100    NA  2824  2824    NA    NA    NA    NA    NA   600   600   600   600   600   600    NA
 [533]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [552]    NA    NA  4260  4260    NA    NA    NA    NA  1412    NA    NA    NA    NA    NA    NA  1320  1320  1320    NA
 [571]    NA    NA    NA  3000  3000     0    NA    NA    NA    NA    NA    NA     0    NA    NA    NA    NA    NA    NA
 [590]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [609]    NA    NA    NA    NA    NA   600   600   600   600  2824  2824  2824    NA    NA    NA    NA    NA    NA    NA
 [628]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  7000  7000    NA    NA    NA    NA    NA    NA
 [647]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [666]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  3000  3000  3000    NA    NA  1284  1284
 [685]  1284  1284  1284  1284 20000    NA    NA    NA 10500 10500    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [704]    NA    NA    NA    NA    NA    NA    NA    NA  1650  1650    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [723]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [742]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA   675   675   675    NA    NA    NA
 [761]    NA    NA    NA    NA    NA   650   650     0    NA    NA    NA    NA    NA  1320  1320    NA    NA    NA    NA
 [780] 15000 15000 15000 15000    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [799]    NA    NA    NA    NA    NA    NA    NA  1320    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [818]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA     0    NA    NA    NA    NA    NA  4300  4300  4300
 [837]  4300    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [856]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [875]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [894]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA  2000  2000  1252  1252     0     0
 [913]     0    NA    NA    NA    NA    NA    NA  5000    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [932]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [951]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
 [970]    NA    NA    NA    NA    NA    NA    NA   550   550   550    NA    NA    NA    NA  1300  1300  1320  1320    NA
 [989]    NA    NA    NA    NA    NA    NA    NA    NA     0     0    NA    NA
 [ reached getOption("max.print") -- omitted 68542 entries ]
demanda_idade_strata3 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(#e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_renda=case_when(renda_domiciliar<salariominimo~"0-1SM",
                                       renda_domiciliar<3*salariominimo~"1-3SM",
                                       renda_domiciliar>3*salariominimo~"5+SM",
                                       #renda_ind<salariominimo~"maior4SM",
                                       #       TRUE~"Não Sabe / Não se Aplica"
                                       )) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_renda) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata3 <-
  merge(demanda_idade_strata3, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_renda,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA strata_renda demanda_ajustada    demanda taxa_chefia  pop_chefe pop_total
  idade_24_29          DF        0-1SM        1168.3608   4196.698   0.2784000   75125.59  269847.7
  idade_24_29          DF        1-3SM         963.0143   3459.103   0.2784000   75125.59  269847.7
  idade_24_29          DF         5+SM               NA         NA   0.2784000   75125.59  269847.7
  idade_24_29          DF         <NA>       29767.1942 106922.389   0.2784000   75125.59  269847.7
  idade_30_39          DF        0-1SM        1345.3357   3105.244   0.4332464  203635.50  470022.4
  idade_30_39          DF        1-3SM        1500.3282   3462.991   0.4332464  203635.50  470022.4
  idade_30_39          DF         5+SM               NA         NA   0.4332464  203635.50  470022.4
  idade_30_39          DF         <NA>       33158.0506  76533.938   0.4332464  203635.50  470022.4
  idade_40_64          DF        0-1SM         655.2037   1218.504   0.5377117  500393.82  930598.7
  idade_40_64          DF        1-3SM               NA         NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         5+SM               NA         NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         <NA>       27615.7421  51357.898   0.5377117  500393.82  930598.7
        Total           -            -       96173.2296 250256.765   4.9974323 3116619.64 6681875.3
demanda_idade_strata3 <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(#e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_renda=case_when(renda_ind<salariominimo~"0-1SM",
                                       renda_ind<3*salariominimo~"1-3SM",
                                       renda_ind>3*salariominimo~"5+SM",
                                       #renda_ind<salariominimo~"maior4SM",
                                       #       TRUE~"Não Sabe / Não se Aplica"
                                       )) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_etario, grupo_pdadA,strata_renda) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF")

demanda_idade_strata3 <-
  merge(demanda_idade_strata3, taxa_chefia_groupo_A,
by = c("grupo_etario", "grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_etario,grupo_pdadA,strata_renda,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata3 %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_etario grupo_pdadA strata_renda demanda_ajustada    demanda taxa_chefia  pop_chefe pop_total
  idade_24_29          DF        0-1SM       11374.9619  40858.339   0.2784000   75125.59  269847.7
  idade_24_29          DF        1-3SM         837.9994   3010.055   0.2784000   75125.59  269847.7
  idade_24_29          DF         5+SM               NA         NA   0.2784000   75125.59  269847.7
  idade_24_29          DF         <NA>       19931.6857  71593.696   0.2784000   75125.59  269847.7
  idade_30_39          DF        0-1SM       11228.6490  25917.469   0.4332464  203635.50  470022.4
  idade_30_39          DF        1-3SM         756.2090   1745.448   0.4332464  203635.50  470022.4
  idade_30_39          DF         5+SM               NA         NA   0.4332464  203635.50  470022.4
  idade_30_39          DF         <NA>       24309.9170  56111.070   0.4332464  203635.50  470022.4
  idade_40_64          DF        0-1SM        7997.8674  14873.895   0.5377117  500393.82  930598.7
  idade_40_64          DF        1-3SM        2915.0652   5421.242   0.5377117  500393.82  930598.7
  idade_40_64          DF         5+SM               NA         NA   0.5377117  500393.82  930598.7
  idade_40_64          DF         <NA>       18984.4531  35306.008   0.5377117  500393.82  930598.7
        Total           -            -       98336.8078 254837.222   4.9974323 3116619.64 6681875.3

###sem grupo etário

#pdad2023$e07#Estado civil
demanda_idade_strata2_total <- amostra_mor %>%#Filtra apenas observações com demanda positiva
  srvyr::filter(e07<6,
                demanda > 0 & !(e04 %in% c(1:3)),!grupo_etario=="Outro") %>%#Cria variável binária: adulto entre 24 e 64 anos, que não é cônjuge nem chefe de casal
  srvyr::mutate(demanda_ind = ifelse(idade %in% c(24:64) & conj_casal == 0, 1, 0),
                strata_escolaridade=case_when(escolaridade==1~"Sem instrução",
                                              escolaridade==2~"Fundamental incompleto ou equivalente",
                                              escolaridade==3~"Fundamental completo ou equivalente",
                                              escolaridade==4~"Médio incompleto ou equivalente",
                                              escolaridade==5~"Médio completo ou equivalente",
                                              escolaridade==6~"Superior incompleto ou equivalente",
                                              escolaridade==7~"Superior completo ",
                                              escolaridade==8~"Sem classificação",
                                              TRUE~"Não Sabe / Não se Aplica")) %>%#Classifica faixas etárias de interesse
  srvyr::group_by(grupo_pdadA,strata_escolaridade) %>%
  srvyr::summarise(demanda = survey_total(demanda_ind, vartype = c("cv", "ci"), na.rm = TRUE)) %>%
  as.data.frame() %>%  #Converte para data.frame e aplica filtro de precisão
  mutate(demanda=ifelse(demanda_cv>params$cv_max,NA,demanda))
demanda_idade_strata2_total %>% filter(grupo_pdadA=="DF")

demanda_idade_strata2_total <-
  merge(demanda_idade_strata2_total, taxa_chefia_groupo_A_total,
by = c("grupo_pdadA")) %>% 
  mutate(demanda_ajustada = demanda * taxa_chefia) %>% select(grupo_pdadA,strata_escolaridade,demanda_ajustada,demanda,taxa_chefia,pop_chefe,pop_total)
demanda_idade_strata2_total %>% filter(grupo_pdadA=="DF") %>% adorn_totals()
 grupo_pdadA                   strata_escolaridade demanda_ajustada    demanda taxa_chefia pop_chefe pop_total
          DF   Fundamental completo ou equivalente         3313.338   7103.630   0.4664289  779154.9   1670469
          DF Fundamental incompleto ou equivalente         9313.591  19967.870   0.4664289  779154.9   1670469
          DF         Médio completo ou equivalente        35637.186  76404.329   0.4664289  779154.9   1670469
          DF       Médio incompleto ou equivalente         5287.205  11335.501   0.4664289  779154.9   1670469
          DF                     Sem classificação         6006.581  12877.806   0.4664289  779154.9   1670469
          DF                         Sem instrução         1343.304   2879.975   0.4664289  779154.9   1670469
          DF                    Superior completo         43468.027  93193.256   0.4664289  779154.9   1670469
          DF    Superior incompleto ou equivalente        14879.448  31900.785   0.4664289  779154.9   1670469
       Total                                     -       119248.680 255663.153   3.7314311 6233239.3  13363751

Intenção de formar novo domicílio particular nos próximos 12 meses

###Por grupo Etário

demanda_idade_strata2 %>% filter(grupo_pdadA=="DF") %>% filter(!strata_mudança=="Não Sabe / Não se Aplica") %>% 
  select(grupo_etario,grupo_pdadA,strata_mudança, demanda_ajustada) %>% 
  spread(strata_mudança, demanda_ajustada) %>%  adorn_totals(where = "row") %>%   
  mutate(percentual = (sim/(sim+Não))*100)  
 grupo_etario grupo_pdadA      Não      sim percentual
  idade_24_29          DF 13259.93 17799.33   57.30765
  idade_30_39          DF 12203.76 22324.02   64.65524
  idade_40_64          DF 14236.68 14432.66   50.34180
        Total           - 39700.37 54556.02   57.88044

Intenção de formar novo domicílio particular nos próximos 12 meses Destino

demanda_idade_strata2 %>% filter(grupo_pdadA=="DF") %>% #filter(!is.na(demanda_ajustada)) %>%
  adorn_totals()
 grupo_etario grupo_pdadA                     destino demanda_ajustada   demanda taxa_chefia   pop_chefe  pop_total
  idade_24_29          DF     Na Região Adminstrativa         530.8859  1906.918   0.2784000    75125.59   269847.7
  idade_24_29          DF                Plano Piloto               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                        Gama               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Taguatinga               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Sobradinho               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Planaltina               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF          Núcleo Bandeirante               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                   Ceilândia               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                       Guará               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                    Cruzeiro               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                   Samambaia               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                 Santa Maria               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF               São Sebastião               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF            Recanto Das Emas               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                    Lago Sul               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                Riacho Fundo               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Lago Norte               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                Águas Claras               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF             Riacho Fundo II               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF        Sudoeste e Octogonal               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                      Varjão               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF               Sobradinho II               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF             Jardim Botânico               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                      Itapoã               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF               Vicente Pires               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Arniqueira               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                No município               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF       Águas Lindas de Goiás               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                  Planaltina               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF Santo Antônio do Descoberto               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF  Outros municípios de Goiás               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF                       Goiás               NA        NA   0.2784000    75125.59   269847.7
  idade_24_29          DF            Distrito Federal        2615.7508  9395.656   0.2784000    75125.59   269847.7
  idade_30_39          DF     Na Região Adminstrativa               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                Plano Piloto               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                        Gama               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                  Taguatinga               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                  Brazlândia               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                  Sobradinho               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF          Núcleo Bandeirante               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                   Ceilândia               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                       Guará               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                   Samambaia               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF               São Sebastião               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF            Recanto Das Emas               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                Riacho Fundo               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                Águas Claras               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF             Riacho Fundo II               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                      Itapoã               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF               Vicente Pires               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                      Fercal               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF       Águas Lindas de Goiás               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                   Novo Gama               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF         Valparaíso de Goiás               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF  Outros municípios de Goiás               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF                       Goiás               NA        NA   0.4332464   203635.50   470022.4
  idade_30_39          DF            Distrito Federal        3704.3359  8550.183   0.4332464   203635.50   470022.4
  idade_40_64          DF     Na Região Adminstrativa               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                Plano Piloto               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                        Gama               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                  Taguatinga               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                  Sobradinho               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                  Planaltina               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                       Guará               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                   Samambaia               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF               São Sebastião               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                Águas Claras               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF             Riacho Fundo II               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF               Vicente Pires               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                      Fercal               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF       Águas Lindas de Goiás               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                  Planaltina               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF         Valparaíso de Goiás               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF  Outros municípios de Goiás               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF                       Goiás               NA        NA   0.5377117   500393.82   930598.7
  idade_40_64          DF            Distrito Federal        1933.8511  3596.446   0.5377117   500393.82   930598.7
        Total           -                           -        8784.8237 23449.204  29.8016352 16873879.14 37866887.0
LS0tDQp0aXRsZTogIkRlbWFuZGEgSGFiaXRhY2lvbmFsIG5vIERpc3RyaXRvIEZlZGVyYWwg4oCTIFJlbGF0w7NyaW8gRXN0aW1hdGl2YSBBbW9zdHJhbCINCmF1dGhvcjogIklQRURGL0RFUEFUIOKAlCBUaGlhZ28gTi4gR2FyZGluIg0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRoZW1lOiBqb3VybmFsDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQpwYXJhbXM6DQogIGFub19wZGFkOiAyMDI1DQogIGFycXVpdm9fcGRhZDogInBkYWQyMDI0b3V0LmNzdiIgICAgIyBhanVzdGUgcGFyYSAyMDI1IHF1YW5kbyBkaXNwb27DrXZlbA0KICBkaWNfZG9tOiAiRGljX0RvbS5jc3YiDQogIGRpY19tb3I6ICJEaWNfbW9yLmNzdiINCiAgZ3J1cG9fbGFiZWxzOiBbIkRGIiwiUE1CIiwiw4FyZWEgUnVyYWwiXQ0KICBjdl9tYXg6IDAuMjUNCg0KLS0tDQojIDEuIEFwcmVzZW50YcOnw6NvDQpFc3RlIHJlbGF0w7NyaW8gZXN0aW1hIGEgZGVtYW5kYSBoYWJpdGFjaW9uYWwgcG90ZW5jaWFsIG5vIERpc3RyaXRvIEZlZGVyYWwgYSBwYXJ0aXIgZGEgUERBRCwgdXRpbGl6YW5kbyBleHBhbnPDo28gYW1vc3RyYWwgY29tIGRlc2VuaG8gY29tcGxleG8gKGVzdHJhdG9zLCBjb25nbG9tZXJhZG9zIGUgcGVzb3MpLiBBcyBlc3RpbWF0aXZhcyBzw6NvIGFwcmVzZW50YWRhcyBjb20gbWVkaWRhcyBkZSBpbmNlcnRlemEgKGVycm8tcGFkcsOjbywgSUMgZSBDVikgZSBwdWJsaWNhZGFzIHNvbWVudGUgcXVhbmRvIG8gQ1Yg4omkIDI1JS4NCk9zIG1pY3JvZGFkb3Mgc8OjbyBwYWRyb25pemFkb3MgKG5vbWVzLCB0aXBvcyBlIHLDs3R1bG9zKSwgaGFybW9uaXphbW9zIGPDs2RpZ29zIGRlIFJBL1BNQi/DgXJlYSBSdXJhbCBlIGRlcml2YW1vcyB2YXJpw6F2ZWlzIGRlIGludGVyZXNzZSAoaWRhZGUsIGNvbmRpw6fDo28gbm8gZG9taWPDrWxpbywgZ3J1cG9zIGV0w6FyaW9zLCBpbmRpY2Fkb3JlcyBkZSBkZW1hbmRhKS4gUmVncmFzIGRlIHF1YWxpZGFkZSB2ZXJpZmljYW0gY2hhdmVzIChkb21pY8OtbGlvL3Blc3NvYSksIGR1cGxpY2lkYWRlcyBlIGNvZXLDqm5jaWEgZG8gZGVzZW5obyBhbW9zdHJhbC4NCkVzdGltYW1vczogDQooaSkgdGF4YSBkZSBjaGVmaWEgcG9yIGZhaXhhIGV0w6FyaWEgZSBncnVwbyB0ZXJyaXRvcmlhbDsgDQooaWkpIHF1YW50aWRhZGUgZGUgYWR1bHRvcyBwb3RlbmNpYWxtZW50ZSBkZW1hbmRhbnRlcyAoMjTigJM2NCBhbm9zLCBuw6NvIHJlc3BvbnPDoXZlaXMgbmVtIGPDtG5qdWdlcywgc29iIHJlZ3JhcyBmYW1pbGlhcmVzKTsgZSANCihpaWkpIGRlbWFuZGEgZmluYWwgY29tbyBwcm9kdXRvIGRhIGRlbWFuZGEgcG90ZW5jaWFsIHBlbGEgdGF4YSBkZSBjaGVmaWEgZGEgcmVzcGVjdGl2YSBmYWl4YS4NCg0KUmVzdWx0YWRvcyBzw6NvIGVzdHJhdGlmaWNhZG9zIHBvciBncnVwbyB0ZXJyaXRvcmlhbCAoREYsIFBNQiwgw4FyZWEgUnVyYWwpIGUsIHF1YW5kbyBhIHByZWNpc8OjbyBwZXJtaXRlLCBwb3IgUmVnacOjbyBBZG1pbmlzdHJhdGl2YSAoUkEpIGUgZmFpeGFzIGV0w6FyaWFzICgyNOKAkzI5LCAzMOKAkzM5LCA0MOKAkzY0KS4gQ8OpbHVsYXMgY29tIENWIGFsdG8gc8OjbyBzdXByaW1pZGFzIChOQSkgZSwgc2UgbmVjZXNzw6FyaW8sIGFncmVnYWRhcy4NCg0KIyAyLiBQcmVwYXJhw6fDo28gZG8gQW1iaWVudGUNCg0KIyMgMi4xIOKAlCBDQVJSRUdBTUVOVE8gREUgUEFDT1RFUyBFIENPTkZJR1VSQcOHw4NPIERPIEFNQklFTlRFDQoNCkVzdGUgYmxvY28gcHJlcGFyYSBvIGFtYmllbnRlIGRlIGV4ZWN1w6fDo28sIGdhcmFudGluZG86DQoNCiAtIGluc3RhbGHDp8OjbyBlIGNhcnJlZ2FtZW50byBkb3MgcGFjb3RlcyBuZWNlc3PDoXJpb3M7DQogLSBkZWZpbmnDp8OjbyBkZSBwYXLDom1ldHJvcyBkbyBwcm9qZXRvIChhbm8sIGNhbWluaG9zLCBsaW1pdGVzIGRlIENWKTsNCiAtIHBhZHJvbml6YcOnw6NvIGRlIG9ww6fDtWVzIGdsb2JhaXMgZGUgZXhpYmnDp8OjbyBlIGFycmVkb25kYW1lbnRvLg0KDQpgYGB7cn0NCg0KDQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoInBhY21hbiIsIHF1aWV0bHkgPSBUUlVFKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCg0KIyBDYXJyZWdhIG9zIHByaW5jaXBhaXMgcGFjb3RlcyB1dGlsaXphZG9zIG5vIHJlbGF0w7NyaW8uDQoNCiMgQSBmdW7Dp8OjbyBwYWNtYW46OnBfbG9hZCgpIGluc3RhbGEgYXV0b21hdGljYW1lbnRlIG8gcGFjb3RlIGNhc28gbsOjbyBlc3RlamEgcHJlc2VudGUuDQoNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgICAgIyBNYW5pcHVsYcOnw6NvIGUgdmlzdWFsaXphw6fDo28gZGUgZGFkb3MNCiAgICAgICAgICAgICAgIGRhdGEudGFibGUsICAgIyBMZWl0dXJhIGUgb3BlcmHDp8O1ZXMgZWZpY2llbnRlcyBjb20gZ3JhbmRlcyBiYXNlcw0KICAgICAgICAgICAgICAgamFuaXRvciwgICAgICAjIFBhZHJvbml6YcOnw6NvIGRlIG5vbWVzIGUgbGltcGV6YSBkZSB0YWJlbGFzDQogICAgICAgICAgICAgICBzdHJpbmdyLCAgICAgICMgTWFuaXB1bGHDp8OjbyBkZSBzdHJpbmdzICh0ZXh0bykNCiAgICAgICAgICAgICAgIGx1YnJpZGF0ZSwgICAgIyBNYW5pcHVsYcOnw6NvIGRlIGRhdGFzDQogICAgICAgICAgICAgICBzdXJ2ZXksICAgICAgICMgRGVzZW5obyBlIGFuw6FsaXNlIGRlIGRhZG9zIGFtb3N0cmFpcyBjb21wbGV4b3MNCiAgICAgICAgICAgICAgIHNydnlyLCAgICAgICAgIyBJbnRlcmZhY2UgdGlkeSBwYXJhIG8gcGFjb3RlIHN1cnZleQ0KICAgICAgICAgICAgICAgZ3QsICAgICAgICAgICAjIEdlcmHDp8OjbyBkZSB0YWJlbGFzIGZvcm1hdGFkYXMNCiAgICAgICAgICAgICAgIHNjYWxlcywgICAgICAgIyBFc2NhbGFzIG51bcOpcmljYXMgZSByb3R1bGFnZW0gcGFyYSBncsOhZmljb3MNCiAgICAgICAgICAgICAgIHJlYWRyLCAgICAgICAgIyBMZWl0dXJhIGRlIGFycXVpdm9zIENTVg0KICAgICAgICAgICAgICAgcmVhZHhsLCAgICAgICAjIExlaXR1cmEgZGUgcGxhbmlsaGFzIEV4Y2VsDQogICAgICAgICAgICAgICBnbHVlICAgICAgICAgICMgQ29uc3RydcOnw6NvIGRpbsOibWljYSBkZSB0ZXh0b3MgZSBleHByZXNzw7Vlcw0KKQ0KDQpgYGANCiMgRGVmaW5lIG9ww6fDtWVzIGdsb2JhaXMgZG8gUiBNYXJrZG93bjoNCg0KLSAgc2NpcGVuID0gOTk5IGV2aXRhIG5vdGHDp8OjbyBjaWVudMOtZmljYSAoZXguOiAxZSswNSDihpIgMTAwMDAwKQ0KLSBkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0Ugc3VwcmltZSBtZW5zYWdlbnMgZG8gZHBseXINCmBgYHtyfQ0KDQoNCm9wdGlvbnMoDQpzY2lwZW4gPSA5OTksDQpkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UNCikNCmBgYA0KDQoNCiMjIDIuMiDigJQgREVGSU5Jw4fDg08gREUgUEFSw4JNRVRST1MgR0xPQkFJUyBETyBSRUxBVMOTUklPDQoNCg0KIEFxdWkgZGVmaW5pbW9zIHRvZG9zIG9zIHBhcsOibWV0cm9zIHF1ZSBjb250cm9sYW0gYSBleGVjdcOnw6NvOg0KDQogLSBjYW1pbmhvcyBkZSBhcnF1aXZvcyAoZGFkb3MgZSBkaWNpb27DoXJpb3MpOw0KDQogLSBwYXLDom1ldHJvcyBhbW9zdHJhaXMgKENWIG3DoXhpbW8gcGVybWl0aWRvKTsNCg0KIC0gZmFpeGFzIGV0w6FyaWFzIGUgYW5vIGRlIHJlZmVyw6puY2lhLg0KDQpFc3RlcyBwYXLDom1ldHJvcyBwb2RlbSBzZXIgYWx0ZXJhZG9zIHNlbSBtZXhlciBubyBjb3JwbyBkbyByZWxhdMOzcmlvLg0KYGBge3J9DQoNCg0KcGFyYW1zIDwtIGxpc3QoDQpzYWxhcmlvbWluaW1vID0gMTMwMiwgICAgICAgICAgICAgICAgICAjIFNhbMOhcmlvIG3DrW5pbW8gdmlnZW50ZQ0KYW5vX3BkYWQgICA9IDIwMjUsICAgICAgICAgICAgICAgICAgICAgICMgQW5vIGRlIHJlZmVyw6puY2lhIGRhIHBlc3F1aXNhDQphcnF1aXZvX3BkYWQgPSAiL2RhdGEvcGRhZDIwMjRvdXQuY3N2IiwgICAgIyBDYW1pbmhvIGRvIGFycXVpdm8gcHJpbmNpcGFsIGRhIFBEQUQNCmRpY19kb20gICAgPSAiL2RhdGEvZGljaW9uYXJpb19kb20uY3N2IiwgIyBDYW1pbmhvIGRvIGRpY2lvbsOhcmlvIGRlIGRvbWljw61saW9zDQpkaWNfbW9yICAgID0gIi9kYXRhL2RpY2lvbmFyaW9fbW9yLmNzdiIsICMgQ2FtaW5obyBkbyBkaWNpb27DoXJpbyBkZSBtb3JhZG9yZXMNCmN2X21heCAgICAgPSAwLjI1ICAgICAgICAgICAgICAgICAgICAgICMgQ29lZmljaWVudGUgZGUgdmFyaWHDp8OjbyBtw6F4aW1vIGFjZWl0byAoMjUlKQ0KKQ0Kc2FsYXJpb21pbmltbzwtMTMwMg0KYGBgDQoNCiMjIDIuMyDigJQgQ1JJQcOHw4NPIERFIERJUkVUw5NSSU9TIChPUENJT05BTCkNCkVzdGUgdHJlY2hvIGNyaWEgYXV0b21hdGljYW1lbnRlIGFzIHBhc3RhcyBvbmRlIG9zIGRhZG9zIGUgc2HDrWRhcw0KZG8gcmVsYXTDs3JpbyBzZXLDo28gYXJtYXplbmFkb3MsIGV2aXRhbmRvIGVycm9zIGRlIGNhbWluaG8gaW5leGlzdGVudGUuDQoNCg0KYGBge3J9DQoNCg0KI2lmICghZGlyLmV4aXN0cygiZGF0YSIpKSBkaXIuY3JlYXRlKCJkYXRhIikNCiNpZiAoIWRpci5leGlzdHMoIm91dHB1dCIpKSBkaXIuY3JlYXRlKCJvdXRwdXQiKQ0KDQpgYGANCiMjICAyLjQg4oCUIFZFUklGSUNBw4fDg08gSU5JQ0lBTCBETyBBTUJJRU5URQ0KVmVyaWZpY2Egc2Ugb3MgcGFjb3RlcyBlc3NlbmNpYWlzIGVzdMOjbyBjYXJyZWdhZG9zIGUgaW1wcmltZQ0KdW1hIG1lbnNhZ2VtIGRlIGNvbmZpcm1hw6fDo28gbm8gY29uc29sZS4NCmBgYHtyfQ0KcGFjb3Rlc19lc3NlbmNpYWlzIDwtIGMoInRpZHl2ZXJzZSIsICJzdXJ2ZXkiLCAic3J2eXIiLCAiZ3QiKQ0KcGFjb3Rlc19mYWx0YW5kbyA8LSBwYWNvdGVzX2Vzc2VuY2lhaXNbIXNhcHBseShwYWNvdGVzX2Vzc2VuY2lhaXMsIHJlcXVpcmVOYW1lc3BhY2UsIHF1aWV0bHkgPSBUUlVFKV0NCmBgYA0KIyMgMi41IOKAlCBJTVBPUlRBw4fDg08gRE9TIERBRE9TDQpFc3RlIGJsb2NvIHJlYWxpemEgYSBsZWl0dXJhIGRvcyBtaWNyb2RhZG9zIGRhIFBEQUQgZSBkb3MgZGljaW9uw6FyaW9zDQpkZSBkb21pY8OtbGlvcyBlIG1vcmFkb3JlcywgYXBsaWNhbmRvIGxpbXBlemEgYsOhc2ljYSAobm9tZXMgY29uc2lzdGVudGVzKS4NCg0KTGVpdHVyYSBkb3MgZGljaW9uw6FyaW9zIChlc3RydXR1cmEgZGFzIHZhcmnDoXZlaXMpDQpgYGB7cn0NCmRpY19kb20gPC0gcmVhZHI6OnJlYWRfY3N2KHBhcmFtcyRkaWNfZG9tLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSB8Pmphbml0b3I6OmNsZWFuX25hbWVzKCkNCmRpY19tb3IgPC0gcmVhZHI6OnJlYWRfY3N2KHBhcmFtcyRkaWNfbW9yLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSB8Pmphbml0b3I6OmNsZWFuX25hbWVzKCkNCnBkYWQyMDIzIDwtIHJlYWRyOjpyZWFkX2NzdihwYXJhbXMkYXJxdWl2b19wZGFkLCBzaG93X2NvbF90eXBlcyA9IEZBTFNFKSB8Pmphbml0b3I6OmNsZWFuX25hbWVzKCkjTGVpdHVyYSBkb3MgbWljcm9kYWRvcyBkYSBQREFEDQoNCmBgYA0KDQoNCg0KDQojIDMuIFByZXBhcmHDp8OjbyBkb3MgRGFkb3M6IENyaWHDp8OjbyBkZSBWYXJpw6F2ZWlzIERlcml2YWRhcw0KDQpFc3RlIGJsb2NvIHRlbSBwb3Igb2JqZXRpdm8gcHJlcGFyYXIgZSBhanVzdGFyIG9zIG1pY3JvZGFkb3MgZGEgUERBRCBwYXJhIG8gY8OhbGN1bG8gZGEgZGVtYW5kYSBoYWJpdGFjaW9uYWwgY29tIGJhc2UgbmEgdGF4YSBkZSBjaGVmaWEgdHJhZGljaW9uYWwsIGlzdG8gw6ksIGNvbnNpZGVyYW5kbyB0b2RvcyBvcyBjaGVmZXMgZGUgZG9taWPDrWxpbyBkYSBmYWl4YSBldMOhcmlhIGRlIDI0IGEgNjQgYW5vcy4NCkFzIGV0YXBhcyBpbmNsdWVtIGEgaGFybW9uaXphw6fDo28gZGFzIGJhc2VzIGRlIG1vcmFkb3JlcyBlIGRvbWljw61saW9zLCBhIGNyaWHDp8OjbyBkZSB2YXJpw6F2ZWlzIGRlcml2YWRhcyBlIGEgaWRlbnRpZmljYcOnw6NvIGRvcyBhcnJhbmpvcyBmYW1pbGlhcmVzIHF1ZSBjb25maWd1cmFtIG91IG7Do28gZGVtYW5kYSBoYWJpdGFjaW9uYWwuDQoNCg0KIyMgMy4xIOKAlCBBanVzdGVzIGRlIElkZW50aWZpY2HDp8OjbyBlIENyaWHDp8OjbyBkZSBWYXJpw6F2ZWlzIGRlIENvbnRleHRvDQoNCkVzdGUgYmxvY28gaGFybW9uaXphIHZhcmnDoXZlaXMgYsOhc2ljYXMgZGEgUERBRCwgY29tbyBVRiwgUkEgZSBjw7NkaWdvcyBkZSBkb21pY8OtbGlvLCBwYXJhIHBlcm1pdGlyIGEgY2xhc3NpZmljYcOnw6NvIHRlcnJpdG9yaWFsIGUgZmFtaWxpYXIgZG9zIHJlZ2lzdHJvcy4NCg0KYGBge3J9DQpwZGFkMjAyMyRVRltwZGFkMjAyMyRhMDF1Zj09NTJdPC0iUE1CIg0KcGRhZDIwMjMkVUZbcGRhZDIwMjMkYTAxdWY9PTUzXTwtIkRGIg0KcGRhZDIwMjMkVUYgfD4gdGFibGUoKQ0KYGBgDQpJbmNsdXPDo28gZGUgZGVzY3Jpw6fDtWVzIGRlIGxvY2FsaWRhZGUgYSBwYXJ0aXIgZG8gZGljaW9uw6FyaW8gZGUgZG9taWPDrWxpb3MNCg0KYGBge3J9DQojZGljX2RvbSB8PiBmaWx0ZXIoc3RyX2RldGVjdChjb2x1bmEsImxvY2EiKSkNCnBkYWQyMDIzIHw+DQpsZWZ0X2pvaW4oZGljX2RvbSB8PiBmaWx0ZXIoY29sdW5hPT0ibG9jYWxpZGFkZSIpIHw+IG11dGF0ZShzdHJhdGFfbG9jYWxpZGFkZT1kZXNjX3ZhbG9yKSB8PiBzZWxlY3QoLWNvbHVuYSwtZGVzY19jb2x1bmEsLWRlc2NfdmFsb3IpLGJ5PWMoImxvY2FsaWRhZGUiPSJ2YWxvciIpKS0+cGRhZDIwMjMNCmBgYA0KDQpDcmlhw6fDo28gZSBwYWRyb25pemHDp8OjbyBkZSB2YXJpw6F2ZWlzIGRlcml2YWRhcw0KDQpgYGB7cn0NCnBkYWQyMDIzJGlkYWRlPC1wZGFkMjAyMyRpZGFkZV9jYWxjdWxhZGENCnBkYWQyMDIzJEEwMW5maWNoYTwtcGRhZDIwMjMkZmljaGENCnBkYWQyMDIzJFJBX25vbWU8LXBkYWQyMDIzJHN0cmF0YV9sb2NhbGlkYWRlDQpwZGFkMjAyMzwtcGRhZDIwMjMgJT4lIG11dGF0ZShncnVwb19wZGFkQT1jYXNlX3doZW4oUkFfbm9tZT09IsOBcmVhIFJ1cmFsIn4iw4FyZWEgUnVyYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVGPT0iREYifiJERiIsVFJVRX5VRikpDQpgYGANCg0KY29udGFnZW0gZGUgcGVzc29hcyBubyBkb21pY8OtbGlvIChBMDFucGVzc29hcykNCg0KYGBge3J9DQpwZGFkMjAyMyAlPiUgc2VsZWN0KGZpY2hhLG1vcmFkb3JfaWQpICU+JQ0KICBtdXRhdGUobl9tb3JhZG9yPWFzLm51bWVyaWMoc3RyX3JlbW92ZShtb3JhZG9yX2lkLHBhc3RlMChmaWNoYSwiLSIpKSkpICU+JQ0KICBncm91cF9ieShmaWNoYSkgJT4lc3VtbWFyaXNlKEEwMW5wZXNzb2FzPW1heChuX21vcmFkb3IpKSAlPiUNCiAgcmlnaHRfam9pbihwZGFkMjAyMyxieT1jKCJmaWNoYSIpICktPnBkYWQyMDIzDQpgYGANCg0KDQojIyAzLjMg4oCUIEZpbHRyYWdlbSBkYSBQb3B1bGHDp8OjbyBkZSBJbnRlcmVzc2UNCg0KTmVzdGEgZXRhcGEsIHJlc3RyaW5nZS1zZSBhIGJhc2UgYXBlbmFzIGFvcyBkb21pY8OtbGlvcyBjdWpvIHJlc3BvbnPDoXZlbCB0ZW0gZW50cmUgMjQgZSA2NCBhbm9zLCBmYWl4YSBjb25zaWRlcmFkYSBlY29ub21pY2FtZW50ZSBhdGl2YSBlIGZvY28gZGEgYW7DoWxpc2UgZGEgZGVtYW5kYSBoYWJpdGFjaW9uYWwuDQoNCkRlaXhhciBhcGVuYXMgb3MgZG9taWPDrWxpb3MvbW9yYWRvcmVzIG9uZGUgbyByZXNwb25zw6F2ZWwgdGVtIGVudHJlIDI0IGUgNjQgYW5vcy4NCg0KYGBge3J9DQpwZGFkMjAyM19vcmlnaW5hbCA8LSBwZGFkMjAyMw0KcGRhZDIwMjMgPC1zdWJzZXQocGRhZDIwMjMsZmljaGEgJWluJSBzdWJzZXQocGRhZDIwMjMsIGUwNCA9PSAxICYgaWRhZGVfY2FsY3VsYWRhICVpbiUgYygyNDo2NCkpJGZpY2hhKQ0KYGBgDQpDYXNvIGRlc2VqYS1zZSBpZ25vcmFyIGVzc2EgcmVncmEgb3JkYXIgZXNzYSBhbHRlcm5hdGl2YToNCmBgYHtyfQ0KI3BkYWQyMDIzX29yaWdpbmFsIDwtIHBkYWQyMDIzDQpgYGANCg0KIyMgMy40IOKAlCBJZGVudGlmaWNhw6fDo28gZG9zIERvbWljw61saW9zIGNvbSBEZW1hbmRhIEhhYml0YWNpb25hbA0KDQpOZXN0YSBzdWJzZcOnw6NvIGluaWNpYS1zZSBhIGlkZW50aWZpY2HDp8OjbyBkb3MgYXJyYW5qb3MgZmFtaWxpYXJlcywgYSBwYXJ0aXIgZGEgY3JpYcOnw6NvIGRhIHZhcmnDoXZlbCBtYXRyaXpfZmFtaWxpYXIsIHF1ZSBhZ3J1cGEgaW5mb3JtYcOnw7VlcyBwb3IgdGlwbyBkZSBtZW1icm8gKHJlc3BvbnPDoXZlbCwgY8O0bmp1Z2UsIGZpbGhvLCBldGMuKS4NCg0KDQpgYGB7cn0NCm1hdHJpel9mYW1pbGlhciA8LSBwZGFkMjAyMyAlPiUgDQogICMgc2VsZWN0KEEwMW5maWNoYSwgQTAxbnBlc3NvYXMsIGUwNCwgaWRhZGUpICU+JSANCiAgbXV0YXRlKGNvbmRpY2FvID0gMSwgDQogICAgICAgICBlMDRfZWRpdCA9IGNhc2Vfd2hlbihlMDQgPT0gMSB+ICdyZXNwb25zYXZlbCcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDIgfiAnY29uanVnZScsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDMgfiAnY29uanVnZScsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDQgJiBpZGFkZSA8IDI0IH4gJ2ZpbGhvX21lbm9yMjQnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSA1ICYgaWRhZGUgPCAyNCB+ICdmaWxob19tZW5vcjI0JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSA2ICYgaWRhZGUgPCAyNCB+ICdmaWxob19tZW5vcjI0JyAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDQgJiBpZGFkZSA+PTI0IH4gJ2ZpbGhvX21haW9yMjQnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSA1ICYgaWRhZGUgPj0yNCB+ICdmaWxob19tYWlvcjI0JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSA2ICYgaWRhZGUgPj0yNCB+ICdmaWxob19tYWlvcjI0JywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gNyB+ICdnZW5yb19ub3JhJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gOCB+ICdwYWlzJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gOSB+ICdzb2dyb3MnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSAxMCB+ICduZXRvJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gMTEgfiAnYmlzbmV0bycsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDEyIH4gJ2lybWFvJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gMTMgfiAnYXZvcycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gMTQgfiAnb3V0cm9fcGFyZW50ZScsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDE1IH4gJ2FncmVnYWRvJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSAxNiB+ICdjb252aXZlbnRlJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDQgPT0gMTcgfiAncGVuc2lvbmlzdGEnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA0ID09IDE4IH4gJ2VtcHJlZ2Fkb19kb21lc3RpY28nLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNCA9PSAxOSB+ICdwYXJlbnRlX2VtcHJlZ2FkbycpKSAlPiUgDQogIGdyb3VwX2J5KEEwMW5maWNoYSwgQTAxbnBlc3NvYXMsDQogICAgICAgICAgIGUwNF9lZGl0KSAlPiUgDQogIHN1bW1hcmlzZShuID0gc3VtKGNvbmRpY2FvKSkgJT4lICANCiAgc3ByZWFkKGUwNF9lZGl0LCBuKQ0KYGBgDQoNCiMjIDMuNSDigJQgSW5jbHVzw6NvIGRlIEluZGljYWRvcmVzIGRlIElkb3NvcyBlIEFkdWx0b3MNCk5lc3RhIGZhc2Ugc8OjbyBjcmlhZGFzIHZhcmnDoXZlaXMgYXV4aWxpYXJlcyBxdWUgaW5kaWNhbToNCg0KLSBwcmVzZW7Dp2EgZGUgaWRvc29zICg2NSspIG5vIGRvbWljw61saW87DQotIHByZXNlbsOnYSBkZSBhZHVsdG9zICgyNOKAkzY0KTsNCi0gZSBzZSBlc3RlcyBzw6NvIHJlc3BvbnPDoXZlaXMgb3UgY8O0bmp1Z2VzLg0KDQpFc3NhcyB2YXJpw6F2ZWlzIHPDo28gY3J1Y2lhaXMgcGFyYSBkZXRlcm1pbmFyIHF1YW5kbyBvIGRvbWljw61saW8gZ2VyYSBvdSBuw6NvIGRlbWFuZGEuDQoNCkNyaWFyIHZhcmnDoXZlbCBpbmRpY2Fkb3JhIGRlIGlkb3NvIG5vIGRvbWljw61saW8NCmBgYHtyfQ0KcGRhZDIwMjMkaWRvc28gPC0gaWZlbHNlKHBkYWQyMDIzJGlkYWRlID49IDY1LCAxLCAwKQ0KDQptYXRyaXpfaWRvc29zIDwtDQogIGFzLmRhdGEuZnJhbWUodGFibGUocGRhZDIwMjMkQTAxbmZpY2hhLCBwZGFkMjAyMyRpZG9zbykpDQoNCnBkYWQyMDIzJGlkb3NvIDwtIE5VTEwNCg0KbWF0cml6X2lkb3NvcyRpZG9zb3MgPC0NCiAgYXMubnVtZXJpYyhsZXZlbHMobWF0cml6X2lkb3NvcyRWYXIyKSlbbWF0cml6X2lkb3NvcyRWYXIyXSAqIG1hdHJpel9pZG9zb3MkRnJlcQ0KDQpuYW1lcyhtYXRyaXpfaWRvc29zKVsxXSA8LSAiQTAxbmZpY2hhIg0KDQptYXRyaXpfaWRvc29zIDwtIHN1YnNldChtYXRyaXpfaWRvc29zLCBpZG9zb3MgPiAwKQ0KDQptYXRyaXpfZmFtaWxpYXIgPC0NCiAgbWVyZ2UobWF0cml6X2ZhbWlsaWFyLA0KICAgICAgICBtYXRyaXpfaWRvc29zLA0KICAgICAgICBieSA9ICJBMDFuZmljaGEiLA0KICAgICAgICBhbGwueCA9IFRSVUUpDQoNCiNybShtYXRyaXpfaWRvc29zKQ0KYGBgDQoNCkluZGljYWRvcmEgc2UgbyBpZG9zbyDDqSByZXNwb25zw6F2ZWwgb3UgY8O0bmp1Z2UNCg0KYGBge3J9DQptYXRyaXpfZmFtaWxpYXIkaWRvc29fY29uaiA8LQ0KICBpZmVsc2UoDQogICAgbWF0cml6X2ZhbWlsaWFyJEEwMW5maWNoYSAlaW4lIHN1YnNldChwZGFkMjAyMywgZTA0ICVpbiUgYygyLCAzKSAmDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkYWRlID49IDY1KSRBMDFuZmljaGEsDQogICAgMSwNCiAgICAwDQogICkNCmBgYA0KDQpDcmlhw6fDo28gZGUgdmFyacOhdmVsIGluZGljYWRvcmEgZGUgYWR1bHRvICgyNOKAkzY0IGFub3MpDQoNCmBgYHtyfQ0KcGRhZDIwMjMkYWR1bHRvIDwtDQogIGlmZWxzZShwZGFkMjAyMyRpZGFkZSA+PSAyNCAmIHBkYWQyMDIzJGlkYWRlIDwgNjUsIDEsIDApDQoNCm1hdHJpel9hZHVsdG8gPC0NCiAgYXMuZGF0YS5mcmFtZSh0YWJsZShwZGFkMjAyMyRBMDFuZmljaGEsIHBkYWQyMDIzJGFkdWx0bykpDQoNCnBkYWQyMDIzJGFkdWx0byA8LSBOVUxMDQoNCm1hdHJpel9hZHVsdG8kYWR1bHRvIDwtDQogIGFzLm51bWVyaWMobGV2ZWxzKG1hdHJpel9hZHVsdG8kVmFyMikpW21hdHJpel9hZHVsdG8kVmFyMl0gKiBtYXRyaXpfYWR1bHRvJEZyZXENCg0KbmFtZXMobWF0cml6X2FkdWx0bylbMV0gPC0gIkEwMW5maWNoYSINCg0KbWF0cml6X2FkdWx0byA8LSBzdWJzZXQobWF0cml6X2FkdWx0bywgYWR1bHRvID4gMCkNCg0KbWF0cml6X2ZhbWlsaWFyIDwtDQogIG1lcmdlKG1hdHJpel9mYW1pbGlhciwNCiAgICAgICAgbWF0cml6X2FkdWx0bywNCiAgICAgICAgYnkgPSAiQTAxbmZpY2hhIiwNCiAgICAgICAgYWxsLnggPSBUUlVFKQ0KDQojcm0obWF0cml6X2FkdWx0bykNCmBgYA0KDQoNCklkZW50aWZpY2HDp8OjbyBkZSBhZHVsdG9zIHJlc3BvbnPDoXZlaXMgZSBjw7RuanVnZXMNCg0KYGBge3J9DQptYXRyaXpfZmFtaWxpYXIkYWR1bHRvX3Jlc3AgPC0NCiAgaWZlbHNlKA0KICAgIG1hdHJpel9mYW1pbGlhciRBMDFuZmljaGEgJWluJSBzdWJzZXQocGRhZDIwMjMsIGUwNCA9PSAxICYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRhZGUgPj0gMjQgJiBpZGFkZSA8IDY1KSRBMDFuZmljaGEsDQogICAgMSwNCiAgICAwDQogICkNCm1hdHJpel9mYW1pbGlhciAlPiUgZ3JvdXBfYnkoYWR1bHRvX3Jlc3ApICU+JSBzdW1tYXJpc2Uobj1uKCkpICMjIyB0b2RvcyBvcyBkb21pY2lsaW9zIHRlbSBhZHVsdG9zIGNvbW8gcmVzcG9uc2F2ZWlzIHBlbG8gZG9taWNpbGlvDQptYXRyaXpfZmFtaWxpYXIkYWR1bHRvX2NvbmogPC0NCiAgaWZlbHNlKA0KICAgIG1hdHJpel9mYW1pbGlhciRBMDFuZmljaGEgJWluJSBzdWJzZXQocGRhZDIwMjMsIGUwNCAlaW4lIGMoMiwgMykgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGFkZSA+PSAyNCAmIGlkYWRlIDwgNjUpJEEwMW5maWNoYSwNCiAgICAxLA0KICAgIDANCiAgKQ0KDQojbWF0cml6X2ZhbWlsaWFyICU+JSBncm91cF9ieShhZHVsdG9fY29uaikgJT4lIHN1bW1hcmlzZShuPW4oKSkgIyMjIHRvZG9zIG9zIGRvbWljaWxpb3MgdGVtIGFkdWx0b3MgY29tbyByZXNwb25zYXZlaXMgcGVsbyBkb21pY2lsaW8NCg0KYGBgDQoNCg0KDQoNCiMjIDMuNiDigJQgQ8OhbGN1bG8gZGEgRGVtYW5kYSBIYWJpdGFjaW9uYWwgbm8gRG9taWPDrWxpbw0KDQpBcXVpIHPDo28gYXBsaWNhZGFzIGFzIHJlZ3JhcyBxdWUgZGV0ZXJtaW5hbSBzZSBvIGRvbWljw61saW8gZ2VyYSBkZW1hbmRhOg0KDQpuw6NvIGjDoSBkZW1hbmRhIHF1YW5kbyBvIGRvbWljw61saW8gY29udMOpbSBhcGVuYXMgbyByZXNwb25zw6F2ZWwsIGPDtG5qdWdlLCBmaWxob3MgbWVub3JlcyBlIGlkb3NvczsNCg0KaMOhIGRlbWFuZGEgcXVhbmRvIGV4aXN0ZW0gYWR1bHRvcyBhZGljaW9uYWlzICgyNOKAkzY0IGFub3MpIHF1ZSBuw6NvIHPDo28gcmVzcG9uc8OhdmVpcyBuZW0gY8O0bmp1Z2VzLg0KDQoNCklkZW50aWZpY2HDp8OjbyBkZSBkb21pY8OtbGlvcyBzZW0gZGVtYW5kYQ0KYGBge3J9DQojIGZpbGhvcyBtZW5vcmVzIGRlIDI0IGFub3MgZSBpZG9zb3MuDQptYXRyaXpfZmFtaWxpYXIkZGVtYW5kYSA8LSBOQQ0KbWF0cml6X2ZhbWlsaWFyJGRlbWFuZGEgPC0NCiAgaWZlbHNlKCgoDQogICAgcm93U3VtcyhtYXRyaXpfZmFtaWxpYXJbLCBjKCJyZXNwb25zYXZlbCIsICJjb25qdWdlIiwgImZpbGhvX21lbm9yMjQiLCAiaWRvc29zIildLCBuYS5ybSA9VFJVRSkgDQogICAgLSAobWF0cml6X2ZhbWlsaWFyWywgYygiaWRvc29fY29uaiIpXSkNCiAgKSA9PSBtYXRyaXpfZmFtaWxpYXIkQTAxbnBlc3NvYXMpID09IFRSVUUsDQogIDAsDQogIG1hdHJpel9mYW1pbGlhciRkZW1hbmRhKQ0KDQptYXRyaXpfZmFtaWxpYXIkZGVtYW5kYSAlPiUgdGFibGUoKQ0KYGBgDQoNCk7Dum1lcm8gZGUgcGVzc29hcyBubyBkb21pY8OtbGlvIHF1ZSBkZW1hbmRhbSBoYWJpdGHDp8OjbyAtIGkuZSB0ZW0gcGVzc29hcyBlbnRyZSAyNCBlIDY0IGFub3MgcXVlIG7Do28gc8OjbyByZXNwb25zw6F2ZWlzIG91IGPDtG5qdWdlcy4NCg0KYGBge3J9DQptYXRyaXpfZmFtaWxpYXIkZGVtYW5kYSA8LQ0KICBpZmVsc2UoKG1hdHJpel9mYW1pbGlhciRBMDFucGVzc29hcyAtICgNCiAgICByb3dTdW1zKG1hdHJpel9mYW1pbGlhclssIGMoInJlc3BvbnNhdmVsIiwgImNvbmp1Z2UiLCAiZmlsaG9fbWVub3IyNCIsICJpZG9zb3MiKV0sIG5hLnJtID0NCiAgICAgICAgICAgICAgVFJVRSkgLSAobWF0cml6X2ZhbWlsaWFyWywgYygiaWRvc29fY29uaiIpXSkNCiAgKSkgPiAwLA0KICAoDQogICAgbWF0cml6X2ZhbWlsaWFyJGFkdWx0byAtIHJvd1N1bXMobWF0cml6X2ZhbWlsaWFyWywgYygiYWR1bHRvX3Jlc3AiLCAiYWR1bHRvX2NvbmoiKV0sIG5hLnJtID0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUpDQogICksDQogIG1hdHJpel9mYW1pbGlhciRkZW1hbmRhDQogICkNCmBgYA0KDQojIyAzLjcg4oCUIElkZW50aWZpY2HDp8OjbyBkZSBDYXNhaXMgRXNwZWPDrWZpY29zDQoNCg0KRXN0ZSBibG9jbyByZWZpbmEgb3MgY2Fzb3MgZGUgY2FzYWlzIGVzcGVjaWFpcyAocGFpcywgYXbDs3MsIHNvZ3JvcywgZ2Vucm9zL25vcmFzIGUgZmlsaG9zIGFkdWx0b3MpLCBxdWUgZGVtYW5kYW0gcmVncmFzIGRpZmVyZW5jaWFkYXMgbmEgaWRlbnRpZmljYcOnw6NvIGRlIGNoZWZlcyBlIGPDtG5qdWdlcy4NCk8gb2JqZXRpdm8gw6kgZXZpdGFyIGR1cGxhIGNvbnRhZ2VtIGRlIGRlbWFuZGEgb3UgaW1wdXRhw6fDo28gaW5kZXZpZGEuDQoNCg0KDQpDYXNhaXMgZGUgYXbDs3MsIHBhaXMgZSBzb2dyb3MNCmBgYHtyfQ0KbWF0cml6X2ZhbWlsaWFyJGNhc2FsX2F2b3MgPC0gaWZlbHNlKG1hdHJpel9mYW1pbGlhciRhdm9zID09IDIsIDEsIE5BKQ0KbWF0cml6X2ZhbWlsaWFyJGNhc2FsX3BhaXMgPC0gaWZlbHNlKG1hdHJpel9mYW1pbGlhciRwYWlzID09IDIsIDEsIE5BKQ0KbWF0cml6X2ZhbWlsaWFyJGNhc2FsX3NvZ3JvcyA8LSBpZmVsc2UobWF0cml6X2ZhbWlsaWFyJHNvZ3JvcyA9PSAyLCAxLCBOQSkNCg0KYGBgDQoNCg0KDQoNCiMjIDMuOCDigJQgSWRlbnRpZmljYcOnw6NvIGUgQ2xhc3NpZmljYcOnw6NvIGRvcyBDYXNhaXMNCg0KTmVzdGEgZXRhcGEsIGlkZW50aWZpY2FtLXNlIGRpZmVyZW50ZXMgdGlwb3MgZGUgY2FzYWlzIHByZXNlbnRlcyBub3MgZG9taWPDrWxpb3MgKGF2w7NzLCBzb2dyb3MsIHBhaXMgZSBmaWxob3MgLyBnZW5yb3MgLyBub3JhcykuDQpPIG9iamV0aXZvIMOpIGRldGVybWluYXIgY29ycmV0YW1lbnRlIHF1ZW0gw6kgbyBjaGVmZSBkbyBjYXNhbCBlIHNldSBjw7RuanVnZSwgZXZpdGFuZG8gZHVwbGEgY29udGFnZW0gb3UgYXRyaWJ1acOnw6NvIGluY29ycmV0YSBkZSBkZW1hbmRhLg0KDQpBIGluZGljYcOnw6NvIGRhIGV4aXN0w6puY2lhIGRlIGNhc2FsIGRlIGZpbGhvcyDDqSBhIHByw7NwcmlhIHZhcmnDoXZlbCBkZSBnZW5yby9ub3JhLg0KRmF6LXNlIHBhcmEgY2FkYSB0aXBvIGRlIGNhc2FsIHNlcGFyYWRvIHBvcnF1ZSBwb2RlIGhhdmVyIG1haXMgZGUgdW0gdGlwbyBkZSBjYXNhbCBwb3IgZG9taWPDrWxpby4NClNlcGFyYS1zZSBvcyBpbmRpdsOtZHVvcyBkZSBjYWRhIGNhc2FsIHBhcmEgY2FsY3VsYXIgYSBpZGFkZSBtw6F4aW1hICh1dGlsaXphZGEgcGFyYSBpZGVudGlmaWNhciBvIGNoZWZlKS4NCg0KYGBge3J9DQppZGFkZV9jYXNhbF9hdm9zIDwtDQogIHN1YnNldCgNCiAgICBwZGFkMjAyMywNCiAgICBBMDFuZmljaGEgJWluJSBzdWJzZXQobWF0cml6X2ZhbWlsaWFyLCBjYXNhbF9hdm9zID09IDEgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwKSRBMDFuZmljaGEpICU+JQ0KICBzdWJzZXQoZTA0ID09IDEzKQ0KDQppZGFkZV9jYXNhbF9zb2dyb3MgPC0NCiAgc3Vic2V0KA0KICAgIHBkYWQyMDIzLA0KICAgIEEwMW5maWNoYSAlaW4lIHN1YnNldChtYXRyaXpfZmFtaWxpYXIsIGNhc2FsX3NvZ3JvcyA9PSAxICYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCkkQTAxbmZpY2hhKSAlPiUNCiAgc3Vic2V0KGUwNCA9PSA5KQ0KDQppZGFkZV9jYXNhbF9wYWlzIDwtDQogIHN1YnNldCgNCiAgICBwZGFkMjAyMywNCiAgICBBMDFuZmljaGEgJWluJSBzdWJzZXQobWF0cml6X2ZhbWlsaWFyLCBjYXNhbF9wYWlzID09IDEgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwKSRBMDFuZmljaGEpICU+JQ0KICBzdWJzZXQoZTA0ID09IDgpDQpgYGANCg0KIyMgMy45IOKAlCBEZXRlcm1pbmHDp8OjbyBkbyBDaGVmZSBkbyBDYXNhbCBwb3IgVGlwbyBkZSBQYXJlbnRlc2NvDQoNCkFxdWkgY2FsY3VsYS1zZSBhIGlkYWRlIGRvIGPDtG5qdWdlIG1haXMgdmVsaG8gcGFyYSBpZGVudGlmaWNhciBvIGNoZWZlIGRlIGNhZGEgY2FzYWwuDQpBIHJlZ3JhIGRlZmluZSBvIGNoZWZlIGNvbW8gbyBpbmRpdsOtZHVvIG1haXMgdmVsaG8gZG8gcGFyOyBlbSBjYXNvIGRlIGVtcGF0ZSwgdXNhLXNlIG8gbWVub3IgaWRlbnRpZmljYWRvciAobW9yYWRvcl9pZCkgY29tbyBjcml0w6lyaW8gc2VjdW5kw6FyaW8uDQoNCmBgYHtyfQ0KaWRhZGVfY2FzYWxfYXZvczIgPC0gaWRhZGVfY2FzYWxfYXZvcyAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUNCiAgc3VtbWFyaXNlKGNoZWZlX2lkYWRlID0gbWF4KGlkYWRlKSkNCg0KaWRhZGVfY2FzYWxfYXZvcyA8LQ0KICBtZXJnZShpZGFkZV9jYXNhbF9hdm9zLA0KICAgICAgICBpZGFkZV9jYXNhbF9hdm9zMiwNCiAgICAgICAgYnkgPSAiQTAxbmZpY2hhIiwNCiAgICAgICAgYWxsLnggPSBUUlVFKQ0KDQppZGFkZV9jYXNhbF9hdm9zIDwtIGlkYWRlX2Nhc2FsX2F2b3MgJT4lDQogIGdyb3VwX2J5KEEwMW5maWNoYSkgJT4lDQogIG11dGF0ZShjaGVmZV9pZCA9IGlmZWxzZShzdW0oaWRhZGUpIC8gMiA9PSBjaGVmZV9pZGFkZSxtaW4obW9yYWRvcl9pZCksaWZlbHNlKGlkYWRlID09IGNoZWZlX2lkYWRlLCBtb3JhZG9yX2lkLCAwKSkpICU+JQ0KICBtdXRhdGUoY2hlZmVfY2FzYWwgPSBpZmVsc2UobW9yYWRvcl9pZCA9PSBjaGVmZV9pZCwgMSwgMCkpICU+JQ0KICBtdXRhdGUoY29ual9jYXNhbCA9IGlmZWxzZShtb3JhZG9yX2lkICE9IGNoZWZlX2lkLCAxLCAwKSkNCiNybShpZGFkZV9jYXNhbF9hdm9zMikNCg0KaWRhZGVfY2FzYWxfc29ncm9zMiA8LSBpZGFkZV9jYXNhbF9zb2dyb3MgJT4lIA0KICBncm91cF9ieShBMDFuZmljaGEpICU+JSANCiAgc3VtbWFyaXNlKGNoZWZlX2lkYWRlID0gbWF4KGlkYWRlKSkNCg0KaWRhZGVfY2FzYWxfc29ncm9zIDwtDQogIG1lcmdlKGlkYWRlX2Nhc2FsX3NvZ3JvcywNCiAgICAgICAgaWRhZGVfY2FzYWxfc29ncm9zMiwNCiAgICAgICAgYnkgPSAiQTAxbmZpY2hhIiwNCiAgICAgICAgYWxsLnggPSBUUlVFKQ0KDQppZGFkZV9jYXNhbF9zb2dyb3MgPC0gaWRhZGVfY2FzYWxfc29ncm9zICU+JQ0KICBncm91cF9ieShBMDFuZmljaGEpICU+JQ0KICBtdXRhdGUoY2hlZmVfaWQgPSBpZmVsc2Uoc3VtKGlkYWRlKSAvIDIgPT0gY2hlZmVfaWRhZGUsbWluKG1vcmFkb3JfaWQpLGlmZWxzZShpZGFkZSA9PSBjaGVmZV9pZGFkZSwgbW9yYWRvcl9pZCwgMCkpKSAlPiUNCiAgbXV0YXRlKGNoZWZlX2Nhc2FsID0gaWZlbHNlKG1vcmFkb3JfaWQgPT0gY2hlZmVfaWQsIDEsIDApKSAlPiUNCiAgbXV0YXRlKGNvbmpfY2FzYWwgPSBpZmVsc2UobW9yYWRvcl9pZCAhPSBjaGVmZV9pZCwgMSwgMCkpDQojcm0oaWRhZGVfY2FzYWxfc29ncm9zMikNCg0KaWRhZGVfY2FzYWxfcGFpczIgPC0gaWRhZGVfY2FzYWxfcGFpcyAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUNCiAgc3VtbWFyaXNlKGNoZWZlX2lkYWRlID0gbWF4KGlkYWRlKSkNCg0KaWRhZGVfY2FzYWxfcGFpcyA8LQ0KICBtZXJnZShpZGFkZV9jYXNhbF9wYWlzLA0KICAgICAgICBpZGFkZV9jYXNhbF9wYWlzMiwNCiAgICAgICAgYnkgPSAiQTAxbmZpY2hhIiwNCiAgICAgICAgYWxsLnggPSBUUlVFKQ0KDQppZGFkZV9jYXNhbF9wYWlzIDwtIGlkYWRlX2Nhc2FsX3BhaXMgJT4lDQogIGdyb3VwX2J5KEEwMW5maWNoYSkgJT4lDQogIG11dGF0ZShjaGVmZV9pZCA9IGlmZWxzZShzdW0oaWRhZGUpIC8gMiA9PSBjaGVmZV9pZGFkZSxtaW4obW9yYWRvcl9pZCksaWZlbHNlKGlkYWRlID09IGNoZWZlX2lkYWRlLCBtb3JhZG9yX2lkLCAwKSkpICU+JQ0KICBtdXRhdGUoY2hlZmVfY2FzYWwgPSBpZmVsc2UobW9yYWRvcl9pZCA9PSBjaGVmZV9pZCwgMSwgMCkpICU+JQ0KICBtdXRhdGUoY29ual9jYXNhbCA9IGlmZWxzZShtb3JhZG9yX2lkICE9IGNoZWZlX2lkLCAxLCAwKSkNCiNybShpZGFkZV9jYXNhbF9wYWlzMikNCg0KYGBgDQoNCg0KIyMgMy4xMCDigJQgQ2FzYWlzIEZvcm1hZG9zIHBvciBGaWxob3MsIEdlbnJvcyBvdSBOb3Jhcw0KDQpBcyBwcsOzeGltYXMgZXRhcGFzIGxpZGFtIGNvbSBhcnJhbmpvcyBlbSBxdWUgZmlsaG9zIGFkdWx0b3MgZSBnZW5yb3Mvbm9yYXMgY29tcMO1ZW0gbm92b3MgbsO6Y2xlb3MgZmFtaWxpYXJlcyBkZW50cm8gZG8gZG9taWPDrWxpby4NCkNhZGEgY2FzbyDDqSB0cmF0YWRvIHNlcGFyYWRhbWVudGUsIGNvbmZvcm1lIGEgcXVhbnRpZGFkZSBkZSBmaWxob3MgYWR1bHRvcyBlIG8gdGlwbyBkZSB2w61uY3Vsby4NCg0KYGBge3J9DQojIENBU08gMSDigJQgR2Vucm8vbm9yYSBjb20gYXBlbmFzIHVtKGEpIGZpbGhvKGEpIGFkdWx0byhhKSAo4omlMjQgYW5vcykNCg0KaWRhZGVfY2FzYWxfZmlsaG9zMDEgPC0NCiAgc3Vic2V0KA0KICAgIHBkYWQyMDIzLA0KICAgIEEwMW5maWNoYSAlaW4lIHN1YnNldChtYXRyaXpfZmFtaWxpYXIsIGdlbnJvX25vcmEgPT0gMSAmIGZpbGhvX21haW9yMjQgPT0gMSwgZGVtYW5kYSA+IDApJEEwMW5maWNoYSkgJT4lDQogIHN1YnNldChlMDQgPT0gNyB8IChlMDQgJWluJSBjKDQ6NikgJiBpZGFkZSA+PSAyNCkpICMgTWFudMOpbSBhcGVuYXMgcmVnaXN0cm9zIGRvIGdlbnJvL25vcmEgKGUwND09NykgZSBkb3MgZmlsaG9zIGFkdWx0b3MgKGUwNCA0OjYsIGlkYWRl4omlMjQpDQojIENhbGN1bGEgYSBpZGFkZSBtw6F4aW1hIGRlbnRybyBkZSBjYWRhIGRvbWljw61saW8gcGFyYSBpZGVudGlmaWNhciBvIGNoZWZlIGRvIGNhc2FsDQppZGFkZV9jYXNhbF9maWxob3MwMWIgPC0gaWRhZGVfY2FzYWxfZmlsaG9zMDEgJT4lIA0KICBncm91cF9ieShBMDFuZmljaGEpICU+JSBzdW1tYXJpc2UoY2hlZmVfaWRhZGUgPSBtYXgoaWRhZGUpKQ0KIyBKdW50YSBvIHZhbG9yIGRhIGlkYWRlIG3DoXhpbWEgZGUgdm9sdGEgw6AgYmFzZSBwcmluY2lwYWwNCmlkYWRlX2Nhc2FsX2ZpbGhvczAxIDwtDQogIG1lcmdlKGlkYWRlX2Nhc2FsX2ZpbGhvczAxLA0KICAgICAgICBpZGFkZV9jYXNhbF9maWxob3MwMWIsDQogICAgICAgIGJ5ID0gIkEwMW5maWNoYSIsDQogICAgICAgIGFsbC54ID0gVFJVRSkNCiMgRGVmaW5lIG8gY2hlZmUgZG8gY2FzYWwgKG8gbWFpcyB2ZWxobykgZSBvIGPDtG5qdWdlIChvIG91dHJvIGluZGl2w61kdW8pDQppZGFkZV9jYXNhbF9maWxob3MwMSA8LSBpZGFkZV9jYXNhbF9maWxob3MwMSAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUgDQogIG11dGF0ZShjaGVmZV9pZCA9IGlmZWxzZShzdW0oaWRhZGUpIC8gMiA9PSBjaGVmZV9pZGFkZSxtaW4obW9yYWRvcl9pZCksaWZlbHNlKGlkYWRlID09IGNoZWZlX2lkYWRlLCBtb3JhZG9yX2lkLCAwKSkpICU+JSMgY2hlZmVfaWQgPSBpZCBkbyBpbmRpdsOtZHVvIG1haXMgdmVsaG87IGVtIGVtcGF0ZSwgZXNjb2xoZSBvIG1lbm9yIG1vcmFkb3JfaWQNCiAgbXV0YXRlKGNoZWZlX2Nhc2FsID0gaWZlbHNlKG1vcmFkb3JfaWQgPT0gY2hlZmVfaWQsIDEsIDApKSAlPiUNCiAgbXV0YXRlKGNvbmpfY2FzYWwgPSBpZmVsc2UobW9yYWRvcl9pZCAhPSBjaGVmZV9pZCwgMSwgMCkpDQojcm0oaWRhZGVfY2FzYWxfZmlsaG9zMDFiKQ0KYGBgDQoNCg0KYGBge3J9DQojIENBU08gMiDigJQgR2Vucm8vbm9yYSBjb20gZG9pcyBvdSBtYWlzIGZpbGhvcyBhZHVsdG9zICjiiaUyNCBhbm9zKQ0KaWRhZGVfY2FzYWxfZmlsaG9zMDIgPC0NCiAgc3Vic2V0KHBkYWQyMDIzLEEwMW5maWNoYSAlaW4lIHN1YnNldChtYXRyaXpfZmFtaWxpYXIsIGdlbnJvX25vcmEgPT0gMSAmZmlsaG9fbWFpb3IyNCA+PSAyLCBkZW1hbmRhID4gMCkkQTAxbmZpY2hhKSAlPiUgIyAjIERvbWljw61saW9zIGNvbSAxIGdlbnJvL25vcmEgZSAyIG91IG1haXMgZmlsaG9zIGFkdWx0b3MsIGNvbSBkZW1hbmRhIHBvc2l0aXZhDQogIHN1YnNldChlMDQgPT0gNyB8IChlMDQgJWluJSBjKDQ6NikgJiBpZGFkZSA+PSAyNCkpICMgTWFudMOpbSByZWdpc3Ryb3MgZGUgZ2Vucm8vbm9yYSAoZTA0PT03KSBlIGZpbGhvcyBhZHVsdG9zIChlMDQgNDo2KQ0KIyBEZW50cm8gZGVzc2VzIGRvbWljw61saW9zLCBpZGVudGlmaWNhIG8oYSkgZmlsaG8oYSkgYWR1bHRvKGEpIG1haXMgdmVsaG8oYSkNCmlkYWRlX2Nhc2FsX2ZpbGhvczAyYWQgPC0gaWRhZGVfY2FzYWxfZmlsaG9zMDIgJT4lDQogIGdyb3VwX2J5KEEwMW5maWNoYSkgJT4lDQogIGZpbHRlcihlMDQgJWluJSBjKDQ6NikpICU+JXN1bW1hcmlzZShpZGFkZV9maWxobyA9IG1heChpZGFkZSkpDQojSnVudGEgZXNzYSBpZGFkZSBtw6F4aW1hIMOgIGJhc2UgcHJpbmNpcGFsDQppZGFkZV9jYXNhbF9maWxob3MwMiA8LQ0KICBtZXJnZShpZGFkZV9jYXNhbF9maWxob3MwMiwNCiAgICAgICAgaWRhZGVfY2FzYWxfZmlsaG9zMDJhZCwNCiAgICAgICAgYnkgPSAiQTAxbmZpY2hhIiwNCiAgICAgICAgYWxsLnggPSBUUlVFKSAlPiUgICBzdWJzZXQoZTA0ID09IDcgfCBpZGFkZSA9PSBpZGFkZV9maWxobykgJT4lDQogIHN1YnNldCghKEEwMW5maWNoYSA9PSA1NzY1OCAmIG1vcmFkb3JfaWQgPT0gNCkpICMgUmV0aXJhLXNlIGVzdGUgY2FzbyBlc3BlY8OtZmljbyBlbSBxdWUgb3MgZG9pcyBmaWxob3MgbWFpcyB2ZWxob3Mgc8OjbyBnw6ptZW9zLg0KI3JtKGlkYWRlX2Nhc2FsX2ZpbGhvczAyYWQpDQoNCmlkYWRlX2Nhc2FsX2ZpbGhvczAyYiA8LSBpZGFkZV9jYXNhbF9maWxob3MwMiAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUgIHN1bW1hcmlzZShjaGVmZV9pZGFkZSA9IG1heChpZGFkZSkpDQoNCmlkYWRlX2Nhc2FsX2ZpbGhvczAyIDwtDQogIG1lcmdlKGlkYWRlX2Nhc2FsX2ZpbGhvczAyLA0KICAgICAgICBpZGFkZV9jYXNhbF9maWxob3MwMmIsDQogICAgICAgIGJ5ID0gIkEwMW5maWNoYSIsDQogICAgICAgIGFsbC54ID0gVFJVRSkNCg0KaWRhZGVfY2FzYWxfZmlsaG9zMDIgPC0gaWRhZGVfY2FzYWxfZmlsaG9zMDIgJT4lDQogIGdyb3VwX2J5KEEwMW5maWNoYSkgJT4lDQogIG11dGF0ZShjaGVmZV9pZCA9IGlmZWxzZShzdW0oaWRhZGUpIC8gMiA9PSBjaGVmZV9pZGFkZSxtaW4obW9yYWRvcl9pZCksaWZlbHNlKGlkYWRlID09IGNoZWZlX2lkYWRlLCBtb3JhZG9yX2lkLCAwKSkpICU+JQ0KICBtdXRhdGUoY2hlZmVfY2FzYWwgPSBpZmVsc2UobW9yYWRvcl9pZCA9PSBjaGVmZV9pZCwgMSwgMCkpICU+JQ0KICBtdXRhdGUoY29ual9jYXNhbCA9IGlmZWxzZShtb3JhZG9yX2lkICE9IGNoZWZlX2lkLCAxLCAwKSkNCiNybShpZGFkZV9jYXNhbF9maWxob3MwMmIpDQpgYGANCg0KDQojIyAzLjExIOKAlCBDYXNhaXMgY29tIEdlbnJvcyAvIE5vcmFzIGNvbW8gQ2hlZmVzDQoNClRyYXRhLXNlIGRvcyBjYXNvcyBlbSBxdWUgbyBnZW5ybyBvdSBub3JhIMOpIG8gY2hlZmUgZG8gbsO6Y2xlbyBmYW1pbGlhciwgZSBvIGZpbGhvIG1haXMgdmVsaG8gw6kgaWRlbnRpZmljYWRvIGNvbW8gY8O0bmp1Z2UuDQpFc3NlcyBhanVzdGVzIHBlcm1pdGVtIHJlcHJlc2VudGFyIGNvcnJldGFtZW50ZSBvIHBhcGVsIGRlIGNhZGEgaW5kaXbDrWR1byBubyBhcnJhbmpvLg0KDQoNCmBgYHtyfQ0KIyBPIGdlbnJvL25vcmEgdmFpIHNlciBvIGNoZWZlIG5lc3RlIGNhc28uIEltcHV0YW0tc2Ugb3MgZmlsaG9zIG1haXMgdmVsaG9zIGNvbW8gY8O0bmp1Z2UuDQppZGFkZV9jYXNhbF9maWxob3MwM2dlbnJvIDwtDQogIHN1YnNldCgNCiAgICBwZGFkMjAyMywNCiAgICBBMDFuZmljaGEgJWluJSBzdWJzZXQobWF0cml6X2ZhbWlsaWFyLCBnZW5yb19ub3JhID09IDIgJg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwKSRBMDFuZmljaGENCiAgKSAlPiUNCiAgc3Vic2V0KGUwNCA9PSA3KQ0KICAjIFRlbSBhbGd1bnMgY2Fzb3MgcXVlIHRlbSBkb2lzIGdlbnJvcy9ub3JhcywgZSBuw6NvIHRlbSBmaWxob3MgY29tIG1haXMgZGUgMjQgYW5vcywgYXBlbmFzIGZpbGhvcyBtZW5vcmVzLg0KaWRhZGVfY2FzYWxfZmlsaG9zMDNmaWxobyA8LQ0KICBzdWJzZXQoDQogICAgcGRhZDIwMjMsDQogICAgQTAxbmZpY2hhICVpbiUgc3Vic2V0KG1hdHJpel9mYW1pbGlhciwgZ2Vucm9fbm9yYSA9PSAyICYNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCkkQTAxbmZpY2hhDQogICkgJT4lDQogIHN1YnNldChlMDQgJWluJSBjKDQ6NikpICU+JQ0KICBhcnJhbmdlKGRlc2MoaWRhZGUpKSAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUNCiAgc2xpY2UoMToyKQ0KICAjIEp1bnRvIG9zIGRhZG9zIGRvcyBnZW5yb3MgZSBmaWxob3MuDQppZGFkZV9jYXNhbF9maWxob3MwMyA8LQ0KICByYmluZChpZGFkZV9jYXNhbF9maWxob3MwM2dlbnJvLCBpZGFkZV9jYXNhbF9maWxob3MwM2ZpbGhvKQ0KDQppZGFkZV9jYXNhbF9maWxob3MwMyA8LSBpZGFkZV9jYXNhbF9maWxob3MwMyAlPiUNCiAgZ3JvdXBfYnkoQTAxbmZpY2hhKSAlPiUNCiAgbXV0YXRlKGNoZWZlX2Nhc2FsID0gaWZlbHNlKGUwNCA9PSA3LCAxLCAwKSkgJT4lDQogIG11dGF0ZShjb25qX2Nhc2FsID0gaWZlbHNlKGUwNCAhPSA3LCAxLCAwKSkgJT4lDQogIG11dGF0ZShjaGVmZV9pZCA9IGlmZWxzZShjaGVmZV9jYXNhbCA9PSAxLCBtb3JhZG9yX2lkLCAwKSkNCg0KI3JtKGlkYWRlX2Nhc2FsX2ZpbGhvczAzZ2Vucm8sIGlkYWRlX2Nhc2FsX2ZpbGhvczAzZmlsaG8pDQpgYGANCg0KIyMgMy4xMiDigJQgSnVuw6fDo28gRmluYWwgZG9zIENhc2FpcyBlIEludGVncmHDp8OjbyBjb20gYSBCYXNlDQoNClBvciBmaW0sIHRvZG9zIG9zIGNhc2FpcyBpZGVudGlmaWNhZG9zIHPDo28gY29uc29saWRhZG9zIGVtIHVtIMO6bmljbyBvYmpldG8gKGNhc2FpcykgZSByZWluY29ycG9yYWRvcyDDoCBiYXNlIG9yaWdpbmFsIGRhIFBEQUQuDQpUYW1iw6ltIMOpIGluY29ycG9yYWRhIGEgdmFyacOhdmVsIGRlIGRlbWFuZGEgaGFiaXRhY2lvbmFsIGUgbyBlc3RyYXRvIGRlIHJlbmRhIGRvIHJlc3BvbnPDoXZlbC4NCg0KDQpgYGB7cn0NCmNhc2FpcyA8LQ0KICBiaW5kX3Jvd3MoDQogICAgI2xpc3QoDQogICAgICBpZGFkZV9jYXNhbF9hdm9zLA0KICAgICAgaWRhZGVfY2FzYWxfcGFpcywNCiAgICAgIGlkYWRlX2Nhc2FsX3NvZ3JvcywNCiAgICAgIGlkYWRlX2Nhc2FsX2ZpbGhvczAxLA0KICAgICAgaWRhZGVfY2FzYWxfZmlsaG9zMDIsDQogICAgICBpZGFkZV9jYXNhbF9maWxob3MwMw0KICAgICkNCg0KICAjIEFwZXNhciBkZSBvIG9iamV0byBzZXIgImNhc2FpcyIsIG8gbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIMOpIMOtbXBhciBwb3JxdWUgdMOqbSBjYXNhaXMgcXVlIHPDsyB0ZW0gbyBnZW5yby4NCmNhc2FpcyA8LQ0KICBjYXNhaXNbLCBjKCJBMDFuZmljaGEiLA0KICAgICAgICAgICAgICJtb3JhZG9yX2lkIiwNCiAgICAgICAgICAgICAiY2hlZmVfY2FzYWwiLA0KICAgICAgICAgICAgICJjb25qX2Nhc2FsIiwNCiAgICAgICAgICAgICAiY2hlZmVfaWQiKV0NCg0KY2FzYWlzIDwtIGFzLmRhdGEuZnJhbWUoY2FzYWlzKQ0KYGBgDQoNCkFkacOnw6NvIGRhIGluZm9ybWHDp8OjbyBzb2JyZSBjYXNhaXMgZSBkZW1hbmRhIMOgIFBEQUQNCg0KYGBge3J9DQpwZGFkMjAyM19vcmlnaW5hbCA8LQ0KICBtZXJnZSgNCiAgICBwZGFkMjAyM19vcmlnaW5hbCwNCiAgICBjYXNhaXMsDQogICAgYWxsLnggPSBUUlVFLA0KICAgIGJ5ID0gYygiQTAxbmZpY2hhIiwgIm1vcmFkb3JfaWQiKQ0KICApDQoNCnBkYWQyMDIzX29yaWdpbmFsJGNvbmpfY2FzYWwgPC0NCiAgaWZlbHNlKGlzLm5hKHBkYWQyMDIzX29yaWdpbmFsJGNvbmpfY2FzYWwpID09IFRSVUUsDQogICAgICAgICAwLA0KICAgICAgICAgcGRhZDIwMjNfb3JpZ2luYWwkY29ual9jYXNhbCkNCg0KI3BkYWQyMDIzX29yaWdpbmFsJGNvbmpfY2FzYWwgJT4lIHRhYmxlKCkNCiAgIyBKdW50YW5kbyBhcyBpbmZvcm1hw6fDtWVzIGRlIGRlbWFuZGEgaGFiaXRhY2lvbmFsIGNvbSBhIFBEQUQuDQpwZGFkMjAyM19vcmlnaW5hbCA8LQ0KICBtZXJnZShwZGFkMjAyM19vcmlnaW5hbCwNCiAgICAgICAgbWF0cml6X2ZhbWlsaWFyWywgYygiQTAxbmZpY2hhIiwgImRlbWFuZGEiKV0sDQogICAgICAgIGJ5ID0gIkEwMW5maWNoYSIsDQogICAgICAgIGFsbC54ID0gVFJVRSkNCnBkYWQyMDIzX29yaWdpbmFsJGRlbWFuZGEgJT4lIHRhYmxlKCkNCmBgYA0KDQoNCkNvbnRhYmlsaXphw6fDo28gZGEgcmVuZGEgZG8gcmVzcG9uc8OhdmVsDQoNCmBgYHtyfQ0KcGRhZF9yZW5kYSA8LSBwZGFkMjAyM19vcmlnaW5hbCAlPiUNCiAgZmlsdGVyKGUwNCA9PSAxKSAlPiUNCiAgbXV0YXRlKA0KICAgIHJlbmRhX3Jlc3AgPSBjYXNlX3doZW4oDQogICAgICByZW5kYV9pbmRfciA8PSAxMTAwIH4gImF0ZTAxU00iLA0KICAgICAgcmVuZGFfaW5kX3IgPiAxMTAwICYNCiAgICAgICAgcmVuZGFfaW5kX3IgPD0gMzMwMCB+ICIxYTNTTSIsDQogICAgICByZW5kYV9pbmRfciA+IDMzMDAgJg0KICAgICAgICByZW5kYV9pbmRfciA8PSA1NTAwIH4gIjNhNVNNIiwNCiAgICAgIHJlbmRhX2luZF9yID4gNTUwMCAmDQogICAgICAgIHJlbmRhX2luZF9yIDw9IDEzMjAwIH4gIjVhMTJTTSIsDQogICAgICByZW5kYV9pbmRfciA+IDEzMjAwIH4gIm1haXNkZTEyU00iDQogICAgKQ0KICApICU+JQ0KICBzZWxlY3QoQTAxbmZpY2hhLCByZW5kYV9yZXNwKQ0KDQojIEp1bsOnw6NvIGRvcyBkYWRvcyBkZSByZW5kYSBkb3MgcmVzcG9uc8OhdmVsIGNvbSBhcyBkZW1haXMgaW5mb3JtYcOnw7VlcyBkYSBQREFELg0KcGRhZDIwMjNfb3JpZ2luYWwgPC0NCiAgbWVyZ2UocGRhZDIwMjNfb3JpZ2luYWwsDQogICAgICAgIHBkYWRfcmVuZGEsDQogICAgICAgIGJ5ID0gIkEwMW5maWNoYSIsDQogICAgICAgIGFsbC54ID0gVFJVRSkNCmBgYA0KDQoNCmBgYHtyfQ0KDQpwZGFkMjAyM19vcmlnaW5hbCRkZW1hbmRhICU+JSB0YWJsZSgpDQoNCg0KYGBgDQoNCiMgNC4gRXhwYW5zw6NvIEFtb3N0cmFsDQoNCg0KDQpOZXN0YSBzZcOnw6NvLCBkZWNsYXJhLXNlIG8gZGVzZW5obyBhbW9zdHJhbCBjb21wbGV4byBxdWUgc2Vyw6EgdXRpbGl6YWRvIG5hIGVzdGltYcOnw6NvIGRhcyB0YXhhcyBlIHRvdGFpcyBleHBhbmRpZG9zLg0KTyBwbGFubyBjb25zaWRlcmE6DQoNCi0gaWRlbnRpZmljYcOnw6NvIGRlIGNvbmdsb21lcmFkb3MgKGZpY2hhKSwNCi0gZXN0cmF0b3MgKHNldG9yX2Rpc3RyaXRvKSwgZQ0KLSBwZXNvcyBhbW9zdHJhaXMgKHBlc29fbW9yKS4NCg0KYGBge3J9DQphbW9zdHJhX21vciA8LSANCiAgc3VydmV5OjpzdnlkZXNpZ24oaWQgPSB+ZmljaGEsDQogICAgICAgICAgICAgICAgICAgIHN0cmF0YSA9IH5zZXRvcl9kaXN0cml0bywNCiAgICAgICAgICAgICAgICAgICAgd2VpZ2h0cyA9IH5wZXNvX21vciwNCiAgICAgICAgICAgICAgICAgICAgbmVzdD1UUlVFLA0KICAgICAgICAgICAgICAgICAgICBkYXRhPXBkYWQyMDIzX29yaWdpbmFsKSANCg0KYW1vc3RyYV9tb3IgPC0gc3J2eXI6OmFzX3N1cnZleShhbW9zdHJhX21vcikgJT4lIA0KICBtdXRhdGUoZ3J1cG9fZXRhcmlvID0gY2FzZV93aGVuKGlkYWRlICVpbiUgYygyNDoyOSkgfiAiaWRhZGVfMjRfMjkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGFkZSAlaW4lIGMoMzA6MzkpIH4gImlkYWRlXzMwXzM5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRhZGUgJWluJSBjKDQwOjY0KSB+ICJpZGFkZV80MF82NCIsVFJVRX4iT3V0cm8iKSkNCmBgYA0KDQoNCg0KDQoNCiMgNS5Fc3RpbWF0aXZhIGRhIFRheGEgZGUgQ2hlZmlhDQoNCk5lc3RhIHNlw6fDo28gZXN0aW1hbW9zIGEgdGF4YSBkZSBjaGVmaWEgZGUgZG9taWPDrWxpbyBwb3IgZmFpeGEgZXTDoXJpYSBlIHBvciBncnVwbyB0ZXJyaXRvcmlhbCAoREYsIFBNQiwgw4FyZWEgUnVyYWwpLCB1dGlsaXphbmRvIG8gZGVzZW5obyBhbW9zdHJhbCBhbW9zdHJhX21vciBqw6EgZGVjbGFyYWRvLg0KUHVibGljYW1vcyBhcGVuYXMgZXN0aW1hdGl2YXMgY29tIENWIOKJpCBwYXJhbXMkY3ZfbWF4Lg0KDQojIyA1LjEgVGF4YSBkZSBDaGVmaWEgfCBzZW0gZmFpeGEgZGUgaWRhZGUNCkNhbGN1bGFuZG8gYSBwb3B1bGHDp8OjbyB0b3RhbA0KYGBge3J9DQpwb3BfdG90YWxfdG90YWwgPC0gYW1vc3RyYV9tb3IgJT4lDQogIHNydnlyOjpncm91cF9ieShncnVwb19wZGFkQSkgJT4lDQogIHNydnlyOjpmaWx0ZXIoIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lDQogIHNydnlyOjpzdW1tYXJpc2UocG9wX3RvdGFsID0gc3VydmV5X3RvdGFsKHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpKSkgJT4lIA0KICBtdXRhdGUocG9wX3RvdGFsPWlmZWxzZShwb3BfdG90YWxfY3Y+cGFyYW1zJGN2X21heCxOQSxwb3BfdG90YWwpKQ0KDQpwb3BfdG90YWxfdG90YWwNCmBgYA0KQ2FsY3VsYW5kbyBhIHBvcHVsYcOnw6NvIGNoZWZlIGRlIGRvbWljw61saW8NCmBgYHtyfQ0KcG9wX2NoZWZlX3RvdGFsIDwtIGFtb3N0cmFfbW9yICU+JQ0KICBzcnZ5cjo6ZmlsdGVyKGUwNCA9PSAxLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fcGRhZEEpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKHBvcF9jaGVmZSA9IHN1cnZleV90b3RhbCh2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSkpICU+JSANCiAgbXV0YXRlKHBvcF9jaGVmZT1pZmVsc2UocG9wX2NoZWZlX2N2PnBhcmFtcyRjdl9tYXgsTkEscG9wX2NoZWZlKSkNCnBvcF9jaGVmZV90b3RhbA0KYGBgDQpDYWxjdWxhbmRvIGEgdGF4YSBkZSBjaGVmaWENCmBgYHtyfQ0KdGF4YV9jaGVmaWFfZ3JvdXBvX0FfdG90YWwgPC0gcG9wX2NoZWZlX3RvdGFsICU+JQ0KICBsZWZ0X2pvaW4ocG9wX3RvdGFsX3RvdGFsLCBieSA9IGMoImdydXBvX3BkYWRBIikpICU+JQ0KICBtdXRhdGUodGF4YV9jaGVmaWEgPSBwb3BfY2hlZmUgLyBwb3BfdG90YWwpICU+JSANCiAgc2VsZWN0KGdydXBvX3BkYWRBLCB0YXhhX2NoZWZpYSwgcG9wX2NoZWZlLCBwb3BfdG90YWwpIA0KdGF4YV9jaGVmaWFfZ3JvdXBvX0FfdG90YWwgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCmBgYA0KDQojIyA1LjIgIFRheGEgZGUgQ2hlZmlhIGdydXBvcyBQREFEQSB8IEZhaXhhIGRlIElkYWRlDQpDYWxjdWxhbmRvIGEgcG9wdWxhw6fDo28gdG90YWwNCmBgYHtyfQ0KcG9wX3RvdGFsIDwtIGFtb3N0cmFfbW9yICU+JQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLGdydXBvX3BkYWRBKSAlPiUNCiAgc3J2eXI6OmZpbHRlcighZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShwb3BfdG90YWwgPSBzdXJ2ZXlfdG90YWwodmFydHlwZSA9IGMoImN2IiwgImNpIikpKSAlPiUgDQogIG11dGF0ZShwb3BfdG90YWw9aWZlbHNlKHBvcF90b3RhbF9jdj5wYXJhbXMkY3ZfbWF4LE5BLHBvcF90b3RhbCkpDQoNCnBvcF90b3RhbA0KYGBgDQpDYWxjdWxhbmRvIGEgcG9wdWxhw6fDo28gY2hlZmUgZGUgZG9taWPDrWxpbw0KYGBge3J9DQpwb3BfY2hlZmUgPC0gYW1vc3RyYV9tb3IgJT4lDQogIHNydnlyOjpmaWx0ZXIoZTA0ID09IDEsIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lDQogIHNydnlyOjpncm91cF9ieShncnVwb19ldGFyaW8sZ3J1cG9fcGRhZEEpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKHBvcF9jaGVmZSA9IHN1cnZleV90b3RhbCh2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSkpICU+JSANCiAgbXV0YXRlKHBvcF9jaGVmZT1pZmVsc2UocG9wX2NoZWZlX2N2PnBhcmFtcyRjdl9tYXgsTkEscG9wX2NoZWZlKSkNCnBvcF9jaGVmZQ0KYGBgDQpDYWxjdWxhbmRvIGEgdGF4YSBkZSBjaGVmaWENCmBgYHtyfQ0KdGF4YV9jaGVmaWFfZ3JvdXBvX0EgPC0gcG9wX2NoZWZlICU+JQ0KICBsZWZ0X2pvaW4ocG9wX3RvdGFsLCBieSA9IGMoImdydXBvX2V0YXJpbyIsICJncnVwb19wZGFkQSIpKSAlPiUNCiAgbXV0YXRlKHRheGFfY2hlZmlhID0gcG9wX2NoZWZlIC8gcG9wX3RvdGFsKSAlPiUgDQogIHNlbGVjdChncnVwb19ldGFyaW8sIGdydXBvX3BkYWRBLCB0YXhhX2NoZWZpYSwgcG9wX2NoZWZlLCBwb3BfdG90YWwpIA0KdGF4YV9jaGVmaWFfZ3JvdXBvX0EgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCmBgYA0KDQoNCiMjIDUuMiAgVGF4YSBkZSBDaGVmaWEgUkEgJiBNdW5pY8OtcGlvcyB8IEZhaXhhIGRlIElkYWRlIA0KQ2FsY3VsYW5kbyBhIHBvcHVsYcOnw6NvIHRvdGFsDQpgYGB7cn0NCnBvcF90b3RhbCA8LSBhbW9zdHJhX21vciAlPiUNCiAgc3J2eXI6Omdyb3VwX2J5KGdydXBvX2V0YXJpbyxncnVwb19wZGFkQSxzdHJhdGFfbG9jYWxpZGFkZSkgJT4lDQogIHNydnlyOjpmaWx0ZXIoIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lDQogIHNydnlyOjpzdW1tYXJpc2UocG9wX3RvdGFsID0gc3VydmV5X3RvdGFsKHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpKSkgJT4lIA0KICBtdXRhdGUocG9wX3RvdGFsPWlmZWxzZShwb3BfdG90YWxfY3Y+cGFyYW1zJGN2X21heCxOQSxwb3BfdG90YWwpKQ0KDQpwb3BfdG90YWwNCmBgYA0KQ2FsY3VsYW5kbyBhIHBvcHVsYcOnw6NvIGNoZWZlIGRlIGRvbWljw61saW8NCmBgYHtyfQ0KcG9wX2NoZWZlIDwtIGFtb3N0cmFfbW9yICU+JQ0KICBzcnZ5cjo6ZmlsdGVyKGUwNCA9PSAxLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLGdydXBvX3BkYWRBLHN0cmF0YV9sb2NhbGlkYWRlKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShwb3BfY2hlZmUgPSBzdXJ2ZXlfdG90YWwodmFydHlwZSA9IGMoImN2IiwgImNpIikpKSAlPiUgDQogIG11dGF0ZShwb3BfY2hlZmU9aWZlbHNlKHBvcF9jaGVmZV9jdj5wYXJhbXMkY3ZfbWF4LE5BLHBvcF9jaGVmZSkpDQpwb3BfY2hlZmUgDQpgYGANCkNhbGN1bGFuZG8gYSB0YXhhIGRlIGNoZWZpYQ0KYGBge3J9DQp0YXhhX2NoZWZpYV9zdHJhdGFfbG9jYWxpZGFkZSA8LSBwb3BfY2hlZmUgJT4lDQogIGxlZnRfam9pbihwb3BfdG90YWwsIGJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIiwnc3RyYXRhX2xvY2FsaWRhZGUnKSkgJT4lDQogIG11dGF0ZSh0YXhhX2NoZWZpYSA9IHBvcF9jaGVmZSAvIHBvcF90b3RhbCkgJT4lIA0KICBzZWxlY3QoZ3J1cG9fZXRhcmlvLCBncnVwb19wZGFkQSxzdHJhdGFfbG9jYWxpZGFkZSwgdGF4YV9jaGVmaWEsIHBvcF9jaGVmZSwgcG9wX3RvdGFsKSANCnRheGFfY2hlZmlhX3N0cmF0YV9sb2NhbGlkYWRlICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQpgYGANCg0KDQoNCiMgNi4gRXN0aW1hw6fDo28gZGEgRGVtYW5kYQ0KDQpFc3RpbWFtb3MgYSBkZW1hbmRhLCBubyBuw612ZWwgZG8gbW9yYWRvciwgYWR1bHRvcyAyNOKAkzY0IHF1ZSBuw6NvIHPDo28gcmVzcG9uc8OhdmVpcyBuZW0gY8O0bmp1Z2VzLiDDiSBhIG1hbmVpcmEgbWFpcyBkaXJldGEgZGUgZXZpdGFyIGR1cGxpY2HDp8O1ZXMuDQpwdWJsaWNhbW9zIGFwZW5hcyByZXN1bHRhZG9zIGNvbSBDViDiiaQgcGFyYW1zJGN2X21heCBlIGNydXphbW9zIHBvciBmYWl4YSBldMOhcmlhIGUgZ3J1cG8gdXNhbmRvIGEgbWVzbWEgZGVmaW5pw6fDo28gZG8gQmxvY28gNS4NCiMjIDYuMSAgREVNQU5EQSBHcnVwb3MgUERBRCBBIHwgc2VtIGZhaXhhIGV0w6FyaWENCg0KQ2FsY3VsYW5kbyBhIGRlbWFuZGEgcG90ZW5jaWFsIHBvciBmYWl4YSBldMOhcmlhIGUgZ3J1cG8gdGVycml0b3JpYWwuDQoNCg0KYGBge3J9DQpkZW1hbmRhX2lkYWRlIDwtIGFtb3N0cmFfbW9yICU+JSNGaWx0cmEgYXBlbmFzIG9ic2VydmHDp8O1ZXMgY29tIGRlbWFuZGEgcG9zaXRpdmENCiAgc3J2eXI6OmZpbHRlcihkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19wZGFkQSkgJT4lDQogIHNydnlyOjpzdW1tYXJpc2UoZGVtYW5kYSA9IHN1cnZleV90b3RhbChkZW1hbmRhX2luZCwgdmFydHlwZSA9IGMoImN2IiwgImNpIiksIG5hLnJtID0gVFJVRSkpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lICAjQ29udmVydGUgcGFyYSBkYXRhLmZyYW1lIGUgYXBsaWNhIGZpbHRybyBkZSBwcmVjaXPDo28NCiAgbXV0YXRlKGRlbWFuZGE9aWZlbHNlKGRlbWFuZGFfY3Y+cGFyYW1zJGN2X21heCxOQSxkZW1hbmRhKSkNCmRlbWFuZGFfaWRhZGUgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCmBgYA0KVmVyc8OjbyBjb20gYSB0YXhhIGRlIGNoZWZpYSBkbyBkbw0KYGBge3J9DQpkZW1hbmRhX2lkYWRlX2dyb3Vwb19BX3RvdGFsIDwtDQogIG1lcmdlKGRlbWFuZGFfaWRhZGUsIHRheGFfY2hlZmlhX2dyb3Vwb19BX3RvdGFsLA0KYnkgPSBjKCJncnVwb19wZGFkQSIpKSAlPiUgDQogIG11dGF0ZShkZW1hbmRhX2FqdXN0YWRhID0gZGVtYW5kYSAqIHRheGFfY2hlZmlhKSAlPiUgc2VsZWN0KGdydXBvX3BkYWRBLGRlbWFuZGFfYWp1c3RhZGEsZGVtYW5kYSx0YXhhX2NoZWZpYSxwb3BfY2hlZmUscG9wX3RvdGFsKQ0KZGVtYW5kYV9pZGFkZV9ncm91cG9fQV90b3RhbCAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KIyMgNi4yICBERU1BTkRBIEdydXBvcyBQREFEIEEgfCBQb3IgZmFpeGEgZXTDoXJpYQ0KDQpDYWxjdWxhbmRvIGEgZGVtYW5kYSBwb3RlbmNpYWwgcG9yIGZhaXhhIGV0w6FyaWEgZSBncnVwbyB0ZXJyaXRvcmlhbC4NCg0KDQpgYGB7cn0NCmRlbWFuZGFfaWRhZGUgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKGRlbWFuZGEgPiAwICYgIShlMDQgJWluJSBjKDE6MykpLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JSNDcmlhIHZhcmnDoXZlbCBiaW7DoXJpYTogYWR1bHRvIGVudHJlIDI0IGUgNjQgYW5vcywgcXVlIG7Do28gw6kgY8O0bmp1Z2UgbmVtIGNoZWZlIGRlIGNhc2FsDQogIHNydnlyOjptdXRhdGUoZGVtYW5kYV9pbmQgPSBpZmVsc2UoaWRhZGUgJWluJSBjKDI0OjY0KSAmIGNvbmpfY2FzYWwgPT0gMCwgMSwgMCkpICU+JSNDbGFzc2lmaWNhIGZhaXhhcyBldMOhcmlhcyBkZSBpbnRlcmVzc2UNCiAgc3J2eXI6Omdyb3VwX2J5KGdydXBvX2V0YXJpbywgZ3J1cG9fcGRhZEEpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKGRlbWFuZGEgPSBzdXJ2ZXlfdG90YWwoZGVtYW5kYV9pbmQsIHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAgI0NvbnZlcnRlIHBhcmEgZGF0YS5mcmFtZSBlIGFwbGljYSBmaWx0cm8gZGUgcHJlY2lzw6NvDQogIG11dGF0ZShkZW1hbmRhPWlmZWxzZShkZW1hbmRhX2N2PnBhcmFtcyRjdl9tYXgsTkEsZGVtYW5kYSkpDQpkZW1hbmRhX2lkYWRlICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQpgYGANClZlcnPDo28gY29tIGEgdGF4YSBkZSBjaGVmaWEgZG8gZG8NCmBgYHtyfQ0KZGVtYW5kYV9pZGFkZV9ncm91cG9fQSA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlLCB0YXhhX2NoZWZpYV9ncm91cG9fQSwNCmJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fZXRhcmlvLGdydXBvX3BkYWRBLGRlbWFuZGFfYWp1c3RhZGEsZGVtYW5kYSx0YXhhX2NoZWZpYSxwb3BfY2hlZmUscG9wX3RvdGFsKQ0KZGVtYW5kYV9pZGFkZV9ncm91cG9fQSAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KIyMgNi4zICBERU1BTkRBIFJBICYgTXVuaWPDrXBpb3MgfCBQb3IgZmFpeGEgZXTDoXJpYQ0KQ2FsY3VsYW5kbyBhIGRlbWFuZGEgcG90ZW5jaWFsIHBvciBmYWl4YSBldMOhcmlhIGUgZ3J1cG8gdGVycml0b3JpYWwuIA0KDQoNCmBgYHtyfQ0KDQpkZW1hbmRhX2lkYWRlIDwtIGFtb3N0cmFfbW9yICU+JSNGaWx0cmEgYXBlbmFzIG9ic2VydmHDp8O1ZXMgY29tIGRlbWFuZGEgcG9zaXRpdmENCiAgc3J2eXI6OmZpbHRlcihkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19ldGFyaW8sIGdydXBvX3BkYWRBLHN0cmF0YV9sb2NhbGlkYWRlKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZSAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKQ0KYGBgDQojIyMgVmVyc8OjbyBjb20gYSB0YXhhIGRlIGNoZWZpYSBkbyBHUlVQTyBQREFEIEENCmBgYHtyfQ0KZGVtYW5kYV9pZGFkZV9SQSA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlLCB0YXhhX2NoZWZpYV9ncm91cG9fQSwNCmJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fZXRhcmlvLHN0cmF0YV9sb2NhbGlkYWRlLGdydXBvX3BkYWRBLGRlbWFuZGFfYWp1c3RhZGEsZGVtYW5kYSx0YXhhX2NoZWZpYSxwb3BfY2hlZmUscG9wX3RvdGFsKQ0KZGVtYW5kYV9pZGFkZV9SQSAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KDQoNCg0KIyMjIFZlcnPDo28gY29tIGEgdGF4YSBkZSBjaGVmaWEgZG8gR1JVUE8gUERBRCBBDQpgYGB7cn0NCmRlbWFuZGFfaWRhZGVfUkEgPC0NCiAgbWVyZ2UoZGVtYW5kYV9pZGFkZSwgdGF4YV9jaGVmaWFfc3RyYXRhX2xvY2FsaWRhZGUsDQpieSA9IGMoImdydXBvX2V0YXJpbyIsICJncnVwb19wZGFkQSIsInN0cmF0YV9sb2NhbGlkYWRlIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fZXRhcmlvLHN0cmF0YV9sb2NhbGlkYWRlLGdydXBvX3BkYWRBLGRlbWFuZGFfYWp1c3RhZGEsZGVtYW5kYSx0YXhhX2NoZWZpYSxwb3BfY2hlZmUscG9wX3RvdGFsKQ0KZGVtYW5kYV9pZGFkZV9SQSAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KDQojIDcuIEFuYWxpc2VzIEVzdHJhdGlmaWNhZGFzDQojIyA3LjEgRXN0YWRvIENpdmlsIA0KIyMjUG9yIGdydXBvIEV0w6FyaW8NCmBgYHtyfQ0KI3BkYWQyMDIzJGUwNyNFc3RhZG8gY2l2aWwNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMSA8LSBhbW9zdHJhX21vciAlPiUjRmlsdHJhIGFwZW5hcyBvYnNlcnZhw6fDtWVzIGNvbSBkZW1hbmRhIHBvc2l0aXZhDQogIHNydnlyOjpmaWx0ZXIoZTA3PDYsDQogICAgICAgICAgICAgICAgZGVtYW5kYSA+IDAgJiAhKGUwNCAlaW4lIGMoMTozKSksIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lI0NyaWEgdmFyacOhdmVsIGJpbsOhcmlhOiBhZHVsdG8gZW50cmUgMjQgZSA2NCBhbm9zLCBxdWUgbsOjbyDDqSBjw7RuanVnZSBuZW0gY2hlZmUgZGUgY2FzYWwNCiAgc3J2eXI6Om11dGF0ZShkZW1hbmRhX2luZCA9IGlmZWxzZShpZGFkZSAlaW4lIGMoMjQ6NjQpICYgY29ual9jYXNhbCA9PSAwLCAxLCAwKSwNCiAgICAgICAgICAgICAgICBzdHJhdGFfZXN0YWRvX2NpdmlsPWNhc2Vfd2hlbihlMDc9PTF+IlNvbHRlaXJvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDc9PTJ+IkNhc2FkbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA3PT0zfiJEZXNxdWl0YWRvIG91IHNlcGFyYWRvIGp1ZGljaWFsbWVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNz09NH4iRGVzcXVpdGFkbyBvdSBzZXBhcmFkbyBqdWRpY2lhbG1lbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDc9PTV+IlZpw7p2byIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRX4iTsOjbyBTYWJlIC8gTsOjbyBzZSBBcGxpY2EiKSkgJT4lI0NsYXNzaWZpY2EgZmFpeGFzIGV0w6FyaWFzIGRlIGludGVyZXNzZQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLCBncnVwb19wZGFkQSxzdHJhdGFfZXN0YWRvX2NpdmlsKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGExICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMSA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlX3N0cmF0YTEsIHRheGFfY2hlZmlhX2dyb3Vwb19BLA0KYnkgPSBjKCJncnVwb19ldGFyaW8iLCAiZ3J1cG9fcGRhZEEiKSkgJT4lIA0KICBtdXRhdGUoZGVtYW5kYV9hanVzdGFkYSA9IGRlbWFuZGEgKiB0YXhhX2NoZWZpYSkgJT4lIHNlbGVjdChncnVwb19ldGFyaW8sZ3J1cG9fcGRhZEEsc3RyYXRhX2VzdGFkb19jaXZpbCxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMSAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KDQojIyNzZW0gZ3J1cG8gZXTDoXJpbw0KYGBge3J9DQojcGRhZDIwMjMkZTA3I0VzdGFkbyBjaXZpbA0KZGVtYW5kYV9pZGFkZV9zdHJhdGExX3RvdGFsIDwtIGFtb3N0cmFfbW9yICU+JSNGaWx0cmEgYXBlbmFzIG9ic2VydmHDp8O1ZXMgY29tIGRlbWFuZGEgcG9zaXRpdmENCiAgc3J2eXI6OmZpbHRlcihlMDc8NiwNCiAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApLA0KICAgICAgICAgICAgICAgIHN0cmF0YV9lc3RhZG9fY2l2aWw9Y2FzZV93aGVuKGUwNz09MX4iU29sdGVpcm8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNz09Mn4iQ2FzYWRvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlMDc9PTN+IkRlc3F1aXRhZG8gb3Ugc2VwYXJhZG8ganVkaWNpYWxtZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA3PT00fiJEZXNxdWl0YWRvIG91IHNlcGFyYWRvIGp1ZGljaWFsbWVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUwNz09NX4iVmnDunZvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFfiJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSIpKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19wZGFkQSxzdHJhdGFfZXN0YWRvX2NpdmlsKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGExX3RvdGFsICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMV90b3RhbCA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlX3N0cmF0YTFfdG90YWwsIHRheGFfY2hlZmlhX2dyb3Vwb19BX3RvdGFsLA0KYnkgPSBjKCJncnVwb19wZGFkQSIpKSAlPiUgDQogIG11dGF0ZShkZW1hbmRhX2FqdXN0YWRhID0gZGVtYW5kYSAqIHRheGFfY2hlZmlhKSAlPiUgc2VsZWN0KGdydXBvX3BkYWRBLHN0cmF0YV9lc3RhZG9fY2l2aWwsZGVtYW5kYV9hanVzdGFkYSxkZW1hbmRhLHRheGFfY2hlZmlhLHBvcF9jaGVmZSxwb3BfdG90YWwpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTFfdG90YWwgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikgJT4lIGFkb3JuX3RvdGFscygpDQpgYGANCg0KDQoNCiMjIDcuMiBFc2NvbGFyaWRhZGUgDQojIyNQb3IgZ3J1cG8gRXTDoXJpbw0KYGBge3J9DQpwZGFkMjAyMyRlc2NvbGFyaWRhZGUjRXN0YWRvIGNpdmlsDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKGUwNzw2LA0KICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwICYgIShlMDQgJWluJSBjKDE6MykpLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JSNDcmlhIHZhcmnDoXZlbCBiaW7DoXJpYTogYWR1bHRvIGVudHJlIDI0IGUgNjQgYW5vcywgcXVlIG7Do28gw6kgY8O0bmp1Z2UgbmVtIGNoZWZlIGRlIGNhc2FsDQogIHNydnlyOjptdXRhdGUoZGVtYW5kYV9pbmQgPSBpZmVsc2UoaWRhZGUgJWluJSBjKDI0OjY0KSAmIGNvbmpfY2FzYWwgPT0gMCwgMSwgMCksDQogICAgICAgICAgICAgICAgc3RyYXRhX2VzY29sYXJpZGFkZT1jYXNlX3doZW4oZXNjb2xhcmlkYWRlPT0xfiJTZW0gaW5zdHJ1w6fDo28iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09Mn4iRnVuZGFtZW50YWwgaW5jb21wbGV0byBvdSBlcXVpdmFsZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT0zfiJGdW5kYW1lbnRhbCBjb21wbGV0byBvdSBlcXVpdmFsZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT00fiJNw6lkaW8gaW5jb21wbGV0byBvdSBlcXVpdmFsZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT01fiJNw6lkaW8gY29tcGxldG8gb3UgZXF1aXZhbGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09Nn4iU3VwZXJpb3IgaW5jb21wbGV0byBvdSBlcXVpdmFsZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT03fiJTdXBlcmlvciBjb21wbGV0byAiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09OH4iU2VtIGNsYXNzaWZpY2HDp8OjbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRX4iTsOjbyBTYWJlIC8gTsOjbyBzZSBBcGxpY2EiKSkgJT4lI0NsYXNzaWZpY2EgZmFpeGFzIGV0w6FyaWFzIGRlIGludGVyZXNzZQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLCBncnVwb19wZGFkQSxzdHJhdGFfZXNjb2xhcmlkYWRlKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGEyICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMiA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlX3N0cmF0YTIsIHRheGFfY2hlZmlhX2dyb3Vwb19BLA0KYnkgPSBjKCJncnVwb19ldGFyaW8iLCAiZ3J1cG9fcGRhZEEiKSkgJT4lIA0KICBtdXRhdGUoZGVtYW5kYV9hanVzdGFkYSA9IGRlbWFuZGEgKiB0YXhhX2NoZWZpYSkgJT4lIHNlbGVjdChncnVwb19ldGFyaW8sZ3J1cG9fcGRhZEEsc3RyYXRhX2VzY29sYXJpZGFkZSxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMiAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KDQojIyNzZW0gZ3J1cG8gZXTDoXJpbw0KYGBge3J9DQojcGRhZDIwMjMkZTA3I0VzdGFkbyBjaXZpbA0KZGVtYW5kYV9pZGFkZV9zdHJhdGEyX3RvdGFsIDwtIGFtb3N0cmFfbW9yICU+JSNGaWx0cmEgYXBlbmFzIG9ic2VydmHDp8O1ZXMgY29tIGRlbWFuZGEgcG9zaXRpdmENCiAgc3J2eXI6OmZpbHRlcihlMDc8NiwNCiAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApLA0KICAgICAgICAgICAgICAgIHN0cmF0YV9lc2NvbGFyaWRhZGU9Y2FzZV93aGVuKGVzY29sYXJpZGFkZT09MX4iU2VtIGluc3RydcOnw6NvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTJ+IkZ1bmRhbWVudGFsIGluY29tcGxldG8gb3UgZXF1aXZhbGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09M34iRnVuZGFtZW50YWwgY29tcGxldG8gb3UgZXF1aXZhbGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09NH4iTcOpZGlvIGluY29tcGxldG8gb3UgZXF1aXZhbGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09NX4iTcOpZGlvIGNvbXBsZXRvIG91IGVxdWl2YWxlbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTZ+IlN1cGVyaW9yIGluY29tcGxldG8gb3UgZXF1aXZhbGVudGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY29sYXJpZGFkZT09N34iU3VwZXJpb3IgY29tcGxldG8gIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTh+IlNlbSBjbGFzc2lmaWNhw6fDo28iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUV+Ik7Do28gU2FiZSAvIE7Do28gc2UgQXBsaWNhIikpICU+JSNDbGFzc2lmaWNhIGZhaXhhcyBldMOhcmlhcyBkZSBpbnRlcmVzc2UNCiAgc3J2eXI6Omdyb3VwX2J5KGdydXBvX3BkYWRBLHN0cmF0YV9lc2NvbGFyaWRhZGUpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKGRlbWFuZGEgPSBzdXJ2ZXlfdG90YWwoZGVtYW5kYV9pbmQsIHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAgI0NvbnZlcnRlIHBhcmEgZGF0YS5mcmFtZSBlIGFwbGljYSBmaWx0cm8gZGUgcHJlY2lzw6NvDQogIG11dGF0ZShkZW1hbmRhPWlmZWxzZShkZW1hbmRhX2N2PnBhcmFtcyRjdl9tYXgsTkEsZGVtYW5kYSkpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTJfdG90YWwgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCg0KZGVtYW5kYV9pZGFkZV9zdHJhdGEyX3RvdGFsIDwtDQogIG1lcmdlKGRlbWFuZGFfaWRhZGVfc3RyYXRhMl90b3RhbCwgdGF4YV9jaGVmaWFfZ3JvdXBvX0FfdG90YWwsDQpieSA9IGMoImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fcGRhZEEsc3RyYXRhX2VzY29sYXJpZGFkZSxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMl90b3RhbCAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KDQoNCiMjIDcuMiBzYWxhcmlvbWluaW1vDQojIyNQb3IgZ3J1cG8gRXTDoXJpbw0KYGBge3J9DQpwZGFkMjAyM19vcmlnaW5hbCRyZW5kYQ0KDQpgYGANCg0KYGBge3J9DQpwZGFkMjAyMyRyZW5kYV9pbmQjRXN0YWRvIGNpdmlsDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKCNlMDc8NiwNCiAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApLA0KICAgICAgICAgICAgICAgIHN0cmF0YV9yZW5kYT1jYXNlX3doZW4ocmVuZGFfaW5kPDMqc2FsYXJpb21pbmltb34iMC0zU00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGFfaW5kPDUqc2FsYXJpb21pbmltb34iMy01U00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGFfaW5kPjUqc2FsYXJpb21pbmltb34iNStTTSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcmVuZGFfaW5kPHNhbGFyaW9taW5pbW9+Im1haW9yNFNNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgICAgICAgVFJVRX4iTsOjbyBTYWJlIC8gTsOjbyBzZSBBcGxpY2EiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19ldGFyaW8sIGdydXBvX3BkYWRBLHN0cmF0YV9yZW5kYSkgJT4lDQogIHNydnlyOjpzdW1tYXJpc2UoZGVtYW5kYSA9IHN1cnZleV90b3RhbChkZW1hbmRhX2luZCwgdmFydHlwZSA9IGMoImN2IiwgImNpIiksIG5hLnJtID0gVFJVRSkpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lICAjQ29udmVydGUgcGFyYSBkYXRhLmZyYW1lIGUgYXBsaWNhIGZpbHRybyBkZSBwcmVjaXPDo28NCiAgbXV0YXRlKGRlbWFuZGE9aWZlbHNlKGRlbWFuZGFfY3Y+cGFyYW1zJGN2X21heCxOQSxkZW1hbmRhKSkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMyAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKQ0KDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgPC0NCiAgbWVyZ2UoZGVtYW5kYV9pZGFkZV9zdHJhdGEzLCB0YXhhX2NoZWZpYV9ncm91cG9fQSwNCmJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fZXRhcmlvLGdydXBvX3BkYWRBLHN0cmF0YV9yZW5kYSxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMyAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmBgYA0KYGBge3J9DQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKCNlMDc8NiwNCiAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApLA0KICAgICAgICAgICAgICAgIHN0cmF0YV9yZW5kYT1jYXNlX3doZW4ocmVuZGFfaW5kPHNhbGFyaW9taW5pbW9+IjAtMVNNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRhX2luZDwzKnNhbGFyaW9taW5pbW9+IjEtM1NNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRhX2luZD4zKnNhbGFyaW9taW5pbW9+IjUrU00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI3JlbmRhX2luZDxzYWxhcmlvbWluaW1vfiJtYWlvcjRTTSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICAgICAgIFRSVUV+Ik7Do28gU2FiZSAvIE7Do28gc2UgQXBsaWNhIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgJT4lI0NsYXNzaWZpY2EgZmFpeGFzIGV0w6FyaWFzIGRlIGludGVyZXNzZQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLCBncnVwb19wZGFkQSxzdHJhdGFfcmVuZGEpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKGRlbWFuZGEgPSBzdXJ2ZXlfdG90YWwoZGVtYW5kYV9pbmQsIHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAgI0NvbnZlcnRlIHBhcmEgZGF0YS5mcmFtZSBlIGFwbGljYSBmaWx0cm8gZGUgcHJlY2lzw6NvDQogIG11dGF0ZShkZW1hbmRhPWlmZWxzZShkZW1hbmRhX2N2PnBhcmFtcyRjdl9tYXgsTkEsZGVtYW5kYSkpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCg0KZGVtYW5kYV9pZGFkZV9zdHJhdGEzIDwtDQogIG1lcmdlKGRlbWFuZGFfaWRhZGVfc3RyYXRhMywgdGF4YV9jaGVmaWFfZ3JvdXBvX0EsDQpieSA9IGMoImdydXBvX2V0YXJpbyIsICJncnVwb19wZGFkQSIpKSAlPiUgDQogIG11dGF0ZShkZW1hbmRhX2FqdXN0YWRhID0gZGVtYW5kYSAqIHRheGFfY2hlZmlhKSAlPiUgc2VsZWN0KGdydXBvX2V0YXJpbyxncnVwb19wZGFkQSxzdHJhdGFfcmVuZGEsZGVtYW5kYV9hanVzdGFkYSxkZW1hbmRhLHRheGFfY2hlZmlhLHBvcF9jaGVmZSxwb3BfdG90YWwpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikgJT4lIGFkb3JuX3RvdGFscygpDQpgYGANCiMjIFJlbmRhIERvbWljaWxpYXINCmBgYHtyfQ0KcGRhZDIwMjNfb3JpZ2luYWwkcmVuZGFfZG9taWNpbGlhcg0KZGVtYW5kYV9pZGFkZV9zdHJhdGEzIDwtIGFtb3N0cmFfbW9yICU+JSNGaWx0cmEgYXBlbmFzIG9ic2VydmHDp8O1ZXMgY29tIGRlbWFuZGEgcG9zaXRpdmENCiAgc3J2eXI6OmZpbHRlcigjZTA3PDYsDQogICAgICAgICAgICAgICAgZGVtYW5kYSA+IDAgJiAhKGUwNCAlaW4lIGMoMTozKSksIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lI0NyaWEgdmFyacOhdmVsIGJpbsOhcmlhOiBhZHVsdG8gZW50cmUgMjQgZSA2NCBhbm9zLCBxdWUgbsOjbyDDqSBjw7RuanVnZSBuZW0gY2hlZmUgZGUgY2FzYWwNCiAgc3J2eXI6Om11dGF0ZShkZW1hbmRhX2luZCA9IGlmZWxzZShpZGFkZSAlaW4lIGMoMjQ6NjQpICYgY29ual9jYXNhbCA9PSAwLCAxLCAwKSwNCiAgICAgICAgICAgICAgICBzdHJhdGFfcmVuZGE9Y2FzZV93aGVuKHJlbmRhX2RvbWljaWxpYXI8c2FsYXJpb21pbmltb34iMC0xU00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGFfZG9taWNpbGlhcjwzKnNhbGFyaW9taW5pbW9+IjEtM1NNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRhX2RvbWljaWxpYXI+MypzYWxhcmlvbWluaW1vfiI1K1NNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNyZW5kYV9pbmQ8c2FsYXJpb21pbmltb34ibWFpb3I0U00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAgICAgICBUUlVFfiJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpICU+JSNDbGFzc2lmaWNhIGZhaXhhcyBldMOhcmlhcyBkZSBpbnRlcmVzc2UNCiAgc3J2eXI6Omdyb3VwX2J5KGdydXBvX2V0YXJpbywgZ3J1cG9fcGRhZEEsc3RyYXRhX3JlbmRhKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGEzICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMyA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlX3N0cmF0YTMsIHRheGFfY2hlZmlhX2dyb3Vwb19BLA0KYnkgPSBjKCJncnVwb19ldGFyaW8iLCAiZ3J1cG9fcGRhZEEiKSkgJT4lIA0KICBtdXRhdGUoZGVtYW5kYV9hanVzdGFkYSA9IGRlbWFuZGEgKiB0YXhhX2NoZWZpYSkgJT4lIHNlbGVjdChncnVwb19ldGFyaW8sZ3J1cG9fcGRhZEEsc3RyYXRhX3JlbmRhLGRlbWFuZGFfYWp1c3RhZGEsZGVtYW5kYSx0YXhhX2NoZWZpYSxwb3BfY2hlZmUscG9wX3RvdGFsKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGEzICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpICU+JSBhZG9ybl90b3RhbHMoKQ0KYGBgDQoNCg0KYGBge3J9DQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKCNlMDc8NiwNCiAgICAgICAgICAgICAgICBkZW1hbmRhID4gMCAmICEoZTA0ICVpbiUgYygxOjMpKSwhZ3J1cG9fZXRhcmlvPT0iT3V0cm8iKSAlPiUjQ3JpYSB2YXJpw6F2ZWwgYmluw6FyaWE6IGFkdWx0byBlbnRyZSAyNCBlIDY0IGFub3MsIHF1ZSBuw6NvIMOpIGPDtG5qdWdlIG5lbSBjaGVmZSBkZSBjYXNhbA0KICBzcnZ5cjo6bXV0YXRlKGRlbWFuZGFfaW5kID0gaWZlbHNlKGlkYWRlICVpbiUgYygyNDo2NCkgJiBjb25qX2Nhc2FsID09IDAsIDEsIDApLA0KICAgICAgICAgICAgICAgIHN0cmF0YV9yZW5kYT1jYXNlX3doZW4ocmVuZGFfaW5kPHNhbGFyaW9taW5pbW9+IjAtMVNNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRhX2luZDwzKnNhbGFyaW9taW5pbW9+IjEtM1NNIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRhX2luZD4zKnNhbGFyaW9taW5pbW9+IjUrU00iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI3JlbmRhX2luZDxzYWxhcmlvbWluaW1vfiJtYWlvcjRTTSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICAgICAgIFRSVUV+Ik7Do28gU2FiZSAvIE7Do28gc2UgQXBsaWNhIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgJT4lI0NsYXNzaWZpY2EgZmFpeGFzIGV0w6FyaWFzIGRlIGludGVyZXNzZQ0KICBzcnZ5cjo6Z3JvdXBfYnkoZ3J1cG9fZXRhcmlvLCBncnVwb19wZGFkQSxzdHJhdGFfcmVuZGEpICU+JQ0KICBzcnZ5cjo6c3VtbWFyaXNlKGRlbWFuZGEgPSBzdXJ2ZXlfdG90YWwoZGVtYW5kYV9pbmQsIHZhcnR5cGUgPSBjKCJjdiIsICJjaSIpLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAgI0NvbnZlcnRlIHBhcmEgZGF0YS5mcmFtZSBlIGFwbGljYSBmaWx0cm8gZGUgcHJlY2lzw6NvDQogIG11dGF0ZShkZW1hbmRhPWlmZWxzZShkZW1hbmRhX2N2PnBhcmFtcyRjdl9tYXgsTkEsZGVtYW5kYSkpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikNCg0KZGVtYW5kYV9pZGFkZV9zdHJhdGEzIDwtDQogIG1lcmdlKGRlbWFuZGFfaWRhZGVfc3RyYXRhMywgdGF4YV9jaGVmaWFfZ3JvdXBvX0EsDQpieSA9IGMoImdydXBvX2V0YXJpbyIsICJncnVwb19wZGFkQSIpKSAlPiUgDQogIG11dGF0ZShkZW1hbmRhX2FqdXN0YWRhID0gZGVtYW5kYSAqIHRheGFfY2hlZmlhKSAlPiUgc2VsZWN0KGdydXBvX2V0YXJpbyxncnVwb19wZGFkQSxzdHJhdGFfcmVuZGEsZGVtYW5kYV9hanVzdGFkYSxkZW1hbmRhLHRheGFfY2hlZmlhLHBvcF9jaGVmZSxwb3BfdG90YWwpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTMgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikgJT4lIGFkb3JuX3RvdGFscygpDQpgYGANCg0KIyMjc2VtIGdydXBvIGV0w6FyaW8NCmBgYHtyfQ0KI3BkYWQyMDIzJGUwNyNFc3RhZG8gY2l2aWwNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMl90b3RhbCA8LSBhbW9zdHJhX21vciAlPiUjRmlsdHJhIGFwZW5hcyBvYnNlcnZhw6fDtWVzIGNvbSBkZW1hbmRhIHBvc2l0aXZhDQogIHNydnlyOjpmaWx0ZXIoZTA3PDYsDQogICAgICAgICAgICAgICAgZGVtYW5kYSA+IDAgJiAhKGUwNCAlaW4lIGMoMTozKSksIWdydXBvX2V0YXJpbz09Ik91dHJvIikgJT4lI0NyaWEgdmFyacOhdmVsIGJpbsOhcmlhOiBhZHVsdG8gZW50cmUgMjQgZSA2NCBhbm9zLCBxdWUgbsOjbyDDqSBjw7RuanVnZSBuZW0gY2hlZmUgZGUgY2FzYWwNCiAgc3J2eXI6Om11dGF0ZShkZW1hbmRhX2luZCA9IGlmZWxzZShpZGFkZSAlaW4lIGMoMjQ6NjQpICYgY29ual9jYXNhbCA9PSAwLCAxLCAwKSwNCiAgICAgICAgICAgICAgICBzdHJhdGFfZXNjb2xhcmlkYWRlPWNhc2Vfd2hlbihlc2NvbGFyaWRhZGU9PTF+IlNlbSBpbnN0cnXDp8OjbyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT0yfiJGdW5kYW1lbnRhbCBpbmNvbXBsZXRvIG91IGVxdWl2YWxlbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTN+IkZ1bmRhbWVudGFsIGNvbXBsZXRvIG91IGVxdWl2YWxlbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTR+Ik3DqWRpbyBpbmNvbXBsZXRvIG91IGVxdWl2YWxlbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTV+Ik3DqWRpbyBjb21wbGV0byBvdSBlcXVpdmFsZW50ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT02fiJTdXBlcmlvciBpbmNvbXBsZXRvIG91IGVxdWl2YWxlbnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NvbGFyaWRhZGU9PTd+IlN1cGVyaW9yIGNvbXBsZXRvICIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjb2xhcmlkYWRlPT04fiJTZW0gY2xhc3NpZmljYcOnw6NvIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFfiJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSIpKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19wZGFkQSxzdHJhdGFfZXNjb2xhcmlkYWRlKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KZGVtYW5kYV9pZGFkZV9zdHJhdGEyX3RvdGFsICU+JSBmaWx0ZXIoZ3J1cG9fcGRhZEE9PSJERiIpDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMl90b3RhbCA8LQ0KICBtZXJnZShkZW1hbmRhX2lkYWRlX3N0cmF0YTJfdG90YWwsIHRheGFfY2hlZmlhX2dyb3Vwb19BX3RvdGFsLA0KYnkgPSBjKCJncnVwb19wZGFkQSIpKSAlPiUgDQogIG11dGF0ZShkZW1hbmRhX2FqdXN0YWRhID0gZGVtYW5kYSAqIHRheGFfY2hlZmlhKSAlPiUgc2VsZWN0KGdydXBvX3BkYWRBLHN0cmF0YV9lc2NvbGFyaWRhZGUsZGVtYW5kYV9hanVzdGFkYSxkZW1hbmRhLHRheGFfY2hlZmlhLHBvcF9jaGVmZSxwb3BfdG90YWwpDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTJfdG90YWwgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikgJT4lIGFkb3JuX3RvdGFscygpDQpgYGANCiMjIEludGVuw6fDo28gZGUgZm9ybWFyIG5vdm8gZG9taWPDrWxpbyBwYXJ0aWN1bGFyIG5vcyBwcsOzeGltb3MgMTIgbWVzZXMNCg0KDQojIyNQb3IgZ3J1cG8gRXTDoXJpbw0KYGBge3J9DQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKGUyMjwzLA0KICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwICYgIShlMDQgJWluJSBjKDE6MykpLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JSNDcmlhIHZhcmnDoXZlbCBiaW7DoXJpYTogYWR1bHRvIGVudHJlIDI0IGUgNjQgYW5vcywgcXVlIG7Do28gw6kgY8O0bmp1Z2UgbmVtIGNoZWZlIGRlIGNhc2FsDQogIHNydnlyOjptdXRhdGUoZGVtYW5kYV9pbmQgPSBpZmVsc2UoaWRhZGUgJWluJSBjKDI0OjY0KSAmIGNvbmpfY2FzYWwgPT0gMCwgMSwgMCksDQogICAgICAgICAgICAgICAgc3RyYXRhX211ZGFuw6dhPWNhc2Vfd2hlbihlMDk9PTF+InNpbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA5PT0yfiJOw6NvIixUUlVFfiJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSIpKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19ldGFyaW8sIGdydXBvX3BkYWRBLHN0cmF0YV9tdWRhbsOnYSkgJT4lDQogIHNydnlyOjpzdW1tYXJpc2UoZGVtYW5kYSA9IHN1cnZleV90b3RhbChkZW1hbmRhX2luZCwgdmFydHlwZSA9IGMoImN2IiwgImNpIiksIG5hLnJtID0gVFJVRSkpICU+JQ0KICBhcy5kYXRhLmZyYW1lKCkgJT4lICAjQ29udmVydGUgcGFyYSBkYXRhLmZyYW1lIGUgYXBsaWNhIGZpbHRybyBkZSBwcmVjaXPDo28NCiAgbXV0YXRlKGRlbWFuZGE9aWZlbHNlKGRlbWFuZGFfY3Y+cGFyYW1zJGN2X21heCxOQSxkZW1hbmRhKSkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMiAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKQ0KDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgPC0NCiAgbWVyZ2UoZGVtYW5kYV9pZGFkZV9zdHJhdGEyLCB0YXhhX2NoZWZpYV9ncm91cG9fQSwNCmJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JSBzZWxlY3QoZ3J1cG9fZXRhcmlvLGdydXBvX3BkYWRBLHN0cmF0YV9tdWRhbsOnYSxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkgDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgJT4lIGZpbHRlcihncnVwb19wZGFkQT09IkRGIikgJT4lIGZpbHRlcighc3RyYXRhX211ZGFuw6dhPT0iTsOjbyBTYWJlIC8gTsOjbyBzZSBBcGxpY2EiKSAlPiUgYWRvcm5fdG90YWxzKCkNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMiAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgZmlsdGVyKCFzdHJhdGFfbXVkYW7Dp2E9PSJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSIpICU+JSANCiAgc2VsZWN0KGdydXBvX2V0YXJpbyxncnVwb19wZGFkQSxzdHJhdGFfbXVkYW7Dp2EsIGRlbWFuZGFfYWp1c3RhZGEpICU+JSANCiAgc3ByZWFkKHN0cmF0YV9tdWRhbsOnYSwgZGVtYW5kYV9hanVzdGFkYSkgJT4lICBhZG9ybl90b3RhbHMod2hlcmUgPSAicm93IikgJT4lICAgDQogIG11dGF0ZShwZXJjZW50dWFsID0gKHNpbS8oc2ltK07Do28pKSoxMDApICANCg0KYGBgDQojIyBJbnRlbsOnw6NvIGRlIGZvcm1hciBub3ZvIGRvbWljw61saW8gcGFydGljdWxhciBub3MgcHLDs3hpbW9zIDEyIG1lc2VzIERlc3Rpbm8NCmBgYHtyfQ0KcGRhZDIwMjNfb3JpZ2luYWwkZTIyXzEgJT4lIHRhYmxlDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgPC0gYW1vc3RyYV9tb3IgJT4lI0ZpbHRyYSBhcGVuYXMgb2JzZXJ2YcOnw7VlcyBjb20gZGVtYW5kYSBwb3NpdGl2YQ0KICBzcnZ5cjo6ZmlsdGVyKGUyMl8xPDg4ODg4LA0KICAgICAgICAgICAgICAgIGRlbWFuZGEgPiAwICYgIShlMDQgJWluJSBjKDE6MykpLCFncnVwb19ldGFyaW89PSJPdXRybyIpICU+JSNDcmlhIHZhcmnDoXZlbCBiaW7DoXJpYTogYWR1bHRvIGVudHJlIDI0IGUgNjQgYW5vcywgcXVlIG7Do28gw6kgY8O0bmp1Z2UgbmVtIGNoZWZlIGRlIGNhc2FsDQogIHNydnlyOjptdXRhdGUoZGVtYW5kYV9pbmQgPSBpZmVsc2UoaWRhZGUgJWluJSBjKDI0OjY0KSAmIGNvbmpfY2FzYWwgPT0gMCwgMSwgMCksDQogICAgICAgICAgICAgICAgc3RyYXRhX211ZGFuw6dhPWNhc2Vfd2hlbihlMDk9PTF+InNpbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZTA5PT0yfiJOw6NvIixUUlVFfiJOw6NvIFNhYmUgLyBOw6NvIHNlIEFwbGljYSIpKSAlPiUjQ2xhc3NpZmljYSBmYWl4YXMgZXTDoXJpYXMgZGUgaW50ZXJlc3NlDQogIHNydnlyOjpncm91cF9ieShncnVwb19ldGFyaW8sIGdydXBvX3BkYWRBLGUyMl8xKSAlPiUNCiAgc3J2eXI6OnN1bW1hcmlzZShkZW1hbmRhID0gc3VydmV5X3RvdGFsKGRlbWFuZGFfaW5kLCB2YXJ0eXBlID0gYygiY3YiLCAiY2kiKSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgICNDb252ZXJ0ZSBwYXJhIGRhdGEuZnJhbWUgZSBhcGxpY2EgZmlsdHJvIGRlIHByZWNpc8Ojbw0KICBtdXRhdGUoZGVtYW5kYT1pZmVsc2UoZGVtYW5kYV9jdj5wYXJhbXMkY3ZfbWF4LE5BLGRlbWFuZGEpKQ0KI2RlbWFuZGFfaWRhZGVfc3RyYXRhMiAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKQ0KDQpkZW1hbmRhX2lkYWRlX3N0cmF0YTIgPC0NCiAgbWVyZ2UoZGVtYW5kYV9pZGFkZV9zdHJhdGEyLCB0YXhhX2NoZWZpYV9ncm91cG9fQSwNCmJ5ID0gYygiZ3J1cG9fZXRhcmlvIiwgImdydXBvX3BkYWRBIikpICU+JSANCiAgbXV0YXRlKGRlbWFuZGFfYWp1c3RhZGEgPSBkZW1hbmRhICogdGF4YV9jaGVmaWEpICU+JQ0KICBsZWZ0X2pvaW4oZGljX21vciAlPiUgZmlsdGVyKGNvbHVuYT09IkUyMl8xIikgLCBieT1jKCJlMjJfMSI9InZhbG9yIikpICU+JSBtdXRhdGUoZGVzdGlubz1kZXNjX3ZhbG9yKSAlPiUgDQogIHNlbGVjdChncnVwb19ldGFyaW8sZ3J1cG9fcGRhZEEsZGVzdGlubyxkZW1hbmRhX2FqdXN0YWRhLGRlbWFuZGEsdGF4YV9jaGVmaWEscG9wX2NoZWZlLHBvcF90b3RhbCkgDQoNCmRlbWFuZGFfaWRhZGVfc3RyYXRhMiAlPiUgZmlsdGVyKGdydXBvX3BkYWRBPT0iREYiKSAlPiUgI2ZpbHRlcighaXMubmEoZGVtYW5kYV9hanVzdGFkYSkpICU+JQ0KICBhZG9ybl90b3RhbHMoKQ0KDQpgYGANCg0KDQoNCg0KDQoNCg==