Free Tools: Pastebin.xyz Private Pastebin
101 Hits total
c Language
23.695 Author
close

Untitled

This is a quick overview of some features

  1. // ==UserScript==
  2. // @name         Tinychat Enhancement Suite (TES)
  3. // @namespace    https://greasyfork.org/en/users/80816-james-koss
  4. // @version      2019.09.04v135
  5. // @description  Fixes some Tinychat room shortcomings and adds useful features.
  6. // @author       MutationObserver, phuein, legend
  7. // @match        https://tinychat.com/room/*
  8. // @match        https://tinychat.com/*
  9. // @exclude      https://tinychat.com/room/*?1
  10. // @exclude      https://tinychat.com/settings/*
  11. // @exclude      https://tinychat.com/subscription/*
  12. // @exclude      https://tinychat.com/promote/*
  13. // @exclude      https://tinychat.com/gifts
  14. // @exclude      https://tinychat.com/home
  15. // @grant        GM_setValue
  16. // @grant        GM_getValue
  17. // @grant        GM_listValues
  18.  
  19. // ==/UserScript==
  20. /* jshint -W097 */
  21.  
  22. TESwsParser ``;
  23. var waitingForDom = 0;
  24. var initInterval = setInterval(function () {
  25.     if (document.querySelector("tinychat-webrtc-app") && document.querySelector("tinychat-webrtc-app").shadowRoot) TESapp = runTES ``;
  26.     else if(waitingForDom < 3) {
  27.         tcl("Waiting for DOM...");
  28.         waitingForDom += 1;
  29.     }
  30. }, 500);
  31.  
  32. function triggerMouseEvent(node, eventType) {
  33.     var mouseEvent = document.createEvent('MouseEvent');
  34.     mouseEvent.initMouseEvent(eventType, true, true);
  35.     node.dispatchEvent(mouseEvent);
  36. }
  37.  
  38. function runTES() {
  39.     clearInterval(initInterval);
  40.     try {
  41.         /* Begin main function */
  42.         var tinychat = TinychatApp.getInstance();
  43.         var packetWorker = tinychat.defaultChatroom.packetWorker;
  44.         var userlist = tinychat.defaultChatroom.userlist;
  45.  
  46.         // packetWorker.tcSocket.chatRoom._chatlog.chatroom._videolist.needToBlurOtherVids = false;
  47.         packetWorker.tcSocket.chatRoom._chatlog.chatroom._videolist.blurOtherVids = function () {};
  48.  
  49.         var bodyElem = document.querySelector("body");
  50.  
  51.         bodyElem.style.overflow = "hidden"; // NOTE: Any issues with this??
  52.  
  53.         var webappOuter = document.querySelector("tinychat-webrtc-app");
  54.         var webappElem = webappOuter.shadowRoot;
  55.         var chatlogElem = webappElem.querySelector("tc-chatlog").shadowRoot;
  56.         var titleElem = webappElem.querySelector("tc-title").shadowRoot;
  57.         var sidemenuElem = webappElem.querySelector("tc-sidemenu").shadowRoot;
  58.         var videomoderationElem = sidemenuElem.querySelector("tc-video-moderation").shadowRoot;
  59.         var videolistElem = webappElem.querySelector("tc-videolist").shadowRoot;
  60.  
  61.         var chatlistElem = sidemenuElem.querySelector("tc-chatlist").shadowRoot;
  62.         var userlistElem = sidemenuElem.querySelector("tc-userlist").shadowRoot;
  63.         var userContextmenuElem = userlistElem.querySelector("tc-user-contextmenu").shadowRoot;
  64.  
  65.         var chatlogCSS = chatlogElem.querySelector("#chat-wrapper");
  66.         var sidemenuCSS = sidemenuElem.querySelector("#sidemenu");
  67.         var videomoderationCSS = videomoderationElem.querySelector("#moderatorlist");
  68.         var webappCSS = webappElem.querySelector("#room");
  69.         var chatlistCSS = chatlistElem.querySelector("#chatlist");
  70.         var userlistCSS = userlistElem.querySelector("#userlist");
  71.         var userContextmenuCSS = userContextmenuElem.querySelector("#main");
  72.         var titleCSS = titleElem.querySelector("#room-header");
  73.         var videolistCSS = videolistElem.querySelector("#videolist");
  74.         var bodyCSS = document.querySelector("body");
  75.  
  76.         var userinfoCont = sidemenuElem.querySelector("#user-info > div");
  77.         var scrollbox = chatlogElem.querySelector("#chat");
  78.         var unreadbubble = chatlogElem.querySelector("#input-unread");
  79.  
  80.         var resourceDirectory = document.querySelector('link[rel="manifest"]').getAttribute("href").split("manifest")[0]; // /([d.-])+/
  81.         var audioPop = new Audio(resourceDirectory + 'sound/pop.mp3');
  82.         var settingMentions = [];
  83.         var settingIgnoredUsers = [];
  84.         var settingBannedUsers = [];
  85.         var giftsElemWidth = 127;
  86.         var messageHeight;
  87.         var chatboxHeight;
  88.         var totalScrolledUp = 0;
  89.         var freshInstall = (GM_listValues().length == 0);
  90.         var isModerator = (!userlistElem.querySelector("#button-banlist").classList.contains("hidden"));
  91.         var isPaidAccount = (sidemenuElem.querySelector("#sidemenu-wider"));
  92.  
  93.         var browserFirefox = navigator.userAgent.includes("Firefox/");
  94.         var urlAddress = new URL(window.location.href);
  95.         var urlPars = urlAddress.searchParams;
  96.         var modder = 'memes'
  97.  
  98.         var messageQueryString = "#chat-content .message";
  99.         var camQueryString = ".videos-items > div:not([id='youtube'])";
  100.  
  101.         var userCount = 0;
  102.         var messageCount = 0;
  103.         var camMaxedCurrent = null;
  104.         //var autoScrollStatus = true;
  105.         //var userScrolledChat = false;
  106.         var roomName = webappOuter.getAttribute("roomname");
  107.         var joinTime = getFormattedDateTime(new Date(), "time");
  108.         var joinDate = getFormattedDateTime(new Date());
  109.         var myNick;
  110.         var updBaLi = ()=>{tinychat.defaultChatroom.Banlist(()=>{})}
  111.         var BaLi = ()=>{return tinychat.defaultChatroom.banlist};
  112.         var unB = (a)=>{packetWorker.send(tinychat.defaultChatroom.tcPkt_Unban(a.id, ()=>{}))};
  113.  
  114.         // Remember ignored users.
  115.         var manuallyIgnored = GM_getValue("manuallyIgnored") || [];
  116.         // Ignore from saved list.
  117.         setTimeout(()=>{
  118.             for (let i=0; i < userlist.items.length; i++) {
  119.                 let u = userlist.items[i];
  120.                 let nick = u.nickname;
  121.                 let username = u.username;
  122.  
  123.                 ignoreFromManualList(username, nick);
  124.             }
  125.         }, 2000)
  126.  
  127.         var ignoreOriginal = userlist.ignore;
  128.         userlist.ignore = function() {
  129.             let a = arguments[0];
  130.             let b = a.isUsername ? a.username : a.nickname;
  131.             b = b.toUpperCase();
  132.  
  133.             ignoreOriginal.apply(this, arguments);
  134.  
  135.             let i = manuallyIgnored.indexOf(b);
  136.             // Add ignored.
  137.             if (userlist.isIgnored(a) && i === -1) {
  138.                 manuallyIgnored.push(b);
  139.                 GM_setValue("manuallyIgnored", manuallyIgnored);
  140.                 //console.log('added to TES ignored list: ' + b)
  141.             }
  142.         }
  143.  
  144.         var unignoreOriginal = userlist.unignore;
  145.         userlist.unignore = function() {
  146.             let a = arguments[0];
  147.             let b = a.isUsername ? a.username : a.nickname;
  148.             b = b.toUpperCase();
  149.  
  150.             unignoreOriginal.apply(this, arguments);
  151.  
  152.             let i = manuallyIgnored.indexOf(b);
  153.             // Remove unignored.
  154.             if (!userlist.isIgnored(a) && i > -1) {
  155.                 manuallyIgnored.splice(i);
  156.                 GM_setValue("manuallyIgnored", manuallyIgnored);
  157.                 //console.log('removed from TES ignored list: ' + b)
  158.             }
  159.         }
  160.  
  161.         var showToast = tinychat.defaultChatroom.app.showToast;
  162.         function ignoreFromManualList(username, nick) {
  163.             let u = userlist.getByNickname(nick);
  164.  
  165.             username = username.toUpperCase();
  166.             nick = nick.toUpperCase();
  167.  
  168.             let i = manuallyIgnored.indexOf(username);
  169.             let j = manuallyIgnored.indexOf(nick);
  170.  
  171.             // Always ignore by username, but only ignore nickname if there is no username.
  172.             if (i > -1 || (j > -1 && !username)) {
  173.                 // Temporary disable the annoying toast popup notification.
  174.                 tinychat.defaultChatroom.app.showToast = ()=>{};
  175.                 userlist.ignore(u);
  176.                 tinychat.defaultChatroom.app.showToast = showToast;
  177.                 tcl('Autoignoring ' + nick + ' (' + username + ')')
  178.             }
  179.         }
  180.  
  181.         document.title = roomName + " - Tinychat";
  182.         declareGlobalVars();
  183.         var settingsWaitInterval = setInterval(waitForSettings, 1000);
  184.  
  185.         injectCSS();
  186.         injectElements();
  187.  
  188.         if (userinfoCont.hasAttribute("title")) {
  189.             bodyCSS.classList.add("logged-in");
  190.             sidemenuElem.querySelector("#sidemenu").classList.add("logged-in");
  191.         }
  192.         if (isModerator) {
  193.             userlistElem.querySelector("#userlist").classList.add("tes-mod");
  194.             chatlistElem.querySelector("#chatlist").classList.add("tes-mod");
  195.         }
  196.  
  197.         // Add open-mic option by pressing middle-mouse button on mic button.
  198.         var talkBtn = videolistElem.querySelector("#videos-footer-push-to-talk");
  199.         talkBtn.addEventListener("mousedown", function (e) {
  200.             if (e.which == 2) {
  201.                 e.preventDefault();
  202.                 e.stopPropagation();
  203.                 triggerMouseEvent(talkBtn, "mousedown");
  204.             }
  205.         });
  206.         // Ignore further events relating to this click.
  207.         talkBtn.addEventListener("mouseup", function (e) {
  208.             if (e.which == 2) {
  209.                 e.preventDefault();
  210.                 e.stopPropagation();
  211.             }
  212.         });
  213.         talkBtn.addEventListener("click", function (e) {
  214.             if (e.which == 2) {
  215.                 e.preventDefault();
  216.                 e.stopPropagation();
  217.             }
  218.         });
  219.         // Add instructions in title (tooltip.)
  220.         talkBtn.setAttribute("title", "Wheel-Click to talk freely.");
  221.  
  222.         // Add talking tracking.
  223.         setInterval(function () {
  224.             for (let i = 0; i < 12; i++) {
  225.                 try {
  226.                     let audioLevel = packetWorker.tcSocket.chatRoom._chatlog.chatroom._videolist.items[i].audiolevel;
  227.                     let nick = packetWorker.tcSocket.chatRoom._chatlog.chatroom._videolist.items[i].userentity.nickname;
  228.                     let indicator = videolistElem.querySelector('div#videolist > div#videos-content > div#videos > div.videos-items:last-child > div#camUser-' + nick +
  229.                         ' > tc-video-item').shadowRoot.querySelector('div.video > div > div.overlay > .icon-tes-talking');
  230.  
  231.                     indicator.style.opacity = audioLevel;
  232.                 } catch (e) {
  233.                     // pass
  234.                 }
  235.             }
  236.         }, 250);
  237.  
  238.         // Track chat input box.
  239.         var inputBox = chatlogCSS.querySelector('div#chat-position > form#input > textarea');
  240.  
  241.         var advert = "BIG CAMS - MIC INDICATOR - OPENMIC - ANTISPAM: https://greasyfork.org/en/scripts/389657-tinychat-enhancement-suite-tes";
  242.         var discord = "don't lose contact with your chat friends https://discord.gg/Me4xZ5W 50+ chatters in server, cause we all get banned sometimes";
  243.         var inputBoxHeight = inputBox.clientHeight;
  244.         //var lastInputBoxHeight = inputBoxHeight;
  245.  
  246.         inputBox.onkeyup = function(e) {
  247.             if (inputBox.value === '') {
  248.                 // Restore height if text deleted.
  249.                 inputBox.style.height = inputBoxHeight + "px";
  250.  
  251.                 // Catch up if autoscrolling, after msg sent.
  252.                 /*if (autoScrollStatus === true && settingsQuick["Autoscroll"]) {
  253.                     updateScroll();
  254.                 }*/
  255.             }
  256.  
  257.             // Advertise the extension.
  258.             if (inputBox.value === '/ad') {
  259.                 inputBox.value = advert;
  260.                 return;
  261.             }
  262.  
  263.             // Advertise the discord.
  264.             if (inputBox.value === '/discord') {
  265.                 inputBox.value = discord;
  266.                 return;
  267.             }
  268.  
  269.             // Clean manual-ignore list.
  270.             if (inputBox.value === '/ignores') {
  271.                 inputBox.value = '';
  272.  
  273.                 GM_setValue("manuallyIgnored", []);
  274.                 manuallyIgnored = [];
  275.                 return;
  276.             }
  277.  
  278.             // Kick all users.
  279.             if (inputBox.value === '/nuke') {
  280.                 inputBox.value = '';
  281.  
  282.                 if (!tinychat.defaultChatroom.isOperator()) return;
  283.  
  284.                 try {
  285.                     for (let i=0; i < userlist.items.length; i++) {
  286.                         let user = userlist.items[i];
  287.  
  288.                         if (user.isOperator) continue;
  289.  
  290.                         userlist.kick(user);
  291.                     }
  292.                 } catch(e) { console.log('autokicker nuke:', e);}
  293.  
  294.                 return;
  295.             }
  296.  
  297.             // Unban all users.
  298.             if (inputBox.value === '/clear') {
  299.                 inputBox.value = '';
  300.  
  301.                 if (!tinychat.defaultChatroom.isOperator()) return;
  302.  
  303.                 try {
  304.                     // Update and clear banlist.
  305.                     updBaLi();
  306.  
  307.                     setTimeout(() => {
  308.                         let bl = BaLi();
  309.  
  310.                         for (let i=0; i < bl.length; i++) {
  311.                             let user = bl[i];
  312.                             unB(user);
  313.                         }
  314.  
  315.                         console.log("Done clearing the banlist!");
  316.                     }, 2000);
  317.                 } catch(e) { console.log('clear banlist:', e);}
  318.  
  319.                 return;
  320.             }
  321.         };
  322.  
  323.         var settingsQuick = {
  324.             "RememberIgnore": (GM_getValue("tes-RememberIgnore") == "true" || GM_getValue("tes-RememberIgnore") == undefined),
  325.             "MentionsMonitor": (GM_getValue("tes-MentionsMonitor") == "true" || GM_getValue("tes-MentionsMonitor") == undefined),
  326.             "NotificationsOff": (GM_getValue("tes-NotificationsOff") == "true"),
  327.             "ChangeFont": (GM_getValue("tes-ChangeFont") == "true" || GM_getValue("tes-ChangeFont") == undefined),
  328.             "NightMode": (GM_getValue("tes-NightMode") == "true"),
  329.             "NightModeBlack": (GM_getValue("tes-NightModeBlack") == "true" || GM_getValue("tes-NightModeBlack") == undefined),
  330.             "MaxedCamLeft": (GM_getValue("tes-MaxedCamLeft") == "true" || GM_getValue("tes-MaxedCamLeft") == undefined),
  331.             "BorderlessCams": (GM_getValue("tes-BorderlessCams") == "true"),
  332.             "HideNewCams": (GM_getValue("tes-HideNewCams") == "true"),
  333.             "Ignored": (GM_getValue("tes-Ignored") == "true"),
  334.             "IgnoredMonitor": (GM_getValue("tes-IgnoredMonitor") == "true" || GM_getValue("tes-IgnoredMonitor") == undefined),
  335.             "Banned": (GM_getValue("tes-Banned") == "true"),
  336.             "BannedMonitor": (GM_getValue("tes-BannedMonitor") == "true" || GM_getValue("tes-BannedMonitor") == undefined),
  337.             "ToggleHiddenMsgs": (GM_getValue("tes-ToggleHiddenMsgs") == "true" || GM_getValue("tes-ToggleHiddenMsgs") == undefined),
  338.         };
  339.         if (settingsQuick["ChangeFont"]) bodyElem.classList.add("tes-changefont");
  340.         if (settingsQuick["NightMode"]) nightmodeToggle(true);
  341.         if (settingsQuick["MaxedCamLeft"]) videolistCSS.classList.add("tes-leftcam");
  342.         if (settingsQuick["BorderlessCams"]) borderlessCamsToggle(true);
  343.  
  344.         if (browserFirefox && 1 == 2) {
  345.             titleElem.querySelector("#room-header-info").insertAdjacentHTML("afterend", `
  346.         <div id="tes-firefoxwarning" class="style-scope tinychat-title"
  347.         style="font-size: .75em; background: white; color: grey; width: 200px; padding: 5px; line-height: 13px;vertical-align: middle;border: #ddd 1px solid;border-width: 0px 1px 0px 1px;">
  348.                 <div class="style-scope tinychat-title" style="display: table;height: 100%;">
  349.                         <span style="display: table-cell; vertical-align: middle;top: 16%;" class="style-scope tinychat-title">
  350.                         Tinychat Enhancement Suite requires Chrome. Other browsers only have autoscroll & cam maxing.
  351.                         </span>
  352.                 </div>
  353.         </div>
  354.         `);
  355.         }
  356.  
  357.         function waitForSettings() {
  358.             try {
  359.                 settingsVisible = false;
  360.                 if (titleElem.querySelector("#room-header-gifts") != null) {
  361.                     clearInterval(settingsWaitInterval);
  362.  
  363.                     giftsElemWidth = titleElem.querySelector("#room-header-gifts").offsetWidth;
  364.                     if (titleElem.querySelector("#room-header-gifts-items") == null) {
  365.                         giftsElemWidth1000 = giftsElemWidth + 45;
  366.                     } else {
  367.                         giftsElemWidth1000 = giftsElemWidth;
  368.                     }
  369.                     if (titleCSS.querySelector("#titleCSS")) {
  370.                         titleCSS.querySelector("#titleCSS").innerHTML += `
  371.                                 #tes-settings {
  372.                                         right: ` + giftsElemWidth + `px;
  373.                                 }
  374.                         `;
  375.                     }
  376.  
  377.                     var sidemenuFakeBorder = document.createElement("span");
  378.                     sidemenuFakeBorder.setAttribute("id", "tes-sidemenufakeborder");
  379.                     sidemenuCSS.insertAdjacentElement("beforeend", sidemenuFakeBorder);
  380.  
  381.                     settingsElem = titleElem.querySelector("#room-header-gifts").insertAdjacentHTML("beforebegin", `
  382.                 <div id="tes-settings">
  383.                         <div id="tes-settingsBox" class="hidden">
  384.                                 <p id="title"><a href="https://greasyfork.org/en/scripts/32964-tinychat-enhancement-suite" target="_blank">Tinychat Enhancement Suite</a></p>
  385.                                 <div id="tes-settings-mentions" class="tes-setting-container">
  386.                                         <input type="checkbox">
  387.                                         <span class="label">
  388.                                                 Alert phrases
  389.                                                 <span class="info" data-title='A comma-separated list of phrases to alert/highlight for. Example of 3 phrases: "hello, Google Chrome, sky"'>?</span>
  390.                                         </span>
  391.                                         <div class="inputcontainer">
  392.                                                 <input class="text" placeholder="enter alert phrases here"><button class="save blue-button">save</button>
  393.                                         </div>
  394.                                 </div>
  395.                                 <div id="tes-settings-rememberignore" class="tes-setting-container" style="display: none;">
  396.                                         <input type="checkbox">
  397.                                         <span class="label">
  398.                                                 Remember Ignore
  399.                                         </span>
  400.                                 </div>
  401.                                 <div id="tes-settings-notifications" class="tes-setting-container">
  402.                                         <input type="checkbox">
  403.                                         <span class="label">
  404.                                                 Hide notifications
  405.                                         </span>
  406.                                 </div>
  407.                                 <div id="tes-settings-changefont" class="tes-setting-container">
  408.                                         <input type="checkbox">
  409.                                         <span class="label">
  410.                                                 Improve font
  411.                                                 <span class="info" data-title='The default font is too thin in some browsers'>?</span>
  412.                                         </span>
  413.                                 </div>
  414.                                 <div id="tes-settings-nightmode" class="tes-setting-container">
  415.                                         <input type="checkbox">
  416.                                         <span class="label">
  417.                                                 Night mode
  418.                                         </span>
  419.                                         <span id="black" class="colorCont"><input type="radio" class="nightmode-colors"><span class="sublabel">Black</span></span>
  420.                                         <span id="gray" class="colorCont"><input type="radio" class="nightmode-colors"><span class="sublabel">Gray</span></span>
  421.                                 </div>
  422.                                 <div id="tes-settings-maxcamposition" class="tes-setting-container right">
  423.                                         <input type="checkbox">
  424.                                         <span class="label">Maxed cam on left
  425.                                         </span>
  426.                                 </div>
  427.                                 <div id="tes-settings-borderlesscams" class="tes-setting-container right">
  428.                                         <input type="checkbox">
  429.                                         <span class="label">Remove cam spacing
  430.                                         </span>
  431.                                 </div>
  432.                 <div id="tes-settings-hidenewcams" class="tes-setting-container right">
  433.                                         <input type="checkbox">
  434.                                         <span class="label">Auto hide new cams
  435.                                         </span>
  436.                                 </div>
  437.                 <div id="tes-settings-ignored" class="tes-setting-container rightright">
  438.                                         <input type="checkbox">
  439.                                         <span class="label">
  440.                                                 Cam auto-hide users
  441.                                                 <span class="info" data-title='A comma-separated list of users to auto-hide their cam. Example of 3 users: "bob, mike, jim"'>?</span>
  442.                                         </span>
  443.                                         <div class="inputcontainer">
  444.                                                 <input class="text" placeholder="enter nicknames here"><button class="save blue-button">save</button>
  445.                                         </div>
  446.                                 </div>
  447.                 <div id="tes-settings-banned" class="tes-setting-container rightright">
  448.                                         <input type="checkbox">
  449.                                         <span class="label">
  450.                                                 Auto-banned users
  451.                                                 <span class="info" data-title='A comma-separated list of users to auto-ban on join. Example of 3 users: "bob, mike, jim"'>?</span>
  452.                                         </span>
  453.                                         <div class="inputcontainer">
  454.                                                 <input class="text" placeholder="enter nicknames here"><button class="save blue-button">save</button>
  455.                                         </div>
  456.                                 </div>
  457.                 <!-- BROKEN <div id="tes-settings-togglehiddenmsgs" class="tes-setting-container rightright">
  458.                                         <input type="checkbox">
  459.                                         <span class="label">Hide spam chat messages
  460.                                         </span>
  461.                                 </div> -->
  462.                                 <!--
  463.                                         <div id="tes-settings-messageanim" class="tes-setting-container">
  464.                                                 <input type="checkbox">
  465.                                                 <span class="label">
  466.                                                         Disable message animation
  467.                                                 </span>
  468.                                         </div>
  469.                                 -->
  470.                         </div>
  471.                         <div id="tes-updateNotifier"><a class="tes-closeButtonSmall">✕</a><span>TES now works in Firefox!</span></div>
  472.                         <div id="tes-settingsGear" title="Tinychat Enhancement Suite settings"><span>✱</span></div>
  473.                 </div>
  474.                 `);
  475.  
  476.                     titleElem.getElementById("tes-settingsGear").addEventListener("click", toggleSettingsDisplay);
  477.                     titleElem.getElementById("tes-updateNotifier").addEventListener("click", function () {
  478.                         toggleSettingsDisplay("updateNotifier");
  479.                     });
  480.                     if (!freshInstall && GM_getValue("tes-updateNotifSeen") != "2019.03.16v64") titleElem.getElementById("tes-updateNotifier").classList.add("visible");
  481.  
  482.                     titleElem.querySelector("#tes-settings #tes-settings-mentions button.save").addEventListener("click", function () {
  483.                         mentionsManager("save");
  484.                     });
  485.                     mentionsManager("load");
  486.  
  487.                     titleElem.querySelector("#tes-settings #tes-settings-ignored button.save").addEventListener("click", function () {
  488.                         ignoredManager("save");
  489.                     });
  490.                     ignoredManager("load");
  491.  
  492.                     titleElem.querySelector("#tes-settings #tes-settings-banned button.save").addEventListener("click", function () {
  493.                         bannedManager("save");
  494.                     });
  495.                     bannedManager("load");
  496.  
  497.                     settingsCheckboxUpdate();
  498.                     titleElem.querySelector("#tes-settings-rememberignore input").addEventListener("click", function () {
  499.                         settingsCheckboxUpdate("tes-settings-rememberignore");
  500.                     });
  501.                     titleElem.querySelector("#tes-settings-mentions input:first-of-type").addEventListener("click", function () {
  502.                         settingsCheckboxUpdate("tes-settings-mentions");
  503.                     });
  504.                     titleElem.querySelector("#tes-settings-notifications input:first-of-type").addEventListener("click", function () {
  505.                         settingsCheckboxUpdate("tes-settings-notifications");
  506.                     });
  507.                     titleElem.querySelector("#tes-settings-changefont input").addEventListener("click", function () {
  508.                         settingsCheckboxUpdate("tes-settings-changefont");
  509.                     });
  510.                     titleElem.querySelector("#tes-settings-nightmode input").addEventListener("click", function () {
  511.                         settingsCheckboxUpdate("tes-settings-nightmode");
  512.                     });
  513.                     titleElem.querySelector("#tes-settings-nightmode #black").addEventListener("click", function () {
  514.                         settingsCheckboxUpdate("tes-settings-nightmode-black");
  515.                     });
  516.                     titleElem.querySelector("#tes-settings-nightmode #gray").addEventListener("click", function () {
  517.                         settingsCheckboxUpdate("tes-settings-nightmode-gray");
  518.                     });
  519.                     titleElem.querySelector("#tes-settings-maxcamposition input").addEventListener("click", function () {
  520.                         settingsCheckboxUpdate("tes-settings-maxcamposition");
  521.                     });
  522.                     titleElem.querySelector("#tes-settings-borderlesscams input").addEventListener("click", function () {
  523.                         settingsCheckboxUpdate("tes-settings-borderlesscams");
  524.                     });
  525.                     titleElem.querySelector("#tes-settings-hidenewcams input").addEventListener("click", function () {
  526.                         settingsCheckboxUpdate("tes-settings-hidenewcams");
  527.                     });
  528.                     titleElem.querySelector("#tes-settings-ignored input:first-of-type").addEventListener("click", function () {
  529.                         settingsCheckboxUpdate("tes-settings-ignored");
  530.                     });
  531.                     titleElem.querySelector("#tes-settings-banned input:first-of-type").addEventListener("click", function () {
  532.                         settingsCheckboxUpdate("tes-settings-banned");
  533.                     });
  534.                     /*titleElem.querySelector("#tes-settings-togglehiddenmsgs input").addEventListener("click", function () {
  535.                         settingsCheckboxUpdate("tes-settings-togglehiddenmsgs");
  536.                     });*/
  537.  
  538.                     notificationHider();
  539.  
  540.                     newUserAdded();
  541.                     newMessageAdded();
  542.                     setTimeout(newCamAdded, 2000); // Delay to wait for cameras to load.
  543.                     setTimeout(messageParserCheckCSS, 2000);
  544.                 }
  545.             } catch (e) {
  546.                 tcl("error waitForSettings: " + e.message);
  547.             }
  548.         }
  549.  
  550.         function nightmodeToggle(arg) {
  551.             try {
  552.                 var nightmodeClasses = ["tes-nightmode"];
  553.  
  554.                 if (settingsQuick["NightModeBlack"]) nightmodeClasses.push("blacknight");
  555.  
  556.                 if (arg == true) {
  557.                     bodyElem.classList.add(...nightmodeClasses);
  558.                     titleCSS.classList.add(...nightmodeClasses);
  559.                     sidemenuCSS.classList.add(...nightmodeClasses);
  560.                     userlistCSS.classList.add(...nightmodeClasses);
  561.                     webappCSS.classList.add(...nightmodeClasses);
  562.                     videolistCSS.classList.add(...nightmodeClasses);
  563.                     videomoderationCSS.classList.add(...nightmodeClasses);
  564.                     chatlistCSS.classList.add(...nightmodeClasses);
  565.                     chatlogCSS.classList.add(...nightmodeClasses);
  566.                     chatlogElem.querySelector("#chat-wider").classList.add(...nightmodeClasses);
  567.                     // Messages:
  568.                     if (chatlogElem.querySelector(messageQueryString) != null) {
  569.                         var messageElems = chatlogElem.querySelectorAll(messageQueryString);
  570.                         for (var i = 0; i < messageElems.length; i++) {
  571.                             var messageItem = messageElems[i].querySelector("tc-message-html").shadowRoot;
  572.                             var messageItemCSS = messageItem.querySelector(".message");
  573.                             //messageItemCSS.classList.add(...nightmodeClasses);
  574.                             messageItem.appendChild(messageParserAddCSSNightmode());
  575.                             if (settingsQuick["NightModeBlack"]) messageItem.appendChild(messageParserAddCSSBlacknight());
  576.                         }
  577.                     }
  578.                     // Cams:
  579.                     if (videolistElem.querySelector(camQueryString) != null) {
  580.                         var camElems = videolistElem.querySelectorAll(camQueryString);
  581.                         for (var i = 0; i < camElems.length; i++) {
  582.                             var camItem = camElems[i].querySelector("tc-video-item").shadowRoot;
  583.                             var camItemCSS = camItem.querySelector(".video");
  584.                             camItemCSS.classList.add(...nightmodeClasses);
  585.  
  586.                             camItem.appendChild(camParserAddCSSNightmode());
  587.                             if (settingsQuick["NightModeBlack"]) camItem.appendChild(camParserAddCSSBlacknight());
  588.  
  589.                             if (camItemCSS.querySelector("#camItemCSS") == null) camItemCSS.insertAdjacentHTML("afterbegin", camItemCSShtml);
  590.                         }
  591.                     }
  592.                 }
  593.                 if (arg == false) {
  594.                     if (!settingsQuick["NightModeBlack"] && settingsQuick["NightMode"]) nightmodeClasses = ["blacknight"];
  595.  
  596.                     bodyElem.classList.remove(...nightmodeClasses);
  597.                     titleCSS.classList.remove(...nightmodeClasses);
  598.                     sidemenuCSS.classList.remove(...nightmodeClasses);
  599.                     userlistCSS.classList.remove(...nightmodeClasses);
  600.                     webappCSS.classList.remove(...nightmodeClasses);
  601.                     videolistCSS.classList.remove(...nightmodeClasses);
  602.                     videomoderationCSS.classList.remove(...nightmodeClasses);
  603.                     chatlistCSS.classList.remove(...nightmodeClasses);
  604.                     chatlogCSS.classList.remove(...nightmodeClasses);
  605.                     chatlogElem.querySelector("#chat-wider").classList.remove(...nightmodeClasses);
  606.                     // Messages:
  607.                     if (chatlogElem.querySelector(messageQueryString) != null) {
  608.                         var messageElems = chatlogElem.querySelectorAll(messageQueryString);
  609.                         for (i = 0; i < messageElems.length; i++) {
  610.                             var messageItem = messageElems[i].querySelector("tc-message-html").shadowRoot;
  611.                             //var messageItemCSS = messageItem.querySelector(".message");
  612.                             //messageItemCSS.classList.remove(...nightmodeClasses);
  613.  
  614.                             var child = messageItem.getElementById("messageCSSNightmode");
  615.                             if (child) {
  616.                                 messageItem.removeChild(child);
  617.                             }
  618.                             child = messageItem.getElementById("messageCSSBlacknight");
  619.                             if (child) {
  620.                                 messageItem.removeChild(child);
  621.                             }
  622.                         }
  623.                     }
  624.                     // Cams:
  625.                     if (videolistElem.querySelector(camQueryString) != null) {
  626.                         var camElems = videolistElem.querySelectorAll(camQueryString);
  627.                         for (var i = 0; i < camElems.length; i++) {
  628.                             var camItem = camElems[i].querySelector("tc-video-item").shadowRoot;
  629.                             var camItemCSS = camItem.querySelector(".video");
  630.                             camItemCSS.classList.remove(...nightmodeClasses);
  631.  
  632.                             var child = camItem.getElementById("camItemCSShtmlNightmode");
  633.                             if (child) {
  634.                                 camItem.removeChild(child);
  635.                             }
  636.  
  637.                             var child = camItem.getElementById("camItemCSShtmlBlacknight");
  638.                             if (child) {
  639.                                 camItem.removeChild(child);
  640.                             }
  641.                         }
  642.                     }
  643.                 }
  644.             } catch (e) {
  645.                 tcl("error nightmodeToggle: " + e.message);
  646.             }
  647.         }
  648.  
  649.         function showUpdateNotifier(text) {
  650.             try {
  651.  
  652.                 var updateNotifier = titleElem.querySelector("#tes-updateNotifier");
  653.                 updateNotifier.querySelector("span").innerHTML = text;
  654.                 updateNotifier.classList.add("visible");
  655.                 if (settingsVisible == true) toggleSettingsDisplay();
  656.  
  657.             } catch (e) {
  658.                 tcl("error showUpdateNotifier: " + e.message);
  659.             }
  660.         }
  661.  
  662.         function toggleSettingsDisplay(arg) {
  663.             try {
  664.                 if (arg == "updateNotifier") {
  665.                     titleElem.querySelector("#tes-updateNotifier").classList.remove("visible");
  666.                     GM_setValue("tes-updateNotifSeen", "2019.03.16v64");
  667.                 }
  668.  
  669.                 if (settingsVisible == true) {
  670.                     titleElem.getElementById("tes-settingsBox").classList.add("hidden");
  671.                     titleElem.getElementById("tes-settings").classList.remove("tes-open");
  672.                     settingsVisible = false;
  673.                 } else {
  674.                     titleElem.getElementById("tes-settingsBox").classList.remove("hidden");
  675.                     titleElem.getElementById("tes-settings").classList.add("tes-open");
  676.                     settingsVisible = true;
  677.                 }
  678.             } catch (e) {
  679.                 tcl("error toggleSettingsDisplay: " + e.message);
  680.             }
  681.         }
  682.  
  683.         function settingsCheckboxUpdate(settingName = null, value = null) {
  684.             try {
  685.                 if (settingName == null && value == null) {
  686.                     titleElem.getElementById("tes-settings-rememberignore").querySelector("input").checked = settingsQuick["RememberIgnore"];
  687.                     titleElem.getElementById("tes-settings-mentions").querySelector("input").checked = settingsQuick["MentionsMonitor"];
  688.                     titleElem.getElementById("tes-settings-notifications").querySelector("input").checked = settingsQuick["NotificationsOff"];
  689.                     titleElem.getElementById("tes-settings-changefont").querySelector("input").checked = settingsQuick["ChangeFont"];
  690.                     titleElem.getElementById("tes-settings-nightmode").querySelector("input").checked = settingsQuick["NightMode"];
  691.                     titleElem.getElementById("tes-settings-maxcamposition").querySelector("input").checked = settingsQuick["MaxedCamLeft"];
  692.                     titleElem.getElementById("tes-settings-borderlesscams").querySelector("input").checked = settingsQuick["BorderlessCams"];
  693.                     titleElem.getElementById("tes-settings-hidenewcams").querySelector("input").checked = settingsQuick["HideNewCams"];
  694.                     titleElem.getElementById("tes-settings-ignored").querySelector("input").checked = settingsQuick["IgnoredMonitor"];
  695.                     titleElem.getElementById("tes-settings-banned").querySelector("input").checked = settingsQuick["BannedMonitor"];
  696.                     //titleElem.getElementById("tes-settings-togglehiddenmsgs").querySelector("input").checked = settingsQuick["ToggleHiddenMsgs"];
  697.  
  698.                     titleElem.querySelector("#tes-settings-nightmode #black input").checked = settingsQuick["NightModeBlack"];
  699.                     titleElem.querySelector("#tes-settings-nightmode #gray input").checked = (settingsQuick["NightModeBlack"] == false);
  700.  
  701.                     return;
  702.                 }
  703.                 if (settingName == "tes-settings-rememberignore") {
  704.                     if (value == null) {
  705.                         let newValue = titleElem.getElementById("tes-settings-rememberignore").querySelector("input").checked;
  706.                         settingsQuick["RememberIgnore"] = newValue;
  707.                         GM_setValue("tes-RememberIgnore", newValue.toString());
  708.                     }
  709.                 }
  710.                 if (settingName == "tes-settings-mentions") {
  711.                     if (value == null) {
  712.                         let newValue = titleElem.getElementById("tes-settings-mentions").querySelector("input:first-of-type").checked;
  713.                         // if (newValue) {
  714.                         // titleElem.getElementById("tes-settings-mentions").getAttribute("class").includes("setting-disabled");
  715.                         // }
  716.                         settingsQuick["MentionsMonitor"] = newValue;
  717.                         GM_setValue("tes-MentionsMonitor", newValue.toString());
  718.                     }
  719.                 }
  720.                 if (settingName == "tes-settings-ignored") {
  721.                     if (value == null) {
  722.                         let newValue = titleElem.getElementById("tes-settings-ignored").querySelector("input:first-of-type").checked;
  723.                         // if (newValue) {
  724.                         // titleElem.getElementById("tes-settings-ignored").getAttribute("class").includes("setting-disabled");
  725.                         // }
  726.                         settingsQuick["IgnoredMonitor"] = newValue;
  727.                         GM_setValue("tes-IgnoredMonitor", newValue.toString());
  728.                     }
  729.                 }
  730.                 if (settingName == "tes-settings-banned") {
  731.                     if (value == null) {
  732.                         let newValue = titleElem.getElementById("tes-settings-banned").querySelector("input:first-of-type").checked;
  733.                         // if (newValue) {
  734.                         // titleElem.getElementById("tes-settings-ignored").getAttribute("class").includes("setting-disabled");
  735.                         // }
  736.                         settingsQuick["BannedMonitor"] = newValue;
  737.                         GM_setValue("tes-BannedMonitor", newValue.toString());
  738.                     }
  739.                 }
  740.                 if (settingName == "tes-settings-notifications") {
  741.                     if (value == null) {
  742.                         let newValue = titleElem.getElementById("tes-settings-notifications").querySelector("input").checked;
  743.                         settingsQuick["NotificationsOff"] = newValue;
  744.                         GM_setValue("tes-NotificationsOff", newValue.toString());
  745.                         notificationHider();
  746.                     }
  747.                 }
  748.                 if (settingName == "tes-settings-changefont") {
  749.                     if (value == null) {
  750.                         let newValue = titleElem.getElementById("tes-settings-changefont").querySelector("input").checked;
  751.                         settingsQuick["ChangeFont"] = newValue;
  752.                         GM_setValue("tes-ChangeFont", newValue.toString());
  753.                         fontToggle(newValue);
  754.                     }
  755.                 }
  756.                 if (settingName == "tes-settings-nightmode") {
  757.                     if (value == null) {
  758.                         let newValue = titleElem.getElementById("tes-settings-nightmode").querySelector("input").checked;
  759.                         settingsQuick["NightMode"] = newValue;
  760.                         GM_setValue("tes-NightMode", newValue.toString());
  761.                         nightmodeToggle(newValue);
  762.                     }
  763.                 }
  764.                 if (settingName == "tes-settings-nightmode-black") {
  765.                     if (value == null) {
  766.                         let newValue = titleElem.querySelector("#tes-settings-nightmode #black input").checked;
  767.                         titleElem.querySelector("#tes-settings-nightmode #gray input").checked = (!newValue);
  768.                         settingsQuick["NightModeBlack"] = newValue;
  769.                         GM_setValue("tes-NightModeBlack", newValue.toString());
  770.                         //nightmodeToggle(newValue);
  771.                         //nightmodeToggle(true);
  772.  
  773.                         if (titleElem.querySelector("#tes-settings-nightmode #black input").checked || titleElem.querySelector("#tes-settings-nightmode #gray input").checked) {
  774.                             titleElem.querySelector("#tes-settings-nightmode > input").checked = true;
  775.                             GM_setValue("tes-NightMode", true.toString());
  776.                             settingsQuick["NightMode"] = true;
  777.                             nightmodeToggle(false);
  778.                             nightmodeToggle(true);
  779.                         }
  780.                     }
  781.                 }
  782.                 if (settingName == "tes-settings-nightmode-gray") {
  783.                     if (value == null) {
  784.                         let newValue = (!titleElem.querySelector("#tes-settings-nightmode #gray input").checked);
  785.                         titleElem.querySelector("#tes-settings-nightmode #black input").checked = newValue;
  786.                         settingsQuick["NightModeBlack"] = newValue;
  787.                         GM_setValue("tes-NightModeBlack", newValue.toString());
  788.                         //nightmodeToggle(newValue);
  789.  
  790.                         if (titleElem.querySelector("#tes-settings-nightmode #black input").checked || titleElem.querySelector("#tes-settings-nightmode #gray input").checked) {
  791.                             titleElem.querySelector("#tes-settings-nightmode > input").checked = true;
  792.                             GM_setValue("tes-NightMode", true.toString());
  793.                             settingsQuick["NightMode"] = true;
  794.                             nightmodeToggle(false);
  795.                             nightmodeToggle(true);
  796.                         }
  797.                     }
  798.                 }
  799.                 if (settingName == "tes-settings-maxcamposition") {
  800.                     if (value == null) {
  801.                         let newValue = titleElem.getElementById("tes-settings-maxcamposition").querySelector("input").checked;
  802.                         settingsQuick["MaxedCamLeft"] = newValue;
  803.                         GM_setValue("tes-MaxedCamLeft", newValue.toString());
  804.                         maxCamPositionToggle(newValue);
  805.                     }
  806.                 }
  807.                 if (settingName == "tes-settings-borderlesscams") {
  808.                     if (value == null) {
  809.                         let newValue = titleElem.getElementById("tes-settings-borderlesscams").querySelector("input").checked;
  810.                         settingsQuick["BorderlessCams"] = newValue;
  811.                         GM_setValue("tes-BorderlessCams", newValue.toString());
  812.                         borderlessCamsToggle(newValue);
  813.                     }
  814.                 }
  815.                 if (settingName == "tes-settings-hidenewcams") {
  816.                     if (value == null) {
  817.                         let newValue = titleElem.getElementById("tes-settings-hidenewcams").querySelector("input").checked;
  818.                         settingsQuick["HideNewCams"] = newValue;
  819.                         GM_setValue("tes-HideNewCams", newValue.toString());
  820.                     }
  821.                 }
  822.                 /*if (settingName == "tes-settings-togglehiddenmsgs") {
  823.                     if (value == null) {
  824.                         let newValue = titleElem.getElementById("tes-settings-togglehiddenmsgs").querySelector("input").checked;
  825.                         settingsQuick["ToggleHiddenMsgs"] = newValue;
  826.                         GM_setValue("tes-ToggleHiddenMsgs", newValue.toString());
  827.  
  828.                         // Toggle display of all elements with relevant class.
  829.                         //var elems = chatlogElem.querySelectorAll(".hideSpamChat");
  830.                         //console.log('elems', elems)
  831.                         //if (elems) {
  832.                             // Get state from checkbox.
  833.                             //var state = 'block';
  834.                             //console.log('checkbox', settingsQuick["ToggleHiddenMsgs"], newValue)
  835.                             //if (settingsQuick["ToggleHiddenMsgs"]) {
  836.                             //    state = 'none';
  837.                             //}
  838.  
  839.                             //for (var i = 0; i < elems.length; i++) {
  840.                             //    var el = elems[i];
  841.                             //    el.style.display = state;
  842.                             //}
  843.                         //}
  844.  
  845.                         if (newValue) {
  846.                             messageParserAddCSSSpam(true)
  847.                         } else {
  848.                             messageParserAddCSSSpam(false)
  849.                         }
  850.  
  851.                     }
  852.                 }*/
  853.             } catch (e) {
  854.                 tcl("error settingsCheckboxUpdate: " + e.message);
  855.             }
  856.         }
  857.  
  858.         function fontToggle(arg) {
  859.             try {
  860.                 arg ? bodyElem.classList.add("tes-changefont") : bodyElem.classList.remove("tes-changefont");
  861.             } catch (e) {
  862.                 tcl("error fontToggle: " + e.message);
  863.             }
  864.         }
  865.  
  866.         function borderlessCamsToggle(arg) {
  867.             try {
  868.                 if (videolistElem.querySelector(camQueryString) != null) {
  869.                     var camElems = videolistElem.querySelectorAll(camQueryString);
  870.                     for (i = 0; i < camElems.length; i++) {
  871.                         var camItem = camElems[i].querySelector("tc-video-item").shadowRoot;
  872.                         var camElem = camItem.querySelector(".video");
  873.                         arg ? camElem.classList.add("tes-borderlesscams") : camElem.classList.remove("tes-borderlesscams");
  874.  
  875.                         if (arg) {
  876.                             camItem.appendChild(camParserAddCSSBorderless());
  877.                         } else {
  878.                             var child = camItem.getElementById("camItemCSShtmlBorderless");
  879.                             if (child) {
  880.                                 camItem.removeChild(child);
  881.                             }
  882.                         }
  883.                     }
  884.                 }
  885.                 arg ? videolistCSS.classList.add("tes-borderlesscams") : videolistCSS.classList.remove("tes-borderlesscams");
  886.             } catch (e) {
  887.                 tcl("error borderlessCamsToggle: " + e.message);
  888.             }
  889.         }
  890.  
  891.         function maxCamPositionToggle(arg) {
  892.             try {
  893.                 arg ? videolistCSS.classList.add("tes-leftcam") : videolistCSS.classList.remove("tes-leftcam");
  894.             } catch (e) {
  895.                 tcl("error maxCamPositionToggle: " + e.message);
  896.             }
  897.         }
  898.  
  899.         function notificationHider() {
  900.             try {
  901.                 chatlogContainer = chatlogElem.querySelector("#chat-content");
  902.                 settingsQuick["NotificationsOff"] ? chatlogContainer.classList.add("tes-notif-off") : chatlogContainer.classList.remove("tes-notif-off");
  903.             } catch (e) {
  904.                 tcl("error notificationHider: " + e.message);
  905.             }
  906.         }
  907.  
  908.         function copyChatlog(opt = null) {
  909.             try {
  910.                 if (opt == "close") {
  911.                     chatlogDisplayElem.classList.remove("show");
  912.                     chatlogDisplayClose.classList.remove("show");
  913.                     setTimeout(function () {
  914.                         chatlogDisplayCont.classList.remove("show");
  915.                     }, 300);
  916.                     return;
  917.                 }
  918.  
  919.                 var filename = "tinychat_" + roomName + "_" + joinDate + "_" + joinTime.replace(/:/g, ".") + "-chatlog.log";
  920.                 var chatlogText = "Tinychat room " + roomName + " on " + joinDate + " " + joinTime + newline + "Users (" + usersCountInitial + "): " + userlistInitial + newline + chatlogMain;
  921.  
  922.                 var downloadLink = 'data:text/plain;charset=utf-8,' + encodeURIComponent(chatlogText);
  923.                 var downloadElem = document.createElement('a');
  924.                 downloadElem.setAttribute("href", downloadLink);
  925.  
  926.                 downloadElem.setAttribute("download", filename);
  927.  
  928.                 if (opt == "download") {
  929.                     if (browserFirefox) showUpdateNotifier("Chat log downloading doesn't work in Firefox yet.");
  930.                     else downloadElem.click();
  931.                 }
  932.                 if (opt == "view" || opt == null) {
  933.                     if (typeof chatlogDisplayCont == "undefined") {
  934.                         chatlogDisplayCont = chatlogElem.querySelector("#tes-chatlogDisplay");
  935.                         chatlogDisplayElem = chatlogDisplayCont.querySelector("textarea");
  936.                         chatlogDisplayClose = chatlogDisplayCont.querySelector("#close");
  937.                     }
  938.                     chatlogDisplayElem.value = chatlogText;
  939.                     chatlogDisplayCont.classList.add("show");
  940.                     setTimeout(function () {
  941.                         chatlogDisplayElem.classList.add("show");
  942.                         chatlogDisplayClose.classList.add("show");
  943.                     }, 50);
  944.                     chatlogDisplayElem.scrollTop = chatlogDisplayElem.scrollHeight;
  945.                 }
  946.             } catch (e) {
  947.                 tcl("error copyChatlog: " + e.message);
  948.             }
  949.         }
  950.  
  951.         function getFormattedDateTime(d, opt = null) {
  952.             try {
  953.                 if (opt == "time") return d.toLocaleTimeString('en-US', {
  954.                     hour12: false
  955.                 });
  956.                 else return d.toLocaleDateString('zh-CN', {
  957.                     'year': 'numeric',
  958.                     'month': '2-digit',
  959.                     'day': '2-digit'
  960.                 }).replace(///g, "-");
  961.             } catch (e) {
  962.                 tcl("error getFormattedDateTime: " + e.message);
  963.             }
  964.         }
  965.  
  966.         function mentionsManager(mode) {
  967.             try {
  968.                 var inputElem = titleElem.querySelector("#tes-settings #tes-settings-mentions input.text");
  969.                 // phrases = inputElem.value.split(",");
  970.                 var phrase = inputElem.value;
  971.                 if (phrase.endsWith(",")) {
  972.                     phrase = phrase.slice(0, -1);
  973.                 }
  974.                 if (phrase.startsWith(",")) {
  975.                     phrase = phrase.slice(1);
  976.                 }
  977.  
  978.                 if (mode == "save") {
  979.                     GM_setValue("tes-Mentions", phrase);
  980.                     settingMentions = phrase.split(",").map(x => x.trim());
  981.                     inputElem.value = phrase;
  982.                 }
  983.                 if (mode == "load") {
  984.                     var loadedMentions = GM_getValue("tes-Mentions");
  985.                     if (loadedMentions != undefined) {
  986.                         inputElem.value = loadedMentions;
  987.                         settingMentions = loadedMentions.split(",").map(x => x.trim());
  988.                     }
  989.                 }
  990.  
  991.                 /*var phrase = phrase.toString();
  992.                 if (mode == "save") {
  993.                     settingMentions.push(phrases);
  994.                     GM_setValue("tes-Mentions", JSON.stringify(setting_Mentions));
  995.                 }
  996.                 if (mode == "load") {
  997.                     var mentions = JSON.parse(GM_getValue("tes-Mentions"));
  998.                     settingMentions = mentions;
  999.                     inputElem.value = settingMentions.join();
  1000.                 }*/
  1001.             } catch (e) {
  1002.                 tcl("error mentionsManager: " + e.message);
  1003.             }
  1004.         }
  1005.  
  1006.         function ignoredManager(mode) {
  1007.             try {
  1008.                 var inputElem = titleElem.querySelector("#tes-settings #tes-settings-ignored input.text");
  1009.                 // phrases = inputElem.value.split(",");
  1010.                 var phrase = inputElem.value;
  1011.                 if (phrase.endsWith(",")) {
  1012.                     phrase = phrase.slice(0, -1);
  1013.                 }
  1014.                 if (phrase.startsWith(",")) {
  1015.                     phrase = phrase.slice(1);
  1016.                 }
  1017.  
  1018.                 if (mode == "save") {
  1019.                     GM_setValue("tes-IgnoredUsers", phrase);
  1020.                     settingIgnoredUsers = phrase.split(",").map(x => x.trim().toUpperCase());
  1021.                     inputElem.value = phrase;
  1022.                 }
  1023.                 if (mode == "load") {
  1024.                     var loadedIgnoredUsers = GM_getValue("tes-IgnoredUsers");
  1025.                     if (loadedIgnoredUsers != undefined) {
  1026.                         inputElem.value = loadedIgnoredUsers;
  1027.                         settingIgnoredUsers = loadedIgnoredUsers.split(",").map(x => x.trim().toUpperCase());
  1028.                     }
  1029.                 }
  1030.             } catch (e) {
  1031.                 tcl("error ignoredManager: " + e.message);
  1032.             }
  1033.         }
  1034.  
  1035.         function bannedManager(mode) {
  1036.             try {
  1037.                 var inputElem = titleElem.querySelector("#tes-settings #tes-settings-banned input.text");
  1038.                 // phrases = inputElem.value.split(",");
  1039.                 var phrase = inputElem.value;
  1040.                 if (phrase.endsWith(",")) {
  1041.                     phrase = phrase.slice(0, -1);
  1042.                 }
  1043.                 if (phrase.startsWith(",")) {
  1044.                     phrase = phrase.slice(1);
  1045.                 }
  1046.  
  1047.                 if (mode == "save") {
  1048.                     GM_setValue("tes-BannedUsers", phrase);
  1049.                     settingBannedUsers = phrase.split(",").map(x => x.trim().toUpperCase());
  1050.                     inputElem.value = phrase;
  1051.                 }
  1052.                 if (mode == "load") {
  1053.                     var loadedBannedUsers = GM_getValue("tes-BannedUsers");
  1054.                     if (loadedBannedUsers != undefined) {
  1055.                         inputElem.value = loadedBannedUsers;
  1056.                         settingBannedUsers = loadedBannedUsers.split(",").map(x => x.trim().toUpperCase());
  1057.                     }
  1058.                 }
  1059.             } catch (e) {
  1060.                 tcl("error bannedManager: " + e.message);
  1061.             }
  1062.         }
  1063.  
  1064.         function declareGlobalVars() {
  1065.             try {
  1066.                 globalCSS = `:root {
  1067.                 --textcolor: black;
  1068.                 --bgcolor: white;
  1069.  
  1070.                 --nightmode-bgcolor: #2d373a;
  1071.                 --nightmode-trimcolor: #3c4a4e;
  1072.                 --nightmode-textcolor: #9faaad;
  1073.                 --nightmode-textSecondarycolor: #4e5f65;
  1074.                 --nightmode-headerButtonscolor: #3986a7;
  1075.  
  1076.                 --nightmodeBlack-bgcolor: black;
  1077.                 --nightmodeBlack-trimcolor: #222;
  1078.  
  1079.         }
  1080.  
  1081.         * {
  1082.           scrollbar-color: #ccc transparent;
  1083.           scrollbar-width: thin;
  1084.         }
  1085.         .tes-nightmode * { scrollbar-color: #242C2E transparent; }
  1086.         .tes-nightmode.blacknight * { scrollbar-color: #111 transparent; }
  1087.  
  1088.         .list-item > span[data-status="gold"] {
  1089.                 color: unset !important;
  1090.         }
  1091.  
  1092.         .list-item > span[data-status="extreme"] {
  1093.                 color: unset !important;
  1094.         }
  1095.  
  1096.         .list-item > span[data-status="pro"] {
  1097.                 color: unset !important;
  1098.         }
  1099.         `;
  1100.  
  1101.                 camItemCSShtml = `
  1102.                 <style id="camItemCSS">` + globalCSS + `
  1103.                         .icon-tes-max {
  1104.                                 position: absolute;
  1105.                                 top: -40%;
  1106.                                 right: 0;
  1107.                                 z-index: 9;
  1108.                                 background: none;
  1109.                                 border: 0;
  1110.                         }
  1111.                         .icon-tes-max:hover { cursor: pointer; }
  1112.                         .icon-tes-max path { fill: #04caff; }
  1113.  
  1114.                         .video:hover .icon-tes-max {
  1115.                                 top: 40%;
  1116.                                 transition: top .2s ease .2s,
  1117.                                                 left .2s ease .2s,
  1118.                                                 right .2s ease .2s,
  1119.                                                 opacity .2s;
  1120.                                 }
  1121.  
  1122.                         /* Disable cam border
  1123.                         .video:after { border: none; }
  1124.                         .video > div { background-color: unset; }
  1125.                         video,
  1126.                         .video > div > .overlay {
  1127.                                 border-radius: 10px;
  1128.                         }
  1129.                         */
  1130.                         .video { transition: .4s; }
  1131.                         .tes-borderlesscams.video { padding: 0; }
  1132.                         .tes-borderlesscams.video:after { display: none; }
  1133.  
  1134.                         .tes-nightmode.video:after { border-color: var(--nightmode-bgcolor); }
  1135.                                         .tes-nightmode.blacknight.video:after { border-color: var(--nightmodeBlack-bgcolor); }
  1136.                         .tes-nightmode.blacknight.video > div > .waiting { background: #111; }
  1137.                         .tes-nightmode.blacknight.video > div { background-color: #111; }
  1138.  
  1139.             /* Fix pro blur. */
  1140.             div.video > div > div.blured {
  1141.                 display: none !important;
  1142.             }
  1143.  
  1144.             div.video > div > video {
  1145.                 filter: none !important;
  1146.             }
  1147.  
  1148.             .icon-resize {opacity: 0 !important;} /* Original resize is unused now. */
  1149.                 </style>
  1150.         `;
  1151.  
  1152.                 camItemCSShtmlNightmode = `.video:after { border-color: var(--nightmode-bgcolor); }`;
  1153.                 camItemCSShtmlBlacknight = `
  1154.                 .video:after { border-color: var(--nightmodeBlack-bgcolor); }
  1155.                         .video > div > .waiting { background: #111; }
  1156.                         .video > div { background-color: #111; }
  1157.     `;
  1158.                 camItemCSShtmlBorderless = `
  1159.                         .video { padding: 0; }
  1160.                         .video:after { display: none; }
  1161.     `;
  1162.  
  1163.                 // Includes talking indicator css.
  1164.                 camMaxCSShtml = `
  1165.         <style id="camMaxCSS">` + globalCSS + `
  1166.                 .tes-max .js-video {
  1167.                         width: 15%!important;
  1168.                         z-index: 1;
  1169.                 }
  1170.                 .tes-leftcam .tes-max .js-video {
  1171.                         float: right;
  1172.                         order: 2;
  1173.                 }
  1174.                 .tes-leftcam .tes-max .tes-maxedCam {
  1175.                         float: left;
  1176.                         order: 1;
  1177.                 }
  1178.  
  1179.                 div[data-video-count="5"] .tes-max .js-video:not(.tes-maxedCam),
  1180.                 div[data-video-count="6"] .tes-max .js-video:not(.tes-maxedCam),
  1181.                 div[data-video-count="7"] .tes-max .js-video:not(.tes-maxedCam)
  1182.                 { width: 20%!important; }
  1183.                 .tes-max.tes-camCount2 .js-video { width: 30%!important; }
  1184.                 .tes-max.tes-camCount10-11 .js-video { width: 16%!important; }
  1185.                 .tes-max.tes-camCount12 .js-video { width: 14%!important; }
  1186.  
  1187.                 :not(.hidden) + .tes-max.tes-camCount12 .js-video,
  1188.                 :not(.hidden) + .tes-max.tes-camCount10-11 .js-video,
  1189.                 :not(.hidden) + .tes-max .js-video
  1190.                 { width: 30%!important; }
  1191.                 :not(.hidden) + .tes-max.tes-camCount2 .js-video { width: 60%!important; }
  1192.  
  1193.                 .tes-max .js-video.tes-maxedCam,
  1194.                 :not(.hidden) + .tes-max .js-video.tes-maxedCam { width: 70%!important; }
  1195.  
  1196.                 @media screen and (max-width: 1400px) {
  1197.                         .tes-max .js-video { width: 20%!important; }
  1198.  
  1199.                         .tes-max.tes-camCount2 .js-video { width: 40%!important; }
  1200.                         .tes-max.tes-camCount10-11 .js-video { width: 18%!important; }
  1201.                         .tes-max.tes-camCount12 .js-video { width: 15%!important; }
  1202.  
  1203.                         .tes-max .js-video.tes-maxedCam,
  1204.                         :not(.hidden) + .tes-max .js-video.tes-maxedCam { width: 60%!important; }
  1205.                 }
  1206.         </style>
  1207.         `;
  1208.  
  1209.                 camMaxButtonHtml = `
  1210.                 <button class="icon-tes-max" id="maxbutton-camName">
  1211.                         <svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
  1212.                                 <path d="M14.37 12.95l3.335 3.336a1.003 1.003 0 1 1-1.42 1.42L12.95 14.37a8.028 8.028 0 1 1 1.42-1.42zm-6.342 1.1a6.02 6.02 0 1 0 0-12.042 6.02 6.02 0 0 0 0 12.042zM6.012 9.032a.996.996
  1213.                                 0 0 1-.994-1.004c0-.554.452-1.003.994-1.003h4.033c.55 0 .994.445.994 1.003 0 .555-.454 1.004-.995 1.004H6.012z" fill-rule="evenodd"></path>
  1214.                                 <path d="M0 .99C0 .445.444 0 1 0a1 1 0 0 1 1 .99v4.02C2 5.555 1.556 6 1 6a1 1 0 0 1-1-.99V.99z" transform="translate(7 5)" fill-rule="evenodd"></path>
  1215.                         </svg>
  1216.                 </button>
  1217.         `;
  1218.  
  1219.                 camTalkingIndicatorHtml = `
  1220.         <div class="icon-tes-talking" id="micIndicator-camName">
  1221.                         <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
  1222.                 <path d="M12 2c1.103 0 2 .897 2 2v7c0 1.103-.897 2-2 2s-2-.897-2-2v-7c0-1.103.897-2 2-2zm0-2c-2.209 0-4 1.791-4 4v7c0 2.209 1.791 4 4 4s4-1.791 4-4v-7c0-2.209-1.791-4-4-4zm8 9v2c0 4.418-3.582 8-8 8s-8-3.582-8-8v-2h2v2c0 3.309 2.691 6 6 6s6-2.691 6-6v-2h2zm-7 13v-2h-2v2h-4v2h10v-2h-4z"/>
  1223.             </svg>
  1224.                 </div>
  1225.         <style>
  1226.             .icon-tes-talking {
  1227.               position: absolute;
  1228.               height: 22px;
  1229.               width: 22px;
  1230.               top: 8px;
  1231.               padding: 0;
  1232.               border: none;
  1233.               background-color: transparent;
  1234.               cursor: pointer;
  1235.               opacity: 0;
  1236.               transition: .05s;
  1237.  
  1238.               left: 50%;
  1239.               margin-left: -11px;
  1240.             }
  1241.  
  1242.             .icon-tes-talking > svg {
  1243.               fill: white;
  1244.               filter: drop-shadow(0px 0px 2px black);
  1245.             }
  1246.         </style>
  1247.     `;
  1248.             } catch (e) {
  1249.                 tcl("error declareGlobalVars: " + e.message);
  1250.             }
  1251.         }
  1252.  
  1253.         function injectCSS(cssName = null) {
  1254.             try {
  1255.                 // Indenting is purposely wrong, for readability
  1256.                 var insertPosition = "beforeend";
  1257.                 headElem = document.querySelector("head");
  1258.                 browserSpoofedChrome = (headElem.innerHTML.includes("Shady DOM styles for") ? true : false);
  1259.                 if (browserSpoofedChrome) tcl("browserSpoofedChrome");
  1260.                 var firefoxCSS = "";
  1261.  
  1262.                 { // titleCSS
  1263.                     if (browserFirefox) var firefoxCSS = `
  1264.                 #tes-settings-nightmode .nightmode-colors:after { display: none; }
  1265.                 #tes-settings-nightmode .nightmode-colors {
  1266.  
  1267.                 }
  1268.                 #tes-settings-nightmode > span {
  1269.                         position: relative;
  1270.                         top: -4px;
  1271.                 }
  1272.                 #tes-settings-nightmode .label { margin-right: 3px; }
  1273.                 #tes-settings-nightmode .sublabel {
  1274.                         margin-left: unset;
  1275.                         position: relative;
  1276.                         top: -2px;
  1277.                 }
  1278.                 #tes-settings-nightmode .colorCont {
  1279.                         position: relative;
  1280.                         top: -2px;
  1281.                 }
  1282.         `;
  1283.  
  1284.                     titleCSShtml = `
  1285.         <style id="titleCSS" scope="tinychat-title">` + globalCSS + `
  1286.                 @keyframes ease-to-left {
  1287.                         0% {right: -50px; opacity: 0;}
  1288.                         100% {right: 0; opacity: 1;}
  1289.                 }
  1290.                 @keyframes ease-to-right {
  1291.                         0% {right:auto;}
  1292.                         100% {right:0;}
  1293.                 }
  1294.                 @keyframes ease-to-bottom-21px {
  1295.                         0% {top:-300px; opacity: 0;}
  1296.                         100% {top:0; opacity: 1;}
  1297.                 }
  1298.                 #tes-header-grabber {
  1299.                     position: absolute;
  1300.                         top: 88px;
  1301.                         right: 50%;
  1302.                         background: white;
  1303.                         width: 60px;
  1304.                         height: 20px;
  1305.                         border: #ddd 1px solid;
  1306.                         border-radius: 19px;
  1307.                         text-align: center;
  1308.                         color: #b4c1c5;
  1309.                         cursor: pointer;
  1310.                         transition: .4s;
  1311.                 }
  1312.                 #tes-header-grabber:hover {
  1313.                         background: #e9eaea;
  1314.                         z-index: 1;
  1315.                         border-bottom: 0px;
  1316.                 }
  1317.                 .tes-headerCollapsed #tes-header-grabber {
  1318.                         top: 9px;
  1319.                         background: #f6f6f6;
  1320.                         border-top: 0;
  1321.                         z-index: 9;
  1322.                         border-radius: 11px;
  1323.                         line-height: 11px;
  1324.                         border-top-left-radius: 0;
  1325.                         border-top-right-radius: 0;
  1326.                         height: 12px;
  1327.                 }
  1328.                 .tes-headerCollapsed:hover #tes-header-grabber {
  1329.                         height: 29px;
  1330.                         line-height: 43px;
  1331.                 }
  1332.                 input {
  1333.                         border: 1px solid #c4d4dc;
  1334.                         line-height: 16px;
  1335.                         padding-left: 3px;
  1336.                 }
  1337.                 .label ~ input {
  1338.                         border-bottom-left-radius: 6px;
  1339.                         border-top-left-radius: 6px;
  1340.                 }
  1341.                 input ~ button {
  1342.                         border-bottom-right-radius: 6px;
  1343.                         border-top-right-radius: 6px;
  1344.                 }
  1345.                 input[type="button"], button {
  1346.                         display: inline;
  1347.                         padding: 0 15px;
  1348.                         border: 0;
  1349.                         box-sizing: border-box;
  1350.                         letter-spacing: 1px;
  1351.                         font-size: 12px;
  1352.                         font-weight: bold;
  1353.                         line-height: 20px;
  1354.                         text-align: center;
  1355.                         transition: .2s;
  1356.                         outline: none;
  1357.                 }
  1358.                 .blue-button {
  1359.                         color: #fff;
  1360.                         background-color: #41b7ef;
  1361.                 }
  1362.                 .blue-button:hover {
  1363.                     background-color: #54ccf3;
  1364.                 }
  1365.                 .blue-button:active {
  1366.                     background-color: #38a8dd;
  1367.                 }
  1368.                 .tes-setting-container {
  1369.                         line-height: initial;
  1370.                 }
  1371.                 #tes-settings { color: var(--textcolor); }
  1372.                 #tes-settings > div {
  1373.                         /*animation: ease-to-bottom-21px .2s ease 0s 1;*/
  1374.                         position: relative;
  1375.                         top: 0;
  1376.                         height: 100px;
  1377.                 }
  1378.                 @media screen and (max-width: 1000px) {
  1379.                         #tes-settings > div {
  1380.                                 height: 92px;
  1381.                         }
  1382.                 }
  1383.                 #tes-settings .hidden { display: none; }
  1384.                 #tes-settings #title {
  1385.                         font-weight: bold;
  1386.                         margin-top: 6px;
  1387.             width: 600px;
  1388.                 }
  1389.                 #tes-settings {
  1390.                         transition: all .4s ease-in-out;
  1391.                         animation: ease-to-bottom-21px .2s ease 0s 1;
  1392.                         /*max-height: 10%;*/
  1393.                         font-size: 11px;
  1394.                         flex: none;
  1395.                         overflow: hidden;
  1396.                         z-index: 7;
  1397.                         position: absolute;
  1398.                         top: -2px;
  1399.                         right: ` + (giftsElemWidth + 10).toString() + `px;
  1400.                 }
  1401.                 @media screen and (max-width: 1000px) {
  1402.                         #tes-settings {
  1403.                                 right: 37px!important;
  1404.                                 top: -20px;
  1405.                         }
  1406.                         #tes-settings.tes-open {
  1407.                                 top: 6px;
  1408.                         }
  1409.                         #tes-settingsGear {
  1410.                                 font-size: 52px!important;
  1411.                         }
  1412.                         #room-header-gifts-buttons > #give-gift {
  1413.                                 width: 102px;
  1414.                         }
  1415.                 }
  1416.                 @media screen and (max-width: 600px) {
  1417.                         #tes-settings {
  1418.                                 right: -4px!important;
  1419.                         top: 19px;
  1420.                         }
  1421.                 }
  1422.                 #tes-settings:hover {
  1423.                         overflow: visible;
  1424.                 }
  1425.         #tes-settings-mentions {
  1426.             max-width: 360px;
  1427.         }
  1428.                 #tes-settings-mentions .inputcontainer {
  1429.                         float: right;
  1430.                         position: relative;
  1431.                         top: -3px;
  1432.                 }
  1433.         #tes-settings-ignored {
  1434.             max-width: 360px;
  1435.             top: 54px;
  1436.         }
  1437.                 #tes-settings-ignored .inputcontainer {
  1438.                         float: right;
  1439.                         position: relative;
  1440.                         top: 3px;
  1441.                 }
  1442.         #tes-settings-banned {
  1443.             max-width: 360px;
  1444.             top: 8px;
  1445.         }
  1446.                 #tes-settings-banned .inputcontainer {
  1447.                         float: right;
  1448.                         position: relative;
  1449.                         top: 3px;
  1450.                 }
  1451.                 #tes-settingsGear {
  1452.                         font-size: 70px;
  1453.                         color: #38cd57;
  1454.                         color: #53b6ef;
  1455.                         float: right;
  1456.                 }
  1457.                 #tes-settingsGear:hover {
  1458.                         cursor: pointer;
  1459.                         color: #7ccefe;
  1460.                 }
  1461.                 .tes-open #tes-settingsGear {
  1462.                         background: white;
  1463.                         border-bottom-right-radius: 15px;
  1464.                         border-top-right-radius: 15px;
  1465.                         border: #ddd 1px solid;
  1466.                         border-left: 0;
  1467.                         /*transition: all .2s linear;*/
  1468.                         }
  1469.                 #tes-settingsGear span {
  1470.                         display: block;
  1471.                         transition: transform 0.4s ease-in-out;
  1472.                 }
  1473.                 .tes-open #tes-settingsGear span {
  1474.                         transform: rotate(-90deg);
  1475.                 }
  1476.                 #tes-settingsBox {
  1477.                         background: white;
  1478.                         padding: 0px 10px 0px 10px;
  1479.                         float: left;
  1480.                         border: #53b6ef 1px solid;
  1481.                         border-top-left-radius: 12px;
  1482.                         border-bottom-left-radius: 12px;
  1483.                         animation: ease-to-left .2s ease 0s 1;
  1484.                         right: 0;
  1485.                 }
  1486.                 #tes-settingsBox.hidden {
  1487.                         animation: ease-to-right .2s ease 0s 1;
  1488.                         display: visible;
  1489.                         /*position: relative; right: -1000px;*/
  1490.                 }
  1491.  
  1492.                 #tes-settings-nightmode .nightmode-colors {
  1493.                         width: 0px;
  1494.                         height: 0px;
  1495.                 }
  1496.                 #tes-settings-nightmode .nightmode-colors:after {
  1497.                         content: " ";
  1498.                         border-radius: 3px;
  1499.                         height: 11px;
  1500.                         width: 11px;
  1501.                         margin-left: 3px;
  1502.                         top: -9px;
  1503.                         position: relative;
  1504.                         display: block;
  1505.                 }
  1506.                 #tes-settings-nightmode .nightmode-colors:checked:after {
  1507.                         border: #41a9c1 1px solid;
  1508.                 }
  1509.                 #black .nightmode-colors:after { background: black; }
  1510.                 #gray .nightmode-colors:after { background: #575e60; }
  1511.                 #tes-settings-nightmode .sublabel { margin-left: 15px; }
  1512.  
  1513.                 /*** Inline with header ***/
  1514.                 #tes-settingsBox {
  1515.                         border-bottom-width: 0;
  1516.                         border-top-left-radius: 0px;
  1517.                         border-bottom-left-radius: 0px;
  1518.                 }
  1519.                 #tes-settingsGear {
  1520.                         display: table;
  1521.                 }
  1522.                 #tes-settingsGear span {
  1523.                         display: table-cell;
  1524.                         vertical-align: middle;
  1525.                 }
  1526.                 /*** *************   ***/
  1527.  
  1528.                 #tes-settings .tes-setting-container > input[type=checkbox]:first-child {
  1529.                         margin: 0;
  1530.                         margin-right: 1px;
  1531.                         float: left;
  1532.                         position: absolute;
  1533.                         left: 8px;
  1534.                 }
  1535.                 #tes-settings .right {
  1536.                         position: absolute;
  1537.                         left: 210px;
  1538.                 }
  1539.         #tes-settings .rightright {
  1540.                         position: absolute;
  1541.                         left: 380px;
  1542.                 }
  1543.         .hideSpamChat {
  1544.             display: none;
  1545.         }
  1546.                 #tes-settings-maxcamposition { top: 54px; }
  1547.                 #tes-settings-borderlesscams { top: 67px; }
  1548.         #tes-settings-hidenewcams { top: 80px; }
  1549.         #tes-settings-togglehiddenmsgs { top: 41px; }
  1550.                 #tes-settings .label {
  1551.                         margin-right: 4px;
  1552.                         margin-left: 16px;
  1553.                 }
  1554.                 #tes-settings .right .label, #tes-settings .rightright .label {
  1555.                         margin-left: 24px;
  1556.                 }
  1557.                 #tes-settings .info{
  1558.                         margin-left: 3px;
  1559.                         color: #0d94e3;
  1560.                         font-weight: bold;
  1561.                         font-family: Arial;
  1562.                         border: #0d94e3 1px solid;
  1563.                         border-radius: 16px;
  1564.                         height: 1em;
  1565.                         width: 1em;
  1566.                         text-align: center;
  1567.                         display: inline-block;
  1568.                 }
  1569.                 #tes-settings .info:hover:after{
  1570.                         font-weight: normal;
  1571.                         padding: 4px 7px 4px 7px;
  1572.                         border-radius: 7px;
  1573.                         color: white;
  1574.                         background: #61787f;
  1575.                         content: attr(data-title);
  1576.                         display: inline-block;
  1577.                         position: absolute;
  1578.                         top: 52px;
  1579.                         left: 0;
  1580.                         z-index: 9;
  1581.                 }
  1582.                 /*#tes-settings .label:hover:before{
  1583.                         border: solid;
  1584.                         border-color: #61787f transparent;
  1585.                         border-width: 0px 6px 6px 6px;
  1586.                         top: 10px;
  1587.                         content: "";
  1588.                         left: 8%;
  1589.                         position: relative;
  1590.                         display: inline-block;
  1591.                 }*/
  1592.  
  1593.                 #tes-settings a:visited, #tes-settings a:link {
  1594.                         text-decoration: none;
  1595.                         color: inherit;
  1596.                 }
  1597.                 #tes-settings a:hover {
  1598.                         color: #53b6ef;
  1599.                 }
  1600.  
  1601.                 #room-header {
  1602.                         height: 100px;
  1603.                         max-height: unset;
  1604.                         min-height: unset;
  1605.                         transition: all .4s ease-in-out;
  1606.                 }
  1607.                 #room-header.tes-headerCollapsed {
  1608.                         height: 10px;
  1609.                 }
  1610.                 #room-header.tes-headerCollapsed:hover {
  1611.                         height: 27px;
  1612.                 }
  1613.                 @media screen and (max-width: 600px) {
  1614.                         #room-header {
  1615.                                 min-height: inherit;
  1616.                                 max-height: inherit;
  1617.                         }
  1618.                 }
  1619.                 #room-header-info {
  1620.                         padding: 0;
  1621.                         padding-right: 45px;
  1622.                 }
  1623.         #room-header-info > h1 {
  1624.             user-select: text;
  1625.         }
  1626.                 #room-header-info-text {
  1627.                         height: auto;
  1628.             user-select: text;
  1629.                 }
  1630.         #room-header-info-details, #room-header-info-details * {
  1631.             user-select: text;
  1632.                 }
  1633.                 @media screen and (max-width: 600px) {
  1634.                         #room-header-info-text {
  1635.                                 height: inherit;
  1636.                         }
  1637.                 }
  1638.                 #room-header-avatar {
  1639.                         margin: 2px 10px 0 35px;
  1640.                         height: 90px;
  1641.                         min-width: 90px;
  1642.                         max-width: 90px;
  1643.                         transition: all .5s linear;
  1644.                 }
  1645.                 #room-header-avatar:hover {
  1646.                         border-radius: unset;
  1647.                         z-index: 10000;
  1648.                         width: 150px;
  1649.                         height: 100px;
  1650.                         overflow: unset;
  1651.                 }
  1652.                 .tes-headerCollapsed:hover #room-header-avatar:hover {
  1653.                         z-index: 9;
  1654.                 }
  1655.                 #room-header-gifts {
  1656.                         padding: 10px 10px;
  1657.                 }
  1658.  
  1659.                 .tes-headerCollapsed #tes-settingsGear {
  1660.                         font-size: 33px;
  1661.                 }
  1662.                 .tes-headerCollapsed #tes-settings > div {
  1663.                     height: fit-content;
  1664.                 }
  1665.                 .tes-headerCollapsed #tes-settingsBox {
  1666.                         border-width: 1px;
  1667.                         border-radius: 7px;
  1668.                         border-top-right-radius: 0;
  1669.                         padding-bottom: 7px;
  1670.                 }
  1671.                 .tes-headerCollapsed #tes-settings {
  1672.                         top: 13px;
  1673.                         right: 0;
  1674.                 }
  1675.                 #tes-settings > div#tes-updateNotifier {
  1676.                         top: -200px;
  1677.                         margin-right: -33px;
  1678.                         float: left;
  1679.                         border: #53b6ef 1px solid;
  1680.                         border-radius: 8px 0 0px 8px;
  1681.                         padding: 5px;
  1682.                         padding-right: 32px;
  1683.                         height: auto;
  1684.                         transition: visibility 0s, opacity 0.5s linear;
  1685.                         background: white;
  1686.                 }
  1687.                 #tes-settings.tes-open > div#tes-updateNotifier {
  1688.                         visibility: hidden;
  1689.                         opacity: 0;
  1690.                         width: 0;
  1691.                         height: 0;
  1692.                         padding: 0;
  1693.                 }
  1694.                 #tes-settings > div#tes-updateNotifier:hover { cursor: pointer; }
  1695.                 .tes-closeButtonSmall {
  1696.                         float: left;
  1697.                         padding-right: 5px;
  1698.                         color: #41b7ef;
  1699.                         padding-left: 5px;
  1700.                 }
  1701.                 #tes-settings > div#tes-updateNotifier.visible { top: 38px; }
  1702.                 .tes-closeButtonSmall:hover { color: #7ccefe; }
  1703.  
  1704.                 #room-header.tes-nightmode,
  1705.                 .tes-nightmode #tes-header-grabber {
  1706.                         background-color: var(--nightmode-bgcolor);
  1707.                         border-color: var(--nightmode-trimcolor);
  1708.                 }
  1709.                                 #room-header.tes-nightmode.blacknight,
  1710.                                 .tes-nightmode.blacknight #tes-header-grabber {
  1711.                                         background-color: var(--nightmodeBlack-bgcolor);
  1712.                                         border-color: #222;
  1713.                                         border-bottom-color: #222;
  1714.                                 }
  1715.                 .tes-nightmode #tes-header-grabber:hover { background-color: var(--nightmode-trimcolor); }
  1716.                                 .tes-nightmode.blacknight #tes-header-grabber:hover { background-color: #141414; }
  1717.                 .tes-nightmode #room-header-info-details > span:after { background-color: var(--nightmode-bgcolor); }
  1718.                                 .tes-nightmode.blacknight #room-header-info-details > span:after { background-color: var(--nightmodeBlack-bgcolor); }
  1719.                 .tes-nightmode #tes-header-grabber { color: #565e61; }
  1720.                 .tes-nightmode #room-header-info > h1 { color: var(--nightmode-textcolor); }
  1721.                 .tes-nightmode #room-header-info > h1:after,
  1722.                 .tes-nightmode #room-header-info-text:after {
  1723.                         opacity: 0;
  1724.                 }
  1725.                 .tes-nightmode #room-header-gifts-items { background-color: #313c3f; }
  1726.                 .tes-nightmode #room-header-gifts-items > a > img { mix-blend-mode: multiply; }
  1727.                 .tes-nightmode #room-header-gifts-items:hover > a > img { mix-blend-mode: unset; }
  1728.                 .tes-nightmode #room-header-info-details > a { color: #417186; }
  1729.                 .tes-nightmode #tes-settings { color: #98a1a4; }
  1730.                 .tes-nightmode #tes-settingsGear { color: #145876; }
  1731.                 .tes-nightmode #tes-settingsGear:hover { color: #1c7ca6; }
  1732.                 .tes-nightmode #tes-settingsBox,
  1733.                 .tes-nightmode .tes-open #tes-settingsGear {
  1734.                         background-color: #354245;
  1735.                         border-color: var(--nightmode-trimcolor);
  1736.                 }
  1737.                                 .tes-nightmode.blacknight #tes-settingsBox,
  1738.                                 .tes-nightmode.blacknight .tes-open #tes-settingsGear {
  1739.                                         background-color: #222;
  1740.                                         border-color: #333;
  1741.                                 }
  1742.                 .tes-nightmode #tes-settings > div#tes-updateNotifier { border-color: #5d7883; }
  1743.                 .tes-nightmode #tes-settings > div#tes-updateNotifier {
  1744.                         background-color: #354245;
  1745.                         border-color: #145876;
  1746.                 }
  1747.                 .tes-nightmode input {
  1748.                         background: #626b6f;
  1749.                         color: #c4c8ca;
  1750.                         border-color: #79868b;
  1751.                 }
  1752.                                 .tes-nightmode.blacknight input {
  1753.                                         background: #444;
  1754.                                         border-color: #666;
  1755.                                 }
  1756.                 .tes-nightmode #tes-settings .info {
  1757.                         color: var(--nightmode-headerButtonscolor);
  1758.                         border-color: var(--nightmode-headerButtonscolor);
  1759.                 }
  1760.                 .tes-nightmode path { fill: var(--nightmode-headerButtonscolor); }
  1761.                 .tes-nightmode circle { stroke: var(--nightmode-headerButtonscolor); }
  1762.                 @media screen and (max-width: 800px) {
  1763.                         .tes-nightmode #room-header-gifts { background-color: var(--nightmode-bgcolor); }
  1764.                                 .tes-nightmode.blacknight #room-header-gifts { background-color: var(--nightmodeBlack-bgcolor); }
  1765.                         }
  1766.                 .tes-nightmode #room-header-gifts-buttons > #upgrade { background-color: #6d551d; }
  1767.                 .tes-nightmode #room-header-gifts-buttons > #upgrade:hover { background-color: #776231; }
  1768.                 .tes-nightmode #room-header-gifts-buttons > #get-coins {
  1769.                         background-color: #3a474b;
  1770.                         border-color: #275b72;
  1771.                         color: #317490;
  1772.                 }
  1773.                         .tes-nightmode.blacknight #room-header-gifts-buttons > #get-coins { background-color: #222; }
  1774.                 .tes-nightmode #room-header-gifts-buttons > #get-coins:hover {
  1775.                         background-color: #48626a;
  1776.                         color: #5fa9c8;
  1777.                 }
  1778.                 .tes-nightmode #room-header-gifts-buttons > a {
  1779.                         background-color: #275b72;
  1780.                         color: #788f97;
  1781.                 }
  1782.                 .tes-nightmode #room-header-gifts-buttons > #give-gift:hover {
  1783.                         background-color: #1a80a2;
  1784.                         color: #a3b5d2;
  1785.                 } ` + firefoxCSS + `
  1786.         </style>
  1787.         `;
  1788.                     titleCSS.insertAdjacentHTML(insertPosition, titleCSShtml);
  1789.                 }
  1790.  
  1791.                 { // videolistCSS
  1792.                     videolistCSShtml = `
  1793.         <style id="videolistCSS" scope="tc-videolist">` + globalCSS + `
  1794.                 #videos-header {
  1795.                         height: 10px;
  1796.                         min-height: 10px;
  1797.                         background: none!important;
  1798.                         z-index: 5;
  1799.                 }
  1800.                 #videolist.tes-sidemenuCollapsed { width: 93%; }
  1801.                 #Fvideolist * {
  1802.                         width: 75%!important;
  1803.                         display: contents;
  1804.                         float: right;
  1805.                         flex-direction: column;
  1806.                 }
  1807.                 #Fvideos {
  1808.                         flex-direction: unset;
  1809.                         flex-wrap: unset;
  1810.                 }
  1811.                 #videos-header > span {
  1812.                         line-height: initial;
  1813.                         position: relative;
  1814.                         top: 1px;
  1815.                         background: none;
  1816.                 }
  1817.                 #videos-header > span > svg {
  1818.                         height: 16px;
  1819.                         padding: 0;
  1820.                 }
  1821.                 #youtube.video:after { border: none; }
  1822.  
  1823.                 .js-video { transition: all .4s ease-in-out; }
  1824.                 .tes-max-noAnim .js-video { transition: unset; }
  1825.                 .tes-max.videos-items:last-child { edisplay: block; }
  1826.                 /* Smaller footer buttons */
  1827.                 #videos-footer {
  1828.                         height: 43px;
  1829.                         min-height: unset;
  1830.                         padding-bottom: 0;
  1831.                 }
  1832.  
  1833.                 #videos-footer > div {
  1834.                         height: 35px;
  1835.                         min-height: unset;
  1836.                         line-height: 35px;
  1837.                 }
  1838.                 #videos-footer-broadcast-wrapper > div {
  1839.                         height: 35px;
  1840.                         line-height: 37px;
  1841.                         font-size: 15px;
  1842.                 }
  1843.                 #videos-footer-broadcast-wrapper > #videos-footer-push-to-talk { line-height: 34px; }
  1844.                 #videos-footer > div svg { transform: scale(.70); }
  1845.                 #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:before { top: 14px; }
  1846.  
  1847.                 #videolist.tes-nightmode { background: var(--nightmode-bgcolor); }
  1848.                                 #videolist.tes-nightmode.blacknight { background: var(--nightmodeBlack-bgcolor); }
  1849.                 .tes-nightmode #videos-footer-youtube { background-color: #723e3c; }
  1850.                                 .tes-nightmode.blacknight #videos-footer-youtube { background-color: #4e1f1d; }
  1851.                 .tes-nightmode #videos-footer-youtube:hover { background-color: #a83c38; }
  1852.                                 .tes-nightmode.blacknight #videos-footer-youtube:hover { background-color: #742825; }
  1853.  
  1854.                 .tes-nightmode #videos-footer-broadcast,
  1855.                 .tes-nightmode #videos-footer-broadcast-wrapper > #videos-footer-submenu-button {
  1856.                         background-color: #31684c;
  1857.                         color: #519472;
  1858.                 }
  1859.                                 .tes-nightmode.blacknight #videos-footer-broadcast,
  1860.                                 .tes-nightmode.blacknight #videos-footer-broadcast-wrapper > #videos-footer-submenu-button {
  1861.                                         background-color: #12261c;
  1862.                                         color: #2d5240;
  1863.                                 }
  1864.                 .tes-nightmode #videos-footer-broadcast:hover,
  1865.                 .tes-nightmode #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:hover {
  1866.                         background-color: #338e5f;
  1867.                         color: #82d9ad;
  1868.                 }
  1869.                                 .tes-nightmode.blacknight #videos-footer-broadcast:hover,
  1870.                                 .tes-nightmode.blacknight #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:hover {
  1871.                                         background-color: #17402b;
  1872.                                         color: #41956b;
  1873.                                 }
  1874.                 .tes-nightmode #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:before { border-color: #519472 transparent; }
  1875.                                 .tes-nightmode.blacknight #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:before { border-color: #41956b transparent; }
  1876.                 .tes-nightmode #videos-footer-broadcast-wrapper > #videos-footer-submenu-button:hover:before { border-color: #82d9ad transparent; }
  1877.  
  1878.                 .tes-nightmode #videos-footer-push-to-talk { background-color: #31684c; }
  1879.                 .tes-nightmode #videos-footer-push-to-talk path { fill: #82d9ad; }
  1880.                 .tes-nightmode #videos-footer-push-to-talk:hover { background-color: #338e5f; }
  1881.  
  1882.                 #videos-footer-broadcast-wrapper.active-ptt > #videos-footer-push-to-talk { background-color: #404f54; }
  1883.                 #videos-footer-broadcast-wrapper.active-ptt > #videos-footer-push-to-talk path { fill: #74817a; }
  1884.  
  1885.                 .tes-nightmode #videos-footer-broadcast-wrapper.active > #videos-footer-broadcast,
  1886.                 .tes-nightmode #videos-footer-broadcast-wrapper.active > #videos-footer-submenu-button {
  1887.                         background-color: #404f54;
  1888.                         color: #74817a;
  1889.                 }
  1890.                                 .tes-nightmode.blacknight #videos-footer-broadcast-wrapper.active > #videos-footer-broadcast,
  1891.                                 .tes-nightmode.blacknight #videos-footer-broadcast-wrapper.active > #videos-footer-submenu-button {
  1892.                                         background-color: #222;
  1893.                                         color: #555;
  1894.                                 }
  1895.                 .tes-nightmode #videos-footer-broadcast-wrapper.active > #videos-footer-submenu-button:before { border-color: #74817a transparent; }
  1896.                 .tes-nightmode #videos-header path { fill: var(--nightmode-headerButtonscolor); }
  1897.                 .tes-nightmode #videos-header path[fill="none"] { stroke: var(--nightmode-headerButtonscolor); fill: none; }
  1898.                 .tes-nightmode .videos-header-volume { border-color: #3a474b; }
  1899.                                 .tes-nightmode.blacknight .videos-header-volume { border-color: #222; }
  1900.                 .tes-nightmode #videos-footer-youtube path { fill: #996d6c; }
  1901.                                 .tes-nightmode.blacknight #videos-footer-youtube path { fill: #634645; }
  1902.         </style>
  1903.         `;
  1904.                     videolistCSS.insertAdjacentHTML(insertPosition, videolistCSShtml);
  1905.                 }
  1906.  
  1907.                 { // chatlistCSS
  1908.                     chatlistCSShtml = `
  1909.         <style id="chatlistCSS" scope="tinychat-chatlist">` + globalCSS + `
  1910.                 #chatlist.tes-mod { margin-top: 22px; }
  1911.                 #chatlist > div > span {
  1912.                         padding-left: 1px;
  1913.                 }
  1914.                 #chatlist > #header {
  1915.                         top: 3px;
  1916.                         height: auto;
  1917.                 }
  1918.  
  1919.         .list-item > span > span > span.send-gift {
  1920.                         display: none;
  1921.                 }
  1922.  
  1923.                 /*** --- this block is in chatlistCSS & userlistCSS --- ***/
  1924.                         .list-item > span > img {
  1925.                                 right: 13px;
  1926.                                 left: auto;
  1927.                         }
  1928.                         .list-item > span[data-status]:before {
  1929.                                 left: auto;
  1930.                                 right: 0;
  1931.                         }
  1932.                         .list-item > span > span {
  1933.                                 background: none!important;
  1934.                                 box-shadow: none!important;
  1935.                         }
  1936.                 /*** ---                                        --- ***/
  1937.  
  1938.                 .close-instant > path {
  1939.                         fill: white;
  1940.                 }
  1941.                 .list-item > span > span { /* gift and close buttons */
  1942.                         right: 16px;
  1943.                 }
  1944.                 .list-item > span:hover > span { /* gift and close buttons */
  1945.                         right: 16px;
  1946.                         background: var(--nightmode-bgcolor);
  1947.                 }
  1948.  
  1949.                 /*** --- this block is in chatlistCSS & userlistCSS --- ***/
  1950.                 .tes-nightmode.blacknight .list-item > span,
  1951.                 .tes-nightmode.blacknight .list-item > span> span {
  1952.                         background: var(--nightmodeBlack-bgcolor);
  1953.                 }
  1954.                 .tes-nightmode.blacknight .list-item > span > span { box-shadow: 0 0 3px 3px var(--nightmodeBlack-bgcolor); }
  1955.                 .tes-nightmode.blacknight .list-item > span:hover,
  1956.                 .tes-nightmode.blacknight .list-item > span:hover > span,
  1957.                 .tes-nightmode.blacknight .list-item + .list-item > span:hover,
  1958.                 #chatlist.tes-nightmode.blacknight > #header ~ .list-item > span.active {
  1959.                         background: #222;
  1960.                 }
  1961.                 /*** ---                                        --- ***/
  1962.  
  1963.         </style>
  1964.         `;
  1965.                     chatlistCSS.insertAdjacentHTML(insertPosition, chatlistCSShtml);
  1966.                 }
  1967.  
  1968.                 { // userlistCSS
  1969.                     userlistCSShtml = `
  1970.         <style id="userlistCSS" scope="tinychat-userlist">` + globalCSS + `
  1971.                 #userlist > div > span {
  1972.                         padding-left: 1px;
  1973.                 }
  1974.                 .list-item > span > span {
  1975.                         right: auto;
  1976.                         padding: 0 5px;
  1977.                 }
  1978.                 .list-item > span > .nickname {
  1979.                         padding-right: 3px;
  1980.                         transition: .5s;
  1981.                 }
  1982.                 .nickname.tes-myNick { color: #b3b3b3; }
  1983.  
  1984.         .list-item > span > span > span.send-gift {
  1985.                         display: none;
  1986.                 }
  1987.  
  1988.                 /*** --- this block is in chatlistCSS & userlistCSS --- ***/
  1989.                         .list-item > span > img {
  1990.                                 right: 13px;
  1991.                                 left: auto;
  1992.                         }
  1993.                         .list-item > span[data-status]:before {
  1994.                                 left: auto;
  1995.                                 right: 0;
  1996.                         }
  1997.                         .list-item > span > span {
  1998.                                 background: none;
  1999.                                 box-shadow: none;
  2000.                         }
  2001.                 /*** ---                                        --- ***/
  2002.  
  2003.                 .list-item > span > span[data-moderator="1"]:before {
  2004.                         filter: hue-rotate(226deg) saturate(4000%);
  2005.                 }
  2006.                 #userlist > #header {
  2007.                         top: auto;
  2008.                         height: auto;
  2009.                         overflow: unset;
  2010.                 }
  2011.                 #header > span {
  2012.                         width: unset!important;
  2013.                         overflow: unset!important;
  2014.                         }
  2015.                 #button-banlist {
  2016.                         right: -34px;
  2017.                         position: fixed;
  2018.                         top: 74px;
  2019.                         left: 1px;
  2020.                         width: 147px;
  2021.                         transition: 1s;
  2022.                         z-index: 8;
  2023.                 }
  2024.                 @media screen and (max-width: 1000px) {
  2025.                         #button-banlist {
  2026.                                 top: -80px;
  2027.                                 left: 5px;
  2028.                                 width: 115px;
  2029.                                 position: absolute;
  2030.                         }
  2031.                 }
  2032.                 .tes-sidemenuCollapsed #button-banlist {
  2033.                         left: -100px;
  2034.                         width: 10px;
  2035.                         opacity: 0;
  2036.                 }
  2037.                 #contextmenu { z-index: 6; }
  2038.                 #userlist .yourname, span[data-user-id="840113"] {
  2039.                         color: white!important;
  2040.                 }
  2041.  
  2042.                 /*** --- this block is in chatlistCSS & userlistCSS --- ***/
  2043.                 .tes-nightmode.blacknight .list-item > span,
  2044.                 .tes-nightmode.blacknight .list-item > span> span {
  2045.                         background: var(--nightmodeBlack-bgcolor);
  2046.                 }
  2047.                 .tes-nightmode.blacknight .list-item > span > span { box-shadow: 0 0 3px 3px var(--nightmodeBlack-bgcolor); }
  2048.                 .tes-nightmode.blacknight .list-item > span:hover,
  2049.                 .tes-nightmode.blacknight .list-item > span:hover > span,
  2050.                 .tes-nightmode.blacknight .list-item + .list-item > span:hover,
  2051.                 #chatlist.tes-nightmode.blacknight > #header ~ .list-item > span.active {
  2052.                         background: #222;
  2053.                 }
  2054.                 /*** ---                                        --- ***/
  2055.                 .tes-nightmode.blacknight .list-item > span:hover > span { box-shadow: 0 0 3px 3px #222; }
  2056.                 .tes-nightmode.blacknight #button-banlist { background: #222; }
  2057.                 .tes-nightmode.blacknight #button-banlist:hover { background: #00708f; }
  2058.  
  2059.                 /*#userlist > div {
  2060.                   transition: 0s; animation-duration: 0s; -webkit-animation-duration: 0s;
  2061.                 }*/
  2062.         </style>
  2063.         `;
  2064.                     userlistCSS.insertAdjacentHTML(insertPosition, userlistCSShtml);
  2065.                 }
  2066.  
  2067.                 { // userContextmenuCSS
  2068.                     userContextmenuCSShtml = `
  2069.         <style id="userContextmenuCSS" scope="tinychat-user-contextmenu">` + globalCSS + `
  2070.                 #main {
  2071.                         border: 1px solid rgba(0, 0, 0, .1);
  2072.                 }
  2073.         </style>
  2074.         `;
  2075.                     userContextmenuCSS.insertAdjacentHTML(insertPosition, userContextmenuCSShtml);
  2076.                 }
  2077.  
  2078.                 { // bodyCSS
  2079.                     bodyCSShtml = `
  2080.         <style id="bodyCSS">` + globalCSS + `
  2081.                 #nav-static-wrapper {
  2082.                         width: 2px;
  2083.                         opacity: .7;
  2084.                 }
  2085.                 @media screen and (max-width: 1000px) {
  2086.                         #nav-static-wrapper {
  2087.                                 width: 82px;
  2088.                                 opacity: 1;
  2089.                         }
  2090.                 }
  2091.            #content {
  2092.                    padding: 0;
  2093.                 }
  2094.             #menu-icon { transition: 1s; }
  2095.                 .tes-sidemenuCollapsed #menu-icon {
  2096.                         z-index: -1;
  2097.                         opacity: 0;
  2098.                 }
  2099.                 body.tes-changefont {
  2100.                   font-family: sans-serif;
  2101.                 }
  2102.                 #header-user {
  2103.                         left: 62px;
  2104.                         bottom: 22px;
  2105.                         transition: 1s;
  2106.                 }
  2107.                 .tes-sidemenuCollapsed #header-user { display: none; }
  2108.                 @media screen and (max-width: 1000px) {
  2109.                         #header-user {
  2110.                                 left: 21px;
  2111.                         }
  2112.                 }
  2113.                 @media screen and (max-width: 600px) {
  2114.                         #header-user {
  2115.                                 left: auto;
  2116.                                 right: 54px;
  2117.                         }
  2118.                 }
  2119.                 @media screen and (min-width: 1000px) {
  2120.                         #menu-icon:hover { opacity: 1; }
  2121.                         #menu-icon {
  2122.                                 top: 4px;
  2123.                                 left: 19px;
  2124.                                 height: 12px;
  2125.                                 width: 109px;
  2126.                                 font-size: 10px;
  2127.                                 background: #04caff;
  2128.                                 border-radius: 6px;
  2129.                                 opacity: .8;
  2130.                         }
  2131.                         #menu-icon:after {
  2132.                                 position: absolute;
  2133.                                 top: 3px;
  2134.                                 left: 51px;
  2135.                                 content: "";
  2136.                                 height: 7px;
  2137.                                 width: 7px;
  2138.                                 border-width: 2px 2px 0px 0px;
  2139.                                 border-style: solid;
  2140.                                 border-color: #fff;
  2141.                                 box-sizing: border-box;
  2142.                                 transform: rotate(45deg);
  2143.                                 transition: .2s;
  2144.                         }
  2145.                         #menu-icon:hover:after {
  2146.                                 left: 55px;
  2147.                         }
  2148.                         #menu-icon.expanded:after {
  2149.                                 border-width: 0px 0px 2px 2px;
  2150.                         }
  2151.                         #menu-icon.expanded:hover:after {
  2152.                                 left: 40px;
  2153.                         }
  2154.                         #menu-icon > svg {
  2155.                                 opacity: 0;
  2156.                         }
  2157.                 }
  2158.  
  2159.                 body.tes-nightmode {
  2160.                         color: var(--nightmode-textcolor);
  2161.                         background: var(--nightmode-bgcolor);
  2162.                 }
  2163.                                 body.tes-nightmode.blacknight {
  2164.                                         color: gray;
  2165.                                         background: var(--nightmodeBlack-bgcolor);
  2166.                                 }
  2167.                 .tes-nightmode.blacknight #nav-static-wrapper { background: var(--nightmodeBlack-bgcolor); }
  2168.         </style>
  2169.         `;
  2170.                     bodyCSS.insertAdjacentHTML(insertPosition, bodyCSShtml);
  2171.                 }
  2172.  
  2173.                 messageCSS = `
  2174.                 /* PLACEHOLDER for general msg css modifications that always apply inside its own shadowroot. */
  2175.         `;
  2176.  
  2177.                 messageCSSNightmode = `
  2178.          #html { color: var(--nightmode-textcolor); }
  2179.  
  2180.                 .tes-nightmode.tes-mention-message { color: #e44a3f; }
  2181.                 .tes-nightmode.message.system,
  2182.                 .tes-nightmode #chat-content > .message.system {
  2183.                         background-color: #313c3f;
  2184.                         color: #677174;
  2185.                 }
  2186.        .tes-nightmode.blacknight.message.system,
  2187.        .tes-nightmode.blacknight #chat-content > .message.system {
  2188.            background-color: #090909;
  2189.            color: #4d4d4d;
  2190.         }
  2191.      `;
  2192.                 messageCSSBlacknight = `
  2193.          #html { color: gray; }
  2194.      `;
  2195.  
  2196.                 messageCSSMention = `#html { color: red !important }`;
  2197.  
  2198.                 messageCSSSpam = ` { display: none; }`; // Partial code! Implemented with JS.
  2199.  
  2200.                 { // chatlogCSS
  2201.                     chatlogCSShtml = `
  2202.         <style id="chatlogCSS" scope="tinychat-chatlog">` + globalCSS + `
  2203.  
  2204.                 #chat-content > .message {
  2205.                         padding-bottom: 0;
  2206.                         padding-top: 0!important;
  2207.                         margin-bottom: 0;
  2208.                         min-height: 0px!important;
  2209.                 }
  2210.                 /*
  2211.                 #chat-content > .message:hover {
  2212.                         background: rgba(0, 0, 0, 0.03);
  2213.                 }
  2214.                 */
  2215.  
  2216.                 .message a:first-child,
  2217.                 .message a:first-child img:first-child {
  2218.                         transition: .1s;
  2219.             pointer-events: none;
  2220.                 }
  2221.         /*
  2222.                 .message a:first-child:hover {
  2223.                         width: 100px!important;
  2224.                         height: 75px!important;
  2225.                         z-index: 1000;
  2226.                 }
  2227.         */
  2228.  
  2229.                 #chat-content > .message.common {
  2230.                         margin-bottom: 5px;
  2231.                 }
  2232.                 #chat-content > .message.system {
  2233.                         padding: 0;
  2234.                 }
  2235.                 #chat-content.tes-notif-off > .message.system {
  2236.                         display: none;
  2237.                 }
  2238.                 #chat-content.tes-notif-off > .message.system.dontHide {
  2239.                         display: initial;
  2240.                 }
  2241.                 #chat-instant > a:first-child,
  2242.                 #chat-content > .message > a:first-child {
  2243.                         top: auto;
  2244.                  }
  2245.                 #chat-position { bottom: 3px; }
  2246.                 #chat-position #input:before { background: none; }
  2247.                 #chat-instant > a > .avatar,
  2248.                 #chat-content > .message > a > .avatar {
  2249.                         border-radius: unset;
  2250.                 }
  2251.                 #timestamp {
  2252.                         font-size: 11px;
  2253.                         color: silver;
  2254.                         /* float: right; */
  2255.                         position: absolute;
  2256.                         right: 0;
  2257.             top: 0;
  2258.                         padding-top: 3px;
  2259.             cursor: default;
  2260.                 }
  2261.                 #timestamp:hover {
  2262.                         z-index: 500;
  2263.                         background: var(--bgcolor);
  2264.                         padding-left: 5px;
  2265.                 }
  2266.                 #chat-content > .message > .nickname {
  2267.                         overflow: initial;
  2268.                         line-height: initial;
  2269.             pointer-events: none;
  2270.                 }
  2271.                 #chat-content div.message.common:last-of-type {
  2272.                         margin-bottom: 10px;
  2273.                 }
  2274.                 #chat-instant-button.tes-loading {
  2275.                         border: 0;
  2276.                         font-size: x-large;
  2277.                         animation: spin .5s linear infinite;
  2278.                 }
  2279.                 @keyframes spin {
  2280.                         0% { transform: rotate(0deg); }
  2281.                         100% { transform: rotate(360deg); }
  2282.                 }
  2283.                 #tes-chatlogDisplay {
  2284.                         display: none;
  2285.                         position: fixed;
  2286.                         top: 50px;
  2287.                         left: 50px;
  2288.                         width: 90%;
  2289.                         height: 80%;
  2290.                         z-index: 7;
  2291.                         cursor: default;
  2292.                 }
  2293.                 #tes-chatlogDisplay.show { display: unset; }
  2294.                 #tes-chatlogDisplay * {
  2295.                         float: left;
  2296.                         height: 100%;
  2297.                 }
  2298.                 #tes-chatlogDisplay textarea {
  2299.                         background: rgba(255, 255, 255, .8);
  2300.                         transition: .2s;
  2301.                         opacity: 0;
  2302.                         border-radius: 6px;
  2303.                         width: 90%;
  2304.                 }
  2305.                 #tes-chatlogDisplay textarea.show {
  2306.                         opacity: 1;
  2307.                 }
  2308.                 #tes-chatlogDisplay #close {
  2309.                         opacity: 0;
  2310.                         transition: .2s;
  2311.                         width: 40px;
  2312.                         background: #41b7ef;
  2313.                         height: 40px;
  2314.                         border-top-right-radius: 10px;
  2315.                         border-bottom-right-radius: 10px;
  2316.                         position: relative;
  2317.                         color: white;
  2318.                         top: 40%;
  2319.                         vertical-align: middle;
  2320.                         font-size: 22px;
  2321.                         text-align: center;
  2322.                         padding-top: 8px;
  2323.                         cursor: pointer;
  2324.                 }
  2325.                 #tes-chatlogDisplay #close:hover {
  2326.                         background: #72caf3;
  2327.                 }
  2328.                 #tes-chatlogDisplay #close.show {
  2329.                         opacity: 1;
  2330.                 }
  2331.                 #tes-chatlogButtons {
  2332.                         position: absolute;
  2333.                         top: 2px;
  2334.                         left: 6px;
  2335.                         font: 15px monospace;
  2336.                         z-index: 11;
  2337.                 }
  2338.                 .tes-chatlogBut {
  2339.                         padding: 2px;
  2340.                         border-radius: 4px;
  2341.                         border: silver 1px solid;
  2342.                         color: silver;
  2343.                         transition: .3s;
  2344.                         width: 10px;
  2345.                         height: 10px;
  2346.                         overflow: hidden;
  2347.                         cursor: pointer;
  2348.                         opacity: 1;
  2349.                         float: left;
  2350.                 }
  2351.                 .tes-chatlogBut:hover {
  2352.                         width: 1.5em;
  2353.                         color: var(--textcolor);
  2354.                         border-color: var(--textcolor);
  2355.                 }
  2356.                 .tes-chatlogBut ~ .tes-chatlogBut { margin-left: 2px; }
  2357.                 .tes-chatlogBut .icon { width: auto; }
  2358.                 .tes-chatlogBut .label {
  2359.                         width: 0;
  2360.                         opacity: 0;
  2361.                         overflow: hidden;
  2362.                         transition: .3s;
  2363.                         display: block;
  2364.                         position: relative;
  2365.                         top: -2px;
  2366.                         left: 13px;
  2367.                         font: 11px sans-serif;
  2368.                         color: var(--textcolor);
  2369.                 }
  2370.                 .tes-chatlogBut:hover .label {
  2371.                         opacity: 1;
  2372.                         width: auto;
  2373.                 }
  2374.                 .tes-chatboxPM #tes-chatlogSave {
  2375.                         opacity: 0;
  2376.                         z-index: -5;
  2377.                 }
  2378.                 #tes-chatlogSave .icon {
  2379.                         /* transform: scaleY(.6); */
  2380.                         position: absolute;
  2381.                         top: -1px;
  2382.                         left: 4px;
  2383.                 }
  2384.                 #tes-chatlogSave .icon svg {
  2385.                         width: 19px;
  2386.                         height: 19px;
  2387.                         position: relative;
  2388.                         left: -3px;
  2389.                 }
  2390.                 #tes-chatlogSave .icon path {
  2391.                         transform: scale(.08) scaleX(1.2) rotate(180deg);
  2392.                         10%: 10px
  2393.                         height:;
  2394.                         fill: #ccc;
  2395.                         transform-origin: 11px 12px;
  2396.                 }
  2397.                 #tes-chatlogSave:hover .icon path { fill: var(--textcolor); }
  2398.                 #tes-chatlogSave:hover { width: 4.2em; }
  2399.                 #tes-chatlogSave:hover .label { width: 4.3em; }
  2400.                 #tes-chatlogView .icon {
  2401.                         font-size: 10px;
  2402.                         top: 1px;
  2403.                         position: absolute;
  2404.                 }
  2405.                 #tes-chatlogView:hover { width: 2.5em; }
  2406.  
  2407.                 .tes-nightmode #tes-chatlogSave .icon path { fill: var(--nightmode-textSecondarycolor); }
  2408.                         .tes-nightmode.blacknight #tes-chatlogSave .icon path { fill: #444; }
  2409.                 .tes-nightmode #tes-chatlogSave:hover .icon path { fill: var(--nightmode-textcolor); }
  2410.                         .tes-nightmode.blacknight #tes-chatlogSave:hover .icon path { fill: gray; }
  2411.                 .tes-nightmode .tes-chatlogBut {
  2412.                         color: var(--nightmode-textSecondarycolor);
  2413.                         border-color: var(--nightmode-textSecondarycolor);
  2414.                 }
  2415.                                 .tes-nightmode.blacknight .tes-chatlogBut {
  2416.                                         color: #444;
  2417.                                         border-color: #444;
  2418.                                 }
  2419.                 .tes-nightmode .tes-chatlogBut:hover {
  2420.                         color: var(--nightmode-textcolor);
  2421.                         border-color: var(--nightmode-textcolor);
  2422.                 }
  2423.                                 .tes-nightmode.blacknight .tes-chatlogBut:hover {
  2424.                                         color: #777;
  2425.                                         border-color: #777;
  2426.                                 }
  2427.                 .tes-nightmode #tes-chatlogDisplay textarea {
  2428.                         background: rgba(45, 55, 58, .8);
  2429.                         color: var(--nightmode-textcolor);
  2430.                         border: 1px solid #506368;
  2431.                         caret-color: #41b7ef;
  2432.                 }
  2433.                                 .tes-nightmode.blacknight #tes-chatlogDisplay textarea {
  2434.                                         background: rgba(0, 0, 0, .8);
  2435.                                         color: gray;
  2436.                                         border: 1px solid #444;
  2437.                                 }
  2438.                 .tes-nightmode .tes-chatlogBut .label { color: var(--nightmode-textcolor); }
  2439.                                 .tes-nightmode.blacknight .tes-chatlogBut .label { color: gray; }
  2440.                 .tes-nightmode #chat-content > .message > .nickname[data-status=""],
  2441.                 .tes-nightmode #chat-instant > .nickname[data-status=""] {
  2442.                         color: var(--nightmode-textcolor);
  2443.                 }
  2444.                                 .tes-nightmode.blacknight #chat-content > .message > .nickname[data-status=""],
  2445.                                 .tes-nightmode.blacknight #chat-instant > .nickname[data-status=""] {
  2446.                                         color: gray;
  2447.                                 }
  2448.  
  2449.                 #chat-wrapper.tes-nightmode,
  2450.                 .tes-nightmode .on-white-scroll::-webkit-scrollbar-track,
  2451.                 .tes-nightmode #textarea,
  2452.                 .tes-nightmode #chat-instant {
  2453.                         background: var(--nightmode-bgcolor);
  2454.                         color: var(--nightmode-textcolor);
  2455.                 }
  2456.                                 #chat-wrapper.tes-nightmode.blacknight,
  2457.                                 .tes-nightmode.blacknight .on-white-scroll::-webkit-scrollbar-track,
  2458.                                 .tes-nightmode.blacknight #textarea,
  2459.                                 .tes-nightmode.blacknight #chat-instant {
  2460.                                         background: var(--nightmodeBlack-bgcolor);
  2461.                                         color: gray;
  2462.                                 }
  2463.                 .tes-nightmode #input > .waiting { background-color: var(--nightmode-trimcolor); }
  2464.                         .tes-nightmode.blacknight #input > .waiting { background-color: #222; }
  2465.  
  2466.                 .tes-nightmode .on-white-scroll::-webkit-scrollbar-thumb {
  2467.                         border-color: var(--nightmode-bgcolor);
  2468.                 }
  2469.                                 .tes-nightmode.blacknight .on-white-scroll::-webkit-scrollbar-thumb {
  2470.                                         border-color: var(--nightmodeBlack-bgcolor);
  2471.                                 }
  2472.  
  2473.                 #chat-wrapper.tes-nightmode { border-color: var(--nightmode-trimcolor); }
  2474.                                 #chat-wrapper.tes-nightmode.blacknight { border-color: #222; }
  2475.                 .tes-nightmode #timestamp { color: var(--nightmode-textSecondarycolor); }
  2476.                                 .tes-nightmode.blacknight #timestamp { color: #545454; }
  2477.                 #chat-wider.tes-nightmode { background-color: var(--nightmode-trimcolor); }
  2478.                                 #chat-wider.tes-nightmode.blacknight { background-color: #141414; }
  2479.                 #chat-wider.tes-nightmode:before { border-color: transparent #636e6e; }
  2480.                                 #chat-wider.tes-nightmode.blacknight:before { border-color: transparent #444; }
  2481.                 .tes-nightmode #input:after { border-color: var(--nightmode-trimcolor); }
  2482.                                 .tes-nightmode.blacknight #input:after { border-color: #222; }
  2483.                 .tes-nightmode #chat-content > .message.system { background-color: #313c3f; }
  2484.                                 .tes-nightmode.blacknight #chat-content > .message.system { background-color: #090909; }
  2485.                 .tes-nightmode.blacknight .on-white-scroll::-webkit-scrollbar-thumb { background-color: #111; }
  2486.                 .tes-nightmode #timestamp:hover { background-color: var(--nightmode-bgcolor); }
  2487.                         .tes-nightmode.blacknight #timestamp:hover { background-color: var(--nightmodeBlack-bgcolor); }
  2488.  
  2489.                 #chat-instant > .nickname[data-status="gold"], #chat-wrapper.full-screen #chat-instant > .nickname[data-status="gold"], #chat-content > .message > .nickname[data-status="gold"], #chat-wrapper.full-screen #chat-content > .message > .nickname[data-status="gold"] {
  2490.                         color: unset !important;
  2491.                 }
  2492.  
  2493.                 #chat-instant > .nickname[data-status="extreme"], #chat-wrapper.full-screen #chat-instant > .nickname[data-status="extreme"], #chat-content > .message > .nickname[data-status="extreme"], #chat-wrapper.full-screen #chat-content > .message > .nickname[data-status="extreme"] {
  2494.                         color: unset !important;
  2495.                 }
  2496.  
  2497.                 #chat-instant > .nickname[data-status="pro"], #chat-wrapper.full-screen #chat-instant > .nickname[data-status="pro"], #chat-content > .message > .nickname[data-status="pro"], #chat-wrapper.full-screen #chat-content > .message > .nickname[data-status="pro"] {
  2498.                         color: unset !important;
  2499.                 }
  2500.  
  2501.                 #chat-content > .message.sub-pro > .avatar, #chat-content > .message.sub-extreme > .avatar, #chat-content > .message.sub-gold > .avatar {
  2502.                         animation-duration: 0s !important;-webkit-animation-duration: 0s !important;
  2503.                 }
  2504.         </style>
  2505.         `;
  2506.                     chatlogCSS.insertAdjacentHTML(insertPosition, chatlogCSShtml);
  2507.                 }
  2508.  
  2509.                 { // sidemenuCSS
  2510.                     var firefoxCSS = "";
  2511.                     if (browserSpoofedChrome) {
  2512.                         firefoxCSS = `
  2513.                         #sidemenu {
  2514.                                 left: 0!important;
  2515.                         }
  2516.                 `;
  2517.                     }
  2518.                     sidemenuCSShtml = `
  2519.         <style id="sidemenuCSS" scope="tinychat-sidemenu">` + globalCSS + `
  2520.                 #sidemenu {
  2521.                         min-width: 200px;
  2522.                         max-width: 10%;
  2523.                         left: auto;
  2524.                         transition: 1s;
  2525.         }
  2526.                 * {
  2527.                   scrollbar-color: #5A6366 transparent;
  2528.                   scrollbar-width: thin;
  2529.                 }
  2530.                 @media screen and (max-width: 1000px) {
  2531.                         #sidemenu {
  2532.                                 left: -188px;
  2533.                         }
  2534.                 }
  2535.                 #sidemenu-content {
  2536.                         padding-left: 2px;
  2537.                 }
  2538.                 #live-directory-wrapper {
  2539.                         padding: 0;
  2540.                 }
  2541.                 #top-buttons-wrapper {
  2542.                         padding: 0;
  2543.                 }
  2544.                 #user-info { transition: 1s; }
  2545.                 .logged-in #user-info {
  2546.                         padding: 0;
  2547.                         height: auto;
  2548.                         text-align: center;
  2549.                 }
  2550.                 #user-info > div { overflow: unset; }
  2551.                 #user-info > div:before {
  2552.                     position: relative;
  2553.                         top: 0;
  2554.                 }
  2555.                 #user-info button { opacity: .8; }
  2556.                 #user-info:hover button { opacity: 1; }
  2557.                 #user-info > a { display: none; }
  2558.                 #user-info:hover > a { display: initial; }
  2559.                 /* Smaller footer */
  2560.                 #user-info > button {
  2561.                         height: 26px;
  2562.                         line-height: 25px;
  2563.                         font-size: 15px;
  2564.                 }
  2565.                 #user-info {
  2566.                         padding: 6px 26px;
  2567.                         height: 40px;
  2568.                 }
  2569.                 @media screen and (min-width: 1000px) {
  2570.                         #live-directory, #upgrade {
  2571.                                 height: 23px;
  2572.                                 line-height: 22px;
  2573.                                 font-size: 13px;
  2574.                                 opacity: .8;
  2575.                         }
  2576.                         #live-directory:before {
  2577.                                 height: 8px;
  2578.                                 width: 8px;
  2579.                                 top: 0px;
  2580.                         }
  2581.                         #upgrade {
  2582.                                 margin-top: 4px;
  2583.                         }
  2584.                         #live-directory:hover, #upgrade:hover {
  2585.                                 opacity: 1;
  2586.                         }
  2587.                 }
  2588.                 #sidemenu.tes-sidemenuCollapsed {
  2589.                         min-width: 10px;
  2590.                         max-width: 10px;
  2591.                 }
  2592.                 .tes-sidemenuCollapsed #user-info { display: none; }
  2593.                 #tes-sidemenu-grabber {
  2594.                         position: absolute;
  2595.                         top: 50%;
  2596.                         right: 0;
  2597.                         background: var(--nightmode-trimcolor);
  2598.                         color: #536165;
  2599.                         z-index: 3;
  2600.                         border-radius: 10px 0 0 10px;
  2601.                         height: 37px;
  2602.                         padding-top: 24px;
  2603.                         width: 21px;
  2604.                         text-align: center;
  2605.                         font-size: 11px;
  2606.                         transition: .4s;
  2607.  
  2608.                         /*
  2609.                         background: white;
  2610.                         border: #dddddd 1px solid;
  2611.                         border-right: 0;
  2612.                         */
  2613.                 }
  2614.                 #tes-sidemenu-grabber:hover {
  2615.                         background: #506368;
  2616.                         color: #788c91;
  2617.                         cursor: pointer;
  2618.                 }
  2619.                 .tes-sidemenuCollapsed #tes-sidemenu-grabber {
  2620.                         border-radius: 0 10px 10px 0;
  2621.                         right: -7px;
  2622.                         text-align: right;
  2623.                         padding-right: 3px;
  2624.                 }
  2625.                 .tes-sidemenuCollapsed #tes-sidemenu-grabber:hover {
  2626.                         right: -18px;
  2627.                         padding-right: 9px;
  2628.                         width: 18px;
  2629.                 }
  2630.                 #tes-sidemenufakeborder {
  2631.                         display: none;
  2632.                         position: absolute;
  2633.                         right: 0;
  2634.                         width: 1px;
  2635.                         height: 100px;
  2636.                 }
  2637.                 ` + firefoxCSS +
  2638.                         `
  2639.                 .tes-nightmode #tes-sidemenufakeborder {
  2640.                         display: unset;
  2641.                         background: var(--nightmode-trimcolor);
  2642.                 }
  2643.                         .tes-nightmode.blacknight #tes-sidemenufakeborder { background: var(--nightmodeBlack-trimcolor); }
  2644.                 .tes-nightmode #sidemenu-content { border-right: var(--nightmode-trimcolor) 1px solid; }
  2645.                         .tes-nightmode.blacknight #sidemenu-content { border-right: var(--nightmodeBlack-trimcolor) 1px solid; }
  2646.  
  2647.                 #sidemenu.tes-nightmode.blacknight,
  2648.                 .tes-nightmode.blacknight #sidemenu-content::-webkit-scrollbar-track {
  2649.                         background: var(--nightmodeBlack-bgcolor);
  2650.                 }
  2651.                 #sidemenu.tes-nightmode.blacknight,
  2652.                 .tes-nightmode.blacknight #sidemenu-content::-webkit-scrollbar-track {
  2653.                         background: var(--nightmodeBlack-bgcolor);
  2654.                 }
  2655.                 .tes-nightmode.blacknight #tes-sidemenu-grabber {
  2656.                         background: #141414;
  2657.                         color: #3b3b3b;
  2658.                 }
  2659.                 .tes-nightmode.blacknight #tes-sidemenu-grabber:hover {
  2660.                         background: #333;
  2661.                         color: #5c5c5c;
  2662.                 }
  2663.                 .tes-nightmode.blacknight #user-info { background: var(--nightmodeBlack-bgcolor); }
  2664.                 .tes-nightmode.blacknight #user-info > button {
  2665.                         background: #035268;
  2666.                         color: #aaa;
  2667.                 }
  2668.                 .tes-nightmode.blacknight #user-info > button:hover {
  2669.                         background: #0080a3;
  2670.                         color: white;
  2671.                 }
  2672.                 .tes-nightmode.blacknight #sidemenu-content::-webkit-scrollbar-thumb {
  2673.                         border: 5px solid var(--nightmodeBlack-bgcolor);
  2674.                         background-color: #111;
  2675.                 }
  2676.         </style>
  2677.         `;
  2678.                     sidemenuCSS.insertAdjacentHTML(insertPosition, sidemenuCSShtml);
  2679.                 }
  2680.  
  2681.                 { // videomoderationCSS
  2682.                     videomoderationCSShtml = `
  2683.         <style id="videomoderationCSS" scope="tc-video-moderation">` + globalCSS + `
  2684.                 #moderatorlist {
  2685.                         padding-left: 0;
  2686.                         z-index: 7;
  2687.                 }
  2688.                 #moderatorlist:hover {
  2689.                     position: absolute;
  2690.                         background: white;
  2691.                         z-index: 1000;
  2692.                         width: 300px;
  2693.                         min-height: 155px;
  2694.                         flex-direction: column;
  2695.                         position: absolute;
  2696.                         background: rgba(45, 55, 58, 0.8);
  2697.                         z-index: 1000;
  2698.                         width: 350px;
  2699.                         max-height: fit-content!important;
  2700.                         left: 15px;
  2701.                         border-radius: 13px;
  2702.                         border: #47575c 1px solid;
  2703.                         top: 105px;
  2704.                 }
  2705.                 #moderatorlist:after {
  2706.                         top: 47px;
  2707.                 }
  2708.                 #moderatorlist:hover #header {
  2709.                         height: unset;
  2710.                         top: unset;
  2711.                 }
  2712.  
  2713.                 #moderatorlist.tes-nightmode.blacknight > #header > span > button { background: var(--nightmodeBlack-bgcolor); }
  2714.                 #moderatorlist.tes-nightmode.blacknight:hover {
  2715.                         background: var(--nightmodeBlack-bgcolor);
  2716.                         border-color: #333;
  2717.                 }
  2718.         </style>
  2719.         `;
  2720.                     videomoderationCSS.insertAdjacentHTML(insertPosition, videomoderationCSShtml);
  2721.                 }
  2722.  
  2723.                 { // webappCSS
  2724.                     webappCSShtml = `
  2725.         <style id="webappCSS" scope="tinychat-webrtc-app">` + globalCSS + `
  2726.                 #room {
  2727.                         padding: 0;
  2728.                         padding-left: 200px;
  2729.                 }
  2730.                 #room.tes-sidemenuCollapsed { padding-left: 0; }
  2731.                 @media screen and (max-width: 1000px) {
  2732.                         :host > #room {
  2733.                                 padding-left: 82px;
  2734.                         }
  2735.                 }
  2736.                 @media screen and (max-width: 600px) {
  2737.                         :host > #room {
  2738.                                 padding-left: 0;
  2739.                         }
  2740.                 }
  2741.                 .tes-nightmode tc-videolist { background: var(--nightmode-bgcolor); }
  2742.                 .tes-nightmode.blacknight tc-videolist { background: var(--nightmodeBlack-bgcolor); }
  2743.         </style>
  2744.         `;
  2745.                     webappCSS.insertAdjacentHTML(insertPosition, webappCSShtml);
  2746.                 }
  2747.             } catch (e) {
  2748.                 tcl("error injectCSS: " + e.message);
  2749.             }
  2750.         }
  2751.  
  2752.         function injectElements() {
  2753.             try {
  2754.                 headerGrabberParElem = titleElem.querySelector("#room-header");
  2755.                 headerGrabberParElem.insertAdjacentHTML("beforeend", `<div id="tes-header-grabber">▲</div>`);
  2756.                 headerGrabberElem = headerGrabberParElem.querySelector("#tes-header-grabber");
  2757.                 headerGrabberElem.addEventListener("click", headerGrabber);
  2758.  
  2759.                 sidemenuOverlayElem = bodyElem.querySelector("#menu-icon");
  2760.                 sidemenuOverlayElem.addEventListener("click", function () {
  2761.                     sidemenuOverlayElem.classList.toggle("expanded");
  2762.                 });
  2763.  
  2764.                 chatlogButtonsHTML = `
  2765.                 <div id="tes-chatlogButtons">
  2766.                         <div id="tes-chatlogSave" class="tes-chatlogBut">
  2767.                                 <span class="icon">
  2768.                                         <svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  2769.                                                 <path d="m0,50l50,-50l50,50l-25,0l0,50l-50,0l0,-50l-25,0z"></path>
  2770.                                         </svg>
  2771.                                 </span><!-- ⇩ -->
  2772.                                 <span class="label">download</span>
  2773.                         </div>
  2774.                         <div id="tes-chatlogView" class="tes-chatlogBut">
  2775.                                 <span class="icon">☰</span>
  2776.                                 <span class="label">view</span>
  2777.                         </div>
  2778.                         <div id="tes-chatlogDisplay">
  2779.                                 <textarea spellcheck="false"></textarea>
  2780.                                 <div id="close">✕</div>
  2781.                         </div>
  2782.                 </div>`;
  2783.  
  2784.                 selectAllButton = chatlogElem.querySelector("#chat-wrapper").insertAdjacentHTML("afterbegin", chatlogButtonsHTML);
  2785.                 chatlogElem.querySelector("#tes-chatlogSave").addEventListener("click", function () {
  2786.                     copyChatlog("download")
  2787.                 });
  2788.                 chatlogElem.querySelector("#tes-chatlogView").addEventListener("click", function () {
  2789.                     copyChatlog("view")
  2790.                 });
  2791.                 chatlogElem.querySelector("#tes-chatlogDisplay #close").addEventListener("click", function () {
  2792.                     copyChatlog("close")
  2793.                 });
  2794.  
  2795.                 if (!isPaidAccount) {
  2796.                     sidemenuGrabberParElem = sidemenuElem.querySelector("#sidemenu");
  2797.                     sidemenuGrabberElem = document.createElement("div");
  2798.                     sidemenuGrabberElem.setAttribute("id", "tes-sidemenu-grabber");
  2799.                     sidemenuGrabberElem.innerHTML = "◀";
  2800.                     sidemenuGrabberElem.addEventListener("click", sidemenuGrabber);
  2801.                     sidemenuGrabberParElem.appendChild(sidemenuGrabberElem);
  2802.                     sidemenuGrabberElem = sidemenuElem.querySelector("#tes-sidemenu-grabber");
  2803.                 }
  2804.             } catch (e) {
  2805.                 tcl("error injectElements: " + e.message);
  2806.             }
  2807.         }
  2808.  
  2809.         function sidemenuGrabber() {
  2810.             try {
  2811.                 sidemenuGrabberParElem.classList.toggle("tes-sidemenuCollapsed");
  2812.                 sidemenuGrabberParElem.classList.contains("tes-sidemenuCollapsed") ? sidemenuGrabberElem.innerHTML = "▶" : sidemenuGrabberElem.innerHTML = "◀";
  2813.  
  2814.                 userlistElem.querySelector("#userlist").classList.toggle("tes-sidemenuCollapsed");
  2815.                 videolistElem.querySelector("#videolist").classList.toggle("tes-sidemenuCollapsed");
  2816.                 webappElem.querySelector("#room").classList.toggle("tes-sidemenuCollapsed");
  2817.                 bodyElem.classList.toggle("tes-sidemenuCollapsed");
  2818.             } catch (e) {
  2819.                 tcl("error sidemenuGrabber: " + e.message);
  2820.             }
  2821.         }
  2822.  
  2823.         function headerGrabber() {
  2824.             try {
  2825.                 head