Data Collection (Web Scraping)

Data Science Programming

Chello Frhino Mike M (52240031)

March 13, 2025

foto

1 Web Scraping di R dengan ChatGPT

1.1 Tujuan

Setelah menyelesaikan panduan ini, Anda akan memiliki kemampuan untuk:

  • Memahami konsep fundamental web scraping serta cara menerapkannya dalam R.
  • Menggunakan paket rvest untuk mengumpulkan data dari halaman web.
  • Mengenali elemen HTML yang dibutuhkan dengan memanfaatkan Developer Tools di peramban.
  • Mengambil data dari tabel maupun elemen non-tabel pada situs web.
  • Menggunakan perulangan untuk mengotomatisasi pengambilan data dari berbagai halaman.
  • Membersihkan dan mengelola data hasil scraping agar lebih terstruktur di R.
  • Menghindari kendala umum serta mencegah pemblokiran saat melakukan web scraping.

1.2 Pendahuluan

  • Web scraping merupakan teknik untuk mengekstrak data dari situs web ketika informasi tersebut tidak tersedia dalam format terstruktur seperti CSV atau Excel.
  • Dalam panduan ini, kita akan memakai paket rvest di R untuk mengambil data dari halaman web.

1.3 Cara Cepat: Menyalin Data dari Tabel

  1. Instal paket data.pasta di R.
  2. Salin tabel langsung dari situs web.
  3. Gunakan fitur paste as data frame dari data.pasta untuk mengonversinya ke dalam format R.

1.4 Memulai Web Scraping dengan rvest

  1. Instal dan impor paket rvest:

    install.packages("rvest")  
    library(rvest)  
  2. Gunakan read_html("URL") untuk mengambil konten halaman web.

  3. Gunakan html_node() untuk menyeleksi elemen tertentu seperti tabel.

  4. Gunakan html_table() untuk mengubah tabel menjadi data frame yang dapat dianalisis di R.

1.5 Menemukan Elemen HTML dengan Developer Tools (F12)

  1. Tekan F12 di browser untuk membuka Developer Tools.
  2. Arahkan ke tab Elements.
  3. Gunakan Element Inspector untuk menyorot tabel atau elemen HTML lainnya.
  4. Identifikasi tag atau atribut yang berisi data yang akan diambil, seperti <table>, <div>, atau ID tertentu.

1.6 Contoh Scraping Tabel Data R Packages

  1. Buka halaman web yang berisi tabel data.

  2. Gunakan read_html() untuk membaca halaman tersebut:

    url <- "https://example.com"
    page <- read_html(url)
  3. Gunakan html_node() untuk memilih tabel:

    table <- page %>% html_node("table")
  4. Konversi ke format data frame:

    data <- table %>% html_table()

1.7 Mengambil Data dari Beberapa Halaman Web

  1. Siapkan daftar URL dari berbagai halaman yang ingin di-scrape.

  2. Gunakan perulangan for untuk membaca setiap halaman secara otomatis:

    urls <- c(
      "https://www.transfermarkt.com/germany/kader/verein/3262/saison_id/2023/plus/1",
      "https://www.transfermarkt.com/spain/kader/verein/3375/saison_id/2023/plus/1",
      "https://www.transfermarkt.com/italy/kader/verein/3376/saison_id/2023/plus/1",
      "https://www.transfermarkt.com/france/kader/verein/3374/saison_id/2023/plus/1"
    )
    
    for (url in urls) {
        halaman <- read_html(url)
        tabel <- halaman %>% html_node("table") %>% html_table()
        print(tabel)
    }
  3. Gabungkan data dari berbagai halaman ke dalam satu dataset untuk analisis lebih lanjut.

1.8 Mengambil Data Non-Tabel dari Website

  1. Gunakan Developer Tools (F12) untuk menemukan elemen HTML yang menyimpan data yang dibutuhkan.

  2. Gunakan html_nodes() untuk mengekstrak informasi spesifik seperti nama produk atau harga:

    judul <- halaman %>% html_node(".title-class") %>% html_text()
    harga <- halaman %>% html_node(".price-class") %>% html_text()
  3. Simpan data ke dalam data frame agar lebih mudah dianalisis:

    data_produk <- data.frame(Judul = judul, Harga = harga)

1.9 Scraping Banyak Halaman secara Otomatis

  1. Identifikasi pola URL yang berubah di setiap halaman (misalnya, perubahan nomor halaman).

  2. Gunakan perulangan untuk membuat daftar URL dan mengambil data secara otomatis:

    base_url <- "https://www.transfermarkt.com/germany/kader/verein/3262/saison_id/2023/plus/"
    semua_halaman <- list()
    
    for (i in 1:5) {
        url <- paste0(base_url, i)
        halaman <- read_html(url)
        tabel <- halaman %>% html_node("table") %>% html_table()
        semua_halaman[[i]] <- tabel
    }
    
    data_final <- do.call(rbind, semua_halaman)
  3. Gabungkan seluruh hasil scraping ke dalam satu dataset untuk analisis lebih lanjut.

1.10 Membersihkan Data Hasil Scraping

  1. Periksa kembali data untuk memastikan tidak ada nilai yang hilang atau format yang salah.
  2. Jika ada data yang tidak sesuai format, gunakan mutate() atau case_when() untuk mengubahnya.
  3. Gunakan separate() untuk memecah informasi dalam satu kolom menjadi beberapa kolom jika diperlukan.

1.11 Tips Menghindari Pemblokiran Saat Scraping

  • Jangan mengakses terlalu banyak halaman dalam waktu singkat.
  • Tambahkan jeda antar permintaan menggunakan Sys.sleep(2).
  • Hindari scraping situs yang memiliki perlindungan tinggi tanpa izin eksplisit.

2 Kesimpulan

Dengan memanfaatkan paket rvest di R, kita dapat mengambil data dari berbagai website, baik dalam bentuk tabel maupun elemen lain seperti teks dan harga. Memahami struktur HTML sangat penting agar scraping berjalan dengan baik. Selain itu, pastikan untuk menggunakan metode yang etis agar tidak melanggar kebijakan situs web.

LS0tDQp0aXRsZTogIkRhdGEgQ29sbGVjdGlvbiAoV2ViIFNjcmFwaW5nKSINCnN1YnRpdGxlOiAiRGF0YSBTY2llbmNlIFByb2dyYW1taW5nIg0KYXV0aG9yOiANCiAgLSAiQ2hlbGxvIEZyaGlubyBNaWtlIE0gKDUyMjQwMDMxKSINCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIHJtZGZvcm1hdHM6OmRvd25jdXRlOiAgICMgaHR0cHM6Ly9naXRodWIuY29tL2p1YmEvcm1kZm9ybWF0cw0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogdHJ1ZQ0KICAgIGxpZ2h0Ym94OiB0cnVlDQogICAgZ2FsbGVyeTogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQ0KICAgIGxpYl9kaXI6IGxpYnMNCiAgICBkZl9wcmludDogInBhZ2VkIg0KICAgIGNvZGVfZm9sZGluZzogInNob3ciDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgDQotLS0NCg0KPHN0eWxlPg0KICBib2R5IHsNCiAgICB0ZXh0LWFsaWduOiBqdXN0aWZ5Ow0KICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOw0KICAgIG92ZXJmbG93LXg6IGF1dG87DQogICAgZm9udC1mYW1pbHk6IGN1cnNpdmU7DQogIH0NCjwvc3R5bGU+DQoNCjxpbWcgaWQ9ImZvdG8tYXV0aG9yIiBzcmM9IkM6L1VzZXJzL1VTRVIvRG9jdW1lbnRzL1JCb3hwbG90L2ltZy9XaGF0c0FwcCBJbWFnZSAyMDI0LTExLTI0IGF0IDMuMjkuNDEgUE0uanBlZyIgYWx0PSJmb3RvIiBzdHlsZT0id2lkdGg6MzAwcHg7IGRpc3BsYXk6IGJsb2NrOyBtYXJnaW46IGF1dG87Ij4NCg0KIyAqKldlYiBTY3JhcGluZyBkaSBSIGRlbmdhbiBDaGF0R1BUKioNCg0KIyMgKipUdWp1YW4qKiAgDQpTZXRlbGFoIG1lbnllbGVzYWlrYW4gcGFuZHVhbiBpbmksIEFuZGEgYWthbiBtZW1pbGlraSBrZW1hbXB1YW4gdW50dWs6ICANCg0KLSBNZW1haGFtaSBrb25zZXAgZnVuZGFtZW50YWwgd2ViIHNjcmFwaW5nIHNlcnRhIGNhcmEgbWVuZXJhcGthbm55YSBkYWxhbSBSLiAgDQotIE1lbmdndW5ha2FuIHBha2V0IGBydmVzdGAgdW50dWsgbWVuZ3VtcHVsa2FuIGRhdGEgZGFyaSBoYWxhbWFuIHdlYi4gIA0KLSBNZW5nZW5hbGkgZWxlbWVuIEhUTUwgeWFuZyBkaWJ1dHVoa2FuIGRlbmdhbiBtZW1hbmZhYXRrYW4gKkRldmVsb3BlciBUb29scyogZGkgcGVyYW1iYW4uICANCi0gTWVuZ2FtYmlsIGRhdGEgZGFyaSB0YWJlbCBtYXVwdW4gZWxlbWVuIG5vbi10YWJlbCBwYWRhIHNpdHVzIHdlYi4gIA0KLSBNZW5nZ3VuYWthbiBwZXJ1bGFuZ2FuIHVudHVrIG1lbmdvdG9tYXRpc2FzaSBwZW5nYW1iaWxhbiBkYXRhIGRhcmkgYmVyYmFnYWkgaGFsYW1hbi4gIA0KLSBNZW1iZXJzaWhrYW4gZGFuIG1lbmdlbG9sYSBkYXRhIGhhc2lsIHNjcmFwaW5nIGFnYXIgbGViaWggdGVyc3RydWt0dXIgZGkgUi4gIA0KLSBNZW5naGluZGFyaSBrZW5kYWxhIHVtdW0gc2VydGEgbWVuY2VnYWggcGVtYmxva2lyYW4gc2FhdCBtZWxha3VrYW4gd2ViIHNjcmFwaW5nLg0KDQojIyAqKlBlbmRhaHVsdWFuKiogIA0KLSBXZWIgc2NyYXBpbmcgbWVydXBha2FuIHRla25payB1bnR1ayBtZW5nZWtzdHJhayBkYXRhIGRhcmkgc2l0dXMgd2ViIGtldGlrYSBpbmZvcm1hc2kgdGVyc2VidXQgdGlkYWsgdGVyc2VkaWEgZGFsYW0gZm9ybWF0IHRlcnN0cnVrdHVyIHNlcGVydGkgQ1NWIGF0YXUgRXhjZWwuICANCi0gRGFsYW0gcGFuZHVhbiBpbmksIGtpdGEgYWthbiBtZW1ha2FpIHBha2V0IGBydmVzdGAgZGkgUiB1bnR1ayBtZW5nYW1iaWwgZGF0YSBkYXJpIGhhbGFtYW4gd2ViLg0KDQojIyAqKkNhcmEgQ2VwYXQ6IE1lbnlhbGluIERhdGEgZGFyaSBUYWJlbCoqICANCjEuIEluc3RhbCBwYWtldCBgZGF0YS5wYXN0YWAgZGkgUi4gIA0KMi4gU2FsaW4gdGFiZWwgbGFuZ3N1bmcgZGFyaSBzaXR1cyB3ZWIuICANCjMuIEd1bmFrYW4gZml0dXIgKnBhc3RlIGFzIGRhdGEgZnJhbWUqIGRhcmkgYGRhdGEucGFzdGFgIHVudHVrIG1lbmdvbnZlcnNpbnlhIGtlIGRhbGFtIGZvcm1hdCBSLiAgDQoNCiMjICoqTWVtdWxhaSBXZWIgU2NyYXBpbmcgZGVuZ2FuIGBydmVzdGAqKiAgDQoxLiBJbnN0YWwgZGFuIGltcG9yIHBha2V0IGBydmVzdGA6ICANCiAgIGBgYHINCiAgIGluc3RhbGwucGFja2FnZXMoInJ2ZXN0IikgIA0KICAgbGlicmFyeShydmVzdCkgIA0KICAgYGBgICANCjIuIEd1bmFrYW4gYHJlYWRfaHRtbCgiVVJMIilgIHVudHVrIG1lbmdhbWJpbCBrb250ZW4gaGFsYW1hbiB3ZWIuICANCjMuIEd1bmFrYW4gYGh0bWxfbm9kZSgpYCB1bnR1ayBtZW55ZWxla3NpIGVsZW1lbiB0ZXJ0ZW50dSBzZXBlcnRpIHRhYmVsLiAgDQo0LiBHdW5ha2FuIGBodG1sX3RhYmxlKClgIHVudHVrIG1lbmd1YmFoIHRhYmVsIG1lbmphZGkgKmRhdGEgZnJhbWUqIHlhbmcgZGFwYXQgZGlhbmFsaXNpcyBkaSBSLiAgDQoNCiMjICoqTWVuZW11a2FuIEVsZW1lbiBIVE1MIGRlbmdhbiBEZXZlbG9wZXIgVG9vbHMgKEYxMikqKiAgDQoxLiBUZWthbiAqKkYxMioqIGRpIGJyb3dzZXIgdW50dWsgbWVtYnVrYSAqRGV2ZWxvcGVyIFRvb2xzKi4gIA0KMi4gQXJhaGthbiBrZSB0YWIgKipFbGVtZW50cyoqLiAgDQozLiBHdW5ha2FuICoqRWxlbWVudCBJbnNwZWN0b3IqKiB1bnR1ayBtZW55b3JvdCB0YWJlbCBhdGF1IGVsZW1lbiBIVE1MIGxhaW5ueWEuICANCjQuIElkZW50aWZpa2FzaSB0YWcgYXRhdSBhdHJpYnV0IHlhbmcgYmVyaXNpIGRhdGEgeWFuZyBha2FuIGRpYW1iaWwsIHNlcGVydGkgYDx0YWJsZT5gLCBgPGRpdj5gLCBhdGF1IElEIHRlcnRlbnR1Lg0KDQojIyAqKkNvbnRvaCBTY3JhcGluZyBUYWJlbCBEYXRhIFIgUGFja2FnZXMqKg0KMS4gQnVrYSBoYWxhbWFuIHdlYiB5YW5nIGJlcmlzaSB0YWJlbCBkYXRhLg0KMi4gR3VuYWthbiBgcmVhZF9odG1sKClgIHVudHVrIG1lbWJhY2EgaGFsYW1hbiB0ZXJzZWJ1dDoNCiAgIGBgYHINCiAgIHVybCA8LSAiaHR0cHM6Ly9leGFtcGxlLmNvbSINCiAgIHBhZ2UgPC0gcmVhZF9odG1sKHVybCkNCiAgIGBgYA0KMy4gR3VuYWthbiBgaHRtbF9ub2RlKClgIHVudHVrIG1lbWlsaWggdGFiZWw6DQogICBgYGByDQogICB0YWJsZSA8LSBwYWdlICU+JSBodG1sX25vZGUoInRhYmxlIikNCiAgIGBgYA0KNC4gS29udmVyc2kga2UgZm9ybWF0ICpkYXRhIGZyYW1lKjoNCiAgIGBgYHINCiAgIGRhdGEgPC0gdGFibGUgJT4lIGh0bWxfdGFibGUoKQ0KICAgYGBgDQoNCiMjICoqTWVuZ2FtYmlsIERhdGEgZGFyaSBCZWJlcmFwYSBIYWxhbWFuIFdlYioqICANCjEuIFNpYXBrYW4gZGFmdGFyIFVSTCBkYXJpIGJlcmJhZ2FpIGhhbGFtYW4geWFuZyBpbmdpbiBkaS1zY3JhcGUuICANCjIuIEd1bmFrYW4gcGVydWxhbmdhbiBgZm9yYCB1bnR1ayBtZW1iYWNhIHNldGlhcCBoYWxhbWFuIHNlY2FyYSBvdG9tYXRpczogIA0KDQogICBgYGByDQogICB1cmxzIDwtIGMoDQogICAgICJodHRwczovL3d3dy50cmFuc2Zlcm1hcmt0LmNvbS9nZXJtYW55L2thZGVyL3ZlcmVpbi8zMjYyL3NhaXNvbl9pZC8yMDIzL3BsdXMvMSIsDQogICAgICJodHRwczovL3d3dy50cmFuc2Zlcm1hcmt0LmNvbS9zcGFpbi9rYWRlci92ZXJlaW4vMzM3NS9zYWlzb25faWQvMjAyMy9wbHVzLzEiLA0KICAgICAiaHR0cHM6Ly93d3cudHJhbnNmZXJtYXJrdC5jb20vaXRhbHkva2FkZXIvdmVyZWluLzMzNzYvc2Fpc29uX2lkLzIwMjMvcGx1cy8xIiwNCiAgICAgImh0dHBzOi8vd3d3LnRyYW5zZmVybWFya3QuY29tL2ZyYW5jZS9rYWRlci92ZXJlaW4vMzM3NC9zYWlzb25faWQvMjAyMy9wbHVzLzEiDQogICApDQoNCiAgIGZvciAodXJsIGluIHVybHMpIHsNCiAgICAgICBoYWxhbWFuIDwtIHJlYWRfaHRtbCh1cmwpDQogICAgICAgdGFiZWwgPC0gaGFsYW1hbiAlPiUgaHRtbF9ub2RlKCJ0YWJsZSIpICU+JSBodG1sX3RhYmxlKCkNCiAgICAgICBwcmludCh0YWJlbCkNCiAgIH0NCiAgIGBgYA0KMy4gR2FidW5na2FuIGRhdGEgZGFyaSBiZXJiYWdhaSBoYWxhbWFuIGtlIGRhbGFtIHNhdHUgZGF0YXNldCB1bnR1ayBhbmFsaXNpcyBsZWJpaCBsYW5qdXQuICANCg0KIyMgKipNZW5nYW1iaWwgRGF0YSBOb24tVGFiZWwgZGFyaSBXZWJzaXRlKiogIA0KMS4gR3VuYWthbiAqKkRldmVsb3BlciBUb29scyAoRjEyKSoqIHVudHVrIG1lbmVtdWthbiBlbGVtZW4gSFRNTCB5YW5nIG1lbnlpbXBhbiBkYXRhIHlhbmcgZGlidXR1aGthbi4gIA0KMi4gR3VuYWthbiBgaHRtbF9ub2RlcygpYCB1bnR1ayBtZW5nZWtzdHJhayBpbmZvcm1hc2kgc3Blc2lmaWsgc2VwZXJ0aSBuYW1hIHByb2R1ayBhdGF1IGhhcmdhOiAgDQoNCiAgIGBgYHINCiAgIGp1ZHVsIDwtIGhhbGFtYW4gJT4lIGh0bWxfbm9kZSgiLnRpdGxlLWNsYXNzIikgJT4lIGh0bWxfdGV4dCgpDQogICBoYXJnYSA8LSBoYWxhbWFuICU+JSBodG1sX25vZGUoIi5wcmljZS1jbGFzcyIpICU+JSBodG1sX3RleHQoKQ0KICAgYGBgDQoNCjMuIFNpbXBhbiBkYXRhIGtlIGRhbGFtICpkYXRhIGZyYW1lKiBhZ2FyIGxlYmloIG11ZGFoIGRpYW5hbGlzaXM6ICANCg0KICAgYGBgcg0KICAgZGF0YV9wcm9kdWsgPC0gZGF0YS5mcmFtZShKdWR1bCA9IGp1ZHVsLCBIYXJnYSA9IGhhcmdhKQ0KICAgYGBgDQoNCiMjICoqU2NyYXBpbmcgQmFueWFrIEhhbGFtYW4gc2VjYXJhIE90b21hdGlzKiogIA0KMS4gSWRlbnRpZmlrYXNpIHBvbGEgVVJMIHlhbmcgYmVydWJhaCBkaSBzZXRpYXAgaGFsYW1hbiAobWlzYWxueWEsIHBlcnViYWhhbiBub21vciBoYWxhbWFuKS4gIA0KMi4gR3VuYWthbiBwZXJ1bGFuZ2FuIHVudHVrIG1lbWJ1YXQgZGFmdGFyIFVSTCBkYW4gbWVuZ2FtYmlsIGRhdGEgc2VjYXJhIG90b21hdGlzOiAgDQoNCiAgIGBgYHINCiAgIGJhc2VfdXJsIDwtICJodHRwczovL3d3dy50cmFuc2Zlcm1hcmt0LmNvbS9nZXJtYW55L2thZGVyL3ZlcmVpbi8zMjYyL3NhaXNvbl9pZC8yMDIzL3BsdXMvIg0KICAgc2VtdWFfaGFsYW1hbiA8LSBsaXN0KCkNCg0KICAgZm9yIChpIGluIDE6NSkgew0KICAgICAgIHVybCA8LSBwYXN0ZTAoYmFzZV91cmwsIGkpDQogICAgICAgaGFsYW1hbiA8LSByZWFkX2h0bWwodXJsKQ0KICAgICAgIHRhYmVsIDwtIGhhbGFtYW4gJT4lIGh0bWxfbm9kZSgidGFibGUiKSAlPiUgaHRtbF90YWJsZSgpDQogICAgICAgc2VtdWFfaGFsYW1hbltbaV1dIDwtIHRhYmVsDQogICB9DQoNCiAgIGRhdGFfZmluYWwgPC0gZG8uY2FsbChyYmluZCwgc2VtdWFfaGFsYW1hbikNCiAgIGBgYA0KMy4gR2FidW5na2FuIHNlbHVydWggaGFzaWwgc2NyYXBpbmcga2UgZGFsYW0gc2F0dSBkYXRhc2V0IHVudHVrIGFuYWxpc2lzIGxlYmloIGxhbmp1dC4gIA0KDQojIyAqKk1lbWJlcnNpaGthbiBEYXRhIEhhc2lsIFNjcmFwaW5nKiogIA0KMS4gUGVyaWtzYSBrZW1iYWxpIGRhdGEgdW50dWsgbWVtYXN0aWthbiB0aWRhayBhZGEgbmlsYWkgeWFuZyBoaWxhbmcgYXRhdSBmb3JtYXQgeWFuZyBzYWxhaC4gIA0KMi4gSmlrYSBhZGEgZGF0YSB5YW5nIHRpZGFrIHNlc3VhaSBmb3JtYXQsIGd1bmFrYW4gYG11dGF0ZSgpYCBhdGF1IGBjYXNlX3doZW4oKWAgdW50dWsgbWVuZ3ViYWhueWEuICANCjMuIEd1bmFrYW4gYHNlcGFyYXRlKClgIHVudHVrIG1lbWVjYWggaW5mb3JtYXNpIGRhbGFtIHNhdHUga29sb20gbWVuamFkaSBiZWJlcmFwYSBrb2xvbSBqaWthIGRpcGVybHVrYW4uICANCg0KIyMgKipUaXBzIE1lbmdoaW5kYXJpIFBlbWJsb2tpcmFuIFNhYXQgU2NyYXBpbmcqKiAgDQotIEphbmdhbiBtZW5nYWtzZXMgdGVybGFsdSBiYW55YWsgaGFsYW1hbiBkYWxhbSB3YWt0dSBzaW5na2F0LiAgDQotIFRhbWJhaGthbiBqZWRhIGFudGFyIHBlcm1pbnRhYW4gbWVuZ2d1bmFrYW4gYFN5cy5zbGVlcCgyKWAuICANCi0gSGluZGFyaSBzY3JhcGluZyBzaXR1cyB5YW5nIG1lbWlsaWtpIHBlcmxpbmR1bmdhbiB0aW5nZ2kgdGFucGEgaXppbiBla3NwbGlzaXQuICANCg0KIyAqKktlc2ltcHVsYW4qKiAgDQpEZW5nYW4gbWVtYW5mYWF0a2FuIHBha2V0IGBydmVzdGAgZGkgUiwga2l0YSBkYXBhdCBtZW5nYW1iaWwgZGF0YSBkYXJpIGJlcmJhZ2FpIHdlYnNpdGUsIGJhaWsgZGFsYW0gYmVudHVrIHRhYmVsIG1hdXB1biBlbGVtZW4gbGFpbiBzZXBlcnRpIHRla3MgZGFuIGhhcmdhLiBNZW1haGFtaSBzdHJ1a3R1ciBIVE1MIHNhbmdhdCBwZW50aW5nIGFnYXIgc2NyYXBpbmcgYmVyamFsYW4gZGVuZ2FuIGJhaWsuIFNlbGFpbiBpdHUsIHBhc3Rpa2FuIHVudHVrIG1lbmdndW5ha2FuIG1ldG9kZSB5YW5nIGV0aXMgYWdhciB0aWRhayBtZWxhbmdnYXIga2ViaWpha2FuIHNpdHVzIHdlYi4NCg0KIyAqKlJlZnJlbnNpKioNCi0gaHR0cHM6Ly9ib29rZG93bi5vcmcvZHNjaWVuY2VsYWJzL2RhdGFfc2NpZW5jZV9wcm9ncmFtbWluZy8wNC1EYXRhX0NvbGxlY3Rpb24uaHRtbA0KLSBodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PU1IZE1GeFV5R2RrDQoNCg0KDQoNCg==