第7章の内容

データの準備

まずは第6章までと同じデータを読み込む

###For chapter 07
phyto_metadata <- readRDS("phyto_metadata.obj")
species_ryuko_data <- readRDS("phyto_ryuko_data.obj")
metadata_ecoplate <- readRDS("metadata_ecopl.obj")
summary_ecoplate <- readRDS("summary_ecopl.obj")
species_richness <- apply(species_ryuko_data > 0, 1, sum) #種数の計算
total_abundance <- apply(species_ryuko_data, 1, sum) #総個体数の計算

7.1 重回帰分析

7.1.1 説明変数が二つ以上ある場合の可視化方法

復習として二つの説明変数それぞれに対する散布図を描いてみる

#種数と温度の関係
plot(species_richness ~ phyto_metadata$temp, cex = 2) 

#種数と総個体数の関係
plot(species_richness ~ total_abundance, cex = 2)

3次元散布図について描いてみる(scatterplot3dというパッケージのインストールを済ませましょう)

library(scatterplot3d)
scatterplot3d(
  x = phyto_metadata$temp, y = total_abundance, z = species_richness, #軸に使うベクトルの設定
  xlab = "temperature", ylab = "abundance", zlab = "richness", #軸ラベルの設定
  angle = 30 #角度の設定
)

マウスで操作が可能なインタラクティブな3次元散布図も描いてみましょう(rglというパッケージのインストールが必要ですが,うまくいかない時は諦めて飛ばしてよいです)

library(rgl)
plot3d(
  x = phyto_metadata$temp, y = total_abundance, z = species_richness,
  xlab = "temperature", ylab = "abundance", zlab = "richness", #軸ラベルの設定
  type = "s", #マークのタイプ
  size = 3,  #マークのサイズ
  col = c(2,9)[as.factor(phyto_metadata$year)] #年ごとに色指定を変える
)
rgl.snapshot("fig7.3b.tiff")

Rスクリプトを実行したときのグラフは新しいウィンドウに表示されます.そのイメージは以下の通り.

図7.3b
図7.3b

7.1.2 重回帰分析のイメージ

重回帰分析に行く前に「単」回帰分析をしてみる

#温度及び総個体数による単回帰分析
model_temp <- lm(species_richness ~ phyto_metadata$temp)
model_abundance <- lm(species_richness ~ total_abundance)
#温度による回帰直線の描写
plot(species_richness ~ phyto_metadata$temp, cex = 2)
abline(model_temp) #これが回帰分析の結果から回帰直線を描くコード

#総個体数による回帰直線の描写
plot(species_richness ~ total_abundance, cex = 2)
abline(model_abundance) #これが回帰分析の結果から回帰直線を描くコード

重回帰分析をイメージしてもらうために「回帰平面」を描いてみる

#3次元散布図のコード
plot3d(
  x = phyto_metadata$temp, y = total_abundance, z = species_richness,
  xlab = "temperature", ylab = "abundance", zlab = "richness",
  type = "s",
  size = 3,
  col = c(2,9)[as.factor(phyto_metadata$year)] #年ごとに色指定を変える
)
#重回帰分析のコード
fit_model <- lm(species_richness ~ phyto_metadata$temp + total_abundance)
#重回帰分析の結果を格納したオブジェクト(fit_model)から回帰係数を抽出する
plane_coeff <- coef(fit_model)
#回帰係数を使って「回帰平面」を上描きする
planes3d(plane_coeff[2], plane_coeff[3], -1, plane_coeff[1], col = "blue", alpha = 0.5)
#rgl.snapshot("fig7.5.tiff")

Rスクリプトを実行したときのグラフは新しいウィンドウに表示されます.そのイメージは以下の通り.

図7.5 3次元散布図と回帰平面
図7.5 3次元散布図と回帰平面

7.1.3 重回帰分析のコーディング

#lm関数を使って重回帰分析を実行する
multi_model <- lm(species_richness ~ phyto_metadata$temp + total_abundance)
#summary関数をつかって重回帰分析の結果を表示する
summary(multi_model)

Call:
lm(formula = species_richness ~ phyto_metadata$temp + total_abundance)

Residuals:
    Min      1Q  Median      3Q     Max 
-8.2519 -3.6671 -0.5555  1.4574 13.0203 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)
(Intercept)         8.733183   7.271159   1.201    0.253
phyto_metadata$temp 0.974593   0.548926   1.775    0.101
total_abundance     0.005174   0.011083   0.467    0.649

Residual standard error: 5.93 on 12 degrees of freedom
Multiple R-squared:  0.5009,    Adjusted R-squared:  0.4178 
F-statistic: 6.023 on 2 and 12 DF,  p-value: 0.01545

7.2 交互作用

7.2.1 交互作用ありの分散分析

交互作用を直感的に理解するためにまずは可視化してみる

参照元: https://momonoki2017.blogspot.com/2018/08/r019.html

data("ToothGrowth") #Rに標準で付属するサンプルデータを読み込み
sub_TG <- subset(ToothGrowth, dose > 0.5) #摂取量が0.5より大きいデータだけをsubset関数で抜き出す

#摂取量x摂取タイプで箱ひげ図を描写する
boxplot(
  len ~ dose + supp, data = sub_TG, #公式
  outline = F, #外れ値の扱い
  col = c("white", "white", "gray", "gray") #列ごとの色の指定
)
#生データを箱ひげ図に重ね合わせる
stripchart(
  len ~ dose + supp, data = sub_TG, #公式
  method = "stack",
  pch = c(1,1,2,2), #記号の指定:1と2列目(1.OJと2.OJ)に1を指定,3と4列目(1.VCと2.VC)に2を指定
  cex = 3, #マークの大きさを指定
  vertical = TRUE,
  add = TRUE
)

交互作用に特化した可視化方法もある

interaction.plot(
  x.factor = sub_TG$dose, #主要因の指定
  response = sub_TG$len,   #応答変数(y軸)の指定
  trace.factor = sub_TG$supp, #副要因の指定
  xlab = "dose level", ylab = "growth" #軸ラベルの指定
)

「二要因の分散分析と交互作用」についてやってみる

まずは、交互作用ナシの二要因分散分析(「応答変数 ~ 説明変数1 + 説明変数2」の形で公式を書く)

model_tooth01 <- lm(len ~ dose + supp, data = sub_TG)
anova(model_tooth01) #分散分析の結果の表示にはanova関数を使う
Analysis of Variance Table

Response: len
          Df Sum Sq Mean Sq F value   Pr(>F)    
dose       1 405.13  405.13 26.9841 7.72e-06 ***
supp       1  85.56   85.56  5.6985   0.0222 *  
Residuals 37 555.51   15.01                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

次に、交互作用アリの二要因分散分析を、「応答変数 ~ 説明変数1 + 説明変数2 + 説明変数1: 説明変数2」の形で公式を書いて実現する

model_tooth02 <- lm(len ~ dose + supp + dose:supp, data = sub_TG)
anova(model_tooth02)
Analysis of Variance Table

Response: len
          Df Sum Sq Mean Sq F value    Pr(>F)    
dose       1 405.13  405.13 31.3510 2.387e-06 ***
supp       1  85.56   85.56  6.6207   0.01435 *  
dose:supp  1  90.30   90.30  6.9878   0.01208 *  
Residuals 36 465.21   12.92                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

7.3 一般線形モデルとモデル選択

7.3.3 一般線形モデルとしてのRのlm関数の使いかた

分散分析タイプのデータを一般線形モデルで扱う

(復習)anova関数を使うと分散分析の表として結果が出力される

anova(lm(species_richness ~ as.factor(phyto_metadata$month)))
Analysis of Variance Table

Response: species_richness
                                Df Sum Sq Mean Sq F value  Pr(>F)  
as.factor(phyto_metadata$month)  3 418.83 139.611  3.5985 0.04961 *
Residuals                       11 426.77  38.797                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

一般線形モデル(General Linear Model)の形式で出力するには、summary関数を使えばよい

####General Linear Model01####
summary(lm(species_richness ~ phyto_metadata$month))

Call:
lm(formula = species_richness ~ phyto_metadata$month)

Residuals:
    Min      1Q  Median      3Q     Max 
-10.200  -2.167  -0.800   1.650  11.200 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)   
(Intercept)               16.500      4.404   3.746  0.00323 **
phyto_metadata$monthM04    9.300      5.211   1.785  0.10190   
phyto_metadata$monthM05   11.167      5.686   1.964  0.07531 . 
phyto_metadata$monthM10   16.700      5.211   3.205  0.00839 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.229 on 11 degrees of freedom
Multiple R-squared:  0.4953,    Adjusted R-squared:  0.3577 
F-statistic: 3.599 on 3 and 11 DF,  p-value: 0.04961
カテゴリー変数と量的変数が混じったデータを一般線形モデルで扱う

ToothGrowthデータをすべて使って、一般線形モデルで解析してみよう.

####General Linear Model02####
data("ToothGrowth") #データの読み込み

まずは、変数のタイプ(クラス)を確認する

class(ToothGrowth$supp)
[1] "factor"
class(ToothGrowth$dose)
[1] "numeric"

interaction.plot関数を使って交互作用を可視化してみよう

interaction.plot(
  x.factor = ToothGrowth$dose, #主要因を摂取量にする
  response = ToothGrowth$len,  #応答変数は成長量
  trace.factor = ToothGrowth$supp, #副要因は摂取タイプ
  xlab = "dose level", ylab = "growth" #軸ラベルの指定
)

では、実際に一般線形モデルとして解析・結果の出力をしてみましょう

model_tooth03 <- lm(len ~ dose + supp + dose:supp, data = ToothGrowth) #解析の結果は一旦、オブジェクトmodel_tooth03に格納する
summary(model_tooth03) #結果の出力

Call:
lm(formula = len ~ dose + supp + dose:supp, data = ToothGrowth)

Residuals:
    Min      1Q  Median      3Q     Max 
-8.2264 -2.8462  0.0504  2.2893  7.9386 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   11.550      1.581   7.304 1.09e-09 ***
dose           7.811      1.195   6.534 2.03e-08 ***
suppVC        -8.255      2.236  -3.691 0.000507 ***
dose:suppVC    3.904      1.691   2.309 0.024631 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 4.083 on 56 degrees of freedom
Multiple R-squared:  0.7296,    Adjusted R-squared:  0.7151 
F-statistic: 50.36 on 3 and 56 DF,  p-value: 6.521e-16
二群比較用のデータを一般線形モデルで扱う
####General Linear Model03####
summary(lm(species_richness ~ as.factor(phyto_metadata$year))) #一般線形モデルの出力を直接summary関数の入力にしている

Call:
lm(formula = species_richness ~ as.factor(phyto_metadata$year))

Residuals:
    Min      1Q  Median      3Q     Max 
-12.429  -4.964  -0.500   4.536  14.571 

Coefficients:
                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                          28.429      3.023   9.403 3.66e-07 ***
as.factor(phyto_metadata$year)2019   -1.929      4.140  -0.466    0.649    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.999 on 13 degrees of freedom
Multiple R-squared:  0.01642,   Adjusted R-squared:  -0.05924 
F-statistic: 0.217 on 1 and 13 DF,  p-value: 0.649

7.3.4 モデル選択

ますは可視化してみる

年の間の種数の違い、温度による種数の違い、総個体数による種数の違いをそれぞれ可視化する

#2018 vs 2019
#箱ひげ図
boxplot(
  species_richness ~ phyto_metadata$year, #モデル式
  outline = F, #外れ値の扱い
  col = c("white", "gray") #色の指定
)
#散布図
stripchart(
  species_richness ~ phyto_metadata$year, #モデル式
  method = "stack", #同一値の描画設定
  pch = c(1,2), #描画マークの種類指定
  cex = 3,   #描画マークの大きさ指定
  vertical = TRUE, #横向きか縦向きかの指定
  add = TRUE #箱ひげ図に重ね合わせるかどうかの指定
)

#回帰直線を描くための準備としての単回帰分析
model_temp <- lm(species_richness ~ phyto_metadata$temp)
model_abundance <- lm(species_richness ~ total_abundance)
#単回帰分析の結果を使って、散布図と回帰直線を重ね合わせる
plot(species_richness ~ phyto_metadata$temp, cex = 2) #散布図
abline(model_temp) #回帰直線

#単回帰分析の結果を使って、散布図と回帰直線を重ね合わせる
plot(species_richness ~ total_abundance, cex = 2) #散布図
abline(model_abundance) #回帰直線

step関数を使ったモデル選択

#ステップ関数でのモデル選択の結果をオブジェクトselected_modelに格納(選択している途上の結果もコンソール上に出力される)
selected_model <- step(lm(species_richness ~ phyto_metadata$temp + total_abundance + phyto_metadata$year))
Start:  AIC=52.99
species_richness ~ phyto_metadata$temp + total_abundance + phyto_metadata$year

                      Df Sum of Sq    RSS    AIC
- total_abundance      1    28.372 329.45 52.340
<none>                             301.08 52.990
- phyto_metadata$year  1   120.932 422.01 56.055
- phyto_metadata$temp  1   168.925 470.00 57.670

Step:  AIC=52.34
species_richness ~ phyto_metadata$temp + phyto_metadata$year

                      Df Sum of Sq    RSS    AIC
<none>                             329.45 52.340
- phyto_metadata$year  1    100.22 429.67 54.325
- phyto_metadata$temp  1    502.27 831.71 64.232

選択されたベストモデルのまとめを出力する

→温度と年が入ったモデルがベストであることがわかる

summary(selected_model)

Call:
lm(formula = species_richness ~ phyto_metadata$temp + phyto_metadata$year)

Residuals:
    Min      1Q  Median      3Q     Max 
-6.2495 -3.4168 -0.1866  1.8900 11.7505 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)   
(Intercept)         -1.286e+04  6.735e+03  -1.910  0.08037 . 
phyto_metadata$temp  1.588e+00  3.712e-01   4.277  0.00107 **
phyto_metadata$year  6.371e+00  3.334e+00   1.911  0.08023 . 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.24 on 12 degrees of freedom
Multiple R-squared:  0.6104,    Adjusted R-squared:  0.5455 
F-statistic:   9.4 on 2 and 12 DF,  p-value: 0.003497
LS0tDQp0aXRsZTogImFkdmFuY2VkX3VuaXZhcmlhdGUuUuOBq+WvvuW/nOOBl+OBn1IgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyDnrKw356ug44Gu5YaF5a65DQoNCiMjIyDjg4fjg7zjgr/jga7mupblgpkNCuOBvuOBmuOBr+esrDbnq6Djgb7jgafjgajlkIzjgZjjg4fjg7zjgr/jgpLoqq3jgb/ovrzjgoANCmBgYHtyfQ0KIyMjRm9yIGNoYXB0ZXIgMDcNCnBoeXRvX21ldGFkYXRhIDwtIHJlYWRSRFMoInBoeXRvX21ldGFkYXRhLm9iaiIpDQpzcGVjaWVzX3J5dWtvX2RhdGEgPC0gcmVhZFJEUygicGh5dG9fcnl1a29fZGF0YS5vYmoiKQ0KbWV0YWRhdGFfZWNvcGxhdGUgPC0gcmVhZFJEUygibWV0YWRhdGFfZWNvcGwub2JqIikNCnN1bW1hcnlfZWNvcGxhdGUgPC0gcmVhZFJEUygic3VtbWFyeV9lY29wbC5vYmoiKQ0Kc3BlY2llc19yaWNobmVzcyA8LSBhcHBseShzcGVjaWVzX3J5dWtvX2RhdGEgPiAwLCAxLCBzdW0pICPnqK7mlbDjga7oqIjnrpcNCnRvdGFsX2FidW5kYW5jZSA8LSBhcHBseShzcGVjaWVzX3J5dWtvX2RhdGEsIDEsIHN1bSkgI+e3j+WAi+S9k+aVsOOBruioiOeulw0KYGBgDQoNCiMjIyA3LjEg6YeN5Zue5biw5YiG5p6QDQojIyMjIDcuMS4xIOiqrOaYjuWkieaVsOOBjOS6jOOBpOS7peS4iuOBguOCi+WgtOWQiOOBruWPr+imluWMluaWueazlQ0K5b6p57+S44Go44GX44Gm5LqM44Gk44Gu6Kqs5piO5aSJ5pWw44Gd44KM44Ge44KM44Gr5a++44GZ44KL5pWj5biD5Zuz44KS5o+P44GE44Gm44G/44KLDQpgYGB7cn0NCiPnqK7mlbDjgajmuKnluqbjga7plqLkv4INCnBsb3Qoc3BlY2llc19yaWNobmVzcyB+IHBoeXRvX21ldGFkYXRhJHRlbXAsIGNleCA9IDIpIA0KI+eoruaVsOOBqOe3j+WAi+S9k+aVsOOBrumWouS/gg0KcGxvdChzcGVjaWVzX3JpY2huZXNzIH4gdG90YWxfYWJ1bmRhbmNlLCBjZXggPSAyKQ0KDQpgYGANCjPmrKHlhYPmlaPluIPlm7PjgavjgaTjgYTjgabmj4/jgYTjgabjgb/jgosoc2NhdHRlcnBsb3QzZOOBqOOBhOOBhuODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODq+OCkua4iOOBvuOBm+OBvuOBl+OCh+OBhikNCmBgYHtyfQ0KbGlicmFyeShzY2F0dGVycGxvdDNkKQ0Kc2NhdHRlcnBsb3QzZCgNCiAgeCA9IHBoeXRvX21ldGFkYXRhJHRlbXAsIHkgPSB0b3RhbF9hYnVuZGFuY2UsIHogPSBzcGVjaWVzX3JpY2huZXNzLOOAgCPou7jjgavkvb/jgYbjg5njgq/jg4jjg6vjga7oqK3lrpoNCiAgeGxhYiA9ICJ0ZW1wZXJhdHVyZSIsIHlsYWIgPSAiYWJ1bmRhbmNlIiwgemxhYiA9ICJyaWNobmVzcyIs44CAI+i7uOODqeODmeODq+OBruioreWumg0KICBhbmdsZSA9IDMw44CAI+inkuW6puOBruioreWumg0KKQ0KYGBgDQrjg57jgqbjgrnjgafmk43kvZzjgYzlj6/og73jgarjgqTjg7Pjgr/jg6njgq/jg4bjgqPjg5bjgaoz5qyh5YWD5pWj5biD5Zuz44KC5o+P44GE44Gm44G/44G+44GX44KH44GGKHJnbOOBqOOBhOOBhuODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODq+OBjOW/heimgeOBp+OBmeOBjO+8jOOBhuOBvuOBj+OBhOOBi+OBquOBhOaZguOBr+irpuOCgeOBpumjm+OBsOOBl+OBpuOCiOOBhOOBp+OBmSkNCg0KYGBge3J9DQpsaWJyYXJ5KHJnbCkNCnBsb3QzZCgNCiAgeCA9IHBoeXRvX21ldGFkYXRhJHRlbXAsIHkgPSB0b3RhbF9hYnVuZGFuY2UsIHogPSBzcGVjaWVzX3JpY2huZXNzLA0KICB4bGFiID0gInRlbXBlcmF0dXJlIiwgeWxhYiA9ICJhYnVuZGFuY2UiLCB6bGFiID0gInJpY2huZXNzIizjgIAj6Lu444Op44OZ44Or44Gu6Kit5a6aDQogIHR5cGUgPSAicyIs44CAI+ODnuODvOOCr+OBruOCv+OCpOODlw0KICBzaXplID0gMyzjgIDjgIAj44Oe44O844Kv44Gu44K144Kk44K6DQogIGNvbCA9IGMoMiw5KVthcy5mYWN0b3IocGh5dG9fbWV0YWRhdGEkeWVhcild44CAI+W5tOOBlOOBqOOBq+iJsuaMh+WumuOCkuWkieOBiOOCiw0KKQ0KcmdsLnNuYXBzaG90KCJmaWc3LjNiLnRpZmYiKQ0KYGBgDQpS44K544Kv44Oq44OX44OI44KS5a6f6KGM44GX44Gf44Go44GN44Gu44Kw44Op44OV44Gv5paw44GX44GE44Km44Kj44Oz44OJ44Km44Gr6KGo56S644GV44KM44G+44GZ77yO44Gd44Gu44Kk44Oh44O844K444Gv5Lul5LiL44Gu6YCa44KK77yODQoNCiFb5ZuzNy4zYl0oZmlnNy4zYi50aWZmKQ0KDQoNCg0KIyMjIyA3LjEuMiDph43lm57luLDliIbmnpDjga7jgqTjg6Hjg7zjgrgNCumHjeWbnuW4sOWIhuaekOOBq+ihjOOBj+WJjeOBq+OAjOWNmOOAjeWbnuW4sOWIhuaekOOCkuOBl+OBpuOBv+OCiw0KYGBge3J9DQoj5rip5bqm5Y+K44Gz57eP5YCL5L2T5pWw44Gr44KI44KL5Y2Y5Zue5biw5YiG5p6QDQptb2RlbF90ZW1wIDwtIGxtKHNwZWNpZXNfcmljaG5lc3MgfiBwaHl0b19tZXRhZGF0YSR0ZW1wKQ0KbW9kZWxfYWJ1bmRhbmNlIDwtIGxtKHNwZWNpZXNfcmljaG5lc3MgfiB0b3RhbF9hYnVuZGFuY2UpDQoj5rip5bqm44Gr44KI44KL5Zue5biw55u057ea44Gu5o+P5YaZDQpwbG90KHNwZWNpZXNfcmljaG5lc3MgfiBwaHl0b19tZXRhZGF0YSR0ZW1wLCBjZXggPSAyKQ0KYWJsaW5lKG1vZGVsX3RlbXApICPjgZPjgozjgYzlm57luLDliIbmnpDjga7ntZDmnpzjgYvjgonlm57luLDnm7Tnt5rjgpLmj4/jgY/jgrPjg7zjg4kNCiPnt4/lgIvkvZPmlbDjgavjgojjgovlm57luLDnm7Tnt5rjga7mj4/lhpkNCnBsb3Qoc3BlY2llc19yaWNobmVzcyB+IHRvdGFsX2FidW5kYW5jZSwgY2V4ID0gMikNCmFibGluZShtb2RlbF9hYnVuZGFuY2UpICPjgZPjgozjgYzlm57luLDliIbmnpDjga7ntZDmnpzjgYvjgonlm57luLDnm7Tnt5rjgpLmj4/jgY/jgrPjg7zjg4kNCg0KYGBgDQrph43lm57luLDliIbmnpDjgpLjgqTjg6Hjg7zjgrjjgZfjgabjgoLjgonjgYbjgZ/jgoHjgavjgIzlm57luLDlubPpnaLjgI3jgpLmj4/jgYTjgabjgb/jgosNCmBgYHtyfQ0KIzPmrKHlhYPmlaPluIPlm7Pjga7jgrPjg7zjg4kNCnBsb3QzZCgNCiAgeCA9IHBoeXRvX21ldGFkYXRhJHRlbXAsIHkgPSB0b3RhbF9hYnVuZGFuY2UsIHogPSBzcGVjaWVzX3JpY2huZXNzLA0KICB4bGFiID0gInRlbXBlcmF0dXJlIiwgeWxhYiA9ICJhYnVuZGFuY2UiLCB6bGFiID0gInJpY2huZXNzIiwNCiAgdHlwZSA9ICJzIiwNCiAgc2l6ZSA9IDMsDQogIGNvbCA9IGMoMiw5KVthcy5mYWN0b3IocGh5dG9fbWV0YWRhdGEkeWVhcildICPlubTjgZTjgajjgavoibLmjIflrprjgpLlpInjgYjjgosNCikNCiPph43lm57luLDliIbmnpDjga7jgrPjg7zjg4kNCmZpdF9tb2RlbCA8LSBsbShzcGVjaWVzX3JpY2huZXNzIH4gcGh5dG9fbWV0YWRhdGEkdGVtcCArIHRvdGFsX2FidW5kYW5jZSkNCiPph43lm57luLDliIbmnpDjga7ntZDmnpzjgpLmoLzntI3jgZfjgZ/jgqrjg5bjgrjjgqfjgq/jg4goZml0X21vZGVsKeOBi+OCieWbnuW4sOS/guaVsOOCkuaKveWHuuOBmeOCiw0KcGxhbmVfY29lZmYgPC0gY29lZihmaXRfbW9kZWwpDQoj5Zue5biw5L+C5pWw44KS5L2/44Gj44Gm44CM5Zue5biw5bmz6Z2i44CN44KS5LiK5o+P44GN44GZ44KLDQpwbGFuZXMzZChwbGFuZV9jb2VmZlsyXSwgcGxhbmVfY29lZmZbM10sIC0xLCBwbGFuZV9jb2VmZlsxXSwgY29sID0gImJsdWUiLCBhbHBoYSA9IDAuNSkNCiNyZ2wuc25hcHNob3QoImZpZzcuNS50aWZmIikNCmBgYA0KUuOCueOCr+ODquODl+ODiOOCkuWun+ihjOOBl+OBn+OBqOOBjeOBruOCsOODqeODleOBr+aWsOOBl+OBhOOCpuOCo+ODs+ODieOCpuOBq+ihqOekuuOBleOCjOOBvuOBme+8juOBneOBruOCpOODoeODvOOCuOOBr+S7peS4i+OBrumAmuOCiu+8jg0KDQohW+WbszcuNSAz5qyh5YWD5pWj5biD5Zuz44Go5Zue5biw5bmz6Z2iXShmaWc3LjUudGlmZikNCg0KIyMjIyA3LjEuMyDph43lm57luLDliIbmnpDjga7jgrPjg7zjg4fjgqPjg7PjgrANCmBgYHtyfQ0KI2xt6Zai5pWw44KS5L2/44Gj44Gm6YeN5Zue5biw5YiG5p6Q44KS5a6f6KGM44GZ44KLDQptdWx0aV9tb2RlbCA8LSBsbShzcGVjaWVzX3JpY2huZXNzIH4gcGh5dG9fbWV0YWRhdGEkdGVtcCArIHRvdGFsX2FidW5kYW5jZSkNCiNzdW1tYXJ56Zai5pWw44KS44Gk44GL44Gj44Gm6YeN5Zue5biw5YiG5p6Q44Gu57WQ5p6c44KS6KGo56S644GZ44KLDQpzdW1tYXJ5KG11bHRpX21vZGVsKQ0KYGBgDQojIyMgNy4yIOS6pOS6kuS9nOeUqA0KIyMjIyA3LjIuMSDkuqTkupLkvZznlKjjgYLjgorjga7liIbmlaPliIbmnpANCuS6pOS6kuS9nOeUqOOCkuebtOaEn+eahOOBq+eQhuino+OBmeOCi+OBn+OCgeOBq+OBvuOBmuOBr+WPr+imluWMluOBl+OBpuOBv+OCiw0KDQrlj4LnhaflhYM6IGh0dHBzOi8vbW9tb25va2kyMDE3LmJsb2dzcG90LmNvbS8yMDE4LzA4L3IwMTkuaHRtbA0KDQpgYGB7cn0NCmRhdGEoIlRvb3RoR3Jvd3RoIikgI1LjgavmqJnmupbjgafku5jlsZ7jgZnjgovjgrXjg7Pjg5fjg6vjg4fjg7zjgr/jgpLoqq3jgb/ovrzjgb8NCnN1Yl9URyA8LSBzdWJzZXQoVG9vdGhHcm93dGgsIGRvc2UgPiAwLjUp44CAI+aRguWPlumHj+OBjDAuNeOCiOOCiuWkp+OBjeOBhOODh+ODvOOCv+OBoOOBkeOCknN1YnNldOmWouaVsOOBp+aKnOOBjeWHuuOBmQ0KDQoj5pGC5Y+W6YeP772Y5pGC5Y+W44K/44Kk44OX44Gn566x44Gy44GS5Zuz44KS5o+P5YaZ44GZ44KLDQpib3hwbG90KA0KICBsZW4gfiBkb3NlICsgc3VwcCwgZGF0YSA9IHN1Yl9URywgI+WFrOW8jw0KICBvdXRsaW5lID0gRizjgIAj5aSW44KM5YCk44Gu5omx44GEDQogIGNvbCA9IGMoIndoaXRlIiwgIndoaXRlIiwgImdyYXkiLCAiZ3JheSIp44CAI+WIl+OBlOOBqOOBruiJsuOBruaMh+Wumg0KKQ0KI+eUn+ODh+ODvOOCv+OCkueuseOBsuOBkuWbs+OBq+mHjeOBreWQiOOCj+OBm+OCiw0Kc3RyaXBjaGFydCgNCiAgbGVuIH4gZG9zZSArIHN1cHAsIGRhdGEgPSBzdWJfVEcsICPlhazlvI8NCiAgbWV0aG9kID0gInN0YWNrIiwNCiAgcGNoID0gYygxLDEsMiwyKSzjgIAj6KiY5Y+344Gu5oyH5a6aOu+8keOBqO+8kuWIl+ebrigxLk9K44GoMi5PSinjgasx44KS5oyH5a6a77yM77yT44Go77yU5YiX55uuKDEuVkPjgagyLlZDKeOBqzLjgpLmjIflrpoNCiAgY2V4ID0gMywgI+ODnuODvOOCr+OBruWkp+OBjeOBleOCkuaMh+Wumg0KICB2ZXJ0aWNhbCA9IFRSVUUsDQogIGFkZCA9IFRSVUUNCikNCmBgYA0K5Lqk5LqS5L2c55So44Gr54m55YyW44GX44Gf5Y+v6KaW5YyW5pa55rOV44KC44GC44KLDQpgYGB7cn0NCmludGVyYWN0aW9uLnBsb3QoDQogIHguZmFjdG9yID0gc3ViX1RHJGRvc2Us44CAI+S4u+imgeWboOOBruaMh+Wumg0KICByZXNwb25zZSA9IHN1Yl9URyRsZW4sICAgI+W/nOetlOWkieaVsCjvvZnou7gp44Gu5oyH5a6aDQogIHRyYWNlLmZhY3RvciA9IHN1Yl9URyRzdXBwLOOAgCPlia/opoHlm6Djga7mjIflrpoNCiAgeGxhYiA9ICJkb3NlIGxldmVsIiwgeWxhYiA9ICJncm93dGgi44CAI+i7uOODqeODmeODq+OBruaMh+Wumg0KKQ0KYGBgDQrjgIzkuozopoHlm6Djga7liIbmlaPliIbmnpDjgajkuqTkupLkvZznlKjjgI3jgavjgaTjgYTjgabjgoTjgaPjgabjgb/jgosNCg0K44G+44Ga44Gv44CB5Lqk5LqS5L2c55So44OK44K344Gu5LqM6KaB5Zug5YiG5pWj5YiG5p6QKOOAjOW/nOetlOWkieaVsCB+IOiqrOaYjuWkieaVsDEgKyDoqqzmmI7lpInmlbDvvJLjgI3jga7lvaLjgaflhazlvI/jgpLmm7jjgY8pDQpgYGB7cn0NCm1vZGVsX3Rvb3RoMDEgPC0gbG0obGVuIH4gZG9zZSArIHN1cHAsIGRhdGEgPSBzdWJfVEcpDQphbm92YShtb2RlbF90b290aDAxKSAj5YiG5pWj5YiG5p6Q44Gu57WQ5p6c44Gu6KGo56S644Gr44GvYW5vdmHplqLmlbDjgpLkvb/jgYYNCmBgYA0KDQrmrKHjgavjgIHkuqTkupLkvZznlKjjgqLjg6rjga7kuozopoHlm6DliIbmlaPliIbmnpDjgpLjgIHjgIzlv5znrZTlpInmlbAgfiDoqqzmmI7lpInmlbAxICsg6Kqs5piO5aSJ5pWw77ySICsg6Kqs5piO5aSJ5pWw77yROiDoqqzmmI7lpInmlbDvvJLjgI3jga7lvaLjgaflhazlvI/jgpLmm7jjgYTjgablrp/nj77jgZnjgosNCmBgYHtyfQ0KbW9kZWxfdG9vdGgwMiA8LSBsbShsZW4gfiBkb3NlICsgc3VwcCArIGRvc2U6c3VwcCwgZGF0YSA9IHN1Yl9URykNCmFub3ZhKG1vZGVsX3Rvb3RoMDIpDQpgYGANCiMjIyA3LjMg5LiA6Iis57ea5b2i44Oi44OH44Or44Go44Oi44OH44Or6YG45oqeDQojIyMjIDcuMy4zIOS4gOiIrOe3muW9ouODouODh+ODq+OBqOOBl+OBpuOBrlLjga5sbemWouaVsOOBruS9v+OBhOOBi+OBnw0KIyMjIyMg5YiG5pWj5YiG5p6Q44K/44Kk44OX44Gu44OH44O844K/44KS5LiA6Iis57ea5b2i44Oi44OH44Or44Gn5omx44GGDQoo5b6p57+SKWFub3Zh6Zai5pWw44KS5L2/44GG44Go5YiG5pWj5YiG5p6Q44Gu6KGo44Go44GX44Gm57WQ5p6c44GM5Ye65Yqb44GV44KM44KLDQpgYGB7cn0NCmFub3ZhKGxtKHNwZWNpZXNfcmljaG5lc3MgfiBhcy5mYWN0b3IocGh5dG9fbWV0YWRhdGEkbW9udGgpKSkNCmBgYA0K5LiA6Iis57ea5b2i44Oi44OH44OrKEdlbmVyYWwgTGluZWFy44CATW9kZWwp44Gu5b2i5byP44Gn5Ye65Yqb44GZ44KL44Gr44Gv44CBc3VtbWFyeemWouaVsOOCkuS9v+OBiOOBsOOCiOOBhA0KYGBge3J9DQojIyMjR2VuZXJhbCBMaW5lYXIgTW9kZWwwMSMjIyMNCnN1bW1hcnkobG0oc3BlY2llc19yaWNobmVzcyB+IHBoeXRvX21ldGFkYXRhJG1vbnRoKSkNCmBgYA0KIyMjIyMg44Kr44OG44K044Oq44O85aSJ5pWw44Go6YeP55qE5aSJ5pWw44GM5re344GY44Gj44Gf44OH44O844K/44KS5LiA6Iis57ea5b2i44Oi44OH44Or44Gn5omx44GGDQpUb290aEdyb3d0aOODh+ODvOOCv+OCkuOBmeOBueOBpuS9v+OBo+OBpuOAgeS4gOiIrOe3muW9ouODouODh+ODq+OBp+ino+aekOOBl+OBpuOBv+OCiOOBhu+8jg0KYGBge3J9DQojIyMjR2VuZXJhbCBMaW5lYXIgTW9kZWwwMiMjIyMNCmRhdGEoIlRvb3RoR3Jvd3RoIinjgIAj44OH44O844K/44Gu6Kqt44G/6L6844G/DQpgYGANCuOBvuOBmuOBr+OAgeWkieaVsOOBruOCv+OCpOODlyjjgq/jg6njgrkp44KS56K66KqN44GZ44KLDQpgYGB7cn0NCmNsYXNzKFRvb3RoR3Jvd3RoJHN1cHApDQpjbGFzcyhUb290aEdyb3d0aCRkb3NlKQ0KYGBgDQppbnRlcmFjdGlvbi5wbG906Zai5pWw44KS5L2/44Gj44Gm5Lqk5LqS5L2c55So44KS5Y+v6KaW5YyW44GX44Gm44G/44KI44GGDQpgYGB7cn0NCmludGVyYWN0aW9uLnBsb3QoDQogIHguZmFjdG9yID0gVG9vdGhHcm93dGgkZG9zZSzjgIAj5Li76KaB5Zug44KS5pGC5Y+W6YeP44Gr44GZ44KLDQogIHJlc3BvbnNlID0gVG9vdGhHcm93dGgkbGVuLOOAgCAj5b+c562U5aSJ5pWw44Gv5oiQ6ZW36YePDQogIHRyYWNlLmZhY3RvciA9IFRvb3RoR3Jvd3RoJHN1cHAs44CAI+WJr+imgeWboOOBr+aRguWPluOCv+OCpOODlw0KICB4bGFiID0gImRvc2UgbGV2ZWwiLCB5bGFiID0gImdyb3d0aCLjgIAj6Lu444Op44OZ44Or44Gu5oyH5a6aDQopDQpgYGANCuOBp+OBr+OAgeWun+mam+OBq+S4gOiIrOe3muW9ouODouODh+ODq+OBqOOBl+OBpuino+aekOODu+e1kOaenOOBruWHuuWKm+OCkuOBl+OBpuOBv+OBvuOBl+OCh+OBhg0KYGBge3J9DQptb2RlbF90b290aDAzIDwtIGxtKGxlbiB+IGRvc2UgKyBzdXBwICsgZG9zZTpzdXBwLCBkYXRhID0gVG9vdGhHcm93dGgpICPop6PmnpDjga7ntZDmnpzjga/kuIDml6bjgIHjgqrjg5bjgrjjgqfjgq/jg4htb2RlbF90b290aDAz44Gr5qC857SN44GZ44KLDQpzdW1tYXJ5KG1vZGVsX3Rvb3RoMDMpICPntZDmnpzjga7lh7rlipsNCmBgYA0KIyMjIyMg5LqM576k5q+U6LyD55So44Gu44OH44O844K/44KS5LiA6Iis57ea5b2i44Oi44OH44Or44Gn5omx44GGDQpgYGB7cn0NCiMjIyNHZW5lcmFsIExpbmVhciBNb2RlbDAzIyMjIw0Kc3VtbWFyeShsbShzcGVjaWVzX3JpY2huZXNzIH4gYXMuZmFjdG9yKHBoeXRvX21ldGFkYXRhJHllYXIpKSkgI+S4gOiIrOe3muW9ouODouODh+ODq+OBruWHuuWKm+OCkuebtOaOpXN1bW1hcnnplqLmlbDjga7lhaXlipvjgavjgZfjgabjgYTjgosNCmBgYA0KIyMjIyA3LjMuNCDjg6Ljg4fjg6vpgbjmip4NCuOBvuOBmeOBr+WPr+imluWMluOBl+OBpuOBv+OCiw0KDQrlubTjga7plpPjga7nqK7mlbDjga7pgZXjgYTjgIHmuKnluqbjgavjgojjgovnqK7mlbDjga7pgZXjgYTjgIHnt4/lgIvkvZPmlbDjgavjgojjgovnqK7mlbDjga7pgZXjgYTjgpLjgZ3jgozjgZ7jgozlj6/oppbljJbjgZnjgosNCmBgYHtyfQ0KIzIwMTggdnMgMjAxOQ0KI+euseOBsuOBkuWbsw0KYm94cGxvdCgNCiAgc3BlY2llc19yaWNobmVzcyB+IHBoeXRvX21ldGFkYXRhJHllYXIsICPjg6Ljg4fjg6vlvI8NCiAgb3V0bGluZSA9IEYs44CAI+WkluOCjOWApOOBruaJseOBhA0KICBjb2wgPSBjKCJ3aGl0ZSIsICJncmF5IinjgIAj6Imy44Gu5oyH5a6aDQopDQoj5pWj5biD5ZuzDQpzdHJpcGNoYXJ0KA0KICBzcGVjaWVzX3JpY2huZXNzIH4gcGh5dG9fbWV0YWRhdGEkeWVhcizjgIAj44Oi44OH44Or5byPDQogIG1ldGhvZCA9ICJzdGFjayIs44CAI+WQjOS4gOWApOOBruaPj+eUu+ioreWumg0KICBwY2ggPSBjKDEsMiks44CAI+aPj+eUu+ODnuODvOOCr+OBrueorumhnuaMh+Wumg0KICBjZXggPSAzLOOAgOOAgOOAgCPmj4/nlLvjg57jg7zjgq/jga7lpKfjgY3jgZXmjIflrpoNCiAgdmVydGljYWwgPSBUUlVFLOOAgCPmqKrlkJHjgY3jgYvnuKblkJHjgY3jgYvjga7mjIflrpoNCiAgYWRkID0gVFJVReOAgCPnrrHjgbLjgZLlm7Pjgavph43jga3lkIjjgo/jgZvjgovjgYvjganjgYbjgYvjga7mjIflrpoNCikNCiPlm57luLDnm7Tnt5rjgpLmj4/jgY/jgZ/jgoHjga7mupblgpnjgajjgZfjgabjga7ljZjlm57luLDliIbmnpANCm1vZGVsX3RlbXAgPC0gbG0oc3BlY2llc19yaWNobmVzcyB+IHBoeXRvX21ldGFkYXRhJHRlbXApDQptb2RlbF9hYnVuZGFuY2UgPC0gbG0oc3BlY2llc19yaWNobmVzcyB+IHRvdGFsX2FidW5kYW5jZSkNCiPljZjlm57luLDliIbmnpDjga7ntZDmnpzjgpLkvb/jgaPjgabjgIHmlaPluIPlm7Pjgajlm57luLDnm7Tnt5rjgpLph43jga3lkIjjgo/jgZvjgosNCnBsb3Qoc3BlY2llc19yaWNobmVzcyB+IHBoeXRvX21ldGFkYXRhJHRlbXAsIGNleCA9IDIpICPmlaPluIPlm7MNCmFibGluZShtb2RlbF90ZW1wKSAj5Zue5biw55u057eaDQoj5Y2Y5Zue5biw5YiG5p6Q44Gu57WQ5p6c44KS5L2/44Gj44Gm44CB5pWj5biD5Zuz44Go5Zue5biw55u057ea44KS6YeN44Gt5ZCI44KP44Gb44KLDQpwbG90KHNwZWNpZXNfcmljaG5lc3MgfiB0b3RhbF9hYnVuZGFuY2UsIGNleCA9IDIpICPmlaPluIPlm7MNCmFibGluZShtb2RlbF9hYnVuZGFuY2UpICPlm57luLDnm7Tnt5oNCmBgYA0Kc3RlcOmWouaVsOOCkuS9v+OBo+OBn+ODouODh+ODq+mBuOaKng0KYGBge3J9DQoj44K544OG44OD44OX6Zai5pWw44Gn44Gu44Oi44OH44Or6YG45oqe44Gu57WQ5p6c44KS44Kq44OW44K444Kn44Kv44OIc2VsZWN0ZWRfbW9kZWzjgavmoLzntI0o6YG45oqe44GX44Gm44GE44KL6YCU5LiK44Gu57WQ5p6c44KC44Kz44Oz44K944O844Or5LiK44Gr5Ye65Yqb44GV44KM44KLKQ0Kc2VsZWN0ZWRfbW9kZWwgPC0gc3RlcChsbShzcGVjaWVzX3JpY2huZXNzIH4gcGh5dG9fbWV0YWRhdGEkdGVtcCArIHRvdGFsX2FidW5kYW5jZSArIHBoeXRvX21ldGFkYXRhJHllYXIpKQ0KYGBgDQrpgbjmip7jgZXjgozjgZ/jg5njgrnjg4jjg6Ljg4fjg6vjga7jgb7jgajjgoHjgpLlh7rlipvjgZnjgosNCg0K4oaS5rip5bqm44Go5bm044GM5YWl44Gj44Gf44Oi44OH44Or44GM44OZ44K544OI44Gn44GC44KL44GT44Go44GM44KP44GL44KLDQpgYGB7cn0NCnN1bW1hcnkoc2VsZWN0ZWRfbW9kZWwpDQpgYGANCg0K