Assignment: Select another news organization and grab 5000 of their tweets. Some possibilities: For Billings Gazette headlines: billingsgazette Wall Street Journal: wsj Washington Post: washingtonpost CNN: cnn CNN breaking news: cnnbrk USA Today: usatoday

  1. Unnest the words of the tweets, remove stop words and weird web “words”, and create a table and a word cloud of the top words.
  2. Conduct a sentiment analysis using bing, remove any errors like trump = positive, and create a graph of the words that contribute most to each sentiment.
  3. Do the same as above but with the nrc sentiment lexicon.
  4. Unnest the tweets as bigrams, remove stop words and errors, and create a table and word cloud of the most common bigrams.
  5. Using the bigrams, look for the most common words that follow two different words. You may choose trump and pelosi, or choose your own.
news_tweets <- get_timeline("billingsgazette", n = 5000)
news_words <- news_tweets %>% 
  unnest_tokens(word, text) %>% 
  select(screen_name, word)
news_words %>%
  count(word, sort = T)
news_words %>% 
  anti_join(get_stopwords()) %>% 
  count(word, sort = T)
Joining, by = "word"
news_words %>% 
  anti_join(get_stopwords()) %>% 
  filter(!word == "https",
         !word == "t.co") %>%
  count(word, sort = T)
Joining, by = "word"
news_words %>% 
  anti_join(get_stopwords()) %>% 
  filter(!word == "https",
         !word == "t.co") %>%
  count(word, sort = T) %>%
  top_n(200) %>%
  wordcloud2(size = .5)
Joining, by = "word"
Selecting by n
bing <- get_sentiments("bing")
bing
news_words %>% 
  inner_join(bing) %>% 
  count(word, sentiment, sort = TRUE)
Joining, by = "word"
news_words %>% 
  inner_join(bing) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE) 
Joining, by = "word"
news_words %>% 
  inner_join(bing) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE)%>%
  group_by(sentiment) %>%
  top_n(10) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(vars(sentiment), scales = "free") +
  labs(y = "News headlines: Words that contribute the most to each sentiment",
       x = NULL) +
  coord_flip() +
  theme_minimal()
Joining, by = "word"
Selecting by n

nrc <- get_sentiments("nrc")
nrc
nrc %>%
  distinct(sentiment)
news_words %>% 
  inner_join(nrc) %>% 
  filter(!word == "trump") %>%
  count(word, sentiment, sort = TRUE)%>%
  group_by(sentiment) %>%
  top_n(5) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(vars(sentiment), scales = "free") +
  labs(y = "News headlines: Words that contribute the most to each sentiment",
       x = NULL) +
  coord_flip() +
  theme_minimal()
Joining, by = "word"
Selecting by n

news_tweets %>%
  select(text) %>%                                                 # this selects just the text of the tweets
  unnest_tokens(words, text, token = "ngrams", n = 2)
NA
news_tweets %>%
  select(text) %>%                                                 #
  unnest_tokens(words, text, token = "ngrams", n = 2) %>%
  count(words, sort = T)
news_tweets %>%
  select(text) %>%                                                 # this selects just the text of the tweets
  unnest_tokens(words, text, token = "ngrams", n = 2) %>% 
  separate(words, c("word1", "word2"), sep = " ") %>%          # separate them temporarily
  filter(!word1 %in% stop_words$word) %>%                      # remove if first word is a stop word
  filter(!word2 %in% stop_words$word) %>%                      # remove if second word is a stop word   
  unite(words, word1, word2, sep = " ")                        # put them back together
remove_words = c("https", "t.co")

news_tweets %>%
  select(text) %>%                                                 
  unnest_tokens(words, text, token = "ngrams", n = 2) %>% 
  separate(words, c("word1", "word2"), sep = " ") %>%          # separate them temporarily
  filter(!word1 %in% stop_words$word) %>%                      # remove if first word is a stop word
  filter(!word2 %in% stop_words$word) %>%                      # remove if second word is a stop word   
  filter(!word1 %in% remove_words) %>%                         # these two lines remove our remove_words
  filter(!word2 %in% remove_words) %>%                         
  unite(words, word1, word2, sep = " ")                        # put them back together
remove_words = c("https", "t.co")

news_tweets %>%
  select(text) %>%                                                 
  unnest_tokens(words, text, token = "ngrams", n = 2) %>% 
  separate(words, c("word1", "word2"), sep = " ") %>%          # separate them temporarily
  filter(!word1 %in% stop_words$word) %>%                      # remove if first word is a stop word
  filter(!word2 %in% stop_words$word) %>%                      # remove if second word is a stop word   
  filter(!word1 %in% remove_words) %>%                         # these two lines remove our remove_words
  filter(!word2 %in% remove_words) %>%                         
  unite(words, word1, word2, sep = " ") -> news_bigrams                       # put them back together
news_bigrams %>% 
  count(words, sort = T)
news_bigrams %>% 
  count(words, sort = T) %>%
  top_n(100) %>%
  wordcloud2(size = .5)
Selecting by n

NA
first_word <- c("trump", "covid19")                                  # these need to be lowercase

news_bigrams %>%             
  count(words, sort = TRUE) %>%
  separate(words, c("word1", "word2"), sep = " ") %>%       # separate the two words
  filter(word1 %in% first_word) %>%                          # find first words from our list
  count(word1, word2, wt = n, sort = TRUE) %>% 
  rename(total = nn)
first_word <- c("trump", "covid19")                                  # these need to be lowercase

news_bigrams %>%             
  count(words, sort = TRUE) %>%
  separate(words, c("word1", "word2"), sep = " ") %>%       # separate the two words
  filter(word1 %in% first_word) %>%                          # find first words from our list
  count(word1, word2, wt = n, sort = TRUE) %>% 
  rename(total = nn) %>%
  mutate(word2 = factor(word2, levels = rev(unique(word2)))) %>%     # put the words in order
  group_by(word1) %>% 
  top_n(5) %>% 
  ggplot(aes(word2, total, fill = word1)) +                          #
  scale_fill_viridis_d() +                                           # set the color palette
  geom_col(show.legend = FALSE) +
  labs(x = NULL, y = NULL, title = "Word following:") +
  facet_wrap(~word1, scales = "free") +
  coord_flip()
Selecting by total

LS0tCnRpdGxlOiAiUmllc2VuIFR3ZWV0cyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKQXNzaWdubWVudDoKU2VsZWN0IGFub3RoZXIgbmV3cyBvcmdhbml6YXRpb24gYW5kIGdyYWIgNTAwMCBvZiB0aGVpciB0d2VldHMuClNvbWUgcG9zc2liaWxpdGllczoKRm9yIEJpbGxpbmdzIEdhemV0dGUgaGVhZGxpbmVzOiBiaWxsaW5nc2dhemV0dGUKV2FsbCBTdHJlZXQgSm91cm5hbDogd3NqCldhc2hpbmd0b24gUG9zdDogd2FzaGluZ3RvbnBvc3QKQ05OOiBjbm4KQ05OIGJyZWFraW5nIG5ld3M6IGNubmJyawpVU0EgVG9kYXk6IHVzYXRvZGF5CgoxLiBVbm5lc3QgdGhlIHdvcmRzIG9mIHRoZSB0d2VldHMsIHJlbW92ZSBzdG9wIHdvcmRzIGFuZCB3ZWlyZCB3ZWIgIndvcmRzIiwgYW5kIGNyZWF0ZSBhIHRhYmxlIGFuZCBhIHdvcmQgY2xvdWQgb2YgdGhlIHRvcCB3b3Jkcy4gIAoyLiBDb25kdWN0IGEgc2VudGltZW50IGFuYWx5c2lzIHVzaW5nIGJpbmcsIHJlbW92ZSBhbnkgZXJyb3JzIGxpa2UgdHJ1bXAgPSBwb3NpdGl2ZSwgYW5kIGNyZWF0ZSBhIGdyYXBoIG9mIHRoZSB3b3JkcyB0aGF0IGNvbnRyaWJ1dGUgbW9zdCB0byBlYWNoIHNlbnRpbWVudC4gIAozLiBEbyB0aGUgc2FtZSBhcyBhYm92ZSBidXQgd2l0aCB0aGUgbnJjIHNlbnRpbWVudCBsZXhpY29uLiAgCjQuIFVubmVzdCB0aGUgdHdlZXRzIGFzIGJpZ3JhbXMsIHJlbW92ZSBzdG9wIHdvcmRzIGFuZCBlcnJvcnMsIGFuZCBjcmVhdGUgYSB0YWJsZSBhbmQgd29yZCBjbG91ZCBvZiB0aGUgbW9zdCBjb21tb24gYmlncmFtcy4gIAo1LiBVc2luZyB0aGUgYmlncmFtcywgbG9vayBmb3IgdGhlIG1vc3QgY29tbW9uIHdvcmRzIHRoYXQgZm9sbG93IHR3byBkaWZmZXJlbnQgd29yZHMuIFlvdSBtYXkgY2hvb3NlIHRydW1wIGFuZCBwZWxvc2ksIG9yIGNob29zZSB5b3VyIG93bi4gIAoKYGBge3J9Cm5ld3NfdHdlZXRzIDwtIGdldF90aW1lbGluZSgiYmlsbGluZ3NnYXpldHRlIiwgbiA9IDUwMDApCmBgYAoKYGBge3J9Cm5ld3Nfd29yZHMgPC0gbmV3c190d2VldHMgJT4lIAogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lIAogIHNlbGVjdChzY3JlZW5fbmFtZSwgd29yZCkKYGBgCgoKYGBge3J9Cm5ld3Nfd29yZHMgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFQpCmBgYAoKYGBge3J9Cm5ld3Nfd29yZHMgJT4lIAogIGFudGlfam9pbihnZXRfc3RvcHdvcmRzKCkpICU+JSAKICBjb3VudCh3b3JkLCBzb3J0ID0gVCkKYGBgCgoKYGBge3J9Cm5ld3Nfd29yZHMgJT4lIAogIGFudGlfam9pbihnZXRfc3RvcHdvcmRzKCkpICU+JSAKICBmaWx0ZXIoIXdvcmQgPT0gImh0dHBzIiwKICAgICAgICAgIXdvcmQgPT0gInQuY28iKSAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVCkKYGBgCgoKYGBge3J9Cm5ld3Nfd29yZHMgJT4lIAogIGFudGlfam9pbihnZXRfc3RvcHdvcmRzKCkpICU+JSAKICBmaWx0ZXIoIXdvcmQgPT0gImh0dHBzIiwKICAgICAgICAgIXdvcmQgPT0gInQuY28iKSAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVCkgJT4lCiAgdG9wX24oMjAwKSAlPiUKICB3b3JkY2xvdWQyKHNpemUgPSAuNSkKYGBgCgoKYGBge3J9CmJpbmcgPC0gZ2V0X3NlbnRpbWVudHMoImJpbmciKQpiaW5nCmBgYAoKCmBgYHtyfQpuZXdzX3dvcmRzICU+JSAKICBpbm5lcl9qb2luKGJpbmcpICU+JSAKICBjb3VudCh3b3JkLCBzZW50aW1lbnQsIHNvcnQgPSBUUlVFKQoKYGBgCgoKCmBgYHtyfQpuZXdzX3dvcmRzICU+JSAKICBpbm5lcl9qb2luKGJpbmcpICU+JSAKICBmaWx0ZXIoIXdvcmQgPT0gInRydW1wIikgJT4lCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSkgCmBgYAoKCmBgYHtyfQpuZXdzX3dvcmRzICU+JSAKICBpbm5lcl9qb2luKGJpbmcpICU+JSAKICBmaWx0ZXIoIXdvcmQgPT0gInRydW1wIikgJT4lCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSklPiUKICBncm91cF9ieShzZW50aW1lbnQpICU+JQogIHRvcF9uKDEwKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUKICBnZ3Bsb3QoYWVzKHdvcmQsIG4sIGZpbGwgPSBzZW50aW1lbnQpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X3dyYXAodmFycyhzZW50aW1lbnQpLCBzY2FsZXMgPSAiZnJlZSIpICsKICBsYWJzKHkgPSAiTmV3cyBoZWFkbGluZXM6IFdvcmRzIHRoYXQgY29udHJpYnV0ZSB0aGUgbW9zdCB0byBlYWNoIHNlbnRpbWVudCIsCiAgICAgICB4ID0gTlVMTCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCgpgYGB7cn0KbnJjIDwtIGdldF9zZW50aW1lbnRzKCJucmMiKQpucmMKYGBgCgoKYGBge3J9Cm5yYyAlPiUKICBkaXN0aW5jdChzZW50aW1lbnQpCmBgYAoKCgpgYGB7cn0KbmV3c193b3JkcyAlPiUgCiAgaW5uZXJfam9pbihucmMpICU+JSAKICBmaWx0ZXIoIXdvcmQgPT0gInRydW1wIikgJT4lCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSklPiUKICBncm91cF9ieShzZW50aW1lbnQpICU+JQogIHRvcF9uKDUpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpICU+JQogIGdncGxvdChhZXMod29yZCwgbiwgZmlsbCA9IHNlbnRpbWVudCkpICsKICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh2YXJzKHNlbnRpbWVudCksIHNjYWxlcyA9ICJmcmVlIikgKwogIGxhYnMoeSA9ICJOZXdzIGhlYWRsaW5lczogV29yZHMgdGhhdCBjb250cmlidXRlIHRoZSBtb3N0IHRvIGVhY2ggc2VudGltZW50IiwKICAgICAgIHggPSBOVUxMKSArCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgoKCmBgYHtyfQpuZXdzX3R3ZWV0cyAlPiUKICBzZWxlY3QodGV4dCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhpcyBzZWxlY3RzIGp1c3QgdGhlIHRleHQgb2YgdGhlIHR3ZWV0cwogIHVubmVzdF90b2tlbnMod29yZHMsIHRleHQsIHRva2VuID0gIm5ncmFtcyIsIG4gPSAyKQoKYGBgCgpgYGB7cn0KbmV3c190d2VldHMgJT4lCiAgc2VsZWN0KHRleHQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjCiAgdW5uZXN0X3Rva2Vucyh3b3JkcywgdGV4dCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9IDIpICU+JQogIGNvdW50KHdvcmRzLCBzb3J0ID0gVCkKYGBgCgpgYGB7cn0KbmV3c190d2VldHMgJT4lCiAgc2VsZWN0KHRleHQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoaXMgc2VsZWN0cyBqdXN0IHRoZSB0ZXh0IG9mIHRoZSB0d2VldHMKICB1bm5lc3RfdG9rZW5zKHdvcmRzLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgJT4lIAogIHNlcGFyYXRlKHdvcmRzLCBjKCJ3b3JkMSIsICJ3b3JkMiIpLCBzZXAgPSAiICIpICU+JSAgICAgICAgICAjIHNlcGFyYXRlIHRoZW0gdGVtcG9yYXJpbHkKICBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUgICAgICAgICAgICAgICAgICAgICAgIyByZW1vdmUgaWYgZmlyc3Qgd29yZCBpcyBhIHN0b3Agd29yZAogIGZpbHRlcighd29yZDIgJWluJSBzdG9wX3dvcmRzJHdvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBpZiBzZWNvbmQgd29yZCBpcyBhIHN0b3Agd29yZCAgIAogIHVuaXRlKHdvcmRzLCB3b3JkMSwgd29yZDIsIHNlcCA9ICIgIikgICAgICAgICAgICAgICAgICAgICAgICAjIHB1dCB0aGVtIGJhY2sgdG9nZXRoZXIKYGBgCgoKYGBge3J9CnJlbW92ZV93b3JkcyA9IGMoImh0dHBzIiwgInQuY28iKQoKbmV3c190d2VldHMgJT4lCiAgc2VsZWN0KHRleHQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICB1bm5lc3RfdG9rZW5zKHdvcmRzLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgJT4lIAogIHNlcGFyYXRlKHdvcmRzLCBjKCJ3b3JkMSIsICJ3b3JkMiIpLCBzZXAgPSAiICIpICU+JSAgICAgICAgICAjIHNlcGFyYXRlIHRoZW0gdGVtcG9yYXJpbHkKICBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUgICAgICAgICAgICAgICAgICAgICAgIyByZW1vdmUgaWYgZmlyc3Qgd29yZCBpcyBhIHN0b3Agd29yZAogIGZpbHRlcighd29yZDIgJWluJSBzdG9wX3dvcmRzJHdvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBpZiBzZWNvbmQgd29yZCBpcyBhIHN0b3Agd29yZCAgIAogIGZpbHRlcighd29yZDEgJWluJSByZW1vdmVfd29yZHMpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZXNlIHR3byBsaW5lcyByZW1vdmUgb3VyIHJlbW92ZV93b3JkcwogIGZpbHRlcighd29yZDIgJWluJSByZW1vdmVfd29yZHMpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAKICB1bml0ZSh3b3Jkcywgd29yZDEsIHdvcmQyLCBzZXAgPSAiICIpICAgICAgICAgICAgICAgICAgICAgICAgIyBwdXQgdGhlbSBiYWNrIHRvZ2V0aGVyCmBgYAoKCmBgYHtyfQpyZW1vdmVfd29yZHMgPSBjKCJodHRwcyIsICJ0LmNvIikKCm5ld3NfdHdlZXRzICU+JQogIHNlbGVjdCh0ZXh0KSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgdW5uZXN0X3Rva2Vucyh3b3JkcywgdGV4dCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9IDIpICU+JSAKICBzZXBhcmF0ZSh3b3JkcywgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUgICAgICAgICAgIyBzZXBhcmF0ZSB0aGVtIHRlbXBvcmFyaWx5CiAgZmlsdGVyKCF3b3JkMSAlaW4lIHN0b3Bfd29yZHMkd29yZCkgJT4lICAgICAgICAgICAgICAgICAgICAgICMgcmVtb3ZlIGlmIGZpcnN0IHdvcmQgaXMgYSBzdG9wIHdvcmQKICBmaWx0ZXIoIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUgICAgICAgICAgICAgICAgICAgICAgIyByZW1vdmUgaWYgc2Vjb25kIHdvcmQgaXMgYSBzdG9wIHdvcmQgICAKICBmaWx0ZXIoIXdvcmQxICVpbiUgcmVtb3ZlX3dvcmRzKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGVzZSB0d28gbGluZXMgcmVtb3ZlIG91ciByZW1vdmVfd29yZHMKICBmaWx0ZXIoIXdvcmQyICVpbiUgcmVtb3ZlX3dvcmRzKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgCiAgdW5pdGUod29yZHMsIHdvcmQxLCB3b3JkMiwgc2VwID0gIiAiKSAtPiBuZXdzX2JpZ3JhbXMgICAgICAgICAgICAgICAgICAgICAgICMgcHV0IHRoZW0gYmFjayB0b2dldGhlcgpgYGAKCgoKCmBgYHtyfQpuZXdzX2JpZ3JhbXMgJT4lIAogIGNvdW50KHdvcmRzLCBzb3J0ID0gVCkKYGBgCgoKYGBge3J9Cm5ld3NfYmlncmFtcyAlPiUgCiAgY291bnQod29yZHMsIHNvcnQgPSBUKSAlPiUKICB0b3BfbigxMDApICU+JQogIHdvcmRjbG91ZDIoc2l6ZSA9IC41KQogIApgYGAKCgoKYGBge3J9CmZpcnN0X3dvcmQgPC0gYygidHJ1bXAiLCAiY292aWQxOSIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlc2UgbmVlZCB0byBiZSBsb3dlcmNhc2UKCm5ld3NfYmlncmFtcyAlPiUgICAgICAgICAgICAgCiAgY291bnQod29yZHMsIHNvcnQgPSBUUlVFKSAlPiUKICBzZXBhcmF0ZSh3b3JkcywgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUgICAgICAgIyBzZXBhcmF0ZSB0aGUgdHdvIHdvcmRzCiAgZmlsdGVyKHdvcmQxICVpbiUgZmlyc3Rfd29yZCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZpbmQgZmlyc3Qgd29yZHMgZnJvbSBvdXIgbGlzdAogIGNvdW50KHdvcmQxLCB3b3JkMiwgd3QgPSBuLCBzb3J0ID0gVFJVRSkgJT4lIAogIHJlbmFtZSh0b3RhbCA9IG5uKQpgYGAKCmBgYHtyfQpmaXJzdF93b3JkIDwtIGMoInRydW1wIiwgImNvdmlkMTkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZXNlIG5lZWQgdG8gYmUgbG93ZXJjYXNlCgpuZXdzX2JpZ3JhbXMgJT4lICAgICAgICAgICAgIAogIGNvdW50KHdvcmRzLCBzb3J0ID0gVFJVRSkgJT4lCiAgc2VwYXJhdGUod29yZHMsIGMoIndvcmQxIiwgIndvcmQyIiksIHNlcCA9ICIgIikgJT4lICAgICAgICMgc2VwYXJhdGUgdGhlIHR3byB3b3JkcwogIGZpbHRlcih3b3JkMSAlaW4lIGZpcnN0X3dvcmQpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgIyBmaW5kIGZpcnN0IHdvcmRzIGZyb20gb3VyIGxpc3QKICBjb3VudCh3b3JkMSwgd29yZDIsIHd0ID0gbiwgc29ydCA9IFRSVUUpICU+JSAKICByZW5hbWUodG90YWwgPSBubikgJT4lCiAgbXV0YXRlKHdvcmQyID0gZmFjdG9yKHdvcmQyLCBsZXZlbHMgPSByZXYodW5pcXVlKHdvcmQyKSkpKSAlPiUgICAgICMgcHV0IHRoZSB3b3JkcyBpbiBvcmRlcgogIGdyb3VwX2J5KHdvcmQxKSAlPiUgCiAgdG9wX24oNSkgJT4lIAogIGdncGxvdChhZXMod29yZDIsIHRvdGFsLCBmaWxsID0gd29yZDEpKSArICAgICAgICAgICAgICAgICAgICAgICAgICAjCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc2V0IHRoZSBjb2xvciBwYWxldHRlCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9IE5VTEwsIHkgPSBOVUxMLCB0aXRsZSA9ICJXb3JkIGZvbGxvd2luZzoiKSArCiAgZmFjZXRfd3JhcCh+d29yZDEsIHNjYWxlcyA9ICJmcmVlIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==