NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Reslator - LNMTL Plugin // @author Spawner // @version 1.2.95 // @namespace reader_translators // @match https://lnmtl.com/chapter/* // @require https://userscripts-mirror.org/scripts/source/107941.user.js#sha384=Q8t880BurrlGKTdpvYv2+da12PYnvljdiU8aJvakk1uE3QMbzb190ueXNpAUY98p // @updateURL https://openuserjs.org/meta/Spawner/Reslator_-_LNMTL_Plugin.meta.js // @downloadURL https://openuserjs.org/install/Spawner/Reslator_-_LNMTL_Plugin.user.js // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @license MIT // @run-at document-start // @connect translate.alibaba.com // @connect aidatrans.com // @connect test.niutrans.com // @connect niutrans.com // @connect translate.googleapis.com // @connect translate.minganci.org // @connect https://www.kingsoftai-fanyi.com/aida_api/text/translate // @connect kingsoftai-fanyi.com/aida_api/text/translate // @connect kingsoftai-fanyi.com // @require http://code.jquery.com/jquery-3.4.1.min.js // @description 6/1/2020, 1:51:50 PM // ==/UserScript== /* | Plugin : Reslator | Version : 1.2.941 | Author : Spawner | Description : Reader & Translator, which gives the user a better experience. CHANGELOG : 1.0 - Initial release 1.1 - Add Glossary support 1.2 - + Fixed : Word higlighter + Raw on click delay 1.2.1 - Fixed comments section 1.2.2 - + Improve performance + Fixing a small issue in the glossary 1.2.3 - + Performance improvement + Add secondary theme switcher + Save raw/original text state 1.2.4 - Improve Aideep speed + Fix translation display 1.2.5 - Fix niutrans API 1.2.6 - Added a new provider 1.2.7 - + Navigation between chapters has become much smoother. + Changing the main font of the reader for a better a better one. + Adding a font size controller. + Fixed font delay problem. 1.2.8 - + Fixed niutrans + Added deepL ( temporary ) 1.2.9 - + Added Alibaba service 1.2.91 - + Deepl removed + Alibaba model changed 1.2.92 - + Deepl fixed. + Niutrans fixed. 1.2.93 - + Niutrans fixed (again). 1.2.94 - + Fixed some bugs on some providers. + Added a new translation engine ( Aideep translation ) 1.2.95 - + AIDeep fix */ let iframeHandler; let uniqueWords = new Map(); let autoThemeState = GM_SuperValue.get("autoThemeState", false); let autoReaderState = GM_SuperValue.get("autoReaderState", false); let autoRawState = GM_SuperValue.get("autoRawState", false); let providerOriginalState = GM_SuperValue.get("providerOriginalState", false); let providerGoogleState = GM_SuperValue.get("providerGoogleState", false); let providerAlibabaState = GM_SuperValue.get("providerAlibabaState", false); let providerNiutransState = GM_SuperValue.get("providerNiutransState", false); let providerAideepState = GM_SuperValue.get("providerAideepState", false); let providerDeeplState = GM_SuperValue.get("providerDeeplState", false); let secondaryTheme = GM_SuperValue.get("secondaryTheme", ""); let fontSizeValue = GM_SuperValue.get("fontSizeValue", ""); let fontSizeValueDefault = GM_SuperValue.get("fontSizeValueDefault", ""); const providers = ["Google", "Alibaba", "Niutrans", "Aideep", "Deepl"]; let isTranslated = { Google: [providerGoogleState, false], Niutrans: [providerNiutransState, false], Alibaba: [providerAlibabaState, false], Aideep: [providerAideepState, false], Deepl: [providerDeeplState, false], }; const providerObject = { Google: { maxSize: 5000, timeout: 0, color: ["48, 175, 219", 0.04], }, Niutrans: { maxSize: 4000, timeout: 400, color: ["235, 77, 75", 0.06], }, Alibaba: { maxSize: 900, timeout: 1000, color: ["255, 164, 58", 0.06], }, Aideep: { maxSize: 1500, timeout: 30, color: ["140, 122, 230", 0.1], }, Deepl: { maxSize: 1000, timeout: 1000, color: ["52, 73, 94", 0.1], } }; /** * Show text * * If no translation is enabled, show the original text * otherwise hide it. */ if ( !providerGoogleState && !providerAlibabaState && !providerNiutransState && !providerAideepState ) providerOriginalState = true; if (fontSizeValue === "" || fontSizeValueDefault === "") { fontSizeValue = "20"; fontSizeValueDefault = "19"; } /** * Apply the theme properly. * * The reason to set the display as 'none' and opacity as '0' * is to avoid the iframe onload screen flash, we also need to hide the scrollbar * since we will be using the iframe one. */ if (autoReaderState) { GM_addStyle( ` html { background-color : ${autoThemeState ? "#E9E9E9" : "#25282F"}; } #app { display : none; opacity : 0; overflow-y : hidden; } ` ); } /* * Initializing our CSS Styles * * The iframe ( #pageContainer ) needs to be created at document-start * to avoid any performance issues. */ GM_addStyle(` #pageContainer, #pagePreload { font-family : Open sans; position : fixed; top : 0px; left : 0px; overflow-y : scroll; width : 100%; height : 100%; display : block; border-width : 0px; } `); /* * Global variables for theme & settings Colors * * Using the :root selector to easily * switch between colors. */ let CSSRoot = ` :root { --background-color : #E9E9E9; --close-btn-back-color : #fff; --close-btn-fore-color : #000; --title-color : #000; --chapter-color : #000; --raw-color : #424242; --settings-t-clicked-color : #E9E9E9; --settings-label-color : rgba(51, 47, 53, 0.4); --settings-check-back-color : linear-gradient(to right, #000000, #434343); --checked-background : #029992; --checked-background-rgb : 2, 153, 146; } [data-theme="dark"] { --background-color : #25282F; --close-btn-back-color : #000; --close-btn-fore-color : #fff; --title-color : #fff; --chapter-color : #E9E9E9; --raw-color : #424242; --settings-t-clicked-color : #25282F; --settings-label-color : #E9E9E9; --settings-check-back-color : #E9E9E847; --checked-background : #029992; --checked-background-rgb : 2, 153, 146; } [data-sec-theme="gold"] { --checked-background : #F39B3A; --checked-background-rgb : 243, 155, 58; } [data-sec-theme="moon"] { --checked-background : #9c88ff; --checked-background-rgb : 156, 136, 255; } [data-sec-theme="bomb"] { --checked-background : #eb4d4b; --checked-background-rgb : 235, 77, 75; } [data-sec-theme="default"] { --checked-background : #029992; --checked-background-rgb : 2, 153, 146; } `; /* * Our iframe body styles * * Note : To avoid the scroll flickering issue we will * be using will-change : transform as a temporary solution. */ let CSSContainer = ` html { background-color : var(--background-color); } @keyframes fadein { from { opacity : 0; } to { opacity : 1; } } .chapterBody { position : relative !important; font-family : "Source Sans Pro" !important; text-align : justify !important; animation : fadein 3s; will-change : transform; overflow : visible; color : var(--chapter-color); max-width : 72%; min-height : 100%; margin : 0 auto; padding-bottom : 80px; } .pageContainerBackground { animation : fadein 1s; min-height : 100%; } .pageContainerSettings { transition : all 0.35s ease-in-out; background-color : transparent !important; margin : auto; } .pageSplit { animation : fadein 3s; border-bottom : 1px solid rgba(var(--checked-background-rgb), 0.3) !important; /*margin : 0px 0px 10px;*/ } h1.header-title { color : var(--checked-background); animation : fadein 3s; font-family : Poppins; font-weight : 300; font-size : 2.25em; text-align : center; padding-bottom : .3em; line-height : 1.2; margin : 3em auto .2em; color : var(--title-color); text-shadow : 0 0 4px rgba(0, 0, 100,.5); } `; let CSSForm = ` .settingsForm { will-change : transform; position : relative; justify-content : center; margin-left : -16; margin-top : 20; flex-wrap : wrap; } form { font-size : 13px; letter-spacing : .2em; font-family : sans-serif; display : flex; margin-top : 0em; } label { user-select : none; color : var(--settings-label-color); text-transform : uppercase; font-family : sans-serif; display : flex; font-weight : bold; padding : 7px 16px; /* margin-right : -4px; */ } input[type=checkbox], input[type=radio] { color : #000; position : normal; visibility : hidden; display : none; } input[type=checkbox][value=o-translator-p]:checked+label { background : #fff; cursor : pointer; } input[type=checkbox][value=o-translator-p]:hover+label { color : #000; cursor : pointer; } input[type=checkbox][value=g-translator-p]:checked+label { color : #fff; background : var(--settings-check-back-color); cursor : pointer; } input[type=checkbox][value=s-translator-p]:checked+label { color : #fff; background : var(--settings-check-back-color); cursor : pointer; } input[type=checkbox][value=n-translator-p]:checked+label { color : #fff; background : var(--settings-check-back-color); cursor : pointer; } input[type=checkbox][value=b-translator-p]:checked+label { color : #fff; background : var(--settings-check-back-color); cursor : pointer; } input[type=checkbox][value=y-translator-p]:checked+label { color : #fff; background : var(--settings-check-back-color); cursor : pointer; } input[type=checkbox][name=g-translator-p]:checked+label, input[type=radio][name=g-translator-p]:checked+label { color : #fff; background : #000; cursor : pointer; } input[type=checkbox]+label:hover, input[type=radio]+label:hover { /* transition : all 0.25s ease-in-out; */ color : #fff; cursor : pointer; } input[type=checkbox]+label, input[type=radio]+label { transition : all 0.15s cubic-bezier(0.4, 0, 0.6, 1) 0s; background : var(--settings-t-clicked-color); color : #545454; } input[type=radio][value=raw]:checked+label { color : #fff; background : #7DD7FB; cursor : default; } input[type=radio][value=mode-enabled]:checked+label { transition : all 200ms ease; background : var(--checked-background); color : #fff; cursor : default; } input[type=radio][value=mode-disabled]:checked+label { background : #25282F; color : #fff; cursor : default; } input[type=radio][value=theme-enabled]:checked+label { background : #fff; color : #000; cursor : default; } input[type=radio][value=theme-disabled]:checked+label { background : #000; color : #fff; cursor : default; } .radio-group, .checkbox-group { font-size : 9px; letter-spacing : .2em; border : solid 0px rgb(125, 214, 255); display : flex; margin : 0px 0px 30px; border-radius : 20px; overflow : hidden; box-shadow : rgba(0, 0, 0, 0.3) 0px 8px 16px 0px; opacity : 0.7; } .radio-group:hover, .checkbox-group { opacity : 1; transition : 1.0s; } `; let CSSChapterBody = ` .sentence { animation : fadein 2s; } .sentence.or { margin-block-end: -0.5em !important; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.google.default { padding : 0px; background : transparent; border-left-style : none; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.alibaba.default { padding : 0px; background : transparent; border-left-style : none; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.niutrans.default { padding : 0px; background : transparent; border-left-style : none; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.Aideep.default { padding : 0px; background : transparent; border-left-style : none; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.deepl { margin-block-end: -0.5em !important; word-spacing : 1px; text-align : initial; animation : fadein 0.4s; line-height : 1.7; font-size : 17px; border-left-style : solid; border-color : transparent transparent transparent rgb(${providerObject["Deepl"]["color"][0]}); padding : 10 10px; background : rgba(${providerObject["Deepl"]["color"][0]}, ${providerObject["Deepl"]["color"][1]}); margin : 25 0; } .sentence.deepl.default { padding : 0px; background : transparent; border-left-style : none; word-spacing : 1px; text-align : initial; font-weight : 300; line-height : 1.7; margin-top : 3.1em; font-size : 20px; } .sentence.alibaba { margin-block-end: -0.5em !important; word-spacing : 1px; text-align : initial; animation : fadein 1s; line-height : 1.7; font-size : 17px; border-left-style : solid; border-color : transparent transparent transparent rgb(${providerObject["Alibaba"]["color"][0]}); padding : 10 10px; background : rgba(${providerObject["Alibaba"]["color"][0]}, ${providerObject["Alibaba"]["color"][1]}); margin : 25 0; } .sentence.google { margin-block-end: -0.5em !important; word-spacing : 1px; text-align : initial; animation : fadein 1s; line-height : 1.7; font-size : 18px; border-left-style : solid; border-color : transparent transparent transparent rgb(${providerObject["Google"]["color"][0]}); padding : 10 10px; background : rgba(${providerObject["Google"]["color"][0]}, ${providerObject["Google"]["color"][1]}); margin : 25 0; } .sentence.niutrans { margin-block-end: -0.5em !important; animation : fadein 1s; line-height : 1.7; font-size : 18px; border-left-style : solid; border-color : transparent transparent transparent rgb(${providerObject["Niutrans"]["color"][0]}); padding : 10 10px; background : rgba(${providerObject["Niutrans"]["color"][0]}, ${providerObject["Niutrans"]["color"][1]}); margin : 25 0; } .sentence.Aideep { margin-block-end: -0.5em !important; word-spacing : 1px; text-align : initial; animation : fadein 1s; line-height : 1.7; font-size : 18px; border-left-style : solid; border-color : transparent transparent transparent rgb(${providerObject["Aideep"]["color"][0]}); padding : 10 10px; background : rgba(${providerObject["Aideep"]["color"][0]}, ${providerObject["Aideep"]["color"][1]}); margin : 25 0; } .sentence.edit { overflow: hidden; background: none; outline: none; resize: none; margin-block-end: -0.5em !important; word-spacing: 1px; text-align: initial; animation: fadein 0.5s; line-height: 1.7; font-size: 18px; border-left-style: solid; padding: 10 20px; margin: 25 0; background-color: var(--background-color); box-shadow: 0 10px 10px 0 rgba(0, 0, 0, 0.1), 0 0 1px 0 rgba(0, 0, 0, 0.2); color: var(--title-color); border-radius: 13px; border-left-color: var(--checked-background); } .original { display : inline; word-spacing : 1px; text-align : initial; font-weight : 600; font-size : 19px; /*margin-bottom : 3.8em;*/ color : var(--checked-background); } .highlighter { font-weight : 500; /*animation : fadein 1s;*/ } `; let CSSTooltip = ` .tooltip { position : relative; display : inline; } .tooltip .tooltip-text { visibility : hidden; width : 120px; background-color : #555; color : #fff; text-align : center; /* border-radius : 6px; */ padding : 3px 0; position : absolute; z-index : 1; opacity : 0; transition : opacity 0.3s; } /* Tooltip top content */ .top .tooltip-text { bottom : 100%; left : 50%; margin-left : -60px; /* 120/2 = 60 */ } .tooltip .tooltip-text::after { content : ""; position : absolute; border-width : 5px; border-style : solid; } /* Tooltip top arrow */ .top .tooltip-text::after { margin-left : -5px; left : 50%; top : 100%; border-color : var(--checked-background) transparent transparent transparent; } .tooltip:hover .tooltip-text { visibility : visible; opacity : 1; } .highlighter-default { /* animation : fadein 1s; */ /* font-weight : 600; */ } `; let CSSNextPrevArrow = ` .arrow { position : fixed; top : 90%; width : 4vmin; height : 4vmin; background : transparent; border-top : 1vmin solid gray; border-right : 1vmin solid black; box-shadow : 0 0 0 black; transition : all 200ms ease; opacity : 0.4; } .arrow.left { cursor : pointer; /* left : 55px; */ right : 3%; top : 88%; transform : translate3d(0, -50%, 0) rotate(-135deg); } .arrow.right { cursor : pointer; right : 4%; top : 78%; transform : translate3d(0,-50%,0) rotate(45deg); } .arrow:hover { border-color : #2d3436; box-shadow : 0.5vmin -0.5vmin 0 white; opacity : 1; } .arrow: before { content : ''; position : absolute; top : 50%; left : 50%; transform : translate(-40%,-60%) rotate(45deg); width : 200%; height : 200%; } `; let CSSCloseBtn = ` .close-button { box-shadow : rgba(0, 0, 0, 0.4) 0px 8px 16px 0px; width : 5vmin; height : 5vmin; box-shadow : 0px 10 10px 10px rgba(0, 0, 0, 0.25); border-radius : 50%; background : var(--close-btn-back-color); position : fixed; right : 3.6%; top : 67%; display : block; z-index : 200; text-indent : -9999px; cursor : pointer; } .close-button:before, .close-button:after { content : ''; width : 55%; height : 2px; background : var(--close-btn-fore-color); position : absolute; top : 48%; left : 22%; -webkit-transform : rotate(-45deg); -moz-transform : rotate(-45deg); -ms-transform : rotate(-45deg); -o-transform : rotate(-45deg); transform : rotate(-45deg); -webkit-transition: all 0.3s ease-out; -moz-transition : all 0.3s ease-out; -ms-transition : all 0.3s ease-out; -o-transition : all 0.3s ease-out; transition : all 0.3s ease-out; } .close-button:after { -webkit-transform : rotate(45deg); -moz-transform : rotate(45deg); -ms-transform : rotate(45deg); -o-transform : rotate(45deg); transform : rotate(45deg); -webkit-transition: all 0.3s ease-out; -moz-transition : all 0.3s ease-out; -ms-transition : all 0.3s ease-out; -o-transition : all 0.3s ease-out; transition : all 0.3s ease-out; } .close-button:hover:before, .close-button:hover:after { -webkit-transform: rotate(180deg); -moz-transform : rotate(180deg); -ms-transform : rotate(180deg); -o-transform : rotate(180deg); transform : rotate(180deg); } `; let CSSBtnTheme = ` .fa, .fab, .fal, .far, .fas { line-height: 0; } ul { animation: fadein 2s; padding: 0; position: relative; margin: 0 0 100 0; transform: scale(0.65); justify-content: start; display: inline-block; flex-direction: row; flex-wrap: nowrap; /* justify-content: end; */ align-items: unsafe; /* align-content: end; */ margin: 0 -5vmin; /* margin: 0 500px; */ /* margin-bottom: 7.8em !important; */ padding-inline-start: 0px !important; display: inline-flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: baseline; align-content: stretch; } ul li { animation : fadein 1s; list-style : none; margin : 0 7px; display : block; } ul li:after, .rr-font--update.rr-inc:after { pointer-events: none; content: ""; position: absolute; top: -140px; bottom: -230px; right: 0; z-index: 10; /* padding-left: 320; */ border-right: 1.0px solid rgba(var(--checked-background-rgb), 0.3); transform: rotate(30deg); } ul li a { position : relative; display : list-item; width : 60px; height : 60px; text-align : center; line-height : 63px; background : var(--background-color); border-radius: 50%; font-size : 35px; color : darkgray; transition : .5s; } ul li a:hover { cursor : pointer; } ul li a::before { content : ''; position : absolute; top : 0; left : 0; width : 100%; height : 100%; border-radius: 50%; background : #009992; transition : .5s; transform : scale(.9); z-index : -1; } ul li a:hover { color : black; } ul li a:hover::before { transform : scale(1.1); background: #009992; } ul li:nth-child(1) a::before { background: #ffee10; } ul li:nth-child(1) a:hover::before { box-shadow: 0 0 10px #e67e22; } ul li:nth-child(1) a:hover { box-shadow : 0 0 5px #e67e22; text-shadow: 0 0 5px #e67e22; } ul li:nth-child(2) a::before { background: #95a5a6; } ul li:nth-child(2) a:hover::before { box-shadow: 0 0 10px #9b59b6; } ul li:nth-child(2) a:hover { box-shadow : 0 0 5px #9b59b6; text-shadow: 0 0 5px #9b59b6; } ul li:nth-child(3) a::before { background: #e74c3c; } ul li:nth-child(3) a:hover::before { box-shadow: 0 0 10px #e74c3c; } ul li:nth-child(3) a:hover { box-shadow : 0 0 5px #e74c3c; text-shadow: 0 0 5px #e74c3c; } ul li:nth-child(4) a:hover::before { box-shadow: 0 0 10px #029992; } ul li:nth-child(4) a:hover { box-shadow : 0 0 5px #029992; text-shadow: 0 0 5px #029992; } /*ul li a { color: transparent; }*/ `; let CSSTagBtn = ` .settings-container { animation: fadein 3s; overflow: hidden; border-bottom: 1px solid rgba(var(--checked-background-rgb), 0.3); margin-bottom: 150px; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: flex-start; align-items: center; align-content: stretch; } .raw-block { /* margin-bottom: 4.8em; */ margin: 16px 0; /* display: -webkit-box; */ align-items: center; margin-bottom: 4.5em; } .tag-num { user-select : none; font-size : 10px; line-height : 18px; position : relative; display : inline-flex; height : 18px; padding : 0 6px; letter-spacing: .25px; color : black; border-radius : 18px; background : #c0c2cc; margin : 0 7px; } .tag-num:hover { cursor : pointer; transition : all 400ms ease; background : black; color : white; } .rr-font--update.rr-dec { font-size: 15px; margin-left: 30px; } .rr-font--update.rr-inc { font-size: 22px; margin-right: 20px; position: relative; margin-left: 15px; } .rr-font--update.rr-inc:hover { /*transform: scale(1.3);*/ color: var(--checked-background); transition: all 0.3s ease-out; } .rr-font--update.rr-dec:hover { color: var(--checked-background); transition: all 0.3s ease-out; } .rr-font--update { user-select : none; color : darkgray; font-family : Open sans; width : 30px; font-weight : 700; font-size : 18px; cursor : pointer; } .btn-custom { font-family: "Source sans Pro"; outline: 0; border-radius: 16px; border: 1px solid var(--checked-background); background: transparent; color: var(--checked-background); width: 120px; height: 24px; cursor: pointer; text-transform: uppercase; margin-left: 30px; } .btn-custom:hover { transition: background 0.3s ease-in-out; background: white; } #font-indicator { color: var(--checked-background); font-family: Source sans pro; font-weight: 600; } .sentence.or,[class^="default"] { font-size: ${fontSizeValue}; } [class^="sentence"]:not(.or) { font-weight: 300; font-size: ${fontSizeValueDefault}; } `; /* | Plugin Mobile support. */ let CSSMediaQuery = ` @media only screen and (max-width: 600px) { label { display: inline-block; font-size: 95%; } .radio-group, .checkbox-group { display: grid; } .chapterBody { margin: 7%;max-width: 82%; } .sentence.or { font-size: 92%; text-align: initial; font-weight: 300; } .settingsForm { flex-wrap: wrap; display: contents; } .original { font-size: 87%; text-align: initial; font-weight: 500; } .sentence.google { font-size: 87%; text-align: initial; font-weight: 300; } .sentence.google.default { font-size: 92%; text-align: initial; font-weight: 300; } .sentence.niutrans { font-size: 87%; text-align: initial; font-weight: 300;} .sentence.niutrans.default { font-size: 92%; text-align: initial; font-weight: 300; } .sentence.aideep { font-size: 87%; text-align: initial; font-weight: 300; } .sentence.aideep.default { font-size: 92%; text-align: initial; font-weight: 300; } .sentence.alibaba { font-size: 87%; text-align: initial; font-weight: 300; } .sentence.alibaba.default { font-size: 92%; text-align: initial; font-weight: 300; } .sentence.deepl { font-size: 87%; text-align: initial; font-weight: 300; } .sentence.deepl.default { font-size: 92%; text-align: initial; font-weight: 300; } .close-button { max-width: 7vmin; max-height: 7vmin; min-width: 7vmin; min-height: 7vmin; right: 3%; top: 57%; background: #393A3D; border-radius: 50%; } .close-button:before, .close-button:after { background:white; } .arrow.left { top: 76%; } .arrow.right { top: 68%; right: 5%; } .tooltip { display: inline; } h1.header-title { font-size: 150% } .rr-font--update.rr-dec { font-size: 15px !important; margin-left: 35px !important; } .rr-font--update.rr-inc { margin-right: 15px !important; margin-left: 5px !important; } .btn-custom { height: 54px !important; text-align: center !important;} ul li { margin: 0 12px 4 !important; } ul li:after, .rr-font--update.rr-inc:after { border-right: 2px solid rgba(var(--checked-background-rgb), 1); } ul { animation:fadein 2s;padding:0!important;position:relative!important;margin:0 0 100!important;transform:scale(.65)!important;justify-content:center!important;display:flex!important;flex-direction:row!important;align-items:unsafe!important;margin:0 -10vm!important;margin:0 -10vmin!important;flex-wrap:wrap!important;justify-content:space-evenly!important;align-items:baseline!important;align-content:center!important} } `; window.onload = async function () { /* | Adding Glossary support */ await new Promise((resolve) => setTimeout(resolve, 10)); if ( $('style[type="text/css"]').text().includes("noWordWrapping") && !( window.sessionStorage.getItem("userjs_UGMTLComplete") && window.sessionStorage.getItem("userjs_UGMTLComplete") > window.performance.timing.fetchStart ) ) { await new Promise((resolve) => document.addEventListener("userjs_UGMTLComplete", resolve) ); } else { /* | Swaping Chinese/English words to have a better translation. */ mainBodyWordsReplacer(); } /* | Inject the iframe to the DOM. */ $("#app") .get(0) .insertAdjacentHTML( "afterEnd", `<iframe id="pageContainer" style="display:${ autoReaderState ? "block" : "none" }">` ); /* | Get raw & original text from main page. */ const originalSentences = $(".chapter-body") .find(".translated") .text() .replace(/(\xAD)/g, "") .trim() .split("\n"); const originalRaw = $(".chapter-body") .find(".original") .text() .trim() .split("\n"); const chapterTitle = $(".chapter-title")[0].textContent; /* | Add a button for the reader mode. */ $(".js-toggle-original").after( '<button class="btn btn-enabled reader-mode">READER MODE</button>' ); $(".btn.btn-enabled.reader-mode").css( "boxShadow", "rgb(236, 240, 241) 0px 0px 8px" ); $(".btn.btn-enabled.reader-mode").css("color", "black"); /* | Reader btn onClick event. */ $(".reader-mode").click(function () { $("#app").css({ display: "none", opacity: "0" }); $("#pageContainer").show(); }); /* | We will need this for the tooltip & highlighting words. | The values produces non-ut8 characters so we must remove them | so that there will be no problem replacing them using regex. */ $(".translated t").each(function (index) { let chineseValue = $(this).attr("data-title"); let value = $(this).attr("data-title", $(this).text()).text().trimLeft(); const replacedValue = value.replace( /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/(\xAD)]/g, "" ); if (replacedValue != "" || replacedValue.length != 0) uniqueWords.set(replacedValue, chineseValue); }); /* | This what will be using to control the iframe DOM */ iframeHandler = $("#pageContainer").contents(); /* | Toggle theme state. */ autoThemeState ? iframeHandler.find(":root").eq(0).attr("data-theme", "light") : iframeHandler.find(":root").eq(0).attr("data-theme", "dark"); /* | Append the needed styles for the iframe. */ addStyles(); /* | Add iframe form. */ addForm(); /* | Apply secondary theme. */ iframeHandler.find(":root").eq(0).attr("data-sec-theme", secondaryTheme); /* | Toggle secondary colors. */ iframeHandler.find(".drag").click(function () { iframeHandler.find(":root").eq(0).attr("data-sec-theme", "gold"); GM_SuperValue.set("secondaryTheme", "gold"); }); iframeHandler.find(".moon").click(function () { iframeHandler.find(":root").eq(0).attr("data-sec-theme", "moon"); GM_SuperValue.set("secondaryTheme", "moon"); }); iframeHandler.find(".bomb").click(function () { iframeHandler.find(":root").eq(0).attr("data-sec-theme", "bomb"); GM_SuperValue.set("secondaryTheme", "bomb"); }); iframeHandler.find(".norm").click(function () { iframeHandler.find(":root").eq(0).attr("data-sec-theme", "default"); GM_SuperValue.set("secondaryTheme", ""); }); /* | If one provider is running then removed color/border translation identifier. */ iframeHandler.find("input[name='items[]']").change(function (e) { onlyOneRunning(); }); for (let index in providers) { let provider = providers[index]; if (eval("provider" + provider + "State")) { providerSelector( originalRaw, provider.toLowerCase(), providerObject[provider]["maxSize"] ); } } iframeHandler.find(".close-button").click(function () { $("#app").css({ display: "block", opacity: "1", "overflow-y": "scroll" }); $("#pageContainer").hide(); }); /* | Hooking next/prev page on click | Replacing href results a bug, so I'll be using this approach. */ iframeHandler.find(".arrow.right").click(function () { window.location.assign($(this).attr("value")); }); iframeHandler.find(".arrow.left").click(function () { window.location.assign($(this).attr("value")); }); /* | Add original and raw text ( with display:none ) | Also there is a non-utf8 coming out of nowhere so we must clean that */ for (let i in originalSentences) { for (const [key, value] of uniqueWords.entries()) { originalSentences[i] = originalSentences[i].replace( new RegExp("(?<![<>])(" + key + ")(?![<>])", "g"), `<span class="highlighter">$&</span>` ); } iframeHandler .find(".chapterBody") .append(`<div class="sentence or">${originalSentences[i]}</div>`); iframeHandler .find(".chapterBody") .append( `<div class="raw-block"><p class="original">${originalRaw[i]}</p><a class="tag-num">${i}</a></div>` ); } if (!autoRawState) iframeHandler.find(".raw-block").hide(); if (!providerOriginalState) iframeHandler.find(".sentence.or").hide(); // Should be optimized... iframeHandler.find(".rr-dec").click(function () { let currentFontSize = parseInt( iframeHandler.find('.sentence.or,[class^="default"]').css("font-size") ) - 1; let currentFontSizeDefault = parseInt( iframeHandler .find('[class^="sentence"]:not(.or,.default)') .css("font-size") ) - 1; if (currentFontSize <= 17) return; iframeHandler .find('[class^="sentence"]:not(.or)') .css("font-size", currentFontSizeDefault); iframeHandler .find('.sentence.or,[class^="default"]') .css("font-size", currentFontSize); iframeHandler.find("#font-indicator").text(currentFontSize); GM_SuperValue.set("fontSizeValueDefault", currentFontSizeDefault); GM_SuperValue.set("fontSizeValue", currentFontSize); }); iframeHandler.find(".rr-inc").click(function () { let currentFontSize = parseInt( iframeHandler.find('.sentence.or,[class^="default"]').css("font-size") ) + 1; let currentFontSizeDefault = parseInt( iframeHandler .find('[class^="sentence"]:not(.or,.default)') .css("font-size") ) + 1; if (currentFontSize >= 30) return; iframeHandler .find('[class^="sentence"]:not(.or)') .css("font-size", currentFontSizeDefault); iframeHandler.find(".sentence.or").css("font-size", currentFontSize); iframeHandler.find("#font-indicator").text(currentFontSize); GM_SuperValue.set("fontSizeValueDefault", currentFontSizeDefault); GM_SuperValue.set("fontSizeValue", currentFontSize); }); providerChangedEvent(originalRaw); settingsChangedEvent(); iframeHandler.find(".btn-custom").on("click", function () { let self = $(this); let stringBuilder = `${chapterTitle}\n\n\n`; self.text("Copied ;-)"); setTimeout(function () { self.text("Copy Edited Text"); }, 600); let rawEdits = iframeHandler .find(".sentence.edit") .toArray() .map((p) => p.textContent); for (let index in rawEdits) { stringBuilder += `${rawEdits[index]}\n\n\n`; } window.navigator.clipboard.writeText(stringBuilder); }); iframeHandler.find(".tag-num").on("click", function () { let index = parseInt(this.textContent); if ($(this).attr("value")) { iframeHandler .find(".tag-num") .eq(index) .next() .filter(".sentence.edit") .fadeToggle(200); return; } iframeHandler .find(".raw-block") .eq(index) .append( '<div class="sentence edit" contenteditable="plaintext-only" spellcheck="false"/>' ); $(this).attr("value", "clicked"); }); }; function addStyles() { iframeHandler.find("head").append( $( ` <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="preload" onload="this.rel = 'stylesheet'" as="style" href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600|Poppins|Source+Sans+Pro:300,400,500,600'> <link rel="preload" onload="this.rel = 'stylesheet'" as="style" href='https://use.fontawesome.com/releases/v5.6.3/css/all.css'> ${ $(".next > a").attr("href") != undefined ? `<link rel="prefetch" href="${$(".next > a").attr( "href" )}">` : "" } <style type='text/css'> ${CSSRoot} ${CSSContainer} ${CSSCloseBtn} ${CSSForm} ${CSSChapterBody} ${CSSTooltip} ${CSSNextPrevArrow} ${CSSMediaQuery} ${CSSBtnTheme} ${CSSTagBtn} </style> ` ) ); } function addForm() { const chapterTitle = $(".chapter-title")[0].textContent.split(":"); const readerState = autoReaderState ? "" : "checked"; const themeState = autoThemeState ? "" : "checked"; const rawState = autoRawState ? "" : "checked"; const pageNext = $(".next > a").attr("href"); const pagePrevious = $(".previous > a").attr("href"); const nextChapterButton = pageNext != null ? '<a value="' + pageNext + '" class="arrow right"></a>' : ""; const prevChapterButton = pagePrevious != null ? '<a value="' + pagePrevious + '" class="arrow left"></a>' : ""; const isOriginalEnabled = providerOriginalState ? "checked" : ""; const isGoogleEnabled = providerGoogleState ? "checked" : ""; const isAlibabaEnabled = providerAlibabaState ? "checked" : ""; const isNiutransEnabled = providerNiutransState ? "checked" : ""; const isAideepEnabled = providerAideepState ? "checked" : ""; const isDeeplEnabled = providerDeeplState ? "checked" : ""; iframeHandler.find("body").append( ` <div id="clean-reader"> <div class="pageContainerBackground"> <a class="close-button">Close</a> ${prevChapterButton} ${nextChapterButton} <form class="settingsForm"> <label>Provider</label> <div class="radio-group"> <input type="checkbox" id="Original-translator" value="o-translator-p" name="items[]" ${isOriginalEnabled}> <label for="Original-translator">Original</label> <input type="checkbox" id="Google-translator" value="g-translator-p" name="items[]" ${isGoogleEnabled}> <label for="Google-translator"><span style="color:rgb(${ providerObject["Google"]["color"][0] });text-shadow: 0 0 3px #30AFDB, 0 0 5px #30AFDB;padding-right: 6">◼ </span> Google</label> <input type="checkbox" id="Alibaba-translator" value="s-translator-p" name="items[]" ${isAlibabaEnabled}> <label for="Alibaba-translator"><span style="color:rgb(${ providerObject["Alibaba"]["color"][0] });text-shadow: 0 0 3px #e74c3c, 0 0 5px #e74c3c;padding-right: 6">◼ </span> Alibaba</label> <input type="checkbox" id="Niutrans-translator" value="n-translator-p" name="items[]" ${isNiutransEnabled}> <label for="Niutrans-translator"><span style="color:rgb(${ providerObject["Niutrans"]["color"][0] });text-shadow: 0 0 3px #e74c3c, 0 0 5px #e74c3c;padding-right: 6">◼ </span> Niutrans</label> <input type="checkbox" id="Aideep-translator" value="b-translator-p" name="items[]" ${isAideepEnabled}> <label for="Aideep-translator"><span style="color:rgb(${ providerObject["Aideep"]["color"][0] });text-shadow: 0 0 3px #6F68F2, 0 0 5px #6F68F2;padding-right: 6">◼ </span> Aideep</label> <input type="checkbox" id="Deepl-translator" value="y-translator-p" name="items[]" ${isDeeplEnabled}> <label for="Deepl-translator"><span style="color:rgb(${ providerObject["Deepl"]["color"][0] });text-shadow: 0 0 3px #34495e, 0 0 5px #34495e;padding-right: 6">◼ </span> Deepl</label> </div> <label>Raw</label> <div class="radio-group"> <input type="radio" id="option-one-a" name="raw" value="mode-enabled" checked> <label for="option-one-a">Enable</label> <input type="radio" id="option-two-2" name="raw" value="mode-disabled" ${rawState}> <label for="option-two-2">Disable</label> </div> <label>Reader</label> <div class="radio-group"> <input type="radio" id="option-1" name="mode" value="mode-enabled" data-theme="dark" checked> <label for="option-1">Always</label> <input type="radio" id="option-2" name="mode" value="mode-disabled" data-theme="light" ${readerState}> <label for="option-2">Never</label> </div> <label>Theme</label> <div class="radio-group theme"> <input type="radio" id="option-1-1" name="theme" value="theme-enabled" checked> <label for="option-1-1">Light</label> <input type="radio" id="option-2-2" name="theme" value="theme-disabled" ${themeState}> <label for="option-2-2">Dark</label> </div> </form> <h1 class="header-title">${ chapterTitle[1] } - <span style="transition : all 200ms ease;color:var(--checked-background);font-weight:bold">${chapterTitle[0].replace( "#", "" )}</h1> <div class="pageSplit"></div> <div class="settings-container"> <ul> <li> <a class="drag"><i class="fab fa-d-and-d"></i></a> </li> <li> <a class="moon"><i class="fas fa-bowling-ball"></i></a> </li> <li> <a class="bomb"><i class="fas fa-bomb"></i></a> </li> <li> <a class="norm"><i class="fas fa-tint"></i> </a> </li> </ul><span class="rr-font--update rr-dec">A-</span><div id="font-indicator">${fontSizeValue}</div><span class="rr-font--update rr-inc">A+</span> <button class="btn-custom">Copy edited text</button></div> <div class="chapterBody"> </div> </div> </div> ` ); } function providerChangedEvent(raws) { const addEventHandler = (iframe, provider) => { const capitalizeProvider = provider.charAt(0).toUpperCase() + provider.slice(1); iframe.find(`#${capitalizeProvider}-translator`).change(function () { GM_SuperValue.set(`provider${capitalizeProvider}State`, this.checked); this.checked && !isTranslated[capitalizeProvider][1] ? providerSelector( raws, provider, providerObject[capitalizeProvider]["maxSize"] ) : iframe.find(`.sentence.${provider}`).fadeToggle(300); }); }; addEventHandler(iframeHandler, "google"); addEventHandler(iframeHandler, "alibaba"); addEventHandler(iframeHandler, "niutrans"); addEventHandler(iframeHandler, "Aideep"); addEventHandler(iframeHandler, "deepl"); iframeHandler.find("#Original-translator").change(function () { GM_SuperValue.set("providerOriginalState", this.checked); iframeHandler.find(".sentence.or").delay(100).fadeToggle(100); }); } function settingsChangedEvent() { /* READER CHANGING STATE */ iframeHandler.find("input[type=radio][name=mode]").change(function () { autoReaderState = $(this).val().includes("enabled"); GM_SuperValue.set("autoReaderState", autoReaderState); }); /* RAW CHANGING STATE */ iframeHandler.find("input[type=radio][name=raw]").click(function () { autoRawState = $(this).val().includes("enabled"); GM_SuperValue.set("autoRawState", autoRawState); autoRawState ? iframeHandler.find(".raw-block").delay(100).fadeIn(300) : iframeHandler.find(".raw-block").fadeOut(200); }); /* THEME CHANGING STATE */ iframeHandler.find("input[type=radio][name=theme]").click(function () { autoThemeState = $(this).val().includes("enabled"); GM_SuperValue.set("autoThemeState", autoThemeState); autoThemeState ? iframeHandler.find(":root").eq(0).attr("data-theme", "light") : iframeHandler.find(":root").eq(0).attr("data-theme", "dark"); }); } function onlyOneRunning() { let runningProviders = []; iframeHandler.find("input[name='items[]']:checked").each(function () { runningProviders.push( $(this).attr("id").replace("-translator", "").toLowerCase() ); }); if (runningProviders.length == 1) { iframeHandler .find(`.sentence.${runningProviders[0]}`) .attr("class", `sentence ${runningProviders[0]} default`); iframeHandler.find(".highlighter-default").css("font-weight", "500"); } else { for (let id in runningProviders) { iframeHandler .find(`.sentence.${runningProviders[id]}.default`) .attr("class", `sentence ${runningProviders[id]}`); iframeHandler.find(".highlighter-default").css("font-weight", "500"); } } return runningProviders.length; } const disableCheckbox = (elementId, status) => iframeHandler.find(elementId).prop("disabled", status); async function providerSelector(raw, name, chunksize) { const taskDelay = (m) => new Promise((r) => setTimeout(r, m)); let translatedChunks = []; let chunks = []; chunks = separateIntoChunks(raw, chunksize); chunks[0] = chunks[0].trimLeft(); console.log(name); switch (name) { case "alibaba": { disableCheckbox("#Alibaba-translator", true); for (let id in chunks) { translatedChunks[id] = await alibabaTranslator(chunks[id]); console.log("test_2"); await taskDelay(providerObject["Alibaba"]["timeout"]); } // Translation is finished. isTranslated["Alibaba"][1] = true; disableCheckbox("#Alibaba-translator", false); } break; case "google": { disableCheckbox("#Google-translator", true); for (let id in chunks) { translatedChunks[id] = await googleTranslator(chunks[id]); await taskDelay(providerObject["Google"]["timeout"]); } // Translation is finished. isTranslated["Google"][1] = true; disableCheckbox("#Google-translator", false); } break; case "niutrans": { disableCheckbox("#Niutrans-translator", true); let query = await niutransGetQuery(); for (let id in chunks) { translatedChunks[id] = await niutransTranslator(chunks[id], query); await taskDelay(providerObject["Niutrans"]["timeout"]); } // Translation is finished. isTranslated["Niutrans"][1] = true; disableCheckbox("#Niutrans-translator", false); } break; case "aideep": { console.log('case ai deep'); disableCheckbox("#Aideep-translator", true); let timer = -performance.now(); //const tokens = await AideepReceiveTokens(); for (let id in chunks) { translatedChunks[id] = await AideepTranslator_2(chunks[id]); await taskDelay(providerObject["Aideep"]["timeout"]); } timer += performance.now(); console.log("Time: " + (timer / 1000).toFixed(5) + " sec."); // Translation is finished. isTranslated["Aideep"][1] = true; disableCheckbox("#Aideep-translator", false); } break; case "deepl": { console.log('case deepl'); disableCheckbox("#Deepl-translator", true); for (let id in chunks) { translatedChunks[id] = await deeplTranslator(chunks[id]); await taskDelay(providerObject["Deepl"]["timeout"]); } // Translation is finished. isTranslated["Deepl"][1] = true; disableCheckbox("#Deepl-translator", false); } break; } let finalResult = seperateChunksIntoPars(translatedChunks); createSentence(finalResult, name, onlyOneRunning()); } function mainBodyWordsReplacer() { $(".original t").each(function () { const textSpace = $(this).get(0).previousSibling.nodeName == "T" ? " " : ""; const textValue = $(this).text(); $(this).text(textSpace + $(this).attr("data-title")); $(this).attr("data-title", textValue); }); } function createSentence(paragraphs, provider, runningProviders) { if (runningProviders == 1) { provider.concat(" default"); } paragraphs.forEach((sentence, index) => { for (const [key, value] of uniqueWords.entries()) sentence = sentence.replace( new RegExp("(?<![<>])(" + key + ")(?![<>])", "g"), `<span class="highlighter-default">$&</span>` ); iframeHandler .find(".raw-block") .eq(index) .before(`<p class="sentence ${provider}">` + sentence + "</p>"); }); onlyOneRunning(); } function googleTranslator(text) { return new Promise((resolve) => $.ajax( "https://translate.googleapis.com/translate_a/single?client=gtx&sl=zh-CN&tl=en&dt=t", { method: "POST", data: { q: text }, dataType: "json", } ) .done((t) => { let paragraph = ""; for (let i = 0; i < t[0].length; i++) { paragraph += t[0][i][0]; } resolve(paragraph); }) .fail(function (xhr, textStatus, errorThrown) { GM_SuperValue.set("providerGoogleState", false); disableCheckbox("#Google-translator", false); iframeHandler.find("#Google-translator").prop("checked", false); }) ); } function alibabaTranslator(text) { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://translate.alibaba.com/translationopenseviceapp/trans/TranslateTextAddAlignment.do?srcLanguage=zh&tgtLanguage=en&bizType=general&srcText=" + encodeURI(text), headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/74.0.3729.169 Safari/537.36", }, onload: function (result) { try { resolve(JSON.parse(result.response).listTargetText[0]); } catch (error) { GM_SuperValue.set("providerAlibabaState", false); disableCheckbox("#Alibaba-translator", false); iframeHandler.find("#Alibaba-translator").prop("checked", false); } }, }); }); } function niutransGetUrlHash() { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://niutrans.com/Trans?type=text", headers: { accept: "application/json, text/plain, */*" }, onload: function (result) { try { var webpackHash = /js\/app\.(.*)\.js/g.exec(result.response); resolve(webpackHash[1]); } catch (error) { console.log(error); } }, }); }); } async function niutransGetQuery() { let hash = await niutransGetUrlHash(); return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://niutrans.com/static/js/app." + hash + ".js", headers: { accept: "application/json, text/plain, */*" }, onload: function (result) { try { var webpackHash = /testtrans\?query=(.*?)"/g.exec(result.response); resolve(webpackHash[1]); } catch (error) { console.log(error); } }, }); }); } function niutransTranslator(text, query) { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://test.niutrans.com/NiuTransServer/testtrans?query=" + query + "&from=cht&to=en&src_text=" + encodeURIComponent(text) + "&source=text", headers: { accept: "application/json, text/plain, */*", "accept-language": "en-US,en;q=0.9,tr-TR;q=0.8,tr;q=0.7,zh-TW;q=0.6,zh;q=0.5", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site", }, onload: function (result) { try { var myResponse = JSON.parse(result.response).tgt_text; var t = [...myResponse.split("\n \n")].join("\n\n"); resolve(t); } catch (error) { console.log(error); GM_SuperValue.set("providerNiutransState", false); disableCheckbox("#Niutrans-translator", false); iframeHandler.find("#Niutrans-translator").prop("checked", false); } }, }); }); } async function AideepTranslator_2(text) { console.log('aideeeeeeep'); var timestamp = Date.now(); const formData = { source: "zh", target: "en", text: text, mark: timestamp, verify: md5(md5(text) + timestamp + "fpoTYKWlvhwhVaFG") }; return new Promise((resolve) => { GM_xmlhttpRequest({ method: 'POST', url: 'https://www.kingsoftai-fanyi.com/aida_api/text/translate', data: JSON.stringify(formData), headers: { 'Content-Type': 'application/json', 'Host': 'www.kingsoftai-fanyi.com', 'Origin': 'https://www.kingsoftai-fanyi.com', 'Referer': 'https://www.kingsoftai-fanyi.com/translate', 'User-Agent': 'Mozilla/5.0 (Windows NT 8.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98 Safari/537.36' }, onload: (result) => { try { const cleanedResult = Array.from(JSON.parse(result.responseText).data.translateTexts.map(p => p.translation))[0].split("\n \n").join("\n\n"); resolve(cleanedResult); } catch (error) { //console.log('error\n'); GM_SuperValue.set("providerAIDeepState", false); disableCheckbox("#AIDeep-translator", false); iframeHandler.find("#AIDeep-translator").prop("checked", false); } } }) }) } async function AideepTranslator(text, _tokens) { const formData = { from: "zh", to: "en", query: text, transtype: "realtime", simple_means_flag: 3, sign: sign(text, _tokens[0]), token: _tokens[1], domain: "common", }; return new Promise((resolve) => { GM_xmlhttpRequest({ method: "POST", url: "https://fanyi.Aideep.com/v2transapi", data: $.param(formData), headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Accept: "application/json", Referer: "https://fanyi.Aideep.com", "Accept-Encoding": "gzip, deflate", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", }, onload: function (result) { try { const jsonObj = JSON.parse(result.responseText); resolve(jsonObj.trans_result.data.map((p) => p.dst).join("\n\n")); } catch (error) { GM_SuperValue.set("providerAideepState", false); disableCheckbox("#Aideep-translator", false); iframeHandler.find("#Aideep-translator").prop("checked", false); } }, }); }); } function AideepReceiveTokens() { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://fanyi.Aideep.com/", headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", }, onload: function (result) { try { const windowToken = result.responseText.match( /window\.gtk = '(.*?)'/ )[1]; const commonToken = result.responseText.match(/token: '(.*?)',/)[1]; resolve([windowToken, commonToken]); } catch (error) { disableCheckbox("#Aideep-translator", false); iframeHandler.find("#Aideep-translator").prop("checked", false); } }, }); }); } async function deeplTranslator(text) { console.log('deepl clicked'); return new Promise((resolve) => { GM_xmlhttpRequest({ method: "GET", url: "https://translate.minganci.org/deepl?text=" + encodeURI(text) + "&source_lang=ZH&target_lang=EN", headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36", }, onload: function (result) { try { let jsonObj = JSON.parse(result.response); console.log(jsonObj.translations[0].text); resolve(jsonObj.translations[0].text); } catch (error) { //console.log(error); GM_SuperValue.set("providerDeeplState", false); disableCheckbox("#Deepl-translator", false); iframeHandler.find("#Deepl-translator").prop("checked", false); } }, }); }); } /* | Utilities */ function setCookie(a, val, url, c, name) { return ( (a = [a, "=", val]), url && a.push(";expires=", url), c && a.push(";domain=", c), name && a.push(";path=", name), (document.cookie = a.join("")), a.join("") ); } function separateIntoChunks(paragraphs, size) { let chunks = []; let currentchunk = ""; for (let i = 0; i < paragraphs.length; i++) { if ((currentchunk + paragraphs[i]).length >= size) { chunks.push(currentchunk); currentchunk = paragraphs[i]; } else { currentchunk = currentchunk + "\n\n" + paragraphs[i]; } } if (paragraphs.length != 0) { chunks.push(currentchunk); } return chunks; } function seperateChunksIntoPars(chunks, splitby = "\n\n") { let pars = []; chunks.forEach((chunk) => chunk.split(splitby).forEach((par) => pars.push(par)) ); return pars; } function a(r) { if (Array.isArray(r)) { for (var o = 0, t = Array(r.length); o < r.length; o++) t[o] = r[o]; return t; } return Array.from(r); } function n(a, o) { var s = 0; for (; s < o.length - 2; s = s + 3) { var d = o.charAt(s + 2); d = d >= "a" ? d.charCodeAt(0) - 87 : Number(d); d = "+" === o.charAt(s + 1) ? a >>> d : a << d; a = "+" === o.charAt(s) ? (a + d) & 4294967295 : a ^ d; } return a; } function sign(r, gtk = 0) { var i = null; var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); if (null === o) { var t = r.length; t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10)); } else { for ( var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++ ) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]); var g = f.length; g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join("")); } var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); u = null !== i ? i : (i = gtk || "") || ""; for ( var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++ ) { var A = r.charCodeAt(v); 128 > A ? (S[c++] = A) : (2048 > A ? (S[c++] = (A >> 6) | 192) : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? ((A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v))), (S[c++] = (A >> 18) | 240), (S[c++] = ((A >> 12) & 63) | 128)) : (S[c++] = (A >> 12) | 224), (S[c++] = ((A >> 6) & 63) | 128)), (S[c++] = (63 & A) | 128)); } for ( var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++ ) (p += S[b]), (p = n(p, F)); return ( (p = n(p, D)), (p ^= s), 0 > p && (p = (2147483647 & p) + 2147483648), (p %= 1e6), p.toString() + "." + (p ^ m) ); } function md5(str) { var k = [], i = 0; for (i = 0; i < 64;) k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); var b, c, d, j, x = [], str2 = unescape(encodeURI(str)), a = str2.length, h = [(b = 1732584193), (c = -271733879), ~b, ~c]; for (i = 0; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << (8 * (i++ % 4)); x[(str = ((a + 8) >> 6) * 16 + 14)] = a * 8; i = 0; for (; i < str; i += 16) { a = h; j = 0; for (; j < 64;) { a = [ (d = a[3]), (b = a[1] | 0) + (((d = a[0] + [ (b & (c = a[2])) | (~b & d), (d & b) | (~d & c), b ^ c ^ d, c ^ (b | ~d), ][(a = j >> 4)] + (k[j] + (x[([j, 5 * j + 1, 3 * j + 5, 7 * j][a] % 16) + i] | 0))) << (a = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21][ 4 * a + (j++ % 4) ])) | (d >>> (32 - a))), b, c, ]; } for (j = 4; j;) { h[--j] = h[j] + a[j]; } } str = ""; for (; j < 32;) { str += ((h[j >> 3] >> ((1 ^ (j++ & 7)) * 4)) & 15).toString(16); } return str; }