Raw Source
XDHx86 / My Video (Web Video Player)

// ==UserScript==
// @name         My Video (Web Video Player)
// @namespace    https://openuserjs.org/users/XDHx86/scripts
// @version      1.6.5
// @description  Custom video player with custom UI and shortcuts, EVERYTHING is customizable. Works on facebook, youtube and almost all websites.
// @icon         https://visualpharm.com/assets/563/Clapperboard-595b40b75ba036ed117d5939.svg
// @author       XDHx86
// @copyright    2020, XDHx86 (https://openuserjs.org/users/XDHx86)
// @license      MIT
// @downloadURL  https://openuserjs.org/install/XDHx86/My_Video_(Web_Video_Player).js
// @updateURL    https://openuserjs.org/meta/XDHx86/My_Video_(Web_Video_Player).meta.js
// @exclude      https://www.youtube.com/live_chat*
// @match        http*://*/*
// @match        file://*/*.avi
// @match        file://*/*.mkv
// @match        file://*/*.m4v
// @match        file://*/*.flv
// @match        file://*/*.divx
// @match        file://*/*.mpeg
// @match        file://*/*.webm
// @match        file://*/*.mp4
// @match        file://*/*.wmv
// @match        file://*/*.mov
// @match        file://*/*.ogv
// @match        file://*/*.ogm
// @match        file://*/*.ogx
// @connect      www.y2mate.com
// @connect      fbdown.net
// @grant        GM_setValue
// @grant        GM_listValues
// @grant        GM_getValue
// @grant        GM_download
// @grant        GM_addStyle
// @grant        GM_notification
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    {
        let version = GM_getValue('scriptversion', '');
        if (!version || version != GM_info.script.version) {
            GM_setValue('scriptversion', GM_info.script.version);
            window.open('https://openuserjs.org/scripts/XDHx86/My_Video_(Web_Video_Player)#changelog', '_blank');
        }
    }
    Object.defineProperty(Object.prototype, 'MV_search', {
        value: function(value, options) {
            let output = { found: false },
                altv,
                checkit = (inp, opt) => {
                    let output = false;
                    if (opt) {
                        if (opt instanceof RegExp && opt.test(inp)) output = true;
                        else if (typeof opt == 'string' && inp && inp.includes && inp.includes(value)) output = true;
                    }
                    else if (inp == value) output = true;
                    return output;
                };
            if (Array.isArray(this)) {
                for (let i = 0; i < this.length; i++) {
                    if (typeof this[i] == 'object') {
                        let obj = this[i];
                        for (let w in obj) {
                            if (checkit(obj[w], options)) {
                                output = { found: true, obj: obj, child: w, index: i, value: obj[w] };
                                break;
                            }
                        }
                        if (output.found) break;
                    } else if (Array.isArray(this[i])) {
                        let arr = this[i];
                        for (let j = 0; j < arr.length; j++) {
                            if (checkit(arr[j], options)) {
                                output = { found: true, array: arr, index: j, parentindex: i, value: arr[j] };
                                break;
                            }
                        }
                        if (output.found) break;
                    }
                    else if (checkit(this[i], options)) {
                        output = { found: true, array: this, index: i, value: this[i] };
                        break;
                    }
                }
            }
            else {
                for (let e in this) {
                    if (typeof this[e] == 'object') {
                        let obj = this[e];
                        for (let w in obj) {
                            if (checkit(obj[w], options)) {
                                output = { found: true, obj: obj, sub: w, child: e, value: obj[w]};
                                break;
                            }
                        }
                        if (output.found) break;
                    }
                    else if (Array.isArray(this[e])) {
                        let arr = this[e];
                        for (let i = 0; i < arr.length; i++) {
                            if (checkit(arr[i])) {
                                output = { found: true, array: arr, index: i, child: e, value: arr[i] };
                                break;
                            }
                        }
                        if (output.found) break;
                    }
                    else if (checkit(this[e], options)) {
                        output = { found: true, obj: this, child: e, value: this[e] };
                        break;
                    }
                }
            }
            return output;
        },
        enumerable: false
    });
    Object.defineProperty(Object.prototype, 'MV_deepSearch', {
        value: function(value) {
            let output = { found: false },
                search;
            if (Array.isArray(this)) {
                for (let i = 0; i < this.length; i++) {
                    if (this[i] == value) {
                        output = { found: true, array: this, index: i };
                        break;
                    } else if (typeof this[i] == 'object' || Array.isArray(this[i])) {
                        if (this[i]) search = this[i].MV_deepSearch(value);
                        if (search && search.found) {
                            output = search;
                            output.parentindex = i;
                            output.child = i;
                            break;
                        }
                    }
                }
            } else if (typeof this == 'object') {
                for (let e in this) {
                    if (this[e] == value) {
                        output = { found: true, obj: this, sub: e };
                        break;
                    } else if (typeof this[e] == 'object' || Array.isArray(this[e])) {
                        if (this[e]) search = this[e].MV_deepSearch(value);
                        if (search && search.found) {
                            output = search;
                            output.child = e;
                            output.index = e;
                            break;
                        }
                    }
                }
            }
            return output;
        },
        enumerable: false
    });
    Object.defineProperty(Object.prototype, 'MV_hasClass', {
        value: function(classes) {
            let output = false;
            if (!this.classList) return output;
            if (!Array.isArray(classes)) classes = [classes];
            for (let i = 0; i < classes.length; i++) if (this.classList.contains(classes[i])) output = true;
            return output;
        },
        enumerable: false
    });
    String.prototype.MV_includes = function(arr) {
        let output = false;
        for (let i = 0; i < arr.length; i++) if (this.includes(arr[i])) output = true;
        return output;
    }
    String.prototype.MV_getName = function() {
        let output,
            res = this.split('/').MV_search('', /\.(avi|mkv|flv|divx|mpe?g|webm|mp4|wmv|mov|ogv|ogm|ogx)/);
        if (res.found) {
            let newr = res.value.split(/\.(avi|mkv|flv|divx|mpe?g|webm|mp4|wmv|mov|ogv|ogm|ogx)/);
            newr.pop();
            output = newr.join('.');
        }
        return output;
    }
    Number.prototype.MV_format = String.prototype.MV_format = function() {
        let time = parseFloat(this),
            sec = '00',
            hour = '00',
            min = '00';
        if (time >= 0 && time < 60) {
            sec = Math.floor(time);
        } else if (time >= 60 && time < 3600) {
            min = (time / 60);
            sec = ((min % 1) * 60);
        } else if (time >= 3600) {
            hour = (time / 3600);
            min = ((hour % 1) * 60);
            sec = ((min % 1) * 60);
        }
        if (hour < 10) hour = '0' + Math.floor(hour);
        else hour = Math.floor(hour);
        if (min < 10) min = '0' + Math.floor(min);
        else min = Math.floor(min);
        if (sec < 10) sec = '0' + Math.floor(sec);
        else sec = Math.floor(sec);
        return hour + ':' + min + ':' + sec;
    }
    if (GM_getValue('firsttime', true)) {
        GM_setValue('play', 'KeyK');
        GM_setValue('stop', 'KeyS');
        GM_setValue('volplus', 'ArrowUp');
        GM_setValue('volminus', 'ArrowDown');
        GM_setValue('volstep', 0.05);
        GM_setValue('mute', 'KeyM');
        GM_setValue('smallback', 'Comma');
        GM_setValue('smallforward', 'Period');
        GM_setValue('smallstep', 3);
        GM_setValue('bigback', 'KeyJ');
        GM_setValue('bigforward', 'KeyL');
        GM_setValue('bigstep', 30);
        GM_setValue('incplayback', 'KeyT');
        GM_setValue('decplayback', 'KeyY');
        GM_setValue('playbackstep', 0.1);
        GM_setValue('resplayback', 'KeyR');
        GM_setValue('fullscreen', 'KeyF');
        GM_setValue('download', 'KeyD');
        GM_setValue('pipm', 'KeyP');
        GM_setValue('loop', 'KeyO');
        GM_setValue('customui', 'KeyZ');
        GM_setValue('smallctrl', 10);
        GM_setValue('smallshift', 20);
        GM_setValue('bigctrl', 90);
        GM_setValue('bigshift', 120);
        GM_setValue('exclusions', ['placeholder', 'www.soundcloud.com', 'www.spotify.com', 'open.spotify.com', 'discord.com']);
        GM_setValue('disabledbtns', ['placeholder']);
        GM_setValue('savedtime', ['placeholder']);
        GM_setValue('hage', 7);
        GM_setValue('autoresume', false);
        GM_setValue('autocustomui', false);
        GM_setValue('nocustomui', ['placeholder', 'www.youtube.com', 'www.facebook.com']);
        GM_setValue('noautoresume', ['placeholder', 'www.youtube.com', 'www.facebook.com']);
        GM_setValue('cuicss', ['linear-gradient(140deg, rgba(0, 0, 0, 1) 0%, rgba(85, 85, 85, 1) 89%, rgba(153, 153, 153, 1) 100%)', '#fff3', 'inherit', '#111', '#ccc', '#333', '#111', '#111', '#ccc', '#333', '#000', 'transparent', '#111', '#000', '#ccc', '#ccc', '#ccc', '#ccc', '#fff', '#0007']);
        GM_setValue('ccss', '');
        GM_setValue('firsttime', false);
    }
    let play = GM_getValue('play', 'KeyK'),
        stop = GM_getValue('stop', 'KeyS'),
        volplus = GM_getValue('volplus', 'ArrowUp'),
        volminus = GM_getValue('volminus', 'ArrowDown'),
        volstep = parseFloat(GM_getValue('volstep', 0.05)),
        mute = GM_getValue('mute', 'KeyM'),
        smallback = GM_getValue('smallback', 'Comma'),
        smallforward = GM_getValue('smallforward', 'Period'),
        smallstep = parseFloat(GM_getValue('smallstep', 3)),
        bigback = GM_getValue('bigback', 'KeyJ'),
        bigforward = GM_getValue('bigforward', 'KeyL'),
        bigstep = parseFloat(GM_getValue('bigstep', 30)),
        incplayback = GM_getValue('incplayback', 'KeyT'),
        decplayback = GM_getValue('decplayback', 'KeyY'),
        playbackstep = parseFloat(GM_getValue('playbackstep', 0.1)),
        resplayback = GM_getValue('resplayback', 'KeyR'),
        fullscreen = GM_getValue('fullscreen', 'KeyF'),
        download = GM_getValue('download', 'KeyD'),
        pipm = GM_getValue('pipm', 'KeyP'),
        loop = GM_getValue('loop', 'KeyO'),
        customui = GM_getValue('customui', 'Keyz'),
        smallctrl = parseFloat(GM_getValue('smallctrl', 10)),
        smallshift = parseFloat(GM_getValue('smallshift', 20)),
        bigctrl = parseFloat(GM_getValue('bigctrl', 90)),
        bigshift = parseFloat(GM_getValue('bigshift', 120)),
        exclusions = GM_getValue('exclusions', ['placeholder', 'www.soundcloud.com', 'www.spotify.com', 'open.spotify.com', 'discord.com']),
        disabledbtns = GM_getValue('disabledbtns', ['placeholder']),
        savedtime = GM_getValue('savedtime', ['placeholder']),
        hage = parseFloat(GM_getValue('hage', 7)),
        autoresume = GM_getValue('autoresume', false),
        autocustomui = GM_getValue('autocustomui', false),
        nocustomui = GM_getValue('nocustomui', ['placeholder', 'www.youtube.com', 'www.facebook.com']),
        noautoresume = GM_getValue('noautoresume', ['placeholder', 'www.youtube.com', 'www.facebook.com']),
        cuicss = GM_getValue('cuicss', ['linear-gradient(140deg, rgba(0, 0, 0, 1) 0%, rgba(85, 85, 85, 1) 89%, rgba(153, 153, 153, 1) 100%)', '#fff3', 'inherit', '#111', '#ccc', '#333', '#111', '#111', '#ccc', '#333', '#000', 'transparent', '#111', '#000', '#ccc', '#ccc', '#ccc', '#ccc', '#fff', '#0007']),
        ccss = GM_getValue('ccss', ''),
        KEY = {
            code: play,
            altKey: false,
            ctrlKey: false,
            shiftKey: false,
            metaKey: false,
            target: { tagName: 'DIV' }
        },
        sch, och, bch, fch, sach, sbch, CSS, CCSS, CUICSS, CUIBC;
    if (!Array.isArray(savedtime)) {
        savedtime = JSON.parse(savedtime);
        GM_setValue('savedtime', savedtime);
    }
    if (!Array.isArray(exclusions)) {
        exclusions = JSON.parse(exclusions);
        GM_setValue('exclusions', exclusions);
    }
    if (!Array.isArray(disabledbtns)) {
        disabledbtns = JSON.parse(disabledbtns);
        GM_setValue('disabledbtns', disabledbtns);
    }
    if (!Array.isArray(nocustomui)) {
        nocustomui = JSON.parse(nocustomui);
        GM_setValue('nocustomui', nocustomui);
    }
    if (!Array.isArray(noautoresume)) {
        noautoresume = JSON.parse(noautoresume);
        GM_setValue('noautoresume', noautoresume);
    }
    const s = document.createElement('div'),
          m = document.createElement('div'),
          a = document.createElement('div'),
          f = document.createElement('div'),
          x = document.createElement('div'),
          c = document.createElement('div'),
          o = document.createElement('div'),
          u = document.createElement('div'),
          p = document.createElement('div'),
          k = document.createElement('div'),
          svga = '<svg xmlns="http://www.w3.org/2000/svg" style="display: inline-block; width: 20px; fill: #090; margin-right: 5px !important; transform: rotate(-90deg);" viewBox="0 0 26 26"> <path d="M13,15.405l8.764-8.584c0.392-0.383,1.019-0.38,1.406,0.008l1.536,1.536c0.391,0.391,0.39,1.026-0.002,1.417L13.707,20.707 C13.512,20.902,13.256,21,13,21c-0.256,0-0.512-0.098-0.707-0.293L1.296,9.782c-0.393-0.39-0.394-1.025-0.002-1.417L2.83,6.829 c0.387-0.387,1.015-0.391,1.406-0.008L13,15.405z"/> </svg>',
          svgplay = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 7 5 L 7 19 L 19 12 L 7 5 z"/> </svg>',
          svgpause = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 5 5 L 5 19 L 10 19 L 10 5 L 5 5 z M 14 5 L 14 19 L 19 19 L 19 5 L 14 5 z"/> </svg>',
          svgstop = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 5 5 L 5 19 L 19 19 L 19 5 L 5 5 z"/> </svg>',
          svgdownload = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 10 0 L 10 10 L 6.5 10 L 12 17.5 L 17.5 10 L 14 10 L 14 0 L 10 0 z M 0 22 L 0 24 L 24 24 L 24 22 L 0 22 z"/> </svg>',
          svgtheater = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"> <path d="M3,39V9h42v30H3z M7,35h34V13H7V35z"/> </svg>',
          svgfullscreen = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"> <path d="M 6 6 L 6 18 A 2.0002 2.0002 0 1 0 10 18 L 10 10 L 18 10 A 2.0002 2.0002 0 1 0 18 6 L 6 6 z M 32 6 A 2.0002 2.0002 0 0 0 31.859375 9.9980469 A 2.0002 2.0002 0 0 0 32 10 L 40 10 L 40 18 A 2.0002 2.0002 0 0 0 41.830078 20.021484 A 2.0002 2.0002 0 0 0 42.029297 20.027344 A 2.0002 2.0002 0 0 0 44 18 L 44 6 L 32 6 z M 7.9707031 30.972656 A 2.0002 2.0002 0 0 0 6 33 L 6 45 L 18 45 A 2.0002 2.0002 0 0 0 18.199219 44.992188 A 2.0002 2.0002 0 0 0 18 41 L 10 41 L 10 33 A 2.0002 2.0002 0 0 0 7.9707031 30.972656 z M 41.970703 30.972656 A 2.0002 2.0002 0 0 0 40 33 L 40 41 L 32 41 A 2.0002 2.0002 0 1 0 32 45 L 44 45 L 44 33 A 2.0002 2.0002 0 0 0 41.970703 30.972656 z"/> </svg>',
          svgnormalscreen = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"> <path d="M 16.970703 4.9726562 A 2.0002 2.0002 0 0 0 15 7 L 15 15 L 7 15 A 2.0002 2.0002 0 1 0 7 19 L 19 19 L 19 7 A 2.0002 2.0002 0 0 0 16.970703 4.9726562 z M 32.970703 4.9726562 A 2.0002 2.0002 0 0 0 31.003906 6.8613281 A 2.0002 2.0002 0 0 0 31 7 L 31 19 L 43 19 A 2.0002 2.0002 0 0 0 43.199219 18.992188 A 2.0002 2.0002 0 0 0 43 15 L 35 15 L 35 7 A 2.0002 2.0002 0 0 0 32.970703 4.9726562 z M 7 31 A 2.0002 2.0002 0 1 0 7 35 L 15 35 L 15 43 A 2.0002 2.0002 0 1 0 19 43 L 19 31 L 7 31 z M 31 31 L 31 43 A 2.0002 2.0002 0 1 0 35 43 L 35 35 L 43 35 A 2.0002 2.0002 0 1 0 43 31 L 31 31 z"/> </svg>',
          svgvolmute = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 3 L 6 9 L 2 9 L 2 15 L 6 15 L 12 21 L 12 3 z M 14.71875 7.28125 L 13.28125 8.71875 L 16.09375 11.5 L 13.28125 14.28125 L 14.71875 15.71875 L 17.5 12.90625 L 20.28125 15.71875 L 21.71875 14.28125 L 18.90625 11.5 L 21.71875 8.71875 L 20.28125 7.28125 L 17.5 10.09375 L 14.71875 7.28125 z"/> </svg>',
          svgvollow = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 3 L 6 9 L 2 9 L 2 15 L 6 15 L 12 21 L 12 3 z M 14 8.09375 L 14 15.8125 C 15.7 15.4125 17 13.9 17 12 C 17 10.1 15.7 8.59375 14 8.09375 z"/> </svg>',
          svgvolmid = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 3 L 6 9 L 2 9 L 2 15 L 6 15 L 12 21 L 12 3 z M 14 5 L 14 7 C 16.279 7.465 18 9.586 18 12 C 18 14.414 16.279 16.535 14 17 L 14 19 C 17.386 18.512 20 15.519 20 12 C 20 8.481 17.386 5.488 14 5 z M 14 9 L 14 15 C 15.125 14.689 16 13.475 16 12 C 16 10.525 15.125 9.388 14 9 z"/> </svg>',
          svgvolhigh = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 3 L 6 9 L 2 9 L 2 15 L 6 15 L 12 21 L 12 3 z M 14 3.09375 L 14 5.09375 C 17.4 5.59375 20 8.5 20 12 C 20 15.5 17.4 18.40625 14 18.90625 L 14 20.90625 C 18.5 20.40625 22 16.6 22 12 C 22 7.4 18.5 3.59375 14 3.09375 z M 14 8.09375 L 14 15.8125 C 15.7 15.4125 17 13.9 17 12 C 17 10.1 15.7 8.59375 14 8.09375 z"/> </svg>',
          svgsubtitle = '<svg viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M213.333 0C95.513 0 0 95.513 0 213.333V1706.67C0 1824.49 95.513 1920 213.333 1920H1706.67c117.82 0 213.33-95.51 213.33-213.33V213.333C1920 95.513 1824.49 0 1706.67 0H213.333ZM320 1200c0-44.18 35.817-80 80-80h693.33c44.19 0 80 35.82 80 80s-35.81 80-80 80H400c-44.183 0-80-35.82-80-80Zm1066.67 0c0-44.18 35.81-80 80-80H1520c44.18 0 80 35.82 80 80s-35.82 80-80 80h-53.33c-44.19 0-80-35.82-80-80Zm-640.003 320c0-44.18 35.817-80 80-80H1520c44.18 0 80 35.82 80 80s-35.82 80-80 80H826.667c-44.183 0-80-35.82-80-80ZM320 1520c0-44.18 35.817-80 80-80h53.333c44.183 0 80 35.82 80 80s-35.817 80-80 80H400c-44.183 0-80-35.82-80-80Z"/> </svg>';
    function ui() {
        CSS = GM_addStyle(`.MV_settings, .MV_menu, .MV_alert, .MV_filter, .MV_converter, .MV_styler, .MV_customui, .MV_ovarlay, .MV_exclusions, .MV_subtitles { width: fit-content; width: -moz-fit-content; height: fit-content; height: -moz-fit-content; font-family: Arial; font-size: 14px; z-index: 2147483644; position: fixed; transition: all 0.5s ease; user-select: none; line-height: initial; margin: 0; padding: 0; background-color: #000; color: #090; } .MV_menu *, .MV_filter *, .MV_styler *, .MV_exclusions *, .MV_converter *, .MV_subtitles * { transition: all 0.5s; }  .MV_alert {  z-index: 2147483647; bottom: 3%; width: 500px; height: fit-content; height: -moz-fit-content; border-radius: 20px; border: 1px #090 solid; display: none; opacity: 0; cursor: default; text-align: center; padding: 25px; font-weight: 700; font-size: 25px; } .MV_settings { bottom: 0; left: 0; padding: 5px; border-top-right-radius: 5px; cursor: pointer; opacity: 0.7; font-family: cursive; font-weight: 700; border-left: 7px #090 solid; } .MV_settings:hover { opacity: 1; } .MV_menu::-webkit-resizer, .MV_menu::-webkit-scrollbar-corner, .MV_menu::-webkit-scrollbar-button { width: 0; height: 0; display: none; } .MV_menu::-webkit-scrollbar-thumb { background-color: #090; } .MV_menu::-webkit-scrollbar-track, .MV_menu::-webkit-scrollbar { background-color: #000; width: 10px; } .MV_menu { top: 2%; left: 0; padding: 20px; width: 400px; margin-left: -600px; border-radius: 0px 15px 15px 0px; scrollbar-color: #090 #000; scrollbar-width: thin; } .MV_menu h2, .MV_styler h2, .MV_styler h3, .MV_filter h2, .MV_exclusions h2, .MV_converter h2, .MV_subtitles h2 { font-size: 22px; margin: 0; transition: inherit; color: #090; cursor: pointer; font-weight: bolder; font-family: Helvetica Neue, Segoe UI, Helvetica, Arial, sans-serif; } .MV_help { cursor: help; border-bottom: 2px #aaa dotted; } .MV_filter h2, .MV_exclusions h2, .MV_converter h2 { cursor: default; } .MV_styler h3 { font-size: 18px; cursor: default; margin: 3px; } .MV_menu input[type=number], .MV_menu input[type=text], .MV_filter input[type=text], .MV_styler input, .MV_subtitles input { width: auto; min-width: 100px; margin: 2px; background-color: #111; color: #777;border: none; padding: 2px; text-transform: capitalize; margin-left: 15px; text-align: center; font-weight: bolder; outline: none; transition: inherit; } .MV_menu input[type=number]:focus, .MV_menu input[type=text]:focus, .MV_styler input:focus, .MV_filter input:focus .MV_subtitles input:focus { box-shadow: 0 0 5px 2px #090; padding: 3px; margin: 5px 1px 5px 10px; outline: none; border: 1px solid #090; } .MV_menu input:invalid, .MV_filter input:invalid, .MV_styler input:invalid, .MV_subtitles input:invalid { box-shadow: 0 0 5px 2px #900; outline: 0; border: 1px solid #900; } .MV_filter select, .MV_exclusions select, .MV_converter select { border: 1px solid #090; margin: 2px; background-color: #000; color: #090; outline: none; cursor: pointer; font-size: 20px; padding: 3px 10px; } .MV_s, .MV_o, .MV_b, .MV_f, .MV_sb, .MV_sa { overflow: hidden; height: 0px; transition: inherit; } .MV_b input[type=file] { cursor: pointer; background-color: #000; color: #090; padding: 3px; border: 1px solid #090; } .MV_btn { transition: inherit; border: none; color: #000; background-color: #090; outline: 0; font-family: sans-serif; cursor: pointer; padding: 5px 20px; font-weight: bolder; margin-left: 10px; margin-top: 10px; } .MV_btn:hover { color: #090; background-color: #000; } [class^="MV_"] *:disabled { opacity: 0.6 !important; cursor: not-allowed !important; color: #000 !important; background-color: #090 !important; } .MV_overlay { z-index: 2147483640 !important; top: 0; right: 0; position: fixed; background-color: #000; opacity: 0.7; display: none; height: 100%; width: 100%; } .MV_styler, .MV_filter, .MV_exclusions, .MV_converter, .MV_subtitles { box-shadow: 0 0 20px 20px #090; top: 20px; display: none; padding: 20px; margin: 20px auto; border-radius: 20px; } .MV_customui { display: none; top: 0; left: 0; width: 100%; height: 100%; z-index: 2147483635 !important; } .MV_hidden { display: none !important; } .MV_subb { display: block; bottom: 40px; position: absolute; padding: 10px; font-size: 1.5em; color: #fff; background: #000; overflow-wrap: normal; transition: none 0s ease 0s !important; } #MV_sub { display: none !important; } `);
        CUICSS = GM_addStyle(`.MV_ctheater .MV_wrapper { display: grid; align-content: center; } .MV_container { text-align: initial; margin: auto; display: block; height: -moz-fit-content; width: -moz-fit-content; height: fit-content; width: fit-content; } .MV_container video:not(.MV_vfullscreen, .MV_framed, .MV_maxheight) { height: auto !important; } .MV_container video { width: 100% !important; position: static !important; } .MV_vfullscreen, .MV_container .MV_framed, .MV_maxheight { height: 100% !important } .MV_theater { width: 80%; height: 80%; transition: none !important; } .MV_theater video { height: 100% !important; width: 100% !important; background-color: #000 !important; } .MV_controls { display: none; position: relative; z-index: 2; margin-top: -40px; height: 40px; width: 100%; opacity: 0; transition: all 0.5s !important; } .MV_controls:hover { display: block !important; opacity: 1 !important; cursor: default !important; } .MV_cbtn { font-size: 14px; font-family: "Segeo UI", "Helvetica Neue", "Helvetica"; margin-left: 5px; border: none; background-size: contain; background-repeat: no-repeat; display: inline-block; width: 25px; height: 25px; padding: 0; cursor: pointer; text-align: center; vertical-align: middle; } .MV_lbtns { float: left; height: 30px; } .MV_cbtn:first-child { margin-left: 0; } .MV_cbtn:hover { opacity: 0.5; } .MV_cbtn svg { height: 20px; } .MV_rbtns { float: right; height: 30px; } .MV_bar { height: 10px; position: absolute; width: 100%; overflow: hidden; } .MV_bar, .MV_bar * { transition: none !important; min-width: 0%; max-width: 100%; } .MV_highlight { transition: none !important; position: absolute; z-index: 4; display: none; bottom: 50px; color: #ccc; background-color: #000; margin-left: -30px; padding: 3px; border-radius: 5px; opacity: 1; text-align: center; } .MV_thumbnail, .MV_thumbnail * { max-width: 120px; max-height: 120px; display: block; } .MV_played, .MV_loaded { height: 30px; display: inline-block; } .MV_played { z-index: 2; margin-right: -5px; width: 0; position: relative; } .MV_loaded { z-index: 1; position: absolute; width: 0%; } .MV_thumb { z-index: 3; position: absolute; width: 10px; height: inherit; display: inline-block; cursor: pointer; } .MV_customui * { transition: inherit; user-select: none; } .MV_lbtns, .MV_rbtns { top: 10px; position: relative; } .MV_time { font-size: 16px; font-weight: 700; text-align: center; vertical-align: middle; user-select: text; } .MV_vol input { border-radius: 0; padding: 0; height: auto; float: right; width: 50px; -moz-appearance: none; appearance: none; border: none; outline: none; cursor: pointer; } .MV_vol input::-webkit-slider-thumb, .MV_vol input::-moz-range-thumb {-moz-appearance: none; appearance: none; width: 7%; max-width: 100%; min-width: 0%; height: 100%; opacity: 0.7; } .MV_vol:before { margin: 10px; margin-left: -10px; content: attr(data-content); bottom: -7px; position: absolute; text-align: center; opacity: 1; } .MV_vol { overflow: hidden; text-align: center; vertical-align: middle; width: 0; display: inline-block; white-space: nowrap; position: relative; } .MV_playbackm { display: inline-grid; height: 150px; align-self: flex-start; text-align: center; width: 0; overflow: hidden; white-space: nowrap; position: relative; bottom: 150px; z-index: 4; } .MV_playbackm span { padding: 3px; font-weight: 700; cursor: pointer; } .MV_buffer { position: absolute; height: 50px; width: 50px; animation: MV_rotate 2s linear infinite; border: 5px solid; border-radius: 50%; } .MV_theater .MV_resizer { display: block !important; } .MV_resizer { display: none; width: 10px; height: 10px; margin-left: 100%; background-color: #ccc; cursor: se-resize; } @keyframes MV_rotate { from {transform: rotate(0deg);} to {transform:rotate(360deg);} }`);
        CUIBC = GM_addStyle(`.MV_customui { background-image: ${cuicss[0]}; } .MV_controls { background: ${cuicss[1]}; } .MV_time { background: ${cuicss[2]}; color: ${cuicss[15]}; } .MV_vol input { background: ${cuicss[3]}; } .MV_vol input::-moz-range-thumb, .MV_vol input::-webkit-slider-thumb { background: ${cuicss[4]}; } .MV_playbackm span, .MV_playbackm { background: ${cuicss[5]}; color: ${cuicss[16]}; } .MV_playbackm span:hover { background: ${cuicss[6]}; color: ${cuicss[17]}; } .MV_bar { background: ${cuicss[7]}; } .MV_played { background: ${cuicss[8]}; } .MV_loaded { background: ${cuicss[9]}; } .MV_thumb { background: ${cuicss[10]}; } .MV_cbtn { background: ${cuicss[11]}; color: ${cuicss[14]}; } .MV_ctheater { background: ${cuicss[12]} } .MV_cbtn svg { fill: ${cuicss[13]}; } .MV_buffer { border-color: ${cuicss[13]} transparent; } .MV_vol:before { color: ${cuicss[14]}; .MV_subb { color: ${cuicss[18]}; background: ${cuicss[19]}; }`);
        CCSS = GM_addStyle(ccss);
        s.innerHTML = 'XDHx86 - MyVideo v1.6 | Settings';
        m.innerHTML = `<h2> ${svga} Shortcuts: </h2> <div class="MV_s"> Play: <input type="text"> <br> Stop: <input type="text"> <br> Volume Up: <input type="text"> <br> Volume Down: <input type="text"> <br> Volume Step: <input type="number" min="0.01" max="0.2" step="0.01"> <br> Mute: <input type="text"> <br> Short Backward: <input type="text"> <br> Short Forward: <input type="text"> <br> Short Step: <input type="number" min="3" max="30" step="1"> <br> Long Backward: <input type="text"> <br> Long Forward: <input type="text"> <br> Long Step: <input type="number" min="10" max="120" step="1"> <br> Decrease Playback Rate: <input type="text"> <br> Increase Playback Rate: <input type="text"> <br> Playback Rate Step: <input type="number" min="0.1" max="0.5" step="0.1"> <br> Reset Playback Rate: <input type="text"> <br> Fullscreen: <input type="text"> <br> Download: <input type="text"> <br> Play in Picture Mode: <input type="text"> <br> Loop: <input type="text"> <br> Custom Video Player: <input type="text"> <br> </div> <h2> ${svga} General: </h2> <div class="MV_o"> Auto resume from last stop: <br> Yes <input type="radio" name="ar"> No <input type="radio" name="ar"> <br> Auto use custom video player: <br> Yes <input type="radio" name="cu"> No <input type="radio" name="cu"> <br> Don't use custom video player on this site (${location.host}): <br> Yes <input type="radio" name="nc"> No <input type="radio" name="nc"> <br> Don't auto resume on this site (${location.host}): <br> Yes <input type="radio" name="dr"> No <input type="radio" name="dr"> <br> <span class="MV_help" title="Click to see notes"> Delete history older than (Days): </span> <input type="number" min="3" max="30" step="1"> <br> Ctrl short step: <input type="number" min="5" max="100" step="1"> <br> Shift short step: <input type="number" min="5" max="100" step="1"> <br> Ctrl long step: <input type="number" min="10" max="600" step="1"> <br> Shift long step: <input type="number" min="10" max="600" step="1"> <br> Customize styles: <button class="MV_btn"> Open Styler </button> <br> <span class="MV_help" title="Click to see notes"> Disable Keys: </span> <button class="MV_btn"> Config Keys </button> <br> Execlusions: <button class="MV_btn"> Config Exclusions </button> </div> <h2> ${svga} Backup & Restore: </h2> <div class="MV_b"> Backup: <button class="MV_btn"> Backup </button> <br> Restore: <input type="file"> <button class="MV_btn"> Restore </button> </div> <h2> ${svga} Feedback: </h2> <div class="MV_f"> <button class=MV_btn> Send an Email </button> </div> <br> <button class="MV_btn"> Save </button> <button class="MV_btn"> Reset </button>`;
        c.innerHTML = `<h2> ${svga} Basic Styling: </h2> <div class="MV_sb"> <h3> Background Colors: </h3> Custom UI: <input type="text"> <br> Controls Bar: <input type="text"> <br> Time: <input type="text"> <br> Volume Menu: <input type="text"> <br> Volume Slider: <input type="text"> <br> Playback Menu: <input type="text"> <br> Playback Menu Button (Hover): <input type="text"> <br> Progress Bar: <input type="text"> <br> Progress Bar (Played): <input type="text"> <br> Progress Bar (Loaded): <input type="text"> <br> Progress Bar (Thumb): <input type="text"> <br> Buttons: <input type="text"> <br> Theater Mode: <input type="text"> <br> <h3> Button & Text Colors: </h3> Buttons: <input type="text"> <br> Button Text: <input type="text"> <br> Time: <input type="text"> <br> Playback Menu Button (Text): <input type="text"> <br> Playback Menu Text (Hover): <input type="text"> <br> Subtitle Text Color: <input type="text"> <br> Subtitle Background Color: <input type="text"> </div> <h2> ${svga} Advanced Styling </h2> <div class="MV_sa"> Open Advanced Styler: <button class="MV_btn"> Open </button> </div> <br> <button class="MV_btn"> Save </button> <button class="MV_btn"> Reset </button>`;
        x.innerHTML = `<h2> Exclusions: </h2> Add <select> <option value="page"> Page </option> <option value="website"> Website </option> </select> <button class="MV_btn"> To Exclusions </button>  <h2> Execluded: </h2> <select size="6"> </select> <br> <button class="MV_btn" disabled> Remove </button>`;
        f.innerHTML = `<h2> Disable Keys: </h2> <h3> Disabled buttons only work on this website and not globally.<br><br>Disabled buttons will work inside custom UI. </h3> Key: <input type=text> <button class=MV_btn> Disable </button> <br> <h2> Disabled Buttons: </h2> <select size=6> </select> <br> <button class="MV_btn" disabled> Remove </button>`;
        u.innerHTML = `<div class="MV_wrapper"> <div class="MV_container"> <div class="MV_controls"> <div class="MV_highlight"> <span class="MV_thumbnail"> </span> <span class="MV_currenttime"> </span> </div> <div class="MV_bar"> <div class="MV_loaded"> </div> <div class="MV_played"> </div> <div class="MV_thumb"> </div> </div> <div class="MV_lbtns"> <button class="MV_cbtn">${svgpause}</button> <button class="MV_cbtn">${svgstop}</button> <span class="MV_time">00:00:00/00:00:00</span> </div> <div class="MV_rbtns"> <span class="MV_vol" data-content="20"> <input type="range" min="0" max="100" step="1"> </span> <button class="MV_cbtn">${svgvolhigh}</button> <button class="MV_cbtn">${svgsubtitle}</button> <button class="MV_cbtn">1.0x</button> <div class="MV_playbackm"> <span> 0.2 </span> <span> 0.5 </span> <span> 1.0 </span> <span> 1.2 </span> <span> 1.5 </span> <span> 2.0 </span> </div> <button class="MV_cbtn">${svgdownload}</button> <button class="MV_cbtn">${svgtheater}</button> <button class="MV_cbtn">${svgfullscreen}</button> </div> </div> <div class="MV_buffer"> </div> <div class="MV_resizer"> </div> <div class="MV_subb" style="display: none;"> <span class="MV_capt"> </span> <p id="MV_sub"></p> </div> </div> </div>`;
        p.innerHTML = `<h2> Video Converter: </h2> Choose video quality and format: <select> </select> <br> <button class=MV_btn> Download </button> ${location.href.includes('youtube.com') ? ` <br> <br> Download this video thubnail: <a href="https://i.ytimg.com/vi/${location.href.substr(location.href.indexOf('v=')+2).includes('&') ? location.href.substr(location.href.indexOf('v=')+2).substr(0, location.href.substr(location.href.indexOf('v=')+2).indexOf('&')) : location.href.substr(location.href.indexOf('v=')+2)}/maxresdefault.jpg" target="_blank"> Download </a> <br> <br> Credits goes to <a href="https://www.y2mate.com/" traget="_blank">https://www.y2mate.com/</a>` : ` <br> <br> Credits goes to <a href="https://fbdown.net/" traget="_blank">https://fbdown.net/</a>`}`;
        k.innerHTML = `<h2> Import Subtitle </h2> <br> Upload Subtitle: <input type="file" accept=".srt,.vtt"> <br> <button class="MV_btn"> Import </button>`
        s.className = 'MV_settings';
        m.className = 'MV_menu';
        a.className = 'MV_alert';
        x.className = 'MV_exclusions';
        f.className = 'MV_filter';
        c.className = 'MV_styler';
        u.className = 'MV_customui';
        o.className = 'MV_overlay';
        p.className = 'MV_converter';
        k.className = 'MV_subtitles';
        document.body.appendChild(s);
        document.body.appendChild(m);
        document.body.appendChild(x);
        document.body.appendChild(a);
        document.body.appendChild(f);
        document.body.appendChild(c);
        document.body.appendChild(u);
        document.body.appendChild(o);
        document.body.appendChild(p);
        document.body.appendChild(k);
        {
            let p = 20;
            m.querySelector('.MV_s').style.height = '-moz-fit-content';
            m.querySelector('.MV_s').style.height = 'fit-content';
            sch = m.querySelector('.MV_s').offsetHeight + p;
            m.querySelector('.MV_s').style.height = '0';
            m.querySelector('.MV_o').style.height = '-moz-fit-content';
            m.querySelector('.MV_o').style.height = 'fit-content';
            och = m.querySelector('.MV_o').offsetHeight + p;
            m.querySelector('.MV_o').style.height = '0';
            m.querySelector('.MV_b').style.height = '-moz-fit-content';
            m.querySelector('.MV_b').style.height = 'fit-content';
            bch = m.querySelector('.MV_b').offsetHeight + p;
            m.querySelector('.MV_b').style.height = '0';
            m.querySelector('.MV_f').style.height = '-moz-fit-content';
            m.querySelector('.MV_f').style.height = 'fit-content';
            fch = m.querySelector('.MV_f').offsetHeight + p;
            m.querySelector('.MV_f').style.height = '0';
            c.style.display = 'block';
            c.querySelector('.MV_sb').style.height = '-moz-fit-content';
            c.querySelector('.MV_sb').style.height = 'fit-content';
            sbch = c.querySelector('.MV_sb').offsetHeight + p;
            c.querySelector('.MV_sb').style.height = '0';
            c.querySelector('.MV_sa').style.height = '-moz-fit-content';
            c.querySelector('.MV_sa').style.height = 'fit-content';
            sach = c.querySelector('.MV_sa').offsetHeight + p;
            c.querySelector('.MV_sa').style.height = '0';
            c.style.display = 'none';
        }
        document.body.onclick = e => {
            let path = e.target;
            for (let i = 0; i < 10; i++) {
                if (path.MV_hasClass(['MV_menu', 'MV_alert', 'MV_styler', 'MV_overlay', 'MV_settings', 'MV_filter', 'MV_exclusions', 'MV_converter', 'MV_subtitles', 'MV_container'])) return;
                else if (path.parentElement && path.parentElement.classList) path = path.parentElement;
                if (i == 9) {
                    sh('sf');
                    sh('of');
                    sh('bf');
                    sh('ff');
                    sh('stf');
                    sh('flf');
                    sh('xcf');
                    sh('subf');
                    sh('menuf');
                }
            }
        }
        s.onclick = () => {
            if (m.style.marginLeft == '0' || m.style.marginLeft == '0px') {
                sh('menuf');
                sh('sf');
                sh('of');
                sh('bf');
                sh('ff');
                sh('stf');
                sh('flf');
                sh('xcf');
                sh('cvf');
                sh('subf');
            } else sh('menut');
        }
        s.oncontextmenu = e => {
            if (confirm('Right-clicking this menu adds this website (' + location.host + ') to exclusions, are you sure you want that?')) {
                e.preventDefault();
                if (!exclusions.includes(location.host)) {
                    exclusions.push(location.host);
                    GM_setValue('exclusions', exclusions);
                    rvals();
                }
                remove();
            } else if (confirm('Then exclude this page only? (' + location.href + ')')) {
                e.preventDefault();
                if (!exclusions.includes(location.href)) {
                    exclusions.push(location.href);
                    GM_setValue('exclusions', exclusions);
                    rvals();
                }
                remove();
            }
        }
        m.querySelectorAll('h2')[0].onclick = () => {
            if (m.querySelector('.MV_s').style.height == '0' || m.querySelector('.MV_s').style.height == '0px') {
                sh('st');
                sh('of');
                sh('bf');
                sh('ff');
            } else sh('sf');
        }
        m.querySelectorAll('h2')[1].onclick = () => {
            if (m.querySelector('.MV_o').style.height == '0' || m.querySelector('.MV_o').style.height == '0px') {
                sh('sf');
                sh('ot');
                sh('bf');
                sh('ff');
            } else sh('of');
        }
        m.querySelectorAll('h2')[2].onclick = () => {
            if (m.querySelector('.MV_b').style.height == '0' || m.querySelector('.MV_b').style.height == '0px') {
                sh('sf');
                sh('of');
                sh('bt');
                sh('ff');
            } else sh('bf');
        }
        m.querySelectorAll('h2')[3].onclick = () => {
            if (m.querySelector('.MV_f').style.height == '0' || m.querySelector('.MV_f').style.height == '0px') {
                sh('sf');
                sh('of');
                sh('bf');
                sh('ft');
            } else sh('ff');
        }
        m.querySelectorAll('.MV_btn')[0].onclick = () => {
            if (c.style.display == 'block') {
                sh('flf');
                sh('stf');
                sh('cvf');
                sh('xcf');
            } else {
                sh('flf');
                sh('xcf');
                sh('cvf');
                sh('stt');
            }
        }
        m.querySelectorAll('.MV_btn')[1].onclick = () => {
            if (f.style.display == 'block') {
                sh('flf');
                sh('xcf');
                sh('cvf');
                sh('stf');
            } else {
                sh('stf');
                sh('xcf');
                sh('cvf');
                sh('flt');
            }
        }
        m.querySelectorAll('.MV_btn')[2].onclick = () => {
            if (x.style.display == 'block') {
                sh('flf');
                sh('xcf');
                sh('cvf');
                sh('stf');
            } else {
                sh('stf');
                sh('flf');
                sh('cvf');
                sh('xct');
            }
        }
        o.onclick = () => {
            sh('stf');
            sh('flf');
            sh('xcf');
            sh('cvf');
            sh('subf');
        }
        c.querySelectorAll('h2')[0].onclick = () => {
            if (c.querySelector('.MV_sb').style.height == '0' || c.querySelector('.MV_sb').style.height == '0px') {
                sh('faf');
                sh('fbt');
            }
            else sh('fbf');
        }
        c.querySelectorAll('h2')[1].onclick = () => {
            if (c.querySelector('.MV_sa').style.height == '0' || c.querySelector('.MV_sa').style.height == '0px') {
                sh('fbf');
                sh('fat');
            }
            else sh('faf');
        }
        f.querySelector('input').onkeydown = e => e.preventDefault();
        f.querySelector('input').onkeyup = function(e) {
            if (/capslock|f[0-9]|home|end|pageup|delete|backspace|escape|tab|pagedown|insert|numlock|backquote/i.test(e.code)) alt('No special characters allowed!');
            else if (!e.code || e.key == 'Clear') return;
            else if (e.ctrlKey || e.altKey || e.metaKey || e.shiftKey) alt('No special characters allowed!');
            else if (e.code == 'Enter') this.nextElementSibling.click();
            else if (!/control|shift|alt|meta|osl|osr/i.test(e.code)) {
                this.value = e.code;
                this.setCustomValidity('');
            }
        }
        if (location.host.includes('facebook')) p.querySelector('button').innerText = 'Download';
    }
    function sh(w) {
        switch (w) {
            case 'menuf':
                m.style.marginLeft = '-600px';
                break;
            case 'menut':
                m.style.marginLeft = '0px';
                break;
            case 'sf':
                m.querySelector('.MV_s').style.height = '0px';
                m.querySelectorAll('svg')[0].style.transform = 'rotate(-90deg)';
                break;
            case 'st':
                m.querySelector('.MV_s').style.height = sch + 'px';
                m.querySelectorAll('svg')[0].style.transform = 'rotate(0deg)';
                break;
            case 'of':
                m.querySelector('.MV_o').style.height = '0px';
                m.querySelectorAll('svg')[1].style.transform = 'rotate(-90deg)';
                break;
            case 'ot':
                m.querySelector('.MV_o').style.height = och + 'px';
                m.querySelectorAll('svg')[1].style.transform = 'rotate(0deg)';
                break;
            case 'bf':
                m.querySelector('.MV_b').style.height = '0px';
                m.querySelectorAll('svg')[2].style.transform = 'rotate(-90deg)';
                break;
            case 'bt':
                m.querySelector('.MV_b').style.height = bch + 'px';
                m.querySelectorAll('svg')[2].style.transform = 'rotate(0deg)';
                break;
            case 'ff':
                m.querySelector('.MV_f').style.height = '0px';
                m.querySelectorAll('svg')[3].style.transform = 'rotate(-90deg)';
                break;
            case 'ft':
                m.querySelector('.MV_f').style.height = fch + 'px';
                m.querySelectorAll('svg')[3].style.transform = 'rotate(0deg)';
                break;
            case 'flf':
                f.style.display = 'none';
                o.style.display = 'none';
                break;
            case 'flt':
                f.style.display = 'block';
                o.style.display = 'block';
                f.style.left = (document.body.offsetWidth - f.offsetWidth) / 2 + 'px';
                break;
            case 'stf':
                c.style.display = 'none';
                o.style.display = 'none';
                break;
            case 'stt':
                c.style.display = 'block';
                o.style.display = 'block';
                c.style.left = (document.body.offsetWidth - c.offsetWidth) / 2 + 'px';
                break;
            case 'xcf':
                x.style.display = 'none';
                o.style.display = 'none';
                break;
            case 'xct':
                x.style.display = 'block';
                o.style.display = 'block';
                x.style.left = (document.body.offsetWidth - x.offsetWidth) / 2 + 'px';
                break;
            case 'cvf':
                p.style.display = 'none';
                o.style.display = 'none';
                break;
            case 'cvt':
                sh('flf');
                sh('stf');
                sh('xcf');
                p.style.display = 'block';
                o.style.display = 'block';
                p.style.left = (document.body.offsetWidth - p.offsetWidth) / 2 + 'px';
                break;
            case 'fbf':
                c.querySelector('.MV_sb').style.height = '0px';
                c.querySelectorAll('svg')[0].style.transform = 'rotate(-90deg)';
                break;
            case 'fbt':
                c.querySelector('.MV_sb').style.height = sbch + 'px';
                c.querySelectorAll('svg')[0].style.transform = 'rotate(0deg)';
                break;
            case 'faf':
                c.querySelector('.MV_sa').style.height = '0px';
                c.querySelectorAll('svg')[1].style.transform = 'rotate(-90deg)';
                break;
            case 'fat':
                c.querySelector('.MV_sa').style.height = sach + 'px';
                c.querySelectorAll('svg')[1].style.transform = 'rotate(0deg)';
                break;
            case 'subt':
                k.style.display = 'block';
                o.style.display = 'block';
                k.style.left = (document.body.offsetWidth - k.offsetWidth) / 2 + 'px';
                break;
            case 'subf':
                k.style.display = 'none';
                o.style.display = 'none';
                break;
        }
    }
    function set() {
        const inputst = m.querySelectorAll('input[type=text]'),
              inputsn = m.querySelectorAll('input[type=number]'),
              inputsr = m.querySelectorAll('input[type=radio]'),
              valst = [play, stop, volplus, volminus, mute, smallback, smallforward, bigback, bigforward, incplayback, decplayback, resplayback, fullscreen, download, pipm, loop, customui],
              valstn = ['play', 'stop', 'volplus', 'volminus', 'mute', 'smallback', 'smallforward', 'bigback', 'bigforward', 'incplayback', 'decplayback', 'resplayback', 'fullscreen', 'download', 'pipm', 'loop', 'customui'],
              valsn = [volstep, smallstep, bigstep, playbackstep, hage, smallctrl, smallshift, bigctrl, bigshift],
              valsnn = ['volstep', 'smallstep', 'bigstep', 'playbackstep', 'hage', 'smallctrl', 'smallshift', 'bigctrl', 'bigshift'],
              backup = m.querySelectorAll('.MV_btn')[3],
              restore = m.querySelectorAll('.MV_btn')[4],
              feedbck = m.querySelectorAll('.MV_btn')[5],
              save = m.querySelectorAll('.MV_btn')[6],
              reset = m.querySelectorAll('.MV_btn')[7],
              help = m.querySelectorAll('.MV_help'),
              inputsc = c.querySelectorAll('input'),
              advcss = c.querySelectorAll('.MV_btn')[0],
              csave = c.querySelectorAll('.MV_btn')[1],
              creset = c.querySelectorAll('.MV_btn')[2],
              fselect = f.querySelector('select'),
              fbtns = f.querySelectorAll('.MV_btn'),
              xselects = x.querySelectorAll('select'),
              xbtns = x.querySelectorAll('.MV_btn'),
              subbtn = k.querySelector('button'),
              convselect = p.querySelector('select'),
              convbtn = p.querySelector('button');
        let i = 0;
        for (let elm of inputst) {
            elm.value = valst[i];
            elm.setAttribute('mv-og', elm.value);
            elm.setAttribute('mv-name', valstn[i]);
            i++;
            elm.onkeydown = e => {
                if ((e.shiftKey && e.code != 'Tab') || /tab/i.test(e.code)) return;
                else e.preventDefault();
            }
            elm.onkeyup = function(e) {
                if (/capslock|f[0-9]|home|end|pageup|pagedown|insert|numlock|backquote/i.test(e.code)) alt('No special characters allowed!');
                else if (e.ctrlKey || e.altKey || e.metaKey || (e.shiftKey && e.code != 'Tab')) alt('No special characters allowed!');
                else if (!e.code || e.key == 'Clear') return;
                else if (e.code == 'Delete' || e.code == 'Backspace') this.value = this.getAttribute('mv-og');
                else if (e.code == 'Escape') this.blur();
                else if (e.code == 'Enter' && this.nextElementSibling.nextElementSibling) this.nextElementSibling.nextElementSibling.focus();
                else if (!/control|shift|alt|meta|osl|osr/i.test(e.code) && e.code != 'Tab') this.value = e.code;
            }
            elm.onblur = function() {
                if (!/digit|numpad|key|space|bracket|semi|comma|period|slash|(^quote)|minus|arrow|equal/i.test(this.value)) {
                    alt('No special characters allowed!');
                    this.value = this.getAttribute('mv-og');
                }
                let v = this.value.toLowerCase(),
                    a = inputst,
                    c = [];
                for (let e of a) c.push(e.value.toLowerCase());
                if (c.indexOf(v) != c.lastIndexOf(v)) {
                    alt('This value is already assigned!');
                    this.value = this.getAttribute('mv-og');
                }
            }
        }
        let j = 0;
        for (let elm of inputsn) {
            elm.value = valsn[j];
            elm.setAttribute('mv-og', elm.value);
            elm.setAttribute('mv-name', valsnn[j]);
            j++;
            elm.onkeydown = e => {
                if ((e.shiftKey && e.code != 'Tab') || /tab|backspace|period|arrow/i.test(e.code)) return;
                else e.preventDefault();
            }
            elm.onkeyup = function(e) {
                if (e.ctrlKey || e.altKey || e.metaKey || (e.shiftKey && e.code != 'Tab')) alt('No special characters allowed!');
                else if (!e.code || e.key == 'Clear') return;
                else if (e.code == 'Delete') this.value = this.getAttribute('mv-og');
                else if (e.code == 'Escape') this.blur();
                else if (e.code == 'Enter' && this.nextElementSibling.nextElementSibling) this.nextElementSibling.nextElementSibling.focus();
                else if (e.code == 'Period') this.value += '.0';
                else if (!/control|shift|alt|meta|osl|enter|osr/i.test(e.code) && e.code != 'Tab' && (e.key <= 9 && e.key >= 0)) this.value += e.key;
            }
            elm.onblur = function() {
                if (isNaN(parseFloat(this.value)) || this.value > parseFloat(this.max) || this.value < parseFloat(this.min) || !this.validity.valid) {
                    alt(`Invalid value! No more than ${this.max} nor less than ${this.min} and divisible by ${this.step}.`, 7000);
                    this.value = this.getAttribute('mv-og');
                }
            }
        }
        {
            if (autoresume) inputsr[0].checked = true;
            else inputsr[1].checked = true;
            if (autocustomui) inputsr[2].checked = true;
            else inputsr[3].checked = true;
            if (nocustomui.includes(location.host)) inputsr[4].checked = true;
            else inputsr[5].checked = true;
            if (noautoresume.includes(location.host)) inputsr[6].checked = true;
            else inputsr[7].checked = true;
            let result = disabledbtns.MV_search(location.host);
            if (result.found && result.obj.buttons.length > 0) for (let i = 0; i < result.obj.buttons.length; i++) fselect.options.add(new Option(result.obj.buttons[i], result.obj.buttons[i]));
            for (let i = 0; i < exclusions.length; i++) xselects[1].options.add(new Option(exclusions[i], exclusions[i]));
        }
        for (let elm of help) elm.onclick = () => window.open('https://openuserjs.org/scripts/XDHx86/My_Video_(Web_Video_Player)#notes');
        let kk = 0;
        for (let elm of inputsc) {
            elm.value = cuicss[kk];
            elm.style.textTransform = 'none';
            kk++;
        }
        backup.onclick = () => br(0);
        restore.onclick = () => br(1);
        feedbck.onclick = feedback;
        save.onclick = () => {
            for (let e of inputst) if (e.getAttribute('mv-name')) GM_setValue(e.getAttribute('mv-name'), e.value);
            for (let e of inputsn) if (e.getAttribute('mv-name')) GM_setValue(e.getAttribute('mv-name'), e.value);
            if (inputsr[0].checked) GM_setValue('autoresume', true);
            else GM_setValue('autoresume', false);
            if (inputsr[2].checked) GM_setValue('autocustomui', true);
            else GM_setValue('autocustomui', false);
            if (inputsr[4].checked) {
                if (!nocustomui.includes(location.host)) nocustomui.push(location.host);
                GM_setValue('nocustomui', nocustomui);
            } else {
                if (nocustomui.includes(location.host)) nocustomui.splice(nocustomui.indexOf(location.host), 1);
                GM_setValue('nocustomui', nocustomui);
            }
            if (inputsr[6].checked) {
                if (!noautoresume.includes(location.host)) noautoresume.push(location.host);
                GM_setValue('noautoresume', noautoresume);
            } else {
                if (noautoresume.includes(location.host)) noautoresume.splice(noautoresume.indexOf(location.host), 1);
                GM_setValue('noautoresume', noautoresume);
            }
            rvals();
            alt('Settings will take effect immediately.');
        }
        reset.onclick = () => {
            if (confirm('Are you sure you want to reset the script?\nThis cannot be undone and it will DELETE all the saved data')) {
                GM_setValue('firsttime', true);
                if (confirm('Changes will take effect after reload, reload now?')) location.reload();
            }
        }
        advcss.onclick = () => {
            const win = window.open('', 'MV_advCSS', 'menubar=no,status=no,titlebar=no,location=no,top=0,height=' + window.screen.availHeight - 200 + 'width=' + window.screen.availWidth / 2),
                  doc = win.document;
            doc.head.innerHTML = `<style> body { font-family: arial; background-color: #333; color: #090; } .container { padding: 20px; } .header { text-align: center; } .note { margin: 20px 30px; display: flex; align-content: center; } .text { display: block; margin: auto; width: 100%; height: 100%; } .MV_btn { transition: all 0.5s; border: none; color: #000; background-color: #090; outline: 0; font-family: sans-serif; cursor: pointer; padding: 5px 20px; font-weight: bolder; margin-left: 10px; margin-top: 10px; } .MV_btn:hover { color: #090; background-color: #000; } textarea::selection { color: #000; background-color: #070770; } textarea { width: 700px; display: inline-block; height: 600px; background-color: #000; border: 1px #090 solid; outline: 0; max-width: 700px; max-height: 700px; box-shadow: 0 0 5px 2px #090; margin: 0 10px; color: #090; font-size: 14px; font-weight: 600; font-family: arial; }</style>`;
            doc.body.innerHTML = `<div class=container> <h2 class=header> Advanced CSS Editor </h2> <span class=note> Notes: <br> - Please don't actually use this to write your code, just use an editor then paste here. </span> <div class=text> <textarea spellcheck=false>${ccss}</textarea> <button class=MV_btn> Copy main CSS </button> <button class=MV_btn> Copy custom UI CSS </button> <textarea style="opacity: 0; width: 0; height: 0;" readonly=readonly>${CSS.innerHTML}</textarea> <textarea style="opacity: 0; width: 0; height: 0;" readonly=readonly>${CUICSS.innerHTML}</textarea> </div> <button class=MV_btn> Save </button> <button class=MV_btn> Reset </button> </div>`;
            let et = doc.querySelectorAll('textarea')[0],
                css = doc.querySelectorAll('textarea')[1],
                cuicss = doc.querySelectorAll('textarea')[2],
                cssb = doc.querySelectorAll('.MV_btn')[0],
                cuicssb = doc.querySelectorAll('.MV_btn')[1],
                save = doc.querySelectorAll('.MV_btn')[2],
                reset = doc.querySelectorAll('.MV_btn')[3];
            cssb.onclick = () => {
                css.select();
                win.document.execCommand('copy');
                win.alert('Copied to clipboard');
            }
            cuicssb.onclick = () => {
                cuicss.select();
                win.document.execCommand('copy');
                win.alert('Copied to clipboard');
            }
            save.onclick = () => {
                GM_setValue('ccss', et.value);
                rvals();
                ucss();
                win.alert('Settings will take effect immediately.');
            }
            reset.onclick = () => {
                if (!win.confirm('Are you sure you want to reset it? This cannot be undone and will delete all CSS code written.')) return;
                et.innerHTML = '';
                et.value = '';
                GM_setValue('ccss', '');
                rvals();
                ucss();
                win.alert('Settings will take effect immediately.');
            }
        }
        csave.onclick = () => {
            let a = [],
                validate = c => {
                    let img = document.createElement('img');
                    img.style = 'background: rgb(0, 0, 0)';
                    img.style = 'background: ' + c;
                    if (img.style.background != 'rgb(0, 0, 0)' && img.style.background != '') return true;
                    img.style = 'background: rgb(255, 255, 255)';
                    img.style = 'background: ' + c;
                    return (img.style.background != 'rgb(255, 255, 255)' && img.style.background != '');
                };
            for (let e of inputsc) {
                if (!validate(e.value)) {
                    e.setCustomValidity('Invalid value!');
                    e.reportValidity();
                    e.onfocus = function() { this.setCustomValidity('Invalid value!'); this.reportValidity(); }
                    e.onchange = function() {
                        this.onchange = null;
                        this.onfocus = null;
                        this.setCustomValidity('');
                    }
                } else a.push(e.value);
            }
            if (a.length == 20) {
                GM_setValue('cuicss', a);
                rvals();
                alt('Settings will take effect immediately.');
                ucss();
            }
        }
        creset.onclick = () => {
            GM_setValue('cuicss', ['linear-gradient(140deg, rgba(0, 0, 0, 1) 0%, rgba(85, 85, 85, 1) 89%, rgba(153, 153, 153, 1) 100%)', '#fff3', 'inherit', '#111', '#ccc', '#333', '#111', '#111', '#ccc', '#333', '#000', 'transparent', '#111', '#000', '#ccc', '#ccc', '#ccc', '#ccc', '#fff', '#0007']);
            rvals();
            ucss();
            let k = 0;
            for (let elm of inputsc) {
                elm.value = cuicss[k];
                elm.style.textTransform = 'none';
                k++;
            }
            alt('Settings will take effect immediately.');
        }
        fselect.onchange = function() {
            if (this.selectedIndex > -1) fbtns[1].disabled = false;
            else fbtns[1].disabled = false;
        }
        fbtns[0].onclick = () => {
            let i = f.querySelector('input');
            if (!i.value || i.value == '') {
                alt('Forgot to add the button to disable?');
                i.setCustomValidity('Invalid Value!');
                i.reportValidity();
            } else {
                let result = disabledbtns.MV_search(location.host);
                if (result.found) {
                    if (!result.obj.buttons.includes(i.value)) {
                        fselect.options.add(new Option(i.value, i.value));
                        result.obj.buttons.push(i.value);
                        GM_setValue('disabledbtns', disabledbtns);
                        rvals();
                        alt('Disabled successfully.');
                    } else alt('Button already disabled.');
                } else {
                    let obj = {
                        host: location.host,
                        buttons: [i.value]
                    };
                    fselect.options.add(new Option(i.value, i.value));
                    disabledbtns.push(obj);
                    GM_setValue('disabledbtns', disabledbtns);
                    rvals();
                    alt('Disabled successfully.');
                }
            }
        }
        fbtns[1].onclick = function() {
            if (fselect.selectedIndex > -1) {
                if (confirm('Are you sure you want to remove this rule?')) {
                    this.disabled = true;
                    let d = disabledbtns.MV_search(location.host).obj.buttons;
                    d.splice(d.indexOf(fselect.value), 1);
                    GM_setValue('disabledbtns', disabledbtns);
                    rvals();
                    fselect.selectedOptions[0].remove();
                }
            }
        }
        xselects[1].onchange = function() {
            if (this.selectedIndex > -1) xbtns[1].disabled = false;
            else xbtns[1].disabled = false;
        }
        xbtns[0].onclick = () => {
            let w = xselects[0].value;
            if (exclusions.includes(location.href) || exclusions.includes(location.host)) {
                alt('Page/Website is already excluded');
                return;
            }
            if (w == 'page') {
                if (!confirm('Are you sure you want to add (' + location.href + ') to exclusions?')) return;
                xselects[1].options.add(new Option(location.href, location.href));
                exclusions.push(location.href);
                GM_setValue('exclusions', exclusions);
                rvals();
                remove();
            } else {
                if (!confirm('Are you sure you want to add (' + location.host + ') to exclusions?')) return;
                xselects[1].options.add(new Option(location.host, location.host));
                exclusions.push(location.host);
                GM_setValue('exclusions', exclusions);
                rvals();
                remove();
            }
        }
        xbtns[1].onclick = function() {
            if (xselects[1].selectedIndex > -1) {
                if (confirm('Are you sure you want to remove this rule?')) {
                    this.disabled = true;
                    exclusions.splice(exclusions.MV_search(xselects[1].value).index, 1);
                    GM_setValue('exclusions', exclusions);
                    rvals();
                    xselects[1].selectedOptions[0].remove();
                }
            }
        }
        subbtn.onclick = () => {
            const reader = new FileReader();
            reader.onload = e => {
                u.querySelector('#MV_sub').innerText = reader.result;
                alt('Please wait for a moment');
                sh('subf');
                subthis()
            }
            reader.readAsText(k.querySelector('input').files[0]);
            u.querySelectorAll('.MV_cbtn')[3].onclick = remsub;
        }
        convbtn.onclick = () => {
            let rs = {
                vid: convselect.selectedOptions[0].getAttribute('mv-vid'),
                key: convselect.selectedOptions[0].value
            }
            if (location.host.includes('facebook')) Download('', convselect.selectedOptions[0].getAttribute('mv-title'), convselect.value);
            else if (location.host.includes('youtube')) convert2('youtube', rs);
            if (location.host.includes('youtube')) {
                p.querySelector('select').disabled = true;
                p.querySelector('button').innerText = 'Converting...';
                p.querySelector('button').disabled = true;
            }
        }
    }
    function cuiset() {
        const container = u.querySelector('.MV_container'),
              controls = u.querySelector('.MV_controls'),
              bar = u.querySelector('.MV_bar'),
              loaded = u.querySelector('.MV_loaded'),
              played = u.querySelector('.MV_played'),
              thumb = u.querySelector('.MV_thumb'),
              highlight = u.querySelector('.MV_highlight'),
              currenttime = u.querySelector('.MV_highlight .MV_currenttime'),
              thumbnail = u.querySelector('.MV_highlight .MV_thumbnail'),
              btns = u.querySelectorAll('.MV_cbtn'),
              time = u.querySelector('.MV_time'),
              volm = u.querySelector('.MV_vol'),
              vol = u.querySelector('input'),
              playbackm = u.querySelector('.MV_playbackm'),
              buffer = u.querySelector('.MV_buffer'),
              resizer = u.querySelector('.MV_resizer'),
              treechange = new CustomEvent('treechange', {
                  cancelable: false,
                  detail: {
                      vid() { return container.querySelector('video'); }
                  }
              }),
              observer = new MutationObserver(() => container.dispatchEvent(treechange));
        observer.observe(container, { childList: true });
        container.addEventListener('treechange', e => {
            if (e.detail.vid() && u.style.display == 'block') {
                e.detail.vid().onloadedmetadata = ee => {
                    let v = e.detail.vid();
                    douiplz(v);
                    douiplz(v);
                }
            }
            else if (!e.detail.vid() && u.style.display == 'block') douiplz('exit');
        });
        let idle = 0;
        container.onclick = e => {
            if (e.target.tagName != 'VIDEO') return;
            btns[0].click();
        }
        container.ondblclick = e => {
            if (e.target.tagName != 'VIDEO') return;
            btns[6].click();
        }
        container.onmousemove = () => {
            controls.style.display = 'block';
            container.style.cursor = 'default';
            setTimeout(() => { controls.style.opacity = 1; }, 10);
            idle = 0;
        }
        container.onwheel = e => {
            e.preventDefault();
            let v = u.querySelector('video');
            if (e.deltaY > 0) {
                if (v.muted) v.muted = false;
                if (v.volume - volstep >= 0) v.volume -= volstep;
                else v.volume = 0;
            } else if (e.deltaY < 0) {
                if (v.muted) v.muted = false;
                if (v.volume + volstep <= 1) v.volume += volstep;
                else v.volume = 1;
            }
        }
        container.onkeydown = e => {
            let vals = [play, stop, volplus, volminus, mute, smallback, smallforward, bigback, bigforward, incplayback, decplayback, resplayback, fullscreen, download, pipm, loop, customui],
                v = u.querySelector('video');
            if (e.altKey || e.metaKey || vals.includes(e.code) || ((e.ctrlKey || e.shiftKey) && !['ArrowLeft', 'ArrowRight', 'Space', loop].includes(e.code))) return;
            if (e.code == 'ArrowLeft' && !e.ctrlKey && !e.shiftKey) v.currentTime -= smallstep;
            else if (e.code == 'ArrowRight' && !e.ctrlKey && !e.shiftKey) v.currentTime += smallstep;
            if (e.code == 'ArrowLeft' && e.ctrlKey && !e.shiftKey) v.currentTime -= smallctrl;
            else if (e.code == 'ArrowRight' && e.ctrlKey && !e.shiftKey) v.currentTime += smallctrl;
            if (e.code == 'ArrowLeft' && !e.ctrlKey && e.shiftKey) v.currentTime -= smallshift;
            else if (e.code == 'ArrowRight' && !e.ctrlKey && e.shiftKey) v.currentTime += smallshift;
            else if (e.code == 'ArrowUp') {
                if (v.volume + volstep <= 1) v.volume += volstep;
                else v.volume = 1;
            }
            else if (e.code == 'ArrowDown') {
                if (v.volume - volstep >= 0) v.volume -= volstep;
                else v.volume = 0;
            }
            else if (e.code == 'Space') {
                if (v.paused) v.play();
                else v.pause();
            }
        }
        u.onfullscreenchange = () => {
            let v = u.querySelector('video'),
                fullscreenelm = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
            if (fullscreenelm) btns[6].innerHTML = svgnormalscreen;
            else {
                if (container.MV_hasClass('MV_theater')) {
                    container.classList.remove('MV_theater');
                    u.classList.remove('MV_ctheater');
                    s.style.display = 'block';
                    container.style.width = '';
                    container.style.height = '';
                    container.style.maxWidth = container.getAttribute('mv-maxw');
                }
                if (v.MV_hasClass('MV_vfullscreen')) {
                    v.classList.remove('MV_vfullscreen');
                    s.style.display = 'block';
                }
                buffer.style.left = (v.offsetLeft + (v.offsetWidth / 2) - 30) + 'px';
                buffer.style.top = (v.offsetTop + (v.offsetHeight / 2) - 30) + 'px';
                btns[6].innerHTML = svgfullscreen;
            }
        }
        setInterval(() => {
            idle++;
            if (idle >= 3) {
                controls.style.opacity = 0;
                container.style.cursor = 'none';
                setTimeout(() => { controls.style.display = 'none'; }, 500);
            }
        }, 1000);
        btns[0].onclick = () => {
            let v = u.querySelector('video');
            if (v.paused) btns[0].innerHTML = svgpause;
            else btns[0].innerHTML = svgplay;
            KEY.code = play;
            handler(KEY);
        }
        btns[1].onclick = () => {
            KEY.code = stop;
            handler(KEY);
        }
        btns[2].onclick = () => {
            if (volm.style.width == '80px') volm.style.width = '0';
            else volm.style.width = '80px';
        }
        btns[3].onclick = () => {
            if (location.host == 'www.youtube.com') {
                let ysub = document.querySelector('.captions-text'),
                    usub = u.querySelector('.MV_capt');
                function ttt(ml) {
                    let ysub = document.querySelector('.captions-text'),
                        usub = u.querySelector('.MV_capt'),
                        subb = u.querySelector('.MV_subb');
                    usub.innerText = ysub.innerText;
                    subb.style.display = 'block';
                    subb.style.left = ((document.body.offsetWidth - subb.offsetWidth) / 2) - 20 + 'px';
                }
                const obs = new MutationObserver(ttt)
                if (ysub) {
                    obs.observe(ysub, { attributes: true, childList: true, subtree: true });
                    alt('Added YT Subtitles');
                }
                else if (confirm('Adding subtitles in youtube adds the original captions in the video, if this is the inteded action please select the caption and enable it first before enabling the subtitle option. Otherwise select OK to upload your own.')) {
                    let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
                        v = u.querySelector('video');
                    if (isfullscreen) {
                        KEY.code = fullscreen;
                        handler(KEY);
                    }
                    v.pause();
                    sh('subt');
                }
            } else {
                let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
                    v = u.querySelector('video');
                if (isfullscreen) {
                    KEY.code = fullscreen;
                    handler(KEY);
                }
                v.pause();
                sh('subt');
            }
        }
        btns[4].onclick = () => {
            if (playbackm.style.width == '30px') playbackm.style.width = '0';
            else playbackm.style.width = '30px';
        }
        btns[5].onclick = () => {
            KEY.code = download;
            handler(KEY);
        }
        btns[6].onclick = () => {
            let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
                v = u.querySelector('video');
            if (isfullscreen) {
                KEY.code = fullscreen;
                handler(KEY);
            }
            dofull(u);
            container.style.width = '';
            container.style.height = '';
            container.style.maxWidth = container.getAttribute('mv-maxw');
            if (container.MV_hasClass('MV_theater')) {
                container.classList.remove('MV_theater');
                u.classList.remove('MV_ctheater');
            }
            else {
                container.classList.add('MV_theater');
                u.classList.add('MV_ctheater');
            }
            buffer.style.left = (v.offsetLeft + (v.offsetWidth / 2) - 30) + 'px';
            buffer.style.top = (v.offsetTop + (v.offsetHeight / 2) - 30) + 'px';
        }
        btns[7].onclick = () => {
            if (container.MV_hasClass('MV_theater')) {
                container.classList.remove('MV_theater');
                u.classList.remove('MV_ctheater');
                dofull(u);
            }
            let v = u.querySelector('video');
            container.style.width = '';
            container.style.height = '';
            container.style.maxWidth = container.getAttribute('mv-maxw');
            buffer.style.left = (v.offsetLeft + (v.offsetWidth / 2) - 30) + 'px';
            buffer.style.top = (v.offsetTop + (v.offsetHeight / 2) - 30) + 'px';
            KEY.code = fullscreen;
            handler(KEY);
        }
        vol.onmousedown = () => {
            let v = u.querySelector('video');
            vol.onmousemove = () => {
                if (v.muted) v.muted = false;
                v.volume = vol.value / 100;
            }
            vol.onmouseup = () => {
                if (v.muted) v.muted = false;
                v.volume = vol.value / 100;
                vol.onmousedown = null;
            }
        }
        vol.onkeydown = e => {
            e.preventDefault();
            vol.blur();
            container.focus();
        }
        vol.onkeyup = e => {
            e.preventDefault();
            vol.blur();
            container.focus();
        }
        for (let elm of btns) {
            elm.onkeydown = elm.onkeyup = e => {
                e.preventDefault();
                container.focus();
            }
        }
        playbackm.onclick = e => {
            if (e.target.tagName == 'SPAN') {
                let val = parseFloat(e.target.innerText),
                    v = u.querySelector('video');
                v.playbackRate = val;
            }
        }
        function calct(e, v, c = 0) {
            let rect = bar.getBoundingClientRect(),
                x = e.clientX - rect.left,
                d = (x / bar.offsetWidth) * v.duration;
            if (d < 0) d = 0;
            else if (d > v.duration) d = v.duration;
            if (c == 0) {
                v.currentTime = d;
                played.style.width = x + 'px';
                highlight.style.left = x + 'px';
            } else if (c == 1) {
                v.currentTime = d;
                played.style.width = x + 'px';
                currenttime.innerText = d.MV_format();
                if (v.videoHeight < 1440 && !v.src.startsWith('blob')) getvidth(v.src, d);
                highlight.style.left = x + 'px';
            } else {
                currenttime.innerText = d.MV_format();
                if (v.videoHeight < 1440 && !v.src.startsWith('blob')) getvidth(v.src, d);
                highlight.style.left = x + 'px';
            }
        }
        let downed = false;
        bar.onmousedown = e => {
            let v = u.querySelector('video');
            calct(e, v);
            downed = true;
            window.onmousemove = ee => {
                highlight.style.display = 'inline-block';
                calct(ee, v, 1);
            }
            window.onmouseup = () => {
                highlight.style.display = 'none';
                window.onmousemove = null;
                downed = false;
            }
        }
        bar.onmouseover = () => {
            bar.onmousemove = e => {
                let v = u.querySelector('video');
                highlight.style.display = 'inline-block';
                calct(e, v, 2);
            }
        }
        bar.onmouseout = () => { if (!downed) highlight.style.display = 'none'; }
        resizer.onmousedown = e => {
            let v = u.querySelector('video'),
                startX, startY, startWidth, startHeight;
            container.style.maxWidth = '';
            startX = e.clientX;
            startY = e.clientY;
            startWidth = parseInt(getComputedStyle(container).width, 10);
            startHeight = parseInt(getComputedStyle(container).height, 10);
            window.onmousemove = ee => {
                container.style.width = (startWidth + ee.clientX - startX) + 'px';
                container.style.height = (startHeight + ee.clientY - startY) + 'px';
                buffer.style.left = (v.offsetLeft + (v.offsetWidth / 2) - 30) + 'px';
                buffer.style.top = (v.offsetTop + (v.offsetHeight / 2) - 30) + 'px';
            }
            window.onmouseup = () => {
                window.onmousemove = null;
                window.onmouseup = null;
                buffer.style.left = (v.offsetLeft + (v.offsetWidth / 2) - 30) + 'px';
                buffer.style.top = (v.offsetTop + (v.offsetHeight / 2) - 30) + 'px';
            }
        }
    }
    function vidset(v) {
        const container = u.querySelector('.MV_container'),
              loaded = u.querySelector('.MV_loaded'),
              played = u.querySelector('.MV_played'),
              time = u.querySelector('.MV_time'),
              volm = u.querySelector('.MV_vol'),
              vol = u.querySelector('input'),
              btns = u.querySelectorAll('.MV_cbtn'),
              buffer = u.querySelector('.MV_buffer'),
              inframe = () => window.self != window.top,
              vwidth = () => {
                  let output;
                  for (let i = 40; i < 300;) {
                      if (16 * i >= window.innerWidth) {
                          output = 16 * (i - 20);
                          break;
                      }
                      i = i + 10;
                  }
                  return output + 'px';
              };
        {
            if (inframe()) {
                container.style.maxWidth = window.innerWidth.toFixed(0) + 'px';
                v.classList.add('MV_framed');
                s.classList.add('MV_hidden');
                container.setAttribute('mv-maxw', container.style.maxWidth);
            }
            else if ((v.videoWidth > window.innerWidth || v.videoWidth == 0) && !inframe()) {
                container.style.maxWidth = vwidth();
                container.setAttribute('mv-maxw', container.style.maxWidth);
            }
            if ((v.videoHeight > window.innerHeight && v.videoHeight > v.videoWidth) && !inframe()) v.classList.add('MV_maxheight');
            if (v.paused) btns[0].innerHTML = svgplay;
            else btns[0].innerHTML = svgpause;
            let volume = v.volume;
            vol.value = (v.volume * 100).toFixed(0);
            volm.setAttribute('data-content', (v.volume * 100).toFixed(0));
            if (v.volume == 0) btns[2].innerHTML = svgvolmute;
            else if (v.muted) btns[2].innerHTML = svgvolmute;
            else if (v.volume > 0 && v.volume < 0.33) btns[2].innerHTML = svgvollow;
            else if (v.volume > 0.33 && v.volume < 0.66) btns[2].innerHTML = svgvolmid;
            else if (v.volume > 0.66) btns[2].innerHTML = svgvolhigh;
            btns[4].innerText = v.playbackRate.toFixed(1);
            played.style.width = ((v.currentTime / v.duration) * 100) + '%';
            time.innerText = v.currentTime.MV_format() + '/' + v.duration.MV_format();
            buffer.style.left = (container.offsetLeft + (container.offsetWidth / 2) - 30) + 'px';
            buffer.style.top = (container.offsetTop + (container.offsetHeight / 2) - 30) + 'px';
            buffer.style.display = 'none';
            try {
                for (let i = 0; i < v.buffered.length; i++) {
                    let start = v.buffered.start(i),
                        end = v.buffered.end(i),
                        time = v.currentTime;
                    if (time >= start && time <= end) {
                        let percent = v.buffered.end(i) / v.duration;
                        if (percent * 100 >= 95) percent = 100;
                        else percent = 100 * Math.min(1, Math.max(0, percent));
                        loaded.style.width = percent + '%';
                    }
                }
            } catch (e) { return; }
        }
        v.addEventListener('play', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            btns[0].innerHTML = svgpause;
        });
        v.addEventListener('pause', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            btns[0].innerHTML = svgplay;
        });
        v.addEventListener('volumechange', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            if (this.volume == 0) btns[2].innerHTML = svgvolmute;
            else if (this.volume > 0 && this.volume < 0.33) btns[2].innerHTML = svgvollow;
            else if (this.volume > 0.33 && this.volume < 0.66) btns[2].innerHTML = svgvolmid;
            else if (this.volume > 0.66) btns[2].innerHTML = svgvolhigh;
            vol.value = (this.volume * 100).toFixed(0);
            volm.setAttribute('data-content', (this.volume * 100).toFixed(0));
        });
        v.addEventListener('ratechange', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            btns[4].innerText = this.playbackRate.toFixed(1);
        });
        v.addEventListener('timeupdate', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            played.style.width = ((this.currentTime / this.duration) * 100) + '%';
            time.innerText = this.currentTime.MV_format() + '/' + this.duration.MV_format();
            for (let i = 0; i < this.buffered.length; i++) {
                let start = this.buffered.start(i),
                    end = this.buffered.end(i),
                    time = this.currentTime;
                if (time >= start && time <= end) {
                    let percent = this.buffered.end(i) / this.duration;
                    if (percent * 100 >= 95) percent = 100;
                    else percent = 100 * Math.min(1, Math.max(0, percent));
                    loaded.style.width = percent + '%';
                }
            }
        });
        v.addEventListener('progress', function() {
            if (!this.parentElement.MV_hasClass('MV_container')) return;
            for (let i = 0; i < this.buffered.length; i++) {
                let start = this.buffered.start(i),
                    end = this.buffered.end(i),
                    time = this.currentTime;
                if (time >= start && time <= end) {
                    let percent = this.buffered.end(i) / this.duration;
                    if (percent * 100 >= 95) percent = 100;
                    else percent = 100 * Math.min(1, Math.max(0, percent));
                    loaded.style.width = percent + '%';
                }
            }
        });
        v.addEventListener('waiting', () => { buffer.style.display = 'block'; });
        v.addEventListener('canplay', () => { buffer.style.display = 'none'; });
        v.addEventListener('ended', () => {
            if (u.style.display == 'block' && document.fullscreenElement && document.fullscreenElement.MV_hasClass('MV_container')) {
                KEY.code = fullscreen;
                handler(KEY);
            }
        });
    }
    let ogv;
    function douiplz(v) {
        let order = () => { for (let i = 0; i < v.parentElement.children.length; i++) if (v.parentElement.children[i].tagName == 'VIDEO') return i; },
            controls = () => {
                if (v.controls) return true;
                else return false;
            };
        if (v == 'exit') {
            u.style.display = 'none';
            ogv = false;
            return;
        }
        if (!ogv) {
            ogv = {
                parent: v.parentElement,
                order: order(),
                controls: controls()
            };
            u.style.display = 'block';
            u.querySelector('.MV_container').insertBefore(v, u.querySelector('.MV_container').firstChild);
            v.controls = false;
            vidset(v);
            v.focus();
        } else {
            u.style.display = 'none';
            v.controls = ogv.controls;
            ogv.parent.insertBefore(v, ogv.parent.children[ogv.order]);
            ogv = false;
        }
    }
    function alt(msg, time=3000) {
        a.innerText = msg;
        a.style.cursor = 'default';
        a.style.margin = '0 ' + (document.body.offsetWidth - 500) / 2 + 'px';
        a.style.display = 'block';
        setTimeout(() => { a.style.opacity = '1'; }, 200);
        setTimeout(() => { a.style.opacity = '0'; }, time);
        setTimeout(() => { a.style.display = 'none'; }, time + 600);
    }
    function rvals() {
		play = GM_getValue('play', 'KeyK');
		stop = GM_getValue('stop', 'KeyS');
		volplus = GM_getValue('volplus', 'ArrowUp');
		volminus = GM_getValue('volminus', 'ArrowDown');
		volstep = parseFloat(GM_getValue('volstep', 0.05));
		mute = GM_getValue('mute', 'KeyM');
		smallback = GM_getValue('smallback', 'Comma');
		smallforward = GM_getValue('smallforward', 'Period');
		smallstep = parseFloat(GM_getValue('smallstep', 3));
		bigback = GM_getValue('bigback', 'KeyJ');
		bigforward = GM_getValue('bigforward', 'KeyL');
		bigstep = parseFloat(GM_getValue('bigstep', 30));
		incplayback = GM_getValue('incplayback', 'KeyT');
		decplayback = GM_getValue('decplayback', 'KeyY');
		playbackstep = parseFloat(GM_getValue('playbackstep', 0.1));
		resplayback = GM_getValue('resplayback', 'KeyR');
		fullscreen = GM_getValue('fullscreen', 'KeyF');
		download = GM_getValue('download', 'KeyD');
		pipm = GM_getValue('pipm', 'KeyP');
		loop = GM_getValue('loop', 'KeyO');
		customui = GM_getValue('customui', 'KeyZ');
        smallctrl = parseFloat(GM_getValue('smallctrl', 10));
        smallshift = parseFloat(GM_getValue('smallshift', 20));
        bigctrl = parseFloat(GM_getValue('bigctrl', 90));
        bigshift = parseFloat(GM_getValue('bigshift', 120));
		exclusions = GM_getValue('exclusions', ['placeholder', 'www.soundcloud.com', 'www.spotify.com', 'open.spotify.com', 'discord.com']);
        disabledbtns = GM_getValue('disabledbtns', ['placeholder']);
		savedtime = GM_getValue('savedtime', ['placeholder']);
        hage = parseFloat(GM_getValue('hage', 7));
		autoresume = GM_getValue('autoresume', false);
		autocustomui = GM_getValue('autocustomui', false);
		nocustomui = GM_getValue('nocustomui', ['placeholder', 'www.youtube.com', 'www.facebook.com']);
        noautoresume = GM_getValue('noautoresume', ['placeholder', 'www.youtube.com', 'www.facebook.com']);
		cuicss = GM_getValue('cuicss', ['linear-gradient(140deg, rgba(0, 0, 0, 1) 0%, rgba(85, 85, 85, 1) 89%, rgba(153, 153, 153, 1) 100%)', '#fff3', 'inherit', '#111', '#ccc', '#333', '#111', '#111', '#ccc', '#333', '#000', 'transparent', '#111', '#000', '#ccc', '#ccc', '#ccc', '#ccc', '#fff', '#0007']);
		ccss = GM_getValue('ccss', '');
    }
    function ucss() {
        CUIBC.remove();
        CCSS.remove();
        CUIBC = GM_addStyle(`.MV_customui { background-image: ${cuicss[0]}; } .MV_controls { background: ${cuicss[1]}; } .MV_time { background: ${cuicss[2]}; color: ${cuicss[15]}; } .MV_vol input { background: ${cuicss[3]}; } .MV_vol input::-moz-range-thumb, .MV_vol input::-webkit-slider-thumb { background: ${cuicss[4]}; } .MV_playbackm span, .MV_playbackm { background: ${cuicss[5]}; color: ${cuicss[16]}; } .MV_playbackm span:hover { background: ${cuicss[6]}; color: ${cuicss[17]}; } .MV_bar { background: ${cuicss[7]}; } .MV_played { background: ${cuicss[8]}; } .MV_loaded { background: ${cuicss[9]}; } .MV_thumb { background: ${cuicss[10]}; } .MV_cbtn { background: ${cuicss[11]}; color: ${cuicss[14]}; } .MV_ctheater { background: ${cuicss[12]} } .MV_cbtn svg { fill: ${cuicss[13]}; } .MV_buffer { border-color: ${cuicss[13]} transparent; } .MV_vol:before { color: ${cuicss[14]}; } .MV_subb { color: ${cuicss[18]}; background: ${cuicss[19]}; }`);
        CCSS = GM_addStyle(ccss);
    }
    let recording = [];
    function record(v) {
        v.addEventListener('timeupdate', function() {
            let search1 = savedtime.MV_search(this.src),
                search2 = savedtime.MV_search(location.href);
            if (!recording.includes(this.src)) {
                recording.push(this.src);
                if ((search1.found || (search2.found && document.querySelectorAll('video').length == 1)) && !this.paused && this.currentTime < 20) resume(v);
            }
            if (this.currentTime > 20) {
                if (search1.found) {
                    let obj = search1.obj;
                    obj.href = location.href;
                    obj.time = this.currentTime;
                    obj.lastplayed = (new Date);
                } else if (search2.found && document.querySelectorAll('video').length == 1) {
                    let obj = search2.obj;
                    obj.src = this.src;
                    obj.time = this.currentTime;
                    obj.lastplayed = (new Date);
                } else {
                    let obj = {
                        href: location.href,
                        src: this.src,
                        time: this.currentTime,
                        lastplayed: (new Date)
                    };
                    savedtime.push(obj);
                }
                GM_setValue('savedtime', savedtime);
                rvals();
            }
        });
        v.addEventListener('ended', function() { this.setAttribute('mv-active', false); });
    }
    function resume(v) {
        if (noautoresume.includes(location.host)) return;
        if (this && this.tagName == 'VIDEO') v = this;
        let search1 = savedtime.MV_search(v.src),
            search2 = savedtime.MV_search(location.href);
        if (search2.found && autoresume && document.querySelectorAll('video').length == 1) v.currentTime = search2.obj.time;
        else if (search1.found && autoresume) v.currentTime = search1.obj.time;
        else if ((search1.found || (search2.found && document.querySelectorAll('video').length == 1)) && !autoresume && v.currentTime < 20) {
            let time;
            if (search1.obj) time = search1.obj.time.MV_format();
            else time = search2.obj.time.MV_format();
            if (confirm('You stopped at (' + time + ') last time, continue?')) {
                if (search2.found && document.querySelectorAll('video').length == 1) v.currentTime = search2.obj.time;
                else if (search1.found) v.currentTime = search1.obj.time;
                if (confirm('Auto resume next time?')) {
                    GM_setValue('autoresume', true);
                    m.querySelector('input[name=ar]').checked = true;
                    rvals();
                }
            } else v.onplay = null;
        } else v.onplay = null;
        v.onplay = null;
    }
    function selectv() {
        window.oncontextmenu = t => {
            t.preventDefault();
            let e = t.target;
            if (e.tagName == 'VIDEO') {
                e.setAttribute('mv-active', true);
                e.onended = () => e.setAttribute('mv-active', false);
            } else if (e.querySelector('video')) {
                e.querySelector('video').setAttribute('mv-active', true);
                e.querySelector('video').addEventListener('ended', function() { this.setAttribute('mv-active', false); });
                alt('Video selected, press stop (' + stop + ') to disable selection.');
            } else if (e.parentElement.querySelector('video')) {
                e.parentElement.querySelector('video').setAttribute('mv-active', true);
                e.parentElement.querySelector('video').addEventListener('ended', function() { this.setAttribute('mv-active', false); });
                alt('Video selected, press stop (' + stop + ') to disable selection.');
            } else if (e.parentElement.parentElement.querySelector('video')) {
                e.parentElement.parentElement.querySelector('video').setAttribute('mv-active', true);
                e.parentElement.parentElement.querySelector('video').addEventListener('ended', function() { this.setAttribute('mv-active', false); });
                alt('Video selected, press stop (' + stop + ') to disable selection.');
            } else if (e.parentElement.parentElement.parentElement.querySelector('video')) {
                e.parentElement.parentElement.parentElement.querySelector('video').setAttribute('mv-active', true);
                e.parentElement.parentElement.parentElement.querySelector('video').addEventListener('ended', function() { this.setAttribute('mv-active', false); });
                alt('Video selected, press stop (' + stop + ') to disable selection.');
            } else alt('Could\'t find the video unfortunately. :(');
            window.oncontextmenu = null;
        }
    }
    function convert(url, title) {
        GM_xmlhttpRequest({
            url: 'https://fbdown.net/download.php',
            method: 'POST',
            data: 'URLz=' + encodeURIComponent(url),
            headers: {
                'content-type': 'application/x-www-form-urlencoded;',
                'host': 'fbdown.net',
                'origin': 'https://fbdown.net',
                'referer': 'https://fbdown.net/index.php'
            },
            onload: r => {
                const doc = (new DOMParser).parseFromString(r.responseText, 'text/html'),
                      sdl = doc.querySelector('#sdlink'),
                      hdl = doc.querySelector('#hdlink'),
                      sel = p.querySelector('select');
                sel.innerHTML = '';
                if (!hdl && !sdl) alt('An error has occured please try again.');
                else {
                    if (sdl && sdl.href) {
                        let op = `<option value="${sdl.href}" mv-title="${title}"> SD Video </option>`;
                        sel.innerHTML += op;
                    }
                    if (hdl && hdl.href) {
                        let op = `<option value="${hdl.href}" mv-title="${title}"> HD Video </option>`;
                        sel.innerHTML += op;
                    }
                    sh('cvt');
                }
            }
        });
    }
    function convert2(url, resolved) {
        if (!resolved) {
            GM_xmlhttpRequest({
                url: 'https://www.y2mate.com/mates/en874/analyzeV2/ajax',
                method: 'POST',
                data: 'k_query=' + encodeURIComponent(url) + '&k_page=home&hl=en&q_auto=0',
                headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' },
                onload: r => {
                    const json = JSON.parse(r.responseText),
                          sel = p.querySelector('select');
                    if (json.c_status == 'FAILED') alt('Something went wrong, try again later.');
                    else {
                        sh('cvt');
                        sel.innerHTML = '';
                        const title = json.title,
                              links = json.links,
                              vid = json.vid,
                              mp4 = links.mp4,
                              mp3 = links.mp3;
                        for (let e in mp4) {
                            const key = mp4[e].k,
                                  text = mp4[e].q_text,
                                  quality = mp4[e].q,
                                  op = `<option value="${key}" mv-vid="${vid}" mv-title="${title}" mv-quality="${quality}">${text}</option>`;
                            sel.innerHTML += op;
                        }
                        for (let e in mp3) {
                            const key = mp3[e].k,
                                  text = mp3[e].q_text,
                                  quality = mp3[e].q,
                                  op = `<option value="${key}" mv-vid="${vid}" mv-title="${title}" mv-quality="${quality}">${text}</option>`;
                            sel.innerHTML += op;
                        }
                    }
                }
            });
        }
        else {
            GM_xmlhttpRequest({
                url: 'https://www.y2mate.com/mates/convertV2/index',
                method: 'POST',
                data: `vid=${resolved.vid}&k=${resolved.key}`,
                headers: { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' },
                onload: r => {
                    p.querySelector('select').disabled = false;
                    p.querySelector('button').innerText = 'Download';
                    p.querySelector('button').disabled = false;
                    const json = JSON.parse(r.responseText);
                    if (json.c_status == 'FAILED') alt('Something went wrong, try again later.');
                    else {
                        const dlink = json.dlink,
                              title = json.title,
                              ext = json.ftype
                        Download('', title, dlink, ext);
                    }
                }
            });
        }
    }
    function Download(e, given, source, ext) {
        let src = source || e.src,
            title = given || src.MV_getName() || document.title || 'video',
            getlink = () => {
                let p = e.parentElement;
                do p = p.parentElement;
                while (!p.querySelector('a[aria-label="Enlarge"]') && !p.querySelector('div[aria-label="Enter fullscreen"]'));
                let l = p.querySelector('a[aria-label="Enlarge"]').href || p.querySelector('div[aria-label="Enter fullscreen"]').href;
                l.includes('__cft') ? l = l.substr(0, l.indexOf('__cft')-1) : l;
                return l;
            },
            gettitle = () => {
                let p = e.parentElement;
                do p = p.parentElement;
                while (!p.querySelector('div[dir=auto]') && !p.querySelector('span[dir=auto]'));
                return (p.querySelector('div[dir=auto]') || p.querySelector('span[dir=auto]')).innerText;
            };
        if (location.protocol.includes('file')) {
            alt('Trying to download a local file? Really??');
            return;
        }
        title = title.trim();
        if (!/\.(avi|mkv|flv|divx|mpe?g|webm|mp4|wmv|mov|ogv|ogm|ogx|m4v|m4a|mp3|aac)$/.test(title)) title += '.' + (ext || 'mp4');
        title = title.replaceAll(/[\/\\|<>"?*:]\n/gm, '-');
        if (location.href.includes('youtube.com') && !ext) convert2(location.href);
        else if (location.href.includes('facebook.com')) {
            if (u.style.display != 'block') convert(getlink(), gettitle());
            else alt('Please exit custom UI first.');
        }
        GM_download({
            url: src,
            name: title,
            saveAs: true,
            onerror: function(error) {
                console.error(error);
                if (error.details === undefined) {
                    if (GM_info.downloadMode == 'native') alt('Current Download Mode Isn\'t Compatible With The Script, Please Change The Download Mode To "Default" Or "Browser API" In TamperMonkey Settings!', 5000);
                    else if (error.error.includes('canceled')) alt('Download Canceled.');
                    else if (error.error.includes('not_succeeded')) {
                        GM_notification({
                            title: 'Download Failed!',
                            text: 'Reason: NETWORK_ERROR\nClick Here To Restart.',
                            onclick: () => Download(e, given, source, ext)
                        });
                    }
                    else if (error.error == 'filename must not contain illegal characters') {
                        let newtitle = prompt('Please rename the file!\n\nFile name contains illegal characters / \\ | < > " ? * :\n\nCurrent name: '+title);
                        if (newtitle === null || newtitle == title) {
                            if (confirm('Cancel download?\n\nOK - Yes, cancel.\nCancel - No, don\'t cancel.')) return;
                            else {
                                newtitle = prompt('Then please rename the file!!!\n\nFile name contains illegal characters / \\ | < > " ? * :\n\nCurrent name: ' + title);
                                if (newtitle === null || newtitle == title) alt('Download Canceled.');
                                else Download(e, newtitle, source, ext);
                            }
                        }
                        else Download(e, newtitle, source, ext);
                    }
                    else if (!source) {
                        if (location.href.includes('youtube.com')) convert2(location.href);
                        else if (location.href.includes('facebook.com')) {
                            if (u.style.display != 'block') convert(getlink(), gettitle());
                            else alt('Please exit custom UI first.');
                        } else alt('Cannot download this video, try online video converters.');
                    }
                    else Download(e, given, source, ext);
                }
                else if (error.details.current == 'SERVER_FORBIDDEN') {
                    GM_notification({
                        title: 'Download Failed!',
                        text: 'Reason: SERVER_FORBIDDEN\nDetails: Server Closed Connection Due To Unauthorized Access OR The Link Expired.\nPlease Reload Then Try Again!',
                    });
                    return;
                }
                else if (error.details.current != 'USER_CANCELED') {
                    GM_notification({
                        title: 'Download Failed!',
                        text: 'Reason: USER_CANCELED\nClick Here To Restart.',
                        onclick: () => Download(e, given, source, ext)
                    });
                }
            }
        });
    }
    let noffsetw, noffseth, noffsetl, foffsetw, foffseth;
    function dofull(e) {
        let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
            buffer = u.querySelector('.MV_buffer'),
            v = u.querySelector('video') || e;
        if (e.tagName == 'VIDEO') {
            if (!e.getAttribute('mv-ogctrls')) {
                e.setAttribute('mv-ogctrls', e.controls);
                e.controls = true;
            } else e.controls = e.getAttribute('mv-ogctrls');
        }
        if (!isfullscreen) {
            if (e.requestFullscreen) e.requestFullscreen();
            else if (e.mozRequestFullScreen) e.mozRequestFullScreen();
            else if (e.webkitRequestFullScreen) e.webkitRequestFullScreen();
            else if (e.msRequestFullscreen) e.msRequestFullscreen();
            s.style.display = 'none';
            v.classList.add('MV_vfullscreen');
            if (e.MV_hasClass('MV_container')) {
                noffsetw = v.offsetWidth;
                noffseth = v.offsetHeight;
                noffsetl = v.offsetLeft;
                buffer.style.left = ((window.screen.width / 2) - 30) + 'px';
                buffer.style.top = ((window.screen.height / 2) - 30) + 'px';
            }
        } else {
            if (document.exitFullscreen) document.exitFullscreen();
            else if (document.webkitExitFullscreen) document.webkitExitFullscreen();
            else if (document.mozCancelFullScreen) document.mozCancelFullScreen();
            else if (document.msExitFullscreen) document.msExitFullscreen();
            s.style.display = 'block';
            v.classList.remove('MV_vfullscreen');
            if (e.MV_hasClass('MV_container')) {
                buffer.style.left = (noffsetl + (noffsetw / 2) - 30) + 'px';
                buffer.style.top = ((noffseth / 2) - 30) + 'px';
            }
        }
    }
    function timedloop(t1, t2, v) {
        let timer = () => { if (v.currentTime >= t2) v.currentTime = t1; };
        v.addEventListener('timeupdate', timer);
        window.MV_timerloop = timer;
        v.play();
    }
    function handler(e) {
        if (e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA' || e.altKey || e.metaKey || ((e.ctrlKey || e.shiftKey) && ![bigforward, bigback, smallforward, smallback, loop].includes(e.code)) || (e.target.tagName == 'DIV' && (e.target.MV_search('comment', 'includes').found || e.target.MV_search('Comment', 'includes').found || e.target.MV_search('editor', 'includes').found || e.target.MV_search('Editor', 'includes').found))) return;
        let key = e.code,
            v = document.querySelectorAll('video'),
            f,
            ui = false,
            fe = document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement,
            vals = [play, stop, volplus, volminus, mute, smallback, smallforward, bigback, bigforward, decplayback, incplayback, resplayback, fullscreen, download, pipm, loop, customui];
        if (u.style.display == 'block') ui = true;
        if (disabledbtns.MV_search(location.host).found && disabledbtns.MV_search(location.host).obj.buttons.includes(key) && !ui) {
            if (ogv.parent) ogv.parent.focus();
            else document.body.focus();
            return;
        }
        if (vals.includes(key)) {
            if (u.style.display == 'block') {
                v = u.querySelector('video');
                f = v.parentElement;
            }
            else if (fe && fe.tagName == 'VIDEO') v = fe;
            else if (fe && fe.querySelector('video')) v = fe.querySelector('video');
            else if (v.length == 1) v = v[0];
            else {
                let ps = [];
                for (let i = 0; i < v.length; i++) {
                    let e = v[i];
                    if (!e.paused) ps.push(e);
                }
                if (ps.length == 1) v = ps[0];
                else if (document.querySelector('video[mv-active=true]')) v = document.querySelector('video[mv-active=true]');
                else {
                    alt('Multiple videos found, please select one by right clicking it.', 5000);
                    selectv();
                    return;
                }
            }
        } else return;
        if (v) v.setAttribute('mv-active', true);
        if (!f) f = v;
        if (ui) v.focus();
        if (key == play) {
            if (v.paused) v.play();
            else v.pause();
        }
        else if (key == stop) {
            v.currentTime = 0;
            v.pause();
            v.setAttribute('mv-active', false);
        }
        else if (key == volplus) {
            if (v.muted) v.muted = false;
            if (v.volume + volstep <= 1) v.volume += volstep;
            else v.volume = 1;
        }
        else if (key == volminus) {
            if (v.muted) v.muted = false;
            if (v.volume - volstep >= 0) v.volume -= volstep;
            else v.volume = 0;
        }
        else if (key == mute) {
            let btn = u.querySelectorAll('.MV_cbtn')[2];
            if (v.muted) {
                v.muted = false;
                let vol = v.volume;
                v.volume = 0.5;
                v.volume = vol;
            }
            else {
                v.muted = true;
                setTimeout(() => { btn.innerHTML = svgvolmute; }, 10);
            }
        }
        else if (key == smallback && !e.ctrlKey && !e.shiftKey) v.currentTime -= smallstep;
        else if (key == smallforward && !e.ctrlKey && !e.shiftKey) v.currentTime += smallstep;
        else if (key == bigback && !e.ctrlKey && !e.shiftKey) v.currentTime -= bigstep;
        else if (key == bigforward && !e.ctrlKey && !e.shiftKey) v.currentTime += bigstep;
        else if (key == smallback && e.ctrlKey && !e.shiftKey) v.currentTime -= smallctrl;
        else if (key == smallforward && e.ctrlKey && !e.shiftKey) v.currentTime += smallctrl;
        else if (key == bigback && e.ctrlKey && !e.shiftKey) v.currentTime -= bigctrl;
        else if (key == bigforward && e.ctrlKey && !e.shiftKey) v.currentTime += bigctrl;
        else if (key == smallback && !e.ctrlKey && e.shiftKey) v.currentTime -= smallshift;
        else if (key == smallforward && !e.ctrlKey && e.shiftKey) v.currentTime += smallshift;
        else if (key == bigback && !e.ctrlKey && e.shiftKey) v.currentTime -= bigshift;
        else if (key == bigforward && !e.ctrlKey && e.shiftKey) v.currentTime += bigshift;
        else if (key == decplayback) {
            if (v.playbackRate + playbackstep <= 5) v.playbackRate += playbackstep;
            else v.playbackRate = 5;
        }
        else if (key == incplayback) {
            if (v.playbackRate - playbackstep >= 0.1) v.playbackRate -= playbackstep;
            else v.playbackRate = 0.1;
        }
        else if (key == resplayback) v.playbackRate = 1;
        else if (key == fullscreen) dofull(f);
        else if (key == download) Download(v);
        else if (key == pipm) {
            if (document.pictureInPictureElement) document.exitPictureInPicture();
            else if (document.pictureInPictureEnabled) v.requestPictureInPicture();
        }
        else if (key == loop && !e.ctrlKey && e.shiftKey) {
            if (!window.MV_timerloop) {
                v.pause();
                let time1 = v.currentTime,
                    controler = e => {
                        v.removeEventListener('seeked', controler);
                        let time2 = v.currentTime;
                        alt('Looping from ' + time1.MV_format() + ' To ' + time2.MV_format());
                        timedloop(time1, time2, v);
                    };
                alt('Loop start point set: ' + time1.MV_format() + '\nPlease set end point by seeking.');
                v.addEventListener('seeked', controler);
            } else {
                v.removeEventListener('timeupdate', window.MV_timerloop);
                window.MV_timerloop = undefined;
                alt('Looping stopped.');
            }
        }
        else if (key == loop) {
            if (v.loop) v.loop = false;
            else v.loop = true;
        }
        else if (key == customui) douiplz(v);
    }
    function deleteold() {
        for (let i = 1; i < savedtime.length; i++) {
            let e = savedtime[i];
            if (e.lastplayed) {
                let age = (new Date((new Date) - (new Date(e.lastplayed)))).getDate();
                if (age > hage + 1) savedtime.splice(i, 1);
            }
        }
        GM_setValue('savedtime', savedtime);
        rvals();
    }
    function br(mode) {
        const i = document.querySelector('.MV_b input'),
              fr = new FileReader(),
              f = i.files[0];
        let res;
        if (!fr) alt('File API not supported!');
        else if (mode == 0) {
            const a = document.createElement('a'),
                  date = (new Date).toDateString().split(' '),
                  time = date[2] + '-' + date[1],
                  names = GM_listValues(),
                  values = [],
                  parsed = [];
            names.forEach(e => { values.push(GM_getValue(e)); });
            parsed.push(names);
            parsed.push(values);
            a.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(parsed));
            a.download = '(' + time + ').XDHx86_MyVideo.data.txt';
            a.click();
            a.remove();
        } else if (mode == 1) {
            if (!f) {
                alt('Please select a file!');
                return;
            }
            fr.onload = () => { res = fr.result; }
            fr.readAsText(f);
            setTimeout(() => {
                let arr = JSON.parse(res),
                    g = arr[0],
                    v = arr[1];
                if (!g || !g.MV_search('firsttime').found) alt('This is not a backup file, please check the uploaded file.');
                else {
                    for (let i = 0; i < g.length; i++) GM_setValue(g[i], v[i]);
                    if (confirm('Settings will take effect after reload.\nReload now?')) location.reload();
                }
            }, 1500);
        }
    }
    function feedback() {
        let html = document.createElement('div'),
            css = document.createElement('style');
        html.className = 'MV_fcontainer';
        html.innerHTML = '<div class="MV_main"> <h3 class="MV_head"> Subject: </h3> <input class="MV_sub"> <h3 class="MV_head"> Message Body: </h3> <span> Please don\'t actually use this to write your message and use an editor then paste here. </span> <br> <textarea class="MV_msg" spellcheck="true" style=" "></textarea> <br> <br> <button class="MV_send"> Send </button> </div>';
        css.innerHTML = '.MV_fcontainer { z-index: 2147483644; top: 0; left: 0; position: absolute; background-color: #000c; color: #090; width: 100%; height: 100%; display: flex; transition: all 0.5s; user-select: none; } .MV_main { margin: auto; transition: inherit; background-color: #000; height: 70%; padding: 20px; border-radius: 15px; width: 50%; box-shadow: 0 0 20px 20px #090; } .MV_head { margin: 15px 0 0; } .MV_fcontainer input { width: auto; min-width: 100px; margin: 2px; background-color: #111; color: #777; border: none; padding: 2px; outline: 0; margin-left: 15px; font-weight: bolder; outline: 0; transition: inherit; } .MV_fcontainer input:focus { box-shadow: 0 0 5px 2px #090; padding: 3px; margin: 5px 1px 5px 10px; outline: 0; border: 1px solid #090; } .MV_fcontainer span { margin-left: 15px; } .MV_msg { width: calc(100% - 40px); height: calc(100% - 250px); min-width: 100px; margin: 2px; background-color: #111; color: #777; border: none; padding: 2px; outline: 0; margin-left: 15px; font-weight: bolder; outline: 0; transition: inherit; } .MV_send:hover { color: #090; background-color: #000; } .MV_send { transition: inherit; border: none; color: #000; background-color: #090; outline: 0; font-family: sans-serif; cursor: pointer; padding: 5px 20px; font-weight: bolder; margin-left: 10px; margin-top: 10px; }';
        document.body.appendChild(html);
        document.head.appendChild(css);
        html.onclick = e => {
            if (e.target.MV_hasClass('MV_fcontainer')) {
                html.remove();
                css.remove();
            }
        }
        html.querySelector('.MV_send').onclick = () => {
            let sub = html.querySelector('.MV_sub'),
                msg = html.querySelector('.MV_msg'),
                validate = () => {
                    let output = true;
                    if (!msg.value) {
                        msg.setCustomValidity('Message body is required');
                        msg.reportValidity();
                        msg.onfocus = () => msg.setCustomValidity('');
                        alt('Message body is required!');
                        output = false;
                    }
                    return output;
            };
            if (validate()) {
                if (!sub.value) sub.value = 'My Video v' + GM_info.script.version + ' feedback';
                let link = 'mailto:xdhx86@gmail.com&subject=' + encodeURIComponent(sub.value) + '&body=' + encodeURIComponent(msg.value);
                window.open(link, '_blank');
                html.remove();
                css.remove();
                alt('Thanks for the feedback!');
            }
        }
    }
    function getvidth(link, seekto=0) {
        let vid = document.createElement('video'),
            thumbnail = u.querySelector('.MV_thumbnail');
        thumbnail.innerHTML = '<span class="MV_rotate"></span>';
        vid.src = link;
        vid.load();
        vid.onloadedmetadata = () => {
            if (vid.duration < seekto) seekto = vid.duration;
            vid.onseeked = () => {
                let canvas = document.createElement('canvas');
                canvas.width = vid.videoWidth;
                canvas.height = vid.videoHeight;
                let ctx = canvas.getContext('2d');
                ctx.drawImage(vid, 0, 0, canvas.width, canvas.height);
                thumbnail.innerHTML = '';
                thumbnail.appendChild(ctx.canvas);
                vid.remove();
                ctx = canvas = vid = undefined;
            }
            setTimeout(() => { vid.currentTime = seekto; }, 200);
        }
    }
    function remove() {
        c.remove();
        f.remove();
        m.remove();
        o.remove();
        s.remove();
        u.remove();
        x.remove();
        window.onkeydown = null;
        for (let e of document.querySelectorAll('video')) e.onplay = null;
        let cmd = GM_registerMenuCommand('Remove from exclusions ('+location.host+')', () => {
            if (exclusions.MV_search(location.href).found) {
                if (!confirm('Are you sure you want to remove (' + location.href + ') from exclusions?')) return;
                exclusions.splice(exclusions.MV_search(location.href).index, 1);
                GM_setValue('exclusions', exclusions);
                rvals();
                include();
            }
            else {
                if (!confirm('Are you sure you want to remove (' + location.host + ') from exclusions?')) return;
                exclusions.splice(exclusions.MV_search(location.host).index, 1);
                GM_setValue('exclusions', exclusions);
                rvals();
                include();
            }
            GM_unregisterMenuCommand(cmd);
        });
        alt('Added successfully. To remove go to TamperMonkey addon menu');
        setTimeout(() => a.remove, 6000);
    }
    let removesubpls;
    function subthis() {
        removesubpls = false;
        let subj = [{
            key: '0',
            from: '00:00:00',
            to: '00:00:00',
            text: 'Place Holder'
        }],
            arr = u.querySelector('#MV_sub').innerHTML.split('<br><br>');
        arr.forEach(e => {
            if (e.split('<br>')[1]) {
                let parts = e.split('<br>'),
                    key = parts[0],
                    from = parts[1].split(' --&gt; ')[0].split(',')[0],
                    to = parts[1].split(' --&gt; ')[1].split(',')[0],
                    text = parts.splice(2).join(' '),
                    obj = {
                        key: key,
                        from: from,
                        to: to,
                        text: text
                    };
                subj.push(obj);
            }
        });
        u.querySelector('video').addEventListener('timeupdate', function(e) {
            let time = u.querySelector('.MV_time').innerText.split('/')[0],
                subb = u.querySelector('.MV_subb'),
                capt = u.querySelector('.MV_capt');
            if (removesubpls) {
                capt.innerText = '';
                subb.style.display = 'none';
                return;
            }
            for (let i = 0; i < subj.length; i++) {
                if (subj[i].from < time && subj[i].to > time) {
                    capt.innerText = subj[i].text;
                    subb.style.display = 'block';
                }
                if (subj[i].from == time) {
                    capt.innerText = subj[i].text;
                    subb.style.display = 'block';
                }
                if (subj[i].to == time) {
                    capt.innerText = '';
                    subb.style.display = 'none';
                }
            }
            subb.style.left = ((document.body.offsetWidth - subb.offsetWidth) / 2) - 20 + 'px';
        });
        alt('Subtitle imported successfully');
    }
    function remsub() {
        let v = u.querySelector('video'),
            subb = u.querySelector('.MV_subb'),
            capt = u.querySelector('.MV_capt'),
            sub = u.querySelector('#MV_sub'),
            subbtn = u.querySelectorAll('.MV_cbtn')[3];
        v.pause();
        if (!confirm('This will remove current subtitle, are you sure?')) return;
        removesubpls = true;
        subb.style.display = 'none';
        sub.innerHTML = '';
        subbtn.onclick = () => {
            if (location.host == 'www.youtube.com') {
                let ysub = document.querySelector('.captions-text'),
                    usub = u.querySelector('.MV_capt');
                function ttt(ml) {
                    let ysub = document.querySelector('.captions-text'),
                        usub = u.querySelector('.MV_capt'),
                        subb = u.querySelector('.MV_subb');
                    usub.innerText = ysub.innerText;
                    subb.style.display = 'block';
                    subb.style.left = ((document.body.offsetWidth - subb.offsetWidth) / 2) - 20 + 'px';
                }
                const obs = new MutationObserver(ttt)
                if (ysub) {
                    obs.observe(ysub, { attributes: true, childList: true, subtree: true });
                    alt('Added YT Subtitles');
                }
                else if (confirm('Adding subtitles in youtube adds the original captions in the video, if this is the inteded action please select the caption and enable it first before enabling the subtitle option. Otherwise select OK to upload your own.')) {
                    let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
                        v = u.querySelector('video');
                    if (isfullscreen) {
                        KEY.code = fullscreen;
                        handler(KEY);
                    }
                    v.pause();
                    sh('subt');
                }
            } else {
                let isfullscreen = (document.fullscreenElement && document.fullscreenElement !== null) || (document.webkitFullscreenElement && document.webkitFullscreenElement !== null) || (document.mozFullScreenElement && document.mozFullScreenElement !== null) || (document.msFullscreenElement && document.msFullscreenElement !== null),
                    v = u.querySelector('video');
                if (isfullscreen) {
                    KEY.code = fullscreen;
                    handler(KEY);
                }
                v.pause();
                sh('subt');
            }
        }
    }
    let INTERVAL, tracked = [];
    function include() {
        ui();
        set();
        cuiset();
        window.onkeydown = handler;
        INTERVAL = setInterval(() => {
            for (let e of document.querySelectorAll('video')) {
                if (!tracked.includes(e.src)) {
                    let search1 = savedtime.MV_search(e.src),
                        search2 = savedtime.MV_search(location.href);
                    record(e);
                    tracked.push(e.src);
                    if ((search1.found || (search2.found && document.querySelectorAll('video').length == 1))) e.onplay = resume;
                    else e.onplay = null;
                }
            }
        }, 3000);
    }
    if (location.href.MV_includes(exclusions)) {
        let cmd = GM_registerMenuCommand('Remove from exclusions ('+location.host+')', () => {
            if (exclusions.MV_search(location.href).found) {
                if (!confirm('Are you sure you want to remove (' + location.href + ') from exclusions?')) return;
                exclusions.splice(exclusions.MV_search(location.href).index, 1);
                GM_setValue('exclusions', exclusions);
                rvals();
                include();
                alt('Removed successfully.');
            }
            else {
                if (!confirm('Are you sure you want to remove (' + location.host + ') from exclusions?')) return;
                exclusions.splice(exclusions.MV_search(location.host).index, 1);
                GM_setValue('exclusions', exclusions);
                rvals();
                include();
                alt('Removed successfully.');
            }
            GM_unregisterMenuCommand(cmd);
        });
    }
    else {
        include();
        let added = false,
            cuiloader = (retries=0) => {
                if (retries >= 3 || added) return;
                if (autocustomui && document.querySelectorAll('video').length == 1) {
                    let v = document.querySelector('video');
                    added = true;
                    v.ontimeupdate = v.oncanplay = v.onplay = v.onplaying = v.onprogress = e => {
                        v.ontimeupdate = v.oncanplay = v.onplay = v.onplaying = v.onprogress = null;
                        if (u.style.display != 'block') douiplz(v);
                    }
                }
            }
        if (!nocustomui.includes(location.host)) {
            let i = 0,
                int = setInterval(() => {
                    if (!added) {
                        cuiloader(i);
                        i++;
                    }
                    if (added || i >= 3) clearInterval(int);
                }, 3000);
        }
    }
    deleteold();
    GM_registerMenuCommand('Feedback', feedback);
})();