Student ID: 1A182901-2


  1. Set up environment
rm(list=ls(all=TRUE))
setwd("~/Desktop/R/polimetrics")
library(quanteda)
library(readtext)
library(stm)
library(ggplot2)
library(wordcloud)
library(cowplot)
  1. Import Data
myText <- readtext("~/Desktop/r/polimetrics/UK/*.txt",
                   docvarsfrom = "filenames", dvsep = " ", docvarnames = c("Party", "Year"))
mycorpus <- corpus(myText, docid_field = "doc_id")
docnames(mycorpus) <- gsub(".txt", "", docnames(mycorpus ))
myDfm <- dfm(mycorpus , remove = stopwords("english"), tolower = TRUE, stem = TRUE,
             remove_punct = TRUE, remove_numbers=TRUE)
  1. Wordfish
reswf <- textmodel_wordfish(myDfm, dir = c(3, 1))
df_wf <- data.frame(v_wf = reswf$theta,
                    title = reswf$docs,
                    year = docvars(myDfm)$Year)
##Graph
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
gr_wf <- ggplot(df_wf,aes(y=reorder(title,v_wf),x=v_wf))
gr_wf_res <- gr_wf +
  geom_point() + 
  ggtitle("Wordfish Result") +
  ylab("") + 
  xlab("") + 
  theme_light() + 
  theme(legend.position="none",plot.title = element_text(hjust = 0.5))
gr_wf_res

  1. STM with wf score
mycorpus2 <- mycorpus
mycorpus2$documents$wf <- df_wf$v_wf
myDfm2 <- dfm(mycorpus2 , remove = stopwords("english"), tolower = TRUE, stem = TRUE,
             remove_punct = TRUE, remove_numbers=TRUE)
#STM
Dfm_stm <- convert(myDfm2, to = "stm", docvars = docvars(mycorpus2))
Dfm_stm$meta$Year <- as.character(Dfm_stm$meta$Year)
stmFitted1 <- stm(Dfm_stm$documents,
                 Dfm_stm$vocab,
                 K = 6,
                 max.em.its = 50,
                 prevalence = ~ wf + Year,
                 data = Dfm_stm$meta,
                 init.type = "Spectral")
prep <- estimateEffect(1:6 ~ wf + Year, 
                       stmFitted1, 
                       meta = Dfm_stm$meta, 
                       uncertainty = "Global")

4.1. Justify “K=6”

K <-c(5,6,7)
storage  <- searchK(Dfm_stm$documents,
                    Dfm_stm$vocab,
                    K,
                    max.em.its = 75,
                    N = floor(0.2 * length(Dfm_stm$documents)),
                    prevalence = ~ Year + wf,
                    data = Dfm_stm$meta,
                    init.type = "Spectral")
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(storage$results$semcoh,
     storage$results$exclus,
     xlab= "Semantic coherence",
     ylab= "Exclusivity",
     col= "blue",
     pch = 19,
     cex = 1,
     lty = "solid",
     lwd = 2)
text(storage$results$semcoh,
     storage$results$exclus,
     labels=storage$results$K,
     cex= 1,
     pos=2)

4.2. Top Topics

par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted1, type = "summary", labeltype = c("frex"))

par(mfrow=c(1,1),mar=c(0, 1, 0, 1))
plot(stmFitted1, type = "labels", labeltype = c("frex"))

par(mfrow=c(2,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(prep, "wf", method = "continuous", topics = 4,
     model = stmFitted1, printlegend = FALSE, xaxt = "n", xlab = "wf")
seq <- seq(from = as.numeric("-2"), to = as.numeric("2"))
axis(1, at = seq)
title("Topic 4")
abline(h=0, col="blue")
plot(prep, "wf", method = "continuous", topics = 6,
     model = stmFitted1, printlegend = FALSE, xaxt = "n", xlab = "wf")
seq <- seq(from = as.numeric("-2"), to = as.numeric("2"))
axis(1, at = seq)
title("Topic 6")
abline(h=0, col="blue")

4.3. 92 versus 97

par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(prep,
     covariate = "Year", 
     topics = c(1, 2, 3, 4, 5,6),
     model = stmFitted1, method = "difference",
     cov.value1 = "97", 
     cov.value2 = "92",
     xlim = c(-1, 1),
     xlab = "More 1992     ...    More 1997",
     main = "Effect of 92 vs. 97",
     labeltype = "custom",
     custom.labels = c('Topic 1','Topic2', 'Topic 3','Topic 4', 'Topic 5','Topic 6'))

  1. STM with only Year
Dfm_stm2 <- convert(myDfm, to = "stm", docvars = docvars(mycorpus))
Dfm_stm2$meta$Year <- as.character(Dfm_stm2$meta$Year)
stmFitted2 <- stm(Dfm_stm2$documents,
                  Dfm_stm2$vocab,
                  K = 6,
                  max.em.its = 50,
                  prevalence = ~ Year,
                  data = Dfm_stm2$meta,
                  init.type = "Spectral")
prep2 <- estimateEffect(1:6 ~ Year, 
                       stmFitted2, 
                       meta = Dfm_stm2$meta, 
                       uncertainty = "Global")
stmFitted2_content <- stm(Dfm_stm2$documents,
                         Dfm_stm2$vocab,
                         K = 6, 
                         max.em.its = 75, 
                         prevalence = ~ Year, 
                         content = ~ Year,  
                         data = Dfm_stm2$meta, 
                         init.type = "Spectral")

5.1. Check K

K <-c(5,6,7)
storage2  <- searchK(Dfm_stm2$documents,
                    Dfm_stm2$vocab,
                    K,
                    max.em.its = 75,
                    N = floor(0.2 * length(Dfm_stm2$documents)),
                    prevalence = ~ Year,
                    data = Dfm_stm2$meta,
                    init.type = "Spectral")
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(storage2$results$semcoh,
     storage2$results$exclus,
     xlab= "Semantic coherence",
     ylab= "Exclusivity",
     col= "blue",
     pch = 19,
     cex = 1,
     lty = "solid",
     lwd = 2)
text(storage2$results$semcoh,
     storage2$results$exclus,
     labels=storage2$results$K,
     cex= 1,
     pos=2)

5.2. Result

par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted2, type = "summary", labeltype = c("frex"))

par(mfrow=c(2,1),mar=c(1,1,1,1))
plot(stmFitted2_content, type = "perspectives", topics = 4,main = "Topic4")
plot(stmFitted2_content, type = "perspectives", topics = 6,main = "Topic6")

par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted2, type = "perspectives", labeltype = c("frex"), topics = c(4, 6))


LS0tCnRpdGxlOiAiSG9tZSBBc3NpZ25tZW50IDQiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFllbiBDaGVuZyBIc3VhbgotLS0KIyMjI1N0dWRlbnQgSUQ6IDFBMTgyOTAxLTIKKioqCgo+MS4gU2V0IHVwIGVudmlyb25tZW50CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kcm0obGlzdD1scyhhbGw9VFJVRSkpCnNldHdkKCJ+L0Rlc2t0b3AvUi9wb2xpbWV0cmljcyIpCmxpYnJhcnkocXVhbnRlZGEpCmxpYnJhcnkocmVhZHRleHQpCmxpYnJhcnkoc3RtKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkod29yZGNsb3VkKQpsaWJyYXJ5KGNvd3Bsb3QpCmBgYAoKPjIuIEltcG9ydCBEYXRhCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbXlUZXh0IDwtIHJlYWR0ZXh0KCJ+L0Rlc2t0b3Avci9wb2xpbWV0cmljcy9VSy8qLnR4dCIsCiAgICAgICAgICAgICAgICAgICBkb2N2YXJzZnJvbSA9ICJmaWxlbmFtZXMiLCBkdnNlcCA9ICIgIiwgZG9jdmFybmFtZXMgPSBjKCJQYXJ0eSIsICJZZWFyIikpCgpteWNvcnB1cyA8LSBjb3JwdXMobXlUZXh0LCBkb2NpZF9maWVsZCA9ICJkb2NfaWQiKQpkb2NuYW1lcyhteWNvcnB1cykgPC0gZ3N1YigiLnR4dCIsICIiLCBkb2NuYW1lcyhteWNvcnB1cyApKQoKbXlEZm0gPC0gZGZtKG15Y29ycHVzICwgcmVtb3ZlID0gc3RvcHdvcmRzKCJlbmdsaXNoIiksIHRvbG93ZXIgPSBUUlVFLCBzdGVtID0gVFJVRSwKICAgICAgICAgICAgIHJlbW92ZV9wdW5jdCA9IFRSVUUsIHJlbW92ZV9udW1iZXJzPVRSVUUpCgpgYGAKCj4zLiBXb3JkZmlzaAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnJlc3dmIDwtIHRleHRtb2RlbF93b3JkZmlzaChteURmbSwgZGlyID0gYygzLCAxKSkKZGZfd2YgPC0gZGF0YS5mcmFtZSh2X3dmID0gcmVzd2YkdGhldGEsCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSByZXN3ZiRkb2NzLAogICAgICAgICAgICAgICAgICAgIHllYXIgPSBkb2N2YXJzKG15RGZtKSRZZWFyKQoKIyNHcmFwaApwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCmdyX3dmIDwtIGdncGxvdChkZl93ZixhZXMoeT1yZW9yZGVyKHRpdGxlLHZfd2YpLHg9dl93ZikpCmdyX3dmX3JlcyA8LSBncl93ZiArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2d0aXRsZSgiV29yZGZpc2ggUmVzdWx0IikgKwogIHlsYWIoIiIpICsgCiAgeGxhYigiIikgKyAKICB0aGVtZV9saWdodCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIixwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKZ3Jfd2ZfcmVzCmBgYAoKPjQuIFNUTSB3aXRoIHdmIHNjb3JlCgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KbXljb3JwdXMyIDwtIG15Y29ycHVzCm15Y29ycHVzMiRkb2N1bWVudHMkd2YgPC0gZGZfd2Ykdl93ZgpteURmbTIgPC0gZGZtKG15Y29ycHVzMiAsIHJlbW92ZSA9IHN0b3B3b3JkcygiZW5nbGlzaCIpLCB0b2xvd2VyID0gVFJVRSwgc3RlbSA9IFRSVUUsCiAgICAgICAgICAgICByZW1vdmVfcHVuY3QgPSBUUlVFLCByZW1vdmVfbnVtYmVycz1UUlVFKQojU1RNCkRmbV9zdG0gPC0gY29udmVydChteURmbTIsIHRvID0gInN0bSIsIGRvY3ZhcnMgPSBkb2N2YXJzKG15Y29ycHVzMikpCkRmbV9zdG0kbWV0YSRZZWFyIDwtIGFzLmNoYXJhY3RlcihEZm1fc3RtJG1ldGEkWWVhcikKc3RtRml0dGVkMSA8LSBzdG0oRGZtX3N0bSRkb2N1bWVudHMsCiAgICAgICAgICAgICAgICAgRGZtX3N0bSR2b2NhYiwKICAgICAgICAgICAgICAgICBLID0gNiwKICAgICAgICAgICAgICAgICBtYXguZW0uaXRzID0gNTAsCiAgICAgICAgICAgICAgICAgcHJldmFsZW5jZSA9IH4gd2YgKyBZZWFyLAogICAgICAgICAgICAgICAgIGRhdGEgPSBEZm1fc3RtJG1ldGEsCiAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKcHJlcCA8LSBlc3RpbWF0ZUVmZmVjdCgxOjYgfiB3ZiArIFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgIHN0bUZpdHRlZDEsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBEZm1fc3RtJG1ldGEsIAogICAgICAgICAgICAgICAgICAgICAgIHVuY2VydGFpbnR5ID0gIkdsb2JhbCIpCgpgYGAKCj40LjEuIEp1c3RpZnkgIks9NiIKCmBgYHtyIHJlc3VsdHM9ImhpZGUifQpLIDwtYyg1LDYsNykKc3RvcmFnZSAgPC0gc2VhcmNoSyhEZm1fc3RtJGRvY3VtZW50cywKICAgICAgICAgICAgICAgICAgICBEZm1fc3RtJHZvY2FiLAogICAgICAgICAgICAgICAgICAgIEssCiAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LAogICAgICAgICAgICAgICAgICAgIE4gPSBmbG9vcigwLjIgKiBsZW5ndGgoRGZtX3N0bSRkb2N1bWVudHMpKSwKICAgICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBZZWFyICsgd2YsCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IERmbV9zdG0kbWV0YSwKICAgICAgICAgICAgICAgICAgICBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCnBsb3Qoc3RvcmFnZSRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAogICAgIHhsYWI9ICJTZW1hbnRpYyBjb2hlcmVuY2UiLAogICAgIHlsYWI9ICJFeGNsdXNpdml0eSIsCiAgICAgY29sPSAiYmx1ZSIsCiAgICAgcGNoID0gMTksCiAgICAgY2V4ID0gMSwKICAgICBsdHkgPSAic29saWQiLAogICAgIGx3ZCA9IDIpCnRleHQoc3RvcmFnZSRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAogICAgIGxhYmVscz1zdG9yYWdlJHJlc3VsdHMkSywKICAgICBjZXg9IDEsCiAgICAgcG9zPTIpCmBgYAoKKiBBcyB0aGUgcGxvdCBvZiBzZW1hbnRpYyBjb2hlcmVuY2UgYW5kIGV4Y2x1c2l2aXR5LCBLIGVxdWFsIHRvIDYgd2FzIHRoZSBzdWdnZXN0ZWQgc2V0dXAuCgo+NC4yLiBUb3AgVG9waWNzCgpgYGB7cn0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHN0bUZpdHRlZDEsIHR5cGUgPSAic3VtbWFyeSIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSkKYGBgCmBgYHtyfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDAsIDEsIDAsIDEpKQpwbG90KHN0bUZpdHRlZDEsIHR5cGUgPSAibGFiZWxzIiwgbGFiZWx0eXBlID0gYygiZnJleCIpKQpgYGAKCiogQXMgdGhlIEZSRVggcmVzdWx0IG9mIHRob3NlIHNpeCB0b3BpY3MsIHNvbWUgb2YgdGhlIHRvcGljcyBjb3VsZCBiZSByZXByZXNlbnRlZCBhcyBzcGVjaWZpYyBpc3N1ZXMuCiAgICAxLiBUb3BpYyA0IG1pZ2h0IGJlIHRoZSBsaWJlcmFsIGRlbW9jcmF0aWMgdG9waWMuCiAgICAyLiBUb3BpYyA1IG1pZ2h0IGJlIHRoZSBsYWJvciB0b3BpYy4KICAgIDMuIFRvcGljIDYgbWlnaHQgYmUgdGhlIGNvbnNlcnZhdGl2ZSB0b3BpYy4KCiogSSBjaG9zZSB0byBwbG90IHRvcGljIDQgYW5kIHRvcGljIDYgYWNyb3NzIHdvcmRmaXNoIHNjb3JlIGFzIHRoZSBmb2xsb3dpbmcuCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwYXIobWZyb3c9YygyLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCgpwbG90KHByZXAsICJ3ZiIsIG1ldGhvZCA9ICJjb250aW51b3VzIiwgdG9waWNzID0gNCwKICAgICBtb2RlbCA9IHN0bUZpdHRlZDEsIHByaW50bGVnZW5kID0gRkFMU0UsIHhheHQgPSAibiIsIHhsYWIgPSAid2YiKQpzZXEgPC0gc2VxKGZyb20gPSBhcy5udW1lcmljKCItMiIpLCB0byA9IGFzLm51bWVyaWMoIjIiKSkKYXhpcygxLCBhdCA9IHNlcSkKdGl0bGUoIlRvcGljIDQiKQphYmxpbmUoaD0wLCBjb2w9ImJsdWUiKQoKcGxvdChwcmVwLCAid2YiLCBtZXRob2QgPSAiY29udGludW91cyIsIHRvcGljcyA9IDYsCiAgICAgbW9kZWwgPSBzdG1GaXR0ZWQxLCBwcmludGxlZ2VuZCA9IEZBTFNFLCB4YXh0ID0gIm4iLCB4bGFiID0gIndmIikKc2VxIDwtIHNlcShmcm9tID0gYXMubnVtZXJpYygiLTIiKSwgdG8gPSBhcy5udW1lcmljKCIyIikpCmF4aXMoMSwgYXQgPSBzZXEpCnRpdGxlKCJUb3BpYyA2IikKYWJsaW5lKGg9MCwgY29sPSJibHVlIikKYGBgCgoqIEFzIHRoZSB3b3JkZmlzaCBwb3NpdGlvbiBMSUJERU0gLSBMQUIgLSBDT05TLCB0aGUgcmVzdWx0IHNob3dlZCBjb250cmFkaWN0b3J5IHBhdHRlcm5zIGJldHdlZW4gdG9waWMgNCBhbmQgdG9waWMgNi4KICAgICsgTElCREVNIHJlcHJlc2VudGVkIG1vcmUgdG9waWMgNCwgd2hpY2ggaW5jbHVkaW5nIHRoZSB0ZXJtcyBvZiBsaWJlcmFsIGRlbW9jcmFjeSwgYW5kIHRoZSBwcm9wb3Npb24gZGVjcmVhc2VkIGdyYWR1YWxseSBhcyB3b3JkZmlzaCBzY29yZSBpbmNyZWFzZWQuCiAgICArIE9uIHRoZSBvdGhlciBoYW5kLCB0aGUgQ09OUyBpbiAxOTkyIGFuZCAxOTk3IHRhbGtlZCBtb3JlIHByb3BvdGlvbiBvZiB0b3BpYyA2LgoKPjQuMy4gOTIgdmVyc3VzIDk3CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHByZXAsCiAgICAgY292YXJpYXRlID0gIlllYXIiLCAKICAgICB0b3BpY3MgPSBjKDEsIDIsIDMsIDQsIDUsNiksCiAgICAgbW9kZWwgPSBzdG1GaXR0ZWQxLCBtZXRob2QgPSAiZGlmZmVyZW5jZSIsCiAgICAgY292LnZhbHVlMSA9ICI5NyIsIAogICAgIGNvdi52YWx1ZTIgPSAiOTIiLAogICAgIHhsaW0gPSBjKC0xLCAxKSwKICAgICB4bGFiID0gIk1vcmUgMTk5MiAgICAgLi4uICAgIE1vcmUgMTk5NyIsCiAgICAgbWFpbiA9ICJFZmZlY3Qgb2YgOTIgdnMuIDk3IiwKICAgICBsYWJlbHR5cGUgPSAiY3VzdG9tIiwKICAgICBjdXN0b20ubGFiZWxzID0gYygnVG9waWMgMScsJ1RvcGljMicsICdUb3BpYyAzJywnVG9waWMgNCcsICdUb3BpYyA1JywnVG9waWMgNicpKQpgYGAKKiBEZXNwaXRlIHNvbWUgZGlmZmVyZW5jZSBvZiBwb3NpdGlvbnMsIGFsbCA2IHRvcGljcyB3ZXJlIG5vdCBzaWduaWZpY2FudGx5IHByZXNlbnRlZCBvbmx5IGluIDE5OTIgb3IgMTk5Ny4KCj41LiBTVE0gd2l0aCBvbmx5IFllYXIKCmBgYHtyIGVjaG89VCwgcmVzdWx0cz0iaGlkZSJ9CkRmbV9zdG0yIDwtIGNvbnZlcnQobXlEZm0sIHRvID0gInN0bSIsIGRvY3ZhcnMgPSBkb2N2YXJzKG15Y29ycHVzKSkKRGZtX3N0bTIkbWV0YSRZZWFyIDwtIGFzLmNoYXJhY3RlcihEZm1fc3RtMiRtZXRhJFllYXIpCgpzdG1GaXR0ZWQyIDwtIHN0bShEZm1fc3RtMiRkb2N1bWVudHMsCiAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICBLID0gNiwKICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDUwLAogICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBZZWFyLAogICAgICAgICAgICAgICAgICBkYXRhID0gRGZtX3N0bTIkbWV0YSwKICAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKCnByZXAyIDwtIGVzdGltYXRlRWZmZWN0KDE6NiB+IFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgIHN0bUZpdHRlZDIsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBEZm1fc3RtMiRtZXRhLCAKICAgICAgICAgICAgICAgICAgICAgICB1bmNlcnRhaW50eSA9ICJHbG9iYWwiKQpzdG1GaXR0ZWQyX2NvbnRlbnQgPC0gc3RtKERmbV9zdG0yJGRvY3VtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICAgICAgICAgSyA9IDYsIAogICAgICAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LCAKICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZhbGVuY2UgPSB+IFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IH4gWWVhciwgIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IERmbV9zdG0yJG1ldGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKYGBgCgo+NS4xLiBDaGVjayBLCgpgYGB7ciBlY2hvPVQsIHJlc3VsdHM9ImhpZGUifQpLIDwtYyg1LDYsNykKc3RvcmFnZTIgIDwtIHNlYXJjaEsoRGZtX3N0bTIkZG9jdW1lbnRzLAogICAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICAgIEssCiAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LAogICAgICAgICAgICAgICAgICAgIE4gPSBmbG9vcigwLjIgKiBsZW5ndGgoRGZtX3N0bTIkZG9jdW1lbnRzKSksCiAgICAgICAgICAgICAgICAgICAgcHJldmFsZW5jZSA9IH4gWWVhciwKICAgICAgICAgICAgICAgICAgICBkYXRhID0gRGZtX3N0bTIkbWV0YSwKICAgICAgICAgICAgICAgICAgICBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQpgYGAKCmBgYHtyfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCnBsb3Qoc3RvcmFnZTIkcmVzdWx0cyRzZW1jb2gsCiAgICAgc3RvcmFnZTIkcmVzdWx0cyRleGNsdXMsCiAgICAgeGxhYj0gIlNlbWFudGljIGNvaGVyZW5jZSIsCiAgICAgeWxhYj0gIkV4Y2x1c2l2aXR5IiwKICAgICBjb2w9ICJibHVlIiwKICAgICBwY2ggPSAxOSwKICAgICBjZXggPSAxLAogICAgIGx0eSA9ICJzb2xpZCIsCiAgICAgbHdkID0gMikKdGV4dChzdG9yYWdlMiRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlMiRyZXN1bHRzJGV4Y2x1cywKICAgICBsYWJlbHM9c3RvcmFnZTIkcmVzdWx0cyRLLAogICAgIGNleD0gMSwKICAgICBwb3M9MikKYGBgCgoqIEFzIHRoZSBncmFwaCBhYm92ZSwgSyBlcXVhbCB0byA2IHdhcyBzdGlsbCB0aGUgc3VnZ2VzdGVkIHNldHVwLgoKPjUuMi4gUmVzdWx0CgpgYGB7cn0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHN0bUZpdHRlZDIsIHR5cGUgPSAic3VtbWFyeSIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSkKYGBgCmBgYHtyfQpwYXIobWZyb3c9YygyLDEpLG1hcj1jKDEsMSwxLDEpKQpwbG90KHN0bUZpdHRlZDJfY29udGVudCwgdHlwZSA9ICJwZXJzcGVjdGl2ZXMiLCB0b3BpY3MgPSA0LG1haW4gPSAiVG9waWM0IikKcGxvdChzdG1GaXR0ZWQyX2NvbnRlbnQsIHR5cGUgPSAicGVyc3BlY3RpdmVzIiwgdG9waWNzID0gNixtYWluID0gIlRvcGljNiIpCmBgYAoqIFRoZSBjb21wYXJpc29uIGJldHdlZW4gMTk5MiBhbmQgMTk5NyBpbiB0b3BpYyA0IGFuZCA2IHNob3dlZCB0aGUgZm9sbG93aW5nIHBhdHRlcm5zLgogICAgMS4gVGhlIHJlcHJlc2VudGF0aXZlIHdvcmRzIHdlcmUgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgZGlzY3Vzc2lvbiBpbmNsdWRpbmcgd29yZGZpc2ggc2NvcmUuIAogICAgMi4gVGhlIHdvcmQgInNjaG9vbCIgd2FzIHVzZWQgbW9yZSBvZnRlbiBpbiAxOTk3LCBpbiBib3RoIHRvcGljIDQgYW5kIHRvcGljIDYuCiAgICAzLiBNb3N0IG9mIHRoZSByZXByZXNlbnRhdGl2ZSB3b3JkcyBhcHBlYXJlZCBpbiBib3RoIDE5OTIgYW5kIDE5OTcgbWFuaWZlc3RvLgoKYGBge3J9CnBhcihtZnJvdz1jKDEsMSksbWFyPWMoNS4xLCA0LjEsIDQuMSwgMi4xKSkKcGxvdChzdG1GaXR0ZWQyLCB0eXBlID0gInBlcnNwZWN0aXZlcyIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSwgdG9waWNzID0gYyg0LCA2KSkKYGBgCgoqIENvbXBhcmluZyBUb3BpYyA0IGFuZCBUb3BpYyA2LCB0aGUgcGF0dGVybiBvZiBUb3BpYyA0IGFzIGEgZGVtb2NyYXRpYyB0b3BpYyB3YXMgbW9yZSBzaWduaWZpY2FudC4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSB0b3BpYyA2IGRpZCBub3Qgc2hvdyBjbGVhciBpc3N1ZS4KCgoqKioKCgoK