1 Inferensi dalam Regresi Linier

Setelah membaca bagian ini, kita akan dapat:

  1. Memahami distribusi perkiraan regresi.
  2. Membuat perkiraan interval untuk parameter regresi, respon rata-rata, dan prediksi.
  3. Dapat melakukan uji signifikansi regresi

Model regresi linear yang sederhana, biasa di modelkan sebagai berikut, \[Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\]

dimana \(\epsilon_i \sim N(0, \sigma^2)\). Contohnya saja kita akan menggunakan observasi \((x_i,y_i)\) untuk \(i = 1,2,..., n\). Dalam menentukan nilai \(\beta_0\) dan \(\beta_1\) model yang akan diminimalkan adalah, \[f(\beta_0, \beta_1) = \sum_{i = 1}^{n}(y_i - (\beta_0 + \beta_1 x_i))^2\] Lalu, kita masukkan nilai-nilai \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) yang sudah kita temukan, \[\begin{aligned} \hat{\beta}_1 &= \frac{S_{xy}}{S_{xx}} = \frac{\sum_{i = 1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sum_{i = 1}^{n}(x_i - \bar{x})^2}\\ \hat{\beta}_0 &= \bar{y} - \hat{\beta}_1 \bar{x}.\end{aligned}\] Kita juga akan memperkirakan \(\sigma ^2\) menggunakan \(s_e^2\). Dengan begitu, kita menemukan \(s_e^2\) adalah sama dengan kita memperkirakan \(\sigma\), dimana; \[s_e = \text{RSE} = \sqrt{\frac{1}{n - 2}\sum_{i = 1}^n e_i^2}\] biasa kita menyebutnya RSE (Residual Standar Error).

Ketika kita aplikasikan perhitungan ke data “cars”, kita memperoleh hasilnya 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

Bagian bawah dari hasil coding, akan membahas nilai-nilai dari Estimate, RSE (Residual Standar Error) dan Multiple R-squared.

Selanjutnya, kita akan membahas semua informasi di bawah Koefisien dan juga F-Statistics, dengan coding sebagai berikut;

Untuk memulai, kita akan mencatat bahwa ada ekspresi lain yang setara untuk \(S_{xy}\) yang tidak kita lihat di bagian terakhir; \[S_{xy}= \sum_{i = 1}^{n}(x_i - \bar{x})(y_i - \bar{y}) = \sum_{i = 1}^{n}(x_i - \bar{x}) y_i\] Mungkin ini kesetaraan yang tidak terduga. Namun, ini akan berguna untuk mengilustrasikan konsep di bagian ini.

Perhatikan bahwa, \(\hat{\beta}_1\) adalah contoh statistik jika dihitung dengan data observasi seperti yang tertulis di atas \(\hat{\beta}_0\).

Pada bagian ini akan lebih mudah untuk menggunakan keduanya \(\hat{\beta}_1\) dan \(\hat{\beta}_0\) sebagai variabel acak. Kita harus mengamati masing-masing nilai \(Y_i\). Maka, kita akan menggunakan notasi yang sedikit berbeda, menggantikan huruf kapital \(Y_i\) dengan huruf kecil \(y_i\).

\[\begin{aligned} \hat{\beta}_1 &= \frac{\sum_{i = 1}^{n}(x_i - \bar{x}) Y_i}{\sum_{i = 1}^{n}(x_i - \bar{x})^2} \\ \hat{\beta}_0 &= \bar{Y} - \hat{\beta}_1 \bar{x} \end{aligned}\]

Berhubungan dengan bagian terakhir, kita berpendapat bahwa perkiraan parameter model yang tidak diketahui ini \(\beta_0\) dan \(\beta_1\) bagus karena kami mendapatkannya dengan meminimalkan kesalahan. Sekarang kita akan membahas teorema Gauss-Markov yang membawa gagasan ini lebih jauh, yang menunjukkan bahwa perkiraan ini sebenarnya adalah perkiraan “terbaik”, dari sudut pandang tertentu.

1.1 Teorema Gauss - Markov

Teorema Gauss - Markov memberitahukan kita bahwa ketika kita ingin memperkirakan parameter sederhana linear model regresion \(\beta_0\) dan \(\beta_1\), maka \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) yang kita peroleh adalah perkiraan tidak bias linier terbaik, atau di singkat BLUE (Kondisi aktual untuk teorema Gauss-Markov lebih santai daripada model SLR).

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

1.1.1 Linear

Dalam pengaturan SLR bahwa \(x_i\) nilai-nilai dianggap jumlah tetap dan diketahui. Kemudian perkiraan linier adalah salah satu yang dapat ditulis sebagai kombinasi linier dari \(Y_i\). Dalam kasus \(\hat{\beta}_1\) kita bisa melihat bahwa; \[\hat{\beta}_1 = \frac{\sum_{i = 1}^{n}(x_i - \bar{x}) Y_i}{\sum_{i = 1}^{n}(x_i - \bar{x})^2} = \sum_{i = 1}^n k_i Y_i = k_1 Y_1 + k_2 Y_2 + \cdots k_n Y_n\] dimana, \(k_i = \displaystyle\frac{(x_i - \bar{x})}{\sum_{i = 1}^{n}(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 keduanya \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) adalah penduga linier.

1.1.2 Tidak Bias

Sekarang kita tahu perkiraan linier kita, lalu seberapa baik perkiraan kita? Salah satu ukuran “Kebaikan” dari suatu perkiraan adalah biasnya. Secara khusus, pasti kita lebih menyukai perkiraan yang tidak bias, artinya adalah nilai yang diharapkan adalah parameter yang sedang di perkirakan.

Dalam kasus estimasi regresi, kita memiliki; \[\begin{aligned} \text{E}[\hat{\beta}_0] &= \beta_0 \\ \text{E}[\hat{\beta}_1] &= \beta_1\end{aligned}\] Kasus diatas memberi tahu kita bahwa, ketika kondisi model SLR terpenuhi, maka rata-rata perkiraan kita akan benar. Namun, seperti yang kita lihat pada bagian terakhir saat melakukan simulasi dari model SLR, hal itu tidak berarti bahwa setiap perkiraan individu akan benar. Hanya saja, jika kita mengulangi proses tersebut beberapa kali, maka rata-rata perkiraannya akan benar.

1.1.3 Terbaik

Sekarang, jika kita membatasi diri pada linier dan estimasi tidak bias, bagaimana kita dapat mendefinisikan estimasi terbaik? Estimasi dengan varian minimum.

Pertama, sangat mudah untuk membuat perkiraan \(\beta_1\) yang memiliki varian yang sangat rendah, tetapi tidak bias. Contohnya saja, diberikan; \[\hat{\theta}_{BAD} = 5\] Lalu, kita tahu bahwa \(\hat{\theta}_{BAD}\) adalah nilai konstan, \[\text{Var}[\hat{\theta}_{BAD}] = 0\].

Namun sejak, \[\text{E}[\hat{\theta}_{BAD}] = 5\] kita bisa mengatakan \(\hat{\theta}_{BAD}\) adalah penaksir bias kecuali \(\beta_1=5\), yang tidak akan kita ketahui sebelumnya. Alasan tersebut adalah perkiraan yang buruk (kecuali secara kebetulan \(\beta_1=5\)) meskipun variannya bernilai sangat kecil. Ini adalah bagian dari alasan kita membatasi diri pada perkiraan yang tidak bias. Apa gunanya perkiraan, jika memperkirakan kuantitas yang salah?

Jadi sekarang, pertanyaan yang wajar adalah, apa variansnya \(\hat{\beta}_0\) dan \(\hat{\beta}_1\)?

Formula nya adalah sebagai berikut; \[\begin{aligned} \text{Var}[\hat{\beta}_0] &= \sigma^2 \left(\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}\right) \\ \text{Var}[\hat{\beta}_1] &= \frac{\sigma^2}{S_{xx}}\end{aligned}\]

Persamaan diatas mengukur variabilitas dari estimasi, karena peluang acak selama pengambilan sampel. Apakah ini “yang terbaik”? Apakah varians ini sekecil kemungkinan yang bisa kita dapatkan? Kalian hanya perlu menerima kata-kata kita bahwa mereka memang benar karena menunjukkan bahwa ini benar berada di luar cakupan kursus ini.

1.2 Distribusi Sampling

Kita telah “mendefinisikan ulang” perkiraan untuk \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) sebagai variabel acak, kemudian kita dapat membahas distribusi samplingnya, yaitu distribusi ketika suatu statistik dianggap sebagai variabel acak.

Sejak keduanya \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) adalah kombinasi linier dari \(Y_i\) dan masing-masing nilai \(Y_i\) berdistribusi normal, maka keduanya \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) juga mengikuti berdistribusi normal.

Kemudian, dengan menggabungkan semua hal diatas, kita sampai pada distribusi \(\hat{\beta}_0\) dan \(\hat{\beta}_1\).

Dimana untuk \(\hat{\beta}_1\) dapat kita katakan bahwa; \[\hat{\beta}_1 = \frac{S_{xy}}{S_{xx}}= \frac{\sum_{i = 1}^{n}(x_i - \bar{x}) Y_i}{\sum_{i = 1}^{n}(x_i - \bar{x})^2} \sim N\left( \beta_1, \ \frac{\sigma^2}{\sum_{i = 1}^{n}(x_i - \bar{x})^2} \right)\] Atau singkatnya kita katakan, \[\hat{\beta}_1 \sim N\left(\beta_1, \frac{\sigma^2}{S_{xx}}\right)\]

Dan untuk \(\hat{\beta}_0\), sebagai berikut; \[\hat{\beta}_0 = \bar{Y} - \hat{\beta}_1 \bar{x} \sim N\left( \beta_0, \ \frac{\sigma^2 \sum_{i = 1}^{n}x_i^2}{n \sum_{i = 1}^{n}(x_i - \bar{x})^2} \right)\] Atau singkatnya kita katakan, \[\hat{\beta}_0 \sim N\left( \beta_0, \sigma^2 \left(\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}\right) \right)\]

Pada titik ini kita telah lalai untuk membuktikan sejumlah hasil. ALih-alih bekerja melalui turunan yang membosankan dari distribusi sampel ini, kita memilih akan membenarkan hasil ini untuk diri kita sendiri menggunakan simulasi.

Catatan untuk kalian para pembaca: Derivasi dan bukti ini dapat ditambahkan ke lampiran di lain waktu. Kalian juga dapat menemukan hasil ini di hampir semua buku teks regresi linier standar. Di UIUC, hasil ini kemungkinan besar akan disajikan di STAT 424 dan STAT 425. Namun, karena kalian tidak akan diminta untuk melakukan penurunan jenis ini dalam kursus ini, hasil tersebut untuk saat ini dihilangkan.

1.2.1 Simulasi Distribusi Sampel

Untuk memverifikasi hasil diatas, maka kita akan mensimulasikan sampel ukuran \(n\) = 100 dari model; \[Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\] dimana \(\epsilon_i \sim N(0, \sigma^2)\).

Dalam hal ini, parameternya adalah; 1. \(\beta_0=3\) 2. \(\beta_1=6\) 3. \(\sigma^2=4\)

Kemudian, berdasarkan data diatas, kita harus menemukan, \[\hat{\beta}_1 \sim N\left(\beta_1, \frac{\sigma^2}{S_{xx}} \right)\] dan \[\hat{\beta}_0 \sim N\left( \beta_0, \sigma^2 \left(\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}\right) \right)\]

Pertama kita perlu memutuskan apa yang akan menjadi nilai \(x\) kita untuk simulasi ini. Hal tersebut dikarenakan nilai \(x\) dalam SLR juga dianggap kuantitas yang diketahui. Pilihan nilai-nilai \(x\) itu sewenang-wenang. Disini kita juga mengambil bilangan untuk mengacakan, dan menghitung \(S_{xx}\) yang kita perlukan kedepannya.

Kita juga mengambil nilai parameter kita yang telah kita tentukan diatas.

Dengan informasi yang ada, kita akan tahu distribusi sampling kita yang seharusnya;

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

\[\hat{\beta}_1 \sim N( 6, 0.1176238)\] dan, \[\hat{\beta}_0 \sim N( 3, 0.04)\] Maksudnya adalah, \[\begin{aligned} \text{E}[\hat{\beta}_1] &= 6 \\ \text{Var}[\hat{\beta}_1] &= 0.1176238 \end{aligned}\] dan \[\begin{aligned} \text{E}[\hat{\beta}_0] &= 3 \\ \text{Var}[\hat{\beta}_0] &= 0.04\end{aligned}\]

Sekarang kita mensimulasikan data dari model ini sebanyak 10.000 kali. Perhatikan bahwa mungkin ini bukan cara yang baik dalam R untuk melakukan simulasi. Namun, kita melakukan simulasi dengan cara seperti ini agar kita mendapatkan kejelasan. Misalnya, kita bisa menggunakan fungsi sim_slr() dari bagian sebelumnya. Kita juga memilih untuk menyimpan variabel di lingkungan global ketimbang membuat bingkai data untuk setiap kumpulan data simulasi baru.

Setiap kita mesimulasikan data, kita akan memperoleh nilai koefisien yang diperkirakan. Variabel \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) sekarang menyimpan 10.000 nilai simulasi \(\hat{\beta}_0\) dan \(\hat{\beta}_1\) masing-masing.

Kita pertama-tama harus memverifikasi distribusi dari \(\hat{\beta}_1\).

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

Kita melihat bahwa cara empiris dan benar dan varians sangat mirip. Kita juga memverifikasi bahwa distribusi empiris adalah normal. Untuk melakukannya, kami merencanakan histogram dari \(\hat{\beta}_1\), dan menambahkan kurva untuk distribusi sebennarnya dari \(\hat{\beta}_1\). Kita akan menggunakan prob = TRUE untuk meletakkan histogram pada skala yang sama dengan kurva normal.

Kemudian, kita mengulangi proses yang sama untuk \(\hat{\beta}_0\)

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

Dalam simulasi ini, kita hanya mensimulasikan sejumlah sampel yang terbatas. Untuk benar-benar memverifikasi hasil distribusi, kita perlu mengamati jumlah sampel yang tidak terbatas. Namun, plot berikut harus menjelaskan bahwa jika kita terus melakukan simulasi, hasil empirisnya akan semakin mendekati apa yang diharapkan.

1.3 Standar Kesalahan (Standar Errors)

Jadi sekarang kita percaya pada dua hasil distribusi, yaitu; \[\begin{aligned} \hat{\beta}_0 &\sim N\left( \beta_0, \sigma^2 \left(\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}\right) \right) \\ \hat{\beta}_1 &\sim N\left( \beta_1, \frac{\sigma^2}{S_{xx}} \right) \end{aligned}\]

Kemudian dengan menstandarkan hasil ini, kita menemukan, \[\frac{\hat{\beta}_0 - \beta_0}{\text{SD}[\hat{\beta}_0]} \sim N(0, 1)\] dan \[\frac{\hat{\beta}_1 - \beta_1}{\text{SD}[\hat{\beta}_1]} \sim N(0, 1)\] dimana, \[\text{SD}[\hat{\beta}_0] = \sigma\sqrt{\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}}\] dan \[\text{SD}[\hat{\beta}_1] = \frac{\sigma}{\sqrt{S_{xx}}}\]

Karena kita tidak tahu \(\sigma\) dalam praktiknya, maka kita harus memperkirakannya menggunakan \(s_e\), yang akan kita masukkan ke ekspresi kita yang ada untuk stnadar deviasi perkiraan kita.

Kedua ekspresi baru ini disebut standar kesalahan (standar errors) yang merupakan perkiraan standar deviasi dari distribusi pengambilan sampel.

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

\[\text{SE}[\hat{\beta}_1] = \frac{s_e}{\sqrt{S_{xx}}}\]

Sekarang jika kita membagi dengan standar kesalahan, alih-alih standar deviasi. Kita akan memperoleh hasil berikut yang memungkinkan kita untuk membuat interval kepercayaan dan melakukan pengujian hipotesis.

\[\frac{\hat{\beta}_0 - \beta_0}{\text{SE}[\hat{\beta}_0]} \sim t_{n-2}\]

\[\frac{\hat{\beta}_1 - \beta_1}{\text{SE}[\hat{\beta}_1]} \sim t_{n-2}\]

Untuk melihat ini, pertama kita harus memperhatikan bahwa,

\[\frac{\text{RSS}}{\sigma^2} = \frac{(n-2)s_e^2}{\sigma^2} \sim \chi_{n-2}^2\]

Juga perlu diingat bahwa variabel acak \(T\) didefinisikan sebagai,

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

mengikuti ditribusi \(t\) dengan derajat kebebasan \(d\), dimana \(\chi_{d}^2\) adalah variabel acak \(\chi^2\) dengan derajat kebebasan \(d\).

Kita menulis, \[T \sim t_d\] untuk mengatakan bahwa variabel acak \(T\) mengikuti distribusi \(t\) dengan derajat kebebasan \(d\).

Kemudian kita menggunakan trik klasik dengan “kalikan dengan1” dan menyusun ulang beberapa untuk sampai pada

\[\begin{aligned} \frac{\hat{\beta}_1 - \beta_1}{\text{SE}[\hat{\beta}_1]} &= \frac{\hat{\beta}_1 - \beta_1}{s_e / \sqrt{S_{xx}}} \\ &= \frac{\hat{\beta}_1 - \beta_1}{s_e / \sqrt{S_{xx}}} \cdot \frac{\sigma / \sqrt{S_{xx}}}{\sigma / \sqrt{S_{xx}}} \\ &= \frac{\hat{\beta}_1 - \beta_1}{\sigma / \sqrt{S_{xx}}} \cdot \frac{\sigma / \sqrt{S_{xx}}}{s_e / \sqrt{S_{xx}}} \\ &= \frac{\hat{\beta}_1 - \beta_1}{\sigma / \sqrt{S_{xx}}} \bigg/ \sqrt{\frac{s_e^2}{\sigma^2}} \\ &= \frac{\hat{\beta}_1 - \beta_1}{\text{SD}[\hat{\beta}_1]} \bigg/ \sqrt{\frac{\frac{(n - 2)s_e^2}{\sigma^2}}{n - 2}} \sim \frac{Z}{\sqrt{\frac{\chi_{n-2}^2}{n-2}}} \sim t_{n-2} \end{aligned}\]

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

Ingatlah bahwa distribusinya \(t\) mirip dengan standar normal, tetapi dengan ekor yang lebih berat. Ketika derajat kebebasan meningkat, maka distribusi \(t\) menjadi lebih dan lebih seperti standar normal. Dibawah ini kita akan memplot distribusi normal yang standar serta dua contoh distribusi \(t\) dengan derajat kebebasan yang berbeda. Perhatikan bagaimana distribusi \(t\) dengan derajat kebebasan yang lebih besar akan lebih mirip dengan kurva standar normal.

1.4 Interval Keyakinan untuk Kemiringan dan Perpotongan (Intercept)

Ingatlah bahwa interval kepercayaan sering kali berbentuk:

\[\text{EST} \pm \text{CRIT} \cdot \text{SE}\] atau \[\text{EST} \pm \text{MARGIN}\]

Dimana: \(\text{EST}\) adalah perkiraan untuk parameter yang diminati, \(\text{SE}\) adalah perkiraan standar kesalahan (standar errors), dan \(\text{MARGIN} = \text{CRIT} \cdot \text{SE}\)

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

\[\hat{\beta}_0 \pm t_{\alpha/2, n - 2} \cdot \text{SE}[\hat{\beta}_0] \quad \quad \quad \hat{\beta}_0 \pm t_{\alpha/2, n - 2} \cdot s_e\sqrt{\frac{1}{n}+\frac{\bar{x}^2}{S_{xx}}}\] dan \[\hat{\beta}_1 \pm t_{\alpha/2, n - 2} \cdot \text{SE}[\hat{\beta}_1] \quad \quad \quad \hat{\beta}_1 \pm t_{\alpha/2, n - 2} \cdot \frac{s_e}{\sqrt{S_{xx}}}\]

dimana \(t_{\alpha/2, n - 2}\) adalah nilai kritis sedemikian rupa \(P(t_{n-2} > t_{\alpha/2, n - 2}) = \alpha/2\)

1.5 Pengujian Hipotesis

“We may speak of this hypothesis as the ‘null hypothesis’, and it should be noted that the null hypothesis is never proved or established, but is possibly disproved, in the course of experimentation” - Ronald Aylmer Fisher

Ingat bahwa uji statistik (\(\text{TS}\)) untuk sebuah pengujian, sering berupa;

\[\text{TS} = \frac{\text{EST} - \text{HYP}}{\text{SE}}\]

dimana, \(\text{Est}\) adalah perkiraan untuk parameter yang diminati, \(\text{HYP}\) adalah nilai hipotesis dari parameter, dan \(\text{SE}\) adalah perkiraan standar kesalahan (standar errors).

Jadi, untuk mengujinya; \[H_0: \beta_0 = \beta_{00} \quad \text{vs} \quad H_1: \beta_0 \neq \beta_{00}\]

kita menggunakan uji statistik,

\[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}}}}\]

dimana, dibawah hipotesis nol, dan mengikuti distribusi \(t\) dengan derajat kebebasan \(n-2\). Kita gunakan \(\beta_{00}\) untuk menunjukkan nilai hipotesis \(\beta_0\).

Begitu pula untuk menguji \[H_0: \beta_1 = \beta_{10} \quad \text{vs} \quad H_1: \beta_1 \neq \beta_{10}\]

kita menggunakan uji statistik \[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, dibawah hipotesis nol, mengikuti distribusi \(t\) dengan derajat kebebasan \(n-2\). Kita sekarang menggunakan \(\beta_{10}\) untuk menunjukkan nilai hipotesis \(\beta_1\).

1.6 Contoh cars

Sekarang kita kembali ke contoh data cars dari bagian terakhir untuk mengilustrasikan konsep ini. Kita 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

Fungsi names() memberitahu kita tentang informasi apa saja yang tersedia, dan kemudian kita menggunakan oeprator $ dan coefficients untuk mengekstrak informasi yang kita inginkan. Dua nilai disini harus segera akrab.

\[\hat{\beta}_0 = -17.5790949\] dan \[\hat{\beta}_1 = 3.9324088\]

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

Sekarang mari kita fokus dengan 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 standar kesalahan (standar errors) dari \(\hat{\beta_1}\), \[\text{SE}[\hat{\beta}_1] = \frac{s_e}{\sqrt{S_{xx}}} = 0.4155128.\]

Nilai ketiga t value adalah nilai uji statistik untuk pengujian \(H_0: \beta_1 = 0\) vs \(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|) memberi kita nilai p dari pengujian itu.

\[\text{p-value} = 1.4898365\times 10^{-12}\]

Perhatikan disini, kita secara khusus menguji apakah benar atau tidak bahwa \(\beta_1 = 0\).

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, coding berikut menyimpan informasi summary(stop_dist_model)$coefficients dalam variabel baru stop_dist_model_test_info, lalu mengekstrak setiap elemen menjadi variabel baru yang akan menjelaskan informasi yang dikandungnya.

Kami kemudian dapat memverifikasi beberapa ekspresi yang setara: statistik uji \(t\) untuk \(\hat{\beta_1}\) dan nilai p dua sisi yang terkait dengan uji statistik tersebut.

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

1.6.2 Signifikansi Regresi, Uji-t

Kita berhenti sejenak untuk membahas pentingnya uji regresi. Pertama, perhatikan bahwa berdasarkan hasil distribusi di atas, kita 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 kita mengasumsikan hipotesis nol benar, maka \(\beta_1=0\) dan kita memiliki modelnya, \[Y_i = \beta_0 + \epsilon_i\]

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

  1. Dibawah \(H_0\) tidak ada hubungan linier yang signifikan antara \(x\) dan \(y\).
  2. Dibawah \(H_1\) ada hubungan linier yang signifikan antara \(x\) dan \(y\).

Untuk contoh cars,

  1. Dibawah \(H_0\) tidak ada hubungan linier yang signifikan antara kecepatan dan jarak berhenti.
  2. Dibawah \(H_1\) ada hubungan linier yang signifikan antara kecepatan dan jarak berhenti.

Sekali lagi, pengujian itu terlihat pada keluaran dari summary(), \[\text{p-value} = 1.4898365\times 10^{-12}\]

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

Dalam plot data simulasi ini, kita bisa melihat hubungan yang jelas antara \(x\) dan \(y\). Namun, ini bukan hubungan linier. Jika kita memasukkan garis ke data ini, itu sangat datar. Tes yang dihasilkan untuk \(H_0: \beta_1 = 0\) vs \(H_1: \beta_1 \neq 0\) memberikan nilai p yang besar, dalam kasus ini bernilai \(0.7564548\). Jadi, kita akan gagal untuk 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” \(H_0: \beta_1 = 0\) vs \(H_1: \beta_1 \neq 0\) hanya dapat mendeteksi hubungan yang garis lurus (linier).

1.6.3 Interval Keyakinan Dalam R

Dengan menggunakan R kita dapat dengan mudah mendapatkan interva kepercayaan untk \(\beta_0\) dan \(\beta_1\).

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

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

cars sebagai contoh saat menginterpretasikan interval ini, kita katakan 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 kepercayaan 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 kita lihat sebelumnya.

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

Catatan, kita dapat mengekstrak nilai tertentu dari keluaran ini dengan beberapa cara. Coding ini tidak dijalankan, dan sebagai gantinya, kalian harus memeriksa hubungannya dengan keluaran coding diatas.

##       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

Kita juga dapat memverifikasi kalkulasi yang R lakukan untuk selang \(\beta_1\).

##    speed    speed 
## 2.817919 5.046899

1.7 Interval Keyakinan untuk Respon Rata-Rata

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

Dalam situasi ini, kita menggunakan \(\hat{y}(x)\) sebagai perkiraan \(E[Y \mid X = x]\) kita. Kita sedikit memodifikasi notasi kita 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 bagus karena tidak bias; \[\text{E}[\hat{y}(x)] = \beta_0 + \beta_1 x\] Kita 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. Sejak \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) adalah kombinasi linier dari variabel acak normal, begitu juga dengan \(\hat{y}(x)\). \[\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, kerena kita perlu memperkirakan varians, kita sampai pada standar kesalahan (standar errors) dari perkiraan kita. \[\text{SE}[\hat{y}(x)] = s_e \sqrt{\frac{1}{n}+\frac{(x-\bar{x})^2}{S_{xx}}}\] Kita 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 dalam R, maka kita menggunakan fungsi predict(). Kita memberikan fungsi model pas kita serta data baru, lalu disimpan sebagai data frame (hal ini penting dilakukan agar R mengetahui nama variabel prediktor).

Disini, kita menemukan interval kepercayaan untuk jarak berhenti rata-rata saat mobil melaju 5 mil perjam 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 Prediksi Interval untuk Pengamatan Baru

Terkadang kita menginginkan perkiraan 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 kita 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 ini, kita menambahkan faktor tambahan \(\sigma^2\) ke variabilitas perkiraan kita, untuk menjelaskan variabilitas pengamatan tentang garis regresi (linier regression). \[\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}}}\] Kita 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 R pemberitahuan hanya ada sedikit perubahan dalam sintaks dari menemukan interval kepercayaan untuk respons 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 repons rata-rata.

1.9 Keyakinan dan Pita Prediksi

Seringkali kita ingin memplot kedua interval keyakinan untuk respons rata-rata dan interval prediksi untuk semua kemungkinan nilai \(x\). Kita menyebutnya keyakinan dan pita prediksi.

Beberapa hal yang perlu diperhatikan:

  1. Kita menggunakan argumen ylim untuk meregangkan sumbu-\(y\) dari plot, karena pita lebih panjang daripada titik.

  2. Kita menambahkan titik pada titik (\(x,y\)) tersebut.

    • Ini adalah titik yang akan selalu dilewati garis regresi. (Pikirkan alasannya)
    • Ini adalah titi dimana keyakinan dan pita prediksi menjadi yang tersempit. Lihatlah kesalahan standar keduanya untuk memahami mengapa.
  3. Pita prediksi (titik-titik biru) kurang melengkung dibandingkan dengan pita kepercayaan (biru putus-putus). Ini adalah hasil dari faktor \(\sigma^2\) tambahan yang ditambahkan ke varians pada nilai \(x\) berapapun.

1.10 Signifikansi Regresi, Uji-F

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

Ingat dari bagian terakhir dekomposisi varians yang kita lihat sebelumnya menghihitung \(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 \(F\) test, kita akan mengatur informasi ini dalam tabel ANOVA

ANOVA, atau Analisis Varians akan menjadi konsep yang sering kita bahas dalam bagian ini. Untuk saat ini, kita akan fokus pada hasil tabel, yaitu \(F\) statistik. \[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\) dibawah hipotesis nol. Sebuah distribusi \(F\) adalah distribusi kontinu yang hanya mengambil nilai positif dan memiliki dua parameter, yaitu dua derajat kebebasan.

Ingatlah, pentingnya uji regresi, \(Y\) tidak tergantung pada \(x\) dalam 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 bisa menggunakan \(F\) statistik 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, kita akan menolak null saat \(F\) statistiknya benar, yaitu, ketika ada kemungkinan rendah bahwa pengamatan bisa datang dari model nol secara kebetulan. Kita akan menghitung nilai p untuk kita dengan R.

Untuk melakukan \(F\) tes di R kalian dapat melihat baris terakhir dari output yang dalam fungsi summary() disebut F-statistics yang memberikan nilai uji statistik, derajat kebebasan yang relevan, serta \(p-value\) dari pengujian

## 
## 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, kalian dapat menggunakan fungsi anova() dalam menampilkan informasidalam 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 (\(p-value\)) untuk pengujian. Kalian harus memperhatikan bahwa nilai p (\(p-value\)) dari distribusi \(t\) adalah sama. Kalian mungkin juga memperhatikan bahwa nilai statistik pengujian untuk uji \(t\), \(9.46399\), dapat dikuadratkan untuk mendapatkan nilai \(F\) statistik, \(89.5671065\).

Perhatikan bahwa ada cara lain yang setara untuk melakukan ini dalam R, dimana kita akan sering sekali 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 (data cars). Catat \(\hat{y} = \bar{y}\) itu 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\). Kita kemudian dapat menganggap penggunaan anova() ini sebagai perbandingan langsung kedua model (Perhatikan bahwa kita mendapatkan nilai p (\(p-value\)) yang sama lagi).

LS0tDQp0aXRsZTogIlN0YXRpc3RpY2FsIENvbXB1dGluZzogTWlkdGVybSINCmF1dGhvcjogIkltZWxkYSBTaWFudHVyaSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNCmBgYHtyIExvZ28sIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2dpdGh1Yi5jb20vQmFrdGktU2lyZWdhci9pbWFnZXMvYmxvYi9tYXN0ZXIvbG9nby5wbmc/cmF3PXRydWUiKQ0KYGBgDQoNCiMgSW5mZXJlbnNpIGRhbGFtIFJlZ3Jlc2kgTGluaWVyDQoNClNldGVsYWggbWVtYmFjYSBiYWdpYW4gaW5pLCBraXRhIGFrYW4gZGFwYXQ6DQoNCjEuIE1lbWFoYW1pIGRpc3RyaWJ1c2kgcGVya2lyYWFuIHJlZ3Jlc2kuDQoyLiBNZW1idWF0IHBlcmtpcmFhbiBpbnRlcnZhbCB1bnR1ayBwYXJhbWV0ZXIgcmVncmVzaSwgcmVzcG9uIHJhdGEtcmF0YSwgZGFuIHByZWRpa3NpLg0KMy4gRGFwYXQgbWVsYWt1a2FuIHVqaSBzaWduaWZpa2Fuc2kgcmVncmVzaQ0KDQpNb2RlbCByZWdyZXNpIGxpbmVhciB5YW5nIHNlZGVyaGFuYSwgYmlhc2EgZGkgbW9kZWxrYW4gc2ViYWdhaSBiZXJpa3V0LCANCiQkWV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF9pICsgXGVwc2lsb25faSQkDQoNCmRpbWFuYSAkXGVwc2lsb25faSBcc2ltIE4oMCwgXHNpZ21hXjIpJC4gQ29udG9obnlhIHNhamEga2l0YSBha2FuIG1lbmdndW5ha2FuIG9ic2VydmFzaSAkKHhfaSx5X2kpJCB1bnR1ayAkaSA9IDEsMiwuLi4sIG4kLiBEYWxhbSBtZW5lbnR1a2FuIG5pbGFpICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIG1vZGVsIHlhbmcgYWthbiBkaW1pbmltYWxrYW4gYWRhbGFoLA0KJCRmKFxiZXRhXzAsIFxiZXRhXzEpID0gXHN1bV97aSA9IDF9XntufSh5X2kgLSAoXGJldGFfMCArIFxiZXRhXzEgeF9pKSleMiQkDQpMYWx1LCBraXRhIG1hc3Vra2FuIG5pbGFpLW5pbGFpICRcaGF0e1xiZXRhfV8wJCBkYW4gJFxoYXR7XGJldGF9XzEkIHlhbmcgc3VkYWgga2l0YSB0ZW11a2FuLA0KJCRcYmVnaW57YWxpZ25lZH0gXGhhdHtcYmV0YX1fMSAmPSBcZnJhY3tTX3t4eX19e1Nfe3h4fX0gPSBcZnJhY3tcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pKHlfaSAtIFxiYXJ7eX0pfXtcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pXjJ9XFwgXGhhdHtcYmV0YX1fMCAmPSBcYmFye3l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye3h9LlxlbmR7YWxpZ25lZH0kJA0KS2l0YSBqdWdhIGFrYW4gbWVtcGVya2lyYWthbiAkXHNpZ21hIF4yJCBtZW5nZ3VuYWthbiAkc19lXjIkLiBEZW5nYW4gYmVnaXR1LCBraXRhIG1lbmVtdWthbiAkc19lXjIkIGFkYWxhaCBzYW1hIGRlbmdhbiBraXRhIG1lbXBlcmtpcmFrYW4gJFxzaWdtYSQsIGRpbWFuYTsNCiQkc19lID0gXHRleHR7UlNFfSA9IFxzcXJ0e1xmcmFjezF9e24gLSAyfVxzdW1fe2kgPSAxfV5uIGVfaV4yfSQkDQpiaWFzYSBraXRhIG1lbnllYnV0bnlhIFJTRSAoUmVzaWR1YWwgU3RhbmRhciBFcnJvcikuIA0KDQpLZXRpa2Ega2l0YSBhcGxpa2FzaWthbiBwZXJoaXR1bmdhbiBrZSBkYXRhICJjYXJzIiwga2l0YSBtZW1wZXJvbGVoIGhhc2lsbnlhIHNlYmFnYWkgYmVyaWt1dDsNCmBgYHtyfQ0KZGF0YShjYXJzKQ0Kc3RvcF9kaXN0X21vZGVsID0gbG0oZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycykNCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNCkJhZ2lhbiBiYXdhaCBkYXJpIGhhc2lsIGNvZGluZywgYWthbiBtZW1iYWhhcyBuaWxhaS1uaWxhaSBkYXJpIEVzdGltYXRlLCBSU0UgKFJlc2lkdWFsIFN0YW5kYXIgRXJyb3IpIGRhbiBNdWx0aXBsZSBSLXNxdWFyZWQuDQoNClNlbGFuanV0bnlhLCBraXRhIGFrYW4gbWVtYmFoYXMgc2VtdWEgaW5mb3JtYXNpIGRpIGJhd2FoIEtvZWZpc2llbiBkYW4ganVnYSBGLVN0YXRpc3RpY3MsIGRlbmdhbiBjb2Rpbmcgc2ViYWdhaSBiZXJpa3V0Ow0KYGBge3J9DQpwbG90KGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMsDQogICAgIHhsYWIgPSAiU3BlZWQgKGluIE1pbGVzIFBlciBIb3VyKSIsDQogICAgIHlsYWIgPSAiU3RvcHBpbmcgRGlzdGFuY2UgKGluIEZlZXQpIiwNCiAgICAgbWFpbiA9ICJTdG9wcGluZyBEaXN0YW5jZSB2cyBTcGVlZCIsDQogICAgIHBjaCAgPSAyMCwNCiAgICAgY2V4ICA9IDIsDQogICAgIGNvbCAgPSAiZ3JleSIpDQphYmxpbmUoc3RvcF9kaXN0X21vZGVsLCBsd2QgPSA1LCBjb2wgPSAiZGFya29yYW5nZSIpDQpgYGANClVudHVrIG1lbXVsYWksIGtpdGEgYWthbiBtZW5jYXRhdCBiYWh3YSBhZGEgZWtzcHJlc2kgbGFpbiB5YW5nIHNldGFyYSB1bnR1ayAkU197eHl9JCB5YW5nIHRpZGFrIGtpdGEgbGloYXQgZGkgYmFnaWFuIHRlcmFraGlyOw0KJCRTX3t4eX09IFxzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSkoeV9pIC0gXGJhcnt5fSkgPSBcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pIHlfaSQkDQpNdW5na2luIGluaSBrZXNldGFyYWFuIHlhbmcgdGlkYWsgdGVyZHVnYS4gTmFtdW4sIGluaSBha2FuIGJlcmd1bmEgdW50dWsgbWVuZ2lsdXN0cmFzaWthbiBrb25zZXAgZGkgYmFnaWFuIGluaS4NCg0KUGVyaGF0aWthbiBiYWh3YSwgJFxoYXR7XGJldGF9XzEkIGFkYWxhaCBjb250b2ggc3RhdGlzdGlrIGppa2EgZGloaXR1bmcgZGVuZ2FuIGRhdGEgb2JzZXJ2YXNpIHNlcGVydGkgeWFuZyB0ZXJ0dWxpcyBkaSBhdGFzICRcaGF0e1xiZXRhfV8wJC4NCg0KUGFkYSBiYWdpYW4gaW5pIGFrYW4gbGViaWggbXVkYWggdW50dWsgbWVuZ2d1bmFrYW4ga2VkdWFueWEgJFxoYXR7XGJldGF9XzEkIGRhbiAkXGhhdHtcYmV0YX1fMCQgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLiBLaXRhIGhhcnVzIG1lbmdhbWF0aSBtYXNpbmctbWFzaW5nIG5pbGFpICRZX2kkLiBNYWthLCBraXRhIGFrYW4gbWVuZ2d1bmFrYW4gbm90YXNpIHlhbmcgc2VkaWtpdCBiZXJiZWRhLCBtZW5nZ2FudGlrYW4gaHVydWYga2FwaXRhbCAkWV9pJCBkZW5nYW4gaHVydWYga2VjaWwgJHlfaSQuDQoNCiQkXGJlZ2lue2FsaWduZWR9IFxoYXR7XGJldGF9XzEgJj0gXGZyYWN7XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KSBZX2l9e1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSleMn0gXFwgXGhhdHtcYmV0YX1fMCAmPSBcYmFye1l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye3h9IFxlbmR7YWxpZ25lZH0kJA0KDQpCZXJodWJ1bmdhbiBkZW5nYW4gYmFnaWFuIHRlcmFraGlyLCBraXRhIGJlcnBlbmRhcGF0IGJhaHdhIHBlcmtpcmFhbiBwYXJhbWV0ZXIgbW9kZWwgeWFuZyB0aWRhayBkaWtldGFodWkgaW5pICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIGJhZ3VzIGthcmVuYSBrYW1pIG1lbmRhcGF0a2FubnlhIGRlbmdhbiBtZW1pbmltYWxrYW4ga2VzYWxhaGFuLiBTZWthcmFuZyBraXRhIGFrYW4gbWVtYmFoYXMgdGVvcmVtYSBHYXVzcy1NYXJrb3YgeWFuZyBtZW1iYXdhIGdhZ2FzYW4gaW5pIGxlYmloIGphdWgsIHlhbmcgbWVudW5qdWtrYW4gYmFod2EgcGVya2lyYWFuIGluaSBzZWJlbmFybnlhIGFkYWxhaCBwZXJraXJhYW4gInRlcmJhaWsiLCBkYXJpIHN1ZHV0IHBhbmRhbmcgdGVydGVudHUuDQoNCiMjIFRlb3JlbWEgR2F1c3MgLSBNYXJrb3YNCg0KKipUZW9yZW1hIEdhdXNzIC0gTWFya292KiogbWVtYmVyaXRhaHVrYW4ga2l0YSBiYWh3YSBrZXRpa2Ega2l0YSBpbmdpbiBtZW1wZXJraXJha2FuIHBhcmFtZXRlciBzZWRlcmhhbmEgbGluZWFyIG1vZGVsIHJlZ3Jlc2lvbiAkXGJldGFfMCQgZGFuICRcYmV0YV8xJCwgbWFrYSAkXGhhdHtcYmV0YX1fMCQgZGFuICRcaGF0e1xiZXRhfV8xJCB5YW5nIGtpdGEgcGVyb2xlaCBhZGFsYWggKipwZXJraXJhYW4gdGlkYWsgYmlhcyBsaW5pZXIgdGVyYmFpayoqLCBhdGF1IGRpIHNpbmdrYXQgQkxVRSAoS29uZGlzaSBha3R1YWwgdW50dWsgdGVvcmVtYSBHYXVzcy1NYXJrb3YgbGViaWggc2FudGFpIGRhcmlwYWRhIG1vZGVsIFNMUikuDQoNClNla2FyYW5nIGtpdGEgYWthbiBtZW1iYWhhcyAqbGluaWVyLCB0aWRhayBiaWFzIGRhbiB0ZXJiYWlrKiB5YW5nIGJlcmthaXRhbiBkZW5nYW4gcGVya2lyYWFuIGluaS4gDQoNCiMjIyAqKkxpbmVhcioqDQoNCkRhbGFtIHBlbmdhdHVyYW4gU0xSIGJhaHdhICR4X2kkIG5pbGFpLW5pbGFpIGRpYW5nZ2FwIGp1bWxhaCB0ZXRhcCBkYW4gZGlrZXRhaHVpLiBLZW11ZGlhbiBwZXJraXJhYW4gKipsaW5pZXIqKiBhZGFsYWggc2FsYWggc2F0dSB5YW5nIGRhcGF0IGRpdHVsaXMgc2ViYWdhaSBrb21iaW5hc2kgbGluaWVyIGRhcmkgJFlfaSQuIERhbGFtIGthc3VzICRcaGF0e1xiZXRhfV8xJCBraXRhIGJpc2EgbWVsaWhhdCBiYWh3YTsNCiQkXGhhdHtcYmV0YX1fMSA9IFxmcmFje1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSkgWV9pfXtcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pXjJ9ID0gXHN1bV97aSA9IDF9Xm4ga19pIFlfaSA9IGtfMSBZXzEgKyBrXzIgWV8yICsgXGNkb3RzIGtfbiBZX24kJA0KZGltYW5hLCAka19pID0gXGRpc3BsYXlzdHlsZVxmcmFjeyh4X2kgLSBcYmFye3h9KX17XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KV4yfSQgDQpEZW5nYW4gY2FyYSB5YW5nIHNhbWEsIGtpdGEgZGFwYXQgbWVudW5qdWtrYW4gYmFod2EgJFxoYXR7XGJldGF9XzAkIGRhcGF0IGRpdHVsaXMgc2ViYWdhaSBrb21iaW5hc2kgbGluaWVyIGRhcmkgJFlfaSQuIEphZGkga2VkdWFueWEgJFxoYXR7XGJldGF9XzAkIGRhbiAkXGhhdHtcYmV0YX1fMSQgYWRhbGFoIHBlbmR1Z2EgbGluaWVyLg0KDQojIyMgKipUaWRhayBCaWFzKioNCg0KU2VrYXJhbmcga2l0YSB0YWh1IHBlcmtpcmFhbiBsaW5pZXIga2l0YSwgbGFsdSBzZWJlcmFwYSBiYWlrIHBlcmtpcmFhbiBraXRhPyBTYWxhaCBzYXR1IHVrdXJhbiAiS2ViYWlrYW4iIGRhcmkgc3VhdHUgcGVya2lyYWFuIGFkYWxhaCAqKmJpYXNueWEqKi4gU2VjYXJhIGtodXN1cywgcGFzdGkga2l0YSBsZWJpaCBtZW55dWthaSBwZXJraXJhYW4geWFuZyAqKnRpZGFrIGJpYXMqKiwgYXJ0aW55YSBhZGFsYWggbmlsYWkgeWFuZyBkaWhhcmFwa2FuIGFkYWxhaCBwYXJhbWV0ZXIgeWFuZyBzZWRhbmcgZGkgcGVya2lyYWthbi4NCg0KRGFsYW0ga2FzdXMgZXN0aW1hc2kgcmVncmVzaSwga2l0YSBtZW1pbGlraTsNCiQkXGJlZ2lue2FsaWduZWR9IFx0ZXh0e0V9W1xoYXR7XGJldGF9XzBdICY9IFxiZXRhXzAgXFwgXHRleHR7RX1bXGhhdHtcYmV0YX1fMV0gJj0gXGJldGFfMVxlbmR7YWxpZ25lZH0kJA0KS2FzdXMgZGlhdGFzIG1lbWJlcmkgdGFodSBraXRhIGJhaHdhLCBrZXRpa2Ega29uZGlzaSBtb2RlbCBTTFIgdGVycGVudWhpLCBtYWthIHJhdGEtcmF0YSBwZXJraXJhYW4ga2l0YSBha2FuIGJlbmFyLiBOYW11biwgc2VwZXJ0aSB5YW5nIGtpdGEgbGloYXQgcGFkYSBiYWdpYW4gdGVyYWtoaXIgc2FhdCBtZWxha3VrYW4gc2ltdWxhc2kgZGFyaSBtb2RlbCBTTFIsIGhhbCBpdHUgdGlkYWsgYmVyYXJ0aSBiYWh3YSBzZXRpYXAgcGVya2lyYWFuIGluZGl2aWR1IGFrYW4gYmVuYXIuIEhhbnlhIHNhamEsIGppa2Ega2l0YSBtZW5ndWxhbmdpIHByb3NlcyB0ZXJzZWJ1dCBiZWJlcmFwYSBrYWxpLCBtYWthIHJhdGEtcmF0YSBwZXJraXJhYW5ueWEgYWthbiBiZW5hci4NCg0KIyMjICoqVGVyYmFpayoqDQoNClNla2FyYW5nLCBqaWthIGtpdGEgbWVtYmF0YXNpIGRpcmkgcGFkYSAqbGluaWVyIGRhbiBlc3RpbWFzaSB0aWRhayBiaWFzKiwgYmFnYWltYW5hIGtpdGEgZGFwYXQgbWVuZGVmaW5pc2lrYW4gZXN0aW1hc2kgdGVyYmFpaz8gRXN0aW1hc2kgZGVuZ2FuICoqdmFyaWFuIG1pbmltdW0qKi4NCg0KUGVydGFtYSwgc2FuZ2F0IG11ZGFoIHVudHVrIG1lbWJ1YXQgcGVya2lyYWFuICRcYmV0YV8xJCB5YW5nIG1lbWlsaWtpIHZhcmlhbiB5YW5nIHNhbmdhdCByZW5kYWgsIHRldGFwaSB0aWRhayBiaWFzLiBDb250b2hueWEgc2FqYSwgZGliZXJpa2FuOw0KJCRcaGF0e1x0aGV0YX1fe0JBRH0gPSA1JCQNCkxhbHUsIGtpdGEgdGFodSBiYWh3YSAkXGhhdHtcdGhldGF9X3tCQUR9JCBhZGFsYWggbmlsYWkga29uc3RhbiwNCiQkXHRleHR7VmFyfVtcaGF0e1x0aGV0YX1fe0JBRH1dID0gMCQkLiANCg0KTmFtdW4gc2VqYWssICQkXHRleHR7RX1bXGhhdHtcdGhldGF9X3tCQUR9XSA9IDUkJA0Ka2l0YSBiaXNhIG1lbmdhdGFrYW4gJFxoYXR7XHRoZXRhfV97QkFEfSQgYWRhbGFoIHBlbmFrc2lyIGJpYXMga2VjdWFsaSAkXGJldGFfMT01JCwgeWFuZyB0aWRhayBha2FuIGtpdGEga2V0YWh1aSBzZWJlbHVtbnlhLiBBbGFzYW4gdGVyc2VidXQgYWRhbGFoIHBlcmtpcmFhbiB5YW5nIGJ1cnVrIChrZWN1YWxpIHNlY2FyYSBrZWJldHVsYW4gJFxiZXRhXzE9NSQpIG1lc2tpcHVuIHZhcmlhbm55YSBiZXJuaWxhaSBzYW5nYXQga2VjaWwuIEluaSBhZGFsYWggYmFnaWFuIGRhcmkgYWxhc2FuIGtpdGEgbWVtYmF0YXNpIGRpcmkgcGFkYSBwZXJraXJhYW4geWFuZyAqdGlkYWsgYmlhcyouIEFwYSBndW5hbnlhIHBlcmtpcmFhbiwgamlrYSBtZW1wZXJraXJha2FuIGt1YW50aXRhcyB5YW5nIHNhbGFoPyAgIA0KDQpKYWRpIHNla2FyYW5nLCBwZXJ0YW55YWFuIHlhbmcgd2FqYXIgYWRhbGFoLCBhcGEgdmFyaWFuc255YSAkXGhhdHtcYmV0YX1fMCQgZGFuICRcaGF0e1xiZXRhfV8xJD8gDQoNCkZvcm11bGEgbnlhIGFkYWxhaCBzZWJhZ2FpIGJlcmlrdXQ7DQokJFxiZWdpbnthbGlnbmVkfSBcdGV4dHtWYXJ9W1xoYXR7XGJldGF9XzBdICY9IFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19XHJpZ2h0KSBcXCBcdGV4dHtWYXJ9W1xoYXR7XGJldGF9XzFdICY9IFxmcmFje1xzaWdtYV4yfXtTX3t4eH19XGVuZHthbGlnbmVkfSQkDQoNClBlcnNhbWFhbiBkaWF0YXMgbWVuZ3VrdXIgdmFyaWFiaWxpdGFzIGRhcmkgZXN0aW1hc2ksIGthcmVuYSBwZWx1YW5nIGFjYWsgc2VsYW1hIHBlbmdhbWJpbGFuIHNhbXBlbC4gQXBha2FoIGluaSAieWFuZyB0ZXJiYWlrIj8gQXBha2FoIHZhcmlhbnMgaW5pIHNla2VjaWwga2VtdW5na2luYW4geWFuZyBiaXNhIGtpdGEgZGFwYXRrYW4/IEthbGlhbiBoYW55YSBwZXJsdSBtZW5lcmltYSBrYXRhLWthdGEga2l0YSBiYWh3YSBtZXJla2EgbWVtYW5nIGJlbmFyIGthcmVuYSBtZW51bmp1a2thbiBiYWh3YSBpbmkgYmVuYXIgYmVyYWRhIGRpIGx1YXIgY2FrdXBhbiBrdXJzdXMgaW5pLg0KDQojIyBEaXN0cmlidXNpIFNhbXBsaW5nDQoNCktpdGEgdGVsYWggIm1lbmRlZmluaXNpa2FuIHVsYW5nIiBwZXJraXJhYW4gdW50dWsgJFxoYXR7XGJldGF9XzAkIGRhbiAkXGhhdHtcYmV0YX1fMSQgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLCBrZW11ZGlhbiBraXRhIGRhcGF0IG1lbWJhaGFzICoqZGlzdHJpYnVzaSBzYW1wbGluZ255YSoqLCB5YWl0dSBkaXN0cmlidXNpIGtldGlrYSBzdWF0dSBzdGF0aXN0aWsgZGlhbmdnYXAgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLg0KDQpTZWphayBrZWR1YW55YSAkXGhhdHtcYmV0YX1fMCQgZGFuICRcaGF0e1xiZXRhfV8xJCBhZGFsYWgga29tYmluYXNpIGxpbmllciBkYXJpICRZX2kkIGRhbiBtYXNpbmctbWFzaW5nIG5pbGFpICRZX2kkIGJlcmRpc3RyaWJ1c2kgbm9ybWFsLCBtYWthIGtlZHVhbnlhICRcaGF0e1xiZXRhfV8wJCBkYW4gJFxoYXR7XGJldGF9XzEkIGp1Z2EgbWVuZ2lrdXRpIGJlcmRpc3RyaWJ1c2kgbm9ybWFsLg0KDQpLZW11ZGlhbiwgZGVuZ2FuIG1lbmdnYWJ1bmdrYW4gc2VtdWEgaGFsIGRpYXRhcywga2l0YSBzYW1wYWkgcGFkYSBkaXN0cmlidXNpICRcaGF0e1xiZXRhfV8wJCBkYW4gJFxoYXR7XGJldGF9XzEkLiANCg0KRGltYW5hIHVudHVrICRcaGF0e1xiZXRhfV8xJCBkYXBhdCBraXRhIGthdGFrYW4gYmFod2E7IA0KJCRcaGF0e1xiZXRhfV8xID0gXGZyYWN7U197eHl9fXtTX3t4eH19PSBcZnJhY3tcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pIFlfaX17XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KV4yfSBcc2ltIE5cbGVmdCggIFxiZXRhXzEsIFwgXGZyYWN7XHNpZ21hXjJ9e1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSleMn0gXHJpZ2h0KSQkDQpBdGF1IHNpbmdrYXRueWEga2l0YSBrYXRha2FuLA0KJCRcaGF0e1xiZXRhfV8xIFxzaW0gTlxsZWZ0KFxiZXRhXzEsIFxmcmFje1xzaWdtYV4yfXtTX3t4eH19XHJpZ2h0KSQkDQoNCkRhbiB1bnR1ayAkXGhhdHtcYmV0YX1fMCQsIHNlYmFnYWkgYmVyaWt1dDsNCiQkXGhhdHtcYmV0YX1fMCA9IFxiYXJ7WX0gLSBcaGF0e1xiZXRhfV8xIFxiYXJ7eH0gXHNpbSBOXGxlZnQoICBcYmV0YV8wLCBcIFxmcmFje1xzaWdtYV4yIFxzdW1fe2kgPSAxfV57bn14X2leMn17biBcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pXjJ9IFxyaWdodCkkJA0KQXRhdSBzaW5na2F0bnlhIGtpdGEga2F0YWthbiwNCiQkXGhhdHtcYmV0YX1fMCBcc2ltIE5cbGVmdCggIFxiZXRhXzAsIFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19XHJpZ2h0KSBccmlnaHQpJCQNCg0KUGFkYSB0aXRpayBpbmkga2l0YSB0ZWxhaCBsYWxhaSB1bnR1ayBtZW1idWt0aWthbiBzZWp1bWxhaCBoYXNpbC4gQUxpaC1hbGloIGJla2VyamEgbWVsYWx1aSB0dXJ1bmFuIHlhbmcgbWVtYm9zYW5rYW4gZGFyaSBkaXN0cmlidXNpIHNhbXBlbCBpbmksIGtpdGEgbWVtaWxpaCBha2FuIG1lbWJlbmFya2FuIGhhc2lsIGluaSB1bnR1ayBkaXJpIGtpdGEgc2VuZGlyaSBtZW5nZ3VuYWthbiBzaW11bGFzaS4gDQoNCkNhdGF0YW4gdW50dWsga2FsaWFuIHBhcmEgcGVtYmFjYTogRGVyaXZhc2kgZGFuIGJ1a3RpIGluaSBkYXBhdCBkaXRhbWJhaGthbiBrZSBsYW1waXJhbiBkaSBsYWluIHdha3R1LiBLYWxpYW4ganVnYSBkYXBhdCBtZW5lbXVrYW4gaGFzaWwgaW5pIGRpIGhhbXBpciBzZW11YSBidWt1IHRla3MgcmVncmVzaSBsaW5pZXIgc3RhbmRhci4gRGkgVUlVQywgaGFzaWwgaW5pIGtlbXVuZ2tpbmFuIGJlc2FyIGFrYW4gZGlzYWppa2FuIGRpIFNUQVQgNDI0IGRhbiBTVEFUIDQyNS4gTmFtdW4sIGthcmVuYSBrYWxpYW4gdGlkYWsgYWthbiBkaW1pbnRhIHVudHVrIG1lbGFrdWthbiBwZW51cnVuYW4gamVuaXMgaW5pIGRhbGFtIGt1cnN1cyBpbmksIGhhc2lsIHRlcnNlYnV0IHVudHVrIHNhYXQgaW5pIGRpaGlsYW5na2FuLg0KDQojIyMgU2ltdWxhc2kgRGlzdHJpYnVzaSBTYW1wZWwNCg0KVW50dWsgbWVtdmVyaWZpa2FzaSBoYXNpbCBkaWF0YXMsIG1ha2Ega2l0YSBha2FuIG1lbnNpbXVsYXNpa2FuIHNhbXBlbCB1a3VyYW4gJG4kID0gMTAwIGRhcmkgbW9kZWw7DQokJFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kkJA0KZGltYW5hICRcZXBzaWxvbl9pIFxzaW0gTigwLCBcc2lnbWFeMikkLiANCg0KRGFsYW0gaGFsIGluaSwgcGFyYW1ldGVybnlhIGFkYWxhaDsNCjEuICRcYmV0YV8wPTMkDQoyLiAkXGJldGFfMT02JA0KMy4gJFxzaWdtYV4yPTQkDQoNCktlbXVkaWFuLCBiZXJkYXNhcmthbiBkYXRhIGRpYXRhcywga2l0YSBoYXJ1cyBtZW5lbXVrYW4sDQokJFxoYXR7XGJldGF9XzEgXHNpbSBOXGxlZnQoXGJldGFfMSwgXGZyYWN7XHNpZ21hXjJ9e1Nfe3h4fX0gXHJpZ2h0KSQkDQpkYW4gDQokJFxoYXR7XGJldGF9XzAgXHNpbSBOXGxlZnQoICBcYmV0YV8wLCBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fVxyaWdodCkgXHJpZ2h0KSQkDQoNClBlcnRhbWEga2l0YSBwZXJsdSBtZW11dHVza2FuIGFwYSB5YW5nIGFrYW4gbWVuamFkaSBuaWxhaSAkeCQga2l0YSB1bnR1ayBzaW11bGFzaSBpbmkuIEhhbCB0ZXJzZWJ1dCBkaWthcmVuYWthbiBuaWxhaSAkeCQgZGFsYW0gU0xSIGp1Z2EgZGlhbmdnYXAga3VhbnRpdGFzIHlhbmcgZGlrZXRhaHVpLiBQaWxpaGFuIG5pbGFpLW5pbGFpICR4JCBpdHUgc2V3ZW5hbmctd2VuYW5nLiBEaXNpbmkga2l0YSBqdWdhIG1lbmdhbWJpbCBiaWxhbmdhbiB1bnR1ayBtZW5nYWNha2FuLCBkYW4gbWVuZ2hpdHVuZyAkU197eHh9JCB5YW5nIGtpdGEgcGVybHVrYW4ga2VkZXBhbm55YS4gDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoNDIpDQpzYW1wbGVfc2l6ZSA9IDEwMCAjIHRoaXMgaXMgbg0KeCA9IHNlcSgtMSwgMSwgbGVuZ3RoID0gc2FtcGxlX3NpemUpDQpTeHggPSBzdW0oKHggLSBtZWFuKHgpKSBeIDIpDQpgYGANCg0KS2l0YSBqdWdhIG1lbmdhbWJpbCBuaWxhaSBwYXJhbWV0ZXIga2l0YSB5YW5nIHRlbGFoIGtpdGEgdGVudHVrYW4gZGlhdGFzLg0KDQpgYGB7cn0NCmJldGFfMD0gMw0KYmV0YV8xPSA2DQpzaWdtYSA9IDINCmBgYA0KDQpEZW5nYW4gaW5mb3JtYXNpIHlhbmcgYWRhLCBraXRhIGFrYW4gdGFodSBkaXN0cmlidXNpIHNhbXBsaW5nIGtpdGEgeWFuZyBzZWhhcnVzbnlhOyANCg0KYGBge3J9DQoodmFyX2JldGFfMV9oYXQgPSBzaWdtYSBeIDIgLyBTeHgpDQpgYGANCmBgYHtyfQ0KKHZhcl9iZXRhXzBfaGF0ID0gc2lnbWEgXiAyICogKDEgLyBzYW1wbGVfc2l6ZSArIG1lYW4oeCkgXiAyIC8gU3h4KSkNCmBgYA0KDQokJFxoYXR7XGJldGF9XzEgXHNpbSBOKCAgNiwgMC4xMTc2MjM4KSQkDQpkYW4sDQokJFxoYXR7XGJldGF9XzAgXHNpbSBOKCAgMywgMC4wNCkkJA0KTWFrc3VkbnlhIGFkYWxhaCwNCiQkXGJlZ2lue2FsaWduZWR9IFx0ZXh0e0V9W1xoYXR7XGJldGF9XzFdICY9IDYgXFwgXHRleHR7VmFyfVtcaGF0e1xiZXRhfV8xXSAmPSAwLjExNzYyMzggXGVuZHthbGlnbmVkfSQkDQpkYW4NCiQkXGJlZ2lue2FsaWduZWR9IFx0ZXh0e0V9W1xoYXR7XGJldGF9XzBdICY9IDMgXFwgXHRleHR7VmFyfVtcaGF0e1xiZXRhfV8wXSAmPSAwLjA0XGVuZHthbGlnbmVkfSQkDQoNClNla2FyYW5nIGtpdGEgbWVuc2ltdWxhc2lrYW4gZGF0YSBkYXJpIG1vZGVsIGluaSBzZWJhbnlhayAxMC4wMDAga2FsaS4gUGVyaGF0aWthbiBiYWh3YSBtdW5na2luIGluaSBidWthbiBjYXJhIHlhbmcgYmFpayBkYWxhbSBgUmAgdW50dWsgbWVsYWt1a2FuIHNpbXVsYXNpLiBOYW11biwga2l0YSBtZWxha3VrYW4gc2ltdWxhc2kgZGVuZ2FuIGNhcmEgc2VwZXJ0aSBpbmkgYWdhciBraXRhIG1lbmRhcGF0a2FuIGtlamVsYXNhbi4gTWlzYWxueWEsIGtpdGEgYmlzYSBtZW5nZ3VuYWthbiBmdW5nc2kgYHNpbV9zbHIoKWAgZGFyaSBiYWdpYW4gc2ViZWx1bW55YS4gS2l0YSBqdWdhIG1lbWlsaWggdW50dWsgbWVueWltcGFuIHZhcmlhYmVsIGRpIGxpbmdrdW5nYW4gZ2xvYmFsIGtldGltYmFuZyBtZW1idWF0IGJpbmdrYWkgZGF0YSB1bnR1ayBzZXRpYXAga3VtcHVsYW4gZGF0YSBzaW11bGFzaSBiYXJ1LiANCg0KYGBge3J9DQpudW1fc2FtcGxlcyA9IDEwMDAwDQpiZXRhXzBfaGF0cyA9IHJlcCgwLCBudW1fc2FtcGxlcykNCmJldGFfMV9oYXRzID0gcmVwKDAsIG51bV9zYW1wbGVzKQ0KDQpmb3IgKGkgaW4gMTpudW1fc2FtcGxlcykgew0KICBlcHMgPSBybm9ybShzYW1wbGVfc2l6ZSwgbWVhbiA9IDAsIHNkID0gc2lnbWEpDQogIHkgICA9IGJldGFfMCArIGJldGFfMSAqIHggKyBlcHMNCiAgDQogIHNpbV9tb2RlbCA9IGxtKHkgfiB4KQ0KICANCiAgYmV0YV8wX2hhdHNbaV0gPSBjb2VmKHNpbV9tb2RlbClbMV0NCiAgYmV0YV8xX2hhdHNbaV0gPSBjb2VmKHNpbV9tb2RlbClbMl0NCn0NCmBgYA0KDQpTZXRpYXAga2l0YSBtZXNpbXVsYXNpa2FuIGRhdGEsIGtpdGEgYWthbiBtZW1wZXJvbGVoIG5pbGFpIGtvZWZpc2llbiB5YW5nIGRpcGVya2lyYWthbi4gVmFyaWFiZWwgJFxoYXR7XGJldGF9XzAkIGRhbiAkXGhhdHtcYmV0YX1fMSQgc2VrYXJhbmcgbWVueWltcGFuIDEwLjAwMCBuaWxhaSBzaW11bGFzaSAkXGhhdHtcYmV0YX1fMCQgZGFuICRcaGF0e1xiZXRhfV8xJCBtYXNpbmctbWFzaW5nLiANCg0KS2l0YSBwZXJ0YW1hLXRhbWEgaGFydXMgbWVtdmVyaWZpa2FzaSBkaXN0cmlidXNpIGRhcmkgJFxoYXR7XGJldGF9XzEkLg0KDQpgYGB7cn0NCm1lYW4oYmV0YV8xX2hhdHMpICMgZW1waXJpY2FsIG1lYW4NCmBgYA0KDQpgYGB7cn0NCmJldGFfMSAgICAgICAgICAgICMgdHJ1ZSBtZWFuDQpgYGANCg0KYGBge3J9DQp2YXIoYmV0YV8xX2hhdHMpICAjIGVtcGlyaWNhbCB2YXJpYW5jZQ0KYGBgDQoNCmBgYHtyfQ0KdmFyX2JldGFfMV9oYXQgICAgIyB0cnVlIHZhcmlhbmNlDQpgYGANCg0KS2l0YSBtZWxpaGF0IGJhaHdhIGNhcmEgZW1waXJpcyBkYW4gYmVuYXIgZGFuIHZhcmlhbnMgc2FuZ2F0IG1pcmlwLiBLaXRhIGp1Z2EgbWVtdmVyaWZpa2FzaSBiYWh3YSBkaXN0cmlidXNpIGVtcGlyaXMgYWRhbGFoIG5vcm1hbC4gVW50dWsgbWVsYWt1a2FubnlhLCBrYW1pIG1lcmVuY2FuYWthbiBoaXN0b2dyYW0gZGFyaSAkXGhhdHtcYmV0YX1fMSQsIGRhbiBtZW5hbWJhaGthbiBrdXJ2YSB1bnR1ayBkaXN0cmlidXNpIHNlYmVubmFybnlhIGRhcmkgJFxoYXR7XGJldGF9XzEkLiBLaXRhIGFrYW4gbWVuZ2d1bmFrYW4gYHByb2IgPSBUUlVFYCB1bnR1ayBtZWxldGFra2FuIGhpc3RvZ3JhbSBwYWRhIHNrYWxhIHlhbmcgc2FtYSBkZW5nYW4ga3VydmEgbm9ybWFsLiANCg0KYGBge3J9DQojIG5vdGUgbmVlZCB0byB1c2UgcHJvYiA9IFRSVUUNCmhpc3QoYmV0YV8xX2hhdHMsIHByb2IgPSBUUlVFLCBicmVha3MgPSAyMCwgDQogICAgIHhsYWIgPSBleHByZXNzaW9uKGhhdChiZXRhKVsxXSksIG1haW4gPSAiIiwgYm9yZGVyID0gImRvZGdlcmJsdWUiKQ0KY3VydmUoZG5vcm0oeCwgbWVhbiA9IGJldGFfMSwgc2QgPSBzcXJ0KHZhcl9iZXRhXzFfaGF0KSksIA0KICAgICAgY29sID0gImRhcmtvcmFuZ2UiLCBhZGQgPSBUUlVFLCBsd2QgPSAzKQ0KYGBgDQoNCktlbXVkaWFuLCBraXRhIG1lbmd1bGFuZ2kgcHJvc2VzIHlhbmcgc2FtYSB1bnR1ayAkXGhhdHtcYmV0YX1fMCQNCg0KYGBge3J9DQptZWFuKGJldGFfMF9oYXRzKSAjIGVtcGlyaWNhbCBtZWFuDQpgYGANCg0KYGBge3J9DQpiZXRhXzAgICAgICAgICAgICAjIHRydWUgbWVhbg0KYGBgDQoNCmBgYHtyfQ0KdmFyKGJldGFfMF9oYXRzKSAgIyBlbXBpcmljYWwgdmFyaWFuY2UNCmBgYA0KDQpgYGB7cn0NCnZhcl9iZXRhXzBfaGF0ICAgICMgdHJ1ZSB2YXJpYW5jZQ0KYGBgDQoNCmBgYHtyfQ0KaGlzdChiZXRhXzBfaGF0cywgcHJvYiA9IFRSVUUsIGJyZWFrcyA9IDI1LCANCiAgICAgeGxhYiA9IGV4cHJlc3Npb24oaGF0KGJldGEpWzBdKSwgbWFpbiA9ICIiLCBib3JkZXIgPSAiZG9kZ2VyYmx1ZSIpDQpjdXJ2ZShkbm9ybSh4LCBtZWFuID0gYmV0YV8wLCBzZCA9IHNxcnQodmFyX2JldGFfMF9oYXQpKSwNCiAgICAgIGNvbCA9ICJkYXJrb3JhbmdlIiwgYWRkID0gVFJVRSwgbHdkID0gMykNCmBgYA0KDQpEYWxhbSBzaW11bGFzaSBpbmksIGtpdGEgaGFueWEgbWVuc2ltdWxhc2lrYW4gc2VqdW1sYWggc2FtcGVsIHlhbmcgdGVyYmF0YXMuIFVudHVrIGJlbmFyLWJlbmFyIG1lbXZlcmlmaWthc2kgaGFzaWwgZGlzdHJpYnVzaSwga2l0YSBwZXJsdSBtZW5nYW1hdGkganVtbGFoIHNhbXBlbCB5YW5nIHRpZGFrIHRlcmJhdGFzLiBOYW11biwgcGxvdCBiZXJpa3V0IGhhcnVzIG1lbmplbGFza2FuIGJhaHdhIGppa2Ega2l0YSB0ZXJ1cyBtZWxha3VrYW4gc2ltdWxhc2ksIGhhc2lsIGVtcGlyaXNueWEgYWthbiBzZW1ha2luIG1lbmRla2F0aSBhcGEgeWFuZyBkaWhhcmFwa2FuLg0KDQpgYGB7cn0NCnBhcihtYXIgPSBjKDUsIDUsIDEsIDEpKSAjIGFkanVzdGVkIHBsb3QgbWFyZ2lucywgb3RoZXJ3aXNlIHRoZSAiaGF0IiBkb2VzIG5vdCBkaXNwbGF5DQpwbG90KGN1bXN1bShiZXRhXzFfaGF0cykgLyAoMTpsZW5ndGgoYmV0YV8xX2hhdHMpKSwgdHlwZSA9ICJsIiwgeWxpbSA9IGMoNS45NSwgNi4wNSksDQogICAgIHhsYWIgPSAiTnVtYmVyIG9mIFNpbXVsYXRpb25zIiwNCiAgICAgeWxhYiA9IGV4cHJlc3Npb24oIkVtcGlyaWNhbCBNZWFuIG9mICIgfiBoYXQoYmV0YSlbMV0pLA0KICAgICBjb2wgID0gImRvZGdlcmJsdWUiKQ0KYWJsaW5lKGggPSA2LCBjb2wgPSAiZGFya29yYW5nZSIsIGx3ZCA9IDIpDQpgYGANCg0KYGBge3J9DQpwYXIobWFyID0gYyg1LCA1LCAxLCAxKSkgIyBhZGp1c3RlZCBwbG90IG1hcmdpbnMsIG90aGVyd2lzZSB0aGUgImhhdCIgZG9lcyBub3QgZGlzcGxheQ0KcGxvdChjdW1zdW0oYmV0YV8wX2hhdHMpIC8gKDE6bGVuZ3RoKGJldGFfMF9oYXRzKSksIHR5cGUgPSAibCIsIHlsaW0gPSBjKDIuOTUsIDMuMDUpLA0KICAgICB4bGFiID0gIk51bWJlciBvZiBTaW11bGF0aW9ucyIsDQogICAgIHlsYWIgPSBleHByZXNzaW9uKCJFbXBpcmljYWwgTWVhbiBvZiAiIH4gaGF0KGJldGEpWzBdKSwNCiAgICAgY29sICA9ICJkb2RnZXJibHVlIikNCmFibGluZShoID0gMywgY29sID0gImRhcmtvcmFuZ2UiLCBsd2QgPSAyKQ0KYGBgDQoNCiMjIFN0YW5kYXIgS2VzYWxhaGFuIChTdGFuZGFyIEVycm9ycykNCg0KSmFkaSBzZWthcmFuZyBraXRhIHBlcmNheWEgcGFkYSBkdWEgaGFzaWwgZGlzdHJpYnVzaSwgeWFpdHU7DQokJFxiZWdpbnthbGlnbmVkfSBcaGF0e1xiZXRhfV8wICZcc2ltIE5cbGVmdCggIFxiZXRhXzAsIFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19XHJpZ2h0KSBccmlnaHQpIFxcIFxoYXR7XGJldGF9XzEgJlxzaW0gTlxsZWZ0KCAgXGJldGFfMSwgXGZyYWN7XHNpZ21hXjJ9e1Nfe3h4fX0gXHJpZ2h0KSBcZW5ke2FsaWduZWR9JCQNCg0KS2VtdWRpYW4gZGVuZ2FuIG1lbnN0YW5kYXJrYW4gaGFzaWwgaW5pLCBraXRhIG1lbmVtdWthbiwgDQokJFxmcmFje1xoYXR7XGJldGF9XzAgLSBcYmV0YV8wfXtcdGV4dHtTRH1bXGhhdHtcYmV0YX1fMF19IFxzaW0gTigwLCAxKSQkDQpkYW4NCiQkXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1x0ZXh0e1NEfVtcaGF0e1xiZXRhfV8xXX0gXHNpbSBOKDAsIDEpJCQNCmRpbWFuYSwNCiQkXHRleHR7U0R9W1xoYXR7XGJldGF9XzBdID0gXHNpZ21hXHNxcnR7XGZyYWN7MX17bn0gKyBcZnJhY3tcYmFye3h9XjJ9e1Nfe3h4fX19JCQNCmRhbg0KJCRcdGV4dHtTRH1bXGhhdHtcYmV0YX1fMV0gPSBcZnJhY3tcc2lnbWF9e1xzcXJ0e1Nfe3h4fX19JCQNCg0KS2FyZW5hIGtpdGEgdGlkYWsgdGFodSAkXHNpZ21hJCBkYWxhbSBwcmFrdGlrbnlhLCBtYWthIGtpdGEgaGFydXMgbWVtcGVya2lyYWthbm55YSBtZW5nZ3VuYWthbiAkc19lJCwgeWFuZyBha2FuIGtpdGEgbWFzdWtrYW4ga2UgZWtzcHJlc2kga2l0YSB5YW5nIGFkYSB1bnR1ayBzdG5hZGFyIGRldmlhc2kgcGVya2lyYWFuIGtpdGEuIA0KDQpLZWR1YSBla3NwcmVzaSBiYXJ1IGluaSBkaXNlYnV0ICoqc3RhbmRhciBrZXNhbGFoYW4gKHN0YW5kYXIgZXJyb3JzKSoqIHlhbmcgbWVydXBha2FuICpwZXJraXJhYW4qIHN0YW5kYXIgZGV2aWFzaSBkYXJpIGRpc3RyaWJ1c2kgcGVuZ2FtYmlsYW4gc2FtcGVsLg0KDQokJFx0ZXh0e1NFfVtcaGF0e1xiZXRhfV8wXSA9IHNfZVxzcXJ0e1xmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19fSQkDQoNCiQkXHRleHR7U0V9W1xoYXR7XGJldGF9XzFdID0gXGZyYWN7c19lfXtcc3FydHtTX3t4eH19fSQkDQoNClNla2FyYW5nIGppa2Ega2l0YSBtZW1iYWdpIGRlbmdhbiBzdGFuZGFyIGtlc2FsYWhhbiwgYWxpaC1hbGloIHN0YW5kYXIgZGV2aWFzaS4gS2l0YSBha2FuIG1lbXBlcm9sZWggaGFzaWwgYmVyaWt1dCB5YW5nIG1lbXVuZ2tpbmthbiBraXRhIHVudHVrIG1lbWJ1YXQgaW50ZXJ2YWwga2VwZXJjYXlhYW4gZGFuIG1lbGFrdWthbiBwZW5ndWppYW4gaGlwb3Rlc2lzLg0KDQokJFxmcmFje1xoYXR7XGJldGF9XzAgLSBcYmV0YV8wfXtcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMF19IFxzaW0gdF97bi0yfSQkDQoNCiQkXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXX0gXHNpbSB0X3tuLTJ9JCQNCg0KVW50dWsgbWVsaWhhdCBpbmksIHBlcnRhbWEga2l0YSBoYXJ1cyBtZW1wZXJoYXRpa2FuIGJhaHdhLA0KDQokJFxmcmFje1x0ZXh0e1JTU319e1xzaWdtYV4yfSA9IFxmcmFjeyhuLTIpc19lXjJ9e1xzaWdtYV4yfSBcc2ltIFxjaGlfe24tMn1eMiQkDQoNCkp1Z2EgcGVybHUgZGlpbmdhdCBiYWh3YSB2YXJpYWJlbCBhY2FrICRUJCBkaWRlZmluaXNpa2FuIHNlYmFnYWksDQoNCiQkVCA9IFxmcmFje1p9e1xzcXJ0e1xmcmFje1xjaGlfe2R9XjJ9e2R9fX0kJA0KDQptZW5naWt1dGkgZGl0cmlidXNpICR0JCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gJGQkLCBkaW1hbmEgJFxjaGlfe2R9XjIkIGFkYWxhaCB2YXJpYWJlbCBhY2FrICRcY2hpXjIkIGRlbmdhbiBkZXJhamF0IGtlYmViYXNhbiAkZCQuDQoNCktpdGEgbWVudWxpcywgDQokJFQgXHNpbSB0X2QkJA0KdW50dWsgbWVuZ2F0YWthbiBiYWh3YSB2YXJpYWJlbCBhY2FrICRUJCBtZW5naWt1dGkgZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuICRkJC4NCg0KS2VtdWRpYW4ga2l0YSBtZW5nZ3VuYWthbiB0cmlrIGtsYXNpayBkZW5nYW4gImthbGlrYW4gZGVuZ2FuMSIgZGFuIG1lbnl1c3VuIHVsYW5nIGJlYmVyYXBhIHVudHVrIHNhbXBhaSBwYWRhDQoNCiQkXGJlZ2lue2FsaWduZWR9IFxmcmFje1xoYXR7XGJldGF9XzEgLSBcYmV0YV8xfXtcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV19ICY9IFxmcmFje1xoYXR7XGJldGF9XzEgLSBcYmV0YV8xfXtzX2UgLyBcc3FydHtTX3t4eH19fSBcXCAmPSBcZnJhY3tcaGF0e1xiZXRhfV8xIC0gXGJldGFfMX17c19lIC8gXHNxcnR7U197eHh9fX0gXGNkb3QgXGZyYWN7XHNpZ21hIC8gXHNxcnR7U197eHh9fX17XHNpZ21hIC8gXHNxcnR7U197eHh9fX0gXFwgJj0gXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1xzaWdtYSAvIFxzcXJ0e1Nfe3h4fX19IFxjZG90IFxmcmFje1xzaWdtYSAvIFxzcXJ0e1Nfe3h4fX19e3NfZSAvIFxzcXJ0e1Nfe3h4fX19IFxcICY9IFxmcmFje1xoYXR7XGJldGF9XzEgLSBcYmV0YV8xfXtcc2lnbWEgLyBcc3FydHtTX3t4eH19fSBcYmlnZy8gXHNxcnR7XGZyYWN7c19lXjJ9e1xzaWdtYV4yfX0gXFwgJj0gXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1x0ZXh0e1NEfVtcaGF0e1xiZXRhfV8xXX0gXGJpZ2cvIFxzcXJ0e1xmcmFje1xmcmFjeyhuIC0gMilzX2VeMn17XHNpZ21hXjJ9fXtuIC0gMn19IFxzaW0gXGZyYWN7Wn17XHNxcnR7XGZyYWN7XGNoaV97bi0yfV4yfXtuLTJ9fX0gXHNpbSB0X3tuLTJ9IFxlbmR7YWxpZ25lZH0kJA0KDQpkaW1hbmEgJFogXHNpbSBOKDAsMSkkDQoNCkluZ2F0bGFoIGJhaHdhIGRpc3RyaWJ1c2lueWEgJHQkIG1pcmlwIGRlbmdhbiBzdGFuZGFyIG5vcm1hbCwgdGV0YXBpIGRlbmdhbiBla29yIHlhbmcgbGViaWggYmVyYXQuIEtldGlrYSBkZXJhamF0IGtlYmViYXNhbiBtZW5pbmdrYXQsIG1ha2EgZGlzdHJpYnVzaSAkdCQgbWVuamFkaSBsZWJpaCBkYW4gbGViaWggc2VwZXJ0aSBzdGFuZGFyIG5vcm1hbC4gRGliYXdhaCBpbmkga2l0YSBha2FuIG1lbXBsb3QgZGlzdHJpYnVzaSBub3JtYWwgeWFuZyBzdGFuZGFyIHNlcnRhIGR1YSBjb250b2ggZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgYmVyYmVkYS4gUGVyaGF0aWthbiBiYWdhaW1hbmEgZGlzdHJpYnVzaSAkdCQgZGVuZ2FuIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgbGViaWggYmVzYXIgYWthbiBsZWJpaCBtaXJpcCBkZW5nYW4ga3VydmEgc3RhbmRhciBub3JtYWwuDQoNCmBgYHtyfQ0KIyBkZWZpbmUgZ3JpZCBvZiB4IHZhbHVlcw0KeCA9IHNlcSgtNCwgNCwgbGVuZ3RoID0gMTAwKQ0KDQojIHBsb3QgY3VydmUgZm9yIHN0YW5kYXJkIG5vcm1hbA0KcGxvdCh4LCBkbm9ybSh4KSwgdHlwZSA9ICJsIiwgbHR5ID0gMSwgbHdkID0gMiwNCiAgICAgeGxhYiA9ICJ4IiwgeWxhYiA9ICJEZW5zaXR5IiwgbWFpbiA9ICJOb3JtYWwgdnMgdCBEaXN0cmlidXRpb25zIikNCiMgYWRkIGN1cnZlcyBmb3IgdCBkaXN0cmlidXRpb25zDQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEpLCBsdHkgPSAzLCBsd2QgPSAyLCBjb2wgPSAiZGFya29yYW5nZSIpDQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEwKSwgbHR5ID0gMiwgbHdkID0gMiwgY29sID0gImRvZGdlcmJsdWUiKQ0KDQojIGFkZCBsZWdlbmQNCmxlZ2VuZCgidG9wcmlnaHQiLCB0aXRsZSA9ICJEaXN0cmlidXRpb25zIiwNCiAgICAgICBsZWdlbmQgPSBjKCJ0LCBkZiA9IDEiLCAidCwgZGYgPSAxMCIsICJTdGFuZGFyZCBOb3JtYWwiKSwgDQogICAgICAgbHdkID0gMiwgbHR5ID0gYygzLCAyLCAxKSwgY29sID0gYygiZGFya29yYW5nZSIsICJkb2RnZXJibHVlIiwgImJsYWNrIikpDQpgYGANCg0KIyMgSW50ZXJ2YWwgS2V5YWtpbmFuIHVudHVrIEtlbWlyaW5nYW4gZGFuIFBlcnBvdG9uZ2FuIChJbnRlcmNlcHQpDQoNCkluZ2F0bGFoIGJhaHdhIGludGVydmFsIGtlcGVyY2F5YWFuIHNlcmluZyBrYWxpIGJlcmJlbnR1azoNCg0KJCRcdGV4dHtFU1R9IFxwbSBcdGV4dHtDUklUfSBcY2RvdCBcdGV4dHtTRX0kJA0KYXRhdSANCiQkXHRleHR7RVNUfSBccG0gXHRleHR7TUFSR0lOfSQkDQoNCkRpbWFuYTogJFx0ZXh0e0VTVH0kIGFkYWxhaCBwZXJraXJhYW4gdW50dWsgcGFyYW1ldGVyIHlhbmcgZGltaW5hdGksICRcdGV4dHtTRX0kIGFkYWxhaCBwZXJraXJhYW4gc3RhbmRhciBrZXNhbGFoYW4gKHN0YW5kYXIgZXJyb3JzKSwgZGFuICRcdGV4dHtNQVJHSU59ID0gXHRleHR7Q1JJVH0gXGNkb3QgXHRleHR7U0V9JA0KDQpLZW11ZGlhbiwgdW50dWsgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQga2l0YSBkYXBhdCBtZW1idWF0IGludGVydmFsIGtlcGVyY2F5YWFuIG1lbmdndW5ha2FuOw0KDQokJFxoYXR7XGJldGF9XzAgXHBtIHRfe1xhbHBoYS8yLCBuIC0gMn0gXGNkb3QgXHRleHR7U0V9W1xoYXR7XGJldGF9XzBdIFxxdWFkIFxxdWFkIFxxdWFkIFxoYXR7XGJldGF9XzAgXHBtIHRfe1xhbHBoYS8yLCBuIC0gMn0gXGNkb3Qgc19lXHNxcnR7XGZyYWN7MX17bn0rXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19fSQkDQpkYW4NCiQkXGhhdHtcYmV0YX1fMSBccG0gdF97XGFscGhhLzIsIG4gLSAyfSBcY2RvdCBcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV0gIFxxdWFkIFxxdWFkIFxxdWFkIFxoYXR7XGJldGF9XzEgXHBtIHRfe1xhbHBoYS8yLCBuIC0gMn0gXGNkb3QgXGZyYWN7c19lfXtcc3FydHtTX3t4eH19fSQkDQoNCmRpbWFuYSAkdF97XGFscGhhLzIsIG4gLSAyfSQgYWRhbGFoIG5pbGFpIGtyaXRpcyBzZWRlbWlraWFuIHJ1cGEgJFAodF97bi0yfSA+IHRfe1xhbHBoYS8yLCBuIC0gMn0pID0gXGFscGhhLzIkDQoNCiMjIFBlbmd1amlhbiBIaXBvdGVzaXMNCg0KKiJXZSBtYXkgc3BlYWsgb2YgdGhpcyBoeXBvdGhlc2lzIGFzIHRoZSDigJhudWxsIGh5cG90aGVzaXPigJksIGFuZCBpdCBzaG91bGQgYmUgbm90ZWQgdGhhdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIG5ldmVyIHByb3ZlZCBvciBlc3RhYmxpc2hlZCwgYnV0IGlzIHBvc3NpYmx5IGRpc3Byb3ZlZCwgaW4gdGhlIGNvdXJzZSBvZiBleHBlcmltZW50YXRpb24iKiAtICoqUm9uYWxkIEF5bG1lciBGaXNoZXIqKg0KDQpJbmdhdCBiYWh3YSB1amkgc3RhdGlzdGlrICgkXHRleHR7VFN9JCkgdW50dWsgc2VidWFoIHBlbmd1amlhbiwgc2VyaW5nIGJlcnVwYTsNCg0KJCRcdGV4dHtUU30gPSBcZnJhY3tcdGV4dHtFU1R9IC0gXHRleHR7SFlQfX17XHRleHR7U0V9fSQkDQoNCmRpbWFuYSwgJFx0ZXh0e0VzdH0kIGFkYWxhaCBwZXJraXJhYW4gdW50dWsgcGFyYW1ldGVyIHlhbmcgZGltaW5hdGksICRcdGV4dHtIWVB9JCBhZGFsYWggbmlsYWkgaGlwb3Rlc2lzIGRhcmkgcGFyYW1ldGVyLCBkYW4gJFx0ZXh0e1NFfSQgYWRhbGFoIHBlcmtpcmFhbiBzdGFuZGFyIGtlc2FsYWhhbiAoc3RhbmRhciBlcnJvcnMpLiANCg0KSmFkaSwgdW50dWsgbWVuZ3VqaW55YTsNCiQkSF8wOiBcYmV0YV8wID0gXGJldGFfezAwfSBccXVhZCBcdGV4dHt2c30gXHF1YWQgSF8xOiBcYmV0YV8wIFxuZXEgXGJldGFfezAwfSQkDQoNCmtpdGEgbWVuZ2d1bmFrYW4gdWppIHN0YXRpc3RpaywNCg0KJCR0ID0gXGZyYWN7XGhhdHtcYmV0YX1fMCAtIFxiZXRhX3swMH19e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8wXX0gPSBcZnJhY3tcaGF0e1xiZXRhfV8wLVxiZXRhX3swMH19e3NfZVxzcXJ0e1xmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19fX0kJA0KDQpkaW1hbmEsIGRpYmF3YWggaGlwb3Rlc2lzIG5vbCwgZGFuIG1lbmdpa3V0aSBkaXN0cmlidXNpICR0JCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gJG4tMiQuIEtpdGEgZ3VuYWthbiAkXGJldGFfezAwfSQgdW50dWsgbWVudW5qdWtrYW4gbmlsYWkgaGlwb3Rlc2lzICRcYmV0YV8wJC4NCg0KQmVnaXR1IHB1bGEgdW50dWsgbWVuZ3VqaQ0KJCRIXzA6IFxiZXRhXzEgPSBcYmV0YV97MTB9IFxxdWFkIFx0ZXh0e3ZzfSBccXVhZCBIXzE6IFxiZXRhXzEgXG5lcSBcYmV0YV97MTB9JCQNCg0Ka2l0YSBtZW5nZ3VuYWthbiB1amkgc3RhdGlzdGlrDQokJHQgPSBcZnJhY3tcaGF0e1xiZXRhfV8xLVxiZXRhX3sxMH19e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXX0gPSBcZnJhY3tcaGF0e1xiZXRhfV8xLVxiZXRhX3sxMH19e3NfZSAvIFxzcXJ0e1Nfe3h4fX19JCQNCg0KeWFuZyBsYWdpLWxhZ2ksIGRpYmF3YWggaGlwb3Rlc2lzIG5vbCwgbWVuZ2lrdXRpIGRpc3RyaWJ1c2kgJHQkIGRlbmdhbiAgZGVyYWphdCBrZWJlYmFzYW4gJG4tMiQuIEtpdGEgc2VrYXJhbmcgbWVuZ2d1bmFrYW4gJFxiZXRhX3sxMH0kIHVudHVrIG1lbnVuanVra2FuIG5pbGFpIGhpcG90ZXNpcyAkXGJldGFfMSQuDQoNCiMjIENvbnRvaCBgY2Fyc2ANCg0KU2VrYXJhbmcga2l0YSBrZW1iYWxpIGtlIGNvbnRvaCBkYXRhIGBjYXJzYCBkYXJpIGJhZ2lhbiB0ZXJha2hpciB1bnR1ayBtZW5naWx1c3RyYXNpa2FuIGtvbnNlcCBpbmkuIEtpdGEgcGVydGFtYS10YW1hIG1lbnllc3VhaWthbiBtb2RlbCBtZW5nZ3VuYWthbiBgbG0oKWAsIGtlbXVkaWFuIG1lbmdndW5ha2FuIGBzdW1tYXJ5KClgIHVudHVrIG1lbGloYXQgaGFzaWwgc2VjYXJhIGxlYmloIHJpbmNpLg0KDQpgYGB7cn0NCnN0b3BfZGlzdF9tb2RlbCA9IGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpDQpzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkNCmBgYA0KDQojIyMgUGVuZ3VqaWFuIGRhbGFtIGBSYA0KDQpTZWthcmFuZyBraXRhIGFrYW4gbWVtYmFoYXMgaGFzaWwgeWFuZyBkaXRhbXBpbGthbiB5YW5nIGRpc2VidXQgYGNvZWZmaWNpZW50c2AuIFBlcnRhbWEsIGluZ2F0bGFoIGJhaHdhIGtpdGEgZGFwYXQgbWVuZ2Vrc3RyYWsgaW5mb3JtYXNpIGluaSBzZWNhcmEgbGFuZ3N1bmcuDQoNCmBgYHtyfQ0KbmFtZXMoc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpJGNvZWZmaWNpZW50cw0KYGBgDQoNCkZ1bmdzaSBgbmFtZXMoKWAgbWVtYmVyaXRhaHUga2l0YSB0ZW50YW5nIGluZm9ybWFzaSBhcGEgc2FqYSB5YW5nIHRlcnNlZGlhLCBkYW4ga2VtdWRpYW4ga2l0YSBtZW5nZ3VuYWthbiBvZXByYXRvciBgJGAgZGFuIGBjb2VmZmljaWVudHNgIHVudHVrIG1lbmdla3N0cmFrIGluZm9ybWFzaSB5YW5nIGtpdGEgaW5naW5rYW4uIER1YSBuaWxhaSBkaXNpbmkgaGFydXMgc2VnZXJhIGFrcmFiLg0KDQokJFxoYXR7XGJldGF9XzAgPSAtMTcuNTc5MDk0OSQkDQpkYW4NCiQkXGhhdHtcYmV0YX1fMSA9IDMuOTMyNDA4OCQkDQoNCnlhbmcgbWVydXBha2FuIHBlcmtpcmFhbiBraXRhIHVudHVrIHBhcmFtZXRlciBtb2RlbCAkXGJldGFfMCQgZGFuICRcYmV0YV8xJC4NCg0KU2VrYXJhbmcgbWFyaSBraXRhIGZva3VzIGRlbmdhbiBrZWx1YXJhbiBiYXJpcyBrZWR1YSwgeWFuZyByZWxldmFuIGRlbmdhbiAkXGJldGFfMSQuDQoNCmBgYHtyfQ0Kc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpJGNvZWZmaWNpZW50c1syLF0NCmBgYA0KDQpTZWthbGkgbGFnaSwgbmlsYWkgcGVydGFtYSBgRXN0aW1hdGVgIGFkYWxhaA0KJCRcaGF0e1xiZXRhfV8xID0gMy45MzI0MDg4JCQNCg0KTmlsYWkga2VkdWEgYFN0ZC4gRXJyb3JgIGFkYWxhaCBzdGFuZGFyIGtlc2FsYWhhbiAoc3RhbmRhciBlcnJvcnMpIGRhcmkgJFxoYXR7XGJldGFfMX0kLA0KJCRcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV0gPSBcZnJhY3tzX2V9e1xzcXJ0e1Nfe3h4fX19ID0gMC40MTU1MTI4LiQkDQoNCk5pbGFpIGtldGlnYSBgdCB2YWx1ZWAgYWRhbGFoIG5pbGFpIHVqaSBzdGF0aXN0aWsgdW50dWsgcGVuZ3VqaWFuICRIXzA6IFxiZXRhXzEgPSAwJCB2cyAkSF8xOiBcYmV0YV8xIFxuZXEgMCQsDQokJHQgPSBcZnJhY3tcaGF0e1xiZXRhfV8xLTB9e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXX0gPSBcZnJhY3tcaGF0e1xiZXRhfV8xLTB9e3NfZSAvIFxzcXJ0e1Nfe3h4fX19ID0gOS40NjM5OSQkDQoNClRlcmFraGlyIGBQcig+fHR8KWAgbWVtYmVyaSBraXRhIG5pbGFpIHAgZGFyaSBwZW5ndWppYW4gaXR1Lg0KDQokJFx0ZXh0e3AtdmFsdWV9ID0gMS40ODk4MzY1XHRpbWVzIDEwXnstMTJ9JCQNCg0KUGVyaGF0aWthbiBkaXNpbmksIGtpdGEgc2VjYXJhIGtodXN1cyBtZW5ndWppIGFwYWthaCBiZW5hciBhdGF1IHRpZGFrIGJhaHdhICRcYmV0YV8xID0gMCQuDQoNCkJhcmlzIHBlcnRhbWEga2VsdWFyYW4gbWVsYXBvcmthbiBuaWxhaSB5YW5nIHNhbWEsIHRldGFwaSB1bnR1ayAkXGJldGFfMCQNCg0KYGBge3J9DQpzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRzWzEsXQ0KYGBgDQoNClNpbmdrYXRueWEsIGNvZGluZyBiZXJpa3V0IG1lbnlpbXBhbiBpbmZvcm1hc2kgYHN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHNgIGRhbGFtIHZhcmlhYmVsIGJhcnUgYHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9gLCBsYWx1IG1lbmdla3N0cmFrIHNldGlhcCBlbGVtZW4gbWVuamFkaSB2YXJpYWJlbCBiYXJ1IHlhbmcgYWthbiBtZW5qZWxhc2thbiBpbmZvcm1hc2kgeWFuZyBkaWthbmR1bmdueWEuDQoNCmBgYHtyfQ0Kc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mbyA9IHN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHMNCg0KYmV0YV8wX2hhdCAgICAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1sxLCAxXSAjIEVzdGltYXRlDQpiZXRhXzBfaGF0X3NlICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzEsIDJdICMgU3RkLiBFcnJvcg0KYmV0YV8wX2hhdF90ICAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1sxLCAzXSAjIHQgdmFsdWUNCmJldGFfMF9oYXRfcHZhbCA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMSwgNF0gIyBQcig+fHR8KQ0KDQpiZXRhXzFfaGF0ICAgICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzIsIDFdICMgRXN0aW1hdGUNCmJldGFfMV9oYXRfc2UgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMiwgMl0gIyBTdGQuIEVycm9yDQpiZXRhXzFfaGF0X3QgICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzIsIDNdICMgdCB2YWx1ZQ0KYmV0YV8xX2hhdF9wdmFsID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1syLCA0XSAjIFByKD58dHwpDQpgYGANCg0KS2FtaSBrZW11ZGlhbiBkYXBhdCBtZW12ZXJpZmlrYXNpIGJlYmVyYXBhIGVrc3ByZXNpIHlhbmcgc2V0YXJhOiBzdGF0aXN0aWsgdWppICR0JCB1bnR1ayAkXGhhdHtcYmV0YV8xfSQgZGFuIG5pbGFpIHAgZHVhIHNpc2kgeWFuZyB0ZXJrYWl0IGRlbmdhbiB1amkgc3RhdGlzdGlrIHRlcnNlYnV0LiANCg0KYGBge3J9DQooYmV0YV8xX2hhdCAtIDApIC8gYmV0YV8xX2hhdF9zZQ0KYGBgDQoNCmBgYHtyfQ0KYmV0YV8xX2hhdF90DQpgYGANCg0KYGBge3J9DQoyICogcHQoYWJzKGJldGFfMV9oYXRfdCksIGRmID0gbGVuZ3RoKHJlc2lkKHN0b3BfZGlzdF9tb2RlbCkpIC0gMiwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQoNCmBgYHtyfQ0KYmV0YV8xX2hhdF9wdmFsDQpgYGANCg0KIyMjIFNpZ25pZmlrYW5zaSBSZWdyZXNpLCBVamktdA0KDQpLaXRhIGJlcmhlbnRpIHNlamVuYWsgdW50dWsgbWVtYmFoYXMgKipwZW50aW5nbnlhIHVqaSByZWdyZXNpKiouIFBlcnRhbWEsIHBlcmhhdGlrYW4gYmFod2EgYmVyZGFzYXJrYW4gaGFzaWwgZGlzdHJpYnVzaSBkaSBhdGFzLCBraXRhIGRhcGF0IG1lbmd1amkgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQgdGVyaGFkYXAgbmlsYWkgdGVydGVudHUsIGRhbiBtZWxha3VrYW4gcGVuZ3VqaWFuIHNhdHUgZGFuIGR1YSBzaXNpLg0KDQpOYW11biwgc2F0dSB0ZXMgeWFuZyBzYW5nYXQgc3Blc2lmaWssDQokJEhfMDogXGJldGFfMSA9IDAgXHF1YWQgXHRleHR7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIDAkJA0KcGFsaW5nIHNlcmluZyBkaWd1bmFrYW4uIE1hcmkga2l0YSBwaWtpcmthbiBwZW5ndWppYW4gaW5pIGRhbGFtIGthaXRhbm55YSBkZW5nYW4gbW9kZWwgcmVncmVzaSBsaW5pZXIgc2VkZXJoYW5hLA0KJCRZX2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X2kgKyBcZXBzaWxvbl9pJCQNCg0KSmlrYSBraXRhIG1lbmdhc3Vtc2lrYW4gaGlwb3Rlc2lzIG5vbCBiZW5hciwgbWFrYSAkXGJldGFfMT0wJCBkYW4ga2l0YSBtZW1pbGlraSBtb2RlbG55YSwgJCRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faSQkDQoNCkRhbGFtIG1vZGVsIGluaSwgcmVzcG9uICoqdGlkYWsqKiBiZXJnYW50dW5nIHBhZGEgcHJlZGlrdG9yLiBKYWRpIGtpdGEgYmlzYSBtZW1pa2lya2FuIHRlcyBpbmkgZGVuZ2FuIGNhcmEgYmVyaWt1dCwNCg0KMS4gRGliYXdhaCAkSF8wJCB0aWRhayBhZGEgaHVidW5nYW4gbGluaWVyIHlhbmcgc2lnbmlmaWthbiBhbnRhcmEgJHgkIGRhbiAkeSQuDQoyLiBEaWJhd2FoICRIXzEkIGFkYSBodWJ1bmdhbiAqKmxpbmllcioqIHlhbmcgc2lnbmlmaWthbiBhbnRhcmEgJHgkIGRhbiAkeSQuDQoNClVudHVrIGNvbnRvaCBgY2Fyc2AsDQoNCjEuIERpYmF3YWggJEhfMCQgdGlkYWsgYWRhIGh1YnVuZ2FuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuIA0KMi4gRGliYXdhaCAkSF8xJCBhZGEgaHVidW5nYW4gKipsaW5pZXIqKiB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuDQoNClNla2FsaSBsYWdpLCBwZW5ndWppYW4gaXR1IHRlcmxpaGF0IHBhZGEga2VsdWFyYW4gZGFyaSBgc3VtbWFyeSgpYCwNCiQkXHRleHR7cC12YWx1ZX0gPSAxLjQ4OTgzNjVcdGltZXMgMTBeey0xMn0kJA0KDQpEZW5nYW4gbmlsYWkgcCB5YW5nIHNhbmdhdCByZW5kYWggaW5pLCBraXRhIGFrYW4gbWVub2xhayBoaXBvdGVzaXMgbm9sIGRlbmdhbiBhbGFzYW4gYXBhcHVuIHRpbmdrYXQgJFxhbHBoYSQsIGthdGFrYW5sYWggbWlzYWxueWEgJFxhbHBoYSA9IDAsMDEkLiBKYWRpIGtpdGEga2F0YWthbiBhZGEgaHVidW5nYW4gKipsaW5pZXIqKiB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuIFBlcmhhdGlrYW4gYmFod2Ega2l0YSBtZW5la2Fua2FuICoqbGluaWVyKiouDQoNCiFbXShDOlxVc2Vyc1xJTUVMREEgU0lBTlRVUklcRG93bmxvYWRzXGNzbWlkdGVybS5wbmcpDQpEYWxhbSBwbG90IGRhdGEgc2ltdWxhc2kgaW5pLCBraXRhIGJpc2EgbWVsaWhhdCBodWJ1bmdhbiB5YW5nIGplbGFzIGFudGFyYSAkeCQgZGFuICR5JC4gTmFtdW4sIGluaSBidWthbiBodWJ1bmdhbiBsaW5pZXIuIEppa2Ega2l0YSBtZW1hc3Vra2FuIGdhcmlzIGtlIGRhdGEgaW5pLCBpdHUgc2FuZ2F0IGRhdGFyLiBUZXMgeWFuZyBkaWhhc2lsa2FuIHVudHVrICRIXzA6IFxiZXRhXzEgPSAwJCB2cyAkSF8xOiBcYmV0YV8xIFxuZXEgMCQgbWVtYmVyaWthbiBuaWxhaSBwIHlhbmcgYmVzYXIsIGRhbGFtIGthc3VzIGluaSBiZXJuaWxhaSAkMC43NTY0NTQ4JC4gSmFkaSwga2l0YSBha2FuICoqZ2FnYWwgdW50dWsgbWVub2xhayoqIGRhbiBtZW5nYXRha2FuIGJhaHdhIHRpZGFrIGFkYSBodWJ1bmdhbiBsaW5pZXIgeWFuZyBzaWduaWZpa2FuIGFudGFyYSAkeCQgZGFuICR5JC4gS2l0YSBha2FuIG1lbGloYXQgbmFudGkgYmFnYWltYW5hIG1lbnllc3VhaWthbiBrdXJ2YSBrZSBkYXRhIGluaSBtZW5nZ3VuYWthbiBtb2RlbCAibGluaWVyIiAkSF8wOiBcYmV0YV8xID0gMCQgdnMgJEhfMTogXGJldGFfMSBcbmVxIDAkIGhhbnlhIGRhcGF0IG1lbmRldGVrc2kgaHVidW5nYW4geWFuZyBnYXJpcyBsdXJ1cyAobGluaWVyKS4NCg0KIyMjIEludGVydmFsIEtleWFraW5hbiBEYWxhbSBgUmANCg0KRGVuZ2FuIG1lbmdndW5ha2FuIGBSYCBraXRhIGRhcGF0IGRlbmdhbiBtdWRhaCBtZW5kYXBhdGthbiBpbnRlcnZhIGtlcGVyY2F5YWFuIHVudGsgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQuDQoNCmBgYHtyfQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSkNCmBgYA0KDQpJbmkgc2VjYXJhIG90b21hdGlzIGFrYW4gbWVuZ2hpdHVuZyBpbnRlcnZhbCBrZXBlcmNheWFhbiA5OSUgdW50dWsga2VkdWFueWEgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQsIGJhcmlzIHBlcnRhbWEgdW50dWsgJFxiZXRhXzAkLCBkYW4gYmFyaXMga2VkdWEgdW50dWsgJFxiZXRhXzEkLg0KDQpgY2Fyc2Agc2ViYWdhaSBjb250b2ggc2FhdCBtZW5naW50ZXJwcmV0YXNpa2FuIGludGVydmFsIGluaSwga2l0YSBrYXRha2FuIDk5JSB5YWtpbiBiYWh3YSB1bnR1ayBwZW5pbmdrYXRhbiBrZWNlcGF0YW4gMSBtaWwgcGVyIGphbSwgcGVuaW5na2F0YW4gcmF0YS1yYXRhIGphcmFrIGJlcmhlbnRpIGFkYWxhaCBhbnRhcmEgJDIuODE3OTE4NyQgZGFuICQ1LjA0Njg5ODgkIGtha2ksIHlhbmcgbWVydXBha2FuIGludGVydmFsIHVudHVrICRcYmV0YV8xJC4NCg0KUGVyaGF0aWthbiBiYWh3YSBpbnRlcnZhbCBrZXBlcmNheWFhbiA5OSUgaW5pICoqdGlkYWsqKiBtZW5nYW5kdW5nIG5pbGFpIGhpcG90ZXNpcyAwLiBLYXJlbmEgdGlkYWsgbWVuZ2FuZHVuZyAwLCBpbmkgc2V0YXJhIGRlbmdhbiBtZW5vbGFrIHBlbmd1amlhbiAkSF8wOiBcYmV0YV8xID0gMCQgdnMgJEhfMTogXGJldGFfMSBcbmVxIDAkIGRpICRcYWxwaGEgPSAwLDAxJCwgeWFuZyB0ZWxhaCBraXRhIGxpaGF0IHNlYmVsdW1ueWEuDQoNCkthbGlhbiBoYXJ1cyBjdXJpZ2EgdGVyaGFkYXAgaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgJFxiZXRhXzAkLCBrYXJlbmEgbWVuY2FrdXAgbmlsYWkgbmVnYXRpZiwgeWFuZyBzZXN1YWkgZGVuZ2FuIGphcmFrIGhlbnRpIG5lZ2F0aWYuIFNlY2FyYSB0ZWtuaXMgaW50ZXJwcmV0YXNpbnlhIGFkYWxhaCA5OSUga2l0YSB5YWtpbiBiYWh3YSBqYXJhayBiZXJoZW50aSByYXRhLXJhdGEgc2VidWFoIG1vYmlsIHlhbmcgbWVuZW1wdWggamFyYWsgMCBtaWwgcGVyIGphbSBhZGFsYWggYW50YXJhICQtMzUuNzA2NjEwMyQgZGFuICQwLjU0ODQyMDUkIGtha2ksIHRldGFwaSBraXRhIHRpZGFrIGJlZ2l0dSBwZXJjYXlhLCBrYXJlbmEga2l0YSBiZW5hci1iZW5hciB5YWtpbiBiYWh3YSBpdHUgYWthbiBtZW5qYWRpIG5vbi1uZWdhdGlmLg0KDQpDYXRhdGFuLCBraXRhIGRhcGF0IG1lbmdla3N0cmFrIG5pbGFpIHRlcnRlbnR1IGRhcmkga2VsdWFyYW4gaW5pIGRlbmdhbiBiZWJlcmFwYSBjYXJhLiBDb2RpbmcgaW5pIHRpZGFrIGRpamFsYW5rYW4sIGRhbiBzZWJhZ2FpIGdhbnRpbnlhLCBrYWxpYW4gaGFydXMgbWVtZXJpa3NhIGh1YnVuZ2FubnlhIGRlbmdhbiBrZWx1YXJhbiBjb2RpbmcgZGlhdGFzLiANCg0KYGBge3J9DQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsxLF0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzEsIDFdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsxLCAyXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIHBhcm0gPSAiKEludGVyY2VwdCkiLCBsZXZlbCA9IDAuOTkpDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsyLF0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpWzIsIDFdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsyLCAyXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIHBhcm0gPSAic3BlZWQiLCBsZXZlbCA9IDAuOTkpDQpgYGANCg0KS2l0YSBqdWdhIGRhcGF0IG1lbXZlcmlmaWthc2kga2Fsa3VsYXNpIHlhbmcgYFJgIGxha3VrYW4gdW50dWsgc2VsYW5nICRcYmV0YV8xJC4NCg0KYGBge3J9DQojIHN0b3JlIGVzdGltYXRlDQpiZXRhXzFfaGF0ID0gY29lZihzdG9wX2Rpc3RfbW9kZWwpWzJdDQoNCiMgc3RvcmUgc3RhbmRhcmQgZXJyb3INCmJldGFfMV9oYXRfc2UgPSBzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRzWzIsIDJdDQoNCiMgY2FsY3VsYXRlIGNyaXRpY2FsIHZhbHVlIGZvciB0d28tc2lkZWQgOTklIENJDQpjcml0ID0gcXQoMC45OTUsIGRmID0gbGVuZ3RoKHJlc2lkKHN0b3BfZGlzdF9tb2RlbCkpIC0gMikNCg0KIyBlc3QgLSBtYXJnaW4sIGVzdCArIG1hcmdpbg0KYyhiZXRhXzFfaGF0IC0gY3JpdCAqIGJldGFfMV9oYXRfc2UsIGJldGFfMV9oYXQgKyBjcml0ICogYmV0YV8xX2hhdF9zZSkNCmBgYA0KDQoNCiMjIEludGVydmFsIEtleWFraW5hbiB1bnR1ayBSZXNwb24gUmF0YS1SYXRhDQoNClNlbGFpbiBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayAkXGJldGFfMCQgZGFuICRcYmV0YV8xJCwgYWRhIGR1YSBwZXJraXJhYW4gaW50ZXJ2YWwgdW11bSBsYWlubnlhIHlhbmcgZGlndW5ha2FuIGRlbmdhbiByZWdyZXNpLiBQZXJ0YW1hIGRpc2VidXQgKippbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayByZXNwb25zIHJhdGEtcmF0YSoqLiBTZXJpbmdrYWxpLCBraXRhIG1lbmdpbmdpbmthbiBwZXJraXJhYW4gaW50ZXJ2YWwgdW50dWsgbWVhbiwgJEVbWSBcbWlkIFggPSB4XSQgdW50dWsgbmlsYWkgJHgkIHRlcnRlbnR1LiANCg0KRGFsYW0gc2l0dWFzaSBpbmksIGtpdGEgbWVuZ2d1bmFrYW4gJFxoYXR7eX0oeCkkIHNlYmFnYWkgcGVya2lyYWFuICRFW1kgXG1pZCBYID0geF0kIGtpdGEuIEtpdGEgc2VkaWtpdCBtZW1vZGlmaWthc2kgbm90YXNpIGtpdGEgdW50dWsgbWVtcGVyamVsYXMgYmFod2EgbmlsYWkgcHJlZGlrc2kgYWRhbGFoIGZ1bmdzaSBkYXJpIG5pbGFpICR4JC4NCiQkXGhhdHt5fSh4KSA9IFxoYXR7XGJldGF9XzAgKyBcaGF0e1xiZXRhfV8xIHgkJA0KSW5nYXQgaXR1LA0KJCRcdGV4dHtFfVtZIFxtaWQgWCA9IHhdID0gXGJldGFfMCArIFxiZXRhXzEgeCQkDQpKYWRpLCAkXGhhdHt5fSh4KSQgYWRhbGFoIHBlcmtpcmFhbiB5YW5nIGJhZ3VzIGthcmVuYSB0aWRhayBiaWFzOyANCiQkXHRleHR7RX1bXGhhdHt5fSh4KV0gPSBcYmV0YV8wICsgXGJldGFfMSB4JCQNCktpdGEga2VtdWRpYW4gYmlzYSBtZW5kYXBhdGthbiwgDQokJFx0ZXh0e1Zhcn1bXGhhdHt5fSh4KV0gPSBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufStcZnJhY3soeC1cYmFye3h9KV4yfXtTX3t4eH19XHJpZ2h0KSQkDQpTZXBlcnRpIHBlcmtpcmFhbiBsYWluIHlhbmcgdGVsYWgga2l0YSBsaWhhdCwgJFxoYXR7eX0oeCkkIGp1Z2EgbWVuZ2lrdXRpIGRpc3RyaWJ1c2kgbm9ybWFsLiBTZWphayAkXGhhdHtcYmV0YV8wfSQgZGFuICRcaGF0e1xiZXRhXzF9JCBhZGFsYWgga29tYmluYXNpIGxpbmllciBkYXJpIHZhcmlhYmVsIGFjYWsgbm9ybWFsLCBiZWdpdHUganVnYSBkZW5nYW4gJFxoYXR7eX0oeCkkLg0KJCRcaGF0e3l9KHgpIFxzaW0gTiBcbGVmdChcYmV0YV8wICsgXGJldGFfMSB4LCBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufStcZnJhY3soeC1cYmFye3h9KV4yfXtTX3t4eH19XHJpZ2h0KSBccmlnaHQpJCQNCkRhbiB0ZXJha2hpciwga2VyZW5hIGtpdGEgcGVybHUgbWVtcGVya2lyYWthbiB2YXJpYW5zLCBraXRhIHNhbXBhaSBwYWRhIHN0YW5kYXIga2VzYWxhaGFuIChzdGFuZGFyIGVycm9ycykgZGFyaSBwZXJraXJhYW4ga2l0YS4NCiQkXHRleHR7U0V9W1xoYXR7eX0oeCldID0gc19lIFxzcXJ0e1xmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX19JCQNCktpdGEga2VtdWRpYW4sIGRhcGF0IG1lbmdndW5ha2FuIGluaSB1bnR1ayBtZW5lbXVrYW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgcmVzcG9ucyByYXRhLXJhdGEsDQokJFxoYXR7eX0oeCkgXHBtIHRfe1xhbHBoYS8yLCBuIC0gMn0gXGNkb3Qgc19lXHNxcnR7XGZyYWN7MX17bn0rXGZyYWN7KHgtXGJhcnt4fSleMn17U197eHh9fX0kJA0KVW50dWsgbWVuZW11a2FuIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbnMgcmF0YS1yYXRhIGRhbGFtIGBSYCwgbWFrYSBraXRhIG1lbmdndW5ha2FuIGZ1bmdzaSBgcHJlZGljdCgpYC4gS2l0YSBtZW1iZXJpa2FuIGZ1bmdzaSBtb2RlbCBwYXMga2l0YSBzZXJ0YSBkYXRhIGJhcnUsIGxhbHUgZGlzaW1wYW4gc2ViYWdhaSBkYXRhIGZyYW1lIChoYWwgaW5pIHBlbnRpbmcgZGlsYWt1a2FuIGFnYXIgYFJgIG1lbmdldGFodWkgbmFtYSB2YXJpYWJlbCBwcmVkaWt0b3IpLiANCg0KRGlzaW5pLCBraXRhIG1lbmVtdWthbiBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayBqYXJhayBiZXJoZW50aSByYXRhLXJhdGEgc2FhdCBtb2JpbCBtZWxhanUgNSBtaWwgcGVyamFtIGRhbiBzYWF0IG1vYmlsIG1lbGFqdSAyMSBtaWwgcGVyIGphbS4gDQoNCmBgYHtyfQ0KbmV3X3NwZWVkcyA9IGRhdGEuZnJhbWUoc3BlZWQgPSBjKDUsIDIxKSkNCnByZWRpY3Qoc3RvcF9kaXN0X21vZGVsLCBuZXdkYXRhID0gbmV3X3NwZWVkcywgDQogICAgICAgIGludGVydmFsID0gYygiY29uZmlkZW5jZSIpLCBsZXZlbCA9IDAuOTkpDQpgYGANCg0KIyMgUHJlZGlrc2kgSW50ZXJ2YWwgdW50dWsgUGVuZ2FtYXRhbiBCYXJ1DQoNClRlcmthZGFuZyBraXRhIG1lbmdpbmdpbmthbiBwZXJraXJhYW4gaW50ZXJ2YWwgdW50dWsgcGVuZ2FtYXRhbiBiYXJ1LCAkWSQsIHVudHVrIG5pbGFpICR4JCB0ZXJ0ZW50dS4gSW5pIHNhbmdhdCBtaXJpcCBkZW5nYW4gaW50ZXJ2YWwgdW50dWsgcmVzcG9ucyByYXRhLXJhdGEsICRcdGV4dHtFfVtZIFxtaWQgWCA9IHhdJCwgdGV0YXBpIGJlcmJlZGEgZGFsYW0gc2F0dSBoYWwgeWFuZyBzYW5nYXQgcGVudGluZy4gDQoNClRlYmFrYW4gdGVyYmFpayBraXRhIHVudHVrIG9ic2VydmFzaSBiYXJ1IG1hc2loICRcaGF0e3l9KHgpJC4gUGVya2lyYWFuIHJhdGEtcmF0YSBtYXNpaCBtZXJ1cGFrYW4gcHJlZGlrc2kgdGVyYmFpayB5YW5nIGJpc2Ega2l0YSBidWF0LiBQZXJiZWRhYW5ueWEgdGVybGV0YWsgcGFkYSBqdW1sYWggdmFyaWFiaWxpdGFzLiBLaXRhIHRhaHUgYmFod2EgcGVuZ2FtYXRhbiBha2FuIGJlcnZhcmlhc2kgdGVudGFuZyBnYXJpcyByZWdyZXNpIHlhbmcgc2ViZW5hcm55YSBtZW51cnV0IGRpc3RyaWJ1c2kgJE4oMCwgXHNpZ21hXjIpJC4gS2FyZW5hIGluaSwga2l0YSBtZW5hbWJhaGthbiBmYWt0b3IgdGFtYmFoYW4gJFxzaWdtYV4yJCBrZSB2YXJpYWJpbGl0YXMgcGVya2lyYWFuIGtpdGEsIHVudHVrIG1lbmplbGFza2FuIHZhcmlhYmlsaXRhcyBwZW5nYW1hdGFuIHRlbnRhbmcgZ2FyaXMgcmVncmVzaSAobGluaWVyIHJlZ3Jlc3Npb24pLg0KJCRcYmVnaW57YWxpZ25lZH0gXHRleHR7VmFyfVtcaGF0e3l9KHgpICsgXGVwc2lsb25dICY9IFx0ZXh0e1Zhcn1bXGhhdHt5fSh4KV0gKyBcdGV4dHtWYXJ9W1xlcHNpbG9uXSBcXFsyZXhdICY9IFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX1ccmlnaHQpICsgXHNpZ21hXjIgXFxbMmV4XSAmPSBcc2lnbWFeMiBcbGVmdCgxICsgXGZyYWN7MX17bn0rXGZyYWN7KHgtXGJhcnt4fSleMn17U197eHh9fVxyaWdodCkgXGVuZHthbGlnbmVkfSQkDQokJFxoYXR7eX0oeCkgKyBcZXBzaWxvbiBcc2ltIE4gXGxlZnQoXGJldGFfMCArIFxiZXRhXzEgeCwgXCBcc2lnbWFeMiBcbGVmdCgxICsgXGZyYWN7MX17bn0rXGZyYWN7KHgtXGJhcnt4fSleMn17U197eHh9fVxyaWdodCkgXHJpZ2h0KSQkDQokJFx0ZXh0e1NFfVtcaGF0e3l9KHgpICsgXGVwc2lsb25dID0gc19lIFxzcXJ0ezEgKyBcZnJhY3sxfXtufStcZnJhY3soeC1cYmFye3h9KV4yfXtTX3t4eH19fSQkDQpLaXRhIGtlbXVkaWFuIGRhcGF0IG1lbmVtdWthbiAqKmludGVydmFsIHByZWRpa3NpKiogbWVuZ2d1bmFrYW4sIA0KDQokJFxoYXR7eX0oeCkgXHBtIHRfe1xhbHBoYS8yLCBuIC0gMn0gXGNkb3Qgc19lXHNxcnR7MSArIFxmcmFjezF9e259K1xmcmFjeyh4LVxiYXJ7eH0pXjJ9e1Nfe3h4fX19JCQNCg0KVW50dWsgbWVuZ2hpdHVuZyBpbmksIHVudHVrIHNhdHUgc2V0IHBvaW4gZGFsYW0gYFJgIHBlbWJlcml0YWh1YW4gaGFueWEgYWRhIHNlZGlraXQgcGVydWJhaGFuIGRhbGFtIHNpbnRha3MgZGFyaSBtZW5lbXVrYW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgcmVzcG9ucyByYXRhLXJhdGEuDQoNCmBgYHtyfQ0KcHJlZGljdChzdG9wX2Rpc3RfbW9kZWwsIG5ld2RhdGEgPSBuZXdfc3BlZWRzLCANCiAgICAgICAgaW50ZXJ2YWwgPSBjKCJwcmVkaWN0aW9uIiksIGxldmVsID0gMC45OSkNCmBgYA0KDQpQZXJoYXRpa2FuIGp1Z2EgYmFod2Ega2VkdWEgaW50ZXJ2YWwgaW5pIGxlYmloIGxlYmFyIGRhcmlwYWRhIGludGVydmFsIGtlcGVyY2F5YWFuIHlhbmcgc2VzdWFpIHVudHVrIHJlcG9ucyByYXRhLXJhdGEuDQoNCiMjIEtleWFraW5hbiBkYW4gUGl0YSBQcmVkaWtzaQ0KDQpTZXJpbmdrYWxpIGtpdGEgaW5naW4gbWVtcGxvdCBrZWR1YSBpbnRlcnZhbCBrZXlha2luYW4gdW50dWsgcmVzcG9ucyByYXRhLXJhdGEgZGFuIGludGVydmFsIHByZWRpa3NpIHVudHVrIHNlbXVhIGtlbXVuZ2tpbmFuIG5pbGFpICR4JC4gS2l0YSBtZW55ZWJ1dG55YSBrZXlha2luYW4gZGFuIHBpdGEgcHJlZGlrc2kuIA0KDQpgYGB7cn0NCnNwZWVkX2dyaWQgPSBzZXEobWluKGNhcnMkc3BlZWQpLCBtYXgoY2FycyRzcGVlZCksIGJ5ID0gMC4wMSkNCmRpc3RfY2lfYmFuZCA9IHByZWRpY3Qoc3RvcF9kaXN0X21vZGVsLCANCiAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YSA9IGRhdGEuZnJhbWUoc3BlZWQgPSBzcGVlZF9ncmlkKSwgDQogICAgICAgICAgICAgICAgICAgICAgIGludGVydmFsID0gImNvbmZpZGVuY2UiLCBsZXZlbCA9IDAuOTkpDQpkaXN0X3BpX2JhbmQgPSBwcmVkaWN0KHN0b3BfZGlzdF9tb2RlbCwgDQogICAgICAgICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBkYXRhLmZyYW1lKHNwZWVkID0gc3BlZWRfZ3JpZCksIA0KICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9ICJwcmVkaWN0aW9uIiwgbGV2ZWwgPSAwLjk5KSANCg0KcGxvdChkaXN0IH4gc3BlZWQsIGRhdGEgPSBjYXJzLA0KICAgICB4bGFiID0gIlNwZWVkIChpbiBNaWxlcyBQZXIgSG91cikiLA0KICAgICB5bGFiID0gIlN0b3BwaW5nIERpc3RhbmNlIChpbiBGZWV0KSIsDQogICAgIG1haW4gPSAiU3RvcHBpbmcgRGlzdGFuY2UgdnMgU3BlZWQiLA0KICAgICBwY2ggID0gMjAsDQogICAgIGNleCAgPSAyLA0KICAgICBjb2wgID0gImdyZXkiLA0KICAgICB5bGltID0gYyhtaW4oZGlzdF9waV9iYW5kKSwgbWF4KGRpc3RfcGlfYmFuZCkpKQ0KYWJsaW5lKHN0b3BfZGlzdF9tb2RlbCwgbHdkID0gNSwgY29sID0gImRhcmtvcmFuZ2UiKQ0KDQpsaW5lcyhzcGVlZF9ncmlkLCBkaXN0X2NpX2JhbmRbLCJsd3IiXSwgY29sID0gImRvZGdlcmJsdWUiLCBsd2QgPSAzLCBsdHkgPSAyKQ0KbGluZXMoc3BlZWRfZ3JpZCwgZGlzdF9jaV9iYW5kWywidXByIl0sIGNvbCA9ICJkb2RnZXJibHVlIiwgbHdkID0gMywgbHR5ID0gMikNCmxpbmVzKHNwZWVkX2dyaWQsIGRpc3RfcGlfYmFuZFssImx3ciJdLCBjb2wgPSAiZG9kZ2VyYmx1ZSIsIGx3ZCA9IDMsIGx0eSA9IDMpDQpsaW5lcyhzcGVlZF9ncmlkLCBkaXN0X3BpX2JhbmRbLCJ1cHIiXSwgY29sID0gImRvZGdlcmJsdWUiLCBsd2QgPSAzLCBsdHkgPSAzKQ0KcG9pbnRzKG1lYW4oY2FycyRzcGVlZCksIG1lYW4oY2FycyRkaXN0KSwgcGNoID0gIisiLCBjZXggPSAzKQ0KYGBgDQoNCkJlYmVyYXBhIGhhbCB5YW5nIHBlcmx1IGRpcGVyaGF0aWthbjoNCg0KMS4gS2l0YSBtZW5nZ3VuYWthbiBhcmd1bWVuIGB5bGltYCB1bnR1ayBtZXJlZ2FuZ2thbiBzdW1idS0keSQgZGFyaSBwbG90LCBrYXJlbmEgcGl0YSBsZWJpaCBwYW5qYW5nIGRhcmlwYWRhIHRpdGlrLiANCg0KMi4gS2l0YSBtZW5hbWJhaGthbiB0aXRpayBwYWRhIHRpdGlrICgkeCx5JCkgdGVyc2VidXQuIA0KICAgIC0gSW5pIGFkYWxhaCB0aXRpayB5YW5nIGFrYW4gKipzZWxhbHUqKiBkaWxld2F0aSBnYXJpcyByZWdyZXNpLiAoUGlraXJrYW4gYWxhc2FubnlhKQ0KICAgIC0gSW5pIGFkYWxhaCB0aXRpIGRpbWFuYSBrZXlha2luYW4gZGFuIHBpdGEgcHJlZGlrc2kgbWVuamFkaSB5YW5nIHRlcnNlbXBpdC4gTGloYXRsYWgga2VzYWxhaGFuIHN0YW5kYXIga2VkdWFueWEgdW50dWsgbWVtYWhhbWkgbWVuZ2FwYS4NCiAgICANCjMuIFBpdGEgcHJlZGlrc2kgKHRpdGlrLXRpdGlrIGJpcnUpIGt1cmFuZyBtZWxlbmdrdW5nIGRpYmFuZGluZ2thbiBkZW5nYW4gcGl0YSBrZXBlcmNheWFhbiAoYmlydSBwdXR1cy1wdXR1cykuIEluaSBhZGFsYWggaGFzaWwgZGFyaSBmYWt0b3IgJFxzaWdtYV4yJCB0YW1iYWhhbiB5YW5nIGRpdGFtYmFoa2FuIGtlIHZhcmlhbnMgcGFkYSBuaWxhaSAkeCQgYmVyYXBhcHVuLiANCg0KIyMgU2lnbmlmaWthbnNpIFJlZ3Jlc2ksIFVqaS1GDQoNCkRhbGFtIGthc3VzIHJlZ3Jlc2kgbGluaWVyIHNlZGVyaGFuYSwgdWppIHNpZ25pZmlrYW5zaSByZWdyZXNpICR0JCBzZXRhcmEgZGVuZ2FuIHVqaSBsYWluLCB5YWl0dSAkRiQgbWVuZ3VqaSBzaWduaWZpa2Fuc2kgcmVncmVzaS4gS2VzZXRhcmFhbiBpbmkgaGFueWEgYWthbiAqKmJlcmxha3UgYmVuYXIqKiB1bnR1ayByZWdyZXNpIGxpbmllciBzZWRlcmhhbmEsIGRhbiBkaSBiYWdpYW4gc2VsYW5qdXRueWEga2l0YSBoYW55YSBha2FuIG1lbmdndW5ha2FuICRGJCB1bnR1ayBtZW5ndWppIHNpZ25pZmlrYW5zaSByZWdyZXNpLg0KDQpJbmdhdCBkYXJpIGJhZ2lhbiB0ZXJha2hpciBkZWtvbXBvc2lzaSB2YXJpYW5zIHlhbmcga2l0YSBsaWhhdCBzZWJlbHVtbnlhIG1lbmdoaWhpdHVuZyAkUl4yJCwNCiQkXHN1bV97aT0xfV57bn0oeV9pIC0gXGJhcnt5fSleMiA9IFxzdW1fe2k9MX1ee259KHlfaSAtIFxoYXR7eX1faSleMiArIFxzdW1fe2k9MX1ee259KFxoYXR7eX1faSAtIFxiYXJ7eX0pXjIkJA0KDQphdGF1IHNpbmdrYXRueWEsDQokJFx0ZXh0e1NTVH0gPSBcdGV4dHtTU0V9ICsgXHRleHR7U1NSZWd9LiQkDQoNClVudHVrIG1lbmdlbWJhbmdrYW4gJEYkIHRlc3QsIGtpdGEgYWthbiBtZW5nYXR1ciBpbmZvcm1hc2kgaW5pIGRhbGFtIHRhYmVsICoqQU5PVkEqKg0KDQohW10oQzpcVXNlcnNcSU1FTERBIFNJQU5UVVJJXERvd25sb2Fkc1xhbm92YS5wbmcpDQoNCkFOT1ZBLCBhdGF1IEFuYWxpc2lzIFZhcmlhbnMgYWthbiBtZW5qYWRpIGtvbnNlcCB5YW5nIHNlcmluZyBraXRhIGJhaGFzIGRhbGFtIGJhZ2lhbiBpbmkuIFVudHVrIHNhYXQgaW5pLCBraXRhIGFrYW4gZm9rdXMgcGFkYSBoYXNpbCB0YWJlbCwgeWFpdHUgJEYkIHN0YXRpc3Rpay4gDQokJEYgPSBcZnJhY3tcc3VtX3tpPTF9XntufShcaGF0e3l9X2kgLSBcYmFye3l9KV4yIC8gMX17XHN1bV97aT0xfV57bn0oeV9pIC0gXGhhdHt5fV9pKV4yIC8gKG4gLSAyKX0gXHNpbSBGX3sxLCBuIC0gMn0kJA0KDQp5YW5nIG1lbmdpa3V0aSBkaXN0cmlidXNpICRGJCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gJDEkIGRhbiAkbi0yJCBkaWJhd2FoIGhpcG90ZXNpcyBub2wuIFNlYnVhaCBkaXN0cmlidXNpICRGJCBhZGFsYWggZGlzdHJpYnVzaSBrb250aW51IHlhbmcgaGFueWEgbWVuZ2FtYmlsIG5pbGFpIHBvc2l0aWYgZGFuIG1lbWlsaWtpIGR1YSBwYXJhbWV0ZXIsIHlhaXR1IGR1YSBkZXJhamF0IGtlYmViYXNhbi4NCg0KSW5nYXRsYWgsIHBlbnRpbmdueWEgdWppIHJlZ3Jlc2ksICRZJCAqKnRpZGFrKiogdGVyZ2FudHVuZyBwYWRhICR4JCBkYWxhbSBoaXBvdGVzaXMgbm9sLg0KJCRIXzA6IFxiZXRhXzEgPSAwIFxxdWFkIFxxdWFkIFlfaSA9IFxiZXRhXzAgKyBcZXBzaWxvbl9pJCQNClNlZGFuZ2thbiBwYWRhIGhpcG90ZXNpcyBhbHRlcm5hdGlmICRZJCBtdW5na2luIGJlcmdhbnR1bmcgcGFkYSAkeCQNCiQkSF8xOiBcYmV0YV8xIFxuZXEgMCBccXVhZCBccXVhZCBZX2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X2kgKyBcZXBzaWxvbl9pJCQNCktpdGEgYmlzYSBtZW5nZ3VuYWthbiAkRiQgc3RhdGlzdGlrIHVudHVrIG1lbGFrdWthbiB0ZXMgaW5pLg0KJCRGID0gXGZyYWN7XHN1bV97aT0xfV57bn0oXGhhdHt5fV9pIC0gXGJhcnt5fSleMiAvIDF9e1xzdW1fe2k9MX1ee259KHlfaSAtIFxoYXR7eX1faSleMiAvIChuIC0gMil9JCQNClNlY2FyYSBraHVzdXMsIGtpdGEgYWthbiBtZW5vbGFrIG51bGwgc2FhdCAkRiQgc3RhdGlzdGlrbnlhIGJlbmFyLCB5YWl0dSwga2V0aWthIGFkYSBrZW11bmdraW5hbiByZW5kYWggYmFod2EgcGVuZ2FtYXRhbiBiaXNhIGRhdGFuZyBkYXJpIG1vZGVsIG5vbCBzZWNhcmEga2ViZXR1bGFuLiBLaXRhIGFrYW4gbWVuZ2hpdHVuZyBuaWxhaSBwIHVudHVrIGtpdGEgZGVuZ2FuIGBSYC4NCg0KVW50dWsgbWVsYWt1a2FuICRGJCB0ZXMgZGkgYFJgIGthbGlhbiBkYXBhdCBtZWxpaGF0IGJhcmlzIHRlcmFraGlyIGRhcmkgb3V0cHV0IHlhbmcgZGFsYW0gZnVuZ3NpIGBzdW1tYXJ5KClgIGRpc2VidXQgYEYtc3RhdGlzdGljc2AgeWFuZyBtZW1iZXJpa2FuIG5pbGFpIHVqaSBzdGF0aXN0aWssIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgcmVsZXZhbiwgc2VydGEgJHAtdmFsdWUkIGRhcmkgcGVuZ3VqaWFuDQoNCmBgYHtyfQ0Kc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpDQpgYGANCg0KU2VsYWluIGl0dSwga2FsaWFuIGRhcGF0IG1lbmdndW5ha2FuIGZ1bmdzaSBgYW5vdmEoKWAgZGFsYW0gbWVuYW1waWxrYW4gaW5mb3JtYXNpZGFsYW0gdGFiZWwgQU5PVkEuDQoNCmBgYHtyfQ0KYW5vdmEoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNCkluaSBqdWdhIG1lbWJlcmlrYW4gbmlsYWkgcCAoJHAtdmFsdWUkKSB1bnR1ayBwZW5ndWppYW4uIEthbGlhbiBoYXJ1cyBtZW1wZXJoYXRpa2FuIGJhaHdhIG5pbGFpIHAgKCRwLXZhbHVlJCkgZGFyaSBkaXN0cmlidXNpICR0JCBhZGFsYWggc2FtYS4gS2FsaWFuIG11bmdraW4ganVnYSBtZW1wZXJoYXRpa2FuIGJhaHdhIG5pbGFpIHN0YXRpc3RpayBwZW5ndWppYW4gdW50dWsgdWppICR0JCwgJDkuNDYzOTkkLCBkYXBhdCBkaWt1YWRyYXRrYW4gdW50dWsgbWVuZGFwYXRrYW4gbmlsYWkgJEYkIHN0YXRpc3RpaywgJDg5LjU2NzEwNjUkLg0KDQpQZXJoYXRpa2FuIGJhaHdhIGFkYSBjYXJhIGxhaW4geWFuZyBzZXRhcmEgdW50dWsgbWVsYWt1a2FuIGluaSBkYWxhbSBgUmAsIGRpbWFuYSBraXRhIGFrYW4gc2VyaW5nIHNla2FsaSB1bnR1ayBtZW1iYW5kaW5na2FuIGR1YSBtb2RlbC4NCg0KYGBge3J9DQphbm92YShsbShkaXN0IH4gMSwgZGF0YSA9IGNhcnMpLCBsbShkaXN0IH4gc3BlZWQsIGRhdGEgPSBjYXJzKSkNCmBgYA0KDQpQZXJueWF0YWFuIG1vZGVsIGBsbShkaXN0IH4gMSwgZGF0YSA9IGNhcnMpYCBtZW5lcmFwa2FuIG1vZGVsICRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faSQga2UgZGF0YSBtb2JpbCAoZGF0YSBjYXJzKS4gQ2F0YXQgJFxoYXR7eX0gPSBcYmFye3l9JCBpdHUga2V0aWthICRZX2kgPSBcYmV0YV8wICsgXGVwc2lsb25faSQNCg0KUGVybnlhdGFhbiBtb2RlbCBgbG0oZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycylgIG1lbmVyYXBrYW4gbW9kZWwgJFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kkLiBLaXRhIGtlbXVkaWFuIGRhcGF0IG1lbmdhbmdnYXAgcGVuZ2d1bmFhbiBgYW5vdmEoKWAgaW5pIHNlYmFnYWkgcGVyYmFuZGluZ2FuIGxhbmdzdW5nIGtlZHVhIG1vZGVsIChQZXJoYXRpa2FuIGJhaHdhIGtpdGEgbWVuZGFwYXRrYW4gbmlsYWkgcCAoJHAtdmFsdWUkKSB5YW5nIHNhbWEgbGFnaSkuIA==