Fast-Codeforces

Make Codeforces convenient

  1. // ==UserScript==
  2. // @name Fast-Codeforces
  3. // @namespace xcxcli
  4. // @version 0.3.5.4
  5. // @match *://codeforces.com/*
  6. // @match *://codeforces.ml/*
  7. // @description Make Codeforces convenient
  8. // @author xcxcli
  9. // ==/UserScript==
  10. unsafeWindow.onload=function(){
  11. let $=unsafeWindow.jQuery,math=unsafeWindow.MathJax.Hub,Codeforces=unsafeWindow.Codeforces;
  12. $.default=function(obj,val){
  13. for(let i in obj)if(!(i in val))delete obj[i];
  14. for(let i in val)if(!(i in obj))obj[i]=val[i];
  15. return obj;
  16. };
  17. String.prototype.frl=function(c){
  18. if(this.indexOf(c)===-1)return this;
  19. return this.slice(0,this.indexOf(c));
  20. };
  21. String.prototype.frr=function(c){
  22. if(this.indexOf(c)===-1)return this;
  23. return this.slice(this.indexOf(c)+c.length);
  24. };
  25. String.prototype.last=function(){return this[this.length-1];}
  26. String.prototype.replaceAll=function(s1,s2){return this.split(s1).join(s2);};
  27. let gets=function(dir,val){
  28. if(("fc-"+dir)in localStorage===false||localStorage["fc-"+dir]==="undefined")return val;
  29. return JSON.parse(localStorage["fc-"+dir]);
  30. },puts=function(dir,val){
  31. if(val!==void 0)localStorage["fc-"+dir]=JSON.stringify(val);
  32. else localStorage["fc-"+dir]="undefined";
  33. },noop=function(){},Alert=Codeforces.alert,version="v0.3.5.4",
  34. Confirm=function(str,fy,fn=noop,y="确定",n="取消"){Codeforces.confirm(str,fy,fn,y,n);$("#fc-input").focus();},
  35. URLmatch=function(url){
  36. if(!url)url=location.href;
  37. if(url[0]==="/")url=location.origin+url;
  38. if(url[0]===".")url=location.href+url;
  39. url=new URL(url);
  40. if(url.pathname.slice(-1)==='/')url.pathname=url.pathname.slice(0,-1);
  41. return{host:url.origin,path:url.pathname,parr:url.pathname.split('/').slice(1)};
  42. },
  43. GetTitle=function(val){return val.slice(0,val.indexOf("</title>")).slice(val.indexOf("<title>")+7);},
  44. fc=$.default(gets("fc",{}),{version:version,ele:[],using:false,mode:[]}),
  45. user=$(".lang-chooser>div:eq(1)>a:eq(0)").html(),user_csrf=$("[name=X-Csrf-Token]").attr("content"),
  46. show_pre=function(){$("#pageContent,#pre-bar").show();},hide_pre=function(){$("#pageContent,#pre-bar").hide();},
  47. menu,fc_need=["fc","pro-user","sub-user","sta-user"],Clear=function(){
  48. for(let i in localStorage){
  49. if(i.slice(0,3)!=="fc-")continue;
  50. let j=i.slice(3);
  51. if(fc_need.indexOf(j)<0)delete localStorage[i];
  52. }
  53. },default_set=function(){for(let i in localStorage)if(i.slice(0,3)==="fc-"&&i!=="fc-fc")delete localStorage[i];},
  54. add_menu=function(id){
  55. $("#fc-setting-menu-add").append(`<li><a id="fc-setting-menu-`+id+`">`+eles[id].name+`</a></li>`);
  56. $("#fc-setting-menu-"+id).click(function(){$(this).parent().remove(),menu.splice(menu.indexOf(id),1),sub_menu(id);});
  57. },
  58. sub_menu=function(id){
  59. $("#fc-setting-menu-sub").append(`<li><a id="fc-setting-menu-`+id+`">`+eles[id].name+`</a></li>`);
  60. $("#fc-setting-menu-"+id).click(function(){$(this).parent().remove(),menu.push(id),add_menu(id);});
  61. },
  62. sta_default={auto_open:true,interval:5000},sta_user,sta_t=0,sta_cnt=0,
  63. get_sta=function(user,cnt,page=1,show=true){
  64. let tmp={csrf_token:user_csrf,action:"toggleShowUnofficial"},load=$("#fc-status-load"),loadstr="",t=sta_t;
  65. if(show)tmp.showUnofficial="on";
  66. clearInterval(sta_t),load.html("");
  67. if(cnt!==sta_cnt)return;
  68. sta_t=setInterval(function(){loadstr=loadstr.length===2?"":loadstr+".",$("#fc-status-load").html("Loading"+loadstr);},500);
  69. $.ajax({url:"/submissions/"+user+"/page/"+page,type:"POST",data:tmp,error:function(e){Alert("出错了");return;},
  70. success:function(e){
  71. clearInterval(sta_t),load.html("");
  72. if(cnt!==sta_cnt)return;
  73. let val=$(e),tpage=val.find(".active").attr("pageindex");
  74. try{if(val.find(".second-level-menu-list a:eq(0)").html().toLowerCase()!==user.toLowerCase()){Alert("该用户不存在");return;}}
  75. catch(e){Alert("该用户不存在");return;}
  76. if(tpage!=page&&(tpage!==void 0||page!=1)){Alert("该记录不存在");return;}
  77. val=val.find("#pageContent"),val.children(":eq(0)").remove(),val.children(":eq(0)").remove(),val.find(".pagination").remove(),$("#fc-status-main").html(val.html());
  78. if(sta_user.interval>=0)setTimeout(function(){get_sta(user,cnt,page,show);},sta_user.interval);
  79. }});
  80. },
  81. sub_default={auto_open:true},sub_user,
  82. getsub=function(func){
  83. let sub=gets("sub");
  84. if(sub!==void 0){$("#fc-submit-form").html(sub),func();return;}
  85. $.ajax({type:"GET",data:{},url:"/problemset/submit",error:function(e){Alert("获取提交界面失败");},
  86. success:function(e){
  87. sub=$(e).find(".submit-form"),sub.find("tr:nth-child(5)").remove(),sub.find(".submit").attr("id","fc-submit-button");
  88. sub.find(".aceEditorTd").html(`<textarea style="width:600px;height:300px;resize:none" name="source"></textarea><br/>`);
  89. sub.find("[name=submittedProblemCode]").attr("name","submittedProblemIndex"),sub=sub.html(),puts("sub",sub),$("#fc-submit-form").html(sub),func();
  90. }});
  91. },
  92. pro_default={mem:0,auto_open:false},pro_user,prepro,prolist,focpro,promap={},
  93. showpro=function(id){$("#fc-problem-menu-"+id).addClass("focpro"),$("#fc-problem-"+id+",#fc-bar-problem-"+id).show();},
  94. hidepro=function(id){$("#fc-problem-menu-"+id).removeClass("focpro"),$("#fc-problem-"+id+",#fc-bar-problem-"+id).hide();},
  95. add_pro=function(pro,x,y){
  96. pro.find(".sample-test .title").each(function(){//Changed Form Codeforces
  97. let preId=("id"+Math.random()).replaceAll(".","0"),cpyId=("id"+Math.random()).replaceAll(".", "0");
  98. let $copy=$(`<div title="Copy" data-clipboard-target="#`+preId+`" id="`+cpyId+`" class="input-output-copier">Copy</div>`);
  99. $(this).parent().find("pre").attr("id", preId),$(this).append($copy);
  100. let clipboard=new unsafeWindow.Clipboard('#'+cpyId,{
  101. text:function(trigger){return Codeforces.filterClipboardText(document.querySelector('#'+preId).innerText);}
  102. }),isInput=$(this).parent().hasClass("input");
  103. clipboard.on('success',function(e){Alert("The example "+(isInput?"input":"output")+" has been copied into the clipboard");e.clearSelection();});
  104. });
  105. x+=y,pro=[pro.find(`.problem-statement`),pro.find(`#sidebar`)],promap[x]=0;
  106. $("#fc-problem-menu-add").before(`<li id="fc-problem-menu-`+x+`"><a>`+x+`</a><a>X</a></li>`);
  107. $("#fc-problem-menu-"+x+">a:eq(0)").click(function(){if(focpro!==void 0)hidepro(focpro),showpro(focpro=this.innerHTML);});
  108. $("#fc-problem-menu-"+x+">a:eq(1)").click(function(){
  109. let fa=$(this).parent(),id=fa.children()[0].innerHTML,pos=prolist.indexOf(id);delete promap[prolist[pos]],prolist.splice(pos,1);
  110. if(focpro===id){
  111. if(pos===prolist.length)--pos;
  112. if(pos!==-1)focpro=prolist[pos],showpro(focpro);
  113. else focpro=void 0;
  114. }
  115. fa.remove(),$("#fc-problem-"+id).remove(),$("#fc-bar-problem-"+id).remove(),puts("pro-list",prolist);
  116. });
  117. $("#fc-problem-contain").append(pro[0].attr("id","fc-problem-"+x));$("#fc-bar-problem").append(pro[1].attr("id","fc-bar-problem-"+x));
  118. if(focpro!==void 0)hidepro(focpro);
  119. showpro(x),prolist.push(focpro=x),math.Queue(["Typeset",math,"fc-problem-"+x]),puts("pro-list",prolist);
  120. },
  121. addpro=function(x,y){
  122. let load=$(`<li id="fc-problem-memu-add-`+x+y+`"><a></a></li>`),loadstr="";promap[x+y]=1,$("#fc-problem-menu").append(load);
  123. let t=setInterval(function(){loadstr=loadstr.length===2?"":loadstr+".",load.find("a").html("Loading "+x+y+loadstr);},400);
  124. $.ajax({type:"GET",data:{},url:"/contest/"+x+"/problem/"+y,error:function(e){clearInterval(t),load.remove(),Alert("出错了!");},
  125. success:function(e){
  126. clearInterval(t),load.remove();let pro=$(e),title=GetTitle(e);
  127. if((title!=="Problem - "+y+" - Codeforces (Unofficial mirror site by GGAutomaton, accelerated for Chinese users)"&&title!=="Problem - "+y+
  128. " - Codeforces")||!pro.find(`#sidebar a[href="/contest/`+x+`"]`).length){delete promap[x+y],Alert("题目"+x+y+"不存在");return;}
  129. add_pro(pro,x,y);
  130. }});
  131. },
  132. newpro=function(Id){
  133. if(Id===""||Id===null)return;
  134. if(typeof Id!=="string"){Alert("请输入正确的题号");return;}
  135. if(promap[Id]===0){Alert("该题目已在序列中");return;}
  136. if(promap[Id]===1){Alert("该题目已在加载中");return;}
  137. if(!/^[0-9]+[A-Za-z][1|2]?$/.test(Id)){Alert("请输入正确的题号");return;}
  138. let id=Id.last(),cid;
  139. if(parseInt(id)>0)id=Id.slice(-2),cid=parseInt(Id.slice(0,Id.length-2));
  140. else cid=parseInt(Id.slice(0,Id.length-1));
  141. addpro(cid,id);
  142. },
  143. pre_pro=function(){for(let i=0;i<prepro.length;++i)newpro(prepro[i]);},
  144. modes={"contest":{name:"比赛",js:[],css:[]}},
  145. eles={"problem":{name:"查看题目",js:[],css:["sidebar-menu","status"],
  146. init:function(){
  147. pro_user=$.default(gets("pro-user",{}),pro_default),prolist=[],promap={},puts("pro-user",pro_user),prepro=gets("pro-list");
  148. $("#pageContent").after($(`<div id="fc-problem" class="fc-main" style="display:none"><div class="second-level-menu">
  149. <ul class="second-level-menu-list" id="fc-problem-menu">
  150. <li id="fc-problem-menu-add"><a>+add problem</a></li><li id="fc-problem-menu-close"><a>-hide window</a></li>
  151. </ul></div><div class="problemindexholder">
  152. <a href="javascript:;" id="fc-problem-submit" style="float:right">提交</a><div class="ttypography" id="fc-problem-contain"></div></div></div>`));
  153. $("#fc-problem-submit").click(function(){
  154. if(ele.indexOf("submit")<0){Alert("请先在设置中打开“快速提交”功能");return;}
  155. Change("submit"),$("#fc-submit .ace_text-input").focus();
  156. if(focpro!==void 0)$("#fc-submit [name=submittedProblemIndex]").val(focpro);
  157. });
  158. $("#fc-problem-menu-close").click(function(){Change("problem");});$("#fc-bar-menu").after(`<div id="fc-bar-problem" style="display:none"></div>`);
  159. $("#fc-problem-menu-add").click(function(){Confirm(`请输入题目编号:<input id="fc-input"/>`,function(){newpro($("#fc-input").val());});});
  160. $("#fc-problem-menu-add").hover(function(){let x=$("#fc-problem-menu>.backLava");if(x.length>0)x.remove();});
  161. var url=URLmatch();
  162. if(/https+:\/\/codeforces\.[com|ml]/.test(url.host)&&(/^\/problemset\/problem\/[1-9][0-9]*\/[A-Z]$/.test(url.path)||/^\/contest\/[1-9][0-9]*\/problem\/[A-Z]$/.test(url.path)))
  163. $(`<a href="javascript:;" style="position:absolute;right:0;top:0">添加到题目</a>`).prependTo($('#pageContent .problemindexholder')).click(function(){
  164. Change("problem");var x=url.path.match(/[1-9][0-9]*/)[0],y=url.path.match(/[A-Z]/)[0];
  165. if(prolist.indexOf(x+y)>=0){$('#fc-problem-menu-'+x+y).click(),Alert("该题目已在序列中");return;}
  166. add_pro($('#pageContent .problemindexholder').clone(),x,y);
  167. });
  168. if(pro_user.mem==2)pre_pro();
  169. else if(pro_user.mem==1&&prepro.length>0)Confirm("您上次浏览的题目未关闭,要重新加载吗?",function(){Change("problem"),pre_pro();},function(){puts("pro-list",[]);});
  170. else puts("pro-list",[]);
  171. if(pro_user.auto_open)$(document).click(function(e){
  172. let url=$(e.toElement).attr("href");if(url==null)return true;url=URLmatch(url);
  173. if(!/https+:\/\/codeforces\.[com|ml]/.test(url.host))return true;
  174. if(!/^\/problemset\/problem\/[1-9][0-9]*\/[A-Z]$/.test(url.path)&&!/^\/contest\/[1-9][0-9]*\/problem\/[A-Z]$/.test(url.path))return true;
  175. Change("problem"),newpro(url.path.match(/[1-9][0-9]*/)[0]+"/"+url.path.match(/[A-Z]/)[0]);return false;
  176. });
  177. },remove:function(){$("#fc-problem").remove(),$("#fc-bar-problem").remove();},
  178. hide:function(){$("#fc-problem,#fc-bar-problem").hide(),$("#fc-menu-problem").css("background-color","white");},
  179. show:function(){$("#fc-problem,#fc-bar-problem").show(),$("#fc-menu-problem").css("background-color","#AAAAAA");},
  180. set:function(){
  181. $("#fc-setting-clear").before($(`<div><div class="section-title">题目设置</div><br/>
  182. <p><span>上一次未关闭的题目是否打开:</span><select id="fc-setting-problem-memory">
  183. <option value="0">否</option><option value="1">我自己决定是否打开</option><option value="2">自动打开</option>
  184. </select></p><input type="checkbox" id="fc-setting-problem-auto_open"/>
  185. <label for="fc-setting-problem-auto_open">点击题目链接时在"查看题目"中将其打开<span class="fc-care">*</span></label>
  186. <br/><br/><button type="button" id="fc-setting-problem-end">保存</button><hr/></div>`));
  187. if(pro_user.auto_open)$("#fc-setting-problem-auto_open").attr("checked","checked");
  188. $("#fc-setting-problem-end").click(function(){
  189. pro_user={mem:$("#fc-setting-problem-memory>option:selected").val(),auto_open:$("#fc-setting-problem-auto_open:checked").length===1};
  190. puts("pro-user",pro_user),Alert("修改成功");
  191. });
  192. $("#fc-setting-problem-memory>option:eq("+pro_user.mem+")").attr("selected","selected");
  193. }},"submit":{name:"提交代码",js:[],css:[],
  194. init:function(){
  195. sub_user=$.default(gets("sub-user",{}),sub_default),puts("sub-user",sub_user);
  196. $("#pageContent").after($(`<div id="fc-submit" class="fc-main" style="display:none">
  197. <form id="fc-submit-form" method="post" enctype="multipart/form-data" target="_blank"></form></div>`));
  198. getsub(function(){$("#fc-submit-button").click(function(){
  199. $("#fc-submit .fc-care").remove();let val=$("#fc-submit [name=submittedProblemIndex]").val();
  200. if(val===""){$("#fc-submit .error__submittedProblemIndex").html(`<span class="fc-care">Choose the problem</span>`);return false;}
  201. if(!/^[0-9]+[A-Za-z][1|2]?$/.test(val)){$("#fc-submit .error__submittedProblemIndex").html(`<span class="fc-care">Input a legal problem</span>`);return false;}
  202. let id=val.last(),cid;
  203. if(parseInt(id)>0)id=val.slice(-2),cid=parseInt(val.slice(0,val.length-2));
  204. else cid=parseInt(val.slice(0,val.length-1));
  205. if($("#fc-submit [name=source]").val()===""){$("#fc-submit .aceEditorTd").append(`<span class="fc-care">Put you source into the textarea</span>`);return false;}
  206. $("#fc-submit [name=submittedProblemIndex]").val(id);
  207. if(!sub_user.auto_open||ele.indexOf("status")<0){$("#fc-submit-form").attr("action",`/contest/`+cid+`/submit?csrf_token=`+user_csrf);return true;}
  208. $.ajax({type:"POST",url:`/contest/`+cid+`/submit?csrf_token=`+user_csrf,error:function(e){Alert("提交失败");return;},data:{
  209. csrf_token:user_csrf,action:"submitSolutionFormSubmitted",submittedProblemIndex:$("#fc-submit [name=submittedProblemIndex]").val(),
  210. programTypeId:$("#fc-submit [name=programTypeId]>option:selected").val(),source:$("#fc-submit [name=source]").val()},
  211. success:function(e){
  212. let sub=$(e);
  213. if(!sub.find(`#sidebar a[href="/contest/`+cid+`"]`).length){Alert("该题目不存在!");return;}
  214. if(sub.find(".error.for__source").length){Alert("您已经提交过相同的代码!");return;}
  215. if(GetTitle(e).substr(0,6)!=="Status"){Alert("该题目不存在!");return;}
  216. }
  217. });
  218. Change("status"),$("#fc-status-user").val(user),$("#fc-status-page").val(1),$("#fc-status-show").attr("checked","checked");
  219. $("#fc-status-see").click(),document.documentElement.scrollTop=0;return false;
  220. });});
  221. },set:function(){
  222. $("#fc-setting-clear").before(`<div><div class="section-title">提交设置</div><br/>
  223. <span>点击提交时:</span><select name="auto_open" id="fc-setting-submit-auto_open">
  224. <option value="true">若开启了“查看状态”,则进行跳转</option><option value="false">打开“status”页面</option>
  225. </select><span class="fc-care">*</span><br/><br/><button type="button" id="fc-setting-submit-end">保存</button><hr/></div>`);
  226. $("#fc-setting-submit-auto_open>option:eq("+(sub_user.auto_open===true?0:1)+")").attr("selected","selected");
  227. $("#fc-setting-submit-end").click(function(){sub_user={auto_open:$("#fc-setting-submit-auto_open>option:selected").val()==="true"},puts("sub-user",sub_user);});
  228. }},"status":{name:"查看状态",js:["facebox"],css:["status","facebox"],
  229. init:function(){
  230. sta_user=$.default(gets("sta-user",{}),sta_default),puts("sta-user",sta_user);
  231. $("#pageContent").after($(`<div id="fc-status" class="fc-main" style="display:none"><div id="fc-status-head">
  232. 用户:<input type="text" id="fc-status-user" value="`+user+`"/>&nbsp;&nbsp;&nbsp;页码:<input type="text" id="fc-status-page" value="1"/>&nbsp;&nbsp;&nbsp;
  233. <input type="checkbox" id="fc-status-show"/ checked>show unofficial&nbsp;&nbsp;&nbsp;<button type="button" id="fc-status-see">查看</button>
  234. &nbsp;&nbsp;&nbsp;<button type="button" id="fc-status-stop">停止本次自动刷新</button>
  235. <a id="fc-status-load"></a></div><div id="fc-status-main"></div></div>`));
  236. $("#fc-status-stop").click(function(){++sta_cnt,clearInterval(sta_t),$("#fc-status-load").html("");});
  237. $("#fc-status-see").click(function(){get_sta($("#fc-status-user").val(),++sta_cnt,$("#fc-status-page").val(),$("#fc-status-show:checked").length===1);});
  238. if(sta_user.auto_open)get_sta(user,0);
  239. },set:function(){
  240. $("#fc-setting-clear").before(`<div><div class="section-title">提交记录设置</div><br/>
  241. <input type="checkbox" id="fc-setting-status-auto_open"><label for="fc-setting-status-auto_open">是否自动打开自己的提交记录</label><br/><br/>
  242. 自动刷新间隔(不刷新为-1):<input type="number" min="-1" value="`+sta_user.interval+`" id="fc-setting-status-interval"/>毫秒<br/><br/>
  243. <button type="button" id="fc-setting-status-end">保存</button><hr/></div>`);
  244. if(sta_user.auto_open)$("#fc-setting-status-auto_open").attr("checked","checked");
  245. $("#fc-setting-status-end").click(function(){
  246. let interval=parseInt($("#fc-setting-status-interval").val());
  247. if(typeof interval!=="number"||interval!==interval){Alert("自动刷新间隔应为大于等于-1的整数");return;}
  248. if(interval<0)interval=1;$("#fc-setting-status-interval").val(interval);
  249. sta_user={auto_open:$("#fc-setting-status-auto_open:checked").length===1,interval:interval},puts("sta-user",sta_user),Alert("修改成功");
  250. });
  251. }},"setting":{name:"设置",js:[],css:[],
  252. init:function(){
  253. $("#pageContent").after($(`<div id="fc-setting" class="fc-main problem-statement" style="display:none">
  254. <div class="header"><div class="title">设置</div><div>带有<span class="fc-care">*</span>的选项在修改后,需要重新加载才能生效。</div></div>
  255. <div><div class="section-title">Fast Codeforces版本:`+version+`</div></div><hr/>
  256. <button type="button" class="fc-care" id="fc-setting-clear">清理缓存</button><br/><br/>
  257. <button type="button" class="fc-care" id="fc-setting-default">恢复默认设置</button></div>`));
  258. for(let i=0;i<len;++i)eles[ele[i]].set();
  259. $("#fc-setting-clear").click(function(){Confirm("您确定要清除缓存?",function(){Clear(),Alert("清除缓存成功");});});
  260. $("#fc-setting-default").click(function(){Confirm("您确定要恢复默认设置?请先保存好您的文件",function(){Reload(),default_set(),showMain(),Alert("恢复默认设置成功");});});
  261. },set:function(){
  262. menu=ele.slice();
  263. $("#fc-setting-clear").before($(`<div><div class="section-title">目录设置<span class="fc-care">*</span></div><br/><h6>当前目录</h6>
  264. <ul id="fc-setting-menu-add"></ul><h6>剩余目录</h6><ul id="fc-setting-menu-sub"></ul><button id="fc-setting-menu-end" class="fc-care">保存</button><hr/></div>`));
  265. for(let i=0;i<len;++i)add_menu(ele[i]);
  266. for(let i in eles)if(ele.indexOf(i)===-1)sub_menu(i);
  267. $("#fc-setting-menu-end").click(function(){
  268. Confirm("您确定要修改目录吗?",function(){Reload(),fc.ele=menu,puts("fc",fc),showMain(),Alert("修改成功");});
  269. });
  270. }}},ele,len,nele="pre",css_ready=[],js_ready=[],
  271. Change=function(id){
  272. if(nele===id)eles[id].hide(),show_pre(),nele="pre";
  273. else if(nele==="pre")hide_pre(),eles[id].show(),nele=id;
  274. else eles[nele].hide(),eles[id].show(),nele=id;
  275. },
  276. CreateEle=function(id){
  277. let obj=eles[id],js=obj.js,css=obj.css;
  278. for(let i=0;i<js.length;++i)if(js_ready.indexOf(js[i])==-1)$("head").append($(`<script src="//sta.codeforces.com/s/0/js/`+js[i]+`.js"></script>`)),js_ready.push(js[i]);
  279. for(let i=0;i<css.length;++i)if(css_ready.indexOf(css[i])==-1)$("head").append($(`<link rel="stylesheet" href="//sta.codeforces.com/s/0/css/`+css[i]+`.css"/>`)),css_ready.push(css[i]);
  280. $("#fc-stop").before($(`<a>&nbsp;&nbsp;<span id="fc-menu-`+id+`" style="border-radius:3px">`+obj.name+`</span>
  281. <span style="float:right">&#8635;</span></a><br/>`)),obj.init();
  282. if(!("show" in eles[id]))eles[id].show=function(){$("#fc-"+id).show(),$("#fc-menu-"+id).css("background-color","#AAAAAA");};
  283. if(!("hide" in eles[id]))eles[id].hide=function(){$("#fc-"+id).hide(),$("#fc-menu-"+id).css("background-color","white");};
  284. if(!("remove" in eles[id]))eles[id].remove=function(){$("#fc-"+id).remove();};
  285. if(!("set" in eles[id]))eles[id].set=function(){};
  286. $("#fc-menu-"+id).click(function(){Change(id);});
  287. $("#fc-menu-"+id).siblings().click(function(){
  288. if(nele===id)Change(id);
  289. obj.remove(),obj.init(),Alert("加载成功!");
  290. });
  291. },
  292. Reload=function(){
  293. if(nele!=="pre")Change(nele);
  294. for(let i=0;i<len;++i)eles[ele[i]].remove();
  295. },
  296. showLogin=function(){
  297. Reload(),$("#fc-menu").html(`<a href="javascript:;" id="fc-start">开始使用Fast Codeforces</a>`);
  298. $("#fc-start").click(function(){Confirm("Fast Codeforces需要使用您的CSRF-token,您确定要授权吗?",function(){fc.using=true,puts("fc",fc),Alert("授权成功"),showMain();});});
  299. },
  300. showMain=function(){
  301. ele=fc.ele;
  302. if(ele.length===0)ele=["problem","submit","status","setting"];
  303. if(ele.indexOf("setting")===-1)ele.push("setting");
  304. fc.ele=ele,puts("fc",fc),len=ele.length,nele="pre",$("#fc-menu").html(`<a href="javascript:;" id="fc-stop">停止使用Fast Codeforces</a>`);
  305. $("#fc-stop").click(function(){Confirm("您确认要停止使用Fast Codeforces?",function(){fc.using=false,puts("fc",fc),Alert("Fast Codeforces已停止"),showLogin();});});
  306. for(let i=0;i<len;++i)if(ele[i]!=="setting")CreateEle(ele[i]);
  307. if(ele.indexOf("setting")>=0)CreateEle("setting");
  308. };puts("fc",fc);
  309. $(function(){
  310. if($("#sidebar").length===0)return;
  311. let sidebar=$("#sidebar").html();
  312. $("#sidebar").html(`<div id="fc-bar">
  313. <style>
  314. .input-output-copier{font-size:1.2rem;float:right;color:#888 !important;cursor:pointer;border:1px solid rgb(185, 185, 185);padding:3px;margin:1px;line-height:1.1rem;text-transform:none;}
  315. .input-output-copier:hover{background-color:#def;}
  316. .fc-main{margin-right:22em !important;margin:1em;padding-top:1em;min-height:20em;}[type=button],[type=submit],#fc-menu>a>span{cursor:pointer}
  317. .focpro{background-color:grey;}#fc-problem-menu>li{border-radius:12px;cursor:pointer}.fc-care{color:red}
  318. </style>
  319. <div class="roundbox sidebox" id="fc-bar-menu"><div class="roundbox-lt">&nbsp;</div><div class="roundbox-rt">&nbsp;</div>
  320. <div class="caption titled">&rarr; Fast Codeforces<div class="top-links"><a id="fc-menu-turn">-</a>
  321. <a href="https://github.com/xcx-xcx/fast-codeforces">帮助&文档</a></div></div>
  322. <div style="padding:0.5em">
  323. <div id="fc-menu" style="text-align:center;border-bottom:1px solid rgb(185,185,185);margin:0 -0.5em 0.5em -0.5em;padding:0 1em 0.5em 1em"></div>
  324. </div></div></div><div id="pre-bar">`+sidebar+`</div>`);
  325. $("#fc-menu-turn").click(function(){
  326. let x=$("#fc-menu-turn");
  327. if(x.html()==="-")x.html("+"),$("#fc-menu").hide();
  328. else x.html("-"),$("#fc-menu").show();
  329. });
  330. Codeforces.countdown();
  331. if($(".header-bell").length===0)$("#fc-menu").html(`<span>请登录(不可用)后再使用!</span>`);
  332. else if(fc.using)showMain();
  333. else showLogin();
  334. if(version!==fc.version)fc.version=version,puts("fc",fc),setTimeout(function(){Alert("Fast Codeforces的版本已经更新了,赶快去设置看看呗");},500);
  335. });};

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址