Initial IDE

This commit is contained in:
cuom1999 2022-02-20 19:33:35 -06:00
parent ed6e79fdf0
commit c4a91ccf0f
6 changed files with 1428 additions and 1 deletions

View file

@ -18,7 +18,7 @@ from judge.feed import AtomBlogFeed, AtomCommentFeed, AtomProblemFeed, BlogFeed,
from judge.forms import CustomAuthenticationForm from judge.forms import CustomAuthenticationForm
from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \ from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \
SolutionSitemap, UrlSitemap, UserSitemap 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, \ notification, organization, preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, \
ticket, totp, user, widgets ticket, totp, user, widgets
from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \ 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'submit/$', user.import_users_submit, name='import_users_submit'),
url(r'sample/$', user.sample_import_users, name='import_users_sample') 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', favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png',

29
judge/views/ide.py Normal file
View 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
View 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
View 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
View 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
View 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>