Text Cleaning
Sebelum membuat wordclod dari kata yang diinginkan, maka perlu melakukan penghapusan kata-kata ataupun atribut yang diprediksikan akan sering muncul namun tidak memiliki makna yang berarti terhadap kata yang diinginkan. Jika hal ini tidak dilakukan, maka akan memberikan hasil analisis yang kurang sesuai.
library(tm)
library(NLP)
Build corpus
# build a corpus, and specify the source to be character vectors
myCorpus1 <- Corpus(VectorSource(tweets1$text))
myCorpus2 <- Corpus(VectorSource(tweets2$text))
# convert to lower case
myCorpus1 <- tm_map(myCorpus1,function(x) iconv(enc2utf8(x), sub="byte"))
myCorpus1 <- tm_map(myCorpus1, content_transformer(tolower))
myCorpus2 <- tm_map(myCorpus2,function(x) iconv(enc2utf8(x), sub="byte"))
myCorpus2 <- tm_map(myCorpus2, content_transformer(tolower))
# remove URLs
removeURL <- function(x) gsub("http[^[:space:]]*", "", x)
myCorpus1 <- tm_map(myCorpus1, content_transformer(removeURL))
myCorpus2 <- tm_map(myCorpus2, content_transformer(removeURL))
# remove anything other than English letters or space
removeNumPunct <- function(x) gsub("[^[:alpha:][:space:]]*", "", x)
myCorpus1 <- tm_map(myCorpus1, content_transformer(removeNumPunct))
myCorpus2 <- tm_map(myCorpus2, content_transformer(removeNumPunct))
# remove stopwords
myStopwords <- c(setdiff(stopwords('english'), c("r", "big")), "use", "see", "used", "via", "amp","ruangguru", "zenius","ààààà","àààà","ààà","àà","à","ðÿ")
stopwords_id <- read.table('stopwords-id.txt', header = FALSE)
myStopwords <- c(myStopwords, as.matrix(stopwords_id$V1), "hi", "yg")
myCorpus1 <- tm_map(myCorpus1, removeWords, myStopwords)
myCorpus2 <- tm_map(myCorpus2, removeWords, myStopwords)
# remove extra whitespace
myCorpus1<- tm_map(myCorpus1, stripWhitespace)
myCorpus2<- tm_map(myCorpus2, stripWhitespace)
# keep a copy for stem completion later
myCorpusCopy1 <- myCorpus1
myCorpusCopy2 <- myCorpus2
Frequent Words
Build Term Document Matrix
tdm1 <- TermDocumentMatrix(myCorpus1, control = list(wordLengths = c(1, Inf)))
tdm2 <- TermDocumentMatrix(myCorpus2, control = list(wordLengths = c(1, Inf)))
tdm1
tdm2
Top Frequent Terms
freq.terms1 <- findFreqTerms(tdm1, lowfreq = 10)
freq.terms2 <- findFreqTerms(tdm2, lowfreq = 10)
freq.terms1[1:75]
freq.terms2[1:75]
term.freq1 <- rowSums(as.matrix(tdm1))
term.freq1 <- subset(term.freq1, term.freq1 >= 10)
df1 <- data.frame(term = names(term.freq1), freq = term.freq1)
term.freq2 <- rowSums(as.matrix(tdm2))
term.freq2 <- subset(term.freq2, term.freq2 >= 10)
df2 <- data.frame(term = names(term.freq2), freq = term.freq2)
par(mfrow=c(1,2))
library(ggplot2)
ggplot(df1, aes(x=term, y=freq)) + geom_bar(stat="identity") +
xlab("Terms") + ylab("Count") + coord_flip() +
theme(axis.text=element_text(size=7))

ggplot(df2, aes(x=term, y=freq)) + geom_bar(stat="identity") +
xlab("Terms") + ylab("Count") + coord_flip() +
theme(axis.text=element_text(size=7))

Dari histogram di atas, maka dapat diketahui kata-kata apa saja yang sering diungkapkan bersamaan dengan kata yang ingin diketahui (ruangguru vs zenius)
Wordcloud
Build Wordcloud
library(wordcloud)
m1 <- as.matrix(tdm1)
m2 <- as.matrix(tdm2)
# calculate the frequency of words and sort it by frequency
word.freq1 <- sort(rowSums(m1), decreasing = T)
word.freq2 <- sort(rowSums(m2), decreasing = T)
# colors
pal <- brewer.pal(9, "BuGn")[-(1:4)]
wordcloud(words = names(word.freq1), freq = word.freq1, min.freq = 10,
random.order = F, colors = pal)

RUANGGURU >> dari wordcloud diatas dapat diketahui bahwa kata ruangguru sangat erat kaitannya dengan kata kode, diskon, aplikasi dan squad jika dilihat pada status Twitter 9 hari terakhir.
wordcloud(words = names(word.freq2), freq = word.freq1, min.freq = 10,
random.order = F, colors = pal)

ZENIUS >> dari wordcloud diatas dapat diketahui bahwa kata zenius sangat erat kaitannya dengan kata edc, educationfess dan belajar jika dilihat pada status Twitter 9 hari terakhir.
SUMMARY Walaupun pada awal deskripsi data menggunakan time series menunjukkan kedua media belajar online tersebut mengalami kenaikan nilai trends yang sangat signifikan dianatara tanggal 3 s.d 5 November 2018. Namun jika dilihat kata yang erat kaitannya (banyak dibahas di Twitter) dengan kedua media belajar online tersebut maka dapat dikatakan kata-kata pendukung dari kedua media belajar online tersebut adalah berbeda.
LS0tDQp0aXRsZTogIkVYRVJDSVNFIDItRURVQ0FUSU9OIg0KYXV0aG9yOiAiQWZpZmFoIE51ciBJc3dhcmkgKDA2MjExNTQwMDAwMTA5KSINCmRhdGU6ICIxMiBOb3ZlbWJlciAyMDE4Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiMjIEV4dHJhY3RpbmcgVHdlZXRzDQpEYXRhIHlhbmcgYWthbiBkaWd1bmFrYW4gZGFsYW0gbWVsYWt1a2FuIGFuYWxpc2lzIHRleHQgbWluaW5nIGFkYWxhaCBkZW5nYW4gbWVuZ2d1bmFrYW4gZGF0YSB5YW5nIGFkYSBwYWRhIFR3aXR0ZXIuIFNiZWx1bSBtZWxha3VrYW4gcGVuZ2FtYmlsYW4gZGF0YSBwYXN0aWthbiBzdWRhaCBtZW1pbGlraSBha3NlcyB0b2tlbiBkYW4ganVnYSBBUElzIHBhZGEgaHR0cHM6Ly9kZXZlbG9wZXIudHdpdHRlci5jb20NCg0KIyMjIFJldHJpZXZlIHR3ZWV0cyBmcm9tIFR3aXR0ZXINClBhc3Rpa2FuIHBhY2thZ2UgdW50dWsgbWVuZ2FtYmlsIGRhdGEgcGFkYSBUd2l0dGVyIHRlbGFoIHRlci1pbnN0YWxsIChydHdlZXQpIGRhbiBwYWNrYWdlIHlhbmcgYWthbiBtZW5kdWt1bmcgb3V0cHV0IHlhbmcgZGlpbmdpbmthbiAoZXg6dGlkeXZlcnNlKQ0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgTG9hZCBwYWNrYWdlcw0KbGlicmFyeShydHdlZXQpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KIyBBY2Nlc3MgdG9rZW4gYW5kIEFQSXMNCmNvbnN1bWVyX2tleSAgICA8LSAiRER6VzEwQ3hPVkMxU1Q4NzdzOFpiREpmcSINCmNvbnN1bWVyX3NlY3JldCA8LSAiQmIxNFRKM3llaFV5emEyeHg2THJMS2s5c2FNR3pseVVuVjFVU2d2UlNSdkc3YWZSbFQiDQphY2Nlc3NfdG9rZW4gICAgPC0gIjIwNjUyNjE3MS1Gdzl6T2N2Z2NSdHNlOW54czJOamVMZHNENWFadE5qQmlnMzBJbjBqIg0KYWNjZXNzX3NlY3JldCAgIDwtICJXeEMyT1hYN3B5NTZaeldJMVp3SUlLcGxKWklSRWlhMVh1WTVnQVFSb2hvaEoiDQpgYGANCk1lbWFzdWtrYW4ga2VlbXBhdCBuaWxhaSB0b2tlbiB5YW5nIHRlbGFoIGRpIHBlcm9sZWggZGFyaSBkZXZlbG9wZXIgdHdpdHRlcg0KYGBge3J9DQojIFR3aXR0ZXIgYXV0aGVudGljYXRpb24NCmNyZWF0ZV90b2tlbigNCiAgYXBwICAgICAgICAgICAgID0gIm15X3R3aXR0ZXJfcmVzZWFyY2hfYXBwIiwNCiAgY29uc3VtZXJfa2V5ICAgID0gY29uc3VtZXJfa2V5LA0KICBjb25zdW1lcl9zZWNyZXQgPSBjb25zdW1lcl9zZWNyZXQsDQogIGFjY2Vzc190b2tlbiAgICA9IGFjY2Vzc190b2tlbiwNCiAgYWNjZXNzX3NlY3JldCAgID0gYWNjZXNzX3NlY3JldCkNCmBgYA0KTWVuZ2VtYmFsaWthbiBzdGF0dXMgVHdpdHRlciB5YW5nIGNvY29rIGRlbmdhbiBwZXJtaW50YWFuIHBlbmNhcmlhbiB5YW5nIGRpc2VkaWFrYW4gcGVuZ2d1bmEuIEhhbnlhIGRhcGF0IG1lbmdhbWJpbCBkYXRhIGRhcmkgNi05IGhhcmkgc2ViZWx1bW55YS4gVW50dWsgbWVuZ2VtYmFsaWthbiBsZWJpaCBkYXJpIDE4LjAwMCBzdGF0dXMgZGFsYW0gc2F0dSBwYW5nZ2lsYW4sIGF0dXIgInJldHJ5b25yYXRlbGltaXQiIGtlIFRSVUUuDQoNClBhZGEga2FzdXMga2FsaSBpbmksIGluZ2luIG1lbmdldGFodWkgcGVyYmVkYWFuIGFudGFyYSBtZWRpYSBiZWxhamFyIG9ubGluZSAoZWR1Y2F0aW9uKSBydWFuZ2d1cnUgZGFuIGp1Z2EgemVuaXVzLg0KYGBge3Igd2FybmluZz1GQUxTRX0NCiMgUmV0cmlldmUgdHdlZXRzDQp0d2VldHMxIDwtIHNlYXJjaF90d2VldHMoInJ1YW5nZ3VydSIsIG4gPSAyMDAwMCwgdHdlZXRfbW9kZT0iZXh0ZW5kZWQiKQ0KdHdlZXRzMSA8LSBkaXN0aW5jdCh0d2VldHMxLCB0ZXh0LCAua2VlcF9hbGw9VFJVRSkNCnR3ZWV0czIgPC0gc2VhcmNoX3R3ZWV0cygiemVuaXVzIiwgbiA9IDIwMDAwLCB0d2VldF9tb2RlPSJleHRlbmRlZCIpDQp0d2VldHMyIDwtIGRpc3RpbmN0KHR3ZWV0czIsIHRleHQsIC5rZWVwX2FsbD1UUlVFKQ0KYGBgDQoNCg0KIyMjIFR3ZWV0cyBEZXNjcmlwdGlvbg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KIyMgcGxvdCB0aW1lIHNlcmllcyBvZiB0d2VldHMNCnBhcihtZnJvdz1jKDEsMikpDQp0c19wbG90KHR3ZWV0czEsICIyIGhvdXJzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZ2dwbG90Mjo6ZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpKSArDQogIGxhYnMoDQogICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgIHRpdGxlID0gIkZyZXF1ZW5jeSBvZiBSVUFOR0dVUlUgVHdpdHRlciBzdGF0dXNlcyBmcm9tIHBhc3QgOSBkYXlzIiwNCiAgICBzdWJ0aXRsZSA9ICJUd2l0dGVyIHN0YXR1cyAodHdlZXQpIGNvdW50cyBhZ2dyZWdhdGVkIHVzaW5nIHRocmVlLWhvdXIgaW50ZXJ2YWxzIiwNCiAgICBjYXB0aW9uID0gIlxuU291cmNlOiBEYXRhIGNvbGxlY3RlZCBmcm9tIFR3aXR0ZXIncyBSRVNUIEFQSSB2aWEgcnR3ZWV0Ig0KICApDQp0c19wbG90KHR3ZWV0czIsICIyIGhvdXJzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZ2dwbG90Mjo6ZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpKSArDQogIGxhYnMoDQogICAgeCA9IE5VTEwsIHkgPSBOVUxMLA0KICAgIHRpdGxlID0gIkZyZXF1ZW5jeSBvZiBaRU5JVVMgVHdpdHRlciBzdGF0dXNlcyBmcm9tIHBhc3QgOSBkYXlzIiwNCiAgICBzdWJ0aXRsZSA9ICJUd2l0dGVyIHN0YXR1cyAodHdlZXQpIGNvdW50cyBhZ2dyZWdhdGVkIHVzaW5nIHRocmVlLWhvdXIgaW50ZXJ2YWxzIiwNCiAgICBjYXB0aW9uID0gIlxuU291cmNlOiBEYXRhIGNvbGxlY3RlZCBmcm9tIFR3aXR0ZXIncyBSRVNUIEFQSSB2aWEgcnR3ZWV0Ig0KICApDQpgYGANCkRlbmdhbiBtZW5nZ3VuYWthbiBwbG90IHRpbWUgc2VyaWVzLCBtYWthIGRhcGF0IGRpa2V0YWh1aSB0cmVuZCBkYXJpIGthdGEgInJ1YW5nZ3VydSIgZGFuICJ6ZW5pdXMiIHBhZGEgOSBoYXJpIHRlcmFraGlyIGRlbmdhbiBpbnRlcnZhbCB3YWt0dSBzZWJlc2FyIDIgamFtLk1ha2EgZGFwYXQgZGlrZXRhaHVpIGtpcmEta2lyYSBwdWt1bCBiZXJhcGEgcGFyYSBwZW5nZ3VuYSBUd2l0dGVyIGFrYW4gbWVtYnVhdCBzdGF0dXMgZGVuZ2FuIG1lbmdndW5ha2FuIHVuc3VyIGtlZHVhIGthdGEgdGVyc2VidXQuIERhcmkga2VkdWEgdGltZXNlcmllcyBkYXBhdCBkaWtldGFodWkgYW50YXJhIHRhbmdnYWwgNCBkYW4gNSBOb3ZlbWJlciAyMDE4IGthdGEgcnVhbmdndXJ1IGRhbiBqdWdhIHplbml1cyBtZW1pbGlraSB0cmVuZCB5YW5nIHNpZ25pZmlrYW4gbWVuaW5na2F0LiANCg0KYGBge3J9DQp0YWlsKHR3ZWV0czEsIDEwKQ0KdGFpbCh0d2VldHMyLCAxMCkNCmBgYA0KDQojIyBUZXh0IENsZWFuaW5nDQpTZWJlbHVtIG1lbWJ1YXQgd29yZGNsb2QgZGFyaSBrYXRhIHlhbmcgZGlpbmdpbmthbiwgbWFrYSBwZXJsdSBtZWxha3VrYW4gcGVuZ2hhcHVzYW4ga2F0YS1rYXRhIGF0YXVwdW4gYXRyaWJ1dCB5YW5nIGRpcHJlZGlrc2lrYW4gYWthbiBzZXJpbmcgbXVuY3VsIG5hbXVuIHRpZGFrIG1lbWlsaWtpIG1ha25hIHlhbmcgYmVyYXJ0aSB0ZXJoYWRhcCBrYXRhIHlhbmcgZGlpbmdpbmthbi4gSmlrYSBoYWwgaW5pIHRpZGFrIGRpbGFrdWthbiwgbWFrYSBha2FuIG1lbWJlcmlrYW4gaGFzaWwgYW5hbGlzaXMgeWFuZyBrdXJhbmcgc2VzdWFpLg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0bSkNCmxpYnJhcnkoTkxQKQ0KYGBgDQojIyMgQnVpbGQgY29ycHVzDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KDQojIGJ1aWxkIGEgY29ycHVzLCBhbmQgc3BlY2lmeSB0aGUgc291cmNlIHRvIGJlIGNoYXJhY3RlciB2ZWN0b3JzIA0KbXlDb3JwdXMxIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UodHdlZXRzMSR0ZXh0KSkNCm15Q29ycHVzMiA8LSBDb3JwdXMoVmVjdG9yU291cmNlKHR3ZWV0czIkdGV4dCkpDQojIGNvbnZlcnQgdG8gbG93ZXIgY2FzZQ0KbXlDb3JwdXMxIDwtIHRtX21hcChteUNvcnB1czEsZnVuY3Rpb24oeCkgaWNvbnYoZW5jMnV0ZjgoeCksIHN1Yj0iYnl0ZSIpKQ0KbXlDb3JwdXMxIDwtIHRtX21hcChteUNvcnB1czEsIGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcikpDQpteUNvcnB1czIgPC0gdG1fbWFwKG15Q29ycHVzMixmdW5jdGlvbih4KSBpY29udihlbmMydXRmOCh4KSwgc3ViPSJieXRlIikpDQpteUNvcnB1czIgPC0gdG1fbWFwKG15Q29ycHVzMiwgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkNCiMgcmVtb3ZlIFVSTHMNCnJlbW92ZVVSTCA8LSBmdW5jdGlvbih4KSBnc3ViKCJodHRwW15bOnNwYWNlOl1dKiIsICIiLCB4KQ0KbXlDb3JwdXMxIDwtIHRtX21hcChteUNvcnB1czEsIGNvbnRlbnRfdHJhbnNmb3JtZXIocmVtb3ZlVVJMKSkNCm15Q29ycHVzMiA8LSB0bV9tYXAobXlDb3JwdXMyLCBjb250ZW50X3RyYW5zZm9ybWVyKHJlbW92ZVVSTCkpDQojIHJlbW92ZSBhbnl0aGluZyBvdGhlciB0aGFuIEVuZ2xpc2ggbGV0dGVycyBvciBzcGFjZSANCnJlbW92ZU51bVB1bmN0IDwtIGZ1bmN0aW9uKHgpIGdzdWIoIlteWzphbHBoYTpdWzpzcGFjZTpdXSoiLCAiIiwgeCkgDQpteUNvcnB1czEgPC0gdG1fbWFwKG15Q29ycHVzMSwgY29udGVudF90cmFuc2Zvcm1lcihyZW1vdmVOdW1QdW5jdCkpDQpteUNvcnB1czIgPC0gdG1fbWFwKG15Q29ycHVzMiwgY29udGVudF90cmFuc2Zvcm1lcihyZW1vdmVOdW1QdW5jdCkpDQojIHJlbW92ZSBzdG9wd29yZHMNCm15U3RvcHdvcmRzIDwtIGMoc2V0ZGlmZihzdG9wd29yZHMoJ2VuZ2xpc2gnKSwgYygiciIsICJiaWciKSksICJ1c2UiLCAic2VlIiwgInVzZWQiLCAidmlhIiwgImFtcCIsInJ1YW5nZ3VydSIsICJ6ZW5pdXMiLCLDoMOgw6DDoMOgIiwiw6DDoMOgw6AiLCLDoMOgw6AiLCLDoMOgIiwiw6AiLCLDsMO/IikNCnN0b3B3b3Jkc19pZCA8LSByZWFkLnRhYmxlKCdzdG9wd29yZHMtaWQudHh0JywgaGVhZGVyID0gRkFMU0UpDQpteVN0b3B3b3JkcyA8LSBjKG15U3RvcHdvcmRzLCBhcy5tYXRyaXgoc3RvcHdvcmRzX2lkJFYxKSwgImhpIiwgInlnIikNCm15Q29ycHVzMSA8LSB0bV9tYXAobXlDb3JwdXMxLCByZW1vdmVXb3JkcywgbXlTdG9wd29yZHMpDQpteUNvcnB1czIgPC0gdG1fbWFwKG15Q29ycHVzMiwgcmVtb3ZlV29yZHMsIG15U3RvcHdvcmRzKQ0KIyByZW1vdmUgZXh0cmEgd2hpdGVzcGFjZQ0KbXlDb3JwdXMxPC0gdG1fbWFwKG15Q29ycHVzMSwgc3RyaXBXaGl0ZXNwYWNlKQ0KbXlDb3JwdXMyPC0gdG1fbWFwKG15Q29ycHVzMiwgc3RyaXBXaGl0ZXNwYWNlKQ0KIyBrZWVwIGEgY29weSBmb3Igc3RlbSBjb21wbGV0aW9uIGxhdGVyDQpteUNvcnB1c0NvcHkxIDwtIG15Q29ycHVzMQ0KbXlDb3JwdXNDb3B5MiA8LSBteUNvcnB1czINCmBgYA0KIyMgRnJlcXVlbnQgV29yZHMNCg0KIyMjIEJ1aWxkIFRlcm0gRG9jdW1lbnQgTWF0cml4DQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0KdGRtMSA8LSBUZXJtRG9jdW1lbnRNYXRyaXgobXlDb3JwdXMxLCBjb250cm9sID0gbGlzdCh3b3JkTGVuZ3RocyA9IGMoMSwgSW5mKSkpDQp0ZG0yIDwtIFRlcm1Eb2N1bWVudE1hdHJpeChteUNvcnB1czIsIGNvbnRyb2wgPSBsaXN0KHdvcmRMZW5ndGhzID0gYygxLCBJbmYpKSkNCnRkbTENCnRkbTINCmBgYA0KDQojIyMgVG9wIEZyZXF1ZW50IFRlcm1zDQoNCmBgYHtyIHdhcm5pbmc9RkFMU0V9DQpmcmVxLnRlcm1zMSA8LSBmaW5kRnJlcVRlcm1zKHRkbTEsIGxvd2ZyZXEgPSAxMCkNCmZyZXEudGVybXMyIDwtIGZpbmRGcmVxVGVybXModGRtMiwgbG93ZnJlcSA9IDEwKQ0KYGBgDQoNCmBgYHtyfQ0KZnJlcS50ZXJtczFbMTo3NV0NCmZyZXEudGVybXMyWzE6NzVdDQpgYGANCg0KYGBge3J9DQp0ZXJtLmZyZXExIDwtIHJvd1N1bXMoYXMubWF0cml4KHRkbTEpKQ0KdGVybS5mcmVxMSA8LSBzdWJzZXQodGVybS5mcmVxMSwgdGVybS5mcmVxMSA+PSAxMCkNCmRmMSA8LSBkYXRhLmZyYW1lKHRlcm0gPSBuYW1lcyh0ZXJtLmZyZXExKSwgZnJlcSA9IHRlcm0uZnJlcTEpDQp0ZXJtLmZyZXEyIDwtIHJvd1N1bXMoYXMubWF0cml4KHRkbTIpKQ0KdGVybS5mcmVxMiA8LSBzdWJzZXQodGVybS5mcmVxMiwgdGVybS5mcmVxMiA+PSAxMCkNCmRmMiA8LSBkYXRhLmZyYW1lKHRlcm0gPSBuYW1lcyh0ZXJtLmZyZXEyKSwgZnJlcSA9IHRlcm0uZnJlcTIpDQpgYGANCg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRmMSwgYWVzKHg9dGVybSwgeT1mcmVxKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgeGxhYigiVGVybXMiKSArIHlsYWIoIkNvdW50IikgKyBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9NykpDQpnZ3Bsb3QoZGYyLCBhZXMoeD10ZXJtLCB5PWZyZXEpKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICB4bGFiKCJUZXJtcyIpICsgeWxhYigiQ291bnQiKSArIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT03KSkNCmBgYA0KRGFyaSBoaXN0b2dyYW0gZGkgYXRhcywgbWFrYSBkYXBhdCBkaWtldGFodWkga2F0YS1rYXRhIGFwYSBzYWphIHlhbmcgc2VyaW5nIGRpdW5na2Fwa2FuIGJlcnNhbWFhbiBkZW5nYW4ga2F0YSB5YW5nIGluZ2luIGRpa2V0YWh1aSAocnVhbmdndXJ1IHZzIHplbml1cykNCg0KIyMgV29yZGNsb3VkDQoNCiMjIyBCdWlsZCBXb3JkY2xvdWQNCmBgYHtyfQ0KbGlicmFyeSh3b3JkY2xvdWQpDQpgYGANCg0KYGBge3J9DQptMSA8LSBhcy5tYXRyaXgodGRtMSkNCm0yIDwtIGFzLm1hdHJpeCh0ZG0yKQ0KIyBjYWxjdWxhdGUgdGhlIGZyZXF1ZW5jeSBvZiB3b3JkcyBhbmQgc29ydCBpdCBieSBmcmVxdWVuY3kgDQp3b3JkLmZyZXExIDwtIHNvcnQocm93U3VtcyhtMSksIGRlY3JlYXNpbmcgPSBUKQ0Kd29yZC5mcmVxMiA8LSBzb3J0KHJvd1N1bXMobTIpLCBkZWNyZWFzaW5nID0gVCkNCiMgY29sb3JzDQpwYWwgPC0gYnJld2VyLnBhbCg5LCAiQnVHbiIpWy0oMTo0KV0NCmBgYA0KDQoNCg0KYGBge3J9DQp3b3JkY2xvdWQod29yZHMgPSBuYW1lcyh3b3JkLmZyZXExKSwgZnJlcSA9IHdvcmQuZnJlcTEsIG1pbi5mcmVxID0gMTAsDQogICAgcmFuZG9tLm9yZGVyID0gRiwgY29sb3JzID0gcGFsKQ0KYGBgDQpSVUFOR0dVUlUgPj4gZGFyaSB3b3JkY2xvdWQgZGlhdGFzIGRhcGF0IGRpa2V0YWh1aSBiYWh3YSBrYXRhIHJ1YW5nZ3VydSBzYW5nYXQgZXJhdCBrYWl0YW5ueWEgZGVuZ2FuIGthdGEga29kZSwgZGlza29uLCBhcGxpa2FzaSBkYW4gc3F1YWQgamlrYSBkaWxpaGF0IHBhZGEgc3RhdHVzIFR3aXR0ZXIgOSBoYXJpIHRlcmFraGlyLiANCg0KYGBge3J9DQp3b3JkY2xvdWQod29yZHMgPSBuYW1lcyh3b3JkLmZyZXEyKSwgZnJlcSA9IHdvcmQuZnJlcTEsIG1pbi5mcmVxID0gMTAsDQogICAgcmFuZG9tLm9yZGVyID0gRiwgY29sb3JzID0gcGFsKQ0KYGBgDQpaRU5JVVMgPj4gZGFyaSB3b3JkY2xvdWQgZGlhdGFzIGRhcGF0IGRpa2V0YWh1aSBiYWh3YSBrYXRhIHplbml1cyBzYW5nYXQgZXJhdCBrYWl0YW5ueWEgZGVuZ2FuIGthdGEgZWRjLCBlZHVjYXRpb25mZXNzIGRhbiBiZWxhamFyIGppa2EgZGlsaWhhdCBwYWRhIHN0YXR1cyBUd2l0dGVyIDkgaGFyaSB0ZXJha2hpci4gDQoNCg0KU1VNTUFSWQ0KV2FsYXVwdW4gcGFkYSBhd2FsIGRlc2tyaXBzaSBkYXRhIG1lbmdndW5ha2FuIHRpbWUgc2VyaWVzIG1lbnVuanVra2FuIGtlZHVhIG1lZGlhIGJlbGFqYXIgb25saW5lIHRlcnNlYnV0IG1lbmdhbGFtaSBrZW5haWthbiBuaWxhaSB0cmVuZHMgeWFuZyBzYW5nYXQgc2lnbmlmaWthbiBkaWFuYXRhcmEgdGFuZ2dhbCAzIHMuZCA1IE5vdmVtYmVyIDIwMTguIE5hbXVuIGppa2EgZGlsaWhhdCBrYXRhIHlhbmcgZXJhdCBrYWl0YW5ueWEgKGJhbnlhayBkaWJhaGFzIGRpIFR3aXR0ZXIpIGRlbmdhbiBrZWR1YSBtZWRpYSBiZWxhamFyIG9ubGluZSB0ZXJzZWJ1dCBtYWthIGRhcGF0IGRpa2F0YWthbiBrYXRhLWthdGEgcGVuZHVrdW5nIGRhcmkga2VkdWEgbWVkaWEgYmVsYWphciBvbmxpbmUgdGVyc2VidXQgYWRhbGFoIGJlcmJlZGEuDQo=