Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++

Dieses Skript verbessert einige Websites. 🔥Twitter(X): Fügt Zeitformatanzeige, HD-Bildanzeige, Bild- und Video-Downloads usw. hinzu. 🔥Youtube: Fügt Video-Downloads, Anzeigenentfernung usw. hinzu. 🔥Tiktok: Bietet HD-Video-Downloads ohne Wasserzeichen usw. Weitere Funktionen finden Sie in der Beschreibung~

// ==UserScript==
// @name       Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ar    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:bg    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:cs    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:da    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:de    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:el    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:en    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:eo    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:es    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:fi    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:fr    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:fr-CA Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:he    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:hr    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:hu    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:id    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:it    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ja    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ka    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ko    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:nb    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:nl    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:pl    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:pt-BR Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ro    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ru    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:sk    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:sr    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:sv    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:th    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:tr    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:uk    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:ug    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @name:vi    Twitter(X)ᴾˡᵘˢ+++ ; Youtubeᴾˡᵘˢ+++
// @description       This script will provide enhancements to some websites. 🔥Twitter(X): Add time formatting display, HD picture display, picture and video downloading, etc. 🔥Youtube: Add video downloading, ad removal, etc. 🔥Tiktok: Provide HD watermark-free video downloading, etc. For more features, please check the description~
// @description:ar    سيوفر هذا البرنامج النصي تحسينات لبعض المواقع الإلكترونية. 🔥Twitter(X): إضافة عرض تنسيق الوقت، وعرض الصور عالية الدقة، وتنزيل الصور والفيديو، وما إلى ذلك. 🔥Youtube: إضافة تنزيل الفيديو، وإزالة الإعلانات، وما إلى ذلك. 🔥Tiktok: توفير تنزيل فيديو عالي الدقة بدون علامة مائية، وما إلى ذلك. لمزيد من الميزات، يرجى التحقق من الوصف~
// @description:bg    Този скрипт ще предостави подобрения на някои уебсайтове. 🔥Twitter(X): Добавяне на дисплей за форматиране на време, показване на HD картина, изтегляне на снимки и видео и т.н. 🔥Youtube: Добавяне на изтегляне на видео, премахване на реклами и т.н. 🔥Tiktok: Предоставяне на изтегляне на HD видео без воден знак и т.н. За повече функции , моля, проверете описанието~
// @description:cs    Tento skript poskytne vylepšení některých webových stránek. 🔥Twitter(X): Přidejte zobrazení formátování času, zobrazení obrázků HD, stahování obrázků a videí atd. 🔥Youtube: Přidejte stahování videa, odstraňování reklam atd. 🔥Tiktok: Poskytujte stahování videa HD bez vodoznaku atd. Další funkce , zkontrolujte prosím popis~
// @description:da    Dette script vil give forbedringer til nogle websteder. 🔥Twitter(X): Tilføj tidsformateringsvisning, HD-billedvisning, billed- og videodownload osv. 🔥Youtube: Tilføj videodownload, annoncefjernelse osv. 🔥Tiktok: Giver HD vandmærkefri videodownload osv. For flere funktioner , tjek venligst beskrivelsen~
// @description:de    Dieses Skript verbessert einige Websites. 🔥Twitter(X): Fügt Zeitformatanzeige, HD-Bildanzeige, Bild- und Video-Downloads usw. hinzu. 🔥Youtube: Fügt Video-Downloads, Anzeigenentfernung usw. hinzu. 🔥Tiktok: Bietet HD-Video-Downloads ohne Wasserzeichen usw. Weitere Funktionen finden Sie in der Beschreibung~
// @description:el    Αυτό το σενάριο θα παρέχει βελτιώσεις σε ορισμένους ιστότοπους. 🔥Twitter(X): Προσθήκη εμφάνισης μορφοποίησης ώρας, προβολής εικόνων HD, λήψης εικόνων και βίντεο κ.λπ. 🔥Youtube: Προσθήκη λήψης βίντεο, αφαίρεση διαφημίσεων κ.λπ. 🔥Tiktok: Παρέχετε λήψη βίντεο HD χωρίς υδατογράφημα κ.λπ. Για περισσότερες δυνατότητες , ελέγξτε την περιγραφή~
// @description:en    This script will provide enhancements to some websites. 🔥Twitter(X): Add time formatting display, HD picture display, picture and video downloading, etc. 🔥Youtube: Add video downloading, ad removal, etc. 🔥Tiktok: Provide HD watermark-free video downloading, etc. For more features, please check the description~
// @description:eo    Ĉi tiu skripto provizos plibonigojn al iuj retejoj. 🔥Twitter(X): Aldonu horformatan ekranon, HD-bildon, elŝuton de bildoj kaj filmetojn ktp. 🔥Youtube: Aldonu video-elŝutadon, forigon de reklamoj ktp. 🔥Tiktok: Provizu HD-senpagan video-elŝutadon, ktp. Por pliaj funkcioj , bonvolu kontroli la priskribon~
// @description:es    Este script proporcionará mejoras a algunos sitios web.🔥twitter (x): agregue la pantalla de formato de tiempo, visualización de imágenes HD, descarga de imágenes y videos, etc. 🔥Youtube: Agregue la descarga de video, eliminación de anuncios, etc. 🔥tiktok: proporcione descarga de video sin marca de agua HD, etc. para obtener más funciones, por favor verifique la descripción ~
// @description:fi    Tämä komentosarja tarjoaa parannuksia joihinkin verkkosivustoihin. 🔥Twitter(X): Lisää ajan muotoilun näyttö, HD-kuvanäyttö, kuvien ja videoiden lataus jne. 🔥Youtube: Lisää videoiden lataus, mainosten poisto jne. 🔥Tiktok: Tarjoa HD-vesileimatonta videoiden latausta jne. Lisää ominaisuuksia , tarkista kuvaus~
// @description:fr    Ce script apportera des améliorations à certains sites Web. 🔥Twitter(X) : Ajout de l'affichage du formatage de l'heure, de l'affichage d'images HD, du téléchargement d'images et de vidéos, etc. 🔥Youtube : Ajout du téléchargement de vidéos, de la suppression des publicités, etc. 🔥Tiktok : Fournit un téléchargement de vidéos HD sans filigrane, etc. Pour plus de fonctionnalités, veuillez consulter la description~
// @description:fr-CA Ce script apportera des améliorations à certains sites Web. 🔥Twitter(X) : Ajout de l'affichage du formatage de l'heure, de l'affichage d'images HD, du téléchargement d'images et de vidéos, etc. 🔥Youtube : Ajout du téléchargement de vidéos, de la suppression des publicités, etc. 🔥Tiktok : Fournit un téléchargement de vidéos HD sans filigrane, etc. Pour plus de fonctionnalités, veuillez consulter la description~
// @description:he    סקריפט זה יספק שיפורים לאתרים מסוימים. 🔥Twitter(X): הוסף תצוגת עיצוב זמן, תצוגת תמונות HD, הורדת תמונות ווידאו וכו'. 🔥YouTube: הוסף הורדת וידאו, הסרת מודעות וכו'. , אנא בדוק את התיאור~
// @description:hr    Ova skripta će poboljšati neke web stranice. 🔥Twitter(X): Dodajte prikaz formatiranja vremena, HD prikaz slike, preuzimanje slika i videa itd. 🔥Youtube: Dodajte preuzimanje videa, uklanjanje oglasa itd. 🔥Tiktok: Omogućite preuzimanje HD videa bez vodenog žiga itd. Za više značajki , provjerite opis~
// @description:hu    Ez a szkript fejlesztéseket biztosít bizonyos webhelyeken. 🔥Twitter(X): Időformázási megjelenítés hozzáadása, HD képmegjelenítés, kép- és videóletöltés stb. 🔥Youtube: Videó letöltése, hirdetések eltávolítása stb. , ellenőrizze a leírást~
// @description:id    Skrip ini akan memberikan peningkatan pada beberapa situs web. 🔥Twitter(X): Menambahkan tampilan format waktu, tampilan gambar HD, pengunduhan gambar dan video, dll. 🔥Youtube: Menambahkan pengunduhan video, penghapusan iklan, dll. 🔥Tiktok: Menyediakan pengunduhan video HD tanpa tanda air, dll. Untuk fitur lainnya, silakan periksa deskripsi~
// @description:it    Questo script migliorerà alcuni siti web. 🔥Twitter(X): aggiunge la visualizzazione della formattazione dell'ora, la visualizzazione delle immagini HD, il download di immagini e video, ecc. 🔥Youtube: aggiunge il download di video, la rimozione degli annunci, ecc. 🔥Tiktok: fornisce il download di video HD senza filigrana, ecc. Per altre funzionalità, controlla la descrizione~
// @description:ja    このスクリプトは、いくつかのウェブサイトの機能強化を提供します。🔥Twitter(X): 時間フォーマット表示、HD画像表示、画像とビデオのダウンロードなどを追加します。🔥Youtube: ビデオのダウンロード、広告の削除などを追加します。🔥Tiktok: HDウォーターマークのないビデオのダウンロードなどを提供します。その他の機能については、説明を確認してください~
// @description:ka    This script will provide enhancements to some websites. 🔥Twitter(X): Add time formatting display, HD picture display, picture and video downloading, etc. 🔥Youtube: Add video downloading, ad removal, etc. 🔥Tiktok: Provide HD watermark-free video downloading, etc. For more features, please check the description~
// @description:ko    이 스크립트는 일부 웹사이트에 개선 사항을 제공합니다. 🔥Twitter(X): 시간 형식 표시, HD 사진 표시, 사진 및 비디오 다운로드 등을 추가합니다. 🔥Youtube: 비디오 다운로드, 광고 제거 등을 추가합니다. 🔥Tiktok: HD 워터마크 없는 비디오 다운로드 등을 제공합니다. 자세한 내용은 설명을 확인하세요~
// @description:nb    Dette skriptet vil gi forbedringer til enkelte nettsteder. 🔥Twitter(X): Legg til tidsformateringsvisning, HD-bildevisning, bilde- og videonedlasting osv. 🔥Youtube: Legg til videonedlasting, annonsefjerning osv. 🔥Tiktok: Gi HD vannmerkefri videonedlasting osv. For flere funksjoner , sjekk beskrivelsen~
// @description:nl    Dit script zal verbeteringen aan sommige websites bieden. 🔥Twitter(X): Voeg weergave van tijdsopmaak, HD-afbeeldingsweergave, downloaden van afbeeldingen en video's, enz. toe. 🔥Youtube: Voeg videodownloads, advertentieverwijdering, enz. toe. 🔥Tiktok: Biedt HD-watermerkvrije videodownloads, enz. Voor meer functies, bekijk de beschrijving~
// @description:pl    Ten skrypt wprowadzi ulepszenia do niektórych witryn internetowych. 🔥Twitter(X): Dodaj wyświetlanie formatu czasu, wyświetlanie obrazów HD, pobieranie obrazów i filmów itp. 🔥Youtube: Dodaj pobieranie filmów, usuwanie reklam itp. 🔥Tiktok: Zapewnij pobieranie filmów HD bez znaku wodnego itp. Aby uzyskać więcej funkcji, sprawdź opis~
// @description:pt-BR Este script fornecerá melhorias para alguns sites. 🔥Twitter(X): Adicione exibição de formatação de hora, exibição de imagem em HD, download de imagem e vídeo, etc. 🔥Youtube: Adicione download de vídeo, remoção de anúncios, etc. 🔥Tiktok: Forneça download de vídeo em HD sem marca d'água, etc. Para mais recursos, verifique a descrição~
// @description:ro    Acest script va oferi îmbunătățiri unor site-uri web. 🔥Twitter(X): Adăugați afișaj de formatare a orei, afișare a imaginii HD, descărcare de imagini și videoclipuri etc. 🔥Youtube: Adăugați descărcare video, eliminare a reclamelor etc. 🔥Tiktok: Oferiți descărcare video HD fără filigran etc. Pentru mai multe funcții , vă rugăm să verificați descrierea~
// @description:ru    Этот скрипт улучшит работу некоторых веб-сайтов. 🔥Twitter(X): Добавить отображение форматирования времени, отображение HD-изображений, загрузку изображений и видео и т. д. 🔥Youtube: Добавить загрузку видео, удалить рекламу и т. д. 🔥TikTok: Обеспечить загрузку HD-видео без водяных знаков и т. д. Для получения дополнительных функций, пожалуйста, проверьте описание~
// @description:sk    Tento skript poskytne vylepšenia niektorých webových stránok. 🔥Twitter(X): Pridajte zobrazenie formátovania času, zobrazenie HD obrázkov, sťahovanie obrázkov a videí atď. 🔥Youtube: Pridajte sťahovanie videa, odstraňovanie reklám atď. 🔥Tiktok: Poskytnite sťahovanie videa HD bez vodoznaku atď. Ďalšie funkcie , prosím skontrolujte popis ~
// @description:sr    Ова скрипта ће пружити побољшања неким веб локацијама. 🔥Твиттер(Кс): Додајте приказ форматирања времена, приказ ХД слике, преузимање слика и видео записа итд. 🔥Иоутубе: Додајте преузимање видео записа, уклањање огласа итд. 🔥Тикток: Омогућите преузимање видео записа у ХД-у без воденог жига итд. За више функција , молимо проверите опис~
// @description:sv    Detta skript kommer att ge förbättringar till vissa webbplatser. 🔥Twitter(X): Lägg till tidsformateringsvisning, HD-bildvisning, bild- och videonedladdning, etc. 🔥Youtube: Lägg till videonedladdning, annonsborttagning etc. 🔥Tiktok: Tillhandahåller HD vattenstämpelfri videonedladdning, etc. För fler funktioner , kontrollera beskrivningen~
// @description:th    สคริปต์นี้จะให้การปรับปรุงแก่บางเว็บไซต์🔥twitter (x): เพิ่มการจัดรูปแบบการจัดรูปแบบการจัดรูปแบบการแสดงภาพ HD รูปภาพและวิดีโอการดาวน์โหลด ฯลฯ 🔥youtube: เพิ่มการดาวน์โหลดวิดีโอการลบโฆษณา ฯลฯ 🔥tiktok: ให้การดาวน์โหลดวิดีโอที่ปราศจากลายน้ำ HD ฯลฯ สำหรับคุณสมบัติเพิ่มเติมโปรดตรวจสอบคำอธิบาย ~
// @description:tr    Bu script bazı web sitelerine geliştirmeler sağlayacaktır. 🔥Twitter(X): Zaman biçimlendirme gösterimi, HD resim gösterimi, resim ve video indirme vb. ekleyin. 🔥Youtube: Video indirme, reklam kaldırma vb. ekleyin. 🔥Tiktok: HD filigransız video indirme vb. sağlayın. Daha fazla özellik için lütfen açıklamayı kontrol edin~
// @description:uk    Цей сценарій покращить роботу деяких веб-сайтів. 🔥Twitter(X): додайте відображення форматування часу, відображення HD-зображення, завантаження зображень і відео тощо. 🔥Youtube: додайте завантаження відео, видалення реклами тощо. 🔥Tiktok: забезпечте завантаження відео HD без водяних знаків тощо. Для додаткових функцій , будь ласка, перевірте опис~
// @description:ug    بۇ قوليازما بەزى تور بېكەتلەرنى ياخشىلاش بىلەن تەمىنلەيدۇ. 🔥Twitter (X): ۋاقىت فورماتلاش ئېكرانى ، HD رەسىم كۆرسىتىش ، رەسىم ۋە سىن چۈشۈرۈش قاتارلىقلارنى قوشۇڭ outYoutube: سىن چۈشۈرۈش ، ئېلان ئۆچۈرۈش قاتارلىقلارنى قوشۇڭ ikTiktok: HD سۇ ماركىسىسىز سىن چۈشۈرۈش قاتارلىقلار بىلەن تەمىنلەڭ. ، چۈشەندۈرۈشنى تەكشۈرۈپ بېقىڭ ~
// @description:vi    Tập lệnh này sẽ cung cấp các cải tiến cho một số trang web. 🔥Twitter(X): Thêm hiển thị định dạng thời gian, hiển thị hình ảnh HD, tải xuống hình ảnh và video, v.v. 🔥Youtube: Thêm tải xuống video, xóa quảng cáo, v.v. 🔥Tiktok: Cung cấp tải xuống video HD không có hình mờ, v.v. Để biết thêm các tính năng, vui lòng kiểm tra phần mô tả~
// @namespace   PeterParker_X_Y_NameScope
// @version     1.1.2
// @author      PeterParker
// @icon        data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABhxJREFUeF7lm09oHUUcx3/7nm0aWou2CtL2kFLbREXFRPBU+tJb8Gb1Yg8VhIhHb6U86HvwKKWCR8WAx3qRipfYW7rBk2Iq2EvTKkUspRhbJTRpm/p25TdvZ3d2dmb2N7vzNnnJQMhLdnZ2vp/5/dvdeR5s8eZtcf1QHYDmL40EdhB99o4BhPPpRaj50HnDr2ph+guAiQ7PRmIEAFR5YZv17Ey0qGfY9nMPIBEdCz56/xab19F70e/ob/zfD3sOxnM+d/i4Yf79geEOgCSciz5zcw74Z8rqIBD2s7f3O9vcgigPQCHcVrQOzLkXj4PeKtyAKAegudAC8JiP4yq7Ei4DyQVRIkYUB9C8egUAmJ+j+Ms/fkWx8FJ9pt76UOMW4ENnfLLI4PYAeiaP4lnDVT/z21yRaxc6x2wN3qRtCrUDIJj8eojnxFy6BB3ABhHvGgINgGT2Vfl8no8YYgIA0NyBCOBqKE7mweVm3twqO75rqqO/Vmc8V19uBxCi/Xr6vU4lFktoCZqWmx3MACS/x4tspNXnos2uELZN9xJ6AArxVac8FFifeBW6C9eMLpVjBcZ4YAXAZvV3fHk+nvSTmYtKEShu2/TJuN+jj07Hn/EYH+PJzNewNnPRCMFsBfpCSQ2g5OqLk8dZozDVKqJA7IsNj4sAxGN4fOXNt8sA0FpBJQB0k9/582wsygRAPqYike8GaivIAlCsvm3wM62sOHkRgGwl3D2ChWvQXfg1Nw7guMaUyC6crQ1IAGwLHwoAqpvYFBQ5cQCHyqRFBYB00VMk94srqwtg26dPwrbp92N9opvIwRGtIC8I4kDme4ToUlJxlAagMX+b9CevLAJAE5YbRn9dACxqHSQAkhv0HQDFhOUgJ1uHLovIYxMCYcYNJABZ88cz8GEH9bmenL4oAGQ3sU2B/Bp9A2DjAvLkdVUcN39VnWBKjyagNBdIZ4PEAqRbXvFCNgBcBMB0FZlfBfK5lgSQPOCUKVPTIDV4mdIkdQyVJWwKAEUDIDkNMnLJHaLgAnoLoFaC1OBlchPqGCoLyK8E+VkFAFAygYsKsGgAJGYATiCuCAULSJ7zq+hS4gBl8iYTVxVRlArQzvwLugDFDVAcb7obGBRZn3gt7icKLBMA6eZfAgDFDSiFj+s+9OhvjAHpNz66Sdo8FXItVDee3eprLYAGwKYoqgKA/eoXqARlIRvJFexXH3ecJO8L5Juh+I2vafUoGaGK1cdrrAsAvDAVQv1IgqJ+mI6lezPp272hP88eQPo9gWQBtDjAp8PjAYpEcTVBoCicLtvck4MIIjgIafiQ4dWYcjgTADyhqX4mgIcae3ubnBrP3YJj/HP025XIouO0b/Q2WPl/HwT/nmpvUTSy8ZFYD4AyDrRG5+Dskeo2QhQFgechjNaiasdZ9jUZc4Hwm7FGUOttd1lYHRmZXR4/JU+gse8u4M8gNP/OC4A/cnt5x+35d5/5iW3CrAXge+9d92MAYS3Z9qIS6e3eA7D72UHQD7D8D4TL941z9QJvMgaAPbuXxlpesqsze/LQMHjP79sUALh4FJPKAkYIAwQgXLoD8PihOgeA166fuB5vvc28GAkujaZ2g8SjbAYAHvi1dxZT2+kyADAgKuPBJgAgmj5fWOXbYaUrDBKA279nzF8lPhMD+Fk6K/AOHBqIIBgqANROLCoXW/nP4NvRKxD26gKxDTKAUAp+RhfQBUJbAGJJOh+Vp1iqqhqW13LDcpuX3zamp7IAVvworIAeBDFnalyAC21H5aexFrdRIvVFGByUtix//BBYGlQ0lRVk06DG/FnAwEJoaBi6q6vw5901+O6vV+CTpY9LSCp/6uzYZ/D68B+w/8DTvcHKANCmwGiej4KnYHnpX1hdWYOVB2vwRXgKPg8+KK+ixAgXhj6Fqf++h527trNRRl7ary2CVG6QsgAEQJ0L1tGg2VBBHcNNv94dHnXubN5Cy98qmzdLBoE5CP92WN4Zro77AF7b9vsB8sXLA+AjVgfCiXA+bXcA+g/CqfD+ARBtrJxVRL5a3sxNPufeAkxXY7tQ+Ndm4zUQvj5bSwJURV+frRaAq/DncJwtD+B/6XGfbp4XQ5oAAAAASUVORK5CYII=
// @include     https://x.com/*
// @include     https://twitter.com/*
// @include     https://mobile.x.com/*
// @include     https://www.youtube.com/**
// @include     https://music.youtube.com/watch**
// @include     https://www.tiktok.com/@*
// @include     /^https:\/\/((ko|fr|es|ja|pt|it|th|ar|tr|de|he|nl|pl|www|best)+\.)?aliexpress\.(ru|us|com)\/*/
// @include     /^https:\/\/www\.lazada.(com|sg|th|id|vn|my|ph)*/
// @include     *://www.ebay.*/*
// @exclude     *://accounts.youtube.com/*
// @exclude     *://www.youtube.com/live_chat_replay*
// @exclude     *://www.youtube.com/persist_identity*
// @exclude     *://x.com/i/flow/*
// @connect     tikdownloader.io
// @connect     api.cobalt.tools
// @license     MIT
// @run-at      document-idle
// @antifeature referral-link
// @grant       GM_registerMenuCommand
// @grant       GM_openInTab
// @grant       GM.openInTab
// @grant       GM_addStyle
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_xmlhttpRequest
// @grant       GM_download
// @grant       GM_setClipboard
// ==/UserScript==
(function () {
	'use strict';

	/*!
	* Copyright (c) 2024, PeterParker. All rights reserved.
	*
	* Permission is hereby granted, free of charge, to any person obtaining a copy
	 * of this software and associated documentation files (the "Software"), to deal
	 * in the Software without restriction, including without limitation the rights
	* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	* copies of the Software, and to permit persons to whom the Software is
	* furnished to do so, subject to the following conditions:
	*
	* The above copyright notice and this permission notice shall be included in
	* all copies or substantial portions of the Software.
	*
	* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	*
	* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	* SOFTWARE.
	*/
	const language = {
	  "zh": {
	    "dateFormat": {
	      "week": ["日", "一", "二", "三", "四", "五", "六"]
	    },
	    "download": {
	      "download": "下载",
	      "completed": "下载完成",
	      "tip": "点击下载视频",
	      "preparing": "正在准备下载,请稍后..."
	    },
	    "menuCommand": {
	      "settings": "设置",
	      "titleDateFormat": "时间格式设置:",
	      "buttonClose": "关闭",
	      "goodsHistories": {
	        "clear": "清空所有商品浏览记录"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh!已复制!"
	      },
	      "dialog": {
	        "title": "设置",
	        "contentPieceMax": "最大浏览记录数(最小: {min},最大:{max},改变的值自动保存):",
	        "contentPieceClear": "清除所有浏览历史记录。注意:清除后历史记录不可恢复,请谨慎操作。",
	        "contentPieceClearBtn": "清除",
	        "clearConfirmContent": "是否要清除所有浏览记录?一旦被清除,将无法恢复~"
	      },
	      "historyToolbar": {
	        "boxTitle": "浏览记录",
	        "expandTipText": "记录"
	      }
	    }
	  },
	  "en": {
	    "dateFormat": {
	      "week": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
	    },
	    "download": {
	      "download": "Download",
	      "completed": "Download Completed",
	      "tip": "Click to download video",
	      "preparing": "Preparing to download, please wait..."
	    },
	    "menuCommand": {
	      "settings": "Settings",
	      "titleDateFormat": "Time format settings:",
	      "buttonClose": "Close",
	      "goodsHistories": {
	        "clear": "Clear all product browsing history"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Copied!"
	      },
	      "dialog": {
	        "title": "Ohhhh! I'm settings",
	        "contentPieceMax": "Maximum number of browsing histories(min:{min}, max:{max}, Changed values ​​are automatically saved):",
	        "contentPieceClear": "Clear all browsing history. Note: The history cannot be restored after clearing. Please operate with caution.",
	        "contentPieceClearBtn": "Clear",
	        "clearConfirmContent": "Do you want to clear all browsing history? Once cleared, it cannot be restored"
	      },
	      "historyToolbar": {
	        "boxTitle": "Browsing history",
	        "expandTipText": "History"
	      }
	    }
	  },
	  "ja": {
	    "dateFormat": {
	      "week": ["日", "月", "火", "水", "木", "金", "土"]
	    },
	    "download": {
	      "download": "ダウンロード",
	      "completed": "ダウンロード完了",
	      "tip": "クリックしてビデオをダウンロード",
	      "preparing": "ダウンロードの準備をしています。お待ちください..."
	    },
	    "menuCommand": {
	      "settings": "設定",
	      "titleDateFormat": "時刻形式の設定:",
	      "buttonClose": "閉鎖",
	      "goodsHistories": {
	        "clear": "製品の閲覧履歴をすべて消去する"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, コピーされました"
	      },
	      "dialog": {
	        "title": "設定",
	        "contentPieceMax": "閲覧レコードの最大数(最小値:{min}、最大値:{max}、変更された値は自動的に保存されます):",
	        "contentPieceClear": "すべての閲覧履歴を消去します。 ※クリア後の履歴は元に戻せませんので、慎重に操作してください。",
	        "contentPieceClearBtn": "クリア",
	        "clearConfirmContent": "すべての閲覧履歴を消去しますか?一度クリアすると元に戻せませんよ~"
	      },
	      "historyToolbar": {
	        "boxTitle": "閲覧履歴",
	        "expandTipText": "記録"
	      }
	    }
	  },
	  "fr": {
	    "dateFormat": {
	      "week": ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"]
	    },
	    "download": {
	      "download": "télécharger",
	      "completed": "éléchargement terminé",
	      "tip": "Cliquez pour télécharger la vidéo",
	      "preparing": "Vous êtes en train de télécharger, veuillez patienter..."
	    },
	    "menuCommand": {
	      "settings": "installation",
	      "titleDateFormat": "Paramètres du format de l'heure :",
	      "buttonClose": "fermeture",
	      "goodsHistories": {
	        "clear": "Effacer tout l'historique de navigation des produits"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Copié!"
	      },
	      "dialog": {
	        "title": "installation",
	        "contentPieceMax": "Nombre maximum d'enregistrements de navigation (minimum : {min}, maximum : {max}, les valeurs modifiées sont automatiquement enregistrées) :",
	        "contentPieceClear": "Effacez tout l’historique de navigation. Remarque : L'historique ne peut pas être récupéré après l'effacement, veuillez agir avec prudence.",
	        "contentPieceClearBtn": "Clair",
	        "clearConfirmContent": "Voulez-vous effacer tout l’historique de navigation ? Une fois effacé, il ne peut pas être restauré ~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Historique de navigation",
	        "expandTipText": "Enregistrer"
	      }
	    }
	  },
	  "de": {
	    "dateFormat": {
	      "week": ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"]
	    },
	    "download": {
	      "download": "herunterladen",
	      "completed": "Download abgeschlossen",
	      "tip": "Klicken Sie hier, um das Video herunterzuladen",
	      "preparing": "Der Download wird vorbereitet, bitte warten..."
	    },
	    "menuCommand": {
	      "settings": "aufstellen",
	      "titleDateFormat": "Einstellungen für das Zeitformat:",
	      "buttonClose": "Schließung",
	      "goodsHistories": {
	        "clear": "Löschen Sie den gesamten Browserverlauf des Produkts"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Kopiert!"
	      },
	      "dialog": {
	        "title": "aufstellen",
	        "contentPieceMax": "Maximale Anzahl an Browsing-Datensätzen (Minimum: {min}, Maximum: {max}, geänderte Werte werden automatisch gespeichert):",
	        "contentPieceClear": "Löschen Sie den gesamten Browserverlauf. Hinweis: Der Verlauf kann nach dem Löschen nicht wiederhergestellt werden. Bitte gehen Sie vorsichtig vor.",
	        "contentPieceClearBtn": "Klar",
	        "clearConfirmContent": "Möchten Sie den gesamten Browserverlauf löschen? Nach dem Löschen kann es nicht wiederhergestellt werden~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Browser-Verlauf",
	        "expandTipText": "Aufzeichnen"
	      }
	    }
	  },
	  "it": {
	    "dateFormat": {
	      "week": ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"]
	    },
	    "download": {
	      "download": "scaricamento",
	      "completed": "Download completato",
	      "tip": "Fare clic per scaricare il video",
	      "preparing": "Preparazione al download, attendere..."
	    },
	    "menuCommand": {
	      "settings": "impostare",
	      "titleDateFormat": "Impostazioni del formato dell'ora:",
	      "buttonClose": "chiusura",
	      "goodsHistories": {
	        "clear": "Cancella tutta la cronologia di navigazione del prodotto"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Copiato!"
	      },
	      "dialog": {
	        "title": "impostare",
	        "contentPieceMax": "Numero massimo di record di navigazione (minimo: {min}, massimo: {max}, i valori modificati vengono salvati automaticamente):",
	        "contentPieceClear": "Cancella tutta la cronologia di navigazione. Nota: la cronologia non può essere recuperata dopo la cancellazione, si prega di operare con cautela.",
	        "contentPieceClearBtn": "Chiaro",
	        "clearConfirmContent": "Vuoi cancellare tutta la cronologia di navigazione? Una volta cancellato, non può essere ripristinato~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Cronologia di navigazione",
	        "expandTipText": "Documentazione"
	      }
	    }
	  },
	  "ko": {
	    "dateFormat": {
	      "week": ["일", "월", "화", "수", "목", "금", "토"]
	    },
	    "download": {
	      "download": "다운로드",
	      "completed": "다운로드 완료",
	      "tip": "비디오를 다운로드하려면 클릭하세요",
	      "preparing": "다운로드 준비 중입니다. 잠시 기다려 주세요..."
	    },
	    "menuCommand": {
	      "settings": "설정",
	      "titleDateFormat": "시간 형식 설정:",
	      "buttonClose": "폐쇄",
	      "goodsHistories": {
	        "clear": "모든 제품 검색 기록 지우기"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, 복사됨!"
	      },
	      "dialog": {
	        "title": "설정",
	        "contentPieceMax": "최대 검색 기록 수(최소: {min}, 최대: {max}, 변경된 값은 자동으로 저장됩니다):",
	        "contentPieceClear": "모든 검색 기록을 지웁니다. 참고: 삭제 후에는 기록을 복구할 수 없으므로 주의해서 조작하시기 바랍니다.",
	        "contentPieceClearBtn": "분명한",
	        "clearConfirmContent": "모든 검색 기록을 삭제하시겠습니까? 한번 삭제하면 복원이 불가능해요~"
	      },
	      "historyToolbar": {
	        "boxTitle": "검색 기록",
	        "expandTipText": "기록"
	      }
	    }
	  },
	  "ru": {
	    "dateFormat": {
	      "week": ["ВС", "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ"]
	    },
	    "download": {
	      "download": "скачать",
	      "completed": "Загрузка завершена",
	      "tip": "Нажмите, чтобы скачать видео",
	      "preparing": "Подготовка к загрузке, пожалуйста, подождите..."
	    },
	    "menuCommand": {
	      "settings": "настраивать",
	      "titleDateFormat": "Настройки формата времени:",
	      "buttonClose": "закрытие",
	      "goodsHistories": {
	        "clear": "Очистить всю историю просмотра товаров"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Скопировано!"
	      },
	      "dialog": {
	        "title": "настраивать",
	        "contentPieceMax": "Максимальное количество записей просмотра (минимум: {min}, максимум: {max}, измененные значения сохраняются автоматически):",
	        "contentPieceClear": "Очистить всю историю просмотров. Примечание. После очистки историю невозможно восстановить, действуйте осторожно.",
	        "contentPieceClearBtn": "Прозрачный",
	        "clearConfirmContent": "Хотите очистить всю историю просмотров? После очистки его невозможно восстановить~"
	      },
	      "historyToolbar": {
	        "boxTitle": "История браузера",
	        "expandTipText": "Записывать"
	      }
	    }
	  },
	  "pt": {
	    "dateFormat": {
	      "week": ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]
	    },
	    "download": {
	      "download": "descargar",
	      "completed": "Descarga completa",
	      "tip": "Clique para baixar o vídeo",
	      "preparing": "Preparando o download, aguarde..."
	    },
	    "menuCommand": {
	      "settings": "configuración",
	      "titleDateFormat": "Configuración de formato de hora:",
	      "buttonClose": "cierre",
	      "goodsHistories": {
	        "clear": "Quer limpar todo o histórico de navegação do produto? Uma vez limpo, não será recuperável"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Copiado!"
	      },
	      "dialog": {
	        "title": "configurar",
	        "contentPieceMax": "Número máximo de registos de navegação (mínimo: {min}, máximo: {max}, os valores alterados são guardados automaticamente):",
	        "contentPieceClear": "Limpe todo o histórico de navegação. Nota: O histórico não pode ser recuperado após a limpeza, opere com cuidado.",
	        "contentPieceClearBtn": "Claro",
	        "clearConfirmContent": "Quer limpar todo o histórico de navegação? Uma vez limpo, não pode ser restaurado ~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Histórico de navegação",
	        "expandTipText": "Registo"
	      }
	    }
	  },
	  "es": {
	    "dateFormat": {
	      "week": ["DOM", "LUN", "MAR", "MIER", "JUE", "VIE", "SÁB"]
	    },
	    "download": {
	      "download": "descargar",
	      "completed": "Descarga completa",
	      "tip": "Haga clic para descargar el vídeo",
	      "preparing": "Preparándose para descargar, espere..."
	    },
	    "menuCommand": {
	      "settings": "configuración",
	      "titleDateFormat": "Configuración de formato de hora:",
	      "buttonClose": "cierre",
	      "goodsHistories": {
	        "clear": "Borrar todo el historial de navegación de productos"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Copiado!"
	      },
	      "dialog": {
	        "title": "configuración",
	        "contentPieceMax": "Número máximo de registros de navegación (mínimo: {min}, máximo: {max}, los valores modificados se guardan automáticamente):",
	        "contentPieceClear": "Borrar todo el historial de navegación. Nota: El historial no se puede recuperar después de borrarlo; opere con precaución.",
	        "contentPieceClearBtn": "Claro",
	        "clearConfirmContent": "¿Quieres borrar todo el historial de navegación? Una vez borrado, no se puede restaurar ~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Historial de navegación",
	        "expandTipText": "Registro"
	      }
	    }
	  },
	  "th": {
	    "dateFormat": {
	      "week": ["วันอาทิตย์", "วันจันทร์", "วันอังคาร", "วันพุธ", " วันพฤหัสบดี", "วันศุกร์ ", "วันเสาร์ "]
	    },
	    "download": {
	      "download": "ดาวน์โหลด",
	      "completed": "ดาวน์โหลดเสร็จสมบูรณ์",
	      "tip": "คลิกเพื่อดาวน์โหลดวิดีโอ",
	      "preparing": "กำลังเตรียมดาวน์โหลด กรุณารอสักครู่..."
	    },
	    "menuCommand": {
	      "settings": "ตั้งค่า",
	      "titleDateFormat": "การตั้งค่ารูปแบบเวลา:",
	      "buttonClose": "ปิด",
	      "goodsHistories": {
	        "clear": "ล้างประวัติการเรียกดูผลิตภัณฑ์ทั้งหมด"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh!โอ้! คัดลอก!"
	      },
	      "dialog": {
	        "title": "ตั้งค่า",
	        "contentPieceMax": "จำนวนบันทึกการสืบค้นสูงสุด (ขั้นต่ำ: {min}, สูงสุด: {max}, ค่าที่เปลี่ยนแปลงจะถูกบันทึกโดยอัตโนมัติ):",
	        "contentPieceClear": "ล้างประวัติการเข้าชมทั้งหมด หมายเหตุ: ไม่สามารถกู้คืนประวัติได้หลังจากเคลียร์แล้ว โปรดดำเนินการด้วยความระมัดระวัง",
	        "contentPieceClearBtn": "ชัดเจน",
	        "clearConfirmContent": "คุณต้องการล้างประวัติการเข้าชมทั้งหมดหรือไม่? เมื่อเคลียร์แล้วจะไม่สามารถกู้คืนได้~"
	      },
	      "historyToolbar": {
	        "boxTitle": "ประวัติการเรียกดู",
	        "expandTipText": "บันทึก"
	      }
	    }
	  },
	  "tr": {
	    "dateFormat": {
	      "week": ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"]
	    },
	    "download": {
	      "download": "indirmek",
	      "completed": "İndirme tamamlandı",
	      "tip": "Videoyu indirmek için tıklayın",
	      "preparing": "İndirmeye hazırlanıyor, lütfen bekleyin..."
	    },
	    "menuCommand": {
	      "settings": "kurmak",
	      "titleDateFormat": "Saat formatı ayarları:",
	      "buttonClose": "kapatma",
	      "goodsHistories": {
	        "clear": "Tüm ürün tarama geçmişini temizle"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh,Kopyalandı!"
	      },
	      "dialog": {
	        "title": "kurmak",
	        "contentPieceMax": "Maksimum tarama kaydı sayısı (minimum: {min}, maksimum: {max}, değiştirilen değerler otomatik olarak kaydedilir):",
	        "contentPieceClear": "Tüm tarama geçmişini temizleyin. Not: Geçmiş temizlendikten sonra kurtarılamaz, lütfen dikkatli çalışın.",
	        "contentPieceClearBtn": "Temizlemek",
	        "clearConfirmContent": "Tüm tarama geçmişini temizlemek istiyor musunuz? Bir kez temizlendiğinde geri yüklenemez~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Tarama geçmişi",
	        "expandTipText": "Kayıt"
	      }
	    }
	  },
	  "nl": {
	    "dateFormat": {
	      "week": ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"]
	    },
	    "download": {
	      "download": "downloaden",
	      "completed": "Downloaden voltooid",
	      "tip": "Klik om video te downloaden",
	      "preparing": "Bezig met downloaden, even geduld a.u.b...."
	    },
	    "menuCommand": {
	      "settings": "opgezet",
	      "titleDateFormat": "Instellingen tijdformaat:",
	      "buttonClose": "sluiting",
	      "goodsHistories": {
	        "clear": "Wis de volledige browsegeschiedenis van producten"
	      }
	    },
	    "ecommerce": {
	      "operat": {
	        "copied": "Ohhhh, Gekopieerd!"
	      },
	      "dialog": {
	        "title": "opgezet",
	        "contentPieceMax": "Maximaal aantal browserecords (minimaal: {min}, maximaal: {max}, gewijzigde waarden worden automatisch opgeslagen):",
	        "contentPieceClear": "Wis alle browsegeschiedenis. Opmerking: de geschiedenis kan na het wissen niet worden hersteld. Wees voorzichtig.",
	        "contentPieceClearBtn": "Duidelijk",
	        "clearConfirmContent": "Wilt u de hele browsegeschiedenis wissen? Eenmaal gewist, kan het niet meer worden hersteld~"
	      },
	      "historyToolbar": {
	        "boxTitle": "Geschiedenis doorbladeren",
	        "expandTipText": "Dossier"
	      }
	    }
	  }
	};

	const isDev = false, isDebug = false;
	const currentHost = window.location.host;
	const currentUrl = window.location.href;
	(navigator.language.indexOf("-") != -1 ? navigator.language.split("-")[0] : navigator.language).toLocaleLowerCase();
	const storageKeys = {};
	const ScriptConst = {
	  "language": language,
	  "isDev": isDev,
	  "isDebug": isDebug,
	  "currentHost": currentHost,
	  "currentUrl": currentUrl,
	  "storageKeys": storageKeys
	};

	var __async$7 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const selectLanguage = () => {
	  var _a;
	  return (_a = ScriptConst.language[ScriptConst.lang]) != null ? _a : ScriptConst.language["en"];
	};
	const logger = (level = "log", ...messages) => {
	  {
	    return;
	  }
	};
	const Tools = {
	  decryptStr: function(str) {
	    let result = atob(str);
	    return result.split("").reverse().join("");
	  },
	  encryptStr: function(str) {
	    let result = str.split("").reverse().join("");
	    return btoa(result);
	  },
	  platform: function() {
	    let platform = "unknown";
	    const currentHost = ScriptConst.currentHost;
	    if (/twitter|x\.com$/.test(currentHost)) {
	      platform = "x";
	    } else if (/aliexpress/.test(currentHost)) {
	      platform = "aliexpress";
	    } else if (/youtube\.com$/.test(currentHost)) {
	      platform = "youtube";
	    } else if (/www\.amazon\.com$/.test(currentHost)) {
	      platform = "amazon";
	    } else if (/www\.ebay\./.test(currentHost)) {
	      platform = "ebay";
	    } else if (/www\.lazada\./.test(currentHost)) {
	      platform = "lazada";
	    } else if (/www\.tiktok\.com/.test(currentHost)) {
	      platform = "tiktok";
	    }
	    return platform;
	  },
	  removeAliexpressAnchors: function(node) {
	    const tagName = node.tagName;
	    if (!tagName)
	      return;
	    const exist = ["A", "IMG", "DIV", "SPAN", "LABEL", "TABLE", "TR", "TD", "CANVAS"].some((name) => name === tagName);
	    if (exist) {
	      node.removeAttribute("data-spm-anchor-id");
	      for (let i = 0; i < node.childNodes.length; i++) {
	        this.removeAliexpressAnchors(node.childNodes[i]);
	      }
	    }
	  },
	  openInTab: function(url, options = { "active": true, "insert": true, "setParent": true }) {
	    if (typeof GM_openInTab === "function") {
	      GM_openInTab(url, options);
	    } else {
	      GM.openInTab(url, options);
	    }
	  },
	  request: function(mothed, url, param, headers = { "Content-Type": "application/json;charset=UTF-8" }) {
	    return new Promise(function(resolve, reject) {
	      GM_xmlhttpRequest({
	        url,
	        method: mothed,
	        data: param,
	        headers,
	        onload: function(response) {
	          const status = response.status;
	          if (status == 200 || status == "200") {
	            var responseText = response.responseText;
	            resolve({ "code": "success", "result": responseText });
	          } else {
	            resolve({ "code": "error", "result": null });
	          }
	        },
	        onabort: function() {
	          resolve({ "code": "error", "result": null });
	        },
	        onerror: function() {
	          resolve({ "code": "error", "result": null });
	        }
	      });
	    });
	  },
	  crossRequest: function(method, url, param) {
	    if (!method) {
	      method = "get";
	    }
	    if (!url) {
	      return new Promise(function(resolve, reject) {
	        reject({ "code": "error", "result": null });
	      });
	    }
	    if (!param) {
	      param = {};
	    }
	    method = method.toUpperCase();
	    let config = {
	      method
	    };
	    if (method === "POST") {
	      config.headers["Content-Type"] = "application/json";
	      config.body = JSON.stringify(param);
	    }
	    return new Promise(function(resolve, reject) {
	      fetch(url, config).then((response) => response.text()).then((text) => {
	        resolve({ "code": "success", "result": text });
	      }).catch((error) => {
	        reject({ "code": "error", "result": null });
	      });
	    });
	  },
	  getParamterBySuffix: function(url = window.location.href, suffix = "html") {
	    if (url.indexOf("?") != -1) {
	      url = url.split("?")[0];
	    }
	    if (url.indexOf("#") != -1) {
	      url = url.split("#")[0];
	    }
	    let regex = new RegExp("/item/([^/]*?)." + suffix);
	    if (/lazada/.test(url)) {
	      regex = new RegExp("-i(\\d+)-");
	    }
	    const match = url.match(regex);
	    return match ? match[1] : null;
	  },
	  getParamterBySearch: function(paramsString = window.location.href, tag) {
	    if (paramsString.indexOf("?") != -1) {
	      paramsString = paramsString.split("?")[1];
	    }
	    const params = new URLSearchParams(paramsString);
	    return params.get(tag);
	  },
	  waitForElementByInterval: function(selector, target = document.body, allowEmpty = true, delay = 10, maxDelay = 10 * 1e3) {
	    return new Promise((resolve, reject) => {
	      let totalDelay = 0;
	      let element = target.querySelector(selector);
	      let result = allowEmpty ? !!element : !!element && !!element.innerHTML;
	      if (result) {
	        resolve(element);
	      }
	      const elementInterval = setInterval(() => {
	        if (totalDelay >= maxDelay) {
	          clearInterval(elementInterval);
	          resolve(null);
	        }
	        element = target.querySelector(selector);
	        result = allowEmpty ? !!element : !!element && !!element.innerHTML;
	        if (result) {
	          clearInterval(elementInterval);
	          resolve(element);
	        } else {
	          totalDelay += delay;
	        }
	      }, delay);
	    });
	  },
	  randomNumber: function() {
	    return Math.ceil(Math.random() * 1e8);
	  },
	  elementInContainer: function(container, element) {
	    return container.contains(element);
	  },
	  mustGetElement: function(handler) {
	    return __async$7(this, null, function* () {
	      const getElements = (handler2) => __async$7(this, null, function* () {
	        const promiseArray = [];
	        const handlers = handler2.split("@");
	        for (let i = 0; i < handlers.length; i++) {
	          const eleName = handlers[i];
	          if (!eleName) {
	            continue;
	          }
	          if (eleName == "body") {
	            promiseArray.push(
	              new Promise((resolve, reject) => {
	                resolve(document.body);
	              })
	            );
	          } else if (eleName == "html") {
	            promiseArray.push(
	              new Promise((resolve, reject) => {
	                resolve(document.html);
	              })
	            );
	          } else {
	            promiseArray.push(this.waitForElementByInterval(eleName, document.body, true, 10, 1500));
	          }
	        }
	        let element2 = yield Promise.race(promiseArray);
	        return element2;
	      });
	      let element = yield getElements(handler);
	      return new Promise((resolve, reject) => {
	        if (element) {
	          resolve(element);
	          return;
	        }
	        const waitInterval = setInterval(() => {
	          element = getElements(handler);
	          if (element) {
	            clearInterval(waitInterval);
	            resolve(element);
	            return;
	          }
	        }, 2e3);
	      });
	    });
	  },
	  loopTask: function(callback, delay = 1500) {
	    callback();
	    setInterval(() => {
	      callback();
	    }, delay);
	  },
	  distinguishRemoveAndTry: function(distinguish, callback) {
	    const distinguishElements = distinguish.map((name) => document.querySelector("*[name='" + name + "']"));
	    const validateRs = distinguishElements.some((ele) => ele === null || ele === void 0);
	    if (validateRs) {
	      distinguishElements.reverse().forEach((element) => {
	        if (element) {
	          element.remove();
	        }
	      });
	      callback();
	    }
	  }
	};

	const Toast = {
	  initStyle: function() {
	    GM_addStyle(`
      @keyframes fadeIn {
          0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @-webkit-keyframes fadeIn {
          0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @-moz-keyframes fadeIn {
          0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @-o-keyframes fadeIn {
          0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @-ms-keyframes fadeIn {
          0%    {opacity: 0}
          100%  {opacity: 1}
      }
      @keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      @-webkit-keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      @-moz-keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      @-o-keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      @-ms-keyframes fadeOut {
          0%    {opacity: 1}
          100%  {opacity: 0}
      }
      .toast-style-kk998y{
          position: fixed;
          background: rgba(0, 0, 0, 0.7);
          color: #fff;
          font-size: 14px;
          line-height: 1;
          padding:10px;
          border-radius: 3px;
          left: 50%;
          transform: translateX(-50%);
          -webkit-transform: translateX(-50%);
          -moz-transform: translateX(-50%);
          -o-transform: translateX(-50%);
          -ms-transform: translateX(-50%);
          z-index: 999999999999999999999999999;
          white-space: nowrap;
      }
      .fadeOut{
          animation: fadeOut .5s;
      }
      .fadeIn{
          animation:fadeIn .5s;
      }
    `);
	  },
	  show: function(params) {
	    let time = params.time;
	    let background = params.background;
	    let color = params.color;
	    let position = params.position;
	    let defaultMarginValue = 50;
	    if (time == void 0 || time == "") {
	      time = 1500;
	    }
	    if (position == void 0 || position == "") {
	      position = "center-bottom";
	    }
	    const el = document.createElement("div");
	    if (background != void 0 && background != "") {
	      el.style.backgroundColor = background;
	    }
	    if (color != void 0 && color != "") {
	      el.style.color = color;
	    }
	    el.setAttribute("class", "toast-style-kk998y");
	    el.innerText = params.message;
	    el.style.zIndex = 999999999;
	    if (position === "center-bottom") {
	      el.style.bottom = defaultMarginValue + "px";
	    } else {
	      el.style.top = defaultMarginValue + "px";
	    }
	    document.body.appendChild(el);
	    el.classList.add("fadeIn");
	    setTimeout(function() {
	      el.classList.remove("fadeIn");
	      el.classList.add("fadeOut");
	      el.addEventListener("animationend", function() {
	        document.body.removeChild(el);
	      });
	      el.addEventListener("webkitAnimationEnd", function() {
	        document.body.removeChild(el);
	      });
	    }, time);
	  }
	};

	var __async$6 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const FMT = 7;
	let fmt = GM_getValue("fmt", FMT);
	const XSettingsDialog = {
	  number: Math.ceil(Math.random() * 1e8),
	  formats: [
	    "Do nothing",
	    "31.12.70 23:59",
	    "31.12.70 23:59:59",
	    "31.12.70(Th) 23:59",
	    "31.12.70(Th) 23:59:59",
	    "70/12/31 23:59",
	    "70/12/31 23:59:59",
	    "70/12/31(Th) 23:59",
	    "70/12/31(Th) 23:59:59 [ye/mo/da(we) ho:mi:se]",
	    "70-12/31 23:59",
	    "70-12/31 23:59'59",
	    "70-12/31(Th) 23:59",
	    "70-12/31(Th) 23:59'59",
	    "M59-12-31 23:59",
	    "M59-12-31 23:59:59",
	    "M59-12-31(Th) 23:59",
	    "M59-12-31(Th) 23:59:59"
	  ],
	  make: function() {
	    let dialog = document.createElement("div");
	    dialog.className = "dialog_u_" + this.number;
	    dialog.style.all = "initial";
	    dialog.style.backgroundColor = "rgb(235, 235, 235)";
	    dialog.style.borderRadius = "2px";
	    dialog.style.display = "none";
	    dialog.style.fontFamily = "monospace";
	    dialog.style.fontSize = "12px";
	    dialog.style.width = "480px";
	    dialog.style.paddingLeft = "5px";
	    dialog.style.paddingRight = "5px";
	    dialog.style.paddingTop = "5px";
	    dialog.style.paddingBottom = "5px";
	    dialog.style.position = "fixed";
	    dialog.style.right = "8px";
	    dialog.style.top = "8px";
	    dialog.style.zIndex = "2147483647";
	    dialog.style.overflow = "auto";
	    let formatsHtml = `<table border="0" style="width:100%;padding:5px;">`;
	    for (var i = 1; i <= this.formats.length; i++) {
	      if (i % 2 != 0) {
	        formatsHtml += `<tr style="width:100%;">`;
	      }
	      formatsHtml += `<td width="50"><input type="radio" name="fmt" value="` + (i - 1) + `" class="top_r" />` + (i + "." + this.formats[i - 1]) + `</td>`;
	      if (i % 2 == 0) {
	        formatsHtml += `</tr>`;
	      }
	    }
	    formatsHtml += `</table>`;
	    let html = `
        <div style="font-size:15px;font-weight:bold;margin-bottom:5px;">` + selectLanguage().menuCommand.titleDateFormat + `</div>
        <div>` + formatsHtml + `</div>
        <div style="margin-top:15px;text-align:center;">
          <button name="closex">` + selectLanguage().menuCommand.buttonClose + `</button>
        </div>
      `;
	    dialog.innerHTML = html;
	    return dialog;
	  },
	  addEvent: function(dialog) {
	    dialog.querySelector("button[name='closex']").addEventListener("click", function(event) {
	      for (let e of dialog.querySelectorAll('input[name="fmt"]')) {
	        if (e.checked) {
	          fmt = +e.value;
	          break;
	        }
	      }
	      GM_setValue("fmt", fmt);
	      dialog.style.display = "none";
	    }, false);
	  },
	  init: function() {
	    let dialog = this.make();
	    this.addEvent(dialog);
	    document.body.appendChild(dialog);
	    GM_registerMenuCommand(selectLanguage().menuCommand.settings, function() {
	      if (dialog.style.display == "none") {
	        dialog.querySelector('input[name="fmt"][value="' + fmt + '"]').checked = true;
	        dialog.style.display = "block";
	      }
	    });
	  }
	};
	const XDateFormat = {
	  df: function(date, f) {
	    var _a;
	    const WEEK = selectLanguage().dateFormat.week;
	    const YE = date.getFullYear().toString().slice(-2);
	    const YM = date.getFullYear() - 1911;
	    const MO = ("0" + (date.getMonth() + 1)).slice(-2);
	    const DA = ("0" + date.getDate()).slice(-2);
	    const WE = WEEK[date.getDay()];
	    const HO = ("0" + date.getHours()).slice(-2);
	    const MI = ("0" + date.getMinutes()).slice(-2);
	    const SE = ("0" + date.getSeconds()).slice(-2);
	    const F = [
	      DA + "." + MO + "." + YE + " " + HO + ":" + MI,
	      DA + "." + MO + "." + YE + " " + HO + ":" + MI + ":" + SE,
	      DA + "." + MO + "." + YE + "(" + WE + ") " + HO + ":" + MI,
	      DA + "." + MO + "." + YE + "(" + WE + ") " + HO + ":" + MI + ":" + SE,
	      YE + "/" + MO + "/" + DA + " " + HO + ":" + MI,
	      YE + "/" + MO + "/" + DA + " " + HO + ":" + MI + ":" + SE,
	      YE + "/" + MO + "/" + DA + "(" + WE + ") " + HO + ":" + MI,
	      YE + "/" + MO + "/" + DA + "(" + WE + ") " + HO + ":" + MI + ":" + SE,
	      YE + "-" + MO + "/" + DA + " " + HO + ":" + MI,
	      YE + "-" + MO + "/" + DA + " " + HO + ":" + MI + "'" + SE,
	      YE + "-" + MO + "/" + DA + "(" + WE + ") " + HO + ":" + MI,
	      YE + "-" + MO + "/" + DA + "(" + WE + ") " + HO + ":" + MI + "'" + SE,
	      "M" + YM + "-" + MO + "-" + DA + " " + HO + ":" + MI,
	      "M" + YM + "-" + MO + "-" + DA + " " + HO + ":" + MI + ":" + SE,
	      "M" + YM + "-" + MO + "-" + DA + "(" + WE + ") " + HO + ":" + MI,
	      "M" + YM + "-" + MO + "-" + DA + "(" + WE + ") " + HO + ":" + MI + ":" + SE,
	      YE + "/" + MO + "/" + DA + "(" + WE + ") " + HO + ":" + MI + ":" + SE
	    ];
	    return (_a = F[f - 1]) != null ? _a : F[16];
	  },
	  repldatetime: function() {
	    const MYNAME = "peter_parker_x1190";
	    const SEL = 'main div[data-testid="primaryColumn"] section article time[datetime*=":"]';
	    const SEL_2 = 'div[aria-labelledby="modal-header"] div[data-testid^="User-Name"] time[datetime]';
	    const SEL_3 = 'div[aria-labelledby="modal-header"] div[aria-label] time[datetime]';
	    const SEL_4 = 'main section[aria-labelledby="detail-header"] article div[data-testid^="User-Name"] time[datetime]';
	    const SEL_5 = 'main section div[data-testid="conversation"] div[aria-label] time[datetime]';
	    document.querySelectorAll(SEL + ", " + SEL_2 + ", " + SEL_3 + ", " + SEL_4 + ", " + SEL_5).forEach((e) => {
	      const SEL_ADD = "span.us-" + MYNAME;
	      let d = e.getAttribute("datetime");
	      let df = this.df(new Date(d), fmt);
	      let pe = e.parentNode;
	      let old = pe.querySelectorAll(SEL_ADD);
	      if (!old.length) {
	        let span = document.createElement("span");
	        span.className = "us-" + MYNAME;
	        span.setAttribute("datetime", d);
	        span.setAttribute("local-datetime", df);
	        span.textContent = df;
	        span.style = e.style;
	        e.style.setProperty("display", "none");
	        pe.appendChild(span);
	      } else if (old[0].getAttribute("local-datetime") != df) {
	        old[0].setAttribute("local-datetime", df);
	        old[0].textContent = df;
	        old[0].style = e.style;
	      }
	    });
	  }
	};
	const XOrigimg = () => {
	  const SEL_D = 'div[style*="background-image:"]';
	  const SEL_I = "img";
	  let elms = document.querySelectorAll(SEL_D + ", " + SEL_I);
	  for (let e of elms) {
	    let regex = /^(.+pbs\.twimg\.com\/[^?]+\?format=\w+)(&|&amp;)(name=)(\w+)([")]*)$/;
	    if (/div/i.test(e.tagName)) {
	      let r2 = regex.exec(e.style.backgroundImage);
	      if (r2 && r2[4] != "orig") {
	        e.style.backgroundImage = r2[1] + r2[2] + r2[3] + "orig" + r2[5];
	        continue;
	      }
	      continue;
	    }
	    let r = regex.exec(e.getAttribute("src"));
	    if (r && r[4] != "orig") {
	      e.setAttribute("src", r[1] + r[2] + r[3] + "orig" + r[5]);
	      continue;
	    }
	  }
	};
	const XHidepromo = () => {
	  var _a, _b;
	  const SEL = 'path[d^="M19.498 3h-15c-1.381 0-2.5 1.12-2.5 2.5v13c0 1.38 1.119 2.5"]';
	  const SEL_2 = 'main div[data-testid="sidebarColumn"] section div[data-testid="trend"] div.r-14gqq1x span.css-1qaijid.r-bcqeeo.r-qvutc0';
	  const SEL_3 = 'main div[data-testid="primaryColumn"] section article span.css-1jxf684.r-bcqeeo.r-qvutc0.r-poiln3';
	  const SEL_4 = 'main div[data-testid="primaryColumn"] section span.css-901oao.css-16my406.r-bcqeeo.r-qvutc0';
	  let elms = document.querySelectorAll(SEL);
	  let elms_2 = document.querySelectorAll(SEL_2);
	  let elms_3 = document.querySelectorAll(SEL_3);
	  let elms_4 = document.querySelectorAll(SEL_4);
	  const PROMO = {
	    "ja": "によるプロモーション$",
	    "ko": " 님이 프로모션함$",
	    "zh": "^由 .+ 推广$",
	    "ru": "^Реклама от ",
	    "de": "^Gesponsert von ",
	    "it": "^Sponsorizzato da ",
	    "fr": "^Sponsorisé par ",
	    "pt": "^Promovido por ",
	    "en": "^Promoted by "
	  };
	  const PROMO_L = (_a = PROMO[ScriptConst.lang]) != null ? _a : PROMO["en"];
	  const PROMO_2 = {
	    "ja": "プロモポスト",
	    "ko": "Promoted Post",
	    "zh": "推广帖",
	    "ru": "Promoted Post",
	    "de": "Gesponserter Post",
	    "it": "Promoted Post",
	    "fr": "Promoted Post",
	    "pt": "Post promovido",
	    "en": "Promoted Post"
	  };
	  const PROMO_L_2 = (_b = PROMO_2[ScriptConst.lang]) != null ? _b : PROMO_2["en"];
	  for (let e of elms) {
	    let xpe = e.closest('div[data-testid="cellInnerDiv"]');
	    if (!xpe)
	      xpe = e.closest("div.css-175oi2r.r-1adg3ll.r-1ny4l3l");
	    if (!xpe)
	      xpe = e.closest('div.css-175oi2r.r-1ny4l3l[data-testid="UserCell"]');
	    if (xpe)
	      xpe.style.setProperty("display", "none");
	  }
	  for (let e of elms_2) {
	    const REGEX = new RegExp(PROMO_L, "i");
	    if (!REGEX.test(e.textContent))
	      continue;
	    let xpe = e.closest("div.css-175oi2r.r-1adg3ll.r-1ny4l3l");
	    xpe.style.setProperty("display", "none");
	  }
	  for (let e of elms_3) {
	    if (e.textContent != "Ad")
	      continue;
	    let xpe = e.closest('div[data-testid="cellInnerDiv"]');
	    xpe.style.setProperty("display", "none");
	  }
	  for (let e of elms_4) {
	    if (e.textContent != PROMO_2["en"] && e.textContent != PROMO_L_2)
	      continue;
	    let xpe = e.closest('div[data-testid="cellInnerDiv"]');
	    xpe.style.setProperty("display", "none");
	  }
	};
	const XDownload = {
	  history: [],
	  show_sensitive: true,
	  is_tweetdeck: ScriptConst.currentHost.indexOf("tweetdeck") >= 0,
	  filename: "twitter_{user-name}(@{user-id})_{date-time}_{status-id}_{file-type}",
	  css: `
    .tmd-down {margin-left: 12px; order: 99;}
    .tmd-down:hover > div > div > div > div {color: rgba(29, 161, 242, 1.0);}
    .tmd-down:hover > div > div > div > div > div {background-color: rgba(29, 161, 242, 0.1);}
    .tmd-down:active > div > div > div > div > div {background-color: rgba(29, 161, 242, 0.2);}
    .tmd-down:hover svg {color: rgba(29, 161, 242, 1.0);}
    .tmd-down:hover div:first-child:not(:last-child) {background-color: rgba(29, 161, 242, 0.1);}
    .tmd-down:active div:first-child:not(:last-child) {background-color: rgba(29, 161, 242, 0.2);}
    .tmd-down.tmd-media {position: absolute; right: 0;}
    .tmd-down.tmd-media > div {display: flex; border-radius: 99px; margin: 2px;}
    .tmd-down.tmd-media > div > div {display: flex; margin: 6px; color: #fff;}
    .tmd-down.tmd-media:hover > div {background-color: rgba(255,255,255, 0.6);}
    .tmd-down.tmd-media:hover > div > div {color: rgba(29, 161, 242, 1.0);}
    .tmd-down.tmd-media:not(:hover) > div > div {filter: drop-shadow(0 0 1px #000);}
    .tmd-down g {display: none;}
    .tmd-down.download g.download, .tmd-down.completed g.completed, .tmd-down.loading g.loading,.tmd-down.failed g.failed {display: unset;}
    .tmd-down.loading svg {animation: spin 1s linear infinite;}
    @keyframes spin {0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);}}
    .tmd-btn {display: inline-block; background-color: #1DA1F2; color: #FFFFFF; padding: 0 20px; border-radius: 99px;}
    .tmd-tag {display: inline-block; background-color: #FFFFFF; color: #1DA1F2; padding: 0 10px; border-radius: 10px; border: 1px solid #1DA1F2;  font-weight: bold; margin: 5px;}
    .tmd-btn:hover {background-color: rgba(29, 161, 242, 0.9);}
    .tmd-tag:hover {background-color: rgba(29, 161, 242, 0.1);}
    .tmd-notifier {display: none; position: fixed; left: 16px; bottom: 16px; color: #000; background: #fff; border: 1px solid #ccc; border-radius: 8px; padding: 4px;}
    .tmd-notifier.running {display: flex; align-items: center;}
    .tmd-notifier label {display: inline-flex; align-items: center; margin: 0 8px;}
    .tmd-notifier label:before {content: " "; width: 32px; height: 16px; background-position: center; background-repeat: no-repeat;}
    .tmd-notifier label:nth-child(1):before {background-image:url("data:image/svg+xml;charset=utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2216%22 height=%2216%22 viewBox=%220 0 24 24%22><path d=%22M3,14 v5 q0,2 2,2 h14 q2,0 2,-2 v-5 M7,10 l4,4 q1,1 2,0 l4,-4 M12,3 v11%22 fill=%22none%22 stroke=%22%23666%22 stroke-width=%222%22 stroke-linecap=%22round%22 /></svg>");}
    .tmd-notifier label:nth-child(2):before {background-image:url("data:image/svg+xml;charset=utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2216%22 height=%2216%22 viewBox=%220 0 24 24%22><path d=%22M12,2 a1,1 0 0 1 0,20 a1,1 0 0 1 0,-20 M12,5 v7 h6%22 fill=%22none%22 stroke=%22%23999%22 stroke-width=%222%22 stroke-linejoin=%22round%22 stroke-linecap=%22round%22 /></svg>");}
    .tmd-notifier label:nth-child(3):before {background-image:url("data:image/svg+xml;charset=utf8,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2216%22 height=%2216%22 viewBox=%220 0 24 24%22><path d=%22M12,0 a2,2 0 0 0 0,24 a2,2 0 0 0 0,-24%22 fill=%22%23f66%22 stroke=%22none%22 /><path d=%22M14.5,5 a1,1 0 0 0 -5,0 l0.5,9 a1,1 0 0 0 4,0 z M12,17 a2,2 0 0 0 0,5 a2,2 0 0 0 0,-5%22 fill=%22%23fff%22 stroke=%22none%22 /></svg>");}
    .tmd-down.tmd-img {position: absolute; right: 0; bottom: 0; display: none !important;}
    .tmd-down.tmd-img > div {display: flex; border-radius: 99px; margin: 2px; background-color: rgba(255,255,255, 0.6);}
    .tmd-down.tmd-img > div > div {display: flex; margin: 6px; color: #fff !important;}
    .tmd-down.tmd-img:not(:hover) > div > div {filter: drop-shadow(0 0 1px #000);}
    .tmd-down.tmd-img:hover > div > div {color: rgba(29, 161, 242, 1.0);}
    :hover > .tmd-down.tmd-img, .tmd-img.loading, .tmd-img.completed, .tmd-img.failed {display: block !important;}
    .tweet-detail-action-item {width: 20% !important;}
    `,
	  css_ss: `
    /* show sensitive in media tab */
    li[role="listitem"]>div>div>div>div:not(:last-child) {filter: none;}
    li[role="listitem"]>div>div>div>div+div:last-child {display: none;}
    `,
	  svg: `
    <g class="download"><path d="M3,14 v5 q0,2 2,2 h14 q2,0 2,-2 v-5 M7,10 l4,4 q1,1 2,0 l4,-4 M12,3 v11" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" /></g>
    <g class="completed"><path d="M3,14 v5 q0,2 2,2 h14 q2,0 2,-2 v-5 M7,10 l3,4 q1,1 2,0 l8,-11" fill="none" stroke="#1DA1F2" stroke-width="2" stroke-linecap="round" /></g>
    <g class="loading"><circle cx="12" cy="12" r="10" fill="none" stroke="#1DA1F2" stroke-width="4" opacity="0.4" /><path d="M12,2 a10,10 0 0 1 10,10" fill="none" stroke="#1DA1F2" stroke-width="4" stroke-linecap="round" /></g>
    <g class="failed"><circle cx="12" cy="12" r="11" fill="#f33" stroke="currentColor" stroke-width="2" opacity="0.8" /><path d="M14,5 a1,1 0 0 0 -4,0 l0.5,9.5 a1.5,1.5 0 0 0 3,0 z M12,17 a2,2 0 0 0 0,4 a2,2 0 0 0 0,-4" fill="#fff" stroke="none" /></g>
    `,
	  getCookie: function() {
	    const cookieString = document.cookie;
	    const cookiePairs = cookieString.split(";");
	    const cookiesObject = {};
	    for (const pair of cookiePairs) {
	      const [key, value] = pair.split("=");
	      cookiesObject[key.trim()] = value.trim();
	    }
	    return cookiesObject;
	  },
	  formatDate: function(i, o, tz) {
	    let d = new Date(i);
	    if (tz) {
	      d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
	    }
	    let m = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
	    let v = {
	      YYYY: d.getUTCFullYear().toString(),
	      YY: d.getUTCFullYear().toString(),
	      MM: d.getUTCMonth() + 1,
	      MMM: m[d.getUTCMonth()],
	      DD: d.getUTCDate(),
	      hh: d.getUTCHours(),
	      mm: d.getUTCMinutes(),
	      ss: d.getUTCSeconds(),
	      h2: d.getUTCHours() % 12,
	      ap: d.getUTCHours() < 12 ? "AM" : "PM"
	    };
	    return o.replace(/(YY(YY)?|MMM?|DD|hh|mm|ss|h2|ap)/g, (n) => ("0" + v[n]).substr(-n.length));
	  },
	  detect: function(node) {
	    let article = node.tagName == "ARTICLE" && node || node.tagName == "DIV" && (node.querySelector("article") || node.closest("article"));
	    if (article) {
	      this.addButtonTo(article);
	    }
	    let listitems = node.tagName == "LI" && node.getAttribute("role") == "listitem" && [node] || node.tagName == "DIV" && node.querySelectorAll('li[role="listitem"]');
	    if (listitems) {
	      this.addButtonToMedia(listitems);
	    }
	  },
	  addButtonTo: function(article) {
	    if (article.dataset.detected) {
	      return;
	    }
	    article.dataset.detected = "true";
	    const media_selector = [
	      'a[href*="/photo/1"]',
	      'div[role="progressbar"]',
	      'button[data-testid="playButton"]',
	      'a[href="/settings/content_you_see"]',
	      "div.media-image-container",
	      "div.media-preview-container",
	      'div[aria-labelledby]>div:first-child>div[role="button"][tabindex="0"]'
	    ];
	    const media = article.querySelector(media_selector.join(","));
	    if (media) {
	      let status_id = article.querySelector('a[href*="/status/"]').href.split("/status/").pop().split("/").shift();
	      let btn_group = article.querySelector('div[role="group"]:last-of-type, ul.tweet-actions, ul.tweet-detail-actions');
	      let btn_share = Array.from(btn_group.querySelectorAll(":scope>div>div, li.tweet-action-item>a, li.tweet-detail-action-item>a")).pop().parentNode;
	      let btn_down = btn_share.cloneNode(true);
	      btn_down.querySelector("button").removeAttribute("disabled");
	      if (this.is_tweetdeck) {
	        btn_down.firstElementChild.innerHTML = '<svg viewBox="0 0 24 24" style="width: 18px; height: 18px;">' + this.svg + "</svg>";
	        btn_down.firstElementChild.removeAttribute("rel");
	        btn_down.classList.replace("pull-left", "pull-right");
	      } else {
	        btn_down.querySelector("svg").innerHTML = this.svg;
	      }
	      let is_exist = this.history.indexOf(status_id) >= 0;
	      this.status(btn_down, "tmd-down");
	      this.status(btn_down, is_exist ? "completed" : "download", is_exist ? selectLanguage().download.completed : selectLanguage().download.download);
	      btn_group.insertBefore(btn_down, btn_share.nextSibling);
	      btn_down.onclick = () => {
	        this.click(btn_down, status_id, is_exist);
	      };
	      if (this.show_sensitive) {
	        let btn_show = article.querySelector('div[aria-labelledby] div[role="button"][tabindex="0"]:not([data-testid]) > div[dir] > span > span');
	        if (btn_show) {
	          btn_show.click();
	        }
	      }
	    }
	    const imgs = article.querySelectorAll('a[href*="/photo/"]');
	    if (imgs.length > 1) {
	      let status_id = article.querySelector('a[href*="/status/"]').href.split("/status/").pop().split("/").shift();
	      let btn_group = article.querySelector('div[role="group"]:last-of-type');
	      Array.from(btn_group.querySelectorAll(":scope>div>div")).pop().parentNode;
	      imgs.forEach((img) => {
	        let index = img.href.split("/status/").pop().split("/").pop();
	        let is_exist = this.history.indexOf(status_id) >= 0;
	        let btn_down = document.createElement("div");
	        btn_down.innerHTML = '<div><div><svg viewBox="0 0 24 24" style="width: 18px; height: 18px;">' + this.svg + "</svg></div></div>";
	        btn_down.classList.add("tmd-down", "tmd-img");
	        this.status(btn_down, "download");
	        img.parentNode.appendChild(btn_down);
	        btn_down.onclick = (e) => {
	          e.preventDefault();
	          this.click(btn_down, status_id, is_exist, index);
	        };
	      });
	    }
	  },
	  addButtonToMedia: function(listitems) {
	    listitems.forEach((li) => {
	      if (li.dataset.detected)
	        return;
	      li.dataset.detected = "true";
	      let status_id = li.querySelector('a[href*="/status/"]').href.split("/status/").pop().split("/").shift();
	      let is_exist = this.history.indexOf(status_id) >= 0;
	      let btn_down = document.createElement("div");
	      btn_down.innerHTML = '<div><div><svg viewBox="0 0 24 24" style="width: 18px; height: 18px;">' + this.svg + "</svg></div></div>";
	      btn_down.classList.add("tmd-down", "tmd-media");
	      this.status(btn_down, is_exist ? "completed" : "download", is_exist ? selectLanguage().download.completed : selectLanguage().download.download);
	      li.appendChild(btn_down);
	      btn_down.onclick = () => {
	        this.click(btn_down, status_id, is_exist);
	      };
	    });
	  },
	  status: function(btn, css, title, style) {
	    if (css) {
	      btn.classList.remove("download", "completed", "loading", "failed");
	      btn.classList.add(css);
	    }
	    if (title)
	      btn.title = title;
	    if (style)
	      btn.style.cssText = style;
	  },
	  fetchJson: function(status_id) {
	    return __async$6(this, null, function* () {
	      const base_url = `https://${ScriptConst.currentHost}/i/api/graphql/NmCeCgkVlsRGS1cAwqtgmw/TweetDetail`;
	      const variables = {
	        "focalTweetId": status_id,
	        "with_rux_injections": false,
	        "includePromotedContent": true,
	        "withCommunity": true,
	        "withQuickPromoteEligibilityTweetFields": true,
	        "withBirdwatchNotes": true,
	        "withVoice": true,
	        "withV2Timeline": true
	      };
	      const features = {
	        "rweb_lists_timeline_redesign_enabled": true,
	        "responsive_web_graphql_exclude_directive_enabled": true,
	        "verified_phone_label_enabled": false,
	        "creator_subscriptions_tweet_preview_api_enabled": true,
	        "responsive_web_graphql_timeline_navigation_enabled": true,
	        "responsive_web_graphql_skip_user_profile_image_extensions_enabled": false,
	        "tweetypie_unmention_optimization_enabled": true,
	        "responsive_web_edit_tweet_api_enabled": true,
	        "graphql_is_translatable_rweb_tweet_is_translatable_enabled": true,
	        "view_counts_everywhere_api_enabled": true,
	        "longform_notetweets_consumption_enabled": true,
	        "responsive_web_twitter_article_tweet_consumption_enabled": false,
	        "tweet_awards_web_tipping_enabled": false,
	        "freedom_of_speech_not_reach_fetch_enabled": true,
	        "standardized_nudges_misinfo": true,
	        "tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled": true,
	        "longform_notetweets_rich_text_read_enabled": true,
	        "longform_notetweets_inline_media_enabled": true,
	        "responsive_web_media_download_video_enabled": false,
	        "responsive_web_enhance_cards_enabled": false
	      };
	      const url = encodeURI(`${base_url}?variables=${JSON.stringify(variables)}&features=${JSON.stringify(features)}`);
	      const cookies = this.getCookie();
	      const headers = {
	        "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
	        "x-twitter-active-user": "yes",
	        "x-twitter-client-language": cookies.lang,
	        "x-csrf-token": cookies.ct0
	      };
	      if (cookies.ct0.length == 32)
	        headers["x-guest-token"] = cookies.gt;
	      let tweet_detail = yield fetch(url, { headers }).then((result) => result.json());
	      let tweet_entrie = tweet_detail.data.threaded_conversation_with_injections_v2.instructions[0].entries.find((n) => n.entryId == `tweet-${status_id}`);
	      let tweet_result = tweet_entrie.content.itemContent.tweet_results.result;
	      return tweet_result.tweet || tweet_result;
	    });
	  },
	  click: function(btn, status_id, is_exist, index) {
	    return __async$6(this, null, function* () {
	      if (btn.classList.contains("loading"))
	        return;
	      this.status(btn, "loading");
	      let save_history = yield GM_getValue("save_history", true);
	      let json = yield this.fetchJson(status_id);
	      let tweet = json.legacy;
	      let user = json.core.user_results.result.legacy;
	      let invalid_chars = {
	        "\\": "\",
	        "/": "/",
	        "|": "|",
	        "<": "<",
	        ">": ">",
	        ":": ":",
	        "*": "*",
	        "?": "?",
	        '"': """,
	        "​": "",
	        "‌": "",
	        "‍": "",
	        "⁠": "",
	        "\uFEFF": "",
	        "🔞": ""
	      };
	      let datetime = this.filename.match(/{date-time(-local)?:[^{}]+}/) ? this.filename.match(/{date-time(?:-local)?:([^{}]+)}/)[1].replace(/[\\/ | <>*?:"]/g, (v) => invalid_chars[v]) : "YYYYMMDD-hhmmss";
	      let info = {};
	      info["status-id"] = status_id;
	      info["user-name"] = user.name.replace(/([\\/|*?:"] | [\u200b - \u200d\u2060\ufeff] | 🔞) /g, (v) => invalid_chars[v]);
	      info["user-id"] = user.screen_name;
	      info["date-time"] = this.formatDate(tweet.created_at, datetime);
	      info["date-time-local"] = this.formatDate(tweet.created_at, datetime, true);
	      info["full-text"] = tweet.full_text.split("\n").join(" ").replace(/\s*https:\/\/t\.co\/\w+/g, "").replace(/[\\/ | <>*?:"]|[\u200b-\u200d\u2060\ufeff]/g, (v) => invalid_chars[v]);
	      let medias = tweet.extended_entities && tweet.extended_entities.media;
	      if (medias == void 0) {
	        medias = JSON.parse(json.card.legacy.binding_values[0].value.string_value).media_entities;
	        medias = Object.values(medias);
	      }
	      if (index) {
	        medias = [medias[index - 1]];
	      }
	      if (medias.length > 0) {
	        let tasks = medias.length;
	        let tasks_result = [];
	        medias.forEach((media, i) => {
	          info.url = media.type == "photo" ? media.media_url_https + ":orig" : media.video_info.variants.filter((n) => n.content_type == "video/mp4").sort((a, b) => b.bitrate - a.bitrate)[0].url;
	          info.file = info.url.split("/").pop().split(/[:?]/).shift();
	          info["file-name"] = info.file.split(".").shift();
	          info["file-ext"] = info.file.split(".").pop();
	          info["file-type"] = media.type.replace("animated_", "");
	          info.out = (this.filename.replace(/\.?{file-ext}/, "") + ((medias.length > 1 || index) && !this.filename.match("{file-name}") ? "-" + (index ? index - 1 : i) : "") + ".{file-ext}").replace(/{([^{}:]+)(:[^{}]+)?}/g, (match, name) => info[name]);
	          this.downloader.add({
	            url: info.url,
	            name: info.out,
	            onload: () => {
	              tasks -= 1;
	              tasks_result.push((medias.length > 1 || index ? (index ? index : i + 1) + ": " : "") + selectLanguage().download.completed);
	              this.status(btn, null, tasks_result.sort().join("\n"));
	              if (tasks === 0) {
	                this.status(btn, "completed", selectLanguage().download.completed);
	                if (save_history && !is_exist) {
	                  this.history.push(status_id);
	                }
	              }
	            },
	            onerror: (result) => {
	              tasks = -1;
	              tasks_result.push((medias.length > 1 ? i + 1 + ": " : "") + result.details.current);
	              this.status(btn, "failed", tasks_result.sort().join("\n"));
	            }
	          });
	        });
	      } else {
	        this.status(btn, "failed", "MEDIA_NOT_FOUND");
	      }
	    });
	  },
	  downloader: function() {
	    let tasks = [], thread = 0, max_thread = 2, retry = 0, max_retry = 2, failed = 0, notifier, has_failed = false;
	    return {
	      add: function(task) {
	        tasks.push(task);
	        if (thread < max_thread) {
	          thread += 1;
	          this.next();
	        } else {
	          this.update();
	        }
	      },
	      next: function() {
	        return __async$6(this, null, function* () {
	          let task = tasks.shift();
	          yield this.start(task);
	          if (tasks.length > 0 && thread <= max_thread) {
	            this.next();
	          } else {
	            thread -= 1;
	          }
	          this.update();
	        });
	      },
	      start: function(task) {
	        this.update();
	        return new Promise((resolve) => {
	          GM_download({
	            url: task.url,
	            name: task.name,
	            onload: (result) => {
	              task.onload();
	              resolve();
	            },
	            onerror: (result) => {
	              this.retry(task, result);
	              resolve();
	            },
	            ontimeout: (result) => {
	              this.retry(task, result);
	              resolve();
	            }
	          });
	        });
	      },
	      retry: function(task, result) {
	        retry += 1;
	        if (retry == 3)
	          max_thread = 1;
	        if (task.retry && task.retry >= max_retry || result.details && result.details.current == "USER_CANCELED") {
	          task.onerror(result);
	          failed += 1;
	        } else {
	          if (max_thread == 1)
	            task.retry = (task.retry || 0) + 1;
	          this.add(task);
	        }
	      },
	      update: function() {
	        if (!notifier) {
	          notifier = document.createElement("div");
	          notifier.title = "Twitter Media Downloader";
	          notifier.classList.add("tmd-notifier");
	          notifier.innerHTML = "<label>0</label>|<label>0</label>";
	          document.body.appendChild(notifier);
	        }
	        if (failed > 0 && !has_failed) {
	          has_failed = true;
	          notifier.innerHTML += "|";
	          let clear = document.createElement("label");
	          notifier.appendChild(clear);
	          clear.onclick = () => {
	            notifier.innerHTML = "<label>0</label>|<label>0</label>";
	            failed = 0;
	            has_failed = false;
	            this.update();
	          };
	        }
	        notifier.firstChild.innerText = thread;
	        notifier.firstChild.nextElementSibling.innerText = tasks.length;
	        if (failed > 0) {
	          notifier.lastChild.innerText = failed;
	        }
	        if (thread > 0 || tasks.length > 0 || failed > 0) {
	          notifier.classList.add("running");
	        } else {
	          notifier.classList.remove("running");
	        }
	      }
	    };
	  }(),
	  init: function() {
	    document.head.insertAdjacentHTML("beforeend", "<style>" + this.css + (this.show_sensitive ? this.css_ss : "") + "</style>");
	  }
	};
	const X = {
	  XSettingsDialog,
	  XDateFormat,
	  XOrigimg,
	  XHidepromo,
	  XDownload
	};

	var __async$5 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const Tiktok = {
	  extractHref: function(html) {
	    const regex = /<a\s+(?:[^>]*?\s+)?href=(['"])(.*?)\1/gi;
	    const hrefs = [];
	    let match;
	    while ((match = regex.exec(html)) !== null) {
	      hrefs.push(match[2]);
	    }
	    return hrefs.filter((href) => href.indexOf("snapcdn.app") != -1);
	  },
	  download: function(url, element) {
	    return __async$5(this, null, function* () {
	      Toast.show({ "message": selectLanguage().download.preparing, "background": "#000" });
	      element.classList.add("download-loadding");
	      const data = yield Tools.request(
	        "POST",
	        "https://tikdownloader.io/api/ajaxSearch",
	        "q=" + url + "&lang=en",
	        { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" }
	      );
	      if (data.code === "success") {
	        const result = JSON.parse(data.result);
	        if (result.status == "ok" && result.hasOwnProperty("data")) {
	          const data2 = result.data;
	          const downloadUrls = this.extractHref(data2);
	          if (downloadUrls.length >= 2) {
	            Tools.openInTab(downloadUrls.at(-2));
	          }
	        }
	      }
	      element.classList.remove("download-loadding");
	    });
	  },
	  start: function() {
	    return __async$5(this, null, function* () {
	      if (!/www\.tiktok\.com/.test(window.location.host)) {
	        return;
	      }
	      GM_addStyle(`
      @keyframes scriptspin {0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);}}
      .download-loadding{
        animation: scriptspin 1s linear infinite;
      }
    `);
	      setInterval(() => {
	        if (!document.querySelector("#tiktok-download-990i")) {
	          const container = document.querySelector("#main-content-video_detail") || document.body;
	          if (!container) {
	            return;
	          }
	          const divs = container.querySelectorAll("div");
	          const regex = /-DivRightControlsWrapper|-DivMiniPlayerContainer/;
	          const matchedDiv = Array.from(divs).find((div) => {
	            return div.classList.value.split(" ").some((className) => {
	              return regex.test(className);
	            });
	          });
	          if (matchedDiv) {
	            let cloneNode = null;
	            let isDetail = matchedDiv.children.length != 1;
	            if (isDetail) {
	              cloneNode = matchedDiv.children[0].cloneNode(true);
	            } else {
	              cloneNode = matchedDiv.cloneNode(true);
	            }
	            cloneNode.id = "tiktok-download-990i";
	            cloneNode.querySelector("div").innerHTML = `<svg t="1724300009050" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5307" width="35" height="35"><path d="M298.666667 554.666667v85.333333H256v128h512v-128h-42.666667v-85.333333h128v213.333333a85.333333 85.333333 0 0 1-78.933333 85.077333L768 853.333333H256a85.333333 85.333333 0 0 1-85.12-78.933333L170.666667 768v-213.333333h128z" fill="#ffffff" p-id="5308"></path><path d="M512 627.498667l219.477333-219.477334h-120.704L512 506.88 413.141333 408.021333H292.522667L512 627.498667z" fill="#ffffff" p-id="5309"></path><path d="M554.666667 528V167.978667h-85.333334v360.021333h85.333334z" fill="#ffffff" p-id="5310"></path></svg>`;
	            if (isDetail) {
	              matchedDiv.insertBefore(cloneNode, matchedDiv.children[0]);
	            } else {
	              cloneNode.style.right = 166 + "px";
	              matchedDiv.parentNode.insertBefore(cloneNode, matchedDiv);
	            }
	            cloneNode.title = selectLanguage().download.tip;
	            cloneNode.addEventListener("click", () => {
	              Tiktok.download(window.location.href, cloneNode);
	            });
	          }
	        }
	      }, 1500);
	    });
	  }
	};

	const dialog = function() {
	  class Dialog {
	    constructor() {
	      this.mask = document.createElement("div");
	      this.dialogStyle = document.createElement("style");
	      this.setStyle(this.mask, {
	        "width": "100%",
	        "height": "100%",
	        "backgroundColor": "rgba(0, 0, 0, .6)",
	        "position": "fixed",
	        "left": "0px",
	        "top": "0px",
	        "bottom": "0px",
	        "right": "0px",
	        "z-index": "9999999999999"
	      });
	      this.content = document.createElement("div");
	      this.setStyle(this.content, {
	        "max-width": "450px",
	        "width": "100%",
	        "max-height": "600px",
	        "backgroundColor": "#fff",
	        "boxShadow": "0 0 2px #999",
	        "position": "absolute",
	        "left": "50%",
	        "top": "50%",
	        "transform": "translate(-50%,-50%)",
	        "borderRadius": "5px"
	      });
	      this.mask.appendChild(this.content);
	    }
	    middleBox(param) {
	      this.content.innerHTML = "";
	      let title = "默认标题内容";
	      if ({}.toString.call(param) === "[object String]") {
	        title = param;
	      } else if ({}.toString.call(param) === "[object Object]") {
	        title = param.title;
	      }
	      document.body.appendChild(this.mask);
	      this.title = document.createElement("div");
	      this.setStyle(this.title, {
	        "width": "100%",
	        "height": "40px",
	        "lineHeight": "40px",
	        "boxSizing": "border-box",
	        "background-color": "#dedede",
	        "color": "#000",
	        "text-align": "center",
	        "font-weight": "700",
	        "font-size": "17px",
	        "border-radius": "4px 4px 0px 0px"
	      });
	      this.title.innerText = title;
	      this.content.appendChild(this.title);
	      this.closeBtn = document.createElement("div");
	      this.closeBtn.innerText = "×";
	      this.setStyle(this.closeBtn, {
	        "textDecoration": "none",
	        "color": "#000",
	        "position": "absolute",
	        "right": "10px",
	        "top": "0px",
	        "fontSize": "25px",
	        "display": "inline-block",
	        "cursor": "pointer"
	      });
	      this.title.appendChild(this.closeBtn);
	      this.closeBtn.onclick = () => this.close();
	    }
	    showMake(param) {
	      if (param.hasOwnProperty("styleSheet")) {
	        this.dialogStyle.textContent = param.styleSheet;
	      }
	      document.querySelector("head").appendChild(this.dialogStyle);
	      this.middleBox(param);
	      this.dialogContent = document.createElement("div");
	      this.setStyle(this.dialogContent, {
	        "padding": "15px",
	        "max-height": "400px"
	      });
	      this.dialogContent.innerHTML = param.content;
	      this.content.appendChild(this.dialogContent);
	      param.onContentReady(this);
	    }
	    close() {
	      document.body.removeChild(this.mask);
	      document.querySelector("head").removeChild(this.dialogStyle);
	    }
	    setStyle(ele, styleObj) {
	      for (let attr in styleObj) {
	        ele.style[attr] = styleObj[attr];
	      }
	    }
	  }
	  let dialog2 = null;
	  return function() {
	    if (!dialog2) {
	      dialog2 = new Dialog();
	    }
	    return dialog2;
	  }();
	}();

	const GoodsHistroy = {
	  storageKeys: {
	    goodsHistory: "goooods_history_key",
	    offset: "goooods_wrapper_key",
	    maximumRecordsKey: "goooods_max_records_key"
	  },
	  defaultValue: {
	    historyStorage: { "aliexpress": [], "amazon": [], "shein": [], "shopee": [], "lazada": [], "ebay": [] },
	    offsetWrapper: { right: 10, bottom: 0 },
	    records: { min: 10, max: 500, default: 100 },
	    toolbarGoodsNum: 4
	  },
	  push: function(platform, obj) {
	    var _a;
	    try {
	      const storageObj = GM_getValue(this.storageKeys.goodsHistory, this.defaultValue.historyStorage);
	      const maximumRecords = GM_getValue(this.storageKeys.maximumRecordsKey, this.defaultValue.records.default);
	      const histories = (_a = storageObj[platform]) != null ? _a : [];
	      if (histories.length >= maximumRecords) {
	        histories.splice(0, parseInt(maximumRecords / 5));
	      }
	      const newArr = histories.filter((item, index) => item.id != obj.id);
	      newArr.push(obj);
	      storageObj[platform] = newArr;
	      GM_setValue(this.storageKeys.goodsHistory, storageObj);
	    } catch (e) {
	    }
	  },
	  get: function(platform, num = -1) {
	    const storageObj = GM_getValue(this.storageKeys.goodsHistory, this.defaultValue.historyStorage);
	    const histories = storageObj[platform];
	    if (num > 0) {
	      const showHistories = [];
	      for (let i = histories.length - 1; i >= 0; i--) {
	        if (showHistories.length >= num)
	          break;
	        showHistories.push(histories[i]);
	      }
	      return showHistories;
	    }
	    return histories;
	  },
	  remove: function(platform, id) {
	    const storageObj = GM_getValue(this.storageKeys.goodsHistory, this.defaultValue.historyStorage);
	    const histories = storageObj[platform];
	    let newArr = histories.filter((item, index) => item.id != id);
	    storageObj[platform] = newArr;
	    GM_setValue(this.storageKeys.goodsHistory, storageObj);
	  },
	  removeAll: function() {
	    GM_setValue(this.storageKeys.goodsHistory, this.defaultValue.historyStorage);
	    document.querySelector(".peter99032j-xyz-panel-aside-body .goods_____review").innerHTML = "";
	    document.querySelector(".peter99032j-xyz-panel-aside-main .panel-aside-main_____content").innerHTML = "";
	  },
	  removeAllConfirm: function() {
	    if (confirm(selectLanguage().ecommerce.dialog.clearConfirmContent)) {
	      this.removeAll();
	    }
	  },
	  registerMenuCommand: function() {
	    GM_registerMenuCommand(selectLanguage().menuCommand.settings, () => {
	      this.showSettingDialog();
	    });
	  },
	  getGoodsByDateGroup: function(platform) {
	    const histories = this.get(platform).reverse();
	    const group = [];
	    const today = new Date();
	    const yesterday = new Date(today);
	    const format = "dd/MM";
	    yesterday.setDate(today.getDate() - 1);
	    const todayStr = this.dateFormat(today, format);
	    const yesterdayStr = this.dateFormat(yesterday, format);
	    const showDateFormat = (todayStr2, yesterdayStr2, current) => {
	      return current === todayStr2 ? "Today" : current === yesterdayStr2 ? "Yesterday" : current;
	    };
	    let items = [], cacheDateStr = null, currentDateStr = null;
	    for (let i = 0; i < histories.length; i++) {
	      today.setTime(histories[i].date);
	      currentDateStr = this.dateFormat(today, format);
	      if (!!cacheDateStr) {
	        if (cacheDateStr != currentDateStr) {
	          group.push({
	            "str": showDateFormat(todayStr, yesterdayStr, cacheDateStr),
	            "items": items
	          });
	          items = [];
	          cacheDateStr = currentDateStr;
	        }
	      } else {
	        cacheDateStr = currentDateStr;
	      }
	      items.push(histories[i]);
	    }
	    if (items.length != 0) {
	      group.push({
	        "str": showDateFormat(todayStr, yesterdayStr, cacheDateStr),
	        "items": items
	      });
	    }
	    return group;
	  },
	  dateFormat: function(date, format) {
	    var showDate = {
	      "M+": date.getMonth() + 1,
	      "d+": date.getDate(),
	      "h+": date.getHours(),
	      "m+": date.getMinutes(),
	      "s+": date.getSeconds(),
	      "q+": Math.floor((date.getMonth() + 3) / 3),
	      "S+": date.getMilliseconds()
	    };
	    if (/(y+)/i.test(format)) {
	      format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
	    }
	    for (var k in showDate) {
	      if (new RegExp("(" + k + ")").test(format)) {
	        format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? showDate[k] : ("00" + showDate[k]).substr(("" + showDate[k]).length));
	      }
	    }
	    return format;
	  },
	  showSettingDialog: function() {
	    const outerId = "dialog_x_" + Tools.randomNumber();
	    const self = this;
	    const { min, max } = this.defaultValue.records;
	    const maximumRecords = GM_getValue(this.storageKeys.maximumRecordsKey, this.defaultValue.records.default);
	    const styleSheet = `
      #` + outerId + `{
        padding:15px;
      }
      #` + outerId + ` .d_____piece{
        margin-bottom:15px;
        font-size:15px;
      }
      #` + outerId + ` .d_____input{
        padding: 5px 10px !important;
        background-color: #fafafa !important;
        color: #000 !important;
        border: 1px solid #ccc !important;
        font-size: 14px !important;
        border-radius: 4px !important;
        width: 80px !important;
        text-align: center !important;
      }
      #` + outerId + ` .d_____btn{
        padding: 3px 10px !important;
        background-color: #edf2fa !important;
        color: #000 !important;
        border-radius: 4px!important;
        font-size: 14px!important;
      }
      #` + outerId + ` .d_____btn:hover{
        background-color: #cdd1da !important;
      }
    `;
	    var tips = selectLanguage().ecommerce.dialog.contentPieceMax;
	    tips = tips.replace("{min}", min);
	    tips = tips.replace("{max}", max);
	    const content = `
      <div id="` + outerId + `">
        <div class="d_____piece">
          ` + tips + `<input class="d_____input" number="number" min="` + min + `" max="` + max + `" step="1"  value="` + maximumRecords + `" name="maximum-records"/>
        </div>
        <div class="d_____piece">
          <p>` + selectLanguage().ecommerce.dialog.contentPieceClear + `</p>
          <button class="d_____btn" name="clear">` + selectLanguage().ecommerce.dialog.contentPieceClearBtn + `</button>
        </div>
      </div>
    `;
	    dialog.showMake({
	      title: selectLanguage().ecommerce.dialog.title,
	      content,
	      styleSheet,
	      onContentReady: function($that) {
	        $that.dialogContent.querySelector("button[name='clear']").addEventListener("click", function() {
	          self.removeAllConfirm();
	        });
	        $that.dialogContent.querySelector("input[name='maximum-records']").onchange = function(e) {
	          const value = this.value;
	          if (value >= min && value <= max) {
	            GM_setValue(self.storageKeys.maximumRecordsKey, value);
	          }
	        };
	      }
	    });
	  },
	  showOrHideHistoryBox: function(platform) {
	    const self = this;
	    const group = this.getGoodsByDateGroup(platform);
	    const contentElement = document.querySelector(".peter99032j-xyz-panel-aside-main .panel-aside-main_____content");
	    contentElement.innerHTML = "";
	    let historiesBoxHtml = "", jumpUrl = "", imgUrl = "";
	    for (let i = 0; i < group.length; i++) {
	      historiesBoxHtml += `<div class="panel-aside-main_____item">`;
	      historiesBoxHtml += `<div class="item_____title"> —— ` + group[i].str + ` —— </div>`;
	      historiesBoxHtml += `<div class="item_____container">`;
	      for (let j = 0; j < group[i].items.length; j++) {
	        jumpUrl = Tools.encryptStr("https://page.mimixiaoke.com/api/product/redirect?url=" + encodeURIComponent(group[i].items[j].url));
	        if (platform == "aliexpress") {
	          imgUrl = group[i].items[j].pic.split("_")[0];
	        } else {
	          imgUrl = group[i].items[j].pic;
	        }
	        historiesBoxHtml += `
          <div class="histories-box-review_item">
            <a title="` + group[i].items[j].title + `" jump-tag="true" href="javascript:void(0);" jump-url="` + jumpUrl + `" target="_blank">
              <div class="review___shadow">
                <div class="delete_____btn" data-id="` + group[i].items[j].id + `">×</div>
              </div>
              <div class="review___img"><img src="` + imgUrl + `" /></div>
              <div class="review___text">` + group[i].items[j].price + `</div>
            </a>
          </div>
        `;
	      }
	      historiesBoxHtml += `</div>`;
	      historiesBoxHtml += `</div>`;
	    }
	    contentElement.innerHTML = historiesBoxHtml;
	    document.querySelectorAll(".peter99032j-xyz-panel-aside-main .delete_____btn").forEach((ele) => {
	      ele.addEventListener("click", function(e) {
	        e.stopPropagation();
	        e.preventDefault();
	        const id = this.getAttribute("data-id");
	        this.parentNode.parentNode.parentNode.remove();
	        self.remove(platform, id);
	      });
	    });
	    const items = document.querySelectorAll(".peter99032j-xyz-panel-aside-main .histories-box-review_item > a");
	    items.forEach((ele) => {
	      ele.addEventListener("mouseover", function() {
	        this.querySelector(".review___shadow").style.display = "block";
	      });
	      ele.addEventListener("mouseout", function() {
	        this.querySelector(".review___shadow").style.display = "none";
	      });
	    });
	    document.querySelectorAll(".peter99032j-xyz-panel-aside-main a[jump-tag='true']").forEach((ele) => {
	      ele.addEventListener("click", function(e) {
	        e.stopPropagation();
	        e.preventDefault();
	        const href = this.getAttribute("jump-url");
	        Tools.openInTab(Tools.decryptStr(href));
	      });
	    });
	  },
	  createHistoryBox: function(platform) {
	    const wrapperOffset = GM_getValue(this.storageKeys.offset, this.defaultValue.offsetWrapper);
	    let css = `
      .peter99032j-xyz-panel-wrapper{
        position: fixed;
        bottom: ` + wrapperOffset.bottom + `px;
        right: ` + wrapperOffset.right + `px;
        z-index: 999999999;
        box-sizing: border-box;
      }

      .peter99032j-xyz-panel-wrapper svg.icon-svg path{
        fill: #bfbfbf;
      }

      .peter99032j-xyz-panel-wrapper svg.icon-svg:hover path{
        fill: #6a7a9b;
      }

      /*** 历史记录大box ***/
      .peter99032j-xyz-panel-wrapper >.peter99032j-xyz-panel-aside-main{
        width: 400px;
        height: 400px;
        position: absolute;
        right: 0px;
        bottom: 70px;
        border-radius: 5px;
        border: 1px solid #ebebeb;
        background-color: #fafafa;
        overflow-y: auto;
        overflow-x: hidden;
        background-color:#fafafa;
        display:none;
        -moz-box-shadow:2px 2px 5px #b6bdc5;
        -webkit-box-shadow:2px 2px 5px #b6bdc5;
        box-shadow:2px 2px 5px #b6bdc5;
      }
      .peter99032j-xyz-panel-wrapper >.peter99032j-xyz-panel-aside-main >.panel-aside-main_____inner{
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
      }

      .peter99032j-xyz-panel-aside-main .panel-aside-main_____header{
        display: flex;
        align-items: center;
        flex-direction: row;
        height:40px;
        background: #dedede;
      }
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____header >.header_____title{
        align-items: center;
        display: flex;
        flex: 1;
        margin-left: 15px;
        font-size: 15px;
        font-weight: bold;
      }
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____header >.header_____title >svg{
        margin-right:5px;
      }
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____header >.header_____close,
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____header >.header_____setting{
        display: flex;
        justify-content: center;
        align-items: center;
        cursor:pointer;
        width:35px;
      }

      .peter99032j-xyz-panel-aside-main .panel-aside-main_____content{
        flex: 1;
        overflow: auto;
      }

      .peter99032j-xyz-panel-aside-main .panel-aside-main_____item{
        padding: 5px;
        margin:5px 0px;
      }
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____item .item_____title{
        font-size: 13px;
        font-weight: 500;
        text-align: center;
        color: #b6b6b6;
        padding: 5px 0px;
      }
      .peter99032j-xyz-panel-aside-main .panel-aside-main_____item .item_____container{
        display: flex;
        flex-flow: wrap;
        flex-direction: row;
        justify-content: flex-start;
      }

      /**** 历史记录展示 ****/
      .peter99032j-xyz-panel-aside-main .histories-box-review_item{
        width:33.3333%;
        margin: 5px 0px;
        overflow: hidden;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item >a{
        display: block !important;
        position: relative !important;
        margin: 0px auto !important;
        background-color: #fff !important;
        width: 110px !important;
        border-radius: 5px !important;
        border: 1px solid #ccc !important;
        box-sizing: content-box !important;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item > a >.review___shadow{
        position:absolute;
        left:0px;
        right:0px;
        top:0px;
        bottom:0px;
        z-index:99;
        text-align: center;
        border:2px solid red;
        border-radius: 5px;
        display:none;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item > a >.review___shadow .delete_____btn{
        position: absolute;
        top: 0px;
        right: 0px;
        width: 15px;
        height: 15px;
        text-align: center;
        line-height: 10px;
        background-color:red;
        color:#FFF;
        font-size:13px;
        border-radius:3px;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item > a >.review___img{
        width:110px;
        height: 110px;
        border-radius: 5px 5px 0px 0px;
        overflow: hidden;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item > a >.review___img >img{
        width:100%;
      }
      .peter99032j-xyz-panel-aside-main .histories-box-review_item > a >.review___text{
        text-align: center!important;
        font-size: 13px !important;
        color: #000 !important;
        text-decoration: underline !important;
        padding: 5px!important;
        white-space: nowrap!important;
        overflow: hidden!important;
        text-overflow: ellipsis!important;
      }

      /*** 横向小卡片 ***/
      .peter99032j-xyz-panel-wrapper >.peter99032j-xyz-panel-aside-body{
        display: flex;
        border-radius:5px;
        overflow: hidden;
        background-color: #fafafa;
        -moz-box-shadow:2px 2px 5px #b6bdc5;
        -webkit-box-shadow:2px 2px 5px #b6bdc5;
        box-shadow:2px 2px 5px #b6bdc5;
        height:60px;
      }
      .peter99032j-xyz-panel-wrapper >.peter99032j-xyz-panel-aside-body >div{
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .peter99032j-xyz-panel-aside-body .goods_____expand{
        cursor: pointer;
        width: 20px !important;
      }

      .peter99032j-xyz-panel-aside-body .goods_____expand svg{
        transition: transform 0.3s;
      }

      /**** goods展示 ****/
      .peter99032j-xyz-panel-aside-body .goods_____review{
        flex-direction: row;
        width:auto;
        transition: all 0.5s ease-in-out;
      }
      .peter99032j-xyz-panel-aside-body .goods-review_____item{
        width:45px;
        height:45px;
        line-height:45px;
        margin:0px 5px;
        position:relative;
        border-radius: 4px;
        overflow: hidden;
        cursor:pointer;
      }
      .peter99032j-xyz-panel-aside-body .goods-review_____item >a{
        display:block;
        width: 100%;
        height: 100%;
      }
      .peter99032j-xyz-panel-aside-body .goods-review_____item > a>.review___shadow{
        position:absolute;
        left:0px;
        right:0px;
        top:0px;
        bottom:0px;
        z-index:99;
        text-align: center;
        background-color:rgb(61 155 164 / 20%);
        display:none;
      }
      .peter99032j-xyz-panel-aside-body .goods-review_____item > a>.review___shadow img{
        width:15px;
      }
      .peter99032j-xyz-panel-aside-body .goods-review_____item img{
        width:100%;
      }

      /** 展开历史记录BOX **/
      .peter99032j-xyz-panel-aside-body .history-box_____expand{
        flex-direction: column;
        text-align: center;
        margin:0px 10px;
        cursor: pointer;
      }
      .peter99032j-xyz-panel-aside-body .history-box_____expand img{
        width:26px;
      }
      .peter99032j-xyz-panel-aside-body .history-box_____expand label{
        font-size:12px;
        font-weight: bold;
      }

      .peter99032j-xyz-panel-aside-body .wrapper_____drag-handle{
        width: 20px !important;
        cursor: grab;
        box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 3px -2px, rgba(0, 0, 0, 0.14) 0px 3px 4px 0px, rgba(0, 0, 0, 0.12) 0px 1px 8px 0px;
      }
    `;
	    const histories = this.get(platform, this.defaultValue.toolbarGoodsNum);
	    const historySVG = `
      <svg t="1722328287419" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14202" width="25" height="25"><path d="M757.9648 948.1216H271.6672c-107.264 0-194.2016-86.9376-194.2016-194.2016V267.6736c0-107.264 86.9376-194.2016 194.2016-194.2016h486.2464c107.264 0 194.2016 86.9376 194.2016 194.2016v486.2464c0.0512 107.264-86.8864 194.2016-194.1504 194.2016z" fill="#F6CC4F" p-id="14203"></path><path d="M823.3472 441.6512c-38.9632-171.5712-210.2784-279.4496-381.8496-240.5376-47.7696 10.8544-91.4944 32.0512-128.9216 62.1568l0.2048-44.3904a25.61024 25.61024 0 0 0-25.4976-25.7024h-0.1024c-14.08 0-25.5488 11.3664-25.6 25.4976l-0.512 111.8208c-0.0512 6.8096 2.6624 13.312 7.424 18.1248 4.7616 4.8128 11.3152 7.5264 18.0736 7.5776l119.296 0.3584h0.1024c14.08 0 25.5488-11.4176 25.6-25.4976a25.61024 25.61024 0 0 0-25.4976-25.7024l-63.7952-0.2048c31.9488-26.2656 69.5296-44.7488 110.6432-54.0672 144.0256-32.7168 287.8976 57.856 320.6144 201.9328 32.7168 144.0768-57.9072 287.8976-201.9328 320.6144-144.128 32.7168-287.8976-57.9072-320.6144-201.9328-4.9152-21.6576-7.168-43.8272-6.656-65.8432a25.6512 25.6512 0 0 0-24.9856-26.2144 25.61536 25.61536 0 0 0-26.2144 24.9856c-0.6144 26.2144 2.048 52.5824 7.8848 78.3872 33.5872 147.9168 165.4784 248.5248 311.1424 248.5248 23.3472 0 47.0016-2.56 70.7072-7.936 171.52-39.0656 279.4496-210.3296 240.4864-381.952z" fill="#F7F8F8" p-id="14204"></path><path d="M512.1536 382.3104c-14.1312 0-25.6 11.4688-25.6 25.6v106.7008c0 6.3488 2.3552 12.4416 6.6048 17.152l91.5968 101.6832c5.0688 5.632 12.032 8.448 19.0464 8.448 6.0928 0 12.2368-2.1504 17.1008-6.6048a25.58976 25.58976 0 0 0 1.8944-36.1472l-85.0432-94.3616V407.9104c0-14.1824-11.4688-25.6-25.6-25.6z" fill="#F7F8F8" p-id="14205"></path></svg>
    `;
	    let goodsHtml = ``, jumpUrl = "";
	    histories.forEach((h) => {
	      jumpUrl = Tools.encryptStr("https://page.mimixiaoke.com/api/product/redirect?url=" + encodeURIComponent(h.url));
	      goodsHtml += `
        <div class="goods-review_____item">
          <a title="` + h.title + `" jump-tag="true" jump-url="` + jumpUrl + `" target="_blank">
            <div class="review___shadow">
              <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAVlJREFUWEftlsGRgzAMRS26wBQTUtluKltSDKYLlJUHMY6xZMGFi7lkCObr6cuWAHfzBTfHdw2gOdAcOOXAPM+/fGwB4OGcG7f7iX4R8d113dT3fby3XCYACgwAPxZBBiKYYRh2YOldFUAKjIivNNNlWUZEJEB2ZI9HazUQEUALLgluIH95thpEESCEQCKHbADgyfXNACcAeNEzpVyT9/6Zwx0ApOD/QFFAypKEvfdR74x7XwCaOGevANIpiPXWNm1eji8ATZyzCyGgdhos63gN6eQAorhFmMugOcml3PtJmo3FukpPqO6TdCMfHLBuIKkMiUvFU5RnXwSgP6W9kG6gbQ0tpya0NxvFftsx5JJIVucWWkp4uhHVIMhKajy0jptPtLMwLy634kJm6fSrzqVa4OIpqKlSfdd1HbdRHOufTj9+3zIFLwHUAK88N30PXBG2vtMAmgPNgQ/i7v8h6Um2jAAAAABJRU5ErkJggg==" />
            </div>
            <img src="` + h.pic + `" />
          </a>
        </div>
      `;
	    });
	    let html = `
      <div class="peter99032j-xyz-panel-wrapper">
        <div class="peter99032j-xyz-panel-aside-main">
          <div class="panel-aside-main_____inner">
            <div class="panel-aside-main_____header">
              <div class="header_____title">
                ` + historySVG + `
                ` + selectLanguage().ecommerce.historyToolbar.boxTitle + `
              </div>
              <div class="header_____setting">
                <svg class="icon-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1770" width="30" height="30"><path d="M811.04 468.728a39.72 39.72 0 0 0-27.672-30.36l-10.2-2.28a100.872 100.872 0 0 1-68.856-120.24l3.12-9.552a41.592 41.592 0 0 0-11.424-40.368 281.64 281.64 0 0 0-36.816-24.336c-12.36-7.2-25.224-13.536-38.496-18.912a41.592 41.592 0 0 0-41.592 9.984l-7.08 7.488a100.248 100.248 0 0 1-69.264 27.456 100.464 100.464 0 0 1-68.64-27.672l-6.864-7.272a41.592 41.592 0 0 0-41.592-9.984 294.96 294.96 0 0 0-37.848 18.912c-12.696 7.152-24.792 15.288-36.192 24.336a41.592 41.592 0 0 0-10.824 40.368l2.904 9.552a101.088 101.088 0 0 1-10.8 74.064 96.72 96.72 0 0 1-57.408 45.552l-9.792 2.28a35.352 35.352 0 0 0-26.616 28.488c-1.872 14.352-2.64 28.8-2.28 43.272-0.408 14.736 0.36 29.472 2.28 44.088a39.936 39.936 0 0 0 25.8 31.2l9.552 2.304a99 99 0 0 1 57.624 46.992c12.984 22.392 16.848 48.912 10.8 74.064l-2.064 9.36a41.592 41.592 0 0 0 11.856 40.344c11.136 9.072 22.968 17.28 35.352 24.552 12.312 7.488 25.176 14.016 38.496 19.536 14.64 4.608 30.624 0.768 41.592-9.984l6.648-7.272a101.088 101.088 0 0 1 139.152 0l6.672 7.272a41.592 41.592 0 0 0 41.592 9.984 295.152 295.152 0 0 0 37.224-19.536 271.848 271.848 0 0 0 36.624-24.336c10.944-10.32 15.48-25.752 11.856-40.368l-2.928-9.768a100.872 100.872 0 0 1 69.48-120l9.576-2.304a39.72 39.72 0 0 0 27.648-30.36c1.68-14.376 2.232-28.824 1.68-43.272a291.192 291.192 0 0 0-2.304-43.272z m-307.44 190.944a147.672 147.672 0 1 1 0-295.344 147.672 147.672 0 0 1 0 295.344z" fill="#8a8a8a" p-id="1771"></path></svg>
              </div>
              <div class="header_____close">
                <svg class="icon-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1609" width="30" height="30"><path d="M673.5644448 281.66826667L512 447.82933333 351.16373333 281.71377813a44.6464 44.6464 0 0 0-63.6700448-0.50062293 46.1027552 46.1027552 0 0 0-0.50062186 64.6712896L447.82933333 512l-160.83626666 165.84248853c-17.52177813 18.06791147-17.29422187 46.8764448 0.50062186 64.6712896a44.69191147 44.69191147 0 0 0 63.71555627-0.45511146L512 576.17066667l161.5644448 165.93351146a44.78293333 44.78293333 0 0 0 63.7155552 0.4096 45.96622187 45.96622187 0 0 0 0.45511147-64.62577813L576.17066667 512l161.5644448-166.16106667a46.01173333 46.01173333 0 0 0-0.45511147-64.62577813 44.73742187 44.73742187 0 0 0-63.7155552 0.45511147z" fill="#5D6E7F" p-id="1610"></path></svg>
              </div>
            </div>
            <div class="panel-aside-main_____content"></div>
          </div>
        </div>
        <div class="peter99032j-xyz-panel-aside-body">
          <div class="goods_____expand">
            <svg focusable="false" class="icon-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1365" width="20" height="20"><path d="M317.84959998 926.1056a46.08 46.08 0 0 1 10.8544-29.9008L643.68639998 521.216a13.312 13.312 0 0 0 0-18.432l-3.6864-3.072L328.70399998 127.7952a46.4896 46.4896 0 0 1 71.0656-59.8016l311.0912 370.68799999a105.8816 105.8816 0 0 1 0 146.63680002l-311.0912 370.68799999a46.2848 46.2848 0 0 1-81.92-29.9008z" fill="#bfbfbf" p-id="1366"></path></svg>
          </div>
          <div class="goods_____review">
            ` + goodsHtml + `
          </div>
          <div class="history-box_____expand">
            ` + historySVG + `
            <label>` + selectLanguage().ecommerce.historyToolbar.expandTipText + `</label>
          </div>
          <div class="wrapper_____drag-handle">
            <svg focusable="false" class="icon-svg" viewBox="0 0 24 24" data-testid="DragIndicatorIcon"><path d="M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2m-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2m0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2" fill="#bfbfbf"></path></svg>
          </div>
        </div>
      </div>
    `;
	    GM_addStyle(css);
	    document.querySelector("body").insertAdjacentHTML("afterend", html);
	    this.addEventListener(platform);
	  },
	  addEventListener: function(platform) {
	    const self = this;
	    const items = document.querySelectorAll(".goods_____review >.goods-review_____item >a");
	    items.forEach((ele) => {
	      ele.addEventListener("mouseover", function() {
	        this.querySelector(".review___shadow").style.display = "block";
	      });
	      ele.addEventListener("mouseout", function() {
	        this.querySelector(".review___shadow").style.display = "none";
	      });
	    });
	    const goodsExpandEle = document.querySelector(".peter99032j-xyz-panel-wrapper .goods_____expand");
	    if (goodsExpandEle) {
	      goodsExpandEle.addEventListener("click", function() {
	        const goodsReviewEle = this.nextElementSibling;
	        const svgEle = this.querySelector("svg");
	        svgEle.style.transition = "transform 0.3s";
	        if (goodsReviewEle.style.width == "0px") {
	          goodsReviewEle.style.width = "auto";
	          svgEle.style.transform = "rotate(0deg)";
	        } else {
	          goodsReviewEle.style.width = "0px";
	          svgEle.style.transform = "rotate(180deg)";
	        }
	      });
	    }
	    const historyBoxExpandEles = [
	      document.querySelector(".peter99032j-xyz-panel-wrapper .history-box_____expand"),
	      document.querySelector(".peter99032j-xyz-panel-wrapper .header_____close")
	    ];
	    const asideMainEle = document.querySelector(".peter99032j-xyz-panel-wrapper >.peter99032j-xyz-panel-aside-main");
	    if (asideMainEle) {
	      historyBoxExpandEles.forEach((ele) => {
	        if (ele) {
	          ele.addEventListener("click", function() {
	            if (!asideMainEle.style.display || asideMainEle.style.display === "none") {
	              self.showOrHideHistoryBox(platform);
	              asideMainEle.style.display = "block";
	            } else {
	              asideMainEle.style.display = "none";
	            }
	          });
	        }
	      });
	    }
	    document.body.addEventListener("click", function(e) {
	      if (asideMainEle.style.display && asideMainEle.style.display !== "none") {
	        asideMainEle.style.display = "none";
	      }
	    });
	    const headerSettingElement = document.querySelector(".peter99032j-xyz-panel-wrapper .header_____setting");
	    if (headerSettingElement) {
	      headerSettingElement.addEventListener("click", () => {
	        self.showSettingDialog();
	      });
	    }
	    document.querySelectorAll(".peter99032j-xyz-panel-aside-body a[jump-tag='true']").forEach((ele) => {
	      ele.addEventListener("click", function(e) {
	        e.stopPropagation();
	        e.preventDefault();
	        const href = this.getAttribute("jump-url");
	        Tools.openInTab(Tools.decryptStr(href));
	      });
	    });
	    const draggable = document.querySelector(".peter99032j-xyz-panel-wrapper .wrapper_____drag-handle");
	    const wrapper = document.querySelector(".peter99032j-xyz-panel-wrapper");
	    let offsetX, offsetY;
	    const padding = 0;
	    const { width, height } = wrapper.getBoundingClientRect();
	    const offsetWrapper = Object.assign({}, this.defaultValue.offsetWrapper);
	    const move = (e) => {
	      const { innerWidth, innerHeight } = window;
	      innerWidth - (e.clientX - offsetX) - width;
	      let y = innerHeight - (e.clientY - offsetY) - height;
	      if (y < padding) {
	        y = padding;
	      } else if (y > innerHeight - height) {
	        y = innerHeight - height - padding;
	      }
	      wrapper.style.bottom = y + "px";
	      offsetWrapper.bottom = y;
	      GM_setValue(this.storageKeys.offset, offsetWrapper);
	    };
	    if (draggable && wrapper) {
	      draggable.addEventListener("mousedown", function(e) {
	        offsetX = e.clientX - wrapper.offsetLeft - 10;
	        offsetY = e.clientY - wrapper.offsetTop - 10;
	        draggable.style.cursor = "grabbing";
	        wrapper.style.userSelect = "none";
	        document.addEventListener("mousemove", move);
	      });
	      document.addEventListener("mouseup", function() {
	        draggable.style.cursor = "grab";
	        wrapper.style.userSelect = "default";
	        document.removeEventListener("mousemove", move);
	      });
	    }
	  },
	  removeAnchor: function() {
	    if (/aliexpress\./.test(window.location.host)) {
	      setInterval(() => {
	        const anchors = document.querySelectorAll("div[class='peter99032j-xyz-panel-wrapper']");
	        anchors.forEach((ele) => {
	          Tools.removeAliexpressAnchors(ele);
	        });
	      }, 1500);
	    }
	  },
	  start: function(platform) {
	    try {
	      if (!/aliexpress\.ru/.test(window.location.host)) {
	        this.createHistoryBox(platform);
	        this.registerMenuCommand();
	      }
	      this.removeAnchor();
	    } catch (e) {
	    }
	  }
	};

	var __async$4 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const Aliexpress = {
	  languageStoageKey: "language-stoage-key",
	  currencyStoageKey: "language-currency-key",
	  baseUrl: "https://oversea.mimixiaoke.com",
	  checkDomInsertRs: true,
	  getLang: function() {
	    const host = window.location.host;
	    let lang = "en";
	    if (/^(us|ko|uk|fr|de|it|ca|au|jp|ja|he|kr|ru|br|in|es|mx|pl|tr|ar|id|th|vn|sg|my|ph|be|nl|se|ch|no|dk|at|ie|fi|pt|gr|hu|cz|bg|ro|ua|il|sa|eg|ir|pk|iq|af|ly|et|gh|ke|ng|za|tz|mg|mw|zm|bw|sn|cm|ci|gh|ma|tn|mr|mu|om|kw|qa|bh|ae|lb|jo|sy|lb|il|ps|kr|cl|pe|uy|ec|ve|bo|gt|pa|hn|ni|cr|sv|gt|sl|lr|sd|er|dj|et|mw|mz|ao|tz|zm|zw|mw|na|bw|ls|mg|km)\.aliexpress\.com$/.test(host)) {
	      lang = host.split(".")[0];
	    } else if (/^www\.aliexpress\.com$/.test(host)) {
	      lang = "en";
	    } else if (/^aliexpress\.ru$/.test(host)) {
	      lang = "ru";
	    }
	    GM_setValue(this.languageStoageKey, lang);
	    return lang;
	  },
	  getCurrency: function() {
	    const host = window.location.host;
	    return new Promise((resolve, reject) => {
	      if (host.indexOf("aliexpress.ru") != -1) {
	        resolve("unknown");
	      } else {
	        const element = document.querySelector("div[class^='ship-to--menuItem--']") || document.querySelector("div[class^='countryFlag--']");
	        if (element) {
	          let currency = element.textContent;
	          if (currency) {
	            currency = encodeURIComponent(currency);
	            GM_setValue(this.currencyStoageKey, currency);
	            resolve(currency);
	          } else {
	            resolve("unknown");
	          }
	        } else {
	          resolve("unknown");
	        }
	      }
	    });
	  },
	  detail: function() {
	    return __async$4(this, null, function* () {
	      const visitUrl = window.location.href;
	      const validate = [/\/item\/[^\/]*?\.html\?/, /\/item\/[^\/]*?\.html$/].map((reg) => reg.test(visitUrl)).some((rs) => rs == true);
	      if (!validate)
	        return;
	      const language = this.getLang();
	      const currency = yield this.getCurrency();
	      const id = Tools.getParamterBySuffix(visitUrl, "html");
	      const url = this.baseUrl + "/api/coupon/query?ids=" + id + "&qu=&p=aliexpress&no=9&v=1.0.1&lang=" + language + "&mul=false&currency=" + currency;
	      const data = yield Tools.crossRequest("GET", url, null);
	      if (data.code == "success" && !!data.result) {
	        const json = JSON.parse(data.result);
	        yield this.detailAnalyze(json, language, currency);
	      }
	      if (!/aliexpress\.ru/.test(window.location.host)) {
	        const priceValueElement = document.querySelector("span.product-price-value, div[class*='ProductPrice_SnowPrice']");
	        const sliderImgElement = document.querySelector("div[class*='slider--img'] >img, picture[class*='Picture__container'] >img");
	        const priceTitleElement = document.querySelector("h1[data-pl='product-title'], h1[class*='HazeProductDescription_HazeProductDescription__smallText_']");
	        if (sliderImgElement) {
	          const imgSrc = sliderImgElement.getAttribute("src");
	          const price = priceValueElement ? priceValueElement.innerText : "Unknown";
	          const title = priceTitleElement ? priceTitleElement.innerText : "--";
	          const goods = { "id": id, "url": visitUrl, "pic": imgSrc, "date": new Date().getTime(), "price": price, "title": title };
	          GoodsHistroy.push("aliexpress", goods);
	        }
	      }
	    });
	  },
	  detailAnalyze: function(json, language, currency) {
	    return __async$4(this, null, function* () {
	      this.checkDomInsertRs = false;
	      try {
	        if (!json)
	          return;
	        let couponResult = null;
	        let qrcodeResult = null;
	        if (!!json.data && !!json.data.css && !!json.data.html && !!json.data.handler) {
	          const { handler, css, html, templateId, distinguish } = json.data;
	          GM_addStyle(css);
	          const element = yield Tools.mustGetElement(handler);
	          logger("info", "coupon insert:element", element);
	          if (element) {
	            couponResult = { "element": element, "html": html, "templateId": templateId, "distinguish": distinguish };
	          }
	        }
	        if (!!json.id && !!json.mscan && !!json.mscan.html && !!json.mscan.mount) {
	          const { iden, html, mount, distinguish } = json.mscan;
	          const id = json.id;
	          const promiseResultArray = [];
	          const elementPromise = Tools.mustGetElement(mount);
	          const reqUrl = this.baseUrl + "/api/coupon/change?id=" + id + "&lang=" + language + "&platform=aliexpress&currency=" + currency;
	          logger("info", "coupon change >>>>>>>>>>>>>", reqUrl);
	          const reqPromise = Tools.crossRequest("GET", reqUrl, null);
	          promiseResultArray.push(elementPromise, reqPromise);
	          const allResult = yield Promise.all(promiseResultArray);
	          let element = null, qrcodeData = null;
	          for (let i = 0; i < allResult.length; i++) {
	            if (allResult[i]) {
	              if (allResult[i].hasOwnProperty("code")) {
	                qrcodeData = allResult[i];
	              } else {
	                element = allResult[i];
	              }
	            }
	          }
	          logger("info", "qrcocd insert:element", element);
	          if (element && qrcodeData) {
	            qrcodeResult = { "element": element, "html": html, "iden": iden, "qrcodeData": qrcodeData, "distinguish": distinguish };
	          }
	        }
	        Tools.loopTask(() => {
	          if (couponResult) {
	            Tools.distinguishRemoveAndTry(couponResult.distinguish, () => {
	              this.detailCouponAnalyze(couponResult);
	            });
	          }
	          if (qrcodeResult) {
	            Tools.distinguishRemoveAndTry(qrcodeResult.distinguish, () => {
	              this.detailMscanAnalyze(qrcodeResult);
	            });
	          }
	        });
	      } catch (error) {
	      } finally {
	        this.checkDomInsertRs = true;
	      }
	    });
	  },
	  detailCouponAnalyze: function(result) {
	    const { element, html, templateId } = result;
	    element.insertAdjacentHTML("afterend", html);
	    const templateIdEle = document.querySelector("div[id='" + templateId + "']");
	    if (templateIdEle) {
	      const couponCodeElement = templateIdEle.querySelector(".coupon-code");
	      const promoCode = Tools.decryptStr(couponCodeElement.getAttribute("data-encryptcode"));
	      templateIdEle.addEventListener("click", () => {
	        GM_setClipboard(promoCode, "txt", () => {
	          Toast.show({ "message": selectLanguage().ecommerce.operat.copied, "background": "#D3031C" });
	        });
	      });
	    }
	  },
	  detailMscanAnalyze: function(result) {
	    const { element, html, qrcodeData, iden } = result;
	    element.insertAdjacentHTML("afterend", html);
	    if (!!qrcodeData && qrcodeData.code === "success" && !!qrcodeData.result) {
	      const mscanImg = JSON.parse(qrcodeData.result).mscanImg;
	      if (!!mscanImg) {
	        const canvasElement = document.getElementById("mscan" + iden);
	        if (canvasElement) {
	          var cxt = canvasElement.getContext("2d");
	          var imgData = new Image();
	          imgData.src = mscanImg;
	          imgData.onload = function() {
	            cxt.drawImage(imgData, 0, 0, imgData.width, imgData.height);
	          };
	        }
	      }
	    }
	  },
	  trade: function() {
	    return __async$4(this, null, function* () {
	      const visitUrl = window.location.href;
	      const validate = [
	        /\/trade\/confirm\.html/,
	        /\/checkout\?/
	      ].map((reg) => reg.test(visitUrl)).some((rs) => rs == true);
	      if (!validate)
	        return;
	      const language = yield GM_getValue(this.languageStoageKey, navigator.language);
	      const currency = yield GM_getValue(this.currencyStoageKey, "USD");
	      const ids = Tools.getParamterBySearch(window.location.search, "objectId") || Tools.getParamterBySearch(window.location.search, "availableProductShopcartIds") || Tools.getParamterBySearch(window.location.search, "itemId");
	      const confirmUrl = this.baseUrl + "/api/coupon/query?ids=" + ids + "&qu=&p=aliexpress&no=9&v=1.0.1&lang=" + language + "&mul=true&currency=" + currency;
	      const res = yield Tools.crossRequest("GET", confirmUrl, null);
	      if (res.code == "success" && !!res.result) {
	        const json = JSON.parse(res.result);
	        yield this.tradeAnalyze(json, language);
	      }
	    });
	  },
	  tradeAnalyze: function(json, language) {
	    return __async$4(this, null, function* () {
	      if (!json || !json.handler || !json.css || !json.templateId) {
	        return;
	      }
	      const { handler, css, html, templateId, distinguish } = json;
	      GM_addStyle(css);
	      let element = yield Tools.mustGetElement(handler);
	      Tools.loopTask(() => {
	        if (!element) {
	          return;
	        }
	        Tools.distinguishRemoveAndTry(distinguish, () => {
	          element.insertAdjacentHTML("afterend", html);
	          const templateIdEle = document.querySelector("#" + templateId + ">.item");
	          if (templateIdEle) {
	            const promoCode = Tools.decryptStr(templateIdEle.querySelector(".copy").getAttribute("data-encryptcode"));
	            templateIdEle.addEventListener("click", () => {
	              GM_setClipboard(promoCode, "txt", () => {
	                Toast.show({ "message": selectLanguage().ecommerce.operat.copied, "background": "#D3031C" });
	              });
	            });
	            const arrowElement = document.querySelector(".pl-summary__item-arrow-pc");
	            if (arrowElement) {
	              arrowElement.click();
	            }
	          }
	        });
	      });
	    });
	  },
	  isRun: function() {
	    return window.location.host.indexOf("aliexpress.") != -1;
	  },
	  removeAnchor: function() {
	    Tools.loopTask(() => {
	      const anchors = document.querySelectorAll("div[name^='ali-gogo-coupon-']");
	      anchors.forEach((ele) => Tools.removeAliexpressAnchors(ele));
	    }, 2500);
	  },
	  start: function() {
	    return __async$4(this, null, function* () {
	      if (this.isRun()) {
	        this.detail();
	        this.trade();
	        this.removeAnchor();
	      }
	    });
	  }
	};

	var __async$3 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const AliexpressSearch = {
	  visitUrl: window.location.href,
	  baseUrl: "https://oversea.mimixiaoke.com",
	  loopIsComplete: true,
	  searchAttribute: "loop-task-i9v---search",
	  cacheRequestMap: {},
	  requestAndSaveSate: function(method, url, param) {
	    return new Promise((resolve, reject) => {
	      const key = "key_" + new Date().getTime();
	      const xhr = new XMLHttpRequest();
	      this.cacheRequestMap[key] = xhr;
	      if (method === "GET") {
	        let queryString = "";
	        if (param) {
	          const params = new URLSearchParams(param);
	          queryString = "?" + params.toString();
	        }
	        xhr.open(method, url + queryString);
	        xhr.send();
	      } else if (method === "POST") {
	        xhr.open(method, url);
	        xhr.setRequestHeader("Content - Type", "application/json");
	        xhr.send(JSON.stringify(param));
	      } else {
	        resolve({ "code": "error", "requestKey": key, "result": null });
	        return;
	      }
	      xhr.onreadystatechange = function() {
	        if (xhr.readyState === 4) {
	          if (xhr.status >= 200 && xhr.status < 300) {
	            try {
	              resolve({ "code": "success", "requestKey": key, "result": xhr.responseText });
	            } catch (e) {
	              resolve({ "code": "error", "requestKey": key, "result": null });
	            }
	          } else {
	            resolve({ "code": "error", "requestKey": key, "result": null });
	          }
	        }
	      };
	    });
	  },
	  requestConf: function() {
	    return new Promise((resolve, reject) => {
	      Tools.crossRequest("GET", this.baseUrl + "/api/load/conf", null).then((data) => {
	        if (data.code == "success" && !!data.result) {
	          resolve(data.result);
	        } else {
	          resolve(null);
	        }
	      });
	    });
	  },
	  pickupGoodsItem: function(confString) {
	    const visitHref = window.location.href;
	    const selectorElementList = new Array();
	    let confFilter = confString;
	    try {
	      confFilter = confFilter.replace(/\\\\/g, "\\");
	    } catch (e) {
	    }
	    const confJson = JSON.parse(confFilter);
	    for (let key in confJson) {
	      if (!confJson.hasOwnProperty(key)) {
	        continue;
	      }
	      for (let i = 0; i < confJson[key].length; i++) {
	        const itemJson = confJson[key][i];
	        if (!itemJson.hasOwnProperty("elements") || !itemJson.hasOwnProperty("matches")) {
	          continue;
	        }
	        const { elements, matches } = itemJson;
	        const isMatch = matches.map((reg) => new RegExp(reg, "i").test(visitHref)).some((res) => res);
	        if (isMatch) {
	          for (let j = 0; j < elements.length; j++) {
	            selectorElementList.push({
	              "element": elements[j]["element"],
	              "findA": elements[j]["findA"],
	              "page": elements[j]["page"]
	            });
	          }
	        }
	      }
	    }
	    return selectorElementList;
	  },
	  isInbusinessPage: function() {
	    return /inbusiness\.aliexpress\.com\/web\/search-products/.test(this.visitUrl);
	  },
	  getGoodsIdByUrl: function(href) {
	    if (!href)
	      return null;
	    href = href.indexOf("http") == -1 ? location.protocol + href : href;
	    const id = Tools.getParamterBySuffix(href, "html");
	    return id;
	  },
	  calcRequestGroup: function(array) {
	    const itemsPerGroup = 8, len = array.length;
	    let groups = [];
	    for (let i = 0; i < len; i++) {
	      const groupIndex = Math.floor(i / itemsPerGroup);
	      if (!groups[groupIndex]) {
	        groups[groupIndex] = [];
	      }
	      groups[groupIndex].push(array[i]);
	    }
	    return groups;
	  },
	  isElementDisplayed: function(element) {
	    if (element.offsetParent !== null) {
	      return true;
	    }
	    const style = window.getComputedStyle(element);
	    return style.display !== "none";
	  },
	  getGoodsLinkByElement: function(element, findTag) {
	    let searchElement = null;
	    if (findTag == "this") {
	      searchElement = element;
	    } else if (/^child@/.test(findTag)) {
	      searchElement = element.querySelector(findTag.replace(/^child@/, ""));
	    }
	    return searchElement;
	  },
	  pickUpWholesale: function(selectors, language, currency) {
	    return __async$3(this, null, function* () {
	      const items = [];
	      try {
	        selectors.forEach((elementObj) => {
	          if (elementObj.element) {
	            const elements = document.querySelectorAll(elementObj.element + ":not([" + this.searchAttribute + "='true'])");
	            const findA = elementObj.findA;
	            elements.forEach((element) => {
	              if (element && this.isElementDisplayed(element) && !element.getAttribute(this.searchAttribute)) {
	                const goodsLink = this.getGoodsLinkByElement(element, findA);
	                let id = null;
	                if (/\/item\/[^\/]*?\.html/.test(goodsLink)) {
	                  id = this.getGoodsIdByUrl(goodsLink.getAttribute("href"));
	                }
	                if (id) {
	                  items.push({
	                    "id": id,
	                    "platform": "aliexpress",
	                    "handler": element,
	                    "findA": findA,
	                    "from": "wholesale"
	                  });
	                }
	              }
	            });
	          }
	        });
	        if (items.length > 0) {
	          yield this.search(items, language, currency);
	        }
	      } catch (e) {
	      }
	    });
	  },
	  pickUpInbusiness: function(language, currency) {
	    return __async$3(this, null, function* () {
	      const validate = this.isInbusinessPage();
	      if (!validate)
	        return;
	      try {
	        const iceContainerElement = document.querySelector("#ice-container");
	        const loadMoreElement = yield Tools.waitForElementByInterval("#loadMore", iceContainerElement);
	        if (loadMoreElement) {
	          const array = new Array();
	          const containerElement = loadMoreElement.previousElementSibling;
	          if (containerElement && containerElement.tagName === "DIV") {
	            const childNodes = containerElement.childNodes;
	            childNodes.forEach((child) => {
	              if (child.tagName === "A" && this.isElementDisplayed(child) && !child.getAttribute(this.searchAttribute)) {
	                const id = this.getGoodsIdByUrl(child.getAttribute("href"));
	                if (id) {
	                  array.push({
	                    "id": id,
	                    "platform": "aliexpress",
	                    "handler": child,
	                    "from": "inbusiness"
	                  });
	                }
	              }
	            });
	          }
	          yield this.search(array, language, currency);
	        }
	      } catch (e) {
	      }
	    });
	  },
	  search: function(array, language, currency) {
	    const groups = this.calcRequestGroup(array);
	    const len = groups.length;
	    return new Promise((resolve, reject) => {
	      if (len <= 0) {
	        resolve("complete");
	        return;
	      }
	      const promises = [];
	      for (let i = 0; i < groups.length; i++) {
	        promises.push(this.createItemHtml(groups[i], language, currency));
	      }
	      Promise.all(promises).then((data) => {
	        resolve("complete");
	      });
	    });
	  },
	  createItemHtml: function(group, language, currency) {
	    return new Promise((resolve, reject) => {
	      try {
	        if (Array.isArray(group) && group.length === 0) {
	          resolve("exception");
	          return;
	        }
	        let reqId = "";
	        const platform = group[0].platform;
	        for (var i = 0; i < group.length; i++) {
	          if (group[i].handler.getAttribute(this.searchAttribute)) {
	            continue;
	          }
	          reqId += group[i].id + ",";
	        }
	        if (reqId.endsWith(",")) {
	          reqId = reqId.slice(0, -1);
	        }
	        logger("info", "request start >>>>>>>>>>>>>", group);
	        const searchUrl = this.baseUrl + "/api/coupon/exist?platform=" + platform + "&ids=" + reqId + "&lang=" + language + "&no=9&v=1.0.1&currency=" + currency;
	        logger("info", "request searchUrl >>>>>>>>>>>>>:", searchUrl);
	        this.requestAndSaveSate("GET", searchUrl, null).then((data) => {
	          logger("info", "request finish >>>>>>>>>>>>>");
	          delete this.cacheRequestMap[data.requestKey];
	          if (data.code != "success" || !data.result) {
	            resolve("exception");
	            return;
	          }
	          const json = JSON.parse(data.result);
	          logger("info", "json", json);
	          let isBroken = false;
	          for (let key in json) {
	            const { encryptLink, tip } = json[key];
	            const { handler, findA } = group.find((obj) => obj.id === key);
	            let decryptUrl = null;
	            if (encryptLink) {
	              try {
	                const decryptLink = atob(encryptLink);
	                decryptUrl = decryptLink.split("").reverse().join("");
	              } catch (e) {
	              }
	            }
	            const elementA = this.getGoodsLinkByElement(handler, findA);
	            const currentId = elementA ? this.getGoodsIdByUrl(elementA.getAttribute("href")) : "";
	            if (currentId != key) {
	              group.forEach((gItem) => {
	                const ele = gItem.handler;
	                ele.removeAttribute(this.searchAttribute);
	                const tipElement = ele.querySelector("div[name^='ali-gogo-coupon-']");
	                if (tipElement) {
	                  tipElement.remove();
	                }
	              });
	              logger("info", "exception currentGoodsId != request id");
	              isBroken = true;
	              break;
	            } else {
	              if (!handler.getAttribute(this.searchAttribute)) {
	                handler.setAttribute(this.searchAttribute, "true");
	                if (tip) {
	                  handler.style.position = "relative";
	                  handler.insertAdjacentHTML("beforeend", tip);
	                  logger("info", "exist coupon >>>>>>>>>>>>>", key);
	                }
	                if (decryptUrl) {
	                  this.relativeJ(handler, decryptUrl);
	                  logger("info", "good job >>>>>>>>>>>>>", key);
	                }
	              }
	            }
	          }
	          resolve(isBroken ? "broken" : "complete");
	        });
	      } catch (e) {
	        resolve("exception");
	      }
	    });
	  },
	  relativeJ: function(handler, decryptUrl) {
	    const clickTipAttribute = "tip-vjd1jd89fcv-i";
	    let elements = null;
	    if (handler.tagName == "A") {
	      elements = [handler];
	    } else {
	      elements = handler.querySelectorAll("a");
	    }
	    elements.forEach((elementA) => {
	      const href = elementA.getAttribute("href");
	      if (/\/item\/[^\/]*?\.html/.test(href)) {
	        if (elementA.getAttribute(clickTipAttribute)) {
	          return;
	        }
	        elementA.setAttribute(clickTipAttribute, "true");
	        elementA.addEventListener("click", function(e) {
	          let isPreventDefault = true;
	          const target = e.target;
	          const tagName = target.tagName.toUpperCase();
	          if (tagName == "A") {
	            const href2 = target.getAttribute("href");
	            if (!/\/item\/[^\/]*?\.html/.test(href2)) {
	              isPreventDefault = false;
	            }
	          }
	          if (isPreventDefault) {
	            Array.from(target.classList).forEach((className) => {
	              const iscontains = ["icon", "--btn--"].map((name) => className.indexOf(name) != -1).some((result) => result);
	              if (iscontains) {
	                isPreventDefault = false;
	              }
	            });
	          }
	          if (isPreventDefault) {
	            e.preventDefault();
	            e.stopPropagation();
	            Tools.openInTab(decryptUrl);
	          }
	        });
	      }
	    });
	  },
	  isRun: function() {
	    let run = false;
	    if (window.location.host.indexOf("aliexpress.") != -1) {
	      run = !/\/(item|trade|checkout)\//.test(window.location.pathname);
	    }
	    return run;
	  },
	  start: function() {
	    return __async$3(this, null, function* () {
	      if (!this.isRun())
	        return;
	      let removeTagIsComplete = true;
	      const language = Aliexpress.getLang();
	      const currency = yield Aliexpress.getCurrency();
	      const confString = yield this.requestConf();
	      if (!confString) {
	        return;
	      }
	      const selectors = this.pickupGoodsItem(confString);
	      setInterval(() => __async$3(this, null, function* () {
	        if (removeTagIsComplete && this.loopIsComplete) {
	          this.loopIsComplete = false;
	          yield this.pickUpInbusiness(language, currency);
	          yield this.pickUpWholesale(selectors, language, currency);
	          this.loopIsComplete = true;
	        }
	      }), 1700);
	      if (selectors.length != 0 && window.location.pathname != "/") {
	        let oldUrl = window.location.href;
	        setInterval(() => {
	          if (oldUrl != window.location.href && removeTagIsComplete) {
	            removeTagIsComplete = false;
	            Object.keys(this.cacheRequestMap).forEach((key) => {
	              this.cacheRequestMap[key].abort();
	            });
	            this.cacheRequestMap = {};
	            document.querySelectorAll("*[" + this.searchAttribute + "='true']").forEach((element) => {
	              const tipElement = element.querySelector("*[name^='ali-gogo-coupon-']");
	              if (tipElement) {
	                tipElement.remove();
	              }
	            });
	            oldUrl = window.location.href;
	          }
	          removeTagIsComplete = true;
	        }, 777);
	        const promises = [];
	        selectors.forEach((selector) => {
	          promises.push(Tools.waitForElementByInterval(selector.element, document.body, true, 50, 3e3));
	        });
	        const observerElement = yield Promise.race(promises);
	        if (observerElement) {
	          const observer = new MutationObserver((mutationsList) => {
	            if (mutationsList.length == 1) {
	              const mutation = mutationsList[0];
	              if (mutation.type === "attributes" && mutation.attributeName === "href") {
	                if (removeTagIsComplete) {
	                  removeTagIsComplete = false;
	                  document.querySelectorAll("*[" + this.searchAttribute + "='true']").forEach((element) => {
	                    element.removeAttribute(this.searchAttribute);
	                    const tipElement = element.querySelector("*[name^='ali-gogo-coupon-']");
	                    if (tipElement) {
	                      tipElement.remove();
	                    }
	                  });
	                  removeTagIsComplete = true;
	                }
	              }
	            }
	          });
	          observer.observe(observerElement, { attributes: true });
	        }
	      }
	    });
	  }
	};

	var __async$2 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e2) {
	        reject(e2);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e2) {
	        reject(e2);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const Ebay = {
	  baseUrl: "https://oversea.mimixiaoke.com",
	  getGoodsId: function(url) {
	    const regex = /https?:\/\/www\.ebay\.[a-z.]+\/itm\/(\d+)/;
	    const match = url.match(regex);
	    return match ? match[1] : null;
	  },
	  isDetail: function() {
	    const visitUrl = window.location.href;
	    return [/https?:\/\/www\.ebay\.[a-z.]+\/itm\/\d+/].map((rs) => rs.test(visitUrl)).some((rs) => rs);
	  },
	  getMarketplace: function(url) {
	    try {
	      const urlObj = new URL(url);
	      const hostname = urlObj.hostname;
	      const topLevelDomainMatch = hostname.match(/ebay\.(\w{2,3})$/);
	      return topLevelDomainMatch ? topLevelDomainMatch[1] : null;
	    } catch (error) {
	      logger("error", "getMarketplace", e);
	    }
	    return null;
	  },
	  detail: function() {
	    return __async$2(this, null, function* () {
	      const validate = this.isDetail();
	      if (!validate)
	        return;
	      const visitUrl = window.location.href;
	      const id = this.getGoodsId(visitUrl);
	      if (!id) {
	        return;
	      }
	      const titleElement = document.querySelector(".x-item-title__mainTitle");
	      const priceElement = document.querySelector(".x-price-primary >span");
	      const imgElement = document.querySelector(".ux-image-grid-item >img") || document.querySelector(".ux-image-carousel-item >img");
	      if (imgElement) {
	        const imgSrc = imgElement.getAttribute("src");
	        const title = titleElement ? titleElement.innerText : "--";
	        const price = priceElement ? priceElement.innerText : "Unknown";
	        const goods = { "id": id, "url": visitUrl, "pic": imgSrc, "date": new Date().getTime(), "price": price, "title": title };
	        GoodsHistroy.push("ebay", goods);
	      }
	      const marketplace = this.getMarketplace(visitUrl);
	      const url = this.baseUrl + "/api/coupon/query?ids=" + id + "&qu=&p=ebay&no=9&v=1.0.1&marketplace=" + marketplace + "&mul=false";
	      const data = yield Tools.crossRequest("GET", url, null);
	      if (data.code == "success" && !!data.result) {
	        const json = JSON.parse(data.result);
	        yield this.detailAnalyze(json, marketplace);
	      }
	    });
	  },
	  detailAnalyze: function(json, marketplace) {
	    return __async$2(this, null, function* () {
	      let couponResult = null;
	      let qrcodeResult = null;
	      if (!!json.data && !!json.data.css && !!json.data.html && !!json.data.handler) {
	        const { handler, css, html, templateId, distinguish } = json.data;
	        GM_addStyle(css);
	        const element = yield Tools.mustGetElement(handler);
	        if (element) {
	          couponResult = { "element": element, "html": html, "templateId": templateId, "distinguish": distinguish };
	        }
	      }
	      if (!!json.id && !!json.mscan && !!json.mscan.html && !!json.mscan.mount) {
	        const { iden, html, mount, distinguish } = json.mscan;
	        const id = json.id;
	        const promiseResultArray = [];
	        const elementPromise = Tools.mustGetElement(mount);
	        const reqUrl = this.baseUrl + "/api/coupon/change?id=" + id + "&marketplace=" + marketplace + "&platform=ebay";
	        const reqPromise = Tools.crossRequest("GET", reqUrl, null);
	        promiseResultArray.push(elementPromise, reqPromise);
	        const allResult = yield Promise.all(promiseResultArray);
	        let element = null, qrcodeData = null;
	        for (let i = 0; i < allResult.length; i++) {
	          if (allResult[i]) {
	            if (allResult[i].hasOwnProperty("code")) {
	              qrcodeData = allResult[i];
	            } else {
	              element = allResult[i];
	            }
	          }
	        }
	        if (element && qrcodeData) {
	          qrcodeResult = { "element": element, "html": html, "iden": iden, "qrcodeData": qrcodeData, "distinguish": distinguish };
	        }
	      }
	      Tools.loopTask(() => {
	        if (couponResult) {
	          Tools.distinguishRemoveAndTry(couponResult.distinguish, () => {
	            this.detailCouponAnalyze(couponResult);
	          });
	        }
	        if (qrcodeResult) {
	          Tools.distinguishRemoveAndTry(qrcodeResult.distinguish, () => {
	            this.detailMscanAnalyze(qrcodeResult);
	          });
	        }
	      });
	    });
	  },
	  detailCouponAnalyze: function(result) {
	    const { element, html, templateId } = result;
	    element.insertAdjacentHTML("afterend", html);
	    const templateIdEle = document.querySelector("div[id='" + templateId + "']");
	    if (templateIdEle) {
	      const couponCodeElement = templateIdEle.querySelector(".coupon-code");
	      const promoCode = Tools.decryptStr(couponCodeElement.getAttribute("data-encryptcode"));
	      templateIdEle.addEventListener("click", () => {
	        GM_setClipboard(promoCode, "txt", () => {
	          Toast.show({ "message": selectLanguage().ecommerce.operat.copied, "background": "#D3031C" });
	        });
	      });
	    }
	  },
	  detailMscanAnalyze: function(result) {
	    const { element, html, qrcodeData, iden } = result;
	    element.insertAdjacentHTML("afterend", html);
	    if (!!qrcodeData && qrcodeData.code === "success" && !!qrcodeData.result) {
	      const mscanImg = JSON.parse(qrcodeData.result).mscanImg;
	      if (!!mscanImg) {
	        const canvasElement = document.getElementById("mscan" + iden);
	        if (canvasElement) {
	          var cxt = canvasElement.getContext("2d");
	          var imgData = new Image();
	          imgData.src = mscanImg;
	          imgData.onload = function() {
	            cxt.drawImage(imgData, 0, 0, imgData.width, imgData.height);
	          };
	        }
	      }
	    }
	  },
	  start: function() {
	    return __async$2(this, null, function* () {
	      this.detail();
	    });
	  }
	};

	var __async$1 = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const Lazada = {
	  baseUrl: "https://oversea.mimixiaoke.com",
	  visitUrl: window.location.href,
	  getMarketplace: function(url) {
	    try {
	      const domainParts = new URL(url).hostname.split(".");
	      const countryCode = domainParts[domainParts.length - 1];
	      return countryCode;
	    } catch (error) {
	      console.log(error);
	    }
	    return null;
	  },
	  detailMyMscanAnalyze: function(result) {
	    return __async$1(this, null, function* () {
	      const { id, iden, marketplace, platform, mount, html, cmd } = result;
	      if (!mount || !html) {
	        return;
	      }
	      if (cmd && cmd.do && cmd.ele) {
	        const cmdElement = yield Tools.waitForElementByInterval(cmd.ele);
	        if (cmdElement) {
	          if (cmd.do == "empty") {
	            cmdElement.innerHTML = "";
	          }
	        }
	      }
	      const element = yield Tools.mustGetElement(mount);
	      if (!element) {
	        return;
	      }
	      element.insertAdjacentHTML("beforeend", html);
	      const reqImageUrl = this.baseUrl + "/api/coupon/change?id={id}&marketplace={marketplace}&platform={platform}".replace("{id}", id).replace("{marketplace}", marketplace).replace("{platform}", platform);
	      const qrcodeData = yield Tools.crossRequest("GET", reqImageUrl, null);
	      if (!!qrcodeData && qrcodeData.code === "success" && !!qrcodeData.result) {
	        let mscanImg = JSON.parse(qrcodeData.result).mscanImg;
	        if (!!mscanImg) {
	          var canvasElement = document.getElementById("mscan" + iden);
	          if (!!canvasElement) {
	            var cxt = canvasElement.getContext("2d");
	            var imgData = new Image();
	            imgData.src = mscanImg;
	            imgData.onload = function() {
	              cxt.drawImage(imgData, 0, 0, imgData.width, imgData.height);
	            };
	          }
	        }
	      }
	    });
	  },
	  detailMy: function() {
	    return __async$1(this, null, function* () {
	      if (!this.isMy()) {
	        return;
	      }
	      const marketplace = "my", platform = "lazada";
	      const ids = Tools.getParamterBySuffix(this.visitUrl);
	      if (!ids) {
	        return;
	      }
	      const reqUrl = this.baseUrl + "/api/coupon/query?ids=" + ids + "&qu=&p=" + platform + "&no=9&v=1.0.1&marketplace=" + marketplace + "&mul=false";
	      const data = yield Tools.crossRequest("GET", reqUrl, null);
	      if (!!data && data.code === "success" && !!data.result) {
	        const json = JSON.parse(data.result);
	        if (json && json.mscan) {
	          const { distinguish, iden, html, cmd, mount } = json.mscan;
	          const mscanResult = {
	            "id": json.id,
	            "iden": iden,
	            "marketplace": marketplace,
	            "platform": platform,
	            "mount": mount,
	            "html": html,
	            "cmd": cmd
	          };
	          Tools.loopTask(() => {
	            Tools.distinguishRemoveAndTry(distinguish, () => {
	              this.detailMyMscanAnalyze(mscanResult);
	            });
	          });
	        }
	      }
	      const titleElement = document.querySelector(".pdp-mod-product-badge-title");
	      const priceElement = yield Tools.waitForElementByInterval(".pdp-product-price >span", document.body, false);
	      const imgElement = document.querySelector(".gallery-preview-panel__content >img:last-child");
	      if (imgElement && priceElement) {
	        const imgSrc = imgElement.getAttribute("src");
	        const title = titleElement ? titleElement.innerText : "--";
	        const price = priceElement ? priceElement.innerText : "Unknown";
	        const goods = { "id": ids, "url": this.visitUrl, "pic": imgSrc, "date": new Date().getTime(), "price": price, "title": title };
	        GoodsHistroy.push("lazada", goods);
	      }
	    });
	  },
	  isMy: function() {
	    return /https:\/\/www\.lazada\.com\.my\/products\/[a-zA-Z0-9\-]+-i\d+-s\d+\.html.*/.test(this.visitUrl);
	  },
	  start: function() {
	    return __async$1(this, null, function* () {
	      this.detailMy();
	    });
	  }
	};

	var __async = (__this, __arguments, generator) => {
	  return new Promise((resolve, reject) => {
	    var fulfilled = (value) => {
	      try {
	        step(generator.next(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var rejected = (value) => {
	      try {
	        step(generator.throw(value));
	      } catch (e) {
	        reject(e);
	      }
	    };
	    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
	    step((generator = generator.apply(__this, __arguments)).next());
	  });
	};
	const YoutubeDownload = {
	  markName: `script-download-----iux998htt`,
	  isComplete: true,
	  download: function(btn) {
	    return __async(this, null, function* () {
	      try {
	        Toast.show({ "message": selectLanguage().download.preparing, "background": "#000" });
	        btn.classList.add("download-loadding");
	        const downloadUl = yield this.getDownloadUrl(window.location.href.replace("music.youtube.com", "www.youtube.com"));
	        window.open(downloadUl, "_blank");
	      } catch (ex) {
	      } finally {
	        btn.classList.remove("download-loadding");
	      }
	    });
	  },
	  getDownloadUrl: function(videoUrl, audioOnly = false) {
	    return new Promise((resolve, reject) => {
	      GM_xmlhttpRequest({
	        method: "POST",
	        url: "https://api.cobalt.tools/api/json",
	        headers: {
	          "Cache-Control": "no-cache",
	          Accept: "application/json",
	          "Content-Type": "application/json"
	        },
	        data: JSON.stringify({
	          url: encodeURI(videoUrl),
	          vQuality: "max",
	          filenamePattern: "basic",
	          isAudioOnly: audioOnly,
	          disableMetadata: true
	        }),
	        onload: (response) => {
	          const data = JSON.parse(response.responseText);
	          if (data == null ? void 0 : data.url)
	            resolve(data.url);
	          else
	            reject(data);
	        },
	        onerror: (err) => reject(err)
	      });
	    });
	  },
	  elementInContainer: function(container, element) {
	    return container.contains(element);
	  },
	  detectYoutubeService: function() {
	    if (window.location.hostname === "www.youtube.com" && window.location.pathname.startsWith("/shorts"))
	      return "shorts";
	    if (window.location.hostname === "www.youtube.com" && window.location.pathname.startsWith("/watch"))
	      return "watch";
	    else if (window.location.hostname === "music.youtube.com")
	      return "music";
	    else if (window.location.hostname === "www.youtube.com")
	      return "youtube";
	    else
	      return null;
	  },
	  hookNavigationEvents: function() {
	    return __async(this, null, function* () {
	      ["yt-navigate", "yt-navigate-finish", "yt-navigate-finish", "yt-page-data-updated"].forEach((evName) => {
	        if (evName) {
	          document.addEventListener(evName, (e) => {
	            this.appendDownloadButton(e);
	          });
	        }
	      });
	    });
	  },
	  appendDownloadButton: function(e) {
	    return __async(this, null, function* () {
	      try {
	        this.isComplete = false;
	        const ytContainerSelector = "#movie_player > div.ytp-chrome-bottom > div.ytp-chrome-controls > div.ytp-right-controls";
	        const ytmContainerSelector = "#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > div.middle-controls-buttons.style-scope.ytmusic-player-bar";
	        const img = document.createElement("img");
	        img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAepJREFUaEPtmEFygzAMRQ3dsm2mx0kOkfO0OQ+HCL1Np91m29ARtgM0gPUluZ3MmE0miSH//S8Jk8o9+FE9uH5XAP47wZJASUDpQCkhpYHq00sCSxY27ct+/Py6d67u6P3l+DG8Wh5mCXjR369eXDUBuJN78jCfbxYgaoBR+KboJa0nCwgVgBd/PSudVIGIAZp2RyUQSkaJ4JwYQgRgLD7SiyCkAD3P8z5MHW5/1Ad0UsEAgPs3R5v2+ZyYTMGPvrscvw48c8K8QxYD4umyEwCkX7AUoAT+BgBLAQVg1v6QqzCB4SbH1sVeKJj5YgDn+GVkDEBTp3r3fVV3caIE+On2InH/yALAasTkLOf1URYA9rZhFYInft4/qSlpXELx5+4dBMRT+bFvaJkA5pMEHwAZAMhb/h2VVo/zvGl3yPjNM0ZxAA/B20LMKj05CKar2SXkAbYamcQ+DU9b6YMeM1e34vkAtlJA7p7+OotlBYmn60AJJFJg//jaREJNEAEE9yyfxmLFsQ0Q98D0RGyuJ7tCJF6cQJRjBCEWrwbQgfiphT5C/s4SbuK1Yghp0NcbO834jKwXHnWYAcz7I/61OP6tSN9r3V4yLwtAsmUNFxQAQzNFlyoJiGwzPKkkYGim6FIlAZFthic9fAI/mIfoMZ8JBO0AAAAASUVORK5CYII=";
	        img.style.width = "44px";
	        img.style.height = "44px";
	        const markName = this.markName;
	        if (document.querySelector("." + markName))
	          return;
	        const escapeHTMLPolicy = trustedTypes.createPolicy("conardEscapePolicy", {
	          createHTML: (string) => string.replace(/\</g, "&lt;")
	        });
	        const downloadButton = document.createElement("button");
	        downloadButton.id = "ytdl-download-button";
	        downloadButton.classList.add("ytp-button", markName);
	        downloadButton.title = selectLanguage().download.tip;
	        downloadButton.style.borderRadius = "50%";
	        downloadButton.appendChild(img);
	        switch (this.detectYoutubeService()) {
	          case "watch":
	            const ytCont = yield Tools.waitForElementByInterval(ytContainerSelector);
	            if (this.elementInContainer(ytCont, ytCont.querySelector("#ytdl-download-button"))) {
	              break;
	            }
	            const ytDlBtnClone = downloadButton.cloneNode(true);
	            ytDlBtnClone.classList.add("YT");
	            ytDlBtnClone.addEventListener("click", () => {
	              this.download(ytDlBtnClone);
	            });
	            ytCont.insertBefore(ytDlBtnClone, ytCont.firstChild);
	            break;
	          case "shorts":
	            if (!document.querySelector("#navigation-button-download-----iux998htt")) {
	              const navigationButtonDown = document.querySelector("#navigation-button-down");
	              const navigationButtonDownload = navigationButtonDown.cloneNode(false);
	              navigationButtonDownload.id = "navigation-button-download-----iux998htt";
	              navigationButtonDownload.style.textAlign = "center";
	              navigationButtonDownload.appendChild(img);
	              document.querySelector(".navigation-container").appendChild(navigationButtonDownload);
	              navigationButtonDownload.addEventListener("click", () => {
	                this.download(img);
	              });
	            }
	            break;
	          case "music":
	            const ytmCont = yield Tools.waitForElementByInterval(ytmContainerSelector);
	            if (this.elementInContainer(ytmCont, ytmCont.querySelector("#ytdl-download-button"))) {
	              break;
	            }
	            const ytmDlBtnClone = downloadButton.cloneNode(true);
	            ytmDlBtnClone.classList.add("YTM");
	            ytmDlBtnClone.addEventListener("click", () => {
	              this.download(ytmDlBtnClone);
	            });
	            ytmCont.insertBefore(ytmDlBtnClone, ytmCont.firstChild);
	            break;
	          default:
	            return;
	        }
	      } catch (error) {
	      } finally {
	        this.isComplete = true;
	      }
	    });
	  },
	  initStyle: function() {
	    GM_addStyle(`
      @keyframes scriptspin {0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);}}
      .download-loadding{
        animation: scriptspin 1s linear infinite;
      }
    `);
	  },
	  asyncAppendDownloadButton: function() {
	    let allDelay = 1e3 * 30, delay = 250;
	    const interval = setInterval(() => {
	      if (document.querySelector("." + this.markName) || allDelay <= 0) {
	        clearInterval(interval);
	      } else {
	        if (this.isComplete)
	          this.appendDownloadButton();
	      }
	      allDelay -= delay;
	    }, delay);
	  },
	  start: function() {
	    this.initStyle();
	    let currentUrl = null;
	    setInterval(() => {
	      const visitUrl = window.location.href;
	      if (currentUrl !== window.location.href) {
	        currentUrl = window.location.href;
	        const watch = /www\.youtube\.com\/watch\?v=/.test(visitUrl);
	        const shorts = /www\.youtube\.com\/shorts\//.test(visitUrl);
	        const music = /music\.youtube\.com\/watch\?v=/.test(visitUrl);
	        if (watch || shorts || music) {
	          this.hookNavigationEvents();
	          this.asyncAppendDownloadButton();
	        }
	      }
	    }, 500);
	  }
	};

	const AllModules = {
	  X,
	  Youtube: {
	    YoutubeDownload
	  },
	  Tiktok,
	  GoodsHistroy,
	  Aliexpress: {
	    Aliexpress,
	    AliexpressSearch
	  },
	  Ebay,
	  Lazada
	};

	const Init = {
	  x: function() {
	    AllModules.X.XDownload.init();
	    AllModules.X.XSettingsDialog.init();
	    const observer = new MutationObserver((ms) => ms.forEach((m) => {
	      m.addedNodes.forEach((node) => {
	        AllModules.X.XDownload.detect(node);
	        AllModules.X.XDateFormat.repldatetime();
	        AllModules.X.XOrigimg();
	        AllModules.X.XHidepromo();
	      });
	    }));
	    observer.observe(document.body, {
	      childList: true,
	      subtree: true
	    });
	  },
	  aliexpress: function() {
	    AllModules.Aliexpress.Aliexpress.start();
	    AllModules.Aliexpress.AliexpressSearch.start();
	    AllModules.GoodsHistroy.start("aliexpress");
	  },
	  youtube: function() {
	    AllModules.Youtube.YoutubeDownload.start();
	  },
	  ebay: function() {
	    AllModules.GoodsHistroy.start("ebay");
	    AllModules.Ebay.start();
	  },
	  lazada: function() {
	    AllModules.GoodsHistroy.start("lazada");
	    AllModules.Lazada.start();
	  },
	  tiktok: function() {
	    AllModules.Tiktok.start();
	  },
	  unknown: function() {
	  },
	  start: function() {
	    Toast.initStyle();
	    const platform = Tools.platform();
	    this[platform]();
	  }
	};
	Init.start();

}());