Study Cases

Confidence Interval~ Week 13

M.Fitrah Aidil Harahap

Student Majoring in Data Science


1 Case Study 1

Confidence Interval for Mean, \(\sigma\) Known: An e-commerce platform wants to estimate the average number of daily transactions per user after launching a new feature. Based on large-scale historical data, the population standard deviation is known.

\[ \begin{eqnarray*} \sigma &=& 3.2 \quad \text{(population standard deviation)} \\ n &=& 100 \quad \text{(sample size)} \\ \bar{x} &=& 12.6 \quad \text{(sample mean)} \end{eqnarray*} \]

Tasks

  1. Identify the appropriate statistical test and justify your choice.
  2. Compute the Confidence Intervals for:
    • \(90\%\)
    • \(95\%\)
    • \(99\%\)
  3. Create a comparison visualization of the three confidence intervals.
  4. Interpret the results in a business analytics context.

JAWAB :

1.1 Uji statistik yang tepat untuk digunakan adalah Z-Test (Z-Interval) untuk rata-rata populasi.

  • Standar Deviasi Populasi (\(\sigma\)) Diketahui: Soal secara eksplisit menyebutkan \(\sigma = 3.2\). Jika \(\sigma\) tidak diketahui, kita akan menggunakan t-test.

  • Ukuran Sampel Besar: Sampel (\(n = 100\)) jauh lebih besar dari 30 (\(n > 30\)), sehingga menurut Teorema Limit Pusat, distribusi rata-rata sampel akan mendekati distribusi normal.

1.2 Perhitungan Confidence Intervals (CI)

Rumus umum Confidence Interval adalah: \[\bar{x} \pm z \cdot \left( \frac{\sigma}{\sqrt{n}} \right)\] Di mana Standard Error (\(SE\)) adalah: \(SE = \frac{3.2}{\sqrt{100}} = 0.32\).

Data Distribusi Z
Confidence_Level Z_Kritis Margin_Error Lower Upper
90% 1.645 0.526 12.074 13.126
95% 1.960 0.627 11.973 13.227
99% 2.576 0.824 11.776 13.424

1.3 Visualisasi Perbandingan

1.4 Interpretasi dalam Konteks Business Analytics

  • Kepastian Presisi: Semakin tinggi tingkat kepercayaan (99%), semakin lebar rentangnya. Secara bisnis, jika kita ingin sangat yakin (99%) bahwa prediksi kita benar, kita harus menerima rentang yang lebih luas (11.78 hingga 13.42 transaksi). Sebaliknya, pada 90%, rentangnya lebih sempit (presisi lebih tinggi), namun risiko melesetnya lebih besar.

  • Efektivitas Fitur Baru: Manajemen e-commerce dapat menyimpulkan dengan keyakinan 95% bahwa rata-rata transaksi harian per user setelah peluncuran fitur baru berada di antara 11.97 hingga 13.23. Angka ini bisa dibandingkan dengan data historis sebelum fitur diluncurkan untuk mengukur kesuksesan KPI.

  • Pengambilan Keputusan: Rentang ini memberikan “batas aman” bagi tim operasional untuk memproyeksikan beban server atau pendapatan harian tanpa hanya mengandalkan satu angka rata-rata tunggal yang mungkin fluktuatif.


2 Case Study 2

Confidence Interval for Mean, \(\sigma\) Unknown: A UX Research team analyzes task completion time (in minutes) for a new mobile application. The data are collected from 12 users:

\[ 8.4,\; 7.9,\; 9.1,\; 8.7,\; 8.2,\; 9.0,\; 7.8,\; 8.5,\; 8.9,\; 8.1,\; 8.6,\; 8.3 \]

Tasks:

  1. Identify the appropriate statistical test and explain why.
  2. Compute the Confidence Intervals for:
    • \(90\%\)
    • \(95\%\)
    • \(99\%\)
  3. Visualize the three intervals on a single plot.
  4. Explain how sample size and confidence level influence the interval width.

JAWAB :

2.1 Identifikasi Uji Statistik

Uji statistik yang tepat adalah One-Sample t-test (t-interval).

  • Standar Deviasi Populasi (\(\sigma\)) Tidak Diketahui: Kita hanya memiliki data sampel, sehingga harus menggunakan standar deviasi sampel (\(s\)).

  • Ukuran Sampel Kecil: Jumlah sampel hanya \(n = 12\) (\(n < 30\)). Dalam kondisi ini, distribusi-\(t\) lebih akurat daripada distribusi-\(z\) untuk mengakomodasi ketidakpastian ekstra dari sampel kecil.

2.2 Perhitungan Confidence Intervals Data:

\(8.4, 7.9, 9.1, 8.7, 8.2, 9.0, 7.8, 8.5, 8.9, 8.1, 8.6, 8.3\)

  • Mean Sampel (\(\bar{x}\)): \(8.458\)

  • Standar Deviasi Sampel (\(s\)): \(0.412\)

  • Degrees of Freedom (\(df\)): \(n - 1 = 11\)

Hasil Estimasi Distribusi T
Confidence Level t-score (df=11) Margin of Error Lower Bound Upper Bound
90% 1.796 0.214 8.244 8.672
95% 2.201 0.262 8.196 8.196
99% 3.106 0.369 8.089 8.827

2.3 Visualisasi Perbandingan

2.4 Pengaruh Ukuran Sampel dan Confidence Level

  • Confidence Level: Semakin tinggi tingkat kepercayaan (misal dari 90% ke 99%), semakin lebar intervalnya. Hal ini karena kita membutuhkan rentang yang lebih luas agar lebih yakin bahwa parameter populasi benar-benar ada di dalamnya.

  • Sample Size (\(n\)): Semakin besar ukuran sampel, semakin sempit intervalnya. Secara matematis, \(n\) berada di penyebut dalam rumus Standard Error (\(s/\sqrt{n}\)). Sampel yang lebih besar mengurangi variabilitas estimasi, sehingga menghasilkan presisi yang lebih tinggi.


3 Case Study 3

Confidence Interval for a Proportion, A/B Testing: A data science team runs an A/B test on a new Call-To-Action (CTA) button design. The experiment yields:

\[ \begin{eqnarray*} n &=& 400 \quad \text{(total users)} \\ x &=& 156 \quad \text{(users who clicked the CTA)} \end{eqnarray*} \]

Tasks:

  1. Compute the sample proportion \(\hat{p}\).
  2. Compute Confidence Intervals for the proportion at:
    • \(90\%\)
    • \(95\%\)
    • \(99\%\)
  3. Visualize and compare the three intervals.
  4. Explain how confidence level affects decision-making in product experiments.

JAWAB :

3.1 Hitung Proporsi Sampel(\(\hat{p}\))

Berdasarkan data eksperimen:

  • Total pengguna (\(n\)) = 400
  • Pengguna yang mengklik CTA (\(x\)) = 156

\[\hat{p} = \frac{x}{n} = \frac{156}{400} = 0.39\] Jadi, proporsi sampelnya adalah 0.39 atau 39%.

3.2 Hitung Confidence Intervals untuk Proporsi

Rumus yang digunakan adalah: \(\hat{p} \pm z \cdot \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}\) Di mana Standard Error (\(SE\)) adalah: \(\sqrt{\frac{0.39 \cdot 0.61}{400}} \approx 0.02439\)

Tabel Interval Kepercayaan
Confidence.Level Nilai.Kritis..z. Margin.of.Error Lower.Bound Upper.Bound
90% 1.645 0.0401 0.3499 0.4301
95% 1.960 0.0478 0.3422 0.4378
99% 2.576 0.0628 0.3272 0.4528*

3.3 Visualisasi Perbandingan

3.4 Pengaruh Confidence Level dalam Pengambilan Keputusan Produk

Dalam konteks eksperimen produk (A/B Testing), tingkat kepercayaan sangat mempengaruhi keputusan:

  • Toleransi Risiko: Tingkat kepercayaan 95% adalah standar industri. Jika kita menggunakan 99%, kita menjadi sangat konservatif—kita butuh bukti yang sangat kuat sebelum menyatakan suatu desain CTA lebih baik. Ini mengurangi risiko False Positive (menyatakan ada efek padahal tidak ada).

  • Kecepatan vs Kepastian: Tingkat kepercayaan 90% menghasilkan interval yang lebih sempit, yang memungkinkan pengambilan keputusan lebih cepat dengan data yang lebih sedikit, namun dengan risiko kesalahan yang lebih tinggi (10%).

  • Aplikasi Praktis: Jika interval kepercayaan untuk desain baru tidak tumpang tindih (overlap) dengan performa desain lama, tim produk dapat dengan percaya diri meluncurkan fitur tersebut. Semakin tinggi tingkat kepercayaan, semakin besar keyakinan bisnis bahwa peningkatan metrik bukan terjadi karena kebetulan.

4 Case Study 4

Precision Comparison (Z-Test vs t-Test): Two data teams measure API latency (in milliseconds) under different conditions.

\[\begin{eqnarray*} \text{Team A:} \\ n &=& 36 \quad \text{(sample size)} \\ \bar{x} &=& 210 \quad \text{(sample mean)} \\ \sigma &=& 24 \quad \text{(known population standard deviation)} \\[6pt] \text{Team B:} \\ n &=& 36 \quad \text{(sample size)} \\ \bar{x} &=& 210 \quad \text{(sample mean)} \\ s &=& 24 \quad \text{(sample standard deviation)} \end{eqnarray*}\]

Tasks

  1. Identify the statistical test used by each team.
  2. Compute Confidence Intervals for 90%, 95%, and 99%.
  3. Create a visualization comparing all intervals.
  4. Explain why the interval widths differ, even with similar data.

JAWAB:

4.1 Identifikasi Uji Statistik

Kedua tim memiliki ukuran sampel yang sama (\(n = 36\)), namun perbedaan terletak pada informasi standar deviasi yang tersedia:

  • Team A (Z-Test): Menggunakan Z-Test karena standar deviasi populasi (\(\sigma\)) diketahui.

  • Team B (t-Test): Menggunakan t-Test karena standar deviasi populasi tidak diketahui, sehingga menggunakan standar deviasi sampel (\(s\)).

4.2 Perhitungan Confidence Interval (CI)

Rumus umum: \(\bar{x} \pm (\text{Critical Value} \times \frac{\text{std dev}}{\sqrt{n}})\) Dengan Standard Error (\(SE\)) = \(\frac{24}{\sqrt{36}} = 4\).

Tabel Interval Kepercayaan Team A
Confidence.Level Nilai.Kritis..z.. Perhitungan..z..x.4. Lower.Bound..ms. Upper.Bound..ms.
90% 1.645 6.58 203.42 216.58
95% 1.960 7.84 202.16 217.84
99% 2.576 10.30 199.70 220.30
Tabel Interval Kepercayaan Team B
Confidence Level t-score (t*) Perhitungan Lower Bound Upper Bound
90% 1.689 210 ± 6.76 203.24 216.76
95% 2.030 210 ± 8.12 201.88 218.12
99% 2.724 210 ± 10.90 199.10 220.90

4.3 Visualisasi Perbandingan

4.4 Analisis Perbedaan Lebar Interval

Meskipun nilai \(\bar{x}\), \(n\), dan angka standar deviasinya sama (24), interval Team B lebih lebar karena alasan berikut:

1. Ketidakpastian Tambahan: Team B menggunakan standar deviasi sampel (\(s\)), yang merupakan estimasi. Distribusi-t memiliki “ekor yang lebih tebal” (heavier tails) untuk mengompensasi ketidakpastian estimasi tersebut.

2. Nilai Kritis: Nilai kritis \(t\) selalu lebih besar daripada nilai kritis \(z\) untuk ukuran sampel yang sama (\(t^ > z^\)).

3. Konservatisme: Pendekatan t-test lebih konservatif (menghasilkan margin of error lebih besar) untuk memastikan bahwa parameter populasi benar-benar tercakup dalam interval ketika informasi populasi tidak lengkap.

5 Case Study 5

One-Sided Confidence Interval: A Software as a Service (SaaS) company wants to ensure that at least 70% of weekly active users utilize a premium feature.

From the experiment:

\[ \begin{eqnarray*} n &=& 250 \quad \text{(total users)} \\ x &=& 185 \quad \text{(active premium users)} \end{eqnarray*} \]

Management is only interested in the lower bound of the estimate.

Tasks:

  1. Identify the type of Confidence Interval and the appropriate test.
  2. Compute the one-sided lower Confidence Interval at:
    • \(90\%\)
    • \(95\%\)
    • \(99\%\)
  3. Visualize the lower bounds for all confidence levels.
  4. Determine whether the 70% target is statistically satisfied.

JAWAB:

5.1 Identifikasi Tipe Confidence Interval dan Uji yang Tepat

  • Tipe Confidence Interval: Menggunakan One-Sided Lower Confidence Interval karena manajemen hanya tertarik pada batas bawah (lower bound) untuk memastikan proporsi pengguna minimal mencapai target tertentu.

  • Uji Statistik: Menggunakan Z-test untuk Proporsi (Z-test for a single proportion) karena data berupa proporsi binominal (aktif/tidak aktif) dengan ukuran sampel yang besar (\(n=250\)).

5.2 Perhitungan One-Sided Lower Confidence Interval

Diketahui :

  • \(n = 250\)\(x = 185\)

  • Proporsi sampel (\(\hat{p}\)) = \(\frac{185}{250} = 0.74\) (74%)

  • Standard Error (\(SE\)) = \(\sqrt{\frac{\hat{p}(1-\hat{p})}{n}} = \sqrt{\frac{0.74 \times 0.26}{250}} \approx 0.0277\)

  • Rumus Lower Bound: \(\hat{p} - (z \times SE)\)

Tabel Batas Bawah Satu Sisi
Confidence Level Z-score (One-Sided) Perhitungan Lower Bound (%)
90% 1.282 0.74 - (1.282 × 0.0277) 70.45%
95% 1.645 0.74 - (1.645 × 0.0277) 69.44%
99% 2.326 0.74 - (2.326 × 0.0277) 67.56%

5.3 Visualisasi Lower Bounds

5.4 Kesimpulan Target 70%

Berdasarkan hasil analisis, apakah target 70% terpenuhi secara statistik?

  • Pada Tingkat Kepercayaan 90%: Terpenuhi, karena batas bawah (70.45%) masih di atas target 70%.

  • Pada Tingkat Kepercayaan 95%: Tidak Terpenuhi secara ketat, karena batas bawah (69.44%) turun sedikit di bawah target 70%.

  • Pada Tingkat Kepercayaan 99%: Tidak Terpenuhi, karena batas bawah (67.56%) berada di bawah target.

Kesimpulan Akhir: Manajemen bisa merasa yakin sebesar 90% bahwa target tercapai, namun jika mereka membutuhkan tingkat keyakinan yang lebih tinggi (95% atau 99%), data saat ini belum cukup kuat untuk menjamin target 70% terpenuhi secara statistik.

LS0tDQp0aXRsZTogIlN0dWR5IENhc2VzIiAgICAgICAgICAgICMgTWFpbiB0aXRsZSBvZiB0aGUgZG9jdW1lbnQNCnN1YnRpdGxlOiAiQ29uZmlkZW5jZSBJbnRlcnZhbH4gV2VlayAxMyIgICMgU3VidGl0bGUgb3IgdG9waWMgZm9yIHdlZWsgMg0KYXV0aG9yOiAiTS4gRml0cmFoIEFpZGlsIEhhcmFoYXAiICAgICAgIyBSZXBsYWNlIHdpdGggeW91ciBmdWxsIG5hbWUNCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiICMgQXV0byBkaXNwbGF5cyB0aGUgY3VycmVudCBkYXRlDQpvdXRwdXQ6ICAgICAgICAgICAgICAgICAgICAgICAgICMgT3V0cHV0IHNlY3Rpb24gZGVmaW5lcyB0aGUgZm9ybWF0IGFuZCBsYXlvdXQgDQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOiAgICAgICMgaHR0cHM6Ly9naXRodWIuY29tL2p1YmEvcm1kZm9ybWF0cw0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlICAgICAgICAjIEVtYmVkcyBhbGwgcmVzb3VyY2VzIChDU1MsIEpTLCBpbWFnZXMpIA0KICAgIHRodW1ibmFpbHM6IHRydWUgICAgICAgICAgICAjIERpc3BsYXlzIGltYWdlIHRodW1ibmFpbHMgaW4gdGhlIGRvYw0KICAgIGxpZ2h0Ym94OiB0cnVlICAgICAgICAgICAgICAjIEVuYWJsZXMgY2xpY2sgdG8gZW5sYXJnZSBpbWFnZXMNCiAgICBnYWxsZXJ5OiB0cnVlICAgICAgICAgICAgICAgIyBHcm91cHMgaW1hZ2VzIGludG8gYW4gaW50ZXJhY3RpdmUgZ2FsbGVyeQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZSAgICAgICAjIEF1dG9tYXRpY2FsbHkgbnVtYmVycyBhbGwgc2VjdGlvbnMNCiAgICBsaWJfZGlyOiBsaWJzICAgICAgICAgICAgICAgIyBEaXJlY3Rvcnkgd2hlcmUgSmF2YVNjcmlwdC9DU1MgbGlicmFyaWVzDQogICAgZGZfcHJpbnQ6ICJwYWdlZCIgICAgICAgICAgICMgRGlzcGxheXMgZGF0YSBmcmFtZXMgYXMgaW50ZXJhY3RpdmUgcGFnZWQgDQogICAgY29kZV9mb2xkaW5nOiAic2hvdyIgICAgICAgICMgQWxsb3dzIGZvbGRpbmcvdW5mb2xkaW5nIFIgY29kZSBibG9ja3MgDQogICAgY29kZV9kb3dubG9hZDogeWVzICAgICAgICAgICMgQWRkcyBhIGJ1dHRvbiB0byBkb3dubG9hZCBhbGwgUiBjb2RlDQogICAgY3NzIDogc3R5bGUuY3NzDQotLS0NCg0KDQoNCmBgYHtyIHByb2ZpbGUsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGh0bWx0b29scykNCkhUTUwoJw0KPGRpdiBzdHlsZT0iZGlzcGxheTogZmxleDsgZ2FwOiAzMHB4OyBhbGlnbi1pdGVtczogY2VudGVyOyBiYWNrZ3JvdW5kOmxpbmVhci1ncmFkaWVudCgxMzVkZWcsICNmNWY3ZmEgMCUsICNjM2NmZTIgMTAwJSk7IHBhZGRpbmc6IDMwcHg7IGJvcmRlci1yYWRpdXM6IDE1cHg7IG1hcmdpbjogMjBweCAwOyI+DQogIDxkaXY+DQogICAgPGltZyBzcmM9IkM6L1VzZXJzL1NyaSBCdWRpeWFudGkvT25lRHJpdmUv44OJ44Kt44Ol44Oh44Oz44OIL0Rlc2t0b3AvRXNzZW50aWFsIG9mIFByb2JhYmlsaXR5L2ZvdG8gQWxtZXQucG5nIg0KIA0KICAgICAgICAgc3R5bGU9IndpZHRoOiAyNTBweDsgaGVpZ2h0OiAyNTBweDsgYm9yZGVyLXJhZGl1czogNTAlOyBvYmplY3QtZml0OiBjb3ZlcjsgYm9yZGVyOiA0cHggc29saWQgd2hpdGU7IGJveC1zaGFkb3c6IDAgNXB4IDE1cHggcmdiYSgwLDAsMCwwLjIpOyI+DQogIDwvZGl2Pg0KICA8ZGl2Pg0KICAgIDxoMSBzdHlsZT0iY29sb3I6ICMyYzNlNTA7IG1hcmdpbjogMDsiPk0uRml0cmFoIEFpZGlsIEhhcmFoYXA8L2gxPg0KICAgIDxwIHN0eWxlPSJjb2xvcjogIzdmOGM4ZDsgbWFyZ2luOiA1cHggMCAxNXB4IDA7Ij5TdHVkZW50IE1ham9yaW5nIGluIERhdGEgU2NpZW5jZTwvcD4NCiAgICANCiAgICA8ZGl2IHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBnYXA6IDE1cHg7IG1hcmdpbi10b3A6IDIwcHg7Ij4NCiAgICAgIDxidXR0b24gc3R5bGU9ImJhY2tncm91bmQ6ICMzNDk4ZGI7IGNvbG9yOiB3aGl0ZTsgcGFkZGluZzogMTBweCAyMHB4OyBib3JkZXI6IG5vbmU7IGJvcmRlci1yYWRpdXM6IDE1cHg7IGN1cnNvcjogcG9pbnRlcjsgZm9udC13ZWlnaHQ6IGJvbGQ7Ij4NCiAgICAgICAgUiBQcm9ncmFtbWluZw0KICAgICAgPC9idXR0b24+DQogICAgICA8YnV0dG9uIHN0eWxlPSJiYWNrZ3JvdW5kOiAjZTc0YzNjOyBjb2xvcjogd2hpdGU7IHBhZGRpbmc6IDEwcHggMjBweDsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiAxNXB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiBib2xkOyI+DQogICAgICAgIERhdGEgU2NpZW5jZQ0KICAgICAgPC9idXR0b24+DQogICAgICA8YnV0dG9uIHN0eWxlPSJiYWNrZ3JvdW5kOiAjMmVjYzcxOyBjb2xvcjogd2hpdGU7IHBhZGRpbmc6IDEwcHggMjBweDsgYm9yZGVyOiBub25lOyBib3JkZXItcmFkaXVzOiAxNXB4OyBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtd2VpZ2h0OiBib2xkOyI+DQogICAgICAgIFN0YXRpc3RpY3MNCiAgICAgIDwvYnV0dG9uPg0KICAgIDwvZGl2Pg0KICA8L2Rpdj4NCjwvZGl2Pg0KJykNCg0KYGBgDQoNCg0KLS0tDQoNCiMjIENhc2UgU3R1ZHkgMQ0KDQoqKkNvbmZpZGVuY2UgSW50ZXJ2YWwgZm9yIE1lYW4sICRcc2lnbWEkIEtub3duOioqIEFuICoqZS1jb21tZXJjZSBwbGF0Zm9ybSoqIHdhbnRzIHRvIGVzdGltYXRlIHRoZSAqKmF2ZXJhZ2UgbnVtYmVyIG9mIGRhaWx5IHRyYW5zYWN0aW9ucyBwZXIgdXNlcioqIGFmdGVyIGxhdW5jaGluZyBhIG5ldyBmZWF0dXJlLiBCYXNlZCBvbiBsYXJnZS1zY2FsZSBoaXN0b3JpY2FsIGRhdGEsIHRoZSAqKnBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uKiogaXMga25vd24uDQoNCiQkDQpcYmVnaW57ZXFuYXJyYXkqfQ0KXHNpZ21hICY9JiAzLjIgXHF1YWQgXHRleHR7KHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uKX0gXFwNCm4gJj0mIDEwMCBccXVhZCBcdGV4dHsoc2FtcGxlIHNpemUpfSBcXA0KXGJhcnt4fSAmPSYgMTIuNiBccXVhZCBcdGV4dHsoc2FtcGxlIG1lYW4pfQ0KXGVuZHtlcW5hcnJheSp9DQokJA0KDQoqKlRhc2tzKioNCg0KMS4gSWRlbnRpZnkgdGhlICoqYXBwcm9wcmlhdGUgc3RhdGlzdGljYWwgdGVzdCoqIGFuZCBqdXN0aWZ5IHlvdXIgY2hvaWNlLg0KMi4gQ29tcHV0ZSB0aGUgQ29uZmlkZW5jZSBJbnRlcnZhbHMgZm9yOg0KICAgLSAkOTBcJSQNCiAgIC0gJDk1XCUkDQogICAtICQ5OVwlJA0KMy4gQ3JlYXRlIGEgKipjb21wYXJpc29uIHZpc3VhbGl6YXRpb24qKiBvZiB0aGUgdGhyZWUgY29uZmlkZW5jZSBpbnRlcnZhbHMuDQo0LiBJbnRlcnByZXQgdGhlIHJlc3VsdHMgaW4gYSBidXNpbmVzcyBhbmFseXRpY3MgY29udGV4dC4NCg0KKipKQVdBQiA6ICoqIA0KDQojIyMgVWppIHN0YXRpc3RpayB5YW5nIHRlcGF0IHVudHVrIGRpZ3VuYWthbiBhZGFsYWggWi1UZXN0IChaLUludGVydmFsKSB1bnR1ayByYXRhLXJhdGEgcG9wdWxhc2kuDQoNCi0gKipTdGFuZGFyIERldmlhc2kgUG9wdWxhc2kgKCRcc2lnbWEkKSBEaWtldGFodWk6KiogU29hbCBzZWNhcmEgZWtzcGxpc2l0IG1lbnllYnV0a2FuICRcc2lnbWEgPSAzLjIkLiBKaWthICRcc2lnbWEkIHRpZGFrIGRpa2V0YWh1aSwga2l0YSBha2FuIG1lbmdndW5ha2FuIHQtdGVzdC4NCg0KLSAqKlVrdXJhbiBTYW1wZWwgQmVzYXI6KiogU2FtcGVsICgkbiA9IDEwMCQpIGphdWggbGViaWggYmVzYXIgZGFyaSAzMCAoJG4gPiAzMCQpLCBzZWhpbmdnYSBtZW51cnV0IFRlb3JlbWEgTGltaXQgUHVzYXQsIGRpc3RyaWJ1c2kgcmF0YS1yYXRhIHNhbXBlbCBha2FuIG1lbmRla2F0aSBkaXN0cmlidXNpIG5vcm1hbC4NCg0KIyMjIFBlcmhpdHVuZ2FuIENvbmZpZGVuY2UgSW50ZXJ2YWxzIChDSSkNCg0KUnVtdXMgdW11bSBDb25maWRlbmNlIEludGVydmFsIGFkYWxhaDoNCiQkXGJhcnt4fSBccG0geiBcY2RvdCBcbGVmdCggXGZyYWN7XHNpZ21hfXtcc3FydHtufX0gXHJpZ2h0KSQkDQpEaSBtYW5hIFN0YW5kYXJkIEVycm9yICgkU0UkKSBhZGFsYWg6IA0KJFNFID0gXGZyYWN7My4yfXtcc3FydHsxMDB9fSA9IDAuMzIkLg0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBNZW1idWF0IGRhdGEgc2VkZXJoYW5hDQpDb25maWRlbmNlX0xldmVsIDwtIGMoIjkwJSIsICI5NSUiLCAiOTklIikNClpfS3JpdGlzIDwtIGMoMS42NDUsIDEuOTYwLCAyLjU3NikNCk1hcmdpbl9FcnJvciA8LSBjKDAuNTI2LCAwLjYyNywgMC44MjQpDQpMb3dlciA8LSBjKDEyLjA3NCwgMTEuOTczLCAxMS43NzYpDQpVcHBlciA8LSBjKDEzLjEyNiwgMTMuMjI3LCAxMy40MjQpDQoNCmRmIDwtIGRhdGEuZnJhbWUoQ29uZmlkZW5jZV9MZXZlbCwgWl9Lcml0aXMsIE1hcmdpbl9FcnJvciwgTG93ZXIsIFVwcGVyKQ0KDQojIE1lbmFtcGlsa2FuIHRhYmVsIHN0YW5kYXINCmtuaXRyOjprYWJsZShkZiwgY2FwdGlvbiA9ICJEYXRhIERpc3RyaWJ1c2kgWiIpDQoNCg0KYGBgDQoNCiMjIyBWaXN1YWxpc2FzaSBQZXJiYW5kaW5nYW4gDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIExvYWQgbGlicmFyeQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIElucHV0IGRhdGENCmRhdGFfY2kgPC0gZGF0YS5mcmFtZSgNCiAgbGV2ZWwgPSBmYWN0b3IoYygiOTAlIiwgIjk1JSIsICI5OSUiKSwgbGV2ZWxzID0gYygiOTklIiwgIjk1JSIsICI5MCUiKSksDQogIG1lYW4gPSBjKDEyLjYsIDEyLjYsIDEyLjYpLA0KICBsb3dlciA9IGMoMTIuMDc0LCAxMS45NzMsIDExLjc3NiksDQogIHVwcGVyID0gYygxMy4xMjYsIDEzLjIyNywgMTMuNDI0KQ0KKQ0KDQojIE1lbWJ1YXQgUGxvdA0KZ2dwbG90KGRhdGFfY2ksIGFlcyh4ID0gbGV2ZWwsIHkgPSBtZWFuKSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbG93ZXIsIHltYXggPSB1cHBlciwgY29sb3IgPSBsZXZlbCksIHdpZHRoID0gMC4zLCBzaXplID0gMS4yKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGNvbG9yID0gImJsYWNrIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIlBlcmJhbmRpbmdhbiBDb25maWRlbmNlIEludGVydmFscyIsDQogICAgICAgc3VidGl0bGUgPSAiUmF0YS1yYXRhIFRyYW5zYWtzaSBIYXJpYW4gKE1lYW4gPSAxMi42KSIsDQogICAgICAgeCA9ICJUaW5na2F0IEtlcGVyY2F5YWFuIiwNCiAgICAgICB5ID0gIkp1bWxhaCBUcmFuc2Frc2kiLA0KICAgICAgIGNvbG9yID0gIkNJIExldmVsIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQoNCiMjIyBJbnRlcnByZXRhc2kgZGFsYW0gS29udGVrcyBCdXNpbmVzcyBBbmFseXRpY3MNCg0KLSAqKktlcGFzdGlhbiBQcmVzaXNpOioqIFNlbWFraW4gdGluZ2dpIHRpbmdrYXQga2VwZXJjYXlhYW4gKDk5JSksIHNlbWFraW4gbGViYXIgcmVudGFuZ255YS4gU2VjYXJhIGJpc25pcywgamlrYSBraXRhIGluZ2luIHNhbmdhdCB5YWtpbiAoOTklKSBiYWh3YSBwcmVkaWtzaSBraXRhIGJlbmFyLCBraXRhIGhhcnVzIG1lbmVyaW1hIHJlbnRhbmcgeWFuZyBsZWJpaCBsdWFzICgxMS43OCBoaW5nZ2EgMTMuNDIgdHJhbnNha3NpKS4gU2ViYWxpa255YSwgcGFkYSA5MCUsIHJlbnRhbmdueWEgbGViaWggc2VtcGl0IChwcmVzaXNpIGxlYmloIHRpbmdnaSksIG5hbXVuIHJpc2lrbyBtZWxlc2V0bnlhIGxlYmloIGJlc2FyLg0KDQotICoqRWZla3Rpdml0YXMgRml0dXIgQmFydToqKiBNYW5hamVtZW4gZS1jb21tZXJjZSBkYXBhdCBtZW55aW1wdWxrYW4gZGVuZ2FuIGtleWFraW5hbiA5NSUgYmFod2EgcmF0YS1yYXRhIHRyYW5zYWtzaSBoYXJpYW4gcGVyIHVzZXIgc2V0ZWxhaCBwZWx1bmN1cmFuIGZpdHVyIGJhcnUgYmVyYWRhIGRpIGFudGFyYSAxMS45NyBoaW5nZ2EgMTMuMjMuIEFuZ2thIGluaSBiaXNhIGRpYmFuZGluZ2thbiBkZW5nYW4gZGF0YSBoaXN0b3JpcyBzZWJlbHVtIGZpdHVyIGRpbHVuY3Vya2FuIHVudHVrIG1lbmd1a3VyIGtlc3Vrc2VzYW4gS1BJLg0KDQotICoqUGVuZ2FtYmlsYW4gS2VwdXR1c2FuOioqIFJlbnRhbmcgaW5pIG1lbWJlcmlrYW4gImJhdGFzIGFtYW4iIGJhZ2kgdGltIG9wZXJhc2lvbmFsIHVudHVrIG1lbXByb3lla3Npa2FuIGJlYmFuIHNlcnZlciBhdGF1IHBlbmRhcGF0YW4gaGFyaWFuIHRhbnBhIGhhbnlhIG1lbmdhbmRhbGthbiBzYXR1IGFuZ2thIHJhdGEtcmF0YSB0dW5nZ2FsIHlhbmcgbXVuZ2tpbiBmbHVrdHVhdGlmLg0KDQotLS0NCg0KIyMgQ2FzZSBTdHVkeSAyIA0KDQoqKkNvbmZpZGVuY2UgSW50ZXJ2YWwgZm9yIE1lYW4sICRcc2lnbWEkIFVua25vd246KiogQSAqKlVYIFJlc2VhcmNoIHRlYW0qKiBhbmFseXplcyAqKnRhc2sgY29tcGxldGlvbiB0aW1lIChpbiBtaW51dGVzKSoqIGZvciBhIG5ldyBtb2JpbGUgYXBwbGljYXRpb24uIFRoZSBkYXRhIGFyZSBjb2xsZWN0ZWQgZnJvbSAqKjEyIHVzZXJzKio6DQoNCiQkDQo4LjQsXDsgNy45LFw7IDkuMSxcOyA4LjcsXDsgOC4yLFw7IDkuMCxcOw0KNy44LFw7IDguNSxcOyA4LjksXDsgOC4xLFw7IDguNixcOyA4LjMNCiQkDQoNCioqVGFza3M6KioNCg0KMS4gSWRlbnRpZnkgdGhlICoqYXBwcm9wcmlhdGUgc3RhdGlzdGljYWwgdGVzdCoqIGFuZCBleHBsYWluIHdoeS4NCjIuIENvbXB1dGUgdGhlIENvbmZpZGVuY2UgSW50ZXJ2YWxzIGZvcjoNCiAgIC0gJDkwXCUkDQogICAtICQ5NVwlJA0KICAgLSAkOTlcJSQNCjMuIFZpc3VhbGl6ZSB0aGUgdGhyZWUgaW50ZXJ2YWxzIG9uIGEgc2luZ2xlIHBsb3QuDQo0LiBFeHBsYWluIGhvdyAqKnNhbXBsZSBzaXplIGFuZCBjb25maWRlbmNlIGxldmVsKiogaW5mbHVlbmNlIHRoZSBpbnRlcnZhbCB3aWR0aC4NCg0KKipKQVdBQiA6KiogDQoNCiMjIyBJZGVudGlmaWthc2kgVWppIFN0YXRpc3Rpaw0KVWppIHN0YXRpc3RpayB5YW5nIHRlcGF0IGFkYWxhaCBPbmUtU2FtcGxlIHQtdGVzdCAodC1pbnRlcnZhbCkuDQoNCi0gKipTdGFuZGFyIERldmlhc2kgUG9wdWxhc2kgKCRcc2lnbWEkKSBUaWRhayBEaWtldGFodWk6KiogS2l0YSBoYW55YSBtZW1pbGlraSBkYXRhIHNhbXBlbCwgc2VoaW5nZ2EgaGFydXMgbWVuZ2d1bmFrYW4gc3RhbmRhciBkZXZpYXNpIHNhbXBlbCAoJHMkKS4NCg0KLSAqKlVrdXJhbiBTYW1wZWwgS2VjaWw6KiogSnVtbGFoIHNhbXBlbCBoYW55YSAkbiA9IDEyJCAoJG4gPCAzMCQpLiBEYWxhbSBrb25kaXNpIGluaSwgZGlzdHJpYnVzaS0kdCQgbGViaWggYWt1cmF0IGRhcmlwYWRhIGRpc3RyaWJ1c2ktJHokIHVudHVrIG1lbmdha29tb2Rhc2kga2V0aWRha3Bhc3RpYW4gZWtzdHJhIGRhcmkgc2FtcGVsIGtlY2lsLg0KDQojIyMgIFBlcmhpdHVuZ2FuIENvbmZpZGVuY2UgSW50ZXJ2YWxzIERhdGE6DQoNCiQ4LjQsIDcuOSwgOS4xLCA4LjcsIDguMiwgOS4wLCA3LjgsIDguNSwgOC45LCA4LjEsIDguNiwgOC4zJA0KDQotICoqTWVhbiBTYW1wZWwgKCRcYmFye3h9JCk6KiogJDguNDU4JA0KDQotICoqU3RhbmRhciBEZXZpYXNpIFNhbXBlbCAoJHMkKToqKiAkMC40MTIkDQoNCi0gKipEZWdyZWVzIG9mIEZyZWVkb20gKCRkZiQpOioqICRuIC0gMSA9IDExJA0KDQpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBEYXRhIGRhcmkgR2FtYmFyIDINCmRhdGFfdCA8LSBkYXRhLmZyYW1lKA0KICAiQ29uZmlkZW5jZSBMZXZlbCIgPSBjKCI5MCUiLCAiOTUlIiwgIjk5JSIpLA0KICAidC1zY29yZSAoZGY9MTEpIiA9IGMoMS43OTYsIDIuMjAxLCAzLjEwNiksDQogICJNYXJnaW4gb2YgRXJyb3IiID0gYygwLjIxNCwgMC4yNjIsIDAuMzY5KSwNCiAgIkxvd2VyIEJvdW5kIiA9IGMoOC4yNDQsIDguMTk2LCA4LjA4OSksDQogICJVcHBlciBCb3VuZCIgPSBjKDguNjcyLCA4LjE5NiwgOC44MjcpLA0KICBjaGVjay5uYW1lcyA9IEZBTFNFDQopDQoNCmtuaXRyOjprYWJsZShkYXRhX3QsIGFsaWduID0gImMiLCBjYXB0aW9uID0gIkhhc2lsIEVzdGltYXNpIERpc3RyaWJ1c2kgVCIpDQoNCmBgYA0KDQojIyMgVmlzdWFsaXNhc2kgUGVyYmFuZGluZ2FuIA0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgMS4gRGF0YSBJbnB1dA0Kd2FrdHVfdHVnYXMgPC0gYyg4LjQsIDcuOSwgOS4xLCA4LjcsIDguMiwgOS4wLCA3LjgsIDguNSwgOC45LCA4LjEsIDguNiwgOC4zKQ0KbiA8LSBsZW5ndGgod2FrdHVfdHVnYXMpDQptZWFuX3ggPC0gbWVhbih3YWt0dV90dWdhcykNCnNkX3ggPC0gc2Qod2FrdHVfdHVnYXMpDQpzZSA8LSBzZF94IC8gc3FydChuKQ0KDQojIDIuIEZ1bmdzaSB1bnR1ayBtZW5naGl0dW5nIENJDQpjYWxjX2NpIDwtIGZ1bmN0aW9uKGxldmVsKSB7DQogIGFscGhhIDwtIDEgLSBsZXZlbA0KICB0X3Njb3JlIDwtIHF0KDEgLSBhbHBoYS8yLCBkZiA9IG4gLSAxKQ0KICBtb2UgPC0gdF9zY29yZSAqIHNlDQogIHJldHVybihjKGxvd2VyID0gbWVhbl94IC0gbW9lLCB1cHBlciA9IG1lYW5feCArIG1vZSkpDQp9DQoNCiMgMy4gTWVtYnVhdCBEYXRhIEZyYW1lIHVudHVrIFBsb3QNCmxldmVscyA8LSBjKDAuOTAsIDAuOTUsIDAuOTkpDQpjaV9yZXN1bHRzIDwtIHQoc2FwcGx5KGxldmVscywgY2FsY19jaSkpDQpkZl9wbG90IDwtIGRhdGEuZnJhbWUoDQogIENvbmZpZGVuY2UgPSBmYWN0b3IoYygiOTAlIiwgIjk1JSIsICI5OSUiKSksDQogIE1lYW4gPSBtZWFuX3gsDQogIExvd2VyID0gY2lfcmVzdWx0c1ssMV0sDQogIFVwcGVyID0gY2lfcmVzdWx0c1ssMl0NCikNCg0KIyA0LiBWaXN1YWxpc2FzaSBkZW5nYW4gZ2dwbG90Mg0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRmX3Bsb3QsIGFlcyh4ID0gQ29uZmlkZW5jZSwgeSA9IE1lYW4pKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBMb3dlciwgeW1heCA9IFVwcGVyLCBjb2xvciA9IENvbmZpZGVuY2UpLCB3aWR0aCA9IDAuMywgc2l6ZSA9IDEuMikgKw0KICBnZW9tX3BvaW50KHNpemUgPSA0KSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiVVggUmVzZWFyY2g6IFRhc2sgQ29tcGxldGlvbiBUaW1lIENvbmZpZGVuY2UgSW50ZXJ2YWxzIiwNCiAgICAgICBzdWJ0aXRsZSA9IHBhc3RlKCJTYW1wbGUgU2l6ZSAobikgPSIsIG4sICJ8IE1lYW4gPSIsIHJvdW5kKG1lYW5feCwgMykpLA0KICAgICAgIHkgPSAiV2FrdHUgKE1lbml0KSIsIHggPSAiQ29uZmlkZW5jZSBMZXZlbCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCg0KYGBgDQoNCiMjIyBQZW5nYXJ1aCBVa3VyYW4gU2FtcGVsIGRhbiBDb25maWRlbmNlIExldmVsDQoNCi0gKipDb25maWRlbmNlIExldmVsOioqIFNlbWFraW4gdGluZ2dpIHRpbmdrYXQga2VwZXJjYXlhYW4gKG1pc2FsIGRhcmkgOTAlIGtlIDk5JSksIHNlbWFraW4gbGViYXIgaW50ZXJ2YWxueWEuIEhhbCBpbmkga2FyZW5hIGtpdGEgbWVtYnV0dWhrYW4gcmVudGFuZyB5YW5nIGxlYmloIGx1YXMgYWdhciBsZWJpaCB5YWtpbiBiYWh3YSBwYXJhbWV0ZXIgcG9wdWxhc2kgYmVuYXItYmVuYXIgYWRhIGRpIGRhbGFtbnlhLg0KDQotICoqU2FtcGxlIFNpemUgKCRuJCk6KiogU2VtYWtpbiBiZXNhciB1a3VyYW4gc2FtcGVsLCBzZW1ha2luIHNlbXBpdCBpbnRlcnZhbG55YS4gU2VjYXJhIG1hdGVtYXRpcywgJG4kIGJlcmFkYSBkaSBwZW55ZWJ1dCBkYWxhbSBydW11cyBTdGFuZGFyZCBFcnJvciAoJHMvXHNxcnR7bn0kKS4gU2FtcGVsIHlhbmcgbGViaWggYmVzYXIgbWVuZ3VyYW5naSB2YXJpYWJpbGl0YXMgZXN0aW1hc2ksIHNlaGluZ2dhIG1lbmdoYXNpbGthbiBwcmVzaXNpIHlhbmcgbGViaWggdGluZ2dpLg0KDQotLS0NCg0KIyMgQ2FzZSBTdHVkeSAzIA0KDQoqKkNvbmZpZGVuY2UgSW50ZXJ2YWwgZm9yIGEgUHJvcG9ydGlvbiwgQS9CIFRlc3Rpbmc6KiogQSBkYXRhIHNjaWVuY2UgdGVhbSBydW5zIGFuICoqQS9CIHRlc3QqKiBvbiBhIG5ldyAqQ2FsbC1Uby1BY3Rpb24gKENUQSkqIGJ1dHRvbiBkZXNpZ24uIFRoZSBleHBlcmltZW50IHlpZWxkczoNCg0KJCQNClxiZWdpbntlcW5hcnJheSp9DQpuICY9JiA0MDAgXHF1YWQgXHRleHR7KHRvdGFsIHVzZXJzKX0gXFwNCnggJj0mIDE1NiBccXVhZCBcdGV4dHsodXNlcnMgd2hvIGNsaWNrZWQgdGhlIENUQSl9DQpcZW5ke2VxbmFycmF5Kn0NCiQkDQoNCioqVGFza3M6KioNCg0KMS4gQ29tcHV0ZSB0aGUgKipzYW1wbGUgcHJvcG9ydGlvbioqICRcaGF0e3B9JC4NCjIuIENvbXB1dGUgQ29uZmlkZW5jZSBJbnRlcnZhbHMgZm9yIHRoZSBwcm9wb3J0aW9uIGF0Og0KICAgLSAkOTBcJSQNCiAgIC0gJDk1XCUkDQogICAtICQ5OVwlJA0KMy4gVmlzdWFsaXplIGFuZCBjb21wYXJlIHRoZSB0aHJlZSBpbnRlcnZhbHMuDQo0LiBFeHBsYWluIGhvdyBjb25maWRlbmNlIGxldmVsIGFmZmVjdHMgZGVjaXNpb24tbWFraW5nIGluIHByb2R1Y3QgZXhwZXJpbWVudHMuDQoNCioqSkFXQUIgOioqIA0KDQojIyMgSGl0dW5nIFByb3BvcnNpIFNhbXBlbCgkXGhhdHtwfSQpDQoNCkJlcmRhc2Fya2FuIGRhdGEgZWtzcGVyaW1lbjoNCg0KLSBUb3RhbCBwZW5nZ3VuYSAoJG4kKSA9IDQwMA0KLSBQZW5nZ3VuYSB5YW5nIG1lbmdrbGlrIENUQSAoJHgkKSA9IDE1Ng0KDQokJFxoYXR7cH0gPSBcZnJhY3t4fXtufSA9IFxmcmFjezE1Nn17NDAwfSA9IDAuMzkkJA0KSmFkaSwgcHJvcG9yc2kgc2FtcGVsbnlhIGFkYWxhaCAwLjM5IGF0YXUgMzklLg0KDQojIyMgSGl0dW5nIENvbmZpZGVuY2UgSW50ZXJ2YWxzIHVudHVrIFByb3BvcnNpDQpSdW11cyB5YW5nIGRpZ3VuYWthbiBhZGFsYWg6IA0KJFxoYXR7cH0gXHBtIHogXGNkb3QgXHNxcnR7XGZyYWN7XGhhdHtwfSgxLVxoYXR7cH0pfXtufX0kDQpEaSBtYW5hIFN0YW5kYXJkIEVycm9yICgkU0UkKSBhZGFsYWg6ICRcc3FydHtcZnJhY3swLjM5IFxjZG90IDAuNjF9ezQwMH19IFxhcHByb3ggMC4wMjQzOSQNCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgSW5zdGFsbCBwYWtldCBqaWthIGJlbHVtIGFkYQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQojIGluc3RhbGwucGFja2FnZXMoImthYmxlRXh0cmEiKQ0KDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQojIE1lbWJ1YXQgZGF0YQ0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBgQ29uZmlkZW5jZSBMZXZlbGAgPSBjKCI5MCUiLCAiOTUlIiwgIjk5JSIpLA0KICBgTmlsYWkgS3JpdGlzICh6KWAgPSBjKDEuNjQ1LCAxLjk2MCwgMi41NzYpLA0KICBgTWFyZ2luIG9mIEVycm9yYCA9IGMoMC4wNDAxLCAwLjA0NzgsIDAuMDYyOCksDQogIGBMb3dlciBCb3VuZGAgPSBjKDAuMzQ5OSwgMC4zNDIyLCAwLjMyNzIpLA0KICBgVXBwZXIgQm91bmRgID0gYygwLjQzMDEsIDAuNDM3OCwgIjAuNDUyOCoiKQ0KKQ0KDQojIE1lbWJ1YXQgdGFiZWwgYmVyZ2F5YSBwcm9mZXNpb25hbA0Ka2FibGUoZGF0YSwgYWxpZ24gPSAibGNjY2MiLCBjYXB0aW9uID0gIlRhYmVsIEludGVydmFsIEtlcGVyY2F5YWFuIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCANCiAgICAgICAgICAgICAgICBmdWxsX3dpZHRoID0gRikNCg0KYGBgDQoNCiMjIyBWaXN1YWxpc2FzaSBQZXJiYW5kaW5nYW4gDQpgYGAge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgMS4gUGVyc2lhcGFuIERhdGENCm4gPC0gNDAwDQp4IDwtIDE1Ng0KcF9oYXQgPC0geCAvIG4NCnNlIDwtIHNxcnQoKHBfaGF0ICogKDEgLSBwX2hhdCkpIC8gbikNCg0KbGV2ZWxzIDwtIGMoMC45MCwgMC45NSwgMC45OSkNCnpfc2NvcmVzIDwtIGMoMS42NDUsIDEuOTYwLCAyLjU3NikNCm1vZSA8LSB6X3Njb3JlcyAqIHNlDQoNCmRmX3Byb3BvcnRpb24gPC0gZGF0YS5mcmFtZSgNCiAgQ29uZmlkZW5jZSA9IGZhY3RvcihjKCI5MCUiLCAiOTUlIiwgIjk5JSIpLCBsZXZlbHMgPSBjKCI5OSUiLCAiOTUlIiwgIjkwJSIpKSwNCiAgTG93ZXIgPSBwX2hhdCAtIG1vZSwNCiAgVXBwZXIgPSBwX2hhdCArIG1vZSwNCiAgTWVhbiA9IHBfaGF0DQopDQoNCiMgMi4gVmlzdWFsaXNhc2kgZGVuZ2FuIGdncGxvdDINCmxpYnJhcnkoZ2dwbG90MikNCmdncGxvdChkZl9wcm9wb3J0aW9uLCBhZXMoeCA9IENvbmZpZGVuY2UsIHkgPSBNZWFuKSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTG93ZXIsIHltYXggPSBVcHBlciwgY29sb3IgPSBDb25maWRlbmNlKSwgd2lkdGggPSAwLjMsIHNpemUgPSAxLjIpICsNCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKw0KICBjb29yZF9mbGlwKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGxhYnModGl0bGUgPSAiQ29uZmlkZW5jZSBJbnRlcnZhbHMgZm9yIENUQSBDbGljayBQcm9wb3J0aW9uIiwNCiAgICAgICBzdWJ0aXRsZSA9IHBhc3RlKCJTYW1wbGUgUHJvcG9ydGlvbiA9IiwgcF9oYXQgKiAxMDAsICIlIHwgbiA9IDQwMCIpLA0KICAgICAgIHkgPSAiUHJvcG9yc2kgS2xpayAoJSkiLCB4ID0gIlRpbmdrYXQgS2VwZXJjYXlhYW4iKSArDQogIHRoZW1lX21pbmltYWwoKQ0KICAgDQoNCg0KYGBgDQoNCiMjIyBQZW5nYXJ1aCBDb25maWRlbmNlIExldmVsIGRhbGFtIFBlbmdhbWJpbGFuIEtlcHV0dXNhbiBQcm9kdWsNCkRhbGFtIGtvbnRla3MgZWtzcGVyaW1lbiBwcm9kdWsgKEEvQiBUZXN0aW5nKSwgdGluZ2thdCBrZXBlcmNheWFhbiBzYW5nYXQgbWVtcGVuZ2FydWhpIGtlcHV0dXNhbjoNCg0KLSAqKlRvbGVyYW5zaSBSaXNpa286KiogVGluZ2thdCBrZXBlcmNheWFhbiA5NSUgYWRhbGFoIHN0YW5kYXIgaW5kdXN0cmkuIEppa2Ega2l0YSBtZW5nZ3VuYWthbiA5OSUsIGtpdGEgbWVuamFkaSBzYW5nYXQga29uc2VydmF0aWbigJRraXRhIGJ1dHVoIGJ1a3RpIHlhbmcgc2FuZ2F0IGt1YXQgc2ViZWx1bSBtZW55YXRha2FuIHN1YXR1IGRlc2FpbiBDVEEgbGViaWggYmFpay4gSW5pIG1lbmd1cmFuZ2kgcmlzaWtvIEZhbHNlIFBvc2l0aXZlIChtZW55YXRha2FuIGFkYSBlZmVrIHBhZGFoYWwgdGlkYWsgYWRhKS4NCg0KLSAqKktlY2VwYXRhbiB2cyBLZXBhc3RpYW46KiogVGluZ2thdCBrZXBlcmNheWFhbiA5MCUgbWVuZ2hhc2lsa2FuIGludGVydmFsIHlhbmcgbGViaWggc2VtcGl0LCB5YW5nIG1lbXVuZ2tpbmthbiBwZW5nYW1iaWxhbiBrZXB1dHVzYW4gbGViaWggY2VwYXQgZGVuZ2FuIGRhdGEgeWFuZyBsZWJpaCBzZWRpa2l0LCBuYW11biBkZW5nYW4gcmlzaWtvIGtlc2FsYWhhbiB5YW5nIGxlYmloIHRpbmdnaSAoMTAlKS4NCg0KLSAqKkFwbGlrYXNpIFByYWt0aXM6KiogSmlrYSBpbnRlcnZhbCBrZXBlcmNheWFhbiB1bnR1ayBkZXNhaW4gYmFydSB0aWRhayB0dW1wYW5nIHRpbmRpaCAob3ZlcmxhcCkgZGVuZ2FuIHBlcmZvcm1hIGRlc2FpbiBsYW1hLCB0aW0gcHJvZHVrIGRhcGF0IGRlbmdhbiBwZXJjYXlhIGRpcmkgbWVsdW5jdXJrYW4gZml0dXIgdGVyc2VidXQuIFNlbWFraW4gdGluZ2dpIHRpbmdrYXQga2VwZXJjYXlhYW4sIHNlbWFraW4gYmVzYXIga2V5YWtpbmFuIGJpc25pcyBiYWh3YSBwZW5pbmdrYXRhbiBtZXRyaWsgYnVrYW4gdGVyamFkaSBrYXJlbmEga2ViZXR1bGFuLg0KDQoNCiMjIENhc2UgU3R1ZHkgNCANCg0KKipQcmVjaXNpb24gQ29tcGFyaXNvbiAoWi1UZXN0IHZzIHQtVGVzdCk6KiogVHdvIGRhdGEgdGVhbXMgbWVhc3VyZSAqKkFQSSBsYXRlbmN5IChpbiBtaWxsaXNlY29uZHMpKiogdW5kZXIgZGlmZmVyZW50IGNvbmRpdGlvbnMuDQoNClxiZWdpbntlcW5hcnJheSp9DQpcdGV4dHtUZWFtIEE6fSBcXA0KbiAmPSYgMzYgXHF1YWQgXHRleHR7KHNhbXBsZSBzaXplKX0gXFwNClxiYXJ7eH0gJj0mIDIxMCBccXVhZCBcdGV4dHsoc2FtcGxlIG1lYW4pfSBcXA0KXHNpZ21hICY9JiAyNCBccXVhZCBcdGV4dHsoa25vd24gcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24pfSBcXFs2cHRdDQoNClx0ZXh0e1RlYW0gQjp9IFxcDQpuICY9JiAzNiBccXVhZCBcdGV4dHsoc2FtcGxlIHNpemUpfSBcXA0KXGJhcnt4fSAmPSYgMjEwIFxxdWFkIFx0ZXh0eyhzYW1wbGUgbWVhbil9IFxcDQpzICY9JiAyNCBccXVhZCBcdGV4dHsoc2FtcGxlIHN0YW5kYXJkIGRldmlhdGlvbil9DQpcZW5ke2VxbmFycmF5Kn0NCg0KKipUYXNrcyoqDQoNCjEuIElkZW50aWZ5IHRoZSBzdGF0aXN0aWNhbCB0ZXN0IHVzZWQgYnkgZWFjaCB0ZWFtLg0KMi4gQ29tcHV0ZSBDb25maWRlbmNlIEludGVydmFscyBmb3IgKio5MCUsIDk1JSwgYW5kIDk5JSoqLg0KMy4gQ3JlYXRlIGEgdmlzdWFsaXphdGlvbiBjb21wYXJpbmcgYWxsIGludGVydmFscy4NCjQuIEV4cGxhaW4gd2h5IHRoZSAqKmludGVydmFsIHdpZHRocyBkaWZmZXIqKiwgZXZlbiB3aXRoIHNpbWlsYXIgZGF0YS4NCg0KDQoqKkpBV0FCOioqDQoNCiMjIyBJZGVudGlmaWthc2kgVWppIFN0YXRpc3Rpaw0KS2VkdWEgdGltIG1lbWlsaWtpIHVrdXJhbiBzYW1wZWwgeWFuZyBzYW1hICgkbiA9IDM2JCksIG5hbXVuIHBlcmJlZGFhbiB0ZXJsZXRhayBwYWRhIGluZm9ybWFzaSBzdGFuZGFyIGRldmlhc2kgeWFuZyB0ZXJzZWRpYToNCg0KLSAqKlRlYW0gQSAoWi1UZXN0KToqKiBNZW5nZ3VuYWthbiBaLVRlc3Qga2FyZW5hIHN0YW5kYXIgZGV2aWFzaSBwb3B1bGFzaSAoJFxzaWdtYSQpIGRpa2V0YWh1aS4NCg0KLSAqKlRlYW0gQiAodC1UZXN0KToqKiBNZW5nZ3VuYWthbiB0LVRlc3Qga2FyZW5hIHN0YW5kYXIgZGV2aWFzaSBwb3B1bGFzaSB0aWRhayBkaWtldGFodWksIHNlaGluZ2dhIG1lbmdndW5ha2FuIHN0YW5kYXIgZGV2aWFzaSBzYW1wZWwgKCRzJCkuDQoNCiMjIyBQZXJoaXR1bmdhbiBDb25maWRlbmNlIEludGVydmFsIChDSSkNClJ1bXVzIHVtdW06ICRcYmFye3h9IFxwbSAoXHRleHR7Q3JpdGljYWwgVmFsdWV9IFx0aW1lcyBcZnJhY3tcdGV4dHtzdGQgZGV2fX17XHNxcnR7bn19KSQNCkRlbmdhbiBTdGFuZGFyZCBFcnJvciAoJFNFJCkgPSAkXGZyYWN7MjR9e1xzcXJ0ezM2fX0gPSA0JC4NCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgTWVtYnVhdCBkYXRhIGZyYW1lDQp0ZWFtX2FfZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBgQ29uZmlkZW5jZSBMZXZlbGAgPSBjKCI5MCUiLCAiOTUlIiwgIjk5JSIpLA0KICBgTmlsYWkgS3JpdGlzICh6KilgID0gYygxLjY0NSwgMS45NjAsIDIuNTc2KSwNCiAgYFBlcmhpdHVuZ2FuICh6KiB4IDQpYCA9IGMoNi41OCwgNy44NCwgMTAuMzApLA0KICBgTG93ZXIgQm91bmQgKG1zKWAgPSBjKDIwMy40MiwgMjAyLjE2LCAxOTkuNzApLA0KICBgVXBwZXIgQm91bmQgKG1zKWAgPSBjKDIxNi41OCwgMjE3Ljg0LCAyMjAuMzApDQopDQoNCiMgTWVuYW1waWxrYW4gdGFiZWwgYWdhciBtdW5jdWwgZGkgUlB1YnMNCmthYmxlKHRlYW1fYV9kYXRhLCBhbGlnbiA9ICJjIiwgY2FwdGlvbiA9ICJUYWJlbCBJbnRlcnZhbCBLZXBlcmNheWFhbiBUZWFtIEEiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiLCAiY29uZGVuc2VkIiwgInJlc3BvbnNpdmUiKSwgDQogICAgICAgICAgICAgICAgZnVsbF93aWR0aCA9IEYsIA0KICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gImNlbnRlciIpDQoNCg0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIE1lbWJ1YXQgZGF0YSBmcmFtZSBUZWFtIEINCnRlYW1fYiA8LSBkYXRhLmZyYW1lKA0KICBDb25maWRlbmNlX0xldmVsID0gYygiOTAlIiwgIjk1JSIsICI5OSUiKSwNCiAgQ3JpdGljYWxfVmFsdWUgPSBjKDEuNjg5LCAyLjAzMCwgMi43MjQpLA0KICBDYWxjdWxhdGlvbiA9IGMoIjIxMCDCsSA2Ljc2IiwgIjIxMCDCsSA4LjEyIiwgIjIxMCDCsSAxMC45MCIpLA0KICBMb3dlcl9Cb3VuZCA9IGMoMjAzLjI0LCAyMDEuODgsIDE5OS4xMCksDQogIFVwcGVyX0JvdW5kID0gYygyMTYuNzYsIDIxOC4xMiwgMjIwLjkwKQ0KKQ0KDQojIE1lbmFtcGlsa2FuIHRhYmVsIEhUTUwgeWFuZyBrb21wYXRpYmVsIGRlbmdhbiBSUHVicw0Ka2FibGUodGVhbV9iLCBjb2wubmFtZXMgPSBjKCJDb25maWRlbmNlIExldmVsIiwgInQtc2NvcmUgKHQqKSIsICJQZXJoaXR1bmdhbiIsICJMb3dlciBCb3VuZCIsICJVcHBlciBCb3VuZCIpLA0KICAgICAgYWxpZ24gPSAiYyIsIGNhcHRpb24gPSAiVGFiZWwgSW50ZXJ2YWwgS2VwZXJjYXlhYW4gVGVhbSBCIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmdWxsX3dpZHRoID0gRikNCg0KYGBgDQoNCiMjIyBWaXN1YWxpc2FzaSBQZXJiYW5kaW5nYW4gDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIDEuIFBhcmFtZXRlciBEYXRhDQpuIDwtIDM2DQptZWFuX3ZhbCA8LSAyMTANCnNkX3ZhbCA8LSAyNA0Kc2UgPC0gc2RfdmFsIC8gc3FydChuKSANCmRmIDwtIG4gLSAxDQpjb25mX2xldmVscyA8LSBjKDAuOTAsIDAuOTUsIDAuOTkpDQoNCiMgMi4gTWVtYnVhdCBEYXRhIEZyYW1lIFBlcmhpdHVuZ2FuDQpwbG90X2RhdGEgPC0gZGF0YS5mcmFtZSgpDQoNCmZvciAoY2wgaW4gY29uZl9sZXZlbHMpIHsNCiAgIyBUZWFtIEEgKFotVGVzdCkNCiAgel9jcml0IDwtIHFub3JtKDEgLSAoMSAtIGNsKSAvIDIpDQogIG1vZV96IDwtIHpfY3JpdCAqIHNlDQogIHBsb3RfZGF0YSA8LSByYmluZChwbG90X2RhdGEsIGRhdGEuZnJhbWUoDQogICAgVGVhbSA9ICJUZWFtIEEgKFotVGVzdDogRGlrZXRhaHVpIFNpZ21hKSIsDQogICAgQ0wgPSBwYXN0ZTAoY2wgKiAxMDAsICIlIiksDQogICAgTG93ZXIgPSByb3VuZChtZWFuX3ZhbCAtIG1vZV96LCAyKSwNCiAgICBVcHBlciA9IHJvdW5kKG1lYW5fdmFsICsgbW9lX3osIDIpDQogICkpDQogIA0KICAjIFRlYW0gQiAodC1UZXN0KQ0KICB0X2NyaXQgPC0gcXQoMSAtICgxIC0gY2wpIC8gMiwgZGYgPSBkZikNCiAgbW9lX3QgPC0gdF9jcml0ICogc2UNCiAgcGxvdF9kYXRhIDwtIHJiaW5kKHBsb3RfZGF0YSwgZGF0YS5mcmFtZSgNCiAgICBUZWFtID0gIlRlYW0gQiAodC1UZXN0OiBQYWthaSBTYW1wZWwgcykiLA0KICAgIENMID0gcGFzdGUwKGNsICogMTAwLCAiJSIpLA0KICAgIExvd2VyID0gcm91bmQobWVhbl92YWwgLSBtb2VfdCwgMiksDQogICAgVXBwZXIgPSByb3VuZChtZWFuX3ZhbCArIG1vZV90LCAyKQ0KICApKQ0KfQ0KDQojIDMuIE1lbWJ1YXQgVmlzdWFsaXNhc2kNCiMgZWNobz1GQUxTRSBwYWRhIGNodW5rIGluaSBtZW5qYW1pbiBoYW55YSBnYW1iYXIgeWFuZyB0YW1waWwNCmdncGxvdChwbG90X2RhdGEsIGFlcyh4ID0gQ0wsIHkgPSBtZWFuX3ZhbCwgY29sb3IgPSBUZWFtKSkgKw0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTG93ZXIsIHltYXggPSBVcHBlciksIA0KICAgICAgICAgICAgICAgIHdpZHRoID0gMC40LCBsaW5ld2lkdGggPSAxLjIsIA0KICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC42KSkgKw0KICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC42KSwgc2l6ZSA9IDMpICsNCiAgZ2VvbV90ZXh0KGFlcyh5ID0gTG93ZXIsIGxhYmVsID0gTG93ZXIpLCANCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC42KSwgdmp1c3QgPSAtMS41LCBzaXplID0gMy41LCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBnZW9tX3RleHQoYWVzKHkgPSBVcHBlciwgbGFiZWwgPSBVcHBlciksIA0KICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjYpLCB2anVzdCA9IC0xLjUsIHNpemUgPSAzLjUsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiUGVyYmFuZGluZ2FuIEludGVydmFsIEtlcGVyY2F5YWFuIChBUEkgTGF0ZW5jeSkiLA0KICAgICAgIHN1YnRpdGxlID0gIlRpbSBCICh0LXRlc3QpIG1lbWlsaWtpIGludGVydmFsIGxlYmloIGxlYmFyIHVudHVrIG1lbmdha29tb2Rhc2kgZXN0aW1hc2kgc3RhbmRhciBkZXZpYXNpIHNhbXBlbC4iLA0KICAgICAgIHggPSAiQ29uZmlkZW5jZSBMZXZlbCIsDQogICAgICAgeSA9ICJMYXRlbmN5IChtcykiLA0KICAgICAgIGNhcHRpb24gPSAiRGF0YTogbj0zNiwgTWVhbj0yMTAsIFNEPTI0IHwgQW5na2EgbWVudW5qdWtrYW4gYmF0YXMgYmF3YWggJiBhdGFzIENJIikgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMmMzZTUwIiwgIiNlNzRjM2MiKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiMjIyBBbmFsaXNpcyBQZXJiZWRhYW4gTGViYXIgSW50ZXJ2YWwNCk1lc2tpcHVuIG5pbGFpICRcYmFye3h9JCwgJG4kLCBkYW4gYW5na2Egc3RhbmRhciBkZXZpYXNpbnlhIHNhbWEgKDI0KSwgaW50ZXJ2YWwgVGVhbSBCIGxlYmloIGxlYmFyIGthcmVuYSBhbGFzYW4gYmVyaWt1dDoNCg0KKioxLioqIEtldGlkYWtwYXN0aWFuIFRhbWJhaGFuOiBUZWFtIEIgbWVuZ2d1bmFrYW4gc3RhbmRhciBkZXZpYXNpIHNhbXBlbCAoJHMkKSwgeWFuZyBtZXJ1cGFrYW4gZXN0aW1hc2kuIERpc3RyaWJ1c2ktdCBtZW1pbGlraSAiZWtvciB5YW5nIGxlYmloIHRlYmFsIiAoaGVhdmllciB0YWlscykgdW50dWsgbWVuZ29tcGVuc2FzaSBrZXRpZGFrcGFzdGlhbiBlc3RpbWFzaSB0ZXJzZWJ1dC4NCg0KKioyLioqIE5pbGFpIEtyaXRpczogTmlsYWkga3JpdGlzICR0JCBzZWxhbHUgbGViaWggYmVzYXIgZGFyaXBhZGEgbmlsYWkga3JpdGlzICR6JCB1bnR1ayB1a3VyYW4gc2FtcGVsIHlhbmcgc2FtYSAoJHReID4gel4kKS4NCg0KKiozLioqIEtvbnNlcnZhdGlzbWU6IFBlbmRla2F0YW4gdC10ZXN0IGxlYmloIGtvbnNlcnZhdGlmIChtZW5naGFzaWxrYW4gbWFyZ2luIG9mIGVycm9yIGxlYmloIGJlc2FyKSB1bnR1ayBtZW1hc3Rpa2FuIGJhaHdhIHBhcmFtZXRlciBwb3B1bGFzaSBiZW5hci1iZW5hciB0ZXJjYWt1cCBkYWxhbSBpbnRlcnZhbCBrZXRpa2EgaW5mb3JtYXNpIHBvcHVsYXNpIHRpZGFrIGxlbmdrYXAuDQoNCiMjIENhc2UgU3R1ZHkgNQ0KDQoqKk9uZS1TaWRlZCBDb25maWRlbmNlIEludGVydmFsOioqIEEgKipTb2Z0d2FyZSBhcyBhIFNlcnZpY2UgKFNhYVMpKiogY29tcGFueSB3YW50cyB0byBlbnN1cmUgdGhhdCAqKmF0IGxlYXN0IDcwJSBvZiB3ZWVrbHkgYWN0aXZlIHVzZXJzKiogdXRpbGl6ZSBhIHByZW1pdW0gZmVhdHVyZS4NCg0KRnJvbSB0aGUgZXhwZXJpbWVudDoNCg0KJCQNClxiZWdpbntlcW5hcnJheSp9DQpuICY9JiAyNTAgXHF1YWQgXHRleHR7KHRvdGFsIHVzZXJzKX0gXFwNCnggJj0mIDE4NSBccXVhZCBcdGV4dHsoYWN0aXZlIHByZW1pdW0gdXNlcnMpfQ0KXGVuZHtlcW5hcnJheSp9DQokJA0KDQpNYW5hZ2VtZW50IGlzIG9ubHkgaW50ZXJlc3RlZCBpbiB0aGUgKipsb3dlciBib3VuZCoqIG9mIHRoZSBlc3RpbWF0ZS4NCg0KKipUYXNrczoqKg0KDQoxLiBJZGVudGlmeSB0aGUgKip0eXBlIG9mIENvbmZpZGVuY2UgSW50ZXJ2YWwqKiBhbmQgdGhlIGFwcHJvcHJpYXRlIHRlc3QuDQoyLiBDb21wdXRlIHRoZSAqKm9uZS1zaWRlZCBsb3dlciBDb25maWRlbmNlIEludGVydmFsKiogYXQ6DQogICAtICQ5MFwlJA0KICAgLSAkOTVcJSQNCiAgIC0gJDk5XCUkDQozLiBWaXN1YWxpemUgdGhlIGxvd2VyIGJvdW5kcyBmb3IgYWxsIGNvbmZpZGVuY2UgbGV2ZWxzLg0KNC4gRGV0ZXJtaW5lIHdoZXRoZXIgdGhlICoqNzAlIHRhcmdldCoqIGlzIHN0YXRpc3RpY2FsbHkgc2F0aXNmaWVkLg0KDQoqKkpBV0FCOioqDQoNCiMjIyBJZGVudGlmaWthc2kgVGlwZSBDb25maWRlbmNlIEludGVydmFsIGRhbiBVamkgeWFuZyBUZXBhdA0KLSAqKlRpcGUgQ29uZmlkZW5jZSBJbnRlcnZhbDoqKiBNZW5nZ3VuYWthbiBPbmUtU2lkZWQgTG93ZXIgQ29uZmlkZW5jZSBJbnRlcnZhbCBrYXJlbmEgbWFuYWplbWVuIGhhbnlhIHRlcnRhcmlrIHBhZGEgYmF0YXMgYmF3YWggKGxvd2VyIGJvdW5kKSB1bnR1ayBtZW1hc3Rpa2FuIHByb3BvcnNpIHBlbmdndW5hIG1pbmltYWwgbWVuY2FwYWkgdGFyZ2V0IHRlcnRlbnR1Lg0KDQotICoqVWppIFN0YXRpc3RpazoqKiBNZW5nZ3VuYWthbiBaLXRlc3QgdW50dWsgUHJvcG9yc2kgKFotdGVzdCBmb3IgYSBzaW5nbGUgcHJvcG9ydGlvbikga2FyZW5hIGRhdGEgYmVydXBhIHByb3BvcnNpIGJpbm9taW5hbCAoYWt0aWYvdGlkYWsgYWt0aWYpIGRlbmdhbiB1a3VyYW4gc2FtcGVsIHlhbmcgYmVzYXIgKCRuPTI1MCQpLg0KDQojIyMgUGVyaGl0dW5nYW4gT25lLVNpZGVkIExvd2VyIENvbmZpZGVuY2UgSW50ZXJ2YWwNCkRpa2V0YWh1aSA6IA0KDQotICRuID0gMjUwJCR4ID0gMTg1JA0KDQotIFByb3BvcnNpIHNhbXBlbCAoJFxoYXR7cH0kKSA9ICRcZnJhY3sxODV9ezI1MH0gPSAwLjc0JCAoNzQlKQ0KDQotIFN0YW5kYXJkIEVycm9yICgkU0UkKSA9ICRcc3FydHtcZnJhY3tcaGF0e3B9KDEtXGhhdHtwfSl9e259fSA9IFxzcXJ0e1xmcmFjezAuNzQgXHRpbWVzIDAuMjZ9ezI1MH19IFxhcHByb3ggMC4wMjc3JA0KDQotIFJ1bXVzIExvd2VyIEJvdW5kOiAkXGhhdHtwfSAtICh6IFx0aW1lcyBTRSkkDQoNCmBgYHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpvbmVfc2lkZWQgPC0gZGF0YS5mcmFtZSgNCiAgQ29uZmlkZW5jZV9MZXZlbCA9IGMoIjkwJSIsICI5NSUiLCAiOTklIiksDQogIFpfc2NvcmUgPSBjKDEuMjgyLCAxLjY0NSwgMi4zMjYpLA0KICBDYWxjdWxhdGlvbiA9IGMoIjAuNzQgLSAoMS4yODIgw5cgMC4wMjc3KSIsICIwLjc0IC0gKDEuNjQ1IMOXIDAuMDI3NykiLCAiMC43NCAtICgyLjMyNiDDlyAwLjAyNzcpIiksDQogIExvd2VyX0JvdW5kID0gYygiNzAuNDUlIiwgIjY5LjQ0JSIsICI2Ny41NiUiKQ0KKQ0KDQprYWJsZShvbmVfc2lkZWQsIGNvbC5uYW1lcyA9IGMoIkNvbmZpZGVuY2UgTGV2ZWwiLCAiWi1zY29yZSAoT25lLVNpZGVkKSIsICJQZXJoaXR1bmdhbiIsICJMb3dlciBCb3VuZCAoJSkiKSwNCiAgICAgIGFsaWduID0gImMiLCBjYXB0aW9uID0gIlRhYmVsIEJhdGFzIEJhd2FoIFNhdHUgU2lzaSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwgZnVsbF93aWR0aCA9IEYpDQoNCmBgYA0KDQojIyMgVmlzdWFsaXNhc2kgTG93ZXIgQm91bmRzIA0KYGBgIHtyIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgRGF0YSBoYXNpbCBwZXJoaXR1bmdhbg0KZGYgPC0gZGF0YS5mcmFtZSgNCiAgQ0wgPSBmYWN0b3IoYygiOTAlIiwgIjk1JSIsICI5OSUiKSwgbGV2ZWxzPWMoIjkwJSIsICI5NSUiLCAiOTklIikpLA0KICBMb3dlcl9Cb3VuZCA9IGMoMC43MDQ1LCAwLjY5NDQsIDAuNjc1NikNCikNCg0KZ2dwbG90KGRmLCBhZXMoeD1DTCwgeT1Mb3dlcl9Cb3VuZCwgZmlsbD1DTCkpICsNCiAgZ2VvbV9jb2wod2lkdGggPSAwLjYpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC43MCwgY29sb3I9InJlZCIsIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4PTEuNSwgeT0wLjcxLCBsYWJlbD0iVGFyZ2V0IDcwJSIsIGNvbG9yPSJyZWQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQsIGxpbWl0cyA9IGMoMCwgMC44KSkgKw0KICBsYWJzKHRpdGxlPSJPbmUtU2lkZWQgTG93ZXIgQ29uZmlkZW5jZSBJbnRlcnZhbCIsDQogICAgICAgc3VidGl0bGU9IkFwYWthaCBiYXRhcyBiYXdhaCBtZWxld2F0aSB0YXJnZXQgNzAlPyIsDQogICAgICAgeD0iQ29uZmlkZW5jZSBMZXZlbCIsIHk9Ikxvd2VyIEJvdW5kICglKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQoNCiMjIyBLZXNpbXB1bGFuIFRhcmdldCA3MCUNCg0KQmVyZGFzYXJrYW4gaGFzaWwgYW5hbGlzaXMsIGFwYWthaCB0YXJnZXQgNzAlIHRlcnBlbnVoaSBzZWNhcmEgc3RhdGlzdGlrPw0KDQotICoqUGFkYSBUaW5na2F0IEtlcGVyY2F5YWFuIDkwJToqKiBUZXJwZW51aGksIGthcmVuYSBiYXRhcyBiYXdhaCAoNzAuNDUlKSBtYXNpaCBkaSBhdGFzIHRhcmdldCA3MCUuDQoNCi0gKipQYWRhIFRpbmdrYXQgS2VwZXJjYXlhYW4gOTUlOioqIFRpZGFrIFRlcnBlbnVoaSBzZWNhcmEga2V0YXQsIGthcmVuYSBiYXRhcyBiYXdhaCAoNjkuNDQlKSB0dXJ1biBzZWRpa2l0IGRpIGJhd2FoIHRhcmdldCA3MCUuDQoNCi0gKipQYWRhIFRpbmdrYXQgS2VwZXJjYXlhYW4gOTklOioqIFRpZGFrIFRlcnBlbnVoaSwga2FyZW5hIGJhdGFzIGJhd2FoICg2Ny41NiUpIGJlcmFkYSBkaSBiYXdhaCB0YXJnZXQuDQoNCktlc2ltcHVsYW4gQWtoaXI6IE1hbmFqZW1lbiBiaXNhIG1lcmFzYSB5YWtpbiBzZWJlc2FyIDkwJSBiYWh3YSB0YXJnZXQgdGVyY2FwYWksIG5hbXVuIGppa2EgbWVyZWthIG1lbWJ1dHVoa2FuIHRpbmdrYXQga2V5YWtpbmFuIHlhbmcgbGViaWggdGluZ2dpICg5NSUgYXRhdSA5OSUpLCBkYXRhIHNhYXQgaW5pIGJlbHVtIGN1a3VwIGt1YXQgdW50dWsgbWVuamFtaW4gdGFyZ2V0IDcwJSB0ZXJwZW51aGkgc2VjYXJhIHN0YXRpc3Rpay4NCg0KDQoNCg0K