KOMUNITAS BELAJAR R
TEKNIK INFORMATIKA - UIN MALIKI MALANG

Pemateri : Muhammad Isa Ansori, SE
Mahasiswa Magister Informatika

1. Deskripsi

Dalam rangka peningkatan kerjasama dengan marketplace di wilayah Malang Raya, perlu dibuatkan standard operasi dan target pencapaian kiriman pada level prosentase atau nilai tertentu yang disepakati agar customer akan puas dengan layanan yang ditawarkan. PT Pos Indonesia KCU (Kantor Cabang Utama) Malang yang salah satunya membawahi wilayah kerja Kota dan Kabupaten Malang mempunyai peran penting untuk meyakinkan marketplace atas jasa pengiriman barang agar sesuai dengan standard waktu yang ditetapkan atau Service Level Agreement (SLA) yang disepakati dimana SLA kiriman PKH ke wilayah DKI Jakarta sebesar 0,98 / 98% kiriman sampai. Adapun standard yang digunakan untuk melakukan perhitungan sebagai analisa awal adalah kiriman dari Malang ke Jakarta dengan menggunakan jasa service/layanan Pos Kilat Khusus (PKH) dimana mempunai SLA maximum 3 hari penyerahan kiriman. Dari kebutuhan tersebut dibutuhkan prediksi untuk layanan PKH ini untuk meyakinkan marketplace yang akan mengadakan kerjasama dengan PREDIKSI REGRESI DENGAN NEURAL NETWORK BACK PROPAGATION

2. Aktivasi Library

Pada Analisa regresi ini dibutuhkan sejumlah library. Library yang digunakan dalam analisa studi kasus ini antara lain:

  1. readxl : library ini digunakan untuk membaca file xls/xlsx
  2. neuralnet : library untuk mengelola penerapan rumus Neural Network back propagation.
  3. Metrics : library untuk menghitung tingkat error dengan menggunakan RMSE.
library(readxl)
library(neuralnet)
library(Metrics)

3. Data Set

Untuk melakukan persiapan data ini, ditetapkan terlebih dahulu SLA kiriman PKH ke wilayah DKI Jakarta sebesar 0,98 / 98% kiriman sampai.

Berikut table data yang akan di prediksi selamat 30 hari dari tanggal 25 April 2022 sampai dengan 25 Mei 2022 sumber data dari : PT Pos Indonesia KCU Malang dalam bentuk Excell.

#baca data excel
data_pkh_malang <- read_excel("data_kh_ml_jkt.xlsx")
data_pkh_malang
## # A tibble: 30 x 6
##    tanggal_kirim       transaksi  berat   otd oversla   nilai
##    <dttm>                  <dbl>  <dbl> <dbl>   <dbl>   <dbl>
##  1 2022-04-25 00:00:00       256 280.     229      27  0.789 
##  2 2022-04-26 00:00:00       212 245.     194      18  0.830 
##  3 2022-04-27 00:00:00       202 174.     182      20  0.802 
##  4 2022-04-28 00:00:00       225 183.     214      11  0.902 
##  5 2022-04-29 00:00:00       103  97.8     56      47  0.0874
##  6 2022-04-30 00:00:00        85  46.6     36      49 -0.153 
##  7 2022-05-01 00:00:00        16  15.1      8       8  0     
##  8 2022-05-02 00:00:00         2   5.20     1       1  0     
##  9 2022-05-04 00:00:00        51  43.3     50       1  0.961 
## 10 2022-05-05 00:00:00        45  85.4     39       6  0.733 
## # ... with 20 more rows

4. Design System

Desain sistem yang akan digunakan untuk kali ini adalah menggunakan neural network backpropagation. Backpropagation (Propagasi balik) adalah salah satu dari jaringan saraf tiruan (Neural Network) merupakan metode pelatihan yang terawasi (Supervised Learning) dengan jaringan multi layer dan memiliki ciri khusus meminimalkan error pada output yang dihasilkan oleh jaringan.

4.1 Flowchart




4.2 Neural Network Design & Rumus



Keterangan:
X : Input layer
Z : Hidden layer
Y : Output
Untuk mencari Hidden layar Z diperoleh dari penjumlahan nilai input X dikali dengan bobot W ditambah dengan bias (B).


Keterangan:
Zn : Hideen layer ke-n
Xi : Input data ke-i
Wi : Bobot input data ke-i terhadap Z ke-i

Setelah semua dicari nilai hidden layer Z maka nilai Y dicari dengan menjumlahkan nilai lapisan tersembunya Z dikalikan dengan bobot lapisan tersembunyi V ditambah biasnya.



Keterangan:
Y : Output
Zi : Hidden layer ke-i
Vi : Bobot hidden layer ke-i terhadap Y

5. Data Training dan Data Testing

Untuk melakukan analisa prediksi diperlukan data Training dan data Testing, dari 30 data akan diambil 28 data Training dan 2 data testing.

5.1 Data Training

# hitung jumlah baris

jmlBaris <- NROW(data_pkh_malang) 

# Membagi Data Training dari 30 baris menjadi 28
data_training <- data_pkh_malang[1:(jmlBaris - 2),]
data_training
## # A tibble: 28 x 6
##    tanggal_kirim       transaksi  berat   otd oversla   nilai
##    <dttm>                  <dbl>  <dbl> <dbl>   <dbl>   <dbl>
##  1 2022-04-25 00:00:00       256 280.     229      27  0.789 
##  2 2022-04-26 00:00:00       212 245.     194      18  0.830 
##  3 2022-04-27 00:00:00       202 174.     182      20  0.802 
##  4 2022-04-28 00:00:00       225 183.     214      11  0.902 
##  5 2022-04-29 00:00:00       103  97.8     56      47  0.0874
##  6 2022-04-30 00:00:00        85  46.6     36      49 -0.153 
##  7 2022-05-01 00:00:00        16  15.1      8       8  0     
##  8 2022-05-02 00:00:00         2   5.20     1       1  0     
##  9 2022-05-04 00:00:00        51  43.3     50       1  0.961 
## 10 2022-05-05 00:00:00        45  85.4     39       6  0.733 
## # ... with 18 more rows

5.2 Data Testing

# Membagi Data Testing dari 30 baris menjadi 2
data_testing <- data_pkh_malang[(jmlBaris-1) :jmlBaris,]
data_testing
## # A tibble: 2 x 6
##   tanggal_kirim       transaksi berat   otd oversla nilai
##   <dttm>                  <dbl> <dbl> <dbl>   <dbl> <dbl>
## 1 2022-05-24 00:00:00       166  131.   140      26 0.687
## 2 2022-05-25 00:00:00       180  132.   174       6 0.933

6. Neural Network Model

Menghitung Rumus

#fungsi neural network
nnmodel <-  neuralnet(nilai ~ transaksi + berat,data = data_training,hidden = c(2), linear.output = T)


Plot

plot(nnmodel)



Hasil

result_nn <- compute(nnmodel, data_testing[,2:3])
result_nn[["net.result"]]
##           [,1]
## [1,] 0.7222035
## [2,] 0.7222035


7. Evaluasi Hasil Prediksi dengan RMSE

Untuk evaluasi digunakan RMSE (Root Mean Square Error) adalah metode pengukuran dengan mengukur perbedaan nilai dari prediksi sebuah model sebagai estimasi atas nilai yang diobservasi. Root Mean Square Error adalah hasil dari akar kuadrat Mean Square Error. Keakuratan metode estimasi kesalahan pengukuran ditandai dengan adanya nilai RMSE yang kecil. Metode estimasi yang mempunyai Root Mean Square Error (RMSE) lebih kecil dikatakan lebih akurat daripada metode estimasi yang mempunyai Root Mean Square Error (RMSE) lebih besar. Namun untuk kali ini yang digunakan prediksi neural network backpropagattion saja.




Keterangan :
At = Nilai data Aktual
Ft = Nilai hasil peramalan
N= banyaknya data
∑ = Summation (Jumlahkan keseluruhan nilai)

errornn = rmse(data_testing$nilai, result_nn$net.result) 
errornn
## [1] 0.1513819

Dari hasil RMSE tingkat errornya sudah rendah yaitu ….. Dengan error yang rendah ini prediksi mempunyai nilai yang tinggi.

8. Kesimpulan

Dari implementasi prediksi dengan neuralnetwork backpropagation dan evaluasi RMSE dapat disimpulkan :
1. Bahwa rencana kerjasama dengan marketplace untuk tujuan DKI Jakarta denga SLA 0,98 namun hasil prediksi …. masih jauh dari harapan, perlu dilakukan upaya-upaya perbaikan operasi.
2. Transaksi dan Berat mempunyai indikator sebagai input yang mempengaruhi nilai yang ada.
3. RMSE 0,14 relatif rendah namun perlu dilakukan uji lagi dengan membandingkan metode lainnya misal dengan KNN atau Multiple Linear Regretion

9. Referensi

LS0tDQp0aXRsZTogIlByZWRpa3NpIFJlZ3Jlc2kgRGVuZ2FuIE5ldXJhbCBOZXR3b3JrIEJhY2sgUHJvcGFnYXRpb24iDQpzdWJ0aXRsZTogIktpcmltYW4gUGFrZXQgUG9zIEluZG9uZXNpYSBUdWp1YW4gTWFsYW5nIEpha2FydGEiDQoNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0aGVtZTogZmxhdGx5DQogICAgY29kZV9mb2xkaW5nOiAic2hvdyINCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCi0tLQ0KDQo8YnI+IDxpbWcgc3JjPSJpbWFnZXMvbG9nb191aW5fa2VjaWwucG5nIiBzdHlsZT0iZmxvYXQ6IGxlZnQ7IG1hcmdpbjogLTEwcHggNTBweCAwcHggNTBweDsgd2lkdGg6MTUlIi8+DQoNCg0KKipLT01VTklUQVMgQkVMQUpBUiBSICoqPGJyPg0KKipURUtOSUsgSU5GT1JNQVRJS0EgLSBVSU4gTUFMSUtJIE1BTEFORyoqDQoNCipQZW1hdGVyaSA6IE11aGFtbWFkIElzYSBBbnNvcmksIFNFKg0KPGJyPg0KKk1haGFzaXN3YSBNYWdpc3RlciBJbmZvcm1hdGlrYSoNCjxicj4NCg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCiMgMS4gRGVza3JpcHNpDQpEYWxhbSByYW5na2EgcGVuaW5na2F0YW4ga2VyamFzYW1hIGRlbmdhbiBtYXJrZXRwbGFjZSBkaSB3aWxheWFoIE1hbGFuZyBSYXlhLCBwZXJsdSBkaWJ1YXRrYW4gc3RhbmRhcmQgb3BlcmFzaSBkYW4gdGFyZ2V0IHBlbmNhcGFpYW4ga2lyaW1hbiBwYWRhIGxldmVsIHByb3NlbnRhc2UgYXRhdSBuaWxhaSB0ZXJ0ZW50dSB5YW5nIGRpc2VwYWthdGkgYWdhciBjdXN0b21lciBha2FuIHB1YXMgZGVuZ2FuIGxheWFuYW4geWFuZyBkaXRhd2Fya2FuLg0KUFQgUG9zIEluZG9uZXNpYSBLQ1UgKEthbnRvciBDYWJhbmcgVXRhbWEpIE1hbGFuZyB5YW5nIHNhbGFoIHNhdHVueWEgbWVtYmF3YWhpIHdpbGF5YWgga2VyamEgIEtvdGEgZGFuIEthYnVwYXRlbiBNYWxhbmcgbWVtcHVueWFpIHBlcmFuIHBlbnRpbmcgdW50dWsgbWV5YWtpbmthbiBtYXJrZXRwbGFjZSBhdGFzIGphc2EgcGVuZ2lyaW1hbiBiYXJhbmcgYWdhciBzZXN1YWkgZGVuZ2FuIHN0YW5kYXJkIHdha3R1IHlhbmcgZGl0ZXRhcGthbiBhdGF1IFNlcnZpY2UgTGV2ZWwgQWdyZWVtZW50IChTTEEpIHlhbmcgZGlzZXBha2F0aSBkaW1hbmEgU0xBIGtpcmltYW4gUEtIIGtlIHdpbGF5YWggREtJIEpha2FydGEgc2ViZXNhciAwLDk4IC8gOTglIGtpcmltYW4gc2FtcGFpLg0KQWRhcHVuIHN0YW5kYXJkIHlhbmcgZGlndW5ha2FuIHVudHVrIG1lbGFrdWthbiBwZXJoaXR1bmdhbiBzZWJhZ2FpIGFuYWxpc2EgYXdhbCBhZGFsYWgga2lyaW1hbiBkYXJpIE1hbGFuZyBrZSBKYWthcnRhIGRlbmdhbiBtZW5nZ3VuYWthbiBqYXNhIHNlcnZpY2UvbGF5YW5hbiBQb3MgS2lsYXQgS2h1c3VzIChQS0gpIGRpbWFuYSBtZW1wdW5haSBTTEEgIG1heGltdW0gMyBoYXJpIHBlbnllcmFoYW4ga2lyaW1hbi4NCkRhcmkga2VidXR1aGFuIHRlcnNlYnV0IGRpYnV0dWhrYW4gcHJlZGlrc2kgdW50dWsgbGF5YW5hbiBQS0ggaW5pIHVudHVrIG1leWFraW5rYW4gbWFya2V0cGxhY2UgeWFuZyBha2FuIG1lbmdhZGFrYW4ga2VyamFzYW1hIGRlbmdhbiAgUFJFRElLU0kgUkVHUkVTSSBERU5HQU4gTkVVUkFMIE5FVFdPUksgQkFDSyBQUk9QQUdBVElPTg0KDQojIDIuIEFrdGl2YXNpIExpYnJhcnkNCg0KUGFkYSBBbmFsaXNhIHJlZ3Jlc2kgaW5pIGRpYnV0dWhrYW4gc2VqdW1sYWggbGlicmFyeS4gTGlicmFyeSB5YW5nIGRpZ3VuYWthbiBkYWxhbSBhbmFsaXNhIHN0dWRpIGthc3VzIGluaSBhbnRhcmEgbGFpbjoNCg0KMS4gIGByZWFkeGxgIDogbGlicmFyeSBpbmkgZGlndW5ha2FuIHVudHVrIG1lbWJhY2EgZmlsZSB4bHMveGxzeA0KMi4gIGBuZXVyYWxuZXRgIDogbGlicmFyeSB1bnR1ayBtZW5nZWxvbGEgcGVuZXJhcGFuIHJ1bXVzIE5ldXJhbCBOZXR3b3JrIGJhY2sgcHJvcGFnYXRpb24uDQozLiAgYE1ldHJpY3NgIDogbGlicmFyeSB1bnR1ayBtZW5naGl0dW5nIHRpbmdrYXQgZXJyb3IgZGVuZ2FuIG1lbmdndW5ha2FuIFJNU0UuDQoNCmBgYHtyLCAgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShuZXVyYWxuZXQpDQpsaWJyYXJ5KE1ldHJpY3MpDQpgYGANCg0KIyAzLiBEYXRhIFNldA0KDQpVbnR1ayBtZWxha3VrYW4gcGVyc2lhcGFuIGRhdGEgaW5pLCBkaXRldGFwa2FuIHRlcmxlYmloIGRhaHVsdSBTTEEga2lyaW1hbiBQS0gga2Ugd2lsYXlhaCBES0kgSmFrYXJ0YSBzZWJlc2FyIDAsOTggLyA5OCUga2lyaW1hbiBzYW1wYWkuDQoNCkJlcmlrdXQgdGFibGUgZGF0YSB5YW5nIGFrYW4gZGkgcHJlZGlrc2kgc2VsYW1hdCAzMCBoYXJpIGRhcmkgdGFuZ2dhbCAyNSBBcHJpbCAyMDIyIHNhbXBhaSBkZW5nYW4gMjUgTWVpIDIwMjIgc3VtYmVyIGRhdGEgZGFyaSA6IFBUIFBvcyBJbmRvbmVzaWEgS0NVIE1hbGFuZyBkYWxhbSBiZW50dWsgRXhjZWxsLg0KDQpgYGB7cn0NCiNiYWNhIGRhdGEgZXhjZWwNCmRhdGFfcGtoX21hbGFuZyA8LSByZWFkX2V4Y2VsKCJkYXRhX2toX21sX2prdC54bHN4IikNCmRhdGFfcGtoX21hbGFuZw0KYGBgDQoNCiMgNC4gRGVzaWduIFN5c3RlbQ0KDQpEZXNhaW4gc2lzdGVtIHlhbmcgYWthbiBkaWd1bmFrYW4gdW50dWsga2FsaSBpbmkgYWRhbGFoIG1lbmdndW5ha2FuIG5ldXJhbCBuZXR3b3JrIGJhY2twcm9wYWdhdGlvbi4gIEJhY2twcm9wYWdhdGlvbiAoUHJvcGFnYXNpIGJhbGlrKSBhZGFsYWggc2FsYWggc2F0dSBkYXJpIGphcmluZ2FuIHNhcmFmIHRpcnVhbiAoTmV1cmFsIE5ldHdvcmspIG1lcnVwYWthbiBtZXRvZGUgcGVsYXRpaGFuIHlhbmcgdGVyYXdhc2kgKFN1cGVydmlzZWQgTGVhcm5pbmcpIGRlbmdhbiBqYXJpbmdhbiBtdWx0aSBsYXllciBkYW4gbWVtaWxpa2kgY2lyaSBraHVzdXMgbWVtaW5pbWFsa2FuIGVycm9yIHBhZGEgb3V0cHV0IHlhbmcgZGloYXNpbGthbiBvbGVoIGphcmluZ2FuLg0KDQojIyA0LjEgRmxvd2NoYXJ0DQo8YnI+IDxpbWcgc3JjPSJpbWFnZXMvZmxvd2NoYXJ0LnBuZyIgc3R5bGU9ImZsb2F0OiBjZW50ZXI7IG1hcmdpbjogLTEwcHggNTBweCAwcHggNTBweDsgd2lkdGg6NTAlIi8+DQo8YnI+DQo8YnI+DQoNCiMjIDQuMiBOZXVyYWwgTmV0d29yayBEZXNpZ24gJiBSdW11cw0KPGJyPiA8aW1nIHNyYz0iaW1hZ2VzL2Rlc2lnbi5wbmciIHN0eWxlPSJmbG9hdDogY2VudGVyOyBtYXJnaW46IC0xMHB4IDUwcHggMHB4IDUwcHg7IHdpZHRoOjUwJSIvPg0KPGJyPg0KDQpLZXRlcmFuZ2FuOiA8YnI+DQpYIDogSW5wdXQgbGF5ZXIgPGJyPg0KWiA6IEhpZGRlbiBsYXllciA8YnI+DQpZIDogT3V0cHV0IDxicj4NClVudHVrIG1lbmNhcmkgSGlkZGVuIGxheWFyIFogZGlwZXJvbGVoIGRhcmkgcGVuanVtbGFoYW4gbmlsYWkgaW5wdXQgWCBkaWthbGkgZGVuZ2FuIGJvYm90IFcgZGl0YW1iYWggZGVuZ2FuIGJpYXMgKEIpLg0KPGJyPg0KPGJyPiA8aW1nIHNyYz0iaW1hZ2VzL3J1bXVzLnBuZyIgc3R5bGU9ImZsb2F0OiBjZW50ZXI7IG1hcmdpbjogLTEwcHggNTBweCAwcHggNTBweDsgd2lkdGg6MzAlIi8+DQo8YnI+DQpLZXRlcmFuZ2FuOiA8YnI+DQpabiA6IEhpZGVlbiBsYXllciBrZS1uIDxicj4NClhpIDogSW5wdXQgZGF0YSBrZS1pIDxicj4NCldpIDogQm9ib3QgaW5wdXQgZGF0YSBrZS1pIHRlcmhhZGFwIFoga2UtaSA8YnI+DQoNClNldGVsYWggc2VtdWEgZGljYXJpIG5pbGFpIGhpZGRlbiBsYXllciBaIG1ha2EgbmlsYWkgWSAgZGljYXJpIGRlbmdhbiBtZW5qdW1sYWhrYW4gbmlsYWkgbGFwaXNhbiB0ZXJzZW1idW55YSBaIGRpa2FsaWthbiBkZW5nYW4gYm9ib3QgbGFwaXNhbiB0ZXJzZW1idW55aSBWIGRpdGFtYmFoIGJpYXNueWEuDQoNCjxicj4gPGltZyBzcmM9ImltYWdlcy9ydW11c1kucG5nIiBzdHlsZT0iZmxvYXQ6IGNlbnRlcjsgbWFyZ2luOiAtMTBweCA1MHB4IDBweCA1MHB4OyB3aWR0aDozMCUiLz4NCjxicj4NCktldGVyYW5nYW46IDxicj4NClkgOiBPdXRwdXQgPGJyPg0KWmkgOiBIaWRkZW4gbGF5ZXIga2UtaSA8YnI+DQpWaSA6IEJvYm90IGhpZGRlbiBsYXllciBrZS1pIHRlcmhhZGFwIFkgPGJyPg0KDQoNCg0KIyA1LiBEYXRhIFRyYWluaW5nIGRhbiBEYXRhIFRlc3RpbmcNCg0KVW50dWsgbWVsYWt1a2FuIGFuYWxpc2EgcHJlZGlrc2kgZGlwZXJsdWthbiBkYXRhIFRyYWluaW5nIGRhbiBkYXRhIFRlc3RpbmcsIGRhcmkgMzAgZGF0YSBha2FuIGRpYW1iaWwgMjggZGF0YSBUcmFpbmluZyBkYW4gMiBkYXRhIHRlc3RpbmcuDQoNCiMjIDUuMSBEYXRhIFRyYWluaW5nDQpgYGB7cn0NCiMgaGl0dW5nIGp1bWxhaCBiYXJpcw0KDQpqbWxCYXJpcyA8LSBOUk9XKGRhdGFfcGtoX21hbGFuZykgDQoNCiMgTWVtYmFnaSBEYXRhIFRyYWluaW5nIGRhcmkgMzAgYmFyaXMgbWVuamFkaSAyOA0KZGF0YV90cmFpbmluZyA8LSBkYXRhX3BraF9tYWxhbmdbMTooam1sQmFyaXMgLSAyKSxdDQpkYXRhX3RyYWluaW5nDQpgYGANCg0KIyMgNS4yIERhdGEgVGVzdGluZw0KDQpgYGB7cn0NCiMgTWVtYmFnaSBEYXRhIFRlc3RpbmcgZGFyaSAzMCBiYXJpcyBtZW5qYWRpIDINCmRhdGFfdGVzdGluZyA8LSBkYXRhX3BraF9tYWxhbmdbKGptbEJhcmlzLTEpIDpqbWxCYXJpcyxdDQpkYXRhX3Rlc3RpbmcNCmBgYA0KDQojIDYuIE5ldXJhbCBOZXR3b3JrIE1vZGVsIA0KDQpNZW5naGl0dW5nIFJ1bXVzDQpgYGB7cn0NCiNmdW5nc2kgbmV1cmFsIG5ldHdvcmsNCm5ubW9kZWwgPC0gIG5ldXJhbG5ldChuaWxhaSB+IHRyYW5zYWtzaSArIGJlcmF0LGRhdGEgPSBkYXRhX3RyYWluaW5nLGhpZGRlbiA9IGMoMiksIGxpbmVhci5vdXRwdXQgPSBUKQ0KYGBgDQo8YnI+DQpQbG90DQpgYGB7cn0NCnBsb3Qobm5tb2RlbCkNCmBgYA0KDQo8YnI+IDxpbWcgc3JjPSJpbWFnZXMvbm4ucG5nIiBzdHlsZT0iZmxvYXQ6IGNlbnRlcjsgbWFyZ2luOiAtMTBweCA1MHB4IDBweCA1MHB4OyB3aWR0aDoxMDAlIi8+PGJyPg0KDQpIYXNpbA0KYGBge3J9DQpyZXN1bHRfbm4gPC0gY29tcHV0ZShubm1vZGVsLCBkYXRhX3Rlc3RpbmdbLDI6M10pDQpyZXN1bHRfbm5bWyJuZXQucmVzdWx0Il1dDQpgYGANCg0KPGJyPg0KDQojIDcuIEV2YWx1YXNpIEhhc2lsIFByZWRpa3NpIGRlbmdhbiBSTVNFDQoNClVudHVrIGV2YWx1YXNpIGRpZ3VuYWthbiBSTVNFIChSb290IE1lYW4gU3F1YXJlIEVycm9yKSAgYWRhbGFoICBtZXRvZGUgcGVuZ3VrdXJhbiBkZW5nYW4gbWVuZ3VrdXIgcGVyYmVkYWFuIG5pbGFpIGRhcmkgcHJlZGlrc2kgc2VidWFoIG1vZGVsIHNlYmFnYWkgZXN0aW1hc2kgYXRhcyBuaWxhaSB5YW5nIGRpb2JzZXJ2YXNpLiBSb290IE1lYW4gU3F1YXJlIEVycm9yIGFkYWxhaCBoYXNpbCBkYXJpIGFrYXIga3VhZHJhdCBNZWFuIFNxdWFyZSBFcnJvci4gS2Vha3VyYXRhbiBtZXRvZGUgZXN0aW1hc2kga2VzYWxhaGFuIHBlbmd1a3VyYW4gZGl0YW5kYWkgZGVuZ2FuIGFkYW55YSBuaWxhaSBSTVNFIHlhbmcga2VjaWwuIE1ldG9kZSBlc3RpbWFzaSB5YW5nIG1lbXB1bnlhaSBSb290IE1lYW4gU3F1YXJlIEVycm9yIChSTVNFKSBsZWJpaCBrZWNpbCBkaWthdGFrYW4gbGViaWggYWt1cmF0IGRhcmlwYWRhIG1ldG9kZSBlc3RpbWFzaSB5YW5nIG1lbXB1bnlhaSBSb290IE1lYW4gU3F1YXJlIEVycm9yIChSTVNFKSBsZWJpaCBiZXNhci4NCk5hbXVuIHVudHVrIGthbGkgaW5pIHlhbmcgZGlndW5ha2FuIHByZWRpa3NpIG5ldXJhbCBuZXR3b3JrIGJhY2twcm9wYWdhdHRpb24gc2FqYS4NCg0KPGJyPg0KPGJyPiA8aW1nIHNyYz0iaW1hZ2VzL3J1bXVzUk1TRS5wbmciIHN0eWxlPSJmbG9hdDogY2VudGVyOyBtYXJnaW46IC0xMHB4IDUwcHggMHB4IDUwcHg7IHdpZHRoOjUwJSIvPg0KPGJyPg0KS2V0ZXJhbmdhbiA6IDxicj4NCkF0ID0gTmlsYWkgZGF0YSBBa3R1YWwgIDxicj4NCkZ0ID0gTmlsYWkgaGFzaWwgcGVyYW1hbGFuICA8YnI+DQpOPSBiYW55YWtueWEgZGF0YSAgPGJyPg0K4oiRID0gU3VtbWF0aW9uIChKdW1sYWhrYW4ga2VzZWx1cnVoYW4gIG5pbGFpKSA8YnI+DQoNCmBgYHtyfQ0KZXJyb3JubiA9IHJtc2UoZGF0YV90ZXN0aW5nJG5pbGFpLCByZXN1bHRfbm4kbmV0LnJlc3VsdCkgDQplcnJvcm5uDQpgYGANCkRhcmkgaGFzaWwgUk1TRSB0aW5na2F0IGVycm9ybnlhIHN1ZGFoIHJlbmRhaCB5YWl0dSAuLi4uLiAgRGVuZ2FuIGVycm9yIHlhbmcgcmVuZGFoIGluaSBwcmVkaWtzaSBtZW1wdW55YWkgbmlsYWkgeWFuZyB0aW5nZ2kuIA0KPGJyPg0KDQojIDguIEtlc2ltcHVsYW4NCkRhcmkgaW1wbGVtZW50YXNpIHByZWRpa3NpIGRlbmdhbiBuZXVyYWxuZXR3b3JrIGJhY2twcm9wYWdhdGlvbiBkYW4gZXZhbHVhc2kgUk1TRSBkYXBhdCBkaXNpbXB1bGthbiA6PGJyPg0KMS4JQmFod2EgcmVuY2FuYSBrZXJqYXNhbWEgZGVuZ2FuIG1hcmtldHBsYWNlIHVudHVrIHR1anVhbiBES0kgSmFrYXJ0YSBkZW5nYSBTTEEgMCw5OCBuYW11biBoYXNpbCBwcmVkaWtzaSAuLi4uIG1hc2loIGphdWggZGFyaSBoYXJhcGFuLCBwZXJsdSBkaWxha3VrYW4gdXBheWEtdXBheWEgcGVyYmFpa2FuIG9wZXJhc2kuPGJyPg0KMi4JVHJhbnNha3NpIGRhbiBCZXJhdCBtZW1wdW55YWkgaW5kaWthdG9yIHNlYmFnYWkgaW5wdXQgeWFuZyBtZW1wZW5nYXJ1aGkgbmlsYWkgeWFuZyBhZGEuPGJyPg0KMy4JUk1TRSAwLDE0IHJlbGF0aWYgcmVuZGFoIG5hbXVuIHBlcmx1IGRpbGFrdWthbiB1amkgbGFnaSBkZW5nYW4gbWVtYmFuZGluZ2thbiBtZXRvZGUgbGFpbm55YSBtaXNhbCBkZW5nYW4gS05OIGF0YXUgTXVsdGlwbGUgTGluZWFyIFJlZ3JldGlvbg0KDQoNCg0KIyA5LiBSZWZlcmVuc2kNCg0KDQo=