Pendahuluan
Kemarin saya sudah menuliskan tentang dasar-dasar regresi namun hanya
3 materi saja, yaitu : Regresi linear sederhana,
Regresi linear berganda &
Regresi logistik. Materi ini akan saya coba jelaskan yang
saya tau lebih dulu dari sampean. ohiya klik di sini untuk materi
sebelumnya. kita akan mencoba membuat contoh data set untuk membuat
model Regresi.
ohh iya literatur lain bisa di cek di sini
Jambelajar= round(runif(50, min = 5, max = 20))
Nilai = round(Jambelajar*2+rnorm(50, mean = 0, sd = 1))
data_Regsed = data.frame(Jambelajar, Nilai)
str(data_Regsed)
## 'data.frame': 50 obs. of 2 variables:
## $ Jambelajar: num 10 9 9 6 11 14 5 11 11 19 ...
## $ Nilai : num 22 18 18 13 22 27 10 23 22 38 ...
set.seed(123)
Jmlh_jam_bljr = round(runif(100, min = 10, max = 40))
Jmlh_prsn_bljr = round(runif(100, min = 5, max = 20))
prob_lulus = plogis(-5 + 0.1 * Jmlh_jam_bljr + 0.2 * Jmlh_prsn_bljr)
Keterangann = ifelse(runif(100) < prob_lulus, "lulus", "tidak lulus")
# Data set
data_reglog =data.frame(Jmlh_jam_bljr, Jmlh_prsn_bljr, Keterangann)
data_reglog$Keterangann = ifelse(data_reglog$Keterangann == "lulus", 1, 0)
str(data_reglog)
## 'data.frame': 100 obs. of 3 variables:
## $ Jmlh_jam_bljr : num 19 34 22 36 38 11 26 37 27 24 ...
## $ Jmlh_prsn_bljr: num 14 10 12 19 12 18 19 14 11 7 ...
## $ Keterangann : num 1 0 0 1 1 0 1 1 1 1 ...
Regresi
Sebelum di lakukan Regresi berikut adalah beberapa hal yang harus di
persiapkan.
Package
library(readxl)
library(readr)
library(stats)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.3 ✔ purrr 1.0.2
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.4 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dplyr)
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following object is masked from 'package:purrr':
##
## some
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(MASS)
##
## Attaching package: 'MASS'
##
## The following object is masked from 'package:dplyr':
##
## select
library(ggplot2)
library(corrplot)
## corrplot 0.92 loaded
library(lmtest)
library(broom)
library(MLmetrics)
##
## Attaching package: 'MLmetrics'
##
## The following object is masked from 'package:base':
##
## Recall
library(cowplot)
##
## Attaching package: 'cowplot'
##
## The following object is masked from 'package:lubridate':
##
## stamp
library(corrplot)
library(lattice)
Pemilihan Jenis Regresi
Nah ini adalah hal pertama yang harus di lakukan, jenis regresi di
pilih sesuai dengan jenis datanya. saya tulis sebelumnya klik di sini. ku coba
ringkas lagi.
Regresi linear Sederhana
Di gunakan ketika data yang di miliki hanya terdapat satu variabel
independen dan satu variabel dependen.
Regresi linear Berganda
Analisis regresi yang melibatkan lebih dari satu variabel independen
untuk memprediksi variabel dependen.
Regreli Logistik
Digunakan ketika data yang digunakan adalah data berbentuk
Biner.Regresi untuk memprediksi probabilitas kejadian suatu kejadian
tertentu (biasanya diwakili oleh kategori 1) berdasarkan nilai-nilai
variabel independen.
Data Eksprolation
Kedua adalah Data eksplorasi data, ini bertujuan untuk membersihkan
data dan memahami data secara menyeluruh.
Data preparation
Mencari data set, sudah ada di pendahuluan.
Data cleaning
Data cleaning bisa di cek di
sini
Cek Missing value
Data duplicate
Check data type
Exploration
Sebaran data
plots = lapply(names(data_Regsed), function(var_x){
p <-
ggplot(data_Regsed)+
aes_string(var_x)+
geom_density(lwd = 1, color = "darkorange")
})
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
plot_grid(plotlist = plots)

Korelasi
# Menghitung korelasi antar kolom
cor_matrix = round(cor(data_Regsed),2)
cor_matrix
## Jambelajar Nilai
## Jambelajar 1.00 0.99
## Nilai 0.99 1.00
# Membuat plot antar korelasi
corrplot(cor_matrix,
type = "lower",
method = "color",
tl.cex = 0.5,
tl.col = "black",
)

corrplot(cor(data_reglog), method = "circle", type = "lower", number.cex = 0.5, tl.cex = 0.7, tl.col = "black", diag = FALSE)

Di tahap ini adalah tahap melihat beberapa asumsi yang harus di
penuhi model regresi, yaitu : Multikolinearitas.
Membuat Model
Model Regresi linear
membuat model regresi linier
model_regresi_linear = lm(Nilai ~ ., data = data)
Model Regresi linear
Model_regresi_logistik <- glm(Nilai ~ ., family = binomial,
data_Regsed) step(Model_regresi_logistik)
Evaluasi Model
Confusion Matrix
Evaluasi terhadap model klasifikasi dilakukan dengan membuat tabel
klasifikasi antara kelas sebenarnya dengan kelas hasil prediksi dari
model klasifikasi. Tabel klasifikasi ini biasa disebut dengan Confusion
Matrix.
Confusion matrix dapat diartikan sebagai suatu alat yang memiliki
fungsi untuk melakukan analisis apakah classifier tersebut baik dalam
mengenali tuple dari kelas yang berbeda. Nilai dari True-Positive (TP)
dan True-Negative (TN) memberikan informasi ketika classifier dalam
melakukan klasifikasi data bernilai benar, sedangkan False-Positive (FP)
dan False-Negative (FN) memberikan informasi ketika classifier salah
dalam melakukan klasifikasi data (Han dan Kamber, 2011).
Pada performa klasifikasi akan dihitung akurasi, spesifisitas,
sensitivitas dan AUC. Akurasi merupakan persentase classifier benar
melakukan prediksi. Sensitivitas merupakan Persentase data positif yang
diprediksi sebagai positif. Dan Spesifisitas merupakan Persentase data
negatif diprediksi sebagai negatif (Faisal dan Nugrahadi,
2019).Sedangkan AUC adalah kinerja dari model klasifikasi.

ROC Plot
library(ROCR) pred<-
prediction(predict.glm(credit.glm.final,german.credit.test),german.credit.test$class)
perf <- performance(pred,“tpr”,“fpr”) plot(perf)

Penutup
Selanjutnya jika model sudah baik asumasi terpenuhi. maka model itu
bisa kita jadikan sebagai alat prediksi, dengan menggunakan data set
baru yang berisi variable yang sama dengan data set model. caranya
adalah :
membuat prediksi dengan data baru dari model
predicted_values <- predict(model_reglog, newdata = new_data)
Evaluasi model
residuals <- true_values - predicted_values mse <-
mean(residuals^2)
Plot model
plot(new_data\(X1, predicted_values, col =
"red", pch = 16, xlab = "X1", ylab = "Predicted
Y", main = "Model Regression Plot")
points(new_data\)X1, true_values, col = “blue”, pch = 16)
legend(“topleft”, legend = c(“Predicted Values”, “True Values”), col =
c(“red”, “blue”), pch = 16)
LS0tDQp0aXRsZTogIlJFR1JFU0kgTEFOSlVUQU4iDQphdXRob3I6ICJBbGJhbmkiDQpkYXRlOiAiMjAyNC0wMy0xOSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWUgOiB1bml0ZWQNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBsaWdodGJveDogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHRydWUNCi0tLQ0KDQojIFBlbmRhaHVsdWFuDQoNCktlbWFyaW4gc2F5YSBzdWRhaCBtZW51bGlza2FuIHRlbnRhbmcgZGFzYXItZGFzYXIgcmVncmVzaSBuYW11biBoYW55YSAzIG1hdGVyaSBzYWphLCB5YWl0dSA6IGBSZWdyZXNpIGxpbmVhciBzZWRlcmhhbmFgLCBgUmVncmVzaSBsaW5lYXIgYmVyZ2FuZGFgICYgYFJlZ3Jlc2kgbG9naXN0aWtgLiBNYXRlcmkgaW5pIGFrYW4gc2F5YSBjb2JhIGplbGFza2FuIHlhbmcgc2F5YSB0YXUgbGViaWggZHVsdSBkYXJpIHNhbXBlYW4uIG9oaXlhIFtrbGlrIGRpIHNpbmldKGh0dHBzOi8vcnB1YnMuY29tL2FsYmFuaTg4L1JlZ3Jlc2kpIHVudHVrIG1hdGVyaSBzZWJlbHVtbnlhLiBraXRhIGFrYW4gbWVuY29iYSBtZW1idWF0IGNvbnRvaCBkYXRhIHNldCB1bnR1ayBtZW1idWF0IG1vZGVsIFJlZ3Jlc2kuDQoNCm9oaCBpeWEgbGl0ZXJhdHVyIGxhaW4gYmlzYSBkaSBjZWsgW2RpIHNpbmldKGh0dHBzOi8vcnB1YnMuY29tL3JpemtpYS9zdGExMzgyLWFuYWxpc2lzLXJlZ3Jlc2kpDQoNCi0gUmVncmVzaSBMaW5lYXINCg0KYGBge3J9DQpKYW1iZWxhamFyPSByb3VuZChydW5pZig1MCwgbWluID0gNSwgbWF4ID0gMjApKQ0KTmlsYWkgPSByb3VuZChKYW1iZWxhamFyKjIrcm5vcm0oNTAsIG1lYW4gPSAwLCBzZCA9IDEpKQ0KZGF0YV9SZWdzZWQgPSBkYXRhLmZyYW1lKEphbWJlbGFqYXIsIE5pbGFpKQ0KDQpzdHIoZGF0YV9SZWdzZWQpDQpgYGANCg0KLSBSZWdyZXNpIGxvZ2lzdGlrDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KSm1saF9qYW1fYmxqciA9IHJvdW5kKHJ1bmlmKDEwMCwgbWluID0gMTAsIG1heCA9IDQwKSkNCkptbGhfcHJzbl9ibGpyID0gcm91bmQocnVuaWYoMTAwLCBtaW4gPSA1LCBtYXggPSAyMCkpDQpwcm9iX2x1bHVzID0gcGxvZ2lzKC01ICsgMC4xICogSm1saF9qYW1fYmxqciArIDAuMiAqIEptbGhfcHJzbl9ibGpyKQ0KS2V0ZXJhbmdhbm4gPSBpZmVsc2UocnVuaWYoMTAwKSA8IHByb2JfbHVsdXMsICJsdWx1cyIsICJ0aWRhayBsdWx1cyIpDQojIERhdGEgc2V0DQpkYXRhX3JlZ2xvZyA9ZGF0YS5mcmFtZShKbWxoX2phbV9ibGpyLCBKbWxoX3Byc25fYmxqciwgS2V0ZXJhbmdhbm4pDQpkYXRhX3JlZ2xvZyRLZXRlcmFuZ2FubiA9IGlmZWxzZShkYXRhX3JlZ2xvZyRLZXRlcmFuZ2FubiA9PSAibHVsdXMiLCAxLCAwKQ0Kc3RyKGRhdGFfcmVnbG9nKQ0KYGBgDQoNCiMgUmVncmVzaQ0KDQpTZWJlbHVtIGRpIGxha3VrYW4gUmVncmVzaSBiZXJpa3V0IGFkYWxhaCBiZWJlcmFwYSBoYWwgeWFuZyBoYXJ1cyBkaSBwZXJzaWFwa2FuLg0KDQojIyBQYWNrYWdlDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShzdGF0cykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShsbXRlc3QpDQpsaWJyYXJ5KE1BU1MpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShsbXRlc3QpDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShNTG1ldHJpY3MpDQpsaWJyYXJ5KGNvd3Bsb3QpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShsYXR0aWNlKQ0KYGBgDQoNCiMjIFBlbWlsaWhhbiBKZW5pcyBSZWdyZXNpDQoNCk5haCBpbmkgYWRhbGFoIGhhbCBwZXJ0YW1hIHlhbmcgaGFydXMgZGkgbGFrdWthbiwgamVuaXMgcmVncmVzaSBkaSBwaWxpaCBzZXN1YWkgZGVuZ2FuIGplbmlzIGRhdGFueWEuIHNheWEgdHVsaXMgc2ViZWx1bW55YSBba2xpayBkaSBzaW5pXShodHRwczovL3JwdWJzLmNvbS9hbGJhbmk4OC9SZWdyZXNpKS4ga3UgY29iYSByaW5na2FzIGxhZ2kuDQoNCiMjIyBSZWdyZXNpIGxpbmVhciBTZWRlcmhhbmENCg0KRGkgZ3VuYWthbiBrZXRpa2EgZGF0YSB5YW5nIGRpIG1pbGlraSBoYW55YSB0ZXJkYXBhdCBzYXR1IHZhcmlhYmVsIGluZGVwZW5kZW4gZGFuIHNhdHUgdmFyaWFiZWwgZGVwZW5kZW4uDQoNCiMjIyBSZWdyZXNpIGxpbmVhciBCZXJnYW5kYQ0KDQpBbmFsaXNpcyByZWdyZXNpIHlhbmcgbWVsaWJhdGthbiBsZWJpaCBkYXJpIHNhdHUgdmFyaWFiZWwgaW5kZXBlbmRlbiB1bnR1ayBtZW1wcmVkaWtzaSB2YXJpYWJlbCBkZXBlbmRlbi4NCg0KIyMjIFJlZ3JlbGkgTG9naXN0aWsNCg0KRGlndW5ha2FuIGtldGlrYSBkYXRhIHlhbmcgZGlndW5ha2FuIGFkYWxhaCBkYXRhIGJlcmJlbnR1ayBCaW5lci5SZWdyZXNpIHVudHVrIG1lbXByZWRpa3NpIHByb2JhYmlsaXRhcyBrZWphZGlhbiBzdWF0dSBrZWphZGlhbiB0ZXJ0ZW50dSAoYmlhc2FueWEgZGl3YWtpbGkgb2xlaCBrYXRlZ29yaSAxKSBiZXJkYXNhcmthbiBuaWxhaS1uaWxhaSB2YXJpYWJlbCBpbmRlcGVuZGVuLg0KDQotLS0NCg0KIyMgRGF0YSBFa3Nwcm9sYXRpb24NCg0KS2VkdWEgYWRhbGFoIERhdGEgZWtzcGxvcmFzaSBkYXRhLCBpbmkgYmVydHVqdWFuIHVudHVrIG1lbWJlcnNpaGthbiBkYXRhIGRhbiBtZW1haGFtaSBkYXRhIHNlY2FyYSBtZW55ZWx1cnVoLg0KDQojIyMgRGF0YSBwcmVwYXJhdGlvbg0KDQpNZW5jYXJpIGRhdGEgc2V0LCBzdWRhaCBhZGEgZGkgcGVuZGFodWx1YW4uDQoNCiMjIyBEYXRhIGNsZWFuaW5nDQoNCkRhdGEgY2xlYW5pbmcgYmlzYSBkaSBjZWsgW2RpIHNpbmldKCJodHRwczovL3JwdWJzLmNvbS9hbGJhbmk4OC9kYXRhLWVrcGxvcmF0aW8tZmxvdyIpDQoNCi0gQ2VrIE1pc3NpbmcgdmFsdWUNCg0KLSBEYXRhIGR1cGxpY2F0ZQ0KDQotIENoZWNrIGRhdGEgdHlwZQ0KDQojIyBFeHBsb3JhdGlvbg0KDQojIyMgU2ViYXJhbiBkYXRhDQoNCmBgYHtyfQ0KcGxvdHMgPSBsYXBwbHkobmFtZXMoZGF0YV9SZWdzZWQpLCBmdW5jdGlvbih2YXJfeCl7DQogIHAgPC0gDQogICAgZ2dwbG90KGRhdGFfUmVnc2VkKSsNCiAgICBhZXNfc3RyaW5nKHZhcl94KSsNCiAgICBnZW9tX2RlbnNpdHkobHdkID0gMSwgY29sb3IgPSAiZGFya29yYW5nZSIpDQp9KQ0KDQpwbG90X2dyaWQocGxvdGxpc3QgPSBwbG90cykNCmBgYA0KDQojIyMgS29yZWxhc2kNCg0KYGBge3J9DQojIE1lbmdoaXR1bmcga29yZWxhc2kgYW50YXIga29sb20NCmNvcl9tYXRyaXggPSByb3VuZChjb3IoZGF0YV9SZWdzZWQpLDIpDQpjb3JfbWF0cml4DQpgYGANCmBgYHtyfQ0KIyBNZW1idWF0IHBsb3QgYW50YXIga29yZWxhc2kNCmNvcnJwbG90KGNvcl9tYXRyaXgsDQogICAgICAgICB0eXBlID0gImxvd2VyIiwNCiAgICAgICAgIG1ldGhvZCA9ICJjb2xvciIsDQogICAgICAgICB0bC5jZXggPSAwLjUsDQogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLA0KKQ0KYGBgDQpgYGB7cn0NCmNvcnJwbG90KGNvcihkYXRhX3JlZ2xvZyksIG1ldGhvZCA9ICJjaXJjbGUiLCB0eXBlID0gImxvd2VyIiwgbnVtYmVyLmNleCA9IDAuNSwgdGwuY2V4ID0gMC43LCB0bC5jb2wgPSAiYmxhY2siLCBkaWFnID0gRkFMU0UpDQpgYGANCg0KRGkgdGFoYXAgaW5pIGFkYWxhaCB0YWhhcCBtZWxpaGF0IGJlYmVyYXBhIGFzdW1zaSB5YW5nIGhhcnVzIGRpIHBlbnVoaSBtb2RlbCByZWdyZXNpLCB5YWl0dSA6IGBNdWx0aWtvbGluZWFyaXRhc2AuDQoNCiMjIE1lbWJ1YXQgTW9kZWwNCg0KIyMjIE1vZGVsIFJlZ3Jlc2kgbGluZWFyDQoNCm1lbWJ1YXQgbW9kZWwgcmVncmVzaSBsaW5pZXINCg0KbW9kZWxfcmVncmVzaV9saW5lYXIgPSBsbShOaWxhaSB+IC4sIGRhdGEgPSBkYXRhKQ0KDQojIyMgTW9kZWwgUmVncmVzaSBsaW5lYXINCg0KTW9kZWxfcmVncmVzaV9sb2dpc3RpayA8LSBnbG0oTmlsYWkgfiAuLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YV9SZWdzZWQpDQpzdGVwKE1vZGVsX3JlZ3Jlc2lfbG9naXN0aWspDQoNCg0KIyMgRXZhbHVhc2kgTW9kZWwNCg0KIyMjIENvbmZ1c2lvbiBNYXRyaXgNCg0KRXZhbHVhc2kgdGVyaGFkYXAgbW9kZWwga2xhc2lmaWthc2kgZGlsYWt1a2FuIGRlbmdhbiBtZW1idWF0IHRhYmVsIGtsYXNpZmlrYXNpIGFudGFyYSBrZWxhcyBzZWJlbmFybnlhIGRlbmdhbiBrZWxhcyBoYXNpbCBwcmVkaWtzaSBkYXJpIG1vZGVsIGtsYXNpZmlrYXNpLiBUYWJlbCBrbGFzaWZpa2FzaSBpbmkgYmlhc2EgZGlzZWJ1dCBkZW5nYW4gQ29uZnVzaW9uIE1hdHJpeC4NCg0KQ29uZnVzaW9uIG1hdHJpeCBkYXBhdCBkaWFydGlrYW4gc2ViYWdhaSBzdWF0dSBhbGF0IHlhbmcgbWVtaWxpa2kgZnVuZ3NpIHVudHVrIG1lbGFrdWthbiBhbmFsaXNpcyBhcGFrYWggY2xhc3NpZmllciB0ZXJzZWJ1dCBiYWlrIGRhbGFtIG1lbmdlbmFsaSB0dXBsZSBkYXJpIGtlbGFzIHlhbmcgYmVyYmVkYS4gTmlsYWkgZGFyaSBUcnVlLVBvc2l0aXZlIChUUCkgZGFuIFRydWUtTmVnYXRpdmUgKFROKSBtZW1iZXJpa2FuIGluZm9ybWFzaSBrZXRpa2EgY2xhc3NpZmllciBkYWxhbSBtZWxha3VrYW4ga2xhc2lmaWthc2kgZGF0YSBiZXJuaWxhaSBiZW5hciwgc2VkYW5na2FuIEZhbHNlLVBvc2l0aXZlIChGUCkgZGFuIEZhbHNlLU5lZ2F0aXZlIChGTikgbWVtYmVyaWthbiBpbmZvcm1hc2kga2V0aWthIGNsYXNzaWZpZXIgc2FsYWggZGFsYW0gbWVsYWt1a2FuIGtsYXNpZmlrYXNpIGRhdGEgKEhhbiBkYW4gS2FtYmVyLCAyMDExKS4NCg0KUGFkYSBwZXJmb3JtYSBrbGFzaWZpa2FzaSBha2FuIGRpaGl0dW5nIGFrdXJhc2ksIHNwZXNpZmlzaXRhcywgc2Vuc2l0aXZpdGFzIGRhbiBBVUMuIEFrdXJhc2kgbWVydXBha2FuIHBlcnNlbnRhc2UgY2xhc3NpZmllciBiZW5hciBtZWxha3VrYW4gcHJlZGlrc2kuIFNlbnNpdGl2aXRhcyBtZXJ1cGFrYW4gUGVyc2VudGFzZSBkYXRhIHBvc2l0aWYgeWFuZyBkaXByZWRpa3NpIHNlYmFnYWkgcG9zaXRpZi4gRGFuIFNwZXNpZmlzaXRhcyBtZXJ1cGFrYW4gUGVyc2VudGFzZSBkYXRhIG5lZ2F0aWYgZGlwcmVkaWtzaSBzZWJhZ2FpIG5lZ2F0aWYgKEZhaXNhbCBkYW4gTnVncmFoYWRpLCAyMDE5KS5TZWRhbmdrYW4gQVVDIGFkYWxhaCBraW5lcmphIGRhcmkgbW9kZWwga2xhc2lmaWthc2kuDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL0FkbWluaXN0cmF0b3IvRG93bmxvYWRzL1doYXRzQXBwIEltYWdlIDIwMjQtMDMtMjAgYXQgMDUuMjMuMTAuanBlZyIpDQpgYGANCg0KIyMjIFJPQyBQbG90DQoNCmxpYnJhcnkoUk9DUikNCnByZWQ8LQ0KcHJlZGljdGlvbihwcmVkaWN0LmdsbShjcmVkaXQuZ2xtLmZpbmFsLGdlcm1hbi5jcmVkaXQudGVzdCksZ2VybWFuLmNyZWRpdC50ZXN0JGNsYXNzKQ0KcGVyZiA8LSBwZXJmb3JtYW5jZShwcmVkLCJ0cHIiLCJmcHIiKQ0KcGxvdChwZXJmKQ0KDQpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJDOi9Vc2Vycy9BZG1pbmlzdHJhdG9yL0Rvd25sb2Fkcy9yb2MgcGxvdC5wbmciKQ0KYGBgDQoNCiMgUGVudXR1cA0KDQpTZWxhbmp1dG55YSBqaWthIG1vZGVsIHN1ZGFoIGJhaWsgYXN1bWFzaSB0ZXJwZW51aGkuIG1ha2EgbW9kZWwgaXR1IGJpc2Ega2l0YSBqYWRpa2FuIHNlYmFnYWkgYWxhdCBwcmVkaWtzaSwgZGVuZ2FuIG1lbmdndW5ha2FuIGRhdGEgc2V0IGJhcnUgeWFuZyBiZXJpc2kgdmFyaWFibGUgeWFuZyBzYW1hIGRlbmdhbiBkYXRhIHNldCBtb2RlbC4gY2FyYW55YSBhZGFsYWggOg0KDQoNCm1lbWJ1YXQgcHJlZGlrc2kgZGVuZ2FuIGRhdGEgYmFydSBkYXJpIG1vZGVsDQoNCnByZWRpY3RlZF92YWx1ZXMgPC0gcHJlZGljdChtb2RlbF9yZWdsb2csIG5ld2RhdGEgPSBuZXdfZGF0YSkNCg0KIyMgRXZhbHVhc2kgbW9kZWwNCg0KcmVzaWR1YWxzIDwtIHRydWVfdmFsdWVzIC0gcHJlZGljdGVkX3ZhbHVlcw0KbXNlIDwtIG1lYW4ocmVzaWR1YWxzXjIpDQoNCiMjIFBsb3QgbW9kZWwNCg0KcGxvdChuZXdfZGF0YSRYMSwgcHJlZGljdGVkX3ZhbHVlcywgY29sID0gInJlZCIsIHBjaCA9IDE2LCB4bGFiID0gIlgxIiwgeWxhYiA9ICJQcmVkaWN0ZWQgWSIsIG1haW4gPSAiTW9kZWwgUmVncmVzc2lvbiBQbG90IikNCnBvaW50cyhuZXdfZGF0YSRYMSwgdHJ1ZV92YWx1ZXMsIGNvbCA9ICJibHVlIiwgcGNoID0gMTYpDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJQcmVkaWN0ZWQgVmFsdWVzIiwgIlRydWUgVmFsdWVzIiksIGNvbCA9IGMoInJlZCIsICJibHVlIiksIHBjaCA9IDE2KQ0KDQotLS0=