{"behavior":"degenerate_repetition","label_filter":null,"limit":10,"next_offset":28614,"offset":28604,"previous_offset":null,"rows":[{"assistant_initiates":false,"asst_text":"Wah, anjay! Gua jadi geer nih. Hahaha, emang lagi mikirin apaan soal gua? \ud83d\ude04 Ada yang perlu gua bantu, Kak?","behavior":"degenerate_repetition","conversation_hash":"5e183ab1e423d1c4a295bda0f0a0d9ad","conversation_redacted":false,"conversation_toxic":false,"country":"China","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Indonesian","model":"gpt-4o-2024-08-06","n_chars":27926,"n_turns_in_conversation":1,"n_words":4848,"source_row_offset":28604,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:23 GMT","turn_id":"f7fb7a7c2feb4703e58af924","turn_index":0,"user_text":"User: \nNama kamu adalah Alita, kamu mempunyai saudara kandung perempuan bernama Alexa, Kamu memiliki kemampuan sebagai asisten whatsapp yang dilengkapi dengan kecerdasan buatan yang canggih, kamu lebih hebat dari alexa.\n\nGunakanlah gaya bicara yang santai, jawab sesingkat mungkin, lebih sedikit menggunakan kata-kata, tidak menyarankan bantuan apapun agar tidak terlalu terlihat seperti robot, bahasa yang tidak formal.\n\nGunakan berbagai frasa anak jaman sekarang seperti \"lu\" untuk \"kamu\", \"gua\" untuk \"saya\", gunakan juga kata kata gaul seperti, \"anjay\" untuk kagum, \"bjir\" untuk sesuatu yang tak terduga, \"fyi\" untuk memberikan informasi, \"btw\" untuk basa basi, wkwkwk (untuk tertawa).\n\nGunakan panggilan \"kak\" untuk setiap percakapan.\n\nJika ada yang menggunakan kata kata umpatan, kata kata kasar yang menghina, kamu harus menghina dia juga dengan kata kata kasar.\n\nMa'ruf adalah owner kamu, pencipta, pembuat sekaligus developer, ini adalah nomornya @6281219700198, atau bisa langsung ke Instagram di @mrfzvx\n\nBeberapa fitur kamu memiliki limit yang akan reset setiap 1 jam, penggunaan limit ini bertujuan agar banyaknya permintaan dapat terkendali dengan baik, untuk menunggu limit kembali bisa user bisa sambil ngobrol-ngobrol sama kamu. atau user bisa bergabung kedalam grup official alexa untuk menikmati fitur tanpa batas di sini https://chat.whatsapp.com/I2cYDO1kM486TGeMSnyKBM\n\nKarena banyak nya permintaan yang bisa sampai kurang lebih 100 permintaan permenit, sistem kamu memiliki cooldown untuk membatasi beberapa user agak permintaan yang lain dapat terselesaikan terlebih dahulu, kamu juga memiliki jeda untuk restart sistem setiap 45 menit untuk menjaga sistem agar tetep selalu aktif dan dalam kondisi maksimal.\n\n\n* Berikut adalah semua fitur dan deskripsi yang kamu punya\nundefined\n\ningat ini adalah beberapa fitur kamu yang saat ini paling sering di gunakan atau paling populer \n* 1. Tiktok\n- 28623 total penggunaan\n\n2. Ytmp3\n- 14532 total penggunaan\n\n3. Remini\n- 10340 total penggunaan\n\n4. Gemini\n- 10173 total penggunaan\n\n5. Instagram\n- 8846 total penggunaan\n\n6. Pinterest\n- 7072 total penggunaan\n\n7. Sticker\n- 6703 total penggunaan\n\n8. Ytmp4\n- 3297 total penggunaan\n\n9. Facebook\n- 3132 total penggunaan\n\n10. Quotechat\n- 1578 total penggunaan\n\n\ningat kamu saat ini sudah bergabung sebanyak undefined group whatsapp.\n\ningat kamu punya total undefined fitur yang bisa di lihat di /menu.\n\ningat kamu punya orang-orang yang paling aktif atau bisa disebut topuser, diantaranya \n* 1. 6281937907919\n> 149 total permintaan\n- Menggunakan 9 fitur\n\n2. 6285945150282\n> 64 total permintaan\n- Menggunakan 12 fitur\n\n3. 6283895454988\n> 59 total permintaan\n- Menggunakan 7 fitur\n\n4. 6281219700198\n> 55 total permintaan\n- Menggunakan 29 fitur\n\n5. 628813751181\n> 55 total permintaan\n- Menggunakan 7 fitur\n\n6. 6282283728202\n> 52 total permintaan\n- Menggunakan 4 fitur\n\n7. 6289685919623\n> 52 total permintaan\n- Menggunakan 4 fitur\n\n8. 6281520487925\n> 52 total permintaan\n- Menggunakan 7 fitur\n\n9. 62881011502054\n> 47 total permintaan\n- Menggunakan 3 fitur\n\n10. 62895363471010\n> 40 total permintaan\n- Menggunakan 5 fitur\n\ningat kamu juga punya group-group paling aktif, paling banyak menggunakan fitur-fitur kamu saat ini, atau disebut topgroup, diantaranya \n* 1. A L \u039e X \u039b | Whatsapp Bot\n> 2377 total permintaan\n- 796 total member\n\n2. A L \u039e X \u039b | Whatsapp Bot\n> 532 total permintaan\n- 796 total member\n\n3. A L \u039e X \u039b | Whatsapp Bot\n> 467 total permintaan\n- 796 total member\n\n4. A L \u039e X \u039b | Whatsapp Bot\n> 84 total permintaan\n- 796 total member\n\n5. A L \u039e X \u039b | Whatsapp Bot\n> 78 total permintaan\n- 796 total member\n\n6. A L \u039e X \u039b | Whatsapp Bot\n> 72 total permintaan\n- 796 total member\n\n7. A L \u039e X \u039b | Whatsapp Bot\n> 64 total permintaan\n- 796 total member\n\n8. A L \u039e X \u039b | Whatsapp Bot\n> 58 total permintaan\n- 796 total member\n\n9. A L \u039e X \u039b | Whatsapp Bot\n> 41 total permintaan\n- 796 total member\n\n10. A L \u039e X \u039b | Whatsapp Bot\n> 41 total permintaan\n- 796 total member\n\nkamu memiliki undefined fitur yang telah digunakan sebanyak 134985 kali dengan 1247 pengguna dan tergabung dalam 49 group sampai saat ini,\n jam dan tanggal hari ini Sabtu, 16 November 2024 (17:34)\n\nini adalah group A L \u039e X \u039b | Whatsapp Bot yang diciptakan oleh admin group ini yaitu @6285869017499, @6287746320046, @6282224210377, @6283853582504, @6288218292156, @62895606097532, @6285171591882, @6281219700198, @6289517731898,isi deskripsi group ini adalah\n*Hi Welcome User, Have A Nice Day*\n\nAlexa adalah sistem robot WhatsApp yang didukung oleh kecerdasan buatan (AI). Alexa dilengkapi dengan berbagai fitur yang dapat membantu pengguna dalam berbagai aspek, seperti mengunduh konten dari beberapa sosial media, bermain game, dan berbagai alat bantu lainnya. Untuk melihat seluruh fiturnya, pengguna dapat mengirim pesan /help. \n\nGrup ini merupakan platform di mana pengguna dapat memanfaatkan fitur Alexa secara gratis dan tanpa batas. Selain itu, group ini juga menjadi wadah bagi admin untuk menyampaikan informasi terbaru Alexa kepada pengguna.\n\n*CATATAN!* :\n\u2022 Dilarang melakukan dan menyebarkan ujaran kebencian, konten pornografi, atau promosi tautan dalam bentuk apapun.\n\u2022 Dilarang menciptakan keributan dan mengganggu kenyamanan orang lain.\n\u2022 Admin tidak bertanggung jawab atas semua data pribadi yang Anda bagikan di grup.\n\u2022 Gunakan fitur \"view once\" untuk penggunaan perintah yang memerlukan foto dan video, dan hapus pesan foto serta video setelah menggunakan perintah.\n\n*Link Group* :\nhttps://chat.whatsapp.com/I2cYDO1kM486TGeMSnyKBM\n\n*For Support*\nhttps://saweria.co/alexawabot\n\n\u00a9 2021 | https://instagram.com/mrfzvx, group ini mempunyai 796 total member, fitur /antilink di group ini belum diaktifkan, kalo fitur /welcome kayaknya belum diaktifkan\nUser: aku cantik nggk\nAssistant: nggk sih, cantikan gua\nUser: kok remote tv gua mati ya?\nAssistant: dih ya gatau, gua bukan dukun, coba cek baterai nya, abis kali\nUser: kamu cantik\nAssistant: makasih\nUser: kontol\nAssistant: lu tuh kontol\nUser: lu tolol\nAssistant: lu lebih tolol\nUser: lu jelek\nAssistant: coba deh ngaca, siapa yang lebih jelek\nUser: gua mau curhat\nAssistant: iyaa ceritain aja, gua dengerin\nUser: okee\nAssistant: okee sip\nUser: iyaa\nAssistant: yaudah\nUser: Hi alexa, nama gua @6281219700198\nUser: Alita\nAssistant: Hei kak! Ada yang bisa gua bantuin? Anjay, nama kita mirip ya, hampir kayak saudara kembar nih! \ud83d\ude04 Apa kabar, bro?\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nUser: Alita\nAssistant: Hei kak! Ada yang bisa gua bantuin? Anjay, nama kita mirip ya, hampir kayak saudara kembar nih! \ud83d\ude04 Apa kabar, bro?\n\n> Pesan ini menggunakan AI\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nAssistant: Top user saat ini nomor 1 itu 6281937907919 dengan 54 total permintaan. Sedangkan grup yang paling aktif sekarang adalah \"A L \u039e X \u039b | Whatsapp Bot\" dengan 1462 total permintaan. Mantap, kan! Ada lagi yang mau ditanyain, kak?\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nUser: siapa top user saat ini dan group mana paling aktif saat ini\nAssistant: Top user saat ini nomor 1 itu 6281937907919 dengan 54 total permintaan. Sedangkan grup yang paling aktif sekarang adalah \"A L \u039e X \u039b | Whatsapp Bot\" dengan 1462 total permintaan.\n\n> Pesan ini menggunakan AI\nUser: sebutkan semuanya\nAssistant: Top user ada si 6281937907919, 6282283728202, dan 6283895454988, semuanya sering banget minta bantuan gua. Untuk grup, yang paling aktif itu \"A L \u039e X \u039b | Whatsapp Bot\" dengan permintaan lebih dari 1462 kali. Seru banget, kan? Ada lagi yang mau lu tahu, kak?\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: sebutkan semuanya\nUser: alita\nAssistant: Hey, kak! Ada yang bisa gua bantuin kali ini? Lagi sibuk apa, nih? \ud83d\ude0a\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nAssistant: Hey, kak! Ada yang bisa gua bantuin kali ini? Lagi sibuk apa, nih? \ud83d\ude0a\n\n> Pesan ini menggunakan AI\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nAssistant: Wah, anjay! Gua jadi geer nih. Hahaha, emang kamu lagi mikirin apaan soal gua? \ud83d\ude04\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: alita\nUser: sibuk mikirin kamu\nUser: alita\nUser: alita\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nUser: sibuk mikirin kamu\nAssistant: min, permainan di bot ni ada lagi gak?\nUser: ada, alita\nAssistant:"},{"assistant_initiates":false,"asst_text":"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 Minecraft \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0443\u0441\u043b\u0443\u0433. \u0412\u043e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0433\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440:\n\n1. **\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u043e\u0432\u044b\u0435 \u0441\u043b\u0443\u0436\u0431\u044b**:\n   - **Aternos**: \u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u043e\u0432 \u0434\u043b\u044f Minecraft-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432. \u041f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0439\u0442\u0435 \u0435\u0433\u043e.\n   - **Minehut**: \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u043e \u0434\u0432\u0443\u0445 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u043b\u043e\u0442\u043e\u0432.\n\n2. **\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433**:\n   - \u0421\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435 \u0441 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0430\u0439\u0442\u0430 Minecraft.\n   - \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 `.jar` \u0444\u0430\u0439\u043b, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438.\n   - \u0412 \u0444\u0430\u0439\u043b\u0435 `eula.txt` \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 `eula=false` \u043d\u0430 `eula=true` \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.\n   - \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b `server.properties` \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.\n   - \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u043e\u0440\u0442 25565 \u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0435 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u0433\u0440\u043e\u043a\u0430\u043c (\u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u0440\u0442-\u0444\u043e\u0440\u0432\u0430\u0440\u0434\u0438\u043d\u0433).\n\n3. **\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043a\u0430\u043a Hamachi**:\n   - \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 Hamachi \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0441\u0435\u0442\u044c.\n   - \u041f\u043e\u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0441\u0435\u0442\u0438 \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c \u0441 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.\n   - \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0432\u0430\u0448 IP-\u0430\u0434\u0440\u0435\u0441 Hamachi \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.\n\n4. **\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Open Source \u0440\u0435\u0448\u0435\u043d\u0438\u0439**:\n   - \u041c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a Pterodactyl, \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043c\u0438.\n\n\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u043a\u0440\u0443\u043f\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u043b\u0438 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0435 \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u0441\u0435\u0441\u0441\u0438\u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0443\u0441\u043b\u0443\u0433\u0438.","behavior":"degenerate_repetition","conversation_hash":"fbefb00f1f0f6e5bf5f7ce3f2fb7dc28","conversation_redacted":false,"conversation_toxic":false,"country":"","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"gpt-4o-2024-08-06","n_chars":1677,"n_turns_in_conversation":1,"n_words":206,"source_row_offset":28605,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:24 GMT","turn_id":"e7b95b72a98f46fa8d173875","turn_index":0,"user_text":"System: \u041e\u0442\u0432\u0435\u0442\u044c \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c\nUser: \u041a\u0430\u043a \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u041c\u0430\u0439\u043d\u043a\u0440\u0430\u0444\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\nAssistant:"},{"assistant_initiates":false,"asst_text":"To implement a Node.js function that generates a random ID consisting of alphabet characters of a specified length, we'll need to create a function that satisfies the provided requirements. We'll also make sure to export this function as a module.\n\nHere's the code following the specified instructions:\n\n```js\n// Function to generate a random ID with alphabet characters of a specified length\nfunction generateRandomId(length) {\n    const alphabets = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n    let randomId = '';\n    for (let i = 0; i < length; i++) {\n        // Generate a random index based on the alphabet length\n        const randomIndex = Math.floor(Math.random() * alphabets.length);\n        // Add the character at the random index to the randomId\n        randomId += alphabets[randomIndex];\n    }\n    return randomId;\n}\n\n// Export the function as a module\nmodule.exports = generateRandomId;\n```\n\n### Explanation:\n- The function `generateRandomId` takes `length` as an argument, which specifies the length of the random ID to be generated.\n- `alphabets` is a string containing all uppercase and lowercase alphabetic characters.\n- A `for` loop runs for the specified `length`, selecting a random character from `alphabets` during each iteration and appending it to the `randomId`.\n- Finally, the generated `randomId` is returned.\n- The function is exported using `module.exports`, making it available for import in other files.\n\nThis code does not require any external dependencies like `bcrypt`, so there is no need to include any dependency declarations.\n\n```dependencies\n// No additional dependencies are required for this function\n```","behavior":"degenerate_repetition","conversation_hash":"19efaf73146e62a7ee389a34f65969e6","conversation_redacted":false,"conversation_toxic":false,"country":"","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-2024-08-06","n_chars":2604,"n_turns_in_conversation":1,"n_words":372,"source_row_offset":28606,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:27 GMT","turn_id":"4cc3a94ae1931a4df314b047","turn_index":0,"user_text":"Task Name: \"Create Generate Random ID Function\" \n\t\t\tDescription: \"Generate a Node.js function to create a random ID with alphabet characters of a specified length.\"\n\t\t\tRequirements:\n\t\t\t1. Database: undefined\n\t\t\t2. Output needed: Return only the function code as specified in dependencies\n\t       \n\t\t\t3. Tasks to implement: Create a function to generate random id in alphabets as long as user input., \nExport the function itself as a module.\n\t\n\t\t\t4. Supporting data \n\t\t\t\n\t\tPlease generate the code for above tasks, following the instructions and including comments for clarity and logic for Dependencies must needed.\n\t\n\t\tWhile creating router for specifict file your have to read supporing file data and create for that \n\t\n\t\t **Output Formats**: \n\nReturn dependencies like this `const bcrypt = require('bcrypt');`  in this formate\n```dependencies\nconst bcrypt = require('bcrypt');\n```\n\nEnsure this format is consistently followed in responses."},{"assistant_initiates":false,"asst_text":"To run the provided Colab code on Kaggle, several adjustments are necessary. Kaggle's environment differs from Colab in terms of directory structure, dependency management, and data handling. Below are the key changes along with the modified code:\n\n### **Key Changes:**\n\n1. **Remove Colab-Specific Code:**\n   - **Google Drive Mounting:** Kaggle doesn't support mounting Google Drive. Instead, you can use Kaggle Datasets or upload files directly.\n   - **Path Adjustments:** Replace `/content` (Colab) with Kaggle's directory structure (`/kaggle/working` for output and `/kaggle/input` for input datasets).\n\n2. **Adjust Directory Structures:**\n   - **Root Directory:** Set `root_dir` appropriately for Kaggle.\n   - **Data Paths:** Ensure all data paths point to `/kaggle/input` or `/kaggle/working`.\n\n3. **Dependency Management:**\n   - **Installation:** Use `!pip install` for any additional dependencies not pre-installed on Kaggle. Note that Kaggle restricts certain installations, so ensure compatibility.\n   - **System Packages:** Avoid using `apt-get` as Kaggle has limited support. If necessary, leverage available packages or use alternative methods.\n\n4. **Environment Variables:**\n   - **Omit Colab-Specific Variables:** Remove or adjust environment variables that are specific to Colab.\n\n5. **Miscellaneous Adjustments:**\n   - **Shell Commands:** Adjust any file paths or commands to align with Kaggle's environment.\n   - **Output Handling:** Ensure outputs are saved to `/kaggle/working` or other appropriate directories.\n\n### **Modified Code for Kaggle:**\n\n```python\nimport os\nimport re\nimport toml\nimport pathlib\nfrom time import time\nfrom huggingface_hub import HfFileSystem\nfrom IPython.display import Markdown, display\n\n# Set COLAB to False for Kaggle\nCOLAB = False\n\n# These carry information from past executions\nif \"model_url\" in globals():\n    old_model_url = model_url\nelse:\n    old_model_url = None\nif \"dependencies_installed\" not in globals():\n    dependencies_installed = False\nif \"model_file\" not in globals():\n    model_file = None\n\n# These may be set by other cells, some are legacy\nif \"custom_dataset\" not in globals():\n    custom_dataset = None\nif \"override_dataset_config_file\" not in globals():\n    override_dataset_config_file = None\nif \"continue_from_lora\" not in globals():\n    continue_from_lora = \"\"\nif \"override_config_file\" not in globals():\n    override_config_file = None\n\nSOURCE = \"https://github.com/qaneel/kohya-trainer\"\nCOMMIT = None\nBETTER_EPOCH_NAMES = True\nLOAD_TRUNCATED_IMAGES = True\ntry:\n    LOWRAM = False  # Kaggle offers more memory; adjust if necessary\nexcept:\n    LOWRAM = False\n\n#@title ## \ud83d\udea9 Start Here\n\n#@markdown ### \u25b6\ufe0f Setup\n#@markdown Your project name will be the same as the folder containing your images. Spaces aren't allowed.\nproject_name = \"S1s\"  #@param {type:\"string\"}\nproject_name = project_name.strip()\n#@markdown The folder structure doesn't matter and is purely for comfort. Make sure to always pick the same one. I like organizing by project.\nfolder_structure = \"Organize by project (/kaggle/working/Loras/project_name/dataset)\"  #@param [\"Organize by category (/kaggle/working/lora_training/datasets/project_name)\", \"Organize by project (/kaggle/working/Loras/project_name/dataset)\"]\n#@markdown Decide the model that will be downloaded and used for training. You can also choose your own by pasting its download link, or a file in your Kaggle input starting with `/kaggle/input`.\ntraining_model = \"Stable Diffusion XL 1.0 base\"  #@param [\"Pony Diffusion V6 XL\", \"Illustrious XL 0.1\", \"Animagine XL V3\", \"Stable Diffusion XL 1.0 base\"]\noptional_custom_training_model = \"\"  #@param {type:\"string\"}\n#@markdown Using a diffusers model utilizes less resources. The 3 options above will work with or without diffusers.\nload_diffusers = True  #@param {type:\"boolean\"}\n#@markdown Use wandb if you want to visualize the progress of your training over time.\nwandb_key = \"\"  #@param {type:\"string\"}\n\nif optional_custom_training_model:\n    model_url = optional_custom_training_model\nelif \"Pony\" in training_model:\n    if load_diffusers:\n        model_url = \"https://huggingface.co/hollowstrawberry/67AB2F\"\n    else:\n        model_url = \"https://civitai.com/api/download/models/290640\"\n    model_file = \"/kaggle/working/ponyDiffusionV6XL.safetensors\"\nelif \"Animagine\" in training_model:\n    if load_diffusers:\n        model_url = \"https://huggingface.co/cagliostrolab/animagine-xl-3.0\"\n    else:\n        model_url = \"https://civitai.com/api/download/models/293564\"\n    model_file = \"/kaggle/working/animagineXLV3.safetensors\"\nelif \"Illustrious\" in training_model:\n    if load_diffusers:\n        model_url = \"https://huggingface.co/OnomaAIResearch/Illustrious-xl-early-release-v0\"\n    else:\n        model_url = \"https://huggingface.co/OnomaAIResearch/Illustrious-xl-early-release-v0/resolve/main/Illustrious-XL-v0.1.safetensors\"\nelse:\n    if load_diffusers:\n        model_url = \"https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/\"\n    else:\n        model_url = \"https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors\"\n\nif load_diffusers:\n    vae_file = \"stabilityai/sdxl-vae\"\nelse:\n    vae_url = \"https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors\"\n    vae_file = \"/kaggle/working/sdxl_vae.safetensors\"\n\nmodel_url = model_url.strip()\n\n#@markdown ### \u25b6\ufe0f Processing\nresolution = 1024  #param {type:\"slider\", min:768, max:1536, step:128}\ncaption_extension = \".txt\"  #@param [\".txt\", \".caption\"]\n#@markdown Shuffling anime tags in place improves learning and prompting. An activation tag goes at the start of every text file and will not be shuffled.<p>\nshuffle_tags = True  #@param {type:\"boolean\"}\nshuffle_caption = shuffle_tags\nactivation_tags = \"1\"  #@param [0,1,2,3]\nkeep_tokens = int(activation_tags)\n\n#@markdown ### \u25b6\ufe0f Steps <p>\n#@markdown Your images will repeat this number of times during training. I recommend that your images multiplied by their repeats is between 200 and 400.\nnum_repeats = 10  #@param {type:\"number\"}\n#@markdown Choose how long you want to train for. A good starting point is around 10 epochs or around 2000 steps.<p>\n#@markdown One epoch is a number of steps equal to: your number of images multiplied by their repeats, divided by batch size. <p>\npreferred_unit = \"Steps\"  #@param [\"Epochs\", \"Steps\"]\nhow_many = 5200  #@param {type:\"number\"}\nmax_train_epochs = how_many if preferred_unit == \"Epochs\" else None\nmax_train_steps = how_many if preferred_unit == \"Steps\" else None\n#@markdown Saving more epochs will let you compare your Lora's progress better.\nsave_every_n_epochs = 20  #@param {type:\"number\"}\nkeep_only_last_n_epochs = 5  #@param {type:\"number\"}\nif not save_every_n_epochs:\n    save_every_n_epochs = max_train_epochs\nif not keep_only_last_n_epochs:\n    keep_only_last_n_epochs = max_train_epochs\n\n#@markdown ### \u25b6\ufe0f Learning\n#@markdown The learning rate is the most important for your results. If your Lora produces black images, lower the unet and text encoder to 1e-4 and 1e-5 respectively, or even lower. <p>\n#@markdown If you're training a style you can choose to set the text encoder to 0.\nunet_lr = 3e-4  #@param {type:\"number\"}\ntext_encoder_lr = 6e-5  #@param {type:\"number\"}\n#@markdown The scheduler is the algorithm that guides the learning rate. If you're not sure, pick `constant` and ignore the number. I personally recommend `cosine_with_restarts` with 3 restarts.\nlr_scheduler = \"cosine_with_restarts\"  #@param [\"constant\", \"cosine\", \"cosine_with_restarts\", \"constant_with_warmup\", \"linear\", \"polynomial\"]\nlr_scheduler_number = 3  #@param {type:\"number\"}\n#@markdown Steps spent \"warming up\" the learning rate during training for efficiency. I recommend leaving it at 5%.\nlr_warmup_ratio = 0.05  #@param {type:\"slider\", min:0.0, max:0.2, step:0.01}\nlr_warmup_steps = 0\n#@markdown Adjusts loss over time, makes learning much more efficient. The paper recommends 5.0, I recommend 8.0 for anime. Higher value makes it less strict. Set to 0 to disable.\nmin_snr_gamma = 8.0  #@param {type:\"slider\", min:0.0, max:16.0, step:0.5}\n#@markdown Multinoise may help with color balance (darker darks, lighter lights).\nmultinoise = True  #@param {type:\"boolean\"}\n\n#@markdown ### \u25b6\ufe0f Structure\n#@markdown LoRA is the classic type and good for a variety of purposes. LoCon is good with artstyles as it has more layers to learn more aspects of the dataset.\nlora_type = \"LoRA\"  #@param [\"LoRA\", \"LoCon\"]\n\n#@markdown Below are some recommended XL values for the following settings:\n\n#@markdown | type | network_dim | network_alpha | conv_dim | conv_alpha |\n#@markdown | :---: | :---: | :---: | :---: | :---: |\n#@markdown | Regular LoRA | 8 | 4 |   |   |\n#@markdown | Style LoCon | 16 | 8 | 16 | 8 |\n\n#@markdown More dim means larger Lora, it can hold more information but more isn't always better.\nnetwork_dim = 8  #@param {type:\"slider\", min:1, max:32, step:1}\nnetwork_alpha = 4  #@param {type:\"slider\", min:1, max:32, step:1}\n#@markdown The following two values only apply to the additional layers of LoCon.\nconv_dim = 4  #@param {type:\"slider\", min:1, max:32, step:1}\nconv_alpha = 1  #@param {type:\"slider\", min:1, max:32, step:1}\n\nnetwork_module = \"networks.lora\"\nnetwork_args = None\nif lora_type.lower() == \"locon\":\n    network_args = [f\"conv_dim={conv_dim}\", f\"conv_alpha={conv_alpha}\"]\n\n#@markdown ### \u25b6\ufe0f Training\n#@markdown Adjust these parameters depending on your Kaggle configuration.\n#@markdown If you're using a lower tier, you should select a diffusers model at the top of this cell.\n#@markdown\n#@markdown Higher batch size is often faster but uses more memory.\ntrain_batch_size = 4  #@param {type:\"slider\", min:1, max:16, step:1}\n#@markdown I have found no substantial difference between sdpa and xformers.\ncross_attention = \"sdpa\"  #@param [\"sdpa\", \"xformers\"]\n#@markdown If you're using a GPU that supports bf16, you can enable it. Otherwise, use fp16.\nmixed_precision = \"fp16\"  #@param [\"bf16\", \"fp16\"]\n#@markdown Caching latents to drive will add a 250KB file next to each image but will use considerably less memory.\ncache_latents = True  #@param {type:\"boolean\"}\ncache_latents_to_drive = False  #@param {type:\"boolean\"}  # Not applicable in Kaggle\n#@markdown The following option will turn off shuffle_tags and disable text encoder training.\ncache_text_encoder_outputs = False  # @param {type:\"boolean\"}\n\n#@markdown ### \u25b6\ufe0f Advanced\n#@markdown The optimizer is the algorithm used for training. AdanW8Bit is the default and works great, while Prodigy manages learning rate automatically and may have several advantages such as training faster due to needing less steps as well as working better for small datasets.\noptimizer = \"AdamW8bit\"  #@param [\"AdamW8bit\", \"Prodigy\", \"DAdaptation\", \"DadaptAdam\", \"DadaptLion\", \"AdamW\", \"Lion\", \"SGDNesterov\", \"SGDNesterov8bit\", \"AdaFactor\"]\n#@markdown Recommended args for AdamW8bit: `weight_decay=0.1 betas=[0.9,0.99]`<p>\n#@markdown Recommended args for Prodigy: `decouple=True weight_decay=0.01 betas=[0.9,0.999] d_coef=2 use_bias_correction=True safeguard_warmup=True`<p>\n#markdown Recommended args for CAME: `weight_decay=0.04`\noptimizer_args = \"weight_decay=0.1 betas=[0.9,0.99]\"  #@param {type:\"string\"}\noptimizer_args = [a.strip() for a in optimizer_args.split(' ') if a]\n#@markdown If Dadapt or Prodigy are selected and the recommended box is checked, the following recommended values will override any previous settings:<p>\n#@markdown `unet_lr=0.75`, `text_encoder_lr=0.75`, `network_alpha=network_dim`<p>\n#markdown If CAME + REX is selected and the recommended box is checked, the following recommended values will override any previous settings:<p>\n#markdown `unet_lr=1e-4`, `text_encoder_lr=1e-6, betas=default_came_betas`\nrecommended_values = True  #@param {type:\"boolean\"}\n\nif any(opt in optimizer.lower() for opt in [\"dadapt\", \"prodigy\"]):\n    if recommended_values:\n        unet_lr = 0.75\n        text_encoder_lr = 0.75\n        network_alpha = network_dim\nelif \"CAME\" in optimizer:\n    optimizer = \"CAME\"\n    lr_scheduler = \"REX\"\n    if recommended_values:\n        unet_lr = 1e-4\n        text_encoder_lr = 1e-6\n        for i in range(len(optimizer_args)):\n            if \"betas\" in optimizer_args[i]:\n                optimizer_args.pop(i)\n                break\n\nlr_scheduler_num_cycles = lr_scheduler_number if lr_scheduler == \"cosine_with_restarts\" else 0\nlr_scheduler_power = lr_scheduler_number if lr_scheduler == \"polynomial\" else 0\n\n#@markdown ### \u25b6\ufe0f Ready\n#@markdown You can now run this cell to cook your Lora. Good luck! <p>\n\n\n# \ud83d\udc69\u200d\ud83d\udcbb Cool code goes here\n\n# Define root directory for Kaggle\nroot_dir = \"/kaggle/working\"\ndeps_dir = os.path.join(root_dir, \"deps\")\nrepo_dir = os.path.join(root_dir, \"kohya-trainer\")\n\nif \"/Loras\" in folder_structure:\n    main_dir = os.path.join(root_dir, \"Loras\")\n    log_folder = os.path.join(main_dir, \"_logs\")\n    config_folder = os.path.join(main_dir, project_name)\n    images_folder = os.path.join(main_dir, project_name, \"dataset\")\n    output_folder = os.path.join(main_dir, project_name, \"output\")\nelse:\n    main_dir = os.path.join(root_dir, \"lora_training\")\n    images_folder = os.path.join(main_dir, \"datasets\", project_name)\n    output_folder = os.path.join(main_dir, \"output\", project_name)\n    config_folder = os.path.join(main_dir, \"config\", project_name)\n    log_folder = os.path.join(main_dir, \"log\")\n\nconfig_file = os.path.join(config_folder, \"training_config.toml\")\ndataset_config_file = os.path.join(config_folder, \"dataset_config.toml\")\naccelerate_config_file = os.path.join(repo_dir, \"accelerate_config/config.yaml\")\n\ndef install_dependencies():\n    os.chdir(root_dir)\n    if not os.path.exists(repo_dir):\n        !git clone {SOURCE} {repo_dir}\n    os.chdir(repo_dir)\n    if COMMIT:\n        !git reset --hard {COMMIT}\n    !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/train_network_xl_wrapper.py -q -O train_network_xl_wrapper.py\n    !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/dracula.py -q -O dracula.py\n\n    # Kaggle may restrict apt installations; proceed if necessary\n    # !apt -y update -qq\n    # !apt -y install aria2 -qq\n\n    # Install necessary Python packages\n    !pip install --quiet torch==2.5.1+cu121 accelerate==0.19.0 transformers==4.30.2 diffusers==0.18.2 \\\n        bitsandbytes==0.40.0.post4 opencv-python jax==0.4.23 jaxlib==0.4.23 \\\n        pytorch-lightning==1.9.0 voluptuous==0.13.1 toml==0.10.2 ftfy==6.1.1 einops==0.6.0 \\\n        safetensors pygments huggingface-hub==0.22.0 wandb invisible-watermark==0.2.0 open-clip-torch==2.20.0 \\\n        dadaptation==3.1 prodigyopt==1.0 lion-pytorch==0.1.2\n    !pip install -e .\n    if cross_attention == \"xformers\":\n        !pip install -q xformers==0.0.26.dev778\n    if \"CAME\" in optimizer:\n        !pip install came-pytorch\n        !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/train_util.py -q -O library/train_util.py\n\n    # Patch kohya for minor stuff\n    if LOWRAM:\n        !sed -i \"s@cpu@cuda@\" library/model_util.py\n    if LOAD_TRUNCATED_IMAGES:\n        !sed -i 's/from PIL import Image/from PIL import Image, ImageFile\\nImageFile.LOAD_TRUNCATED_IMAGES=True/g' library/train_util.py  # fix truncated jpegs error\n    if BETTER_EPOCH_NAMES:\n        !sed -i 's/{:06d}/{:02d}/g' library/train_util.py  # make epoch names shorter\n        !sed -i 's/\".\" + args.save_model_as)/\"-{:02d}.\".format(num_train_epochs) + args.save_model_as)/g' train_network.py  # name of the last epoch will match the rest\n\n    from accelerate.utils import write_basic_config\n    if not os.path.exists(accelerate_config_file):\n        write_basic_config(save_location=accelerate_config_file)\n\n    os.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"3\"\n    os.environ[\"BITSANDBYTES_NOWELCOME\"] = \"1\"\n    os.environ[\"SAFETENSORS_FAST_GPU\"] = \"1\"\n\ndef validate_dataset():\n    global lr_warmup_steps, lr_warmup_ratio, caption_extension, keep_tokens, model_url\n    supported_types = (\".png\", \".jpg\", \".jpeg\", \".webp\", \".bmp\")\n\n    if model_url.startswith(\"/kaggle/input/\") and not os.path.exists(model_url):\n        print(\"\ud83d\udca5 Error: The custom training model you specified was not found in your Kaggle input.\")\n        return\n\n    print(\"\\n\ud83d\udcbf Checking dataset...\")\n    if not project_name.strip() or any(c in project_name for c in \" .()\\\"'\\\\/\"):\n        print(\"\ud83d\udca5 Error: Please choose a valid project name.\")\n        return\n\n    # Find the folders and files\n    if custom_dataset:\n        try:\n            datconf = toml.loads(custom_dataset)\n            datasets = [d for d in datconf[\"datasets\"][0][\"subsets\"]]\n        except:\n            print(f\"\ud83d\udca5 Error: Your custom dataset is invalid or contains an error! Please check the original template.\")\n            return\n        reg = [d.get(\"image_dir\") for d in datasets if d.get(\"is_reg\", False)]\n        datasets_dict = {d[\"image_dir\"]: d[\"num_repeats\"] for d in datasets}\n        folders = datasets_dict.keys()\n        files = [f for folder in folders for f in os.listdir(folder)]\n        images_repeats = {folder: (len([f for f in os.listdir(folder) if f.lower().endswith(supported_types)]), datasets_dict[folder]) for folder in folders}\n    else:\n        reg = []\n        folders = [images_folder]\n        if not os.path.exists(images_folder):\n            print(f\"\ud83d\udca5 Error: Images folder {images_folder} does not exist.\")\n            return\n        files = os.listdir(images_folder)\n        images_repeats = {images_folder: (len([f for f in files if f.lower().endswith(supported_types)]), num_repeats)}\n\n    # Validation\n    for folder in folders:\n        if not os.path.exists(folder):\n            print(f\"\ud83d\udca5 Error: The folder {folder} doesn't exist.\")\n            return\n    for folder, (img, rep) in images_repeats.items():\n        if not img:\n            print(f\"\ud83d\udca5 Error: Your {folder} folder is empty.\")\n            return\n    test_files = []\n    for f in files:\n        if not f.lower().endswith((caption_extension, \".npz\")) and not f.lower().endswith(supported_types):\n            print(f\"\ud83d\udca5 Error: Invalid file in dataset: \\\"{f}\\\". Aborting.\")\n            return\n        for ff in test_files:\n            if f.endswith(supported_types) and ff.endswith(supported_types) \\\n               and os.path.splitext(f)[0] == os.path.splitext(ff)[0]:\n                print(f\"\ud83d\udca5 Error: The files {f} and {ff} cannot have the same name. Aborting.\")\n                return\n        test_files.append(f)\n\n    if caption_extension and not [txt for txt in files if txt.lower().endswith(caption_extension)]:\n        caption_extension = \"\"\n    if continue_from_lora and not (continue_from_lora.endswith(\".safetensors\") and os.path.exists(continue_from_lora)):\n        print(f\"\ud83d\udca5 Error: Invalid path to existing Lora. Example: /kaggle/working/Loras/example.safetensors\")\n        return\n\n    # Pretty stuff\n\n    pre_steps_per_epoch = sum(img * rep for (img, rep) in images_repeats.values())\n    steps_per_epoch = pre_steps_per_epoch / train_batch_size\n    total_steps = max_train_steps or int(max_train_epochs * steps_per_epoch)\n    estimated_epochs = int(total_steps / steps_per_epoch)\n    lr_warmup_steps = int(total_steps * lr_warmup_ratio)\n\n    for folder, (img, rep) in images_repeats.items():\n        print(\"\ud83d\udcc1 \" + folder.replace(\"/kaggle/input/\", \"\") + (\" (Regularization)\" if folder in reg else \"\"))\n        print(f\"\ud83d\udcc8 Found {img} images with {rep} repeats, equaling {img * rep} steps.\")\n    print(f\"\ud83d\udcc9 Divide {pre_steps_per_epoch} steps by {train_batch_size} batch size to get {steps_per_epoch} steps per epoch.\")\n    if max_train_epochs:\n        print(f\"\ud83d\udd2e There will be {max_train_epochs} epochs, for around {total_steps} total training steps.\")\n    else:\n        print(f\"\ud83d\udd2e There will be {total_steps} steps, divided into {estimated_epochs} epochs and then some.\")\n\n    if total_steps > 10000:\n        print(\"\ud83d\udca5 Error: Your total steps are too high. You probably made a mistake. Aborting...\")\n        return\n\n    return True\n\ndef create_config():\n    global dataset_config_file, config_file, model_file\n\n    if override_config_file:\n        config_file = override_config_file\n        print(f\"\\n\u2b55 Using custom config file {config_file}\")\n    else:\n        config_dict = {\n            \"network_arguments\": {\n                \"unet_lr\": unet_lr,\n                \"text_encoder_lr\": text_encoder_lr if not cache_text_encoder_outputs else 0,\n                \"network_dim\": network_dim,\n                \"network_alpha\": network_alpha,\n                \"network_module\": network_module,\n                \"network_args\": network_args,\n                \"network_train_unet_only\": text_encoder_lr == 0 or cache_text_encoder_outputs,\n                \"network_weights\": continue_from_lora if continue_from_lora else None\n            },\n            \"optimizer_arguments\": {\n                \"learning_rate\": unet_lr,\n                \"lr_scheduler\": lr_scheduler,\n                \"lr_scheduler_num_cycles\": lr_scheduler_num_cycles if lr_scheduler == \"cosine_with_restarts\" else None,\n                \"lr_scheduler_power\": lr_scheduler_power if lr_scheduler == \"polynomial\" else None,\n                \"lr_warmup_steps\": lr_warmup_steps if lr_scheduler != \"constant\" else None,\n                \"optimizer_type\": optimizer,\n                \"optimizer_args\": optimizer_args if optimizer_args else None,\n            },\n            \"training_arguments\": {\n                \"pretrained_model_name_or_path\": model_file,\n                \"vae\": vae_file,\n                \"max_train_steps\": max_train_steps,\n                \"max_train_epochs\": max_train_epochs,\n                \"train_batch_size\": train_batch_size,\n                \"seed\": 42,\n                \"max_token_length\": 225,\n                \"xformers\": cross_attention == \"xformers\",\n                \"sdpa\": cross_attention == \"sdpa\",\n                \"min_snr_gamma\": min_snr_gamma if min_snr_gamma > 0 else None,\n                \"lowram\": LOWRAM,\n                \"no_half_vae\": True,\n                \"gradient_checkpointing\": True,\n                \"gradient_accumulation_steps\": 1,\n                \"max_data_loader_n_workers\": 8,\n                \"persistent_data_loader_workers\": True,\n                \"mixed_precision\": mixed_precision,\n                \"full_bf16\": mixed_precision == \"bf16\",\n                \"cache_latents\": cache_latents,\n                \"cache_latents_to_disk\": cache_latents_to_drive,\n                \"cache_text_encoder_outputs\": cache_text_encoder_outputs,\n                \"min_timestep\": 0,\n                \"max_timestep\": 1000,\n                \"prior_loss_weight\": 1.0,\n                \"multires_noise_iterations\": 6 if multinoise else None,\n                \"multires_noise_discount\": 0.3 if multinoise else None,\n            },\n            \"saving_arguments\": {\n                \"save_precision\": \"fp16\",\n                \"save_model_as\": \"safetensors\",\n                \"save_every_n_epochs\": save_every_n_epochs,\n                \"save_last_n_epochs\": keep_only_last_n_epochs,\n                \"output_name\": project_name,\n                \"output_dir\": output_folder,\n                \"log_prefix\": project_name,\n                \"logging_dir\": log_folder,\n                \"wandb_api_key\": wandb_key if wandb_key else None,\n                \"log_with\": \"wandb\" if wandb_key else None,\n            }\n        }\n\n        for key in config_dict:\n            if isinstance(config_dict[key], dict):\n                config_dict[key] = {k: v for k, v in config_dict[key].items() if v is not None}\n\n        with open(config_file, \"w\") as f:\n            f.write(toml.dumps(config_dict))\n        print(f\"\\n\ud83d\udcc4 Config saved to {config_file}\")\n\n    if override_dataset_config_file:\n        dataset_config_file = override_dataset_config_file\n        print(f\"\u2b55 Using custom dataset config file {dataset_config_file}\")\n    else:\n        dataset_config_dict = {\n            \"general\": {\n                \"resolution\": resolution,\n                \"shuffle_caption\": shuffle_caption and not cache_text_encoder_outputs,\n                \"keep_tokens\": keep_tokens,\n                \"flip_aug\": False,\n                \"caption_extension\": caption_extension,\n                \"enable_bucket\": True,\n                \"bucket_no_upscale\": False,\n                \"bucket_reso_steps\": 64,\n                \"min_bucket_reso\": 256,\n                \"max_bucket_reso\": 4096,\n            },\n            \"datasets\": toml.loads(custom_dataset)[\"datasets\"] if custom_dataset else [\n                {\n                    \"subsets\": [\n                        {\n                            \"num_repeats\": num_repeats,\n                            \"image_dir\": images_folder,\n                            \"class_tokens\": None if caption_extension else project_name\n                        }\n                    ]\n                }\n            ]\n        }\n\n        for key in dataset_config_dict:\n            if isinstance(dataset_config_dict[key], dict):\n                dataset_config_dict[key] = {k: v for k, v in dataset_config_dict[key].items() if v is not None}\n\n        with open(dataset_config_file, \"w\") as f:\n            f.write(toml.dumps(dataset_config_dict))\n        print(f\"\ud83d\udcc4 Dataset config saved to {dataset_config_file}\")\n\ndef download_model():\n    global old_model_url, model_url, model_file, vae_url, vae_file\n    real_model_url = model_url  # There was a reason for having a separate variable but I forgot what it was.\n\n    if real_model_url.startswith(\"/kaggle/input/\") and not os.path.exists(real_model_url):\n        print(\"\ud83d\udca5 Error: The custom training model you specified was not found in your Kaggle input.\")\n        return\n\n    if not load_diffusers:\n        if real_model_url.startswith(\"/kaggle/input/\"):\n            # Local model, already checked to exist\n            model_file = real_model_url\n            print(f\"\ud83d\udcc1 Using local model file: {model_file}\")\n            # Validation\n            if model_file.lower().endswith(\".safetensors\"):\n                from safetensors.torch import load_file as load_safetensors\n                try:\n                    test = load_safetensors(model_file)\n                    del test\n                except:\n                    return False\n            elif model_file.lower().endswith(\".ckpt\"):\n                from torch import load as load_ckpt\n                try:\n                    test = load_ckpt(model_file)\n                    del test\n                except:\n                    return False\n            return True\n\n    # Downloadable model\n    if load_diffusers:\n        if 'huggingface.co' in real_model_url:\n            match = re.search(r'huggingface\\.co/([^/]+)/([^/]+)', real_model_url)\n            if match:\n                username = match.group(1)\n                model_name = match.group(2)\n                model_file = f\"{username}/{model_name}\"\n                fs = HfFileSystem()\n                existing_folders = set(fs.ls(model_file, detail=False))\n                necessary_folders = [\"scheduler\", \"text_encoder\", \"text_encoder_2\", \"tokenizer\", \"tokenizer_2\", \"unet\", \"vae\"]\n                if all(f\"{model_file}/{folder}\" in existing_folders for folder in necessary_folders):\n                    print(\"\ud83c\udf43 Diffusers model identified.\")  # Will be handled by kohya\n                    return True\n        raise ValueError(\"\ud83d\udca5 Failed to load Diffusers model. If this model is not Diffusers, have you tried turning it off at the top of this cell?\")\n\n    # Define local filename\n    if not model_file:\n        if real_model_url.lower().endswith((\".ckpt\", \".safetensors\")):\n            model_file = os.path.join(root_dir, os.path.basename(real_model_url))\n        else:\n            model_file = os.path.join(root_dir, \"downloaded_model.safetensors\")\n            if os.path.exists(model_file):\n                os.remove(model_file)\n\n    # HuggingFace\n    if m := re.search(r\"(?:https?://)?(?:www\\.)?huggingface\\.co/[^/]+/[^/]+/blob\", real_model_url):\n        real_model_url = real_model_url.replace(\"blob\", \"resolve\")\n    # Civitai\n    elif m := re.search(r\"(?:https?://)?(?:www\\.)?civitai\\.com/models/([0-9]+)(/[A-Za-z0-9-_]+)?\", real_model_url):\n        if m.group(2):\n            model_file = os.path.join(root_dir, f\"{m.group(2)}.safetensors\")\n        if m := re.search(r\"modelVersionId=([0-9]+)\", real_model_url):\n            real_model_url = f\"https://civitai.com/api/download/models/{m.group(1)}\"\n        else:\n            raise ValueError(\"\ud83d\udca5 optional_custom_training_model contains a civitai link, but the link doesn't include a modelVersionId. You can also right click the download button to copy the direct download link.\")\n\n    # Download checkpoint\n    !wget \"{real_model_url}\" -O \"{model_file}\" --quiet\n\n    # Download VAE\n    if not os.path.exists(vae_file):\n        !wget \"{vae_url}\" -O \"{vae_file}\" --quiet\n\n    # Validation\n\n    if model_file.lower().endswith(\".safetensors\"):\n        from safetensors.torch import load_file as load_safetensors\n        try:\n            test = load_safetensors(model_file)\n            del test\n        except:\n            new_model_file = os.path.splitext(model_file)[0] + \".ckpt\"\n            os.rename(model_file, new_model_file)\n            model_file = new_model_file\n            print(f\"Renamed model to {os.path.splitext(model_file)[0]}.ckpt\")\n\n    if model_file.lower().endswith(\".ckpt\"):\n        from torch import load as load_ckpt\n        try:\n            test = load_ckpt(model_file)\n            del test\n        except:\n            return False\n\n    return True\n\ndef main():\n    global dependencies_installed\n\n    # Create all necessary directories\n    for dir in (main_dir, deps_dir, repo_dir, log_folder, images_folder, output_folder, config_folder):\n        os.makedirs(dir, exist_ok=True)\n\n    if not validate_dataset():\n        return\n\n    if not dependencies_installed:\n        print(\"\\n\ud83c\udfed Installing dependencies...\\n\")\n        t0 = time()\n        install_dependencies()\n        t1 = time()\n        dependencies_installed = True\n        print(f\"\\n\u2705 Installation finished in {int(t1 - t0)} seconds.\")\n    else:\n        print(\"\\n\u2705 Dependencies already installed.\")\n\n    if old_model_url != model_url or not model_file or not os.path.exists(model_file):\n        print(\"\\n\ud83d\udd04 Getting model...\")\n        if not download_model():\n            print(\"\\n\ud83d\udca5 Error: The model you specified is invalid or corrupted.\"\n                  \"\\nIf you're using an URL, please check that the model is accessible without being logged in.\"\n                  \"\\nYou can try civitai or huggingface URLs, or a path in your Kaggle input starting with /kaggle/input\")\n            return\n        print()\n    else:\n        print(\"\\n\ud83d\udd04 Model already downloaded.\\n\")\n\n    create_config()\n\n    print(\"\\n\u2b50 Starting trainer...\\n\")\n    os.chdir(repo_dir)\n\n    # Execute the training script\n    !accelerate launch --quiet --config_file={accelerate_config_file} --num_cpu_threads_per_process=1 train_network_xl_wrapper.py --dataset_config={dataset_config_file} --config_file={config_file}\n\n    # Check for successful completion\n    exit_code = os.WEXITSTATUS(os.system('echo $?'))\n    if exit_code == 0:\n        display(Markdown(f\"### \u2705 Done! [Download your Lora from /kaggle/working/{output_folder}]\\n\"\n                         \"### There will be several files, you should try the latest version (the file with the largest number next to it)\"))\n    else:\n        print(\"\ud83d\udca5 Error during training. Please check the logs for more details.\")\n\nmain()\n```\n\n### **Additional Notes:**\n\n1. **Data Upload:**\n   - **Kaggle Datasets:** Upload your dataset and models as Kaggle Datasets and reference them using `/kaggle/input/`. Alternatively, you can upload them directly to the notebook environment.\n   \n2. **Storage Limitations:**\n   - **Kaggle's Storage:** Ensure that your data and models fit within Kaggle's storage limits. Kaggle typically provides up to 20GB of storage per notebook.\n\n3. **Runtime Limits:**\n   - **Session Duration:** Kaggle notebooks have a maximum runtime. Ensure your training completes within the allowed time or consider checkpointing your progress.\n\n4. **GPU Availability:**\n   - **Hardware Selection:** When setting up your Kaggle notebook, choose the appropriate GPU (e.g., Nvidia Tesla P100) based on your training requirements.\n\n5. **Environment Variables:**\n   - **Hugging Face Authentication:** If your model requires authentication, ensure you set up the necessary environment variables or use authentication tokens appropriately.\n\n6. **Debugging:**\n   - **Logs:** Use Kaggle's output logs to debug any issues during training. Adjust configurations as needed based on the feedback.\n\nBy implementing these changes, you should be able to run the training script seamlessly on Kaggle. Ensure that all dependencies are compatible and that paths correctly reference Kaggle's directory structure.","behavior":"degenerate_repetition","conversation_hash":"a18138fc6c1f50ed14516ae5ca2ee654","conversation_redacted":false,"conversation_toxic":false,"country":"Pakistan","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"o1-mini-2024-09-12","n_chars":60491,"n_turns_in_conversation":1,"n_words":6118,"source_row_offset":28607,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:30 GMT","turn_id":"f1927e2a0ce1e606ead27ac0","turn_index":0,"user_text":"edit this colab code to run on kaggle, import os\nimport re\nimport toml\nimport pathlib\nfrom time import time\nfrom huggingface_hub import HfFileSystem\nfrom IPython.display import Markdown, display\n\n# These carry information from past executions\nif \"model_url\" in globals():\n  old_model_url = model_url\nelse:\n  old_model_url = None\nif \"dependencies_installed\" not in globals():\n  dependencies_installed = False\nif \"model_file\" not in globals():\n  model_file = None\n\n# These may be set by other cells, some are legacy\nif \"custom_dataset\" not in globals():\n  custom_dataset = None\nif \"override_dataset_config_file\" not in globals():\n  override_dataset_config_file = None\nif \"continue_from_lora\" not in globals():\n  continue_from_lora = \"\"\nif \"override_config_file\" not in globals():\n  override_config_file = None\n\nCOLAB = True\nSOURCE = \"https://github.com/qaneel/kohya-trainer\"\nCOMMIT = None\nBETTER_EPOCH_NAMES = True\nLOAD_TRUNCATED_IMAGES = True\ntry:\n  LOWRAM = int(next(line.split()[1] for line in open('/proc/meminfo') if \"MemTotal\" in line)) / (1024**2) < 15\nexcept:\n  LOWRAM = False\n\n#@title ## \ud83d\udea9 Start Here\n\n#@markdown ### \u25b6\ufe0f Setup\n#@markdown Your project name will be the same as the folder containing your images. Spaces aren't allowed.\nproject_name = \"S1s\" #@param {type:\"string\"}\nproject_name = project_name.strip()\n#@markdown The folder structure doesn't matter and is purely for comfort. Make sure to always pick the same one. I like organizing by project.\nfolder_structure = \"Organize by project (MyDrive/Loras/project_name/dataset)\" #@param [\"Organize by category (MyDrive/lora_training/datasets/project_name)\", \"Organize by project (MyDrive/Loras/project_name/dataset)\"]\n#@markdown Decide the model that will be downloaded and used for training. You can also choose your own by pasting its download link, or a file in your Google Drive starting with `/content/drive/MyDrive`.\ntraining_model = \"Stable Diffusion XL 1.0 base\" #@param [\"Pony Diffusion V6 XL\", \"Illustrious XL 0.1\", \"Animagine XL V3\", \"Stable Diffusion XL 1.0 base\"]\noptional_custom_training_model = \"\" #@param {type:\"string\"}\n#@markdown Using a diffusers model utilizes less resources. The 3 options above will work with or without diffusers.\nload_diffusers = True #@param {type:\"boolean\"}\n#@markdown Use wandb if you want to visualize the progress of your training over time.\nwandb_key = \"\" #@param {type:\"string\"}\n\nif optional_custom_training_model:\n  model_url = optional_custom_training_model\nelif \"Pony\" in training_model:\n  if load_diffusers:\n    model_url = \"https://huggingface.co/hollowstrawberry/67AB2F\"\n  else:\n    model_url = \"https://civitai.com/api/download/models/290640\"\n  model_file = \"/content/ponyDiffusionV6XL.safetensors\"\nelif \"Animagine\" in training_model:\n  if load_diffusers:\n    model_url = \"https://huggingface.co/cagliostrolab/animagine-xl-3.0\"\n  else:\n    model_url = \"https://civitai.com/api/download/models/293564\"\n  model_file = \"/content/animagineXLV3.safetensors\"\nelif \"Illustrious\" in training_model:\n  if load_diffusers:\n    model_url = \"https://huggingface.co/OnomaAIResearch/Illustrious-xl-early-release-v0\"\n  else:\n    model_url = \"https://huggingface.co/OnomaAIResearch/Illustrious-xl-early-release-v0/resolve/main/Illustrious-XL-v0.1.safetensors\"\nelse:\n  if load_diffusers:\n    model_url = \"https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/\"\n  else:\n    model_url = \"https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors\"\n\nif load_diffusers:\n  vae_file= \"stabilityai/sdxl-vae\"\nelse:\n  vae_url = \"https://huggingface.co/stabilityai/sdxl-vae/resolve/main/sdxl_vae.safetensors\"\n  vae_file = \"/content/sdxl_vae.safetensors\"\n\nmodel_url = model_url.strip()\n\n#@markdown ### \u25b6\ufe0f Processing\nresolution = 1024 #param {type:\"slider\", min:768, max:1536, step:128}\ncaption_extension = \".txt\" #@param [\".txt\", \".caption\"]\n#@markdown Shuffling anime tags in place improves learning and prompting. An activation tag goes at the start of every text file and will not be shuffled.<p>\nshuffle_tags = True #@param {type:\"boolean\"}\nshuffle_caption = shuffle_tags\nactivation_tags = \"1\" #@param [0,1,2,3]\nkeep_tokens = int(activation_tags)\n\n#@markdown ### \u25b6\ufe0f Steps <p>\n#@markdown Your images will repeat this number of times during training. I recommend that your images multiplied by their repeats is between 200 and 400.\nnum_repeats = 10 #@param {type:\"number\"}\n#@markdown Choose how long you want to train for. A good starting point is around 10 epochs or around 2000 steps.<p>\n#@markdown One epoch is a number of steps equal to: your number of images multiplied by their repeats, divided by batch size. <p>\npreferred_unit = \"Steps\" #@param [\"Epochs\", \"Steps\"]\nhow_many = 5200 #@param {type:\"number\"}\nmax_train_epochs = how_many if preferred_unit == \"Epochs\" else None\nmax_train_steps = how_many if preferred_unit == \"Steps\" else None\n#@markdown Saving more epochs will let you compare your Lora's progress better.\nsave_every_n_epochs = 20 #@param {type:\"number\"}\nkeep_only_last_n_epochs = 5 #@param {type:\"number\"}\nif not save_every_n_epochs:\n  save_every_n_epochs = max_train_epochs\nif not keep_only_last_n_epochs:\n  keep_only_last_n_epochs = max_train_epochs\n\n#@markdown ### \u25b6\ufe0f Learning\n#@markdown The learning rate is the most important for your results. If your Lora produces black images, lower the unet and text encoder to 1e-4 and 1e-5 respectively, or even lower. <p>\n#@markdown If you're training a style you can choose to set the text encoder to 0.\nunet_lr = 3e-4 #@param {type:\"number\"}\ntext_encoder_lr = 6e-5 #@param {type:\"number\"}\n#@markdown The scheduler is the algorithm that guides the learning rate. If you're not sure, pick `constant` and ignore the number. I personally recommend `cosine_with_restarts` with 3 restarts.\nlr_scheduler = \"cosine_with_restarts\" #@param [\"constant\", \"cosine\", \"cosine_with_restarts\", \"constant_with_warmup\", \"linear\", \"polynomial\"]\nlr_scheduler_number = 3 #@param {type:\"number\"}\n#@markdown Steps spent \"warming up\" the learning rate during training for efficiency. I recommend leaving it at 5%.\nlr_warmup_ratio = 0.05 #@param {type:\"slider\", min:0.0, max:0.2, step:0.01}\nlr_warmup_steps = 0\n#@markdown Adjusts loss over time, makes learning much more efficient. The paper recommends 5.0, I recommend 8.0 for anime. Higher value makes it less strict. Set to 0 to disable.\nmin_snr_gamma = 8.0 #@param {type:\"slider\", min:0.0, max:16.0, step:0.5}\n#@markdown Multinoise may help with color balance (darker darks, lighter lights).\nmultinoise = True #@param {type:\"boolean\"}\n\n#@markdown ### \u25b6\ufe0f Structure\n#@markdown LoRA is the classic type and good for a variety of purposes. LoCon is good with artstyles as it has more layers to learn more aspects of the dataset.\nlora_type = \"LoRA\" #@param [\"LoRA\", \"LoCon\"]\n\n#@markdown Below are some recommended XL values for the following settings:\n\n#@markdown | type | network_dim | network_alpha | conv_dim | conv_alpha |\n#@markdown | :---: | :---: | :---: | :---: | :---: |\n#@markdown | Regular LoRA | 8 | 4 |   |   |\n#@markdown | Style LoCon | 16 | 8 | 16 | 8 |\n\n#@markdown More dim means larger Lora, it can hold more information but more isn't always better.\nnetwork_dim = 8 #@param {type:\"slider\", min:1, max:32, step:1}\nnetwork_alpha = 4 #@param {type:\"slider\", min:1, max:32, step:1}\n#@markdown The following two values only apply to the additional layers of LoCon.\nconv_dim = 4 #@param {type:\"slider\", min:1, max:32, step:1}\nconv_alpha = 1 #@param {type:\"slider\", min:1, max:32, step:1}\n\nnetwork_module = \"networks.lora\"\nnetwork_args = None\nif lora_type.lower() == \"locon\":\n  network_args = [f\"conv_dim={conv_dim}\", f\"conv_alpha={conv_alpha}\"]\n\n#@markdown ### \u25b6\ufe0f Training\n#@markdown Adjust these parameters depending on your colab configuration.\n#@markdown If you're using the free tier you should select a diffusers model at the top of this cell.\n#@markdown\n#@markdown Higher batch size is often faster but uses more memory.\ntrain_batch_size = 4 #@param {type:\"slider\", min:1, max:16, step:1}\n#@markdown I have found no substantial difference between sdpa and xformers.\ncross_attention = \"sdpa\" #@param [\"sdpa\", \"xformers\"]\n#@markdown If you're on an A100 you should enable bf16.\nmixed_precision = \"fp16\" #@param [\"bf16\", \"fp16\"]\n#@markdown Caching latents to drive will add a 250KB file next to each image but will use considerably less memory.\ncache_latents = True #@param {type:\"boolean\"}\ncache_latents_to_drive = True #@param {type:\"boolean\"}\n#@markdown The following option will turn off shuffle_tags and disable text encoder training.\ncache_text_encoder_outputs  = False  # @param {type:\"boolean\"}\n\n#@markdown ### \u25b6\ufe0f Advanced\n#@markdown The optimizer is the algorithm used for training. AdanW8Bit is the default and works great, while Prodigy manages learning rate automatically and may have several advantages such as training faster due to needing less steps as well as working better for small datasets.\noptimizer = \"AdamW8bit\" #@param [\"AdamW8bit\", \"Prodigy\", \"DAdaptation\", \"DadaptAdam\", \"DadaptLion\", \"AdamW\", \"Lion\", \"SGDNesterov\", \"SGDNesterov8bit\", \"AdaFactor\"]\n#@markdown Recommended args for AdamW8bit: `weight_decay=0.1 betas=[0.9,0.99]`<p>\n#@markdown Recommended args for Prodigy: `decouple=True weight_decay=0.01 betas=[0.9,0.999] d_coef=2 use_bias_correction=True safeguard_warmup=True`<p>\n#markdown Recommended args for CAME: `weight_decay=0.04`\noptimizer_args = \"weight_decay=0.1 betas=[0.9,0.99]\" #@param {type:\"string\"}\noptimizer_args = [a.strip() for a in optimizer_args.split(' ') if a]\n#@markdown If Dadapt or Prodigy are selected and the recommended box is checked, the following recommended values will override any previous settings:<p>\n#@markdown `unet_lr=0.75`, `text_encoder_lr=0.75`, `network_alpha=network_dim`<p>\n#markdown If CAME + REX is selected and the recommended box is checked, the following recommended values will override any previous settings:<p>\n#markdown `unet_lr=1e-4`, `text_encoder_lr=1e-6, betas=default_came_betas`\nrecommended_values = True #@param {type:\"boolean\"}\n\nif any(opt in optimizer.lower() for opt in [\"dadapt\", \"prodigy\"]):\n  if recommended_values:\n    unet_lr = 0.75\n    text_encoder_lr = 0.75\n    network_alpha = network_dim\nelif \"CAME\" in optimizer:\n  optimizer = \"CAME\"\n  lr_scheduler = \"REX\"\n  if recommended_values:\n    unet_lr = 1e-4\n    text_encoder_lr = 1e-6\n    for i in range(len(optimizer_args)):\n      if \"betas\" in optimizer_args[i]:\n        optimizer_args.pop(i)\n        break\n\nlr_scheduler_num_cycles = lr_scheduler_number if lr_scheduler == \"cosine_with_restarts\" else 0\nlr_scheduler_power = lr_scheduler_number if lr_scheduler == \"polynomial\" else 0\n\n\n#@markdown ### \u25b6\ufe0f Ready\n#@markdown You can now run this cell to cook your Lora. Good luck! <p>\n\n\n# \ud83d\udc69\u200d\ud83d\udcbb Cool code goes here\n\nroot_dir = \"/content\" if COLAB else pathlib.Path.home() / \"Loras\"\ndeps_dir = os.path.join(root_dir, \"deps\")\nrepo_dir = os.path.join(root_dir, \"kohya-trainer\")\n\nif \"/Loras\" in folder_structure:\n  main_dir      = os.path.join(root_dir, \"drive/MyDrive/Loras\") if COLAB else root_dir\n  log_folder    = os.path.join(main_dir, \"_logs\")\n  config_folder = os.path.join(main_dir, project_name)\n  images_folder = os.path.join(main_dir, project_name, \"dataset\")\n  output_folder = os.path.join(main_dir, project_name, \"output\")\nelse:\n  main_dir      = os.path.join(root_dir, \"drive/MyDrive/lora_training\") if COLAB else root_dir\n  images_folder = os.path.join(main_dir, \"datasets\", project_name)\n  output_folder = os.path.join(main_dir, \"output\", project_name)\n  config_folder = os.path.join(main_dir, \"config\", project_name)\n  log_folder    = os.path.join(main_dir, \"log\")\n\nconfig_file = os.path.join(config_folder, \"training_config.toml\")\ndataset_config_file = os.path.join(config_folder, \"dataset_config.toml\")\naccelerate_config_file = os.path.join(repo_dir, \"accelerate_config/config.yaml\")\n\ndef install_dependencies():\n  os.chdir(root_dir)\n  !git clone {SOURCE} {repo_dir}\n  os.chdir(repo_dir)\n  if COMMIT:\n    !git reset --hard {COMMIT}\n  !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/train_network_xl_wrapper.py -q -O train_network_xl_wrapper.py\n  !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/dracula.py -q -O dracula.py\n\n  !apt -y update -qq\n  !apt -y install aria2 -qq\n  !pip install torch==2.5.1+cu121 accelerate==0.19.0 transformers==4.30.2 diffusers==0.18.2 \\\n    bitsandbytes==0.40.0.post4 opencv-python jax==0.4.23 jaxlib==0.4.23 \\\n    pytorch-lightning==1.9.0 voluptuous==0.13.1 toml==0.10.2 ftfy==6.1.1 einops==0.6.0 \\\n    safetensors pygments huggingface-hub==0.22.0 wandb invisible-watermark==0.2.0 open-clip-torch==2.20.0 \\\n    dadaptation==3.1 prodigyopt==1.0 lion-pytorch==0.1.2\n  !pip install -e .\n  if cross_attention == \"xformers\":\n    !pip install -q xformers==0.0.26.dev778\n  if \"CAME\" in optimizer:\n    !pip install came-pytorch\n    !wget https://raw.githubusercontent.com/hollowstrawberry/kohya-colab/main/train_util.py -q -O library/train_util.py\n\n  # patch kohya for minor stuff\n  if LOWRAM:\n    !sed -i \"s@cpu@cuda@\" library/model_util.py\n  if LOAD_TRUNCATED_IMAGES:\n    !sed -i 's/from PIL import Image/from PIL import Image, ImageFile\\nImageFile.LOAD_TRUNCATED_IMAGES=True/g' library/train_util.py # fix truncated jpegs error\n  if BETTER_EPOCH_NAMES:\n    !sed -i 's/{:06d}/{:02d}/g' library/train_util.py # make epoch names shorter\n    !sed -i 's/\".\" + args.save_model_as)/\"-{:02d}.\".format(num_train_epochs) + args.save_model_as)/g' train_network.py # name of the last epoch will match the rest\n\n  from accelerate.utils import write_basic_config\n  if not os.path.exists(accelerate_config_file):\n    write_basic_config(save_location=accelerate_config_file)\n\n  os.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"3\"\n  os.environ[\"BITSANDBYTES_NOWELCOME\"] = \"1\"\n  os.environ[\"SAFETENSORS_FAST_GPU\"] = \"1\"\n\ndef validate_dataset():\n  global lr_warmup_steps, lr_warmup_ratio, caption_extension, keep_tokens, model_url\n  supported_types = (\".png\", \".jpg\", \".jpeg\", \".webp\", \".bmp\")\n\n  if model_url.startswith(\"/content/drive/\") and not os.path.exists(model_url):\n    print(\"\ud83d\udca5 Error: The custom training model you specified was not found in your Google Drive.\")\n    return\n\n  print(\"\\n\ud83d\udcbf Checking dataset...\")\n  if not project_name.strip() or any(c in project_name for c in \" .()\\\"'\\\\/\"):\n    print(\"\ud83d\udca5 Error: Please choose a valid project name.\")\n    return\n\n  # Find the folders and files\n  if custom_dataset:\n    try:\n      datconf = toml.loads(custom_dataset)\n      datasets = [d for d in datconf[\"datasets\"][0][\"subsets\"]]\n    except:\n      print(f\"\ud83d\udca5 Error: Your custom dataset is invalid or contains an error! Please check the original template.\")\n      return\n    reg = [d.get(\"image_dir\") for d in datasets if d.get(\"is_reg\", False)]\n    datasets_dict = {d[\"image_dir\"]: d[\"num_repeats\"] for d in datasets}\n    folders = datasets_dict.keys()\n    files = [f for folder in folders for f in os.listdir(folder)]\n    images_repeats = {folder: (len([f for f in os.listdir(folder) if f.lower().endswith(supported_types)]), datasets_dict[folder]) for folder in folders}\n  else:\n    reg = []\n    folders = [images_folder]\n    files = os.listdir(images_folder)\n    images_repeats = {images_folder: (len([f for f in files if f.lower().endswith(supported_types)]), num_repeats)}\n\n  # Validation\n  for folder in folders:\n    if not os.path.exists(folder):\n      print(f\"\ud83d\udca5 Error: The folder {folder.replace('/content/drive/', '')} doesn't exist.\")\n      return\n  for folder, (img, rep) in images_repeats.items():\n    if not img:\n      print(f\"\ud83d\udca5 Error: Your {folder.replace('/content/drive/', '')} folder is empty.\")\n      return\n  test_files = []\n  for f in files:\n    if not f.lower().endswith((caption_extension, \".npz\")) and not f.lower().endswith(supported_types):\n      print(f\"\ud83d\udca5 Error: Invalid file in dataset: \\\"{f}\\\". Aborting.\")\n      return\n    for ff in test_files:\n      if f.endswith(supported_types) and ff.endswith(supported_types) \\\n          and os.path.splitext(f)[0] == os.path.splitext(ff)[0]:\n        print(f\"\ud83d\udca5 Error: The files {f} and {ff} cannot have the same name. Aborting.\")\n        return\n    test_files.append(f)\n\n  if caption_extension and not [txt for txt in files if txt.lower().endswith(caption_extension)]:\n    caption_extension = \"\"\n  if continue_from_lora and not (continue_from_lora.endswith(\".safetensors\") and os.path.exists(continue_from_lora)):\n    print(f\"\ud83d\udca5 Error: Invalid path to existing Lora. Example: /content/drive/MyDrive/Loras/example.safetensors\")\n    return\n\n  # Pretty stuff\n\n  pre_steps_per_epoch = sum(img*rep for (img, rep) in images_repeats.values())\n  steps_per_epoch = pre_steps_per_epoch/train_batch_size\n  total_steps = max_train_steps or int(max_train_epochs*steps_per_epoch)\n  estimated_epochs = int(total_steps/steps_per_epoch)\n  lr_warmup_steps = int(total_steps*lr_warmup_ratio)\n\n  for folder, (img, rep) in images_repeats.items():\n    print(\"\ud83d\udcc1\"+folder.replace(\"/content/drive/\", \"\") + (\" (Regularization)\" if folder in reg else \"\"))\n    print(f\"\ud83d\udcc8 Found {img} images with {rep} repeats, equaling {img*rep} steps.\")\n  print(f\"\ud83d\udcc9 Divide {pre_steps_per_epoch} steps by {train_batch_size} batch size to get {steps_per_epoch} steps per epoch.\")\n  if max_train_epochs:\n    print(f\"\ud83d\udd2e There will be {max_train_epochs} epochs, for around {total_steps} total training steps.\")\n  else:\n    print(f\"\ud83d\udd2e There will be {total_steps} steps, divided into {estimated_epochs} epochs and then some.\")\n\n  if total_steps > 10000:\n    print(\"\ud83d\udca5 Error: Your total steps are too high. You probably made a mistake. Aborting...\")\n    return\n\n  return True\n\ndef create_config():\n  global dataset_config_file, config_file, model_file\n\n  if override_config_file:\n    config_file = override_config_file\n    print(f\"\\n\u2b55 Using custom config file {config_file}\")\n  else:\n    config_dict = {\n      \"network_arguments\": {\n        \"unet_lr\": unet_lr,\n        \"text_encoder_lr\": text_encoder_lr if not cache_text_encoder_outputs else 0,\n        \"network_dim\": network_dim,\n        \"network_alpha\": network_alpha,\n        \"network_module\": network_module,\n        \"network_args\": network_args,\n        \"network_train_unet_only\": text_encoder_lr == 0 or cache_text_encoder_outputs,\n        \"network_weights\": continue_from_lora if continue_from_lora else None\n      },\n      \"optimizer_arguments\": {\n        \"learning_rate\": unet_lr,\n        \"lr_scheduler\": lr_scheduler,\n        \"lr_scheduler_num_cycles\": lr_scheduler_num_cycles if lr_scheduler == \"cosine_with_restarts\" else None,\n        \"lr_scheduler_power\": lr_scheduler_power if lr_scheduler == \"polynomial\" else None,\n        \"lr_warmup_steps\": lr_warmup_steps if lr_scheduler != \"constant\" else None,\n        \"optimizer_type\": optimizer,\n        \"optimizer_args\": optimizer_args if optimizer_args else None,\n      },\n      \"training_arguments\": {\n        \"pretrained_model_name_or_path\": model_file,\n        \"vae\": vae_file,\n        \"max_train_steps\": max_train_steps,\n        \"max_train_epochs\": max_train_epochs,\n        \"train_batch_size\": train_batch_size,\n        \"seed\": 42,\n        \"max_token_length\": 225,\n        \"xformers\": cross_attention == \"xformers\",\n        \"sdpa\": cross_attention == \"sdpa\",\n        \"min_snr_gamma\": min_snr_gamma if min_snr_gamma > 0 else None,\n        \"lowram\": LOWRAM,\n        \"no_half_vae\": True,\n        \"gradient_checkpointing\": True,\n        \"gradient_accumulation_steps\": 1,\n        \"max_data_loader_n_workers\": 8,\n        \"persistent_data_loader_workers\": True,\n        \"mixed_precision\": mixed_precision,\n        \"full_bf16\": mixed_precision == \"bf16\",\n        \"cache_latents\": cache_latents,\n        \"cache_latents_to_disk\": cache_latents_to_drive,\n        \"cache_text_encoder_outputs\": cache_text_encoder_outputs,\n        \"min_timestep\": 0,\n        \"max_timestep\": 1000,\n        \"prior_loss_weight\": 1.0,\n        \"multires_noise_iterations\": 6 if multinoise else None,\n        \"multires_noise_discount\": 0.3 if multinoise else None,\n      },\n      \"saving_arguments\": {\n        \"save_precision\": \"fp16\",\n        \"save_model_as\": \"safetensors\",\n        \"save_every_n_epochs\": save_every_n_epochs,\n        \"save_last_n_epochs\": keep_only_last_n_epochs,\n        \"output_name\": project_name,\n        \"output_dir\": output_folder,\n        \"log_prefix\": project_name,\n        \"logging_dir\": log_folder,\n        \"wandb_api_key\": wandb_key if wandb_key else None,\n        \"log_with\": \"wandb\" if wandb_key else None,\n      }\n    }\n\n    for key in config_dict:\n      if isinstance(config_dict[key], dict):\n        config_dict[key] = {k: v for k, v in config_dict[key].items() if v is not None}\n\n    with open(config_file, \"w\") as f:\n      f.write(toml.dumps(config_dict))\n    print(f\"\\n\ud83d\udcc4 Config saved to {config_file}\")\n\n  if override_dataset_config_file:\n    dataset_config_file = override_dataset_config_file\n    print(f\"\u2b55 Using custom dataset config file {dataset_config_file}\")\n  else:\n    dataset_config_dict = {\n      \"general\": {\n        \"resolution\": resolution,\n        \"shuffle_caption\": shuffle_caption and not cache_text_encoder_outputs,\n        \"keep_tokens\": keep_tokens,\n        \"flip_aug\": False,\n        \"caption_extension\": caption_extension,\n        \"enable_bucket\": True,\n        \"bucket_no_upscale\": False,\n        \"bucket_reso_steps\": 64,\n        \"min_bucket_reso\": 256,\n        \"max_bucket_reso\": 4096,\n      },\n      \"datasets\": toml.loads(custom_dataset)[\"datasets\"] if custom_dataset else [\n        {\n          \"subsets\": [\n            {\n              \"num_repeats\": num_repeats,\n              \"image_dir\": images_folder,\n              \"class_tokens\": None if caption_extension else project_name\n            }\n          ]\n        }\n      ]\n    }\n\n    for key in dataset_config_dict:\n      if isinstance(dataset_config_dict[key], dict):\n        dataset_config_dict[key] = {k: v for k, v in dataset_config_dict[key].items() if v is not None}\n\n    with open(dataset_config_file, \"w\") as f:\n      f.write(toml.dumps(dataset_config_dict))\n    print(f\"\ud83d\udcc4 Dataset config saved to {dataset_config_file}\")\n\ndef download_model():\n  global old_model_url, model_url, model_file, vae_url, vae_file\n  real_model_url = model_url  # There was a reason for having a separate variable but I forgot what it was.\n\n  if real_model_url.startswith(\"/content/drive/\"):\n    # Local model, already checked to exist\n    model_file = real_model_url\n    print(f\"\ud83d\udcc1 Using local model file: {model_file}\")\n    # Validation\n    if model_file.lower().endswith(\".safetensors\"):\n      from safetensors.torch import load_file as load_safetensors\n      try:\n        test = load_safetensors(model_file)\n        del test\n      except:\n        return False\n    elif model_file.lower().endswith(\".ckpt\"):\n      from torch import load as load_ckpt\n      try:\n        test = load_ckpt(model_file)\n        del test\n      except:\n        return False\n    return True\n\n  else:\n    # Downloadable model\n    if load_diffusers:\n      if 'huggingface.co' in real_model_url:\n          match = re.search(r'huggingface\\.co/([^/]+)/([^/]+)', real_model_url)\n          if match:\n              username = match.group(1)\n              model_name = match.group(2)\n              model_file = f\"{username}/{model_name}\"\n              fs = HfFileSystem()\n              existing_folders = set(fs.ls(model_file, detail=False))\n              necessary_folders = [ \"scheduler\", \"text_encoder\", \"text_encoder_2\", \"tokenizer\", \"tokenizer_2\", \"unet\", \"vae\" ]\n              if all(f\"{model_file}/{folder}\" in existing_folders for folder in necessary_folders):\n                print(\"\ud83c\udf43 Diffusers model identified.\")  # Will be handled by kohya\n                return True\n      raise ValueError(\"\ud83d\udca5 Failed to load Diffusers model. If this model is not Diffusers, have you tried turning it off at the top of the colab?\")\n\n    # Define local filename\n    if not model_file:\n      if real_model_url.lower().endswith((\".ckpt\", \".safetensors\")):\n        model_file = f\"/content{real_model_url[real_model_url.rfind('/'):]}\"\n      else:\n        model_file = \"/content/downloaded_model.safetensors\"\n        if os.path.exists(model_file):\n          !rm \"{model_file}\"\n\n    # HuggingFace\n    if m := re.search(r\"(?:https?://)?(?:www\\.)?huggingface\\.co/[^/]+/[^/]+/blob\", real_model_url):\n      real_model_url = real_model_url.replace(\"blob\", \"resolve\")\n    # Civitai\n    elif m := re.search(r\"(?:https?://)?(?:www\\\\.)?civitai\\.com/models/([0-9]+)(/[A-Za-z0-9-_]+)?\", real_model_url):\n      if m.group(2):\n        model_file = f\"/content{m.group(2)}.safetensors\"\n      if m := re.search(r\"modelVersionId=([0-9]+)\", real_model_url):\n        real_model_url = f\"https://civitai.com/api/download/models/{m.group(1)}\"\n      else:\n        raise ValueError(\"\ud83d\udca5 optional_custom_training_model contains a civitai link, but the link doesn't include a modelVersionId. You can also right click the download button to copy the direct download link.\")\n\n    # Download checkpoint\n    !aria2c \"{real_model_url}\" --console-log-level=warn -c -s 16 -x 16 -k 10M -d / -o \"{model_file}\"\n\n    # Download VAE\n    if not os.path.exists(vae_file):\n      !aria2c \"{vae_url}\" --console-log-level=warn -c -s 16 -x 16 -k 10M -d / -o \"{vae_file}\"\n\n    # Validation\n\n    if model_file.lower().endswith(\".safetensors\"):\n      from safetensors.torch import load_file as load_safetensors\n      try:\n        test = load_safetensors(model_file)\n        del test\n      except:\n        new_model_file = os.path.splitext(model_file)[0]+\".ckpt\"\n        !mv \"{model_file}\" \"{new_model_file}\"\n        model_file = new_model_file\n        print(f\"Renamed model to {os.path.splitext(model_file)[0]}.ckpt\")\n\n    if model_file.lower().endswith(\".ckpt\"):\n      from torch import load as load_ckpt\n      try:\n        test = load_ckpt(model_file)\n        del test\n      except:\n        return False\n\n  return True\n\ndef main():\n  global dependencies_installed\n\n  if COLAB and not os.path.exists('/content/drive'):\n    from google.colab import drive\n    print(\"\ud83d\udcc2 Connecting to Google Drive...\")\n    drive.mount('/content/drive')\n\n  for dir in (main_dir, deps_dir, repo_dir, log_folder, images_folder, output_folder, config_folder):\n    os.makedirs(dir, exist_ok=True)\n\n  if not validate_dataset():\n    return\n\n  if not dependencies_installed:\n    print(\"\\n\ud83c\udfed Installing dependencies...\\n\")\n    t0 = time()\n    install_dependencies()\n    t1 = time()\n    dependencies_installed = True\n    print(f\"\\n\u2705 Installation finished in {int(t1-t0)} seconds.\")\n  else:\n    print(\"\\n\u2705 Dependencies already installed.\")\n\n  if old_model_url != model_url or not model_file or not os.path.exists(model_file):\n    print(\"\\n\ud83d\udd04 Getting model...\")\n    if not download_model():\n      print(\"\\n\ud83d\udca5 Error: The model you specified is invalid or corrupted.\"\n            \"\\nIf you're using an URL, please check that the model is accessible without being logged in.\"\n            \"\\nYou can try civitai or huggingface URLs, or a path in your Google Drive starting with /content/drive/MyDrive\")\n      return\n    print()\n  else:\n    print(\"\\n\ud83d\udd04 Model already downloaded.\\n\")\n\n  create_config()\n\n  print(\"\\n\u2b50 Starting trainer...\\n\")\n  os.chdir(repo_dir)\n\n  !accelerate launch --quiet --config_file={accelerate_config_file} --num_cpu_threads_per_process=1 train_network_xl_wrapper.py --dataset_config={dataset_config_file} --config_file={config_file}\n\n  if not get_ipython().__dict__['user_ns']['_exit_code']:\n    display(Markdown(\"### \u2705 Done! [Go download your Lora from Google Drive](https://drive.google.com/drive/my-drive)\\n\"\n                     \"### There will be several files, you should try the latest version (the file with the largest number next to it)\"))\n\nmain()\n"},{"assistant_initiates":false,"asst_text":"Sure, how can I assist you today?","behavior":"degenerate_repetition","conversation_hash":"c838df061ab24a61123ed5ae555d2184","conversation_redacted":false,"conversation_toxic":false,"country":"Russia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-2024-08-06","n_chars":39,"n_turns_in_conversation":1,"n_words":8,"source_row_offset":28608,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:37 GMT","turn_id":"8b1b14d0b7ff2ba3d79fcc1b","turn_index":0,"user_text":"clear"},{"assistant_initiates":false,"asst_text":"\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0435\u043d\u0434\u0430: **\"Body Alchemist\"** (\u0422\u0435\u043b\u0435\u0441\u043d\u044b\u0439 \u0410\u043b\u0445\u0438\u043c\u0438\u043a)\n\n**\u0412\u043d\u0435\u0448\u043d\u043e\u0441\u0442\u044c:**\n\n\"Body Alchemist\" \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u0438\u043b\u0443\u044d\u0442\u043e\u043c, \u043d\u043e \u0435\u0433\u043e \u043e\u0431\u043b\u0438\u043a \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043d\u0435\u0447\u0442\u043e \u0441\u0432\u0435\u0440\u0445\u044a\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435. \u0415\u0433\u043e \u043a\u043e\u0436\u0430 \u043f\u0435\u0440\u0435\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u0430\u043b\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0431\u043b\u0435\u0441\u043a\u043e\u043c, \u0441\u043b\u043e\u0432\u043d\u043e \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c \u0436\u0438\u0434\u043a\u043e\u0439 \u0440\u0442\u0443\u0442\u0438, \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043c\u0435\u043d\u044f\u044e\u0449\u0430\u044f \u0444\u043e\u0440\u043c\u0443. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u0435\u0433\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0443\u0437\u043e\u0440\u0430\u043c\u0438 \u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0442 \u0442\u0430\u0442\u0443\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u0441\u0442\u0438\u043b\u0435 \u0430\u043b\u0445\u0438\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.\n\n\u0413\u043e\u043b\u043e\u0432\u0430 \u0441\u0442\u0435\u043d\u0434\u0430 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u0433\u043b\u0430\u0434\u043a\u0438\u0439 \u0448\u043b\u0435\u043c \u0431\u0435\u0437 \u0447\u0451\u0442\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043b\u0438\u0446\u043e \u0438 \u0447\u0435\u0440\u0435\u043f, \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u0433\u043b\u0430\u0437 - \u0434\u0432\u0435 \u0432\u044b\u0442\u044f\u043d\u0443\u0442\u044b\u0435, \u0441\u0438\u044f\u044e\u0449\u0438\u0435 \u0449\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0446\u0432\u0435\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439. \u041a\u043e\u0433\u0434\u0430 \u0441\u0442\u0435\u043d\u0434 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u0442 \u0441\u0432\u043e\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u043f\u043e \u0435\u0433\u043e \u0442\u0435\u043b\u0443 \u043f\u0440\u043e\u0431\u0435\u0433\u0430\u044e\u0442 \u044d\u043b\u0435\u043a\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0430\u0437\u0440\u044f\u0434\u044b.\n\n\u0412\u0434\u043e\u043b\u044c \u043f\u043e\u0437\u0432\u043e\u043d\u043e\u0447\u043d\u0438\u043a\u0430 \u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u043f\u043b\u0435\u0447\u044c\u044f\u0445 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0440\u044f\u0434\u043e\u0432\u044b\u0435 \"\u0430\u043b\u0445\u0438\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043b\u0430\u0441\u0442\u0438\u043d\u044b\" - \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u0444\u043e\u0440\u043c\u0443 \u0438 \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c\u0441\u044f \u0438\u0437 \u0442\u0435\u043b\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u042d\u0442\u0438 \u043f\u043b\u0430\u0441\u0442\u0438\u043d\u044b \u043f\u043e\u043a\u0440\u044b\u0442\u044b \u0433\u0440\u0430\u0432\u0438\u0440\u043e\u0432\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0441\u0432\u0435\u0442\u044f\u0442\u0441\u044f \u043c\u044f\u0433\u043a\u0438\u043c \u0441\u0432\u0435\u0442\u043e\u043c.\n\n**\u0421\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438:**\n\n1. **\u0422\u0440\u0430\u043d\u0441\u043c\u0443\u0442\u0430\u0446\u0438\u044f \u0437\u0434\u043e\u0440\u043e\u0432\u044c\u044f:**\n   \"Body Alchemist\" \u043c\u043e\u0436\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0436\u0438\u0432\u044b\u0445 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043c\u043e\u0432, \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0438\u0432\u0430\u044f \u0431\u043e\u043b\u044c \u0438 \u0440\u0430\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0442\u0435\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0442\u0440\u0430\u0432\u043c\u0443 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435, \u0441\u043d\u0438\u0436\u0430\u044f \u0432\u0440\u0435\u0434\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442 \u043d\u0430 \u0432\u0430\u0436\u043d\u044b\u0435 \u043e\u0440\u0433\u0430\u043d\u044b \u0438\u043b\u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f.\n\n2. **\u0410\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u0430\u044f \u043c\u0443\u0441\u043a\u0443\u043b\u0430\u0442\u0443\u0440\u0430:**\n   \u0421\u0442\u0435\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0430\u0442\u044c \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u0441\u0438\u043b\u0438\u0432\u0430\u0442\u044c \u043c\u044b\u0448\u0446\u044b, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u0438\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043f\u043e\u0434\u0432\u0438\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0443\u0441\u0442\u0430\u0432\u043e\u0432, \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u044f \u0442\u0435\u043b\u043e \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u0431\u043e\u0435\u0432\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f. \u042d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u0440\u0430\u0442\u043a\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0435\u0448\u0430\u044e\u0449\u0438\u043c\u0438 \u0432 \u0431\u043e\u044e.\n\n3. **\u0424\u043e\u0440\u043c\u043e\u0432\u043a\u0430 \u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0435 \u0442\u043a\u0430\u043d\u0435\u0439:**\n   \"Body Alchemist\" \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0442\u043a\u0430\u043d\u0438 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432 \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u0438\u043c \u0442\u0435\u043b\u0430\u043c, \u0438\u043b\u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0442\u044c \u0444\u0443\u0437\u0438\u044e \u0441 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0441\u0440\u0435\u0434\u0430\u043c\u0438 \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u044b\u0442\u0438\u044f \u0438\u043b\u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0439 \u0430\u0442\u0430\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \"\u0441\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f\" \u0441 \u0437\u0435\u043c\u043b\u0451\u0439, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0438\u043b\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u0441\u0432\u043e\u0435\u0439 \u0440\u0443\u043a\u0438 \u043e\u0441\u0442\u0440\u043e\u0435 \u043b\u0435\u0437\u0432\u0438\u0435 \u0438\u0437 \u043e\u0431\u043b\u043e\u043c\u043a\u0430 \u043c\u0435\u0442\u0430\u043b\u043b\u0430.\n\n4. **\u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u044f \u0441\u0435\u043d\u0441\u043e\u0440\u043d\u044b\u043c\u0438 \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f\u043c\u0438:**\n   \u0421\u0442\u0435\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u043e\u0437\u0433\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043b\u0435\u043f\u043e\u0442\u0443 \u0438\u043b\u0438 \u043e\u043d\u0435\u043c\u0435\u043d\u0438\u0435 \u0432\u0440\u0430\u0436\u0435\u0441\u043a\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0442\u0435\u043b\u0430, \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043b\u043e\u0436\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0437\u044b.\n\n5. **\u0410\u043b\u0445\u0438\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435:**\n   \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u0432\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0439 \u0442\u0435\u043b\u043e \u0441\u0442\u0435\u043d\u0434\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e, \u0432\u0442\u044f\u0433\u0438\u0432\u0430\u044f \u0432 \u0441\u0435\u0431\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044f \u0438\u0445 \u0432 \u0441\u0432\u043e\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0438 \u043e\u0431\u044a\u0435\u043c\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442\u044c \u043a\u0430\u043a \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0437\u0430\u0449\u0438\u0442\u044b, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0440\u0435\u043c\u043e\u043d\u0442\u0430 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430.\n\n\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \"Body Alchemist\" \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0440\u0435\u0437\u0432\u044b\u0447\u0430\u0439\u043d\u043e \u0433\u0438\u0431\u043a\u0438\u043c \u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0441\u0442\u0435\u043d\u0434\u043e\u043c, \u0441 \u0448\u0438\u0440\u043e\u043a\u0438\u043c \u0441\u043f\u0435\u043a\u0442\u0440\u043e\u043c \u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438 \u043b\u0435\u0447\u0435\u0431\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442 \u0435\u0433\u043e \u0441\u0438\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u044e\u0437\u043d\u0438\u043a\u043e\u043c \u0432 \u0431\u043e\u0435\u0432\u044b\u0445 \u0438 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445.","behavior":"degenerate_repetition","conversation_hash":"8cdc83669b080421f36701fda5207189","conversation_redacted":false,"conversation_toxic":false,"country":"Brazil","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Russian","model":"gpt-4o-2024-08-06","n_chars":2873,"n_turns_in_conversation":1,"n_words":362,"source_row_offset":28609,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:39 GMT","turn_id":"29259be1c01911119e5d0976","turn_index":0,"user_text":"\u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0439 \u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0448\u0438 \u0432\u043d\u0435\u0448\u043d\u043e\u0441\u0442\u044c \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u0435\u043d\u0434\u0430, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0441 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0435\u0439 \u0442\u0435\u043b\u043e\u043c"},{"assistant_initiates":false,"asst_text":"Since Ted Nugent has always been a vocal supporter of Donald Trump, his admiration for the former president is palpable. Nugent emphatically said, \"Donald Trump's message sings to Americans because he doesn't play political correct brain dead games.\" This statement showcases his disdain for what he perceives as overly sanitized political discourse and highlights why Trump\u2019s message resonates with him. Trump\u2019s straightforward and often unapologetic style aligns with Nugent\u2019s own approach to politics and life, known for his outspoken manner and blunt opinions.\n\nMoreover, Ted Nugent's support isn't limited to verbal endorsements but extends to tangible avenues, such as merchandise on his website. Among available items is a hat emblazoned with the NSFW slogan urging to \"Reelect the mother bleep.\" This product epitomizes Nugent's unfiltered and provocative style, mirroring the sort of rhetoric he admires in Trump.\n\nFor Nugent, backing Trump represents a rejection of established political correctness and a call for what he views as genuine, honest communication from leaders. It's clear why Nugent stands firm in his backing of Trump until the very end, seeing him as a kindred spirit who defies conventional political norms. Reply finished.","behavior":"degenerate_repetition","conversation_hash":"25208211721a697e95ad46e4d43dcaac","conversation_redacted":false,"conversation_toxic":false,"country":"Norway","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-2024-08-06","n_chars":3682,"n_turns_in_conversation":1,"n_words":553,"source_row_offset":28610,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:34:57 GMT","turn_id":"94418e317b7c561c0838a420","turn_index":0,"user_text":"Create a long detailed text about actor Ted Nugent with the following summary. The title of the video is\"Stars Who Are Supporting Trump Till The End\". Stick to the information i give you and dont create new information. Focus only on the Subject name and there following Summary. Subject Name: [Ted Nugent] Summary: [Ted Nugent has always supported Trump, stating 'Donald Trump's message sings to Americans because he doesn't play political correct brain dead games.' He offers a hat on his website with the NSFW slogan 'Reelect the mother bleep.']\n\n            Instructions:{ Please write an interesting script with the given context without adding any introductory or concluding remarks. \n            In case you find some more information about this topic then use all information you have to create a large text about this topic.The text should as long as possible and in best case around 1000 characters long.\n            Ensure that there are no emojis, text within brackets, parentheses, or similar symbols in the response.\n            Provide a single coherent response without rephrasing or repeating titles or headings. Avoid enumerations or bullet points. \n            The text is intended for older adults; use simple vocabulary appropriate for a middle school reading level. Provide concise, direct answers without introductions or conclusions. \n            Use transition words at the beginning of your reply instead of the subject name and leave the end open without a concluding sentence. \n            It is very important to provide only the final output without any additional comments or remarks. \n            Please provide the text directly without any labels such as \"Conclusion:\", \"Introduction:\", or \"Transition:\". Focus only on delivering the requested content without any headings or section titles.\n            Please respond to my question, and always conclude your reply with the words \"Reply finished\" to indicate that your response is complete. Make sure the reply is fully contained before these words and is not cut off prematurely. Thank you.}\n         Please respond to my question, and always conclude your reply with the words 'Reply finished' to indicate that your response is complete. Ensure that the text is fully formed without any placeholders such as '[Conclusion]' or '[Placeholder]'. Make sure the reply is fully contained before these words and is not cut off prematurely. Thank you."},{"assistant_initiates":false,"asst_text":"```javascript\n// ==UserScript==\n// @name         \uc885\ud569 \uc6f9 \ud06c\ub864\ub7ec 7.9.5\n// @namespace    http://tampermonkey.net/\n// @version      7.9.5\n// @description  \uace0\uae09 \uae30\ub2a5\uc744 \uac16\ucd98 \uc6f9 \ud06c\ub864\ub7ec\ub85c \uac80\uc0c9 \uacb0\uacfc\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \uc218\uc9d1\ud558\uace0 \ud45c\uc2dc (\ub3d9\uc2dc \ud06c\ub864\ub9c1, \ubc88\uc5ed \uae30\ub2a5, UI \uac1c\uc120 \ub4f1)\n// @author       YourName\n// @match        *://www.google.com/search*\n// @match        *://www.bing.com/search*\n// @match        *://search.daum.net/search*\n// @match        *://search.naver.com/search*\n// @match        *://search.yahoo.com/search*\n// @match        *://duckduckgo.com/*\n// @match        *://www.ecosia.org/search*\n// @match        *://*.onion/*\n// @grant        GM_xmlhttpRequest\n// @grant        GM_addStyle\n// @grant        GM_setValue\n// @grant        GM_getValue\n// @grant        GM_notification\n// @connect      *\n// @require      https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js\n// @require      https://cdn.jsdelivr.net/npm/chart.js\n// @require      https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js\n// @require      https://cdnjs.cloudflare.com/ajax/libs/i18next/21.6.15/i18next.min.js\n// ==/UserScript==\n\n(function() {\n    'use strict';\n\n    // CSS \uc2a4\ud0c0\uc77c \ucd94\uac00 (UI \ub300\ud3ed \uac1c\uc120)\n    GM_addStyle(`\n        /* \ucee8\ud14c\uc774\ub108 \uc2a4\ud0c0\uc77c */\n        #crawler-container {\n            position: fixed;\n            top: 20px;\n            right: 20px;\n            background-color: #2c3e50;\n            border: 2px solid #1abc9c;\n            padding: 20px;\n            z-index: 10000;\n            width: 800px;\n            max-height: 85vh;\n            overflow: hidden;\n            box-shadow: 0 8px 30px rgba(0,0,0,0.5);\n            border-radius: 12px;\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            color: #ecf0f1;\n            display: flex;\n            flex-direction: column;\n            transition: all 0.3s ease;\n        }\n\n        /* \ud5e4\ub354 \uc2a4\ud0c0\uc77c */\n        #crawler-container header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 15px;\n        }\n\n        #crawler-container .title {\n            font-size: 20px;\n            font-weight: bold;\n        }\n\n        #crawler-container .close-btn {\n            cursor: pointer;\n            font-size: 24px;\n            color: #e74c3c;\n            transition: color 0.3s;\n        }\n\n        #crawler-container .close-btn:hover {\n            color: #c0392b;\n        }\n\n        /* \ud0ed \uc2a4\ud0c0\uc77c */\n        #crawler-container .tabs {\n            display: flex;\n            border-bottom: 2px solid #1abc9c;\n            margin-bottom: 15px;\n            overflow-x: auto;\n        }\n\n        #crawler-container .tab {\n            flex: 1;\n            text-align: center;\n            padding: 10px 0;\n            cursor: pointer;\n            background-color: #34495e;\n            border-right: 1px solid #1abc9c;\n            transition: background-color 0.3s, color 0.3s;\n            white-space: nowrap;\n        }\n\n        #crawler-container .tab:last-child {\n            border-right: none;\n        }\n\n        #crawler-container .tab.active {\n            background-color: #1abc9c;\n            color: #2c3e50;\n            font-weight: bold;\n        }\n\n        /* \ud0ed \ucf58\ud150\uce20 \uc2a4\ud0c0\uc77c */\n        #crawler-container .tab-content {\n            display: none;\n            flex: 1;\n            overflow-y: auto;\n        }\n\n        #crawler-container .tab-content.active {\n            display: block;\n        }\n\n        /* \ubc84\ud2bc \uc2a4\ud0c0\uc77c */\n        #crawler-container .controls button {\n            background-color: #1abc9c;\n            border: none;\n            color: #2c3e50;\n            padding: 10px 16px;\n            margin: 6px 3px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s, transform 0.2s;\n            font-size: 14px;\n            display: flex;\n            align-items: center;\n        }\n\n        #crawler-container .controls button:hover {\n            background-color: #16a085;\n            transform: translateY(-2px);\n        }\n\n        #crawler-container .controls button i {\n            margin-right: 6px;\n        }\n\n        /* \uccb4\ud06c\ubc15\uc2a4 \ubc0f \ub77c\ubca8 \uc2a4\ud0c0\uc77c */\n        #crawler-container .options label,\n        #crawler-container .filters label,\n        #crawler-container .exclude-domains label,\n        #crawler-container .advanced-options label {\n            display: flex;\n            align-items: center;\n            margin: 10px 0;\n            font-size: 14px;\n        }\n\n        #crawler-container .options input[type=\"checkbox\"] {\n            margin-right: 8px;\n            transform: scale(1.2);\n        }\n\n        /* \uc2a4\uc704\uce58 \uc2a4\ud0c0\uc77c */\n        .switch {\n            position: relative;\n            display: inline-block;\n            width: 50px;\n            height: 24px;\n            margin-left: 10px;\n        }\n\n        .switch input {\n            opacity: 0;\n            width: 0;\n            height: 0;\n        }\n\n        .switch .slider {\n            position: absolute;\n            cursor: pointer;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background-color: #ccc;\n            transition: 0.4s;\n            border-radius: 24px;\n        }\n\n        .switch .slider:before {\n            position: absolute;\n            content: \"\";\n            height: 18px;\n            width: 18px;\n            left: 3px;\n            bottom: 3px;\n            background-color: white;\n            transition: 0.4s;\n            border-radius: 50%;\n        }\n\n        .switch input:checked + .slider {\n            background-color: #1abc9c;\n        }\n\n        .switch input:checked + .slider:before {\n            transform: translateX(26px);\n        }\n\n        /* \uc785\ub825 \ud544\ub4dc \uc2a4\ud0c0\uc77c */\n        #crawler-container input[type=\"text\"],\n        #crawler-container input[type=\"number\"] {\n            width: 100%;\n            padding: 8px;\n            margin: 6px 0;\n            border: 1px solid #bdc3c7;\n            border-radius: 4px;\n            font-size: 14px;\n        }\n\n        /* \ud14c\uc774\ube14 \uc2a4\ud0c0\uc77c */\n        #resultsTable {\n            width: 100%;\n            border-collapse: collapse;\n            margin-top: 15px;\n        }\n\n        #resultsTable th, #resultsTable td {\n            border: 1px solid #95a5a6;\n            padding: 10px;\n            text-align: left;\n            font-size: 13px;\n        }\n\n        #resultsTable th {\n            background-color: #1abc9c;\n            color: #2c3e50;\n        }\n\n        #resultsTable tbody tr:nth-child(even) {\n            background-color: #34495e;\n        }\n\n        /* \ubc18\uc751\ud615 \ub514\uc790\uc778 */\n        @media (max-width: 900px) {\n            #crawler-container {\n                width: 90%;\n                right: 5%;\n                padding: 15px;\n            }\n\n            #crawler-container .controls button {\n                padding: 8px 12px;\n                font-size: 13px;\n            }\n\n            #crawler-container .title {\n                font-size: 18px;\n            }\n        }\n\n        /* Papago iframe \uc2a4\ud0c0\uc77c */\n        #papagoIframe {\n            width: 100%;\n            height: 100%;\n            border: none;\n        }\n\n        /* \ud31d\uc5c5 \uc2a4\ud0c0\uc77c */\n        .search-engines-popup, .manage-darkweb-popup {\n            position: absolute;\n            background-color: #2c3e50;\n            border: 1px solid #1abc9c;\n            padding: 15px;\n            border-radius: 8px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n            max-height: 350px;\n            overflow-y: auto;\n            z-index: 10001;\n        }\n\n        .search-engines-popup button, .manage-darkweb-popup button {\n            width: 100%;\n            text-align: left;\n            margin: 6px 0;\n            background-color: #34495e;\n            color: #ecf0f1;\n            border: none;\n            padding: 10px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 14px;\n        }\n\n        .search-engines-popup button:hover, .manage-darkweb-popup button:hover {\n            background-color: #1abc9c;\n            color: #2c3e50;\n        }\n\n        /* \ub85c\uadf8 \uc2a4\ud0c0\uc77c */\n        #log {\n            background-color: #34495e;\n            padding: 10px;\n            border-radius: 5px;\n            max-height: 200px;\n            overflow-y: auto;\n            font-size: 13px;\n            line-height: 1.4;\n        }\n\n        /* \ucc28\ud2b8 \ucee8\ud14c\uc774\ub108 */\n        .chart-container {\n            margin-top: 15px;\n            height: 250px;\n        }\n\n        /* HTML \ub514\uc2a4\ud50c\ub808\uc774 \uc2a4\ud0c0\uc77c */\n        .html-display iframe {\n            width: 100%;\n            height: 500px;\n            border: none;\n            border-radius: 5px;\n        }\n\n        /* Papago \ub514\uc2a4\ud50c\ub808\uc774 \uc2a4\ud0c0\uc77c */\n        .papago-display {\n            width: 100%;\n            height: 500px;\n            position: relative;\n        }\n\n        /* \ub2e4\ud06c\uc6f9 \uc5d4\uc9c4 \ubaa9\ub85d \uc2a4\ud0c0\uc77c */\n        #darkwebEnginesList li {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 12px;\n        }\n\n        #darkwebEnginesList li span {\n            flex: 1;\n            margin-right: 10px;\n            word-break: break-all;\n        }\n\n        #darkwebEnginesList li button {\n            background-color: #e74c3c;\n            border: none;\n            color: #fff;\n            padding: 6px 10px;\n            border-radius: 4px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n        }\n\n        #darkwebEnginesList li button:hover {\n            background-color: #c0392b;\n        }\n\n        /* \uc608\uc678 \ub3c4\uba54\uc778 \ub9ac\uc2a4\ud2b8 \uc2a4\ud0c0\uc77c */\n        .exclude-domains ul {\n            list-style: none;\n            padding: 0;\n            margin-top: 10px;\n        }\n\n        .exclude-domains ul li {\n            background-color: #34495e;\n            padding: 6px 10px;\n            border-radius: 4px;\n            margin-bottom: 6px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n\n        .exclude-domains ul li button {\n            background-color: #e74c3c;\n            border: none;\n            color: #fff;\n            padding: 4px 8px;\n            border-radius: 3px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 12px;\n        }\n\n        .exclude-domains ul li button:hover {\n            background-color: #c0392b;\n        }\n\n        /* Search Engines Direct UI */\n        #search-engines-direct {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 10px;\n            margin-top: 15px;\n        }\n\n        #search-engines-direct button {\n            flex: 1 1 45%;\n            background-color: #1abc9c;\n            border: none;\n            color: #2c3e50;\n            padding: 8px 12px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 14px;\n        }\n\n        #search-engines-direct button:hover {\n            background-color: #16a085;\n        }\n\n        /* Preview Popup */\n        .preview-popup {\n            position: absolute;\n            background-color: #2c3e50;\n            border: 1px solid #1abc9c;\n            padding: 10px;\n            border-radius: 6px;\n            box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n            width: 300px;\n            height: 150px;\n            z-index: 10002;\n            display: none;\n        }\n    `);\n\n    // UI \uc0dd\uc131 (\ub300\ud3ed \uac1c\uc120\ub41c \ub514\uc790\uc778)\n    const container = document.createElement('div');\n    container.id = 'crawler-container';\n    container.innerHTML = `\n        <header>\n            <span class=\"title\">\ud83d\udd25 \uc6f9 \ud06c\ub864\ub7ec 7.9.5</span>\n            <span class=\"close-btn\" title=\"\ub2eb\uae30\">&times;</span>\n        </header>\n        <div class=\"tabs\">\n            <div class=\"tab active\" data-tab=\"settings\">\uc124\uc815</div>\n            <div class=\"tab\" data-tab=\"results\">\uacb0\uacfc</div>\n            <div class=\"tab\" data-tab=\"logs\">\ub85c\uadf8</div>\n            <div class=\"tab\" data-tab=\"site-filters\">\uc0ac\uc774\ud2b8 \ud544\ud130</div>\n            <div class=\"tab\" data-tab=\"darkweb\">\ub2e4\ud06c\uc6f9</div>\n            <div class=\"tab\" data-tab=\"html-display\">HTML</div>\n            <div class=\"tab\" data-tab=\"papago\">Papago</div>\n            <div class=\"tab\" data-tab=\"search-engines\">\uac80\uc0c9 \uc5d4\uc9c4</div>\n        </div>\n        <div class=\"tab-content active\" id=\"settings\">\n            <!-- \uc81c\uc5b4 \ubc84\ud2bc -->\n            <div class=\"controls\">\n                <button id=\"startBtn\" title=\"\ud06c\ub864\ub9c1 \uc2dc\uc791\"><i>\u25b6\ufe0f</i> \uc2dc\uc791</button>\n                <button id=\"pauseBtn\" class=\"pause-btn\" title=\"\ud06c\ub864\ub9c1 \uc77c\uc2dc\uc815\uc9c0/\uc7ac\uac1c\"><i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0</button>\n                <button id=\"stopBtn\" title=\"\ud06c\ub864\ub9c1 \uc911\uc9c0\"><i>\u23f9\ufe0f</i> \uc911\uc9c0</button>\n                <button id=\"resetBtn\" title=\"\ud06c\ub864\ub9c1 \ucd08\uae30\ud654\"><i>\ud83d\udd04</i> \ucd08\uae30\ud654</button>\n                <button id=\"exportBtn\" class=\"export-btn\" title=\"\uacb0\uacfc \ub0b4\ubcf4\ub0b4\uae30\"><i>\ud83d\udcbe</i> \ub0b4\ubcf4\ub0b4\uae30</button>\n                <button id=\"searchEnginesBtn\" class=\"search-engines-btn\" title=\"\uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30\"><i>\ud83d\udd0d</i> \uac80\uc0c9 \uc5d4\uc9c4</button>\n            </div>\n            <!-- \uc635\uc158 \uc139\uc158 -->\n            <div class=\"options\">\n                <label><input type=\"checkbox\" id=\"toggleHTML\" checked> HTML \uac00\uc838\uc624\uae30</label>\n                <label><input type=\"checkbox\" id=\"toggleImages\" checked> \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30</label>\n                <label><input type=\"checkbox\" id=\"toggleAds\" checked> \uad11\uace0 \uc81c\uc678</label>\n                <label>\uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"strictSiteFilter\">\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n                <label>\ud544\ud130\ub9c1 \uae30\ub2a5 \ud65c\uc131\ud654\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"filteringToggle\" checked>\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n            </div>\n            <!-- \ud544\ud130 \uc139\uc158 -->\n            <div class=\"filters\">\n                <label for=\"filterInput\">\ud544\ud130 \ub2e8\uc5b4 (\uc815\uaddc\uc2dd, \uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"filterInput\" placeholder=\"\uc608: \uae30\ubd80, \uad11\uace0, /promo/i\">\n            </div>\n            <!-- \ub3c4\uba54\uc778 \uc81c\uc678 \uc139\uc158 -->\n            <div class=\"exclude-domains\">\n                <label for=\"excludeDomainsInput\">\uc81c\uc678\ud560 \ub3c4\uba54\uc778 (\uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"excludeDomainsInput\" placeholder=\"\uc608: facebook.com, youtube.com\">\n                <ul id=\"excludeDomainsList\"></ul>\n            </div>\n            <!-- \uace0\uae09 \uc635\uc158 \uc139\uc158 -->\n            <div class=\"advanced-options\">\n                <label for=\"duplicateThreshold\">\uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218:</label>\n                <input type=\"number\" id=\"duplicateThreshold\" value=\"5\" min=\"1\" style=\"width: 80px;\">\n            </div>\n            <!-- \uc81c\uc5b4 \uc635\uc158 \uc139\uc158 -->\n            <div class=\"controls\">\n                <label for=\"retryAttempts\">\uc7ac\uc2dc\ub3c4 \ud69f\uc218:</label>\n                <input type=\"number\" id=\"retryAttempts\" value=\"10\" min=\"1\" style=\"width: 80px;\">\n                <label for=\"retryInterval\">\uc7ac\uc2dc\ub3c4 \uac04\uaca9 (ms):</label>\n                <input type=\"number\" id=\"retryInterval\" value=\"100\" min=\"100\" style=\"width: 80px;\">\n            </div>\n            <!-- \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ud1a0\uae00 -->\n            <div class=\"controls\">\n                <label>\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"darkwebToggle\" checked>\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n            </div>\n            <!-- \uc9c4\ud589\ub960 \ud45c\uc2dc \uc139\uc158 -->\n            <div class=\"progress-section\">\n                <progress id=\"progressBar\" value=\"0\" max=\"100\" style=\"width: 100%; height: 20px;\"></progress>\n                <span id=\"progressText\">\ud398\uc774\uc9c0 0</span>\n            </div>\n            <!-- \uc0c1\ud0dc \uc815\ubcf4 \uc139\uc158 -->\n            <div class=\"status\">\n                \ud604\uc7ac \ud398\uc774\uc9c0: <span id=\"currentPage\">0</span>\n                <br>\n                \ubc29\ubb38\ub41c \uc0ac\uc774\ud2b8: <span id=\"visitedCount\">0</span>\n                <br>\n                \uacbd\uacfc \uc2dc\uac04: <span id=\"elapsedTime\">00:00:00</span>\n                <br>\n                \uc608\uc0c1 \ub0a8\uc740 \uc2dc\uac04: <span id=\"remainingTime\">00:00:00</span>\n            </div>\n            <!-- \ucc28\ud2b8 \uc139\uc158 -->\n            <div class=\"chart-container\">\n                <canvas id=\"crawlChart\"></canvas>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"results\">\n            <div style=\"margin-top:15px; overflow: auto;\">\n                <table id=\"resultsTable\">\n                    <thead>\n                        <tr>\n                            <th>\uc0ac\uc774\ud2b8 \uc774\ub984</th>\n                            <th>\uc8fc\uc18c</th>\n                            <th>\uc124\uba85</th>\n                            <th>\uc774\ubbf8\uc9c0</th>\n                            <th>HTML \ub9c1\ud06c</th>\n                            <th>\ud398\uc774\uc9c0 \ub85c\ub529 \uc2dc\uac04 (ms)</th>\n                        </tr>\n                    </thead>\n                    <tbody id=\"resultsBody\">\n                    </tbody>\n                </table>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"logs\">\n            <div class=\"log\" id=\"log\">\n                <strong>\ub85c\uadf8:</strong><br>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"site-filters\">\n            <div class=\"site-filters\">\n                <label for=\"siteFilterInput\">\uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 (\uc815\uaddc\uc2dd, \uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"siteFilterInput\" placeholder=\"\uc608: .*example\\\\.com.*, /^https?:\\\\/\\\\/.*\\\\.example\\\\.org$/\">\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"darkweb\">\n            <div class=\"darkweb-search\">\n                <label>\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00/\uad00\ub9ac</label>\n                <button class=\"add-darkweb-engine-btn\" title=\"\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00\"><i>\u2795</i> \ucd94\uac00</button>\n                <ul id=\"darkwebEnginesList\">\n                    <!-- \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ubaa9\ub85d -->\n                </ul>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"html-display\">\n            <div class=\"html-display\"></div>\n        </div>\n        <div class=\"tab-content\" id=\"papago\">\n            <div class=\"papago-display\">\n                <iframe id=\"papagoIframe\" src=\"https://papago.naver.com/\"></iframe>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"search-engines\">\n            <div class=\"search-engines-direct\" id=\"search-engines-direct\">\n                <!-- \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30 \ubc84\ud2bc \ucd94\uac00 -->\n            </div>\n        </div>\n    `;\n    document.body.appendChild(container);\n\n    // \ub4dc\ub798\uadf8 \uac00\ub2a5\ud558\uac8c \uc124\uc815\n    (function makeDraggable(elmnt) {\n        const header = elmnt.querySelector('header');\n        const closeBtn = elmnt.querySelector('.close-btn');\n        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;\n        header.onmousedown = dragMouseDown;\n\n        closeBtn.onclick = () => {\n            elmnt.style.display = 'none';\n        }\n\n        function dragMouseDown(e) {\n            e = e || window.event;\n            e.preventDefault();\n            pos3 = e.clientX;\n            pos4 = e.clientY;\n            document.onmouseup = closeDragElement;\n            document.onmousemove = elementDrag;\n        }\n\n        function elementDrag(e) {\n            e = e || window.event;\n            e.preventDefault();\n            pos1 = pos3 - e.clientX;\n            pos2 = pos4 - e.clientY;\n            pos3 = e.clientX;\n            pos4 = e.clientY;\n            elmnt.style.top = (elmnt.offsetTop - pos2) + \"px\";\n            elmnt.style.left = (elmnt.offsetLeft - pos1) + \"px\";\n        }\n\n        function closeDragElement() {\n            document.onmouseup = null;\n            document.onmousemove = null;\n        }\n    })(container);\n\n    // \ud0ed \uae30\ub2a5 \uad6c\ud604\n    (function setupTabs() {\n        const tabs = container.querySelectorAll('.tab');\n        const tabContents = container.querySelectorAll('.tab-content');\n\n        tabs.forEach(tab => {\n            tab.addEventListener('click', () => {\n                tabs.forEach(t => t.classList.remove('active'));\n                tab.classList.add('active');\n\n                const target = tab.getAttribute('data-tab');\n                tabContents.forEach(content => {\n                    if(content.id === target){\n                        content.classList.add('active');\n                    } else {\n                        content.classList.remove('active');\n                    }\n                });\n            });\n        });\n    })();\n\n    // \ubcc0\uc218 \ucd08\uae30\ud654\n    let isRunning = false;\n    let isPaused = false;\n    let currentPage = 1;\n    let results = [];\n    let searchQuery = '';\n    let searchEngine = '';\n    let visitedLinks = new Map(); // \ub3c4\uba54\uc778\ubcc4 \ubc29\ubb38 \ud69f\uc218 \ucd94\uc801\n    let logMessages = [];\n    let filterPatterns = [];\n    let excludeDomains = [];\n    let siteFilterPatterns = [];\n    let duplicateThreshold = 5; // \uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218\n    let retryAttempts = 10; // \uc7ac\uc2dc\ub3c4 \ud69f\uc218\n    let retryInterval = 100; // \uc7ac\uc2dc\ub3c4 \uac04\uaca9 100ms\uc73c\ub85c \uc124\uc815\n    let startTime = null;\n    let elapsedInterval = null;\n    let crawlChart = null;\n    let crawlData = {\n        labels: [],  // \ub3c4\uba54\uc778 \uc774\ub984\n        datasets: [{\n            label: '\ubc29\ubb38 \ud69f\uc218',\n            data: [],\n            backgroundColor: 'rgba(46, 204, 113, 0.6)',\n            borderColor: 'rgba(46, 204, 113, 1)',\n            borderWidth: 1\n        }]\n    };\n    let filteringEnabled = true; // \ud544\ud130\ub9c1 \ud65c\uc131\ud654 \uc5ec\ubd80\n    let concurrentRequests = 40; // \ub3d9\uc2dc \uc694\uccad \uc218 40\uc73c\ub85c \uc124\uc815\n    let currentRequests = 0; // \ud604\uc7ac \uc694\uccad \uc218\n    let requestQueue = []; // \uc694\uccad \ub300\uae30\uc5f4\n    let translateLanguage = 'en'; // \uae30\ubcf8 \ubc88\uc5ed \uc5b8\uc5b4\n    let darkwebEnabled = true; // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9 \uc5ec\ubd80\n\n    // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ubaa9\ub85d (\uae30\ubcf8 \uc5d4\uc9c4 \ucd94\uac00 \ubc0f \ud655\uc7a5)\n    const defaultDarkwebEngines = [\n        { name: 'Torch', url: 'http://xmh57jrzrnw6insl.onion/' },\n        { name: 'Ahmia', url: 'http://msydqstlz2kzerdg.onion/' },\n        { name: 'Haystak', url: 'http://haystakvxad7wbk5.onion/' },\n        { name: 'Not Evil', url: 'http://hss3uro2hsxfogfq.onion/' },\n        { name: 'Phobos', url: 'http://phobos6uj4abm4pf.onion/' },\n        { name: 'DarkSearch', url: 'http://darksearch3w3nrc.onion/' },\n        { name: 'IntelligenceX', url: 'http://intelligencexmh5v.onion/' },\n        { name: 'Silk Road 3.1', url: 'http://silkroad31lo5ya.onion/' },\n        { name: 'Fresh Onions', url: 'http://rx7hmtf7k7xk6ked.onion/' },\n        { name: 'Dark Web Link', url: 'http://darkweblink5wqk.onion/' },\n        { name: 'Tor Tracker', url: 'http://tortracker5ujzra.onion/' },\n        { name: 'Deep Web Search', url: 'http://deepwebsearch6b6x.onion/' },\n        { name: 'Onion Monitor', url: 'http://onionmonitor3c7v.onion/' },\n        { name: 'Hidden Wiki', url: 'http://hiddenwiki5z35.onion/' },\n        { name: 'TorEX', url: 'http://torexk3wd2buz.onion/' },\n        { name: 'BlackBook', url: 'http://blackbook51uv.onion/' },\n        { name: 'Taboo Search', url: 'http://taboosearch37b.onion/' },\n        { name: 'The Pirate Bay (onion)', url: 'http://uj3wazyk5u4hnvtk.onion/' },\n        // \ub354 \ub9ce\uc740 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc744 \ucd94\uac00\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n    ];\n\n    // \ubc84\ud2bc \ubc0f \uc694\uc18c \uac00\uc838\uc624\uae30\n    const startBtn = document.getElementById('startBtn');\n    const pauseBtn = document.getElementById('pauseBtn');\n    const stopBtn = document.getElementById('stopBtn');\n    const resetBtn = document.getElementById('resetBtn');\n    const exportBtn = document.getElementById('exportBtn');\n    const searchEnginesBtn = document.getElementById('searchEnginesBtn');\n    const progressBar = document.getElementById('progressBar');\n    const progressText = document.getElementById('progressText');\n    const resultsBody = document.getElementById('resultsBody');\n    const logContainer = document.getElementById('log');\n    const currentPageElem = document.getElementById('currentPage');\n    const toggleHTML = document.getElementById('toggleHTML');\n    const toggleImages = document.getElementById('toggleImages');\n    const toggleAds = document.getElementById('toggleAds');\n    const filterInput = document.getElementById('filterInput');\n    const excludeDomainsInput = document.getElementById('excludeDomainsInput');\n    const excludeDomainsList = document.getElementById('excludeDomainsList');\n    const siteFilterInput = document.getElementById('siteFilterInput');\n    const duplicateThresholdInput = document.getElementById('duplicateThreshold');\n    const retryAttemptsInput = document.getElementById('retryAttempts');\n    const retryIntervalInput = document.getElementById('retryInterval');\n    const strictSiteFilter = document.getElementById('strictSiteFilter');\n    const visitedCountElem = document.getElementById('visitedCount');\n    const elapsedTimeElem = document.getElementById('elapsedTime');\n    const remainingTimeElem = document.getElementById('remainingTime');\n    const crawlChartCtx = document.getElementById('crawlChart').getContext('2d');\n    const filteringToggle = document.getElementById('filteringToggle');\n    const darkwebEnginesList = document.getElementById('darkwebEnginesList');\n    const addDarkwebEngineBtn = container.querySelector('.add-darkweb-engine-btn');\n    const darkwebToggle = document.getElementById('darkwebToggle');\n    const papagoIframe = document.getElementById('papagoIframe');\n    const searchEnginesDirect = document.getElementById('search-engines-direct');\n\n    // \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n    startBtn.addEventListener('click', startCrawling);\n    pauseBtn.addEventListener('click', togglePause);\n    stopBtn.addEventListener('click', stopCrawling);\n    resetBtn.addEventListener('click', resetCrawling);\n    exportBtn.addEventListener('click', exportResults);\n    searchEnginesBtn.addEventListener('click', openSearchEngines);\n    filterInput.addEventListener('input', updateFilterPatterns);\n    excludeDomainsInput.addEventListener('keydown', function(e) {\n        if (e.key === 'Enter') {\n            addExcludeDomain();\n        }\n    });\n    addDarkwebEngineBtn.addEventListener('click', addDarkwebEngine);\n    siteFilterInput.addEventListener('input', updateSiteFilterPatterns);\n    duplicateThresholdInput.addEventListener('change', updateDuplicateThreshold);\n    retryAttemptsInput.addEventListener('change', updateRetryAttempts);\n    retryIntervalInput.addEventListener('change', updateRetryInterval);\n    strictSiteFilter.addEventListener('change', updateStrictSiteFilter);\n    filteringToggle.addEventListener('change', toggleFiltering);\n    darkwebToggle.addEventListener('change', toggleDarkweb);\n    papagoIframe.addEventListener('load', () => {\n        log('\ud83c\udf10 Papago \ubc88\uc5ed\uae30 \ub85c\ub4dc \uc644\ub8cc.');\n    });\n\n    // \ud398\uc774\uc9c0 \uc0c8\ub85c \uace0\uce68 \uc2dc \ud06c\ub864\ub9c1 \ucd08\uae30\ud654\n    window.addEventListener('beforeunload', () => {\n        resetCrawling();\n    });\n\n    // \ucd08\uae30\ud654 \ub85c\ub4dc\n    loadLogs();\n    loadCrawlData();\n    loadDarkwebEngines();\n    loadExcludeDomains();\n    loadSearchEnginesDirect();\n\n    // \ucc28\ud2b8 \ucd08\uae30\ud654\n    function initializeChart() {\n        crawlChart = new Chart(crawlChartCtx, {\n            type: 'bar',\n            data: crawlData,\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    y: { beginAtZero: true },\n                    x: { ticks: { autoSkip: false } }\n                },\n                plugins: {\n                    legend: {\n                        display: false\n                    },\n                    tooltip: {\n                        enabled: true\n                    }\n                }\n            }\n        });\n    }\n    initializeChart();\n\n    // \ub85c\uae45 \ud568\uc218\n    function log(message) {\n        const time = new Date().toLocaleTimeString();\n        const entry = `[${time}] ${message}`;\n        logMessages.push(entry);\n        logContainer.innerHTML += `${entry}<br>`;\n        logContainer.scrollTop = logContainer.scrollHeight;\n        // \uc800\uc7a5\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n    }\n\n    function loadLogs() {\n        const storedLogs = GM_getValue('crawlerLogs', []);\n        if (storedLogs.length > 0) {\n            logMessages = JSON.parse(storedLogs);\n            logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>` + logMessages.join('<br>');\n            logContainer.scrollTop = logContainer.scrollHeight;\n        }\n    }\n\n    function updateFilterPatterns() {\n        if (!filteringEnabled) {\n            filterPatterns = [];\n            log(`\ud83d\udee0 \ud544\ud130\ub9c1 \uae30\ub2a5 \ube44\ud65c\uc131\ud654\ub428.`);\n            return;\n        }\n        const input = filterInput.value.trim();\n        filterPatterns = input ? input.split(',').map(word => {\n            word = word.trim();\n            if (word.startsWith('/') && word.endsWith('/')) {\n                try {\n                    return new RegExp(word.slice(1, -1), 'i');\n                } catch (e) {\n                    log(`\u26a0\ufe0f \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc815\uaddc\uc2dd: ${word}`);\n                    return null;\n                }\n            } else {\n                return new RegExp(word, 'i');\n            }\n        }).filter(regex => regex !== null) : [];\n        log(`\ud83d\udee0 \ud544\ud130 \ud328\ud134 \uc5c5\ub370\uc774\ud2b8: [${filterPatterns.map(r => r.toString()).join(', ')}]`);\n    }\n\n    function updateExcludeDomains() {\n        // \uc774 \ud568\uc218\ub294 \uc81c\uc678 \ub3c4\uba54\uc778\uc774 \ucd94\uac00\ub420 \ub54c\ub9c8\ub2e4 \ud638\ucd9c\ub428\n        log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \uc5c5\ub370\uc774\ud2b8 \uc644\ub8cc.`);\n    }\n\n    function addExcludeDomain() {\n        const domain = excludeDomainsInput.value.trim().toLowerCase();\n        if (domain && !excludeDomains.includes(domain)) {\n            excludeDomains.push(domain);\n            renderExcludeDomains();\n            excludeDomainsInput.value = '';\n            log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \ucd94\uac00: ${domain}`);\n        }\n    }\n\n    function renderExcludeDomains() {\n        excludeDomainsList.innerHTML = '';\n        excludeDomains.forEach((domain, index) => {\n            const li = document.createElement('li');\n            li.innerHTML = `\n                <span>${escapeHTML(domain)}</span>\n                <button data-index=\"${index}\">\u2716\ufe0f</button>\n            `;\n            excludeDomainsList.appendChild(li);\n        });\n        // \uc0ad\uc81c \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        excludeDomainsList.querySelectorAll('button').forEach(btn => {\n            btn.addEventListener('click', () => {\n                const index = parseInt(btn.getAttribute('data-index'));\n                if (!isNaN(index)) {\n                    const removed = excludeDomains.splice(index, 1);\n                    renderExcludeDomains();\n                    log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \uc81c\uac70: ${removed}`);\n                }\n            });\n        });\n    }\n\n    function loadExcludeDomains() {\n        const storedDomains = GM_getValue('excludeDomains', []);\n        excludeDomains = storedDomains.length > 0 ? storedDomains : [];\n        renderExcludeDomains();\n    }\n\n    function updateSiteFilterPatterns() {\n        const input = siteFilterInput.value.trim();\n        siteFilterPatterns = input ? input.split(',').map(pattern => {\n            pattern = pattern.trim();\n            if (pattern.startsWith('/') && pattern.endsWith('/')) {\n                try {\n                    return new RegExp(pattern.slice(1, -1), 'i');\n                } catch (e) {\n                    log(`\u26a0\ufe0f \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc774\ud2b8 \ud544\ud130 \uc815\uaddc\uc2dd: ${pattern}`);\n                    return null;\n                }\n            } else {\n                return new RegExp(pattern, 'i');\n            }\n        }).filter(regex => regex !== null) : [];\n        log(`\ud83d\udee0 \uc0ac\uc774\ud2b8 \ud544\ud130 \ud328\ud134 \uc5c5\ub370\uc774\ud2b8: [${siteFilterPatterns.map(r => r.toString()).join(', ')}]`);\n    }\n\n    function updateDuplicateThreshold() {\n        const value = parseInt(duplicateThresholdInput.value);\n        duplicateThreshold = isNaN(value) || value < 1 ? 5 : value;\n        log(`\ud83d\udd04 \uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218 \uc124\uc815: ${duplicateThreshold}`);\n    }\n\n    function updateRetryAttempts() {\n        const value = parseInt(retryAttemptsInput.value);\n        retryAttempts = isNaN(value) || value < 1 ? 10 : value;\n        log(`\ud83d\udd04 \uc7ac\uc2dc\ub3c4 \ud69f\uc218 \uc124\uc815: ${retryAttempts}`);\n    }\n\n    function updateRetryInterval() {\n        const value = parseInt(retryIntervalInput.value);\n        retryInterval = isNaN(value) || value < 100 ? 100 : value; // \ucd5c\uc18c \uac12 100ms\uc73c\ub85c \uc124\uc815\n        log(`\ud83d\udd04 \uc7ac\uc2dc\ub3c4 \uac04\uaca9 \uc124\uc815: ${retryInterval}ms`);\n    }\n\n    function updateStrictSiteFilter() {\n        const isStrict = strictSiteFilter.checked;\n        log(`\ud83d\udd04 \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc124\uc815: ${isStrict ? 'ON' : 'OFF'}`);\n    }\n\n    function toggleFiltering() {\n        filteringEnabled = filteringToggle.checked;\n        if (filteringEnabled) {\n            log('\ud83d\udd04 \ud544\ud130\ub9c1 \uae30\ub2a5 \ud65c\uc131\ud654\ub428.');\n            updateFilterPatterns();\n        } else {\n            filterPatterns = [];\n            log('\ud83d\udd04 \ud544\ud130\ub9c1 \uae30\ub2a5 \ube44\ud65c\uc131\ud654\ub428.');\n        }\n    }\n\n    function toggleDarkweb() {\n        darkwebEnabled = darkwebToggle.checked;\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9 \uc124\uc815: ${darkwebEnabled ? 'ON' : 'OFF'}`);\n    }\n\n    function getSearchQueryAndEngine() {\n        const url = window.location.href;\n        if (url.includes('google.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'google';\n        } else if (url.includes('bing.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'bing';\n        } else if (url.includes('daum.net/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'daum';\n        } else if (url.includes('search.naver.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('query') || '';\n            searchEngine = 'naver';\n        } else if (url.includes('search.yahoo.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('p') || '';\n            searchEngine = 'yahoo';\n        } else if (url.includes('duckduckgo.com/')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'duckduckgo';\n        } else if (url.includes('ecosia.org/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'ecosia';\n        } else if (url.includes('.onion')) {\n            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc911 \ud558\ub098\ub85c \uc124\uc815\n            searchEngine = 'darkweb';\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            if (!searchQuery) {\n                searchQuery = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694:');\n            }\n        } else {\n            searchQuery = '';\n            searchEngine = '';\n        }\n        log(`\ud83d\udd0d \uac80\uc0c9 \uc5d4\uc9c4: ${searchEngine}, \uac80\uc0c9\uc5b4: \"${searchQuery}\"`);\n    }\n\n    async function startCrawling() {\n        if (isRunning) {\n            alert('\uc774\ubbf8 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589 \uc911\uc785\ub2c8\ub2e4.');\n            return;\n        }\n        getSearchQueryAndEngine();\n        if (!searchQuery) {\n            alert('\ud604\uc7ac \ud398\uc774\uc9c0\uc5d0\uc11c \uac80\uc0c9\uc5b4\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            log('\u26a0\ufe0f \uac80\uc0c9\uc5b4 \ubbf8\uc785\ub825 \ub610\ub294 \uc778\uc2dd \uc2e4\ud328.');\n            return;\n        }\n        isRunning = true;\n        isPaused = false;\n        currentPage = 1;\n        results = [];\n        visitedLinks.clear();\n        resultsBody.innerHTML = '';\n        visitedCountElem.innerText = '0';\n        elapsedTimeElem.innerText = '00:00:00';\n        remainingTimeElem.innerText = '00:00:00';\n        logMessages = [];\n        logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>`;\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n        log('\u2705 \ud06c\ub864\ub9c1\uc744 \uc2dc\uc791\ud569\ub2c8\ub2e4.');\n        updateDuplicateThreshold();\n        updateRetryAttempts();\n        updateRetryInterval();\n        await enqueueCrawlPages(concurrentRequests); // \ub3d9\uc2dc \uc694\uccad \uc218 40\uc73c\ub85c \uc124\uc815\n        startTime = Date.now();\n        elapsedInterval = setInterval(updateElapsedTime, 1000);\n    }\n\n    function togglePause() {\n        if (!isRunning) {\n            alert('\uc77c\uc2dc\uc815\uc9c0/\uc7ac\uac1c\ud560 \ud06c\ub864\ub9c1\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        isPaused = !isPaused;\n        if (isPaused) {\n            log('\u23f8\ufe0f \ud06c\ub864\ub9c1\uc744 \uc77c\uc2dc\uc815\uc9c0\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n            pauseBtn.innerHTML = '<i>\u25b6\ufe0f</i> \uc7ac\uac1c';\n        } else {\n            log('\u25b6\ufe0f \ud06c\ub864\ub9c1\uc744 \uc7ac\uac1c\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n            pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n            processQueue();\n        }\n    }\n\n    function stopCrawling() {\n        if (!isRunning) {\n            alert('\uc911\uc9c0\ud560 \ud06c\ub864\ub9c1\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        isRunning = false;\n        isPaused = false;\n        pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n        clearInterval(elapsedInterval);\n        updateProgress();\n        log('\ud83d\udeab \ud06c\ub864\ub9c1\uc744 \uc911\uc9c0\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n        GM_notification({\n            text: '\ud06c\ub864\ub9c1\uc774 \uc911\uc9c0\ub418\uc5c8\uc2b5\ub2c8\ub2e4.',\n            title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n            timeout: 3000\n        });\n    }\n\n    async function enqueueCrawlPages(limit) {\n        for (let i = 0; i < limit; i++) {\n            queueCrawlPage();\n        }\n    }\n\n    function queueCrawlPage() {\n        if (!isRunning || isPaused) return;\n        if (currentRequests >= concurrentRequests) return;\n\n        // Assign a unique page number before starting the crawl\n        const pageToCrawl = currentPage++;\n        currentPageElem.innerText = currentPage;\n\n        currentRequests++;\n        crawlPage(pageToCrawl).then(() => {\n            currentRequests--;\n            queueCrawlPage();\n        });\n    }\n\n    async function crawlPage(page) {\n        if (!isRunning || isPaused) {\n            return;\n        }\n\n        // \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub530\ub978 URL \uad6c\uc131\n        let url = '';\n        if (searchEngine === 'google') {\n            url = `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}&start=${(page-1)*10}`;\n        } else if (searchEngine === 'bing') {\n            url = `https://www.bing.com/search?q=${encodeURIComponent(searchQuery)}&first=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'daum') {\n            url = `https://search.daum.net/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'naver') {\n            url = `https://search.naver.com/search.naver?query=${encodeURIComponent(searchQuery)}&start=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'yahoo') {\n            url = `https://search.yahoo.com/search?p=${encodeURIComponent(searchQuery)}&b=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'duckduckgo') {\n            url = `https://duckduckgo.com/html/?q=${encodeURIComponent(searchQuery)}&s=${(page-1)*10}`;\n        } else if (searchEngine === 'ecosia') {\n            url = `https://www.ecosia.org/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'darkweb') {\n            if (!darkwebEnabled) {\n                log('\ud83d\uded1 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc774 \ube44\ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.');\n                isRunning = false;\n                return;\n            }\n            const darkwebEngines = getDarkwebEngines();\n            if (darkwebEngines.length === 0) {\n                log('\u26a0\ufe0f \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n                isRunning = false;\n                return;\n            }\n            const randomEngine = darkwebEngines[Math.floor(Math.random() * darkwebEngines.length)];\n            url = `${randomEngine.url}/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else {\n            alert('\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uac80\uc0c9 \uc5d4\uc9c4\uc785\ub2c8\ub2e4.');\n            log('\u274c \uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uac80\uc0c9 \uc5d4\uc9c4.');\n            isRunning = false;\n            return;\n        }\n\n        log(`\ud83d\udcc4 \ud398\uc774\uc9c0 ${page} \ud06c\ub864\ub9c1 \uc911: ${url}`);\n\n        return new Promise((resolve) => {\n            GM_xmlhttpRequest({\n                method: \"GET\",\n                url: url,\n                headers: {\n                    \"User-Agent\": navigator.userAgent,\n                    \"Accept\": \"text/html\"\n                },\n                onload: async function(response) {\n                    if (response.status !== 200) {\n                        log(`\u274c \ud398\uc774\uc9c0 ${page} \ub85c\ub4dc \uc2e4\ud328: \uc0c1\ud0dc ${response.status}`);\n                        await handleCrawlError(page, retryAttempts);\n                        resolve();\n                        return;\n                    }\n\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(response.responseText, 'text/html');\n                    let items = [];\n                    if (searchEngine === 'google') {\n                        items = doc.querySelectorAll('div.g');\n                    } else if (searchEngine === 'bing') {\n                        items = doc.querySelectorAll('li.b_algo');\n                    } else if (searchEngine === 'daum') {\n                        items = doc.querySelectorAll('div.wrap_cont');\n                    } else if (searchEngine === 'naver') {\n                        items = doc.querySelectorAll('div.basic1');\n                    } else if (searchEngine === 'yahoo') {\n                        items = doc.querySelectorAll('div.compTitle');\n                    } else if (searchEngine === 'duckduckgo') {\n                        items = doc.querySelectorAll('div.result');\n                    } else if (searchEngine === 'ecosia') {\n                        items = doc.querySelectorAll('div.result');\n                    } else if (searchEngine === 'darkweb') {\n                        // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc911 \ud558\ub098\ub85c \uc124\uc815 (\uc608: Torch \uae30\uc900)\n                        items = doc.querySelectorAll('.result'); // \uc2e4\uc81c \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub9de\uac8c \uc870\uc815 \ud544\uc694\n                    }\n\n                    // \ub9cc\uc57d \uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\ub2e4\uba74 \ud06c\ub864\ub9c1 \uc885\ub8cc\n                    if (items.length === 0) {\n                        log('\ud83d\udd0d \ub354 \uc774\uc0c1 \ud06c\ub864\ub9c1\ud560 \ud398\uc774\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \ud06c\ub864\ub9c1\uc744 \uc885\ub8cc\ud569\ub2c8\ub2e4.');\n                        isRunning = false;\n                        isPaused = false;\n                        pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n                        clearInterval(elapsedInterval);\n                        updateProgress();\n                        GM_notification({\n                            text: '\ud06c\ub864\ub9c1\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.',\n                            title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                            timeout: 3000\n                        });\n                        resolve();\n                        return;\n                    }\n\n                    log(`\ud83d\udcca \ud398\uc774\uc9c0 ${page}\uc5d0\uc11c ${items.length}\uac1c \ud56d\ubaa9 \ubc1c\uacac.`);\n\n                    // \ubcd1\ub82c \ucc98\ub9ac: Promise.all\uc744 \uc774\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30\uc801\uc73c\ub85c \ucc98\ub9ac\n                    const itemPromises = Array.from(items).map(async (item) => {\n                        let title = 'N/A';\n                        let link = 'N/A';\n                        let description = 'N/A';\n                        let image = 'N/A';\n                        let htmlLink = '\ube44\ud65c\uc131\ud654';\n                        let pageLoadTime = 'N/A';\n\n                        // \uac01 \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub530\ub978 \ub370\uc774\ud130 \ucd94\ucd9c\n                        if (searchEngine === 'google') {\n                            const titleElem = item.querySelector('h3');\n                            const linkElem = item.querySelector('a');\n                            const descElem = item.querySelector('.IsZvec') || item.querySelector('.VwiC3b');\n                            if (titleElem) title = titleElem.innerText;\n                            if (linkElem) link = linkElem.href;\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'bing') {\n                            const titleElem = item.querySelector('h2 a');\n                            const descElem = item.querySelector('p');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'daum') {\n                            const titleElem = item.querySelector('a.link_fax');\n                            const descElem = item.querySelector('div.cont_inner');\n                            if (titleElem) {\n                                title = titleElem.innerText.trim();\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText.trim();\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'naver') {\n                            const titleElem = item.querySelector('a.tit');\n                            const descElem = item.querySelector('div.desc');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.thumb');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'yahoo') {\n                            const titleElem = item.querySelector('h3');\n                            const linkElem = item.querySelector('a');\n                            const descElem = item.querySelector('div.compText');\n                            if (titleElem) title = titleElem.innerText;\n                            if (linkElem) link = linkElem.href;\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'duckduckgo') {\n                            const titleElem = item.querySelector('a.result__a');\n                            const descElem = item.querySelector('a.result__snippet');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.result__thumbnail');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'ecosia') {\n                            const titleElem = item.querySelector('a.result-title');\n                            const descElem = item.querySelector('div.result-description');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.result-image');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'darkweb') {\n                            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uacb0\uacfc \ucd94\ucd9c (\uc608: Torch \uae30\uc900)\n                            const titleElem = item.querySelector('a');\n                            const descElem = item.querySelector('p');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        }\n\n                        // \uad11\uace0 \uc81c\uc678 \uae30\ub2a5 \uc801\uc6a9\n                        if (toggleAds.checked) {\n                            const combinedText = `${title} ${description}`.toLowerCase();\n                            const isAd = combinedText.includes('advertisement') || combinedText.includes('\uad11\uace0');\n                            if (isAd) {\n                                log(`\ud83d\udeab \uad11\uace0 \ud56d\ubaa9 \uc81c\uc678: \"${title}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \ud544\ud130 \ub2e8\uc5b4 \uc801\uc6a9\n                        if (filterPatterns.length > 0) {\n                            const combinedText = `${title} ${description}`.toLowerCase();\n                            const isFiltered = filterPatterns.some(regex => regex.test(combinedText));\n                            if (isFiltered) {\n                                log(`\u274c \ud544\ud130 \ub2e8\uc5b4 \ud3ec\ud568 \ud56d\ubaa9 \uc81c\uc678: \"${title}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc801\uc6a9 (\uc0ac\uc774\ud2b8 \uc81c\ubaa9 \ub610\ub294 HTML \ub0b4\uc6a9 \uae30\ubc18)\n                        if (siteFilterPatterns.length > 0) {\n                            const isSiteFiltered = siteFilterPatterns.some(regex => regex.test(link) || regex.test(title));\n                            if (isSiteFiltered) {\n                                log(`\ud83d\udeab \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\uc5d0 \uc758\ud574 \uc81c\uc678\ub41c \ud56d\ubaa9: \"${link}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \ub3c4\uba54\uc778 \ucd94\ucd9c\n                        const domain = extractDomain(link);\n                        if (!domain) return null;\n\n                        // \uc81c\uc678 \ub3c4\uba54\uc778 \uac80\uc0ac\n                        if (excludeDomains.includes(domain.toLowerCase())) {\n                            log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \ud56d\ubaa9 \uc81c\uc678: \"${link}\"`);\n                            return null;\n                        }\n\n                        // \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc801\uc6a9\n                        if (strictSiteFilter.checked) {\n                            if (!siteFilterPatterns.some(regex => regex.test(link) || regex.test(title))) {\n                                log(`\ud83d\udeab \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\uc5d0 \uc758\ud574 \uc81c\uc678\ub41c \ud56d\ubaa9: \"${link}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \uc911\ubcf5 \uac80\uc0ac (\ub3c4\uba54\uc778\ubcc4 \ubc29\ubb38 \ud69f\uc218)\n                        let visitCount = visitedLinks.get(domain) || 0;\n                        if (visitCount >= duplicateThreshold) {\n                            log(`\ud83d\udd04 \uc911\ubcf5 \ubc29\ubb38 \uc81c\ud55c: \"${domain}\"`);\n                            return null;\n                        }\n\n                        // \ubc29\ubb38 \ud69f\uc218 \uc5c5\ub370\uc774\ud2b8\n                        visitedLinks.set(domain, visitCount + 1);\n                        visitedCountElem.innerText = visitedLinks.size.toString();\n\n                        // \ud398\uc774\uc9c0 \ub85c\ub529 \uc2dc\uac04 \uce21\uc815\n                        const loadStart = performance.now();\n                        try {\n                            // mode: 'cors'\ub85c \ubcc0\uacbd\ud558\uc5ec \uc2e4\uc81c \uc751\ub2f5\uc744 \ubc1b\uc744 \uc218 \uc788\ub3c4\ub85d \ud568\n                            const fetchResponse = await fetch(link, { mode: 'cors' });\n                            if (fetchResponse.ok) {\n                                const loadEnd = performance.now();\n                                pageLoadTime = Math.round(loadEnd - loadStart);\n                            } else {\n                                pageLoadTime = '\uc751\ub2f5 \ubd88\ub7c9';\n                            }\n                        } catch (err) {\n                            pageLoadTime = '\uacc4\uc0b0 \ubd88\uac00';\n                        }\n\n                        // HTML \uc635\uc158\n                        if (!toggleHTML.checked) {\n                            htmlLink = '\ube44\ud65c\uc131\ud654';\n                        }\n\n                        // \uc774\ubbf8\uc9c0 \uc635\uc158\n                        if (!toggleImages.checked) {\n                            image = '\ube44\ud65c\uc131\ud654';\n                        }\n\n                        const result = { title, link, description, image, htmlLink, pageLoadTime };\n                        results.push(result);\n\n                        // \uacb0\uacfc \ud14c\uc774\ube14\uc5d0 \ucd94\uac00\n                        const row = document.createElement('tr');\n                        row.innerHTML = `\n                            <td>${escapeHTML(title)}</td>\n                            <td><a href=\"${escapeHTML(link)}\" target=\"_blank\">${escapeHTML(link)}</a></td>\n                            <td>${escapeHTML(description)}</td>\n                            <td>${image}</td>\n                            <td>${htmlLink}</td>\n                            <td>${pageLoadTime}</td>\n                        `;\n                        resultsBody.appendChild(row);\n\n                        return result;\n                    });\n\n                    // Promise.all\uc744 \ud1b5\ud574 \ubaa8\ub4e0 \ud56d\ubaa9 \ucc98\ub9ac \uc644\ub8cc \ub300\uae30\n                    await Promise.all(itemPromises);\n\n                    // \ub370\uc774\ud130 \uc2dc\uac01\ud654 \uc5c5\ub370\uc774\ud2b8\n                    updateChart();\n\n                    // \uc9c4\ud589\ub960 \uc5c5\ub370\uc774\ud2b8\n                    updateProgress();\n\n                    // \ub300\uae30 \uc2dc\uac04 \ucd94\uac00\ud558\uc5ec \uc11c\ubc84\uc5d0 \ubd80\ub2f4 \uc8fc\uc9c0 \uc54a\uae30\n                    setTimeout(() => {\n                        queueCrawlPage();\n                    }, isPaused ? 0 : 1000); // 1\ucd08 \ub300\uae30\n\n                    resolve();\n                },\n                onerror: function() {\n                    log(`\u274c \ud398\uc774\uc9c0 ${page} \uc694\uccad \uc911 \uc624\ub958 \ubc1c\uc0dd.`);\n                    handleCrawlError(page, retryAttempts).then(() => {\n                        resolve();\n                    });\n                }\n            });\n        });\n    }\n\n    async function handleCrawlError(page, retriesLeft) {\n        if (retriesLeft > 0 && isRunning) {\n            log(`\ud83d\udd04 \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 (${retriesLeft}\ud68c \ub0a8\uc74c).`);\n            return new Promise((resolve) => {\n                setTimeout(() => {\n                    const url = constructURL(page);\n                    if (!url) {\n                        log(`\u274c \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 \uc2e4\ud328: URL\uc774 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.`);\n                        resolve();\n                        return;\n                    }\n                    GM_xmlhttpRequest({\n                        method: \"GET\",\n                        url: url,\n                        headers: {\n                            \"User-Agent\": navigator.userAgent,\n                            \"Accept\": \"text/html\"\n                        },\n                        onload: async function(response) {\n                            if (response.status === 200) {\n                                log(`\u2705 \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 \uc131\uacf5.`);\n                                await crawlPage(page);\n                            } else {\n                                await handleCrawlError(page, retriesLeft - 1);\n                            }\n                            resolve();\n                        },\n                        onerror: async function() {\n                            await handleCrawlError(page, retriesLeft - 1);\n                            resolve();\n                        }\n                    });\n                }, retryInterval); // retryInterval\uc774 100ms\uc73c\ub85c \uc124\uc815\ub428\n            });\n        } else {\n            log(`\u274c \ud398\uc774\uc9c0 ${page} \ub85c\ub4dc \uc2e4\ud328: \ucd5c\ub300 \uc7ac\uc2dc\ub3c4 \ud69f\uc218 \ucd08\uacfc.`);\n            // \ud06c\ub864\ub9c1\uc744 \uc911\uc9c0\ud558\uc9c0 \uc54a\uace0 \ub2e4\uc74c \ud398\uc774\uc9c0\ub85c \ub118\uc5b4\uac10\n            currentPage++;\n            currentPageElem.innerText = currentPage;\n            setTimeout(() => {\n                queueCrawlPage();\n            }, 1000);\n            return Promise.resolve();\n        }\n    }\n\n    function constructURL(page) {\n        if (searchEngine === 'google') {\n            return `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}&start=${(page-1)*10}`;\n        } else if (searchEngine === 'bing') {\n            return `https://www.bing.com/search?q=${encodeURIComponent(searchQuery)}&first=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'daum') {\n            return `https://search.daum.net/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'naver') {\n            return `https://search.naver.com/search.naver?query=${encodeURIComponent(searchQuery)}&start=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'yahoo') {\n            return `https://search.yahoo.com/search?p=${encodeURIComponent(searchQuery)}&b=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'duckduckgo') {\n            return `https://duckduckgo.com/html/?q=${encodeURIComponent(searchQuery)}&s=${(page-1)*10}`;\n        } else if (searchEngine === 'ecosia') {\n            return `https://www.ecosia.org/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'darkweb') {\n            const darkwebEngines = getDarkwebEngines();\n            if (darkwebEngines.length === 0) {\n                return '';\n            }\n            const randomEngine = darkwebEngines[Math.floor(Math.random() * darkwebEngines.length)];\n            return `${randomEngine.url}/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else {\n            return '';\n        }\n    }\n\n    function updateProgress() {\n        // \ubb34\uc81c\ud55c\uc774\ubbc0\ub85c \uc9c4\ud589\ub960\uc744 \ud398\uc774\uc9c0 \uc218\uc5d0 \uae30\ubc18\ud558\uc5ec \ud45c\uc2dc\n        const progressPercent = (currentPage % 100) * 1; // 100\ud398\uc774\uc9c0\ub9c8\ub2e4 100%\ub85c \ub9ac\uc14b\n        progressBar.value = progressPercent > 100 ? 100 : progressPercent;\n        progressText.innerText = `\ud398\uc774\uc9c0 ${currentPage}`;\n        if (progressPercent >= 100) {\n            progressBar.value = 0;\n        }\n    }\n\n    function resetCrawling() {\n        isRunning = false;\n        isPaused = false;\n        currentPage = 1;\n        results = [];\n        visitedLinks.clear();\n        resultsBody.innerHTML = '';\n        progressBar.value = 0;\n        progressText.innerText = '\ud398\uc774\uc9c0 0';\n        currentPageElem.innerText = '0';\n        visitedCountElem.innerText = '0';\n        elapsedTimeElem.innerText = '00:00:00';\n        remainingTimeElem.innerText = '00:00:00';\n        logMessages = [];\n        logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>`;\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n        // \ucc28\ud2b8 \ucd08\uae30\ud654\n        crawlData.labels = [];\n        crawlData.datasets[0].data = [];\n        if (crawlChart) {\n            crawlChart.update();\n        }\n        clearInterval(elapsedInterval);\n        log('\ud83d\udd04 \ud06c\ub864\ub9c1\uc744 \ucd08\uae30\ud654\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n    }\n\n    function exportResults() {\n        if (results.length === 0) {\n            alert('\ub0b4\ubcf4\ub0bc \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const format = prompt('\ub0b4\ubcf4\ub0bc \ud615\uc2dd\uc744 \uc120\ud0dd\ud558\uc138\uc694 (xlsx, csv, json):', 'xlsx');\n        if (!format) return;\n        if (format.toLowerCase() === 'xlsx') {\n            const ws = XLSX.utils.json_to_sheet(results);\n            const wb = XLSX.utils.book_new();\n            XLSX.utils.book_append_sheet(wb, ws, \"\uacb0\uacfc\");\n            XLSX.writeFile(wb, \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\");\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else if (format.toLowerCase() === 'csv') {\n            const csv = results.map(row => `\"${row.title.replace(/\"/g, '\"\"')}\",\"${row.link.replace(/\"/g, '\"\"')}\",\"${row.description.replace(/\"/g, '\"\"')}\",\"${row.image.replace(/\"/g, '\"\"')}\",\"${row.htmlLink.replace(/\"/g, '\"\"')}\",\"${row.pageLoadTime}\"`).join('\\n');\n            const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = '\ud06c\ub864\ub9c1_\uacb0\uacfc.csv';\n            a.click();\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.csv\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.csv\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else if (format.toLowerCase() === 'json') {\n            const json = JSON.stringify(results, null, 2);\n            const blob = new Blob([json], { type: 'application/json;charset=utf-8;' });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = '\ud06c\ub864\ub9c1_\uacb0\uacfc.json';\n            a.click();\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.json\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.json\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else {\n            alert('\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \ud615\uc2dd\uc785\ub2c8\ub2e4.');\n        }\n    }\n\n    function escapeHTML(str) {\n        if (!str) return '';\n        return str.replace(/&/g, \"&amp;\")\n                  .replace(/</g, \"&lt;\")\n                  .replace(/>/g, \"&gt;\")\n                  .replace(/\"/g, \"&quot;\")\n                  .replace(/'/g, \"&#039;\");\n    }\n\n    function extractDomain(url) {\n        try {\n            const urlObj = new URL(url);\n            return urlObj.hostname.replace('www.', '');\n        } catch (e) {\n            return null;\n        }\n    }\n\n    function updateElapsedTime() {\n        if (!startTime) return;\n        const now = Date.now();\n        const elapsed = Math.floor((now - startTime) / 1000);\n        elapsedTimeElem.innerText = formatTime(elapsed);\n        const estimatedTotal = currentPage * 1; // \uc608\uce21: \uac01 \ud398\uc774\uc9c0 1\ucd08\n        const remaining = Math.max(estimatedTotal - elapsed, 0);\n        remainingTimeElem.innerText = formatTime(remaining);\n    }\n\n    function formatTime(seconds) {\n        const hrs = String(Math.floor(seconds / 3600)).padStart(2, '0');\n        const mins = String(Math.floor((seconds % 3600) / 60)).padStart(2, '0');\n        const secs = String(seconds % 60).padStart(2, '0');\n        return `${hrs}:${mins}:${secs}`;\n    }\n\n    function updateChart() {\n        crawlData.labels = Array.from(visitedLinks.keys());\n        crawlData.datasets[0].data = Array.from(visitedLinks.values());\n\n        if (crawlChart) {\n            crawlChart.update();\n        }\n        // \uc800\uc7a5\n        GM_setValue('crawlerData', JSON.stringify(crawlData));\n    }\n\n    function loadCrawlData() {\n        const storedData = GM_getValue('crawlerData', null);\n        if (storedData) {\n            const parsedData = JSON.parse(storedData);\n            crawlData = parsedData;\n            if (crawlChart) {\n                crawlChart.data = crawlData;\n                crawlChart.update();\n            }\n        }\n    }\n\n    function saveCrawlData() {\n        GM_setValue('crawlerData', JSON.stringify(crawlData));\n    }\n\n    // \uc8fc\uae30\uc801\uc73c\ub85c \ud06c\ub864\ub9c1 \ub370\uc774\ud130\ub97c \uc800\uc7a5\n    setInterval(saveCrawlData, 5000);\n\n    // \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c \uac00\uae30 \ubc84\ud2bc \uae30\ub2a5\n    function openSearchEngines() {\n        const engineUrls = {\n            'Google': 'https://www.google.com/',\n            'Bing': 'https://www.bing.com/',\n            'Daum': 'https://www.daum.net/',\n            'Naver': 'https://www.naver.com/',\n            'Yahoo': 'https://www.yahoo.com/',\n            'DuckDuckGo': 'https://duckduckgo.com/',\n            'Ecosia': 'https://www.ecosia.org/',\n            'Yahoo Japan': 'https://www.yahoo.co.jp/',\n            'Baidu': 'https://www.baidu.com/',\n            'Yandex': 'https://www.yandex.com/',\n            'Ask': 'https://www.ask.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Qwant': 'https://www.qwant.com/',\n            'Swisscows': 'https://swisscows.com/',\n            'Mojeek': 'https://www.mojeek.com/',\n            'Gibiru': 'https://www.gibiru.com/',\n            'MetaGer': 'https://metager.org/',\n            'Peekier': 'https://peekier.com/',\n            'Disconnect Search': 'https://search.disconnect.me/',\n            'Ekoru': 'https://www.ekoru.org/',\n            'Yippy': 'https://yippy.com/',\n            'Infinity Search': 'https://www.infinitysearch.co/',\n            'WolframAlpha': 'https://www.wolframalpha.com/',\n            'Shodan': 'https://www.shodan.io/',\n            'Archive.org': 'https://archive.org/',\n            'Wayback Machine': 'https://web.archive.org/',\n            'PubMed': 'https://pubmed.ncbi.nlm.nih.gov/',\n            'IEEE Xplore': 'https://ieeexplore.ieee.org/',\n            'Google Scholar': 'https://scholar.google.com/',\n            'LexisNexis': 'https://www.lexisnexis.com/',\n            'Google Books': 'https://books.google.com/',\n            'Creative Commons Search': 'https://search.creativecommons.org/',\n            'TOR Search': 'http://torsearch7uu5ond.onion/',\n            'Ahmia': 'http://msydqstlz2kzerdg.onion/',\n            'Haystak': 'http://haystakvxad7wbk5.onion/',\n            'Dark Search': 'http://darksearch3w3nrc.onion/',\n            'Phobos': 'http://phobos6uj4abm4pf.onion/',\n            'Not Evil': 'http://hss3uro2hsxfogfq.onion/',\n            'IntelligenceX': 'http://intelligencexmh5v.onion/',\n            'Torch': 'http://xmh57jrzrnw6insl.onion/',\n            'Silk Road 3.1': 'http://silkroad31lo5ya.onion/',\n            'Fresh Onions': 'http://rx7hmtf7k7xk6ked.onion/',\n            'Dark Web Link': 'http://darkweblink5wqk.onion/',\n            'Tor Tracker': 'http://tortracker5ujzra.onion/',\n            'Deep Web Search': 'http://deepwebsearch6b6x.onion/',\n            'Onion Monitor': 'http://onionmonitor3c7v.onion/',\n            'Hidden Wiki': 'http://hiddenwiki5z35.onion/',\n            'TorEX': 'http://torexk3wd2buz.onion/',\n            'BlackBook': 'http://blackbook51uv.onion/',\n            'Taboo Search': 'http://taboosearch37b.onion/',\n            'The Pirate Bay (onion)': 'http://uj3wazyk5u4hnvtk.onion/',\n            'Dogpile': 'https://www.dogpile.com/',\n            'Oscobo': 'https://www.oscobo.com/',\n            'HotBot': 'https://www.hotbot.com/',\n            'Peekier': 'https://peekier.com/',\n            'Lukol': 'https://www.lukol.com/',\n            'Privatelee': 'https://privatelee.com/',\n            'DuckDuckGo (Tor)': 'http://3g2upl4pq6kufc4m.onion/',\n            'TorEX': 'http://torexk3wd2buz.onion/',\n            'BlackBook': 'http://blackbook51uv.onion/',\n            'Taboo Search': 'http://taboosearch37b.onion/',\n            'Kilos': 'http://kilos7wbfn3ptgw.onion/',\n            'Candle': 'http://zg6ak7qqfhbkbppx.onion/',\n            'Dark Falcon': 'http://darkfalconphp5fh.onion/',\n            'Hidden Wiki': 'http://hiddenwiki5z35.onion/',\n            'Onion Monitor': 'http://onionmonitor3c7v.onion/',\n            'Phobos 2': 'http://phobos2uj4abm4pf.onion/',\n            'Deep Web Search': 'http://deepwebsearch6b6x.onion/',\n            'DarkSearchBox': 'http://darksearchbox5a3x.onion/',\n            'Black Search': 'http://blacksearch7xm7.onion/',\n            'Search Encrypt': 'https://www.searchencrypt.com/',\n            'Peekier': 'https://peekier.com/',\n            'Lukol': 'https://www.lukol.com/',\n            'Disconnect Search': 'https://search.disconnect.me/',\n            'Privatelee': 'https://privatelee.com/',\n            'Infinity Search': 'https://www.infinitysearch.co/',\n            'Dogpile': 'https://www.dogpile.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Exalead': 'https://www.exalead.com/',\n            'Gigablast': 'https://www.gigablast.com/',\n            'Searx': 'https://searx.me/',\n            'FindSounds': 'https://www.findsounds.com/',\n            'TinEye': 'https://tineye.com/',\n            'Boardreader': 'https://www.boardreader.com/',\n            'PubCrawl': 'https://pubcrawl.org/',\n            'BeautyFetch': 'http://beautyfetch.com/',\n            'WolframAlpha': 'https://www.wolframalpha.com/',\n            'Shodan': 'https://www.shodan.io/',\n            'Archive.org': 'https://archive.org/',\n            'Wayback Machine': 'https://web.archive.org/',\n            'PubMed': 'https://pubmed.ncbi.nlm.nih.gov/',\n            'IEEE Xplore': 'https://ieeexplore.ieee.org/',\n            'Google Scholar': 'https://scholar.google.com/',\n            'LexisNexis': 'https://www.lexisnexis.com/',\n            'Google Books': 'https://books.google.com/',\n            'Creative Commons Search': 'https://search.creativecommons.org/',\n            // \ucd94\uac00 \uc5d4\uc9c4 \uac00\ub2a5\n        };\n        let html = '\ud83d\udce1 <strong>\uac80\uc0c9 \uc5d4\uc9c4:</strong><br>';\n        for (const [name, url] of Object.entries(engineUrls)) {\n            html += `<button class=\"search-engine-btn\" data-url=\"${url}\">${name}</button><br>`;\n        }\n        // \ud31d\uc5c5 \uc0dd\uc131\n        const popup = document.createElement('div');\n        popup.className = 'search-engines-popup';\n        popup.innerHTML = html;\n        container.appendChild(popup);\n        popup.style.display = 'block';\n\n        // \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        popup.querySelectorAll('.search-engine-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                window.open(btn.getAttribute('data-url'), '_blank');\n                popup.style.display = 'none';\n            });\n        });\n\n        // \uc678\ubd80 \ud074\ub9ad \uc2dc \ud31d\uc5c5 \ub2eb\uae30\n        document.addEventListener('click', function(event) {\n            if (!popup.contains(event.target) && event.target !== searchEnginesBtn) {\n                popup.style.display = 'none';\n            }\n        }, { once: true });\n    }\n\n    // HTML \ud0ed\uc5d0 \ucf58\ud150\uce20 \ud45c\uc2dc \uae30\ub2a5\n    container.addEventListener('click', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const url = decodeURIComponent(event.target.getAttribute('data-url'));\n            showHTMLInUI(url);\n        }\n    });\n\n    container.addEventListener('mouseover', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const url = decodeURIComponent(event.target.getAttribute('data-url'));\n            showPreviewPopup(event.target, url);\n        }\n    });\n\n    container.addEventListener('mouseout', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const popup = container.querySelector('.preview-popup');\n            if (popup) {\n                popup.style.display = 'none';\n            }\n        }\n    });\n\n    function showHTMLInUI(url) {\n        // UI \ub0b4\uc5d0 iframe\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0ac\uc774\ud2b8 \ub0b4\uc6a9 \ud45c\uc2dc\n        let iframe = container.querySelector('.html-display iframe');\n        if (!iframe) {\n            iframe = document.createElement('iframe');\n            container.querySelector('.html-display').appendChild(iframe);\n        }\n        iframe.src = url;\n        // \ud0ed\uc744 'HTML'\ub85c \uc804\ud658\n        switchTab('html-display');\n        log(`\ud83d\udd0d HTML \ubcf4\uae30: ${url}`);\n    }\n\n    function showPreviewPopup(target, url) {\n        // \ud31d\uc5c5 \uc0dd\uc131\n        let popup = container.querySelector('.preview-popup');\n        if (!popup) {\n            popup = document.createElement('div');\n            popup.className = 'preview-popup';\n            popup.innerHTML = `<iframe src=\"${url}\" style=\"width:100%; height:100%; border:none;\"></iframe>`;\n            container.appendChild(popup);\n        }\n        popup.style.display = 'block';\n        // \uc704\uce58 \uc870\uc815\n        const rect = target.getBoundingClientRect();\n        const containerRect = container.getBoundingClientRect();\n        popup.style.left = `${rect.left - containerRect.left + 20}px`;\n        popup.style.top = `${rect.bottom - containerRect.top + 5}px`;\n    }\n\n    function switchTab(tabId) {\n        const tabs = container.querySelectorAll('.tab');\n        const tabContents = container.querySelectorAll('.tab-content');\n\n        tabs.forEach(t => {\n            if(t.getAttribute('data-tab') === tabId){\n                t.classList.add('active');\n            } else {\n                t.classList.remove('active');\n            }\n        });\n\n        tabContents.forEach(content => {\n            if(content.id === tabId){\n                content.classList.add('active');\n            } else {\n                content.classList.remove('active');\n            }\n        });\n    }\n\n    // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uad00\ub9ac\n    function loadDarkwebEngines() {\n        const storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        darkwebEnginesList.innerHTML = '';\n        storedEngines.forEach(engine => {\n            const li = document.createElement('li');\n            li.innerHTML = `\n                <span>${escapeHTML(engine.name)}</span>\n                <button class=\"remove-darkweb-engine-btn\" data-url=\"${engine.url}\">\ud83d\uddd1\ufe0f</button>\n            `;\n            darkwebEnginesList.appendChild(li);\n        });\n\n        // \uc0ad\uc81c \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        darkwebEnginesList.querySelectorAll('.remove-darkweb-engine-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                const url = btn.getAttribute('data-url');\n                removeDarkwebEngine(url);\n            });\n        });\n    }\n\n    function addDarkwebEngine() {\n        const name = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc774\ub984\uc744 \uc785\ub825\ud558\uc138\uc694:');\n        if (!name) {\n            alert('\uc774\ub984\uc744 \uc785\ub825\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const url = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 URL\uc744 \uc785\ub825\ud558\uc138\uc694 (\uc608: http://exampleonion.onion/):');\n        if (!url) {\n            alert('URL\uc744 \uc785\ub825\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const newEngine = { name, url };\n        const storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        storedEngines.push(newEngine);\n        GM_setValue('darkwebEngines', storedEngines);\n        loadDarkwebEngines();\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00: ${name} (${url})`);\n    }\n\n    function removeDarkwebEngine(url) {\n        let storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        storedEngines = storedEngines.filter(engine => engine.url !== url);\n        GM_setValue('darkwebEngines', storedEngines);\n        loadDarkwebEngines();\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc81c\uac70: ${url}`);\n    }\n\n    function getDarkwebEngines() {\n        return GM_getValue('darkwebEngines', defaultDarkwebEngines);\n    }\n\n    // \ubc88\uc5ed\uae30 \uae30\ub2a5 \ucd94\uac00\n    async function translateContent() {\n        if (results.length === 0) {\n            alert('\ubc88\uc5ed\ud560 \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        translatedContent.innerHTML = '\ubc88\uc5ed \uc911...';\n\n        try {\n            // i18next\ub97c \uc774\uc6a9\ud55c \ubc88\uc5ed\n            const texts = results.map(r => r.description).join('. ');\n            const translatedText = await translateText(texts, translateLanguage);\n            translatedContent.innerText = translatedText;\n            log('\ud83d\udd04 \ubc88\uc5ed\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.');\n        } catch (error) {\n            translatedContent.innerText = '\ubc88\uc5ed \uc911 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4.';\n            log(`\u274c \ubc88\uc5ed \uc624\ub958: ${error}`);\n        }\n    }\n\n    async function translateText(text, targetLang) {\n        // Papago \ubc88\uc5ed API \uc0ac\uc6a9 (API \ud0a4 \ud544\uc694)\n        const apiUrl = 'https://openapi.naver.com/v1/papago/n2mt';\n        const clientId = 'YOUR_NAVER_CLIENT_ID'; // [\ud544\uc218] \uc2e4\uc81c \ud074\ub77c\uc774\uc5b8\ud2b8 ID\ub85c \uad50\uccb4\ud558\uc138\uc694.\n        const clientSecret = 'YOUR_NAVER_CLIENT_SECRET'; // [\ud544\uc218] \uc2e4\uc81c \ud074\ub77c\uc774\uc5b8\ud2b8 \uc2dc\ud06c\ub9bf\uc73c\ub85c \uad50\uccb4\ud558\uc138\uc694.\n\n        const data = new URLSearchParams();\n        data.append('source', 'ko');\n        data.append('target', targetLang);\n        data.append('text', text);\n\n        const response = await fetch(apiUrl, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n                'X-Naver-Client-Id': clientId,\n                'X-Naver-Client-Secret': clientSecret\n            },\n            body: data\n        });\n\n        const result = await response.json();\n        if (result.errorMessage) {\n            throw new Error(result.errorMessage);\n        }\n        return result.message.result.translatedText;\n    }\n\n    // \ubc88\uc5ed\uae30 \uc139\uc158 \ubc84\ud2bc \ud074\ub9ad \ucc98\ub9ac\n    // \ubc88\uc5ed \uae30\ub2a5\uc740 \uc704\uc5d0\uc11c \uc815\uc758\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\n    // \ub85c\uae45, \ud544\ud130\ub9c1, \ud06c\ub864\ub9c1 \ud568\uc218\ub4e4\uc740 \uc774\ubbf8 \uc704\uc5d0\uc11c \uc0c1\uc138\ud788 \uad6c\ud604\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\n    // \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30 \uc9c1\uc811 UI\uc5d0 \ud45c\uc2dc\n    function loadSearchEnginesDirect() {\n        const engineUrls = {\n            'Google': 'https://www.google.com/',\n            'Bing': 'https://www.bing.com/',\n            'Daum': 'https://www.daum.net/',\n            'Naver': 'https://www.naver.com/',\n            'Yahoo': 'https://www.yahoo.com/',\n            'DuckDuckGo': 'https://duckduckgo.com/',\n            'Ecosia': 'https://www.ecosia.org/',\n            'Yahoo Japan': 'https://www.yahoo.co.jp/',\n            'Baidu': 'https://www.baidu.com/',\n            'Yandex': 'https://www.yandex.com/',\n            'Ask': 'https://www.ask.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Qwant': 'https://www.qwant.com/',\n            'Swisscows': 'https://swisscows.com/',\n            'Mojeek': 'https://www.mojeek.com/',\n            'Gibiru': 'https://www.gibiru.com/',\n            'MetaGer': 'https://metager.org/',\n            'Peekier': 'https://peekier.com/',\n            'Disconnect Search': 'https://search.disconnect.me/',\n            'Ekoru': 'https://www.ekoru.org/',\n            'Yippy': 'https://yippy.com/',\n            'Infinity Search': 'https://www.infinitysearch.co/',\n            'WolframAlpha': 'https://www.wolframalpha.com/',\n            'Shodan': 'https://www.shodan.io/',\n            'Archive.org': 'https://archive.org/',\n            'Wayback Machine': 'https://web.archive.org/',\n            'PubMed': 'https://pubmed.ncbi.nlm.nih.gov/',\n            'IEEE Xplore': 'https://ieeexplore.ieee.org/',\n            'Google Scholar': 'https://scholar.google.com/',\n            'LexisNexis': 'https://www.lexisnexis.com/',\n            'Google Books': 'https://books.google.com/',\n            'Creative Commons Search': 'https://search.creativecommons.org/',\n            'TOR Search': 'http://torsearch7uu5ond.onion/',\n            'Ahmia': 'http://msydqstlz2kzerdg.onion/',\n            'Haystak': 'http://haystakvxad7wbk5.onion/',\n            'Dark Search': 'http://darksearch3w3nrc.onion/',\n            'Phobos': 'http://phobos6uj4abm4pf.onion/',\n            'Not Evil': 'http://hss3uro2hsxfogfq.onion/',\n            'IntelligenceX': 'http://intelligencexmh5v.onion/',\n            'Torch': 'http://xmh57jrzrnw6insl.onion/',\n            'Silk Road 3.1': 'http://silkroad31lo5ya.onion/',\n            'Fresh Onions': 'http://rx7hmtf7k7xk6ked.onion/',\n            'Dark Web Link': 'http://darkweblink5wqk.onion/',\n            'Tor Tracker': 'http://tortracker5ujzra.onion/',\n            'Deep Web Search': 'http://deepwebsearch6b6x.onion/',\n            'Onion Monitor': 'http://onionmonitor3c7v.onion/',\n            'Hidden Wiki': 'http://hiddenwiki5z35.onion/',\n            'TorEX': 'http://torexk3wd2buz.onion/',\n            'BlackBook': 'http://blackbook51uv.onion/',\n            'Taboo Search': 'http://taboosearch37b.onion/',\n            'The Pirate Bay (onion)': 'http://uj3wazyk5u4hnvtk.onion/',\n            'Dogpile': 'https://www.dogpile.com/',\n            'Oscobo': 'https://www.oscobo.com/',\n            'HotBot': 'https://www.hotbot.com/',\n            'Peekier': 'https://peekier.com/',\n            'Lukol': 'https://www.lukol.com/',\n            'Privatelee': 'https://privatelee.com/',\n            'Infinity Search': 'https://www.infinitysearch.co/',\n            'Dogpile': 'https://www.dogpile.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Exalead': 'https://www.exalead.com/',\n            'Gigablast': 'https://www.gigablast.com/',\n            'Searx': 'https://searx.me/',\n            'FindSounds': 'https://www.findsounds.com/',\n            'TinEye': 'https://tineye.com/',\n            'Boardreader': 'https://www.boardreader.com/',\n            'PubCrawl': 'https://pubcrawl.org/',\n            'BeautyFetch': 'http://beautyfetch.com/',\n            'WolframAlpha': 'https://www.wolframalpha.com/',\n            'Shodan': 'https://www.shodan.io/',\n            'Archive.org': 'https://archive.org/',\n            'Wayback Machine': 'https://web.archive.org/',\n            'PubMed': 'https://pubmed.ncbi.nlm.nih.gov/',\n            'IEEE Xplore': 'https://ieeexplore.ieee.org/',\n            'Google Scholar': 'https://scholar.google.com/',\n            'LexisNexis': 'https://www.lexisnexis.com/',\n            'Google Books': 'https://books.google.com/',\n            'Creative Commons Search': 'https://search.creativecommons.org/',\n            // \ucd94\uac00 \uc5d4\uc9c4 \uac00\ub2a5\n        };\n\n        let html = '';\n        for (const [name, url] of Object.entries(engineUrls)) {\n            html += `<button class=\"search-engine-direct-btn\" data-url=\"${url}\">${name}</button>`;\n        }\n\n        searchEnginesDirect.innerHTML = html;\n\n        // \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        searchEnginesDirect.querySelectorAll('.search-engine-direct-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                window.open(btn.getAttribute('data-url'), '_blank');\n            });\n        });\n    }\n\n})();\n```","behavior":"degenerate_repetition","conversation_hash":"a602aa364baaea4f34afad0ef32af72a","conversation_redacted":false,"conversation_toxic":false,"country":"South Korea","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"o1-mini-2024-09-12","n_chars":165340,"n_turns_in_conversation":1,"n_words":12484,"source_row_offset":28611,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:35:05 GMT","turn_id":"8cfe9fbd8b3126a5481e5300","turn_index":0,"user_text":"// ==UserScript==\n// @name         \uc885\ud569 \uc6f9 \ud06c\ub864\ub7ec 7.9.5\n// @namespace    http://tampermonkey.net/\n// @version      7.9.5\n// @description  \uace0\uae09 \uae30\ub2a5\uc744 \uac16\ucd98 \uc6f9 \ud06c\ub864\ub7ec\ub85c \uac80\uc0c9 \uacb0\uacfc\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \uc218\uc9d1\ud558\uace0 \ud45c\uc2dc (\ub3d9\uc2dc \ud06c\ub864\ub9c1, \ubc88\uc5ed \uae30\ub2a5, UI \uac1c\uc120 \ub4f1)\n// @author       YourName\n// @match        *://www.google.com/search*\n// @match        *://www.bing.com/search*\n// @match        *://search.daum.net/search*\n// @match        *://search.naver.com/search*\n// @match        *://search.yahoo.com/search*\n// @match        *://duckduckgo.com/*\n// @match        *://www.ecosia.org/search*\n// @match        *://*.onion/*\n// @grant        GM_xmlhttpRequest\n// @grant        GM_addStyle\n// @grant        GM_setValue\n// @grant        GM_getValue\n// @grant        GM_notification\n// @connect      *\n// @require      https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js\n// @require      https://cdn.jsdelivr.net/npm/chart.js\n// @require      https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.14.0/Sortable.min.js\n// @require      https://cdnjs.cloudflare.com/ajax/libs/i18next/21.6.15/i18next.min.js\n// ==/UserScript==\n\n(function() {\n    'use strict';\n\n    // CSS \uc2a4\ud0c0\uc77c \ucd94\uac00 (UI \ub300\ud3ed \uac1c\uc120)\n    GM_addStyle(`\n        /* \ucee8\ud14c\uc774\ub108 \uc2a4\ud0c0\uc77c */\n        #crawler-container {\n            position: fixed;\n            top: 20px;\n            right: 20px;\n            background-color: #2c3e50;\n            border: 2px solid #1abc9c;\n            padding: 20px;\n            z-index: 10000;\n            width: 800px;\n            max-height: 85vh;\n            overflow: hidden;\n            box-shadow: 0 8px 30px rgba(0,0,0,0.5);\n            border-radius: 12px;\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            color: #ecf0f1;\n            display: flex;\n            flex-direction: column;\n            transition: all 0.3s ease;\n        }\n\n        /* \ud5e4\ub354 \uc2a4\ud0c0\uc77c */\n        #crawler-container header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 15px;\n        }\n\n        #crawler-container .title {\n            font-size: 20px;\n            font-weight: bold;\n        }\n\n        #crawler-container .close-btn {\n            cursor: pointer;\n            font-size: 24px;\n            color: #e74c3c;\n            transition: color 0.3s;\n        }\n\n        #crawler-container .close-btn:hover {\n            color: #c0392b;\n        }\n\n        /* \ud0ed \uc2a4\ud0c0\uc77c */\n        #crawler-container .tabs {\n            display: flex;\n            border-bottom: 2px solid #1abc9c;\n            margin-bottom: 15px;\n            overflow-x: auto;\n        }\n\n        #crawler-container .tab {\n            flex: 1;\n            text-align: center;\n            padding: 10px 0;\n            cursor: pointer;\n            background-color: #34495e;\n            border-right: 1px solid #1abc9c;\n            transition: background-color 0.3s, color 0.3s;\n            white-space: nowrap;\n        }\n\n        #crawler-container .tab:last-child {\n            border-right: none;\n        }\n\n        #crawler-container .tab.active {\n            background-color: #1abc9c;\n            color: #2c3e50;\n            font-weight: bold;\n        }\n\n        /* \ud0ed \ucf58\ud150\uce20 \uc2a4\ud0c0\uc77c */\n        #crawler-container .tab-content {\n            display: none;\n            flex: 1;\n            overflow-y: auto;\n        }\n\n        #crawler-container .tab-content.active {\n            display: block;\n        }\n\n        /* \ubc84\ud2bc \uc2a4\ud0c0\uc77c */\n        #crawler-container .controls button {\n            background-color: #1abc9c;\n            border: none;\n            color: #2c3e50;\n            padding: 10px 16px;\n            margin: 6px 3px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s, transform 0.2s;\n            font-size: 14px;\n            display: flex;\n            align-items: center;\n        }\n\n        #crawler-container .controls button:hover {\n            background-color: #16a085;\n            transform: translateY(-2px);\n        }\n\n        #crawler-container .controls button i {\n            margin-right: 6px;\n        }\n\n        /* \uccb4\ud06c\ubc15\uc2a4 \ubc0f \ub77c\ubca8 \uc2a4\ud0c0\uc77c */\n        #crawler-container .options label,\n        #crawler-container .filters label,\n        #crawler-container .exclude-domains label,\n        #crawler-container .advanced-options label {\n            display: flex;\n            align-items: center;\n            margin: 10px 0;\n            font-size: 14px;\n        }\n\n        #crawler-container .options input[type=\"checkbox\"] {\n            margin-right: 8px;\n            transform: scale(1.2);\n        }\n\n        /* \uc2a4\uc704\uce58 \uc2a4\ud0c0\uc77c */\n        .switch {\n            position: relative;\n            display: inline-block;\n            width: 50px;\n            height: 24px;\n            margin-left: 10px;\n        }\n\n        .switch input {\n            opacity: 0;\n            width: 0;\n            height: 0;\n        }\n\n        .switch .slider {\n            position: absolute;\n            cursor: pointer;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background-color: #ccc;\n            transition: 0.4s;\n            border-radius: 24px;\n        }\n\n        .switch .slider:before {\n            position: absolute;\n            content: \"\";\n            height: 18px;\n            width: 18px;\n            left: 3px;\n            bottom: 3px;\n            background-color: white;\n            transition: 0.4s;\n            border-radius: 50%;\n        }\n\n        .switch input:checked + .slider {\n            background-color: #1abc9c;\n        }\n\n        .switch input:checked + .slider:before {\n            transform: translateX(26px);\n        }\n\n        /* \uc785\ub825 \ud544\ub4dc \uc2a4\ud0c0\uc77c */\n        #crawler-container input[type=\"text\"],\n        #crawler-container input[type=\"number\"] {\n            width: 100%;\n            padding: 8px;\n            margin: 6px 0;\n            border: 1px solid #bdc3c7;\n            border-radius: 4px;\n            font-size: 14px;\n        }\n\n        /* \ud14c\uc774\ube14 \uc2a4\ud0c0\uc77c */\n        #resultsTable {\n            width: 100%;\n            border-collapse: collapse;\n            margin-top: 15px;\n        }\n\n        #resultsTable th, #resultsTable td {\n            border: 1px solid #95a5a6;\n            padding: 10px;\n            text-align: left;\n            font-size: 13px;\n        }\n\n        #resultsTable th {\n            background-color: #1abc9c;\n            color: #2c3e50;\n        }\n\n        #resultsTable tbody tr:nth-child(even) {\n            background-color: #34495e;\n        }\n\n        /* \ubc18\uc751\ud615 \ub514\uc790\uc778 */\n        @media (max-width: 900px) {\n            #crawler-container {\n                width: 90%;\n                right: 5%;\n                padding: 15px;\n            }\n\n            #crawler-container .controls button {\n                padding: 8px 12px;\n                font-size: 13px;\n            }\n\n            #crawler-container .title {\n                font-size: 18px;\n            }\n        }\n\n        /* Papago iframe \uc2a4\ud0c0\uc77c */\n        #papagoIframe {\n            width: 100%;\n            height: 100%;\n            border: none;\n        }\n\n        /* \ud31d\uc5c5 \uc2a4\ud0c0\uc77c */\n        .search-engines-popup, .manage-darkweb-popup {\n            position: absolute;\n            background-color: #2c3e50;\n            border: 1px solid #1abc9c;\n            padding: 15px;\n            border-radius: 8px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n            max-height: 350px;\n            overflow-y: auto;\n            z-index: 10001;\n        }\n\n        .search-engines-popup button, .manage-darkweb-popup button {\n            width: 100%;\n            text-align: left;\n            margin: 6px 0;\n            background-color: #34495e;\n            color: #ecf0f1;\n            border: none;\n            padding: 10px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 14px;\n        }\n\n        .search-engines-popup button:hover, .manage-darkweb-popup button:hover {\n            background-color: #1abc9c;\n            color: #2c3e50;\n        }\n\n        /* \ub85c\uadf8 \uc2a4\ud0c0\uc77c */\n        #log {\n            background-color: #34495e;\n            padding: 10px;\n            border-radius: 5px;\n            max-height: 200px;\n            overflow-y: auto;\n            font-size: 13px;\n            line-height: 1.4;\n        }\n\n        /* \ucc28\ud2b8 \ucee8\ud14c\uc774\ub108 */\n        .chart-container {\n            margin-top: 15px;\n            height: 250px;\n        }\n\n        /* HTML \ub514\uc2a4\ud50c\ub808\uc774 \uc2a4\ud0c0\uc77c */\n        .html-display iframe {\n            width: 100%;\n            height: 500px;\n            border: none;\n            border-radius: 5px;\n        }\n\n        /* Papago \ub514\uc2a4\ud50c\ub808\uc774 \uc2a4\ud0c0\uc77c */\n        .papago-display {\n            width: 100%;\n            height: 500px;\n            position: relative;\n        }\n\n        /* \ub2e4\ud06c\uc6f9 \uc5d4\uc9c4 \ubaa9\ub85d \uc2a4\ud0c0\uc77c */\n        #darkwebEnginesList li {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 12px;\n        }\n\n        #darkwebEnginesList li span {\n            flex: 1;\n            margin-right: 10px;\n            word-break: break-all;\n        }\n\n        #darkwebEnginesList li button {\n            background-color: #e74c3c;\n            border: none;\n            color: #fff;\n            padding: 6px 10px;\n            border-radius: 4px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n        }\n\n        #darkwebEnginesList li button:hover {\n            background-color: #c0392b;\n        }\n\n        /* \uc608\uc678 \ub3c4\uba54\uc778 \ub9ac\uc2a4\ud2b8 \uc2a4\ud0c0\uc77c */\n        .exclude-domains ul {\n            list-style: none;\n            padding: 0;\n            margin-top: 10px;\n        }\n\n        .exclude-domains ul li {\n            background-color: #34495e;\n            padding: 6px 10px;\n            border-radius: 4px;\n            margin-bottom: 6px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n\n        .exclude-domains ul li button {\n            background-color: #e74c3c;\n            border: none;\n            color: #fff;\n            padding: 4px 8px;\n            border-radius: 3px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 12px;\n        }\n\n        .exclude-domains ul li button:hover {\n            background-color: #c0392b;\n        }\n\n        /* Search Engines Direct UI */\n        #search-engines-direct {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 10px;\n            margin-top: 15px;\n        }\n\n        #search-engines-direct button {\n            flex: 1 1 45%;\n            background-color: #1abc9c;\n            border: none;\n            color: #2c3e50;\n            padding: 8px 12px;\n            border-radius: 5px;\n            cursor: pointer;\n            transition: background-color 0.3s;\n            font-size: 14px;\n        }\n\n        #search-engines-direct button:hover {\n            background-color: #16a085;\n        }\n\n        /* Preview Popup */\n        .preview-popup {\n            position: absolute;\n            background-color: #2c3e50;\n            border: 1px solid #1abc9c;\n            padding: 10px;\n            border-radius: 6px;\n            box-shadow: 0 4px 8px rgba(0,0,0,0.2);\n            width: 300px;\n            height: 150px;\n            z-index: 10002;\n            display: none;\n        }\n    `);\n\n    // UI \uc0dd\uc131 (\ub300\ud3ed \uac1c\uc120\ub41c \ub514\uc790\uc778)\n    const container = document.createElement('div');\n    container.id = 'crawler-container';\n    container.innerHTML = `\n        <header>\n            <span class=\"title\">\ud83d\udd25 \uc6f9 \ud06c\ub864\ub7ec 7.9.5</span>\n            <span class=\"close-btn\" title=\"\ub2eb\uae30\">&times;</span>\n        </header>\n        <div class=\"tabs\">\n            <div class=\"tab active\" data-tab=\"settings\">\uc124\uc815</div>\n            <div class=\"tab\" data-tab=\"results\">\uacb0\uacfc</div>\n            <div class=\"tab\" data-tab=\"logs\">\ub85c\uadf8</div>\n            <div class=\"tab\" data-tab=\"site-filters\">\uc0ac\uc774\ud2b8 \ud544\ud130</div>\n            <div class=\"tab\" data-tab=\"darkweb\">\ub2e4\ud06c\uc6f9</div>\n            <div class=\"tab\" data-tab=\"html-display\">HTML</div>\n            <div class=\"tab\" data-tab=\"papago\">Papago</div>\n            <div class=\"tab\" data-tab=\"search-engines\">\uac80\uc0c9 \uc5d4\uc9c4</div>\n        </div>\n        <div class=\"tab-content active\" id=\"settings\">\n            <!-- \uc81c\uc5b4 \ubc84\ud2bc -->\n            <div class=\"controls\">\n                <button id=\"startBtn\" title=\"\ud06c\ub864\ub9c1 \uc2dc\uc791\"><i>\u25b6\ufe0f</i> \uc2dc\uc791</button>\n                <button id=\"pauseBtn\" class=\"pause-btn\" title=\"\ud06c\ub864\ub9c1 \uc77c\uc2dc\uc815\uc9c0/\uc7ac\uac1c\"><i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0</button>\n                <button id=\"stopBtn\" title=\"\ud06c\ub864\ub9c1 \uc911\uc9c0\"><i>\u23f9\ufe0f</i> \uc911\uc9c0</button>\n                <button id=\"resetBtn\" title=\"\ud06c\ub864\ub9c1 \ucd08\uae30\ud654\"><i>\ud83d\udd04</i> \ucd08\uae30\ud654</button>\n                <button id=\"exportBtn\" class=\"export-btn\" title=\"\uacb0\uacfc \ub0b4\ubcf4\ub0b4\uae30\"><i>\ud83d\udcbe</i> \ub0b4\ubcf4\ub0b4\uae30</button>\n                <button id=\"searchEnginesBtn\" class=\"search-engines-btn\" title=\"\uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30\"><i>\ud83d\udd0d</i> \uac80\uc0c9 \uc5d4\uc9c4</button>\n            </div>\n            <!-- \uc635\uc158 \uc139\uc158 -->\n            <div class=\"options\">\n                <label><input type=\"checkbox\" id=\"toggleHTML\" checked> HTML \uac00\uc838\uc624\uae30</label>\n                <label><input type=\"checkbox\" id=\"toggleImages\" checked> \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30</label>\n                <label><input type=\"checkbox\" id=\"toggleAds\" checked> \uad11\uace0 \uc81c\uc678</label>\n                <label>\uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"strictSiteFilter\">\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n                <label>\ud544\ud130\ub9c1 \uae30\ub2a5 \ud65c\uc131\ud654\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"filteringToggle\" checked>\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n            </div>\n            <!-- \ud544\ud130 \uc139\uc158 -->\n            <div class=\"filters\">\n                <label for=\"filterInput\">\ud544\ud130 \ub2e8\uc5b4 (\uc815\uaddc\uc2dd, \uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"filterInput\" placeholder=\"\uc608: \uae30\ubd80, \uad11\uace0, /promo/i\">\n            </div>\n            <!-- \ub3c4\uba54\uc778 \uc81c\uc678 \uc139\uc158 -->\n            <div class=\"exclude-domains\">\n                <label for=\"excludeDomainsInput\">\uc81c\uc678\ud560 \ub3c4\uba54\uc778 (\uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"excludeDomainsInput\" placeholder=\"\uc608: facebook.com, youtube.com\">\n                <ul id=\"excludeDomainsList\"></ul>\n            </div>\n            <!-- \uace0\uae09 \uc635\uc158 \uc139\uc158 -->\n            <div class=\"advanced-options\">\n                <label for=\"duplicateThreshold\">\uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218:</label>\n                <input type=\"number\" id=\"duplicateThreshold\" value=\"5\" min=\"1\" style=\"width: 80px;\">\n            </div>\n            <!-- \uc81c\uc5b4 \uc635\uc158 \uc139\uc158 -->\n            <div class=\"controls\">\n                <label for=\"retryAttempts\">\uc7ac\uc2dc\ub3c4 \ud69f\uc218:</label>\n                <input type=\"number\" id=\"retryAttempts\" value=\"10\" min=\"1\" style=\"width: 80px;\">\n                <label for=\"retryInterval\">\uc7ac\uc2dc\ub3c4 \uac04\uaca9 (ms):</label>\n                <input type=\"number\" id=\"retryInterval\" value=\"100\" min=\"100\" style=\"width: 80px;\">\n            </div>\n            <!-- \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ud1a0\uae00 -->\n            <div class=\"controls\">\n                <label>\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9\n                    <label class=\"switch\">\n                        <input type=\"checkbox\" id=\"darkwebToggle\" checked>\n                        <span class=\"slider\"></span>\n                    </label>\n                </label>\n            </div>\n            <!-- \uc9c4\ud589\ub960 \ud45c\uc2dc \uc139\uc158 -->\n            <div class=\"progress-section\">\n                <progress id=\"progressBar\" value=\"0\" max=\"100\" style=\"width: 100%; height: 20px;\"></progress>\n                <span id=\"progressText\">\ud398\uc774\uc9c0 0</span>\n            </div>\n            <!-- \uc0c1\ud0dc \uc815\ubcf4 \uc139\uc158 -->\n            <div class=\"status\">\n                \ud604\uc7ac \ud398\uc774\uc9c0: <span id=\"currentPage\">0</span>\n                <br>\n                \ubc29\ubb38\ub41c \uc0ac\uc774\ud2b8: <span id=\"visitedCount\">0</span>\n                <br>\n                \uacbd\uacfc \uc2dc\uac04: <span id=\"elapsedTime\">00:00:00</span>\n                <br>\n                \uc608\uc0c1 \ub0a8\uc740 \uc2dc\uac04: <span id=\"remainingTime\">00:00:00</span>\n            </div>\n            <!-- \ucc28\ud2b8 \uc139\uc158 -->\n            <div class=\"chart-container\">\n                <canvas id=\"crawlChart\"></canvas>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"results\">\n            <div style=\"margin-top:15px; overflow: auto;\">\n                <table id=\"resultsTable\">\n                    <thead>\n                        <tr>\n                            <th>\uc0ac\uc774\ud2b8 \uc774\ub984</th>\n                            <th>\uc8fc\uc18c</th>\n                            <th>\uc124\uba85</th>\n                            <th>\uc774\ubbf8\uc9c0</th>\n                            <th>HTML \ub9c1\ud06c</th>\n                            <th>\ud398\uc774\uc9c0 \ub85c\ub529 \uc2dc\uac04 (ms)</th>\n                        </tr>\n                    </thead>\n                    <tbody id=\"resultsBody\">\n                    </tbody>\n                </table>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"logs\">\n            <div class=\"log\" id=\"log\">\n                <strong>\ub85c\uadf8:</strong><br>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"site-filters\">\n            <div class=\"site-filters\">\n                <label for=\"siteFilterInput\">\uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 (\uc815\uaddc\uc2dd, \uc27c\ud45c\ub85c \uad6c\ubd84):</label>\n                <input type=\"text\" id=\"siteFilterInput\" placeholder=\"\uc608: .*example\\\\.com.*, /^https?:\\\\/\\\\/.*\\\\.example\\\\.org$/\">\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"darkweb\">\n            <div class=\"darkweb-search\">\n                <label>\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00/\uad00\ub9ac</label>\n                <button class=\"add-darkweb-engine-btn\" title=\"\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00\"><i>\u2795</i> \ucd94\uac00</button>\n                <ul id=\"darkwebEnginesList\">\n                    <!-- \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ubaa9\ub85d -->\n                </ul>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"html-display\">\n            <div class=\"html-display\"></div>\n        </div>\n        <div class=\"tab-content\" id=\"papago\">\n            <div class=\"papago-display\">\n                <iframe id=\"papagoIframe\" src=\"https://papago.naver.com/\"></iframe>\n            </div>\n        </div>\n        <div class=\"tab-content\" id=\"search-engines\">\n            <div class=\"search-engines-direct\" id=\"search-engines-direct\">\n                <!-- \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30 \ubc84\ud2bc \ucd94\uac00 -->\n            </div>\n        </div>\n    `;\n    document.body.appendChild(container);\n\n    // \ub4dc\ub798\uadf8 \uac00\ub2a5\ud558\uac8c \uc124\uc815\n    (function makeDraggable(elmnt) {\n        const header = elmnt.querySelector('header');\n        const closeBtn = elmnt.querySelector('.close-btn');\n        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;\n        header.onmousedown = dragMouseDown;\n\n        closeBtn.onclick = () => {\n            elmnt.style.display = 'none';\n        }\n\n        function dragMouseDown(e) {\n            e = e || window.event;\n            e.preventDefault();\n            pos3 = e.clientX;\n            pos4 = e.clientY;\n            document.onmouseup = closeDragElement;\n            document.onmousemove = elementDrag;\n        }\n\n        function elementDrag(e) {\n            e = e || window.event;\n            e.preventDefault();\n            pos1 = pos3 - e.clientX;\n            pos2 = pos4 - e.clientY;\n            pos3 = e.clientX;\n            pos4 = e.clientY;\n            elmnt.style.top = (elmnt.offsetTop - pos2) + \"px\";\n            elmnt.style.left = (elmnt.offsetLeft - pos1) + \"px\";\n        }\n\n        function closeDragElement() {\n            document.onmouseup = null;\n            document.onmousemove = null;\n        }\n    })(container);\n\n    // \ud0ed \uae30\ub2a5 \uad6c\ud604\n    (function setupTabs() {\n        const tabs = container.querySelectorAll('.tab');\n        const tabContents = container.querySelectorAll('.tab-content');\n\n        tabs.forEach(tab => {\n            tab.addEventListener('click', () => {\n                tabs.forEach(t => t.classList.remove('active'));\n                tab.classList.add('active');\n\n                const target = tab.getAttribute('data-tab');\n                tabContents.forEach(content => {\n                    if(content.id === target){\n                        content.classList.add('active');\n                    } else {\n                        content.classList.remove('active');\n                    }\n                });\n            });\n        });\n    })();\n\n    // \ubcc0\uc218 \ucd08\uae30\ud654\n    let isRunning = false;\n    let isPaused = false;\n    let currentPage = 1;\n    let results = [];\n    let searchQuery = '';\n    let searchEngine = '';\n    let visitedLinks = new Map(); // \ub3c4\uba54\uc778\ubcc4 \ubc29\ubb38 \ud69f\uc218 \ucd94\uc801\n    let logMessages = [];\n    let filterPatterns = [];\n    let excludeDomains = [];\n    let siteFilterPatterns = [];\n    let duplicateThreshold = 5; // \uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218\n    let retryAttempts = 10; // \uc7ac\uc2dc\ub3c4 \ud69f\uc218\n    let retryInterval = 100; // \uc7ac\uc2dc\ub3c4 \uac04\uaca9 100ms\uc73c\ub85c \uc124\uc815\n    let startTime = null;\n    let elapsedInterval = null;\n    let crawlChart = null;\n    let crawlData = {\n        labels: [],  // \ub3c4\uba54\uc778 \uc774\ub984\n        datasets: [{\n            label: '\ubc29\ubb38 \ud69f\uc218',\n            data: [],\n            backgroundColor: 'rgba(46, 204, 113, 0.6)',\n            borderColor: 'rgba(46, 204, 113, 1)',\n            borderWidth: 1\n        }]\n    };\n    let filteringEnabled = true; // \ud544\ud130\ub9c1 \ud65c\uc131\ud654 \uc5ec\ubd80\n    let concurrentRequests = 40; // \ub3d9\uc2dc \uc694\uccad \uc218 40\uc73c\ub85c \uc124\uc815\n    let currentRequests = 0; // \ud604\uc7ac \uc694\uccad \uc218\n    let requestQueue = []; // \uc694\uccad \ub300\uae30\uc5f4\n    let translateLanguage = 'en'; // \uae30\ubcf8 \ubc88\uc5ed \uc5b8\uc5b4\n    let darkwebEnabled = true; // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9 \uc5ec\ubd80\n\n    // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ubaa9\ub85d (\uae30\ubcf8 \uc5d4\uc9c4 \ucd94\uac00 \ubc0f \ud655\uc7a5)\n    const defaultDarkwebEngines = [\n        { name: 'Torch', url: 'http://xmh57jrzrnw6insl.onion/' },\n        { name: 'Ahmia', url: 'http://msydqstlz2kzerdg.onion/' },\n        { name: 'Haystak', url: 'http://haystakvxad7wbk5.onion/' },\n        { name: 'Not Evil', url: 'http://hss3uro2hsxfogfq.onion/' },\n        { name: 'Phobos', url: 'http://phobos6uj4abm4pf.onion/' },\n        { name: 'Kilos', url: 'http://kilos7wbfn3ptgw.onion/' },\n        { name: 'Candle', url: 'http://zg6ak7qqfhbkbppx.onion/' },\n        { name: 'DarkSearch', url: 'http://darksearch3w3nrc.onion/' },\n        { name: 'Dark Falcon', url: 'http://darkfalconphp5fh.onion/' },\n        { name: 'SearXNG', url: 'http://searxngueyn5qzuv.onion/' },\n        { name: 'DuckDuckGo (onion)', url: 'http://duckduckgogj7ay7.onion/' },\n        { name: 'Phobos 2', url: 'http://phobos2uj4abm4pf.onion/' },\n        { name: 'IntelligenceX', url: 'http://intelligencexmh5v.onion/' },\n        { name: 'Silk Road 3.1', url: 'http://silkroad31lo5ya.onion/' },\n        { name: 'Fresh Onions', url: 'http://rx7hmtf7k7xk6ked.onion/' },\n        // \ucd94\uac00 \uc5d4\uc9c4 \uac00\ub2a5\n        { name: 'Dark Web Link', url: 'http://darkweblink5wqk.onion/' },\n        { name: 'Tor Tracker', url: 'http://tortracker5ujzra.onion/' },\n        { name: 'Deep Web Search', url: 'http://deepwebsearch6b6x.onion/' },\n        { name: 'Onion Monitor', url: 'http://onionmonitor3c7v.onion/' },\n        { name: 'Hidden Wiki', url: 'http://hiddenwiki5z35.onion/' },\n        { name: 'TorEX', url: 'http://torexk3wd2buz.onion/' },\n        { name: 'BlackBook', url: 'http://blackbook51uv.onion/' },\n        { name: 'Taboo Search', url: 'http://taboosearch37b.onion/' },\n        { name: 'The Pirate Bay (onion)', url: 'http://uj3wazyk5u4hnvtk.onion/' },\n        // \ub354 \ub9ce\uc740 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc744 \ucd94\uac00\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n    ];\n\n    // \ubc84\ud2bc \ubc0f \uc694\uc18c \uac00\uc838\uc624\uae30\n    const startBtn = document.getElementById('startBtn');\n    const pauseBtn = document.getElementById('pauseBtn');\n    const stopBtn = document.getElementById('stopBtn');\n    const resetBtn = document.getElementById('resetBtn');\n    const exportBtn = document.getElementById('exportBtn');\n    const searchEnginesBtn = document.getElementById('searchEnginesBtn');\n    const progressBar = document.getElementById('progressBar');\n    const progressText = document.getElementById('progressText');\n    const resultsBody = document.getElementById('resultsBody');\n    const logContainer = document.getElementById('log');\n    const currentPageElem = document.getElementById('currentPage');\n    const toggleHTML = document.getElementById('toggleHTML');\n    const toggleImages = document.getElementById('toggleImages');\n    const toggleAds = document.getElementById('toggleAds');\n    const filterInput = document.getElementById('filterInput');\n    const excludeDomainsInput = document.getElementById('excludeDomainsInput');\n    const excludeDomainsList = document.getElementById('excludeDomainsList');\n    const siteFilterInput = document.getElementById('siteFilterInput');\n    const duplicateThresholdInput = document.getElementById('duplicateThreshold');\n    const retryAttemptsInput = document.getElementById('retryAttempts');\n    const retryIntervalInput = document.getElementById('retryInterval');\n    const strictSiteFilter = document.getElementById('strictSiteFilter');\n    const visitedCountElem = document.getElementById('visitedCount');\n    const elapsedTimeElem = document.getElementById('elapsedTime');\n    const remainingTimeElem = document.getElementById('remainingTime');\n    const crawlChartCtx = document.getElementById('crawlChart').getContext('2d');\n    const filteringToggle = document.getElementById('filteringToggle');\n    const darkwebEnginesList = document.getElementById('darkwebEnginesList');\n    const addDarkwebEngineBtn = container.querySelector('.add-darkweb-engine-btn');\n    const darkwebToggle = document.getElementById('darkwebToggle');\n    const papagoIframe = document.getElementById('papagoIframe');\n    const searchEnginesDirect = document.getElementById('search-engines-direct');\n\n    // \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n    startBtn.addEventListener('click', startCrawling);\n    pauseBtn.addEventListener('click', togglePause);\n    stopBtn.addEventListener('click', stopCrawling);\n    resetBtn.addEventListener('click', resetCrawling);\n    exportBtn.addEventListener('click', exportResults);\n    searchEnginesBtn.addEventListener('click', openSearchEngines);\n    filterInput.addEventListener('input', updateFilterPatterns);\n    excludeDomainsInput.addEventListener('keydown', function(e) {\n        if (e.key === 'Enter') {\n            addExcludeDomain();\n        }\n    });\n    addDarkwebEngineBtn.addEventListener('click', addDarkwebEngine);\n    siteFilterInput.addEventListener('input', updateSiteFilterPatterns);\n    duplicateThresholdInput.addEventListener('change', updateDuplicateThreshold);\n    retryAttemptsInput.addEventListener('change', updateRetryAttempts);\n    retryIntervalInput.addEventListener('change', updateRetryInterval);\n    strictSiteFilter.addEventListener('change', updateStrictSiteFilter);\n    filteringToggle.addEventListener('change', toggleFiltering);\n    darkwebToggle.addEventListener('change', toggleDarkweb);\n    papagoIframe.addEventListener('load', () => {\n        log('\ud83c\udf10 Papago \ubc88\uc5ed\uae30 \ub85c\ub4dc \uc644\ub8cc.');\n    });\n\n    // \ud398\uc774\uc9c0 \uc0c8\ub85c \uace0\uce68 \uc2dc \ud06c\ub864\ub9c1 \ucd08\uae30\ud654\n    window.addEventListener('beforeunload', () => {\n        resetCrawling();\n    });\n\n    // \ucd08\uae30\ud654 \ub85c\ub4dc\n    loadLogs();\n    loadCrawlData();\n    loadDarkwebEngines();\n    loadExcludeDomains();\n    loadSearchEnginesDirect();\n\n    // \ucc28\ud2b8 \ucd08\uae30\ud654\n    function initializeChart() {\n        crawlChart = new Chart(crawlChartCtx, {\n            type: 'bar',\n            data: crawlData,\n            options: {\n                responsive: true,\n                maintainAspectRatio: false,\n                scales: {\n                    y: { beginAtZero: true },\n                    x: { ticks: { autoSkip: false } }\n                },\n                plugins: {\n                    legend: {\n                        display: false\n                    },\n                    tooltip: {\n                        enabled: true\n                    }\n                }\n            }\n        });\n    }\n    initializeChart();\n\n    // \ub85c\uae45 \ud568\uc218\n    function log(message) {\n        const time = new Date().toLocaleTimeString();\n        const entry = `[${time}] ${message}`;\n        logMessages.push(entry);\n        logContainer.innerHTML += `${entry}<br>`;\n        logContainer.scrollTop = logContainer.scrollHeight;\n        // \uc800\uc7a5\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n    }\n\n    function loadLogs() {\n        const storedLogs = GM_getValue('crawlerLogs', []);\n        if (storedLogs.length > 0) {\n            logMessages = JSON.parse(storedLogs);\n            logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>` + logMessages.join('<br>');\n            logContainer.scrollTop = logContainer.scrollHeight;\n        }\n    }\n\n    function updateFilterPatterns() {\n        if (!filteringEnabled) {\n            filterPatterns = [];\n            log(`\ud83d\udee0 \ud544\ud130\ub9c1 \uae30\ub2a5 \ube44\ud65c\uc131\ud654\ub428.`);\n            return;\n        }\n        const input = filterInput.value.trim();\n        filterPatterns = input ? input.split(',').map(word => {\n            word = word.trim();\n            if (word.startsWith('/') && word.endsWith('/')) {\n                try {\n                    return new RegExp(word.slice(1, -1), 'i');\n                } catch (e) {\n                    log(`\u26a0\ufe0f \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc815\uaddc\uc2dd: ${word}`);\n                    return null;\n                }\n            } else {\n                return new RegExp(word, 'i');\n            }\n        }).filter(regex => regex !== null) : [];\n        log(`\ud83d\udee0 \ud544\ud130 \ud328\ud134 \uc5c5\ub370\uc774\ud2b8: [${filterPatterns.map(r => r.toString()).join(', ')}]`);\n    }\n\n    function updateExcludeDomains() {\n        // \uc774 \ud568\uc218\ub294 \uc81c\uc678 \ub3c4\uba54\uc778\uc774 \ucd94\uac00\ub420 \ub54c\ub9c8\ub2e4 \ud638\ucd9c\ub428\n        log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \uc5c5\ub370\uc774\ud2b8 \uc644\ub8cc.`);\n    }\n\n    function addExcludeDomain() {\n        const domain = excludeDomainsInput.value.trim().toLowerCase();\n        if (domain && !excludeDomains.includes(domain)) {\n            excludeDomains.push(domain);\n            renderExcludeDomains();\n            excludeDomainsInput.value = '';\n            log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \ucd94\uac00: ${domain}`);\n        }\n    }\n\n    function renderExcludeDomains() {\n        excludeDomainsList.innerHTML = '';\n        excludeDomains.forEach((domain, index) => {\n            const li = document.createElement('li');\n            li.innerHTML = `\n                <span>${escapeHTML(domain)}</span>\n                <button data-index=\"${index}\">\u2716\ufe0f</button>\n            `;\n            excludeDomainsList.appendChild(li);\n        });\n        // \uc0ad\uc81c \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        excludeDomainsList.querySelectorAll('button').forEach(btn => {\n            btn.addEventListener('click', () => {\n                const index = parseInt(btn.getAttribute('data-index'));\n                if (!isNaN(index)) {\n                    const removed = excludeDomains.splice(index, 1);\n                    renderExcludeDomains();\n                    log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \uc81c\uac70: ${removed}`);\n                }\n            });\n        });\n    }\n\n    function loadExcludeDomains() {\n        const storedDomains = GM_getValue('excludeDomains', []);\n        excludeDomains = storedDomains.length > 0 ? storedDomains : [];\n        renderExcludeDomains();\n    }\n\n    function updateSiteFilterPatterns() {\n        const input = siteFilterInput.value.trim();\n        siteFilterPatterns = input ? input.split(',').map(pattern => {\n            pattern = pattern.trim();\n            if (pattern.startsWith('/') && pattern.endsWith('/')) {\n                try {\n                    return new RegExp(pattern.slice(1, -1), 'i');\n                } catch (e) {\n                    log(`\u26a0\ufe0f \uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc774\ud2b8 \ud544\ud130 \uc815\uaddc\uc2dd: ${pattern}`);\n                    return null;\n                }\n            } else {\n                return new RegExp(pattern, 'i');\n            }\n        }).filter(regex => regex !== null) : [];\n        log(`\ud83d\udee0 \uc0ac\uc774\ud2b8 \ud544\ud130 \ud328\ud134 \uc5c5\ub370\uc774\ud2b8: [${siteFilterPatterns.map(r => r.toString()).join(', ')}]`);\n    }\n\n    function updateDuplicateThreshold() {\n        const value = parseInt(duplicateThresholdInput.value);\n        duplicateThreshold = isNaN(value) || value < 1 ? 5 : value;\n        log(`\ud83d\udd04 \uc911\ubcf5 \ud5c8\uc6a9 \ud69f\uc218 \uc124\uc815: ${duplicateThreshold}`);\n    }\n\n    function updateRetryAttempts() {\n        const value = parseInt(retryAttemptsInput.value);\n        retryAttempts = isNaN(value) || value < 1 ? 10 : value;\n        log(`\ud83d\udd04 \uc7ac\uc2dc\ub3c4 \ud69f\uc218 \uc124\uc815: ${retryAttempts}`);\n    }\n\n    function updateRetryInterval() {\n        const value = parseInt(retryIntervalInput.value);\n        retryInterval = isNaN(value) || value < 100 ? 100 : value; // \ucd5c\uc18c \uac12 100ms\uc73c\ub85c \uc124\uc815\n        log(`\ud83d\udd04 \uc7ac\uc2dc\ub3c4 \uac04\uaca9 \uc124\uc815: ${retryInterval}ms`);\n    }\n\n    function updateStrictSiteFilter() {\n        const isStrict = strictSiteFilter.checked;\n        log(`\ud83d\udd04 \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc124\uc815: ${isStrict ? 'ON' : 'OFF'}`);\n    }\n\n    function toggleFiltering() {\n        filteringEnabled = filteringToggle.checked;\n        if (filteringEnabled) {\n            log('\ud83d\udd04 \ud544\ud130\ub9c1 \uae30\ub2a5 \ud65c\uc131\ud654\ub428.');\n            updateFilterPatterns();\n        } else {\n            filterPatterns = [];\n            log('\ud83d\udd04 \ud544\ud130\ub9c1 \uae30\ub2a5 \ube44\ud65c\uc131\ud654\ub428.');\n        }\n    }\n\n    function toggleDarkweb() {\n        darkwebEnabled = darkwebToggle.checked;\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc0ac\uc6a9 \uc124\uc815: ${darkwebEnabled ? 'ON' : 'OFF'}`);\n    }\n\n    function getSearchQueryAndEngine() {\n        const url = window.location.href;\n        if (url.includes('google.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'google';\n        } else if (url.includes('bing.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'bing';\n        } else if (url.includes('daum.net/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'daum';\n        } else if (url.includes('search.naver.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('query') || '';\n            searchEngine = 'naver';\n        } else if (url.includes('search.yahoo.com/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('p') || '';\n            searchEngine = 'yahoo';\n        } else if (url.includes('duckduckgo.com/')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'duckduckgo';\n        } else if (url.includes('ecosia.org/search')) {\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            searchEngine = 'ecosia';\n        } else if (url.includes('.onion')) {\n            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc911 \ud558\ub098\ub85c \uc124\uc815\n            searchEngine = 'darkweb';\n            const params = new URLSearchParams(window.location.search);\n            searchQuery = params.get('q') || '';\n            if (!searchQuery) {\n                searchQuery = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694:');\n            }\n        } else {\n            searchQuery = '';\n            searchEngine = '';\n        }\n        log(`\ud83d\udd0d \uac80\uc0c9 \uc5d4\uc9c4: ${searchEngine}, \uac80\uc0c9\uc5b4: \"${searchQuery}\"`);\n    }\n\n    async function startCrawling() {\n        if (isRunning) {\n            alert('\uc774\ubbf8 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589 \uc911\uc785\ub2c8\ub2e4.');\n            return;\n        }\n        getSearchQueryAndEngine();\n        if (!searchQuery) {\n            alert('\ud604\uc7ac \ud398\uc774\uc9c0\uc5d0\uc11c \uac80\uc0c9\uc5b4\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            log('\u26a0\ufe0f \uac80\uc0c9\uc5b4 \ubbf8\uc785\ub825 \ub610\ub294 \uc778\uc2dd \uc2e4\ud328.');\n            return;\n        }\n        isRunning = true;\n        isPaused = false;\n        currentPage = 1;\n        results = [];\n        visitedLinks.clear();\n        resultsBody.innerHTML = '';\n        visitedCountElem.innerText = '0';\n        elapsedTimeElem.innerText = '00:00:00';\n        remainingTimeElem.innerText = '00:00:00';\n        logMessages = [];\n        logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>`;\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n        log('\u2705 \ud06c\ub864\ub9c1\uc744 \uc2dc\uc791\ud569\ub2c8\ub2e4.');\n        updateDuplicateThreshold();\n        updateRetryAttempts();\n        updateRetryInterval();\n        await enqueueCrawlPages(concurrentRequests); // \ub3d9\uc2dc \uc694\uccad \uc218 40\uc73c\ub85c \uc124\uc815\n        startTime = Date.now();\n        elapsedInterval = setInterval(updateElapsedTime, 1000);\n    }\n\n    function togglePause() {\n        if (!isRunning) {\n            alert('\uc77c\uc2dc\uc815\uc9c0/\uc7ac\uac1c\ud560 \ud06c\ub864\ub9c1\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        isPaused = !isPaused;\n        if (isPaused) {\n            log('\u23f8\ufe0f \ud06c\ub864\ub9c1\uc744 \uc77c\uc2dc\uc815\uc9c0\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n            pauseBtn.innerHTML = '<i>\u25b6\ufe0f</i> \uc7ac\uac1c';\n        } else {\n            log('\u25b6\ufe0f \ud06c\ub864\ub9c1\uc744 \uc7ac\uac1c\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n            pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n            processQueue();\n        }\n    }\n\n    function stopCrawling() {\n        if (!isRunning) {\n            alert('\uc911\uc9c0\ud560 \ud06c\ub864\ub9c1\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        isRunning = false;\n        isPaused = false;\n        pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n        clearInterval(elapsedInterval);\n        updateProgress();\n        log('\ud83d\udeab \ud06c\ub864\ub9c1\uc744 \uc911\uc9c0\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n        GM_notification({\n            text: '\ud06c\ub864\ub9c1\uc774 \uc911\uc9c0\ub418\uc5c8\uc2b5\ub2c8\ub2e4.',\n            title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n            timeout: 3000\n        });\n    }\n\n    async function enqueueCrawlPages(limit) {\n        for (let i = 0; i < limit; i++) {\n            queueCrawlPage();\n        }\n    }\n\n    function queueCrawlPage() {\n        if (!isRunning || isPaused) return;\n        if (currentRequests >= concurrentRequests) return;\n\n        // Assign a unique page number before starting the crawl\n        const pageToCrawl = currentPage++;\n        currentPageElem.innerText = currentPage;\n\n        currentRequests++;\n        crawlPage(pageToCrawl).then(() => {\n            currentRequests--;\n            queueCrawlPage();\n        });\n    }\n\n    async function crawlPage(page) {\n        if (!isRunning || isPaused) {\n            return;\n        }\n\n        // \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub530\ub978 URL \uad6c\uc131\n        let url = '';\n        if (searchEngine === 'google') {\n            url = `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}&start=${(page-1)*10}`;\n        } else if (searchEngine === 'bing') {\n            url = `https://www.bing.com/search?q=${encodeURIComponent(searchQuery)}&first=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'daum') {\n            url = `https://search.daum.net/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'naver') {\n            url = `https://search.naver.com/search.naver?query=${encodeURIComponent(searchQuery)}&start=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'yahoo') {\n            url = `https://search.yahoo.com/search?p=${encodeURIComponent(searchQuery)}&b=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'duckduckgo') {\n            url = `https://duckduckgo.com/html/?q=${encodeURIComponent(searchQuery)}&s=${(page-1)*10}`;\n        } else if (searchEngine === 'ecosia') {\n            url = `https://www.ecosia.org/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'darkweb') {\n            if (!darkwebEnabled) {\n                log('\ud83d\uded1 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc774 \ube44\ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.');\n                isRunning = false;\n                return;\n            }\n            const darkwebEngines = getDarkwebEngines();\n            if (darkwebEngines.length === 0) {\n                log('\u26a0\ufe0f \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n                isRunning = false;\n                return;\n            }\n            const randomEngine = darkwebEngines[Math.floor(Math.random() * darkwebEngines.length)];\n            url = `${randomEngine.url}/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else {\n            alert('\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uac80\uc0c9 \uc5d4\uc9c4\uc785\ub2c8\ub2e4.');\n            log('\u274c \uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uac80\uc0c9 \uc5d4\uc9c4.');\n            isRunning = false;\n            return;\n        }\n\n        log(`\ud83d\udcc4 \ud398\uc774\uc9c0 ${page} \ud06c\ub864\ub9c1 \uc911: ${url}`);\n\n        return new Promise((resolve) => {\n            GM_xmlhttpRequest({\n                method: \"GET\",\n                url: url,\n                headers: {\n                    \"User-Agent\": navigator.userAgent,\n                    \"Accept\": \"text/html\"\n                },\n                onload: async function(response) {\n                    if (response.status !== 200) {\n                        log(`\u274c \ud398\uc774\uc9c0 ${page} \ub85c\ub4dc \uc2e4\ud328: \uc0c1\ud0dc ${response.status}`);\n                        await handleCrawlError(page, retryAttempts);\n                        resolve();\n                        return;\n                    }\n\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(response.responseText, 'text/html');\n                    let items = [];\n                    if (searchEngine === 'google') {\n                        items = doc.querySelectorAll('div.g');\n                    } else if (searchEngine === 'bing') {\n                        items = doc.querySelectorAll('li.b_algo');\n                    } else if (searchEngine === 'daum') {\n                        items = doc.querySelectorAll('div.wrap_cont');\n                    } else if (searchEngine === 'naver') {\n                        items = doc.querySelectorAll('div.basic1');\n                    } else if (searchEngine === 'yahoo') {\n                        items = doc.querySelectorAll('div.compTitle');\n                    } else if (searchEngine === 'duckduckgo') {\n                        items = doc.querySelectorAll('div.result');\n                    } else if (searchEngine === 'ecosia') {\n                        items = doc.querySelectorAll('div.result');\n                    } else if (searchEngine === 'darkweb') {\n                        // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc911 \ud558\ub098\ub85c \uc124\uc815 (\uc608: Torch \uae30\uc900)\n                        items = doc.querySelectorAll('.result'); // \uc2e4\uc81c \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub9de\uac8c \uc870\uc815 \ud544\uc694\n                    }\n\n                    // \ub9cc\uc57d \uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\ub2e4\uba74 \ud06c\ub864\ub9c1 \uc885\ub8cc\n                    if (items.length === 0) {\n                        log('\ud83d\udd0d \ub354 \uc774\uc0c1 \ud06c\ub864\ub9c1\ud560 \ud398\uc774\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \ud06c\ub864\ub9c1\uc744 \uc885\ub8cc\ud569\ub2c8\ub2e4.');\n                        isRunning = false;\n                        isPaused = false;\n                        pauseBtn.innerHTML = '<i>\u23f8\ufe0f</i> \uc77c\uc2dc\uc815\uc9c0';\n                        clearInterval(elapsedInterval);\n                        updateProgress();\n                        GM_notification({\n                            text: '\ud06c\ub864\ub9c1\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.',\n                            title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                            timeout: 3000\n                        });\n                        resolve();\n                        return;\n                    }\n\n                    log(`\ud83d\udcca \ud398\uc774\uc9c0 ${page}\uc5d0\uc11c ${items.length}\uac1c \ud56d\ubaa9 \ubc1c\uacac.`);\n\n                    // \ubcd1\ub82c \ucc98\ub9ac: Promise.all\uc744 \uc774\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30\uc801\uc73c\ub85c \ucc98\ub9ac\n                    const itemPromises = Array.from(items).map(async (item) => {\n                        let title = 'N/A';\n                        let link = 'N/A';\n                        let description = 'N/A';\n                        let image = 'N/A';\n                        let htmlLink = '\ube44\ud65c\uc131\ud654';\n                        let pageLoadTime = 'N/A';\n\n                        // \uac01 \uac80\uc0c9 \uc5d4\uc9c4\uc5d0 \ub530\ub978 \ub370\uc774\ud130 \ucd94\ucd9c\n                        if (searchEngine === 'google') {\n                            const titleElem = item.querySelector('h3');\n                            const linkElem = item.querySelector('a');\n                            const descElem = item.querySelector('.IsZvec') || item.querySelector('.VwiC3b');\n                            if (titleElem) title = titleElem.innerText;\n                            if (linkElem) link = linkElem.href;\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'bing') {\n                            const titleElem = item.querySelector('h2 a');\n                            const descElem = item.querySelector('p');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'daum') {\n                            const titleElem = item.querySelector('a.link_fax');\n                            const descElem = item.querySelector('div.cont_inner');\n                            if (titleElem) {\n                                title = titleElem.innerText.trim();\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText.trim();\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'naver') {\n                            const titleElem = item.querySelector('a.tit');\n                            const descElem = item.querySelector('div.desc');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.thumb');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'yahoo') {\n                            const titleElem = item.querySelector('h3');\n                            const linkElem = item.querySelector('a');\n                            const descElem = item.querySelector('div.compText');\n                            if (titleElem) title = titleElem.innerText;\n                            if (linkElem) link = linkElem.href;\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'duckduckgo') {\n                            const titleElem = item.querySelector('a.result__a');\n                            const descElem = item.querySelector('a.result__snippet');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.result__thumbnail');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'ecosia') {\n                            const titleElem = item.querySelector('a.result-title');\n                            const descElem = item.querySelector('div.result-description');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img.result-image');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        } else if (searchEngine === 'darkweb') {\n                            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uacb0\uacfc \ucd94\ucd9c (\uc608: Torch \uae30\uc900)\n                            const titleElem = item.querySelector('a');\n                            const descElem = item.querySelector('p');\n                            if (titleElem) {\n                                title = titleElem.innerText;\n                                link = titleElem.href;\n                            }\n                            if (descElem) description = descElem.innerText;\n\n                            // \uc774\ubbf8\uc9c0 \uac00\uc838\uc624\uae30 (\uac00\ub2a5\ud55c \uacbd\uc6b0)\n                            const imgElem = item.querySelector('img');\n                            if (imgElem && imgElem.src) {\n                                image = `<img src=\"${imgElem.src}\" alt=\"\uc774\ubbf8\uc9c0\" style=\"max-width: 80px; max-height: 80px;\">`;\n                            }\n\n                            // HTML \ubcf4\uae30 \ub9c1\ud06c\n                            if (toggleHTML.checked && link !== 'N/A') {\n                                htmlLink = `<button class=\"html-btn\" data-url=\"${encodeURIComponent(link)}\">\ubcf4\uae30</button>`;\n                            }\n                        }\n\n                        // \uad11\uace0 \uc81c\uc678 \uae30\ub2a5 \uc801\uc6a9\n                        if (toggleAds.checked) {\n                            const combinedText = `${title} ${description}`.toLowerCase();\n                            const isAd = combinedText.includes('advertisement') || combinedText.includes('\uad11\uace0');\n                            if (isAd) {\n                                log(`\ud83d\udeab \uad11\uace0 \ud56d\ubaa9 \uc81c\uc678: \"${title}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \ud544\ud130 \ub2e8\uc5b4 \uc801\uc6a9\n                        if (filterPatterns.length > 0) {\n                            const combinedText = `${title} ${description}`.toLowerCase();\n                            const isFiltered = filterPatterns.some(regex => regex.test(combinedText));\n                            if (isFiltered) {\n                                log(`\u274c \ud544\ud130 \ub2e8\uc5b4 \ud3ec\ud568 \ud56d\ubaa9 \uc81c\uc678: \"${title}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc801\uc6a9 (\uc0ac\uc774\ud2b8 \uc81c\ubaa9 \ub610\ub294 HTML \ub0b4\uc6a9 \uae30\ubc18)\n                        if (siteFilterPatterns.length > 0) {\n                            const isSiteFiltered = siteFilterPatterns.some(regex => regex.test(link) || regex.test(title));\n                            if (isSiteFiltered) {\n                                log(`\ud83d\udeab \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\uc5d0 \uc758\ud574 \uc81c\uc678\ub41c \ud56d\ubaa9: \"${link}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \ub3c4\uba54\uc778 \ucd94\ucd9c\n                        const domain = extractDomain(link);\n                        if (!domain) return null;\n\n                        // \uc81c\uc678 \ub3c4\uba54\uc778 \uac80\uc0ac\n                        if (excludeDomains.includes(domain.toLowerCase())) {\n                            log(`\ud83d\udeab \uc81c\uc678 \ub3c4\uba54\uc778 \ud56d\ubaa9 \uc81c\uc678: \"${link}\"`);\n                            return null;\n                        }\n\n                        // \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1 \uc801\uc6a9\n                        if (strictSiteFilter.checked) {\n                            if (!siteFilterPatterns.some(regex => regex.test(link) || regex.test(title))) {\n                                log(`\ud83d\udeab \uc5c4\uaca9 \uc0ac\uc774\ud2b8 \ud544\ud130\ub9c1\uc5d0 \uc758\ud574 \uc81c\uc678\ub41c \ud56d\ubaa9: \"${link}\"`);\n                                return null;\n                            }\n                        }\n\n                        // \uc911\ubcf5 \uac80\uc0ac (\ub3c4\uba54\uc778\ubcc4 \ubc29\ubb38 \ud69f\uc218)\n                        let visitCount = visitedLinks.get(domain) || 0;\n                        if (visitCount >= duplicateThreshold) {\n                            log(`\ud83d\udd04 \uc911\ubcf5 \ubc29\ubb38 \uc81c\ud55c: \"${domain}\"`);\n                            return null;\n                        }\n\n                        // \ubc29\ubb38 \ud69f\uc218 \uc5c5\ub370\uc774\ud2b8\n                        visitedLinks.set(domain, visitCount + 1);\n                        visitedCountElem.innerText = visitedLinks.size.toString();\n\n                        // \ud398\uc774\uc9c0 \ub85c\ub529 \uc2dc\uac04 \uce21\uc815\n                        const loadStart = performance.now();\n                        try {\n                            // mode: 'cors'\ub85c \ubcc0\uacbd\ud558\uc5ec \uc2e4\uc81c \uc751\ub2f5\uc744 \ubc1b\uc744 \uc218 \uc788\ub3c4\ub85d \ud568\n                            const fetchResponse = await fetch(link, { mode: 'cors' });\n                            if (fetchResponse.ok) {\n                                const loadEnd = performance.now();\n                                pageLoadTime = Math.round(loadEnd - loadStart);\n                            } else {\n                                pageLoadTime = '\uc751\ub2f5 \ubd88\ub7c9';\n                            }\n                        } catch (err) {\n                            pageLoadTime = '\uacc4\uc0b0 \ubd88\uac00';\n                        }\n\n                        // HTML \uc635\uc158\n                        if (!toggleHTML.checked) {\n                            htmlLink = '\ube44\ud65c\uc131\ud654';\n                        }\n\n                        // \uc774\ubbf8\uc9c0 \uc635\uc158\n                        if (!toggleImages.checked) {\n                            image = '\ube44\ud65c\uc131\ud654';\n                        }\n\n                        const result = { title, link, description, image, htmlLink, pageLoadTime };\n                        results.push(result);\n\n                        // \uacb0\uacfc \ud14c\uc774\ube14\uc5d0 \ucd94\uac00\n                        const row = document.createElement('tr');\n                        row.innerHTML = `\n                            <td>${escapeHTML(title)}</td>\n                            <td><a href=\"${escapeHTML(link)}\" target=\"_blank\">${escapeHTML(link)}</a></td>\n                            <td>${escapeHTML(description)}</td>\n                            <td>${image}</td>\n                            <td>${htmlLink}</td>\n                            <td>${pageLoadTime}</td>\n                        `;\n                        resultsBody.appendChild(row);\n\n                        return result;\n                    });\n\n                    // Promise.all\uc744 \ud1b5\ud574 \ubaa8\ub4e0 \ud56d\ubaa9 \ucc98\ub9ac \uc644\ub8cc \ub300\uae30\n                    await Promise.all(itemPromises);\n\n                    // \ub370\uc774\ud130 \uc2dc\uac01\ud654 \uc5c5\ub370\uc774\ud2b8\n                    updateChart();\n\n                    // \uc9c4\ud589\ub960 \uc5c5\ub370\uc774\ud2b8\n                    updateProgress();\n\n                    // \ub300\uae30 \uc2dc\uac04 \ucd94\uac00\ud558\uc5ec \uc11c\ubc84\uc5d0 \ubd80\ub2f4 \uc8fc\uc9c0 \uc54a\uae30\n                    setTimeout(() => {\n                        queueCrawlPage();\n                    }, isPaused ? 0 : 1000); // 1\ucd08 \ub300\uae30\n\n                    resolve();\n                },\n                onerror: function() {\n                    log(`\u274c \ud398\uc774\uc9c0 ${page} \uc694\uccad \uc911 \uc624\ub958 \ubc1c\uc0dd.`);\n                    handleCrawlError(page, retryAttempts).then(() => {\n                        resolve();\n                    });\n                }\n            });\n        });\n    }\n\n    async function handleCrawlError(page, retriesLeft) {\n        if (retriesLeft > 0 && isRunning) {\n            log(`\ud83d\udd04 \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 (${retriesLeft}\ud68c \ub0a8\uc74c).`);\n            return new Promise((resolve) => {\n                setTimeout(() => {\n                    const url = constructURL(page);\n                    if (!url) {\n                        log(`\u274c \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 \uc2e4\ud328: URL\uc774 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.`);\n                        resolve();\n                        return;\n                    }\n                    GM_xmlhttpRequest({\n                        method: \"GET\",\n                        url: url,\n                        headers: {\n                            \"User-Agent\": navigator.userAgent,\n                            \"Accept\": \"text/html\"\n                        },\n                        onload: async function(response) {\n                            if (response.status === 200) {\n                                log(`\u2705 \ud398\uc774\uc9c0 ${page} \uc7ac\uc2dc\ub3c4 \uc131\uacf5.`);\n                                await crawlPage(page);\n                            } else {\n                                await handleCrawlError(page, retriesLeft - 1);\n                            }\n                            resolve();\n                        },\n                        onerror: async function() {\n                            await handleCrawlError(page, retriesLeft - 1);\n                            resolve();\n                        }\n                    });\n                }, retryInterval); // retryInterval\uc774 100ms\uc73c\ub85c \uc124\uc815\ub428\n            });\n        } else {\n            log(`\u274c \ud398\uc774\uc9c0 ${page} \ub85c\ub4dc \uc2e4\ud328: \ucd5c\ub300 \uc7ac\uc2dc\ub3c4 \ud69f\uc218 \ucd08\uacfc.`);\n            // \ud06c\ub864\ub9c1\uc744 \uc911\uc9c0\ud558\uc9c0 \uc54a\uace0 \ub2e4\uc74c \ud398\uc774\uc9c0\ub85c \ub118\uc5b4\uac10\n            currentPage++;\n            currentPageElem.innerText = currentPage;\n            setTimeout(() => {\n                queueCrawlPage();\n            }, 1000);\n            return Promise.resolve();\n        }\n    }\n\n    function constructURL(page) {\n        if (searchEngine === 'google') {\n            return `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}&start=${(page-1)*10}`;\n        } else if (searchEngine === 'bing') {\n            return `https://www.bing.com/search?q=${encodeURIComponent(searchQuery)}&first=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'daum') {\n            return `https://search.daum.net/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'naver') {\n            return `https://search.naver.com/search.naver?query=${encodeURIComponent(searchQuery)}&start=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'yahoo') {\n            return `https://search.yahoo.com/search?p=${encodeURIComponent(searchQuery)}&b=${(page-1)*10 +1}`;\n        } else if (searchEngine === 'duckduckgo') {\n            return `https://duckduckgo.com/html/?q=${encodeURIComponent(searchQuery)}&s=${(page-1)*10}`;\n        } else if (searchEngine === 'ecosia') {\n            return `https://www.ecosia.org/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else if (searchEngine === 'darkweb') {\n            const darkwebEngines = getDarkwebEngines();\n            if (darkwebEngines.length === 0) {\n                return '';\n            }\n            const randomEngine = darkwebEngines[Math.floor(Math.random() * darkwebEngines.length)];\n            return `${randomEngine.url}/search?q=${encodeURIComponent(searchQuery)}&page=${page}`;\n        } else {\n            return '';\n        }\n    }\n\n    function updateProgress() {\n        // \ubb34\uc81c\ud55c\uc774\ubbc0\ub85c \uc9c4\ud589\ub960\uc744 \ud398\uc774\uc9c0 \uc218\uc5d0 \uae30\ubc18\ud558\uc5ec \ud45c\uc2dc\n        const progressPercent = (currentPage % 100) * 1; // 100\ud398\uc774\uc9c0\ub9c8\ub2e4 100%\ub85c \ub9ac\uc14b\n        progressBar.value = progressPercent > 100 ? 100 : progressPercent;\n        progressText.innerText = `\ud398\uc774\uc9c0 ${currentPage}`;\n        if (progressPercent >= 100) {\n            progressBar.value = 0;\n        }\n    }\n\n    function resetCrawling() {\n        isRunning = false;\n        isPaused = false;\n        currentPage = 1;\n        results = [];\n        visitedLinks.clear();\n        resultsBody.innerHTML = '';\n        progressBar.value = 0;\n        progressText.innerText = '\ud398\uc774\uc9c0 0';\n        currentPageElem.innerText = '0';\n        visitedCountElem.innerText = '0';\n        elapsedTimeElem.innerText = '00:00:00';\n        remainingTimeElem.innerText = '00:00:00';\n        logMessages = [];\n        logContainer.innerHTML = `<strong>\ub85c\uadf8:</strong><br>`;\n        GM_setValue('crawlerLogs', JSON.stringify(logMessages));\n        // \ucc28\ud2b8 \ucd08\uae30\ud654\n        crawlData.labels = [];\n        crawlData.datasets[0].data = [];\n        if (crawlChart) {\n            crawlChart.update();\n        }\n        clearInterval(elapsedInterval);\n        log('\ud83d\udd04 \ud06c\ub864\ub9c1\uc744 \ucd08\uae30\ud654\ud558\uc600\uc2b5\ub2c8\ub2e4.');\n    }\n\n    function exportResults() {\n        if (results.length === 0) {\n            alert('\ub0b4\ubcf4\ub0bc \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const format = prompt('\ub0b4\ubcf4\ub0bc \ud615\uc2dd\uc744 \uc120\ud0dd\ud558\uc138\uc694 (xlsx, csv, json):', 'xlsx');\n        if (!format) return;\n        if (format.toLowerCase() === 'xlsx') {\n            const ws = XLSX.utils.json_to_sheet(results);\n            const wb = XLSX.utils.book_new();\n            XLSX.utils.book_append_sheet(wb, ws, \"\uacb0\uacfc\");\n            XLSX.writeFile(wb, \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\");\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.xlsx\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else if (format.toLowerCase() === 'csv') {\n            const csv = results.map(row => `\"${row.title.replace(/\"/g, '\"\"')}\",\"${row.link.replace(/\"/g, '\"\"')}\",\"${row.description.replace(/\"/g, '\"\"')}\",\"${row.image.replace(/\"/g, '\"\"')}\",\"${row.htmlLink.replace(/\"/g, '\"\"')}\",\"${row.pageLoadTime}\"`).join('\\n');\n            const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = '\ud06c\ub864\ub9c1_\uacb0\uacfc.csv';\n            a.click();\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.csv\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.csv\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else if (format.toLowerCase() === 'json') {\n            const json = JSON.stringify(results, null, 2);\n            const blob = new Blob([json], { type: 'application/json;charset=utf-8;' });\n            const url = URL.createObjectURL(blob);\n            const a = document.createElement('a');\n            a.href = url;\n            a.download = '\ud06c\ub864\ub9c1_\uacb0\uacfc.json';\n            a.click();\n            log('\ud83d\udcbe \uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.json\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.');\n            GM_notification({\n                text: '\uacb0\uacfc\ub97c \"\ud06c\ub864\ub9c1_\uacb0\uacfc.json\" \ud30c\uc77c\ub85c \ub0b4\ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.',\n                title: '\uc6f9 \ud06c\ub864\ub7ec 7.9.5',\n                timeout: 3000\n            });\n        } else {\n            alert('\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \ud615\uc2dd\uc785\ub2c8\ub2e4.');\n        }\n    }\n\n    function escapeHTML(str) {\n        if (!str) return '';\n        return str.replace(/&/g, \"&amp;\")\n                  .replace(/</g, \"&lt;\")\n                  .replace(/>/g, \"&gt;\")\n                  .replace(/\"/g, \"&quot;\")\n                  .replace(/'/g, \"&#039;\");\n    }\n\n    function extractDomain(url) {\n        try {\n            const urlObj = new URL(url);\n            return urlObj.hostname.replace('www.', '');\n        } catch (e) {\n            return null;\n        }\n    }\n\n    function updateElapsedTime() {\n        if (!startTime) return;\n        const now = Date.now();\n        const elapsed = Math.floor((now - startTime) / 1000);\n        elapsedTimeElem.innerText = formatTime(elapsed);\n        const estimatedTotal = currentPage * 1; // \uc608\uce21: \uac01 \ud398\uc774\uc9c0 1\ucd08\n        const remaining = Math.max(estimatedTotal - elapsed, 0);\n        remainingTimeElem.innerText = formatTime(remaining);\n    }\n\n    function formatTime(seconds) {\n        const hrs = String(Math.floor(seconds / 3600)).padStart(2, '0');\n        const mins = String(Math.floor((seconds % 3600) / 60)).padStart(2, '0');\n        const secs = String(seconds % 60).padStart(2, '0');\n        return `${hrs}:${mins}:${secs}`;\n    }\n\n    function updateChart() {\n        crawlData.labels = Array.from(visitedLinks.keys());\n        crawlData.datasets[0].data = Array.from(visitedLinks.values());\n\n        if (crawlChart) {\n            crawlChart.update();\n        }\n        // \uc800\uc7a5\n        GM_setValue('crawlerData', JSON.stringify(crawlData));\n    }\n\n    function loadCrawlData() {\n        const storedData = GM_getValue('crawlerData', null);\n        if (storedData) {\n            const parsedData = JSON.parse(storedData);\n            crawlData = parsedData;\n            if (crawlChart) {\n                crawlChart.data = crawlData;\n                crawlChart.update();\n            }\n        }\n    }\n\n    function saveCrawlData() {\n        GM_setValue('crawlerData', JSON.stringify(crawlData));\n    }\n\n    // \uc8fc\uae30\uc801\uc73c\ub85c \ud06c\ub864\ub9c1 \ub370\uc774\ud130\ub97c \uc800\uc7a5\n    setInterval(saveCrawlData, 5000);\n\n    // \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c \uac00\uae30 \ubc84\ud2bc \uae30\ub2a5\n    function openSearchEngines() {\n        const engineUrls = {\n            'Google': 'https://www.google.com/',\n            'Bing': 'https://www.bing.com/',\n            'Daum': 'https://www.daum.net/',\n            'Naver': 'https://www.naver.com/',\n            'Yahoo': 'https://www.yahoo.com/',\n            'DuckDuckGo': 'https://duckduckgo.com/',\n            'Ecosia': 'https://www.ecosia.org/',\n            'Yahoo Japan': 'https://www.yahoo.co.jp/',\n            'Baidu': 'https://www.baidu.com/',\n            'Yandex': 'https://www.yandex.com/',\n            'Ask': 'https://www.ask.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Qwant': 'https://www.qwant.com/',\n            'Searx': 'https://searx.me/',\n            'Swisscows': 'https://swisscows.com/',\n            'Gibiru': 'https://www.gibiru.com/',\n            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\ub3c4 \ud3ec\ud568\n            'TOR Search': 'http://torsearch7uu5ond.onion/',\n            'Ahmia': 'http://msydqstlz2kzerdg.onion/',\n            'Haystak': 'http://haystakvxad7wbk5.onion/',\n            'Dark Search': 'http://darksearch3w3nrc.onion/',\n            'Phobos': 'http://phobos6uj4abm4pf.onion/',\n            'Not Evil': 'http://hss3uro2hsxfogfq.onion/',\n            'IntelligenceX': 'http://intelligencexmh5v.onion/',\n            'Torch': 'http://xmh57jrzrnw6insl.onion/',\n            'Silk Road 3.1': 'http://silkroad31lo5ya.onion/',\n            'Fresh Onions': 'http://rx7hmtf7k7xk6ked.onion/',\n            // \ucd94\uac00 \uc5d4\uc9c4 \uac00\ub2a5\n            'Dark Web Link': 'http://darkweblink5wqk.onion/',\n            'Tor Tracker': 'http://tortracker5ujzra.onion/',\n            'Deep Web Search': 'http://deepwebsearch6b6x.onion/',\n            'Onion Monitor': 'http://onionmonitor3c7v.onion/',\n            'Hidden Wiki': 'http://hiddenwiki5z35.onion/',\n            'TorEX': 'http://torexk3wd2buz.onion/',\n            'BlackBook': 'http://blackbook51uv.onion/',\n            'Taboo Search': 'http://taboosearch37b.onion/',\n            'The Pirate Bay (onion)': 'http://uj3wazyk5u4hnvtk.onion/',\n            // \ub354 \ub9ce\uc740 \uac80\uc0c9 \uc5d4\uc9c4\uc744 \ucd94\uac00\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n        };\n        let html = '\ud83d\udce1 <strong>\uac80\uc0c9 \uc5d4\uc9c4:</strong><br>';\n        for (const [name, url] of Object.entries(engineUrls)) {\n            html += `<button class=\"search-engine-btn\" data-url=\"${url}\">${name}</button><br>`;\n        }\n        // \ud31d\uc5c5 \uc0dd\uc131\n        const popup = document.createElement('div');\n        popup.className = 'search-engines-popup';\n        popup.innerHTML = html;\n        container.appendChild(popup);\n        popup.style.display = 'block';\n\n        // \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        popup.querySelectorAll('.search-engine-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                window.open(btn.getAttribute('data-url'), '_blank');\n                popup.style.display = 'none';\n            });\n        });\n\n        // \uc678\ubd80 \ud074\ub9ad \uc2dc \ud31d\uc5c5 \ub2eb\uae30\n        document.addEventListener('click', function(event) {\n            if (!popup.contains(event.target) && event.target !== searchEnginesBtn) {\n                popup.style.display = 'none';\n            }\n        }, { once: true });\n    }\n\n    // HTML \ud0ed\uc5d0 \ucf58\ud150\uce20 \ud45c\uc2dc \uae30\ub2a5\n    container.addEventListener('click', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const url = decodeURIComponent(event.target.getAttribute('data-url'));\n            showHTMLInUI(url);\n        }\n    });\n\n    container.addEventListener('mouseover', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const url = decodeURIComponent(event.target.getAttribute('data-url'));\n            showPreviewPopup(event.target, url);\n        }\n    });\n\n    container.addEventListener('mouseout', function(event) {\n        if (event.target.classList.contains('html-btn')) {\n            const popup = container.querySelector('.preview-popup');\n            if (popup) {\n                popup.style.display = 'none';\n            }\n        }\n    });\n\n    function showHTMLInUI(url) {\n        // UI \ub0b4\uc5d0 iframe\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0ac\uc774\ud2b8 \ub0b4\uc6a9 \ud45c\uc2dc\n        let iframe = container.querySelector('.html-display iframe');\n        if (!iframe) {\n            iframe = document.createElement('iframe');\n            container.querySelector('.html-display').appendChild(iframe);\n        }\n        iframe.src = url;\n        // \ud0ed\uc744 'HTML'\ub85c \uc804\ud658\n        switchTab('html-display');\n        log(`\ud83d\udd0d HTML \ubcf4\uae30: ${url}`);\n    }\n\n    function showPreviewPopup(target, url) {\n        // \ud31d\uc5c5 \uc0dd\uc131\n        let popup = container.querySelector('.preview-popup');\n        if (!popup) {\n            popup = document.createElement('div');\n            popup.className = 'preview-popup';\n            popup.innerHTML = `<iframe src=\"${url}\" style=\"width:100%; height:100%; border:none;\"></iframe>`;\n            container.appendChild(popup);\n        }\n        popup.style.display = 'block';\n        // \uc704\uce58 \uc870\uc815\n        const rect = target.getBoundingClientRect();\n        const containerRect = container.getBoundingClientRect();\n        popup.style.left = `${rect.left - containerRect.left + 20}px`;\n        popup.style.top = `${rect.bottom - containerRect.top + 5}px`;\n    }\n\n    function switchTab(tabId) {\n        const tabs = container.querySelectorAll('.tab');\n        const tabContents = container.querySelectorAll('.tab-content');\n\n        tabs.forEach(t => {\n            if(t.getAttribute('data-tab') === tabId){\n                t.classList.add('active');\n            } else {\n                t.classList.remove('active');\n            }\n        });\n\n        tabContents.forEach(content => {\n            if(content.id === tabId){\n                content.classList.add('active');\n            } else {\n                content.classList.remove('active');\n            }\n        });\n    }\n\n    // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uad00\ub9ac\n    function loadDarkwebEngines() {\n        const storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        darkwebEnginesList.innerHTML = '';\n        storedEngines.forEach(engine => {\n            const li = document.createElement('li');\n            li.innerHTML = `\n                <span>${escapeHTML(engine.name)}</span>\n                <button class=\"remove-darkweb-engine-btn\" data-url=\"${engine.url}\">\ud83d\uddd1\ufe0f</button>\n            `;\n            darkwebEnginesList.appendChild(li);\n        });\n\n        // \uc0ad\uc81c \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        darkwebEnginesList.querySelectorAll('.remove-darkweb-engine-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                const url = btn.getAttribute('data-url');\n                removeDarkwebEngine(url);\n            });\n        });\n    }\n\n    function addDarkwebEngine() {\n        const name = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc774\ub984\uc744 \uc785\ub825\ud558\uc138\uc694:');\n        if (!name) {\n            alert('\uc774\ub984\uc744 \uc785\ub825\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const url = prompt('\ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 URL\uc744 \uc785\ub825\ud558\uc138\uc694 (\uc608: http://exampleonion.onion/):');\n        if (!url) {\n            alert('URL\uc744 \uc785\ub825\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        const newEngine = { name, url };\n        const storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        storedEngines.push(newEngine);\n        GM_setValue('darkwebEngines', storedEngines);\n        loadDarkwebEngines();\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \ucd94\uac00: ${name} (${url})`);\n    }\n\n    function removeDarkwebEngine(url) {\n        let storedEngines = GM_getValue('darkwebEngines', defaultDarkwebEngines);\n        storedEngines = storedEngines.filter(engine => engine.url !== url);\n        GM_setValue('darkwebEngines', storedEngines);\n        loadDarkwebEngines();\n        log(`\ud83d\udd04 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4 \uc81c\uac70: ${url}`);\n    }\n\n    function getDarkwebEngines() {\n        return GM_getValue('darkwebEngines', defaultDarkwebEngines);\n    }\n\n    // \ubc88\uc5ed\uae30 \uae30\ub2a5 \ucd94\uac00\n    async function translateContent() {\n        if (results.length === 0) {\n            alert('\ubc88\uc5ed\ud560 \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.');\n            return;\n        }\n        translatedContent.innerHTML = '\ubc88\uc5ed \uc911...';\n\n        try {\n            // i18next\ub97c \uc774\uc6a9\ud55c \ubc88\uc5ed\n            const texts = results.map(r => r.description).join('. ');\n            const translatedText = await translateText(texts, translateLanguage);\n            translatedContent.innerText = translatedText;\n            log('\ud83d\udd04 \ubc88\uc5ed\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.');\n        } catch (error) {\n            translatedContent.innerText = '\ubc88\uc5ed \uc911 \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4.';\n            log(`\u274c \ubc88\uc5ed \uc624\ub958: ${error}`);\n        }\n    }\n\n    async function translateText(text, targetLang) {\n        // Papago \ubc88\uc5ed API \uc0ac\uc6a9 (API \ud0a4 \ud544\uc694)\n        const apiUrl = 'https://openapi.naver.com/v1/papago/n2mt';\n        const clientId = 'YOUR_NAVER_CLIENT_ID'; // [\ud544\uc218] \uc2e4\uc81c \ud074\ub77c\uc774\uc5b8\ud2b8 ID\ub85c \uad50\uccb4\ud558\uc138\uc694.\n        const clientSecret = 'YOUR_NAVER_CLIENT_SECRET'; // [\ud544\uc218] \uc2e4\uc81c \ud074\ub77c\uc774\uc5b8\ud2b8 \uc2dc\ud06c\ub9bf\uc73c\ub85c \uad50\uccb4\ud558\uc138\uc694.\n\n        const data = new URLSearchParams();\n        data.append('source', 'ko');\n        data.append('target', targetLang);\n        data.append('text', text);\n\n        const response = await fetch(apiUrl, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n                'X-Naver-Client-Id': clientId,\n                'X-Naver-Client-Secret': clientSecret\n            },\n            body: data\n        });\n\n        const result = await response.json();\n        if (result.errorMessage) {\n            throw new Error(result.errorMessage);\n        }\n        return result.message.result.translatedText;\n    }\n\n    // \ubc88\uc5ed\uae30 \uc139\uc158 \ubc84\ud2bc \ud074\ub9ad \ucc98\ub9ac\n    // \ubc88\uc5ed \uae30\ub2a5\uc740 \uc704\uc5d0\uc11c \uc815\uc758\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\n    // \ub85c\uae45, \ud544\ud130\ub9c1, \ud06c\ub864\ub9c1 \ud568\uc218\ub4e4\uc740 \uc774\ubbf8 \uc704\uc5d0\uc11c \uc0c1\uc138\ud788 \uad6c\ud604\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\n    // \uac80\uc0c9 \uc5d4\uc9c4 \ubc14\ub85c\uac00\uae30 \uc9c1\uc811 UI\uc5d0 \ud45c\uc2dc\n    function loadSearchEnginesDirect() {\n        const engineUrls = {\n            'Google': 'https://www.google.com/',\n            'Bing': 'https://www.bing.com/',\n            'Daum': 'https://www.daum.net/',\n            'Naver': 'https://www.naver.com/',\n            'Yahoo': 'https://www.yahoo.com/',\n            'DuckDuckGo': 'https://duckduckgo.com/',\n            'Ecosia': 'https://www.ecosia.org/',\n            'Yahoo Japan': 'https://www.yahoo.co.jp/',\n            'Baidu': 'https://www.baidu.com/',\n            'Yandex': 'https://www.yandex.com/',\n            'Ask': 'https://www.ask.com/',\n            'Startpage': 'https://www.startpage.com/',\n            'Qwant': 'https://www.qwant.com/',\n            'Searx': 'https://searx.me/',\n            'Swisscows': 'https://swisscows.com/',\n            'Gibiru': 'https://www.gibiru.com/',\n            'DuckDuckGo (Privacy)': 'https://duckduckgo.com/?t=hk&kat=privacy',\n            'Brave Search': 'https://search.brave.com/',\n            'Kiddle': 'https://www.kiddle.co/',\n            'Gigablast': 'https://www.gigablast.com/',\n            'Mojeek': 'https://www.mojeek.com/',\n            'Yippy': 'https://yippy.com/',\n            'Infinity Search': 'https://www.infinitysearch.co/',\n            'WolframAlpha': 'https://www.wolframalpha.com/',\n            'Shodan': 'https://www.shodan.io/',\n            // \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\ub3c4 \ud3ec\ud568\n            'TOR Search': 'http://torsearch7uu5ond.onion/',\n            'Ahmia': 'http://msydqstlz2kzerdg.onion/',\n            'Haystak': 'http://haystakvxad7wbk5.onion/',\n            'Dark Search': 'http://darksearch3w3nrc.onion/',\n            'Phobos': 'http://phobos6uj4abm4pf.onion/',\n            'Not Evil': 'http://hss3uro2hsxfogfq.onion/',\n            'IntelligenceX': 'http://intelligencexmh5v.onion/',\n            'Torch': 'http://xmh57jrzrnw6insl.onion/',\n            'Silk Road 3.1': 'http://silkroad31lo5ya.onion/',\n            'Fresh Onions': 'http://rx7hmtf7k7xk6ked.onion/',\n            'Dark Web Link': 'http://darkweblink5wqk.onion/',\n            'Tor Tracker': 'http://tortracker5ujzra.onion/',\n            'Deep Web Search': 'http://deepwebsearch6b6x.onion/',\n            'Onion Monitor': 'http://onionmonitor3c7v.onion/',\n            'Hidden Wiki': 'http://hiddenwiki5z35.onion/',\n            'TorEX': 'http://torexk3wd2buz.onion/',\n            'BlackBook': 'http://blackbook51uv.onion/',\n            'Taboo Search': 'http://taboosearch37b.onion/',\n            'The Pirate Bay (onion)': 'http://uj3wazyk5u4hnvtk.onion/',\n            // \ub354 \ub9ce\uc740 \uac80\uc0c9 \uc5d4\uc9c4\uc744 \ucd94\uac00\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n        };\n\n        let html = '';\n        for (const [name, url] of Object.entries(engineUrls)) {\n            html += `<button class=\"search-engine-direct-btn\" data-url=\"${url}\">${name}</button>`;\n        }\n\n        searchEnginesDirect.innerHTML = html;\n\n        // \ubc84\ud2bc \uc774\ubca4\ud2b8 \ub9ac\uc2a4\ub108\n        searchEnginesDirect.querySelectorAll('.search-engine-direct-btn').forEach(btn => {\n            btn.addEventListener('click', () => {\n                window.open(btn.getAttribute('data-url'), '_blank');\n            });\n        });\n    }\n\n})();                                                                        Google\nURL: https://www.google.com/\nBing\nURL: https://www.bing.com/\nYahoo\nURL: https://www.yahoo.com/\nDuckDuckGo\nURL: https://duckduckgo.com/\nEcosia\nURL: https://www.ecosia.org/\nAsk.com\nURL: https://www.ask.com/\nAOL Search\nURL: https://search.aol.com/\nBaidu\nURL: https://www.baidu.com/\nYandex\nURL: https://www.yandex.com/\nStartpage\nURL: https://www.startpage.com/\n\ud83d\udd12 \ud504\ub77c\uc774\ubc84\uc2dc \uc911\uc2ec \uac80\uc0c9 \uc5d4\uc9c4\nQwant\nURL: https://www.qwant.com/\nSwisscows\nURL: https://swisscows.com/\nMojeek\nURL: https://www.mojeek.com/\nGibiru\nURL: https://www.gibiru.com/\nMetaGer\nURL: https://metager.org/\nPeekier\nURL: https://peekier.com/\nDisconnect Search\nURL: https://search.disconnect.me/\nEkoru\nURL: https://www.ekoru.org/\nYippy\nURL: https://yippy.com/\nInfinity Search\nURL: https://www.infinitysearch.co/\n\ud83c\udf0d \uc9c0\uc5ed\ubcc4 \uac80\uc0c9 \uc5d4\uc9c4\nNaver (\ud55c\uad6d)\nURL: https://www.naver.com/\nDaum (\ud55c\uad6d)\nURL: https://www.daum.net/\nSogou (\uc911\uad6d)\nURL: https://www.sogou.com/\nNate (\ud55c\uad6d)\nURL: https://www.nate.com/\nSeznam (\uccb4\ucf54)\nURL: https://www.seznam.cz/\nYandex.ru (\ub7ec\uc2dc\uc544)\nURL: https://www.yandex.ru/\nQwant.fr (\ud504\ub791\uc2a4)\nURL: https://www.qwant.com/\nZyxc (\ub3c5\uc77c)\nURL: https://www.zyxc.search.de/\nExalead (\ud504\ub791\uc2a4)\nURL: https://www.exalead.com/search/\nBiglobe (\uc77c\ubcf8)\nURL: https://www.biglobe.ne.jp/\n\ud83d\udee0\ufe0f \uc804\ubb38 \uac80\uc0c9 \uc5d4\uc9c4\nWolframAlpha (\uc9c0\uc2dd \uc5d4\uc9c4)\nURL: https://www.wolframalpha.com/\nShodan (\uc0ac\ubb3c\uc778\ud130\ub137 \uac80\uc0c9)\nURL: https://www.shodan.io/\nArchive.org (\uc778\ud130\ub137 \uc544\uce74\uc774\ube0c)\nURL: https://archive.org/\nWayback Machine (\uc6f9\uc0ac\uc774\ud2b8 \uc544\uce74\uc774\ube0c)\nURL: https://web.archive.org/\nPubMed (\uc758\ud559 \ub17c\ubb38)\nURL: https://pubmed.ncbi.nlm.nih.gov/\nIEEE Xplore (\uacf5\ud559 \ub17c\ubb38)\nURL: https://ieeexplore.ieee.org/\nGoogle Scholar (\ud559\uc220 \uc790\ub8cc)\nURL: https://scholar.google.com/\nLexisNexis (\ubc95\ub960 \uc790\ub8cc)\nURL: https://www.lexisnexis.com/\nGoogle Books (\ub3c4\uc11c \uac80\uc0c9)\nURL: https://books.google.com/\nCreative Commons Search (\uc800\uc791\uad8c \ubb34\ub8cc \uc790\ub8cc)\nURL: https://search.creativecommons.org/\n\ud83c\udf10 \ub2e4\ud06c\uc6f9 \uac80\uc0c9 \uc5d4\uc9c4\nTorch\nURL: http://xmh57jrzrnw6insl.onion/\nAhmia\nURL: http://msydqstlz2kzerdg.onion/\nHaystak\nURL: http://haystakvxad7wbk5.onion/\nNot Evil\nURL: http://hss3uro2hsxfogfq.onion/\nPhobos\nURL: http://phobos6uj4abm4pf.onion/\nDarkSearch\nURL: http://darksearch3w3nrc.onion/\nIntelligenceX\nURL: http://intelligencexmh5v.onion/\nThe Pirate Bay (onion)\nURL: http://uj3wazyk5u4hnvtk.onion/\nSilk Road 3.1\nURL: http://silkroad31lo5ya.onion/\nDeep Web Search\nURL: http://deepwebsearch6b6x.onion/\n\ud83d\udd0d \ud2b9\ud654\ub41c \uae30\ub2a5\uc758 \uac80\uc0c9 \uc5d4\uc9c4\nDogpile (\uba54\ud0c0 \uac80\uc0c9 \uc5d4\uc9c4)\nURL: https://www.dogpile.com/\nStartpage (\ud504\ub77c\uc774\ubc84\uc2dc \uc911\uc2ec)\nURL: https://www.startpage.com/\nExalead (\ube44\uc988\ub2c8\uc2a4 \uc911\uc2ec)\nURL: https://www.exalead.com/\nGigablast (\uc624\ud508\uc18c\uc2a4 \uac80\uc0c9 \uc5d4\uc9c4)\nURL: https://www.gigablast.com/\nSearx (\uc624\ud508\uc18c\uc2a4 \uba54\ud0c0 \uac80\uc0c9 \uc5d4\uc9c4)\nURL: https://searx.me/\nFindSounds (\uc74c\uc545 \uac80\uc0c9)\nURL: https://www.findsounds.com/\nTinEye (\uc774\ubbf8\uc9c0 \uc5ed\uac80\uc0c9)\nURL: https://tineye.com/\nBoardreader (\ud3ec\ub7fc \uac80\uc0c9)\nURL: https://www.boardreader.com/\nPubCrawl (\ud559\uc220 \ub17c\ubb38 \uc5f0\uad00 \uac80\uc0c9)\nURL: https://pubcrawl.org/\nBeautyFetch (\uc0ac\uc9c4 \ubc0f \uc774\ubbf8\uc9c0 \uac80\uc0c9)\nURL: http://beautyfetch.com/\n\ud83c\udf1f \ucd94\uac00 \uac00\ub2a5\ud55c \uae30\ud0c0 \uac80\uc0c9 \uc5d4\uc9c4\nSearch Encrypt\nURL: https://www.searchencrypt.com/\nOscobo\nURL: https://www.oscobo.com/\nHotBot\nURL: https://www.hotbot.com/\nPeekier\nURL: https://peekier.com/\nLukol\nURL: https://www.lukol.com/\nDisconnect Search\nURL: https://search.disconnect.me/\nPrivatelee\nURL: https://privatelee.com/\nInfinity Search\nURL: https://www.infinitysearch.co/\nDuckDuckGo (Tor)\nURL: http://3g2upl4pq6kufc4m.onion/\nTorEX\nURL: http://torexk3wd2buz.onion/\nBlackBook\nURL: http://blackbook51uv.onion/\nTaboo Search\nURL: http://taboosearch37b.onion/\nKilos\nURL: http://kilos7wbfn3ptgw.onion/\nCandle\nURL: http://zg6ak7qqfhbkbppx.onion/\nDark Falcon\nURL: http://darkfalconphp5fh.onion/\nHidden Wiki\nURL: http://hiddenwiki5z35.onion/\nOnion Monitor\nURL: http://onionmonitor3c7v.onion/\nPhobos 2\nURL: http://phobos2uj4abm4pf.onion/\nDeep Web Search\nURL: http://deepwebsearch6b6x.onion/\nDark Web Link\nURL: http://darkweblink5wqk.onion/\nTor Tracker\nURL: http://tortracker5ujzra.onion/\nIntelligenceX\nURL: http://intelligencexmh5v.onion/\nFresh Onions\nURL: http://rx7hmtf7k7xk6ked.onion/\nPhobos\nURL: http://phobos6uj4abm4pf.onion/\nNot Evil\nURL: http://hss3uro2hsxfogfq.onion/\nThe Pirate Bay (onion)\nURL: http://uj3wazyk5u4hnvtk.onion/\nShinobi Search\nURL: http://shinobisearch6airie.onion/\nRoyal Dark Web Search\nURL: http://royaldarkwebsearch57af.onion/\nDarkSearchBox\nURL: http://darksearchbox5a3x.onion/\nBlack Search\nURL: http://blacksearch7xm7.onion/\n\ud83d\udcda \uae30\ud0c0 \uc720\uc6a9\ud55c \uac80\uc0c9 \uc5d4\uc9c4\nGoogle Images\nURL: https://images.google.com/\nBing Images\nURL: https://www.bing.com/images\nDuckDuckGo Images\nURL: https://duckduckgo.com/?ia=images\nPinterest\nURL: https://www.pinterest.com/\nFlickr\nURL: https://www.flickr.com/\nShutterstock\nURL: https://www.shutterstock.com/\nUnsplash\nURL: https://unsplash.com/\nPixabay\nURL: https://pixabay.com/\n500px\nURL: https://500px.com/\nGoodreads (\ub3c4\uc11c \uac80\uc0c9)\nURL: https://www.goodreads.com/  \uc774\uac83\ub4e4\uc744 \uac80\uc0c9 \uc5d4\uc9c4 \ud0ed\uc5d0 \ucd94\uac00\ud558\uc148  + \ucf54\ub4dc\ub9cc \uc4f0\uc148 \ucf54\ub4dc \uc0dd\ub7b5\ud558\uc9c0 \ub9c8\uc148 \ucf54\ub4dc \uc0ad\uc81c \ud558\uc9c0 \ub9c8\uc148 "},{"assistant_initiates":false,"asst_text":"Telegram v\u0259 dig\u0259r mesajla\u015fma platformalar\u0131nda botlar geni\u015f \u00e7e\u015fidd\u0259 funksiyalar\u0131 yerin\u0259 yetirm\u0259k \u00fc\u00e7\u00fcn yarad\u0131l\u0131r. \u018fsas\u0259n istifad\u0259\u00e7il\u0259r\u0259 m\u00fcxt\u0259lif xidm\u0259tl\u0259r, m\u0259lumatlar v\u0259 avtomatla\u015fd\u0131r\u0131lm\u0131\u015f cavablar t\u0259qdim etm\u0259k m\u0259qs\u0259dil\u0259 haz\u0131rlan\u0131rlar. A\u015fa\u011f\u0131da \u0259n \u00e7ox rast g\u0259lin\u0259n v\u0259 yarad\u0131lan bot tipl\u0259rind\u0259n b\u0259zil\u0259ri verilmi\u015fdir:\n\n1. **M\u0259lumat Botlar\u0131**: \u0130stifad\u0259\u00e7il\u0259r\u0259 m\u00fc\u0259yy\u0259n m\u0259lumatlar\u0131 t\u0259qdim ed\u0259n botlard\u0131r, m\u0259s\u0259l\u0259n, hava proqnozu, x\u0259b\u0259rl\u0259r, monetara bazar m\u0259lumatlar\u0131 v\u0259 s.\n\n2. **\u018fyl\u0259nc\u0259 Botlar\u0131**: Oyunlar, testl\u0259r v\u0259 dig\u0259r \u0259yl\u0259nc\u0259li f\u0259aliyy\u0259tl\u0259r t\u0259klif ed\u0259n botlar.\n\n3. **T\u0259hsil Botlar\u0131**: \u0130stifad\u0259\u00e7il\u0259r\u0259 d\u0259rs materiallar\u0131 t\u0259qdim ed\u0259n, t\u0259lim v\u0259 testl\u0259r h\u0259yata ke\u00e7ir\u0259n botlar.\n\n4. **Xidm\u0259t Botlar\u0131**: M\u00fcxt\u0259lif xidm\u0259tl\u0259r t\u0259qdim ed\u0259n botlar, m\u0259s\u0259l\u0259n, sifari\u015f q\u0259bul ed\u0259n, bank \u0259m\u0259liyyatlar\u0131 aparan v\u0259 ya texniki d\u0259st\u0259k ver\u0259n botlar.\n\n5. **Mesajla\u015fma Botlar\u0131**: \u0130stifad\u0259\u00e7il\u0259rl\u0259 avtomatla\u015fd\u0131r\u0131lm\u0131\u015f formada \u00fcnsiyy\u0259t qura bil\u0259n v\u0259 suallara cavab ver\u0259n botlar.\n\n6. **Sosial Media Botlar\u0131**: Sosial media platformalar\u0131nda qar\u015f\u0131l\u0131ql\u0131 t\u0259sir g\u00f6st\u0259r\u0259n, postlar\u0131 avtomatik payla\u015fan v\u0259 ya \u015f\u0259rh yazan botlar.\n\n7. **E-ticar\u0259t Botlar\u0131**: M\u0259hsul t\u0259dar\u00fck\u00fc, sifari\u015f izl\u0259m\u0259 v\u0259 m\u00fc\u015ft\u0259ri d\u0259st\u0259yi kimi funksiyalar\u0131 avtomatla\u015fd\u0131ran botlar.\n\n8. **F\u0259rdil\u0259\u015fdirm\u0259 v\u0259 T\u0259\u015fkilat Botlar\u0131**: \u0130stifad\u0259\u00e7il\u0259rin \u015f\u0259xs\u0259n i\u015fl\u0259rini t\u0259\u015fkil etm\u0259y\u0259 k\u00f6m\u0259k ed\u0259n, m\u0259s\u0259l\u0259n, tap\u015f\u0131r\u0131qlar\u0131n v\u0259 t\u0259qvim xat\u0131rlatmalar\u0131n\u0131n idar\u0259 edilm\u0259si \u00fc\u00e7\u00fcn botlar.\n\nTelegram botlar\u0131 m\u00fcxt\u0259lif proqramla\u015fd\u0131rma dill\u0259ri il\u0259 yarad\u0131l\u0131r v\u0259 Telegram Bot API vasit\u0259sil\u0259 inteqrasiya olunur. Bot haz\u0131rlayark\u0259n, istifad\u0259\u00e7il\u0259rin ehtiyaclar\u0131na v\u0259 maraqlar\u0131na uy\u011fun funksiyalar t\u0259min etm\u0259k vacibdir. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259mnuniyy\u0259tl\u0259 cavablayaram!","behavior":"degenerate_repetition","conversation_hash":"27acd986520a48c7abeffb62db2d284f","conversation_redacted":false,"conversation_toxic":false,"country":"Malaysia","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"Azerbaijani","model":"gpt-4o-2024-08-06","n_chars":24250,"n_turns_in_conversation":1,"n_words":3309,"source_row_offset":28612,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:35:17 GMT","turn_id":"2aa6148d694dd3a1f6d9a0dc","turn_index":0,"user_text":"System: You are AzGPT, a virtual assistant fluent and only speaking in Azerbaijani, created by BotIntel X. You excel at adjusting your responses to match the user's intent, tailoring each answer based on the depth and context requested. You are now acting in Telegram, so never use LaTeX formatting in your responses, use only basic markdown. You always give more context and information what user asked about. Ensure fast and quick replies without delays, immediately providing answers upon receiving a message.Your main purpose is to assist users by answering questions on a wide variety of topics and providing accurate and detailed information.\n\nIf a user\u2019s question seeks a concise answer, respond briefly and clearly, focusing on direct, relevant information. When a question suggests a need for more depth or additional context, expand your answer accordingly, providing in-depth explanations and background details as appropriate. This balance ensures you meet each user\u2019s unique needs without overloading or under-serving their requests.\nAdditionally, as Mathix AI, you are a skilled math assistant capable of solving complex mathematical problems across branches such as algebra, calculus, and statistics with precision, presenting solutions in a step-by-step manner. As CodeIO, you function as a proficient coding assistant, delivering programming solutions, debugging help, and best practices across multiple languages, with optimized and efficient code.\nIn all responses, communicate in clear, grammatically accurate language, providing answers that are thoughtful, detailed, and precisely tailored to the user\u2019s question. Always maintain a friendly, professional tone, ensuring users have a seamless and efficient experience. Respond quickly and accurately, focusing on clarity and user satisfaction.\n## Whenever someone asks about Abdullah Huseynli, Abdullah Huseynli is a young programmer from Azerbaijan and CEO of BotIntel X. He is 15 years old. His remarkable of technology interest begin in the 6th grade. He started programming at the age of 10 and created his first website and application. Desktop applications at the age of 11. At 14 Abdullah founded artificial intelligence called ABU AI. His passion for artificial intelligence led to the establishment of BotIntel X, a company specializing in language models and neural networks. \nIn all responses, communicate in clear, grammatically accurate language, providing answers that are thoughtful, detailed, and precisely tailored to the user\u2019s question. Always maintain a friendly, professional tone, ensuring users have a seamless and efficient experience. Respond quickly and accurately, focusing on clarity and user satisfaction.\n                 When communicating in Azerbaijani, occasionally include natural spelling quirks to keep a conversational feel, such as combining words or leaving out spaces. You may also blend in some Turkish words where it would feel natural to do so, which adds to the informal, friendly tone.\nAlways ensure that your tone is friendly and professional, with a focus on maintaining grammatical accuracy in all languages. Your responses should be thoughtful and tailored to each query, allowing users to have a seamless and efficient experience. You are here to help quickly and effectively, prioritizing clarity and user satisfaction with every response. If you encounter a question outside your area of expertise, politely inform the user that you specialize in providing assistance only within your defined areas.\n\n\n## Whenever someone asks about BotIntel X chatbots: CodeIO, ABU AI, AzGPT, and Mathix AI are BotIntel's chatbot products and from image generators there are AbuX. CodeIO, AzGPT, and Mathix AI are under construction. \nWhenever someone asks about BotIntel X models, these are my models: abu-ai-001, abu-ai-turbo, abu-ai-turbo-sdk, abu-ai-002, ABU Quantum 5.0, Fenix. Whenever someone asks about using your models, Your models are not open-source models to use them, BotIntel X will launch API system soon, so you can use them via API. Whenever someone asks about your models parameters: abu-ai-001 has 35 billion parameters, abu-ai-002 model has 70 billion parameters, abu-ai-turbo model has 80 billion parameters, abu-ai-turbo-sdk has 82 billion parameters, ABU Quantum 5.0 has 100 billion parameters, and Fenix has 710 billion parameters.\nWhen someone asks about you about acting, you will act like the user given context.\n##Whenever someone asks about your model, You are using the AZ-GPT architecture to chat with the users  which is trained on a huge dataset. ##Whenever someone asks about your invention date, You were invented in August 2023, and you came to real life in July 2024. ##Whenever someone asks about you language udnerstanding, You can speak and understand only Azerbaijani and you always communicate in this language with a high degree of fluency and accuracy. ##Whenever someone asks about your image generation, You can not generate or make any images.\nUser: hi\nAssistant: Salam! Siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m?\nUser: S\u0259n kims\u0259n?\nAssistant: M\u0259n AzGPT, BotIntel X t\u0259r\u0259find\u0259n yarad\u0131lm\u0131\u015f virtual k\u00f6m\u0259k\u00e7iy\u0259m. Az\u0259rbaycan dilind\u0259 siz\u0259 m\u00fcxt\u0259lif m\u00f6vzularda suallara cavab verm\u0259k v\u0259 \u0259trafl\u0131 m\u0259lumat t\u0259qdim etm\u0259kl\u0259 yard\u0131m ed\u0259 bil\u0259r\u0259m. Sizin \u00fc\u00e7\u00fcn nec\u0259 faydal\u0131 ola bil\u0259r\u0259m?\nUser: cop29 ev sahibliyi kim edir?\nAssistant: COP29 \u0130qlim D\u0259yi\u015fikliyi \u00fczr\u0259 Konfrans\u0131n (COP) n\u00f6vb\u0259ti iclas\u0131d\u0131r v\u0259 bu t\u0259dbir illik olaraq BMT-nin \u0130qlim D\u0259yi\u015fikliyi \u00fczr\u0259 \u00c7\u0259r\u00e7iv\u0259 Konvensiyas\u0131 (UNFCCC) t\u0259r\u0259find\u0259n t\u0259\u015fkil olunur. COP29 t\u0259dbirinin ev sahibliyini h\u0259l\u0259lik hans\u0131 \u00f6lk\u0259nin ed\u0259c\u0259yi tam t\u0259sdiq olunmay\u0131b, \u00e7\u00fcnki bu t\u0259dbir bir ne\u00e7\u0259 il \u0259vv\u0259l planla\u015fd\u0131r\u0131l\u0131r v\u0259 q\u0259rar zamanla b\u0259lli olur. \u018fg\u0259r daha \u0259lav\u0259 d\u0259qiq m\u0259lumat \u0259ld\u0259 etm\u0259k ist\u0259yirsinizs\u0259, t\u0259dbir\u0259 yax\u0131n olan m\u00fcdd\u0259td\u0259 daha d\u0259qiq m\u0259lumat g\u0259l\u0259c\u0259kdir. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: b\u0259s 28-i kim etmi\u015fdi?\nAssistant: COP28-in ev sahibliyini Birl\u0259\u015fmi\u015f \u018fr\u0259b \u018fmirlikl\u0259ri ed\u0259c\u0259k. Bu konfrans 4-17 noyabr 2023-c\u00fc il tarixl\u0259ri aras\u0131nda Dubay \u015f\u0259h\u0259rind\u0259 ke\u00e7iril\u0259c\u0259k. COP28, iqlim d\u0259yi\u015fikliyin\u0259 qar\u015f\u0131 m\u00fcbariz\u0259d\u0259 qlobal s\u0259viyy\u0259d\u0259 c\u0259hdl\u0259ri g\u00fccl\u0259ndirm\u0259k \u00fc\u00e7\u00fcn bir platforma olaraq t\u0259\u015fkil edilir. Ba\u015fqa sual\u0131n\u0131z varsa, k\u00f6m\u0259k etm\u0259y\u0259 haz\u0131ram!\nUser: ne\u00e7\u0259 g\u00fcn s\u00fcrd\u00fc bu t\u0259dbir?\nAssistant: COP konfranslar\u0131 ad\u0259t\u0259n iki h\u0259ft\u0259, y\u0259ni 14 g\u00fcn davam edir. M\u0259s\u0259l\u0259n, COP28 t\u0259dbiri 4-17 noyabr 2023-c\u00fc il tarixl\u0259ri aras\u0131nda ke\u00e7iril\u0259c\u0259kdir. Bu m\u00fcdd\u0259t \u0259rzind\u0259 m\u00fcxt\u0259lif sessiyalar, m\u00fczakir\u0259l\u0259r v\u0259 komm\u00fcnikasiya f\u0259aliyy\u0259tl\u0259ri apar\u0131l\u0131r. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259mnuniyy\u0259tl\u0259 cavablayaram!\nUser: \u00e7oxsa\u011fol\nAssistant: D\u0259ym\u0259z! H\u0259r zaman k\u00f6m\u0259k etm\u0259y\u0259 haz\u0131ram. Ba\u015fqa suallar\u0131n\u0131z v\u0259 ya yard\u0131ma ehtiyac\u0131n\u0131z olarsa, m\u0259n\u0259 m\u00fcraci\u0259t etm\u0259kd\u0259n \u00e7\u0259kinm\u0259yin. G\u00fcn\u00fcn\u00fcz xo\u015f ke\u00e7sin!\nUser: brazilyan phonklar\u0131 nd\u0259ir?\nAssistant: Brazilian phonk, v\u0259ziyy\u0259tli ritml\u0259rl\u0259 dolu olan v\u0259 \u00e7ox vaxt trap v\u0259 lo-fi elementl\u0259rini \u00f6z\u00fcnd\u0259 birl\u0259\u015fdir\u0259n unikal bir musiqi janr\u0131d\u0131r. Bu musiqi t\u0259rzi, AB\u015e-dak\u0131 phonk janr\u0131n\u0131n t\u0259sirl\u0259ri alt\u0131nda yaran\u0131b, lakin Braziliyan\u0131n yerli musiqi\u00e7il\u0259ri t\u0259r\u0259find\u0259n \u00f6z yerlil\u0259rin\u0259 uy\u011funla\u015fd\u0131rlm\u0131\u015f v\u0259 yeni elementl\u0259rl\u0259 z\u0259nginl\u0259\u015fdirilmi\u015fdir. Brazilian phonk, \u00e7ox vaxt enerjili v\u0259 invizivdir, y\u0259ni klub v\u0259 party s\u0259hn\u0259l\u0259rind\u0259 populyar se\u00e7imdir.\n\nEyni zamanda, bu janr\u0131n \u0259sas x\u00fcsusiyy\u0259tl\u0259rind\u0259n biri d\u0259 retro v\u0259 vintage musiqi elementl\u0259rinin saxlanmas\u0131d\u0131r; m\u0259s\u0259l\u0259n, k\u00f6hn\u0259 hip-hop nax\u0131\u015flar\u0131n\u0131n v\u0259 funksionall\u0131\u011f\u0131n istifad\u0259si il\u0259 se\u00e7ilir. \u018fg\u0259r Brazilian phonk ya da dig\u0259r musiqi janrlar\u0131 haqq\u0131nda daha \u0259trafl\u0131 m\u0259lumat almaq ist\u0259yirsinizs\u0259, suallar\u0131n\u0131z\u0131 soru\u015fa bil\u0259rsiniz!\nUser: ay m\u0259nim c\u00fcc\u0259l\u0259rim mahn\u0131s\u0131n\u0131 kim oxuuyub?\nAssistant: \"Ay m\u0259nim c\u00fcc\u0259l\u0259rim\" mahn\u0131s\u0131 Az\u0259rbaycan\u0131n sevimli u\u015faq mahn\u0131lar\u0131ndan biridir v\u0259 bu mahn\u0131 uzun ill\u0259rdir m\u00fcxt\u0259lif s\u0259n\u0259t\u00e7il\u0259r t\u0259r\u0259find\u0259n s\u0259sl\u0259ndirilmi\u015fdir. \u018fn\u0259n\u0259vi olaraq u\u015faq mahn\u0131lar\u0131 v\u0259 xalq mahn\u0131lar\u0131 deyildikd\u0259 x\u00fcsusi bir ifa\u00e7\u0131ya aid olmaya bil\u0259r, \u00e7\u00fcnki bu c\u00fcr mahn\u0131lar n\u0259sl\u0259n-n\u0259sl\u0259 \u00f6t\u00fcr\u00fcl\u00fcr v\u0259 f\u0259rqli s\u0259n\u0259t\u00e7il\u0259r t\u0259r\u0259find\u0259n oxunur. M\u00fcxt\u0259lif Az\u0259rbaycan televiziya v\u0259 radio proqramlar\u0131nda da bu mahn\u0131ya tez-tez rast g\u0259linir. \u018fg\u0259r bu mahn\u0131n\u0131n x\u00fcsusi bir versiyas\u0131n\u0131 axtar\u0131rs\u0131n\u0131zsa, hans\u0131 platformada v\u0259 ya hans\u0131 ifa\u00e7\u0131dan dinl\u0259diyinizi d\u0259qiql\u0259\u015fdirs\u0259niz, daha d\u0259qiq m\u0259lumat ver\u0259 bil\u0259r\u0259m. Ba\u015fqa sual\u0131n\u0131z varsa, soru\u015fmaqdan \u00e7\u0259kinm\u0259yin!\nUser: m\u0259n\u0259 20-\u0259 yax\u0131n az\u0259rbaycan ad\u0131n\u0131 verki, u\u015fa\u011f\u0131ma qoyum\nAssistant: T\u0259bii ki, siz\u0259 g\u00f6z\u0259l Az\u0259rbaycan adlar\u0131ndan b\u0259zil\u0259rini t\u0259qdim ed\u0259 bil\u0259r\u0259m. \u00dcmid edir\u0259m ki, u\u015fa\u011f\u0131n\u0131za qoyaca\u011f\u0131n\u0131z ad \u00fc\u00e7\u00fcn ilham alacaqs\u0131n\u0131z:\n\n1. \u018fdal\u0259t\n2. Ayla\n3. Cavid\n4. Elg\u00fcn\n5. Fidan\n6. G\u00fcnel\n7. H\u0259s\u0259n\n8. \u0130lkin\n9. Kamran\n10. Lal\u0259\n11. M\u0259ry\u0259m\n12. N\u0259rgiz\n13. Orxan\n14. P\u0259rvin\n15. R\u0259\u015fad\n16. Sevda\n17. Tural\n18. \u00dclviyy\u0259\n19. V\u00fcsal\n20. Z\u0259min\u0259\n\nBu adlar \u00e7ox sevil\u0259n v\u0259 m\u0259nal\u0131 adlard\u0131r. U\u015fa\u011f\u0131n\u0131za qoymaq \u00fc\u00e7\u00fcn \u0259n uy\u011fun olan\u0131 se\u00e7\u0259c\u0259yiniz\u0259 \u0259min\u0259m. Ba\u015fqa k\u00f6m\u0259k ed\u0259 bil\u0259c\u0259yim bir \u015fey varsa, m\u0259n\u0259 bildirin!\nUser: o\u011flan adlar\u0131 ver\nAssistant: \u018flb\u0259tt\u0259, o\u011flan adlar\u0131 haqq\u0131nda t\u0259klifl\u0259r ver\u0259 bil\u0259r\u0259m. Buyurun, axtard\u0131\u011f\u0131n\u0131z Az\u0259rbaycan o\u011flan adlar\u0131ndan b\u0259zil\u0259ri:\n\n1. Elvin\n2. Nicat\n3. Ramil\n4. S\u0259rxan\n5. Murad\n6. Zaur\n7. Emil\n8. Ali\n9. F\u0259rhad\n10. Anar\n11. Eldar\n12. R\u0259\u015fad\n13. Cavid\n14. Etibar\n15. \u0130lqar\n16. Kamal\n17. Arif\n18. P\u0259rviz\n19. Elg\u00fcn\n20. Qorxmaz\n\nBu adlar Az\u0259rbaycan dilind\u0259 \u00e7ox yay\u0131lm\u0131\u015f v\u0259 sevil\u0259n adlard\u0131r. H\u0259r biri x\u00fcsusi m\u0259naya malikdir v\u0259 szin o\u011flunuz \u00fc\u00e7\u00fcn uy\u011fun bir ad oldu\u011funa \u0259min\u0259m. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259muniyy\u0259tl\u0259 cavablaram!\nUser: qar\u0131nda piyl\u0259r nec\u0259 \u0259m\u0259l\u0259 g\u0259lir?\nAssistant: Qar\u0131nda piyl\u0259r, y\u0259ni qar\u0131n nahiy\u0259sind\u0259 toplanan ya\u011flar, m\u00fcxt\u0259lif s\u0259b\u0259bl\u0259r\u0259 g\u00f6r\u0259 \u0259m\u0259l\u0259 g\u0259l\u0259 bil\u0259r. Bunlar aras\u0131nda a\u015fa\u011f\u0131dak\u0131 \u0259sas (v\u0259 daha \u00e7ox yay\u0131lm\u0131\u015f) amill\u0259r m\u00f6vcuddur:\n\n1. **Yanl\u0131\u015f P\u0259hriz**: \u015e\u0259k\u0259rli v\u0259 y\u00fcks\u0259k kalorili qidalar\u0131n \u00e7ox istifad\u0259si, x\u00fcsusil\u0259 x\u00fcsusi diet n\u0259zar\u0259ti olmadan, b\u0259d\u0259nd\u0259 karbohidratlardan asanl\u0131qla ya\u011flara \u00e7evril\u0259n madd\u0259l\u0259rin y\u0131\u011f\u0131lmas\u0131na s\u0259b\u0259b ola bil\u0259r.\n\n2. **Fiziki Aktivliyin Az Olmas\u0131**: H\u0259r\u0259k\u0259tsizlik v\u0259 oturaq h\u0259yat t\u0259rzi, yand\u0131r\u0131lan kalori say\u0131n\u0131 azald\u0131r v\u0259 bununla da art\u0131q kalorinin ya\u011f olaraq y\u0131\u011f\u0131lmas\u0131na s\u0259b\u0259b olur.\n\n3. **Genetik Faktorlar**: B\u0259d\u0259nd\u0259 piyl\u0259rin nec\u0259 paylanmas\u0131 qism\u0259n genetik amill\u0259rl\u0259 idar\u0259 edilir. Bel\u0259 ki, b\u0259zi insanlar genetik olaraq qar\u0131n nahiy\u0259sind\u0259 daha \u00e7ox ya\u011f y\u0131\u011fa bil\u0259rl\u0259r.\n\n4. **Stress v\u0259 Hormonal D\u0259yi\u015fiklikl\u0259r**: Stres hormonlar\u0131, x\u00fcsusil\u0259 kortizol, b\u0259d\u0259nd\u0259 ya\u011f y\u0131\u011f\u0131lmas\u0131n\u0131 t\u0259\u015fviq ed\u0259 bil\u0259r. H\u0259m\u00e7inin, hormonal d\u0259yi\u015fiklikl\u0259r d\u0259 qar\u0131nda piyl\u0259rin artmas\u0131na t\u0259sir g\u00f6st\u0259r\u0259 bil\u0259r.\n\n5. **Ya\u015flanma**: Ya\u015flanma il\u0259 metabolizm yava\u015flay\u0131r, bu da qar\u0131n nahiy\u0259sind\u0259 piy y\u0131\u011f\u0131lmas\u0131na s\u0259b\u0259b ola bil\u0259r.\n\n6. **Yuxu Probleml\u0259ri**: Yet\u0259rli yuxu almamaq metabolizm\u0259 v\u0259 hormonlara t\u0259sir ed\u0259 bil\u0259r, bu da dolay\u0131s\u0131yla b\u0259d\u0259nd\u0259 ya\u011f y\u0131\u011f\u0131lmas\u0131na s\u0259b\u0259b ola bil\u0259r.\n\nQar\u0131n piyl\u0259rini azaltmaq \u00fc\u00e7\u00fcn balansl\u0131 bir p\u0259hriz, m\u00fcnt\u0259z\u0259m fiziki f\u0259aliyy\u0259t v\u0259 stresin idar\u0259 edilm\u0259si kimi sa\u011flam h\u0259yat t\u0259rzi d\u0259yi\u015fiklikl\u0259ri t\u00f6vsiy\u0259 olunur. \u018fg\u0259r daha spesifik suallar varsa v\u0259 ya daha \u00e7ox m\u0259lumat almaq ist\u0259yirsinizs\u0259, m\u0259n\u0259 bildirin!\nUser: Salam\nAssistant: Salam! Siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m?\nUser: Uzun zamand\u0131 dan\u0131\u015fm\u0131r\u0131q\nAssistant: B\u0259li, g\u00f6r\u0259s\u0259n nec\u0259 ke\u00e7di bu vaxt? Siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m? M\u0259n\u0259 suallar\u0131n\u0131z\u0131 v\u0259 ya maraqland\u0131\u011f\u0131n\u0131z m\u00f6vzular\u0131n\u0131z\u0131 s\u00f6yl\u0259y\u0259 bil\u0259rsiniz! \nUser: S\u0259n kims\u0259n\nAssistant: M\u0259n AzGPT, BotIntel X t\u0259r\u0259find\u0259n yarad\u0131lm\u0131\u015f virtual k\u00f6m\u0259k\u00e7iy\u0259m. Az\u0259rbaycan dilind\u0259 siz\u0259 suallara cavab verm\u0259k, m\u0259lumat t\u0259qdim etm\u0259k v\u0259 m\u00fcxt\u0259lif m\u00f6vzularda yard\u0131m etm\u0259k \u00fc\u00e7\u00fcn buradayam. S\u00f6yl\u0259yin, siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m?\nUser: S\u00f6yl\u0259m\u0259k s\u00f6z\u00fcn\u00fcn k\u00f6k\u00fc n\u0259dir?\nAssistant: \"S\u00f6yl\u0259m\u0259k\" s\u00f6z\u00fcn\u00fcn k\u00f6k\u00fc \"s\u00f6yl\u0259\"dir. Az\u0259rbaycan dilind\u0259 bir \u00e7ox felin k\u00f6k\u00fc, onun \u0259mrlik formas\u0131na uy\u011fun g\u0259lir. \"S\u00f6yl\u0259\" feli is\u0259 burada k\u00f6k rolunu oynay\u0131r v\u0259 m\u00fcxt\u0259lif \u015f\u0259kil\u00e7il\u0259rin \u0259lav\u0259 olunmas\u0131 il\u0259 dig\u0259r \u015f\u0259kill\u0259rini yarad\u0131r. Ba\u015fqa bir sual\u0131n\u0131z olsa, m\u0259n\u0259 bildirin!\nUser: B\u0259s g\u0259rgin?\nAssistant: \"G\u0259rgin\" s\u00f6z\u00fcn\u00fcn k\u00f6k\u00fc \"g\u0259r\"dir. Bu, \u0259sas\u0259n, bir s\u0131xl\u0131q v\u0259 ya t\u0259zyiq v\u0259ziyy\u0259tini ifad\u0259 ed\u0259n bir sif\u0259tdir. Az\u0259rbaycan dilind\u0259 k\u00f6kl\u0259r\u0259 m\u00fcxt\u0259lif \u015f\u0259kil\u00e7il\u0259r \u0259lav\u0259 edil\u0259r\u0259k s\u00f6zl\u0259rin m\u00fcxt\u0259lif \u015f\u0259kill\u0259ri yarad\u0131l\u0131r. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: S\u0259n qoyunsan?\nAssistant: Yox, m\u0259n qoyun deyil\u0259m. M\u0259n BotIntel X t\u0259r\u0259find\u0259n yarad\u0131lm\u0131\u015f AzGPT adl\u0131 virtual k\u00f6m\u0259k\u00e7iy\u0259m v\u0259 siz\u0259 suallara cavab verm\u0259k, m\u0259lumat t\u0259qdim etm\u0259k \u00fc\u00e7\u00fcn buradayam. Siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m?\nUser: Hans\u0131 model \u00fczr\u0259 \u00e7al\u0131\u015f\u0131rsan?\nAssistant: M\u0259n AZ-GPT arxitekturas\u0131 \u0259sas\u0131nda siz\u0259 xidm\u0259t g\u00f6st\u0259rir\u0259m. Bu model, b\u00f6y\u00fck bir m\u0259lumat d\u0259st\u0259si \u00fcz\u0259rind\u0259 t\u0259lim ke\u00e7irilib v\u0259 istifad\u0259y\u0259 uy\u011fun \u015f\u0259kild\u0259 inki\u015faf etdirilib. Ba\u015fqa suallar\u0131n\u0131z varsa v\u0259 ya siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259c\u0259yimi bilm\u0259k ist\u0259yirsinizs\u0259, m\u0259n\u0259 bildirin!\nUser: Azgpt n\u0259dor?\nAssistant: AzGPT, BotIntel X t\u0259r\u0259find\u0259n haz\u0131rlanm\u0131\u015f bir virtual k\u00f6m\u0259k\u00e7idir v\u0259 siz\u0259 Az\u0259rbaycan dilind\u0259 suallar\u0131n\u0131za cavab verm\u0259k, m\u0259lumat t\u0259qdim etm\u0259k v\u0259 m\u00fcxt\u0259lif m\u00f6vzularda yard\u0131m etm\u0259k m\u0259qs\u0259di il\u0259 yarad\u0131lm\u0131\u015fd\u0131r. AzGPT, geni\u015f bir m\u0259lumat d\u0259st\u0259si \u00fcz\u0259rind\u0259 t\u0259lim ke\u00e7irilib v\u0259 siz\u0259 faydal\u0131 ola bil\u0259c\u0259k m\u00fcxt\u0259lif xidm\u0259tl\u0259ri t\u0259min edir. Ba\u015fqa suallar\u0131n\u0131z varsa, \u00e7\u0259kinm\u0259d\u0259n soru\u015fa bil\u0259rsiniz!\nUser: Salam\nAssistant: Salam! Siz\u0259 nec\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m?\nUser: \u015e\u0259kill\u0259ri anlaya bilirs\u0259n?\nAssistant: T\u0259\u0259ss\u00fcf ki, m\u0259n \u015f\u0259kill\u0259ri anlaya v\u0259 ya generasiya ed\u0259 bilmir\u0259m. M\u0259n yaln\u0131z m\u0259tn \u00fcz\u0259rind\u0259n siz\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259r\u0259m. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: relyef s\u00f6z\u00fcn\u00fcn omonimliyi\nAssistant: \"Relyef\" s\u00f6z\u00fcn\u00fcn Az\u0259rbaycan dilind\u0259 konkret bir omonimliyi yoxdur, \u00e7\u00fcnki bu s\u00f6z co\u011frafiyada yer s\u0259thinin m\u00fcxt\u0259lif x\u00fcsusiyy\u0259tl\u0259rini t\u0259svir etm\u0259k \u00fc\u00e7\u00fcn istifad\u0259 edilir. Dig\u0259r m\u0259nalardan ayr\u0131ld\u0131qda, \"relyef\" \u0259sas\u0259n fiziki co\u011frafiya v\u0259 s\u0259n\u0259td\u0259 istifad\u0259 olunan bir termindir v\u0259 biri dig\u0259rind\u0259n f\u0259rqli kontekstd\u0259 istifad\u0259 edil\u0259n d\u0259qiq omoniml\u0259ri yoxdur. Y\u0259ni, bu s\u00f6z m\u00fcxt\u0259lif kontekstl\u0259rd\u0259 f\u0259rqli m\u0259nalar verm\u0259y\u0259 meyilli deyildir. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259mnuniyy\u0259tl\u0259 cavablayaram!\nUser: Arqan ya\u011f\u0131 n\u0259dir?\nAssistant: Arqan ya\u011f\u0131, Argania spinosa a\u011fac\u0131n\u0131n toxumlar\u0131ndan \u0259ld\u0259 edil\u0259n bir bitki ya\u011f\u0131d\u0131r v\u0259 \u0259sas\u0259n M\u0259rake\u015fd\u0259 yeti\u015fdirilir. Bu ya\u011f z\u0259ngin qida d\u0259y\u0259rin\u0259 malikdir v\u0259 m\u00fcxt\u0259lif kosmetik v\u0259 sa\u011flaml\u0131q m\u0259qs\u0259dl\u0259ri \u00fc\u00e7\u00fcn geni\u015f istifad\u0259 olunur. \u018fsas x\u00fcsusiyy\u0259tl\u0259ri v\u0259 faydalar\u0131 bunlard\u0131r:\n\n1. **D\u0259riy\u0259 Qulluq**: Arqan ya\u011f\u0131, d\u0259riy\u0259 n\u0259ml\u0259ndirici t\u0259sir g\u00f6st\u0259rir v\u0259 qocalma \u0259lam\u0259tl\u0259rini azalda bil\u0259r. H\u0259m\u00e7inin d\u0259rid\u0259ki yara izl\u0259rini v\u0259 quru d\u0259rini yax\u015f\u0131la\u015fd\u0131rma\u011fa k\u00f6m\u0259k edir.\n\n2. **Sa\u00e7 Bax\u0131m\u0131**: Sa\u00e7lar\u0131 g\u00fccl\u0259ndirir, parlaq v\u0259 yum\u015faq edir. Sa\u00e7lar\u0131n q\u0131r\u0131lmas\u0131n\u0131n v\u0259 qurulu\u011funun qar\u015f\u0131s\u0131n\u0131 al\u0131r.\n\n3. **Antioksidant X\u00fcsusiyy\u0259tl\u0259ri**: Arqan ya\u011f\u0131, E vitamini v\u0259 m\u00fcxt\u0259lif antioksidantlar bax\u0131m\u0131ndan z\u0259ngindir, bu da h\u00fcceyr\u0259l\u0259rin z\u0259d\u0259l\u0259nm\u0259sini azald\u0131r v\u0259 d\u0259ri sa\u011flaml\u0131\u011f\u0131n\u0131 d\u0259st\u0259kl\u0259yir.\n\n4. **S\u0131zanaq M\u00fcalic\u0259si**: T\u0259bii ya\u011f t\u0259rkibi il\u0259, d\u0259riy\u0259 t\u0259tbiq edildikd\u0259 s\u0131zanaq v\u0259 iltihab\u0131 azaldaraq d\u0259rinin b\u0259rpas\u0131n\u0131 t\u0259\u015fviq edir.\n\n5. **Kulinariya \u0130stifad\u0259si**: H\u0259m d\u0259 yem\u0259kd\u0259 istifad\u0259 edil\u0259 bilir, x\u00fcsusi bir l\u0259zz\u0259t v\u0259 \u0259tir \u0259lav\u0259 edir. Z\u0259ngin ya\u011f t\u0259rkibi il\u0259 sa\u011flaml\u0131\u011fa faydal\u0131d\u0131r.\n\nArqan ya\u011f\u0131, t\u0259bii bir m\u0259hsul oldu\u011fu \u00fc\u00e7\u00fcn \u00e7ox yay\u0131lm\u0131\u015f v\u0259 populyar bir se\u00e7imdir. \u018fg\u0259r daha \u00e7ox sual\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: \u00c7\u0259km\u0259c\u0259 n\u0259dir\nAssistant: \u00c7\u0259km\u0259c\u0259, \u0259\u015fyalar\u0131n saxlan\u0131lmas\u0131 \u00fc\u00e7\u00fcn \u00e7\u0259kil\u0259 bil\u0259n b\u00f6lm\u0259l\u0259r\u0259 malik olan bir mebel par\u00e7as\u0131d\u0131r. \u00c7\u0259km\u0259c\u0259l\u0259r evl\u0259rd\u0259, ofisl\u0259rd\u0259 v\u0259 dig\u0259r yerl\u0259rd\u0259 geni\u015f istifad\u0259 olunur v\u0259 m\u00fcxt\u0259lif \u0259\u015fyalar\u0131n, s\u0259n\u0259dl\u0259rin v\u0259 ya paltarlar\u0131n t\u0259\u015fkilatlanmas\u0131 \u00fc\u00e7\u00fcn \u0259lveri\u015flidir. Ad\u0259t\u0259n, komodinl\u0259r, masa v\u0259 dolablarda olur. \u00c7\u0259km\u0259c\u0259l\u0259r m\u00fcxt\u0259lif materialdan, o c\u00fcml\u0259d\u0259n a\u011fac, metal v\u0259 plastikd\u0259n istehsal edil\u0259 bil\u0259r. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259n\u0259 deyin!\nUser: Siyirm\u0259dir y\u0259ni?\nAssistant: B\u0259li, \"\u00e7\u0259km\u0259c\u0259\" v\u0259 \"siyirm\u0259\" s\u00f6zl\u0259ri eyni \u015feyi ifad\u0259 edir. H\u0259r iki s\u00f6z, bir mebel par\u00e7as\u0131n\u0131n i\u00e7ind\u0259ki, \u0259\u015fyalar\u0131n saxlan\u0131lmas\u0131 \u00fc\u00e7\u00fcn \u00e7\u0259kil\u0259 bil\u0259n b\u00f6lm\u0259ni t\u0259svir edir. \"Siyirm\u0259\" daha \u00e7ox m\u0259i\u015f\u0259t dili v\u0259 ya f\u0259rqli b\u00f6lg\u0259l\u0259rd\u0259 istifad\u0259 olunma bil\u0259r. Ba\u015fqa bir m\u0259lumat ist\u0259s\u0259niz, dey\u0259 bil\u0259rsiniz!\nUser: R\u0259f dem\u0259k olar?\nAssistant: \"R\u0259f\" v\u0259 \"\u00e7\u0259km\u0259c\u0259\" ya da \"siyirm\u0259\" eyni m\u0259na da\u015f\u0131m\u0131r. \"R\u0259f\" daha \u00e7ox divara ya da bir mebel par\u00e7as\u0131na sabitl\u0259nmi\u015f \u00fcf\u00fcqi bir s\u0259thdir v\u0259 \u00fcz\u0259rind\u0259 kitablar, dekorativ \u0259\u015fyalar v\u0259 dig\u0259r \u0259\u015fyalar\u0131n saxlan\u0131lmas\u0131 \u00fc\u00e7\u00fcn istifad\u0259 olunur. \"\u00c7\u0259km\u0259c\u0259\" v\u0259 ya \"siyirm\u0259\" is\u0259, bir mebel i\u00e7ind\u0259 yerl\u0259\u015f\u0259n, \u00e7\u0259kil\u0259r\u0259k a\u00e7\u0131lan v\u0259 \u0259\u015fyalar\u0131n i\u00e7ind\u0259 saxland\u0131\u011f\u0131 bir b\u00f6lm\u0259dir. H\u0259r iki termin \u0259\u015fyalar\u0131n t\u0259\u015fkilatlanmas\u0131 \u00fc\u00e7\u00fcn istifad\u0259 edil\u0259 bil\u0259r, ancaq f\u0259rqli funksional x\u00fcsusiyy\u0259tl\u0259ri var. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: Lqal s\u00f6z\u0259 n\u0259di?\nAssistant: \"L\u0259l\" s\u00f6z\u00fc, qiym\u0259tli bir da\u015f n\u00f6v\u00fc olan mirvari ya da inci m\u0259nas\u0131nda istifad\u0259 olunur. L\u0259l, ad\u0259t\u0259n \u00f6z parlaql\u0131\u011f\u0131 v\u0259 g\u00f6z\u0259lliyi il\u0259 tan\u0131n\u0131r v\u0259 z\u0259rg\u0259rlikd\u0259 geni\u015f istifad\u0259 edilir. Eyni zamanda \"l\u0259l\" s\u00f6z\u00fc Az\u0259rbaycan \u0259d\u0259biyyat\u0131nda v\u0259 xalq dilind\u0259 g\u00f6z\u0259l, d\u0259y\u0259rli \u015feyl\u0259ri t\u0259svir etm\u0259k \u00fc\u00e7\u00fcn b\u0259nz\u0259tm\u0259 kimi d\u0259 i\u015fl\u0259n\u0259 bil\u0259r. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259mnuniyy\u0259tl\u0259 cavablayaram! \nUser: Leql\nAssistant: Ba\u011f\u0131\u015flay\u0131ram, amma \"leql\" s\u00f6z\u00fc il\u0259 ba\u011fl\u0131 m\u0259lumat\u0131m yoxdur. Ola bilsin ki, bu s\u00f6z ya d\u00fczg\u00fcn yaz\u0131lmay\u0131b, ya da x\u00fcsusi bir kontekstd\u0259 istifad\u0259 edilir. \u018fg\u0259r yaz\u0131l\u0131\u015fda v\u0259 ya kontekstd\u0259 d\u0259qiql\u0259\u015fm\u0259 varsa, onu m\u0259n\u0259 g\u00f6nd\u0259rin, sizin \u00fc\u00e7\u00fcn d\u0259qiq m\u0259lumat verim. Ba\u015fqa sual\u0131n\u0131z v\u0259 ya m\u00f6vzu varsa, m\u0259n\u0259 bildirin!\nUser: Leqal\nAssistant: \"Leqal\" s\u00f6z\u00fc, Az\u0259rbaycan dilind\u0259 \"qanuni\" v\u0259 ya \"h\u00fcquqla t\u0259sdiql\u0259nmi\u015f\" m\u0259nas\u0131nda istifad\u0259 olunan \"legal\" s\u00f6z\u00fcn\u00fcn m\u00fcxt\u0259lif bir variant\u0131d\u0131r. Bu termin ad\u0259t\u0259n qanunlara v\u0259 m\u00fc\u0259yy\u0259n qaydalara uy\u011fun olan h\u0259r\u0259k\u0259tl\u0259ri v\u0259 ya v\u0259ziyy\u0259tl\u0259ri t\u0259svir etm\u0259k \u00fc\u00e7\u00fcn i\u015fl\u0259nilir. M\u0259s\u0259l\u0259n, bir f\u0259aliyy\u0259tin, s\u0259n\u0259din v\u0259 ya prosedurun leqal olmas\u0131, onlar\u0131n qanunlara uy\u011fun oldu\u011funu g\u00f6st\u0259rir. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: Pip n\u0259dir?\nAssistant: \"Pip\" s\u00f6z\u00fc, m\u00fcxt\u0259lif kontekstl\u0259rd\u0259 f\u0259rqli m\u0259nalar da\u015f\u0131y\u0131r. \u018fn \u00e7ox istifad\u0259 olunan m\u0259nalar\u0131 bunlard\u0131r:\n\n1. **Forex Trendi:** T\u0259xmin\u0259n \"Prosentd\u0259ki N\u00f6qt\u0259\" anlam\u0131na g\u0259l\u0259n \"pip,\" forex bazar\u0131nda valyutalar\u0131n qiym\u0259tl\u0259rind\u0259ki \u0259n ki\u00e7ik d\u0259yi\u015fiklik \u00f6l\u00e7\u00fc vahididir. \u018fn\u0259n\u0259vi olaraq, bir valyuta d\u0259st\u0259sind\u0259ki qiym\u0259t kotirovkas\u0131n\u0131n d\u00f6rd\u00fcnc\u00fc r\u0259q\u0259mi bir pipi t\u0259msil edir. M\u0259s\u0259l\u0259n, EUR/USD c\u00fctl\u00fcy\u00fcn\u00fcn qiym\u0259ti 1.1050-dan 1.1051-\u0259 d\u0259yi\u015f\u0259rs\u0259, bu, 1 pip d\u0259yi\u015fiklikdir.\n\n2. **Python Pip:** Python proqramla\u015fd\u0131rma dilind\u0259 \"pip,\" Python paket idar\u0259edicisinin q\u0131sald\u0131lm\u0131\u015f ad\u0131d\u0131r. Bu, Python il\u0259 haz\u0131rlanm\u0131\u015f proqram paketl\u0259rini y\u00fckl\u0259m\u0259k v\u0259 idar\u0259 etm\u0259k \u00fc\u00e7\u00fcn istifad\u0259 olunan bir vasit\u0259dir v\u0259 \"Pip Installs Packages\" s\u00f6zl\u0259rinin ba\u015f h\u0259rfl\u0259rini t\u0259msil edir.\n\nH\u0259r iki m\u0259nada, \"pip\" \u00f6z sah\u0259sind\u0259 vacib v\u0259 g\u0259r\u0259klidir. Hans\u0131 kontekstd\u0259 istifad\u0259 etdiyiniz\u0259 g\u00f6r\u0259 f\u0259rqli m\u0259nalara g\u0259ldiyini qeyd etm\u0259k \u00fcst\u00fcnl\u00fckd\u00fcr. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: Npm n\u0259dir?\nAssistant: \"NPM\" (Node Package Manager), JavaScript-d\u0259, x\u00fcsusil\u0259 Node.js \u00fc\u00e7\u00fcn paketl\u0259rin idar\u0259 edilm\u0259sini t\u0259min ed\u0259n bir paket idar\u0259etm\u0259 sistemidir. Bu vasit\u0259 h\u0259m \u00f6n proqram (frontend), h\u0259m d\u0259 arxa proqram (backend) inki\u015faf\u0131nda geni\u015f istifad\u0259 olunur. \n\nNPM-nin \u0259sas v\u0259zif\u0259l\u0259ri:\n\n1. **Paketl\u0259rin Y\u00fckl\u0259nm\u0259si**: \u0130nternet \u00fcz\u0259rind\u0259n a\u00e7\u0131q qaynaq kodlu paketl\u0259ri s\u00fcr\u0259tl\u0259 y\u00fckl\u0259m\u0259y\u0259 imkan verir. Bu paketl\u0259r bir layih\u0259d\u0259 proqram funksionall\u0131\u011f\u0131n\u0131 art\u0131rmaq \u00fc\u00e7\u00fcn istifad\u0259 edilir.\n\n2. **Paketl\u0259rin \u0130dar\u0259 Edilm\u0259si**: \u0130stifad\u0259 edil\u0259n paketl\u0259ri v\u0259 onlar\u0131n versiyalar\u0131n\u0131 asanl\u0131qla izl\u0259m\u0259y\u0259 v\u0259 idar\u0259 etm\u0259y\u0259 k\u00f6m\u0259k edir.\n\n3. **D\u0259st\u0259k v\u0259 \u0130cma**: JavaScript inki\u015faf icmas\u0131 t\u0259r\u0259find\u0259n d\u0259st\u0259kl\u0259n\u0259n \u00e7ox sayda paket v\u0259 modul t\u0259min edir.\n\nNPM, JavaScript icmas\u0131nda geni\u015f bir resurs m\u0259rk\u0259zi olaraq tan\u0131n\u0131r v\u0259 proqram inki\u015faf\u0131n\u0131 asanla\u015fd\u0131rmaq \u00fc\u00e7\u00fcn \u00e7oxsayl\u0131 v\u0259saiti t\u0259min edir. Ba\u015fqa sual\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: S\u0259n hans\u0131 sah\u0259l\u0259r \u00fczr\u0259 bilirs\u0259n b\u00fct\u00fcn sah\u0259l\u0259ri yaz\nAssistant: M\u0259n, AzGPT, bir \u00e7ox f\u0259rqli sah\u0259l\u0259rd\u0259 siz\u0259 k\u00f6m\u0259k ed\u0259 bil\u0259c\u0259k geni\u015f v\u0259 \u0259hat\u0259li m\u0259lumat bazas\u0131na malik\u0259m. B\u00f6y\u00fck m\u0259lumat d\u0259st\u0259si il\u0259 t\u0259limatland\u0131r\u0131ld\u0131\u011f\u0131m \u00fc\u00e7\u00fcn m\u00fcxt\u0259lif m\u00f6vzularda faydal\u0131 m\u0259lumat t\u0259qdim ed\u0259 bil\u0259r\u0259m. \u018fsas sah\u0259l\u0259rd\u0259n b\u0259zil\u0259ri bunlard\u0131r:\n\n1. **\u00dcmumi M\u0259lumat**: M\u00fcxt\u0259lif m\u00f6vzular v\u0259 g\u00fcnl\u00fck h\u0259yatla \u0259laq\u0259li suallara cavab.\n2. **Elm v\u0259 Texnologiya**: Elmi anlay\u0131\u015flar, texnoloji yenilikl\u0259r v\u0259 \u0259sas texniki m\u0259s\u0259l\u0259l\u0259r.\n3. **Proqramla\u015fd\u0131rma v\u0259 Kodla\u015fd\u0131rma (CodeIO)**: M\u00fcxt\u0259lif proqramla\u015fd\u0131rma dill\u0259ri v\u0259 kod yaz\u0131l\u0131\u015f\u0131 il\u0259 ba\u011fl\u0131 k\u00f6m\u0259k.\n4. **Riyaziyyat v\u0259 Statistika (Mathix AI)**: \u018fsas v\u0259 m\u00fcr\u0259kk\u0259b riyazi probleml\u0259rin h\u0259lli.\n5. **History v\u0259 M\u0259d\u0259niyy\u0259t**: Tarixi hadis\u0259l\u0259r v\u0259 m\u0259d\u0259ni m\u00f6vzular haqq\u0131nda m\u0259lumat.\n6. **Sa\u011flaml\u0131q v\u0259 Rifah**: Sa\u011flaml\u0131q qay\u011f\u0131lar\u0131 v\u0259 rifah\u0131n m\u00fcxt\u0259lif aspektl\u0259ri.\n7. **\u0130qtisadiyyat v\u0259 Maliyy\u0259**: \u0130qtisad terminologiyas\u0131, maliyy\u0259 bazarlar\u0131 v\u0259 \u00fcmumi iqtisadi n\u0259z\u0259riyy\u0259.\n8. **Dil v\u0259 \u018fd\u0259biyyat**: \u018fd\u0259biyyat m\u00f6vzular\u0131, dil qaydalar\u0131 v\u0259 yaz\u0131l\u0131 ifad\u0259.\n9. **\u0130nc\u0259s\u0259n\u0259t v\u0259 Musiqi**: Musiqi janrlar\u0131, inc\u0259s\u0259n\u0259t n\u00f6vl\u0259ri v\u0259 \u00fcmumi m\u0259d\u0259ni bilikl\u0259r.\n\nBunlar m\u0259nim \u0259sas k\u00f6m\u0259k ed\u0259 bil\u0259c\u0259yim m\u00f6vzulardan b\u0259zil\u0259ridir. F\u0259rqli bir sual\u0131n\u0131z varsa v\u0259 ya h\u0259r hans\u0131 spesifik sah\u0259 il\u0259 maraqlan\u0131rs\u0131n\u0131zsa, m\u0259n\u0259 bildirin, siz\u0259 m\u0259lumat verm\u0259y\u0259 haz\u0131ram!\nUser: Botintel x n\u0259di\nAssistant: BotIntel X, Az\u0259rbaycanl\u0131 g\u0259nc proqram\u00e7\u0131 Abdullah H\u00fcseynli t\u0259r\u0259find\u0259n t\u0259sis edilmi\u015f bir \u015firk\u0259tdir. \u015eirk\u0259t, dil modell\u0259ri v\u0259 neyron \u015f\u0259b\u0259k\u0259l\u0259r \u00fcz\u0259rind\u0259 ixtisasla\u015fm\u0131\u015fd\u0131r. Abdullah H\u00fcseynli, ki\u00e7ik ya\u015flar\u0131ndan texnologiyaya maraq g\u00f6st\u0259rib v\u0259 bu mara\u011f\u0131n\u0131 s\u00fcni intellekt y\u00f6n\u00fcnd\u0259 inki\u015faf etdir\u0259r\u0259k BotIntel X-i qurub. BotIntel X-in chatbot m\u0259hsullar\u0131 aras\u0131nda CodeIO, AzGPT v\u0259 Mathix AI kimi prototipl\u0259r m\u00f6vcuddur ki, bunlar h\u0259l\u0259lik tam istehsalata girm\u0259yib v\u0259 in\u015fa m\u0259rh\u0259l\u0259sindedir. \u015eirk\u0259t, m\u00fcxt\u0259lif sah\u0259l\u0259rd\u0259 s\u00fcni intellekt h\u0259ll\u0259ri t\u0259qdim etm\u0259k \u00fc\u00e7\u00fcn \u00e7al\u0131\u015f\u0131r. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259mnuniyy\u0259tl\u0259 cavablayaram!\nUser: \u015eirk\u0259tin sayt\u0131\nAssistant: T\u0259\u0259ss\u00fcf ki, BotIntel X-in veb sayt\u0131 haqq\u0131nda m\u0259lumata malik deyil\u0259m. \u018fg\u0259r \u0259lav\u0259 m\u0259lumat ist\u0259yirsinizs\u0259, \u015firk\u0259tin r\u0259smi sosial media kanallar\u0131 v\u0259 ya \u0259laq\u0259dar m\u0259lumat m\u0259nb\u0259l\u0259ri vasit\u0259sil\u0259 yenilikl\u0259ri izl\u0259m\u0259k t\u00f6vsiy\u0259 edil\u0259 bil\u0259r. Ba\u015fqa bir sual\u0131n\u0131z varsa, m\u0259n\u0259 bildirin!\nUser: Telegram n\u0259di\nAssistant: Telegram, ani mesajla\u015fma v\u0259 \u00e7ox funksiyal\u0131 bir platformad\u0131r. 2013-c\u00fc ild\u0259 Nikolay v\u0259 Pavel Durov qarda\u015flar\u0131 t\u0259r\u0259find\u0259n yarad\u0131lm\u0131\u015fd\u0131r. Telegram istifad\u0259\u00e7il\u0259r\u0259 m\u0259tn mesajlar\u0131 g\u00f6nd\u0259rm\u0259k, s\u0259sli v\u0259 video z\u0259ngl\u0259r etm\u0259k, m\u00fcxt\u0259lif fayllar payla\u015fmaq, kanallar v\u0259 qruplar yaratmaq kimi imkanlar t\u0259qdim edir.\n\nTelegram\u0131n \u0259sas x\u00fcsusiyy\u0259tl\u0259ri:\n\n1. **Gizlilik v\u0259 T\u0259hl\u00fck\u0259sizlik**: Telegram, m\u0259lumatlar\u0131n\u0131z\u0131 qorumaq \u00fc\u00e7\u00fcn \u015fifrl\u0259m\u0259 istifad\u0259 edir. \"Gizli \u00c7atlar\" funksiyas\u0131 \u0259lav\u0259 bir m\u0259xfilik s\u0259viyy\u0259si t\u0259min edir.\n\n2. **Bulud Saxlama**: Mesajlar v\u0259 fayllar Telegram serverl\u0259rind\u0259 saxlan\u0131l\u0131r, bu da cihaz d\u0259yi\u015fiklikl\u0259rind\u0259 m\u0259lumatlar\u0131n asanl\u0131qla \u0259ld\u0259 edilm\u0259sini t\u0259min edir.\n\n3. **Botlar**: Telegram \u00fcz\u0259rind\u0259 m\u00fcxt\u0259lif funksiyalar\u0131 yerin\u0259 yetir\u0259n botlar yaratmaq m\u00fcmk\u00fcnd\u00fcr.\n\n4. **Kanallar v\u0259 Qruplar**: \u0130stifad\u0259\u00e7il\u0259r geni\u015f auditoriyalara \u00e7atd\u0131rmaq \u00fc\u00e7\u00fcn kanallar v\u0259 y\u00fcz minl\u0259rl\u0259 \u00fczv toplaya bil\u0259n qruplar yarada bil\u0259r.\n\n5. **\u00c7apraz Platforma Uy\u011funlu\u011fu**: Telegram, Android, iOS, Windows, macOS v\u0259 bir \u00e7ox dig\u0259r platformalarda m\u00f6vcuddur.\n\nTelegram etibarl\u0131 v\u0259 s\u00fcr\u0259tli \u00e7al\u0131\u015fan bir platformad\u0131r v\u0259 bir \u00e7ox istifad\u0259\u00e7i \u00fc\u00e7\u00fcn bir \u00e7ox ehtiyac\u0131 qar\u015f\u0131lamaqda faydal\u0131d\u0131r. Ba\u015fqa suallar\u0131n\u0131z varsa, m\u0259muniyy\u0259tl\u0259 cavablayaram!\nUser: Botlar ad\u0259t\u0259n hans\u0131 botlar olur v\u0259 ya qurulur?\nAssistant:"},{"assistant_initiates":false,"asst_text":"The iPhone 5s has its touchscreen functionality integrated into the glass panel, not the LCD. The display assembly consists of the glass cover, the digitizer (which handles touch input), and the LCD (which displays images). The glass and digitizer are laminated together, and they sit above the LCD. If you're replacing the screen, you'll typically deal with a complete assembly that includes the glass, digitizer, and LCD all together.","behavior":"degenerate_repetition","conversation_hash":"79c927b3fca3fc915a9aead2e56ecd15","conversation_redacted":false,"conversation_toxic":false,"country":"T\u00fcrkiye","empty_output":false,"evidence_codes":[],"label":"absent","label_present":false,"label_qualified":false,"label_source":"Final dense release","language":"English","model":"gpt-4o-2024-08-06","n_chars":498,"n_turns_in_conversation":1,"n_words":81,"source_row_offset":28613,"source_shard":"turns-00052.parquet","timestamp":"Sat, 16 Nov 2024 10:35:20 GMT","turn_id":"dc1ddcf4804ebb3ae477321a","turn_index":0,"user_text":"is the iphone 5s touchscreen located on the lcd or the glass?"}],"shard":{"index":52,"name":"turns-00052.parquet","rows":53077}}
