ADS - Analisis Data Statistik

Albani

2024-03-03

Pendahuluan


Kontak
Name Albani
E-mail
LinkedIn Profil LinkedIn Al Bani
Rpubs Rpubs
IG Instagram

Sebelum mulai ada beberapa hal yang ingin saya sampaikan :

  • Ubah ADS halaman 1.3, 1.5, 1.6, 1.9, 120, 121 (tolong di coret)
  • Saya hanya mahasiswa biasa
  • Malam ini adalah tentang diskusi bersama bukan tentang siapa yang lebih jago.

WHAT ADS IS ??

Analisis data statistik adalah proses menyelidiki, menganalisis, dan menafsirkan data menggunakan berbagai teknik statistik untuk mendapatkan pemahaman yang lebih dalam tentang fenomena yang diamati. Tujuan utamanya adalah untuk mengidentifikasi pola, hubungan, dan tren yang tersembunyi dalam data, serta untuk membuat inferensi atau prediksi yang dapat digunakan untuk mengambil keputusan yang terinformasi.

Apa yang akan di pelajari pada BAB ini ??

  1. Menyusun angka
  2. Ringkasan data
  3. Penggunaan ringkasan data
  4. Transformasi data

Pertemuan selanjutnya :

  1. Sample Random dan Distribusi teoritis
  2. Uji hipotesis
  3. Regresi
  4. Analisis data kategorik
  5. Analsis Elementer dan analisis variansi dua arah

ADS PREPARATION

Apa yang harus di persiapkan untuk memulai ADS ?

Data dan Pengumpulannya

Sudah ada di materi metode pengumpulan data, apakah masih ingat ?? jika masih ingat mari diskusi..

1. Kapan kita menggunakan data primer dan data sekunder ??

2. Kenapa harus kita harus melakukan sampling ??

3. Apakah ada kumpulan data set untuk praktik (ada di materi modul 3)

Oh iya saya sudah menulis sedikit sekali tentang data, insyaallah akan di banyakin bisa cek dengan cara klik Disini.

ADS TOOLS

R dan aplikasi lainnya memang sangat penting, namun jangan pernah meninggalkan Excel ~ Rangga Pratama head of Starcore analytics
  1. EXCEL
Excel
Excel
  1. R & Py
R
R
  1. Lainnya

Buanyak bangett cari aja di Google

ADS

Sesi ini mengenai tentang data Cleaning and Data Preparation

Chank1
Chank1
  Perlu di ingat, eksplorasi data bukan sekedar tentang berapa rata-ratanya, berapa nilai tertinggi dan terendahnya !! tapi lebih dari itu yakni berkenalan lebih dalam tentang data.

Modul 1

Membahas tentang Menyusun angka.

Menyusunnya dalam bentuk angkatan (Batch) dan diagram batang dan daun.

Harapan dari modul kegiatan 1 adalah : mampu mengambil angka yang menjadi perhatian, menentukan unit unit analisis menyederhanakan dan mengurutkan

Harapan dari modul kegiatan 2 adalah : Menyajikan data serta mengambil sari informasi dari angka tersebut

saya sudah menyiapkan mini projek :

Perhatikan gambar berikut : Data set

Mini projek :

  • Jadikan dalam bentuk tabular (Bebas menggunakan aplikasi apapun)
  • Ambil sari Informasi (Buatlah dalam bentuk table)
  • Kerjakan dalam 10 Menit
  • kumpulkan filenya dengan cara Klik di sini

Modul 2

Membahas tentang Ringkasan Numerik.

Ringkasan numerik di bedakan menjadi 2 jenis :

  1. Pusat data, yang terdiri dari:
  • Mean

rata-rata = \(\frac{\sum{x_i}}{n}\)

Nilai pusat data, biasanya di gunakan seperti :

  • Rata-rata uang yang di hasilkan dalam 1 bulan adalah 271 Triliun
  • Rata-rata IPK mhs Statistik adalah 1.5

Perlu di ingat, rata rata ini hanya bisa di gunakan untuk data numerik atau kuantitatif. data kualitatif tidak bisa di hitung rata-ratanya. gak percaya? mari kita coba :

Jika dalam diskusi kali ini terdapat 15 orang L dan 9 orang P aturan matematika adalah kualitatif tidak bisa di lakukan operasi aritmatika.

sehingga kalau kita paksakan kita rubah dari L = 1 dan P = 2 maka kita bisa hitung :

rata-rata = \(\frac{\sum{(15*1)+(9*2)}}{15+9}= \frac{{33}}{24}=1.375\)

1.375 ini apa? sedangkan hanya ada 2 kategori L sm P, kan tidak mungkin setengah dewa.

  • Median

Median atau nilai tengah. cara menghitungnya :

  • Urutkan data: 3, 4, 5, 6, 7, 8, 9, 12.
  • Karena jumlah data (n) adalah genap (8), median adalah rata-rata dari dua nilai tengah, yaitu \(\frac{{(6 + 7)}} {2} = 6.5\).

Kapan di gunakan?

Mencari harga terbaik : contoh kita mau membeli rumah dengan harga yang fantastis karena lengkap dengan perabotan. Jika terdapat beberapa properti mewah dengan harga yang jauh lebih tinggi daripada properti lainnya, median harga rumah mungkin memberikan gambaran yang lebih baik tentang harga “tengah” di daerah tersebut daripada rata-rata harga rumah.

  • Trirata

Langkah-langkahnya:

  • Urutkan data: 2,5,7,10,13,17,18,20.

  • Tentukan posisi kuartil:

    n=jumlah data=8

    Q1=posisi data 25% * n Q2=posisi data 50% * n Q3=posisi data 75% * n

  • Tentukan nilai kuartil:

  • Q1=data ke 2=5

  • Q2=data ke 4=10

  • Q3=data ke 6=17

nilai Q1, Q2, dan Q3 memberikan wawasan yang berharga tentang sebaran, kecenderungan, dan karakteristik data, yang dapat membantu dalam pengambilan keputusan yang lebih baik dan pemahaman yang lebih baik tentang fenomena yang diamati.

  • Modus

Modusadalah nilai atau nilai-nilai yang paling sering muncul dalam sebuah distribusi data. Mengetahui modus membantu kita memahami nilai yang paling umum atau dominan dalam data tersebut.

rata-rata digunakan untuk memberikan gambaran tentang nilai pusat dari distribusi data, sementara modus digunakan untuk mengidentifikasi nilai yang paling umum atau dominan dalam data.

Contoh kasus untuk modus :

sebagai market research kita ingin mengetahui produk mana yang paling laku. bagaimana caranya? otomatis item yang paling banyak di beli bukan? ini linear dengan pengertian Modus

  1. Sebaran data, yang terdiri dari :
  • Range

Interfal data, dalam perusahaan biasa di tanya ini estimasi selesai di kerjakannya berapa lama? kita bisa menjawab di interfal 2-5 jam pak.

\(\int_{1}^{3}x\)

  • Variansi & Standar Deviasi

Variance : Nilai variance memberikan gambaran tentang seberapa besar variasi total dalam data. Namun, karena diukur dalam satuan kuadrat, nilai variance mungkin sulit diinterpretasikan secara intuitif.

Standar Deviasi : Standar deviasi memberikan ukuran dispersi yang lebih intuitif, karena diukur dalam satuan yang sama dengan data aslinya. Ini memberikan informasi tentang sejauh mana nilai-nilai individual bervariasi dari rata-rata dalam satuan yang dapat dimengerti.

  • Koefisien Varainsi

Ingat kembali salah satu rasio yang biasa digunakan dalam statistika yang berguna untuk melihat sebaran data dari rata-rata hitungnya. Rasio tersebut disebut sebagai koefisien variasi.

Formulanya adalah :

\(kv=\frac{{sd}}{mean}*100\)

Semakin kecil rasio koefisien variasi, maka kita bisa simpulkan bahwa data semakin homogen. Sementara sebaliknya, semakin besar nilai rasionya maka data akan semakin heterogen.

Modul 3

Membahas tentang Penggunaan ringkasan numerik

Contoh Case :

library(readr)
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(vtable)
## Warning: package 'vtable' was built under R version 4.3.3
## Loading required package: kableExtra
## Warning: package 'kableExtra' was built under R version 4.3.3
## 
## Attaching package: 'kableExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(pastecs)
## Warning: package 'pastecs' was built under R version 4.3.3
## 
## Attaching package: 'pastecs'
## 
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## 
## The following object is masked from 'package:tidyr':
## 
##     extract

Contoh kasus :

Kita punya client bertanya : "Mas saya punya data qty penjualan, mau cek mana ya yang lebih fluktuatif?"
#Membuat data set
set.seed(123)
ADS_dataset1 = rnorm(25, mean = 1000, sd = 100)
ADS_dataset2 = rnorm(25, mean = 150, sd = 100)

ADS = data.frame(ADS_dataset1, ADS_dataset2)
sumtable(ADS)
Summary Statistics
Variable N Mean Std. Dev. Min Pctl. 25 Pctl. 75 Max
ADS_dataset1 25 997 95 803 937 1046 1179
ADS_dataset2 25 160 92 -19 110 232 367

Fluktuatif artinya data lebih menyebar (tidak homogen). semakin fluktuatif artinya datanya tidak stabil.

dengan bantuan KF kita bisa melihat data mana yang tidak stabil.

stat.desc(ADS)
##              ADS_dataset1 ADS_dataset2
## nbr.val      2.500000e+01   25.0000000
## nbr.null     0.000000e+00    0.0000000
## nbr.na       0.000000e+00    0.0000000
## min          8.033383e+02  -18.6693311
## max          1.178691e+03  366.8955965
## range        3.753530e+02  385.5649276
## sum          2.491667e+04 4005.3434972
## median       9.782025e+02  143.8088289
## mean         9.966670e+02  160.2137399
## SE.mean      1.893465e+01   18.3774673
## CI.mean.0.95 3.907919e+01   37.9292283
## var          8.963022e+03 8443.2825782
## std.dev      9.467324e+01   91.8873363
## coef.var     9.498984e-02    0.5735297

Terlihat data di atas dataset1 lebih besar dari pada dataset2 sehingga dapat kita simpulkan bahwa data set1 lebih fluktuatif. Artinya dataset2 lebih homogen atau stabil.

Dengan menggunakan R kita bisa menghitung data dengan gampang pengguna Py minggir dulu.

TAMBAHAN

Membuat grafik as tableau

membuat Grafik mudah di R seperti proplayer degan menggunan package berikut.

library(esquisse)
#esquisser(data)

Data set dalam R

Untuk latihan data kumpulan data set yang di sediakan R bisa di cek dengan package berikut.

library(datasets)
data()

data(package = .packages(all.available = TRUE))

Modul 4

Transformasi data

Pendahuluan

Di hampir semua analisis statistik dan pembelajaran mesin, perlu dilakukan beberapa transformasi data (yaitu transformasi data, penskalaan, pemusatan, standardisasi, dan normalisasi) pada data mentah (namun rapi dan bersih!) sebelum dapat digunakan untuk pemodelan.

Pengertian Transformasi

Transformasi data sering kali merupakan syarat untuk melanjutkan analisis statistik. Berikut adalah situasi di mana kita mungkin memerlukan transformasi:

  1. Kita mungkin perlu mengubah skala suatu variabel atau menstandardisasi nilai suatu variabel untuk pemahaman yang lebih baik.

  2. Kita mungkin perlu mengubah hubungan non-linier yang kompleks menjadi hubungan linier. Transformasi membantu kita mengubah hubungan non-linier menjadi hubungan linier.

  3. Dalam inferensi statistik, distribusi simetris (normal) lebih disukai daripada distribusi miring. Selain itu, beberapa teknik analisis statistik (yaitu uji parametrik, regresi linier, dll) memerlukan distribusi variabel yang normal dan homogenitas varians. Jadi, setiap kali kita mempunyai distribusi yang miring dan/atau variansi yang heterogen, kita dapat menggunakan transformasi yang dapat mengurangi kecondongan dan/atau heterogenitas varians.

Macam-macam Transformasi

Macam macam transformasi ini di gunakan sesuai kebutuhan data set kita, karna beda kebutuhan beda juga jenis transdformasi yang umum di gunakan. Dalam konten ini akan hanya ada 3 contoh study case saja karena memang menurut saya jenis transformasi yang sering di gunakan adalah 3 itu saja.

  • Tansformasi Logaritmik

Menggunakan logaritma dari nilai-nilai data. Ini berguna untuk menangani data dengan skala yang sangat luas atau data yang memiliki distribusi miring ke satu arah.

  • Differencing

Mengambil perbedaan antara nilai-nilai data pada waktu yang berbeda untuk menghilangkan tren atau musiman dalam data temporal. nah ini biasa di pakai untuk memenuhi asumsi dalam pembuatan model time series

  • Transformasi Kuadrat

Menggunakan nilai kuadrat dari data. Transformasi ini dapat membantu dalam mengatasi masalah heteroskedastisitas, di mana varians data tidak konstan.

Heteroskedastisitas adalah istilah dalam statistika yang digunakan untuk menggambarkan ketidakseragaman varians dari residual (kesalahan) dalam sebuah model regresi atau analisis data.

Simpelnya heterogen dah itu..

  • Transformasi Akar Kuadrat

Menggunakan akar kuadrat dari nilai-nilai data. Ini sering digunakan untuk mengurangi kebuntuan dalam distribusi data.

kebuntuan yang di maksud adalahnilai-nilai dalam dataset cenderung terkumpul di salah satu sisi distribusi, sehingga distribusi data menjadi miring atau tidak simetris.  
  • Transformasi Box-Cox

Transformasi statistik yang dapat mengubah distribusi data menjadi lebih normal. Parameter lambda digunakan untuk menyesuaikan transformasi berdasarkan data. Box-Cox adalah alat yang berguna dalam analisis statistik untuk menormalkan distribusi data dan meningkatkan kecocokan model regresi atau analisis lainnya. Namun, penting untuk diingat bahwa transformasi ini tidak selalu berhasil untuk semua jenis data, dan terkadang beberapa variasi transformasi atau pendekatan alternatif mungkin diperlukan.

  • Standarisasi (Z-score Transformation)

Mengubah nilai-nilai data sehingga memiliki rata-rata nol dan simpangan baku satu. Ini berguna dalam membandingkan variabel yang diukur dalam unit yang berbeda atau memiliki skala yang besar.

  • Normalisasi (Min-Max Scaling)

Mengubah nilai-nilai data ke dalam rentang tertentu, seperti [0, 1] atau [-1, 1]. Ini memungkinkan data memiliki skala yang seragam.

  • Pengurutan Rangking (Rank Transformation)

Mengganti setiap nilai dalam dataset dengan peringkat atau rangking relatifnya dalam dataset. Ini berguna dalam mengatasi asimetri atau anomali dalam data.

  • Winsorization

Mengganti nilai-nilai outlier dengan nilai-nilai tertentu yang berada di kuartil tertentu dari distribusi data. Ini membantu mengurangi dampak outlier terhadap analisis statistik.

Study case

Study case ini isinya beberapa contoh yang sering kita dapatkan ketika dalam membuat model.

Persiapan

PACKAGE

library(tidyverse)
library(dplyr)
library(readr)
# library for data set
library(datasets)
library(boot)
library(agricolae)
## Warning: package 'agricolae' was built under R version 4.3.3
library(BSDA)
## Loading required package: lattice
## 
## Attaching package: 'lattice'
## The following object is masked from 'package:boot':
## 
##     melanoma
## 
## Attaching package: 'BSDA'
## The following object is masked from 'package:datasets':
## 
##     Orange

Data set

Mencari contoh data set dalam statistika bukanlah hal yang sulit, dengan R kita bisa mendapatkan ribuan data set. kita bisa menginstall package (datasets, ggplot2, lubridate, dplyr). cek di sub bab tambahan,

Let’s Go

Mari menggunakan contoh contoh untuk transformasi data, perlu di ingat konten ini tidak akan membahas semuanya, namun akan membahas yang umum dan akan sering kita pakai dalam kehidupan akhirat, eh maksudnya sehari hari.

Transformasi data dengan logaritma

y = log(x)

Begitulah fungsinya, namun perlu diingat, Yang perlu diperhatikan adalah bahwa transformasi logaritma hanya berlaku untuk nilai-nilai yang positif, karena logaritma dari nol atau nilai negatif tidak terdefinisi dalam matematika. Sebagai alternatif, Anda bisa menggunakan transformasi Box-Cox untuk menangani data yang berisi nilai nol atau negatif.

Transformasi logaritma kita gunakan ketika data kita berdistribusi berada di 1 arah, contohnya kiri atau kanan, contohnya sperti di bawah ini.

head(esoph,6)
##   agegp     alcgp    tobgp ncases ncontrols
## 1 25-34 0-39g/day 0-9g/day      0        40
## 2 25-34 0-39g/day    10-19      0        10
## 3 25-34 0-39g/day    20-29      0         6
## 4 25-34 0-39g/day      30+      0         5
## 5 25-34     40-79 0-9g/day      0        27
## 6 25-34     40-79    10-19      0         7
contohxx2 = esoph %>% 
  select(ncases, ncontrols)
# summary sebelum di tranformasi
summary(contohxx2)
##      ncases         ncontrols     
##  Min.   : 0.000   Min.   : 0.000  
##  1st Qu.: 0.000   1st Qu.: 1.000  
##  Median : 1.000   Median : 4.000  
##  Mean   : 2.273   Mean   : 8.807  
##  3rd Qu.: 4.000   3rd Qu.:10.000  
##  Max.   :17.000   Max.   :60.000
plot(contohxx2, pch =16, col = "darkgreen",  xlab ="ncases", ylab =  "ncontrols", main = "Sebelum di transformasi")
text(x=15, y=50, labels = "**hanya untuk contoh saja yak...**", pos =2,5, col = "red", cex = 0.9)

kelihatan kan plot di atas cenderung ke kiri, nah dengan transformation log, kita bisa membuatnya menjadi menyebar ketengah. Mari kita coba untuk lakukan transformasi.

log_transform = log(contohxx2, base =10)
plot(log_transform, pch =16, col = "darkred", main = "setelah di transformasi")

# Summary setelah di transformasi
summary(log_transform)
##      ncases         ncontrols     
##  Min.   :  -Inf   Min.   :  -Inf  
##  1st Qu.:  -Inf   1st Qu.:0.0000  
##  Median :0.0000   Median :0.6021  
##  Mean   :  -Inf   Mean   :  -Inf  
##  3rd Qu.:0.6021   3rd Qu.:1.0000  
##  Max.   :1.2304   Max.   :1.7782

Karena data yang di gunakan ada angka 0, sebenarnya Transformasi log tidak bisa di gunakan. jadi kita harus menggunakan transformasi Box-Cox.

Transformasi data dengan Diferencing

Transformasi ini banyak di gunakan untuk data yang akan digunakan untuk membuat model dalam analisis time series, transformasi ini di jalankan ketika data set yang kita punya tidak stasioner. penjelasan tentang stasioner akan dibahas di konten yang lain.

summary(ldeaths)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1300    1552    1870    2057    2552    3891
plot(ldeaths, main = "Contoh sebelum di transformasi")

karena di atas hanya contoh, bayangkan saja data di atas tidak stasioner. selanjutnya.

#data sebelum di Transformasi
head(ldeaths)
## [1] 3035 2552 2704 2554 2014 1655
diff_transformation = diff(ldeaths)
# data setelah di transformai
head(diff_transformation)
## [1] -483  152 -150 -540 -359   66
plot(diff_transformation, main = "plot setelah di transformasi")

nah begitulah caranya transformasi data di R, masalah penjelasan stasioiner akan di pelajari di time series.

LS0tDQp0aXRsZTogIkFEUyAtIEFuYWxpc2lzIERhdGEgU3RhdGlzdGlrIg0KYXV0aG9yOiAiQWxiYW5pIg0KZGF0ZTogIjIwMjQtMDMtMDMiDQpvdXRwdXQ6IA0KICAgcm1kZm9ybWF0czo6ZG93bmN1dGU6DQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICBsaWdodGJveDogdHJ1ZQ0KICAgIGRlZmF1bHRfc3R5bGU6ICJkYXJrIg0KICAgIGhpZ2hsaWdodDogTlVMTA0KICAgIGRvd25jdXRlX3RoZW1lOiAiY2hhb3MiDQogICAgdXNlX2Jvb2tkb3duOiBmYWxzZQ0KLS0tDQoNCiMgUGVuZGFodWx1YW4NCg0KKioqKg0KDQp8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8DQp8IDotLS0gICAgIHwgOi0tLSAgICAgICAgICAgICAgICB8DQp8ICoqS29udGFrKiogICB8ICAgICAgICAgICAgICAgICAgICB8DQp8IE5hbWUgICAgIHwgQWxiYW5pICAgICAgICAgICAgICB8DQp8IEUtbWFpbCAgIHwgYWwuYmFuaTEyMzAwQGdtYWlsLmNvbSAgIHwNCnwgTGlua2VkSW4gfCBbUHJvZmlsIExpbmtlZEluIEFsIEJhbmldKGh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9pbi9hbC1iYW5pLTUzMmIwNjI5NC8pIHwNCnwgUnB1YnMgICAgfCAgW1JwdWJzXShodHRwczovL3JwdWJzLmNvbS9hbGJhbmk4OCkgfA0KfCBJRyAgICAgICB8ICBbSW5zdGFncmFtXShodHRwczovL3d3dy5pbnN0YWdyYW0uY29tL2I0bi44OC8pIHwNCg0KKioqKg0KDQpTZWJlbHVtIG11bGFpIGFkYSBiZWJlcmFwYSBoYWwgeWFuZyBpbmdpbiBzYXlhIHNhbXBhaWthbiA6DQoNCi0gVWJhaCBBRFMgaGFsYW1hbiAxLjMsIDEuNSwgMS42LCAxLjksIDEyMCwgMTIxICAodG9sb25nIGRpIGNvcmV0KQ0KLSBTYXlhIGhhbnlhIG1haGFzaXN3YSBiaWFzYQ0KLSBNYWxhbSBpbmkgYWRhbGFoIHRlbnRhbmcgZGlza3VzaSBiZXJzYW1hIGJ1a2FuIHRlbnRhbmcgc2lhcGEgeWFuZyBsZWJpaCBqYWdvLg0KDQojIyBXSEFUIEFEUyBJUyA/Pw0KDQpBbmFsaXNpcyBkYXRhIHN0YXRpc3RpayBhZGFsYWggcHJvc2VzIG1lbnllbGlkaWtpLCBtZW5nYW5hbGlzaXMsIGRhbiBtZW5hZnNpcmthbiBkYXRhIG1lbmdndW5ha2FuIGJlcmJhZ2FpIHRla25payBzdGF0aXN0aWsgdW50dWsgbWVuZGFwYXRrYW4gcGVtYWhhbWFuIHlhbmcgbGViaWggZGFsYW0gdGVudGFuZyBmZW5vbWVuYSB5YW5nIGRpYW1hdGkuIFR1anVhbiB1dGFtYW55YSBhZGFsYWggdW50dWsgbWVuZ2lkZW50aWZpa2FzaSBwb2xhLCBodWJ1bmdhbiwgZGFuIHRyZW4geWFuZyB0ZXJzZW1idW55aSBkYWxhbSBkYXRhLCBzZXJ0YSB1bnR1ayBtZW1idWF0IGluZmVyZW5zaSBhdGF1IHByZWRpa3NpIHlhbmcgZGFwYXQgZGlndW5ha2FuIHVudHVrIG1lbmdhbWJpbCBrZXB1dHVzYW4geWFuZyB0ZXJpbmZvcm1hc2kuIA0KDQoNCkFwYSB5YW5nIGFrYW4gZGkgcGVsYWphcmkgcGFkYSBCQUIgaW5pID8/DQoNCjEuIE1lbnl1c3VuIGFuZ2thDQoyLiBSaW5na2FzYW4gZGF0YQ0KMy4gUGVuZ2d1bmFhbiByaW5na2FzYW4gZGF0YQ0KNC4gVHJhbnNmb3JtYXNpIGRhdGENCg0KUGVydGVtdWFuIHNlbGFuanV0bnlhIDoNCg0KNS4gU2FtcGxlIFJhbmRvbSBkYW4gRGlzdHJpYnVzaSB0ZW9yaXRpcw0KNi4gVWppIGhpcG90ZXNpcw0KNy4gUmVncmVzaQ0KOC4gQW5hbGlzaXMgZGF0YSBrYXRlZ29yaWsNCjkuIEFuYWxzaXMgRWxlbWVudGVyIGRhbiBhbmFsaXNpcyB2YXJpYW5zaSBkdWEgYXJhaA0KDQojIyBBRFMgUFJFUEFSQVRJT04NCg0KQXBhIHlhbmcgaGFydXMgZGkgcGVyc2lhcGthbiB1bnR1ayBtZW11bGFpIEFEUyA/DQoNCiMjIyBEYXRhIGRhbiBQZW5ndW1wdWxhbm55YQ0KDQoqU3VkYWggYWRhIGRpIG1hdGVyaSBtZXRvZGUgcGVuZ3VtcHVsYW4gZGF0YSwgYXBha2FoIG1hc2loIGluZ2F0ID8/Kg0KamlrYSBtYXNpaCBpbmdhdCBtYXJpIGRpc2t1c2kuLg0KDQoqKjEuIEthcGFuIGtpdGEgbWVuZ2d1bmFrYW4gZGF0YSBwcmltZXIgZGFuIGRhdGEgc2VrdW5kZXIgPz8qKg0KDQoqKjIuIEtlbmFwYSBoYXJ1cyBraXRhIGhhcnVzIG1lbGFrdWthbiBzYW1wbGluZyA/PyoqDQoNCioqMy4gQXBha2FoIGFkYSBrdW1wdWxhbiBkYXRhIHNldCB1bnR1ayBwcmFrdGlrIChhZGEgZGkgbWF0ZXJpIG1vZHVsIDMpKioNCg0KT2ggaXlhIHNheWEgc3VkYWggbWVudWxpcyBzZWRpa2l0IHNla2FsaSB0ZW50YW5nIGRhdGEsIGluc3lhYWxsYWggYWthbiBkaSBiYW55YWtpbiBiaXNhIGNlayBkZW5nYW4gY2FyYSBrbGlrIFtEaXNpbmldKGh0dHBzOi8vcnB1YnMuY29tL2FsYmFuaTg4KS4NCg0KIyMjIEFEUyBUT09MUw0KDQogICAgUiBkYW4gYXBsaWthc2kgbGFpbm55YSBtZW1hbmcgc2FuZ2F0IHBlbnRpbmcsIG5hbXVuIGphbmdhbiBwZXJuYWggbWVuaW5nZ2Fsa2FuIEV4Y2VsIH4gUmFuZ2dhIFByYXRhbWEgaGVhZCBvZiBTdGFyY29yZSBhbmFseXRpY3MNCg0KMS4gRVhDRUwNCg0KIVtFeGNlbF0oaHR0cHM6Ly9xcGguY2YyLnF1b3JhY2RuLm5ldC9tYWluLXFpbWctNWYzY2RhZjMwZmVjYzk1YmNiM2FmNmMwMDU1ZGFjNmQtbHEpDQoNCjIuIFIgJiBQeQ0KDQohW1JdKGh0dHBzOi8vZGliaW1iaW5nLWNkbi5zZ3AxLmNkbi5kaWdpdGFsb2NlYW5zcGFjZXMuY29tLzE2NjQ3NjkyOTEwODctMV9kLUsxOVJWZEdUbDVfZnFNUmNGWGp3LmpwZWcud2VicCkNCg0KMy4gTGFpbm55YQ0KDQpCdWFueWFrIGJhbmdldHQgY2FyaSBhamEgZGkgW0dvb2dsZV0od3d3Lmdvb2dsZS5jb20pDQoNCiMgQURTDQoNClNlc2kgaW5pIG1lbmdlbmFpIHRlbnRhbmcgZGF0YSBDbGVhbmluZyBhbmQgRGF0YSBQcmVwYXJhdGlvbg0KDQohW0NoYW5rMV0oaHR0cHM6Ly9naXRodWIuY29tL2I0bjg4L1BST0pFSy1TdGF0aXN0aWthZGFzYXIvYmxvYi9tYWluL3VubmFtZWQtY2h1bmstMS0xKDEpLnBuZz9yYXc9dHJ1ZSkNCg0KICAgICAgUGVybHUgZGkgaW5nYXQsIGVrc3Bsb3Jhc2kgZGF0YSBidWthbiBzZWtlZGFyIHRlbnRhbmcgYmVyYXBhIHJhdGEtcmF0YW55YSwgYmVyYXBhIG5pbGFpIHRlcnRpbmdnaSBkYW4gdGVyZW5kYWhueWEgISEgdGFwaSBsZWJpaCBkYXJpIGl0dSB5YWtuaSBiZXJrZW5hbGFuIGxlYmloIGRhbGFtIHRlbnRhbmcgZGF0YS4NCg0KIyBNb2R1bCAxIA0KDQoqTWVtYmFoYXMgdGVudGFuZyBNZW55dXN1biBhbmdrYSouDQoNCk1lbnl1c3VubnlhIGRhbGFtIGJlbnR1ayBhbmdrYXRhbiAoQmF0Y2gpIGRhbiBkaWFncmFtIGJhdGFuZyBkYW4gZGF1bi4NCg0KSGFyYXBhbiBkYXJpIG1vZHVsIGtlZ2lhdGFuIDEgYWRhbGFoIDogKiptYW1wdSBtZW5nYW1iaWwgYW5na2EgeWFuZyBtZW5qYWRpIHBlcmhhdGlhbiwgbWVuZW50dWthbiB1bml0IHVuaXQgYW5hbGlzaXMgbWVueWVkZXJoYW5ha2FuIGRhbiBtZW5ndXJ1dGthbioqIA0KDQpIYXJhcGFuIGRhcmkgbW9kdWwga2VnaWF0YW4gMiBhZGFsYWggOiAqKk1lbnlhamlrYW4gZGF0YSBzZXJ0YSBtZW5nYW1iaWwgc2FyaSBpbmZvcm1hc2kgZGFyaSBhbmdrYSB0ZXJzZWJ1dCoqDQoNCnNheWEgc3VkYWggbWVueWlhcGthbiBtaW5pIHByb2playA6DQoNClBlcmhhdGlrYW4gZ2FtYmFyIGJlcmlrdXQgOg0KIVtEYXRhIHNldF0oaHR0cHM6Ly9naXRodWIuY29tL2I0bjg4L1BST0pFSy1TdGF0aXN0aWthZGFzYXIvYmxvYi9tYWluL0RhdGElMjBtaW5pJTIwcHJvamVrLmpwZz9yYXc9dHJ1ZSkNCg0KTWluaSBwcm9qZWsgOg0KDQotIEphZGlrYW4gZGFsYW0gYmVudHVrIHRhYnVsYXIgKEJlYmFzIG1lbmdndW5ha2FuIGFwbGlrYXNpIGFwYXB1bikNCi0gQW1iaWwgc2FyaSBJbmZvcm1hc2kgKEJ1YXRsYWggZGFsYW0gYmVudHVrIHRhYmxlKQ0KLSBLZXJqYWthbiBkYWxhbSAxMCBNZW5pdA0KLSBrdW1wdWxrYW4gZmlsZW55YSBkZW5nYW4gY2FyYSBbS2xpayBkaSBzaW5pXShodHRwczovL2Zvcm1zLmdsZS9UTFVmOW1BRHZ0S2lzM0w5OCkNCg0KIyBNb2R1bCAyDQoNCipNZW1iYWhhcyB0ZW50YW5nIFJpbmdrYXNhbiBOdW1lcmlrKi4NCg0KUmluZ2thc2FuIG51bWVyaWsgZGkgYmVkYWthbiBtZW5qYWRpIDIgamVuaXMgOg0KDQphLiBQdXNhdCBkYXRhLCB5YW5nIHRlcmRpcmkgZGFyaToNCg0KLSBNZWFuDQoNCnJhdGEtcmF0YSA9ICRcZnJhY3tcc3Vte3hfaX19e259JA0KDQpOaWxhaSBwdXNhdCBkYXRhLCBiaWFzYW55YSBkaSBndW5ha2FuIHNlcGVydGkgOg0KDQotIFJhdGEtcmF0YSB1YW5nIHlhbmcgZGkgaGFzaWxrYW4gZGFsYW0gMSBidWxhbiBhZGFsYWggYDI3MSBUcmlsaXVuYA0KLSBSYXRhLXJhdGEgSVBLIG1ocyBTdGF0aXN0aWsgYWRhbGFoIDEuNQ0KDQpQZXJsdSBkaSBpbmdhdCwgcmF0YSByYXRhIGluaSBoYW55YSBiaXNhIGRpIGd1bmFrYW4gdW50dWsgZGF0YSBudW1lcmlrIGF0YXUga3VhbnRpdGF0aWYuIGRhdGEga3VhbGl0YXRpZiB0aWRhayBiaXNhIGRpIGhpdHVuZyByYXRhLXJhdGFueWEuIGdhayBwZXJjYXlhPyBtYXJpIGtpdGEgY29iYSA6DQoNCkppa2EgZGFsYW0gZGlza3VzaSBrYWxpIGluaSB0ZXJkYXBhdCAxNSBvcmFuZyBgTGAgZGFuIDkgb3JhbmcgYFBgIGF0dXJhbiBtYXRlbWF0aWthIGFkYWxhaCBrdWFsaXRhdGlmIHRpZGFrIGJpc2EgZGkgbGFrdWthbiBvcGVyYXNpIGFyaXRtYXRpa2EuIA0KDQpzZWhpbmdnYSBrYWxhdSBraXRhIHBha3Nha2FuIGtpdGEgcnViYWggZGFyaSBgTCA9IDFgIGRhbiBgUCA9IDJgIG1ha2Ega2l0YSBiaXNhIGhpdHVuZyA6DQoNCnJhdGEtcmF0YSA9ICRcZnJhY3tcc3VteygxNSoxKSsoOSoyKX19ezE1Kzl9PSBcZnJhY3t7MzN9fXsyNH09MS4zNzUkDQoNCmAxLjM3NWAgaW5pIGFwYT8gc2VkYW5na2FuIGhhbnlhIGFkYSAyIGthdGVnb3JpIGBMYCBzbSBgUGAsIGthbiB0aWRhayBtdW5na2luIHNldGVuZ2FoIGRld2EuDQoNCi0gTWVkaWFuDQoNCk1lZGlhbiBhdGF1IG5pbGFpIHRlbmdhaC4gY2FyYSBtZW5naGl0dW5nbnlhIDoNCg0KLSBVcnV0a2FuIGRhdGE6IDMsIDQsIDUsIDYsIDcsIDgsIDksIDEyLg0KLSBLYXJlbmEganVtbGFoIGRhdGEgKG4pIGFkYWxhaCBnZW5hcCAoOCksIG1lZGlhbiBhZGFsYWggcmF0YS1yYXRhIGRhcmkgZHVhIG5pbGFpIHRlbmdhaCwgeWFpdHUgJFxmcmFje3soNiArIDcpfX0gezJ9ID0gNi41JC4NCg0KS2FwYW4gZGkgZ3VuYWthbj8NCg0KTWVuY2FyaSBoYXJnYSB0ZXJiYWlrIDogY29udG9oIGtpdGEgbWF1IG1lbWJlbGkgcnVtYWggZGVuZ2FuIGhhcmdhIHlhbmcgZmFudGFzdGlzIGthcmVuYSBsZW5na2FwIGRlbmdhbiBwZXJhYm90YW4uIEppa2EgdGVyZGFwYXQgYmViZXJhcGEgcHJvcGVydGkgbWV3YWggZGVuZ2FuIGhhcmdhIHlhbmcgamF1aCBsZWJpaCB0aW5nZ2kgZGFyaXBhZGEgcHJvcGVydGkgbGFpbm55YSwgbWVkaWFuIGhhcmdhIHJ1bWFoIG11bmdraW4gbWVtYmVyaWthbiBnYW1iYXJhbiB5YW5nIGxlYmloIGJhaWsgdGVudGFuZyBoYXJnYSAidGVuZ2FoIiBkaSBkYWVyYWggdGVyc2VidXQgZGFyaXBhZGEgcmF0YS1yYXRhIGhhcmdhIHJ1bWFoLg0KDQotIFRyaXJhdGENCg0KTGFuZ2thaC1sYW5na2FobnlhOg0KDQotIFVydXRrYW4gZGF0YTogMiw1LDcsMTAsMTMsMTcsMTgsMjAuDQoNCi0gVGVudHVrYW4gcG9zaXNpIGt1YXJ0aWw6DQogIA0KICBuPWp1bWxhaCBkYXRhPTgNCiAgDQogIFExPXBvc2lzaSBkYXRhIGAyNSUgKiBuYA0KICBRMj1wb3Npc2kgZGF0YSBgNTAlICogbmANCiAgUTM9cG9zaXNpIGRhdGEgYDc1JSAqIG5gDQoNCi0gVGVudHVrYW4gbmlsYWkga3VhcnRpbDoNCg0KLSBRMT1kYXRhIGtlIDI9NQ0KLSBRMj1kYXRhIGtlIDQ9MTANCi0gUTM9ZGF0YSBrZSA2PTE3DQoNCm5pbGFpIFExLCBRMiwgZGFuIFEzIG1lbWJlcmlrYW4gd2F3YXNhbiB5YW5nIGJlcmhhcmdhIHRlbnRhbmcgc2ViYXJhbiwga2VjZW5kZXJ1bmdhbiwgZGFuIGthcmFrdGVyaXN0aWsgZGF0YSwgeWFuZyBkYXBhdCBtZW1iYW50dSBkYWxhbSBwZW5nYW1iaWxhbiBrZXB1dHVzYW4geWFuZyBsZWJpaCBiYWlrIGRhbiBwZW1haGFtYW4geWFuZyBsZWJpaCBiYWlrIHRlbnRhbmcgZmVub21lbmEgeWFuZyBkaWFtYXRpLg0KDQotIE1vZHVzDQoNCk1vZHVzYWRhbGFoIG5pbGFpIGF0YXUgbmlsYWktbmlsYWkgeWFuZyBwYWxpbmcgc2VyaW5nIG11bmN1bCBkYWxhbSBzZWJ1YWggZGlzdHJpYnVzaSBkYXRhLiBNZW5nZXRhaHVpIG1vZHVzIG1lbWJhbnR1IGtpdGEgbWVtYWhhbWkgbmlsYWkgeWFuZyBwYWxpbmcgdW11bSBhdGF1IGRvbWluYW4gZGFsYW0gZGF0YSB0ZXJzZWJ1dC4NCg0KcmF0YS1yYXRhIGRpZ3VuYWthbiB1bnR1ayBtZW1iZXJpa2FuIGdhbWJhcmFuIHRlbnRhbmcgbmlsYWkgcHVzYXQgZGFyaSBkaXN0cmlidXNpIGRhdGEsIHNlbWVudGFyYSBtb2R1cyBkaWd1bmFrYW4gdW50dWsgbWVuZ2lkZW50aWZpa2FzaSBuaWxhaSB5YW5nIHBhbGluZyB1bXVtIGF0YXUgZG9taW5hbiBkYWxhbSBkYXRhLiANCg0KQ29udG9oIGthc3VzIHVudHVrIG1vZHVzIDoNCg0Kc2ViYWdhaSBtYXJrZXQgcmVzZWFyY2gga2l0YSBpbmdpbiBtZW5nZXRhaHVpIHByb2R1ayBtYW5hIHlhbmcgcGFsaW5nIGxha3UuIGJhZ2FpbWFuYSBjYXJhbnlhPyBvdG9tYXRpcyBpdGVtIHlhbmcgcGFsaW5nIGJhbnlhayBkaSBiZWxpIGJ1a2FuPyBpbmkgbGluZWFyIGRlbmdhbiBwZW5nZXJ0aWFuIE1vZHVzDQoNCmIuIFNlYmFyYW4gZGF0YSwgeWFuZyB0ZXJkaXJpIGRhcmkgOg0KDQotIFJhbmdlDQoNCkludGVyZmFsIGRhdGEsIGRhbGFtIHBlcnVzYWhhYW4gYmlhc2EgZGkgdGFueWEgaW5pIGVzdGltYXNpIHNlbGVzYWkgZGkga2VyamFrYW5ueWEgYmVyYXBhIGxhbWE/IGtpdGEgYmlzYSBtZW5qYXdhYiBkaSBpbnRlcmZhbCAyLTUgamFtIHBhay4NCg0KJFxpbnRfezF9XnszfXgkDQoNCi0gVmFyaWFuc2kgJiBTdGFuZGFyIERldmlhc2kNCg0KVmFyaWFuY2UgICAgICAgICAgOiBOaWxhaSB2YXJpYW5jZSBtZW1iZXJpa2FuIGdhbWJhcmFuIHRlbnRhbmcgc2ViZXJhcGEgYmVzYXIgdmFyaWFzaSB0b3RhbCBkYWxhbSBkYXRhLiBOYW11biwga2FyZW5hIGRpdWt1ciBkYWxhbSBzYXR1YW4ga3VhZHJhdCwgbmlsYWkgdmFyaWFuY2UgbXVuZ2tpbiBzdWxpdCBkaWludGVycHJldGFzaWthbiBzZWNhcmEgaW50dWl0aWYuIA0KDQpTdGFuZGFyIERldmlhc2kgICA6IFN0YW5kYXIgZGV2aWFzaSBtZW1iZXJpa2FuIHVrdXJhbiBkaXNwZXJzaSB5YW5nIGxlYmloIGludHVpdGlmLCBrYXJlbmEgZGl1a3VyIGRhbGFtIHNhdHVhbiB5YW5nIHNhbWEgZGVuZ2FuIGRhdGEgYXNsaW55YS4gSW5pIG1lbWJlcmlrYW4gaW5mb3JtYXNpIHRlbnRhbmcgc2VqYXVoIG1hbmEgbmlsYWktbmlsYWkgaW5kaXZpZHVhbCBiZXJ2YXJpYXNpIGRhcmkgcmF0YS1yYXRhIGRhbGFtIHNhdHVhbiB5YW5nIGRhcGF0IGRpbWVuZ2VydGkuIA0KDQotIEtvZWZpc2llbiBWYXJhaW5zaQ0KDQpJbmdhdCBrZW1iYWxpIHNhbGFoIHNhdHUgcmFzaW8geWFuZyBiaWFzYSBkaWd1bmFrYW4gZGFsYW0gc3RhdGlzdGlrYSB5YW5nIGJlcmd1bmEgdW50dWsgbWVsaWhhdCBzZWJhcmFuIGRhdGEgZGFyaSByYXRhLXJhdGEgaGl0dW5nbnlhLiBSYXNpbyB0ZXJzZWJ1dCBkaXNlYnV0IHNlYmFnYWkga29lZmlzaWVuIHZhcmlhc2kuIA0KDQpGb3JtdWxhbnlhIGFkYWxhaCA6DQoNCiRrdj1cZnJhY3t7c2R9fXttZWFufSoxMDAkDQoNClNlbWFraW4ga2VjaWwgcmFzaW8ga29lZmlzaWVuIHZhcmlhc2ksIG1ha2Ega2l0YSBiaXNhIHNpbXB1bGthbiBiYWh3YSBkYXRhIHNlbWFraW4gaG9tb2dlbi4gU2VtZW50YXJhIHNlYmFsaWtueWEsIHNlbWFraW4gYmVzYXIgbmlsYWkgcmFzaW9ueWEgbWFrYSBkYXRhIGFrYW4gc2VtYWtpbiBoZXRlcm9nZW4uIA0KDQoNCiMgTW9kdWwgMw0KDQoqTWVtYmFoYXMgdGVudGFuZyBQZW5nZ3VuYWFuIHJpbmdrYXNhbiBudW1lcmlrKg0KDQpDb250b2ggQ2FzZSA6DQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodnRhYmxlKQ0KbGlicmFyeShwYXN0ZWNzKQ0KYGBgDQoNCkNvbnRvaCBrYXN1cyA6DQoNCiAgICBLaXRhIHB1bnlhIGNsaWVudCBiZXJ0YW55YSA6ICJNYXMgc2F5YSBwdW55YSBkYXRhIHF0eSBwZW5qdWFsYW4sIG1hdSBjZWsgbWFuYSB5YSB5YW5nIGxlYmloIGZsdWt0dWF0aWY/Ig0KDQpgYGB7cn0NCiNNZW1idWF0IGRhdGEgc2V0DQpzZXQuc2VlZCgxMjMpDQpBRFNfZGF0YXNldDEgPSBybm9ybSgyNSwgbWVhbiA9IDEwMDAsIHNkID0gMTAwKQ0KQURTX2RhdGFzZXQyID0gcm5vcm0oMjUsIG1lYW4gPSAxNTAsIHNkID0gMTAwKQ0KDQpBRFMgPSBkYXRhLmZyYW1lKEFEU19kYXRhc2V0MSwgQURTX2RhdGFzZXQyKQ0Kc3VtdGFibGUoQURTKQ0KYGBgDQoNCkZsdWt0dWF0aWYgYXJ0aW55YSBkYXRhIGxlYmloIG1lbnllYmFyICh0aWRhayBob21vZ2VuKS4gc2VtYWtpbiBmbHVrdHVhdGlmIGFydGlueWEgZGF0YW55YSB0aWRhayBzdGFiaWwuDQoNCmRlbmdhbiBiYW50dWFuIEtGIGtpdGEgYmlzYSBtZWxpaGF0IGRhdGEgbWFuYSB5YW5nIHRpZGFrIHN0YWJpbC4NCg0KYGBge3J9DQpzdGF0LmRlc2MoQURTKQ0KYGBgDQoNClRlcmxpaGF0IGRhdGEgZGkgYXRhcyBgZGF0YXNldDFgIGxlYmloIGJlc2FyIGRhcmkgcGFkYSBgZGF0YXNldDJgIHNlaGluZ2dhIGRhcGF0IGtpdGEgc2ltcHVsa2FuIGJhaHdhIGBkYXRhIHNldDFgIGxlYmloIGBmbHVrdHVhdGlmYC4gQXJ0aW55YSBgZGF0YXNldDJgIGxlYmloIGBob21vZ2VuYCBhdGF1IGBzdGFiaWxgLg0KDQoqRGVuZ2FuIG1lbmdndW5ha2FuIFIga2l0YSBiaXNhIG1lbmdoaXR1bmcgZGF0YSBkZW5nYW4gZ2FtcGFuZyogcGVuZ2d1bmEgUHkgbWluZ2dpciBkdWx1Lg0KDQojIFRBTUJBSEFODQoNCiMjIE1lbWJ1YXQgZ3JhZmlrIGFzIHRhYmxlYXUNCg0KbWVtYnVhdCBHcmFmaWsgbXVkYWggZGkgUiBzZXBlcnRpIHByb3BsYXllciBkZWdhbiBtZW5nZ3VuYW4gcGFja2FnZSBiZXJpa3V0Lg0KDQpgYGB7cn0NCmxpYnJhcnkoZXNxdWlzc2UpDQojZXNxdWlzc2VyKGRhdGEpDQpgYGANCg0KDQojIyBEYXRhIHNldCBkYWxhbSBSDQoNClVudHVrIGxhdGloYW4gZGF0YSBrdW1wdWxhbiBkYXRhIHNldCB5YW5nIGRpIHNlZGlha2FuIFIgYmlzYSBkaSBjZWsgZGVuZ2FuIHBhY2thZ2UgYmVyaWt1dC4NCg0KYGBge3J9DQpsaWJyYXJ5KGRhdGFzZXRzKQ0KZGF0YSgpDQoNCmRhdGEocGFja2FnZSA9IC5wYWNrYWdlcyhhbGwuYXZhaWxhYmxlID0gVFJVRSkpDQpgYGANCg0KDQojIE1vZHVsIDQNCg0KKlRyYW5zZm9ybWFzaSBkYXRhKg0KDQojIyBQZW5kYWh1bHVhbg0KDQpEaSBoYW1waXIgc2VtdWEgYW5hbGlzaXMgc3RhdGlzdGlrIGRhbiBwZW1iZWxhamFyYW4gbWVzaW4sIHBlcmx1IGRpbGFrdWthbiBiZWJlcmFwYSB0cmFuc2Zvcm1hc2kgZGF0YSAoeWFpdHUgdHJhbnNmb3JtYXNpIGRhdGEsIHBlbnNrYWxhYW4sIHBlbXVzYXRhbiwgc3RhbmRhcmRpc2FzaSwgZGFuIG5vcm1hbGlzYXNpKSBwYWRhIGRhdGEgbWVudGFoIChuYW11biByYXBpIGRhbiBiZXJzaWghKSBzZWJlbHVtIGRhcGF0IGRpZ3VuYWthbiB1bnR1ayBwZW1vZGVsYW4uDQoNCiMjIyBQZW5nZXJ0aWFuICBUcmFuc2Zvcm1hc2kNCg0KVHJhbnNmb3JtYXNpIGRhdGEgc2VyaW5nIGthbGkgbWVydXBha2FuIHN5YXJhdCB1bnR1ayBtZWxhbmp1dGthbiBhbmFsaXNpcyBzdGF0aXN0aWsuIEJlcmlrdXQgYWRhbGFoIHNpdHVhc2kgZGkgbWFuYSBraXRhIG11bmdraW4gbWVtZXJsdWthbiB0cmFuc2Zvcm1hc2k6DQoNCjEuIEtpdGEgbXVuZ2tpbiBwZXJsdSBtZW5ndWJhaCBza2FsYSBzdWF0dSB2YXJpYWJlbCBhdGF1IG1lbnN0YW5kYXJkaXNhc2kgbmlsYWkgc3VhdHUgdmFyaWFiZWwgdW50dWsgcGVtYWhhbWFuIHlhbmcgbGViaWggYmFpay4NCg0KMi4gS2l0YSBtdW5na2luIHBlcmx1IG1lbmd1YmFoIGh1YnVuZ2FuIG5vbi1saW5pZXIgeWFuZyBrb21wbGVrcyBtZW5qYWRpIGh1YnVuZ2FuIGxpbmllci4gVHJhbnNmb3JtYXNpIG1lbWJhbnR1IGtpdGEgbWVuZ3ViYWggaHVidW5nYW4gbm9uLWxpbmllciBtZW5qYWRpIGh1YnVuZ2FuIGxpbmllci4NCg0KMy4gRGFsYW0gaW5mZXJlbnNpIHN0YXRpc3RpaywgZGlzdHJpYnVzaSBzaW1ldHJpcyAobm9ybWFsKSBsZWJpaCBkaXN1a2FpIGRhcmlwYWRhIGRpc3RyaWJ1c2kgbWlyaW5nLiBTZWxhaW4gaXR1LCBiZWJlcmFwYSB0ZWtuaWsgYW5hbGlzaXMgc3RhdGlzdGlrICh5YWl0dSB1amkgcGFyYW1ldHJpaywgcmVncmVzaSBsaW5pZXIsIGRsbCkgbWVtZXJsdWthbiBkaXN0cmlidXNpIHZhcmlhYmVsIHlhbmcgbm9ybWFsIGRhbiBob21vZ2VuaXRhcyB2YXJpYW5zLiBKYWRpLCBzZXRpYXAga2FsaSBraXRhIG1lbXB1bnlhaSBkaXN0cmlidXNpIHlhbmcgbWlyaW5nIGRhbi9hdGF1IHZhcmlhbnNpIHlhbmcgaGV0ZXJvZ2VuLCBraXRhIGRhcGF0IG1lbmdndW5ha2FuIHRyYW5zZm9ybWFzaSB5YW5nIGRhcGF0IG1lbmd1cmFuZ2kga2Vjb25kb25nYW4gZGFuL2F0YXUgaGV0ZXJvZ2VuaXRhcyB2YXJpYW5zLg0KDQojIyMgTWFjYW0tbWFjYW0gVHJhbnNmb3JtYXNpDQoNCk1hY2FtIG1hY2FtIHRyYW5zZm9ybWFzaSBpbmkgZGkgZ3VuYWthbiBzZXN1YWkga2VidXR1aGFuIGRhdGEgc2V0IGtpdGEsIGthcm5hIGJlZGEga2VidXR1aGFuIGJlZGEganVnYSBqZW5pcyB0cmFuc2Rmb3JtYXNpIHlhbmcgdW11bSBkaSBndW5ha2FuLiBEYWxhbSBrb250ZW4gaW5pIGFrYW4gaGFueWEgYWRhIDMgY29udG9oIHN0dWR5IGNhc2Ugc2FqYSBrYXJlbmEgbWVtYW5nIG1lbnVydXQgc2F5YSBqZW5pcyB0cmFuc2Zvcm1hc2kgeWFuZyBzZXJpbmcgZGkgZ3VuYWthbiBhZGFsYWggMyBpdHUgc2FqYS4NCg0KLSAqKlRhbnNmb3JtYXNpIExvZ2FyaXRtaWsqKg0KDQpNZW5nZ3VuYWthbiBsb2dhcml0bWEgZGFyaSBuaWxhaS1uaWxhaSBkYXRhLiBJbmkgYmVyZ3VuYSB1bnR1ayBtZW5hbmdhbmkgZGF0YSBkZW5nYW4gc2thbGEgeWFuZyBzYW5nYXQgbHVhcyBhdGF1IGRhdGEgeWFuZyBtZW1pbGlraSBkaXN0cmlidXNpIG1pcmluZyBrZSBzYXR1IGFyYWguIA0KDQotICoqRGlmZmVyZW5jaW5nKioNCg0KTWVuZ2FtYmlsIHBlcmJlZGFhbiBhbnRhcmEgbmlsYWktbmlsYWkgZGF0YSBwYWRhIHdha3R1IHlhbmcgYmVyYmVkYSB1bnR1ayBtZW5naGlsYW5na2FuIHRyZW4gYXRhdSBtdXNpbWFuIGRhbGFtIGRhdGEgdGVtcG9yYWwuIG5haCBpbmkgYmlhc2EgZGkgcGFrYWkgdW50dWsgbWVtZW51aGkgYXN1bXNpIGRhbGFtIHBlbWJ1YXRhbiBtb2RlbCBgdGltZSBzZXJpZXNgDQoNCi0gKipUcmFuc2Zvcm1hc2kgS3VhZHJhdCoqDQoNCk1lbmdndW5ha2FuIG5pbGFpIGt1YWRyYXQgZGFyaSBkYXRhLiBUcmFuc2Zvcm1hc2kgaW5pIGRhcGF0IG1lbWJhbnR1IGRhbGFtIG1lbmdhdGFzaSBtYXNhbGFoIGhldGVyb3NrZWRhc3Rpc2l0YXMsIGRpIG1hbmEgdmFyaWFucyBkYXRhIHRpZGFrIGtvbnN0YW4uIA0KDQogICAgSGV0ZXJvc2tlZGFzdGlzaXRhcyBhZGFsYWggaXN0aWxhaCBkYWxhbSBzdGF0aXN0aWthIHlhbmcgZGlndW5ha2FuIHVudHVrIG1lbmdnYW1iYXJrYW4ga2V0aWRha3NlcmFnYW1hbiB2YXJpYW5zIGRhcmkgcmVzaWR1YWwgKGtlc2FsYWhhbikgZGFsYW0gc2VidWFoIG1vZGVsIHJlZ3Jlc2kgYXRhdSBhbmFsaXNpcyBkYXRhLg0KICAgIA0KU2ltcGVsbnlhIGhldGVyb2dlbiBkYWggaXR1Li4gDQoNCi0gKipUcmFuc2Zvcm1hc2kgQWthciBLdWFkcmF0KioNCg0KTWVuZ2d1bmFrYW4gYWthciBrdWFkcmF0IGRhcmkgbmlsYWktbmlsYWkgZGF0YS4gSW5pIHNlcmluZyBkaWd1bmFrYW4gdW50dWsgbWVuZ3VyYW5naSBrZWJ1bnR1YW4gZGFsYW0gZGlzdHJpYnVzaSBkYXRhLiANCg0KICAgIGtlYnVudHVhbiB5YW5nIGRpIG1ha3N1ZCBhZGFsYWhuaWxhaS1uaWxhaSBkYWxhbSBkYXRhc2V0IGNlbmRlcnVuZyB0ZXJrdW1wdWwgZGkgc2FsYWggc2F0dSBzaXNpIGRpc3RyaWJ1c2ksIHNlaGluZ2dhIGRpc3RyaWJ1c2kgZGF0YSBtZW5qYWRpIG1pcmluZyBhdGF1IHRpZGFrIHNpbWV0cmlzLiAgDQoNCi0gKipUcmFuc2Zvcm1hc2kgQm94LUNveCoqDQoNCiBUcmFuc2Zvcm1hc2kgc3RhdGlzdGlrIHlhbmcgZGFwYXQgbWVuZ3ViYWggZGlzdHJpYnVzaSBkYXRhIG1lbmphZGkgbGViaWggbm9ybWFsLiBQYXJhbWV0ZXIgbGFtYmRhIGRpZ3VuYWthbiB1bnR1ayBtZW55ZXN1YWlrYW4gdHJhbnNmb3JtYXNpIGJlcmRhc2Fya2FuIGRhdGEuIEJveC1Db3ggYWRhbGFoIGFsYXQgeWFuZyBiZXJndW5hIGRhbGFtIGFuYWxpc2lzIHN0YXRpc3RpayB1bnR1ayBtZW5vcm1hbGthbiBkaXN0cmlidXNpIGRhdGEgZGFuIG1lbmluZ2thdGthbiBrZWNvY29rYW4gbW9kZWwgcmVncmVzaSBhdGF1IGFuYWxpc2lzIGxhaW5ueWEuIE5hbXVuLCBwZW50aW5nIHVudHVrIGRpaW5nYXQgYmFod2EgdHJhbnNmb3JtYXNpIGluaSB0aWRhayBzZWxhbHUgYmVyaGFzaWwgdW50dWsgc2VtdWEgamVuaXMgZGF0YSwgZGFuIHRlcmthZGFuZyBiZWJlcmFwYSB2YXJpYXNpIHRyYW5zZm9ybWFzaSBhdGF1IHBlbmRla2F0YW4gYWx0ZXJuYXRpZiBtdW5na2luIGRpcGVybHVrYW4uIA0KDQotICoqU3RhbmRhcmlzYXNpIChaLXNjb3JlIFRyYW5zZm9ybWF0aW9uKSoqDQoNCk1lbmd1YmFoIG5pbGFpLW5pbGFpIGRhdGEgc2VoaW5nZ2EgbWVtaWxpa2kgcmF0YS1yYXRhIG5vbCBkYW4gc2ltcGFuZ2FuIGJha3Ugc2F0dS4gSW5pIGJlcmd1bmEgZGFsYW0gbWVtYmFuZGluZ2thbiB2YXJpYWJlbCB5YW5nIGRpdWt1ciBkYWxhbSB1bml0IHlhbmcgYmVyYmVkYSBhdGF1IG1lbWlsaWtpIHNrYWxhIHlhbmcgYmVzYXIuIA0KDQotICoqTm9ybWFsaXNhc2kgKE1pbi1NYXggU2NhbGluZykqKg0KDQpNZW5ndWJhaCBuaWxhaS1uaWxhaSBkYXRhIGtlIGRhbGFtIHJlbnRhbmcgdGVydGVudHUsIHNlcGVydGkgWzAsIDFdIGF0YXUgWy0xLCAxXS4gSW5pIG1lbXVuZ2tpbmthbiBkYXRhIG1lbWlsaWtpIHNrYWxhIHlhbmcgc2VyYWdhbS4gDQoNCi0gKipQZW5ndXJ1dGFuIFJhbmdraW5nIChSYW5rIFRyYW5zZm9ybWF0aW9uKSoqDQoNCk1lbmdnYW50aSBzZXRpYXAgbmlsYWkgZGFsYW0gZGF0YXNldCBkZW5nYW4gcGVyaW5na2F0IGF0YXUgcmFuZ2tpbmcgcmVsYXRpZm55YSBkYWxhbSBkYXRhc2V0LiBJbmkgYmVyZ3VuYSBkYWxhbSBtZW5nYXRhc2kgYXNpbWV0cmkgYXRhdSBhbm9tYWxpIGRhbGFtIGRhdGEuIA0KDQotICoqV2luc29yaXphdGlvbioqDQoNCk1lbmdnYW50aSBuaWxhaS1uaWxhaSBvdXRsaWVyIGRlbmdhbiBuaWxhaS1uaWxhaSB0ZXJ0ZW50dSB5YW5nIGJlcmFkYSBkaSBrdWFydGlsIHRlcnRlbnR1IGRhcmkgZGlzdHJpYnVzaSBkYXRhLiBJbmkgbWVtYmFudHUgbWVuZ3VyYW5naSBkYW1wYWsgb3V0bGllciB0ZXJoYWRhcCBhbmFsaXNpcyBzdGF0aXN0aWsuIA0KDQojIyBTdHVkeSBjYXNlDQoNClN0dWR5IGNhc2UgaW5pIGlzaW55YSBiZWJlcmFwYSBjb250b2ggeWFuZyBzZXJpbmcga2l0YSBkYXBhdGthbiBrZXRpa2EgZGFsYW0gbWVtYnVhdCBtb2RlbC4NCg0KIyMjIFBlcnNpYXBhbg0KDQojIyMjIFBBQ0tBR0UNCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJlYWRyKQ0KIyBsaWJyYXJ5IGZvciBkYXRhIHNldA0KbGlicmFyeShkYXRhc2V0cykNCmxpYnJhcnkoYm9vdCkNCmxpYnJhcnkoYWdyaWNvbGFlKQ0KbGlicmFyeShCU0RBKQ0KYGBgDQoNCiMjIyMgRGF0YSBzZXQNCg0KTWVuY2FyaSBjb250b2ggZGF0YSBzZXQgZGFsYW0gc3RhdGlzdGlrYSBidWthbmxhaCBoYWwgeWFuZyBzdWxpdCwgZGVuZ2FuIFIga2l0YSBiaXNhIG1lbmRhcGF0a2FuIHJpYnVhbiBkYXRhIHNldC4ga2l0YSBiaXNhIG1lbmdpbnN0YWxsIHBhY2thZ2UgKGRhdGFzZXRzLCBnZ3Bsb3QyLCBsdWJyaWRhdGUsIGRwbHlyKS4gY2VrIGRpIHN1YiBiYWIgdGFtYmFoYW4sDQoNCiMjIExldCdzIEdvDQoNCk1hcmkgbWVuZ2d1bmFrYW4gY29udG9oIGNvbnRvaCB1bnR1ayB0cmFuc2Zvcm1hc2kgZGF0YSwgcGVybHUgZGkgaW5nYXQga29udGVuIGluaSB0aWRhayBha2FuIG1lbWJhaGFzIHNlbXVhbnlhLCBuYW11biBha2FuIG1lbWJhaGFzIHlhbmcgdW11bSBkYW4gYWthbiBzZXJpbmcga2l0YSBwYWthaSBkYWxhbSBrZWhpZHVwYW4gYWtoaXJhdCwgZWggbWFrc3VkbnlhIHNlaGFyaSBoYXJpLg0KDQojIyMgVHJhbnNmb3JtYXNpIGRhdGEgZGVuZ2FuIGxvZ2FyaXRtYQ0KDQpgeSA9IGxvZyh4KWANCg0KQmVnaXR1bGFoIGZ1bmdzaW55YSwgbmFtdW4gcGVybHUgZGlpbmdhdCwgWWFuZyBwZXJsdSBkaXBlcmhhdGlrYW4gYWRhbGFoIGJhaHdhIHRyYW5zZm9ybWFzaSBsb2dhcml0bWEgaGFueWEgYmVybGFrdSB1bnR1ayBuaWxhaS1uaWxhaSB5YW5nIHBvc2l0aWYsIGthcmVuYSBsb2dhcml0bWEgZGFyaSBub2wgYXRhdSBuaWxhaSBuZWdhdGlmIHRpZGFrIHRlcmRlZmluaXNpIGRhbGFtIG1hdGVtYXRpa2EuIFNlYmFnYWkgYWx0ZXJuYXRpZiwgQW5kYSBiaXNhIG1lbmdndW5ha2FuIHRyYW5zZm9ybWFzaSBgQm94LUNveGAgdW50dWsgbWVuYW5nYW5pIGRhdGEgeWFuZyBiZXJpc2kgbmlsYWkgbm9sIGF0YXUgbmVnYXRpZi4NCg0KVHJhbnNmb3JtYXNpIGxvZ2FyaXRtYSBraXRhIGd1bmFrYW4ga2V0aWthIGRhdGEga2l0YSBiZXJkaXN0cmlidXNpIGJlcmFkYSBkaSAxIGFyYWgsIGNvbnRvaG55YSBraXJpIGF0YXUga2FuYW4sIGNvbnRvaG55YSBzcGVydGkgZGkgYmF3YWggaW5pLg0KDQoNCmBgYHtyfQ0KaGVhZChlc29waCw2KQ0KY29udG9oeHgyID0gZXNvcGggJT4lIA0KICBzZWxlY3QobmNhc2VzLCBuY29udHJvbHMpDQojIHN1bW1hcnkgc2ViZWx1bSBkaSB0cmFuZm9ybWFzaQ0Kc3VtbWFyeShjb250b2h4eDIpDQpgYGANCg0KYGBge3J9DQpwbG90KGNvbnRvaHh4MiwgcGNoID0xNiwgY29sID0gImRhcmtncmVlbiIsICB4bGFiID0ibmNhc2VzIiwgeWxhYiA9ICAibmNvbnRyb2xzIiwgbWFpbiA9ICJTZWJlbHVtIGRpIHRyYW5zZm9ybWFzaSIpDQp0ZXh0KHg9MTUsIHk9NTAsIGxhYmVscyA9ICIqKmhhbnlhIHVudHVrIGNvbnRvaCBzYWphIHlhay4uLioqIiwgcG9zID0yLDUsIGNvbCA9ICJyZWQiLCBjZXggPSAwLjkpDQpgYGANCg0Ka2VsaWhhdGFuIGthbiBwbG90IGRpIGF0YXMgY2VuZGVydW5nIGtlIGtpcmksIG5haCBkZW5nYW4gdHJhbnNmb3JtYXRpb24gbG9nLCBraXRhIGJpc2EgbWVtYnVhdG55YSBtZW5qYWRpIG1lbnllYmFyIGtldGVuZ2FoLiBNYXJpIGtpdGEgY29iYSB1bnR1ayBsYWt1a2FuIHRyYW5zZm9ybWFzaS4NCg0KYGBge3J9DQpsb2dfdHJhbnNmb3JtID0gbG9nKGNvbnRvaHh4MiwgYmFzZSA9MTApDQpwbG90KGxvZ190cmFuc2Zvcm0sIHBjaCA9MTYsIGNvbCA9ICJkYXJrcmVkIiwgbWFpbiA9ICJzZXRlbGFoIGRpIHRyYW5zZm9ybWFzaSIpDQpgYGANCg0KYGBge3J9DQojIFN1bW1hcnkgc2V0ZWxhaCBkaSB0cmFuc2Zvcm1hc2kNCnN1bW1hcnkobG9nX3RyYW5zZm9ybSkNCmBgYA0KS2FyZW5hIGRhdGEgeWFuZyBkaSBndW5ha2FuIGFkYSBhbmdrYSAwLCBzZWJlbmFybnlhIFRyYW5zZm9ybWFzaSBsb2cgdGlkYWsgYmlzYSBkaSBndW5ha2FuLiBqYWRpIGtpdGEgaGFydXMgbWVuZ2d1bmFrYW4gYHRyYW5zZm9ybWFzaSBCb3gtQ294YC4NCg0KIyMjIFRyYW5zZm9ybWFzaSBkYXRhIGRlbmdhbiBEaWZlcmVuY2luZw0KDQpUcmFuc2Zvcm1hc2kgaW5pIGJhbnlhayBkaSBndW5ha2FuIHVudHVrIGRhdGEgeWFuZyBha2FuIGRpZ3VuYWthbiB1bnR1ayBtZW1idWF0IG1vZGVsIGRhbGFtIGFuYWxpc2lzIGB0aW1lIHNlcmllc2AsIHRyYW5zZm9ybWFzaSBpbmkgZGkgamFsYW5rYW4ga2V0aWthIGRhdGEgc2V0IHlhbmcga2l0YSBwdW55YSB0aWRhayBzdGFzaW9uZXIuIHBlbmplbGFzYW4gdGVudGFuZyBzdGFzaW9uZXIgYWthbiBkaWJhaGFzIGRpIGtvbnRlbiB5YW5nIGxhaW4uDQoNCmBgYHtyfQ0Kc3VtbWFyeShsZGVhdGhzKQ0KcGxvdChsZGVhdGhzLCBtYWluID0gIkNvbnRvaCBzZWJlbHVtIGRpIHRyYW5zZm9ybWFzaSIpDQpgYGANCg0Ka2FyZW5hIGRpIGF0YXMgaGFueWEgY29udG9oLCBiYXlhbmdrYW4gc2FqYSBkYXRhIGRpIGF0YXMgdGlkYWsgc3Rhc2lvbmVyLiBzZWxhbmp1dG55YS4NCmBgYHtyfQ0KI2RhdGEgc2ViZWx1bSBkaSBUcmFuc2Zvcm1hc2kNCmhlYWQobGRlYXRocykNCmBgYA0KYGBge3J9DQpkaWZmX3RyYW5zZm9ybWF0aW9uID0gZGlmZihsZGVhdGhzKQ0KIyBkYXRhIHNldGVsYWggZGkgdHJhbnNmb3JtYWkNCmhlYWQoZGlmZl90cmFuc2Zvcm1hdGlvbikNCmBgYA0KDQpgYGB7cn0NCnBsb3QoZGlmZl90cmFuc2Zvcm1hdGlvbiwgbWFpbiA9ICJwbG90IHNldGVsYWggZGkgdHJhbnNmb3JtYXNpIikNCmBgYA0KDQpuYWggYmVnaXR1bGFoIGNhcmFueWEgdHJhbnNmb3JtYXNpIGRhdGEgZGkgUiwgbWFzYWxhaCBwZW5qZWxhc2FuIHN0YXNpb2luZXIgYWthbiBkaSBwZWxhamFyaSBkaSB0aW1lIHNlcmllcy4NCg0KDQoNCg==