UTS Teknik Sampling dan Survei

Teknik Sampling dan Survei

Studi Kasus 1 (Simulasi Kesalahan Sampling di Lapangan)

Andikan Anda adalah bagian dari tim riset lapangan yang diminta untuk melakukan survei tingkat penggunaan aplikasi transportasi online di 3 kota menengah di Sumatera. Target sampel total adalah 600 responden, masing-masing 200 per kota. Tetapi, setelah 2 minggu melakukan survei anda menemukan:

  • Di Kota A, tim berhasil mendapatkan 250 responden.
  • Di Kota B, hanya 120 responden yang dapat diwawancarai.
  • Di Kota C, 180 responden.

Instruksi:

  1. Jelaskan dua jenis kesalahan sampling yang terjadi berdasarkan situasi ini.

  2. Jika Anda harus menyesuaikan bobot untuk mengembalikan representasi proporsional, bagaimana Anda akan menghitungnya?


Kesalahan Sampling

Berdasarkan situasi yang diberikan, berikut adalah dua jenis kesalahan sampling yang terjadi:

1. Kesalahan Representasi (Representation Error)

Jumlah responden yang terkumpul tidak sesuai dengan target awal per kota, yaitu 200 responden per kota. Situasi ini menyebabkan:

  • Kota A memiliki 250 responden, yang berarti kelebihan 50 responden (+25% dari target).
  • Kota B hanya memiliki 120 responden, yang berarti kekurangan 80 responden (-40% dari target).
  • Kota C memiliki 180 responden, yang berarti kekurangan 20 responden (-10% dari target).

Karena distribusi jumlah responden tidak seimbang, hasil survei menjadi tidak mewakili proporsi yang diinginkan. Kota A yang kelebihan responden akan memiliki pengaruh yang lebih besar terhadap hasil survei.

2. Kesalahan Sampling Non-Respons (Non-Response Error)

Kesalahan ini terjadi karena di Kota B hanya 120 orang yang berhasil diwawancarai, jauh di bawah target 200. Kemungkinan ada faktor-faktor tertentu yang membuat responden di Kota B tidak mau atau tidak bisa berpartisipasi, seperti kurangnya waktu, ketidakpercayaan terhadap survei, atau alasan lain. Jika karakteristik mereka berbeda dari yang berpartisipasi, hasil survei akan bias.


Menghitung Bobot Responden

Untuk mengembalikan representasi proporsional ke target awal (200 responden per kota dari total 600), bobot untuk masing-masing kota dihitung sebagai berikut:

  1. Proporsi Target:
    • Kota A: \(\frac{200}{600} = 0.3333\)
    • Kota B: \(\frac{200}{600} = 0.3333\)
    • Kota C: \(\frac{200}{600} = 0.3333\)
  2. Proporsi Aktual:
    • Kota A: \(\frac{250}{550} \approx 0.4545\)
    • Kota B: \(\frac{120}{550} \approx 0.2182\)
    • Kota C: \(\frac{180}{550} \approx 0.3273\)
  3. Bobot:
    • Kota A: \(\frac{0.3333}{0.4545} \approx 0.733\)
    • Kota B: \(\frac{0.3333}{0.2182} \approx 1.528\)
    • Kota C: \(\frac{0.3333}{0.3273} \approx 1.018\)

Implementasi Perhitungan dengan R

Berikut adalah implementasi kode untuk menghitung bobot menggunakan R:

library(knitr)
## Warning: package 'knitr' was built under R version 4.4.2
# Data jumlah target dan aktual per kota
kota <- c("Kota A", "Kota B", "Kota C")
target <- c(200, 200, 200)
aktual <- c(250, 120, 180)

# Total
total_target <- sum(target)
total_aktual <- sum(aktual)

# Hitung proporsi target dan aktual
proporsi_target <- target / total_target
proporsi_aktual <- aktual / total_aktual

# Hitung bobot
bobot <- round(proporsi_target / proporsi_aktual, 3)

# Buat data frame hasil
hasil <- data.frame(
  Kota = kota,
  Target = target,
  Aktual = aktual,
  `Proporsi Target` = round(proporsi_target, 4),
  `Proporsi Aktual` = round(proporsi_aktual, 4),
  `Bobot Penyesuaian` = bobot
)

# Tampilkan hasil
kable(hasil, caption = "Tabel Penyesuaian Bobot Responden per Kota")
Tabel Penyesuaian Bobot Responden per Kota
Kota Target Aktual Proporsi.Target Proporsi.Aktual Bobot.Penyesuaian
Kota A 200 250 0.3333 0.4545 0.733
Kota B 200 120 0.3333 0.2182 1.528
Kota C 200 180 0.3333 0.3273 1.019

Studi Kasus 2 (Mendesain Survei dengan Pembobotan Waktu Puncak)

Buatlah desain rancangan survei tentang persepsi kenyamanan pengguna ojek online saat jam sibuk (07.00–09.00 dan 17.00–19.00).

Instruksi:

  1. Desain pendekatan sampling yang memungkinkan Anda menangkap persepsi pengguna secara representatif pada jam sibuk, tanpa melakukan survei sepanjang hari.

  2. Sertakan rancangan waktu, metode pemilihan responden, dan justifikasi pemilihan unit sampling.

  3. Jelaskan bagaimana Anda akan menyesuaikan hasil survei jika 60% responden berasal dari pagi hari, sementara 40% dari sore hari, sedangkan data historis menunjukkan pengguna ojek online saat sore hari dua kali lebih banyak dibanding pagi.


Desain Pendekatan Sampling

Untuk memastikan survei yang representatif, pendekatan yang digunakan adalah stratified time sampling, dengan pembagian dua strata waktu:

  • Pagi (07.00–09.00): Fokus pada jam berangkat kerja/sekolah.
  • Sore (17.00–19.00): Fokus pada jam pulang kerja/sekolah.

Dengan pendekatan ini, survei hanya dilakukan pada jam sibuk yang relevan, sehingga efisien dan tetap representatif tanpa harus mengumpulkan data sepanjang hari. Masing-masing strata waktu merepresentasikan pola penggunaan ojek online yang berbeda.


Rancangan Waktu, Metode, dan Justifikasi

Rancangan Waktu: - Survei dilaksanakan pada hari kerja (Senin-Jumat) selama dua waktu sibuk: pagi (07.00–09.00) dan sore (17.00–19.00).

Metode Pemilihan Responden: - Systematic intercept sampling: Responden dipilih secara sistematis pada lokasi-lokasi strategis, seperti stasiun, terminal, atau kawasan perkantoran. - Contoh: Setiap 10 menit, satu pengguna ojek online yang baru turun diwawancarai.

Justifikasi Pemilihan Unit Sampling: - Unit sampling adalah pengguna aktif ojek online pada jam sibuk. Mereka dipilih karena berada di lokasi dan waktu yang relevan untuk menggambarkan persepsi kenyamanan secara langsung.


Penyesuaian Hasil Survei Berdasarkan Data Historis

Dalam survei ini: - 60% responden berasal dari pagi hari (07.00–09.00). - 40% responden berasal dari sore hari (17.00–19.00).

Namun, data historis menunjukkan bahwa: - Pengguna ojek online di sore hari dua kali lebih banyak dibandingkan pagi hari.

Proporsi Aktual Berdasarkan Data Historis:

  • Pagi: 1 bagian (1/3 atau 0.33)
  • Sore: 2 bagian (2/3 atau 0.67)

Penyesuaian Bobot:

Untuk menghindari bias akibat ketidakseimbangan jumlah responden, dilakukan penyesuaian bobot berdasarkan proporsi aktual dan proporsi survei.

Rumus Bobot: \[ \text{Bobot waktu} = \frac{\text{Proporsi sebenarnya}}{\text{Proporsi hasil survei}} \]

Perhitungan Bobot: - Bobot pagi: \(0.33 / 0.60 \approx 0.56\) - Bobot sore: \(0.67 / 0.40 \approx 1.67\)

library(knitr)

# Data pembobotan
pembobotan_data <- data.frame(
  Waktu = c("Pagi", "Sore"),
  Proporsi_Survei = c(0.60, 0.40),
  Proporsi_Aktual = c(1/3, 2/3),
  Bobot = c((1/3)/0.60, (2/3)/0.40)
)

# Tabel pembobotan
kable(pembobotan_data, caption = "Pembobotan Berdasarkan Proporsi Historis Pengguna")
Pembobotan Berdasarkan Proporsi Historis Pengguna
Waktu Proporsi_Survei Proporsi_Aktual Bobot
Pagi 0.6 0.3333333 0.5555556
Sore 0.4 0.6666667 1.6666667

Simulasi Data dan Analisis

Data Simulasi

Kita buat data simulasi untuk 100 responden:

set.seed(123)  # For reproducibility

# Membuat data untuk 100 responden
data <- data.frame(
  respondent_id = 1:100,
  time_period = c(rep("Pagi", 60), rep("Sore", 40)),
  satisfaction_score = c(rnorm(60, mean = 7, sd = 1.5), rnorm(40, mean = 8, sd = 1.2))
)

head(data)

Terapkan Bobot

Tambahkan bobot ke data berdasarkan waktu:

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
data <- data %>%
  left_join(pembobotan_data %>% select(Waktu, Bobot), by = c("time_period" = "Waktu")) %>%
  mutate(weighted_score = satisfaction_score * Bobot)

head(data)

Perhitungan Rata-rata Berbobot

Hitung rata-rata berbobot:

weighted_mean <- sum(data$weighted_score) / sum(data$Bobot)
weighted_mean
## [1] 7.801546

Studi Kasus 3 (Evaluasi Kepuasan Mahasiswa terhadap Layanan Akademik)

Anda ditugaskan oleh biro akademik kampus untuk merancang instrumen survei yang bertujuan mengevaluasi kepuasan mahasiswa terhadap layanan akademik, yang mencakup layanan seperti: KRS online, bimbingan akademik, pelayanan administrasi, akses informasi akademik, dan bantuan penyelesaian studi.

Tim peneliti meminta Anda untuk:

  • Merancang 25 pertanyaan utama dengan variasi skala dan bentuk pertanyaan.

  • Merancang sistem validasi instrumen.

  • Menentukan metode distribusi dan pengujian kuesioner secara statistik.

  • Menyiapkan simulasi strategi pengambilan sampel dan pengolahan data awal.

Output Laporan yang diharapkan dalam bentuk naratif, mencakup:

• Desain pertanyaan

• Skema validasi

• Strategi distribusi dan sampling

• Simulasi data dan analisis awal


1. Desain Pertanyaan

Berikut adalah desain 25 pertanyaan yang terbagi dalam lima aspek layanan akademik:

  • KRS Online
  • Bimbingan Akademik
  • Pelayanan Administrasi
  • Akses Informasi Akademik
  • Bantuan Penyelesaian Studi

Link Pertanyaan Google Form: Google Form


2. Skema validasi

2.1 Validasi Isi (Content Validity)

Proses validasi isi dilakukan dengan melibatkan pakar atau dosen di bidang pendidikan untuk menilai relevansi setiap pertanyaan terhadap aspek yang dievaluasi. Penilaian dilakukan dengan tiga kategori:

  • Sangat relevan

  • Cukup relevan

  • Tidak relevan

Hasil penilaian dihitung menggunakan Content Validity Ratio (CVR). Jika CVR dari suatu pertanyaan berada di atas ambang batas yang ditentukan, maka pertanyaan tersebut dianggap valid secara isi. Sebaliknya, jika CVR rendah, pertanyaan tersebut perlu direvisi atau dihapus.

2.2 Validasi Statistik

Setelah validasi isi selesai, dilakukan uji coba kuesioner kepada 30 mahasiswa sebagai tahap awal pengujian statistik.

2.2.1 Uji Validitas Konstruk (Construct Validity)

Uji ini bertujuan untuk memastikan bahwa setiap pertanyaan dalam kuesioner benar-benar mengukur aspek yang sesuai. Pendekatan yang digunakan:

  • Korelasi Item-Total: Menghitung korelasi antara setiap item dengan total skor dari aspek terkait. Korelasi > 0.3 menunjukkan validitas yang baik.

  • Analisis Faktor: Dilakukan eksplorasi menggunakan metode Analisis Faktor Eksploratori (EFA) untuk memastikan bahwa kelompok pertanyaan membentuk faktor yang diharapkan.

2.2.2 Uji Reliabilitas

Reliabilitas instrumen diuji menggunakan Cronbach’s Alpha untuk mengevaluasi konsistensi internal antaritem. Kriteria:

  • Alpha > 0.7: Instrumen dianggap reliabel.

  • Alpha < 0.7: Perlu dilakukan revisi pada item tertentu yang mengurangi reliabilitas.


3. Strategi Distribusi dan Sampling

3.1 Strategi Distribusi

Kuesioner akan disebarkan secara daring menggunakan platform Google Forms. Langkah distribusi meliputi:

  • Email Kampus: Kuesioner dikirim melalui sistem email resmi kepada seluruh mahasiswa aktif.

  • Grup Media Sosial: Tautan kuesioner disebarkan melalui grup WhatsApp, Telegram, dan platform komunikasi lainnya.

  • LMS Kampus: Kuesioner juga akan tersedia di Learning Management System (LMS) kampus untuk meningkatkan aksesibilitas.

Pengingat akan dikirimkan secara berkala untuk meningkatkan tingkat respons. Selain itu, insentif berupa sertifikat partisipasi atau hadiah kecil dapat diberikan kepada responden sebagai bentuk apresiasi.

3.2 Strategi Sampling

3.2.1 Populasi dan Teknik Sampling

Populasi target adalah seluruh mahasiswa aktif di kampus. Metode sampling yang digunakan adalah Stratified Random Sampling dengan strata berdasarkan:

  • Program Studi

  • Angkatan (misalnya 2020-2023)

Stratifikasi ini bertujuan untuk memastikan bahwa setiap kelompok terwakili dalam survei.

3.2.2 Ukuran Sampel

Mengacu pada populasi mahasiswa aktif sebanyak 10.000 orang, diperlukan minimal 384 responden untuk tingkat kepercayaan 95% dan margin of error 5%. Untuk tahap uji coba, 30 responden awal akan digunakan untuk memvalidasi instrumen secara statistik.

3.2.3 Alokasi Sampel

Responden dari setiap strata akan diambil secara proporsional. Misalnya, jika Program Studi A memiliki 20% populasi, maka 20% dari total sampel akan diambil dari program studi tersebut.

3.2.4 Peningkatan Respons

Strategi untuk meningkatkan tingkat respons meliputi:

  • Mengirimkan pengingat secara berkala kepada mahasiswa yang belum mengisi kuesioner.

  • Melibatkan organisasi mahasiswa dan dosen untuk mempromosikan survei.

  • Memberikan insentif kepada responden yang berpartisipasi.


4. Simulasi Data dan analisis awal

# Simulasi Data Survei Kepuasan Mahasiswa
set.seed(123)

# Membuat data untuk 5 kategori layanan
data_krs <- data.frame(
  KRS_akses = sample(1:5, 100, replace = TRUE),
  KRS_masalah = sample(1:5, 100, replace = TRUE),
  KRS_efisiensi = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)

# Gabungkan data untuk 5 kategori lainnya
data_bimbingan <- data.frame(
  Bimbingan_frekuensi = sample(1:10, 100, replace = TRUE),
  Bimbingan_kualitas = sample(1:5, 100, replace = TRUE)
)

data_administrasi <- data.frame(
  Administrasi_respons = sample(1:5, 100, replace = TRUE),
  Administrasi_kemudahan = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)

data_akses <- data.frame(
  Akses_frekuensi = sample(1:10, 100, replace = TRUE),
  Akses_informatif = sample(1:5, 100, replace = TRUE)
)

data_bantuan <- data.frame(
  Bantuan_studi = sample(1:5, 100, replace = TRUE),
  Bantuan_tersedia = sample(c("Ya", "Tidak"), 100, replace = TRUE)
)

# Gabungkan semua data menjadi satu data frame
data_survei <- cbind(data_krs, data_bimbingan, data_administrasi, data_akses, data_bantuan)
head(data_survei)

4.1 Deskripsi Statistik Awal

Kita akan menghitung beberapa deskripsi statistik untuk melihat distribusi data dari setiap kategori.

library(dplyr)
summary_statistics <- data_survei %>%
  summarise_all(list(mean = ~mean(as.numeric(as.character(.)), na.rm = TRUE),
                     sd = ~sd(as.numeric(as.character(.)), na.rm = TRUE),
                     median = ~median(as.numeric(as.character(.)), na.rm = TRUE)))
## Warning: There were 9 warnings in `summarise()`.
## The first warning was:
## ℹ In argument: `KRS_efisiensi_mean = (structure(function (..., .x = ..1, .y =
##   ..2, . = ..1) ...`.
## Caused by warning in `mean()`:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 8 remaining warnings.
knitr::kable(summary_statistics, caption = "Deskripsi Statistik Awal")
Deskripsi Statistik Awal
KRS_akses_mean KRS_masalah_mean KRS_efisiensi_mean Bimbingan_frekuensi_mean Bimbingan_kualitas_mean Administrasi_respons_mean Administrasi_kemudahan_mean Akses_frekuensi_mean Akses_informatif_mean Bantuan_studi_mean Bantuan_tersedia_mean KRS_akses_sd KRS_masalah_sd KRS_efisiensi_sd Bimbingan_frekuensi_sd Bimbingan_kualitas_sd Administrasi_respons_sd Administrasi_kemudahan_sd Akses_frekuensi_sd Akses_informatif_sd Bantuan_studi_sd Bantuan_tersedia_sd KRS_akses_median KRS_masalah_median KRS_efisiensi_median Bimbingan_frekuensi_median Bimbingan_kualitas_median Administrasi_respons_median Administrasi_kemudahan_median Akses_frekuensi_median Akses_informatif_median Bantuan_studi_median Bantuan_tersedia_median
2.93 2.95 NaN 5.55 2.99 3.02 NaN 5.48 3.1 3.12 NaN 1.408882 1.5333 NA 2.952058 1.374332 1.456299 NA 2.945567 1.438995 1.49936 NA 3 3 NA 5.5 3 3 NA 6 3 3 NA

4.2 Uji Validitas dan Reliabilitas

4.2.1 Korelasi Item-Total

Untuk memeriksa validitas konstruk, kita akan menghitung korelasi antara item dan total skor untuk setiap kategori.

# Menghitung korelasi item-total untuk kategori KRS
cor_krs <- cor(data_krs$KRS_akses, data_krs$KRS_masalah, use = "complete.obs")
cor_krs
## [1] 0.08720506

4.2.2 Cronbach’s Alpha

Kita akan mengukur reliabilitas setiap kategori menggunakan Cronbach’s Alpha.

library(psych)
## Warning: package 'psych' was built under R version 4.4.3
# Fungsi untuk menghitung Cronbach's Alpha
cronbach_alpha <- function(data) {
  numeric_data <- data[sapply(data, is.numeric)]
  data_clean <- na.omit(numeric_data)
  alpha_result <- psych::alpha(data_clean)
  return(alpha_result$total$raw_alpha)
}

# Menghitung Cronbach's Alpha untuk kategori KRS
cronbach_krs <- cronbach_alpha(data_krs)
cronbach_krs
## [1] 0.1598937

4.3 Penyajian Grafik

Kita akan menggunakan grafik untuk menggambarkan distribusi jawaban dari beberapa pertanyaan.

2.3.1 Histogram untuk KRS_akses

# Membuat histogram untuk melihat distribusi frekuensi untuk KRS_akses
library(ggplot2)
## 
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
## 
##     %+%, alpha
ggplot(data_survei, aes(x = KRS_akses)) +
  geom_bar(fill = "skyblue", color = "black") +
  labs(title = "Distribusi Jawaban KRS Akses", x = "Skala KRS Akses", y = "Frekuensi")

4.3.2 Boxplot untuk Bimbingan_kualitas

# Membuat boxplot untuk Bimbingan_kualitas
ggplot(data_survei, aes(y = Bimbingan_kualitas, x = 1)) +
  geom_boxplot(fill = "lightgreen", color = "black") +
  labs(title = "Distribusi Kepuasan Terhadap Bimbingan Akademik", y = "Kualitas Bimbingan", x = "")

4.4 Kesimpulan

Berdasarkan analisis data awal, kita dapat menyimpulkan bahwa:

  • Layanan KRS Online cenderung memiliki tingkat kepuasan yang bervariasi, dengan sebagian besar mahasiswa merasa kesulitan mengakses atau mengalami masalah teknis.

  • Bimbingan Akademik menunjukkan kepuasan yang cukup baik, namun terdapat kendala dalam hal waktu dan akses.

  • Pelayanan administrasi umumnya dianggap cepat, meskipun ada beberapa laporan keterlambatan.

  • Akses informasi akademik juga bervariasi, dengan beberapa mahasiswa merasa kesulitan menemukan informasi yang diperlukan.

LS0tDQp0aXRsZTogIlVUUyBUZWtuaWsgU2FtcGxpbmcgZGFuIFN1cnZlaSINCnN1YnRpdGxlOiAiVGVrbmlrIFNhbXBsaW5nIGRhbiBTdXJ2ZWkiDQphdXRob3I6ICJKT0FOUyBIRU5LWSBTRVJWQVRJVVMgU0lNQU5VTExBTkciDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY3NzOiAic3R5bGUgMS5jc3MiDQotLS0NCjxpbWcgc3JjPSJmb3RvLmpwZWciIHN0eWxlPSJkaXNwbGF5OiBibG9jazsgbWFyZ2luOiBhdXRvOyB3aWR0aDogMzYwcHg7IGhlaWdodDogNDgwcHg7IiBhbHQ9IiI+DQoNCg0KIyBTdHVkaSBLYXN1cyAxICgqKlNpbXVsYXNpIEtlc2FsYWhhbiBTYW1wbGluZyBkaSBMYXBhbmdhbioqKQ0KDQpBbmRpa2FuIEFuZGEgYWRhbGFoIGJhZ2lhbiBkYXJpIHRpbSByaXNldCBsYXBhbmdhbiB5YW5nIGRpbWludGEgdW50dWsgbWVsYWt1a2FuDQpzdXJ2ZWkgdGluZ2thdCBwZW5nZ3VuYWFuIGFwbGlrYXNpIHRyYW5zcG9ydGFzaSBvbmxpbmUgZGkgKiozIGtvdGEgbWVuZW5nYWgqKiBkaSBTdW1hdGVyYS4NClRhcmdldCBzYW1wZWwgdG90YWwgYWRhbGFoICoqNjAwIHJlc3BvbmRlbioqLCBtYXNpbmctbWFzaW5nIDIwMCBwZXIga290YS4gVGV0YXBpLCBzZXRlbGFoDQoyIG1pbmdndSBtZWxha3VrYW4gc3VydmVpIGFuZGEgbWVuZW11a2FuOg0KDQotIERpIEtvdGEgQSwgdGltIGJlcmhhc2lsIG1lbmRhcGF0a2FuIDI1MCByZXNwb25kZW4uDQotIERpIEtvdGEgQiwgaGFueWEgMTIwIHJlc3BvbmRlbiB5YW5nIGRhcGF0IGRpd2F3YW5jYXJhaS4NCi0gRGkgS290YSBDLCAxODAgcmVzcG9uZGVuLg0KDQoqSW5zdHJ1a3NpOioNCg0KYS4gSmVsYXNrYW4gKipkdWEgamVuaXMga2VzYWxhaGFuIHNhbXBsaW5nKiogeWFuZyB0ZXJqYWRpIGJlcmRhc2Fya2FuIHNpdHVhc2kgaW5pLg0KDQpiLiBKaWthIEFuZGEgaGFydXMgbWVueWVzdWFpa2FuIGJvYm90IHVudHVrIG1lbmdlbWJhbGlrYW4gcmVwcmVzZW50YXNpIHByb3BvcnNpb25hbCwgYmFnYWltYW5hIEFuZGEgYWthbiBtZW5naGl0dW5nbnlhPw0KDQotLS0NCg0KIyMgS2VzYWxhaGFuIFNhbXBsaW5nDQoNCkJlcmRhc2Fya2FuIHNpdHVhc2kgeWFuZyBkaWJlcmlrYW4sIGJlcmlrdXQgYWRhbGFoIGR1YSBqZW5pcyBrZXNhbGFoYW4gc2FtcGxpbmcgeWFuZyB0ZXJqYWRpOg0KDQojIyMgKioxLiBLZXNhbGFoYW4gUmVwcmVzZW50YXNpIChSZXByZXNlbnRhdGlvbiBFcnJvcikqKg0KDQpKdW1sYWggcmVzcG9uZGVuIHlhbmcgdGVya3VtcHVsIHRpZGFrIHNlc3VhaSBkZW5nYW4gdGFyZ2V0IGF3YWwgcGVyIGtvdGEsIHlhaXR1IDIwMCByZXNwb25kZW4gcGVyIGtvdGEuIFNpdHVhc2kgaW5pIG1lbnllYmFia2FuOg0KDQotIEtvdGEgQSBtZW1pbGlraSAyNTAgcmVzcG9uZGVuLCB5YW5nIGJlcmFydGkga2VsZWJpaGFuIDUwIHJlc3BvbmRlbiAoKzI1JSBkYXJpIHRhcmdldCkuDQotIEtvdGEgQiBoYW55YSBtZW1pbGlraSAxMjAgcmVzcG9uZGVuLCB5YW5nIGJlcmFydGkga2VrdXJhbmdhbiA4MCByZXNwb25kZW4gKC00MCUgZGFyaSB0YXJnZXQpLg0KLSBLb3RhIEMgbWVtaWxpa2kgMTgwIHJlc3BvbmRlbiwgeWFuZyBiZXJhcnRpIGtla3VyYW5nYW4gMjAgcmVzcG9uZGVuICgtMTAlIGRhcmkgdGFyZ2V0KS4NCg0KS2FyZW5hIGRpc3RyaWJ1c2kganVtbGFoIHJlc3BvbmRlbiB0aWRhayBzZWltYmFuZywgaGFzaWwgc3VydmVpIG1lbmphZGkgdGlkYWsgbWV3YWtpbGkgcHJvcG9yc2kgeWFuZyBkaWluZ2lua2FuLiBLb3RhIEEgeWFuZyBrZWxlYmloYW4gcmVzcG9uZGVuIGFrYW4gbWVtaWxpa2kgcGVuZ2FydWggeWFuZyBsZWJpaCBiZXNhciB0ZXJoYWRhcCBoYXNpbCBzdXJ2ZWkuDQoNCiMjIyAqKjIuIEtlc2FsYWhhbiBTYW1wbGluZyBOb24tUmVzcG9ucyAoTm9uLVJlc3BvbnNlIEVycm9yKSoqDQoNCktlc2FsYWhhbiBpbmkgdGVyamFkaSBrYXJlbmEgZGkgS290YSBCIGhhbnlhIDEyMCBvcmFuZyB5YW5nIGJlcmhhc2lsIGRpd2F3YW5jYXJhaSwgamF1aCBkaSBiYXdhaCB0YXJnZXQgMjAwLiBLZW11bmdraW5hbiBhZGEgZmFrdG9yLWZha3RvciB0ZXJ0ZW50dSB5YW5nIG1lbWJ1YXQgcmVzcG9uZGVuIGRpIEtvdGEgQiB0aWRhayBtYXUgYXRhdSB0aWRhayBiaXNhIGJlcnBhcnRpc2lwYXNpLCBzZXBlcnRpIGt1cmFuZ255YSB3YWt0dSwga2V0aWRha3BlcmNheWFhbiB0ZXJoYWRhcCBzdXJ2ZWksIGF0YXUgYWxhc2FuIGxhaW4uIEppa2Ega2FyYWt0ZXJpc3RpayBtZXJla2EgYmVyYmVkYSBkYXJpIHlhbmcgYmVycGFydGlzaXBhc2ksIGhhc2lsIHN1cnZlaSBha2FuIGJpYXMuDQoNCi0tLQ0KDQojIyBNZW5naGl0dW5nIEJvYm90IFJlc3BvbmRlbg0KDQpVbnR1ayBtZW5nZW1iYWxpa2FuIHJlcHJlc2VudGFzaSBwcm9wb3JzaW9uYWwga2UgdGFyZ2V0IGF3YWwgKDIwMCByZXNwb25kZW4gcGVyIGtvdGEgZGFyaSB0b3RhbCA2MDApLCBib2JvdCB1bnR1ayBtYXNpbmctbWFzaW5nIGtvdGEgZGloaXR1bmcgc2ViYWdhaSBiZXJpa3V0Og0KDQoxLiAqKlByb3BvcnNpIFRhcmdldDoqKg0KICAgLSBLb3RhIEE6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KICAgLSBLb3RhIEI6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezIwMH17NjAwfSA9IDAuMzMzMyBcKQ0KDQoyLiAqKlByb3BvcnNpIEFrdHVhbDoqKg0KICAgLSBLb3RhIEE6IFwoIFxmcmFjezI1MH17NTUwfSBcYXBwcm94IDAuNDU0NSBcKQ0KICAgLSBLb3RhIEI6IFwoIFxmcmFjezEyMH17NTUwfSBcYXBwcm94IDAuMjE4MiBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezE4MH17NTUwfSBcYXBwcm94IDAuMzI3MyBcKQ0KDQozLiAqKkJvYm90OioqDQogICAtIEtvdGEgQTogXCggXGZyYWN7MC4zMzMzfXswLjQ1NDV9IFxhcHByb3ggMC43MzMgXCkNCiAgIC0gS290YSBCOiBcKCBcZnJhY3swLjMzMzN9ezAuMjE4Mn0gXGFwcHJveCAxLjUyOCBcKQ0KICAgLSBLb3RhIEM6IFwoIFxmcmFjezAuMzMzM317MC4zMjczfSBcYXBwcm94IDEuMDE4IFwpDQoNCi0tLQ0KDQojIyBJbXBsZW1lbnRhc2kgUGVyaGl0dW5nYW4gZGVuZ2FuIFINCg0KQmVyaWt1dCBhZGFsYWggaW1wbGVtZW50YXNpIGtvZGUgdW50dWsgbWVuZ2hpdHVuZyBib2JvdCBtZW5nZ3VuYWthbiBSOg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KbGlicmFyeShrbml0cikNCg0KIyBEYXRhIGp1bWxhaCB0YXJnZXQgZGFuIGFrdHVhbCBwZXIga290YQ0Ka290YSA8LSBjKCJLb3RhIEEiLCAiS290YSBCIiwgIktvdGEgQyIpDQp0YXJnZXQgPC0gYygyMDAsIDIwMCwgMjAwKQ0KYWt0dWFsIDwtIGMoMjUwLCAxMjAsIDE4MCkNCg0KIyBUb3RhbA0KdG90YWxfdGFyZ2V0IDwtIHN1bSh0YXJnZXQpDQp0b3RhbF9ha3R1YWwgPC0gc3VtKGFrdHVhbCkNCg0KIyBIaXR1bmcgcHJvcG9yc2kgdGFyZ2V0IGRhbiBha3R1YWwNCnByb3BvcnNpX3RhcmdldCA8LSB0YXJnZXQgLyB0b3RhbF90YXJnZXQNCnByb3BvcnNpX2FrdHVhbCA8LSBha3R1YWwgLyB0b3RhbF9ha3R1YWwNCg0KIyBIaXR1bmcgYm9ib3QNCmJvYm90IDwtIHJvdW5kKHByb3BvcnNpX3RhcmdldCAvIHByb3BvcnNpX2FrdHVhbCwgMykNCg0KIyBCdWF0IGRhdGEgZnJhbWUgaGFzaWwNCmhhc2lsIDwtIGRhdGEuZnJhbWUoDQogIEtvdGEgPSBrb3RhLA0KICBUYXJnZXQgPSB0YXJnZXQsDQogIEFrdHVhbCA9IGFrdHVhbCwNCiAgYFByb3BvcnNpIFRhcmdldGAgPSByb3VuZChwcm9wb3JzaV90YXJnZXQsIDQpLA0KICBgUHJvcG9yc2kgQWt0dWFsYCA9IHJvdW5kKHByb3BvcnNpX2FrdHVhbCwgNCksDQogIGBCb2JvdCBQZW55ZXN1YWlhbmAgPSBib2JvdA0KKQ0KDQojIFRhbXBpbGthbiBoYXNpbA0Ka2FibGUoaGFzaWwsIGNhcHRpb24gPSAiVGFiZWwgUGVueWVzdWFpYW4gQm9ib3QgUmVzcG9uZGVuIHBlciBLb3RhIikNCmBgYA0KDQojIFN0dWRpIEthc3VzIDIgKCoqTWVuZGVzYWluIFN1cnZlaSBkZW5nYW4gUGVtYm9ib3RhbiBXYWt0dSBQdW5jYWsqKikNCg0KQnVhdGxhaCBkZXNhaW4gcmFuY2FuZ2FuIHN1cnZlaSB0ZW50YW5nICoqcGVyc2Vwc2kga2VueWFtYW5hbiBwZW5nZ3VuYSBvamVrIG9ubGluZSBzYWF0IGphbSBzaWJ1ayAoMDcuMDDigJMwOS4wMCBkYW4gMTcuMDDigJMxOS4wMCkuKioNCg0KKkluc3RydWtzaToqDQoNCmEuIERlc2FpbiBwZW5kZWthdGFuIHNhbXBsaW5nIHlhbmcgKiptZW11bmdraW5rYW4gQW5kYSBtZW5hbmdrYXAgcGVyc2Vwc2kgcGVuZ2d1bmEgc2VjYXJhIHJlcHJlc2VudGF0aWYgcGFkYSBqYW0gc2lidWssKiogdGFucGEgbWVsYWt1a2FuIHN1cnZlaSBzZXBhbmphbmcgaGFyaS4NCg0KYi4gU2VydGFrYW4gKipyYW5jYW5nYW4gd2FrdHUsIG1ldG9kZSBwZW1pbGloYW4gcmVzcG9uZGVuLCBkYW4ganVzdGlmaWthc2kgcGVtaWxpaGFuIHVuaXQgc2FtcGxpbmcqKi4NCg0KYy4gSmVsYXNrYW4gYmFnYWltYW5hIEFuZGEgYWthbiBtZW55ZXN1YWlrYW4gaGFzaWwgc3VydmVpIGppa2EgNjAlIHJlc3BvbmRlbiBiZXJhc2FsIGRhcmkgcGFnaSBoYXJpLCBzZW1lbnRhcmEgNDAlIGRhcmkgc29yZSBoYXJpLCBzZWRhbmdrYW4gZGF0YSBoaXN0b3JpcyBtZW51bmp1a2thbiBwZW5nZ3VuYSBvamVrIG9ubGluZSBzYWF0IHNvcmUgaGFyaSBkdWEga2FsaSBsZWJpaCBiYW55YWsgZGliYW5kaW5nIHBhZ2kuDQoNCi0tLQ0KDQojIyBEZXNhaW4gUGVuZGVrYXRhbiBTYW1wbGluZw0KDQpVbnR1ayBtZW1hc3Rpa2FuIHN1cnZlaSB5YW5nIHJlcHJlc2VudGF0aWYsIHBlbmRla2F0YW4geWFuZyBkaWd1bmFrYW4gYWRhbGFoICoqc3RyYXRpZmllZCB0aW1lIHNhbXBsaW5nKiosIGRlbmdhbiBwZW1iYWdpYW4gZHVhIHN0cmF0YSB3YWt0dToNCg0KLSAqKlBhZ2kgKDA3LjAw4oCTMDkuMDApOioqIEZva3VzIHBhZGEgamFtIGJlcmFuZ2thdCBrZXJqYS9zZWtvbGFoLg0KLSAqKlNvcmUgKDE3LjAw4oCTMTkuMDApOioqIEZva3VzIHBhZGEgamFtIHB1bGFuZyBrZXJqYS9zZWtvbGFoLg0KDQpEZW5nYW4gcGVuZGVrYXRhbiBpbmksIHN1cnZlaSBoYW55YSBkaWxha3VrYW4gcGFkYSBqYW0gc2lidWsgeWFuZyByZWxldmFuLCBzZWhpbmdnYSBlZmlzaWVuIGRhbiB0ZXRhcCByZXByZXNlbnRhdGlmIHRhbnBhIGhhcnVzIG1lbmd1bXB1bGthbiBkYXRhIHNlcGFuamFuZyBoYXJpLiBNYXNpbmctbWFzaW5nIHN0cmF0YSB3YWt0dSBtZXJlcHJlc2VudGFzaWthbiBwb2xhIHBlbmdndW5hYW4gb2playBvbmxpbmUgeWFuZyBiZXJiZWRhLg0KDQotLS0NCg0KIyMgUmFuY2FuZ2FuIFdha3R1LCBNZXRvZGUsIGRhbiBKdXN0aWZpa2FzaQ0KDQoqKlJhbmNhbmdhbiBXYWt0dToqKg0KLSBTdXJ2ZWkgZGlsYWtzYW5ha2FuIHBhZGEgaGFyaSBrZXJqYSAoU2VuaW4tSnVtYXQpIHNlbGFtYSBkdWEgd2FrdHUgc2lidWs6IHBhZ2kgKDA3LjAw4oCTMDkuMDApIGRhbiBzb3JlICgxNy4wMOKAkzE5LjAwKS4NCg0KKipNZXRvZGUgUGVtaWxpaGFuIFJlc3BvbmRlbjoqKg0KLSAqKlN5c3RlbWF0aWMgaW50ZXJjZXB0IHNhbXBsaW5nOioqIFJlc3BvbmRlbiBkaXBpbGloIHNlY2FyYSBzaXN0ZW1hdGlzIHBhZGEgbG9rYXNpLWxva2FzaSBzdHJhdGVnaXMsIHNlcGVydGkgc3Rhc2l1biwgdGVybWluYWwsIGF0YXUga2F3YXNhbiBwZXJrYW50b3Jhbi4NCi0gQ29udG9oOiBTZXRpYXAgMTAgbWVuaXQsIHNhdHUgcGVuZ2d1bmEgb2playBvbmxpbmUgeWFuZyBiYXJ1IHR1cnVuIGRpd2F3YW5jYXJhaS4NCg0KKipKdXN0aWZpa2FzaSBQZW1pbGloYW4gVW5pdCBTYW1wbGluZzoqKg0KLSBVbml0IHNhbXBsaW5nIGFkYWxhaCAqKnBlbmdndW5hIGFrdGlmIG9qZWsgb25saW5lIHBhZGEgamFtIHNpYnVrKiouIE1lcmVrYSBkaXBpbGloIGthcmVuYSBiZXJhZGEgZGkgbG9rYXNpIGRhbiB3YWt0dSB5YW5nIHJlbGV2YW4gdW50dWsgbWVuZ2dhbWJhcmthbiBwZXJzZXBzaSBrZW55YW1hbmFuIHNlY2FyYSBsYW5nc3VuZy4NCg0KLS0tDQoNCiMjIFBlbnllc3VhaWFuIEhhc2lsIFN1cnZlaSBCZXJkYXNhcmthbiBEYXRhIEhpc3RvcmlzDQoNCkRhbGFtIHN1cnZlaSBpbmk6DQotICoqNjAlIHJlc3BvbmRlbiBiZXJhc2FsIGRhcmkgcGFnaSBoYXJpICgwNy4wMOKAkzA5LjAwKS4qKg0KLSAqKjQwJSByZXNwb25kZW4gYmVyYXNhbCBkYXJpIHNvcmUgaGFyaSAoMTcuMDDigJMxOS4wMCkuKioNCg0KTmFtdW4sIGRhdGEgaGlzdG9yaXMgbWVudW5qdWtrYW4gYmFod2E6DQotIFBlbmdndW5hIG9qZWsgb25saW5lIGRpIHNvcmUgaGFyaSBkdWEga2FsaSBsZWJpaCBiYW55YWsgZGliYW5kaW5na2FuIHBhZ2kgaGFyaS4NCg0KIyMjIFByb3BvcnNpIEFrdHVhbCBCZXJkYXNhcmthbiBEYXRhIEhpc3RvcmlzOg0KLSAqKlBhZ2k6KiogMSBiYWdpYW4gKDEvMyBhdGF1IDAuMzMpDQotICoqU29yZToqKiAyIGJhZ2lhbiAoMi8zIGF0YXUgMC42NykNCg0KIyMjIFBlbnllc3VhaWFuIEJvYm90Og0KVW50dWsgbWVuZ2hpbmRhcmkgYmlhcyBha2liYXQga2V0aWRha3NlaW1iYW5nYW4ganVtbGFoIHJlc3BvbmRlbiwgZGlsYWt1a2FuIHBlbnllc3VhaWFuIGJvYm90IGJlcmRhc2Fya2FuIHByb3BvcnNpIGFrdHVhbCBkYW4gcHJvcG9yc2kgc3VydmVpLg0KDQoqKlJ1bXVzIEJvYm90OioqDQokJA0KXHRleHR7Qm9ib3Qgd2FrdHV9ID0gXGZyYWN7XHRleHR7UHJvcG9yc2kgc2ViZW5hcm55YX19e1x0ZXh0e1Byb3BvcnNpIGhhc2lsIHN1cnZlaX19DQokJA0KDQoqKlBlcmhpdHVuZ2FuIEJvYm90OioqDQotICoqQm9ib3QgcGFnaToqKiBcKCAwLjMzIC8gMC42MCBcYXBwcm94IDAuNTYgXCkNCi0gKipCb2JvdCBzb3JlOioqIFwoIDAuNjcgLyAwLjQwIFxhcHByb3ggMS42NyBcKQ0KDQpgYGB7cn0NCmxpYnJhcnkoa25pdHIpDQoNCiMgRGF0YSBwZW1ib2JvdGFuDQpwZW1ib2JvdGFuX2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgV2FrdHUgPSBjKCJQYWdpIiwgIlNvcmUiKSwNCiAgUHJvcG9yc2lfU3VydmVpID0gYygwLjYwLCAwLjQwKSwNCiAgUHJvcG9yc2lfQWt0dWFsID0gYygxLzMsIDIvMyksDQogIEJvYm90ID0gYygoMS8zKS8wLjYwLCAoMi8zKS8wLjQwKQ0KKQ0KDQojIFRhYmVsIHBlbWJvYm90YW4NCmthYmxlKHBlbWJvYm90YW5fZGF0YSwgY2FwdGlvbiA9ICJQZW1ib2JvdGFuIEJlcmRhc2Fya2FuIFByb3BvcnNpIEhpc3RvcmlzIFBlbmdndW5hIikNCmBgYA0KDQotLS0NCg0KIyMgU2ltdWxhc2kgRGF0YSBkYW4gQW5hbGlzaXMNCg0KIyMjIERhdGEgU2ltdWxhc2kNCg0KS2l0YSBidWF0IGRhdGEgc2ltdWxhc2kgdW50dWsgMTAwIHJlc3BvbmRlbjoNCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpICAjIEZvciByZXByb2R1Y2liaWxpdHkNCg0KIyBNZW1idWF0IGRhdGEgdW50dWsgMTAwIHJlc3BvbmRlbg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICByZXNwb25kZW50X2lkID0gMToxMDAsDQogIHRpbWVfcGVyaW9kID0gYyhyZXAoIlBhZ2kiLCA2MCksIHJlcCgiU29yZSIsIDQwKSksDQogIHNhdGlzZmFjdGlvbl9zY29yZSA9IGMocm5vcm0oNjAsIG1lYW4gPSA3LCBzZCA9IDEuNSksIHJub3JtKDQwLCBtZWFuID0gOCwgc2QgPSAxLjIpKQ0KKQ0KDQpoZWFkKGRhdGEpDQoNCmBgYA0KDQojIyMgVGVyYXBrYW4gQm9ib3QNCg0KVGFtYmFoa2FuIGJvYm90IGtlIGRhdGEgYmVyZGFzYXJrYW4gd2FrdHU6DQoNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCg0KZGF0YSA8LSBkYXRhICU+JQ0KICBsZWZ0X2pvaW4ocGVtYm9ib3Rhbl9kYXRhICU+JSBzZWxlY3QoV2FrdHUsIEJvYm90KSwgYnkgPSBjKCJ0aW1lX3BlcmlvZCIgPSAiV2FrdHUiKSkgJT4lDQogIG11dGF0ZSh3ZWlnaHRlZF9zY29yZSA9IHNhdGlzZmFjdGlvbl9zY29yZSAqIEJvYm90KQ0KDQpoZWFkKGRhdGEpDQpgYGANCg0KIyMjIFBlcmhpdHVuZ2FuIFJhdGEtcmF0YSBCZXJib2JvdA0KDQpIaXR1bmcgcmF0YS1yYXRhIGJlcmJvYm90Og0KDQpgYGB7cn0NCndlaWdodGVkX21lYW4gPC0gc3VtKGRhdGEkd2VpZ2h0ZWRfc2NvcmUpIC8gc3VtKGRhdGEkQm9ib3QpDQp3ZWlnaHRlZF9tZWFuDQpgYGANCg0KIyBTdHVkaSBLYXN1cyAzICgqKkV2YWx1YXNpIEtlcHVhc2FuIE1haGFzaXN3YSB0ZXJoYWRhcCBMYXlhbmFuIEFrYWRlbWlrKiopDQpBbmRhIGRpdHVnYXNrYW4gb2xlaCBiaXJvIGFrYWRlbWlrIGthbXB1cyB1bnR1ayBtZXJhbmNhbmcgaW5zdHJ1bWVuIHN1cnZlaSB5YW5nDQpiZXJ0dWp1YW4gbWVuZ2V2YWx1YXNpIGtlcHVhc2FuIG1haGFzaXN3YSB0ZXJoYWRhcCBsYXlhbmFuIGFrYWRlbWlrLCB5YW5nDQptZW5jYWt1cCBsYXlhbmFuIHNlcGVydGk6IEtSUyBvbmxpbmUsIGJpbWJpbmdhbiBha2FkZW1paywgcGVsYXlhbmFuIGFkbWluaXN0cmFzaSwgYWtzZXMNCmluZm9ybWFzaSBha2FkZW1paywgZGFuIGJhbnR1YW4gcGVueWVsZXNhaWFuIHN0dWRpLg0KDQpUaW0gcGVuZWxpdGkgbWVtaW50YSBBbmRhIHVudHVrOg0KDQotIE1lcmFuY2FuZyAyNSBwZXJ0YW55YWFuIHV0YW1hIGRlbmdhbiAqKnZhcmlhc2kgc2thbGEgZGFuIGJlbnR1ayBwZXJ0YW55YWFuKiouDQoNCi0gTWVyYW5jYW5nIHNpc3RlbSB2YWxpZGFzaSBpbnN0cnVtZW4uDQoNCi0gTWVuZW50dWthbiBtZXRvZGUgZGlzdHJpYnVzaSBkYW4gcGVuZ3VqaWFuIGt1ZXNpb25lciBzZWNhcmEgc3RhdGlzdGlrLg0KDQotIE1lbnlpYXBrYW4gc2ltdWxhc2kgc3RyYXRlZ2kgcGVuZ2FtYmlsYW4gc2FtcGVsIGRhbiBwZW5nb2xhaGFuIGRhdGEgYXdhbC4NCg0KT3V0cHV0IExhcG9yYW4geWFuZyBkaWhhcmFwa2FuIGRhbGFtIGJlbnR1ayBuYXJhdGlmLCBtZW5jYWt1cDoNCg0K4oCiIERlc2FpbiBwZXJ0YW55YWFuDQoNCuKAoiBTa2VtYSB2YWxpZGFzaQ0KDQrigKIgU3RyYXRlZ2kgZGlzdHJpYnVzaSBkYW4gc2FtcGxpbmcNCg0K4oCiIFNpbXVsYXNpIGRhdGEgZGFuIGFuYWxpc2lzIGF3YWwNCg0KLS0tDQoNCiMjIDEuIERlc2FpbiBQZXJ0YW55YWFuDQpCZXJpa3V0IGFkYWxhaCBkZXNhaW4gMjUgcGVydGFueWFhbiB5YW5nIHRlcmJhZ2kgZGFsYW0gbGltYSBhc3BlayBsYXlhbmFuIGFrYWRlbWlrOg0KDQotICoqS1JTIE9ubGluZSoqDQotICoqQmltYmluZ2FuIEFrYWRlbWlrKioNCi0gKipQZWxheWFuYW4gQWRtaW5pc3RyYXNpKioNCi0gKipBa3NlcyBJbmZvcm1hc2kgQWthZGVtaWsqKg0KLSAqKkJhbnR1YW4gUGVueWVsZXNhaWFuIFN0dWRpKioNCg0KTGluayBQZXJ0YW55YWFuIEdvb2dsZSBGb3JtOiA8YSBocmVmPSJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9mb3Jtcy9kL2UvMUZBSXBRTFNjZE5lOTN1NkhLUW9VYVZtXzVLTzN3MGhHWVRTX2pHSG10cHEzdU45TmNDR2lWZGcvdmlld2Zvcm0/dXNwPXNoYXJpbmciPkdvb2dsZSBGb3JtPC9hPg0KDQotLS0NCg0KIyMgMi4gU2tlbWEgdmFsaWRhc2kNCg0KIyMjIDIuMSBWYWxpZGFzaSBJc2kgKENvbnRlbnQgVmFsaWRpdHkpDQoNClByb3NlcyB2YWxpZGFzaSBpc2kgZGlsYWt1a2FuIGRlbmdhbiBtZWxpYmF0a2FuIHBha2FyIGF0YXUgZG9zZW4gZGkgYmlkYW5nIHBlbmRpZGlrYW4gdW50dWsgbWVuaWxhaSByZWxldmFuc2kgc2V0aWFwIHBlcnRhbnlhYW4gdGVyaGFkYXAgYXNwZWsgeWFuZyBkaWV2YWx1YXNpLiBQZW5pbGFpYW4gZGlsYWt1a2FuIGRlbmdhbiB0aWdhIGthdGVnb3JpOg0KDQotIFNhbmdhdCByZWxldmFuDQoNCi0gQ3VrdXAgcmVsZXZhbg0KDQotIFRpZGFrIHJlbGV2YW4NCg0KSGFzaWwgcGVuaWxhaWFuIGRpaGl0dW5nIG1lbmdndW5ha2FuIENvbnRlbnQgVmFsaWRpdHkgUmF0aW8gKENWUikuIEppa2EgQ1ZSIGRhcmkgc3VhdHUgcGVydGFueWFhbiBiZXJhZGEgZGkgYXRhcyBhbWJhbmcgYmF0YXMgeWFuZyBkaXRlbnR1a2FuLCBtYWthIHBlcnRhbnlhYW4gdGVyc2VidXQgZGlhbmdnYXAgdmFsaWQgc2VjYXJhIGlzaS4gU2ViYWxpa255YSwgamlrYSBDVlIgcmVuZGFoLCBwZXJ0YW55YWFuIHRlcnNlYnV0IHBlcmx1IGRpcmV2aXNpIGF0YXUgZGloYXB1cy4NCg0KIyMjIDIuMiBWYWxpZGFzaSBTdGF0aXN0aWsNCg0KU2V0ZWxhaCB2YWxpZGFzaSBpc2kgc2VsZXNhaSwgZGlsYWt1a2FuIHVqaSBjb2JhIGt1ZXNpb25lciBrZXBhZGEgMzAgbWFoYXNpc3dhIHNlYmFnYWkgdGFoYXAgYXdhbCBwZW5ndWppYW4gc3RhdGlzdGlrLg0KDQojIyMjIDIuMi4xIFVqaSBWYWxpZGl0YXMgS29uc3RydWsgKENvbnN0cnVjdCBWYWxpZGl0eSkNCg0KVWppIGluaSBiZXJ0dWp1YW4gdW50dWsgbWVtYXN0aWthbiBiYWh3YSBzZXRpYXAgcGVydGFueWFhbiBkYWxhbSBrdWVzaW9uZXIgYmVuYXItYmVuYXIgbWVuZ3VrdXIgYXNwZWsgeWFuZyBzZXN1YWkuIFBlbmRla2F0YW4geWFuZyBkaWd1bmFrYW46DQoNCi0gS29yZWxhc2kgSXRlbS1Ub3RhbDogTWVuZ2hpdHVuZyBrb3JlbGFzaSBhbnRhcmEgc2V0aWFwIGl0ZW0gZGVuZ2FuIHRvdGFsIHNrb3IgZGFyaSBhc3BlayB0ZXJrYWl0LiBLb3JlbGFzaSA+IDAuMyBtZW51bmp1a2thbiB2YWxpZGl0YXMgeWFuZyBiYWlrLg0KDQotIEFuYWxpc2lzIEZha3RvcjogRGlsYWt1a2FuIGVrc3Bsb3Jhc2kgbWVuZ2d1bmFrYW4gbWV0b2RlIEFuYWxpc2lzIEZha3RvciBFa3NwbG9yYXRvcmkgKEVGQSkgdW50dWsgbWVtYXN0aWthbiBiYWh3YSBrZWxvbXBvayBwZXJ0YW55YWFuIG1lbWJlbnR1ayBmYWt0b3IgeWFuZyBkaWhhcmFwa2FuLg0KDQojIyMjIDIuMi4yIFVqaSBSZWxpYWJpbGl0YXMNCg0KUmVsaWFiaWxpdGFzIGluc3RydW1lbiBkaXVqaSBtZW5nZ3VuYWthbiBDcm9uYmFjaOKAmXMgQWxwaGEgdW50dWsgbWVuZ2V2YWx1YXNpIGtvbnNpc3RlbnNpIGludGVybmFsIGFudGFyaXRlbS4gS3JpdGVyaWE6DQoNCi0gQWxwaGEgPiAwLjc6IEluc3RydW1lbiBkaWFuZ2dhcCByZWxpYWJlbC4NCg0KLSBBbHBoYSA8IDAuNzogUGVybHUgZGlsYWt1a2FuIHJldmlzaSBwYWRhIGl0ZW0gdGVydGVudHUgeWFuZyBtZW5ndXJhbmdpIHJlbGlhYmlsaXRhcy4NCg0KDQotLS0NCg0KIyMgMy4gU3RyYXRlZ2kgRGlzdHJpYnVzaSBkYW4gU2FtcGxpbmcNCg0KIyMjIDMuMSBTdHJhdGVnaSBEaXN0cmlidXNpDQoNCkt1ZXNpb25lciBha2FuIGRpc2ViYXJrYW4gc2VjYXJhIGRhcmluZyBtZW5nZ3VuYWthbiBwbGF0Zm9ybSBHb29nbGUgRm9ybXMuIExhbmdrYWggZGlzdHJpYnVzaSBtZWxpcHV0aToNCg0KLSBFbWFpbCBLYW1wdXM6IEt1ZXNpb25lciBkaWtpcmltIG1lbGFsdWkgc2lzdGVtIGVtYWlsIHJlc21pIGtlcGFkYSBzZWx1cnVoIG1haGFzaXN3YSBha3RpZi4NCg0KLSBHcnVwIE1lZGlhIFNvc2lhbDogVGF1dGFuIGt1ZXNpb25lciBkaXNlYmFya2FuIG1lbGFsdWkgZ3J1cCBXaGF0c0FwcCwgVGVsZWdyYW0sIGRhbiBwbGF0Zm9ybSBrb211bmlrYXNpIGxhaW5ueWEuDQoNCi0gTE1TIEthbXB1czogS3Vlc2lvbmVyIGp1Z2EgYWthbiB0ZXJzZWRpYSBkaSBMZWFybmluZyBNYW5hZ2VtZW50IFN5c3RlbSAoTE1TKSBrYW1wdXMgdW50dWsgbWVuaW5na2F0a2FuIGFrc2VzaWJpbGl0YXMuDQoNClBlbmdpbmdhdCBha2FuIGRpa2lyaW1rYW4gc2VjYXJhIGJlcmthbGEgdW50dWsgbWVuaW5na2F0a2FuIHRpbmdrYXQgcmVzcG9ucy4gU2VsYWluIGl0dSwgaW5zZW50aWYgYmVydXBhIHNlcnRpZmlrYXQgcGFydGlzaXBhc2kgYXRhdSBoYWRpYWgga2VjaWwgZGFwYXQgZGliZXJpa2FuIGtlcGFkYSByZXNwb25kZW4gc2ViYWdhaSBiZW50dWsgYXByZXNpYXNpLg0KDQojIyMgMy4yIFN0cmF0ZWdpIFNhbXBsaW5nDQoNCiMjIyMgMy4yLjEgUG9wdWxhc2kgZGFuIFRla25payBTYW1wbGluZw0KDQpQb3B1bGFzaSB0YXJnZXQgYWRhbGFoIHNlbHVydWggbWFoYXNpc3dhIGFrdGlmIGRpIGthbXB1cy4gTWV0b2RlIHNhbXBsaW5nIHlhbmcgZGlndW5ha2FuIGFkYWxhaCBTdHJhdGlmaWVkIFJhbmRvbSBTYW1wbGluZyBkZW5nYW4gc3RyYXRhIGJlcmRhc2Fya2FuOg0KDQotIFByb2dyYW0gU3R1ZGkNCg0KLSBBbmdrYXRhbiAobWlzYWxueWEgMjAyMC0yMDIzKQ0KDQpTdHJhdGlmaWthc2kgaW5pIGJlcnR1anVhbiB1bnR1ayBtZW1hc3Rpa2FuIGJhaHdhIHNldGlhcCBrZWxvbXBvayB0ZXJ3YWtpbGkgZGFsYW0gc3VydmVpLg0KDQojIyMjIDMuMi4yIFVrdXJhbiBTYW1wZWwNCg0KTWVuZ2FjdSBwYWRhIHBvcHVsYXNpIG1haGFzaXN3YSBha3RpZiBzZWJhbnlhayAxMC4wMDAgb3JhbmcsIGRpcGVybHVrYW4gbWluaW1hbCAzODQgcmVzcG9uZGVuIHVudHVrIHRpbmdrYXQga2VwZXJjYXlhYW4gOTUlIGRhbiBtYXJnaW4gb2YgZXJyb3IgNSUuIFVudHVrIHRhaGFwIHVqaSBjb2JhLCAzMCByZXNwb25kZW4gYXdhbCBha2FuIGRpZ3VuYWthbiB1bnR1ayBtZW12YWxpZGFzaSBpbnN0cnVtZW4gc2VjYXJhIHN0YXRpc3Rpay4NCg0KIyMjIyAzLjIuMyBBbG9rYXNpIFNhbXBlbA0KDQpSZXNwb25kZW4gZGFyaSBzZXRpYXAgc3RyYXRhIGFrYW4gZGlhbWJpbCBzZWNhcmEgcHJvcG9yc2lvbmFsLiBNaXNhbG55YSwgamlrYSBQcm9ncmFtIFN0dWRpIEEgbWVtaWxpa2kgMjAlIHBvcHVsYXNpLCBtYWthIDIwJSBkYXJpIHRvdGFsIHNhbXBlbCBha2FuIGRpYW1iaWwgZGFyaSBwcm9ncmFtIHN0dWRpIHRlcnNlYnV0Lg0KDQojIyMjIDMuMi40IFBlbmluZ2thdGFuIFJlc3BvbnMNCg0KU3RyYXRlZ2kgdW50dWsgbWVuaW5na2F0a2FuIHRpbmdrYXQgcmVzcG9ucyBtZWxpcHV0aToNCg0KLSBNZW5naXJpbWthbiBwZW5naW5nYXQgc2VjYXJhIGJlcmthbGEga2VwYWRhIG1haGFzaXN3YSB5YW5nIGJlbHVtIG1lbmdpc2kga3Vlc2lvbmVyLg0KDQotIE1lbGliYXRrYW4gb3JnYW5pc2FzaSBtYWhhc2lzd2EgZGFuIGRvc2VuIHVudHVrIG1lbXByb21vc2lrYW4gc3VydmVpLg0KDQotIE1lbWJlcmlrYW4gaW5zZW50aWYga2VwYWRhIHJlc3BvbmRlbiB5YW5nIGJlcnBhcnRpc2lwYXNpLg0KDQotLS0NCg0KIyMgNC4gU2ltdWxhc2kgRGF0YSBkYW4gYW5hbGlzaXMgYXdhbA0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KIyBTaW11bGFzaSBEYXRhIFN1cnZlaSBLZXB1YXNhbiBNYWhhc2lzd2ENCnNldC5zZWVkKDEyMykNCg0KIyBNZW1idWF0IGRhdGEgdW50dWsgNSBrYXRlZ29yaSBsYXlhbmFuDQpkYXRhX2tycyA8LSBkYXRhLmZyYW1lKA0KICBLUlNfYWtzZXMgPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgS1JTX21hc2FsYWggPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgS1JTX2VmaXNpZW5zaSA9IHNhbXBsZShjKCJZYSIsICJUaWRhayIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFKQ0KKQ0KDQojIEdhYnVuZ2thbiBkYXRhIHVudHVrIDUga2F0ZWdvcmkgbGFpbm55YQ0KZGF0YV9iaW1iaW5nYW4gPC0gZGF0YS5mcmFtZSgNCiAgQmltYmluZ2FuX2ZyZWt1ZW5zaSA9IHNhbXBsZSgxOjEwLCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQmltYmluZ2FuX2t1YWxpdGFzID0gc2FtcGxlKDE6NSwgMTAwLCByZXBsYWNlID0gVFJVRSkNCikNCg0KZGF0YV9hZG1pbmlzdHJhc2kgPC0gZGF0YS5mcmFtZSgNCiAgQWRtaW5pc3RyYXNpX3Jlc3BvbnMgPSBzYW1wbGUoMTo1LCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQWRtaW5pc3RyYXNpX2tlbXVkYWhhbiA9IHNhbXBsZShjKCJZYSIsICJUaWRhayIpLCAxMDAsIHJlcGxhY2UgPSBUUlVFKQ0KKQ0KDQpkYXRhX2Frc2VzIDwtIGRhdGEuZnJhbWUoDQogIEFrc2VzX2ZyZWt1ZW5zaSA9IHNhbXBsZSgxOjEwLCAxMDAsIHJlcGxhY2UgPSBUUlVFKSwNCiAgQWtzZXNfaW5mb3JtYXRpZiA9IHNhbXBsZSgxOjUsIDEwMCwgcmVwbGFjZSA9IFRSVUUpDQopDQoNCmRhdGFfYmFudHVhbiA8LSBkYXRhLmZyYW1lKA0KICBCYW50dWFuX3N0dWRpID0gc2FtcGxlKDE6NSwgMTAwLCByZXBsYWNlID0gVFJVRSksDQogIEJhbnR1YW5fdGVyc2VkaWEgPSBzYW1wbGUoYygiWWEiLCAiVGlkYWsiKSwgMTAwLCByZXBsYWNlID0gVFJVRSkNCikNCg0KIyBHYWJ1bmdrYW4gc2VtdWEgZGF0YSBtZW5qYWRpIHNhdHUgZGF0YSBmcmFtZQ0KZGF0YV9zdXJ2ZWkgPC0gY2JpbmQoZGF0YV9rcnMsIGRhdGFfYmltYmluZ2FuLCBkYXRhX2FkbWluaXN0cmFzaSwgZGF0YV9ha3NlcywgZGF0YV9iYW50dWFuKQ0KaGVhZChkYXRhX3N1cnZlaSkNCmBgYA0KDQoNCiMjIyA0LjEgRGVza3JpcHNpIFN0YXRpc3RpayBBd2FsDQpLaXRhIGFrYW4gbWVuZ2hpdHVuZyBiZWJlcmFwYSBkZXNrcmlwc2kgc3RhdGlzdGlrIHVudHVrIG1lbGloYXQgZGlzdHJpYnVzaSBkYXRhIGRhcmkgc2V0aWFwIGthdGVnb3JpLg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0Kc3VtbWFyeV9zdGF0aXN0aWNzIDwtIGRhdGFfc3VydmVpICU+JQ0KICBzdW1tYXJpc2VfYWxsKGxpc3QobWVhbiA9IH5tZWFuKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgIHNkID0gfnNkKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgIG1lZGlhbiA9IH5tZWRpYW4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoLikpLCBuYS5ybSA9IFRSVUUpKSkNCg0Ka25pdHI6OmthYmxlKHN1bW1hcnlfc3RhdGlzdGljcywgY2FwdGlvbiA9ICJEZXNrcmlwc2kgU3RhdGlzdGlrIEF3YWwiKQ0KYGBgDQoNCiMjIyA0LjIgVWppIFZhbGlkaXRhcyBkYW4gUmVsaWFiaWxpdGFzDQoNCiMjIyMgNC4yLjEgS29yZWxhc2kgSXRlbS1Ub3RhbA0KVW50dWsgbWVtZXJpa3NhIHZhbGlkaXRhcyBrb25zdHJ1aywga2l0YSBha2FuIG1lbmdoaXR1bmcga29yZWxhc2kgYW50YXJhIGl0ZW0gZGFuIHRvdGFsIHNrb3IgdW50dWsgc2V0aWFwIGthdGVnb3JpLg0KDQpgYGB7cn0NCiMgTWVuZ2hpdHVuZyBrb3JlbGFzaSBpdGVtLXRvdGFsIHVudHVrIGthdGVnb3JpIEtSUw0KY29yX2tycyA8LSBjb3IoZGF0YV9rcnMkS1JTX2Frc2VzLCBkYXRhX2tycyRLUlNfbWFzYWxhaCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQpjb3Jfa3JzDQpgYGANCg0KIyMjIyA0LjIuMiBDcm9uYmFjaCdzIEFscGhhDQpLaXRhIGFrYW4gbWVuZ3VrdXIgcmVsaWFiaWxpdGFzIHNldGlhcCBrYXRlZ29yaSBtZW5nZ3VuYWthbiBDcm9uYmFjaCdzIEFscGhhLg0KYGBge3J9DQpsaWJyYXJ5KHBzeWNoKQ0KDQojIEZ1bmdzaSB1bnR1ayBtZW5naGl0dW5nIENyb25iYWNoJ3MgQWxwaGENCmNyb25iYWNoX2FscGhhIDwtIGZ1bmN0aW9uKGRhdGEpIHsNCiAgbnVtZXJpY19kYXRhIDwtIGRhdGFbc2FwcGx5KGRhdGEsIGlzLm51bWVyaWMpXQ0KICBkYXRhX2NsZWFuIDwtIG5hLm9taXQobnVtZXJpY19kYXRhKQ0KICBhbHBoYV9yZXN1bHQgPC0gcHN5Y2g6OmFscGhhKGRhdGFfY2xlYW4pDQogIHJldHVybihhbHBoYV9yZXN1bHQkdG90YWwkcmF3X2FscGhhKQ0KfQ0KDQojIE1lbmdoaXR1bmcgQ3JvbmJhY2gncyBBbHBoYSB1bnR1ayBrYXRlZ29yaSBLUlMNCmNyb25iYWNoX2tycyA8LSBjcm9uYmFjaF9hbHBoYShkYXRhX2tycykNCmNyb25iYWNoX2tycw0KYGBgDQoNCiMjIyA0LjMgUGVueWFqaWFuIEdyYWZpaw0KS2l0YSBha2FuIG1lbmdndW5ha2FuIGdyYWZpayB1bnR1ayBtZW5nZ2FtYmFya2FuIGRpc3RyaWJ1c2kgamF3YWJhbiBkYXJpIGJlYmVyYXBhIHBlcnRhbnlhYW4uDQoNCiMjIyMgMi4zLjEgSGlzdG9ncmFtIHVudHVrIEtSU19ha3Nlcw0KYGBge3J9DQojIE1lbWJ1YXQgaGlzdG9ncmFtIHVudHVrIG1lbGloYXQgZGlzdHJpYnVzaSBmcmVrdWVuc2kgdW50dWsgS1JTX2Frc2VzDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkYXRhX3N1cnZlaSwgYWVzKHggPSBLUlNfYWtzZXMpKSArDQogIGdlb21fYmFyKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1c2kgSmF3YWJhbiBLUlMgQWtzZXMiLCB4ID0gIlNrYWxhIEtSUyBBa3NlcyIsIHkgPSAiRnJla3VlbnNpIikNCmBgYA0KDQojIyMjIDQuMy4yIEJveHBsb3QgdW50dWsgQmltYmluZ2FuX2t1YWxpdGFzDQpgYGB7cn0NCiMgTWVtYnVhdCBib3hwbG90IHVudHVrIEJpbWJpbmdhbl9rdWFsaXRhcw0KZ2dwbG90KGRhdGFfc3VydmVpLCBhZXMoeSA9IEJpbWJpbmdhbl9rdWFsaXRhcywgeCA9IDEpKSArDQogIGdlb21fYm94cGxvdChmaWxsID0gImxpZ2h0Z3JlZW4iLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXNpIEtlcHVhc2FuIFRlcmhhZGFwIEJpbWJpbmdhbiBBa2FkZW1payIsIHkgPSAiS3VhbGl0YXMgQmltYmluZ2FuIiwgeCA9ICIiKQ0KYGBgDQoNCiMjIyA0LjQgS2VzaW1wdWxhbg0KQmVyZGFzYXJrYW4gYW5hbGlzaXMgZGF0YSBhd2FsLCBraXRhIGRhcGF0IG1lbnlpbXB1bGthbiBiYWh3YToNCg0KLSBMYXlhbmFuIEtSUyBPbmxpbmUgY2VuZGVydW5nIG1lbWlsaWtpIHRpbmdrYXQga2VwdWFzYW4geWFuZyBiZXJ2YXJpYXNpLCBkZW5nYW4gc2ViYWdpYW4gYmVzYXIgbWFoYXNpc3dhIG1lcmFzYSBrZXN1bGl0YW4gbWVuZ2Frc2VzIGF0YXUgbWVuZ2FsYW1pIG1hc2FsYWggdGVrbmlzLg0KDQotIEJpbWJpbmdhbiBBa2FkZW1payBtZW51bmp1a2thbiBrZXB1YXNhbiB5YW5nIGN1a3VwIGJhaWssIG5hbXVuIHRlcmRhcGF0IGtlbmRhbGEgZGFsYW0gaGFsIHdha3R1IGRhbiBha3Nlcy4NCg0KLSBQZWxheWFuYW4gYWRtaW5pc3RyYXNpIHVtdW1ueWEgZGlhbmdnYXAgY2VwYXQsIG1lc2tpcHVuIGFkYSBiZWJlcmFwYSBsYXBvcmFuIGtldGVybGFtYmF0YW4uDQoNCi0gQWtzZXMgaW5mb3JtYXNpIGFrYWRlbWlrIGp1Z2EgYmVydmFyaWFzaSwgZGVuZ2FuIGJlYmVyYXBhIG1haGFzaXN3YSBtZXJhc2Ega2VzdWxpdGFuIG1lbmVtdWthbiBpbmZvcm1hc2kgeWFuZyBkaXBlcmx1a2FuLg==