Nama: Nabila Anggita Putri
Program Studi: S1 - Sains Data
Dosen Pengampu: Mr. Bakti Siregar, M.Sc.,
CDS.,
Institusi: Institut Teknologi Sains
Bandung

1. Pendahuluan
Analisis clustering merupakan teknik dalam unsupervised learning yang
bertujuan mengelompokkan individu atau observasi berdasarkan tingkat
kemiripan karakteristik tanpa menggunakan label kelas. Metode ini
penting dalam berbagai bidang analisis data, termasuk segmentasi
pelanggan, karena mampu mengungkap pola tersembunyi (hidden patterns) di
dalam data. Dalam konteks pemasaran ritel, khususnya pada data pelanggan
di sebuah mall, clustering digunakan untuk memahami perilaku belanja
konsumen sehingga perusahaan dapat menyusun strategi pemasaran yang
lebih tepat sasaran.
Pada studi ini dilakukan pendekatan clustering hybrid, yaitu gabungan
atau kombinasi dari beberapa metode clustering untuk menghasilkan
performa segmentasi yang lebih stabil, akurat, dan representatif. Teknik
hybrid memanfaatkan keunggulan setiap algoritma, sehingga dapat
mengatasi keterbatasan yang muncul jika hanya menggunakan satu metode.
Misalnya, metode berbasis jarak kadang sensitif terhadap noise dan
bentuk klaster yang tidak linear, sementara metode berbasis graf dapat
lebih baik dalam memetakan struktur kompleks namun memiliki beban
komputasi tinggi. Dengan pendekatan hybrid, proses clustering dapat
dilakukan lebih robust melalui tahap ekstraksi fitur, reduksi dimensi,
atau penyempurnaan hasil klaster.
Dalam penelitian ini digunakan tiga pendekatan clustering modern yang
mewakili tiga paradigma berbeda:
1. Autoencoder Clustering – pendekatan berbasis deep
learning yang melakukan pembelajaran representasi (representation
learning). Autoencoder mereduksi dimensi data melalui latent space,
sehingga struktur data menjadi lebih kompak dan mudah dipisahkan sebelum
diterapkan algoritma klaster seperti KMeans.
2. Self-Organizing Map (SOM) – metode jaringan saraf
kompetitif yang memproyeksikan data berdimensi tinggi ke dalam grid dua
dimensi. SOM mampu memvisualisasikan pola topologis dan kesamaan antar
data secara intuitif, sehingga sangat membantu dalam interpretasi
struktur klaster.
3. Spectral Clustering – metode berbasis dekomposisi
eigen pada matriks Laplacian graf. Pendekatan ini lebih efektif untuk
mengelompokkan data dengan bentuk klaster yang kompleks, tidak
beraturan, maupun tidak terpisah secara linear.
Ketiga metode tersebut dibandingkan untuk menentukan pendekatan yang
paling tepat dalam mengelompokkan pelanggan mall berdasarkan perilaku
belanja mereka. Melalui analisis ini, diharapkan diperoleh segmentasi
pelanggan yang lebih akurat dan dapat menjadi dasar pengambilan
keputusan dalam strategi pemasaran, pengelolaan loyalitas, dan
pengembangan layanan yang sesuai dengan profil tiap kelompok
pelanggan.
Dataset yang digunakan adalah:
Mall Customers Dataset (Publik — tersedia di
Kaggle). Link: “https://www.kaggle.com/datasets/amisha0528/mall-customers-dataset”.
2. Definisi Dan Teori
2.1 Autoencoder (Unsupervised Clustering)
Autoencoder adalah arsitektur jaringan saraf dalam yang belajar
memetakan data ke ruang berdimensi lebih rendah (latent space) melalui
proses rekonstruksi. Representasi laten inilah yang digunakan sebagai
input untuk clustering.
Rumus:
Autoencoder terdiri dari dua fungsi:
1. Encoder: \[
z = f_{\theta}(x)
\]
2. Decoder: \[
\hat{x} = g_{\phi}(z)
\]
Tujuan Optimasi: \[
\min_{\theta, \phi} \, \lVert x - \hat{x} \rVert^{2}
\]
Sehingga model belajar representasi padat (compressed) yang
mempertahankan struktur utama data.
a. Cara Kerja
- Melakukan encoding data → latent space.
- Melakukan decoding untuk meminimalkan error rekonstruksi.
- Mengambil latent representation z.
- Melakukan clustering pada z (umumnya KMeans atau Gaussian
Mixture).
b. Hyperparameter Utama
- Jumlah neuron di hidden layer
- Dimensi latent space
- Aktivasi (ReLU, Sigmoid)
- Optimizer (Adam)
- Epoch & batch size
c. Kelebihan
- Sangat baik untuk data kompleks.
- Menangkap struktur non-linear.
- Menghasilkan fitur yang lebih representatif untuk clustering.
d. Keterbatasan
- Membutuhkan tuning banyak hyperparameter.
- Butuh komputasi tinggi.
- Rentan overfitting bila data sedikit.
2.2 Self - Organizing Map (SOM)
SOM adalah jaringan saraf unsupervised yang memetakan data berdimensi
tinggi ke grid 2D melalui proses kompetisi antar neuron.
Model Matematis:
Pemilihan neuron pemenang: \[
\text{BMU} = \arg\min_i \, \lVert x - w_i \rVert
\]
Pembaruan Bobot: \[
w_i(t+1) = w_i(t) + \alpha(t) \, h_{\text{BMU}, i}(t) \, (x - w_i(t))
\]
a. Cara Kerja
- Inisialisasi grid neuron.
- Untuk setiap data:
- Tentukan Best Matching Unit (BMU).
- Perbarui bobot tetangga.
- Proses iteratif hingga konvergen.
b. Hyperparameter Utama
- Ukuran grid (misal 10×10)
- Learning rate
- Radius neighborhood
- Jumlah epoch
c. Kelebihan
- Menyediakan peta topografi yang teratur
- Mudah diinterpretasi
- Cocok untuk clustering berbasis visual
d. Keterbatasan
- Butuh pemilihan grid yang tepat
- Tidak optimal untuk data sangat kompleks
- Hasil clustering bergantung pada inisialisasi
2.3 Spectral Clustering
Metode clustering berbasis graf yang menggunakan eigenvector dari
Laplacian graph untuk memproyeksikan data ke subspace sebelum dilakukan
clustering (biasanya KMeans).
Rumus
Membangun similarity matrix: \[
S_{ij} = e^{-\frac{\lVert x_i - x_j \rVert^{2}}{2\sigma^{2}}}
\]
Matriks Laplacian tidak ter-normalisasi: \[
L = D - S
\]
Eigen-decomposition: \[
L v = \lambda v
\]
a. Cara Kerja
- Hitung similarity matrix.
- Hitung Laplacian graph.
- Ambil k eigenvector terkecil.
- Cluster pada ruang eigenvector.
b. Hyperparameter Utama
- Jumlah cluster
- Jenis similarity (rbf, nearest neighbors)
- Parameter sigma
c. Kelebihan
- Menangkap struktur non-linear
- Cocok untuk dataset dengan cluster tidak berbentuk bola
- Lebih stabil dibanding KMeans pada boundary sulit
d. Keterbatsan
- Komputasi tinggi \(O(n^3)\)
- Sensitif terhadap pemilihan parameter sigma
3. Persiapan Data
Dataset berisi \(200\) pelanggan
dengan variabel:
- CustomerID
- Genre
- Age
- Annual Income (k$)
- Spending Score (1 - 100)
3.1 Loading Data
## 'data.frame': 200 obs. of 5 variables:
## $ CustomerID : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Gender : chr "Male" "Male" "Female" "Female" ...
## $ Age : int 19 21 20 23 31 22 35 23 64 30 ...
## $ Income : int 15 15 16 16 17 17 18 18 19 19 ...
## $ SpendingScore: int 39 81 6 77 40 76 6 94 3 72 ...
## CustomerID Gender Age Income
## Min. : 1.00 Length:200 Min. :18.00 Min. : 15.00
## 1st Qu.: 50.75 Class :character 1st Qu.:28.75 1st Qu.: 41.50
## Median :100.50 Mode :character Median :36.00 Median : 61.50
## Mean :100.50 Mean :38.85 Mean : 60.56
## 3rd Qu.:150.25 3rd Qu.:49.00 3rd Qu.: 78.00
## Max. :200.00 Max. :70.00 Max. :137.00
## SpendingScore
## Min. : 1.00
## 1st Qu.:34.75
## Median :50.00
## Mean :50.20
## 3rd Qu.:73.00
## Max. :99.00
4 Redukasi Dimensi
Untuk metode Autoencoder, representasi laten sudah menjadi reduksi
dimensi. Untuk SOM dan Spectral Clustering, reduksi tidak wajib karena
dimensi kecil (4 fitur numerik).
Karena dataset ini kecil dan fitur sudah manageable, reduksi dimensi
tidak dilakukan.
5. Pemodelan Clustering
5.1 Autoencoder + KMeans
Pemilihan Parameter
- Dense layer: 8 → 4 → latent 2
- Aktivasi: ReLU
- Optimizer: Adam
- Epoch: 100
## Metric Value
## 1 Silhouette 0.350
## 2 Davies-Bouldin Index 1.135
## 3 Calinski-Harabasz Index 100.488
5.2 Self-Organizing Map (SOM)
Pemilihan Parameter
- Grid: 10×10
- Learning rate: default
- Iterasi: 1000
## Metric Value
## 1 Silhouette 0.348
## 2 Davies-Bouldin Index 1.140
## 3 Calinski-Harabasz Index 99.534
5.3 Spectral Clustering
Pemilihan Parameter
- k = 3
- SImilarity = radial basis function
## Metric Value
## 1 Silhouette 0.246
## 2 Davies-Bouldin Index 1.823
## 3 Calinski-Harabasz Index 71.140
6. Evaluasi Clustering
Metode evaluasi:
1. Silhouette Index
2. Davies–Bouldin Index (DBI)
3. Calinski–Harabasz Index (CHI)
## [1] 0.3502714
## [1] 0.3476772
## [1] 0.2462819
7. Pembahasan Hasil dan Perbandingan
## Metode Silhouette DBI CHI
## 1 Autoencoder 0.350 1.135 100.488
## 2 SOM 0.348 1.140 99.534
## 3 Spectral 0.246 1.823 71.140
## Interpretasi
## 1 Biasanya baik jika struktur non-linear muncul
## 2 Cocok untuk data sederhana
## 3 Umumnya stabil pada data low-dimensional
Interpretasi:
- Autoencoder lebih unggul bila data memiliki pola non-linear.
- SOM memberikan pemetaan topografi yang baik namun cluster terkadang
kurang tegas.
- Spectral Clustering efektif untuk dataset kecil dengan boundary
non-linear.
8. Kesimpulan dan Rekomendasi
a. Kesimpulan
- Ketiga algoritma mampu mengelompokkan pelanggan mall berdasarkan
pendapatan dan skor belanja.
- Representasi laten dari Autoencoder memberi struktur lebih kompak
sehingga hasil clustering biasanya lebih stabil. -bSOM cocok digunakan
bila interpretasi visual topografi dibutuhkan.
- Spectral Clustering efektif untuk dataset kecil dan mampu menangkap
pola non-linear.
b. Rekomendasi:
Untuk dataset Mall Customers, metode Autoencoder +
KMeans cenderung memberikan performa terbaik karena mampu
mempelajari representasi data secara non-linear sehingga memaksimalkan
pemisahan cluster.
c. Penutup
Melalui analisis yang telah dilakukan, dapat disimpulkan bahwa proses
clustering menggunakan pendekatan hybrid—Autoencoder, Self-Organizing
Map (SOM), dan Spectral Clustering—memberikan pemahaman yang lebih
komprehensif mengenai struktur dan pola tersembunyi dalam dataset
pelanggan mall. Setiap metode menawarkan karakteristik, kekuatan, serta
keterbatasan masing-masing, sehingga memberikan perspektif yang beragam
dalam proses pengelompokan data.
Pendekatan Autoencoder memanfaatkan kemampuan representasi laten
untuk menangkap pola non-linear secara lebih efektif. SOM memberikan
interpretasi topografi yang intuitif, sedangkan Spectral Clustering
menunjukkan kinerja yang baik pada struktur data yang kompleks namun
berukuran kecil. Perbandingan ketiga metode ini memungkinkan pemilihan
model clustering yang paling sesuai dengan tujuan analisis dan
karakteristik dataset.
Harapannya, penelitian dan implementasi ini dapat menjadi landasan
untuk pengembangan metode analisis data lanjutan, serta memberikan
pemahaman yang lebih dalam mengenai penerapan algoritma clustering
modern dalam konteks Data Sains. Semoga laporan ini dapat memberikan
manfaat dan kontribusi positif bagi proses pembelajaran serta studi
lebih lanjut terkait analisis data berbasis unsupervised learning.
DAFTAR PUSTAKA
- Mall Customers Dataset, Amisha0528.Retrieved from
Klik disini
- Siberetika dan Sistem, Bei Lu dan Salman Saeidlou, 12 Agustus
2022.Retrieved from
Klik disini
- Algoritma Pengelompokan Hibrida Berdasarkan Pengelompokan Puncak
Kepadatan yang Ditingkatkan, Limin Guo, Weijia Qin, Zhi Cai, Xingsu,
2024.Retrieved from
Klik
disini
- Deteksi Anomali dalam Penipuan E-commerce Menggunakan Hybrid
Autoencoder-Transformer Frameworks Wowon Priatna, Sri Yulianto Joko
Prasetyo, Sutarto Wijono, Evi Maria, Danny Manongga, 2025.Retrieved from
Klik disini
- Self-organizing, hybrid, PDE-ODE structure for motion control in
informationally-deprived situations, 1998.Retrieved from
Klik disini
LS0tDQp0aXRsZTogIkxBUE9SQU4gQU5BTElTSVMgQ0xVU1RFUklORyBIWUJSSUQiDQphdXRob3I6IA0KICAtICJOYWJpbGEgQW5nZ2l0YSBQdXRyaSINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246DQogICAgc2VsZl9jb250YWluZWQ6IHRydWUNCiAgICB0aHVtYm5haWxzOiB0cnVlDQogICAgbGlnaHRib3g6IHRydWUNCiAgICBnYWxsZXJ5OiB0cnVlDQogICAgbGliX2RpcjogbGlicw0KICAgIGRmX3ByaW50OiAicGFnZWQiDQogICAgY29kZV9mb2xkaW5nOiAic2hvdyINCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBjc3M6ICJTdHlsZS5jc3MiDQotLS0NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXI7IG1hcmdpbi10b3A6MjBweDsiPg0KDQoNCiMjIyAqKk5hbWE6KiogICoqTmFiaWxhIEFuZ2dpdGEgUHV0cmkqKg0KDQojIyMgKipQcm9ncmFtIFN0dWRpOioqICoqUzEgLSBTYWlucyBEYXRhICoqDQoNCiMjIyAqKkRvc2VuIFBlbmdhbXB1OioqICAqKk1yLiBCYWt0aSBTaXJlZ2FyLCBNLlNjLiwgQ0RTLiwqKg0KDQojIyMgKipJbnN0aXR1c2k6KiogICoqSW5zdGl0dXQgVGVrbm9sb2dpIFNhaW5zIEJhbmR1bmcqKg0KDQo8YnI+PGJyPg0KDQo8aW1nIHNyYz0iaW1nL3Byb2ZpbGUuanBlZyIgYWx0PSJGb3RvIEZvcm1hbCIgc3R5bGU9IndpZHRoOjIwMDsgZGlzcGxheTpibG9jazsgbWFyZ2luOmF1dG87IGJvcmRlci1yYWRpdXM6MTJweDsiLz4NCg0KPGJyPg0KDQotLS0NCg0KPC9kaXY+DQoNCg0KIyAqKjEuIFBlbmRhaHVsdWFuKioNCg0KQW5hbGlzaXMgY2x1c3RlcmluZyBtZXJ1cGFrYW4gdGVrbmlrIGRhbGFtIHVuc3VwZXJ2aXNlZCBsZWFybmluZyB5YW5nIGJlcnR1anVhbiBtZW5nZWxvbXBva2thbiBpbmRpdmlkdSBhdGF1IG9ic2VydmFzaSBiZXJkYXNhcmthbiB0aW5na2F0IGtlbWlyaXBhbiBrYXJha3RlcmlzdGlrIHRhbnBhIG1lbmdndW5ha2FuIGxhYmVsIGtlbGFzLiBNZXRvZGUgaW5pIHBlbnRpbmcgZGFsYW0gYmVyYmFnYWkgYmlkYW5nIGFuYWxpc2lzIGRhdGEsIHRlcm1hc3VrIHNlZ21lbnRhc2kgcGVsYW5nZ2FuLCBrYXJlbmEgbWFtcHUgbWVuZ3VuZ2thcCBwb2xhIHRlcnNlbWJ1bnlpIChoaWRkZW4gcGF0dGVybnMpIGRpIGRhbGFtIGRhdGEuIERhbGFtIGtvbnRla3MgcGVtYXNhcmFuIHJpdGVsLCBraHVzdXNueWEgcGFkYSBkYXRhIHBlbGFuZ2dhbiBkaSBzZWJ1YWggbWFsbCwgY2x1c3RlcmluZyBkaWd1bmFrYW4gdW50dWsgbWVtYWhhbWkgcGVyaWxha3UgYmVsYW5qYSBrb25zdW1lbiBzZWhpbmdnYSBwZXJ1c2FoYWFuIGRhcGF0IG1lbnl1c3VuIHN0cmF0ZWdpIHBlbWFzYXJhbiB5YW5nIGxlYmloIHRlcGF0IHNhc2FyYW4uDQoNClBhZGEgc3R1ZGkgaW5pIGRpbGFrdWthbiBwZW5kZWthdGFuIGNsdXN0ZXJpbmcgaHlicmlkLCB5YWl0dSBnYWJ1bmdhbiBhdGF1IGtvbWJpbmFzaSBkYXJpIGJlYmVyYXBhIG1ldG9kZSBjbHVzdGVyaW5nIHVudHVrIG1lbmdoYXNpbGthbiBwZXJmb3JtYSBzZWdtZW50YXNpIHlhbmcgbGViaWggc3RhYmlsLCBha3VyYXQsIGRhbiByZXByZXNlbnRhdGlmLiBUZWtuaWsgaHlicmlkIG1lbWFuZmFhdGthbiBrZXVuZ2d1bGFuIHNldGlhcCBhbGdvcml0bWEsIHNlaGluZ2dhIGRhcGF0IG1lbmdhdGFzaSBrZXRlcmJhdGFzYW4geWFuZyBtdW5jdWwgamlrYSBoYW55YSBtZW5nZ3VuYWthbiBzYXR1IG1ldG9kZS4gTWlzYWxueWEsIG1ldG9kZSBiZXJiYXNpcyBqYXJhayBrYWRhbmcgc2Vuc2l0aWYgdGVyaGFkYXAgbm9pc2UgZGFuIGJlbnR1ayBrbGFzdGVyIHlhbmcgdGlkYWsgbGluZWFyLCBzZW1lbnRhcmEgbWV0b2RlIGJlcmJhc2lzIGdyYWYgZGFwYXQgbGViaWggYmFpayBkYWxhbSBtZW1ldGFrYW4gc3RydWt0dXIga29tcGxla3MgbmFtdW4gbWVtaWxpa2kgYmViYW4ga29tcHV0YXNpIHRpbmdnaS4gRGVuZ2FuIHBlbmRla2F0YW4gaHlicmlkLCBwcm9zZXMgY2x1c3RlcmluZyBkYXBhdCBkaWxha3VrYW4gbGViaWggcm9idXN0IG1lbGFsdWkgdGFoYXAgZWtzdHJha3NpIGZpdHVyLCByZWR1a3NpIGRpbWVuc2ksIGF0YXUgcGVueWVtcHVybmFhbiBoYXNpbCBrbGFzdGVyLg0KDQpEYWxhbSBwZW5lbGl0aWFuIGluaSBkaWd1bmFrYW4gdGlnYSBwZW5kZWthdGFuIGNsdXN0ZXJpbmcgbW9kZXJuIHlhbmcgbWV3YWtpbGkgdGlnYSBwYXJhZGlnbWEgYmVyYmVkYToNCg0KKioxLiBBdXRvZW5jb2RlciBDbHVzdGVyaW5nKiog4oCTIHBlbmRla2F0YW4gYmVyYmFzaXMgZGVlcCBsZWFybmluZyB5YW5nIG1lbGFrdWthbiBwZW1iZWxhamFyYW4gcmVwcmVzZW50YXNpIChyZXByZXNlbnRhdGlvbiBsZWFybmluZykuIEF1dG9lbmNvZGVyIG1lcmVkdWtzaSBkaW1lbnNpIGRhdGEgbWVsYWx1aSBsYXRlbnQgc3BhY2UsIHNlaGluZ2dhIHN0cnVrdHVyIGRhdGEgbWVuamFkaSBsZWJpaCBrb21wYWsgZGFuIG11ZGFoIGRpcGlzYWhrYW4gc2ViZWx1bSBkaXRlcmFwa2FuIGFsZ29yaXRtYSBrbGFzdGVyIHNlcGVydGkgS01lYW5zLg0KDQoqKjIuIFNlbGYtT3JnYW5pemluZyBNYXAgKFNPTSkqKiDigJMgbWV0b2RlIGphcmluZ2FuIHNhcmFmIGtvbXBldGl0aWYgeWFuZyBtZW1wcm95ZWtzaWthbiBkYXRhIGJlcmRpbWVuc2kgdGluZ2dpIGtlIGRhbGFtIGdyaWQgZHVhIGRpbWVuc2kuIFNPTSBtYW1wdSBtZW12aXN1YWxpc2FzaWthbiBwb2xhIHRvcG9sb2dpcyBkYW4ga2VzYW1hYW4gYW50YXIgZGF0YSBzZWNhcmEgaW50dWl0aWYsIHNlaGluZ2dhIHNhbmdhdCBtZW1iYW50dSBkYWxhbSBpbnRlcnByZXRhc2kgc3RydWt0dXIga2xhc3Rlci4NCg0KKiozLiBTcGVjdHJhbCBDbHVzdGVyaW5nKiog4oCTIG1ldG9kZSBiZXJiYXNpcyBkZWtvbXBvc2lzaSBlaWdlbiBwYWRhIG1hdHJpa3MgTGFwbGFjaWFuIGdyYWYuIFBlbmRla2F0YW4gaW5pIGxlYmloIGVmZWt0aWYgdW50dWsgbWVuZ2Vsb21wb2trYW4gZGF0YSBkZW5nYW4gYmVudHVrIGtsYXN0ZXIgeWFuZyBrb21wbGVrcywgdGlkYWsgYmVyYXR1cmFuLCBtYXVwdW4gdGlkYWsgdGVycGlzYWggc2VjYXJhIGxpbmVhci4NCg0KS2V0aWdhIG1ldG9kZSB0ZXJzZWJ1dCBkaWJhbmRpbmdrYW4gdW50dWsgbWVuZW50dWthbiBwZW5kZWthdGFuIHlhbmcgcGFsaW5nIHRlcGF0IGRhbGFtIG1lbmdlbG9tcG9ra2FuIHBlbGFuZ2dhbiBtYWxsIGJlcmRhc2Fya2FuIHBlcmlsYWt1IGJlbGFuamEgbWVyZWthLiBNZWxhbHVpIGFuYWxpc2lzIGluaSwgZGloYXJhcGthbiBkaXBlcm9sZWggc2VnbWVudGFzaSBwZWxhbmdnYW4geWFuZyBsZWJpaCBha3VyYXQgZGFuIGRhcGF0IG1lbmphZGkgZGFzYXIgcGVuZ2FtYmlsYW4ga2VwdXR1c2FuIGRhbGFtIHN0cmF0ZWdpIHBlbWFzYXJhbiwgcGVuZ2Vsb2xhYW4gbG95YWxpdGFzLCBkYW4gcGVuZ2VtYmFuZ2FuIGxheWFuYW4geWFuZyBzZXN1YWkgZGVuZ2FuIHByb2ZpbCB0aWFwIGtlbG9tcG9rIHBlbGFuZ2dhbi4NCg0KRGF0YXNldCB5YW5nIGRpZ3VuYWthbiBhZGFsYWg6DQoNCioqTWFsbCBDdXN0b21lcnMgRGF0YXNldCoqIChQdWJsaWsg4oCUIHRlcnNlZGlhIGRpIEthZ2dsZSkuDQpMaW5rOiDigJxodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2FtaXNoYTA1MjgvbWFsbC1jdXN0b21lcnMtZGF0YXNldOKAnS4NCg0KDQojICoqMi4gRGVmaW5pc2kgRGFuIFRlb3JpKioNCg0KIyMgKioyLjEgQXV0b2VuY29kZXIgKFVuc3VwZXJ2aXNlZCBDbHVzdGVyaW5nKSoqDQoNCkF1dG9lbmNvZGVyIGFkYWxhaCBhcnNpdGVrdHVyIGphcmluZ2FuIHNhcmFmIGRhbGFtIHlhbmcgYmVsYWphciBtZW1ldGFrYW4gZGF0YSBrZSBydWFuZyBiZXJkaW1lbnNpIGxlYmloIHJlbmRhaCAobGF0ZW50IHNwYWNlKSBtZWxhbHVpIHByb3NlcyByZWtvbnN0cnVrc2kuIFJlcHJlc2VudGFzaSBsYXRlbiBpbmlsYWggeWFuZyBkaWd1bmFrYW4gc2ViYWdhaSBpbnB1dCB1bnR1ayBjbHVzdGVyaW5nLg0KDQoqKlJ1bXVzKio6DQoNCkF1dG9lbmNvZGVyIHRlcmRpcmkgZGFyaSBkdWEgZnVuZ3NpOg0KDQoqKjEuIEVuY29kZXIqKjoNClxbDQp6ID0gZl97XHRoZXRhfSh4KQ0KXF0NCg0KKioyLiBEZWNvZGVyKio6DQpcWw0KXGhhdHt4fSA9IGdfe1xwaGl9KHopDQpcXQ0KDQoqKlR1anVhbiBPcHRpbWFzaSoqOg0KXFsNClxtaW5fe1x0aGV0YSwgXHBoaX0gXCwgXGxWZXJ0IHggLSBcaGF0e3h9IFxyVmVydF57Mn0NClxdDQoNClNlaGluZ2dhIG1vZGVsIGJlbGFqYXIgcmVwcmVzZW50YXNpIHBhZGF0IChjb21wcmVzc2VkKSB5YW5nIG1lbXBlcnRhaGFua2FuIHN0cnVrdHVyIHV0YW1hIGRhdGEuDQoNCiMjIyAqKmEuIENhcmEgS2VyamEqKg0KDQotIE1lbGFrdWthbiBlbmNvZGluZyBkYXRhIOKGkiBsYXRlbnQgc3BhY2UuDQotIE1lbGFrdWthbiBkZWNvZGluZyB1bnR1ayBtZW1pbmltYWxrYW4gZXJyb3IgcmVrb25zdHJ1a3NpLg0KLSBNZW5nYW1iaWwgbGF0ZW50IHJlcHJlc2VudGF0aW9uICp6Ki4NCi0gTWVsYWt1a2FuIGNsdXN0ZXJpbmcgcGFkYSAqeiogKHVtdW1ueWEgS01lYW5zIGF0YXUgR2F1c3NpYW4gTWl4dHVyZSkuDQoNCiMjIyAqKmIuIEh5cGVycGFyYW1ldGVyIFV0YW1hKioNCg0KLSBKdW1sYWggbmV1cm9uIGRpIGhpZGRlbiBsYXllcg0KLSBEaW1lbnNpIGxhdGVudCBzcGFjZQ0KLSBBa3RpdmFzaSAoUmVMVSwgU2lnbW9pZCkNCi0gT3B0aW1pemVyIChBZGFtKQ0KLSBFcG9jaCAmIGJhdGNoIHNpemUNCg0KIyMjICoqYy4gS2VsZWJpaGFuKioNCg0KLSBTYW5nYXQgYmFpayB1bnR1ayBkYXRhIGtvbXBsZWtzLg0KLSBNZW5hbmdrYXAgc3RydWt0dXIgbm9uLWxpbmVhci4NCi0gTWVuZ2hhc2lsa2FuIGZpdHVyIHlhbmcgbGViaWggcmVwcmVzZW50YXRpZiB1bnR1ayBjbHVzdGVyaW5nLg0KDQoNCiMjIyAqKmQuIEtldGVyYmF0YXNhbioqDQoNCi0gTWVtYnV0dWhrYW4gdHVuaW5nIGJhbnlhayBoeXBlcnBhcmFtZXRlci4NCi0gQnV0dWgga29tcHV0YXNpIHRpbmdnaS4NCi0gUmVudGFuIG92ZXJmaXR0aW5nIGJpbGEgZGF0YSBzZWRpa2l0Lg0KDQoNCg0KIyMgKioyLjIgU2VsZiAtIE9yZ2FuaXppbmcgTWFwIChTT00pKioNCg0KU09NIGFkYWxhaCBqYXJpbmdhbiBzYXJhZiB1bnN1cGVydmlzZWQgeWFuZyBtZW1ldGFrYW4gZGF0YSBiZXJkaW1lbnNpIHRpbmdnaSBrZSBncmlkIDJEIG1lbGFsdWkgcHJvc2VzIGtvbXBldGlzaSBhbnRhciBuZXVyb24uDQoNCioqTW9kZWwgTWF0ZW1hdGlzKio6DQoNCioqUGVtaWxpaGFuIG5ldXJvbiBwZW1lbmFuZzoqKg0KXFsNClx0ZXh0e0JNVX0gPSBcYXJnXG1pbl9pIFwsIFxsVmVydCB4IC0gd19pIFxyVmVydA0KXF0NCg0KKipQZW1iYXJ1YW4gQm9ib3Q6KioNClxbDQp3X2kodCsxKSA9IHdfaSh0KSArIFxhbHBoYSh0KSBcLCBoX3tcdGV4dHtCTVV9LCBpfSh0KSBcLCAoeCAtIHdfaSh0KSkNClxdDQoNCg0KIyMjICoqYS4gQ2FyYSBLZXJqYSoqDQoNCi0gSW5pc2lhbGlzYXNpIGdyaWQgbmV1cm9uLg0KLSBVbnR1ayBzZXRpYXAgZGF0YToNCiAgICAtIFRlbnR1a2FuIEJlc3QgTWF0Y2hpbmcgVW5pdCAoQk1VKS4NCiAgICAtIFBlcmJhcnVpIGJvYm90IHRldGFuZ2dhLg0KLSBQcm9zZXMgaXRlcmF0aWYgaGluZ2dhIGtvbnZlcmdlbi4NCg0KIyMjICoqYi4gSHlwZXJwYXJhbWV0ZXIgVXRhbWEqKg0KDQotIFVrdXJhbiBncmlkIChtaXNhbCAxMMOXMTApDQotIExlYXJuaW5nIHJhdGUNCi0gUmFkaXVzIG5laWdoYm9yaG9vZA0KLSBKdW1sYWggZXBvY2gNCg0KIyMjICoqYy4gS2VsZWJpaGFuKioNCg0KLSBNZW55ZWRpYWthbiBwZXRhIHRvcG9ncmFmaSB5YW5nIHRlcmF0dXINCi0gTXVkYWggZGlpbnRlcnByZXRhc2kNCi0gQ29jb2sgdW50dWsgY2x1c3RlcmluZyBiZXJiYXNpcyB2aXN1YWwNCg0KIyMjICoqZC4gS2V0ZXJiYXRhc2FuKioNCg0KLSBCdXR1aCBwZW1pbGloYW4gZ3JpZCB5YW5nIHRlcGF0DQotIFRpZGFrIG9wdGltYWwgdW50dWsgZGF0YSBzYW5nYXQga29tcGxla3MNCi0gSGFzaWwgY2x1c3RlcmluZyBiZXJnYW50dW5nIHBhZGEgaW5pc2lhbGlzYXNpDQoNCg0KIyMgKioyLjMgU3BlY3RyYWwgQ2x1c3RlcmluZyoqDQoNCk1ldG9kZSBjbHVzdGVyaW5nIGJlcmJhc2lzIGdyYWYgeWFuZyBtZW5nZ3VuYWthbiBlaWdlbnZlY3RvciBkYXJpIExhcGxhY2lhbiBncmFwaCB1bnR1ayBtZW1wcm95ZWtzaWthbiBkYXRhIGtlIHN1YnNwYWNlIHNlYmVsdW0gZGlsYWt1a2FuIGNsdXN0ZXJpbmcgKGJpYXNhbnlhIEtNZWFucykuDQoNCioqUnVtdXMqKg0KDQoqKk1lbWJhbmd1biBzaW1pbGFyaXR5IG1hdHJpeCoqOg0KXFsNClNfe2lqfSA9IGVeey1cZnJhY3tcbFZlcnQgeF9pIC0geF9qIFxyVmVydF57Mn19ezJcc2lnbWFeezJ9fX0NClxdDQoNCioqTWF0cmlrcyBMYXBsYWNpYW4gdGlkYWsgdGVyLW5vcm1hbGlzYXNpKio6DQpcWw0KTCA9IEQgLSBTDQpcXQ0KDQoNCioqRWlnZW4tZGVjb21wb3NpdGlvbioqOg0KXFsNCkwgdiA9IFxsYW1iZGEgdg0KXF0NCg0KDQojIyMgKiphLiBDYXJhIEtlcmphKioNCg0KLSBIaXR1bmcgc2ltaWxhcml0eSBtYXRyaXguDQotIEhpdHVuZyBMYXBsYWNpYW4gZ3JhcGguDQotIEFtYmlsIGsgZWlnZW52ZWN0b3IgdGVya2VjaWwuDQotIENsdXN0ZXIgcGFkYSBydWFuZyBlaWdlbnZlY3Rvci4NCg0KIyMjICoqYi4gSHlwZXJwYXJhbWV0ZXIgVXRhbWEqKg0KDQotIEp1bWxhaCBjbHVzdGVyDQotIEplbmlzIHNpbWlsYXJpdHkgKihyYmYsIG5lYXJlc3QgbmVpZ2hib3JzKSoNCi0gUGFyYW1ldGVyIHNpZ21hDQoNCg0KIyMjICoqYy4gS2VsZWJpaGFuKioNCg0KLSBNZW5hbmdrYXAgc3RydWt0dXIgbm9uLWxpbmVhcg0KLSBDb2NvayB1bnR1ayBkYXRhc2V0IGRlbmdhbiBjbHVzdGVyIHRpZGFrIGJlcmJlbnR1ayBib2xhDQotIExlYmloIHN0YWJpbCBkaWJhbmRpbmcgS01lYW5zIHBhZGEgYm91bmRhcnkgc3VsaXQNCg0KIyMjICoqZC4gS2V0ZXJiYXRzYW4qKg0KDQotIEtvbXB1dGFzaSB0aW5nZ2kgJE8obl4zKSQNCi0gU2Vuc2l0aWYgdGVyaGFkYXAgcGVtaWxpaGFuIHBhcmFtZXRlciBzaWdtYQ0KDQoNCiMgKiozLiBQZXJzaWFwYW4gRGF0YSoqDQoNCkRhdGFzZXQgYmVyaXNpICQyMDAkIHBlbGFuZ2dhbiBkZW5nYW4gdmFyaWFiZWw6DQoNCi0gKkN1c3RvbWVySUQqDQotICpHZW5yZSoNCi0gKkFnZSoNCi0gKkFubnVhbCBJbmNvbWUgKGskKSoNCi0gKlNwZW5kaW5nIFNjb3JlICgxIC0gMTAwKSoNCg0KDQojIyAqKjMuMSBMb2FkaW5nIERhdGEqKg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQoNCmRmIDwtIHJlYWQuY3N2KCJNYWxsX0N1c3RvbWVycy5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCg0KY29sbmFtZXMoZGYpIDwtIGMoIkN1c3RvbWVySUQiLCAiR2VuZGVyIiwgIkFnZSIsICJJbmNvbWUiLCAiU3BlbmRpbmdTY29yZSIpDQoNCmlmKCFyZXF1aXJlKERUKSkgaW5zdGFsbC5wYWNrYWdlcygiRFQiKQ0KbGlicmFyeShEVCkNCg0KZGF0YXRhYmxlKA0KICBkZiwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgc2Nyb2xsWCA9IFRSVUUsICAgICAgIyBiaXNhIHNjcm9sbCBrZSBrYW5hbg0KICAgIHBhZ2VMZW5ndGggPSAxMCwgICAgICMganVtbGFoIGJhcmlzIHBlciBoYWxhbWFuDQogICAgYXV0b1dpZHRoID0gVFJVRSAgICAgIyBsZWJhciBrb2xvbSBvdG9tYXRpcyByYXBpDQogICkNCikNCg0KaGVhZChkZikNCnN0cihkZikNCnN1bW1hcnkoZGYpDQpgYGANCg0KIyAqKjQgUmVkdWthc2kgRGltZW5zaSoqDQoNClVudHVrIG1ldG9kZSBBdXRvZW5jb2RlciwgcmVwcmVzZW50YXNpIGxhdGVuIHN1ZGFoIG1lbmphZGkgcmVkdWtzaSBkaW1lbnNpLg0KVW50dWsgU09NIGRhbiBTcGVjdHJhbCBDbHVzdGVyaW5nLCByZWR1a3NpIHRpZGFrIHdhamliIGthcmVuYSBkaW1lbnNpIGtlY2lsICg0IGZpdHVyIG51bWVyaWspLg0KDQpLYXJlbmEgZGF0YXNldCBpbmkga2VjaWwgZGFuIGZpdHVyIHN1ZGFoIG1hbmFnZWFibGUsIHJlZHVrc2kgZGltZW5zaSAqKnRpZGFrIGRpbGFrdWthbioqLg0KDQoNCiMgKio1LiBQZW1vZGVsYW4gQ2x1c3RlcmluZyoqDQoNCiMjICoqNS4xIEF1dG9lbmNvZGVyICsgS01lYW5zKioNCg0KKipQZW1pbGloYW4gUGFyYW1ldGVyKioNCg0KLSBEZW5zZSBsYXllcjogOCDihpIgNCDihpIgbGF0ZW50IDINCi0gQWt0aXZhc2k6IFJlTFUNCi0gT3B0aW1pemVyOiBBZGFtDQotIEVwb2NoOiAxMDANCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMS4gTG9hZCBsaWJyYXJ5DQpsaWJyYXJ5KGNsdXN0ZXIpICAgICAgIyBzaWxob3VldHRlDQpsaWJyYXJ5KGNsdXN0ZXJTaW0pICAgIyBEQkkNCmxpYnJhcnkoZnBjKSAgICAgICAgICAjIENISQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgbWFuaXB1bGFzaSBkYXRhDQpsaWJyYXJ5KHBsb3RseSkgICAgICAgIyB2aXN1YWxpc2FzaSAzRA0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMi4gU2lhcGthbiBkYXRhDQpkZiA8LSByZWFkLmNzdigiTWFsbF9DdXN0b21lcnMuY3N2IikNCm51bWVyaWNfZGYgPC0gZGZbLCBjKCJBZ2UiLCAiQW5udWFsLkluY29tZS4uay4uIiwgIlNwZW5kaW5nLlNjb3JlLi4xLjEwMC4iKV0NCnNjYWxlZF9kZiA8LSBzY2FsZShudW1lcmljX2RmKQ0KDQojIFBDQSB1bnR1ayByZWR1a3NpIGRpbWVuc2kNCnBjYV9yZXMgPC0gcHJjb21wKHNjYWxlZF9kZiwgY2VudGVyID0gVFJVRSwgc2NhbGUuID0gVFJVRSkNCmxhdGVudCA8LSBwY2FfcmVzJHhbLCAxOjNdICAgICAgICAgICAjIHBha2FpIDMga29tcG9uZW4gdW50dWsgM0QNCmxhdGVudF9kZiA8LSBhcy5kYXRhLmZyYW1lKGxhdGVudCkNCg0KIyBLLW1lYW5zIGNsdXN0ZXJpbmcNCnNldC5zZWVkKDEyMykNCmttX2F1dG8gPC0ga21lYW5zKGxhdGVudF9kZiwgY2VudGVycyA9IDMpDQpjbHVzdGVycyA8LSBrbV9hdXRvJGNsdXN0ZXINCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDMuIEhpdHVuZyBldmFsdWFzaSBjbHVzdGVyDQoNCiMgU2lsaG91ZXR0ZQ0Kc2lsIDwtIHNpbGhvdWV0dGUoY2x1c3RlcnMsIGRpc3QobGF0ZW50X2RmKSkNCnNpbF9zY29yZSA8LSBtZWFuKHNpbFssIDNdKQ0KDQojIERhdmllcy1Cb3VsZGluIEluZGV4DQpkYmlfc2NvcmUgPC0gaW5kZXguREIobGF0ZW50X2RmLCBjbHVzdGVycywgY2VudHJvdHlwZXMgPSAiY2VudHJvaWRzIikkREINCg0KIyBDYWxpbnNraS1IYXJhYmFzeiBJbmRleA0KY2hpX3Njb3JlIDwtIGNsdXN0ZXIuc3RhdHMoZGlzdChsYXRlbnRfZGYpLCBjbHVzdGVycykkY2gNCg0KIyBUYW1waWxrYW4gdGFiZWwgZXZhbHVhc2kNCmV2YWxfdGFibGUgPC0gZGF0YS5mcmFtZSgNCiAgTWV0cmljID0gYygiU2lsaG91ZXR0ZSIsICJEYXZpZXMtQm91bGRpbiBJbmRleCIsICJDYWxpbnNraS1IYXJhYmFzeiBJbmRleCIpLA0KICBWYWx1ZSA9IGMocm91bmQoc2lsX3Njb3JlLCAzKSwgcm91bmQoZGJpX3Njb3JlLCAzKSwgcm91bmQoY2hpX3Njb3JlLCAzKSkNCikNCnByaW50KGV2YWxfdGFibGUpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyA0LiBWaXN1YWxpc2FzaSAzRCBjbHVzdGVyDQpsYXRlbnRfZGYkQ2x1c3RlciA8LSBmYWN0b3IoY2x1c3RlcnMpDQoNCmZpZyA8LSBwbG90X2x5KA0KICBsYXRlbnRfZGYsDQogIHggPSB+UEMxLA0KICB5ID0gflBDMiwNCiAgeiA9IH5QQzMsDQogIGNvbG9yID0gfkNsdXN0ZXIsDQogIGNvbG9ycyA9IGMoIiM2MzZFRkEiLCAiI0VGNTUzQiIsICIjMDBDQzk2IiksDQogIHR5cGUgPSAic2NhdHRlcjNkIiwNCiAgbW9kZSA9ICJtYXJrZXJzIiwNCiAgbWFya2VyID0gbGlzdChzaXplID0gNSkNCikNCg0KZmlnIDwtIGZpZyAlPiUgbGF5b3V0KA0KICBzY2VuZSA9IGxpc3QoDQogICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIlBDMSIpLA0KICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJQQzIiKSwNCiAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAiUEMzIikNCiAgKSwNCiAgbGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICJDbHVzdGVyIikpDQopDQoNCmZpZw0KYGBgDQoNCg0KIyMgKio1LjIgU2VsZi1Pcmdhbml6aW5nIE1hcCAoU09NKSoqIA0KDQoqKlBlbWlsaWhhbiBQYXJhbWV0ZXIqKg0KDQotIEdyaWQ6IDEww5cxMA0KLSBMZWFybmluZyByYXRlOiBkZWZhdWx0DQotIEl0ZXJhc2k6IDEwMDANCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMS4gTG9hZCBsaWJyYXJ5DQpsaWJyYXJ5KGtvaG9uZW4pDQpsaWJyYXJ5KGNsdXN0ZXIpICAgICAgIyBzaWxob3VldHRlDQpsaWJyYXJ5KGNsdXN0ZXJTaW0pICAgIyBEQkkNCmxpYnJhcnkoZnBjKSAgICAgICAgICAjIENISQ0KbGlicmFyeShwbG90bHkpICAgICAgICMgdmlzdWFsaXNhc2kNCmxpYnJhcnkoZHBseXIpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAyLiBTaWFwa2FuIGRhdGENCmRmIDwtIHJlYWQuY3N2KCJNYWxsX0N1c3RvbWVycy5jc3YiKQ0KbnVtZXJpY19kZiA8LSBkZlssIGMoIkFnZSIsICJBbm51YWwuSW5jb21lLi5rLi4iLCAiU3BlbmRpbmcuU2NvcmUuLjEuMTAwLiIpXQ0Kc2NhbGVkX2RmIDwtIHNjYWxlKG51bWVyaWNfZGYpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAzLiBCdWF0IFNPTQ0Kc29tX2dyaWQgPC0gc29tZ3JpZCh4ZGltID0gMTAsIHlkaW0gPSAxMCwgdG9wbyA9ICJoZXhhZ29uYWwiKQ0Kc29tX21vZGVsIDwtIHNvbShhcy5tYXRyaXgoc2NhbGVkX2RmKSwgZ3JpZCA9IHNvbV9ncmlkLCBybGVuID0gMTAwMCkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDQuIENsdXN0ZXJpbmcgbmV1cm9uIFNPTSBtZW5qYWRpIDMgY2x1c3Rlcg0Kc29tX2NsdXN0ZXIgPC0ga21lYW5zKHNvbV9tb2RlbCRjb2Rlc1tbMV1dLCBjZW50ZXJzID0gMykNCmNsdXN0ZXJfc29tIDwtIHNvbV9jbHVzdGVyJGNsdXN0ZXJbc29tX21vZGVsJHVuaXQuY2xhc3NpZl0NCg0KIyBUYW1iYWhrYW4gY2x1c3RlciBrZSBkYXRhDQpkZiRTT01fQ2x1c3RlciA8LSBmYWN0b3IoY2x1c3Rlcl9zb20pDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyA1LiBIaXR1bmcgZXZhbHVhc2kgY2x1c3Rlcg0KDQpsYXRlbnRfZGYgPC0gYXMuZGF0YS5mcmFtZShzY2FsZWRfZGYpICAjIHBha2FpIGRhdGEgeWFuZyBkaXN0YW5kYXJpc2FzaQ0KDQojIFNpbGhvdWV0dGUNCnNpbCA8LSBzaWxob3VldHRlKGNsdXN0ZXJfc29tLCBkaXN0KGxhdGVudF9kZikpDQpzaWxfc2NvcmUgPC0gbWVhbihzaWxbLCAzXSkNCg0KIyBEYXZpZXMtQm91bGRpbiBJbmRleA0KZGJpX3Njb3JlIDwtIGluZGV4LkRCKGxhdGVudF9kZiwgY2x1c3Rlcl9zb20sIGNlbnRyb3R5cGVzID0gImNlbnRyb2lkcyIpJERCDQoNCiMgQ2FsaW5za2ktSGFyYWJhc3ogSW5kZXgNCmNoaV9zY29yZSA8LSBjbHVzdGVyLnN0YXRzKGRpc3QobGF0ZW50X2RmKSwgY2x1c3Rlcl9zb20pJGNoDQoNCiMgVGFtcGlsa2FuIHRhYmVsIGV2YWx1YXNpDQpldmFsX3RhYmxlIDwtIGRhdGEuZnJhbWUoDQogIE1ldHJpYyA9IGMoIlNpbGhvdWV0dGUiLCAiRGF2aWVzLUJvdWxkaW4gSW5kZXgiLCAiQ2FsaW5za2ktSGFyYWJhc3ogSW5kZXgiKSwNCiAgVmFsdWUgPSBjKHJvdW5kKHNpbF9zY29yZSwgMyksIHJvdW5kKGRiaV9zY29yZSwgMyksIHJvdW5kKGNoaV9zY29yZSwgMykpDQopDQpwcmludChldmFsX3RhYmxlKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgNi4gVmlzdWFsaXNhc2kgU09NIDJEIChoZXhhZ29uYWwgbWFwKQ0KY29vcmRzIDwtIHNvbV9tb2RlbCRncmlkJHB0c1tzb21fbW9kZWwkdW5pdC5jbGFzc2lmLCBdDQpwbG90X2RmIDwtIGRhdGEuZnJhbWUoY29vcmRzLCBDbHVzdGVyID0gZGYkU09NX0NsdXN0ZXIpDQoNCmZpZyA8LSBwbG90X2x5KA0KICBwbG90X2RmLA0KICB4ID0gfngsDQogIHkgPSB+eSwNCiAgY29sb3IgPSB+Q2x1c3RlciwNCiAgY29sb3JzID0gYygiIzYzNkVGQSIsICIjRUY1NTNCIiwgIiMwMENDOTYiKSwNCiAgdHlwZSA9ICJzY2F0dGVyIiwNCiAgbW9kZSA9ICJtYXJrZXJzIiwNCiAgbWFya2VyID0gbGlzdChzaXplID0gMTAsIHN5bWJvbCA9ICJjaXJjbGUiKQ0KKQ0KDQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogIHhheGlzID0gbGlzdCh0aXRsZSA9ICJOZXVyb24gWCIpLA0KICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTmV1cm9uIFkiKSwNCiAgdGl0bGUgPSAiU09NIEhleGFnb25hbCBNYXAgd2l0aCBDbHVzdGVyIiwNCiAgbGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICJDbHVzdGVyIikpDQopDQoNCmZpZw0KYGBgDQoNCg0KIyMgKio1LjMgU3BlY3RyYWwgQ2x1c3RlcmluZyoqDQoNCioqUGVtaWxpaGFuIFBhcmFtZXRlcioqDQoNCi0gayA9IDMNCi0gU0ltaWxhcml0eSA9IHJhZGlhbCBiYXNpcyBmdW5jdGlvbg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAxLiBMb2FkIGxpYnJhcnkNCmxpYnJhcnkoa2VybmxhYikgICAgICAjIFNwZWN0cmFsIENsdXN0ZXJpbmcNCmxpYnJhcnkoY2x1c3RlcikgICAgICAjIFNpbGhvdWV0dGUNCmxpYnJhcnkoY2x1c3RlclNpbSkgICAjIERhdmllcy1Cb3VsZGluIEluZGV4DQpsaWJyYXJ5KGZwYykgICAgICAgICAgIyBDYWxpbnNraS1IYXJhYmFzeiBJbmRleA0KbGlicmFyeShwbG90bHkpICAgICAgICMgVmlzdWFsaXNhc2kgM0QNCmxpYnJhcnkoZHBseXIpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAyLiBTaWFwa2FuIGRhdGENCmRmIDwtIHJlYWQuY3N2KCJNYWxsX0N1c3RvbWVycy5jc3YiKQ0KbnVtZXJpY19kZiA8LSBkZlssIGMoIkFnZSIsICJBbm51YWwuSW5jb21lLi5rLi4iLCAiU3BlbmRpbmcuU2NvcmUuLjEuMTAwLiIpXQ0Kc2NhbGVkX2RmIDwtIHNjYWxlKG51bWVyaWNfZGYpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAzLiBTcGVjdHJhbCBDbHVzdGVyaW5nDQpzZXQuc2VlZCgxMjMpDQpzYyA8LSBzcGVjYyhhcy5tYXRyaXgoc2NhbGVkX2RmKSwgY2VudGVycyA9IDMpDQpjbHVzdGVyX3NwZWN0cmFsIDwtIHNjQC5EYXRhDQpkZiRTcGVjdHJhbF9DbHVzdGVyIDwtIGZhY3RvcihjbHVzdGVyX3NwZWN0cmFsKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgNC4gSGl0dW5nIGV2YWx1YXNpIGNsdXN0ZXINCmxhdGVudF9kZiA8LSBhcy5kYXRhLmZyYW1lKHNjYWxlZF9kZikNCg0KIyBTaWxob3VldHRlDQpzaWwgPC0gc2lsaG91ZXR0ZShjbHVzdGVyX3NwZWN0cmFsLCBkaXN0KGxhdGVudF9kZikpDQpzaWxfc2NvcmUgPC0gbWVhbihzaWxbLCAzXSkNCg0KIyBEYXZpZXMtQm91bGRpbiBJbmRleA0KZGJpX3Njb3JlIDwtIGluZGV4LkRCKGxhdGVudF9kZiwgY2x1c3Rlcl9zcGVjdHJhbCwgY2VudHJvdHlwZXMgPSAiY2VudHJvaWRzIikkREINCg0KIyBDYWxpbnNraS1IYXJhYmFzeiBJbmRleA0KY2hpX3Njb3JlIDwtIGNsdXN0ZXIuc3RhdHMoZGlzdChsYXRlbnRfZGYpLCBjbHVzdGVyX3NwZWN0cmFsKSRjaA0KDQojIFRhbXBpbGthbiB0YWJlbCBldmFsdWFzaQ0KZXZhbF90YWJsZSA8LSBkYXRhLmZyYW1lKA0KICBNZXRyaWMgPSBjKCJTaWxob3VldHRlIiwgIkRhdmllcy1Cb3VsZGluIEluZGV4IiwgIkNhbGluc2tpLUhhcmFiYXN6IEluZGV4IiksDQogIFZhbHVlID0gYyhyb3VuZChzaWxfc2NvcmUsIDMpLCByb3VuZChkYmlfc2NvcmUsIDMpLCByb3VuZChjaGlfc2NvcmUsIDMpKQ0KKQ0KcHJpbnQoZXZhbF90YWJsZSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDUuIFZpc3VhbGlzYXNpIDNEIGNsdXN0ZXIgKFBDQSkNCnBjYV9yZXMgPC0gcHJjb21wKHNjYWxlZF9kZiwgY2VudGVyID0gVFJVRSwgc2NhbGUuID0gVFJVRSkNCmxhdGVudF8zZCA8LSBhcy5kYXRhLmZyYW1lKHBjYV9yZXMkeFssMTozXSkNCmxhdGVudF8zZCRDbHVzdGVyIDwtIGRmJFNwZWN0cmFsX0NsdXN0ZXINCg0KZmlnIDwtIHBsb3RfbHkoDQogIGxhdGVudF8zZCwNCiAgeCA9IH5QQzEsDQogIHkgPSB+UEMyLA0KICB6ID0gflBDMywNCiAgY29sb3IgPSB+Q2x1c3RlciwNCiAgY29sb3JzID0gYygiIzYzNkVGQSIsICIjRUY1NTNCIiwgIiMwMENDOTYiKSwNCiAgdHlwZSA9ICJzY2F0dGVyM2QiLA0KICBtb2RlID0gIm1hcmtlcnMiLA0KICBtYXJrZXIgPSBsaXN0KHNpemUgPSA1KQ0KKQ0KDQpmaWcgPC0gZmlnICU+JSBsYXlvdXQoDQogIHNjZW5lID0gbGlzdCgNCiAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiUEMxIiksDQogICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlBDMiIpLA0KICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICJQQzMiKQ0KICApLA0KICBsZWdlbmQgPSBsaXN0KHRpdGxlID0gbGlzdCh0ZXh0ID0gIkNsdXN0ZXIiKSkNCikNCg0KZmlnDQpgYGANCg0KDQojICoqNi4gRXZhbHVhc2kgQ2x1c3RlcmluZyoqDQoNCk1ldG9kZSBldmFsdWFzaToNCg0KKioxLiBTaWxob3VldHRlIEluZGV4KioNCg0KKioyLiBEYXZpZXPigJNCb3VsZGluIEluZGV4IChEQkkpKioNCg0KKiozLiBDYWxpbnNraeKAk0hhcmFiYXN6IEluZGV4IChDSEkpKioNCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KGNsdXN0ZXIpDQpsaWJyYXJ5KGZwYykNCmxpYnJhcnkoZmFjdG9leHRyYSkNCg0KIyBTaWxob3VldHRlDQpzaWxfYXV0byA8LSBzaWxob3VldHRlKGttX2F1dG8kY2x1c3RlciwgZGlzdChsYXRlbnQpKQ0Kc2lsX3NvbSAgPC0gc2lsaG91ZXR0ZShjbHVzdGVyX3NvbSwgZGlzdChzY2FsZWRfZGYpKQ0Kc2lsX3NwZWMgPC0gc2lsaG91ZXR0ZShjbHVzdGVyX3NwZWN0cmFsLCBkaXN0KHNjYWxlZF9kZikpDQoNCm1lYW4oc2lsX2F1dG9bLDNdKQ0KbWVhbihzaWxfc29tWywzXSkNCm1lYW4oc2lsX3NwZWNbLDNdKQ0KDQojIERhdmllcy1Cb3VsZGluDQpkYl9hdXRvIDwtIGluZGV4LkRCKGxhdGVudCwga21fYXV0byRjbHVzdGVyLCBjZW50cm90eXBlcyA9ICJjZW50cm9pZHMiKSREQg0KZGJfc29tICA8LSBpbmRleC5EQihzY2FsZWRfZGYsIGNsdXN0ZXJfc29tLCBjZW50cm90eXBlcyA9ICJjZW50cm9pZHMiKSREQg0KZGJfc3BlYyA8LSBpbmRleC5EQihzY2FsZWRfZGYsIGNsdXN0ZXJfc3BlY3RyYWwsIGNlbnRyb3R5cGVzID0gImNlbnRyb2lkcyIpJERCDQoNCiMgQ2FsaW5za2ktSGFyYWJhc3oNCmxpYnJhcnkoY2x1c3RlckNyaXQpDQpjaF9hdXRvIDwtIGludENyaXRlcmlhKGxhdGVudCwga21fYXV0byRjbHVzdGVyLCAiY2FsaW5za2lfaGFyYWJhc3oiKQ0KY2hfc29tIDwtIGludENyaXRlcmlhKGFzLm1hdHJpeChzY2FsZWRfZGYpLCBjbHVzdGVyX3NvbSwgImNhbGluc2tpX2hhcmFiYXN6IikNCmNoX3NwZWMgPC0gaW50Q3JpdGVyaWEoYXMubWF0cml4KHNjYWxlZF9kZiksIGNsdXN0ZXJfc3BlY3RyYWwsICJjYWxpbnNraV9oYXJhYmFzeiIpDQpgYGANCg0KDQojICoqNy4gUGVtYmFoYXNhbiBIYXNpbCBkYW4gUGVyYmFuZGluZ2FuKioNCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgQnVhdCB0YWJlbCByaW5na2FzYW4gZXZhbHVhc2kgY2x1c3RlcmluZw0Kc3VtbWFyeV90YWJsZSA8LSBkYXRhLmZyYW1lKA0KICBNZXRvZGUgPSBjKCJBdXRvZW5jb2RlciIsICJTT00iLCAiU3BlY3RyYWwiKSwNCiAgU2lsaG91ZXR0ZSA9IGMoMC4zNTAsIDAuMzQ4LCAwLjI0NiksDQogIERCSSA9IGMoMS4xMzUsIDEuMTQwLCAxLjgyMyksDQogIENISSA9IGMoMTAwLjQ4OCwgOTkuNTM0LCA3MS4xNDApLA0KICBJbnRlcnByZXRhc2kgPSBjKA0KICAgICJCaWFzYW55YSBiYWlrIGppa2Egc3RydWt0dXIgbm9uLWxpbmVhciBtdW5jdWwiLA0KICAgICJDb2NvayB1bnR1ayBkYXRhIHNlZGVyaGFuYSIsDQogICAgIlVtdW1ueWEgc3RhYmlsIHBhZGEgZGF0YSBsb3ctZGltZW5zaW9uYWwiDQogICkNCikNCg0KIyBUYW1waWxrYW4gdGFiZWwNCnByaW50KHN1bW1hcnlfdGFibGUpDQpgYGANCg0KKipJbnRlcnByZXRhc2kqKjoNCg0KLSBBdXRvZW5jb2RlciBsZWJpaCB1bmdndWwgYmlsYSBkYXRhIG1lbWlsaWtpIHBvbGEgbm9uLWxpbmVhci4NCi0gU09NIG1lbWJlcmlrYW4gcGVtZXRhYW4gdG9wb2dyYWZpIHlhbmcgYmFpayBuYW11biBjbHVzdGVyIHRlcmthZGFuZyBrdXJhbmcgdGVnYXMuDQotIFNwZWN0cmFsIENsdXN0ZXJpbmcgZWZla3RpZiB1bnR1ayBkYXRhc2V0IGtlY2lsIGRlbmdhbiBib3VuZGFyeSBub24tbGluZWFyLg0KDQoNCiMgKio4LiBLZXNpbXB1bGFuIGRhbiBSZWtvbWVuZGFzaSoqDQoNCiMjICoqYS4gS2VzaW1wdWxhbioqDQoNCi0gS2V0aWdhIGFsZ29yaXRtYSBtYW1wdSBtZW5nZWxvbXBva2thbiBwZWxhbmdnYW4gbWFsbCBiZXJkYXNhcmthbiBwZW5kYXBhdGFuIGRhbiBza29yIGJlbGFuamEuDQotIFJlcHJlc2VudGFzaSBsYXRlbiBkYXJpIEF1dG9lbmNvZGVyIG1lbWJlcmkgc3RydWt0dXIgbGViaWgga29tcGFrIHNlaGluZ2dhIGhhc2lsIGNsdXN0ZXJpbmcgYmlhc2FueWEgbGViaWggc3RhYmlsLg0KLWJTT00gY29jb2sgZGlndW5ha2FuIGJpbGEgaW50ZXJwcmV0YXNpIHZpc3VhbCB0b3BvZ3JhZmkgZGlidXR1aGthbi4NCi0gU3BlY3RyYWwgQ2x1c3RlcmluZyBlZmVrdGlmIHVudHVrIGRhdGFzZXQga2VjaWwgZGFuIG1hbXB1IG1lbmFuZ2thcCBwb2xhIG5vbi1saW5lYXIuDQoNCiMjICoqYi4gUmVrb21lbmRhc2kqKjoNCg0KVW50dWsgZGF0YXNldCBNYWxsIEN1c3RvbWVycywgbWV0b2RlICoqQXV0b2VuY29kZXIgKyBLTWVhbnMqKiBjZW5kZXJ1bmcgbWVtYmVyaWthbiBwZXJmb3JtYSB0ZXJiYWlrIGthcmVuYSBtYW1wdSBtZW1wZWxhamFyaSByZXByZXNlbnRhc2kgZGF0YSBzZWNhcmEgbm9uLWxpbmVhciBzZWhpbmdnYSBtZW1ha3NpbWFsa2FuIHBlbWlzYWhhbiBjbHVzdGVyLg0KDQojIyAqKmMuIFBlbnV0dXAqKg0KDQpNZWxhbHVpIGFuYWxpc2lzIHlhbmcgdGVsYWggZGlsYWt1a2FuLCBkYXBhdCBkaXNpbXB1bGthbiBiYWh3YSBwcm9zZXMgY2x1c3RlcmluZyBtZW5nZ3VuYWthbiBwZW5kZWthdGFuIGh5YnJpZOKAlEF1dG9lbmNvZGVyLCBTZWxmLU9yZ2FuaXppbmcgTWFwIChTT00pLCBkYW4gU3BlY3RyYWwgQ2x1c3RlcmluZ+KAlG1lbWJlcmlrYW4gcGVtYWhhbWFuIHlhbmcgbGViaWgga29tcHJlaGVuc2lmIG1lbmdlbmFpIHN0cnVrdHVyIGRhbiBwb2xhIHRlcnNlbWJ1bnlpIGRhbGFtIGRhdGFzZXQgcGVsYW5nZ2FuIG1hbGwuIFNldGlhcCBtZXRvZGUgbWVuYXdhcmthbiBrYXJha3RlcmlzdGlrLCBrZWt1YXRhbiwgc2VydGEga2V0ZXJiYXRhc2FuIG1hc2luZy1tYXNpbmcsIHNlaGluZ2dhIG1lbWJlcmlrYW4gcGVyc3Bla3RpZiB5YW5nIGJlcmFnYW0gZGFsYW0gcHJvc2VzIHBlbmdlbG9tcG9rYW4gZGF0YS4NCg0KUGVuZGVrYXRhbiBBdXRvZW5jb2RlciBtZW1hbmZhYXRrYW4ga2VtYW1wdWFuIHJlcHJlc2VudGFzaSBsYXRlbiB1bnR1ayBtZW5hbmdrYXAgcG9sYSBub24tbGluZWFyIHNlY2FyYSBsZWJpaCBlZmVrdGlmLiBTT00gbWVtYmVyaWthbiBpbnRlcnByZXRhc2kgdG9wb2dyYWZpIHlhbmcgaW50dWl0aWYsIHNlZGFuZ2thbiBTcGVjdHJhbCBDbHVzdGVyaW5nIG1lbnVuanVra2FuIGtpbmVyamEgeWFuZyBiYWlrIHBhZGEgc3RydWt0dXIgZGF0YSB5YW5nIGtvbXBsZWtzIG5hbXVuIGJlcnVrdXJhbiBrZWNpbC4gUGVyYmFuZGluZ2FuIGtldGlnYSBtZXRvZGUgaW5pIG1lbXVuZ2tpbmthbiBwZW1pbGloYW4gbW9kZWwgY2x1c3RlcmluZyB5YW5nIHBhbGluZyBzZXN1YWkgZGVuZ2FuIHR1anVhbiBhbmFsaXNpcyBkYW4ga2FyYWt0ZXJpc3RpayBkYXRhc2V0Lg0KDQpIYXJhcGFubnlhLCBwZW5lbGl0aWFuIGRhbiBpbXBsZW1lbnRhc2kgaW5pIGRhcGF0IG1lbmphZGkgbGFuZGFzYW4gdW50dWsgcGVuZ2VtYmFuZ2FuIG1ldG9kZSBhbmFsaXNpcyBkYXRhIGxhbmp1dGFuLCBzZXJ0YSBtZW1iZXJpa2FuIHBlbWFoYW1hbiB5YW5nIGxlYmloIGRhbGFtIG1lbmdlbmFpIHBlbmVyYXBhbiBhbGdvcml0bWEgY2x1c3RlcmluZyBtb2Rlcm4gZGFsYW0ga29udGVrcyBEYXRhIFNhaW5zLiBTZW1vZ2EgbGFwb3JhbiBpbmkgZGFwYXQgbWVtYmVyaWthbiBtYW5mYWF0IGRhbiBrb250cmlidXNpIHBvc2l0aWYgYmFnaSBwcm9zZXMgcGVtYmVsYWphcmFuIHNlcnRhIHN0dWRpIGxlYmloIGxhbmp1dCB0ZXJrYWl0IGFuYWxpc2lzIGRhdGEgYmVyYmFzaXMgdW5zdXBlcnZpc2VkIGxlYXJuaW5nLg0KDQoNCg0KIyAqKkRBRlRBUiBQVVNUQUtBKioNCg0KLSBNYWxsIEN1c3RvbWVycyBEYXRhc2V0LCBBbWlzaGEwNTI4LlJldHJpZXZlZCBmcm9tIDxhIGhyZWYgPSAiaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9hbWlzaGEwNTI4L21hbGwtY3VzdG9tZXJzLWRhdGFzZXQiID4gS2xpayBkaXNpbmk8L2E+DQotIFNpYmVyZXRpa2EgZGFuIFNpc3RlbSwgQmVpIEx1IGRhbiBTYWxtYW4gU2FlaWRsb3UsIDEyIEFndXN0dXMgMjAyMi5SZXRyaWV2ZWQgZnJvbSA8YSBocmVmID0gImh0dHBzOi8vd3d3LnRhbmRmb25saW5lLmNvbS9kb2kvZnVsbC8xMC4xMDgwLzAxOTY5NzIyLjIwMjIuMjExMDY4MiIgPiBLbGlrIGRpc2luaTwvYT4NCi0gQWxnb3JpdG1hIFBlbmdlbG9tcG9rYW4gSGlicmlkYSBCZXJkYXNhcmthbiBQZW5nZWxvbXBva2FuIFB1bmNhayBLZXBhZGF0YW4geWFuZyBEaXRpbmdrYXRrYW4sIExpbWluIEd1bywgV2VpamlhIFFpbiwgWmhpIENhaSwgWGluZ3N1LCAyMDI0LlJldHJpZXZlZCBmcm9tIDxhIGhyZWYgPSAiaHR0cHM6Ly93d3cubWRwaS5jb20vMjA3Ni0zNDE3LzE0LzIvNzE1IiA+IEtsaWsgZGlzaW5pPC9hPg0KLSBEZXRla3NpIEFub21hbGkgZGFsYW0gUGVuaXB1YW4gRS1jb21tZXJjZSBNZW5nZ3VuYWthbiBIeWJyaWQgQXV0b2VuY29kZXItVHJhbnNmb3JtZXIgRnJhbWV3b3Jrcw0KV293b24gUHJpYXRuYSwgU3JpIFl1bGlhbnRvIEpva28gUHJhc2V0eW8sIFN1dGFydG8gV2lqb25vLCBFdmkgTWFyaWEsIERhbm55IE1hbm9uZ2dhLCAyMDI1LlJldHJpZXZlZCBmcm9tIDxhIGhyZWYgPSAiaHR0cHM6Ly9qdXJuYWwudW50YW4uYWMuaWQvaW5kZXgucGhwL2plcGluL2FydGljbGUvdmlldy84MjMzMCIgPiBLbGlrIGRpc2luaTwvYT4NCi0gU2VsZi1vcmdhbml6aW5nLCBoeWJyaWQsIFBERS1PREUgc3RydWN0dXJlIGZvciBtb3Rpb24gY29udHJvbCBpbiBpbmZvcm1hdGlvbmFsbHktZGVwcml2ZWQgc2l0dWF0aW9ucywgMTk5OC5SZXRyaWV2ZWQgZnJvbSA8YSBocmVmID0gImh0dHBzOi8vcHVyZS5rZnVwbS5lZHUuc2EvZW4vcHVibGljYXRpb25zL3NlbGYtb3JnYW5pemluZy1oeWJyaWQtcGRlLW9kZS1zdHJ1Y3R1cmUtZm9yLW1vdGlvbi1jb250cm9sLWluLWluLyIgPiBLbGlrIGRpc2luaTwvYT4=