From 1cd6b7bf2b0087f097feb62cbbd269f72f866ec3 Mon Sep 17 00:00:00 2001 From: Astor Bizard <astor.bizard@grenoble-inp.fr> Date: Wed, 9 Jun 2021 13:32:52 +0200 Subject: [PATCH] Temporary token now sent to execution server. Added prompt to load newer submission after execution. --- amd/build/vplide.min.js | 2 +- amd/src/vplide.js | 55 +++++++++++++++++++++++++++++++------ editor/editor_utility.php | 2 ++ forms/edit.json.php | 3 ++ lang/en/vpl.php | 2 ++ lang/fr/vpl.php | 2 ++ locallib.php | 37 +++++++++++++++++++++++++ vpl_submission_CE.class.php | 2 ++ 8 files changed, 96 insertions(+), 9 deletions(-) diff --git a/amd/build/vplide.min.js b/amd/build/vplide.min.js index bc28d72a..a8543b52 100644 --- a/amd/build/vplide.min.js +++ b/amd/build/vplide.min.js @@ -1 +1 @@ -define(["jquery","jqueryui","mod_vpl/vplutil","mod_vpl/vplidefile","mod_vpl/vplidebutton","mod_vpl/vplterminal","mod_vpl/vplvnc"],function(a,b,c,d,e,f,g){if("undefined"!=typeof i)return i;var h,i=function(b,i){var j,k,l,m,n,o=this,p=i.minfiles||0,q=i.maxfiles||0,r=i.restrictededitor||i.example,s=i.example,t=!1,u=c.scrollBarWidth();c.setStr({...M.str.mod_vpl,...M.str.moodle,...i.str});var v=c.str,w=a("#"+b);if(a("head").append('<meta name="viewport" content="initial-scale=1">').append('<meta name="viewport" width="device-width">'),"object"!=typeof w)throw new Error("VPL: constructor tag_id not found");var x,y={new:!0,rename:!0,delete:!0,save:!0,run:!0,edit:!0,debug:!0,evaluate:!0,import:!0,resetfiles:!0,correctedfiles:!0,sort:!0,multidelete:!0,theme:!0,console:!0,comments:!0};"undefined"==typeof i.loadajaxurl&&(i.loadajaxurl=i.ajaxurl),x=p<q,i.new=x,i.rename=x,i.delete=x,i.comments=i.comments&&!i.example,i.sort=q-p>=2,i.multidelete=i.sort,i.import=!r;var z=function(a){return!y[a]||i[a]};function A(a){a.originalEvent.dataTransfer.dropEffect=r?"none":"copy",a.preventDefault()}function B(a){if(r)return a.stopImmediatePropagation(),!1;for(var b=[],d=function(a,c=""){return new Promise(function(e){if(a.isFile)a.file(function(a){var d=c+a.name;Object.defineProperty(a,"name",{get:function(){return d}}),b.push(a),e()});else if(a.isDirectory){a.createReader().readEntries(function(b){for(var f=[],g=0;g<b.length;g++)f.push(d(b[g],c+a.name+"/"));Promise.all(f).then(e)})}else e()})},e=a.originalEvent.dataTransfer,f=[],g=0;g<e.items.length;g++)f.push(d(e.items[g].webkitGetAsEntry()));return e.files.length>0&&(Promise.all(f).then(function(){c.readSelectedFiles(b,function(a){return j.addFile(a,!0,n,m)},function(){j.fileListVisibleIfNeeded()})}),a.stopImmediatePropagation(),!1)}function C(a){return!r||(a.stopPropagation(),!1)}i.console=z("run")||z("debug"),"undefined"==typeof i.fontSize&&(i.fontSize=12),i.fontSize=parseInt(i.fontSize),w.on("drop",B),w.on("dragover",A);var D=a("#vpl_menu"),E=new e(D,z),F=a("#vpl_tr"),G=a("#vpl_filelist"),H=a("#vpl_filelist_header"),I=a("#vpl_filelist_content"),J=a("#vpl_tabs_ul"),K=a("#vpl_tabs"),L=a("#vpl_results"),N=a("#vpl_results_accordion");G.vplMinWidth=80,this.updateEvaluationNumber=function(a){if("undefined"!=typeof a.nevaluations){var b=a.nevaluations;"undefined"!=typeof a.reductionbyevaluation&&a.reductionbyevaluation>""&&0!=a.reductionbyevaluation&&(0!=a.freeevaluations&&(b=b+"/"+a.freeevaluations),b=b+" -"+a.reductionbyevaluation),E.setExtracontent("evaluate",b)}},this.lastResult=null,this.getTerminal=function(){return va},this.setResultGrade=function(a,b){var c="vpl_ide_accordion_t_grade";if(0==N.find(".vpl_ide_accordion_c_grade").length&&(N.append('<div class="'+c+'"></div>'),N.append('<div class="vpl_ide_accordion_c_grade"></div>')),"undefined"==typeof b)return N.find("h4."+c).length>0;var d=N.find("."+c);return a>""?(d.replaceWith('<h4 class="'+c+'">'+a+"</h4>"),!0):(d.replaceWith('<div class="'+c+'"></div>'),!1)},this.setResultTab=function(b,c,d){var e="vpl_ide_accordion_t_"+b,f="vpl_ide_accordion_c_"+b;if(0==N.find("."+f).length&&(N.append('<div class="'+e+'"></div>'),N.append('<div class="'+f+'"></div>')),"undefined"==typeof d)return N.find("h4."+e).length>0;var g=N.find("."+e),h=N.find("."+f),i=a("<div>"+c+"</div>");return i.find("h4").replaceWith(function(){return a("<h5>").append(a(this).contents())}),h.html()==i.html()?c>"":c>""?(g.replaceWith('<h4 class="'+e+'">'+v(b)+"</h4>"),h.replaceWith('<div class="ui-widget '+f+'">'+i.html()+"</div>"),!0):(g.replaceWith('<div class="'+e+'"></div>'),h.replaceWith('<div class="'+f+'"></div>'),!1)},this.setResult=function(a,b){o.updateEvaluationNumber(a);var d,e=j.getFiles(),f=[];for(d=0;d<e.length;d++)f[d]=e[d].getFileName(),e[d].clearAnnotations();var g,h,k,m=!1,n=c.sanitizeText(a.grade);if(h=o.setResultGrade(n,a.grade),m=m||h,g=o.setResultTab("variables",a.variables,a.variables),m=m||g,k=c.processResult(a.compilation,f,e,!0,!1),g=o.setResultTab("compilation",k,a.compilation),m=m||g,k=c.processResult(a.evaluation,f,e,!1,!1),g=o.setResultTab("comments",k,a.evaluation),m=m||g,k=c.sanitizeText(a.execution),g=o.setResultTab("execution",k,a.execution),m=m||g,(g=o.setResultTab("description",i.description,i.description))&&"object"==typeof MathJax){var p=N.find(".vpl_ide_accordion_c_description")[0];MathJax.Hub.Queue(["Typeset",MathJax.Hub,p])}if(m=m||g){for(L.show(),L.vplVisible=!0,N.accordion("refresh"),N.accordion("option","active",h?1:0),d=0;d<e.length;d++)for(var q=e[d].getAnnotations(),r=0;r<q.length;r++)if(b||"error"==q[r].type){j.gotoFile(d,q[r].row+1);break}}else L.hide(),L.vplVisible=!1;c.delay("autoResizeTab",l)},N.accordion({heightStyle:"fill",header:"h4",animate:!1,beforeActivate:function(a,b){return!("newHeader"in b&&b.newHeader.hasClass("vpl_ide_accordion_t_grade"))}}),N.on("click","a",function(a){j.gotoFileLink(a.currentTarget)&&a.preventDefault()}),L.vplVisible=!1,L.hide(),G.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),H.text(v("filelist")),H.html(c.iconFolder()+H.html()),H.addClass("ui-widget-header ui-button-text-only ui-corner-all"),I.addClass("ui-widget ui-corner-all"),G.width(2*G.vplMinWidth),G.on("click","a",function(a){a.preventDefault(),j.gotoFileLink(a.currentTarget)}),G.vplVisible=!1,G.hide();var O=!1;function P(){return!1===O&&(O=(K.outerWidth(!0)-K.width())/2),O}function Q(a,b){var c,d=b.position.left-b.originalPosition.left;if(0!==d)c=K.width()+G.width()-G.vplMinWidth,K.resizable("option","maxWidth",c),G.width(G.vplOriginalWidth+d);else{var e=b.size.width-b.originalSize.width;L.width(L.vplOriginalWidth-e)}j.currentFile("adjustSize")}var R={containment:"parent",resize:Q,start:function(){a(window).off("resize",l),K.resizable("option","minWidth",100),L.vplVisible&&(L.vplOriginalWidth=L.width()),G.vplVisible&&(G.vplOriginalWidth=G.width())},stop:function(b,c){Q(0,c),K.resizable("option","maxWidth",1e5),K.resizable("option","minWidth",0),l(),a(window).on("resize",l)},handles:""};function S(){j.currentFile("focus")}K.resizable(R),k=function(b){var c=K.width(),d=0;J.width(1e5);var e=J.children("li:visible").last();if(e.length){var f=J.parent().scrollLeft();d=f+e.position().left+e.width()+O,J.width(d);var g=j.currentFile();if(g&&b){var h=a(g.getTabNameId()),i=f+h.position().left;(i-=(c-h.outerWidth())/2)<0&&(i=0),J.parent().finish().animate({scrollLeft:i},"slow")}}d<c&&J.width("")},l=function(){var b,c=K.width(),d=D.width(),e=!1;if(b=0,b+=G.vplVisible?1:0,b+=L.vplVisible?2:0,K.resizable("destroy"),R.handles=["e","w","e","e, w"][b],R.disable=0===b,K.resizable(R),F.width(D.outerWidth()),G.vplVisible){var f=G.outerWidth()+O;c+=f,f>=100?(d-=f,K.css("left",f)):e=!0}else K.css("left",0);if(L.vplVisible){var g=L.outerWidth()+O;c+=g,(d-=g)<100&&(e=!0)}if(e){var h=D.width()/c,i=0;G.vplVisible&&(i=G.width()*h,G.width(i-O),i+=O,K.css("left",i)),K.width(K.width()*h),L.vplVisible&&L.width(D.width()-(i+K.width()+O))}else K.width(d);k(!0),function(){var b=(t?1:.7)*(a(window).innerHeight()-D.height()-P());b<150&&(b=150),F.height(b);var c=b-3*P();K.height(c),L.vplVisible&&(L.height(c+P()),N.accordion("refresh")),G.vplVisible&&(I.height(c-(H.outerHeight()+P())),G.height(c))}(),j.currentFile("adjustSize")};var T=a.extend({},{close:S},c.dialogbaseOptions);function U(b,d){return c.showMessage(b,a.extend({},T,d))}m=function(a){return c.showErrorMessage(a,{close:S})};var V=a("#vpl_ide_dialog_new");function W(b){if("click"!=b.type&&("keypress"!=b.type||13!=b.keyCode))return!0;V.dialog("close");var c={name:a("#vpl_ide_input_newfilename").val(),contents:"",encoding:0},d=j.addFile(c,!1,n,m);return!!d&&(j.open(d),K.tabs("option","active",j.getTabPos(d)),d.focus(),!0)}var X={};X[v("ok")]=W,X[v("cancel")]=function(){a(this).dialog("close")},V.find("input").on("keypress",W),V.dialog(a.extend({},T,{title:v("create_new_file"),buttons:X})),c.setDialogTitleIcon(V,"new");var Y=a("#vpl_ide_dialog_rename");function Z(b){("click"==b.type||"keypress"==b.type&&13==b.keyCode)&&(Y.dialog("close"),j.renameFile(j.currentFile("getFileName"),a("#vpl_ide_input_renamefilename").val(),m),b.preventDefault())}Y.find("input").on("keypress",Z),X[v("ok")]=Z,Y.dialog(a.extend({},T,{open:function(){a("#vpl_ide_input_renamefilename").val(j.currentFile("getFileName"))},title:v("rename_file"),buttons:X})),c.setDialogTitleIcon(Y,"rename"),X[v("ok")]=function(){a(this).dialog("close")};var $=a("#vpl_ide_dialog_comments");$.dialog(a.extend({},T,{title:v("comments"),width:"40em",buttons:X})),c.setDialogTitleIcon($,"comments"),a("#vpl_ide_input_comments").width("30em");var _=a("#vpl_ide_dialog_about"),aa={};aa[v("ok")]=function(){a(this).dialog("close")};var ba=a("#vpl_ide_dialog_shortcuts");ba.dialog(a.extend({},T,{open:function(){var b=E.getShortcuts(j.currentFile("getEditor"));a("#vpl_ide_dialog_shortcuts").html(b)},title:v("shortcuts"),width:400,height:300,buttons:aa})),ba.dialog("option","height",300),c.setDialogTitleIcon(ba,"shortcuts"),aa[v("shortcuts")]=function(){a(this).dialog("close"),ba.dialog("open")},_.dialog(a.extend({},T,{open:function(){var b=E.getShortcuts(j.currentFile("getEditor"));_.next().find("button").filter(function(){return a(this).text()==v("shortcuts")}).button(""!=b?"enable":"disable")},title:v("about"),width:400,height:300,buttons:aa})),_.dialog("option","height",300),c.setDialogTitleIcon(_,"about");var ca=a("#vpl_ide_dialog_sort"),da={};da[v("ok")]=function(){var b=j.getFiles(),c=/[^\d]*/,d=[],e=0,f=a("#vpl_sort_list li");if(f.length==b.length){for(f.each(function(){var a=parseInt(this.id.replace(c,""));d.push(b[a])}),e=0;e<f.length;e++)b[e]=d[e];j.setModified(),a(this).dialog("close")}},da[v("cancel")]=function(){a(this).dialog("close")},ca.dialog(a.extend({},T,{title:v("sort"),buttons:da,open:function(){var b=a("#vpl_sort_list");b.html("");for(var c=j.getFiles(),d=0;d<c.length;d++){var e=a('<li id="vpl_fsort_'+d+'"class="ui-widget-content"></li>');d<p&&e.addClass("ui-state-disabled"),e.text(d+1+"-"+c[d].getFileName()),b.append(e)}b.sortable({items:"li:not(.ui-state-disabled)",placeholder:"ui-state-highlight",start:function(a,b){b.item.addClass("ui-state-highlight")},stop:function(a,b){b.item.removeClass("ui-state-highlight")}}),b.disableSelection()},maxHeight:400})),c.setDialogTitleIcon(ca,"sort");var ea=a("#vpl_ide_dialog_multidelete"),fa={};fa[v("selectall")]=function(){a(this).find("input").prop("checked",!0)},fa[v("deselectall")]=function(){a(this).find("input").prop("checked",!1)},fa[v("deleteselected")]=function(){var b=j.getFiles(),d=[];a("#vpl_multidelete_list label").each(function(){var c=a(this);if(c.find("input").prop("checked")){var e=c.data("fileid");d.push(b[e].getFileName())}});for(var e=0;e<d.length;e++)j.deleteFile(d[e],!1,m);c.delay("updateMenu",n),c.delay("updateFileList",j.updateFileList),a(this).dialog("close")},fa[v("cancel")]=function(){a(this).dialog("close")},ea.dialog(a.extend({},T,{title:v("multidelete"),buttons:fa,open:function(){var b=a("#vpl_multidelete_list");b.html("");for(var d=j.getFiles(),e=p;e<d.length;e++){var f=c.sanitizeText(d[e].getFileName()),g=a('<label><input type="checkbox"> '+f+"</label>");g.data("fileid",e),b.append(g),b.append("<br>")}b.find("label").button()},maxHeight:400,maxWidth:400})),c.setDialogTitleIcon(ea,"multidelete");var ga=a("#vpl_ide_dialog_fontsize"),ha=a("#vpl_ide_dialog_fontsize .vpl_fontsize_slider"),ia={};ia[v("ok")]=function(){var b=ha.slider("value");j.setFontSize(b),a(this).dialog("close"),c.setUserPreferences({fontSize:b})},ia[v("cancel")]=function(){j.setFontSize(ha.data("vpl_fontsize")),a(this).dialog("close")},ia[v("reset")]=function(){ha.slider("value",12)},ga.dialog(a.extend({},T,{title:v("fontsize"),buttons:ia,open:function(){ha.data("vpl_fontsize",j.getFontSize()),ha.slider("value",j.getFontSize())}})),ha.slider({min:1,max:48,change:function(){var a=ha.slider("value");j.setFontSize(a),ga.find(".vpl_fontsize_slider_value").text(a)}}),c.setDialogTitleIcon(ga,"fontsize");var ja=a("#vpl_ide_dialog_theme"),ka=a("#vpl_ide_dialog_theme select.acetheme"),la=a("#vpl_ide_dialog_theme select.interfacetheme"),ma=a("#interfacetheme-colorpicker-primary"),na=a("#interfacetheme-colorpicker-secondary"),oa=ma.add(na),pa={};pa[v("ok")]=function(){a(this).data("okpressed",!0),a(this).dialog("close");var b={aceTheme:ka.val(),interfaceTheme:la.val()};"custom"==la.val()&&(b.customInterfaceColors={primary:ma.val(),secondary:na.val()}),c.setUserPreferences(b)},pa[v("cancel")]=function(){a(this).dialog("close")};var qa=function(b){a(".vpl_ide").removeClass(function(){return(this.className.match(/(^| )(vpl_theme_[^ ]*)/)||["","",""])[2]}).addClass("vpl_theme_"+b)};ja.dialog(a.extend({},T,{title:v("theme"),buttons:pa,modal:!1,open:function(){a(this).data("okpressed",!1);var b=j.getTheme();ka.data("originalvalue",b).val(b);var c=a("#vplide").attr("class").match(/(^| )(vpl_theme_([^ ]*))/)[3];la.data("originalvalue",c).val(c),oa.each(function(){a(this).data("originalvalue",a(this).val())})},close:function(){a(this).data("okpressed")||(j.setTheme(ka.data("originalvalue")),qa(la.data("originalvalue")),oa.each(function(){a(this).val(a(this).data("originalvalue")).change()}))}})),ka.change(function(){j.setTheme(ka.val())}),la.change(function(){qa(la.val())}),c.setDialogTitleIcon(ja,"theme"),a(".colourdialogue").mousemove(function(b){a(this).next(".previewcolour").css("top",b.pageY-a(this).offset().top-50).css("left",b.pageX-a(this).offset().left)}),a(".previewcolour").mousemove(function(b){a(this).prev(".colourdialogue").trigger(b)});var ra=function(a){var b=a.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(,\s*(\d+))?\)$/);return{r:parseInt(b[1]),g:parseInt(b[2]),b:parseInt(b[3])}},sa=function(a,b,c){return"rgb("+(a.r*c+b.r*(1-c))+","+(a.g*c+b.g*(1-c))+","+(a.b*c+b.b*(1-c))+")"},ta=[...document.styleSheets].filter(function(a){return"custom-interfacetheme-css"==a.title})[0],ua=function(){var a=ma.next(".admin_colourpicker").children(".currentcolour").css("background-color"),b=na.next(".admin_colourpicker").children(".currentcolour").css("background-color"),c=ra(a),d=ra(b);ta.cssRules.length>0&&ta.deleteRule(0),ta.insertRule(".path-mod-vpl .vpl_ide {--vpl-interface-theme-primary: "+a+";--vpl-interface-theme-secondary: "+b+";--vpl-interface-theme-ternary: "+sa(c,d,.3)+";--vpl-interface-theme-highlight: "+sa(c,d,.7)+";}",0)};oa.change(function(){if(null===a(this).val().match(/^(#(?:[a-f0-9A-F]{3}){1,2}|[a-z]+)$/))return!1;a(this).next(".admin_colourpicker").children(".currentcolour").css("background-color",a(this).val()),ua()}),a(".colourdialogue").click(function(){ua()}),ua();var va=new f("vpl_dialog_terminal","vpl_terminal",v),wa=new g("vpl_dialog_vnc",v),xa=va,ya=a("#vpl_ide_input_file");function za(){c.requestAction("resetfiles","",{},i.ajaxurl).done(function(a){var b=a.files;for(var d in b)b.hasOwnProperty(d)&&j.addFile(b[d],!0,c.doNothing,m);j.fileListVisibleIfNeeded(),c.delay("updateMenu",n)}).fail(m)}function Aa(){c.requestAction("correctedfiles","",{},i.ajaxurl).done(function(a){var b=a.files;for(var d in b)j.addFile(b[d],!0,c.doNothing,m);j.fileListVisibleIfNeeded()}).fail(m)}ya.on("change",function(){c.readSelectedFiles(this.files,function(a){return j.addFile(a,!0,n,m)},function(){j.fileListVisibleIfNeeded()})}),E.add({name:"filelist",originalAction:function(){j.fileListVisible(!j.isFileListVisible()),c.delay("updateMenu",n),c.delay("autoResizeTab",l),c.delay("updateFileList",j.updateFileList)},bindKey:{win:"Ctrl-L",mac:"Ctrl-L"}}),E.add({name:"new",originalAction:function(){j.length()<q&&V.dialog("open")},bindKey:{win:"Alt-N",mac:"Option-N"}}),E.add({name:"rename",originalAction:function(){var a=j.currentFile();a&&j.getFilePosById(a.getId())>=p&&Y.dialog("open")},bindKey:{win:"Ctrl-R",mac:"Ctrl-R"}}),E.add({name:"delete",originalAction:function(){var a=j.currentFile();if(a){var b=a.getFileName();U(v("delete_file_fq",b),{ok:function(){j.deleteFile(b,m)},title:v("delete_file_q"),icon:"trash"})}},bindKey:{win:"Ctrl-D",mac:"Ctrl-D"}}),E.add({name:"close",originalAction:function(){var a=j.currentFile();a&&j.close(a)},bindKey:{win:"Alt-W",mac:"Option-W"}}),E.add({name:"import",originalAction:function(){ya.val(""),ya.trigger("click")},bindKey:{win:"Ctrl-I",mac:"Ctrl-I"}}),E.add({name:"sort",originalAction:function(){ca.dialog("open")},bindKey:{win:"Ctrl-O",mac:"Ctrl-O"}}),E.add({name:"multidelete",originalAction:function(){ea.dialog("open")}}),E.add({name:"fontsize",originalAction:function(){ga.dialog("open")}}),E.add({name:"theme",originalAction:function(){ja.dialog("open")}}),E.add({name:"print",originalAction:function(){window.print()},bindKey:{win:"Alt-P",mac:"Command-P"}}),E.add({name:"undo",originalAction:function(){j.currentFile("undo")}}),E.add({name:"redo",originalAction:function(){j.currentFile("redo")}}),E.add({name:"select_all",editorName:"selectall",originalAction:function(){j.currentFile("selectAll")}}),E.add({name:"find",originalAction:function(){j.currentFile("find")}}),E.add({name:"find_replace",editorName:"replace",originalAction:function(){j.currentFile("replace")}}),E.add({name:"next",editorName:"findnext",originalAction:function(){j.currentFile("next")}}),E.add({name:"fullscreen",originalAction:function(){var b="header, nav, footer, aside, .dropdown, #page-header, div.navbar, #nav-drawer";b+=", div.tabtree, #dock, .breadcrumb-nav, .moodle-actionmenu",t?(w.removeClass("vpl_ide_root_fullscreen"),a("body").removeClass("vpl_body_fullscreen"),E.setText("fullscreen","fullscreen",c.str("fullscreen")),a(b).show(),a("#vpl_ide_user").hide(),t=!1):(a("body").addClass("vpl_body_fullscreen").scrollTop(0),a(b).hide(),w.addClass("vpl_ide_root_fullscreen"),E.setText("fullscreen","regularscreen",c.str("regularscreen")),i.username&&a("#vpl_ide_user").show(),t=!0),S(),setTimeout(l,10)},bindKey:{win:"Alt-F",mac:"Ctrl-F"}}),E.add({name:"download",originalAction:function(){window.location=i.download}}),E.add({name:"correctedfiles",originalAction:function(){U(v("surecorrectedfiles"),{title:v("correctedfiles"),ok:Aa})}}),E.add({name:"resetfiles",originalAction:function(){U(v("sureresetfiles"),{title:v("resetfiles"),ok:za,icon:"resetfiles"})}}),E.add({name:"save",originalAction:function(){var b={files:j.getFilesToSave(),comments:a("#vpl_ide_input_comments").val(),version:j.getVersion()};!function a(){c.requestAction("save","saving",b,i.ajaxurl).done(function(d){d.requestsconfirmation?U(d.question,{title:v("saving"),icon:"alert",yes:function(){b.version=d.version,a()}}):(j.resetModified(),j.setVersion(d.version),E.setTimeLeft(d),c.delay("updateMenu",n))}).fail(m)}()},bindKey:{win:"Ctrl-S",mac:"Command-S"}});var Ba={getConsole:function(){return xa},setResult:o.setResult,ajaxurl:i.ajaxurl,run:function(a,b,c){xa&&xa.isOpen()&&xa.close(),"terminal"==a?(xa=va,va.connect(b.executionURL,function(){c.close(),S()})):(xa=wa,wa.connect(b.secure,b.server,b.portToUse,b.VNCpassword,b.executionPath,function(){c.close(),S()}))},lastAction:!1,getLastAction:function(){var a=this.lastAction;return this.lastAction=!1,a},setLastAction:function(a){this.lastAction=a}};function Ca(a,b,d){d||(d={}),xa.isConnected()||c.requestAction(a,"",d,i.ajaxurl).done(function(d){c.webSocketMonitor(d,a,b,Ba)}).fail(m)}function Da(){Ca("run","running",{XGEOMETRY:wa.getCanvasSize()})}function Ea(){Ca("debug","debugging",{XGEOMETRY:wa.getCanvasSize()})}function Fa(){Ca("evaluate","evaluating")}E.add({name:"run",originalAction:function(){Ba.setLastAction(Da),Da()},bindKey:{win:"Ctrl-F11",mac:"Command-U"}}),E.add({name:"debug",originalAction:function(){Ba.setLastAction(Ea),Ea()},bindKey:{win:"Alt-F11",mac:"Option-U"}}),E.add({name:"evaluate",originalAction:function(){Ba.setLastAction(Fa),Fa()},bindKey:{win:"Shift-F11",mac:"Command-Option-U"}}),E.add({name:"comments",originalAction:function(){$.dialog("open")}}),E.add({name:"console",originalAction:function(){xa.isOpen()?xa.close():xa.show()}}),E.add({name:"user"}),E.add({name:"about",originalAction:function(){_.dialog("open")}}),E.add({name:"timeleft",originalAction:function(){E.toggleTimeLeft()}}),E.add({name:"more",originalAction:function(){var b=a("#vpl_ide_menuextra");b.is(":visible")?(E.setText("more","more",c.str("more")),b.hide()):(E.setText("more","less",c.str("less")),b.show()),c.delay("updateMenu",n),c.delay("autoResizeTab",l)}}),D.addClass("ui-widget-header ui-corner-all");var Ga="";Ga+=E.getHTML("more"),Ga+=E.getHTML("save"),Ga+="<span id='vpl_ide_mexecution'>",Ga+=E.getHTML("run"),Ga+=E.getHTML("debug"),Ga+=E.getHTML("evaluate"),Ga+=E.getHTML("comments"),Ga+=E.getHTML("console"),Ga+="</span> ",Ga+="<span id='vpl_ide_menuextra'>",Ga+="<span id='vpl_ide_file'>",Ga+=E.getHTML("filelist"),Ga+=E.getHTML("new"),Ga+=E.getHTML("rename"),Ga+=E.getHTML("delete"),Ga+=E.getHTML("import"),Ga+=E.getHTML("download"),Ga+=E.getHTML("resetfiles"),Ga+=E.getHTML("correctedfiles"),Ga+=E.getHTML("sort"),Ga+=E.getHTML("multidelete"),Ga+=E.getHTML("fontsize"),Ga+=E.getHTML("theme"),Ga+="</span> ",Ga+="<span id='vpl_ide_edit'>",Ga+=E.getHTML("undo"),Ga+=E.getHTML("redo"),Ga+=E.getHTML("select_all"),Ga+=E.getHTML("find"),Ga+=E.getHTML("find_replace"),Ga+=E.getHTML("next"),Ga+="</span> ",Ga+="</span> ",Ga+=E.getHTML("fullscreen")+" ",Ga+=E.getHTML("about")+" ",Ga+=E.getHTML("user")+" ",Ga+=E.getHTML("timeleft"),Ga+='<div class="clearfix"></div>',D.append(Ga),a("#vpl_ide_more").button(),a("#vpl_ide_save").button(),a("#vpl_ide_menuextra").hide(),a("#vpl_ide_file").controlgroup(),a("#vpl_ide_edit").controlgroup(),a("#vpl_ide_mexecution").controlgroup(),a("#vpl_ide_fullscreen").button(),a("#vpl_ide_theme").button(),a("#vpl_ide_about").button(),a("#vpl_ide_user").button().css("float","right").hide(),a("#vpl_ide_timeleft").button().css("float","right").hide(),a("#vpl_menu .ui-button").css("padding","6px"),a("#vpl_menu .ui-button-text").css("padding","0");for(var Ha=["filelist","more","fullscreen","about","resetfiles","download","comments","console","import","fontsize","timeleft"],Ia=0;Ia<Ha.length;Ia++)E.enable(Ha[Ia],!0);E.setExtracontent("user",i.username),E.setTimeLeft(i),n=function(){var a,b=j.currentFile(),d=j.length();d?K.show():K.hide(),j.isFileListVisible()?E.setText("filelist","filelistclose",c.str("filelist")):E.setText("filelist","filelist",c.str("filelist"));var e,f=j.isModified();if(E.enable("save",f),E.enable("run",(!f||i.example)&&z("run")),E.enable("debug",(!f||i.example)&&z("debug")),E.enable("evaluate",(!f||i.example)&&z("evaluate")),E.enable("download",!f),E.enable("new",d<q),E.enable("sort",d-p>1),E.enable("multidelete",d-p>1),E.enable("theme",!0),E.enable("correctedfiles",i.correctedfiles),b&&0!==d){var g=j.getFilePosById(b.getId());E.enable("rename",g>=p&&0!==d),E.enable("delete",g>=p&&0!==d),E.enable("undo",b.hasUndo()),E.enable("redo",b.hasRedo()),E.enable("select_all",b.hasSelectAll()),E.enable("find",b.hasFind()),E.enable("find_replace",b.hasFindReplace()),E.enable("next",b.hasNext()),c.delay("updateFileList",j.updateFileList)}else for(e=["rename","delete","undo","redo","select_all","find","find_replace","next"],a=0;a<e.length;a++)E.enable(e[a],!1)},K.on("tabsactivate",function(){j.currentFile("focus"),c.delay("updateMenu",n),c.delay("autoResizeTab",l)});var Ja=a(window);Ja.on("resize",l),i.example||Ja.on("beforeunload",function(){if(j.isModified())return v("changesNotSaved")}),j=new function(){var b=a("#vpl_tabs_ul");a("#vpl_tabs").tabs();var e,f=a("#vpl_tabs").tabs("widget"),g=[],m=[],o=!0,t=this;function w(a){for(var b=a.toLowerCase()+"/",c=0;c<g.length;c++){var d=g[c].getFileName().toLowerCase()+"/";if(0===d.indexOf(b)||0===b.indexOf(d))return!0}return!1}function x(a,b){if(c.isBlockly(a))return!1;if(c.isBlockly(b))for(var d=0;d<g.length;d++)if(c.isBlockly(g[d].getFileName()))return!0;return!1}t.setVersion=function(a){e=a},t.getVersion=function(){return e},this.updateFileList=function(){t.generateFileList()},this.fileNameExists=function(a){for(var b=a.toLowerCase(),c=0;c<g.length;c++)if(g[c].getFileName().toLowerCase()==b)return c;return-1},this.restrictedPaste=C,this.dropHandler=B,this.dragoverHandler=A,this.readOnly=s,this.restrictedEdit=r,this.adjustTabsTitles=k,this.minNumberOfFiles=p,this.scrollBarWidth=u;var y="";this.setClipboard=function(a){y=a},this.getClipboard=function(){return y},this.getTabPos=function(a){for(var b=0;b<m.length;b++)if(m[b]==a)return b;return m.length},this.getTheme=function(){return i.theme},this.setTheme=function(a){i.theme=a;for(var b=0;b<g.length;b++)g[b].setTheme(a)},this.addTab=function(a){var c='<a href="#vpl_file'+a+'"></a>';b.append('<li id="vpl_tab_name'+a+'">'+c+"</li>"),f.append('<div id="vpl_file'+a+'" class="vpl_ide_file"></div>')},this.removeTab=function(a){b.find("#vpl_tab_name"+a).remove(),f.find("#vpl_file"+a).remove()},this.open=function(a){var b;if(!(b="object"==typeof a?a:g[a]).isOpen()){var d=b.getId();t.addTab(d),m.push(b),E.setGetkeys(b.open()),f.tabs("refresh"),k(!1),c.delay("updateFileList",t.updateFileList),c.delay("updateMenu",n)}},this.close=function(a){if(a.isOpen()){var b,d=a.getId();a.close(),t.removeTab(d);var e=t.getTabPos(a);return m.splice(e,1),f.tabs("refresh"),k(!1),t.fileListVisible(!0),c.delay("updateFileList",t.updateFileList),c.delay("adjustTabsTitles",k,!1),m.length>e?(b=t.getFilePosById(m[e].getId()),void t.gotoFile(b,"c")):e>0?(b=t.getFilePosById(m[e-1].getId()),void t.gotoFile(b,"c")):void 0}},this.isClosed=function(a){return!g[a].isOpen()},this.fileListVisible=function(a){a!==G.vplVisible&&(a?c.delay("fileListVisible",function(){G.vplVisible=!0,t.updateFileList(),G.show(),l()}):c.delay("fileListVisible",function(){G.vplVisible=!1,G.hide(),l()}))},this.isFileListVisible=function(){return G.vplVisible},this.fileListVisibleIfNeeded=function(){if(!this.isFileListVisible())for(var a=0;a<g.length;a++)if(!g[a].isOpen())return void this.fileListVisible(!0)},this.setFontSize=function(a){i.fontSize=a;for(var b=0;b<g.length;b++)g[b].setFontSize(a);va.setFontSize(a)},this.getFontSize=function(){return i.fontSize},this.addFile=function(a,b,e,f){if("string"!=typeof a.name||!c.validPath(a.name))return f(v("incorrect_file_name")+" ("+a.name+")"),!1;!0!==b&&(b=!1);var j=this.fileNameExists(a.name);if(-1!=j)return b?(g[j].setContent(a.contents),t.setModified(),e(),c.delay("updateFileList",t.updateFileList),a):(f(v("filenotadded",a.name)),!1);if(w(a.name)||x("",a.name))return f(v("filenotadded",a.name)),!1;if(g.length>=q)return f(v("maxfilesexceeded")+" ("+q+")"),!1;var k=c.getUniqueId(),l=new d(k,a.name,a.contents,this,h,i.id);return 1==a.encoding?l.extendToBinary():c.isBlockly(a.name)?l.extendToBlockly():l.extendToCodeEditor(),l.setFileName(a.name),g.push(l),t.setModified(),g.length>5&&t.fileListVisible(!0),e(),l},this.renameFile=function(a,b,d){var e=this.fileNameExists(a);try{if(-1==e)throw new Error("Internal error: File name not found");if(e<p)throw new Error("Internal error: Renaming required filename");if(g[e].getFileName()==b)return!0;if(!c.validPath(b)||w(b)||x(a,b))throw v("incorrect_file_name");if(c.isBinary(a)&&c.fileExtension(a)!=c.fileExtension(b))throw v("incorrect_file_name");if(c.isBlockly(a)!=c.isBlockly(b))throw v("incorrect_file_name");g[e].setFileName(b)}catch(a){return d(v("filenotrenamed",b)+": "+a),!1}return t.setModified(),k(!1),c.delay("updateFileList",t.updateFileList),!0},this.deleteFile=function(a,b,d){var e=this.fileNameExists(a);return-1==e?(d(v("filenotdeleted",a)),!1):e<p?(d(v("filenotdeleted",a)),!1):(t.setModified(),t.close(g[e]),g.splice(e,1),c.delay("updateFileList",t.updateFileList),!0)},this.currentFile=function(){var a=f.tabs("option","active");if(a in m){var b=m[a];if(0===arguments.length)return b;var c=arguments[0];if("function"==typeof b[c]){var d=b[c],e=Array.prototype.slice(arguments);return e.shift(),d.apply(b,e)}}return!1},this.currentPos=function(){return f.tabs("option","active")},this.getFileTab=function(a){for(var b=0;b<m.length;b++)if(m[b].getId()==a)return b;return-1},this.getFilePosById=function(a){for(var b=0;b<g.length;b++)if(g[b].getId()==a)return b;return-1},this.gotoFile=function(a,b){var c=g[a];t.open(c),f.tabs("option","active",t.getFileTab(c.getId())),"c"!==b&&c.gotoLine(parseInt(b,10)),c.focus()},this.gotoFileLink=function(b){var c=a(b),d=c.data("file"),e=-1;if((e=d>""?this.fileNameExists(d):t.getFilePosById(c.data("fileid")))>=0){var f=c.data("line");return"undefined"==typeof f&&(f="c"),t.gotoFile(e,f),!0}return!1},this.getFilesToSave=function(){for(var a=[],b=0;b<g.length;b++){var c={};c.name=g[b].getFileName(),c.contents=g[b].getContent(),c.encoding=g[b].isBinary()?1:0,a.push(c)}return a},this.resetModified=function(){o=!1;for(var a=0;a<g.length;a++)g[a].resetModified();c.delay("updateMenu",n),c.delay("updateFileList",t.updateFileList)},this.setModified=function(){o=!0,c.delay("updateFileList",t.updateFileList),c.delay("updateMenu",n)},this.isModified=function(){return o},this.length=function(){return g.length},this.clearAnnotations=function(){for(var a=0;a<g.length;a++)g[a].clearAnnotations()},this.getFile=function(a){return g[a]},this.getFiles=function(){return g},this.getDirectoryStructure=function(){var a={isDir:!0,content:{}};function b(b){var c=g[b],d=c.getFileName().split("/"),e=a;for(var f in d)if(d.hasOwnProperty(f)){var h=d[f];f==d.length-1?e.content[h]={isDir:!1,content:c,pos:b}:(e.content[h]||(e.content[h]={isDir:!0,content:{}}),e=e.content[h])}}for(var c in g)g.hasOwnProperty(c)&&b(c);return a},this.generateFileList=function(){if(t.isFileListVisible()){var a='<span class="vpl_ide_dirindent"></span>',b=[],d="";!function b(d,e,f){for(var g in d.content)if(d.content.hasOwnProperty(g)){var h=d.content[g];if(h.isDir)f.push(e+c.iconFolder()+c.sanitizeText(g)),b(h,e+a,f);else{var i=h.content,j=c.sanitizeText(g),k=c.sanitizeText(i.getFileName());i.isOpen()&&(j="<b>"+j+"</b>");var l='<a href="#" data-fileid="'+i.getId()+'" title="'+k+'">'+j+"</a>";i.isModified()&&(l=c.iconModified()+l),h.pos<p&&(l+=c.iconRequired()),f.push(e+l)}}}(t.getDirectoryStructure(),"",b);for(var e=0;e<b.length;e++)d+=b[e]+"<br>";I.html("<div>"+d+"</div>")}},b.on("click","span.vpl_ide_closeicon",function(){j.close(j.currentFile())}),b.on("dblclick","span.vpl_ide_closeicon",E.getAction("delete")),b.on("dblclick","a",E.getAction("rename")),I.on("dblclick","a",E.getAction("rename"))},l(),function(){var a=D.width();function b(){var b=D.width();a!=b&&(a=b,l())}b(),setInterval(b,1e3)}(),j.resetModified(),c.requestAction("load","loading",i,i.loadajaxurl).done(function(b){for(var d=!0,e=b.files,f=!1,g=0;g<e.length;g++){var h=e[g],r=j.addFile(h,!1,n,m);r?(r.resetModified(),g<p||e.length<=5?j.open(r):f=!0):d=!1}K.tabs("option","active",0),b.compilationexecution&&o.setResult(b.compilationexecution,!1),E.setTimeLeft(b),b.comments>""&&a("#vpl_ide_input_comments").val(b.comments),d?j.resetModified():j.setModified(),0===j.length()&&q>0?E.getAction("new")():i.saved||j.setModified(),j.setFontSize(i.fontSize),j.setVersion(b.version),j.fileListVisible(f),c.afterAll("AfterLoadFiles",function(){n(),l(),k(!0)})}).fail(m)};return window.VPLIDE=i,{init:function(a,b){h=new i(a,b)}}}); \ No newline at end of file +define(["jquery","jqueryui","mod_vpl/vplutil","mod_vpl/vplidefile","mod_vpl/vplidebutton","mod_vpl/vplterminal","mod_vpl/vplvnc"],function(a,b,c,d,e,f,g){if("undefined"!=typeof i)return i;var h,i=function(b,i){var j,k,l,m,n,o=this,p=i.minfiles||0,q=i.maxfiles||0,r=i.restrictededitor||i.example,s=i.example,t=!1,u=c.scrollBarWidth();c.setStr({...M.str.mod_vpl,...M.str.moodle,...i.str});var v=c.str,w=a("#"+b);if(a("head").append('<meta name="viewport" content="initial-scale=1">').append('<meta name="viewport" width="device-width">'),"object"!=typeof w)throw new Error("VPL: constructor tag_id not found");var x,y={new:!0,rename:!0,delete:!0,save:!0,run:!0,edit:!0,debug:!0,evaluate:!0,import:!0,resetfiles:!0,correctedfiles:!0,sort:!0,multidelete:!0,theme:!0,console:!0,comments:!0};"undefined"==typeof i.loadajaxurl&&(i.loadajaxurl=i.ajaxurl),x=p<q,i.new=x,i.rename=x,i.delete=x,i.comments=i.comments&&!i.example,i.sort=q-p>=2,i.multidelete=i.sort,i.import=!r;var z=function(a){return!y[a]||i[a]};function A(a){a.originalEvent.dataTransfer.dropEffect=r?"none":"copy",a.preventDefault()}function B(a){if(r)return a.stopImmediatePropagation(),!1;for(var b=[],d=function(a,c=""){return new Promise(function(e){if(a.isFile)a.file(function(a){var d=c+a.name;Object.defineProperty(a,"name",{get:function(){return d}}),b.push(a),e()});else if(a.isDirectory){a.createReader().readEntries(function(b){for(var f=[],g=0;g<b.length;g++)f.push(d(b[g],c+a.name+"/"));Promise.all(f).then(e)})}else e()})},e=a.originalEvent.dataTransfer,f=[],g=0;g<e.items.length;g++)f.push(d(e.items[g].webkitGetAsEntry()));return e.files.length>0&&(Promise.all(f).then(function(){c.readSelectedFiles(b,function(a){return j.addFile(a,!0,n,m)},function(){j.fileListVisibleIfNeeded()})}),a.stopImmediatePropagation(),!1)}function C(a){return!r||(a.stopPropagation(),!1)}i.console=z("run")||z("debug"),"undefined"==typeof i.fontSize&&(i.fontSize=12),i.fontSize=parseInt(i.fontSize),w.on("drop",B),w.on("dragover",A);var D=a("#vpl_menu"),E=new e(D,z),F=a("#vpl_tr"),G=a("#vpl_filelist"),H=a("#vpl_filelist_header"),I=a("#vpl_filelist_content"),J=a("#vpl_tabs_ul"),K=a("#vpl_tabs"),L=a("#vpl_results"),N=a("#vpl_results_accordion");G.vplMinWidth=80,this.updateEvaluationNumber=function(a){if("undefined"!=typeof a.nevaluations){var b=a.nevaluations;"undefined"!=typeof a.reductionbyevaluation&&a.reductionbyevaluation>""&&0!=a.reductionbyevaluation&&(0!=a.freeevaluations&&(b=b+"/"+a.freeevaluations),b=b+" -"+a.reductionbyevaluation),E.setExtracontent("evaluate",b)}},this.lastResult=null,this.getTerminal=function(){return va},this.setResultGrade=function(a,b){var c="vpl_ide_accordion_t_grade";if(0==N.find(".vpl_ide_accordion_c_grade").length&&(N.append('<div class="'+c+'"></div>'),N.append('<div class="vpl_ide_accordion_c_grade"></div>')),"undefined"==typeof b)return N.find("h4."+c).length>0;var d=N.find("."+c);return a>""?(d.replaceWith('<h4 class="'+c+'">'+a+"</h4>"),!0):(d.replaceWith('<div class="'+c+'"></div>'),!1)},this.setResultTab=function(b,c,d){var e="vpl_ide_accordion_t_"+b,f="vpl_ide_accordion_c_"+b;if(0==N.find("."+f).length&&(N.append('<div class="'+e+'"></div>'),N.append('<div class="'+f+'"></div>')),"undefined"==typeof d)return N.find("h4."+e).length>0;var g=N.find("."+e),h=N.find("."+f),i=a("<div>"+c+"</div>");return i.find("h4").replaceWith(function(){return a("<h5>").append(a(this).contents())}),h.html()==i.html()?c>"":c>""?(g.replaceWith('<h4 class="'+e+'">'+v(b)+"</h4>"),h.replaceWith('<div class="ui-widget '+f+'">'+i.html()+"</div>"),!0):(g.replaceWith('<div class="'+e+'"></div>'),h.replaceWith('<div class="'+f+'"></div>'),!1)},this.setResult=function(a,b){o.updateEvaluationNumber(a);var d,e=j.getFiles(),f=[];for(d=0;d<e.length;d++)f[d]=e[d].getFileName(),e[d].clearAnnotations();var g,h,k,m=!1,n=c.sanitizeText(a.grade);if(h=o.setResultGrade(n,a.grade),m=m||h,g=o.setResultTab("variables",a.variables,a.variables),m=m||g,k=c.processResult(a.compilation,f,e,!0,!1),g=o.setResultTab("compilation",k,a.compilation),m=m||g,k=c.processResult(a.evaluation,f,e,!1,!1),g=o.setResultTab("comments",k,a.evaluation),m=m||g,k=c.sanitizeText(a.execution),g=o.setResultTab("execution",k,a.execution),m=m||g,(g=o.setResultTab("description",i.description,i.description))&&"object"==typeof MathJax){var p=N.find(".vpl_ide_accordion_c_description")[0];MathJax.Hub.Queue(["Typeset",MathJax.Hub,p])}if(m=m||g){for(L.show(),L.vplVisible=!0,N.accordion("refresh"),N.accordion("option","active",h?1:0),d=0;d<e.length;d++)for(var q=e[d].getAnnotations(),r=0;r<q.length;r++)if(b||"error"==q[r].type){j.gotoFile(d,q[r].row+1);break}}else L.hide(),L.vplVisible=!1;c.delay("autoResizeTab",l)},N.accordion({heightStyle:"fill",header:"h4",animate:!1,beforeActivate:function(a,b){return!("newHeader"in b&&b.newHeader.hasClass("vpl_ide_accordion_t_grade"))}}),N.on("click","a",function(a){j.gotoFileLink(a.currentTarget)&&a.preventDefault()}),L.vplVisible=!1,L.hide(),G.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),H.text(v("filelist")),H.html(c.iconFolder()+H.html()),H.addClass("ui-widget-header ui-button-text-only ui-corner-all"),I.addClass("ui-widget ui-corner-all"),G.width(2*G.vplMinWidth),G.on("click","a",function(a){a.preventDefault(),j.gotoFileLink(a.currentTarget)}),G.vplVisible=!1,G.hide();var O=!1;function P(){return!1===O&&(O=(K.outerWidth(!0)-K.width())/2),O}function Q(a,b){var c,d=b.position.left-b.originalPosition.left;if(0!==d)c=K.width()+G.width()-G.vplMinWidth,K.resizable("option","maxWidth",c),G.width(G.vplOriginalWidth+d);else{var e=b.size.width-b.originalSize.width;L.width(L.vplOriginalWidth-e)}j.currentFile("adjustSize")}var R={containment:"parent",resize:Q,start:function(){a(window).off("resize",l),K.resizable("option","minWidth",100),L.vplVisible&&(L.vplOriginalWidth=L.width()),G.vplVisible&&(G.vplOriginalWidth=G.width())},stop:function(b,c){Q(0,c),K.resizable("option","maxWidth",1e5),K.resizable("option","minWidth",0),l(),a(window).on("resize",l)},handles:""};function S(){j.currentFile("focus")}K.resizable(R),k=function(b){var c=K.width(),d=0;J.width(1e5);var e=J.children("li:visible").last();if(e.length){var f=J.parent().scrollLeft();d=f+e.position().left+e.width()+O,J.width(d);var g=j.currentFile();if(g&&b){var h=a(g.getTabNameId()),i=f+h.position().left;(i-=(c-h.outerWidth())/2)<0&&(i=0),J.parent().finish().animate({scrollLeft:i},"slow")}}d<c&&J.width("")},l=function(){var b,c=K.width(),d=D.width(),e=!1;if(b=0,b+=G.vplVisible?1:0,b+=L.vplVisible?2:0,K.resizable("destroy"),R.handles=["e","w","e","e, w"][b],R.disable=0===b,K.resizable(R),F.width(D.outerWidth()),G.vplVisible){var f=G.outerWidth()+O;c+=f,f>=100?(d-=f,K.css("left",f)):e=!0}else K.css("left",0);if(L.vplVisible){var g=L.outerWidth()+O;c+=g,(d-=g)<100&&(e=!0)}if(e){var h=D.width()/c,i=0;G.vplVisible&&(i=G.width()*h,G.width(i-O),i+=O,K.css("left",i)),K.width(K.width()*h),L.vplVisible&&L.width(D.width()-(i+K.width()+O))}else K.width(d);k(!0),function(){var b=(t?1:.7)*(a(window).innerHeight()-D.height()-P());b<150&&(b=150),F.height(b);var c=b-3*P();K.height(c),L.vplVisible&&(L.height(c+P()),N.accordion("refresh")),G.vplVisible&&(I.height(c-(H.outerHeight()+P())),G.height(c))}(),j.currentFile("adjustSize")};var T=a.extend({},{close:S},c.dialogbaseOptions);function U(b,d){return c.showMessage(b,a.extend({},T,d))}m=function(a){return c.showErrorMessage(a,{close:S})};var V=a("#vpl_ide_dialog_new");function W(b){if("click"!=b.type&&("keypress"!=b.type||13!=b.keyCode))return!0;V.dialog("close");var c={name:a("#vpl_ide_input_newfilename").val(),contents:"",encoding:0},d=j.addFile(c,!1,n,m);return!!d&&(j.open(d),K.tabs("option","active",j.getTabPos(d)),d.focus(),!0)}var X={};X[v("ok")]=W,X[v("cancel")]=function(){a(this).dialog("close")},V.find("input").on("keypress",W),V.dialog(a.extend({},T,{title:v("create_new_file"),buttons:X})),c.setDialogTitleIcon(V,"new");var Y=a("#vpl_ide_dialog_rename");function Z(b){("click"==b.type||"keypress"==b.type&&13==b.keyCode)&&(Y.dialog("close"),j.renameFile(j.currentFile("getFileName"),a("#vpl_ide_input_renamefilename").val(),m),b.preventDefault())}Y.find("input").on("keypress",Z),X[v("ok")]=Z,Y.dialog(a.extend({},T,{open:function(){a("#vpl_ide_input_renamefilename").val(j.currentFile("getFileName"))},title:v("rename_file"),buttons:X})),c.setDialogTitleIcon(Y,"rename"),X[v("ok")]=function(){a(this).dialog("close")};var $=a("#vpl_ide_dialog_comments");$.dialog(a.extend({},T,{title:v("comments"),width:"40em",buttons:X})),c.setDialogTitleIcon($,"comments"),a("#vpl_ide_input_comments").width("30em");var _=a("#vpl_ide_dialog_about"),aa={};aa[v("ok")]=function(){a(this).dialog("close")};var ba=a("#vpl_ide_dialog_shortcuts");ba.dialog(a.extend({},T,{open:function(){var b=E.getShortcuts(j.currentFile("getEditor"));a("#vpl_ide_dialog_shortcuts").html(b)},title:v("shortcuts"),width:400,height:300,buttons:aa})),ba.dialog("option","height",300),c.setDialogTitleIcon(ba,"shortcuts"),aa[v("shortcuts")]=function(){a(this).dialog("close"),ba.dialog("open")},_.dialog(a.extend({},T,{open:function(){var b=E.getShortcuts(j.currentFile("getEditor"));_.next().find("button").filter(function(){return a(this).text()==v("shortcuts")}).button(""!=b?"enable":"disable")},title:v("about"),width:400,height:300,buttons:aa})),_.dialog("option","height",300),c.setDialogTitleIcon(_,"about");var ca=a("#vpl_ide_dialog_sort"),da={};da[v("ok")]=function(){var b=j.getFiles(),c=/[^\d]*/,d=[],e=0,f=a("#vpl_sort_list li");if(f.length==b.length){for(f.each(function(){var a=parseInt(this.id.replace(c,""));d.push(b[a])}),e=0;e<f.length;e++)b[e]=d[e];j.setModified(),a(this).dialog("close")}},da[v("cancel")]=function(){a(this).dialog("close")},ca.dialog(a.extend({},T,{title:v("sort"),buttons:da,open:function(){var b=a("#vpl_sort_list");b.html("");for(var c=j.getFiles(),d=0;d<c.length;d++){var e=a('<li id="vpl_fsort_'+d+'"class="ui-widget-content"></li>');d<p&&e.addClass("ui-state-disabled"),e.text(d+1+"-"+c[d].getFileName()),b.append(e)}b.sortable({items:"li:not(.ui-state-disabled)",placeholder:"ui-state-highlight",start:function(a,b){b.item.addClass("ui-state-highlight")},stop:function(a,b){b.item.removeClass("ui-state-highlight")}}),b.disableSelection()},maxHeight:400})),c.setDialogTitleIcon(ca,"sort");var ea=a("#vpl_ide_dialog_multidelete"),fa={};fa[v("selectall")]=function(){a(this).find("input").prop("checked",!0)},fa[v("deselectall")]=function(){a(this).find("input").prop("checked",!1)},fa[v("deleteselected")]=function(){var b=j.getFiles(),d=[];a("#vpl_multidelete_list label").each(function(){var c=a(this);if(c.find("input").prop("checked")){var e=c.data("fileid");d.push(b[e].getFileName())}});for(var e=0;e<d.length;e++)j.deleteFile(d[e],!1,m);c.delay("updateMenu",n),c.delay("updateFileList",j.updateFileList),a(this).dialog("close")},fa[v("cancel")]=function(){a(this).dialog("close")},ea.dialog(a.extend({},T,{title:v("multidelete"),buttons:fa,open:function(){var b=a("#vpl_multidelete_list");b.html("");for(var d=j.getFiles(),e=p;e<d.length;e++){var f=c.sanitizeText(d[e].getFileName()),g=a('<label><input type="checkbox"> '+f+"</label>");g.data("fileid",e),b.append(g),b.append("<br>")}b.find("label").button()},maxHeight:400,maxWidth:400})),c.setDialogTitleIcon(ea,"multidelete");var ga=a("#vpl_ide_dialog_fontsize"),ha=a("#vpl_ide_dialog_fontsize .vpl_fontsize_slider"),ia={};ia[v("ok")]=function(){var b=ha.slider("value");j.setFontSize(b),a(this).dialog("close"),c.setUserPreferences({fontSize:b})},ia[v("cancel")]=function(){j.setFontSize(ha.data("vpl_fontsize")),a(this).dialog("close")},ia[v("reset")]=function(){ha.slider("value",12)},ga.dialog(a.extend({},T,{title:v("fontsize"),buttons:ia,open:function(){ha.data("vpl_fontsize",j.getFontSize()),ha.slider("value",j.getFontSize())}})),ha.slider({min:1,max:48,change:function(){var a=ha.slider("value");j.setFontSize(a),ga.find(".vpl_fontsize_slider_value").text(a)}}),c.setDialogTitleIcon(ga,"fontsize");var ja=a("#vpl_ide_dialog_theme"),ka=a("#vpl_ide_dialog_theme select.acetheme"),la=a("#vpl_ide_dialog_theme select.interfacetheme"),ma=a("#interfacetheme-colorpicker-primary"),na=a("#interfacetheme-colorpicker-secondary"),oa=ma.add(na),pa={};pa[v("ok")]=function(){a(this).data("okpressed",!0),a(this).dialog("close");var b={aceTheme:ka.val(),interfaceTheme:la.val()};"custom"==la.val()&&(b.customInterfaceColors={primary:ma.val(),secondary:na.val()}),c.setUserPreferences(b)},pa[v("cancel")]=function(){a(this).dialog("close")};var qa=function(b){a(".vpl_ide").removeClass(function(){return(this.className.match(/(^| )(vpl_theme_[^ ]*)/)||["","",""])[2]}).addClass("vpl_theme_"+b)};ja.dialog(a.extend({},T,{title:v("theme"),buttons:pa,modal:!1,open:function(){a(this).data("okpressed",!1);var b=j.getTheme();ka.data("originalvalue",b).val(b);var c=a("#vplide").attr("class").match(/(^| )(vpl_theme_([^ ]*))/)[3];la.data("originalvalue",c).val(c),oa.each(function(){a(this).data("originalvalue",a(this).val())})},close:function(){a(this).data("okpressed")||(j.setTheme(ka.data("originalvalue")),qa(la.data("originalvalue")),oa.each(function(){a(this).val(a(this).data("originalvalue")).change()}))}})),ka.change(function(){j.setTheme(ka.val())}),la.change(function(){qa(la.val())}),c.setDialogTitleIcon(ja,"theme"),a(".colourdialogue").mousemove(function(b){a(this).next(".previewcolour").css("top",b.pageY-a(this).offset().top-50).css("left",b.pageX-a(this).offset().left)}),a(".previewcolour").mousemove(function(b){a(this).prev(".colourdialogue").trigger(b)});var ra=function(a){var b=a.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(,\s*(\d+))?\)$/);return{r:parseInt(b[1]),g:parseInt(b[2]),b:parseInt(b[3])}},sa=function(a,b,c){return"rgb("+(a.r*c+b.r*(1-c))+","+(a.g*c+b.g*(1-c))+","+(a.b*c+b.b*(1-c))+")"},ta=[...document.styleSheets].filter(function(a){return"custom-interfacetheme-css"==a.title})[0],ua=function(){var a=ma.next(".admin_colourpicker").children(".currentcolour").css("background-color"),b=na.next(".admin_colourpicker").children(".currentcolour").css("background-color"),c=ra(a),d=ra(b);ta.cssRules.length>0&&ta.deleteRule(0),ta.insertRule(".path-mod-vpl .vpl_ide {--vpl-interface-theme-primary: "+a+";--vpl-interface-theme-secondary: "+b+";--vpl-interface-theme-ternary: "+sa(c,d,.3)+";--vpl-interface-theme-highlight: "+sa(c,d,.7)+";}",0)};oa.change(function(){if(null===a(this).val().match(/^(#(?:[a-f0-9A-F]{3}){1,2}|[a-z]+)$/))return!1;a(this).next(".admin_colourpicker").children(".currentcolour").css("background-color",a(this).val()),ua()}),a(".colourdialogue").click(function(){ua()}),ua();var va=new f("vpl_dialog_terminal","vpl_terminal",v),wa=new g("vpl_dialog_vnc",v),xa=va,ya=a("#vpl_ide_input_file");function za(){c.requestAction("resetfiles","",{},i.ajaxurl).done(function(a){var b=a.files;for(var d in b)b.hasOwnProperty(d)&&j.addFile(b[d],!0,c.doNothing,m);j.fileListVisibleIfNeeded(),c.delay("updateMenu",n)}).fail(m)}function Aa(){c.requestAction("correctedfiles","",{},i.ajaxurl).done(function(a){var b=a.files;for(var d in b)j.addFile(b[d],!0,c.doNothing,m);j.fileListVisibleIfNeeded()}).fail(m)}ya.on("change",function(){c.readSelectedFiles(this.files,function(a){return j.addFile(a,!0,n,m)},function(){j.fileListVisibleIfNeeded()})}),E.add({name:"filelist",originalAction:function(){j.fileListVisible(!j.isFileListVisible()),c.delay("updateMenu",n),c.delay("autoResizeTab",l),c.delay("updateFileList",j.updateFileList)},bindKey:{win:"Ctrl-L",mac:"Ctrl-L"}}),E.add({name:"new",originalAction:function(){j.length()<q&&V.dialog("open")},bindKey:{win:"Alt-N",mac:"Option-N"}}),E.add({name:"rename",originalAction:function(){var a=j.currentFile();a&&j.getFilePosById(a.getId())>=p&&Y.dialog("open")},bindKey:{win:"Ctrl-R",mac:"Ctrl-R"}}),E.add({name:"delete",originalAction:function(){var a=j.currentFile();if(a){var b=a.getFileName();U(v("delete_file_fq",b),{ok:function(){j.deleteFile(b,m)},title:v("delete_file_q"),icon:"trash"})}},bindKey:{win:"Ctrl-D",mac:"Ctrl-D"}}),E.add({name:"close",originalAction:function(){var a=j.currentFile();a&&j.close(a)},bindKey:{win:"Alt-W",mac:"Option-W"}}),E.add({name:"import",originalAction:function(){ya.val(""),ya.trigger("click")},bindKey:{win:"Ctrl-I",mac:"Ctrl-I"}}),E.add({name:"sort",originalAction:function(){ca.dialog("open")},bindKey:{win:"Ctrl-O",mac:"Ctrl-O"}}),E.add({name:"multidelete",originalAction:function(){ea.dialog("open")}}),E.add({name:"fontsize",originalAction:function(){ga.dialog("open")}}),E.add({name:"theme",originalAction:function(){ja.dialog("open")}}),E.add({name:"print",originalAction:function(){window.print()},bindKey:{win:"Alt-P",mac:"Command-P"}}),E.add({name:"undo",originalAction:function(){j.currentFile("undo")}}),E.add({name:"redo",originalAction:function(){j.currentFile("redo")}}),E.add({name:"select_all",editorName:"selectall",originalAction:function(){j.currentFile("selectAll")}}),E.add({name:"find",originalAction:function(){j.currentFile("find")}}),E.add({name:"find_replace",editorName:"replace",originalAction:function(){j.currentFile("replace")}}),E.add({name:"next",editorName:"findnext",originalAction:function(){j.currentFile("next")}}),E.add({name:"fullscreen",originalAction:function(){var b="header, nav, footer, aside, .dropdown, #page-header, div.navbar, #nav-drawer";b+=", div.tabtree, #dock, .breadcrumb-nav, .moodle-actionmenu",t?(w.removeClass("vpl_ide_root_fullscreen"),a("body").removeClass("vpl_body_fullscreen"),E.setText("fullscreen","fullscreen",c.str("fullscreen")),a(b).show(),a("#vpl_ide_user").hide(),t=!1):(a("body").addClass("vpl_body_fullscreen").scrollTop(0),a(b).hide(),w.addClass("vpl_ide_root_fullscreen"),E.setText("fullscreen","regularscreen",c.str("regularscreen")),i.username&&a("#vpl_ide_user").show(),t=!0),S(),setTimeout(l,10)},bindKey:{win:"Alt-F",mac:"Ctrl-F"}}),E.add({name:"download",originalAction:function(){window.location=i.download}}),E.add({name:"correctedfiles",originalAction:function(){U(v("surecorrectedfiles"),{title:v("correctedfiles"),ok:Aa})}}),E.add({name:"resetfiles",originalAction:function(){U(v("sureresetfiles"),{title:v("resetfiles"),ok:za,icon:"resetfiles"})}}),E.add({name:"save",originalAction:function(){var b={files:j.getFilesToSave(),comments:a("#vpl_ide_input_comments").val(),version:j.getVersion()};!function a(){c.requestAction("save","saving",b,i.ajaxurl).done(function(d){d.requestsconfirmation?U(d.question,{title:v("saving"),icon:"alert",yes:function(){b.version=d.version,a()}}):(j.resetModified(),j.setVersion(d.version),E.setTimeLeft(d),c.delay("updateMenu",n))}).fail(m)}()},bindKey:{win:"Ctrl-S",mac:"Command-S"}});var Ba={getConsole:function(){return xa},setResult:o.setResult,ajaxurl:i.ajaxurl,run:function(b,d,e){xa&&xa.isOpen()&&xa.close();var f=function(){e.readyState!=e.OPEN&&a.ajax({type:"POST",url:i.loadajaxurl+"getlastversion",data:JSON.stringify(i),contentType:"application/json; charset=utf-8",dataType:"json"}).done(function(a){a.success&&j.getVersion()<a.response.version&&U(v("morerecentversionloadprompt"),{title:v("morerecentversionsaved"),yes:function(){c.requestAction("load","loading",i,i.loadajaxurl).done(function(a){for(var b=a.files,d=0;d<b.length;d++)j.addFile(b[d],!0,c.doNothing,m);j.fileListVisibleIfNeeded(),j.resetModified(),j.setVersion(a.version),j.fileListVisible(b.length>5),K.tabs("option","active",0),c.afterAll("AfterLoadFiles",function(){j.resetModified(),n(),l(),k(!1)})}).fail(m)}})}),e.close(),S()};"terminal"==b?(xa=va,va.connect(d.executionURL,f)):(xa=wa,wa.connect(d.secure,d.server,d.portToUse,d.VNCpassword,d.executionPath,f))},lastAction:!1,getLastAction:function(){var a=this.lastAction;return this.lastAction=!1,a},setLastAction:function(a){this.lastAction=a}};function Ca(a,b,d){d||(d={}),xa.isConnected()||c.requestAction(a,"",d,i.ajaxurl).done(function(d){c.webSocketMonitor(d,a,b,Ba)}).fail(m)}function Da(){Ca("run","running",{XGEOMETRY:wa.getCanvasSize()})}function Ea(){Ca("debug","debugging",{XGEOMETRY:wa.getCanvasSize()})}function Fa(){Ca("evaluate","evaluating")}E.add({name:"run",originalAction:function(){Ba.setLastAction(Da),Da()},bindKey:{win:"Ctrl-F11",mac:"Command-U"}}),E.add({name:"debug",originalAction:function(){Ba.setLastAction(Ea),Ea()},bindKey:{win:"Alt-F11",mac:"Option-U"}}),E.add({name:"evaluate",originalAction:function(){Ba.setLastAction(Fa),Fa()},bindKey:{win:"Shift-F11",mac:"Command-Option-U"}}),E.add({name:"comments",originalAction:function(){$.dialog("open")}}),E.add({name:"console",originalAction:function(){xa.isOpen()?xa.close():xa.show()}}),E.add({name:"user"}),E.add({name:"about",originalAction:function(){_.dialog("open")}}),E.add({name:"timeleft",originalAction:function(){E.toggleTimeLeft()}}),E.add({name:"more",originalAction:function(){var b=a("#vpl_ide_menuextra");b.is(":visible")?(E.setText("more","more",c.str("more")),b.hide()):(E.setText("more","less",c.str("less")),b.show()),c.delay("updateMenu",n),c.delay("autoResizeTab",l)}}),D.addClass("ui-widget-header ui-corner-all");var Ga="";Ga+=E.getHTML("more"),Ga+=E.getHTML("save"),Ga+="<span id='vpl_ide_mexecution'>",Ga+=E.getHTML("run"),Ga+=E.getHTML("debug"),Ga+=E.getHTML("evaluate"),Ga+=E.getHTML("comments"),Ga+=E.getHTML("console"),Ga+="</span> ",Ga+="<span id='vpl_ide_menuextra'>",Ga+="<span id='vpl_ide_file'>",Ga+=E.getHTML("filelist"),Ga+=E.getHTML("new"),Ga+=E.getHTML("rename"),Ga+=E.getHTML("delete"),Ga+=E.getHTML("import"),Ga+=E.getHTML("download"),Ga+=E.getHTML("resetfiles"),Ga+=E.getHTML("correctedfiles"),Ga+=E.getHTML("sort"),Ga+=E.getHTML("multidelete"),Ga+=E.getHTML("fontsize"),Ga+=E.getHTML("theme"),Ga+="</span> ",Ga+="<span id='vpl_ide_edit'>",Ga+=E.getHTML("undo"),Ga+=E.getHTML("redo"),Ga+=E.getHTML("select_all"),Ga+=E.getHTML("find"),Ga+=E.getHTML("find_replace"),Ga+=E.getHTML("next"),Ga+="</span> ",Ga+="</span> ",Ga+=E.getHTML("fullscreen")+" ",Ga+=E.getHTML("about")+" ",Ga+=E.getHTML("user")+" ",Ga+=E.getHTML("timeleft"),Ga+='<div class="clearfix"></div>',D.append(Ga),a("#vpl_ide_more").button(),a("#vpl_ide_save").button(),a("#vpl_ide_menuextra").hide(),a("#vpl_ide_file").controlgroup(),a("#vpl_ide_edit").controlgroup(),a("#vpl_ide_mexecution").controlgroup(),a("#vpl_ide_fullscreen").button(),a("#vpl_ide_theme").button(),a("#vpl_ide_about").button(),a("#vpl_ide_user").button().css("float","right").hide(),a("#vpl_ide_timeleft").button().css("float","right").hide(),a("#vpl_menu .ui-button").css("padding","6px"),a("#vpl_menu .ui-button-text").css("padding","0");for(var Ha=["filelist","more","fullscreen","about","resetfiles","download","comments","console","import","fontsize","timeleft"],Ia=0;Ia<Ha.length;Ia++)E.enable(Ha[Ia],!0);E.setExtracontent("user",i.username),E.setTimeLeft(i),n=function(){var a,b=j.currentFile(),d=j.length();d?K.show():K.hide(),j.isFileListVisible()?E.setText("filelist","filelistclose",c.str("filelist")):E.setText("filelist","filelist",c.str("filelist"));var e,f=j.isModified();if(E.enable("save",f),E.enable("run",(!f||i.example)&&z("run")),E.enable("debug",(!f||i.example)&&z("debug")),E.enable("evaluate",(!f||i.example)&&z("evaluate")),E.enable("download",!f),E.enable("new",d<q),E.enable("sort",d-p>1),E.enable("multidelete",d-p>1),E.enable("theme",!0),E.enable("correctedfiles",i.correctedfiles),b&&0!==d){var g=j.getFilePosById(b.getId());E.enable("rename",g>=p&&0!==d),E.enable("delete",g>=p&&0!==d),E.enable("undo",b.hasUndo()),E.enable("redo",b.hasRedo()),E.enable("select_all",b.hasSelectAll()),E.enable("find",b.hasFind()),E.enable("find_replace",b.hasFindReplace()),E.enable("next",b.hasNext()),c.delay("updateFileList",j.updateFileList)}else for(e=["rename","delete","undo","redo","select_all","find","find_replace","next"],a=0;a<e.length;a++)E.enable(e[a],!1)},K.on("tabsactivate",function(){j.currentFile("focus"),c.delay("updateMenu",n),c.delay("autoResizeTab",l)});var Ja=a(window);Ja.on("resize",l),i.example||Ja.on("beforeunload",function(){if(j.isModified())return v("changesNotSaved")}),j=new function(){var b=a("#vpl_tabs_ul");a("#vpl_tabs").tabs();var e,f=a("#vpl_tabs").tabs("widget"),g=[],m=[],o=!0,t=this;function w(a){for(var b=a.toLowerCase()+"/",c=0;c<g.length;c++){var d=g[c].getFileName().toLowerCase()+"/";if(0===d.indexOf(b)||0===b.indexOf(d))return!0}return!1}function x(a,b){if(c.isBlockly(a))return!1;if(c.isBlockly(b))for(var d=0;d<g.length;d++)if(c.isBlockly(g[d].getFileName()))return!0;return!1}t.setVersion=function(a){e=a},t.getVersion=function(){return e},this.updateFileList=function(){t.generateFileList()},this.fileNameExists=function(a){for(var b=a.toLowerCase(),c=0;c<g.length;c++)if(g[c].getFileName().toLowerCase()==b)return c;return-1},this.restrictedPaste=C,this.dropHandler=B,this.dragoverHandler=A,this.readOnly=s,this.restrictedEdit=r,this.adjustTabsTitles=k,this.minNumberOfFiles=p,this.scrollBarWidth=u;var y="";this.setClipboard=function(a){y=a},this.getClipboard=function(){return y},this.getTabPos=function(a){for(var b=0;b<m.length;b++)if(m[b]==a)return b;return m.length},this.getTheme=function(){return i.theme},this.setTheme=function(a){i.theme=a;for(var b=0;b<g.length;b++)g[b].setTheme(a)},this.addTab=function(a){var c='<a href="#vpl_file'+a+'"></a>';b.append('<li id="vpl_tab_name'+a+'">'+c+"</li>"),f.append('<div id="vpl_file'+a+'" class="vpl_ide_file"></div>')},this.removeTab=function(a){b.find("#vpl_tab_name"+a).remove(),f.find("#vpl_file"+a).remove()},this.open=function(a){var b;if(!(b="object"==typeof a?a:g[a]).isOpen()){var d=b.getId();t.addTab(d),m.push(b),E.setGetkeys(b.open()),f.tabs("refresh"),k(!1),c.delay("updateFileList",t.updateFileList),c.delay("updateMenu",n)}},this.close=function(a){if(a.isOpen()){var b,d=a.getId();a.close(),t.removeTab(d);var e=t.getTabPos(a);return m.splice(e,1),f.tabs("refresh"),k(!1),t.fileListVisible(!0),c.delay("updateFileList",t.updateFileList),c.delay("adjustTabsTitles",k,!1),m.length>e?(b=t.getFilePosById(m[e].getId()),void t.gotoFile(b,"c")):e>0?(b=t.getFilePosById(m[e-1].getId()),void t.gotoFile(b,"c")):void 0}},this.isClosed=function(a){return!g[a].isOpen()},this.fileListVisible=function(a){a!==G.vplVisible&&(a?c.delay("fileListVisible",function(){G.vplVisible=!0,t.updateFileList(),G.show(),l()}):c.delay("fileListVisible",function(){G.vplVisible=!1,G.hide(),l()}))},this.isFileListVisible=function(){return G.vplVisible},this.fileListVisibleIfNeeded=function(){if(!this.isFileListVisible())for(var a=0;a<g.length;a++)if(!g[a].isOpen())return void this.fileListVisible(!0)},this.setFontSize=function(a){i.fontSize=a;for(var b=0;b<g.length;b++)g[b].setFontSize(a);va.setFontSize(a)},this.getFontSize=function(){return i.fontSize},this.addFile=function(a,b,e,f){if("string"!=typeof a.name||!c.validPath(a.name))return f(v("incorrect_file_name")+" ("+a.name+")"),!1;!0!==b&&(b=!1);var j=this.fileNameExists(a.name);if(-1!=j)return b?(g[j].setContent(a.contents),t.setModified(),e(),c.delay("updateFileList",t.updateFileList),a):(f(v("filenotadded",a.name)),!1);if(w(a.name)||x("",a.name))return f(v("filenotadded",a.name)),!1;if(g.length>=q)return f(v("maxfilesexceeded")+" ("+q+")"),!1;var k=c.getUniqueId(),l=new d(k,a.name,a.contents,this,h,i.id);return l.resetModified(),1==a.encoding?l.extendToBinary():c.isBlockly(a.name)?l.extendToBlockly():l.extendToCodeEditor(),l.setFileName(a.name),g.push(l),t.setModified(),g.length>5&&t.fileListVisible(!0),e(),l},this.renameFile=function(a,b,d){var e=this.fileNameExists(a);try{if(-1==e)throw new Error("Internal error: File name not found");if(e<p)throw new Error("Internal error: Renaming required filename");if(g[e].getFileName()==b)return!0;if(!c.validPath(b)||w(b)||x(a,b))throw v("incorrect_file_name");if(c.isBinary(a)&&c.fileExtension(a)!=c.fileExtension(b))throw v("incorrect_file_name");if(c.isBlockly(a)!=c.isBlockly(b))throw v("incorrect_file_name");g[e].setFileName(b)}catch(a){return d(v("filenotrenamed",b)+": "+a),!1}return t.setModified(),k(!1),c.delay("updateFileList",t.updateFileList),!0},this.deleteFile=function(a,b,d){var e=this.fileNameExists(a);return-1==e?(d(v("filenotdeleted",a)),!1):e<p?(d(v("filenotdeleted",a)),!1):(t.setModified(),t.close(g[e]),g.splice(e,1),c.delay("updateFileList",t.updateFileList),!0)},this.currentFile=function(){var a=f.tabs("option","active");if(a in m){var b=m[a];if(0===arguments.length)return b;var c=arguments[0];if("function"==typeof b[c]){var d=b[c],e=Array.prototype.slice(arguments);return e.shift(),d.apply(b,e)}}return!1},this.currentPos=function(){return f.tabs("option","active")},this.getFileTab=function(a){for(var b=0;b<m.length;b++)if(m[b].getId()==a)return b;return-1},this.getFilePosById=function(a){for(var b=0;b<g.length;b++)if(g[b].getId()==a)return b;return-1},this.gotoFile=function(a,b){var c=g[a];t.open(c),f.tabs("option","active",t.getFileTab(c.getId())),"c"!==b&&c.gotoLine(parseInt(b,10)),c.focus()},this.gotoFileLink=function(b){var c=a(b),d=c.data("file"),e=-1;if((e=d>""?this.fileNameExists(d):t.getFilePosById(c.data("fileid")))>=0){var f=c.data("line");return"undefined"==typeof f&&(f="c"),t.gotoFile(e,f),!0}return!1},this.getFilesToSave=function(){for(var a=[],b=0;b<g.length;b++){var c={};c.name=g[b].getFileName(),c.contents=g[b].getContent(),c.encoding=g[b].isBinary()?1:0,a.push(c)}return a},this.resetModified=function(){o=!1;for(var a=0;a<g.length;a++)g[a].resetModified();c.delay("updateMenu",n),c.delay("updateFileList",t.updateFileList)},this.setModified=function(){o=!0,c.delay("updateFileList",t.updateFileList),c.delay("updateMenu",n)},this.isModified=function(){return o},this.length=function(){return g.length},this.clearAnnotations=function(){for(var a=0;a<g.length;a++)g[a].clearAnnotations()},this.getFile=function(a){return g[a]},this.getFiles=function(){return g},this.getDirectoryStructure=function(){var a={isDir:!0,content:{}};function b(b){var c=g[b],d=c.getFileName().split("/"),e=a;for(var f in d)if(d.hasOwnProperty(f)){var h=d[f];f==d.length-1?e.content[h]={isDir:!1,content:c,pos:b}:(e.content[h]||(e.content[h]={isDir:!0,content:{}}),e=e.content[h])}}for(var c in g)g.hasOwnProperty(c)&&b(c);return a},this.generateFileList=function(){if(t.isFileListVisible()){var a='<span class="vpl_ide_dirindent"></span>',b=[],d="";!function b(d,e,f){for(var g in d.content)if(d.content.hasOwnProperty(g)){var h=d.content[g];if(h.isDir)f.push(e+c.iconFolder()+c.sanitizeText(g)),b(h,e+a,f);else{var i=h.content,j=c.sanitizeText(g),k=c.sanitizeText(i.getFileName());i.isOpen()&&(j="<b>"+j+"</b>");var l='<a href="#" data-fileid="'+i.getId()+'" title="'+k+'">'+j+"</a>";i.isModified()&&(l=c.iconModified()+l),h.pos<p&&(l+=c.iconRequired()),f.push(e+l)}}}(t.getDirectoryStructure(),"",b);for(var e=0;e<b.length;e++)d+=b[e]+"<br>";I.html("<div>"+d+"</div>")}},b.on("click","span.vpl_ide_closeicon",function(){j.close(j.currentFile())}),b.on("dblclick","span.vpl_ide_closeicon",E.getAction("delete")),b.on("dblclick","a",E.getAction("rename")),I.on("dblclick","a",E.getAction("rename"))},l(),function(){var a=D.width();function b(){var b=D.width();a!=b&&(a=b,l())}b(),setInterval(b,1e3)}(),j.resetModified(),c.requestAction("load","loading",i,i.loadajaxurl).done(function(b){for(var d=!0,e=b.files,f=!1,g=0;g<e.length;g++){var h=e[g],r=j.addFile(h,!1,n,m);r?(r.resetModified(),g<p||e.length<=5?j.open(r):f=!0):d=!1}K.tabs("option","active",0),b.compilationexecution&&o.setResult(b.compilationexecution,!1),E.setTimeLeft(b),b.comments>""&&a("#vpl_ide_input_comments").val(b.comments),d?j.resetModified():j.setModified(),0===j.length()&&q>0?E.getAction("new")():i.saved||j.setModified(),j.setFontSize(i.fontSize),j.setVersion(b.version),j.fileListVisible(f),c.afterAll("AfterLoadFiles",function(){n(),l(),k(!0)})}).fail(m)};return window.VPLIDE=i,{init:function(a,b){h=new i(a,b)}}}); \ No newline at end of file diff --git a/amd/src/vplide.js b/amd/src/vplide.js index 09b7eee5..aca63e25 100644 --- a/amd/src/vplide.js +++ b/amd/src/vplide.js @@ -1737,6 +1737,44 @@ define( } }); + var reloadFilesAfterExecution = function() { + $.ajax({ + type: "POST", + url: options.loadajaxurl + 'getlastversion', + 'data': JSON.stringify(options), + contentType: "application/json; charset=utf-8", + dataType: "json" + }).done(function(outcome) { + if (outcome.success && fileManager.getVersion() < outcome.response.version) { + // A more recent version exists, prompt user to load it. + showMessage(str('morerecentversionloadprompt'), { + title: str('morerecentversionsaved'), + yes: function() { + VPLUtil.requestAction('load', 'loading', options, options.loadajaxurl) + .done(function(response) { + var files = response.files; + for (var i = 0; i < files.length; i++) { + fileManager.addFile(files[i], true, VPLUtil.doNothing, showErrorMessage); + } + fileManager.fileListVisibleIfNeeded(); + fileManager.resetModified(); + fileManager.setVersion(response.version); + fileManager.fileListVisible(files.length > 5); + tabs.tabs('option', 'active', 0); + VPLUtil.afterAll('AfterLoadFiles', function() { + fileManager.resetModified(); + updateMenu(); + autoResizeTab(); + adjustTabsTitles(false); + }); + }) + .fail(showErrorMessage); + } + }); + } + }); + }; + var executionActions = { 'getConsole': function() { return lastConsole; @@ -1747,19 +1785,20 @@ define( if (lastConsole && lastConsole.isOpen()) { lastConsole.close(); } + var afterExecution = function() { + if (ws.readyState != ws.OPEN) { + reloadFilesAfterExecution(); + } + ws.close(); + focusCurrentFile(); + }; if (type == 'terminal') { lastConsole = terminal; - terminal.connect(coninfo.executionURL, function() { - ws.close(); - focusCurrentFile(); - }); + terminal.connect(coninfo.executionURL, afterExecution); } else { lastConsole = VNCClient; VNCClient.connect(coninfo.secure, coninfo.server, coninfo.portToUse, coninfo.VNCpassword, - coninfo.executionPath, function() { - ws.close(); - focusCurrentFile(); - }); + coninfo.executionPath, afterExecution); } }, 'lastAction': false, diff --git a/editor/editor_utility.php b/editor/editor_utility.php index 70a50990..c7e1483a 100644 --- a/editor/editor_utility.php +++ b/editor/editor_utility.php @@ -121,6 +121,8 @@ class vpl_editor_util { 'interfacetheme', 'keyboard', 'maxfilesexceeded', + 'morerecentversionloadprompt', + 'morerecentversionsaved', 'new', 'next', 'load', diff --git a/forms/edit.json.php b/forms/edit.json.php index ce17308c..31dceb0a 100644 --- a/forms/edit.json.php +++ b/forms/edit.json.php @@ -118,6 +118,9 @@ try { case 'getjails' : $outcome->response->servers = vpl_jailserver_manager::get_https_server_list( $vpl->get_instance()->jailservers ); break; + case 'getlastversion' : + $outcome->response->version = $vpl->last_user_submission( $userid )->id; + break; default : throw new Exception( 'ajax action error: ' + $action ); } diff --git a/lang/en/vpl.php b/lang/en/vpl.php index 444549f3..ff723045 100644 --- a/lang/en/vpl.php +++ b/lang/en/vpl.php @@ -203,6 +203,8 @@ $string ['minsimlevel'] = 'Minimum similarity level to show'; $string ['moduleconfigtitle'] = 'VPL Module Config'; $string ['modulename'] = 'Virtual programming lab'; $string ['modulenameplural'] = 'Virtual programming labs'; +$string ['morerecentversionloadprompt'] = 'A more recent version has been saved. Do you want to load it?'; +$string ['morerecentversionsaved'] = 'More recent version saved'; $string ['multidelete'] = 'Multiple delete'; $string ['nevaluations'] = '{$a} automatic evaluations done'; $string ['new'] = 'New'; diff --git a/lang/fr/vpl.php b/lang/fr/vpl.php index 45fa5bef..e98d20c6 100644 --- a/lang/fr/vpl.php +++ b/lang/fr/vpl.php @@ -181,6 +181,8 @@ $string ['minsimlevel'] = 'Niveau minimal de similarité à montrer'; $string ['moduleconfigtitle'] = 'Config. du module VPL'; $string ['modulename'] = 'Laboratoire virtuel de programmation (VPL)'; $string ['modulenameplural'] = 'Laboratoires virtuels de programmation'; +$string ['morerecentversionloadprompt'] = 'Une version plus récente a été sauvegardée. Voulez-vous la charger ?'; +$string ['morerecentversionsaved'] = 'Version plus récente sauvegardée'; $string ['multidelete'] = 'Suppression multiple'; $string ['new'] = 'Nouveau'; $string ['new_file_name'] = 'Nom du nouveau fichier'; diff --git a/locallib.php b/locallib.php index 89c53ecf..457952a4 100644 --- a/locallib.php +++ b/locallib.php @@ -918,6 +918,7 @@ function vpl_get_webservice_available() { } function vpl_get_webservice_token($vpl) { global $DB, $USER, $CFG; + require_once($CFG->dirroot . '/webservice/lib.php'); $now = time(); if ($USER->id <= 2) { return ''; @@ -962,6 +963,42 @@ function vpl_get_webservice_urlbase($vpl) { . '&wstoken=' . $token . '&id=' . $vpl->get_course_module()->id . '&wsfunction='; } +/** + * Retrieve or generate a temporary embedded webservice token for the given vpl and user. + * @param mod_vpl $vpl The VPL to get the token for. + * @param int $userid The id of the user to get the token for. + * @return string The token, or an empty string if service is unavailable. + */ +function vpl_get_temporary_webservice_token($vpl, $userid) { + global $CFG, $DB; + require_once($CFG->libdir . '/externallib.php'); + if (! $CFG->enablewebservices) { + return ''; + } + $service = $DB->get_record( 'external_services', array ( + 'shortname' => 'mod_vpl_edit', + 'enabled' => 1 + ) ); + if (empty( $service )) { + return ''; + } + // If such a token already exists and is still valid, use it. + $tokens = $DB->get_records( 'external_tokens', array( + 'tokentype' => EXTERNAL_TOKEN_EMBEDDED, + 'userid' => $userid, + 'externalserviceid' => $service->id, + 'sid' => session_id(), + 'contextid' => $vpl->get_context()->id + ) ); + foreach ($tokens as $token) { + if ($token->validuntil == 0 || $token->validuntil > time()) { + return $token->token; + } + } + // No such valid token found, generate a new one. + return external_generate_token(EXTERNAL_TOKEN_EMBEDDED, $service, $userid, $vpl->get_context()->id, time() + DAYSECS); +} + function vpl_timestamp_to_midday($timestamp) { return $timestamp - ($timestamp + date('Z')) % 86400 + 43200; } diff --git a/vpl_submission_CE.class.php b/vpl_submission_CE.class.php index d91169bf..11e0fe92 100644 --- a/vpl_submission_CE.class.php +++ b/vpl_submission_CE.class.php @@ -25,6 +25,7 @@ defined('MOODLE_INTERNAL') || die(); require_once(dirname(__FILE__).'/../../lib/gradelib.php'); +require_once(dirname(__FILE__).'/locallib.php'); require_once(dirname(__FILE__).'/vpl_submission.class.php'); require_once(dirname(__FILE__).'/jail/jailserver_manager.class.php'); require_once(dirname(__FILE__).'/jail/running_processes.class.php'); @@ -289,6 +290,7 @@ class mod_vpl_submission_CE extends mod_vpl_submission { $info .= vpl_bash_export( 'MOODLE_USER_NAME', $user->username ); } $info .= vpl_bash_export( 'MOODLE_USER_ID', $subinstance->userid ); + $info .= vpl_bash_export( 'MOODLE_USER_TOKEN', vpl_get_temporary_webservice_token($vpl, $subinstance->userid) ); if ($type == 2) { // If evaluation add information. $info .= vpl_bash_export( 'VPL_MAXTIME', $data->maxtime ); $info .= vpl_bash_export( 'VPL_MAXMEMORY', $data->maxmemory ); -- GitLab