1. Prefácio
Este estudo apresenta uma análise detalhada das temperaturas médias
diárias registadas em Tóquio entre janeiro de 2019 e março de 2020,
utilizando técnicas de modelagem de séries temporais. Através da
aplicação do modelo ARIMA, exploram-se padrões sazonais e tendências que
caracterizam o clima de Tóquio durante esse período. A modelagem permite
não só compreender as variações históricas das temperaturas, como também
prever valores futuros com um grau razoável de precisão. O relatório
oferece uma abordagem prática à análise de séries temporais, desde a
visualização dos dados até à validação dos modelos, proporcionando uma
visão integrada dos métodos estatísticos utilizados na previsão
climática.
Autor
Sylvie Borges, nascida em 1999, é uma entusiasta das Ciências Humanas
e tem trilhado um percurso académico que reflete a sua paixão pelo
conhecimento e pela gestão de pessoas. Iniciou a sua formação na
prestigiada Universidade Católica Portuguesa, onde se graduou em Línguas
Estrangeiras Aplicadas. Sempre movida pela curiosidade intelectual,
continuou os estudos com um Mestrado em Gestão de Recursos Humanos, pelo
ISCTE Business School, campo onde desenvolveu uma sólida compreensão da
dinâmica organizacional.
Com um olhar atento às mudanças do mundo moderno, Sylvie percebeu que
as Tecnologias da Informação representavam um novo horizonte para a
gestão de pessoas. Desde 2021, tem-se dedicado a explorar este domínio
emergente, construindo uma ponte entre a comunicação, gestão e as novas
ferramentas tecnológicas. Em busca de uma compreensão ainda mais
profunda, inscreveu-se numa Pós-Graduação em Data Science (Universidade
Europeia), determinada a dominar os métodos e linguagens que moldam o
quotidiano dos profissionais das TI, enriquecendo assim a sua capacidade
de interagir com este universo em constante evolução.
Licença Este trabalho está licenciado sob uma licença Creative
Commons Attribution-NonCommercial ShareAlike 4.0 International License.
O resultado deste trabalho não providencia aconselhamento
financeiro.
2. Introdução
O presente estudo tem como objetivo a análise de uma série temporal
referente às temperaturas médias diárias registadas em Tóquio entre 1 de
janeiro de 2019 e 31 de março de 2020. O dataset utilizado remete para
temperatura média diária em graus Celsius e será analisado com recurso a
métodos de séries temporais abordados no curso de Análise de Séries
Temporais.
A análise de séries temporais apresenta-se como uma técnica
estatística que permite estudar os dados sequenciais ao longo do tempo,
identificar padrões e realizar previsões futuras com base em dados
históricos. Este tipo de análise é amplamente utilizado em diversas
áreas, como a meteorologia, economia e finanças, devido à sua capacidade
de modelar e prever comportamentos futuros.
Para o desenvolvimento deste trabalho, serão explorados diferentes
modelos de séries temporais, como o ARIMA e outros métodos. O objetivo é
selecionar o modelo que melhor se ajusta aos dados de temperatura e, com
base nesse modelo, realizar previsões para períodos futuros.
Além disso, será feita uma análise dos resíduos do modelo selecionado
para verificar a sua adequação e, por fim, será apresentado um conjunto
de previsões com base nos dados disponíveis. As decisões tomadas ao
longo do processo serão devidamente justificadas e documentadas no
relatório.
O trabalho será desenvolvido utilizando o software R, e o relatório
final incluirá todas as análises, gráficos e previsões, conforme as
instruções fornecidas.
3. Análise descritiva da série temporal
3.1) Visualização
O primeiro passo realizado foi o carregamento do dataset e a
visualização dos dados, utilizando a linguagem R para a tarefa.
Procedeu-se ao carregamento do dataset pretendudi e converteu-se a
coluna ‘’Date’’ para o formato de data. De seguida, visualizaram-se os
primeiros registos do dataset para garantir que os dados foram
carregados corretamente. Por fim, plotou-se a série temporal utilizando
a biblioteca ‘’ggplot2’’ para observar a variação da temperatura ao
longo do tempo.
Quanto ao gráfico obtido, o mesmo mostra temperatura média diária em
Tóquio entre 2019 e 2020, sendo que se podem retirar algumas
observações:

Existe um padrão bem definido que segue as estações do ano. As
temperaturas começam mais baixas no início de 2019, aumentando
gradualmente até atingir um pico por volta de julho a agosto,
representando o verão. Após o pico, as temperaturas começam a cair
novamente, chegando a um ponto mais baixo no inverno (dezembro e
janeiro);
A temperatura atinge o seu valor máximo em torno de 30°C durante
o verão (por volta de julho/agosto de 2019) e o seu valor mais baixo,
próximo de 0°C, no inverno (janeiro de 2020);
Embora o padrão geral seja uma curva suave, existem flutuações
diárias consideráveis, o que reflete a variabilidade do clima no
dia-a-dia.
# Carregar pacotes necessários
library(ggplot2)
# Importar o dataset
data <- read.csv("C:/Users/Sylvie/Downloads/Temperatura_Toquio_dataset.csv")
# Verificar as primeiras linhas dos dados
head(data)
# Converter a coluna 'Date' para formato de data
data$Date <- as.Date(data$Date)
# Visualizar a estrutura do dataset
str(data)
#Visualizar a série temporal
# Criar um gráfico da série temporal
ggplot(data, aes(x = Date, y = Temperature)) +
geom_line(color = "blue") +
labs(title = "Temperatura Média Diária em Tóquio (2019-2020)",
x = "Data", y = "Temperatura (°C)") +
theme_minimal()
3.2) Decomposição
Após, procedeu-se a uma análise estatística básica para compreender a
distribuição inicial dos dados, obtendo informações sobre o Mínimo
(0.890), 1ºQuartil (7.975), Mediana (13.790), Média (14.978), 3ºQuartil
(21.830) e o Máximo (30.300); que permitem entender a distribuição,
centralidade e dispersão da variável ‘’Temperatura’‘. Permite, também,
identificar possíveis outliers ou comportamentos anómalos nos dados.
Depois, verificaram-se os valores em falta. Esta verificação é essencial
para assegurar que não há valores em falta (NA) no conjunto de dados.
Valores ausentes podem impactar negativamente as análises e a modelagem,
especialmente em séries temporais, pois os modelos exigem séries
completas. Se existissem valores em falta (não é o caso, visto que não
existem valores em falta), seria necessário tratar esses dados antes de
continuar a análise, por exemplo, imputando ou interpolando os valores
ausentes. De seguida, procedeu-se à decomposição da série temporal. Este
método permite separar a série em componentes de tendência, sazonalidade
e resíduos, o que permite um melhor entendimento da estrutura dos dados.
Convertendo os dados numa série temporal (ts), podemos decompor a série
usando a função’‘decompose’’. O resultado é um gráfico que demonstra a
tendência (variação de longo prazo), a sazonalidade (padrões
repetitivos) e os resíduos (variações aleatórias). Neste caso, a série
temporal não apresenta períodos ou tem menos do que dois, o que não nos
permite tirar conclusões assertivas.
# Resumo estatístico básico da temperatura
summary(data$Temperature)
# Verificar se há valores em falta (NA)
sum(is.na(data$Temperature))
# Decomposição da série temporal
# Instalar o pacote 'forecast'
# install.packages("forecast")
library(forecast)
# Converter a série temporal
ts_data <- ts(data$Temperature, start = c(2019, 1), frequency = 365)
# Decomposição da série temporal
decomposed <- decompose(ts_data)
plot(decomposed)
4. Modelação da série temporal
Primeiramente, optou-se pela divisão dos dados. Este passo permite
avaliar a precisão do modelo, dividindo os dados em conjuntos de treino
e de teste. O conjunto de treino é utilizado para ajustar o modelo,
enquanto que o conjunto de teste é utilizado para validar
previsões.Neste passo, utilizou-se a função ‘’window’’ para dividir os
dados. O conjunto de treino inclui os dados até 29-02-2020 e o conjunto
de teste inclui os dados a partir de 01-03-2020.
# Dividir os dados em treino e teste
train_data <- window(ts_data,end = c(2020, 59))
test_data <- window(ts_data, start = c(2020, 60))
# Verificar os dados de treino e teste
head(train_data)
head(test_data)
Após a divisão dos dados, prosseguiu-se para a aplicação do modelo
ARIMA. Este modelo é utilizado para modelar séries temporais. Utiliza-se
a função ‘’auto.arima’’ para identificar automaticamente o melhor modelo
ARIMA para os dados de treino.
O resumo do modelo (summary) fornece informações detalhadas sobre os
parâmetros do modelo. De seguida, optou-se pela função ‘’forecast’’ para
fazer previsões para o período de teste e plotou-se as previsões junto
com os valores reais.
# Identificação do modelo ARIMA
fit <- auto.arima(train_data)
summary(fit)
# Previsões
forecasted <- forecast(fit, h =length(test_data))
plot(forecasted)
lines(test_data, col = rgb(1,0,0))
Em média, o modelo ARIMA(2,1,2) ajustou-se bem aos dados com um erro
relativamente baixo (RMSE = 1.8855) e um MAPE de 16.18%, o que sugere
uma precisão razoável nas previsões. O valor de ACF1 muito próximo de 0
sugere que o modelo capturou a maior parte da estrutura da série
temporal, e os resíduos parecem ser ruído aleatório, sem correlação
significativa.
Com base no gráfico apresentado, a linha preta representa os dados
históricos, enquanto que a área sombreada e as linhas a vermelho indicam
as previsões para o futuro:

O modelo ARIMA(2,1,2) foi usado para prever as temperaturas
futuras, sendo útil para capturar padrões sazonais e tendências na série
temporal;
A área sombreada em cinza ao redor da previsão indica o intervalo
de confiança, ou seja, a incerteza da previsão. Quanto mais longe no
futuro, maior a faixa, o que reflete o aumento da incerteza. No gráfico,
o intervalo expande-se ligeiramente conforme o tempo avança, o que é
comum em previsões de séries temporais;
A linha vermelha indica a previsão, que segue um padrão
relativamente semelhante ao ciclo sazonal observado anteriormente, com
oscilações previstas, provavelmente influenciadas por flutuações
sazonais. A previsão sugere que a temperatura irá continuar com
variações em torno dos níveis observados no final de 2019.
Assim, o modelo ARIMA prevê que as temperaturas em Tóquio manterão o
padrão de variação, mas com uma certa incerteza nos valores exatos,
especialmente à medida que o período de previsão avança.
5. Previsões para a série temporal
Para avaliar a precisão das previsões, calculou-se o erro quadrático
médio (MSE). O MSE apresenta-se como a medida da diferença média ao
quadrado entre os valores previstos e os valores reais. Neste caso,
calculou-se o MSE utilizando a diferença entre as previsões e os valores
reais. Um MSE menor indica previsões mais precisas.
# Calcular o erro quadrático médio (MSE)
mse <- mean ((forecasted$mean - test_data)^2)
print(paste('Mean Squared Error:',mse))
Após o cálculo do MSE, com um valor de 15.69 (aproximadamente),
prosseguiu-se com a análise dos resíduos. Esta é importante para
verificar a adecuação do modelo. Os resíduos são as diferenças entre os
valores observados e os valores previstos pelo modelo. Analisou-se a
autocorrelação dos resíduos para identificar padrões não captados pelo
modelo.
As funções ‘’acf’’ e ‘’pacf’’ foram utilizadas para plotar a função
de autocorrelação e a função de autocorrelação parcial dos resíduos. Se
os gráficos ‘’acf’’ e ‘’pacf’’ dos resíduos não apresentam picos
significativos fora dos intervalos de confiança, indica que os resíduos
são aleatórios e o modelo é adequado.


# Análise dos resíduos
residuals <- residuals(fit)
acf(residuals, main = 'ACF dos Resíduos')
pacf(residuals, main = 'PACF dos Resíduos')
# Plotar resíduos
plot(residuals, main = 'Resíduos do Modelo ARIMA', ylab = 'Resíduos')
O gráfico remetente aos resíduos exibe, portanto, os resíduos do
modelo ARIMA usado para prever a temperatura em Tóquio de 2019 a 2020.
Os resíduos representam a diferença entre os valores observados e os
valores previstos pelo modelo ARIMA. Os resíduos parecem estar centrados
em torno de zero, o que é um bom sinal. Isto sugere que o modelo ARIMA,
em média, não está sistematicamente a super ou subestimar as
temperaturas.

O gráfico mostra que os resíduos mantêm uma variação relativamente
constante ao longo do tempo, o que é um indicativo de variância
constante dos resíduos. Esta é uma boa propriedade para um modelo de
série temporal, pois indica que os erros de previsão não aumentam nem
diminuem de maneira sistemática ao longo do tempo.
Idealmente, os resíduos de um modelo ARIMA devem mostrar um “ruído
branco”, ou seja, devem ser não correlacionados e não devem apresentar
padrões ou tendências. O gráfico parece mostrar uma distribuição
aleatória sem padrões visíveis, o que sugere que o modelo capturou bem
as principais tendências e sazonalidades da série temporal.
Embora a maior parte dos resíduos esteja em torno de 0, há alguns
picos de desvios maiores (acima de 4 ou abaixo de -6), indicando que o
modelo teve alguns momentos onde não conseguiu capturar totalmente as
variações da série temporal, possivelmente devido a eventos extremos ou
fatores não modelados.
Por fim, decidiu-se aplicar o teste de Ljung-Box para verificar a
hipótese de que os resíduiso de facto não são autocorrelacionados. Um
p-value alto (geralmente superior a 0.05) indica que não existe
autocorrelação significativa nos resíduos. Como p=0.69, o mesmo
comprova-se.
# Teste de Ljung-Box
Box.test(residuals, lag = 20, type = 'Ljung-Box')
6. Conclusão
A análise das temperaturas médias diárias registadas em Tóquio entre
1 de janeiro de 2019 e 31 de março de 2020 proporcionou uma compreensão
detalhada da estrutura da série temporal, culminando em previsões
fundamentadas e pontos relevantes. O processo iniciou-se com uma análise
descritiva dos dados, que revelou padrões sazonais claros e uma
variabilidade diária notável, características típicas de séries
temporais meteorológicas. A ausência de valores em falta facilitou a
modelagem e garantiu a integridade dos resultados.
A decomposição da série temporal, apesar de limitada devido ao curto
período de observação, foi capaz de isolar componentes essenciais como a
tendência e a sazonalidade, reforçando a importância de modelar
corretamente as oscilações ao longo das estações do ano. Isso indicou
uma série temporal que segue um ciclo natural das estações, com picos no
verão e mínimas no inverno.
O modelo ARIMA, selecionado automaticamente através do método
‘’auto.arima’’, mostrou-se eficaz ao capturar as dinâmicas principais da
série, incluindo os padrões sazonais e a tendência de longo prazo. Com a
escolha do modelo ARIMA(2,1,2), as previsões para os meses subsequentes
exibiram uma trajetória consistente com os padrões históricos de
temperatura, o que indica que o modelo conseguiu generalizar bem as
flutuações da série temporal. O erro quadrático médio (MSE = 15.69)
demonstrou que o modelo tem uma precisão razoável, embora haja espaço
para melhorias, especialmente nos momentos em que ocorreram desvios
maiores.
A análise dos resíduos do modelo revelou resultados positivos. Os
resíduos apresentaram-se como “ruído branco”, ou seja, não mostraram
padrões ou autocorrelações significativas, sugerindo que o modelo
conseguiu capturar a maior parte da estrutura da série temporal. Picos
esporádicos de erros, no entanto, indicam que o modelo poderia ser
aprimorado para capturar eventos climáticos atípicos. A variância
constante dos resíduos ao longo do tempo e o teste de Ljung-Box, com um
p-valor de 0.69, confirmaram que o modelo ajustado não apresentou
autocorrelação significativa, o que valida ainda mais a adequação do
ARIMA para este conjunto de dados.
Em resumo, o modelo ARIMA selecionado foi eficaz para prever as
temperaturas médias diárias em Tóquio, capturando com precisão os
padrões sazonais e as tendências. A análise dos resíduos e os testes de
diagnóstico corroboraram a adequação do modelo, tornando-o uma
ferramenta confiável para previsões futuras, com uma margem de erro
relativamente baixa. Este trabalho demonstra a importância de um
processo rigoroso de análise de séries temporais para entender
comportamentos climáticos e oferece uma base sólida para estudos
meteorológicos futuros ou previsões de temperatura em outras cidades ou
regiões com padrões climáticos semelhantes.
7. Referências
Morettin, P. A., & Toloi, C. M. de C. (2022). Análise de séries
temporais. São Paulo: Blucher.
LS0tDQp0aXRsZTogIkFuw6FsaXNlIGRlIFPDqXJpZXMgVGVtcG9yYWlzIGVtIFIiDQpzdWJ0aXRsZTogJ1RlbXBlcmF0dXJhIE3DqWRpYSBEacOhcmlhIGVtIFTDs3F1aW8nDQphdXRob3I6ICdTeWx2aWUgTWFydGlucyBCb3JnZXMnDQpkYXRlOiAnMjEtMDktMjAyNCcNCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KICAgDQotLS0NCg0KIyAxLiBQcmVmw6FjaW8NCg0KRXN0ZSBlc3R1ZG8gYXByZXNlbnRhIHVtYSBhbsOhbGlzZSBkZXRhbGhhZGEgZGFzIHRlbXBlcmF0dXJhcyBtw6lkaWFzIGRpw6FyaWFzIHJlZ2lzdGFkYXMgZW0gVMOzcXVpbyBlbnRyZSBqYW5laXJvIGRlIDIwMTkgZSBtYXLDp28gZGUgMjAyMCwgdXRpbGl6YW5kbyB0w6ljbmljYXMgZGUgbW9kZWxhZ2VtIGRlIHPDqXJpZXMgdGVtcG9yYWlzLiBBdHJhdsOpcyBkYSBhcGxpY2HDp8OjbyBkbyBtb2RlbG8gQVJJTUEsIGV4cGxvcmFtLXNlIHBhZHLDtWVzIHNhem9uYWlzIGUgdGVuZMOqbmNpYXMgcXVlIGNhcmFjdGVyaXphbSBvIGNsaW1hIGRlIFTDs3F1aW8gZHVyYW50ZSBlc3NlIHBlcsOtb2RvLiBBIG1vZGVsYWdlbSBwZXJtaXRlIG7Do28gc8OzIGNvbXByZWVuZGVyIGFzIHZhcmlhw6fDtWVzIGhpc3TDs3JpY2FzIGRhcyB0ZW1wZXJhdHVyYXMsIGNvbW8gdGFtYsOpbSBwcmV2ZXIgdmFsb3JlcyBmdXR1cm9zIGNvbSB1bSBncmF1IHJhem/DoXZlbCBkZSBwcmVjaXPDo28uIE8gcmVsYXTDs3JpbyBvZmVyZWNlIHVtYSBhYm9yZGFnZW0gcHLDoXRpY2Egw6AgYW7DoWxpc2UgZGUgc8OpcmllcyB0ZW1wb3JhaXMsIGRlc2RlIGEgdmlzdWFsaXphw6fDo28gZG9zIGRhZG9zIGF0w6kgw6AgdmFsaWRhw6fDo28gZG9zIG1vZGVsb3MsIHByb3BvcmNpb25hbmRvIHVtYSB2aXPDo28gaW50ZWdyYWRhIGRvcyBtw6l0b2RvcyBlc3RhdMOtc3RpY29zIHV0aWxpemFkb3MgbmEgcHJldmlzw6NvIGNsaW3DoXRpY2EuDQoNCkF1dG9yDQoNClN5bHZpZSBCb3JnZXMsIG5hc2NpZGEgZW0gMTk5OSwgw6kgdW1hIGVudHVzaWFzdGEgZGFzIENpw6puY2lhcyBIdW1hbmFzIGUgdGVtIHRyaWxoYWRvIHVtIHBlcmN1cnNvIGFjYWTDqW1pY28gcXVlIHJlZmxldGUgYSBzdWEgcGFpeMOjbyBwZWxvIGNvbmhlY2ltZW50byBlIHBlbGEgZ2VzdMOjbyBkZSBwZXNzb2FzLiBJbmljaW91IGEgc3VhIGZvcm1hw6fDo28gbmEgcHJlc3RpZ2lhZGEgVW5pdmVyc2lkYWRlIENhdMOzbGljYSBQb3J0dWd1ZXNhLCBvbmRlIHNlIGdyYWR1b3UgZW0gTMOtbmd1YXMgRXN0cmFuZ2VpcmFzIEFwbGljYWRhcy4gU2VtcHJlIG1vdmlkYSBwZWxhIGN1cmlvc2lkYWRlIGludGVsZWN0dWFsLCBjb250aW51b3Ugb3MgZXN0dWRvcyBjb20gdW0gTWVzdHJhZG8gZW0gR2VzdMOjbyBkZSBSZWN1cnNvcyBIdW1hbm9zLCBwZWxvIElTQ1RFIEJ1c2luZXNzIFNjaG9vbCwgY2FtcG8gb25kZSBkZXNlbnZvbHZldSB1bWEgc8OzbGlkYSBjb21wcmVlbnPDo28gZGEgZGluw6JtaWNhIG9yZ2FuaXphY2lvbmFsLg0KDQpDb20gdW0gb2xoYXIgYXRlbnRvIMOgcyBtdWRhbsOnYXMgZG8gbXVuZG8gbW9kZXJubywgU3lsdmllIHBlcmNlYmV1IHF1ZSBhcyBUZWNub2xvZ2lhcyBkYSBJbmZvcm1hw6fDo28gcmVwcmVzZW50YXZhbSB1bSBub3ZvIGhvcml6b250ZSBwYXJhIGEgZ2VzdMOjbyBkZSBwZXNzb2FzLiBEZXNkZSAyMDIxLCB0ZW0tc2UgZGVkaWNhZG8gYSBleHBsb3JhciBlc3RlIGRvbcOtbmlvIGVtZXJnZW50ZSwgY29uc3RydWluZG8gdW1hIHBvbnRlIGVudHJlIGEgY29tdW5pY2HDp8OjbywgZ2VzdMOjbyBlIGFzIG5vdmFzIGZlcnJhbWVudGFzIHRlY25vbMOzZ2ljYXMuIEVtIGJ1c2NhIGRlIHVtYSBjb21wcmVlbnPDo28gYWluZGEgbWFpcyBwcm9mdW5kYSwgaW5zY3JldmV1LXNlIG51bWEgUMOzcy1HcmFkdWHDp8OjbyBlbSBEYXRhIFNjaWVuY2UgKFVuaXZlcnNpZGFkZSBFdXJvcGVpYSksIGRldGVybWluYWRhIGEgZG9taW5hciBvcyBtw6l0b2RvcyBlIGxpbmd1YWdlbnMgcXVlIG1vbGRhbSBvIHF1b3RpZGlhbm8gZG9zIHByb2Zpc3Npb25haXMgZGFzIFRJLCBlbnJpcXVlY2VuZG8gYXNzaW0gYSBzdWEgY2FwYWNpZGFkZSBkZSBpbnRlcmFnaXIgY29tIGVzdGUgdW5pdmVyc28gZW0gY29uc3RhbnRlIGV2b2x1w6fDo28uDQoNCkxpY2Vuw6dhIEVzdGUgdHJhYmFsaG8gZXN0w6EgbGljZW5jaWFkbyBzb2IgdW1hIGxpY2Vuw6dhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tTm9uQ29tbWVyY2lhbCBTaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIE8gcmVzdWx0YWRvIGRlc3RlIHRyYWJhbGhvIG7Do28gcHJvdmlkZW5jaWEgYWNvbnNlbGhhbWVudG8gZmluYW5jZWlyby4NCg0KDQoNCiMgMi4gSW50cm9kdcOnw6NvDQoNCk8gcHJlc2VudGUgZXN0dWRvIHRlbSBjb21vIG9iamV0aXZvIGEgYW7DoWxpc2UgZGUgdW1hIHPDqXJpZSB0ZW1wb3JhbCByZWZlcmVudGUgw6BzIHRlbXBlcmF0dXJhcyBtw6lkaWFzIGRpw6FyaWFzIHJlZ2lzdGFkYXMgZW0gVMOzcXVpbyBlbnRyZSAxIGRlIGphbmVpcm8gZGUgMjAxOSBlIDMxIGRlIG1hcsOnbyBkZSAyMDIwLiBPIGRhdGFzZXQgdXRpbGl6YWRvIHJlbWV0ZSBwYXJhIHRlbXBlcmF0dXJhIG3DqWRpYSBkacOhcmlhIGVtIGdyYXVzIENlbHNpdXMgZSBzZXLDoSBhbmFsaXNhZG8gY29tIHJlY3Vyc28gYSBtw6l0b2RvcyBkZSBzw6lyaWVzIHRlbXBvcmFpcyBhYm9yZGFkb3Mgbm8gY3Vyc28gZGUgQW7DoWxpc2UgZGUgU8OpcmllcyBUZW1wb3JhaXMuDQoNCkEgYW7DoWxpc2UgZGUgc8OpcmllcyB0ZW1wb3JhaXMgYXByZXNlbnRhLXNlIGNvbW8gdW1hIHTDqWNuaWNhIGVzdGF0w61zdGljYSBxdWUgcGVybWl0ZSBlc3R1ZGFyIG9zIGRhZG9zIHNlcXVlbmNpYWlzIGFvIGxvbmdvIGRvIHRlbXBvLCBpZGVudGlmaWNhciBwYWRyw7VlcyBlIHJlYWxpemFyIHByZXZpc8O1ZXMgZnV0dXJhcyBjb20gYmFzZSBlbSBkYWRvcyBoaXN0w7NyaWNvcy4gRXN0ZSB0aXBvIGRlIGFuw6FsaXNlIMOpIGFtcGxhbWVudGUgdXRpbGl6YWRvIGVtIGRpdmVyc2FzIMOhcmVhcywgY29tbyBhIG1ldGVvcm9sb2dpYSwgZWNvbm9taWEgZSBmaW5hbsOnYXMsIGRldmlkbyDDoCBzdWEgY2FwYWNpZGFkZSBkZSBtb2RlbGFyIGUgcHJldmVyIGNvbXBvcnRhbWVudG9zIGZ1dHVyb3MuDQoNClBhcmEgbyBkZXNlbnZvbHZpbWVudG8gZGVzdGUgdHJhYmFsaG8sIHNlcsOjbyBleHBsb3JhZG9zIGRpZmVyZW50ZXMgbW9kZWxvcyBkZSBzw6lyaWVzIHRlbXBvcmFpcywgY29tbyBvIEFSSU1BIGUgb3V0cm9zIG3DqXRvZG9zLiBPIG9iamV0aXZvIMOpIHNlbGVjaW9uYXIgbyBtb2RlbG8gcXVlIG1lbGhvciBzZSBhanVzdGEgYW9zIGRhZG9zIGRlIHRlbXBlcmF0dXJhIGUsIGNvbSBiYXNlIG5lc3NlIG1vZGVsbywgcmVhbGl6YXIgcHJldmlzw7VlcyBwYXJhIHBlcsOtb2RvcyBmdXR1cm9zLg0KDQpBbMOpbSBkaXNzbywgc2Vyw6EgZmVpdGEgdW1hIGFuw6FsaXNlIGRvcyByZXPDrWR1b3MgZG8gbW9kZWxvIHNlbGVjaW9uYWRvIHBhcmEgdmVyaWZpY2FyIGEgc3VhIGFkZXF1YcOnw6NvIGUsIHBvciBmaW0sIHNlcsOhIGFwcmVzZW50YWRvIHVtIGNvbmp1bnRvIGRlIHByZXZpc8O1ZXMgY29tIGJhc2Ugbm9zIGRhZG9zIGRpc3BvbsOtdmVpcy4gQXMgZGVjaXPDtWVzIHRvbWFkYXMgYW8gbG9uZ28gZG8gcHJvY2Vzc28gc2Vyw6NvIGRldmlkYW1lbnRlIGp1c3RpZmljYWRhcyBlIGRvY3VtZW50YWRhcyBubyByZWxhdMOzcmlvLg0KDQpPIHRyYWJhbGhvIHNlcsOhIGRlc2Vudm9sdmlkbyB1dGlsaXphbmRvIG8gc29mdHdhcmUgUiwgZSBvIHJlbGF0w7NyaW8gZmluYWwgaW5jbHVpcsOhIHRvZGFzIGFzIGFuw6FsaXNlcywgZ3LDoWZpY29zIGUgcHJldmlzw7VlcywgY29uZm9ybWUgYXMgaW5zdHJ1w6fDtWVzIGZvcm5lY2lkYXMuDQoNCiMgMy4gQW7DoWxpc2UgZGVzY3JpdGl2YSBkYSBzw6lyaWUgdGVtcG9yYWwNCg0KIyMgMy4xKSBWaXN1YWxpemHDp8Ojbw0KDQpPIHByaW1laXJvIHBhc3NvIHJlYWxpemFkbyBmb2kgbyBjYXJyZWdhbWVudG8gZG8gZGF0YXNldCBlIGEgdmlzdWFsaXphw6fDo28gZG9zIGRhZG9zLCB1dGlsaXphbmRvIGEgbGluZ3VhZ2VtIFIgcGFyYSBhIHRhcmVmYS4gUHJvY2VkZXUtc2UgYW8gY2FycmVnYW1lbnRvIGRvIGRhdGFzZXQgcHJldGVuZHVkaSBlIGNvbnZlcnRldS1zZSBhIGNvbHVuYSAnJ0RhdGUnJyBwYXJhIG8gZm9ybWF0byBkZSBkYXRhLiBEZSBzZWd1aWRhLCB2aXN1YWxpemFyYW0tc2Ugb3MgcHJpbWVpcm9zIHJlZ2lzdG9zIGRvIGRhdGFzZXQgcGFyYSBnYXJhbnRpciBxdWUgb3MgZGFkb3MgZm9yYW0gY2FycmVnYWRvcyBjb3JyZXRhbWVudGUuIFBvciBmaW0sIHBsb3RvdS1zZSBhIHPDqXJpZSB0ZW1wb3JhbCB1dGlsaXphbmRvIGEgYmlibGlvdGVjYSAnJ2dncGxvdDInJyBwYXJhIG9ic2VydmFyIGEgdmFyaWHDp8OjbyBkYSB0ZW1wZXJhdHVyYSBhbyBsb25nbyBkbyB0ZW1wby4NCg0KUXVhbnRvIGFvIGdyw6FmaWNvIG9idGlkbywgbyBtZXNtbyBtb3N0cmEgdGVtcGVyYXR1cmEgbcOpZGlhIGRpw6FyaWEgZW0gVMOzcXVpbyBlbnRyZSAyMDE5IGUgMjAyMCwgc2VuZG8gcXVlIHNlIHBvZGVtIHJldGlyYXIgYWxndW1hcyBvYnNlcnZhw6fDtWVzOg0KDQohW10oMi5WaXN1YWxpemFyJTIwYSUyMGVzdHJ1dHVyYSUyMGRvJTIwZGF0YXNldC5wbmcpDQoNCi0gICBFeGlzdGUgdW0gcGFkcsOjbyBiZW0gZGVmaW5pZG8gcXVlIHNlZ3VlIGFzIGVzdGHDp8O1ZXMgZG8gYW5vLiBBcyB0ZW1wZXJhdHVyYXMgY29tZcOnYW0gbWFpcyBiYWl4YXMgbm8gaW7DrWNpbyBkZSAyMDE5LCBhdW1lbnRhbmRvIGdyYWR1YWxtZW50ZSBhdMOpIGF0aW5naXIgdW0gcGljbyBwb3Igdm9sdGEgZGUganVsaG8gYSBhZ29zdG8sIHJlcHJlc2VudGFuZG8gbyB2ZXLDo28uIEFww7NzIG8gcGljbywgYXMgdGVtcGVyYXR1cmFzIGNvbWXDp2FtIGEgY2FpciBub3ZhbWVudGUsIGNoZWdhbmRvIGEgdW0gcG9udG8gbWFpcyBiYWl4byBubyBpbnZlcm5vIChkZXplbWJybyBlIGphbmVpcm8pOw0KDQotICAgQSB0ZW1wZXJhdHVyYSBhdGluZ2UgbyBzZXUgdmFsb3IgbcOheGltbyBlbSB0b3JubyBkZSAzMMKwQyBkdXJhbnRlIG8gdmVyw6NvIChwb3Igdm9sdGEgZGUganVsaG8vYWdvc3RvIGRlIDIwMTkpIGUgbyBzZXUgdmFsb3IgbWFpcyBiYWl4bywgcHLDs3hpbW8gZGUgMMKwQywgbm8gaW52ZXJubyAoamFuZWlybyBkZSAyMDIwKTsNCg0KLSAgIEVtYm9yYSBvIHBhZHLDo28gZ2VyYWwgc2VqYSB1bWEgY3VydmEgc3VhdmUsIGV4aXN0ZW0gZmx1dHVhw6fDtWVzIGRpw6FyaWFzIGNvbnNpZGVyw6F2ZWlzLCBvIHF1ZSByZWZsZXRlIGEgdmFyaWFiaWxpZGFkZSBkbyBjbGltYSBubyBkaWEtYS1kaWEuDQoNCmBgYHtyfQ0KIyBDYXJyZWdhciBwYWNvdGVzIG5lY2Vzc8Ohcmlvcw0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIEltcG9ydGFyIG8gZGF0YXNldA0KZGF0YSA8LSByZWFkLmNzdigiQzovVXNlcnMvU3lsdmllL0Rvd25sb2Fkcy9UZW1wZXJhdHVyYV9Ub3F1aW9fZGF0YXNldC5jc3YiKQ0KDQojIFZlcmlmaWNhciBhcyBwcmltZWlyYXMgbGluaGFzIGRvcyBkYWRvcw0KaGVhZChkYXRhKQ0KDQojIENvbnZlcnRlciBhIGNvbHVuYSAnRGF0ZScgcGFyYSBmb3JtYXRvIGRlIGRhdGENCmRhdGEkRGF0ZSA8LSBhcy5EYXRlKGRhdGEkRGF0ZSkNCg0KIyBWaXN1YWxpemFyIGEgZXN0cnV0dXJhIGRvIGRhdGFzZXQNCnN0cihkYXRhKQ0KDQojVmlzdWFsaXphciBhIHPDqXJpZSB0ZW1wb3JhbA0KIyBDcmlhciB1bSBncsOhZmljbyBkYSBzw6lyaWUgdGVtcG9yYWwNCmdncGxvdChkYXRhLCBhZXMoeCA9IERhdGUsIHkgPSBUZW1wZXJhdHVyZSkpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gImJsdWUiKSArDQogIGxhYnModGl0bGUgPSAiVGVtcGVyYXR1cmEgTcOpZGlhIERpw6FyaWEgZW0gVMOzcXVpbyAoMjAxOS0yMDIwKSIsDQogICAgICAgeCA9ICJEYXRhIiwgeSA9ICJUZW1wZXJhdHVyYSAowrBDKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQojIyAzLjIpIERlY29tcG9zacOnw6NvDQoNCkFww7NzLCBwcm9jZWRldS1zZSBhIHVtYSBhbsOhbGlzZSBlc3RhdMOtc3RpY2EgYsOhc2ljYSBwYXJhIGNvbXByZWVuZGVyIGEgZGlzdHJpYnVpw6fDo28gaW5pY2lhbCBkb3MgZGFkb3MsIG9idGVuZG8gaW5mb3JtYcOnw7VlcyBzb2JyZSBvIE3DrW5pbW8gKDAuODkwKSwgMcK6UXVhcnRpbCAoNy45NzUpLCBNZWRpYW5hICgxMy43OTApLCBNw6lkaWEgKDE0Ljk3OCksIDPCulF1YXJ0aWwgKDIxLjgzMCkgZSBvIE3DoXhpbW8gKDMwLjMwMCk7IHF1ZSBwZXJtaXRlbSBlbnRlbmRlciBhIGRpc3RyaWJ1acOnw6NvLCBjZW50cmFsaWRhZGUgZSBkaXNwZXJzw6NvIGRhIHZhcmnDoXZlbCAnJ1RlbXBlcmF0dXJhJycuIFBlcm1pdGUsIHRhbWLDqW0sIGlkZW50aWZpY2FyIHBvc3PDrXZlaXMgb3V0bGllcnMgb3UgY29tcG9ydGFtZW50b3MgYW7Ds21hbG9zIG5vcyBkYWRvcy4gRGVwb2lzLCB2ZXJpZmljYXJhbS1zZSBvcyB2YWxvcmVzIGVtIGZhbHRhLiBFc3RhIHZlcmlmaWNhw6fDo28gw6kgZXNzZW5jaWFsIHBhcmEgYXNzZWd1cmFyIHF1ZSBuw6NvIGjDoSB2YWxvcmVzIGVtIGZhbHRhIChOQSkgbm8gY29uanVudG8gZGUgZGFkb3MuIFZhbG9yZXMgYXVzZW50ZXMgcG9kZW0gaW1wYWN0YXIgbmVnYXRpdmFtZW50ZSBhcyBhbsOhbGlzZXMgZSBhIG1vZGVsYWdlbSwgZXNwZWNpYWxtZW50ZSBlbSBzw6lyaWVzIHRlbXBvcmFpcywgcG9pcyBvcyBtb2RlbG9zIGV4aWdlbSBzw6lyaWVzIGNvbXBsZXRhcy4gU2UgZXhpc3Rpc3NlbSB2YWxvcmVzIGVtIGZhbHRhIChuw6NvIMOpIG8gY2FzbywgdmlzdG8gcXVlIG7Do28gZXhpc3RlbSB2YWxvcmVzIGVtIGZhbHRhKSwgc2VyaWEgbmVjZXNzw6FyaW8gdHJhdGFyIGVzc2VzIGRhZG9zIGFudGVzIGRlIGNvbnRpbnVhciBhIGFuw6FsaXNlLCBwb3IgZXhlbXBsbywgaW1wdXRhbmRvIG91IGludGVycG9sYW5kbyBvcyB2YWxvcmVzIGF1c2VudGVzLiBEZSBzZWd1aWRhLCBwcm9jZWRldS1zZSDDoCBkZWNvbXBvc2nDp8OjbyBkYSBzw6lyaWUgdGVtcG9yYWwuIEVzdGUgbcOpdG9kbyBwZXJtaXRlIHNlcGFyYXIgYSBzw6lyaWUgZW0gY29tcG9uZW50ZXMgZGUgdGVuZMOqbmNpYSwgc2F6b25hbGlkYWRlIGUgcmVzw61kdW9zLCBvIHF1ZSBwZXJtaXRlIHVtIG1lbGhvciBlbnRlbmRpbWVudG8gZGEgZXN0cnV0dXJhIGRvcyBkYWRvcy4gQ29udmVydGVuZG8gb3MgZGFkb3MgbnVtYSBzw6lyaWUgdGVtcG9yYWwgKHRzKSwgcG9kZW1vcyBkZWNvbXBvciBhIHPDqXJpZSB1c2FuZG8gYSBmdW7Dp8OjbyAnJ2RlY29tcG9zZScnLiBPIHJlc3VsdGFkbyDDqSB1bSBncsOhZmljbyBxdWUgZGVtb25zdHJhIGEgdGVuZMOqbmNpYSAodmFyaWHDp8OjbyBkZSBsb25nbyBwcmF6byksIGEgc2F6b25hbGlkYWRlIChwYWRyw7VlcyByZXBldGl0aXZvcykgZSBvcyByZXPDrWR1b3MgKHZhcmlhw6fDtWVzIGFsZWF0w7NyaWFzKS4gTmVzdGUgY2FzbywgYSBzw6lyaWUgdGVtcG9yYWwgbsOjbyBhcHJlc2VudGEgcGVyw61vZG9zIG91IHRlbSBtZW5vcyBkbyBxdWUgZG9pcywgbyBxdWUgbsOjbyBub3MgcGVybWl0ZSB0aXJhciBjb25jbHVzw7VlcyBhc3NlcnRpdmFzLg0KDQpgYGB7cn0NCiMgUmVzdW1vIGVzdGF0w61zdGljbyBiw6FzaWNvIGRhIHRlbXBlcmF0dXJhDQpzdW1tYXJ5KGRhdGEkVGVtcGVyYXR1cmUpDQoNCiMgVmVyaWZpY2FyIHNlIGjDoSB2YWxvcmVzIGVtIGZhbHRhIChOQSkNCnN1bShpcy5uYShkYXRhJFRlbXBlcmF0dXJlKSkNCg0KDQojIERlY29tcG9zacOnw6NvIGRhIHPDqXJpZSB0ZW1wb3JhbA0KIyBJbnN0YWxhciBvIHBhY290ZSAnZm9yZWNhc3QnDQojIGluc3RhbGwucGFja2FnZXMoImZvcmVjYXN0IikNCmxpYnJhcnkoZm9yZWNhc3QpDQoNCiMgQ29udmVydGVyIGEgc8OpcmllIHRlbXBvcmFsDQp0c19kYXRhIDwtIHRzKGRhdGEkVGVtcGVyYXR1cmUsIHN0YXJ0ID0gYygyMDE5LCAxKSwgZnJlcXVlbmN5ID0gMzY1KQ0KDQojIERlY29tcG9zacOnw6NvIGRhIHPDqXJpZSB0ZW1wb3JhbA0KZGVjb21wb3NlZCA8LSBkZWNvbXBvc2UodHNfZGF0YSkNCnBsb3QoZGVjb21wb3NlZCkNCmBgYA0KDQojIDQuIE1vZGVsYcOnw6NvIGRhIHPDqXJpZSB0ZW1wb3JhbA0KDQpQcmltZWlyYW1lbnRlLCBvcHRvdS1zZSBwZWxhIGRpdmlzw6NvIGRvcyBkYWRvcy4gRXN0ZSBwYXNzbyBwZXJtaXRlIGF2YWxpYXIgYSBwcmVjaXPDo28gZG8gbW9kZWxvLCBkaXZpZGluZG8gb3MgZGFkb3MgZW0gY29uanVudG9zIGRlIHRyZWlubyBlIGRlIHRlc3RlLiBPIGNvbmp1bnRvIGRlIHRyZWlubyDDqSB1dGlsaXphZG8gcGFyYSBhanVzdGFyIG8gbW9kZWxvLCBlbnF1YW50byBxdWUgbyBjb25qdW50byBkZSB0ZXN0ZSDDqSB1dGlsaXphZG8gcGFyYSB2YWxpZGFyIHByZXZpc8O1ZXMuTmVzdGUgcGFzc28sIHV0aWxpem91LXNlIGEgZnVuw6fDo28gJyd3aW5kb3cnJyBwYXJhIGRpdmlkaXIgb3MgZGFkb3MuIE8gY29uanVudG8gZGUgdHJlaW5vIGluY2x1aSBvcyBkYWRvcyBhdMOpIDI5LTAyLTIwMjAgZSBvIGNvbmp1bnRvIGRlIHRlc3RlIGluY2x1aSBvcyBkYWRvcyBhIHBhcnRpciBkZSAwMS0wMy0yMDIwLg0KDQpgYGB7cn0NCiMgRGl2aWRpciBvcyBkYWRvcyBlbSB0cmVpbm8gZSB0ZXN0ZQ0KdHJhaW5fZGF0YSA8LSB3aW5kb3codHNfZGF0YSxlbmQgPSBjKDIwMjAsIDU5KSkNCnRlc3RfZGF0YSA8LSB3aW5kb3codHNfZGF0YSwgc3RhcnQgPSBjKDIwMjAsIDYwKSkNCg0KIyBWZXJpZmljYXIgb3MgZGFkb3MgZGUgdHJlaW5vIGUgdGVzdGUNCmhlYWQodHJhaW5fZGF0YSkNCmhlYWQodGVzdF9kYXRhKQ0KYGBgDQoNCkFww7NzIGEgZGl2aXPDo28gZG9zIGRhZG9zLCBwcm9zc2VndWl1LXNlIHBhcmEgYSBhcGxpY2HDp8OjbyBkbyBtb2RlbG8gQVJJTUEuIEVzdGUgbW9kZWxvIMOpIHV0aWxpemFkbyBwYXJhIG1vZGVsYXIgc8OpcmllcyB0ZW1wb3JhaXMuIFV0aWxpemEtc2UgYSBmdW7Dp8OjbyAnJ2F1dG8uYXJpbWEnJyBwYXJhIGlkZW50aWZpY2FyIGF1dG9tYXRpY2FtZW50ZSBvIG1lbGhvciBtb2RlbG8gQVJJTUEgcGFyYSBvcyBkYWRvcyBkZSB0cmVpbm8uDQoNCk8gcmVzdW1vIGRvIG1vZGVsbyAoc3VtbWFyeSkgZm9ybmVjZSBpbmZvcm1hw6fDtWVzIGRldGFsaGFkYXMgc29icmUgb3MgcGFyw6JtZXRyb3MgZG8gbW9kZWxvLiBEZSBzZWd1aWRhLCBvcHRvdS1zZSBwZWxhIGZ1bsOnw6NvICcnZm9yZWNhc3QnJyBwYXJhIGZhemVyIHByZXZpc8O1ZXMgcGFyYSBvIHBlcsOtb2RvIGRlIHRlc3RlIGUgcGxvdG91LXNlIGFzIHByZXZpc8O1ZXMganVudG8gY29tIG9zIHZhbG9yZXMgcmVhaXMuDQoNCmBgYHtyfQ0KIyBJZGVudGlmaWNhw6fDo28gZG8gbW9kZWxvIEFSSU1BDQpmaXQgPC0gYXV0by5hcmltYSh0cmFpbl9kYXRhKQ0Kc3VtbWFyeShmaXQpDQoNCiMgUHJldmlzw7Vlcw0KZm9yZWNhc3RlZCA8LSBmb3JlY2FzdChmaXQsIGggPWxlbmd0aCh0ZXN0X2RhdGEpKQ0KcGxvdChmb3JlY2FzdGVkKQ0KbGluZXModGVzdF9kYXRhLCBjb2wgPSByZ2IoMSwwLDApKQ0KYGBgDQoNCkVtIG3DqWRpYSwgbyBtb2RlbG8gQVJJTUEoMiwxLDIpIGFqdXN0b3Utc2UgYmVtIGFvcyBkYWRvcyBjb20gdW0gZXJybyByZWxhdGl2YW1lbnRlIGJhaXhvIChSTVNFID0gMS44ODU1KSBlIHVtIE1BUEUgZGUgMTYuMTglLCBvIHF1ZSBzdWdlcmUgdW1hIHByZWNpc8OjbyByYXpvw6F2ZWwgbmFzIHByZXZpc8O1ZXMuIE8gdmFsb3IgZGUgQUNGMSBtdWl0byBwcsOzeGltbyBkZSAwIHN1Z2VyZSBxdWUgbyBtb2RlbG8gY2FwdHVyb3UgYSBtYWlvciBwYXJ0ZSBkYSBlc3RydXR1cmEgZGEgc8OpcmllIHRlbXBvcmFsLCBlIG9zIHJlc8OtZHVvcyBwYXJlY2VtIHNlciBydcOtZG8gYWxlYXTDs3Jpbywgc2VtIGNvcnJlbGHDp8OjbyBzaWduaWZpY2F0aXZhLg0KDQpDb20gYmFzZSBubyBncsOhZmljbyBhcHJlc2VudGFkbywgYSBsaW5oYSBwcmV0YSByZXByZXNlbnRhIG9zIGRhZG9zIGhpc3TDs3JpY29zLCBlbnF1YW50byBxdWUgYSDDoXJlYSBzb21icmVhZGEgZSBhcyBsaW5oYXMgYSB2ZXJtZWxobyBpbmRpY2FtIGFzIHByZXZpc8O1ZXMgcGFyYSBvIGZ1dHVybzoNCg0KIVtdKDYuRm9yZWNhc3QlMjBBcmltYS5wbmcpDQoNCi0gICBPIG1vZGVsbyBBUklNQSgyLDEsMikgZm9pIHVzYWRvIHBhcmEgcHJldmVyIGFzIHRlbXBlcmF0dXJhcyBmdXR1cmFzLCBzZW5kbyDDunRpbCBwYXJhIGNhcHR1cmFyIHBhZHLDtWVzIHNhem9uYWlzIGUgdGVuZMOqbmNpYXMgbmEgc8OpcmllIHRlbXBvcmFsOw0KDQotICAgQSDDoXJlYSBzb21icmVhZGEgZW0gY2luemEgYW8gcmVkb3IgZGEgcHJldmlzw6NvIGluZGljYSBvIGludGVydmFsbyBkZSBjb25maWFuw6dhLCBvdSBzZWphLCBhIGluY2VydGV6YSBkYSBwcmV2aXPDo28uIFF1YW50byBtYWlzIGxvbmdlIG5vIGZ1dHVybywgbWFpb3IgYSBmYWl4YSwgbyBxdWUgcmVmbGV0ZSBvIGF1bWVudG8gZGEgaW5jZXJ0ZXphLiBObyBncsOhZmljbywgbyBpbnRlcnZhbG8gZXhwYW5kZS1zZSBsaWdlaXJhbWVudGUgY29uZm9ybWUgbyB0ZW1wbyBhdmFuw6dhLCBvIHF1ZSDDqSBjb211bSBlbSBwcmV2aXPDtWVzIGRlIHPDqXJpZXMgdGVtcG9yYWlzOw0KDQotICAgQSBsaW5oYSB2ZXJtZWxoYSBpbmRpY2EgYSBwcmV2aXPDo28sIHF1ZSBzZWd1ZSB1bSBwYWRyw6NvIHJlbGF0aXZhbWVudGUgc2VtZWxoYW50ZSBhbyBjaWNsbyBzYXpvbmFsIG9ic2VydmFkbyBhbnRlcmlvcm1lbnRlLCBjb20gb3NjaWxhw6fDtWVzIHByZXZpc3RhcywgcHJvdmF2ZWxtZW50ZSBpbmZsdWVuY2lhZGFzIHBvciBmbHV0dWHDp8O1ZXMgc2F6b25haXMuIEEgcHJldmlzw6NvIHN1Z2VyZSBxdWUgYSB0ZW1wZXJhdHVyYSBpcsOhIGNvbnRpbnVhciBjb20gdmFyaWHDp8O1ZXMgZW0gdG9ybm8gZG9zIG7DrXZlaXMgb2JzZXJ2YWRvcyBubyBmaW5hbCBkZSAyMDE5Lg0KDQpBc3NpbSwgbyBtb2RlbG8gQVJJTUEgcHJldsOqIHF1ZSBhcyB0ZW1wZXJhdHVyYXMgZW0gVMOzcXVpbyBtYW50ZXLDo28gbyBwYWRyw6NvIGRlIHZhcmlhw6fDo28sIG1hcyBjb20gdW1hIGNlcnRhIGluY2VydGV6YSBub3MgdmFsb3JlcyBleGF0b3MsIGVzcGVjaWFsbWVudGUgw6AgbWVkaWRhIHF1ZSBvIHBlcsOtb2RvIGRlIHByZXZpc8OjbyBhdmFuw6dhLg0KDQojIDUuIFByZXZpc8O1ZXMgcGFyYSBhIHPDqXJpZSB0ZW1wb3JhbA0KDQpQYXJhIGF2YWxpYXIgYSBwcmVjaXPDo28gZGFzIHByZXZpc8O1ZXMsIGNhbGN1bG91LXNlIG8gZXJybyBxdWFkcsOhdGljbyBtw6lkaW8gKE1TRSkuIE8gTVNFIGFwcmVzZW50YS1zZSBjb21vIGEgbWVkaWRhIGRhIGRpZmVyZW7Dp2EgbcOpZGlhIGFvIHF1YWRyYWRvIGVudHJlIG9zIHZhbG9yZXMgcHJldmlzdG9zIGUgb3MgdmFsb3JlcyByZWFpcy4gTmVzdGUgY2FzbywgY2FsY3Vsb3Utc2UgbyBNU0UgdXRpbGl6YW5kbyBhIGRpZmVyZW7Dp2EgZW50cmUgYXMgcHJldmlzw7VlcyBlIG9zIHZhbG9yZXMgcmVhaXMuIFVtIE1TRSBtZW5vciBpbmRpY2EgcHJldmlzw7VlcyBtYWlzIHByZWNpc2FzLg0KDQpgYGB7cn0NCiMgQ2FsY3VsYXIgbyBlcnJvIHF1YWRyw6F0aWNvIG3DqWRpbyAoTVNFKQ0KbXNlIDwtIG1lYW4gKChmb3JlY2FzdGVkJG1lYW4gLSB0ZXN0X2RhdGEpXjIpDQpwcmludChwYXN0ZSgnTWVhbiBTcXVhcmVkIEVycm9yOicsbXNlKSkNCmBgYA0KDQpBcMOzcyBvIGPDoWxjdWxvIGRvIE1TRSwgY29tIHVtIHZhbG9yIGRlIDE1LjY5IChhcHJveGltYWRhbWVudGUpLCBwcm9zc2VndWl1LXNlIGNvbSBhIGFuw6FsaXNlIGRvcyByZXPDrWR1b3MuIEVzdGEgw6kgaW1wb3J0YW50ZSBwYXJhIHZlcmlmaWNhciBhIGFkZWN1YcOnw6NvIGRvIG1vZGVsby4gT3MgcmVzw61kdW9zIHPDo28gYXMgZGlmZXJlbsOnYXMgZW50cmUgb3MgdmFsb3JlcyBvYnNlcnZhZG9zIGUgb3MgdmFsb3JlcyBwcmV2aXN0b3MgcGVsbyBtb2RlbG8uIEFuYWxpc291LXNlIGEgYXV0b2NvcnJlbGHDp8OjbyBkb3MgcmVzw61kdW9zIHBhcmEgaWRlbnRpZmljYXIgcGFkcsO1ZXMgbsOjbyBjYXB0YWRvcyBwZWxvIG1vZGVsby4NCg0KQXMgZnVuw6fDtWVzICcnYWNmJycgZSAnJ3BhY2YnJyBmb3JhbSB1dGlsaXphZGFzIHBhcmEgcGxvdGFyIGEgZnVuw6fDo28gZGUgYXV0b2NvcnJlbGHDp8OjbyBlIGEgZnVuw6fDo28gZGUgYXV0b2NvcnJlbGHDp8OjbyBwYXJjaWFsIGRvcyByZXPDrWR1b3MuIFNlIG9zIGdyw6FmaWNvcyAnJ2FjZicnIGUgJydwYWNmJycgZG9zIHJlc8OtZHVvcyBuw6NvIGFwcmVzZW50YW0gcGljb3Mgc2lnbmlmaWNhdGl2b3MgZm9yYSBkb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuw6dhLCBpbmRpY2EgcXVlIG9zIHJlc8OtZHVvcyBzw6NvIGFsZWF0w7NyaW9zIGUgbyBtb2RlbG8gw6kgYWRlcXVhZG8uDQoNCiFbXShpbWFnZXMvQ2FwdHVyYSUyMGRlJTIwZWNyw6MlMjAyMDI0LTA5LTE2JTIwMjAwNjMwLnBuZyl7d2lkdGg9IjIzMiJ9DQoNCiFbXShpbWFnZXMvQ2FwdHVyYSUyMGRlJTIwZWNyw6MlMjAyMDI0LTA5LTE2JTIwMjAwNTM1LnBuZyl7d2lkdGg9IjIzNiJ9DQoNCmBgYHtyfQ0KIyBBbsOhbGlzZSBkb3MgcmVzw61kdW9zDQpyZXNpZHVhbHMgPC0gcmVzaWR1YWxzKGZpdCkNCmFjZihyZXNpZHVhbHMsIG1haW4gPSAnQUNGIGRvcyBSZXPDrWR1b3MnKQ0KcGFjZihyZXNpZHVhbHMsIG1haW4gPSAnUEFDRiBkb3MgUmVzw61kdW9zJykNCg0KIyBQbG90YXIgcmVzw61kdW9zDQpwbG90KHJlc2lkdWFscywgbWFpbiA9ICdSZXPDrWR1b3MgZG8gTW9kZWxvIEFSSU1BJywgeWxhYiA9ICdSZXPDrWR1b3MnKQ0KYGBgDQoNCk8gZ3LDoWZpY28gcmVtZXRlbnRlIGFvcyByZXPDrWR1b3MgZXhpYmUsIHBvcnRhbnRvLCBvcyByZXPDrWR1b3MgZG8gbW9kZWxvIEFSSU1BIHVzYWRvIHBhcmEgcHJldmVyIGEgdGVtcGVyYXR1cmEgZW0gVMOzcXVpbyBkZSAyMDE5IGEgMjAyMC4gT3MgcmVzw61kdW9zIHJlcHJlc2VudGFtIGEgZGlmZXJlbsOnYSBlbnRyZSBvcyB2YWxvcmVzIG9ic2VydmFkb3MgZSBvcyB2YWxvcmVzIHByZXZpc3RvcyBwZWxvIG1vZGVsbyBBUklNQS4gT3MgcmVzw61kdW9zIHBhcmVjZW0gZXN0YXIgY2VudHJhZG9zIGVtIHRvcm5vIGRlIHplcm8sIG8gcXVlIMOpIHVtIGJvbSBzaW5hbC4gSXN0byBzdWdlcmUgcXVlIG8gbW9kZWxvIEFSSU1BLCBlbSBtw6lkaWEsIG7Do28gZXN0w6Egc2lzdGVtYXRpY2FtZW50ZSBhIHN1cGVyIG91IHN1YmVzdGltYXIgYXMgdGVtcGVyYXR1cmFzLg0KDQohW10oOC5SZXPDrWR1b3MlMjBtb2RlbG8lMjBhcmltYS5wbmcpDQoNCk8gZ3LDoWZpY28gbW9zdHJhIHF1ZSBvcyByZXPDrWR1b3MgbWFudMOqbSB1bWEgdmFyaWHDp8OjbyByZWxhdGl2YW1lbnRlIGNvbnN0YW50ZSBhbyBsb25nbyBkbyB0ZW1wbywgbyBxdWUgw6kgdW0gaW5kaWNhdGl2byBkZSB2YXJpw6JuY2lhIGNvbnN0YW50ZSBkb3MgcmVzw61kdW9zLiBFc3RhIMOpIHVtYSBib2EgcHJvcHJpZWRhZGUgcGFyYSB1bSBtb2RlbG8gZGUgc8OpcmllIHRlbXBvcmFsLCBwb2lzIGluZGljYSBxdWUgb3MgZXJyb3MgZGUgcHJldmlzw6NvIG7Do28gYXVtZW50YW0gbmVtIGRpbWludWVtIGRlIG1hbmVpcmEgc2lzdGVtw6F0aWNhIGFvIGxvbmdvIGRvIHRlbXBvLg0KDQpJZGVhbG1lbnRlLCBvcyByZXPDrWR1b3MgZGUgdW0gbW9kZWxvIEFSSU1BIGRldmVtIG1vc3RyYXIgdW0gInJ1w61kbyBicmFuY28iLCBvdSBzZWphLCBkZXZlbSBzZXIgbsOjbyBjb3JyZWxhY2lvbmFkb3MgZSBuw6NvIGRldmVtIGFwcmVzZW50YXIgcGFkcsO1ZXMgb3UgdGVuZMOqbmNpYXMuIE8gZ3LDoWZpY28gcGFyZWNlIG1vc3RyYXIgdW1hIGRpc3RyaWJ1acOnw6NvIGFsZWF0w7NyaWEgc2VtIHBhZHLDtWVzIHZpc8OtdmVpcywgbyBxdWUgc3VnZXJlIHF1ZSBvIG1vZGVsbyBjYXB0dXJvdSBiZW0gYXMgcHJpbmNpcGFpcyB0ZW5kw6puY2lhcyBlIHNhem9uYWxpZGFkZXMgZGEgc8OpcmllIHRlbXBvcmFsLg0KDQpFbWJvcmEgYSBtYWlvciBwYXJ0ZSBkb3MgcmVzw61kdW9zIGVzdGVqYSBlbSB0b3JubyBkZSAwLCBow6EgYWxndW5zIHBpY29zIGRlIGRlc3Zpb3MgbWFpb3JlcyAoYWNpbWEgZGUgNCBvdSBhYmFpeG8gZGUgLTYpLCBpbmRpY2FuZG8gcXVlIG8gbW9kZWxvIHRldmUgYWxndW5zIG1vbWVudG9zIG9uZGUgbsOjbyBjb25zZWd1aXUgY2FwdHVyYXIgdG90YWxtZW50ZSBhcyB2YXJpYcOnw7VlcyBkYSBzw6lyaWUgdGVtcG9yYWwsIHBvc3NpdmVsbWVudGUgZGV2aWRvIGEgZXZlbnRvcyBleHRyZW1vcyBvdSBmYXRvcmVzIG7Do28gbW9kZWxhZG9zLg0KDQpQb3IgZmltLCBkZWNpZGl1LXNlIGFwbGljYXIgbyB0ZXN0ZSBkZSBManVuZy1Cb3ggcGFyYSB2ZXJpZmljYXIgYSBoaXDDs3Rlc2UgZGUgcXVlIG9zIHJlc8OtZHVpc28gZGUgZmFjdG8gbsOjbyBzw6NvIGF1dG9jb3JyZWxhY2lvbmFkb3MuIFVtIHAtdmFsdWUgYWx0byAoZ2VyYWxtZW50ZSBzdXBlcmlvciBhIDAuMDUpIGluZGljYSBxdWUgbsOjbyBleGlzdGUgYXV0b2NvcnJlbGHDp8OjbyBzaWduaWZpY2F0aXZhIG5vcyByZXPDrWR1b3MuIENvbW8gcD0wLjY5LCBvIG1lc21vIGNvbXByb3ZhLXNlLg0KDQpgYGB7cn0NCiMgVGVzdGUgZGUgTGp1bmctQm94DQpCb3gudGVzdChyZXNpZHVhbHMsIGxhZyA9IDIwLCB0eXBlID0gJ0xqdW5nLUJveCcpDQpgYGANCg0KDQoNCiMgNi4gQ29uY2x1c8Ojbw0KDQpBIGFuw6FsaXNlIGRhcyB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBkacOhcmlhcyByZWdpc3RhZGFzIGVtIFTDs3F1aW8gZW50cmUgMSBkZSBqYW5laXJvIGRlIDIwMTkgZSAzMSBkZSBtYXLDp28gZGUgMjAyMCBwcm9wb3JjaW9ub3UgdW1hIGNvbXByZWVuc8OjbyBkZXRhbGhhZGEgZGEgZXN0cnV0dXJhIGRhIHPDqXJpZSB0ZW1wb3JhbCwgY3VsbWluYW5kbyBlbSBwcmV2aXPDtWVzIGZ1bmRhbWVudGFkYXMgZSBwb250b3MgcmVsZXZhbnRlcy4gTyBwcm9jZXNzbyBpbmljaW91LXNlIGNvbSB1bWEgYW7DoWxpc2UgZGVzY3JpdGl2YSBkb3MgZGFkb3MsIHF1ZSByZXZlbG91IHBhZHLDtWVzIHNhem9uYWlzIGNsYXJvcyBlIHVtYSB2YXJpYWJpbGlkYWRlIGRpw6FyaWEgbm90w6F2ZWwsIGNhcmFjdGVyw61zdGljYXMgdMOtcGljYXMgZGUgc8OpcmllcyB0ZW1wb3JhaXMgbWV0ZW9yb2zDs2dpY2FzLiBBIGF1c8OqbmNpYSBkZSB2YWxvcmVzIGVtIGZhbHRhIGZhY2lsaXRvdSBhIG1vZGVsYWdlbSBlIGdhcmFudGl1IGEgaW50ZWdyaWRhZGUgZG9zIHJlc3VsdGFkb3MuDQoNCkEgZGVjb21wb3Npw6fDo28gZGEgc8OpcmllIHRlbXBvcmFsLCBhcGVzYXIgZGUgbGltaXRhZGEgZGV2aWRvIGFvIGN1cnRvIHBlcsOtb2RvIGRlIG9ic2VydmHDp8OjbywgZm9pIGNhcGF6IGRlIGlzb2xhciBjb21wb25lbnRlcyBlc3NlbmNpYWlzIGNvbW8gYSB0ZW5kw6puY2lhIGUgYSBzYXpvbmFsaWRhZGUsIHJlZm9yw6dhbmRvIGEgaW1wb3J0w6JuY2lhIGRlIG1vZGVsYXIgY29ycmV0YW1lbnRlIGFzIG9zY2lsYcOnw7VlcyBhbyBsb25nbyBkYXMgZXN0YcOnw7VlcyBkbyBhbm8uIElzc28gaW5kaWNvdSB1bWEgc8OpcmllIHRlbXBvcmFsIHF1ZSBzZWd1ZSB1bSBjaWNsbyBuYXR1cmFsIGRhcyBlc3Rhw6fDtWVzLCBjb20gcGljb3Mgbm8gdmVyw6NvIGUgbcOtbmltYXMgbm8gaW52ZXJuby4NCg0KTyBtb2RlbG8gQVJJTUEsIHNlbGVjaW9uYWRvIGF1dG9tYXRpY2FtZW50ZSBhdHJhdsOpcyBkbyBtw6l0b2RvICcnYXV0by5hcmltYScnLCBtb3N0cm91LXNlIGVmaWNheiBhbyBjYXB0dXJhciBhcyBkaW7Dom1pY2FzIHByaW5jaXBhaXMgZGEgc8OpcmllLCBpbmNsdWluZG8gb3MgcGFkcsO1ZXMgc2F6b25haXMgZSBhIHRlbmTDqm5jaWEgZGUgbG9uZ28gcHJhem8uIENvbSBhIGVzY29saGEgZG8gbW9kZWxvIEFSSU1BKDIsMSwyKSwgYXMgcHJldmlzw7VlcyBwYXJhIG9zIG1lc2VzIHN1YnNlcXVlbnRlcyBleGliaXJhbSB1bWEgdHJhamV0w7NyaWEgY29uc2lzdGVudGUgY29tIG9zIHBhZHLDtWVzIGhpc3TDs3JpY29zIGRlIHRlbXBlcmF0dXJhLCBvIHF1ZSBpbmRpY2EgcXVlIG8gbW9kZWxvIGNvbnNlZ3VpdSBnZW5lcmFsaXphciBiZW0gYXMgZmx1dHVhw6fDtWVzIGRhIHPDqXJpZSB0ZW1wb3JhbC4gTyBlcnJvIHF1YWRyw6F0aWNvIG3DqWRpbyAoTVNFID0gMTUuNjkpIGRlbW9uc3Ryb3UgcXVlIG8gbW9kZWxvIHRlbSB1bWEgcHJlY2lzw6NvIHJhem/DoXZlbCwgZW1ib3JhIGhhamEgZXNwYcOnbyBwYXJhIG1lbGhvcmlhcywgZXNwZWNpYWxtZW50ZSBub3MgbW9tZW50b3MgZW0gcXVlIG9jb3JyZXJhbSBkZXN2aW9zIG1haW9yZXMuDQoNCkEgYW7DoWxpc2UgZG9zIHJlc8OtZHVvcyBkbyBtb2RlbG8gcmV2ZWxvdSByZXN1bHRhZG9zIHBvc2l0aXZvcy4gT3MgcmVzw61kdW9zIGFwcmVzZW50YXJhbS1zZSBjb21vICJydcOtZG8gYnJhbmNvIiwgb3Ugc2VqYSwgbsOjbyBtb3N0cmFyYW0gcGFkcsO1ZXMgb3UgYXV0b2NvcnJlbGHDp8O1ZXMgc2lnbmlmaWNhdGl2YXMsIHN1Z2VyaW5kbyBxdWUgbyBtb2RlbG8gY29uc2VndWl1IGNhcHR1cmFyIGEgbWFpb3IgcGFydGUgZGEgZXN0cnV0dXJhIGRhIHPDqXJpZSB0ZW1wb3JhbC4gUGljb3MgZXNwb3LDoWRpY29zIGRlIGVycm9zLCBubyBlbnRhbnRvLCBpbmRpY2FtIHF1ZSBvIG1vZGVsbyBwb2RlcmlhIHNlciBhcHJpbW9yYWRvIHBhcmEgY2FwdHVyYXIgZXZlbnRvcyBjbGltw6F0aWNvcyBhdMOtcGljb3MuIEEgdmFyacOibmNpYSBjb25zdGFudGUgZG9zIHJlc8OtZHVvcyBhbyBsb25nbyBkbyB0ZW1wbyBlIG8gdGVzdGUgZGUgTGp1bmctQm94LCBjb20gdW0gcC12YWxvciBkZSAwLjY5LCBjb25maXJtYXJhbSBxdWUgbyBtb2RlbG8gYWp1c3RhZG8gbsOjbyBhcHJlc2VudG91IGF1dG9jb3JyZWxhw6fDo28gc2lnbmlmaWNhdGl2YSwgbyBxdWUgdmFsaWRhIGFpbmRhIG1haXMgYSBhZGVxdWHDp8OjbyBkbyBBUklNQSBwYXJhIGVzdGUgY29uanVudG8gZGUgZGFkb3MuDQoNCkVtIHJlc3VtbywgbyBtb2RlbG8gQVJJTUEgc2VsZWNpb25hZG8gZm9pIGVmaWNheiBwYXJhIHByZXZlciBhcyB0ZW1wZXJhdHVyYXMgbcOpZGlhcyBkacOhcmlhcyBlbSBUw7NxdWlvLCBjYXB0dXJhbmRvIGNvbSBwcmVjaXPDo28gb3MgcGFkcsO1ZXMgc2F6b25haXMgZSBhcyB0ZW5kw6puY2lhcy4gQSBhbsOhbGlzZSBkb3MgcmVzw61kdW9zIGUgb3MgdGVzdGVzIGRlIGRpYWduw7NzdGljbyBjb3Jyb2JvcmFyYW0gYSBhZGVxdWHDp8OjbyBkbyBtb2RlbG8sIHRvcm5hbmRvLW8gdW1hIGZlcnJhbWVudGEgY29uZmnDoXZlbCBwYXJhIHByZXZpc8O1ZXMgZnV0dXJhcywgY29tIHVtYSBtYXJnZW0gZGUgZXJybyByZWxhdGl2YW1lbnRlIGJhaXhhLiBFc3RlIHRyYWJhbGhvIGRlbW9uc3RyYSBhIGltcG9ydMOibmNpYSBkZSB1bSBwcm9jZXNzbyByaWdvcm9zbyBkZSBhbsOhbGlzZSBkZSBzw6lyaWVzIHRlbXBvcmFpcyBwYXJhIGVudGVuZGVyIGNvbXBvcnRhbWVudG9zIGNsaW3DoXRpY29zIGUgb2ZlcmVjZSB1bWEgYmFzZSBzw7NsaWRhIHBhcmEgZXN0dWRvcyBtZXRlb3JvbMOzZ2ljb3MgZnV0dXJvcyBvdSBwcmV2aXPDtWVzIGRlIHRlbXBlcmF0dXJhIGVtIG91dHJhcyBjaWRhZGVzIG91IHJlZ2nDtWVzIGNvbSBwYWRyw7VlcyBjbGltw6F0aWNvcyBzZW1lbGhhbnRlcy4NCg0KDQoNCiMgNy4gUmVmZXLDqm5jaWFzDQoNCk1vcmV0dGluLCBQLiBBLiwgJiBUb2xvaSwgQy4gTS4gZGUgQy4gKDIwMjIpLiBBbsOhbGlzZSBkZSBzw6lyaWVzIHRlbXBvcmFpcy4gU8OjbyBQYXVsbzogQmx1Y2hlci4NCg==