1. Membangun Regresi Linier Berganda
Regresi Linear Berganda adalah model regresi linear dengan melibatkan lebih dari satu variable bebas atau predictor. Dalam bahasa inggris, istilah ini disebut dengan multiple linear regression.
1.1 Meng-import Data dan menampilkannya
library(readxl)
datasembuhjanuari <- read_excel(path = "~/linear algebra/DataSembuhJanuari2021.xlsx")
datasembuhjanuari
1.2.Mencari Summary dari Data
summary(datasembuhjanuari)
1.3.Membuat Matriks Data
pairs(datasembuhjanuari)
pairs(datasembuhjanuari, lower.panel = NULL)
1.4.Visualisasi Data Menggunakan Fungsi Plot
plot(datasembuhjanuari$Sembuh ~ datasembuhjanuari$retail_and_recreation_percent_change_from_baseline, data = datasembuhjanuari)
1.5. Memvisualisasikan Data dengan Sembuh sebagai variabel Y dan Google Mobility Index sebagai variabel X
plot(datasembuhjanuari$Sembuh ~ datasembuhjanuari$
retail_and_recreation_percent_change_from_baseline+datasembuhjanuari$
grocery_and_pharmacy_percent_change_from_baseline+datasembuhjanuari$
parks_percent_change_from_baseline+datasembuhjanuari$
transit_stations_percent_change_from_baseline+datasembuhjanuari$
workplaces_percent_change_from_baseline+datasembuhjanuari$
residential_percent_change_from_baseline, data = datasembuhjanuari)
1.6. Membuat Korelasi Antar Variable
Korelasi merupakan keterhubungan antar variabel. Untuk mengukur seberapa jauh hubungan antara satu variabel dengan variabel yang lain kita dapat menggunakan fungsi cor().
- Korelasi Variable Y dengan X1
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
retail_and_recreation_percent_change_from_baseline)
- Korelasi Variable Y dengan X2
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
grocery_and_pharmacy_percent_change_from_baseline)
- Korelasi Variable Y dengan X3
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
parks_percent_change_from_baseline)
- Korelasi Variable Y dengan X4
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
transit_stations_percent_change_from_baseline)
- Korelasi Variable Y dengan X5
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
workplaces_percent_change_from_baseline)
- Korelasi Variable Y dengan X6
cor(datasembuhjanuari$Sembuh,datasembuhjanuari$
residential_percent_change_from_baseline)
Dari hasil seluruh output di atas dapat disimpulkan bahwa untuk tingkat keterhubungan antara variabel y dengan x1, x2, x3, x4, x5, x6 tidak memiliki hubungan sama sekali karena nilai yang dihasilkan berjumlah kurang dari 0.
1.7. Melakukan Permodelan
Berikut adalah cara melakukan permodelan Regresi Linier Berganda.
model <- lm(datasembuhjanuari$Sembuh ~ datasembuhjanuari$Tanggal, data = datasembuhjanuari)
Selanjutnya dengan model yang telah dibuat di atas, kita akan menggunakan fungsi summary() untuk menjelaskan atau mereview hasil dari model tersebut. Dan dengan ringkasan summary(model) kita dapat melihat informasi terperinci tentang kinerja dan koefisian model.
summary(model)
1.8. Menjelaskan Rincian Model Dengan Fungsi summary()
Di atas merupakan rincian dari model yang telah dibuat.
setelah menjalankan fungsi summary() maka akan didapat 5 nilai residual. Residual adalah perbedaan antara nilai nyata dan nilai prediksi. Yang mana semakin kecil nilai residual maka semakin baik atau benar model yang kita buat. Berikut nilai-nilai residual yang dihasilkan:
- Nilai Minimum = -2809.2
- Nilai Maximum = 3423.0
- Nilai Median = -25.5
- Nilai Quartil 1 = -1332.5
- Nilai Quartil 3 = 1192.7
Dari nilai-nilai tersebut dapat kita lihat bahwa dalam konteks ini berupa nilai minimum, maximum, median, quartil 1 dan quartil 3. Dapat kita simpulkan bahwa model yang telah kita buat belum bisa dikatakan baik atau benar karena nilai-nilai yang dihasilkan tidak mendekati nol.
Di bawah nilai residual terdapat koefisien, yang mana dalam koefisien tersebut terdapat nilai intersep, dan tanggal. Selain itu juga terdapat nilai-p dari koefisien
Selanjutnya terdapat dua R2 yaitu:
Multiple R-squared: 0.994. hal ini menunjukkan bahwa 0.00994% variasi variabel respon, y, dapat dijelaskan oleh variabel prediktor x. Multiple R-squared tidak dapat berkurang saat kita menambahkan lebih banyak variabel independen ke model yang kita buat.
Adjusted R-squared: 0.9938 Adjusted R-squared lebih baik ada penambahan variabel. Jadi jika kita menambahkan lebih dari satu variabel ke model, itu hanya meningkat jika itu mengurangi kesalahan prediksi secara keseluruhan.
1.9. Menggunakan Fungsi anova()
ANOVA (analysis of variance) adalah pengujian yang dilakukan dengan membandingkan varians. Dengan membandingkan varians tersebut, dapat diketahui ada tidaknya perbedaan rata-rata dari tiga atau lebih kelompok. Asumsi normalitas pada ANOVA adalah pada residual yaitu selisih antara Y Prediksi dengan Y Aktual. Tepatnya residual dapat dihitung sebagai berikut: Y Aktual – Y Prediksi. Dimana Y Aktual adalah Y sesungguhnya atau kenyataan. Sedangkan Y prediksi adalah Y hasil persamaan ANOVA.
anova(model)
1.10. Membuat plot() dari Data Real dan Data Prediksi
plot(datasembuhjanuari$Sembuh ~ datasembuhjanuari$
Tanggal,
data = datasembuhjanuari, col = "red", pch = 20, cex = 1.5,
main = "Data Covid SEMBUH di DKI Jakarta dan Google Mobility Index")
abline(model)
Dari Plot di atas perlu kita ketahui bahwa titik-titik Merah yang ada pada grafik tersebut adalah data real dan garis hitam di dalam kotak adalah data prediksi.
plot(cooks.distance(model), pch = 16, col = "red")
plot(model)
1.11. Penggunaan AIC dan BIC
AIC dan BIC banyak digunakan dalam kriteria pemilihan model. AIC berarti Kriteria Informasi Akaike dan BIC berarti Kriteria Informasi Bayesian. Meskipun kedua istilah ini membahas pemilihan model, keduanya tidak sama. Seseorang dapat menemukan perbedaan antara dua pendekatan pemilihan model.
AIC(model)
BIC(model)
1.11 Memunculkan Nilai Predicted dan Memvisualisasikannya
head(predict(model), n = 15)
plot(head(predict(model), n = 20))
1.12. Memunculkan Nilai Residuals
head(resid(model), n = 11)
coef(model)
1.13. Membuat Tabel Untuk Menambah Data Residuals dan Data Predicted
Tabel di bawah merupakan semua proses yang telah dilakukan, sehingga terbuat tabel yang ada nilai residuals dan nilai protected.
datasembuhjanuari$residuals <- model$residuals
datasembuhjanuari$predicted <- model$fitted.values
datasembuhjanuari
1.14. Visualisasi Data Menggunakan scatter.smooth, boxplot dan plot
scatter.smooth(x=datasembuhjanuari$Tanggal, y=datasembuhjanuari$Sembuh,
main="Tanggal ~ SEMBUH")
boxplot(datasembuhjanuari$Sembuh, main="SEMBUH",
boxplot.stats(datasembuhjanuari$Sembuh)$out)
plot(density(datasembuhjanuari$Sembuh), main="Google Mobility Index : SEMBUH",
ylab="Frequency")
coefs <- coef(model)
plot(Sembuh ~ Tanggal, data = datasembuhjanuari)
abline(coefs)
text(x = 12, y = 10, paste('expression = ', round(coefs[1], 2), '+',
round(coefs[2], 2), '*SEMBUH'))
1.15. Melakukan Uji Korelasi Antar Variabel
Adanya korelasi antar variabel dapat dilakukan melalui visualisasi menggunakan scatterplot dan perhitungan matematis menggunakan metode Pearson untuk metode parametrik dan metode rangking Spearman dan Kendall untuk metode non-parametrik. Pada R uji korelasi dapat dilakukan dengan menggunakan fungsi cor.test(). Format fungsi tersebut adalah sebagai berikut:
a. Uji Korelasi Varible Y dengan X1
cor.test(datasembuhjanuari$
retail_and_recreation_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
b. Uji Korelasi Varible Y dengan X2
cor.test(datasembuhjanuari$grocery_and_pharmacy_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
c. Uji Korelasi Varible Y dengan X3
cor.test(datasembuhjanuari$
parks_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
d. Uji Korelasi Varible Y dengan X4
cor.test(datasembuhjanuari$
transit_stations_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
e. Uji Korelasi Varible Y dengan X5
cor.test(datasembuhjanuari$
workplaces_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
d. Uji Korelasi Varible Y dengan X6
cor.test(datasembuhjanuari$
residential_percent_change_from_baseline,
datasembuhjanuari$Sembuh)
Berdasarkan seluruh output yang dihasilkan, metode Pearson menghasilkan output berupa nilai t uji, derajat kebebasan, nilai p-value, rentang estimasi nilai korelasi berdasarkan tingkat kepercayaan, dan estimasi nilai korelasi.
LS0tDQp0aXRsZTogIihKYW51YXJpIDIwMjEgLSBTRU1CVUggQ09WSUQtMTkgRElTRUFTRSlBbmFsaXNpcyBSZWdyZXNpIExpbmVhciBCZXJnYW5kYSBUZXJoYWRhcCBEYXRhIENvdmlkIGRpIERLSSBKYWthcnRhIFBhZGEgQnVsYW4gSmFudWFyaSAyMDIxIg0KYXV0aG9yOiAiUmlmcWksIFByb2YuIERyLiBTdWhhcnRvbm8sIE0uS29tIg0KZGF0ZTogIjI4LzAzLzIwMjIiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAyDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogJzInDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keXsgLyogTm9ybWFsICAqLw0KICAgICAgZm9udC1zaXplOiAxNHB4Ow0KICB9DQp0ZCB7ICAvKiBUYWJsZSAgKi8NCiAgZm9udC1zaXplOiAxMnB4Ow0KfQ0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDM4cHg7DQogIGNvbG9yOiBsaWdodHllbGxvdzsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQpoMSB7IC8qIEhlYWRlciAxICovDQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtQaW5rOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAqLw0KICBmb250LXNpemU6IDIwcHg7DQogIGNvbG9yOiBEYXJrUGluazsNCn0NCmgzIHsgLyogSGVhZGVyIDMgKi8NCiAgZm9udC1zaXplOiAxNnB4Ow0KIyAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmxhY2s7DQp9DQpoNCB7IC8qIEhlYWRlciA0ICovDQogIGZvbnQtc2l6ZTogMTRweDsNCiAgY29sb3I6IERhcmtCbGFjazsNCn0NCmNvZGUucnsgLyogQ29kZSBibG9jayAqLw0KICAgIGZvbnQtc2l6ZTogMTJweDsNCn0NCnByZSB7IC8qIENvZGUgYmxvY2sgLSBkZXRlcm1pbmVzIGNvZGUgc3BhY2luZyBiZXR3ZWVuIGxpbmVzICovDQogICAgZm9udC1zaXplOiAxMnB4Ow0KfQ0KPC9zdHlsZT4NCg0KRG9zZW4gUGVuZ2FtcHUgOiBQcm9mLiBEci4gU3VoYXJ0b25vLCBNLktvbQ0KDQpMZW1iYWdhIDogVW5pdmVyc2l0YXMgSXNsYW0gTmVnZXJpIE1hdWxhbmEgTWFsaWsgSWJyYWhpbSBNYWxhbmcNCg0KSnVydXNhbiA6IFRla25payBJbmZvcm1hdGlrYQ0KDQpGYWt1bHRhcyA6IFNhaW5zIGRhbiBUZWtub2xvZ2kNCg0KIyAxLiBNZW1iYW5ndW4gUmVncmVzaSBMaW5pZXIgQmVyZ2FuZGENCg0KUmVncmVzaSBMaW5lYXIgQmVyZ2FuZGEgYWRhbGFoIG1vZGVsIHJlZ3Jlc2kgbGluZWFyIGRlbmdhbiBtZWxpYmF0a2FuIGxlYmloIGRhcmkgc2F0dSB2YXJpYWJsZSBiZWJhcyBhdGF1IHByZWRpY3Rvci4gRGFsYW0gYmFoYXNhIGluZ2dyaXMsIGlzdGlsYWggaW5pIGRpc2VidXQgZGVuZ2FuIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uLg0KDQojIyAxLjEgTWVuZy1pbXBvcnQgRGF0YSBkYW4gbWVuYW1waWxrYW5ueWENCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQpgYGANCg0KYGBge3J9DQpkYXRhc2VtYnVoamFudWFyaSA8LSByZWFkX2V4Y2VsKHBhdGggPSAifi9saW5lYXIgYWxnZWJyYS9EYXRhU2VtYnVoSmFudWFyaTIwMjEueGxzeCIpDQpkYXRhc2VtYnVoamFudWFyaQ0KYGBgDQoNCiMjIDEuMi5NZW5jYXJpIFN1bW1hcnkgZGFyaSBEYXRhDQoNCmBgYHtyfQ0Kc3VtbWFyeShkYXRhc2VtYnVoamFudWFyaSkNCmBgYA0KDQojIyAxLjMuTWVtYnVhdCBNYXRyaWtzIERhdGENCg0KYGBge3J9DQpwYWlycyhkYXRhc2VtYnVoamFudWFyaSkNCmBgYA0KDQpgYGB7cn0NCnBhaXJzKGRhdGFzZW1idWhqYW51YXJpLCBsb3dlci5wYW5lbCA9IE5VTEwpDQpgYGANCg0KIyMgMS40LlZpc3VhbGlzYXNpIERhdGEgTWVuZ2d1bmFrYW4gRnVuZ3NpIFBsb3QNCg0KYGBge3J9DQpwbG90KGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCB+IGRhdGFzZW1idWhqYW51YXJpJHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBkYXRhID0gZGF0YXNlbWJ1aGphbnVhcmkpDQpgYGANCg0KIyMgMS41LiBNZW12aXN1YWxpc2FzaWthbiBEYXRhIGRlbmdhbiBTZW1idWggc2ViYWdhaSB2YXJpYWJlbCBZIGRhbiBHb29nbGUgTW9iaWxpdHkgSW5kZXggc2ViYWdhaSB2YXJpYWJlbCBYDQpgYGB7cn0NCnBsb3QoZGF0YXNlbWJ1aGphbnVhcmkkU2VtYnVoIH4gZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICAgICAgICAgIHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lK2RhdGFzZW1idWhqYW51YXJpJA0KICAgICAgZ3JvY2VyeV9hbmRfcGhhcm1hY3lfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZStkYXRhc2VtYnVoamFudWFyaSQNCiAgICAgIHBhcmtzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUrZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICB0cmFuc2l0X3N0YXRpb25zX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUrZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICB3b3JrcGxhY2VzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUrZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICByZXNpZGVudGlhbF9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBkYXRhID0gZGF0YXNlbWJ1aGphbnVhcmkpDQpgYGANCiMjIDEuNi4gTWVtYnVhdCBLb3JlbGFzaSBBbnRhciBWYXJpYWJsZQ0KS29yZWxhc2kgbWVydXBha2FuIGtldGVyaHVidW5nYW4gYW50YXIgdmFyaWFiZWwuIFVudHVrIG1lbmd1a3VyIHNlYmVyYXBhIGphdWggaHVidW5nYW4gYW50YXJhIHNhdHUgdmFyaWFiZWwgZGVuZ2FuIHZhcmlhYmVsIHlhbmcgbGFpbiBraXRhIGRhcGF0IG1lbmdndW5ha2FuIGZ1bmdzaSBjb3IoKS4NCg0KICBhLiBLb3JlbGFzaSBWYXJpYWJsZSBZIGRlbmdhbiBYMQ0KICANCmBgYHtyfQ0KY29yKGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCxkYXRhc2VtYnVoamFudWFyaSQNCiAgICAgIHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lKQ0KYGBgDQogIA0KICBiLiBLb3JlbGFzaSBWYXJpYWJsZSBZIGRlbmdhbiBYMg0KYGBge3J9DQpjb3IoZGF0YXNlbWJ1aGphbnVhcmkkU2VtYnVoLGRhdGFzZW1idWhqYW51YXJpJA0KICAgICAgZ3JvY2VyeV9hbmRfcGhhcm1hY3lfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSkNCmBgYA0KICANCiAgYy4gS29yZWxhc2kgVmFyaWFibGUgWSBkZW5nYW4gWDMNCmBgYHtyfQ0KY29yKGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCxkYXRhc2VtYnVoamFudWFyaSQNCiAgICAgIHBhcmtzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUpDQpgYGANCiAgDQogIGQuIEtvcmVsYXNpIFZhcmlhYmxlIFkgZGVuZ2FuIFg0DQpgYGB7cn0NCmNvcihkYXRhc2VtYnVoamFudWFyaSRTZW1idWgsZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICB0cmFuc2l0X3N0YXRpb25zX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUpDQpgYGANCiAgDQogIGUuIEtvcmVsYXNpIFZhcmlhYmxlIFkgZGVuZ2FuIFg1DQpgYGB7cn0NCmNvcihkYXRhc2VtYnVoamFudWFyaSRTZW1idWgsZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICB3b3JrcGxhY2VzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUpDQpgYGANCiAgDQogIGYuIEtvcmVsYXNpIFZhcmlhYmxlIFkgZGVuZ2FuIFg2DQpgYGB7cn0NCmNvcihkYXRhc2VtYnVoamFudWFyaSRTZW1idWgsZGF0YXNlbWJ1aGphbnVhcmkkDQogICAgICByZXNpZGVudGlhbF9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lKQ0KYGBgDQpEYXJpIGhhc2lsIHNlbHVydWggb3V0cHV0IGRpIGF0YXMgZGFwYXQgZGlzaW1wdWxrYW4gYmFod2EgdW50dWsgdGluZ2thdCBrZXRlcmh1YnVuZ2FuIGFudGFyYSB2YXJpYWJlbCB5IGRlbmdhbiB4MSwgeDIsIHgzLCB4NCwgeDUsIHg2IHRpZGFrIG1lbWlsaWtpIGh1YnVuZ2FuIHNhbWEgc2VrYWxpIGthcmVuYSBuaWxhaSB5YW5nIGRpaGFzaWxrYW4gYmVyanVtbGFoIGt1cmFuZyBkYXJpIDAuDQoNCg0KIyMgMS43LiBNZWxha3VrYW4gUGVybW9kZWxhbg0KQmVyaWt1dCBhZGFsYWggY2FyYSBtZWxha3VrYW4gcGVybW9kZWxhbiBSZWdyZXNpIExpbmllciBCZXJnYW5kYS4NCg0KYGBge3J9DQptb2RlbCA8LSBsbShkYXRhc2VtYnVoamFudWFyaSRTZW1idWggfiBkYXRhc2VtYnVoamFudWFyaSRUYW5nZ2FsLCBkYXRhID0gZGF0YXNlbWJ1aGphbnVhcmkpDQpgYGANCg0KICBTZWxhbmp1dG55YSBkZW5nYW4gbW9kZWwgeWFuZyB0ZWxhaCBkaWJ1YXQgZGkgYXRhcywga2l0YSBha2FuIG1lbmdndW5ha2FuIGZ1bmdzaSBzdW1tYXJ5KCkgdW50dWsgbWVuamVsYXNrYW4gYXRhdSBtZXJldmlldyBoYXNpbCBkYXJpIG1vZGVsIHRlcnNlYnV0LiBEYW4gZGVuZ2FuIHJpbmdrYXNhbiBzdW1tYXJ5KG1vZGVsKSBraXRhIGRhcGF0IG1lbGloYXQgaW5mb3JtYXNpIHRlcnBlcmluY2kgdGVudGFuZyBraW5lcmphIGRhbiBrb2VmaXNpYW4gbW9kZWwuDQogIA0KYGBge3J9DQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQoNCiMjIDEuOC4gTWVuamVsYXNrYW4gUmluY2lhbiBNb2RlbCBEZW5nYW4gRnVuZ3NpIHN1bW1hcnkoKQ0KDQpEaSBhdGFzIG1lcnVwYWthbiByaW5jaWFuIGRhcmkgbW9kZWwgeWFuZyB0ZWxhaCBkaWJ1YXQuDQoNCnNldGVsYWggbWVuamFsYW5rYW4gZnVuZ3NpIHN1bW1hcnkoKSBtYWthIGFrYW4gZGlkYXBhdCA1IG5pbGFpIHJlc2lkdWFsLiBSZXNpZHVhbCBhZGFsYWggcGVyYmVkYWFuIGFudGFyYSBuaWxhaSBueWF0YSBkYW4gbmlsYWkgcHJlZGlrc2kuIFlhbmcgbWFuYSBzZW1ha2luIGtlY2lsIG5pbGFpIHJlc2lkdWFsIG1ha2Egc2VtYWtpbiBiYWlrIGF0YXUgYmVuYXIgbW9kZWwgeWFuZyBraXRhIGJ1YXQuIEJlcmlrdXQgbmlsYWktbmlsYWkgcmVzaWR1YWwgeWFuZyBkaWhhc2lsa2FuOg0KDQogICAtIE5pbGFpIE1pbmltdW0gPSAtMjgwOS4yDQogICAtIE5pbGFpIE1heGltdW0gPSAzNDIzLjAgDQogICAtIE5pbGFpIE1lZGlhbiA9IC0yNS41DQogICAtIE5pbGFpIFF1YXJ0aWwgMSA9IC0xMzMyLjUNCiAgIC0gTmlsYWkgUXVhcnRpbCAzID0gMTE5Mi43DQoNCkRhcmkgbmlsYWktbmlsYWkgdGVyc2VidXQgZGFwYXQga2l0YSBsaWhhdCBiYWh3YSBkYWxhbSBrb250ZWtzIGluaSBiZXJ1cGEgbmlsYWkgbWluaW11bSwgbWF4aW11bSwgbWVkaWFuLCBxdWFydGlsIDEgZGFuIHF1YXJ0aWwgMy4gRGFwYXQga2l0YSBzaW1wdWxrYW4gYmFod2EgbW9kZWwgeWFuZyB0ZWxhaCBraXRhIGJ1YXQgYmVsdW0gYmlzYSBkaWthdGFrYW4gYmFpayBhdGF1IGJlbmFyIGthcmVuYSBuaWxhaS1uaWxhaSB5YW5nIGRpaGFzaWxrYW4gdGlkYWsgbWVuZGVrYXRpIG5vbC4NCg0KRGkgYmF3YWggbmlsYWkgcmVzaWR1YWwgdGVyZGFwYXQga29lZmlzaWVuLCB5YW5nIG1hbmEgZGFsYW0ga29lZmlzaWVuIHRlcnNlYnV0IHRlcmRhcGF0IG5pbGFpIGludGVyc2VwLCBkYW4gdGFuZ2dhbC4gU2VsYWluIGl0dSBqdWdhIHRlcmRhcGF0IG5pbGFpLXAgZGFyaSBrb2VmaXNpZW4NCg0KU2VsYW5qdXRueWEgdGVyZGFwYXQgZHVhIFIyIHlhaXR1Og0KDQogIC0gTXVsdGlwbGUgUi1zcXVhcmVkOiAgMC45OTQuIGhhbCBpbmkgbWVudW5qdWtrYW4gYmFod2EgMC4wMDk5NCUgdmFyaWFzaSB2YXJpYWJlbCByZXNwb24sIHksIGRhcGF0IGRpamVsYXNrYW4gb2xlaCB2YXJpYWJlbCBwcmVkaWt0b3IgeC4gTXVsdGlwbGUgUi1zcXVhcmVkIHRpZGFrIGRhcGF0IGJlcmt1cmFuZyBzYWF0IGtpdGEgbWVuYW1iYWhrYW4gbGViaWggYmFueWFrIHZhcmlhYmVsIGluZGVwZW5kZW4ga2UgbW9kZWwgeWFuZyBraXRhIGJ1YXQuDQoNCiAgLSBBZGp1c3RlZCBSLXNxdWFyZWQ6ICAwLjk5MzgNCkFkanVzdGVkIFItc3F1YXJlZCBsZWJpaCBiYWlrIGFkYSBwZW5hbWJhaGFuIHZhcmlhYmVsLiBKYWRpIGppa2Ega2l0YSBtZW5hbWJhaGthbiBsZWJpaCBkYXJpIHNhdHUgdmFyaWFiZWwga2UgbW9kZWwsIGl0dSBoYW55YSBtZW5pbmdrYXQgamlrYSBpdHUgbWVuZ3VyYW5naSBrZXNhbGFoYW4gcHJlZGlrc2kgc2VjYXJhIGtlc2VsdXJ1aGFuLg0KDQojIyAxLjkuIE1lbmdndW5ha2FuIEZ1bmdzaSBhbm92YSgpDQpBTk9WQSAoYW5hbHlzaXMgb2YgdmFyaWFuY2UpIGFkYWxhaCBwZW5ndWppYW4geWFuZyBkaWxha3VrYW4gZGVuZ2FuIG1lbWJhbmRpbmdrYW4gdmFyaWFucy4gRGVuZ2FuIG1lbWJhbmRpbmdrYW4gdmFyaWFucyB0ZXJzZWJ1dCwgZGFwYXQgZGlrZXRhaHVpIGFkYSB0aWRha255YSBwZXJiZWRhYW4gcmF0YS1yYXRhIGRhcmkgdGlnYSBhdGF1IGxlYmloIGtlbG9tcG9rLiBBc3Vtc2kgbm9ybWFsaXRhcyBwYWRhIEFOT1ZBIGFkYWxhaCBwYWRhIHJlc2lkdWFsIHlhaXR1IHNlbGlzaWggYW50YXJhIFkgUHJlZGlrc2kgZGVuZ2FuIFkgQWt0dWFsLiBUZXBhdG55YSByZXNpZHVhbCBkYXBhdCBkaWhpdHVuZyBzZWJhZ2FpIGJlcmlrdXQ6IFkgQWt0dWFsIOKAkyBZIFByZWRpa3NpLiBEaW1hbmEgWSBBa3R1YWwgYWRhbGFoIFkgc2VzdW5nZ3VobnlhIGF0YXUga2VueWF0YWFuLiBTZWRhbmdrYW4gWSBwcmVkaWtzaSBhZGFsYWggWSBoYXNpbCBwZXJzYW1hYW4gQU5PVkEuDQoNCmBgYHtyfQ0KYW5vdmEobW9kZWwpDQpgYGANCg0KIyMgMS4xMC4gTWVtYnVhdCBwbG90KCkgZGFyaSBEYXRhIFJlYWwgZGFuIERhdGEgUHJlZGlrc2kNCmBgYHtyfQ0KcGxvdChkYXRhc2VtYnVoamFudWFyaSRTZW1idWggfiBkYXRhc2VtYnVoamFudWFyaSQNCiAgICAgICAgICAgICAgVGFuZ2dhbCwgDQogICAgIGRhdGEgPSBkYXRhc2VtYnVoamFudWFyaSwgY29sID0gInJlZCIsIHBjaCA9IDIwLCBjZXggPSAxLjUsIA0KICAgICBtYWluID0gIkRhdGEgQ292aWQgU0VNQlVIIGRpIERLSSBKYWthcnRhIGRhbiBHb29nbGUgTW9iaWxpdHkgSW5kZXgiKQ0KYWJsaW5lKG1vZGVsKSANCmBgYA0KRGFyaSBQbG90IGRpIGF0YXMgcGVybHUga2l0YSBrZXRhaHVpIGJhaHdhIHRpdGlrLXRpdGlrIE1lcmFoIHlhbmcgYWRhIHBhZGEgZ3JhZmlrIHRlcnNlYnV0IGFkYWxhaCBkYXRhIHJlYWwgZGFuIGdhcmlzIGhpdGFtIGRpIGRhbGFtIGtvdGFrIGFkYWxhaCBkYXRhIHByZWRpa3NpLg0KDQpgYGB7cn0NCnBsb3QoY29va3MuZGlzdGFuY2UobW9kZWwpLCBwY2ggPSAxNiwgY29sID0gInJlZCIpIA0KYGBgDQoNCmBgYHtyfQ0KcGxvdChtb2RlbCkNCmBgYA0KDQojIyAxLjExLiBQZW5nZ3VuYWFuIEFJQyBkYW4gQklDDQpBSUMgZGFuIEJJQyBiYW55YWsgZGlndW5ha2FuIGRhbGFtIGtyaXRlcmlhIHBlbWlsaWhhbiBtb2RlbC4gQUlDIGJlcmFydGkgS3JpdGVyaWEgSW5mb3JtYXNpIEFrYWlrZSBkYW4gQklDIGJlcmFydGkgS3JpdGVyaWEgSW5mb3JtYXNpIEJheWVzaWFuLiBNZXNraXB1biBrZWR1YSBpc3RpbGFoIGluaSBtZW1iYWhhcyBwZW1pbGloYW4gbW9kZWwsIGtlZHVhbnlhIHRpZGFrIHNhbWEuIFNlc2VvcmFuZyBkYXBhdCBtZW5lbXVrYW4gcGVyYmVkYWFuIGFudGFyYSBkdWEgcGVuZGVrYXRhbiBwZW1pbGloYW4gbW9kZWwuDQoNCmBgYHtyfQ0KQUlDKG1vZGVsKQ0KYGBgDQpgYGB7cn0NCkJJQyhtb2RlbCkNCmBgYA0KDQojIyAxLjExIE1lbXVuY3Vsa2FuIE5pbGFpIFByZWRpY3RlZCBkYW4gTWVtdmlzdWFsaXNhc2lrYW5ueWENCg0KYGBge3J9DQpoZWFkKHByZWRpY3QobW9kZWwpLCBuID0gMTUpDQpgYGANCmBgYHtyfQ0KcGxvdChoZWFkKHByZWRpY3QobW9kZWwpLCBuID0gMjApKQ0KYGBgDQoNCiMjIDEuMTIuIE1lbXVuY3Vsa2FuIE5pbGFpIFJlc2lkdWFscw0KDQpgYGB7cn0NCmhlYWQocmVzaWQobW9kZWwpLCBuID0gMTEpDQpgYGANCmBgYHtyfQ0KY29lZihtb2RlbCkNCmBgYA0KDQojIyAxLjEzLiBNZW1idWF0IFRhYmVsIFVudHVrIE1lbmFtYmFoIERhdGEgUmVzaWR1YWxzIGRhbiBEYXRhIFByZWRpY3RlZA0KDQpUYWJlbCBkaSBiYXdhaCBtZXJ1cGFrYW4gc2VtdWEgcHJvc2VzIHlhbmcgdGVsYWggZGlsYWt1a2FuLCBzZWhpbmdnYSB0ZXJidWF0IHRhYmVsIHlhbmcgYWRhIG5pbGFpIHJlc2lkdWFscyBkYW4gbmlsYWkgcHJvdGVjdGVkLg0KDQpgYGB7cn0NCmRhdGFzZW1idWhqYW51YXJpJHJlc2lkdWFscyA8LSBtb2RlbCRyZXNpZHVhbHMNCmBgYA0KYGBge3J9DQpkYXRhc2VtYnVoamFudWFyaSRwcmVkaWN0ZWQgPC0gbW9kZWwkZml0dGVkLnZhbHVlcw0KZGF0YXNlbWJ1aGphbnVhcmkNCmBgYA0KDQojIyAxLjE0LiBWaXN1YWxpc2FzaSBEYXRhIE1lbmdndW5ha2FuIHNjYXR0ZXIuc21vb3RoLCBib3hwbG90IGRhbiBwbG90DQoNCmBgYHtyfQ0Kc2NhdHRlci5zbW9vdGgoeD1kYXRhc2VtYnVoamFudWFyaSRUYW5nZ2FsLCB5PWRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCwgDQogICAgICAgICAgICAgICBtYWluPSJUYW5nZ2FsIH4gU0VNQlVIIikNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoZGF0YXNlbWJ1aGphbnVhcmkkU2VtYnVoLCBtYWluPSJTRU1CVUgiLCANCiAgICAgICAgYm94cGxvdC5zdGF0cyhkYXRhc2VtYnVoamFudWFyaSRTZW1idWgpJG91dCkNCmBgYA0KYGBge3J9DQpwbG90KGRlbnNpdHkoZGF0YXNlbWJ1aGphbnVhcmkkU2VtYnVoKSwgbWFpbj0iR29vZ2xlIE1vYmlsaXR5IEluZGV4IDogU0VNQlVIIiwgDQogICAgIHlsYWI9IkZyZXF1ZW5jeSIpDQpgYGANCg0KYGBge3J9DQpjb2VmcyA8LSBjb2VmKG1vZGVsKQ0KcGxvdChTZW1idWggfiBUYW5nZ2FsLCBkYXRhID0gZGF0YXNlbWJ1aGphbnVhcmkpDQphYmxpbmUoY29lZnMpDQp0ZXh0KHggPSAxMiwgeSA9IDEwLCBwYXN0ZSgnZXhwcmVzc2lvbiA9ICcsIHJvdW5kKGNvZWZzWzFdLCAyKSwgICcrJywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChjb2Vmc1syXSwgMiksICcqU0VNQlVIJykpDQpgYGANCg0KIyMgMS4xNS4gTWVsYWt1a2FuIFVqaSBLb3JlbGFzaSBBbnRhciBWYXJpYWJlbA0KDQpBZGFueWEga29yZWxhc2kgYW50YXIgdmFyaWFiZWwgZGFwYXQgZGlsYWt1a2FuIG1lbGFsdWkgdmlzdWFsaXNhc2kgbWVuZ2d1bmFrYW4gc2NhdHRlcnBsb3QgZGFuIHBlcmhpdHVuZ2FuIG1hdGVtYXRpcyBtZW5nZ3VuYWthbiBtZXRvZGUgUGVhcnNvbiB1bnR1ayBtZXRvZGUgcGFyYW1ldHJpayBkYW4gbWV0b2RlIHJhbmdraW5nIFNwZWFybWFuIGRhbiBLZW5kYWxsIHVudHVrIG1ldG9kZSBub24tcGFyYW1ldHJpay4gUGFkYSBSIHVqaSBrb3JlbGFzaSBkYXBhdCBkaWxha3VrYW4gZGVuZ2FuIG1lbmdndW5ha2FuIGZ1bmdzaSBjb3IudGVzdCgpLiBGb3JtYXQgZnVuZ3NpIHRlcnNlYnV0IGFkYWxhaCBzZWJhZ2FpIGJlcmlrdXQ6DQoNCioqYS4gVWppIEtvcmVsYXNpIFZhcmlibGUgWSBkZW5nYW4gWDEqKg0KYGBge3J9DQpjb3IudGVzdChkYXRhc2VtYnVoamFudWFyaSQNCiByZXRhaWxfYW5kX3JlY3JlYXRpb25fcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSwgDQogICAgICAgICBkYXRhc2VtYnVoamFudWFyaSRTZW1idWgpDQpgYGANCg0KKipiLiBVamkgS29yZWxhc2kgVmFyaWJsZSBZIGRlbmdhbiBYMioqDQpgYGB7cn0NCmNvci50ZXN0KGRhdGFzZW1idWhqYW51YXJpJGdyb2NlcnlfYW5kX3BoYXJtYWN5X3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUsIA0KICAgICAgICAgZGF0YXNlbWJ1aGphbnVhcmkkU2VtYnVoKQ0KYGBgDQoNCioqYy4gVWppIEtvcmVsYXNpIFZhcmlibGUgWSBkZW5nYW4gWDMqKg0KYGBge3J9DQpjb3IudGVzdChkYXRhc2VtYnVoamFudWFyaSQNCiBwYXJrc19wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCANCiAgICAgICAgIGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCkNCmBgYA0KDQoqKmQuIFVqaSBLb3JlbGFzaSBWYXJpYmxlIFkgZGVuZ2FuIFg0KioNCmBgYHtyfQ0KY29yLnRlc3QoZGF0YXNlbWJ1aGphbnVhcmkkDQogdHJhbnNpdF9zdGF0aW9uc19wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCANCiAgICAgICAgIGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCkNCmBgYA0KDQoqKmUuIFVqaSBLb3JlbGFzaSBWYXJpYmxlIFkgZGVuZ2FuIFg1KioNCmBgYHtyfQ0KY29yLnRlc3QoZGF0YXNlbWJ1aGphbnVhcmkkDQogd29ya3BsYWNlc19wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCANCiAgICAgICAgIGRhdGFzZW1idWhqYW51YXJpJFNlbWJ1aCkNCmBgYA0KDQoqKmQuIFVqaSBLb3JlbGFzaSBWYXJpYmxlIFkgZGVuZ2FuIFg2KioNCmBgYHtyfQ0KY29yLnRlc3QoZGF0YXNlbWJ1aGphbnVhcmkkDQogcmVzaWRlbnRpYWxfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSwgDQogICAgICAgICBkYXRhc2VtYnVoamFudWFyaSRTZW1idWgpDQpgYGANCg0KQmVyZGFzYXJrYW4gc2VsdXJ1aCBvdXRwdXQgeWFuZyBkaWhhc2lsa2FuLCBtZXRvZGUgUGVhcnNvbiBtZW5naGFzaWxrYW4gb3V0cHV0IGJlcnVwYSBuaWxhaSB0IHVqaSwgZGVyYWphdCBrZWJlYmFzYW4sIG5pbGFpIHAtdmFsdWUsIHJlbnRhbmcgZXN0aW1hc2kgbmlsYWkga29yZWxhc2kgYmVyZGFzYXJrYW4gdGluZ2thdCBrZXBlcmNheWFhbiwgZGFuIGVzdGltYXNpIG5pbGFpIGtvcmVsYXNpLg0KDQojIFJlZmVyZW5zaQ0KDQpodHRwczovL3JwdWJzLmNvbS9zdWhhcnRvbm8tdWlubWFsaWtpLzg3NzQ0OQ0KDQoNCg0K