2020-10-20 23:25:34 +02:00
/ * *
2021-07-11 18:51:40 +02:00
* @ name Translator
2021-03-05 13:26:41 +01:00
* @ author DevilBro
2020-10-20 23:25:34 +02:00
* @ authorId 278543574059057154
2022-02-11 14:58:40 +01:00
* @ version 2.3 . 4
2021-07-11 18:51:40 +02:00
* @ description Allows you to translate Messages and your outgoing Messages within Discord
2020-10-20 23:25:34 +02:00
* @ invite Jx3TjNS
2020-11-19 16:45:36 +01:00
* @ donate https : //www.paypal.me/MircoWittrien
* @ patreon https : //www.patreon.com/MircoWittrien
2021-03-09 15:10:55 +01:00
* @ website https : //mwittrien.github.io/
2021-07-11 18:51:40 +02:00
* @ source https : //github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/Translator/
* @ updateUrl https : //mwittrien.github.io/BetterDiscordAddons/Plugins/Translator/Translator.plugin.js
2020-10-20 23:25:34 +02:00
* /
2018-10-11 10:21:26 +02:00
2020-09-19 20:49:33 +02:00
module . exports = ( _ => {
2020-10-09 21:09:35 +02:00
const config = {
2020-09-19 20:49:33 +02:00
"info" : {
2021-07-11 18:51:40 +02:00
"name" : "Translator" ,
2020-09-19 20:49:33 +02:00
"author" : "DevilBro" ,
2022-02-11 14:58:40 +01:00
"version" : "2.3.4" ,
2021-07-11 18:51:40 +02:00
"description" : "Allows you to translate Messages and your outgoing Messages within Discord"
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
} ;
2020-10-31 11:43:29 +01:00
2022-01-30 23:49:21 +01:00
return ! window . BDFDB _Global || ( ! window . BDFDB _Global . loaded && ! window . BDFDB _Global . started ) ? class {
2021-01-06 12:38:36 +01:00
getName ( ) { return config . info . name ; }
getAuthor ( ) { return config . info . author ; }
getVersion ( ) { return config . info . version ; }
2021-02-01 17:13:13 +01:00
getDescription ( ) { return ` The Library Plugin needed for ${ config . info . name } is missing. Open the Plugin Settings to download it. \n \n ${ config . info . description } ` ; }
downloadLibrary ( ) {
require ( "request" ) . get ( "https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js" , ( e , r , b ) => {
2021-03-05 13:14:18 +01:00
if ( ! e && b && r . statusCode == 200 ) require ( "fs" ) . writeFile ( require ( "path" ) . join ( BdApi . Plugins . folder , "0BDFDB.plugin.js" ) , b , _ => BdApi . showToast ( "Finished downloading BDFDB Library" , { type : "success" } ) ) ;
2021-03-06 14:59:48 +01:00
else BdApi . alert ( "Error" , "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library" ) ;
2021-02-01 17:13:13 +01:00
} ) ;
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
load ( ) {
2020-11-19 16:51:14 +01:00
if ( ! window . BDFDB _Global || ! Array . isArray ( window . BDFDB _Global . pluginQueue ) ) window . BDFDB _Global = Object . assign ( { } , window . BDFDB _Global , { pluginQueue : [ ] } ) ;
2020-09-19 20:49:33 +02:00
if ( ! window . BDFDB _Global . downloadModal ) {
window . BDFDB _Global . downloadModal = true ;
2021-01-14 16:14:44 +01:00
BdApi . showConfirmationModal ( "Library Missing" , ` The Library Plugin needed for ${ config . info . name } is missing. Please click "Download Now" to install it. ` , {
2020-09-19 20:49:33 +02:00
confirmText : "Download Now" ,
cancelText : "Cancel" ,
onCancel : _ => { delete window . BDFDB _Global . downloadModal ; } ,
2020-09-20 08:15:13 +02:00
onConfirm : _ => {
delete window . BDFDB _Global . downloadModal ;
2021-02-01 17:13:13 +01:00
this . downloadLibrary ( ) ;
2020-09-20 08:15:13 +02:00
}
2020-09-19 20:49:33 +02:00
} ) ;
}
if ( ! window . BDFDB _Global . pluginQueue . includes ( config . info . name ) ) window . BDFDB _Global . pluginQueue . push ( config . info . name ) ;
2020-10-09 21:09:35 +02:00
}
2021-01-06 12:38:36 +01:00
start ( ) { this . load ( ) ; }
stop ( ) { }
getSettingsPanel ( ) {
2020-11-28 23:12:09 +01:00
let template = document . createElement ( "template" ) ;
2021-01-14 16:14:44 +01:00
template . innerHTML = ` <div style="color: var(--header-primary); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${ config . info . name } is missing. \n Please click <a style="font-weight: 500;">Download Now</a> to install it.</div> ` ;
2021-02-01 17:13:13 +01:00
template . content . firstElementChild . querySelector ( "a" ) . addEventListener ( "click" , this . downloadLibrary ) ;
2020-11-28 23:12:09 +01:00
return template . content . firstElementChild ;
}
2020-10-09 21:09:35 +02:00
} : ( ( [ Plugin , BDFDB ] ) => {
2021-03-20 18:50:17 +01:00
var _this ;
2021-01-21 16:15:24 +01:00
const translateIconGeneral = ` <svg name="Translate" width="24" height="24" viewBox="0 0 24 24"><mask/><path fill="currentColor" mask="url(#translateIconMask)" d="M 4 2 C 2.9005593 2 2 2.9005593 2 4 L 2 17 C 2 18.10035 2.9005593 19 4 19 L 11 19 L 12 22 L 20 22 C 21.10035 22 22 21.099441 22 20 L 22 7 C 22 5.9005592 21.099441 5 20 5 L 10.880859 5 L 10 2 L 4 2 z M 11.173828 6 L 20 6 C 20.550175 6 21 6.4498249 21 7 L 21 20 C 21 20.550175 20.550176 21 20 21 L 13 21 L 15 19 L 14.185547 16.236328 L 15.105469 15.314453 L 17.791016 18 L 18.521484 17.269531 L 15.814453 14.583984 C 16.714739 13.54911 17.414914 12.335023 17.730469 11.080078 L 19 11.080078 L 19 10.039062 L 15.365234 10.039062 L 15.365234 9 L 14.324219 9 L 14.324219 10.039062 L 12.365234 10.039062 L 11.173828 6 z M 7.1660156 6.4160156 C 8.2063466 6.4160156 9.1501519 6.7857022 9.9003906 7.4804688 L 9.9648438 7.5449219 L 8.7441406 8.7246094 L 8.6855469 8.6699219 C 8.4009108 8.3998362 7.9053417 8.0859375 7.1660156 8.0859375 C 5.8555986 8.0859375 4.7890625 9.1708897 4.7890625 10.505859 C 4.7890625 11.84083 5.8555986 12.925781 7.1660156 12.925781 C 8.5364516 12.925781 9.1309647 12.050485 9.2910156 11.464844 L 7.0800781 11.464844 L 7.0800781 9.9160156 L 11.03125 9.9160156 L 11.044922 9.984375 C 11.084932 10.194442 11.099609 10.379777 11.099609 10.589844 C 11.094109 12.945139 9.4803883 14.583984 7.1660156 14.583984 C 4.9107525 14.583984 3.0800781 12.749807 3.0800781 10.5 C 3.0800781 8.2501934 4.9162088 6.4160156 7.1660156 6.4160156 z M 12.675781 11.074219 L 16.669922 11.074219 C 16.669922 11.074219 16.330807 12.390095 15.111328 13.810547 C 14.576613 13.195806 14.206233 12.595386 13.970703 12.115234 L 12.980469 12.115234 L 12.675781 11.074219 z M 13.201172 12.884766 C 13.535824 13.484957 13.940482 14.059272 14.390625 14.583984 L 13.855469 15.115234 L 13.201172 12.884766 z"/><extra/></svg> ` ;
const translateIconMask = ` <mask id="translateIconMask" fill="black"><path fill="white" d="M 0 0 H 24 V 24 H 0 Z"/><path fill="black" d="M24 12 H 12 V 24 H 24 Z"/></mask> ` ;
2020-09-19 20:49:33 +02:00
const translateIcon = translateIconGeneral . replace ( ` <extra/> ` , ` ` ) . replace ( ` <mask/> ` , ` ` ) . replace ( ` mask="url(#translateIconMask)" ` , ` ` ) ;
2021-01-21 16:21:08 +01:00
const translateIconUntranslate = translateIconGeneral . replace ( ` <extra/> ` , ` <path fill="none" stroke="#f04747" stroke-width="2" d="m 14.702359,14.702442 8.596228,8.596148 m 0,-8.597139 -8.59722,8.596147 z"/> ` ) . replace ( ` <mask/> ` , translateIconMask ) ;
2021-03-20 18:50:17 +01:00
const TranslateButtonComponent = class TranslateButton extends BdApi . React . Component {
render ( ) {
2021-06-01 16:17:59 +02:00
const enabled = _this . isTranslationEnabled ( this . props . channelId ) ;
2021-03-20 18:50:17 +01:00
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ChannelTextAreaButton , {
2021-07-11 18:51:40 +02:00
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . _translatortranslatebutton , _this . isTranslationEnabled ( this . props . channelId ) && BDFDB . disCN . _translatortranslating , BDFDB . disCN . textareapickerbutton ) ,
2021-03-20 18:50:17 +01:00
isActive : this . props . isActive ,
iconSVG : translateIcon ,
nativeClass : true ,
2021-06-01 16:17:59 +02:00
tooltip : enabled && {
text : ( _ => ` ${ BDFDB . LanguageUtils . getName ( languages [ _this . getLanguageChoice ( languageTypes . INPUT , messageTypes . SENT , this . props . channelId ) ] ) } ➝ ${ BDFDB . LanguageUtils . getName ( languages [ _this . getLanguageChoice ( languageTypes . OUTPUT , messageTypes . SENT , this . props . channelId ) ] ) } ` ) ,
tooltipConfig : { style : "max-width: 400px" }
} ,
2021-03-20 18:50:17 +01:00
onClick : _ => {
this . props . isActive = true ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
BDFDB . ModalUtils . open ( _this , {
2021-05-12 18:41:59 +02:00
size : "LARGE" ,
2021-03-20 18:50:17 +01:00
header : BDFDB . LanguageUtils . LanguageStrings . SETTINGS ,
subHeader : "" ,
onClose : _ => {
this . props . isActive = false ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
} ,
2021-05-25 10:35:29 +02:00
children : BDFDB . ReactUtils . createElement ( TranslateSettingsComponent , {
channelId : this . props . channelId
} )
2021-03-20 18:50:17 +01:00
} ) ;
} ,
onContextMenu : _ => {
2021-05-25 10:35:29 +02:00
_this . toggleTranslation ( this . props . channelId ) ;
2021-03-20 18:50:17 +01:00
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
} ) ;
}
} ;
2021-05-12 18:41:59 +02:00
const TranslateSettingsComponent = class TranslateSettings extends BdApi . React . Component {
2021-06-01 16:17:59 +02:00
filterLanguages ( direction , place ) {
let isOutput = direction == languageTypes . OUTPUT ;
2021-05-12 18:41:59 +02:00
return BDFDB . ObjectUtils . toArray ( BDFDB . ObjectUtils . map ( isOutput ? BDFDB . ObjectUtils . filter ( languages , lang => ! lang . auto ) : languages , ( lang , id ) => ( {
value : id ,
2021-06-01 16:17:59 +02:00
label : BDFDB . LanguageUtils . getName ( lang ) ,
2021-05-12 18:41:59 +02:00
backup : this . isOnlyBackup ( lang )
2021-06-01 16:17:59 +02:00
} ) ) ) . filter ( isOutput && this . isOnlyBackup ( languages [ _this . getLanguageChoice ( languageTypes . INPUT , place , this . props . channelId ) ] ) ? ( n => n . backup ) : ( n => n ) ) ;
2021-05-12 18:41:59 +02:00
}
isOnlyBackup ( lang ) {
2021-07-03 11:43:59 +02:00
return lang && ( lang . auto && ! translationEngines [ _this . settings . engines . translator ] . auto || ! lang . auto && ! lang . special && ! translationEngines [ _this . settings . engines . translator ] . languages . includes ( lang . id ) ) ;
2021-05-12 18:41:59 +02:00
}
2021-03-20 18:50:17 +01:00
render ( ) {
2021-05-12 18:41:59 +02:00
return [
BDFDB . ArrayUtils . is ( _this . settings . exceptions . wordStart ) && _this . settings . exceptions . wordStart . length && [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsLabel , {
label : ` Words starting with ${ _this . settings . exceptions . wordStart . map ( n => '"' + n + '"' ) . join ( ", " ) } will be ignored `
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCN . marginbottom8
2021-03-20 18:50:17 +01:00
} )
2021-05-12 18:41:59 +02:00
] ,
2021-06-01 16:17:59 +02:00
Object . keys ( _this . defaults . choices ) . map ( place => {
const isSpecific = channelLanguages [ this . props . channelId ] && channelLanguages [ this . props . channelId ] [ place ] ;
return Object . keys ( _this . defaults . choices [ place ] . value ) . map ( direction => [
2021-05-12 18:41:59 +02:00
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
2021-06-01 16:17:59 +02:00
title : ` ${ BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( direction . toLowerCase ( ) ) } Language in ${ place . toLowerCase ( ) } Messages: ` ,
titleChildren : direction == languageTypes . OUTPUT && [ {
text : _ => isSpecific ? ` ${ BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( place ) } Language Selection will be changed specifically for this Channel ` : ` ${ BDFDB . LibraryModules . StringUtils . upperCaseFirstChar ( place ) } Language Selection will be changed for all Channels ` ,
name : isSpecific ? BDFDB . LibraryComponents . SvgIcon . Names . LOCK _CLOSED : BDFDB . LibraryComponents . SvgIcon . Names . LOCK _OPEN ,
color : isSpecific && "var(--bdfdb-red)" ,
onClick : _ => {
if ( channelLanguages [ this . props . channelId ] && channelLanguages [ this . props . channelId ] [ place ] ) {
delete channelLanguages [ this . props . channelId ] [ place ] ;
if ( BDFDB . ObjectUtils . isEmpty ( channelLanguages [ this . props . channelId ] ) ) delete channelLanguages [ this . props . channelId ] ;
}
else {
if ( ! channelLanguages [ this . props . channelId ] ) channelLanguages [ this . props . channelId ] = { } ;
channelLanguages [ this . props . channelId ] [ place ] = { } ;
for ( let l in languageTypes ) channelLanguages [ this . props . channelId ] [ place ] [ languageTypes [ l ] ] = _this . getLanguageChoice ( languageTypes [ l ] , place , null ) ;
}
BDFDB . DataUtils . save ( channelLanguages , _this , "channelLanguages" ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
} , {
iconSVG : ` <svg width="21" height="21" fill="currentColor"><path d="M 0, 10.515 c 0, 2.892, 1.183, 5.521, 3.155, 7.361 L 0, 21.031 h 7.887 V 13.144 l -2.892, 2.892 C 3.549, 14.722, 2.629, 12.75, 2.629, 10.515 c 0 -3.418, 2.235 -6.309, 5.258 -7.492 v -2.629 C 3.418, 1.577, 0, 5.652, 0, 10.515 z M 21.031, 0 H 13.144 v 7.887 l 2.892 -2.892 C 17.482, 6.309, 18.402, 8.281, 18.402, 10.515 c 0, 3.418 -2.235, 6.309 -5.258, 7.492 V 20.768 c 4.469 -1.183, 7.887 -5.258, 7.887 -10.121 c 0 -2.892 -1.183 -5.521 -3.155 -7.361 L 21.031, 0 z"/></svg> ` ,
2021-05-12 18:41:59 +02:00
onClick : _ => {
2021-06-01 16:17:59 +02:00
let input = _this . getLanguageChoice ( languageTypes . INPUT , place , this . props . channelId ) ;
let output = _this . getLanguageChoice ( languageTypes . OUTPUT , place , this . props . channelId ) ;
2021-05-12 18:41:59 +02:00
input = input == "auto" ? "en" : input ;
2021-06-01 16:17:59 +02:00
_this . saveLanguageChoice ( output , languageTypes . INPUT , place , this . props . channelId ) ;
_this . saveLanguageChoice ( input , languageTypes . OUTPUT , place , this . props . channelId ) ;
2021-05-12 18:41:59 +02:00
2021-03-20 18:50:17 +01:00
_this . setLanguages ( ) ;
2021-05-12 18:41:59 +02:00
BDFDB . ReactUtils . forceUpdate ( this ) ;
2021-06-01 16:17:59 +02:00
}
} ] . map ( data => {
const icon = BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Clickable , {
2021-07-11 18:51:40 +02:00
className : BDFDB . disCN . _translatorconfigbutton ,
2021-06-01 16:17:59 +02:00
onClick : data . onClick ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
width : 24 ,
height : 24 ,
color : data . color || "currentColor" ,
name : data . name ,
iconSVG : data . iconSVG
} )
} ) ;
return data . text ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , { text : data . text , children : icon } ) : icon ;
} ) ,
2021-05-12 18:41:59 +02:00
className : BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
2021-06-01 16:17:59 +02:00
value : _this . getLanguageChoice ( direction , place , this . props . channelId ) ,
options : this . filterLanguages ( direction , place ) ,
2021-05-12 18:41:59 +02:00
optionRenderer : lang => languages [ lang . value ] ? BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex . Child , {
grow : 1 ,
children : lang . label
} ) ,
lang . backup && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
text : "Will use Backup Translator" ,
tooltipConfig : {
color : "red"
} ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
nativeClass : true ,
width : 20 ,
height : 20 ,
2021-06-01 16:17:59 +02:00
color : "var(--bdfdb-red)" ,
2021-05-12 18:41:59 +02:00
name : BDFDB . LibraryComponents . SvgIcon . Names . WARNING
} )
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FavButton , {
isFavorite : languages [ lang . value ] . fav == 0 ,
onClick : value => {
2021-05-25 10:35:29 +02:00
if ( value ) favorites . push ( lang . value ) ;
else BDFDB . ArrayUtils . remove ( favorites , lang . value , true ) ;
BDFDB . DataUtils . save ( favorites . sort ( ) , _this , "favorites" ) ;
2021-05-12 18:41:59 +02:00
_this . setLanguages ( ) ;
}
} )
]
} ) : null ,
2021-06-06 13:49:58 +02:00
onChange : value => {
_this . saveLanguageChoice ( value , direction , place , this . props . channelId ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
2021-05-12 18:41:59 +02:00
} )
} ) ,
2021-06-01 16:17:59 +02:00
direction == languageTypes . OUTPUT && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
2021-05-12 18:41:59 +02:00
className : BDFDB . disCN . marginbottom8
} )
2021-06-01 16:17:59 +02:00
] ) ;
2021-05-12 18:41:59 +02:00
} ) ,
Object . keys ( _this . defaults . engines ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : _this . defaults . engines [ key ] . description ,
className : BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Select , {
value : _this . settings . engines [ key ] ,
options : ( key == "backup" ? [ "----" ] : [ ] ) . concat ( Object . keys ( translationEngines ) ) . filter ( key == "backup" ? ( n => n != _this . settings . engines . translator ) : ( n => n ) ) . map ( engineKey => ( { value : engineKey , label : translationEngines [ engineKey ] ? translationEngines [ engineKey ] . name : "----" } ) ) ,
maxVisibleItems : 3 ,
onChange : value => {
_this . settings . engines [ key ] = value ;
BDFDB . DataUtils . save ( _this . settings . engines , _this , "engines" ) ;
_this . setLanguages ( ) ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
}
} )
} ) ) ,
2021-06-01 16:17:59 +02:00
Object . keys ( _this . defaults . general ) . filter ( key => _this . defaults . general [ key ] . popout ) . map ( key => BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
2021-05-12 18:41:59 +02:00
type : "Switch" ,
plugin : _this ,
2021-06-01 16:17:59 +02:00
keys : [ "general" , key ] ,
label : _this . defaults . general [ key ] . description ,
2021-05-12 18:41:59 +02:00
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H5 ,
2021-06-01 16:17:59 +02:00
value : _this . settings . general [ key ]
} ) ) ,
2021-05-12 18:41:59 +02:00
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
label : "Translate your Messages before sending" ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H5 ,
2021-05-25 10:35:29 +02:00
value : _this . isTranslationEnabled ( this . props . channelId ) ,
2021-03-20 18:50:17 +01:00
onChange : value => {
2021-05-25 10:35:29 +02:00
_this . toggleTranslation ( this . props . channelId ) ;
2021-05-12 18:41:59 +02:00
BDFDB . ReactUtils . forceUpdate ( this ) ;
2021-03-20 18:50:17 +01:00
}
} )
2021-05-12 18:41:59 +02:00
] . flat ( 10 ) . filter ( n => n ) ;
2021-03-20 18:50:17 +01:00
}
} ;
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
const brailleConverter = {
"0" : "⠴" , "1" : "⠂" , "2" : "⠆" , "3" : "⠒" , "4" : "⠲" , "5" : "⠢" , "6" : "⠖" , "7" : "⠶" , "8" : "⠦" , "9" : "⠔" , "!" : "⠮" , "\"" : "⠐" , "#" : "⠼" , "$" : "⠫" , "%" : "⠩" , "&" : "⠯" , "'" : "⠄" , "(" : "⠷" , ")" : "⠾" , "*" : "⠡" , "+" : "⠬" , "," : "⠠" , "-" : "⠤" , "." : "⠨" , "/" : "⠌" , ":" : "⠱" , ";" : "⠰" , "<" : "⠣" , "=" : "⠿" , ">" : "⠜" , "?" : "⠹" , "@" : "⠈" , "a" : "⠁" , "b" : "⠃" , "c" : "⠉" , "d" : "⠙" , "e" : "⠑" , "f" : "⠋" , "g" : "⠛" , "h" : "⠓" , "i" : "⠊" , "j" : "⠚" , "k" : "⠅" , "l" : "⠇" , "m" : "⠍" , "n" : "⠝" , "o" : "⠕" , "p" : "⠏" , "q" : "⠟" , "r" : "⠗" , "s" : "⠎" , "t" : "⠞" , "u" : "⠥" , "v" : "⠧" , "w" : "⠺" , "x" : "⠭" , "y" : "⠽" , "z" : "⠵" , "[" : "⠪" , "\\" : "⠳" , "]" : "⠻" , "^" : "⠘" , "⠁" : "a" , "⠂" : "1" , "⠃" : "b" , "⠄" : "'" , "⠅" : "k" , "⠆" : "2" , "⠇" : "l" , "⠈" : "@" , "⠉" : "c" , "⠊" : "i" , "⠋" : "f" , "⠌" : "/" , "⠍" : "m" , "⠎" : "s" , "⠏" : "p" , "⠐" : "\"" , "⠑" : "e" , "⠒" : "3" , "⠓" : "h" , "⠔" : "9" , "⠕" : "o" , "⠖" : "6" , "⠗" : "r" , "⠘" : "^" , "⠙" : "d" , "⠚" : "j" , "⠛" : "g" , "⠜" : ">" , "⠝" : "n" , "⠞" : "t" , "⠟" : "q" , "⠠" : ", " , "⠡" : "*" , "⠢" : "5" , "⠣" : "<" , "⠤" : "-" , "⠥" : "u" , "⠦" : "8" , "⠧" : "v" , "⠨" : "." , "⠩" : "%" , "⠪" : "[" , "⠫" : "$" , "⠬" : "+" , "⠭" : "x" , "⠮" : "!" , "⠯" : "&" , "⠰" : ";" , "⠱" : ":" , "⠲" : "4" , "⠳" : "\\" , "⠴" : "0" , "⠵" : "z" , "⠶" : "7" , "⠷" : "(" , "⠸" : "_" , "⠹" : "?" , "⠺" : "w" , "⠻" : "]" , "⠼" : "#" , "⠽" : "y" , "⠾" : ")" , "⠿" : "=" , "_" : "⠸"
} ;
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
const morseConverter = {
"0" : "− − − − − " , "1" : "·−−−−" , "2" : "··−−−" , "3" : "···−−" , "4" : "····−" , "5" : "·····" , "6" : "−····" , "7" : "−−···" , "8" : "−−−··" , "9" : "−−−−·" , "!" : "−·−·−−" , "\"" : "·−··−·" , "$" : "···−··−" , "&" : "·−···" , "'" : "·−−−−·" , "(" : "−·−−·" , ")" : "−·−−·−" , "+" : "·−·−·" , "," : "−−··−−" , "-" : "−····−" , "." : "·−·−·−" , "/" : "−··−·" , ":" : "−−−···" , ";" : "−·−·−·" , "=" : "−···−" , "?" : "··−−··" , "@" : "·−−·−·" , "a" : "·−" , "b" : "−···" , "c" : "−·−·" , "d" : "−··" , "e" : "·" , "f" : "··−·" , "g" : "−−·" , "h" : "····" , "i" : "··" , "j" : "·−−−" , "k" : "−·−" , "l" : "·−··" , "m" : "− − " , "n" : "−·" , "o" : "− − − " , "p" : "·−−·" , "q" : "−−·−" , "r" : "·−·" , "s" : "···" , "t" : "− " , "u" : "··−" , "v" : "···−" , "w" : "·−−" , "x" : "−··−" , "y" : "−·−−" , "z" : "−−··" , "·" : "e" , "··" : "i" , "···" : "s" , "····" : "h" , "·····" : "5" , "····−" : "4" , "···−" : "v" , "···−··−" : "$" , "···−−" : "3" , "··−" : "u" , "··−·" : "f" , "··−−··" : "?" , "··−−·−" : "_" , "··−−−" : "2" , "·−" : "a" , "·−·" : "r" , "·−··" : "l" , "·−···" : "&" , "·−··−·" : "\"" , "·−·−·" : "+" , "·−·−·−" : "." , "·−−" : "w" , "·−−·" : "p" , "·−−·−·" : "@" , "·−−−" : "j" , "·−−−−" : "1" , "·−−−−·" : "'" , "− " : "t" , "−·" : "n" , "−··" : "d" , "−···" : "b" , "−····" : "6" , "−····−" : "-" , "−···−" : "=" , "−··−" : "x" , "−··−·" : "/" , "−·−" : "k" , "−·−·" : "c" , "−·−·−·" : ";" , "−·−·−−" : "!" , "−·−−" : "y" , "−·−−·" : "(" , "−·−−·−" : ")" , "− − " : "m" , "−−·" : "g" , "−−··" : "z" , "−−···" : "7" , "−−··−−" : "," , "−−·−" : "q" , "− − − " : "o" , "−−−··" : "8" , "−−−···" : ":" , "−−−−·" : "9" , "− − − − − " : "0" , "_" : "··−−·−"
} ;
2021-08-10 15:47:10 +02:00
const googleLanguages = [ "af" , "am" , "ar" , "az" , "be" , "bg" , "bn" , "bs" , "ca" , "ceb" , "co" , "cs" , "cy" , "da" , "de" , "el" , "en" , "eo" , "es" , "et" , "eu" , "fa" , "fi" , "fr" , "fy" , "ga" , "gd" , "gl" , "gu" , "ha" , "haw" , "hi" , "hmn" , "hr" , "ht" , "hu" , "hy" , "id" , "ig" , "is" , "it" , "iw" , "ja" , "jw" , "ka" , "kk" , "km" , "kn" , "ko" , "ku" , "ky" , "la" , "lb" , "lo" , "lt" , "lv" , "mg" , "mi" , "mk" , "ml" , "mn" , "mr" , "ms" , "mt" , "my" , "ne" , "nl" , "no" , "ny" , "or" , "pa" , "pl" , "ps" , "pt" , "ro" , "ru" , "rw" , "sd" , "si" , "sk" , "sl" , "sm" , "sn" , "so" , "sq" , "sr" , "st" , "su" , "sv" , "sw" , "ta" , "te" , "tg" , "th" , "tk" , "tl" , "tr" , "tt" , "ug" , "uk" , "ur" , "uz" , "vi" , "xh" , "yi" , "yo" , "zh-CN" , "zh-TW" , "zu" ] ;
2020-09-19 20:49:33 +02:00
const translationEngines = {
2021-06-06 13:49:58 +02:00
googleapi : {
name : "Google" ,
auto : true ,
funcName : "googleApiTranslate" ,
languages : googleLanguages
} ,
deepl : {
name : "DeepL" ,
auto : true ,
funcName : "deepLTranslate" ,
languages : [ "bg" , "cs" , "da" , "de" , "en" , "el" , "es" , "et" , "fi" , "fr" , "hu" , "it" , "ja" , "lt" , "lv" , "nl" , "pl" , "pt" , "ro" , "ru" , "sk" , "sl" , "sv" , "zh" ] ,
2021-10-14 16:51:23 +02:00
premium : true ,
2021-06-06 13:49:58 +02:00
key : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:fx"
} ,
itranslate : {
name : "iTranslate" ,
auto : true ,
funcName : "iTranslateTranslate" ,
languages : [ ... new Set ( [ "af" , "ar" , "az" , "be" , "bg" , "bn" , "bs" , "ca" , "ceb" , "cs" , "cy" , "da" , "de" , "el" , "en" , "eo" , "es" , "et" , "eu" , "fa" , "fi" , "fil" , "fr" , "ga" , "gl" , "gu" , "ha" , "he" , "hi" , "hmn" , "hr" , "ht" , "hu" , "hy" , "id" , "ig" , "is" , "it" , "ja" , "jw" , "ka" , "kk" , "km" , "kn" , "ko" , "la" , "lo" , "lt" , "lv" , "mg" , "mi" , "mk" , "ml" , "mn" , "mr" , "ms" , "mt" , "my" , "ne" , "nl" , "no" , "ny" , "pa" , "pl" , "pt-BR" , "pt-PT" , "ro" , "ru" , "si" , "sk" , "sl" , "so" , "sq" , "sr" , "st" , "su" , "sv" , "sw" , "ta" , "te" , "tg" , "th" , "tr" , "uk" , "ur" , "uz" , "vi" , "we" , "yi" , "yo" , "zh-CN" , "zh-TW" , "zu" ] . concat ( googleLanguages ) ) ] . sort ( ) ,
key : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
} ,
yandex : {
name : "Yandex" ,
auto : true ,
funcName : "yandexTranslate" ,
languages : [ "af" , "am" , "ar" , "az" , "ba" , "be" , "bg" , "bn" , "bs" , "ca" , "ceb" , "cs" , "cy" , "da" , "de" , "el" , "en" , "eo" , "es" , "et" , "eu" , "fa" , "fi" , "fr" , "ga" , "gd" , "gl" , "gu" , "he" , "hi" , "hr" , "ht" , "hu" , "hy" , "id" , "is" , "it" , "ja" , "jv" , "ka" , "kk" , "km" , "kn" , "ko" , "ky" , "la" , "lb" , "lo" , "lt" , "lv" , "mg" , "mhr" , "mi" , "mk" , "ml" , "mn" , "mr" , "ms" , "mt" , "my" , "ne" , "nl" , "no" , "pa" , "pap" , "pl" , "pt" , "ro" , "ru" , "si" , "sk" , "sl" , "sq" , "sr" , "su" , "sv" , "sw" , "ta" , "te" , "tg" , "th" , "tl" , "tr" , "tt" , "udm" , "uk" , "ur" , "uz" , "vi" , "xh" , "yi" , "zh" ] ,
key : "trnsl.x.x.xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
} ,
papago : {
name : "Papago" ,
auto : false ,
funcName : "papagoTranslate" ,
languages : [ "en" , "es" , "fr" , "id" , "ja" , "ko" , "th" , "vi" , "zh-CN" , "zh-TW" ] ,
key : "xxxxxxxxxxxxxxxxxxxx xxxxxxxxxx"
2021-08-05 14:06:44 +02:00
} ,
baidu : {
name : "Baidu" ,
auto : true ,
funcName : "baiduTranslate" ,
languages : [ "ar" , "bg" , "cs" , "da" , "de" , "el" , "en" , "es" , "et" , "fi" , "fr" , "hu" , "it" , "jp" , "ko" , "nl" , "pl" , "pt" , "ro" , "ru" , "sl" , "sv" , "th" , "vi" , "zh" , "zh-CN" , "zh-TW" ] ,
parser : {
"ar" : "ara" ,
"bg" : "bul" ,
"da" : "dan" ,
"es" : "spa" ,
"et" : "est" ,
"fi" : "fin" ,
"fr" : "fra" ,
"ko" : "kor" ,
"ro" : "rom" ,
"sl" : "slo" ,
"sv" : "swe" ,
"vi" : "vie" ,
2021-08-10 15:47:10 +02:00
"zh-CN" : "wyw" ,
2021-08-05 14:06:44 +02:00
"zh-TW" : "cht"
} ,
key : "xxxxxxxxx xxxxxx xxxxxxxxxx"
2021-06-06 13:49:58 +02:00
}
2020-09-19 20:49:33 +02:00
} ;
2021-05-25 10:35:29 +02:00
var languages = { } ;
var favorites = [ ] ;
2021-06-06 13:49:58 +02:00
var authKeys = { } ;
2021-06-01 16:17:59 +02:00
var channelLanguages = { } ;
2021-05-25 10:35:29 +02:00
var translationEnabledStates = [ ] , isTranslating ;
var translatedMessages = { } , oldMessages = { } ;
2021-06-01 16:17:59 +02:00
const defaultLanguages = {
INPUT : "auto" ,
OUTPUT : "$discord"
} ;
const languageTypes = {
INPUT : "input" ,
OUTPUT : "output"
} ;
const messageTypes = {
RECEIVED : "received" ,
SENT : "sent" ,
} ;
2020-09-19 20:49:33 +02:00
2021-07-11 18:51:40 +02:00
return class Translator extends Plugin {
2021-01-06 12:38:36 +01:00
onLoad ( ) {
2021-03-20 18:50:17 +01:00
_this = this ;
2020-09-19 20:49:33 +02:00
this . defaults = {
2021-03-20 18:50:17 +01:00
general : {
2021-06-01 16:17:59 +02:00
addTranslateButton : { value : true , popout : false , description : "Adds a Translate Button to the Channel Textarea" } ,
usePerChatTranslation : { value : true , popout : false , description : "Enables/Disables the Translator Button State per Channel and not globally" } ,
sendOriginalMessage : { value : false , popout : true , description : "Also sends the original Message when translating your own Message" } ,
showOriginalMessage : { value : false , popout : true , description : "Also shows the original Message when translating someones Message" }
2020-09-19 20:49:33 +02:00
} ,
2021-06-01 16:17:59 +02:00
choices : { } ,
2020-10-31 11:43:29 +01:00
exceptions : {
2020-11-19 16:51:14 +01:00
wordStart : { value : [ "!" ] , max : 1 , description : "Words starting with any of these will be ignored" }
2020-10-31 11:43:29 +01:00
} ,
2020-09-19 20:49:33 +02:00
engines : {
2021-05-12 18:41:59 +02:00
translator : { value : "googleapi" , description : "Translation Engine" } ,
backup : { value : "----" , description : "Backup Engine" }
2020-09-19 20:49:33 +02:00
}
} ;
2021-06-01 16:17:59 +02:00
for ( let m in messageTypes ) this . defaults . choices [ messageTypes [ m ] ] = { value : Object . keys ( languageTypes ) . reduce ( ( newObj , l ) => ( newObj [ languageTypes [ l ] ] = defaultLanguages [ l ] , newObj ) , { } ) } ;
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
this . patchedModules = {
before : {
ChannelTextAreaForm : "render" ,
ChannelEditorContainer : "render" ,
Embed : "render"
} ,
after : {
2022-01-30 23:49:21 +01:00
ChannelTextAreaButtons : "type" ,
2020-09-19 20:49:33 +02:00
Messages : "type" ,
MessageContent : "type" ,
Embed : "render"
}
} ;
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
this . css = `
2021-07-11 18:51:40 +02:00
$ { BDFDB . dotCN . _translatortranslatebutton + BDFDB . dotCNS . _translatortranslating + BDFDB . dotCN . textareaicon } {
2021-06-01 16:17:59 +02:00
color : var ( -- bdfdb - red ) ! important ;
2020-09-19 20:49:33 +02:00
}
2021-07-11 18:51:40 +02:00
$ { BDFDB . dotCN . _translatorconfigbutton } {
2021-06-01 16:26:43 +02:00
margin : 2 px 3 px 0 6 px ;
}
2020-09-19 20:49:33 +02:00
` ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStart ( ) {
2021-10-14 16:51:23 +02:00
// REMOVE 24.09.2021
let oldAuthKeys = BDFDB . DataUtils . load ( this , "authKeys" ) ;
for ( let key in oldAuthKeys ) if ( ! BDFDB . ObjectUtils . is ( oldAuthKeys [ key ] ) ) oldAuthKeys [ key ] = { key : oldAuthKeys [ key ] } ;
BDFDB . DataUtils . save ( oldAuthKeys , this , "authKeys" )
2020-06-09 09:52:52 +02:00
this . forceUpdateAll ( ) ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
2021-01-06 12:38:36 +01:00
onStop ( ) {
2020-06-09 09:52:52 +02:00
this . forceUpdateAll ( ) ;
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getSettingsPanel ( collapseStates = { } ) {
2021-03-20 19:04:57 +01:00
let settingsPanel ;
return settingsPanel = BDFDB . PluginUtils . createSettingsPanel ( this , {
collapseStates : collapseStates ,
children : _ => {
let settingsItems = [ ] ;
for ( let key in this . defaults . general ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsSaveItem , {
type : "Switch" ,
plugin : this ,
keys : [ "general" , key ] ,
label : this . defaults . general [ key ] . description ,
value : this . settings . general [ key ]
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCNS . dividerdefault + BDFDB . disCN . marginbottom8
} ) ) ;
2021-06-06 13:49:58 +02:00
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsPanelList , {
title : "Own Auth Keys:" ,
2021-10-14 16:51:23 +02:00
children : Object . keys ( translationEngines ) . filter ( key => translationEngines [ key ] . key ) . map ( key => BDFDB . ReactUtils . createElement ( "div" , {
className : BDFDB . disCN . marginbottom8 ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Flex , {
className : BDFDB . disCN . marginbottom8 ,
align : BDFDB . LibraryComponents . Flex . Align . CENTER ,
direction : BDFDB . LibraryComponents . Flex . Direction . HORIZONTAL ,
children : [
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormTitle , {
className : BDFDB . disCN . marginreset ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H5 ,
children : translationEngines [ key ] . name
} ) ,
translationEngines [ key ] . premium && BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SettingsItem , {
type : "Switch" ,
margin : 0 ,
grow : 0 ,
label : "Paid Version" ,
tag : BDFDB . LibraryComponents . FormComponents . FormTitle . Tags . H5 ,
value : authKeys [ key ] && authKeys [ key ] . paid ,
onChange : value => {
if ( ! authKeys [ key ] ) authKeys [ key ] = { } ;
authKeys [ key ] . paid = value ;
BDFDB . DataUtils . save ( authKeys , this , "authKeys" ) ;
}
} )
]
} ) ,
BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TextInput , {
placeholder : translationEngines [ key ] . key ,
value : authKeys [ key ] && authKeys [ key ] . key ,
onChange : value => {
if ( ! authKeys [ key ] ) authKeys [ key ] = { } ;
authKeys [ key ] . key = ( value || "" ) . trim ( ) ;
BDFDB . DataUtils . save ( authKeys , this , "authKeys" ) ;
}
} )
]
2021-06-06 13:49:58 +02:00
} ) )
} ) ) ;
settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormDivider , {
className : BDFDB . disCNS . dividerdefault + BDFDB . disCN . marginbottom8
} ) ) ;
2021-03-20 19:04:57 +01:00
for ( let key in this . defaults . exceptions ) settingsItems . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . FormComponents . FormItem , {
title : this . defaults . exceptions [ key ] . description ,
className : BDFDB . disCN . marginbottom8 ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . ListInput , {
placeholder : "New Exception" ,
maxLength : this . defaults . exceptions [ key ] . max ,
items : this . settings . exceptions [ key ] ,
onChange : value => {
this . SettingsUpdated = true ;
BDFDB . DataUtils . save ( value , this , "exceptions" , key ) ;
}
} )
} ) ) ;
return settingsItems . flat ( 10 ) ;
}
} ) ;
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
2021-01-06 12:38:36 +01:00
onSettingsClosed ( ) {
2020-09-19 20:49:33 +02:00
if ( this . SettingsUpdated ) {
delete this . SettingsUpdated ;
this . forceUpdateAll ( ) ;
}
}
2021-01-06 12:38:36 +01:00
forceUpdateAll ( ) {
2020-09-19 20:49:33 +02:00
favorites = BDFDB . DataUtils . load ( this , "favorites" ) ;
2021-05-25 10:35:29 +02:00
favorites = ! BDFDB . ArrayUtils . is ( favorites ) ? [ ] : favorites ;
2020-09-19 20:49:33 +02:00
2021-06-06 13:49:58 +02:00
authKeys = BDFDB . DataUtils . load ( this , "authKeys" ) ;
2021-06-01 16:17:59 +02:00
channelLanguages = BDFDB . DataUtils . load ( this , "channelLanguages" ) ;
2020-09-19 20:49:33 +02:00
this . setLanguages ( ) ;
BDFDB . PatchUtils . forceAllUpdates ( this ) ;
BDFDB . MessageUtils . rerenderAll ( ) ;
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
onMessageContextMenu ( e ) {
if ( e . instance . props . message && e . instance . props . channel ) {
let translated = translatedMessages [ e . instance . props . message . id ] ;
let hint = BDFDB . BDUtils . isPluginEnabled ( "MessageUtilities" ) ? BDFDB . BDUtils . getPlugin ( "MessageUtilities" ) . getActiveShortcutString ( "__Translate_Message" ) : null ;
let [ children , index ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : [ "pin" , "unpin" ] } ) ;
if ( index == - 1 ) [ children , index ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : [ "edit" , "add-reaction" , "quote" ] } ) ;
children . splice ( index > - 1 ? index + 1 : 0 , 0 , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2020-12-21 19:56:36 +01:00
label : translated ? this . labels . context _messageuntranslateoption : this . labels . context _messagetranslateoption ,
2020-09-19 20:49:33 +02:00
id : BDFDB . ContextMenuUtils . createItemId ( this . name , translated ? "untranslate-message" : "translate-message" ) ,
hint : hint && ( _ => {
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . MenuItems . MenuHint , {
hint : hint
} ) ;
} ) ,
disabled : ! translated && isTranslating ,
2021-05-18 20:09:05 +02:00
action : _ => this . translateMessage ( e . instance . props . message , e . instance . props . channel )
2020-09-19 20:49:33 +02:00
} ) ) ;
this . injectSearchItem ( e ) ;
}
}
onNativeContextMenu ( e ) {
2020-05-20 10:25:47 +02:00
this . injectSearchItem ( e ) ;
}
2020-09-19 20:49:33 +02:00
onSlateContextMenu ( e ) {
this . injectSearchItem ( e ) ;
}
injectSearchItem ( e ) {
let text = document . getSelection ( ) . toString ( ) ;
if ( text ) {
let translating , foundTranslation , foundInput , foundOutput ;
let [ children , index ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : [ "devmode-copy-id" , "search-google" ] , group : true } ) ;
children . splice ( index > - 1 ? index + 1 : 0 , 0 , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuGroup , {
children : BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
id : BDFDB . ContextMenuUtils . createItemId ( this . name , "search-translation" ) ,
disabled : isTranslating ,
2021-07-11 18:51:40 +02:00
label : this . labels . context _translator ,
2020-09-19 20:49:33 +02:00
persisting : true ,
action : event => {
let item = BDFDB . DOMUtils . getParent ( BDFDB . dotCN . menuitem , event . target ) ;
if ( item ) {
let createTooltip = _ => {
2021-06-01 16:17:59 +02:00
BDFDB . TooltipUtils . create ( item , [
` ${ BDFDB . LanguageUtils . LibraryStrings . from } ${ foundInput . name } : ` ,
text ,
` ${ BDFDB . LanguageUtils . LibraryStrings . to } ${ foundOutput . name } : ` ,
foundTranslation
] . map ( n => BDFDB . ReactUtils . createElement ( "div" , { children : n } ) ) , {
2021-01-12 19:09:01 +01:00
type : "right" ,
2021-06-01 16:17:59 +02:00
color : "black" ,
2021-01-12 19:09:01 +01:00
className : "googletranslate-tooltip"
} ) ;
2020-09-19 20:49:33 +02:00
} ;
if ( foundTranslation && foundInput && foundOutput ) {
if ( document . querySelector ( ".googletranslate-tooltip" ) ) {
BDFDB . ContextMenuUtils . close ( e . instance ) ;
2021-01-10 11:41:01 +01:00
BDFDB . DiscordUtils . openLink ( this . getGoogleTranslatePageURL ( foundInput . id , foundOutput . id , text ) ) ;
2020-05-23 14:50:13 +02:00
}
2020-09-19 20:49:33 +02:00
else createTooltip ( ) ;
}
else if ( ! translating ) {
translating = true ;
2021-06-01 16:17:59 +02:00
this . translateText ( text , messageTypes . RECEIVED , ( translation , input , output ) => {
2020-09-19 20:49:33 +02:00
if ( translation ) {
foundTranslation = translation , foundInput = input , foundOutput = output ;
createTooltip ( ) ;
}
} ) ;
}
2020-05-23 14:50:13 +02:00
}
2019-12-09 15:56:53 +01:00
}
2020-09-19 20:49:33 +02:00
} )
} ) ) ;
}
}
onMessageOptionContextMenu ( e ) {
if ( e . instance . props . message && e . instance . props . channel ) {
let translated = ! ! translatedMessages [ e . instance . props . message . id ] ;
let [ children , index ] = BDFDB . ContextMenuUtils . findItem ( e . returnvalue , { id : [ "pin" , "unpin" ] } ) ;
children . splice ( index + 1 , 0 , BDFDB . ContextMenuUtils . createItem ( BDFDB . LibraryComponents . MenuItems . MenuItem , {
2020-12-21 19:56:36 +01:00
label : translated ? this . labels . context _messageuntranslateoption : this . labels . context _messagetranslateoption ,
2020-09-19 20:49:33 +02:00
disabled : isTranslating ,
id : BDFDB . ContextMenuUtils . createItemId ( this . name , translated ? "untranslate-message" : "translate-message" ) ,
icon : _ => {
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . MenuItems . MenuIcon , {
icon : translated ? translateIconUntranslate : translateIcon
} ) ;
} ,
2021-05-18 20:09:05 +02:00
action : _ => this . translateMessage ( e . instance . props . message , e . instance . props . channel )
2020-09-19 20:49:33 +02:00
} ) ) ;
}
2020-02-04 08:20:40 +01:00
}
2020-09-23 09:29:56 +02:00
onMessageOptionToolbar ( e ) {
if ( e . instance . props . expanded && e . instance . props . message && e . instance . props . channel ) {
let translated = ! ! translatedMessages [ e . instance . props . message . id ] ;
2021-05-18 20:09:05 +02:00
e . returnvalue . props . children . unshift ( ) ;
e . returnvalue . props . children . unshift ( BDFDB . ReactUtils . createElement ( class extends BdApi . React . Component {
render ( ) {
return BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
key : translated ? "untranslate-message" : "translate-message" ,
text : _ => translated ? _this . labels . context _messageuntranslateoption : _this . labels . context _messagetranslateoption ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . Clickable , {
className : BDFDB . disCN . messagetoolbarbutton ,
onClick : _ => {
if ( ! isTranslating ) _this . translateMessage ( e . instance . props . message , e . instance . props . channel ) . then ( _ => {
translated = ! ! translatedMessages [ e . instance . props . message . id ] ;
BDFDB . ReactUtils . forceUpdate ( this ) ;
} ) ;
} ,
children : BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . SvgIcon , {
className : BDFDB . disCN . messagetoolbaricon ,
iconSVG : translated ? translateIconUntranslate : translateIcon
} )
} )
} ) ;
}
2020-09-23 09:29:56 +02:00
} ) ) ;
}
}
2020-09-19 20:49:33 +02:00
processChannelTextAreaForm ( e ) {
BDFDB . PatchUtils . patch ( this , e . instance , "handleSendMessage" , { instead : e2 => {
2021-05-25 10:35:29 +02:00
if ( this . isTranslationEnabled ( e . instance . props . channel . id ) ) {
2020-09-19 20:49:33 +02:00
e2 . stopOriginalMethodCall ( ) ;
2021-06-01 16:17:59 +02:00
this . translateText ( e2 . methodArguments [ 0 ] , messageTypes . SENT , ( translation , input , output ) => {
2021-10-14 16:51:23 +02:00
translation = ! translation ? e2 . methodArguments [ 0 ] : ( this . settings . general . sendOriginalMessage ? ( translation + "\n\n> *" + e2 . methodArguments [ 0 ] . split ( "\n" ) . join ( "*\n> *" ) + "*" ) : translation ) ;
2020-09-19 20:49:33 +02:00
e2 . originalMethod ( translation ) ;
} ) ;
return Promise . resolve ( {
shouldClear : true ,
shouldRefocus : true
2020-05-14 17:33:14 +02:00
} ) ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
else return e2 . callOriginalMethodAfterwards ( ) ;
} } , { force : true , noCache : true } ) ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
processChannelEditorContainer ( e ) {
2021-05-25 10:35:29 +02:00
if ( this . isTranslationEnabled ( e . instance . props . channel . id ) && isTranslating ) e . instance . props . disabled = true ;
2020-09-19 20:49:33 +02:00
}
2022-01-30 23:49:21 +01:00
processChannelTextAreaButtons ( e ) {
2022-02-11 14:58:40 +01:00
if ( this . settings . general . addTranslateButton && ( e . instance . props . type == BDFDB . LibraryComponents . ChannelTextAreaTypes . NORMAL || e . instance . props . type == BDFDB . LibraryComponents . ChannelTextAreaTypes . SIDEBAR ) && ! e . instance . props . disabled ) {
2022-01-30 23:49:21 +01:00
e . returnvalue . props . children . unshift ( BDFDB . ReactUtils . createElement ( TranslateButtonComponent , {
channelId : e . instance . props . channel . id
} ) ) ;
2020-02-11 09:46:53 +01:00
}
2019-12-21 02:24:30 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
processMessages ( e ) {
e . returnvalue . props . children . props . channelStream = [ ] . concat ( e . returnvalue . props . children . props . channelStream ) ;
for ( let i in e . returnvalue . props . children . props . channelStream ) {
let message = e . returnvalue . props . children . props . channelStream [ i ] . content ;
if ( message ) {
if ( BDFDB . ArrayUtils . is ( message . attachments ) ) this . checkMessage ( e . returnvalue . props . children . props . channelStream [ i ] , message ) ;
else if ( BDFDB . ArrayUtils . is ( message ) ) for ( let j in message ) {
let childMessage = message [ j ] . content ;
if ( childMessage && BDFDB . ArrayUtils . is ( childMessage . attachments ) ) this . checkMessage ( message [ j ] , childMessage ) ;
}
2020-05-15 09:58:08 +02:00
}
}
}
2020-09-19 20:49:33 +02:00
checkMessage ( stream , message ) {
let translation = translatedMessages [ message . id ] ;
if ( translation ) stream . content . content = translation . content ;
else if ( oldMessages [ message . id ] && Object . keys ( message ) . some ( key => ! BDFDB . equals ( oldMessages [ message . id ] [ key ] , message [ key ] ) ) ) {
stream . content . content = oldMessages [ message . id ] . content ;
delete oldMessages [ message . id ] ;
}
2020-05-23 14:50:13 +02:00
}
2019-12-21 11:25:13 +01:00
2020-09-19 20:49:33 +02:00
processMessageContent ( e ) {
if ( e . instance . props . message ) {
let translation = translatedMessages [ e . instance . props . message . id ] ;
2021-05-03 20:30:07 +02:00
if ( translation && translation . content ) e . returnvalue . props . children . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
2021-08-10 15:47:10 +02:00
text : ` ${ BDFDB . LanguageUtils . getName ( translation . input ) } ➝ ${ BDFDB . LanguageUtils . LibraryStrings . to } ${ BDFDB . LanguageUtils . getName ( translation . output ) } ` ,
2020-09-19 20:49:33 +02:00
tooltipConfig : { style : "max-width: 400px" } ,
2021-05-03 20:30:07 +02:00
children : BDFDB . ReactUtils . createElement ( "span" , {
2021-07-11 18:51:40 +02:00
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . messagetimestamp , BDFDB . disCN . messagetimestampinline , BDFDB . disCN . _translatortranslated ) ,
2021-05-03 20:30:07 +02:00
children : BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . messageedited ,
children : ` ( ${ this . labels . translated _watermark } ) `
} )
2020-09-19 20:49:33 +02:00
} )
} ) ) ;
}
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
processEmbed ( e ) {
2021-01-13 18:54:21 +01:00
if ( e . instance . props . embed && e . instance . props . embed . message _id ) {
let translation = translatedMessages [ e . instance . props . embed . message _id ] ;
2021-05-03 20:30:07 +02:00
if ( translation && Object . keys ( translation . embeds ) . length ) {
2020-09-19 20:49:33 +02:00
if ( ! e . returnvalue ) e . instance . props . embed = Object . assign ( { } , e . instance . props . embed , {
rawDescription : translation . embeds [ e . instance . props . embed . id ] ,
originalDescription : e . instance . props . embed . originalDescription || e . instance . props . embed . rawDescription
} ) ;
else {
let [ children , index ] = BDFDB . ReactUtils . findParent ( e . returnvalue , { props : [ [ "className" , BDFDB . disCN . embeddescription ] ] } ) ;
if ( index > - 1 ) children [ index ] . props . children . push ( BDFDB . ReactUtils . createElement ( BDFDB . LibraryComponents . TooltipContainer , {
2021-06-01 16:17:59 +02:00
text : ` ${ BDFDB . LanguageUtils . getName ( translation . input ) } ➝ ${ BDFDB . LanguageUtils . getName ( translation . output ) } ` ,
2020-09-19 20:49:33 +02:00
tooltipConfig : { style : "max-width: 400px" } ,
2021-05-03 20:30:07 +02:00
children : BDFDB . ReactUtils . createElement ( "span" , {
2021-07-11 18:51:40 +02:00
className : BDFDB . DOMUtils . formatClassName ( BDFDB . disCN . messagetimestamp , BDFDB . disCN . messagetimestampinline , BDFDB . disCN . _translatortranslated ) ,
2021-05-03 20:30:07 +02:00
children : BDFDB . ReactUtils . createElement ( "span" , {
className : BDFDB . disCN . messageedited ,
children : ` ( ${ this . labels . translated _watermark } ) `
} )
2020-09-19 20:49:33 +02:00
} )
} ) ) ;
}
}
else if ( ! e . returnvalue && e . instance . props . embed . originalDescription ) {
e . instance . props . embed = Object . assign ( { } , e . instance . props . embed , { rawDescription : e . instance . props . embed . originalDescription } ) ;
delete e . instance . props . embed . originalDescription ;
2020-02-04 08:20:40 +01:00
}
2019-10-24 21:30:55 +02:00
}
2020-02-04 08:20:40 +01:00
}
2021-05-25 10:35:29 +02:00
toggleTranslation ( channelId ) {
if ( ! this . isTranslationEnabled ( channelId ) ) translationEnabledStates . push ( this . settings . general . usePerChatTranslation ? channelId : "global" ) ;
else BDFDB . ArrayUtils . remove ( translationEnabledStates , this . settings . general . usePerChatTranslation ? channelId : "global" , true ) ;
}
isTranslationEnabled ( channelId ) {
return translationEnabledStates . includes ( this . settings . general . usePerChatTranslation ? channelId : "global" ) ;
}
2019-10-24 11:47:57 +02:00
2021-01-06 12:38:36 +01:00
setLanguages ( ) {
2021-05-12 18:41:59 +02:00
if ( this . settings . engines . translator == this . settings . engines . backup ) {
this . settings . engines . backup = Object . keys ( translationEngines ) . filter ( n => n != this . settings . engines . translator ) [ 0 ] ;
BDFDB . DataUtils . save ( this . settings . engines , this , "engines" ) ;
}
2021-05-15 20:55:12 +02:00
let engine = translationEngines [ this . settings . engines . translator ] || { } ;
let backup = translationEngines [ this . settings . engines . backup ] || { } ;
let languageIds = [ ] . concat ( engine . languages , backup . languages ) . flat ( 10 ) . filter ( n => n ) ;
2020-09-19 20:49:33 +02:00
languages = BDFDB . ObjectUtils . deepAssign (
2021-05-15 20:55:12 +02:00
! engine . auto && ! backup . auto ? { } : {
2020-09-19 20:49:33 +02:00
auto : {
2021-05-12 18:41:59 +02:00
auto : true ,
2021-07-09 14:36:06 +02:00
name : "Detect Language" ,
2020-09-19 20:49:33 +02:00
id : "auto"
}
2020-06-05 20:03:21 +02:00
} ,
2020-09-19 20:49:33 +02:00
BDFDB . ObjectUtils . filter ( BDFDB . LanguageUtils . languages , lang => languageIds . includes ( lang . id ) ) ,
{
binary : {
2021-05-12 18:41:59 +02:00
special : true ,
2020-09-19 20:49:33 +02:00
name : "Binary" ,
id : "binary"
} ,
braille : {
2021-05-12 18:41:59 +02:00
special : true ,
2020-09-19 20:49:33 +02:00
name : "Braille 6-dot" ,
id : "braille"
} ,
morse : {
2021-05-12 18:41:59 +02:00
special : true ,
2020-09-19 20:49:33 +02:00
name : "Morse" ,
id : "morse"
}
2020-06-05 20:03:21 +02:00
}
2020-09-19 20:49:33 +02:00
) ;
2021-05-25 10:35:29 +02:00
for ( let id in languages ) languages [ id ] . fav = favorites . includes ( id ) ? 0 : 1 ;
2020-09-19 20:49:33 +02:00
languages = BDFDB . ObjectUtils . sort ( languages , "fav" ) ;
}
2019-01-26 22:45:19 +01:00
2021-06-01 16:17:59 +02:00
getLanguageChoice ( direction , place , channelId ) {
2020-09-19 20:49:33 +02:00
this . setLanguages ( ) ;
2021-06-01 16:17:59 +02:00
let choice ;
if ( channelLanguages [ channelId ] && channelLanguages [ channelId ] [ place ] ) choice = channelLanguages [ channelId ] [ place ] [ direction ] ;
else choice = this . settings . choices [ place ] && this . settings . choices [ place ] [ direction ] ;
2020-09-19 20:49:33 +02:00
choice = languages [ choice ] ? choice : Object . keys ( languages ) [ 0 ] ;
2021-06-01 16:17:59 +02:00
choice = direction == languageTypes . OUTPUT && choice == "auto" ? "en" : choice ;
2020-09-19 20:49:33 +02:00
return choice ;
2019-09-27 09:48:32 +02:00
}
2020-09-19 20:49:33 +02:00
2021-06-01 16:17:59 +02:00
saveLanguageChoice ( choice , direction , place , channelId ) {
if ( channelLanguages [ channelId ] && channelLanguages [ channelId ] [ place ] ) {
channelLanguages [ channelId ] [ place ] [ direction ] = choice ;
BDFDB . DataUtils . save ( channelLanguages , this , "channelLanguages" ) ;
}
else {
this . settings . choices [ place ] [ direction ] = choice ;
BDFDB . DataUtils . save ( this . settings . choices , this , "choices" ) ;
}
}
2020-09-19 20:49:33 +02:00
translateMessage ( message , channel ) {
2021-05-18 20:09:05 +02:00
return new Promise ( callback => {
if ( ! message ) return callback ( null ) ;
if ( translatedMessages [ message . id ] ) {
delete translatedMessages [ message . id ] ;
BDFDB . MessageUtils . rerenderAll ( true ) ;
callback ( false ) ;
}
else {
2021-06-01 16:17:59 +02:00
let orignalContent = message . content || "" ;
for ( let embed of message . embeds ) orignalContent += ( "\n__________________ __________________ __________________\n" + embed . rawDescription ) ;
this . translateText ( orignalContent , messageTypes . RECEIVED , ( translation , input , output ) => {
2021-05-18 20:09:05 +02:00
if ( translation ) {
oldMessages [ message . id ] = new BDFDB . DiscordObjects . Message ( message ) ;
2021-06-01 16:17:59 +02:00
let oldStrings = orignalContent . split ( /\n{0,1}__________________ __________________ __________________\n{0,1}/ ) ;
2021-05-18 20:09:05 +02:00
let strings = translation . split ( /\n{0,1}__________________ __________________ __________________\n{0,1}/ ) ;
2021-06-01 16:17:59 +02:00
let oldContent = this . settings . general . showOriginalMessage && ( oldStrings . shift ( ) || "" ) . trim ( ) ;
let content = ( strings . shift ( ) || "" ) . trim ( ) + ( oldContent ? ` \n \n ${ oldContent } ` : "" ) ;
let embeds = { } ;
2021-05-18 20:09:05 +02:00
for ( let i in message . embeds ) {
message . embeds [ i ] . message _id = message . id ;
2021-06-01 16:17:59 +02:00
let oldEmbedString = this . settings . general . showOriginalMessage && ( oldStrings . shift ( ) || "" ) . trim ( ) ;
embeds [ message . embeds [ i ] . id ] = ( strings . shift ( ) || message . embeds [ i ] . rawDescription ) . trim ( ) + ( oldEmbedString ? ` \n \n ${ oldEmbedString } ` : "" ) ;
2021-05-18 20:09:05 +02:00
}
translatedMessages [ message . id ] = { content , embeds , input , output } ;
BDFDB . MessageUtils . rerenderAll ( true ) ;
2020-09-19 20:49:33 +02:00
}
2021-05-18 20:09:05 +02:00
callback ( true ) ;
} ) ;
}
} ) ;
2019-12-09 15:56:53 +01:00
}
2019-01-26 22:45:19 +01:00
2021-06-01 16:17:59 +02:00
translateText ( text , place , callback ) {
2021-05-12 18:41:59 +02:00
let toast = null , toastInterval , finished = false , finishTranslation = translation => {
2020-09-19 20:49:33 +02:00
isTranslating = false ;
2021-01-26 21:14:48 +01:00
if ( toast ) toast . close ( ) ;
2021-05-12 18:41:59 +02:00
BDFDB . TimeUtils . clear ( toastInterval ) ;
if ( finished ) return ;
finished = true ;
if ( translation ) translation = this . addExceptions ( translation , excepts ) ;
2020-09-19 20:49:33 +02:00
callback ( translation == text ? "" : translation , input , output ) ;
} ;
2021-06-01 16:17:59 +02:00
let [ newText , excepts , translate ] = this . removeExceptions ( text . trim ( ) , place ) ;
let channelId = BDFDB . LibraryModules . LastChannelStore . getChannelId ( ) ;
let input = Object . assign ( { } , languages [ this . getLanguageChoice ( languageTypes . INPUT , place , channelId ) ] ) ;
let output = Object . assign ( { } , languages [ this . getLanguageChoice ( languageTypes . OUTPUT , place , channelId ) ] ) ;
2020-12-14 10:43:32 +01:00
if ( translate && input . id != output . id ) {
let specialCase = this . checkForSpecialCase ( newText , input ) ;
if ( specialCase ) {
input . name = specialCase . name ;
switch ( specialCase . id ) {
2020-10-31 11:43:29 +01:00
case "binary" : newText = this . binary2string ( newText ) ; break ;
case "braille" : newText = this . braille2string ( newText ) ; break ;
case "morse" : newText = this . morse2string ( newText ) ; break ;
2020-09-19 20:49:33 +02:00
}
2020-02-04 08:20:40 +01:00
}
2021-05-12 18:41:59 +02:00
if ( output . special ) {
2020-09-19 20:49:33 +02:00
switch ( output . id ) {
2020-10-31 11:43:29 +01:00
case "binary" : newText = this . string2binary ( newText ) ; break ;
case "braille" : newText = this . string2braille ( newText ) ; break ;
case "morse" : newText = this . string2morse ( newText ) ; break ;
2020-09-19 20:49:33 +02:00
}
2020-10-31 11:43:29 +01:00
finishTranslation ( newText ) ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
else {
2021-05-12 18:41:59 +02:00
const startTranslating = engine => {
2020-09-19 20:49:33 +02:00
isTranslating = true ;
2021-05-12 18:41:59 +02:00
if ( toast ) toast . close ( ) ;
BDFDB . TimeUtils . clear ( toastInterval ) ;
let loadingString = ` ${ this . labels . toast _translating } ( ${ translationEngines [ engine ] . name } ) - ${ BDFDB . LanguageUtils . LibraryStrings . please _wait } ` ;
let currentLoadingString = loadingString ;
toast = BDFDB . NotificationUtils . toast ( loadingString , {
timeout : 0 ,
position : "center" ,
onClose : _ => BDFDB . TimeUtils . clear ( toastInterval )
} ) ;
toastInterval = BDFDB . TimeUtils . interval ( ( _ , count ) => {
if ( count > 40 ) {
finishTranslation ( "" ) ;
BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } ( ${ translationEngines [ engine ] . name } ) - ${ this . labels . toast _translating _tryanother } ` , {
type : "danger" ,
position : "center"
} ) ;
}
else {
currentLoadingString = currentLoadingString . endsWith ( "....." ) ? loadingString : currentLoadingString + "." ;
toast . update ( currentLoadingString ) ;
}
} , 500 ) ;
} ;
if ( this . validTranslator ( this . settings . engines . translator , input , output , specialCase ) ) {
startTranslating ( this . settings . engines . translator ) ;
this [ translationEngines [ this . settings . engines . translator ] . funcName ] . apply ( this , [ { input , output , text : newText , specialCase , engine : translationEngines [ this . settings . engines . translator ] } , translation => {
if ( ! translation && this . validTranslator ( this . settings . engines . backup , input , output , specialCase ) ) {
startTranslating ( this . settings . engines . backup ) ;
this [ translationEngines [ this . settings . engines . backup ] . funcName ] . apply ( this , [ { input , output , text : newText , specialCase , engine : translationEngines [ this . settings . engines . backup ] } , finishTranslation ] ) ;
}
else finishTranslation ( translation ) ;
} ] ) ;
}
else if ( this . validTranslator ( this . settings . engines . backup , input , output , specialCase ) ) {
startTranslating ( this . settings . engines . backup ) ;
this [ translationEngines [ this . settings . engines . backup ] . funcName ] . apply ( this , [ { input , output , text : newText , specialCase , engine : translationEngines [ this . settings . engines . backup ] } , finishTranslation ] ) ;
}
2021-05-18 20:09:05 +02:00
else finishTranslation ( ) ;
2020-02-04 08:20:40 +01:00
}
2019-12-09 15:56:53 +01:00
}
2020-09-19 20:49:33 +02:00
else finishTranslation ( ) ;
2018-10-11 10:21:26 +02:00
}
2020-09-19 20:49:33 +02:00
2021-05-12 18:41:59 +02:00
validTranslator ( key , input , output , specialCase ) {
return translationEngines [ key ] && typeof this [ translationEngines [ key ] . funcName ] == "function" && ( specialCase || input . auto && translationEngines [ key ] . auto || translationEngines [ key ] . languages . includes ( input . id ) && translationEngines [ key ] . languages . includes ( output . id ) ) ;
}
2021-05-12 14:33:47 +02:00
googleApiTranslate ( data , callback ) {
BDFDB . LibraryRequires . request ( ` https://translate.googleapis.com/translate_a/single?client=gtx&sl= ${ data . input . id } &tl= ${ data . output . id } &dt=t&dj=1&source=input&q= ${ encodeURIComponent ( data . text ) } ` , ( error , response , body ) => {
if ( ! error && body && response . statusCode == 200 ) {
try {
body = JSON . parse ( body ) ;
if ( ! data . specialCase && body . src && body . src && languages [ body . src ] ) {
data . input . name = languages [ body . src ] . name ;
data . input . ownlang = languages [ body . src ] . ownlang ;
}
callback ( body . sentences . map ( n => n && n . trans ) . filter ( n => n ) . join ( "" ) ) ;
}
catch ( err ) { callback ( "" ) ; }
2020-02-28 15:01:54 +01:00
}
2021-05-12 14:33:47 +02:00
else {
if ( response . statusCode == 429 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Request Limit per Hour reached. ` , {
type : "danger" ,
position : "center"
} ) ;
else BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server might be down. ` , {
type : "danger" ,
position : "center"
} ) ;
callback ( "" ) ;
2020-09-19 20:49:33 +02:00
}
} ) ;
}
2021-05-12 14:33:47 +02:00
deepLTranslate ( data , callback ) {
2021-10-14 16:51:23 +02:00
BDFDB . LibraryRequires . request ( ` ${ authKeys . deepl && authKeys . deepl . paid ? "https://api.deepl.com/v2/translate" : "https://api-free.deepl.com/v2/translate" } ?auth_key= ${ authKeys . deepl && authKeys . deepl . key || "75cc2f40-fdae-14cd-7242-6a384e2abb9c:fx" } &text= ${ encodeURIComponent ( data . text ) } ${ data . input . auto ? "" : ` &source_lang= ${ data . input . id } ` } &target_lang= ${ data . output . id } ` , ( error , response , body ) => {
2021-05-12 14:33:47 +02:00
if ( ! error && body && response . statusCode == 200 ) {
2020-02-04 08:20:40 +01:00
try {
2021-05-12 14:33:47 +02:00
body = JSON . parse ( body ) ;
if ( ! data . specialCase && body . translations [ 0 ] && body . translations [ 0 ] . detected _source _language && languages [ body . translations [ 0 ] . detected _source _language . toLowerCase ( ) ] ) {
data . input . name = languages [ body . translations [ 0 ] . detected _source _language . toLowerCase ( ) ] . name ;
data . input . ownlang = languages [ body . translations [ 0 ] . detected _source _language . toLowerCase ( ) ] . ownlang ;
2020-02-04 08:20:40 +01:00
}
2021-05-12 14:33:47 +02:00
callback ( body . translations . map ( n => n && n . text ) . filter ( n => n ) . join ( "" ) ) ;
2020-02-04 08:20:40 +01:00
}
catch ( err ) { callback ( "" ) ; }
}
else {
2021-05-18 12:07:15 +02:00
if ( response . statusCode == 429 || response . statusCode == 456 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Request Limit reached. ` , {
2021-05-12 14:33:47 +02:00
type : "danger" ,
position : "center"
} ) ;
else if ( response . statusCode == 403 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . API-Key outdated. ` , {
2021-01-26 21:14:48 +01:00
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
else BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server might be down. ` , {
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-02-04 08:20:40 +01:00
callback ( "" ) ;
}
} ) ;
2020-09-19 20:49:33 +02:00
}
iTranslateTranslate ( data , callback ) {
let translate = _ => {
2021-05-12 14:33:47 +02:00
BDFDB . LibraryRequires . request . post ( {
2020-11-19 16:45:36 +01:00
url : "https://web-api.itranslateapp.com/v3/texts/translate" ,
2020-09-19 20:49:33 +02:00
headers : {
2021-10-14 16:51:23 +02:00
"API-KEY" : authKeys . itranslate && authKeys . itranslate . key || data . engine . APIkey
2020-09-19 20:49:33 +02:00
} ,
body : JSON . stringify ( {
source : {
dialect : data . input . id ,
text : data . text
} ,
target : {
dialect : data . output . id
}
} )
2021-05-12 14:33:47 +02:00
} , ( error , response , body ) => {
2020-09-19 20:49:33 +02:00
if ( ! error && response && response . statusCode == 200 ) {
try {
2021-05-12 14:33:47 +02:00
body = JSON . parse ( body ) ;
if ( ! data . specialCase && body . source && body . source . dialect && languages [ body . source . dialect ] ) {
data . input . name = languages [ body . source . dialect ] . name ;
data . input . ownlang = languages [ body . source . dialect ] . ownlang ;
2020-09-19 20:49:33 +02:00
}
2021-05-12 14:33:47 +02:00
callback ( body . target . text ) ;
2020-09-19 20:49:33 +02:00
}
catch ( err ) { callback ( "" ) ; }
}
else {
2021-05-12 14:33:47 +02:00
if ( response . statusCode == 429 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Request Limit reached. ` , {
type : "danger" ,
position : "center"
} ) ;
else if ( response . statusCode == 403 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . API-Key outdated. ` , {
type : "danger" ,
position : "center"
} ) ;
else BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server might be down. ` , {
2021-01-26 21:14:48 +01:00
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-09-19 20:49:33 +02:00
callback ( "" ) ;
}
} ) ;
} ;
2021-10-14 16:51:23 +02:00
if ( authKeys . itranslate && authKeys . itranslate . key || data . engine . APIkey ) translate ( ) ;
2021-05-12 14:33:47 +02:00
else BDFDB . LibraryRequires . request ( "https://www.itranslate.com/js/webapp/main.js" , { gzip : true } , ( error , response , body ) => {
if ( ! error && body ) {
let APIkey = /var API_KEY = "(.+)"/ . exec ( body ) ;
2020-09-19 20:49:33 +02:00
if ( APIkey ) {
data . engine . APIkey = APIkey [ 1 ] ;
translate ( ) ;
2019-12-10 13:21:59 +01:00
}
2020-09-19 20:49:33 +02:00
else callback ( "" ) ;
2019-12-10 13:21:59 +01:00
}
2020-02-04 08:20:40 +01:00
else callback ( "" ) ;
2020-09-19 20:49:33 +02:00
} ) ;
}
yandexTranslate ( data , callback ) {
2021-10-14 16:51:23 +02:00
BDFDB . LibraryRequires . request ( ` https://translate.yandex.net/api/v1.5/tr/translate?key= ${ authKeys . yandex && authKeys . yandex . key || "trnsl.1.1.20191206T223907Z.52bd512eca953a5b.1ec123ce4dcab3ae859f312d27cdc8609ab280de" } &text= ${ encodeURIComponent ( data . text ) } &lang= ${ data . specialCase || data . input . auto ? data . output . id : ( data . input . id + "-" + data . output . id ) } &options=1 ` , ( error , response , body ) => {
2021-05-12 14:33:47 +02:00
if ( ! error && body && response . statusCode == 200 ) {
2021-08-05 14:06:44 +02:00
try {
body = BDFDB . DOMUtils . create ( body ) ;
let translation = body . querySelector ( "text" ) ;
let detected = body . querySelector ( "detected" ) ;
if ( translation && detected ) {
let detectedLang = detected . getAttribute ( "lang" ) ;
if ( ! data . specialCase && detectedLang && languages [ detectedLang ] ) {
data . input . name = languages [ detectedLang ] . name ;
data . input . ownlang = languages [ detectedLang ] . ownlang ;
}
callback ( translation . innerText ) ;
2020-09-19 20:49:33 +02:00
}
2021-08-05 14:06:44 +02:00
else callback ( "" ) ;
2020-09-19 20:49:33 +02:00
}
2021-08-05 14:06:44 +02:00
catch ( err ) { callback ( "" ) ; }
2020-12-14 10:43:32 +01:00
}
2021-08-05 14:06:44 +02:00
else if ( body && body . indexOf ( 'code="408"' ) > - 1 ) {
2021-05-12 14:33:47 +02:00
BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Monthly Request Limit reached. ` , {
2021-01-26 21:14:48 +01:00
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-12-14 10:43:32 +01:00
callback ( "" ) ;
2020-06-26 22:42:48 +02:00
}
2020-09-19 20:49:33 +02:00
else {
2021-05-12 14:33:47 +02:00
BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server down or API-Key outdated. ` , {
2021-01-26 21:14:48 +01:00
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-09-19 20:49:33 +02:00
callback ( "" ) ;
}
} ) ;
}
papagoTranslate ( data , callback ) {
2021-10-14 16:51:23 +02:00
const credentials = ( authKeys . papago && authKeys . papago . key || "kUNGxtAmTJQFbaFehdjk zC70k3VhpM" ) . split ( " " ) ;
2020-09-19 20:49:33 +02:00
BDFDB . LibraryRequires . request . post ( {
2020-11-19 16:45:36 +01:00
url : "https://openapi.naver.com/v1/papago/n2mt" ,
2020-09-19 20:49:33 +02:00
form : {
source : data . input . id ,
target : data . output . id ,
text : data . text
} ,
headers : {
2021-06-06 13:49:58 +02:00
"X-Naver-Client-Id" : credentials [ 0 ] ,
"X-Naver-Client-Secret" : credentials [ 1 ]
2020-09-19 20:49:33 +02:00
}
2021-05-12 14:33:47 +02:00
} , ( error , response , body ) => {
if ( ! error && body && response . statusCode == 200 ) {
2020-09-19 20:49:33 +02:00
try {
2021-05-12 14:33:47 +02:00
let message = ( JSON . parse ( body ) || { } ) . message ;
2021-06-06 13:49:58 +02:00
let result = message && ( message . body || message . result ) ;
if ( result && result . translatedText ) callback ( result . translatedText ) ;
2020-09-19 20:49:33 +02:00
else callback ( "" ) ;
}
catch ( err ) { callback ( "" ) ; }
}
else {
2021-04-07 16:36:21 +02:00
if ( response . statusCode == 429 ) BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Request Limit per Hour is reached. ` , {
type : "danger" ,
position : "center"
} ) ;
else BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server is down or API-key outdated. ` , {
2021-01-26 21:14:48 +01:00
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-09-19 20:49:33 +02:00
callback ( "" ) ;
}
} ) ;
}
2021-08-05 14:06:44 +02:00
baiduTranslate ( data , callback ) {
2021-10-14 16:51:23 +02:00
const credentials = ( authKeys . baidu && authKeys . baidu . key || "20210425000799880 e12h9h4rh39r8h12r8 D90usZcbznwthzKC1KOb" ) . split ( " " ) ;
2021-08-05 14:06:44 +02:00
BDFDB . LibraryRequires . request . post ( {
url : "https://fanyi-api.baidu.com/api/trans/vip/translate" ,
form : {
from : translationEngines . baidu . parser [ data . input . id ] || data . input . id ,
to : translationEngines . baidu . parser [ data . output . id ] || data . output . id ,
q : data . text ,
appid : credentials [ 0 ] ,
salt : credentials [ 1 ] ,
sign : this . MD5 ( credentials [ 0 ] + data . text + credentials [ 1 ] + credentials [ 2 ] )
}
} , ( error , response , result ) => {
if ( ! error && result && response . statusCode == 200 ) {
try {
result = JSON . parse ( result ) || { } ;
if ( ! result . error _code ) {
let messages = result . trans _result ;
if ( messages && messages . length > 0 && result . from != result . to ) callback ( messages . map ( message => decodeURIComponent ( message . dst ) ) . join ( "\n" ) ) ;
else { callback ( "" ) ; }
}
else {
BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . ${ result . error _code } : ${ result . error _msg } . ` , {
type : "danger" ,
position : "center"
} ) ;
callback ( "" ) ;
}
}
catch ( err ) { callback ( "" ) ; }
}
else {
BDFDB . NotificationUtils . toast ( ` ${ this . labels . toast _translating _failed } . ${ this . labels . toast _translating _tryanother } . Translation Server is down. ` , {
type : "danger" ,
position : "center"
} ) ;
callback ( "" ) ;
}
} ) ;
}
MD5 ( e ) {
function h ( a , b ) {
var e = a & 2147483648 , f = b & 2147483648 , c = a & 1073741824 , d = b & 1073741824 , g = ( a & 1073741823 ) + ( b & 1073741823 ) ;
return c & d ? g ^ 2147483648 ^ e ^ f : c | d ? g & 1073741824 ? g ^ 3221225472 ^ e ^ f : g ^ 1073741824 ^ e ^ f : g ^ e ^ f
}
function k ( a , b , c , d , e , f , g ) {
a = h ( a , h ( h ( b & c | ~ b & d , e ) , g ) ) ;
return h ( a << f | a >>> 32 - f , b ) ;
}
function l ( a , b , c , d , e , f , g ) {
a = h ( a , h ( h ( b & d | c & ~ d , e ) , g ) ) ;
return h ( a << f | a >>> 32 - f , b ) ;
}
function m ( a , b , d , c , e , f , g ) {
a = h ( a , h ( h ( b ^ d ^ c , e ) , g ) ) ;
return h ( a << f | a >>> 32 - f , b )
}
function n ( a , b , d , c , e , f , g ) {
a = h ( a , h ( h ( d ^ ( b | ~ c ) , e ) , g ) ) ;
return h ( a << f | a >>> 32 - f , b ) ;
}
function p ( a ) {
var b = "" , d = "" , c ;
for ( c = 0 ; 3 >= c ; c ++ ) d = a >>> 8 * c & 255 , d = "0" + d . toString ( 16 ) , b += d . substr ( d . length - 2 , 2 ) ;
return b ;
}
var f = [ ] , q , r , s , t , a , b , c , d ;
e = function ( a ) {
a = a . replace ( /\r\n/g , "\n" ) ;
for ( var b = "" , d = 0 ; d < a . length ; d ++ ) {
var c = a . charCodeAt ( d ) ;
128 > c ? b += String . fromCharCode ( c ) : ( 127 < c && 2048 > c ? b += String . fromCharCode ( c >> 6 | 192 ) : ( b += String . fromCharCode ( c >> 12 | 224 ) , b += String . fromCharCode ( c >> 6 & 63 | 128 ) ) , b += String . fromCharCode ( c & 63 | 128 ) )
}
return b ;
} ( e ) ;
f = function ( b ) {
var a , c = b . length ;
a = c + 8 ;
for ( var d = 16 * ( ( a - a % 64 ) / 64 + 1 ) , e = Array ( d - 1 ) , f = 0 , g = 0 ; g < c ; ) a = ( g - g % 4 ) / 4 , f = g % 4 * 8 , e [ a ] |= b . charCodeAt ( g ) << f , g ++ ;
a = ( g - g % 4 ) / 4 ;
e [ a ] |= 128 << g % 4 * 8 ;
e [ d - 2 ] = c << 3 ;
e [ d - 1 ] = c >>> 29 ;
return e
} ( e ) ;
a = 1732584193 , b = 4023233417 , c = 2562383102 , d = 271733878 ;
for ( e = 0 ; e < f . length ; e += 16 ) q = a , r = b , s = c , t = d , a = k ( a , b , c , d , f [ e + 0 ] , 7 , 3614090360 ) , d = k ( d , a , b , c , f [ e + 1 ] , 12 , 3905402710 ) , c = k ( c , d , a , b , f [ e + 2 ] , 17 , 606105819 ) , b = k ( b , c , d , a , f [ e + 3 ] , 22 , 3250441966 ) , a = k ( a , b , c , d , f [ e + 4 ] , 7 , 4118548399 ) , d = k ( d , a , b , c , f [ e + 5 ] , 12 , 1200080426 ) , c = k ( c , d , a , b , f [ e + 6 ] , 17 , 2821735955 ) , b = k ( b , c , d , a , f [ e + 7 ] , 22 , 4249261313 ) , a = k ( a , b , c , d , f [ e + 8 ] , 7 , 1770035416 ) , d = k ( d , a , b , c , f [ e + 9 ] , 12 , 2336552879 ) , c = k ( c , d , a , b , f [ e + 10 ] , 17 , 4294925233 ) , b = k ( b , c , d , a , f [ e + 11 ] , 22 , 2304563134 ) , a = k ( a , b , c , d , f [ e + 12 ] , 7 , 1804603682 ) , d = k ( d , a , b , c , f [ e + 13 ] , 12 , 4254626195 ) , c = k ( c , d , a , b , f [ e + 14 ] , 17 , 2792965006 ) , b = k ( b , c , d , a , f [ e + 15 ] , 22 , 1236535329 ) , a = l ( a , b , c , d , f [ e + 1 ] , 5 , 4129170786 ) , d = l ( d , a , b , c , f [ e + 6 ] , 9 , 3225465664 ) , c = l ( c , d , a , b , f [ e + 11 ] , 14 , 643717713 ) , b = l ( b , c , d , a , f [ e + 0 ] , 20 , 3921069994 ) , a = l ( a , b , c , d , f [ e + 5 ] , 5 , 3593408605 ) , d = l ( d , a , b , c , f [ e + 10 ] , 9 , 38016083 ) , c = l ( c , d , a , b , f [ e + 15 ] , 14 , 3634488961 ) , b = l ( b , c , d , a , f [ e + 4 ] , 20 , 3889429448 ) , a = l ( a , b , c , d , f [ e + 9 ] , 5 , 568446438 ) , d = l ( d , a , b , c , f [ e + 14 ] , 9 , 3275163606 ) , c = l ( c , d , a , b , f [ e + 3 ] , 14 , 4107603335 ) , b = l ( b , c , d , a , f [ e + 8 ] , 20 , 1163531501 ) , a = l ( a , b , c , d , f [ e + 13 ] , 5 , 2850285829 ) , d = l ( d , a , b , c , f [ e + 2 ] , 9 , 4243563512 ) , c = l ( c , d , a , b , f [ e + 7 ] , 14 , 1735328473 ) , b = l ( b , c , d , a , f [ e + 12 ] , 20 , 2368359562 ) , a = m ( a , b , c , d , f [ e + 5 ] , 4 , 4294588738 ) , d = m ( d , a , b , c , f [ e + 8 ] , 11 , 2272392833 ) , c = m ( c , d , a , b , f [ e + 11 ] , 16 , 1839030562 ) , b = m ( b , c , d , a , f [ e + 14 ] , 23 , 4259657740 ) , a = m ( a , b , c , d , f [ e + 1 ] , 4 , 2763975236 ) , d = m ( d , a , b , c , f [ e + 4 ] , 11 , 1272893353 ) , c = m ( c , d , a , b , f [ e + 7 ] , 16 , 4139469664 ) , b = m ( b , c , d , a , f [ e + 10 ] , 23 , 3200236656 ) , a = m ( a , b , c , d , f [ e + 13 ] , 4 , 681279174 ) , d = m ( d , a , b , c , f [ e + 0 ] , 11 , 3936430074 ) , c = m ( c , d , a , b , f [ e + 3 ] , 16 , 3572445317 ) , b = m ( b , c , d , a , f [ e + 6 ] , 23 , 76029189 ) , a = m ( a , b , c , d , f [ e + 9 ] , 4 , 3654602809 ) , d = m ( d , a , b , c , f [ e + 12 ] , 11 , 3873151461 ) , c = m ( c , d , a , b , f [ e + 15 ] , 16 , 530742520 ) , b = m ( b , c , d , a , f [ e + 2 ] , 23 , 3299628645 ) , a = n ( a , b , c , d , f [ e + 0 ] , 6 , 4096336452 ) , d = n ( d , a , b , c , f [ e + 7 ] , 10 , 1126891415 ) , c = n ( c , d , a , b , f [ e + 14 ] , 15 , 2878612391 ) , b = n ( b , c , d , a , f [ e + 5 ] , 21 , 4237533241 ) , a = n ( a , b , c , d , f [ e + 12 ] , 6 , 1700485571 ) , d = n ( d , a , b , c , f [ e + 3 ] , 10 , 2399980690 ) , c = n ( c , d , a , b , f [ e + 10 ] , 15 , 4293915773 ) , b = n ( b , c , d , a , f [ e + 1 ] , 21 , 2240044497 ) , a = n ( a , b , c , d , f [ e + 8 ] , 6 , 1873313359 ) , d = n ( d , a , b , c , f [ e + 15 ] , 10 , 4264355552 ) , c = n ( c , d , a , b , f [ e + 6 ] , 15 , 2734768916 ) , b = n ( b , c , d , a , f [ e + 13 ] , 21 , 1309151649 ) , a = n ( a , b , c , d , f [ e + 4 ] , 6 , 4149444226 ) , d = n ( d , a , b , c , f [ e + 11 ] , 10 , 3174756917 ) , c = n ( c , d , a , b , f [ e + 2 ] , 15 , 718787259 ) , b = n ( b , c , d , a , f [ e + 9 ] , 21 , 3951481745 ) , a = h ( a , q ) , b = h ( b , r ) , c = h ( c , s ) , d = h ( d , t ) ;
return ( p ( a ) + p ( b ) + p ( c ) + p ( d ) ) . toLowerCase ( ) ;
}
2020-02-04 08:20:40 +01:00
2020-09-19 20:49:33 +02:00
checkForSpecialCase ( text , input ) {
2021-05-12 18:41:59 +02:00
if ( input . special ) return input ;
else if ( input . auto ) {
2020-09-19 20:49:33 +02:00
if ( /^[0-1]*$/ . test ( text . replace ( /\s/g , "" ) ) ) {
return { id : "binary" , name : "Binary" } ;
}
else if ( /^[⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿]*$/ . test ( text . replace ( /\s/g , "" ) ) ) {
return { id : "braille" , name : "Braille 6-dot" } ;
}
else if ( /^[/|·−._-]*$/ . test ( text . replace ( /\s/g , "" ) ) ) {
return { id : "morse" , name : "Morse" } ;
}
2019-12-10 13:21:59 +01:00
}
2020-09-19 20:49:33 +02:00
return null ;
2019-04-16 00:30:33 +02:00
}
2020-09-19 20:49:33 +02:00
string2binary ( string ) {
let binary = "" ;
for ( let character of string ) binary += parseInt ( character . charCodeAt ( 0 ) . toString ( 2 ) ) . toPrecision ( 8 ) . split ( "." ) . reverse ( ) . join ( "" ) . toString ( ) + " " ;
return binary ;
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
string2braille ( string ) {
let braille = "" ;
for ( let character of string ) braille += brailleConverter [ character . toLowerCase ( ) ] ? brailleConverter [ character . toLowerCase ( ) ] : character ;
return braille ;
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
string2morse ( string ) {
string = string . replace ( / /g , "%%%%%%%%%%" ) ;
let morse = "" ;
for ( let character of string ) morse += ( morseConverter [ character . toLowerCase ( ) ] ? morseConverter [ character . toLowerCase ( ) ] : character ) + " " ;
morse = morse . split ( "\n" ) ;
for ( let i in morse ) morse [ i ] = morse [ i ] . trim ( ) ;
return morse . join ( "\n" ) . replace ( /% % % % % % % % % % /g , "/ " ) ;
}
2019-04-16 00:30:33 +02:00
2020-09-19 20:49:33 +02:00
binary2string ( binary ) {
let string = "" ;
binary = binary . replace ( /\n/g , "00001010" ) . replace ( /\r/g , "00001101" ) . replace ( /\t/g , "00001001" ) . replace ( /\s/g , "" ) ;
if ( /^[0-1]*$/ . test ( binary ) ) {
2021-01-28 14:45:45 +01:00
let eightDigits = "" ;
2020-09-19 20:49:33 +02:00
let counter = 0 ;
for ( let digit of binary ) {
2021-01-28 14:45:45 +01:00
eightDigits += digit ;
2020-09-19 20:49:33 +02:00
counter ++ ;
if ( counter > 7 ) {
2021-01-28 14:45:45 +01:00
string += String . fromCharCode ( parseInt ( eightDigits , 2 ) . toString ( 10 ) ) ;
eightDigits = "" ;
2020-09-19 20:49:33 +02:00
counter = 0 ;
}
2020-02-04 08:20:40 +01:00
}
2019-04-16 00:30:33 +02:00
}
2021-01-26 21:14:48 +01:00
else BDFDB . NotificationUtils . toast ( "Invalid binary format. Only use 0s and 1s." , {
type : "danger" ,
2021-01-28 14:11:00 +01:00
position : "center"
2021-01-26 21:14:48 +01:00
} ) ;
2020-09-19 20:49:33 +02:00
return string ;
2019-04-16 00:30:33 +02:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
braille2string ( braille ) {
let string = "" ;
for ( let character of braille ) string += brailleConverter [ character . toLowerCase ( ) ] ? brailleConverter [ character . toLowerCase ( ) ] : character ;
return string ;
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
morse2string ( morse ) {
let string = "" ;
for ( let word of morse . replace ( /[_-]/g , "− " ) . replace ( /\./g , "·" ) . replace ( /\r|\t/g , "" ) . split ( /\/|\||\n/g ) ) {
for ( let characterstr of word . trim ( ) . split ( " " ) ) string += morseConverter [ characterstr ] ? morseConverter [ characterstr ] : characterstr ;
string += " " ;
}
return string . trim ( ) ;
2018-10-11 10:21:26 +02:00
}
2020-02-04 08:20:40 +01:00
2020-10-31 11:43:29 +01:00
addExceptions ( string , excepts ) {
for ( let count in excepts ) {
2021-03-20 18:50:17 +01:00
let exception = BDFDB . ArrayUtils . is ( this . settings . exceptions . wordStart ) && this . settings . exceptions . wordStart . some ( n => excepts [ count ] . indexOf ( n ) == 0 ) ? excepts [ count ] . slice ( 1 ) : excepts [ count ] ;
2021-02-04 14:45:34 +01:00
let newString = string . replace ( new RegExp ( BDFDB . StringUtils . regEscape ( ` {{ ${ count } }} ` ) ) , exception ) ;
if ( newString == string ) string = newString + " " + exception ;
else string = newString ;
2019-01-02 23:28:11 +01:00
}
2020-09-19 20:49:33 +02:00
return string ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
2021-06-01 16:17:59 +02:00
removeExceptions ( string , place ) {
2020-10-31 11:43:29 +01:00
let excepts = { } , newString = [ ] , count = 0 ;
2021-06-01 16:17:59 +02:00
if ( place == messageTypes . RECEIVED ) {
2020-09-19 20:49:33 +02:00
let text = [ ] , i = 0 ;
string . split ( "" ) . forEach ( chara => {
if ( chara == "<" && text [ i ] ) i ++ ;
text [ i ] = text [ i ] ? text [ i ] + chara : chara ;
if ( chara == ">" ) i ++ ;
} ) ;
for ( let j in text ) {
if ( text [ j ] . indexOf ( "<" ) == 0 ) {
2021-02-04 14:45:34 +01:00
newString . push ( ` {{ ${ count } }} ` ) ;
2020-10-31 11:43:29 +01:00
excepts [ count ] = text [ j ] ;
2020-09-19 20:49:33 +02:00
count ++ ;
}
else newString . push ( text [ j ] ) ;
2020-02-04 08:20:40 +01:00
}
2020-09-19 20:49:33 +02:00
}
else {
2021-03-20 18:50:17 +01:00
let usedExceptions = BDFDB . ArrayUtils . is ( this . settings . exceptions . wordStart ) ? this . settings . exceptions . wordStart : [ ] ;
2020-09-19 20:49:33 +02:00
string . split ( " " ) . forEach ( word => {
2021-03-22 10:05:26 +01:00
if ( word . indexOf ( "<@!" ) == 0 || word . indexOf ( "<#" ) == 0 || word . indexOf ( ":" ) == 0 || word . indexOf ( "<:" ) == 0 || word . indexOf ( "<a:" ) == 0 || word . indexOf ( "@" ) == 0 || word . indexOf ( "#" ) == 0 || usedExceptions . some ( n => word . indexOf ( n ) == 0 && word . length > 1 ) ) {
2021-02-04 14:45:34 +01:00
newString . push ( ` {{ ${ count } }} ` ) ;
2020-10-31 11:43:29 +01:00
excepts [ count ] = word ;
2020-09-19 20:49:33 +02:00
count ++ ;
}
else newString . push ( word ) ;
} ) ;
}
2020-10-31 11:43:29 +01:00
return [ newString . join ( " " ) , excepts , newString . length - count != 0 ] ;
2020-02-04 08:20:40 +01:00
}
2019-01-26 22:45:19 +01:00
2020-09-19 20:49:33 +02:00
getGoogleTranslatePageURL ( input , output , text ) {
2020-11-19 16:45:36 +01:00
return ` https://translate.google.com/# ${ BDFDB . LanguageUtils . languages [ input ] ? input : "auto" } / ${ output } / ${ encodeURIComponent ( text ) } ` ;
2020-09-19 20:49:33 +02:00
}
2020-07-26 17:02:25 +02:00
2021-01-06 12:38:36 +01:00
setLabelsByLanguage ( ) {
2020-09-19 20:49:33 +02:00
switch ( BDFDB . LanguageUtils . getLanguage ( ) . id ) {
2020-12-21 19:56:36 +01:00
case "bg" : // Bulgarian
return {
2021-08-10 15:47:10 +02:00
context _translator : "Търсене превод" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Превод на съобщението" ,
context _messageuntranslateoption : "Превод на съобщението" ,
popout _translateoption : "Превод" ,
popout _untranslateoption : "Непревод" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Превод" ,
toast _translating _failed : "Преводът не б е успешен" ,
toast _translating _tryanother : "Опитайте друг преводач" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "преведено"
} ;
case "da" : // Danish
return {
2021-08-10 15:47:10 +02:00
context _translator : "Søg oversættelse" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Oversæt besked" ,
context _messageuntranslateoption : "Ikke-oversat besked" ,
popout _translateoption : "Oversætte" ,
popout _untranslateoption : "Untranslate" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Oversætter" ,
toast _translating _failed : "Kunne ikke oversætte" ,
toast _translating _tryanother : "Prøv en anden oversætter" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "oversat"
} ;
case "de" : // German
return {
2021-08-10 15:47:10 +02:00
context _translator : "Übersetzung suchen" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Nachricht übersetzen" ,
context _messageuntranslateoption : "Nachricht unübersetzen" ,
popout _translateoption : "Übersetzen" ,
popout _untranslateoption : "Unübersetzen" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Übersetzen" ,
toast _translating _failed : "Übersetzung fehlgeschlagen" ,
toast _translating _tryanother : "Versuch einen anderen Übersetzer" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "übersetzt"
} ;
case "el" : // Greek
return {
2021-08-10 15:47:10 +02:00
context _translator : "Αναζήτηση μετάφρασης" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Μετάφραση μηνύματος" ,
context _messageuntranslateoption : "Μη μετάφραση μηνύματος" ,
popout _translateoption : "Μεταφράζω" ,
popout _untranslateoption : "Μη μετάφραση" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Μετάφραση" ,
toast _translating _failed : "Αποτυχία μετάφρασης" ,
toast _translating _tryanother : "Δοκιμάστε έναν άλλο Μεταφραστή" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "μεταφρασμένο"
} ;
case "es" : // Spanish
return {
2021-08-10 15:47:10 +02:00
context _translator : "Buscar traducción" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Traducir mensaje" ,
context _messageuntranslateoption : "Mensaje sin traducir" ,
popout _translateoption : "Traducir" ,
popout _untranslateoption : "No traducir" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Traductorio" ,
toast _translating _failed : "No se pudo traducir" ,
toast _translating _tryanother : "Prueba con otro traductor" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "traducido"
} ;
case "fi" : // Finnish
return {
2021-08-10 15:47:10 +02:00
context _translator : "Hae käännöstä" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Käännä viesti" ,
context _messageuntranslateoption : "Käännä viesti" ,
popout _translateoption : "Kääntää" ,
popout _untranslateoption : "Käännä" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Kääntäminen" ,
toast _translating _failed : "Käännös epäonnistui" ,
toast _translating _tryanother : "Kokeile toista kääntäjää" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "käännetty"
} ;
case "fr" : // French
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Recherche de traduction" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Traduire le message" ,
context _messageuntranslateoption : "Message non traduit" ,
popout _translateoption : "Traduire" ,
popout _untranslateoption : "Non traduit" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Traduction en cours" ,
toast _translating _failed : "Échec de la traduction" ,
toast _translating _tryanother : "Essayez un autre traducteur" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "traduit"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "hr" : // Croatian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Pretraži prijevod" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Prevedi poruku" ,
context _messageuntranslateoption : "Prevedi poruku" ,
popout _translateoption : "Prevedi" ,
popout _untranslateoption : "Neprevedi" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Prevođenje" ,
toast _translating _failed : "Prijevod nije uspio" ,
toast _translating _tryanother : "Pokušajte s drugim prevoditeljem" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "prevedeno"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "hu" : // Hungarian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Keresés a fordításban" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Üzenet lefordítása" ,
context _messageuntranslateoption : "Az üzenet lefordítása" ,
popout _translateoption : "fordít" ,
popout _untranslateoption : "Fordítás le" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Fordítás" ,
toast _translating _failed : "Nem sikerült lefordítani" ,
toast _translating _tryanother : "Próbálkozzon másik fordítóval" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "lefordított"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "it" : // Italian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Cerca traduzione" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Traduci messaggio" ,
context _messageuntranslateoption : "Annulla traduzione messaggio" ,
popout _translateoption : "Tradurre" ,
popout _untranslateoption : "Non tradurre" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Tradurre" ,
toast _translating _failed : "Impossibile tradurre" ,
toast _translating _tryanother : "Prova un altro traduttore" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "tradotto"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ja" : // Japanese
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "翻訳を検索" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "メッセージの翻訳" ,
context _messageuntranslateoption : "メッセージの翻訳解除" ,
popout _translateoption : "翻訳する" ,
popout _untranslateoption : "翻訳しない" ,
2021-01-26 21:14:48 +01:00
toast _translating : "翻訳" ,
toast _translating _failed : "翻訳に失敗しました" ,
toast _translating _tryanother : "別の翻訳者を試す" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "翻訳済み"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ko" : // Korean
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "번역 검색" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "메시지 번역" ,
context _messageuntranslateoption : "메시지 번역 취소" ,
popout _translateoption : "옮기다" ,
popout _untranslateoption : "번역 취소" ,
2021-01-26 21:14:48 +01:00
toast _translating : "번역 중" ,
toast _translating _failed : "번역하지 못했습니다." ,
toast _translating _tryanother : "다른 번역기 시도" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "번역"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "lt" : // Lithuanian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Paieškos vertimas" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Versti pranešimą" ,
context _messageuntranslateoption : "Išversti pranešimą" ,
popout _translateoption : "Išversti" ,
popout _untranslateoption : "Neišversti" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Vertimas" ,
toast _translating _failed : "Nepavyko išversti" ,
toast _translating _tryanother : "Išbandykite kitą vertėją" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "išverstas"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "nl" : // Dutch
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Zoek vertaling" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Bericht vertalen" ,
context _messageuntranslateoption : "Bericht onvertalen" ,
popout _translateoption : "Vertalen" ,
popout _untranslateoption : "Onvertalen" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Vertalen" ,
toast _translating _failed : "Kan niet vertalen" ,
toast _translating _tryanother : "Probeer een andere vertaler" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "vertaald"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "no" : // Norwegian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Søk i oversettelse" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Oversett melding" ,
context _messageuntranslateoption : "Ikke oversett melding" ,
popout _translateoption : "Oversette" ,
popout _untranslateoption : "Ikke oversett" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Oversetter" ,
toast _translating _failed : "Kunne ikke oversette" ,
toast _translating _tryanother : "Prøv en annen oversetter" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "oversatt"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pl" : // Polish
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Wyszukaj tłumaczenie" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Przetłumacz wiadomość" ,
context _messageuntranslateoption : "Nieprzetłumacz wiadomość" ,
popout _translateoption : "Tłumaczyć" ,
popout _untranslateoption : "Nie przetłumacz" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Tłumaczenie" ,
toast _translating _failed : "Nie udało się przetłumaczyć" ,
toast _translating _tryanother : "Wypróbuj innego tłumacza" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "przetłumaczony"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "pt-BR" : // Portuguese (Brazil)
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Tradução de pesquisa" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Traduzir mensagem" ,
context _messageuntranslateoption : "Mensagem não traduzida" ,
popout _translateoption : "Traduzir" ,
popout _untranslateoption : "Não traduzido" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Traduzindo" ,
toast _translating _failed : "Falha ao traduzir" ,
toast _translating _tryanother : "Tente outro tradutor" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "traduzido"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ro" : // Romanian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Căutare traducere" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Traduceți mesajul" ,
context _messageuntranslateoption : "Untraduceți mesajul" ,
popout _translateoption : "Traduceți" ,
popout _untranslateoption : "Netradus" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Traducere" ,
toast _translating _failed : "Nu s-a putut traduce" ,
toast _translating _tryanother : "Încercați un alt traducător" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "tradus"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "ru" : // Russian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Искать перевод" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Перевести сообщение" ,
context _messageuntranslateoption : "Непереведенное сообщение" ,
popout _translateoption : "Переведите" ,
popout _untranslateoption : "Неперевести" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Идет перевод" ,
toast _translating _failed : "Н е удалось перевести" ,
toast _translating _tryanother : "Попробуйте другой переводчик" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "переведено"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "sv" : // Swedish
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Sök översättning" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Översätt meddelande" ,
context _messageuntranslateoption : "Untranslate meddelande" ,
popout _translateoption : "Översätt" ,
popout _untranslateoption : "Untranslate" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Översätter" ,
toast _translating _failed : "Det gick inte att översätta" ,
toast _translating _tryanother : "Prova en annan översättare" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "översatt"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "th" : // Thai
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "ค้นหาคำแปล" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "แปลข้อความ" ,
context _messageuntranslateoption : "ยกเลิกการแปลข้อความ" ,
popout _translateoption : "แปลภาษา" ,
popout _untranslateoption : "ไม่แปล" ,
2021-01-26 21:14:48 +01:00
toast _translating : "กำลังแปล" ,
toast _translating _failed : "แปลไม่สำเร็จ" ,
toast _translating _tryanother : "ลองใช้นักแปลคนอื่น" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "แปล"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "tr" : // Turkish
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Çeviri ara" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Mesajı Çevir" ,
context _messageuntranslateoption : "Çeviriyi Kaldı r Mesajı " ,
popout _translateoption : "Çevirmek" ,
popout _untranslateoption : "Çevirmeyi kaldı r" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Çeviri" ,
toast _translating _failed : "Tercüme edilemedi" ,
toast _translating _tryanother : "Başka bir Çevirmen deneyin" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "tercüme"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "uk" : // Ukrainian
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Пошук перекладу" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Перекласти повідомлення" ,
context _messageuntranslateoption : "Неперекладене повідомлення" ,
popout _translateoption : "Перекласти" ,
popout _untranslateoption : "Неперекласти" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Переклад" ,
toast _translating _failed : "Н е вдалося перекласти" ,
toast _translating _tryanother : "Спробуйте іншого перекладача" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "переклав"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
case "vi" : // Vietnamese
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Tìm kiếm bản dịch" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Dịch tin nhắn" ,
context _messageuntranslateoption : "Thư chưa dịch" ,
popout _translateoption : "Phiên dịch" ,
popout _untranslateoption : "Chưa dịch" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Phiên dịch" ,
toast _translating _failed : "Không dịch được" ,
toast _translating _tryanother : "Thử một Trình dịch khác" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "đã dịch"
2020-09-19 20:49:33 +02:00
} ;
2021-01-15 17:54:22 +01:00
case "zh-CN" : // Chinese (China)
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "搜索翻译" ,
2021-01-15 17:56:14 +01:00
context _messagetranslateoption : "翻译消息" ,
context _messageuntranslateoption : "取消翻译消息" ,
2020-12-21 19:56:36 +01:00
popout _translateoption : "翻译" ,
popout _untranslateoption : "取消翻译" ,
2021-01-26 21:14:48 +01:00
toast _translating : "正在翻译" ,
toast _translating _failed : "翻译失败" ,
2021-12-15 21:44:54 +01:00
toast _translating _tryanother : "尝试其它翻译器" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "已翻译"
2020-09-19 20:49:33 +02:00
} ;
2021-01-15 17:54:22 +01:00
case "zh-TW" : // Chinese (Taiwan)
2020-09-19 20:49:33 +02:00
return {
2021-12-15 21:44:54 +01:00
context _translator : "搜尋翻譯" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "翻譯訊息" ,
2021-01-15 17:54:22 +01:00
context _messageuntranslateoption : "取消翻譯訊息" ,
2020-12-21 19:56:36 +01:00
popout _translateoption : "翻譯" ,
popout _untranslateoption : "取消翻譯" ,
2021-01-26 21:14:48 +01:00
toast _translating : "正在翻譯" ,
2021-12-15 21:44:54 +01:00
toast _translating _failed : "無法翻譯" ,
toast _translating _tryanother : "嘗試其它翻譯器" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "已翻譯"
2020-09-19 20:49:33 +02:00
} ;
2020-12-21 19:56:36 +01:00
default : // English
2020-09-19 20:49:33 +02:00
return {
2021-08-10 15:47:10 +02:00
context _translator : "Search Translation" ,
2020-12-21 19:56:36 +01:00
context _messagetranslateoption : "Translate Message" ,
context _messageuntranslateoption : "Untranslate Message" ,
popout _translateoption : "Translate" ,
popout _untranslateoption : "Untranslate" ,
2021-01-26 21:14:48 +01:00
toast _translating : "Translating" ,
toast _translating _failed : "Failed to translate" ,
toast _translating _tryanother : "Try another Translator" ,
2020-12-21 19:56:36 +01:00
translated _watermark : "translated"
2020-09-19 20:49:33 +02:00
} ;
}
}
} ;
2020-10-09 21:09:35 +02:00
} ) ( window . BDFDB _Global . PluginUtils . buildPlugin ( config ) ) ;
2022-01-30 23:49:21 +01:00
} ) ( ) ;