// ==UserScript==
// @name         繁簡自由切換
// @name:zh-CN   简繁自由切换
// @name:ja      簡繁切替
// @name:en      Switch Traditional Chinese and Simplified Chinese
// @namespace    hoothin
// @supportURL   https://github.com/hoothin/UserScripts
// @homepageURL  https://github.com/hoothin/UserScripts
// @version      1.2.7.10
// @description        任意轉換網頁中的簡體中文與正體中文（默認簡體→正體），顯示漢字對應漢語拼音，自訂任意替換文本
// @description:zh-CN  任意转换网页中的简体中文与繁体中文（默认繁体→简体），显示汉字对应汉语拼音，自定义任意替换文本
// @description:ja     ウェブページ上の簡体字中国語と繁体字中国語を自由に変換し、中国語の文字にひらがなを表示し、任意の文字を置き換えることができます。
// @description:en     Convert between simplified and traditional Chinese characters on any webpage, display the Pinyin for the Chinese characters, customize text replacement.
// @author       hoothin
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @grant        GM_notification
// @grant        GM_listValues
// @grant        GM_deleteValue
// @grant        GM_openInTab
// @grant        GM_getResourceText
// @grant        GM_info
// @grant        GM.setValue
// @grant        GM.getValue
// @grant        GM.registerMenuCommand
// @grant        GM.notification
// @grant        GM.listValues
// @grant        GM.deleteValue
// @grant        GM.openInTab
// @grant        GM.getResourceText
// @grant        GM.info
// @grant        unsafeWindow
// @resource pinyinTree        https://hoothin.github.io/UserScripts/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/pinyinTree.json
// @contributionURL      https://ko-fi.com/hoothin
// @contributionAmount 1
// @downloadURL https://update.greasyfork.org/scripts/24300/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese.user.js
// @updateURL https://update.greasyfork.org/scripts/24300/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese.meta.js
// ==/UserScript==
//因一簡對多繁，所以簡轉繁需要優先排除異體字，並根據詞彙轉換。其他需要語義分析的，暫時無解。整理繁簡對照表很費時，因此不打臉的話不再更新，如有需求，刪減自用。更精細的需求可自行申請相應API或自行訓練語義AI並搭建對照數據庫。在油猴脚本裏面如此這般折騰，我是覺得沒有意義啦。。。
(function() {
    'use strict';
    if (window.stcascInited) return;
    if (window.top != window.self) {
        try {
            if (window.self.innerWidth < 300 || window.self.innerHeight < 300) {
                return;
            }
        } catch(e) {
            return;
        }
    }
    window.stcascInited = true;
    var auto = false;
    var notification = true;
    var shortcutKey = 'F8';
    var ctrlKey = true;
    var altKey = false;
    var shiftKey = false;
    var metaKey = false;
    var pinyinShortcutKey = 'F8';
    var pinyinCtrlKey = false;
    var pinyinAltKey = true;
    var pinyinShiftKey = false;
    var pinyinMetaKey = false;
    var disablePinyin = false;
    //此處為單字轉換，scStr 為簡體字列表，tcStr 為正體字列表，一簡對多繁時，可能有多個對應組合，以第一個組合爲準
    const scStr = '万与丑专业丛东丝丢两严丧个丰临为为丽举么么义乌乐乔习乡书买乱争于亏云亘亚产产亩亲亵亸亿仅仆从仑仓仪们价众众优伙会伛伞伟传伡伣伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬侭俣俦俨俩俪俫俭借债倾偬偻偾偿傤傥傧储傩儿克兑兖党兰关兴兹养兽冁内冈册冗写军农冢冯冲冲决况冻净凄准凉凌减凑凛几凤处凫凭凯凶击凿刍划刘则刚创删别刬刭制刹刽刾刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勖勚匀匦匮区医华协单卖卜卢卤卧卫却卷厂厅历历厉压厌厍厐厕厘厠厢厣厦厨厩厮县叁参叆叇双发发变叙叠只台叶号叹叽吁后吓吕吗吨听启吴呆呐呒呓呕呖呗员呙呛呜周咏咙咛咝咤咨咸响哑哒哓哔哕哗哙哜哝哟唇唉唛唝唠唡唢唤啧啬啭啮啯啰啴啸喂喷喽喾嗫嗳嘘嘤嘱噜嚣团园囱围囵国图圆圣圹场坏块坚坛坛坛坛坜坝坞坟坠垄垅垆垒垦垩垫垭垯垱垲垴埘埙埚堑堕塆墙墻壊壮声壳壶壸処备复复够头夸夹夺奁奂奋奖奥奬妆妇妈妩妪妫姗姜姹娄娅娆娇娈娱娲娴婳婴婵婶媪媭嫒嫔嫱嬀嬷孙学孪宁宁宝实宠审宪宫宽宽宾寝对寻导寿将尔尘尝尧尴尸尽尽层屃屉届属屡屦屿岁岂岖岗岘岚岛岩岭岳岽岿峃峄峡峣峤峥峦峰崂崃崄崭嵘嵚嵝巅巨巩巯币布帅师帏帐帘帜带帧帮帱帻帼幂干干并并广庄庆庐庑库应庙庞废庼廏廪开异弃弑张弥弪弯弹强归当录彝彟彦彨彻征径徕御忆忏志忧念忾怀态怂怃怄怅怆怜总怼怿恋恒恳恶恶恸恹恺恻恼恽悦悫悬悭悮悯惊惧惨惩惫惬惭惮惯愠愤愦愿慑慭懑懒懔戆戋戏戗战戬户扎扑托扦执扩扪扫扬扰抚抛抟抠抡抢护报抬抻担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捂捝捞损捡换捣据捻掳掴掷掸掺掼揽揾揿搀搁搂搄搅携摄摅摆摇摈摊撄撑撵撷撸撺擜擞攒敌敍敚敛敩数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权杠条来杨杩杰松板极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桠桡桢档桤桥桦桧桨桩桪梁梦梼梾梿检棁棂棱椁椝椟椠椢椤椫椭椮楼榄榅榇榈榉榝槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴殻毁毂毕毙毡毵氇气氢氩氲汇汇汉污汤汹沟没沣沤沥沦沧沨沩沪泄泞注泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涚涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溁溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪潆潇潋潍潙潜潨潴澛澜濑濒灏灭灯灵灶灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烟烦烧烨烩烫烬热焕焖焘煴爱爷牍牦牵牺犊状犷犸犹狈狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珐珑珰珲琎琏琐琼瑶瑷瑸璎瓒瓮瓯産电画畅畴疖疗疟疠疡疬疭疮疯疱疴痈痉痒痖痨痪痫痴痹瘅瘆瘉瘗瘘瘪瘫瘾瘿癞癣癫皋皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑睾瞆瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硵硷碍碛碜碱礼祃祎祢祯祷祸禀禄禅离秃秆种秘积称秸秽秾稆税稣稳穑穞穷窃窍窎窑窜窝窥窦窭竖竞竪笃笋笔笕笺笼笾筑筚筛筜筝筹筼签签筿简箓箦箧箨箩箪箫篑篓篮篯篱簖籁籴类籼粜粝粤粪粮糁糇糍系系紧绝絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络絶绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡群翘翙翚翱耢耧耸耻聂聋职聍联聩聪肃肠肤肮肴肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑膻臜致舆舍舣舰舱舻艰艳艺节芈芗芜芦苁苇苈苋苌苍苎苏苧苹范茎茏茑茔茕茧荆荐荙荚荛荜荝荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒀蒇蒉蒋蒌蒏蓝蓟蓠蓣蓥蓦蔂蔷蔹蔺蔼蕰蕲蕴薮藓蘖虏虑虚虫虬虮虱虽虾虿蚀蚁蚂蚃蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衆衔补表衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯訚詟誉誊说说谣讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贜贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞跡践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯軆輼车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辟辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郏郐郑郓郦郧郸酂酝酦酱酽酾酿采释里里鈎鉴鉴銮鋭録錾钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链链铿销锁锂锃锄锅锆锇锈锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶长门闩闪闫闬闭问闯闰闱闲闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陦陧陨险随隐隶隽难雇雏雠雳雾霁霉霡霭靓靔静面靥鞑鞒鞯鞲韦韧韨韩韪韫韬韵頽页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕駡马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓鬶魇魉鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鷀鷄鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹾麦麸麹麽黄黉黡黩黪黾鼋鼌鼍鼹齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟酸';
    const tcStr = '萬與醜專業叢東絲丟兩嚴喪個豐臨為爲麗舉麽麼義烏樂喬習鄉書買亂爭於虧雲亙亞産產畝親褻嚲億僅僕從侖倉儀們價衆眾優夥會傴傘偉傳俥俔傷倀倫傖僞佇體餘傭僉俠侶僥偵側僑儈儕儂儘俁儔儼倆儷倈儉藉債傾傯僂僨償儎儻儐儲儺兒剋兌兗黨蘭關興茲養獸囅內岡冊宂寫軍農塚馮沖衝決況凍淨淒準涼淩減湊凜幾鳳處鳧憑凱兇擊鑿芻劃劉則剛創刪別剗剄製剎劊㓨劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳勗勩勻匭匱區醫華協單賣蔔盧鹵臥衛卻捲廠廳曆歷厲壓厭厙龎廁釐廁廂厴廈廚廄廝縣叄參靉靆雙發髮變敘疊隻臺葉號嘆嘰籲後嚇呂嗎噸聽啟吳獃吶嘸囈嘔嚦唄員咼嗆嗚週詠嚨嚀噝吒諮鹹響啞噠嘵嗶噦嘩噲嚌噥喲脣欸嘜嗊嘮啢嗩喚嘖嗇囀齧嘓囉嘽嘯餵噴嘍嚳囁噯噓嚶囑嚕囂團園囪圍圇國圖圓聖壙場壞塊堅壇罎罈壜壢壩塢墳墜壟壠壚壘墾堊墊埡墶壋塏堖塒壎堝塹墮壪牆牆壞壯聲殼壺壼處備複復夠頭誇夾奪奩奐奮獎奧獎妝婦媽嫵嫗媯姍薑奼婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬃嬡嬪嬙媯嬤孫學孿寧甯寶實寵審憲宮寬寛賓寢對尋導壽將爾塵嘗堯尷屍盡儘層屭屜屆屬屢屨嶼歲豈嶇崗峴嵐島巖嶺嶽崬巋嶨嶧峽嶢嶠崢巒峯嶗崍嶮嶄嶸嶔嶁巔鉅鞏巰幣佈帥師幃帳簾幟帶幀幫幬幘幗冪幹乾並併廣莊慶廬廡庫應廟龐廢廎廄廩開異棄弒張彌弳彎彈強歸當錄彜彠彥彲徹徵徑徠禦憶懺誌憂唸愾懷態慫憮慪悵愴憐總懟懌戀恆懇惡噁慟懨愷惻惱惲悅愨懸慳悞憫驚懼慘懲憊愜慚憚慣慍憤憒願懾憖懣懶懍戇戔戲戧戰戩戶紮撲託扡執擴捫掃揚擾撫拋摶摳掄搶護報擡捵擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏摀挩撈損撿換搗據撚擄摑擲撣摻摜攬搵撳攙擱摟揯攪攜攝攄擺搖擯攤攖撐攆擷擼攛㩵擻攢敵敘敓斂斆數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權槓條來楊榪傑鬆闆極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒椏橈楨檔榿橋樺檜槳樁樳樑夢檮棶槤檢梲櫺稜槨槼櫝槧槶欏樿橢槮樓欖榲櫬櫚櫸樧檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆殼毀轂畢斃氈毿氌氣氫氬氳彙匯漢汙湯洶溝沒灃漚瀝淪滄渢溈滬洩濘註淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧涗濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕濚潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦瀠瀟瀲濰溈潛潀瀦瀂瀾瀨瀕灝滅燈靈竈災燦煬爐燉煒熗點煉熾爍爛烴燭煙菸煩燒燁燴燙燼熱煥燜燾熅愛爺牘犛牽犧犢狀獷獁猶狽獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽琺瓏璫琿璡璉瑣瓊瑤璦璸瓔瓚甕甌產電畫暢疇癤療瘧癘瘍癧瘲瘡瘋皰痾癰痙癢瘂癆瘓癇癡痺癉瘮癒瘞瘻癟癱癮癭癩癬癲臯皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼睪瞶瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確磠鹼礙磧磣堿禮禡禕禰禎禱禍稟祿禪離禿稈種祕積稱稭穢穠穭稅穌穩穡穭窮竊竅窵窯竄窩窺竇窶豎競豎篤筍筆筧箋籠籩築篳篩簹箏籌篔簽籤篠簡籙簀篋籜籮簞簫簣簍籃籛籬籪籟糴類秈糶糲粵糞糧糝餱餈係繫緊絕縶糹糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺紲紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏縧繼綈績緒綾緓續綺緋綽鞝緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨羣翹翽翬翺耮耬聳恥聶聾職聹聯聵聰肅腸膚骯餚腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏羶臢緻輿捨艤艦艙艫艱豔藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇薴蘋範莖蘢蔦塋煢繭荊薦薘莢蕘蓽萴蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蒕蕆蕢蔣蔞醟藍薊蘺蕷鎣驀虆薔蘞藺藹薀蘄蘊藪蘚櫱虜慮虛蟲虯蟣蝨雖蝦蠆蝕蟻螞蠁蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁眾銜補錶襯袞襖裊褘襪襲襏裝襠褌褳襝褲襉褸襤襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶誾讋譽謄說説謡訁計訂訃認譏訐訌討讓訕訖託訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談讅誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗謚謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶贓貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗贊讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒蹟踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀體轀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭闢辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郟鄶鄭鄆酈鄖鄲酇醞醱醬釅釃釀採釋裏裡鉤鑒鑑鑾銳錄鏨釒釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鉅鈍鈔鍾鐘鈉鋇鋼鈑鈐鑰欽鈞鎢鈎鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鉋鈰鉉鉈鉍鈮鈹鐸鉶銬銠鉺鋩錏銪鋮鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鎩鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鍊鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銹銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺鍩錯錨錛錡鍀錁錕錩錫錮鑼錘錐錦鑕鍁錈鍃錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鐨鎇鏌鎮鎛鎘鑷钂鐫鎳鎿鎦鎬鎊鎰鎵鑌鎔鏢鏜鏝鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔钀鑞鑱鑲長門閂閃閆閈閉問闖閏闈閑閒閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隯隉隕險隨隱隸雋難僱雛讎靂霧霽黴霢靄靚靝靜麵靨韃鞽韉韝韋韌韍韓韙韞韜韻頹頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顔顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飈飛饗饜飠飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢罵馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢鬹魘魎魚魛魢魷魨魯魴䰾魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鰺鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鼈鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣䲘鶿雞鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鷽鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鵾鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶖鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺䴉鸇鷹鸌鸏鸛鸘鹺麥麩麴麼黃黌黶黷黲黽黿鼂鼉鼴齊齏齒齔齕齗齟齡齙齠齜齦齬齪齲齷龍龔龕龜痠';
    //異體字規範，格式為【正體: 異體列表】
    const oc2tc = {
        "床": "牀",
        "為": "爲",
        "產": "産",
        '眾': '衆',
        '寧': '甯',
        '啟': '啓',
        '鏽': '銹',
        '閱': '閲',
        '顏': '顔',
        '嘆': '歎',
        '線': '缐綫',
        '綠': '緑',
        '幸': '倖',
        '聽': '聼聴'
    };
    //此處為匹配上具體詞語就優先轉換的單字，簡體與正體分開處理。可以用來處理異體字，或者同字替換，以取消單字匹配時的轉換操作
    //簡轉繁，單向轉換
    var sc2tc = {
        '巨':[
            '巨',
            ['鉅','巨款','巨富','巨细','巨子']
        ],
        '折':[
            '折',
            ['摺','折叠','折纸','存折','对折','折痕','奏折','折页','折扇']
        ],
        '霉':[
            '霉',
            ['黴','青霉素','红霉素','霉菌','氯霉素','绿霉素']
        ],
        '捆':[
            '捆',
            ['綑','捆绑','捆扎']
        ],
        '升':[
            '升',
            ['昇','升华','提升','高升','歌舞升平']
        ],
        '划':[
            '劃',
            ['划','划龙舟','划船','划算','划不来']
        ],
        '姜':[
            '姜',
            ['薑','姜片','姜葱','生姜','姜汁','姜母鸭']
        ],
        '御':[
            '禦',
            ['御','御制','御用']
        ],
        '毁':[
            '毀',
            ['燬','烧毁','焚毁','炸毁','销毁'],
            ['譭','诋毁','毁谤']
        ],
        '胡':[
            '胡',
            ['鬍','胡须','胡子','刮胡刀'],
            ['衚','胡同']
        ],
        '须':[
            '須',
            ['鬚','剃须刀','胡须','须发','根须']
        ],
        '同':[
            '同',
            ['衕','衚衕']
        ],
        '叹':[
            '歎',
            ['嘆','悲叹','叹息','仰天长叹','叹惋']
        ],
        '荡':[
            '蕩',
            ['盪','空荡荡','回荡','动荡','荡漾','震荡']
        ],
        '凄':[
            '淒',
            ['悽','凄厉','凄惨','悲凄','凄苦']
        ],
        '栗':[
            '栗',
            ['慄','战栗','颤栗','不寒而栗']
        ],
        '凄':[
            '淒',
            ['悽','凄厉','凄惨','悲凄','凄苦']
        ],
        '沈':[
            '沈',
            ['瀋','沈阳']
        ],
        '苏':[
            '蘇',
            ['甦','复苏','苏醒']
        ],
        '卤':[
            '滷',
            ['鹵','卤钝','卤莽','粗卤','卤地']
        ],
        '准':[
            '準',
            ['准','批准','准许','不准','准予']
        ],
        '杯':[
            '杯',
            ['盃','奖杯','世界杯']
        ],
        '馈':[
            '饋',
            ['餽','馈赠']
        ],
        '向':[
            '向',
            ['嚮','向往','向导']
        ],
        '搜':[
            '搜',
            ['蒐','蒐集','蒐羅']
        ],
        '哗':[
            '嘩',
            ['譁','哗变','喧哗','哗众取宠']
        ],
        '够':[
            '夠',
            ['搆','够不到']
        ],
        '范':[
            '范',
            ['範','模范','范本','示范','规范','范围']
        ],
        '喂':[
            '喂',
            ['餵','喂养','喂饱','饲喂']
        ],
        '迹':[
            '跡',
            ['蹟','古迹','遗迹','事迹','奇迹','史迹']
        ],
        '佩':[
            '佩',
            ['珮','玉佩']
        ],
        '尸':[
            '屍',
            ['尸','尸位素餐']
        ],
        '泛':[
            '泛',
            ['氾','泛滥']
        ],
        '雕':[
            '雕',
            ['彫','雕刻','雕像','雕塑','精雕细琢','雕琢','冰雕']
        ],
        '核':[
            '核',
            ['覈','审核','核实','核准','核对','复核','核查']
        ],
        '困':[
            '困',
            ['睏','困倦','困意','犯困']
        ],
        '欲':[
            '欲',
            ['慾','欲望','情欲','私欲','贪欲','色欲']
        ],
        '致':[
            '致',
            ['緻','精致','细致']
        ],
        '梁':[
            '梁',
            ['樑','栋梁','桥梁']
        ],
        '占':[
            '占',
            ['佔','占用','占领','侵占','占为己有','强占','占有','抢占']
        ],
        '卜':[
            '卜',
            ['蔔','萝卜','胡萝卜']
        ],
        '托':[
            '托',
            ['託','拜托','托付','嘱托','托词','托辞','推托','委托','托病','信托','托梦','托孤','托故','托管','受托','寄托']
        ],
        '刮':[
            '刮',
            ['颳','刮风']
        ],
        '尽':[
            '盡',
            ['儘','尽快','尽早','尽可能','尽显','尽量','尽管']
        ],
        '汇':[
            '匯',
            ['彙','词汇','字汇','汇集','汇编','辞汇']
        ],
        '才':[
            '才',
            ['纔','刚才','方才','却才','恰才']
        ],
        '丑':[
            '醜',
            ['丑','小丑','丑角','乙丑','丁丑','己丑','辛丑','癸丑','副丑']
        ],
        '周':[
            '周',
            ['週','周报','周期','周会','周日','周刊','周波','周岁','周末','周考','一周','二周','三周','四周','五周','两周','双周刊','名剧周','黄金周','周休','周一','周二','周三','周四','周五','周六'],
            ['賙','周济']
        ],
        '冲':[
            '沖',
            ['衝','冲奖','冲高','冲决','冲浪','冲子','冲力','冲要','冲破','冲口','冲顶','冲床','冲突','冲刺','冲金','冲模','冲撞','冲腾','冲锋','冲量','冲动','冲程','冲压','冲杀','冲激','冲击','俯冲','反冲','折冲','缓冲','脉冲','要冲','冲锋枪','冲孔机','冲劲','冲金点','冲压机','冲击波','反冲力','冲锋','横冲','冲冠','首当其冲']
        ],
        '恶':[
            '惡',
            ['噁','恶心']
        ],
        '发':[
            '發',
            ['發','发回'],
            ['髮','发网','发际','发箍','发丝','发式','发带','发型','发卡','发妻','发指','发廊','发饰','发乳','发夹','发菜','发屋','发姐','发油','发套','发蜡','发鬓','发髻','发雕','发辫','发胶','发浆','一发','假发','健发','削发','卷发','握发','束发','染发','植发','栉发','毛发','毫发','烫发','理发','白发','短发','秀发','秃发','结发','美发','胎发','脱发','华发','落发','蓄发','护发','金发','银发','头发','驳发','鬓发','须发','发小','剃发令','洗发','发短心长','怒发冲冠','断发文身','被发','鹤发','黄发垂髫','擢发难数','庞眉皓发','披头散发','间不容发']
        ],
        '复':[
            '復',
            ['複','复诊','复印','复写','复查','复习','复式','复种','复姓','复核','复音','复决','复利','复眼','复句','复合','复果','复述','复胃','复本','复方','复验','复选','复赛','复议','复制','复检','复杂','复叶','复线','复诵','复视','复试','复数','复评','复审','繁复','重复','复元音','复读机','复辅音','复共轭的','合义复词','衍声复词','山重水复'],
            ['覆','复電','批复','核复','禀复','答复','被复','赐复','颠复','倾复','函复','反复','回复','复亡','复函','复命','复审','复复','复败','复书','复核','复没','复灭','复舟']
        ],
        '鉴':[
            '鑒',
            ['鑑','鉴于','鉴识','鉴赏','鉴证','鉴真','鉴谅','鉴别','鉴定','鉴戒','人鉴','借鉴','印鉴','可鉴','品鉴','唐鉴','图鉴','年鉴','殷鉴','洞鉴','王鉴','评鉴','赏鉴','通鉴','风鉴','龟鉴','明通鉴','鉴往知来','鉴古推今','有鉴于此','渊鉴类函','引为鉴戒','之鉴','宝鉴','玉鉴','引以为鉴','手鉴']
        ],
        '历':[
            '歷',
            ['曆','历书','历象','历元','历法','公历','回历','国历','夏历','年历','弘历','挂历','日历','月历','校历','桌历','殷历','皇历','旧历','藏历','西历','农历','阴历','阳历','黄历','台历','万历帝','藏历年','陀历道','阳历年','七曜历','三统历','乾象历','天体历','太初历','格里历','统天历','行事历','农民历','农家历','戊寅元历']
        ],
        '链':[
            '鏈',
            ['鍊','链子','拉链','精链','锻链','项链','锁链','铁链']
        ],
        '签':[
            '簽',
            ['籤','签子','签诗','抽签','掣签','书签','标签','求签','牙签','竹签','贴标签','唐音统签','金瓶掣签','云笈七签']
        ],
        '闲':[
            '閒',
            ['閑','闲闲','熟闲','高闲','闲居','幽闲','逾闲']
        ],
        '赞':[
            '贊',
            ['讚','赞赏','赞佩','赞美','赞誉','赞歌','赞叹','赞许','赞扬','赞颂','赞语','按赞','盛赞','礼赞','称赞','夸赞','颂赞','点赞','赞不绝口']
        ],
        '钟':[
            '鍾',
            ['鐘','钟摆','钟点','钟乳','钟楼','钟头','钟鼎','分钟','丧钟','座钟','挂钟','摆钟','时钟','洪钟','空钟','编钟','诗钟','警钟','电钟','闹钟','点钟','钟点房','钟鼓','钟点工','钟鼎文','大钟寺','石钟乳','光学钟','原子钟','大本钟','大笨钟','宗周钟','平安钟','打卡钟','抖空钟','撞丧钟','救命钟','敲警钟','敲丧钟','潜水钟','生物钟','石英钟','自鸣钟','电子钟','钟鸣','晨钟','黄钟','撞钟']
        ],
        '只':[
            '只',
            ['隻','几只','一只','二只','两只','三只','四只','五只','六只','七只','八只','九只','十只','百只','千只','万只','形单影只','只言片语','只字不提'],
            ['只','只有','只会','只管','只消','只当','只好','只要','只能','只会','只是','只怕','只得','只见','只顾','只许','只因','不只','仅只','只不过','只此一家','只欠东风','只争朝夕']
        ],
        '捂':[
            '捂',
            ['摀','紧捂']
        ],
        '咸':[
            '鹹',
            ['咸','咸阳','咸宜','咸丰','咸和','咸池','咸五','彭咸','季咸','阮咸','阿咸','巫咸','碧咸']
        ],
        '脏':[
            '髒',
            ['臟','脏器','脏腑','五脏','内脏','心脏','肝脏','肺脏','胃脏','胰脏','脺脏','脾脏','肾脏','腑脏','肠脏']
        ],
        '岳':[
            '岳',
            ['嶽','五岳','中岳','北岳','南岳','西岳','东岳','岳立']
        ],
        '云':[
            '雲',
            ['云','人云亦云','云云']
        ],
        '游':[
            '遊',
            ['游','游泳','游水','花游']
        ],
        '弥':[
            '彌',
            ['瀰','弥漫']
        ],
        '松':[
            '鬆',
            ['松','惺松','阿松','松树','松针','松果','松鼠','松林','松竹']
        ],
        '愈':[
            '愈',
            ['癒','不愈','初愈','已愈','康愈','愈合','未愈','治愈','病愈','痊愈','自愈','伤愈','愈疮','渐愈']
        ],
        '尝':[
            '嘗',
            ['嚐','品尝','浅尝辄止','卧薪尝胆']
        ],
        '斗':[
            '斗',
            ['鬥','不斗','久斗','互斗','仍斗','共斗','再斗','初斗','力斗','勇斗','博斗','又斗','合斗','吵斗','善斗','大斗','好斗','想斗','打斗','批斗','抓斗','抗斗','拆斗','拼斗','挑斗','接斗','搏斗','敢斗','文斗','斗一','斗上','斗不','斗久','斗了','斗他','斗你','斗倒','斗出','斗到','斗力','斗勇','斗去','斗口','斗命','斗嘴','斗在','斗垮','斗士','斗奇','斗她','斗妍','斗完','斗弄','斗得','斗心','斗忍','斗志','斗快','斗意','斗成','斗我','斗批','斗技','斗招','斗拳','斗掌','斗斗','斗智','斗棋','斗法','斗牛','斗狗','斗狠','斗眼','斗神','斗私','斗草','斗角','斗起','斗趣','斗酒','斗魂','智斗','暗斗','未斗','格斗','械斗','武斗','死斗','比斗','游斗','激斗','狠斗','猛斗','相斗','私斗','群斗','苦斗','虎斗','血斗','要斗','角斗','越斗','跟斗','迎斗','邀斗','酣斗','乱斗','内斗','别斗','剧斗','劲斗','夺斗','奋斗','厮斗','恶斗','战斗','斗来','斗个','斗传','斗剑','斗劲','斗胜','斗场','斗将','斗恶','斗战','斗擞','斗败','斗敌','斗杀','斗殴','斗气','斗争','斗兽','斗毕','斗舰','斗艺','斗艳','斗赢','斗输','斗过','斗鸡','斗饮','斗闹','斗鱼','斗丽','会斗','权斗','殴斗','决斗','争斗','独斗','竞斗','约斗','缠斗','罢斗','观斗','赌斗','较斗','连斗','门斗','双斗','颤斗','凤斗','斗！']
        ],
        '系':[
            '系',
            ['係','关系','系数'],
            ['系','系统','系列','体系','派系','直系'],
            ['繫','不系','劾系','心系','所系','拘系','擐系','系上','系乎','系了','系住','系囚','系妥','系心','系念','系手','系牢','系留','系腰','系膜','系起','颈系','连系','联系','维系','系马','系个','系块','系带','系怀','系挂','系于','系条','系绊','系紧','系缚','系绳','系缆','系脚','系辞','系铃','系颈','牵系','梦系','身系','腰系','背系','縻系']
        ],
        '舍':[
            '捨',
            ['舍','宿舍','寒舍','屋舍','舍下']
        ],
        '干':[
            '幹',
            ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'],
            ['干','干系','天干','干涉','干扰','干戈','相干']
        ],
        '了':[
            '了',
            ['瞭','了望','了然','了解','了若指掌','了如指掌']
        ],
        '谷':[
            '穀',
            ['谷','低谷','山谷','谷峰','谷底']
        ],
        '仿':[
            '仿',
            ['倣','仿效'],
            ['彷','仿佛','仿徉'],
            ['徬','仿徨']
        ],
        '效':[
            '效',
            ['傚','模效','摹效','仿效','儆效','效尤','效法']
        ],
        '克':[
            '克',
            ['剋','克夫','克扣','克日','克星','克期','克死','克薄','生克','相克','冲克'],
            ['刻','克苦']
        ],
        '吊':[
            '吊',
            ['弔','吊信','吊古','吊唁','吊奠','吊孝','吊客','吊影','吊念','吊慰','吊文','吊民','吊祭','哀吊','唁吊','盆吊','祭吊','陪吊','吊问','吊丧','吊场','吊书','吊词','吊诡','吊贺','吊钱','凭吊']
        ],
        '台':[
            '臺',
            ['颱','冬台','秋台','防台','台风','强台','轻台'],
            ['檯','台凳','台子','台布','台面','吧台','抹台','揩台','球台','窗台','翻台','餐台','台历','台灯','台钟','书台','柜台','赌台','长台']
        ],
        '回':[
            '回',
            ['迴','北回','南回','回圈','回廊','回旋','回游','回翔','回避','峰回','巡回','迂回','回环','回纹','回绕','回肠','回荡','回銮','回响','回风','梦回','盘回','纡回','萦回','轮回','递回']
        ],
        '后':[
            '後',
            ['后','仙后','吕后','天后','太后','封后','帝后','废后','影后','后冠','后土','后妃','后稷','后羿','母后','王后','皇后','舞后','西后','艳后','韦后']
        ],
        '征':[
            '征',
            ['徵','代征','停征','像征','免征','咎征','征了','征人','征信','征候','征兆','征入','征兵','征募','征去','征友','征取','征召','征地','征婚','征引','征得','征收','征文','征求','征片','征用','征稿','征管','征聘','征象','征逐','征集','急征','性征','新征','特征','狂征','病征','稽征','考征','苛征','表征','象征','超征','魏征','带征','广征','强征','征个','征启','征敛','征状','征税','征粮','征纳','征缴','征诏','征询','征调','征财','征费','征赋','征购','征选','应征','横征','减征','滥征','纳征','缓征','联征','详征','诚征','课征','变征','开征','体征']
        ],
        '注':[
            '注',
            ['註','注解','备注','注脚','批注','注册','注定','校注','尾注','注销','标注','注释']
        ],
        '丰':[
            '豐',
            ['丰','三丰','丰姿','丰度','丰情','丰神','丰韵']
        ],
        '并':[
            '並',
            ['併','一并','不并','并入','并力','并合','并吞','并图','并拢','并案','并叠','并砌','并科','并负','并购','并赃','并除','并陇','侵并','兼并','合并','吞并','整并','归并','相并','砌并','被并','裁并','购并','双并']
        ],
        '念':[
            '念',
            ['唸','光念','念佛','念作','念到','念咒','念好','念完','念得','念念','念成','念法','敢念','念书','念给','念经','念诵','念过','念错','念点','没念']
        ],
        '借':[
            '借',
            ['藉','借以','借口','借故','慰借','狼借','借机','借词','凭借','蕴借']
        ],
        '志':[
            '志',
            ['誌','日志','网志','墓志铭','聊斋志异','三国志','杂志']
        ],
        '么':[
            '麼',
            ['么','老么','么女','么儿','么妹','么子','么弟']
        ],
        '布':[
            '布',
            ['佈','公布','分布','宣布','密布','布伏','布署','布兵','布告','布局','布施','布景','布置','布防','布雷','故布','散布','遍布','传布','布个','布坛','布导','布岗','布于','布满','布阵','广布','摆布','满布','发布','预布']
        ],
        '分':[
            '分',
            ['份','分量','身分']
        ],
        '里':[
            '裡',
            ['里','○里','一里','七里','三里','下里','九里','二里','五里','亚里','佳里','克里','全里','两里','八里','公里','六里','凯里','劈里','加里','北里','十里','千里','南里','卡里','吉里','哈里','哥里','啰里','四里','埔里','多里','少里','尤里','居里','峇里','布里','几里','底里','德里','拉里','故里','数里','斯里','普里','东里','格里','归里','波里','乌里','百里','稀里','罗里','英里','莫里','万里','苏里','里亚','里仁','里夫','里奥','里尼','里布','里拉','里昂','里根','里民','里尔','里科','里程','里约','里纳','里美','里肌','里兰','里路','里里','里长','西里','贝里','路里','道里','乡里','邻里','阿里','马里','０里','0里','1里','2里','3里','4里','5里','6里','7里','8里','9里']
        ],
        '面':[
            '面',
            ['麵','制面','吃面','拉面','拌面','揉面','杯面','油面','泡面','炒面','煮面','碗面','羹面','肉面','辣面','面店','面杖','面灰','面碗','面筋','面粉','面糊','面茶','面食','食面','寿面','杆面','凉面','汤面','烫面','发面','酱面','面价','面团','面厂','面摊','面汤','面线','面饺','面饼','面馆','面馍','面龟','饨面','卤面','麦面','干面','擀面']
        ],
        '烟':[
            '煙',
            ['菸','烟斗','吸烟','好烟','戒烟','抽烟','支烟','旱烟','根烟','烟商','烟客','烟枪','烟民','烟灰','烟瘾','烟草','烟酒','烟头','烟鬼','烟龄','禁烟','买烟','香烟']
        ],
        '蒙':[
            '蒙',
            ['濛','灰蒙','空蒙','蒙蒙','迷蒙','弥蒙','蒙雾'],
            ['矇','欺蒙','蒙住','蒙叟','蒙敝','蒙昧','蒙混','蒙瞀','蒙瞢','蒙瞽','蒙蔽','蒙胧','蒙眬','蒙骗'],
            ['懞','蒙懂']
        ],
        '表':[
            '表',
            ['錶','戴表','手表','秒表','腕表','表店','跳表','陀表','怀表','表带','表厂','表壳','表炼','表链','钟表','马表']
        ],
        '板':[
            '板',
            ['闆','老板']
        ],
        '卷':[
            '卷',
            ['捲','卷入','卷起','龙卷风','席卷','蛋卷','花卷','袭卷','卷款','卷发','卷走','卷进','卷曲','卷舌','烟卷']
        ],
        '酸':[
            '酸',
            ['痠','酸软','酸痛','腰酸背痛']
        ],
        '仇':[
            '仇',
            ['讎','复仇','仇恨','报仇','仇敌']
        ],
        '几':[
            '幾',
            ['几','窗明几净','窗明几洁','茶几']
        ],
        '背':[
            '背',
            ['揹','背负','背黑锅','背包']
        ],
        '衔':[
            '銜',
            ['啣','结草衔环','衔着']
        ],
        '构':[
            '構',
            ['搆','构陷','构思']
        ]
    };
    //此處為用語轉換，優先級最高，也可以用來給以上兩種轉換打補靪，此處簡繁共用
    var sc2tcComb = {
        '香烟袅袅':'香煙裊裊',
        '袅袅香烟':'裊裊香煙',
        '补丁':'補靪',
        '老挝':'寮國',
        '沈阳':'瀋陽',
        '战栗':'顫慄',
        '豆蔻':'荳蔻',
        '累累':'纍纍',
        '阿里':'阿里',
        '跟斗':'觔斗',
        '筋斗':'筋斗',
        '折冲':'折衝',
        '梁折':'樑折',
        '松干':'松幹',
        '家伙':'傢伙',
        '伙夫':'伙伕',
        '游斗':'游鬥',
        '回游':'迴游',
        '云游':'雲遊',
        '云宵':'雲霄',
        '考卷发':'考卷發',
        '发卷':'髮卷',
        "烟卷":"菸卷",
        "连卷":"連卷",
        '鼠标':'滑鼠',
        'U盘':'隨身碟',
        '硬盘':'硬碟',
        '磁盘':'磁碟',
        '软件':'軟體',
        '操作系统':'作業系統',
        '文件系统':'檔案系統',
        '笔记本':'筆記型電腦',
        '台式机':'桌上型電腦',
        '网络':'網路',
        '打印':'列印',
        '复印':'影印',
        '充电宝':'行動電源',
        '排插':'延長綫',
        '程序':'程式',
        '光盘':'光碟',
        '音频':'音訊',
        '屏幕':'熒幕',
        '卸载':'解除安裝',
        '文件夹':'檔案夾',
        '局域网':'區域網路',
        '服务器':'伺服器',
        '打伞':'撐傘',
        '洗面奶':'洗面乳',
        '洗发水':'洗髮乳',
        '打底裤':'内搭褲',
        '电饭煲':'電鍋',
        '发卡':'髮夾',
        '聊天群':'聊天視窗',
        '普通话':'國語',
        '简历':'履歷',
        '公交车':'公車',
        '打车':'叫車',
        '出租车':'計程車',
        '地铁':'捷運',
        '自行车':'脚踏車',
        '摩托车':'機車',
        '巴士':'客運',
        '奔驰':'賓士',
        '挺好的':'滿好的',
        '牛逼':'厲害',
        '左拐':'左轉',
        '竖的':'直的',
        '让一下':'借過',
        '凉水':'冰水',
        '打包':'外帶',
        '外卖':'外送',
        '很火':'很紅',
        '宾馆':'飯店',
        '旅馆':'賓館',
        '包间':'包廂',
        '卫生间':'化妝室',
        '幼儿园':'幼稚園',
        '公安局':'警察局',
        '饭店':'餐廳',
        '酒店':'飯店',
        '高校':'大學',
        '写字楼':'辦公大樓',
        '换乘站':'轉運站',
        '豆腐脑':'豆花',
        '菠萝':'鳳梨',
        '薯片':'洋芋片',
        '土豆':'馬鈴薯',
        '花生':'土豆',
        '芝士':'起司',
        '猕猴桃':'奇異果',
        '盒饭':'便當',
        '夜宵':'宵夜',
        '金枪鱼':'鮪魚',
        '三文鱼':'鮭魚',
        '番石榴':'芭樂',
        '冰激淋':'冰淇淋',
        '冰棍':'冰棒',
        '快餐':'速食',
        '格斗':'挌鬥',
        '西红柿':'番茄',
        '西兰花':'花椰菜',
        '创可贴':'OK綳',
        '输液':'打點滴',
        '献血':'捐血',
        'B超':'超音波檢查',
        '疯牛病':'狂牛病',
        '台球':'撞球',
        '乒乓球':'桌球',
        '自由泳':'自由式',
        '蛙泳':'蛙式',
        '初中生':'國中生',
        '本科生':'大學生',
        '程序员':'程式設計師',
        '传销':'直銷',
        '宇航员':'太空人',
        '超声波':'超音波',
        '北京时间':'中原標準時間',
        '保质期':'保存期限',
        '甲肝':'A肝',
        '乙肝':'B肝',
        '丙肝':'C肝',
        '塑料':'塑膠',
        '够不到':'搆不到',
        '够不着':'搆不着',
        '舞娘':'舞孃',
        '秋千':'鞦韆',
        '拐杖':'枴杖',
        '剩余':'賸餘',
        '胡同':'衚衕',
        '个旧':'箇舊',
        '朱砂':'硃砂',
        '知识产权':'智慧財產權'
    };
    var sc2tcCombConfig = {
        "*": sc2tcComb
    };
    //此處為姦文盲親娘
    var fuckIlliteracy = {
        'yyds':'永遠的神'
    };

    var illiteracyConfig = {
        "*": fuckIlliteracy
    }

    //繁轉簡
    var tc2sc = {
        '著':[
            '着',
            ['著','著名','著作','巨著','著稱','顯著','昭著','卓著','所著','著述','編著','著書','名著','原著','遺著','譯著','著譯','著：','著:','土著','論著','專著','日新月著','著有','合著','知著','著錄','著者','較著','頗著','文著','著文','自著','著成','著《','撰著','著撰','拙著','著明','著論','新著','著於','而著','雜著','著足','著花','醫著','聲著']
        ],
        '乾':[
            '干',
            ['乾','乾隆','乾卦','乾道','乾宅','乾造','乾之卦','乾為','「乾」','乾坤','乾元','乾剛','乾方','乾施','乾首','乾象','乾啟','幹鈞','乾化','乾心','幹居','乾符','乾暉','幹曜','乾風','乾雷','乾州','中乾','連乾','乾沒','桑乾','乾乾','花乾']
        ],
        '瞭':[
            '瞭',
            ['了','瞭望','瞭然','瞭解','瞭若指掌','瞭如指掌']
        ]
    };

    var lang = navigator.appName == "Netscape"?navigator.language:navigator.userLanguage;
    lang = lang.toLowerCase();
    switch(lang){
        case "zh-tw":
            /*sc2tc["只"]=[
                '隻',
                ['','']
            ];*/
            /*sc2tcComb['三维']='';
            */
            break;
        case "zh-hk":
            break;
        case "zh-mo":
            break;
        default:
            break;
    }

    const inConfigPage = location.host == 'greasyfork.org' && /scripts\/24300(\-[^\/]*)?$/.test(location.pathname);
    var _GM_listValues, _GM_registerMenuCommand, _GM_notification, _GM_openInTab, _GM_getResourceText, _GM_info;

    var isSimple = (lang === "zh-cn" || lang === "zh-hans" || lang === "zh-sg" || lang === "zh-my");
    var action = 0;//1:noChange, 2:showSimplified, 3:showTraditional
    var enable = false;

    var stDict = {}, tsDict = {}, pinyinTree = null;
    var sc2tcCombTree = {}, tc2scCombTree = {}, fuckIlliteracyTree = {};

    function stranText(txt) {
        if (!txt) return "";
        txt = generalReplace(txt);
        if (enable) {
            if (action == 2) return simplized(txt);
            else if (action == 3) return traditionalized(txt);
        }
        else return txt;
    }

    function generalReplace(orgStr){
        if (!orgStr) return "";
        var str='', char;
        for(var i=0;i<orgStr.length;i++){
            char=orgStr.charAt(i);
            let search=fuckIlliteracyTree[char.toLowerCase()],searchIndex=i,hasMatch=false;
            while(search && searchIndex<orgStr.length){
                let downTree=null;
                if(searchIndex<orgStr.length-1){
                    downTree=search[orgStr.charAt(searchIndex+1).toLowerCase()];
                }
                if(!downTree){
                    if(search.end){
                        hasMatch=true;
                        i=searchIndex;
                        str+=search.end;
                    }
                    break;
                }
                searchIndex++;
                search=downTree;
            }
            if(!hasMatch)str+=char;
        }
        return str;
    }

    function showPinyin(orgStr, node){
        if (!orgStr) return;
        if (!pinyinTree || /^(RUBY|RB|RP)$/i.test(node.parentNode.nodeName)) return;
        let char;
        let hasPinyin=false;
        const collection = document.createDocumentFragment();
        for(var i=0;i<orgStr.length;i++){
            char=orgStr.charAt(i);
            let search=pinyinTree[char.toLowerCase()],searchIndex=i,hasMatch=false;
            let firstEnd=search&&search.end;
            while(search && searchIndex<orgStr.length){
                let downTree=null;
                if(searchIndex<orgStr.length-1){
                    downTree=search[orgStr.charAt(searchIndex+1).toLowerCase()];
                }
                if(!downTree){
                    if(search.end){
                        hasMatch=true;
                        let ruby=document.createElement("ruby");
                        let rb=document.createElement("rb");
                        rb.innerText=orgStr.slice(i, searchIndex+1);
                        ruby.appendChild(rb);
                        let rp=document.createElement("rp");
                        rp.innerText='(';
                        ruby.appendChild(rp);
                        let rt=document.createElement("rt");
                        rt.innerText=search.end;
                        ruby.appendChild(rt);
                        rp=document.createElement("rp");
                        rp.innerText=')';
                        ruby.appendChild(rp);
                        collection.appendChild(ruby);
                        hasPinyin=true;
                        i=searchIndex;
                    }
                    break;
                }
                searchIndex++;
                search=downTree;
            }
            if(!hasMatch){
                if(firstEnd){
                    hasMatch=true;
                    let ruby=document.createElement("ruby");
                    let rb=document.createElement("rb");
                    rb.innerText=orgStr.slice(i, i+1);
                    ruby.appendChild(rb);
                    let rp=document.createElement("rp");
                    rp.innerText='(';
                    ruby.appendChild(rp);
                    let rt=document.createElement("rt");
                    rt.innerText=firstEnd;
                    ruby.appendChild(rt);
                    rp=document.createElement("rp");
                    rp.innerText=')';
                    ruby.appendChild(rp);
                    collection.appendChild(ruby);
                    hasPinyin=true;
                }else{
                    let txtnode = document.createTextNode(char);
                    collection.appendChild(txtnode);
                }
            }
        }
        if(hasPinyin){
            node.parentNode.replaceChild(collection, node);
        }
    }

    function traditionalized(orgStr){
        if (!orgStr) return "";
        var str='', char;
        for(var i=0;i<orgStr.length;i++){
            char=orgStr.charAt(i);
            let search=sc2tcCombTree[char],searchIndex=i,hasMatch=false;
            while(search && searchIndex<orgStr.length){
                let downTree=null;
                if(searchIndex<orgStr.length-1){
                    downTree=search[orgStr.charAt(searchIndex+1)];
                }
                if(!downTree){
                    if(search.end){
                        hasMatch=true;
                        i=searchIndex;
                        str+=search.end;
                    }
                    break;
                }
                searchIndex++;
                search=downTree;
            }
            if(hasMatch){
                continue;
            }
            if(char.charCodeAt(0) > 10000){
                var tChar=stDict[char], sc2tcItem=sc2tc[char];
                if(tChar || sc2tcItem){
                    var newChar="";
                    if(sc2tcItem){
                        if(sc2tcItem.length==1){
                            newChar=sc2tcItem;
                        }else{
                            var defaultChar=sc2tcItem[0],char_f=[],char_b=[],r=i;
                            while(--r>=0 && char_f.length<3){
                                char_f.push(orgStr.charAt(r));
                            }
                            r=i;
                            while(++r<orgStr.length && char_b.length<3){
                                char_b.push(orgStr.charAt(r));
                            }
                            for(var j=1;j<sc2tcItem.length;j++){
                                var others=sc2tcItem[j],otherChar=others[0];
                                for(var k=1;k<others.length;k++){
                                    var curOther=others[k],fadd=curOther.indexOf(char),badd=curOther.length-1-fadd,x=0;
                                    var processChar=char;
                                    while(fadd-->0){
                                        if(char_f[x])processChar=char_f[x]+processChar;
                                    }
                                    x=0;
                                    while(badd-->0){
                                        if(char_b[x])processChar+=char_b[x];
                                    }
                                    if(processChar.indexOf(curOther) != -1){
                                        newChar=otherChar;
                                        break;
                                    }
                                }
                                if(newChar)break;
                            }
                            if(!newChar)newChar=defaultChar;
                        }
                    }else{
                        newChar=tChar;
                    }
                    str+=newChar;
                }else str+=char;
            }
            else str+=char;
        }
        return str;
    }

    function simplized(orgStr){
        if (!orgStr) return "";
        var str='', char;
        for(var i=0;i<orgStr.length;i++){
            char=orgStr.charAt(i);
            let search=tc2scCombTree[char],searchIndex=i,hasMatch=false;
            while(search && searchIndex<orgStr.length){
                let downTree=null;
                if(searchIndex<orgStr.length-1){
                    downTree=search[orgStr.charAt(searchIndex+1)];
                }
                if(!downTree){
                    if(search.end){
                        hasMatch=true;
                        i=searchIndex;
                        str+=search.end;
                    }
                    break;
                }
                searchIndex++;
                search=downTree;
            }
            if(hasMatch){
                continue;
            }
            if(char.charCodeAt(0) > 10000){
                var sChar=tsDict[char], tc2scItem=tc2sc[char];
                if(sChar || tc2scItem){
                    var newChar="";
                    if(tc2scItem){
                        if(tc2scItem.length==1){
                            newChar=tc2scItem;
                        }else{
                            var defaultChar=tc2scItem[0],char_f=[],char_b=[],r=i;
                            while(--r>=0 && char_f.length<3){
                                char_f.push(orgStr.charAt(r));
                            }
                            r=i;
                            while(++r<orgStr.length && char_b.length<3){
                                char_b.push(orgStr.charAt(r));
                            }
                            for(var j=1;j<tc2scItem.length;j++){
                                var others=tc2scItem[j],otherChar=others[0];
                                for(var k=1;k<others.length;k++){
                                    var curOther=others[k],fadd=curOther.indexOf(char),badd=curOther.length-1-fadd,x=0;
                                    var processChar=char;
                                    while(fadd-->0){
                                        if(char_f[x])processChar=char_f[x]+processChar;
                                    }
                                    x=0;
                                    while(badd-->0){
                                        if(char_b[x])processChar+=char_b[x];
                                    }
                                    if(processChar.indexOf(curOther) != -1){
                                        newChar=otherChar;
                                        break;
                                    }
                                }
                                if(newChar)break;
                            }
                            if(!newChar)newChar=defaultChar;
                        }
                    }else{
                        newChar=sChar;
                    }
                    str+=newChar;
                }else str+=char;
            }
            else str+=char;
        }
        return str;
    }

    function stranBody(pNode) {
        var childs;
        if (pNode) {
            childs = pNode.nodeType == 3 ? [pNode] : pNode.childNodes;
        } else {
            document.title = stranText(document.title);
            childs = document.documentElement.childNodes;
        }
        if (childs) {
            for (let i = 0;i<childs.length;i++) {
                let child=childs[i];
                if (/BR|META|SCRIPT|HR|STYLE/i.test(child.nodeName)) continue;
                if (child.getAttribute && child.getAttribute('translate') === 'no') continue;
                if (child.title) {
                    let title = stranText(child.title);
                    if (child.title != title) {
                        child.title = title;
                    }
                }
                if (child.alt) {
                    let alt = stranText(child.alt);
                    if (child.alt != alt) {
                        child.alt = alt;
                    }
                }
                if (child.getAttribute) {
                    let _placeholder = child.getAttribute('placeholder');
                    if (_placeholder) {
                        let placeholder = stranText(_placeholder);
                        if (_placeholder != placeholder) {
                            child.setAttribute('placeholder', placeholder);
                        }
                    }
                }
                if (/TEXTAREA/i.test(child.nodeName) || child.contentEditable == 'true') continue;
                if (/INPUT/i.test(child.nodeName) && child.value !== "" && child.type != "text" && child.type != "search" && child.type != "hidden") {
                    let value = stranText(child.value);
                    if (child.value != value) {
                        child.value = value;
                    }
                } else if(child.nodeType == 3) {
                    let data = stranText(child.data);
                    if (child.data != data) {
                        child.data = data;
                    }
                } else stranBody(child);
            }
        }
    }

    function showPinyinInit() {
        if (disablePinyin) return;
        if (pinyinTree) {
            showPinyinNode();
        } else {
            storage.getItem("pinyinTree", async value => {
                if (value) {
                    pinyinTree = value;
                    showPinyinNode();
                } else {
                    try {
                        pinyinTree = JSON.parse(await _GM_getResourceText("pinyinTree"));
                    } catch(e) {}
                    if (!pinyinTree) {
                        pinyinTree = {};
                        alert("拼音詞典加載失敗，請檢查網路服務或者禁用拼音顯示");
                    } else {
                        storage.setItem("pinyinTree", pinyinTree);
                        showPinyinNode();
                    }
                }
            });
        }
    }

    function showPinyinNode(pNode) {
        var childs;
        if (pNode) {
            childs = pNode.nodeType == 3 ? [pNode] : pNode.childNodes;
        } else {
            childs = document.body.childNodes;
        }
        if (childs) {
            for (let i = 0; i < childs.length; i++) {
                let child = childs[i];
                if (/^(RUBY|RB|RP)$/i.test(child.nodeName)) continue;
                if (child.nodeType == 1) showPinyinNode(child);
            }
            for (let i = 0; i < childs.length; i++) {
                let child = childs[i];
                if (child.nodeType == 3 && child.parentNode.offsetParent) showPinyin(child.data, child);
            }
        }
    }

    _GM_listValues = (cb) => {
        if (typeof GM_listValues != 'undefined') {
            cb(GM_listValues());
        } else if (typeof GM != 'undefined' && typeof GM.listValues != 'undefined') {
            GM.listValues().then(list => cb(list));
        } else if (window.localStorage) {
            let list = [];
            for(let i = 0, len = window.localStorage.length; i < len; i++) {
                let key = localStorage.key(i);
                list.push(key);
            }
            cb(list);
        } else {
            cb([]);
        }
    };
    if (typeof GM_registerMenuCommand != 'undefined') {
        _GM_registerMenuCommand = GM_registerMenuCommand;
    } else if (typeof GM != 'undefined' && typeof GM.registerMenuCommand != 'undefined') {
        _GM_registerMenuCommand = GM.registerMenuCommand;
    } else {
        _GM_registerMenuCommand = (s, f) => {};
    }
    if (typeof GM_notification != 'undefined') {
        _GM_notification = GM_notification;
    } else if (typeof GM != 'undefined' && typeof GM.notification != 'undefined') {
        _GM_notification = GM.notification;
    } else {
        _GM_notification = (s) => {alert(s)};
    }
    if (typeof GM_openInTab != 'undefined') {
        _GM_openInTab = GM_openInTab;
    } else if (typeof GM != 'undefined' && typeof GM.openInTab != 'undefined') {
        _GM_openInTab = GM.openInTab;
    } else {
        _GM_openInTab = (s, t) => {window.open(s)};
    }
    if (typeof GM_getResourceText != 'undefined') {
        _GM_getResourceText = GM_getResourceText;
    } else if (typeof GM != 'undefined' && typeof GM.getResourceText != 'undefined') {
        _GM_getResourceText = GM.getResourceText;
    } else {
        _GM_getResourceText = (s) => {};
    }
    if (typeof GM_info != 'undefined') {
        _GM_info = GM_info;
    } else if (typeof GM != 'undefined' && typeof GM.info != 'undefined') {
        _GM_info = GM.info;
    } else {
        _GM_info = {script: {}};
    }

    //將接口暴露出去
    var _unsafeWindow = (typeof unsafeWindow == 'undefined') ? window : unsafeWindow;
    _unsafeWindow.tc2sc = simplized;
    _unsafeWindow.sc2tc = traditionalized;

    var storage = {
        supportGM: typeof GM_getValue == 'function' && typeof GM_getValue('a', 'b') != 'undefined',
        supportGMPromise: typeof GM != 'undefined' && typeof GM.getValue == 'function' && typeof GM.getValue('a','b') != 'undefined',
        mxAppStorage: (function() {
            try {
                return window.external.mxGetRuntime().storage;
            } catch(e) {
            }
        })(),
        operaUJSStorage: (function() {
            try {
                return window.opera.scriptStorage;
            } catch(e) {
            }
        })(),
        setItem: function (key, value) {
            if (this.supportGM) {
                GM_setValue(key, value);
                if(value === "" && typeof GM_deleteValue != 'undefined'){
                    GM_deleteValue(key);
                }
            } else if (this.supportGMPromise) {
                GM.setValue(key, value);
                if(value === "" && typeof GM != 'undefined' && typeof GM.deleteValue != 'undefined'){
                    GM.deleteValue(key);
                }
            } else if (window.localStorage) {
                window.localStorage.setItem(key, value);
            } else if (this.operaUJSStorage) {
                this.operaUJSStorage.setItem(key, value);
            } else if (this.mxAppStorage) {
                this.mxAppStorage.setConfig(key, value);
            }
        },
        getItem: function (key, cb) {
            var value;
            if (this.supportGM) {
                value = GM_getValue(key);
            } else if (this.supportGMPromise) {
                value = GM.getValue(key).then(v=>{cb(v)});
                return;
            } else if (window.localStorage) {
                value = window.localStorage.getItem(key);
            } else if (this.operaUJSStorage) {
                value = this.operaUJSStorage.getItem(key);
            } else if (this.mxAppStorage) {
                value = this.mxAppStorage.getConfig(key);
            }
            cb(value);
        }
    };

    var keyCallNotSave = true;
    var curInput = null;
    var curLang;
    var currentAction = "action_" + location.hostname.toString().replace(/\./g,"_");
    function setLanguage(keyCall){
        enable = true;
        if (!keyCall || !keyCallNotSave) storage.setItem(currentAction, action);
        switch(action){
            case 1:
              if ( notification ) _GM_notification("已於該網域禁用簡繁切換");
              location.reload();
              break;
            case 2:
              if ( notification ) _GM_notification("已切换至简体中文");
              break;
            case 3:
              if ( notification ) _GM_notification("已切換至繁體中文");
              break;
        }
        if(action > 1){
            stranBody();
        }
    }

    function switchLanguage(){
        let reload = action === 1;
        translateAction(document.body);
        if (reload) location.reload();
    }

    function disableOnSite(){
        action = saveAction === 1 ? "" : 1;
        setLanguage();
        location.reload();
    }

    function translateAction(activeEle, keyCall){
        if(!activeEle)activeEle=document.activeElement;
        if("TEXTAREA"==activeEle.nodeName.toUpperCase()||activeEle.contentEditable=="true"){
            if (curInput != activeEle) {
                curLang = isSimple;
            }
            curLang=!curLang;
            activeEle.innerHTML=curLang?traditionalized(activeEle.innerHTML):simplized(activeEle.innerHTML);
            activeEle.value=curLang?traditionalized(activeEle.value):simplized(activeEle.value);
        }else if("INPUT"==activeEle.nodeName.toUpperCase()){
            if (curInput != activeEle) {
                curLang = isSimple;
            }
            curLang=!curLang;
            activeEle.value=curLang?traditionalized(activeEle.value):simplized(activeEle.value);
        }else{
            var selecter;
            if(window.getSelection()){
                selecter=window.getSelection();
            }else{
                selecter=document.getSelection();
            }
            selecter=document.getSelection();
            var selectStr=selecter.toString().trim();
            if(selectStr!=""){
                var rang = selecter.getRangeAt(0);
                rang.deleteContents();
                curLang=!curLang;
                rang.insertNode(document.createTextNode(curLang?traditionalized(selectStr):simplized(selectStr)));
            }else{
                action=action==2?3:2;
                setLanguage(keyCall);
            }
        }
        curInput = document.activeElement;
    }

    var saveAction;
    function run() {
        action=saveAction?saveAction:(isSimple?(auto?2:3):(auto?3:2));
        enable = !!(auto || saveAction);
        var transPool = [];
        var transWaiting = false;
        function transTask(node) {
            if (node) transPool.push(node);
            if (transWaiting) return;
            transWaiting = true;
            setTimeout(() => {
                transWaiting = false;
                if (transPool.length) {
                    for (let i = 0; i < transPool.length; i++) {
                        if (transPool[i]) {
                            stranBody(transPool[i]);
                        }
                    }
                    transPool = [];
                }
            }, 500);
        }
        let startStrans = () => {
            if (action == 1) return;
            stranBody();
            var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
            var observer = new MutationObserver(function(records) {
                records.map(function(record) {
                    let target = record.target;
                    let parentNode = target && target.parentNode;
                    while (target) {
                        if (/TEXTAREA/i.test(target.nodeName)) return;
                        if (/INPUT/i.test(target.nodeName) && (target.value === "" || target.type === "text" || target.type === "search" || target.type === "hidden")) {
                            return;
                        }
                        if (target.contentEditable == 'true') return;
                        if (target.nodeName.toUpperCase() == 'BODY') {
                            break;
                        }
                        target = target.parentNode;
                    }
                    if (record.type === "characterData") {
                        if (!parentNode) {
                            return;
                        }
                        transTask(parentNode);
                    }
                    if(record.addedNodes){
                        [].forEach.call(record.addedNodes,function(item){
                            transTask(item);
                        });
                    }
                });
            });
            var option = {
                childList: true,
                subtree: true,
                characterData: true
            };
            observer.observe(document.body, option);
        };
        setTimeout(function(){
            if (document.readyState !== 'complete') {
                let loadHandler = e => {
                    if (document.readyState !== 'complete') return;
                    document.removeEventListener("readystatechange", loadHandler);
                    startStrans();
                };
                document.addEventListener("readystatechange", loadHandler);
                return;
            } else {
                startStrans();
            }
        },50);

        curLang = isSimple;
        document.addEventListener("keydown", function(e) {
            if(e.key == shortcutKey && e.ctrlKey == ctrlKey && e.altKey == altKey && e.shiftKey == shiftKey && e.metaKey == metaKey) {
                translateAction(null, true);
            } else if(e.key == pinyinShortcutKey && e.ctrlKey == pinyinCtrlKey && e.altKey == pinyinAltKey && e.shiftKey == pinyinShiftKey && e.metaKey == pinyinMetaKey) {
                showPinyinInit();
            }
        });

        if (inConfigPage) {
            let parent = document.querySelector('#additional-info');
            let baseCon = document.createElement('div');
            baseCon.style.margin = '20px';
            parent.insertBefore(baseCon, parent.children[0]);
            let checkIndex = 0;
            let createCheckbox = (name, defaultValue) => {
                let box = document.createElement('div');
                let checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.checked = defaultValue;
                let id = 'stcnsc-checkbox' + checkIndex++;
                checkbox.id = id;
                let label = document.createElement('label');
                label.setAttribute('for', id);
                label.innerText = name;
                box.appendChild(checkbox);
                box.appendChild(label);
                baseCon.appendChild(box);
                return checkbox;
            };
            let autoInput = createCheckbox('總是自動切換', auto);
            let notificationInput = createCheckbox('切換成功通知', notification);
            let enablePinyinInput = createCheckbox('啟用拼音顯示', !disablePinyin);
            let keyCallNotSaveInput = createCheckbox('用快速鍵切換時不記憶選擇', keyCallNotSave);

            let defaultSimple = document.createElement('select');
            let cnOption = document.createElement('option');
            cnOption.value = 'cn';
            cnOption.innerHTML = '简体中文';
            defaultSimple.appendChild(cnOption);
            let trOption = document.createElement('option');
            trOption.value = 'tr';
            trOption.innerHTML = '正體中文';
            defaultSimple.appendChild(trOption);
            defaultSimple.value = isSimple ? 'cn' : 'tr';

            let defaultSimpleCon = document.createElement('div');
            defaultSimpleCon.style.display = 'flex';
            defaultSimpleCon.style.alignItems = 'center';
            let defaultSimpleTitle = document.createElement('h3');
            defaultSimpleTitle.style.margin = '5px 0';
            defaultSimpleTitle.innerText = '默認語言：';
            defaultSimpleCon.appendChild(defaultSimpleTitle);
            defaultSimpleCon.appendChild(defaultSimple);
            baseCon.appendChild(defaultSimpleCon);

            let shortcutCon = document.createElement('div');
            shortcutCon.style.display = 'flex';
            shortcutCon.style.alignItems = 'center';
            let shortcutTitle = document.createElement('h3');
            shortcutTitle.style.margin = '5px 0';
            shortcutTitle.innerText = '繁簡切換快速鍵：';
            shortcutCon.appendChild(shortcutTitle);
            let shortcutInput = document.createElement('input');
            shortcutInput.style.height = '20px';
            shortcutInput.style.width = '50px';
            shortcutInput.setAttribute('readonly', "readonly");
            shortcutInput.value = shortcutKey;
            shortcutInput.addEventListener("keydown", function(e) {
                if (e.key) {
                    shortcutInput.value = e.key;
                    e.stopPropagation();
                    e.preventDefault();
                }
            }, true);
            shortcutCon.appendChild(shortcutInput);
            baseCon.appendChild(shortcutCon);
            let ctrlKeyInput = createCheckbox('Ctrl 鍵', ctrlKey);
            let altKeyInput = createCheckbox('Alt 鍵', altKey);
            let shiftKeyInput = createCheckbox('Shift 鍵', shiftKey);
            let metaKeyInput = createCheckbox('Meta 鍵', metaKey);
            ctrlKeyInput.parentNode.style.float = "left";
            altKeyInput.parentNode.style.float = "left";
            shiftKeyInput.parentNode.style.float = "left";

            let pinyinShortcutCon = document.createElement('div');
            pinyinShortcutCon.style.display = 'flex';
            pinyinShortcutCon.style.alignItems = 'center';
            let pinyinShortcutTitle = document.createElement('h3');
            pinyinShortcutTitle.style.margin = '5px 0';
            pinyinShortcutTitle.innerText = '顯示拼音快速鍵：';
            pinyinShortcutCon.appendChild(pinyinShortcutTitle);
            let pinyinShortcutInput = document.createElement('input');
            pinyinShortcutInput.style.height = '20px';
            pinyinShortcutInput.style.width = '50px';
            pinyinShortcutInput.setAttribute('readonly', "readonly");
            pinyinShortcutInput.value = pinyinShortcutKey;
            pinyinShortcutInput.addEventListener("keydown", function(e) {
                if (e.key) {
                    pinyinShortcutInput.value = e.key;
                    e.stopPropagation();
                    e.preventDefault();
                }
            }, true);
            pinyinShortcutCon.appendChild(pinyinShortcutInput);
            baseCon.appendChild(pinyinShortcutCon);
            let pinyinCtrlKeyInput = createCheckbox('Ctrl 鍵', pinyinCtrlKey);
            let pinyinAltKeyInput = createCheckbox('Alt 鍵', pinyinAltKey);
            let pinyinShiftKeyInput = createCheckbox('Shift 鍵', pinyinShiftKey);
            let pinyinMetaKeyInput = createCheckbox('Meta 鍵', pinyinMetaKey);
            pinyinCtrlKeyInput.parentNode.style.float = "left";
            pinyinAltKeyInput.parentNode.style.float = "left";
            pinyinShiftKeyInput.parentNode.style.float = "left";

            let createHR = () => {
                baseCon.appendChild(document.createElement('hr'));
            };

            createHR();

            let siteChanged = false;
            let sitesTcTitle = document.createElement('h3');
            sitesTcTitle.style.margin = '5px 0';
            sitesTcTitle.innerText = '簡 → 繁站點：';
            baseCon.appendChild(sitesTcTitle);
            let sitesTcInput = document.createElement('textarea');
            sitesTcInput.placeholder = 'tieba.baidu.com\n一行一條';
            sitesTcInput.style.width = '100%';
            sitesTcInput.style.minHeight = "60px";
            baseCon.appendChild(sitesTcInput);

            let sitesScTitle = document.createElement('h3');
            sitesScTitle.style.margin = '5px 0';
            sitesScTitle.innerText = '繁 → 簡站點：';
            baseCon.appendChild(sitesScTitle);
            let sitesScInput = document.createElement('textarea');
            sitesScInput.placeholder = 'www.gamer.com.tw\n一行一條';
            sitesScInput.style.width = '100%';
            sitesScInput.style.minHeight = "60px";
            baseCon.appendChild(sitesScInput);

            let sitesDisableTitle = document.createElement('h3');
            sitesDisableTitle.style.margin = '5px 0';
            sitesDisableTitle.innerText = '禁用站點：';
            baseCon.appendChild(sitesDisableTitle);
            let sitesDisableInput = document.createElement('textarea');
            sitesDisableInput.placeholder = 'www.rthk.hk\n一行一條';
            sitesDisableInput.style.width = '100%';
            sitesDisableInput.style.minHeight = "60px";
            baseCon.appendChild(sitesDisableInput);

            sitesTcInput.addEventListener("change", function(e) {
                siteChanged = true;
            });
            sitesScInput.addEventListener("change", function(e) {
                siteChanged = true;
            });
            sitesDisableInput.addEventListener("change", function(e) {
                siteChanged = true;
            });


            let customTermTitle = document.createElement('h3');
            customTermTitle.style.margin = '5px 0';
            customTermTitle.innerText = '自訂簡繁用語轉換（可透過通配符設定生效網址範圍）：';

            let addNewGlob1 = document.createElement('button');
            addNewGlob1.innerText = '添加生效網站';
            addNewGlob1.addEventListener("click", function(e) {
                let glob = prompt("生效網站通配符", "https://google.com/*");
                if (!glob) return;
                let words = prompt("轉換用語", "简体,正體") || "";
                if (!sc2tcCombConfig[glob]) sc2tcCombConfig[glob] = {};
                if (words) {
                    words = words.split(/[,， ]/);
                    if (words.length == 2) {
                        sc2tcCombConfig[glob][words[0]] = words[1];
                    }
                }
                customTermInput.value = JSON.stringify(sc2tcCombConfig, null, 4);
            });
            customTermTitle.appendChild(addNewGlob1);

            var downloadTerm = document.createElement('a');
            downloadTerm.download = "簡繁轉換.json";
            downloadTerm.target = "_blank";
            let exportCustom1 = document.createElement('button');
            exportCustom1.innerText = '匯出';
            exportCustom1.addEventListener("click", function(e) {
                let blobStr = [(JSON.stringify(sc2tcCombConfig, null, 4))];
                let myBlob = new Blob(blobStr, { type: "application/json" });
                downloadTerm.href = window.URL.createObjectURL(myBlob);
                downloadTerm.click();
            });
            customTermTitle.appendChild(exportCustom1);

            let importCustom1 = document.createElement('input');
            importCustom1.accept = ".txt, .json";
            importCustom1.type = "file";
            importCustom1.id = "importCustom1";
            importCustom1.style.display = "none";
            let importCustomLabel1 = document.createElement('label');
            importCustomLabel1.innerText = '匯入';
            importCustomLabel1.htmlFor = 'importCustom1';
            let importCustomButton1 = document.createElement('button');
            importCustom1.addEventListener("change", function(e) {
                let reader = new FileReader();
                reader.readAsText(e.target.files[0]);
                reader.onload = function() {
                    try {
                        let jsonData = JSON.parse(this.result);
                        if (!sc2tcCombConfig) sc2tcCombConfig = {};
                        Object.keys(jsonData).forEach(key => {
                            sc2tcCombConfig[key] = jsonData[key];
                        });
                        customTermInput.value = JSON.stringify(sc2tcCombConfig, null, 4);
                    } catch (e) {
                        alert(e.toString());
                    }
                    importCustom1.value = "";
                };
            });
            customTermTitle.appendChild(importCustom1);
            importCustomButton1.appendChild(importCustomLabel1);
            customTermTitle.appendChild(importCustomButton1);

            baseCon.appendChild(customTermTitle);
            let customTermInput = document.createElement('textarea');
            customTermInput.style.width = '100%';
            customTermInput.style.minHeight = "60px";
            customTermInput.value = JSON.stringify(sc2tcCombConfig, null, 4);
            baseCon.appendChild(customTermInput);


            let customIlliteracyTitle = document.createElement('h3');
            customIlliteracyTitle.style.margin = '5px 0';
            customIlliteracyTitle.innerText = '通用字詞轉換（可透過通配符設定生效網址範圍）：';
            let addNewGlob2 = document.createElement('button');
            addNewGlob2.innerText = '添加生效網站';
            addNewGlob2.addEventListener("click", function(e) {
                let glob = prompt("生效網站通配符", "https://google.com/*");
                if (!glob) return;
                let words = prompt("轉換字詞", "yyds,永遠的神") || "";
                if (!illiteracyConfig[glob]) illiteracyConfig[glob] = {};
                if (words) {
                    words = words.split(/[,， ]/);
                    if (words.length == 2) {
                        illiteracyConfig[glob][words[0]] = words[1];
                    }
                }
                customIlliteracyInput.value = JSON.stringify(illiteracyConfig, null, 4);
            });
            customIlliteracyTitle.appendChild(addNewGlob2);

            var downloadIlliteracy = document.createElement('a');
            downloadIlliteracy.download = "用語詞典.json";
            downloadIlliteracy.target = "_blank";
            let exportCustom2 = document.createElement('button');
            exportCustom2.innerText = '匯出';
            exportCustom2.addEventListener("click", function(e) {
                let blobStr = [(JSON.stringify(illiteracyConfig, null, 4))];
                let myBlob = new Blob(blobStr, { type: "application/json" });
                downloadIlliteracy.href = window.URL.createObjectURL(myBlob);
                downloadIlliteracy.click();
            });
            customIlliteracyTitle.appendChild(exportCustom2);

            let importCustom2 = document.createElement('input');
            importCustom2.accept = ".txt, .json";
            importCustom2.type = "file";
            importCustom2.id = "importCustom2";
            importCustom2.style.display = "none";
            let importCustomLabel2 = document.createElement('label');
            importCustomLabel2.innerText = '匯入';
            importCustomLabel2.htmlFor = 'importCustom2';
            let importCustomButton2 = document.createElement('button');
            importCustom2.addEventListener("change", function(e) {
                let reader = new FileReader();
                reader.readAsText(e.target.files[0]);
                reader.onload = function() {
                    try {
                        let jsonData = JSON.parse(this.result);
                        if (!illiteracyConfig) illiteracyConfig = {};
                        Object.keys(jsonData).forEach(key => {
                            illiteracyConfig[key] = jsonData[key];
                        });
                        customIlliteracyInput.value = JSON.stringify(illiteracyConfig, null, 4);
                    } catch (e) {
                        alert(e.toString());
                    }
                    importCustom2.value = "";
                };
            });
            customIlliteracyTitle.appendChild(importCustom2);
            importCustomButton2.appendChild(importCustomLabel2);
            customIlliteracyTitle.appendChild(importCustomButton2);

            baseCon.appendChild(customIlliteracyTitle);
            let customIlliteracyInput = document.createElement('textarea');
            customIlliteracyInput.style.width = '100%';
            customIlliteracyInput.style.minHeight = "60px";
            customIlliteracyInput.value = JSON.stringify(illiteracyConfig, null, 4);
            baseCon.appendChild(customIlliteracyInput);

            let sitesList;
            _GM_listValues(list => {
                sitesList = list;
                sitesList.forEach(site => {
                    if (site.indexOf('action_') === 0 && site.length > 7) {
                        storage.getItem(site, _action => {
                            site = site.replace(/^action_/, '').replace(/_/g, '.') + '\n';
                            switch (_action) {
                                case 1:
                                    sitesDisableInput.value += site;
                                    break;
                                case 2:
                                    sitesScInput.value += site;
                                    break;
                                case 3:
                                    sitesTcInput.value += site;
                                    break;
                            }
                        });
                    }
                });
            });
            let buttonCon = document.createElement('div');
            let saveBtn = document.createElement('button');
            saveBtn.innerText = '保存設定';
            saveBtn.style.display = 'block';
            saveBtn.style.fontSize = 'x-large';
            saveBtn.style.fontWeight = 'bold';
            saveBtn.style.float = 'left';
            saveBtn.style.marginRight = '5px';
            saveBtn.style.pointerEvents = 'all';
            saveBtn.style.cursor = 'pointer';
            saveBtn.addEventListener("click", function(e) {
                auto = autoInput.checked;
                shortcutKey = shortcutInput.value;
                ctrlKey = ctrlKeyInput.checked;
                altKey = altKeyInput.checked;
                shiftKey = shiftKeyInput.checked;
                metaKey = metaKeyInput.checked;
                pinyinShortcutKey = pinyinShortcutInput.value;
                pinyinCtrlKey = pinyinCtrlKeyInput.checked;
                pinyinAltKey = pinyinAltKeyInput.checked;
                pinyinShiftKey = pinyinShiftKeyInput.checked;
                pinyinMetaKey = pinyinMetaKeyInput.checked;
                notification = notificationInput.checked;
                disablePinyin = !enablePinyinInput.checked;
                keyCallNotSave = keyCallNotSaveInput.checked;
                isSimple = defaultSimple.value == 'cn';

                if (siteChanged) {
                    if (sitesList) {
                        sitesList.forEach(site => {
                            if (site.indexOf('action_') === 0) {
                                storage.setItem(site, "");
                            }
                        });
                    }
                    sitesDisableInput.value.trim().split('\n').forEach(site => {
                        if (site.trim()) storage.setItem("action_" + site.replace(/\./g,"_"), 1);
                    });
                    sitesScInput.value.trim().split('\n').forEach(site => {
                        if (site.trim()) storage.setItem("action_" + site.replace(/\./g,"_"), 2);
                    });
                    sitesTcInput.value.trim().split('\n').forEach(site => {
                        if (site.trim()) storage.setItem("action_" + site.replace(/\./g,"_"), 3);
                    });
                }
                storage.setItem('auto', auto);
                storage.setItem('shortcutKey', shortcutKey);
                storage.setItem('ctrlKey', ctrlKey);
                storage.setItem('altKey', altKey);
                storage.setItem('shiftKey', shiftKey);
                storage.setItem('metaKey', metaKey);
                storage.setItem('pinyinShortcutKey', pinyinShortcutKey);
                storage.setItem('pinyinCtrlKey', pinyinCtrlKey);
                storage.setItem('pinyinAltKey', pinyinAltKey);
                storage.setItem('pinyinShiftKey', pinyinShiftKey);
                storage.setItem('pinyinMetaKey', pinyinMetaKey);
                storage.setItem('notification', notification);
                storage.setItem('isSimple', isSimple);
                storage.setItem('disablePinyin', disablePinyin);
                storage.setItem('keyCallNotSave', keyCallNotSave);
                try {
                    sc2tcCombConfig = customTermInput.value ? JSON.parse(customTermInput.value) : "";
                    storage.setItem('sc2tcCombConfig', sc2tcCombConfig);
                } catch (e) {
                    console.log(e);
                    alert("自訂簡繁用語轉換格式錯誤：" + e);
                    return;
                }
                try {
                    illiteracyConfig = customIlliteracyInput.value ? JSON.parse(customIlliteracyInput.value) : "";
                    storage.setItem('illiteracyConfig', illiteracyConfig);
                } catch (e) {
                    console.log(e);
                    alert("通用字詞轉換格式錯誤：" + e);
                    return;
                }
                storage.setItem('sc2tcCombTree', "");
                storage.setItem('tc2scCombTree', "");
                storage.setItem('fuckIlliteracyTree', "");
                alert('保存設定成功！');
                location.reload();
            });
            buttonCon.appendChild(saveBtn);
            let clearBtn = document.createElement('button');
            clearBtn.innerText = '清除預處理緩存';
            clearBtn.style.display = 'block';
            clearBtn.style.fontSize = 'x-large';
            clearBtn.style.fontWeight = 'bold';
            clearBtn.style.pointerEvents = "all";
            clearBtn.style.cursor = "pointer";
            clearBtn.addEventListener("click", function(e) {
                storage.setItem('stDict', "");
                storage.setItem('tsDict', "");
                storage.setItem('sc2tcCombTree', "");
                storage.setItem('tc2scCombTree', "");
                storage.setItem('fuckIlliteracyTree', "");
                storage.setItem('pinyinTree', "");
                alert('清除成功！');
                location.reload();
            });
            buttonCon.appendChild(clearBtn);
            buttonCon.style.cssText = "width: 100%; position: fixed; z-index: 999; bottom: 0px; left: 0px; display: flex; justify-content: center; background: #00000060; padding-bottom: 10px; pointer-events: none;";
            baseCon.appendChild(buttonCon);

            createHR();

            let testTitle = document.createElement('h3');
            testTitle.style.margin = '50px 0 5px 0';
            testTitle.innerText = '繁簡切換測試輸入框：';
            baseCon.appendChild(testTitle);
            let testInput = document.createElement('textarea');
            testInput.style.width = '100%';
            testInput.setAttribute('placeholder', "輸入文字后，按下快速鍵");
            testInput.onclick = e => {
                if (!testInput.style.height) {
                    testInput.style.height = "80vh";
                    testInput.scrollIntoView({block: "center", inline: "nearest"});
                }
            };
            baseCon.appendChild(testInput);
            let testTcBtn = document.createElement('button');
            testTcBtn.innerText = '切換正體';
            testTcBtn.style.display = 'block';
            testTcBtn.style.marginRight = '5px';
            testTcBtn.addEventListener("click", function(e) {
                testInput.value=traditionalized(testInput.value);
                testInput.focus();
            });
            let testScBtn = document.createElement('button');
            testScBtn.innerText = '切换简体';
            testScBtn.style.display = 'block';
            testScBtn.addEventListener("click", function(e) {
                testInput.value=simplized(testInput.value);
                testInput.focus();
            });
            let testBtnGroup = document.createElement('div');
            testBtnGroup.style.display = "flex";
            testBtnGroup.appendChild(testTcBtn);
            testBtnGroup.appendChild(testScBtn);
            baseCon.appendChild(testBtnGroup);
        }
    }

    //不想用await
    function getMulValue(keyList, callback, values) {
        if (!values) values = {};
        let curKey = keyList.shift();
        if (curKey) {
            storage.getItem(curKey, value => {
                values[curKey] = value;
                getMulValue(keyList, callback, values);
            });
        } else {
            callback(values);
        }
    }

    function globMatch(first, second) {
        if (first === '*') {
            return true;
        }
        if (first.length == 0 && second.length == 0){
            return true;
        }
        if (first.length > 1 && first[0] == '*' &&
            second.length == 0){
            return false;
        }
        if ((first.length > 1 && first[0] == '?') ||
            (first.length != 0 && second.length != 0 &&
             first[0] == second[0])){
            return globMatch(first.substring(1),
                             second.substring(1));
        }
        if (first.length > 0 && first[0] == '*'){
            return globMatch(first.substring(1), second) ||
                globMatch(first, second.substring(1));
        }
        return false;
    }

    getMulValue(["version", "auto", "shortcutKey", "ctrlKey", "altKey", "shiftKey", "metaKey", "disablePinyin", "keyCallNotSave", "pinyinShortcutKey", "pinyinCtrlKey", "pinyinAltKey", "pinyinShiftKey", "pinyinMetaKey", "sc2tcCombConfig", "illiteracyConfig", "notification", "isSimple", "sc2tcCombTree", "tc2scCombTree", "fuckIlliteracyTree", "stDict", "tsDict", currentAction], async values => {
        if (_GM_info.script && _GM_info.script.version && _GM_info.script.version !== '1.0.0' && values.version != _GM_info.script.version) {
            storage.setItem('version', _GM_info.script.version);
            storage.setItem('stDict', "");
            storage.setItem('tsDict', "");
            storage.setItem('sc2tcCombTree', "");
            storage.setItem('tc2scCombTree', "");
            storage.setItem('fuckIlliteracyTree', "");
            values.stDict = "";
            values.tsDict = "";
            values.sc2tcCombTree = "";
            values.tc2scCombTree = "";
            values.fuckIlliteracyTree = "";
        }
        let href = location.href.slice(0, 500);
        if (values.sc2tcCombConfig) {
            auto = values.auto;
            shortcutKey = values.shortcutKey;
            ctrlKey = values.ctrlKey;
            altKey = values.altKey;
            shiftKey = values.shiftKey;
            metaKey = values.metaKey;
            disablePinyin = !!values.disablePinyin;
            keyCallNotSave = !!values.keyCallNotSave;
            if (values.pinyinShortcutKey) {
                pinyinShortcutKey = values.pinyinShortcutKey;
                pinyinCtrlKey = values.pinyinCtrlKey;
                pinyinAltKey = values.pinyinAltKey;
                pinyinShiftKey = values.pinyinShiftKey;
                pinyinMetaKey = values.pinyinMetaKey;
            }
            sc2tcCombConfig = values.sc2tcCombConfig;
            notification = values.notification;
            if (typeof values.isSimple != 'undefined') isSimple = values.isSimple;
            sc2tcComb = {};
            for (let key in sc2tcCombConfig) {
                 if (globMatch(key, href)) {
                     let sc2tc = sc2tcCombConfig[key];
                     for (let sc in sc2tc) {
                         sc2tcComb[sc] = sc2tc[sc];
                     }
                 }
            }
        }
        if (values.illiteracyConfig) {
            illiteracyConfig = values.illiteracyConfig;
            fuckIlliteracy = {};
            for (let key in illiteracyConfig) {
                 if (globMatch(key, href)) {
                     let illiteracy = illiteracyConfig[key];
                     for (let w in illiteracy) {
                         fuckIlliteracy[w] = illiteracy[w];
                     }
                 }
            }
        }
        if (values.sc2tcCombTree && values.tc2scCombTree) {
            sc2tcCombTree = values.sc2tcCombTree;
            tc2scCombTree = values.tc2scCombTree;
        } else {
            function makeCombTree(key, value) {
                let curTree=sc2tcCombTree;
                for(let i=0;i<key.length;i++){
                    let curKey=key.charAt(i);
                    let branch=curTree[curKey];
                    let newTree={};
                    if(i==key.length-1){
                        newTree={"end":value};
                        if(branch){
                            branch.end=value;
                        }
                    }
                    if(branch){
                        curTree=branch;
                    }else{
                        curTree[curKey]=newTree;
                        curTree=newTree;
                    }
                }
                curTree=tc2scCombTree;
                for(let i=0;i<value.length;i++){
                    let curKey=value.charAt(i);
                    let branch=curTree[curKey];
                    let newTree={};
                    if(i==value.length-1){
                        newTree={"end":key};
                        if(branch){
                            branch.end=value;
                        }
                    }
                    if(branch){
                        curTree=branch;
                    }else{
                        curTree[curKey]=newTree;
                        curTree=newTree;
                    }
                }
            }
            for(let key in sc2tcComb){
                let value=sc2tcComb[key];
                if (Array.isArray(value)) {
                    value.forEach(v => {
                        makeCombTree(key, v);
                    });
                } else {
                    makeCombTree(key, value);
                }
            }
            storage.setItem("sc2tcCombTree", sc2tcCombTree);
            storage.setItem("tc2scCombTree", tc2scCombTree);
        }
        if (values.fuckIlliteracyTree) {
            fuckIlliteracyTree = values.fuckIlliteracyTree;
        } else {
            for(let key in fuckIlliteracy){
                let value=fuckIlliteracy[key];
                let curTree=fuckIlliteracyTree;
                for(let i=0;i<key.length;i++){
                    let newTree={};
                    if(i==key.length-1){
                        newTree={"end":value};
                    }
                    let curKey=key.charAt(i).toLowerCase();
                    let branch=curTree[curKey];
                    if(!branch){
                        curTree[curKey]=newTree;
                        curTree=newTree;
                    }else{
                        curTree=branch;
                    }
                }
            }
            storage.setItem("fuckIlliteracyTree", fuckIlliteracyTree);
        }
        if (values.stDict && values.tsDict) {
            stDict = values.stDict;
            tsDict = values.tsDict;
        } else {
            for(let i=0;i<scStr.length;i++){
                let _sc=scStr[i];
                let _tc=tcStr[i];
                if(!stDict[_sc])stDict[_sc]=_tc;
                if(!tsDict[_tc])tsDict[_tc]=_sc;
            }
            Object.keys(oc2tc).forEach(key => {
                let ocList=oc2tc[key];
                for(let i=0;i<ocList.length;i++){
                    let oc=ocList[i];
                    stDict[oc]=key;
                    tsDict[oc]=tsDict[key]||key;
                }
            })
            storage.setItem("stDict", stDict);
            storage.setItem("tsDict", tsDict);
        }
        saveAction = values[currentAction];
        if (saveAction !== 1 || inConfigPage) run();
        if (window.top != window.self) return;
        _GM_registerMenuCommand("繁簡切換", switchLanguage);
        let currentState = "";
        switch (saveAction) {
            case 2:
                currentState = "（简体）";
                break;
            case 3:
                currentState = "（正體）";
                break;
        }
        if (!disablePinyin) {
            _GM_registerMenuCommand("顯示拼音", () => showPinyinInit());
        }

        _GM_registerMenuCommand("個性設定", () => {
            _GM_openInTab("https://greasyfork.org/scripts/24300", {active: true});
        });
        _GM_registerMenuCommand(saveAction === 1 ? "取消禁用" : "此站禁用" + currentState, disableOnSite);
        if (!isSimple) {
            _GM_registerMenuCommand("提交詞彙", () => {
                _GM_openInTab("https://github.com/hoothin/UserScripts/issues", {active: true});
            });
        }
    });

})();
