Q. 웹상에서 구할 수 있는 북한기업자료는?
산업연구원은 북한의 언론보도를 주기적으로 모니터링하여 북한기업을
목록화하고 있다. 자료의 메타정보는 다음과 같다.
Q. 산업연구원 북한기업자료의 내용은?
2025년 4월 16일 조회한 기업편 자료의 구조는 아래와 같다.
library(readxl, quietly = T)
# dir_ind : 북한기업자료 폴더
firm = read_excel("./_통일연구/_ind/기업_관리_목록_2504161740.xlsx"
, col_names = paste0("V",1:17))
firm
Q. 자료의 변수 목록은?
위 자료는 17개 변수로 구성되어 있고 변수목록은 다음과 같다.
library(dplyr, quietly = T)
변수목록 = tibble(변수명 = names(firm), 변수내용 = unlist(firm[1, ]))
# 출력
library(knitr, quietly = T)
library(kableExtra, quietly = T) %>% suppressMessages()
kable(변수목록, format = "html", col.names = NULL) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE,
position = "left",
font_size = 10
) %>% row_spec(1:nrow(변수목록), extra_css = "border: none;")
V1 |
기업고유번호 |
V2 |
기업명 |
V3 |
내부분류코드 |
V4 |
분류 (대대분류) |
V5 |
분류 (대분류) |
V6 |
분류 (중분류) |
V7 |
분류 (소분류) |
V8 |
분류 (소소분류) |
V9 |
산업분류 |
V10 |
소재지 |
V11 |
좌표 |
V12 |
위도 |
V13 |
경도 |
V14 |
출처 |
V15 |
서비스여부 |
V16 |
생산·투자보도(2010~현재) |
V17 |
전체보도(2010~현재) |
17개 변수를 살펴보면 크게 기업명칭, 기업분류, 기업위치, 출처 및 보도
수로 구분할 수 있다.
기업명칭 : 기업고유번호(V1), 기업명(V2)
기업분류 : 산업 및 업종 등 기업분류(V3~V9)
기업위치 : 소재지 및 경위도좌표(V10~V13)
출처 및 보도 수 : 출처(V14), 보도 수(V16, V17)
Q. 확인 가능한 기업 수와 보도 수는?
2025년 4월 16일 조회 기준 기업 수와 2010년 이후 보도 수는 다음과
같다.
기업수 = nrow(firm) - 1 # 변수 설명 행 제외
기업별보도수 = firm[2:nrow(firm), ]$V17 %>% as.integer()
보도수0건 = nrow(subset(firm, V17 == "0"))
# 숫자 포맷 함수 정의
comma = function(x) formatC(x, digits = 0, big.mark = ",", format = "f")
small = function(x) formatC(x, digits = 1, format = "f", small.mark = ".")
# 출력 값
출력 = c(
"기업 수" = comma(기업수)
, "보도 수" = comma(sum(기업별보도수))
, " -최대" = comma(max(기업별보도수))
, " -평균" = small(mean(기업별보도수))
, " -중위" = small(median(기업별보도수))
, " -최소" = comma(min(기업별보도수))
, " -표준편차" = small(sd(기업별보도수))
) %>% tibble(항목 = names(.), 값 = .) %>%
mutate(
주석 =
ifelse(항목 == " -최대"
, paste0("전체 보도의 "
, small(max(기업별보도수) / sum(기업별보도수) * 100),"%")
, "")
, 주석 =
ifelse(항목 == " -최소"
, paste0("전체 기업의 "
, small(보도수0건 / 기업수 * 100),"% ("
, comma(보도수0건), "개)")
, 주석)
)
# 출력
kable(출력
, format = "html", align = c("l","r","l")
, col.names = NULL) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed")
, full_width = F
, position = "left"
, font_size = 10
) %>%
row_spec(1:nrow(출력), extra_css = "border: none;")
기업 수 |
3,674 |
|
보도 수 |
86,116 |
|
-최대 |
1,728 |
전체 보도의 2.0% |
-평균 |
23.4 |
|
-중위 |
2.0 |
|
-최소 |
0 |
전체 기업의 26.5% (974개) |
-표준편차 |
99.1 |
|
산업연구원에서 확인한 기업 관련 ‘2010년 이후 보도’(이하 보도)는 총
86,116건이며, 보도를 통해 확인한 기업은 총 3,674개이다.
기업당 평균 보도 수는 약 23건인데 중위값은 2건에 불과하고 표준편차는
약 99건이므로 일부 기업체가 주요하게 다뤄지고 있을 여지가 있다.
가장 많이 보도된 기업의 보도 수는 1,728건으로 전체 보도 수의 2%에
달한다.
보도가 없는 기업은 974개로 26.5%에 달한다.
Q. 산업분류별 기업 수는?
산업분류별 기업 수를 살펴보면 다음과 같다.
library(stringr, quietly = T)
library(plotly, quietly = T) %>% suppressMessages()
# 집계
결측치정리 =
firm[2:nrow(firm), ] %>% # 변수 설명 행 제외
# 결측치 정리
mutate(V4 = ifelse(is.na(V4), "미상", V4)
, V5 = ifelse(is.na(V5), V4, V5)
, V6 = ifelse(is.na(V6), V5, V6)
, V7 = ifelse(is.na(V7), V6, V7)
, V8 = ifelse(is.na(V8), V7, V8)
, 보도수 = as.integer(V17))
기업수집계 = bind_rows(
data.frame(노드 = "전체", 부모 = "", n = length(결측치정리$V17))
, 결측치정리 %>% mutate(노드 = V4, 부모 = "전체") %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 결측치정리 %>% filter(V5 != "미상") %>% mutate(노드 = V5, 부모 = V4) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 결측치정리 %>% filter(V6 != "미상") %>% mutate(노드 = V6, 부모 = V5) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 결측치정리 %>% filter(V7 != "미상") %>% mutate(노드 = V7, 부모 = V6) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
)
# treemap
# 전체
tm = plot_ly(
type = "treemap", name = "전체"
, data = 기업수집계 %>% filter(노드 != 부모)
, ids = ~노드
, labels = ~노드
, parents = ~부모
, values = ~n
, branchvalues = "total"
, textinfo = "label+value"
, maxdepth = 5
, domain = list(column=0)
, height = 450
)
# 중간집계
분류 = c(중분류 = "V5", 소분류 = "V6", 세분류 = "V7")
for (i in 1:length(분류)) {
중간분류 = 분류[i]
중간집계 = 기업수집계 %>%
filter(노드 %in% unique(결측치정리[[중간분류]]) & 노드 != 부모)
tm = tm %>% add_trace(
type = "treemap", name = names(중간분류)
, ids = 중간집계$노드
, labels = 중간집계$노드
, parents = rep(names(중간분류), nrow(중간집계))
, values = 중간집계$n
, maxdepth = 3
, domain = list(row=as.integer(i/2), column=i%%2)
)
}
# 출력
tm %>% layout(grid = list(columns=2, rows=2), autosize = T, font = list(size = 10)
, margin = list(b = 0, l = 0, r = 0, t = 0))
대분류 기준 제조업 3,012개, 비제조업 629개, 미상 33개이다.
중분류 기준 경공업이 1,674개로 최다이며, 비제조업 중 최다는 광업
399개이다.
소분류 기준 음식료품 및 담배 업종이 790개로 최다이며, 비제조업 중
최다는 수력발전 215개이다.
세분류 기준 곡물 및 기타 식료가공이 453개로 최다이며, 비제조업 중
최다는 탄광 194개이다.
Q. 산업분류별 보도 수는?
산업분류별 보도 수를 살펴보면 다음과 같다.
# 집계
보도수집계 = bind_rows(
data.frame(노드 = "전체", 부모 = "", n = sum(결측치정리$보도수))
, 결측치정리 %>% mutate(노드 = V4, 부모 = "전체") %>%
group_by(부모, 노드) %>% summarise(n = sum(보도수), .groups = "drop")
, 결측치정리 %>% filter(V5 != "미상") %>% mutate(노드 = V5, 부모 = V4) %>%
group_by(부모, 노드) %>% summarise(n = sum(보도수), .groups = "drop")
, 결측치정리 %>% filter(V6 != "미상") %>% mutate(노드 = V6, 부모 = V5) %>%
group_by(부모, 노드) %>% summarise(n = sum(보도수), .groups = "drop")
, 결측치정리 %>% filter(V7 != "미상") %>% mutate(노드 = V7, 부모 = V6) %>%
group_by(부모, 노드) %>% summarise(n = sum(보도수), .groups = "drop")
)
# treemap 출력
# 전체
tm = plot_ly(
type = "treemap", name = "전체"
, data = 보도수집계 %>% filter(노드 != 부모)
, ids = ~노드
, labels = ~노드
, parents = ~부모
, values = ~n
, branchvalues = "total"
, textinfo = "label+value"
, maxdepth = 5
, domain = list(row=0)
, height = 450
)
# 중간집계
for (i in 1:length(분류)) {
중간분류 = 분류[i]
중간집계 = 보도수집계 %>%
filter(노드 %in% unique(결측치정리[[중간분류]]) & 노드 != 부모)
tm = tm %>% add_trace(
type = "treemap", name = names(중간분류)
, ids = 중간집계$노드
, labels = 중간집계$노드
, parents = rep(names(중간분류), nrow(중간집계))
, values = 중간집계$n
, maxdepth = 3
, domain = list(row=as.integer(i/2), column=i%%2)
)
}
# 출력
tm %>% layout(grid = list(columns=2, rows=2), autosize = T, font = list(size = 10)
, margin = list(b = 0, l = 0, r = 0, t = 0))
대분류 기준 제조업 54,394건, 비제조업 31,682건의 보도가 확인된다.
중분류 기준 중화학공업이 33,098건으로 최다이며, 비제조업에서는 광업
20,666건이 최다이다.
소분류 기준 탄광이 14,506건으로 최다이며, 제조업에서는 섬유의류
10,355건이 최다이다.
세분류 기준으로도 하위 세분류가 없는 탄광이 14,506건으로 최다이며,
제조업에서는 제철·제강 6,177건이 최다이다.
Q. 보도 수 100위 내 기업의 업종 분포는?
보도 수 100위 내 기업을 살펴보면 다음과 같다.
# 집계
백위기업평균 = 결측치정리 %>% arrange(desc(보도수)) %>% head(100) %>%
mutate(업종 = V6) %>%
group_by(업종) %>% summarise(기업수=n(), 평균보도수=mean(보도수)) %>%
arrange(평균보도수)
백위기업 = 결측치정리 %>% arrange(desc(보도수)) %>% head(100) %>%
mutate(산업부문 = V4
, 업종 = factor(V6, levels = 백위기업평균$업종), 기업 = V2
, 순위 = row_number(), 상위20위 = ifelse(순위 > 20, 5, 10))
업종별집계 = 백위기업 %>% group_by(업종) %>%
summarise(기업수 = n(), 보도수 = sum(보도수))
# 백위기업 산점도
p1 = plot_ly()
for (부문 in unique(백위기업$산업부문)) {
p1 = p1 %>% add_trace(
data = 백위기업 %>% subset(산업부문 == 부문),
type = "scatter",
mode = "markers",
x = ~보도수,
y = ~업종,
text = ~paste(기업, "<br>보도 수:", 보도수, "<br>순위:", 순위),
hoverinfo = "text",
marker = list(
color = ifelse(부문 == "비제조업","darkgreen", "darkviolet"),
size = ~상위20위,
line = list(width = 0)
)
)
}; p1 = p1 %>% layout(yaxis = list(title=""), showlegend = F)
# 백위기업업종(소분류) 트리맵
p2 = plot_ly(
data = 업종별집계
, type = "treemap"
, labels = ~업종
, parents = rep("", nrow(업종별집계))
, values = ~기업수
, textinfo = "label+value"
, domain = list(column=1)
, name = "업종별 기업 수"
) %>% layout(margin = list(b = 5, l = 0, r = 0, t = 5))
# 출력
library(htmltools, quietly = T)
browsable(tagList(
div(style = "display:inline-block; width:49%;", p1),
div(style = "display:inline-block; width:49%;", p2)
))
보도 수 100위 내 기업이 가장 많은 업종은 탄광(25개)이다.
기업당 보도 수가 가장 많은 기업은 1차금속 업종에 속하며, 2위, 3위
기업도 1차금속 업종에 속한다.
보도 수 상위 20위 내 기업의 분포를 살펴보면, 1차금속 업종(1~3위),
섬유의류(4위, 13위), 화학(5위, 6위, 8위), 화력발전(7위, 9위), 탄광(10위,
15위, 17위, 18위), 기계(11위, 12위), 건재(14위), 철광(16위),
수력발전(20위) 등의 업종에 해당한다.
Q. 보도가 없는 기업의 업종은?
2010년 이후 보도가 없는 기업의 업종 분포는 다음과 같다.
# 집계
보도수0기업 = 결측치정리 %>% filter(보도수 == 0)
보도수0기업집계 = bind_rows(
data.frame(노드 = "전체", 부모 = "", n = nrow(보도수0기업))
, 보도수0기업 %>% mutate(노드 = V4, 부모 = "전체") %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 보도수0기업 %>% filter(V5 != "미상") %>% mutate(노드 = V5, 부모 = V4) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 보도수0기업 %>% filter(V6 != "미상") %>% mutate(노드 = V6, 부모 = V5) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
, 보도수0기업 %>% filter(V7 != "미상") %>% mutate(노드 = V7, 부모 = V6) %>%
group_by(부모, 노드) %>% summarise(n = n(), .groups = "drop")
)
# 그래프
Pls = 2:3 %>% lapply(
function(i) {
보도없음비율 = merge(
기업수집계 %>%
filter(노드 %in% unique(결측치정리[[분류[i]]]) & 노드 != 부모) %>%
mutate(전체 = n) %>% select(노드, 전체)
, 보도수0기업집계 %>%
filter(노드 %in% unique(결측치정리[[분류[i]]]) & 노드 != 부모) %>%
mutate(보도없음 = n) %>% select(노드, 보도없음)
, by = "노드"
) %>% filter(전체 >= 50) %>%
mutate(보도없음비율 = 보도없음 / 전체 * 100) %>%
arrange(desc(보도없음비율))
보도없음비율 = 보도없음비율 %>% mutate(노드 = factor(노드, levels = 노드))
plot_ly(
data = 보도없음비율
, type = "bar"
, x = ~보도없음비율
, y = ~노드
, marker = list(color = ~보도없음비율, colorscale = "Viridis")
, text = ~paste0(small(보도없음비율), "%")
, hoverinfo = "text"
, name = names(분류)[i]
, height = 600
) %>% layout(font = list(size = 9)
, margin = list(b = 10, l = 5, r = 5, t = 25))
}
)
# 출력
subplot(Pls, shareX = T, shareY = F, nrows = 2, heights = c(0.4, 0.6)) %>%
layout(showlegend = F
, xaxis = list(title = "2010년 이후 보도되지 않은 비율(%)")
, title = list(text = "소분류(위), 세분류(아래)"
, font = list(size = 9, color = "black")
, xanchor = "left", x = 0.05))
2010년 이후 보도되지 않은 기업의 비율이 가장 큰 업종은 소분류 기준
수력발전(40.5%), 세분류 기준 중소형수력발전(45.8%)이다.
소분류 기준으로는 가구, 목재, 종이 및 잡제품(31.5%), 전기전자(31%),
수송기계(30.3%) 등의 비율도 높은 편이다.
세분류 기준으로는 전자·ICT(40%), 잡제품(36.4%) 등의 비율도 높은
편이다.
LS0tDQp0aXRsZTogDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIGRmX3ByaW50OiBkZWZhdWx0DQotLS0NCg0KIyMjIFEuIOybueyDgeyXkOyEnCDqtaztlaAg7IiYIOyeiOuKlCDrtoHtlZzquLDsl4XsnpDro4zripQ/DQoNCuyCsOyXheyXsOq1rOybkOydgCDrtoHtlZzsnZgg7Ja466Gg67O064+E66W8IOyjvOq4sOyggeycvOuhnCDrqqjri4jthLDrp4HtlZjsl6wg67aB7ZWc6riw7JeF7J2EIOuqqeuhne2ZlO2VmOqzoCDsnojri6QuIOyekOujjOydmCDrqZTtg4DsoJXrs7TripQg64uk7J2M6rO8IOqwmeuLpC4NCg0KLSAgIFVSTCA6IDxodHRwczovL25raW5kdXN0cnkua2lldC5yZS5rci9jb21wL2xpc3QuZG8+DQoNCi0gICDstJ3qtITtjrggOiDslb0gMVx+MuuFhOyghCDsl7Drp5Ag6riw7KSAICjrlJTtj7Ttirgg7KCA7J6l66qFIDog7LSd6rSEX+q4sOyXheuqqeuhnS54bHN4KQ0KDQotICAg6riw7JeF7Y64IDog7ZiE7J6sIOq4sOykgCAo7IiY7IucIOyXheuNsOydtO2KuC4g65SU7Y+07Yq4IOyggOyepeuqhSA6IOq4sOyXhV/qtIDrpqxf66qp66GdLnhsc3gpDQoNCi0gICDsoJzqs7Xrs4DsiJggOiDquLDsl4XrqoUsIOyCsOyXhSDsl4XsooXrtoTrpZgsIOyGjOyerOyngCwg7JyE7LmYIOqyveychOuPhCwgMjAxMOuFhCDsnbTtm4Qg67O064+EIOyImA0KDQojIyMgUS4g7IKw7JeF7Jew6rWs7JuQIOu2ge2VnOq4sOyXheyekOujjOydmCDrgrTsmqnsnYA/DQoNCjIwMjXrhYQgNOyblCAxNuydvCDsobDtmoztlZwg6riw7JeF7Y64IOyekOujjOydmCDqtazsobDripQg7JWE656Y7JmAIOqwmeuLpC4NCg0KYGBge3Ig7J6Q66OM7J296riwIOuwjyDthYzsnbTruJQg7ZmV7J24fQ0KbGlicmFyeShyZWFkeGwsIHF1aWV0bHkgPSBUKQ0KDQojIOuLpOyatOuhnOuTnO2VnCDtjIzsnbwg7J296riwDQpmaXJtID0gcmVhZF9leGNlbCgiLi9f7Ya17J287Jew6rWsL19pbmQv6riw7JeFX+q0gOumrF/rqqnroZ1fMjUwNDE2MTc0MC54bHN4Ig0KICAgICAgICAgICAgICAgICAgLCBjb2xfbmFtZXMgPSBwYXN0ZTAoIlYiLDE6MTcpKSANCmZpcm0NCmBgYA0KDQojIyMgUS4g7J6Q66OM7J2YIOuzgOyImCDrqqnroZ3snYA/DQoNCuychCDsnpDro4zripQgMTfqsJwg67OA7IiY66GcIOq1rOyEseuQmOyWtCDsnojqs6Ag67OA7IiY66qp66Gd7J2AIOuLpOydjOqzvCDqsJnri6QuDQoNCmBgYHtyIOuzgOyImOuqqeuhnX0NCmxpYnJhcnkoZHBseXIsIHF1aWV0bHkgPSBUKQ0KDQrrs4DsiJjrqqnroZ0gPSB0aWJibGUo67OA7IiY66qFID0gbmFtZXMoZmlybSksIOuzgOyImOuCtOyaqSA9IHVubGlzdChmaXJtWzEsIF0pKQ0KDQojIOy2nOugpQ0KbGlicmFyeShrbml0ciwgcXVpZXRseSA9IFQpDQpsaWJyYXJ5KGthYmxlRXh0cmEsIHF1aWV0bHkgPSBUKSAlPiUgc3VwcHJlc3NNZXNzYWdlcygpDQoNCmthYmxlKOuzgOyImOuqqeuhnSwgZm9ybWF0ID0gImh0bWwiLCBjb2wubmFtZXMgPSBOVUxMKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoDQogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLA0KICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwNCiAgICBwb3NpdGlvbiA9ICJsZWZ0IiwNCiAgICBmb250X3NpemUgPSAxMA0KICApICU+JSByb3dfc3BlYygxOm5yb3co67OA7IiY66qp66GdKSwgZXh0cmFfY3NzID0gImJvcmRlcjogbm9uZTsiKQ0KYGBgDQoNCjE36rCcIOuzgOyImOulvCDsgrTtjrTrs7TrqbQg7YGs6rKMIOq4sOyXheuqhey5rSwg6riw7JeF67aE66WYLCDquLDsl4XsnITsuZgsIOy2nOyymCDrsI8g67O064+EIOyImOuhnCDqtazrtoTtlaAg7IiYIOyeiOuLpC4NCg0KLSAgIOq4sOyXheuqhey5rSA6IOq4sOyXheqzoOycoOuyiO2YuChWMSksIOq4sOyXheuqhShWMikNCg0KLSAgIOq4sOyXheu2hOulmCA6IOyCsOyXhSDrsI8g7JeF7KKFIOuTsSDquLDsl4XrtoTrpZgoVjNcflY5KQ0KDQotICAg6riw7JeF7JyE7LmYIDog7IaM7J6s7KeAIOuwjyDqsr3snITrj4TsooztkZwoVjEwXH5WMTMpDQoNCi0gICDstpzsspgg67CPIOuztOuPhCDsiJggOiDstpzsspgoVjE0KSwg67O064+EIOyImChWMTYsIFYxNykNCg0KIyMjIFEuIO2ZleyduCDqsIDriqXtlZwg6riw7JeFIOyImOyZgCDrs7Trj4Qg7IiY64qUPw0KDQoyMDI164WEIDTsm5QgMTbsnbwg7KGw7ZqMIOq4sOykgCDquLDsl4Ug7IiY7JmAIDIwMTDrhYQg7J207ZuEIOuztOuPhCDsiJjripQg64uk7J2M6rO8IOqwmeuLpC4NCg0KYGBge3Ig6riw7JeFIOyImCDrsI8g67O064+EIOyImH0NCuq4sOyXheyImCA9IG5yb3coZmlybSkgLSAxICMg67OA7IiYIOyEpOuqhSDtlokg7KCc7Jm4DQrquLDsl4Xrs4Trs7Trj4TsiJggPSBmaXJtWzI6bnJvdyhmaXJtKSwgXSRWMTcgJT4lIGFzLmludGVnZXIoKQ0K67O064+E7IiYMOqxtCA9IG5yb3coc3Vic2V0KGZpcm0sIFYxNyA9PSAiMCIpKQ0KDQojIOyIq+yekCDtj6zrp7cg7ZWo7IiYIOygleydmA0KY29tbWEgPSBmdW5jdGlvbih4KSBmb3JtYXRDKHgsIGRpZ2l0cyA9IDAsIGJpZy5tYXJrID0gIiwiLCBmb3JtYXQgPSAiZiIpDQpzbWFsbCA9IGZ1bmN0aW9uKHgpIGZvcm1hdEMoeCwgZGlnaXRzID0gMSwgZm9ybWF0ID0gImYiLCBzbWFsbC5tYXJrID0gIi4iKQ0KDQojIOy2nOugpSDqsJINCuy2nOugpSA9IGMoDQogICLquLDsl4Ug7IiYIiA9IGNvbW1hKOq4sOyXheyImCkNCiAgLCAi67O064+EIOyImCIgPSBjb21tYShzdW0o6riw7JeF67OE67O064+E7IiYKSkNCiAgLCAiIC3stZzrjIAiID0gY29tbWEobWF4KOq4sOyXheuzhOuztOuPhOyImCkpDQogICwgIiAt7Y+J6regIiA9IHNtYWxsKG1lYW4o6riw7JeF67OE67O064+E7IiYKSkNCiAgLCAiIC3spJHsnIQiID0gc21hbGwobWVkaWFuKOq4sOyXheuzhOuztOuPhOyImCkpDQogICwgIiAt7LWc7IaMIiA9IGNvbW1hKG1pbijquLDsl4Xrs4Trs7Trj4TsiJgpKQ0KICAsICIgLe2RnOykgO2OuOywqCIgPSBzbWFsbChzZCjquLDsl4Xrs4Trs7Trj4TsiJgpKQ0KKSAlPiUgdGliYmxlKO2VreuqqSA9IG5hbWVzKC4pLCDqsJIgPSAuKSAlPiUgDQogIG11dGF0ZSgNCiAgICDso7zshJ0gPSANCiAgICAgIGlmZWxzZSjtla3rqqkgPT0gIiAt7LWc64yAIg0KICAgICAgICAgICAgICwgcGFzdGUwKCLsoITssrQg67O064+E7J2YICINCiAgICAgICAgICAgICAgICAgICAgICAsIHNtYWxsKG1heCjquLDsl4Xrs4Trs7Trj4TsiJgpIC8gc3VtKOq4sOyXheuzhOuztOuPhOyImCkgKiAxMDApLCIlIikNCiAgICAgICAgICAgICAsICIiKQ0KICAgICwg7KO87ISdID0gDQogICAgICBpZmVsc2Uo7ZWt66qpID09ICIgLey1nOyGjCINCiAgICAgICAgICAgICAsIHBhc3RlMCgi7KCE7LK0IOq4sOyXheydmCAiDQogICAgICAgICAgICAgICAgICAgICAgLCBzbWFsbCjrs7Trj4TsiJgw6rG0IC8g6riw7JeF7IiYICogMTAwKSwiJSAoIg0KICAgICAgICAgICAgICAgICAgICAgICwgY29tbWEo67O064+E7IiYMOqxtCksICLqsJwpIikNCiAgICAgICAgICAgICAsIOyjvOyEnSkNCiAgKQ0KDQojIOy2nOugpQ0Ka2FibGUo7Lac66ClDQogICAgICAsIGZvcm1hdCA9ICJodG1sIiwgYWxpZ24gPSBjKCJsIiwiciIsImwiKQ0KICAgICAgLCBjb2wubmFtZXMgPSBOVUxMKSAlPiUgDQogIGthYmxlX3N0eWxpbmcoDQogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpDQogICAgLCBmdWxsX3dpZHRoID0gRg0KICAgICwgcG9zaXRpb24gPSAibGVmdCINCiAgICAsIGZvbnRfc2l6ZSA9IDEwDQogICkgJT4lDQogIHJvd19zcGVjKDE6bnJvdyjstpzroKUpLCBleHRyYV9jc3MgPSAiYm9yZGVyOiBub25lOyIpDQpgYGANCg0K7IKw7JeF7Jew6rWs7JuQ7JeQ7IScIO2ZleyduO2VnCDquLDsl4Ug6rSA66CoICcyMDEw64WEIOydtO2bhCDrs7Trj4QnKOydtO2VmCDrs7Trj4Qp64qUIOy0nSA4NiwxMTbqsbTsnbTrqbAsIOuztOuPhOulvCDthrXtlbQg7ZmV7J247ZWcIOq4sOyXheydgCDstJ0gMyw2NzTqsJzsnbTri6QuDQoNCuq4sOyXheuLuSDtj4nqt6Ag67O064+EIOyImOuKlCDslb0gMjPqsbTsnbjrjbAg7KSR7JyE6rCS7J2AIDLqsbTsl5Ag67aI6rO87ZWY6rOgIO2RnOykgO2OuOywqOuKlCDslb0gOTnqsbTsnbTrr4DroZwg7J2867aAIOq4sOyXheyytOqwgCDso7zsmpTtlZjqsowg64uk66SE7KeA6rOgIOyeiOydhCDsl6zsp4DqsIAg7J6I64ukLg0KDQrqsIDsnqUg66eO7J20IOuztOuPhOuQnCDquLDsl4XsnZgg67O064+EIOyImOuKlCAxLDcyOOqxtOycvOuhnCDsoITssrQg67O064+EIOyImOydmCAyJeyXkCDri6ztlZzri6QuDQoNCuuztOuPhOqwgCDsl4bripQg6riw7JeF7J2AIDk3NOqwnOuhnCAyNi41JeyXkCDri6ztlZzri6QuDQoNCiMjIyBRLiDsgrDsl4XrtoTrpZjrs4Qg6riw7JeFIOyImOuKlD8NCg0K7IKw7JeF67aE66WY67OEIOq4sOyXhSDsiJjrpbwg7IK07Y6067O066m0IOuLpOydjOqzvCDqsJnri6QuDQoNCmBgYHtyIOyCsOyXheusuOulmOuzhCDquLDsl4Ug7IiYfQ0KbGlicmFyeShzdHJpbmdyLCBxdWlldGx5ID0gVCkNCmxpYnJhcnkocGxvdGx5LCBxdWlldGx5ID0gVCkgJT4lIHN1cHByZXNzTWVzc2FnZXMoKQ0KDQojIOynkeqzhA0K6rKw7Lih7LmY7KCV66asID0gDQogIGZpcm1bMjpucm93KGZpcm0pLCBdICU+JSAjIOuzgOyImCDshKTrqoUg7ZaJIOygnOyZuA0KICAjIOqysOy4oey5mCDsoJXrpqwNCiAgbXV0YXRlKFY0ID0gaWZlbHNlKGlzLm5hKFY0KSwgIuuvuOyDgSIsIFY0KQ0KICAgICAgICAgLCBWNSA9IGlmZWxzZShpcy5uYShWNSksIFY0LCBWNSkNCiAgICAgICAgICwgVjYgPSBpZmVsc2UoaXMubmEoVjYpLCBWNSwgVjYpDQogICAgICAgICAsIFY3ID0gaWZlbHNlKGlzLm5hKFY3KSwgVjYsIFY3KQ0KICAgICAgICAgLCBWOCA9IGlmZWxzZShpcy5uYShWOCksIFY3LCBWOCkNCiAgICAgICAgICwg67O064+E7IiYID0gYXMuaW50ZWdlcihWMTcpKQ0KDQrquLDsl4XsiJjsp5Hqs4QgPSBiaW5kX3Jvd3MoDQogIGRhdGEuZnJhbWUo64W465OcID0gIuyghOyytCIsIOu2gOuqqCA9ICIiLCBuID0gbGVuZ3RoKOqysOy4oey5mOygleumrCRWMTcpKQ0KICAsIOqysOy4oey5mOygleumrCAlPiUgbXV0YXRlKOuFuOuTnCA9IFY0LCDrtoDrqqggPSAi7KCE7LK0IikgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQogICwg6rKw7Lih7LmY7KCV66asICU+JSBmaWx0ZXIoVjUgIT0gIuuvuOyDgSIpICU+JSBtdXRhdGUo64W465OcID0gVjUsIOu2gOuqqCA9IFY0KSAlPiUgDQogICAgZ3JvdXBfYnko67aA66qoLCDrhbjrk5wpICU+JSBzdW1tYXJpc2UobiA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikNCiAgLCDqsrDsuKHsuZjsoJXrpqwgJT4lIGZpbHRlcihWNiAhPSAi66+47IOBIikgJT4lIG11dGF0ZSjrhbjrk5wgPSBWNiwg67aA66qoID0gVjUpICU+JSANCiAgICBncm91cF9ieSjrtoDrqqgsIOuFuOuTnCkgJT4lIHN1bW1hcmlzZShuID0gbigpLCAuZ3JvdXBzID0gImRyb3AiKQ0KICAsIOqysOy4oey5mOygleumrCAlPiUgZmlsdGVyKFY3ICE9ICLrr7jsg4EiKSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY3LCDrtoDrqqggPSBWNikgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQopDQojIHRyZWVtYXANCiMg7KCE7LK0DQp0bSA9IHBsb3RfbHkoDQogIHR5cGUgPSAidHJlZW1hcCIsIG5hbWUgPSAi7KCE7LK0Ig0KICAsIGRhdGEgPSDquLDsl4XsiJjsp5Hqs4QgJT4lIGZpbHRlcijrhbjrk5wgIT0g67aA66qoKQ0KICAsIGlkcyA9IH7rhbjrk5wNCiAgLCBsYWJlbHMgPSB+64W465OcDQogICwgcGFyZW50cyA9IH7rtoDrqqgNCiAgLCB2YWx1ZXMgPSB+bg0KICAsIGJyYW5jaHZhbHVlcyA9ICJ0b3RhbCINCiAgLCB0ZXh0aW5mbyA9ICJsYWJlbCt2YWx1ZSINCiAgLCBtYXhkZXB0aCA9IDUNCiAgLCBkb21haW4gPSBsaXN0KGNvbHVtbj0wKQ0KICAsIGhlaWdodCA9IDQ1MA0KICApDQoNCiMg7KSR6rCE7KeR6rOEDQrrtoTrpZggPSBjKOykkeu2hOulmCA9ICJWNSIsIOyGjOu2hOulmCA9ICJWNiIsIOyEuOu2hOulmCA9ICJWNyIpDQpmb3IgKGkgaW4gMTpsZW5ndGgo67aE66WYKSkgew0KICDspJHqsITrtoTrpZggPSDrtoTrpZhbaV0NCiAg7KSR6rCE7KeR6rOEID0g6riw7JeF7IiY7KeR6rOEICU+JSANCiAgICBmaWx0ZXIo64W465OcICVpbiUgdW5pcXVlKOqysOy4oey5mOygleumrFtb7KSR6rCE67aE66WYXV0pICYg64W465OcICE9IOu2gOuqqCkNCiAgdG0gPSB0bSAlPiUgYWRkX3RyYWNlKA0KICAgIHR5cGUgPSAidHJlZW1hcCIsIG5hbWUgPSBuYW1lcyjspJHqsITrtoTrpZgpDQogICAgLCBpZHMgPSAg7KSR6rCE7KeR6rOEJOuFuOuTnA0KICAgICwgbGFiZWxzID0g7KSR6rCE7KeR6rOEJOuFuOuTnA0KICAgICwgcGFyZW50cyA9IHJlcChuYW1lcyjspJHqsITrtoTrpZgpLCBucm93KOykkeqwhOynkeqzhCkpDQogICAgLCB2YWx1ZXMgPSDspJHqsITsp5Hqs4Qkbg0KICAgICwgbWF4ZGVwdGggPSAzDQogICAgLCBkb21haW4gPSBsaXN0KHJvdz1hcy5pbnRlZ2VyKGkvMiksIGNvbHVtbj1pJSUyKQ0KICApDQp9DQogDQojIOy2nOugpQ0KdG0gJT4lIGxheW91dChncmlkID0gbGlzdChjb2x1bW5zPTIsIHJvd3M9MiksIGF1dG9zaXplID0gVCwgZm9udCA9IGxpc3Qoc2l6ZSA9IDEwKQ0KICAgICAgICAgICAgICAsIG1hcmdpbiA9IGxpc3QoYiA9IDAsIGwgPSAwLCByID0gMCwgdCA9IDApKQ0KYGBgDQoNCuuMgOu2hOulmCDquLDspIAg7KCc7KGw7JeFIDMsMDEy6rCcLCDruYTsoJzsobDsl4UgNjI56rCcLCDrr7jsg4EgMzPqsJzsnbTri6QuDQoNCuykkeu2hOulmCDquLDspIAg6rK96rO17JeF7J20IDEsNjc06rCc66GcIOy1nOuLpOydtOupsCwg67mE7KCc7KGw7JeFIOykkSDstZzri6TripQg6rSR7JeFIDM5OeqwnOydtOuLpC4NCg0K7IaM67aE66WYIOq4sOykgCDsnYzsi53ro4ztkogg67CPIOuLtOuwsCDsl4XsooXsnbQgNzkw6rCc66GcIOy1nOuLpOydtOupsCwg67mE7KCc7KGw7JeFIOykkSDstZzri6TripQg7IiY66Cl67Cc7KCEIDIxNeqwnOydtOuLpC4NCg0K7IS467aE66WYIOq4sOykgCDqs6HrrLwg67CPIOq4sO2DgCDsi53ro4zqsIDqs7XsnbQgNDUz6rCc66GcIOy1nOuLpOydtOupsCwg67mE7KCc7KGw7JeFIOykkSDstZzri6TripQg7YOE6rSRIDE5NOqwnOydtOuLpC4NCg0KIyMjIFEuIOyCsOyXheu2hOulmOuzhCDrs7Trj4Qg7IiY64qUPw0KDQrsgrDsl4XrtoTrpZjrs4Qg67O064+EIOyImOulvCDsgrTtjrTrs7TrqbQg64uk7J2M6rO8IOqwmeuLpC4NCg0KYGBge3Ig7IKw7JeF67aE66WY67OEIOuztOuPhCDsiJh9DQojIOynkeqzhA0K67O064+E7IiY7KeR6rOEID0gYmluZF9yb3dzKA0KICBkYXRhLmZyYW1lKOuFuOuTnCA9ICLsoITssrQiLCDrtoDrqqggPSAiIiwgbiA9IHN1bSjqsrDsuKHsuZjsoJXrpqwk67O064+E7IiYKSkNCiAgLCDqsrDsuKHsuZjsoJXrpqwgJT4lIG11dGF0ZSjrhbjrk5wgPSBWNCwg67aA66qoID0gIuyghOyytCIpICU+JSANCiAgICBncm91cF9ieSjrtoDrqqgsIOuFuOuTnCkgJT4lIHN1bW1hcmlzZShuID0gc3VtKOuztOuPhOyImCksIC5ncm91cHMgPSAiZHJvcCIpDQogICwg6rKw7Lih7LmY7KCV66asICU+JSBmaWx0ZXIoVjUgIT0gIuuvuOyDgSIpICU+JSBtdXRhdGUo64W465OcID0gVjUsIOu2gOuqqCA9IFY0KSAlPiUgDQogICAgZ3JvdXBfYnko67aA66qoLCDrhbjrk5wpICU+JSBzdW1tYXJpc2UobiA9IHN1bSjrs7Trj4TsiJgpLCAuZ3JvdXBzID0gImRyb3AiKQ0KICAsIOqysOy4oey5mOygleumrCAlPiUgZmlsdGVyKFY2ICE9ICLrr7jsg4EiKSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY2LCDrtoDrqqggPSBWNSkgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBzdW0o67O064+E7IiYKSwgLmdyb3VwcyA9ICJkcm9wIikNCiAgLCDqsrDsuKHsuZjsoJXrpqwgJT4lIGZpbHRlcihWNyAhPSAi66+47IOBIikgJT4lIG11dGF0ZSjrhbjrk5wgPSBWNywg67aA66qoID0gVjYpICU+JSANCiAgICBncm91cF9ieSjrtoDrqqgsIOuFuOuTnCkgJT4lIHN1bW1hcmlzZShuID0gc3VtKOuztOuPhOyImCksIC5ncm91cHMgPSAiZHJvcCIpDQopDQoNCiMgdHJlZW1hcCDstpzroKUNCiMg7KCE7LK0DQp0bSA9IHBsb3RfbHkoDQogIHR5cGUgPSAidHJlZW1hcCIsIG5hbWUgPSAi7KCE7LK0Ig0KICAsIGRhdGEgPSDrs7Trj4TsiJjsp5Hqs4QgJT4lIGZpbHRlcijrhbjrk5wgIT0g67aA66qoKQ0KICAsIGlkcyA9IH7rhbjrk5wNCiAgLCBsYWJlbHMgPSB+64W465OcDQogICwgcGFyZW50cyA9IH7rtoDrqqgNCiAgLCB2YWx1ZXMgPSB+bg0KICAsIGJyYW5jaHZhbHVlcyA9ICJ0b3RhbCINCiAgLCB0ZXh0aW5mbyA9ICJsYWJlbCt2YWx1ZSINCiAgLCBtYXhkZXB0aCA9IDUNCiAgLCBkb21haW4gPSBsaXN0KHJvdz0wKQ0KICAsIGhlaWdodCA9IDQ1MA0KICApDQoNCiMg7KSR6rCE7KeR6rOEDQpmb3IgKGkgaW4gMTpsZW5ndGgo67aE66WYKSkgew0KICDspJHqsITrtoTrpZggPSDrtoTrpZhbaV0NCiAg7KSR6rCE7KeR6rOEID0g67O064+E7IiY7KeR6rOEICU+JSANCiAgICBmaWx0ZXIo64W465OcICVpbiUgdW5pcXVlKOqysOy4oey5mOygleumrFtb7KSR6rCE67aE66WYXV0pICYg64W465OcICE9IOu2gOuqqCkNCiAgdG0gPSB0bSAlPiUgYWRkX3RyYWNlKA0KICAgIHR5cGUgPSAidHJlZW1hcCIsIG5hbWUgPSBuYW1lcyjspJHqsITrtoTrpZgpDQogICAgLCBpZHMgPSAg7KSR6rCE7KeR6rOEJOuFuOuTnA0KICAgICwgbGFiZWxzID0g7KSR6rCE7KeR6rOEJOuFuOuTnA0KICAgICwgcGFyZW50cyA9IHJlcChuYW1lcyjspJHqsITrtoTrpZgpLCBucm93KOykkeqwhOynkeqzhCkpDQogICAgLCB2YWx1ZXMgPSDspJHqsITsp5Hqs4Qkbg0KICAgICwgbWF4ZGVwdGggPSAzDQogICAgLCBkb21haW4gPSBsaXN0KHJvdz1hcy5pbnRlZ2VyKGkvMiksIGNvbHVtbj1pJSUyKQ0KICApDQp9DQoNCiMg7Lac66ClDQp0bSAlPiUgbGF5b3V0KGdyaWQgPSBsaXN0KGNvbHVtbnM9Miwgcm93cz0yKSwgYXV0b3NpemUgPSBULCBmb250ID0gbGlzdChzaXplID0gMTApDQogICAgICAgICAgICAgICwgbWFyZ2luID0gbGlzdChiID0gMCwgbCA9IDAsIHIgPSAwLCB0ID0gMCkpDQpgYGANCg0K64yA67aE66WYIOq4sOykgCDsoJzsobDsl4UgNTQsMzk06rG0LCDruYTsoJzsobDsl4UgMzEsNjgy6rG07J2YIOuztOuPhOqwgCDtmZXsnbjrkJzri6QuDQoNCuykkeu2hOulmCDquLDspIAg7KSR7ZmU7ZWZ6rO17JeF7J20IDMzLDA5OOqxtOycvOuhnCDstZzri6TsnbTrqbAsIOu5hOygnOyhsOyXheyXkOyEnOuKlCDqtJHsl4UgMjAsNjY26rG07J20IOy1nOuLpOydtOuLpC4NCg0K7IaM67aE66WYIOq4sOykgCDtg4TqtJHsnbQgMTQsNTA26rG07Jy866GcIOy1nOuLpOydtOupsCwg7KCc7KGw7JeF7JeQ7ISc64qUIOyErOycoOydmOulmCAxMCwzNTXqsbTsnbQg7LWc64uk7J2064ukLg0KDQrshLjrtoTrpZgg6riw7KSA7Jy866Gc64+EIO2VmOychCDshLjrtoTrpZjqsIAg7JeG64qUIO2DhOq0keydtCAxNCw1MDbqsbTsnLzroZwg7LWc64uk7J2066mwLCDsoJzsobDsl4Xsl5DshJzripQg7KCc7LKgwrfsoJzqsJUgNiwxNzfqsbTsnbQg7LWc64uk7J2064ukLg0KDQojIyMgUS4g67O064+EIOyImCAxMDDsnIQg64K0IOq4sOyXheydmCDsl4XsooUg67aE7Y+s64qUPw0KDQrrs7Trj4Qg7IiYIDEwMOychCDrgrQg6riw7JeF7J2EIOyCtO2OtOuztOuptCDri6TsnYzqs7wg6rCZ64ukLg0KDQpgYGB7ciDrs7Trj4Qg7IiYIOyDgeychCAxMDDsnIQg64K0IOq4sOyXheydmCDsl4XsooV9DQojIOynkeqzhA0K67Cx7JyE6riw7JeF7Y+J6regID0g6rKw7Lih7LmY7KCV66asICU+JSBhcnJhbmdlKGRlc2Mo67O064+E7IiYKSkgJT4lIGhlYWQoMTAwKSAlPiUgDQogIG11dGF0ZSjsl4XsooUgPSBWNikgJT4lIA0KICBncm91cF9ieSjsl4XsooUpICU+JSBzdW1tYXJpc2Uo6riw7JeF7IiYPW4oKSwg7Y+J6reg67O064+E7IiYPW1lYW4o67O064+E7IiYKSkgJT4lIA0KICBhcnJhbmdlKO2Pieq3oOuztOuPhOyImCkNCuuwseychOq4sOyXhSA9IOqysOy4oey5mOygleumrCAlPiUgYXJyYW5nZShkZXNjKOuztOuPhOyImCkpICU+JSBoZWFkKDEwMCkgJT4lIA0KICBtdXRhdGUo7IKw7JeF67aA66y4ID0gVjQNCiAgICAgICAgICwg7JeF7KKFID0gZmFjdG9yKFY2LCBsZXZlbHMgPSDrsLHsnITquLDsl4Xtj4nqt6Ak7JeF7KKFKSwg6riw7JeFID0gVjINCiAgICAgICAgICwg7Iic7JyEID0gcm93X251bWJlcigpLCDsg4HsnIQyMOychCA9IGlmZWxzZSjsiJzsnIQgPiAyMCwgNSwgMTApKSANCuyXheyiheuzhOynkeqzhCA9IOuwseychOq4sOyXhSAlPiUgZ3JvdXBfYnko7JeF7KKFKSAlPiUgDQogIHN1bW1hcmlzZSjquLDsl4XsiJggPSBuKCksIOuztOuPhOyImCA9IHN1bSjrs7Trj4TsiJgpKQ0KDQojIOuwseychOq4sOyXhSDsgrDsoJDrj4QNCnAxID0gcGxvdF9seSgpDQpmb3IgKOu2gOusuCBpbiB1bmlxdWUo67Cx7JyE6riw7JeFJOyCsOyXheu2gOusuCkpIHsNCiAgcDEgPSBwMSAlPiUgYWRkX3RyYWNlKA0KICAgIGRhdGEgPSDrsLHsnITquLDsl4UgJT4lIHN1YnNldCjsgrDsl4XrtoDrrLggPT0g67aA66y4KSwNCiAgICB0eXBlID0gInNjYXR0ZXIiLA0KICAgIG1vZGUgPSAibWFya2VycyIsDQogICAgeCA9IH7rs7Trj4TsiJgsDQogICAgeSA9IH7sl4XsooUsDQogICAgdGV4dCA9IH5wYXN0ZSjquLDsl4UsICI8YnI+67O064+EIOyImDoiLCDrs7Trj4TsiJgsICI8YnI+7Iic7JyEOiIsIOyInOychCksDQogICAgaG92ZXJpbmZvID0gInRleHQiLA0KICAgIG1hcmtlciA9IGxpc3QoDQogICAgICBjb2xvciA9IGlmZWxzZSjrtoDrrLggPT0gIuu5hOygnOyhsOyXhSIsImRhcmtncmVlbiIsICJkYXJrdmlvbGV0IiksDQogICAgICBzaXplID0gfuyDgeychDIw7JyELA0KICAgICAgbGluZSA9IGxpc3Qod2lkdGggPSAwKQ0KICAgICkNCiAgKQ0KfTsgcDEgPSBwMSAlPiUgbGF5b3V0KHlheGlzID0gbGlzdCh0aXRsZT0iIiksIHNob3dsZWdlbmQgPSBGKQ0KDQojIOuwseychOq4sOyXheyXheyihSjshozrtoTrpZgpIO2KuOumrOuntQ0KcDIgPSBwbG90X2x5KA0KICAgIGRhdGEgPSDsl4XsooXrs4Tsp5Hqs4QNCiAgICAsIHR5cGUgPSAidHJlZW1hcCINCiAgICAsIGxhYmVscyA9IH7sl4XsooUNCiAgICAsIHBhcmVudHMgPSByZXAoIiIsIG5yb3co7JeF7KKF67OE7KeR6rOEKSkNCiAgICAsIHZhbHVlcyA9IH7quLDsl4XsiJgNCiAgICAsIHRleHRpbmZvID0gImxhYmVsK3ZhbHVlIg0KICAgICwgZG9tYWluID0gbGlzdChjb2x1bW49MSkNCiAgICAsIG5hbWUgPSAi7JeF7KKF67OEIOq4sOyXhSDsiJgiDQogICkgJT4lIGxheW91dChtYXJnaW4gPSBsaXN0KGIgPSA1LCBsID0gMCwgciA9IDAsIHQgPSA1KSkNCg0KIyDstpzroKUNCmxpYnJhcnkoaHRtbHRvb2xzLCBxdWlldGx5ID0gVCkNCmJyb3dzYWJsZSh0YWdMaXN0KA0KICBkaXYoc3R5bGUgPSAiZGlzcGxheTppbmxpbmUtYmxvY2s7IHdpZHRoOjQ5JTsiLCBwMSksDQogIGRpdihzdHlsZSA9ICJkaXNwbGF5OmlubGluZS1ibG9jazsgd2lkdGg6NDklOyIsIHAyKQ0KKSkNCmBgYA0KDQrrs7Trj4Qg7IiYIDEwMOychCDrgrQg6riw7JeF7J20IOqwgOyepSDrp47snYAg7JeF7KKF7J2AIO2DhOq0kSgyNeqwnCnsnbTri6QuDQoNCuq4sOyXheuLuSDrs7Trj4Qg7IiY6rCAIOqwgOyepSDrp47snYAg6riw7JeF7J2AIDHssKjquIjsho0g7JeF7KKF7JeQIOyGje2VmOupsCwgMuychCwgM+ychCDquLDsl4Xrj4QgMeywqOq4iOyGjSDsl4XsooXsl5Ag7IaN7ZWc64ukLg0KDQrrs7Trj4Qg7IiYIOyDgeychCAyMOychCDrgrQg6riw7JeF7J2YIOu2hO2PrOulvCDsgrTtjrTrs7TrqbQsIDHssKjquIjsho0g7JeF7KKFKDFcfjPsnIQpLCDshKzsnKDsnZjrpZgoNOychCwgMTPsnIQpLCDtmZTtlZkoNeychCwgNuychCwgOOychCksIO2ZlOugpeuwnOyghCg37JyELCA57JyEKSwg7YOE6rSRKDEw7JyELCAxNeychCwgMTfsnIQsIDE47JyEKSwg6riw6rOEKDEx7JyELCAxMuychCksIOqxtOyerCgxNOychCksIOyyoOq0kSgxNuychCksIOyImOugpeuwnOyghCgyMOychCkg65Ox7J2YIOyXheyiheyXkCDtlbTri7ntlZzri6QuDQoNCiMjIyBRLiDrs7Trj4TqsIAg7JeG64qUIOq4sOyXheydmCDsl4XsooXsnYA/DQoNCjIwMTDrhYQg7J207ZuEIOuztOuPhOqwgCDsl4bripQg6riw7JeF7J2YIOyXheyihSDrtoTtj6zripQg64uk7J2M6rO8IOqwmeuLpC4NCg0KYGBge3Ig67O064+EIOyImCDsl4bripQg6riw7JeFIOyXheyihSDrtoTtj6x9DQojIOynkeqzhA0K67O064+E7IiYMOq4sOyXhSA9IOqysOy4oey5mOygleumrCAlPiUgZmlsdGVyKOuztOuPhOyImCA9PSAwKQ0KDQrrs7Trj4TsiJgw6riw7JeF7KeR6rOEID0gYmluZF9yb3dzKA0KICBkYXRhLmZyYW1lKOuFuOuTnCA9ICLsoITssrQiLCDrtoDrqqggPSAiIiwgbiA9IG5yb3co67O064+E7IiYMOq4sOyXhSkpDQogICwg67O064+E7IiYMOq4sOyXhSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY0LCDrtoDrqqggPSAi7KCE7LK0IikgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQogICwg67O064+E7IiYMOq4sOyXhSAlPiUgZmlsdGVyKFY1ICE9ICLrr7jsg4EiKSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY1LCDrtoDrqqggPSBWNCkgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQogICwg67O064+E7IiYMOq4sOyXhSAlPiUgZmlsdGVyKFY2ICE9ICLrr7jsg4EiKSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY2LCDrtoDrqqggPSBWNSkgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQogICwg67O064+E7IiYMOq4sOyXhSAlPiUgZmlsdGVyKFY3ICE9ICLrr7jsg4EiKSAlPiUgbXV0YXRlKOuFuOuTnCA9IFY3LCDrtoDrqqggPSBWNikgJT4lIA0KICAgIGdyb3VwX2J5KOu2gOuqqCwg64W465OcKSAlPiUgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQopDQoNCiMg6re4656Y7ZSEDQpQbHMgPSAyOjMgJT4lIGxhcHBseSgNCiAgZnVuY3Rpb24oaSkgew0KICAgIOuztOuPhOyXhuydjOu5hOycqCA9IG1lcmdlKA0KICAgICAg6riw7JeF7IiY7KeR6rOEICU+JSANCiAgICAgICAgZmlsdGVyKOuFuOuTnCAlaW4lIHVuaXF1ZSjqsrDsuKHsuZjsoJXrpqxbW+u2hOulmFtpXV1dKSAmIOuFuOuTnCAhPSDrtoDrqqgpICU+JSANCiAgICAgICAgbXV0YXRlKOyghOyytCA9IG4pICU+JSBzZWxlY3Qo64W465OcLCDsoITssrQpDQogICAgICAsIOuztOuPhOyImDDquLDsl4Xsp5Hqs4QgJT4lIA0KICAgICAgICBmaWx0ZXIo64W465OcICVpbiUgdW5pcXVlKOqysOy4oey5mOygleumrFtb67aE66WYW2ldXV0pICYg64W465OcICE9IOu2gOuqqCkgJT4lIA0KICAgICAgICBtdXRhdGUo67O064+E7JeG7J2MID0gbikgJT4lIHNlbGVjdCjrhbjrk5wsIOuztOuPhOyXhuydjCkNCiAgICAgICwgYnkgPSAi64W465OcIg0KICAgICkgJT4lIGZpbHRlcijsoITssrQgPj0gNTApICU+JSANCiAgICAgIG11dGF0ZSjrs7Trj4Tsl4bsnYzruYTsnKggPSDrs7Trj4Tsl4bsnYwgLyDsoITssrQgKiAxMDApICU+JSANCiAgICAgIGFycmFuZ2UoZGVzYyjrs7Trj4Tsl4bsnYzruYTsnKgpKQ0KICAgIOuztOuPhOyXhuydjOu5hOycqCA9IOuztOuPhOyXhuydjOu5hOycqCAlPiUgbXV0YXRlKOuFuOuTnCA9IGZhY3Rvcijrhbjrk5wsIGxldmVscyA9IOuFuOuTnCkpDQogICAgcGxvdF9seSgNCiAgICAgIGRhdGEgPSDrs7Trj4Tsl4bsnYzruYTsnKgNCiAgICAgICwgdHlwZSA9ICJiYXIiDQogICAgICAsIHggPSB+67O064+E7JeG7J2M67mE7JyoDQogICAgICAsIHkgPSB+64W465OcDQogICAgICAsIG1hcmtlciA9IGxpc3QoY29sb3IgPSB+67O064+E7JeG7J2M67mE7JyoLCBjb2xvcnNjYWxlID0gIlZpcmlkaXMiKQ0KICAgICAgLCB0ZXh0ID0gfnBhc3RlMChzbWFsbCjrs7Trj4Tsl4bsnYzruYTsnKgpLCAiJSIpDQogICAgICAsIGhvdmVyaW5mbyA9ICJ0ZXh0IiANCiAgICAgICwgbmFtZSA9IG5hbWVzKOu2hOulmClbaV0NCiAgICAgICwgaGVpZ2h0ID0gNjAwDQogICAgKSAlPiUgbGF5b3V0KGZvbnQgPSBsaXN0KHNpemUgPSA5KQ0KICAgICAgICAgICAgICAgICAsIG1hcmdpbiA9IGxpc3QoYiA9IDEwLCBsID0gNSwgciA9IDUsIHQgPSAyNSkpDQogIH0NCikgDQoNCiMg7Lac66ClDQpzdWJwbG90KFBscywgc2hhcmVYID0gVCwgc2hhcmVZID0gRiwgbnJvd3MgPSAyLCBoZWlnaHRzID0gYygwLjQsIDAuNikpICU+JSANCiAgbGF5b3V0KHNob3dsZWdlbmQgPSBGDQogICAgICAgICAsIHhheGlzID0gbGlzdCh0aXRsZSA9ICIyMDEw64WEIOydtO2bhCDrs7Trj4TrkJjsp4Ag7JWK7J2AIOu5hOycqCglKSIpDQogICAgICAgICAsIHRpdGxlID0gbGlzdCh0ZXh0ID0gIuyGjOu2hOulmCjsnIQpLCDshLjrtoTrpZgo7JWE656YKSINCiAgICAgICAgICAgICAgICAgICAgICAgICwgZm9udCA9IGxpc3Qoc2l6ZSA9IDksIGNvbG9yID0gImJsYWNrIikNCiAgICAgICAgICAgICAgICAgICAgICAgICwgeGFuY2hvciA9ICJsZWZ0IiwgeCA9IDAuMDUpKQ0KYGBgDQoNCjIwMTDrhYQg7J207ZuEIOuztOuPhOuQmOyngCDslYrsnYAg6riw7JeF7J2YIOu5hOycqOydtCDqsIDsnqUg7YGwIOyXheyiheydgCDshozrtoTrpZgg6riw7KSAIOyImOugpeuwnOyghCg0MC41JSksIOyEuOu2hOulmCDquLDspIAg7KSR7IaM7ZiV7IiY66Cl67Cc7KCEKDQ1LjglKeydtOuLpC4NCg0K7IaM67aE66WYIOq4sOykgOycvOuhnOuKlCDqsIDqtawsIOuqqeyerCwg7KKF7J20IOuwjyDsnqHsoJztkogoMzEuNSUpLCDsoITquLDsoITsnpAoMzElKSwg7IiY7Iah6riw6rOEKDMwLjMlKSDrk7HsnZgg67mE7Jyo64+EIOuGkuydgCDtjrjsnbTri6QuDQoNCuyEuOu2hOulmCDquLDspIDsnLzroZzripQg7KCE7J6QwrdJQ1QoNDAlKSwg7J6h7KCc7ZKIKDM2LjQlKSDrk7HsnZgg67mE7Jyo64+EIOuGkuydgCDtjrjsnbTri6QuDQo=