Probabilidade Discreta

Um modelo probabilístico é uma descrição qualitativa de uma situação, fenômeno ou experimento cujo resultado é incerto. Para definir tal modelo seguimos os passos:

  1. Descrevemos os possíveis resultados do experimento (especificamos o espaço amostral)
  2. Especificamos a lei probabilística, que atribui probabilidades aos resultados ou conjunto de resultados.

A probabilidade Pr(A) de um evento A é a proporção (aproximada) de vezes que o evento ocorre quando repetimos o experimento várias vezes, de maneira independente, sob as mesmas condições. Quanto maior o número de experimentos, melhor é esta aproximação.

Um evento é um resultado medido ou observado de um fenômeno, que aconteceu por chance.

Nas seções seguintes ilustraremos a ideia de probabilidade fazendo contagens de possibilidades e também por meio de experimentos computacionais usando o método de Monte Carlo.

Definindo cartas de um baralho em R

Nesta seção mostraremos como utilizar o R para resolver problemas envolvendo objetos como cartas de um baralho. Embora os problemas listados abaixo possam resolvidos facilmente com uma calculadora, nosso objetivo é ilustrar o uso do R, com comandos que serão imprescidíveis em problemas bem mais complicados que abordaremos mais adiante. Para definir um baralho de cartas no R podemos proceder do seguinte modo, usando os comandos paste e expand.grid:

library(tidyverse)
library(gtools)
suits <- c("Diamonds", "Clubs", "Hearts", "Spades")
numbers <- c("Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King")
deck <- expand.grid(number=numbers, suit=suits)
deck2 <- paste(deck$number,deck$suit)
deck2
 [1] "Ace Diamonds"   "Deuce Diamonds"
 [3] "Three Diamonds" "Four Diamonds" 
 [5] "Five Diamonds"  "Six Diamonds"  
 [7] "Seven Diamonds" "Eight Diamonds"
 [9] "Nine Diamonds"  "Ten Diamonds"  
[11] "Jack Diamonds"  "Queen Diamonds"
[13] "King Diamonds"  "Ace Clubs"     
[15] "Deuce Clubs"    "Three Clubs"   
[17] "Four Clubs"     "Five Clubs"    
[19] "Six Clubs"      "Seven Clubs"   
[21] "Eight Clubs"    "Nine Clubs"    
[23] "Ten Clubs"      "Jack Clubs"    
[25] "Queen Clubs"    "King Clubs"    
[27] "Ace Hearts"     "Deuce Hearts"  
[29] "Three Hearts"   "Four Hearts"   
[31] "Five Hearts"    "Six Hearts"    
[33] "Seven Hearts"   "Eight Hearts"  
[35] "Nine Hearts"    "Ten Hearts"    
[37] "Jack Hearts"    "Queen Hearts"  
[39] "King Hearts"    "Ace Spades"    
[41] "Deuce Spades"   "Three Spades"  
[43] "Four Spades"    "Five Spades"   
[45] "Six Spades"     "Seven Spades"  
[47] "Eight Spades"   "Nine Spades"   
[49] "Ten Spades"     "Jack Spades"   
[51] "Queen Spades"   "King Spades"   

Exemplo. Retirando uma carta do baralho

Por exemplo, calculemos qual é a probabilidade de obtermos King ao retirarmos a primeira carta do baralho. Como um baralho tem 52 cartas e temos 4 Kings, um de cada naipe, a probabilidade de retirarmos uma carta com King é:

4/52
[1] 0.07692308

Podemos reobter este resultado a partir das cartas do baralho. Inicialmente determinamos as cartas com King:

kings <- paste("King", suits)
kings
[1] "King Diamonds" "King Clubs"    "King Hearts"  
[4] "King Spades"  

Examinamos, entre as cartas do baralho, quais são que tem King:

deck2 %in% kings
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [9] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
[17] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[33] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[41] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[49] FALSE FALSE FALSE  TRUE

O comando mean nos dá a proporção do número de resultados TRUE para o número de resultados FALSE:

mean( deck2 %in% kings)
[1] 0.07692308

que é aproximadamente 1/13, como esperado.

Calculemos agora qual é a probabilidade condicional de que a segunda carta seja King dado que a primeira carta for King. Como temos agora somente 3 cartas deste tipo e o baralho agora tem somente 51 cartas, esperamos que a probabilidade seja 3/51. Confirmaremos este resultado em R.

Permutações em R

O comando permutations() computa, para qualquer lista de tamanho n, todos diferentes modos que podemos selecionar r itens. Vejamos um exemplo: de quantos modos podemos selecionar 2 elementos de um grupo de 5 elementos?

permutations(5,2)
      [,1] [,2]
 [1,]    1    2
 [2,]    1    3
 [3,]    1    4
 [4,]    1    5
 [5,]    2    1
 [6,]    2    3
 [7,]    2    4
 [8,]    2    5
 [9,]    3    1
[10,]    3    2
[11,]    3    4
[12,]    3    5
[13,]    4    1
[14,]    4    2
[15,]    4    3
[16,]    4    5
[17,]    5    1
[18,]    5    2
[19,]    5    3
[20,]    5    4

Notemos que a ordem importa. Além disso números repetidos não ocorrem, pois uma vez que selecionamos um número, ele não aparece novamente. Opcionalmente o comando permutations pode ter um vetor como terceiro argumento, como veremos a seguir.

Exemplo. Permutação básica

façamos uma permutação (ou arranjo) de 4 números, 3,4,5,6 em grupos de 3 elementos. De modo mais concreto, se temos uma caixa com 4 bolas marcadas com estes números, quais são os possíveis resultados ao selecionarmos 3 bolas aleatóriamente?

m <- permutations(4,3,c(3,4,5,6,7))
m
      [,1] [,2] [,3]
 [1,]    3    4    5
 [2,]    3    4    6
 [3,]    3    5    4
 [4,]    3    5    6
 [5,]    3    6    4
 [6,]    3    6    5
 [7,]    4    3    5
 [8,]    4    3    6
 [9,]    4    5    3
[10,]    4    5    6
[11,]    4    6    3
[12,]    4    6    5
[13,]    5    3    4
[14,]    5    3    6
[15,]    5    4    3
[16,]    5    4    6
[17,]    5    6    3
[18,]    5    6    4
[19,]    6    3    4
[20,]    6    3    5
[21,]    6    4    3
[22,]    6    4    5
[23,]    6    5    3
[24,]    6    5    4

Como vemos da matriz de saída do comando acima, o número de modos é 24, que pode ser obtido diretamente contando o número de linhas de m:

n <- nrow(m)
n
[1] 24

Façamos uma simulação de 6 escolhas aleatórias de 3 bolas

indice <- sample(n,6)
indice
[1] 10 13 22 14  4 21

Ou seja, as bolas selecionadas têm os números dados por:

m[indice,]
     [,1] [,2] [,3]
[1,]    4    5    6
[2,]    5    3    4
[3,]    6    4    5
[4,]    5    3    6
[5,]    3    5    6
[6,]    6    4    3

Exemplo. Permutação

Simule a seleção aleatória de de 5 números (0 a 9) de 7 dígitos.
Solução

numeros <- permutations(10,7,c(0:9))
n <- nrow(numeros)
n
[1] 604800

Selecionemos 5 números de 7 dígitos:

indice <- sample(n,5)
indice
[1] 187215 360073 178116 292975 259809
numeros[indice,]
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    3    0    8    9    1    6    5
[2,]    5    9    4    6    3    7    0
[3,]    2    9    5    0    3    7    8
[4,]    4    8    5    7    2    6    3
[5,]    4    2    7    3    0    6    1

Exemplo. Probabilidade condicional

Voltemos agora ao problema de calcular a probabilidade de que a segunda carta seja King dado que a primeira carta for King. Computemos todos os possíveis modos de escolher duas cartas, quando a ordem é relevante.

hands <- permutations(52,2,v=deck2)
nrow(hands)
[1] 2652

Ou seja, temos 2652 possibilidades. A primeira carta será selecionada da primeira coluna da matriz hands e similarmente com a segunda:

primeira_carta <- hands[,1]
segunda_carta <- hands[,2]

Vejamos em quantos casos a primeira carta é King:

k <- sum(primeira_carta %in% kings)
k
[1] 204

Ou seja, 204 casos. Para determinar a probabilidade condicional devemos agora determinar qual é a fração destes 204 casos em que temos King na segunda carta:

sum(primeira_carta %in% kings & segunda_carta %in% kings)/sum(primeira_carta %in% kings)
[1] 0.05882353

que é igual a 3/51, como esperado.

Notemos ainda que o mesmo resultado poderia ser obtido utilizando valores esperados:

mean(primeira_carta %in% kings & segunda_carta %in% kings)/mean(primeira_carta %in% kings)
[1] 0.05882353
Estas expressões acima são formas diferentes da relação fundamental \[ Pr(B|A)=\frac{Pr(A \cap B)}{Pr(A)} \]

Combinações em R

Suponhamos agora que a ordem não seja importante. Notemos a diferença entre permutaçôes, onde a ordem importa,

permutations(3,2)
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    2    1
[4,]    2    3
[5,]    3    1
[6,]    3    2

e combinações, onde a ordem não importa:

combinations(3,2)
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    2    3

Exemplo. Blackjack

No jogo blackjack se obtivermos um A e uma carta de face ou 10, teremos um 21 natural, a a vitória é instantânea. Queremos calcular a probabilidade disso acontecer. Notemos que agora devemos enumerar combinações e não permutações, pois a ordem não importa. Um A e um King ou um King e A são a mesma coisa e não queremos contar este caso duas vezes. Para calcular a probabilidade de um 21 natural, inicialmente definimos um vetor que contenha todos os A:

aces <- paste("Ace", suits)
aces
[1] "Ace Diamonds" "Ace Clubs"    "Ace Hearts"  
[4] "Ace Spades"  

Definimos agora um vetor que inclui todas as cartas de face e o 10:

facecard <- c("King","Queen", "Jack", "Ten")
facecard <- expand.grid(number=facecard, suit=suits)
facecard

Formamos o vetor explicitamente:

facecard <- paste(facecard$number,facecard$suit)
facecard
 [1] "King Diamonds"  "Queen Diamonds"
 [3] "Jack Diamonds"  "Ten Diamonds"  
 [5] "King Clubs"     "Queen Clubs"   
 [7] "Jack Clubs"     "Ten Clubs"     
 [9] "King Hearts"    "Queen Hearts"  
[11] "Jack Hearts"    "Ten Hearts"    
[13] "King Spades"    "Queen Spades"  
[15] "Jack Spades"    "Ten Spades"    

Calculamos todas as combinações de 2 cartas que podem ser obtidas a partir das 52 cartas:

hands <- combinations(52,2,v = deck2)
nrow(hands)
[1] 1326

Ou seja, temos 1326 pares de cartas.

summary(hands)
              V1                    V2      
 Ace Clubs     :  51   Three Spades  :  51  
 Ace Diamonds  :  50   Three Hearts  :  50  
 Ace Hearts    :  49   Three Diamonds:  49  
 Ace Spades    :  48   Three Clubs   :  48  
 Deuce Clubs   :  47   Ten Spades    :  47  
 Deuce Diamonds:  46   Ten Hearts    :  46  
 (Other)       :1035   (Other)       :1035  

Temos uma matriz com dois índices: o primeiro (1 a 1326) se refere ao ao par o segundo (1 a 2) à carta do par. Vejamos algumas cartas:

hands[1326,1]
[1] "Three Hearts"
hands[1326,2]
[1] "Three Spades"
hands[1325,1]
[1] "Three Diamonds"
hands[1,1]
[1] "Ace Clubs"
hands[1,2]
[1] "Ace Diamonds"

Por exemplo, o primeiro par é

hands[1,]
[1] "Ace Clubs"    "Ace Diamonds"

e o último par é:

hands[1326,]
[1] "Three Hearts" "Three Spades"

Calculemos agora as probabilidades:

mean(hands[,1] %in% aces & hands[,2] %in% facecard)
[1] 0.04826546

Notemos que embora tenhamos suposto acima que o A é a primeira carta, isso não é importante, pois nas combinações a ordem é irrelevante. Outro modo de calcular esta probabilidade é considerar ambas as possibilidades:

mean((hands[,1] %in% aces & hands[,2] %in% facecard) | (hands[,2] %in% aces & hands[,1] %in% facecard))
[1] 0.04826546

que dá o mesmo resultado.

Simulação de Monte Carlo

Um modo diferente de calcular probabilidades é por meio de experimentos computacionais. Ilustraremos esta ideia usando o chamado método de simulação de Monte Carlo. Suponhamos que temos um caixa com 10 bolas iguais, mas com cores diferentes: 3 vermelhas, 5 azuis e 2 brancas. Vejamos com simular escolhas aleatórias, sem substituição de 5 bolas da caixa. A caixa com as bolas pode ser representada com ajuda do comando rep seguinte do R:

bolas <- rep(c("red", "blue", "white"),times = c(3,5,2))
bolas
 [1] "red"   "red"   "red"   "blue"  "blue"  "blue" 
 [7] "blue"  "blue"  "white" "white"

Selecionemos aleatoriamente, sem substituição, 5 bolas:

sample(bolas,5)
[1] "blue"  "blue"  "red"   "white" "blue" 

Se o comando for repetido, outra conjunto de bolas será obtido:

sample(bolas,5)
[1] "red"   "red"   "white" "blue"  "blue" 

O experimento pode ser replicado quantas vezes quisermos usando o comando replicate:

B <- 6
eventos <- replicate(B, sample(bolas,5))
eventos
     [,1]    [,2]   [,3]    [,4]    [,5]    [,6]  
[1,] "white" "red"  "blue"  "red"   "blue"  "blue"
[2,] "blue"  "blue" "red"   "white" "red"   "blue"
[3,] "blue"  "blue" "red"   "red"   "blue"  "red" 
[4,] "white" "red"  "red"   "blue"  "white" "red" 
[5,] "red"   "blue" "white" "blue"  "white" "red" 

Podemos contar automaticamente o número de bolas de cada tipo obtidas da seguint forma:

tab <- table(eventos)
tab
eventos
 blue   red white 
   12    12     6 

Se selecionarmos 10 bolas o conjunto original é obtido:

sample(bolas,10)
 [1] "blue"  "white" "red"   "blue"  "red"   "blue" 
 [7] "blue"  "white" "blue"  "red"  

embora em ordem diferente. Se selecionarmos somente uma bola, é fácil entender que as probabilidades P1, P2 e P3 de obtermos bolas vermelhas, azuis e brancas devem ser dadas, P1 = 0.3, P2 = 0.5, P3 = 0.2. Façamos uma simulação de Monte Carlo com 10000 experimentos, selecionando uma bola por experimento e contando quantas são obtidas:

B <- 10000
eventos <- replicate(B,sample(bolas,1))
tab <- table(eventos)
tab
eventos
 blue   red white 
 5110  2979  1911 

Vejamos as proporções:

prop.table(tab)
eventos
  blue    red  white 
0.5110 0.2979 0.1911 
que é, aproximadamente, o resultado esperado.

Exemplo. Simulação de Monte Carlo e condição lógica (1)

Vejamos agora qual é a probabilidade de que tenhamos nas duas primeiras escolhas, realizadas sem substituição, obtenhamos bolas azuis. Denominemos tal probabilidade por \(Pr(BB)\). É fácil mostrar que \[ Pr(BB)= \frac{5}{10}\cdot \frac{4}{9} =\frac{2}{9} \approx 0.222 \] Vejamos como obter este resultado a partir de uma simulação de Monte Carlo. Devemos repetir o seguinte experimento diversas vezes e contar o número de vezes que obtemos “blue” “blue”:

experimento <- sample(bolas,2)
experimento
[1] "white" "white"

Façamos o experimento 10 vezes:

B <-10
bolasazuis <- replicate(B,{experimento <- sample(bolas,2) 
(experimento[1]=="blue" & experimento[2]=="blue")})
bolasazuis
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
 [9] FALSE FALSE

O evento BB ocorreu 3 vezes. Calculemos a proporção de número de TRUE e número de FALSE:

mean(bolasazuis)
[1] 0.1

Façamos agora 100000 repetições:

B <-10000
bolasazuis <- replicate(B,{experimento <- sample(bolas,2) 
(experimento[1]=="blue" & experimento[2]=="blue")})
mean(bolasazuis)
[1] 0.226
de modo que reobtemos, aproximadamente, o resultado esperado.

Exemplo. Simulação de Monte Carlo e condição lógica (2)

Suponhamos que queremos saber agora qual é a probabilidade de obtermos os eventos \(RWB\) ao retirarmos 3 bolas, sem substituição. Sabemos que \[ Pr(RWB)=\frac{3}{10}\frac{2}{9}\frac{5}{8}=\frac{1}{24}\approx 0.04167\,. \] Vejamos como obter este resultado a partir de uma simulação de Monte Carlo, fazendo 800 000 repetições:

B <-800000
bolascoloridas <- replicate(B,{experimento <- sample(bolas,3) 
(experimento[1]=="red" & experimento[2]=="white" & experimento[3]=="blue")})
mean(bolascoloridas)
[1] 0.041495
que é o resultado esperado.

Exemplo. Simulação de Monte Carlo e condição lógica (3)

Suponhamos agora que selecionamos aleatoriamente, sem substituição, 5 bolas e queremos saber qual é a probabilidade de que ao menos 2 bolas sejam vermelhas. Para resolver este problema pelo método tradicional anterior teríamos que listar muitos eventos \(RRBWW\), \(RWRRB\), etc., calcular a probabilidade de cada evento e somar. Façamos logo uma simulação de Monte Carlo, usando o comando str_count (pacote stringr) que funciona do seguinte modo:

s <- sample(bolas,5)
s
[1] "blue"  "blue"  "blue"  "blue"  "white"

Contemos o número de bolas vermelhas na amostra:

str_count(s, "red")
[1] 0 0 0 0 0

Ou seja, quando o string é encontrado o valor 1 é atribuído à respectiva componente, caso contrário é 0. Para determinar o número de ocorrências de 1 no vetor usamos o comando:

n <- str_count(s, "red")
length(which(n==1))
[1] 0

Aplicando este comando ao nosso problema, repetindo o experimento 100 000 vezes, a proporção de casos nos quais temos duas ou mais bolas vermelhas é:

library(stringr)
B <- 100000
bolasvermelhas<-replicate(B,{experimento <- sample(bolas,5) 
n <- str_count(experimento, "red")
length(which(n==1)) >=2})
mean(bolasvermelhas)
[1] 0.50112

ou seja, aproximadamente 1/2.

Exemplo. Simulação de Monte Carlo e condição lógica (4)

De uma caixa com 20 bolas, sendo 6 brancas, 4 vermelhas, 7 azuis e 3 verdes são selecionadas 6, sem substituição. (i) Qual é a probabilidade de que a primeira e a última bola da seleção sejam azuis? (ii) Qual é a probabilidade de que ao menos três bolas sejam brancas?

Solução

  1. Definimos a caixa com bolas:
bolas <- rep(c("red", "blue", "white", "green"),times = c(4,7,6,3))
bolas
 [1] "red"   "red"   "red"   "red"   "blue"  "blue" 
 [7] "blue"  "blue"  "blue"  "blue"  "blue"  "white"
[13] "white" "white" "white" "white" "white" "green"
[19] "green" "green"

Selecionamos 6 bolas e repetimos o experimento 900 000 vezes, contando o número de vezes em que a primeira e a sexta bola são azuis:

B <-900000
bolasazuis <- replicate(B,{experimento <- sample(bolas,6) 
(experimento[1]=="blue" & experimento[6]=="blue")})
mean(bolasazuis)
[1] 0.1106511
  1. Devemos agora contabilizar todos os casos em que temos 3 ou mais bolas brancas:
B <-900000
BolasBrancas <- replicate(B,{experimento <- sample(bolas,6) 
n <- str_count(experimento, "white")
length(which(n==1)) >=3})
mean(BolasBrancas)
[1] 0.2254611

Exemplo. Blackjack

Voltando ao problema do jogo blackjack, em vez de usar combinações para deduzir a exata probabilidade do 21 natural, podemos usar o método de Monte Carlo para estimar a probabilidade. Neste caso tiramos duas cartas repetidamente e contamos quantas vezes obtemos 21. Podemos usar o comando sample para retirar uma carta sem substituição:

hand <- sample(deck2, 2)
hand
[1] "King Clubs" "Jack Clubs"

e checar se obtemos 21. Façamos este experimento 100 vezes:

B <- 100
resultados <- replicate(B,{hand <- sample(deck2,2) 
(hand[1] %in% aces & hand[2] %in% facecard) | (hand[2] %in% aces & hand[1] %in% facecard)})
resultados
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  [8] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [15] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [22] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [29] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [36] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [43]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
 [50]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
 [57] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
 [64] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [71] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [78] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [92] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [99] FALSE FALSE

Calculemos a proporção de número de TRUE e número de FALSE:

mean(resultados)
[1] 0.04

Façamos 100000 amostragens:

B <- 100000
resultados <- replicate(B,{hand <- sample(deck2,2) 
(hand[1] %in% aces & hand[2] %in% facecard) | (hand[2] %in% aces & hand[1] %in% facecard)})
mean(resultados)
[1] 0.04845
que é o resultado esperado.

Exemplo. Jogo de volei

Temos dois times de volei, Brasil e Argentina, que estão jogando uma séries de melhor de 7 jogos. O Brasil tem uma equipe melhor e tem 60% de chances de vencer um dado jogo.
(i) Qual é a probabilidade de que a Argentina vença ao menos um jogo?
(ii) Resolva este problema usando simulação de Monte Carlo.
Solução: Notemos que a Argentina precisa vencer ao menos um jogo dos primeiros 4 para que não seja eliminada sem vitórias. A probabililidade de que isso não aconteça é igual à probabilidade do Brasil vencer os 4 primeiros jogos, ou seja,

p_brasil_4v <- 0.6^4
p_brasil_4v
[1] 0.1296

Portanto, a probabilidade a Argentina vença ao menos um jogo entre os 4 primeiros é:

1-p_brasil_4v
[1] 0.8704
  1. Façamos a simulação do experimento 100000 vezes:
B = 100000
argentina_vence <- replicate(B,{resultados <- sample(c("lose","win"), 4, replace = TRUE, prob = c(0.6,0.4)) 
any(resultados=="win")})
mean(argentina_vence)
[1] 0.86982
o que está de acordo com o cálculo exato.

Exemplo. Outra série de jogos de volei

Dois times de volei, Brasil e Sérvia, estão jogando uma série de 7 jogos. O primeiro a vencer 4 jogos vence a série. Ambos os times são equilibrados e ambos têm iguais chances de vencer cada jogo. Se o Brasil vencer o primeiro jogo, qual é a chance de que ele vença a série? Calcule exatamente e depois faça uma simulação de Monte Carlo.

Solução

Calculemos exatamente. O número de jogos restantes é n = 6. Definimos uma variável chamada resultados, que é o vetor de possíveis resultados, sendo 0 uma derrota e 1 uma vitória

n <-6
resultados <- c(0,1)

Criamos uma lista l com todos os possíveis resultados dos jogos remanescentes:

l <- replicate(n,list(resultados))

Criamos um data frame named possibilidades que contém todas as combinações de todos os possíveis resultados para os jogos remanescentes:

possibilidades <- expand.grid(l)
possibilidades

Criamos um vetor chamado resultados que indica se cada linha no data frame possibilidades contém o número suficiente de vitórias para que o time do Brasil vença a série:

resultados <- rowSums(possibilidades)>3
resultados
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [9] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
[17] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
[25] FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE
[33] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
[41] FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE
[49] FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE
[57] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Calculamos em resultados a proporção de casos (TRUE) em que o Brasil vence a série:

mean(resultados)
[1] 0.34375

Façamos agora uma simulação de Monte Carlo. Criamos um objeto chamado resultados que replica para B = 10000 iterações uma série simulada e determina se a série contém ao menos 4 vitórias, o que daria vitória ao time do Brasil e depois calculemos a proporção de casos TRUE

B <- 10000
resultados <- replicate(B,sum(replicate(6, sample(c(0,1),1)))>3)
mean(resultados)
[1] 0.3435
Deste modo, confirmamos o resultado obtido exatamente.

Exemplo. Séries de jogos com diferentes probabilidades

Dois times, A e B jogam uma série de 7 jogos. A probabilidade de A vencer B é p. Determine as probabilidades de que A vença a série para p = 0.5, 0.525, 0.550, … 0.95, e apresente o resultado em um gráfico.

Solução

Definimos o vetor de probabilidades:

p <- seq(0.5, 0.95, 0.025)

Definimos a função:

prob_win <- function(p){
  B <- 10000
  result <- replicate(B, {
    b_win <- sample(c(1,0), 7, replace = TRUE, prob = c(1-p, p))
    sum(b_win)>=4
    })
    mean(result)
}

Façamos agora a avaliação da função para cada valor de p e o correspondente gráfico:

Pr <- sapply(p,prob_win)
plot(p,Pr)

Exemplo. Diferentes números de jogos em cada série

Consideremos um problema semelhante ao anterior, mas agora com probabilidade de que A vença qualquer jogo fixa em p=0.75, mas com diferentes séries com diferentes números de jogos.

Solução.

Devemos agora deixar o número de jogos N como argumento:

prob_win <- function(N, p=0.75){
      B <- 10000
      result <- replicate(B, {
        b_win <- sample(c(1,0), N, replace = TRUE, prob = c(1-p, p))
        sum(b_win)>=(N+1)/2
        })
            mean(result)
    }

Definimos os possíveis valores para N como números ímpares de 1 a 25:

N <- seq(1, 25, 2)
N
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25

Façamos agora a avaliação da função para cada valor de N e o correspondente gráfico:

Pr <- sapply(N,prob_win)
plot(N,Pr)

Exemplo. O problema dos aniversários

Suponhamos que temos uma sala de aula com 50 alunos. Qual é a probabilidade de que dois alunos façam aniversário no mesmo dia? Usemos simulação de Monte Carlo para resolver este problema. Vamos supor que ninguém faz aniversário no dia 29 de fevereiro (o que não muda significativamente o resultado final). Aniversários podem ser representados por números de 1 a 365. Portanto, selecionemos 50 dias de 365 aleatoriamente, com substituição uma vez que dias de aniversários não são exclusivos:

n <- 50
bd <- sample(1:365,n,replace = TRUE)

Para verificar se neste conjunto de 50 dias há ao menos dois repetidos (aniversários no mesmo dia), usaremos o comando duplicated, que retorna o valor TRUE sempre que um elemento do vetor já houver aparecido antes. Por exemplo,

dup <- duplicated(c(2,3,4,2,2,5,3,2,1))
dup
[1] FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
[9] FALSE

Portanto, obtemos o valor TRUE para o elemento 2 na quarta e quinta componentes, onde o 2 se repete.. Além disso, obtemos TRUE para os elementos 3 e 2 na sétima e oitava componentes, onde eles repetem. Se estivermos interessados somente no caso em que a duplicação, podemos usar o comando any:

any(dup)
[1] TRUE

Apliquemos estas ideias ao problema dos aniversários, fazendo 10 amostras:

n < - 50
[1] FALSE
B <- 10
resultado <- replicate(B,{bd <- sample(1:365,n,replace = TRUE) 
any(duplicated(bd))})
resultado
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[10] TRUE

Notemos que em 10 experimentos obtivemos repetições em todos eles. Façamos 100 000 experimentos e calculemos a proporção de repetições:

n < - 50
[1] FALSE
B <- 100000
mesmo_dia <- replicate(B,{bd <- sample(1:365,n,replace = TRUE) 
any(duplicated(bd))})
mean(mesmo_dia)
[1] 0.96977

Portanto, em um grupo de 50 pessoas, aniversários no mesmo dia ocorrem com probabilidade de aproximadamente 97%.

Exemplo. O problema dos aniversários com diversos grupos

Consideremos agora o problema de calcular, para um dado grupo, as chances de haver aniversário no mesmo dia para diferentes grupos com diferente número de pessoas. Criaremos uma tabela para examinar as possibilidades.

Inicialmente criamos uma função a partir da simulação de Monte Carlo definida acima:

compute_prob <- function(n,
B=100000)
{mesmo_dia <- replicate(B,{bd <- sample(1:365,n,replace = TRUE) 
any(duplicated(bd))})
mean(mesmo_dia)
}

Testemos a função

compute_prob(40)
[1] 0.8909

Definimos agora um vetor com diversos valores para \(n\):

n <- 40:60

Notemos que a nossa função não funciona como esperado:

compute_prob(n)
[1] 0.89049

Ou seja, em vez de calcular a probabilidade para todos os n a função somente usou o primeiro valor (= 40). Isso é porque nossa função espera um escalar como entrada e não um vetor. Outras funções em R normalmente aceitam vetores como argumento. Por exemplo:

sqrt(n)
 [1] 6.324555 6.403124 6.480741 6.557439 6.633250
 [6] 6.708204 6.782330 6.855655 6.928203 7.000000
[11] 7.071068 7.141428 7.211103 7.280110 7.348469
[16] 7.416198 7.483315 7.549834 7.615773 7.681146
[21] 7.745967

Devemos usar aqui o comando sapply, que permite a que a avaliação do função seja feita em todas as componentes da entrada:

sapply(n,compute_prob)
 [1] 0.89106 0.90290 0.91373 0.92242 0.93318 0.94118
 [7] 0.94794 0.95505 0.96021 0.96646 0.97077 0.97439
[13] 0.97704 0.98124 0.98390 0.98626 0.98817 0.99028
[19] 0.99119 0.99267 0.99445

Façamos um gráfico para n de 2 a 60:

n <- 2:60
prob <- sapply(n,compute_prob)
plot(n,prob)

Calculemos as probabilidades exatas em vez de usar simulações de Monte Carlo. Neste caso, é mais simples calcular a probabilidade de que o evento (aniversários no mesmo dia) não ocorra. Examinemos a probabilidade Pr(n) de que um número n de pessoas tenha aniversário numa data única. Se n=1 teremos obviamente Pr(1)=1. A probabilidade de que a segunda pessoa tenha aniversário único, dado que a primeira pessoa tinha aniversário único é 363/365. A probabilidade de que a terceira pessoa tenha aniversário único, dado que as duas primeiras tinham aniversário único é 363/365. Assim, as probabilidades 2 e 3 pessoas tenham aniversário único são dada por \[ Pr(2) = 1 \times \frac{364}{365}\,, \quad Pr(3) = 1 \times \frac{364}{365} \times \frac{363}{365}\,. \] De modo geral, \[ Pr(n) = 1 \times \frac{364}{365} \times \frac{363}{365} \times \cdots \times \frac{365-n+1}{365}\,. \] Façamos a implementação em R:

p_exata <- function(n){
  p_unico <- seq(365, 365-n+1)/365
  1 - prod(p_unico)
}

Façamos um teste:

p_exata(40)
[1] 0.8912318

Podemos agora avaliar esta função nos vários valores de n:

eprob <- sapply(n,p_exata)
plot(n, eprob)

Comparemos este resultado gráfico com aquele obtido com o método de Monte Carlo, usando um curva contínua para o resultado exato:

plot(n, prob)
lines(n, eprob, col="blue")

Tal resultado mostra uma boa concordância entre os métodos.

Número de Amostras nas simulações de Monte Carlo

Uma questão crucial em simulações de Monte Carlo envolve a escolha do número de experimentos a serem feitos. Definimos um intervalo de variação de B:

B <- 10^seq(1, 5, len = 100)

e agora uma função que calcula as probabilidades para cada simulação. Fixemos n=30.

compute_prob <- function(B, n = 30){
  same_day <- replicate (B, {
    bdays <- sample(1:365, n, replace=TRUE)
    any(duplicated(bdays))
  })
  mean(same_day)
}

Façamos agora a avaliação da função para todos os valores de B e plotemos o resultado:

prob <- sapply(B, compute_prob)
plot(log10(B), prob, type ="l")

Notemos que a partir de \(B = 10^3\) os resultados começam a estabilizar.

Exemplo. O Problema de Monty Hall

O problema de Monty Hall pode ser formulado da seguinte maneira:

Suponhamos que você está num concurso e tem que escolher entre 3 portas: atrás de uma das portas está um carro, e atrás das outras bodes. Você escolhe uma porta, digamos a porta 1 e o apresentador, que sabe onde está o carro, vai abrir outra porta, 3, por exemplo, onde há um bode. Ele então lhe pergunta: “você quer ficar com a porta 1 ou quer trocar pela porta 2?” Há alguma vantagem em se trocar de porta? Abaixo está o código referente à escolha da primeira porta.

B <- 10000 #número de experimentos
mesma_porta <- replicate(B, {
portas <- as.character(1:3) #define o vetor com components "1", "2", "3". 
premio <- sample(c("carro", "bode", "bode")) #mistura aleatoriament ordem do string "carro", "bode", "bode"
porta_premiada <- portas[premio == "carro"] #determina o índice da porta premiada
minha_escolha<- sample(portas, 1) #faz uma escolha aleatória entre "1", "2", "3"
#show <- sample(portas[!portas %in% c(minha_escolha, porta_premiada)],1)
mesma_porta <- minha_escolha #mantém a escolha original
mesma_porta == porta_premiada #verifica se a escolha da porta corresponde ao prêmio (TRUE ou FALSE)
})
mean(mesma_porta) #calcule a proporção de valores TRUE
[1] 0.3328

Este resultado indica que a probabilidade é 1/3, o que é esperado, pois nada mudou relativamente à escolha original de 1 porta entre 3. Vejamos agora o que ocorre se escolhemos a estratégia de trocar a escolha:

B <- 10000 #número de experimentos
troca_porta <- replicate(B, {
portas <- as.character(1:3) #define o vetor com components "1", "2", "3". 
premio <- sample(c("carro", "bode", "bode")) #mistura aleatoriament ordem do string "carro", "bode", "bode"
porta_premiada <- portas[premio == "carro"] #determina o índice da porta premiada
minha_escolha<- sample(portas, 1) #faz uma escolha aleatória entre "1", "2", "3"
show <- sample(portas[!portas %in% c(minha_escolha, porta_premiada)],1) #mostra a porta diferente da originalmente escolhida e que não contém o carro
troca_porta <- portas[!portas%in%c(minha_escolha, show)]#escolhe a porta que não é a mostrada (pois não contém prêmio e também não é a original)
troca_porta == porta_premiada #verifica se a escolha da porta corresponde ao prêmio (TRUE ou FALSE)
})
mean(troca_porta) #calcule a proporção de valores TRUE
[1] 0.6686

Ou seja, a probabilidade agora é 2/3. Isso é esperado, pois temos agora a informação de qual é uma das portas que não contém o prêmio.

Exercícios

Em todos os problemas abaixo, calcule exatamente e simule com Monte Carlo.

  1. Uma caixa contém 15 bolas brancas e 25 bolas azuis. Duas bolas são selecionadas aleatóriamente, sem substituição. Seja A o evento correspondente ao fato da primeira bola ser branca e B o evento associado ao fato da segunda bola ser azul. Determine \(Pr(A)\), \(Pr(B|A)\), \(Pr(A \cup B)\), \(Pr(A \cap B)\).

  2. (MR p.61 [1]) O circuito mostrado na figura abaixo funciona se e somente se há um caminho de dispositivos funcionais da esquerda para a direita. Suponha que todos os dispositivos falham independentemente que a probabilidade de falha em cada dispositivo é indicada pelo número em cada caixa. Qual é a probabilidade de que o circuito opere?

Circuito de probabilidade. Problema 2
  1. Retiramos, com substituição, 5 bolas de uma caixa que contém 4 bolas brancas, 6 azuis e 7 amarelas. Supondo que as 5 primeiras bolas foram todas amarelas, qual é a probabilidade de que ao retirar a sexta bola encontremos novamente uma bola amarela? R: 0.47

  2. Jogamos um dado honesto 6 vezes. Qual é a probabilidade de não sair um 6 em nenhuma jogada? R: 0.33

  3. Jogamos 2 dados honestos. Qual é a probabilidade de obtermos mais de 10 pontos em 4 jogadas?

  4. Resolva os problemas anteriores supondo que os dados são viciados do seguinte modo: o lado 6 tem probabilidade 1.1/6 e os outros lados têm probabilidades iguais.

  5. Um time de futebol precisa fazer 7 pontos em 5 jogos para não ser rebaixado para a liga inferior. Nos jogos que fará estima-se que ele tem 10% de chances de vencer, 50% de empatar e 40% de perder. Qual é a probabilidade do time não ser rebaixado.

  6. Em um baralho completo, ao retirarmos 5 cartas, determine a probabilidade conseguirmos cada um dos seguintes resultados:
  1. Dois pares
  2. Trinca
  3. Sequência
  4. Flush
  5. Full House
  6. Quadra
  7. Straigh Flash
  8. Royal Flash.

Referências

  1. Douglas C. Montgomery e George C. Runger. Applied Statistics and Probability for Engineers, 6th ed., Wiley, 2014
LS0tDQp0aXRsZTogIlByb2JhYmlsaWRhZGUgRGlzY3JldGEgZSBTaW11bGHDp8O1ZXMgZGUgTW9udGUgQ2FybG8gIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQphdXRob3I6ICJGZXJuYW5kbyBEZWVrZSBTYXNzZSwgQ0NULCBVREVTQyINCmZpZ19jYXB0aW9uOiB5ZXMNCi0tLQ0KDQo8aDQ+UHJvYmFiaWxpZGFkZSBEaXNjcmV0YTwvaDQ+DQpVbSAqbW9kZWxvIHByb2JhYmlsw61zdGljbyogw6kgdW1hIGRlc2NyacOnw6NvIHF1YWxpdGF0aXZhIGRlIHVtYSBzaXR1YcOnw6NvLCAgZmVuw7RtZW5vIG91IGV4cGVyaW1lbnRvIGN1am8gcmVzdWx0YWRvIMOpIGluY2VydG8uIFBhcmEgZGVmaW5pciB0YWwgbW9kZWxvIHNlZ3VpbW9zIG9zIHBhc3NvczogIA0KDQogMS4gRGVzY3JldmVtb3Mgb3MgcG9zc8OtdmVpcyByZXN1bHRhZG9zIGRvIGV4cGVyaW1lbnRvIChlc3BlY2lmaWNhbW9zIG8gZXNwYcOnbyBhbW9zdHJhbCkNCiAyLiBFc3BlY2lmaWNhbW9zIGEgbGVpIHByb2JhYmlsw61zdGljYSwgcXVlIGF0cmlidWkgcHJvYmFiaWxpZGFkZXMgYW9zIHJlc3VsdGFkb3Mgb3UgY29uanVudG8gZGUgcmVzdWx0YWRvcy4gDQogDQogQSBwcm9iYWJpbGlkYWRlICpQcihBKSogZGUgdW0gZXZlbnRvICAqQSAqw6kgYSBwcm9wb3LDp8OjbyAoYXByb3hpbWFkYSkgZGUgdmV6ZXMgcXVlIG8gZXZlbnRvIG9jb3JyZSBxdWFuZG8gcmVwZXRpbW9zIG8gZXhwZXJpbWVudG8gdsOhcmlhcyB2ZXplcywgZGUgbWFuZWlyYSBpbmRlcGVuZGVudGUsIHNvYiBhcyBtZXNtYXMgY29uZGnDp8O1ZXMuIFF1YW50byBtYWlvciBvIG7Dum1lcm8gZGUgZXhwZXJpbWVudG9zLCBtZWxob3Igw6kgZXN0YSBhcHJveGltYcOnw6NvLiANCiANClVtICpldmVudG8qIMOpIHVtIHJlc3VsdGFkbyBtZWRpZG8gb3Ugb2JzZXJ2YWRvIGRlIHVtIGZlbsO0bWVubywgcXVlIGFjb250ZWNldSBwb3IgY2hhbmNlLiANCg0KTmFzIHNlw6fDtWVzIHNlZ3VpbnRlcyBpbHVzdHJhcmVtb3MgYSBpZGVpYSBkZSBwcm9iYWJpbGlkYWRlIGZhemVuZG8gY29udGFnZW5zIGRlIHBvc3NpYmlsaWRhZGVzIGUgdGFtYsOpbSBwb3IgbWVpbyBkZSBleHBlcmltZW50b3MgY29tcHV0YWNpb25haXMgdXNhbmRvIG8gbcOpdG9kbyBkZSBNb250ZSBDYXJsby4gDQoNCjxoND5EZWZpbmluZG8gY2FydGFzIGRlIHVtIGJhcmFsaG8gZW0gUjwvaDQ+DQpOZXN0YSBzZcOnw6NvIG1vc3RyYXJlbW9zIGNvbW8gdXRpbGl6YXIgbyBSIHBhcmEgcmVzb2x2ZXIgcHJvYmxlbWFzIGVudm9sdmVuZG8gb2JqZXRvcyBjb21vIGNhcnRhcyBkZSB1bSBiYXJhbGhvLiBFbWJvcmEgb3MgcHJvYmxlbWFzIGxpc3RhZG9zIGFiYWl4byBwb3NzYW0gcmVzb2x2aWRvcyBmYWNpbG1lbnRlIGNvbSB1bWEgY2FsY3VsYWRvcmEsIG5vc3NvIG9iamV0aXZvIMOpIGlsdXN0cmFyIG8gdXNvIGRvIFIsIGNvbSBjb21hbmRvcyBxdWUgc2Vyw6NvIGltcHJlc2NpZMOtdmVpcyBlbSBwcm9ibGVtYXMgYmVtIG1haXMgY29tcGxpY2Fkb3MgcXVlIGFib3JkYXJlbW9zIG1haXMgYWRpYW50ZS4gIFBhcmEgZGVmaW5pciB1bSBiYXJhbGhvIGRlIGNhcnRhcyBubyBSIHBvZGVtb3MgcHJvY2VkZXIgZG8gc2VndWludGUgbW9kbywgdXNhbmRvIG9zIGNvbWFuZG9zIA0KPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJhbnQ7IGZvbnQtc2l6ZToxZW07Y29sb3I6Ymx1ZSI+cGFzdGU8L3NwYW4+IGUgDQo8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6Q291cmFudDsgZm9udC1zaXplOjFlbTtjb2xvcjpibHVlIj5leHBhbmQuZ3JpZDwvc3Bhbj46IA0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ3Rvb2xzKQ0KYGBgDQpgYGB7cn0NCnN1aXRzIDwtIGMoIkRpYW1vbmRzIiwgIkNsdWJzIiwgIkhlYXJ0cyIsICJTcGFkZXMiKQ0KbnVtYmVycyA8LSBjKCJBY2UiLCAiRGV1Y2UiLCAiVGhyZWUiLCAiRm91ciIsICJGaXZlIiwgIlNpeCIsICJTZXZlbiIsICJFaWdodCIsICJOaW5lIiwgIlRlbiIsICJKYWNrIiwgIlF1ZWVuIiwgIktpbmciKQ0KZGVjayA8LSBleHBhbmQuZ3JpZChudW1iZXI9bnVtYmVycywgc3VpdD1zdWl0cykNCmRlY2syIDwtIHBhc3RlKGRlY2skbnVtYmVyLGRlY2skc3VpdCkNCmRlY2syDQpgYGANCjxoND5FeGVtcGxvLiBSZXRpcmFuZG8gdW1hIGNhcnRhIGRvIGJhcmFsaG8gPC9oND4NClBvciBleGVtcGxvLCBjYWxjdWxlbW9zIHF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIG9idGVybW9zICpLaW5nKiBhbyByZXRpcmFybW9zIGEgcHJpbWVpcmEgY2FydGEgZG8gYmFyYWxoby4gQ29tbyB1bSBiYXJhbGhvIHRlbSA1MiBjYXJ0YXMgZSB0ZW1vcyA0ICpLaW5ncyosIHVtIGRlIGNhZGEgbmFpcGUsIGEgcHJvYmFiaWxpZGFkZSBkZSByZXRpcmFybW9zIHVtYSBjYXJ0YSBjb20gKktpbmcqIMOpOg0KYGBge3J9DQo0LzUyDQpgYGANClBvZGVtb3MgcmVvYnRlciBlc3RlIHJlc3VsdGFkbyBhIHBhcnRpciBkYXMgY2FydGFzIGRvIGJhcmFsaG8uIEluaWNpYWxtZW50ZSBkZXRlcm1pbmFtb3MgYXMgY2FydGFzIGNvbSAqS2luZyo6IA0KYGBge3J9DQpraW5ncyA8LSBwYXN0ZSgiS2luZyIsIHN1aXRzKQ0Ka2luZ3MNCmBgYA0KRXhhbWluYW1vcywgZW50cmUgYXMgY2FydGFzIGRvIGJhcmFsaG8sIHF1YWlzIHPDo28gcXVlIHRlbSAqS2luZyo6DQpgYGB7cn0NCmRlY2syICVpbiUga2luZ3MNCmBgYA0KTyBjb21hbmRvIDxzcGFuIHN0eWxlPSJmb250LWZhbWlseTpDb3VyYW50OyBmb250LXNpemU6MWVtOyI+bWVhbjwvc3Bhbj4gbm9zIGTDoSBhIHByb3BvcsOnw6NvIGRvIG7Dum1lcm8gZGUgcmVzdWx0YWRvcyBUUlVFIHBhcmEgbyBuw7ptZXJvIGRlIHJlc3VsdGFkb3MgRkFMU0U6DQpgYGB7cn0NCm1lYW4oIGRlY2syICVpbiUga2luZ3MpDQpgYGANCnF1ZSDDqSBhcHJveGltYWRhbWVudGUgMS8xMywgY29tbyBlc3BlcmFkby4gDQoNCkNhbGN1bGVtb3MgYWdvcmEgcXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgY29uZGljaW9uYWwgZGUgcXVlIGEgc2VndW5kYSBjYXJ0YSBzZWphICpLaW5nKiBkYWRvIHF1ZSBhIHByaW1laXJhIGNhcnRhIGZvciAqS2luZyouIENvbW8gdGVtb3MgYWdvcmEgc29tZW50ZSAzIGNhcnRhcyBkZXN0ZSB0aXBvIGUgbyBiYXJhbGhvIGFnb3JhIHRlbSBzb21lbnRlIDUxIGNhcnRhcywgZXNwZXJhbW9zIHF1ZSBhIHByb2JhYmlsaWRhZGUgc2VqYSAzLzUxLiBDb25maXJtYXJlbW9zIGVzdGUgcmVzdWx0YWRvIGVtIFIuIA0KDQo8aDQ+UGVybXV0YcOnw7VlcyBlbSBSPC9oND4NCg0KTyBjb21hbmRvIDxzcGFuIHN0eWxlPSJmb250LWZhbWlseTpDb3VyYW50OyBmb250LXNpemU6MWVtOyI+cGVybXV0YXRpb25zKCk8L3NwYW4+IGNvbXB1dGEsIHBhcmEgcXVhbHF1ZXIgbGlzdGEgZGUgdGFtYW5obyAqbiosIHRvZG9zIGRpZmVyZW50ZXMgbW9kb3MgcXVlIHBvZGVtb3Mgc2VsZWNpb25hciAqciogaXRlbnMuIFZlamFtb3MgdW0gZXhlbXBsbzogZGUgcXVhbnRvcyBtb2RvcyBwb2RlbW9zIHNlbGVjaW9uYXIgMiBlbGVtZW50b3MgZGUgdW0gZ3J1cG8gZGUgNSBlbGVtZW50b3M/DQpgYGB7cn0NCnBlcm11dGF0aW9ucyg1LDIpDQpgYGANCk5vdGVtb3MgcXVlIGEgb3JkZW0gaW1wb3J0YS4gQWzDqW0gZGlzc28gbsO6bWVyb3MgcmVwZXRpZG9zIG7Do28gb2NvcnJlbSwgcG9pcyB1bWEgdmV6IHF1ZSBzZWxlY2lvbmFtb3MgdW0gbsO6bWVybywgZWxlIG7Do28gYXBhcmVjZSBub3ZhbWVudGUuIE9wY2lvbmFsbWVudGUgbyBjb21hbmRvIDxzcGFuIHN0eWxlPSJmb250LWZhbWlseTpDb3VyYW50OyBmb250LXNpemU6MWVtOyI+cGVybXV0YXRpb25zPC9zcGFuPiBwb2RlIHRlciB1bSB2ZXRvciBjb21vIHRlcmNlaXJvIGFyZ3VtZW50bywgY29tbyB2ZXJlbW9zIGEgc2VndWlyLg0KDQo8aDQ+RXhlbXBsby4gUGVybXV0YcOnw6NvIGLDoXNpY2E8L2g0Pg0KZmHDp2Ftb3MgdW1hIHBlcm11dGHDp8OjbyAob3UgYXJyYW5qbykgZGUgNCBuw7ptZXJvcywgMyw0LDUsNiBlbSBncnVwb3MgZGUgMyBlbGVtZW50b3MuIERlIG1vZG8gbWFpcyBjb25jcmV0bywgc2UgdGVtb3MgdW1hIGNhaXhhIGNvbSA0IGJvbGFzIG1hcmNhZGFzIGNvbSBlc3RlcyBuw7ptZXJvcywgcXVhaXMgc8OjbyBvcyBwb3Nzw612ZWlzIHJlc3VsdGFkb3MgYW8gc2VsZWNpb25hcm1vcyAzIGJvbGFzIGFsZWF0w7NyaWFtZW50ZT8gDQpgYGB7cn0NCm0gPC0gcGVybXV0YXRpb25zKDQsMyxjKDMsNCw1LDYsNykpDQptDQpgYGANCkNvbW8gdmVtb3MgZGEgbWF0cml6IGRlIHNhw61kYSBkbyBjb21hbmRvIGFjaW1hLCBvIG7Dum1lcm8gZGUgbW9kb3Mgw6kgMjQsIHF1ZSBwb2RlIHNlciBvYnRpZG8gZGlyZXRhbWVudGUgY29udGFuZG8gbyBuw7ptZXJvIGRlIGxpbmhhcyBkZSAqbSo6IA0KYGBge3J9DQpuIDwtIG5yb3cobSkNCm4NCmBgYA0KRmHDp2Ftb3MgdW1hIHNpbXVsYcOnw6NvIGRlIDYgZXNjb2xoYXMgYWxlYXTDs3JpYXMgZGUgMyBib2xhcw0KYGBge3J9DQppbmRpY2UgPC0gc2FtcGxlKG4sNikNCmluZGljZQ0KYGBgDQpPdSBzZWphLCBhcyBib2xhcyBzZWxlY2lvbmFkYXMgdMOqbSBvcyBuw7ptZXJvcyBkYWRvcyBwb3I6IA0KYGBge3J9DQptW2luZGljZSxdDQpgYGANCg0KPEg0PkV4ZW1wbG8uIFBlcm11dGHDp8OjbzwvSDQ+IA0KU2ltdWxlIGEgc2VsZcOnw6NvIGFsZWF0w7NyaWEgZGUgZGUgNSBuw7ptZXJvcyAoMCBhIDkpIGRlIDcgZMOtZ2l0b3MuPGJyPg0KU29sdcOnw6NvIA0KYGBge3J9DQpudW1lcm9zIDwtIHBlcm11dGF0aW9ucygxMCw3LGMoMDo5KSkNCm4gPC0gbnJvdyhudW1lcm9zKQ0Kbg0KYGBgDQpTZWxlY2lvbmVtb3MgNSBuw7ptZXJvcyBkZSA3IGTDrWdpdG9zOiANCmBgYHtyfQ0KaW5kaWNlIDwtIHNhbXBsZShuLDUpDQppbmRpY2UNCm51bWVyb3NbaW5kaWNlLF0NCmBgYA0KPGg0PiBFeGVtcGxvLiBQcm9iYWJpbGlkYWRlIGNvbmRpY2lvbmFsIDwvaDQ+DQpWb2x0ZW1vcyBhZ29yYSBhbyBwcm9ibGVtYSBkZSBjYWxjdWxhciBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGEgc2VndW5kYSBjYXJ0YSBzZWphICpLaW5nKiBkYWRvIHF1ZSBhIHByaW1laXJhIGNhcnRhIGZvciAqS2luZyouIENvbXB1dGVtb3MgdG9kb3Mgb3MgcG9zc8OtdmVpcyBtb2RvcyBkZSBlc2NvbGhlciBkdWFzIGNhcnRhcywgcXVhbmRvIGEgb3JkZW0gw6kgcmVsZXZhbnRlLg0KYGBge3J9DQpoYW5kcyA8LSBwZXJtdXRhdGlvbnMoNTIsMix2PWRlY2syKQ0KbnJvdyhoYW5kcykNCmBgYA0KT3Ugc2VqYSwgdGVtb3MgMjY1MiBwb3NzaWJpbGlkYWRlcy4gQSBwcmltZWlyYSBjYXJ0YSBzZXLDoSBzZWxlY2lvbmFkYSBkYSBwcmltZWlyYSBjb2x1bmEgZGEgbWF0cml6IGhhbmRzIGUgc2ltaWxhcm1lbnRlIGNvbSBhIHNlZ3VuZGE6IA0KYGBge3J9DQpwcmltZWlyYV9jYXJ0YSA8LSBoYW5kc1ssMV0NCnNlZ3VuZGFfY2FydGEgPC0gaGFuZHNbLDJdDQpgYGANClZlamFtb3MgZW0gcXVhbnRvcyBjYXNvcyBhIHByaW1laXJhIGNhcnRhIMOpIEtpbmc6IA0KYGBge3J9DQprIDwtIHN1bShwcmltZWlyYV9jYXJ0YSAlaW4lIGtpbmdzKQ0Kaw0KYGBgDQpPdSBzZWphLCAyMDQgY2Fzb3MuIFBhcmEgZGV0ZXJtaW5hciBhIHByb2JhYmlsaWRhZGUgY29uZGljaW9uYWwgZGV2ZW1vcyBhZ29yYSBkZXRlcm1pbmFyIHF1YWwgw6kgYSBmcmHDp8OjbyBkZXN0ZXMgMjA0IGNhc29zIGVtIHF1ZSAgdGVtb3MgKktpbmcqIG5hIHNlZ3VuZGEgY2FydGE6DQpgYGB7cn0NCnN1bShwcmltZWlyYV9jYXJ0YSAlaW4lIGtpbmdzICYgc2VndW5kYV9jYXJ0YSAlaW4lIGtpbmdzKS9zdW0ocHJpbWVpcmFfY2FydGEgJWluJSBraW5ncykNCmBgYA0KcXVlIMOpIGlndWFsIGEgMy81MSwgY29tbyBlc3BlcmFkby4NCg0KTm90ZW1vcyBhaW5kYSBxdWUgbyBtZXNtbyByZXN1bHRhZG8gcG9kZXJpYSBzZXIgb2J0aWRvIHV0aWxpemFuZG8gdmFsb3JlcyBlc3BlcmFkb3M6DQpgYGB7cn0NCm1lYW4ocHJpbWVpcmFfY2FydGEgJWluJSBraW5ncyAmIHNlZ3VuZGFfY2FydGEgJWluJSBraW5ncykvbWVhbihwcmltZWlyYV9jYXJ0YSAlaW4lIGtpbmdzKQ0KYGBgDQpFc3RhcyBleHByZXNzw7VlcyBhY2ltYSBzw6NvIGZvcm1hcyBkaWZlcmVudGVzIGRhIHJlbGHDp8OjbyBmdW5kYW1lbnRhbCANCiQkDQpQcihCfEEpPVxmcmFje1ByKEEgXGNhcCBCKX17UHIoQSl9DQokJA0KPGg0PkNvbWJpbmHDp8O1ZXMgZW0gUjwvaDQ+DQpTdXBvbmhhbW9zIGFnb3JhIHF1ZSBhIG9yZGVtIG7Do28gc2VqYSBpbXBvcnRhbnRlLiAgTm90ZW1vcyBhIGRpZmVyZW7Dp2EgZW50cmUgcGVybXV0YcOnw7Rlcywgb25kZSBhIG9yZGVtIGltcG9ydGEsDQpgYGB7cn0NCnBlcm11dGF0aW9ucygzLDIpDQpgYGANCmUgY29tYmluYcOnw7Vlcywgb25kZSBhIG9yZGVtIG7Do28gaW1wb3J0YTogDQpgYGB7cn0NCmNvbWJpbmF0aW9ucygzLDIpDQpgYGANCjxoND5FeGVtcGxvLiBCbGFja2phY2s8L2g0Pg0KTm8gam9nbyAqYmxhY2tqYWNrKiBzZSBvYnRpdmVybW9zIHVtIEEgZSB1bWEgY2FydGEgZGUgZmFjZSBvdSAxMCwgdGVyZW1vcyB1bSAyMSBuYXR1cmFsLCBhIGEgdml0w7NyaWEgw6kgaW5zdGFudMOibmVhLiBRdWVyZW1vcyBjYWxjdWxhciBhIHByb2JhYmlsaWRhZGUgZGlzc28gYWNvbnRlY2VyLiBOb3RlbW9zIHF1ZSBhZ29yYSBkZXZlbW9zIGVudW1lcmFyIGNvbWJpbmHDp8O1ZXMgZSBuw6NvIHBlcm11dGHDp8O1ZXMsIHBvaXMgYSBvcmRlbSBuw6NvIGltcG9ydGEuIFVtICpBKiBlIHVtICpLaW5nKiBvdSB1bSAqS2luZyogZSAqQSogc8OjbyBhIG1lc21hIGNvaXNhIGUgbsOjbyBxdWVyZW1vcyBjb250YXIgZXN0ZSBjYXNvIGR1YXMgdmV6ZXMuIFBhcmEgY2FsY3VsYXIgYSBwcm9iYWJpbGlkYWRlIGRlIHVtIDIxIG5hdHVyYWwsIGluaWNpYWxtZW50ZSBkZWZpbmltb3MgdW0gdmV0b3IgcXVlIGNvbnRlbmhhIHRvZG9zIG9zIEE6DQpgYGB7cn0NCmFjZXMgPC0gcGFzdGUoIkFjZSIsIHN1aXRzKQ0KYWNlcw0KYGBgDQpEZWZpbmltb3MgYWdvcmEgdW0gdmV0b3IgcXVlIGluY2x1aSB0b2RhcyBhcyBjYXJ0YXMgZGUgZmFjZSBlIG8gMTA6DQpgYGB7cn0NCmZhY2VjYXJkIDwtIGMoIktpbmciLCJRdWVlbiIsICJKYWNrIiwgIlRlbiIpDQpmYWNlY2FyZCA8LSBleHBhbmQuZ3JpZChudW1iZXI9ZmFjZWNhcmQsIHN1aXQ9c3VpdHMpDQpmYWNlY2FyZA0KYGBgDQpGb3JtYW1vcyBvIHZldG9yIGV4cGxpY2l0YW1lbnRlOg0KYGBge3J9DQpmYWNlY2FyZCA8LSBwYXN0ZShmYWNlY2FyZCRudW1iZXIsZmFjZWNhcmQkc3VpdCkNCmZhY2VjYXJkDQpgYGANCkNhbGN1bGFtb3MgdG9kYXMgYXMgY29tYmluYcOnw7VlcyBkZSAyIGNhcnRhcyBxdWUgcG9kZW0gc2VyIG9idGlkYXMgYSBwYXJ0aXIgZGFzIDUyIGNhcnRhczogDQpgYGB7cn0NCmhhbmRzIDwtIGNvbWJpbmF0aW9ucyg1MiwyLHYgPSBkZWNrMikNCm5yb3coaGFuZHMpDQpgYGANCk91IHNlamEsIHRlbW9zIDEzMjYgcGFyZXMgZGUgY2FydGFzLiANCmBgYHtyfQ0Kc3VtbWFyeShoYW5kcykNCmBgYA0KVGVtb3MgdW1hIG1hdHJpeiBjb20gZG9pcyDDrW5kaWNlczogbyBwcmltZWlybyAoMSBhIDEzMjYpIHNlIHJlZmVyZSBhbyBhbyBwYXIgbyBzZWd1bmRvICgxIGEgMikgw6AgY2FydGEgZG8gcGFyLiBWZWphbW9zIGFsZ3VtYXMgY2FydGFzOg0KYGBge3J9DQpoYW5kc1sxMzI2LDFdDQpoYW5kc1sxMzI2LDJdDQpoYW5kc1sxMzI1LDFdDQpoYW5kc1sxLDFdDQpoYW5kc1sxLDJdDQpgYGANClBvciBleGVtcGxvLCBvIHByaW1laXJvIHBhciDDqSANCmBgYHtyfQ0KaGFuZHNbMSxdDQpgYGANCmUgbyDDumx0aW1vIHBhciDDqTogDQpgYGB7cn0NCmhhbmRzWzEzMjYsXQ0KYGBgDQpDYWxjdWxlbW9zIGFnb3JhIGFzIHByb2JhYmlsaWRhZGVzOg0KYGBge3J9DQptZWFuKGhhbmRzWywxXSAlaW4lIGFjZXMgJiBoYW5kc1ssMl0gJWluJSBmYWNlY2FyZCkNCmBgYA0KTm90ZW1vcyBxdWUgZW1ib3JhIHRlbmhhbW9zIHN1cG9zdG8gYWNpbWEgcXVlIG8gKkEqIMOpIGEgcHJpbWVpcmEgY2FydGEsIGlzc28gbsOjbyDDqSBpbXBvcnRhbnRlLCBwb2lzIG5hcyBjb21iaW5hw6fDtWVzIGEgb3JkZW0gw6kgaXJyZWxldmFudGUuIE91dHJvIG1vZG8gZGUgY2FsY3VsYXIgZXN0YSBwcm9iYWJpbGlkYWRlIMOpIGNvbnNpZGVyYXIgYW1iYXMgYXMgcG9zc2liaWxpZGFkZXM6IA0KYGBge3J9DQptZWFuKChoYW5kc1ssMV0gJWluJSBhY2VzICYgaGFuZHNbLDJdICVpbiUgZmFjZWNhcmQpIHwgKGhhbmRzWywyXSAlaW4lIGFjZXMgJiBoYW5kc1ssMV0gJWluJSBmYWNlY2FyZCkpDQpgYGANCnF1ZSBkw6EgbyBtZXNtbyByZXN1bHRhZG8uIA0KDQo8aDQ+U2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG88L2g0Pg0KVW0gbW9kbyBkaWZlcmVudGUgZGUgY2FsY3VsYXIgcHJvYmFiaWxpZGFkZXMgw6kgcG9yIG1laW8gZGUgZXhwZXJpbWVudG9zIGNvbXB1dGFjaW9uYWlzLiBJbHVzdHJhcmVtb3MgZXN0YSBpZGVpYSB1c2FuZG8gbyBjaGFtYWRvIG3DqXRvZG8gZGUgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8uDQpTdXBvbmhhbW9zIHF1ZSB0ZW1vcyB1bSBjYWl4YSBjb20gMTAgYm9sYXMgaWd1YWlzLCBtYXMgY29tIGNvcmVzIGRpZmVyZW50ZXM6IDMgdmVybWVsaGFzLCA1IGF6dWlzIGUgMiBicmFuY2FzLiBWZWphbW9zIGNvbSBzaW11bGFyIGVzY29saGFzIGFsZWF0w7NyaWFzLCBzZW0gc3Vic3RpdHVpw6fDo28gZGUgNSBib2xhcyBkYSBjYWl4YS4gQSBjYWl4YSBjb20gYXMgYm9sYXMgcG9kZSBzZXIgcmVwcmVzZW50YWRhIGNvbSBhanVkYSBkbyBjb21hbmRvICA8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6Q291cmFudDsgZm9udC1zaXplOjFlbTsiPnJlcDwvc3Bhbj4gc2VndWludGUgZG8gUjogDQpgYGB7cn0NCmJvbGFzIDwtIHJlcChjKCJyZWQiLCAiYmx1ZSIsICJ3aGl0ZSIpLHRpbWVzID0gYygzLDUsMikpDQpib2xhcw0KYGBgDQpTZWxlY2lvbmVtb3MgYWxlYXRvcmlhbWVudGUsIHNlbSBzdWJzdGl0dWnDp8OjbywgNSBib2xhczogDQpgYGB7cn0NCnNhbXBsZShib2xhcyw1KQ0KYGBgDQpTZSBvIGNvbWFuZG8gZm9yIHJlcGV0aWRvLCBvdXRyYSBjb25qdW50byBkZSBib2xhcyBzZXLDoSBvYnRpZG86IA0KYGBge3J9DQpzYW1wbGUoYm9sYXMsNSkNCmBgYA0KTyBleHBlcmltZW50byBwb2RlIHNlciByZXBsaWNhZG8gcXVhbnRhcyB2ZXplcyBxdWlzZXJtb3MgdXNhbmRvIG8gY29tYW5kbyA8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6Q291cmFudDsgZm9udC1zaXplOjFlbTsiPnJlcGxpY2F0ZTwvc3Bhbj46DQpgYGB7cn0NCkIgPC0gNg0KZXZlbnRvcyA8LSByZXBsaWNhdGUoQiwgc2FtcGxlKGJvbGFzLDUpKQ0KZXZlbnRvcw0KYGBgDQpQb2RlbW9zIGNvbnRhciBhdXRvbWF0aWNhbWVudGUgbyBuw7ptZXJvIGRlIGJvbGFzIGRlIGNhZGEgdGlwbyBvYnRpZGFzIGRhIHNlZ3VpbnQgZm9ybWE6IA0KYGBge3J9DQp0YWIgPC0gdGFibGUoZXZlbnRvcykNCnRhYg0KYGBgDQpTZSBzZWxlY2lvbmFybW9zIDEwIGJvbGFzIG8gY29uanVudG8gb3JpZ2luYWwgw6kgb2J0aWRvOiANCmBgYHtyfQ0Kc2FtcGxlKGJvbGFzLDEwKQ0KYGBgDQplbWJvcmEgZW0gb3JkZW0gZGlmZXJlbnRlLiBTZSBzZWxlY2lvbmFybW9zIHNvbWVudGUgdW1hIGJvbGEsIMOpIGbDoWNpbCBlbnRlbmRlciBxdWUgYXMgcHJvYmFiaWxpZGFkZXMgUDEsIFAyIGUgUDMgZGUgb2J0ZXJtb3MgYm9sYXMgdmVybWVsaGFzLCBhenVpcyBlIGJyYW5jYXMgZGV2ZW0gc2VyIGRhZGFzLCBQMSA9IDAuMywgUDIgPSAwLjUsIFAzID0gMC4yLiBGYcOnYW1vcyB1bWEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8gY29tIDEwMDAwIGV4cGVyaW1lbnRvcywgc2VsZWNpb25hbmRvIHVtYSBib2xhIHBvciBleHBlcmltZW50byBlIGNvbnRhbmRvIHF1YW50YXMgc8OjbyBvYnRpZGFzOiANCmBgYHtyfQ0KQiA8LSAxMDAwMA0KZXZlbnRvcyA8LSByZXBsaWNhdGUoQixzYW1wbGUoYm9sYXMsMSkpDQp0YWIgPC0gdGFibGUoZXZlbnRvcykNCnRhYg0KYGBgDQpWZWphbW9zIGFzIHByb3BvcsOnw7VlczogDQpgYGB7cn0NCnByb3AudGFibGUodGFiKQ0KYGBgDQpxdWUgw6ksIGFwcm94aW1hZGFtZW50ZSwgbyByZXN1bHRhZG8gZXNwZXJhZG8uIA0KPGg0PiBFeGVtcGxvLiBTaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsbyBlIGNvbmRpw6fDo28gbMOzZ2ljYSAoMSk8L2g0Pg0KVmVqYW1vcyBhZ29yYSBxdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBxdWUgdGVuaGFtb3MgbmFzIGR1YXMgcHJpbWVpcmFzIGVzY29saGFzLCByZWFsaXphZGFzIHNlbSBzdWJzdGl0dWnDp8Ojbywgb2J0ZW5oYW1vcyBib2xhcyBhenVpcy4gRGVub21pbmVtb3MgdGFsIHByb2JhYmlsaWRhZGUgcG9yICRQcihCQikkLiDDiSBmw6FjaWwgbW9zdHJhciBxdWUgDQokJA0KUHIoQkIpPSBcZnJhY3s1fXsxMH1cY2RvdCBcZnJhY3s0fXs5fSA9XGZyYWN7Mn17OX0gXGFwcHJveCAwLjIyMg0KJCQNClZlamFtb3MgY29tbyBvYnRlciBlc3RlIHJlc3VsdGFkbyBhIHBhcnRpciBkZSB1bWEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8uIERldmVtb3MgcmVwZXRpciBvIHNlZ3VpbnRlIGV4cGVyaW1lbnRvIGRpdmVyc2FzIHZlemVzIGUgY29udGFyIG8gbsO6bWVybyBkZSB2ZXplcyBxdWUgb2J0ZW1vcyAiYmx1ZSIgImJsdWUiOg0KYGBge3J9DQpleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsMikNCmV4cGVyaW1lbnRvDQpgYGANCkZhw6dhbW9zIG8gZXhwZXJpbWVudG8gMTAgdmV6ZXM6IA0KYGBge3J9DQpCIDwtMTANCmJvbGFzYXp1aXMgPC0gcmVwbGljYXRlKEIse2V4cGVyaW1lbnRvIDwtIHNhbXBsZShib2xhcywyKSANCihleHBlcmltZW50b1sxXT09ImJsdWUiICYgZXhwZXJpbWVudG9bMl09PSJibHVlIil9KQ0KYm9sYXNhenVpcw0KYGBgDQpPIGV2ZW50byBCQiBvY29ycmV1IDMgdmV6ZXMuDQpDYWxjdWxlbW9zIGEgcHJvcG9yw6fDo28gZGUgbsO6bWVybyBkZSBUUlVFIGUgbsO6bWVybyBkZSBGQUxTRTogDQpgYGB7cn0NCm1lYW4oYm9sYXNhenVpcykNCmBgYA0KRmHDp2Ftb3MgYWdvcmEgMTAwMDAwIHJlcGV0acOnw7VlczogDQpgYGB7cn0NCkIgPC0xMDAwMA0KYm9sYXNhenVpcyA8LSByZXBsaWNhdGUoQix7ZXhwZXJpbWVudG8gPC0gc2FtcGxlKGJvbGFzLDIpIA0KKGV4cGVyaW1lbnRvWzFdPT0iYmx1ZSIgJiBleHBlcmltZW50b1syXT09ImJsdWUiKX0pDQptZWFuKGJvbGFzYXp1aXMpDQpgYGANCmRlIG1vZG8gcXVlIHJlb2J0ZW1vcywgYXByb3hpbWFkYW1lbnRlLCBvIHJlc3VsdGFkbyBlc3BlcmFkby4gDQo8aDQ+IEV4ZW1wbG8uIFNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvIGUgY29uZGnDp8OjbyBsw7NnaWNhICgyKTwvaDQ+DQpTdXBvbmhhbW9zIHF1ZSBxdWVyZW1vcyBzYWJlciBhZ29yYSBxdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBvYnRlcm1vcyBvcyBldmVudG9zICRSV0IkIGFvIHJldGlyYXJtb3MgMyBib2xhcywgc2VtIHN1YnN0aXR1acOnw6NvLiBTYWJlbW9zIHF1ZSANCiQkDQpQcihSV0IpPVxmcmFjezN9ezEwfVxmcmFjezJ9ezl9XGZyYWN7NX17OH09XGZyYWN7MX17MjR9XGFwcHJveCAwLjA0MTY3XCwuDQokJA0KVmVqYW1vcyBjb21vIG9idGVyIGVzdGUgcmVzdWx0YWRvIGEgcGFydGlyIGRlIHVtYSBzaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsbywgZmF6ZW5kbyA4MDAgMDAwIHJlcGV0acOnw7VlczogDQpgYGB7cn0NCkIgPC04MDAwMDANCmJvbGFzY29sb3JpZGFzIDwtIHJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsMykgDQooZXhwZXJpbWVudG9bMV09PSJyZWQiICYgZXhwZXJpbWVudG9bMl09PSJ3aGl0ZSIgJiBleHBlcmltZW50b1szXT09ImJsdWUiKX0pDQptZWFuKGJvbGFzY29sb3JpZGFzKQ0KYGBgDQpxdWUgw6kgbyByZXN1bHRhZG8gZXNwZXJhZG8uIA0KPGg0PiBFeGVtcGxvLiBTaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsbyBlIGNvbmRpw6fDo28gbMOzZ2ljYSAoMyk8L2g0Pg0KU3Vwb25oYW1vcyBhZ29yYSBxdWUgc2VsZWNpb25hbW9zIGFsZWF0b3JpYW1lbnRlLCBzZW0gc3Vic3RpdHVpw6fDo28sIDUgYm9sYXMgZSBxdWVyZW1vcyBzYWJlciBxdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBxdWUgYW8gbWVub3MgMiBib2xhcyBzZWphbSB2ZXJtZWxoYXMuIFBhcmEgcmVzb2x2ZXIgZXN0ZSBwcm9ibGVtYSBwZWxvIG3DqXRvZG8gdHJhZGljaW9uYWwgYW50ZXJpb3IgdGVyw61hbW9zIHF1ZSBsaXN0YXIgbXVpdG9zIGV2ZW50b3MgJFJSQldXJCwgJFJXUlJCJCwgZXRjLiwgY2FsY3VsYXIgYSBwcm9iYWJpbGlkYWRlIGRlIGNhZGEgZXZlbnRvIGUgc29tYXIuIEZhw6dhbW9zIGxvZ28gdW1hIHNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvLCB1c2FuZG8gbyBjb21hbmRvIDxzcGFuIHN0eWxlPSJmb250LWZhbWlseTpDb3VyYW50OyBmb250LXNpemU6MWVtOyI+c3RyX2NvdW50PC9zcGFuPiAocGFjb3RlIHN0cmluZ3IpIHF1ZSBmdW5jaW9uYSBkbyBzZWd1aW50ZSBtb2RvOiANCmBgYHtyfQ0KcyA8LSBzYW1wbGUoYm9sYXMsNSkNCnMNCmBgYA0KQ29udGVtb3MgbyBuw7ptZXJvIGRlIGJvbGFzIHZlcm1lbGhhcyBuYSBhbW9zdHJhOiANCmBgYHtyfQ0Kc3RyX2NvdW50KHMsICJyZWQiKQ0KYGBgDQpPdSBzZWphLCBxdWFuZG8gbyBzdHJpbmcgw6kgZW5jb250cmFkbyBvIHZhbG9yIDEgw6kgYXRyaWJ1w61kbyDDoCByZXNwZWN0aXZhIGNvbXBvbmVudGUsIGNhc28gY29udHLDoXJpbyDDqSAwLiBQYXJhIGRldGVybWluYXIgbyBuw7ptZXJvIGRlIG9jb3Jyw6puY2lhcyBkZSAxIG5vIHZldG9yIHVzYW1vcyBvIGNvbWFuZG86DQpgYGB7cn0NCm4gPC0gc3RyX2NvdW50KHMsICJyZWQiKQ0KbGVuZ3RoKHdoaWNoKG49PTEpKQ0KYGBgDQpBcGxpY2FuZG8gZXN0ZSBjb21hbmRvIGFvIG5vc3NvIHByb2JsZW1hLCByZXBldGluZG8gbyBleHBlcmltZW50byAxMDAgMDAwIHZlemVzLCBhIHByb3BvcsOnw6NvIGRlIGNhc29zIG5vcyBxdWFpcyB0ZW1vcyBkdWFzIG91IG1haXMgYm9sYXMgdmVybWVsaGFzIMOpOg0KYGBge3J9DQpsaWJyYXJ5KHN0cmluZ3IpDQpCIDwtIDEwMDAwMA0KYm9sYXN2ZXJtZWxoYXM8LXJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsNSkgDQpuIDwtIHN0cl9jb3VudChleHBlcmltZW50bywgInJlZCIpDQpsZW5ndGgod2hpY2gobj09MSkpID49Mn0pDQptZWFuKGJvbGFzdmVybWVsaGFzKQ0KYGBgDQpvdSBzZWphLCBhcHJveGltYWRhbWVudGUgMS8yLiANCg0KPGg0PiBFeGVtcGxvLiBTaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsbyBlIGNvbmRpw6fDo28gbMOzZ2ljYSAoNCk8L2g0Pg0KRGUgdW1hIGNhaXhhIGNvbSAyMCBib2xhcywgc2VuZG8gNiBicmFuY2FzLCAgNCB2ZXJtZWxoYXMsICA3IGF6dWlzIGUgMyB2ZXJkZXMgc8OjbyBzZWxlY2lvbmFkYXMgNiwgc2VtIHN1YnN0aXR1acOnw6NvLiANCihpKSBRdWFsIMOpIGEgcHJvYmFiaWxpZGFkZSBkZSBxdWUgYSBwcmltZWlyYSBlIGEgw7psdGltYSBib2xhIGRhIHNlbGXDp8OjbyBzZWphbSBhenVpcz8gDQooaWkpIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBhbyBtZW5vcyB0csOqcyBib2xhcyBzZWphbSBicmFuY2FzPyANCjxoND5Tb2x1w6fDo288L2g0Pg0KKGkpIERlZmluaW1vcyBhIGNhaXhhIGNvbSBib2xhczogDQpgYGB7cn0NCmJvbGFzIDwtIHJlcChjKCJyZWQiLCAiYmx1ZSIsICJ3aGl0ZSIsICJncmVlbiIpLHRpbWVzID0gYyg0LDcsNiwzKSkNCmJvbGFzDQpgYGANClNlbGVjaW9uYW1vcyA2IGJvbGFzIGUgcmVwZXRpbW9zIG8gZXhwZXJpbWVudG8gOTAwIDAwMCB2ZXplcywgY29udGFuZG8gbyBuw7ptZXJvIGRlIHZlemVzIGVtIHF1ZSBhIHByaW1laXJhIGUgYSBzZXh0YSBib2xhIHPDo28gYXp1aXM6DQpgYGB7cn0NCkIgPC05MDAwMDANCmJvbGFzYXp1aXMgPC0gcmVwbGljYXRlKEIse2V4cGVyaW1lbnRvIDwtIHNhbXBsZShib2xhcyw2KSANCihleHBlcmltZW50b1sxXT09ImJsdWUiICYgZXhwZXJpbWVudG9bNl09PSJibHVlIil9KQ0KbWVhbihib2xhc2F6dWlzKQ0KYGBgDQooaWkpIERldmVtb3MgYWdvcmEgY29udGFiaWxpemFyIHRvZG9zIG9zIGNhc29zIGVtIHF1ZSB0ZW1vcyAzIG91IG1haXMgYm9sYXMgYnJhbmNhczoNCmBgYHtyfQ0KQiA8LTkwMDAwMA0KQm9sYXNCcmFuY2FzIDwtIHJlcGxpY2F0ZShCLHtleHBlcmltZW50byA8LSBzYW1wbGUoYm9sYXMsNikgDQpuIDwtIHN0cl9jb3VudChleHBlcmltZW50bywgIndoaXRlIikNCmxlbmd0aCh3aGljaChuPT0xKSkgPj0zfSkNCm1lYW4oQm9sYXNCcmFuY2FzKQ0KYGBgDQo8aDQ+RXhlbXBsby4gQmxhY2tqYWNrPC9oND4NClZvbHRhbmRvIGFvIHByb2JsZW1hIGRvIGpvZ28gYmxhY2tqYWNrLCBlbSAgdmV6IGRlIHVzYXIgY29tYmluYcOnw7VlcyBwYXJhIGRlZHV6aXIgYSBleGF0YSBwcm9iYWJpbGlkYWRlIGRvIDIxIG5hdHVyYWwsIHBvZGVtb3MgdXNhciBvIG3DqXRvZG8gZGUgTW9udGUgQ2FybG8gcGFyYSBlc3RpbWFyIGEgcHJvYmFiaWxpZGFkZS4gTmVzdGUgY2FzbyB0aXJhbW9zIGR1YXMgY2FydGFzIHJlcGV0aWRhbWVudGUgZSBjb250YW1vcyBxdWFudGFzIHZlemVzIG9idGVtb3MgMjEuIFBvZGVtb3MgdXNhciBvIGNvbWFuZG8gPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJhbnQ7IGZvbnQtc2l6ZToxZW07Ij5zYW1wbGU8L3NwYW4+IHBhcmEgcmV0aXJhciB1bWEgY2FydGEgc2VtIHN1YnN0aXR1acOnw6NvOiANCmBgYHtyfQ0KaGFuZCA8LSBzYW1wbGUoZGVjazIsIDIpDQpoYW5kDQpgYGANCmUgY2hlY2FyIHNlIG9idGVtb3MgMjEuIEZhw6dhbW9zIGVzdGUgZXhwZXJpbWVudG8gMTAwIHZlemVzOg0KYGBge3J9DQpCIDwtIDEwMA0KcmVzdWx0YWRvcyA8LSByZXBsaWNhdGUoQix7aGFuZCA8LSBzYW1wbGUoZGVjazIsMikgDQooaGFuZFsxXSAlaW4lIGFjZXMgJiBoYW5kWzJdICVpbiUgZmFjZWNhcmQpIHwgKGhhbmRbMl0gJWluJSBhY2VzICYgaGFuZFsxXSAlaW4lIGZhY2VjYXJkKX0pDQpyZXN1bHRhZG9zDQpgYGANCg0KQ2FsY3VsZW1vcyBhIHByb3BvcsOnw6NvIGRlIG7Dum1lcm8gZGUgVFJVRSBlIG7Dum1lcm8gZGUgRkFMU0U6IA0KYGBge3J9DQptZWFuKHJlc3VsdGFkb3MpDQpgYGANCkZhw6dhbW9zIDEwMDAwMCBhbW9zdHJhZ2VuczoNCmBgYHtyfQ0KQiA8LSAxMDAwMDANCnJlc3VsdGFkb3MgPC0gcmVwbGljYXRlKEIse2hhbmQgPC0gc2FtcGxlKGRlY2syLDIpIA0KKGhhbmRbMV0gJWluJSBhY2VzICYgaGFuZFsyXSAlaW4lIGZhY2VjYXJkKSB8IChoYW5kWzJdICVpbiUgYWNlcyAmIGhhbmRbMV0gJWluJSBmYWNlY2FyZCl9KQ0KbWVhbihyZXN1bHRhZG9zKQ0KYGBgDQpxdWUgw6kgbyByZXN1bHRhZG8gZXNwZXJhZG8uIA0KPGg0PkV4ZW1wbG8uIEpvZ28gZGUgdm9sZWkgPC9oND4NClRlbW9zIGRvaXMgdGltZXMgZGUgdm9sZWksIEJyYXNpbCBlIEFyZ2VudGluYSwgcXVlIGVzdMOjbyBqb2dhbmRvIHVtYSBzw6lyaWVzIGRlIG1lbGhvciBkZSA3IGpvZ29zLiBPIEJyYXNpbCB0ZW0gdW1hIGVxdWlwZSBtZWxob3IgZSB0ZW0gNjAlIGRlIGNoYW5jZXMgZGUgdmVuY2VyIHVtIGRhZG8gam9nby4gPGJyPg0KKGkpIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBhIEFyZ2VudGluYSB2ZW7Dp2EgYW8gbWVub3MgdW0gam9nbz8gPGJyPg0KKGlpKSBSZXNvbHZhIGVzdGUgcHJvYmxlbWEgdXNhbmRvIHNpbXVsYcOnw6NvIGRlIE1vbnRlIENhcmxvLiA8YnI+DQoqKlNvbHXDp8OjbyoqOiBOb3RlbW9zIHF1ZSBhIEFyZ2VudGluYSBwcmVjaXNhIHZlbmNlciBhbyBtZW5vcyB1bSBqb2dvIGRvcyBwcmltZWlyb3MgNCBwYXJhIHF1ZSBuw6NvIHNlamEgZWxpbWluYWRhIHNlbSB2aXTDs3JpYXMuIEEgcHJvYmFiaWxpbGlkYWRlIGRlIHF1ZSBpc3NvIG7Do28gYWNvbnRlw6dhIMOpIGlndWFsIMOgIHByb2JhYmlsaWRhZGUgZG8gQnJhc2lsIHZlbmNlciBvcyA0IHByaW1laXJvcyBqb2dvcywgb3Ugc2VqYSwgDQpgYGB7cn0NCnBfYnJhc2lsXzR2IDwtIDAuNl40DQpwX2JyYXNpbF80dg0KYGBgDQpQb3J0YW50bywgYSBwcm9iYWJpbGlkYWRlIGEgQXJnZW50aW5hIHZlbsOnYSBhbyBtZW5vcyB1bSBqb2dvIGVudHJlIG9zIDQgcHJpbWVpcm9zIMOpOg0KYGBge3J9DQoxLXBfYnJhc2lsXzR2DQpgYGANCihpaSkgRmHDp2Ftb3MgYSBzaW11bGHDp8OjbyBkbyBleHBlcmltZW50byAxMDAwMDAgdmV6ZXM6IA0KYGBge3J9DQpCID0gMTAwMDAwDQphcmdlbnRpbmFfdmVuY2UgPC0gcmVwbGljYXRlKEIse3Jlc3VsdGFkb3MgPC0gc2FtcGxlKGMoImxvc2UiLCJ3aW4iKSwgNCwgcmVwbGFjZSA9IFRSVUUsIHByb2IgPSBjKDAuNiwwLjQpKSANCmFueShyZXN1bHRhZG9zPT0id2luIil9KQ0KbWVhbihhcmdlbnRpbmFfdmVuY2UpDQpgYGANCm8gcXVlIGVzdMOhIGRlIGFjb3JkbyBjb20gbyBjw6FsY3VsbyBleGF0by4gDQo8aDQ+RXhlbXBsby4gT3V0cmEgc8OpcmllIGRlIGpvZ29zIGRlIHZvbGVpPC9oND4NCiBEb2lzIHRpbWVzIGRlIHZvbGVpLCBCcmFzaWwgZSBTw6lydmlhLCBlc3TDo28gam9nYW5kbyB1bWEgc8OpcmllIGRlIDcgam9nb3MuIE8gcHJpbWVpcm8gYSB2ZW5jZXIgNCBqb2dvcyB2ZW5jZSBhIHPDqXJpZS4gQW1ib3Mgb3MgdGltZXMgc8OjbyBlcXVpbGlicmFkb3MgZSBhbWJvcyB0w6ptIGlndWFpcyBjaGFuY2VzIGRlIHZlbmNlciBjYWRhIGpvZ28uIA0KU2UgbyBCcmFzaWwgdmVuY2VyIG8gcHJpbWVpcm8gam9nbywgcXVhbCDDqSBhIGNoYW5jZSBkZSBxdWUgZWxlIHZlbsOnYSBhIHPDqXJpZT8gQ2FsY3VsZSBleGF0YW1lbnRlIGUgZGVwb2lzIGZhw6dhIHVtYSBzaW11bGHDp8OjbyBkZSBNb250ZSBDYXJsby4NCjxoND4gU29sdcOnw6NvIDwvaDQ+DQpDYWxjdWxlbW9zIGV4YXRhbWVudGUuICBPIG7Dum1lcm8gZGUgam9nb3MgcmVzdGFudGVzIMOpICpuID0gNiouIERlZmluaW1vcyB1bWEgdmFyacOhdmVsIGNoYW1hZGEgKnJlc3VsdGFkb3MqLCBxdWUgw6kgbyB2ZXRvciBkZSBwb3Nzw612ZWlzIHJlc3VsdGFkb3MsIHNlbmRvIDAgdW1hIGRlcnJvdGEgZSAxIHVtYSB2aXTDs3JpYQ0KYGBge3J9DQpuIDwtNg0KcmVzdWx0YWRvcyA8LSBjKDAsMSkNCmBgYA0KQ3JpYW1vcyB1bWEgbGlzdGEgKmwqIGNvbSB0b2RvcyBvcyBwb3Nzw612ZWlzIHJlc3VsdGFkb3MgZG9zIGpvZ29zIHJlbWFuZXNjZW50ZXM6DQpgYGB7cn0NCmwgPC0gcmVwbGljYXRlKG4sbGlzdChyZXN1bHRhZG9zKSkNCmBgYA0KQ3JpYW1vcyB1bSAgZGF0YSBmcmFtZSBuYW1lZCAqcG9zc2liaWxpZGFkZXMqIHF1ZSBjb250w6ltIHRvZGFzIGFzIGNvbWJpbmHDp8O1ZXMgZGUgdG9kb3Mgb3MgcG9zc8OtdmVpcyByZXN1bHRhZG9zIHBhcmEgb3Mgam9nb3MgcmVtYW5lc2NlbnRlczoNCmBgYHtyfQ0KcG9zc2liaWxpZGFkZXMgPC0gZXhwYW5kLmdyaWQobCkNCnBvc3NpYmlsaWRhZGVzDQpgYGANCkNyaWFtb3MgdW0gdmV0b3IgY2hhbWFkbyAqcmVzdWx0YWRvcyogcXVlIGluZGljYSBzZSBjYWRhIGxpbmhhIG5vIGRhdGEgZnJhbWUgKnBvc3NpYmlsaWRhZGVzKiBjb250w6ltIG8gbsO6bWVybyBzdWZpY2llbnRlIGRlIHZpdMOzcmlhcyBwYXJhIHF1ZSBvIHRpbWUgZG8gQnJhc2lsIHZlbsOnYSBhIHPDqXJpZTogDQpgYGB7cn0NCnJlc3VsdGFkb3MgPC0gcm93U3Vtcyhwb3NzaWJpbGlkYWRlcyk+Mw0KcmVzdWx0YWRvcw0KYGBgDQpDYWxjdWxhbW9zIGVtICpyZXN1bHRhZG9zKiBhIHByb3BvcsOnw6NvIGRlIGNhc29zICgqVFJVRSopIGVtIHF1ZSBvIEJyYXNpbCB2ZW5jZSBhIHPDqXJpZToNCmBgYHtyfQ0KbWVhbihyZXN1bHRhZG9zKQ0KYGBgDQpGYcOnYW1vcyBhZ29yYSB1bWEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8uIENyaWFtb3MgdW0gb2JqZXRvIGNoYW1hZG8gKnJlc3VsdGFkb3MqIHF1ZSByZXBsaWNhIHBhcmEgKkIgPSAxMDAwMCogaXRlcmHDp8O1ZXMgdW1hIHPDqXJpZSBzaW11bGFkYSBlIGRldGVybWluYSBzZSBhIHPDqXJpZSBjb250w6ltIGFvIG1lbm9zIDQgdml0w7NyaWFzLCBvIHF1ZSBkYXJpYSB2aXTDs3JpYSBhbyB0aW1lIGRvIEJyYXNpbCBlIGRlcG9pcyBjYWxjdWxlbW9zIGEgcHJvcG9yw6fDo28gZGUgY2Fzb3MgKlRSVUUqDQpgYGB7cn0NCkIgPC0gMTAwMDANCnJlc3VsdGFkb3MgPC0gcmVwbGljYXRlKEIsc3VtKHJlcGxpY2F0ZSg2LCBzYW1wbGUoYygwLDEpLDEpKSk+MykNCm1lYW4ocmVzdWx0YWRvcykNCmBgYA0KRGVzdGUgbW9kbywgY29uZmlybWFtb3MgbyByZXN1bHRhZG8gb2J0aWRvIGV4YXRhbWVudGUuIA0KPGg0PkV4ZW1wbG8uIFPDqXJpZXMgZGUgam9nb3MgY29tIGRpZmVyZW50ZXMgcHJvYmFiaWxpZGFkZXM8L2g0Pg0KRG9pcyB0aW1lcywgKkEqIGUgKkIqIGpvZ2FtIHVtYSBzw6lyaWUgZGUgNyBqb2dvcy4gQSBwcm9iYWJpbGlkYWRlIGRlICpBKiB2ZW5jZXIgKkIqIMOpICpwKi4gDQpEZXRlcm1pbmUgYXMgcHJvYmFiaWxpZGFkZXMgZGUgcXVlICpBKiB2ZW7Dp2EgYSBzw6lyaWUgcGFyYSAqcCogPSAwLjUsIDAuNTI1LCAwLjU1MCwgLi4uICAwLjk1LCBlIGFwcmVzZW50ZSBvIHJlc3VsdGFkbyBlbSB1bSBncsOhZmljby4gDQo8aDQ+U29sdcOnw6NvPC9oND4NCkRlZmluaW1vcyBvIHZldG9yIGRlIHByb2JhYmlsaWRhZGVzOg0KYGBge3J9IA0KcCA8LSBzZXEoMC41LCAwLjk1LCAwLjAyNSkNCmBgYA0KRGVmaW5pbW9zIGEgZnVuw6fDo286IA0KYGBge3J9DQpwcm9iX3dpbiA8LSBmdW5jdGlvbihwKXsNCiAgQiA8LSAxMDAwMA0KICByZXN1bHQgPC0gcmVwbGljYXRlKEIsIHsNCiAgICBiX3dpbiA8LSBzYW1wbGUoYygxLDApLCA3LCByZXBsYWNlID0gVFJVRSwgcHJvYiA9IGMoMS1wLCBwKSkNCiAgICBzdW0oYl93aW4pPj00DQogICAgfSkNCiAgICBtZWFuKHJlc3VsdCkNCn0NCmBgYA0KRmHDp2Ftb3MgYWdvcmEgYSBhdmFsaWHDp8OjbyBkYSBmdW7Dp8OjbyBwYXJhIGNhZGEgdmFsb3IgZGUgKnAqIGUgbyBjb3JyZXNwb25kZW50ZSBncsOhZmljbzoNCmBgYHtyfQ0KUHIgPC0gc2FwcGx5KHAscHJvYl93aW4pDQpwbG90KHAsUHIpDQpgYGANCjxoND5FeGVtcGxvLiBEaWZlcmVudGVzIG7Dum1lcm9zIGRlIGpvZ29zIGVtIGNhZGEgc8OpcmllPC9oND4gQ29uc2lkZXJlbW9zIHVtIHByb2JsZW1hIHNlbWVsaGFudGUgYW8gYW50ZXJpb3IsIG1hcyBhZ29yYSBjb20gcHJvYmFiaWxpZGFkZSBkZSBxdWUgKkEqIHZlbsOnYSBxdWFscXVlciBqb2dvIGZpeGEgZW0gKnA9MC43NSosIG1hcyBjb20gZGlmZXJlbnRlcyBzw6lyaWVzIGNvbSBkaWZlcmVudGVzIG7Dum1lcm9zIGRlIGpvZ29zLiANCjxoND5Tb2x1w6fDo28uIDwvaDQ+DQpEZXZlbW9zIGFnb3JhIGRlaXhhciBvIG7Dum1lcm8gZGUgam9nb3MgKk4qIGNvbW8gYXJndW1lbnRvOiANCmBgYHtyfQ0KcHJvYl93aW4gPC0gZnVuY3Rpb24oTiwgcD0wLjc1KXsNCiAgICAgIEIgPC0gMTAwMDANCiAgICAgIHJlc3VsdCA8LSByZXBsaWNhdGUoQiwgew0KICAgICAgICBiX3dpbiA8LSBzYW1wbGUoYygxLDApLCBOLCByZXBsYWNlID0gVFJVRSwgcHJvYiA9IGMoMS1wLCBwKSkNCiAgICAgICAgc3VtKGJfd2luKT49KE4rMSkvMg0KICAgICAgICB9KQ0KICAgICAgICAgICAgbWVhbihyZXN1bHQpDQogICAgfQ0KYGBgDQpEZWZpbmltb3Mgb3MgcG9zc8OtdmVpcyB2YWxvcmVzIHBhcmEgKk4qIGNvbW8gbsO6bWVyb3Mgw61tcGFyZXMgZGUgMSBhIDI1Og0KYGBge3J9DQpOIDwtIHNlcSgxLCAyNSwgMikNCk4NCmBgYA0KRmHDp2Ftb3MgYWdvcmEgYSBhdmFsaWHDp8OjbyBkYSBmdW7Dp8OjbyBwYXJhIGNhZGEgdmFsb3IgZGUgKk4qIGUgbyBjb3JyZXNwb25kZW50ZSBncsOhZmljbzoNCmBgYHtyfQ0KUHIgPC0gc2FwcGx5KE4scHJvYl93aW4pDQpwbG90KE4sUHIpDQpgYGANCjxoND5FeGVtcGxvLiBPIHByb2JsZW1hIGRvcyBhbml2ZXJzw6FyaW9zPC9oND4NClN1cG9uaGFtb3MgcXVlIHRlbW9zIHVtYSBzYWxhIGRlIGF1bGEgY29tIDUwIGFsdW5vcy4gUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGRvaXMgYWx1bm9zIGZhw6dhbSBhbml2ZXJzw6FyaW8gbm8gbWVzbW8gZGlhPyBVc2Vtb3Mgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8gcGFyYSByZXNvbHZlciBlc3RlIHByb2JsZW1hLiBWYW1vcyBzdXBvciBxdWUgbmluZ3XDqW0gZmF6IGFuaXZlcnPDoXJpbyBubyBkaWEgMjkgZGUgZmV2ZXJlaXJvIChvIHF1ZSBuw6NvIG11ZGEgc2lnbmlmaWNhdGl2YW1lbnRlIG8gcmVzdWx0YWRvIGZpbmFsKS4gQW5pdmVyc8OhcmlvcyBwb2RlbSBzZXIgcmVwcmVzZW50YWRvcyBwb3IgbsO6bWVyb3MgZGUgMSBhIDM2NS4gUG9ydGFudG8sIHNlbGVjaW9uZW1vcyA1MCBkaWFzIGRlIDM2NSBhbGVhdG9yaWFtZW50ZSwgY29tIHN1YnN0aXR1acOnw6NvIHVtYSB2ZXogcXVlIGRpYXMgZGUgYW5pdmVyc8OhcmlvcyBuw6NvIHPDo28gZXhjbHVzaXZvczogDQpgYGB7cn0NCm4gPC0gNTANCmJkIDwtIHNhbXBsZSgxOjM2NSxuLHJlcGxhY2UgPSBUUlVFKQ0KYGBgDQpQYXJhIHZlcmlmaWNhciBzZSBuZXN0ZSBjb25qdW50byBkZSA1MCBkaWFzIGjDoSBhbyBtZW5vcyBkb2lzIHJlcGV0aWRvcyAoYW5pdmVyc8OhcmlvcyBubyBtZXNtbyBkaWEpLCB1c2FyZW1vcyBvIGNvbWFuZG8gPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJhbnQ7IGZvbnQtc2l6ZToxZW07Ij5kdXBsaWNhdGVkPC9zcGFuPiwgcXVlIHJldG9ybmEgbyB2YWxvciBUUlVFIHNlbXByZSBxdWUgdW0gZWxlbWVudG8gZG8gdmV0b3IgasOhIGhvdXZlciBhcGFyZWNpZG8gYW50ZXMuIFBvciBleGVtcGxvLCANCmBgYHtyfQ0KZHVwIDwtIGR1cGxpY2F0ZWQoYygyLDMsNCwyLDIsNSwzLDIsMSkpDQpkdXANCmBgYA0KUG9ydGFudG8sIG9idGVtb3MgbyB2YWxvciBUUlVFIHBhcmEgbyBlbGVtZW50byAyIG5hIHF1YXJ0YSBlIHF1aW50YSBjb21wb25lbnRlcywgb25kZSBvIDIgc2UgcmVwZXRlLi4gQWzDqW0gZGlzc28sIG9idGVtb3MgVFJVRSBwYXJhIG9zIGVsZW1lbnRvcyAzIGUgMiBuYSBzw6l0aW1hIGUgb2l0YXZhIGNvbXBvbmVudGVzLCBvbmRlIGVsZXMgcmVwZXRlbS4gU2UgZXN0aXZlcm1vcyBpbnRlcmVzc2Fkb3Mgc29tZW50ZSBubyBjYXNvIGVtIHF1ZSBhIGR1cGxpY2HDp8OjbywgcG9kZW1vcyB1c2FyIG8gY29tYW5kbyAgPHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJhbnQ7IGZvbnQtc2l6ZToxZW07Ij5hbnk8L3NwYW4+Og0KYGBge3J9DQphbnkoZHVwKQ0KYGBgDQpBcGxpcXVlbW9zIGVzdGFzIGlkZWlhcyBhbyBwcm9ibGVtYSBkb3MgYW5pdmVyc8OhcmlvcywgZmF6ZW5kbyAxMCBhbW9zdHJhczoNCmBgYHtyfQ0KbiA8IC0gNTANCkIgPC0gMTANCnJlc3VsdGFkbyA8LSByZXBsaWNhdGUoQix7YmQgPC0gc2FtcGxlKDE6MzY1LG4scmVwbGFjZSA9IFRSVUUpIA0KYW55KGR1cGxpY2F0ZWQoYmQpKX0pDQpyZXN1bHRhZG8NCmBgYA0KTm90ZW1vcyBxdWUgZW0gMTAgZXhwZXJpbWVudG9zIG9idGl2ZW1vcyByZXBldGnDp8O1ZXMgZW0gdG9kb3MgZWxlcy4gRmHDp2Ftb3MgMTAwIDAwMCBleHBlcmltZW50b3MgZSBjYWxjdWxlbW9zIGEgcHJvcG9yw6fDo28gZGUgcmVwZXRpw6fDtWVzOiANCmBgYHtyfQ0KbiA8IC0gNTANCkIgPC0gMTAwMDAwDQptZXNtb19kaWEgPC0gcmVwbGljYXRlKEIse2JkIDwtIHNhbXBsZSgxOjM2NSxuLHJlcGxhY2UgPSBUUlVFKSANCmFueShkdXBsaWNhdGVkKGJkKSl9KQ0KbWVhbihtZXNtb19kaWEpDQpgYGANClBvcnRhbnRvLCBlbSB1bSBncnVwbyBkZSA1MCBwZXNzb2FzLCBhbml2ZXJzw6FyaW9zIG5vIG1lc21vIGRpYSBvY29ycmVtIGNvbSBwcm9iYWJpbGlkYWRlIGRlIGFwcm94aW1hZGFtZW50ZSA5NyUuIA0KDQo8aDQ+RXhlbXBsby4gTyBwcm9ibGVtYSBkb3MgYW5pdmVyc8OhcmlvcyBjb20gZGl2ZXJzb3MgZ3J1cG9zPC9oND4NCkNvbnNpZGVyZW1vcyBhZ29yYSBvIHByb2JsZW1hIGRlIGNhbGN1bGFyLCBwYXJhIHVtIGRhZG8gZ3J1cG8sIGFzIGNoYW5jZXMgZGUgaGF2ZXIgYW5pdmVyc8OhcmlvIG5vIG1lc21vIGRpYSBwYXJhIGRpZmVyZW50ZXMgZ3J1cG9zIGNvbSBkaWZlcmVudGUgbsO6bWVybyBkZSBwZXNzb2FzLiBDcmlhcmVtb3MgdW1hIHRhYmVsYSBwYXJhIGV4YW1pbmFyIGFzIHBvc3NpYmlsaWRhZGVzLg0KDQpJbmljaWFsbWVudGUgY3JpYW1vcyB1bWEgZnVuw6fDo28gYSBwYXJ0aXIgZGEgc2ltdWxhw6fDo28gZGUgTW9udGUgQ2FybG8gZGVmaW5pZGEgYWNpbWE6DQpgYGB7cn0NCmNvbXB1dGVfcHJvYiA8LSBmdW5jdGlvbihuLA0KQj0xMDAwMDApDQp7bWVzbW9fZGlhIDwtIHJlcGxpY2F0ZShCLHtiZCA8LSBzYW1wbGUoMTozNjUsbixyZXBsYWNlID0gVFJVRSkgDQphbnkoZHVwbGljYXRlZChiZCkpfSkNCm1lYW4obWVzbW9fZGlhKQ0KfQ0KYGBgDQpUZXN0ZW1vcyBhIGZ1bsOnw6NvIA0KYGBge3J9DQpjb21wdXRlX3Byb2IoNDApDQpgYGANCkRlZmluaW1vcyBhZ29yYSB1bSB2ZXRvciBjb20gZGl2ZXJzb3MgdmFsb3JlcyBwYXJhICRuJDogDQpgYGB7cn0NCm4gPC0gNDA6NjANCmBgYA0KTm90ZW1vcyBxdWUgYSBub3NzYSBmdW7Dp8OjbyBuw6NvIGZ1bmNpb25hIGNvbW8gZXNwZXJhZG86DQpgYGB7cn0NCmNvbXB1dGVfcHJvYihuKQ0KYGBgDQpPdSBzZWphLCBlbSB2ZXogZGUgY2FsY3VsYXIgYSBwcm9iYWJpbGlkYWRlIHBhcmEgdG9kb3Mgb3MgbiBhIGZ1bsOnw6NvIHNvbWVudGUgdXNvdSBvIHByaW1laXJvIHZhbG9yICg9IDQwKS4gSXNzbyDDqSBwb3JxdWUgbm9zc2EgZnVuw6fDo28gZXNwZXJhIHVtIGVzY2FsYXIgY29tbyBlbnRyYWRhIGUgbsOjbyB1bSB2ZXRvci4gT3V0cmFzIGZ1bsOnw7VlcyBlbSBSIG5vcm1hbG1lbnRlIGFjZWl0YW0gdmV0b3JlcyBjb21vIGFyZ3VtZW50by4gUG9yIGV4ZW1wbG86IA0KYGBge3J9DQpzcXJ0KG4pDQpgYGANCkRldmVtb3MgdXNhciBhcXVpIG8gY29tYW5kbyA8c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6Q291cmFudDsgZm9udC1zaXplOjFlbTsiPnNhcHBseTwvc3Bhbj4sIHF1ZSBwZXJtaXRlIGEgcXVlIGEgYXZhbGlhw6fDo28gZG8gZnVuw6fDo28gc2VqYSBmZWl0YSBlbSB0b2RhcyBhcyBjb21wb25lbnRlcyBkYSBlbnRyYWRhOiANCmBgYHtyfQ0Kc2FwcGx5KG4sY29tcHV0ZV9wcm9iKQ0KYGBgDQpGYcOnYW1vcyB1bSBncsOhZmljbyBwYXJhICpuKiBkZSAyIGEgNjA6DQpgYGB7cn0NCm4gPC0gMjo2MA0KcHJvYiA8LSBzYXBwbHkobixjb21wdXRlX3Byb2IpDQpwbG90KG4scHJvYikNCmBgYA0KQ2FsY3VsZW1vcyBhcyBwcm9iYWJpbGlkYWRlcyBleGF0YXMgZW0gdmV6IGRlIHVzYXIgc2ltdWxhw6fDtWVzIGRlIE1vbnRlIENhcmxvLiBOZXN0ZSBjYXNvLCDDqSBtYWlzIHNpbXBsZXMgY2FsY3VsYXIgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBvIGV2ZW50byAoYW5pdmVyc8OhcmlvcyBubyBtZXNtbyBkaWEpIG7Do28gb2NvcnJhLiBFeGFtaW5lbW9zIGEgcHJvYmFiaWxpZGFkZSAqUHIobikqIGRlIHF1ZSB1bSBuw7ptZXJvICpuKiBkZSBwZXNzb2FzIHRlbmhhIGFuaXZlcnPDoXJpbyBudW1hIGRhdGEgw7puaWNhLiBTZSAqbj0xKiB0ZXJlbW9zIG9idmlhbWVudGUgKlByKDEpPTEqLiBBIHByb2JhYmlsaWRhZGUgZGUgcXVlIGEgc2VndW5kYSBwZXNzb2EgdGVuaGEgYW5pdmVyc8OhcmlvIMO6bmljbywgZGFkbyBxdWUgYSBwcmltZWlyYSBwZXNzb2EgdGluaGEgYW5pdmVyc8OhcmlvIMO6bmljbyDDqSAzNjMvMzY1LiBBIHByb2JhYmlsaWRhZGUgZGUgcXVlIGEgdGVyY2VpcmEgcGVzc29hIHRlbmhhIGFuaXZlcnPDoXJpbyDDum5pY28sIGRhZG8gcXVlIGFzIGR1YXMgcHJpbWVpcmFzIHRpbmhhbSBhbml2ZXJzw6FyaW8gw7puaWNvIMOpIDM2My8zNjUuIEFzc2ltLCBhcyBwcm9iYWJpbGlkYWRlcyAyIGUgMyBwZXNzb2FzIHRlbmhhbSBhbml2ZXJzw6FyaW8gw7puaWNvIHPDo28gZGFkYSBwb3INCiQkDQpQcigyKSA9IDEgXHRpbWVzIFxmcmFjezM2NH17MzY1fVwsLCBccXVhZCAgUHIoMykgPSAxIFx0aW1lcyBcZnJhY3szNjR9ezM2NX0gXHRpbWVzIFxmcmFjezM2M317MzY1fVwsLg0KJCQNCkRlIG1vZG8gZ2VyYWwsDQokJA0KIFByKG4pID0gMSBcdGltZXMgXGZyYWN7MzY0fXszNjV9IFx0aW1lcyBcZnJhY3szNjN9ezM2NX0gXHRpbWVzIFxjZG90cyBcdGltZXMgXGZyYWN7MzY1LW4rMX17MzY1fVwsLg0KJCQNCkZhw6dhbW9zIGEgaW1wbGVtZW50YcOnw6NvIGVtIFI6IA0KYGBge3J9IA0KcF9leGF0YSA8LSBmdW5jdGlvbihuKXsNCiAgcF91bmljbyA8LSBzZXEoMzY1LCAzNjUtbisxKS8zNjUNCiAgMSAtIHByb2QocF91bmljbykNCn0NCmBgYA0KRmHDp2Ftb3MgdW0gdGVzdGU6IA0KYGBge3J9DQpwX2V4YXRhKDQwKQ0KYGBgDQpQb2RlbW9zIGFnb3JhIGF2YWxpYXIgZXN0YSBmdW7Dp8OjbyBub3MgdsOhcmlvcyB2YWxvcmVzIGRlICpuKjoNCmBgYHtyfQ0KZXByb2IgPC0gc2FwcGx5KG4scF9leGF0YSkNCnBsb3QobiwgZXByb2IpDQpgYGANCkNvbXBhcmVtb3MgZXN0ZSByZXN1bHRhZG8gZ3LDoWZpY28gY29tIGFxdWVsZSBvYnRpZG8gY29tIG8gbcOpdG9kbyBkZSBNb250ZSBDYXJsbywgdXNhbmRvIHVtIGN1cnZhIGNvbnTDrW51YSBwYXJhIG8gcmVzdWx0YWRvIGV4YXRvOiANCmBgYHtyfQ0KcGxvdChuLCBwcm9iKQ0KbGluZXMobiwgZXByb2IsIGNvbD0iYmx1ZSIpDQpgYGANClRhbCByZXN1bHRhZG8gbW9zdHJhIHVtYSBib2EgY29uY29yZMOibmNpYSBlbnRyZSBvcyBtw6l0b2Rvcy4gDQoNCjxoND5Ow7ptZXJvIGRlIEFtb3N0cmFzIG5hcyBzaW11bGHDp8O1ZXMgZGUgTW9udGUgQ2FybG88L2g0Pg0KVW1hIHF1ZXN0w6NvIGNydWNpYWwgZW0gc2ltdWxhw6fDtWVzIGRlIE1vbnRlIENhcmxvIGVudm9sdmUgYSBlc2NvbGhhIGRvIG7Dum1lcm8gZGUgZXhwZXJpbWVudG9zIGEgc2VyZW0gZmVpdG9zLiANCkRlZmluaW1vcyB1bSBpbnRlcnZhbG8gZGUgdmFyaWHDp8OjbyBkZSAqQio6IA0KYGBge3J9DQpCIDwtIDEwXnNlcSgxLCA1LCBsZW4gPSAxMDApDQpgYGANCmUgYWdvcmEgdW1hIGZ1bsOnw6NvIHF1ZSBjYWxjdWxhIGFzIHByb2JhYmlsaWRhZGVzIHBhcmEgY2FkYSBzaW11bGHDp8Ojby4gRml4ZW1vcyAqbj0zMCouDQpgYGB7cn0NCmNvbXB1dGVfcHJvYiA8LSBmdW5jdGlvbihCLCBuID0gMzApew0KICBzYW1lX2RheSA8LSByZXBsaWNhdGUgKEIsIHsNCiAgICBiZGF5cyA8LSBzYW1wbGUoMTozNjUsIG4sIHJlcGxhY2U9VFJVRSkNCiAgICBhbnkoZHVwbGljYXRlZChiZGF5cykpDQogIH0pDQogIG1lYW4oc2FtZV9kYXkpDQp9DQpgYGANCkZhw6dhbW9zIGFnb3JhIGEgYXZhbGlhw6fDo28gZGEgZnVuw6fDo28gcGFyYSB0b2RvcyBvcyB2YWxvcmVzIGRlICpCKiBlIHBsb3RlbW9zIG8gcmVzdWx0YWRvOiANCmBgYHtyfQ0KcHJvYiA8LSBzYXBwbHkoQiwgY29tcHV0ZV9wcm9iKQ0KcGxvdChsb2cxMChCKSwgcHJvYiwgdHlwZSA9ImwiKQ0KYGBgDQogTm90ZW1vcyBxdWUgYSBwYXJ0aXIgZGUgJEIgPSAxMF4zJCBvcyByZXN1bHRhZG9zIGNvbWXDp2FtIGEgZXN0YWJpbGl6YXIuIA0KIA0KPGg0PkV4ZW1wbG8uIE8gUHJvYmxlbWEgZGUgTW9udHkgSGFsbDwvaDQ+DQpPIHByb2JsZW1hIGRlIE1vbnR5IEhhbGwgcG9kZSBzZXIgZm9ybXVsYWRvIGRhIHNlZ3VpbnRlIG1hbmVpcmE6IA0KDQpTdXBvbmhhbW9zIHF1ZSB2b2PDqiBlc3TDoSBudW0gY29uY3Vyc28gZSB0ZW0gcXVlIGVzY29saGVyIGVudHJlIDMgcG9ydGFzOiBhdHLDoXMgZGUgdW1hIGRhcyBwb3J0YXMgZXN0w6EgdW0gY2Fycm8sIGUgYXRyw6FzIGRhcyBvdXRyYXMgYm9kZXMuIFZvY8OqIGVzY29saGUgdW1hIHBvcnRhLCBkaWdhbW9zIGEgcG9ydGEgMSBlIG8gYXByZXNlbnRhZG9yLCBxdWUgc2FiZSBvbmRlIGVzdMOhIG8gY2Fycm8sIHZhaSBhYnJpciBvdXRyYSBwb3J0YSwgMywgcG9yIGV4ZW1wbG8sIG9uZGUgaMOhIHVtIGJvZGUuIEVsZSBlbnTDo28gbGhlIHBlcmd1bnRhOiAidm9jw6ogcXVlciBmaWNhciBjb20gYSBwb3J0YSAxIG91IHF1ZXIgdHJvY2FyIHBlbGEgcG9ydGEgMj8iIEjDoSBhbGd1bWEgdmFudGFnZW0gZW0gc2UgdHJvY2FyIGRlIHBvcnRhPyANCkFiYWl4byBlc3TDoSBvIGPDs2RpZ28gcmVmZXJlbnRlIMOgIGVzY29saGEgZGEgcHJpbWVpcmEgcG9ydGEuDQpgYGB7cn0NCkIgPC0gMTAwMDAgI27Dum1lcm8gZGUgZXhwZXJpbWVudG9zDQptZXNtYV9wb3J0YSA8LSByZXBsaWNhdGUoQiwgew0KcG9ydGFzIDwtIGFzLmNoYXJhY3RlcigxOjMpICNkZWZpbmUgbyB2ZXRvciBjb20gY29tcG9uZW50cyAiMSIsICIyIiwgIjMiLiANCnByZW1pbyA8LSBzYW1wbGUoYygiY2Fycm8iLCAiYm9kZSIsICJib2RlIikpICNtaXN0dXJhIGFsZWF0b3JpYW1lbnQgb3JkZW0gZG8gc3RyaW5nICJjYXJybyIsICJib2RlIiwgImJvZGUiDQpwb3J0YV9wcmVtaWFkYSA8LSBwb3J0YXNbcHJlbWlvID09ICJjYXJybyJdICNkZXRlcm1pbmEgbyDDrW5kaWNlIGRhIHBvcnRhIHByZW1pYWRhDQptaW5oYV9lc2NvbGhhPC0gc2FtcGxlKHBvcnRhcywgMSkgI2ZheiB1bWEgZXNjb2xoYSBhbGVhdMOzcmlhIGVudHJlICIxIiwgIjIiLCAiMyINCiNzaG93IDwtIHNhbXBsZShwb3J0YXNbIXBvcnRhcyAlaW4lIGMobWluaGFfZXNjb2xoYSwgcG9ydGFfcHJlbWlhZGEpXSwxKQ0KbWVzbWFfcG9ydGEgPC0gbWluaGFfZXNjb2xoYSAjbWFudMOpbSBhIGVzY29saGEgb3JpZ2luYWwNCm1lc21hX3BvcnRhID09IHBvcnRhX3ByZW1pYWRhICN2ZXJpZmljYSBzZSBhIGVzY29saGEgZGEgcG9ydGEgY29ycmVzcG9uZGUgYW8gcHLDqm1pbyAoVFJVRSBvdSBGQUxTRSkNCn0pDQptZWFuKG1lc21hX3BvcnRhKSAjY2FsY3VsZSBhIHByb3BvcsOnw6NvIGRlIHZhbG9yZXMgVFJVRQ0KYGBgDQogRXN0ZSByZXN1bHRhZG8gaW5kaWNhIHF1ZSBhIHByb2JhYmlsaWRhZGUgw6kgMS8zLCBvIHF1ZSDDqSBlc3BlcmFkbywgcG9pcyBuYWRhIG11ZG91IHJlbGF0aXZhbWVudGUgw6AgZXNjb2xoYSBvcmlnaW5hbCBkZSAxIHBvcnRhIGVudHJlIDMuICBWZWphbW9zIGFnb3JhIG8gcXVlIG9jb3JyZSBzZSBlc2NvbGhlbW9zIGEgZXN0cmF0w6lnaWEgZGUgdHJvY2FyIGEgZXNjb2xoYTogDQpgYGB7cn0NCkIgPC0gMTAwMDAgI27Dum1lcm8gZGUgZXhwZXJpbWVudG9zDQp0cm9jYV9wb3J0YSA8LSByZXBsaWNhdGUoQiwgew0KcG9ydGFzIDwtIGFzLmNoYXJhY3RlcigxOjMpICNkZWZpbmUgbyB2ZXRvciBjb20gY29tcG9uZW50cyAiMSIsICIyIiwgIjMiLiANCnByZW1pbyA8LSBzYW1wbGUoYygiY2Fycm8iLCAiYm9kZSIsICJib2RlIikpICNtaXN0dXJhIGFsZWF0b3JpYW1lbnQgb3JkZW0gZG8gc3RyaW5nICJjYXJybyIsICJib2RlIiwgImJvZGUiDQpwb3J0YV9wcmVtaWFkYSA8LSBwb3J0YXNbcHJlbWlvID09ICJjYXJybyJdICNkZXRlcm1pbmEgbyDDrW5kaWNlIGRhIHBvcnRhIHByZW1pYWRhDQptaW5oYV9lc2NvbGhhPC0gc2FtcGxlKHBvcnRhcywgMSkgI2ZheiB1bWEgZXNjb2xoYSBhbGVhdMOzcmlhIGVudHJlICIxIiwgIjIiLCAiMyINCnNob3cgPC0gc2FtcGxlKHBvcnRhc1shcG9ydGFzICVpbiUgYyhtaW5oYV9lc2NvbGhhLCBwb3J0YV9wcmVtaWFkYSldLDEpICNtb3N0cmEgYSBwb3J0YSBkaWZlcmVudGUgZGEgb3JpZ2luYWxtZW50ZSBlc2NvbGhpZGEgZSBxdWUgbsOjbyBjb250w6ltIG8gY2Fycm8NCnRyb2NhX3BvcnRhIDwtIHBvcnRhc1shcG9ydGFzJWluJWMobWluaGFfZXNjb2xoYSwgc2hvdyldI2VzY29saGUgYSBwb3J0YSBxdWUgbsOjbyDDqSBhIG1vc3RyYWRhIChwb2lzIG7Do28gY29udMOpbSBwcsOqbWlvIGUgdGFtYsOpbSBuw6NvIMOpIGEgb3JpZ2luYWwpDQp0cm9jYV9wb3J0YSA9PSBwb3J0YV9wcmVtaWFkYSAjdmVyaWZpY2Egc2UgYSBlc2NvbGhhIGRhIHBvcnRhIGNvcnJlc3BvbmRlIGFvIHByw6ptaW8gKFRSVUUgb3UgRkFMU0UpDQp9KQ0KbWVhbih0cm9jYV9wb3J0YSkgI2NhbGN1bGUgYSBwcm9wb3LDp8OjbyBkZSB2YWxvcmVzIFRSVUUNCmBgYA0KIE91IHNlamEsIGEgcHJvYmFiaWxpZGFkZSBhZ29yYSDDqSAyLzMuIElzc28gw6kgZXNwZXJhZG8sIHBvaXMgdGVtb3MgYWdvcmEgYSBpbmZvcm1hw6fDo28gZGUgcXVhbCDDqSB1bWEgZGFzIHBvcnRhcyBxdWUgbsOjbyBjb250w6ltIG8gcHLDqm1pby4gDQogDQo8aDQ+IEV4ZXJjw61jaW9zIDwvaDQ+DQpFbSB0b2RvcyBvcyBwcm9ibGVtYXMgYWJhaXhvLCBjYWxjdWxlIGV4YXRhbWVudGUgZSBzaW11bGUgY29tIE1vbnRlIENhcmxvLg0KDQoxLiBVbWEgY2FpeGEgY29udMOpbSAxNSBib2xhcyBicmFuY2FzIGUgMjUgYm9sYXMgYXp1aXMuIER1YXMgYm9sYXMgc8OjbyBzZWxlY2lvbmFkYXMgYWxlYXTDs3JpYW1lbnRlLCBzZW0gc3Vic3RpdHVpw6fDo28uIFNlamEgKkEqIG8gZXZlbnRvIGNvcnJlc3BvbmRlbnRlIGFvIGZhdG8gZGEgcHJpbWVpcmEgYm9sYSBzZXIgYnJhbmNhIGUgKkIqIG8gZXZlbnRvIGFzc29jaWFkbyBhbyBmYXRvIGRhIHNlZ3VuZGEgYm9sYSBzZXIgYXp1bC4gRGV0ZXJtaW5lICRQcihBKSQsICRQcihCfEEpJCwgJFByKEEgXGN1cCBCKSQsICRQcihBIFxjYXAgQikkLiAgDQoNCjIuIChNUiBwLjYxIFsxXSkgTyBjaXJjdWl0byBtb3N0cmFkbyBuYSBmaWd1cmEgYWJhaXhvIGZ1bmNpb25hIHNlIGUgc29tZW50ZSBzZSBow6EgdW0gY2FtaW5obyBkZSBkaXNwb3NpdGl2b3MgZnVuY2lvbmFpcyBkYSBlc3F1ZXJkYSBwYXJhIGEgZGlyZWl0YS4gU3Vwb25oYSBxdWUgdG9kb3Mgb3MgZGlzcG9zaXRpdm9zIGZhbGhhbSBpbmRlcGVuZGVudGVtZW50ZSBxdWUgYSBwcm9iYWJpbGlkYWRlIGRlIGZhbGhhIGVtIGNhZGEgZGlzcG9zaXRpdm8gw6kgaW5kaWNhZGEgcGVsbyBuw7ptZXJvIGVtIGNhZGEgY2FpeGEuIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIHF1ZSBvIGNpcmN1aXRvIG9wZXJlPyANCg0KPGNlbnRlcj4gDQohW0NpcmN1aXRvIGRlIHByb2JhYmlsaWRhZGUuIFByb2JsZW1hIDJdKHByb2JfY2lyYzEucG5nKQ0KPC9jZW50ZXI+DQoNCg0KMy4gUmV0aXJhbW9zLCBjb20gc3Vic3RpdHVpw6fDo28sICA1IGJvbGFzIGRlIHVtYSBjYWl4YSBxdWUgY29udMOpbSA0IGJvbGFzIGJyYW5jYXMsIDYgYXp1aXMgZSA3IGFtYXJlbGFzLiBTdXBvbmRvIHF1ZSBhcyA1IHByaW1laXJhcyBib2xhcyBmb3JhbSB0b2RhcyBhbWFyZWxhcywgcXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZGUgcXVlIGFvIHJldGlyYXIgYSBzZXh0YSBib2xhIGVuY29udHJlbW9zIG5vdmFtZW50ZSB1bWEgYm9sYSBhbWFyZWxhPyBSOiAwLjQ3DQoNCjQuIEpvZ2Ftb3MgdW0gZGFkbyBob25lc3RvIDYgdmV6ZXMuIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIG7Do28gc2FpciB1bSA2IGVtIG5lbmh1bWEgam9nYWRhPyAgUjogMC4zMw0KDQo1LiBKb2dhbW9zIDIgZGFkb3MgaG9uZXN0b3MuIFF1YWwgw6kgYSBwcm9iYWJpbGlkYWRlIGRlIG9idGVybW9zIG1haXMgZGUgMTAgcG9udG9zIGVtIDQgam9nYWRhcz8gDQoNCjYuIFJlc29sdmEgb3MgcHJvYmxlbWFzIGFudGVyaW9yZXMgc3Vwb25kbyBxdWUgb3MgZGFkb3Mgc8OjbyB2aWNpYWRvcyBkbyBzZWd1aW50ZSBtb2RvOiBvIGxhZG8gNiB0ZW0gcHJvYmFiaWxpZGFkZSAxLjEvNiBlIG9zIG91dHJvcyBsYWRvcyB0w6ptIHByb2JhYmlsaWRhZGVzIGlndWFpcy4gIA0KDQo3LiBVbSB0aW1lIGRlIGZ1dGVib2wgcHJlY2lzYSBmYXplciA3IHBvbnRvcyBlbSA1IGpvZ29zIHBhcmEgbsOjbyBzZXIgcmViYWl4YWRvIHBhcmEgYSBsaWdhIGluZmVyaW9yLiBOb3Mgam9nb3MgcXVlIGZhcsOhIGVzdGltYS1zZSBxdWUgZWxlIHRlbSAxMCUgZGUgY2hhbmNlcyBkZSB2ZW5jZXIsIDUwJSBkZSBlbXBhdGFyIGUgNDAlIGRlIHBlcmRlci4gUXVhbCDDqSBhIHByb2JhYmlsaWRhZGUgZG8gdGltZSBuw6NvIHNlciByZWJhaXhhZG8uICANCg0KOC4gRW0gdW0gYmFyYWxobyBjb21wbGV0bywgYW8gcmV0aXJhcm1vcyA1IGNhcnRhcywgZGV0ZXJtaW5lICBhIHByb2JhYmlsaWRhZGUgY29uc2VndWlybW9zIGNhZGEgdW0gZG9zIHNlZ3VpbnRlcyByZXN1bHRhZG9zOiANCihhKSBEb2lzIHBhcmVzIDxicj4NCihiKSBUcmluY2EgPGJyPg0KKGMpIFNlcXXDqm5jaWEgPGJyPg0KKGQpIEZsdXNoIDxicj4NCihlKSBGdWxsIEhvdXNlIDxicj4NCihmKSBRdWFkcmEgPGJyPg0KKGcpIFN0cmFpZ2ggRmxhc2ggPGJyPg0KKGgpIFJveWFsIEZsYXNoLg0KDQo8aDQ+UmVmZXLDqm5jaWFzPC9oND4NCjEuIERvdWdsYXMgQy4gTW9udGdvbWVyeSBlIEdlb3JnZSBDLiBSdW5nZXIuIEFwcGxpZWQgU3RhdGlzdGljcyBhbmQgUHJvYmFiaWxpdHkgZm9yIEVuZ2luZWVycywgNnRoIGVkLiwgV2lsZXksICAyMDE0DQo=