DATA COLLECTION

PRATIKUM 4 WEB SCRAPING DATA WITH R

Fikaaaa.jpg


Praktikum 4: Implementasi Web Scraping dalam Analisis Data

1. Latar Belakang

Dalam dunia digital saat ini, banyak informasi yang hanya tersedia di situs web dalam bentuk HTML dan tidak disediakan dalam format terstruktur seperti CSV atau API. Web scraping menjadi salah satu teknik yang memungkinkan pengambilan data secara otomatis, sehingga memudahkan proses analisis data.

Bahasa pemrograman R menyediakan berbagai alat yang dapat digunakan untuk scraping data dari situs web dengan lebih efisien. Praktikum ini bertujuan untuk mengeksplorasi berbagai metode web scraping menggunakan R, mulai dari teknik dasar hingga scraping data dari situs dengan struktur yang kompleks. Selain itu, penggunaan teknologi AI seperti ChatGPT juga akan dieksplorasi sebagai alat bantu dalam memahami elemen HTML dan optimasi kode scraping.


2. Perangkat dan Paket yang Digunakan

Untuk melaksanakan web scraping dalam R, beberapa perangkat dan pustaka berikut perlu dipersiapkan:

  1. R dan RStudio → Sebagai lingkungan pemrograman utama.
  2. Paket rvest → Digunakan untuk mengambil dan mengekstrak data dari halaman web.
  3. Paket tidyverse → Untuk manipulasi data setelah scraping.
  4. ChatGPT → Sebagai alat bantu untuk memahami struktur HTML dan menulis kode scraping secara lebih efisien.

Instalasi Paket

Sebelum melakukan scraping, pastikan semua paket telah diinstal di R dengan menjalankan perintah berikut:

install.packages("rvest")  # Paket utama untuk scraping
install.packages("tidyverse")  # Paket tambahan untuk manipulasi data

Kemudian, pustaka yang dibutuhkan dapat dipanggil dengan:

library(rvest)
library(tidyverse)

3. Teknik dan Metode Web Scraping

3.1 Ekstraksi Data dari Tabel Web

Banyak situs menyediakan informasi dalam bentuk tabel yang dapat langsung diambil menggunakan R tanpa perlu memahami struktur HTML secara mendalam.

Langkah-langkahnya:

  1. Buka situs web yang memiliki tabel data.
  2. Gunakan fitur Inspect Element untuk memastikan lokasi tabel dalam struktur HTML.
  3. Gunakan html_table() untuk mengekstrak data tabel ke dalam format data frame.

Contoh Kode:

url <- "https://www.worldometers.info/coronavirus/"
page <- read_html(url)

table <- page %>% html_node("table") %>% html_table(fill = TRUE)

head(table)  # Menampilkan beberapa baris pertama dari tabel

3.3 Scraping dari Banyak Halaman Secara Otomatis

Beberapa situs memiliki data yang tersebar di berbagai halaman. Untuk mengambil data dari beberapa halaman, kita bisa menggunakan loop dan menyusun dataset akhir secara otomatis.

Langkah-langkahnya:

  1. Tentukan pola URL yang digunakan untuk navigasi antar halaman.
  2. Gunakan loop for untuk mengakses setiap halaman dan mengambil data.
  3. Gabungkan hasil scraping dari semua halaman menjadi satu dataset besar.

Contoh Kode:

base_url <- "https://example.com/products?page="
all_data <- list()

for (i in 1:5) {
  page <- read_html(paste0(base_url, i))
  names <- page %>% html_nodes(".product-name") %>% html_text()
  prices <- page %>% html_nodes(".product-price") %>% html_text()
  
  all_data[[i]] <- data.frame(Name = names, Price = prices)
}

final_data <- bind_rows(all_data)

print(final_data)  # Menampilkan hasil scraping

3.4 Pemanfaatan ChatGPT dalam Web Scraping

Ketika menghadapi situs dengan struktur HTML yang kompleks atau sulit dipahami, ChatGPT dapat digunakan sebagai alat bantu untuk:

  • Memahami hierarki elemen HTML dalam sebuah halaman web.
  • Memberikan rekomendasi mengenai tag dan atribut yang relevan.
  • Menyusun kode scraping berdasarkan struktur HTML yang ada.

Cara Menggunakannya:

  1. Salin kode HTML dari elemen yang ingin diambil.
  2. Minta bantuan ChatGPT untuk menentukan cara scraping elemen tersebut.
  3. Gunakan rekomendasi yang diberikan untuk menulis kode scraping.

Contoh Kode dengan Bantuan ChatGPT:

Misalnya, jika struktur HTML suatu situs berisi:

html
<h2 class="news-title">Judul Berita</h2>

ChatGPT dapat menyarankan penggunaan:

titles <- page %>% html_nodes(".news-title") %>% html_text()

Cara ini memudahkan proses scraping tanpa harus memahami HTML secara mendalam.


4. Tantangan dalam Web Scraping dan Solusinya

Saat melakukan web scraping, ada beberapa kendala yang sering dihadapi:

  1. Pemblokiran oleh Situs Web
    • Beberapa situs mendeteksi aktivitas scraping dan membatasi akses.
    • Solusi: Gunakan Sys.sleep() untuk menambahkan jeda antar request atau ubah user-agent agar menyerupai browser biasa.
  2. Struktur HTML yang Kompleks
    • Data tersembunyi dalam elemen HTML yang sulit diakses.
    • Solusi: Gunakan Inspect Element atau minta bantuan ChatGPT untuk memahami pola HTML yang digunakan.
  3. Data yang Dimuat Secara Dinamis
    • Beberapa situs memuat data menggunakan JavaScript, sehingga tidak langsung tersedia dalam kode HTML.
    • Solusi: Gunakan Selenium atau cari tahu apakah situs memiliki API yang bisa digunakan.

5. Kesimpulan

Web scraping adalah teknik yang sangat berguna dalam pengumpulan data dari berbagai situs web. Dengan memanfaatkan paket rvest, kita dapat dengan mudah mengekstrak data dalam format tabel maupun non-tabel. Jika situs memiliki struktur HTML yang kompleks, ChatGPT dapat digunakan sebagai alat bantu untuk memahami dan menyusun kode scraping dengan lebih cepat.

Namun, perlu diingat bahwa web scraping harus dilakukan dengan etika yang baik, termasuk menghormati aturan yang ditetapkan oleh pemilik situs. Dengan pemahaman yang benar, web scraping dapat menjadi alat yang sangat bermanfaat dalam analisis data berbasis web.


Referensi

  1. Exsight. (2025, 1 Januari). Web Scraping dengan R: Tutorial Praktis. Diakses pada 12 Maret 2025, dari https://exsight.id/blog/2025/01/01/web-scraping-dengan-r-tutorial-praktis/

  2. Algoritma. (2024, 20 Desember). Panduan Lengkap Web Scraping: Teknik dan Implementasi. Diakses pada 12 Maret 2025, dari https://blog.algorit.ma/web-scraping-2/

  3. CapSolver. (2024, 15 November). Mengenal Web Scraping dengan R dan Cara Menghindari Blokir. Diakses pada 12 Maret 2025, dari https://www.capsolver.com/id/blog/All/scraping-r

LS0tDQp0aXRsZTogIkRBVEEgQ09MTEVDVElPTiINCg0Kc3VidGl0bGU6ICJQUkFUSUtVTSA0IFdFQiBTQ1JBUElORyBEQVRBIFdJVEggUiAiDQoNCmF1dGhvcjogDQogIC0gIiBGaWthIElyc2FuZGkgRGVzdnlhbnRpICg1MjI0MDAwMTMpIg0KICANCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OnJlYWR0aGVkb3duOg0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgY3NzOiAiU3R5bGUuY3NzIg0KICAgIA0KLS0tDQoNCiA8aW1nIGlkPSJsb2dvLXV0YW1hIiBzcmM9IkZpa2FhYWEuanBnIiBhbHQ9IkZpa2FhYWEuanBnIiBzdHlsZT0id2lkdGg6MjAwcHg7IGRpc3BsYXk6IGJsb2NrOyBtYXJnaW46IGF1dG87Ij4NCg0KLS0tDQoNCiANCiMgKipQcmFrdGlrdW0gNDogSW1wbGVtZW50YXNpIFdlYiBTY3JhcGluZyBkYWxhbSBBbmFsaXNpcyBEYXRhKiogIA0KDQojIyAqKjEuIExhdGFyIEJlbGFrYW5nKiogIA0KRGFsYW0gZHVuaWEgZGlnaXRhbCBzYWF0IGluaSwgYmFueWFrIGluZm9ybWFzaSB5YW5nIGhhbnlhIHRlcnNlZGlhIGRpIHNpdHVzIHdlYiBkYWxhbSBiZW50dWsgSFRNTCBkYW4gdGlkYWsgZGlzZWRpYWthbiBkYWxhbSBmb3JtYXQgdGVyc3RydWt0dXIgc2VwZXJ0aSBDU1YgYXRhdSBBUEkuIFdlYiBzY3JhcGluZyBtZW5qYWRpIHNhbGFoIHNhdHUgdGVrbmlrIHlhbmcgbWVtdW5na2lua2FuIHBlbmdhbWJpbGFuIGRhdGEgc2VjYXJhIG90b21hdGlzLCBzZWhpbmdnYSBtZW11ZGFoa2FuIHByb3NlcyBhbmFsaXNpcyBkYXRhLiAgDQoNCkJhaGFzYSBwZW1yb2dyYW1hbiBSIG1lbnllZGlha2FuIGJlcmJhZ2FpIGFsYXQgeWFuZyBkYXBhdCBkaWd1bmFrYW4gdW50dWsgc2NyYXBpbmcgZGF0YSBkYXJpIHNpdHVzIHdlYiBkZW5nYW4gbGViaWggZWZpc2llbi4gUHJha3Rpa3VtIGluaSBiZXJ0dWp1YW4gdW50dWsgbWVuZ2Vrc3Bsb3Jhc2kgYmVyYmFnYWkgbWV0b2RlIHdlYiBzY3JhcGluZyBtZW5nZ3VuYWthbiBSLCBtdWxhaSBkYXJpIHRla25payBkYXNhciBoaW5nZ2Egc2NyYXBpbmcgZGF0YSBkYXJpIHNpdHVzIGRlbmdhbiBzdHJ1a3R1ciB5YW5nIGtvbXBsZWtzLiBTZWxhaW4gaXR1LCBwZW5nZ3VuYWFuIHRla25vbG9naSBBSSBzZXBlcnRpIENoYXRHUFQganVnYSBha2FuIGRpZWtzcGxvcmFzaSBzZWJhZ2FpIGFsYXQgYmFudHUgZGFsYW0gbWVtYWhhbWkgZWxlbWVuIEhUTUwgZGFuIG9wdGltYXNpIGtvZGUgc2NyYXBpbmcuICANCg0KLS0tDQoNCiMjICoqMi4gUGVyYW5na2F0IGRhbiBQYWtldCB5YW5nIERpZ3VuYWthbioqICANClVudHVrIG1lbGFrc2FuYWthbiB3ZWIgc2NyYXBpbmcgZGFsYW0gUiwgYmViZXJhcGEgcGVyYW5na2F0IGRhbiBwdXN0YWthIGJlcmlrdXQgcGVybHUgZGlwZXJzaWFwa2FuOiAgDQoNCjEuICoqUiBkYW4gUlN0dWRpbyoqIOKGkiBTZWJhZ2FpIGxpbmdrdW5nYW4gcGVtcm9ncmFtYW4gdXRhbWEuICANCjIuICoqUGFrZXQgYHJ2ZXN0YCoqIOKGkiBEaWd1bmFrYW4gdW50dWsgbWVuZ2FtYmlsIGRhbiBtZW5nZWtzdHJhayBkYXRhIGRhcmkgaGFsYW1hbiB3ZWIuICANCjMuICoqUGFrZXQgYHRpZHl2ZXJzZWAqKiDihpIgVW50dWsgbWFuaXB1bGFzaSBkYXRhIHNldGVsYWggc2NyYXBpbmcuICANCjQuICoqQ2hhdEdQVCoqIOKGkiBTZWJhZ2FpIGFsYXQgYmFudHUgdW50dWsgbWVtYWhhbWkgc3RydWt0dXIgSFRNTCBkYW4gbWVudWxpcyBrb2RlIHNjcmFwaW5nIHNlY2FyYSBsZWJpaCBlZmlzaWVuLiAgDQoNCiMjIyAqKkluc3RhbGFzaSBQYWtldCoqICANClNlYmVsdW0gbWVsYWt1a2FuIHNjcmFwaW5nLCBwYXN0aWthbiBzZW11YSBwYWtldCB0ZWxhaCBkaWluc3RhbCBkaSBSIGRlbmdhbiBtZW5qYWxhbmthbiBwZXJpbnRhaCBiZXJpa3V0OiAgDQoNCmBgYA0KaW5zdGFsbC5wYWNrYWdlcygicnZlc3QiKSAgIyBQYWtldCB1dGFtYSB1bnR1ayBzY3JhcGluZw0KaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikgICMgUGFrZXQgdGFtYmFoYW4gdW50dWsgbWFuaXB1bGFzaSBkYXRhDQpgYGANCg0KS2VtdWRpYW4sIHB1c3Rha2EgeWFuZyBkaWJ1dHVoa2FuIGRhcGF0IGRpcGFuZ2dpbCBkZW5nYW46ICANCg0KYGBgcg0KbGlicmFyeShydmVzdCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCi0tLQ0KDQojIyAqKjMuIFRla25payBkYW4gTWV0b2RlIFdlYiBTY3JhcGluZyoqICANCg0KIyMjICoqMy4xIEVrc3RyYWtzaSBEYXRhIGRhcmkgVGFiZWwgV2ViKiogIA0KQmFueWFrIHNpdHVzIG1lbnllZGlha2FuIGluZm9ybWFzaSBkYWxhbSBiZW50dWsgdGFiZWwgeWFuZyBkYXBhdCBsYW5nc3VuZyBkaWFtYmlsIG1lbmdndW5ha2FuIFIgdGFucGEgcGVybHUgbWVtYWhhbWkgc3RydWt0dXIgSFRNTCBzZWNhcmEgbWVuZGFsYW0uICANCg0KIyMjIyAqKkxhbmdrYWgtbGFuZ2thaG55YToqKiAgDQoxLiBCdWthIHNpdHVzIHdlYiB5YW5nIG1lbWlsaWtpIHRhYmVsIGRhdGEuICANCjIuIEd1bmFrYW4gZml0dXIgKipJbnNwZWN0IEVsZW1lbnQqKiB1bnR1ayBtZW1hc3Rpa2FuIGxva2FzaSB0YWJlbCBkYWxhbSBzdHJ1a3R1ciBIVE1MLiAgDQozLiBHdW5ha2FuIGBodG1sX3RhYmxlKClgIHVudHVrIG1lbmdla3N0cmFrIGRhdGEgdGFiZWwga2UgZGFsYW0gZm9ybWF0IGRhdGEgZnJhbWUuICANCg0KIyMjIyAqKkNvbnRvaCBLb2RlOioqICANCmBgYHINCnVybCA8LSAiaHR0cHM6Ly93d3cud29ybGRvbWV0ZXJzLmluZm8vY29yb25hdmlydXMvIg0KcGFnZSA8LSByZWFkX2h0bWwodXJsKQ0KDQp0YWJsZSA8LSBwYWdlICU+JSBodG1sX25vZGUoInRhYmxlIikgJT4lIGh0bWxfdGFibGUoZmlsbCA9IFRSVUUpDQoNCmhlYWQodGFibGUpICAjIE1lbmFtcGlsa2FuIGJlYmVyYXBhIGJhcmlzIHBlcnRhbWEgZGFyaSB0YWJlbA0KYGBgDQoNCi0tLQ0KDQojIyMgKiozLjIgTWVuZ2FtYmlsIERhdGEgTm9uLVRhYmVsIChKdWR1bCwgUGFyYWdyYWYsIGRhbiBMaW5rKSoqICANClNlbGFpbiB0YWJlbCwgYmFueWFrIGRhdGEgcGVudGluZyB5YW5nIHRlcnNlYmFyIGRhbGFtIHRla3MsIGhlYWRpbmcsIGF0YXUgaHlwZXJsaW5rLiBVbnR1ayBzY3JhcGluZyBqZW5pcyBkYXRhIGluaSwga2l0YSBwZXJsdSBtZW5naWRlbnRpZmlrYXNpIGVsZW1lbiBIVE1MIHlhbmcgbWVueWltcGFubnlhLiAgDQoNCiMjIyMgKipMYW5na2FoLWxhbmdrYWhueWE6KiogIA0KMS4gR3VuYWthbiAqKkluc3BlY3QgRWxlbWVudCoqIHVudHVrIG1lbmVtdWthbiBlbGVtZW4gSFRNTCB5YW5nIGJlcmlzaSBkYXRhLiAgDQoyLiBHdW5ha2FuIGBodG1sX25vZGVzKClgIGRhbiBgaHRtbF90ZXh0KClgIHVudHVrIG1lbmdhbWJpbCB0ZWtzIGRhcmkgZWxlbWVuIHRlcnNlYnV0LiAgDQoNCiMjIyMgKipDb250b2ggS29kZToqKiAgDQpgYGByDQp1cmwgPC0gImh0dHBzOi8vd3d3LmJiYy5jb20vbmV3cyINCnBhZ2UgPC0gcmVhZF9odG1sKHVybCkNCg0KaGVhZGxpbmVzIDwtIHBhZ2UgJT4lIGh0bWxfbm9kZXMoImgzIikgJT4lIGh0bWxfdGV4dCgpDQoNCnByaW50KGhlYWRsaW5lcykgICMgTWVuYW1waWxrYW4gZGFmdGFyIGp1ZHVsIGJlcml0YQ0KYGBgDQoNCi0tLQ0KDQojIyMgKiozLjMgU2NyYXBpbmcgZGFyaSBCYW55YWsgSGFsYW1hbiBTZWNhcmEgT3RvbWF0aXMqKiAgDQpCZWJlcmFwYSBzaXR1cyBtZW1pbGlraSBkYXRhIHlhbmcgdGVyc2ViYXIgZGkgYmVyYmFnYWkgaGFsYW1hbi4gVW50dWsgbWVuZ2FtYmlsIGRhdGEgZGFyaSBiZWJlcmFwYSBoYWxhbWFuLCBraXRhIGJpc2EgbWVuZ2d1bmFrYW4gbG9vcCBkYW4gbWVueXVzdW4gZGF0YXNldCBha2hpciBzZWNhcmEgb3RvbWF0aXMuICANCg0KIyMjIyAqKkxhbmdrYWgtbGFuZ2thaG55YToqKiAgDQoxLiBUZW50dWthbiBwb2xhIFVSTCB5YW5nIGRpZ3VuYWthbiB1bnR1ayBuYXZpZ2FzaSBhbnRhciBoYWxhbWFuLiAgDQoyLiBHdW5ha2FuIGxvb3AgYGZvcmAgdW50dWsgbWVuZ2Frc2VzIHNldGlhcCBoYWxhbWFuIGRhbiBtZW5nYW1iaWwgZGF0YS4gIA0KMy4gR2FidW5na2FuIGhhc2lsIHNjcmFwaW5nIGRhcmkgc2VtdWEgaGFsYW1hbiBtZW5qYWRpIHNhdHUgZGF0YXNldCBiZXNhci4gIA0KDQojIyMjICoqQ29udG9oIEtvZGU6KiogIA0KDQpgYGANCmJhc2VfdXJsIDwtICJodHRwczovL2V4YW1wbGUuY29tL3Byb2R1Y3RzP3BhZ2U9Ig0KYWxsX2RhdGEgPC0gbGlzdCgpDQoNCmZvciAoaSBpbiAxOjUpIHsNCiAgcGFnZSA8LSByZWFkX2h0bWwocGFzdGUwKGJhc2VfdXJsLCBpKSkNCiAgbmFtZXMgPC0gcGFnZSAlPiUgaHRtbF9ub2RlcygiLnByb2R1Y3QtbmFtZSIpICU+JSBodG1sX3RleHQoKQ0KICBwcmljZXMgPC0gcGFnZSAlPiUgaHRtbF9ub2RlcygiLnByb2R1Y3QtcHJpY2UiKSAlPiUgaHRtbF90ZXh0KCkNCiAgDQogIGFsbF9kYXRhW1tpXV0gPC0gZGF0YS5mcmFtZShOYW1lID0gbmFtZXMsIFByaWNlID0gcHJpY2VzKQ0KfQ0KDQpmaW5hbF9kYXRhIDwtIGJpbmRfcm93cyhhbGxfZGF0YSkNCg0KcHJpbnQoZmluYWxfZGF0YSkgICMgTWVuYW1waWxrYW4gaGFzaWwgc2NyYXBpbmcNCg0KYGBgDQoNCi0tLQ0KDQojIyMgKiozLjQgUGVtYW5mYWF0YW4gQ2hhdEdQVCBkYWxhbSBXZWIgU2NyYXBpbmcqKiAgDQpLZXRpa2EgbWVuZ2hhZGFwaSBzaXR1cyBkZW5nYW4gc3RydWt0dXIgSFRNTCB5YW5nIGtvbXBsZWtzIGF0YXUgc3VsaXQgZGlwYWhhbWksIENoYXRHUFQgZGFwYXQgZGlndW5ha2FuIHNlYmFnYWkgYWxhdCBiYW50dSB1bnR1azogIA0KDQotIE1lbWFoYW1pIGhpZXJhcmtpIGVsZW1lbiBIVE1MIGRhbGFtIHNlYnVhaCBoYWxhbWFuIHdlYi4gIA0KLSBNZW1iZXJpa2FuIHJla29tZW5kYXNpIG1lbmdlbmFpIHRhZyBkYW4gYXRyaWJ1dCB5YW5nIHJlbGV2YW4uICANCi0gTWVueXVzdW4ga29kZSBzY3JhcGluZyBiZXJkYXNhcmthbiBzdHJ1a3R1ciBIVE1MIHlhbmcgYWRhLiAgDQoNCiMjIyMgKipDYXJhIE1lbmdndW5ha2FubnlhOioqICANCjEuICoqU2FsaW4ga29kZSBIVE1MKiogZGFyaSBlbGVtZW4geWFuZyBpbmdpbiBkaWFtYmlsLiAgDQoyLiAqKk1pbnRhIGJhbnR1YW4gQ2hhdEdQVCoqIHVudHVrIG1lbmVudHVrYW4gY2FyYSBzY3JhcGluZyBlbGVtZW4gdGVyc2VidXQuICANCjMuICoqR3VuYWthbiByZWtvbWVuZGFzaSoqIHlhbmcgZGliZXJpa2FuIHVudHVrIG1lbnVsaXMga29kZSBzY3JhcGluZy4gIA0KDQojIyMjICoqQ29udG9oIEtvZGUgZGVuZ2FuIEJhbnR1YW4gQ2hhdEdQVDoqKiAgDQpNaXNhbG55YSwgamlrYSBzdHJ1a3R1ciBIVE1MIHN1YXR1IHNpdHVzIGJlcmlzaTogIA0KDQpgYGANCmh0bWwNCjxoMiBjbGFzcz0ibmV3cy10aXRsZSI+SnVkdWwgQmVyaXRhPC9oMj4NCg0KYGBgDQpDaGF0R1BUIGRhcGF0IG1lbnlhcmFua2FuIHBlbmdndW5hYW46ICANCg0KYGBgDQp0aXRsZXMgPC0gcGFnZSAlPiUgaHRtbF9ub2RlcygiLm5ld3MtdGl0bGUiKSAlPiUgaHRtbF90ZXh0KCkNCg0KYGBgDQpDYXJhIGluaSBtZW11ZGFoa2FuIHByb3NlcyBzY3JhcGluZyB0YW5wYSBoYXJ1cyBtZW1haGFtaSBIVE1MIHNlY2FyYSBtZW5kYWxhbS4gIA0KDQotLS0NCg0KIyMgKio0LiBUYW50YW5nYW4gZGFsYW0gV2ViIFNjcmFwaW5nIGRhbiBTb2x1c2lueWEqKiAgDQoNClNhYXQgbWVsYWt1a2FuIHdlYiBzY3JhcGluZywgYWRhIGJlYmVyYXBhIGtlbmRhbGEgeWFuZyBzZXJpbmcgZGloYWRhcGk6ICANCg0KMS4gKipQZW1ibG9raXJhbiBvbGVoIFNpdHVzIFdlYioqICANCiAgIC0gQmViZXJhcGEgc2l0dXMgbWVuZGV0ZWtzaSBha3Rpdml0YXMgc2NyYXBpbmcgZGFuIG1lbWJhdGFzaSBha3Nlcy4gIA0KICAgLSAqKlNvbHVzaToqKiBHdW5ha2FuIGBTeXMuc2xlZXAoKWAgdW50dWsgbWVuYW1iYWhrYW4gamVkYSBhbnRhciByZXF1ZXN0IGF0YXUgdWJhaCB1c2VyLWFnZW50IGFnYXIgbWVueWVydXBhaSBicm93c2VyIGJpYXNhLiAgDQoNCjIuICoqU3RydWt0dXIgSFRNTCB5YW5nIEtvbXBsZWtzKiogIA0KICAgLSBEYXRhIHRlcnNlbWJ1bnlpIGRhbGFtIGVsZW1lbiBIVE1MIHlhbmcgc3VsaXQgZGlha3Nlcy4gIA0KICAgLSAqKlNvbHVzaToqKiBHdW5ha2FuICoqSW5zcGVjdCBFbGVtZW50KiogYXRhdSBtaW50YSBiYW50dWFuIENoYXRHUFQgdW50dWsgbWVtYWhhbWkgcG9sYSBIVE1MIHlhbmcgZGlndW5ha2FuLiAgDQoNCjMuICoqRGF0YSB5YW5nIERpbXVhdCBTZWNhcmEgRGluYW1pcyoqICANCiAgIC0gQmViZXJhcGEgc2l0dXMgbWVtdWF0IGRhdGEgbWVuZ2d1bmFrYW4gSmF2YVNjcmlwdCwgc2VoaW5nZ2EgdGlkYWsgbGFuZ3N1bmcgdGVyc2VkaWEgZGFsYW0ga29kZSBIVE1MLiAgDQogICAtICoqU29sdXNpOioqIEd1bmFrYW4gU2VsZW5pdW0gYXRhdSBjYXJpIHRhaHUgYXBha2FoIHNpdHVzIG1lbWlsaWtpIEFQSSB5YW5nIGJpc2EgZGlndW5ha2FuLiAgDQoNCi0tLQ0KDQojIyAqKjUuIEtlc2ltcHVsYW4qKiAgDQoNCldlYiBzY3JhcGluZyBhZGFsYWggdGVrbmlrIHlhbmcgc2FuZ2F0IGJlcmd1bmEgZGFsYW0gcGVuZ3VtcHVsYW4gZGF0YSBkYXJpIGJlcmJhZ2FpIHNpdHVzIHdlYi4gRGVuZ2FuIG1lbWFuZmFhdGthbiAqKnBha2V0IHJ2ZXN0KiosIGtpdGEgZGFwYXQgZGVuZ2FuIG11ZGFoIG1lbmdla3N0cmFrIGRhdGEgZGFsYW0gZm9ybWF0IHRhYmVsIG1hdXB1biBub24tdGFiZWwuIEppa2Egc2l0dXMgbWVtaWxpa2kgc3RydWt0dXIgSFRNTCB5YW5nIGtvbXBsZWtzLCAqKkNoYXRHUFQqKiBkYXBhdCBkaWd1bmFrYW4gc2ViYWdhaSBhbGF0IGJhbnR1IHVudHVrIG1lbWFoYW1pIGRhbiBtZW55dXN1biBrb2RlIHNjcmFwaW5nIGRlbmdhbiBsZWJpaCBjZXBhdC4gIA0KDQpOYW11biwgcGVybHUgZGlpbmdhdCBiYWh3YSB3ZWIgc2NyYXBpbmcgaGFydXMgZGlsYWt1a2FuIGRlbmdhbiAqKmV0aWthIHlhbmcgYmFpayoqLCB0ZXJtYXN1ayBtZW5naG9ybWF0aSBhdHVyYW4geWFuZyBkaXRldGFwa2FuIG9sZWggcGVtaWxpayBzaXR1cy4gRGVuZ2FuIHBlbWFoYW1hbiB5YW5nIGJlbmFyLCB3ZWIgc2NyYXBpbmcgZGFwYXQgbWVuamFkaSBhbGF0IHlhbmcgc2FuZ2F0IGJlcm1hbmZhYXQgZGFsYW0gYW5hbGlzaXMgZGF0YSBiZXJiYXNpcyB3ZWIuICANCg0KLS0tDQoNCiMjICoqUmVmZXJlbnNpKioNCg0KMS4gRXhzaWdodC4gKDIwMjUsIDEgSmFudWFyaSkuICpXZWIgU2NyYXBpbmcgZGVuZ2FuIFI6IFR1dG9yaWFsIFByYWt0aXMuKiBEaWFrc2VzIHBhZGEgMTIgTWFyZXQgMjAyNSwgZGFyaSBbaHR0cHM6Ly9leHNpZ2h0LmlkL2Jsb2cvMjAyNS8wMS8wMS93ZWItc2NyYXBpbmctZGVuZ2FuLXItdHV0b3JpYWwtcHJha3Rpcy9dKGh0dHBzOi8vZXhzaWdodC5pZC9ibG9nLzIwMjUvMDEvMDEvd2ViLXNjcmFwaW5nLWRlbmdhbi1yLXR1dG9yaWFsLXByYWt0aXMvKSAgDQoNCjIuIEFsZ29yaXRtYS4gKDIwMjQsIDIwIERlc2VtYmVyKS4gKlBhbmR1YW4gTGVuZ2thcCBXZWIgU2NyYXBpbmc6IFRla25payBkYW4gSW1wbGVtZW50YXNpLiogRGlha3NlcyBwYWRhIDEyIE1hcmV0IDIwMjUsIGRhcmkgW2h0dHBzOi8vYmxvZy5hbGdvcml0Lm1hL3dlYi1zY3JhcGluZy0yL10oaHR0cHM6Ly9ibG9nLmFsZ29yaXQubWEvd2ViLXNjcmFwaW5nLTIvKSAgDQogDQozLiBDYXBTb2x2ZXIuICgyMDI0LCAxNSBOb3ZlbWJlcikuICpNZW5nZW5hbCBXZWIgU2NyYXBpbmcgZGVuZ2FuIFIgZGFuIENhcmEgTWVuZ2hpbmRhcmkgQmxva2lyLiogRGlha3NlcyBwYWRhIDEyIE1hcmV0IDIwMjUsIGRhcmkgW2h0dHBzOi8vd3d3LmNhcHNvbHZlci5jb20vaWQvYmxvZy9BbGwvc2NyYXBpbmctcl0oaHR0cHM6Ly93d3cuY2Fwc29sdmVyLmNvbS9pZC9ibG9nL0FsbC9zY3JhcGluZy1yKSAgDQoNCg0K