// ==UserScript==
// @name YouTube DeBlock
// @description Fully Working 2023 UnBlocker for YouTube. Get rid of that pesky blocker, and return my vids!
// @author YelloNox
// @version 1.1.8
// @created 2023-10-10
// @namespace https://yello.zip
// @homepage https://github.com/YelloNox/YouTube-UnBlock
// @match *://www.youtube.com/*
// @grant none
// ==/UserScript==
(function () {
"use strict";
/* User Customization */
const disableTheaterToggle = false;
const disableReloadToggle = false;
const disableOptionsMenu = false;
var forceEnableEmbed = false;
/* Language INFO: https://github.com/YelloNox/YouTube-UnBlock/blob/main/language.md */
const language = "en";
/* End User Customization */
// Any class the blocker uses
const blockerClass = "ytd-enforcement-message-view-model";
// Any class on the broken video (e.x. yt-playability-error-supported-renderers)
var ogVideoClass = "yt-playability-error-supported-renderers";
if (forceEnableEmbed) {
// Any class of the official video for force replacing
ogVideoClass = "html5-video-player";
}
// Class of the parent for the custom content locaiton
const customContentParentID = "end";
// Original Youtube URL
const youtubeURL = "youtube.com";
// Change to theater mode on load
const changeTheaterOnStart = false;
// Domains to redirect to.
var domainList = [
"youtube.com/embed",
"yout-ube.com",
"piped.kavin.rocks",
"subscriptions.gir.st",
"nsfwyoutube.com", // Disabled (for now)
];
// Does domain include www. (if not, need to remove later)
var domainListUrlStat = [
true, //"youtube.com/embed",
true, //"yout-ube.com",
false, //"piped.kavin.rocks",
false, //"subscriptions.gir.st",
false, //"nsfwyoutube.com",
];
// --- Do Not Touch --- //
var newDomain = domainList[0];
var newDomainListUrlStat = domainListUrlStat[0];
// Temp Functions //
const tempReplaceClass = "replaceme";
let isBlocked = false;
let isSubChange = false;
let isChangingFrame = false;
var updatedURL = window.location.href;
var previousDropdownValue;
// --- Do Not Touch --- //
// -------------- Main Loop Funcitons -------------- //
// Function that checks if the page is even blocked
var theaterStartRunOnce = false;
function checkClass() {
const blockerElement = document.querySelectorAll("." + blockerClass);
const videoElement = document.querySelectorAll("." + ogVideoClass);
if (blockerElement.length > 0) {
isBlocked = true;
console.log("blocked [checkClass]: yes");
}
if (forceEnableEmbed && videoElement.length > 0) {
isBlocked = true;
forceEnableEmbed = false;
console.log("Forcing Unblock");
}
if (isBlocked) {
console.log("Replacing Original [checkClass]");
replaceVideo();
addDomainToURLs();
isBlocked = false;
} else {
// console.log("[checkClass] #2") - Cogs Log
urlTracker();
dropdownTracker();
}
if (changeTheaterOnStart && !theaterStartRunOnce) {
changeTheaterMode(true);
theaterStartRunOnce = true;
}
}
// -------------- Event Listeners -------------- //
// Checks if the url has changed, if so, reload the iframe (thus reloading the video)
function urlTracker() {
var currentURL = window.location.href;
// console.log("Test URL [urlTracker]"); - Cogs Log
if (currentURL != updatedURL) {
console.log("Found New URL");
updatedURL = window.location.href;
if (isSubChange) {
isBlocked = true;
}
}
}
// Checks if the dropdown has changed
function dropdownTracker() {
var dropdown = document.getElementById("dropdown");
if (dropdown) {
changeSelection(dropdown);
}
}
function changeSelection(dropdown) {
try {
dropdown.addEventListener("change", function () {
checkDropdownChange(dropdown);
});
} catch (error) {
console.error("Error [changeSelection]: " + error);
}
}
function checkDropdownChange(dropdown) {
var newValue = dropdown.value;
// Check if the value has actually changed
if (newValue !== previousDropdownValue) {
newDomain = domainList[newValue];
newDomainListUrlStat = domainListUrlStat[newValue];
console.log("Selection Changed [newDomain]: " + newDomain);
console.log(
"Selection Changed [newDomainListUrlStat]: " +
newDomainListUrlStat
);
reloadFrame();
// Update the previousValue variable
previousDropdownValue = newValue;
}
}
// Reload Frame when "Reload Frame" button is clicked
function reloadFrame() {
replaceVideo();
addDomainToURLs();
console.log("clicked [reloadFrame]");
}
// -------------- Checks -------------- //
function appendingFrame(isSet) {
if (isSet == true) {
isChangingFrame = true;
} else {
isChangingFrame = false;
}
console.log("ChangingFrames: " + changingFrame);
}
// -------------- Actions -------------- //
// Remove the *blocker* from the page by locating the class name.
function removeElementsByClassName(removeClass) {
console.log("Removing [removeElementsByClassName]: " + removeClass);
const elements = document.querySelectorAll("." + removeClass);
try {
elements.forEach((element) => {
element.remove();
});
} catch (error) {
console.error(
"Error removing elements [removeElementsByClassName]: " + error
);
}
}
// Checks string and returns if contains matching text
function checkText(string, text) {
console.log("Checking string [checkText]");
return string.includes(text);
}
// Function to replace "youtube.com" with selected domain
function getNewURL(newDomain) {
console.log("New URL [newDomain]: " + newDomain);
const currentURL = window.location.href;
try {
if (currentURL.includes(youtubeURL)) {
var newURL = currentURL.replace(youtubeURL, newDomain);
if (newDomainListUrlStat == false) {
newURL = newURL.replace(/www./g, "");
}
return newURL;
}
} catch (error) {
console.error("Error [newURL]: " + error);
}
}
// Adds "youtube.com" to all nameless urls on webpage
function addDomainToURLs() {
console.log("Adding [addDomainToURLs]");
const links = document.querySelectorAll("a");
try {
links.forEach((link) => {
let href = link.getAttribute("href");
if (
href &&
!href.startsWith("http") &&
!href.startsWith("www")
) {
href = "https://www." + youtubeURL + href;
link.setAttribute("href", href);
}
});
} catch (error) {
console.error("[addDomainToURLs] #1", error);
}
}
// Is it the first video change, or recurring?
function replaceVideo() {
if (!isSubChange) {
console.log("replacing [replaceVideo]");
removeElementsByClassName(blockerClass);
createJFrame(ogVideoClass);
isSubChange = true;
return;
}
if (isSubChange) {
console.log("replacing subclick [replaceVideo]");
removeOgIframe();
createJFrame(tempReplaceClass);
console.log("In with the new [replaceVideo]");
}
isBlocked = false;
}
// Fixes unusable URL(s)
function fixURL(URL) {
const playlistCheck = "&list=";
const watchStamp = "watch?v=";
const timestamp = "&t=";
const isURL = checkText(URL, youtubeURL);
const isPlaylist = checkText(URL, playlistCheck);
const isTimestamp = checkText(URL, timestamp);
console.log(
"isURL:" +
isURL +
" isPlaylist:" +
isPlaylist +
" isTimestamp:" +
isTimestamp
);
console.log("URL [fixURL]:" + URL);
if (isURL) {
URL = URL.replace(watchStamp, "");
console.log("Is Not Playlist [fixURL]: " + URL);
}
if (isURL && isTimestamp) {
URL = URL.split(timestamp)[0];
console.log("\nURL Split Timestamp Fix [fixURL]: " + URL);
}
if (isPlaylist) {
URL = URL.split(playlistCheck)[0];
console.log("\nURL Split Playlist Fix [fixURL]: " + URL);
}
return URL;
}
// Fixes webpage address
function fixPage() {
var tmpURL = window.location.href;
const playlistCheck = "&list=";
const isBrokePlaylist = checkText(tmpURL, playlistCheck);
if (isBrokePlaylist) {
printAlert(0);
var regex = /(&list)\D+\d+/g;
console.log("URL Fix Original: [fixPage]: " + tmpURL);
tmpURL = tmpURL.replace(regex, "");
console.log("URL Fix New: [fixPage]: " + tmpURL);
window.location.href = tmpURL;
}
}
var theaterModeToggle = true;
function toggleTheater() {
if (theaterModeToggle) {
console.log("Changing Mode [toggleTheater]: Off");
theaterModeToggle = false;
} else {
console.log("Changing Mode [toggleTheater]: On");
theaterModeToggle = true;
}
changeTheaterMode(theaterModeToggle);
}
// Thanx https://stackoverflow.com/questions/53584026/toggle-the-cinema-mode-on-youtube-with-javascript :>
function changeTheaterMode(state) {
try {
const collection = document.getElementsByTagName("ytd-watch-flexy");
const ytd_watch_flexy = collection.item(0);
if (!ytd_watch_flexy) {
console.error("No ytd-watch-flexy Found[changeTheaterMode]");
return;
}
if (state) {
ytd_watch_flexy.theater = true;
console.log("Theater On [changeTheaterMode]");
} else {
ytd_watch_flexy.theater = false;
console.log("Theater Off [changeTheaterMode]");
}
} catch (error) {
console.error("Theater-Mode Error [changeTheaterMode]: " + error);
}
}
// -------------- JFrame Control -------------- //
// Create video embedding frame
function createJFrame(classToOverturn) {
var newURL = getNewURL(newDomain);
const elements = document.querySelectorAll("." + classToOverturn);
console.log("newURL Beginning [createJFrame]: " + newURL);
fixPage();
newURL = fixURL(newURL);
try {
const firstElement = elements[0]; // Get the first element in the array -> trying to prevent duplicate videos
if (firstElement) {
const iframe = document.createElement("iframe");
iframe.width = "100%";
iframe.height = "100%";
iframe.src = newURL;
iframe.allow =
"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
// autoplay: ^ (autoplay removed after bug; also never worked anyhow)
iframe.allowFullscreen = true;
iframe.zIndex = "9999";
firstElement.parentNode.replaceChild(iframe, firstElement);
console.log("Modified URL:", newURL);
}
} catch (error) {
console.error("Error creating iframe [createJFrame]: " + error);
}
}
// Removes the original video frame.
function removeOgIframe() {
const iframes = document.querySelectorAll("iframe");
console.log("removing jFrame [removeOgIframe]");
try {
iframes.forEach((iframe) => {
const paragraph = document.createElement("p");
paragraph.className = tempReplaceClass;
iframe.parentNode.insertBefore(paragraph, iframe);
iframe.remove();
console.log("Out with the old [removeOgIframe]");
});
} catch (error) {
console.error("Error [removeOgIframe]: " + error);
}
}
// -------------- Experimental Features (unused) -------------- //
// Save dropdown selection to local storage
function dropdownStore() {
try {
rememberButton.addEventListener("click", function () {
localStorage.setItem("selectedOption", dropdown.value);
console.log("Selection Stored");
});
} catch (error) {
console.error("Error [dropdownStore]: " + error);
}
}
// -------------- Language Information -------------- //
// xtxt is for the type of text needed (i.e. dropdown / theater mode button / ect...) for the main category of text.
// vers is the item in the container (i.e. dropdown: youtube, yout-ube) for multiple subtexts.
// top tier explination!
function getText(xtxt, vers) {
const translations = {
en: {
theaterMode: ["Theater"],
reloadFrame: ["Reload Frame"],
dropdown: [
"YouTube™ [Embed]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
de: {
theaterMode: ["Theater"],
reloadFrame: ["Rahmen neu laden"],
dropdown: [
"YouTube™ [Einbetten]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
es: {
theaterMode: ["Teatro"],
reloadFrame: ["Recargar Marco"],
dropdown: [
"YouTube™ [Incrustar]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
fr: {
theaterMode: ["Théâtre"],
reloadFrame: ["Recharger le Cadre"],
dropdown: [
"YouTube™ [Intégrer]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
it: {
theaterMode: ["Teatro"],
reloadFrame: ["Ricarica Cornice"],
dropdown: [
"YouTube™ [Incorpora]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
jp: {
theaterMode: ["劇場"],
reloadFrame: ["フレームを再読み込み"],
dropdown: [
"YouTube™ [埋め込み]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
ko: {
theaterMode: ["극장"],
reloadFrame: ["프레임 다시 로드"],
dropdown: [
"YouTube™ [임베드]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
nl: {
theaterMode: ["Theater"],
reloadFrame: ["Frame Herladen"],
dropdown: [
"YouTube™ [Insluiten]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
pl: {
theaterMode: ["Teatr"],
reloadFrame: ["Przeładuj Ramkę"],
dropdown: [
"YouTube™ [Osadź]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
pt: {
theaterMode: ["Teatro"],
reloadFrame: ["Recarregar Quadro"],
dropdown: [
"YouTube™ [Embutir]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
ru: {
theaterMode: ["Театр"],
reloadFrame: ["Перезагрузить Рамку"],
dropdown: [
"YouTube™ [Вставить]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
ar: {
theaterMode: ["مسرح"],
reloadFrame: ["إعادة تحميل الإطار"],
dropdown: [
"YouTube™ [تضمين]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
zh: {
theaterMode: ["剧院"],
reloadFrame: ["重新加载框架"],
dropdown: [
"YouTube™ [嵌入]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
hi: {
theaterMode: ["रंगमंच"],
reloadFrame: ["फ्रेम पुनः लोड करें"],
dropdown: [
"YouTube™ [एम्बेड करें]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
sv: {
theaterMode: ["Teater"],
reloadFrame: ["Ladda om Ramen"],
dropdown: [
"YouTube™ [Bädda in]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
no: {
theaterMode: ["Teater"],
reloadFrame: ["Last Inn Rammen på Nytt"],
dropdown: [
"YouTube™ [Bygg inn]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
da: {
theaterMode: ["Teater"],
reloadFrame: ["Genindlæs Rammen"],
dropdown: [
"YouTube™ [Vložit]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
cs: {
theaterMode: ["Divadlo"],
reloadFrame: ["Rámeček znovu načíst"],
dropdown: [
"YouTube™ [Vložit]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
hu: {
theaterMode: ["Színház"],
reloadFrame: ["Keret Újratöltése"],
dropdown: [
"YouTube™ [Beágyazás]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
tr: {
theaterMode: ["Tiyatro"],
reloadFrame: ["Çerçeveyi Yeniden Yükle"],
dropdown: [
"YouTube™ [Gömme]",
"yout-ube",
"kavin.rocks",
"gir.st",
],
},
};
const languageTranslations = translations[language];
return languageTranslations && languageTranslations[xtxt]
? languageTranslations[xtxt][vers]
: undefined;
}
// alertT is the alert type (i.e. invalid page...)
function printAlert(alertT) {
const translations = {
en: {
0: [
"Oops! Something went wrong.\n\n- Issue: The playlist feature is currently not working.\n- Action: You will be redirected to a static page shortly.\n\nI am looking for a fix.",
],
},
de: {
0: [
"Hoppla! Etwas ist schief gelaufen.\n\n- Problem: Die Playlist-Funktion funktioniert derzeit nicht.\n- Aktion: Sie werden in Kürze auf eine Standardseite umgeleitet.\n\nIch suche nach einer Lösung.",
],
},
es: {
0: [
"¡Vaya! Algo salió mal.\n\n- Problema: La función de lista de reproducción no está funcionando actualmente.\n- Acción: Serás redirigido a una página estándar en breve.\n\nEstoy buscando una solución.",
],
},
fr: {
0: [
"Oups ! Un problème est survenu.\n\n- Problème : La fonction de playlist ne fonctionne pas actuellement.\n- Action : Vous serez redirigé vers une page standard sous peu.\n\nJe cherche une solution.",
],
},
it: {
0: [
"Ops! Qualcosa è andato storto.\n\n- Problema: La funzione playlist non sta funzionando al momento.\n- Azione: Sarai reindirizzato a una pagina standard a breve.\n\nSto cercando una soluzione.",
],
},
jp: {
0: [
"おっと!何かが間違っていました。\n\n- 問題:プレイリスト機能は現在動作していません。\n- 処置:間もなく標準ページにリダイレクトされます。\n\n修正を探しています。",
],
},
ko: {
0: [
"이런! 문제가 발생했습니다.\n\n- 문제: 플레이리스트 기능이 현재 작동하지 않습니다.\n- 조치: 곧 표준 페이지로 리디렉션됩니다.\n\n해결책을 찾고 있습니다.",
],
},
nl: {
0: [
"Oeps! Er is iets misgegaan.\n\n- Probleem: De afspeellijstfunctie werkt momenteel niet.\n- Actie: Je wordt binnenkort omgeleid naar een standaardpagina.\n\nIk ben op zoek naar een oplossing.",
],
},
pl: {
0: [
"Ups! Coś poszło nie tak.\n\n- Problem: Funkcja listy odtwarzania obecnie nie działa.\n- Działanie: Wkrótce zostaniesz przekierowany na standardową stronę.\n\nSzukam rozwiązania.",
],
},
pt: {
0: [
"Ops! Algo deu errado.\n\n- Problema: A função de playlist atualmente não está funcionando.\n- Ação: Você será redirecionado para uma página padrão em breve.\n\nEstou procurando uma solução.",
],
},
ru: {
0: [
"Ой! Что-то пошло не так.\n\n- Проблема: В настоящее время функция плейлиста не работает.\n- Действие: Скоро вы будете перенаправлены на стандартную страницу.\n\nЯ ищу решение.",
],
},
ar: {
0: [
"عفوًا! هناك خطأ ما.\n\n- المشكلة: ميزة قائمة التشغيل لا تعمل حاليًا.\n- الإجراء: ستتم إعادتك إلى صفحة قياسية قريبًا.\n\nأبحث عن حل.",
],
},
zh: {
0: [
"哎呀!出了点问题。\n\n- 问题:播放列表功能目前无法使用。\n- 操作:您将很快被重定向到标准页面。\n\n我正在寻找解决方案。",
],
},
hi: {
0: [
"उफ! कुछ गलत हो गया।\n\n- समस्या: प्लेलिस्ट सुविधा वर्तमान में काम नहीं कर रही है।\n- कार्रवाई: आपको जल्द ही एक मानक पृष्ठ पर अनुप्रेषित किया जाएगा।\n\nमैं एक समाधान ढूँढ रहा हूँ।",
],
},
sv: {
0: [
"Oops! Något gick fel.\n\n- Problem: Spellistefunktionen fungerar inte för närvarande.\n- Åtgärd: Du kommer att omdirigeras till en standard sida inom kort.\n\nJag letar efter en lösning.",
],
},
no: {
0: [
"Oisann! Noe gikk galt.\n\n- Problem: Spillelistefunksjonen virker ikke for øyeblikket.\n- Handling: Du vil bli omdirigert til en standardside snart.\n\nJeg ser etter en løsning.",
],
},
da: {
0: [
"Ups! Noget gik galt.\n\n- Problem: Afspilningsliste funktionen virker ikke i øjeblikket.\n- Handling: Du vil snart blive omdirigeret til en standard side.\n\nJeg leder efter en løsning.",
],
},
cs: {
0: [
"Jejda! Něco se pokazilo.\n\n- Problém: Funkce playlistu momentálně nefunguje.\n- Akce: Brzy budete přesměrováni na standardní stránku.\n\nHledám řešení.",
],
},
hu: {
0: [
"Hoppá! Valami hiba történt.\n\n- Probléma: A lejátszási lista funkció jelenleg nem működik.\n- Teendő: Hamarosan egy szabványos oldalra lesz átirányítva.\n\nMegoldást keresek.",
],
},
tr: {
0: [
"Oops! Bir şeyler yanlış gitti.\n\n- Sorun: Oynatma listesi özelliği şu anda çalışmıyor.\n- Eylem: Yakında standart bir say",
],
},
};
const languageTranslations = translations[language];
alert(languageTranslations[alertT]);
}
// -------------- Custom HTML Start -------------- //
// Custom CSS
var css = `
.btn-style {
position: relative;
display: inline-block;
padding: 9px;
height: 40px;
color: white;
background-color: transparent;
box-shadow: none;
text-shadow: none;
border: 1px solid white;
border-radius: 0px;
z-index: 9999;
opacity: 100%;
transition: transform 0.3s ease;
user-select: none;
}
.btn-style:hover {
opacity: 80%;
}
.main-btn {
margin-right: 16px;
transition: transform 0.1s ease;
}
.main-btn:active {
border: 1px solid transparent !important;
transform: scale(0.9);
}
.dropdown-content {
position: relative;
background-color: black;
}
.custom-container {
border: none;
display: inline-block;
margin-right: 16px;
margin-left: 16px;
transition: transform 0.3s ease;
}
`;
var ranCustomContentOnce = false;
function customContent() {
// Create Container
var customContainer = document.createElement("div");
customContainer.classList.add("custom-container");
/* Not Complete */
// Create Button Theater Mode
var theaterButton = document.createElement("button");
theaterButton.textContent = getText("theaterMode", 0);
theaterButton.classList.add("btn-style", "main-btn");
/**/
// Create Button Reload
var reloadButton = document.createElement("button");
reloadButton.textContent = getText("reloadFrame", 0);
reloadButton.classList.add("btn-style", "main-btn");
// Create Dropdown Menu
var dropdownButton = document.createElement("select");
dropdownButton.id = "dropdown";
dropdownButton.classList.add("btn-style");
const options = [
{ value: "0", text: getText("dropdown", 0) },
{ value: "1", text: getText("dropdown", 1) },
{ value: "2", text: getText("dropdown", 2) },
{ value: "3", text: getText("dropdown", 3) },
//{ value: "4", text: "NSFW YouTube [Broken!]" } Fix later?
];
var htmlContent = options
.map(
(option) =>
`<option class="dropdown-content" value="${option.value}">${option.text}</option>`
)
.join("");
dropdownButton.innerHTML = htmlContent;
// -------------- Custom HTML End -------------- //
// ----- Appending custom content to page ----- //
// Add items to Container
if (!disableTheaterToggle) {
customContainer.appendChild(theaterButton);
}
if (!disableReloadToggle) {
customContainer.appendChild(reloadButton);
}
if (!disableOptionsMenu) {
customContainer.appendChild(dropdownButton);
}
// Append CSS to page
var style = document.createElement("style");
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);
// Find ID Location
var exsistingParent = document.getElementById(customContentParentID);
console.log("Found exsistingParent: " + exsistingParent);
// Add Container to Page
if (exsistingParent != null) {
exsistingParent.insertBefore(
customContainer,
exsistingParent.firstChild
);
console.log("Added customContainer to page");
} else {
console.error("Error [customContent]: No exsistingParent found");
}
theaterButton.addEventListener("click", toggleTheaterStingyWorkaround);
reloadButton.addEventListener("click", reloadFrame);
ranCustomContentOnce = true;
}
try {
if (!ranCustomContentOnce) {
customContent();
console.log("Loaded [customContent]");
} else {
console.log(
"Tried to load, but was allready loaded [customContent]"
);
}
} catch (error) {
console.error("Error [customContent]: " + error);
}
// -------------- Active Listeners -------------- //
// Run every second to check for updates on page (Will not ping any server till a new page is clicked)
try {
window.setInterval(checkClass, 1000);
} catch (error) {
console.error("Error Running [window.setInterval]: " + error);
}
try {
document.addEventListener("click", checkClass, 1000);
} catch (error) {
console.error("Error Running [document.addEventListener]: " + error);
}
// ------------- Passive Listeners ------------- //
// Fullscreen Toggle
function toggleTheaterStingyWorkaround() {
const event = new KeyboardEvent("keydown", {
key: "t",
keyCode: 84,
});
document.dispatchEvent(event);
location.reload();
}
})();