第3週

12/21(TH) 不平等を無くすために何をするべきか1

       不平等を無くすために何をするべきか2

講義では、所得の世界的格差の現状を踏まえて、高所得者に対する資産課税、金融取引税の可能性について議論します。

01/09(TU) Rでデータサイエンス3:GNI係数と所得分布  [Main]・[授業]

Poverty and Inequality―Distribution of income or consumption(データが少ない難点)

GINI index (World Bank estimate);SI.POV.GINI [Link]

Income share held by lowest 10%:SI.DST.FRST.10 [Link]

Income share held by lowest 20%:SI.DST.FRST.20 [Link]

Income share held by second 20%:SI.DST.02ND.20 [Link]

Income share held by third 20%:SI.DST.03RD.20 [Link]

Income share held by fourth 20%:SI.DST.04TH.20 [Link]

Income share held by highest 20%:SI.DST.05TH.20 [Link]

Income share held by highest 10%:SI.DST.10TH.10 [Link]

指標について

  • GINI index (World Bank estimate);SI.POV.GINI [Link]

    • Gini index measures the extent to which the distribution of income (or, in some cases, consumption expenditure) among individuals or households within an economy deviates from a perfectly equal distribution. A Lorenz curve plots the cumulative percentages of total income received against the cumulative number of recipients, starting with the poorest individual or household. The Gini index measures the area between the Lorenz curve and a hypothetical line of absolute equality, expressed as a percentage of the maximum area under the line. Thus a Gini index of 0 represents perfect equality, while an index of 100 implies perfect inequality.

    • ジニ指数は、経済内の個人または世帯間の所得(または場合によっては消費支出)の分布が、完全に平等な分布からどの程度逸脱しているかを測定する。ローレンツ曲線は、最も貧しい個人または世帯から始まり、受給者の累積数に対する総所得の累積割合をプロットしたものである。ジニ指数は、ローレンツ曲線と絶対的平等の仮想線との間の面積を測定するもので、線の下の最大面積の百分率で表される。したがって、ジニ指数0は完全な平等を表し、指数100は完全な不平等を意味する。

  • Income share held by lowest 10%:SI.DST.FRST.10 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles.

    • 所得または消費の割合は、デシルまたは五分位数で示される人口のサブグループに発生する割合です。

  • Income share held by lowest 20%:SI.DST.FRST.20 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles. Percentage shares by quintile may not sum to 100 because of rounding.

    • 所得または消費の割合は、デシルまたは五分位数で示される人口のサブグループに発生する割合です。五分位数によるシェアの割合は、四捨五入のため100にならない場合があります。(Apple)

  • Income share held by second 20%:SI.DST.02ND.20 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles. Percentage shares by quintile may not sum to 100 because of rounding.

    • 所得または消費に占める割合は、10分位または5分位で示される人口のサブグループに帰属する割合である。四捨五入の関係上、五分位階級別の割合の合計が100にならない場合がある。(DeepL)

  • Income share held by third 20%:SI.DST.03RD.20 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles. Percentage shares by quintile may not sum to 100 because of rounding.

    • 所得または消費に占める割合は、10分位または5分位で示される人口のサブグループに帰属する割合である。四捨五入の関係上、五分位階級別の割合の合計が100にならない場合がある。(DeepL)

  • Income share held by fourth 20%:SI.DST.04TH.20 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles. Percentage shares by quintile may not sum to 100 because of rounding.

    • 所得または消費の割合は、十分位数または五分位数で示される人口のサブグループに生じる割合です。四捨五入のため、五分位別の割合の合計が 100 にならない場合があります。(Google)

  • Income share held by highest 20%:SI.DST.05TH.20 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles. Percentage shares by quintile may not sum to 100 because of rounding.

    • 所得または消費の割合は、十分位数または五分位数で示される人口のサブグループに生じる割合です。四捨五入のため、五分位別の割合の合計が 100 にならない場合があります。

  • Income share held by highest 10%:SI.DST.10TH.10 [Link]

    • Percentage share of income or consumption is the share that accrues to subgroups of population indicated by deciles or quintiles.

    • 所得または消費の割合は、十分位数または五分位数で示される人口のサブグループに生じる割合です。

内容

library(tidyverse)
── Attaching core tidyverse packages ───────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     ── Conflicts ─────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(WDI)
df_gini <- WDI(indicator = c(gini = "SI.POV.GINI",
                            `0-10` = "SI.DST.FRST.10",
                            `0-20` = "SI.DST.FRST.20",
                            `20-40` = "SI.DST.02ND.20",
                            `40-60` = "SI.DST.03RD.20",
                            `60-80` = "SI.DST.04TH.20",
                            `80-100` = "SI.DST.05TH.20",
                            `90-100` = "SI.DST.10TH.10"))
df_gini
write_csv(df_gini, "data/gini.csv")
df_gini <- read_csv("data/gini.csv")
Rows: 16758 Columns: 12── Column specification ─────────────────────────────────────────────────
Delimiter: ","
chr (3): country, iso2c, iso3c
dbl (9): year, gini, 0-10, 0-20, 20-40, 40-60, 60-80, 80-100, 90-100
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
df_gini_long <- df_gini |> 
  pivot_longer(-(1:5), names_to = "levels", values_to = "value")
df_gini_long

どのくらい GINI のデータがあるか確かめる

df_gini |> group_by(year) |> drop_na(gini) |> 
  summarize(n = n()) |>
  ggplot(aes(year, n)) + geom_col()

実際のデータの個数も計算してみる。

df_gini_long |> 
  group_by(year, levels) |> drop_na(value) |>
  summarize(num = n()) |> distinct(year, num) |> arrange(desc(year))
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

GINIだけでなく、他の値についても調べる。

df_gini_long |> 
  group_by(year, levels) |> drop_na(value) |>
  summarize(num = n()) |> distinct(year, num) |> 
  ggplot(aes(year, num)) + geom_col()
`summarise()` has grouped output by 'year'. You can override using the `.groups` argument.

2022年は、7カ国分しかデータがないがその国名を表示する。

df_gini_long |> filter(year == 2022) |> drop_na(gini) |>
  distinct(country, gini)
COUNTRY_GINI <- "Bangladesh"
YEAR_GINI <- 2022
df_gini_long |> 
  filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value)) + geom_col()

COUNTRY_GINI <- "Bhutan"
YEAR_GINI <- 2022
df_gini_long |> 
  filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value)) + geom_col()

COUNTRY_GINI <- "Costa Rica"
YEAR_GINI <- 2022
df_gini_long |> 
  filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value)) + geom_col()

GINI って何!?

ジニ係数(ジニけいすう、: Gini coefficient)とは主に社会における所得の不平等さを測る指標である。0から1で表され、各人の所得が均一で格差が全くない状態を0、たった一人が全ての所得を独占している状態を1とする。ローレンツ曲線をもとに、1912年にイタリアの統計学者、コッラド・ジニによって考案された。それ以外にも、富の偏在性やエネルギー消費における不平等さなどに応用される。(Wikipedia)

ジニ係数のグラフ ジニ係数は、Aの面積をABの各面積の合計で割ったものに等しい。すなわち、ジニ係数 =A/(A+B)となる。また、A+B=0.5のため、2×Aにも等しい(縦軸は0と1の間の値をとるため)

Derivation of the Lorenz curve and Gini coefficient for global income in 2011 [リンク]

df_gini_calc <- df_gini |> 
  mutate(`0` = 0, `10` = `0-10`, `20` = `0-20`, `40` = `0-20` + `20-40`, `60` = `0-20` + `20-40` + `40-60`, `80` = `0-20` + `20-40` + `40-60` + `60-80`, `90` = `0-20` + `20-40` + `40-60` + `60-80` + `80-100`-`90-100`, `100` = 100) 
df_gini_calc %>% drop_na() |> filter(country == "Bangladesh")
df_gini_calc_long <- df_gini_calc |>  pivot_longer(`0`:`100`, names_to = "classes", values_to = "cumulative_share") |> mutate(classes = as.numeric(classes))
df_gini_calc_long %>% drop_na() |> filter(country == "Bangladesh")

確認

df_gini_calc_long |> filter(country == "Bangladesh") |> 
  filter(year == 2022) |> ggplot() + geom_line(aes(classes, cumulative_share)) + geom_segment(aes(x = 0, y = 0, xend = 100, yend = 100), color = 'red') + 
  scale_x_continuous(breaks = seq(0,100,by=20)) + 
  scale_y_continuous(breaks = seq(0,100,by=20)) #+

  #annotate("text", x = 10, y = 80, label = gini)

Shade region between two lines with ggplot: [リンク]

df_gini_calc |> group_by(country, year) |> 
  drop_na(gini) |>
  summarize(gini, gini_trapezoid = 100-(2*`10` + 3*`20` + 4*`40` + 4*`60` + 3*`80` + 2*`90` + 100)/10) |> 
  distinct(country, year, gini, gini_trapezoid)
`summarise()` has grouped output by 'country'. You can override using the `.groups` argument.
#### For the calcualtion of the area under the curve
    #### Trapezoidal rule
    trapezoid <- function(x, y) {
                     sum(diff(x)*(y[-1]+y[-length(y)]))/2
                 }
    #### Simpson's rule: more accurate
    simpson <- function(x, y){
                   n <- length(y)
                   odd <- n %% 2
                   if (odd)
                       area <- 1/3*sum( y[1] + 2*sum(y[seq(3,(n-2),by=2)]) + 4*sum(y[seq(2,(n-1),by=2)]) + y[n])
                   if (!odd)
                       area <- 1/3*sum( y[1] + 2*sum(y[seq(3,(n-3),by=2)]) + 4*sum(y[seq(2,(n-2),by=2)]) + y[n-1]) + 1/2*(y[n-1] + y[n])
                   dx <- x[2] - x[1]
                   return(area * dx)
    }
    
SIMPSON <- function(x, h=1){
  # AUC function computes the Area Under the Curve of a time serie using
  # the Simpson's Rule (numerical method).
  # https://link.springer.com/chapter/10.1007/978-1-4612-4974-0_26
  
  # Arguments
  # x: (vector) time serie values
  # h: (int) temporal resolution of the time serie. default h=1
  
  n = length(x)-1
  
  xValues = seq(from=1, to=n, by=2)
  
  sum <- list()
  for(i in 1:length(xValues)){
    n_sub <- xValues[[i]]-1
    n <- xValues[[i]]
    n_add <- xValues[[i]]+1
    
    v1 <- x[[n_sub+1]]
    v2 <- x[[n+1]]
    v3 <- x[[n_add+1]]
    
    s <- (h/3)*(v1+4*v2+v3)
    sum <- append(sum, s)
  }
  sum <- unlist(sum)
  
  auc <- sum(sum)
  
  return(auc)
  
}
simpson(c(0,0.2,0.4,0.6,0.8,1),c(0,0.04,0.16,0.36,0.64,1))
[1] 0.3346667
library(DescTools)

Area Under the Curve: [リンク]

https://rdrr.io/cran/DescTools/f/

df_gini_calc_long |> group_by(country, year) |> 
  drop_na(gini) |>
  summarize(gini, gini_spline = round(100-AUC(classes, cumulative_share, method = "spline")/50, digits = 1), gini_trapezoid = round(100-AUC(classes, cumulative_share)/50, digits = 1), gini_simpson = round(100 - simpson(classes, cumulative_share)/50, digits = 1)) |> 
  distinct(country, year, gini, gini_spline, gini_trapezoid, gini_simpson)
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'country', 'year'. You can override using the `.groups` argument.
df_gini_calc_long |> group_by(country, year) |> 
  drop_na(gini) |>
  summarize(gini, gini_spline = round(100-AUC(classes, cumulative_share, method = "spline")/50, digits = 1), gini_trapezoid = round(100-AUC(classes, cumulative_share)/50, digits = 1), gini_simpson = round(100 - simpson(classes, cumulative_share)/50, digits = 1)) |> 
  distinct(country, year, gini, gini_spline, gini_trapezoid, gini_simpson)
Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
Please use `reframe()` instead.
When switching from `summarise()` to `reframe()`, remember that `reframe()` always returns an ungrouped data frame and adjust accordingly.`summarise()` has grouped output by 'country', 'year'. You can override using the `.groups` argument.

AUC: Calculating Area under a Curve [リンク]

https://www.statsdirect.com/help/default.htm#nonparametric_methods/gini.htm

GINI Calculator

x に、数の列を入れるとその分配に関する、GINI を計算します。

x <- c(1,1,1,4,10)
Lc(x)[c(1,2)] |> as.tibble() |> mutate(d = p, .after = 1) |> 
  pivot_longer(-1, names_to = "name", values_to = "value") |>
  ggplot(aes(p, value, fill = name)) + geom_area(position = "identity") +
  annotate("text", x = 0.25, y = 0.75, label = paste("GINI = ",round(Lc(x)$Gini, digits = 2)))

SER <- c(0,5,3,1,1)
SER1 <- c(0,sort(SER))
SER1
[1] 0 0 1 1 3 5
N = length(SER1)
Y <- 0:N/N; Y
[1] 0.0000000 0.1666667 0.3333333 0.5000000 0.6666667 0.8333333 1.0000000

定義にもどって要確認

df_gini_long |> filter(year == 2022) |> drop_na(gini)

他の見せ方に修正

df_gini_long |> filter(year == 2022) |> drop_na(gini) |>
  ggplot(aes(x = levels, y = adj, col = country)) + geom_line()

和をとったものを計算しないといけない。以下はあとで利用

df_gini_long <- df_gini |> 
  pivot_longer(-(1:5), names_to = "levels", values_to = "value") |>
  mutate(levels = as.numeric(levels)) |> 
  mutate(cut = case_when(levels == 5 ~ '0-10',
                         levels == 10 ~ '0-20',
                         levels == 30 ~ '20-40',
                         levels == 50 ~ '40-60',
                         levels == 70 ~ '60-80',
                         levels == 90 ~ '80-100',
                         levels == 95 ~ '90-100'),
         adj = case_when(levels == 5 ~ value*2,
                         levels == 95 ~ value*2,
                         .default = value))
df_gini_long
df_gini_rev <- WDI(indicator = c(gini = "SI.POV.GINI",
                            '0-10' = "SI.DST.FRST.10",
                            '0-20' = "SI.DST.FRST.20",
                            '20-40' = "SI.DST.02ND.20",
                            '40-60' = "SI.DST.03RD.20",
                            '60-80' = "SI.DST.04TH.20",
                            '80-100' = "SI.DST.05TH.20",
                            '90-100' = "SI.DST.10TH.10"))
df_gini_rev_long <- df_gini_rev |> 
  pivot_longer(-(1:5), names_to = "levels", values_to = "value")
df_gini_rev_long
COUNTRY_GINI <- "Bangladesh"
YEAR_GINI <- 2022
df_gini_rev_long |> 
  filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value)) + geom_col()

df_gini_rev_long2 <- df_gini_rev |> drop_na(gini) |> 
  mutate('0-10' = `0-10` *2, '90-100' = `90-100` *2) |>
  pivot_longer(-(1:5), names_to = "levels", values_to = "value")
COUNTRY_GINI <- "Bangladesh"
YEAR_GINI <- 2022
df_gini_rev_long2 |> 
  filter(country == COUNTRY_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value)) + geom_col()

COUNTRIES_GINI <- c("Bhutan", "Bangladesh","Indonesia","Costa Rica")
YEAR_GINI <- 2022
df_gini_rev_long2 |> 
  filter(country %in% COUNTRIES_GINI, year == YEAR_GINI) |>
  ggplot(aes(levels, value, fill = factor(country, levels = COUNTRIES_GINI))) + geom_col(position = "dodge") + labs(fill = "")

YEAR_GINI <- 2000
df_gini_rev |> 
  filter(year == YEAR_GINI) |> drop_na(gini) |>
  ggplot(aes(gini, `90-100`)) + geom_point() + geom_smooth(method = "lm")

YEAR_GINI <- 2000
df_gini_rev |> 
  filter(year == YEAR_GINI) |> drop_na(gini) |>
  ggplot(aes(gini, `80-100`)) + geom_point() + geom_smooth(method = "lm")

YEAR_GINI <- 2000
df_gini_rev |> filter(year == YEAR_GINI) |> drop_na(gini) |>
  ggplot(aes(gini)) + geom_histogram(binwidth = 5)

To Do

df_gini_rev |> filter(iso2c == "ID", year == 2022)
df_gini_rev  |> mutate('10-20' = `0-20`-`0-10`, .before = `0-20`) |> mutate('80-90' = `80-100`-`90-100`, .before = `80-100`) |> select(-c(`0-20`, `80-100`)) |>
  filter(iso2c == "ID", year == 2022)
df_gini_rev  |> mutate('10-20' = `0-20`-`0-10`, .before = `0-20`) |> mutate('80-90' = `80-100`-`90-100`, .before = `80-100`) |> select(-c(`0-20`, `80-100`)) |>
  pivot_longer(-(1:5), names_to = "range", values_to = "value") |> 
  filter(iso2c == "ID", year == 2022) |> pull() |> 
  append(0,0) |> Gini(weights = c(1,1,1,2,2,2,1,1))
[1] 0.4137295

37.9

df_gini_rev  |> mutate('10-20' = `0-20`-`0-10`, .before = `0-20`) |> mutate('80-90' = `80-100`-`90-100`, .before = `80-100`) |> select(-c(`0-20`, `80-100`)) |>
  pivot_longer(-(1:5), names_to = "range", values_to = "value") |> 
  filter(iso2c == "ID", year == 2022) |> pull() -> id
Gini(c(0.5,1.5,3,5,7,8.5,9.5), id, conf.level=0.95, unbiased=FALSE)
     gini    lwr.ci    upr.ci 
0.2138977 0.1187878 0.3806978 
LS0tCnRpdGxlOiAiR0VTIDAwMSDmvJTnv5IzIgphdXRob3I6ICJILiBTdXp1a2kiCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojIyDnrKwz6YCxCgoxMi8yMShUSCnjgIDkuI3lubPnrYnjgpLnhKHjgY/jgZnjgZ/jgoHjgavkvZXjgpLjgZnjgovjgbnjgY3jgYsxCgrjgIDjgIDjgIDjgIDjgIAgwqDkuI3lubPnrYnjgpLnhKHjgY/jgZnjgZ/jgoHjgavkvZXjgpLjgZnjgovjgbnjgY3jgYsyCgrorJvnvqnjgafjga/jgIHmiYDlvpfjga7kuJbnlYznmoTmoLzlt67jga7nj77nirbjgpLouI/jgb7jgYjjgabjgIHpq5jmiYDlvpfogIXjgavlr77jgZnjgovos4fnlKPoqrLnqI7jgIHph5Hono3lj5blvJXnqI7jga7lj6/og73mgKfjgavjgaTjgYTjgaborbDoq5bjgZfjgb7jgZnjgIIKCjAxLzA5KFRVKeOAgFLjgafjg4fjg7zjgr/jgrXjgqTjgqjjg7Pjgrkz77yaR05J5L+C5pWw44Go5omA5b6X5YiG5biD44CAIFtbTWFpbl0oaHR0cHM6Ly9kcy1zbC5naXRodWIuaW8vaW50cm8yci9nZXMwMDEvZ2VzMDAxLW1haW4ubmIuaHRtbCld44O7W+aOiOalrV0KCioqUG92ZXJ0eSBhbmQgSW5lcXVhbGl0eeKAlURpc3RyaWJ1dGlvbiBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb27vvIjjg4fjg7zjgr/jgYzlsJHjgarjgYTpm6PngrnvvIkqKgoKR0lOSSBpbmRleCAoV29ybGQgQmFuayBlc3RpbWF0ZSnvvJtTSS5QT1YuR0lOSSBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5QT1YuR0lOSSldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSBsb3dlc3QgMTAl77yaU0kuRFNULkZSU1QuMTAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuRlJTVC4xMCldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSBsb3dlc3QgMjAl77yaU0kuRFNULkZSU1QuMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuRlJTVC4yMCldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSBzZWNvbmQgMjAl77yaU0kuRFNULjAyTkQuMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuMDJORC4yMCldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSB0aGlyZCAyMCXvvJpTSS5EU1QuMDNSRC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMDNSRC4yMCldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSBmb3VydGggMjAl77yaU0kuRFNULjA0VEguMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuMDRUSC4yMCldCgpJbmNvbWUgc2hhcmUgaGVsZCBieSBoaWdoZXN0IDIwJe+8mlNJLkRTVC4wNVRILjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLkRTVC4wNVRILjIwKV0KCkluY29tZSBzaGFyZSBoZWxkIGJ5IGhpZ2hlc3QgMTAl77yaU0kuRFNULjEwVEguMTAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjEwVEguMTApXQoKIyMjIOaMh+aomeOBq+OBpOOBhOOBpgoKLSAgIEdJTkkgaW5kZXggKFdvcmxkIEJhbmsgZXN0aW1hdGUp77ybU0kuUE9WLkdJTkkgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuUE9WLkdJTkkpXQoKICAgIC0gICBHaW5pIGluZGV4IG1lYXN1cmVzIHRoZSBleHRlbnQgdG8gd2hpY2ggdGhlIGRpc3RyaWJ1dGlvbiBvZiBpbmNvbWUgKG9yLCBpbiBzb21lIGNhc2VzLCBjb25zdW1wdGlvbiBleHBlbmRpdHVyZSkgYW1vbmcgaW5kaXZpZHVhbHMgb3IgaG91c2Vob2xkcyB3aXRoaW4gYW4gZWNvbm9teSBkZXZpYXRlcyBmcm9tIGEgcGVyZmVjdGx5IGVxdWFsIGRpc3RyaWJ1dGlvbi4gQSBMb3JlbnogY3VydmUgcGxvdHMgdGhlIGN1bXVsYXRpdmUgcGVyY2VudGFnZXMgb2YgdG90YWwgaW5jb21lIHJlY2VpdmVkIGFnYWluc3QgdGhlIGN1bXVsYXRpdmUgbnVtYmVyIG9mIHJlY2lwaWVudHMsIHN0YXJ0aW5nIHdpdGggdGhlIHBvb3Jlc3QgaW5kaXZpZHVhbCBvciBob3VzZWhvbGQuIFRoZSBHaW5pIGluZGV4IG1lYXN1cmVzIHRoZSBhcmVhIGJldHdlZW4gdGhlIExvcmVueiBjdXJ2ZSBhbmQgYSBoeXBvdGhldGljYWwgbGluZSBvZiBhYnNvbHV0ZSBlcXVhbGl0eSwgZXhwcmVzc2VkIGFzIGEgcGVyY2VudGFnZSBvZiB0aGUgbWF4aW11bSBhcmVhIHVuZGVyIHRoZSBsaW5lLiBUaHVzIGEgR2luaSBpbmRleCBvZiAwIHJlcHJlc2VudHMgcGVyZmVjdCBlcXVhbGl0eSwgd2hpbGUgYW4gaW5kZXggb2YgMTAwIGltcGxpZXMgcGVyZmVjdCBpbmVxdWFsaXR5LgoKICAgIC0gICDjgrjjg4vmjIfmlbDjga/jgIHntYzmuIjlhoXjga7lgIvkurrjgb7jgZ/jga/kuJbluK/plpPjga7miYDlvpfvvIjjgb7jgZ/jga/loLTlkIjjgavjgojjgaPjgabjga/mtojosrvmlK/lh7rvvInjga7liIbluIPjgYzjgIHlrozlhajjgavlubPnrYnjgarliIbluIPjgYvjgonjganjga7nqIvluqbpgLjohLHjgZfjgabjgYTjgovjgYvjgpLmuKzlrprjgZnjgovjgILjg63jg7zjg6zjg7Pjg4Tmm7Lnt5rjga/jgIHmnIDjgoLosqfjgZfjgYTlgIvkurrjgb7jgZ/jga/kuJbluK/jgYvjgonlp4vjgb7jgorjgIHlj5fntabogIXjga7ntK/nqY3mlbDjgavlr77jgZnjgovnt4/miYDlvpfjga7ntK/nqY3libLlkIjjgpLjg5fjg63jg4Pjg4jjgZfjgZ/jgoLjga7jgafjgYLjgovjgILjgrjjg4vmjIfmlbDjga/jgIHjg63jg7zjg6zjg7Pjg4Tmm7Lnt5rjgajntbblr77nmoTlubPnrYnjga7ku67mg7Pnt5rjgajjga7plpPjga7pnaLnqY3jgpLmuKzlrprjgZnjgovjgoLjga7jgafjgIHnt5rjga7kuIvjga7mnIDlpKfpnaLnqY3jga7nmb7liIbnjofjgafooajjgZXjgozjgovjgILjgZfjgZ/jgYzjgaPjgabjgIHjgrjjg4vmjIfmlbAw44Gv5a6M5YWo44Gq5bmz562J44KS6KGo44GX44CB5oyH5pWwMTAw44Gv5a6M5YWo44Gq5LiN5bmz562J44KS5oSP5ZGz44GZ44KL44CCCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgbG93ZXN0IDEwJe+8mlNJLkRTVC5GUlNULjEwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULkZSU1QuMTApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gu5Ymy5ZCI44Gv44CB44OH44K344Or44G+44Gf44Gv5LqU5YiG5L2N5pWw44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr55m655Sf44GZ44KL5Ymy5ZCI44Gn44GZ44CCCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgbG93ZXN0IDIwJe+8mlNJLkRTVC5GUlNULjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULkZSU1QuMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeODh+OCt+ODq+OBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eZuueUn+OBmeOCi+WJsuWQiOOBp+OBmeOAguS6lOWIhuS9jeaVsOOBq+OCiOOCi+OCt+OCp+OCouOBruWJsuWQiOOBr+OAgeWbm+aNqOS6lOWFpeOBruOBn+OCgTEwMOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCiuOBvuOBmeOAgihBcHBsZSkKCi0gICBJbmNvbWUgc2hhcmUgaGVsZCBieSBzZWNvbmQgMjAl77yaU0kuRFNULjAyTkQuMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuMDJORC4yMCldCgogICAgLSAgIFBlcmNlbnRhZ2Ugc2hhcmUgb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9uIGlzIHRoZSBzaGFyZSB0aGF0IGFjY3J1ZXMgdG8gc3ViZ3JvdXBzIG9mIHBvcHVsYXRpb24gaW5kaWNhdGVkIGJ5IGRlY2lsZXMgb3IgcXVpbnRpbGVzLiBQZXJjZW50YWdlIHNoYXJlcyBieSBxdWludGlsZSBtYXkgbm90IHN1bSB0byAxMDAgYmVjYXVzZSBvZiByb3VuZGluZy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gr5Y2g44KB44KL5Ymy5ZCI44Gv44CBMTDliIbkvY3jgb7jgZ/jga815YiG5L2N44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr5biw5bGe44GZ44KL5Ymy5ZCI44Gn44GC44KL44CC5Zub5o2o5LqU5YWl44Gu6Zai5L+C5LiK44CB5LqU5YiG5L2N6ZqO57Sa5Yil44Gu5Ymy5ZCI44Gu5ZCI6KiI44GMMTAw44Gr44Gq44KJ44Gq44GE5aC05ZCI44GM44GC44KL44CC77yIRGVlcEzvvIkKCi0gICBJbmNvbWUgc2hhcmUgaGVsZCBieSB0aGlyZCAyMCXvvJpTSS5EU1QuMDNSRC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMDNSRC4yMCldCgogICAgLSAgIFBlcmNlbnRhZ2Ugc2hhcmUgb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9uIGlzIHRoZSBzaGFyZSB0aGF0IGFjY3J1ZXMgdG8gc3ViZ3JvdXBzIG9mIHBvcHVsYXRpb24gaW5kaWNhdGVkIGJ5IGRlY2lsZXMgb3IgcXVpbnRpbGVzLiBQZXJjZW50YWdlIHNoYXJlcyBieSBxdWludGlsZSBtYXkgbm90IHN1bSB0byAxMDAgYmVjYXVzZSBvZiByb3VuZGluZy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gr5Y2g44KB44KL5Ymy5ZCI44Gv44CBMTDliIbkvY3jgb7jgZ/jga815YiG5L2N44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr5biw5bGe44GZ44KL5Ymy5ZCI44Gn44GC44KL44CC5Zub5o2o5LqU5YWl44Gu6Zai5L+C5LiK44CB5LqU5YiG5L2N6ZqO57Sa5Yil44Gu5Ymy5ZCI44Gu5ZCI6KiI44GMMTAw44Gr44Gq44KJ44Gq44GE5aC05ZCI44GM44GC44KL44CC77yIRGVlcEzvvIkKCi0gICBJbmNvbWUgc2hhcmUgaGVsZCBieSBmb3VydGggMjAl77yaU0kuRFNULjA0VEguMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuMDRUSC4yMCldCgogICAgLSAgIFBlcmNlbnRhZ2Ugc2hhcmUgb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9uIGlzIHRoZSBzaGFyZSB0aGF0IGFjY3J1ZXMgdG8gc3ViZ3JvdXBzIG9mIHBvcHVsYXRpb24gaW5kaWNhdGVkIGJ5IGRlY2lsZXMgb3IgcXVpbnRpbGVzLiBQZXJjZW50YWdlIHNoYXJlcyBieSBxdWludGlsZSBtYXkgbm90IHN1bSB0byAxMDAgYmVjYXVzZSBvZiByb3VuZGluZy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gu5Ymy5ZCI44Gv44CB5Y2B5YiG5L2N5pWw44G+44Gf44Gv5LqU5YiG5L2N5pWw44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr55Sf44GY44KL5Ymy5ZCI44Gn44GZ44CC5Zub5o2o5LqU5YWl44Gu44Gf44KB44CB5LqU5YiG5L2N5Yil44Gu5Ymy5ZCI44Gu5ZCI6KiI44GMIDEwMCDjgavjgarjgonjgarjgYTloLTlkIjjgYzjgYLjgorjgb7jgZnjgIIoR29vZ2xlKQoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGhpZ2hlc3QgMjAl77yaU0kuRFNULjA1VEguMjAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjA1VEguMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeWNgeWIhuS9jeaVsOOBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eUn+OBmOOCi+WJsuWQiOOBp+OBmeOAguWbm+aNqOS6lOWFpeOBruOBn+OCgeOAgeS6lOWIhuS9jeWIpeOBruWJsuWQiOOBruWQiOioiOOBjCAxMDAg44Gr44Gq44KJ44Gq44GE5aC05ZCI44GM44GC44KK44G+44GZ44CCCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgaGlnaGVzdCAxMCXvvJpTSS5EU1QuMTBUSC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMTBUSC4xMCldCgogICAgLSAgIFBlcmNlbnRhZ2Ugc2hhcmUgb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9uIGlzIHRoZSBzaGFyZSB0aGF0IGFjY3J1ZXMgdG8gc3ViZ3JvdXBzIG9mIHBvcHVsYXRpb24gaW5kaWNhdGVkIGJ5IGRlY2lsZXMgb3IgcXVpbnRpbGVzLgoKICAgIC0gICDmiYDlvpfjgb7jgZ/jga/mtojosrvjga7libLlkIjjga/jgIHljYHliIbkvY3mlbDjgb7jgZ/jga/kupTliIbkvY3mlbDjgafnpLrjgZXjgozjgovkurrlj6Pjga7jgrXjg5bjgrDjg6vjg7zjg5fjgavnlJ/jgZjjgovlibLlkIjjgafjgZnjgIIKCiMjIOWGheWuuQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KFdESSkKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CmRmX2dpbmkgPC0gV0RJKGluZGljYXRvciA9IGMoZ2luaSA9ICJTSS5QT1YuR0lOSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgMC0xMGAgPSAiU0kuRFNULkZSU1QuMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDAtMjBgID0gIlNJLkRTVC5GUlNULjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAyMC00MGAgPSAiU0kuRFNULjAyTkQuMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDQwLTYwYCA9ICJTSS5EU1QuMDNSRC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgNjAtODBgID0gIlNJLkRTVC4wNFRILjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGA4MC0xMDBgID0gIlNJLkRTVC4wNVRILjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGA5MC0xMDBgID0gIlNJLkRTVC4xMFRILjEwIikpCmBgYAoKYGBge3J9CmRmX2dpbmkKYGBgCgpgYGB7ciBldmFsID0gRkFMU0V9CndyaXRlX2NzdihkZl9naW5pLCAiZGF0YS9naW5pLmNzdiIpCmBgYAoKYGBge3J9CmRmX2dpbmkgPC0gcmVhZF9jc3YoImRhdGEvZ2luaS5jc3YiKQpgYGAKCmBgYHtyfQpkZl9naW5pX2xvbmcgPC0gZGZfZ2luaSB8PiAKICBwaXZvdF9sb25nZXIoLSgxOjUpLCBuYW1lc190byA9ICJsZXZlbHMiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKQpkZl9naW5pX2xvbmcKYGBgCgrjganjga7jgY/jgonjgYQgR0lOSSDjga7jg4fjg7zjgr/jgYzjgYLjgovjgYvnorrjgYvjgoHjgosKCmBgYHtyfQpkZl9naW5pIHw+IGdyb3VwX2J5KHllYXIpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgc3VtbWFyaXplKG4gPSBuKCkpIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBuKSkgKyBnZW9tX2NvbCgpCmBgYAoK5a6f6Zqb44Gu44OH44O844K/44Gu5YCL5pWw44KC6KiI566X44GX44Gm44G/44KL44CCCgpgYGB7cn0KZGZfZ2luaV9sb25nIHw+IAogIGdyb3VwX2J5KHllYXIsIGxldmVscykgfD4gZHJvcF9uYSh2YWx1ZSkgfD4KICBzdW1tYXJpemUobnVtID0gbigpKSB8PiBkaXN0aW5jdCh5ZWFyLCBudW0pIHw+IGFycmFuZ2UoZGVzYyh5ZWFyKSkKYGBgCgpHSU5J44Gg44GR44Gn44Gq44GP44CB5LuW44Gu5YCk44Gr44Gk44GE44Gm44KC6Kq/44G544KL44CCCgpgYGB7cn0KZGZfZ2luaV9sb25nIHw+IAogIGdyb3VwX2J5KHllYXIsIGxldmVscykgfD4gZHJvcF9uYSh2YWx1ZSkgfD4KICBzdW1tYXJpemUobnVtID0gbigpKSB8PiBkaXN0aW5jdCh5ZWFyLCBudW0pIHw+IAogIGdncGxvdChhZXMoeWVhciwgbnVtKSkgKyBnZW9tX2NvbCgpCmBgYAoKMjAyMuW5tOOBr+OAgTfjgqvlm73liIbjgZfjgYvjg4fjg7zjgr/jgYzjgarjgYTjgYzjgZ3jga7lm73lkI3jgpLooajnpLrjgZnjgovjgIIKCmBgYHtyfQpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKHllYXIgPT0gMjAyMikgfD4gZHJvcF9uYShnaW5pKSB8PgogIGRpc3RpbmN0KGNvdW50cnksIGdpbmkpCmBgYAoKYGBge3J9CkNPVU5UUllfR0lOSSA8LSAiQmFuZ2xhZGVzaCIKWUVBUl9HSU5JIDwtIDIwMjIKZGZfZ2luaV9sb25nIHw+IAogIGZpbHRlcihjb3VudHJ5ID09IENPVU5UUllfR0lOSSwgeWVhciA9PSBZRUFSX0dJTkkpIHw+CiAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpCmBgYAoKYGBge3J9CkNPVU5UUllfR0lOSSA8LSAiQmh1dGFuIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gCiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJDb3N0YSBSaWNhIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gCiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgojIyBHSU5JIOOBo+OBpuS9le+8ge+8nwoKKirjgrjjg4vkv4LmlbAqKu+8iOOCuOODi+OBkeOBhOOBmeOBhuOAgVvoi7FdKGh0dHBzOi8vamEud2lraXBlZGlhLm9yZy93aWtpLyVFOCU4QiVCMSVFOCVBQSU5RSAi6Iux6KqeIik6wqBHaW5pIGNvZWZmaWNpZW5077yJ44Go44Gv5Li744Gr56S+5Lya44Gr44GK44GR44KL5omA5b6X44Gu5LiN5bmz562J44GV44KS5ris44KL5oyH5qiZ44Gn44GC44KL44CCMOOBi+OCiTHjgafooajjgZXjgozjgIHlkITkurrjga7miYDlvpfjgYzlnYfkuIDjgafmoLzlt67jgYzlhajjgY/jgarjgYTnirbmhYvjgpIw44CB44Gf44Gj44Gf5LiA5Lq644GM5YWo44Gm44Gu5omA5b6X44KS54us5Y2g44GX44Gm44GE44KL54q25oWL44KSMeOBqOOBmeOCi+OAguODreODvOODrOODs+ODhOabsue3muOCkuOCguOBqOOBq+OAgTE5MTLlubTjgavjgqTjgr/jg6rjgqLjga7ntbHoqIjlrabogIXjgIHjgrPjg4Pjg6njg4njg7vjgrjjg4vjgavjgojjgaPjgabogIPmoYjjgZXjgozjgZ/jgILjgZ3jgozku6XlpJbjgavjgoLjgIHlr4zjga7lgY/lnKjmgKfjgoTjgqjjg43jg6vjgq7jg7zmtojosrvjgavjgYrjgZHjgovkuI3lubPnrYnjgZXjgarjganjgavlv5znlKjjgZXjgozjgovjgILvvIhXaWtpcGVkaWHvvIkKCiFbXShpbWFnZXMvY2xpcGJvYXJkLTcxOTg4Njg1NS5wbmcpCgrjgrjjg4vkv4LmlbDjga7jgrDjg6njg5Ug44K444OL5L+C5pWw44Gv44CBKkEq44Gu6Z2i56mN44KSKkEq44GoKkIq44Gu5ZCE6Z2i56mN44Gu5ZCI6KiI44Gn5Ymy44Gj44Gf44KC44Gu44Gr562J44GX44GE44CC44GZ44Gq44KP44Gh44CB44K444OL5L+C5pWwID0qQSov77yIKkEqKypCKu+8ieOBqOOBquOCi+OAguOBvuOBn+OAgSpBKisqQio9MC4144Gu44Gf44KB44CBMsOXKkEq44Gr44KC562J44GX44GE77yI57im6Lu444GvMOOBqDHjga7plpPjga7lgKTjgpLjgajjgovjgZ/jgoHvvIkKCiFbXShpbWFnZXMvY2xpcGJvYXJkLTQzNjU1NDM2OC5wbmcpCgpEZXJpdmF0aW9uIG9mIHRoZSBMb3JlbnogY3VydmUgYW5kIEdpbmkgY29lZmZpY2llbnQgZm9yIGdsb2JhbCBpbmNvbWUgaW4gMjAxMSBbW+ODquODs+OCr10oaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9lL2U3L0xvcmVuel9jdXJ2ZV9nbG9iYWxfaW5jb21lXzIwMTEuc3ZnKV0KCmBgYHtyfQpkZl9naW5pX2NhbGMgPC0gZGZfZ2luaSB8PiAKICBtdXRhdGUoYDBgID0gMCwgYDEwYCA9IGAwLTEwYCwgYDIwYCA9IGAwLTIwYCwgYDQwYCA9IGAwLTIwYCArIGAyMC00MGAsIGA2MGAgPSBgMC0yMGAgKyBgMjAtNDBgICsgYDQwLTYwYCwgYDgwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgICsgYDYwLTgwYCwgYDkwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgICsgYDYwLTgwYCArIGA4MC0xMDBgLWA5MC0xMDBgLCBgMTAwYCA9IDEwMCkgCmRmX2dpbmlfY2FsYyAlPiUgZHJvcF9uYSgpIHw+IGZpbHRlcihjb3VudHJ5ID09ICJCYW5nbGFkZXNoIikKYGBgCgpgYGB7cn0KZGZfZ2luaV9jYWxjX2xvbmcgPC0gZGZfZ2luaV9jYWxjIHw+ICBwaXZvdF9sb25nZXIoYDBgOmAxMDBgLCBuYW1lc190byA9ICJjbGFzc2VzIiwgdmFsdWVzX3RvID0gImN1bXVsYXRpdmVfc2hhcmUiKSB8PiBtdXRhdGUoY2xhc3NlcyA9IGFzLm51bWVyaWMoY2xhc3NlcykpCmRmX2dpbmlfY2FsY19sb25nICU+JSBkcm9wX25hKCkgfD4gZmlsdGVyKGNvdW50cnkgPT0gIkJhbmdsYWRlc2giKQpgYGAKCueiuuiqjQoKYGBge3J9CmRmX2dpbmlfY2FsY19sb25nIHw+IGZpbHRlcihjb3VudHJ5ID09ICJCYW5nbGFkZXNoIikgfD4gCiAgZmlsdGVyKHllYXIgPT0gMjAyMikgfD4gZ2dwbG90KCkgKyBnZW9tX2xpbmUoYWVzKGNsYXNzZXMsIGN1bXVsYXRpdmVfc2hhcmUpKSArIGdlb21fc2VnbWVudChhZXMoeCA9IDAsIHkgPSAwLCB4ZW5kID0gMTAwLCB5ZW5kID0gMTAwKSwgY29sb3IgPSAncmVkJykgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMTAwLGJ5PTIwKSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsMTAwLGJ5PTIwKSkgIysKICAjYW5ub3RhdGUoInRleHQiLCB4ID0gMTAsIHkgPSA4MCwgbGFiZWwgPSBnaW5pKQpgYGAKClNoYWRlIHJlZ2lvbiBiZXR3ZWVuIHR3byBsaW5lcyB3aXRoIGdncGxvdDogW1vjg6rjg7Pjgq9dKGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI4NTg2NjM1L3NoYWRlLXJlZ2lvbi1iZXR3ZWVuLXR3by1saW5lcy13aXRoLWdncGxvdCldCgpgYGB7cn0KZGZfZ2luaV9jYWxjIHw+IGdyb3VwX2J5KGNvdW50cnksIHllYXIpIHw+IAogIGRyb3BfbmEoZ2luaSkgfD4KICBzdW1tYXJpemUoZ2luaSwgZ2luaV90cmFwZXpvaWQgPSAxMDAtKDIqYDEwYCArIDMqYDIwYCArIDQqYDQwYCArIDQqYDYwYCArIDMqYDgwYCArIDIqYDkwYCArIDEwMCkvMTApIHw+IAogIGRpc3RpbmN0KGNvdW50cnksIHllYXIsIGdpbmksIGdpbmlfdHJhcGV6b2lkKQpgYGAKCmBgYHtyfQojIyMjIEZvciB0aGUgY2FsY3VhbHRpb24gb2YgdGhlIGFyZWEgdW5kZXIgdGhlIGN1cnZlCiAgICAjIyMjIFRyYXBlem9pZGFsIHJ1bGUKICAgIHRyYXBlem9pZCA8LSBmdW5jdGlvbih4LCB5KSB7CiAgICAgICAgICAgICAgICAgICAgIHN1bShkaWZmKHgpKih5Wy0xXSt5Wy1sZW5ndGgoeSldKSkvMgogICAgICAgICAgICAgICAgIH0KICAgICMjIyMgU2ltcHNvbidzIHJ1bGU6IG1vcmUgYWNjdXJhdGUKICAgIHNpbXBzb24gPC0gZnVuY3Rpb24oeCwgeSl7CiAgICAgICAgICAgICAgICAgICBuIDwtIGxlbmd0aCh5KQogICAgICAgICAgICAgICAgICAgb2RkIDwtIG4gJSUgMgogICAgICAgICAgICAgICAgICAgaWYgKG9kZCkKICAgICAgICAgICAgICAgICAgICAgICBhcmVhIDwtIDEvMypzdW0oIHlbMV0gKyAyKnN1bSh5W3NlcSgzLChuLTIpLGJ5PTIpXSkgKyA0KnN1bSh5W3NlcSgyLChuLTEpLGJ5PTIpXSkgKyB5W25dKQogICAgICAgICAgICAgICAgICAgaWYgKCFvZGQpCiAgICAgICAgICAgICAgICAgICAgICAgYXJlYSA8LSAxLzMqc3VtKCB5WzFdICsgMipzdW0oeVtzZXEoMywobi0zKSxieT0yKV0pICsgNCpzdW0oeVtzZXEoMiwobi0yKSxieT0yKV0pICsgeVtuLTFdKSArIDEvMiooeVtuLTFdICsgeVtuXSkKICAgICAgICAgICAgICAgICAgIGR4IDwtIHhbMl0gLSB4WzFdCiAgICAgICAgICAgICAgICAgICByZXR1cm4oYXJlYSAqIGR4KQogICAgfQogICAgClNJTVBTT04gPC0gZnVuY3Rpb24oeCwgaD0xKXsKICAjIEFVQyBmdW5jdGlvbiBjb21wdXRlcyB0aGUgQXJlYSBVbmRlciB0aGUgQ3VydmUgb2YgYSB0aW1lIHNlcmllIHVzaW5nCiAgIyB0aGUgU2ltcHNvbidzIFJ1bGUgKG51bWVyaWNhbCBtZXRob2QpLgogICMgaHR0cHM6Ly9saW5rLnNwcmluZ2VyLmNvbS9jaGFwdGVyLzEwLjEwMDcvOTc4LTEtNDYxMi00OTc0LTBfMjYKICAKICAjIEFyZ3VtZW50cwogICMgeDogKHZlY3RvcikgdGltZSBzZXJpZSB2YWx1ZXMKICAjIGg6IChpbnQpIHRlbXBvcmFsIHJlc29sdXRpb24gb2YgdGhlIHRpbWUgc2VyaWUuIGRlZmF1bHQgaD0xCiAgCiAgbiA9IGxlbmd0aCh4KS0xCiAgCiAgeFZhbHVlcyA9IHNlcShmcm9tPTEsIHRvPW4sIGJ5PTIpCiAgCiAgc3VtIDwtIGxpc3QoKQogIGZvcihpIGluIDE6bGVuZ3RoKHhWYWx1ZXMpKXsKICAgIG5fc3ViIDwtIHhWYWx1ZXNbW2ldXS0xCiAgICBuIDwtIHhWYWx1ZXNbW2ldXQogICAgbl9hZGQgPC0geFZhbHVlc1tbaV1dKzEKICAgIAogICAgdjEgPC0geFtbbl9zdWIrMV1dCiAgICB2MiA8LSB4W1tuKzFdXQogICAgdjMgPC0geFtbbl9hZGQrMV1dCiAgICAKICAgIHMgPC0gKGgvMykqKHYxKzQqdjIrdjMpCiAgICBzdW0gPC0gYXBwZW5kKHN1bSwgcykKICB9CiAgc3VtIDwtIHVubGlzdChzdW0pCiAgCiAgYXVjIDwtIHN1bShzdW0pCiAgCiAgcmV0dXJuKGF1YykKICAKfQpgYGAKCmBgYHtyfQpzaW1wc29uKGMoMCwwLjIsMC40LDAuNiwwLjgsMSksYygwLDAuMDQsMC4xNiwwLjM2LDAuNjQsMSkpCmBgYAoKYGBge3J9CmxpYnJhcnkoRGVzY1Rvb2xzKQpgYGAKCkFyZWEgVW5kZXIgdGhlIEN1cnZlOiBbW+ODquODs+OCr10oaHR0cHM6Ly9zZWFyY2guci1wcm9qZWN0Lm9yZy9DUkFOL3JlZm1hbnMvRGVzY1Rvb2xzL2h0bWwvQVVDLmh0bWwpXQoKPGh0dHBzOi8vcmRyci5pby9jcmFuL0Rlc2NUb29scy9mLz4KCmBgYHtyfQpkZl9naW5pX2NhbGNfbG9uZyB8PiBncm91cF9ieShjb3VudHJ5LCB5ZWFyKSB8PiAKICBkcm9wX25hKGdpbmkpIHw+CiAgc3VtbWFyaXplKGdpbmksIGdpbmlfc3BsaW5lID0gcm91bmQoMTAwLUFVQyhjbGFzc2VzLCBjdW11bGF0aXZlX3NoYXJlLCBtZXRob2QgPSAic3BsaW5lIikvNTAsIGRpZ2l0cyA9IDEpLCBnaW5pX3RyYXBlem9pZCA9IHJvdW5kKDEwMC1BVUMoY2xhc3NlcywgY3VtdWxhdGl2ZV9zaGFyZSkvNTAsIGRpZ2l0cyA9IDEpLCBnaW5pX3NpbXBzb24gPSByb3VuZCgxMDAgLSBzaW1wc29uKGNsYXNzZXMsIGN1bXVsYXRpdmVfc2hhcmUpLzUwLCBkaWdpdHMgPSAxKSkgfD4gCiAgZGlzdGluY3QoY291bnRyeSwgeWVhciwgZ2luaSwgZ2luaV9zcGxpbmUsIGdpbmlfdHJhcGV6b2lkLCBnaW5pX3NpbXBzb24pCmBgYAoKYGBge3J9CmRmX2dpbmlfY2FsY19sb25nIHw+IGdyb3VwX2J5KGNvdW50cnksIHllYXIpIHw+IAogIGRyb3BfbmEoZ2luaSkgfD4KICBzdW1tYXJpemUoZ2luaSwgZ2luaV9zcGxpbmUgPSByb3VuZCgxMDAtQVVDKGNsYXNzZXMsIGN1bXVsYXRpdmVfc2hhcmUsIG1ldGhvZCA9ICJzcGxpbmUiKS81MCwgZGlnaXRzID0gMSksIGdpbmlfdHJhcGV6b2lkID0gcm91bmQoMTAwLUFVQyhjbGFzc2VzLCBjdW11bGF0aXZlX3NoYXJlKS81MCwgZGlnaXRzID0gMSksIGdpbmlfc2ltcHNvbiA9IHJvdW5kKDEwMCAtIHNpbXBzb24oY2xhc3NlcywgY3VtdWxhdGl2ZV9zaGFyZSkvNTAsIGRpZ2l0cyA9IDEpKSB8PiAKICBkaXN0aW5jdChjb3VudHJ5LCB5ZWFyLCBnaW5pLCBnaW5pX3NwbGluZSwgZ2luaV90cmFwZXpvaWQsIGdpbmlfc2ltcHNvbikKYGBgCgpBVUM6IENhbGN1bGF0aW5nIEFyZWEgdW5kZXIgYSBDdXJ2ZSBbW+ODquODs+OCr10oaHR0cHM6Ly93d3cuc21pbjk1LmNvbS9kYXRhdml6L2NhbGN1bGF0aW5nLWFyZWEtdW5kZXItYS1jdXJ2ZSNjYWxjdWxhdGluZy1hcmVhLXVuZGVyLWEtY3VydmUpXQoKPGh0dHBzOi8vd3d3LnN0YXRzZGlyZWN0LmNvbS9oZWxwL2RlZmF1bHQuaHRtI25vbnBhcmFtZXRyaWNfbWV0aG9kcy9naW5pLmh0bT4KCiMjIyBHSU5JIENhbGN1bGF0b3IKCngg44Gr44CB5pWw44Gu5YiX44KS5YWl44KM44KL44Go44Gd44Gu5YiG6YWN44Gr6Zai44GZ44KL44CBR0lOSSDjgpLoqIjnrpfjgZfjgb7jgZnjgIIKCmBgYHtyfQp4IDwtIGMoMSwxLDEsNCwxMCkKTGMoeClbYygxLDIpXSB8PiBhcy50aWJibGUoKSB8PiBtdXRhdGUoZCA9IHAsIC5hZnRlciA9IDEpIHw+IAogIHBpdm90X2xvbmdlcigtMSwgbmFtZXNfdG8gPSAibmFtZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpIHw+CiAgZ2dwbG90KGFlcyhwLCB2YWx1ZSwgZmlsbCA9IG5hbWUpKSArIGdlb21fYXJlYShwb3NpdGlvbiA9ICJpZGVudGl0eSIpICsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAwLjI1LCB5ID0gMC43NSwgbGFiZWwgPSBwYXN0ZSgiR0lOSSA9ICIscm91bmQoTGMoeCkkR2luaSwgZGlnaXRzID0gMikpKQpgYGAKCmBgYHtyfQpTRVIgPC0gYygwLDUsMywxLDEpClNFUjEgPC0gYygwLHNvcnQoU0VSKSkKU0VSMQpOID0gbGVuZ3RoKFNFUjEpClkgPC0gMDpOL047IFkKYGBgCgrlrprnvqnjgavjgoLjganjgaPjgabopoHnorroqo0KCmBgYHtyfQpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKHllYXIgPT0gMjAyMikgfD4gZHJvcF9uYShnaW5pKQpgYGAKCuS7luOBruimi+OBm+aWueOBq+S/ruatowoKYGBge3J9CmRmX2dpbmlfbG9uZyB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiBkcm9wX25hKGdpbmkpIHw+CiAgZ2dwbG90KGFlcyh4ID0gbGV2ZWxzLCB5ID0gYWRqLCBjb2wgPSBjb3VudHJ5KSkgKyBnZW9tX2xpbmUoKQpgYGAKCuWSjOOCkuOBqOOBo+OBn+OCguOBruOCkuioiOeul+OBl+OBquOBhOOBqOOBhOOBkeOBquOBhOOAguS7peS4i+OBr+OBguOBqOOBp+WIqeeUqAoKYGBge3IgZXZhbCA9IEZBTFNFfQpkZl9naW5pX2xvbmcgPC0gZGZfZ2luaSB8PiAKICBwaXZvdF9sb25nZXIoLSgxOjUpLCBuYW1lc190byA9ICJsZXZlbHMiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSB8PgogIG11dGF0ZShsZXZlbHMgPSBhcy5udW1lcmljKGxldmVscykpIHw+IAogIG11dGF0ZShjdXQgPSBjYXNlX3doZW4obGV2ZWxzID09IDUgfiAnMC0xMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPT0gMTAgfiAnMC0yMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPT0gMzAgfiAnMjAtNDAnLAogICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID09IDUwIH4gJzQwLTYwJywKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9PSA3MCB+ICc2MC04MCcsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPT0gOTAgfiAnODAtMTAwJywKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9PSA5NSB+ICc5MC0xMDAnKSwKICAgICAgICAgYWRqID0gY2FzZV93aGVuKGxldmVscyA9PSA1IH4gdmFsdWUqMiwKICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9PSA5NSB+IHZhbHVlKjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdCA9IHZhbHVlKSkKZGZfZ2luaV9sb25nCmBgYAoKYGBge3J9CmRmX2dpbmlfcmV2IDwtIFdESShpbmRpY2F0b3IgPSBjKGdpbmkgPSAiU0kuUE9WLkdJTkkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJzAtMTAnID0gIlNJLkRTVC5GUlNULjEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcwLTIwJyA9ICJTSS5EU1QuRlJTVC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMjAtNDAnID0gIlNJLkRTVC4wMk5ELjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICc0MC02MCcgPSAiU0kuRFNULjAzUkQuMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJzYwLTgwJyA9ICJTSS5EU1QuMDRUSC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnODAtMTAwJyA9ICJTSS5EU1QuMDVUSC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnOTAtMTAwJyA9ICJTSS5EU1QuMTBUSC4xMCIpKQpgYGAKCmBgYHtyfQpkZl9naW5pX3Jldl9sb25nIDwtIGRmX2dpbmlfcmV2IHw+IAogIHBpdm90X2xvbmdlcigtKDE6NSksIG5hbWVzX3RvID0gImxldmVscyIsIHZhbHVlc190byA9ICJ2YWx1ZSIpCmRmX2dpbmlfcmV2X2xvbmcKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJCYW5nbGFkZXNoIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX3Jldl9sb25nIHw+IAogIGZpbHRlcihjb3VudHJ5ID09IENPVU5UUllfR0lOSSwgeWVhciA9PSBZRUFSX0dJTkkpIHw+CiAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpCmBgYAoKYGBge3J9CmRmX2dpbmlfcmV2X2xvbmcyIDwtIGRmX2dpbmlfcmV2IHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgbXV0YXRlKCcwLTEwJyA9IGAwLTEwYCAqMiwgJzkwLTEwMCcgPSBgOTAtMTAwYCAqMikgfD4KICBwaXZvdF9sb25nZXIoLSgxOjUpLCBuYW1lc190byA9ICJsZXZlbHMiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKQpDT1VOVFJZX0dJTkkgPC0gIkJhbmdsYWRlc2giCllFQVJfR0lOSSA8LSAyMDIyCmRmX2dpbmlfcmV2X2xvbmcyIHw+IAogIGZpbHRlcihjb3VudHJ5ID09IENPVU5UUllfR0lOSSwgeWVhciA9PSBZRUFSX0dJTkkpIHw+CiAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpCmBgYAoKYGBge3J9CkNPVU5UUklFU19HSU5JIDwtIGMoIkJodXRhbiIsICJCYW5nbGFkZXNoIiwiSW5kb25lc2lhIiwiQ29zdGEgUmljYSIpCllFQVJfR0lOSSA8LSAyMDIyCmRmX2dpbmlfcmV2X2xvbmcyIHw+IAogIGZpbHRlcihjb3VudHJ5ICVpbiUgQ09VTlRSSUVTX0dJTkksIHllYXIgPT0gWUVBUl9HSU5JKSB8PgogIGdncGxvdChhZXMobGV2ZWxzLCB2YWx1ZSwgZmlsbCA9IGZhY3Rvcihjb3VudHJ5LCBsZXZlbHMgPSBDT1VOVFJJRVNfR0lOSSkpKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKyBsYWJzKGZpbGwgPSAiIikKYGBgCgpgYGB7cn0KWUVBUl9HSU5JIDwtIDIwMDAKZGZfZ2luaV9yZXYgfD4gCiAgZmlsdGVyKHllYXIgPT0gWUVBUl9HSU5JKSB8PiBkcm9wX25hKGdpbmkpIHw+CiAgZ2dwbG90KGFlcyhnaW5pLCBgOTAtMTAwYCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKYGBgCgpgYGB7cn0KWUVBUl9HSU5JIDwtIDIwMDAKZGZfZ2luaV9yZXYgfD4gCiAgZmlsdGVyKHllYXIgPT0gWUVBUl9HSU5JKSB8PiBkcm9wX25hKGdpbmkpIHw+CiAgZ2dwbG90KGFlcyhnaW5pLCBgODAtMTAwYCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKYGBgCgpgYGB7cn0KWUVBUl9HSU5JIDwtIDIwMDAKZGZfZ2luaV9yZXYgfD4gZmlsdGVyKHllYXIgPT0gWUVBUl9HSU5JKSB8PiBkcm9wX25hKGdpbmkpIHw+CiAgZ2dwbG90KGFlcyhnaW5pKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUpCmBgYAoKIyMgVG8gRG8KCi0gICBleHRyYSA9IFRSVUUg44Gn5YiG5p6Q44KS5aeL44KB44KL5pa544GM44KI44GE44CCCgotICAgRGlzdHJpYnV0aW9uIOOCkuWkp+WIh+OBq+OBmeOCi+WbnuOBq+OBl+OBpuOCguOCiOOBhOOAggoKLSAgIHdlaWdodCDjgpLkvb/jgYjjgbDjgIFEZXNjVG9vbHM6Okdpbmkg44Gn44CBTG9yZW50eiBDdXJ2ZSDjgpLkvZzjgorlh7rjgZfjgIHjgZ3jgozjgYvjgonoqIjnrpfjgafjgY3jgovjgYvjgoLjgZfjgozjgarjgYTjga7jgafjgIHoqabjgZfjgabjgb/jgovjgIIKCi0gICDjgYTjgY/jgaTjgYvjga7jgIFMb3JlbnR6IOabsue3muOBqOOAgeOBneOBruS4i+OCkumAj+aYjuW6puOCkuOBpOOBkeOBpuOAgemHjeOBreWQiOOCj+OBmeOBk+OBqOOCkuODiOODqeOCpOOAggoKLSAgIDAtMTAsIDkwLTEwMCDjgavjgaTjgYTjgabjga7mibHjgYTjgpLjganjgYbjgZnjgovjgYvjgpLogIPjgYjjgovjgIIKCmBgYHtyfQpkZl9naW5pX3JldiB8PiBmaWx0ZXIoaXNvMmMgPT0gIklEIiwgeWVhciA9PSAyMDIyKQpgYGAKCmBgYHtyfQpkZl9naW5pX3JldiAgfD4gbXV0YXRlKCcxMC0yMCcgPSBgMC0yMGAtYDAtMTBgLCAuYmVmb3JlID0gYDAtMjBgKSB8PiBtdXRhdGUoJzgwLTkwJyA9IGA4MC0xMDBgLWA5MC0xMDBgLCAuYmVmb3JlID0gYDgwLTEwMGApIHw+IHNlbGVjdCgtYyhgMC0yMGAsIGA4MC0xMDBgKSkgfD4KICBmaWx0ZXIoaXNvMmMgPT0gIklEIiwgeWVhciA9PSAyMDIyKQpgYGAKCmBgYHtyfQpkZl9naW5pX3JldiAgfD4gbXV0YXRlKCcxMC0yMCcgPSBgMC0yMGAtYDAtMTBgLCAuYmVmb3JlID0gYDAtMjBgKSB8PiBtdXRhdGUoJzgwLTkwJyA9IGA4MC0xMDBgLWA5MC0xMDBgLCAuYmVmb3JlID0gYDgwLTEwMGApIHw+IHNlbGVjdCgtYyhgMC0yMGAsIGA4MC0xMDBgKSkgfD4KICBwaXZvdF9sb25nZXIoLSgxOjUpLCBuYW1lc190byA9ICJyYW5nZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpIHw+IAogIGZpbHRlcihpc28yYyA9PSAiSUQiLCB5ZWFyID09IDIwMjIpIHw+IHB1bGwoKSB8PiAKICBhcHBlbmQoMCwwKSB8PiBHaW5pKHdlaWdodHMgPSBjKDEsMSwxLDIsMiwyLDEsMSkpCmBgYAoKMzcuOQoKYGBge3J9CmRmX2dpbmlfcmV2ICB8PiBtdXRhdGUoJzEwLTIwJyA9IGAwLTIwYC1gMC0xMGAsIC5iZWZvcmUgPSBgMC0yMGApIHw+IG11dGF0ZSgnODAtOTAnID0gYDgwLTEwMGAtYDkwLTEwMGAsIC5iZWZvcmUgPSBgODAtMTAwYCkgfD4gc2VsZWN0KC1jKGAwLTIwYCwgYDgwLTEwMGApKSB8PgogIHBpdm90X2xvbmdlcigtKDE6NSksIG5hbWVzX3RvID0gInJhbmdlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgfD4gCiAgZmlsdGVyKGlzbzJjID09ICJJRCIsIHllYXIgPT0gMjAyMikgfD4gcHVsbCgpIC0+IGlkCkdpbmkoYygwLjUsMS41LDMsNSw3LDguNSw5LjUpLCBpZCwgY29uZi5sZXZlbD0wLjk1LCB1bmJpYXNlZD1GQUxTRSkKYGBgCg==