Today we are going to talk a bit about Chapter 6 and the Case Study in Chapter 9 from Text Mining with R.

Here is the link to one of the original papers on topic modeling LDA.

Chapter 6 Topic Modeling

Word-topic probabilities

First example,

library(topicmodels)
data("AssociatedPress")
AssociatedPress
<<DocumentTermMatrix (documents: 2246, terms: 10473)>>
Non-/sparse entries: 302031/23220327
Sparsity           : 99%
Maximal term length: 18
Weighting          : term frequency (tf)
ap_lda <- LDA(AssociatedPress, k = 2, control = list(seed = 1234))
ap_lda
A LDA_VEM topic model with 2 topics.

Here is the first example using Gibbs Sampling for the Bayesian Estiation. Here is a good website for learning about LDA Using Gibbs Sampling.

Understanding the output.

per-topic-per-word probabilities are called beta \(\beta\), from the model.

library(tidytext)
ap_topics <- tidy(ap_lda, matrix = "beta")
ap_topics
library(ggplot2)
library(dplyr)
ap_top_terms <- ap_topics %>%
  group_by(topic) %>%
  top_n(10, beta) %>%
  ungroup() %>%
  arrange(topic, -beta)
ap_top_terms %>%
  mutate(term = reorder(term, beta)) %>%
  ggplot(aes(term, beta, fill = factor(topic))) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~ topic, scales = "free") +
  coord_flip()

library(tidyverse)
library(tidyr)
beta_spread <- ap_topics %>%
  mutate(topic = paste0("topic", topic)) %>%
  spread(topic, beta) %>%
  filter(topic1 > .001 | topic2 > .001) %>%
  mutate(log_ratio = log2(topic2 / topic1))
beta_spread

Document-topic probabilities

library(tidytext)
ap_documents <- tidy(ap_lda, matrix = "gamma")
ap_documents
tidy(AssociatedPress) %>%
  filter(document == 6) %>%
  arrange(desc(count))

Chapter 9 Case Study: Analyzing usenet text

setwd("~/classes/2017-2018/Winter2018/Stat6864/TidyText")

Here is a nice discussion about the 20 Newsgroups data.

wget http://people.csail.mit.edu/jrennie/20Newsgroups/20news-bydate.tar.gz
--2018-03-09 10:49:12--  http://people.csail.mit.edu/jrennie/20Newsgroups/20news-bydate.tar.gz
Resolving people.csail.mit.edu (people.csail.mit.edu)... 128.30.2.133
Connecting to people.csail.mit.edu (people.csail.mit.edu)|128.30.2.133|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 14464277 (14M) [application/x-gzip]
Saving to: ‘20news-bydate.tar.gz’

     0K .......... .......... .......... .......... ..........  0%  266K 53s
    50K .......... .......... .......... .......... ..........  0%  504K 40s
   100K .......... .......... .......... .......... ..........  1% 1.86M 29s
   150K .......... .......... .......... .......... ..........  1%  671K 27s
   200K .......... .......... .......... .......... ..........  1%  650K 26s
   250K .......... .......... .......... .......... ..........  2% 2.00M 23s
   300K .......... .......... .......... .......... ..........  2%  734K 22s
   350K .......... .......... .......... .......... ..........  2% 1.44M 20s
   400K .......... .......... .......... .......... ..........  3%  811K 20s
   450K .......... .......... .......... .......... ..........  3%  609K 20s
   500K .......... .......... .......... .......... ..........  3% 2.39M 19s
   550K .......... .......... .......... .......... ..........  4%  738K 19s
   600K .......... .......... .......... .......... ..........  4% 2.42M 17s
   650K .......... .......... .......... .......... ..........  4%  772K 17s
   700K .......... .......... .......... .......... ..........  5% 1.27M 17s
   750K .......... .......... .......... .......... ..........  5% 1.00M 17s
   800K .......... .......... .......... .......... ..........  6%  669K 17s
   850K .......... .......... .......... .......... ..........  6% 3.53M 16s
   900K .......... .......... .......... .......... ..........  6%  688K 16s
   950K .......... .......... .......... .......... ..........  7% 4.52M 15s
  1000K .......... .......... .......... .......... ..........  7% 1.61M 15s
  1050K .......... .......... .......... .......... ..........  7%  877K 15s
  1100K .......... .......... .......... .......... ..........  8% 2.52M 14s
  1150K .......... .......... .......... .......... ..........  8%  805K 14s
  1200K .......... .......... .......... .......... ..........  8% 2.42M 14s
  1250K .......... .......... .......... .......... ..........  9%  801K 14s
  1300K .......... .......... .......... .......... ..........  9% 3.62M 14s
  1350K .......... .......... .......... .......... ..........  9% 1.13M 13s
  1400K .......... .......... .......... .......... .......... 10% 1.40M 13s
  1450K .......... .......... .......... .......... .......... 10% 2.64M 13s
  1500K .......... .......... .......... .......... .......... 10%  788K 13s
  1550K .......... .......... .......... .......... .......... 11% 5.26M 13s
  1600K .......... .......... .......... .......... .......... 11% 2.03M 12s
  1650K .......... .......... .......... .......... .......... 12%  914K 12s
  1700K .......... .......... .......... .......... .......... 12% 3.63M 12s
  1750K .......... .......... .......... .......... .......... 12% 1.01M 12s
  1800K .......... .......... .......... .......... .......... 13% 1.73M 12s
  1850K .......... .......... .......... .......... .......... 13% 3.66M 11s
  1900K .......... .......... .......... .......... .......... 13% 1.00M 11s
  1950K .......... .......... .......... .......... .......... 14% 1.96M 11s
  2000K .......... .......... .......... .......... .......... 14% 3.65M 11s
  2050K .......... .......... .......... .......... .......... 14% 1.10M 11s
  2100K .......... .......... .......... .......... .......... 15% 1.50M 11s
  2150K .......... .......... .......... .......... .......... 15% 6.43M 11s
  2200K .......... .......... .......... .......... .......... 15% 1.03M 11s
  2250K .......... .......... .......... .......... .......... 16% 1.49M 10s
  2300K .......... .......... .......... .......... .......... 16% 19.4M 10s
  2350K .......... .......... .......... .......... .......... 16% 1.67M 10s
  2400K .......... .......... .......... .......... .......... 17%  928K 10s
  2450K .......... .......... .......... .......... .......... 17% 27.6M 10s
  2500K .......... .......... .......... .......... .......... 18% 3.97M 10s
  2550K .......... .......... .......... .......... .......... 18%  701K 10s
  2600K .......... .......... .......... .......... .......... 18% 25.1M 10s
  2650K .......... .......... .......... .......... .......... 19% 14.7M 9s
  2700K .......... .......... .......... .......... .......... 19% 1.45M 9s
  2750K .......... .......... .......... .......... .......... 19% 1016K 9s
  2800K .......... .......... .......... .......... .......... 20% 36.0M 9s
  2850K .......... .......... .......... .......... .......... 20% 4.10M 9s
  2900K .......... .......... .......... .......... .......... 20%  955K 9s
  2950K .......... .......... .......... .......... .......... 21% 2.01M 9s
  3000K .......... .......... .......... .......... .......... 21% 25.4M 9s
  3050K .......... .......... .......... .......... .......... 21% 4.68M 9s
  3100K .......... .......... .......... .......... .......... 22%  969K 9s
  3150K .......... .......... .......... .......... .......... 22% 2.08M 8s
  3200K .......... .......... .......... .......... .......... 23% 35.1M 8s
  3250K .......... .......... .......... .......... .......... 23% 4.36M 8s
  3300K .......... .......... .......... .......... .......... 23%  986K 8s
  3350K .......... .......... .......... .......... .......... 24% 2.13M 8s
  3400K .......... .......... .......... .......... .......... 24% 43.3M 8s
  3450K .......... .......... .......... .......... .......... 24% 4.17M 8s
  3500K .......... .......... .......... .......... .......... 25%  990K 8s
  3550K .......... .......... .......... .......... .......... 25% 2.11M 8s
  3600K .......... .......... .......... .......... .......... 25% 31.3M 8s
  3650K .......... .......... .......... .......... .......... 26% 7.43M 7s
  3700K .......... .......... .......... .......... .......... 26% 1.67M 7s
  3750K .......... .......... .......... .......... .......... 26% 1017K 7s
  3800K .......... .......... .......... .......... .......... 27% 32.6M 7s
  3850K .......... .......... .......... .......... .......... 27% 38.3M 7s
  3900K .......... .......... .......... .......... .......... 27% 3.02M 7s
  3950K .......... .......... .......... .......... .......... 28% 1.09M 7s
  4000K .......... .......... .......... .......... .......... 28% 2.04M 7s
  4050K .......... .......... .......... .......... .......... 29% 31.1M 7s
  4100K .......... .......... .......... .......... .......... 29% 7.99M 7s
  4150K .......... .......... .......... .......... .......... 29% 2.05M 7s
  4200K .......... .......... .......... .......... .......... 30% 1.06M 7s
  4250K .......... .......... .......... .......... .......... 30% 4.86M 7s
  4300K .......... .......... .......... .......... .......... 30% 28.8M 7s
  4350K .......... .......... .......... .......... .......... 31% 8.71M 6s
  4400K .......... .......... .......... .......... .......... 31% 1.60M 6s
  4450K .......... .......... .......... .......... .......... 31% 1.06M 6s
  4500K .......... .......... .......... .......... .......... 32% 28.3M 6s
  4550K .......... .......... .......... .......... .......... 32% 38.5M 6s
  4600K .......... .......... .......... .......... .......... 32% 6.96M 6s
  4650K .......... .......... .......... .......... .......... 33% 2.03M 6s
  4700K .......... .......... .......... .......... .......... 33% 1.07M 6s
  4750K .......... .......... .......... .......... .......... 33% 5.15M 6s
  4800K .......... .......... .......... .......... .......... 34% 35.4M 6s
  4850K .......... .......... .......... .......... .......... 34% 41.7M 6s
  4900K .......... .......... .......... .......... .......... 35% 2.10M 6s
  4950K .......... .......... .......... .......... .......... 35%  922K 6s
  5000K .......... .......... .......... .......... .......... 35% 9.61M 6s
  5050K .......... .......... .......... .......... .......... 36% 26.9M 6s
  5100K .......... .......... .......... .......... .......... 36% 33.1M 6s
  5150K .......... .......... .......... .......... .......... 36% 3.10M 5s
  5200K .......... .......... .......... .......... .......... 37% 1.61M 5s
  5250K .......... .......... .......... .......... .......... 37% 1.43M 5s
  5300K .......... .......... .......... .......... .......... 37% 11.1M 5s
  5350K .......... .......... .......... .......... .......... 38% 34.2M 5s
  5400K .......... .......... .......... .......... .......... 38% 16.0M 5s
  5450K .......... .......... .......... .......... .......... 38% 2.64M 5s
  5500K .......... .......... .......... .......... .......... 39%  863K 5s
  5550K .......... .......... .......... .......... .......... 39% 24.0M 5s
  5600K .......... .......... .......... .......... .......... 39% 11.3M 5s
  5650K .......... .......... .......... .......... .......... 40% 39.8M 5s
  5700K .......... .......... .......... .......... .......... 40% 8.04M 5s
  5750K .......... .......... .......... .......... .......... 41% 2.46M 5s
  5800K .......... .......... .......... .......... .......... 41%  929K 5s
  5850K .......... .......... .......... .......... .......... 41% 25.0M 5s
  5900K .......... .......... .......... .......... .......... 42% 12.3M 5s
  5950K .......... .......... .......... .......... .......... 42% 35.2M 5s
  6000K .......... .......... .......... .......... .......... 42% 8.39M 5s
  6050K .......... .......... .......... .......... .......... 43% 2.54M 5s
  6100K .......... .......... .......... .......... .......... 43%  935K 5s
  6150K .......... .......... .......... .......... .......... 43% 29.4M 4s
  6200K .......... .......... .......... .......... .......... 44% 12.0M 4s
  6250K .......... .......... .......... .......... .......... 44% 25.3M 4s
  6300K .......... .......... .......... .......... .......... 44% 41.4M 4s
  6350K .......... .......... .......... .......... .......... 45% 2.55M 4s
  6400K .......... .......... .......... .......... .......... 45% 1.80M 4s
  6450K .......... .......... .......... .......... .......... 46% 1.43M 4s
  6500K .......... .......... .......... .......... .......... 46% 37.4M 4s
  6550K .......... .......... .......... .......... .......... 46% 13.1M 4s
  6600K .......... .......... .......... .......... .......... 47% 34.2M 4s
  6650K .......... .......... .......... .......... .......... 47% 6.66M 4s
  6700K .......... .......... .......... .......... .......... 47% 2.09M 4s
  6750K .......... .......... .......... .......... .......... 48%  869K 4s
  6800K .......... .......... .......... .......... .......... 48% 24.8M 4s
  6850K .......... .......... .......... .......... .......... 48% 36.2M 4s
  6900K .......... .......... .......... .......... .......... 49% 51.4M 4s
  6950K .......... .......... .......... .......... .......... 49% 69.3M 4s
  7000K .......... .......... .......... .......... .......... 49% 9.26M 4s
  7050K .......... .......... .......... .......... .......... 50% 2.01M 4s
  7100K .......... .......... .......... .......... .......... 50%  943K 4s
  7150K .......... .......... .......... .......... .......... 50% 32.4M 4s
  7200K .......... .......... .......... .......... .......... 51% 42.3M 4s
  7250K .......... .......... .......... .......... .......... 51% 54.2M 4s
  7300K .......... .......... .......... .......... .......... 52% 57.4M 3s
  7350K .......... .......... .......... .......... .......... 52% 5.18M 3s
  7400K .......... .......... .......... .......... .......... 52% 2.00M 3s
  7450K .......... .......... .......... .......... .......... 53% 1.01M 3s
  7500K .......... .......... .......... .......... .......... 53% 20.0M 3s
  7550K .......... .......... .......... .......... .......... 53% 35.5M 3s
  7600K .......... .......... .......... .......... .......... 54% 38.2M 3s
  7650K .......... .......... .......... .......... .......... 54% 43.4M 3s
  7700K .......... .......... .......... .......... .......... 54% 7.29M 3s
  7750K .......... .......... .......... .......... .......... 55% 2.50M 3s
  7800K .......... .......... .......... .......... .......... 55%  945K 3s
  7850K .......... .......... .......... .......... .......... 55% 23.7M 3s
  7900K .......... .......... .......... .......... .......... 56% 39.6M 3s
  7950K .......... .......... .......... .......... .......... 56% 16.1M 3s
  8000K .......... .......... .......... .......... .......... 56% 40.5M 3s
  8050K .......... .......... .......... .......... .......... 57% 17.7M 3s
  8100K .......... .......... .......... .......... .......... 57% 4.33M 3s
  8150K .......... .......... .......... .......... .......... 58% 1.43M 3s
  8200K .......... .......... .......... .......... .......... 58% 1.47M 3s
  8250K .......... .......... .......... .......... .......... 58% 28.0M 3s
  8300K .......... .......... .......... .......... .......... 59% 35.8M 3s
  8350K .......... .......... .......... .......... .......... 59% 49.0M 3s
  8400K .......... .......... .......... .......... .......... 59% 49.0M 3s
  8450K .......... .......... .......... .......... .......... 60% 6.22M 3s
  8500K .......... .......... .......... .......... .......... 60% 2.10M 3s
  8550K .......... .......... .......... .......... .......... 60% 1.67M 3s
  8600K .......... .......... .......... .......... .......... 61% 2.23M 3s
  8650K .......... .......... .......... .......... .......... 61% 33.6M 3s
  8700K .......... .......... .......... .......... .......... 61% 38.9M 3s
  8750K .......... .......... .......... .......... .......... 62% 42.8M 2s
  8800K .......... .......... .......... .......... .......... 62% 48.6M 2s
  8850K .......... .......... .......... .......... .......... 63%  527K 2s
  8900K .......... .......... .......... .......... .......... 63%  522M 2s
  8950K .......... .......... .......... .......... .......... 63%  597M 2s
  9000K .......... .......... .......... .......... .......... 64%  471M 2s
  9050K .......... .......... .......... .......... .......... 64%  521M 2s
  9100K .......... .......... .......... .......... .......... 64%  602M 2s
  9150K .......... .......... .......... .......... .......... 65%  599M 2s
  9200K .......... .......... .......... .......... .......... 65%  523M 2s
  9250K .......... .......... .......... .......... .......... 65% 1.89M 2s
  9300K .......... .......... .......... .......... .......... 66%  953K 2s
  9350K .......... .......... .......... .......... .......... 66% 21.8M 2s
  9400K .......... .......... .......... .......... .......... 66% 20.5M 2s
  9450K .......... .......... .......... .......... .......... 67% 28.8M 2s
  9500K .......... .......... .......... .......... .......... 67% 6.05M 2s
  9550K .......... .......... .......... .......... .......... 67% 1.48M 2s
  9600K .......... .......... .......... .......... .......... 68% 1.19M 2s
  9650K .......... .......... .......... .......... .......... 68% 18.9M 2s
  9700K .......... .......... .......... .......... .......... 69% 29.1M 2s
  9750K .......... .......... .......... .......... .......... 69% 35.4M 2s
  9800K .......... .......... .......... .......... .......... 69% 5.52M 2s
  9850K .......... .......... .......... .......... .......... 70% 1.32M 2s
  9900K .......... .......... .......... .......... .......... 70% 1.37M 2s
  9950K .......... .......... .......... .......... .......... 70% 29.2M 2s
 10000K .......... .......... .......... .......... .......... 71% 16.0M 2s
 10050K .......... .......... .......... .......... .......... 71% 36.1M 2s
 10100K .......... .......... .......... .......... .......... 71% 2.39M 2s
 10150K .......... .......... .......... .......... .......... 72% 1.52M 2s
 10200K .......... .......... .......... .......... .......... 72% 1.77M 2s
 10250K .......... .......... .......... .......... .......... 72% 33.8M 2s
 10300K .......... .......... .......... .......... .......... 73% 10.7M 2s
 10350K .......... .......... .......... .......... .......... 73% 34.1M 2s
 10400K .......... .......... .......... .......... .......... 73% 2.45M 2s
 10450K .......... .......... .......... .......... .......... 74% 1.48M 2s
 10500K .......... .......... .......... .......... .......... 74% 1.81M 2s
 10550K .......... .......... .......... .......... .......... 75% 33.0M 2s
 10600K .......... .......... .......... .......... .......... 75% 22.0M 2s
 10650K .......... .......... .......... .......... .......... 75% 39.0M 1s
 10700K .......... .......... .......... .......... .......... 76% 2.30M 1s
 10750K .......... .......... .......... .......... .......... 76% 1.44M 1s
 10800K .......... .......... .......... .......... .......... 76% 1.87M 1s
 10850K .......... .......... .......... .......... .......... 77% 47.1M 1s
 10900K .......... .......... .......... .......... .......... 77% 11.0M 1s
 10950K .......... .......... .......... .......... .......... 77% 27.1M 1s
 11000K .......... .......... .......... .......... .......... 78% 3.18M 1s
 11050K .......... .......... .......... .......... .......... 78% 1.62M 1s
 11100K .......... .......... .......... .......... .......... 78% 1.46M 1s
 11150K .......... .......... .......... .......... .......... 79% 35.3M 1s
 11200K .......... .......... .......... .......... .......... 79% 16.3M 1s
 11250K .......... .......... .......... .......... .......... 79% 25.7M 1s
 11300K .......... .......... .......... .......... .......... 80% 3.12M 1s
 11350K .......... .......... .......... .......... .......... 80% 1.94M 1s
 11400K .......... .......... .......... .......... .......... 81% 1.23M 1s
 11450K .......... .......... .......... .......... .......... 81% 36.6M 1s
 11500K .......... .......... .......... .......... .......... 81% 18.6M 1s
 11550K .......... .......... .......... .......... .......... 82% 20.3M 1s
 11600K .......... .......... .......... .......... .......... 82% 7.02M 1s
 11650K .......... .......... .......... .......... .......... 82% 2.24M 1s
 11700K .......... .......... .......... .......... .......... 83%  982K 1s
 11750K .......... .......... .......... .......... .......... 83% 25.7M 1s
 11800K .......... .......... .......... .......... .......... 83% 27.1M 1s
 11850K .......... .......... .......... .......... .......... 84% 40.8M 1s
 11900K .......... .......... .......... .......... .......... 84% 11.1M 1s
 11950K .......... .......... .......... .......... .......... 84% 1.87M 1s
 12000K .......... .......... .......... .......... .......... 85% 1.67M 1s
 12050K .......... .......... .......... .......... .......... 85% 2.04M 1s
 12100K .......... .......... .......... .......... .......... 86% 34.6M 1s
 12150K .......... .......... .......... .......... .......... 86% 41.6M 1s
 12200K .......... .......... .......... .......... .......... 86% 57.2M 1s
 12250K .......... .......... .......... .......... .......... 87% 3.54M 1s
 12300K .......... .......... .......... .......... .......... 87% 1.89M 1s
 12350K .......... .......... .......... .......... .......... 87% 1.13M 1s
 12400K .......... .......... .......... .......... .......... 88% 35.9M 1s
 12450K .......... .......... .......... .......... .......... 88% 50.0M 1s
 12500K .......... .......... .......... .......... .......... 88% 53.0M 1s
 12550K .......... .......... .......... .......... .......... 89% 51.4M 1s
 12600K .......... .......... .......... .......... .......... 89% 1.62M 1s
 12650K .......... .......... .......... .......... .......... 89% 1.45M 1s
 12700K .......... .......... .......... .......... .......... 90% 2.43M 1s
 12750K .......... .......... .......... .......... .......... 90% 32.6M 1s
 12800K .......... .......... .......... .......... .......... 90% 46.5M 1s
 12850K .......... .......... .......... .......... .......... 91% 47.7M 1s
 12900K .......... .......... .......... .......... .......... 91% 1.74M 0s
 12950K .......... .......... .......... .......... .......... 92% 4.61M 0s
 13000K .......... .......... .......... .......... .......... 92% 1.13M 0s
 13050K .......... .......... .......... .......... .......... 92% 24.1M 0s
 13100K .......... .......... .......... .......... .......... 93% 35.7M 0s
 13150K .......... .......... .......... .......... .......... 93% 44.6M 0s
 13200K .......... .......... .......... .......... .......... 93% 52.1M 0s
 13250K .......... .......... .......... .......... .......... 94% 1.57M 0s
 13300K .......... .......... .......... .......... .......... 94% 2.25M 0s
 13350K .......... .......... .......... .......... .......... 94% 1.67M 0s
 13400K .......... .......... .......... .......... .......... 95% 36.4M 0s
 13450K .......... .......... .......... .......... .......... 95% 47.6M 0s
 13500K .......... .......... .......... .......... .......... 95% 22.2M 0s
 13550K .......... .......... .......... .......... .......... 96% 36.8M 0s
 13600K .......... .......... .......... .......... .......... 96% 1.76M 0s
 13650K .......... .......... .......... .......... .......... 96% 1.12M 0s
 13700K .......... .......... .......... .......... .......... 97% 4.64M 0s
 13750K .......... .......... .......... .......... .......... 97% 33.2M 0s
 13800K .......... .......... .......... .......... .......... 98% 40.4M 0s
 13850K .......... .......... .......... .......... .......... 98% 52.7M 0s
 13900K .......... .......... .......... .......... .......... 98% 3.73M 0s
 13950K .......... .......... .......... .......... .......... 99% 2.45M 0s
 14000K .......... .......... .......... .......... .......... 99% 1.01M 0s
 14050K .......... .......... .......... .......... .......... 99% 24.5M 0s
 14100K .......... .......... .....                           100% 33.1M=5.6s

2018-03-09 10:49:19 (2.46 MB/s) - ‘20news-bydate.tar.gz’ saved [14464277/14464277]
tar -xzf 20news-bydate.tar.gz
library(dplyr)
library(tidyr)
library(purrr)
library(readr)
raw_text <- data_frame(folder = dir(training_folder, full.names = TRUE)) %>%
  unnest(map(folder, read_folder)) %>%
  transmute(newsgroup = basename(folder), id, text)
Error in mutate_impl(.data, dots) : 
  Column `id` is of unsupported type function
library(ggplot2)
raw_text %>%
  group_by(newsgroup) %>%
  summarize(messages = n_distinct(id)) %>%
  ggplot(aes(newsgroup, messages)) +
  geom_col() +
  coord_flip()
Error in eval(lhs, parent, parent) : object 'raw_text' not found
LS0tCnRpdGxlOiAiVG9waWMgTW9kZWxpbmciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClRvZGF5IHdlIGFyZSBnb2luZyB0byB0YWxrIGEgYml0IGFib3V0IENoYXB0ZXIgNiBhbmQgdGhlIENhc2UgU3R1ZHkgaW4gQ2hhcHRlciA5IGZyb20gW1RleHQgTWluaW5nIHdpdGggUl0od3d3LnRpZHl0ZXh0bWluaW5nLmNvbSkuCgpIZXJlIGlzIHRoZSBsaW5rIHRvIG9uZSBvZiB0aGUgb3JpZ2luYWwgcGFwZXJzIG9uIHRvcGljIG1vZGVsaW5nIFtMREFdKGh0dHA6Ly93d3cuam1sci5vcmcvcGFwZXJzL3ZvbHVtZTMvYmxlaTAzYS9ibGVpMDNhLnBkZikuCgojIENoYXB0ZXIgNiBUb3BpYyBNb2RlbGluZwoKIyBXb3JkLXRvcGljIHByb2JhYmlsaXRpZXMKCkZpcnN0IGV4YW1wbGUsCgpgYGB7cn0KbGlicmFyeSh0b3BpY21vZGVscykKCmRhdGEoIkFzc29jaWF0ZWRQcmVzcyIpCkFzc29jaWF0ZWRQcmVzcwpgYGAKCmBgYHtyfQphcF9sZGEgPC0gTERBKEFzc29jaWF0ZWRQcmVzcywgayA9IDIsIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSAxMjM0KSkKYXBfbGRhCmBgYAoKSGVyZSBpcyB0aGUgZmlyc3QgZXhhbXBsZSB1c2luZyBHaWJicyBTYW1wbGluZyBmb3IgdGhlIEJheWVzaWFuIEVzdGlhdGlvbi4gIEhlcmUgaXMgYSBnb29kIHdlYnNpdGUgZm9yIGxlYXJuaW5nIGFib3V0IFtMREEgVXNpbmcgR2liYnMgU2FtcGxpbmddKGh0dHA6Ly9ldGhlbjgxODEuZ2l0aHViLmlvL21hY2hpbmUtbGVhcm5pbmcvY2x1c3RlcmluZ19vbGQvdG9waWNfbW9kZWwvTERBLmh0bWwpLgoKVW5kZXJzdGFuZGluZyB0aGUgb3V0cHV0LgoKcGVyLXRvcGljLXBlci13b3JkIHByb2JhYmlsaXRpZXMgYXJlIGNhbGxlZCBiZXRhICRcYmV0YSQsIGZyb20gdGhlIG1vZGVsLgoKYGBge3J9CmxpYnJhcnkodGlkeXRleHQpCgphcF90b3BpY3MgPC0gdGlkeShhcF9sZGEsIG1hdHJpeCA9ICJiZXRhIikKYXBfdG9waWNzCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKCmFwX3RvcF90ZXJtcyA8LSBhcF90b3BpY3MgJT4lCiAgZ3JvdXBfYnkodG9waWMpICU+JQogIHRvcF9uKDEwLCBiZXRhKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZSh0b3BpYywgLWJldGEpCgphcF90b3BfdGVybXMgJT4lCiAgbXV0YXRlKHRlcm0gPSByZW9yZGVyKHRlcm0sIGJldGEpKSAlPiUKICBnZ3Bsb3QoYWVzKHRlcm0sIGJldGEsIGZpbGwgPSBmYWN0b3IodG9waWMpKSkgKwogIGdlb21fY29sKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBmYWNldF93cmFwKH4gdG9waWMsIHNjYWxlcyA9ICJmcmVlIikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWR5cikKCmJldGFfc3ByZWFkIDwtIGFwX3RvcGljcyAlPiUKICBtdXRhdGUodG9waWMgPSBwYXN0ZTAoInRvcGljIiwgdG9waWMpKSAlPiUKICBzcHJlYWQodG9waWMsIGJldGEpICU+JQogIGZpbHRlcih0b3BpYzEgPiAuMDAxIHwgdG9waWMyID4gLjAwMSkgJT4lCiAgbXV0YXRlKGxvZ19yYXRpbyA9IGxvZzIodG9waWMyIC8gdG9waWMxKSkKCmJldGFfc3ByZWFkCmBgYAoKIyBEb2N1bWVudC10b3BpYyBwcm9iYWJpbGl0aWVzCgpgYGB7cn0KbGlicmFyeSh0aWR5dGV4dCkKYXBfZG9jdW1lbnRzIDwtIHRpZHkoYXBfbGRhLCBtYXRyaXggPSAiZ2FtbWEiKQphcF9kb2N1bWVudHMKYGBgCgoKYGBge3J9CnRpZHkoQXNzb2NpYXRlZFByZXNzKSAlPiUKICBmaWx0ZXIoZG9jdW1lbnQgPT0gNikgJT4lCiAgYXJyYW5nZShkZXNjKGNvdW50KSkKYGBgCgojIENoYXB0ZXIgOSBDYXNlIFN0dWR5OiBBbmFseXppbmcgdXNlbmV0IHRleHQKCmBgYHtyfQpzZXR3ZCgifi9jbGFzc2VzLzIwMTctMjAxOC9XaW50ZXIyMDE4L1N0YXQ2ODY0L1RpZHlUZXh0IikKYGBgCgpIZXJlIGlzIGEgbmljZSBkaXNjdXNzaW9uIGFib3V0IHRoZSAyMCBOZXdzZ3JvdXBzIGRhdGEuCgpgYGB7YmFzaH0Kd2dldCBodHRwOi8vcGVvcGxlLmNzYWlsLm1pdC5lZHUvanJlbm5pZS8yME5ld3Nncm91cHMvMjBuZXdzLWJ5ZGF0ZS50YXIuZ3oKYGBgCgpgYGB7YmFzaH0KdGFyIC14emYgMjBuZXdzLWJ5ZGF0ZS50YXIuZ3oKYGBgCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShwdXJycikKbGlicmFyeShyZWFkcikKYGBgCgpgYGB7cn0KIHNldHdkKCJ+L2NsYXNzZXMvMjAxNy0yMDE4L1dpbnRlcjIwMTgvU3RhdDY4NjQvVGlkeVRleHQiKQoKdHJhaW5pbmdfZm9sZGVyIDwtICIyMG5ld3MtYnlkYXRlLzIwbmV3cy1ieWRhdGUtdHJhaW4vIgoKIyBEZWZpbmUgYSBmdW5jdGlvbiB0byByZWFkIGFsbCBmaWxlcyBmcm9tIGEgZm9sZGVyIGludG8gYSBkYXRhIGZyYW1lCnJlYWRfZm9sZGVyIDwtIGZ1bmN0aW9uKGluZm9sZGVyKSB7CiAgZGF0YV9mcmFtZShmaWxlID0gZGlyKGluZm9sZGVyLCBmdWxsLm5hbWVzID0gVFJVRSkpICU+JQogICAgbXV0YXRlKHRleHQgPSBtYXAoZmlsZSwgcmVhZF9saW5lcykpICU+JQogICAgdHJhbnNtdXRlKGlkID0gYmFzZW5hbWUoZmlsZSksIHRleHQpICU+JQogICAgdW5uZXN0KHRleHQpCn0KCiMgVXNlIHVubmVzdCgpIGFuZCBtYXAoKSB0byBhcHBseSByZWFkX2ZvbGRlciB0byBlYWNoIHN1YmZvbGRlcgpyYXdfdGV4dCA8LSBkYXRhX2ZyYW1lKGZvbGRlciA9IGRpcih0cmFpbmluZ19mb2xkZXIsIGZ1bGwubmFtZXMgPSBUUlVFKSkgJT4lCiAgdW5uZXN0KG1hcChmb2xkZXIsIHJlYWRfZm9sZGVyKSkgJT4lCiAgdHJhbnNtdXRlKG5ld3Nncm91cCA9IGJhc2VuYW1lKGZvbGRlciksIGlkLCB0ZXh0KQoKYGBgCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQoKcmF3X3RleHQgJT4lCiAgZ3JvdXBfYnkobmV3c2dyb3VwKSAlPiUKICBzdW1tYXJpemUobWVzc2FnZXMgPSBuX2Rpc3RpbmN0KGlkKSkgJT4lCiAgZ2dwbG90KGFlcyhuZXdzZ3JvdXAsIG1lc3NhZ2VzKSkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCgoK