Tugas Individu

Praktikum 2 Pemrograman Dasar - Pemrograman Sains Data

Foto Diri

Praktikum 2 – Sintaks dan Alur Kontrol


1 Praktikum

1.1 Tujuan

Praktikum ini bertujuan untuk:
1. Memahami dan mengimplementasikan pernyataan kondisional dalam pemrograman menggunakan if, if-else, dan if-elif-else.
2. Menerapkan perulangan seperti for loop, while loop, break, dan continue untuk menganalisis dataset.

Praktikum ini menggunakan dataset berikut:

ID Nama Usia Gaji Posisi Performa
1 Bagas 25 5000 Staff Baik
2 Joan 30 7000 Supervisor Sangat Baik
3 Alya 27 6500 Staff Rata-rata
4 Dwi 35 10000 Manajer Baik
5 Nabil 40 12000 Direktur Sangat Baik

1.2 Implementasi Pernyataan Kondisional

Bonus karyawan ditentukan berdasarkan performa, dengan ketentuan berikut:
- Sangat Baik → 20% dari gaji
- Baik → 10% dari gaji
- Rata-rata → 5% dari gaji

Langkah Kerja:

  1. Menggunakan if-elif-else untuk menghitung bonus berdasarkan performa karyawan.

  2. Menampilkan hasil dalam format berikut:

    "Nama: Bagas, Bonus: 500"
  3. Mengimplementasikan kode dalam Python dan R.

jawab:

a.dalam kode Phyton:

# Mebuat daftar karyawan dengan data nama, gaji, dan performany
karyawan = [
    {"Nama": "Bagas", "Gaji": 5000, "Performa": "Baik"},
    {"Nama": "Joan", "Gaji": 7000, "Performa": "Sangat Baik"},
    {"Nama": "Alya", "Gaji": 6500, "Performa": "Rata-rata"},
    {"Nama": "Dwi", "Gaji": 10000, "Performa": "Baik"},
    {"Nama": "Nabil", "Gaji": 12000, "Performa": "Sangat Baik"}
]

# Loop untuk menghitung bonusnya berdasarkan performa masing-masing karyawan
for k in karyawan:
    if k["Performa"] == "Sangat Baik":  # Kalo performanya Sangat Baik, bonusnya 20% dari gaji
        bonus = k["Gaji"] * 0.2
    elif k["Performa"] == "Baik":  # Kalo performanya Baik, bonusnya 10% dari gaji
        bonus = k["Gaji"] * 0.1
    else:  # Kalo performanya Rata-rata, bonusnya 5% dari gaji
        bonus = k["Gaji"] * 0.05
    print(f'Nama: {k["Nama"]}, Bonus: {int(bonus)}')  # Menampilkan hasil
## Nama: Bagas, Bonus: 500
## Nama: Joan, Bonus: 1400
## Nama: Alya, Bonus: 325
## Nama: Dwi, Bonus: 1000
## Nama: Nabil, Bonus: 2400

penjelasan: Kode Python ini bertujuan untuk menghitung bonus karyawan berdasarkan performa mereka. Data karyawan disimpan dalam list of dictionaries, yang berisi nama, gaji, dan performa. Program menggunakan loop for untuk membaca setiap karyawan. Variabel k merepresentasikan setiap karyawan dalam daftar. Kemudian, struktur if-elif-else digunakan untuk menentukan besar bonus berdasarkan performa. Setelah itu, hasilnya ditampilkan dalam format yang jelas.Perintah ini mencetak nama karyawan dan jumlah bonusnya, dengan int(bonus) memastikan hasil dalam angka bulat.

b. dalam kode r :

# Bikin data karyawan dalam bentuk dataframe
karyawan <- data.frame(
  Nama = c("Bagas", "Joan", "Alya", "Dwi", "Nabil"),  # Nama karyawan
  Gaji = c(5000, 7000, 6500, 10000, 12000),  # Gaji masing-masing karyawan
  Performa = c("Baik", "Sangat Baik", "Rata-rata", "Baik", "Sangat Baik")  # Kategori performa
)

# Loop buat ngitung bonus tiap karyawan berdasarkan performanya
for (k in 1:nrow(karyawan)) {  
  if (karyawan$Performa[k] == "Sangat Baik") {  # Kalo performanya "Sangat Baik", bonusnya 20% dari gaji
    bonus <- karyawan$Gaji[k] * 0.2  
  } else if (karyawan$Performa[k] == "Baik") {  # Kalo "Baik", bonusnya 10% dari gaji
    bonus <- karyawan$Gaji[k] * 0.1  
  } else {  # Kalau "Rata-rata", bonusnya 5% dari gaji
    bonus <- karyawan$Gaji[k] * 0.05  
  }
  
  # Nampilin hasilnya biar bisa dicek
  cat("Nama:", karyawan$Nama[k], ", Bonus:", as.integer(bonus), "\n")  
}
## Nama: Bagas , Bonus: 500 
## Nama: Joan , Bonus: 1400 
## Nama: Alya , Bonus: 325 
## Nama: Dwi , Bonus: 1000 
## Nama: Nabil , Bonus: 2400

penjelasan : Kode R ini bertujuan untuk menghitung bonus karyawan berdasarkan performa mereka. Data karyawan disimpan dalam data frame, yang berisi nama, gaji, dan performa. Program menggunakan loop for untuk membaca setiap karyawan. Variabel k merepresentasikan indeks setiap karyawan dalam data frame. Kemudian, struktur if-else digunakan untuk menentukan besar bonus berdasarkan performa. Setelah itu, hasilnya ditampilkan dalam format yang jelas. Perintah ini mencetak nama karyawan dan jumlah bonusnya, dengan as.integer() memastikan hasil dalam angka bulat.


1.3 Implementasi Perulangan (For & While Loop)

1.3.1. Menggunakan for loop untuk menampilkan karyawan dengan gaji lebih dari 6000.

Output yang diharapkan:
Nama: Joan, Gaji: 7000 Nama: Alya, Gaji: 6500 Nama: Dwi, Gaji: 10000 Nama: Nabil, Gaji: 12000
jawab:

a.dalam kode Phyton:

# Membuat daftar karyawan dengan data nama, gaji, dan performa
karyawan = [
    {"Nama": "Bagas", "Gaji": 5000, "Performa": "Baik"},
    {"Nama": "Joan", "Gaji": 7000, "Performa": "Sangat Baik"},
    {"Nama": "Alya", "Gaji": 6500, "Performa": "Rata-rata"},
    {"Nama": "Dwi", "Gaji": 10000, "Performa": "Baik"},
    {"Nama": "Nabil", "Gaji": 12000, "Performa": "Sangat Baik"}
]

# Loop untuk menampilkan karyawan yang memiliki gaji lebih dari 6000
for k in karyawan:
    if k["Gaji"] > 6000:  # Hanya mencetak karyawan yang gajinya lebih dari 6000
        print(f'Nama: {k["Nama"]}, Gaji: {k["Gaji"]}')
## Nama: Joan, Gaji: 7000
## Nama: Alya, Gaji: 6500
## Nama: Dwi, Gaji: 10000
## Nama: Nabil, Gaji: 12000

pejelasan: Kode Python ini digunakan untuk menampilkan karyawan yang memiliki gaji lebih dari 6000. Data karyawan disimpan dalam list of dictionaries, yang berisi nama, gaji, dan performa. Program menggunakan loop for untuk membaca setiap karyawan, lalu menggunakan struktur if untuk mengecek apakah gajinya lebih dari 6000. Jika syarat tersebut terpenuhi, nama dan gaji karyawan akan ditampilkan dalam format “Nama: [Nama Karyawan], Gaji: [Jumlah Gaji]”. Dengan cara ini, hanya karyawan yang memenuhi kriteria yang akan dicetak, sementara yang lainnya dilewati.

b. dalam kode r :

# Membuat data karyawan dalam bentuk data frame
karyawan <- data.frame(
  Nama = c("Bagas", "Joan", "Alya", "Dwi", "Nabil"),
  Gaji = c(5000, 7000, 6500, 10000, 12000),
  Performa = c("Baik", "Sangat Baik", "Rata-rata", "Baik", "Sangat Baik")
)

# Loop untuk menampilkan karyawan yang gajinya lebih dari 6000
for (k in 1:nrow(karyawan)) {
  if (karyawan$Gaji[k] > 6000) {  
    # Kalau gajinya lebih dari 6000, tampilkan nama dan gajinya
    cat("Nama:", karyawan$Nama[k], ", Gaji:", karyawan$Gaji[k], "\n")
  }
}
## Nama: Joan , Gaji: 7000 
## Nama: Alya , Gaji: 6500 
## Nama: Dwi , Gaji: 10000 
## Nama: Nabil , Gaji: 12000

penejelasan: Kode R ini digunakan untuk menampilkan karyawan yang memiliki gaji lebih dari 6000. Data karyawan disimpan dalam data frame, yang berisi nama, gaji, dan performa. Program menggunakan loop for untuk membaca setiap baris data dengan indeks k. Di dalam loop, struktur if digunakan untuk mengecek apakah gaji karyawan lebih dari 6000. Jika syarat tersebut terpenuhi, nama dan gaji karyawan akan ditampilkan menggunakan cat() dalam format “Nama: [Nama Karyawan], Gaji: [Jumlah Gaji]”. Dengan cara ini, hanya karyawan yang memenuhi kriteria yang akan dicetak, sementara yang lainnya dilewati.

1.3.2. Menggunakan while loop untuk menampilkan karyawan sampai menemukan posisi “Manajer”.

Output yang diharapkan:
Nama: Bagas, Posisi: Staff Nama: Joan, Posisi: Supervisor Nama: Alya, Posisi: Staff Nama: Dwi, Posisi: Manajer (Berhenti di sini)
jawab:

a.dalam kode Phyton:

# Membuat daftar karyawan dengan nama, gaji, performa, dan posisi
karyawan = [
    {"Nama": "Bagas", "Gaji": 5000, "Performa": "Baik", "Posisi": "Staff"},
    {"Nama": "Joan", "Gaji": 7000, "Performa": "Sangat Baik", "Posisi": "Supervisor"},
    {"Nama": "Alya", "Gaji": 6500, "Performa": "Rata-rata", "Posisi": "Staff"},
    {"Nama": "Dwi", "Gaji": 10000, "Performa": "Baik", "Posisi": "Manajer"},
    {"Nama": "Nabil", "Gaji": 12000, "Performa": "Sangat Baik", "Posisi": "Direktur"}
]

# Inisialisasi indeks
k = 0  # Mulai dari karyawan pertama

# Loop untuk menampilkan karyawan sampai menemukan Manajer
while k < len(karyawan):
    print(f'Nama: {karyawan[k]["Nama"]}, Posisi: {karyawan[k]["Posisi"]}')  
    
    # Jika posisi adalah "Manajer", loop berhenti
    if karyawan[k]["Posisi"] == "Manajer":
        break
    
    k += 1  # Lanjut ke karyawan berikutnya
## Nama: Bagas, Posisi: Staff
## Nama: Joan, Posisi: Supervisor
## Nama: Alya, Posisi: Staff
## Nama: Dwi, Posisi: Manajer

penjelasan: Kode Python ini digunakan untuk menampilkan daftar karyawan berdasarkan posisi mereka hingga menemukan karyawan dengan posisi Manajer. Data karyawan disimpan dalam list of dictionaries, yang berisi nama, gaji, performa, dan posisi. Program menggunakan while loop untuk membaca setiap karyawan dari indeks 0. Setiap karyawan ditampilkan dalam format “Nama: [Nama Karyawan], Posisi: [Posisi]”. Jika posisi karyawan adalah “Manajer”, program akan menghentikan loop menggunakan break, sehingga karyawan setelahnya tidak akan ditampilkan. Dengan cara ini, program hanya menampilkan karyawan hingga posisi Manajer ditemukan.

b. dalam kode r :

# Membuat data frame karyawan
karyawan <- data.frame(
  Nama = c("Bagas", "Joan", "Alya", "Dwi", "Nabil"),
  Gaji = c(5000, 7000, 6500, 10000, 12000),
  Performa = c("Baik", "Sangat Baik", "Rata-rata", "Baik", "Sangat Baik"),
  Posisi = c("Staff", "Supervisor", "Staff", "Manajer", "Direktur"),
  stringsAsFactors = FALSE
)

# Inisialisasi variabel indeks
k <- 1

# Loop while untuk menampilkan karyawan sampai menemukan Manajer
while (k <= nrow(karyawan)) {
  cat("Nama:", karyawan$Nama[k], ", Posisi:", karyawan$Posisi[k], "\n")
  
  # Jika posisi adalah "Manajer", loop berhenti
  if (karyawan$Posisi[k] == "Manajer") {
    break
  }
  
  # Tambah indeks
  k <- k + 1
}
## Nama: Bagas , Posisi: Staff 
## Nama: Joan , Posisi: Supervisor 
## Nama: Alya , Posisi: Staff 
## Nama: Dwi , Posisi: Manajer

penjelasan: Kode R ini digunakan untuk menampilkan daftar karyawan berdasarkan posisi mereka hingga menemukan karyawan dengan posisi Manajer. Data karyawan disimpan dalam data frame, yang berisi nama, gaji, performa, dan posisi. Program menggunakan while loop untuk membaca setiap baris data dengan indeks k. Setiap karyawan ditampilkan dalam format “Nama: [Nama Karyawan], Posisi: [Posisi]” menggunakan cat(). Jika posisi karyawan adalah “Manajer”, program akan menghentikan loop menggunakan break, sehingga karyawan setelahnya tidak akan ditampilkan. Dengan cara ini, program hanya mencetak daftar karyawan hingga posisi Manajer ditemukan.

1.3.3. Menggunakan break untuk menghentikan perulangan ketika menemukan karyawan dengan gaji di atas 10.000.

Output yang diharapkan:
Nama: Bagas, Gaji: 5000 Nama: Joan, Gaji: 7000 Nama: Alya, Gaji: 6500 Nama: Dwi, Gaji: 10000 (Berhenti karena Nabil memiliki gaji di atas 10.000)
jawab:

a.dalam kode Phyton:

# Membuat daftar karyawan dengan nama, gaji, performa, dan posisi
karyawan = [
    {"Nama": "Bagas", "Gaji": 5000, "Performa": "Baik", "Posisi": "Staff"},
    {"Nama": "Joan", "Gaji": 7000, "Performa": "Sangat Baik", "Posisi": "Supervisor"},
    {"Nama": "Alya", "Gaji": 6500, "Performa": "Rata-rata", "Posisi": "Staff"},
    {"Nama": "Dwi", "Gaji": 10000, "Performa": "Baik", "Posisi": "Manajer"},
    {"Nama": "Nabil", "Gaji": 12000, "Performa": "Sangat Baik", "Posisi": "Direktur"}
]

# Loop untuk menampilkan karyawan sampai menemukan gaji di atas 10.000
for k in karyawan:
    # Jika gaji lebih dari 10.000, hentikan loop sebelum mencetak
    if k["Gaji"] > 10000:
        break

    print(f'Nama: {k["Nama"]}, Gaji: {k["Gaji"]}')
## Nama: Bagas, Gaji: 5000
## Nama: Joan, Gaji: 7000
## Nama: Alya, Gaji: 6500
## Nama: Dwi, Gaji: 10000

penjelasan: Kode Python ini digunakan untuk menampilkan daftar karyawan hingga menemukan karyawan dengan gaji di atas 10.000. Data karyawan disimpan dalam list of dictionaries, yang mencakup nama, gaji, performa, dan posisi. Program menggunakan loop for untuk membaca setiap data karyawan. Saat membaca setiap elemen, program memeriksa apakah gaji karyawan lebih dari 10.000. Jika kondisi tersebut terpenuhi, loop akan dihentikan menggunakan break, sehingga karyawan dengan gaji lebih tinggi tidak akan ditampilkan. Dengan pendekatan ini, program hanya mencetak daftar karyawan hingga menemukan batas gaji yang ditentukan.

b. dalam kode r :

# Membuat daftar karyawan dengan nama, gaji, performa, dan posisi
karyawan <- data.frame(
  Nama = c("Bagas", "Joan", "Alya", "Dwi", "Nabil"),
  Gaji = c(5000, 7000, 6500, 10000, 12000),
  Performa = c("Baik", "Sangat Baik", "Rata-rata", "Baik", "Sangat Baik"),
  Posisi = c("Staff", "Supervisor", "Staff", "Manajer", "Direktur")
)

# Loop untuk menampilkan karyawan sampai menemukan gaji di atas 10.000
for (k in 1:nrow(karyawan)) {
  # Jika gaji lebih dari 10.000, hentikan loop sebelum mencetak
  if (karyawan$Gaji[k] > 10000) {
    break
  }
  
  cat("Nama:", karyawan$Nama[k], ", Gaji:", karyawan$Gaji[k], "\n")
}
## Nama: Bagas , Gaji: 5000 
## Nama: Joan , Gaji: 7000 
## Nama: Alya , Gaji: 6500 
## Nama: Dwi , Gaji: 10000

penjelasan: Kode R ini bertujuan untuk menampilkan daftar karyawan hingga menemukan karyawan dengan gaji di atas 10.000. Data karyawan disimpan dalam data frame, yang berisi informasi nama, gaji, performa, dan posisi. Program menggunakan loop for untuk membaca setiap baris data berdasarkan indeks. Dalam setiap iterasi, program memeriksa apakah gaji karyawan lebih dari 10.000. Jika kondisi tersebut terpenuhi, loop dihentikan dengan break, sehingga karyawan dengan gaji lebih tinggi tidak akan ditampilkan. Dengan metode ini, hanya karyawan dengan gaji di bawah atau sama dengan 10.000 yang akan dicetak.

1.3.4. Menggunakan continue untuk melewati karyawan dengan performa “Rata-rata”.

Output yang diharapkan:
Nama: Bagas, Performa: Baik Nama: Joan, Performa: Sangat Baik Nama: Dwi, Performa: Baik Nama: Nabil, Performa: Sangat Baik (Alya dilewati karena performanya "Rata-rata")
jawab:

a.dalam kode Phyton:

# Membuat daftar karyawan
karyawan = [
    {"Nama": "Bagas", "Gaji": 5000, "Performa": "Baik", "Posisi": "Staff"},
    {"Nama": "Joan", "Gaji": 7000, "Performa": "Sangat Baik", "Posisi": "Supervisor"},
    {"Nama": "Alya", "Gaji": 6500, "Performa": "Rata-rata", "Posisi": "Staff"},
    {"Nama": "Dwi", "Gaji": 10000, "Performa": "Baik", "Posisi": "Manajer"},
    {"Nama": "Nabil", "Gaji": 12000, "Performa": "Sangat Baik", "Posisi": "Direktur"}
]

for k in karyawan:
    if k["Performa"] == "Rata-rata":
        continue
    print(f'Nama: {k["Nama"]}, Performa: {k["Performa"]}')
## Nama: Bagas, Performa: Baik
## Nama: Joan, Performa: Sangat Baik
## Nama: Dwi, Performa: Baik
## Nama: Nabil, Performa: Sangat Baik

penjelasan: Kode Python ini bertujuan untuk menampilkan daftar karyawan dengan mengecualikan mereka yang memiliki performa “Rata-rata”. Data karyawan disimpan dalam bentuk list of dictionaries, yang berisi informasi nama, gaji, performa, dan posisi. Program menggunakan loop for untuk membaca setiap elemen dalam daftar karyawan. Dalam setiap iterasi, program memeriksa apakah nilai “Performa” adalah “Rata-rata”. Jika kondisi ini terpenuhi, maka perintah continue akan dilewati, sehingga karyawan tersebut tidak akan ditampilkan. Dengan metode ini, hanya karyawan dengan performa “Baik” atau “Sangat Baik” yang dicetak dalam output.

b. dalam kode r :

# Membuat data frame karyawan
karyawan <- data.frame(
  Nama = c("Bagas", "Joan", "Alya", "Dwi", "Nabil"),
  Gaji = c(5000, 7000, 6500, 10000, 12000),
  Performa = c("Baik", "Sangat Baik", "Rata-rata", "Baik", "Sangat Baik"),
  Posisi = c("Staff", "Supervisor", "Staff", "Manajer", "Direktur"),
  stringsAsFactors = FALSE
)

for (k in 1:nrow(karyawan)) {
  if(karyawan$Performa[k] == "Rata-rata") {
    next
  }
  cat("Nama:", karyawan$Nama[k], ", Performa:", karyawan$Performa[k], "\n")
}
## Nama: Bagas , Performa: Baik 
## Nama: Joan , Performa: Sangat Baik 
## Nama: Dwi , Performa: Baik 
## Nama: Nabil , Performa: Sangat Baik

penjelasan: Kode R ini bertujuan untuk menampilkan daftar karyawan dengan mengecualikan mereka yang memiliki performa “Rata-rata”. Data karyawan disimpan dalam bentuk data frame, yang berisi informasi nama, gaji, performa, dan posisi. Program menggunakan loop for untuk membaca setiap baris dalam data frame berdasarkan indeks. Dalam setiap iterasi, program memeriksa apakah nilai “Performa” adalah “Rata-rata”. Jika kondisi ini terpenuhi, maka perintah next akan dilewati, sehingga karyawan tersebut tidak akan ditampilkan. Dengan metode ini, hanya karyawan dengan performa “Baik” atau “Sangat Baik” yang akan dicetak dalam output. —

Kesimpulan

Berikut adalah perbedaan kode Python dan R untuk setiap nomor:

No Deskripsi Kode Python Kode R
1 Menghitung bonus berdasarkan performa Menggunakan list of dictionaries, lalu for loop dengan if-elif-else untuk menghitung bonus dan mencetak hasil. Menggunakan data frame, lalu for loop dengan if-else untuk menghitung bonus dan mencetak hasil menggunakan cat().
2 Menampilkan karyawan dengan gaji lebih dari 6000 Menggunakan for loop untuk mengecek gaji dalam list of dictionaries, lalu mencetak data jika gaji lebih dari 6000. Menggunakan for loop dalam data frame, lalu mencetak data jika gaji lebih dari 6000 menggunakan cat().
3 Menampilkan karyawan sampai menemukan posisi “Manajer” Menggunakan while loop untuk mencetak karyawan, lalu break jika posisi adalah “Manajer”. Menggunakan while loop dalam data frame, lalu break jika posisi adalah “Manajer”.
4 Menghentikan loop saat menemukan karyawan dengan gaji di atas 10.000 Menggunakan for loop, lalu break jika gaji lebih dari 10.000 sebelum mencetak. Menggunakan for loop dalam data frame, lalu break jika gaji lebih dari 10.000 sebelum mencetak.
5 Melewati karyawan dengan performa “Rata-rata” Menggunakan for loop, lalu continue jika performa adalah “Rata-rata”. Menggunakan for loop, lalu next jika performa adalah “Rata-rata”.

Sintaks (Cara Menulis Kode)

Python memiliki sintaks yang lebih rapi dan mudah dipahami, terutama karena penggunaan indentasi untuk menandai blok kode. Hal ini membuat kode Python lebih terstruktur dan nyaman dibaca. Selain itu, Python memiliki aturan yang lebih konsisten dalam penulisan, sehingga pemula pun bisa cepat memahami cara kerja bahasa ini.

Sementara itu, R memiliki sintaks yang lebih fleksibel, tetapi terkadang kurang konsisten dibanding Python. R lebih berorientasi pada analisis data, sehingga banyak fungsi bawaan yang langsung bekerja pada data tanpa perlu menulis kode terlalu panjang. Namun, fleksibilitas ini juga bisa membuat kode R sulit dipahami jika tidak ditulis dengan rapi.

Alur Kontrol (Cara Program Mengambil Keputusan & Mengulang Kode)

Baik Python maupun R mendukung struktur kontrol seperti percabangan (if-else) dan perulangan (for dan while).

  • Python lebih sering menggunakan pendekatan yang lebih ringkas seperti list comprehension, yang membuat kode lebih efisien dan mudah dibaca. Python juga memiliki banyak fitur pemrograman fungsional yang mempermudah manipulasi data dan pengolahan dalam jumlah besar.
  • R, di sisi lain, lebih mengandalkan vektorisasi dan fungsi seperti apply(), lapply(), dan sapply(), yang memungkinkan pengguna untuk memproses data dalam bentuk vektor atau matriks tanpa harus menulis perulangan eksplisit. Hal ini membuat R lebih efisien dalam analisis data, tetapi bisa terasa kurang intuitif bagi yang belum terbiasa.

Referensi

  1. Siregar, B. (n.d.). Syntax and Control Flow. Diakses pada 26 Februari 2025, dari https://bookdown.org/dsciencelabs/data_science_programming/02-Syntax-and-Control-Flow.html

  2. Data Science Labs. (2023). Syntax and Control Flow [Video]. YouTube. Diakses pada 26 Februari 2025, dari https://youtu.be/eSYeHlwDCNA

LS0tCnRpdGxlOiAiVHVnYXMgSW5kaXZpZHUgIgpzdWJ0aXRsZTogIlByYWt0aWt1bSAyIFBlbXJvZ3JhbWFuIERhc2FyIC0gUGVtcm9ncmFtYW4gU2FpbnMgRGF0YSIKYXV0aG9yOiAiT2xpdmlhIE1laWxpbmRhIERhdnRpbiBQZXNpcmVyb24iCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCIKb3V0cHV0OgogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOiAgICMgaHR0cHM6Ly9naXRodWIuY29tL2p1YmEvcm1kZm9ybWF0cwogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIHRodW1ibmFpbHM6IHRydWUKICAgIGxpZ2h0Ym94OiB0cnVlCiAgICBnYWxsZXJ5OiB0cnVlCiAgICBsaWJfZGlyOiBsaWJzCiAgICBkZl9wcmludDogInBhZ2VkIgogICAgY29kZV9mb2xkaW5nOiAic2hvdyIKICAgIGNvZGVfZG93bmxvYWQ6IHllcyAKICAgIGNzczogInN0eWxlLmNzcyIKLS0tCgo8aW1nIHNyYz0iSU1HLTIwMjUwMjEyLVdBMDAwNi5qcGciIHdpZHRoPSIzMDAiIHN0eWxlPSJkaXNwbGF5OiBibG9jazsgbWFyZ2luOiBhdXRvOyIgYWx0PSJGb3RvIERpcmkiPgotLS0KCiMgUHJha3Rpa3VtIDIg4oCTIFNpbnRha3MgZGFuIEFsdXIgS29udHJvbCAgCgotLS0KCiMjICoqMSBQcmFrdGlrdW0qKiAgCiMjIyAqKjEuMSBUdWp1YW4qKiAgClByYWt0aWt1bSBpbmkgYmVydHVqdWFuIHVudHVrOiAgCjEuIE1lbWFoYW1pIGRhbiBtZW5naW1wbGVtZW50YXNpa2FuICoqcGVybnlhdGFhbiBrb25kaXNpb25hbCoqIGRhbGFtIHBlbXJvZ3JhbWFuIG1lbmdndW5ha2FuICoqaWYsIGlmLWVsc2UsIGRhbiBpZi1lbGlmLWVsc2UqKi4gIAoyLiBNZW5lcmFwa2FuICoqcGVydWxhbmdhbioqIHNlcGVydGkgKipmb3IgbG9vcCwgd2hpbGUgbG9vcCwgYnJlYWssIGRhbiBjb250aW51ZSoqIHVudHVrIG1lbmdhbmFsaXNpcyBkYXRhc2V0LiAgCgpQcmFrdGlrdW0gaW5pIG1lbmdndW5ha2FuIGRhdGFzZXQgYmVyaWt1dDogIAoKfCBJRCB8IE5hbWEgIHwgVXNpYSB8IEdhamkgIHwgUG9zaXNpICAgICB8IFBlcmZvcm1hICAgfCAgCnwtLS0tfC0tLS0tLS18LS0tLS0tfC0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwgIAp8IDEgIHwgQmFnYXMgfCAyNSAgIHwgNTAwMCAgfCBTdGFmZiAgICAgIHwgQmFpayAgICAgICB8ICAKfCAyICB8IEpvYW4gIHwgMzAgICB8IDcwMDAgIHwgU3VwZXJ2aXNvciB8IFNhbmdhdCBCYWlrIHwgIAp8IDMgIHwgQWx5YSAgfCAyNyAgIHwgNjUwMCAgfCBTdGFmZiAgICAgIHwgUmF0YS1yYXRhICB8ICAKfCA0ICB8IER3aSAgIHwgMzUgICB8IDEwMDAwIHwgTWFuYWplciAgICB8IEJhaWsgICAgICAgfCAgCnwgNSAgfCBOYWJpbCB8IDQwICAgfCAxMjAwMCB8IERpcmVrdHVyICAgfCBTYW5nYXQgQmFpayB8ICAKCi0tLQoKIyMgKioxLjIgSW1wbGVtZW50YXNpIFBlcm55YXRhYW4gS29uZGlzaW9uYWwqKiAgCkJvbnVzIGthcnlhd2FuIGRpdGVudHVrYW4gYmVyZGFzYXJrYW4gKipwZXJmb3JtYSoqLCBkZW5nYW4ga2V0ZW50dWFuIGJlcmlrdXQ6ICAKLSAqKlNhbmdhdCBCYWlrKiog4oaSIDIwJSBkYXJpIGdhamkgIAotICoqQmFpayoqIOKGkiAxMCUgZGFyaSBnYWppICAKLSAqKlJhdGEtcmF0YSoqIOKGkiA1JSBkYXJpIGdhamkgIAoKIyMjICoqTGFuZ2thaCBLZXJqYToqKiAgCjEuIE1lbmdndW5ha2FuICoqaWYtZWxpZi1lbHNlKiogdW50dWsgbWVuZ2hpdHVuZyBib251cyBiZXJkYXNhcmthbiBwZXJmb3JtYSBrYXJ5YXdhbi4gIAoyLiBNZW5hbXBpbGthbiBoYXNpbCBkYWxhbSBmb3JtYXQgYmVyaWt1dDogIAogICBgYGAKICAgIk5hbWE6IEJhZ2FzLCBCb251czogNTAwIgogICBgYGAgIAozLiBNZW5naW1wbGVtZW50YXNpa2FuIGtvZGUgZGFsYW0gKipQeXRob24gZGFuIFIqKi4gIAoKamF3YWI6CgojIyMjIGEuZGFsYW0ga29kZSBQaHl0b246CgpgYGB7cHl0aG9ufQojIE1lYnVhdCBkYWZ0YXIga2FyeWF3YW4gZGVuZ2FuIGRhdGEgbmFtYSwgZ2FqaSwgZGFuIHBlcmZvcm1hbnkKa2FyeWF3YW4gPSBbCiAgICB7Ik5hbWEiOiAiQmFnYXMiLCAiR2FqaSI6IDUwMDAsICJQZXJmb3JtYSI6ICJCYWlrIn0sCiAgICB7Ik5hbWEiOiAiSm9hbiIsICJHYWppIjogNzAwMCwgIlBlcmZvcm1hIjogIlNhbmdhdCBCYWlrIn0sCiAgICB7Ik5hbWEiOiAiQWx5YSIsICJHYWppIjogNjUwMCwgIlBlcmZvcm1hIjogIlJhdGEtcmF0YSJ9LAogICAgeyJOYW1hIjogIkR3aSIsICJHYWppIjogMTAwMDAsICJQZXJmb3JtYSI6ICJCYWlrIn0sCiAgICB7Ik5hbWEiOiAiTmFiaWwiLCAiR2FqaSI6IDEyMDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsifQpdCgojIExvb3AgdW50dWsgbWVuZ2hpdHVuZyBib251c255YSBiZXJkYXNhcmthbiBwZXJmb3JtYSBtYXNpbmctbWFzaW5nIGthcnlhd2FuCmZvciBrIGluIGthcnlhd2FuOgogICAgaWYga1siUGVyZm9ybWEiXSA9PSAiU2FuZ2F0IEJhaWsiOiAgIyBLYWxvIHBlcmZvcm1hbnlhIFNhbmdhdCBCYWlrLCBib251c255YSAyMCUgZGFyaSBnYWppCiAgICAgICAgYm9udXMgPSBrWyJHYWppIl0gKiAwLjIKICAgIGVsaWYga1siUGVyZm9ybWEiXSA9PSAiQmFpayI6ICAjIEthbG8gcGVyZm9ybWFueWEgQmFpaywgYm9udXNueWEgMTAlIGRhcmkgZ2FqaQogICAgICAgIGJvbnVzID0ga1siR2FqaSJdICogMC4xCiAgICBlbHNlOiAgIyBLYWxvIHBlcmZvcm1hbnlhIFJhdGEtcmF0YSwgYm9udXNueWEgNSUgZGFyaSBnYWppCiAgICAgICAgYm9udXMgPSBrWyJHYWppIl0gKiAwLjA1CiAgICBwcmludChmJ05hbWE6IHtrWyJOYW1hIl19LCBCb251czoge2ludChib251cyl9JykgICMgTWVuYW1waWxrYW4gaGFzaWwKCmBgYApwZW5qZWxhc2FuOgpLb2RlIFB5dGhvbiBpbmkgYmVydHVqdWFuIHVudHVrIG1lbmdoaXR1bmcgYm9udXMga2FyeWF3YW4gYmVyZGFzYXJrYW4gcGVyZm9ybWEgbWVyZWthLiBEYXRhIGthcnlhd2FuIGRpc2ltcGFuIGRhbGFtIGxpc3Qgb2YgZGljdGlvbmFyaWVzLCB5YW5nIGJlcmlzaSBuYW1hLCBnYWppLCBkYW4gcGVyZm9ybWEuIFByb2dyYW0gbWVuZ2d1bmFrYW4gbG9vcCBmb3IgdW50dWsgbWVtYmFjYSBzZXRpYXAga2FyeWF3YW4uIFZhcmlhYmVsIGsgbWVyZXByZXNlbnRhc2lrYW4gc2V0aWFwIGthcnlhd2FuIGRhbGFtIGRhZnRhci4gS2VtdWRpYW4sIHN0cnVrdHVyIGlmLWVsaWYtZWxzZSBkaWd1bmFrYW4gdW50dWsgbWVuZW50dWthbiBiZXNhciBib251cyBiZXJkYXNhcmthbiBwZXJmb3JtYS4gU2V0ZWxhaCBpdHUsIGhhc2lsbnlhIGRpdGFtcGlsa2FuIGRhbGFtIGZvcm1hdCB5YW5nIGplbGFzLlBlcmludGFoIGluaSBtZW5jZXRhayBuYW1hIGthcnlhd2FuIGRhbiBqdW1sYWggYm9udXNueWEsIGRlbmdhbiBpbnQoYm9udXMpIG1lbWFzdGlrYW4gaGFzaWwgZGFsYW0gYW5na2EgYnVsYXQuCgojIyMjIGIuIGRhbGFtIGtvZGUgciA6CmBgYHtyfQojIEJpa2luIGRhdGEga2FyeWF3YW4gZGFsYW0gYmVudHVrIGRhdGFmcmFtZQprYXJ5YXdhbiA8LSBkYXRhLmZyYW1lKAogIE5hbWEgPSBjKCJCYWdhcyIsICJKb2FuIiwgIkFseWEiLCAiRHdpIiwgIk5hYmlsIiksICAjIE5hbWEga2FyeWF3YW4KICBHYWppID0gYyg1MDAwLCA3MDAwLCA2NTAwLCAxMDAwMCwgMTIwMDApLCAgIyBHYWppIG1hc2luZy1tYXNpbmcga2FyeWF3YW4KICBQZXJmb3JtYSA9IGMoIkJhaWsiLCAiU2FuZ2F0IEJhaWsiLCAiUmF0YS1yYXRhIiwgIkJhaWsiLCAiU2FuZ2F0IEJhaWsiKSAgIyBLYXRlZ29yaSBwZXJmb3JtYQopCgojIExvb3AgYnVhdCBuZ2l0dW5nIGJvbnVzIHRpYXAga2FyeWF3YW4gYmVyZGFzYXJrYW4gcGVyZm9ybWFueWEKZm9yIChrIGluIDE6bnJvdyhrYXJ5YXdhbikpIHsgIAogIGlmIChrYXJ5YXdhbiRQZXJmb3JtYVtrXSA9PSAiU2FuZ2F0IEJhaWsiKSB7ICAjIEthbG8gcGVyZm9ybWFueWEgIlNhbmdhdCBCYWlrIiwgYm9udXNueWEgMjAlIGRhcmkgZ2FqaQogICAgYm9udXMgPC0ga2FyeWF3YW4kR2FqaVtrXSAqIDAuMiAgCiAgfSBlbHNlIGlmIChrYXJ5YXdhbiRQZXJmb3JtYVtrXSA9PSAiQmFpayIpIHsgICMgS2FsbyAiQmFpayIsIGJvbnVzbnlhIDEwJSBkYXJpIGdhamkKICAgIGJvbnVzIDwtIGthcnlhd2FuJEdhamlba10gKiAwLjEgIAogIH0gZWxzZSB7ICAjIEthbGF1ICJSYXRhLXJhdGEiLCBib251c255YSA1JSBkYXJpIGdhamkKICAgIGJvbnVzIDwtIGthcnlhd2FuJEdhamlba10gKiAwLjA1ICAKICB9CiAgCiAgIyBOYW1waWxpbiBoYXNpbG55YSBiaWFyIGJpc2EgZGljZWsKICBjYXQoIk5hbWE6Iiwga2FyeWF3YW4kTmFtYVtrXSwgIiwgQm9udXM6IiwgYXMuaW50ZWdlcihib251cyksICJcbiIpICAKfQoKYGBgCnBlbmplbGFzYW4gOgpLb2RlIFIgaW5pIGJlcnR1anVhbiB1bnR1ayBtZW5naGl0dW5nIGJvbnVzIGthcnlhd2FuIGJlcmRhc2Fya2FuIHBlcmZvcm1hIG1lcmVrYS4gRGF0YSBrYXJ5YXdhbiBkaXNpbXBhbiBkYWxhbSAqKmRhdGEgZnJhbWUqKiwgeWFuZyBiZXJpc2kgKipuYW1hLCBnYWppLCBkYW4gcGVyZm9ybWEqKi4gUHJvZ3JhbSBtZW5nZ3VuYWthbiAqKmxvb3AgZm9yKiogdW50dWsgbWVtYmFjYSBzZXRpYXAga2FyeWF3YW4uIFZhcmlhYmVsIGBrYCBtZXJlcHJlc2VudGFzaWthbiBpbmRla3Mgc2V0aWFwIGthcnlhd2FuIGRhbGFtIGRhdGEgZnJhbWUuIEtlbXVkaWFuLCBzdHJ1a3R1ciAqKmlmLWVsc2UqKiBkaWd1bmFrYW4gdW50dWsgbWVuZW50dWthbiBiZXNhciBib251cyBiZXJkYXNhcmthbiBwZXJmb3JtYS4gU2V0ZWxhaCBpdHUsIGhhc2lsbnlhIGRpdGFtcGlsa2FuIGRhbGFtIGZvcm1hdCB5YW5nIGplbGFzLiBQZXJpbnRhaCBpbmkgbWVuY2V0YWsgKipuYW1hIGthcnlhd2FuIGRhbiBqdW1sYWggYm9udXNueWEqKiwgZGVuZ2FuICoqYXMuaW50ZWdlcigpKiogbWVtYXN0aWthbiBoYXNpbCBkYWxhbSBhbmdrYSBidWxhdC4KCgotLS0KCiMjICoqMS4zIEltcGxlbWVudGFzaSBQZXJ1bGFuZ2FuIChGb3IgJiBXaGlsZSBMb29wKSoqICAKCiMjIyAxLjMuMS4gKipNZW5nZ3VuYWthbiBmb3IgbG9vcCoqIHVudHVrIG1lbmFtcGlsa2FuIGthcnlhd2FuIGRlbmdhbiBnYWppIGxlYmloIGRhcmkgKio2MDAwKiouICAKICAgKipPdXRwdXQgeWFuZyBkaWhhcmFwa2FuOioqICAKICAgYGBgCiAgIE5hbWE6IEpvYW4sIEdhamk6IDcwMDAgIAogICBOYW1hOiBBbHlhLCBHYWppOiA2NTAwICAKICAgTmFtYTogRHdpLCBHYWppOiAxMDAwMCAgCiAgIE5hbWE6IE5hYmlsLCBHYWppOiAxMjAwMCAgCiAgIGBgYCAgCmphd2FiOgoKIyMjIyBhLmRhbGFtIGtvZGUgUGh5dG9uOgoKYGBge3B5dGhvbn0KIyBNZW1idWF0IGRhZnRhciBrYXJ5YXdhbiBkZW5nYW4gZGF0YSBuYW1hLCBnYWppLCBkYW4gcGVyZm9ybWEKa2FyeWF3YW4gPSBbCiAgICB7Ik5hbWEiOiAiQmFnYXMiLCAiR2FqaSI6IDUwMDAsICJQZXJmb3JtYSI6ICJCYWlrIn0sCiAgICB7Ik5hbWEiOiAiSm9hbiIsICJHYWppIjogNzAwMCwgIlBlcmZvcm1hIjogIlNhbmdhdCBCYWlrIn0sCiAgICB7Ik5hbWEiOiAiQWx5YSIsICJHYWppIjogNjUwMCwgIlBlcmZvcm1hIjogIlJhdGEtcmF0YSJ9LAogICAgeyJOYW1hIjogIkR3aSIsICJHYWppIjogMTAwMDAsICJQZXJmb3JtYSI6ICJCYWlrIn0sCiAgICB7Ik5hbWEiOiAiTmFiaWwiLCAiR2FqaSI6IDEyMDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsifQpdCgojIExvb3AgdW50dWsgbWVuYW1waWxrYW4ga2FyeWF3YW4geWFuZyBtZW1pbGlraSBnYWppIGxlYmloIGRhcmkgNjAwMApmb3IgayBpbiBrYXJ5YXdhbjoKICAgIGlmIGtbIkdhamkiXSA+IDYwMDA6ICAjIEhhbnlhIG1lbmNldGFrIGthcnlhd2FuIHlhbmcgZ2FqaW55YSBsZWJpaCBkYXJpIDYwMDAKICAgICAgICBwcmludChmJ05hbWE6IHtrWyJOYW1hIl19LCBHYWppOiB7a1siR2FqaSJdfScpCgpgYGAKcGVqZWxhc2FuOgpLb2RlIFB5dGhvbiBpbmkgZGlndW5ha2FuIHVudHVrIG1lbmFtcGlsa2FuIGthcnlhd2FuIHlhbmcgbWVtaWxpa2kgZ2FqaSBsZWJpaCBkYXJpICoqNjAwMCoqLiBEYXRhIGthcnlhd2FuIGRpc2ltcGFuIGRhbGFtICoqbGlzdCBvZiBkaWN0aW9uYXJpZXMqKiwgeWFuZyBiZXJpc2kgKipuYW1hLCBnYWppLCBkYW4gcGVyZm9ybWEqKi4gUHJvZ3JhbSBtZW5nZ3VuYWthbiAqKmxvb3AgZm9yKiogdW50dWsgbWVtYmFjYSBzZXRpYXAga2FyeWF3YW4sIGxhbHUgbWVuZ2d1bmFrYW4gKipzdHJ1a3R1ciBpZioqIHVudHVrIG1lbmdlY2VrIGFwYWthaCBnYWppbnlhIGxlYmloIGRhcmkgKio2MDAwKiouIEppa2Egc3lhcmF0IHRlcnNlYnV0IHRlcnBlbnVoaSwgbmFtYSBkYW4gZ2FqaSBrYXJ5YXdhbiBha2FuIGRpdGFtcGlsa2FuIGRhbGFtIGZvcm1hdCAqKiJOYW1hOiBbTmFtYSBLYXJ5YXdhbl0sIEdhamk6IFtKdW1sYWggR2FqaV0iKiouIERlbmdhbiBjYXJhIGluaSwgaGFueWEga2FyeWF3YW4geWFuZyBtZW1lbnVoaSBrcml0ZXJpYSB5YW5nIGFrYW4gZGljZXRhaywgc2VtZW50YXJhIHlhbmcgbGFpbm55YSBkaWxld2F0aS4gCgoKIyMjIyBiLiBkYWxhbSBrb2RlIHIgOgoKYGBge3J9CiMgTWVtYnVhdCBkYXRhIGthcnlhd2FuIGRhbGFtIGJlbnR1ayBkYXRhIGZyYW1lCmthcnlhd2FuIDwtIGRhdGEuZnJhbWUoCiAgTmFtYSA9IGMoIkJhZ2FzIiwgIkpvYW4iLCAiQWx5YSIsICJEd2kiLCAiTmFiaWwiKSwKICBHYWppID0gYyg1MDAwLCA3MDAwLCA2NTAwLCAxMDAwMCwgMTIwMDApLAogIFBlcmZvcm1hID0gYygiQmFpayIsICJTYW5nYXQgQmFpayIsICJSYXRhLXJhdGEiLCAiQmFpayIsICJTYW5nYXQgQmFpayIpCikKCiMgTG9vcCB1bnR1ayBtZW5hbXBpbGthbiBrYXJ5YXdhbiB5YW5nIGdhamlueWEgbGViaWggZGFyaSA2MDAwCmZvciAoayBpbiAxOm5yb3coa2FyeWF3YW4pKSB7CiAgaWYgKGthcnlhd2FuJEdhamlba10gPiA2MDAwKSB7ICAKICAgICMgS2FsYXUgZ2FqaW55YSBsZWJpaCBkYXJpIDYwMDAsIHRhbXBpbGthbiBuYW1hIGRhbiBnYWppbnlhCiAgICBjYXQoIk5hbWE6Iiwga2FyeWF3YW4kTmFtYVtrXSwgIiwgR2FqaToiLCBrYXJ5YXdhbiRHYWppW2tdLCAiXG4iKQogIH0KfQoKCmBgYApwZW5lamVsYXNhbjoKS29kZSBSIGluaSBkaWd1bmFrYW4gdW50dWsgbWVuYW1waWxrYW4ga2FyeWF3YW4geWFuZyBtZW1pbGlraSBnYWppIGxlYmloIGRhcmkgKio2MDAwKiouIERhdGEga2FyeWF3YW4gZGlzaW1wYW4gZGFsYW0gKipkYXRhIGZyYW1lKiosIHlhbmcgYmVyaXNpICoqbmFtYSwgZ2FqaSwgZGFuIHBlcmZvcm1hKiouIFByb2dyYW0gbWVuZ2d1bmFrYW4gKipsb29wIGZvcioqIHVudHVrIG1lbWJhY2Egc2V0aWFwIGJhcmlzIGRhdGEgZGVuZ2FuIGluZGVrcyBga2AuIERpIGRhbGFtIGxvb3AsICoqc3RydWt0dXIgaWYqKiBkaWd1bmFrYW4gdW50dWsgbWVuZ2VjZWsgYXBha2FoIGdhamkga2FyeWF3YW4gbGViaWggZGFyaSAqKjYwMDAqKi4gSmlrYSBzeWFyYXQgdGVyc2VidXQgdGVycGVudWhpLCBuYW1hIGRhbiBnYWppIGthcnlhd2FuIGFrYW4gZGl0YW1waWxrYW4gbWVuZ2d1bmFrYW4gKipjYXQoKSoqIGRhbGFtIGZvcm1hdCAqKiJOYW1hOiBbTmFtYSBLYXJ5YXdhbl0sIEdhamk6IFtKdW1sYWggR2FqaV0iKiouIERlbmdhbiBjYXJhIGluaSwgaGFueWEga2FyeWF3YW4geWFuZyBtZW1lbnVoaSBrcml0ZXJpYSB5YW5nIGFrYW4gZGljZXRhaywgc2VtZW50YXJhIHlhbmcgbGFpbm55YSBkaWxld2F0aS4gCiAgIAojIyMgMS4zLjIuICoqTWVuZ2d1bmFrYW4gd2hpbGUgbG9vcCoqIHVudHVrIG1lbmFtcGlsa2FuIGthcnlhd2FuIHNhbXBhaSBtZW5lbXVrYW4gcG9zaXNpICoqIk1hbmFqZXIiKiouICAKICAgKipPdXRwdXQgeWFuZyBkaWhhcmFwa2FuOioqICAKICAgYGBgCiAgIE5hbWE6IEJhZ2FzLCBQb3Npc2k6IFN0YWZmICAKICAgTmFtYTogSm9hbiwgUG9zaXNpOiBTdXBlcnZpc29yICAKICAgTmFtYTogQWx5YSwgUG9zaXNpOiBTdGFmZiAgCiAgIE5hbWE6IER3aSwgUG9zaXNpOiBNYW5hamVyIChCZXJoZW50aSBkaSBzaW5pKSAgCiAgIGBgYCAgCiAgamF3YWI6CiAgCiMjIyMgYS5kYWxhbSBrb2RlIFBoeXRvbjoKCmBgYHtweXRob259CiMgTWVtYnVhdCBkYWZ0YXIga2FyeWF3YW4gZGVuZ2FuIG5hbWEsIGdhamksIHBlcmZvcm1hLCBkYW4gcG9zaXNpCmthcnlhd2FuID0gWwogICAgeyJOYW1hIjogIkJhZ2FzIiwgIkdhamkiOiA1MDAwLCAiUGVyZm9ybWEiOiAiQmFpayIsICJQb3Npc2kiOiAiU3RhZmYifSwKICAgIHsiTmFtYSI6ICJKb2FuIiwgIkdhamkiOiA3MDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsiLCAiUG9zaXNpIjogIlN1cGVydmlzb3IifSwKICAgIHsiTmFtYSI6ICJBbHlhIiwgIkdhamkiOiA2NTAwLCAiUGVyZm9ybWEiOiAiUmF0YS1yYXRhIiwgIlBvc2lzaSI6ICJTdGFmZiJ9LAogICAgeyJOYW1hIjogIkR3aSIsICJHYWppIjogMTAwMDAsICJQZXJmb3JtYSI6ICJCYWlrIiwgIlBvc2lzaSI6ICJNYW5hamVyIn0sCiAgICB7Ik5hbWEiOiAiTmFiaWwiLCAiR2FqaSI6IDEyMDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsiLCAiUG9zaXNpIjogIkRpcmVrdHVyIn0KXQoKIyBJbmlzaWFsaXNhc2kgaW5kZWtzCmsgPSAwICAjIE11bGFpIGRhcmkga2FyeWF3YW4gcGVydGFtYQoKIyBMb29wIHVudHVrIG1lbmFtcGlsa2FuIGthcnlhd2FuIHNhbXBhaSBtZW5lbXVrYW4gTWFuYWplcgp3aGlsZSBrIDwgbGVuKGthcnlhd2FuKToKICAgIHByaW50KGYnTmFtYToge2thcnlhd2FuW2tdWyJOYW1hIl19LCBQb3Npc2k6IHtrYXJ5YXdhbltrXVsiUG9zaXNpIl19JykgIAogICAgCiAgICAjIEppa2EgcG9zaXNpIGFkYWxhaCAiTWFuYWplciIsIGxvb3AgYmVyaGVudGkKICAgIGlmIGthcnlhd2FuW2tdWyJQb3Npc2kiXSA9PSAiTWFuYWplciI6CiAgICAgICAgYnJlYWsKICAgIAogICAgayArPSAxICAjIExhbmp1dCBrZSBrYXJ5YXdhbiBiZXJpa3V0bnlhCmBgYApwZW5qZWxhc2FuOgpLb2RlIFB5dGhvbiBpbmkgZGlndW5ha2FuIHVudHVrIG1lbmFtcGlsa2FuIGRhZnRhciBrYXJ5YXdhbiBiZXJkYXNhcmthbiBwb3Npc2kgbWVyZWthIGhpbmdnYSBtZW5lbXVrYW4ga2FyeWF3YW4gZGVuZ2FuIHBvc2lzaSAqKk1hbmFqZXIqKi4gRGF0YSBrYXJ5YXdhbiBkaXNpbXBhbiBkYWxhbSAqKmxpc3Qgb2YgZGljdGlvbmFyaWVzKiosIHlhbmcgYmVyaXNpICoqbmFtYSwgZ2FqaSwgcGVyZm9ybWEsIGRhbiBwb3Npc2kqKi4gUHJvZ3JhbSBtZW5nZ3VuYWthbiAqKndoaWxlIGxvb3AqKiB1bnR1ayBtZW1iYWNhIHNldGlhcCBrYXJ5YXdhbiBkYXJpIGluZGVrcyAqKjAqKi4gU2V0aWFwIGthcnlhd2FuIGRpdGFtcGlsa2FuIGRhbGFtIGZvcm1hdCAqKiJOYW1hOiBbTmFtYSBLYXJ5YXdhbl0sIFBvc2lzaTogW1Bvc2lzaV0iKiouIEppa2EgcG9zaXNpIGthcnlhd2FuIGFkYWxhaCAqKiJNYW5hamVyIioqLCBwcm9ncmFtIGFrYW4gbWVuZ2hlbnRpa2FuIGxvb3AgbWVuZ2d1bmFrYW4gKipicmVhayoqLCBzZWhpbmdnYSBrYXJ5YXdhbiBzZXRlbGFobnlhIHRpZGFrIGFrYW4gZGl0YW1waWxrYW4uIERlbmdhbiBjYXJhIGluaSwgcHJvZ3JhbSBoYW55YSBtZW5hbXBpbGthbiBrYXJ5YXdhbiBoaW5nZ2EgcG9zaXNpICoqTWFuYWplcioqIGRpdGVtdWthbi4gCgojIyMjIGIuIGRhbGFtIGtvZGUgciA6CgpgYGB7cn0KIyBNZW1idWF0IGRhdGEgZnJhbWUga2FyeWF3YW4Ka2FyeWF3YW4gPC0gZGF0YS5mcmFtZSgKICBOYW1hID0gYygiQmFnYXMiLCAiSm9hbiIsICJBbHlhIiwgIkR3aSIsICJOYWJpbCIpLAogIEdhamkgPSBjKDUwMDAsIDcwMDAsIDY1MDAsIDEwMDAwLCAxMjAwMCksCiAgUGVyZm9ybWEgPSBjKCJCYWlrIiwgIlNhbmdhdCBCYWlrIiwgIlJhdGEtcmF0YSIsICJCYWlrIiwgIlNhbmdhdCBCYWlrIiksCiAgUG9zaXNpID0gYygiU3RhZmYiLCAiU3VwZXJ2aXNvciIsICJTdGFmZiIsICJNYW5hamVyIiwgIkRpcmVrdHVyIiksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgSW5pc2lhbGlzYXNpIHZhcmlhYmVsIGluZGVrcwprIDwtIDEKCiMgTG9vcCB3aGlsZSB1bnR1ayBtZW5hbXBpbGthbiBrYXJ5YXdhbiBzYW1wYWkgbWVuZW11a2FuIE1hbmFqZXIKd2hpbGUgKGsgPD0gbnJvdyhrYXJ5YXdhbikpIHsKICBjYXQoIk5hbWE6Iiwga2FyeWF3YW4kTmFtYVtrXSwgIiwgUG9zaXNpOiIsIGthcnlhd2FuJFBvc2lzaVtrXSwgIlxuIikKICAKICAjIEppa2EgcG9zaXNpIGFkYWxhaCAiTWFuYWplciIsIGxvb3AgYmVyaGVudGkKICBpZiAoa2FyeWF3YW4kUG9zaXNpW2tdID09ICJNYW5hamVyIikgewogICAgYnJlYWsKICB9CiAgCiAgIyBUYW1iYWggaW5kZWtzCiAgayA8LSBrICsgMQp9CgpgYGAKcGVuamVsYXNhbjoKS29kZSBSIGluaSBkaWd1bmFrYW4gdW50dWsgbWVuYW1waWxrYW4gZGFmdGFyIGthcnlhd2FuIGJlcmRhc2Fya2FuIHBvc2lzaSBtZXJla2EgaGluZ2dhIG1lbmVtdWthbiBrYXJ5YXdhbiBkZW5nYW4gcG9zaXNpICoqTWFuYWplcioqLiBEYXRhIGthcnlhd2FuIGRpc2ltcGFuIGRhbGFtICoqZGF0YSBmcmFtZSoqLCB5YW5nIGJlcmlzaSAqKm5hbWEsIGdhamksIHBlcmZvcm1hLCBkYW4gcG9zaXNpKiouIFByb2dyYW0gbWVuZ2d1bmFrYW4gKip3aGlsZSBsb29wKiogdW50dWsgbWVtYmFjYSBzZXRpYXAgYmFyaXMgZGF0YSBkZW5nYW4gaW5kZWtzIGBrYC4gU2V0aWFwIGthcnlhd2FuIGRpdGFtcGlsa2FuIGRhbGFtIGZvcm1hdCAqKiJOYW1hOiBbTmFtYSBLYXJ5YXdhbl0sIFBvc2lzaTogW1Bvc2lzaV0iKiogbWVuZ2d1bmFrYW4gKipjYXQoKSoqLiBKaWthIHBvc2lzaSBrYXJ5YXdhbiBhZGFsYWggKioiTWFuYWplciIqKiwgcHJvZ3JhbSBha2FuIG1lbmdoZW50aWthbiBsb29wIG1lbmdndW5ha2FuICoqYnJlYWsqKiwgc2VoaW5nZ2Ega2FyeWF3YW4gc2V0ZWxhaG55YSB0aWRhayBha2FuIGRpdGFtcGlsa2FuLiBEZW5nYW4gY2FyYSBpbmksIHByb2dyYW0gaGFueWEgbWVuY2V0YWsgZGFmdGFyIGthcnlhd2FuIGhpbmdnYSBwb3Npc2kgKipNYW5hamVyKiogZGl0ZW11a2FuLiAKCiMjIyAxLjMuMy4gKipNZW5nZ3VuYWthbiBicmVhayoqIHVudHVrIG1lbmdoZW50aWthbiBwZXJ1bGFuZ2FuIGtldGlrYSBtZW5lbXVrYW4ga2FyeWF3YW4gZGVuZ2FuIGdhamkgZGkgYXRhcyAqKjEwLjAwMCoqLiAgCiAgICoqT3V0cHV0IHlhbmcgZGloYXJhcGthbjoqKiAgCiAgIGBgYAogICBOYW1hOiBCYWdhcywgR2FqaTogNTAwMCAgCiAgIE5hbWE6IEpvYW4sIEdhamk6IDcwMDAgIAogICBOYW1hOiBBbHlhLCBHYWppOiA2NTAwICAKICAgTmFtYTogRHdpLCBHYWppOiAxMDAwMCAgCiAgIChCZXJoZW50aSBrYXJlbmEgTmFiaWwgbWVtaWxpa2kgZ2FqaSBkaSBhdGFzIDEwLjAwMCkgIAogICBgYGAgIApqYXdhYjoKCiMjIyMgYS5kYWxhbSBrb2RlIFBoeXRvbjoKYGBge3B5dGhvbn0KIyBNZW1idWF0IGRhZnRhciBrYXJ5YXdhbiBkZW5nYW4gbmFtYSwgZ2FqaSwgcGVyZm9ybWEsIGRhbiBwb3Npc2kKa2FyeWF3YW4gPSBbCiAgICB7Ik5hbWEiOiAiQmFnYXMiLCAiR2FqaSI6IDUwMDAsICJQZXJmb3JtYSI6ICJCYWlrIiwgIlBvc2lzaSI6ICJTdGFmZiJ9LAogICAgeyJOYW1hIjogIkpvYW4iLCAiR2FqaSI6IDcwMDAsICJQZXJmb3JtYSI6ICJTYW5nYXQgQmFpayIsICJQb3Npc2kiOiAiU3VwZXJ2aXNvciJ9LAogICAgeyJOYW1hIjogIkFseWEiLCAiR2FqaSI6IDY1MDAsICJQZXJmb3JtYSI6ICJSYXRhLXJhdGEiLCAiUG9zaXNpIjogIlN0YWZmIn0sCiAgICB7Ik5hbWEiOiAiRHdpIiwgIkdhamkiOiAxMDAwMCwgIlBlcmZvcm1hIjogIkJhaWsiLCAiUG9zaXNpIjogIk1hbmFqZXIifSwKICAgIHsiTmFtYSI6ICJOYWJpbCIsICJHYWppIjogMTIwMDAsICJQZXJmb3JtYSI6ICJTYW5nYXQgQmFpayIsICJQb3Npc2kiOiAiRGlyZWt0dXIifQpdCgojIExvb3AgdW50dWsgbWVuYW1waWxrYW4ga2FyeWF3YW4gc2FtcGFpIG1lbmVtdWthbiBnYWppIGRpIGF0YXMgMTAuMDAwCmZvciBrIGluIGthcnlhd2FuOgogICAgIyBKaWthIGdhamkgbGViaWggZGFyaSAxMC4wMDAsIGhlbnRpa2FuIGxvb3Agc2ViZWx1bSBtZW5jZXRhawogICAgaWYga1siR2FqaSJdID4gMTAwMDA6CiAgICAgICAgYnJlYWsKCiAgICBwcmludChmJ05hbWE6IHtrWyJOYW1hIl19LCBHYWppOiB7a1siR2FqaSJdfScpCmBgYApwZW5qZWxhc2FuOgpLb2RlIFB5dGhvbiBpbmkgZGlndW5ha2FuIHVudHVrIG1lbmFtcGlsa2FuIGRhZnRhciBrYXJ5YXdhbiBoaW5nZ2EgbWVuZW11a2FuIGthcnlhd2FuIGRlbmdhbiBnYWppIGRpIGF0YXMgKioxMC4wMDAqKi4gRGF0YSBrYXJ5YXdhbiBkaXNpbXBhbiBkYWxhbSAqKmxpc3Qgb2YgZGljdGlvbmFyaWVzKiosIHlhbmcgbWVuY2FrdXAgKipuYW1hLCBnYWppLCBwZXJmb3JtYSwgZGFuIHBvc2lzaSoqLiBQcm9ncmFtIG1lbmdndW5ha2FuICoqbG9vcCBmb3IqKiB1bnR1ayBtZW1iYWNhIHNldGlhcCBkYXRhIGthcnlhd2FuLiBTYWF0IG1lbWJhY2Egc2V0aWFwIGVsZW1lbiwgcHJvZ3JhbSBtZW1lcmlrc2EgYXBha2FoIGdhamkga2FyeWF3YW4gbGViaWggZGFyaSAqKjEwLjAwMCoqLiBKaWthIGtvbmRpc2kgdGVyc2VidXQgdGVycGVudWhpLCAqKmxvb3AgYWthbiBkaWhlbnRpa2FuIG1lbmdndW5ha2FuIGJyZWFrKiosIHNlaGluZ2dhIGthcnlhd2FuIGRlbmdhbiBnYWppIGxlYmloIHRpbmdnaSB0aWRhayBha2FuIGRpdGFtcGlsa2FuLiBEZW5nYW4gcGVuZGVrYXRhbiBpbmksIHByb2dyYW0gaGFueWEgbWVuY2V0YWsgZGFmdGFyIGthcnlhd2FuIGhpbmdnYSBtZW5lbXVrYW4gYmF0YXMgZ2FqaSB5YW5nIGRpdGVudHVrYW4uIAoKIyMjIyBiLiBkYWxhbSBrb2RlIHIgOgpgYGB7cn0KIyBNZW1idWF0IGRhZnRhciBrYXJ5YXdhbiBkZW5nYW4gbmFtYSwgZ2FqaSwgcGVyZm9ybWEsIGRhbiBwb3Npc2kKa2FyeWF3YW4gPC0gZGF0YS5mcmFtZSgKICBOYW1hID0gYygiQmFnYXMiLCAiSm9hbiIsICJBbHlhIiwgIkR3aSIsICJOYWJpbCIpLAogIEdhamkgPSBjKDUwMDAsIDcwMDAsIDY1MDAsIDEwMDAwLCAxMjAwMCksCiAgUGVyZm9ybWEgPSBjKCJCYWlrIiwgIlNhbmdhdCBCYWlrIiwgIlJhdGEtcmF0YSIsICJCYWlrIiwgIlNhbmdhdCBCYWlrIiksCiAgUG9zaXNpID0gYygiU3RhZmYiLCAiU3VwZXJ2aXNvciIsICJTdGFmZiIsICJNYW5hamVyIiwgIkRpcmVrdHVyIikKKQoKIyBMb29wIHVudHVrIG1lbmFtcGlsa2FuIGthcnlhd2FuIHNhbXBhaSBtZW5lbXVrYW4gZ2FqaSBkaSBhdGFzIDEwLjAwMApmb3IgKGsgaW4gMTpucm93KGthcnlhd2FuKSkgewogICMgSmlrYSBnYWppIGxlYmloIGRhcmkgMTAuMDAwLCBoZW50aWthbiBsb29wIHNlYmVsdW0gbWVuY2V0YWsKICBpZiAoa2FyeWF3YW4kR2FqaVtrXSA+IDEwMDAwKSB7CiAgICBicmVhawogIH0KICAKICBjYXQoIk5hbWE6Iiwga2FyeWF3YW4kTmFtYVtrXSwgIiwgR2FqaToiLCBrYXJ5YXdhbiRHYWppW2tdLCAiXG4iKQp9CgpgYGAKcGVuamVsYXNhbjoKS29kZSBSIGluaSBiZXJ0dWp1YW4gdW50dWsgbWVuYW1waWxrYW4gZGFmdGFyIGthcnlhd2FuIGhpbmdnYSBtZW5lbXVrYW4ga2FyeWF3YW4gZGVuZ2FuIGdhamkgZGkgYXRhcyAqKjEwLjAwMCoqLiBEYXRhIGthcnlhd2FuIGRpc2ltcGFuIGRhbGFtICoqZGF0YSBmcmFtZSoqLCB5YW5nIGJlcmlzaSBpbmZvcm1hc2kgbmFtYSwgZ2FqaSwgcGVyZm9ybWEsIGRhbiBwb3Npc2kuIFByb2dyYW0gbWVuZ2d1bmFrYW4gKipsb29wIGZvcioqIHVudHVrIG1lbWJhY2Egc2V0aWFwIGJhcmlzIGRhdGEgYmVyZGFzYXJrYW4gaW5kZWtzLiBEYWxhbSBzZXRpYXAgaXRlcmFzaSwgcHJvZ3JhbSBtZW1lcmlrc2EgYXBha2FoIGdhamkga2FyeWF3YW4gbGViaWggZGFyaSAqKjEwLjAwMCoqLiBKaWthIGtvbmRpc2kgdGVyc2VidXQgdGVycGVudWhpLCAqKmxvb3AgZGloZW50aWthbiBkZW5nYW4gYnJlYWsqKiwgc2VoaW5nZ2Ega2FyeWF3YW4gZGVuZ2FuIGdhamkgbGViaWggdGluZ2dpIHRpZGFrIGFrYW4gZGl0YW1waWxrYW4uIERlbmdhbiBtZXRvZGUgaW5pLCBoYW55YSBrYXJ5YXdhbiBkZW5nYW4gZ2FqaSBkaSBiYXdhaCBhdGF1IHNhbWEgZGVuZ2FuICoqMTAuMDAwKiogeWFuZyBha2FuIGRpY2V0YWsuIAoKIyMjIDEuMy40LiAqKk1lbmdndW5ha2FuIGNvbnRpbnVlKiogdW50dWsgbWVsZXdhdGkga2FyeWF3YW4gZGVuZ2FuIHBlcmZvcm1hICoqIlJhdGEtcmF0YSIqKi4gIAogICAqKk91dHB1dCB5YW5nIGRpaGFyYXBrYW46KiogIAogICBgYGAKICAgTmFtYTogQmFnYXMsIFBlcmZvcm1hOiBCYWlrICAKICAgTmFtYTogSm9hbiwgUGVyZm9ybWE6IFNhbmdhdCBCYWlrICAKICAgTmFtYTogRHdpLCBQZXJmb3JtYTogQmFpayAgCiAgIE5hbWE6IE5hYmlsLCBQZXJmb3JtYTogU2FuZ2F0IEJhaWsgIAogICAoQWx5YSBkaWxld2F0aSBrYXJlbmEgcGVyZm9ybWFueWEgIlJhdGEtcmF0YSIpICAKICAgYGBgICAKamF3YWI6CgojIyMjIGEuZGFsYW0ga29kZSBQaHl0b246CgpgYGB7cHl0aG9ufQojIE1lbWJ1YXQgZGFmdGFyIGthcnlhd2FuCmthcnlhd2FuID0gWwogICAgeyJOYW1hIjogIkJhZ2FzIiwgIkdhamkiOiA1MDAwLCAiUGVyZm9ybWEiOiAiQmFpayIsICJQb3Npc2kiOiAiU3RhZmYifSwKICAgIHsiTmFtYSI6ICJKb2FuIiwgIkdhamkiOiA3MDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsiLCAiUG9zaXNpIjogIlN1cGVydmlzb3IifSwKICAgIHsiTmFtYSI6ICJBbHlhIiwgIkdhamkiOiA2NTAwLCAiUGVyZm9ybWEiOiAiUmF0YS1yYXRhIiwgIlBvc2lzaSI6ICJTdGFmZiJ9LAogICAgeyJOYW1hIjogIkR3aSIsICJHYWppIjogMTAwMDAsICJQZXJmb3JtYSI6ICJCYWlrIiwgIlBvc2lzaSI6ICJNYW5hamVyIn0sCiAgICB7Ik5hbWEiOiAiTmFiaWwiLCAiR2FqaSI6IDEyMDAwLCAiUGVyZm9ybWEiOiAiU2FuZ2F0IEJhaWsiLCAiUG9zaXNpIjogIkRpcmVrdHVyIn0KXQoKZm9yIGsgaW4ga2FyeWF3YW46CiAgICBpZiBrWyJQZXJmb3JtYSJdID09ICJSYXRhLXJhdGEiOgogICAgICAgIGNvbnRpbnVlCiAgICBwcmludChmJ05hbWE6IHtrWyJOYW1hIl19LCBQZXJmb3JtYToge2tbIlBlcmZvcm1hIl19JykKCmBgYApwZW5qZWxhc2FuOgpLb2RlIFB5dGhvbiBpbmkgYmVydHVqdWFuIHVudHVrIG1lbmFtcGlsa2FuIGRhZnRhciBrYXJ5YXdhbiBkZW5nYW4gbWVuZ2VjdWFsaWthbiBtZXJla2EgeWFuZyBtZW1pbGlraSBwZXJmb3JtYSAqKiJSYXRhLXJhdGEiKiouIERhdGEga2FyeWF3YW4gZGlzaW1wYW4gZGFsYW0gYmVudHVrICoqbGlzdCBvZiBkaWN0aW9uYXJpZXMqKiwgeWFuZyBiZXJpc2kgaW5mb3JtYXNpIG5hbWEsIGdhamksIHBlcmZvcm1hLCBkYW4gcG9zaXNpLiBQcm9ncmFtIG1lbmdndW5ha2FuICoqbG9vcCBmb3IqKiB1bnR1ayBtZW1iYWNhIHNldGlhcCBlbGVtZW4gZGFsYW0gZGFmdGFyIGthcnlhd2FuLiBEYWxhbSBzZXRpYXAgaXRlcmFzaSwgcHJvZ3JhbSBtZW1lcmlrc2EgYXBha2FoIG5pbGFpICoqIlBlcmZvcm1hIioqIGFkYWxhaCAqKiJSYXRhLXJhdGEiKiouIEppa2Ega29uZGlzaSBpbmkgdGVycGVudWhpLCBtYWthICoqcGVyaW50YWggY29udGludWUgYWthbiBkaWxld2F0aSoqLCBzZWhpbmdnYSBrYXJ5YXdhbiB0ZXJzZWJ1dCB0aWRhayBha2FuIGRpdGFtcGlsa2FuLiBEZW5nYW4gbWV0b2RlIGluaSwgaGFueWEga2FyeWF3YW4gZGVuZ2FuIHBlcmZvcm1hICoqIkJhaWsiKiogYXRhdSAqKiJTYW5nYXQgQmFpayIqKiB5YW5nIGRpY2V0YWsgZGFsYW0gb3V0cHV0LgoKIyMjIyBiLiBkYWxhbSBrb2RlIHIgOgpgYGB7cn0KIyBNZW1idWF0IGRhdGEgZnJhbWUga2FyeWF3YW4Ka2FyeWF3YW4gPC0gZGF0YS5mcmFtZSgKICBOYW1hID0gYygiQmFnYXMiLCAiSm9hbiIsICJBbHlhIiwgIkR3aSIsICJOYWJpbCIpLAogIEdhamkgPSBjKDUwMDAsIDcwMDAsIDY1MDAsIDEwMDAwLCAxMjAwMCksCiAgUGVyZm9ybWEgPSBjKCJCYWlrIiwgIlNhbmdhdCBCYWlrIiwgIlJhdGEtcmF0YSIsICJCYWlrIiwgIlNhbmdhdCBCYWlrIiksCiAgUG9zaXNpID0gYygiU3RhZmYiLCAiU3VwZXJ2aXNvciIsICJTdGFmZiIsICJNYW5hamVyIiwgIkRpcmVrdHVyIiksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCmZvciAoayBpbiAxOm5yb3coa2FyeWF3YW4pKSB7CiAgaWYoa2FyeWF3YW4kUGVyZm9ybWFba10gPT0gIlJhdGEtcmF0YSIpIHsKICAgIG5leHQKICB9CiAgY2F0KCJOYW1hOiIsIGthcnlhd2FuJE5hbWFba10sICIsIFBlcmZvcm1hOiIsIGthcnlhd2FuJFBlcmZvcm1hW2tdLCAiXG4iKQp9CmBgYApwZW5qZWxhc2FuOgpLb2RlIFIgaW5pIGJlcnR1anVhbiB1bnR1ayBtZW5hbXBpbGthbiBkYWZ0YXIga2FyeWF3YW4gZGVuZ2FuIG1lbmdlY3VhbGlrYW4gbWVyZWthIHlhbmcgbWVtaWxpa2kgcGVyZm9ybWEgKioiUmF0YS1yYXRhIioqLiBEYXRhIGthcnlhd2FuIGRpc2ltcGFuIGRhbGFtIGJlbnR1ayAqKmRhdGEgZnJhbWUqKiwgeWFuZyBiZXJpc2kgaW5mb3JtYXNpIG5hbWEsIGdhamksIHBlcmZvcm1hLCBkYW4gcG9zaXNpLiBQcm9ncmFtIG1lbmdndW5ha2FuICoqbG9vcCBmb3IqKiB1bnR1ayBtZW1iYWNhIHNldGlhcCBiYXJpcyBkYWxhbSBkYXRhIGZyYW1lIGJlcmRhc2Fya2FuIGluZGVrcy4gRGFsYW0gc2V0aWFwIGl0ZXJhc2ksIHByb2dyYW0gbWVtZXJpa3NhIGFwYWthaCBuaWxhaSAqKiJQZXJmb3JtYSIqKiBhZGFsYWggKioiUmF0YS1yYXRhIioqLiBKaWthIGtvbmRpc2kgaW5pIHRlcnBlbnVoaSwgbWFrYSAqKnBlcmludGFoIG5leHQgYWthbiBkaWxld2F0aSoqLCBzZWhpbmdnYSBrYXJ5YXdhbiB0ZXJzZWJ1dCB0aWRhayBha2FuIGRpdGFtcGlsa2FuLiBEZW5nYW4gbWV0b2RlIGluaSwgaGFueWEga2FyeWF3YW4gZGVuZ2FuIHBlcmZvcm1hICoqIkJhaWsiKiogYXRhdSAqKiJTYW5nYXQgQmFpayIqKiB5YW5nIGFrYW4gZGljZXRhayBkYWxhbSBvdXRwdXQuIAotLS0KCiMjICoqS2VzaW1wdWxhbioqICAKCkJlcmlrdXQgYWRhbGFoIHBlcmJlZGFhbiBrb2RlIFB5dGhvbiBkYW4gUiB1bnR1ayBzZXRpYXAgbm9tb3I6Cgp8ICoqTm8qKiB8ICoqRGVza3JpcHNpKiogfCAqKktvZGUgUHl0aG9uKiogfCAqKktvZGUgUioqIHwKfC0tLS0tLS0tfC0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18CnwgKioxKiogfCBNZW5naGl0dW5nIGJvbnVzIGJlcmRhc2Fya2FuIHBlcmZvcm1hIHwgTWVuZ2d1bmFrYW4gKipsaXN0IG9mIGRpY3Rpb25hcmllcyoqLCBsYWx1ICoqZm9yIGxvb3AqKiBkZW5nYW4gKippZi1lbGlmLWVsc2UqKiB1bnR1ayBtZW5naGl0dW5nIGJvbnVzIGRhbiBtZW5jZXRhayBoYXNpbC4gfCBNZW5nZ3VuYWthbiAqKmRhdGEgZnJhbWUqKiwgbGFsdSAqKmZvciBsb29wKiogZGVuZ2FuICoqaWYtZWxzZSoqIHVudHVrIG1lbmdoaXR1bmcgYm9udXMgZGFuIG1lbmNldGFrIGhhc2lsIG1lbmdndW5ha2FuIGBjYXQoKWAuIHwKfCAqKjIqKiB8IE1lbmFtcGlsa2FuIGthcnlhd2FuIGRlbmdhbiBnYWppIGxlYmloIGRhcmkgNjAwMCB8IE1lbmdndW5ha2FuICoqZm9yIGxvb3AqKiB1bnR1ayBtZW5nZWNlayBnYWppIGRhbGFtICoqbGlzdCBvZiBkaWN0aW9uYXJpZXMqKiwgbGFsdSBtZW5jZXRhayBkYXRhIGppa2EgZ2FqaSBsZWJpaCBkYXJpIDYwMDAuIHwgTWVuZ2d1bmFrYW4gKipmb3IgbG9vcCoqIGRhbGFtICoqZGF0YSBmcmFtZSoqLCBsYWx1IG1lbmNldGFrIGRhdGEgamlrYSBnYWppIGxlYmloIGRhcmkgNjAwMCBtZW5nZ3VuYWthbiBgY2F0KClgLiB8CnwgKiozKiogfCBNZW5hbXBpbGthbiBrYXJ5YXdhbiBzYW1wYWkgbWVuZW11a2FuIHBvc2lzaSAiTWFuYWplciIgfCBNZW5nZ3VuYWthbiAqKndoaWxlIGxvb3AqKiB1bnR1ayBtZW5jZXRhayBrYXJ5YXdhbiwgbGFsdSAqKmJyZWFrKiogamlrYSBwb3Npc2kgYWRhbGFoICJNYW5hamVyIi4gfCBNZW5nZ3VuYWthbiAqKndoaWxlIGxvb3AqKiBkYWxhbSAqKmRhdGEgZnJhbWUqKiwgbGFsdSAqKmJyZWFrKiogamlrYSBwb3Npc2kgYWRhbGFoICJNYW5hamVyIi4gfAp8ICoqNCoqIHwgTWVuZ2hlbnRpa2FuIGxvb3Agc2FhdCBtZW5lbXVrYW4ga2FyeWF3YW4gZGVuZ2FuIGdhamkgZGkgYXRhcyAxMC4wMDAgfCBNZW5nZ3VuYWthbiAqKmZvciBsb29wKiosIGxhbHUgKipicmVhayoqIGppa2EgZ2FqaSBsZWJpaCBkYXJpIDEwLjAwMCBzZWJlbHVtIG1lbmNldGFrLiB8IE1lbmdndW5ha2FuICoqZm9yIGxvb3AqKiBkYWxhbSAqKmRhdGEgZnJhbWUqKiwgbGFsdSAqKmJyZWFrKiogamlrYSBnYWppIGxlYmloIGRhcmkgMTAuMDAwIHNlYmVsdW0gbWVuY2V0YWsuIHwKfCAqKjUqKiB8IE1lbGV3YXRpIGthcnlhd2FuIGRlbmdhbiBwZXJmb3JtYSAiUmF0YS1yYXRhIiB8IE1lbmdndW5ha2FuICoqZm9yIGxvb3AqKiwgbGFsdSAqKmNvbnRpbnVlKiogamlrYSBwZXJmb3JtYSBhZGFsYWggIlJhdGEtcmF0YSIuIHwgTWVuZ2d1bmFrYW4gKipmb3IgbG9vcCoqLCBsYWx1ICoqbmV4dCoqIGppa2EgcGVyZm9ybWEgYWRhbGFoICJSYXRhLXJhdGEiLiB8CgojIyMgKipTaW50YWtzIChDYXJhIE1lbnVsaXMgS29kZSkqKiAgClB5dGhvbiBtZW1pbGlraSBzaW50YWtzIHlhbmcgbGViaWggcmFwaSBkYW4gbXVkYWggZGlwYWhhbWksIHRlcnV0YW1hIGthcmVuYSBwZW5nZ3VuYWFuIGluZGVudGFzaSB1bnR1ayBtZW5hbmRhaSBibG9rIGtvZGUuIEhhbCBpbmkgbWVtYnVhdCBrb2RlIFB5dGhvbiBsZWJpaCB0ZXJzdHJ1a3R1ciBkYW4gbnlhbWFuIGRpYmFjYS4gU2VsYWluIGl0dSwgUHl0aG9uIG1lbWlsaWtpIGF0dXJhbiB5YW5nIGxlYmloIGtvbnNpc3RlbiBkYWxhbSBwZW51bGlzYW4sIHNlaGluZ2dhIHBlbXVsYSBwdW4gYmlzYSBjZXBhdCBtZW1haGFtaSBjYXJhIGtlcmphIGJhaGFzYSBpbmkuICAKClNlbWVudGFyYSBpdHUsIFIgbWVtaWxpa2kgc2ludGFrcyB5YW5nIGxlYmloIGZsZWtzaWJlbCwgdGV0YXBpIHRlcmthZGFuZyBrdXJhbmcga29uc2lzdGVuIGRpYmFuZGluZyBQeXRob24uIFIgbGViaWggYmVyb3JpZW50YXNpIHBhZGEgYW5hbGlzaXMgZGF0YSwgc2VoaW5nZ2EgYmFueWFrIGZ1bmdzaSBiYXdhYW4geWFuZyBsYW5nc3VuZyBiZWtlcmphIHBhZGEgZGF0YSB0YW5wYSBwZXJsdSBtZW51bGlzIGtvZGUgdGVybGFsdSBwYW5qYW5nLiBOYW11biwgZmxla3NpYmlsaXRhcyBpbmkganVnYSBiaXNhIG1lbWJ1YXQga29kZSBSIHN1bGl0IGRpcGFoYW1pIGppa2EgdGlkYWsgZGl0dWxpcyBkZW5nYW4gcmFwaS4gIAoKIyMjICoqQWx1ciBLb250cm9sIChDYXJhIFByb2dyYW0gTWVuZ2FtYmlsIEtlcHV0dXNhbiAmIE1lbmd1bGFuZyBLb2RlKSoqICAKQmFpayBQeXRob24gbWF1cHVuIFIgbWVuZHVrdW5nIHN0cnVrdHVyIGtvbnRyb2wgc2VwZXJ0aSBwZXJjYWJhbmdhbiAoYGlmLWVsc2VgKSBkYW4gcGVydWxhbmdhbiAoYGZvcmAgZGFuIGB3aGlsZWApLiAgCgotICoqUHl0aG9uKiogbGViaWggc2VyaW5nIG1lbmdndW5ha2FuIHBlbmRla2F0YW4geWFuZyBsZWJpaCByaW5na2FzIHNlcGVydGkgKmxpc3QgY29tcHJlaGVuc2lvbiosIHlhbmcgbWVtYnVhdCBrb2RlIGxlYmloIGVmaXNpZW4gZGFuIG11ZGFoIGRpYmFjYS4gUHl0aG9uIGp1Z2EgbWVtaWxpa2kgYmFueWFrIGZpdHVyIHBlbXJvZ3JhbWFuIGZ1bmdzaW9uYWwgeWFuZyBtZW1wZXJtdWRhaCBtYW5pcHVsYXNpIGRhdGEgZGFuIHBlbmdvbGFoYW4gZGFsYW0ganVtbGFoIGJlc2FyLiAgCi0gKipSKiosIGRpIHNpc2kgbGFpbiwgbGViaWggbWVuZ2FuZGFsa2FuIHZla3RvcmlzYXNpIGRhbiBmdW5nc2kgc2VwZXJ0aSBgYXBwbHkoKWAsIGBsYXBwbHkoKWAsIGRhbiBgc2FwcGx5KClgLCB5YW5nIG1lbXVuZ2tpbmthbiBwZW5nZ3VuYSB1bnR1ayBtZW1wcm9zZXMgZGF0YSBkYWxhbSBiZW50dWsgdmVrdG9yIGF0YXUgbWF0cmlrcyB0YW5wYSBoYXJ1cyBtZW51bGlzIHBlcnVsYW5nYW4gZWtzcGxpc2l0LiBIYWwgaW5pIG1lbWJ1YXQgUiBsZWJpaCBlZmlzaWVuIGRhbGFtIGFuYWxpc2lzIGRhdGEsIHRldGFwaSBiaXNhIHRlcmFzYSBrdXJhbmcgaW50dWl0aWYgYmFnaSB5YW5nIGJlbHVtIHRlcmJpYXNhLiAgCgotLS0KCiMjIFJlZmVyZW5zaQoKCjEuIFNpcmVnYXIsIEIuIChuLmQuKS4gU3ludGF4IGFuZCBDb250cm9sIEZsb3cuIERpYWtzZXMgcGFkYSAyNiBGZWJydWFyaSAyMDI1LCBkYXJpIGh0dHBzOi8vYm9va2Rvd24ub3JnL2RzY2llbmNlbGFicy9kYXRhX3NjaWVuY2VfcHJvZ3JhbW1pbmcvMDItU3ludGF4LWFuZC1Db250cm9sLUZsb3cuaHRtbAoKCjIuIERhdGEgU2NpZW5jZSBMYWJzLiAoMjAyMykuIFN5bnRheCBhbmQgQ29udHJvbCBGbG93IFtWaWRlb10uIFlvdVR1YmUuIERpYWtzZXMgcGFkYSAyNiBGZWJydWFyaSAyMDI1LCBkYXJpIGh0dHBzOi8veW91dHUuYmUvZVNZZUhsd0RDTkEKCgo=