Mata Kuliah : Linear Algebra (C)

Dosen Pengampu : Prof. Dr. Suhartono, M.Kom

Lembaga : Universitas Islam Negeri Maulana Malik Ibrahim Malang

Fakultas : Sains dan Teknologi

Jurusan : Teknik Informatika

NIM : 210605110050

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)
datameninggaljanuari <- read_excel(path = "DataMeninggalJanuari2021.xlsx")
datameninggaljanuari

1.2.Mencari Summary dari Data

summary(datameninggaljanuari)
    Tanggal                      Meninggal   
 Min.   :2021-01-01 00:00:00   Min.   :3308  
 1st Qu.:2021-01-08 06:00:00   1st Qu.:3468  
 Median :2021-01-15 12:00:00   Median :3745  
 Mean   :2021-01-15 12:00:00   Mean   :3752  
 3rd Qu.:2021-01-22 18:00:00   3rd Qu.:4013  
 Max.   :2021-01-30 00:00:00   Max.   :4254  
 retail_and_recreation_percent_change_from_baseline
 Min.   :-32.00                                    
 1st Qu.:-27.75                                    
 Median :-25.00                                    
 Mean   :-24.33                                    
 3rd Qu.:-20.25                                    
 Max.   :-15.00                                    
 grocery_and_pharmacy_percent_change_from_baseline
 Min.   :-20.000                                  
 1st Qu.:-15.000                                  
 Median :-10.500                                  
 Mean   : -8.733                                  
 3rd Qu.: -2.000                                  
 Max.   :  5.000                                  
 parks_percent_change_from_baseline transit_stations_percent_change_from_baseline
 Min.   :-36.00                     Min.   :-46.00                               
 1st Qu.:-30.00                     1st Qu.:-43.00                               
 Median :-24.50                     Median :-40.00                               
 Mean   :-20.37                     Mean   :-37.43                               
 3rd Qu.:-14.50                     3rd Qu.:-33.00                               
 Max.   : 18.00                     Max.   :-22.00                               
 workplaces_percent_change_from_baseline residential_percent_change_from_baseline
 Min.   :-66.00                          Min.   : 7.00                           
 1st Qu.:-32.00                          1st Qu.:10.00                           
 Median :-28.50                          Median :11.00                           
 Mean   :-27.80                          Mean   :10.97                           
 3rd Qu.:-23.25                          3rd Qu.:12.00                           
 Max.   : -8.00                          Max.   :19.00                           

1.3.Membuat Matriks Data

pairs(datameninggaljanuari)

pairs(datameninggaljanuari, lower.panel = NULL)

1.4.Visualisasi Data Menggunakan Fungsi Plot

plot(datameninggaljanuari$Meninggal ~ datameninggaljanuari$retail_and_recreation_percent_change_from_baseline, data = datameninggaljanuari)

1.5. Memvisualisasikan Data dengan Self Isolation sebagai variabel Y dan Google Mobility Index sebagai variabel X

plot(datameninggaljanuari$Meninggal ~ datameninggaljanuari$
              retail_and_recreation_percent_change_from_baseline+datameninggaljanuari$
      grocery_and_pharmacy_percent_change_from_baseline+datameninggaljanuari$
      parks_percent_change_from_baseline+datameninggaljanuari$
      transit_stations_percent_change_from_baseline+datameninggaljanuari$
      workplaces_percent_change_from_baseline+datameninggaljanuari$
      residential_percent_change_from_baseline, data = datameninggaljanuari)

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().

  1. Korelasi Variable Y dengan X1
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      retail_and_recreation_percent_change_from_baseline)
[1] -0.6652543
  1. Korelasi Variable Y dengan X2
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      grocery_and_pharmacy_percent_change_from_baseline)
[1] -0.69114
  1. Korelasi Variable Y dengan X3
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      parks_percent_change_from_baseline)
[1] -0.7928997
  1. Korelasi Variable Y dengan X4
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      transit_stations_percent_change_from_baseline)
[1] -0.6729416
  1. Korelasi Variable Y dengan X5
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      workplaces_percent_change_from_baseline)
[1] -0.05621336
  1. Korelasi Variable Y dengan X6
cor(datameninggaljanuari$Meninggal,datameninggaljanuari$
      residential_percent_change_from_baseline)
[1] -0.3004949

Dari hasil seluruh output di atas dapat disimpulkan bahwa untuk tingkat keterhubungan antara variabel y dengan x1, x2, x3, x4, dan x5 memiliki hubungan karena nilai yang dihasilkan berjumlah lebih dari 0.3. Sedangkan untuk tingkat keterhubungan antara variabel y dan x6 tidak sangat terhubung karena nilai yang dihasilkan berjumlah kurang dari 0.

1.7. Melakukan Permodelan

Berikut adalah cara melakukan permodelan Regresi Linier Berganda.

model <- lm(datameninggaljanuari$Meninggal ~ datameninggaljanuari$Tanggal, data = datameninggaljanuari)

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)

Call:
lm(formula = datameninggaljanuari$Meninggal ~ datameninggaljanuari$Tanggal, 
    data = datameninggaljanuari)

Residuals:
    Min      1Q  Median      3Q     Max 
-57.527 -10.806   0.571   9.914  56.767 

Coefficients:
                               Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  -6.292e+05  9.673e+03  -65.05   <2e-16 ***
datameninggaljanuari$Tanggal  3.930e-04  6.005e-06   65.43   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 24.6 on 28 degrees of freedom
Multiple R-squared:  0.9935,    Adjusted R-squared:  0.9933 
F-statistic:  4282 on 1 and 28 DF,  p-value: < 2.2e-16

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 = -57.527 Nilai Maximum = 56.767 Nilai Median = 0.571 Nilai Quartil 1 = -10.806 Nilai Quartil 3 = 9.914

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.9935. hal ini menunjukkan bahwa 0.009997% 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.9933 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)
Analysis of Variance Table

Response: datameninggaljanuari$Meninggal
                             Df  Sum Sq Mean Sq F value    Pr(>F)    
datameninggaljanuari$Tanggal  1 2590635 2590635  4281.6 < 2.2e-16 ***
Residuals                    28   16942     605                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

1.10. Membuat plot() dari Data Real dan Data Prediksi

plot(datameninggaljanuari$Meninggal ~ datameninggaljanuari$
              Tanggal, 
     data = datameninggaljanuari, col = "dodgerblue", pch = 20, cex = 1.5, 
     main = "Data Covid MENINGGAL di DKI Jakarta dan Google Mobility Index")
abline(model) 

Dari Plot di atas perlu kita ketahui bahwa titik-titik hijau yang ada pada grafik tersebut adalah data real dan garis hitam di dalam kotak adalah data prediksi.

plot(cooks.distance(model), pch = 16, col = "dodgerblue") 

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)
[1] 281.2266
BIC(model)
[1] 285.4302

1.11 Memunculkan Nilai Predicted dan Memvisualisasikannya

head(predict(model), n = 15)
       1        2        3        4        5        6        7        8        9 
3259.310 3293.261 3327.212 3361.163 3395.114 3429.065 3463.016 3496.967 3530.918 
      10       11       12       13       14       15 
3564.869 3598.820 3632.771 3666.722 3700.673 3734.624 
plot(head(predict(model), n = 20))

1.12. Memunculkan Nilai Residuals

head(resid(model), n = 11)
         1          2          3          4          5          6          7 
 48.690323  40.739266  17.788209   7.837152  -3.113904 -19.064961 -28.016018 
         8          9         10         11 
-33.967075 -45.918131 -13.869188  -9.820245 
coef(model)
                 (Intercept) datameninggaljanuari$Tanggal 
                -6.29181e+05                  3.92952e-04 

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.

datameninggaljanuari$residuals <- model$residuals
datameninggaljanuari$predicted <- model$fitted.values
datameninggaljanuari

1.14. Visualisasi Data Menggunakan scatter.smooth, boxplot dan plot

scatter.smooth(x=datameninggaljanuari$Tanggal, y=datameninggaljanuari$Meninggal, 
               main="Tanggal ~ MENINGGAL")

boxplot(datameninggaljanuari$Meninggal, main="MENINGGAL", 
        boxplot.stats(datameninggaljanuari$Meninggal)$out)

plot(density(datameninggaljanuari$Meninggal), main="Google Mobility Index: MENINGGAL", 
     ylab="Frequency")

coefs <- coef(model)
plot(Meninggal ~ Tanggal, data = datameninggaljanuari)
abline(coefs)
text(x = 12, y = 10, paste('expression = ', round(coefs[1], 2),  '+', 
                           round(coefs[2], 2), '*MENINGGAL'))

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(datameninggaljanuari$
 retail_and_recreation_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$retail_and_recreation_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -4.7149, df = 28, p-value = 6.047e-05
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.8272548 -0.4011223
sample estimates:
       cor 
-0.6652543 

b. Uji Korelasi Varible Y dengan X2

cor.test(datameninggaljanuari$grocery_and_pharmacy_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$grocery_and_pharmacy_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -5.0603, df = 28, p-value = 2.352e-05
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.8418032 -0.4405715
sample estimates:
     cor 
-0.69114 

c. Uji Korelasi Varible Y dengan X3

cor.test(datameninggaljanuari$
 parks_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$parks_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -6.8854, df = 28, p-value = 1.751e-07
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.8969489 -0.6056345
sample estimates:
       cor 
-0.7928997 

d. Uji Korelasi Varible Y dengan X4

cor.test(datameninggaljanuari$
 transit_stations_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$transit_stations_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -4.814, df = 28, p-value = 4.612e-05
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.8315980 -0.4127362
sample estimates:
       cor 
-0.6729416 

e. Uji Korelasi Varible Y dengan X5

cor.test(datameninggaljanuari$
 workplaces_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$workplaces_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -0.29792, df = 28, p-value = 0.768
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.4082154  0.3103409
sample estimates:
        cor 
-0.05621336 

d. Uji Korelasi Varible Y dengan X6

cor.test(datameninggaljanuari$
 residential_percent_change_from_baseline, 
         datameninggaljanuari$Meninggal)

    Pearson's product-moment correlation

data:  datameninggaljanuari$residential_percent_change_from_baseline and datameninggaljanuari$Meninggal
t = -1.6671, df = 28, p-value = 0.1066
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
 -0.59621809  0.06703107
sample estimates:
       cor 
-0.3004949 

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.

LS0tDQp0aXRsZTogIihKYW51YXJpIDIwMjEgLSBNRU5JTkdHQUwgQ09WSUQtMTkgRElTRUFTRSkgQW5hbGlzaXMgUmVncmVzaSBMaW5lYXIgQmVyZ2FuZGEgVGVyaGFkYXAgRGF0YSBDb3ZpZCBkaSBES0kgSmFrYXJ0YSBQYWRhIEJ1bGFuIEphbnVhcmkgMjAyMSINCmF1dGhvcjogIlJpZnFpIE11cnRpYW5pLCBQcm9mLiBEci4gU3VoYXJ0b25vLCBNLktvbS4iDQpkYXRlOiAiMy8yNC8yMDIyIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogc3BhY2VsYWINCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogMg0KICAgIHRvY19mbG9hdDogeWVzDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6ICcyJw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoqKk1hdGEgS3VsaWFoKiogOiAqKkxpbmVhciBBbGdlYnJhIChDKSoqDQoNCioqRG9zZW4gUGVuZ2FtcHUqKiA6ICoqUHJvZi4gRHIuIFN1aGFydG9ubywgTS5Lb20qKg0KDQoqKkxlbWJhZ2EqKiA6ICoqVW5pdmVyc2l0YXMgSXNsYW0gTmVnZXJpIE1hdWxhbmEgTWFsaWsgSWJyYWhpbSBNYWxhbmcqKg0KDQoqKkZha3VsdGFzKiogOiAqKlNhaW5zIGRhbiBUZWtub2xvZ2kqKg0KDQoqKkp1cnVzYW4qKiA6ICoqVGVrbmlrIEluZm9ybWF0aWthKioNCg0KKipOSU0qKiA6ICoqMjEwNjA1MTEwMDUwKioNCg0KDQojIDEuIE1lbWJhbmd1biBSZWdyZXNpIExpbmllciBCZXJnYW5kYQ0KDQpSZWdyZXNpIExpbmVhciBCZXJnYW5kYSBhZGFsYWggbW9kZWwgcmVncmVzaSBsaW5lYXIgZGVuZ2FuIG1lbGliYXRrYW4gbGViaWggZGFyaSBzYXR1IHZhcmlhYmxlIGJlYmFzIGF0YXUgcHJlZGljdG9yLiBEYWxhbSBiYWhhc2EgaW5nZ3JpcywgaXN0aWxhaCBpbmkgZGlzZWJ1dCBkZW5nYW4gbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24uDQoNCiMjIDEuMSBNZW5nLWltcG9ydCBEYXRhIGRhbiBtZW5hbXBpbGthbm55YQ0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KDQpgYGB7cn0NCmRhdGFtZW5pbmdnYWxqYW51YXJpIDwtIHJlYWRfZXhjZWwocGF0aCA9ICJEYXRhTWVuaW5nZ2FsSmFudWFyaTIwMjEueGxzeCIpDQpkYXRhbWVuaW5nZ2FsamFudWFyaQ0KYGBgDQoNCiMjIDEuMi5NZW5jYXJpIFN1bW1hcnkgZGFyaSBEYXRhDQoNCmBgYHtyfQ0Kc3VtbWFyeShkYXRhbWVuaW5nZ2FsamFudWFyaSkNCmBgYA0KDQojIyAxLjMuTWVtYnVhdCBNYXRyaWtzIERhdGENCg0KYGBge3J9DQpwYWlycyhkYXRhbWVuaW5nZ2FsamFudWFyaSkNCmBgYA0KDQpgYGB7cn0NCnBhaXJzKGRhdGFtZW5pbmdnYWxqYW51YXJpLCBsb3dlci5wYW5lbCA9IE5VTEwpDQpgYGANCg0KIyMgMS40LlZpc3VhbGlzYXNpIERhdGEgTWVuZ2d1bmFrYW4gRnVuZ3NpIFBsb3QNCg0KYGBge3J9DQpwbG90KGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCB+IGRhdGFtZW5pbmdnYWxqYW51YXJpJHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBkYXRhID0gZGF0YW1lbmluZ2dhbGphbnVhcmkpDQpgYGANCg0KIyMgMS41LiBNZW12aXN1YWxpc2FzaWthbiBEYXRhIGRlbmdhbiBTZWxmIElzb2xhdGlvbiBzZWJhZ2FpIHZhcmlhYmVsIFkgZGFuIEdvb2dsZSBNb2JpbGl0eSBJbmRleCBzZWJhZ2FpIHZhcmlhYmVsIFgNCmBgYHtyfQ0KcGxvdChkYXRhbWVuaW5nZ2FsamFudWFyaSRNZW5pbmdnYWwgfiBkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgICAgICAgICAgcmV0YWlsX2FuZF9yZWNyZWF0aW9uX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUrZGF0YW1lbmluZ2dhbGphbnVhcmkkDQogICAgICBncm9jZXJ5X2FuZF9waGFybWFjeV9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lK2RhdGFtZW5pbmdnYWxqYW51YXJpJA0KICAgICAgcGFya3NfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZStkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHRyYW5zaXRfc3RhdGlvbnNfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZStkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHdvcmtwbGFjZXNfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZStkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHJlc2lkZW50aWFsX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUsIGRhdGEgPSBkYXRhbWVuaW5nZ2FsamFudWFyaSkNCmBgYA0KIyMgMS42LiBNZW1idWF0IEtvcmVsYXNpIEFudGFyIFZhcmlhYmxlDQpLb3JlbGFzaSBtZXJ1cGFrYW4ga2V0ZXJodWJ1bmdhbiBhbnRhciB2YXJpYWJlbC4gVW50dWsgbWVuZ3VrdXIgc2ViZXJhcGEgamF1aCBodWJ1bmdhbiBhbnRhcmEgc2F0dSB2YXJpYWJlbCBkZW5nYW4gdmFyaWFiZWwgeWFuZyBsYWluIGtpdGEgZGFwYXQgbWVuZ2d1bmFrYW4gZnVuZ3NpIGNvcigpLg0KDQogIGEuIEtvcmVsYXNpIFZhcmlhYmxlIFkgZGVuZ2FuIFgxDQogIA0KYGBge3J9DQpjb3IoZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsLGRhdGFtZW5pbmdnYWxqYW51YXJpJA0KICAgICAgcmV0YWlsX2FuZF9yZWNyZWF0aW9uX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUpDQpgYGANCiAgDQogIGIuIEtvcmVsYXNpIFZhcmlhYmxlIFkgZGVuZ2FuIFgyDQpgYGB7cn0NCmNvcihkYXRhbWVuaW5nZ2FsamFudWFyaSRNZW5pbmdnYWwsZGF0YW1lbmluZ2dhbGphbnVhcmkkDQogICAgICBncm9jZXJ5X2FuZF9waGFybWFjeV9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lKQ0KYGBgDQogIA0KICBjLiBLb3JlbGFzaSBWYXJpYWJsZSBZIGRlbmdhbiBYMw0KYGBge3J9DQpjb3IoZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsLGRhdGFtZW5pbmdnYWxqYW51YXJpJA0KICAgICAgcGFya3NfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSkNCmBgYA0KICANCiAgZC4gS29yZWxhc2kgVmFyaWFibGUgWSBkZW5nYW4gWDQNCmBgYHtyfQ0KY29yKGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCxkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHRyYW5zaXRfc3RhdGlvbnNfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSkNCmBgYA0KICANCiAgZS4gS29yZWxhc2kgVmFyaWFibGUgWSBkZW5nYW4gWDUNCmBgYHtyfQ0KY29yKGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCxkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHdvcmtwbGFjZXNfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSkNCmBgYA0KICANCiAgZi4gS29yZWxhc2kgVmFyaWFibGUgWSBkZW5nYW4gWDYNCmBgYHtyfQ0KY29yKGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCxkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiAgICAgIHJlc2lkZW50aWFsX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUpDQpgYGANCkRhcmkgaGFzaWwgc2VsdXJ1aCBvdXRwdXQgZGkgYXRhcyBkYXBhdCBkaXNpbXB1bGthbiBiYWh3YSB1bnR1ayB0aW5na2F0IGtldGVyaHVidW5nYW4gYW50YXJhIHZhcmlhYmVsIHkgZGVuZ2FuIHgxLCB4MiwgeDMsIHg0LCBkYW4geDUgbWVtaWxpa2kgaHVidW5nYW4ga2FyZW5hIG5pbGFpIHlhbmcgZGloYXNpbGthbiBiZXJqdW1sYWggbGViaWggZGFyaSAwLjMuIFNlZGFuZ2thbiB1bnR1ayB0aW5na2F0IGtldGVyaHVidW5nYW4gYW50YXJhIHZhcmlhYmVsIHkgZGFuIHg2IHRpZGFrIHNhbmdhdCB0ZXJodWJ1bmcga2FyZW5hIG5pbGFpIHlhbmcgZGloYXNpbGthbiBiZXJqdW1sYWgga3VyYW5nIGRhcmkgMC4NCg0KDQojIyAxLjcuIE1lbGFrdWthbiBQZXJtb2RlbGFuDQpCZXJpa3V0IGFkYWxhaCBjYXJhIG1lbGFrdWthbiBwZXJtb2RlbGFuIFJlZ3Jlc2kgTGluaWVyIEJlcmdhbmRhLg0KDQpgYGB7cn0NCm1vZGVsIDwtIGxtKGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCB+IGRhdGFtZW5pbmdnYWxqYW51YXJpJFRhbmdnYWwsIGRhdGEgPSBkYXRhbWVuaW5nZ2FsamFudWFyaSkNCmBgYA0KDQogIFNlbGFuanV0bnlhIGRlbmdhbiBtb2RlbCB5YW5nIHRlbGFoIGRpYnVhdCBkaSBhdGFzLCBraXRhIGFrYW4gbWVuZ2d1bmFrYW4gZnVuZ3NpIHN1bW1hcnkoKSB1bnR1ayBtZW5qZWxhc2thbiBhdGF1IG1lcmV2aWV3IGhhc2lsIGRhcmkgbW9kZWwgdGVyc2VidXQuIERhbiBkZW5nYW4gcmluZ2thc2FuIHN1bW1hcnkobW9kZWwpIGtpdGEgZGFwYXQgbWVsaWhhdCBpbmZvcm1hc2kgdGVycGVyaW5jaSB0ZW50YW5nIGtpbmVyamEgZGFuIGtvZWZpc2lhbiBtb2RlbC4NCiAgDQpgYGB7cn0NCnN1bW1hcnkobW9kZWwpDQpgYGANCg0KIyMgMS44LiBNZW5qZWxhc2thbiBSaW5jaWFuIE1vZGVsIERlbmdhbiBGdW5nc2kgc3VtbWFyeSgpDQoNCkRpIGF0YXMgbWVydXBha2FuIHJpbmNpYW4gZGFyaSBtb2RlbCB5YW5nIHRlbGFoIGRpYnVhdC4NCg0Kc2V0ZWxhaCBtZW5qYWxhbmthbiBmdW5nc2kgc3VtbWFyeSgpIG1ha2EgYWthbiBkaWRhcGF0IDUgbmlsYWkgcmVzaWR1YWwuIFJlc2lkdWFsIGFkYWxhaCBwZXJiZWRhYW4gYW50YXJhIG5pbGFpIG55YXRhIGRhbiBuaWxhaSBwcmVkaWtzaS4gWWFuZyBtYW5hIHNlbWFraW4ga2VjaWwgbmlsYWkgcmVzaWR1YWwgbWFrYSBzZW1ha2luIGJhaWsgYXRhdSBiZW5hciBtb2RlbCB5YW5nIGtpdGEgYnVhdC4gQmVyaWt1dCBuaWxhaS1uaWxhaSByZXNpZHVhbCB5YW5nIGRpaGFzaWxrYW46DQoNCk5pbGFpIE1pbmltdW0gPSAtNTcuNTI3DQpOaWxhaSBNYXhpbXVtID0gNTYuNzY3DQpOaWxhaSBNZWRpYW4gPSAwLjU3MQ0KTmlsYWkgUXVhcnRpbCAxID0gLTEwLjgwNg0KTmlsYWkgUXVhcnRpbCAzID0gOS45MTQNCg0KRGFyaSBuaWxhaS1uaWxhaSB0ZXJzZWJ1dCBkYXBhdCBraXRhIGxpaGF0IGJhaHdhIGRhbGFtIGtvbnRla3MgaW5pIGJlcnVwYSBuaWxhaSBtaW5pbXVtLCBtYXhpbXVtLCBtZWRpYW4sIHF1YXJ0aWwgMSBkYW4gcXVhcnRpbCAzLiBEYXBhdCBraXRhIHNpbXB1bGthbiBiYWh3YSBtb2RlbCB5YW5nIHRlbGFoIGtpdGEgYnVhdCBiZWx1bSBiaXNhIGRpa2F0YWthbiBiYWlrIGF0YXUgYmVuYXIga2FyZW5hIG5pbGFpLW5pbGFpIHlhbmcgZGloYXNpbGthbiB0aWRhayBtZW5kZWthdGkgbm9sLg0KDQpEaSBiYXdhaCBuaWxhaSByZXNpZHVhbCB0ZXJkYXBhdCBrb2VmaXNpZW4sIHlhbmcgbWFuYSBkYWxhbSBrb2VmaXNpZW4gdGVyc2VidXQgdGVyZGFwYXQgbmlsYWkgaW50ZXJzZXAsIGRhbiB0YW5nZ2FsLiBTZWxhaW4gaXR1IGp1Z2EgdGVyZGFwYXQgbmlsYWktcCBkYXJpIGtvZWZpc2llbg0KDQpTZWxhbmp1dG55YSB0ZXJkYXBhdCBkdWEgUjIgeWFpdHU6DQoNCk11bHRpcGxlIFItc3F1YXJlZDogMC45OTM1LiBoYWwgaW5pIG1lbnVuanVra2FuIGJhaHdhIDAuMDA5OTk3JSB2YXJpYXNpIHZhcmlhYmVsIHJlc3BvbiwgeSwgZGFwYXQgZGlqZWxhc2thbiBvbGVoIHZhcmlhYmVsIHByZWRpa3RvciB4LiBNdWx0aXBsZSBSLXNxdWFyZWQgdGlkYWsgZGFwYXQgYmVya3VyYW5nIHNhYXQga2l0YSBtZW5hbWJhaGthbiBsZWJpaCBiYW55YWsgdmFyaWFiZWwgaW5kZXBlbmRlbiBrZSBtb2RlbCB5YW5nIGtpdGEgYnVhdC4NCg0KQWRqdXN0ZWQgUi1zcXVhcmVkOiAgMC45OTMzDQpBZGp1c3RlZCBSLXNxdWFyZWQgbGViaWggYmFpayBhZGEgcGVuYW1iYWhhbiB2YXJpYWJlbC4gSmFkaSBqaWthIGtpdGEgbWVuYW1iYWhrYW4gbGViaWggZGFyaSBzYXR1IHZhcmlhYmVsIGtlIG1vZGVsLCBpdHUgaGFueWEgbWVuaW5na2F0IGppa2EgaXR1IG1lbmd1cmFuZ2kga2VzYWxhaGFuIHByZWRpa3NpIHNlY2FyYSBrZXNlbHVydWhhbi4NCg0KIyMgMS45LiBNZW5nZ3VuYWthbiBGdW5nc2kgYW5vdmEoKQ0KQU5PVkEgKGFuYWx5c2lzIG9mIHZhcmlhbmNlKSBhZGFsYWggcGVuZ3VqaWFuIHlhbmcgZGlsYWt1a2FuIGRlbmdhbiBtZW1iYW5kaW5na2FuIHZhcmlhbnMuIERlbmdhbiBtZW1iYW5kaW5na2FuIHZhcmlhbnMgdGVyc2VidXQsIGRhcGF0IGRpa2V0YWh1aSBhZGEgdGlkYWtueWEgcGVyYmVkYWFuIHJhdGEtcmF0YSBkYXJpIHRpZ2EgYXRhdSBsZWJpaCBrZWxvbXBvay4gQXN1bXNpIG5vcm1hbGl0YXMgcGFkYSBBTk9WQSBhZGFsYWggcGFkYSByZXNpZHVhbCB5YWl0dSBzZWxpc2loIGFudGFyYSBZIFByZWRpa3NpIGRlbmdhbiBZIEFrdHVhbC4gVGVwYXRueWEgcmVzaWR1YWwgZGFwYXQgZGloaXR1bmcgc2ViYWdhaSBiZXJpa3V0OiBZIEFrdHVhbCDigJMgWSBQcmVkaWtzaS4gRGltYW5hIFkgQWt0dWFsIGFkYWxhaCBZIHNlc3VuZ2d1aG55YSBhdGF1IGtlbnlhdGFhbi4gU2VkYW5na2FuIFkgcHJlZGlrc2kgYWRhbGFoIFkgaGFzaWwgcGVyc2FtYWFuIEFOT1ZBLg0KDQpgYGB7cn0NCmFub3ZhKG1vZGVsKQ0KYGBgDQoNCiMjIDEuMTAuIE1lbWJ1YXQgcGxvdCgpIGRhcmkgRGF0YSBSZWFsIGRhbiBEYXRhIFByZWRpa3NpDQpgYGB7cn0NCnBsb3QoZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsIH4gZGF0YW1lbmluZ2dhbGphbnVhcmkkDQogICAgICAgICAgICAgIFRhbmdnYWwsIA0KICAgICBkYXRhID0gZGF0YW1lbmluZ2dhbGphbnVhcmksIGNvbCA9ICJkb2RnZXJibHVlIiwgcGNoID0gMjAsIGNleCA9IDEuNSwgDQogICAgIG1haW4gPSAiRGF0YSBDb3ZpZCBNRU5JTkdHQUwgZGkgREtJIEpha2FydGEgZGFuIEdvb2dsZSBNb2JpbGl0eSBJbmRleCIpDQphYmxpbmUobW9kZWwpIA0KYGBgDQpEYXJpIFBsb3QgZGkgYXRhcyBwZXJsdSBraXRhIGtldGFodWkgYmFod2EgdGl0aWstdGl0aWsgaGlqYXUgeWFuZyBhZGEgcGFkYSBncmFmaWsgdGVyc2VidXQgYWRhbGFoIGRhdGEgcmVhbCBkYW4gZ2FyaXMgaGl0YW0gZGkgZGFsYW0ga290YWsgYWRhbGFoIGRhdGEgcHJlZGlrc2kuDQoNCmBgYHtyfQ0KcGxvdChjb29rcy5kaXN0YW5jZShtb2RlbCksIHBjaCA9IDE2LCBjb2wgPSAiZG9kZ2VyYmx1ZSIpIA0KYGBgDQoNCmBgYHtyfQ0KcGxvdChtb2RlbCkNCmBgYA0KDQojIyAxLjExLiBQZW5nZ3VuYWFuIEFJQyBkYW4gQklDDQpBSUMgZGFuIEJJQyBiYW55YWsgZGlndW5ha2FuIGRhbGFtIGtyaXRlcmlhIHBlbWlsaWhhbiBtb2RlbC4gQUlDIGJlcmFydGkgS3JpdGVyaWEgSW5mb3JtYXNpIEFrYWlrZSBkYW4gQklDIGJlcmFydGkgS3JpdGVyaWEgSW5mb3JtYXNpIEJheWVzaWFuLiBNZXNraXB1biBrZWR1YSBpc3RpbGFoIGluaSBtZW1iYWhhcyBwZW1pbGloYW4gbW9kZWwsIGtlZHVhbnlhIHRpZGFrIHNhbWEuIFNlc2VvcmFuZyBkYXBhdCBtZW5lbXVrYW4gcGVyYmVkYWFuIGFudGFyYSBkdWEgcGVuZGVrYXRhbiBwZW1pbGloYW4gbW9kZWwuDQoNCmBgYHtyfQ0KQUlDKG1vZGVsKQ0KYGBgDQpgYGB7cn0NCkJJQyhtb2RlbCkNCmBgYA0KDQojIyAxLjExIE1lbXVuY3Vsa2FuIE5pbGFpIFByZWRpY3RlZCBkYW4gTWVtdmlzdWFsaXNhc2lrYW5ueWENCg0KYGBge3J9DQpoZWFkKHByZWRpY3QobW9kZWwpLCBuID0gMTUpDQpgYGANCmBgYHtyfQ0KcGxvdChoZWFkKHByZWRpY3QobW9kZWwpLCBuID0gMjApKQ0KYGBgDQoNCiMjIDEuMTIuIE1lbXVuY3Vsa2FuIE5pbGFpIFJlc2lkdWFscw0KDQpgYGB7cn0NCmhlYWQocmVzaWQobW9kZWwpLCBuID0gMTEpDQpgYGANCmBgYHtyfQ0KY29lZihtb2RlbCkNCmBgYA0KDQojIyAxLjEzLiBNZW1idWF0IFRhYmVsIFVudHVrIE1lbmFtYmFoIERhdGEgUmVzaWR1YWxzIGRhbiBEYXRhIFByZWRpY3RlZA0KDQpUYWJlbCBkaSBiYXdhaCBtZXJ1cGFrYW4gc2VtdWEgcHJvc2VzIHlhbmcgdGVsYWggZGlsYWt1a2FuLCBzZWhpbmdnYSB0ZXJidWF0IHRhYmVsIHlhbmcgYWRhIG5pbGFpIHJlc2lkdWFscyBkYW4gbmlsYWkgcHJvdGVjdGVkLg0KDQpgYGB7cn0NCmRhdGFtZW5pbmdnYWxqYW51YXJpJHJlc2lkdWFscyA8LSBtb2RlbCRyZXNpZHVhbHMNCmBgYA0KYGBge3J9DQpkYXRhbWVuaW5nZ2FsamFudWFyaSRwcmVkaWN0ZWQgPC0gbW9kZWwkZml0dGVkLnZhbHVlcw0KZGF0YW1lbmluZ2dhbGphbnVhcmkNCmBgYA0KDQojIyAxLjE0LiBWaXN1YWxpc2FzaSBEYXRhIE1lbmdndW5ha2FuIHNjYXR0ZXIuc21vb3RoLCBib3hwbG90IGRhbiBwbG90DQoNCmBgYHtyfQ0Kc2NhdHRlci5zbW9vdGgoeD1kYXRhbWVuaW5nZ2FsamFudWFyaSRUYW5nZ2FsLCB5PWRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCwgDQogICAgICAgICAgICAgICBtYWluPSJUYW5nZ2FsIH4gTUVOSU5HR0FMIikNCmBgYA0KDQpgYGB7cn0NCmJveHBsb3QoZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsLCBtYWluPSJNRU5JTkdHQUwiLCANCiAgICAgICAgYm94cGxvdC5zdGF0cyhkYXRhbWVuaW5nZ2FsamFudWFyaSRNZW5pbmdnYWwpJG91dCkNCmBgYA0KYGBge3J9DQpwbG90KGRlbnNpdHkoZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsKSwgbWFpbj0iR29vZ2xlIE1vYmlsaXR5IEluZGV4OiBNRU5JTkdHQUwiLCANCiAgICAgeWxhYj0iRnJlcXVlbmN5IikNCmBgYA0KDQpgYGB7cn0NCmNvZWZzIDwtIGNvZWYobW9kZWwpDQpwbG90KE1lbmluZ2dhbCB+IFRhbmdnYWwsIGRhdGEgPSBkYXRhbWVuaW5nZ2FsamFudWFyaSkNCmFibGluZShjb2VmcykNCnRleHQoeCA9IDEyLCB5ID0gMTAsIHBhc3RlKCdleHByZXNzaW9uID0gJywgcm91bmQoY29lZnNbMV0sIDIpLCAgJysnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGNvZWZzWzJdLCAyKSwgJypNRU5JTkdHQUwnKSkNCmBgYA0KDQojIyAxLjE1LiBNZWxha3VrYW4gVWppIEtvcmVsYXNpIEFudGFyIFZhcmlhYmVsDQoNCkFkYW55YSBrb3JlbGFzaSBhbnRhciB2YXJpYWJlbCBkYXBhdCBkaWxha3VrYW4gbWVsYWx1aSB2aXN1YWxpc2FzaSBtZW5nZ3VuYWthbiBzY2F0dGVycGxvdCBkYW4gcGVyaGl0dW5nYW4gbWF0ZW1hdGlzIG1lbmdndW5ha2FuIG1ldG9kZSBQZWFyc29uIHVudHVrIG1ldG9kZSBwYXJhbWV0cmlrIGRhbiBtZXRvZGUgcmFuZ2tpbmcgU3BlYXJtYW4gZGFuIEtlbmRhbGwgdW50dWsgbWV0b2RlIG5vbi1wYXJhbWV0cmlrLiBQYWRhIFIgdWppIGtvcmVsYXNpIGRhcGF0IGRpbGFrdWthbiBkZW5nYW4gbWVuZ2d1bmFrYW4gZnVuZ3NpIGNvci50ZXN0KCkuIEZvcm1hdCBmdW5nc2kgdGVyc2VidXQgYWRhbGFoIHNlYmFnYWkgYmVyaWt1dDoNCg0KKiphLiBVamkgS29yZWxhc2kgVmFyaWJsZSBZIGRlbmdhbiBYMSoqDQpgYGB7cn0NCmNvci50ZXN0KGRhdGFtZW5pbmdnYWxqYW51YXJpJA0KIHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCANCiAgICAgICAgIGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCkNCmBgYA0KDQoqKmIuIFVqaSBLb3JlbGFzaSBWYXJpYmxlIFkgZGVuZ2FuIFgyKioNCmBgYHtyfQ0KY29yLnRlc3QoZGF0YW1lbmluZ2dhbGphbnVhcmkkZ3JvY2VyeV9hbmRfcGhhcm1hY3lfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSwgDQogICAgICAgICBkYXRhbWVuaW5nZ2FsamFudWFyaSRNZW5pbmdnYWwpDQpgYGANCg0KKipjLiBVamkgS29yZWxhc2kgVmFyaWJsZSBZIGRlbmdhbiBYMyoqDQpgYGB7cn0NCmNvci50ZXN0KGRhdGFtZW5pbmdnYWxqYW51YXJpJA0KIHBhcmtzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUsIA0KICAgICAgICAgZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsKQ0KYGBgDQoNCioqZC4gVWppIEtvcmVsYXNpIFZhcmlibGUgWSBkZW5nYW4gWDQqKg0KYGBge3J9DQpjb3IudGVzdChkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiB0cmFuc2l0X3N0YXRpb25zX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUsIA0KICAgICAgICAgZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsKQ0KYGBgDQoNCioqZS4gVWppIEtvcmVsYXNpIFZhcmlibGUgWSBkZW5nYW4gWDUqKg0KYGBge3J9DQpjb3IudGVzdChkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiB3b3JrcGxhY2VzX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUsIA0KICAgICAgICAgZGF0YW1lbmluZ2dhbGphbnVhcmkkTWVuaW5nZ2FsKQ0KYGBgDQoNCioqZC4gVWppIEtvcmVsYXNpIFZhcmlibGUgWSBkZW5nYW4gWDYqKg0KYGBge3J9DQpjb3IudGVzdChkYXRhbWVuaW5nZ2FsamFudWFyaSQNCiByZXNpZGVudGlhbF9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCANCiAgICAgICAgIGRhdGFtZW5pbmdnYWxqYW51YXJpJE1lbmluZ2dhbCkNCmBgYA0KDQpCZXJkYXNhcmthbiBzZWx1cnVoIG91dHB1dCB5YW5nIGRpaGFzaWxrYW4sIG1ldG9kZSBQZWFyc29uIG1lbmdoYXNpbGthbiBvdXRwdXQgYmVydXBhIG5pbGFpIHQgdWppLCBkZXJhamF0IGtlYmViYXNhbiwgbmlsYWkgcC12YWx1ZSwgcmVudGFuZyBlc3RpbWFzaSBuaWxhaSBrb3JlbGFzaSBiZXJkYXNhcmthbiB0aW5na2F0IGtlcGVyY2F5YWFuLCBkYW4gZXN0aW1hc2kgbmlsYWkga29yZWxhc2kuDQoNCiMgUmVmZXJlbnNpDQoNCmh0dHBzOi8vcnB1YnMuY29tL3N1aGFydG9uby11aW5tYWxpa2kvODc3NDQ5DQoNCg0KDQo=