library(flexdashboard)
knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE,
include = TRUE
)
##
r = getOption("repos")
r["CRAN"] = "http://cran.us.r-project.org"
options(repos = r)
###
if(!require(tidyverse)){install.packages("tidyverse")}
if(!require(googlesheets4)){install.packages("googlesheets4")}
if(!require(googledrive)){install.packages("googledrive")}
if(!require(dplyr)){install.packages("dplyr")}
if(!require(httr2)){install.packages("httr2")}
if(!require(jsonlite)){install.packages("jsonlite")}
if(!require(Rselenium)){install.packages("Rselenium")}
WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:
https://cran.rstudio.com/bin/windows/Rtools/
if(!require(chromote)){install.packages("chromote")}
if(!require(purrr)){install.packages("purrr")}
if(!require(wdman)){install.packages("wdman")}
if(!require(pdftools)){install.packages("pdftools")}
##
library(pdftools)
library(chromote)
library(purrr)
library(wdman)
library(tidyverse)
library(rvest)
library(dplyr)
library(jsonlite)
library(RSelenium)
library(googlesheets4)
library(googledrive)
Men_Boulder_Soure_July
##################################################
# scraping active page using chromote #
#############################################
# URL of the webpage to scrape
url <- "https://www.ifsc-climbing.org/events/ifsc-youth-european-cup-soure-2024/result/index?discipline=boulder&category=juniors+male"
############ chromote:: OPTION ######
# Create a new Chromote session
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "05950A1DC90DF813492AC530BBB47528"
$loaderId
[1] "9743B4D260941915025041C232947F50"
Quali
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();') # Replace with your CSS selector
Sys.sleep(10)
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Qualification"
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(compe, length(scrap$Name) ),
Stage = rep("Quali", length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 29
############### ##################
Men_youth_Soure_Quali <- scrap
Finals
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "BF2172E91D6664C1E383BBD881CBB628"
$loaderId
[1] "38FD1E43902DE59C1EF6B3D6FD75CE45"
#
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();')
#
Sys.sleep(10)
###
b$Runtime$evaluate("
let dropdown = document.querySelector('select.d3-ty-select'); // Find the dropdown by class
if (dropdown) {
dropdown.value = 'Final'; // Set the value to 'Final'
dropdown.dispatchEvent(new Event('change', { bubbles: true })); // Trigger update
}
")
$result
$result$type
[1] "boolean"
$result$value
[1] TRUE
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Final"
###
Sys.sleep(10)
#
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(compe, length(scrap$Name) ),
Stage = rep(stage, length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 10
############### ##################
Men_youth_Soure_Finals <- scrap
Men_youth_a_Boulder_Soure_July
##################################################
# scraping active page using chromote #
#############################################
# URL of the webpage to scrape
url <- "https://www.ifsc-climbing.org/events/ifsc-youth-european-cup-soure-2024/result/index?discipline=boulder&category=youth+a+male"
############ chromote:: OPTION ######
# Create a new Chromote session
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "CB1F9DB9D3F1CAFEB1474C1B9301AEDA"
$loaderId
[1] "773458DAEC4AB3081D0D16CE91C7BE85"
Quali
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();') # Replace with your CSS selector
Sys.sleep(10)
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Qualification"
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(paste(compe, "a"), length(scrap$Name) ),
Stage = rep("Quali", length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 50
############### ##################
Men_youth_a_Soure_Quali <- scrap
Finals
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "681F7700384D1C2679371675CBC04CF8"
$loaderId
[1] "4D264165B75610A11303D183F6E8E918"
#
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();')
#
Sys.sleep(10)
###
b$Runtime$evaluate("
let dropdown = document.querySelector('select.d3-ty-select'); // Find the dropdown by class
if (dropdown) {
dropdown.value = 'Final'; // Set the value to 'Final'
dropdown.dispatchEvent(new Event('change', { bubbles: true })); // Trigger update
}
")
$result
$result$type
[1] "boolean"
$result$value
[1] TRUE
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Final"
###
Sys.sleep(10)
#
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(paste(compe,"a"), length(scrap$Name) ),
Stage = rep(stage, length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 10
############### ##################
Men_youth_a_Soure_Finals <- scrap
Men_youth_b_Boulder_Soure_July
##################################################
# scraping active page using chromote #
#############################################
# URL of the webpage to scrape
url <- "https://www.ifsc-climbing.org/events/ifsc-youth-european-cup-soure-2024/result/index?discipline=boulder&category=youth+b+male"
############ chromote:: OPTION ######
# Create a new Chromote session
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "95E2DE97D34D40B725F7862C1A0F2120"
$loaderId
[1] "95286FACC9AECDC3D5F0059A5B5F95E9"
Quali
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();') # Replace with your CSS selector
Sys.sleep(10)
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Qualification"
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(paste(compe,"b"), length(scrap$Name) ),
Stage = rep("Quali", length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 45
############### ##################
Men_youth_b_Soure_Quali <- scrap
Finals
b <- ChromoteSession$new()
# Navigate to the webpage
b$Page$navigate(url)
$frameId
[1] "C798A8B246D7FFCB91DDC1ECE25A6DC2"
$loaderId
[1] "93842CE02F60BA53EA41CC65234B3DD1"
#
html <- b$Runtime$evaluate('document.querySelector(".appearence-none:nth-child(1)").click();')
#
Sys.sleep(10)
###
b$Runtime$evaluate("
let dropdown = document.querySelector('select.d3-ty-select'); // Find the dropdown by class
if (dropdown) {
dropdown.value = 'Final'; // Set the value to 'Final'
dropdown.dispatchEvent(new Event('change', { bubbles: true })); // Trigger update
}
")
$result
$result$type
[1] "boolean"
$result$value
[1] TRUE
###
stage <- b$Runtime$evaluate("
document.querySelector('select.d3-ty-select').value;
")$result$value
stage
[1] "Final"
###
Sys.sleep(10)
#
### WAIT for "backstage" page loading ####
html <- b$Runtime$evaluate("document.documentElement.outerHTML")$result$value
##
page <- read_html(html)
###
compe <- page %>%
html_elements('h2.d3-ty-heading-2') %>%
html_text()
###
competitor_divs <- page %>%
html_elements("tr.px-6") #
# Extract and clean data
scrap <- competitor_divs %>%
map_df(~{
rank <- .x %>% html_element("td.py-2:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1) # rank
name <- .x %>% html_element("td.py-2:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1) # name
country <- .x %>% html_element("td.py-2:nth-child(3)") %>% html_text(trim = TRUE) %>% tail(1) # country
b1.T <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b2.T <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b3.T <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b4.T <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b5.T <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b6.T <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(1)") %>% html_text(trim = TRUE) %>% tail(1)
b1.Z <- .x %>% html_element("td.py-2:nth-child(4) span:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b2.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(2) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b3.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(3) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b4.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(4) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b5.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(5) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
b6.Z <- .x %>% html_element(".d3-ty-ascent:nth-child(6) .bg-blue-aa:nth-child(2)") %>% html_text(trim = TRUE) %>% tail(1)
score <- .x %>% html_element("span.text-black") %>% html_text(trim = TRUE) %>% tail(1)
# Return as a tibble
tibble(Name = name,
Rank = rank,
Country = country,
B1.T = b1.T,
B2.T = b2.T,
B3.T = b3.T,
B4.T = b4.T,
B5.T = b5.T,
B6.T = b6.T,
B1.Z = b1.Z,
B2.Z = b2.Z,
B3.Z = b3.Z,
B4.Z = b4.Z,
B5.Z = b5.Z,
B6.Z = b6.Z,
Score = score)
})
###
scrap <- scrap %>%
separate(Score, into = c("Ts.Zs","attempts.t", "attempts.z"), sep = " ") %>% separate(Ts.Zs, into = c("Tops","Zones"), sep="T") %>% separate(Zones, into = c("Zones",NA), sep="z")
#
scrap <- scrap %>%
mutate_at(c(2,4:17), as.numeric) %>%
mutate(Competition = rep(paste(compe,"b"), length(scrap$Name) ),
Stage = rep(stage, length(scrap$Name ) ) )
##
compe
[1] "IFSC Youth European Cup Soure 2024"
n.competitors <- max(scrap$Rank, na.rm = TRUE); n.competitors
[1] 10
############### ##################
Men_youth_b_Soure_Finals <- scrap
WRITE
### Write google sheet ###
Men_Boulder_Youth_Soure.24 <- rbind(Men_youth_Soure_Quali,
Men_youth_Soure_Finals,
Men_youth_a_Soure_Quali,
Men_youth_a_Soure_Finals,
Men_youth_b_Soure_Quali,
Men_youth_b_Soure_Finals)
Men_Boulder_Youth_Soure.24 %>% print(n=length(Men_Boulder_Youth_Soure.24$Name))
#
Men_Boulder_Youth_Soure.24 %>%
filter(Competition== "IFSC Youth European Cup Soure 2024") %>%
knitr::kable()
guillermo PEINADO FRANGANILLO |
1 |
ESP |
1 |
NA |
5 |
1 |
1 |
NA |
1 |
2 |
3 |
1 |
1 |
NA |
4 |
5 |
8 |
8 |
IFSC Youth European Cup Soure 2024 |
Quali |
luca BOLDRINI |
2 |
ITA |
1 |
NA |
5 |
1 |
1 |
NA |
1 |
4 |
5 |
1 |
1 |
NA |
4 |
5 |
8 |
12 |
IFSC Youth European Cup Soure 2024 |
Quali |
raffael GRUBER |
3 |
AUT |
2 |
NA |
7 |
3 |
1 |
NA |
2 |
2 |
6 |
3 |
1 |
NA |
4 |
5 |
13 |
14 |
IFSC Youth European Cup Soure 2024 |
Quali |
darius RAPA |
4 |
ROU |
1 |
NA |
9 |
3 |
3 |
NA |
1 |
4 |
9 |
3 |
1 |
NA |
4 |
5 |
16 |
18 |
IFSC Youth European Cup Soure 2024 |
Quali |
alexandre NOËL |
5 |
BEL |
1 |
NA |
NA |
1 |
2 |
NA |
1 |
3 |
2 |
1 |
2 |
NA |
3 |
5 |
4 |
9 |
IFSC Youth European Cup Soure 2024 |
Quali |
tomer YAKOBOVITCH |
6 |
ISR |
1 |
NA |
2 |
1 |
NA |
NA |
1 |
NA |
2 |
1 |
2 |
NA |
3 |
4 |
4 |
6 |
IFSC Youth European Cup Soure 2024 |
Quali |
tolani ETCHAR |
6 |
FRA |
1 |
NA |
NA |
1 |
2 |
NA |
1 |
2 |
NA |
1 |
2 |
NA |
3 |
4 |
4 |
6 |
IFSC Youth European Cup Soure 2024 |
Quali |
james JENKINS |
8 |
GBR |
1 |
NA |
5 |
NA |
2 |
NA |
1 |
NA |
5 |
2 |
1 |
NA |
3 |
4 |
8 |
9 |
IFSC Youth European Cup Soure 2024 |
Quali |
lau MACIÀ LLOBET |
9 |
ESP |
2 |
NA |
NA |
4 |
4 |
NA |
2 |
NA |
NA |
2 |
2 |
NA |
3 |
3 |
10 |
6 |
IFSC Youth European Cup Soure 2024 |
Quali |
ilja AUERSPERG |
10 |
AUT |
1 |
NA |
NA |
2 |
NA |
NA |
1 |
2 |
6 |
2 |
2 |
NA |
2 |
5 |
3 |
13 |
IFSC Youth European Cup Soure 2024 |
Quali |
florian SCHWEIGER |
11 |
GER |
1 |
NA |
NA |
1 |
NA |
NA |
1 |
3 |
NA |
1 |
1 |
NA |
2 |
4 |
2 |
6 |
IFSC Youth European Cup Soure 2024 |
Quali |
levin STRAUBHAAR |
12 |
SUI |
1 |
NA |
NA |
NA |
1 |
NA |
1 |
NA |
7 |
1 |
1 |
NA |
2 |
4 |
2 |
10 |
IFSC Youth European Cup Soure 2024 |
Quali |
maksym VNUKOV |
13 |
UKR |
2 |
NA |
NA |
2 |
NA |
NA |
2 |
NA |
NA |
2 |
1 |
NA |
2 |
3 |
4 |
5 |
IFSC Youth European Cup Soure 2024 |
Quali |
mael BERNIER |
14 |
FRA |
4 |
NA |
NA |
3 |
NA |
NA |
1 |
NA |
NA |
3 |
1 |
NA |
2 |
3 |
7 |
5 |
IFSC Youth European Cup Soure 2024 |
Quali |
raúl ESCRIBANO SÁNCHEZ |
15 |
ESP |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
4 |
1 |
2 |
NA |
1 |
4 |
1 |
8 |
IFSC Youth European Cup Soure 2024 |
Quali |
sam POULLAIN |
15 |
FRA |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
4 |
NA |
1 |
2 |
NA |
1 |
4 |
1 |
8 |
IFSC Youth European Cup Soure 2024 |
Quali |
tim KOROSEC |
17 |
SLO |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
1 |
NA |
1 |
3 |
1 |
3 |
IFSC Youth European Cup Soure 2024 |
Quali |
maël MARCADÉ |
18 |
SUI |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
2 |
NA |
1 |
3 |
1 |
4 |
IFSC Youth European Cup Soure 2024 |
Quali |
nicolò SACRIPANTI |
18 |
ITA |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
2 |
1 |
NA |
1 |
3 |
1 |
4 |
IFSC Youth European Cup Soure 2024 |
Quali |
finn ALTEMÖLLER |
20 |
GER |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
8 |
NA |
1 |
NA |
1 |
3 |
1 |
10 |
IFSC Youth European Cup Soure 2024 |
Quali |
gorazd JUREKOVIC |
20 |
SLO |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
6 |
3 |
NA |
1 |
3 |
1 |
10 |
IFSC Youth European Cup Soure 2024 |
Quali |
gad PICK |
22 |
ISR |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
2 |
1 |
NA |
1 |
3 |
2 |
5 |
IFSC Youth European Cup Soure 2024 |
Quali |
gadi HALFON |
23 |
ISR |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
1 |
8 |
NA |
1 |
3 |
2 |
11 |
IFSC Youth European Cup Soure 2024 |
Quali |
dimitar DIMITROV |
24 |
BUL |
3 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
NA |
5 |
NA |
1 |
2 |
3 |
6 |
IFSC Youth European Cup Soure 2024 |
Quali |
tomass DILANS |
25 |
LAT |
7 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
2 |
NA |
1 |
2 |
7 |
4 |
IFSC Youth European Cup Soure 2024 |
Quali |
vasco AVELAR |
26 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
1 |
NA |
0 |
2 |
0 |
3 |
IFSC Youth European Cup Soure 2024 |
Quali |
nedas GRIGALIUNAS |
26 |
LTU |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
NA |
2 |
NA |
0 |
2 |
0 |
3 |
IFSC Youth European Cup Soure 2024 |
Quali |
daniil SAMYSHEV |
28 |
UKR |
NA |
NA |
NA |
NA |
NA |
NA |
7 |
NA |
NA |
NA |
2 |
NA |
0 |
2 |
0 |
9 |
IFSC Youth European Cup Soure 2024 |
Quali |
josé GOMES |
29 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
3 |
NA |
NA |
NA |
7 |
NA |
0 |
2 |
0 |
10 |
IFSC Youth European Cup Soure 2024 |
Quali |
guillermo PEINADO FRANGANILLO |
1 |
ESP |
1 |
NA |
1 |
NA |
NA |
NA |
1 |
2 |
1 |
1 |
NA |
NA |
2 |
4 |
2 |
5 |
IFSC Youth European Cup Soure 2024 |
Final |
ilja AUERSPERG |
2 |
AUT |
NA |
3 |
NA |
NA |
NA |
NA |
5 |
1 |
NA |
1 |
NA |
NA |
1 |
3 |
3 |
7 |
IFSC Youth European Cup Soure 2024 |
Final |
tomer YAKOBOVITCH |
3 |
ISR |
4 |
NA |
NA |
NA |
NA |
NA |
2 |
2 |
NA |
2 |
NA |
NA |
1 |
3 |
4 |
6 |
IFSC Youth European Cup Soure 2024 |
Final |
james JENKINS |
4 |
GBR |
5 |
NA |
NA |
NA |
NA |
NA |
2 |
5 |
NA |
1 |
NA |
NA |
1 |
3 |
5 |
8 |
IFSC Youth European Cup Soure 2024 |
Final |
tolani ETCHAR |
5 |
FRA |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
1 |
2 |
NA |
NA |
NA |
0 |
3 |
0 |
7 |
IFSC Youth European Cup Soure 2024 |
Final |
luca BOLDRINI |
6 |
ITA |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
NA |
1 |
3 |
NA |
NA |
0 |
3 |
0 |
8 |
IFSC Youth European Cup Soure 2024 |
Final |
raffael GRUBER |
7 |
AUT |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
1 |
NA |
4 |
NA |
NA |
0 |
3 |
0 |
9 |
IFSC Youth European Cup Soure 2024 |
Final |
alexandre NOËL |
8 |
BEL |
NA |
NA |
NA |
NA |
NA |
NA |
5 |
NA |
1 |
4 |
NA |
NA |
0 |
3 |
0 |
10 |
IFSC Youth European Cup Soure 2024 |
Final |
darius RAPA |
9 |
ROU |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
7 |
NA |
1 |
NA |
NA |
0 |
3 |
0 |
12 |
IFSC Youth European Cup Soure 2024 |
Final |
lau MACIÀ LLOBET |
10 |
ESP |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
4 |
NA |
NA |
0 |
2 |
0 |
5 |
IFSC Youth European Cup Soure 2024 |
Final |
#
Men_Boulder_Youth_Soure.24 %>%
filter(Competition== "IFSC Youth European Cup Soure 2024 a") %>%
knitr::kable()
corentin LAPORTE |
1 |
BEL |
1 |
NA |
NA |
2 |
1 |
1 |
1 |
1 |
5 |
2 |
1 |
1 |
4 |
6 |
5 |
11 |
IFSC Youth European Cup Soure 2024 a |
Quali |
timo OSSIG |
2 |
GER |
1 |
NA |
NA |
4 |
4 |
3 |
1 |
1 |
3 |
1 |
1 |
1 |
4 |
6 |
12 |
8 |
IFSC Youth European Cup Soure 2024 a |
Quali |
jan STIPEK |
3 |
CZE |
1 |
NA |
NA |
1 |
1 |
1 |
1 |
NA |
8 |
1 |
1 |
1 |
4 |
5 |
4 |
12 |
IFSC Youth European Cup Soure 2024 a |
Quali |
gefen LEVI |
4 |
ISR |
1 |
NA |
NA |
3 |
1 |
1 |
1 |
1 |
NA |
1 |
1 |
1 |
4 |
5 |
6 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
reem HAREL |
5 |
ISR |
1 |
NA |
NA |
2 |
2 |
2 |
1 |
NA |
NA |
2 |
1 |
1 |
4 |
4 |
7 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
camille CLAUDE |
6 |
FRA |
1 |
NA |
NA |
1 |
NA |
2 |
1 |
1 |
3 |
1 |
2 |
2 |
3 |
6 |
4 |
10 |
IFSC Youth European Cup Soure 2024 a |
Quali |
julian SCHRITTWIESER |
7 |
AUT |
3 |
NA |
NA |
1 |
NA |
1 |
1 |
6 |
4 |
1 |
1 |
1 |
3 |
6 |
5 |
14 |
IFSC Youth European Cup Soure 2024 a |
Quali |
adrien GSELL |
8 |
FRA |
2 |
NA |
4 |
NA |
NA |
1 |
2 |
4 |
4 |
1 |
5 |
1 |
3 |
6 |
7 |
17 |
IFSC Youth European Cup Soure 2024 a |
Quali |
andrés VILA ANDRÉS |
9 |
ESP |
3 |
NA |
10 |
4 |
NA |
NA |
3 |
1 |
10 |
2 |
3 |
1 |
3 |
6 |
17 |
20 |
IFSC Youth European Cup Soure 2024 a |
Quali |
janne EISENKOLB |
10 |
GER |
1 |
NA |
NA |
1 |
1 |
NA |
1 |
1 |
NA |
1 |
1 |
1 |
3 |
5 |
3 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
lukas MOKROLUSKY |
11 |
CZE |
1 |
NA |
NA |
1 |
NA |
4 |
1 |
NA |
7 |
1 |
1 |
2 |
3 |
5 |
6 |
12 |
IFSC Youth European Cup Soure 2024 a |
Quali |
lovre ČULIĆ |
12 |
CRO |
3 |
NA |
7 |
NA |
NA |
1 |
2 |
NA |
5 |
4 |
3 |
1 |
3 |
5 |
11 |
15 |
IFSC Youth European Cup Soure 2024 a |
Quali |
simone BELARDINELLI |
13 |
ITA |
1 |
NA |
NA |
NA |
2 |
2 |
1 |
NA |
2 |
NA |
1 |
1 |
3 |
4 |
5 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
jonas KÖRNER |
14 |
GER |
1 |
NA |
3 |
NA |
3 |
NA |
1 |
NA |
3 |
NA |
1 |
1 |
3 |
4 |
7 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
finley KERSWELL |
15 |
GBR |
2 |
NA |
NA |
NA |
5 |
1 |
1 |
NA |
NA |
3 |
1 |
1 |
3 |
4 |
8 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
erik SETTIMO |
16 |
ITA |
1 |
NA |
NA |
NA |
4 |
4 |
1 |
NA |
NA |
6 |
1 |
2 |
3 |
4 |
9 |
10 |
IFSC Youth European Cup Soure 2024 a |
Quali |
manuel antonio PASTOR SÁNCHEZ |
17 |
ESP |
1 |
NA |
NA |
NA |
NA |
2 |
1 |
2 |
10 |
2 |
2 |
1 |
2 |
6 |
3 |
18 |
IFSC Youth European Cup Soure 2024 a |
Quali |
lucas TRANDAFIR |
18 |
GER |
2 |
NA |
NA |
NA |
NA |
1 |
2 |
3 |
9 |
1 |
3 |
1 |
2 |
6 |
3 |
19 |
IFSC Youth European Cup Soure 2024 a |
Quali |
francesco MARCHIONNI |
19 |
ITA |
1 |
NA |
NA |
NA |
2 |
NA |
1 |
2 |
NA |
3 |
1 |
2 |
2 |
5 |
3 |
9 |
IFSC Youth European Cup Soure 2024 a |
Quali |
boyan KIROV |
20 |
BUL |
2 |
NA |
NA |
NA |
NA |
1 |
2 |
7 |
NA |
8 |
1 |
1 |
2 |
5 |
3 |
19 |
IFSC Youth European Cup Soure 2024 a |
Quali |
oscar PONGRATZ |
21 |
GER |
1 |
NA |
NA |
NA |
NA |
3 |
1 |
NA |
3 |
1 |
1 |
1 |
2 |
5 |
4 |
7 |
IFSC Youth European Cup Soure 2024 a |
Quali |
dmytro BESPALYI |
22 |
UKR |
11 |
NA |
NA |
NA |
8 |
NA |
11 |
NA |
10 |
4 |
3 |
1 |
2 |
5 |
19 |
29 |
IFSC Youth European Cup Soure 2024 a |
Quali |
alexandru-florian ZAHARIA |
23 |
ROU |
1 |
NA |
NA |
NA |
NA |
1 |
1 |
NA |
NA |
2 |
2 |
1 |
2 |
4 |
2 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
darius NAIMJI |
24 |
CZE |
1 |
NA |
NA |
1 |
NA |
NA |
1 |
NA |
NA |
1 |
3 |
3 |
2 |
4 |
2 |
8 |
IFSC Youth European Cup Soure 2024 a |
Quali |
davide TORRONI |
25 |
SUI |
1 |
NA |
NA |
NA |
NA |
2 |
1 |
NA |
NA |
2 |
1 |
1 |
2 |
4 |
3 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
or SIVAN |
26 |
ISR |
3 |
NA |
NA |
NA |
1 |
NA |
3 |
NA |
NA |
3 |
1 |
1 |
2 |
4 |
4 |
8 |
IFSC Youth European Cup Soure 2024 a |
Quali |
esteban BRIDOUX |
27 |
FRA |
5 |
NA |
NA |
NA |
NA |
4 |
5 |
NA |
NA |
7 |
4 |
1 |
2 |
4 |
9 |
17 |
IFSC Youth European Cup Soure 2024 a |
Quali |
ivan RUSEV |
28 |
BUL |
2 |
NA |
NA |
NA |
NA |
1 |
2 |
NA |
NA |
1 |
NA |
1 |
2 |
3 |
3 |
4 |
IFSC Youth European Cup Soure 2024 a |
Quali |
itay RUBANENKO |
29 |
ISR |
1 |
NA |
NA |
NA |
NA |
3 |
1 |
NA |
NA |
NA |
NA |
1 |
2 |
2 |
4 |
2 |
IFSC Youth European Cup Soure 2024 a |
Quali |
tommaso MILANESE |
30 |
ITA |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
3 |
6 |
1 |
1 |
1 |
1 |
6 |
2 |
14 |
IFSC Youth European Cup Soure 2024 a |
Quali |
nikodem WODZYNSKI |
31 |
POL |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
3 |
NA |
12 |
4 |
1 |
1 |
5 |
1 |
21 |
IFSC Youth European Cup Soure 2024 a |
Quali |
kasper TALLON |
32 |
BEL |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
3 |
NA |
4 |
2 |
1 |
1 |
5 |
2 |
12 |
IFSC Youth European Cup Soure 2024 a |
Quali |
anej KOSTOMAJ |
33 |
SLO |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
2 |
1 |
1 |
1 |
4 |
2 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
briq MIDDELBURG |
34 |
NED |
3 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
1 |
2 |
2 |
1 |
4 |
3 |
7 |
IFSC Youth European Cup Soure 2024 a |
Quali |
santiago ORONICH GREGORIO |
35 |
ESP |
NA |
NA |
NA |
NA |
NA |
3 |
1 |
NA |
NA |
3 |
6 |
1 |
1 |
4 |
3 |
11 |
IFSC Youth European Cup Soure 2024 a |
Quali |
lucas PÉREZ NIETO |
36 |
ESP |
6 |
NA |
NA |
NA |
NA |
NA |
6 |
NA |
NA |
5 |
1 |
3 |
1 |
4 |
6 |
15 |
IFSC Youth European Cup Soure 2024 a |
Quali |
jaroslav SIKULA |
37 |
CZE |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
NA |
2 |
3 |
1 |
3 |
1 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
oleksandr NEBOHA |
38 |
UKR |
2 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
2 |
2 |
1 |
3 |
2 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
paulo MERCADO GUÐRÚNARSON |
39 |
ISL |
3 |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
7 |
1 |
1 |
3 |
3 |
10 |
IFSC Youth European Cup Soure 2024 a |
Quali |
sebastian ŠTANCEL |
40 |
SVK |
4 |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
NA |
1 |
2 |
1 |
3 |
4 |
4 |
IFSC Youth European Cup Soure 2024 a |
Quali |
greipur ÁSMUNDARSON |
41 |
ISL |
7 |
NA |
NA |
NA |
NA |
NA |
7 |
NA |
NA |
NA |
4 |
1 |
1 |
3 |
7 |
12 |
IFSC Youth European Cup Soure 2024 a |
Quali |
yuval LAHAV |
42 |
ISR |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
1 |
1 |
0 |
4 |
0 |
4 |
IFSC Youth European Cup Soure 2024 a |
Quali |
garðar logi BJÖRNSSON |
43 |
ISL |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
1 |
2 |
0 |
4 |
0 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
marek SOUKAL |
44 |
CZE |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
2 |
3 |
1 |
0 |
4 |
0 |
7 |
IFSC Youth European Cup Soure 2024 a |
Quali |
noa SEEUWS |
45 |
BEL |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
NA |
NA |
NA |
1 |
1 |
0 |
3 |
0 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
daniel ŠTANCEL |
45 |
SVK |
NA |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
3 |
1 |
0 |
3 |
0 |
6 |
IFSC Youth European Cup Soure 2024 a |
Quali |
francisco BERNARDES |
47 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
8 |
NA |
6 |
0 |
3 |
0 |
16 |
IFSC Youth European Cup Soure 2024 a |
Quali |
pedro GONÇALVES |
48 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
4 |
NA |
NA |
NA |
NA |
1 |
0 |
2 |
0 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
tiago SEQUEIRA |
48 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
3 |
NA |
NA |
NA |
2 |
NA |
0 |
2 |
0 |
5 |
IFSC Youth European Cup Soure 2024 a |
Quali |
oskaras MIKELIONIS |
50 |
LTU |
NA |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
NA |
NA |
0 |
1 |
0 |
2 |
IFSC Youth European Cup Soure 2024 a |
Quali |
corentin LAPORTE |
1 |
BEL |
3 |
NA |
1 |
NA |
NA |
NA |
2 |
2 |
1 |
1 |
NA |
NA |
2 |
4 |
4 |
6 |
IFSC Youth European Cup Soure 2024 a |
Final |
adrien GSELL |
2 |
FRA |
5 |
NA |
NA |
NA |
NA |
NA |
2 |
3 |
1 |
3 |
NA |
NA |
1 |
4 |
5 |
9 |
IFSC Youth European Cup Soure 2024 a |
Final |
camille CLAUDE |
3 |
FRA |
7 |
NA |
NA |
NA |
NA |
NA |
4 |
9 |
1 |
1 |
NA |
NA |
1 |
4 |
7 |
15 |
IFSC Youth European Cup Soure 2024 a |
Final |
jan STIPEK |
4 |
CZE |
NA |
NA |
1 |
NA |
NA |
NA |
2 |
NA |
1 |
1 |
NA |
NA |
1 |
3 |
1 |
4 |
IFSC Youth European Cup Soure 2024 a |
Final |
gefen LEVI |
5 |
ISR |
NA |
NA |
NA |
3 |
NA |
NA |
7 |
NA |
1 |
3 |
NA |
NA |
1 |
3 |
3 |
11 |
IFSC Youth European Cup Soure 2024 a |
Final |
janne EISENKOLB |
6 |
GER |
NA |
7 |
NA |
NA |
NA |
NA |
10 |
1 |
NA |
4 |
NA |
NA |
1 |
3 |
7 |
15 |
IFSC Youth European Cup Soure 2024 a |
Final |
timo OSSIG |
7 |
GER |
NA |
1 |
NA |
NA |
NA |
NA |
4 |
1 |
NA |
NA |
NA |
NA |
1 |
2 |
1 |
5 |
IFSC Youth European Cup Soure 2024 a |
Final |
julian SCHRITTWIESER |
8 |
AUT |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
4 |
3 |
4 |
NA |
NA |
0 |
4 |
0 |
12 |
IFSC Youth European Cup Soure 2024 a |
Final |
andrés VILA ANDRÉS |
9 |
ESP |
NA |
NA |
NA |
NA |
NA |
NA |
6 |
NA |
2 |
NA |
NA |
NA |
0 |
2 |
0 |
8 |
IFSC Youth European Cup Soure 2024 a |
Final |
reem HAREL |
10 |
ISR |
NA |
NA |
NA |
NA |
NA |
NA |
5 |
NA |
4 |
NA |
NA |
NA |
0 |
2 |
0 |
9 |
IFSC Youth European Cup Soure 2024 a |
Final |
#
Men_Boulder_Youth_Soure.24 %>%
filter(Competition== "IFSC Youth European Cup Soure 2024 b") %>%
knitr::kable()
andrea ludovico CHELLERIS |
1 |
ITA |
1 |
2 |
2 |
1 |
2 |
2 |
1 |
1 |
2 |
1 |
1 |
2 |
6 |
6 |
10 |
8 |
IFSC Youth European Cup Soure 2024 b |
Quali |
or MARK |
2 |
ISR |
1 |
1 |
1 |
NA |
6 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
5 |
6 |
10 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
elyasaf LANEL |
3 |
ISR |
1 |
3 |
2 |
3 |
3 |
NA |
1 |
1 |
2 |
2 |
2 |
1 |
5 |
6 |
12 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
vincent VAN HAGE |
4 |
NED |
2 |
3 |
2 |
1 |
1 |
NA |
1 |
1 |
2 |
1 |
1 |
NA |
5 |
5 |
9 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
itamar HAREL |
5 |
ISR |
1 |
NA |
1 |
2 |
1 |
NA |
1 |
1 |
1 |
1 |
1 |
1 |
4 |
6 |
5 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
eñaut USON POBES |
6 |
ESP |
1 |
NA |
1 |
2 |
2 |
NA |
1 |
1 |
1 |
1 |
2 |
2 |
4 |
6 |
6 |
8 |
IFSC Youth European Cup Soure 2024 b |
Quali |
moreno GHILARDI |
6 |
SUI |
1 |
NA |
1 |
2 |
2 |
NA |
1 |
1 |
1 |
2 |
2 |
1 |
4 |
6 |
6 |
8 |
IFSC Youth European Cup Soure 2024 b |
Quali |
mattis EISENKOLB |
8 |
GER |
2 |
NA |
NA |
2 |
2 |
3 |
2 |
1 |
1 |
1 |
2 |
1 |
4 |
6 |
9 |
8 |
IFSC Youth European Cup Soure 2024 b |
Quali |
bernat MUNNÉ GUITART |
9 |
ESP |
NA |
NA |
2 |
1 |
1 |
NA |
1 |
1 |
2 |
1 |
1 |
3 |
3 |
6 |
4 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
mathis DUTEURTRE |
10 |
FRA |
1 |
NA |
2 |
1 |
NA |
NA |
1 |
3 |
2 |
1 |
1 |
2 |
3 |
6 |
4 |
10 |
IFSC Youth European Cup Soure 2024 b |
Quali |
adrien BREMOND POTEAU |
11 |
FRA |
1 |
NA |
NA |
2 |
2 |
NA |
1 |
1 |
2 |
2 |
2 |
2 |
3 |
6 |
5 |
10 |
IFSC Youth European Cup Soure 2024 b |
Quali |
célestin COPPIETERS |
12 |
BEL |
3 |
NA |
NA |
1 |
1 |
NA |
1 |
1 |
5 |
1 |
1 |
2 |
3 |
6 |
5 |
11 |
IFSC Youth European Cup Soure 2024 b |
Quali |
brecht D’HAESELEER |
13 |
BEL |
3 |
NA |
1 |
NA |
2 |
NA |
1 |
1 |
1 |
1 |
1 |
4 |
3 |
6 |
6 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
gabriele FISANOTTI |
14 |
ITA |
2 |
NA |
NA |
2 |
2 |
NA |
1 |
1 |
3 |
1 |
1 |
3 |
3 |
6 |
6 |
10 |
IFSC Youth European Cup Soure 2024 b |
Quali |
max JAKOB |
15 |
SUI |
4 |
NA |
1 |
1 |
NA |
NA |
1 |
8 |
1 |
1 |
5 |
1 |
3 |
6 |
6 |
17 |
IFSC Youth European Cup Soure 2024 b |
Quali |
olivier HUISMAN |
16 |
SUI |
NA |
NA |
3 |
2 |
2 |
NA |
1 |
2 |
1 |
1 |
1 |
1 |
3 |
6 |
7 |
7 |
IFSC Youth European Cup Soure 2024 b |
Quali |
aristide MADRY ALLEPAERTS |
17 |
FRA |
2 |
NA |
4 |
NA |
1 |
NA |
1 |
1 |
4 |
1 |
1 |
2 |
3 |
6 |
7 |
10 |
IFSC Youth European Cup Soure 2024 b |
Quali |
matej RAJŠEK |
17 |
SLO |
2 |
NA |
4 |
1 |
NA |
NA |
1 |
2 |
4 |
1 |
1 |
1 |
3 |
6 |
7 |
10 |
IFSC Youth European Cup Soure 2024 b |
Quali |
adrian KATHAN |
19 |
AUT |
NA |
3 |
3 |
NA |
2 |
NA |
1 |
1 |
2 |
1 |
1 |
1 |
3 |
6 |
8 |
7 |
IFSC Youth European Cup Soure 2024 b |
Quali |
makar IVANOV |
20 |
UKR |
3 |
NA |
NA |
2 |
1 |
NA |
3 |
1 |
2 |
2 |
1 |
NA |
3 |
5 |
6 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
mathias TYCHON |
21 |
BEL |
2 |
NA |
NA |
1 |
3 |
NA |
2 |
1 |
NA |
1 |
1 |
NA |
3 |
4 |
6 |
5 |
IFSC Youth European Cup Soure 2024 b |
Quali |
carlos FERREIRA GÓMEZ-VALADÉS |
22 |
ESP |
2 |
NA |
NA |
1 |
3 |
NA |
1 |
1 |
NA |
1 |
3 |
NA |
3 |
4 |
6 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
denis BECHEV |
23 |
BUL |
1 |
NA |
NA |
1 |
NA |
NA |
1 |
1 |
2 |
1 |
1 |
2 |
2 |
6 |
2 |
8 |
IFSC Youth European Cup Soure 2024 b |
Quali |
jaroslav AMBROZ |
24 |
CZE |
NA |
NA |
2 |
2 |
NA |
NA |
1 |
1 |
2 |
2 |
1 |
2 |
2 |
6 |
4 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
julian LEITNER |
25 |
AUT |
NA |
NA |
NA |
1 |
3 |
NA |
1 |
1 |
1 |
1 |
1 |
7 |
2 |
6 |
4 |
12 |
IFSC Youth European Cup Soure 2024 b |
Quali |
pietro FRANZONI |
26 |
ITA |
2 |
NA |
NA |
2 |
NA |
NA |
1 |
1 |
NA |
1 |
1 |
5 |
2 |
5 |
4 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
tijn EXALTO |
27 |
NED |
NA |
NA |
NA |
3 |
1 |
NA |
1 |
2 |
NA |
3 |
1 |
5 |
2 |
5 |
4 |
12 |
IFSC Youth European Cup Soure 2024 b |
Quali |
lovro TOMAŽIN |
28 |
SLO |
NA |
NA |
NA |
4 |
2 |
NA |
1 |
5 |
NA |
3 |
1 |
4 |
2 |
5 |
6 |
14 |
IFSC Youth European Cup Soure 2024 b |
Quali |
yagel BERGER |
29 |
ISR |
1 |
NA |
NA |
3 |
NA |
NA |
1 |
2 |
NA |
2 |
NA |
2 |
2 |
4 |
4 |
7 |
IFSC Youth European Cup Soure 2024 b |
Quali |
noé SHANKLAND |
30 |
FRA |
2 |
NA |
NA |
4 |
NA |
NA |
1 |
1 |
NA |
3 |
NA |
1 |
2 |
4 |
6 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
marlon RODZIS |
31 |
GER |
NA |
NA |
NA |
1 |
NA |
NA |
2 |
1 |
1 |
1 |
6 |
1 |
1 |
6 |
1 |
12 |
IFSC Youth European Cup Soure 2024 b |
Quali |
timotej CERMAK |
32 |
CZE |
3 |
NA |
NA |
NA |
NA |
NA |
1 |
1 |
NA |
1 |
2 |
7 |
1 |
5 |
3 |
12 |
IFSC Youth European Cup Soure 2024 b |
Quali |
adam PAAR |
33 |
CZE |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
2 |
NA |
1 |
NA |
NA |
1 |
3 |
1 |
4 |
IFSC Youth European Cup Soure 2024 b |
Quali |
laurin BECKER |
34 |
GER |
NA |
NA |
NA |
4 |
NA |
NA |
1 |
NA |
NA |
4 |
4 |
NA |
1 |
3 |
4 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
guilherme MATIAS |
35 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
3 |
1 |
1 |
3 |
2 |
0 |
6 |
0 |
11 |
IFSC Youth European Cup Soure 2024 b |
Quali |
lucijan PULJEK |
36 |
CRO |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
1 |
1 |
3 |
0 |
4 |
0 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
omri YADID |
36 |
ISR |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
1 |
2 |
2 |
0 |
4 |
0 |
6 |
IFSC Youth European Cup Soure 2024 b |
Quali |
tiago RIBEIRO |
38 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
5 |
3 |
NA |
3 |
4 |
NA |
0 |
4 |
0 |
15 |
IFSC Youth European Cup Soure 2024 b |
Quali |
aleksandar DRAZHEV |
39 |
BUL |
NA |
NA |
NA |
NA |
NA |
NA |
3 |
2 |
NA |
8 |
NA |
7 |
0 |
4 |
0 |
20 |
IFSC Youth European Cup Soure 2024 b |
Quali |
filip LEBLOCH |
40 |
CZE |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
2 |
NA |
1 |
NA |
NA |
0 |
3 |
0 |
4 |
IFSC Youth European Cup Soure 2024 b |
Quali |
finn WUESTENBERGS |
40 |
BEL |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
NA |
NA |
2 |
1 |
NA |
0 |
3 |
0 |
4 |
IFSC Youth European Cup Soure 2024 b |
Quali |
stefan KIRCHEV |
42 |
BUL |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
1 |
NA |
NA |
NA |
7 |
0 |
3 |
0 |
9 |
IFSC Youth European Cup Soure 2024 b |
Quali |
martim LOPES |
43 |
POR |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
2 |
NA |
0 |
2 |
0 |
3 |
IFSC Youth European Cup Soure 2024 b |
Quali |
viltautas POCIUS |
44 |
LTU |
NA |
NA |
NA |
NA |
NA |
NA |
2 |
NA |
NA |
NA |
5 |
NA |
0 |
2 |
0 |
7 |
IFSC Youth European Cup Soure 2024 b |
Quali |
oscar LENEHAN |
45 |
IRL |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
0 |
0 |
0 |
0 |
IFSC Youth European Cup Soure 2024 b |
Quali |
elyasaf LANEL |
1 |
ISR |
4 |
7 |
1 |
NA |
NA |
NA |
1 |
6 |
1 |
1 |
NA |
NA |
3 |
4 |
12 |
9 |
IFSC Youth European Cup Soure 2024 b |
Final |
or MARK |
2 |
ISR |
1 |
4 |
NA |
NA |
NA |
NA |
1 |
4 |
1 |
2 |
NA |
NA |
2 |
4 |
5 |
8 |
IFSC Youth European Cup Soure 2024 b |
Final |
itamar HAREL |
3 |
ISR |
3 |
3 |
NA |
NA |
NA |
NA |
1 |
2 |
1 |
1 |
NA |
NA |
2 |
4 |
6 |
5 |
IFSC Youth European Cup Soure 2024 b |
Final |
mattis EISENKOLB |
4 |
GER |
NA |
5 |
2 |
NA |
NA |
NA |
1 |
2 |
1 |
2 |
NA |
NA |
2 |
4 |
7 |
6 |
IFSC Youth European Cup Soure 2024 b |
Final |
bernat MUNNÉ GUITART |
5 |
ESP |
1 |
NA |
NA |
NA |
NA |
NA |
1 |
5 |
1 |
3 |
NA |
NA |
1 |
4 |
1 |
10 |
IFSC Youth European Cup Soure 2024 b |
Final |
eñaut USON POBES |
6 |
ESP |
NA |
NA |
2 |
NA |
NA |
NA |
4 |
NA |
1 |
2 |
NA |
NA |
1 |
3 |
2 |
7 |
IFSC Youth European Cup Soure 2024 b |
Final |
andrea ludovico CHELLERIS |
7 |
ITA |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
5 |
1 |
4 |
NA |
NA |
0 |
4 |
0 |
11 |
IFSC Youth European Cup Soure 2024 b |
Final |
moreno GHILARDI |
8 |
SUI |
NA |
NA |
NA |
NA |
NA |
NA |
8 |
6 |
5 |
2 |
NA |
NA |
0 |
4 |
0 |
21 |
IFSC Youth European Cup Soure 2024 b |
Final |
vincent VAN HAGE |
9 |
NED |
NA |
NA |
NA |
NA |
NA |
NA |
1 |
11 |
1 |
NA |
NA |
NA |
0 |
3 |
0 |
13 |
IFSC Youth European Cup Soure 2024 b |
Final |
mathis DUTEURTRE |
10 |
FRA |
NA |
NA |
NA |
NA |
NA |
NA |
NA |
5 |
1 |
NA |
NA |
NA |
0 |
2 |
0 |
6 |
IFSC Youth European Cup Soure 2024 b |
Final |
#
options(gargle_oauth_email = "villatoropazfj@dataanalysislab.com")
gs4_deauth()
gs4_auth()
sheet_write(data = Men_Boulder_Youth_Soure.24,
ss= "https://docs.google.com/spreadsheets/d/1bBLij1V2M1Qdsr6Yor7RF0RTgoZZpWesdLEmCYNTUes/edit?usp=sharing",
sheet=paste("Men_Boulder_Youth_Soure.24"))
LS0tDQp0aXRsZTogIklGU0NfWW91dGhfcmVzdWx0c18yMDI0Ig0KYXV0aG9yOiAiRmVkZXJpY28gSi4gVmlsbGF0b3JvIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHRydWUNCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCi0tLQ0KDQojIyMjIyBGdWVudGU6IFtodHRwczovL3d3dy5pZnNjLWNsaW1iaW5nLm9yZy9jYWxlbmRhci9pbmRleF0oaHR0cHM6Ly93d3cuaWZzYy1jbGltYmluZy5vcmcvY2FsZW5kYXIvaW5kZXgpDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPVRSVUV9DQpsaWJyYXJ5KGZsZXhkYXNoYm9hcmQpDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGVjaG8gPSBUUlVFLA0KCW1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KCWluY2x1ZGUgPSBUUlVFDQopDQpgYGAgIA0KDQpgYGB7ciBwYWNrYWdlcywgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KIyMNCnIgPSBnZXRPcHRpb24oInJlcG9zIikNCnJbIkNSQU4iXSA9ICJodHRwOi8vY3Jhbi51cy5yLXByb2plY3Qub3JnIg0Kb3B0aW9ucyhyZXBvcyA9IHIpDQojIyMNCmlmKCFyZXF1aXJlKHRpZHl2ZXJzZSkpe2luc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpfQ0KaWYoIXJlcXVpcmUoZ29vZ2xlc2hlZXRzNCkpe2luc3RhbGwucGFja2FnZXMoImdvb2dsZXNoZWV0czQiKX0NCmlmKCFyZXF1aXJlKGdvb2dsZWRyaXZlKSl7aW5zdGFsbC5wYWNrYWdlcygiZ29vZ2xlZHJpdmUiKX0NCmlmKCFyZXF1aXJlKGRwbHlyKSl7aW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKX0NCmlmKCFyZXF1aXJlKGh0dHIyKSl7aW5zdGFsbC5wYWNrYWdlcygiaHR0cjIiKX0NCmlmKCFyZXF1aXJlKGpzb25saXRlKSl7aW5zdGFsbC5wYWNrYWdlcygianNvbmxpdGUiKX0NCmlmKCFyZXF1aXJlKFJzZWxlbml1bSkpe2luc3RhbGwucGFja2FnZXMoIlJzZWxlbml1bSIpfQ0KaWYoIXJlcXVpcmUoY2hyb21vdGUpKXtpbnN0YWxsLnBhY2thZ2VzKCJjaHJvbW90ZSIpfQ0KaWYoIXJlcXVpcmUocHVycnIpKXtpbnN0YWxsLnBhY2thZ2VzKCJwdXJyciIpfQ0KaWYoIXJlcXVpcmUod2RtYW4pKXtpbnN0YWxsLnBhY2thZ2VzKCJ3ZG1hbiIpfQ0KaWYoIXJlcXVpcmUocGRmdG9vbHMpKXtpbnN0YWxsLnBhY2thZ2VzKCJwZGZ0b29scyIpfQ0KIyMNCmxpYnJhcnkocGRmdG9vbHMpDQpsaWJyYXJ5KGNocm9tb3RlKQ0KbGlicmFyeShwdXJycikNCmxpYnJhcnkod2RtYW4pDQoNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShydmVzdCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGpzb25saXRlKQ0KbGlicmFyeShSU2VsZW5pdW0pDQoNCmxpYnJhcnkoZ29vZ2xlc2hlZXRzNCkNCmxpYnJhcnkoZ29vZ2xlZHJpdmUpDQoNCmBgYCAgDQoNCiMjIE1lbl9Cb3VsZGVyX1NvdXJlX0p1bHkNCg0KYGBge3IgaW5jbHVkZT1UUlVFfQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgc2NyYXBpbmcgYWN0aXZlIHBhZ2UgdXNpbmcgY2hyb21vdGUgIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCiMgVVJMIG9mIHRoZSB3ZWJwYWdlIHRvIHNjcmFwZQ0KdXJsIDwtICJodHRwczovL3d3dy5pZnNjLWNsaW1iaW5nLm9yZy9ldmVudHMvaWZzYy15b3V0aC1ldXJvcGVhbi1jdXAtc291cmUtMjAyNC9yZXN1bHQvaW5kZXg/ZGlzY2lwbGluZT1ib3VsZGVyJmNhdGVnb3J5PWp1bmlvcnMrbWFsZSINCiMjIyMjIyMjIyMjIyAgIGNocm9tb3RlOjogT1BUSU9OICMjIyMjIw0KIyBDcmVhdGUgYSBuZXcgQ2hyb21vdGUgc2Vzc2lvbg0KYiA8LSBDaHJvbW90ZVNlc3Npb24kbmV3KCkNCiMgTmF2aWdhdGUgdG8gdGhlIHdlYnBhZ2UNCmIkUGFnZSRuYXZpZ2F0ZSh1cmwpDQpgYGAgIA0KDQojIyMgUXVhbGkNCmBgYHtyfQ0KaHRtbCA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoJ2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5hcHBlYXJlbmNlLW5vbmU6bnRoLWNoaWxkKDEpIikuY2xpY2soKTsnKSAgIyBSZXBsYWNlIHdpdGggeW91ciBDU1Mgc2VsZWN0b3INClN5cy5zbGVlcCgxMCkgDQoNCiMjIyBXQUlUIGZvciAiYmFja3N0YWdlIiBwYWdlIGxvYWRpbmcgIyMjIw0KaHRtbCA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoImRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vdXRlckhUTUwiKSRyZXN1bHQkdmFsdWUNCiMjIA0KcGFnZSA8LSByZWFkX2h0bWwoaHRtbCkNCiMjIw0Kc3RhZ2UgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCINCiAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignc2VsZWN0LmQzLXR5LXNlbGVjdCcpLnZhbHVlOw0KIikkcmVzdWx0JHZhbHVlDQpzdGFnZQ0KIyMjIA0KY29tcGUgPC0gcGFnZSAlPiUNCiAgaHRtbF9lbGVtZW50cygnaDIuZDMtdHktaGVhZGluZy0yJykgJT4lDQogIGh0bWxfdGV4dCgpDQojIyMNCmNvbXBldGl0b3JfZGl2cyA8LSBwYWdlICU+JSANCiAgaHRtbF9lbGVtZW50cygidHIucHgtNiIpICMgDQoNCiMgRXh0cmFjdCBhbmQgY2xlYW4gZGF0YQ0Kc2NyYXAgPC0gY29tcGV0aXRvcl9kaXZzICU+JQ0KICBtYXBfZGYofnsNCiAgICByYW5rIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyByYW5rDQogICAgbmFtZSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgbmFtZQ0KICAgIGNvdW50cnkgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMykiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIGNvdW50cnkgDQogICAgDQogICAgYjEuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCg0KSBzcGFuOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjIuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgyKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIzLlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMykgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNC5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDQpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjUuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg1KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI2LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICANCiAgICBiMS5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDQpIHNwYW46bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMi5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDIpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjMuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgzKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI0LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNCkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNS5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDUpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjYuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg2KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIA0KICAgIHNjb3JlIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInNwYW4udGV4dC1ibGFjayIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgIyBSZXR1cm4gYXMgYSB0aWJibGUNCiAgICB0aWJibGUoTmFtZSA9IG5hbWUsIA0KICAgICAgICAgICBSYW5rID0gcmFuaywNCiAgICAgICAgICAgQ291bnRyeSA9IGNvdW50cnksDQogICAgICAgICAgIEIxLlQgPSBiMS5ULA0KICAgICAgICAgICBCMi5UID0gYjIuVCwNCiAgICAgICAgICAgQjMuVCA9IGIzLlQsDQogICAgICAgICAgIEI0LlQgPSBiNC5ULA0KICAgICAgICAgICBCNS5UID0gYjUuVCwNCiAgICAgICAgICAgQjYuVCA9IGI2LlQsDQogICAgICAgICAgIEIxLlogPSBiMS5aLA0KICAgICAgICAgICBCMi5aID0gYjIuWiwNCiAgICAgICAgICAgQjMuWiA9IGIzLlosDQogICAgICAgICAgIEI0LlogPSBiNC5aLA0KICAgICAgICAgICBCNS5aID0gYjUuWiwNCiAgICAgICAgICAgQjYuWiA9IGI2LlosDQogICAgICAgICAgIFNjb3JlID0gc2NvcmUpDQogIH0pDQojIyMNCnNjcmFwIDwtIHNjcmFwICU+JQ0KICBzZXBhcmF0ZShTY29yZSwgaW50byA9IGMoIlRzLlpzIiwiYXR0ZW1wdHMudCIsICJhdHRlbXB0cy56IiksIHNlcCA9ICIgIikgJT4lIHNlcGFyYXRlKFRzLlpzLCBpbnRvID0gYygiVG9wcyIsIlpvbmVzIiksIHNlcD0iVCIpICU+JSBzZXBhcmF0ZShab25lcywgaW50byA9IGMoIlpvbmVzIixOQSksIHNlcD0ieiIpDQojDQpzY3JhcCA8LSBzY3JhcCAlPiUgDQogIG11dGF0ZV9hdChjKDIsNDoxNyksIGFzLm51bWVyaWMpICU+JQ0KICBtdXRhdGUoQ29tcGV0aXRpb24gPSByZXAoY29tcGUsIGxlbmd0aChzY3JhcCROYW1lKSApLA0KICAgICAgICAgU3RhZ2UgPSByZXAoIlF1YWxpIiwgbGVuZ3RoKHNjcmFwJE5hbWUgKSApICkNCiMjDQpjb21wZQ0Kbi5jb21wZXRpdG9ycyA8LSBtYXgoc2NyYXAkUmFuaywgbmEucm0gPSBUUlVFKTsgbi5jb21wZXRpdG9ycw0KIyMjIyMjIyMjIyMjIyMjICMjIyMjIyMjIyMjIyMjIyMjIw0KTWVuX3lvdXRoX1NvdXJlX1F1YWxpIDwtIHNjcmFwDQpgYGAgIA0KDQoNCiMjIyBGaW5hbHMNCg0KYGBge3J9DQpiIDwtIENocm9tb3RlU2Vzc2lvbiRuZXcoKQ0KIyBOYXZpZ2F0ZSB0byB0aGUgd2VicGFnZQ0KYiRQYWdlJG5hdmlnYXRlKHVybCkNCiMNCmh0bWwgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCdkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIuYXBwZWFyZW5jZS1ub25lOm50aC1jaGlsZCgxKSIpLmNsaWNrKCk7JykNCiMNClN5cy5zbGVlcCgxMCkgDQojIyMNCmIkUnVudGltZSRldmFsdWF0ZSgiDQogIGxldCBkcm9wZG93biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKTsgLy8gRmluZCB0aGUgZHJvcGRvd24gYnkgY2xhc3MNCiAgaWYgKGRyb3Bkb3duKSB7DQogICAgZHJvcGRvd24udmFsdWUgPSAnRmluYWwnOyAgLy8gU2V0IHRoZSB2YWx1ZSB0byAnRmluYWwnDQogICAgZHJvcGRvd24uZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2NoYW5nZScsIHsgYnViYmxlczogdHJ1ZSB9KSk7IC8vIFRyaWdnZXIgdXBkYXRlDQogIH0NCiIpDQojIyMNCnN0YWdlIDwtIGIkUnVudGltZSRldmFsdWF0ZSgiDQogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKS52YWx1ZTsNCiIpJHJlc3VsdCR2YWx1ZQ0Kc3RhZ2UNCiMjIw0KU3lzLnNsZWVwKDEwKSANCiMNCiMjIyBXQUlUIGZvciAiYmFja3N0YWdlIiBwYWdlIGxvYWRpbmcgIyMjIw0KaHRtbCA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoImRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vdXRlckhUTUwiKSRyZXN1bHQkdmFsdWUNCiMjIA0KcGFnZSA8LSByZWFkX2h0bWwoaHRtbCkNCiMjIyANCmNvbXBlIDwtIHBhZ2UgJT4lDQogIGh0bWxfZWxlbWVudHMoJ2gyLmQzLXR5LWhlYWRpbmctMicpICU+JQ0KICBodG1sX3RleHQoKQ0KIyMjDQpjb21wZXRpdG9yX2RpdnMgPC0gcGFnZSAlPiUgDQogIGh0bWxfZWxlbWVudHMoInRyLnB4LTYiKSAjIA0KIyBFeHRyYWN0IGFuZCBjbGVhbiBkYXRhDQpzY3JhcCA8LSBjb21wZXRpdG9yX2RpdnMgJT4lDQogIG1hcF9kZih+ew0KICAgIHJhbmsgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIHJhbmsNCiAgICBuYW1lIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyBuYW1lDQogICAgY291bnRyeSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgzKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgY291bnRyeSANCiAgICANCiAgICBiMS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDQpIHNwYW46bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMi5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDIpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjMuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgzKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI0LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNCkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDUpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjYuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg2KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIA0KICAgIGIxLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoNCkgc3BhbjpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIyLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMy5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDMpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjQuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg0KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI1LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNSkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNi5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDYpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgDQogICAgc2NvcmUgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgic3Bhbi50ZXh0LWJsYWNrIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICAjIFJldHVybiBhcyBhIHRpYmJsZQ0KICAgIHRpYmJsZShOYW1lID0gbmFtZSwgDQogICAgICAgICAgIFJhbmsgPSByYW5rLA0KICAgICAgICAgICBDb3VudHJ5ID0gY291bnRyeSwNCiAgICAgICAgICAgQjEuVCA9IGIxLlQsDQogICAgICAgICAgIEIyLlQgPSBiMi5ULA0KICAgICAgICAgICBCMy5UID0gYjMuVCwNCiAgICAgICAgICAgQjQuVCA9IGI0LlQsDQogICAgICAgICAgIEI1LlQgPSBiNS5ULA0KICAgICAgICAgICBCNi5UID0gYjYuVCwNCiAgICAgICAgICAgQjEuWiA9IGIxLlosDQogICAgICAgICAgIEIyLlogPSBiMi5aLA0KICAgICAgICAgICBCMy5aID0gYjMuWiwNCiAgICAgICAgICAgQjQuWiA9IGI0LlosDQogICAgICAgICAgIEI1LlogPSBiNS5aLA0KICAgICAgICAgICBCNi5aID0gYjYuWiwNCiAgICAgICAgICAgU2NvcmUgPSBzY29yZSkNCiAgfSkNCiMjIw0Kc2NyYXAgPC0gc2NyYXAgJT4lDQogIHNlcGFyYXRlKFNjb3JlLCBpbnRvID0gYygiVHMuWnMiLCJhdHRlbXB0cy50IiwgImF0dGVtcHRzLnoiKSwgc2VwID0gIiAiKSAlPiUgc2VwYXJhdGUoVHMuWnMsIGludG8gPSBjKCJUb3BzIiwiWm9uZXMiKSwgc2VwPSJUIikgJT4lIHNlcGFyYXRlKFpvbmVzLCBpbnRvID0gYygiWm9uZXMiLE5BKSwgc2VwPSJ6IikNCiMNCnNjcmFwIDwtIHNjcmFwICU+JSANCiAgbXV0YXRlX2F0KGMoMiw0OjE3KSwgYXMubnVtZXJpYykgJT4lDQogIG11dGF0ZShDb21wZXRpdGlvbiA9IHJlcChjb21wZSwgbGVuZ3RoKHNjcmFwJE5hbWUpICksDQogICAgICAgICBTdGFnZSA9IHJlcChzdGFnZSwgbGVuZ3RoKHNjcmFwJE5hbWUgKSApICkNCiMjDQpjb21wZQ0Kbi5jb21wZXRpdG9ycyA8LSBtYXgoc2NyYXAkUmFuaywgbmEucm0gPSBUUlVFKTsgbi5jb21wZXRpdG9ycw0KIyMjIyMjIyMjIyMjIyMjICMjIyMjIyMjIyMjIyMjIyMjIw0KTWVuX3lvdXRoX1NvdXJlX0ZpbmFscyA8LSBzY3JhcA0KYGBgICANCg0KIyMgTWVuX3lvdXRoX2FfQm91bGRlcl9Tb3VyZV9KdWx5DQoNCmBgYHtyIGluY2x1ZGU9VFJVRX0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIHNjcmFwaW5nIGFjdGl2ZSBwYWdlIHVzaW5nIGNocm9tb3RlICMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIFVSTCBvZiB0aGUgd2VicGFnZSB0byBzY3JhcGUNCnVybCA8LSAiaHR0cHM6Ly93d3cuaWZzYy1jbGltYmluZy5vcmcvZXZlbnRzL2lmc2MteW91dGgtZXVyb3BlYW4tY3VwLXNvdXJlLTIwMjQvcmVzdWx0L2luZGV4P2Rpc2NpcGxpbmU9Ym91bGRlciZjYXRlZ29yeT15b3V0aCthK21hbGUiDQojIyMjIyMjIyMjIyMgICBjaHJvbW90ZTo6IE9QVElPTiAjIyMjIyMNCiMgQ3JlYXRlIGEgbmV3IENocm9tb3RlIHNlc3Npb24NCmIgPC0gQ2hyb21vdGVTZXNzaW9uJG5ldygpDQojIE5hdmlnYXRlIHRvIHRoZSB3ZWJwYWdlDQpiJFBhZ2UkbmF2aWdhdGUodXJsKQ0KYGBgICANCg0KIyMjIFF1YWxpDQpgYGB7cn0NCmh0bWwgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCdkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIuYXBwZWFyZW5jZS1ub25lOm50aC1jaGlsZCgxKSIpLmNsaWNrKCk7JykgICMgUmVwbGFjZSB3aXRoIHlvdXIgQ1NTIHNlbGVjdG9yDQpTeXMuc2xlZXAoMTApIA0KDQojIyMgV0FJVCBmb3IgImJhY2tzdGFnZSIgcGFnZSBsb2FkaW5nICMjIyMNCmh0bWwgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCJkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQub3V0ZXJIVE1MIikkcmVzdWx0JHZhbHVlDQojIyANCnBhZ2UgPC0gcmVhZF9odG1sKGh0bWwpDQojIyMNCnN0YWdlIDwtIGIkUnVudGltZSRldmFsdWF0ZSgiDQogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKS52YWx1ZTsNCiIpJHJlc3VsdCR2YWx1ZQ0Kc3RhZ2UNCiMjIyANCmNvbXBlIDwtIHBhZ2UgJT4lDQogIGh0bWxfZWxlbWVudHMoJ2gyLmQzLXR5LWhlYWRpbmctMicpICU+JQ0KICBodG1sX3RleHQoKQ0KIyMjDQpjb21wZXRpdG9yX2RpdnMgPC0gcGFnZSAlPiUgDQogIGh0bWxfZWxlbWVudHMoInRyLnB4LTYiKSAjIA0KDQojIEV4dHJhY3QgYW5kIGNsZWFuIGRhdGENCnNjcmFwIDwtIGNvbXBldGl0b3JfZGl2cyAlPiUNCiAgbWFwX2RmKH57DQogICAgcmFuayA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgcmFuaw0KICAgIG5hbWUgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIG5hbWUNCiAgICBjb3VudHJ5IDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDMpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyBjb3VudHJ5IA0KICAgIA0KICAgIGIxLlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoNCkgc3BhbjpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIyLlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMy5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDMpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjQuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg0KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI1LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNSkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNi5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDYpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgDQogICAgYjEuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCg0KSBzcGFuOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjIuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgyKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIzLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMykgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNC5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDQpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjUuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg1KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI2LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICANCiAgICBzY29yZSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJzcGFuLnRleHQtYmxhY2siKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgICMgUmV0dXJuIGFzIGEgdGliYmxlDQogICAgdGliYmxlKE5hbWUgPSBuYW1lLCANCiAgICAgICAgICAgUmFuayA9IHJhbmssDQogICAgICAgICAgIENvdW50cnkgPSBjb3VudHJ5LA0KICAgICAgICAgICBCMS5UID0gYjEuVCwNCiAgICAgICAgICAgQjIuVCA9IGIyLlQsDQogICAgICAgICAgIEIzLlQgPSBiMy5ULA0KICAgICAgICAgICBCNC5UID0gYjQuVCwNCiAgICAgICAgICAgQjUuVCA9IGI1LlQsDQogICAgICAgICAgIEI2LlQgPSBiNi5ULA0KICAgICAgICAgICBCMS5aID0gYjEuWiwNCiAgICAgICAgICAgQjIuWiA9IGIyLlosDQogICAgICAgICAgIEIzLlogPSBiMy5aLA0KICAgICAgICAgICBCNC5aID0gYjQuWiwNCiAgICAgICAgICAgQjUuWiA9IGI1LlosDQogICAgICAgICAgIEI2LlogPSBiNi5aLA0KICAgICAgICAgICBTY29yZSA9IHNjb3JlKQ0KICB9KQ0KIyMjDQpzY3JhcCA8LSBzY3JhcCAlPiUNCiAgc2VwYXJhdGUoU2NvcmUsIGludG8gPSBjKCJUcy5acyIsImF0dGVtcHRzLnQiLCAiYXR0ZW1wdHMueiIpLCBzZXAgPSAiICIpICU+JSBzZXBhcmF0ZShUcy5acywgaW50byA9IGMoIlRvcHMiLCJab25lcyIpLCBzZXA9IlQiKSAlPiUgc2VwYXJhdGUoWm9uZXMsIGludG8gPSBjKCJab25lcyIsTkEpLCBzZXA9InoiKQ0KIw0Kc2NyYXAgPC0gc2NyYXAgJT4lIA0KICBtdXRhdGVfYXQoYygyLDQ6MTcpLCBhcy5udW1lcmljKSAlPiUNCiAgbXV0YXRlKENvbXBldGl0aW9uID0gcmVwKHBhc3RlKGNvbXBlLCAiYSIpLCBsZW5ndGgoc2NyYXAkTmFtZSkgKSwNCiAgICAgICAgIFN0YWdlID0gcmVwKCJRdWFsaSIsIGxlbmd0aChzY3JhcCROYW1lICkgKSApDQojIw0KY29tcGUNCm4uY29tcGV0aXRvcnMgPC0gbWF4KHNjcmFwJFJhbmssIG5hLnJtID0gVFJVRSk7IG4uY29tcGV0aXRvcnMNCiMjIyMjIyMjIyMjIyMjIyAjIyMjIyMjIyMjIyMjIyMjIyMNCk1lbl95b3V0aF9hX1NvdXJlX1F1YWxpIDwtIHNjcmFwDQpgYGAgIA0KDQoNCiMjIyBGaW5hbHMNCg0KYGBge3J9DQpiIDwtIENocm9tb3RlU2Vzc2lvbiRuZXcoKQ0KIyBOYXZpZ2F0ZSB0byB0aGUgd2VicGFnZQ0KYiRQYWdlJG5hdmlnYXRlKHVybCkNCiMNCmh0bWwgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCdkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIuYXBwZWFyZW5jZS1ub25lOm50aC1jaGlsZCgxKSIpLmNsaWNrKCk7JykNCiMNClN5cy5zbGVlcCgxMCkgDQojIyMNCmIkUnVudGltZSRldmFsdWF0ZSgiDQogIGxldCBkcm9wZG93biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKTsgLy8gRmluZCB0aGUgZHJvcGRvd24gYnkgY2xhc3MNCiAgaWYgKGRyb3Bkb3duKSB7DQogICAgZHJvcGRvd24udmFsdWUgPSAnRmluYWwnOyAgLy8gU2V0IHRoZSB2YWx1ZSB0byAnRmluYWwnDQogICAgZHJvcGRvd24uZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2NoYW5nZScsIHsgYnViYmxlczogdHJ1ZSB9KSk7IC8vIFRyaWdnZXIgdXBkYXRlDQogIH0NCiIpDQojIyMNCnN0YWdlIDwtIGIkUnVudGltZSRldmFsdWF0ZSgiDQogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKS52YWx1ZTsNCiIpJHJlc3VsdCR2YWx1ZQ0Kc3RhZ2UNCiMjIw0KU3lzLnNsZWVwKDEwKSANCiMNCiMjIyBXQUlUIGZvciAiYmFja3N0YWdlIiBwYWdlIGxvYWRpbmcgIyMjIw0KaHRtbCA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoImRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vdXRlckhUTUwiKSRyZXN1bHQkdmFsdWUNCiMjIA0KcGFnZSA8LSByZWFkX2h0bWwoaHRtbCkNCiMjIyANCmNvbXBlIDwtIHBhZ2UgJT4lDQogIGh0bWxfZWxlbWVudHMoJ2gyLmQzLXR5LWhlYWRpbmctMicpICU+JQ0KICBodG1sX3RleHQoKQ0KIyMjDQpjb21wZXRpdG9yX2RpdnMgPC0gcGFnZSAlPiUgDQogIGh0bWxfZWxlbWVudHMoInRyLnB4LTYiKSAjIA0KIyBFeHRyYWN0IGFuZCBjbGVhbiBkYXRhDQpzY3JhcCA8LSBjb21wZXRpdG9yX2RpdnMgJT4lDQogIG1hcF9kZih+ew0KICAgIHJhbmsgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIHJhbmsNCiAgICBuYW1lIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyBuYW1lDQogICAgY291bnRyeSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgzKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgY291bnRyeSANCiAgICANCiAgICBiMS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDQpIHNwYW46bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMi5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDIpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjMuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgzKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI0LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNCkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDUpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjYuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg2KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIA0KICAgIGIxLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoNCkgc3BhbjpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIyLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMy5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDMpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjQuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg0KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI1LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNSkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNi5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDYpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgDQogICAgc2NvcmUgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgic3Bhbi50ZXh0LWJsYWNrIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICAjIFJldHVybiBhcyBhIHRpYmJsZQ0KICAgIHRpYmJsZShOYW1lID0gbmFtZSwgDQogICAgICAgICAgIFJhbmsgPSByYW5rLA0KICAgICAgICAgICBDb3VudHJ5ID0gY291bnRyeSwNCiAgICAgICAgICAgQjEuVCA9IGIxLlQsDQogICAgICAgICAgIEIyLlQgPSBiMi5ULA0KICAgICAgICAgICBCMy5UID0gYjMuVCwNCiAgICAgICAgICAgQjQuVCA9IGI0LlQsDQogICAgICAgICAgIEI1LlQgPSBiNS5ULA0KICAgICAgICAgICBCNi5UID0gYjYuVCwNCiAgICAgICAgICAgQjEuWiA9IGIxLlosDQogICAgICAgICAgIEIyLlogPSBiMi5aLA0KICAgICAgICAgICBCMy5aID0gYjMuWiwNCiAgICAgICAgICAgQjQuWiA9IGI0LlosDQogICAgICAgICAgIEI1LlogPSBiNS5aLA0KICAgICAgICAgICBCNi5aID0gYjYuWiwNCiAgICAgICAgICAgU2NvcmUgPSBzY29yZSkNCiAgfSkNCiMjIw0Kc2NyYXAgPC0gc2NyYXAgJT4lDQogIHNlcGFyYXRlKFNjb3JlLCBpbnRvID0gYygiVHMuWnMiLCJhdHRlbXB0cy50IiwgImF0dGVtcHRzLnoiKSwgc2VwID0gIiAiKSAlPiUgc2VwYXJhdGUoVHMuWnMsIGludG8gPSBjKCJUb3BzIiwiWm9uZXMiKSwgc2VwPSJUIikgJT4lIHNlcGFyYXRlKFpvbmVzLCBpbnRvID0gYygiWm9uZXMiLE5BKSwgc2VwPSJ6IikNCiMNCnNjcmFwIDwtIHNjcmFwICU+JSANCiAgbXV0YXRlX2F0KGMoMiw0OjE3KSwgYXMubnVtZXJpYykgJT4lDQogIG11dGF0ZShDb21wZXRpdGlvbiA9IHJlcChwYXN0ZShjb21wZSwiYSIpLCBsZW5ndGgoc2NyYXAkTmFtZSkgKSwNCiAgICAgICAgIFN0YWdlID0gcmVwKHN0YWdlLCBsZW5ndGgoc2NyYXAkTmFtZSApICkgKQ0KIyMNCmNvbXBlDQpuLmNvbXBldGl0b3JzIDwtIG1heChzY3JhcCRSYW5rLCBuYS5ybSA9IFRSVUUpOyBuLmNvbXBldGl0b3JzDQojIyMjIyMjIyMjIyMjIyMgIyMjIyMjIyMjIyMjIyMjIyMjDQpNZW5feW91dGhfYV9Tb3VyZV9GaW5hbHMgPC0gc2NyYXANCmBgYCAgDQoNCiMjIE1lbl95b3V0aF9iX0JvdWxkZXJfU291cmVfSnVseQ0KDQpgYGB7ciBpbmNsdWRlPVRSVUV9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyBzY3JhcGluZyBhY3RpdmUgcGFnZSB1c2luZyBjaHJvbW90ZSAjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyBVUkwgb2YgdGhlIHdlYnBhZ2UgdG8gc2NyYXBlDQp1cmwgPC0gImh0dHBzOi8vd3d3Lmlmc2MtY2xpbWJpbmcub3JnL2V2ZW50cy9pZnNjLXlvdXRoLWV1cm9wZWFuLWN1cC1zb3VyZS0yMDI0L3Jlc3VsdC9pbmRleD9kaXNjaXBsaW5lPWJvdWxkZXImY2F0ZWdvcnk9eW91dGgrYittYWxlIg0KIyMjIyMjIyMjIyMjICAgY2hyb21vdGU6OiBPUFRJT04gIyMjIyMjDQojIENyZWF0ZSBhIG5ldyBDaHJvbW90ZSBzZXNzaW9uDQpiIDwtIENocm9tb3RlU2Vzc2lvbiRuZXcoKQ0KIyBOYXZpZ2F0ZSB0byB0aGUgd2VicGFnZQ0KYiRQYWdlJG5hdmlnYXRlKHVybCkNCmBgYCAgDQoNCiMjIyBRdWFsaQ0KYGBge3J9DQpodG1sIDwtIGIkUnVudGltZSRldmFsdWF0ZSgnZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmFwcGVhcmVuY2Utbm9uZTpudGgtY2hpbGQoMSkiKS5jbGljaygpOycpICAjIFJlcGxhY2Ugd2l0aCB5b3VyIENTUyBzZWxlY3Rvcg0KU3lzLnNsZWVwKDEwKSANCg0KIyMjIFdBSVQgZm9yICJiYWNrc3RhZ2UiIHBhZ2UgbG9hZGluZyAjIyMjDQpodG1sIDwtIGIkUnVudGltZSRldmFsdWF0ZSgiZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50Lm91dGVySFRNTCIpJHJlc3VsdCR2YWx1ZQ0KIyMgDQpwYWdlIDwtIHJlYWRfaHRtbChodG1sKQ0KIyMjDQpzdGFnZSA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoIg0KICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzZWxlY3QuZDMtdHktc2VsZWN0JykudmFsdWU7DQoiKSRyZXN1bHQkdmFsdWUNCnN0YWdlDQojIyMgDQpjb21wZSA8LSBwYWdlICU+JQ0KICBodG1sX2VsZW1lbnRzKCdoMi5kMy10eS1oZWFkaW5nLTInKSAlPiUNCiAgaHRtbF90ZXh0KCkNCiMjIw0KY29tcGV0aXRvcl9kaXZzIDwtIHBhZ2UgJT4lIA0KICBodG1sX2VsZW1lbnRzKCJ0ci5weC02IikgIyANCg0KIyBFeHRyYWN0IGFuZCBjbGVhbiBkYXRhDQpzY3JhcCA8LSBjb21wZXRpdG9yX2RpdnMgJT4lDQogIG1hcF9kZih+ew0KICAgIHJhbmsgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIHJhbmsNCiAgICBuYW1lIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyBuYW1lDQogICAgY291bnRyeSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgzKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgY291bnRyeSANCiAgICANCiAgICBiMS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDQpIHNwYW46bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMi5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDIpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjMuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgzKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI0LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNCkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDUpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjYuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg2KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIA0KICAgIGIxLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoNCkgc3BhbjpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIyLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMy5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDMpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjQuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg0KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI1LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNSkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNi5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDYpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgDQogICAgc2NvcmUgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgic3Bhbi50ZXh0LWJsYWNrIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICAjIFJldHVybiBhcyBhIHRpYmJsZQ0KICAgIHRpYmJsZShOYW1lID0gbmFtZSwgDQogICAgICAgICAgIFJhbmsgPSByYW5rLA0KICAgICAgICAgICBDb3VudHJ5ID0gY291bnRyeSwNCiAgICAgICAgICAgQjEuVCA9IGIxLlQsDQogICAgICAgICAgIEIyLlQgPSBiMi5ULA0KICAgICAgICAgICBCMy5UID0gYjMuVCwNCiAgICAgICAgICAgQjQuVCA9IGI0LlQsDQogICAgICAgICAgIEI1LlQgPSBiNS5ULA0KICAgICAgICAgICBCNi5UID0gYjYuVCwNCiAgICAgICAgICAgQjEuWiA9IGIxLlosDQogICAgICAgICAgIEIyLlogPSBiMi5aLA0KICAgICAgICAgICBCMy5aID0gYjMuWiwNCiAgICAgICAgICAgQjQuWiA9IGI0LlosDQogICAgICAgICAgIEI1LlogPSBiNS5aLA0KICAgICAgICAgICBCNi5aID0gYjYuWiwNCiAgICAgICAgICAgU2NvcmUgPSBzY29yZSkNCiAgfSkNCiMjIw0Kc2NyYXAgPC0gc2NyYXAgJT4lDQogIHNlcGFyYXRlKFNjb3JlLCBpbnRvID0gYygiVHMuWnMiLCJhdHRlbXB0cy50IiwgImF0dGVtcHRzLnoiKSwgc2VwID0gIiAiKSAlPiUgc2VwYXJhdGUoVHMuWnMsIGludG8gPSBjKCJUb3BzIiwiWm9uZXMiKSwgc2VwPSJUIikgJT4lIHNlcGFyYXRlKFpvbmVzLCBpbnRvID0gYygiWm9uZXMiLE5BKSwgc2VwPSJ6IikNCiMNCnNjcmFwIDwtIHNjcmFwICU+JSANCiAgbXV0YXRlX2F0KGMoMiw0OjE3KSwgYXMubnVtZXJpYykgJT4lDQogIG11dGF0ZShDb21wZXRpdGlvbiA9IHJlcChwYXN0ZShjb21wZSwiYiIpLCBsZW5ndGgoc2NyYXAkTmFtZSkgKSwNCiAgICAgICAgIFN0YWdlID0gcmVwKCJRdWFsaSIsIGxlbmd0aChzY3JhcCROYW1lICkgKSApDQojIw0KY29tcGUNCm4uY29tcGV0aXRvcnMgPC0gbWF4KHNjcmFwJFJhbmssIG5hLnJtID0gVFJVRSk7IG4uY29tcGV0aXRvcnMNCiMjIyMjIyMjIyMjIyMjIyAjIyMjIyMjIyMjIyMjIyMjIyMNCk1lbl95b3V0aF9iX1NvdXJlX1F1YWxpIDwtIHNjcmFwDQpgYGAgIA0KDQoNCiMjIyBGaW5hbHMNCg0KYGBge3J9DQpiIDwtIENocm9tb3RlU2Vzc2lvbiRuZXcoKQ0KIyBOYXZpZ2F0ZSB0byB0aGUgd2VicGFnZQ0KYiRQYWdlJG5hdmlnYXRlKHVybCkNCiMNCmh0bWwgPC0gYiRSdW50aW1lJGV2YWx1YXRlKCdkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIuYXBwZWFyZW5jZS1ub25lOm50aC1jaGlsZCgxKSIpLmNsaWNrKCk7JykNCiMNClN5cy5zbGVlcCgxMCkgDQojIyMNCmIkUnVudGltZSRldmFsdWF0ZSgiDQogIGxldCBkcm9wZG93biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKTsgLy8gRmluZCB0aGUgZHJvcGRvd24gYnkgY2xhc3MNCiAgaWYgKGRyb3Bkb3duKSB7DQogICAgZHJvcGRvd24udmFsdWUgPSAnRmluYWwnOyAgLy8gU2V0IHRoZSB2YWx1ZSB0byAnRmluYWwnDQogICAgZHJvcGRvd24uZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2NoYW5nZScsIHsgYnViYmxlczogdHJ1ZSB9KSk7IC8vIFRyaWdnZXIgdXBkYXRlDQogIH0NCiIpDQojIyMNCnN0YWdlIDwtIGIkUnVudGltZSRldmFsdWF0ZSgiDQogIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdC5kMy10eS1zZWxlY3QnKS52YWx1ZTsNCiIpJHJlc3VsdCR2YWx1ZQ0Kc3RhZ2UNCiMjIw0KU3lzLnNsZWVwKDEwKSANCiMNCiMjIyBXQUlUIGZvciAiYmFja3N0YWdlIiBwYWdlIGxvYWRpbmcgIyMjIw0KaHRtbCA8LSBiJFJ1bnRpbWUkZXZhbHVhdGUoImRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vdXRlckhUTUwiKSRyZXN1bHQkdmFsdWUNCiMjIA0KcGFnZSA8LSByZWFkX2h0bWwoaHRtbCkNCiMjIyANCmNvbXBlIDwtIHBhZ2UgJT4lDQogIGh0bWxfZWxlbWVudHMoJ2gyLmQzLXR5LWhlYWRpbmctMicpICU+JQ0KICBodG1sX3RleHQoKQ0KIyMjDQpjb21wZXRpdG9yX2RpdnMgPC0gcGFnZSAlPiUgDQogIGh0bWxfZWxlbWVudHMoInRyLnB4LTYiKSAjIA0KIyBFeHRyYWN0IGFuZCBjbGVhbiBkYXRhDQpzY3JhcCA8LSBjb21wZXRpdG9yX2RpdnMgJT4lDQogIG1hcF9kZih+ew0KICAgIHJhbmsgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKSAjIHJhbmsNCiAgICBuYW1lIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkgIyBuYW1lDQogICAgY291bnRyeSA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCJ0ZC5weS0yOm50aC1jaGlsZCgzKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpICMgY291bnRyeSANCiAgICANCiAgICBiMS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoInRkLnB5LTI6bnRoLWNoaWxkKDQpIHNwYW46bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMi5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDIpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjMuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCgzKSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI0LlQgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNCkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDEpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNS5UIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDUpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgxKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjYuVCA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg2KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMSkiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIA0KICAgIGIxLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgidGQucHktMjpudGgtY2hpbGQoNCkgc3BhbjpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGIyLlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoMikgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiMy5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDMpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgYjQuWiA8LSAueCAlPiUgaHRtbF9lbGVtZW50KCIuZDMtdHktYXNjZW50Om50aC1jaGlsZCg0KSAuYmctYmx1ZS1hYTpudGgtY2hpbGQoMikiKSAlPiUgaHRtbF90ZXh0KHRyaW0gPSBUUlVFKSAlPiUgdGFpbCgxKQ0KICAgIGI1LlogPC0gLnggJT4lIGh0bWxfZWxlbWVudCgiLmQzLXR5LWFzY2VudDpudGgtY2hpbGQoNSkgLmJnLWJsdWUtYWE6bnRoLWNoaWxkKDIpIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICBiNi5aIDwtIC54ICU+JSBodG1sX2VsZW1lbnQoIi5kMy10eS1hc2NlbnQ6bnRoLWNoaWxkKDYpIC5iZy1ibHVlLWFhOm50aC1jaGlsZCgyKSIpICU+JSBodG1sX3RleHQodHJpbSA9IFRSVUUpICU+JSB0YWlsKDEpDQogICAgDQogICAgc2NvcmUgPC0gLnggJT4lIGh0bWxfZWxlbWVudCgic3Bhbi50ZXh0LWJsYWNrIikgJT4lIGh0bWxfdGV4dCh0cmltID0gVFJVRSkgJT4lIHRhaWwoMSkNCiAgICAjIFJldHVybiBhcyBhIHRpYmJsZQ0KICAgIHRpYmJsZShOYW1lID0gbmFtZSwgDQogICAgICAgICAgIFJhbmsgPSByYW5rLA0KICAgICAgICAgICBDb3VudHJ5ID0gY291bnRyeSwNCiAgICAgICAgICAgQjEuVCA9IGIxLlQsDQogICAgICAgICAgIEIyLlQgPSBiMi5ULA0KICAgICAgICAgICBCMy5UID0gYjMuVCwNCiAgICAgICAgICAgQjQuVCA9IGI0LlQsDQogICAgICAgICAgIEI1LlQgPSBiNS5ULA0KICAgICAgICAgICBCNi5UID0gYjYuVCwNCiAgICAgICAgICAgQjEuWiA9IGIxLlosDQogICAgICAgICAgIEIyLlogPSBiMi5aLA0KICAgICAgICAgICBCMy5aID0gYjMuWiwNCiAgICAgICAgICAgQjQuWiA9IGI0LlosDQogICAgICAgICAgIEI1LlogPSBiNS5aLA0KICAgICAgICAgICBCNi5aID0gYjYuWiwNCiAgICAgICAgICAgU2NvcmUgPSBzY29yZSkNCiAgfSkNCiMjIw0Kc2NyYXAgPC0gc2NyYXAgJT4lDQogIHNlcGFyYXRlKFNjb3JlLCBpbnRvID0gYygiVHMuWnMiLCJhdHRlbXB0cy50IiwgImF0dGVtcHRzLnoiKSwgc2VwID0gIiAiKSAlPiUgc2VwYXJhdGUoVHMuWnMsIGludG8gPSBjKCJUb3BzIiwiWm9uZXMiKSwgc2VwPSJUIikgJT4lIHNlcGFyYXRlKFpvbmVzLCBpbnRvID0gYygiWm9uZXMiLE5BKSwgc2VwPSJ6IikNCiMNCnNjcmFwIDwtIHNjcmFwICU+JSANCiAgbXV0YXRlX2F0KGMoMiw0OjE3KSwgYXMubnVtZXJpYykgJT4lDQogIG11dGF0ZShDb21wZXRpdGlvbiA9IHJlcChwYXN0ZShjb21wZSwiYiIpLCBsZW5ndGgoc2NyYXAkTmFtZSkgKSwNCiAgICAgICAgIFN0YWdlID0gcmVwKHN0YWdlLCBsZW5ndGgoc2NyYXAkTmFtZSApICkgKQ0KIyMNCmNvbXBlDQpuLmNvbXBldGl0b3JzIDwtIG1heChzY3JhcCRSYW5rLCBuYS5ybSA9IFRSVUUpOyBuLmNvbXBldGl0b3JzDQojIyMjIyMjIyMjIyMjIyMgIyMjIyMjIyMjIyMjIyMjIyMjDQpNZW5feW91dGhfYl9Tb3VyZV9GaW5hbHMgPC0gc2NyYXANCmBgYCAgDQoNCiMjIyBXUklURQ0KDQpgYGB7ciBpbmNsdWRlPVRSVUUsIGV2YWw9IFRSVUV9DQojIyMgV3JpdGUgZ29vZ2xlIHNoZWV0ICMjIw0KTWVuX0JvdWxkZXJfWW91dGhfU291cmUuMjQgPC0gcmJpbmQoTWVuX3lvdXRoX1NvdXJlX1F1YWxpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVuX3lvdXRoX1NvdXJlX0ZpbmFscywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lbl95b3V0aF9hX1NvdXJlX1F1YWxpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVuX3lvdXRoX2FfU291cmVfRmluYWxzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVuX3lvdXRoX2JfU291cmVfUXVhbGksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZW5feW91dGhfYl9Tb3VyZV9GaW5hbHMpDQpNZW5fQm91bGRlcl9Zb3V0aF9Tb3VyZS4yNCAlPiUgcHJpbnQobj1sZW5ndGgoTWVuX0JvdWxkZXJfWW91dGhfU291cmUuMjQkTmFtZSkpDQojDQpNZW5fQm91bGRlcl9Zb3V0aF9Tb3VyZS4yNCAlPiUNCiAgZmlsdGVyKENvbXBldGl0aW9uPT0gIklGU0MgWW91dGggRXVyb3BlYW4gQ3VwIFNvdXJlIDIwMjQiKSAlPiUNCiAga25pdHI6OmthYmxlKCkNCiMNCk1lbl9Cb3VsZGVyX1lvdXRoX1NvdXJlLjI0ICU+JQ0KICBmaWx0ZXIoQ29tcGV0aXRpb249PSAiSUZTQyBZb3V0aCBFdXJvcGVhbiBDdXAgU291cmUgMjAyNCBhIikgJT4lDQogIGtuaXRyOjprYWJsZSgpDQojDQpNZW5fQm91bGRlcl9Zb3V0aF9Tb3VyZS4yNCAlPiUNCiAgZmlsdGVyKENvbXBldGl0aW9uPT0gIklGU0MgWW91dGggRXVyb3BlYW4gQ3VwIFNvdXJlIDIwMjQgYiIpICU+JQ0KICBrbml0cjo6a2FibGUoKQ0KIw0Kb3B0aW9ucyhnYXJnbGVfb2F1dGhfZW1haWwgPSAidmlsbGF0b3JvcGF6ZmpAZGF0YWFuYWx5c2lzbGFiLmNvbSIpDQpnczRfZGVhdXRoKCkNCmdzNF9hdXRoKCkNCnNoZWV0X3dyaXRlKGRhdGEgPSBNZW5fQm91bGRlcl9Zb3V0aF9Tb3VyZS4yNCwNCiAgICAgICAgICAgIHNzPSAiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMWJCTGlqMVYyTTFRZHNyNllvcjdSRjBSVGdvWlpwV2VzZExFbUNZTlRVZXMvZWRpdD91c3A9c2hhcmluZyIsIA0KICAgICAgICAgICAgc2hlZXQ9cGFzdGUoIk1lbl9Cb3VsZGVyX1lvdXRoX1NvdXJlLjI0IikpICANCg0KYGBgDQoNCiMjIyBDb25zb2xpZGFkbyBlbiBsYSBbSG9qYSBHb29nbGVdKGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFiQkxpajFWMk0xUWRzcjZZb3I3UkYwUlRnb1pacFdlc2RMRW1DWU5UVWVzL2VkaXQ/dXNwPXNoYXJpbmcpDQo=