Lecture5: Wordcloudパッケージ, Manipulate関数

sentence1 & sentence1

sentence1 <- "The parent of Facebook, Instagram and WhatsApp reduced its work force by 13 percent and extended a hiring freeze through the first quarter of next year."

sentence2 <- "Over the summer, Lyft cut 2 percent of its employees, mostly as a result of shutting down its car rental business, and froze hiring. "

sentence1出現頻度表

wordLst<-strsplit(sentence1,"[[:space:]]|[[:punct:]]")
wordLst<-unlist(wordLst)
wordLst<-tolower(wordLst)
wordLst<- wordLst[wordLst != ""]
s1_freq <- table(wordLst)
(s1_freq_table<-sort(s1_freq, decreasing=TRUE))
wordLst
      and        of       the        13         a        by  extended  facebook     first 
        2         2         2         1         1         1         1         1         1 
    force    freeze    hiring instagram       its      next    parent   percent   quarter 
        1         1         1         1         1         1         1         1         1 
  reduced   through  whatsapp      work      year 
        1         1         1         1         1 

sentence2出現頻度表

wordLst<-strsplit(sentence2,"[[:space:]]|[[:punct:]]")
wordLst<-unlist(wordLst)
wordLst<-tolower(wordLst)
wordLst<- wordLst[wordLst != ""]
s2_freq <- table(wordLst)
(s2_freq_table<-sort(s2_freq, decreasing=TRUE))
wordLst
      its        of         2         a       and        as  business       car       cut 
        2         2         1         1         1         1         1         1         1 
     down employees     froze    hiring      lyft    mostly      over   percent    rental 
        1         1         1         1         1         1         1         1         1 
   result  shutting    summer       the 
        1         1         1         1 

2つの変数を連結(merge)

全ての単語

freq_merge <-merge(s1_freq_table, s2_freq_table, all=T, by="wordLst",suffixes = c(".s1",".s2"))
freq_merge

View

View(s1_freq_table)

共通単語のみ

merge(s1_freq_table, s2_freq_table, by="wordLst")

s1_freq_tableの単語基準

merge(s1_freq_table, s2_freq_table, all.x=TRUE, by="wordLst")

s2_freq_tableの単語基準

merge(s1_freq_table, s2_freq_table, all.y=TRUE, by="wordLst")

空セル(NA)に値を代入

freq_merge[is.na(freq_merge)] <- 0

View

View(freq_merge)

Loading packages: wordcloud, manipulate

library(wordcloud)
library(manipulate)

”sample_ja_2”の頻度テーブル

txt2<-readLines("sample_texts/sample_ja_2.txt")
wordLst<-strsplit(txt2,"[[:space:]]|[[:punct:]]")
wordLst<-unlist(wordLst)
wordLst<- wordLst[wordLst != ""]
freq2 <- table(wordLst)
freq_table2<-sort(freq2, decreasing=TRUE)
(freqData2 <- data.frame(freq_table2))
wordcloud(freqData2$wordLst,freqData2$Freq)

RColorBrewer Package

binfo<-brewer.pal.info[]
palets <-rownames(binfo[binfo$maxcolors>10,])
palets
 [1] "BrBG"     "PiYG"     "PRGn"     "PuOr"     "RdBu"     "RdGy"     "RdYlBu"   "RdYlGn"  
 [9] "Spectral" "Paired"   "Set3"    

wordcloud using custom colors

palets[10]
[1] "Paired"
wordcloud(freqData2$wordLst,freqData2$Freq, colors=brewer.pal(10,palets[1]))

wordcloud using custom colors

wordcloud(freqData2$wordLst,freqData2$Freq, colors=brewer.pal(10,palets[10]), min.freq=2)

wordcloud2

Introduction

install.packages('wordcloud2')
library('wordcloud2')
wordcloud2(freqData2)

manipulate (インタラクティブなプロット)

manipulate関数の書き方

  • 単一実行スクリプトの場合
manipulate(
  実行スクリプト,
  picker, sliderの情報(複数の場合はカンマで結合)
)
  • 複数実行スクリプトの場合
manipulate(
  {
  複数の実行スクリプト
  },
  picker, sliderの情報(複数の場合はカンマで結合)
)

注意:manipulate関数は、配布Notebookファイルではなく、拡張子”.R”のファイル上で確認すること

色の選択

title="PCH Symbols"
xlabel="x"
ylabel="y"
plot(0,0,pch=8,cex=5,col="blue", main=title, xlab=xlabel, ylab=ylabel)

  • picker()関数
manipulate(plot(0,0,pch=8,cex=5,col=myColors), myColors=picker("red", "violet", "pink", "orange", "yellow", "green", "blue", "cyan") )
  • picker()関数 & List
colors = c("red", "violet", "pink", "orange", "yellow", "green", "blue", "cyan")
manipulate(plot(0,0,pch=8,cex=5,col=myColors), myColors=picker(colors) )

プロットマーカーの選択

manipulate(
  plot(0,0,pch=myMarkers,cex=5,col=myColors), myColors=picker("red", "violet", "pink", "orange", "yellow", "green", "blue", "cyan",initial="violet"),
  myMarkers=picker(1,2,3,4,5,6,7,8,initial="5")
)

picker + List

colPalets = c("red", "violet", "pink", "orange", "yellow", "green", "blue", "cyan")
manipulate(
  plot(0,0,pch=myMarkers,cex=5,col=myColors, main=title, xlab=xlabel, ylab=ylabel),
  myColors=picker(as.list(colPalets),initial=colPalets[2]),
  myMarkers=picker(as.list(seq(1,8)),initial="5")
)

プロットサイズの選択

  • slider()関数
manipulate(
  plot(0,0,pch=8,cex=mySize,col="blue"),
  mySize=slider(1,10,initial=5)
)

棒グラフ(引数:テーブル型データの場合)

barplot(freq_table2[1:15], las=3, ylab="Frequency")

棒グラフ(引数:テーブルフレーム型の場合)

freqLst <- freqData2$Freq[1:15]
names(freqLst) <-freqData2$wordLst[1:15]
barplot(freqLst, las=3, ylab="Frequency")

色付き棒グラフ

color8 = c("red", "violet", "pink", "orange", "yellow", "green", "blue", "cyan")
barplot(freqLst, las=3,col=color8,ylab="Frequency")

練習1:manipulate関数で、上の棒グラフの軸ラベルの向き(変数las)と、色(変数col)をインタラクティブに変更できるようにしてください。

  • 実行結果例は、配布資料の動画を参照

練習2:manipulate関数で、下のwordcloud描画の変数colorsと、変数min.freqをインタラクティブに変更できるようにしてください。

  • 実行結果例は、配布資料の動画を参照

wordcloud using custom colors

wordcloud(freqData2$wordLst,freqData2$Freq, colors=brewer.pal(10,palets[10]), min.freq=2)

LS0tCnRpdGxlOiAiTGVjMDU6IE1hbmlwdWxhdGUiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgTGVjdHVyZTU6IFdvcmRjbG91ZOODkeODg+OCseODvOOCuCwgTWFuaXB1bGF0ZemWouaVsAoKIyMgc2VudGVuY2UxICYgc2VudGVuY2UxCmBgYHtyfQpzZW50ZW5jZTEgPC0gIlRoZSBwYXJlbnQgb2YgRmFjZWJvb2ssIEluc3RhZ3JhbSBhbmQgV2hhdHNBcHAgcmVkdWNlZCBpdHMgd29yayBmb3JjZSBieSAxMyBwZXJjZW50IGFuZCBleHRlbmRlZCBhIGhpcmluZyBmcmVlemUgdGhyb3VnaCB0aGUgZmlyc3QgcXVhcnRlciBvZiBuZXh0IHllYXIuIgoKc2VudGVuY2UyIDwtICJPdmVyIHRoZSBzdW1tZXIsIEx5ZnQgY3V0IDIgcGVyY2VudCBvZiBpdHMgZW1wbG95ZWVzLCBtb3N0bHkgYXMgYSByZXN1bHQgb2Ygc2h1dHRpbmcgZG93biBpdHMgY2FyIHJlbnRhbCBidXNpbmVzcywgYW5kIGZyb3plIGhpcmluZy4gIgpgYGAKCiMjIHNlbnRlbmNlMeWHuuePvumgu+W6puihqApgYGB7cn0Kd29yZExzdDwtc3Ryc3BsaXQoc2VudGVuY2UxLCJbWzpzcGFjZTpdXXxbWzpwdW5jdDpdXSIpCndvcmRMc3Q8LXVubGlzdCh3b3JkTHN0KQp3b3JkTHN0PC10b2xvd2VyKHdvcmRMc3QpCndvcmRMc3Q8LSB3b3JkTHN0W3dvcmRMc3QgIT0gIiJdCnMxX2ZyZXEgPC0gdGFibGUod29yZExzdCkKKHMxX2ZyZXFfdGFibGU8LXNvcnQoczFfZnJlcSwgZGVjcmVhc2luZz1UUlVFKSkKYGBgCiMjIHNlbnRlbmNlMuWHuuePvumgu+W6puihqApgYGB7cn0Kd29yZExzdDwtc3Ryc3BsaXQoc2VudGVuY2UyLCJbWzpzcGFjZTpdXXxbWzpwdW5jdDpdXSIpCndvcmRMc3Q8LXVubGlzdCh3b3JkTHN0KQp3b3JkTHN0PC10b2xvd2VyKHdvcmRMc3QpCndvcmRMc3Q8LSB3b3JkTHN0W3dvcmRMc3QgIT0gIiJdCnMyX2ZyZXEgPC0gdGFibGUod29yZExzdCkKKHMyX2ZyZXFfdGFibGU8LXNvcnQoczJfZnJlcSwgZGVjcmVhc2luZz1UUlVFKSkKYGBgCgoKIyMg77yS44Gk44Gu5aSJ5pWw44KS6YCj57WQKG1lcmdlKQojIyMg5YWo44Gm44Gu5Y2Y6KqeCmBgYHtyfQpmcmVxX21lcmdlIDwtbWVyZ2UoczFfZnJlcV90YWJsZSwgczJfZnJlcV90YWJsZSwgYWxsPVQsIGJ5PSJ3b3JkTHN0IixzdWZmaXhlcyA9IGMoIi5zMSIsIi5zMiIpKQpmcmVxX21lcmdlCmBgYAoKIyMjIFZpZXcKYGBge3IsIGV2YWw9RkFMU0V9ClZpZXcoczFfZnJlcV90YWJsZSkKYGBgCgojIyMg5YWx6YCa5Y2Y6Kqe44Gu44G/CmBgYHtyfQptZXJnZShzMV9mcmVxX3RhYmxlLCBzMl9mcmVxX3RhYmxlLCBieT0id29yZExzdCIpCmBgYAoKIyMjIHMxX2ZyZXFfdGFibGXjga7ljZjoqp7ln7rmupYKYGBge3J9Cm1lcmdlKHMxX2ZyZXFfdGFibGUsIHMyX2ZyZXFfdGFibGUsIGFsbC54PVRSVUUsIGJ5PSJ3b3JkTHN0IikKYGBgCgojIyMgczJfZnJlcV90YWJsZeOBruWNmOiqnuWfuua6lgpgYGB7cn0KbWVyZ2UoczFfZnJlcV90YWJsZSwgczJfZnJlcV90YWJsZSwgYWxsLnk9VFJVRSwgYnk9IndvcmRMc3QiKQpgYGAKCiMjIOepuuOCu+ODq++8iE5B77yJ44Gr5YCk44KS5Luj5YWlCmBgYHtyfQpmcmVxX21lcmdlW2lzLm5hKGZyZXFfbWVyZ2UpXSA8LSAwCmBgYAoKIyMjIFZpZXcKYGBge3IsIGV2YWw9RkFMU0V9ClZpZXcoZnJlcV9tZXJnZSkKYGBgCgojIyBMb2FkaW5nIHBhY2thZ2VzOiB3b3JkY2xvdWQsIG1hbmlwdWxhdGUKYGBge3J9CmxpYnJhcnkod29yZGNsb3VkKQpsaWJyYXJ5KG1hbmlwdWxhdGUpCmBgYAojIyAg4oCdc2FtcGxlX2phXzLigJ3jga7poLvluqbjg4bjg7zjg5bjg6sKYGBge3J9CnR4dDI8LXJlYWRMaW5lcygic2FtcGxlX3RleHRzL3NhbXBsZV9qYV8yLnR4dCIpCndvcmRMc3Q8LXN0cnNwbGl0KHR4dDIsIltbOnNwYWNlOl1dfFtbOnB1bmN0Ol1dIikKd29yZExzdDwtdW5saXN0KHdvcmRMc3QpCndvcmRMc3Q8LSB3b3JkTHN0W3dvcmRMc3QgIT0gIiJdCmZyZXEyIDwtIHRhYmxlKHdvcmRMc3QpCmZyZXFfdGFibGUyPC1zb3J0KGZyZXEyLCBkZWNyZWFzaW5nPVRSVUUpCihmcmVxRGF0YTIgPC0gZGF0YS5mcmFtZShmcmVxX3RhYmxlMikpCmBgYAoKYGBge3J9CndvcmRjbG91ZChmcmVxRGF0YTIkd29yZExzdCxmcmVxRGF0YTIkRnJlcSkKYGBgCgojIyMgPGEgaHJlZj0iaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL1JDb2xvckJyZXdlci9SQ29sb3JCcmV3ZXIucGRmIiB0YXJnZXQ9Il9ibGFuayI+UkNvbG9yQnJld2VyIFBhY2thZ2U8L2E+CmBgYHtyfQpiaW5mbzwtYnJld2VyLnBhbC5pbmZvW10KcGFsZXRzIDwtcm93bmFtZXMoYmluZm9bYmluZm8kbWF4Y29sb3JzPjEwLF0pCnBhbGV0cwpgYGAKCiMjIyB3b3JkY2xvdWQgdXNpbmcgY3VzdG9tIGNvbG9ycwpgYGB7cn0KcGFsZXRzWzEwXQp3b3JkY2xvdWQoZnJlcURhdGEyJHdvcmRMc3QsZnJlcURhdGEyJEZyZXEsIGNvbG9ycz1icmV3ZXIucGFsKDEwLHBhbGV0c1sxXSkpCmBgYAojIyMgd29yZGNsb3VkIHVzaW5nIGN1c3RvbSBjb2xvcnMKYGBge3J9CndvcmRjbG91ZChmcmVxRGF0YTIkd29yZExzdCxmcmVxRGF0YTIkRnJlcSwgY29sb3JzPWJyZXdlci5wYWwoMTAscGFsZXRzWzEwXSksIG1pbi5mcmVxPTIpCmBgYAoKIyMgd29yZGNsb3VkMgojIyMgPGEgaHJlZj0iaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3dvcmRjbG91ZDIvdmlnbmV0dGVzL3dvcmRjbG91ZC5odG1sIiB0YXJnZXQ9Il9ibGFuayI+SW50cm9kdWN0aW9uPC9hPgpgYGB7ciwgZXZhbD1GQUxTRX0KaW5zdGFsbC5wYWNrYWdlcygnd29yZGNsb3VkMicpCmBgYAoKYGBge3J9CmxpYnJhcnkoJ3dvcmRjbG91ZDInKQpgYGAKCgpgYGB7cn0Kd29yZGNsb3VkMihmcmVxRGF0YTIpCmBgYAoKIyMgbWFuaXB1bGF0ZSAo44Kk44Oz44K/44Op44Kv44OG44Kj44OW44Gq44OX44Ot44OD44OIKQojIyMgbWFuaXB1bGF0ZemWouaVsOOBruabuOOBjeaWuQoqIOWNmOS4gOWun+ihjOOCueOCr+ODquODl+ODiOOBruWgtOWQiApgYGAKbWFuaXB1bGF0ZSgKICDlrp/ooYzjgrnjgq/jg6rjg5fjg4gsCiAgcGlja2VyLCBzbGlkZXLjga7mg4XloLHvvIjopIfmlbDjga7loLTlkIjjga/jgqvjg7Pjg57jgafntZDlkIjvvIkKKQpgYGAKCiog6KSH5pWw5a6f6KGM44K544Kv44Oq44OX44OI44Gu5aC05ZCICmBgYAptYW5pcHVsYXRlKAogIHsKICDopIfmlbDjga7lrp/ooYzjgrnjgq/jg6rjg5fjg4gKICB9LAogIHBpY2tlciwgc2xpZGVy44Gu5oOF5aCx77yI6KSH5pWw44Gu5aC05ZCI44Gv44Kr44Oz44Oe44Gn57WQ5ZCI77yJCikKYGBgCgojIyMjIOazqOaEj++8mm1hbmlwdWxhdGXplqLmlbDjga/jgIHphY3luINOb3RlYm9va+ODleOCoeOCpOODq+OBp+OBr+OBquOBj+OAgeaLoeW8teWtkOKAnS5S4oCd44Gu44OV44Kh44Kk44Or5LiK44Gn56K66KqN44GZ44KL44GT44GoCgojIyMg6Imy44Gu6YG45oqeCmBgYHtyfQp0aXRsZT0iUENIIFN5bWJvbHMiCnhsYWJlbD0ieCIKeWxhYmVsPSJ5IgpwbG90KDAsMCxwY2g9OCxjZXg9NSxjb2w9ImJsdWUiLCBtYWluPXRpdGxlLCB4bGFiPXhsYWJlbCwgeWxhYj15bGFiZWwpCmBgYAoKKiBwaWNrZXIoKemWouaVsApgYGB7cixlcnJvcj1GQUxTRSxldmFsPUZBTFNFfQptYW5pcHVsYXRlKHBsb3QoMCwwLHBjaD04LGNleD01LGNvbD1teUNvbG9ycyksIG15Q29sb3JzPXBpY2tlcigicmVkIiwgInZpb2xldCIsICJwaW5rIiwgIm9yYW5nZSIsICJ5ZWxsb3ciLCAiZ3JlZW4iLCAiYmx1ZSIsICJjeWFuIikgKQpgYGAKKiBwaWNrZXIoKemWouaVsCAmIExpc3QKYGBge3IsZXJyb3I9RkFMU0UsZXZhbD1GQUxTRX0KY29sb3JzID0gYygicmVkIiwgInZpb2xldCIsICJwaW5rIiwgIm9yYW5nZSIsICJ5ZWxsb3ciLCAiZ3JlZW4iLCAiYmx1ZSIsICJjeWFuIikKbWFuaXB1bGF0ZShwbG90KDAsMCxwY2g9OCxjZXg9NSxjb2w9bXlDb2xvcnMpLCBteUNvbG9ycz1waWNrZXIoY29sb3JzKSApCmBgYAoKIyMjIOODl+ODreODg+ODiOODnuODvOOCq+ODvOOBrumBuOaKngoqIDxhIGhyZWY9Imh0dHA6Ly9jc2UubmFyby5hZmZyYy5nby5qcC90YWtlemF3YS9yLXRpcHMvci81My5odG1sIiB0YXJnZXQ9Il9ibGFuayI+44Oe44O844Kr44O8PC9hPgoqIHBpY2tlcigp6Zai5pWwCmBgYHtyLGVycm9yPUZBTFNFLGV2YWw9RkFMU0V9Cm1hbmlwdWxhdGUoCiAgcGxvdCgwLDAscGNoPW15TWFya2VycyxjZXg9NSxjb2w9bXlDb2xvcnMpLCBteUNvbG9ycz1waWNrZXIoInJlZCIsICJ2aW9sZXQiLCAicGluayIsICJvcmFuZ2UiLCAieWVsbG93IiwgImdyZWVuIiwgImJsdWUiLCAiY3lhbiIsaW5pdGlhbD0idmlvbGV0IiksCiAgbXlNYXJrZXJzPXBpY2tlcigxLDIsMyw0LDUsNiw3LDgsaW5pdGlhbD0iNSIpCikKYGBgCgojIyMgcGlja2VyICsgTGlzdApgYGB7cixlcnJvcj1GQUxTRSxldmFsPUZBTFNFfQpjb2xQYWxldHMgPSBjKCJyZWQiLCAidmlvbGV0IiwgInBpbmsiLCAib3JhbmdlIiwgInllbGxvdyIsICJncmVlbiIsICJibHVlIiwgImN5YW4iKQptYW5pcHVsYXRlKAogIHBsb3QoMCwwLHBjaD1teU1hcmtlcnMsY2V4PTUsY29sPW15Q29sb3JzLCBtYWluPXRpdGxlLCB4bGFiPXhsYWJlbCwgeWxhYj15bGFiZWwpLAogIG15Q29sb3JzPXBpY2tlcihhcy5saXN0KGNvbFBhbGV0cyksaW5pdGlhbD1jb2xQYWxldHNbMl0pLAogIG15TWFya2Vycz1waWNrZXIoYXMubGlzdChzZXEoMSw4KSksaW5pdGlhbD0iNSIpCikKYGBgCgojIyMg44OX44Ot44OD44OI44K144Kk44K644Gu6YG45oqeCiogc2xpZGVyKCnplqLmlbAKYGBge3IsZXJyb3I9RkFMU0UsZXZhbD1GQUxTRX0KbWFuaXB1bGF0ZSgKICBwbG90KDAsMCxwY2g9OCxjZXg9bXlTaXplLGNvbD0iYmx1ZSIpLAogIG15U2l6ZT1zbGlkZXIoMSwxMCxpbml0aWFsPTUpCikKYGBgCgojIyDmo5LjgrDjg6njg5Uo5byV5pWw77ya44OG44O844OW44Or5Z6L44OH44O844K/44Gu5aC05ZCIKQpgYGB7cn0KYmFycGxvdChmcmVxX3RhYmxlMlsxOjE1XSwgbGFzPTMsIHlsYWI9IkZyZXF1ZW5jeSIpCmBgYAoKIyMg5qOS44Kw44Op44OVKOW8leaVsO+8muODhuODvOODluODq+ODleODrOODvOODoOWei+OBruWgtOWQiCkKYGBge3J9CmZyZXFMc3QgPC0gZnJlcURhdGEyJEZyZXFbMToxNV0KbmFtZXMoZnJlcUxzdCkgPC1mcmVxRGF0YTIkd29yZExzdFsxOjE1XQpiYXJwbG90KGZyZXFMc3QsIGxhcz0zLCB5bGFiPSJGcmVxdWVuY3kiKQpgYGAKCgojIyDoibLku5jjgY3mo5LjgrDjg6njg5UKYGBge3J9CmNvbG9yOCA9IGMoInJlZCIsICJ2aW9sZXQiLCAicGluayIsICJvcmFuZ2UiLCAieWVsbG93IiwgImdyZWVuIiwgImJsdWUiLCAiY3lhbiIpCmJhcnBsb3QoZnJlcUxzdCwgbGFzPTMsY29sPWNvbG9yOCx5bGFiPSJGcmVxdWVuY3kiKQpgYGAKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyAiPue3tOe/kjE8L3NwYW4+Om1hbmlwdWxhdGXplqLmlbDjgafjgIHkuIrjga7mo5LjgrDjg6njg5Xjga7ou7jjg6njg5njg6vjga7lkJHjgY3vvIjlpInmlbBsYXPvvInjgajjgIHoibLvvIjlpInmlbBjb2zvvInjgpLjgqTjg7Pjgr/jg6njgq/jg4bjgqPjg5bjgavlpInmm7TjgafjgY3jgovjgojjgYbjgavjgZfjgabjgY/jgaDjgZXjgYTjgIIKCiog5a6f6KGM57WQ5p6c5L6L44Gv44CB6YWN5biD6LOH5paZ44Gu5YuV55S744KS5Y+C54WnCgoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyAiPue3tOe/kjI8L3NwYW4+Om1hbmlwdWxhdGXplqLmlbDjgafjgIHkuIvjga53b3JkY2xvdWTmj4/nlLvjga7lpInmlbBjb2xvcnPjgajjgIHlpInmlbBtaW4uZnJlceOCkuOCpOODs+OCv+ODqeOCr+ODhuOCo+ODluOBq+WkieabtOOBp+OBjeOCi+OCiOOBhuOBq+OBl+OBpuOBj+OBoOOBleOBhOOAggoKKiDlrp/ooYzntZDmnpzkvovjga/jgIHphY3luIPos4fmlpnjga7li5XnlLvjgpLlj4LnhacKCiMjIyB3b3JkY2xvdWQgdXNpbmcgY3VzdG9tIGNvbG9ycwpgYGB7cn0Kd29yZGNsb3VkKGZyZXFEYXRhMiR3b3JkTHN0LGZyZXFEYXRhMiRGcmVxLCBjb2xvcnM9YnJld2VyLnBhbCgxMCxwYWxldHNbMTBdKSwgbWluLmZyZXE9MikKYGBgCgoKCg==