演習の概要

注意事項

  • 慶應義塾大学SFCで開講している「環境ガバナンスのデータサイエンス」「空間モデリング特論」の授業履修者向けの演習用ページです。
  • 必ずしも全てのバージョンのRやOSで動作確認を行っていません。この演習用ページを作成している段階では、R3.5.3を使っています。
  • Rの更新などにより、Rコードなどを予告無しに変更する場合があります。

データ分析の準備

データのダウンロード

  • 演習で用いるデータはここからダウンロードしてください。
  • ここでは./直下にgisdataフォルダを作成し、setwd("gisdata")とディレクトリを指定しています

パッケージのインストール

  • install.packages()でパッケージをインストールし、library()でパッケージを呼び出す
  • ここでは以下のパッケージを用います
install.packages("spdep")
install.packages("sf")
install.packages("spatstat")
install.packages("tidyverse")
install.packages("kokudosuuchi")
library(spdep)
library(sf)
library(spatstat)
library(tidyverse)
library(kokudosuuchi)

以下の方法でパイプ %>% の優先順位を高める

needs::prioritize(magrittr)

データの読み込み

都道府県境界データ(ポリゴン)、都道府県庁所在地データ(ポイント)及び都道府県別属性データを読み込みます。

pref_pnt <- sf::st_read('pref_gov.shp')
jpn_pref <- sf::st_read('jpn_pref.shp')
hd06 <- readr::read_csv("hd06.csv")

都道府県境界ポリゴンデータに属性データhd06を結合します。

jpn_pref_hd06 <- dplyr::inner_join(jpn_pref, hd06, by=c("PREF_CODE"="PREF_CODE"))

リスク分析

粗率

確率地図を作成する

spdepprobmap()で確率地図を作成する。粗率は以下のように計算する。

jpn_hd06_pm <- spdep::probmap(jpn_pref_hd06$HD06, jpn_pref_hd06$POPJ06/100)
summary(jpn_hd06_pm)
      raw            expCount        relRisk            pmap       
 Min.   : 95.15   Min.   :  822   Min.   : 69.45   Min.   :0.0000  
 1st Qu.:137.58   1st Qu.: 1581   1st Qu.:100.42   1st Qu.:0.5122  
 Median :152.10   Median : 2381   Median :111.02   Median :1.0000  
 Mean   :151.09   Mean   : 3677   Mean   :110.28   Mean   :0.7424  
 3rd Qu.:169.73   3rd Qu.: 3729   3rd Qu.:123.89   3rd Qu.:1.0000  
 Max.   :199.93   Max.   :16995   Max.   :145.93   Max.   :1.0000  

主題図を作成する

まず、都道府県別心疾患死亡者数を地図上に可視化する

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=HD06)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Number of Death by Heart Disease")

粗率(ここでは、心疾患死亡者数/人口数x100)の計算結果はjpn_hd06_pmrawに格納されている

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_pm$raw)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Raw Rate of Death by Heart Disease")

相対危険度

主題図を作成する

リスクの期待値と相対危険度の計算結果はjpn_hd06_pmexpCountrelRiskに格納されている。

期待値の主題図は以下のように描画できる。

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_pm$expCount)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Expected Count of Death by Heart Disease")

相対危険度の主題図は以下のように描画できる。

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_pm$relRisk)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Expected Count of Death by Heart Disease")

ポアソン確率

主題図を作成する

ポアソン確率の計算結果はjpn_hd06_pmpmapに格納されている。

主題図は以下のようにして描画できる。

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_pm$pmap)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Poisson Probability of Death by Heart Disease")

相対リスクのベイズ推定

グローバルな経験ベイズ推定

Marshallのグローバルな経験ベイズ推定を行うには、spdepEBest()関数を用いる。

jpn_hd06_ebg <- EBest(jpn_pref_hd06$HD06, jpn_pref_hd06$POPJ06/100)
summary(jpn_hd06_ebg)
      raw             estmm       
 Min.   : 95.15   Min.   : 95.95  
 1st Qu.:137.58   1st Qu.:137.55  
 Median :152.10   Median :151.82  
 Mean   :151.09   Mean   :150.73  
 3rd Qu.:169.73   3rd Qu.:168.51  
 Max.   :199.93   Max.   :198.81  

以下のようにグローバルな経験ベイズ推定結果の主題図を作成する。

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_ebg$estmm)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Global EB Estimate of Death by Heart Disease Risk")

ローカルな経験ベイズ推定

Marshallのローカルな経験ベイズ推定を行うには、まず隣接行列を定義したのち、spdepEBlocal()関数を用いる。

隣接行列を定義する

pref.tri.nb <- sf::st_coordinates(st_centroid(pref.pnt)) %>%
                    spdep::tri2nb()

ローカルな経験ベイズ推定を行う

jpn_hd06_ebl <- EBlocal(jpn_pref_hd06$HD06, jpn_pref_hd06$POPJ06/100, pref.tri.nb)
summary(jpn_hd06_ebl)
      raw              est       
 Min.   : 95.15   Min.   : 95.7  
 1st Qu.:137.58   1st Qu.:138.0  
 Median :152.10   Median :151.3  
 Mean   :151.09   Mean   :150.8  
 3rd Qu.:169.73   3rd Qu.:169.0  
 Max.   :199.93   Max.   :199.1  

ローカルな経験ベイズ推定結果の主題図を作成する。

ggplot2::ggplot(data = jpn_pref_hd06, aes(fill=jpn_hd06_ebl$est)) + 
  geom_sf() + 
  scale_fill_distiller(palette="Reds", trans = "reverse") + 
  theme_bw() +
  labs(title = "Local EB Estimate of Death by Heart Disease Risk")

ローカルな経験ベイズ推定によるMoran’s Iの繰り返し検定

EBImoran.mc(jpn_pref_hd06$HD06, jpn_pref_hd06$POPJ06/100, 
            nb2listw(pref.tri.nb, style="W", zero.policy=TRUE), 
            nsim=999, zero.policy=TRUE)
The default for subtract_mean_in_numerator set TRUE from February 2016

    Monte-Carlo simulation of Empirical Bayes Index (mean subtracted)

data:  cases: jpn_pref_hd06$HD06, risk population: jpn_pref_hd06$POPJ06/100
weights: nb2listw(pref.tri.nb, style = "W", zero.policy = TRUE)
number of simulations + 1: 1000

statistic = 0.015911, observed rank = 680, p-value = 0.32
alternative hypothesis: greater

通常のMoran’s Iの繰り返し検定

set.seed(1234)
moran.mc(jpn_pref_hd06$POPJ06/100, 
            listw=nb2listw(pref.tri.nb, style="W", zero.policy=TRUE), 
            nsim=999, zero.policy=TRUE)

    Monte-Carlo simulation of Moran I

data:  jpn_pref_hd06$POPJ06/100 
weights: nb2listw(pref.tri.nb, style = "W", zero.policy = TRUE)  
number of simulations + 1: 1000 

statistic = -0.1045, observed rank = 149, p-value = 0.851
alternative hypothesis: greater
LS0tCnRpdGxlOiAi56m66ZaT44Oi44OH44Oq44Oz44KwUua8lOe/kjUiCiNhdXRob3I6ICJUb21veXVraSBGdXJ1dGFuaSIKI2RhdGU6ICIyMDE5LzMvMjkiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAotLS0KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGUgPSBUUlVFKQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3IgPSBUUlVFKQpgYGAKCiMjIOa8lOe/kuOBruamguimgQotIOODquOCueOCr+WIhuaekO+8mueyl+eOh+OAgeebuOWvvuWNsemZuuW6puOAgeODneOCouOCveODs+eiuueOh+OAgeebuOWvvuODquOCueOCr+OBruODmeOCpOOCuuaOqOWumgoKIyMjIOazqOaEj+S6i+mghQotIOaFtuaHiee+qeWhvuWkp+WtplNGQ+OBp+mWi+ism+OBl+OBpuOBhOOCi+OAjOepuumWk+ODouODh+ODquODs+OCsOOAjeOBruaOiOalreWxpeS/ruiAheWQkeOBkeOBrua8lOe/kueUqOODmuODvOOCuOOBp+OBmeOAggotIOW/heOBmuOBl+OCguWFqOOBpuOBruODkOODvOOCuOODp+ODs+OBrlLjgoRPU+OBp+WLleS9nOeiuuiqjeOCkuihjOOBo+OBpuOBhOOBvuOBm+OCk+OAguOBk+OBrua8lOe/kueUqOODmuODvOOCuOOCkuS9nOaIkOOBl+OBpuOBhOOCi+autemajuOBp+OBr+OAgVIzLjUuM+OCkuS9v+OBo+OBpuOBhOOBvuOBmeOAggotIFLjga7mm7TmlrDjgarjganjgavjgojjgorjgIFS44Kz44O844OJ44Gq44Gp44KS5LqI5ZGK54Sh44GX44Gr5aSJ5pu044GZ44KL5aC05ZCI44GM44GC44KK44G+44GZ44CCIAoKIyMg44OH44O844K/5YiG5p6Q44Gu5rqW5YKZCiMjIyDjg4fjg7zjgr/jga7jg4Djgqbjg7Pjg63jg7zjg4kKLSDmvJTnv5LjgafnlKjjgYTjgovjg4fjg7zjgr/jga9b44GT44GTXShodHRwOi8vd2ViLnNmYy5rZWlvLmFjLmpwL35tYXVuei9hc2FrdXJhX3NwL2FzYWt1cmFfc3BfZGF0YV8xMTAxLnppcCnjgYvjgonjg4Djgqbjg7Pjg63jg7zjg4njgZfjgabjgY/jgaDjgZXjgYTjgIIKLSDjgZPjgZPjgafjga9gLi9g55u05LiL44GrYGdpc2RhdGFg44OV44Kp44Or44OA44KS5L2c5oiQ44GX44CBYHNldHdkKCJnaXNkYXRhIilg44Go44OH44Kj44Os44Kv44OI44Oq44KS5oyH5a6a44GX44Gm44GE44G+44GZCgojIyMg44OR44OD44Kx44O844K444Gu44Kk44Oz44K544OI44O844OrCi0gYGluc3RhbGwucGFja2FnZXMoKWDjgafjg5Hjg4PjgrHjg7zjgrjjgpLjgqTjg7Pjgrnjg4jjg7zjg6vjgZfjgIFgbGlicmFyeSgpYOOBp+ODkeODg+OCseODvOOCuOOCkuWRvOOBs+WHuuOBmQotIOOBk+OBk+OBp+OBr+S7peS4i+OBruODkeODg+OCseODvOOCuOOCkueUqOOBhOOBvuOBmQoKYGBge3IgaW5zdGFsbCBwYWNrYWdlcywgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygic3BkZXAiKQppbnN0YWxsLnBhY2thZ2VzKCJzZiIpCmluc3RhbGwucGFja2FnZXMoInNwYXRzdGF0IikKaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKaW5zdGFsbC5wYWNrYWdlcygia29rdWRvc3V1Y2hpIikKYGBgCgpgYGB7ciBsaWJyYXJ5LCBldmFsPUZBTFNFfQpsaWJyYXJ5KHNwZGVwKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHNwYXRzdGF0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShrb2t1ZG9zdXVjaGkpCmBgYAoK5Lul5LiL44Gu5pa55rOV44Gn44OR44Kk44OXICU+JSDjga7lhKrlhYjpoIbkvY3jgpLpq5jjgoHjgosKYGBge3IgcGlwZV9wcmlvcml0aXplfQpuZWVkczo6cHJpb3JpdGl6ZShtYWdyaXR0cikKYGBgCgojIyMg44OH44O844K/44Gu6Kqt44G/6L6844G/CumDvemBk+W6nOecjOWig+eVjOODh+ODvOOCv++8iOODneODquOCtOODs++8ieOAgemDvemBk+W6nOecjOW6geaJgOWcqOWcsOODh+ODvOOCv++8iOODneOCpOODs+ODiO+8ieWPiuOBs+mDvemBk+W6nOecjOWIpeWxnuaAp+ODh+ODvOOCv+OCkuiqreOBv+i+vOOBv+OBvuOBmeOAggpgYGB7ciBqcG5fZGF0YSwgZXZhbD1GQUxTRX0KcHJlZl9wbnQgPC0gc2Y6OnN0X3JlYWQoJ3ByZWZfZ292LnNocCcpCmpwbl9wcmVmIDwtIHNmOjpzdF9yZWFkKCdqcG5fcHJlZi5zaHAnKQpoZDA2IDwtIHJlYWRyOjpyZWFkX2NzdigiaGQwNi5jc3YiKQpgYGAKCumDvemBk+W6nOecjOWig+eVjOODneODquOCtOODs+ODh+ODvOOCv+OBq+WxnuaAp+ODh+ODvOOCv2BoZDA2YOOCkue1kOWQiOOBl+OBvuOBmeOAggpgYGB7ciBqcG5fbWF0Y2gsIGV2YWw9RkFMU0V9Cmpwbl9wcmVmX2hkMDYgPC0gZHBseXI6OmlubmVyX2pvaW4oanBuX3ByZWYsIGhkMDYsIGJ5PWMoIlBSRUZfQ09ERSI9IlBSRUZfQ09ERSIpKQpgYGAKCiMjIOODquOCueOCr+WIhuaekAojIyMg57KX546HCiMjIyDnorrnjoflnLDlm7PjgpLkvZzmiJDjgZnjgosKYHNwZGVwYOOBrmBwcm9ibWFwKClg44Gn56K6546H5Zyw5Zuz44KS5L2c5oiQ44GZ44KL44CC57KX546H44Gv5Lul5LiL44Gu44KI44GG44Gr6KiI566X44GZ44KL44CCCmBgYHtyIGpwbl9yaXNrMX0KanBuX2hkMDZfcG0gPC0gc3BkZXA6OnByb2JtYXAoanBuX3ByZWZfaGQwNiRIRDA2LCBqcG5fcHJlZl9oZDA2JFBPUEowNi8xMDApCnN1bW1hcnkoanBuX2hkMDZfcG0pCmBgYAojIyMjIOS4u+mhjOWbs+OCkuS9nOaIkOOBmeOCiwrjgb7jgZrjgIHpg73pgZPlupznnIzliKXlv4Pnlr7mgqPmrbvkuqHogIXmlbDjgpLlnLDlm7PkuIrjgavlj6/oppbljJbjgZnjgosKYGBge3IganBuX3Jpc2sxX21hcH0KZ2dwbG90Mjo6Z2dwbG90KGRhdGEgPSBqcG5fcHJlZl9oZDA2LCBhZXMoZmlsbD1IRDA2KSkgKyAKICBnZW9tX3NmKCkgKyAKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlPSJSZWRzIiwgdHJhbnMgPSAicmV2ZXJzZSIpICsgCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJOdW1iZXIgb2YgRGVhdGggYnkgSGVhcnQgRGlzZWFzZSIpCmBgYAoK57KX546H77yI44GT44GT44Gn44Gv44CB5b+D55a+5oKj5q275Lqh6ICF5pWwL+S6uuWPo+aVsHgxMDDvvInjga7oqIjnrpfntZDmnpzjga9ganBuX2hkMDZfcG1g44GuYHJhd2DjgavmoLzntI3jgZXjgozjgabjgYTjgosKYGBge3IganBuX3Jpc2syX21hcH0KZ2dwbG90Mjo6Z2dwbG90KGRhdGEgPSBqcG5fcHJlZl9oZDA2LCBhZXMoZmlsbD1qcG5faGQwNl9wbSRyYXcpKSArIAogIGdlb21fc2YoKSArIAogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGU9IlJlZHMiLCB0cmFucyA9ICJyZXZlcnNlIikgKyAKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gIlJhdyBSYXRlIG9mIERlYXRoIGJ5IEhlYXJ0IERpc2Vhc2UiKQpgYGAKCiMjIyDnm7jlr77ljbHpmbrluqYKIyMjIyDkuLvpoYzlm7PjgpLkvZzmiJDjgZnjgosK44Oq44K544Kv44Gu5pyf5b6F5YCk44Go55u45a++5Y2x6Zm65bqm44Gu6KiI566X57WQ5p6c44GvYGpwbl9oZDA2X3BtYOOBrmBleHBDb3VudGDjgahgcmVsUmlza2DjgavmoLzntI3jgZXjgozjgabjgYTjgovjgIIKCuacn+W+heWApOOBruS4u+mhjOWbs+OBr+S7peS4i+OBruOCiOOBhuOBq+aPj+eUu+OBp+OBjeOCi+OAggpgYGB7ciBqcG5fcmlzazNfbWFwfQpnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YSA9IGpwbl9wcmVmX2hkMDYsIGFlcyhmaWxsPWpwbl9oZDA2X3BtJGV4cENvdW50KSkgKyAKICBnZW9tX3NmKCkgKyAKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlPSJSZWRzIiwgdHJhbnMgPSAicmV2ZXJzZSIpICsgCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJFeHBlY3RlZCBDb3VudCBvZiBEZWF0aCBieSBIZWFydCBEaXNlYXNlIikKYGBgCgrnm7jlr77ljbHpmbrluqbjga7kuLvpoYzlm7Pjga/ku6XkuIvjga7jgojjgYbjgavmj4/nlLvjgafjgY3jgovjgIIKYGBge3IganBuX3Jpc2s0X21hcH0KZ2dwbG90Mjo6Z2dwbG90KGRhdGEgPSBqcG5fcHJlZl9oZDA2LCBhZXMoZmlsbD1qcG5faGQwNl9wbSRyZWxSaXNrKSkgKyAKICBnZW9tX3NmKCkgKyAKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlPSJSZWRzIiwgdHJhbnMgPSAicmV2ZXJzZSIpICsgCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJFeHBlY3RlZCBDb3VudCBvZiBEZWF0aCBieSBIZWFydCBEaXNlYXNlIikKYGBgCgojIyMg44Od44Ki44K944Oz56K6546HCiMjIyMg5Li76aGM5Zuz44KS5L2c5oiQ44GZ44KLCuODneOCouOCveODs+eiuueOh+OBruioiOeul+e1kOaenOOBr2BqcG5faGQwNl9wbWDjga5gcG1hcGDjgavmoLzntI3jgZXjgozjgabjgYTjgovjgIIKCuS4u+mhjOWbs+OBr+S7peS4i+OBruOCiOOBhuOBq+OBl+OBpuaPj+eUu+OBp+OBjeOCi+OAggpgYGB7ciBqcG5fcmlzazVfbWFwfQpnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YSA9IGpwbl9wcmVmX2hkMDYsIGFlcyhmaWxsPWpwbl9oZDA2X3BtJHBtYXApKSArIAogIGdlb21fc2YoKSArIAogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGU9IlJlZHMiLCB0cmFucyA9ICJyZXZlcnNlIikgKyAKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gIlBvaXNzb24gUHJvYmFiaWxpdHkgb2YgRGVhdGggYnkgSGVhcnQgRGlzZWFzZSIpCmBgYAoKIyMjIOebuOWvvuODquOCueOCr+OBruODmeOCpOOCuuaOqOWumgojIyMjIOOCsOODreODvOODkOODq+OBque1jOmok+ODmeOCpOOCuuaOqOWumgpNYXJzaGFsbOOBruOCsOODreODvOODkOODq+OBque1jOmok+ODmeOCpOOCuuaOqOWumuOCkuihjOOBhuOBq+OBr+OAgWBzcGRlcGDjga5gRUJlc3QoKWDplqLmlbDjgpLnlKjjgYTjgovjgIIKCmBgYHtyIGpwbl9yaXNrMn0KanBuX2hkMDZfZWJnIDwtIEVCZXN0KGpwbl9wcmVmX2hkMDYkSEQwNiwganBuX3ByZWZfaGQwNiRQT1BKMDYvMTAwKQpzdW1tYXJ5KGpwbl9oZDA2X2ViZykKYGBgCgrku6XkuIvjga7jgojjgYbjgavjgrDjg63jg7zjg5Djg6vjgarntYzpqJPjg5njgqTjgrrmjqjlrprntZDmnpzjga7kuLvpoYzlm7PjgpLkvZzmiJDjgZnjgovjgIIKYGBge3IganBuX3Jpc2s2X21hcH0KZ2dwbG90Mjo6Z2dwbG90KGRhdGEgPSBqcG5fcHJlZl9oZDA2LCBhZXMoZmlsbD1qcG5faGQwNl9lYmckZXN0bW0pKSArIAogIGdlb21fc2YoKSArIAogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGU9IlJlZHMiLCB0cmFucyA9ICJyZXZlcnNlIikgKyAKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gIkdsb2JhbCBFQiBFc3RpbWF0ZSBvZiBEZWF0aCBieSBIZWFydCBEaXNlYXNlIFJpc2siKQpgYGAKCiMjIyMg44Ot44O844Kr44Or44Gq57WM6aiT44OZ44Kk44K65o6o5a6aCk1hcnNoYWxs44Gu44Ot44O844Kr44Or44Gq57WM6aiT44OZ44Kk44K65o6o5a6a44KS6KGM44GG44Gr44Gv44CB44G+44Ga6Zqj5o6l6KGM5YiX44KS5a6a576p44GX44Gf44Gu44Gh44CBYHNwZGVwYOOBrmBFQmxvY2FsKClg6Zai5pWw44KS55So44GE44KL44CCCgrpmqPmjqXooYzliJfjgpLlrprnvqnjgZnjgosKYGBge3IganBuX3RyaX0KcHJlZi50cmkubmIgPC0gc2Y6OnN0X2Nvb3JkaW5hdGVzKHN0X2NlbnRyb2lkKHByZWYucG50KSkgJT4lCiAgICAgICAgICAgICAgICAgICAgc3BkZXA6OnRyaTJuYigpCmBgYArjg63jg7zjgqvjg6vjgarntYzpqJPjg5njgqTjgrrmjqjlrprjgpLooYzjgYYKYGBge3IganBuX3Jpc2szfQpqcG5faGQwNl9lYmwgPC0gRUJsb2NhbChqcG5fcHJlZl9oZDA2JEhEMDYsIGpwbl9wcmVmX2hkMDYkUE9QSjA2LzEwMCwgcHJlZi50cmkubmIpCnN1bW1hcnkoanBuX2hkMDZfZWJsKQpgYGAKCuODreODvOOCq+ODq+OBque1jOmok+ODmeOCpOOCuuaOqOWumue1kOaenOOBruS4u+mhjOWbs+OCkuS9nOaIkOOBmeOCi+OAggpgYGB7ciBqcG5fcmlzazdfbWFwfQpnZ3Bsb3QyOjpnZ3Bsb3QoZGF0YSA9IGpwbl9wcmVmX2hkMDYsIGFlcyhmaWxsPWpwbl9oZDA2X2VibCRlc3QpKSArIAogIGdlb21fc2YoKSArIAogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGU9IlJlZHMiLCB0cmFucyA9ICJyZXZlcnNlIikgKyAKICB0aGVtZV9idygpICsKICBsYWJzKHRpdGxlID0gIkxvY2FsIEVCIEVzdGltYXRlIG9mIERlYXRoIGJ5IEhlYXJ0IERpc2Vhc2UgUmlzayIpCmBgYAoKIyMjIyDjg63jg7zjgqvjg6vjgarntYzpqJPjg5njgqTjgrrmjqjlrprjgavjgojjgotNb3JhbidzIEnjga7nubDjgorov5TjgZfmpJzlrpoKYGBge3IganBuX0VCTF9Nb3Jhbi5tY30KRUJJbW9yYW4ubWMoanBuX3ByZWZfaGQwNiRIRDA2LCBqcG5fcHJlZl9oZDA2JFBPUEowNi8xMDAsIAogICAgICAgICAgICBuYjJsaXN0dyhwcmVmLnRyaS5uYiwgc3R5bGU9IlciLCB6ZXJvLnBvbGljeT1UUlVFKSwgCiAgICAgICAgICAgIG5zaW09OTk5LCB6ZXJvLnBvbGljeT1UUlVFKQpgYGAKCiMjIyMg6YCa5bi444GuTW9yYW4ncyBJ44Gu57mw44KK6L+U44GX5qSc5a6aCmBgYHtyIGpwbl9Nb3Jhbi5tY30Kc2V0LnNlZWQoMTIzNCkKbW9yYW4ubWMoanBuX3ByZWZfaGQwNiRQT1BKMDYvMTAwLCAKICAgICAgICAgICAgbGlzdHc9bmIybGlzdHcocHJlZi50cmkubmIsIHN0eWxlPSJXIiwgemVyby5wb2xpY3k9VFJVRSksIAogICAgICAgICAgICBuc2ltPTk5OSwgemVyby5wb2xpY3k9VFJVRSkKYGBgCgoK