算法评测平台前端。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

393 lines
18 KiB

<% include util %>
<%
if (typeof contest === 'undefined') contest = null;
if (contest) {
this.title = this.alpha(pid) + '. ' + syzoj.utils.removeTitleTag(problem.title) + ' - ' + contest.title + ' - 比赛';
} else {
this.title = problem.title + ' - 题目';
}
%>
<% include header %>
<style>
#languages-menu::-webkit-scrollbar, #testcase-menu::-webkit-scrollbar {
width: 0px;
background: transparent;
}
#languages-menu .item::after, #testcase-menu .item::after {
display: none;
}
</style>
<% include monaco-editor %>
<div class="ui center aligned grid">
<div class="row">
<h1 class="ui header">
<% if (contest) { %>
<%= this.alpha(pid) %>. <%= syzoj.utils.removeTitleTag(problem.title) %>
<% } else { %>
#<%= problem.id %>. <%= problem.title %><% if (problem.allowedEdit && !problem.is_public) { %><span class="ui tiny red label">未公开</span><% } %>
<% } %>
</h1>
</div>
<% if (problem.type !== 'submit-answer') { %>
<div class="row" style="margin-top: -15px">
<span class="ui label">内存限制:<%= problem.memory_limit %> MiB</span>
<span class="ui label">时间限制:<%= problem.time_limit %> ms</span>
<% if (problem.type === 'interaction') { %>
<span class="ui label">题目类型:交互</span>
<% } else if (problem.file_io) { %>
<span class="ui label">输入文件:<%= problem.file_io_input_name %></span>
<span class="ui label">输出文件:<%= problem.file_io_output_name %></span>
<% } else { %>
<span class="ui label">标准输入输出</span>
<% } %>
</div>
<% } %>
<% if (problem.type !== 'interaction') { %>
<div class="row" style="margin-top: -<%= problem.type === 'submit-answer' ? 15 : 23 %>px">
<span class="ui label">题目类型:<%= { 'submit-answer': '答案提交', 'interaction': '交互', 'traditional': '传统' }[problem.type] %></span>
<span class="ui label">评测方式:<%= (testcases && !testcases.error) ? (testcases.spj ? 'Special Judge' : '文本比较') : '无测试数据' %></span>
</div>
<% } %>
<% if (!contest) { %>
<div class="row" style="margin-top: -23px">
<span class="ui label">上传者:
<% if (problem.is_anonymous && !problem.allowedManage) { %>
匿名
<% } else { %>
<a href="<%= syzoj.utils.makeUrl(['user', problem.user_id]) %>"><%= problem.user.username %></a>
<% } %>
</span>
<% if (problem.allowedManage) { %>
<span class="ui label">公开者:
<% if (problem.publicizer) { %>
<a href="<%= syzoj.utils.makeUrl(['user', problem.publicizer_id]) %>"><%= problem.publicizer.username %></a>
<% } else { %>
未知
<% } %>
</span>
<% } %>
</div>
<% } %>
</div>
<div class="ui grid">
<div class="row">
<div class="column">
<div class="ui buttons">
<% if (typeof contest !== 'undefined' && contest) { %>
<% if (!contest.ended) { %>
<a class="small ui primary button" href="#submit_code">提交</a>
<% } else { %>
<a class="small ui primary button" href="<%= syzoj.utils.makeUrl(['problem', problem.id]) %>">转到题库</a>
<% } %>
<a class="small ui positive button" href="<%= syzoj.utils.makeUrl(['contest', contest.id, 'submissions'], { problem_id: pid }) %>">提交记录</a>
<% if (problem.additional_file) { %>
<a class="small ui teal button" href="<%= syzoj.utils.makeUrl(['contest', contest.id, pid, 'download', 'additional_file']) %>">附加文件</a>
<% } %>
<a href="<%= syzoj.utils.makeUrl(['contest', contest.id]) %>" class="ui orange button">返回比赛</a>
<% } else { %>
<% if (testcases && !testcases.error) { %>
<a class="small ui primary button" href="#submit_code">提交</a>
<% } %>
<a class="small ui positive button" href="<%= syzoj.utils.makeUrl(['submissions'], { problem_id: problem.id }) %>">提交记录</a>
<a class="small ui orange button" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'statistics', problem.type === 'submit-answer' ? 'shortest' : 'fastest']) %>">统计</a>
<a class="small ui yellow button" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'testdata']) %>">测试数据</a>
<% if (problem.additional_file) { %>
<a class="small ui teal button" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'download', 'additional_file']) %>">附加文件</a>
<% } %>
<a class="small ui brown button" href="<%= syzoj.utils.makeUrl(['discussion', 'problem', problem.id]) %>" style="position: relative; ">
讨论
<% if (discussionCount) { %>
<div class="floating ui red tiny circular label" style="background-color: #8c5633 !important; top: -0.6em; "><%= discussionCount %></div>
<% } %>
</a>
<% } %>
</div>
<% if (!contest) { %>
<div class="ui buttons right floated">
<% if (problem.allowedEdit) { %>
<a class="small ui button" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'edit']) %>">编辑</a>
<a class="small ui button" href="<%= syzoj.utils.makeUrl(['problem', problem.id, 'manage']) %>">管理</a>
<% } %>
<% if (problem.allowedManage) { %>
<% if (problem.is_public) { %>
<a class="small ui button" id="dis_public" href-post="<%= syzoj.utils.makeUrl(['problem', problem.id, 'dis_public']) %>">取消公开</a>
<% } else { %>
<a class="small ui button" id="public" href-post="<%= syzoj.utils.makeUrl(['problem', problem.id, 'public']) %>">公开</a>
<% } %>
<div class="ui basic modal" id="modal-delete">
<div class="ui icon header">
<i class="trash icon"></i>
<p style="margin-top: 15px; ">删除题目</p>
</div>
<div class="content" style="text-align: center; ">
<p>确认删除此题目吗?提交记录、讨论以及测试数据将一并删除。<br>
删除题目导致的修改用户提交、通过数量可能会耗费一些时间。</p>
<b>警告:删除比赛中的题目会导致系统错乱!请确认没有比赛使用此题目。</b>
</div>
<div class="actions">
<div class="ui red basic cancel inverted button">
<i class="remove icon"></i>
</div>
<a class="ui green ok inverted button" href-post="<%= syzoj.utils.makeUrl(['problem', problem.id, 'delete']) %>">
<i class="checkmark icon"></i>
</a>
</div>
</div>
<div class="small ui red button" onclick="$('#modal-delete').modal('show')">删除</div>
<% } %>
</div>
<% } %>
</div>
</div>
<% if (problem.description) { %>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">题目描述</h4>
<div class="ui bottom attached segment font-content"><%- problem.description %></div>
</div>
</div>
<% } %>
<% if (problem.input_format) { %>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">输入格式</h4>
<div class="ui bottom attached segment font-content"><%- problem.input_format %></div>
</div>
</div>
<% } %>
<% if (problem.output_format) { %>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">输出格式</h4>
<div class="ui bottom attached segment font-content"><%- problem.output_format %></div>
</div>
</div>
<% } %>
<% if (problem.example) { %>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">样例</h4>
<div class="ui bottom attached segment font-content"><%- problem.example %></div>
</div>
</div>
<% } %>
<% if (problem.limit_and_hint) { %>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">数据范围与提示</h4>
<div class="ui bottom attached segment font-content"><%- problem.limit_and_hint %></div>
</div>
</div>
<% } %>
<% if (problem.tags && problem.tags.length && (typeof contest === 'undefined' || !contest)) { %>
<div class="row">
<div class="column">
<h4 class="ui block header" id="show_tag_title_div" style="margin-bottom: 0; margin-left: -1px; margin-right: -1px; "><a href="#" id="show_tag_button" style="color: #000; ">显示分类标签</a></h4>
<div class="ui bottom attached segment" style="display: none; " id="show_tag_div">
<% for (let tag of problem.tags) { %>
<a href="<%= syzoj.utils.makeUrl(['problems', 'tag', tag.id]) %>" class="ui medium <%= tag.color %> label">
<%= tag.name %>
</a>
<% } %>
</div>
</div>
</div>
<script>
$(function () {
$('#show_tag_button').click(function (e) {
e.preventDefault();
$('#show_tag_title_div').addClass('top');
$('#show_tag_title_div').addClass('top attached');
$('#show_tag_title_div').text('分类标签');
$('#show_tag_div').css('display', '');
})
});
</script>
<% } %>
<% let noSubmit = false; %>
<%
if (typeof contest !== 'undefined' && contest && contest.ended || (!testcases || testcases.error)) {
noSubmit = true;
}
%>
<% if (!noSubmit) { %>
<div class="row">
<div class="column">
<%
const formUrl = syzoj.utils.makeUrl(['problem', 'practice', problem.id, cid, 'submit']);
%>
<form action="<%= formUrl %>" method="post" onsubmit="return submit_code()" id="submit_code" enctype="multipart/form-data">
<% if (problem.type === 'submit-answer') { %>
<%
let cases = [];
if (testcases && !testcases.error) {
for (let subtasks of testcases) {
for (let testcase of subtasks.cases) {
cases.push(testcase.answer);
}
}
}
%>
<script>
var cases = <%- serializejs(cases) %>, currCase = 0;
</script>
<div class="ui grid">
<% if (testcases) { %>
<div class="four wide column" style="margin-right: -25px; ">
<div class="ui attached vertical fluid pointing menu" id="testcase-menu" style="height: 370px; overflow-y: scroll; overflow-x: hidden; ">
<% for (let i = 0; i < cases.length; i++) { %>
<a style="border-radius: 0; " class="item<%= i === 0 ? ' active' : '' %>" data-value="<%= i %>">
<%= cases[i] %>
</a>
<% } %>
</div>
</div>
<div class="twelve wide stretched column" style="position: relative; padding-left: 0; margin-left: calc(-1rem - 1px); width: calc(75% + 1rem + 13px) !important; ">
<% for (let i = 0; i < cases.length; i++) { %>
<div id="editor-<%= i %>" class="editor" style="position: absolute; width: 100%; height: calc(100% - 28px); border: 1px solid #D4D4D5; overflow: hidden; <%= i === 0 ? '' : 'visibility: hidden; ' %>">
<%- this.showLoadingEditor(); %>
</div>
<% } %>
</div>
<% } %>
<input id="answer_by_editor" name="answer_by_editor" type="hidden">
<script>
window.onEditorLoaded(function () {
window.editors = [];
for (var i = 0; i < cases.length; i++) {
var editor = window.createCodeEditor(document.getElementById("editor-" + i));
editors[i] = editor;
}
$(function () {
$('#testcase-menu .item').click(function() {
$(this)
.addClass('active')
.closest('.ui.menu')
.find('.item')
.not($(this))
.removeClass('active')
;
var x = $(this).attr('data-value');
if (currCase != x) {
$('#editor-' + currCase).css('visibility', 'hidden');
$('#editor-' + x).css('visibility', 'visible');
currCase = x;
}
});
});
});
</script>
<div class="ui form" style="width: 100%; ">
<div class="inline fields" style="width: 100%; ">
<div class="field" style="margin: 0 auto; ">
<label for="answer">或者,上传答案(请使用 ZIP 格式压缩)</label>
<input type="file" id="answer" name="answer">
</div>
</div>
</div>
</div>
<div class="ui center aligned vertical segment" style="padding-bottom: 0; "><button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button></div>
<% } else { %>
<input name="language" type="hidden" id="form">
<input name="code" type="hidden">
<div class="ui grid">
<div class="four wide column" style="margin-right: -25px; ">
<div class="ui attached vertical fluid pointing menu" id="languages-menu" style="height: 370px; overflow-y: scroll; overflow-x: hidden; ">
<%
let language = syzoj.config.enabled_languages[0];
if (state) {
language = state.language;
} else if (lastLanguage) language = lastLanguage;
%>
<% for (lang of syzoj.config.enabled_languages) { %>
<a style="border-radius: 0; " class="item<%= lang === language ? ' active' : '' %>" data-value="<%= lang %>" data-mode="<%= syzoj.languages[lang].editor %>">
<%= syzoj.languages[lang].show %>
<div class="ui right floated" style="opacity: 0.4; margin-top: 8px; font-size: 0.7em; "><%= syzoj.languages[lang].version %></div>
</a>
<% } %>
</div>
</div>
<div class="twelve wide stretched column" style="position: relative; padding-left: 0; margin-left: calc(-1rem - 1px); width: calc(75% + 1rem + 13px) !important; ">
<div id="editor" style="position: absolute; width: 100%; height: calc(100% - 28px); border: 1px solid #D4D4D5; overflow: hidden; " class="editor">
<%- this.showLoadingEditor(); %>
</div>
</div>
<div class="ui form" style="width: 100%; ">
<div class="inline fields" style="width: 100%; ">
<div class="field" style="margin: 0 auto; ">
<label for="answer">或者,上传代码文件</label>
<input type="file" id="answer" name="answer">
</div>
</div>
</div>
</div>
<div class="ui center aligned vertical segment" style="padding-bottom: 0; ">
<button type="submit" class="ui labeled icon button"><i class="ui edit icon"></i>提交</button>
</div>
<% } %>
</form>
</div>
</div>
<% } %>
</div>
<% if (problem.type !== 'submit-answer') { %>
<script type="text/javascript">
var editor;
window.onEditorLoaded(function () {
var editorElement = document.getElementById('editor');
var content = '';
<% if (state) { %>content = <%- serializejs(state.code) %>;<% } %>
editor = window.createCodeEditor(editorElement, $('#languages-menu .item.active').data('mode'), content);
window.editor = editor;
});
var lastSubmitted = '';
function submit_code() {
if (!$('#submit_code input[name=answer]').val().trim() && !editor.getValue().trim()) return false;
$('#submit_code input[name=language]').val($('#languages-menu .item.active').data('value'));
lastSubmitted = editor.getValue();
$('#submit_code input[name=code]').val(editor.getValue());
return true;
}
$('#languages-menu')[0].scrollTop = $('#languages-menu .active')[0].offsetTop - $('#languages-menu')[0].firstElementChild.offsetTop;
$(function () {
$('#languages-menu .item').click(function() {
$(this)
.addClass('active')
.closest('.ui.menu')
.find('.item')
.not($(this))
.removeClass('active')
;
monaco.editor.setModelLanguage(editor.getModel(), $(this).data('mode'));
});
});
</script>
<% } else { %>
<script>
function submit_code() {
var a = [];
for (var i = 0; i < cases.length; i++) {
a.push({
filename: cases[i],
data: editors[i].getValue()
});
}
$('#answer_by_editor').val(JSON.stringify(a));
}
</script>
<% } %>
<% include footer %>