タンパク質相互作用ネットワークを題材に中心性指標とタンパク質の必須性の関係を調査します。具体的に,次のことを行います。

必須タンパク質と非必須タンパク質を中心性指標の比較

igraphパッケージの読み込み

library(igraph)

次のパッケージを付け加えます: ‘igraph’

以下のオブジェクトは ‘package:stats’ からマスクされています:

    decompose, spectrum

以下のオブジェクトは ‘package:base’ からマスクされています:

    union

大腸菌のタンパク質相互作用ネットワークの読み込み

  • ../data/ecoli_ppi_Hu_etal_2009.txt
  • エッジリスト形式
  • Hu P, Janga SC, Babu M, Díaz-Mejía JJ, Butland G, et al. Global functional atlas of Escherichia coli encompassing previously uncharacterized proteins. PLoS Biol. 2009 Apr 28;7(4):e96. doi: 10.1371/journal.pbio.1000096.
# エッジリストの読み込み
d <- read.table("../data/ecoli_ppi_Hu_etal_2009.txt")
# グラフオブジェクトの作成
g <- simplify(graph_from_data_frame(d,directed=F),remove.multiple=T,remove.loops=T)

# 最大連結成分の取得
cls <- components(g,"weak")
g <- induced_subgraph(g, V(g)$name[cls$membership==which(cls$csize==max(cls$csize))[[1]]])

中心性指標の計算

# 次数中心性(degree centrality)
degree <- degree(g)
# 固有ベクトル中心性(eigenvector centraliry)
eigen <- eigen_centrality(g)$vector
# PageRank
page <- page_rank(g)$vector
# 近接中心性(closeness centrality)
closen <- closeness(g)
# 媒介中心性(betweenness centrality)
between <- betweenness(g)
# サブグラフ中心性(subgraph centrality)
subgraph <- subgraph_centrality(g)
# データフレームにまとめる
nprop <- data.frame(V(g)$name,degree,eigen,page,closen,between,subgraph)
names(nprop)[[1]] <- "gene"

タンパク質の必須性のデータを読み込む

Baba T, Ara T, Hasegawa M, Takai Y, Okumura Y, Baba M, Datsenko KA, Tomita M, Wanner BL, Mori H. Construction of Escherichia coli K-12 in-frame, single-gene knockout mutants: the Keio collection. Mol Syst Biol. 2006;2:2006.0008. Epub 2006 Feb 21. doi: 10.1038/msb4100050

ess <- read.table("../data/ecoli_proteins_essentiality_Baba2006MSB.txt",header=T)
# 必須(E),非必須(N),不明(u)
# 中心性指標のデータと必須性のデータをマージする
d <- merge(ess, nprop,by="gene")
# unknownの遺伝子を除外する。
d <- d[d$essential!="u",]

Boxplotの表示

layout(matrix(1:6, ncol=3))
# 次数中心性(degree centrality)
boxplot(log(d$degree)~d$essential,xlab="Essentiality",ylab="Degree")
# 固有ベクトル中心性(eigenvector centraliry)
boxplot(log(d$eigen)~d$essential,xlab="Essentiality",ylab="Eigenvector")
# PageRank
boxplot(log(d$page)~d$essential,xlab="Essentiality",ylab="PageRank")
# 近接中心性(closeness centrality)
boxplot(d$closen~d$essential,xlab="Essentiality",ylab="Closeness")
# 媒介中心性(betweenness centrality)
boxplot(log(d$between+1)~d$essential,xlab="Essentiality",ylab="Betweenness")
# サブグラフ中心性(subgraph centrality)
boxplot(log(d$subgraph)~d$essential,xlab="Essentiality",ylab="Subgraph")

必須タンパク質と非必須タンパク質の中心性指標の差の検定

前準備

# 必須タンパク質の中心性指標
ess_nprop <- d[d$essential=="E",]
# 非必須タンパク質の中心性指標
noness_nprop <- d[d$essential=="N",]

Wilcoxon検定

cat("次数中心性(degree centrality)
    中央値 必須:",median(ess_nprop$degree),"非必須:",median(noness_nprop$degree),"\n")
次数中心性(degree centrality)
    中央値 必須: 9 非必須: 2 
wilcox.test(ess_nprop$degree, noness_nprop$degree)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$degree and noness_nprop$degree
W = 171775, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0
cat("固有ベクトル中心性(eigenvector centraliry)
    中央値 必須:",median(ess_nprop$eigen),"非必須:",median(noness_nprop$eigen),"\n")
固有ベクトル中心性(eigenvector centraliry)
    中央値 必須: 0.04040747 非必須: 0.00491207 
wilcox.test(ess_nprop$eigen, noness_nprop$eigen)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$eigen and noness_nprop$eigen
W = 173696, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0
cat("PageRank
    中央値 必須:",median(ess_nprop$page),"非必須:",median(noness_nprop$page),"\n")
PageRank
    中央値 必須: 0.0008231837 非必須: 0.0002878847 
wilcox.test(ess_nprop$page, noness_nprop$page)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$page and noness_nprop$page
W = 168277, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0
cat("近接中心性(closeness centrality)
    中央値 必須:",median(ess_nprop$closen),"非必須:",median(noness_nprop$closen),"\n")
近接中心性(closeness centrality)
    中央値 必須: 0.0001693338 非必須: 0.0001446132 
wilcox.test(ess_nprop$closen, noness_nprop$closen)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$closen and noness_nprop$closen
W = 173099, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0
cat("媒介中心性(betweenness centrality)
    中央値 必須:",median(ess_nprop$between),"非必須:",median(noness_nprop$between),"\n")
媒介中心性(betweenness centrality)
    中央値 必須: 2453.932 非必須: 47.76135 
wilcox.test(ess_nprop$between, noness_nprop$between)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$between and noness_nprop$between
W = 166378, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0
cat("サブグラフ中心性(subgraph centrality)
    中央値 必須:",median(ess_nprop$subgraph),"非必須:",median(noness_nprop$subgraph),"\n")
サブグラフ中心性(subgraph centrality)
    中央値 必須: 6.05615e+11 非必須: 8949452569 
wilcox.test(ess_nprop$subgraph, noness_nprop$subgraph)

    Wilcoxon rank sum test with continuity correction

data:  ess_nprop$subgraph and noness_nprop$subgraph
W = 173693, p-value < 2.2e-16
alternative hypothesis: true location shift is not equal to 0

単一の中心性指標を用いて必須タンパク質を判別する

前準備

# 必須なら1,非必須なら0とする。
ess_score <- ifelse(d$essential == "E",1,0)
# ROCカーブを書くためのパッケージを読み込む
library(pROC)
Type 'citation("pROC")' for a citation.

次のパッケージを付け加えます: ‘pROC’

以下のオブジェクトは ‘package:stats’ からマスクされています:

    cov, smooth, var

ROCカーブのプロット

layout(matrix(1:6, ncol=3))
# 次数中心性(degree centrality)
plot.roc(ess_score,d$degree,print.auc=T,main="Degree")
Setting levels: control = 0, case = 1
Setting direction: controls < cases
# 固有ベクトル中心性(eigenvector centraliry)
plot.roc(ess_score,d$eigen,print.auc=T,main="Eigenvector")
Setting levels: control = 0, case = 1
Setting direction: controls < cases
# PageRank
plot.roc(ess_score,d$page,print.auc=T,main="PageRank")
Setting levels: control = 0, case = 1
Setting direction: controls < cases
# 近接中心性(closeness centrality)
plot.roc(ess_score,d$closen,print.auc=T,main="Closeness")
Setting levels: control = 0, case = 1
Setting direction: controls < cases
# 媒介中心性(betweenness centrality)
plot.roc(ess_score,d$between,print.auc=T,main="Betweenness")
Setting levels: control = 0, case = 1
Setting direction: controls < cases
# サブグラフ中心性(Subgraph centrality)
plot.roc(ess_score,d$subgraph,print.auc=T,main="Subgraph")
Setting levels: control = 0, case = 1
Setting direction: controls < cases

やってみよう

酵母のデータ

  • 出芽酵母のタンパク質相互作用ネットワーク
    • ../data/yeast_ppi_Batada_etal_2006.txt
    • エッジリスト形式
    • Batada NN et al. (2006) Stratus not altocumulus: a new view of the yeast protein interaction network. PLoS Biol 4, e317. doi: 10.1371/journal.pbio.0040317
  • 出芽酵母タンパク質(遺伝子)の必須性
    • ../data/yeast_proteins_essentiality_OGEE.txt
    • 必須(E),非必須(N)
    • Chen WH, Minguez P, Lercher MJ, Bork P (2012) OGEE: an online gene essentiality database. Nucleic Acids Res 40, D901-906. doi: 10.1093/nar/gkr986.
LS0tDQp0aXRsZTogIuS4reW/g+aAp+ino+aekO+8iENlbnRyYWxpdHkgYW5hbHlzaXPvvIkiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQrjgr/jg7Pjg5Hjgq/os6rnm7jkupLkvZznlKjjg43jg4Pjg4jjg6/jg7zjgq/jgpLpoYzmnZDjgavkuK3lv4PmgKfmjIfmqJnjgajjgr/jg7Pjg5Hjgq/os6rjga7lv4XpoIjmgKfjga7plqLkv4LjgpLoqr/mn7vjgZfjgb7jgZnjgILlhbfkvZPnmoTjgavvvIzmrKHjga7jgZPjgajjgpLooYzjgYTjgb7jgZnjgIINCg0KICArIOOCv+ODs+ODkeOCr+izquebuOS6kuS9nOeUqOODjeODg+ODiOODr+ODvOOCr+OBruS4reW/g+aAp+aMh+aomeOCkuioiOeul+OBmeOCi+OBk+OBqOOBp+mHjeimgeOBquOCv+ODs+ODkeOCr+izquOCkuWQjOWumuOBl+OBvuOBmeOAgg0KICArIOW/hemgiOOCv+ODs+ODkeOCr+izquOBqOmdnuW/hemgiOOCv+ODs+ODkeOCr+izquOCkuS4reW/g+aAp+aMh+aomeOCkuavlOi8g+OBl++8jOW3ruOBrue1seioiOWIhuaekOOCkuihjOOBhOOBvuOBmeOAgg0KICArIOWNmOS4gOOBruS4reW/g+aAp+aMh+aomeOCkueUqOOBhOOBpuW/hemgiOOCv+ODs+ODkeOCr+izquOCkuWIpOWIpeOBl+OBvuOBmeOAgg0KDQojIOW/hemgiOOCv+ODs+ODkeOCr+izquOBqOmdnuW/hemgiOOCv+ODs+ODkeOCr+izquOCkuS4reW/g+aAp+aMh+aomeOBruavlOi8gw0KIyMjIGlncmFwaOODkeODg+OCseODvOOCuOOBruiqreOBv+i+vOOBvw0KYGBge3J9DQpsaWJyYXJ5KGlncmFwaCkNCmBgYA0KDQojIyMg5aSn6IW46I+M44Gu44K/44Oz44OR44Kv6LOq55u45LqS5L2c55So44ON44OD44OI44Ov44O844Kv44Gu6Kqt44G/6L6844G/DQogICsgYC4uL2RhdGEvZWNvbGlfcHBpX0h1X2V0YWxfMjAwOS50eHRgDQogICsg44Ko44OD44K444Oq44K544OI5b2i5byPDQogICsgSHUgUCwgSmFuZ2EgU0MsIEJhYnUgTSwgRMOtYXotTWVqw61hIEpKLCBCdXRsYW5kIEcsIGV0IGFsLiBHbG9iYWwgZnVuY3Rpb25hbCBhdGxhcyBvZiBFc2NoZXJpY2hpYSBjb2xpIGVuY29tcGFzc2luZyBwcmV2aW91c2x5IHVuY2hhcmFjdGVyaXplZCBwcm90ZWlucy4gUExvUyBCaW9sLiAyMDA5IEFwciAyODs3KDQpOmU5Ni4gZG9pOiAxMC4xMzcxL2pvdXJuYWwucGJpby4xMDAwMDk2Lg0KYGBge3J9DQojIOOCqOODg+OCuOODquOCueODiOOBruiqreOBv+i+vOOBvw0KZCA8LSByZWFkLnRhYmxlKCIuLi9kYXRhL2Vjb2xpX3BwaV9IdV9ldGFsXzIwMDkudHh0IikNCiMg44Kw44Op44OV44Kq44OW44K444Kn44Kv44OI44Gu5L2c5oiQDQpnIDwtIHNpbXBsaWZ5KGdyYXBoX2Zyb21fZGF0YV9mcmFtZShkLGRpcmVjdGVkPUYpLHJlbW92ZS5tdWx0aXBsZT1ULHJlbW92ZS5sb29wcz1UKQ0KDQojIOacgOWkp+mAo+e1kOaIkOWIhuOBruWPluW+lw0KY2xzIDwtIGNvbXBvbmVudHMoZywid2VhayIpDQpnIDwtIGluZHVjZWRfc3ViZ3JhcGgoZywgVihnKSRuYW1lW2NscyRtZW1iZXJzaGlwPT13aGljaChjbHMkY3NpemU9PW1heChjbHMkY3NpemUpKVtbMV1dXSkNCmBgYA0KDQojIyMg5Lit5b+D5oCn5oyH5qiZ44Gu6KiI566XDQpgYGB7cn0NCiMg5qyh5pWw5Lit5b+D5oCn77yIZGVncmVlIGNlbnRyYWxpdHnvvIkNCmRlZ3JlZSA8LSBkZWdyZWUoZykNCiMg5Zu65pyJ44OZ44Kv44OI44Or5Lit5b+D5oCn77yIZWlnZW52ZWN0b3IgY2VudHJhbGlyee+8iQ0KZWlnZW4gPC0gZWlnZW5fY2VudHJhbGl0eShnKSR2ZWN0b3INCiMgUGFnZVJhbmsNCnBhZ2UgPC0gcGFnZV9yYW5rKGcpJHZlY3Rvcg0KIyDov5HmjqXkuK3lv4PmgKfvvIhjbG9zZW5lc3MgY2VudHJhbGl0ee+8iQ0KY2xvc2VuIDwtIGNsb3NlbmVzcyhnKQ0KIyDlqpLku4vkuK3lv4PmgKfvvIhiZXR3ZWVubmVzcyBjZW50cmFsaXR577yJDQpiZXR3ZWVuIDwtIGJldHdlZW5uZXNzKGcpDQojIOOCteODluOCsOODqeODleS4reW/g+aAp++8iHN1YmdyYXBoIGNlbnRyYWxpdHnvvIkNCnN1YmdyYXBoIDwtIHN1YmdyYXBoX2NlbnRyYWxpdHkoZykNCmBgYA0KDQpgYGB7cn0NCiMg44OH44O844K/44OV44Os44O844Og44Gr44G+44Go44KB44KLDQpucHJvcCA8LSBkYXRhLmZyYW1lKFYoZykkbmFtZSxkZWdyZWUsZWlnZW4scGFnZSxjbG9zZW4sYmV0d2VlbixzdWJncmFwaCkNCm5hbWVzKG5wcm9wKVtbMV1dIDwtICJnZW5lIg0KYGBgDQoNCiMjIyDjgr/jg7Pjg5Hjgq/os6rjga7lv4XpoIjmgKfjga7jg4fjg7zjgr/jgpLoqq3jgb/ovrzjgoANCkJhYmEgVCwgQXJhIFQsIEhhc2VnYXdhIE0sIFRha2FpIFksIE9rdW11cmEgWSwgQmFiYSBNLCBEYXRzZW5rbyBLQSwgVG9taXRhIE0sIFdhbm5lciBCTCwgTW9yaSBILiBDb25zdHJ1Y3Rpb24gb2YgRXNjaGVyaWNoaWEgY29saSBLLTEyIGluLWZyYW1lLCBzaW5nbGUtZ2VuZSBrbm9ja291dCBtdXRhbnRzOiB0aGUgS2VpbyBjb2xsZWN0aW9uLiBNb2wgU3lzdCBCaW9sLiAyMDA2OzI6MjAwNi4wMDA4LiBFcHViIDIwMDYgRmViIDIxLiBkb2k6IDEwLjEwMzgvbXNiNDEwMDA1MA0KYGBge3J9DQplc3MgPC0gcmVhZC50YWJsZSgiLi4vZGF0YS9lY29saV9wcm90ZWluc19lc3NlbnRpYWxpdHlfQmFiYTIwMDZNU0IudHh0IixoZWFkZXI9VCkNCiMg5b+F6aCI77yIRe+8ie+8jOmdnuW/hemgiO+8iE7vvInvvIzkuI3mmI7vvIh177yJDQpgYGANCg0KYGBge3J9DQojIOS4reW/g+aAp+aMh+aomeOBruODh+ODvOOCv+OBqOW/hemgiOaAp+OBruODh+ODvOOCv+OCkuODnuODvOOCuOOBmeOCiw0KZCA8LSBtZXJnZShlc3MsIG5wcm9wLGJ5PSJnZW5lIikNCiMgdW5rbm93buOBrumBuuS8neWtkOOCkumZpOWkluOBmeOCi+OAgg0KZCA8LSBkW2QkZXNzZW50aWFsIT0idSIsXQ0KYGBgDQoNCiMjIyBCb3hwbG9044Gu6KGo56S6DQpgYGB7cn0NCmxheW91dChtYXRyaXgoMTo2LCBuY29sPTMpKQ0KIyDmrKHmlbDkuK3lv4PmgKfvvIhkZWdyZWUgY2VudHJhbGl0ee+8iQ0KYm94cGxvdChsb2coZCRkZWdyZWUpfmQkZXNzZW50aWFsLHhsYWI9IkVzc2VudGlhbGl0eSIseWxhYj0iRGVncmVlIikNCiMg5Zu65pyJ44OZ44Kv44OI44Or5Lit5b+D5oCn77yIZWlnZW52ZWN0b3IgY2VudHJhbGlyee+8iQ0KYm94cGxvdChsb2coZCRlaWdlbil+ZCRlc3NlbnRpYWwseGxhYj0iRXNzZW50aWFsaXR5Iix5bGFiPSJFaWdlbnZlY3RvciIpDQojIFBhZ2VSYW5rDQpib3hwbG90KGxvZyhkJHBhZ2UpfmQkZXNzZW50aWFsLHhsYWI9IkVzc2VudGlhbGl0eSIseWxhYj0iUGFnZVJhbmsiKQ0KIyDov5HmjqXkuK3lv4PmgKfvvIhjbG9zZW5lc3MgY2VudHJhbGl0ee+8iQ0KYm94cGxvdChkJGNsb3Nlbn5kJGVzc2VudGlhbCx4bGFiPSJFc3NlbnRpYWxpdHkiLHlsYWI9IkNsb3NlbmVzcyIpDQojIOWqkuS7i+S4reW/g+aAp++8iGJldHdlZW5uZXNzIGNlbnRyYWxpdHnvvIkNCmJveHBsb3QobG9nKGQkYmV0d2VlbisxKX5kJGVzc2VudGlhbCx4bGFiPSJFc3NlbnRpYWxpdHkiLHlsYWI9IkJldHdlZW5uZXNzIikNCiMg44K144OW44Kw44Op44OV5Lit5b+D5oCn77yIc3ViZ3JhcGggY2VudHJhbGl0ee+8iQ0KYm94cGxvdChsb2coZCRzdWJncmFwaCl+ZCRlc3NlbnRpYWwseGxhYj0iRXNzZW50aWFsaXR5Iix5bGFiPSJTdWJncmFwaCIpDQpgYGANCg0KIyDlv4XpoIjjgr/jg7Pjg5Hjgq/os6rjgajpnZ7lv4XpoIjjgr/jg7Pjg5Hjgq/os6rjga7kuK3lv4PmgKfmjIfmqJnjga7lt67jga7mpJzlrpoNCiMjIyDliY3mupblgpkNCmBgYHtyfQ0KIyDlv4XpoIjjgr/jg7Pjg5Hjgq/os6rjga7kuK3lv4PmgKfmjIfmqJkNCmVzc19ucHJvcCA8LSBkW2QkZXNzZW50aWFsPT0iRSIsXQ0KIyDpnZ7lv4XpoIjjgr/jg7Pjg5Hjgq/os6rjga7kuK3lv4PmgKfmjIfmqJkNCm5vbmVzc19ucHJvcCA8LSBkW2QkZXNzZW50aWFsPT0iTiIsXQ0KYGBgDQoNCiMjIyBXaWxjb3hvbuaknOWumg0KYGBge3J9DQpjYXQoIuasoeaVsOS4reW/g+aAp++8iGRlZ3JlZSBjZW50cmFsaXR577yJDQogICAg5Lit5aSu5YCk44CA5b+F6aCI77yaIixtZWRpYW4oZXNzX25wcm9wJGRlZ3JlZSksIumdnuW/hemgiO+8miIsbWVkaWFuKG5vbmVzc19ucHJvcCRkZWdyZWUpLCJcbiIpDQp3aWxjb3gudGVzdChlc3NfbnByb3AkZGVncmVlLCBub25lc3NfbnByb3AkZGVncmVlKQ0KYGBgDQoNCmBgYHtyfQ0KY2F0KCLlm7rmnInjg5njgq/jg4jjg6vkuK3lv4PmgKfvvIhlaWdlbnZlY3RvciBjZW50cmFsaXJ577yJDQogICAg5Lit5aSu5YCk44CA5b+F6aCI77yaIixtZWRpYW4oZXNzX25wcm9wJGVpZ2VuKSwi6Z2e5b+F6aCI77yaIixtZWRpYW4obm9uZXNzX25wcm9wJGVpZ2VuKSwiXG4iKQ0Kd2lsY294LnRlc3QoZXNzX25wcm9wJGVpZ2VuLCBub25lc3NfbnByb3AkZWlnZW4pDQoNCmNhdCgiUGFnZVJhbmsNCiAgICDkuK3lpK7lgKTjgIDlv4XpoIjvvJoiLG1lZGlhbihlc3NfbnByb3AkcGFnZSksIumdnuW/hemgiO+8miIsbWVkaWFuKG5vbmVzc19ucHJvcCRwYWdlKSwiXG4iKQ0Kd2lsY294LnRlc3QoZXNzX25wcm9wJHBhZ2UsIG5vbmVzc19ucHJvcCRwYWdlKQ0KDQpjYXQoIui/keaOpeS4reW/g+aAp++8iGNsb3NlbmVzcyBjZW50cmFsaXR577yJDQogICAg5Lit5aSu5YCk44CA5b+F6aCI77yaIixtZWRpYW4oZXNzX25wcm9wJGNsb3NlbiksIumdnuW/hemgiO+8miIsbWVkaWFuKG5vbmVzc19ucHJvcCRjbG9zZW4pLCJcbiIpDQp3aWxjb3gudGVzdChlc3NfbnByb3AkY2xvc2VuLCBub25lc3NfbnByb3AkY2xvc2VuKQ0KDQpjYXQoIuWqkuS7i+S4reW/g+aAp++8iGJldHdlZW5uZXNzIGNlbnRyYWxpdHnvvIkNCiAgICDkuK3lpK7lgKTjgIDlv4XpoIjvvJoiLG1lZGlhbihlc3NfbnByb3AkYmV0d2VlbiksIumdnuW/hemgiO+8miIsbWVkaWFuKG5vbmVzc19ucHJvcCRiZXR3ZWVuKSwiXG4iKQ0Kd2lsY294LnRlc3QoZXNzX25wcm9wJGJldHdlZW4sIG5vbmVzc19ucHJvcCRiZXR3ZWVuKQ0KDQpjYXQoIuOCteODluOCsOODqeODleS4reW/g+aAp++8iHN1YmdyYXBoIGNlbnRyYWxpdHnvvIkNCiAgICDkuK3lpK7lgKTjgIDlv4XpoIjvvJoiLG1lZGlhbihlc3NfbnByb3Akc3ViZ3JhcGgpLCLpnZ7lv4XpoIjvvJoiLG1lZGlhbihub25lc3NfbnByb3Akc3ViZ3JhcGgpLCJcbiIpDQp3aWxjb3gudGVzdChlc3NfbnByb3Akc3ViZ3JhcGgsIG5vbmVzc19ucHJvcCRzdWJncmFwaCkNCmBgYA0KDQojIOWNmOS4gOOBruS4reW/g+aAp+aMh+aomeOCkueUqOOBhOOBpuW/hemgiOOCv+ODs+ODkeOCr+izquOCkuWIpOWIpeOBmeOCiw0KDQojIyMg5YmN5rqW5YKZDQpgYGB7cn0NCiMg5b+F6aCI44Gq44KJMe+8jOmdnuW/hemgiOOBquOCiTDjgajjgZnjgovjgIINCmVzc19zY29yZSA8LSBpZmVsc2UoZCRlc3NlbnRpYWwgPT0gIkUiLDEsMCkNCiMgUk9D44Kr44O844OW44KS5pu444GP44Gf44KB44Gu44OR44OD44Kx44O844K444KS6Kqt44G/6L6844KADQpsaWJyYXJ5KHBST0MpDQpgYGANCg0KIyMjIFJPQ+OCq+ODvOODluOBruODl+ODreODg+ODiA0KYGBge3J9DQpsYXlvdXQobWF0cml4KDE6NiwgbmNvbD0zKSkNCiMg5qyh5pWw5Lit5b+D5oCn77yIZGVncmVlIGNlbnRyYWxpdHnvvIkNCnBsb3Qucm9jKGVzc19zY29yZSxkJGRlZ3JlZSxwcmludC5hdWM9VCxtYWluPSJEZWdyZWUiKQ0KIyDlm7rmnInjg5njgq/jg4jjg6vkuK3lv4PmgKfvvIhlaWdlbnZlY3RvciBjZW50cmFsaXJ577yJDQpwbG90LnJvYyhlc3Nfc2NvcmUsZCRlaWdlbixwcmludC5hdWM9VCxtYWluPSJFaWdlbnZlY3RvciIpDQojIFBhZ2VSYW5rDQpwbG90LnJvYyhlc3Nfc2NvcmUsZCRwYWdlLHByaW50LmF1Yz1ULG1haW49IlBhZ2VSYW5rIikNCiMg6L+R5o6l5Lit5b+D5oCn77yIY2xvc2VuZXNzIGNlbnRyYWxpdHnvvIkNCnBsb3Qucm9jKGVzc19zY29yZSxkJGNsb3NlbixwcmludC5hdWM9VCxtYWluPSJDbG9zZW5lc3MiKQ0KIyDlqpLku4vkuK3lv4PmgKfvvIhiZXR3ZWVubmVzcyBjZW50cmFsaXR577yJDQpwbG90LnJvYyhlc3Nfc2NvcmUsZCRiZXR3ZWVuLHByaW50LmF1Yz1ULG1haW49IkJldHdlZW5uZXNzIikNCiMg44K144OW44Kw44Op44OV5Lit5b+D5oCn77yIU3ViZ3JhcGggY2VudHJhbGl0ee+8iQ0KcGxvdC5yb2MoZXNzX3Njb3JlLGQkc3ViZ3JhcGgscHJpbnQuYXVjPVQsbWFpbj0iU3ViZ3JhcGgiKQ0KYGBgDQoNCiMg44KE44Gj44Gm44G/44KI44GGDQogICsg44GT44GuTm90ZWJvb2vjgpLlj4LogIPjgavjgZfjgabvvIzphbXmr43jga7jg4fjg7zjgr/jgpLop6PmnpDjgZfjgabjgb/jgojjgYbjgIINCiAgKyBOb3RlYm9va+OCkuWPguiAg+OBq+iHquWIhuOBruODh+ODvOOCv+OCkuino+aekOOBl+OBpuOBv+OCiOOBhuOAgg0KDQojIyMg6YW15q+N44Gu44OH44O844K/DQogICsg5Ye66Iq96YW15q+N44Gu44K/44Oz44OR44Kv6LOq55u45LqS5L2c55So44ON44OD44OI44Ov44O844KvDQogICAgICsgYGAuLi9kYXRhL3llYXN0X3BwaV9CYXRhZGFfZXRhbF8yMDA2LnR4dGBgDQogICAgICsg44Ko44OD44K444Oq44K544OI5b2i5byPDQogICAgICsgQmF0YWRhIE5OIGV0IGFsLiAoMjAwNikgU3RyYXR1cyBub3QgYWx0b2N1bXVsdXM6IGEgbmV3IHZpZXcgb2YgdGhlIHllYXN0IHByb3RlaW4gaW50ZXJhY3Rpb24gbmV0d29yay4gUExvUyBCaW9sIDQsIGUzMTcuIGRvaTogMTAuMTM3MS9qb3VybmFsLnBiaW8uMDA0MDMxNw0KICArIOWHuuiKvemFteavjeOCv+ODs+ODkeOCr+izqu+8iOmBuuS8neWtkO+8ieOBruW/hemgiOaApw0KICAgICArIGBgLi4vZGF0YS95ZWFzdF9wcm90ZWluc19lc3NlbnRpYWxpdHlfT0dFRS50eHRgYA0KICAgICArIOW/hemgiO+8iEXvvInvvIzpnZ7lv4XpoIjvvIhO77yJDQogICAgICsgQ2hlbiBXSCwgTWluZ3VleiBQLCBMZXJjaGVyIE1KLCBCb3JrIFAgKDIwMTIpIE9HRUU6IGFuIG9ubGluZSBnZW5lIGVzc2VudGlhbGl0eSBkYXRhYmFzZS4gTnVjbGVpYyBBY2lkcyBSZXMgNDAsIEQ5MDEtOTA2LiBkb2k6IDEwLjEwOTMvbmFyL2drcjk4Ni4=