1 Bab 8 Dugaan dalam Regresi Linier

Setelah membaca bab ini, diharapkan anda akan memiliki kemampuan untuk:

  • Memahami distribusi perkiraan regresi.
  • Membuat perkiraan interval untuk parameter regresi, respon rata-rata, dan prediksi.
  • Uji signifikansi regresi.

Pada bagian akhir, kita akan mendefinisikan model regresi linier sederhana,

\[Y_i=\beta_0+\beta_1x_1+\epsilon_i\]

dimana \(\epsilon_i\backsim N(0,\sigma^2)\). Kemudian kita menggunakan pengamatan \((x_i,y_i)\), untuk \(i=1,2,...,n\), untuk mencari nilai \(\beta_0\) dan \(\beta_1\) yang diminimalkan

\[f(\beta_0,\beta_1)=\sum^n_{i=1}(y_i-(\beta_0+\beta_1x_i))^2\]

Kita memiliki nilai-nilai \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) yang telah kita temukan sebagai berikut:

\[\hat{\beta_1}=\frac{S_{xy}}{S_{xx}}=\frac{\sum^n_{i=1}(x_i-\bar{x})(y_i-\bar{y})}{\sum^n_{i=1}(x_i-\bar{x})^2}\]

\[\hat{\beta_0}=\bar{y}-\hat{\beta_1}\bar{x}\]

Kita juga memperkirakan \(\sigma^2\) menggunakan \(s^2_e\). Artinya, kita menemukan bahwa \(s_e\) ini adalah perkiraan dari \(\sigma\), dimana:

\[s_e=RSE=\sqrt{\frac{1}{n-2}\sum^n_{i=1}e^2_i}\]

yang mana RSE merupakan singkatan dari “Residual Standard Error” (Kesalahan Standar Sisa).

Ketika diterapkan pada data cars, kita memperoleh hasil sebagai berikut:

## 
## Call:
## lm(formula = dist ~ speed, data = cars)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -29.069  -9.525  -2.272   9.215  43.201 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -17.5791     6.7584  -2.601   0.0123 *  
## speed         3.9324     0.4155   9.464 1.49e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15.38 on 48 degrees of freedom
## Multiple R-squared:  0.6511, Adjusted R-squared:  0.6438 
## F-statistic: 89.57 on 1 and 48 DF,  p-value: 1.49e-12

Pada bagian akhir, kita hanya membahas nilai-nilai Estimate, Residual Standard Error, dan Multiple R-squared. Pada bagian ini, kita akan membahas semua informasi mengenai Coefficients serta F-statistic.

Untuk memulai, kita akan mencatat bahwa ada ekspresi lain yang setara untuk \(S_{xy}\) yang tidak kita lihat pada bagian akhir,

\[S_{xy}=\sum^n_{i=1}(x_i-\bar{x})(y_i-\bar{y})=\sum^n_{i=1}(x_i-\bar{x}y_i)\]

Ini mungkin kesetaraan yang mengejutkan (Cobalah untuk membuktikannya). Namun, hal tersebut akan sangat membantu untuk menggambarkan konsep pada bagian ini.

Perhatikan bahwa, \(\hat{\beta_1}\) adalah statistik sampel jika dihitung dengan data pengamatan yang ditulis di atas, seperti \(\hat{\beta_0}\).

Tetapi, dalam bagian ini akan lebih mudah untuk menggunakan \(\hat{\beta_1}\) dan \(\hat{\beta_0}\) sebagai variabel acak, akan tetapi, kita belum mengamati nilai untuk setiap \(Y_i\). Jika demikian, kita akan menggunakan notasi yang sedikit berbeda, menggantikan \(Y_i\) kapital dengan \(y_i\) huruf kecil.

\(\hat{\beta_1}=\frac{\sum^n_{i=1}(x_i-\bar{x})Y_i}{\sum^n_{i=1}(x_i-\bar{x})^2}\)

\(\hat{\beta_0}=\bar{Y}-\hat{\beta_1}\bar{x}\)

Pada bagian akhir kita berpendapat bahwa perkiraan parameter model yang tidak diketahui ini (\(\beta_0\) dan \(\beta_1\)) adalah baik karena kita memperolehnya dengan meminimalkan kesalahan. Sekarang kita akan membahas teorema Gauss-Markov yang membawa gagasan ini lebih lanjut, menunjukkan bahwa perkiraan ini sebanarnya adalah perkiraan yang “terbaik”, dari sudut pandang tertentu.

1.1 Teorema Gauss-Markov

Teorema Gauss-Markov memberitahu kita bahwa ketika memperkirakan parameter model regresi linier sederhana \(\beta_0\), dan \(\beta_1\), \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) yang kita dapatkan adalah perkiraan tidak bias linier terbaik. (Kondisi sebenarnya teorema Gauss-Markov lebih santai daripada model SLR)

Sekarang kita akan membahas linier, tidak bias, dan terbaik yang berhubungan dengan perkiraan ini.

1.1.1 Linier

Mengingat kembali, dalam aturan SLR, nilai-nilai \(x_i\) dianggap tetap dan jumlahnya diketahui. Kemudian, perkiraan linier adalah salah satu yang dapat ditulis sebagai kombinasi linier dari \(Y_i\). Dalam kasus \(\hat{\beta_1}\) kita dapatkan

\[\hat{\beta_1}=\frac{\sum^n_{i=1}(x_i-\bar{x})Y_i}{\sum^n_{i=1}(x_i-\bar{x})^2}=\sum^n_{i=1}k_iY_i=k_1Y_1+k_2Y_2+...+k_nY_n\]

dimana \(k_i=\frac{(x_i-\bar{x})}{\sum^n_{i=1}(x_i-\bar{x})^2}\).

Dengan cara yang sama, kita dapat menunjukkan bahwa \(\hat{\beta_0}\) dapat ditulis sebagai kombinasi linier dari \(Y_i\). Jadi, \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) keduanya adalah estimator linier.

1.1.2 Unbias

Sekarang kita tahu bahwa perkiraan kita adalah linier, seberapa baguskah perkiraan ini? Salah satu ukuran “goodness” (kebaikan) dari perkiraan ini adalah bias. Secara khusus, kita lebih suka perkiraan yang tidak bias, yang artinya nilai yang diharapkan adalah parameter yang sedang diperkirakan.

Pada kasus perkiraan regresi, kita memiliki

\[E[\hat{\beta_0}]=\beta_0\] \[E[\hat{\beta_1}]=\beta_1\]

Ini artinya, ketika menemukan kondisi model SLR, rata-rata perkiraan kita akan benar. Tetapi, seperti yang kita lihat pada bagian terakhir ketika menyimulasikan dari model SLR, itu bukan berarti bahwa setiap perkiraan individual akan benar. Hanya saja, jika kita mengulangi prosesnya sebanyak tak terhingga, rata-rata perkiraan akan benar.

1.1.3 The Best

Sekarang, jika kita membatasi diri terhadap perkiraan linier dan tidak bias, bagaimana cara kita menentukan perkiraan terbaik? Perkiraan dengan variansi minimum.

Pertama, perhatikan bahwa sangat mudah untuk membuat perkiraan untuk \(\beta_1\) yang memiliki variansi sangat rendah, tetapi tidak bias. Sebagai contoh, tentukan:

\[\hat{\theta}_{BAD}=5\].

Lalu, karena \(\hat{\theta}_{BAD}\) adalah nilai konstan, maka

\[Var[\hat{\theta}_{BAD}]=0\].

Namun karena,

\[E[\hat{\theta}_{BAD}]=5\]

kita mengatakan bahwa \(\hat{\theta}_{BAD}\) adalah estimator bias kecuali \(\beta_1=5\) yang tidak akan kita ketahui sebelumnya. Ini adalah perkiraan yang buruk (kecuai secara kebetulan \(\beta_1=5\)) meskipun memiliki kemungkinan variansi terkecil. Ini adalah bagian dari alasan kita membatasi diri pada perkiraan tidak bias. Apa gunanya sebuah perkiraan, jika memperkirakan kuantitas yang salah?

Sekarang, pertanyaan wajarnya adalah, apa variansi dari \(\hat{\beta_0}\) dan \(\hat{\beta_1}\)? Yaitu,

\[Var[\hat{\beta_0}]=\sigma^2(\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}})\]

\[Var[\hat{\beta_1}]=\frac{\sigma^2}{S_{xx}}\]

Ini mengukur variabilitas dari perkiraan dikarenakan peluang acak selama pengambilan sampel. Apakah ini “yang terbaik”? Apakah variansi sekecil ini yang kemungkinan kita bisa dapatkan? Anda hanya perlu mempercayai apa yang kami katakan karena menunjukkan bahwa ini benar berada di luar cakupan kursus ini.

1.2 Distribusi Sampling

Sekarang kita telah “mendefinisikan ulang” perkiraan untuk \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) sebagai variabel acak, kita dapat mendiskusikan distribusi samplingnya, yang merupakan distribusi ketika statistik dianggap sebagai variabel acak.

Karena \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) adalah kombinasi linier dari \(Y_i\) dan setiap \(Y_i\) adalah distribusi normal, maka \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) juga mengikuti distribusi normal.

kemudian, gabungkan semua hal di atas, kita dapatkan distribusi \(\hat{\beta_0}\) dan \(\hat{\beta_1}\).

Untuk \(\hat{\beta_1}\) kita tuliskan, \(\hat{\beta_1}=\frac{S_{xy}}{S_{xx}}=\frac{\sum^n_{i=1}(x_i-\bar{x})Y_i}{\sum^n_{i=1}(x_i-\bar{x})^2}\backsim N(\beta_1,\frac{\sigma^2}{\sum^n_{i=1}(x_i-\bar{x})^2})\)

atau lebih ringkas,

\[\hat{\beta_1}\backsim N(\beta_1,\frac{\sigma^2}{S_{xx}})\].

Dan untuk \(\hat{\beta_0}\),

\[\hat{\beta_0}\backsim N(\beta_0,\sigma^2(\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}))\]

Sejauh ini, kita gagal membuktikan sejumlah hasilnya. Kita tidak akan mengerjakan turunan yang membosankan dari distribusi sampel ini, tetapi kita akan membenarkan hasilnya menggunakan simulasi.

Catatan untuk pembaca saat ini: Turunan dan pembuktian ini mungkin bisa ditambahkan ke lampiran untuk kemudian hari. Anda juga dapat menemukan hasil ini di hampir semua buku regresi linier sederhana. Di UIUC, hasil ini kemungkinan besar akan disajikan di STAT 424 dan STAT425. Namun, karena Anda tidak diminta untuk melakukan penurunan jenis ini pada kursus kali ini, maka untuk saat ini hasil tersebut bisa dihilangkan.

1.2.1 Menyimulasikan Distribusi Sampling

Untuk memeriksa hasil di atas, kita akan menyimulasikan sampel dengan ukuran \(n=100\) dari model berikut

\[Y_i=\beta_0+\beta_1x_i+\epsilon_i\]

dimana \(\epsilon_i∼N(0,\sigma^2)\)

  • \(\beta_0=3\)
  • \(\beta_1=6\)
  • \(\sigma^2=4\)

Kemudian, berdasarkan keterangan di atas, kita harus menemukan

\[\hat{\beta_1}\backsim N(\beta_1,\frac{\sigma^2}{S_{xx}})\]

\[\hat{\beta_0}\backsim N(\beta_0,\sigma^2(\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}))\].

Pertama, kita sebelumnya perlu memutuskan berapa nilai \(x\) kita untuk simulasi ini, karena nilai \(x\) dalam SLR kuantitasnya dianggap diketahui. Pilihan nilai \(x\) tidak tetap atau selalu berubah. Di sini kita juga menetapkan seed untuk pengacakan, dan menghitung \(S_{xx}\) yang akan kita perlukan untuk selanjutnya.

Kita juga akan memperbaiki nilai parameter kita.

Dengan informasi ini, kita mengetahui bahwa distribusi sampling seharusnya:

## [1] 0.1176238
## [1] 0.04

\(\hat{\beta_1}\backsim N(6, 0.1176238)\)

dan

\(\hat{\beta_0}\backsim N(3, 0.04)\)

Yaitu,

\(E[\hat{\beta_1}]=6\) \(Var[\hat{\beta_1}]=0.1176238\)

dan

\(E[\hat{\beta_0}]=3\) \(Var[\hat{\beta_0}]=0.04\)

Sekarang kita menyimulasikan data dari model ini sebanyak 10.000 kali. Perhatikan bahwa cara ini bukan merupakan cara R untuk melakukan simulasi. Kita melakukan simulasi dengan cara ini untuk mendapatkan kejelasan. Sebagai contoh, kita bisa menggunakan fungsi sim_slr dari bagian sebelumnya. Kita juga menyimpan variabel di environment global, bukan membuat data frame untuk setiap kumpulan data simulasi baru.

Setiap saat kita menyimulasikan data, kita memperoleh nilai perkiraan koefisien. Variabel beta_0_hats dan beta_1_hats sekarang menyimpan 10.000 nilai simulasi dari masing-masing \(\hat{\beta_0}\) dan \(\hat{\beta_1}\).

Kita verifikasi distribusi \(\hat{\beta_1}\) terlebih dahulu.

## [1] 6.001998
## [1] 6
## [1] 0.11899
## [1] 0.1176238

Kita dapat lihat bahwa rata-rata maupun varianse empiris dan rata-rata maupun variansi sebenarnya sangatlah mirip. Kita juga akan memeriksa distribusi empiris bersifat normal. Untuk melakukannya, kita memplot beta_1_hats ke histogram, dan tambahkan kurva untuk distribusi sebenarnya dari \(\hat{\beta_1}\). Kita gunakan prob = TRUE untuk meletakkan histogram pada skala yang sama dengan kurva normal.

Kemudian, kita ulangi prosesnya untuk \(\hat{\beta_0}\)

## [1] 3.001147
## [1] 3
## [1] 0.04017924
## [1] 0.04

Pada pelajaran simulasi ini, kita hanya bisa menyimulasikan sampel dengan jumlah yang terbatas. Untuk benar-benar memeriksa hasil distribusi, kita perlu mengamati sampel dengan jumlah yang tak terbatas. Namun, plot berikut ini menjelaskan bahwa jika kita melanjutkan proses simulasi ini, maka hasil empirisnya semakin mendekati apa yang kita harapkan.

1.3 Standar Error

Jadi, sekarang kita yakin terhadap hasil distribusi berikut,

\[\hat{\beta_0}\backsim N(\beta_0,\sigma^2(\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}))\] \[\hat{\beta_1}\backsim N(\beta_1,\frac{\sigma^2}{S_{xx}})\]

Dengan menstandarkan hasil ini, kita temukan bahwa

\[\frac{\hat{\beta_0}-\beta_0}{SD[\hat{\beta_0}]}\backsim N(0,1)\]

dan

\[\frac{\hat{\beta_1}-\beta_1}{SD[\hat{\beta_1}]}\backsim N(0,1)\]

dimana

\[SD[\hat{\beta_0}]=\sigma\sqrt{\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}}\]

dan

\[SD[\hat{\beta_1}]=\frac{\sigma}{\sqrt{S_{xx}}}\].

Karena kita tidak mengetahui \(\sigma\) dalam praktiknya, kita harus memperkirakannya menggunakan \(s_e\), yang kita masukkan ke ekspresi yang ada untuk standar deviasi perkiraan kita.

Kedua ekspresi baru ini disebut dengan kesalahan standar yang merupakan perkiraan standar deviasi dari distribusi sampling.

\[SE[\hat{\beta_0}]=s_e\sqrt{\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}}\] \[SE[\hat{\beta_1}]=\frac{s_e}{\sqrt{S_{xx}}}\]

Sekarang, jika kita bagi dengan kesalahan standar (bukan standar deviasi), kita akan memperoleh hasil berikut yang memungkinkan untuk membuat interval kepercayaan dan melakukan uji hipotesis.

\[\frac{\hat{\beta_0}-\beta_0}{SE[\hat{\beta_0}]}\backsim t_{n-2}\] \[\frac{\hat{\beta_1}-\beta_1}{SE[\hat{\beta_1}]}\backsim t_{n-2}\]

Untuk melihatnya, pertama-tama perhatikan bahwa,

\[\frac{RSS}{\sigma^2}=\frac{(n-2)s^2_e}{\sigma^2}\backsim \chi^2_{n-2}\]

Dan juga ingat kembali variabel \(T\) didefinisikan sebagai,

\[T=\frac{Z}{\sqrt{\frac{\chi^2_d}{d}}}\]

mengikuti distribusi \(t\) dengan derajat kebebasan \(d\), dimana \(\chi^2_d\) adalah variabel acak \(\chi^2\) dengan derajat kebebasan \(d\).

Kita tulis,

\(T\backsim t_d\)

untuk mengatakan bahwa variabel acak \(T\) mengikuti distribusi \(t\) dengan derajat kebebasan \(d\).

Kemudian, kita menggunakan trik klasik “dikalikan dengan 1” dan beberapa penyusunan ulang untuk sampai kepada,

\(\frac{\hat{\beta_1}-\beta_1}{SE[\hat{\beta_1}]}=\frac{\hat{\beta_1}-\beta_1}{\frac{s_e}{\sqrt{S_{xx}}}}\)

\(=\frac{\hat{\beta_1}-\beta_1}{\frac{s_e}{\sqrt{S_{xx}}}}.\frac{\frac{\sigma}{\sqrt{S_{xx}}}}{\frac{\sigma}{\sqrt{S_{xx}}}}\)

\(=\frac{\hat{\beta_1}-\beta_1}{\frac{\sigma}{\sqrt{S_{xx}}}}.\frac{\frac{\sigma}{\sqrt{S_{xx}}}}{\frac{s_e}{\sqrt{S_{xx}}}}\)

\(=\frac{\hat{\beta_1}-\beta_1}{\frac{\sigma}{\sqrt{S_{xx}}}}/\sqrt{\frac{s^2_e}{\sigma^2}}\)

\(=\frac{\hat{\beta_1}-\beta_1}{SD[\hat{\beta_1}]}/\sqrt{\frac{\frac{(n-2)s^2_e}{\sigma^2}}{n-2}}\backsim \frac{Z}{\sqrt{\frac{\chi^2_{n-2}}{n-2}}}\backsim t_{n-2}\)

dimana \(Z\backsim N(0,1)\)

Ingatlah bahwa distribusi \(t\) mirip dengan normal standar, tetapi dengan ekor (tails) yang lebih padat. Ketika derjat kebebasannya meningkat, distribusi \(t\) menjadi lebih seperti normal standar. Di bawah ini kita plot distribusi normal standar dengan dua contoh dari distribusi \(t\) dengan derajat kebebasan yang berbeda. Perhatikan bagaimana distribusi \(t\) dengan derajat kebebasan yang lebih besar akan lebih mirip dengan kurva normal standar.

1.4 Interval Kepercayaan untuk Kemiringan dan Intersep

Ingat bahwa interval kepercayaan untuk rata-rata sering kali berbentuk:

\(EST±CRIT.SE\)

atau

\(EST±MARGIN\)

dimana EST merupakan perkiraan untuk parameter yang diinginkan, SE adalah kesalahan standar dari perkiraan, dan MARGIN = CRIT.SE.

Kemudian, kita dapat membuat interval kepercayaan untuk \(\beta_0\) dan \(\beta_1\) menggunakan

\(\hat{\beta_0}±t_{a/2,n-2}.SE[\hat{\beta_0}]\) \(\hat{\beta_0}±t_{a/2,n-2}.s_e\sqrt{\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}}\)

dan

\(\hat{\beta_1}±t_{a/2,n-2}.SE[\hat{\beta_1}]\) \(\hat{\beta_1}±t_{a/2,n-2}.\frac{s_e}{\sqrt{S_{xx}}}\)

dimana \(t_{a/2, n-2}\) adalah nilai kritis seperti \(P(t_{n-2}>t_{a/2, n-2)}=\frac{a}{2}\).

1.5 Pengujian Hipotesis

Ingat bahwa statistik uji \(\text{TS}\) untuk sarana pengujian sering kali berbentuk:

\(\text{TS} = \frac{\text{EST} - \text {HYP}} {\text {SE}}\)

di mana \(\text {HYP}\) \(\text {EST}\) adalah perkiraan untuk parameter yang diminati, adalah nilai hipotesis dari parameter, dan \(\text{SE}\) adalah kesalahan standar perkiraan.

Jadi, untuk mengujinya

\(H_0: \beta_0 = \beta_ {00} \quad \text {vs} \quad H_1: \beta_0 \neq \beta_ {00}\)

kami menggunakan statistik uji

\(t = \frac {\hat {\beta} _0 - \beta_{00}} {\text {SE} [\hat {\beta} _0]} = \frac {\hat {\beta} _0- \beta_ { 00}} {s_e \sqrt {\frac {1} {n} + \frac {\bar {x} ^ 2} {S_ {xx}}}}\)

yang, di bawah hipotesis nol, mengikuti a t distribusi dengan \(n - 2\) derajat kebebasan. Kita gunakan \(\beta_ {00}\) untuk menunjukkan nilai yang dihipotesiskan dari \(\beta_0.\)

Begitu pula untuk mengetes

\(H_0: \beta_1 = \beta_ {10} \quad \text {vs} \quad H_1: \beta_1 \neq \beta_ {10}\)

kami menggunakan statistik uji

\(t = \frac {\hat {\beta} _1- \beta_ {10}} {\text {SE} [\hat {\beta} _1]} = \frac {\hat {\beta} _1- \beta_ { 10}} {s_e / \sqrt {S_ {xx}}}\)

yang lagi-lagi, di bawah hipotesis nol, mengikuti distribusi t dengan \(n - 2\) derajat kebebasan. Sekarang kami menggunakan \(\beta_ {10}\) untuk menunjukkan nilai hipotesis dari \(\beta_1\) .

1.6 Contoh cars

Sekarang kita kembali ke cars contoh dari bagian terakhir untuk mengilustrasikan konsep ini. Kami pertama-tama menyesuaikan model menggunakan lm() kemudian menggunakan summary() untuk melihat hasil secara lebih rinci.

## 
## Call:
## lm(formula = dist ~ speed, data = cars)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -29.069  -9.525  -2.272   9.215  43.201 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -17.5791     6.7584  -2.601   0.0123 *  
## speed         3.9324     0.4155   9.464 1.49e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15.38 on 48 degrees of freedom
## Multiple R-squared:  0.6511, Adjusted R-squared:  0.6438 
## F-statistic: 89.57 on 1 and 48 DF,  p-value: 1.49e-12

1.6.1 Pengujian dalam R

Sekarang kita akan membahas hasil yang ditampilkan yang disebut Coefficients. Pertama, ingatlah bahwa kita dapat mengekstrak informasi ini secara langsung.

##  [1] "call"          "terms"         "residuals"     "coefficients" 
##  [5] "aliased"       "sigma"         "df"            "r.squared"    
##  [9] "adj.r.squared" "fstatistic"    "cov.unscaled"
##               Estimate Std. Error   t value     Pr(>|t|)
## (Intercept) -17.579095  6.7584402 -2.601058 1.231882e-02
## speed         3.932409  0.4155128  9.463990 1.489836e-12

The names() Fungsi memberitahu kita apa informasi yang tersedia, dan kemudian kita menggunakan operator dan coefficient suntuk mengekstrak informasi yang kita tertarik. Dua nilai di sini harus segera akrab.

\[\hat {\beta} _0 = -17.5790949\]

dan

\[\hat {\beta} _1 = 3.9324088\]

yang merupakan perkiraan kami untuk parameter model \(\beta_0\) dan \(\beta_1\) .

Sekarang mari kita fokus pada keluaran baris kedua, yang relevan dengan \(\beta_1\) .

##     Estimate   Std. Error      t value     Pr(>|t|) 
## 3.932409e+00 4.155128e-01 9.463990e+00 1.489836e-12

Sekali lagi, nilai pertama Estimate adalah

\[\hat {\beta} _1 = 3.9324088.\]

Nilai kedua, Std. Error, adalah kesalahan standar dari \(\hat {\beta} _1\),

\(\text {SE} [\hat {\beta} _1] = \frac {s_e} {\sqrt {S_ {xx}}} = 0,4155128.\)

Nilai ketiga, t-value, adalah nilai statistik uji untuk pengujian \(H_0: \beta_1 = 0 \quad {vs} \quad H_1: \beta_1 \neq 0 ,\)

\(t = \frac {\hat {\beta} _1-0} {\text {SE} [\hat {\beta} _1]} = \frac {\hat {\beta} _1-0} {s_e / \sqrt {S_ {xx}}} = 9,46399.\)

Terakhir, \(Pr(>|t|)\). beri kami nilai p dari pengujian itu.

\(\text {p-value} = 1,4898365 \times 10 ^ {- 12}\)

Perhatikan di sini, kami secara khusus menguji apakah \(\beta_1 = 0\) atau tidak .

Baris pertama keluaran melaporkan nilai yang sama, tetapi untuk \(\beta_0\) .

##     Estimate   Std. Error      t value     Pr(>|t|) 
## -17.57909489   6.75844017  -2.60105800   0.01231882

Singkatnya, kode berikut menyimpan informasi summary(stop_dist_model)coefficients dalam variabel baru (stop_dist_model_test_info), lalu mengekstrak setiap elemen menjadi variabel baru yang menjelaskan informasi yang dikandungnya.

Kemudian kita dapat memverifikasi beberapa ekspresi yang setara: statistik uji t untuk \(\hat {\beta} _1\) dan nilai p dua sisi yang terkait dengan statistik uji tersebut.

## [1] 9.46399
## [1] 9.46399
## [1] 1.489836e-12
## [1] 1.489836e-12

1.6.2 Signifikansi Regresi, Uji-t

Kami berhenti sejenak untuk membahas pentingnya uji regresi . Pertama, perhatikan bahwa berdasarkan hasil distribusi di atas, kami dapat menguji \(\beta_0\) dan \(\beta_1\) terhadap nilai tertentu, dan melakukan pengujian satu dan dua sisi.

Namun, satu tes yang sangat spesifik,

\(H_0: \beta_1 = 0 \quad \text {vs} \quad H_1: \beta_1 \neq 0\)

paling sering digunakan. Mari kita pikirkan pengujian ini dalam kaitannya dengan model regresi linier sederhana,

\(Y_i = \beta_0 + \beta_1 x_i + \epsilon_i.\)

Jika kami mengasumsikan hipotesis nol benar, maka \(\beta_1 = 0\) dan kami memiliki model,

\(Y_i = \beta_0 + \epsilon_i.\)

Dalam model ini, respon tidak bergantung pada prediktor. Jadi kita bisa memikirkan tes ini dengan cara berikut,

  • Di bawah \(H_0\) tidak ada hubungan linier yang signifikan antara \(x\) dan \(y\) .
  • Di bawah \(H_1\) ada hubungan linier yang signifikan antara \(x\) dan \(y\) .

Untuk contoh cars,

  • Di bawah \(H_0\) tidak ada hubungan linier yang signifikan antara kecepatan dan jarak berhenti.
  • Di bawah \(H_1\) ada hubungan linier yang signifikan antara kecepatan dan jarak berhenti.

Sekali lagi, pengujian itu terlihat pada keluaran dari summary(),

\(\text {nilai-p} = 1,4898365 \times 10 ^ {- 12}.\)

Dengan nilai p yang sangat rendah ini, kami akan menolak hipotesis nol pada tingkat \(\alpha\) yang masuk akal , misalnya \(\alpha = 0,01\) . Jadi kami katakan ada hubungan linier yang signifikan antara kecepatan dan jarak berhenti. Perhatikan bahwa kami menekankan linier .

Dalam plot data simulasi ini, kita melihat hubungan yang jelas antara \(x\) dan \(y\) , namun ini bukan hubungan linier. Jika kita memasukkan garis ke data ini, itu sangat datar. Hasil pengujian untuk \(H_0: \beta_1 = 0 \quad \text{vs} \quad H_1: \beta_1 \neq 0\) memberikan nilai p yang besar, dalam hal ini \(0,7564548\) , jadi kami gagal menolak dan mengatakan bahwa tidak ada hubungan linier yang signifikan antara \(x\) dan \(y\) . Kita akan melihat nanti bagaimana menyesuaikan kurva ke data ini menggunakan model “linier”, tetapi untuk saat ini, sadari bahwa pengujian \(H_0: \beta_1 = 0\quad \text{vs} \quad H_1: \beta_1 \neq 0\) hanya dapat mendeteksi hubungan garis lurus.

1.6.3 Interval Keyakinan dalam R

Dengan menggunakan Rkita bisa dengan mudah mendapatkan interval kepercayaan untuk \(\beta_0\) dan \(\beta_1\) .

##                  0.5 %    99.5 %
## (Intercept) -35.706610 0.5484205
## speed         2.817919 5.0468988

Ini secara otomatis menghitung 99% interval keyakinan untuk \(\beta_0\) dan \(\beta_1\) , baris pertama untuk \(\beta_0\) , baris kedua untuk \(\beta_1\) .

Sebagai carscontoh saat menafsirkan interval ini, kami katakan, kami 99% yakin bahwa untuk peningkatan kecepatan 1 mil per jam, peningkatan rata-rata jarak berhenti adalah antara \(2.8179187\) dan \(5.0468988\) kaki, yang merupakan interval untuk \(\beta_1\) .

Perhatikan bahwa interval keyakinan 99% ini tidak mengandung nilai hipotesis 0. Karena tidak mengandung 0, ini setara dengan menolak pengujian \(H_0: \beta_1 = 0\) vs \(H_1: \beta_1 \neq 0\) di \(\alpha = 0.01\) , yang telah kami lihat sebelumnya.

Anda harus mencurigai interval keyakinan untuk \(\beta_0\) , karena mencakup nilai negatif, yang sesuai dengan jarak henti negatif. Secara teknis interpretasinya adalah bahwa kami 99% yakin bahwa jarak berhenti rata-rata sebuah mobil yang menempuh jarak 0 mil per jam adalah antara -35.7066103 dan 0.5484205 kaki, tetapi kami tidak begitu percaya itu, karena kami benar-benar yakin bahwa itu akan terjadi. non-negatif.

Catatan, kita dapat mengekstrak nilai tertentu dari keluaran ini dengan beberapa cara. Kode ini tidak dijalankan, dan sebagai gantinya, Anda harus memeriksa hubungannya dengan keluaran kode di atas.

##       0.5 %      99.5 % 
## -35.7066103   0.5484205
## [1] -35.70661
## [1] 0.5484205
##                 0.5 %    99.5 %
## (Intercept) -35.70661 0.5484205
##    0.5 %   99.5 % 
## 2.817919 5.046899
## [1] 2.817919
## [1] 5.046899
##          0.5 %   99.5 %
## speed 2.817919 5.046899

Kami juga dapat memverifikasi bahwa kalkulasi yang bekerja Runtuk interval \(\beta_1\) .

##    speed    speed 
## 2.817919 5.046899

1.7 Interval Keyakinan untuk Respon Rata-rata

Selain interval keyakinan untuk \(\beta_0\) dan \(\beta_1\) , ada dua perkiraan interval umum lainnya yang digunakan dengan regresi. Yang pertama disebut interval kepercayaan untuk respons rata-rata . Seringkali, kita menginginkan estimasi interval untuk mean, \(E [Y \mid X = x]\) untuk nilai \(x\) tertentu .

Dalam situasi ini kita menggunakan \(\hat {y} (x)\) sebagai perkiraan kita untuk \(E [Y \mid X = x]\) . Kami mengubah sedikit notasi kami untuk memperjelas bahwa nilai prediksi adalah fungsi dari nilai x .

\[\hat {y} (x) = \hat {\beta} _0 + \hat {\beta} _1 x\]

Ingat itu,

\[\text {E} [Y \mid X = x] = \beta_0 + \beta_1 x.\]

Jadi, \(\hat {y} (x)\) adalah perkiraan yang baik karena tidak bias:

\[\text {E} [\hat {y} (x)] = \beta_0 + \beta_1 x.\]

Kami kemudian bisa mendapatkan,

\[\text{Var}[\hat{y}(x)] = \sigma^2 \left(\frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}\right).\]

Seperti perkiraan lain yang telah kita lihat, \(\hat {y} (x)\) juga mengikuti distribusi normal. Karena \(\hat {\beta} _0\) dan \(\hat {\beta} _1\) adalah kombinasi linier dari variabel acak normal, \(\hat {y} (x)\) juga.

\[\hat{y}(x) \sim N \left(\beta_0 + \beta_1 x, \sigma^2 \left(\frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}\right) \right)\]

Dan terakhir, karena kita perlu memperkirakan varians ini, kita sampai pada kesalahan standar dari perkiraan kita,

\[\text {SE} [\hat {y} (x)] = s_e \sqrt {\frac {1} {n} + \frac {(x- \bar {x}) ^ 2} {S_ {xx}} }.\]

Kami kemudian dapat menggunakan ini untuk menemukan interval kepercayaan untuk respons rata-rata,

\[\hat {y} (x) \pm t _ {\alpha / 2, n - 2} \cdot s_e \sqrt {\frac {1} {n} + \frac {(x- \bar {x}) ^ 2 } {S_ {xx}}}\]

Untuk menemukan interval kepercayaan untuk respons rata-rata menggunakan R, kami menggunakan predict() fungsi. Kami memberikan fungsi model pas kami serta data baru, disimpan sebagai bingkai data. (Ini penting, agar R mengetahui nama variabel prediktor.) Di sini, kami menemukan interval kepercayaan untuk jarak berhenti rata-rata saat mobil melaju 5 mil per jam dan saat mobil melaju 21 mil per jam.

##         fit       lwr      upr
## 1  2.082949 -10.89309 15.05898
## 2 65.001489  56.45836 73.54462

1.8 Interval Prediksi untuk Pengamatan Baru

Terkadang kita menginginkan estimasi interval untuk pengamatan baru, \(Y\) , untuk nilai \(x\) tertentu . Ini sangat mirip dengan interval untuk respons rata-rata, \(\text {E} [Y \mid X = x]\) , tetapi berbeda dalam satu hal yang sangat penting.

Tebakan terbaik kami untuk observasi baru masih \(\hat {y} (x)\) . Perkiraan rata-rata masih merupakan prediksi terbaik yang bisa kita buat. Perbedaannya terletak pada jumlah variabilitas. Kita tahu bahwa pengamatan akan bervariasi tentang garis regresi yang sebenarnya menurut distribusi \(N (0, \sigma ^ 2)\) . Karena itu kami menambahkan faktor tambahan \(\sigma^2\) ke variabilitas perkiraan kami untuk menjelaskan variabilitas pengamatan tentang garis regresi.

\(\begin{aligned}\text{Var}[\hat{y}(x) + \epsilon] &= \text{Var}[\hat{y}(x)] + \text{Var}[\epsilon] \\[2ex] \sigma^2 \left(\frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}\right) + \sigma^2 \\[2ex] \sigma^2 \left(1 + \frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}\right)\end{aligned}\)

\(\hat{y}(x) + \epsilon \sim N \left(\beta_0 + \beta_1 x, \ \sigma^2 \left(1 + \frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}\right) \right)\)

\(\text{SE}[\hat{y}(x) + \epsilon] = s_e \sqrt{1 + \frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}}\)

Kami kemudian dapat menemukan interval prediksi menggunakan,

\(\hat {y} (x) \pm t _ {\alpha / 2, n - 2} \cdot s_e \sqrt {1 + \frac {1} {n} + \frac {(x- \bar {x}) ^ 2} {S_ {xx}}}.\)

Untuk menghitung ini untuk satu set poin dalam Rpemberitahuan hanya ada sedikit perubahan dalam sintaks dari menemukan interval kepercayaan untuk respon rata-rata.

##         fit       lwr       upr
## 1  2.082949 -41.16099  45.32689
## 2 65.001489  22.87494 107.12803

Perhatikan juga bahwa kedua interval ini lebih lebar daripada interval kepercayaan yang sesuai untuk respons rata-rata.

1.9 Pita Keyakinan dan Prediksi

Seringkali kami ingin memplot kedua interval kepercayaan untuk respons rata-rata dan interval prediksi untuk semua kemungkinan nilai \(x\) . Kami menyebutnya band kepercayaan dan prediksi.

Beberapa hal yang perlu diperhatikan:

  • Kami menggunakan ylim argumen untuk meregangkan sumbu - y dari plot, karena pita memperpanjang lebih jauh dari titik point.

  • Kami menambahkan titik di titik \((\bar {x}, \bar {y})\) .

    • Ini adalah titik yang akan selalu dilewati garis regresi . (Pikirkan alasannya.)
    • Ini adalah titik di mana band keyakinan dan prediksi menjadi yang tersempit. Lihatlah kesalahan standar keduanya untuk memahami mengapa.

*Pita prediksi (titik-titik biru) kurang melengkung dibandingkan dengan pita kepercayaan (biru putus-putus). Ini adalah hasil dari faktor tambahan \(\sigma ^ 2\) yang ditambahkan ke varian pada nilai \(x\) apa pun .

1.10 Signifikansi Regresi, Uji-F

Dalam kasus regresi linier sederhana, uji \(t\) untuk signifikansi regresi sama dengan uji lain, uji \(F\) untuk signifikansi regresi. Kesetaraan ini hanya akan benar untuk regresi linier sederhana, dan di bagian selanjutnya kita hanya akan menggunakan uji \(F\) untuk signifikansi regresi.

Ingat dari bagian terakhir dekomposisi varians yang kita lihat sebelum menghitung \(R ^ 2\) ,

\[\sum_ {i = 1} ^ {n} (y_i - \bar {y}) ^ 2 = \sum_ {i = 1} ^ {n} (y_i - \hat {y} _i) ^ 2 + \sum_ { i = 1} ^ {n} (\hat {y} _i - \bar {y}) ^ 2,\]

atau, singkatnya,

\[\text {SST} = \text {SSE} + \text {SSReg}.\]

Untuk mengembangkan uji \(F\), kita akan mengatur informasi ini ke dalam tabel ANOVA,

Sumber Jumlah Kuadrat Derajat Kebebasan Rata-rata Kuadrat F
Regresi \(\sum^n_{i=1}(\hat{y}_i-y)^2\) 1 \(\frac{SSReg}{1}\) \(\frac{MSReg}{MSE}\)
Eror \(\sum^n_{i=1}(y_i-\hat{y}_i)^2\) \(n-2\) \(\frac{SSReg}{n-2}\)
Total \(\sum^n_{i=1}(y_i-y)^2\) \(n-1\)

ANOVA, atau Analisis Varians akan menjadi konsep yang sering kita bahas dalam kursus ini. Untuk saat ini, kita akan fokus pada hasil tabel, yaitu statistik \(F\) ,

\[F = \frac {\sum_ {i = 1} ^ {n} (\hat {y} _i - \bar {y}) ^ 2/1} {\sum_ {i = 1} ^ {n} (y_i - \hat {y} _i) ^ 2 / (n - 2)} \sim F_ {1, n - 2}\]

yang mengikuti distribusi \(F\) dengan derajat kebebasan \(1\) dan \(n - 2\) di bawah hipotesis nol. Sebuah \(F\) distribusi adalah distribusi kontinu yang mengambil nilai-nilai positif hanya dan memiliki dua parameter, yang merupakan dua derajat kebebasan.

Ingat, dalam arti dari uji regresi, \(Y\) tidak tidak tergantung pada \(x\) di hipotesis nol.

\(H_0: \beta_1 = 0 \quad \quad Y_i = \beta_0 + \epsilon_i\)

Sedangkan pada hipotesis alternatif \(Y\) mungkin bergantung pada \(x\) .

\(H_1: \beta_1 \neq 0 \quad \quad Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\)

Kita dapat menggunakan statistik F untuk melakukan tes ini.

\[F = \frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2 / 1}{\sum_{i=1}^{n}(y_i - \hat{y}_i)^2 / (n - 2)}\]

Secara khusus, kami akan menolak nol ketika statistik \(F\) besar, yaitu, ketika ada kemungkinan rendah bahwa pengamatan bisa datang dari model nol secara kebetulan. Kami akan menghitung nilai p dengan menggunakan R

Untuk melakukan uji \(F\) di R Anda dapat melihat baris terakhir dari keluaran dari panggilan yang memberikan nilai statistik uji, derajat kebebasan yang relevan, serta nilai p dari pengujian. summary() yang disebut F-statistic

## 
## Call:
## lm(formula = dist ~ speed, data = cars)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -29.069  -9.525  -2.272   9.215  43.201 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -17.5791     6.7584  -2.601   0.0123 *  
## speed         3.9324     0.4155   9.464 1.49e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15.38 on 48 degrees of freedom
## Multiple R-squared:  0.6511, Adjusted R-squared:  0.6438 
## F-statistic: 89.57 on 1 and 48 DF,  p-value: 1.49e-12

Selain itu, Anda dapat menggunakan anova() fungsi tersebut untuk menampilkan informasi dalam tabel ANOVA.

## Analysis of Variance Table
## 
## Response: dist
##           Df Sum Sq Mean Sq F value   Pr(>F)    
## speed      1  21186 21185.5  89.567 1.49e-12 ***
## Residuals 48  11354   236.5                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Ini juga memberikan nilai p untuk pengujian. Anda harus memperhatikan bahwa nilai-p dari uji \(t\) adalah sama. Anda mungkin juga memperhatikan bahwa nilai statistik uji untuk uji \(t\) , \(9.46399\) , dapat dikuadratkan untuk mendapatkan nilai statistik \(F\) , \(89.5671065\) .

Perhatikan bahwa ada cara lain yang setara untuk melakukan ini R, di mana kita akan sering kembali untuk membandingkan dua model.

## Analysis of Variance Table
## 
## Model 1: dist ~ 1
## Model 2: dist ~ speed
##   Res.Df   RSS Df Sum of Sq      F   Pr(>F)    
## 1     49 32539                                 
## 2     48 11354  1     21186 89.567 1.49e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Pernyataan model lm(dist ~ 1, data = cars) menerapkan model \(Y_i = \beta_0 + \epsilon_i\) ke data mobil. Perhatikan bahwa \(\hat {y} = \bar {y}\) ketika \(Y_i = \beta_0 + \epsilon_i\) .

Pernyataan model lm(dist ~ speed, data = cars) menerapkan model \(Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\) .

Kami kemudian dapat menganggap penggunaan ini anova()sebagai perbandingan langsung kedua model. (Perhatikan bahwa kita mendapatkan nilai p yang sama lagi.)

LS0tDQp0aXRsZTogIk1pZHRlcm0gRXhhbSINCmF1dGhvcjogIk5pY2hvbGFzIEFuZHJpYW4iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgaGlnaGxpZ2h0OiBtb25vY2hyb21lDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIExvZ28sIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2dpdGh1Yi5jb20vQmFrdGktU2lyZWdhci9pbWFnZXMvYmxvYi9tYXN0ZXIvbG9nby5wbmc/cmF3PXRydWUiKQ0KYGBgDQoNCiMgQmFiIDggRHVnYWFuIGRhbGFtIFJlZ3Jlc2kgTGluaWVyDQoNClNldGVsYWggbWVtYmFjYSBiYWIgaW5pLCBkaWhhcmFwa2FuIGFuZGEgYWthbiBtZW1pbGlraSBrZW1hbXB1YW4gdW50dWs6DQoNCiogTWVtYWhhbWkgZGlzdHJpYnVzaSBwZXJraXJhYW4gcmVncmVzaS4NCiogTWVtYnVhdCBwZXJraXJhYW4gaW50ZXJ2YWwgdW50dWsgcGFyYW1ldGVyIHJlZ3Jlc2ksIHJlc3BvbiByYXRhLXJhdGEsIGRhbiBwcmVkaWtzaS4NCiogVWppIHNpZ25pZmlrYW5zaSByZWdyZXNpLg0KDQpQYWRhIGJhZ2lhbiBha2hpciwga2l0YSBha2FuIG1lbmRlZmluaXNpa2FuIG1vZGVsIHJlZ3Jlc2kgbGluaWVyIHNlZGVyaGFuYSwNCg0KJCRZX2k9XGJldGFfMCtcYmV0YV8xeF8xK1xlcHNpbG9uX2kkJA0KDQpkaW1hbmEgJFxlcHNpbG9uX2lcYmFja3NpbSBOKDAsXHNpZ21hXjIpJC4gS2VtdWRpYW4ga2l0YSBtZW5nZ3VuYWthbiBwZW5nYW1hdGFuICQoeF9pLHlfaSkkLCB1bnR1ayAkaT0xLDIsLi4uLG4kLCB1bnR1ayBtZW5jYXJpIG5pbGFpICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIHlhbmcgZGltaW5pbWFsa2FuDQoNCiQkZihcYmV0YV8wLFxiZXRhXzEpPVxzdW1ebl97aT0xfSh5X2ktKFxiZXRhXzArXGJldGFfMXhfaSkpXjIkJA0KDQpLaXRhIG1lbWlsaWtpIG5pbGFpLW5pbGFpICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kIHlhbmcgdGVsYWgga2l0YSB0ZW11a2FuIHNlYmFnYWkgYmVyaWt1dDoNCg0KJCRcaGF0e1xiZXRhXzF9PVxmcmFje1Nfe3h5fX17U197eHh9fT1cZnJhY3tcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pKHlfaS1cYmFye3l9KX17XHN1bV5uX3tpPTF9KHhfaS1cYmFye3h9KV4yfSQkDQoNCiQkXGhhdHtcYmV0YV8wfT1cYmFye3l9LVxoYXR7XGJldGFfMX1cYmFye3h9JCQNCg0KS2l0YSBqdWdhIG1lbXBlcmtpcmFrYW4gJFxzaWdtYV4yJCBtZW5nZ3VuYWthbiAkc14yX2UkLiBBcnRpbnlhLCBraXRhIG1lbmVtdWthbiBiYWh3YSAkc19lJCBpbmkgYWRhbGFoIHBlcmtpcmFhbiBkYXJpICRcc2lnbWEkLCBkaW1hbmE6DQoNCiQkc19lPVJTRT1cc3FydHtcZnJhY3sxfXtuLTJ9XHN1bV5uX3tpPTF9ZV4yX2l9JCQNCg0KeWFuZyBtYW5hIFJTRSBtZXJ1cGFrYW4gc2luZ2thdGFuIGRhcmkgIlJlc2lkdWFsIFN0YW5kYXJkIEVycm9yIiAoS2VzYWxhaGFuIFN0YW5kYXIgU2lzYSkuDQoNCktldGlrYSBkaXRlcmFwa2FuIHBhZGEgZGF0YSBgY2Fyc2AsIGtpdGEgbWVtcGVyb2xlaCBoYXNpbCBzZWJhZ2FpIGJlcmlrdXQ6DQoNCmBgYHtyfQ0Kc3RvcF9kaXN0X21vZGVsID0gbG0oZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycykNCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNClBhZGEgYmFnaWFuIGFraGlyLCBraXRhIGhhbnlhIG1lbWJhaGFzIG5pbGFpLW5pbGFpIGBFc3RpbWF0ZWAsIGBSZXNpZHVhbCBTdGFuZGFyZCBFcnJvcmAsIGRhbiBgTXVsdGlwbGUgUi1zcXVhcmVkYC4gUGFkYSBiYWdpYW4gaW5pLCBraXRhIGFrYW4gbWVtYmFoYXMgc2VtdWEgaW5mb3JtYXNpIG1lbmdlbmFpIGBDb2VmZmljaWVudHNgIHNlcnRhIGBGLXN0YXRpc3RpY2AuDQoNCmBgYHtyfQ0KcGxvdChkaXN0IH4gc3BlZWQsIGRhdGEgPSBjYXJzLA0KICAgICB4bGFiID0gIlNwZWVkIChpbiBNaWxlcyBQZXIgSG91cikiLA0KICAgICB5bGFiID0gIlN0b3BwaW5nIERpc3RhbmNlIChpbiBGZWV0KSIsDQogICAgIG1haW4gPSAiU3RvcHBpbmcgRGlzdGFuY2UgdnMgU3BlZWQiLA0KICAgICBwY2ggID0gMjAsDQogICAgIGNleCAgPSAyLA0KICAgICBjb2wgID0gImdyZXkiKQ0KYWJsaW5lKHN0b3BfZGlzdF9tb2RlbCwgbHdkID0gNSwgY29sID0gImRhcmtvcmFuZ2UiKQ0KYGBgDQoNClVudHVrIG1lbXVsYWksIGtpdGEgYWthbiBtZW5jYXRhdCBiYWh3YSBhZGEgZWtzcHJlc2kgbGFpbiB5YW5nIHNldGFyYSB1bnR1ayAkU197eHl9JCB5YW5nIHRpZGFrIGtpdGEgbGloYXQgcGFkYSBiYWdpYW4gYWtoaXIsIA0KDQokJFNfe3h5fT1cc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pKHlfaS1cYmFye3l9KT1cc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH15X2kpJCQNCg0KSW5pIG11bmdraW4ga2VzZXRhcmFhbiB5YW5nIG1lbmdlanV0a2FuIChDb2JhbGFoIHVudHVrIG1lbWJ1a3Rpa2FubnlhKS4gTmFtdW4sIGhhbCB0ZXJzZWJ1dCBha2FuIHNhbmdhdCBtZW1iYW50dSB1bnR1ayBtZW5nZ2FtYmFya2FuIGtvbnNlcCBwYWRhIGJhZ2lhbiBpbmkuDQoNClBlcmhhdGlrYW4gYmFod2EsICRcaGF0e1xiZXRhXzF9JCBhZGFsYWggKipzdGF0aXN0aWsgc2FtcGVsKiogamlrYSBkaWhpdHVuZyBkZW5nYW4gZGF0YSBwZW5nYW1hdGFuIHlhbmcgZGl0dWxpcyBkaSBhdGFzLCBzZXBlcnRpICRcaGF0e1xiZXRhXzB9JC4NCg0KVGV0YXBpLCBkYWxhbSBiYWdpYW4gaW5pIGFrYW4gbGViaWggbXVkYWggdW50dWsgbWVuZ2d1bmFrYW4gJFxoYXR7XGJldGFfMX0kIGRhbiAkXGhhdHtcYmV0YV8wfSQgc2ViYWdhaSAqKnZhcmlhYmVsIGFjYWsqKiwgYWthbiB0ZXRhcGksIGtpdGEgYmVsdW0gbWVuZ2FtYXRpIG5pbGFpIHVudHVrIHNldGlhcCAkWV9pJC4gSmlrYSBkZW1pa2lhbiwga2l0YSBha2FuIG1lbmdndW5ha2FuIG5vdGFzaSB5YW5nIHNlZGlraXQgYmVyYmVkYSwgbWVuZ2dhbnRpa2FuICRZX2kkIGthcGl0YWwgZGVuZ2FuICR5X2kkIGh1cnVmIGtlY2lsLg0KDQokXGhhdHtcYmV0YV8xfT1cZnJhY3tcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pWV9pfXtcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pXjJ9JA0KDQokXGhhdHtcYmV0YV8wfT1cYmFye1l9LVxoYXR7XGJldGFfMX1cYmFye3h9JA0KDQpQYWRhIGJhZ2lhbiBha2hpciBraXRhIGJlcnBlbmRhcGF0IGJhaHdhIHBlcmtpcmFhbiBwYXJhbWV0ZXIgbW9kZWwgeWFuZyB0aWRhayBkaWtldGFodWkgaW5pICgkXGJldGFfMCQgZGFuICRcYmV0YV8xJCkgYWRhbGFoIGJhaWsga2FyZW5hIGtpdGEgbWVtcGVyb2xlaG55YSBkZW5nYW4gbWVtaW5pbWFsa2FuIGtlc2FsYWhhbi4gU2VrYXJhbmcga2l0YSBha2FuIG1lbWJhaGFzIHRlb3JlbWEgR2F1c3MtTWFya292IHlhbmcgbWVtYmF3YSBnYWdhc2FuIGluaSBsZWJpaCBsYW5qdXQsIG1lbnVuanVra2FuIGJhaHdhIHBlcmtpcmFhbiBpbmkgc2ViYW5hcm55YSBhZGFsYWggcGVya2lyYWFuIHlhbmcgInRlcmJhaWsiLCBkYXJpIHN1ZHV0IHBhbmRhbmcgdGVydGVudHUuDQoNCiMjIFRlb3JlbWEgR2F1c3MtTWFya292DQoNCioqVGVvcmVtYSBHYXVzcy1NYXJrb3YqKiBtZW1iZXJpdGFodSBraXRhIGJhaHdhIGtldGlrYSBtZW1wZXJraXJha2FuIHBhcmFtZXRlciBtb2RlbCByZWdyZXNpIGxpbmllciBzZWRlcmhhbmEgJFxiZXRhXzAkLCBkYW4gJFxiZXRhXzEkLCAkXGhhdHtcYmV0YV8wfSQgZGFuICRcaGF0e1xiZXRhXzF9JCB5YW5nIGtpdGEgZGFwYXRrYW4gYWRhbGFoICoqcGVya2lyYWFuIHRpZGFrIGJpYXMgbGluaWVyIHRlcmJhaWsqKi4gKEtvbmRpc2kgc2ViZW5hcm55YSB0ZW9yZW1hIEdhdXNzLU1hcmtvdiBsZWJpaCBzYW50YWkgZGFyaXBhZGEgbW9kZWwgU0xSKQ0KDQpTZWthcmFuZyBraXRhIGFrYW4gbWVtYmFoYXMgKmxpbmllciosICp0aWRhayBiaWFzKiwgZGFuICp0ZXJiYWlrKiB5YW5nIGJlcmh1YnVuZ2FuIGRlbmdhbiBwZXJraXJhYW4gaW5pLg0KDQojIyMgTGluaWVyDQoNCk1lbmdpbmdhdCBrZW1iYWxpLCBkYWxhbSBhdHVyYW4gU0xSLCBuaWxhaS1uaWxhaSAkeF9pJCBkaWFuZ2dhcCB0ZXRhcCBkYW4ganVtbGFobnlhIGRpa2V0YWh1aS4gS2VtdWRpYW4sIHBlcmtpcmFhbiAqKmxpbmllcioqIGFkYWxhaCBzYWxhaCBzYXR1IHlhbmcgZGFwYXQgZGl0dWxpcyBzZWJhZ2FpIGtvbWJpbmFzaSBsaW5pZXIgZGFyaSAkWV9pJC4gRGFsYW0ga2FzdXMgJFxoYXR7XGJldGFfMX0kIGtpdGEgZGFwYXRrYW4NCg0KJCRcaGF0e1xiZXRhXzF9PVxmcmFje1xzdW1ebl97aT0xfSh4X2ktXGJhcnt4fSlZX2l9e1xzdW1ebl97aT0xfSh4X2ktXGJhcnt4fSleMn09XHN1bV5uX3tpPTF9a19pWV9pPWtfMVlfMStrXzJZXzIrLi4uK2tfbllfbiQkDQoNCmRpbWFuYSAka19pPVxmcmFjeyh4X2ktXGJhcnt4fSl9e1xzdW1ebl97aT0xfSh4X2ktXGJhcnt4fSleMn0kLg0KDQpEZW5nYW4gY2FyYSB5YW5nIHNhbWEsIGtpdGEgZGFwYXQgbWVudW5qdWtrYW4gYmFod2EgJFxoYXR7XGJldGFfMH0kIGRhcGF0IGRpdHVsaXMgc2ViYWdhaSBrb21iaW5hc2kgbGluaWVyIGRhcmkgJFlfaSQuIEphZGksICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kIGtlZHVhbnlhIGFkYWxhaCBlc3RpbWF0b3IgbGluaWVyLg0KDQojIyMgVW5iaWFzDQoNClNla2FyYW5nIGtpdGEgdGFodSBiYWh3YSBwZXJraXJhYW4ga2l0YSBhZGFsYWggKmxpbmllciosIHNlYmVyYXBhIGJhZ3Vza2FoIHBlcmtpcmFhbiBpbmk/IFNhbGFoIHNhdHUgdWt1cmFuICJnb29kbmVzcyIgKGtlYmFpa2FuKSBkYXJpIHBlcmtpcmFhbiBpbmkgYWRhbGFoICoqYmlhcyoqLiBTZWNhcmEga2h1c3VzLCBraXRhIGxlYmloIHN1a2EgcGVya2lyYWFuIHlhbmcgKip0aWRhayBiaWFzKiosIHlhbmcgYXJ0aW55YSBuaWxhaSB5YW5nIGRpaGFyYXBrYW4gYWRhbGFoIHBhcmFtZXRlciB5YW5nIHNlZGFuZyBkaXBlcmtpcmFrYW4uDQoNClBhZGEga2FzdXMgcGVya2lyYWFuIHJlZ3Jlc2ksIGtpdGEgbWVtaWxpa2kNCg0KJCRFW1xoYXR7XGJldGFfMH1dPVxiZXRhXzAkJA0KJCRFW1xoYXR7XGJldGFfMX1dPVxiZXRhXzEkJA0KDQpJbmkgYXJ0aW55YSwga2V0aWthIG1lbmVtdWthbiBrb25kaXNpIG1vZGVsIFNMUiwgcmF0YS1yYXRhIHBlcmtpcmFhbiBraXRhIGFrYW4gYmVuYXIuIFRldGFwaSwgc2VwZXJ0aSB5YW5nIGtpdGEgbGloYXQgcGFkYSBiYWdpYW4gdGVyYWtoaXIga2V0aWthIG1lbnlpbXVsYXNpa2FuIGRhcmkgbW9kZWwgU0xSLCBpdHUgYnVrYW4gYmVyYXJ0aSBiYWh3YSBzZXRpYXAgcGVya2lyYWFuIGluZGl2aWR1YWwgYWthbiBiZW5hci4gSGFueWEgc2FqYSwgamlrYSBraXRhIG1lbmd1bGFuZ2kgcHJvc2VzbnlhIHNlYmFueWFrIHRhayB0ZXJoaW5nZ2EsIHJhdGEtcmF0YSBwZXJraXJhYW4gYWthbiBiZW5hci4NCg0KIyMjIFRoZSBCZXN0DQoNClNla2FyYW5nLCBqaWthIGtpdGEgbWVtYmF0YXNpIGRpcmkgdGVyaGFkYXAgcGVya2lyYWFuICpsaW5pZXIqIGRhbiAqdGlkYWsgYmlhcyosIGJhZ2FpbWFuYSBjYXJhIGtpdGEgbWVuZW50dWthbiBwZXJraXJhYW4gKnRlcmJhaWsqPyBQZXJraXJhYW4gZGVuZ2FuICoqdmFyaWFuc2kgbWluaW11bSoqLg0KDQpQZXJ0YW1hLCBwZXJoYXRpa2FuIGJhaHdhIHNhbmdhdCBtdWRhaCB1bnR1ayBtZW1idWF0IHBlcmtpcmFhbiB1bnR1ayAkXGJldGFfMSQgeWFuZyBtZW1pbGlraSB2YXJpYW5zaSBzYW5nYXQgcmVuZGFoLCB0ZXRhcGkgdGlkYWsgYmlhcy4gU2ViYWdhaSBjb250b2gsIHRlbnR1a2FuOg0KDQokJFxoYXR7XHRoZXRhfV97QkFEfT01JCQuDQoNCkxhbHUsIGthcmVuYSAkXGhhdHtcdGhldGF9X3tCQUR9JCBhZGFsYWggbmlsYWkga29uc3RhbiwgbWFrYQ0KDQokJFZhcltcaGF0e1x0aGV0YX1fe0JBRH1dPTAkJC4NCg0KTmFtdW4ga2FyZW5hLA0KDQokJEVbXGhhdHtcdGhldGF9X3tCQUR9XT01JCQNCg0Ka2l0YSBtZW5nYXRha2FuIGJhaHdhICRcaGF0e1x0aGV0YX1fe0JBRH0kIGFkYWxhaCBlc3RpbWF0b3IgYmlhcyBrZWN1YWxpICRcYmV0YV8xPTUkIHlhbmcgdGlkYWsgYWthbiBraXRhIGtldGFodWkgc2ViZWx1bW55YS4gSW5pIGFkYWxhaCBwZXJraXJhYW4geWFuZyBidXJ1ayAoa2VjdWFpIHNlY2FyYSBrZWJldHVsYW4gJFxiZXRhXzE9NSQpIG1lc2tpcHVuIG1lbWlsaWtpIGtlbXVuZ2tpbmFuIHZhcmlhbnNpIHRlcmtlY2lsLiBJbmkgYWRhbGFoIGJhZ2lhbiBkYXJpIGFsYXNhbiBraXRhIG1lbWJhdGFzaSBkaXJpIHBhZGEgcGVya2lyYWFuICp0aWRhayBiaWFzKi4gQXBhIGd1bmFueWEgc2VidWFoIHBlcmtpcmFhbiwgamlrYSBtZW1wZXJraXJha2FuIGt1YW50aXRhcyB5YW5nIHNhbGFoPw0KDQpTZWthcmFuZywgcGVydGFueWFhbiB3YWphcm55YSBhZGFsYWgsIGFwYSB2YXJpYW5zaSBkYXJpICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kPyBZYWl0dSwNCg0KJCRWYXJbXGhhdHtcYmV0YV8wfV09XHNpZ21hXjIoXGZyYWN7MX17bn0rXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19KSQkDQoNCiQkVmFyW1xoYXR7XGJldGFfMX1dPVxmcmFje1xzaWdtYV4yfXtTX3t4eH19JCQNCg0KSW5pIG1lbmd1a3VyIHZhcmlhYmlsaXRhcyBkYXJpIHBlcmtpcmFhbiBkaWthcmVuYWthbiBwZWx1YW5nIGFjYWsgc2VsYW1hIHBlbmdhbWJpbGFuIHNhbXBlbC4gQXBha2FoIGluaSAieWFuZyB0ZXJiYWlrIj8gQXBha2FoIHZhcmlhbnNpIHNla2VjaWwgaW5pIHlhbmcga2VtdW5na2luYW4ga2l0YSBiaXNhIGRhcGF0a2FuPyBBbmRhIGhhbnlhIHBlcmx1IG1lbXBlcmNheWFpIGFwYSB5YW5nIGthbWkga2F0YWthbiBrYXJlbmEgbWVudW5qdWtrYW4gYmFod2EgaW5pIGJlbmFyIGJlcmFkYSBkaSBsdWFyIGNha3VwYW4ga3Vyc3VzIGluaS4NCg0KIyMgRGlzdHJpYnVzaSBTYW1wbGluZw0KDQpTZWthcmFuZyBraXRhIHRlbGFoICJtZW5kZWZpbmlzaWthbiB1bGFuZyIgcGVya2lyYWFuIHVudHVrICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kIHNlYmFnYWkgdmFyaWFiZWwgYWNhaywga2l0YSBkYXBhdCBtZW5kaXNrdXNpa2FuICoqZGlzdHJpYnVzaSBzYW1wbGluZ255YSoqLCB5YW5nIG1lcnVwYWthbiBkaXN0cmlidXNpIGtldGlrYSBzdGF0aXN0aWsgZGlhbmdnYXAgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLg0KDQpLYXJlbmEgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQgYWRhbGFoIGtvbWJpbmFzaSBsaW5pZXIgZGFyaSAkWV9pJCBkYW4gc2V0aWFwICRZX2kkIGFkYWxhaCBkaXN0cmlidXNpIG5vcm1hbCwgbWFrYSAkXGhhdHtcYmV0YV8wfSQgZGFuICRcaGF0e1xiZXRhXzF9JCBqdWdhIG1lbmdpa3V0aSBkaXN0cmlidXNpIG5vcm1hbC4NCg0Ka2VtdWRpYW4sIGdhYnVuZ2thbiBzZW11YSBoYWwgZGkgYXRhcywga2l0YSBkYXBhdGthbiBkaXN0cmlidXNpICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kLg0KDQpVbnR1ayAkXGhhdHtcYmV0YV8xfSQga2l0YSB0dWxpc2thbiwNCiRcaGF0e1xiZXRhXzF9PVxmcmFje1Nfe3h5fX17U197eHh9fT1cZnJhY3tcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pWV9pfXtcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pXjJ9XGJhY2tzaW0gTihcYmV0YV8xLFxmcmFje1xzaWdtYV4yfXtcc3VtXm5fe2k9MX0oeF9pLVxiYXJ7eH0pXjJ9KSQNCg0KYXRhdSBsZWJpaCByaW5na2FzLA0KDQokJFxoYXR7XGJldGFfMX1cYmFja3NpbSBOKFxiZXRhXzEsXGZyYWN7XHNpZ21hXjJ9e1Nfe3h4fX0pJCQuDQoNCkRhbiB1bnR1ayAkXGhhdHtcYmV0YV8wfSQsDQoNCiQkXGhhdHtcYmV0YV8wfVxiYWNrc2ltIE4oXGJldGFfMCxcc2lnbWFeMihcZnJhY3sxfXtufStcZnJhY3tcYmFye3h9XjJ9e1Nfe3h4fX0pKSQkDQoNClNlamF1aCBpbmksIGtpdGEgZ2FnYWwgbWVtYnVrdGlrYW4gc2VqdW1sYWggaGFzaWxueWEuIEtpdGEgdGlkYWsgYWthbiBtZW5nZXJqYWthbiB0dXJ1bmFuIHlhbmcgbWVtYm9zYW5rYW4gZGFyaSBkaXN0cmlidXNpIHNhbXBlbCBpbmksIHRldGFwaSBraXRhIGFrYW4gbWVtYmVuYXJrYW4gaGFzaWxueWEgbWVuZ2d1bmFrYW4gc2ltdWxhc2kuDQoNCkNhdGF0YW4gdW50dWsgcGVtYmFjYSBzYWF0IGluaTogVHVydW5hbiBkYW4gcGVtYnVrdGlhbiBpbmkgbXVuZ2tpbiBiaXNhIGRpdGFtYmFoa2FuIGtlIGxhbXBpcmFuIHVudHVrIGtlbXVkaWFuIGhhcmkuIEFuZGEganVnYSBkYXBhdCBtZW5lbXVrYW4gaGFzaWwgaW5pIGRpIGhhbXBpciBzZW11YSBidWt1IHJlZ3Jlc2kgbGluaWVyIHNlZGVyaGFuYS4gRGkgVUlVQywgaGFzaWwgaW5pIGtlbXVuZ2tpbmFuIGJlc2FyIGFrYW4gZGlzYWppa2FuIGRpIFNUQVQgNDI0IGRhbiBTVEFUNDI1LiBOYW11biwga2FyZW5hIEFuZGEgdGlkYWsgZGltaW50YSB1bnR1ayBtZWxha3VrYW4gcGVudXJ1bmFuIGplbmlzIGluaSBwYWRhIGt1cnN1cyBrYWxpIGluaSwgbWFrYSB1bnR1ayBzYWF0IGluaSBoYXNpbCB0ZXJzZWJ1dCBiaXNhIGRpaGlsYW5na2FuLg0KDQojIyMgTWVueWltdWxhc2lrYW4gRGlzdHJpYnVzaSBTYW1wbGluZw0KDQpVbnR1ayBtZW1lcmlrc2EgaGFzaWwgZGkgYXRhcywga2l0YSBha2FuIG1lbnlpbXVsYXNpa2FuIHNhbXBlbCBkZW5nYW4gdWt1cmFuICRuPTEwMCQgZGFyaSBtb2RlbCBiZXJpa3V0DQoNCiQkWV9pPVxiZXRhXzArXGJldGFfMXhfaStcZXBzaWxvbl9pJCQNCg0KZGltYW5hICRcZXBzaWxvbl9pw6LCiMK8TigwLFxzaWdtYV4yKSQNCg0KKiAkXGJldGFfMD0zJA0KKiAkXGJldGFfMT02JA0KKiAkXHNpZ21hXjI9NCQNCg0KS2VtdWRpYW4sIGJlcmRhc2Fya2FuIGtldGVyYW5nYW4gZGkgYXRhcywga2l0YSBoYXJ1cyBtZW5lbXVrYW4gDQoNCiQkXGhhdHtcYmV0YV8xfVxiYWNrc2ltIE4oXGJldGFfMSxcZnJhY3tcc2lnbWFeMn17U197eHh9fSkkJA0KDQokJFxoYXR7XGJldGFfMH1cYmFja3NpbSBOKFxiZXRhXzAsXHNpZ21hXjIoXGZyYWN7MX17bn0rXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19KSkkJC4NCg0KUGVydGFtYSwga2l0YSBzZWJlbHVtbnlhIHBlcmx1IG1lbXV0dXNrYW4gYmVyYXBhIG5pbGFpICR4JCBraXRhIHVudHVrIHNpbXVsYXNpIGluaSwga2FyZW5hIG5pbGFpICR4JCBkYWxhbSBTTFIga3VhbnRpdGFzbnlhIGRpYW5nZ2FwIGRpa2V0YWh1aS4gUGlsaWhhbiBuaWxhaSAkeCQgdGlkYWsgdGV0YXAgYXRhdSBzZWxhbHUgYmVydWJhaC4gRGkgc2luaSBraXRhIGp1Z2EgbWVuZXRhcGthbiBzZWVkIHVudHVrIHBlbmdhY2FrYW4sIGRhbiBtZW5naGl0dW5nICRTX3t4eH0kIHlhbmcgYWthbiBraXRhIHBlcmx1a2FuIHVudHVrIHNlbGFuanV0bnlhLg0KDQpgYGB7cn0NCnNldC5zZWVkKDQyKQ0Kc2FtcGxlX3NpemUgPSAxMDAgIyB0aGlzIGlzIG4NCnggPSBzZXEoLTEsIDEsIGxlbmd0aCA9IHNhbXBsZV9zaXplKQ0KU3h4ID0gc3VtKCh4IC0gbWVhbih4KSkgXiAyKQ0KYGBgDQoNCktpdGEganVnYSBha2FuIG1lbXBlcmJhaWtpIG5pbGFpIHBhcmFtZXRlciBraXRhLg0KDQpgYGB7cn0NCmJldGFfMCA9IDMNCmJldGFfMSA9IDYNCnNpZ21hICA9IDINCmBgYA0KDQpEZW5nYW4gaW5mb3JtYXNpIGluaSwga2l0YSBtZW5nZXRhaHVpIGJhaHdhIGRpc3RyaWJ1c2kgc2FtcGxpbmcgc2VoYXJ1c255YToNCg0KYGBge3J9DQoodmFyX2JldGFfMV9oYXQgPSBzaWdtYSBeIDIgLyBTeHgpDQoodmFyX2JldGFfMF9oYXQgPSBzaWdtYSBeIDIgKiAoMSAvIHNhbXBsZV9zaXplICsgbWVhbih4KSBeIDIgLyBTeHgpKQ0KYGBgDQoNCiRcaGF0e1xiZXRhXzF9XGJhY2tzaW0gTig2LCAwLjExNzYyMzgpJA0KDQpkYW4NCg0KJFxoYXR7XGJldGFfMH1cYmFja3NpbSBOKDMsIDAuMDQpJA0KDQpZYWl0dSwNCg0KJEVbXGhhdHtcYmV0YV8xfV09NiQNCiRWYXJbXGhhdHtcYmV0YV8xfV09MC4xMTc2MjM4JA0KDQpkYW4NCg0KJEVbXGhhdHtcYmV0YV8wfV09MyQNCiRWYXJbXGhhdHtcYmV0YV8wfV09MC4wNCQNCg0KU2VrYXJhbmcga2l0YSBtZW55aW11bGFzaWthbiBkYXRhIGRhcmkgbW9kZWwgaW5pIHNlYmFueWFrIDEwLjAwMCBrYWxpLiBQZXJoYXRpa2FuIGJhaHdhIGNhcmEgaW5pIGJ1a2FuIG1lcnVwYWthbiBjYXJhIGBSYCB1bnR1ayBtZWxha3VrYW4gc2ltdWxhc2kuIEtpdGEgbWVsYWt1a2FuIHNpbXVsYXNpIGRlbmdhbiBjYXJhIGluaSB1bnR1ayBtZW5kYXBhdGthbiBrZWplbGFzYW4uIFNlYmFnYWkgY29udG9oLCBraXRhIGJpc2EgbWVuZ2d1bmFrYW4gZnVuZ3NpIGBzaW1fc2xyYCBkYXJpIGJhZ2lhbiBzZWJlbHVtbnlhLiBLaXRhIGp1Z2EgbWVueWltcGFuIHZhcmlhYmVsIGRpIGVudmlyb25tZW50IGdsb2JhbCwgYnVrYW4gbWVtYnVhdCBkYXRhIGZyYW1lIHVudHVrIHNldGlhcCBrdW1wdWxhbiBkYXRhIHNpbXVsYXNpIGJhcnUuDQoNCmBgYHtyfQ0KbnVtX3NhbXBsZXMgPSAxMDAwMA0KYmV0YV8wX2hhdHMgPSByZXAoMCwgbnVtX3NhbXBsZXMpDQpiZXRhXzFfaGF0cyA9IHJlcCgwLCBudW1fc2FtcGxlcykNCg0KZm9yIChpIGluIDE6bnVtX3NhbXBsZXMpIHsNCiAgZXBzID0gcm5vcm0oc2FtcGxlX3NpemUsIG1lYW4gPSAwLCBzZCA9IHNpZ21hKQ0KICB5ICAgPSBiZXRhXzAgKyBiZXRhXzEgKiB4ICsgZXBzDQogIA0KICBzaW1fbW9kZWwgPSBsbSh5IH4geCkNCiAgDQogIGJldGFfMF9oYXRzW2ldID0gY29lZihzaW1fbW9kZWwpWzFdDQogIGJldGFfMV9oYXRzW2ldID0gY29lZihzaW1fbW9kZWwpWzJdDQp9DQpgYGANCg0KU2V0aWFwIHNhYXQga2l0YSBtZW55aW11bGFzaWthbiBkYXRhLCBraXRhIG1lbXBlcm9sZWggbmlsYWkgcGVya2lyYWFuIGtvZWZpc2llbi4gVmFyaWFiZWwgYGJldGFfMF9oYXRzYCBkYW4gYGJldGFfMV9oYXRzYCBzZWthcmFuZyBtZW55aW1wYW4gMTAuMDAwIG5pbGFpIHNpbXVsYXNpIGRhcmkgbWFzaW5nLW1hc2luZyAkXGhhdHtcYmV0YV8wfSQgZGFuICRcaGF0e1xiZXRhXzF9JC4NCg0KS2l0YSB2ZXJpZmlrYXNpIGRpc3RyaWJ1c2kgJFxoYXR7XGJldGFfMX0kIHRlcmxlYmloIGRhaHVsdS4NCg0KYGBge3J9DQptZWFuKGJldGFfMV9oYXRzKSAjIHJhdGEtcmF0YSBlbXBpcmlzDQpiZXRhXzEgICAgICAgICAgICAjIHJhdGEtcmF0YSBzZWJlbmFybnlhDQp2YXIoYmV0YV8xX2hhdHMpICAjIHZhcmlhbnNpIGVtcGlyaXMNCnZhcl9iZXRhXzFfaGF0ICAgICMgdmFyaWFuc2kgc2ViZW5hcm55YQ0KYGBgDQoNCktpdGEgZGFwYXQgbGloYXQgYmFod2EgcmF0YS1yYXRhIG1hdXB1biB2YXJpYW5zZSBlbXBpcmlzIGRhbiByYXRhLXJhdGEgbWF1cHVuIHZhcmlhbnNpIHNlYmVuYXJueWEgc2FuZ2F0bGFoIG1pcmlwLiBLaXRhIGp1Z2EgYWthbiBtZW1lcmlrc2EgZGlzdHJpYnVzaSBlbXBpcmlzIGJlcnNpZmF0IG5vcm1hbC4gVW50dWsgbWVsYWt1a2FubnlhLCBraXRhIG1lbXBsb3QgYGJldGFfMV9oYXRzYCBrZSBoaXN0b2dyYW0sIGRhbiB0YW1iYWhrYW4ga3VydmEgdW50dWsgZGlzdHJpYnVzaSBzZWJlbmFybnlhIGRhcmkgJFxoYXR7XGJldGFfMX0kLiBLaXRhIGd1bmFrYW4gYHByb2IgPSBUUlVFYCB1bnR1ayBtZWxldGFra2FuIGhpc3RvZ3JhbSBwYWRhIHNrYWxhIHlhbmcgc2FtYSBkZW5nYW4ga3VydmEgbm9ybWFsLg0KDQpgYGB7cn0NCiMgY2F0YXQgYmFod2Ega2l0YSBwZXJsdSBtZW5nZ3VuYWthbiBwcm9iID0gVFJVRQ0KaGlzdChiZXRhXzFfaGF0cywgcHJvYiA9IFRSVUUsIGJyZWFrcyA9IDIwLCANCiAgICAgeGxhYiA9IGV4cHJlc3Npb24oaGF0KGJldGEpWzFdKSwgbWFpbiA9ICIiLCBib3JkZXIgPSAiZG9kZ2VyYmx1ZSIpDQpjdXJ2ZShkbm9ybSh4LCBtZWFuID0gYmV0YV8xLCBzZCA9IHNxcnQodmFyX2JldGFfMV9oYXQpKSwgDQogICAgICBjb2wgPSAiZGFya29yYW5nZSIsIGFkZCA9IFRSVUUsIGx3ZCA9IDMpDQpgYGANCg0KS2VtdWRpYW4sIGtpdGEgdWxhbmdpIHByb3Nlc255YSB1bnR1ayAkXGhhdHtcYmV0YV8wfSQNCg0KYGBge3J9DQptZWFuKGJldGFfMF9oYXRzKSAjIHJhdGEtcmF0YSBlbXBpcmlzDQpiZXRhXzAgICAgICAgICAgICAjIHJhdGEtcmF0YSBzZWJlbmFybnlhDQp2YXIoYmV0YV8wX2hhdHMpICAjIHZhcmlhbnNpIGVtcGlyaXMNCnZhcl9iZXRhXzBfaGF0ICAgICMgdmFyaWFuc2kgc2ViZW5hcm55YQ0KDQpoaXN0KGJldGFfMF9oYXRzLCBwcm9iID0gVFJVRSwgYnJlYWtzID0gMjUsIA0KICAgICB4bGFiID0gZXhwcmVzc2lvbihoYXQoYmV0YSlbMF0pLCBtYWluID0gIiIsIGJvcmRlciA9ICJkb2RnZXJibHVlIikNCmN1cnZlKGRub3JtKHgsIG1lYW4gPSBiZXRhXzAsIHNkID0gc3FydCh2YXJfYmV0YV8wX2hhdCkpLA0KICAgICAgY29sID0gImRhcmtvcmFuZ2UiLCBhZGQgPSBUUlVFLCBsd2QgPSAzKQ0KYGBgDQoNClBhZGEgcGVsYWphcmFuIHNpbXVsYXNpIGluaSwga2l0YSBoYW55YSBiaXNhIG1lbnlpbXVsYXNpa2FuIHNhbXBlbCBkZW5nYW4ganVtbGFoIHlhbmcgdGVyYmF0YXMuIFVudHVrIGJlbmFyLWJlbmFyIG1lbWVyaWtzYSBoYXNpbCBkaXN0cmlidXNpLCBraXRhIHBlcmx1IG1lbmdhbWF0aSBzYW1wZWwgZGVuZ2FuIGp1bWxhaCB5YW5nIHRhayB0ZXJiYXRhcy4gTmFtdW4sIHBsb3QgYmVyaWt1dCBpbmkgbWVuamVsYXNrYW4gYmFod2EgamlrYSBraXRhIG1lbGFuanV0a2FuIHByb3NlcyBzaW11bGFzaSBpbmksIG1ha2EgaGFzaWwgZW1waXJpc255YSBzZW1ha2luIG1lbmRla2F0aSBhcGEgeWFuZyBraXRhIGhhcmFwa2FuLg0KDQpgYGB7cn0NCnBhcihtYXIgPSBjKDUsIDUsIDEsIDEpKSAjIHNlc3VhaWthbiBtYXJnaW4gcGxvdCwgamlrYSB0aWRhayAidG9waSIgdGlkYWsgYWthbiBkaXRhbXBpbGthbg0KcGxvdChjdW1zdW0oYmV0YV8xX2hhdHMpIC8gKDE6bGVuZ3RoKGJldGFfMV9oYXRzKSksIHR5cGUgPSAibCIsIHlsaW0gPSBjKDUuOTUsIDYuMDUpLA0KICAgICB4bGFiID0gIk51bWJlciBvZiBTaW11bGF0aW9ucyIsDQogICAgIHlsYWIgPSBleHByZXNzaW9uKCJFbXBpcmljYWwgTWVhbiBvZiAiIH4gaGF0KGJldGEpWzFdKSwNCiAgICAgY29sICA9ICJkb2RnZXJibHVlIikNCmFibGluZShoID0gNiwgY29sID0gImRhcmtvcmFuZ2UiLCBsd2QgPSAyKQ0KYGBgDQoNCmBgYHtyfQ0KcGFyKG1hciA9IGMoNSwgNSwgMSwgMSkpICMgc2VzdWFpa2FuIG1hcmdpbiBwbG90LCBqaWthIHRpZGFrICJ0b3BpIiB0aWRhayBha2FuIGRpdGFtcGlsa2FuDQpwbG90KGN1bXN1bShiZXRhXzBfaGF0cykgLyAoMTpsZW5ndGgoYmV0YV8wX2hhdHMpKSwgdHlwZSA9ICJsIiwgeWxpbSA9IGMoMi45NSwgMy4wNSksDQogICAgIHhsYWIgPSAiTnVtYmVyIG9mIFNpbXVsYXRpb25zIiwNCiAgICAgeWxhYiA9IGV4cHJlc3Npb24oIkVtcGlyaWNhbCBNZWFuIG9mICIgfiBoYXQoYmV0YSlbMF0pLA0KICAgICBjb2wgID0gImRvZGdlcmJsdWUiKQ0KYWJsaW5lKGggPSAzLCBjb2wgPSAiZGFya29yYW5nZSIsIGx3ZCA9IDIpDQpgYGANCg0KIyMgU3RhbmRhciBFcnJvcg0KDQpKYWRpLCBzZWthcmFuZyBraXRhIHlha2luIHRlcmhhZGFwIGhhc2lsIGRpc3RyaWJ1c2kgYmVyaWt1dCwNCg0KJCRcaGF0e1xiZXRhXzB9XGJhY2tzaW0gTihcYmV0YV8wLFxzaWdtYV4yKFxmcmFjezF9e259K1xmcmFje1xiYXJ7eH1eMn17U197eHh9fSkpJCQNCiQkXGhhdHtcYmV0YV8xfVxiYWNrc2ltIE4oXGJldGFfMSxcZnJhY3tcc2lnbWFeMn17U197eHh9fSkkJA0KDQpEZW5nYW4gbWVuc3RhbmRhcmthbiBoYXNpbCBpbmksIGtpdGEgdGVtdWthbiBiYWh3YQ0KDQokJFxmcmFje1xoYXR7XGJldGFfMH0tXGJldGFfMH17U0RbXGhhdHtcYmV0YV8wfV19XGJhY2tzaW0gTigwLDEpJCQNCg0KZGFuDQoNCiQkXGZyYWN7XGhhdHtcYmV0YV8xfS1cYmV0YV8xfXtTRFtcaGF0e1xiZXRhXzF9XX1cYmFja3NpbSBOKDAsMSkkJA0KDQpkaW1hbmENCg0KJCRTRFtcaGF0e1xiZXRhXzB9XT1cc2lnbWFcc3FydHtcZnJhY3sxfXtufStcZnJhY3tcYmFye3h9XjJ9e1Nfe3h4fX19JCQNCg0KZGFuDQoNCiQkU0RbXGhhdHtcYmV0YV8xfV09XGZyYWN7XHNpZ21hfXtcc3FydHtTX3t4eH19fSQkLg0KDQpLYXJlbmEga2l0YSB0aWRhayBtZW5nZXRhaHVpICRcc2lnbWEkIGRhbGFtIHByYWt0aWtueWEsIGtpdGEgaGFydXMgbWVtcGVya2lyYWthbm55YSBtZW5nZ3VuYWthbiAkc19lJCwgeWFuZyBraXRhIG1hc3Vra2FuIGtlIGVrc3ByZXNpIHlhbmcgYWRhIHVudHVrIHN0YW5kYXIgZGV2aWFzaSBwZXJraXJhYW4ga2l0YS4NCg0KS2VkdWEgZWtzcHJlc2kgYmFydSBpbmkgZGlzZWJ1dCBkZW5nYW4gKiprZXNhbGFoYW4gc3RhbmRhcioqIHlhbmcgbWVydXBha2FuICpwZXJraXJhYW4qIHN0YW5kYXIgZGV2aWFzaSBkYXJpIGRpc3RyaWJ1c2kgc2FtcGxpbmcuDQoNCiQkU0VbXGhhdHtcYmV0YV8wfV09c19lXHNxcnR7XGZyYWN7MX17bn0rXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19fSQkDQokJFNFW1xoYXR7XGJldGFfMX1dPVxmcmFje3NfZX17XHNxcnR7U197eHh9fX0kJA0KDQpTZWthcmFuZywgamlrYSBraXRhIGJhZ2kgZGVuZ2FuIGtlc2FsYWhhbiBzdGFuZGFyIChidWthbiBzdGFuZGFyIGRldmlhc2kpLCBraXRhIGFrYW4gbWVtcGVyb2xlaCBoYXNpbCBiZXJpa3V0IHlhbmcgbWVtdW5na2lua2FuIHVudHVrIG1lbWJ1YXQgaW50ZXJ2YWwga2VwZXJjYXlhYW4gZGFuIG1lbGFrdWthbiB1amkgaGlwb3Rlc2lzLg0KDQoNCiQkXGZyYWN7XGhhdHtcYmV0YV8wfS1cYmV0YV8wfXtTRVtcaGF0e1xiZXRhXzB9XX1cYmFja3NpbSB0X3tuLTJ9JCQNCiQkXGZyYWN7XGhhdHtcYmV0YV8xfS1cYmV0YV8xfXtTRVtcaGF0e1xiZXRhXzF9XX1cYmFja3NpbSB0X3tuLTJ9JCQNCg0KVW50dWsgbWVsaWhhdG55YSwgcGVydGFtYS10YW1hIHBlcmhhdGlrYW4gYmFod2EsDQoNCiQkXGZyYWN7UlNTfXtcc2lnbWFeMn09XGZyYWN7KG4tMilzXjJfZX17XHNpZ21hXjJ9XGJhY2tzaW0gXGNoaV4yX3tuLTJ9JCQNCg0KRGFuIGp1Z2EgaW5nYXQga2VtYmFsaSB2YXJpYWJlbCAkVCQgZGlkZWZpbmlzaWthbiBzZWJhZ2FpLA0KDQokJFQ9XGZyYWN7Wn17XHNxcnR7XGZyYWN7XGNoaV4yX2R9e2R9fX0kJA0KDQptZW5naWt1dGkgZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuICRkJCwgZGltYW5hICRcY2hpXjJfZCQgYWRhbGFoIHZhcmlhYmVsIGFjYWsgJFxjaGleMiQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuICRkJC4NCg0KS2l0YSB0dWxpcywNCg0KJFRcYmFja3NpbSB0X2QkDQoNCnVudHVrIG1lbmdhdGFrYW4gYmFod2EgdmFyaWFiZWwgYWNhayAkVCQgbWVuZ2lrdXRpIGRpc3RyaWJ1c2kgJHQkIGRlbmdhbiBkZXJhamF0IGtlYmViYXNhbiAkZCQuDQoNCktlbXVkaWFuLCBraXRhIG1lbmdndW5ha2FuIHRyaWsga2xhc2lrICJkaWthbGlrYW4gZGVuZ2FuIDEiIGRhbiBiZWJlcmFwYSBwZW55dXN1bmFuIHVsYW5nIHVudHVrIHNhbXBhaSBrZXBhZGEsDQoNCiRcZnJhY3tcaGF0e1xiZXRhXzF9LVxiZXRhXzF9e1NFW1xoYXR7XGJldGFfMX1dfT1cZnJhY3tcaGF0e1xiZXRhXzF9LVxiZXRhXzF9e1xmcmFje3NfZX17XHNxcnR7U197eHh9fX19JA0KDQokPVxmcmFje1xoYXR7XGJldGFfMX0tXGJldGFfMX17XGZyYWN7c19lfXtcc3FydHtTX3t4eH19fX0uXGZyYWN7XGZyYWN7XHNpZ21hfXtcc3FydHtTX3t4eH19fX17XGZyYWN7XHNpZ21hfXtcc3FydHtTX3t4eH19fX0kDQoNCiQ9XGZyYWN7XGhhdHtcYmV0YV8xfS1cYmV0YV8xfXtcZnJhY3tcc2lnbWF9e1xzcXJ0e1Nfe3h4fX19fS5cZnJhY3tcZnJhY3tcc2lnbWF9e1xzcXJ0e1Nfe3h4fX19fXtcZnJhY3tzX2V9e1xzcXJ0e1Nfe3h4fX19fSQNCg0KJD1cZnJhY3tcaGF0e1xiZXRhXzF9LVxiZXRhXzF9e1xmcmFje1xzaWdtYX17XHNxcnR7U197eHh9fX19L1xzcXJ0e1xmcmFje3NeMl9lfXtcc2lnbWFeMn19JA0KDQokPVxmcmFje1xoYXR7XGJldGFfMX0tXGJldGFfMX17U0RbXGhhdHtcYmV0YV8xfV19L1xzcXJ0e1xmcmFje1xmcmFjeyhuLTIpc14yX2V9e1xzaWdtYV4yfX17bi0yfX1cYmFja3NpbSBcZnJhY3tafXtcc3FydHtcZnJhY3tcY2hpXjJfe24tMn19e24tMn19fVxiYWNrc2ltIHRfe24tMn0kDQoNCmRpbWFuYSAkWlxiYWNrc2ltIE4oMCwxKSQNCg0KSW5nYXRsYWggYmFod2EgZGlzdHJpYnVzaSAkdCQgbWlyaXAgZGVuZ2FuIG5vcm1hbCBzdGFuZGFyLCB0ZXRhcGkgZGVuZ2FuIGVrb3IgKHRhaWxzKSB5YW5nIGxlYmloIHBhZGF0LiBLZXRpa2EgZGVyamF0IGtlYmViYXNhbm55YSBtZW5pbmdrYXQsIGRpc3RyaWJ1c2kgJHQkIG1lbmphZGkgbGViaWggc2VwZXJ0aSBub3JtYWwgc3RhbmRhci4gRGkgYmF3YWggaW5pIGtpdGEgcGxvdCBkaXN0cmlidXNpIG5vcm1hbCBzdGFuZGFyIGRlbmdhbiBkdWEgY29udG9oIGRhcmkgZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgYmVyYmVkYS4gUGVyaGF0aWthbiBiYWdhaW1hbmEgZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgbGViaWggYmVzYXIgYWthbiBsZWJpaCBtaXJpcCBkZW5nYW4ga3VydmEgbm9ybWFsIHN0YW5kYXIuDQoNCmBgYHtyfQ0KIyBtZW5lbnR1a2FuIGdyaWQgZGFyaSBuaWxhaSB4DQp4ID0gc2VxKC00LCA0LCBsZW5ndGggPSAxMDApDQoNCiMgbWVtcGxvdCBrdXJ2YSB1bnR1ayBub3JtYWwgc3RhbmRhcg0KcGxvdCh4LCBkbm9ybSh4KSwgdHlwZSA9ICJsIiwgbHR5ID0gMSwgbHdkID0gMiwNCiAgICAgeGxhYiA9ICJ4IiwgeWxhYiA9ICJEZW5zaXR5IiwgbWFpbiA9ICJOb3JtYWwgdnMgdCBEaXN0cmlidXRpb25zIikNCiMgbWVuYW1iYWgga3VydmEgdW50dWsgZGlzdHJpYnVzaSB0DQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEpLCBsdHkgPSAzLCBsd2QgPSAyLCBjb2wgPSAiZGFya29yYW5nZSIpDQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEwKSwgbHR5ID0gMiwgbHdkID0gMiwgY29sID0gImRvZGdlcmJsdWUiKQ0KDQojIG1lbmFtYmFoIGxlZ2VuZA0KbGVnZW5kKCJ0b3ByaWdodCIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbnMiLA0KICAgICAgIGxlZ2VuZCA9IGMoInQsIGRmID0gMSIsICJ0LCBkZiA9IDEwIiwgIlN0YW5kYXJkIE5vcm1hbCIpLCANCiAgICAgICBsd2QgPSAyLCBsdHkgPSBjKDMsIDIsIDEpLCBjb2wgPSBjKCJkYXJrb3JhbmdlIiwgImRvZGdlcmJsdWUiLCAiYmxhY2siKSkNCmBgYA0KDQojIyBJbnRlcnZhbCBLZXBlcmNheWFhbiB1bnR1ayBLZW1pcmluZ2FuIGRhbiBJbnRlcnNlcA0KDQpJbmdhdCBiYWh3YSBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayByYXRhLXJhdGEgc2VyaW5nIGthbGkgYmVyYmVudHVrOg0KDQokRVNUw4LCsUNSSVQuU0UkDQoNCmF0YXUNCg0KJEVTVMOCwrFNQVJHSU4kDQoNCmRpbWFuYSBFU1QgbWVydXBha2FuIHBlcmtpcmFhbiB1bnR1ayBwYXJhbWV0ZXIgeWFuZyBkaWluZ2lua2FuLCBTRSBhZGFsYWgga2VzYWxhaGFuIHN0YW5kYXIgZGFyaSBwZXJraXJhYW4sIGRhbiBNQVJHSU4gPSBDUklULlNFLg0KDQpLZW11ZGlhbiwga2l0YSBkYXBhdCBtZW1idWF0IGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIG1lbmdndW5ha2FuDQoNCiRcaGF0e1xiZXRhXzB9w4LCsXRfe2EvMixuLTJ9LlNFW1xoYXR7XGJldGFfMH1dJA0KJFxoYXR7XGJldGFfMH3DgsKxdF97YS8yLG4tMn0uc19lXHNxcnR7XGZyYWN7MX17bn0rXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19fSQNCg0KZGFuDQoNCiRcaGF0e1xiZXRhXzF9w4LCsXRfe2EvMixuLTJ9LlNFW1xoYXR7XGJldGFfMX1dJA0KJFxoYXR7XGJldGFfMX3DgsKxdF97YS8yLG4tMn0uXGZyYWN7c19lfXtcc3FydHtTX3t4eH19fSQNCg0KZGltYW5hICR0X3thLzIsIG4tMn0kIGFkYWxhaCBuaWxhaSBrcml0aXMgc2VwZXJ0aSAkUCh0X3tuLTJ9PnRfe2EvMiwgbi0yKX09XGZyYWN7YX17Mn0kLg0KDQoNCiMjIFBlbmd1amlhbiBIaXBvdGVzaXMNCg0KSW5nYXQgYmFod2Egc3RhdGlzdGlrIHVqaSAkXHRleHR7VFN9JCB1bnR1ayBzYXJhbmEgcGVuZ3VqaWFuIHNlcmluZyBrYWxpIGJlcmJlbnR1azoNCg0KJFx0ZXh0e1RTfSA9IFxmcmFje1x0ZXh0e0VTVH0gLSBcdGV4dCB7SFlQfX0ge1x0ZXh0IHtTRX19JA0KDQpkaSBtYW5hICRcdGV4dCB7SFlQfSQgJFx0ZXh0IHtFU1R9JCBhZGFsYWggcGVya2lyYWFuIHVudHVrIHBhcmFtZXRlciB5YW5nIGRpbWluYXRpLCBhZGFsYWggbmlsYWkgaGlwb3Rlc2lzIGRhcmkgcGFyYW1ldGVyLCBkYW4gJFx0ZXh0e1NFfSQgYWRhbGFoIGtlc2FsYWhhbiBzdGFuZGFyIHBlcmtpcmFhbi4NCg0KSmFkaSwgdW50dWsgbWVuZ3VqaW55YQ0KDQokSF8wOiBcYmV0YV8wID0gXGJldGFfIHswMH0gXHF1YWQgXHRleHQge3ZzfSBccXVhZCBIXzE6IFxiZXRhXzAgXG5lcSBcYmV0YV8gezAwfSQNCg0Ka2FtaSBtZW5nZ3VuYWthbiBzdGF0aXN0aWsgdWppDQoNCiR0ID0gXGZyYWMge1xoYXQge1xiZXRhfSBfMCAtIFxiZXRhX3swMH19IHtcdGV4dCB7U0V9IFtcaGF0IHtcYmV0YX0gXzBdfSA9IFxmcmFjIHtcaGF0IHtcYmV0YX0gXzAtIFxiZXRhXyB7IDAwfX0ge3NfZSBcc3FydCB7XGZyYWMgezF9IHtufSArIFxmcmFjIHtcYmFyIHt4fSBeIDJ9IHtTXyB7eHh9fX19JA0KDQp5YW5nLCBkaSBiYXdhaCBoaXBvdGVzaXMgbm9sLCBtZW5naWt1dGkgYSB0IGRpc3RyaWJ1c2kgZGVuZ2FuICRuIC0gMiQgZGVyYWphdCBrZWJlYmFzYW4uIEtpdGEgZ3VuYWthbiAkXGJldGFfIHswMH0kIHVudHVrIG1lbnVuanVra2FuIG5pbGFpIHlhbmcgZGloaXBvdGVzaXNrYW4gZGFyaSAkXGJldGFfMC4kDQoNCkJlZ2l0dSBwdWxhIHVudHVrIG1lbmdldGVzDQoNCiRIXzA6IFxiZXRhXzEgPSBcYmV0YV8gezEwfSBccXVhZCBcdGV4dCB7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIFxiZXRhXyB7MTB9JA0KDQprYW1pIG1lbmdndW5ha2FuIHN0YXRpc3RpayB1amkNCg0KJHQgPSBcZnJhYyB7XGhhdCB7XGJldGF9IF8xLSBcYmV0YV8gezEwfX0ge1x0ZXh0IHtTRX0gW1xoYXQge1xiZXRhfSBfMV19ID0gXGZyYWMge1xoYXQge1xiZXRhfSBfMS0gXGJldGFfIHsgMTB9fSB7c19lIC8gXHNxcnQge1NfIHt4eH19fSQNCg0KeWFuZyBsYWdpLWxhZ2ksIGRpIGJhd2FoIGhpcG90ZXNpcyBub2wsIG1lbmdpa3V0aSBkaXN0cmlidXNpIHQgZGVuZ2FuICRuIC0gMiQgZGVyYWphdCBrZWJlYmFzYW4uIFNla2FyYW5nIGthbWkgbWVuZ2d1bmFrYW4gJFxiZXRhXyB7MTB9JCB1bnR1ayBtZW51bmp1a2thbiBuaWxhaSBoaXBvdGVzaXMgZGFyaSAkXGJldGFfMSQgLg0KDQoNCiMjIENvbnRvaCBjYXJzDQoNClNla2FyYW5nIGtpdGEga2VtYmFsaSBrZSBjYXJzIGNvbnRvaCBkYXJpIGJhZ2lhbiB0ZXJha2hpciB1bnR1ayBtZW5naWx1c3RyYXNpa2FuIGtvbnNlcCBpbmkuIEthbWkgcGVydGFtYS10YW1hIG1lbnllc3VhaWthbiBtb2RlbCBtZW5nZ3VuYWthbiBgbG0oKWAga2VtdWRpYW4gbWVuZ2d1bmFrYW4gYHN1bW1hcnkoKWAgdW50dWsgbWVsaWhhdCBoYXNpbCBzZWNhcmEgbGViaWggcmluY2kuDQoNCmBgYHtyfQ0Kc3RvcF9kaXN0X21vZGVsID0gbG0oZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycykNCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KDQpgYGANCg0KIyMjIFBlbmd1amlhbiBkYWxhbSBSDQoNClNla2FyYW5nIGtpdGEgYWthbiBtZW1iYWhhcyBoYXNpbCB5YW5nIGRpdGFtcGlsa2FuIHlhbmcgZGlzZWJ1dCBgQ29lZmZpY2llbnRzYC4gUGVydGFtYSwgaW5nYXRsYWggYmFod2Ega2l0YSBkYXBhdCBtZW5nZWtzdHJhayBpbmZvcm1hc2kgaW5pIHNlY2FyYSBsYW5nc3VuZy4NCg0KYGBge3J9DQpuYW1lcyhzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkpDQpgYGANCg0KYGBge3J9DQpzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRzDQpgYGANCg0KVGhlIGBuYW1lcygpYCBGdW5nc2kgbWVtYmVyaXRhaHUga2l0YSBhcGEgaW5mb3JtYXNpIHlhbmcgdGVyc2VkaWEsIGRhbiBrZW11ZGlhbiBraXRhIG1lbmdndW5ha2FuIG9wZXJhdG9yIGRhbiBgY29lZmZpY2llbnRgIHN1bnR1ayBtZW5nZWtzdHJhayBpbmZvcm1hc2kgeWFuZyBraXRhIHRlcnRhcmlrLiBEdWEgbmlsYWkgZGkgc2luaSBoYXJ1cyBzZWdlcmEgYWtyYWIuDQoNCiQkXGhhdCB7XGJldGF9IF8wID0gLTE3LjU3OTA5NDkkJA0KDQpkYW4NCg0KJCRcaGF0IHtcYmV0YX0gXzEgPSAzLjkzMjQwODgkJA0KDQp5YW5nIG1lcnVwYWthbiBwZXJraXJhYW4ga2FtaSB1bnR1ayBwYXJhbWV0ZXIgbW9kZWwgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQgLg0KDQpTZWthcmFuZyBtYXJpIGtpdGEgZm9rdXMgcGFkYSBrZWx1YXJhbiBiYXJpcyBrZWR1YSwgeWFuZyByZWxldmFuIGRlbmdhbiAkXGJldGFfMSQgLg0KDQpgYGB7cn0NCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHNbMixdDQpgYGANCg0KU2VrYWxpIGxhZ2ksIG5pbGFpIHBlcnRhbWEgYEVzdGltYXRlYCBhZGFsYWgNCg0KJCRcaGF0IHtcYmV0YX0gXzEgPSAzLjkzMjQwODguJCQNCg0KTmlsYWkga2VkdWEsIGBTdGQuIEVycm9yYCwgYWRhbGFoIGtlc2FsYWhhbiBzdGFuZGFyIGRhcmkgJFxoYXQge1xiZXRhfSBfMSQsDQoNCiRcdGV4dCB7U0V9IFtcaGF0IHtcYmV0YX0gXzFdID0gXGZyYWMge3NfZX0ge1xzcXJ0IHtTXyB7eHh9fX0gPSAwLDQxNTUxMjguJA0KDQpOaWxhaSBrZXRpZ2EsIGB0LXZhbHVlYCwgYWRhbGFoIG5pbGFpIHN0YXRpc3RpayB1amkgdW50dWsgcGVuZ3VqaWFuICRIXzA6IFxiZXRhXzEgPSAwIFxxdWFkICB7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIDAgLCQNCg0KJHQgPSBcZnJhYyB7XGhhdCB7XGJldGF9IF8xLTB9IHtcdGV4dCB7U0V9IFtcaGF0IHtcYmV0YX0gXzFdfSA9IFxmcmFjIHtcaGF0IHtcYmV0YX0gXzEtMH0ge3NfZSAvIFxzcXJ0IHtTXyB7eHh9fX0gPSA5LDQ2Mzk5LiQNCg0KVGVyYWtoaXIsICRQcig+fHR8KSQuIGJlcmkga2FtaSBuaWxhaSBwIGRhcmkgcGVuZ3VqaWFuIGl0dS4NCg0KJFx0ZXh0IHtwLXZhbHVlfSA9IDEsNDg5ODM2NSBcdGltZXMgMTAgXiB7LSAxMn0kDQoNClBlcmhhdGlrYW4gZGkgc2luaSwga2FtaSBzZWNhcmEga2h1c3VzIG1lbmd1amkgYXBha2FoICRcYmV0YV8xID0gMCQgYXRhdSB0aWRhayAuDQoNCkJhcmlzIHBlcnRhbWEga2VsdWFyYW4gbWVsYXBvcmthbiBuaWxhaSB5YW5nIHNhbWEsIHRldGFwaSB1bnR1ayAkXGJldGFfMCQgLg0KDQpgYGB7cn0NCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHNbMSxdDQpgYGANCg0KU2luZ2thdG55YSwga29kZSBiZXJpa3V0IG1lbnlpbXBhbiBpbmZvcm1hc2kgYHN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKWNvZWZmaWNpZW50c2AgZGFsYW0gdmFyaWFiZWwgYmFydSANCmAoc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mbylgLCBsYWx1IG1lbmdla3N0cmFrIHNldGlhcCBlbGVtZW4gbWVuamFkaSB2YXJpYWJlbCBiYXJ1IHlhbmcgbWVuamVsYXNrYW4gaW5mb3JtYXNpIHlhbmcgZGlrYW5kdW5nbnlhLg0KDQpgYGB7cn0NCnN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm8gPSBzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRzDQoNCmJldGFfMF9oYXQgICAgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMSwgMV0gIyBFc3RpbWF0ZQ0KYmV0YV8wX2hhdF9zZSAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1sxLCAyXSAjIFN0ZC4gRXJyb3INCmJldGFfMF9oYXRfdCAgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMSwgM10gIyB0IHZhbHVlDQpiZXRhXzBfaGF0X3B2YWwgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzEsIDRdICMgUHIoPnx0fCkNCg0KYmV0YV8xX2hhdCAgICAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1syLCAxXSAjIEVzdGltYXRlDQpiZXRhXzFfaGF0X3NlICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzIsIDJdICMgU3RkLiBFcnJvcg0KYmV0YV8xX2hhdF90ICAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1syLCAzXSAjIHQgdmFsdWUNCmJldGFfMV9oYXRfcHZhbCA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMiwgNF0gIyBQcig+fHR8KQ0KYGBgDQoNCktlbXVkaWFuIGtpdGEgZGFwYXQgbWVtdmVyaWZpa2FzaSBiZWJlcmFwYSBla3NwcmVzaSB5YW5nIHNldGFyYTogc3RhdGlzdGlrIHVqaSB0IHVudHVrICRcaGF0IHtcYmV0YX0gXzEkIGRhbiBuaWxhaSBwIGR1YSBzaXNpIHlhbmcgdGVya2FpdCBkZW5nYW4gc3RhdGlzdGlrIHVqaSB0ZXJzZWJ1dC4NCg0KYGBge3J9DQooYmV0YV8xX2hhdCAtIDApIC8gYmV0YV8xX2hhdF9zZQ0KYGBgDQoNCmBgYHtyfQ0KYmV0YV8xX2hhdF90DQpgYGANCg0KYGBge3J9DQoyICogcHQoYWJzKGJldGFfMV9oYXRfdCksIGRmID0gbGVuZ3RoKHJlc2lkKHN0b3BfZGlzdF9tb2RlbCkpIC0gMiwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQoNCmBgYHtyfQ0KYmV0YV8xX2hhdF9wdmFsDQpgYGANCg0KIyMjICBTaWduaWZpa2Fuc2kgUmVncmVzaSwgVWppLXQNCg0KS2FtaSBiZXJoZW50aSBzZWplbmFrIHVudHVrIG1lbWJhaGFzIHBlbnRpbmdueWEgdWppIHJlZ3Jlc2kgLiBQZXJ0YW1hLCBwZXJoYXRpa2FuIGJhaHdhIGJlcmRhc2Fya2FuIGhhc2lsIGRpc3RyaWJ1c2kgZGkgYXRhcywga2FtaSBkYXBhdCBtZW5ndWppICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIHRlcmhhZGFwIG5pbGFpIHRlcnRlbnR1LCBkYW4gbWVsYWt1a2FuIHBlbmd1amlhbiBzYXR1IGRhbiBkdWEgc2lzaS4NCg0KTmFtdW4sIHNhdHUgdGVzIHlhbmcgc2FuZ2F0IHNwZXNpZmlrLA0KDQokSF8wOiBcYmV0YV8xID0gMCBccXVhZCBcdGV4dCB7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIDAkDQoNCnBhbGluZyBzZXJpbmcgZGlndW5ha2FuLiBNYXJpIGtpdGEgcGlraXJrYW4gcGVuZ3VqaWFuIGluaSBkYWxhbSBrYWl0YW5ueWEgZGVuZ2FuIG1vZGVsIHJlZ3Jlc2kgbGluaWVyIHNlZGVyaGFuYSwNCg0KJFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kuJA0KDQpKaWthIGthbWkgbWVuZ2FzdW1zaWthbiBoaXBvdGVzaXMgbm9sIGJlbmFyLCBtYWthICRcYmV0YV8xID0gMCQgZGFuIGthbWkgbWVtaWxpa2kgbW9kZWwsDQoNCiRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faS4kDQoNCkRhbGFtIG1vZGVsIGluaSwgcmVzcG9uIHRpZGFrIGJlcmdhbnR1bmcgcGFkYSBwcmVkaWt0b3IuIEphZGkga2l0YSBiaXNhIG1lbWlraXJrYW4gdGVzIGluaSBkZW5nYW4gY2FyYSBiZXJpa3V0LA0KDQoqIERpIGJhd2FoICRIXzAkIHRpZGFrIGFkYSBodWJ1bmdhbiBsaW5pZXIgeWFuZyBzaWduaWZpa2FuIGFudGFyYSAkeCQgZGFuICR5JCAuDQoqIERpIGJhd2FoICRIXzEkIGFkYSBodWJ1bmdhbiBsaW5pZXIgeWFuZyBzaWduaWZpa2FuIGFudGFyYSAkeCQgZGFuICR5JCAuDQoNClVudHVrIGNvbnRvaCBgY2Fyc2AsDQoNCiogRGkgYmF3YWggJEhfMCQgdGlkYWsgYWRhIGh1YnVuZ2FuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuDQoqIERpIGJhd2FoICRIXzEkIGFkYSBodWJ1bmdhbiBsaW5pZXIgeWFuZyBzaWduaWZpa2FuIGFudGFyYSBrZWNlcGF0YW4gZGFuIGphcmFrIGJlcmhlbnRpLg0KDQpTZWthbGkgbGFnaSwgcGVuZ3VqaWFuIGl0dSB0ZXJsaWhhdCBwYWRhIGtlbHVhcmFuIGRhcmkgYHN1bW1hcnkoKWAsDQoNCiRcdGV4dCB7bmlsYWktcH0gPSAxLDQ4OTgzNjUgXHRpbWVzIDEwIF4gey0gMTJ9LiQNCg0KRGVuZ2FuIG5pbGFpIHAgeWFuZyBzYW5nYXQgcmVuZGFoIGluaSwga2FtaSBha2FuIG1lbm9sYWsgaGlwb3Rlc2lzIG5vbCBwYWRhIHRpbmdrYXQgJFxhbHBoYSQgeWFuZyBtYXN1ayBha2FsICwgbWlzYWxueWEgJFxhbHBoYSA9IDAsMDEkIC4gSmFkaSBrYW1pIGthdGFrYW4gYWRhIGh1YnVuZ2FuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuIFBlcmhhdGlrYW4gYmFod2Ega2FtaSBtZW5la2Fua2FuIGxpbmllciAuDQoNCkRhbGFtIHBsb3QgZGF0YSBzaW11bGFzaSBpbmksIGtpdGEgbWVsaWhhdCBodWJ1bmdhbiB5YW5nIGplbGFzIGFudGFyYSAkeCQgZGFuICR5JCAsIG5hbXVuIGluaSBidWthbiBodWJ1bmdhbiBsaW5pZXIuIEppa2Ega2l0YSBtZW1hc3Vra2FuIGdhcmlzIGtlIGRhdGEgaW5pLCBpdHUgc2FuZ2F0IGRhdGFyLiBIYXNpbCBwZW5ndWppYW4gdW50dWsgJEhfMDogXGJldGFfMSA9IDAgXHF1YWQgXHRleHR7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIDAkIG1lbWJlcmlrYW4gbmlsYWkgcCB5YW5nIGJlc2FyLCBkYWxhbSBoYWwgaW5pICQwLDc1NjQ1NDgkICwgamFkaSBrYW1pIGdhZ2FsIG1lbm9sYWsgZGFuIG1lbmdhdGFrYW4gYmFod2EgdGlkYWsgYWRhIGh1YnVuZ2FuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhICR4JCBkYW4gJHkkIC4gS2l0YSBha2FuIG1lbGloYXQgbmFudGkgYmFnYWltYW5hIG1lbnllc3VhaWthbiBrdXJ2YSBrZSBkYXRhIGluaSBtZW5nZ3VuYWthbiBtb2RlbCAibGluaWVyIiwgdGV0YXBpIHVudHVrIHNhYXQgaW5pLCBzYWRhcmkgYmFod2EgcGVuZ3VqaWFuICRIXzA6IFxiZXRhXzEgPSAwXHF1YWQgIFx0ZXh0e3ZzfSBccXVhZCBIXzE6IFxiZXRhXzEgXG5lcSAwJCBoYW55YSBkYXBhdCBtZW5kZXRla3NpIGh1YnVuZ2FuIGdhcmlzIGx1cnVzLg0KDQojIyMgSW50ZXJ2YWwgS2V5YWtpbmFuIGRhbGFtIFINCg0KRGVuZ2FuIG1lbmdndW5ha2FuIFJraXRhIGJpc2EgZGVuZ2FuIG11ZGFoIG1lbmRhcGF0a2FuIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIC4NCg0KYGBge3J9DQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KQ0KYGBgDQoNCkluaSBzZWNhcmEgb3RvbWF0aXMgbWVuZ2hpdHVuZyA5OSUgaW50ZXJ2YWwga2V5YWtpbmFuIHVudHVrICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkICwgYmFyaXMgcGVydGFtYSB1bnR1ayAkXGJldGFfMCQgLCBiYXJpcyBrZWR1YSB1bnR1ayAkXGJldGFfMSQgLg0KDQpTZWJhZ2FpIGNhcnNjb250b2ggc2FhdCBtZW5hZnNpcmthbiBpbnRlcnZhbCBpbmksIGthbWkga2F0YWthbiwga2FtaSA5OSUgeWFraW4gYmFod2EgdW50dWsgcGVuaW5na2F0YW4ga2VjZXBhdGFuIDEgbWlsIHBlciBqYW0sIHBlbmluZ2thdGFuIHJhdGEtcmF0YSBqYXJhayBiZXJoZW50aSBhZGFsYWggYW50YXJhICQyLjgxNzkxODckIGRhbiAkNS4wNDY4OTg4JCBrYWtpLCB5YW5nIG1lcnVwYWthbiBpbnRlcnZhbCB1bnR1ayAkXGJldGFfMSQgLg0KDQpQZXJoYXRpa2FuIGJhaHdhIGludGVydmFsIGtleWFraW5hbiA5OSUgaW5pIHRpZGFrIG1lbmdhbmR1bmcgbmlsYWkgaGlwb3Rlc2lzIDAuIEthcmVuYSB0aWRhayBtZW5nYW5kdW5nIDAsIGluaSBzZXRhcmEgZGVuZ2FuIG1lbm9sYWsgcGVuZ3VqaWFuICRIXzA6IFxiZXRhXzEgPSAwJCB2cyAkSF8xOiBcYmV0YV8xIFxuZXEgMCQgZGkgJFxhbHBoYSA9IDAuMDEkICwgeWFuZyB0ZWxhaCBrYW1pIGxpaGF0IHNlYmVsdW1ueWEuDQoNCkFuZGEgaGFydXMgbWVuY3VyaWdhaSBpbnRlcnZhbCBrZXlha2luYW4gdW50dWsgJFxiZXRhXzAkICwga2FyZW5hIG1lbmNha3VwIG5pbGFpIG5lZ2F0aWYsIHlhbmcgc2VzdWFpIGRlbmdhbiBqYXJhayBoZW50aSBuZWdhdGlmLiBTZWNhcmEgdGVrbmlzIGludGVycHJldGFzaW55YSBhZGFsYWggYmFod2Ega2FtaSA5OSUgeWFraW4gYmFod2EgamFyYWsgYmVyaGVudGkgcmF0YS1yYXRhIHNlYnVhaCBtb2JpbCB5YW5nIG1lbmVtcHVoIGphcmFrIDAgbWlsIHBlciBqYW0gYWRhbGFoIGFudGFyYSAtMzUuNzA2NjEwMyBkYW4gMC41NDg0MjA1IGtha2ksIHRldGFwaSBrYW1pIHRpZGFrIGJlZ2l0dSBwZXJjYXlhIGl0dSwga2FyZW5hIGthbWkgYmVuYXItYmVuYXIgeWFraW4gYmFod2EgaXR1IGFrYW4gdGVyamFkaS4gbm9uLW5lZ2F0aWYuDQoNCkNhdGF0YW4sIGtpdGEgZGFwYXQgbWVuZ2Vrc3RyYWsgbmlsYWkgdGVydGVudHUgZGFyaSBrZWx1YXJhbiBpbmkgZGVuZ2FuIGJlYmVyYXBhIGNhcmEuIEtvZGUgaW5pIHRpZGFrIGRpamFsYW5rYW4sIGRhbiBzZWJhZ2FpIGdhbnRpbnlhLCBBbmRhIGhhcnVzIG1lbWVyaWtzYSBodWJ1bmdhbm55YSBkZW5nYW4ga2VsdWFyYW4ga29kZSBkaSBhdGFzLg0KDQpgYGB7cn0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzEsXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMSwgMV0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzEsIDJdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgcGFybSA9ICIoSW50ZXJjZXB0KSIsIGxldmVsID0gMC45OSkNCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzIsXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMiwgMV0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzIsIDJdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgcGFybSA9ICJzcGVlZCIsIGxldmVsID0gMC45OSkNCmBgYA0KDQpLYW1pIGp1Z2EgZGFwYXQgbWVtdmVyaWZpa2FzaSBiYWh3YSBrYWxrdWxhc2kgeWFuZyBiZWtlcmphIFJ1bnR1ayBpbnRlcnZhbCAkXGJldGFfMSQgLg0KDQpgYGB7cn0NCiMgc3RvcmUgZXN0aW1hdGUNCmJldGFfMV9oYXQgPSBjb2VmKHN0b3BfZGlzdF9tb2RlbClbMl0NCg0KIyBzdG9yZSBzdGFuZGFyZCBlcnJvcg0KYmV0YV8xX2hhdF9zZSA9IHN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHNbMiwgMl0NCg0KIyBjYWxjdWxhdGUgY3JpdGljYWwgdmFsdWUgZm9yIHR3by1zaWRlZCA5OSUgQ0kNCmNyaXQgPSBxdCgwLjk5NSwgZGYgPSBsZW5ndGgocmVzaWQoc3RvcF9kaXN0X21vZGVsKSkgLSAyKQ0KDQojIGVzdCAtIG1hcmdpbiwgZXN0ICsgbWFyZ2luDQpjKGJldGFfMV9oYXQgLSBjcml0ICogYmV0YV8xX2hhdF9zZSwgYmV0YV8xX2hhdCArIGNyaXQgKiBiZXRhXzFfaGF0X3NlKQ0KYGBgDQoNCiMjIEludGVydmFsIEtleWFraW5hbiB1bnR1ayBSZXNwb24gUmF0YS1yYXRhDQoNClNlbGFpbiBpbnRlcnZhbCBrZXlha2luYW4gdW50dWsgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQgLCBhZGEgZHVhIHBlcmtpcmFhbiBpbnRlcnZhbCB1bXVtIGxhaW5ueWEgeWFuZyBkaWd1bmFrYW4gZGVuZ2FuIHJlZ3Jlc2kuIFlhbmcgcGVydGFtYSBkaXNlYnV0IGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbnMgcmF0YS1yYXRhIC4gU2VyaW5na2FsaSwga2l0YSBtZW5naW5naW5rYW4gZXN0aW1hc2kgaW50ZXJ2YWwgdW50dWsgbWVhbiwgJEUgW1kgXG1pZCBYID0geF0kIHVudHVrIG5pbGFpICR4JCB0ZXJ0ZW50dSAuDQoNCkRhbGFtIHNpdHVhc2kgaW5pIGtpdGEgbWVuZ2d1bmFrYW4gJFxoYXQge3l9ICh4KSQgc2ViYWdhaSBwZXJraXJhYW4ga2l0YSB1bnR1ayAkRSBbWSBcbWlkIFggPSB4XSQgLiBLYW1pIG1lbmd1YmFoIHNlZGlraXQgbm90YXNpIGthbWkgdW50dWsgbWVtcGVyamVsYXMgYmFod2EgbmlsYWkgcHJlZGlrc2kgYWRhbGFoIGZ1bmdzaSBkYXJpIG5pbGFpIHggLg0KDQokJFxoYXQge3l9ICh4KSA9IFxoYXQge1xiZXRhfSBfMCArIFxoYXQge1xiZXRhfSBfMSB4JCQNCg0KSW5nYXQgaXR1LA0KDQokJFx0ZXh0IHtFfSBbWSBcbWlkIFggPSB4XSA9IFxiZXRhXzAgKyBcYmV0YV8xIHguJCQNCg0KSmFkaSwgJFxoYXQge3l9ICh4KSQgYWRhbGFoIHBlcmtpcmFhbiB5YW5nIGJhaWsga2FyZW5hIHRpZGFrIGJpYXM6DQoNCiQkXHRleHQge0V9IFtcaGF0IHt5fSAoeCldID0gXGJldGFfMCArIFxiZXRhXzEgeC4kJA0KDQpLYW1pIGtlbXVkaWFuIGJpc2EgbWVuZGFwYXRrYW4sDQoNCiQkXHRleHR7VmFyfVtcaGF0e3l9KHgpXSA9IFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX1ccmlnaHQpLiQkDQoNClNlcGVydGkgcGVya2lyYWFuIGxhaW4geWFuZyB0ZWxhaCBraXRhIGxpaGF0LCAkXGhhdCB7eX0gKHgpJCBqdWdhIG1lbmdpa3V0aSBkaXN0cmlidXNpIG5vcm1hbC4gS2FyZW5hICRcaGF0IHtcYmV0YX0gXzAkIGRhbiAkXGhhdCB7XGJldGF9IF8xJCBhZGFsYWgga29tYmluYXNpIGxpbmllciBkYXJpIHZhcmlhYmVsIGFjYWsgbm9ybWFsLCAkXGhhdCB7eX0gKHgpJCBqdWdhLg0KDQokJFxoYXR7eX0oeCkgXHNpbSBOIFxsZWZ0KFxiZXRhXzAgKyBcYmV0YV8xIHgsIFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX1ccmlnaHQpIFxyaWdodCkkJA0KDQpEYW4gdGVyYWtoaXIsIGthcmVuYSBraXRhIHBlcmx1IG1lbXBlcmtpcmFrYW4gdmFyaWFucyBpbmksIGtpdGEgc2FtcGFpIHBhZGEga2VzYWxhaGFuIHN0YW5kYXIgZGFyaSBwZXJraXJhYW4ga2l0YSwNCg0KJCRcdGV4dCB7U0V9IFtcaGF0IHt5fSAoeCldID0gc19lIFxzcXJ0IHtcZnJhYyB7MX0ge259ICsgXGZyYWMgeyh4LSBcYmFyIHt4fSkgXiAyfSB7U18ge3h4fX0gfS4kJA0KDQpLYW1pIGtlbXVkaWFuIGRhcGF0IG1lbmdndW5ha2FuIGluaSB1bnR1ayBtZW5lbXVrYW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgcmVzcG9ucyByYXRhLXJhdGEsDQoNCiQkXGhhdCB7eX0gKHgpIFxwbSB0IF8ge1xhbHBoYSAvIDIsIG4gLSAyfSBcY2RvdCBzX2UgXHNxcnQge1xmcmFjIHsxfSB7bn0gKyBcZnJhYyB7KHgtIFxiYXIge3h9KSBeIDIgfSB7U18ge3h4fX19JCQNCg0KVW50dWsgbWVuZW11a2FuIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbnMgcmF0YS1yYXRhIG1lbmdndW5ha2FuIGBSYCwga2FtaSBtZW5nZ3VuYWthbiBgcHJlZGljdCgpYCBmdW5nc2kuIEthbWkgbWVtYmVyaWthbiBmdW5nc2kgbW9kZWwgcGFzIGthbWkgc2VydGEgZGF0YSBiYXJ1LCBkaXNpbXBhbiBzZWJhZ2FpIGJpbmdrYWkgZGF0YS4gKEluaSBwZW50aW5nLCBhZ2FyIGBSYCBtZW5nZXRhaHVpIG5hbWEgdmFyaWFiZWwgcHJlZGlrdG9yLikgRGkgc2luaSwga2FtaSBtZW5lbXVrYW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgamFyYWsgYmVyaGVudGkgcmF0YS1yYXRhIHNhYXQgbW9iaWwgbWVsYWp1IDUgbWlsIHBlciBqYW0gZGFuIHNhYXQgbW9iaWwgbWVsYWp1IDIxIG1pbCBwZXIgamFtLg0KDQpgYGB7cn0NCm5ld19zcGVlZHMgPSBkYXRhLmZyYW1lKHNwZWVkID0gYyg1LCAyMSkpDQpwcmVkaWN0KHN0b3BfZGlzdF9tb2RlbCwgbmV3ZGF0YSA9IG5ld19zcGVlZHMsIA0KICAgICAgICBpbnRlcnZhbCA9IGMoImNvbmZpZGVuY2UiKSwgbGV2ZWwgPSAwLjk5KQ0KYGBgDQoNCiMjIEludGVydmFsIFByZWRpa3NpIHVudHVrIFBlbmdhbWF0YW4gQmFydQ0KDQpUZXJrYWRhbmcga2l0YSBtZW5naW5naW5rYW4gZXN0aW1hc2kgaW50ZXJ2YWwgdW50dWsgcGVuZ2FtYXRhbiBiYXJ1LCAkWSQgLCB1bnR1ayBuaWxhaSAkeCQgdGVydGVudHUgLiBJbmkgc2FuZ2F0IG1pcmlwIGRlbmdhbiBpbnRlcnZhbCB1bnR1ayByZXNwb25zIHJhdGEtcmF0YSwgJFx0ZXh0IHtFfSBbWSBcbWlkIFggPSB4XSQgLCB0ZXRhcGkgYmVyYmVkYSBkYWxhbSBzYXR1IGhhbCB5YW5nIHNhbmdhdCBwZW50aW5nLg0KDQpUZWJha2FuIHRlcmJhaWsga2FtaSB1bnR1ayBvYnNlcnZhc2kgYmFydSBtYXNpaCAkXGhhdCB7eX0gKHgpJCAuIFBlcmtpcmFhbiByYXRhLXJhdGEgbWFzaWggbWVydXBha2FuIHByZWRpa3NpIHRlcmJhaWsgeWFuZyBiaXNhIGtpdGEgYnVhdC4gUGVyYmVkYWFubnlhIHRlcmxldGFrIHBhZGEganVtbGFoIHZhcmlhYmlsaXRhcy4gS2l0YSB0YWh1IGJhaHdhIHBlbmdhbWF0YW4gYWthbiBiZXJ2YXJpYXNpIHRlbnRhbmcgZ2FyaXMgcmVncmVzaSB5YW5nIHNlYmVuYXJueWEgbWVudXJ1dCBkaXN0cmlidXNpICROICgwLCBcc2lnbWEgXiAyKSQgLiBLYXJlbmEgaXR1IGthbWkgbWVuYW1iYWhrYW4gZmFrdG9yIHRhbWJhaGFuICRcc2lnbWFeMiQga2UgdmFyaWFiaWxpdGFzIHBlcmtpcmFhbiBrYW1pIHVudHVrIG1lbmplbGFza2FuIHZhcmlhYmlsaXRhcyBwZW5nYW1hdGFuIHRlbnRhbmcgZ2FyaXMgcmVncmVzaS4NCg0KJFxiZWdpbnthbGlnbmVkfVx0ZXh0e1Zhcn1bXGhhdHt5fSh4KSArIFxlcHNpbG9uXSAmPSBcdGV4dHtWYXJ9W1xoYXR7eX0oeCldICsgXHRleHR7VmFyfVtcZXBzaWxvbl0gXFxbMmV4XSBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufStcZnJhY3soeC1cYmFye3h9KV4yfXtTX3t4eH19XHJpZ2h0KSArIFxzaWdtYV4yIFxcWzJleF0gXHNpZ21hXjIgXGxlZnQoMSArIFxmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX1ccmlnaHQpXGVuZHthbGlnbmVkfSQNCg0KJFxoYXR7eX0oeCkgKyBcZXBzaWxvbiBcc2ltIE4gXGxlZnQoXGJldGFfMCArIFxiZXRhXzEgeCwgXCBcc2lnbWFeMiBcbGVmdCgxICsgXGZyYWN7MX17bn0rXGZyYWN7KHgtXGJhcnt4fSleMn17U197eHh9fVxyaWdodCkgXHJpZ2h0KSQNCg0KJFx0ZXh0e1NFfVtcaGF0e3l9KHgpICsgXGVwc2lsb25dID0gc19lIFxzcXJ0ezEgKyBcZnJhY3sxfXtufStcZnJhY3soeC1cYmFye3h9KV4yfXtTX3t4eH19fSQNCg0KS2FtaSBrZW11ZGlhbiBkYXBhdCBtZW5lbXVrYW4gaW50ZXJ2YWwgcHJlZGlrc2kgbWVuZ2d1bmFrYW4sDQoNCiRcaGF0IHt5fSAoeCkgXHBtIHQgXyB7XGFscGhhIC8gMiwgbiAtIDJ9IFxjZG90IHNfZSBcc3FydCB7MSArIFxmcmFjIHsxfSB7bn0gKyBcZnJhYyB7KHgtIFxiYXIge3h9KSBeIDJ9IHtTXyB7eHh9fX0uJA0KDQpVbnR1ayBtZW5naGl0dW5nIGluaSB1bnR1ayBzYXR1IHNldCBwb2luIGRhbGFtIFJwZW1iZXJpdGFodWFuIGhhbnlhIGFkYSBzZWRpa2l0IHBlcnViYWhhbiBkYWxhbSBzaW50YWtzIGRhcmkgbWVuZW11a2FuIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbiByYXRhLXJhdGEuDQoNCmBgYHtyfQ0KcHJlZGljdChzdG9wX2Rpc3RfbW9kZWwsIG5ld2RhdGEgPSBuZXdfc3BlZWRzLCANCiAgICAgICAgaW50ZXJ2YWwgPSBjKCJwcmVkaWN0aW9uIiksIGxldmVsID0gMC45OSkNCmBgYA0KDQpQZXJoYXRpa2FuIGp1Z2EgYmFod2Ega2VkdWEgaW50ZXJ2YWwgaW5pIGxlYmloIGxlYmFyIGRhcmlwYWRhIGludGVydmFsIGtlcGVyY2F5YWFuIHlhbmcgc2VzdWFpIHVudHVrIHJlc3BvbnMgcmF0YS1yYXRhLg0KDQojIyBQaXRhIEtleWFraW5hbiBkYW4gUHJlZGlrc2kNCg0KU2VyaW5na2FsaSBrYW1pIGluZ2luIG1lbXBsb3Qga2VkdWEgaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgcmVzcG9ucyByYXRhLXJhdGEgZGFuIGludGVydmFsIHByZWRpa3NpIHVudHVrIHNlbXVhIGtlbXVuZ2tpbmFuIG5pbGFpICR4JCAuIEthbWkgbWVueWVidXRueWEgYmFuZCBrZXBlcmNheWFhbiBkYW4gcHJlZGlrc2kuDQoNCmBgYHtyfQ0Kc3BlZWRfZ3JpZCA9IHNlcShtaW4oY2FycyRzcGVlZCksIG1heChjYXJzJHNwZWVkKSwgYnkgPSAwLjAxKQ0KZGlzdF9jaV9iYW5kID0gcHJlZGljdChzdG9wX2Rpc3RfbW9kZWwsIA0KICAgICAgICAgICAgICAgICAgICAgICBuZXdkYXRhID0gZGF0YS5mcmFtZShzcGVlZCA9IHNwZWVkX2dyaWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIsIGxldmVsID0gMC45OSkNCmRpc3RfcGlfYmFuZCA9IHByZWRpY3Qoc3RvcF9kaXN0X21vZGVsLCANCiAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YSA9IGRhdGEuZnJhbWUoc3BlZWQgPSBzcGVlZF9ncmlkKSwgDQogICAgICAgICAgICAgICAgICAgICAgIGludGVydmFsID0gInByZWRpY3Rpb24iLCBsZXZlbCA9IDAuOTkpIA0KDQpwbG90KGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMsDQogICAgIHhsYWIgPSAiU3BlZWQgKGluIE1pbGVzIFBlciBIb3VyKSIsDQogICAgIHlsYWIgPSAiU3RvcHBpbmcgRGlzdGFuY2UgKGluIEZlZXQpIiwNCiAgICAgbWFpbiA9ICJTdG9wcGluZyBEaXN0YW5jZSB2cyBTcGVlZCIsDQogICAgIHBjaCAgPSAyMCwNCiAgICAgY2V4ICA9IDIsDQogICAgIGNvbCAgPSAiZ3JleSIsDQogICAgIHlsaW0gPSBjKG1pbihkaXN0X3BpX2JhbmQpLCBtYXgoZGlzdF9waV9iYW5kKSkpDQphYmxpbmUoc3RvcF9kaXN0X21vZGVsLCBsd2QgPSA1LCBjb2wgPSAiZGFya29yYW5nZSIpDQoNCmxpbmVzKHNwZWVkX2dyaWQsIGRpc3RfY2lfYmFuZFssImx3ciJdLCBjb2wgPSAiZG9kZ2VyYmx1ZSIsIGx3ZCA9IDMsIGx0eSA9IDIpDQpsaW5lcyhzcGVlZF9ncmlkLCBkaXN0X2NpX2JhbmRbLCJ1cHIiXSwgY29sID0gImRvZGdlcmJsdWUiLCBsd2QgPSAzLCBsdHkgPSAyKQ0KbGluZXMoc3BlZWRfZ3JpZCwgZGlzdF9waV9iYW5kWywibHdyIl0sIGNvbCA9ICJkb2RnZXJibHVlIiwgbHdkID0gMywgbHR5ID0gMykNCmxpbmVzKHNwZWVkX2dyaWQsIGRpc3RfcGlfYmFuZFssInVwciJdLCBjb2wgPSAiZG9kZ2VyYmx1ZSIsIGx3ZCA9IDMsIGx0eSA9IDMpDQpwb2ludHMobWVhbihjYXJzJHNwZWVkKSwgbWVhbihjYXJzJGRpc3QpLCBwY2ggPSAiKyIsIGNleCA9IDMpDQpgYGANCg0KQmViZXJhcGEgaGFsIHlhbmcgcGVybHUgZGlwZXJoYXRpa2FuOg0KDQoqIEthbWkgbWVuZ2d1bmFrYW4gYHlsaW1gIGFyZ3VtZW4gdW50dWsgbWVyZWdhbmdrYW4gc3VtYnUgLSB5IGRhcmkgcGxvdCwga2FyZW5hIHBpdGEgbWVtcGVycGFuamFuZyBsZWJpaCBqYXVoIGRhcmkgdGl0aWsgcG9pbnQuDQoNCiogS2FtaSBtZW5hbWJhaGthbiB0aXRpayBkaSB0aXRpayAkKFxiYXIge3h9LCBcYmFyIHt5fSkkIC4NCiAgKiBJbmkgYWRhbGFoIHRpdGlrIHlhbmcgYWthbiBzZWxhbHUgZGlsZXdhdGkgZ2FyaXMgcmVncmVzaSAuIChQaWtpcmthbiBhbGFzYW5ueWEuKQ0KICAqIEluaSBhZGFsYWggdGl0aWsgZGkgbWFuYSBiYW5kIGtleWFraW5hbiBkYW4gcHJlZGlrc2kgbWVuamFkaSB5YW5nIHRlcnNlbXBpdC4gTGloYXRsYWgga2VzYWxhaGFuIHN0YW5kYXIga2VkdWFueWEgdW50dWsgbWVtYWhhbWkgbWVuZ2FwYS4NCg0KKlBpdGEgcHJlZGlrc2kgKHRpdGlrLXRpdGlrIGJpcnUpIGt1cmFuZyBtZWxlbmdrdW5nIGRpYmFuZGluZ2thbiBkZW5nYW4gcGl0YSBrZXBlcmNheWFhbiAoYmlydSBwdXR1cy1wdXR1cykuIEluaSBhZGFsYWggaGFzaWwgZGFyaSBmYWt0b3IgdGFtYmFoYW4gJFxzaWdtYSBeIDIkIHlhbmcgZGl0YW1iYWhrYW4ga2UgdmFyaWFuIHBhZGEgbmlsYWkgJHgkIGFwYSBwdW4gLg0KDQoNCiMjIFNpZ25pZmlrYW5zaSBSZWdyZXNpLCBVamktRg0KDQpEYWxhbSBrYXN1cyByZWdyZXNpIGxpbmllciBzZWRlcmhhbmEsIHVqaSAkdCQgdW50dWsgc2lnbmlmaWthbnNpIHJlZ3Jlc2kgc2FtYSBkZW5nYW4gdWppIGxhaW4sIHVqaSAkRiQgdW50dWsgc2lnbmlmaWthbnNpIHJlZ3Jlc2kuIEtlc2V0YXJhYW4gaW5pIGhhbnlhIGFrYW4gYmVuYXIgdW50dWsgcmVncmVzaSBsaW5pZXIgc2VkZXJoYW5hLCBkYW4gZGkgYmFnaWFuIHNlbGFuanV0bnlhIGtpdGEgaGFueWEgYWthbiBtZW5nZ3VuYWthbiB1amkgJEYkIHVudHVrIHNpZ25pZmlrYW5zaSByZWdyZXNpLg0KDQpJbmdhdCBkYXJpIGJhZ2lhbiB0ZXJha2hpciBkZWtvbXBvc2lzaSB2YXJpYW5zIHlhbmcga2l0YSBsaWhhdCBzZWJlbHVtIG1lbmdoaXR1bmcgJFIgXiAyJCAsDQoNCiQkXHN1bV8ge2kgPSAxfSBeIHtufSAoeV9pIC0gXGJhciB7eX0pIF4gMiA9IFxzdW1fIHtpID0gMX0gXiB7bn0gKHlfaSAtIFxoYXQge3l9IF9pKSBeIDIgKyBcc3VtXyB7IGkgPSAxfSBeIHtufSAoXGhhdCB7eX0gX2kgLSBcYmFyIHt5fSkgXiAyLCQkDQoNCmF0YXUsIHNpbmdrYXRueWEsDQoNCiQkXHRleHQge1NTVH0gPSBcdGV4dCB7U1NFfSArIFx0ZXh0IHtTU1JlZ30uJCQNCg0KVW50dWsgbWVuZ2VtYmFuZ2thbiB1amkgJEYkLCBraXRhIGFrYW4gbWVuZ2F0dXIgaW5mb3JtYXNpIGluaSBrZSBkYWxhbSB0YWJlbCAqKkFOT1ZBKiosDQoNClN1bWJlciAgICAgICAgICAgICAgSnVtbGFoIEt1YWRyYXQgICAgICAgICAgRGVyYWphdCBLZWJlYmFzYW4gICAgUmF0YS1yYXRhIEt1YWRyYXQgICAgICAgICAgICAgRg0KLS0tLS0tLSAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAtLS0tLS0tLS0tLS0tLS0tLSAgIC0tLS0tLS0tLS0tLS0tLS0tLS0gICAtLS0tLS0tLS0tLS0tLS0tLS0tDQpSZWdyZXNpICAgICAkXHN1bV5uX3tpPTF9KFxoYXR7eX1faS15KV4yJCAgICAgICAgICAgMSAgICAgICAgICAgICRcZnJhY3tTU1JlZ317MX0kICAgICRcZnJhY3tNU1JlZ317TVNFfSQNCkVyb3IgICAgICAgJFxzdW1ebl97aT0xfSh5X2ktXGhhdHt5fV9pKV4yJCAgICAgICAgJG4tMiQgICAgICAgICAkXGZyYWN7U1NSZWd9e24tMn0kICAgDQpUb3RhbCAgICAgICAgICAkXHN1bV5uX3tpPTF9KHlfaS15KV4yJCAgICAgICAgICAgICRuLTEkDQoNCkFOT1ZBLCBhdGF1IEFuYWxpc2lzIFZhcmlhbnMgYWthbiBtZW5qYWRpIGtvbnNlcCB5YW5nIHNlcmluZyBraXRhIGJhaGFzIGRhbGFtIGt1cnN1cyBpbmkuIFVudHVrIHNhYXQgaW5pLCBraXRhIGFrYW4gZm9rdXMgcGFkYSBoYXNpbCB0YWJlbCwgeWFpdHUgc3RhdGlzdGlrICRGJCAsDQoNCiQkRiA9IFxmcmFjIHtcc3VtXyB7aSA9IDF9IF4ge259IChcaGF0IHt5fSBfaSAtIFxiYXIge3l9KSBeIDIvMX0ge1xzdW1fIHtpID0gMX0gXiB7bn0gKHlfaSAtIFxoYXQge3l9IF9pKSBeIDIgLyAobiAtIDIpfSBcc2ltIEZfIHsxLCBuIC0gMn0kJA0KDQp5YW5nIG1lbmdpa3V0aSBkaXN0cmlidXNpICRGJCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gJDEkIGRhbiAkbiAtIDIkIGRpIGJhd2FoIGhpcG90ZXNpcyBub2wuIFNlYnVhaCAkRiQgZGlzdHJpYnVzaSBhZGFsYWggZGlzdHJpYnVzaSBrb250aW51IHlhbmcgbWVuZ2FtYmlsIG5pbGFpLW5pbGFpIHBvc2l0aWYgaGFueWEgZGFuIG1lbWlsaWtpIGR1YSBwYXJhbWV0ZXIsIHlhbmcgbWVydXBha2FuIGR1YSBkZXJhamF0IGtlYmViYXNhbi4NCg0KSW5nYXQsIGRhbGFtIGFydGkgZGFyaSB1amkgcmVncmVzaSwgJFkkIHRpZGFrIHRpZGFrIHRlcmdhbnR1bmcgcGFkYSAkeCQgZGkgaGlwb3Rlc2lzIG5vbC4NCg0KJEhfMDogXGJldGFfMSA9IDAgXHF1YWQgXHF1YWQgWV9pID0gXGJldGFfMCArIFxlcHNpbG9uX2kkDQoNClNlZGFuZ2thbiBwYWRhIGhpcG90ZXNpcyBhbHRlcm5hdGlmICRZJCBtdW5na2luIGJlcmdhbnR1bmcgcGFkYSAkeCQgLg0KDQokSF8xOiBcYmV0YV8xIFxuZXEgMCBccXVhZCBccXVhZCBZX2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X2kgKyBcZXBzaWxvbl9pJA0KDQpLaXRhIGRhcGF0IG1lbmdndW5ha2FuIHN0YXRpc3RpayBGIHVudHVrIG1lbGFrdWthbiB0ZXMgaW5pLg0KDQokJEYgPSBcZnJhY3tcc3VtX3tpPTF9XntufShcaGF0e3l9X2kgLSBcYmFye3l9KV4yIC8gMX17XHN1bV97aT0xfV57bn0oeV9pIC0gXGhhdHt5fV9pKV4yIC8gKG4gLSAyKX0kJA0KDQpTZWNhcmEga2h1c3VzLCBrYW1pIGFrYW4gbWVub2xhayBub2wga2V0aWthIHN0YXRpc3RpayAkRiQgYmVzYXIsIHlhaXR1LCBrZXRpa2EgYWRhIGtlbXVuZ2tpbmFuIHJlbmRhaCBiYWh3YSBwZW5nYW1hdGFuIGJpc2EgZGF0YW5nIGRhcmkgbW9kZWwgbm9sIHNlY2FyYSBrZWJldHVsYW4uIEthbWkgYWthbiBtZW5naGl0dW5nIG5pbGFpIHAgZGVuZ2FuIG1lbmdndW5ha2FuIFINCg0KVW50dWsgbWVsYWt1a2FuIHVqaSAkRiQgZGkgUiBBbmRhIGRhcGF0IG1lbGloYXQgYmFyaXMgdGVyYWtoaXIgZGFyaSBrZWx1YXJhbiBkYXJpIHBhbmdnaWxhbiB5YW5nIG1lbWJlcmlrYW4gbmlsYWkgc3RhdGlzdGlrIHVqaSwgZGVyYWphdCBrZWJlYmFzYW4geWFuZyByZWxldmFuLCBzZXJ0YSBuaWxhaSBwIGRhcmkgcGVuZ3VqaWFuLiBgc3VtbWFyeSgpYCB5YW5nIGRpc2VidXQgYEYtc3RhdGlzdGljYA0KDQpgYGB7cn0NCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNClNlbGFpbiBpdHUsIEFuZGEgZGFwYXQgbWVuZ2d1bmFrYW4gYGFub3ZhKClgIGZ1bmdzaSB0ZXJzZWJ1dCB1bnR1ayBtZW5hbXBpbGthbiBpbmZvcm1hc2kgZGFsYW0gdGFiZWwgQU5PVkEuDQoNCmBgYHtyfQ0KYW5vdmEoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNCkluaSBqdWdhIG1lbWJlcmlrYW4gbmlsYWkgcCB1bnR1ayBwZW5ndWppYW4uIEFuZGEgaGFydXMgbWVtcGVyaGF0aWthbiBiYWh3YSBuaWxhaS1wIGRhcmkgdWppICR0JCBhZGFsYWggc2FtYS4gQW5kYSBtdW5na2luIGp1Z2EgbWVtcGVyaGF0aWthbiBiYWh3YSBuaWxhaSBzdGF0aXN0aWsgdWppIHVudHVrIHVqaSAkdCQgLCAkOS40NjM5OSQgLCBkYXBhdCBkaWt1YWRyYXRrYW4gdW50dWsgbWVuZGFwYXRrYW4gbmlsYWkgc3RhdGlzdGlrICRGJCAsICQ4OS41NjcxMDY1JCAuDQoNClBlcmhhdGlrYW4gYmFod2EgYWRhIGNhcmEgbGFpbiB5YW5nIHNldGFyYSB1bnR1ayBtZWxha3VrYW4gaW5pIFIsIGRpIG1hbmEga2l0YSBha2FuIHNlcmluZyBrZW1iYWxpIHVudHVrIG1lbWJhbmRpbmdrYW4gZHVhIG1vZGVsLg0KDQpgYGB7cn0NCmFub3ZhKGxtKGRpc3QgfiAxLCBkYXRhID0gY2FycyksIGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpKQ0KYGBgDQoNClBlcm55YXRhYW4gbW9kZWwgbG0oZGlzdCB+IDEsIGRhdGEgPSBjYXJzKSBtZW5lcmFwa2FuIG1vZGVsICRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faSQga2UgZGF0YSBtb2JpbC4gUGVyaGF0aWthbiBiYWh3YSAkXGhhdCB7eX0gPSBcYmFyIHt5fSQga2V0aWthICRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faSQgLg0KDQpQZXJueWF0YWFuIG1vZGVsIGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpIG1lbmVyYXBrYW4gbW9kZWwgJFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kkIC4NCg0KS2FtaSBrZW11ZGlhbiBkYXBhdCBtZW5nYW5nZ2FwIHBlbmdndW5hYW4gaW5pIGFub3ZhKClzZWJhZ2FpIHBlcmJhbmRpbmdhbiBsYW5nc3VuZyBrZWR1YSBtb2RlbC4gKFBlcmhhdGlrYW4gYmFod2Ega2l0YSBtZW5kYXBhdGthbiBuaWxhaSBwIHlhbmcgc2FtYSBsYWdpLik=