Interferensi dalam Regresi Linier
Setelah membaca bab ini, anda akan dapat:
- Memahami distribusi estimasi regresi.
- Membuat interval untuk parameter regresi, responden rata-rata, dan prediksi.
- Menguji taraf signifikansi suatu regresi.
Dalam bab sebelumnya, anda sudah menegaskan model dari regresi linear sederhana, \[Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\] dimana \(\epsilon_i \sim N(0, \sigma^2)\). Lalu gunakan observasi \((x_i,y_i)\), dengan \(i=1,2,...,n\) untuk mendapatkan nilai \(\beta_0\) dan \(\beta_1\) yang diminimalkan \[f(\beta_0, \beta_1) = \sum_{i = 1}^{n}(y_i - (\beta_0 + \beta_1 x_i))^2.\] Nilainya dapat juga disebut \(\hat{\beta_0}\) dan \(\hat{\beta_1}\), dapat dibentuk juga menjadi \[\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}\] \(\sigma^2\) juga di estimasi menggunakan \(s_e^2\). Dalam kata lain, \(s_e\) merupakan estimasi dari \(\sigma\), dimana \[s_e = \text{RSE} = \sqrt{\frac{1}{n - 2}\sum_{i = 1}^n e_i^2}\] dapat disebut RSE (Residual Standard Error).
Ketika diaplikasikan dalam data cars, berikut hasil yang diperoleh:
##
## 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 sebelumnya, kita hanya membahas Estimasi, RSE, dan R-kuadrat berganda. Kali ini akan membahas mengenai koefisien dan F-statistik.

Sebelum mulai, berikut catatan untuk persamaan \(S_{xy}\) yang tidak diberikan pada bagian sebelumnya, \[S_{xy}= \sum_{i = 1}^{n}(x_i - \bar{x})(y_i - \bar{y}) = \sum_{i = 1}^{n}(x_i - \bar{x}) y_i.\] Persamaan ini mungkin tidak terduga. (Coba untuk buktikan.) Namun, akan berguna untuk mengilustrasikan konsep pada bagian ini.
Perlu diingat bahwa \(\hat{\beta_1}\) adalah sampel statistik ketika dikalkulasikan dengan data yang diperlihatkan diatas seperti \(\hat{\beta_0}\)
Namun, dalam bagian ini wajar untuk menggunakan \(\hat{\beta_1}\) dan \(\hat{\beta_0}\) sebagai variabel acak, yang berarti nilai \(Y_i\) belum diperoleh. Dalam kasus ini, notasi yang akan digunakan sedikit berbeda, mensubstitusi \(Y_i\) dan \(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}\] Pada bagian sebelumnya, dinyatakan bahwa parameter \(\beta_0\) dan \(\beta_1\) untuk model yang tidak diketahui dapat diperoleh dengan meminimalkan error. Sekarang membahas teorema Gauss-Markov yang melanjutkan permasalahan tersebut lebih dalam lagi, memperlihatkan beberapa estimasi yang berupa estimasi “terbaik” dalam sudut pandang tertentu.
Teorema Gauss-Markov
Teorema Gauss-Markov mengatakan bahwa saat melakukan estimasi parameter untuk regresi linear sederhana \(\beta_0\),\(\beta_1\), \(\beta_0\) dan \(\beta_1\) yang diturunkan berupa best linear unbiased estimates (BLUE). (Kondisi sebenarnya untuk teorema Gauss-Markov lebih fleksibel dibandingan dengan model SLR)
Sekarang membahas linier, unbiased, dan terbaik yang bersangkutan dengan estimasi ini.
Linier
Mengingat kembali aturan SLR yaitu nilai \(x_i\) dikatakan tetap dengan nilai yang diketahui. Maka estimasi linier dapat dituliskan sebagai kombinasi linier dari \(Y_i\). Dalam kasus dari \(\hat{\beta_1}\) dapat dilihat \[\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}\)
Dalam bentuk yang mirip, dapat dilihat bahwa \(\hat{\beta_0}\) dapat dituliskan sebagai kombinasi linier dari \(Y_i\). Maka \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) adalah estimator linier.
Unbiased
Sekarang telah diketahui bahwa estimasinya linier, seberapa baguskah estimasinya? Salah satu perhitungan “goodness” suatu estimate adalah bias. Secara spesifik, lebih baik jika estimasi tersebut tidak bias, yang artinya nilai ekspektasinya adalah parameter yang diestimasikan.
Dalam kasus estimasi regresi, diperoleh: \[\begin{aligned}
\text{E}[\hat{\beta}_0] &= \beta_0 \\
\text{E}[\hat{\beta}_1] &= \beta_1.
\end{aligned}\]
Dengan ini dapat dikatakan bahwa saat kondisi SLR terpenuhi, maka estimasinya rata-rata benar. Namun, seperti pada bagian sebelumnya saat mensimulasikan model SLR itu tidak menunjukkan jika estimasi individunya benar. Jika proses tersebut diulang sampai dengan tak terhingga pengulangan, maka estimasinya rata-rata benar.
Terbaik
Sekarang, jika estimasi linier dan unbiased dibatasi, bagaimana cara menjelaskan estimasi terbaik? Dengan variansi minimum.
Pertama, perlu dicatat bahwa sangat mudah untuk membuat estimasi untuk \(\beta_1\) yang memiliki variansi sangat rendah tetapi bukan unbiased. Contohnya: \[\hat{\theta}_{BAD} = 5.\] Karena \(\hat{\theta}_{BAD}\) adalah nilai konstan \[\text{Var}[\hat{\theta}_{BAD}] = 0.\] Namun sejak, \[\text{E}[\hat{\theta}_{BAD}] = 5\] \(\hat{\theta}_{BAD}\) dapat dikatakan estimator bias kecuali \(\beta_1=5\), yang berarti tidak diketahui sebelumnya. Untuk hal ini, estimasinya buruk (kecuali \(\beta_1=5\)) walaupun variansi yang terkecil. Ini adalah alasan mengapa estimasi unbiased tersebut dibatasi. Apa bagusnya suatu estimasi jika mengestimasi jumlah yang tidak tepat?
Maka, pertanyaannya adalah, apa variansi dari \(\hat{\beta_0}\) dan \(\hat{\beta_1}\)?
\[\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}\]
Hal ini mengukur variabilitas dari suatu estimasi dikarenakan kemungkinan yang acak saat sampling. Apakah ini yang “terbaik”? Apakah variansinya sudah yang paling kecil yang dapat diperoleh? Anda hanya perlu mempercayai apa yang kami katakan karena menunjukkan bahwa hal itu benar berada di luar cakupan kursus ini.
Distribusi sampling
Sekarang estimasi \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) sebagai variabel acak, maka dapat didiskusikan distribusi samplingnya yang berarti distribusi saat statistik dianggap variabel acak.
Karena \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) berupa kombinasi linier dari \(Y_i\) dan tiap \(Y_i\) distribusi normal, maka \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) juga mengikuti distribusi normal.
Lalu dengan menggabungkan semua menjadi satu menghasilkan distribusi \(\hat{\beta_0}\) dan \(\hat{\beta_1}\).
Untuk \(\hat{\beta_1}\), \[\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).\]
Jika disederhanakan, \[\hat{\beta}_1 \sim N\left( \beta_1, \frac{\sigma^2}{S_{xx}} \right).\] dan untuk \(\hat{\beta_0}\), \[\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).\]
Jika disederhanakan, \[\hat{\beta}_0 \sim N\left( \beta_0, \sigma^2 \left(\frac{1}{n} + \frac{\bar{x}^2}{S_{xx}}\right) \right)\]
Saat ini belum ada bukti untuk hasilnya. Hasil tersebut akan dicocokan dengan menggunakan simulasi dan bukan melakukan turunan dari distribusi sampling.
Catatan untuk pembaca: Turunan dan bukti dapat ditambahkan dalam lampiran suatu waktu nanti. Anda juga bisa menemukan hasil yang mendekati pada buku regresi standar linier. Di UIUC, hasil tersebut kemungkinan dipresentasikan pada STAT 424 dan STAT 425. Namun, karena anda tidak akan mempertanyakan penurunan, dalam kursus ini tidak akan dibahas.
Simulasi Distribusi Sampling
Untuk membuktikan hasil diatas, simulasikan sample ukuran \(n=100\) dari model \[Y_i = \beta_0 + \beta_1 x_i + \epsilon_i\] dimana \(\epsilon_i \sim N(0, \sigma^2).\) Dalam kasus ini parameternya:
- \(\beta_0=3\)
- \(\beta_1=6\)
- \(\sigma^2=4\)
Dari pernyataan diatas, menghasilkan \[\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 tentukan dahulu nilai \(x\) untuk simulasi, karena \(x\) dalam SLR juga dianggap kuantitas. Penentuan \(x\) tidak diatur. Disini juga mempersiapkan seed untuk pengacakan, dan kalkulasi \(S_{xx}\) yang diperlukan nantinya.
Memperbaiki nilai parameter
Dengan informasi diatas, distribusi samplingnya:
## [1] 0.1176238
## [1] 0.04
\[\hat{\beta}_1 \sim N( 6, 0.1176238)\] dan \[\hat{\beta}_0 \sim N( 3, 0.04).\] Hasilnya, \[\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 simulasikan data dari model ini sebanyak 10.000 kali. Catatan: Hal ini bukan cara R untuk melakukan simulasi. Simulasi dengan cara ini dilakukan untuk menambah kejelasan. Contoh: Fungsi sim_slr() dapat digunakan pada bagian sebelumnya. Variabel tersebut disimpan pada global environment daripada membuat data frame untuk tiap simulasi.
Tiap simulasi data dilakukan menghasilkan koefisien estimasi. Variabel beta_0_hats dan beta_1_hats sekarang menyimpan 10.000 nilai simulasi dari \(\hat{\beta_0}\) dan \(\hat{\beta_1}\) secara berurutan.
Pertama membuktikan distribusi dari \(\hat{\beta_1}\).
## [1] 6.001998
## [1] 6
## [1] 0.11899
## [1] 0.1176238
Nilai empiris rata-rata dan variansi sangat mirip. Sudah dibuktikan distribusinya itu normal. beta_1_hats divisualisasikan dalam bentuk histogram, dan menambahkan kurva distribusi \(\hat{\beta_1}\). Untuk menyesuaikan skala dengan kurva menggunakan prob = TRUE.
# note need to use prob = TRUE
hist(beta_1_hats, prob = TRUE, breaks = 20,
xlab = expression(hat(beta)[1]), main = "", border = "dodgerblue")
curve(dnorm(x, mean = beta_1, sd = sqrt(var_beta_1_hat)),
col = "darkorange", add = TRUE, lwd = 3)

Lalu ulang proses \(\hat{\beta_0}\).
## [1] 3.001147
## [1] 3
## [1] 0.04017924
## [1] 0.04
hist(beta_0_hats, prob = TRUE, breaks = 25,
xlab = expression(hat(beta)[0]), main = "", border = "dodgerblue")
curve(dnorm(x, mean = beta_0, sd = sqrt(var_beta_0_hat)),
col = "darkorange", add = TRUE, lwd = 3)

Pembelajaran simulasi ini hanya mensimulasikan jumlah sampel yang terbatas. Untuk membuktikan hasil distribusi, diperlukan sampel yang tidak terhingga. Namun dalam plot berikut memperlihatkannya dengan cukup jelas jika simulasi itu berlanjut.
par(mar = c(5, 5, 1, 1)) # adjusted plot margins, otherwise the "hat" does not display
plot(cumsum(beta_1_hats) / (1:length(beta_1_hats)), type = "l", ylim = c(5.95, 6.05),
xlab = "Number of Simulations",
ylab = expression("Empirical Mean of " ~ hat(beta)[1]),
col = "dodgerblue")
abline(h = 6, col = "darkorange", lwd = 2)

par(mar = c(5, 5, 1, 1)) # adjusted plot margins, otherwise the "hat" does not display
plot(cumsum(beta_0_hats) / (1:length(beta_0_hats)), type = "l", ylim = c(2.95, 3.05),
xlab = "Number of Simulations",
ylab = expression("Empirical Mean of " ~ hat(beta)[0]),
col = "dodgerblue")
abline(h = 3, col = "darkorange", lwd = 2)

Kesalahan Baku (Standard Error)
Sekarang ada 2 hasil distribusi yang dipercaya, \[\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}\]
Dengan menstandarisasi hasil tersebut diperoleh \[\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 tidak ada \(\sigma\) dalam latihan, maka kita akan mengestimasi menggunakan \(s_e\), dimasukkan pada persamaan yang dimiliki sebagai standar deviasi dari estimasi.
Kedua persamaan baru itu disebut kesalahan baku yang berupa estimasi standar deviasi dari distribusi sampling. \[\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 dibagi dengan kesalahan baku dan bukan standar deviasinya, hasil berikut digunakan untuk membuat selang kepercayaan dan melakukan uji 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 mendapatkan itu, perlu dicatat bahwa \[\frac{\text{RSS}}{\sigma^2} = \frac{(n-2)s_e^2}{\sigma^2} \sim \chi_{n-2}^2.\] dan ingat kembali variabel acak \(T\), \[T = \frac{Z}{\sqrt{\frac{\chi_{d}^2}{d}}}\] dilanjutkan distribusi \(t\) dengan derajat kebebasan \(d\), dimana \(\chi_d^2\) dan \(\chi^2\) variabel acak dengan derajat kebebasan \(d\).
Dituliskan, \[T\sim t_d\] dikatakan bahwa variabel acak \(T\) berhubungan dengan distribusi \(t\) dengan derajat kebebasan \(d\).
Lalu menggunakan trik klasik yaitu “dikalikan dengan 1” dan diatur ulang sehingga menghasilkan \[\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)\).
Mengingat kembali distribusi \(t\) mirip dengan normal standar, tapi dengan ekor/ujung yang berbobot. Ketika derajat kebebasan meningkat, distribusi \(t\) semakin menjadi normal. Dibawah ini divisualisasikan distribusi normal standar seperti 2 contoh lainnya dari distribusi \(t\) dengan derajat kebebasan yang berbeda. Perhatikan bagaimana distribusi \(t\) dengan derajat kebebasan yang lebih besar mirip dengan kurva normal standar.
# define grid of x values
x = seq(-4, 4, length = 100)
# plot curve for standard normal
plot(x, dnorm(x), type = "l", lty = 1, lwd = 2,
xlab = "x", ylab = "Density", main = "Normal vs t Distributions")
# add curves for t distributions
lines(x, dt(x, df = 1), lty = 3, lwd = 2, col = "darkorange")
lines(x, dt(x, df = 10), lty = 2, lwd = 2, col = "dodgerblue")
# add legend
legend("topright", title = "Distributions",
legend = c("t, df = 1", "t, df = 10", "Standard Normal"),
lwd = 2, lty = c(3, 2, 1), col = c("darkorange", "dodgerblue", "black"))

Selang Kepercayaan untuk Kemiringan dan Perpotongan
Ingat kembali dimana selang kepercayaan berbentuk: \[\text{EST} \pm \text{CRIT} \cdot \text{SE}\] atau \[\text{EST} \pm \text{MARGIN}\] dimana \(\text{EST}\) sebuah estimasi untuk parameter ketertarikan. \(\text{SE}\) sebagai kesalahan baku dari suatu estimasi, dan \(\text{MARGIN}=\text{CRIT} \cdot \text{SE}\)
Lalu untuk \(\beta_0\) dan \(\beta_1\) dapat membuat selang 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 yang berarti \[P(t_{n-2} > t_{\alpha/2, n - 2}) = \alpha/2\].
Uji Hipotesis
Ingat kembali dimana uji statistik \(\text{(TS)}\) untuk uji rata-rata dalam bentuk: \[\text{TS} = \frac{\text{EST} - \text{HYP}}{\text{SE}}\] dimana \(\text{EsT}\) adalah estimasi untuk parameter ketertarikan, \(\text{HYP}\) adalah nilai hipotesis dari parameter, dan \(\text{SE}\) berupa kesalahan baku.
Maka ujinya \[H_0: \beta_0 = \beta_{00} \quad \text{vs} \quad H_1: \beta_0 \neq \beta_{00}\] gunakan uji statistiknya \[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 berarti dibawah hipotesis 0, diikuti dengan distribusi \(t\) dengan \(n-2\) derajat kebebasan. Digunakan \(\beta_{00}\) untuk dinotasikan dengan nilai hipotesis \(\beta_0\).
Ujinya \[H_0: \beta_1 = \beta_{10} \quad \text{vs} \quad H_1: \beta_1 \neq \beta_{10}\] gunakan uji statistiknya \[t = \frac{\hat{\beta}_1-\beta_{10}}{\text{SE}[\hat{\beta}_1]} = \frac{\hat{\beta}_1-\beta_{10}}{s_e / \sqrt{S_{xx}}}s\] yang berarti dibawah hipotesis 0, diikuti dengan distribusi \(t\) dengan \(n-2\) derajat kebebasan. Digunakan \(\beta_{10}\) untuk dinotasikan dengan nilai hipotesis \(\beta_1\).
Contoh cars
Sekarang menggunakan cars dari bagian sebelumnya untuk mengilustrasi konsepnya. Awalnya gunakan model lm() lalu gunakan summary() untuk melihat hasilnya dengan lebih detail.
##
## 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
Uji dalam R
sekarang membahas hasil yang ditampilkan yang disebut Coefficient. Pertama ingat kembali bahwa dapat mengekstrak informasi 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() memberi informasi yang diperoleh lalu gunakan operator $ dan Coefficients untuk mendapatkan informasi yang dibutuhkan. 2 hasil tersebut seharusnya terlihat tidak asing. \[\hat{\beta}_0 = -17.5790949\] dan \[\hat{\beta}_1 = 3.9324088\] yang berupa estimasi dari model parameter \(\beta_0\) dan \(\beta_1\).
Sekarang fokus pada baris kedua dari hasilm yang relevan terhadap \(\beta_1\).
## Estimate Std. Error t value Pr(>|t|)
## 3.932409e+00 4.155128e-01 9.463990e+00 1.489836e-12
Nilai pertama, Estimasi \[\hat{\beta}_1 = 3.9324088.\] Nilai kedua, Std. Error, kesalahan baku dari \(\hat{\beta_1}\), \[\text{SE}[\hat{\beta}_1] = \frac{s_e}{\sqrt{S_{xx}}} = 0.4155128.\] Nilai ketiga, t value, nilai uji statistik dari untuk menguji \(H_0: \beta_1 = 0\) vs \(H_1: \beta_1 \ne 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|), memberikan nilai p-value dari uji tersebut. \[\text{p-value} = 1.4898365\times 10^{-12}\] Perlu dicatat disini secara spesifik untuk menguji apakah \(\beta_1=0\). Pada baris pertama dari laporan output dengan uji sama tetapi untuk \(\beta_0\).
## Estimate Std. Error t value Pr(>|t|)
## -17.57909489 6.75844017 -2.60105800 0.01231882
Kesimpulan, kode berikut menyimpan informasi summary(stop_dist_model)$coefficient dalam variabel baru stop_dist_model_test_info, lalu ekstrak tiap elemen pada variabel baru yang mendeskripsi informasi di dalamnya.
Bisa dibuktikan beberapa persamaan yang setara: Uji \(t\) statistik \(\hat{\beta_1}\) dan 2 sisi nilai p / p-value berasosiasi dengan uji statistik.
## [1] 9.46399
## [1] 9.46399
## [1] 1.489836e-12
## [1] 1.489836e-12
Signifikansi Regresi, Uji-t
Sekarang membahas uji signifikansi regresi. Pertama, perlu dicatat berdasarkan hasil distribusi, \(\beta_0\) dan \(\beta_1\) dapat diuji untuk nilai tertentu dan melakukan uji 1 dan 2 sisi.
Namun, satu uji spesifik, \[H_0: \beta_1 = 0 \quad \text{vs} \quad H_1: \beta_1 \neq 0\] sering digunakan. Mari pikirkan tentang pengujian ini dalam kaitannya dengan model regresi linier sederhana, \[Y_i = \beta_0 + \beta_1 x_i + \epsilon_i.\] Jika diasumsikan hipotesis 0 adalah benar, maka \(\beta_1=0\) dan memperoleh model, \[Y_i = \beta_0 + \epsilon_i.\] Dalam model ini, responden tidak bergantung dengan prediktor. Dengan begitu dapat dipikirkan dengan uji sebagai berikut,
- Dibawah \(H_0\) tidak ada perbedaan linier yang signifikan antara \(x\) dan \(y\).
- Dibawah \(H_1\) ada perbedaan linier yang signifikan antara \(x\) dan \(y\).
Untuk contoh cars,
- Dibawah \(H_0\) tidak ada perbedaan linier yang signifikan antara kecepatan dan jarak berhenti.
- Dibawah \(H_1\) ada perbedaan linier yang signifikan antara kecepatan dan jarak berhenti.
Uji tersebut dapat dilihat dari hasil summary(), \[\text{p-value} = 1.4898365\times 10^{-12}.\] Dengan nilai p yang sangat kecil, hipotesis 0 akan ditolak dalam batas wajar \(\alpha\), contoh \(\alpha=0.01\). Dengan begitu ada perbedaan linier yang signifikan antara kecepatan dan jarak berhenti.
Daritadi kami menekankan Linier.

Dalam plot dari data simulasi ini, dapat dilihat dengan jelas hubungan \(x\) dan \(y\), namun itu bukanlah hubungan linier. Jika kita menggambarkan garis pada data ini akan menjadi rata. Hasil uji untuk \(H_0:\beta_1=0\) vs \(H_1:\beta_1\ne0\) memberikan nilai p yang tinggi yaitu 0.7564548, maka gagal menolak dan dikatakan bahwa tidak ada hubungan linier antara \(x\) dan \(y\). Nantinya akan dilihat bagaimana memasukkan kurva pada data menggunakan model “linier”, untuk sekarang \(H_0:\beta_1=0\) vs \(H_1:\beta_1\ne0\) hanya dapat mendeteksi sebuah garis hubungan.
Selang Kepercayaan di R
Dengan menggunakan R, selang kepercayaan \(\beta_0\) dan \(\beta_1\) sangatlah mudah untuk didapatkan.
## 0.5 % 99.5 %
## (Intercept) -35.706610 0.5484205
## speed 2.817919 5.0468988
Dengan ini akan menghitung 99% selang kepercayaan dari \(\beta_0\) dan \(\beta_1\), baris pertama untuk \(\beta_0\) dan baris kedua untuk \(\beta_1\).
Untuk contoh cars saat menafsirkan dengan interval, dapat dikatakan 99% kepercayaan dalam penambahan kecepatan 1 mil per jam, rata-rata meningkat pada jarak berhenti diantara 2.8179187-5.0468988 kaki yang mana berupa selang untuk \(\beta_1\).
Perlu dicatat pada 99% selang kepercayaan tidak mengandung hipotesis 0. Karena tidak mengandung 0 yang artinya menolah uji \(H_0:\beta_1 = 0\) vs \(H_1:\beta_1\ne0\) saat \(\alpha=0.01\), seperti yang terjadi sebelumnya.
Anda harus agak curiga terhadap interval kepercayaan untuk \(\beta_0\), karena mencakup nilai negatif, yang sesuai dengan jarak berhenti 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, nilai spesifik dapat diperoleh dari output/hasil beberapa cara. Kode ini tidak run tetapi sebaiknya diperiksa hubungan output dari kode 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
Bisa dipastikan juga kalkulasi selang \(\beta_1\) yang dilakukan dengan menggunakan R.
## speed speed
## 2.817919 5.046899
Interval Kepercayaan diri untuk Rata-Rata Respon
Selain interval kepercayaan untuk \(\beta_0\) dan \(\beta_1\), ada dua perkiraan interval umum lainnya yang digunakan dalam regresi. Yang pertama disebut interval kepercayaan untuk rata-rata respon . Seringkali, kami ingin perkiraan interval untuk rata-rata, \(E[Y|X=x]\) untuk nilai \(x\) tertentu. Dalam keadaan ini kita menggunakan \(\hat{y}(x)\) sebagai perkiraan dari \(E[Y|X=x]\). Kita mengubah sedikit notasi untuk memperjelas bahawa nilai prediksi adalah fungsi dari nilai \(x\)
\[\hat{y}=\hat\beta_0 + \hat\beta_{1}x\]
ingat, \[E[Y|X=x]=\beta_0 +\beta_{1}x\]
Jadi, \(\hat{y}\) adalah perkiraan yang bagus karena tidak bias \[E[\hat{y}]=\beta_0+\beta_{1}x\]
kemudiaan bisa mendapatkan, \[{Var[\hat{y}(x)]= σ^2({1\over n}+{x-\bar{x}^2 \over S_{xx}})}\]
Seperti perkiraan lainnya \(\hat{y}\) juga mengikuti distribusi normal. Sejak \(\hat\beta_0\) dan \(\hat\beta_1\) adalah kombinasi linear dari variabel random normal, \(\hat{y}\). \[\hat{y}∼N(β_0+β_1x,σ^2({1\over n}+{x-\bar{x}^2 \over S_{xx}}))\]
Dan akhirnya, sejak kita membutuhkan memperkirakan variansi, kita harus memperkirakan standar error. \[SE[\hat{y}]=s_e\sqrt{\frac{1}{n}+\frac{(x-x^2)}{S_{xx}}}\]
lalu kita dapat menggunakan untuk menemukan interval kepercayaan untuk rata-rata respon. \[\hat{y}±t_{α/2,n-2}. s_e\sqrt{\frac{1}{n}+\frac{(x-x^2)}{S_{xx}}}\]
Untuk menemukan interval kepercayaan untuk respons rata-rata menggunakan R, kami menggunakan fungsi predict(). Kami memberikan fungsi model yang dipasang serta data baru, disimpan sebagai bingkai data. (Ini penting, sehingga R mengetahui nama variabel prediktor.) Di sini, kami menemukan interval kepercayaan diri untuk jarak henti rata-rata ketika mobil bepergian 5 mil per jam dan ketika mobil bepergian 21 mil per jam.
## fit lwr upr
## 1 2.082949 -10.89309 15.05898
## 2 65.001489 56.45836 73.54462
Prediksi Interval untuk Observasi Baru
Terkadang kita ingin meng-estimasikan interval yang baru, \(Y\), untuk nilai tertentu dari \(x\). Ini sangat mirip dengan interval respon rata-rata, \(E[Y | X = x]\), tapi berbeda di satu hal yang sangat penting.
Tebakan terbaik kita untuk observasi yang baru masih tetap \(\hat y(x)\). Estimasi rata-rata masih tetap prediksi terbaik yang bisa kita buat. Perbedaanya terdapat pada jumlah variabilitasnya. Kita tahu bahwa observasi itu akan bervariasi tentang garis regresi yang sebenarnya menurut distribusi \(N(0,σ^2)\). Karena ini kita menambahkan beberapa faktor dari \(σ^2\) untuk estimasi variabilitas kita dengan tujuan untuk menjelaskan variabilitas dari observasi tentang garis regresi.
\[Var[\hat y(x)+ϵ]= Var[\hat y(x)]+Var [ϵ]\] \[= \sigma^2 (\frac{1}{n}+\frac {(x-\bar x)^2}{S{xx}}) + σ^2 \] \[ = \sigma^2 (1 +\frac{1}{n}+\frac {(x-\bar x)^2}{S{xx}})\] \[\hat y(x) + ϵ ∼ N (\beta_0 + \beta_1x,σ^2(1 +\frac{1}{n}+\frac {(x-\bar x)^2}{S{xx}}))\] \[SE[\hat y(x)+ϵ] = s_e \sqrt {1 +\frac{1}{n}+\frac {(x-\bar x)^2}{S{xx}}}\]
Lalu kita dapat menemukan interval prediksi menggunakan,
\[\hat y(x) ± t_{\alpha/2,n-2} ⋅ s_e\sqrt{1 +\frac{1}{n}+\frac {(x-\bar x)^2}{S{xx}}}.\] Untuk menghitung ini untuk kumpulan poin di R, ketahuilah bahwa hanya ada sedikit perubahan didalam sintaks dari penemuan interval kepercayaan untuk respon rata-rata.
## fit lwr upr
## 1 2.082949 -41.16099 45.32689
## 2 65.001489 22.87494 107.12803
Juga ketahuilah bahwa dua interval ini lebih lebar dibanding interval kepercayaan yang sesuai untuk respon rata-rata.
Keyakinan dan Band Prediksi
Seringkali kita akan memplot kedua interval kepercayaan untuk respon rata-rata dan interval prediksi untuk semua kemungkinan dari nilai \(x\). Kita memanggil ini sebagai kepercayaan dan band prediksi.
speed_grid = seq(min(cars$speed), max(cars$speed), by = 0.01)
dist_ci_band = predict(stop_dist_model,
newdata = data.frame(speed = speed_grid),
interval = "confidence", level = 0.99)
dist_pi_band = predict(stop_dist_model,
newdata = data.frame(speed = speed_grid),
interval = "prediction", level = 0.99)
plot(dist ~ speed, data = cars,
xlab = "Speed (in Miles Per Hour)",
ylab = "Stopping Distance (in Feet)",
main = "Stopping Distance vs Speed",
pch = 20,
cex = 2,
col = "grey",
ylim = c(min(dist_pi_band), max(dist_pi_band)))
abline(stop_dist_model, lwd = 5, col = "darkorange")
lines(speed_grid, dist_ci_band[,"lwr"], col = "dodgerblue", lwd = 3, lty = 2)
lines(speed_grid, dist_ci_band[,"upr"], col = "dodgerblue", lwd = 3, lty = 2)
lines(speed_grid, dist_pi_band[,"lwr"], col = "dodgerblue", lwd = 3, lty = 3)
lines(speed_grid, dist_pi_band[,"upr"], col = "dodgerblue", lwd = 3, lty = 3)
points(mean(cars$speed), mean(cars$dist), pch = "+", cex = 3)

Beberapa hal yang perlu diperhatikan: ~Kita menggunakan argumen ylim untuk melonggarkan sumbu y dari plot tersebut, sejak bandnya lebih jauh daripada titik yang ada. ~Kita menambahkan poin di poin \((x,\bar y)\) Ini merupakan sebuah titik dimana garis regresinya akan selalu melewatinya. (Pikirkan kenapa bisa terjadi.) Ini adalah titik dimana kedua kepercayaan dan band prediksi menjadi yang tersempit. Lihatlah kepada standar kesalahannya dari keduanya untuk mengetahui kenapa itu bisa terjadi.
Uji F, Signifikansi Regresi
Kasus dari regresi linear sederhana, uji \(t\) untuk signifikasi regresi merupakan nilai equivalent untuk uji lainnya, yaitu uji \(F\) untuk signifikansi regresi. Equivalent ini hanya akan menjadi benar untuk regresi linear sederhana, dan di bagian selanjutnya kita hanya akan menggunakan uji \(F\) untuk signifikansi regresinya.
Ingatlah kembali di seksi terakhir dari dekomposisi varians yang kita lihat sebelum menghitung nilai `\(R^2\),
\[∑_{i=1}^n ( y_i - \bar y)^2 = \Sigma_{i-1}^n (y_i - \bar y_i)^2 + \Sigma_{i=1}^n (\hat y_i - \bar y)^2,\]
atau, lebih singkatnya,
\[SST = SSE + SSReg.\]
Untuk mengembangkan uji \(F\), kita akan mengatur lagi informasi ini di tabel ANOVA,

ANOVA atau analisis dari varians akan menjadi sebuah konsep yang sering kita bahas dalam kelas ini. Untuk sekarang, kita akan fokus kepada hasil-hasil didalam tabel, dimana \(F\) statistiknya,
\[\frac {\Sigma_{i=1}^n ( y_i - \bar y)^2/1}{\Sigma_{i=1}^n ( y_i - \hat y_i)^2/(n-2)} ∼ F_{1,n-2}\]
dimana 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 mempunyai dua parameter, yang merupakan dua derajat kebebasan.
Ingatlah kembali, didalam signifikansi dari uji regresi, \(Y\) tidak bergantung kepada \(x\) di hipotesis nol.
\[H_0 : \beta_1 = 0\] \[ Y_i = \beta_0 + \epsilon_i\]
Disaat alternatif dari hipotesis \(Y\) bergantung kepada \(x\).
\[H_0 : \beta_1 ≠ 0\] \[ Y_i = \beta_1x_i + \epsilon_i\]
Kita dapat menggunakan \(F\) statistik untuk menunjukkan pengujian ini.
\[F = \frac {\Sigma_{i=1}^n (\hat y_i - \bar y)^2/1}{\Sigma_{i=1}^n ( y_i - \hat y_i)^2/(n-2)}\]
Secara khusus, kita akan menolak hipoteis nolnya disaat nilai \(F\) statistiknya besar, itu dia, disaat ada probabilitas rendah bahwa pengamatan secara kebetulan, dapat berasal dari model hipotesis nol. Kita akan membiarkan R menghitung nilai p untuk kita.
UNtuk menunjukkan uji \(F\) di R, anda dapat melihat di baris terakhir dari data yang keluar dari summary() yang dipanggil F-statistic yang memberikan nilai dari uji statistik, nilai derajat kebebasan yang relevan, juga nilai p dari pengujian tersebut.
##
## 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 fungsi anova() untuk menampilkan informasi dari 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 dari suatu pengujian. Anda harus memperhatikan bahwa nilai p dari uji \(t\) itu sama. Anda juga mungkin sadar bahwa nilai dari uji statistik dari uji \(t\), 9.46399, bisa di kuadratkan untuk mendapatkan nilai dari \(F\) statistik, 89.5671065.
Perhatikan bahwa ada beberapa jalanlain yang sama yang dapat dilakukan di R, yang sering kita lohat 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\) kepada data cars. Perhatikan bahwa \(\hat y = \bar y\) disaat \(Y_i = \beta_0 + \epsilon_i\).
Pernyataan model lm(dist ~ speed, data = cars) menerapkan model \(Y_i = \beta_0 + \beta_1x_i + \epsilon_i\).
Lalu kita dapat memikirkan kegunaan dari anova() sebagai perbandingan secara langsung dari dua model. (Perhatikan bahwa kita mendapatkan lagi nilai p yang sama.)
LS0tDQp0aXRsZTogJ0ludGVyZmVyZW5zaSBkYWxhbSBSZWdyZXNpIExpbmllcicNCmF1dGhvcjogIkplcnJlbCINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNCmBgYHtyIExvZ28sIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2dpdGh1Yi5jb20vQmFrdGktU2lyZWdhci9pbWFnZXMvYmxvYi9tYXN0ZXIvbG9nby5wbmc/cmF3PXRydWUiKQ0KYGBgDQoNCiMgSW50ZXJmZXJlbnNpIGRhbGFtIFJlZ3Jlc2kgTGluaWVyDQoNClNldGVsYWggbWVtYmFjYSBiYWIgaW5pLCBhbmRhIGFrYW4gZGFwYXQ6DQoNCiogTWVtYWhhbWkgZGlzdHJpYnVzaSBlc3RpbWFzaSByZWdyZXNpLg0KKiBNZW1idWF0IGludGVydmFsIHVudHVrIHBhcmFtZXRlciByZWdyZXNpLCByZXNwb25kZW4gcmF0YS1yYXRhLCBkYW4gcHJlZGlrc2kuDQoqIE1lbmd1amkgdGFyYWYgc2lnbmlmaWthbnNpIHN1YXR1IHJlZ3Jlc2kuDQoNCkRhbGFtIGJhYiBzZWJlbHVtbnlhLCBhbmRhIHN1ZGFoIG1lbmVnYXNrYW4gbW9kZWwgZGFyaSByZWdyZXNpIGxpbmVhciBzZWRlcmhhbmEsDQokJFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFxlcHNpbG9uX2kkJA0KZGltYW5hICRcZXBzaWxvbl9pIFxzaW0gTigwLCBcc2lnbWFeMikkLiBMYWx1IGd1bmFrYW4gb2JzZXJ2YXNpICQoeF9pLHlfaSkkLCBkZW5nYW4gJGk9MSwyLC4uLixuJCB1bnR1ayBtZW5kYXBhdGthbiBuaWxhaSAkXGJldGFfMCQgZGFuICRcYmV0YV8xJCB5YW5nIGRpbWluaW1hbGthbg0KJCRmKFxiZXRhXzAsIFxiZXRhXzEpID0gXHN1bV97aSA9IDF9XntufSh5X2kgLSAoXGJldGFfMCArIFxiZXRhXzEgeF9pKSleMi4kJA0KTmlsYWlueWEgZGFwYXQganVnYSBkaXNlYnV0ICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kLCBkYXBhdCBkaWJlbnR1ayBqdWdhIG1lbmphZGkNCiQkXGJlZ2lue2FsaWduZWR9DQpcaGF0e1xiZXRhfV8xICY9IFxmcmFje1Nfe3h5fX17U197eHh9fSA9IFxmcmFje1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSkoeV9pIC0gXGJhcnt5fSl9e1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSleMn1cXA0KXGhhdHtcYmV0YX1fMCAmPSBcYmFye3l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye3h9Lg0KXGVuZHthbGlnbmVkfSQkDQokXHNpZ21hXjIkIGp1Z2EgZGkgZXN0aW1hc2kgbWVuZ2d1bmFrYW4gJHNfZV4yJC4gRGFsYW0ga2F0YSBsYWluLCAkc19lJCBtZXJ1cGFrYW4gZXN0aW1hc2kgZGFyaSAkXHNpZ21hJCwgZGltYW5hDQokJHNfZSA9IFx0ZXh0e1JTRX0gPSBcc3FydHtcZnJhY3sxfXtuIC0gMn1cc3VtX3tpID0gMX1ebiBlX2leMn0kJA0KZGFwYXQgZGlzZWJ1dCBSU0UgKFJlc2lkdWFsIFN0YW5kYXJkIEVycm9yKS4NCg0KDQpLZXRpa2EgZGlhcGxpa2FzaWthbiBkYWxhbSBkYXRhIGBjYXJzYCwgYmVyaWt1dCBoYXNpbCB5YW5nIGRpcGVyb2xlaDoNCmBgYHtyfQ0Kc3RvcF9kaXN0X21vZGVsID0gbG0oZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycykNCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNCkJhZ2lhbiBzZWJlbHVtbnlhLCBraXRhIGhhbnlhIG1lbWJhaGFzIGBFc3RpbWFzaWAsIGBSU0VgLCBkYW4gYFIta3VhZHJhdCBiZXJnYW5kYWAuIEthbGkgaW5pIGFrYW4gbWVtYmFoYXMgbWVuZ2VuYWkgYGtvZWZpc2llbmAgZGFuIGBGLXN0YXRpc3Rpa2AuDQoNCmBgYHtyfQ0KcGxvdChkaXN0IH4gc3BlZWQsIGRhdGEgPSBjYXJzLA0KICAgICB4bGFiID0gIlNwZWVkIChpbiBNaWxlcyBQZXIgSG91cikiLA0KICAgICB5bGFiID0gIlN0b3BwaW5nIERpc3RhbmNlIChpbiBGZWV0KSIsDQogICAgIG1haW4gPSAiU3RvcHBpbmcgRGlzdGFuY2UgdnMgU3BlZWQiLA0KICAgICBwY2ggID0gMjAsDQogICAgIGNleCAgPSAyLA0KICAgICBjb2wgID0gImdyZXkiKQ0KYWJsaW5lKHN0b3BfZGlzdF9tb2RlbCwgbHdkID0gNSwgY29sID0gImRhcmtvcmFuZ2UiKQ0KYGBgDQoNClNlYmVsdW0gbXVsYWksIGJlcmlrdXQgY2F0YXRhbiB1bnR1ayBwZXJzYW1hYW4gJFNfe3h5fSQgeWFuZyB0aWRhayBkaWJlcmlrYW4gcGFkYSBiYWdpYW4gc2ViZWx1bW55YSwNCiQkU197eHl9PSBcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pKHlfaSAtIFxiYXJ7eX0pID0gXHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KSB5X2kuJCQNClBlcnNhbWFhbiBpbmkgbXVuZ2tpbiB0aWRhayB0ZXJkdWdhLiAoQ29iYSB1bnR1ayBidWt0aWthbi4pIE5hbXVuLCBha2FuIGJlcmd1bmEgdW50dWsgbWVuZ2lsdXN0cmFzaWthbiBrb25zZXAgcGFkYSBiYWdpYW4gaW5pLg0KDQpQZXJsdSBkaWluZ2F0IGJhaHdhICRcaGF0e1xiZXRhXzF9JCBhZGFsYWggKipzYW1wZWwgc3RhdGlzdGlrKioga2V0aWthIGRpa2Fsa3VsYXNpa2FuIGRlbmdhbiBkYXRhIHlhbmcgZGlwZXJsaWhhdGthbiBkaWF0YXMgc2VwZXJ0aSAkXGhhdHtcYmV0YV8wfSQNCg0KTmFtdW4sIGRhbGFtIGJhZ2lhbiBpbmkgd2FqYXIgdW50dWsgbWVuZ2d1bmFrYW4gJFxoYXR7XGJldGFfMX0kIGRhbiAkXGhhdHtcYmV0YV8wfSQgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLCB5YW5nIGJlcmFydGkgbmlsYWkgJFlfaSQgYmVsdW0gZGlwZXJvbGVoLiBEYWxhbSBrYXN1cyBpbmksIG5vdGFzaSB5YW5nIGFrYW4gZGlndW5ha2FuIHNlZGlraXQgYmVyYmVkYSwgbWVuc3Vic3RpdHVzaSAkWV9pJCBkYW4gJHlfaSQuDQokJFxiZWdpbnthbGlnbmVkfQ0KXGhhdHtcYmV0YX1fMSAmPSBcZnJhY3tcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pIFlfaX17XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KV4yfSBcXA0KXGhhdHtcYmV0YX1fMCAmPSBcYmFye1l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye3h9DQpcZW5ke2FsaWduZWR9JCQNClBhZGEgYmFnaWFuIHNlYmVsdW1ueWEsIGRpbnlhdGFrYW4gYmFod2EgcGFyYW1ldGVyICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIHVudHVrIG1vZGVsIHlhbmcgdGlkYWsgZGlrZXRhaHVpIGRhcGF0IGRpcGVyb2xlaCBkZW5nYW4gbWVtaW5pbWFsa2FuIGVycm9yLiBTZWthcmFuZyBtZW1iYWhhcyB0ZW9yZW1hIEdhdXNzLU1hcmtvdiB5YW5nIG1lbGFuanV0a2FuIHBlcm1hc2FsYWhhbiB0ZXJzZWJ1dCBsZWJpaCBkYWxhbSBsYWdpLCBtZW1wZXJsaWhhdGthbiBiZWJlcmFwYSBlc3RpbWFzaSB5YW5nIGJlcnVwYSBlc3RpbWFzaSAidGVyYmFpayIgZGFsYW0gc3VkdXQgcGFuZGFuZyB0ZXJ0ZW50dS4NCg0KIyMgVGVvcmVtYSBHYXVzcy1NYXJrb3YNCg0KVGVvcmVtYSBHYXVzcy1NYXJrb3YgbWVuZ2F0YWthbiBiYWh3YSBzYWF0IG1lbGFrdWthbiBlc3RpbWFzaSBwYXJhbWV0ZXIgdW50dWsgcmVncmVzaSBsaW5lYXIgc2VkZXJoYW5hICRcYmV0YV8wJCwkXGJldGFfMSQsICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkIHlhbmcgZGl0dXJ1bmthbiBiZXJ1cGEgKipiZXN0IGxpbmVhciB1bmJpYXNlZCBlc3RpbWF0ZXMqKiAqKEJMVUUpKi4gKEtvbmRpc2kgc2ViZW5hcm55YSB1bnR1ayB0ZW9yZW1hIEdhdXNzLU1hcmtvdiBsZWJpaCBmbGVrc2liZWwgZGliYW5kaW5nYW4gZGVuZ2FuIG1vZGVsIFNMUikNCg0KU2VrYXJhbmcgbWVtYmFoYXMgKmxpbmllciosICp1bmJpYXNlZCosIGRhbiAqdGVyYmFpayogeWFuZyBiZXJzYW5na3V0YW4gZGVuZ2FuIGVzdGltYXNpIGluaS4NCg0KIyMjIExpbmllcg0KDQpNZW5naW5nYXQga2VtYmFsaSBhdHVyYW4gU0xSIHlhaXR1IG5pbGFpICR4X2kkIGRpa2F0YWthbiB0ZXRhcCBkZW5nYW4gbmlsYWkgeWFuZyBkaWtldGFodWkuIE1ha2EgZXN0aW1hc2kgKipsaW5pZXIqKiBkYXBhdCBkaXR1bGlza2FuIHNlYmFnYWkga29tYmluYXNpIGxpbmllciBkYXJpICRZX2kkLiBEYWxhbSBrYXN1cyBkYXJpICRcaGF0e1xiZXRhXzF9JCBkYXBhdCBkaWxpaGF0DQokJFxoYXR7XGJldGF9XzEgPSBcZnJhY3tcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pIFlfaX17XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KV4yfSA9IFxzdW1fe2kgPSAxfV5uIGtfaSBZX2kgPSBrXzEgWV8xICsga18yIFlfMiArIFxjZG90cyBrX24gWV9uJCQNCmRpbWFuYSAka19pID0gXGRpc3BsYXlzdHlsZVxmcmFjeyh4X2kgLSBcYmFye3h9KX17XHN1bV97aSA9IDF9XntufSh4X2kgLSBcYmFye3h9KV4yfSQNCg0KRGFsYW0gYmVudHVrIHlhbmcgbWlyaXAsIGRhcGF0IGRpbGloYXQgYmFod2EgJFxoYXR7XGJldGFfMH0kIGRhcGF0IGRpdHVsaXNrYW4gc2ViYWdhaSBrb21iaW5hc2kgbGluaWVyIGRhcmkgJFlfaSQuIE1ha2EgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQgYWRhbGFoIGVzdGltYXRvciBsaW5pZXIuDQoNCiMjIyBVbmJpYXNlZA0KDQpTZWthcmFuZyB0ZWxhaCBkaWtldGFodWkgYmFod2EgZXN0aW1hc2lueWEgKmxpbmllciosIHNlYmVyYXBhIGJhZ3Vza2FoIGVzdGltYXNpbnlhPyBTYWxhaCBzYXR1IHBlcmhpdHVuZ2FuICJnb29kbmVzcyIgc3VhdHUgZXN0aW1hdGUgYWRhbGFoICoqYmlhcyoqLiBTZWNhcmEgc3Blc2lmaWssIGxlYmloIGJhaWsgamlrYSBlc3RpbWFzaSB0ZXJzZWJ1dCAqKnRpZGFrIGJpYXMqKiwgeWFuZyBhcnRpbnlhIG5pbGFpIGVrc3Bla3Rhc2lueWEgYWRhbGFoIHBhcmFtZXRlciB5YW5nIGRpZXN0aW1hc2lrYW4uDQoNCkRhbGFtIGthc3VzIGVzdGltYXNpIHJlZ3Jlc2ksIGRpcGVyb2xlaDoNCiQkXGJlZ2lue2FsaWduZWR9DQpcdGV4dHtFfVtcaGF0e1xiZXRhfV8wXSAmPSBcYmV0YV8wIFxcDQpcdGV4dHtFfVtcaGF0e1xiZXRhfV8xXSAmPSBcYmV0YV8xLg0KXGVuZHthbGlnbmVkfSQkDQoNCkRlbmdhbiBpbmkgZGFwYXQgZGlrYXRha2FuIGJhaHdhIHNhYXQga29uZGlzaSBTTFIgdGVycGVudWhpLCBtYWthIGVzdGltYXNpbnlhIHJhdGEtcmF0YSBiZW5hci4gTmFtdW4sIHNlcGVydGkgcGFkYSBiYWdpYW4gc2ViZWx1bW55YSBzYWF0IG1lbnNpbXVsYXNpa2FuIG1vZGVsIFNMUiBpdHUgdGlkYWsgbWVudW5qdWtrYW4gamlrYSBlc3RpbWFzaSBpbmRpdmlkdW55YSBiZW5hci4gSmlrYSBwcm9zZXMgdGVyc2VidXQgZGl1bGFuZyBzYW1wYWkgZGVuZ2FuIHRhayB0ZXJoaW5nZ2EgcGVuZ3VsYW5nYW4sIG1ha2EgZXN0aW1hc2lueWEgcmF0YS1yYXRhIGJlbmFyLiANCg0KIyMjIFRlcmJhaWsNCg0KU2VrYXJhbmcsIGppa2EgZXN0aW1hc2kgKmxpbmllciogZGFuICp1bmJpYXNlZCogZGliYXRhc2ksIGJhZ2FpbWFuYSBjYXJhIG1lbmplbGFza2FuIGVzdGltYXNpIHRlcmJhaWs/IERlbmdhbiAqKnZhcmlhbnNpIG1pbmltdW0qKi4NCg0KUGVydGFtYSwgcGVybHUgZGljYXRhdCBiYWh3YSBzYW5nYXQgbXVkYWggdW50dWsgbWVtYnVhdCBlc3RpbWFzaSB1bnR1ayAkXGJldGFfMSQgeWFuZyBtZW1pbGlraSB2YXJpYW5zaSBzYW5nYXQgcmVuZGFoIHRldGFwaSBidWthbiB1bmJpYXNlZC4gDQpDb250b2hueWE6IA0KJCRcaGF0e1x0aGV0YX1fe0JBRH0gPSA1LiQkDQpLYXJlbmEgJFxoYXR7XHRoZXRhfV97QkFEfSQgYWRhbGFoIG5pbGFpIGtvbnN0YW4gDQokJFx0ZXh0e1Zhcn1bXGhhdHtcdGhldGF9X3tCQUR9XSA9IDAuJCQNCk5hbXVuIHNlamFrLCANCiQkXHRleHR7RX1bXGhhdHtcdGhldGF9X3tCQUR9XSA9IDUkJA0KJFxoYXR7XHRoZXRhfV97QkFEfSQgZGFwYXQgZGlrYXRha2FuIGVzdGltYXRvciBiaWFzIGtlY3VhbGkgJFxiZXRhXzE9NSQsIHlhbmcgYmVyYXJ0aSB0aWRhayBkaWtldGFodWkgc2ViZWx1bW55YS4gVW50dWsgaGFsIGluaSwgZXN0aW1hc2lueWEgYnVydWsgKGtlY3VhbGkgJFxiZXRhXzE9NSQpIHdhbGF1cHVuIHZhcmlhbnNpIHlhbmcgdGVya2VjaWwuIEluaSBhZGFsYWggYWxhc2FuIG1lbmdhcGEgZXN0aW1hc2kgdW5iaWFzZWQgdGVyc2VidXQgZGliYXRhc2kuIEFwYSBiYWd1c255YSBzdWF0dSBlc3RpbWFzaSBqaWthIG1lbmdlc3RpbWFzaSBqdW1sYWggeWFuZyB0aWRhayB0ZXBhdD8NCg0KTWFrYSwgcGVydGFueWFhbm55YSBhZGFsYWgsIGFwYSB2YXJpYW5zaSBkYXJpICRcaGF0e1xiZXRhXzB9JCBkYW4gJFxoYXR7XGJldGFfMX0kPw0KDQokJFxiZWdpbnthbGlnbmVkfQ0KXHRleHR7VmFyfVtcaGF0e1xiZXRhfV8wXSAmPSBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fVxyaWdodCkgXFwNClx0ZXh0e1Zhcn1bXGhhdHtcYmV0YX1fMV0gJj0gXGZyYWN7XHNpZ21hXjJ9e1Nfe3h4fX0uDQpcZW5ke2FsaWduZWR9JCQNCg0KSGFsIGluaSBtZW5ndWt1ciB2YXJpYWJpbGl0YXMgZGFyaSBzdWF0dSBlc3RpbWFzaSBkaWthcmVuYWthbiBrZW11bmdraW5hbiB5YW5nIGFjYWsgc2FhdCBzYW1wbGluZy4gQXBha2FoIGluaSB5YW5nICJ0ZXJiYWlrIj8gQXBha2FoIHZhcmlhbnNpbnlhIHN1ZGFoIHlhbmcgcGFsaW5nIGtlY2lsIHlhbmcgZGFwYXQgZGlwZXJvbGVoPyBBbmRhIGhhbnlhIHBlcmx1IG1lbXBlcmNheWFpIGFwYSB5YW5nIGthbWkga2F0YWthbiBrYXJlbmEgbWVudW5qdWtrYW4gYmFod2EgaGFsIGl0dSBiZW5hciBiZXJhZGEgZGkgbHVhciBjYWt1cGFuIGt1cnN1cyBpbmkuDQoNCiMjIERpc3RyaWJ1c2kgc2FtcGxpbmcNCg0KU2VrYXJhbmcgZXN0aW1hc2kgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQgc2ViYWdhaSB2YXJpYWJlbCBhY2FrLCBtYWthIGRhcGF0IGRpZGlza3VzaWthbiAqKmRpc3RyaWJ1c2kgc2FtcGxpbmdueWEqKiB5YW5nIGJlcmFydGkgZGlzdHJpYnVzaSBzYWF0IHN0YXRpc3RpayBkaWFuZ2dhcCB2YXJpYWJlbCBhY2FrLg0KDQpLYXJlbmEgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQgYmVydXBhIGtvbWJpbmFzaSBsaW5pZXIgZGFyaSAkWV9pJCBkYW4gdGlhcCAkWV9pJCBkaXN0cmlidXNpIG5vcm1hbCwgbWFrYSAkXGhhdHtcYmV0YV8wfSQgZGFuICRcaGF0e1xiZXRhXzF9JCBqdWdhIG1lbmdpa3V0aSBkaXN0cmlidXNpIG5vcm1hbC4NCg0KTGFsdSBkZW5nYW4gbWVuZ2dhYnVuZ2thbiBzZW11YSBtZW5qYWRpIHNhdHUgbWVuZ2hhc2lsa2FuIGRpc3RyaWJ1c2kgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQuDQoNClVudHVrICRcaGF0e1xiZXRhXzF9JCwgDQokJFxoYXR7XGJldGF9XzEgPSBcZnJhY3tTX3t4eX19e1Nfe3h4fX0gDQo9IFxmcmFje1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSkgWV9pfXtcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pXjJ9DQpcc2ltIE5cbGVmdCggIFxiZXRhXzEsIFwgXGZyYWN7XHNpZ21hXjJ9e1xzdW1fe2kgPSAxfV57bn0oeF9pIC0gXGJhcnt4fSleMn0gXHJpZ2h0KS4kJA0KDQpKaWthIGRpc2VkZXJoYW5ha2FuLCANCiQkXGhhdHtcYmV0YX1fMSBcc2ltIE5cbGVmdCggIFxiZXRhXzEsIFxmcmFje1xzaWdtYV4yfXtTX3t4eH19IFxyaWdodCkuJCQNCmRhbiB1bnR1ayAkXGhhdHtcYmV0YV8wfSQsDQokJFxoYXR7XGJldGF9XzAgPSBcYmFye1l9IC0gXGhhdHtcYmV0YX1fMSBcYmFye3h9IA0KXHNpbSBOXGxlZnQoICBcYmV0YV8wLCBcIFxmcmFje1xzaWdtYV4yIFxzdW1fe2kgPSAxfV57bn14X2leMn17biBcc3VtX3tpID0gMX1ee259KHhfaSAtIFxiYXJ7eH0pXjJ9IFxyaWdodCkuJCQNCg0KSmlrYSBkaXNlZGVyaGFuYWthbiwNCiQkXGhhdHtcYmV0YX1fMCBcc2ltIE5cbGVmdCggIFxiZXRhXzAsIFxzaWdtYV4yIFxsZWZ0KFxmcmFjezF9e259ICsgXGZyYWN7XGJhcnt4fV4yfXtTX3t4eH19XHJpZ2h0KSBccmlnaHQpJCQNCg0KU2FhdCBpbmkgYmVsdW0gYWRhIGJ1a3RpIHVudHVrIGhhc2lsbnlhLiBIYXNpbCB0ZXJzZWJ1dCBha2FuIGRpY29jb2thbiBkZW5nYW4gbWVuZ2d1bmFrYW4gc2ltdWxhc2kgZGFuIGJ1a2FuIG1lbGFrdWthbiB0dXJ1bmFuIGRhcmkgZGlzdHJpYnVzaSBzYW1wbGluZy4NCg0KQ2F0YXRhbiB1bnR1ayBwZW1iYWNhOiBUdXJ1bmFuIGRhbiBidWt0aSBkYXBhdCBkaXRhbWJhaGthbiBkYWxhbSBsYW1waXJhbiBzdWF0dSB3YWt0dSBuYW50aS4gQW5kYSBqdWdhIGJpc2EgbWVuZW11a2FuIGhhc2lsIHlhbmcgbWVuZGVrYXRpIHBhZGEgYnVrdSByZWdyZXNpIHN0YW5kYXIgbGluaWVyLiBEaSBVSVVDLCBoYXNpbCB0ZXJzZWJ1dCBrZW11bmdraW5hbiBkaXByZXNlbnRhc2lrYW4gcGFkYSBTVEFUIDQyNCBkYW4gU1RBVCA0MjUuIE5hbXVuLCBrYXJlbmEgYW5kYSB0aWRhayBha2FuIG1lbXBlcnRhbnlha2FuIHBlbnVydW5hbiwgZGFsYW0ga3Vyc3VzIGluaSB0aWRhayBha2FuIGRpYmFoYXMuDQoNCiMjIyBTaW11bGFzaSBEaXN0cmlidXNpIFNhbXBsaW5nDQoNClVudHVrIG1lbWJ1a3Rpa2FuIGhhc2lsIGRpYXRhcywgc2ltdWxhc2lrYW4gc2FtcGxlIHVrdXJhbiAkbj0xMDAkIGRhcmkgbW9kZWwNCiQkWV9pID0gXGJldGFfMCArIFxiZXRhXzEgeF9pICsgXGVwc2lsb25faSQkDQpkaW1hbmEgJFxlcHNpbG9uX2kgXHNpbSBOKDAsIFxzaWdtYV4yKS4kIERhbGFtIGthc3VzIGluaSBwYXJhbWV0ZXJueWE6DQoNCiogJFxiZXRhXzA9MyQNCiogJFxiZXRhXzE9NiQNCiogJFxzaWdtYV4yPTQkDQoNCkRhcmkgcGVybnlhdGFhbiBkaWF0YXMsIG1lbmdoYXNpbGthbg0KJCRcaGF0e1xiZXRhfV8xIFxzaW0gTlxsZWZ0KCAgXGJldGFfMSwgXGZyYWN7XHNpZ21hXjJ9e1Nfe3h4fX0gXHJpZ2h0KSQkDQpkYW4gDQokJFxoYXR7XGJldGF9XzAgXHNpbSBOXGxlZnQoICBcYmV0YV8wLCBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fVxyaWdodCkgXHJpZ2h0KS4kJA0KUGVydGFtYSB0ZW50dWthbiBkYWh1bHUgbmlsYWkgJHgkIHVudHVrIHNpbXVsYXNpLCBrYXJlbmEgJHgkIGRhbGFtIFNMUiBqdWdhIGRpYW5nZ2FwIGt1YW50aXRhcy4gUGVuZW50dWFuICR4JCB0aWRhayBkaWF0dXIuIERpc2luaSBqdWdhIG1lbXBlcnNpYXBrYW4gc2VlZCB1bnR1ayBwZW5nYWNha2FuLCBkYW4ga2Fsa3VsYXNpICRTX3t4eH0kIHlhbmcgZGlwZXJsdWthbiBuYW50aW55YS4NCg0KYGBge3J9DQpzZXQuc2VlZCg0MikNCnNhbXBsZV9zaXplID0gMTAwICMgdGhpcyBpcyBuDQp4ID0gc2VxKC0xLCAxLCBsZW5ndGggPSBzYW1wbGVfc2l6ZSkNClN4eCA9IHN1bSgoeCAtIG1lYW4oeCkpIF4gMikNCmBgYA0KDQpNZW1wZXJiYWlraSBuaWxhaSBwYXJhbWV0ZXINCmBgYHtyfQ0KYmV0YV8wID0gMw0KYmV0YV8xID0gNg0Kc2lnbWEgID0gMg0KYGBgDQpEZW5nYW4gaW5mb3JtYXNpIGRpYXRhcywgZGlzdHJpYnVzaSBzYW1wbGluZ255YToNCmBgYHtyfQ0KKHZhcl9iZXRhXzFfaGF0ID0gc2lnbWEgXiAyIC8gU3h4KQ0KKHZhcl9iZXRhXzBfaGF0ID0gc2lnbWEgXiAyICogKDEgLyBzYW1wbGVfc2l6ZSArIG1lYW4oeCkgXiAyIC8gU3h4KSkNCmBgYA0KDQokJFxoYXR7XGJldGF9XzEgXHNpbSBOKCAgNiwgMC4xMTc2MjM4KSQkDQpkYW4NCiQkXGhhdHtcYmV0YX1fMCBcc2ltIE4oICAzLCAwLjA0KS4kJA0KSGFzaWxueWEsDQokJFxiZWdpbnthbGlnbmVkfQ0KXHRleHR7RX1bXGhhdHtcYmV0YX1fMV0gJj0gNiBcXA0KXHRleHR7VmFyfVtcaGF0e1xiZXRhfV8xXSAmPSAwLjExNzYyMzgNClxlbmR7YWxpZ25lZH0kJA0KZGFuIA0KJCRcYmVnaW57YWxpZ25lZH0NClx0ZXh0e0V9W1xoYXR7XGJldGF9XzBdICY9IDMgXFwNClx0ZXh0e1Zhcn1bXGhhdHtcYmV0YX1fMF0gJj0gMC4wNC4NClxlbmR7YWxpZ25lZH0kJA0KDQpTZWthcmFuZyBzaW11bGFzaWthbiBkYXRhIGRhcmkgbW9kZWwgaW5pIHNlYmFueWFrIDEwLjAwMCBrYWxpLiBDYXRhdGFuOiBIYWwgaW5pIGJ1a2FuIGNhcmEgYFJgIHVudHVrIG1lbGFrdWthbiBzaW11bGFzaS4gU2ltdWxhc2kgZGVuZ2FuIGNhcmEgaW5pIGRpbGFrdWthbiB1bnR1ayBtZW5hbWJhaCBrZWplbGFzYW4uIENvbnRvaDogRnVuZ3NpIGBzaW1fc2xyKClgIGRhcGF0IGRpZ3VuYWthbiBwYWRhIGJhZ2lhbiBzZWJlbHVtbnlhLiBWYXJpYWJlbCB0ZXJzZWJ1dCBkaXNpbXBhbiBwYWRhICpnbG9iYWwgZW52aXJvbm1lbnQqIGRhcmlwYWRhIG1lbWJ1YXQgZGF0YSBmcmFtZSB1bnR1ayB0aWFwIHNpbXVsYXNpLg0KDQpgYGB7cn0NCm51bV9zYW1wbGVzID0gMTAwMDANCmJldGFfMF9oYXRzID0gcmVwKDAsIG51bV9zYW1wbGVzKQ0KYmV0YV8xX2hhdHMgPSByZXAoMCwgbnVtX3NhbXBsZXMpDQoNCmZvciAoaSBpbiAxOm51bV9zYW1wbGVzKSB7DQogIGVwcyA9IHJub3JtKHNhbXBsZV9zaXplLCBtZWFuID0gMCwgc2QgPSBzaWdtYSkNCiAgeSAgID0gYmV0YV8wICsgYmV0YV8xICogeCArIGVwcw0KICANCiAgc2ltX21vZGVsID0gbG0oeSB+IHgpDQogIA0KICBiZXRhXzBfaGF0c1tpXSA9IGNvZWYoc2ltX21vZGVsKVsxXQ0KICBiZXRhXzFfaGF0c1tpXSA9IGNvZWYoc2ltX21vZGVsKVsyXQ0KfQ0KYGBgDQoNClRpYXAgc2ltdWxhc2kgZGF0YSBkaWxha3VrYW4gbWVuZ2hhc2lsa2FuIGtvZWZpc2llbiBlc3RpbWFzaS4gVmFyaWFiZWwgYGJldGFfMF9oYXRzYCBkYW4gYGJldGFfMV9oYXRzYCBzZWthcmFuZyBtZW55aW1wYW4gMTAuMDAwIG5pbGFpIHNpbXVsYXNpIGRhcmkgJFxoYXR7XGJldGFfMH0kIGRhbiAkXGhhdHtcYmV0YV8xfSQgc2VjYXJhIGJlcnVydXRhbi4NCg0KUGVydGFtYSBtZW1idWt0aWthbiBkaXN0cmlidXNpIGRhcmkgJFxoYXR7XGJldGFfMX0kLg0KYGBge3J9DQptZWFuKGJldGFfMV9oYXRzKSAjIGVtcGlyaWNhbCBtZWFuDQpgYGANCmBgYHtyfQ0KYmV0YV8xICAgICAgICAgICAgIyB0cnVlIG1lYW4NCmBgYA0KYGBge3J9DQp2YXIoYmV0YV8xX2hhdHMpICAjIGVtcGlyaWNhbCB2YXJpYW5jZQ0KYGBgDQpgYGB7cn0NCnZhcl9iZXRhXzFfaGF0ICAgICMgdHJ1ZSB2YXJpYW5jZQ0KYGBgDQoNCk5pbGFpIGVtcGlyaXMgcmF0YS1yYXRhIGRhbiB2YXJpYW5zaSAqc2FuZ2F0KiBtaXJpcC4gU3VkYWggZGlidWt0aWthbiBkaXN0cmlidXNpbnlhIGl0dSBub3JtYWwuIGBiZXRhXzFfaGF0c2AgZGl2aXN1YWxpc2FzaWthbiBkYWxhbSBiZW50dWsgaGlzdG9ncmFtLCBkYW4gbWVuYW1iYWhrYW4ga3VydmEgZGlzdHJpYnVzaSAkXGhhdHtcYmV0YV8xfSQuIFVudHVrIG1lbnllc3VhaWthbiBza2FsYSBkZW5nYW4ga3VydmEgbWVuZ2d1bmFrYW4gYHByb2IgPSBUUlVFYC4NCg0KYGBge3J9DQojIG5vdGUgbmVlZCB0byB1c2UgcHJvYiA9IFRSVUUNCmhpc3QoYmV0YV8xX2hhdHMsIHByb2IgPSBUUlVFLCBicmVha3MgPSAyMCwgDQogICAgIHhsYWIgPSBleHByZXNzaW9uKGhhdChiZXRhKVsxXSksIG1haW4gPSAiIiwgYm9yZGVyID0gImRvZGdlcmJsdWUiKQ0KY3VydmUoZG5vcm0oeCwgbWVhbiA9IGJldGFfMSwgc2QgPSBzcXJ0KHZhcl9iZXRhXzFfaGF0KSksIA0KICAgICAgY29sID0gImRhcmtvcmFuZ2UiLCBhZGQgPSBUUlVFLCBsd2QgPSAzKQ0KYGBgDQoNCkxhbHUgdWxhbmcgcHJvc2VzICRcaGF0e1xiZXRhXzB9JC4NCmBgYHtyfQ0KbWVhbihiZXRhXzBfaGF0cykgIyBlbXBpcmljYWwgbWVhbg0KYGBgDQpgYGB7cn0NCmJldGFfMCAgICAgICAgICAgICMgdHJ1ZSBtZWFuDQpgYGANCmBgYHtyfQ0KdmFyKGJldGFfMF9oYXRzKSAgIyBlbXBpcmljYWwgdmFyaWFuY2UNCmBgYA0KYGBge3J9DQp2YXJfYmV0YV8wX2hhdCAgICAjIHRydWUgdmFyaWFuY2UNCmBgYA0KDQpgYGB7cn0NCmhpc3QoYmV0YV8wX2hhdHMsIHByb2IgPSBUUlVFLCBicmVha3MgPSAyNSwgDQogICAgIHhsYWIgPSBleHByZXNzaW9uKGhhdChiZXRhKVswXSksIG1haW4gPSAiIiwgYm9yZGVyID0gImRvZGdlcmJsdWUiKQ0KY3VydmUoZG5vcm0oeCwgbWVhbiA9IGJldGFfMCwgc2QgPSBzcXJ0KHZhcl9iZXRhXzBfaGF0KSksDQogICAgICBjb2wgPSAiZGFya29yYW5nZSIsIGFkZCA9IFRSVUUsIGx3ZCA9IDMpDQpgYGANCg0KUGVtYmVsYWphcmFuIHNpbXVsYXNpIGluaSBoYW55YSBtZW5zaW11bGFzaWthbiBqdW1sYWggc2FtcGVsIHlhbmcgdGVyYmF0YXMuIFVudHVrIG1lbWJ1a3Rpa2FuIGhhc2lsIGRpc3RyaWJ1c2ksIGRpcGVybHVrYW4gc2FtcGVsIHlhbmcgdGlkYWsgdGVyaGluZ2dhLiBOYW11biBkYWxhbSBwbG90IGJlcmlrdXQgbWVtcGVybGloYXRrYW5ueWEgZGVuZ2FuIGN1a3VwIGplbGFzIGppa2Egc2ltdWxhc2kgaXR1IGJlcmxhbmp1dC4NCg0KYGBge3J9DQpwYXIobWFyID0gYyg1LCA1LCAxLCAxKSkgIyBhZGp1c3RlZCBwbG90IG1hcmdpbnMsIG90aGVyd2lzZSB0aGUgImhhdCIgZG9lcyBub3QgZGlzcGxheQ0KcGxvdChjdW1zdW0oYmV0YV8xX2hhdHMpIC8gKDE6bGVuZ3RoKGJldGFfMV9oYXRzKSksIHR5cGUgPSAibCIsIHlsaW0gPSBjKDUuOTUsIDYuMDUpLA0KICAgICB4bGFiID0gIk51bWJlciBvZiBTaW11bGF0aW9ucyIsDQogICAgIHlsYWIgPSBleHByZXNzaW9uKCJFbXBpcmljYWwgTWVhbiBvZiAiIH4gaGF0KGJldGEpWzFdKSwNCiAgICAgY29sICA9ICJkb2RnZXJibHVlIikNCmFibGluZShoID0gNiwgY29sID0gImRhcmtvcmFuZ2UiLCBsd2QgPSAyKQ0KYGBgDQoNCmBgYHtyfQ0KcGFyKG1hciA9IGMoNSwgNSwgMSwgMSkpICMgYWRqdXN0ZWQgcGxvdCBtYXJnaW5zLCBvdGhlcndpc2UgdGhlICJoYXQiIGRvZXMgbm90IGRpc3BsYXkNCnBsb3QoY3Vtc3VtKGJldGFfMF9oYXRzKSAvICgxOmxlbmd0aChiZXRhXzBfaGF0cykpLCB0eXBlID0gImwiLCB5bGltID0gYygyLjk1LCAzLjA1KSwNCiAgICAgeGxhYiA9ICJOdW1iZXIgb2YgU2ltdWxhdGlvbnMiLA0KICAgICB5bGFiID0gZXhwcmVzc2lvbigiRW1waXJpY2FsIE1lYW4gb2YgIiB+IGhhdChiZXRhKVswXSksDQogICAgIGNvbCAgPSAiZG9kZ2VyYmx1ZSIpDQphYmxpbmUoaCA9IDMsIGNvbCA9ICJkYXJrb3JhbmdlIiwgbHdkID0gMikNCmBgYA0KDQojIyBLZXNhbGFoYW4gQmFrdSAoU3RhbmRhcmQgRXJyb3IpDQoNClNla2FyYW5nIGFkYSAyIGhhc2lsIGRpc3RyaWJ1c2kgeWFuZyBkaXBlcmNheWEsDQokJFxiZWdpbnthbGlnbmVkfQ0KXGhhdHtcYmV0YX1fMCAmXHNpbSBOXGxlZnQoICBcYmV0YV8wLCBcc2lnbWFeMiBcbGVmdChcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fVxyaWdodCkgXHJpZ2h0KSBcXA0KXGhhdHtcYmV0YX1fMSAmXHNpbSBOXGxlZnQoICBcYmV0YV8xLCBcZnJhY3tcc2lnbWFeMn17U197eHh9fSBccmlnaHQpLg0KXGVuZHthbGlnbmVkfSQkDQoNCkRlbmdhbiBtZW5zdGFuZGFyaXNhc2kgaGFzaWwgdGVyc2VidXQgZGlwZXJvbGVoDQokJFxmcmFje1xoYXR7XGJldGF9XzAgLSBcYmV0YV8wfXtcdGV4dHtTRH1bXGhhdHtcYmV0YX1fMF19IFxzaW0gTigwLCAxKSQkDQpkYW4NCiQkXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1x0ZXh0e1NEfVtcaGF0e1xiZXRhfV8xXX0gXHNpbSBOKDAsIDEpJCQNCmRpbWFuYQ0KJCRcdGV4dHtTRH1bXGhhdHtcYmV0YX1fMF0gPSBcc2lnbWFcc3FydHtcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fX0kJA0KZGFuDQokJFx0ZXh0e1NEfVtcaGF0e1xiZXRhfV8xXSA9IFxmcmFje1xzaWdtYX17XHNxcnR7U197eHh9fX0uJCQNCg0KS2FyZW5hIHRpZGFrIGFkYSAkXHNpZ21hJCBkYWxhbSBsYXRpaGFuLCBtYWthIGtpdGEgYWthbiBtZW5nZXN0aW1hc2kgbWVuZ2d1bmFrYW4gJHNfZSQsIGRpbWFzdWtrYW4gcGFkYSBwZXJzYW1hYW4geWFuZyBkaW1pbGlraSBzZWJhZ2FpIHN0YW5kYXIgZGV2aWFzaSBkYXJpIGVzdGltYXNpLg0KDQpLZWR1YSBwZXJzYW1hYW4gYmFydSBpdHUgZGlzZWJ1dCAqKmtlc2FsYWhhbiBiYWt1KiogeWFuZyBiZXJ1cGEgKmVzdGltYXNpKiBzdGFuZGFyIGRldmlhc2kgZGFyaSBkaXN0cmlidXNpIHNhbXBsaW5nLg0KJCRcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMF0gPSBzX2Vcc3FydHtcZnJhY3sxfXtufSArIFxmcmFje1xiYXJ7eH1eMn17U197eHh9fX0kJA0KJCRcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV0gPSBcZnJhY3tzX2V9e1xzcXJ0e1Nfe3h4fX19JCQNClNla2FyYW5nIGRpYmFnaSBkZW5nYW4ga2VzYWxhaGFuIGJha3UgZGFuIGJ1a2FuIHN0YW5kYXIgZGV2aWFzaW55YSwgaGFzaWwgYmVyaWt1dCBkaWd1bmFrYW4gdW50dWsgbWVtYnVhdCBzZWxhbmcga2VwZXJjYXlhYW4gZGFuIG1lbGFrdWthbiB1amkgaGlwb3Rlc2lzLg0KDQokJFxmcmFje1xoYXR7XGJldGF9XzAgLSBcYmV0YV8wfXtcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMF19IFxzaW0gdF97bi0yfSQkDQokJFxmcmFje1xoYXR7XGJldGF9XzEgLSBcYmV0YV8xfXtcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV19IFxzaW0gdF97bi0yfSQkDQpVbnR1ayBtZW5kYXBhdGthbiBpdHUsIHBlcmx1IGRpY2F0YXQgYmFod2ENCiQkXGZyYWN7XHRleHR7UlNTfX17XHNpZ21hXjJ9ID0gXGZyYWN7KG4tMilzX2VeMn17XHNpZ21hXjJ9IFxzaW0gXGNoaV97bi0yfV4yLiQkDQpkYW4gaW5nYXQga2VtYmFsaSB2YXJpYWJlbCBhY2FrICRUJCwgDQokJFQgPSBcZnJhY3tafXtcc3FydHtcZnJhY3tcY2hpX3tkfV4yfXtkfX19JCQNCmRpbGFuanV0a2FuIGRpc3RyaWJ1c2kgJHQkIGRlbmdhbiBkZXJhamF0IGtlYmViYXNhbiAkZCQsIGRpbWFuYSAkXGNoaV9kXjIkIGRhbiAkXGNoaV4yJCB2YXJpYWJlbCBhY2FrIGRlbmdhbiBkZXJhamF0IGtlYmViYXNhbiAkZCQuDQoNCkRpdHVsaXNrYW4sIA0KJCRUXHNpbSB0X2QkJA0KZGlrYXRha2FuIGJhaHdhIHZhcmlhYmVsIGFjYWsgJFQkIGJlcmh1YnVuZ2FuIGRlbmdhbiBkaXN0cmlidXNpICR0JCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gJGQkLg0KDQpMYWx1IG1lbmdndW5ha2FuIHRyaWsga2xhc2lrIHlhaXR1ICJkaWthbGlrYW4gZGVuZ2FuIDEiIGRhbiBkaWF0dXIgdWxhbmcgc2VoaW5nZ2EgbWVuZ2hhc2lsa2FuDQokJFxiZWdpbnthbGlnbmVkfQ0KXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXX0gDQomPSBcZnJhY3tcaGF0e1xiZXRhfV8xIC0gXGJldGFfMX17c19lIC8gXHNxcnR7U197eHh9fX0gXFwNCiY9IFxmcmFje1xoYXR7XGJldGF9XzEgLSBcYmV0YV8xfXtzX2UgLyBcc3FydHtTX3t4eH19fSBcY2RvdCBcZnJhY3tcc2lnbWEgLyBcc3FydHtTX3t4eH19fXtcc2lnbWEgLyBcc3FydHtTX3t4eH19fSBcXA0KJj0gXGZyYWN7XGhhdHtcYmV0YX1fMSAtIFxiZXRhXzF9e1xzaWdtYSAvIFxzcXJ0e1Nfe3h4fX19IFxjZG90IFxmcmFje1xzaWdtYSAvIFxzcXJ0e1Nfe3h4fX19e3NfZSAvIFxzcXJ0e1Nfe3h4fX19IFxcDQomPSBcZnJhY3tcaGF0e1xiZXRhfV8xIC0gXGJldGFfMX17XHNpZ21hIC8gXHNxcnR7U197eHh9fX0gXGJpZ2cvIFxzcXJ0e1xmcmFje3NfZV4yfXtcc2lnbWFeMn19IFxcDQomPSBcZnJhY3tcaGF0e1xiZXRhfV8xIC0gXGJldGFfMX17XHRleHR7U0R9W1xoYXR7XGJldGF9XzFdfSBcYmlnZy8gXHNxcnR7XGZyYWN7XGZyYWN7KG4gLSAyKXNfZV4yfXtcc2lnbWFeMn19e24gLSAyfX0NClxzaW0gXGZyYWN7Wn17XHNxcnR7XGZyYWN7XGNoaV97bi0yfV4yfXtuLTJ9fX0NClxzaW0gdF97bi0yfQ0KXGVuZHthbGlnbmVkfSQkDQoNCmRpbWFuYSAkWlxzaW0gTigwLDEpJC4NCg0KTWVuZ2luZ2F0IGtlbWJhbGkgZGlzdHJpYnVzaSAkdCQgbWlyaXAgZGVuZ2FuIG5vcm1hbCBzdGFuZGFyLCB0YXBpIGRlbmdhbiBla29yL3VqdW5nIHlhbmcgYmVyYm9ib3QuIEtldGlrYSBkZXJhamF0IGtlYmViYXNhbiBtZW5pbmdrYXQsIGRpc3RyaWJ1c2kgJHQkIHNlbWFraW4gbWVuamFkaSBub3JtYWwuIERpYmF3YWggaW5pIGRpdmlzdWFsaXNhc2lrYW4gZGlzdHJpYnVzaSBub3JtYWwgc3RhbmRhciBzZXBlcnRpIDIgY29udG9oIGxhaW5ueWEgZGFyaSBkaXN0cmlidXNpICR0JCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4geWFuZyBiZXJiZWRhLiBQZXJoYXRpa2FuIGJhZ2FpbWFuYSBkaXN0cmlidXNpICR0JCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4geWFuZyBsZWJpaCBiZXNhciBtaXJpcCBkZW5nYW4ga3VydmEgbm9ybWFsIHN0YW5kYXIuDQoNCmBgYHtyfQ0KIyBkZWZpbmUgZ3JpZCBvZiB4IHZhbHVlcw0KeCA9IHNlcSgtNCwgNCwgbGVuZ3RoID0gMTAwKQ0KDQojIHBsb3QgY3VydmUgZm9yIHN0YW5kYXJkIG5vcm1hbA0KcGxvdCh4LCBkbm9ybSh4KSwgdHlwZSA9ICJsIiwgbHR5ID0gMSwgbHdkID0gMiwNCiAgICAgeGxhYiA9ICJ4IiwgeWxhYiA9ICJEZW5zaXR5IiwgbWFpbiA9ICJOb3JtYWwgdnMgdCBEaXN0cmlidXRpb25zIikNCiMgYWRkIGN1cnZlcyBmb3IgdCBkaXN0cmlidXRpb25zDQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEpLCBsdHkgPSAzLCBsd2QgPSAyLCBjb2wgPSAiZGFya29yYW5nZSIpDQpsaW5lcyh4LCBkdCh4LCBkZiA9IDEwKSwgbHR5ID0gMiwgbHdkID0gMiwgY29sID0gImRvZGdlcmJsdWUiKQ0KDQojIGFkZCBsZWdlbmQNCmxlZ2VuZCgidG9wcmlnaHQiLCB0aXRsZSA9ICJEaXN0cmlidXRpb25zIiwNCiAgICAgICBsZWdlbmQgPSBjKCJ0LCBkZiA9IDEiLCAidCwgZGYgPSAxMCIsICJTdGFuZGFyZCBOb3JtYWwiKSwgDQogICAgICAgbHdkID0gMiwgbHR5ID0gYygzLCAyLCAxKSwgY29sID0gYygiZGFya29yYW5nZSIsICJkb2RnZXJibHVlIiwgImJsYWNrIikpDQpgYGANCg0KIyMgU2VsYW5nIEtlcGVyY2F5YWFuIHVudHVrIEtlbWlyaW5nYW4gZGFuIFBlcnBvdG9uZ2FuDQoNCkluZ2F0IGtlbWJhbGkgZGltYW5hIHNlbGFuZyBrZXBlcmNheWFhbiBiZXJiZW50dWs6DQokJFx0ZXh0e0VTVH0gXHBtIFx0ZXh0e0NSSVR9IFxjZG90IFx0ZXh0e1NFfSQkDQphdGF1IA0KJCRcdGV4dHtFU1R9IFxwbSBcdGV4dHtNQVJHSU59JCQNCmRpbWFuYSAkXHRleHR7RVNUfSQgc2VidWFoIGVzdGltYXNpIHVudHVrIHBhcmFtZXRlciBrZXRlcnRhcmlrYW4uICRcdGV4dHtTRX0kIHNlYmFnYWkga2VzYWxhaGFuIGJha3UgZGFyaSBzdWF0dSBlc3RpbWFzaSwgZGFuICRcdGV4dHtNQVJHSU59PVx0ZXh0e0NSSVR9IFxjZG90IFx0ZXh0e1NFfSQNCg0KTGFsdSB1bnR1ayAkXGJldGFfMCQgZGFuICRcYmV0YV8xJCBkYXBhdCBtZW1idWF0IHNlbGFuZyBrZXBlcmNheWFhbiBtZW5nZ3VuYWthbg0KJCRcaGF0e1xiZXRhfV8wIFxwbSB0X3tcYWxwaGEvMiwgbiAtIDJ9IFxjZG90IFx0ZXh0e1NFfVtcaGF0e1xiZXRhfV8wXSBccXVhZCBccXVhZCBccXVhZCBcaGF0e1xiZXRhfV8wIFxwbSB0X3tcYWxwaGEvMiwgbiAtIDJ9IFxjZG90IHNfZVxzcXJ0e1xmcmFjezF9e259K1xmcmFje1xiYXJ7eH1eMn17U197eHh9fX0kJA0KZGFuIA0KJCRcaGF0e1xiZXRhfV8xIFxwbSB0X3tcYWxwaGEvMiwgbiAtIDJ9IFxjZG90IFx0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXSAgXHF1YWQgXHF1YWQgXHF1YWQgXGhhdHtcYmV0YX1fMSBccG0gdF97XGFscGhhLzIsIG4gLSAyfSBcY2RvdCBcZnJhY3tzX2V9e1xzcXJ0e1Nfe3h4fX19JCQNCmRpbWFuYSAkdF97XGFscGhhLzIsbi0yfSQgYWRhbGFoIG5pbGFpIGtyaXRpcyB5YW5nIGJlcmFydGkgJCRQKHRfe24tMn0gPiB0X3tcYWxwaGEvMiwgbiAtIDJ9KSA9IFxhbHBoYS8yJCQuDQoNCiMjIFVqaSBIaXBvdGVzaXMNCg0KSW5nYXQga2VtYmFsaSBkaW1hbmEgdWppIHN0YXRpc3RpayAkXHRleHR7KFRTKX0kIHVudHVrIHVqaSByYXRhLXJhdGEgZGFsYW0gYmVudHVrOiANCiQkXHRleHR7VFN9ID0gXGZyYWN7XHRleHR7RVNUfSAtIFx0ZXh0e0hZUH19e1x0ZXh0e1NFfX0kJA0KZGltYW5hICRcdGV4dHtFc1R9JCBhZGFsYWggZXN0aW1hc2kgdW50dWsgcGFyYW1ldGVyIGtldGVydGFyaWthbiwgJFx0ZXh0e0hZUH0kIGFkYWxhaCBuaWxhaSBoaXBvdGVzaXMgZGFyaSBwYXJhbWV0ZXIsIGRhbiAkXHRleHR7U0V9JCBiZXJ1cGEga2VzYWxhaGFuIGJha3UuDQoNCk1ha2EgdWppbnlhDQokJEhfMDogXGJldGFfMCA9IFxiZXRhX3swMH0gXHF1YWQgXHRleHR7dnN9IFxxdWFkIEhfMTogXGJldGFfMCBcbmVxIFxiZXRhX3swMH0kJA0KZ3VuYWthbiB1amkgc3RhdGlzdGlrbnlhDQokJHQgPSBcZnJhY3tcaGF0e1xiZXRhfV8wIC0gXGJldGFfezAwfX17XHRleHR7U0V9W1xoYXR7XGJldGF9XzBdfSA9IFxmcmFje1xoYXR7XGJldGF9XzAtXGJldGFfezAwfX17c19lXHNxcnR7XGZyYWN7MX17bn0gKyBcZnJhY3tcYmFye3h9XjJ9e1Nfe3h4fX19fSQkDQp5YW5nIGJlcmFydGkgZGliYXdhaCBoaXBvdGVzaXMgMCwgZGlpa3V0aSBkZW5nYW4gZGlzdHJpYnVzaSAkdCQgZGVuZ2FuICRuLTIkIGRlcmFqYXQga2ViZWJhc2FuLiBEaWd1bmFrYW4gJFxiZXRhX3swMH0kIHVudHVrIGRpbm90YXNpa2FuIGRlbmdhbiBuaWxhaSBoaXBvdGVzaXMgJFxiZXRhXzAkLg0KDQpVamlueWENCiQkSF8wOiBcYmV0YV8xID0gXGJldGFfezEwfSBccXVhZCBcdGV4dHt2c30gXHF1YWQgSF8xOiBcYmV0YV8xIFxuZXEgXGJldGFfezEwfSQkDQpndW5ha2FuIHVqaSBzdGF0aXN0aWtueWENCiQkdCA9IFxmcmFje1xoYXR7XGJldGF9XzEtXGJldGFfezEwfX17XHRleHR7U0V9W1xoYXR7XGJldGF9XzFdfSA9IFxmcmFje1xoYXR7XGJldGF9XzEtXGJldGFfezEwfX17c19lIC8gXHNxcnR7U197eHh9fX1zJCQNCiB5YW5nIGJlcmFydGkgZGliYXdhaCBoaXBvdGVzaXMgMCwgZGlpa3V0aSBkZW5nYW4gZGlzdHJpYnVzaSAkdCQgZGVuZ2FuICRuLTIkIGRlcmFqYXQga2ViZWJhc2FuLiBEaWd1bmFrYW4gJFxiZXRhX3sxMH0kIHVudHVrIGRpbm90YXNpa2FuIGRlbmdhbiBuaWxhaSBoaXBvdGVzaXMgJFxiZXRhXzEkLg0KDQojIyBDb250b2ggYGNhcnNgIA0KDQpTZWthcmFuZyBtZW5nZ3VuYWthbiBgY2Fyc2AgZGFyaSBiYWdpYW4gc2ViZWx1bW55YSB1bnR1ayBtZW5naWx1c3RyYXNpIGtvbnNlcG55YS4gQXdhbG55YSBndW5ha2FuIG1vZGVsIGBsbSgpYCBsYWx1IGd1bmFrYW4gYHN1bW1hcnkoKWAgdW50dWsgbWVsaWhhdCBoYXNpbG55YSBkZW5nYW4gbGViaWggZGV0YWlsLg0KDQpgYGB7cn0NCnN0b3BfZGlzdF9tb2RlbCA9IGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpDQpzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkNCmBgYA0KDQojIyMgVWppIGRhbGFtIGBSYA0KDQpzZWthcmFuZyBtZW1iYWhhcyBoYXNpbCB5YW5nIGRpdGFtcGlsa2FuIHlhbmcgZGlzZWJ1dCBgQ29lZmZpY2llbnRgLiBQZXJ0YW1hIGluZ2F0IGtlbWJhbGkgYmFod2EgZGFwYXQgbWVuZ2Vrc3RyYWsgaW5mb3JtYXNpIHNlY2FyYSBsYW5nc3VuZy4NCg0KYGBge3J9DQpuYW1lcyhzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkpDQpgYGANCmBgYHtyfQ0Kc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpJGNvZWZmaWNpZW50cw0KYGBgDQoNCkZ1bmdzaSBgbmFtZXMoKWAgbWVtYmVyaSBpbmZvcm1hc2kgeWFuZyBkaXBlcm9sZWggbGFsdSBndW5ha2FuIG9wZXJhdG9yIGAkYCBkYW4gYENvZWZmaWNpZW50c2AgdW50dWsgbWVuZGFwYXRrYW4gaW5mb3JtYXNpIHlhbmcgZGlidXR1aGthbi4gMiBoYXNpbCB0ZXJzZWJ1dCBzZWhhcnVzbnlhIHRlcmxpaGF0IHRpZGFrIGFzaW5nLg0KJCRcaGF0e1xiZXRhfV8wID0gLTE3LjU3OTA5NDkkJA0KZGFuIA0KJCRcaGF0e1xiZXRhfV8xID0gMy45MzI0MDg4JCQNCnlhbmcgYmVydXBhIGVzdGltYXNpIGRhcmkgbW9kZWwgcGFyYW1ldGVyICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkLg0KDQpTZWthcmFuZyBmb2t1cyBwYWRhIGJhcmlzIGtlZHVhIGRhcmkgaGFzaWxtIHlhbmcgcmVsZXZhbiB0ZXJoYWRhcCAkXGJldGFfMSQuDQoNCmBgYHtyfQ0Kc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpJGNvZWZmaWNpZW50c1syLF0NCmBgYA0KDQpOaWxhaSBwZXJ0YW1hLCBgRXN0aW1hc2lgDQokJFxoYXR7XGJldGF9XzEgPSAzLjkzMjQwODguJCQNCk5pbGFpIGtlZHVhLCBgU3RkLiBFcnJvcmAsIGtlc2FsYWhhbiBiYWt1IGRhcmkgJFxoYXR7XGJldGFfMX0kLA0KJCRcdGV4dHtTRX1bXGhhdHtcYmV0YX1fMV0gPSBcZnJhY3tzX2V9e1xzcXJ0e1Nfe3h4fX19ID0gMC40MTU1MTI4LiQkDQpOaWxhaSBrZXRpZ2EsIGB0IHZhbHVlYCwgbmlsYWkgdWppIHN0YXRpc3RpayBkYXJpIHVudHVrIG1lbmd1amkgJEhfMDogXGJldGFfMSA9IDAkIHZzICRIXzE6IFxiZXRhXzEgXG5lIDAkLA0KDQokJHQgPSBcZnJhY3tcaGF0e1xiZXRhfV8xLTB9e1x0ZXh0e1NFfVtcaGF0e1xiZXRhfV8xXX0gPSBcZnJhY3tcaGF0e1xiZXRhfV8xLTB9e3NfZSAvIFxzcXJ0e1Nfe3h4fX19ID0gOS40NjM5OS4kJA0KVGVyYWtoaXIsIGBQcig+fHR8KWAsIG1lbWJlcmlrYW4gbmlsYWkgcC12YWx1ZSBkYXJpIHVqaSB0ZXJzZWJ1dC4NCiQkXHRleHR7cC12YWx1ZX0gPSAxLjQ4OTgzNjVcdGltZXMgMTBeey0xMn0kJA0KUGVybHUgZGljYXRhdCBkaXNpbmkgc2VjYXJhIHNwZXNpZmlrIHVudHVrIG1lbmd1amkgYXBha2FoICRcYmV0YV8xPTAkLg0KUGFkYSBiYXJpcyBwZXJ0YW1hIGRhcmkgbGFwb3JhbiBvdXRwdXQgZGVuZ2FuIHVqaSBzYW1hIHRldGFwaSB1bnR1ayAkXGJldGFfMCQuIA0KYGBge3J9DQpzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRzWzEsXQ0KYGBgDQoNCktlc2ltcHVsYW4sIGtvZGUgYmVyaWt1dCBtZW55aW1wYW4gaW5mb3JtYXNpIGBzdW1tYXJ5KHN0b3BfZGlzdF9tb2RlbCkkY29lZmZpY2llbnRgIGRhbGFtIHZhcmlhYmVsIGJhcnUgYHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9gLCBsYWx1IGVrc3RyYWsgdGlhcCBlbGVtZW4gcGFkYSB2YXJpYWJlbCBiYXJ1IHlhbmcgbWVuZGVza3JpcHNpIGluZm9ybWFzaSBkaSBkYWxhbW55YS4NCg0KYGBge3J9DQpzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvID0gc3VtbWFyeShzdG9wX2Rpc3RfbW9kZWwpJGNvZWZmaWNpZW50cw0KDQpiZXRhXzBfaGF0ICAgICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzEsIDFdICMgRXN0aW1hdGUNCmJldGFfMF9oYXRfc2UgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMSwgMl0gIyBTdGQuIEVycm9yDQpiZXRhXzBfaGF0X3QgICAgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzEsIDNdICMgdCB2YWx1ZQ0KYmV0YV8wX2hhdF9wdmFsID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1sxLCA0XSAjIFByKD58dHwpDQoNCmJldGFfMV9oYXQgICAgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMiwgMV0gIyBFc3RpbWF0ZQ0KYmV0YV8xX2hhdF9zZSAgID0gc3RvcF9kaXN0X21vZGVsX3Rlc3RfaW5mb1syLCAyXSAjIFN0ZC4gRXJyb3INCmJldGFfMV9oYXRfdCAgICA9IHN0b3BfZGlzdF9tb2RlbF90ZXN0X2luZm9bMiwgM10gIyB0IHZhbHVlDQpiZXRhXzFfaGF0X3B2YWwgPSBzdG9wX2Rpc3RfbW9kZWxfdGVzdF9pbmZvWzIsIDRdICMgUHIoPnx0fCkNCmBgYA0KDQpCaXNhIGRpYnVrdGlrYW4gYmViZXJhcGEgcGVyc2FtYWFuIHlhbmcgc2V0YXJhOiBVamkgJHQkIHN0YXRpc3RpayAkXGhhdHtcYmV0YV8xfSQgZGFuIDIgc2lzaSBuaWxhaSBwIC8gcC12YWx1ZSBiZXJhc29zaWFzaSBkZW5nYW4gdWppIHN0YXRpc3Rpay4gDQpgYGB7cn0NCihiZXRhXzFfaGF0IC0gMCkgLyBiZXRhXzFfaGF0X3NlDQpgYGANCmBgYHtyfQ0KYmV0YV8xX2hhdF90DQpgYGANCmBgYHtyfQ0KMiAqIHB0KGFicyhiZXRhXzFfaGF0X3QpLCBkZiA9IGxlbmd0aChyZXNpZChzdG9wX2Rpc3RfbW9kZWwpKSAtIDIsIGxvd2VyLnRhaWwgPSBGQUxTRSkNCmBgYA0KYGBge3J9DQpiZXRhXzFfaGF0X3B2YWwNCmBgYA0KDQojIyMgU2lnbmlmaWthbnNpIFJlZ3Jlc2ksIFVqaS10DQoNClNla2FyYW5nIG1lbWJhaGFzIHVqaSAqKnNpZ25pZmlrYW5zaSByZWdyZXNpKiouIFBlcnRhbWEsIHBlcmx1IGRpY2F0YXQgYmVyZGFzYXJrYW4gaGFzaWwgZGlzdHJpYnVzaSwgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQgZGFwYXQgZGl1amkgdW50dWsgbmlsYWkgdGVydGVudHUgZGFuIG1lbGFrdWthbiB1amkgMSBkYW4gMiBzaXNpLg0KDQpOYW11biwgc2F0dSB1amkgc3Blc2lmaWssDQokJEhfMDogXGJldGFfMSA9IDAgXHF1YWQgXHRleHR7dnN9IFxxdWFkIEhfMTogXGJldGFfMSBcbmVxIDAkJA0Kc2VyaW5nIGRpZ3VuYWthbi4gIE1hcmkgcGlraXJrYW4gdGVudGFuZyBwZW5ndWppYW4gaW5pIGRhbGFtIGthaXRhbm55YSBkZW5nYW4gbW9kZWwgcmVncmVzaSBsaW5pZXIgc2VkZXJoYW5hLA0KJCRZX2kgPSBcYmV0YV8wICsgXGJldGFfMSB4X2kgKyBcZXBzaWxvbl9pLiQkDQpKaWthIGRpYXN1bXNpa2FuIGhpcG90ZXNpcyAwIGFkYWxhaCBiZW5hciwgbWFrYSAkXGJldGFfMT0wJCBkYW4gbWVtcGVyb2xlaCBtb2RlbCwNCiQkWV9pID0gXGJldGFfMCArIFxlcHNpbG9uX2kuJCQNCkRhbGFtIG1vZGVsIGluaSwgcmVzcG9uZGVuICoqdGlkYWsqKiBiZXJnYW50dW5nIGRlbmdhbiBwcmVkaWt0b3IuIERlbmdhbiBiZWdpdHUgZGFwYXQgZGlwaWtpcmthbiBkZW5nYW4gdWppIHNlYmFnYWkgYmVyaWt1dCwNCg0KKiBEaWJhd2FoICRIXzAkIHRpZGFrIGFkYSBwZXJiZWRhYW4gbGluaWVyIHlhbmcgc2lnbmlmaWthbiBhbnRhcmEgJHgkIGRhbiAkeSQuDQoqIERpYmF3YWggJEhfMSQgYWRhIHBlcmJlZGFhbiBsaW5pZXIgeWFuZyBzaWduaWZpa2FuIGFudGFyYSAkeCQgZGFuICR5JC4NCg0KVW50dWsgY29udG9oIGBjYXJzYCwNCg0KKiBEaWJhd2FoICRIXzAkIHRpZGFrIGFkYSBwZXJiZWRhYW4gbGluaWVyIHlhbmcgc2lnbmlmaWthbiBhbnRhcmEga2VjZXBhdGFuIGRhbiBqYXJhayBiZXJoZW50aS4NCiogRGliYXdhaCAkSF8xJCBhZGEgcGVyYmVkYWFuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuDQoNClVqaSB0ZXJzZWJ1dCBkYXBhdCBkaWxpaGF0IGRhcmkgaGFzaWwgYHN1bW1hcnkoKWAsDQokJFx0ZXh0e3AtdmFsdWV9ID0gMS40ODk4MzY1XHRpbWVzIDEwXnstMTJ9LiQkDQpEZW5nYW4gbmlsYWkgcCB5YW5nIHNhbmdhdCBrZWNpbCwgaGlwb3Rlc2lzIDAgYWthbiBkaXRvbGFrIGRhbGFtIGJhdGFzIHdhamFyICRcYWxwaGEkLCBjb250b2ggJFxhbHBoYT0wLjAxJC4gRGVuZ2FuIGJlZ2l0dSBhZGEgcGVyYmVkYWFuIGxpbmllciB5YW5nIHNpZ25pZmlrYW4gYW50YXJhIGtlY2VwYXRhbiBkYW4gamFyYWsgYmVyaGVudGkuDQoNCkRhcml0YWRpIGthbWkgbWVuZWthbmthbiAqKkxpbmllcioqLg0KDQpgYGB7cn0NCiMga25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6XFVzZXJzXEFjZXJcRGVza3RvcFxQaG90b3Nob3AgUHJvamVjdFxTZW1lc3RlciA1XFN0YXRpc3RpYyBDb21wdXRhdGlvblxXZWVrIDhcMS5wbmciKQ0KbGlicmFyeShPcGVuSW1hZ2VSKQ0KaW1nMSA9IHJlYWRJbWFnZSgiMS5wbmciKQ0KaW1hZ2VTaG93KGltZzEpDQpgYGANCg0KRGFsYW0gcGxvdCBkYXJpIGRhdGEgc2ltdWxhc2kgaW5pLCBkYXBhdCBkaWxpaGF0IGRlbmdhbiBqZWxhcyBodWJ1bmdhbiAkeCQgZGFuICR5JCwgbmFtdW4gaXR1IGJ1a2FubGFoIGh1YnVuZ2FuIGxpbmllci4gSmlrYSBraXRhIG1lbmdnYW1iYXJrYW4gZ2FyaXMgcGFkYSBkYXRhIGluaSBha2FuIG1lbmphZGkgcmF0YS4gSGFzaWwgdWppIHVudHVrICRIXzA6XGJldGFfMT0wJCB2cyAkSF8xOlxiZXRhXzFcbmUwJCBtZW1iZXJpa2FuIG5pbGFpIHAgeWFuZyB0aW5nZ2kgeWFpdHUgMC43NTY0NTQ4LCBtYWthIGdhZ2FsIG1lbm9sYWsgZGFuIGRpa2F0YWthbiBiYWh3YSB0aWRhayBhZGEgaHVidW5nYW4gbGluaWVyIGFudGFyYSAkeCQgZGFuICR5JC4gTmFudGlueWEgYWthbiBkaWxpaGF0IGJhZ2FpbWFuYSBtZW1hc3Vra2FuIGt1cnZhIHBhZGEgZGF0YSBtZW5nZ3VuYWthbiBtb2RlbCAibGluaWVyIiwgdW50dWsgc2VrYXJhbmcgJEhfMDpcYmV0YV8xPTAkIHZzICRIXzE6XGJldGFfMVxuZTAkIGhhbnlhIGRhcGF0IG1lbmRldGVrc2kgc2VidWFoIGdhcmlzIGh1YnVuZ2FuLg0KDQojIyMgU2VsYW5nIEtlcGVyY2F5YWFuIGRpIGBSYA0KDQpEZW5nYW4gbWVuZ2d1bmFrYW4gYFJgLCBzZWxhbmcga2VwZXJjYXlhYW4gJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQgc2FuZ2F0bGFoIG11ZGFoIHVudHVrIGRpZGFwYXRrYW4uDQpgYGB7cn0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBsZXZlbCA9IDAuOTkpDQpgYGANCg0KRGVuZ2FuIGluaSBha2FuIG1lbmdoaXR1bmcgOTklIHNlbGFuZyBrZXBlcmNheWFhbiBkYXJpICRcYmV0YV8wJCBkYW4gJFxiZXRhXzEkLCBiYXJpcyBwZXJ0YW1hIHVudHVrICRcYmV0YV8wJCBkYW4gYmFyaXMga2VkdWEgdW50dWsgJFxiZXRhXzEkLg0KDQpVbnR1ayBjb250b2ggYGNhcnNgIHNhYXQgbWVuYWZzaXJrYW4gZGVuZ2FuIGludGVydmFsLCBkYXBhdCBkaWthdGFrYW4gOTklIGtlcGVyY2F5YWFuIGRhbGFtIHBlbmFtYmFoYW4ga2VjZXBhdGFuIDEgbWlsIHBlciBqYW0sIHJhdGEtcmF0YSBtZW5pbmdrYXQgcGFkYSBqYXJhayBiZXJoZW50aSBkaWFudGFyYSAyLjgxNzkxODctNS4wNDY4OTg4IGtha2kgeWFuZyBtYW5hIGJlcnVwYSBzZWxhbmcgdW50dWsgJFxiZXRhXzEkLg0KDQpQZXJsdSBkaWNhdGF0IHBhZGEgOTklIHNlbGFuZyBrZXBlcmNheWFhbiAqKnRpZGFrKiogbWVuZ2FuZHVuZyBoaXBvdGVzaXMgMC4gS2FyZW5hIHRpZGFrIG1lbmdhbmR1bmcgMCB5YW5nIGFydGlueWEgbWVub2xhaCB1amkgJEhfMDpcYmV0YV8xID0gMCQgdnMgJEhfMTpcYmV0YV8xXG5lMCQgc2FhdCAkXGFscGhhPTAuMDEkLCBzZXBlcnRpIHlhbmcgdGVyamFkaSBzZWJlbHVtbnlhLg0KDQpBbmRhIGhhcnVzIGFnYWsgY3VyaWdhIHRlcmhhZGFwIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrICRcYmV0YV8wJCwga2FyZW5hIG1lbmNha3VwIG5pbGFpIG5lZ2F0aWYsIHlhbmcgc2VzdWFpIGRlbmdhbiBqYXJhayBiZXJoZW50aSBuZWdhdGlmLiBTZWNhcmEgdGVrbmlzIGludGVycHJldGFzaW55YSBhZGFsYWggYmFod2Ega2FtaSA5OSUgeWFraW4gYmFod2EgamFyYWsgYmVyaGVudGkgcmF0YS1yYXRhIHNlYnVhaCBtb2JpbCB5YW5nIG1lbmVtcHVoIGphcmFrIDAgbWlsIHBlciBqYW0gYWRhbGFoIGFudGFyYSAtMzUuNzA2NjEwMyBkYW4gMC41NDg0MjA1IGtha2ksIHRldGFwaSBrYW1pIHRpZGFrIGJlZ2l0dSBwZXJjYXlhIGl0dSwga2FyZW5hIGthbWkgYmVuYXItYmVuYXIgeWFraW4gYmFod2EgaXR1IGFrYW4gdGVyamFkaS4gbm9uLW5lZ2F0aWYuDQoNCkNhdGF0YW4sIG5pbGFpIHNwZXNpZmlrIGRhcGF0IGRpcGVyb2xlaCBkYXJpIG91dHB1dC9oYXNpbCBiZWJlcmFwYSBjYXJhLiBLb2RlIGluaSB0aWRhayBydW4gdGV0YXBpIHNlYmFpa255YSBkaXBlcmlrc2EgaHVidW5nYW4gb3V0cHV0IGRhcmkga29kZSBkaWF0YXMuDQoNCmBgYHtyfQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMSxdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsxLCAxXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMSwgMl0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBwYXJtID0gIihJbnRlcmNlcHQpIiwgbGV2ZWwgPSAwLjk5KQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMixdDQpjb25maW50KHN0b3BfZGlzdF9tb2RlbCwgbGV2ZWwgPSAwLjk5KVsyLCAxXQ0KY29uZmludChzdG9wX2Rpc3RfbW9kZWwsIGxldmVsID0gMC45OSlbMiwgMl0NCmNvbmZpbnQoc3RvcF9kaXN0X21vZGVsLCBwYXJtID0gInNwZWVkIiwgbGV2ZWwgPSAwLjk5KQ0KYGBgDQoNCkJpc2EgZGlwYXN0aWthbiBqdWdhIGthbGt1bGFzaSBzZWxhbmcgJFxiZXRhXzEkIHlhbmcgZGlsYWt1a2FuIGRlbmdhbiBtZW5nZ3VuYWthbiBgUmAuDQpgYGB7cn0NCiMgc3RvcmUgZXN0aW1hdGUNCmJldGFfMV9oYXQgPSBjb2VmKHN0b3BfZGlzdF9tb2RlbClbMl0NCg0KIyBzdG9yZSBzdGFuZGFyZCBlcnJvcg0KYmV0YV8xX2hhdF9zZSA9IHN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKSRjb2VmZmljaWVudHNbMiwgMl0NCg0KIyBjYWxjdWxhdGUgY3JpdGljYWwgdmFsdWUgZm9yIHR3by1zaWRlZCA5OSUgQ0kNCmNyaXQgPSBxdCgwLjk5NSwgZGYgPSBsZW5ndGgocmVzaWQoc3RvcF9kaXN0X21vZGVsKSkgLSAyKQ0KDQojIGVzdCAtIG1hcmdpbiwgZXN0ICsgbWFyZ2luDQpjKGJldGFfMV9oYXQgLSBjcml0ICogYmV0YV8xX2hhdF9zZSwgYmV0YV8xX2hhdCArIGNyaXQgKiBiZXRhXzFfaGF0X3NlKQ0KYGBgDQoNCg0KIyMgSW50ZXJ2YWwgS2VwZXJjYXlhYW4gZGlyaSB1bnR1ayBSYXRhLVJhdGEgUmVzcG9uDQpTZWxhaW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gdW50dWsgJFxiZXRhXzAkIGRhbiAkXGJldGFfMSQsIGFkYSBkdWEgcGVya2lyYWFuIGludGVydmFsIHVtdW0gbGFpbm55YSB5YW5nIGRpZ3VuYWthbiBkYWxhbSByZWdyZXNpLiBZYW5nIHBlcnRhbWEgZGlzZWJ1dCBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayByYXRhLXJhdGEgcmVzcG9uIC4gU2VyaW5na2FsaSwga2FtaSBpbmdpbiBwZXJraXJhYW4gaW50ZXJ2YWwgdW50dWsgcmF0YS1yYXRhLCAkRVtZfFg9eF0kIHVudHVrIG5pbGFpICR4JCB0ZXJ0ZW50dS4NCkRhbGFtIGtlYWRhYW4gaW5pIGtpdGEgbWVuZ2d1bmFrYW4gJFxoYXR7eX0oeCkkIHNlYmFnYWkgcGVya2lyYWFuIGRhcmkgJEVbWXxYPXhdJC4gS2l0YSBtZW5ndWJhaCBzZWRpa2l0IG5vdGFzaSB1bnR1ayBtZW1wZXJqZWxhcyBiYWhhd2EgbmlsYWkgcHJlZGlrc2kgYWRhbGFoIGZ1bmdzaSBkYXJpIG5pbGFpICR4JA0KDQokJFxoYXR7eX09XGhhdFxiZXRhXzAgKyBcaGF0XGJldGFfezF9eCQkDQoNCmluZ2F0LCAkJEVbWXxYPXhdPVxiZXRhXzAgK1xiZXRhX3sxfXgkJA0KDQpKYWRpLCAkXGhhdHt5fSQgYWRhbGFoIHBlcmtpcmFhbiB5YW5nIGJhZ3VzIGthcmVuYSB0aWRhayBiaWFzDQokJEVbXGhhdHt5fV09XGJldGFfMCtcYmV0YV97MX14JCQNCg0Ka2VtdWRpYWFuIGJpc2EgbWVuZGFwYXRrYW4sDQokJHtWYXJbXGhhdHt5fSh4KV09IM+DXjIoezFcb3ZlciBufSt7eC1cYmFye3h9XjIgXG92ZXIgU197eHh9fSl9JCQNCg0KU2VwZXJ0aSBwZXJraXJhYW4gbGFpbm55YSAkXGhhdHt5fSQganVnYSBtZW5naWt1dGkgZGlzdHJpYnVzaSBub3JtYWwuIFNlamFrICRcaGF0XGJldGFfMCQgZGFuICRcaGF0XGJldGFfMSQgYWRhbGFoIGtvbWJpbmFzaSBsaW5lYXIgZGFyaSB2YXJpYWJlbCByYW5kb20gbm9ybWFsLCAkXGhhdHt5fSQuDQokJFxoYXR7eX3iiLxOKM6yXzArzrJfMXgsz4NeMih7MVxvdmVyIG59K3t4LVxiYXJ7eH1eMiBcb3ZlciBTX3t4eH19KSkkJA0KDQpEYW4gYWtoaXJueWEsIHNlamFrIGtpdGEgbWVtYnV0dWhrYW4gbWVtcGVya2lyYWthbiB2YXJpYW5zaSwga2l0YSBoYXJ1cyBtZW1wZXJraXJha2FuIHN0YW5kYXIgZXJyb3IuDQokJFNFW1xoYXR7eX1dPXNfZVxzcXJ0e1xmcmFjezF9e259K1xmcmFjeyh4LXheMil9e1Nfe3h4fX19JCQNCg0KbGFsdSBraXRhIGRhcGF0IG1lbmdndW5ha2FuIHVudHVrIG1lbmVtdWthbiBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayByYXRhLXJhdGEgcmVzcG9uLg0KJCRcaGF0e3l9wrF0X3vOsS8yLG4tMn0uIHNfZVxzcXJ0e1xmcmFjezF9e259K1xmcmFjeyh4LXheMil9e1Nfe3h4fX19JCQNCg0KVW50dWsgbWVuZW11a2FuIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbnMgcmF0YS1yYXRhIG1lbmdndW5ha2FuIFIsIGthbWkgbWVuZ2d1bmFrYW4gZnVuZ3NpIHByZWRpY3QoKS4gS2FtaSBtZW1iZXJpa2FuIGZ1bmdzaSBtb2RlbCB5YW5nIGRpcGFzYW5nIHNlcnRhIGRhdGEgYmFydSwgZGlzaW1wYW4gc2ViYWdhaSBiaW5na2FpIGRhdGEuIChJbmkgcGVudGluZywgc2VoaW5nZ2EgUiBtZW5nZXRhaHVpIG5hbWEgdmFyaWFiZWwgcHJlZGlrdG9yLikgRGkgc2luaSwga2FtaSBtZW5lbXVrYW4gaW50ZXJ2YWwga2VwZXJjYXlhYW4gZGlyaSB1bnR1ayBqYXJhayBoZW50aSByYXRhLXJhdGEga2V0aWthIG1vYmlsIGJlcGVyZ2lhbiA1IG1pbCBwZXIgamFtIGRhbiBrZXRpa2EgbW9iaWwgYmVwZXJnaWFuIDIxIG1pbCBwZXIgamFtLg0KYGBge3J9DQpuZXdfc3BlZWRzID0gZGF0YS5mcmFtZShzcGVlZCA9IGMoNSwgMjEpKQ0KcHJlZGljdChzdG9wX2Rpc3RfbW9kZWwsIG5ld2RhdGEgPSBuZXdfc3BlZWRzLCANCiAgICAgICAgaW50ZXJ2YWwgPSBjKCJjb25maWRlbmNlIiksIGxldmVsID0gMC45OSkNCmBgYA0KIyMgUHJlZGlrc2kgSW50ZXJ2YWwgdW50dWsgT2JzZXJ2YXNpIEJhcnUNCg0KVGVya2FkYW5nIGtpdGEgaW5naW4gbWVuZy1lc3RpbWFzaWthbiBpbnRlcnZhbCB5YW5nIGJhcnUsICRZJCwgdW50dWsgbmlsYWkgdGVydGVudHUgZGFyaSAkeCQuIEluaSBzYW5nYXQgbWlyaXAgZGVuZ2FuIGludGVydmFsIHJlc3BvbiByYXRhLXJhdGEsICRFW1kgfCBYID0geF0kLCB0YXBpIGJlcmJlZGEgZGkgc2F0dSBoYWwgeWFuZyBzYW5nYXQgcGVudGluZy4NCg0KVGViYWthbiB0ZXJiYWlrIGtpdGEgdW50dWsgb2JzZXJ2YXNpIHlhbmcgYmFydSBtYXNpaCB0ZXRhcCAkXGhhdCB5KHgpJC4gRXN0aW1hc2kgcmF0YS1yYXRhIG1hc2loIHRldGFwIHByZWRpa3NpIHRlcmJhaWsgeWFuZyBiaXNhIGtpdGEgYnVhdC4gUGVyYmVkYWFueWEgdGVyZGFwYXQgcGFkYSBqdW1sYWggdmFyaWFiaWxpdGFzbnlhLiBLaXRhIHRhaHUgYmFod2Egb2JzZXJ2YXNpIGl0dSBha2FuIGJlcnZhcmlhc2kgdGVudGFuZyBnYXJpcyByZWdyZXNpIHlhbmcgc2ViZW5hcm55YSBtZW51cnV0IGRpc3RyaWJ1c2kgJE4oMCzPg14yKSQuIEthcmVuYSBpbmkga2l0YSBtZW5hbWJhaGthbiBiZWJlcmFwYSBmYWt0b3IgZGFyaSAkz4NeMiQgdW50dWsgZXN0aW1hc2kgdmFyaWFiaWxpdGFzIGtpdGEgZGVuZ2FuIHR1anVhbiB1bnR1ayBtZW5qZWxhc2thbiB2YXJpYWJpbGl0YXMgZGFyaSBvYnNlcnZhc2kgdGVudGFuZyBnYXJpcyByZWdyZXNpLg0KDQokJFZhcltcaGF0IHkoeCkrz7VdPSBWYXJbXGhhdCB5KHgpXStWYXIgW8+1XSQkDQokJD0gXHNpZ21hXjIgKFxmcmFjezF9e259K1xmcmFjIHsoeC1cYmFyIHgpXjJ9e1N7eHh9fSkgKyDPg14yICQkDQokJCA9IFxzaWdtYV4yICgxICtcZnJhY3sxfXtufStcZnJhYyB7KHgtXGJhciB4KV4yfXtTe3h4fX0pJCQNCiQkXGhhdCB5KHgpICsgz7Ug4oi8IE4gKFxiZXRhXzAgKyBcYmV0YV8xeCzPg14yKDEgK1xmcmFjezF9e259K1xmcmFjIHsoeC1cYmFyIHgpXjJ9e1N7eHh9fSkpJCQNCiQkU0VbXGhhdCB5KHgpK8+1XSA9IHNfZSBcc3FydCB7MSArXGZyYWN7MX17bn0rXGZyYWMgeyh4LVxiYXIgeCleMn17U3t4eH19fSQkDQoNCkxhbHUga2l0YSBkYXBhdCBtZW5lbXVrYW4gaW50ZXJ2YWwgcHJlZGlrc2kgbWVuZ2d1bmFrYW4sDQoNCiQkXGhhdCB5KHgpIMKxIHRfe1xhbHBoYS8yLG4tMn0g4ouFIHNfZVxzcXJ0ezEgK1xmcmFjezF9e259K1xmcmFjIHsoeC1cYmFyIHgpXjJ9e1N7eHh9fX0uJCQNClVudHVrIG1lbmdoaXR1bmcgaW5pIHVudHVrIGt1bXB1bGFuIHBvaW4gZGkgYFJgLCBrZXRhaHVpbGFoIGJhaHdhIGhhbnlhIGFkYSBzZWRpa2l0IHBlcnViYWhhbiBkaWRhbGFtIHNpbnRha3MgZGFyaSBwZW5lbXVhbiBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayByZXNwb24gcmF0YS1yYXRhLg0KDQpgYGB7cn0NCnByZWRpY3Qoc3RvcF9kaXN0X21vZGVsLCBuZXdkYXRhID0gbmV3X3NwZWVkcywgDQogICAgICAgIGludGVydmFsID0gYygicHJlZGljdGlvbiIpLCBsZXZlbCA9IDAuOTkpDQpgYGANCg0KSnVnYSBrZXRhaHVpbGFoIGJhaHdhIGR1YSBpbnRlcnZhbCBpbmkgbGViaWggbGViYXIgZGliYW5kaW5nIGludGVydmFsIGtlcGVyY2F5YWFuIHlhbmcgc2VzdWFpIHVudHVrIHJlc3BvbiByYXRhLXJhdGEuDQoNCiMjIEtleWFraW5hbiBkYW4gQmFuZCBQcmVkaWtzaQ0KDQpTZXJpbmdrYWxpIGtpdGEgYWthbiBtZW1wbG90IGtlZHVhIGludGVydmFsIGtlcGVyY2F5YWFuIHVudHVrIHJlc3BvbiByYXRhLXJhdGEgZGFuIGludGVydmFsIHByZWRpa3NpIHVudHVrIHNlbXVhIGtlbXVuZ2tpbmFuIGRhcmkgbmlsYWkgJHgkLiBLaXRhIG1lbWFuZ2dpbCBpbmkgc2ViYWdhaSBrZXBlcmNheWFhbiBkYW4gYmFuZCBwcmVkaWtzaS4NCg0KYGBge3J9DQpzcGVlZF9ncmlkID0gc2VxKG1pbihjYXJzJHNwZWVkKSwgbWF4KGNhcnMkc3BlZWQpLCBieSA9IDAuMDEpDQpkaXN0X2NpX2JhbmQgPSBwcmVkaWN0KHN0b3BfZGlzdF9tb2RlbCwgDQogICAgICAgICAgICAgICAgICAgICAgIG5ld2RhdGEgPSBkYXRhLmZyYW1lKHNwZWVkID0gc3BlZWRfZ3JpZCksIA0KICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9ICJjb25maWRlbmNlIiwgbGV2ZWwgPSAwLjk5KQ0KZGlzdF9waV9iYW5kID0gcHJlZGljdChzdG9wX2Rpc3RfbW9kZWwsIA0KICAgICAgICAgICAgICAgICAgICAgICBuZXdkYXRhID0gZGF0YS5mcmFtZShzcGVlZCA9IHNwZWVkX2dyaWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWwgPSAicHJlZGljdGlvbiIsIGxldmVsID0gMC45OSkgDQoNCnBsb3QoZGlzdCB+IHNwZWVkLCBkYXRhID0gY2FycywNCiAgICAgeGxhYiA9ICJTcGVlZCAoaW4gTWlsZXMgUGVyIEhvdXIpIiwNCiAgICAgeWxhYiA9ICJTdG9wcGluZyBEaXN0YW5jZSAoaW4gRmVldCkiLA0KICAgICBtYWluID0gIlN0b3BwaW5nIERpc3RhbmNlIHZzIFNwZWVkIiwNCiAgICAgcGNoICA9IDIwLA0KICAgICBjZXggID0gMiwNCiAgICAgY29sICA9ICJncmV5IiwNCiAgICAgeWxpbSA9IGMobWluKGRpc3RfcGlfYmFuZCksIG1heChkaXN0X3BpX2JhbmQpKSkNCmFibGluZShzdG9wX2Rpc3RfbW9kZWwsIGx3ZCA9IDUsIGNvbCA9ICJkYXJrb3JhbmdlIikNCg0KbGluZXMoc3BlZWRfZ3JpZCwgZGlzdF9jaV9iYW5kWywibHdyIl0sIGNvbCA9ICJkb2RnZXJibHVlIiwgbHdkID0gMywgbHR5ID0gMikNCmxpbmVzKHNwZWVkX2dyaWQsIGRpc3RfY2lfYmFuZFssInVwciJdLCBjb2wgPSAiZG9kZ2VyYmx1ZSIsIGx3ZCA9IDMsIGx0eSA9IDIpDQpsaW5lcyhzcGVlZF9ncmlkLCBkaXN0X3BpX2JhbmRbLCJsd3IiXSwgY29sID0gImRvZGdlcmJsdWUiLCBsd2QgPSAzLCBsdHkgPSAzKQ0KbGluZXMoc3BlZWRfZ3JpZCwgZGlzdF9waV9iYW5kWywidXByIl0sIGNvbCA9ICJkb2RnZXJibHVlIiwgbHdkID0gMywgbHR5ID0gMykNCnBvaW50cyhtZWFuKGNhcnMkc3BlZWQpLCBtZWFuKGNhcnMkZGlzdCksIHBjaCA9ICIrIiwgY2V4ID0gMykNCmBgYA0KDQpCZWJlcmFwYSBoYWwgeWFuZyBwZXJsdSBkaXBlcmhhdGlrYW46DQogIH5LaXRhIG1lbmdndW5ha2FuIGFyZ3VtZW4gYHlsaW1gIHVudHVrIG1lbG9uZ2dhcmthbiBzdW1idSB5IGRhcmkgcGxvdCB0ZXJzZWJ1dCwgc2VqYWsgYmFuZG55YSBsZWJpaCBqYXVoIGRhcmlwYWRhIHRpdGlrIHlhbmcgYWRhLg0KICB+S2l0YSBtZW5hbWJhaGthbiBwb2luIGRpIHBvaW4gJCh4LFxiYXIgeSkkDQogICAgSW5pIG1lcnVwYWthbiBzZWJ1YWggdGl0aWsgZGltYW5hIGdhcmlzIHJlZ3Jlc2lueWEgYWthbiBzZWxhbHUgbWVsZXdhdGlueWEuIChQaWtpcmthbiBrZW5hcGEgYmlzYSB0ZXJqYWRpLikNCiAgICBJbmkgYWRhbGFoIHRpdGlrIGRpbWFuYSBrZWR1YSBrZXBlcmNheWFhbiBkYW4gYmFuZCBwcmVkaWtzaSBtZW5qYWRpIHlhbmcgdGVyc2VtcGl0LiBMaWhhdGxhaCBrZXBhZGEgc3RhbmRhciBrZXNhbGFoYW5ueWEgZGFyaSBrZWR1YW55YSB1bnR1ayBtZW5nZXRhaHVpIGtlbmFwYSBpdHUgYmlzYSB0ZXJqYWRpLg0KDQojIyBVamkgRiwgU2lnbmlmaWthbnNpIFJlZ3Jlc2kNCg0KS2FzdXMgZGFyaSByZWdyZXNpIGxpbmVhciBzZWRlcmhhbmEsIHVqaSAkdCQgdW50dWsgc2lnbmlmaWthc2kgcmVncmVzaSBtZXJ1cGFrYW4gbmlsYWkgZXF1aXZhbGVudCB1bnR1ayB1amkgbGFpbm55YSwgeWFpdHUgdWppICRGJCB1bnR1ayBzaWduaWZpa2Fuc2kgcmVncmVzaS4gRXF1aXZhbGVudCBpbmkgaGFueWEgYWthbiBtZW5qYWRpIGJlbmFyIHVudHVrIHJlZ3Jlc2kgbGluZWFyIHNlZGVyaGFuYSwgZGFuIGRpIGJhZ2lhbiBzZWxhbmp1dG55YSBraXRhIGhhbnlhIGFrYW4gbWVuZ2d1bmFrYW4gdWppICRGJCB1bnR1ayBzaWduaWZpa2Fuc2kgcmVncmVzaW55YS4NCg0KSW5nYXRsYWgga2VtYmFsaSBkaSBzZWtzaSB0ZXJha2hpciBkYXJpIGRla29tcG9zaXNpIHZhcmlhbnMgeWFuZyBraXRhIGxpaGF0IHNlYmVsdW0gbWVuZ2hpdHVuZyBuaWxhaSBgJFJeMiQsIA0KDQokJOKIkV97aT0xfV5uICggeV9pIC0gXGJhciB5KV4yID0gXFNpZ21hX3tpLTF9Xm4gKHlfaSAtIFxiYXIgeV9pKV4yICsgXFNpZ21hX3tpPTF9Xm4gKFxoYXQgeV9pIC0gXGJhciB5KV4yLCQkDQoNCmF0YXUsIGxlYmloIHNpbmdrYXRueWEsDQoNCiQkU1NUID0gU1NFICsgU1NSZWcuJCQNCg0KVW50dWsgbWVuZ2VtYmFuZ2thbiB1amkgJEYkLCBraXRhIGFrYW4gbWVuZ2F0dXIgbGFnaSBpbmZvcm1hc2kgaW5pIGRpIHRhYmVsIGBBTk9WQWAsDQoNCmBgYHtyfQ0KIyBrbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzpcVXNlcnNcQWNlclxEZXNrdG9wXFBob3Rvc2hvcCBQcm9qZWN0XFNlbWVzdGVyIDVcU3RhdGlzdGljIENvbXB1dGF0aW9uXFdlZWsgOFwyLnBuZyIpDQpsaWJyYXJ5KE9wZW5JbWFnZVIpDQppbWcyID0gcmVhZEltYWdlKCIyLnBuZyIpDQppbWFnZVNob3coaW1nMikNCmBgYA0KDQpBTk9WQSBhdGF1IGFuYWxpc2lzIGRhcmkgdmFyaWFucyBha2FuIG1lbmphZGkgc2VidWFoIGtvbnNlcCB5YW5nIHNlcmluZyBraXRhIGJhaGFzIGRhbGFtIGtlbGFzIGluaS4NClVudHVrIHNla2FyYW5nLCBraXRhIGFrYW4gZm9rdXMga2VwYWRhIGhhc2lsLWhhc2lsIGRpZGFsYW0gdGFiZWwsIGRpbWFuYSAkRiQgc3RhdGlzdGlrbnlhLA0KDQokJFxmcmFjIHtcU2lnbWFfe2k9MX1ebiAoIHlfaSAtIFxiYXIgeSleMi8xfXtcU2lnbWFfe2k9MX1ebiAoIHlfaSAtIFxoYXQgeV9pKV4yLyhuLTIpfSDiiLwgRl97MSxuLTJ9JCQNCg0KZGltYW5hIG1lbmdpa3V0aSBkaXN0cmlidXNpICRGJCBkZW5nYW4gZGVyYWphdCBrZWJlYmFzYW4gMSBkYW4gJG4tMiQgZGliYXdhaCBoaXBvdGVzaXMgbm9sLiBTZWJ1YWggZGlzdHJpYnVzaSAkRiQgYWRhbGFoIGRpc3RyaWJ1c2kga29udGludSB5YW5nIGhhbnlhIG1lbmdhbWJpbCBuaWxhaSBwb3NpdGlmIGRhbiBtZW1wdW55YWkgZHVhIHBhcmFtZXRlciwgeWFuZyBtZXJ1cGFrYW4gZHVhIGRlcmFqYXQga2ViZWJhc2FuLg0KDQpJbmdhdGxhaCBrZW1iYWxpLCBkaWRhbGFtIHNpZ25pZmlrYW5zaSBkYXJpIHVqaSByZWdyZXNpLCAkWSQgYHRpZGFrYCBiZXJnYW50dW5nIGtlcGFkYSAkeCQgZGkgaGlwb3Rlc2lzIG5vbC4NCg0KJCRIXzAgOiBcYmV0YV8xID0gMCQkICQkIFlfaSA9IFxiZXRhXzAgKyBcZXBzaWxvbl9pJCQNCg0KRGlzYWF0IGFsdGVybmF0aWYgZGFyaSBoaXBvdGVzaXMgJFkkIGJlcmdhbnR1bmcga2VwYWRhICR4JC4NCg0KJCRIXzAgOiBcYmV0YV8xIOKJoCAwJCQgJCQgWV9pID0gXGJldGFfMXhfaSArIFxlcHNpbG9uX2kkJA0KDQpLaXRhIGRhcGF0IG1lbmdndW5ha2FuICRGJCBzdGF0aXN0aWsgdW50dWsgbWVudW5qdWtrYW4gcGVuZ3VqaWFuIGluaS4NCg0KJCRGID0gXGZyYWMge1xTaWdtYV97aT0xfV5uIChcaGF0IHlfaSAtIFxiYXIgeSleMi8xfXtcU2lnbWFfe2k9MX1ebiAoIHlfaSAtIFxoYXQgeV9pKV4yLyhuLTIpfSQkDQoNClNlY2FyYSBraHVzdXMsIGtpdGEgYWthbiBtZW5vbGFrIGhpcG90ZWlzIG5vbG55YSBkaXNhYXQgbmlsYWkgJEYkIHN0YXRpc3Rpa255YSBiZXNhciwgaXR1IGRpYSwgZGlzYWF0IGFkYSBwcm9iYWJpbGl0YXMgcmVuZGFoIGJhaHdhIHBlbmdhbWF0YW4gc2VjYXJhIGtlYmV0dWxhbiwgZGFwYXQgYmVyYXNhbCBkYXJpIG1vZGVsIGhpcG90ZXNpcyBub2wuIEtpdGEgYWthbiBtZW1iaWFya2FuIGBSYCBtZW5naGl0dW5nIG5pbGFpIHAgdW50dWsga2l0YS4NCg0KVU50dWsgbWVudW5qdWtrYW4gdWppICRGJCBkaSBgUmAsIGFuZGEgZGFwYXQgbWVsaWhhdCBkaSBiYXJpcyB0ZXJha2hpciBkYXJpIGRhdGEgeWFuZyBrZWx1YXIgZGFyaSBgc3VtbWFyeSgpYCB5YW5nIGRpcGFuZ2dpbCBgRi1zdGF0aXN0aWNgIHlhbmcgbWVtYmVyaWthbiBuaWxhaSBkYXJpIHVqaSBzdGF0aXN0aWssIG5pbGFpIGRlcmFqYXQga2ViZWJhc2FuIHlhbmcgcmVsZXZhbiwganVnYSBuaWxhaSBwIGRhcmkgcGVuZ3VqaWFuIHRlcnNlYnV0Lg0KDQpgYGB7cn0NCnN1bW1hcnkoc3RvcF9kaXN0X21vZGVsKQ0KYGBgDQoNClNlbGFpbiBpdHUsIGFuZGEgZGFwYXQgbWVuZ2d1bmFrYW4gZnVuZ3NpIGBhbm92YSgpYCB1bnR1ayBtZW5hbXBpbGthbiBpbmZvcm1hc2kgZGFyaSB0YWJlbCBBTk9WQS4NCg0KYGBge3J9DQphbm92YShzdG9wX2Rpc3RfbW9kZWwpDQpgYGANCg0KSW5pIGp1Z2EgbWVtYmVyaWthbiBuaWxhaSBwIGRhcmkgc3VhdHUgcGVuZ3VqaWFuLiBBbmRhIGhhcnVzIG1lbXBlcmhhdGlrYW4gYmFod2EgbmlsYWkgcCBkYXJpIHVqaSAkdCQgaXR1IHNhbWEuIEFuZGEganVnYSBtdW5na2luIHNhZGFyIGJhaHdhIG5pbGFpIGRhcmkgdWppIHN0YXRpc3RpayBkYXJpIHVqaSAkdCQsIDkuNDYzOTksIGJpc2EgZGkga3VhZHJhdGthbiB1bnR1ayBtZW5kYXBhdGthbiBuaWxhaSBkYXJpICRGJCBzdGF0aXN0aWssIDg5LjU2NzEwNjUuDQoNClBlcmhhdGlrYW4gYmFod2EgYWRhIGJlYmVyYXBhIGphbGFubGFpbiB5YW5nIHNhbWEgeWFuZyBkYXBhdCBkaWxha3VrYW4gZGkgYFJgLCB5YW5nIHNlcmluZyBraXRhIGxvaGF0IHVudHVrIG1lbWJhbmRpbmdrYW4gZHVhIG1vZGVsLg0KDQpgYGB7cn0NCmFub3ZhKGxtKGRpc3QgfiAxLCBkYXRhID0gY2FycyksIGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpKQ0KYGBgDQoNClBlcm55YXRhYW4gbW9kZWwgYGxtKGRpc3QgfiAxLCBkYXRhID0gY2FycylgIG1lbmVyYXBrYW4gbW9kZWwgJFlfaSA9IFxiZXRhXzAgKyBcZXBzaWxvbl9pJCBrZXBhZGEgZGF0YSBgY2Fyc2AuIFBlcmhhdGlrYW4gYmFod2EgJFxoYXQgeSA9IFxiYXIgeSQgZGlzYWF0ICRZX2kgPSAgXGJldGFfMCArIFxlcHNpbG9uX2kkLg0KDQpQZXJueWF0YWFuIG1vZGVsIGBsbShkaXN0IH4gc3BlZWQsIGRhdGEgPSBjYXJzKWAgbWVuZXJhcGthbiBtb2RlbCAkWV9pID0gXGJldGFfMCArIFxiZXRhXzF4X2kgKyBcZXBzaWxvbl9pJC4NCg0KTGFsdSBraXRhIGRhcGF0IG1lbWlraXJrYW4ga2VndW5hYW4gZGFyaSAgYGFub3ZhKClgIHNlYmFnYWkgcGVyYmFuZGluZ2FuIHNlY2FyYSBsYW5nc3VuZyBkYXJpIGR1YSBtb2RlbC4NCihQZXJoYXRpa2FuIGJhaHdhIGtpdGEgbWVuZGFwYXRrYW4gbGFnaSBuaWxhaSBwIHlhbmcgc2FtYS4pDQo=