Initial Proposal

Week ten was an interesting week were sentiment analysis was introduced. In week ten discussion I posted regarding Game of thrones and sentiment analysis for season 6 premiere. I feel that we did not cover the topic in depth so my proposal is the following. The election is over and unless the electoral college votes against Donald Trump he will be president. I want to do sentiment analysis using twitter. My primary goal is to capture the mood of the people within the month of November and December, classify twits as positive, negative, or neutral, and identify these words. I will implement learned material and implemented in the spirit of the class.

1 Scrape twitter for data regarding the election (message, date, Maybe geographical location)

2 After cleaning the data, I will use Mongo dB to store information

3 Analysis is going to be perform by querying Mongo dB and using ggplot2

I will use R, Mongo dB, Twitter, R packages (tidyr, dplyr, tm, ggplot2)

Intro

The goal of this my final project was to be able to gather information from a social website clean this data transform the data, and classify it. The topic intrige me due to the many application that can be achived.I see this project as a small step into inplementing a sentiment market reasearch tool with the inclusion of many other social media sites.

Twitter

I first start by connecting to the Twitter API. I first tried to connect using #library(“ROAuth”) but due to the api not validating my access code I search for a different implementation. What worked for me was using direct access authentication with the Twitter API.

#options(RCurlOptions = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")))
consumerKey = "" 
consumerSecret = ""
accessToken =""
accessTokenSecret=""

#reqURL = "https://api.twitter.com/oauth/request_token" #important at the moment that it is https  Twitter needs a secure connection
#accessURL = "https://api.twitter.com/oauth/access_token"
#authURL = "https://api.twitter.com/oauth/authorize"
#twitCred = OAuthFactory$new(consumerKey=consumerKey,consumerSecret=consumerSecret,requestURL=reqURL,accessURL=accessURL,authURL=authURL)
#twitCred$handshake() 
#registerTwitterOAuth(twitCred)


#setup_twitter_oauth(consumerKey,consumerSecret,accessToken,accessTokenSecret)

Data Acquisition

I used two search methods with TwitteR and the API connection.The first was the Search Twitter and the second one GetUser.This allowed me two get two different data sources and apply sentiment analysis.In my first method I searched for Trump and dowloaded 10,000 Twitts.The second methode I used Donald Trump Twitter handle to collect all his twitter feeds.I also tried getting his 17.7 M followers but when I search to download the direct connection only produced 56 fallowers.Finally each file were exported to a CSV file that was later uploaded to GitHub.

#tweets=searchTwitter("trump", n=10000,lang = "en")
#df = do.call("rbind", lapply(tweets, as.data.frame))

#write.csv(df, "Trump10000Tweets.csv", row.names=FALSE)


#TrumpTwiterAcct <- getUser("realDonaldTrump")
#donaldtweetslist = userTimeline(TrumpTwiterAcct, n=3200, includeRts=TRUE, excludeReplies=TRUE)
#tumpprofiletweetsdf = do.call("rbind", lapply(donaldtweetslist, as.data.frame))
#write.csv(tumpprofiletweetsdf, "realDonaldTrump3200Tweets.csv", row.names=FALSE)

Github

After uploading the data to github I user Rcurl to bring it back to my project. This was done in order to obtain a reproducible example.

url1 = "https://raw.githubusercontent.com/chrisestevez/DataAnalyticsProjects/master/FinalProject/Trump10000Tweets.csv"
Rdata1 = getURL(url1)
TrumpSearch = read.csv(text = Rdata1,header = TRUE,stringsAsFactors = F,sep=",")
head(TrumpSearch,5)
                                                                                                                                                     text
1                                                      RT @AboveTopSecret: ACLU Threatens Donald Trump Via New York Times Ad #ATS https://t.co/WPc6NC5Ci3
2                                                #Breaking News: A Gang Of Trump Fans Just Viciously Attacked Peaceful Protesters https://t.co/bqqyPz2Vai
3            @Siclittlemonkey As far as I know Trump hasn't done anything illegal. Hillary, on the other hand, should be behind bars for her many crimes.
4     RT @bannerite: #Shameless Donald Trump's sons behind nonprofit selling access to president-elect | Center for Public Integrity https://t.co<U+0085>
5 RT @feistybunnygirl: When u voted for Trump bc he promised to deport all the brown people, but then u realize he's going to cut ur SS &amp; Med<U+0085>
  favorited favoriteCount       replyToSN             created truncated
1     FALSE             0            <NA> 2016-12-20 05:23:19     FALSE
2     FALSE             1            <NA> 2016-12-20 05:23:19     FALSE
3     FALSE             0 Siclittlemonkey 2016-12-20 05:23:19     FALSE
4     FALSE             0            <NA> 2016-12-20 05:23:19     FALSE
5     FALSE             0            <NA> 2016-12-20 05:23:19     FALSE
    replyToSID           id replyToUID
1           NA 8.110795e+17         NA
2           NA 8.110795e+17         NA
3 8.110783e+17 8.110795e+17  429591885
4           NA 8.110795e+17         NA
5           NA 8.110795e+17         NA
                                                                          statusSource
1 <a href="http://twitter.com/download/android" rel="nofollow">Twitter for Android</a>
2                                  <a href="http://ifttt.com" rel="nofollow">IFTTT</a>
3    <a href="http://twitter.com/#!/download/ipad" rel="nofollow">Twitter for iPad</a>
4   <a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
5 <a href="http://twitter.com/download/android" rel="nofollow">Twitter for Android</a>
       screenName retweetCount isRetweet retweeted longitude latitude
1  OSDlirectioner            2      TRUE     FALSE        NA       NA
2 OccupyDemocrats            0     FALSE     FALSE        NA       NA
3   LibsAreInsane            0     FALSE     FALSE        NA       NA
4       akeithism           69      TRUE     FALSE        NA       NA
5       thelaynee          175      TRUE     FALSE        NA       NA
TrumpSearchText  = as.vector(TrumpSearch$text)

url2 = "https://raw.githubusercontent.com/chrisestevez/DataAnalyticsProjects/master/FinalProject/realDonaldTrump3200Tweets.csv"
Rdata2 = getURL(url2)
TrumpPersonal = read.csv(text = Rdata2,header = TRUE,stringsAsFactors = F,sep=",")
TrumpPersonalText  = as.vector(TrumpPersonal$text)
head(TrumpPersonal,5)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                 text
1                                                                                                                                                                                                                                                                                                                               "@mike_pence: Congratulations to @RealDonaldTrump; officially elected President of the United States today by the Electoral College!"
2                                                                                                                                                                                                                                                                                                                          "@Franklin_Graham: Congratulations to President-elect @realDonaldTrump--the electoral votes are in and it's official." Thank you Franklin!
3 RT @DanScavino: #TrumpTrain<ed><U+00A0><U+00BD><ed><U+00BA><U+0082><ed><U+00A0><U+00BD><ed><U+00B2><U+00A8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8> https://t.co/qAQdBGEwSv
4                                                                                                                                                                                                                                                                                                                        We did it! Thank you to all of my great supporters, we just officially won the election (despite all of the distorted and inaccurate media).
5                                                                                                                                                                                                                                                                                                                        Today there were terror attacks in Turkey, Switzerland and Germany - and it is only getting worse. The civilized world must change thinking!
  favorited favoriteCount replyToSN             created truncated
1     FALSE          3714        NA 2016-12-20 02:50:25     FALSE
2     FALSE          5234        NA 2016-12-20 02:46:01     FALSE
3     FALSE             0        NA 2016-12-20 01:31:21     FALSE
4     FALSE        106442        NA 2016-12-19 23:51:41     FALSE
5     FALSE         58597        NA 2016-12-19 23:21:11     FALSE
  replyToSID           id replyToUID
1         NA 8.110410e+17         NA
2         NA 8.110399e+17         NA
3         NA 8.110211e+17         NA
4         NA 8.109961e+17         NA
5         NA 8.109884e+17         NA
                                                                          statusSource
1   <a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
2   <a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
3   <a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
4 <a href="http://twitter.com/download/android" rel="nofollow">Twitter for Android</a>
5 <a href="http://twitter.com/download/android" rel="nofollow">Twitter for Android</a>
       screenName retweetCount isRetweet retweeted longitude latitude
1 realDonaldTrump         1041     FALSE     FALSE        NA       NA
2 realDonaldTrump         1257     FALSE     FALSE        NA       NA
3 realDonaldTrump         3621      TRUE     FALSE        NA       NA
4 realDonaldTrump        32627     FALSE     FALSE        NA       NA
5 realDonaldTrump        21416     FALSE     FALSE        NA       NA

syuzhet

The sentiment analysis algorithm used here is based on the Word-Emotion Association of Saif Mohammad and Peter Turney. The use a dictionary that associates the words to eight different emotions and a negative/Positive sentiment.Please see exmaples below.

get_nrc_sentiment("Donal Trump is awesome and amazing I'm happy he is running for president")
  anger anticipation disgust fear joy sadness surprise trust negative
1     0            1       0    0   1       0        1     2        0
  positive
1        2
get_nrc_sentiment("I hate Donal Trump he is a liar and deceiving person")
  anger anticipation disgust fear joy sadness surprise trust negative
1     1            0       2    1   0       1        1     1        3
  positive
1        0

10,000 Twitts

In this part of the project I investigate to see if there is any pattern in emotion or sentiment by the Twitter Community.I begin by using the acquire data that was obtain by searching for the term Trump. The twitts were converted into a vector in order to process effectively the data. I used gsub to remove various unwanted terms. I later applied the sentiment algorithm and merge the results to the original data.After merging the data I used dplyr and tidyr to transform and plot the data using ggplot2.

head(TrumpSearchText,5)
[1] "RT @AboveTopSecret: ACLU Threatens Donald Trump Via New York Times Ad #ATS https://t.co/WPc6NC5Ci3"                                                   
[2] "#Breaking News: A Gang Of Trump Fans Just Viciously Attacked Peaceful Protesters https://t.co/bqqyPz2Vai"                                             
[3] "@Siclittlemonkey As far as I know Trump hasn't done anything illegal. Hillary, on the other hand, should be behind bars for her many crimes."         
[4] "RT @bannerite: #Shameless Donald Trump's sons behind nonprofit selling access to president-elect | Center for Public Integrity https://t.co<U+0085>"  
[5] "RT @feistybunnygirl: When u voted for Trump bc he promised to deport all the brown people, but then u realize he's going to cut ur SS &amp; Med<U+0085>"
RT @AboveTopSecret: ACLU Threatens Donald Trump Via New York Times Ad #ATS https://t.co/WPc6NC5Ci3

#Breaking News: A Gang Of Trump Fans Just Viciously Attacked Peaceful Protesters https://t.co/bqqyPz2Vai

@Siclittlemonkey As far as I know Trump hasn't done anything illegal. Hillary, on the other hand, should be behind bars for her many crimes.

RT @bannerite: #Shameless Donald Trump's sons behind nonprofit selling access to president-elect | Center for Public Integrity https://t.co㠼㸵

RT @feistybunnygirl: When u voted for Trump bc he promised to deport all the brown people, but then u realize he's going to cut ur SS &amp; Med㠼㸵
 cleanTweet = gsub("rt|RT", "", TrumpSearchText) # remove Retweet
cleanTweet = gsub("http\\w+", "", cleanTweet)  # remove links http
cleanTweet = gsub("<.*?>", "", cleanTweet) # remove html tags
cleanTweet = gsub("@\\w+", "", cleanTweet) # remove at(@)
cleanTweet = gsub("[[:punct:]]", "", cleanTweet) # remove punctuation
cleanTweet  = gsub("\r?\n|\r", " ", cleanTweet) # remove /n
cleanTweet = gsub("[[:digit:]]", "", cleanTweet) # remove numbers/Digits
cleanTweet = gsub("㠼|㸵|㤼|㸲|㸱|㸳|㸴|㸶|攼|㹤", "", cleanTweet) #  asian letters
cleanTweet = gsub("[ |\t]{2,}", "", cleanTweet) # remove tabs
cleanTweet = gsub("^ ", "", cleanTweet)  # remove blank spaces at the beginning
cleanTweet = gsub(" $", "", cleanTweet) # remove blank spaces at the end 

TrumpSearchSentiment = get_nrc_sentiment(cleanTweet)
head(TrumpSearchSentiment,5)
  anger anticipation disgust fear joy sadness surprise trust negative
1     0            0       0    0   0       0        1     0        0
2     1            1       0    1   1       0        2     1        1
3     1            0       1    1   0       1        1     0        1
4     0            1       1    0   0       0        0     1        1
5     0            0       0    0   0       0        1     0        0
  positive
1        0
2        1
3        0
4        2
5        0
TrumpSearchFinalData = cbind(TrumpSearch,TrumpSearchSentiment)

plotData1 =gather(TrumpSearchFinalData,"sentiment","values",17:24)  %>% 
  group_by( sentiment) %>%
  summarise(Total = sum(values))

ggplot(data = plotData1, aes(x = plotData1$sentiment, y = plotData1$Total)) +
        geom_bar(aes(fill = sentiment), stat = "identity") +
       theme(legend.position = "none") +
        xlab("Emotions") + ylab("Total") + ggtitle("Emotion for Search Term Trump")+
   geom_text(aes(label =   plotData1$Total), position = position_dodge(width=0.75), vjust = -0.25)

plotData2 =gather(TrumpSearchFinalData,"Polarity","values",25:26)  %>% 
  group_by( Polarity) %>%
  summarise(Total = sum(values))

ggplot(data = plotData2, aes(x = plotData2$Polarity, y = plotData2$Total)) +
        geom_bar(aes(fill = plotData2$Polarity), stat = "identity") +
       theme(legend.position = "none") +
        xlab("Sentiment") + ylab("Total") + ggtitle("Sentiment for Search Term Trump")+
  geom_text(aes(label =   plotData2$Total), position = position_dodge(width=0.75), vjust = -0.25)

Sentiment @realDonaldTrump

In this section I focused on Donal Trumps personal twitter handle.The data set includes retwitts and ranges from 2/2016-12/2016. I also try to make sense of the emotions and sentiment by plotting the data monthly.

head( TrumpPersonalText,5)
[1] "\"@mike_pence: Congratulations to @RealDonaldTrump; officially elected President of the United States today by the Electoral College!\""                                                                                                                                                                                                                                                                                                                            
[2] "\"@Franklin_Graham: Congratulations to President-elect @realDonaldTrump--the electoral votes are in and it's official.\" Thank you Franklin!"                                                                                                                                                                                                                                                                                                                       
[3] "RT @DanScavino: #TrumpTrain<ed><U+00A0><U+00BD><ed><U+00BA><U+0082><ed><U+00A0><U+00BD><ed><U+00B2><U+00A8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8> https://t.co/qAQdBGEwSv"
[4] "We did it! Thank you to all of my great supporters, we just officially won the election (despite all of the distorted and inaccurate media)."                                                                                                                                                                                                                                                                                                                       
[5] "Today there were terror attacks in Turkey, Switzerland and Germany - and it is only getting worse. The civilized world must change thinking!"                                                                                                                                                                                                                                                                                                                       
"@mike_pence: Congratulations to @RealDonaldTrump; officially elected President of the United States today by the Electoral College!"

"@Franklin_Graham: Congratulations to President-elect @realDonaldTrump--the electoral votes are in and it's official." Thank you Franklin!

RT @DanScavino: #TrumpTrain<ed><U+00A0><U+00BD><ed><U+00BA><U+0082><ed><U+00A0><U+00BD><ed><U+00B2><U+00A8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8><ed><U+00A0><U+00BC><ed><U+00B7><U+00BA><ed><U+00A0><U+00BC><ed><U+00B7><U+00B8> https://t.co/qAQdBGEwSv

We did it! Thank you to all of my great supporters, we just officially won the election (despite all of the distorted and inaccurate media).

Today there were terror attacks in Turkey, Switzerland and Germany - and it is only getting worse. The civilized world must change thinking!
 cleanTweetp = gsub("rt|RT", "", TrumpPersonalText) # remove Retweet
cleanTweetp = gsub("http\\w+", "", cleanTweetp)  # remove links http
cleanTweetp = gsub("<.*?>", "", cleanTweetp) # remove html tags
cleanTweetp = gsub("@\\w+", "", cleanTweetp) # remove at(@)
cleanTweetp = gsub("[[:punct:]]", "", cleanTweetp) # remove punctuation
cleanTweetp  = gsub("\r?\n|\r", " ", cleanTweetp) # remove /n
cleanTweetp = gsub("[[:digit:]]", "", cleanTweetp) # remove numbers/Digits
cleanTweetp = gsub("㠼|㸵|㤼|㸲|㸱|㸳|㸴|㸶|攼|㹤", "", cleanTweetp) #  asian letters
cleanTweetp = gsub("[ |\t]{2,}", "", cleanTweetp) # remove tabs
cleanTweetp = gsub("^ ", "", cleanTweetp)  # remove blank spaces at the beginning
cleanTweetp = gsub(" $", "", cleanTweetp) # remove blank spaces at the end 

TrumpPersonalSentiment = get_nrc_sentiment(cleanTweetp)
head(TrumpPersonalSentiment,5)
  anger anticipation disgust fear joy sadness surprise trust negative
1     0            0       0    0   0       0        0     2        0
2     0            0       0    0   0       0        0     1        0
3     0            0       0    0   0       0        0     0        0
4     0            0       0    0   0       0        0     0        1
5     0            0       0    3   1       1        0     1        2
  positive
1        2
2        0
3        0
4        0
5        1
TrumpPersonalFinalData = cbind(TrumpPersonal,TrumpPersonalSentiment)

plotData3 =gather(TrumpPersonalFinalData,"sentiment","values",17:24)  %>% 
  group_by( sentiment) %>%
  summarise(Total = sum(values))

ggplot(data = plotData3, aes(x = plotData3$sentiment, y = plotData3$Total)) +
        geom_bar(aes(fill = sentiment), stat = "identity") +
       theme(legend.position = "none") +
        xlab("Sentiment") + ylab("Total") + ggtitle("Emotions for @realDonaldTrump")+
   geom_text(aes(label =   plotData3$Total), position = position_dodge(width=0.75), vjust = -0.25)

plotData4 =gather(TrumpPersonalFinalData,"Polarity","values",25:26)  %>% 
  group_by( Polarity) %>%
  summarise(Total = sum(values))

ggplot(data = plotData4, aes(x = plotData4$Polarity, y = plotData4$Total)) +
        geom_bar(aes(fill = plotData4$Polarity), stat = "identity") +
       theme(legend.position = "none") +
        xlab("Sentiment") + ylab("Total") + ggtitle("Sentiment for @realDonaldTrump")+
  geom_text(aes(label =   plotData4$Total), position = position_dodge(width=0.75), vjust = -0.25)

plotData5 = select(TrumpPersonalFinalData,created,17:24)
 plotData5 = separate(plotData5,created,c("date","Time")," ") %>%
  group_by(date)%>%
   summarise(Anger=sum(anger), Anticipation=sum(anticipation), Disgust=sum(disgust), Fear=sum(fear), Joy=sum(joy), Sadness=sum(sadness), Surprise=sum(surprise), Trust=sum(trust))
 
 plotData5$date = as.Date(plotData5$date,"%Y-%m-%d") 

 plotData5$date <- as.Date(cut(plotData5$date, breaks = "month"))
 
  plotData5 = gather(plotData5,"sentiment","values",2:9)%>%
        group_by(date,sentiment)%>%
    summarise(Total=sum(values))
  
ggplot(data = plotData5, aes(x = plotData5$date, y = plotData5$Total, group = plotData5$sentiment)) +
        geom_line(size = 2.5, alpha = 0.7, aes(color = sentiment,stat = "identity")) +
        geom_point(size = 0.5) +
        #ylim(0, 0.6) +
        theme(legend.title=element_blank(), axis.title.x = element_blank()) +
        ylab("Total") + 
        ggtitle("Emotions of @realDonaldTrump 2/2016-12/2016")+
  scale_y_continuous(limits=c(0,300)) 

plotData6 =gather(TrumpPersonalFinalData,"Polarity","values",25:26)  %>% 
  group_by( created,Polarity) %>%
  summarise(Total = sum(values))
 plotData6 = separate(plotData6,created,c("date","Time")," ")
 plotData6$date = as.Date(plotData6$date,"%Y-%m-%d") 
 plotData6$date <- as.Date(cut(plotData6$date, breaks = "month"))


  plotData6 = select(plotData6,date,Polarity,Total)%>%
    group_by(date,Polarity)%>%
    summarise(Total = sum(Total))

  ggplot(data = plotData6, aes(x = plotData6$date, y = plotData6$Total, group = plotData6$Polarity)) +
        geom_line(size = 2.5, alpha = 0.7, aes(color = plotData6$Polarity,stat = "identity")) +
        geom_point(size = 0.5) +
        #ylim(0, 0.6) +
        theme(legend.title=element_blank(), axis.title.x = element_blank()) +
        ylab("Total") + 
        ggtitle("Sentiment of @realDonaldTrump 2/2016-12/2016")+
  scale_y_continuous(limits=c(0,500)) 

Wordcloud @realDonaldTrump

vector = TrumpPersonal$text
Corpus <- Corpus(VectorSource(vector))
Corpus = tm_map(Corpus,removeNumbers)
Corpus = tm_map(Corpus,str_replace_all,pattern = "http\\w+", replacement =" ")
Corpus = tm_map(Corpus,str_replace_all,pattern = "<.*?>", replacement =" ")
Corpus = tm_map(Corpus,str_replace_all,pattern = "@\\w+", replacement =" ")
Corpus = tm_map(Corpus,str_replace_all,pattern ="\\=", replacement =" ")
Corpus = tm_map(Corpus,str_replace_all,pattern = "[[:punct:]]", replacement =" ")
Corpus = tm_map(Corpus,str_replace_all,pattern = "amp", replacement =" ")
Corpus = tm_map(Corpus,removeWords, words= stopwords("en"))
Corpus = tm_map(Corpus,tolower)
Corpus = tm_map(Corpus,stripWhitespace)
Corpus = tm_map(Corpus, PlainTextDocument)

tdm = TermDocumentMatrix(Corpus)
tdm
<<TermDocumentMatrix (terms: 6678, documents: 3195)>>
Non-/sparse entries: 31745/21304465
Sparsity           : 100%
Maximal term length: 28
Weighting          : term frequency (tf)
wordcloud(words = Corpus, 
          max.words=200, random.order=FALSE, rot.per=0.35, 
          colors=brewer.pal(8, "Dark2"))

failed Attempt

# 
# 
# #Data Manipulation and Algorithm Implementation
# #tweets.text = laply(tweets, function(t)t$getText())
# 
# #now if you haven’t download the documents that Michael mention on his video, you definitely need to do it now. Remember to save them in the same folder that your R code
# 
# score.sentiment = function(sentences, positiveWords, negativeWords, .progress='none')
# {
# require(plyr)
# require(stringr)
# 
# # we got a vector of sentences. plyr will handle a list or a vector as an “l” for us
# # we want a simple array of scores back, so we use “l” + “a” + “ply” = laply:
# scores = laply(sentences, function(sentence, positiveWords, negativeWords) {
# 
# # clean up sentences with R’s regex-driven global substitute, gsub():
# sentence = gsub('[[:punct:]]', '', sentence)
# sentence = gsub('[[:cntrl:]]', '', sentence)
# sentence = gsub('\\d+', '', sentence)
# # and convert to lower case:
# sentence = tolower(sentence)
# 
# # split into words. str_split is in the stringr package
# word.list = str_split(sentence, '\\s+')
# # sometimes a list() is one level of hierarchy too much
# words = unlist(word.list)
# 
# # compare our words to the dictionaries of positive & negative terms
# pos.matches = match(words, positiveWords)
# neg.matches = match(words, negativeWords)
# 
# # match() returns the position of the matched term or NA
# # we just want a TRUE/FALSE:
# pos.matches = !is.na(pos.matches)
# neg.matches = !is.na(neg.matches)
# 
# # and conveniently enough, TRUE/FALSE will be treated as 1/0 by sum():
# score = sum(pos.matches) - sum(neg.matches)
# 
# return(score)
# }, positiveWords,negativeWords, .progress=.progress )
# 
# scores.df = data.frame(score=scores, text=sentences)
# return(scores.df)
# }
# 
# #this positive and negative words are related to abortion
# positiveWords = scan('positive.txt',what = 'character', comment.char = ';')
# negativeWords = scan('negative.txt',what = 'character', comment.char = ';')
# 
# #Analyse the results
# 
# analysis = score.sentiment(mydf, pos.words, neg.words,.progress='none')
#  table(analysis$score)
#  mean(analysis$score)
#  median(analysis$score)
#  hist(analysis$score)

Conclusion

Sentiment analysis can be applied to many topics.It was interesting to see how he was relating a positive message within his twitter handle.This overshadow the negativity. Also towards november Trust emotion was very high indicating support and self confidence. In the instance were the term trump was search suprise seem to be the overwhelming emotion.

LS0tDQp0aXRsZTogIjYwNyBGaW5hbCBQcm9qZWN0IC0gU2VudGltZW50IEFuYWx5c2lzIFR3aXR0ZXIgIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0aGVtZTogY29zbW8NCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCg0KbGlicmFyeSgidGlkeXIiKQ0KbGlicmFyeSgiZHBseXIiKQ0KbGlicmFyeSgidG0iKQ0KbGlicmFyeSgiUkN1cmwiKQ0KI2xpYnJhcnkoIlJPQXV0aCIpDQpsaWJyYXJ5KCJ0d2l0dGVSIikNCmxpYnJhcnkoInN0cmluZ3IiKQ0KbGlicmFyeSgic3l1emhldCIpDQpsaWJyYXJ5KCJsdWJyaWRhdGUiKQ0KbGlicmFyeSgiZ2dwbG90MiIpDQpsaWJyYXJ5KCJ3b3JkY2xvdWQiKQ0KbGlicmFyeSgiUkNvbG9yQnJld2VyIikNCmBgYA0KI0luaXRpYWwgUHJvcG9zYWwNCldlZWsgdGVuIHdhcyBhbiBpbnRlcmVzdGluZyB3ZWVrIHdlcmUgc2VudGltZW50IGFuYWx5c2lzIHdhcyBpbnRyb2R1Y2VkLiBJbiB3ZWVrIHRlbiBkaXNjdXNzaW9uIEkgcG9zdGVkIHJlZ2FyZGluZyBHYW1lIG9mIHRocm9uZXMgYW5kIHNlbnRpbWVudCBhbmFseXNpcyBmb3Igc2Vhc29uIDYgcHJlbWllcmUuIEkgZmVlbCB0aGF0IHdlIGRpZCBub3QgY292ZXIgdGhlIHRvcGljIGluIGRlcHRoIHNvIG15IHByb3Bvc2FsIGlzIHRoZSBmb2xsb3dpbmcuDQpUaGUgZWxlY3Rpb24gaXMgb3ZlciBhbmQgdW5sZXNzIHRoZSBlbGVjdG9yYWwgY29sbGVnZSB2b3RlcyBhZ2FpbnN0IERvbmFsZCBUcnVtcCBoZSB3aWxsIGJlIHByZXNpZGVudC4gSSB3YW50IHRvIGRvIHNlbnRpbWVudCBhbmFseXNpcyB1c2luZyB0d2l0dGVyLiBNeSBwcmltYXJ5IGdvYWwgaXMgdG8gY2FwdHVyZSB0aGUgbW9vZCBvZiB0aGUgcGVvcGxlIHdpdGhpbiB0aGUgbW9udGggb2YgTm92ZW1iZXIgYW5kIERlY2VtYmVyLCBjbGFzc2lmeSB0d2l0cyBhcyBwb3NpdGl2ZSwgbmVnYXRpdmUsIG9yIG5ldXRyYWwsIGFuZCBpZGVudGlmeSB0aGVzZSB3b3Jkcy4gSSB3aWxsIGltcGxlbWVudCBsZWFybmVkIG1hdGVyaWFsIGFuZCBpbXBsZW1lbnRlZCBpbiB0aGUgc3Bpcml0IG9mIHRoZSBjbGFzcy4NCg0KMQlTY3JhcGUgdHdpdHRlciBmb3IgZGF0YSByZWdhcmRpbmcgdGhlIGVsZWN0aW9uIChtZXNzYWdlLCBkYXRlLCBNYXliZSBnZW9ncmFwaGljYWwgbG9jYXRpb24pIA0KDQoyCUFmdGVyIGNsZWFuaW5nIHRoZSBkYXRhLCBJIHdpbGwgdXNlIE1vbmdvIGRCIHRvIHN0b3JlIGluZm9ybWF0aW9uIA0KDQozCUFuYWx5c2lzIGlzIGdvaW5nIHRvIGJlIHBlcmZvcm0gYnkgcXVlcnlpbmcgTW9uZ28gZEIgYW5kIHVzaW5nIGdncGxvdDIgDQoNCkkgd2lsbCB1c2UgUiwgTW9uZ28gZEIsIFR3aXR0ZXIsIFIgcGFja2FnZXMgKHRpZHlyLCBkcGx5ciwgdG0sIGdncGxvdDIpDQoNCg0KI0ludHJvDQpUaGUgZ29hbCBvZiB0aGlzIG15IGZpbmFsIHByb2plY3Qgd2FzIHRvIGJlIGFibGUgdG8gZ2F0aGVyIGluZm9ybWF0aW9uIGZyb20gYSBzb2NpYWwgd2Vic2l0ZSBjbGVhbiB0aGlzIGRhdGEgdHJhbnNmb3JtIHRoZSBkYXRhLCBhbmQgY2xhc3NpZnkgaXQuIFRoZSB0b3BpYyBpbnRyaWdlIG1lIGR1ZSB0byB0aGUgbWFueSBhcHBsaWNhdGlvbiB0aGF0IGNhbiBiZSBhY2hpdmVkLkkgc2VlIHRoaXMgcHJvamVjdCBhcyBhIHNtYWxsIHN0ZXAgaW50byBpbnBsZW1lbnRpbmcgYSBzZW50aW1lbnQgbWFya2V0IHJlYXNlYXJjaCB0b29sIHdpdGggdGhlIGluY2x1c2lvbiBvZiBtYW55IG90aGVyIHNvY2lhbCBtZWRpYSBzaXRlcy4NCg0KDQoNCiNUd2l0dGVyDQpJIGZpcnN0IHN0YXJ0IGJ5IGNvbm5lY3RpbmcgdG8gdGhlIFR3aXR0ZXIgQVBJLiBJIGZpcnN0IHRyaWVkIHRvIGNvbm5lY3QgdXNpbmcgI2xpYnJhcnkoIlJPQXV0aCIpIGJ1dCBkdWUgdG8gdGhlIGFwaSBub3QgdmFsaWRhdGluZyBteSBhY2Nlc3MgY29kZSBJIHNlYXJjaCBmb3IgYSBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb24uIFdoYXQgd29ya2VkIGZvciBtZSB3YXMgdXNpbmcgZGlyZWN0IGFjY2VzcyAgYXV0aGVudGljYXRpb24gd2l0aCB0aGUgVHdpdHRlciBBUEkuDQpgYGB7cn0NCg0KDQoNCiNvcHRpb25zKFJDdXJsT3B0aW9ucyA9IGxpc3QoY2FpbmZvID0gc3lzdGVtLmZpbGUoIkN1cmxTU0wiLCAiY2FjZXJ0LnBlbSIsIHBhY2thZ2UgPSAiUkN1cmwiKSkpDQpjb25zdW1lcktleSA9ICIiIA0KY29uc3VtZXJTZWNyZXQgPSAiIg0KYWNjZXNzVG9rZW4gPSIiDQphY2Nlc3NUb2tlblNlY3JldD0iIg0KDQojcmVxVVJMID0gImh0dHBzOi8vYXBpLnR3aXR0ZXIuY29tL29hdXRoL3JlcXVlc3RfdG9rZW4iICNpbXBvcnRhbnQgYXQgdGhlIG1vbWVudCB0aGF0IGl0IGlzIGh0dHBzICBUd2l0dGVyIG5lZWRzIGEgc2VjdXJlIGNvbm5lY3Rpb24NCiNhY2Nlc3NVUkwgPSAiaHR0cHM6Ly9hcGkudHdpdHRlci5jb20vb2F1dGgvYWNjZXNzX3Rva2VuIg0KI2F1dGhVUkwgPSAiaHR0cHM6Ly9hcGkudHdpdHRlci5jb20vb2F1dGgvYXV0aG9yaXplIg0KI3R3aXRDcmVkID0gT0F1dGhGYWN0b3J5JG5ldyhjb25zdW1lcktleT1jb25zdW1lcktleSxjb25zdW1lclNlY3JldD1jb25zdW1lclNlY3JldCxyZXF1ZXN0VVJMPXJlcVVSTCxhY2Nlc3NVUkw9YWNjZXNzVVJMLGF1dGhVUkw9YXV0aFVSTCkNCiN0d2l0Q3JlZCRoYW5kc2hha2UoKSANCiNyZWdpc3RlclR3aXR0ZXJPQXV0aCh0d2l0Q3JlZCkNCg0KDQojc2V0dXBfdHdpdHRlcl9vYXV0aChjb25zdW1lcktleSxjb25zdW1lclNlY3JldCxhY2Nlc3NUb2tlbixhY2Nlc3NUb2tlblNlY3JldCkNCmBgYA0KDQojRGF0YSBBY3F1aXNpdGlvbg0KSSB1c2VkIHR3byBzZWFyY2ggbWV0aG9kcyB3aXRoIFR3aXR0ZVIgYW5kIHRoZSBBUEkgY29ubmVjdGlvbi5UaGUgZmlyc3Qgd2FzIHRoZSBTZWFyY2ggVHdpdHRlciBhbmQgdGhlIHNlY29uZCBvbmUgR2V0VXNlci5UaGlzIGFsbG93ZWQgbWUgdHdvIGdldCB0d28gZGlmZmVyZW50IGRhdGEgc291cmNlcyBhbmQgYXBwbHkgc2VudGltZW50IGFuYWx5c2lzLkluIG15IGZpcnN0IG1ldGhvZCBJIHNlYXJjaGVkIGZvciBUcnVtcCBhbmQgZG93bG9hZGVkIDEwLDAwMCBUd2l0dHMuVGhlIHNlY29uZCBtZXRob2RlIEkgdXNlZCBEb25hbGQgVHJ1bXAgVHdpdHRlciBoYW5kbGUgdG8gY29sbGVjdCBhbGwgaGlzIHR3aXR0ZXIgZmVlZHMuSSBhbHNvIHRyaWVkIGdldHRpbmcgaGlzIDE3LjcgTSBmb2xsb3dlcnMgYnV0IHdoZW4gSSBzZWFyY2ggdG8gZG93bmxvYWQgdGhlIGRpcmVjdCBjb25uZWN0aW9uIG9ubHkgcHJvZHVjZWQgNTYgZmFsbG93ZXJzLkZpbmFsbHkgZWFjaCBmaWxlIHdlcmUgZXhwb3J0ZWQgdG8gYSBDU1YgZmlsZSB0aGF0IHdhcyBsYXRlciB1cGxvYWRlZCB0byBHaXRIdWIuDQpgYGB7cn0NCg0KI3R3ZWV0cz1zZWFyY2hUd2l0dGVyKCJ0cnVtcCIsIG49MTAwMDAsbGFuZyA9ICJlbiIpDQojZGYgPSBkby5jYWxsKCJyYmluZCIsIGxhcHBseSh0d2VldHMsIGFzLmRhdGEuZnJhbWUpKQ0KDQojd3JpdGUuY3N2KGRmLCAiVHJ1bXAxMDAwMFR3ZWV0cy5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQoNCg0KI1RydW1wVHdpdGVyQWNjdCA8LSBnZXRVc2VyKCJyZWFsRG9uYWxkVHJ1bXAiKQ0KI2RvbmFsZHR3ZWV0c2xpc3QgPSB1c2VyVGltZWxpbmUoVHJ1bXBUd2l0ZXJBY2N0LCBuPTMyMDAsIGluY2x1ZGVSdHM9VFJVRSwgZXhjbHVkZVJlcGxpZXM9VFJVRSkNCiN0dW1wcHJvZmlsZXR3ZWV0c2RmID0gZG8uY2FsbCgicmJpbmQiLCBsYXBwbHkoZG9uYWxkdHdlZXRzbGlzdCwgYXMuZGF0YS5mcmFtZSkpDQojd3JpdGUuY3N2KHR1bXBwcm9maWxldHdlZXRzZGYsICJyZWFsRG9uYWxkVHJ1bXAzMjAwVHdlZXRzLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCg0KYGBgDQoNCg0KI0dpdGh1Yg0KQWZ0ZXIgdXBsb2FkaW5nIHRoZSBkYXRhIHRvIGdpdGh1YiBJIHVzZXIgUmN1cmwgdG8gYnJpbmcgaXQgYmFjayB0byBteSBwcm9qZWN0LiBUaGlzIHdhcyBkb25lIGluIG9yZGVyIHRvIG9idGFpbiBhIHJlcHJvZHVjaWJsZSBleGFtcGxlLg0KYGBge3J9DQp1cmwxID0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9jaHJpc2VzdGV2ZXovRGF0YUFuYWx5dGljc1Byb2plY3RzL21hc3Rlci9GaW5hbFByb2plY3QvVHJ1bXAxMDAwMFR3ZWV0cy5jc3YiDQpSZGF0YTEgPSBnZXRVUkwodXJsMSkNClRydW1wU2VhcmNoID0gcmVhZC5jc3YodGV4dCA9IFJkYXRhMSxoZWFkZXIgPSBUUlVFLHN0cmluZ3NBc0ZhY3RvcnMgPSBGLHNlcD0iLCIpDQpoZWFkKFRydW1wU2VhcmNoLDUpDQoNClRydW1wU2VhcmNoVGV4dCAgPSBhcy52ZWN0b3IoVHJ1bXBTZWFyY2gkdGV4dCkNCg0KdXJsMiA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY2hyaXNlc3RldmV6L0RhdGFBbmFseXRpY3NQcm9qZWN0cy9tYXN0ZXIvRmluYWxQcm9qZWN0L3JlYWxEb25hbGRUcnVtcDMyMDBUd2VldHMuY3N2Ig0KUmRhdGEyID0gZ2V0VVJMKHVybDIpDQpUcnVtcFBlcnNvbmFsID0gcmVhZC5jc3YodGV4dCA9IFJkYXRhMixoZWFkZXIgPSBUUlVFLHN0cmluZ3NBc0ZhY3RvcnMgPSBGLHNlcD0iLCIpDQpUcnVtcFBlcnNvbmFsVGV4dCAgPSBhcy52ZWN0b3IoVHJ1bXBQZXJzb25hbCR0ZXh0KQ0KaGVhZChUcnVtcFBlcnNvbmFsLDUpDQoNCmBgYA0KDQojc3l1emhldA0KVGhlIHNlbnRpbWVudCBhbmFseXNpcyBhbGdvcml0aG0gdXNlZCBoZXJlIGlzIGJhc2VkIG9uIHRoZSBXb3JkLUVtb3Rpb24gQXNzb2NpYXRpb24gb2YgU2FpZiBNb2hhbW1hZCBhbmQgUGV0ZXIgVHVybmV5LiBUaGUgdXNlIGEgZGljdGlvbmFyeSB0aGF0IGFzc29jaWF0ZXMgdGhlIHdvcmRzIHRvIGVpZ2h0IGRpZmZlcmVudCBlbW90aW9ucyBhbmQgYSBuZWdhdGl2ZS9Qb3NpdGl2ZSBzZW50aW1lbnQuUGxlYXNlIHNlZSBleG1hcGxlcyBiZWxvdy4NCmBgYHtyfQ0KZ2V0X25yY19zZW50aW1lbnQoIkRvbmFsIFRydW1wIGlzIGF3ZXNvbWUgYW5kIGFtYXppbmcgSSdtIGhhcHB5IGhlIGlzIHJ1bm5pbmcgZm9yIHByZXNpZGVudCIpDQoNCmdldF9ucmNfc2VudGltZW50KCJJIGhhdGUgRG9uYWwgVHJ1bXAgaGUgaXMgYSBsaWFyIGFuZCBkZWNlaXZpbmcgcGVyc29uIikNCmBgYA0KDQojMTAsMDAwIFR3aXR0cw0KSW4gdGhpcyBwYXJ0IG9mIHRoZSBwcm9qZWN0IEkgaW52ZXN0aWdhdGUgdG8gc2VlIGlmIHRoZXJlIGlzIGFueSBwYXR0ZXJuIGluIGVtb3Rpb24gb3Igc2VudGltZW50IGJ5IHRoZSBUd2l0dGVyIENvbW11bml0eS5JIGJlZ2luIGJ5IHVzaW5nIHRoZSBhY3F1aXJlIGRhdGEgdGhhdCB3YXMgb2J0YWluIGJ5IHNlYXJjaGluZyBmb3IgdGhlIHRlcm0gVHJ1bXAuIFRoZSB0d2l0dHMgd2VyZSBjb252ZXJ0ZWQgaW50byBhIHZlY3RvciBpbiBvcmRlciB0byBwcm9jZXNzIGVmZmVjdGl2ZWx5IHRoZSBkYXRhLiBJIHVzZWQgZ3N1YiB0byByZW1vdmUgdmFyaW91cyB1bndhbnRlZCB0ZXJtcy4gSSBsYXRlciBhcHBsaWVkIHRoZSBzZW50aW1lbnQgYWxnb3JpdGhtIGFuZCBtZXJnZSB0aGUgcmVzdWx0cyB0byB0aGUgb3JpZ2luYWwgZGF0YS5BZnRlciBtZXJnaW5nIHRoZSBkYXRhIEkgdXNlZCBkcGx5ciBhbmQgdGlkeXIgdG8gdHJhbnNmb3JtIGFuZCBwbG90IHRoZSBkYXRhIHVzaW5nIGdncGxvdDIuDQpgYGB7cn0NCmhlYWQoVHJ1bXBTZWFyY2hUZXh0LDUpDQoNCiBjbGVhblR3ZWV0ID0gZ3N1YigicnR8UlQiLCAiIiwgVHJ1bXBTZWFyY2hUZXh0KSAjIHJlbW92ZSBSZXR3ZWV0DQpjbGVhblR3ZWV0ID0gZ3N1YigiaHR0cFxcdysiLCAiIiwgY2xlYW5Ud2VldCkgICMgcmVtb3ZlIGxpbmtzIGh0dHANCmNsZWFuVHdlZXQgPSBnc3ViKCI8Lio/PiIsICIiLCBjbGVhblR3ZWV0KSAjIHJlbW92ZSBodG1sIHRhZ3MNCmNsZWFuVHdlZXQgPSBnc3ViKCJAXFx3KyIsICIiLCBjbGVhblR3ZWV0KSAjIHJlbW92ZSBhdChAKQ0KY2xlYW5Ud2VldCA9IGdzdWIoIltbOnB1bmN0Ol1dIiwgIiIsIGNsZWFuVHdlZXQpICMgcmVtb3ZlIHB1bmN0dWF0aW9uDQpjbGVhblR3ZWV0ICA9IGdzdWIoIlxyP1xufFxyIiwgIiAiLCBjbGVhblR3ZWV0KSAjIHJlbW92ZSAvbg0KY2xlYW5Ud2VldCA9IGdzdWIoIltbOmRpZ2l0Ol1dIiwgIiIsIGNsZWFuVHdlZXQpICMgcmVtb3ZlIG51bWJlcnMvRGlnaXRzDQpjbGVhblR3ZWV0ID0gZ3N1Yigi46C8fOO4tXzjpLx847iyfOO4sXzjuLN847i0fOO4tnzmlLx847mkIiwgIiIsIGNsZWFuVHdlZXQpICMgIGFzaWFuIGxldHRlcnMNCmNsZWFuVHdlZXQgPSBnc3ViKCJbIHxcdF17Mix9IiwgIiIsIGNsZWFuVHdlZXQpICMgcmVtb3ZlIHRhYnMNCmNsZWFuVHdlZXQgPSBnc3ViKCJeICIsICIiLCBjbGVhblR3ZWV0KSAgIyByZW1vdmUgYmxhbmsgc3BhY2VzIGF0IHRoZSBiZWdpbm5pbmcNCmNsZWFuVHdlZXQgPSBnc3ViKCIgJCIsICIiLCBjbGVhblR3ZWV0KSAjIHJlbW92ZSBibGFuayBzcGFjZXMgYXQgdGhlIGVuZCANCg0KVHJ1bXBTZWFyY2hTZW50aW1lbnQgPSBnZXRfbnJjX3NlbnRpbWVudChjbGVhblR3ZWV0KQ0KaGVhZChUcnVtcFNlYXJjaFNlbnRpbWVudCw1KQ0KVHJ1bXBTZWFyY2hGaW5hbERhdGEgPSBjYmluZChUcnVtcFNlYXJjaCxUcnVtcFNlYXJjaFNlbnRpbWVudCkNCg0KcGxvdERhdGExID1nYXRoZXIoVHJ1bXBTZWFyY2hGaW5hbERhdGEsInNlbnRpbWVudCIsInZhbHVlcyIsMTc6MjQpICAlPiUgDQogIGdyb3VwX2J5KCBzZW50aW1lbnQpICU+JQ0KICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkNCg0KZ2dwbG90KGRhdGEgPSBwbG90RGF0YTEsIGFlcyh4ID0gcGxvdERhdGExJHNlbnRpbWVudCwgeSA9IHBsb3REYXRhMSRUb3RhbCkpICsNCiAgICAgICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSBzZW50aW1lbnQpLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgICAgICB4bGFiKCJFbW90aW9ucyIpICsgeWxhYigiVG90YWwiKSArIGdndGl0bGUoIkVtb3Rpb24gZm9yIFNlYXJjaCBUZXJtIFRydW1wIikrDQogICBnZW9tX3RleHQoYWVzKGxhYmVsID0gICBwbG90RGF0YTEkVG90YWwpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNzUpLCB2anVzdCA9IC0wLjI1KQ0KDQpwbG90RGF0YTIgPWdhdGhlcihUcnVtcFNlYXJjaEZpbmFsRGF0YSwiUG9sYXJpdHkiLCJ2YWx1ZXMiLDI1OjI2KSAgJT4lIA0KICBncm91cF9ieSggUG9sYXJpdHkpICU+JQ0KICBzdW1tYXJpc2UoVG90YWwgPSBzdW0odmFsdWVzKSkNCg0KZ2dwbG90KGRhdGEgPSBwbG90RGF0YTIsIGFlcyh4ID0gcGxvdERhdGEyJFBvbGFyaXR5LCB5ID0gcGxvdERhdGEyJFRvdGFsKSkgKw0KICAgICAgICBnZW9tX2JhcihhZXMoZmlsbCA9IHBsb3REYXRhMiRQb2xhcml0eSksIHN0YXQgPSAiaWRlbnRpdHkiKSArDQogICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgICAgIHhsYWIoIlNlbnRpbWVudCIpICsgeWxhYigiVG90YWwiKSArIGdndGl0bGUoIlNlbnRpbWVudCBmb3IgU2VhcmNoIFRlcm0gVHJ1bXAiKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9ICAgcGxvdERhdGEyJFRvdGFsKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjc1KSwgdmp1c3QgPSAtMC4yNSkNCg0KYGBgDQoNCiNTZW50aW1lbnQgQHJlYWxEb25hbGRUcnVtcA0KSW4gdGhpcyBzZWN0aW9uIEkgZm9jdXNlZCBvbiBEb25hbCBUcnVtcHMgcGVyc29uYWwgdHdpdHRlciBoYW5kbGUuVGhlIGRhdGEgc2V0IGluY2x1ZGVzIHJldHdpdHRzIGFuZCByYW5nZXMgZnJvbSAyLzIwMTYtMTIvMjAxNi4gSSBhbHNvIHRyeSB0byBtYWtlIHNlbnNlIG9mIHRoZSBlbW90aW9ucyBhbmQgc2VudGltZW50IGJ5IHBsb3R0aW5nIHRoZSBkYXRhIG1vbnRobHkuDQpgYGB7cn0NCmhlYWQoIFRydW1wUGVyc29uYWxUZXh0LDUpDQogY2xlYW5Ud2VldHAgPSBnc3ViKCJydHxSVCIsICIiLCBUcnVtcFBlcnNvbmFsVGV4dCkgIyByZW1vdmUgUmV0d2VldA0KY2xlYW5Ud2VldHAgPSBnc3ViKCJodHRwXFx3KyIsICIiLCBjbGVhblR3ZWV0cCkgICMgcmVtb3ZlIGxpbmtzIGh0dHANCmNsZWFuVHdlZXRwID0gZ3N1YigiPC4qPz4iLCAiIiwgY2xlYW5Ud2VldHApICMgcmVtb3ZlIGh0bWwgdGFncw0KY2xlYW5Ud2VldHAgPSBnc3ViKCJAXFx3KyIsICIiLCBjbGVhblR3ZWV0cCkgIyByZW1vdmUgYXQoQCkNCmNsZWFuVHdlZXRwID0gZ3N1YigiW1s6cHVuY3Q6XV0iLCAiIiwgY2xlYW5Ud2VldHApICMgcmVtb3ZlIHB1bmN0dWF0aW9uDQpjbGVhblR3ZWV0cCAgPSBnc3ViKCJccj9cbnxcciIsICIgIiwgY2xlYW5Ud2VldHApICMgcmVtb3ZlIC9uDQpjbGVhblR3ZWV0cCA9IGdzdWIoIltbOmRpZ2l0Ol1dIiwgIiIsIGNsZWFuVHdlZXRwKSAjIHJlbW92ZSBudW1iZXJzL0RpZ2l0cw0KY2xlYW5Ud2VldHAgPSBnc3ViKCLjoLx847i1fOOkvHzjuLJ847ixfOO4s3zjuLR847i2fOaUvHzjuaQiLCAiIiwgY2xlYW5Ud2VldHApICMgIGFzaWFuIGxldHRlcnMNCmNsZWFuVHdlZXRwID0gZ3N1YigiWyB8XHRdezIsfSIsICIiLCBjbGVhblR3ZWV0cCkgIyByZW1vdmUgdGFicw0KY2xlYW5Ud2VldHAgPSBnc3ViKCJeICIsICIiLCBjbGVhblR3ZWV0cCkgICMgcmVtb3ZlIGJsYW5rIHNwYWNlcyBhdCB0aGUgYmVnaW5uaW5nDQpjbGVhblR3ZWV0cCA9IGdzdWIoIiAkIiwgIiIsIGNsZWFuVHdlZXRwKSAjIHJlbW92ZSBibGFuayBzcGFjZXMgYXQgdGhlIGVuZCANCg0KVHJ1bXBQZXJzb25hbFNlbnRpbWVudCA9IGdldF9ucmNfc2VudGltZW50KGNsZWFuVHdlZXRwKQ0KaGVhZChUcnVtcFBlcnNvbmFsU2VudGltZW50LDUpDQpUcnVtcFBlcnNvbmFsRmluYWxEYXRhID0gY2JpbmQoVHJ1bXBQZXJzb25hbCxUcnVtcFBlcnNvbmFsU2VudGltZW50KQ0KDQpwbG90RGF0YTMgPWdhdGhlcihUcnVtcFBlcnNvbmFsRmluYWxEYXRhLCJzZW50aW1lbnQiLCJ2YWx1ZXMiLDE3OjI0KSAgJT4lIA0KICBncm91cF9ieSggc2VudGltZW50KSAlPiUNCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpDQoNCmdncGxvdChkYXRhID0gcGxvdERhdGEzLCBhZXMoeCA9IHBsb3REYXRhMyRzZW50aW1lbnQsIHkgPSBwbG90RGF0YTMkVG90YWwpKSArDQogICAgICAgIGdlb21fYmFyKGFlcyhmaWxsID0gc2VudGltZW50KSwgc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICAgICAgeGxhYigiU2VudGltZW50IikgKyB5bGFiKCJUb3RhbCIpICsgZ2d0aXRsZSgiRW1vdGlvbnMgZm9yIEByZWFsRG9uYWxkVHJ1bXAiKSsNCiAgIGdlb21fdGV4dChhZXMobGFiZWwgPSAgIHBsb3REYXRhMyRUb3RhbCksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGg9MC43NSksIHZqdXN0ID0gLTAuMjUpDQoNCnBsb3REYXRhNCA9Z2F0aGVyKFRydW1wUGVyc29uYWxGaW5hbERhdGEsIlBvbGFyaXR5IiwidmFsdWVzIiwyNToyNikgICU+JSANCiAgZ3JvdXBfYnkoIFBvbGFyaXR5KSAlPiUNCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpDQoNCmdncGxvdChkYXRhID0gcGxvdERhdGE0LCBhZXMoeCA9IHBsb3REYXRhNCRQb2xhcml0eSwgeSA9IHBsb3REYXRhNCRUb3RhbCkpICsNCiAgICAgICAgZ2VvbV9iYXIoYWVzKGZpbGwgPSBwbG90RGF0YTQkUG9sYXJpdHkpLCBzdGF0ID0gImlkZW50aXR5IikgKw0KICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgICAgICB4bGFiKCJTZW50aW1lbnQiKSArIHlsYWIoIlRvdGFsIikgKyBnZ3RpdGxlKCJTZW50aW1lbnQgZm9yIEByZWFsRG9uYWxkVHJ1bXAiKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9ICAgcGxvdERhdGE0JFRvdGFsKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjc1KSwgdmp1c3QgPSAtMC4yNSkNCg0KDQpwbG90RGF0YTUgPSBzZWxlY3QoVHJ1bXBQZXJzb25hbEZpbmFsRGF0YSxjcmVhdGVkLDE3OjI0KQ0KIHBsb3REYXRhNSA9IHNlcGFyYXRlKHBsb3REYXRhNSxjcmVhdGVkLGMoImRhdGUiLCJUaW1lIiksIiAiKSAlPiUNCiAgZ3JvdXBfYnkoZGF0ZSklPiUNCiAgIHN1bW1hcmlzZShBbmdlcj1zdW0oYW5nZXIpLCBBbnRpY2lwYXRpb249c3VtKGFudGljaXBhdGlvbiksIERpc2d1c3Q9c3VtKGRpc2d1c3QpLCBGZWFyPXN1bShmZWFyKSwgSm95PXN1bShqb3kpLCBTYWRuZXNzPXN1bShzYWRuZXNzKSwgU3VycHJpc2U9c3VtKHN1cnByaXNlKSwgVHJ1c3Q9c3VtKHRydXN0KSkNCiANCiBwbG90RGF0YTUkZGF0ZSA9IGFzLkRhdGUocGxvdERhdGE1JGRhdGUsIiVZLSVtLSVkIikgDQoNCiBwbG90RGF0YTUkZGF0ZSA8LSBhcy5EYXRlKGN1dChwbG90RGF0YTUkZGF0ZSwgYnJlYWtzID0gIm1vbnRoIikpDQogDQogIHBsb3REYXRhNSA9IGdhdGhlcihwbG90RGF0YTUsInNlbnRpbWVudCIsInZhbHVlcyIsMjo5KSU+JQ0KICAgICAgICBncm91cF9ieShkYXRlLHNlbnRpbWVudCklPiUNCiAgICBzdW1tYXJpc2UoVG90YWw9c3VtKHZhbHVlcykpDQogIA0KZ2dwbG90KGRhdGEgPSBwbG90RGF0YTUsIGFlcyh4ID0gcGxvdERhdGE1JGRhdGUsIHkgPSBwbG90RGF0YTUkVG90YWwsIGdyb3VwID0gcGxvdERhdGE1JHNlbnRpbWVudCkpICsNCiAgICAgICAgZ2VvbV9saW5lKHNpemUgPSAyLjUsIGFscGhhID0gMC43LCBhZXMoY29sb3IgPSBzZW50aW1lbnQsc3RhdCA9ICJpZGVudGl0eSIpKSArDQogICAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDAuNSkgKw0KICAgICAgICAjeWxpbSgwLCAwLjYpICsNCiAgICAgICAgdGhlbWUobGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSArDQogICAgICAgIHlsYWIoIlRvdGFsIikgKyANCiAgICAgICAgZ2d0aXRsZSgiRW1vdGlvbnMgb2YgQHJlYWxEb25hbGRUcnVtcCAyLzIwMTYtMTIvMjAxNiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwzMDApKSANCg0KDQpwbG90RGF0YTYgPWdhdGhlcihUcnVtcFBlcnNvbmFsRmluYWxEYXRhLCJQb2xhcml0eSIsInZhbHVlcyIsMjU6MjYpICAlPiUgDQogIGdyb3VwX2J5KCBjcmVhdGVkLFBvbGFyaXR5KSAlPiUNCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKHZhbHVlcykpDQogcGxvdERhdGE2ID0gc2VwYXJhdGUocGxvdERhdGE2LGNyZWF0ZWQsYygiZGF0ZSIsIlRpbWUiKSwiICIpDQogcGxvdERhdGE2JGRhdGUgPSBhcy5EYXRlKHBsb3REYXRhNiRkYXRlLCIlWS0lbS0lZCIpIA0KIHBsb3REYXRhNiRkYXRlIDwtIGFzLkRhdGUoY3V0KHBsb3REYXRhNiRkYXRlLCBicmVha3MgPSAibW9udGgiKSkNCg0KDQogIHBsb3REYXRhNiA9IHNlbGVjdChwbG90RGF0YTYsZGF0ZSxQb2xhcml0eSxUb3RhbCklPiUNCiAgICBncm91cF9ieShkYXRlLFBvbGFyaXR5KSU+JQ0KICAgIHN1bW1hcmlzZShUb3RhbCA9IHN1bShUb3RhbCkpDQoNCiAgZ2dwbG90KGRhdGEgPSBwbG90RGF0YTYsIGFlcyh4ID0gcGxvdERhdGE2JGRhdGUsIHkgPSBwbG90RGF0YTYkVG90YWwsIGdyb3VwID0gcGxvdERhdGE2JFBvbGFyaXR5KSkgKw0KICAgICAgICBnZW9tX2xpbmUoc2l6ZSA9IDIuNSwgYWxwaGEgPSAwLjcsIGFlcyhjb2xvciA9IHBsb3REYXRhNiRQb2xhcml0eSxzdGF0ID0gImlkZW50aXR5IikpICsNCiAgICAgICAgZ2VvbV9wb2ludChzaXplID0gMC41KSArDQogICAgICAgICN5bGltKDAsIDAuNikgKw0KICAgICAgICB0aGVtZShsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgICAgICAgeWxhYigiVG90YWwiKSArIA0KICAgICAgICBnZ3RpdGxlKCJTZW50aW1lbnQgb2YgQHJlYWxEb25hbGRUcnVtcCAyLzIwMTYtMTIvMjAxNiIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCw1MDApKSANCiAgDQogIA0KYGBgDQoNCiNXb3JkY2xvdWQgQHJlYWxEb25hbGRUcnVtcA0KYGBge3J9DQp2ZWN0b3IgPSBUcnVtcFBlcnNvbmFsJHRleHQNCkNvcnB1cyA8LSBDb3JwdXMoVmVjdG9yU291cmNlKHZlY3RvcikpDQpDb3JwdXMgPSB0bV9tYXAoQ29ycHVzLHJlbW92ZU51bWJlcnMpDQpDb3JwdXMgPSB0bV9tYXAoQ29ycHVzLHN0cl9yZXBsYWNlX2FsbCxwYXR0ZXJuID0gImh0dHBcXHcrIiwgcmVwbGFjZW1lbnQgPSIgIikNCkNvcnB1cyA9IHRtX21hcChDb3JwdXMsc3RyX3JlcGxhY2VfYWxsLHBhdHRlcm4gPSAiPC4qPz4iLCByZXBsYWNlbWVudCA9IiAiKQ0KQ29ycHVzID0gdG1fbWFwKENvcnB1cyxzdHJfcmVwbGFjZV9hbGwscGF0dGVybiA9ICJAXFx3KyIsIHJlcGxhY2VtZW50ID0iICIpDQpDb3JwdXMgPSB0bV9tYXAoQ29ycHVzLHN0cl9yZXBsYWNlX2FsbCxwYXR0ZXJuID0iXFw9IiwgcmVwbGFjZW1lbnQgPSIgIikNCkNvcnB1cyA9IHRtX21hcChDb3JwdXMsc3RyX3JlcGxhY2VfYWxsLHBhdHRlcm4gPSAiW1s6cHVuY3Q6XV0iLCByZXBsYWNlbWVudCA9IiAiKQ0KQ29ycHVzID0gdG1fbWFwKENvcnB1cyxzdHJfcmVwbGFjZV9hbGwscGF0dGVybiA9ICJhbXAiLCByZXBsYWNlbWVudCA9IiAiKQ0KQ29ycHVzID0gdG1fbWFwKENvcnB1cyxyZW1vdmVXb3Jkcywgd29yZHM9IHN0b3B3b3JkcygiZW4iKSkNCkNvcnB1cyA9IHRtX21hcChDb3JwdXMsdG9sb3dlcikNCkNvcnB1cyA9IHRtX21hcChDb3JwdXMsc3RyaXBXaGl0ZXNwYWNlKQ0KQ29ycHVzID0gdG1fbWFwKENvcnB1cywgUGxhaW5UZXh0RG9jdW1lbnQpDQoNCnRkbSA9IFRlcm1Eb2N1bWVudE1hdHJpeChDb3JwdXMpDQp0ZG0NCndvcmRjbG91ZCh3b3JkcyA9IENvcnB1cywgDQogICAgICAgICAgbWF4LndvcmRzPTIwMCwgcmFuZG9tLm9yZGVyPUZBTFNFLCByb3QucGVyPTAuMzUsIA0KICAgICAgICAgIGNvbG9ycz1icmV3ZXIucGFsKDgsICJEYXJrMiIpKQ0KDQpgYGANCg0KDQojZmFpbGVkIEF0dGVtcHQNCmBgYHtyfQ0KDQoNCiMgDQojIA0KIyAjRGF0YSBNYW5pcHVsYXRpb24gYW5kIEFsZ29yaXRobSBJbXBsZW1lbnRhdGlvbg0KIyAjdHdlZXRzLnRleHQgPSBsYXBseSh0d2VldHMsIGZ1bmN0aW9uKHQpdCRnZXRUZXh0KCkpDQojIA0KIyAjbm93IGlmIHlvdSBoYXZlbuKAmXQgZG93bmxvYWQgdGhlIGRvY3VtZW50cyB0aGF0IE1pY2hhZWwgbWVudGlvbiBvbiBoaXMgdmlkZW8sIHlvdSBkZWZpbml0ZWx5IG5lZWQgdG8gZG8gaXQgbm93LiBSZW1lbWJlciB0byBzYXZlIHRoZW0gaW4gdGhlIHNhbWUgZm9sZGVyIHRoYXQgeW91ciBSIGNvZGUNCiMgDQojIHNjb3JlLnNlbnRpbWVudCA9IGZ1bmN0aW9uKHNlbnRlbmNlcywgcG9zaXRpdmVXb3JkcywgbmVnYXRpdmVXb3JkcywgLnByb2dyZXNzPSdub25lJykNCiMgew0KIyByZXF1aXJlKHBseXIpDQojIHJlcXVpcmUoc3RyaW5ncikNCiMgDQojICMgd2UgZ290IGEgdmVjdG9yIG9mIHNlbnRlbmNlcy4gcGx5ciB3aWxsIGhhbmRsZSBhIGxpc3Qgb3IgYSB2ZWN0b3IgYXMgYW4g4oCcbOKAnSBmb3IgdXMNCiMgIyB3ZSB3YW50IGEgc2ltcGxlIGFycmF5IG9mIHNjb3JlcyBiYWNrLCBzbyB3ZSB1c2Ug4oCcbOKAnSArIOKAnGHigJ0gKyDigJxwbHnigJ0gPSBsYXBseToNCiMgc2NvcmVzID0gbGFwbHkoc2VudGVuY2VzLCBmdW5jdGlvbihzZW50ZW5jZSwgcG9zaXRpdmVXb3JkcywgbmVnYXRpdmVXb3Jkcykgew0KIyANCiMgIyBjbGVhbiB1cCBzZW50ZW5jZXMgd2l0aCBS4oCZcyByZWdleC1kcml2ZW4gZ2xvYmFsIHN1YnN0aXR1dGUsIGdzdWIoKToNCiMgc2VudGVuY2UgPSBnc3ViKCdbWzpwdW5jdDpdXScsICcnLCBzZW50ZW5jZSkNCiMgc2VudGVuY2UgPSBnc3ViKCdbWzpjbnRybDpdXScsICcnLCBzZW50ZW5jZSkNCiMgc2VudGVuY2UgPSBnc3ViKCdcXGQrJywgJycsIHNlbnRlbmNlKQ0KIyAjIGFuZCBjb252ZXJ0IHRvIGxvd2VyIGNhc2U6DQojIHNlbnRlbmNlID0gdG9sb3dlcihzZW50ZW5jZSkNCiMgDQojICMgc3BsaXQgaW50byB3b3Jkcy4gc3RyX3NwbGl0IGlzIGluIHRoZSBzdHJpbmdyIHBhY2thZ2UNCiMgd29yZC5saXN0ID0gc3RyX3NwbGl0KHNlbnRlbmNlLCAnXFxzKycpDQojICMgc29tZXRpbWVzIGEgbGlzdCgpIGlzIG9uZSBsZXZlbCBvZiBoaWVyYXJjaHkgdG9vIG11Y2gNCiMgd29yZHMgPSB1bmxpc3Qod29yZC5saXN0KQ0KIyANCiMgIyBjb21wYXJlIG91ciB3b3JkcyB0byB0aGUgZGljdGlvbmFyaWVzIG9mIHBvc2l0aXZlICYgbmVnYXRpdmUgdGVybXMNCiMgcG9zLm1hdGNoZXMgPSBtYXRjaCh3b3JkcywgcG9zaXRpdmVXb3JkcykNCiMgbmVnLm1hdGNoZXMgPSBtYXRjaCh3b3JkcywgbmVnYXRpdmVXb3JkcykNCiMgDQojICMgbWF0Y2goKSByZXR1cm5zIHRoZSBwb3NpdGlvbiBvZiB0aGUgbWF0Y2hlZCB0ZXJtIG9yIE5BDQojICMgd2UganVzdCB3YW50IGEgVFJVRS9GQUxTRToNCiMgcG9zLm1hdGNoZXMgPSAhaXMubmEocG9zLm1hdGNoZXMpDQojIG5lZy5tYXRjaGVzID0gIWlzLm5hKG5lZy5tYXRjaGVzKQ0KIyANCiMgIyBhbmQgY29udmVuaWVudGx5IGVub3VnaCwgVFJVRS9GQUxTRSB3aWxsIGJlIHRyZWF0ZWQgYXMgMS8wIGJ5IHN1bSgpOg0KIyBzY29yZSA9IHN1bShwb3MubWF0Y2hlcykgLSBzdW0obmVnLm1hdGNoZXMpDQojIA0KIyByZXR1cm4oc2NvcmUpDQojIH0sIHBvc2l0aXZlV29yZHMsbmVnYXRpdmVXb3JkcywgLnByb2dyZXNzPS5wcm9ncmVzcyApDQojIA0KIyBzY29yZXMuZGYgPSBkYXRhLmZyYW1lKHNjb3JlPXNjb3JlcywgdGV4dD1zZW50ZW5jZXMpDQojIHJldHVybihzY29yZXMuZGYpDQojIH0NCiMgDQojICN0aGlzIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSB3b3JkcyBhcmUgcmVsYXRlZCB0byBhYm9ydGlvbg0KIyBwb3NpdGl2ZVdvcmRzID0gc2NhbigncG9zaXRpdmUudHh0Jyx3aGF0ID0gJ2NoYXJhY3RlcicsIGNvbW1lbnQuY2hhciA9ICc7JykNCiMgbmVnYXRpdmVXb3JkcyA9IHNjYW4oJ25lZ2F0aXZlLnR4dCcsd2hhdCA9ICdjaGFyYWN0ZXInLCBjb21tZW50LmNoYXIgPSAnOycpDQojIA0KIyAjQW5hbHlzZSB0aGUgcmVzdWx0cw0KIyANCiMgYW5hbHlzaXMgPSBzY29yZS5zZW50aW1lbnQobXlkZiwgcG9zLndvcmRzLCBuZWcud29yZHMsLnByb2dyZXNzPSdub25lJykNCiMgIHRhYmxlKGFuYWx5c2lzJHNjb3JlKQ0KIyAgbWVhbihhbmFseXNpcyRzY29yZSkNCiMgIG1lZGlhbihhbmFseXNpcyRzY29yZSkNCiMgIGhpc3QoYW5hbHlzaXMkc2NvcmUpDQoNCg0KDQoNCmBgYA0KDQoNCiNDb25jbHVzaW9uDQpTZW50aW1lbnQgYW5hbHlzaXMgY2FuIGJlIGFwcGxpZWQgdG8gbWFueSB0b3BpY3MuSXQgd2FzIGludGVyZXN0aW5nIHRvIHNlZSBob3cgaGUgd2FzIHJlbGF0aW5nIGEgcG9zaXRpdmUgbWVzc2FnZSB3aXRoaW4gaGlzIHR3aXR0ZXIgaGFuZGxlLlRoaXMgb3ZlcnNoYWRvdyB0aGUgbmVnYXRpdml0eS4gQWxzbyB0b3dhcmRzIG5vdmVtYmVyIFRydXN0IGVtb3Rpb24gd2FzIHZlcnkgaGlnaCBpbmRpY2F0aW5nIHN1cHBvcnQgYW5kIHNlbGYgY29uZmlkZW5jZS4gSW4gdGhlIGluc3RhbmNlIHdlcmUgdGhlIHRlcm0gdHJ1bXAgd2FzIHNlYXJjaCBzdXByaXNlIHNlZW0gdG8gYmUgdGhlIG92ZXJ3aGVsbWluZyBlbW90aW9uLg0KDQoNCiNSZWZlcmVuY2VzDQoNCmh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjE3ODEwMTQvcmVtb3ZlLWFsbC1saW5lLWJyZWFrcy1lbnRlci1zeW1ib2xzLWZyb20tdGhlLXN0cmluZy11c2luZy1yDQoNCmh0dHA6Ly90ZWNobm9rYXJhay5jb20vaG93LXRvLWNsZWFuLXRoZS10d2l0dGVyLWRhdGEtdXNpbmctci10d2l0dGVyLW1pbmluZy10dXRvcmlhbC5odG1sDQoNCmh0dHA6Ly9qdWxpYXNpbGdlLmNvbS9ibG9nL0pveS10by10aGUtV29ybGQvDQoNCmh0dHBzOi8vd3d3LnItYmxvZ2dlcnMuY29tL3Bsb3Qtd2Vla2x5LW9yLW1vbnRobHktdG90YWxzLWluLXIvDQoNCmh0dHA6Ly9zYWlmbW9oYW1tYWQuY29tL1dlYlBhZ2VzL05SQy1FbW90aW9uLUxleGljb24uaHRtDQoNCmh0dHBzOi8vd3d3LmNzLnVpYy5lZHUvfmxpdWIvRkJTL3NlbnRpbWVudC1hbmFseXNpcy5odG1sDQoNCmh0dHBzOi8vZ2l0aHViLmNvbS9qZWZmcmV5YnJlZW4vdHdpdHRlci1zZW50aW1lbnQtYW5hbHlzaXMtdHV0b3JpYWwtMjAxMTA3DQo=