├── .gitignore ├── LICENSE ├── R ├── sysdata.rda ├── utils.R ├── mockup-timeline.R └── mockup-status.R ├── tools └── readme │ ├── ex.png │ ├── ex2.png │ ├── ex3.png │ └── ex.html ├── .Rbuildignore ├── NAMESPACE ├── DESCRIPTION ├── mocktwitter.Rproj ├── make.R ├── man ├── mocktwitter_timeline.Rd └── mocktwitter_status.Rd ├── LICENSE.md ├── README.md └── README.Rmd /.gitignore: -------------------------------------------------------------------------------- 1 | .Rhistory 2 | .RData 3 | .Rproj.user 4 | make.R 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: Michael Wayne Kearney 3 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/mocktwitter/HEAD/R/sysdata.rda -------------------------------------------------------------------------------- /tools/readme/ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/mocktwitter/HEAD/tools/readme/ex.png -------------------------------------------------------------------------------- /tools/readme/ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/mocktwitter/HEAD/tools/readme/ex2.png -------------------------------------------------------------------------------- /tools/readme/ex3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkearney/mocktwitter/HEAD/tools/readme/ex3.png -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^README\.Rmd$ 2 | ^LICENSE\.md$ 3 | ^mocktwitter\.Rproj$ 4 | ^\.Rproj\.user$ 5 | \.DS_Store$ 6 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(mocktwitter_status,character) 4 | S3method(mocktwitter_status,data.frame) 5 | S3method(mocktwitter_status,factor) 6 | S3method(mocktwitter_timeline,character) 7 | S3method(mocktwitter_timeline,factor) 8 | export(mocktwitter_status) 9 | export(mocktwitter_timeline) 10 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: mocktwitter 2 | Version: 0.0.0.9000 3 | Title: What the Package Does (One Line, Title Case) 4 | Description: Generates mockup HTML Twitter pages. 5 | License: MIT + file LICENSE 6 | Encoding: UTF-8 7 | LazyData: true 8 | ByteCompile: true 9 | Authors@R: person("Michael Wayne", "Kearney", , 10 | "kearneymw@missouri.edu", role = c("aut", "cre"), 11 | comment = c(ORCID = "0000-0002-0730-4694")) 12 | license: MIT 13 | RoxygenNote: 6.0.1.9000 14 | -------------------------------------------------------------------------------- /mocktwitter.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /make.R: -------------------------------------------------------------------------------- 1 | 2 | library(usethis) 3 | use_description() 4 | devtools::document() 5 | devtools::install() 6 | use_git_config() 7 | use_readme_rmd() 8 | use_git() 9 | use_git_ignore() 10 | 11 | 12 | devtools::load_all() 13 | 14 | writeLines(template, "/tmp/tmp.html") 15 | 16 | con <- file("/tmp/tmp.html") 17 | x <- readLines(con, warn = FALSE, encoding = "UTF-8") 18 | close(con) 19 | 20 | template <- x 21 | 22 | save(template, file = "R/sysdata.rda") 23 | rmarkdown::render("README.Rmd") 24 | unlink("README.html") 25 | 26 | rdt <- rtweet::lookup_statuses("1010900865602019329") 27 | 28 | mocktwitter("1010900865602019329") 29 | traceback() -------------------------------------------------------------------------------- /man/mocktwitter_timeline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mockup-timeline.R 3 | \name{mocktwitter_timeline} 4 | \alias{mocktwitter_timeline} 5 | \title{Create a mockup of a Twitter timeline} 6 | \usage{ 7 | mocktwitter_timeline(x, file = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{Twitter timeline data frame (as returned by rtweet).} 11 | 12 | \item{file}{File name to save as. Defaults to temporary file.} 13 | } 14 | \value{ 15 | Saves an html file 16 | } 17 | \description{ 18 | Generates HTML twitter timeline page. 19 | } 20 | \examples{ 21 | \dontrun{ 22 | ## create mock-up of Twitter timeline 23 | 24 | ## the timeline URL 25 | mocktwitter_timeline("https://twitter.com/kearneymw") 26 | 27 | ## the screen name or user ID 28 | mocktwitter_timeline("kearneymw") 29 | 30 | ## or get timeline data from rtweet 31 | kmw <- rtweet::get_timeline("kearneymw") 32 | mocktwitter_timeline(kmw) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /man/mocktwitter_status.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mockup-status.R 3 | \name{mocktwitter_status} 4 | \alias{mocktwitter_status} 5 | \title{Create a mockup of a Twitter status} 6 | \usage{ 7 | mocktwitter_status(x, file = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{Twitter status data frame (as returned by rtweet).} 11 | 12 | \item{file}{File name to save as. Defaults to temporary file.} 13 | } 14 | \value{ 15 | Saves an html file 16 | } 17 | \description{ 18 | Generates HTML twitter status page. 19 | } 20 | \examples{ 21 | \dontrun{ 22 | ## create mock-up of Twitter status about rtweet release using 23 | 24 | ## the status URL 25 | mocktwitter_status("https://twitter.com/kearneymw/status/1009431823791902720") 26 | 27 | ## the status_id 28 | mocktwitter_status("1009431823791902720") 29 | 30 | ## or pick a tweet from my timeline to display 31 | kmw <- rtweet::get_timeline("kearneymw") 32 | mocktwitter_status(kmw[1, ]) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2018 Michael Wayne Kearney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | read_source <- function(x) { 2 | x <- httr::GET(x) 3 | httr::warn_for_status(x) 4 | httr::content(x, as = "text", encoding = "UTF-8") 5 | } 6 | 7 | 8 | is_id <- function(x) { 9 | x <- gsub("\\s|/", "", x) 10 | nchar(gsub("\\d", "", x)) == 0 11 | } 12 | 13 | is_token_configured <- function() { 14 | if (exists(".rtweet_token_config")) { 15 | return(get("rtweet_token_config", envir = .rtweet_token_config)) 16 | } 17 | .rtweet_token_config <- new.env() 18 | assign(".rtweet_token_config", .rtweet_token_config, envir = .GlobalEnv) 19 | if (identical(Sys.getenv("TWITTER_PAT"), "")) { 20 | assign("rtweet_token_config", FALSE, envir = .rtweet_token_config) 21 | return(FALSE) 22 | } 23 | token <- readRDS(Sys.getenv("TWITTER_PAT")) 24 | if (!inherits(token, c("Token", "Token1.0"))) { 25 | assign("rtweet_token_config", FALSE, envir = .rtweet_token_config) 26 | return(FALSE) 27 | } 28 | x <- tryCatch(rtweet:::authenticating_user_name(token), 29 | error = function(e) return(FALSE), 30 | warning = function(w) return(FALSE)) 31 | if (identical(x, FALSE) || length(x) != 1L || !is.character(x)) { 32 | assign("rtweet_token_config", FALSE, envir = .rtweet_token_config) 33 | return(FALSE) 34 | } 35 | assign("rtweet_token_config", TRUE, envir = .rtweet_token_config) 36 | TRUE 37 | } 38 | 39 | is_status_id <- function(x) { 40 | x <- tryCatch(rtweet::lookup_statuses(x), 41 | error = function(e) return(NULL), 42 | warning = function(w) return(NULL)) 43 | is.data.frame(x) && nrow(x) == 1L 44 | } 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # mocktwitter 5 | 6 | 🐧🐦 Generate HTML pages for Twitter statuses. 7 | 8 | ## Installation 9 | 10 | You can install the current version of mocktwitter from 11 | [Github](https://github.com) with: 12 | 13 | ``` r 14 | ## install from github 15 | devtools::install_github("mkearney/mocktwitter") 16 | ``` 17 | 18 | ## `mocktwitter_status()` 19 | 20 | Use `mocktwitter_status()` with a status URL, status ID, or tweets data 21 | returned by [**{rtweet}**](http://rtweet.info) to create a [mock-up of a 22 | Twitter status HTML page](htols/readme/ex.html): 23 | 24 | ``` r 25 | ## (1) URL to twitter status data byrealDonaldTrump 26 | mocktwitter_status("https://twitter.com/realDonaldTrump/status/1010900865602019329") 27 | 28 | ## (2) mockup an HTML twitter page for a readDonaldTrump status 29 | mocktwitter_status("1010900865602019329") 30 | 31 | ## (3) twitter status data from rtweet for a realDonaldTrump tweet 32 | rdt <- rtweet::lookup_statuses("1010900865602019329") 33 | 34 | ## override with custom text 35 | rdt$text <- "Give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore. Send these, the homeless, tempest-tossed to me, I lift my lamp beside the golden door!" 36 | 37 | ## mock-up an HTML twitter page 38 | mocktwitter_status(rdt, file = "tools/readme/ex.html") 39 | ``` 40 | 41 |

42 | 43 | 44 | 45 |

46 | 47 | In Rstudio, a preview will be displayed in the viewer pane. 48 | 49 |

50 | 51 | 52 | 53 |

54 | 55 | ## `mocktwitter_timeline()` (**dev in progress**) 56 | 57 | Use `mocktwitter_timeline()` with a user URL, screen name, user ID, or 58 | timeline data returned by [**{rtweet}**](http://rtweet.info) to create a 59 | [mock-up of a Twitter status HTML page](tools/readme/ex2.html): 60 | 61 | ``` r 62 | ## (1) URL to a twitter timeline 63 | mocktwitter_timeline("https://twitter.com/kearneymw") 64 | 65 | ## (2) screen name or user ID of twitter account 66 | mocktwitter_timeline("kearneymw", file = "tools/readme/ex2.html") 67 | ``` 68 | 69 |

70 | 71 | 72 | 73 |

74 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r setup, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | eval = FALSE, 11 | comment = "#>", 12 | fig.path = "man/figures/README-", 13 | out.width = "100%" 14 | ) 15 | ``` 16 | # mocktwitter 17 | 18 | 🐧🐦 Generate HTML pages for Twitter statuses. 19 | 20 | ## Installation 21 | 22 | You can install the current version of mocktwitter from [Github](https://github.com) with: 23 | 24 | ```{r} 25 | ## install from github 26 | devtools::install_github("mkearney/mocktwitter") 27 | ``` 28 | 29 | ## `mocktwitter_status()` 30 | 31 | Use `mocktwitter_status()` with a status URL, status ID, or tweets data returned by [**{rtweet}**](http://rtweet.info) to create a [mock-up of a Twitter status HTML page](htols/readme/ex.html): 32 | 33 | ```{r} 34 | ## (1) URL to twitter status data byrealDonaldTrump 35 | mocktwitter_status("https://twitter.com/realDonaldTrump/status/1010900865602019329") 36 | 37 | ## (2) mockup an HTML twitter page for a readDonaldTrump status 38 | mocktwitter_status("1010900865602019329") 39 | 40 | ## (3) twitter status data from rtweet for a realDonaldTrump tweet 41 | rdt <- rtweet::lookup_statuses("1010900865602019329") 42 | 43 | ## override with custom text 44 | rdt$text <- "Give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore. Send these, the homeless, tempest-tossed to me, I lift my lamp beside the golden door!" 45 | 46 | ## mock-up an HTML twitter page 47 | mocktwitter_status(rdt, file = "tools/readme/ex.html") 48 | ``` 49 | 50 |

51 | 52 | In Rstudio, a preview will be displayed in the viewer pane. 53 | 54 |

55 | 56 | ## `mocktwitter_timeline()` (**dev in progress**) 57 | 58 | Use `mocktwitter_timeline()` with a user URL, screen name, user ID, or timeline 59 | data returned by [**{rtweet}**](http://rtweet.info) to create a [mock-up of a Twitter status HTML page](tools/readme/ex2.html): 60 | 61 | 62 | ```{r} 63 | ## (1) URL to a twitter timeline 64 | mocktwitter_timeline("https://twitter.com/kearneymw") 65 | 66 | ## (2) screen name or user ID of twitter account 67 | mocktwitter_timeline("kearneymw", file = "tools/readme/ex2.html") 68 | ``` 69 | 70 | 71 |

72 | -------------------------------------------------------------------------------- /R/mockup-timeline.R: -------------------------------------------------------------------------------- 1 | #' Create a mockup of a Twitter timeline 2 | #' 3 | #' Generates HTML twitter timeline page. 4 | #' 5 | #' @param x Twitter timeline data frame (as returned by rtweet). 6 | #' @param file File name to save as. Defaults to temporary file. 7 | #' @return Saves an html file 8 | #' @examples 9 | #' \dontrun{ 10 | #' ## create mock-up of Twitter timeline 11 | #' 12 | #' ## the timeline URL 13 | #' mocktwitter_timeline("https://twitter.com/kearneymw") 14 | #' 15 | #' ## the screen name or user ID 16 | #' mocktwitter_timeline("kearneymw") 17 | #' 18 | #' ## or get timeline data from rtweet 19 | #' kmw <- rtweet::get_timeline("kearneymw") 20 | #' mocktwitter_timeline(kmw) 21 | #' 22 | #' } 23 | #' @export 24 | mocktwitter_timeline <- function(x, file = NULL) { 25 | UseMethod("mocktwitter_timeline") 26 | } 27 | 28 | mocktwitter_timeline.default <- function(x, file = NULL) { 29 | stop("must supply screen name, user id, or twitter timeline data frame ", 30 | "returned by an rtweet function") 31 | } 32 | 33 | #' @export 34 | mocktwitter_timeline.factor <- function(x, file = NULL) { 35 | x <- as.character(x) 36 | mocktwitter_timeline(x, file) 37 | } 38 | 39 | #' @export 40 | mocktwitter_timeline.character <- function(x, file = NULL) { 41 | stopifnot(length(x) == 1L) 42 | if (!is_token_configured()) { 43 | stop("please setup your Twitter API token, see: ", 44 | "http://rtweet.info/articles/auth.html or ", 45 | "vignette(\"auth\", package = \"rtweet\") for more information") 46 | } 47 | if (grepl("^http", x)) { 48 | x <- gsub( 49 | "https://[[:graph:]]{0,30}twitter\\.com/|/$", 50 | "", x) 51 | } 52 | mocktwitter_mytimeline(x, file) 53 | } 54 | 55 | 56 | mocktwitter_mytimeline <- function(user, file) { 57 | tml <- read_source(sprintf("https://twitter.com/%s", user)) 58 | tml <- sub(".{0,97}signin-l.{0,148}", "", tml) 59 | tml <- sub( 60 | ".{0,112}SignupCallOut.*personalized timeline.*signup_callout.{0,60}", 61 | "", tml) 62 | tml <- sub(".{0,12}nav secondary-nav session-dropdown.*page-outer", 63 | "\n\n\n\n\n
" 70 | tml <- sub("", css, tml) 71 | tmp <- tempfile(fileext = ".html") 72 | if (is.null(file)) { 73 | file <- tmp 74 | } 75 | writeLines(tml, file) 76 | message("Saving as ", file) 77 | file.copy(file, tmp) 78 | if (rstudioapi::isAvailable()) { 79 | rstudioapi::viewer(tmp) 80 | } else if (!exists(".mocktwitter_opened")) { 81 | assign(".mocktwitter_opened", new.env(), envir = .GlobalEnv) 82 | browseURL(file) 83 | } 84 | invisible(file) 85 | } 86 | -------------------------------------------------------------------------------- /R/mockup-status.R: -------------------------------------------------------------------------------- 1 | 2 | #' Create a mockup of a Twitter status 3 | #' 4 | #' Generates HTML twitter status page. 5 | #' 6 | #' @param x Twitter status data frame (as returned by rtweet). 7 | #' @param file File name to save as. Defaults to temporary file. 8 | #' @return Saves an html file 9 | #' @examples 10 | #' \dontrun{ 11 | #' ## create mock-up of Twitter status about rtweet release using 12 | #' 13 | #' ## the status URL 14 | #' mocktwitter_status("https://twitter.com/kearneymw/status/1009431823791902720") 15 | #' 16 | #' ## the status_id 17 | #' mocktwitter_status("1009431823791902720") 18 | #' 19 | #' ## or pick a tweet from my timeline to display 20 | #' kmw <- rtweet::get_timeline("kearneymw") 21 | #' mocktwitter_status(kmw[1, ]) 22 | #' 23 | #' } 24 | #' @export 25 | mocktwitter_status <- function(x, file = NULL) UseMethod("mocktwitter_status") 26 | 27 | mocktwitter_status.default <- function(x, file = NULL) { 28 | stop("must supply status_id or a twitter status data frame returned by an ", 29 | "rtweet function") 30 | } 31 | 32 | #' @export 33 | mocktwitter_status.factor <- function(x, file = NULL) { 34 | x <- as.character(x) 35 | mocktwitter_status(x, file) 36 | } 37 | 38 | #' @export 39 | mocktwitter_status.character <- function(x, file = NULL) { 40 | stopifnot(length(x) == 1L) 41 | if (!is_token_configured()) { 42 | stop("please setup your Twitter API token, see: ", 43 | "http://rtweet.info/articles/auth.html or ", 44 | "vignette(\"auth\", package = \"rtweet\") for more information") 45 | } 46 | if (grepl("^http", x)) { 47 | x <- gsub( 48 | "https://[[:graph:]]{0,30}twitter\\.com/[[:graph:]]+/status/|/$", 49 | "", x) 50 | } 51 | x <- rtweet::lookup_statuses(x) 52 | mocktwitter_status(x, file) 53 | } 54 | 55 | 56 | #' @export 57 | mocktwitter_status.data.frame <- function(x, file = NULL) { 58 | if (any(!req_vars() %in% names(x))) { 59 | missing <- req_vars()[!req_vars() %in% names(x)] 60 | stop(paste("Missing the following variables:", 61 | paste(missing, collapse = ", "))) 62 | } 63 | if (nrow(x) > 1L) { 64 | warning("Can only create one status at a time. Using the first ", 65 | "observation...") 66 | x <- x[1, ] 67 | } 68 | if (x$retweet_count >= 1000) { 69 | x$retweet_count <- prettyNum(x$retweet_count, big.mark = ",") 70 | } 71 | if (x$favorite_count >= 1000) { 72 | x$favorite_count <- prettyNum(x$favorite_count, big.mark = ",") 73 | } 74 | if (x$favorite_count > 0) { 75 | favs <- read_source(sprintf("https://twitter.com/%s/status/%s", 76 | x$screen_name, x$status_id)) 77 | m <- gregexpr("(?<=data-user-id=.{1})\\d+(?=.{1} original-title)", 78 | favs, perl = TRUE) 79 | if (length(m[[1]]) > 0) { 80 | favs <- unique(regmatches(favs, m)[[1]]) 81 | } else { 82 | favs <- NULL 83 | } 84 | } else { 85 | favs <- NULL 86 | } 87 | if (x$retweet_count > 0) { 88 | rts <- rtweet::get_retweeters(x$status_id) 89 | rts <- c(favs, rts$user_id) 90 | } else { 91 | rts <- favs 92 | } 93 | rts <- unique(rts) 94 | if (length(rts) > 9) { 95 | rts <- rts[sample(seq_along(rts), 9)] 96 | } 97 | if (length(rts) > 0) { 98 | fav_users <- rtweet::lookup_users(rts) 99 | } else { 100 | fav_users <- NULL 101 | } 102 | y <- template 103 | y <- gsub("\\{status_text\\}", x$text, y) 104 | y <- gsub("\\{screen_name\\}", x$screen_name, y) 105 | y <- gsub("\\{user_id\\}", x$user_id, y) 106 | y <- gsub("\\{status_id\\}", x$status_id, y) 107 | y <- gsub("\\{retweet_count\\}", x$retweet_count, y) 108 | y <- gsub("\\{favourites_count\\}", x$favorite_count, y) 109 | y <- gsub("\\{name\\}", x$name, y) 110 | y <- gsub("\\{description\\}", x$description, y) 111 | y <- gsub("\\{location\\}", x$location, y) 112 | y <- gsub("\\{profile_url\\}", sub("(https?://www\\.)|(https?://)", "", 113 | x$profile_expanded_url), y) 114 | y <- gsub("\\{account_created_at\\}", x$account_created_at, y) 115 | y <- gsub("\\{created_at\\}", x$created_at, y) 116 | y <- gsub("\\{profile_image_url\\}", 117 | sub("_[^_]+\\.jpg", "_", x$profile_image_url), y) 118 | y <- gsub("\\{profile_banner_url\\}", x$profile_banner_url, y) 119 | if (!is.null(fav_users)) { 120 | fav_users_code <- li_favusers(fav_users) 121 | y <- gsub("\\{fav_users\\}", fav_users_code, y) 122 | } 123 | if (is.null(file)) { 124 | file <- tempfile(fileext = ".html") 125 | message("Saving as ", file) 126 | writeLines(y, file) 127 | file.copy(file, tmp) 128 | } else { 129 | tmp <- tempfile(fileext = ".html") 130 | message("Saving as ", file) 131 | writeLines(y, file) 132 | file.copy(file, tmp) 133 | } 134 | if (rstudioapi::isAvailable()) { 135 | rstudioapi::viewer(tmp) 136 | } else { 137 | browseURL(file) 138 | } 139 | } 140 | 141 | li_favuser <- function(x) { 142 | sprintf(paste0('\n%s\n'), x$user_id, x$screen_name, x$user_id, x$name, 146 | x$profile_image_url, x$name) 147 | } 148 | 149 | li_favusers <- function(x) { 150 | paste(lapply(seq_len(nrow(x)), function(.x) li_favuser(x[.x, ])), 151 | collapse = "\n\n") 152 | } 153 | 154 | req_vars <- function() { 155 | c("retweet_count", "favorite_count", "status_id", "user_id", "screen_name", 156 | "profile_image_url", "profile_url", "profile_banner_url", "created_at", 157 | "text", "name", "description", "location") 158 | } 159 | -------------------------------------------------------------------------------- /tools/readme/ex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 23 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | Donald J. Trump on Twitter: "Give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore. Send these, the homeless, tempest-tossed to me, I lift my lamp beside the golden door!" 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 95 | 98 | 99 | 100 | 111 | 112 | Skip to content 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
124 |
125 | 126 | 127 | 128 |
129 |
130 |
131 | 132 | 133 |
    134 |
  • 135 | 136 | 137 | Home 138 | Home 139 | Home, current page. 140 | 141 |
  • 142 |
  • 143 | 144 | 145 | 146 | Moments 147 | Moments 148 | Moments, current page. 149 | 150 |
  • 151 |
152 |
153 |
154 |
155 | 156 | 157 | 158 | 161 | 162 | 163 | 164 | 165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |

Saved searches

173 |
    174 | 175 |
  • 176 | Remove 177 | 178 |
  • 179 |
180 |
181 | 182 |
    183 | 184 |
  • 185 | 186 |
  • 187 |
188 |
    189 | 190 |
  • 191 | 192 | 193 |
    194 | 195 | In this conversation 196 |
    197 | 198 | 199 | Verified accountProtected Tweets @ 200 | 201 | 202 |
    203 |
  • 204 |
  • 205 |
206 | 207 |
    208 | 209 |
  • 210 |
211 | 212 |
213 |
214 | Suggested users 215 |
216 |
    217 | 218 |
  • 219 | 220 | 221 | 222 | 223 | 224 | 225 | Verified accountProtected Tweets @ 226 | 227 | 228 |
  • 229 |
  • 230 |
231 | 232 |
    233 | 234 |
  • 235 | 236 | 237 | 238 | 239 | 240 | 241 | Verified accountProtected Tweets @ 242 | 243 | 244 |
  • 245 |
  • 246 |
247 |
248 | 249 |
250 |
    251 |
  • 252 | 253 |
  • 254 |
255 |
256 |
257 |
258 | 259 |
260 |
261 | 262 | 263 |
    264 |
  • 265 | 266 | Language: English 267 | 268 |
    269 |
    270 | 271 | 272 |
    273 |
      274 |
    • Bahasa Indonesia
    • 275 |
    • Bahasa Melayu
    • 276 |
    • Català
    • 277 |
    • Čeština
    • 278 |
    • Dansk
    • 279 |
    • Deutsch
    • 280 |
    • English UK
    • 281 |
    • Español
    • 282 |
    • Filipino
    • 283 |
    • Français
    • 284 |
    • Hrvatski
    • 285 |
    • Italiano
    • 286 |
    • Magyar
    • 287 |
    • Nederlands
    • 288 |
    • Norsk
    • 289 |
    • Polski
    • 290 |
    • Português
    • 291 |
    • Română
    • 292 |
    • Slovenčina
    • 293 |
    • Suomi
    • 294 |
    • Svenska
    • 295 |
    • Tiếng Việt
    • 296 |
    • Türkçe
    • 297 |
    • Ελληνικά
    • 298 |
    • Български език
    • 299 |
    • Русский
    • 300 |
    • Српски
    • 301 |
    • Українська мова
    • 302 |
    • עִבְרִית
    • 303 |
    • العربية
    • 304 |
    • فارسی
    • 305 |
    • मराठी
    • 306 |
    • हिन्दी
    • 307 |
    • বাংলা
    • 308 |
    • ગુજરાતી
    • 309 |
    • தமிழ்
    • 310 |
    • ಕನ್ನಡ
    • 311 |
    • ภาษาไทย
    • 312 |
    • 한국어
    • 313 |
    • 日本語
    • 314 |
    • 简体中文
    • 315 |
    • 繁體中文
    • 316 |
    317 |
    318 |
    319 |
    320 | 321 | 322 |
    323 |
    324 |
  • 325 |
326 | 327 |
    328 |
  • 329 | 330 | Have an account? Log in 331 | 332 |
    333 |
    334 |
    335 |
    Have an account?
    336 |
    340 |
    341 | 348 |
    349 | 350 |
    351 | 352 | 353 |
    354 | 355 |
    356 | 360 | · 361 | Forgot password? 362 |
    363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 |
    374 |
    375 |
    376 |
    New to Twitter?
    377 | Sign up 381 | 382 |
    383 |
    384 |
    385 |
  • 386 |
387 |
388 | 389 |
390 |
391 |
392 |
393 | 394 | 395 |
396 |
397 | 398 | 399 | 400 | realDonaldTrump's profile 401 | 402 |
403 |
404 |
405 | 406 |
407 |
408 | 412 |
413 | 414 |
415 | 416 |
417 |
418 | 425 | Donald J. Trump 426 | 427 |
428 | 429 |
430 | 431 | 432 |
433 |
434 | 435 |
436 | 437 | 438 |
439 | 440 |
441 |
442 |
443 |
444 |
445 | 452 | Donald J. Trump 453 | 454 |
455 |
456 |
457 | 458 | Donald J. Trump
459 |
460 |
461 | 462 | @realDonaldTrump 463 | 464 |
465 |
466 |
467 | 468 |
469 |
470 | 471 |
472 |
473 | 474 | 475 |
476 |
477 |
478 |
479 |
480 | 481 |
482 |
483 | 484 | 485 |
486 |
487 |

Tweets

488 |
489 | 490 | 491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |

499 | Donald J. Trump 501 |

502 | 503 |

504 | 505 | @realDonaldTrump 506 | 507 |

508 | 509 | 510 | 511 |

45th President of the United States of America🇺🇸

512 | 513 |
514 | 515 | 516 | Washington, DC 517 | 518 | 519 |
520 | 521 |
522 | 523 | 524 | Instagram.com/realDonaldTrump 525 | 526 | 527 | 528 |
529 | 530 | 531 |
532 | 533 | 2009-03-18 13:46:38 534 |
535 | 536 |
537 | 538 | 539 | 540 |
541 | 542 | 543 |
544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 |
552 | 553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |

Tweets

562 |
563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 |
575 |
576 |
577 |
578 |
579 |
580 | 581 |
582 | 583 | 584 | 585 | 586 | 587 |
589 |
590 |
591 |
    592 |
  • © 2018 Twitter
  • 593 |
  • About
  • 594 |
  • Help Center
  • 595 |
  • Terms
  • 596 |
  • Privacy policy
  • 597 |
  • Cookies
  • 598 |
  • Ads info
  • 599 |
600 |
601 |
602 | 603 |
604 | 605 |
606 | 607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 | 618 | 619 | 620 | 1157 | 1158 | 1159 | 1170 | 1171 | 1172 | 1173 | 1174 |
1175 |
1176 |
1177 |
1178 |
1179 |
1180 | 1181 | 1182 | Dismiss 1183 | 1184 |
1185 |
1186 |
1187 | 1188 | 1189 | 1190 | 1191 |
1192 |
1193 | 1194 |
1195 |
1196 | 1201 | 1202 |
1203 |
1204 | 1205 | 1206 | 1207 | Previous 1208 | 1209 | 1210 | 1211 |
1212 |
1213 | 1214 | 1215 | 1216 | Next 1217 | 1218 | 1219 | 1220 |
1221 |
1222 |
1223 |
1224 | 1225 | 1226 |
1227 | 1228 |
1229 | 1230 | 1231 |
1232 |
1233 |
1234 | 1239 | 1240 | 1241 |
1242 |

Go to a person's profile

1243 |
1244 | 1245 |
1246 |
1247 |
1248 | 1249 | 1250 | 1251 | 1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |

Saved searches

1260 |
    1261 | 1262 |
  • 1263 | Remove 1264 | 1265 |
  • 1266 |
1267 |
1268 | 1269 |
    1270 | 1271 |
  • 1272 | 1273 |
  • 1274 |
1275 |
    1276 | 1277 |
  • 1278 | 1279 | 1280 |
    1281 | 1282 | In this conversation 1283 |
    1284 | 1285 | 1286 | Verified accountProtected Tweets @ 1287 | 1288 | 1289 |
    1290 |
  • 1291 |
  • 1292 |
1293 | 1294 |
    1295 | 1296 |
  • 1297 |
1298 | 1299 |
1300 |
1301 | Suggested users 1302 |
1303 |
    1304 | 1305 |
  • 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | 1312 | Verified accountProtected Tweets @ 1313 | 1314 | 1315 |
  • 1316 |
  • 1317 |
1318 | 1319 |
    1320 | 1321 |
  • 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | Verified accountProtected Tweets @ 1329 | 1330 | 1331 |
  • 1332 |
  • 1333 |
1334 |
1335 | 1336 |
1337 |
    1338 |
  • 1339 | 1340 |
  • 1341 |
1342 |
1343 |
1344 |
1345 | 1346 |
1347 |
1348 |
1349 | 1350 |
1351 |
1352 |
1353 | 1354 |
1355 |
1356 |
1357 | 1362 | 1363 |
1364 |

Promote this Tweet

1365 |
1366 |
1367 |
1368 |
1369 | 1375 |
1376 |
1377 |
1378 |
1379 |
1380 |
1381 | 1382 | 1383 |
1384 |
1385 |
1386 | 1391 | 1392 | 1393 |
1394 |

Block

1395 |
1396 | 1397 |
1398 |
1399 |
1400 | 1401 |
1402 | 1403 |
1404 | 1405 | 1406 |
1407 |
1408 |
1409 |
1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 |
1417 |
1418 |
1419 | 1420 | 1421 |
1422 |
    1423 |
  • 1424 |

    Tweet with a location

    1425 |

    1426 | You can add location information to your Tweets, such as your city or precise location, from the web and via third-party applications. You always have the option to delete your Tweet location history. 1427 | Learn more 1428 |

    1429 |
    1430 | 1431 | 1432 |
    1433 |
  • 1434 |
1435 |
1436 | 1437 |
1438 | 1439 |
1440 |
1441 |
1442 | 1443 | 1444 |
1445 |
1446 |
1447 | 1448 | 1449 |
1450 |
1451 |
    1452 |
    1453 |
    1454 | 1455 |
    1456 | 1457 | 1458 | 1459 |
    1460 |
    1461 |
    1462 | 1467 | 1468 |
    1469 |

    Your lists

    1470 |
    1471 |
    1472 |
    1473 | 1474 |
    1475 |
    1476 |
    1477 |
    1478 |
    1479 |
    1480 |
    1481 | 1486 | 1487 |
    1488 |

    Create a new list

    1489 |
    1490 |
    1491 |
    1492 |
    1493 | 1494 | 1495 |
    1496 |
    1497 | 1498 |
    1499 | 1500 | 1501 | Under 100 characters, optional 1502 |
    1503 |
    1504 | 1505 |
    1506 | Privacy 1507 |
    1508 | 1512 | 1516 |
    1517 |
    1518 |
    1519 | 1520 |
    1521 | 1522 |
    1523 |
    1524 | 1525 |
    1526 |
    1527 |
    1528 |
    1529 | 1530 |
    1531 |
    1532 |
    1533 | 1538 | 1539 | 1540 |
    1541 |

    1542 |
    1543 | 1544 |
    1545 |
    1546 |
    1547 |
    1548 | 1549 |
    1550 |
    1551 | 1552 |
    1553 |
    1554 |
    1555 |
    1556 |
    1557 |
    1558 |
    1559 | 1560 | 1561 | 1562 | 1563 |
    1564 |
    1565 |
    1566 | 1571 | 1572 |
    1573 |

    Copy link to Tweet

    1574 |
    1575 |
    1576 |
    1577 | 1581 |
    1582 |
    1583 |
    1584 |
    1585 |
    1586 | 1587 | 1588 |
    1589 |
    1590 |
    1591 | 1596 | 1597 |
    1598 |

    Embed this Tweet

    1599 |

    Embed this Video

    1600 |
    1601 |
    1602 |
    1603 |

    Add this Tweet to your website by copying the code below. Learn more

    1604 |

    Add this video to your website by copying the code below. Learn more

    1605 |
    1606 | 1607 |
    1608 |
    1609 |
    1610 |

    Hmm, there was a problem reaching the server.

    1611 |
    1612 | 1613 |
    1614 |
    1615 | 1619 |
    1620 |
    1621 | 1625 |
    1626 |
    1627 |
    1628 |
    1629 |

    By embedding Twitter content in your website or app, you are agreeing to the Twitter Developer Agreement and Developer Policy.

    1630 |

    Preview

    1631 |
    1632 |
    1633 |
    1634 | 1635 |
    1636 |
    1637 |
    1638 |
    1639 | 1640 | 1641 |
    1642 |
    1643 |
    1644 | 1649 | 1650 |
    1651 |

    Why you're seeing this ad

    1652 |
    1653 |
    1654 |
    1655 |
    1656 |
    1657 | 1659 |
    1660 |
    1661 |
    1662 |
    1663 | 1664 | 1665 | 1666 |
    1667 |
    1668 |
    1669 | 1674 | 1675 |
    1676 |

    Log in to Twitter

    1677 |
    1678 |
    1679 |
    1680 | 1681 |
    1682 |
    1683 |
    1687 |
    1688 | 1695 |
    1696 | 1697 |
    1698 | 1699 | 1700 |
    1701 | 1702 |
    1703 | 1707 | · 1708 | Forgot password? 1709 |
    1710 | 1711 | 1712 | 1713 | 1714 | 1715 | 1716 | 1717 | 1718 | 1719 | 1720 |
    1721 |
    1722 |
    1723 |
    1724 | Don't have an account? Sign up » 1725 |
    1726 |
    1727 |
    1728 |
    1729 | 1730 |
    1731 |
    1732 |
    1733 | 1738 | 1739 |
    1740 |

    Sign up for Twitter

    1741 |
    1742 |
    1743 |
    1744 | 1745 |
    1746 |

    Not on Twitter? Sign up, tune into the things you care about, and get updates as they happen.

    1747 |
    1748 |
    1750 | Sign up 1754 |
    1755 |
    1756 |
    1757 |
    1758 | Have an account? Log in » 1759 |
    1760 |
    1761 |
    1762 |
    1763 | 1764 |
    1765 |
    1766 |
    1767 | 1772 | 1773 |
    1774 |

    Two-way (sending and receiving) short codes:

    1775 |
    1776 |
    1777 | 1778 | 1779 | 1780 | 1781 | 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | 1809 | 1810 | 1811 | 1812 | 1813 | 1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1842 | 1843 | 1844 |
    CountryCodeFor customers of
    United States40404(any)
    Canada21212(any)
    United Kingdom86444Vodafone, Orange, 3, O2
    Brazil40404Nextel, TIM
    Haiti40404Digicel, Voila
    Ireland51210Vodafone, O2
    India53000Bharti Airtel, Videocon, Reliance
    Indonesia89887AXIS, 3, Telkomsel, Indosat, XL Axiata
    Italy4880804Wind
    3424486444Vodafone
    1840 | » See SMS short codes for other countries 1841 |
    1845 |
    1846 |
    1847 |
    1848 |
    1849 | 1850 |
    1851 |
    1852 |
    1853 | 1858 | 1859 |
    1860 |

    Confirmation

    1861 |
    1862 |
    1863 |
    1864 |
    1865 | 1871 |
    1872 |
    1873 |
    1874 |
    1875 |
    1876 |
    1877 |
    1878 |
    1879 | 1880 | 1881 |
    1882 |
    1883 |
    1884 | 1889 | 1890 |
    1891 |

     

    1892 |
    1893 |
    1894 |
    1895 |
    1896 | 1904 |
    1905 |
    1906 |
    1907 |
    1908 |
    1909 |
    1910 | 1911 | 1912 | 1913 |
    1914 |
    1915 | 1916 | 1921 |
    1922 |
    1923 |
    1924 | 1925 | 1926 |
    1927 |
    1928 |
    1929 |
    1930 |
    1931 |
    1932 |
    1933 | 1934 | 1937 |
    1938 | 1939 | 1940 | 1941 | 1942 |
    1943 |

    1944 | 1945 | Welcome home! 1946 |

    1947 |

    This timeline is where you’ll spend most of your time, getting instant updates about what matters to you.

    1948 |
    1949 | 1950 | 1951 | 1952 |
    1953 |

    1954 | 1955 | Tweets not working for you? 1956 |

    1957 |

    1958 | Hover over the profile pic and click the Following button to unfollow any account. 1959 |

    1960 |
    1961 | 1962 |
    1963 | 1964 |

    1965 | 1966 | Say a lot with a little 1967 |

    1968 |

    1969 | When you see a Tweet you love, tap the heart — it lets the person who wrote it know you shared the love. 1970 |

    1971 |
    1972 | 1973 |
    1974 |

    1975 | 1976 | Spread the word 1977 |

    1978 |

    1979 | The fastest way to share someone else’s Tweet with your followers is with a Retweet. Tap the icon to send it instantly. 1980 |

    1981 |
    1982 | 1983 |
    1984 |

    1985 | 1986 | Join the conversation 1987 |

    1988 |

    1989 | Add your thoughts about any Tweet with a Reply. Find a topic you’re passionate about, and jump right in. 1990 |

    1991 |
    1992 | 1993 | 1994 | 1995 |
    1996 |

    1997 | 1998 | Learn the latest 1999 |

    2000 |

    2001 | Get instant insight into what people are talking about now. 2002 |

    2003 |
    2004 | 2005 |
    2006 |

    2007 | 2008 | Get more of what you love 2009 |

    2010 |

    2011 | Follow more accounts to get instant updates about topics you care about. 2012 |

    2013 |
    2014 | 2015 |
    2016 |

    2017 | 2018 | Find what's happening 2019 |

    2020 |

    2021 | See the latest conversations about any topic instantly. 2022 |

    2023 |
    2024 | 2025 |
    2026 |

    2027 | 2028 | Never miss a Moment 2029 |

    2030 |

    2031 | Catch up instantly on the best stories happening as they unfold. 2032 |

    2033 |
    2034 |
    2035 | 2036 |
    2037 | 2038 | 2039 |
    2040 |
    2041 |
    2042 |
    2043 | 2044 | 2045 | 2046 | 2047 | 2048 |
    2049 |
    2050 |
    2051 |
    2052 | 2053 | 2054 |
    2055 |
    2056 | 2057 |
    2058 | 2062 |
    2063 |
    2064 |
    2065 |
    2066 |
    2067 |
    2070 |
    2071 |
    2077 | 2078 | 2079 | 2080 |
    2081 | 2082 |
    2142 | 2143 | 2144 | 2145 |
    2146 |
    2147 | 2148 | 2149 | 2150 | Donald J. Trump‏ @realDonaldTrump 2151 | 2152 | 2153 | 2154 | 10m10 minutes ago 2155 | 2156 | 2157 | 2158 | 2159 | 2160 |
    2161 |
    2167 | 2168 | 2178 | 2188 | 2198 | 2208 | 2218 | 2228 | 2238 | 2239 | 2240 |
    2241 | 2242 |
    2243 | 2244 |
    2245 |
    2246 | 2252 |
    2253 |
    2254 |
    2255 |
    2256 |
    2257 |
      2258 | 2259 |
    • 2260 | 2261 |
    • 2262 |
    • 2263 | 2264 |
    • 2265 |
    2266 |
    2267 | 2268 |
    2269 | 2270 |
    2271 | 2272 |
    2273 | 2274 |
    2275 | 2276 | 2277 | 2278 |
    2279 |

    Give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore. Send these, the homeless, tempest-tossed to me, I lift my lamp beside the golden door!

    2280 |
    2281 | 2282 | 2283 | 2284 | 2285 | 2286 | 2287 | 2288 |
    2289 |
    2290 | 2291 | 2018-06-24 15:02:02 2292 | 2293 | 2294 | 2295 |
    2296 | 2297 | 2298 |
    2299 |
    2300 | 2301 |
      2302 |
    • 2303 | 2308 | 2309 | 30,743 Retweets 2310 | 2311 |
    • 2312 | 2313 |
    • 2314 | 2319 | 2320 | 117,185 Likes 2321 | 2322 |
    • 2323 | 2324 |
    • 2325 | 2326 | Kevin Brian 2327 | 2328 | 2329 | 2330 | Heather B 2331 | 2332 | 2333 | 2334 | 🚂TrumpGirl🚂🇺🇸 2335 | 2336 | 2337 | 2338 | koda1950 2339 | 2340 | 2341 | 2342 | Deb 2343 | 2344 | 2345 | 2346 | 12th RRDC 2347 | 2348 | 2349 | 2350 | ritan 2351 | 2352 | 2353 | 2354 | Tlozano 2355 | 2356 | 2357 | 2358 | DEBBIE  🐝 2359 | 2360 |
    • 2361 |
    2362 | 2363 | 2364 |
    2365 |
    2366 | 2367 | 2368 | 2369 |
    2370 | 2371 | 2372 | 2373 | 2374 |
    2375 | 2376 | 2377 | 2378 | 2379 | {reply_count} replies 2380 | 2381 | 2382 | 2383 | 2384 | 30,743 Retweets 2385 | 2386 | 2387 | 2388 | 2389 | 117,185 likes 2390 | 2391 | 2392 |
    2393 | 2394 |
    2395 |
    2396 | 2407 |
    2408 | 2409 |
    2410 | 2433 |
    2434 | 2435 | 2436 |
    2437 | 2459 |
    2460 | 2461 | 2462 | 2463 | 2464 | 2465 | 2466 |
    2467 | 2468 |
    2469 | 2470 |
    2471 | 2472 |
    2473 |
    2474 | 2475 |
    2476 | 2477 | 2478 | 2479 |
    2480 |
    2481 |
    2482 |
    2485 |
    2486 |
      2487 | 2488 | 2489 | 2490 | 2491 | 2492 | 2493 | 2494 | 2495 | 2496 | 2497 | 2498 | 2499 | 2500 | 2501 | 2502 | 2503 | 2504 |
    2505 |
    2506 |
    2507 |
    2508 |
    2509 | 2510 | 2511 |

    2512 | 2513 | 2514 |

    2515 | 2516 |

    2517 |
    2518 |
    2519 | 2520 | 2521 |
    2522 |
    2523 | 2524 |
    2525 |
    2526 | 2527 |
    2528 |
    2529 |
    2530 |
    2531 |
    2532 |

    Loading seems to be taking a while.

    2533 |

    2534 | Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information. 2535 |

    2536 |
    2537 |
    2538 |
    2539 | 2540 |
      2541 |
      2542 |
      2543 |
      2544 |
      2545 |
      2546 | 2547 | 2548 | 2549 |
      2550 | 2551 | 2552 |
      2553 |
      2554 |

      Promoted Tweet

      2555 |
        2556 | 2557 |
      2558 |
      2559 |
      2560 | 2561 |
      2562 |
      2563 |
      2564 |
      2565 | 2566 |

      false

      2567 |
      2568 |
      2569 |
        2570 |
      2571 |
      2572 |
      2573 | 2574 |
      2575 |
      2576 | 2577 | 2578 |
      2579 |
      2581 |
      2582 |
      2583 |
        2584 |
      • © 2018 Twitter
      • 2585 |
      • About
      • 2586 |
      • Help Center
      • 2587 |
      • Terms
      • 2588 |
      • Privacy policy
      • 2589 |
      • Cookies
      • 2590 |
      • Ads info
      • 2591 |
      2592 |
      2593 |
      2594 | 2595 |
      2596 | 2597 |
      2598 |
      2599 | 2600 | 2601 |
      2602 |
      2603 |
      2604 |
      2605 | 2606 |
      2607 | 2608 | 2609 | 2610 |
      2611 | 2612 | 2613 | 2614 | 2615 | 2616 | 2617 | 2618 | 2619 | 2620 | 2621 | 2622 | 2623 | 2624 | 2625 | 2626 | --------------------------------------------------------------------------------