前回(12月19日)の復習

今回の演習の内容

指標について

何のデータか、変数はどのようなものか、定義は?など、確認。データのURL を記録するのもたいせつ。

  • 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.

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

準備

毎回 tidyverseWDIDescTools を使いますから、R Notebook の最初には、次のコードチャンクを作成し、実行(Run)します。これらの(機能を拡張する)パッケージがインストールされていない場合は、インストールします。Tools>Install Packages …

library(tidyverse)
library(WDI)
library(DescTools)

データの読み込み

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"))

保存と読み込み

何度もダウンロードしなくて良いように、保存したものを読み込みます。

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

gini が NA ではない値のもののみ表示します

df_gini |> drop_na(gini)

変形:各階級の値を縦に並べ、縦長形式の表にします。Long format

pivot_longer(cols, names_to = "", values_to = "") についてはいずれ説明します。ここでは、レベルに分けられたものを levels という名の列にレベルを、value という名の列に、その値を並べたものとします。

df_gini_long <- df_gini |> 
  pivot_longer(`0-10`:`90-100`, names_to = "levels", values_to = "value")
df_gini_long

整えられた(tidy)データ

  • 各列はひとつの変数

  • 各行はひとつの観測値

階級(levels)を変数として扱うために、このように変形しました。

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

df_gini |> drop_na(gini) |> 
  ggplot(aes(year)) + geom_bar()

実際には、次のような計算をして、棒グラフで表示しています。

  • group_by(year) 年ごとにグループとする

  • summarize(n = n()) それぞれのグループごとのデータを数えます。直前に、drop_na(gini) としてあるので、gini が NA ではないデータの数を数えています。

  • 棒グラフ:ggplot(aes(year, n)) + geom_col()

すなわち、次のものと同じです。

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.

2022年にデータが存在する7つの国名を表示

df_gini_long |> filter(year == 2022) |> drop_na(value) |>
  distinct(country, gini) |> arrange(gini)

7カ国のいくつかについて調べる

x = levels とし、y = value とするところで、Long にした効果が出ています。

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

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

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

練習1. Indonesia, El Salvador, Paraguay, Ecuador のいずれかについてグラフを描いてみましょう。

並べて描いてみましょう

ジニ指数は小さいほうから、Bhutan, Bangladesh, Indonesia, El Salvador, Paraguay, Equador, Costa Rica でした。

df_gini_long |> filter(year == 2022) |> 
  filter(levels != "gini") |>  drop_na(value) |>
  ggplot(aes(levels, value)) + geom_col() + facet_wrap(~country)

考えてみよう

  1. 最後下がっているのは正常?

  2. どのように表示するのがよいのだろうか。

  3. これらの図をみて、ジニ指数の大きさについてわかりますか。

  4. このデータから、ジニ指数を計算するには、どうしたら良いのだろうか。

ジニ指数の計算

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`,
         `30` = `0-20`+`20-40`/2, `40` = `0-20` + `20-40`, 
         `50` = `0-20` + `20-40` + `40-60`/2, 
         `60` = `0-20` + `20-40` + `40-60`, 
         `70` = `0-20` + `20-40` + `40-60` + `60-80`/2,  
         `80` = `0-20` + `20-40` + `40-60` + `60-80`, 
         `90` = `0-20` + `20-40` + `40-60` + `60-80` + `80-100`-`90-100`,
         `100` = 100) |>
  select(-c(`0-10`:`90-100`)) # 不必要な部分を消去
df_gini_calc %>% drop_na() 

縦長の Long Table に変換

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() 

確認

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)

4カ国をジニ指数順にならべた棒グラフ

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

練習2. 7カ国すべてについて、80-100 と、90-100 の部分だけ、表示できないでしょうか。(難:答えは一番下)

2000年のジニ指数と90%以上の割合の相関

df_gini |> 
  filter(year == 2000) |> drop_na(gini) |>
  ggplot(aes(gini, `90-100`)) + geom_point() + 
  geom_smooth(formula = 'y ~ x', method = "lm")

練習3. 2000年(または他の年の)ジニ指数と80%以上の割合の相関

復習

課題

練習1 から練習3.

提出はしなくて良いですが、ぜひ実際に手を動かして実行してください。

参考文献

  1. 「みんなのデータサイエンス - Data Science for All」[はじめてのデータサイエンス]

    • 導入として、GDP(国内総生産)のデータを使って説明しています。
  2. Posit Recipes(旧 Posit Primers): The Basics 対話型の演習サイトの最初 [Link]

  3. Posit Cheat Sheet. 早見表です。印刷して使うために、PDF も提供しています。[Site Link]

  4. DataCamp Cheat Sheet: Tidyverse for Biginners. データサイエンスの教育をしている会社の早見表の一つです。基本が簡単にまとまっています。[Link]

練習2の答え

SEVEN_COUNTRIES <- c("Bhutan", "Bangladesh","Indonesia","El Salvador", "Paraguay", "Equador", "Costa Rica")
YEAR_GINI <- 2022
df_gini_long |> 
  filter(country %in% SEVEN_COUNTRIES, year == YEAR_GINI) |>
  filter(levels %in% c('80-100','90-100')) |>
  ggplot(aes(levels, value, fill = factor(country, levels = SEVEN_COUNTRIES))) + geom_col(position = "dodge", col = "black", linewidth = 0.2) + labs(fill = "")

LS0tCnRpdGxlOiAi44K444OL5oyH5pWw44Go5omA5b6X5YiG5biDIgphdXRob3I6ICJILiBTdXp1a2kiCmRhdGU6ICIyMDI05bm0MeaciDnml6UiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQoKIyMg5LiW55WM6ZaL55m65oyH5qiZ77yIV29ybGQgRGV2ZWxvcG1lbnQgSW5kaWNhdG9yc++8iVtbTGlua10oaHR0cHM6Ly9kYXRhdG9waWNzLndvcmxkYmFuay5vcmcvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy8pXQoKIyMjIyAqKuiyp+WbsOOBqOS4jeW5s+etie+8iFBvdmVydHkgYW5kIEluZXF1YWxpdHnvvIkqKgoKKirmiYDlvpfjgb7jgZ/jga/mtojosrvjga7liIbphY3vvIhEaXN0cmlidXRpb24gb2YgaW5jb21lIG9yIGNvbnN1bXB0aW9u77yJKioKCkdJTkkg5oyH5pWwICjkuJbnlYzpioDooYzmjqjoqIgp77yaU0kuUE9WLkdJTkkgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuUE9WLkdJTkkpXQoK5LiL5L2NIDEwJSDjgYzljaDjgoHjgovmiYDlvpfjgrfjgqfjgqLvvJpTSS5EU1QuRlJTVC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjEwKV0KCuS4i+S9jSAyMCUg44GM5Y2g44KB44KL5omA5b6X44K344Kn44Ki77yaU0kuRFNULkZSU1QuMjAgW1tMaW5rXShodHRwczovL2RhdGFiYW5rLndvcmxkYmFuay5vcmcvbWV0YWRhdGFnbG9zc2FyeS93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzL3Nlcmllcy9TSS5EU1QuRlJTVC4yMCldCgoy55Wq55uu44GuIDIwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMDJORC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC4wMk5ELjIwKV0KCjPnlarnm67jga4gMjAlIOOBjOWNoOOCgeOCi+WPjuWFpeOCt+OCp+OCoiDvvJpTSS5EU1QuMDNSRC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMDNSRC4yMCldCgo055Wq55uu44GuIDIwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMDRUSC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC4wNFRILjIwKV0KCuS4iuS9jSAyMCUg44GM5Y2g44KB44KL5Y+O5YWl44K344Kn44Ki77yaU0kuRFNULjA1VEguMjAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjA1VEguMjApXQoK5LiK5L2NIDEwJSDjgYzljaDjgoHjgovlj47lhaXjgrfjgqfjgqLvvJpTSS5EU1QuMTBUSC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YS53b3JsZGJhbmsub3JnL2luZGljYXRvci9TSS5EU1QuMTBUSC4xMCldCgojIyDliY3lm57vvIgxMuaciDE55pel77yJ44Gu5b6p57+SCgotICAg44OR44OD44Kx44O844K477yIUGFja2FnZe+8ieOBruWIqeeUqO+8mgoKICAgIC0gICDjgqTjg7Pjgrnjg4jjg7zjg6vvvIhpbnN0YWxsYXRpb27vvInvvJpUb29scyBcPiBJbnN0YWxsIFBhY2thZ2VzCgogICAgLSAgIOODreODvOODie+8iGxvYWTvvIlgbGlicmFyeSh0aWR5dmVyc2UpOyBsaWJyYXJ5KFdESSk7IGxpYnJhcnkoc2hvd3RleHQpYAoKLSAgIOODh+ODvOOCv+OBruWPluW+l++8mmBXREkoaW5kaWNhdG9yID0gYyhwb3AgPSAiU1AuUE9QLlRPVEwiKSlgCgotICAg54m55a6a44Gu6KGM44Gu5Y+W5b6X77yaYGZpbHRlcigpLCBkcm9wX25hKCksIGRpc3RpbmN0KClgCgotICAg5oqY44KM57ea44Kw44Op44OVCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gcG9wKSArIGdlb21fbGluZSgpYAoKICAgIC0gICBgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHBvcCwgY29sID0gY291bnRyeSkgKyBnZW9tX2xpbmUoKWAKCiMjIOS7iuWbnuOBrua8lOe/kuOBruWGheWuuQoKLSAgIOODkeODg+OCseODvOOCuO+8iFBhY2thZ2XvvInjgqTjg7Pjgrnjg4jjg7zjg6vvvIjjgrPjg7Pjg5Tjg6Xjg7zjgr/jgavlhaXjgozjgabjgYrjgY/vvInvvJpgRGVzY1Rvb2xzYAoKLSAgIOODkeODg+OCseODvOOCuOOBruODreODvOODie+8iOOBmeOBkOS9v+OBiOOCi+OCiOOBhuOBq+OBmeOCi++8ie+8mmB0aWR5dmVyc2VgLCBgV0RJYCwgYERlc2NUb29sc2AKCi0gICDjg4fjg7zjgr/jga7lj5blvpfvvJpgV0RJKClgCgotICAg54m55a6a44Gu5p2h5Lu244Gr44GC44Gj44Gf6KGM44KS6YG45oqe77yaYGZpbHRlcigpYAoKLSAgIOaWsOOBl+OBhOWIl+OCkuS7luOBruWIl+OBi+OCieioiOeul+OBl+OBpuWKoOOBiOOCi++8mmBtdXRhdGUoKWAKCi0gICDpoIbnlarjgavjgIHlpInlvaLjgIHoppbopprljJbjgarjganjgpLjgZnjgovjgZ/jgoHjga7jg5HjgqTjg5fvvJpgfD5gIO+8iOOBvuOBn+OBr+OAgWAlPiVg77yJCgotICAg44OS44K544OI44Kw44Op44Og77yI5bqm5pWw5YiG5biD77yJ77yaZ2dwbG90KC4uLikgKyBnZW9tX2hpc3RvZ3JhbSgpCgotICAg5qOS44Kw44Op44OV77yaZ2dwbG90KC4uLikgKyBnZW9tX2NvbCgpLCBnZ3Bsb3QoLi4uKSArIGdlb21fYmFyKCkKCiMjIyDmjIfmqJnjgavjgaTjgYTjgaYKCuS9leOBruODh+ODvOOCv+OBi+OAgeWkieaVsOOBr+OBqeOBruOCiOOBhuOBquOCguOBruOBi+OAgeWumue+qeOBr++8n+OBquOBqeOAgeeiuuiqjeOAguODh+ODvOOCv+OBrlVSTCDjgpLoqJjpjLLjgZnjgovjga7jgoLjgZ/jgYTjgZvjgaTjgIIKCi0gICBHSU5JIGluZGV4IChXb3JsZCBCYW5rIGVzdGltYXRlKe+8m1NJLlBPVi5HSU5JIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLlBPVi5HSU5JKV0KCiAgICAtICAgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgZXh0ZW50IHRvIHdoaWNoIHRoZSBkaXN0cmlidXRpb24gb2YgaW5jb21lIChvciwgaW4gc29tZSBjYXNlcywgY29uc3VtcHRpb24gZXhwZW5kaXR1cmUpIGFtb25nIGluZGl2aWR1YWxzIG9yIGhvdXNlaG9sZHMgd2l0aGluIGFuIGVjb25vbXkgZGV2aWF0ZXMgZnJvbSBhIHBlcmZlY3RseSBlcXVhbCBkaXN0cmlidXRpb24uIEEgTG9yZW56IGN1cnZlIHBsb3RzIHRoZSBjdW11bGF0aXZlIHBlcmNlbnRhZ2VzIG9mIHRvdGFsIGluY29tZSByZWNlaXZlZCBhZ2FpbnN0IHRoZSBjdW11bGF0aXZlIG51bWJlciBvZiByZWNpcGllbnRzLCBzdGFydGluZyB3aXRoIHRoZSBwb29yZXN0IGluZGl2aWR1YWwgb3IgaG91c2Vob2xkLiBUaGUgR2luaSBpbmRleCBtZWFzdXJlcyB0aGUgYXJlYSBiZXR3ZWVuIHRoZSBMb3JlbnogY3VydmUgYW5kIGEgaHlwb3RoZXRpY2FsIGxpbmUgb2YgYWJzb2x1dGUgZXF1YWxpdHksIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIG1heGltdW0gYXJlYSB1bmRlciB0aGUgbGluZS4gVGh1cyBhIEdpbmkgaW5kZXggb2YgMCByZXByZXNlbnRzIHBlcmZlY3QgZXF1YWxpdHksIHdoaWxlIGFuIGluZGV4IG9mIDEwMCBpbXBsaWVzIHBlcmZlY3QgaW5lcXVhbGl0eS4KCiAgICAtICAg44K444OL5oyH5pWw44Gv44CB57WM5riI5YaF44Gu5YCL5Lq644G+44Gf44Gv5LiW5biv6ZaT44Gu5omA5b6X77yI44G+44Gf44Gv5aC05ZCI44Gr44KI44Gj44Gm44Gv5raI6LK75pSv5Ye677yJ44Gu5YiG5biD44GM44CB5a6M5YWo44Gr5bmz562J44Gq5YiG5biD44GL44KJ44Gp44Gu56iL5bqm6YC46ISx44GX44Gm44GE44KL44GL44KS5ris5a6a44GZ44KL44CC44Ot44O844Os44Oz44OE5puy57ea44Gv44CB5pyA44KC6LKn44GX44GE5YCL5Lq644G+44Gf44Gv5LiW5biv44GL44KJ5aeL44G+44KK44CB5Y+X57Wm6ICF44Gu57Sv56mN5pWw44Gr5a++44GZ44KL57eP5omA5b6X44Gu57Sv56mN5Ymy5ZCI44KS44OX44Ot44OD44OI44GX44Gf44KC44Gu44Gn44GC44KL44CC44K444OL5oyH5pWw44Gv44CB44Ot44O844Os44Oz44OE5puy57ea44Go57W25a++55qE5bmz562J44Gu5Luu5oOz57ea44Go44Gu6ZaT44Gu6Z2i56mN44KS5ris5a6a44GZ44KL44KC44Gu44Gn44CB57ea44Gu5LiL44Gu5pyA5aSn6Z2i56mN44Gu55m+5YiG546H44Gn6KGo44GV44KM44KL44CC44GX44Gf44GM44Gj44Gm44CB44K444OL5oyH5pWwMOOBr+WujOWFqOOBquW5s+etieOCkuihqOOBl+OAgeaMh+aVsDEwMOOBr+WujOWFqOOBquS4jeW5s+etieOCkuaEj+WRs+OBmeOCi+OAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGxvd2VzdCAxMCXvvJpTSS5EU1QuRlJTVC4xMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjEwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeODh+OCt+ODq+OBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eZuueUn+OBmeOCi+WJsuWQiOOBp+OBmeOAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGxvd2VzdCAyMCXvvJpTSS5EU1QuRlJTVC4yMCBbW0xpbmtdKGh0dHBzOi8vZGF0YWJhbmsud29ybGRiYW5rLm9yZy9tZXRhZGF0YWdsb3NzYXJ5L3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMvc2VyaWVzL1NJLkRTVC5GUlNULjIwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuIFBlcmNlbnRhZ2Ugc2hhcmVzIGJ5IHF1aW50aWxlIG1heSBub3Qgc3VtIHRvIDEwMCBiZWNhdXNlIG9mIHJvdW5kaW5nLgoKICAgIC0gICDmiYDlvpfjgb7jgZ/jga/mtojosrvjga7libLlkIjjga/jgIHjg4fjgrfjg6vjgb7jgZ/jga/kupTliIbkvY3mlbDjgafnpLrjgZXjgozjgovkurrlj6Pjga7jgrXjg5bjgrDjg6vjg7zjg5fjgavnmbrnlJ/jgZnjgovlibLlkIjjgafjgZnjgILkupTliIbkvY3mlbDjgavjgojjgovjgrfjgqfjgqLjga7libLlkIjjga/jgIHlm5vmjajkupTlhaXjga7jgZ/jgoExMDDjgavjgarjgonjgarjgYTloLTlkIjjgYzjgYLjgorjgb7jgZnjgIIoQXBwbGUpCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgc2Vjb25kIDIwJe+8mlNJLkRTVC4wMk5ELjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULjAyTkQuMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBq+WNoOOCgeOCi+WJsuWQiOOBr+OAgTEw5YiG5L2N44G+44Gf44GvNeWIhuS9jeOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+W4sOWxnuOBmeOCi+WJsuWQiOOBp+OBguOCi+OAguWbm+aNqOS6lOWFpeOBrumWouS/guS4iuOAgeS6lOWIhuS9jemajue0muWIpeOBruWJsuWQiOOBruWQiOioiOOBjDEwMOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCi+OAgu+8iERlZXBM77yJCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgdGhpcmQgMjAl77yaU0kuRFNULjAzUkQuMjAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjAzUkQuMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBq+WNoOOCgeOCi+WJsuWQiOOBr+OAgTEw5YiG5L2N44G+44Gf44GvNeWIhuS9jeOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+W4sOWxnuOBmeOCi+WJsuWQiOOBp+OBguOCi+OAguWbm+aNqOS6lOWFpeOBrumWouS/guS4iuOAgeS6lOWIhuS9jemajue0muWIpeOBruWJsuWQiOOBruWQiOioiOOBjDEwMOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCi+OAgu+8iERlZXBM77yJCgotICAgSW5jb21lIHNoYXJlIGhlbGQgYnkgZm91cnRoIDIwJe+8mlNJLkRTVC4wNFRILjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhYmFuay53b3JsZGJhbmsub3JnL21ldGFkYXRhZ2xvc3Nhcnkvd29ybGQtZGV2ZWxvcG1lbnQtaW5kaWNhdG9ycy9zZXJpZXMvU0kuRFNULjA0VEguMjApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4gUGVyY2VudGFnZSBzaGFyZXMgYnkgcXVpbnRpbGUgbWF5IG5vdCBzdW0gdG8gMTAwIGJlY2F1c2Ugb2Ygcm91bmRpbmcuCgogICAgLSAgIOaJgOW+l+OBvuOBn+OBr+a2iOiyu+OBruWJsuWQiOOBr+OAgeWNgeWIhuS9jeaVsOOBvuOBn+OBr+S6lOWIhuS9jeaVsOOBp+ekuuOBleOCjOOCi+S6uuWPo+OBruOCteODluOCsOODq+ODvOODl+OBq+eUn+OBmOOCi+WJsuWQiOOBp+OBmeOAguWbm+aNqOS6lOWFpeOBruOBn+OCgeOAgeS6lOWIhuS9jeWIpeOBruWJsuWQiOOBruWQiOioiOOBjCAxMDAg44Gr44Gq44KJ44Gq44GE5aC05ZCI44GM44GC44KK44G+44GZ44CCKEdvb2dsZSkKCi0gICBJbmNvbWUgc2hhcmUgaGVsZCBieSBoaWdoZXN0IDIwJe+8mlNJLkRTVC4wNVRILjIwIFtbTGlua10oaHR0cHM6Ly9kYXRhLndvcmxkYmFuay5vcmcvaW5kaWNhdG9yL1NJLkRTVC4wNVRILjIwKV0KCiAgICAtICAgUGVyY2VudGFnZSBzaGFyZSBvZiBpbmNvbWUgb3IgY29uc3VtcHRpb24gaXMgdGhlIHNoYXJlIHRoYXQgYWNjcnVlcyB0byBzdWJncm91cHMgb2YgcG9wdWxhdGlvbiBpbmRpY2F0ZWQgYnkgZGVjaWxlcyBvciBxdWludGlsZXMuIFBlcmNlbnRhZ2Ugc2hhcmVzIGJ5IHF1aW50aWxlIG1heSBub3Qgc3VtIHRvIDEwMCBiZWNhdXNlIG9mIHJvdW5kaW5nLgoKICAgIC0gICDmiYDlvpfjgb7jgZ/jga/mtojosrvjga7libLlkIjjga/jgIHljYHliIbkvY3mlbDjgb7jgZ/jga/kupTliIbkvY3mlbDjgafnpLrjgZXjgozjgovkurrlj6Pjga7jgrXjg5bjgrDjg6vjg7zjg5fjgavnlJ/jgZjjgovlibLlkIjjgafjgZnjgILlm5vmjajkupTlhaXjga7jgZ/jgoHjgIHkupTliIbkvY3liKXjga7libLlkIjjga7lkIjoqIjjgYwgMTAwIOOBq+OBquOCieOBquOBhOWgtOWQiOOBjOOBguOCiuOBvuOBmeOAggoKLSAgIEluY29tZSBzaGFyZSBoZWxkIGJ5IGhpZ2hlc3QgMTAl77yaU0kuRFNULjEwVEguMTAgW1tMaW5rXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvU0kuRFNULjEwVEguMTApXQoKICAgIC0gICBQZXJjZW50YWdlIHNoYXJlIG9mIGluY29tZSBvciBjb25zdW1wdGlvbiBpcyB0aGUgc2hhcmUgdGhhdCBhY2NydWVzIHRvIHN1Ymdyb3VwcyBvZiBwb3B1bGF0aW9uIGluZGljYXRlZCBieSBkZWNpbGVzIG9yIHF1aW50aWxlcy4KCiAgICAtICAg5omA5b6X44G+44Gf44Gv5raI6LK744Gu5Ymy5ZCI44Gv44CB5Y2B5YiG5L2N5pWw44G+44Gf44Gv5LqU5YiG5L2N5pWw44Gn56S644GV44KM44KL5Lq65Y+j44Gu44K144OW44Kw44Or44O844OX44Gr55Sf44GY44KL5Ymy5ZCI44Gn44GZ44CCCgojIyDmupblgpkKCuavjuWbniBgdGlkeXZlcnNlYCDjgaggYFdESWAg44GoIGBEZXNjVG9vbHNgIOOCkuS9v+OBhOOBvuOBmeOBi+OCieOAgVIgTm90ZWJvb2sg44Gu5pyA5Yid44Gr44Gv44CB5qyh44Gu44Kz44O844OJ44OB44Oj44Oz44Kv44KS5L2c5oiQ44GX44CB5a6f6KGM77yIUnVu77yJ44GX44G+44GZ44CC44GT44KM44KJ44Gu77yI5qmf6IO944KS5ouh5by144GZ44KL77yJ44OR44OD44Kx44O844K444GM44Kk44Oz44K544OI44O844Or44GV44KM44Gm44GE44Gq44GE5aC05ZCI44Gv44CB44Kk44Oz44K544OI44O844Or44GX44G+44GZ44CCVG9vbHNcPkluc3RhbGwgUGFja2FnZXMgLi4uCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoV0RJKQpsaWJyYXJ5KERlc2NUb29scykKYGBgCgojIyDjg4fjg7zjgr/jga7oqq3jgb/ovrzjgb8KCmBgYHtyIGV2YWwgPSBGQUxTRX0KZGZfZ2luaSA8LSBXREkoaW5kaWNhdG9yID0gYyhnaW5pID0gIlNJLlBPVi5HSU5JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAwLTEwYCA9ICJTSS5EU1QuRlJTVC4xMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgMC0yMGAgPSAiU0kuRFNULkZSU1QuMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDIwLTQwYCA9ICJTSS5EU1QuMDJORC4yMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgNDAtNjBgID0gIlNJLkRTVC4wM1JELjIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGA2MC04MGAgPSAiU0kuRFNULjA0VEguMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDgwLTEwMGAgPSAiU0kuRFNULjA1VEguMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYDkwLTEwMGAgPSAiU0kuRFNULjEwVEguMTAiKSkKYGBgCgoKCiMjIyDkv53lrZjjgajoqq3jgb/ovrzjgb8KCuS9leW6puOCguODgOOCpuODs+ODreODvOODieOBl+OBquOBj+OBpuiJr+OBhOOCiOOBhuOBq+OAgeS/neWtmOOBl+OBn+OCguOBruOCkuiqreOBv+i+vOOBv+OBvuOBmeOAggoKYGBge3IgZXZhbCA9IEZBTFNFfQp3cml0ZV9jc3YoZGZfZ2luaSwgImRhdGEvZ2luaS5jc3YiKQpgYGAKCmBgYHtyfQpkZl9naW5pIDwtIHJlYWRfY3N2KCJkYXRhL2dpbmkuY3N2IikKYGBgCiMjIyDjg4fjg7zjgr/jga7norroqo0KCmBgYHtyfQpkZl9naW5pCmBgYAoKIyMjIGdpbmkg44GMIE5BIOOBp+OBr+OBquOBhOWApOOBruOCguOBruOBruOBv+ihqOekuuOBl+OBvuOBmQoKYGBge3J9CmRmX2dpbmkgfD4gZHJvcF9uYShnaW5pKQpgYGAKCiMjIyDlpInlvaLvvJrlkITpmo7ntJrjga7lgKTjgpLnuKbjgavkuKbjgbnjgIHnuKbplbflvaLlvI/jga7ooajjgavjgZfjgb7jgZnjgIJMb25nIGZvcm1hdAoKYHBpdm90X2xvbmdlcihjb2xzLCBuYW1lc190byA9ICIiLCB2YWx1ZXNfdG8gPSAiIilgIOOBq+OBpOOBhOOBpuOBr+OBhOOBmuOCjOiqrOaYjuOBl+OBvuOBmeOAguOBk+OBk+OBp+OBr+OAgeODrOODmeODq+OBq+WIhuOBkeOCieOCjOOBn+OCguOBruOCkiBsZXZlbHMg44Go44GE44GG5ZCN44Gu5YiX44Gr44Os44OZ44Or44KS44CBdmFsdWUg44Go44GE44GG5ZCN44Gu5YiX44Gr44CB44Gd44Gu5YCk44KS5Lim44G544Gf44KC44Gu44Go44GX44G+44GZ44CCCgpgYGB7cn0KZGZfZ2luaV9sb25nIDwtIGRmX2dpbmkgfD4gCiAgcGl2b3RfbG9uZ2VyKGAwLTEwYDpgOTAtMTAwYCwgbmFtZXNfdG8gPSAibGV2ZWxzIiwgdmFsdWVzX3RvID0gInZhbHVlIikKZGZfZ2luaV9sb25nCmBgYAoKIyMjIOaVtOOBiOOCieOCjOOBn++8iHRpZHnvvInjg4fjg7zjgr8KCi0gICDlkITliJfjga/jgbLjgajjgaTjga7lpInmlbAKCi0gICDlkITooYzjga/jgbLjgajjgaTjga7oprPmuKzlgKQKCumajue0mu+8iGxldmVsc++8ieOCkuWkieaVsOOBqOOBl+OBpuaJseOBhuOBn+OCgeOBq+OAgeOBk+OBruOCiOOBhuOBq+WkieW9ouOBl+OBvuOBl+OBn+OAggoKIVtdKGh0dHBzOi8vaWN1LWhzdXp1a2kuZ2l0aHViLmlvL2RhNHIvZGF0YS90aWR5LTEucG5nKQoKIyMjIOOBqeOBruOBj+OCieOBhCBHSU5JIOOBruODh+ODvOOCv+OBjOOBguOCi+OBi+eiuuOBi+OCgeOCiwoKYGBge3J9CmRmX2dpbmkgfD4gZHJvcF9uYShnaW5pKSB8PiAKICBnZ3Bsb3QoYWVzKHllYXIpKSArIGdlb21fYmFyKCkKYGBgCgrlrp/pmpvjgavjga/jgIHmrKHjga7jgojjgYbjgaroqIjnrpfjgpLjgZfjgabjgIHmo5LjgrDjg6njg5XjgafooajnpLrjgZfjgabjgYTjgb7jgZnjgIIKCi0gICBgZ3JvdXBfYnkoeWVhcilgIOW5tOOBlOOBqOOBq+OCsOODq+ODvOODl+OBqOOBmeOCiwoKLSAgIGBzdW1tYXJpemUobiA9IG4oKSlgIOOBneOCjOOBnuOCjOOBruOCsOODq+ODvOODl+OBlOOBqOOBruODh+ODvOOCv+OCkuaVsOOBiOOBvuOBmeOAguebtOWJjeOBq+OAgWBkcm9wX25hKGdpbmkpYCDjgajjgZfjgabjgYLjgovjga7jgafjgIFgZ2luaWAg44GMIE5BIOOBp+OBr+OBquOBhOODh+ODvOOCv+OBruaVsOOCkuaVsOOBiOOBpuOBhOOBvuOBmeOAggoKLSAgIOajkuOCsOODqeODle+8mmBnZ3Bsb3QoYWVzKHllYXIsIG4pKSArIGdlb21fY29sKClgCgrjgZnjgarjgo/jgaHjgIHmrKHjga7jgoLjga7jgajlkIzjgZjjgafjgZnjgIIKCmBgYHtyfQpkZl9naW5pIHw+IGdyb3VwX2J5KHllYXIpIHw+IGRyb3BfbmEoZ2luaSkgfD4gCiAgc3VtbWFyaXplKG4gPSBuKCkpIHw+CiAgZ2dwbG90KGFlcyh5ZWFyLCBuKSkgKyBnZW9tX2NvbCgpCmBgYAoKIyMjIOWun+mam+OBruODh+ODvOOCv+OBruWAi+aVsAoKYGBge3J9CmRmX2dpbmlfbG9uZyB8PiAKICBncm91cF9ieSh5ZWFyLCBsZXZlbHMpIHw+IGRyb3BfbmEodmFsdWUpIHw+CiAgc3VtbWFyaXplKG51bSA9IG4oKSkgfD4gZGlzdGluY3QoeWVhciwgbnVtKSB8PiBhcnJhbmdlKGRlc2MoeWVhcikpCmBgYAoKIyMjIDIwMjLlubTjgavjg4fjg7zjgr/jgYzlrZjlnKjjgZnjgos344Gk44Gu5Zu95ZCN44KS6KGo56S6CgpgYGB7cn0KZGZfZ2luaV9sb25nIHw+IGZpbHRlcih5ZWFyID09IDIwMjIpIHw+IGRyb3BfbmEodmFsdWUpIHw+CiAgZGlzdGluY3QoY291bnRyeSwgZ2luaSkgfD4gYXJyYW5nZShnaW5pKQpgYGAKCiMjIyDvvJfjgqvlm73jga7jgYTjgY/jgaTjgYvjgavjgaTjgYTjgaboqr/jgbnjgosKCmB4ID0gbGV2ZWxzYCDjgajjgZfjgIFgeSA9IHZhbHVlYCDjgajjgZnjgovjgajjgZPjgo3jgafjgIFMb25nIOOBq+OBl+OBn+WKueaenOOBjOWHuuOBpuOBhOOBvuOBmeOAggoKYGBge3J9CkNPVU5UUllfR0lOSSA8LSAiQmh1dGFuIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJCYW5nbGFkZXNoIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgpgYGB7cn0KQ09VTlRSWV9HSU5JIDwtICJDb3N0YSBSaWNhIgpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gZmlsdGVyKGxldmVscyAhPSAiZ2luaSIpIHw+CiAgZmlsdGVyKGNvdW50cnkgPT0gQ09VTlRSWV9HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKCkKYGBgCgoqKue3tOe/kjEu44CASW5kb25lc2lhLCBFbCBTYWx2YWRvciwgUGFyYWd1YXksIEVjdWFkb3Ig44Gu44GE44Ga44KM44GL44Gr44Gk44GE44Gm44Kw44Op44OV44KS5o+P44GE44Gm44G/44G+44GX44KH44GG44CCKioKCmBgYHtyfQoKYGBgCgojIyMg5Lim44G544Gm5o+P44GE44Gm44G/44G+44GX44KH44GGCgrjgrjjg4vmjIfmlbDjga/lsI/jgZXjgYTjgbvjgYbjgYvjgonjgIFCaHV0YW4sIEJhbmdsYWRlc2gsIEluZG9uZXNpYSwgRWwgU2FsdmFkb3IsIFBhcmFndWF5LCBFcXVhZG9yLCBDb3N0YSBSaWNhIOOBp+OBl+OBn+OAggoKYGBge3J9CmRmX2dpbmlfbG9uZyB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiAKICBmaWx0ZXIobGV2ZWxzICE9ICJnaW5pIikgfD4gIGRyb3BfbmEodmFsdWUpIHw+CiAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpICsgZmFjZXRfd3JhcCh+Y291bnRyeSkKYGBgCgojIyMg6ICD44GI44Gm44G/44KI44GGCgoxLiAg5pyA5b6M5LiL44GM44Gj44Gm44GE44KL44Gu44Gv5q2j5bi477yfCgoyLiAg44Gp44Gu44KI44GG44Gr6KGo56S644GZ44KL44Gu44GM44KI44GE44Gu44Gg44KN44GG44GL44CCCgozLiAg44GT44KM44KJ44Gu5Zuz44KS44G/44Gm44CB44K444OL5oyH5pWw44Gu5aSn44GN44GV44Gr44Gk44GE44Gm44KP44GL44KK44G+44GZ44GL44CCCgo0LiAg44GT44Gu44OH44O844K/44GL44KJ44CB44K444OL5oyH5pWw44KS6KiI566X44GZ44KL44Gr44Gv44CB44Gp44GG44GX44Gf44KJ6Imv44GE44Gu44Gg44KN44GG44GL44CCCgojIyDjgrjjg4vmjIfmlbDjga7oqIjnrpcKCkRlcml2YXRpb24gb2YgdGhlIExvcmVueiBjdXJ2ZSBhbmQgR2luaSBjb2VmZmljaWVudCBmb3IgZ2xvYmFsIGluY29tZSBpbiAyMDExIFtb44Oq44Oz44KvXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9HaW5pX2NvZWZmaWNpZW50KV0KCiMjIyDjgrjjg4vmjIfmlbDjgpLoqIjnrpfjgZnjgovjgZ/jgoHjgavlpInmj5sKCmBgYHtyfQpkZl9naW5pX2NhbGMgPC0gZGZfZ2luaSB8PiAKICBtdXRhdGUoYDBgID0gMCwgYDEwYCA9IGAwLTEwYCwgYDIwYCA9IGAwLTIwYCwKICAgICAgICAgYDMwYCA9IGAwLTIwYCtgMjAtNDBgLzIsIGA0MGAgPSBgMC0yMGAgKyBgMjAtNDBgLCAKICAgICAgICAgYDUwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgLzIsIAogICAgICAgICBgNjBgID0gYDAtMjBgICsgYDIwLTQwYCArIGA0MC02MGAsIAogICAgICAgICBgNzBgID0gYDAtMjBgICsgYDIwLTQwYCArIGA0MC02MGAgKyBgNjAtODBgLzIsICAKICAgICAgICAgYDgwYCA9IGAwLTIwYCArIGAyMC00MGAgKyBgNDAtNjBgICsgYDYwLTgwYCwgCiAgICAgICAgIGA5MGAgPSBgMC0yMGAgKyBgMjAtNDBgICsgYDQwLTYwYCArIGA2MC04MGAgKyBgODAtMTAwYC1gOTAtMTAwYCwKICAgICAgICAgYDEwMGAgPSAxMDApIHw+CiAgc2VsZWN0KC1jKGAwLTEwYDpgOTAtMTAwYCkpICMg5LiN5b+F6KaB44Gq6YOo5YiG44KS5raI5Y67CmRmX2dpbmlfY2FsYyAlPiUgZHJvcF9uYSgpIApgYGAKCiMjIyDnuKbplbfjga4gTG9uZyBUYWJsZSDjgavlpInmj5sKCmBgYHtyfQpkZl9naW5pX2NhbGNfbG9uZyA8LSBkZl9naW5pX2NhbGMgfD4gIHBpdm90X2xvbmdlcihgMGA6YDEwMGAsIG5hbWVzX3RvID0gImNsYXNzZXMiLCB2YWx1ZXNfdG8gPSAiY3VtdWxhdGl2ZV9zaGFyZSIpIHw+IG11dGF0ZShjbGFzc2VzID0gYXMubnVtZXJpYyhjbGFzc2VzKSkKZGZfZ2luaV9jYWxjX2xvbmcgJT4lIGRyb3BfbmEoKSAKYGBgCgojIyMg56K66KqNCgpgYGB7cn0KZGZfZ2luaV9jYWxjX2xvbmcgfD4gZmlsdGVyKGNvdW50cnkgPT0gIkJhbmdsYWRlc2giKSB8PiAKICBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoY2xhc3NlcywgY3VtdWxhdGl2ZV9zaGFyZSkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4ID0gMCwgeSA9IDAsIHhlbmQgPSAxMDAsIHllbmQgPSAxMDApLCBjb2xvciA9ICdyZWQnKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwxMDAsYnk9MjApKSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwxMDAsYnk9MjApKSAjKwogICNhbm5vdGF0ZSgidGV4dCIsIHggPSAxMCwgeSA9IDgwLCBsYWJlbCA9IGdpbmkpCmBgYAoKIyMjIO+8lOOCq+WbveOCkuOCuOODi+aMh+aVsOmghuOBq+OBquOCieOBueOBn+ajkuOCsOODqeODlQoKYGBge3J9CkNPVU5UUklFU19HSU5JIDwtIGMoIkJodXRhbiIsICJCYW5nbGFkZXNoIiwiSW5kb25lc2lhIiwiQ29zdGEgUmljYSIpCllFQVJfR0lOSSA8LSAyMDIyCmRmX2dpbmlfbG9uZyB8PiAKICBmaWx0ZXIoY291bnRyeSAlaW4lIENPVU5UUklFU19HSU5JLCB5ZWFyID09IFlFQVJfR0lOSSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUsIGZpbGwgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gQ09VTlRSSUVTX0dJTkkpKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsgbGFicyhmaWxsID0gIiIpCmBgYAoKKirnt7Tnv5IyLiDvvJfjgqvlm73jgZnjgbnjgabjgavjgaTjgYTjgabjgIE4MC0xMDAg44Go44CBOTAtMTAwIOOBrumDqOWIhuOBoOOBkeOAgeihqOekuuOBp+OBjeOBquOBhOOBp+OBl+OCh+OBhuOBi+OAgu+8iOmbo++8muetlOOBiOOBr+S4gOeVquS4i++8iSoqCgpgYGB7cn0KCmBgYAoKKioyMDAw5bm044Gu44K444OL5oyH5pWw44GoOTDvvIXku6XkuIrjga7libLlkIjjga7nm7jplqIqKgoKYGBge3J9CmRmX2dpbmkgfD4gCiAgZmlsdGVyKHllYXIgPT0gMjAwMCkgfD4gZHJvcF9uYShnaW5pKSB8PgogIGdncGxvdChhZXMoZ2luaSwgYDkwLTEwMGApKSArIGdlb21fcG9pbnQoKSArIAogIGdlb21fc21vb3RoKGZvcm11bGEgPSAneSB+IHgnLCBtZXRob2QgPSAibG0iKQpgYGAKCioq57e057+SMy4gMjAwMOW5tO+8iOOBvuOBn+OBr+S7luOBruW5tOOBru+8ieOCuOODi+aMh+aVsOOBqDgw77yF5Lul5LiK44Gu5Ymy5ZCI44Gu55u46ZaiKioKCmBgYHtyfQoKYGBgCgojIyDlvqnnv5IKCi0gICDjg5Hjg4PjgrHjg7zjgrjvvIhQYWNrYWdl77yJ44Gu5Yip55So77yaCgogICAgLSAgIOOCpOODs+OCueODiOODvOODq++8iGluc3RhbGxhdGlvbu+8ie+8mlRvb2xzIFw+IEluc3RhbGwgUGFja2FnZXMKCiAgICAtICAg44Ot44O844OJ77yIbG9hZO+8iWBsaWJyYXJ5KHRpZHl2ZXJzZSk7IGxpYnJhcnkoV0RJKTsgbGlicmFyeShEZXNjVG9vbHMpYAoKLSAgIOODh+ODvOOCv+OBruWPluW+l++8mmBgIFdESShpbmRpY2F0b3IgPSBjKGdpbmkgPSAiU0kuUE9WLkdJTkkiLGAwLTEwYCA9ICJTSS5EU1QuRlJTVC4xMCIsLi4uLGA5MC0xMDBgID0gIlNJLkRTVC4xMFRILjEwIikpIGBgCgotICAg54m55a6a44Gu6KGM44Gu5Y+W5b6X77yaYGZpbHRlcigpLCBkcm9wX25hKCksIGRpc3RpbmN0KClgCgotICAg5qOS44Kw44Op44OVCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHllYXIpKSArIGdlb21fYmFyKClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUpKSArIGdlb21fY29sKClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSBsZXZlbHMsIHkgPSB2YWx1ZSwgZmlsbCA9IGNvdW50cnkpKSArIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIilgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKHggPSBnaW5pLCBmaWxsID0gcmVnaW9uKSkgKyBnZW9tX2hpc3RvZ3JhbSgpYAoKLSAgIOaVo+W4g+Wbs++8iCvlm57luLDnm7Tnt5rvvIkKCiAgICAtICAgYGdncGxvdChhZXMoZ2luaSwgOTAtMTAwKSkgKyBnZW9tX3BvaW50KClgCgogICAgLSAgIGBnZ3Bsb3QoYWVzKGdpbmksIDgwLTEwMCkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoZm9ybXVsYSA9ICd5IH4geCcsIG1ldGhvZCA9ICJsbSIpYAoKIyMg6Kqy6aGMCgoqKue3tOe/kjEg44GL44KJ57e057+SMy4qKgoK5o+Q5Ye644Gv44GX44Gq44GP44Gm6Imv44GE44Gn44GZ44GM44CB44Gc44Gy5a6f6Zqb44Gr5omL44KS5YuV44GL44GX44Gm5a6f6KGM44GX44Gm44GP44Gg44GV44GE44CCCgojIyDlj4LogIPmlofnjK4KCjEuICDjgIzjgb/jgpPjgarjga7jg4fjg7zjgr/jgrXjgqTjgqjjg7PjgrkgLSBEYXRhIFNjaWVuY2UgZm9yIEFsbOOAjVtb44Gv44GY44KB44Gm44Gu44OH44O844K/44K144Kk44Ko44Oz44K5XShodHRwczovL2ljdS1oc3V6dWtpLmdpdGh1Yi5pby9kczRhai9maXJzdC1leGFtcGxlLmh0bWwjZmlyc3QtZXhhbXBsZSldCgogICAgLSAgIOWwjuWFpeOBqOOBl+OBpuOAgUdEUO+8iOWbveWGhee3j+eUn+eUo++8ieOBruODh+ODvOOCv+OCkuS9v+OBo+OBpuiqrOaYjuOBl+OBpuOBhOOBvuOBmeOAggoKMi4gIFBvc2l0IFJlY2lwZXPvvIjml6cgUG9zaXQgUHJpbWVyc++8iTogVGhlIEJhc2ljcyDlr77oqbHlnovjga7mvJTnv5LjgrXjgqTjg4jjga7mnIDliJ0gW1tMaW5rXShodHRwczovL3Bvc2l0LmNsb3VkL2xlYXJuL3JlY2lwZXMpXQoKMy4gIFBvc2l0IENoZWF0IFNoZWV0LiDml6nopovooajjgafjgZnjgILljbDliLfjgZfjgabkvb/jgYbjgZ/jgoHjgavjgIFQREYg44KC5o+Q5L6b44GX44Gm44GE44G+44GZ44CCW1tTaXRlIExpbmtdKGh0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vY2hlYXRzaGVldHMvKV0KCjQuICBEYXRhQ2FtcCBDaGVhdCBTaGVldDogVGlkeXZlcnNlIGZvciBCaWdpbm5lcnMuIOODh+ODvOOCv+OCteOCpOOCqOODs+OCueOBruaVmeiCsuOCkuOBl+OBpuOBhOOCi+S8muekvuOBruaXqeimi+ihqOOBruS4gOOBpOOBp+OBmeOAguWfuuacrOOBjOewoeWNmOOBq+OBvuOBqOOBvuOBo+OBpuOBhOOBvuOBmeOAgltbTGlua10oaHR0cHM6Ly9pbWFnZXMuZGF0YWNhbXAuY29tL2ltYWdlL3VwbG9hZC92MTY3NjMwMjY5Ny9NYXJrZXRpbmcvQmxvZy9UaWR5dmVyc2VfQ2hlYXRfU2hlZXQucGRmKV0KCjwhLS0gIyMg5Y+C6ICD77yRIC0tPgoKPCEtLSDpmo7ntJrjgpIgMTAlIOWIu+OBv+OBq+e1seS4gOOBl+OAgUxvbmcg5b2i5byP44Gr5aSJ5o+b44CCIC0tPgoKPCEtLSBgYGB7cn0gLS0+CjwhLS0gZGZfZ2luaV9yZXYgPC0gZGZfZ2luaSB8PiAgLS0+CjwhLS0gICBtdXRhdGUoYDAtMTBgID0gYDAtMTBgLCBgMTAtMjBgID0gYDAtMjBgLWAwLTEwYCxgMjAtMzBgID0gYDIwLTQwYC8yLCBgMzAtNDBgID0gYDIwLTQwYC8yLCBgNDAtNTBgID0gYDQwLTYwYC8yLCBgNTAtNjBgID0gYDQwLTYwYC8yLCBgNjAtNzBgID0gYDYwLTgwYC8yLCBgNzAtODBgPWA2MC04MGAvMiwgYDgwLTkwYCA9IGA4MC0xMDBgLWA5MC0xMDBgLCBgOTAtMTAwYCA9IGA5MC0xMDBgKSB8PiAgLS0+CjwhLS0gICBzZWxlY3QoLWMoYDAtMjBgLCBgMjAtNDBgLGA0MC02MGAsYDYwLTgwYCwgYDgwLTEwMGApKSB8PiAgLS0+CjwhLS0gICBzZWxlY3QoMTo2LCA4OjE1LCA3KSAgLS0+CjwhLS0gZGZfZ2luaV9yZXYgJT4lIGRyb3BfbmEoKSAtLT4KPCEtLSBgYGAgLS0+Cgo8IS0tIGBgYHtyfSAtLT4KPCEtLSBkZl9naW5pX3Jldl9sb25nIDwtIGRmX2dpbmlfcmV2IHw+IHBpdm90X2xvbmdlcig2OjE1LCBuYW1lc190byA9ICJsZXZlbHMiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAtLT4KPCEtLSBkZl9naW5pX3Jldl9sb25nIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gYGBge3IgZmlnLmhlaWdodD05LCBmaWcud2lkdGg9OH0gLS0+CjwhLS0gZGZfZ2luaV9yZXZfbG9uZyB8PiBmaWx0ZXIoeWVhciA9PSAyMDIyKSB8PiBkcm9wX25hKGdpbmkpIHw+IC0tPgo8IS0tICAgZ2dwbG90KGFlcyhsZXZlbHMsIHZhbHVlKSkgKyBnZW9tX2NvbCgpICsgIC0tPgo8IS0tICAgZmFjZXRfd3JhcCh+Y291bnRyeSwgbmNvbCA9IDIpIC0tPgo8IS0tIGBgYCAtLT4KCjwhLS0gIyMg5Y+C6ICD77ySIC0tPgoKPCEtLSDmm7Lnt5rjga7kuIvjga7pnaLnqY3jgpLoqIjnrpfjgZnjgovjgIBBVUMg44KS5Yip55So44GX44Gm44CB44K444OL5L+C5pWw44KS6KiI566X44CCIC0tPgoKPCEtLSBBcmVhIFVuZGVyIHRoZSBDdXJ2ZTogW1vjg6rjg7Pjgq9dKGh0dHBzOi8vc2VhcmNoLnItcHJvamVjdC5vcmcvQ1JBTi9yZWZtYW5zL0Rlc2NUb29scy9odG1sL0FVQy5odG1sKV0gLS0+Cgo8IS0tIDxodHRwczovL3JkcnIuaW8vY3Jhbi9EZXNjVG9vbHMvZi8+IC0tPgoKPCEtLSBgYGB7cn0gLS0+CjwhLS0gZGZfZ2luaV9jYWxjX2xvbmcgfD4gZ3JvdXBfYnkoY291bnRyeSwgeWVhcikgfD4gIC0tPgo8IS0tICAgZHJvcF9uYShnaW5pKSB8PiAtLT4KPCEtLSAgIHJlZnJhbWUoZ2luaSwgZ2luaV9zcGxpbmUgPSByb3VuZCgxMDAtQVVDKGNsYXNzZXMsIGN1bXVsYXRpdmVfc2hhcmUsIG1ldGhvZCA9ICJzcGxpbmUiKS81MCwgZGlnaXRzID0gMSksIGdpbmlfdHJhcGV6b2lkID0gcm91bmQoMTAwLUFVQyhjbGFzc2VzLCBjdW11bGF0aXZlX3NoYXJlKS81MCwgZGlnaXRzID0gMSkpIHw+ICAtLT4KPCEtLSAgIGRpc3RpbmN0KGNvdW50cnksIHllYXIsIGdpbmksIGdpbmlfc3BsaW5lLCBnaW5pX3RyYXBlem9pZCkgLS0+CjwhLS0gYGBgIC0tPgoKIyMjIOe3tOe/kjLjga7nrZTjgYgKCmBgYHtyfQpTRVZFTl9DT1VOVFJJRVMgPC0gYygiQmh1dGFuIiwgIkJhbmdsYWRlc2giLCJJbmRvbmVzaWEiLCJFbCBTYWx2YWRvciIsICJQYXJhZ3VheSIsICJFcXVhZG9yIiwgIkNvc3RhIFJpY2EiKQpZRUFSX0dJTkkgPC0gMjAyMgpkZl9naW5pX2xvbmcgfD4gCiAgZmlsdGVyKGNvdW50cnkgJWluJSBTRVZFTl9DT1VOVFJJRVMsIHllYXIgPT0gWUVBUl9HSU5JKSB8PgogIGZpbHRlcihsZXZlbHMgJWluJSBjKCc4MC0xMDAnLCc5MC0xMDAnKSkgfD4KICBnZ3Bsb3QoYWVzKGxldmVscywgdmFsdWUsIGZpbGwgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gU0VWRU5fQ09VTlRSSUVTKSkpICsgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiLCBjb2wgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjIpICsgbGFicyhmaWxsID0gIiIpCmBgYAo=