Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
|
c4a91ccf0f |
6 changed files with 1428 additions and 1 deletions
|
@ -18,7 +18,7 @@ from judge.feed import AtomBlogFeed, AtomCommentFeed, AtomProblemFeed, BlogFeed,
|
|||
from judge.forms import CustomAuthenticationForm
|
||||
from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \
|
||||
SolutionSitemap, UrlSitemap, UserSitemap
|
||||
from judge.views import TitledTemplateView, about, api, blog, comment, contests, language, license, mailgun, \
|
||||
from judge.views import TitledTemplateView, about, api, blog, comment, contests, ide, language, license, mailgun, \
|
||||
notification, organization, preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, \
|
||||
ticket, totp, user, widgets
|
||||
from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \
|
||||
|
@ -399,6 +399,11 @@ urlpatterns = [
|
|||
url(r'submit/$', user.import_users_submit, name='import_users_submit'),
|
||||
url(r'sample/$', user.sample_import_users, name='import_users_sample')
|
||||
])),
|
||||
|
||||
url(r'^ide/', include([
|
||||
url(r'^$', login_required(TitledTemplateView.as_view(template_name='ide.html', title=_('IDE'))), name='ide'),
|
||||
url(r'api', ide.api, name='ide_api'),
|
||||
])),
|
||||
]
|
||||
|
||||
favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png',
|
||||
|
|
29
judge/views/ide.py
Normal file
29
judge/views/ide.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from django.utils.translation import gettext as _
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponse, Http404, JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
import requests, json, http
|
||||
|
||||
PREFIX_URL = 'ide/api'
|
||||
|
||||
@login_required
|
||||
@csrf_exempt
|
||||
def api(request):
|
||||
url = 'http://localhost:2358' + request.get_full_path()[len(PREFIX_URL) + 1:]
|
||||
headers = {'X-Judge0-Token': 'cuom1999'}
|
||||
r = None
|
||||
if request.method == 'POST':
|
||||
r = requests.post(url, data=json.loads(request.body.decode('utf-8')), headers=headers)
|
||||
elif request.method == 'GET':
|
||||
r = requests.get(url, headers=headers)
|
||||
else:
|
||||
return Http404()
|
||||
|
||||
res = r.content.decode('utf-8')
|
||||
try:
|
||||
res = json.loads(r.content.decode('utf-8'))
|
||||
return JsonResponse(res, status=r.status_code, safe=False)
|
||||
except Exception:
|
||||
return HttpResponse(res)
|
||||
|
132
resources/download.js
Normal file
132
resources/download.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
//download.js v3.0, by dandavis; 2008-2014. [CCBY2] see http://danml.com/download.html for tests/usage
|
||||
// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
|
||||
// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
|
||||
// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support
|
||||
|
||||
// data can be a string, Blob, File, or dataURL
|
||||
|
||||
|
||||
|
||||
|
||||
function download(data, strFileName, strMimeType) {
|
||||
|
||||
var self = window, // this script is only for browsers anyway...
|
||||
u = "application/octet-stream", // this default mime also triggers iframe downloads
|
||||
m = strMimeType || u,
|
||||
x = data,
|
||||
D = document,
|
||||
a = D.createElement("a"),
|
||||
z = function(a){return String(a);},
|
||||
|
||||
|
||||
B = self.Blob || self.MozBlob || self.WebKitBlob || z,
|
||||
BB = self.MSBlobBuilder || self.WebKitBlobBuilder || self.BlobBuilder,
|
||||
fn = strFileName || "download",
|
||||
blob,
|
||||
b,
|
||||
ua,
|
||||
fr;
|
||||
|
||||
//if(typeof B.bind === 'function' ){ B=B.bind(self); }
|
||||
|
||||
if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
|
||||
x=[x, m];
|
||||
m=x[0];
|
||||
x=x[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//go ahead and download dataURLs right away
|
||||
if(String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)){
|
||||
return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:
|
||||
navigator.msSaveBlob(d2b(x), fn) :
|
||||
saver(x) ; // everyone else can save dataURLs un-processed
|
||||
}//end if dataURL passed?
|
||||
|
||||
try{
|
||||
|
||||
blob = x instanceof B ?
|
||||
x :
|
||||
new B([x], {type: m}) ;
|
||||
}catch(y){
|
||||
if(BB){
|
||||
b = new BB();
|
||||
b.append([x]);
|
||||
blob = b.getBlob(m); // the blob
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function d2b(u) {
|
||||
var p= u.split(/[:;,]/),
|
||||
t= p[1],
|
||||
dec= p[2] == "base64" ? atob : decodeURIComponent,
|
||||
bin= dec(p.pop()),
|
||||
mx= bin.length,
|
||||
i= 0,
|
||||
uia= new Uint8Array(mx);
|
||||
|
||||
for(i;i<mx;++i) uia[i]= bin.charCodeAt(i);
|
||||
|
||||
return new B([uia], {type: t});
|
||||
}
|
||||
|
||||
function saver(url, winMode){
|
||||
|
||||
|
||||
if ('download' in a) { //html5 A[download]
|
||||
a.href = url;
|
||||
a.setAttribute("download", fn);
|
||||
a.innerHTML = "downloading...";
|
||||
D.body.appendChild(a);
|
||||
setTimeout(function() {
|
||||
a.click();
|
||||
D.body.removeChild(a);
|
||||
if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(a.href);}, 250 );}
|
||||
}, 66);
|
||||
return true;
|
||||
}
|
||||
|
||||
//do iframe dataURL download (old ch+FF):
|
||||
var f = D.createElement("iframe");
|
||||
D.body.appendChild(f);
|
||||
if(!winMode){ // force a mime that will download:
|
||||
url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
|
||||
}
|
||||
|
||||
|
||||
f.src = url;
|
||||
setTimeout(function(){ D.body.removeChild(f); }, 333);
|
||||
|
||||
}//end saver
|
||||
|
||||
|
||||
if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
|
||||
return navigator.msSaveBlob(blob, fn);
|
||||
}
|
||||
|
||||
if(self.URL){ // simple fast and modern way using Blob and URL:
|
||||
saver(self.URL.createObjectURL(blob), true);
|
||||
}else{
|
||||
// handle non-Blob()+non-URL browsers:
|
||||
if(typeof blob === "string" || blob.constructor===z ){
|
||||
try{
|
||||
return saver( "data:" + m + ";base64," + self.btoa(blob) );
|
||||
}catch(y){
|
||||
return saver( "data:" + m + "," + encodeURIComponent(blob) );
|
||||
}
|
||||
}
|
||||
|
||||
// Blob but not URL:
|
||||
fr=new FileReader();
|
||||
fr.onload=function(e){
|
||||
saver(this.result);
|
||||
};
|
||||
fr.readAsDataURL(blob);
|
||||
}
|
||||
return true;
|
||||
} /* end download() */
|
||||
|
166
resources/ide.css
Normal file
166
resources/ide.css
Normal file
|
@ -0,0 +1,166 @@
|
|||
html, body {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: url(/images/judge0_background.png) no-repeat center center fixed;
|
||||
-webkit-background-size: cover;
|
||||
-moz-background-size: cover;
|
||||
-o-background-size: cover;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.ui[class*="left action"].input>.dropdown {
|
||||
border-radius: 0 .28571429rem .28571429rem 0;
|
||||
}
|
||||
|
||||
.ui.selection.dropdown {
|
||||
width: 205px;
|
||||
}
|
||||
|
||||
.lm_header .lm_tab {
|
||||
padding-bottom: 3px;
|
||||
height: 16px;
|
||||
font-family: "Droid Sans Mono", monospace, monospace, "Droid Sans Fallback";
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.lm_header .lm_tab.lm_active {
|
||||
box-shadow: none;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
|
||||
#site-navigation {
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
background: #1e1e1e;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
#navigation-message {
|
||||
font-size: 1.2em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@keyframes slide {
|
||||
0% { transform: translateX(570px); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
@-webkit-keyframes slide {
|
||||
0% { transform: translateX(570px); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
|
||||
.navigation-message-text {
|
||||
white-space: nowrap;
|
||||
-moz-animation: slide 60s linear infinite;
|
||||
-webkit-animation: slide 60s linear infinite;
|
||||
animation: slide 60s linear infinite;
|
||||
}
|
||||
|
||||
.navigation-message-text:hover {
|
||||
-moz-animation-play-state: paused;
|
||||
-webkit-animation-play-state: paused;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
#navigation-message a {
|
||||
color: #41a5f1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#site-icon {
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#site-header {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
#site-header h2 {
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
font-family: 'Exo 2', sans-serif;
|
||||
}
|
||||
|
||||
#site-content {
|
||||
height: calc(100% - 45px - 19px);
|
||||
}
|
||||
|
||||
#site-modal .header {
|
||||
color: #db2828;
|
||||
}
|
||||
|
||||
#site-footer {
|
||||
background-color: darkslategrey;
|
||||
bottom: 0;
|
||||
font-family: monospace, monospace, "Droid Sans Fallback";
|
||||
font-size: 13px;
|
||||
height: 19px;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#site-footer {
|
||||
color: gray;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#editor-status-line {
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
height: 19px;
|
||||
padding: 0px 16px;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
#editor-status-line input[type=text] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#editor-status-line input[type=text]::selection {
|
||||
background-color: #cce2ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation: blinker 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
background: #FFD700;
|
||||
}
|
||||
}
|
||||
|
||||
.dot {
|
||||
background: #0E6EB8;
|
||||
position: absolute;
|
||||
border-radius: 50px;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
right: 7.5px;
|
||||
top: 7.5px;
|
||||
}
|
||||
|
||||
.no-left-padding {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 205px !important;
|
||||
}
|
868
resources/ide.js
Normal file
868
resources/ide.js
Normal file
|
@ -0,0 +1,868 @@
|
|||
var wait = true;
|
||||
var check_timeout = 300;
|
||||
|
||||
var editorMode = localStorageGetItem("editorMode") || "normal";
|
||||
var redirectStderrToStdout = ((localStorageGetItem("redirectStderrToStdout") || "false") === "true");
|
||||
var editorModeObject = null;
|
||||
|
||||
var fontSize = 14;
|
||||
|
||||
var MonacoVim;
|
||||
var MonacoEmacs;
|
||||
|
||||
var layout;
|
||||
|
||||
var sourceEditor;
|
||||
var stdinEditor;
|
||||
var stdoutEditor;
|
||||
var stderrEditor;
|
||||
|
||||
var isEditorDirty = false;
|
||||
var currentLanguageId;
|
||||
|
||||
var $selectLanguage
|
||||
var $selectTheme
|
||||
var $insertTemplateBtn;
|
||||
var $runBtn;
|
||||
|
||||
var timeStart;
|
||||
var timeEnd;
|
||||
|
||||
var layoutConfig = {
|
||||
settings: {
|
||||
showPopoutIcon: false,
|
||||
reorderEnabled: true
|
||||
},
|
||||
dimensions: {
|
||||
borderWidth: 3,
|
||||
headerHeight: 22
|
||||
},
|
||||
content: [{
|
||||
type: "row",
|
||||
content: [{
|
||||
type: "component",
|
||||
componentName: "source",
|
||||
title: "SOURCE",
|
||||
isClosable: false,
|
||||
componentState: {
|
||||
readOnly: false
|
||||
},
|
||||
width: 60
|
||||
}, {
|
||||
type: "column",
|
||||
content: [{
|
||||
type: "stack",
|
||||
content: [{
|
||||
type: "component",
|
||||
componentName: "stdin",
|
||||
title: "STDIN",
|
||||
isClosable: false,
|
||||
componentState: {
|
||||
readOnly: false
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
type: "stack",
|
||||
content: [{
|
||||
type: "component",
|
||||
componentName: "stdout",
|
||||
title: "STDOUT",
|
||||
isClosable: false,
|
||||
componentState: {
|
||||
readOnly: true
|
||||
}
|
||||
}, {
|
||||
type: "component",
|
||||
componentName: "stderr",
|
||||
title: "STDERR",
|
||||
isClosable: false,
|
||||
componentState: {
|
||||
readOnly: true
|
||||
}
|
||||
},
|
||||
]
|
||||
}]
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
function encode(str) {
|
||||
return btoa(unescape(encodeURIComponent(str || "")));
|
||||
}
|
||||
|
||||
function decode(bytes) {
|
||||
var escaped = escape(atob(bytes || ""));
|
||||
try {
|
||||
return decodeURIComponent(escaped);
|
||||
} catch {
|
||||
return unescape(escaped);
|
||||
}
|
||||
}
|
||||
|
||||
function localStorageSetItem(key, value) {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
} catch (ignorable) {
|
||||
}
|
||||
}
|
||||
|
||||
function localStorageGetItem(key) {
|
||||
try {
|
||||
return localStorage.getItem(key);
|
||||
} catch (ignorable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showError(title, content) {
|
||||
$("#site-modal #title").html(title);
|
||||
$("#site-modal .content").html(content);
|
||||
$("#site-modal").modal("show");
|
||||
}
|
||||
|
||||
function handleError(jqXHR, textStatus, errorThrown) {
|
||||
showError(`${jqXHR.statusText} (${jqXHR.status})`, `<pre>${JSON.stringify(jqXHR, null, 4)}</pre>`);
|
||||
}
|
||||
|
||||
function handleRunError(jqXHR, textStatus, errorThrown) {
|
||||
handleError(jqXHR, textStatus, errorThrown);
|
||||
$runBtn.removeClass("loading");
|
||||
}
|
||||
|
||||
function handleResult(data) {
|
||||
timeEnd = performance.now();
|
||||
|
||||
var status = data.status;
|
||||
var stdout = decode(data.stdout);
|
||||
var stderr = decode(data.stderr);
|
||||
var compile_output = decode(data.compile_output);
|
||||
var time = (data.time === null ? "-" : data.time + "s");
|
||||
var memory = (data.memory === null ? "-" : data.memory + "KB");
|
||||
|
||||
stdoutEditor.setValue(compile_output + stdout + `\n[${status.description}, ${time}, ${memory}]`);
|
||||
stderrEditor.setValue(stderr);
|
||||
|
||||
if (stdout !== "") {
|
||||
var dot = document.getElementById("stdout-dot");
|
||||
if (!dot.parentElement.classList.contains("lm_active")) {
|
||||
dot.hidden = false;
|
||||
}
|
||||
}
|
||||
if (stderr !== "") {
|
||||
var dot = document.getElementById("stderr-dot");
|
||||
if (!dot.parentElement.classList.contains("lm_active")) {
|
||||
dot.hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
$runBtn.removeClass("loading");
|
||||
}
|
||||
|
||||
function getIdFromURI() {
|
||||
var uri = location.search.substr(1).trim();
|
||||
return uri.split("&")[0];
|
||||
}
|
||||
|
||||
function downloadSource() {
|
||||
var value = parseInt($selectLanguage.val());
|
||||
download(sourceEditor.getValue(), fileNames[value], "text/plain");
|
||||
}
|
||||
|
||||
function loadSavedSource() {
|
||||
snippet_id = getIdFromURI();
|
||||
|
||||
if (snippet_id.length == 36) {
|
||||
$.ajax({
|
||||
url: apiUrl + "/submissions/" + snippet_id + "?fields=source_code,language_id,stdin,stdout,stderr,compile_output,message,time,memory,status&base64_encoded=true",
|
||||
type: "GET",
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
sourceEditor.setValue(decode(data["source_code"]));
|
||||
$selectLanguage.dropdown("set selected", data["language_id"]);
|
||||
stdinEditor.setValue(decode(data["stdin"]));
|
||||
stderrEditor.setValue(decode(data["stderr"]));
|
||||
var time = (data.time === null ? "-" : data.time + "s");
|
||||
var memory = (data.memory === null ? "-" : data.memory + "KB");
|
||||
stdoutEditor.setValue(decode(data["compile_output"]) + decode(data["stdout"]) + `\n[${data.status.description}, ${time}, ${memory}]`);
|
||||
changeEditorLanguage();
|
||||
},
|
||||
error: handleRunError
|
||||
});
|
||||
} else {
|
||||
loadRandomLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
function run() {
|
||||
if (sourceEditor.getValue().trim() === "") {
|
||||
showError("Error", "Source code can't be empty!");
|
||||
return;
|
||||
} else {
|
||||
$runBtn.addClass("loading");
|
||||
}
|
||||
|
||||
document.getElementById("stdout-dot").hidden = true;
|
||||
document.getElementById("stderr-dot").hidden = true;
|
||||
|
||||
stdoutEditor.setValue("");
|
||||
stderrEditor.setValue("");
|
||||
|
||||
var sourceValue = encode(sourceEditor.getValue());
|
||||
var stdinValue = encode(stdinEditor.getValue());
|
||||
var languageId = resolveLanguageId($selectLanguage.val());
|
||||
|
||||
if (parseInt(languageId) === 44) {
|
||||
sourceValue = sourceEditor.getValue();
|
||||
}
|
||||
|
||||
var data = {
|
||||
source_code: sourceValue,
|
||||
language_id: languageId,
|
||||
stdin: stdinValue,
|
||||
redirect_stderr_to_stdout: redirectStderrToStdout
|
||||
};
|
||||
|
||||
var sendRequest = function(data) {
|
||||
timeStart = performance.now();
|
||||
$.ajax({
|
||||
url: apiUrl + `/submissions?base64_encoded=true&wait=${wait}`,
|
||||
type: "POST",
|
||||
async: true,
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify(data),
|
||||
xhrFields: {
|
||||
withCredentials: apiUrl.indexOf("/secure") != -1 ? true : false
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
console.log(data.token);
|
||||
if (wait == true) {
|
||||
handleResult(data);
|
||||
} else {
|
||||
setTimeout(fetchSubmission.bind(null, data.token), check_timeout);
|
||||
}
|
||||
},
|
||||
error: handleRunError
|
||||
});
|
||||
}
|
||||
|
||||
sendRequest(data);
|
||||
}
|
||||
|
||||
function fetchSubmission(submission_token) {
|
||||
$.ajax({
|
||||
url: apiUrl + "/submissions/" + submission_token + "?base64_encoded=true",
|
||||
type: "GET",
|
||||
async: true,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (data.status.id <= 2) { // In Queue or Processing
|
||||
setTimeout(fetchSubmission.bind(null, submission_token), check_timeout);
|
||||
return;
|
||||
}
|
||||
handleResult(data);
|
||||
},
|
||||
error: handleRunError
|
||||
});
|
||||
}
|
||||
|
||||
function changeEditorLanguage() {
|
||||
monaco.editor.setModelLanguage(sourceEditor.getModel(), $selectLanguage.find(":selected").attr("mode"));
|
||||
currentLanguageId = parseInt($selectLanguage.val());
|
||||
$(".lm_title")[0].innerText = fileNames[currentLanguageId];
|
||||
apiUrl = resolveApiUrl($selectLanguage.val());
|
||||
}
|
||||
|
||||
function insertTemplate() {
|
||||
currentLanguageId = parseInt($selectLanguage.val());
|
||||
sourceEditor.setValue(sources[currentLanguageId]);
|
||||
changeEditorLanguage();
|
||||
}
|
||||
|
||||
function loadRandomLanguage() {
|
||||
var values = [];
|
||||
for (var i = 0; i < $selectLanguage[0].options.length; ++i) {
|
||||
values.push($selectLanguage[0].options[i].value);
|
||||
}
|
||||
// $selectLanguage.dropdown("set selected", values[Math.floor(Math.random() * $selectLanguage[0].length)]);
|
||||
$selectLanguage.dropdown("set selected", values[9]);
|
||||
apiUrl = resolveApiUrl($selectLanguage.val());
|
||||
insertTemplate();
|
||||
}
|
||||
|
||||
function resizeEditor(layoutInfo) {
|
||||
if (editorMode != "normal") {
|
||||
var statusLineHeight = $("#editor-status-line").height();
|
||||
layoutInfo.height -= statusLineHeight;
|
||||
layoutInfo.contentHeight -= statusLineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function disposeEditorModeObject() {
|
||||
try {
|
||||
editorModeObject.dispose();
|
||||
editorModeObject = null;
|
||||
} catch(ignorable) {
|
||||
}
|
||||
}
|
||||
|
||||
function changeEditorMode() {
|
||||
disposeEditorModeObject();
|
||||
|
||||
if (editorMode == "vim") {
|
||||
editorModeObject = MonacoVim.initVimMode(sourceEditor, $("#editor-status-line")[0]);
|
||||
} else if (editorMode == "emacs") {
|
||||
var statusNode = $("#editor-status-line")[0];
|
||||
editorModeObject = new MonacoEmacs.EmacsExtension(sourceEditor);
|
||||
editorModeObject.onDidMarkChange(function(e) {
|
||||
statusNode.textContent = e ? "Mark Set!" : "Mark Unset";
|
||||
});
|
||||
editorModeObject.onDidChangeKey(function(str) {
|
||||
statusNode.textContent = str;
|
||||
});
|
||||
editorModeObject.start();
|
||||
}
|
||||
}
|
||||
|
||||
function resolveLanguageId(id) {
|
||||
id = parseInt(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
function resolveApiUrl(id) {
|
||||
id = parseInt(id);
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
function editorsUpdateFontSize(fontSize) {
|
||||
sourceEditor.updateOptions({fontSize: fontSize});
|
||||
stdinEditor.updateOptions({fontSize: fontSize});
|
||||
stdoutEditor.updateOptions({fontSize: fontSize});
|
||||
stderrEditor.updateOptions({fontSize: fontSize});
|
||||
}
|
||||
|
||||
function getDefaultTheme() {
|
||||
return localStorageGetItem('editor-theme') || 'vs-dark';
|
||||
}
|
||||
|
||||
function editorsUpdateTheme(isInit) {
|
||||
var theme = $selectTheme.val();
|
||||
if (isInit) {
|
||||
theme = getDefaultTheme();
|
||||
$selectTheme.val(theme).change();
|
||||
}
|
||||
else localStorageSetItem('editor-theme', theme);
|
||||
|
||||
var $siteNavigation = $("#site-navigation");
|
||||
if (theme == 'vs') {
|
||||
$siteNavigation.removeClass('inverted');
|
||||
$siteNavigation.css('background', 'white');
|
||||
}
|
||||
else {
|
||||
$("#site-navigation").addClass('inverted');
|
||||
$siteNavigation.css('background', '#1e1e1e');
|
||||
}
|
||||
sourceEditor.updateOptions({theme: theme});
|
||||
stdinEditor.updateOptions({theme: theme});
|
||||
stdoutEditor.updateOptions({theme: theme});
|
||||
stderrEditor.updateOptions({theme: theme});
|
||||
}
|
||||
|
||||
function updateScreenElements() {
|
||||
var display = window.innerWidth <= 1200 ? "none" : "";
|
||||
$(".wide.screen.only").each(function(index) {
|
||||
$(this).css("display", display);
|
||||
});
|
||||
}
|
||||
|
||||
$(window).resize(function() {
|
||||
layout.updateSize();
|
||||
updateScreenElements();
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
updateScreenElements();
|
||||
|
||||
$selectLanguage = $("#select-language");
|
||||
$selectLanguage.change(function (e) {
|
||||
if (!isEditorDirty) {
|
||||
insertTemplate();
|
||||
} else {
|
||||
changeEditorLanguage();
|
||||
}
|
||||
});
|
||||
|
||||
$selectTheme = $("#select-theme");
|
||||
$selectTheme.change(function(e) {
|
||||
editorsUpdateTheme(false);
|
||||
});
|
||||
|
||||
$insertTemplateBtn = $("#insert-template-btn");
|
||||
$insertTemplateBtn.click(function (e) {
|
||||
if (isEditorDirty && confirm("Are you sure? Your current changes will be lost.")) {
|
||||
insertTemplate();
|
||||
}
|
||||
});
|
||||
|
||||
$runBtn = $("#run-btn");
|
||||
$runBtn.click(function (e) {
|
||||
run();
|
||||
});
|
||||
|
||||
$(`input[name="editor-mode"][value="${editorMode}"]`).prop("checked", true);
|
||||
$("input[name=\"editor-mode\"]").on("change", function(e) {
|
||||
editorMode = e.target.value;
|
||||
localStorageSetItem("editorMode", editorMode);
|
||||
|
||||
resizeEditor(sourceEditor.getLayoutInfo());
|
||||
changeEditorMode();
|
||||
|
||||
sourceEditor.focus();
|
||||
});
|
||||
|
||||
$("input[name=\"redirect-output\"]").prop("checked", redirectStderrToStdout)
|
||||
$("input[name=\"redirect-output\"]").on("change", function(e) {
|
||||
redirectStderrToStdout = e.target.checked;
|
||||
localStorageSetItem("redirectStderrToStdout", redirectStderrToStdout);
|
||||
});
|
||||
|
||||
$("body").keydown(function (e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
if (keyCode == 120 || (event.ctrlKey && keyCode == 66)) { // F9 || ctrl B
|
||||
e.preventDefault();
|
||||
run();
|
||||
} else if (event.ctrlKey && (keyCode == 107 || keyCode == 187)) { // Ctrl++
|
||||
e.preventDefault();
|
||||
fontSize += 1;
|
||||
editorsUpdateFontSize(fontSize);
|
||||
} else if (event.ctrlKey && (keyCode == 107 || keyCode == 189)) { // Ctrl+-
|
||||
e.preventDefault();
|
||||
fontSize -= 1;
|
||||
editorsUpdateFontSize(fontSize);
|
||||
}
|
||||
});
|
||||
|
||||
$("select.dropdown").dropdown();
|
||||
$(".ui.dropdown").dropdown();
|
||||
$(".ui.dropdown.site-links").dropdown({action: "hide", on: "hover"});
|
||||
$(".ui.checkbox").checkbox();
|
||||
$(".message .close").on("click", function () {
|
||||
$(this).closest(".message").transition("fade");
|
||||
});
|
||||
|
||||
require(["vs/editor/editor.main", "monaco-vim", "monaco-emacs"], function (ignorable, MVim, MEmacs) {
|
||||
layout = new GoldenLayout(layoutConfig, $("#site-content"));
|
||||
|
||||
MonacoVim = MVim;
|
||||
MonacoEmacs = MEmacs;
|
||||
|
||||
layout.registerComponent("source", function (container, state) {
|
||||
sourceEditor = monaco.editor.create(container.getElement()[0], {
|
||||
automaticLayout: true,
|
||||
theme: getDefaultTheme(),
|
||||
scrollBeyondLastLine: true,
|
||||
readOnly: state.readOnly,
|
||||
language: "cpp",
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
matchBrackets: false,
|
||||
});
|
||||
|
||||
changeEditorMode();
|
||||
|
||||
sourceEditor.getModel().onDidChangeContent(function (e) {
|
||||
currentLanguageId = parseInt($selectLanguage.val());
|
||||
isEditorDirty = sourceEditor.getValue() != sources[currentLanguageId];
|
||||
});
|
||||
|
||||
sourceEditor.onDidLayoutChange(resizeEditor);
|
||||
|
||||
sourceEditor.onDidChangeCursorPosition(function(e) {
|
||||
var line = sourceEditor.getPosition().lineNumber;
|
||||
var col = sourceEditor.getPosition().column;
|
||||
$('#cursor-position').html(`Line ${line}, Column ${col}`)
|
||||
})
|
||||
});
|
||||
|
||||
layout.registerComponent("stdin", function (container, state) {
|
||||
stdinEditor = monaco.editor.create(container.getElement()[0], {
|
||||
automaticLayout: true,
|
||||
theme: getDefaultTheme(),
|
||||
scrollBeyondLastLine: false,
|
||||
readOnly: state.readOnly,
|
||||
language: "plaintext",
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: "on",
|
||||
});
|
||||
});
|
||||
|
||||
layout.registerComponent("stdout", function (container, state) {
|
||||
stdoutEditor = monaco.editor.create(container.getElement()[0], {
|
||||
automaticLayout: true,
|
||||
theme: getDefaultTheme(),
|
||||
scrollBeyondLastLine: false,
|
||||
readOnly: state.readOnly,
|
||||
language: "plaintext",
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: "on",
|
||||
});
|
||||
|
||||
container.on("tab", function(tab) {
|
||||
tab.element.append("<span id=\"stdout-dot\" class=\"dot\" hidden></span>");
|
||||
tab.element.on("mousedown", function(e) {
|
||||
e.target.closest(".lm_tab").children[3].hidden = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
layout.registerComponent("stderr", function (container, state) {
|
||||
stderrEditor = monaco.editor.create(container.getElement()[0], {
|
||||
automaticLayout: true,
|
||||
theme: getDefaultTheme(),
|
||||
scrollBeyondLastLine: false,
|
||||
readOnly: state.readOnly,
|
||||
language: "plaintext",
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: "on",
|
||||
});
|
||||
|
||||
container.on("tab", function(tab) {
|
||||
tab.element.append("<span id=\"stderr-dot\" class=\"dot\" hidden></span>");
|
||||
tab.element.on("mousedown", function(e) {
|
||||
e.target.closest(".lm_tab").children[3].hidden = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
layout.on("initialised", function () {
|
||||
$(".monaco-editor")[0].appendChild($("#editor-status-line")[0]);
|
||||
if (getIdFromURI()) {
|
||||
loadSavedSource();
|
||||
} else {
|
||||
loadRandomLanguage();
|
||||
}
|
||||
$("#site-navigation").css("border-bottom", "1px solid black");
|
||||
sourceEditor.focus();
|
||||
editorsUpdateFontSize(fontSize);
|
||||
editorsUpdateTheme(true);
|
||||
});
|
||||
|
||||
layout.init();
|
||||
});
|
||||
});
|
||||
|
||||
// Template Sources
|
||||
var assemblySource = "\
|
||||
section .text\n\
|
||||
global _start\n\
|
||||
\n\
|
||||
_start:\n\
|
||||
\n\
|
||||
xor eax, eax\n\
|
||||
lea edx, [rax+len]\n\
|
||||
mov al, 1\n\
|
||||
mov esi, msg\n\
|
||||
mov edi, eax\n\
|
||||
syscall\n\
|
||||
\n\
|
||||
xor edi, edi\n\
|
||||
lea eax, [rdi+60]\n\
|
||||
syscall\n\
|
||||
\n\
|
||||
section .rodata\n\
|
||||
\n\
|
||||
msg db 'hello, world', 0xa\n\
|
||||
len equ $ - msg\n\
|
||||
";
|
||||
|
||||
var bashSource = "echo \"hello, world\"";
|
||||
|
||||
var basicSource = "PRINT \"hello, world\"";
|
||||
|
||||
var cSource = "\
|
||||
// Powered by Judge0\n\
|
||||
#include <stdio.h>\n\
|
||||
\n\
|
||||
int main(void) {\n\
|
||||
printf(\"Hello Judge0!\\n\");\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var csharpSource = "\
|
||||
public class Hello {\n\
|
||||
public static void Main() {\n\
|
||||
System.Console.WriteLine(\"hello, world\");\n\
|
||||
}\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var cppSource = "\
|
||||
#include <iostream>\n\
|
||||
\n\
|
||||
int main() {\n\
|
||||
std::cout << \"hello, world\" << std::endl;\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var clojureSource = "(println \"hello, world\")\n";
|
||||
|
||||
var cobolSource = "\
|
||||
IDENTIFICATION DIVISION.\n\
|
||||
PROGRAM-ID. MAIN.\n\
|
||||
PROCEDURE DIVISION.\n\
|
||||
DISPLAY \"hello, world\".\n\
|
||||
STOP RUN.\n\
|
||||
";
|
||||
|
||||
var lispSource = "(write-line \"hello, world\")";
|
||||
|
||||
var dSource = "\
|
||||
import std.stdio;\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
writeln(\"hello, world\");\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var elixirSource = "IO.puts \"hello, world\"";
|
||||
|
||||
var erlangSource = "\
|
||||
main(_) ->\n\
|
||||
io:fwrite(\"hello, world\\n\").\n\
|
||||
";
|
||||
|
||||
var executableSource = "\
|
||||
Judge0 IDE assumes that content of executable is Base64 encoded.\n\
|
||||
\n\
|
||||
This means that you should Base64 encode content of your binary,\n\
|
||||
paste it here and click \"Run\".\n\
|
||||
\n\
|
||||
Here is an example of compiled \"hello, world\" NASM program.\n\
|
||||
Content of compiled binary is Base64 encoded and used as source code.\n\
|
||||
\n\
|
||||
https://ide.judge0.com/?kS_f\n\
|
||||
";
|
||||
|
||||
var fsharpSource = "printfn \"hello, world\"\n";
|
||||
|
||||
var fortranSource = "\
|
||||
program main\n\
|
||||
print *, \"hello, world\"\n\
|
||||
end\n\
|
||||
";
|
||||
|
||||
var goSource = "\
|
||||
package main\n\
|
||||
\n\
|
||||
import \"fmt\"\n\
|
||||
\n\
|
||||
func main() {\n\
|
||||
fmt.Println(\"hello, world\")\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var groovySource = "println \"hello, world\"\n";
|
||||
|
||||
var haskellSource = "main = putStrLn \"hello, world\"";
|
||||
|
||||
var javaSource = "\
|
||||
public class Main {\n\
|
||||
public static void main(String[] args) {\n\
|
||||
System.out.println(\"hello, world\");\n\
|
||||
}\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var javaScriptSource = "console.log(\"hello, world\");";
|
||||
|
||||
var kotlinSource = "\
|
||||
fun main() {\n\
|
||||
println(\"hello, world\")\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var luaSource = "print(\"hello, world\")";
|
||||
|
||||
var objectiveCSource = "\
|
||||
#import <Foundation/Foundation.h>\n\
|
||||
\n\
|
||||
int main() {\n\
|
||||
@autoreleasepool {\n\
|
||||
char name[10];\n\
|
||||
scanf(\"%s\", name);\n\
|
||||
NSString *message = [NSString stringWithFormat:@\"hello, %s\\n\", name];\n\
|
||||
printf(\"%s\", message.UTF8String);\n\
|
||||
}\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var ocamlSource = "print_endline \"hello, world\"";
|
||||
|
||||
var octaveSource = "printf(\"hello, world\\n\");";
|
||||
|
||||
var pascalSource = "\
|
||||
program Hello;\n\
|
||||
begin\n\
|
||||
writeln ('hello, world')\n\
|
||||
end.\n\
|
||||
";
|
||||
|
||||
var perlSource = "\
|
||||
my $name = <STDIN>;\n\
|
||||
print \"hello, $name\";\n\
|
||||
";
|
||||
|
||||
var phpSource = "\
|
||||
<?php\n\
|
||||
print(\"hello, world\\n\");\n\
|
||||
?>\n\
|
||||
";
|
||||
|
||||
var plainTextSource = "hello, world\n";
|
||||
|
||||
var prologSource = "\
|
||||
:- initialization(main).\n\
|
||||
main :- write('hello, world\\n').\n\
|
||||
";
|
||||
|
||||
var pythonSource = "print(\"hello, world\")";
|
||||
|
||||
var rSource = "cat(\"hello, world\\n\")";
|
||||
|
||||
var rubySource = "puts \"hello, world\"";
|
||||
|
||||
var rustSource = "\
|
||||
fn main() {\n\
|
||||
println!(\"hello, world\");\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var scalaSource = "\
|
||||
object Main {\n\
|
||||
def main(args: Array[String]) = {\n\
|
||||
val name = scala.io.StdIn.readLine()\n\
|
||||
println(\"hello, \"+ name)\n\
|
||||
}\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
var swiftSource = "\
|
||||
import Foundation\n\
|
||||
let name = readLine()\n\
|
||||
print(\"hello, \\(name!)\")\n\
|
||||
";
|
||||
|
||||
var typescriptSource = "console.log(\"hello, world\");";
|
||||
|
||||
var vbSource = "\
|
||||
Public Module Program\n\
|
||||
Public Sub Main()\n\
|
||||
Console.WriteLine(\"hello, world\")\n\
|
||||
End Sub\n\
|
||||
End Module\n\
|
||||
";
|
||||
|
||||
var sources = {
|
||||
45: assemblySource,
|
||||
46: bashSource,
|
||||
47: basicSource,
|
||||
48: cSource,
|
||||
49: cSource,
|
||||
50: cSource,
|
||||
51: csharpSource,
|
||||
52: cppSource,
|
||||
53: cppSource,
|
||||
54: cppSource,
|
||||
55: lispSource,
|
||||
56: dSource,
|
||||
57: elixirSource,
|
||||
58: erlangSource,
|
||||
44: executableSource,
|
||||
59: fortranSource,
|
||||
60: goSource,
|
||||
61: haskellSource,
|
||||
62: javaSource,
|
||||
63: javaScriptSource,
|
||||
64: luaSource,
|
||||
65: ocamlSource,
|
||||
66: octaveSource,
|
||||
67: pascalSource,
|
||||
68: phpSource,
|
||||
43: plainTextSource,
|
||||
69: prologSource,
|
||||
70: pythonSource,
|
||||
71: pythonSource,
|
||||
72: rubySource,
|
||||
73: rustSource,
|
||||
74: typescriptSource,
|
||||
75: cSource,
|
||||
76: cppSource,
|
||||
77: cobolSource,
|
||||
78: kotlinSource,
|
||||
79: objectiveCSource,
|
||||
80: rSource,
|
||||
81: scalaSource,
|
||||
83: swiftSource,
|
||||
84: vbSource,
|
||||
85: perlSource,
|
||||
86: clojureSource,
|
||||
87: fsharpSource,
|
||||
88: groovySource,
|
||||
};
|
||||
|
||||
var fileNames = {
|
||||
45: "main.asm",
|
||||
46: "script.sh",
|
||||
47: "main.bas",
|
||||
48: "main.c",
|
||||
49: "main.c",
|
||||
50: "main.c",
|
||||
51: "Main.cs",
|
||||
52: "main.cpp",
|
||||
53: "main.cpp",
|
||||
54: "main.cpp",
|
||||
55: "script.lisp",
|
||||
56: "main.d",
|
||||
57: "script.exs",
|
||||
58: "main.erl",
|
||||
44: "a.out",
|
||||
59: "main.f90",
|
||||
60: "main.go",
|
||||
61: "main.hs",
|
||||
62: "Main.java",
|
||||
63: "script.js",
|
||||
64: "script.lua",
|
||||
65: "main.ml",
|
||||
66: "script.m",
|
||||
67: "main.pas",
|
||||
68: "script.php",
|
||||
43: "text.txt",
|
||||
69: "main.pro",
|
||||
70: "script.py",
|
||||
71: "script.py",
|
||||
72: "script.rb",
|
||||
73: "main.rs",
|
||||
74: "script.ts",
|
||||
75: "main.c",
|
||||
76: "main.cpp",
|
||||
77: "main.cob",
|
||||
78: "Main.kt",
|
||||
79: "main.m",
|
||||
80: "script.r",
|
||||
81: "Main.scala",
|
||||
83: "Main.swift",
|
||||
84: "Main.vb",
|
||||
85: "script.pl",
|
||||
86: "main.clj",
|
||||
87: "script.fsx",
|
||||
88: "script.groovy",
|
||||
};
|
227
templates/ide.html
Normal file
227
templates/ide.html
Normal file
|
@ -0,0 +1,227 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- Favicons-->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#FFBB33">
|
||||
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
|
||||
{# Chrome 39 for Android colour #}
|
||||
<meta name="theme-color" content="#FFBB33">
|
||||
{% if og_image %}
|
||||
<meta property="og:image" content="{{ request.build_absolute_uri(og_image) }}">
|
||||
{% endif %}
|
||||
{% block og_title %}{% endblock %}
|
||||
<meta property="og:site_name" content="{{ SITE_LONG_NAME }}">
|
||||
<meta property="og:url"
|
||||
content="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||
{% if meta_description %}
|
||||
<meta property="og:description" content="{{ meta_description }}">
|
||||
{% endif %}
|
||||
|
||||
<meta property="og:title" content="IDE">
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/goldenlayout.min.js" integrity="sha256-NhJAZDfGgv4PiB+GVlSrPdh3uc75XXYSM4su8hgTchI=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-base.css" integrity="sha256-oIDR18yKFZtfjCJfDsJYpTBv1S9QmxYopeqw2dO96xM=" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-dark-theme.css" integrity="sha256-ygw8PvSDJJUGLf6Q9KIQsYR3mOmiQNlDaxMLDOx9xL0=" crossorigin="anonymous" />
|
||||
|
||||
<script>
|
||||
var require = {
|
||||
paths: {
|
||||
"vs": "https://unpkg.com/monaco-editor/min/vs",
|
||||
"monaco-vim": "https://unpkg.com/monaco-vim/dist/monaco-vim",
|
||||
"monaco-emacs": "https://unpkg.com/monaco-emacs/dist/monaco-emacs"
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="https://unpkg.com/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="https://unpkg.com/monaco-editor@0.23.0/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script src="https://unpkg.com/monaco-editor@0.23.0/min/vs/editor/editor.main.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha256-t8GepnyPmw9t+foMh3mKNvcorqNHamSKtKRxxpUEgFI=" crossorigin="anonymous"></script>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Exo+2" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="{{ static('download.js') }}"></script>
|
||||
|
||||
<script type="text/javascript" src="{{ static('ide.js') }}"></script>
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="{{ static('ide.css') }}">
|
||||
|
||||
<title>IDE</title>
|
||||
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
window.apiUrl = "{{ url('ide_api') }}";
|
||||
$(window).on('beforeunload', function(e) {
|
||||
return "T";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="site-navigation" class="ui small inverted menu">
|
||||
<div id="site-header" class="header item">
|
||||
<a href="/">
|
||||
<img id="site-icon" src="{{ static('icons/logo.png') }}">
|
||||
</a>
|
||||
</div>
|
||||
<div class="left menu">
|
||||
<div class="ui dropdown item site-links on-hover">
|
||||
File <i class="dropdown icon"></i>
|
||||
<div class="menu">
|
||||
<a class="item" target="_blank" href="/"><i class="file code icon"></i>{{ _('New File') }}</a>
|
||||
<div class="item" onclick="downloadSource()"><i class="download icon"></i>{{ _('Download') }}</div>
|
||||
<div id="insert-template-btn" class="item"><i class="file code outline icon"></i>{{ _('Insert template
|
||||
for current language') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="link item" onclick="$('#site-settings').modal('show')"><i class="cog icon"></i> Settings</div>
|
||||
<div class="item borderless">
|
||||
<select id="select-language" class="ui dropdown">
|
||||
<option value="45" mode="UNKNOWN">Assembly (NASM 2.14.02)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="46" mode="shell">Bash (5.0.0)</option>
|
||||
<option value="47" mode="UNKNOWN">Basic (FBC 1.07.1)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="75" mode="c">C (Clang 7.0.1)</option>
|
||||
<option value="48" mode="c">C (GCC 7.4.0)</option>
|
||||
<option value="49" mode="c">C (GCC 8.3.0)</option>
|
||||
<option value="50" mode="c">C (GCC 9.2.0)</option>
|
||||
<option value="51" mode="csharp">C# (Mono 6.6.0.161)</option>
|
||||
<option value="76" mode="cpp">C++ (Clang 7.0.1)</option>
|
||||
<option value="52" mode="cpp">C++ (GCC 7.4.0)</option>
|
||||
<option value="53" mode="cpp">C++ (GCC 8.3.0)</option>
|
||||
<option value="54" mode="cpp">C++ (GCC 9.2.0)</option>
|
||||
<option value="86" mode="clojure">Clojure (1.10.1)</option>
|
||||
<option value="77" mode="UNKNOWN">COBOL (GnuCOBOL 2.2)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="55" mode="UNKNOWN">Common Lisp (SBCL 2.0.0)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="56" mode="UNKNOWN">D (DMD 2.089.1)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="57" mode="UNKNOWN">Elixir (1.9.4)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="58" mode="UNKNOWN">Erlang (OTP 22.2)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="44" mode="plaintext">Executable</option>
|
||||
<option value="87" mode="fsharp">F# (.NET Core SDK 3.1.202)</option>
|
||||
<option value="59" mode="UNKNOWN">Fortran (GFortran 9.2.0)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="60" mode="go">Go (1.13.5)</option>
|
||||
<option value="88" mode="UNKNOWN">Groovy (3.0.3)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="61" mode="UNKNOWN">Haskell (GHC 8.8.1)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="62" mode="java">Java (OpenJDK 13.0.1)</option>
|
||||
<option value="63" mode="javascript">JavaScript (Node.js 12.14.0)</option>
|
||||
<option value="78" mode="kotlin">Kotlin (1.3.70)</option>
|
||||
<option value="64" mode="lua">Lua (5.3.5)</option>
|
||||
<option value="79" mode="objective-c">Objective-C (Clang 7.0.1)</option>
|
||||
<option value="65" mode="UNKNOWN">OCaml (4.09.0)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="66" mode="UNKNOWN">Octave (5.1.0)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="67" mode="pascal">Pascal (FPC 3.0.4)</option>
|
||||
<option value="85" mode="perl">Perl (5.28.1)</option>
|
||||
<option value="68" mode="php">PHP (7.4.1)</option>
|
||||
<option value="43" mode="plaintext">Plain Text</option>
|
||||
<option value="69" mode="UNKNOWN">Prolog (GNU Prolog 1.4.5)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="70" mode="python">Python (2.7.17)</option>
|
||||
<option value="71" mode="python">Python (3.8.1)</option>
|
||||
<option value="80" mode="r">R (4.0.0)</option>
|
||||
<option value="72" mode="ruby">Ruby (2.7.0)</option>
|
||||
<option value="73" mode="rust">Rust (1.40.0)</option>
|
||||
<option value="81" mode="UNKNOWN">Scala (2.13.2)</option> <!-- Unknown mode. Help needed. -->
|
||||
<option value="83" mode="swift">Swift (5.2.3)</option>
|
||||
<option value="74" mode="typescript">TypeScript (3.7.4)</option>
|
||||
<option value="84" mode="vb">Visual Basic.Net (vbnc 0.0.0.5943)</option> <!-- (vbnc 0.0.0.5943) -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="item no-left-padding borderless">
|
||||
<button id="run-btn" class="ui primary labeled icon button"><i class="play icon"></i>Run (F9)</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="site-content"></div>
|
||||
|
||||
<div id="site-modal" class="ui modal">
|
||||
<div class="header">
|
||||
<i class="close icon"></i>
|
||||
<span id="title"></span>
|
||||
</div>
|
||||
<div class="scrolling content"></div>
|
||||
<div class="actions">
|
||||
<div class="ui small labeled icon cancel button">
|
||||
<i class="remove icon"></i>
|
||||
Close (ESC)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="site-settings" class="ui modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
<i class="cog icon"></i>
|
||||
Settings
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="ui form">
|
||||
<div class="inline fields">
|
||||
<label>Editor Mode</label>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="editor-mode" value="normal" checked="checked">
|
||||
<label>Normal</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="editor-mode" value="vim">
|
||||
<label>Vim</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui radio checkbox">
|
||||
<input type="radio" name="editor-mode" value="emacs">
|
||||
<label>Emacs</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="redirect-output">
|
||||
<label>Redirect stderr to stdout</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline field">
|
||||
<label>{{ _('Editor Theme') }}</label>
|
||||
<select id="select-theme" class="ui dropdown">
|
||||
<option value="vs">VS Light</option>
|
||||
<option value="vs-dark">VS Dark</option>
|
||||
<option value="hc-black">HC Black</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="site-footer">
|
||||
<div id="editor-status-line"></div>
|
||||
<span id="cursor-position"></span>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue