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개 변수를 살펴보면 크게 기업명칭, 기업분류, 기업위치, 출처 및 보도 수로 구분할 수 있다.

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=