Regression
流浪汪星人 怎麼做 data package?
https://data.gov.tw/dataset/25602 98年度台灣地區各縣市流浪狗數調查結果?
https://animal.coa.gov.tw/html/index_06_0621_dog.html
computerR
: 各縣市平均每100個家庭的電腦數目
graduate
: 各縣市研究所畢業者人數
require(dplyr)
require(ggplot2)
#https://www.dropbox.com/s/t8doe35f3o2we2m/dogs.txt?dl=0
# big5 data 用 file - reopen with encoding - save with encoding
dogs <- read.table("../../../data/txt/dogs.txt", header = T, fileEncoding="utf8")
qplot(computerR, adoptedR, data=dogs)
lm.model <- lm(adoptedR~computerR, data=dogs, x =TRUE)
summary(lm.model)
#plot(computerR~adoptedR, data=dogs)
ggplot(dogs, aes(x = computerR, y = adoptedR)) +
geom_point() +
stat_smooth(method = "lm", col = "red")
anova(lm.model)
- 殘差分析 (Residuals analysis)
plot(lm.model)
resid <- lm.model$residuals
# using ggplot: https://rpubs.com/therimalaya/43190
# check normality
shapiro.test(resid)
- Correlation matrix 選取解釋變數
dogs1 <- dogs[-c(1,5)]
round(cor(dogs1),2); head(dogs1)
pairs(dogs1)
# or using ggplot2
#install.package('GGally')
require(GGally)
Loading required package: GGally
Registered S3 method overwritten by 'GGally':
method from
+.gg ggplot2
Attaching package: ‘GGally’
The following object is masked from ‘package:dplyr’:
nasa
ggpairs(dogs1[, c(2, 4:6)])
Error in ggpairs(dogs1[, c(2, 4:6)]) : 找不到物件 'dogs1'
比較紐約狗
The nycdogs
package contains three datasets, nyc_license, nyc_bites
, and nyc_zips
. They contain, respectively, data on all licensed dogs in New York city, data on reported dog bites in New York city, and geographical data for New York city at the zip code level.
- nycdogs is a data package, bundling several datasets into a convenient format.
#devtools::install_github("kjhealy/nycdogs")
library(tidyverse)
library(sf)
require(nycdogs)
Loading required package: nycdogs
To look at the tibble that contains the licensing data
nyc_license
- use the
nyc_zips
object to create a map of, for example, the prevalence of dog names by zip code:
nyc_coco <- nyc_license %>%
group_by(zip_code, animal_name) %>%
tally() %>%
mutate(freq = n / sum(n),
pct = round(freq*100, 2)) %>%
filter(animal_name == "Coco")
nyc_coco
coco_map <- left_join(nyc_zips, nyc_coco)
Joining, by = "zip_code"
## Map theme
theme_nymap <- function(base_size=9, base_family="") {
require(grid)
theme_bw(base_size=base_size, base_family=base_family) %+replace%
theme(axis.line=element_blank(),
axis.text=element_blank(),
axis.ticks=element_blank(),
axis.title=element_blank(),
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid=element_blank(),
panel.spacing=unit(0, "lines"),
plot.background=element_blank(),
legend.justification = c(0,0),
legend.position = c(0.1, 0.6),
legend.direction = "horizontal"
)
}
coco_map %>% ggplot(mapping = aes(fill = pct)) +
geom_sf(color = "gray80", size = 0.1) +
scale_fill_viridis_c(option = "A") +
labs(fill = "Percent of Licensed Dogs") +
annotate(geom = "text", x = -74.145, y = 40.82,
label = "Where's Coco?", size = 6) +
theme_nymap() +
guides(fill = guide_legend(title.position = "top",
label.position = "bottom"))
Topic modeling
從文件中找出潛在「主題」的統計模型。
LDA 的[數學推導](原文:Blei, David M., Andrew Y. Ng, and Michael I. Jordan. 2003. “Latent Dirichlet Allocation.” The Journal of Machine Learning Research 3(1): 993-1022.)
先用 quanteda
的例子練習看看。
require(quanteda)
require(quanteda.corpora)
require(lubridate)
require(topicmodels)
corp_news <- download('data_corpus_guardian')
嘗試 URL 'https://www.dropbox.com/s/7mu92jzodpq11zc/data_corpus_guardian.rds?dl=1&v=1'
Content type 'application/binary' length 11347175 bytes (10.8 MB)
==================================================
downloaded 10.8 MB
corp_news_subset <- corpus_subset(corp_news, 'date' >= 2016)
ndoc(corp_news_subset)
[1] 6000
記得在文本處理中,採 non-position 的作法,要先把 text 表徵成 document-term matrix
(document-feature matrix
)。 where rows represent documents, and columns terms. Each cell is a count of how many times the term occurs in the document. Terms are typically words, but could be any n-gram of interest.同時也要(在一些預設之下)決定如何前處理你的資料。
- 以這個例子來說,前處理包括了移除功能詞、標點符號;找出顯著特徵詞作為 features the top 5% of the most frequent features (
min_termfreq = 0.95
) that appear in less than 10% of all documents (max_docfreq = 0.1
) using dfm_trim()
to focus on common but distinguishing features.
dfmat_news <- dfm(corp_news, remove_punct = TRUE, remove = stopwords('en')) %>%
dfm_remove(c('*-time', '*-timeUpdated', 'GMT', 'BST')) %>%
dfm_trim(min_termfreq = 0.95, termfreq_type = "quantile",
max_docfreq = 0.1, docfreq_type = "prop")
dfmat_news <- dfmat_news[ntoken(dfmat_news) > 0,]
- 施行主題模型 topic modeling (使用
topicmodel
套件中的 LDA
),預先決定主題數量 \(k\) (需要一點時間)
dtm <- convert(dfmat_news, to = "topicmodels")
lda <- LDA(dtm, k = 10)
- 建好模型之後,就可以看看這些主題使用了哪些重要詞彙
terms(lda, 10)
Topic 1 Topic 2 Topic 3 Topic 4 Topic 5
[1,] "hospital" "online" "nhs" "climate" "officers"
[2,] "violence" "game" "food" "china" "investigation"
[3,] "died" "games" "workers" "chinese" "justice"
[4,] "doctors" "music" "funding" "leadership" "inquiry"
[5,] "medical" "users" "housing" "paris" "allegations"
[6,] "child" "google" "income" "agreement" "trial"
[7,] "parents" "apple" "scheme" "development" "officer"
[8,] "woman" "internet" "customers" "elections" "charges"
[9,] "mental" "facebook" "cuts" "trade" "criminal"
[10,] "mother" "video" "data" "politics" "alleged"
Topic 6 Topic 7 Topic 8 Topic 9 Topic 10
[1,] "energy" "trump" "mps" "syria" "markets"
[2,] "water" "clinton" "australia" "military" "prices"
[3,] "climate" "republican" "referendum" "refugees" "shares"
[4,] "gas" "sanders" "australian" "isis" "oil"
[5,] "project" "obama" "corbyn" "attacks" "sales"
[6,] "land" "donald" "labor" "russian" "rate"
[7,] "environmental" "cruz" "tory" "syrian" "banks"
[8,] "green" "2016" "2016" "forces" "euro"
[9,] "coal" "hillary" "mp" "russia" "investors"
[10,] "food" "presidential" "osborne" "islamic" "quarter"
docvars(dfmat_news, 'topic') <- topics(lda)
head(topics(lda), 20)
text136751 text118588 text45146 text93623 text136585 text65682 text107174
4 2 10 8 8 5 3
text22792 text32425 text139163 text169133 text90312 text153451 text31104
5 9 3 1 6 5 3
text163885 text81309 text157885 text99128 text173244 text27905
6 10 2 9 6 9
應用
多觀摩一些專案,例如
Every year since 1947, representatives of UN member states gather at the annual sessions of the United Nations General Assembly. The centrepiece of each session is the General Debate. This is a forum at which leaders and other senior officials deliver statements that present their government’s perspective on the major issues in world politics. These statements are akin to the annual legislative state-of-the-union addresses in domestic politics. This new dataset, the UN General Debate Corpus (UNGDC), introduces the corpus of texts of General Debate statements from 1970 (Session 25) to 2016 (Session 71). Basic visualization and corpus exploration tools are available here.
完整從 http://shakespeare.mit.edu 抓檔過程在此。但若理解不需要再無故排放 CO2。資料在此。說明參見:https://m-clark.github.io/text-analysis-with-R/topic-modeling.html
可以參考 Julia Silge (text mining with R 作者) 最近做的 side project 福爾摩斯的故事
# `stm` require `glmnet`, which requieres R >= 3.6.0 so you would have to update R to be able to install it library(stm)
# check your R version with `version`, download latest R (3.6.2), install and restart Rstudio
#library(stm)
----------------------------------------
# Word embeddings
https://cbail.github.io/textasdata/word2vec/rmarkdown/word2vec.html
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIE1vZGVsaW5nLiB3ZWVrMTUiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCgoKIyBSZWdyZXNzaW9uCgrmtYHmtarmsarmmJ/kurog5oCO6bq85YGaIGRhdGEgcGFja2FnZT8KCmh0dHBzOi8vZGF0YS5nb3YudHcvZGF0YXNldC8yNTYwMgo5OOW5tOW6puWPsOeBo+WcsOWNgOWQhOe4o+W4gua1gea1queLl+aVuOiqv+afpee1kOaenD8KCmh0dHBzOi8vYW5pbWFsLmNvYS5nb3YudHcvaHRtbC9pbmRleF8wNl8wNjIxX2RvZy5odG1sCgoKCgotIGBjb21wdXRlclJgOiDlkITnuKPluILlubPlnYfmr48xMDDlgIvlrrbluq3nmoTpm7vohabmlbjnm64KLSBgZ3JhZHVhdGVgOiDlkITnuKPluILnoJTnqbbmiYDnlaLmpa3ogIXkurrmlbgKCgpgYGB7cn0KcmVxdWlyZShkcGx5cikKcmVxdWlyZShnZ3Bsb3QyKQojaHR0cHM6Ly93d3cuZHJvcGJveC5jb20vcy90OGRvZTM1ZjNvMndlMm0vZG9ncy50eHQ/ZGw9MAojIGJpZzUgZGF0YSDnlKggZmlsZSAtIHJlb3BlbiB3aXRoIGVuY29kaW5nIC0gc2F2ZSB3aXRoIGVuY29kaW5nCmRvZ3MgPC0gcmVhZC50YWJsZSgiLi4vLi4vLi4vZGF0YS90eHQvZG9ncy50eHQiLCBoZWFkZXIgPSBULCBmaWxlRW5jb2Rpbmc9InV0ZjgiKQpxcGxvdChjb21wdXRlclIsIGFkb3B0ZWRSLCBkYXRhPWRvZ3MpCgpgYGAKCgoKLSDov7Tmrbjkv4LmlbjoqIjnrpfmjqjoq5YKYGBge3J9CmxtLm1vZGVsIDwtIGxtKGFkb3B0ZWRSfmNvbXB1dGVyUiwgZGF0YT1kb2dzLCB4ID1UUlVFKQpzdW1tYXJ5KGxtLm1vZGVsKQoKYGBgCgoKYGBge3J9CiNwbG90KGNvbXB1dGVyUn5hZG9wdGVkUiwgZGF0YT1kb2dzKQpnZ3Bsb3QoZG9ncywgYWVzKHggPSBjb21wdXRlclIsIHkgPSBhZG9wdGVkUikpICsgCiAgZ2VvbV9wb2ludCgpICsKICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikKYGBgCgoKCi0g57Ch5Zau57ea5oCn6L+05q2455qEIEFOT1ZBIOihqOagvApgYGB7cn0KYW5vdmEobG0ubW9kZWwpCmBgYAoKCi0g5q6Y5beu5YiG5p6QIChSZXNpZHVhbHMgYW5hbHlzaXMpCgpgYGB7cn0KcGxvdChsbS5tb2RlbCkKcmVzaWQgPC0gbG0ubW9kZWwkcmVzaWR1YWxzCiMgdXNpbmcgZ2dwbG90OiBodHRwczovL3JwdWJzLmNvbS90aGVyaW1hbGF5YS80MzE5MAojIGNoZWNrIG5vcm1hbGl0eQpzaGFwaXJvLnRlc3QocmVzaWQpCgpgYGAKCgoKLSBDb3JyZWxhdGlvbiBtYXRyaXgg6YG45Y+W6Kej6YeL6K6K5pW4CgpgYGB7cn0KZG9nczEgPC0gZG9nc1stYygxLDUpXQpyb3VuZChjb3IoZG9nczEpLDIpOyBoZWFkKGRvZ3MxKQpgYGAKCgoKYGBge3J9CnBhaXJzKGRvZ3MxKQojIG9yIHVzaW5nIGdncGxvdDIgCmBgYAoKCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlKCdHR2FsbHknKQpyZXF1aXJlKEdHYWxseSkKZ2dwYWlycyhkb2dzMVssIGMoMiwgNDo2KV0pCgpgYGAKCiMjIOavlOi8g+e0kOe0hOeLlwoKClRoZSBgbnljZG9nc2AgcGFja2FnZSBjb250YWlucyB0aHJlZSBkYXRhc2V0cywgYG55Y19saWNlbnNlLCBueWNfYml0ZXNgLCBhbmQgYG55Y196aXBzYC4gVGhleSBjb250YWluLCByZXNwZWN0aXZlbHksIGRhdGEgb24gYWxsIGxpY2Vuc2VkIGRvZ3MgaW4gTmV3IFlvcmsgY2l0eSwgZGF0YSBvbiByZXBvcnRlZCBkb2cgYml0ZXMgaW4gTmV3IFlvcmsgY2l0eSwgYW5kIGdlb2dyYXBoaWNhbCBkYXRhIGZvciBOZXcgWW9yayBjaXR5IGF0IHRoZSB6aXAgY29kZSBsZXZlbC4KCi0gbnljZG9ncyBpcyBhIGRhdGEgcGFja2FnZSwgYnVuZGxpbmcgc2V2ZXJhbCBkYXRhc2V0cyBpbnRvIGEgY29udmVuaWVudCBmb3JtYXQuCgpgYGB7cn0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigia2poZWFseS9ueWNkb2dzIikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2YpCnJlcXVpcmUobnljZG9ncykKYGBgCgoKVG8gbG9vayBhdCB0aGUgdGliYmxlIHRoYXQgY29udGFpbnMgdGhlIGxpY2Vuc2luZyBkYXRhCgpgYGB7cn0KbnljX2xpY2Vuc2UKYGBgCgoKCi0gdXNlIHRoZSBgbnljX3ppcHNgIG9iamVjdCB0byBjcmVhdGUgYSBtYXAgb2YsIGZvciBleGFtcGxlLCB0aGUgcHJldmFsZW5jZSBvZiBkb2cgbmFtZXMgYnkgemlwIGNvZGU6CgoKYGBge3J9Cm55Y19jb2NvIDwtIG55Y19saWNlbnNlICU+JQogICAgZ3JvdXBfYnkoemlwX2NvZGUsIGFuaW1hbF9uYW1lKSAlPiUKICAgIHRhbGx5KCkgJT4lCiAgICBtdXRhdGUoZnJlcSA9IG4gLyBzdW0obiksCiAgICAgICAgICAgcGN0ID0gcm91bmQoZnJlcSoxMDAsIDIpKSAlPiUKICAgIGZpbHRlcihhbmltYWxfbmFtZSA9PSAiQ29jbyIpCgpueWNfY29jbwpgYGAKCgpgYGB7cn0KY29jb19tYXAgPC0gbGVmdF9qb2luKG55Y196aXBzLCBueWNfY29jbykKIyMgTWFwIHRoZW1lCnRoZW1lX255bWFwIDwtIGZ1bmN0aW9uKGJhc2Vfc2l6ZT05LCBiYXNlX2ZhbWlseT0iIikgewogICAgcmVxdWlyZShncmlkKQogICAgdGhlbWVfYncoYmFzZV9zaXplPWJhc2Vfc2l6ZSwgYmFzZV9mYW1pbHk9YmFzZV9mYW1pbHkpICUrcmVwbGFjZSUKICAgICAgICB0aGVtZShheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgIGF4aXMudGV4dD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgYXhpcy50aXRsZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgcGFuZWwuYmFja2dyb3VuZD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBwYW5lbC5zcGFjaW5nPXVuaXQoMCwgImxpbmVzIiksCiAgICAgICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwwKSwKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuMSwgMC42KSwgCiAgICAgICAgICAgICAgbGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIgogICAgICAgICkKfQpgYGAKCi0g5Y+v5Lul5L2c5Zyw5ZyWCgoKYGBge3J9CmNvY29fbWFwICU+JSBnZ3Bsb3QobWFwcGluZyA9IGFlcyhmaWxsID0gcGN0KSkgKwogICAgZ2VvbV9zZihjb2xvciA9ICJncmF5ODAiLCBzaXplID0gMC4xKSArCiAgICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiQSIpICsKICAgIGxhYnMoZmlsbCA9ICJQZXJjZW50IG9mIExpY2Vuc2VkIERvZ3MiKSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IC03NC4xNDUsIHkgPSA0MC44MiwgCiAgICAgICAgICAgbGFiZWwgPSAiV2hlcmUncyBDb2NvPyIsIHNpemUgPSA2KSArIAogICAgdGhlbWVfbnltYXAoKSArIAogICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUucG9zaXRpb24gPSAidG9wIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkKYGBgCgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgVG9waWMgbW9kZWxpbmcgCgotIOW+nuaWh+S7tuS4reaJvuWHuua9m+WcqOOAjOS4u+mhjOOAjeeahOe1seioiOaooeWei+OAggoKLSBMREEg55qEW+aVuOWtuOaOqOWwjl0o5Y6f5paH77yaQmxlaSwgRGF2aWQgTS4sIEFuZHJldyBZLiBOZywgYW5kIE1pY2hhZWwgSS4gSm9yZGFuLiAyMDAzLiAiTGF0ZW50IERpcmljaGxldCBBbGxvY2F0aW9uLiIgVGhlIEpvdXJuYWwgb2YgTWFjaGluZSBMZWFybmluZyBSZXNlYXJjaCAzKDEpOiA5OTMtMTAyMi4pCgotIOWFiOeUqCBgcXVhbnRlZGFgIOeahOS+i+WtkOe3tOe/kueci+eci+OAggoKYGBge3J9CnJlcXVpcmUocXVhbnRlZGEpCnJlcXVpcmUocXVhbnRlZGEuY29ycG9yYSkKcmVxdWlyZShsdWJyaWRhdGUpCnJlcXVpcmUodG9waWNtb2RlbCkKYGBgCgoKLSDkuIvovInoi7HlnIvooZvloLHos4fmlpnvvIzmjJHpgbggMjAxNiDlh7rniYjnmoTmlrDogZ4KCmBgYHtyfQpjb3JwX25ld3MgPC0gZG93bmxvYWQoJ2RhdGFfY29ycHVzX2d1YXJkaWFuJykKY29ycF9uZXdzX3N1YnNldCA8LSBjb3JwdXNfc3Vic2V0KGNvcnBfbmV3cywgJ2RhdGUnID49IDIwMTYpCm5kb2MoY29ycF9uZXdzX3N1YnNldCkKYGBgCgoKCj4g6KiY5b6X5Zyo5paH5pys6JmV55CG5Lit77yM5o6hIG5vbi1wb3NpdGlvbiDnmoTkvZzms5XvvIzopoHlhYjmioogdGV4dCDooajlvrXmiJAgYGRvY3VtZW50LXRlcm0gbWF0cml4YCAoYGRvY3VtZW50LWZlYXR1cmUgbWF0cml4YCnjgIIgd2hlcmUgcm93cyByZXByZXNlbnQgZG9jdW1lbnRzLCBhbmQgY29sdW1ucyB0ZXJtcy4gRWFjaCBjZWxsIGlzIGEgY291bnQgb2YgaG93IG1hbnkgdGltZXMgdGhlIHRlcm0gb2NjdXJzIGluIHRoZSBkb2N1bWVudC4gVGVybXMgYXJlIHR5cGljYWxseSB3b3JkcywgYnV0IGNvdWxkIGJlIGFueSBuLWdyYW0gb2YgaW50ZXJlc3Qu5ZCM5pmC5Lmf6KaB77yI5Zyo5LiA5Lqb6aCQ6Kit5LmL5LiL77yJ5rG65a6a5aaC5L2V5YmN6JmV55CG5L2g55qE6LOH5paZ44CCCgoKLSDku6XpgJnlgIvkvovlrZDkvoboqqrvvIzliY3omZXnkIbljIXmi6zkuobnp7vpmaTlip/og73oqZ7jgIHmqJnpu57nrKbomZ/vvJvmib7lh7rpoa/okZfnibnlvrXoqZ7kvZzngrogKipmZWF0dXJlcyoqICB0aGUgdG9wIDUlIG9mIHRoZSBtb3N0IGZyZXF1ZW50IGZlYXR1cmVzIChgbWluX3Rlcm1mcmVxID0gMC45NWApIHRoYXQgYXBwZWFyIGluIGxlc3MgdGhhbiAxMCUgb2YgYWxsIGRvY3VtZW50cyAoYG1heF9kb2NmcmVxID0gMC4xYCkgdXNpbmcgYGRmbV90cmltKClgIHRvIGZvY3VzIG9uIGNvbW1vbiBidXQgZGlzdGluZ3Vpc2hpbmcgZmVhdHVyZXMuCgpgYGB7cn0KZGZtYXRfbmV3cyA8LSBkZm0oY29ycF9uZXdzLCByZW1vdmVfcHVuY3QgPSBUUlVFLCByZW1vdmUgPSBzdG9wd29yZHMoJ2VuJykpICU+JSAKICAgIGRmbV9yZW1vdmUoYygnKi10aW1lJywgJyotdGltZVVwZGF0ZWQnLCAnR01UJywgJ0JTVCcpKSAlPiUgCiAgICBkZm1fdHJpbShtaW5fdGVybWZyZXEgPSAwLjk1LCB0ZXJtZnJlcV90eXBlID0gInF1YW50aWxlIiwgCiAgICAgICAgICAgICBtYXhfZG9jZnJlcSA9IDAuMSwgZG9jZnJlcV90eXBlID0gInByb3AiKQoKZGZtYXRfbmV3cyA8LSBkZm1hdF9uZXdzW250b2tlbihkZm1hdF9uZXdzKSA+IDAsXQoKYGBgCgoKLSDmlr3ooYzkuLvpoYzmqKHlnosgdG9waWMgbW9kZWxpbmcgKOS9v+eUqCBgdG9waWNtb2RlbGAg5aWX5Lu25Lit55qEIGBMREFgKe+8jOmgkOWFiOaxuuWumuS4u+mhjOaVuOmHjyAkayQg77yI6ZyA6KaB5LiA6bue5pmC6ZaT77yJCgpgYGB7cn0KZHRtIDwtIGNvbnZlcnQoZGZtYXRfbmV3cywgdG8gPSAidG9waWNtb2RlbHMiKQpsZGEgPC0gTERBKGR0bSwgayA9IDEwKQpgYGAKCgotIOW7uuWlveaooeWei+S5i+W+jO+8jOWwseWPr+S7peeci+eci+mAmeS6m+S4u+mhjOS9v+eUqOS6huWTquS6m+mHjeimgeipnuW9mQoKYGBge3J9CnRlcm1zKGxkYSwgMTApCmBgYAoKLSDkuZ/lj6/ku6XlhLLlrZjotbfkvobnlbbmiJDmlofku7bnmoTlvozoqK3os4fmlpkKCmBgYHtyfQpkb2N2YXJzKGRmbWF0X25ld3MsICd0b3BpYycpIDwtIHRvcGljcyhsZGEpCmhlYWQodG9waWNzKGxkYSksIDIwKQoKYGBgCgotIOaAjum6vOimluimuuWMlumAmeS6m+S4u+mhjOeahOWIhuS9iO+8nwpgTERBdmlzYChodHRwczovL2dpdGh1Yi5jb20vY3BzaWV2ZXJ0L0xEQXZpcy8pCgohW10oaHR0cHM6Ly9rbm93bGVkZ2VyLnJiaW5kLmlvL2ltZy9MREF2aXMucG5nKQoKCiMjIOaHieeUqAoK5aSa6KeA5pGp5LiA5Lqb5bCI5qGI77yM5L6L5aaCCgotIFvoga/lkIjlnIsgR2VuZXJhbCBEZWJhdGUgQ29ycHVzXShodHRwczovL2RhdGEud29ybGQvaWFuL3VuaXRlZC1uYXRpb25zLWdlbmVyYWwtZGViYXRlLWNvcnB1cynjgILlj6/ku6XlhYjmib7nnIvnnIvmmK/lkKbliKXkurrlt7LntpPmioros4fmlpnomZXnkIblpb3kuobvvIzlpoIgW2thZ2dsZSDlubPlj7BdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vdW5pdGVkbmF0aW9ucy91bi1nZW5lcmFsLWRlYmF0ZXMjdW4tZ2VuZXJhbC1kZWJhdGVzLmNzdinjgILnlKjkuLvpoYzmqKHlnovkvobnnIvnnIvkuI3lkIzlubTku6PvvIxb5ZCE5ZyL5Luj6KGo6YO95Zyo6KuH5LuA6bq844CM5Li76aGM44CN44CCXShodHRwOi8vdW5nZC5zbWlraGF5bG92Lm5ldC8pCiAgLSDlu7bkvLjvvJrlj7DngaPlnIvmnIPvvJ/kuI3lkIznuKPluILnmoTorbDmnIPos6roqaLvvJ8KCgo+IEV2ZXJ5IHllYXIgc2luY2UgMTk0NywgcmVwcmVzZW50YXRpdmVzIG9mIFVOIG1lbWJlciBzdGF0ZXMgZ2F0aGVyIGF0IHRoZSBhbm51YWwgc2Vzc2lvbnMgb2YgdGhlIFVuaXRlZCBOYXRpb25zIEdlbmVyYWwgQXNzZW1ibHkuIFRoZSBjZW50cmVwaWVjZSBvZiBlYWNoIHNlc3Npb24gaXMgdGhlIEdlbmVyYWwgRGViYXRlLiBUaGlzIGlzIGEgZm9ydW0gYXQgd2hpY2ggbGVhZGVycyBhbmQgb3RoZXIgc2VuaW9yIG9mZmljaWFscyBkZWxpdmVyIHN0YXRlbWVudHMgdGhhdCBwcmVzZW50IHRoZWlyIGdvdmVybm1lbnTigJlzIHBlcnNwZWN0aXZlIG9uIHRoZSBtYWpvciBpc3N1ZXMgaW4gd29ybGQgcG9saXRpY3MuIFRoZXNlIHN0YXRlbWVudHMgYXJlIGFraW4gdG8gdGhlIGFubnVhbCBsZWdpc2xhdGl2ZSBzdGF0ZS1vZi10aGUtdW5pb24gYWRkcmVzc2VzIGluIGRvbWVzdGljIHBvbGl0aWNzLiBUaGlzIG5ldyBkYXRhc2V0LCB0aGUgVU4gR2VuZXJhbCBEZWJhdGUgQ29ycHVzIChVTkdEQyksIGludHJvZHVjZXMgdGhlIGNvcnB1cyBvZiB0ZXh0cyBvZiBHZW5lcmFsIERlYmF0ZSBzdGF0ZW1lbnRzIGZyb20gMTk3MCAoU2Vzc2lvbiAyNSkgdG8gMjAxNiAoU2Vzc2lvbiA3MSkuIEJhc2ljIHZpc3VhbGl6YXRpb24gYW5kIGNvcnB1cyBleHBsb3JhdGlvbiB0b29scyBhcmUgYXZhaWxhYmxlIGhlcmUuCgoKCgoKLSDnlKjojo7nv4HlkI3liofnjqnnnIvnnIsKCuWujOaVtOW+niBodHRwOi8vc2hha2VzcGVhcmUubWl0LmVkdSDmipPmqpTpgY7nqItb5Zyo5q2kXShodHRwczovL20tY2xhcmsuZ2l0aHViLmlvL3RleHQtYW5hbHlzaXMtd2l0aC1SL3NoYWtlc3BlYXJlLmh0bWwjc2hha2VzcGVhcmUtc3RhcnQtdG8tZmluaXNoKeOAguS9huiLpeeQhuino+S4jemcgOimgeWGjeeEoeaVheaOkuaUviBDTzLjgIJb6LOH5paZ5Zyo5q2kXShodHRwczovL2dpdGh1Yi5jb20vbS1jbGFyay90ZXh0LWFuYWx5c2lzLXdpdGgtUi9ibG9iL21hc3Rlci9kYXRhL3NoYWtlc19kdG1fc3RlbW1lZC5SRGF0YSnjgILoqqrmmI7lj4PopovvvJpodHRwczovL20tY2xhcmsuZ2l0aHViLmlvL3RleHQtYW5hbHlzaXMtd2l0aC1SL3RvcGljLW1vZGVsaW5nLmh0bWwKCgotIOmAsumajueahOS4u+mhjOaooeWeizogU3RydWN0dXJhbCB0b3BpYyBtb2RlbCAoW3dpdGggYHN0bWAgcGFja2FnZV0oaHR0cHM6Ly93d3cuc3RydWN0dXJhbHRvcGljbW9kZWwuY29tLykpIAoK5Y+v5Lul5Y+D6ICDIEp1bGlhIFNpbGdlICh0ZXh0IG1pbmluZyB3aXRoIFIg5L2c6ICFKSDmnIDov5HlgZrnmoQgc2lkZSBwcm9qZWN0IFvnpo/niL7mkanmlq/nmoTmlYXkuotdKGh0dHBzOi8vanVsaWFzaWxnZS5jb20vYmxvZy9zaGVybG9jay1ob2xtZXMtc3RtLykKCgpgYGB7cn0KIyBgc3RtYCByZXF1aXJlIGBnbG1uZXRgLCB3aGljaCByZXF1aWVyZXMgUiA+PSAzLjYuMCBzbyB5b3Ugd291bGQgaGF2ZSB0byB1cGRhdGUgUiB0byBiZSBhYmxlIHRvIGluc3RhbGwgaXQgbGlicmFyeShzdG0pCiMgY2hlY2sgeW91ciBSIHZlcnNpb24gd2l0aCBgdmVyc2lvbmAsIGRvd25sb2FkIGxhdGVzdCBSICgzLjYuMiksIGluc3RhbGwgYW5kIHJlc3RhcnQgUnN0dWRpbwoKI2xpYnJhcnkoc3RtKQoKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIFdvcmQgZW1iZWRkaW5ncwoKaHR0cHM6Ly9jYmFpbC5naXRodWIuaW8vdGV4dGFzZGF0YS93b3JkMnZlYy9ybWFya2Rvd24vd29yZDJ2ZWMuaHRtbAo=