ChatGPT 轻松管理聊天

搜索聊天、过滤聊天、快速/批量删除聊天。

当前为 2025-06-03 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name                   ChatGPT Easy Chat Management
// @name:ckb               Chatgpt بە ئاسانی بەڕێوەبردنی چاتەکان
// @name:zu                I-Chatgpt ukuphatha izingxoxo kalula
// @name:yo                Lightig wa ni rọọrun ṣakoso awọn ibaraẹnisọrọ
// @name:en-GB             ChatGPT Easily manage chats
// @name:zh-HK             ChatGPT 輕鬆管理聊天
// @name:zh-MO             ChatGPT 輕鬆管理聊天
// @name:zh-MY             ChatGPT 轻松管理聊天
// @name:zh-SG             ChatGPT 轻松管理聊天
// @name:zh                ChatGPT 轻松管理聊天
// @name:xh                I-CHATGPPT ilawula ngokulula iincoko
// @name:yi                טשאַטגפּט לייכט פירן טשאַץ
// @name:fr-CA             Chatgpt Gérez facilement les chats
// @name:wo                ChatGPT
// @name:zh-TW             ChatGPT 輕鬆管理聊天
// @name:ve                ChatGPT ni lavhelese nga hu leluwaho nyambedzano
// @name:vi                Chatgpt dễ dàng quản lý các cuộc trò chuyện
// @name:uz                Chatgpt Kamchiliklarni osongina boshqaradi
// @name:ur                چیٹ آسانی سے چیٹس کا انتظام کرتے ہیں
// @name:ug                Chatgpt ئاسانلا چاتاقنى باشقۇرىدۇ
// @name:ty                Te faatere nei o ChatGPT i te mau aparauraa
// @name:tw                ChatGPT yɛ mmerɛw sɛ wobɛhwɛ nkɔmmɔbɔ so .
// @name:uk                Чатгпт легко керувати чатами
// @name:tt                Чатгипт чатлар белән идарә итә
// @name:ts                Chatgpt hi ku olova lawula ti-chat .
// @name:tr                Chatgpt sohbetleri kolayca yönetin
// @name:to                ChatGPT Pule’i Faingofua ’a e ngaahi talanoa .
// @name:tn                ChatGPT Go laola dipuisano tse di bonolo
// @name:tl                Ang chatgpt ay madaling pamahalaan ang mga chat
// @name:ti                CHATGPT ንታት ብቐሊሉ የመሓድር
// @name:tk                ChatGPton sygyrlary aňsatlyk bilen dolandyryň
// @name:tg                Чатчпппппппппсро идора кунед
// @name:th                CHATGPT จัดการแชทได้อย่างง่ายดาย
// @name:te                చాట్‌గ్ప్ట్ చాట్‌లను సులభంగా నిర్వహించండి
// @name:sw                Chatgpt kusimamia kwa urahisi mazungumzo
// @name:su                ChatGPS gampang ngatur chats
// @name:ta                அரட்டைகளை எளிதில் நிர்வகிக்கவும்
// @name:sv                Chatgpt hanterar enkelt chattar
// @name:st                Chatgpt Hantle habonolo
// @name:ss                I-ChatGPT ilawula kahle tingcoco
// @name:sq                Chatgpt menaxhoni me lehtësi bisedat
// @name:so                CHATGPTPTPTPTPTPTPTPT SITE waxay maamushaa sheekaysiga
// @name:sn                Chatgpt inogadzirisa nyore chats
// @name:sm                Talatalanoaga faigofie ona puleaina talatalanoaga
// @name:sr                ЦхатГпт Лако управљајте четовима
// @name:sl                Chatgpt enostavno upravljati klepete
// @name:sk                Chatgpt ľahko spravovať rozhovory
// @name:si                චැට් පහසුවෙන් සංදර්ශන කළමනාකරණය කරන්න
// @name:sh                ЦхатГпт Лако управљајте четовима
// @name:sg                ChatGPT Esily ti sara lisoro na azo .
// @name:se                ChatGPT álkit hálddašit ságastallamiid
// @name:sd                چٽپٽ آسانيء سان چٽ کي منظم ڪري ٿو
// @name:sa                चॅट्जीपीटी सहजतया गपशपं प्रबन्धयन्तु।
// @name:rw                Ikiganiro Byoroshye Gucunga Ibiganiro
// @name:ro                Chatgpt gestionează cu ușurință chaturile
// @name:rn                ChatGPT Gucungera neza ubutumwa
// @name:qu                chatgpt fácilmente manejar chats .
// @name:ru                Chatgpt легко управлять чатами
// @name:ps                د چیټکوټ په اسانۍ سره چاټونه اداره کوي
// @name:pl                Chatgpt łatwo zarządzaj czatami
// @name:pa                ਚੱਟਾਨਾਂ ਨੂੰ ਆਸਾਨੀ ਨਾਲ ਪ੍ਰਬੰਧਿਤ ਕਰੋ
// @name:os                ChatGPT æнцонæй къухдариуæг кæны чатæн
// @name:pt-BR             Chatgpt gerencia facilmente bate -papos
// @name:pt-PT             Chatgpt gerencia facilmente bate -papos
// @name:pt                Chatgpt gerencia facilmente bate -papos
// @name:or                ଚାଟ୍ ଟୁଟି ସହଜରେ ଚଟାଣ ପରିଚାଳନା କରନ୍ତୁ |
// @name:oc                ChatGPT gestionar facilmente los chats .
// @name:om                Chatgpt Chaat salphaatti bulchuu .
// @name:ny                ChatGTT SART TRAMISH
// @name:nr                Fala /Suma Susa .
// @name:nb                Chatgpt klarer enkelt chatter
// @name:nl                Chatgpt beheren eenvoudig chats
// @name:ne                च्याट गर्न सजीलो CHTST CHEST
// @name:my                chatgpt အလွယ်တကူ chats ကိုစီမံခန့်ခွဲ
// @name:mt                Chatgpt faċilment jimmaniġġja chats
// @name:ms                Chatgpt dengan mudah menguruskan sembang
// @name:mr                Chatgpt सहजपणे गप्पा व्यवस्थापित करा
// @name:mo                Chatgpt gestionează cu ușurință chaturile
// @name:mn                Chatgpt амархан чатыг хялбархан удирддаг
// @name:ml                ചാറ്റ്ഗേറ്റ് ചാറ്റുകൾ എളുപ്പത്തിൽ മാനേജുചെയ്യുക
// @name:mk                Chatgpt лесно управува со разговори
// @name:mh                ChatGPT Ej kōṃṃan bwe en pidodo aer kōnono .
// @name:mi                He ngawari te whakahaere i nga whakawhitinga
// @name:mg                Mora mitantana ny chatgpt mora
// @name:lv                Chatgpt viegli pārvaldīt tērzēšanu
// @name:lt                „ChatGpt“ lengvai valdo pokalbius
// @name:ln                Chatgpt e gérer na pete ba chats .
// @name:lo                ChatGPT ຄຸ້ມຄອງການສົນທະນາໄດ້ຢ່າງງ່າຍດາຍ
// @name:lg                ChatGpt enyangu okuddukanya emboozi .
// @name:lb                ChatGPT einfach managen Chats
// @name:la                Chatgpt facile Curo Chats
// @name:ky                Чатгптай
// @name:kv                ЧатГПТ Кокниӧн веськӧдлӧны чатъясӧн .
// @name:ku                Chatgpt bi hêsanî chat
// @name:kr                ChatGPT kəskelan zandewa cistǝgǝ
// @name:kn                ಚಾಟ್ಜಿಪಿಟಿ ಸುಲಭವಾಗಿ ಚಾಟ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ
// @name:km                Chatgpt គ្រប់គ្រងការជជែក
// @name:ko                Chatgpt는 채팅을 쉽게 관리합니다
// @name:kl                ChatGPT chats-inik ajornanngitsumik aqutsisinnaavutit
// @name:kk                Чатшпта чаттарды оңай басқаруда
// @name:kg                ChatGPT ke sadilaka masolo kukonda mpasi
// @name:ka                Chatgpt ადვილად მართავს ჩეთებს
// @name:jv                ChatGPT Gampang Ngatur Chats
// @name:iu                ChatGPT-ᑯᑦ ᐊᐅᓚᑦᑎᖏᓐᓇᐅᔭᖅᑐᑦ ᐅᖃᖃᑎᒌᒍᑎᓂᒃ
// @name:ja                ChatGptはチャットを簡単に管理します
// @name:it                Chatgpt gestisce facilmente le chat
// @name:ig                Nkata dị mfe jikwaa nkata
// @name:is                Chatgpt stjórna auðveldlega spjalli
// @name:id                Chatgpt dengan mudah mengelola obrolan
// @name:hy                Chatgpt- ը հեշտությամբ կառավարում է զրույցները
// @name:hu                A chatgpt könnyen kezelheti a csevegést
// @name:ht                Chatgpt fasil jere cha
// @name:hr                Chatgpt lako upravljati chatovima
// @name:hmn               Chatgpt yooj yim tswj chats
// @name:hi                CHATGPT आसानी से चैट का प्रबंधन करें
// @name:he                צ’אט
// @name:gv                ChatGPT Easily.
// @name:ha                CYGTP sauƙin sarrafawa
// @name:gu                ચેટગપ્ટ સરળતાથી ચેટ્સનું સંચાલન કરો
// @name:gn                CHATGPT Ojesareko pya’e umi ñe’ẽjoaju rehe .
// @name:gl                Chatgpt xestionar facilmente os chats
// @name:gd                Bidh Chatgpt furasta a ’comharrachadh chait
// @name:ga                Chatgpt comhrá a bhainistiú go héasca
// @name:gsw-berne         ChatGPT Easily manage chats
// @name:fy                Chatgpt maklik beheare petearen
// @name:fo                ChatGPT umsitur Lætt
// @name:fj                Vakarautaki ni Eusily ni lewa .
// @name:fi                ChatgPT hallitsee helposti keskusteluja
// @name:fr                Chatgpt Gérez facilement les chats
// @name:ff                ChatGPT Ko yaawi ina jogori waɗde yeewtereeji
// @name:fil               Ang chatgpt ay madaling pamahalaan ang mga chat
// @name:fa                Chatgpt به راحتی چت ها را مدیریت می کند
// @name:eu                Chatgpt erraz kudeatu txatak
// @name:et                Chatgpt hallake vestlusi hõlpsalt
// @name:eo                Chatgpt facile administras babiladojn
// @name:ee                Chatgpt kpɔa dzeɖoɖowo dzi bɔbɔe .
// @name:el                Το Chatgpt διαχειρίζεται εύκολα τις συνομιλίες
// @name:dz                ChatGPT འཇམ་ཏོང་ཏོ་སྦེ་ཁ་སླབ་ཚུ་འཛིན་སྐྱོང་འཐབ་ནི།
// @name:es                Chatgpt administrar fácilmente los chats
// @name:dv                ޗެޓްޖީޕީޓީ އިން ފަސޭހައިން ޗެޓް މެނޭޖް ކުރަނީ
// @name:en                ChatGPT Easily manage chats
// @name:da                Chatgpt Administrer let chats
// @name:de                ChatGPT verwalten einfach Chats
// @name:cy                Chatgpt yn rheoli sgyrsiau yn hawdd
// @name:cv                ЧатГПТ йĕркеллĕ чатсене йĕркелеме пулать
// @name:co                Chatgpt fabricà facilmente i chats
// @name:ch                Gaigue-ña si ChatGPT Gi i lina’la’
// @name:cs                Chatgpt Snadno spravuje chaty
// @name:ceb               Ang chatgpt dali nga magdumala sa mga chat
// @name:ce                ChatGPT Easily-н урхалла до чаташна
// @name:ca                Chatgpt gestiona fàcilment els xats
// @name:bs                Chaggpt Lako upravljati chatovima
// @name:br                ChatGPT Aes merañ ar c’hrogadoù
// @name:bo                ChatGPT ཁ་བརྡ་བདེ་བླག་ངང་འཛིན་སྐྱོང་བྱེད་པ།
// @name:bn                চ্যাটজিপ্ট সহজেই চ্যাট পরিচালনা করুন
// @name:bh                चैटजीपीटी आसानी से चैट के प्रबंधन करीं
// @name:bm                ChatGPT bɛ se ka barow ɲɛnabɔ nɔgɔya la .
// @name:bg                Chatgpt лесно управлява чатовете
// @name:be                Chatgpt лёгка кіраваць чатамі
// @name:ba                ChatGPT еңел идара итеү чат
// @name:av                ChatGPT Бигьаго нухмалъи гьабизе чат
// @name:ay                Chatgpt ukax jasakiw chats ukar apnaqañama .
// @name:az                ChatGept asanlıqla söhbətləri idarə edin
// @name:as                Chatgpt সহজে চ্যাট পৰিচালনা কৰে
// @name:ar                ChatGPT بسهولة إدارة الدردشات
// @name:ab                ЧатГПТ Имарианы ацәажәарақәа рнапхгара
// @name:af                Chatgpt bestuur maklik geselsies
// @name:ak                ChatGPT yɛ mmerɛw sɛ wobɛhwɛ nkɔmmɔbɔ so .
// @name:am                ውይይት በቀላሉ ቻትዎችን ያስተዳድራል
// @name:aa                ChatGPT sahlin walalih walal
// @name:zh-CN             ChatGPT 轻松管理聊天
// @description:ckb        گەڕان بەدوای چات، چاتی فلتەر، خێرا/وەجبەیی بسڕەوە چات.
// @description:zu         Ukucinga Chat, Chat Chat Chat, Fast / Batch Delete Chat.
// @description:yo         Wiwọle Wiwa, Iyipada àlẹmọ, Yara / Itọsọna Paare Paare Ret.
// @description:en-GB      Search chat, filter chat, fast/batch delete chat.
// @description:zh-HK      搜索聊天、過濾聊天、快速/批量刪除聊天。
// @description:zh-MO      搜索聊天、過濾聊天、快速/批量刪除聊天。
// @description:zh-MY      搜索聊天、过滤聊天、快速/批量删除聊天。
// @description:zh-SG      搜索聊天、过滤聊天、快速/批量删除聊天。
// @description:zh         搜索聊天、过滤聊天、快速/批量删除聊天。
// @name:es-419            Chatgpt administrar fácilmente los chats
// @description:es-419     Buscar chat, filtrar chat, fast/lotes eliminar chat.
// @description:xh         Incoko yokukhangela, incoko yecebo lokucoca, ngokukhawuleza / ibhetch cima incoko.
// @description:yi         זוכן טשאַט, פילטער שמועסן, שנעל / פּעקל ויסמעקן שמועסן.
// @description:fr-CA      Chat de recherche, chat filtre, chat de suppression rapide / lot.
// @description:wo         Seetlu chat, segg, chat de filtre, gaaw/batch chat.
// @description:zh-TW      搜索聊天、過濾聊天、快速/批量刪除聊天。
// @description:ve         U ṱoḓa nyambedzano, nyambedzano ya u sefa, nyambedzano ya u ṱavhanya/batch ya u phumula.
// @description:vi         Chat tìm kiếm, trò chuyện lọc, trò chuyện xóa nhanh/hàng loạt.
// @description:uz         Chatni qidirish, Filtr chat, tez / partiya chatni o’chirib tashlang.
// @description:ur         سرچ چیٹ ، فلٹر چیٹ ، فاسٹ/بیچ کو حذف کریں چیٹ۔
// @description:ug         ئىزدەش پاراڭ, سۈزگۈچ پاراڭ, تېز / تۈركۈملەش پاراڭ.
// @description:ty         A imi i te chat, te chat, te chat vitiviti/batch.
// @description:tw         Hwehwɛ nkɔmmɔbɔ, filter nkɔmmɔbɔ, fast/batch Popa nkɔmmɔbɔ.
// @description:uk         Шукайте чат, чат фільтр, швидкий/пакетний вилучення чату.
// @description:tt         Чат, фильтр чат, тиз / партия чатны бетерегез.
// @description:ts         Ku lavisisa chat, filter chat, ku hatlisa/ku batch Susa chat.
// @description:tr         Sohbet, filtre sohbeti, hızlı/toplu Sil sohbet arayın.
// @description:to         Fekumi ki he talanoa, talanoa filter, talanoa delete vave/batch.
// @description:tn         Batla motlotlo, sefa puisano, ka potlako / batch hlakola puisano.
// @description:tl         Paghahanap chat, filter chat, mabilis/batch tanggalin ang chat.
// @description:ti         ዕላል፡ ፍልተር ቻት፡ ቅልጡፍ/ባች ምድምሳስ ቻት ድለ።
// @description:tk         Söhbet söhbetdeşligi, süzgüç söhbet, çalt / partiýa söhbetdeşligi pozuň.
// @description:tg         Чат, филтри филтр, чат зуд / Bitche нест кунед.
// @description:th         ค้นหาแชทตัวกรองแชท Fast/Batch ลบแชท
// @description:te         శోధన చాట్, ఫిల్టర్ చాట్, ఫాస్ట్/బ్యాచ్ తొలగించు చాట్.
// @description:sw         Tafuta gumzo, gumzo la kichujio, mazungumzo ya haraka/batch.
// @description:su         Milarian chat, nyaring panipuan, gancang / tumpak cup.
// @description:ta         தேடு அரட்டை, வடிகட்டி அரட்டை, வேகமான/தொகுதி நீக்கு அரட்டை.
// @description:sv         Sökchatt, filterchatt, snabb/batch radera chatt.
// @description:st         Batla Chat, Chatter Chat, Faces / Batch Delet Chat.
// @description:ss         Sesha ingcoco, chat yekuhlunga, kushesha/ batch desice chat.
// @description:sq         Biseda në kërkim, biseda filtri, Fast/Batch Fshi bisedën.
// @description:so         Raadinta Wadahadalka, Xirfadlaha Fund, Soonka / Dufcaddii tirtir sheekada.
// @description:sn         Tsvaga Chat, Firita Chat, Fast / Batch Delete Chat.
// @description:sm         Saili talatalanoaga, faʻamama talanoaga, vave / botch tape le talatalanoaga.
// @description:sr         Тражи Цхат, Филтер Цхат, Фаст / Батцх Делете Цхат.
// @description:sl         Poiščite klepet, filtrirajte klepet, hitri/serija brisanje klepeta.
// @description:sk         Vyhľadajte chat, chat filtra, rýchly/dávkový odstránený chat.
// @description:si         සෙවුම් චැට්, පෙරහන් චැට්, වේගවත් / කණ්ඩායම මකන්න කතාබස්.
// @description:sh         Тражи Цхат, Филтер Цхат, Фаст / Батцх Делете Цхат.
// @description:sg         Recherche chat, filtre chat, fast/batch chat.
// @description:se         Ohcat chat, filterchat, fast/batch slette chat.
// @description:sd         ڳولا چيٽ، فلٽر چيٽ، فاسٽ / بيچ خارج ڪريو چيٽ.
// @description:sa         सर्च गपशप, फ़िल्टर चैट, फास्ट/बैच विलोप करें गपशप।
// @description:rw         Shakisha Ikiganiro, Guyunguruzi Ikiganiro, Byihuta / Bitch Gusiba Ikiganiro.
// @description:ro         Chat de căutare, chat de filtrare, chat de ștergere rapidă/lot.
// @description:rn         Rondera ibiganiro, ucungure, wihute/ushireho ubutumwa.
// @description:qu         Buscar chat, filtro chat, rápido/lote borrar chat.
// @description:ru         Поиск чата, фильтр чат, быстрый/партия удалить чат.
// @description:ps         د چیټ چیټ، فلټر چیټ، ګړندي / بیچ حذف کول.
// @description:pl         Wyszukaj czat, czat filtrujący, szybki/partii usuń czat.
// @description:pa         ਖੋਜ ਚੈਟ, ਫਿਲਟਰ ਚੈਟ, ਤੇਜ਼ / ਬੈਚ ਮਿਟਾਓ ਗੱਲਬਾਤ.
// @description:os         Агурæн чат, фильтр чат, тагъд/партион удалить чат.
// @description:pt-BR      Pesquise bate -papo, bate -papo de filtro, bate -papo de exclusão rápida/lote.
// @description:pt-PT      Pesquise bate -papo, bate -papo de filtro, bate -papo de exclusão rápida/lote.
// @description:pt         Pesquise bate -papo, bate -papo de filtro, bate -papo de exclusão rápida/lote.
// @description:or         ଚାଟ୍, ଫିଲ୍ଟର ଚାଟ୍, ଫାଷ୍ଟ / ବ୍ୟାଚ୍ ଡିଲିଟ୍ ଚାଟ୍ ଡିଲିଟ୍ କରନ୍ତୁ |
// @description:oc         Cerca chat, filtre chat, chat de supression rapida/lots.
// @description:om         Chaat barbaadi, filter chat, fast/batch delete chat.
// @description:ny         Kusaka macheza, zosefera, mwachangu / batch chochotsa macheza.
// @description:nr         I-in ts, iso, i-orss, i-or.
// @description:nb         Søk chat, filter chat, rask/batch slett chat.
// @description:nl         Zoek chat, filterchat, snel/batch verwijderen chat.
// @description:ne         खोजी च्याट, फिल्टर च्याट, द्रुत / ब्याच च्याट लगाउनुहोस्।
// @description:my         Search Chat, Filter Chat, Filter Chat, Fast / Batch Delete Chat ။
// @description:mt         Fittex chat, chat tal-filtru, fast / lott tħassar chat.
// @description:ms         CHAT Chat, sembang penapis, cepat/batch padam sembang.
// @description:mr         चॅट, फिल्टर चॅट, वेगवान/बॅच चॅट हटवा.
// @description:mo         Chat de căutare, chat de filtrare, chat de ștergere rapidă/lot.
// @description:mn         Чат, шүүлтүүр чат, хурдан / багц устгах чатыг устгах.
// @description:ml         തിരയൽ, ചാറ്റ് ഫിൽട്ടർ ചെയ്യുക, വേഗത്തിൽ / ബാച്ച് ഇല്ലാതാക്കുക ചാറ്റ് ചെയ്യുക.
// @description:mk         Разговор за пребарување, разговор за филтрирање, брз/разделување на серија.
// @description:mh         Chat in pukōt, kōnono in filter, kōnono eo em̧ōkaj an m̧ōkaj.
// @description:mi         Rapua te korero, tātari, tere / tere te korero korero korero.
// @description:mg         Fikarohana Chat, Filter Chat, Fast / Batch Delete Chat.
// @description:lv         Meklējiet tērzēšanu, filtru tērzēšanu, ātru/partijas dzēšanas tērzēšanu.
// @description:lt         Paieškos pokalbis, filtrų pokalbis, greitas/partijos ištrynimo pokalbis.
// @description:ln         Boluka chat, filtrer chat, Fast/batch effacer chat.
// @description:lo         ຄົ້ນຫາສົນທະນາ, ການສົນທະນາການກັ່ນຕອງ, Delete Fast / Batch Delete Chat.
// @description:lg         Noonya emboozi, sengejja emboozi, okusangula okusazaamu mu bwangu/okusangula.
// @description:lb         Sich Chat, Filter Chat, Fast / Batch läschen Chat.
// @description:la         Search Chat, filter Chat, Fast / Batch Delete Chat.
// @description:ky         Чат издөө, чыпкалоочу чат, тез / партиялык чат.
// @description:kv         Корсьны чат, фильтр чат, пост/партия удалить чат.
// @description:ku         Chat lêgerîn, chat filter, Fast / Batch Chat.
// @description:kr         Zande kulashiye, zande filterbe, duwaro/batch delete.
// @description:kn         ಚಾಟ್ ಹುಡುಕಿ, ಫಿಲ್ಟರ್ ಚಾಟ್, ಫಾಸ್ಟ್/ಬ್ಯಾಚ್ ಅಳಿಸು ಚಾಟ್.
// @description:km         ស្វែងរកការស្វែងរកតម្រងជជែកកំសាន្តរហ័ស / បាច់ជជែកជជែកជជែកកំសាន្ត។
// @description:ko         검색 채팅, 필터 채팅, 빠른/배치 삭제 채팅.
// @description:kl         Ujaasineq, filter-chat, sukkasuumik/batch-imik delete-mik chat-imik ujarlerneq.
// @description:kk         Чат, чат, Сүзгі, жылдам / буманы іздеу Чатты жою.
// @description:kg         Sosa masolo, chat ya filtre, chat ya nswalu/ya batch.
// @description:ka         მოძებნეთ ჩეთი, ფილტრის ჩეთი, სწრაფი/სურათების წაშლა ჩეთი.
// @description:jv         Nggoleki Goleki, ngobrol Filter, cepet / batch mbusak.
// @description:iu         ᕿᓂᕐᓗᑎᑦ ᐅᖃᖃᑎᒌᒍᑎᒥᒃ, ᓴᓗᒻᒪᖅᓴᐃᔾᔪᑎᒥᒃ ᐅᖃᖃᑎᒌᒍᑎᒥᒃ, ᓱᒃᑲᔪᒥᒃ/ᑲᑎᙵᔪᒥᒃ ᐲᖅᓯᓗᑎᑦ ᐅᖃᖃᑎᒌᒍᑎᒥᒃ.
// @description:ja         チャット、フィルターチャット、高速/バッチ削除チャットを検索します。
// @description:it         Cerca chat, chat filtrante, elimina veloce/batch.
// @description:ig         Nchọta nkata, Nyocha Nkata, ngwa ngwa / bch Hichapụ nkata.
// @description:is         Leitaðu að spjalli, síu spjalli, hratt/lotu Eyða spjalli.
// @description:id         Cari Obrolan, Obrolan Filter, Obrolan Hapus Batch/Batch.
// @description:hy         Որոնում Զրուցարան, Զրուցարան, Fast / Batch Delete նջել Զրուցարան.
// @description:hu         Keressen csevegést, szűrő csevegést, gyors/tétel törlés csevegést.
// @description:ht         Search chat, filtre chat, vit/pakèt efase chat.
// @description:hr         Pretražite chat, filter chat, brz/batch brisanje chata.
// @description:hmn        Tshawb Tham, Lim Sib Tham, ceev / Batch Delete kev sib tham.
// @description:hi         खोज चैट, फ़िल्टर चैट, फास्ट/बैच डिलीट चैट।
// @description:he         חיפוש בצ’אט, סנן צ’אט, מהיר/אצווה מחק צ’אט.
// @description:gv         Ct chat, filter chat, s’fast/batch chat.
// @description:ha         Tattaunawa, tace taɗi, Fast / Batch Share Chat.
// @description:gu         ચેટ, ફિલ્ટર ચેટ, ફાસ્ટ/બેચ કા delete ી નાખો ચેટ.
// @description:gn         Eheka chat, filtro chat, pya’e/batch Embogue chat.
// @description:gl         Buscar chat, chat de filtro, chat de eliminación rápida/lote.
// @description:gd         Rannsaich cat, bruidheach cabadaich, luath / baidse Cuir às do chat.
// @description:ga         Cuardaigh comhrá, comhrá scagaire, tapa/baisc scrios comhrá.
// @description:gsw-berne  Search chat, filter chat, fast/batch delete chat.
// @description:fy         Sykje Chat, Filter Chat, Fast / Batch / Batch wiskje Chat.
// @description:fo         Leita kjatt, filtur prát, fast/bólkur strika kjak.
// @description:fj         Vakasaqarai veisau, totolo, totolo/bati deleti.
// @description:fi         Hakukeskustelu, suodatin chat, nopea/eräpoisto chat.
// @description:fr         Chat de recherche, chat filtre, chat de suppression rapide / lot.
// @description:ff         Yiylo yeewtere, yeewtere filtirde, yeewtere momtunde yaawnde/batch.
// @description:fil        Paghahanap chat, filter chat, mabilis/batch tanggalin ang chat.
// @description:fa         چت را جستجو کنید ، گپ فیلتر ، چت سریع/دسته ای را حذف کنید.
// @description:eu         Bilatu txat, iragazi txat, azkarra / sorta berriketan.
// @description:et         Otsige vestlust, filtreerige vestlus, kiire/partii kustuta vestlus.
// @description:eo         Serĉu babilejon, filtran babilejon, Rapida/Batch Forigi Babilejon.
// @description:ee         Search chat, filter chat, fast/batch delete chat.
// @description:el         Αναζήτηση συνομιλίας, συνομιλία φίλτρου, συνομιλία γρήγορης/παρτίδας.
// @description:dz         འཚོལ་ཞིབ་ཁ་སླབ་ ཚགས་མ་ཁ་སླབ་ མགྱོགས་དྲགས་/བེཆ་ བཏོན་གཏང་བའི་ཁ་སླབ་།
// @description:es         Buscar chat, filtrar chat, fast/lotes eliminar chat.
// @description:dv         ޗެޓް، ފިލްޓަރ ޗެޓް، ފަސްޓް/ބެޗް ޑިލީޓް ޗެޓް.
// @description:en         Search chat, filter chat, fast/batch delete chat.
// @description:da         Søgchat, filterchat, hurtig/batch slet chat.
// @description:de         Suchen Sie Chat, Filter -Chat, Schnell/Stapel -Chat löschen.
// @description:cy         Chwilio sgwrs, sgwrs hidlo, sgwrsio cyflym/swp Dileu sgwrs.
// @description:cv         Шырав чат, фильтр чат, хăвăрт/пайчĕн делете чат.
// @description:co         A ricerca di u chat, filtru chat, veloce / batch eliminate u chat.
// @description:ch         Manma’å’ñao i chat, ya filter, båba/batch.
// @description:cs         Hledejte chat, chat filtru, rychlý/dávkový chat.
// @description:ceb        Pagpangita Chat, Filter Chat, Fast / Batch Delete Chat.
// @description:ce         Лехамаш чат, фильтр чат, сиха/батч делете чат.
// @description:ca         Cerqueu xat, xat de filtres, xat de suprimir ràpid/lot.
// @description:bs         Pretražite chat, filter chat, brza / serija Delete Chat.
// @description:br         Klask flapañ, flapañ silañ, flapañ buan/batch dilemel.
// @description:bo         འཚོལ་ཞིབ་ཁ་བརྡ་དང་། ཚགས་རླུང་ཁ་བརྡ། མགྱོགས་པོ། བསུབ་པའི་ཁ་བརྡ།
// @description:bn         চ্যাট অনুসন্ধান করুন, ফিল্টার চ্যাট, দ্রুত/ব্যাচ মুছুন চ্যাট।
// @description:bh         खोज चैट, फिल्टर चैट, फास्ट/बैच हटाईं चैट।
// @description:bm         Search chat, filter chat, teliya/batch delete chat.
// @description:bg         Чат за търсене, чат за филтриране, бърз/партиден изтриване чат.
// @description:be         Шукайце чат, фільтр -чат, хуткі/партыйны выдаленне чата.
// @description:ba         Эҙләү чат, фильтр чат, тиҙ/партия юйыу чат.
// @description:av         Поиск чат, фильтр чат, быстро/парти делеат чат.
// @description:ay         Chat, Filtrar Chat, Fast/Batch Chat chat.
// @description:az         Axtarış sohbeti, filtr chat, sürətli / toplu silmək söhbət.
// @description:as         Search Chat, ফিল্টাৰ চেট, দ্ৰুত/বেচ মচি পেলাওক চেট।
// @description:ar         بحث الدردشة ، دردشة التصفية ، الدردشة السريعة/الدُفعة.
// @description:ab         Аԥшааратә чат, афильтр аицәажәара, аццакыра/абатч аныхратә чат.
// @description:af         Soek chat, filter chat, vinnige/groep delete chat.
// @description:ak         Hwehwɛ nkɔmmɔbɔ, filter nkɔmmɔbɔ, fast/batch Popa nkɔmmɔbɔ.
// @description:am         ፍለጋ ውይይት, ማጣሪያ ውይይት, ፈጣን / የቡድን ሰርዝ
// @description:aa         walal, maydaddaarat walala, sissik/batch baysiyyih walala.
// @description            Search for chats, filter them, quickly/bulk delete them.
// @description:zh-CN      搜索聊天、过滤聊天、快速/批量删除聊天。
// @author                 mysy00
// @namespace              https://github.com/mysy00/userscripts
// @supportURL             https://github.com/mysy00/userscripts/issues
// @homepageURL            https://github.com/mysy00/userscripts
// @homepage               https://github.com/mysy00/userscripts
// @license                MIT
// @match                  https://chatgpt.com/*
// @icon                   https://raw.githubusercontent.com/ChinaGodMan/UserScriptsHistory/main/scriptsIcon/chatgpt-plus.png
// @compatible             chrome
// @compatible             firefox
// @compatible             edge
// @compatible             opera
// @compatible             safari
// @compatible             kiwi
// @compatible             qq
// @compatible             via
// @compatible             brave
// @version                2025.6.3.1
// @created                2025-06-03 11:26:11
// ==/UserScript==

/**
 * File: chatgpt-easy-management.user.js
 * Project: UserScripts
 * File Created: 2025/06/03,Tuesday 11:26:11
 * Author: mysy00
 * -----
 * Last Modified: 2025/06/03,Tuesday 11:34:19
 * Modified By: 人民的勤务员@ChinaGodMan ([email protected])
 * -----
 * License: MIT License
 * Copyright © 2024 - 2025 ChinaGodMan,Inc
 */

(function () {
    'use strict'

    const API = 'https://chatgpt.com/backend-api'
    const MAX_MSG_LEN = 100
    const RETRIES = 3
    const RETRY_DELAY = 300
    const PAGE_SIZE = 50

    const wait = ms => new Promise(r => setTimeout(r, ms))
    const fmt = ts => {
        const d = new Date(ts * 1000)
        const date = d.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })
        const time = d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })
        return `${date} ${time}`
    }
    const trimStr = s =>
        typeof s === 'string' && s.length > MAX_MSG_LEN ? s.slice(0, MAX_MSG_LEN) + '…' : s
    const extractText = part => {
        // If it’s a plain string, return it
        if (typeof part === 'string') {
            return part
        }
        // If it’s an object with an explicit type
        if (part && typeof part === 'object') {
            // ChatGPT image attachments often come as { type: 'image_url', url: '…' }
            if (part.content_type === 'image_asset_pointer') {
                return '🖼️'
            }
            // Some variants may include a url/src field even without type
            if (part.url || part.src) {
                return '[image]'
            }
        }
        // Otherwise we don’t know how to render it
        return '[unknown]'
    }

    async function getToken() {
        const res = await fetch('https://chatgpt.com/api/auth/session', { credentials: 'include' })
        const j = await res.json()
        if (!j.accessToken) throw new Error('No auth token')
        return j.accessToken
    }

    async function fetchPage(offset = 0, limit = PAGE_SIZE) {
        const t = await getToken()
        const res = await fetch(`${API}/conversations?offset=${offset}&limit=${limit}`, {
            headers: { Authorization: `Bearer ${t}` }
        })
        if (!res.ok) throw new Error(`Summaries fetch failed ${res.status}`)
        return res.json()
    }

    async function fetchDetailsWithRetry(id) {
        for (let i = 0; i < RETRIES; i++) {
            try {
                const t = await getToken()
                const res = await fetch(`${API}/conversation/${id}`, {
                    headers: { Authorization: `Bearer ${t}` }
                })
                if (!res.ok) throw new Error()
                return await res.json()
            } catch {
                await wait(RETRY_DELAY)
            }
        }
        throw new Error(`Failed to load details for ${id}`)
    }

    async function deleteChat(id) {
        const t = await getToken()
        const res = await fetch(`${API}/conversation/${id}`, {
            method: 'PATCH',
            headers: {
                Authorization: `Bearer ${t}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ is_visible: false })
        })
        if (!res.ok) throw new Error(`Delete failed ${res.status}`)
        await wait(200)
    }

    function injectStyles() {
        if (document.getElementById('bd-styles')) return
        const st = document.createElement('style')
        st.id = 'bd-styles'
        st.textContent = `
        /* Overlay & modal shell */
        #bd-overlay { background: rgba(0,0,0,0.5) !important; }
        #bd-overlay.hidden { display: none !important; }
        #bd-modal {
          background: var(--sidebar-surface-primary);
          color: var(--token-text-primary);
          border-radius: 16px;
          box-shadow: 0 20px 60px rgba(0,0,0,0.45);
          display: flex; flex-direction: column;
          max-width: 800px; width: 90%; max-height: 85vh; overflow: hidden;
          transform: translateY(20px); opacity: 0;
          animation: fadeInUp 0.3s ease-out forwards;
          font-family: inherit;
        }
        @keyframes fadeInUp { to { transform: translateY(0); opacity: 1; } }
        /* Header */
        #bd-modal > .header {
          background: var(--sidebar-surface-tertiary);
          padding: 16px 24px;
          display: flex; align-items: center;
          border-bottom: 1px solid var(--border-light);
          gap: 12px;
        }
        #bd-modal .header h2 { margin: 0; flex: 1; font-size: 18px; }
        #bd-modal .header button {
          background: var(--sidebar-surface-secondary);
          color: var(--token-text-primary);
          border: none; border-radius: 6px;
          font-size: 14px; font-weight: 500;
          padding: 6px 14px; cursor: pointer;
        }
        #bd-modal .header button:hover { background: var(--sidebar-surface-hover); }
        #bd-modal .header input[type="number"] {
          width: 60px; padding: 6px 8px; margin-left: 8px;
          border: 1px solid var(--border-light);
          border-radius: 6px;
          background: var(--sidebar-surface-secondary);
          color: var(--token-text-primary);
        }
        /* Status */
        #bd-status {
          padding: 8px 24px; font-size: 14px; color: var(--token-text-secondary);
        }
        /* Chat rows */
        #bd-modal .chat-row {
          padding: 16px 20px; border-bottom: 1px solid var(--border-light);
          display: flex; flex-direction: column; gap: 6px;
        }
        #bd-modal .chat-row:hover { background: var(--menu-item-active); }
        #bd-modal .chat-row.selected { background: var(--interactive-bg-secondary-press) !important; }
        .chat-row .top { display: flex; align-items: center; }
        .chat-row .title { margin-left: 8px; font-weight: 600; font-size: 15px; }
        .chat-row .meta  { font-size: 13px; }
        .chat-row .msg   { font-size: 14px; line-height: 1.4; word-break: break-word; }
        /* Footer */
        #bd-modal > .footer {
          background: var(--sidebar-surface-tertiary);
          padding: 16px 24px;
          display: flex; align-items: center;
          border-top: 1px solid var(--border-light);
          justify-content: flex-end; gap: 12px;
        }
        #bd-modal .footer button {
          background: var(--sidebar-surface-secondary);
          color: var(--token-text-primary);
          border: none; border-radius: 6px;
          font-size: 14px; font-weight: 500;
          padding: 6px 14px; cursor: pointer;
        }
        #bd-modal .footer button:first-child {
          background: var(--sidebar-surface-tertiary);
          border: 1px solid var(--border-light);
        }
        #bd-modal .footer button:last-child {
          background: var(--danger-action);
          color: var(--button-text);
        }
        #bd-modal .footer button:hover { background: var(--sidebar-surface-hover); }
      `
        document.head.appendChild(st)
    }

    function renderChatCard(convo, updateCount) {
        const row = document.createElement('div')
        row.className = 'chat-row'
        row.dataset.id = convo.id

        const top = document.createElement('div'); top.className = 'top'
        const cb = document.createElement('input'); cb.type = 'checkbox'; cb.dataset.id = convo.id
        const tit = document.createElement('div'); tit.className = 'title'; tit.textContent = convo.title || '(no title)'
        top.append(cb, tit)
        row.append(top)

        const meta = document.createElement('div'); meta.className = 'meta'; row.append(meta)
        const m1 = document.createElement('div'); m1.className = 'msg'; row.append(m1)
        const m2 = document.createElement('div'); m2.className = 'msg'; row.append(m2)

        function updateSelection() {
            row.classList.toggle('selected', cb.checked)
            updateCount()
        }

        row.addEventListener('click', e => {
            if (e.target.tagName !== 'INPUT') cb.checked = !cb.checked
            updateSelection()
        })
        cb.addEventListener('change', e => { updateSelection(); e.stopPropagation() })

        row.update = ({ create_time, update_time, first, last }) => {
            row.dataset.updateTs = update_time
            meta.innerHTML = `<strong>Created:</strong> ${fmt(create_time)} — <strong>Updated:</strong> ${fmt(update_time)}`
            m1.innerHTML = `<strong>First:</strong> ${first}`
            m2.innerHTML = `<strong>Last:</strong> ${last}`
        }

        return row
    }

    function openModal() {
        // If there's already an overlay, remove it entirely so state resets
        const existing = document.getElementById('bd-overlay')
        if (existing) existing.remove()

        injectStyles()

        const overlay = document.createElement('div')
        overlay.id = 'bd-overlay'
        Object.assign(overlay.style, { position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9999 })

        function hideAndRemove() { overlay.remove() }

        overlay.addEventListener('click', e => { if (e.target === overlay) hideAndRemove() })
        window.addEventListener('keydown', function esc(e) { if (e.key === 'Escape') { hideAndRemove(); window.removeEventListener('keydown', esc) } })

        const modal = document.createElement('div'); modal.id = 'bd-modal'
        const statusEl = document.createElement('div'); statusEl.id = 'bd-status'
        const list = document.createElement('div'); Object.assign(list.style, { flex: '1 1 auto', overflowY: 'auto' })

        // Header
        const header = document.createElement('div'); header.className = 'header'
        const h2 = document.createElement('h2'); h2.textContent = 'Bulk Delete Chats'
        const sortBtn = document.createElement('button'); sortBtn.textContent = 'Sort by Updated'
        const ageInput = document.createElement('input'); ageInput.type = 'number'; ageInput.min = '0'; ageInput.placeholder = 'Days'
        const listOldBtn = document.createElement('button'); listOldBtn.textContent = 'List older'
        const refreshBtn = document.createElement('button'); refreshBtn.textContent = 'Reload'
        const closeBtn = document.createElement('button'); closeBtn.textContent = '✕'
        header.append(h2, sortBtn, ageInput, listOldBtn, refreshBtn, closeBtn)

        // Footer
        const footer = document.createElement('div'); footer.className = 'footer'
        const cancelBtn = document.createElement('button'); cancelBtn.textContent = 'Cancel'
        const delBtn = document.createElement('button'); delBtn.textContent = 'Delete Selected'
        footer.append(cancelBtn, delBtn)

        modal.append(header, statusEl, list, footer)
        overlay.append(modal)
        document.body.append(overlay)

        let totalChats = 0, offset = 0, loadingMore = false
        const rows = []

        function updateCount() {
            const shown = rows.length
            const sel = list.querySelectorAll('input:checked').length
            statusEl.textContent = `Showing ${shown} of ${totalChats} chats — ${sel} selected`
        }

        const obs = new IntersectionObserver((ents) => {
            ents.forEach(ent => {
                if (!ent.isIntersecting) return
                obs.unobserve(ent.target)
                fetchDetailsWithRetry(ent.target.dataset.id)
                    .then(dt => {
                        const userMsgs = Object.values(dt.mapping || {})
                            .filter(n => n.message?.author?.role === 'user')
                            .map(n => extractText(n.message?.content?.parts?.[0]))
                        let first = trimStr(userMsgs[0] || '—')
                        let last = trimStr(userMsgs.at(-1) || '—')
                        if (first === last) {
                            const asst = Object.values(dt.mapping || {})
                                .filter(n => n.message?.author?.role === 'assistant')
                            if (asst.length) {
                                last = 'Chat: ' + trimStr(extractText(asst.at(-1).message.content.parts?.[0] || ''))
                            }
                        }
                        ent.target.update({ create_time: dt.create_time, update_time: dt.update_time, first, last })
                    })
                    .catch(() => ent.target.update({ create_time: 0, update_time: 0, first: '✖️', last: '✖️' }))
            })
        }, { root: list, threshold: 0.1 })

        async function loadChats() {
            list.innerHTML = ''
            rows.length = 0
            offset = 0
            const page = await fetchPage(0, PAGE_SIZE)
            totalChats = page.total ?? page.total_count ?? page.pagination?.total_count ?? page.pagination?.total ?? page.items.length
            page.items.forEach(c => {
                const row = renderChatCard(c, updateCount)
                list.append(row)
                rows.push(row)
            })
            offset = page.items.length
            updateCount()
            rows.forEach(r => obs.observe(r))
        }

        // initial load
        loadChats().catch(() => statusEl.textContent = 'Failed to load chats.')

        // Refresh handler
        refreshBtn.addEventListener('click', async () => {
            statusEl.textContent = 'Reloading…'
            obs.disconnect()
            try {
                await loadChats()
                statusEl.textContent = 'Reloaded.'
            } catch (err) {
                statusEl.textContent = 'Reload failed.'
                console.error(err)
            }
        })

        // Infinite scroll
        list.addEventListener('scroll', async () => {
            if (loadingMore) return
            if (offset < totalChats && list.scrollTop + list.clientHeight >= list.scrollHeight - 50) {
                loadingMore = true
                const page = await fetchPage(offset, PAGE_SIZE)
                page.items.forEach(c => {
                    const row = renderChatCard(c, updateCount)
                    list.append(row)
                    rows.push(row)
                    obs.observe(row)
                })
                offset += page.items.length
                updateCount()
                loadingMore = false
            }
        })

        // Sort
        sortBtn.addEventListener('click', () => {
            rows
                .sort((a, b) => Number(b.dataset.updateTs) - Number(a.dataset.updateTs))
                .forEach(r => list.append(r))
            updateCount()
        })

        // Filter older
        listOldBtn.addEventListener('click', () => {
            const days = parseInt(ageInput.value, 10)
            if (isNaN(days) || days < 0) {
                statusEl.textContent = 'Enter a valid number of days'
                return
            }
            const threshold = Math.floor(Date.now() / 1000) - days * 86400
            statusEl.textContent = `Filtering chats older than ${days} days…`
            obs.disconnect()
            const filtered = rows.filter(r => Number(r.dataset.updateTs) < threshold)
            list.innerHTML = ''
            filtered.forEach(r => { r.querySelector('input').checked = true; r.classList.add('selected'); list.append(r); obs.observe(r) })
            updateCount()
        })

        // Cancel & close
        cancelBtn.addEventListener('click', hideAndRemove)
        closeBtn.addEventListener('click', hideAndRemove)

        // Delete flow
        delBtn.addEventListener('click', () => {
            const selected = [...list.querySelectorAll('.chat-row.selected')]
            if (!selected.length) {
                statusEl.textContent = 'No chats selected.'
                return
            }

            const confirmPane = document.createElement('div')
            confirmPane.id = 'bd-confirm-pane'
            confirmPane.style = 'flex:1 1 auto;overflow-y:auto;padding:16px'

            const info = document.createElement('div')
            info.textContent = `Confirm deletion of ${selected.length} chat(s). Uncheck any you’d like to keep:`
            info.style = 'margin-bottom:12px;font-weight:500'
            confirmPane.appendChild(info)

            selected.forEach((row, idx) => {
                const id = row.dataset.id
                const title = row.querySelector('.title').textContent
                const label = document.createElement('label')
                label.style = 'display:flex;align-items:center;margin-bottom:8px'
                const cb = document.createElement('input')
                cb.type = 'checkbox'; cb.checked = true; cb.dataset.id = id; cb.style = 'margin-right:8px'
                label.append(cb, document.createTextNode(`${idx + 1}. ${title}`))
                confirmPane.appendChild(label)
            })

            footer.innerHTML = ''
            const backBtn = document.createElement('button'); backBtn.textContent = 'Back'
            const confirmBtn = document.createElement('button')
            confirmBtn.textContent = 'Confirm Delete'
            confirmBtn.style = 'background:var(--danger-action);color:var(--button-text)'
            footer.append(backBtn, confirmBtn)

            list.replaceWith(confirmPane)

            backBtn.addEventListener('click', () => {
                confirmPane.replaceWith(list)
                footer.innerHTML = ''
                footer.append(cancelBtn, delBtn)
                updateCount()
            })

            confirmBtn.addEventListener('click', async () => {
                const toDelete = [...confirmPane.querySelectorAll('input:checked')]
                if (!toDelete.length) {
                    statusEl.textContent = 'Nothing to delete.'
                    return
                }
                let done = 0, failed = 0
                for (const cb of toDelete) {
                    done++
                    statusEl.textContent = `Deleting (${done}/${toDelete.length})…`
                    try { await deleteChat(cb.dataset.id) } catch { failed++ }
                }
                statusEl.textContent = `Deleted ${toDelete.length - failed}, ${failed} failed.`
                // close & remove after a short pause
                setTimeout(hideAndRemove, 1000)
            })
        })
    }

    // Inject main icon & quick-delete buttons
    function injectIcon() {
        const target = document.querySelector('#sidebar-header')
        if (!target || target.querySelector('[data-bulk-delete]')) return

        const link = document.createElement('a')
        link.className = document.querySelectorAll('#sidebar-header > a')[0].className
        link.dataset.bulkDelete = 'true'; link.href = '#'
        link.setAttribute('aria-label', 'Bulk Delete Chats')
        link.setAttribute('role', 'button')
        link.innerHTML = `
        <svg width="24" height="24" fill="currentColor">
          <path d="M9 3v1H4v2h16V4h-5V3H9zm-1 5v12h2V8H8zm4 0v12h2V8h-2z"/>
        </svg>`
        link.addEventListener('click', e => { e.preventDefault(); openModal() })
        target.append(link)
    }

    function injectQuickDeleteButtons() {
        document.querySelectorAll('a[data-discover][href^="/c/"]').forEach(link => {
            if (link.querySelector('.quick-delete-btn')) return
            const convoId = link.getAttribute('href').split('/').pop()
            if (!convoId) return
            const btn = document.createElement('button')
            btn.className = 'quick-delete-btn'
            btn.setAttribute('aria-label', 'Delete conversation')
            btn.style.cssText = 'margin-left:8px;background:transparent;border:none;cursor:pointer;color:var(--token-text-secondary);'
            btn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 3v1H4v2h16V4h-5V3H9zm-1 5v12h2V8H8zm4 0v12h2V8h-2z" fill="currentColor"/></svg>`
            btn.addEventListener('click', async e => {
                e.preventDefault(); e.stopPropagation()
                try { await deleteChat(convoId); link.remove() } catch (err) { console.error('Quick delete failed', err) }
            })
            const trailing = link.querySelector('.text-token-text-tertiary');
            (trailing || link).appendChild(btn)
        })
    }

    const observer = new MutationObserver(() => {
        injectIcon()
        injectQuickDeleteButtons()
    })
    observer.observe(document.body, { childList: true, subtree: true })

    window.addEventListener('load', () => {
        injectIcon()
        injectQuickDeleteButtons()
    })
})()