Memuat Packages and Library
packages=c('dplyr', 'tidyverse', 'tidytext', 'ggplot2', 'ggraph', 'knitr', 'quRan')
for (p in packages){
if (! require (p,character.only = T)){
install.packages(p)
}
library(p,character.only = T)
}
Sebelum kita memuat data, mari kita mulai dengan terjemahan bahasa inggris dari surat pertama Al-Qur’an yakni surat Al-Fatihah. Terjemahan ini menggunakan terjemahan Bahasa Inggris dari Dr. Mustafa Khattab, the Clear Quran. Untuk lebih jelasnya bisa dilihat di https://quran.com/1
text <- c("In the Name of Allah—the Most Compassionate, Most Merciful.",
"All praise is for Allah—Lord of all worlds,",
"the Most Compassionate, Most Merciful,",
"Master of the Day of Judgment.",
"You ˹alone˺ we worship and You ˹alone˺ we ask for help.",
"Guide us along the Straight Path,",
"the Path of those You have blessed—not those You are displeased with, or those who are astray.")
text
[1] "In the Name of Allah—the Most Compassionate, Most Merciful."
[2] "All praise is for Allah—Lord of all worlds,"
[3] "the Most Compassionate, Most Merciful,"
[4] "Master of the Day of Judgment."
[5] "You ⾚lone˺ we worship and You ⾚lone˺ we ask for help."
[6] "Guide us along the Straight Path,"
[7] "the Path of those You have blessed—not those You are displeased with, or those who are astray."
Pertama-tama kita perlu memasukkannya ke dalam data frame untuk membuatnya menjadi kumpulan dataset text yang rapi.
text_df <- tibble(line = 1:7, text = text)
text_df
Tibble adalah modern class dari data frame dalam R, tersedia dalam packages dplyr dan tibble. Tibbles sangat bagus untuk digunakan dengan tidy tools.
Perhatikan bahwa data frame yang berisi teks ini belum kompatibel dengan analisis teks yang rapi. Kami tidak dapat menyaring kata atau menghitung yang paling sering muncul, karena setiap baris terdiri dari beberapa kata gabungan. Kita perlu mengonversi terlebih dahulu sehingga memiliki satu-token-per-dokumen-per-baris.
Token adalah unit teks yang bermakna, paling sering berupa kata, yang bisa digunakan untuk analisis lebih lanjut, dan tokenisasi adalah proses pemisahan teks menjadi token.
Dalam contoh pertama ini, kita hanya memiliki satu dokumen (Al-Fatihah), tetapi kita akan mengeksplorasi contoh dengan banyak dokumen (Surat).
Dalam kerangka teks rapi kita, kita perlu memecah teks menjadi token individu (proses yang disebut tokenization) dan mengubahnya menjadi struktur data yang rapi. * Gunakan fungsi unnest_tokens() tidytext.
text_df %>%
unnest_tokens(word, text)
Setelah menggunakan unnest_tokens, ada satu token (kata) di setiap baris dari frame data baru; tokenization default di unnest_tokens() adalah untuk kata tunggal. Kolom lain, seperti nomor baris dari setiap kata, dipertahankan. Tanda baca telah dihilangkan.Secara default, unnest_tokens() mengonversi token menjadi huruf kecil, yang membuatnya lebih mudah untuk dibandingkan atau digabungkan dengan kumpulan data lainnya. (Gunakan argumen to_lower = FALSE untuk mematikan fitur ini). Sekarang kita dapat memanipulasi, memproses, dan memvisualisasikan teks menggunakan alat standar tidy tools, yaitu dplyr, rapir, dan ggplot2
Fokus pada versi dan Variabel Quran yang Dipilih Paket quran memiliki 4 versi quran. Ini memberikan ayat-ayat penuh Al-Qur’an, dalam bingkai data yang berisi satu baris per ayat, diformat agar nyaman untuk analisis teks. dari ) dan di , .
quran_ar (Quran dalam bahasa Arab dengan vokal) quran_ar_min (Quran dalam bahasa Arab tanpa vokal) quran_en_sahih (Quran dalam bahasa Inggris, terjemahan Shahih Internasional) quran_en_yusufali (Quran dalam bahasa Inggris, terjemahan Yusuf Ali) kita akan menganalisis variabel yang dipilih (kolom) dari quran_en_sahih
quranES <- quran_en_sahih %>% select(surah_id,
ayah_id,
surah_title_en,
surah_title_en_trans,
revelation_type,
text,
surah,
ayah,
ayah_title)
# quranES
Mengerjakan ini sebagai kumpulan data yang rapi, kita perlu merestrukturisasinya dalam format satu-token-per-baris, yang seperti yang kita lihat sebelumnya dilakukan dengan fungsi unnest_tokens().
tidyES <- quranES %>%
unnest_tokens(word, text)
tidyES
Fungsi ini memisahkan setiap baris teks dalam data frame asli menjadi token. Tokenisasi default adalah untuk kata-kata, tetapi opsi lain mencakup karakter, n-gram, kalimat, baris, paragraf, atau pemisahan di sekitar pola regex.
Sekarang data dalam format satu kata per baris, kita dapat memanipulasinya dengan tidy tools seperti dplyr. Seringkali dalam analisis teks, kami menghapus kata-kata berhenti; stop words adalah kata-kata yang tidak berguna untuk analisis, biasanya kata-kata yang sangat umum seperti “the”, “of”, “to”, dan sebagainya dalam bahasa Inggris. Kita dapat menghapus stopwords (disimpan dalam tidytext dataset stop_words) dengan anti_join().
data(stop_words)
tidyES <- tidyES %>%
anti_join(stop_words)
Joining, by = "word"
Dataset stop_words dalam package tidytext berisi stopwords dari tiga leksikon. Kita dapat menggunakan semuanya bersama-sama, seperti yang kita miliki di sini, atau filter() untuk hanya menggunakan satu set stopword jika itu lebih sesuai untuk analisis tertentu.
Count dan Plot
Kita juga dapat menggunakan dplyr’s count() untuk menemukan kata-kata yang paling umum di seluruh Quran secara keseluruhan.
Karena kami telah menggunakan tidytools, jumlah kata disimpan dalam data frame yang rapi. Hal ini memungkinkan kita untuk menyalurkannya langsung ke paket ggplot2, misalnya untuk membuat visualisasi kata-kata yang paling umum dalam Sahih International Translation of the Quran. Kami memplot kata-kata yang muncul lebih dari 150 kali.
tidyES %>% count(word, sort = TRUE)
tidyES %>%
count(word, sort = TRUE) %>%
filter(n > 150) %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(x = word, y = n)) +
geom_col() +
xlab(NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10)
)

Lakukan Hal yang sama untuk Quran in English Terjemahan Yusuf Ali
quranEY <- quran_en_yusufali %>% select(surah_id,
ayah_id,
surah_title_en,
surah_title_en_trans,
revelation_type,
text,
surah,
ayah,
ayah_title)
# quranES
tidyEY <- quranEY %>%
unnest_tokens(word, text)
tidyEY
my_stopwords <- tibble(word = c('ye', 'verily', 'will', 'said', 'say', 'us',
'thy', 'thee', 'thou', 'hath', 'doth'))
tidyEY <- tidyEY %>%
anti_join(my_stopwords)
Joining, by = "word"
tidyEY %>%
count(word, sort = TRUE) %>%
filter(n > 150) %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(x = word, y = n)) +
geom_col() +
xlab(NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10)
)

Sentimen Dataset
get_sentiments("bing")
Kata Positif dan Negatif yang paling Umum
bing_word_counts <- tidyES %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
ungroup()
Joining, by = "word"
bing_word_counts
bing_word_counts %>%
group_by(sentiment) %>%
top_n(20) %>%
ungroup() %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free_y") +
labs(y = "Contribution to sentiment",
x = NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10))
Selecting by n

bing_word_countsEY <- tidyEY %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
ungroup()
Joining, by = "word"
bing_word_countsEY
bing_word_countsEY %>%
group_by(sentiment) %>%
top_n(20) %>%
ungroup() %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free_y") +
labs(y = "Contribution to sentiment",
x = NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10))
Selecting by n

Memperbesar kedalam Surah
bingnegative <- get_sentiments("bing") %>%
filter(sentiment == "negative")
wordcounts <- tidyES %>%
group_by(surah_title_en) %>%
summarize(words = n())
tidyES %>%
semi_join(bingnegative) %>%
group_by(surah_title_en) %>%
summarize(negativewords = n()) %>%
left_join(wordcounts, by = c("surah_title_en")) %>%
mutate(ratio = negativewords/words) %>%
top_n(20) %>%
ggplot(aes(x = surah_title_en, y = ratio)) +
geom_col() +
xlab(NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10))
Joining, by = "word"
Selecting by ratio

bingnegative <- get_sentiments("bing") %>%
filter(sentiment == "negative")
wordcounts <- tidyEY %>%
group_by(surah_title_en) %>%
summarize(words = n())
tidyEY %>%
semi_join(bingnegative) %>%
group_by(surah_title_en) %>%
summarize(negativewords = n()) %>%
left_join(wordcounts, by = c("surah_title_en")) %>%
mutate(ratio = negativewords/words) %>%
top_n(20) %>%
ggplot(aes(x = surah_title_en, y = ratio)) +
geom_col() +
xlab(NULL) +
coord_flip() +
theme(axis.text = element_text(
angle = 0,
color="blue",
size=10))
Joining, by = "word"
Selecting by ratio

Wordclouds
library(wordcloud)
Loading required package: RColorBrewer
tidyES %>%
count(word) %>%
with(wordcloud(word, n, max.words = 100))

library(wordcloud)
tidyEY %>%
count(word) %>%
with(wordcloud(word, n, max.words = 100))

library(reshape2)
Attaching package: ‘reshape2’
The following object is masked from ‘package:tidyr’:
smiths
tidyES %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(colors = c("#eb52a6", "#54f0b1"),
max.words = 50)
Joining, by = "word"
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
guidance could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
paradise could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
sufficient could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
benefit could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
righteousness could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
covenant could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
unquestionably could not be fit on page. It will not be plotted.
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
enjoyment could not be fit on page. It will not be plotted.

library(reshape2)
tidyEY %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(colors = c("#eb52a6", "#54f0b1"),
max.words = 50)
Joining, by = "word"
Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words = 50) :
righteous could not be fit on page. It will not be plotted.

Kesimpulan
Analisis sentimen menyediakan cara untuk memahami sikap dan pendapat yang diungkapkan dalam teks. dengan mengeksplorasi bagaimana menerapkan analisis sentimen untuk dua versi Quran bahasa Inggris menggunakan prinsip-prinsip tidydata. Sebagian besar hasilnya hampir mirip.
Daftar Pustaka
https://rpubs.com/azmanH/686029
LS0tDQp0aXRsZTogIkFuYWxpc2lzIFNlbnRpbWVuIFRlcmplbWFoYW4gQmFoYXNhIEluZ2dyaXMgQWwtUXVyYW4gTWVuZ2d1bmFrYW4gVGlkeVRleHQiDQphdXRob3I6ICJQcm9mLiBEciBTdWhhcnRvbm8gTS5Lb20gJiBVJ3VuIFNldGlhd2F0aSwgUy5Lb20iDQpkYXRlOiAiMTEvMy8yMDIxIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogc3BhY2VsYWINCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDINCiAgICB0b2NfZmxvYXQ6IHRydWUNCnN1YnRpdGxlOiBNYWdpc3RlciBJbmZvcm1hdGlrYSBVSU4gTWF1bGFuYSBNYWxpayBJYnJhaGltIE1hbGFuZyANCi0tLQ0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpib2R5eyAvKiBOb3JtYWwgICovDQogICAgICBmb250LXNpemU6IDE0cHg7DQogIH0NCnRkIHsgIC8qIFRhYmxlICAqLw0KICBmb250LXNpemU6IDEycHg7DQp9DQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMzhweDsNCiAgY29sb3I6IGxpZ2h0Ymx1ZTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQpoMSB7IC8qIEhlYWRlciAxICovDQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtCbHVlOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAqLw0KICBmb250LXNpemU6IDIwcHg7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCn0NCmgzIHsgLyogSGVhZGVyIDMgKi8NCiAgZm9udC1zaXplOiAxNnB4Ow0KIyAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCn0NCmg0IHsgLyogSGVhZGVyIDQgKi8NCiAgZm9udC1zaXplOiAxNHB4Ow0KICBjb2xvcjogRGFya0JsdWU7DQp9DQpjb2RlLnJ7IC8qIENvZGUgYmxvY2sgKi8NCiAgICBmb250LXNpemU6IDEycHg7DQp9DQpwcmUgeyAvKiBDb2RlIGJsb2NrIC0gZGV0ZXJtaW5lcyBjb2RlIHNwYWNpbmcgYmV0d2VlbiBsaW5lcyAqLw0KICAgIGZvbnQtc2l6ZTogMTJweDsNCn0NCjwvc3R5bGU+DQoNCiMgTWVtdWF0IFBhY2thZ2VzIGFuZCBMaWJyYXJ5DQoNCmBgYHtyfQ0KcGFja2FnZXM9YygnZHBseXInLCAndGlkeXZlcnNlJywgJ3RpZHl0ZXh0JywgJ2dncGxvdDInLCAnZ2dyYXBoJywgJ2tuaXRyJywgJ3F1UmFuJykNCmZvciAocCBpbiBwYWNrYWdlcyl7DQogIGlmICghIHJlcXVpcmUgKHAsY2hhcmFjdGVyLm9ubHkgPSBUKSl7DQogICAgaW5zdGFsbC5wYWNrYWdlcyhwKQ0KICB9DQpsaWJyYXJ5KHAsY2hhcmFjdGVyLm9ubHkgPSBUKQ0KfQ0KYGBgDQoNClNlYmVsdW0ga2l0YSBtZW11YXQgZGF0YSwgbWFyaSBraXRhIG11bGFpIGRlbmdhbiB0ZXJqZW1haGFuIGJhaGFzYSBpbmdncmlzIGRhcmkgc3VyYXQgcGVydGFtYSBBbC1RdXInYW4geWFrbmkgc3VyYXQgQWwtRmF0aWhhaC4gVGVyamVtYWhhbiBpbmkgbWVuZ2d1bmFrYW4gdGVyamVtYWhhbiBCYWhhc2EgSW5nZ3JpcyBkYXJpIGBEci4gTXVzdGFmYSBLaGF0dGFiLCB0aGUgQ2xlYXIgUXVyYW5gLiBVbnR1ayBsZWJpaCBqZWxhc255YSBiaXNhIGRpbGloYXQgZGkgPGEgaHJlZj0iaHR0cHM6Ly9xdXJhbi5jb20vMSI+aHR0cHM6Ly9xdXJhbi5jb20vMTwvYT4NCg0KYGBge3J9DQp0ZXh0IDwtIGMoIkluIHRoZSBOYW1lIG9mIEFsbGFo4oCUdGhlIE1vc3QgQ29tcGFzc2lvbmF0ZSwgTW9zdCBNZXJjaWZ1bC4iLA0KICAgICAgICAgICJBbGwgcHJhaXNlIGlzIGZvciBBbGxhaOKAlExvcmQgb2YgYWxsIHdvcmxkcywiLA0KICAgICAgICAgICJ0aGUgTW9zdCBDb21wYXNzaW9uYXRlLCBNb3N0IE1lcmNpZnVsLCIsDQogICAgICAgICAgIk1hc3RlciBvZiB0aGUgRGF5IG9mIEp1ZGdtZW50LiIsDQogICAgICAgICAgIllvdSDLuWFsb25ly7ogd2Ugd29yc2hpcCBhbmQgWW91IMu5YWxvbmXLuiB3ZSBhc2sgZm9yIGhlbHAuIiwNCiAgICAgICAgICAiR3VpZGUgdXMgYWxvbmcgdGhlIFN0cmFpZ2h0IFBhdGgsIiwNCiAgICAgICAgICAidGhlIFBhdGggb2YgdGhvc2UgWW91IGhhdmUgYmxlc3NlZOKAlG5vdCB0aG9zZSBZb3UgYXJlIGRpc3BsZWFzZWQgd2l0aCwgb3IgdGhvc2Ugd2hvIGFyZSBhc3RyYXkuIikNCg0KdGV4dA0KYGBgDQpQZXJ0YW1hLXRhbWEga2l0YSBwZXJsdSBtZW1hc3Vra2FubnlhIGtlIGRhbGFtICBkYXRhIGZyYW1lIHVudHVrIG1lbWJ1YXRueWEgbWVuamFkaSBrdW1wdWxhbiBkYXRhc2V0IHRleHQgeWFuZyByYXBpLg0KDQpgYGB7cn0NCnRleHRfZGYgPC0gdGliYmxlKGxpbmUgPSAxOjcsIHRleHQgPSB0ZXh0KQ0KdGV4dF9kZg0KYGBgDQpUaWJibGUgYWRhbGFoIG1vZGVybiBjbGFzcyBkYXJpIGRhdGEgZnJhbWUgZGFsYW0gUiwgdGVyc2VkaWEgZGFsYW0gcGFja2FnZXMgZHBseXIgZGFuIHRpYmJsZS4gVGliYmxlcyBzYW5nYXQgYmFndXMgdW50dWsgZGlndW5ha2FuIGRlbmdhbiB0aWR5IHRvb2xzLg0KDQpQZXJoYXRpa2FuIGJhaHdhIGRhdGEgZnJhbWUgeWFuZyBiZXJpc2kgdGVrcyBpbmkgYmVsdW0ga29tcGF0aWJlbCBkZW5nYW4gYW5hbGlzaXMgdGVrcyB5YW5nIHJhcGkuIEthbWkgdGlkYWsgZGFwYXQgbWVueWFyaW5nIGthdGEgYXRhdSBtZW5naGl0dW5nIHlhbmcgcGFsaW5nIHNlcmluZyBtdW5jdWwsIGthcmVuYSBzZXRpYXAgYmFyaXMgdGVyZGlyaSBkYXJpIGJlYmVyYXBhIGthdGEgZ2FidW5nYW4uIEtpdGEgcGVybHUgbWVuZ29udmVyc2kgdGVybGViaWggZGFodWx1IHNlaGluZ2dhIG1lbWlsaWtpIHNhdHUtdG9rZW4tcGVyLWRva3VtZW4tcGVyLWJhcmlzLg0KDQpUb2tlbiBhZGFsYWggdW5pdCB0ZWtzIHlhbmcgYmVybWFrbmEsIHBhbGluZyBzZXJpbmcgYmVydXBhIGthdGEsIHlhbmcgYmlzYSBkaWd1bmFrYW4gdW50dWsgYW5hbGlzaXMgbGViaWggbGFuanV0LCBkYW4gdG9rZW5pc2FzaSBhZGFsYWggcHJvc2VzIHBlbWlzYWhhbiB0ZWtzIG1lbmphZGkgdG9rZW4uDQoNCkRhbGFtIGNvbnRvaCBwZXJ0YW1hIGluaSwga2l0YSBoYW55YSBtZW1pbGlraSBzYXR1IGRva3VtZW4gKEFsLUZhdGloYWgpLCB0ZXRhcGkga2l0YSBha2FuIG1lbmdla3NwbG9yYXNpIGNvbnRvaCBkZW5nYW4gYmFueWFrIGRva3VtZW4gKFN1cmF0KS4NCg0KRGFsYW0ga2VyYW5na2EgdGVrcyByYXBpIGtpdGEsIGtpdGEgcGVybHUgbWVtZWNhaCB0ZWtzIG1lbmphZGkgdG9rZW4gaW5kaXZpZHUgKHByb3NlcyB5YW5nIGRpc2VidXQgdG9rZW5pemF0aW9uKSBkYW4gbWVuZ3ViYWhueWEgbWVuamFkaSBzdHJ1a3R1ciBkYXRhIHlhbmcgcmFwaS4gKiBHdW5ha2FuIGZ1bmdzaSB1bm5lc3RfdG9rZW5zKCkgdGlkeXRleHQuDQoNCmBgYHtyfQ0KdGV4dF9kZiAlPiUNCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0KQ0KYGBgDQpTZXRlbGFoIG1lbmdndW5ha2FuIHVubmVzdF90b2tlbnMsIGFkYSBzYXR1IHRva2VuIChrYXRhKSBkaSBzZXRpYXAgYmFyaXMgZGFyaSBmcmFtZSBkYXRhIGJhcnU7IHRva2VuaXphdGlvbiBkZWZhdWx0IGRpIHVubmVzdF90b2tlbnMoKSBhZGFsYWggdW50dWsga2F0YSB0dW5nZ2FsLiBLb2xvbSBsYWluLCBzZXBlcnRpIG5vbW9yIGJhcmlzIGRhcmkgc2V0aWFwIGthdGEsIGRpcGVydGFoYW5rYW4uIFRhbmRhIGJhY2EgdGVsYWggZGloaWxhbmdrYW4uU2VjYXJhIGRlZmF1bHQsIHVubmVzdF90b2tlbnMoKSBtZW5nb252ZXJzaSB0b2tlbiBtZW5qYWRpIGh1cnVmIGtlY2lsLCB5YW5nIG1lbWJ1YXRueWEgbGViaWggbXVkYWggdW50dWsgZGliYW5kaW5na2FuIGF0YXUgZGlnYWJ1bmdrYW4gZGVuZ2FuIGt1bXB1bGFuIGRhdGEgbGFpbm55YS4gKEd1bmFrYW4gYXJndW1lbiB0b19sb3dlciA9IEZBTFNFIHVudHVrIG1lbWF0aWthbiBmaXR1ciBpbmkpLg0KU2VrYXJhbmcga2l0YSBkYXBhdCBtZW1hbmlwdWxhc2ksIG1lbXByb3NlcywgZGFuIG1lbXZpc3VhbGlzYXNpa2FuIHRla3MgbWVuZ2d1bmFrYW4gYWxhdCBzdGFuZGFyIHRpZHkgdG9vbHMsIHlhaXR1IGRwbHlyLCByYXBpciwgZGFuIGdncGxvdDINCg0KRm9rdXMgcGFkYSB2ZXJzaSBkYW4gVmFyaWFiZWwgUXVyYW4geWFuZyBEaXBpbGloDQpQYWtldCBxdXJhbiBtZW1pbGlraSA0IHZlcnNpIHF1cmFuLiBJbmkgbWVtYmVyaWthbiBheWF0LWF5YXQgcGVudWggQWwtUXVyJ2FuLCBkYWxhbSBiaW5na2FpIGRhdGEgeWFuZyBiZXJpc2kgc2F0dSBiYXJpcyBwZXIgYXlhdCwgZGlmb3JtYXQgYWdhciBueWFtYW4gdW50dWsgYW5hbGlzaXMgdGVrcy4gZGFyaSApIGRhbiBkaSAsIC4NCg0KcXVyYW5fYXIgKFF1cmFuIGRhbGFtIGJhaGFzYSBBcmFiIGRlbmdhbiB2b2thbCkNCnF1cmFuX2FyX21pbiAoUXVyYW4gZGFsYW0gYmFoYXNhIEFyYWIgdGFucGEgdm9rYWwpDQpxdXJhbl9lbl9zYWhpaCAoUXVyYW4gZGFsYW0gYmFoYXNhIEluZ2dyaXMsIHRlcmplbWFoYW4gU2hhaGloIEludGVybmFzaW9uYWwpDQpxdXJhbl9lbl95dXN1ZmFsaSAoUXVyYW4gZGFsYW0gYmFoYXNhIEluZ2dyaXMsIHRlcmplbWFoYW4gWXVzdWYgQWxpKQ0Ka2l0YSBha2FuIG1lbmdhbmFsaXNpcyB2YXJpYWJlbCB5YW5nIGRpcGlsaWggKGtvbG9tKSBkYXJpIHF1cmFuX2VuX3NhaGloDQoNCmBgYHtyfQ0KcXVyYW5FUyA8LSBxdXJhbl9lbl9zYWhpaCAlPiUgc2VsZWN0KHN1cmFoX2lkLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXlhaF9pZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyYWhfdGl0bGVfZW4sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJhaF90aXRsZV9lbl90cmFucywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVsYXRpb25fdHlwZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJhaCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF5YWgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheWFoX3RpdGxlKQ0KIyBxdXJhbkVTDQpgYGANCg0KDQpNZW5nZXJqYWthbiBpbmkgc2ViYWdhaSBrdW1wdWxhbiBkYXRhIHlhbmcgcmFwaSwga2l0YSBwZXJsdSBtZXJlc3RydWt0dXJpc2FzaW55YSBkYWxhbSBmb3JtYXQgc2F0dS10b2tlbi1wZXItYmFyaXMsIHlhbmcgc2VwZXJ0aSB5YW5nIGtpdGEgbGloYXQgc2ViZWx1bW55YSBkaWxha3VrYW4gZGVuZ2FuIGZ1bmdzaSB1bm5lc3RfdG9rZW5zKCkuDQoNCmBgYHtyfQ0KdGlkeUVTIDwtIHF1cmFuRVMgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkNCnRpZHlFUw0KYGBgDQoNCkZ1bmdzaSBpbmkgbWVtaXNhaGthbiBzZXRpYXAgYmFyaXMgdGVrcyBkYWxhbSBkYXRhIGZyYW1lIGFzbGkgbWVuamFkaSB0b2tlbi4gVG9rZW5pc2FzaSBkZWZhdWx0IGFkYWxhaCB1bnR1ayBrYXRhLWthdGEsIHRldGFwaSBvcHNpIGxhaW4gbWVuY2FrdXAga2FyYWt0ZXIsIG4tZ3JhbSwga2FsaW1hdCwgYmFyaXMsIHBhcmFncmFmLCBhdGF1IHBlbWlzYWhhbiBkaSBzZWtpdGFyIHBvbGEgcmVnZXguDQoNClNla2FyYW5nIGRhdGEgZGFsYW0gZm9ybWF0IHNhdHUga2F0YSBwZXIgYmFyaXMsIGtpdGEgZGFwYXQgbWVtYW5pcHVsYXNpbnlhIGRlbmdhbiB0aWR5IHRvb2xzIHNlcGVydGkgZHBseXIuIFNlcmluZ2thbGkgZGFsYW0gYW5hbGlzaXMgdGVrcywga2FtaSBtZW5naGFwdXMga2F0YS1rYXRhIGJlcmhlbnRpOyBzdG9wIHdvcmRzIGFkYWxhaCBrYXRhLWthdGEgeWFuZyB0aWRhayBiZXJndW5hIHVudHVrIGFuYWxpc2lzLCBiaWFzYW55YSBrYXRhLWthdGEgeWFuZyBzYW5nYXQgdW11bSBzZXBlcnRpIOKAnHRoZeKAnSwg4oCcb2bigJ0sIOKAnHRv4oCdLCBkYW4gc2ViYWdhaW55YSBkYWxhbSBiYWhhc2EgSW5nZ3Jpcy4gS2l0YSBkYXBhdCBtZW5naGFwdXMgc3RvcHdvcmRzIChkaXNpbXBhbiBkYWxhbSB0aWR5dGV4dCBkYXRhc2V0IHN0b3Bfd29yZHMpIGRlbmdhbiBhbnRpX2pvaW4oKS4NCg0KYGBge3J9DQpkYXRhKHN0b3Bfd29yZHMpDQoNCnRpZHlFUyA8LSB0aWR5RVMgJT4lDQogIGFudGlfam9pbihzdG9wX3dvcmRzKQ0KYGBgDQoNCkRhdGFzZXQgc3RvcF93b3JkcyBkYWxhbSBwYWNrYWdlIHRpZHl0ZXh0IGJlcmlzaSBzdG9wd29yZHMgZGFyaSB0aWdhIGxla3Npa29uLiBLaXRhIGRhcGF0IG1lbmdndW5ha2FuIHNlbXVhbnlhIGJlcnNhbWEtc2FtYSwgc2VwZXJ0aSB5YW5nIGtpdGEgbWlsaWtpIGRpIHNpbmksIGF0YXUgZmlsdGVyKCkgdW50dWsgaGFueWEgbWVuZ2d1bmFrYW4gc2F0dSBzZXQgc3RvcHdvcmQgamlrYSBpdHUgbGViaWggc2VzdWFpIHVudHVrIGFuYWxpc2lzIHRlcnRlbnR1Lg0KDQoNCiMgQ291bnQgZGFuIFBsb3QNCg0KS2l0YSBqdWdhIGRhcGF0IG1lbmdndW5ha2FuIGRwbHlyJ3MgY291bnQoKSB1bnR1ayBtZW5lbXVrYW4ga2F0YS1rYXRhIHlhbmcgcGFsaW5nIHVtdW0gZGkgc2VsdXJ1aCBRdXJhbiBzZWNhcmEga2VzZWx1cnVoYW4uDQoNCkthcmVuYSBrYW1pIHRlbGFoIG1lbmdndW5ha2FuIHRpZHl0b29scywganVtbGFoIGthdGEgZGlzaW1wYW4gZGFsYW0gZGF0YSBmcmFtZSB5YW5nIHJhcGkuIEhhbCBpbmkgbWVtdW5na2lua2FuIGtpdGEgdW50dWsgbWVueWFsdXJrYW5ueWEgbGFuZ3N1bmcga2UgcGFrZXQgZ2dwbG90MiwgbWlzYWxueWEgdW50dWsgbWVtYnVhdCB2aXN1YWxpc2FzaSBrYXRhLWthdGEgeWFuZyBwYWxpbmcgdW11bSBkYWxhbSBTYWhpaCBJbnRlcm5hdGlvbmFsIFRyYW5zbGF0aW9uIG9mIHRoZSBRdXJhbi4gS2FtaSBtZW1wbG90IGthdGEta2F0YSB5YW5nIG11bmN1bCBsZWJpaCBkYXJpIDE1MCBrYWxpLg0KYGBge3J9DQp0aWR5RVMgJT4lIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyfQ0KdGlkeUVTICU+JQ0KICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lDQogIGZpbHRlcihuID4gMTUwKSAlPiUNCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gd29yZCwgeSA9IG4pKSArDQogIGdlb21fY29sKCkgKw0KICB4bGFiKE5VTEwpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KCANCiAgICBhbmdsZSA9IDAsIA0KICAgIGNvbG9yPSJibHVlIiwgDQogICAgc2l6ZT0xMCkNCiAgKQ0KYGBgDQpMYWt1a2FuIEhhbCB5YW5nIHNhbWEgdW50dWsgUXVyYW4gaW4gRW5nbGlzaCBUZXJqZW1haGFuIFl1c3VmIEFsaQ0KDQpgYGB7cn0NCnF1cmFuRVkgPC0gcXVyYW5fZW5feXVzdWZhbGkgJT4lIHNlbGVjdChzdXJhaF9pZCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF5YWhfaWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cmFoX3RpdGxlX2VuLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyYWhfdGl0bGVfZW5fdHJhbnMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZlbGF0aW9uX3R5cGUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyYWgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheWFoLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXlhaF90aXRsZSkNCiMgcXVyYW5FUw0KYGBgDQoNCmBgYHtyfQ0KdGlkeUVZIDwtIHF1cmFuRVkgJT4lDQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkNCnRpZHlFWQ0KYGBgDQoNCmBgYHtyfQ0KbXlfc3RvcHdvcmRzIDwtIHRpYmJsZSh3b3JkID0gYygneWUnLCAndmVyaWx5JywgJ3dpbGwnLCAnc2FpZCcsICdzYXknLCAndXMnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3RoeScsICd0aGVlJywgJ3Rob3UnLCAnaGF0aCcsICdkb3RoJykpDQp0aWR5RVkgPC0gdGlkeUVZICU+JQ0KICBhbnRpX2pvaW4obXlfc3RvcHdvcmRzKQ0KYGBgDQpgYGB7cn0NCnRpZHlFWSAlPiUNCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpICU+JQ0KICBmaWx0ZXIobiA+IDE1MCkgJT4lDQogIG11dGF0ZSh3b3JkID0gcmVvcmRlcih3b3JkLCBuKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHdvcmQsIHkgPSBuKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgeGxhYihOVUxMKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dCggDQogICAgYW5nbGUgPSAwLCANCiAgICBjb2xvcj0iYmx1ZSIsIA0KICAgIHNpemU9MTApDQogICkNCmBgYA0KDQojIFNlbnRpbWVuIERhdGFzZXQNCg0KYGBge3J9DQpnZXRfc2VudGltZW50cygiYmluZyIpDQpgYGANCiMgS2F0YSBQb3NpdGlmIGRhbiBOZWdhdGlmIHlhbmcgcGFsaW5nIFVtdW0NCg0KYGBge3J9DQpiaW5nX3dvcmRfY291bnRzIDwtIHRpZHlFUyAlPiUNCiAgaW5uZXJfam9pbihnZXRfc2VudGltZW50cygiYmluZyIpKSAlPiUNCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSkgJT4lDQogIHVuZ3JvdXAoKQ0KDQpiaW5nX3dvcmRfY291bnRzDQpgYGANCmBgYHtyfQ0KYmluZ193b3JkX2NvdW50cyAlPiUNCiAgZ3JvdXBfYnkoc2VudGltZW50KSAlPiUNCiAgdG9wX24oMjApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh3b3JkID0gcmVvcmRlcih3b3JkLCBuKSkgJT4lDQogIGdncGxvdChhZXMod29yZCwgbiwgZmlsbCA9IHNlbnRpbWVudCkpICsNCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBmYWNldF93cmFwKH5zZW50aW1lbnQsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIGxhYnMoeSA9ICJDb250cmlidXRpb24gdG8gc2VudGltZW50IiwNCiAgICAgICB4ID0gTlVMTCkgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoIA0KICAgIGFuZ2xlID0gMCwgDQogICAgY29sb3I9ImJsdWUiLCANCiAgICBzaXplPTEwKSkNCmBgYA0KYGBge3J9DQpiaW5nX3dvcmRfY291bnRzRVkgPC0gdGlkeUVZICU+JQ0KICBpbm5lcl9qb2luKGdldF9zZW50aW1lbnRzKCJiaW5nIikpICU+JQ0KICBjb3VudCh3b3JkLCBzZW50aW1lbnQsIHNvcnQgPSBUUlVFKSAlPiUNCiAgdW5ncm91cCgpDQoNCmJpbmdfd29yZF9jb3VudHNFWQ0KYGBgDQpgYGB7cn0NCmJpbmdfd29yZF9jb3VudHNFWSAlPiUNCiAgZ3JvdXBfYnkoc2VudGltZW50KSAlPiUNCiAgdG9wX24oMjApICU+JQ0KICB1bmdyb3VwKCkgJT4lDQogIG11dGF0ZSh3b3JkID0gcmVvcmRlcih3b3JkLCBuKSkgJT4lDQogIGdncGxvdChhZXMod29yZCwgbiwgZmlsbCA9IHNlbnRpbWVudCkpICsNCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBmYWNldF93cmFwKH5zZW50aW1lbnQsIHNjYWxlcyA9ICJmcmVlX3kiKSArDQogIGxhYnMoeSA9ICJDb250cmlidXRpb24gdG8gc2VudGltZW50IiwNCiAgICAgICB4ID0gTlVMTCkgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoIA0KICAgIGFuZ2xlID0gMCwgDQogICAgY29sb3I9ImJsdWUiLCANCiAgICBzaXplPTEwKSkNCmBgYA0KIyBNZW1wZXJiZXNhciBrZWRhbGFtIFN1cmFoDQoNCmBgYHtyfQ0KYmluZ25lZ2F0aXZlIDwtIGdldF9zZW50aW1lbnRzKCJiaW5nIikgJT4lIA0KICBmaWx0ZXIoc2VudGltZW50ID09ICJuZWdhdGl2ZSIpDQoNCndvcmRjb3VudHMgPC0gdGlkeUVTICU+JQ0KICBncm91cF9ieShzdXJhaF90aXRsZV9lbikgJT4lDQogIHN1bW1hcml6ZSh3b3JkcyA9IG4oKSkNCg0KdGlkeUVTICU+JQ0KICBzZW1pX2pvaW4oYmluZ25lZ2F0aXZlKSAlPiUNCiAgZ3JvdXBfYnkoc3VyYWhfdGl0bGVfZW4pICU+JQ0KICBzdW1tYXJpemUobmVnYXRpdmV3b3JkcyA9IG4oKSkgJT4lDQogIGxlZnRfam9pbih3b3JkY291bnRzLCBieSA9IGMoInN1cmFoX3RpdGxlX2VuIikpICU+JQ0KICBtdXRhdGUocmF0aW8gPSBuZWdhdGl2ZXdvcmRzL3dvcmRzKSAlPiUNCiAgdG9wX24oMjApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzdXJhaF90aXRsZV9lbiwgeSA9IHJhdGlvKSkgKw0KICBnZW9tX2NvbCgpICsNCiAgeGxhYihOVUxMKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dCggDQogICAgYW5nbGUgPSAwLCANCiAgICBjb2xvcj0iYmx1ZSIsIA0KICAgIHNpemU9MTApKQ0KYGBgDQpgYGB7cn0NCmJpbmduZWdhdGl2ZSA8LSBnZXRfc2VudGltZW50cygiYmluZyIpICU+JSANCiAgZmlsdGVyKHNlbnRpbWVudCA9PSAibmVnYXRpdmUiKQ0KDQp3b3JkY291bnRzIDwtIHRpZHlFWSAlPiUNCiAgZ3JvdXBfYnkoc3VyYWhfdGl0bGVfZW4pICU+JQ0KICBzdW1tYXJpemUod29yZHMgPSBuKCkpDQoNCnRpZHlFWSAlPiUNCiAgc2VtaV9qb2luKGJpbmduZWdhdGl2ZSkgJT4lDQogIGdyb3VwX2J5KHN1cmFoX3RpdGxlX2VuKSAlPiUNCiAgc3VtbWFyaXplKG5lZ2F0aXZld29yZHMgPSBuKCkpICU+JQ0KICBsZWZ0X2pvaW4od29yZGNvdW50cywgYnkgPSBjKCJzdXJhaF90aXRsZV9lbiIpKSAlPiUNCiAgbXV0YXRlKHJhdGlvID0gbmVnYXRpdmV3b3Jkcy93b3JkcykgJT4lDQogIHRvcF9uKDIwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3VyYWhfdGl0bGVfZW4sIHkgPSByYXRpbykpICsNCiAgZ2VvbV9jb2woKSArDQogIHhsYWIoTlVMTCkgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoIA0KICAgIGFuZ2xlID0gMCwgDQogICAgY29sb3I9ImJsdWUiLCANCiAgICBzaXplPTEwKSkNCmBgYA0KDQojIFdvcmRjbG91ZHMNCg0KYGBge3J9DQpsaWJyYXJ5KHdvcmRjbG91ZCkNCnRpZHlFUyAlPiUNCiAgY291bnQod29yZCkgJT4lDQogIHdpdGgod29yZGNsb3VkKHdvcmQsIG4sIG1heC53b3JkcyA9IDEwMCkpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KHdvcmRjbG91ZCkNCnRpZHlFWSAlPiUNCiAgY291bnQod29yZCkgJT4lDQogIHdpdGgod29yZGNsb3VkKHdvcmQsIG4sIG1heC53b3JkcyA9IDEwMCkpDQpgYGANCmBgYHtyfQ0KbGlicmFyeShyZXNoYXBlMikNCnRpZHlFUyAlPiUNCiAgaW5uZXJfam9pbihnZXRfc2VudGltZW50cygiYmluZyIpKSAlPiUNCiAgY291bnQod29yZCwgc2VudGltZW50LCBzb3J0ID0gVFJVRSkgJT4lDQogIGFjYXN0KHdvcmQgfiBzZW50aW1lbnQsIHZhbHVlLnZhciA9ICJuIiwgZmlsbCA9IDApICU+JQ0KICBjb21wYXJpc29uLmNsb3VkKGNvbG9ycyA9IGMoIiNlYjUyYTYiLCAiIzU0ZjBiMSIpLA0KICAgICAgICAgICAgICAgICAgIG1heC53b3JkcyA9IDUwKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkocmVzaGFwZTIpDQp0aWR5RVkgJT4lDQogIGlubmVyX2pvaW4oZ2V0X3NlbnRpbWVudHMoImJpbmciKSkgJT4lDQogIGNvdW50KHdvcmQsIHNlbnRpbWVudCwgc29ydCA9IFRSVUUpICU+JQ0KICBhY2FzdCh3b3JkIH4gc2VudGltZW50LCB2YWx1ZS52YXIgPSAibiIsIGZpbGwgPSAwKSAlPiUNCiAgY29tcGFyaXNvbi5jbG91ZChjb2xvcnMgPSBjKCIjZWI1MmE2IiwgIiM1NGYwYjEiKSwNCiAgICAgICAgICAgICAgICAgICBtYXgud29yZHMgPSA1MCkNCmBgYA0KDQojIEtlc2ltcHVsYW4NCg0KQW5hbGlzaXMgc2VudGltZW4gbWVueWVkaWFrYW4gY2FyYSB1bnR1ayBtZW1haGFtaSBzaWthcCBkYW4gcGVuZGFwYXQgeWFuZyBkaXVuZ2thcGthbiBkYWxhbSB0ZWtzLiBkZW5nYW4gbWVuZ2Vrc3Bsb3Jhc2kgYmFnYWltYW5hIG1lbmVyYXBrYW4gYW5hbGlzaXMgc2VudGltZW4gdW50dWsgZHVhIHZlcnNpIFF1cmFuIGJhaGFzYSBJbmdncmlzIG1lbmdndW5ha2FuIHByaW5zaXAtcHJpbnNpcCB0aWR5ZGF0YS4gU2ViYWdpYW4gYmVzYXIgaGFzaWxueWEgaGFtcGlyIG1pcmlwLg0KDQoNCkRhZnRhciBQdXN0YWthDQoNCjxhIGhyZWY9Imh0dHBzOi8vcnB1YnMuY29tL2F6bWFuSC82ODYwMjkiPmh0dHBzOi8vcnB1YnMuY29tL2F6bWFuSC82ODYwMjk8L2E+DQo=