From 7fa4a58abec9d977b722c111215f682e1136581f Mon Sep 17 00:00:00 2001
From: masnn
Date: Fri, 3 Apr 2020 18:52:20 +0800
Subject: [PATCH] templates
---
templates/about.html | 137 +++++++++++
templates/ac_mail.html | 10 +
templates/bsod.html | 28 +++
templates/components/comments.html | 37 +++
templates/components/comments_base.html | 46 ++++
templates/components/comments_discussion.html | 63 +++++
templates/components/comments_solution.html | 96 ++++++++
templates/components/contest.html | 8 +
templates/components/form.html | 201 +++++++++++++++
templates/components/home.html | 17 ++
templates/components/homework.html | 8 +
templates/components/md_hint.html | 29 +++
templates/components/noscript_note.html | 7 +
templates/components/nothing.html | 6 +
templates/components/paginator.html | 25 ++
templates/components/problem.html | 40 +++
templates/components/record.html | 15 ++
templates/components/sidemenu.html | 15 ++
templates/components/user.html | 26 ++
templates/contest_detail.html | 81 ++++++
templates/contest_edit.html | 41 ++++
templates/contest_main.html | 132 ++++++++++
templates/contest_scoreboard.html | 58 +++++
.../contest_scoreboard_download_html.html | 48 ++++
templates/discussion_create.html | 29 +++
templates/discussion_detail.html | 131 ++++++++++
templates/discussion_edit.html | 31 +++
templates/discussion_main_or_node.html | 44 ++++
templates/discussion_nodes_widget.html | 17 ++
templates/domain_base.html | 40 +++
templates/domain_join.html | 26 ++
templates/domain_main.html | 205 ++++++++++++++++
templates/domain_manage_dashboard.html | 22 ++
templates/domain_manage_discussion.html | 22 ++
templates/domain_manage_edit.html | 21 ++
.../domain_manage_join_applications.html | 60 +++++
templates/domain_manage_permission.html | 60 +++++
templates/domain_manage_role.html | 90 +++++++
templates/domain_manage_user.html | 101 ++++++++
templates/error.html | 22 ++
templates/fs_upload.html | 23 ++
templates/home_domain.html | 99 ++++++++
templates/home_domain_create.html | 36 +++
templates/home_file.html | 44 ++++
templates/home_messages.html | 24 ++
templates/home_security.html | 99 ++++++++
templates/home_settings.html | 69 ++++++
templates/homework_detail.html | 78 ++++++
templates/homework_edit.html | 48 ++++
templates/homework_main.html | 68 ++++++
templates/judge_playground.html | 6 +
templates/layout/basic.html | 19 ++
templates/layout/home_base.html | 13 +
templates/layout/html5.html | 46 ++++
templates/layout/immersive.html | 24 ++
templates/layout/mail.html | 30 +++
templates/layout/simple.html | 4 +
templates/layout/wiki_base.html | 16 ++
templates/partials/contest_sidebar.html | 108 ++++++++
templates/partials/discussion_edit_form.html | 6 +
templates/partials/discussion_list.html | 46 ++++
templates/partials/domain_edit_form.html | 9 +
templates/partials/footer.html | 74 ++++++
templates/partials/hamburger.html | 7 +
templates/partials/header.html | 11 +
templates/partials/header_mobile.html | 17 ++
.../homework_default_penalty_rules.yaml | 6 +
templates/partials/homework_sidebar.html | 85 +++++++
templates/partials/login_dialog.html | 45 ++++
templates/partials/nav.html | 97 ++++++++
templates/partials/path.html | 19 ++
templates/partials/problem_default.md | 99 ++++++++
templates/partials/problem_list.html | 69 ++++++
templates/partials/problem_lucky.html | 8 +
templates/partials/problem_sidebar.html | 15 ++
.../partials/problem_sidebar_contest.html | 42 ++++
.../partials/problem_sidebar_homework.html | 42 ++++
.../partials/problem_sidebar_normal.html | 192 +++++++++++++++
templates/partials/problem_stat.html | 3 +
templates/partials/training_default.json | 14 ++
templates/problem_copy.html | 63 +++++
templates/problem_detail.html | 94 +++++++
templates/problem_edit.html | 70 ++++++
templates/problem_main.html | 85 +++++++
templates/problem_settings.html | 73 ++++++
templates/problem_solution.html | 49 ++++
templates/problem_statistics.html | 20 ++
templates/problem_submit.html | 64 +++++
templates/problem_submit_tr.html | 18 ++
templates/problem_upload.html | 17 ++
templates/record_detail.html | 112 +++++++++
templates/record_detail_status.html | 57 +++++
templates/record_detail_summary.html | 10 +
templates/record_main.html | 110 +++++++++
templates/record_main_tr.html | 37 +++
templates/training_detail.html | 205 ++++++++++++++++
templates/training_edit.html | 58 +++++
templates/training_main.html | 98 ++++++++
templates/user_changemail_mail.html | 6 +
templates/user_changemail_mail_sent.html | 9 +
templates/user_detail.html | 231 ++++++++++++++++++
templates/user_login.html | 37 +++
templates/user_logout.html | 14 ++
templates/user_lostpass.html | 21 ++
templates/user_lostpass_mail.html | 6 +
templates/user_lostpass_mail_sent.html | 9 +
templates/user_lostpass_with_code.html | 29 +++
templates/user_register.html | 21 ++
templates/user_register_mail.html | 6 +
templates/user_register_mail_sent.html | 9 +
templates/user_register_with_code.html | 35 +++
templates/wiki_help.html | 198 +++++++++++++++
112 files changed, 5726 insertions(+)
create mode 100644 templates/about.html
create mode 100644 templates/ac_mail.html
create mode 100644 templates/bsod.html
create mode 100644 templates/components/comments.html
create mode 100644 templates/components/comments_base.html
create mode 100644 templates/components/comments_discussion.html
create mode 100644 templates/components/comments_solution.html
create mode 100644 templates/components/contest.html
create mode 100644 templates/components/form.html
create mode 100644 templates/components/home.html
create mode 100644 templates/components/homework.html
create mode 100644 templates/components/md_hint.html
create mode 100644 templates/components/noscript_note.html
create mode 100644 templates/components/nothing.html
create mode 100644 templates/components/paginator.html
create mode 100644 templates/components/problem.html
create mode 100644 templates/components/record.html
create mode 100644 templates/components/sidemenu.html
create mode 100644 templates/components/user.html
create mode 100644 templates/contest_detail.html
create mode 100644 templates/contest_edit.html
create mode 100644 templates/contest_main.html
create mode 100644 templates/contest_scoreboard.html
create mode 100644 templates/contest_scoreboard_download_html.html
create mode 100644 templates/discussion_create.html
create mode 100644 templates/discussion_detail.html
create mode 100644 templates/discussion_edit.html
create mode 100644 templates/discussion_main_or_node.html
create mode 100644 templates/discussion_nodes_widget.html
create mode 100644 templates/domain_base.html
create mode 100644 templates/domain_join.html
create mode 100644 templates/domain_main.html
create mode 100644 templates/domain_manage_dashboard.html
create mode 100644 templates/domain_manage_discussion.html
create mode 100644 templates/domain_manage_edit.html
create mode 100644 templates/domain_manage_join_applications.html
create mode 100644 templates/domain_manage_permission.html
create mode 100644 templates/domain_manage_role.html
create mode 100644 templates/domain_manage_user.html
create mode 100644 templates/error.html
create mode 100644 templates/fs_upload.html
create mode 100644 templates/home_domain.html
create mode 100644 templates/home_domain_create.html
create mode 100644 templates/home_file.html
create mode 100644 templates/home_messages.html
create mode 100644 templates/home_security.html
create mode 100644 templates/home_settings.html
create mode 100644 templates/homework_detail.html
create mode 100644 templates/homework_edit.html
create mode 100644 templates/homework_main.html
create mode 100644 templates/judge_playground.html
create mode 100644 templates/layout/basic.html
create mode 100644 templates/layout/home_base.html
create mode 100644 templates/layout/html5.html
create mode 100644 templates/layout/immersive.html
create mode 100644 templates/layout/mail.html
create mode 100644 templates/layout/simple.html
create mode 100644 templates/layout/wiki_base.html
create mode 100644 templates/partials/contest_sidebar.html
create mode 100644 templates/partials/discussion_edit_form.html
create mode 100644 templates/partials/discussion_list.html
create mode 100644 templates/partials/domain_edit_form.html
create mode 100644 templates/partials/footer.html
create mode 100644 templates/partials/hamburger.html
create mode 100644 templates/partials/header.html
create mode 100644 templates/partials/header_mobile.html
create mode 100644 templates/partials/homework_default_penalty_rules.yaml
create mode 100644 templates/partials/homework_sidebar.html
create mode 100644 templates/partials/login_dialog.html
create mode 100644 templates/partials/nav.html
create mode 100644 templates/partials/path.html
create mode 100644 templates/partials/problem_default.md
create mode 100644 templates/partials/problem_list.html
create mode 100644 templates/partials/problem_lucky.html
create mode 100644 templates/partials/problem_sidebar.html
create mode 100644 templates/partials/problem_sidebar_contest.html
create mode 100644 templates/partials/problem_sidebar_homework.html
create mode 100644 templates/partials/problem_sidebar_normal.html
create mode 100644 templates/partials/problem_stat.html
create mode 100644 templates/partials/training_default.json
create mode 100644 templates/problem_copy.html
create mode 100644 templates/problem_detail.html
create mode 100644 templates/problem_edit.html
create mode 100644 templates/problem_main.html
create mode 100644 templates/problem_settings.html
create mode 100644 templates/problem_solution.html
create mode 100644 templates/problem_statistics.html
create mode 100644 templates/problem_submit.html
create mode 100644 templates/problem_submit_tr.html
create mode 100644 templates/problem_upload.html
create mode 100644 templates/record_detail.html
create mode 100644 templates/record_detail_status.html
create mode 100644 templates/record_detail_summary.html
create mode 100644 templates/record_main.html
create mode 100644 templates/record_main_tr.html
create mode 100644 templates/training_detail.html
create mode 100644 templates/training_edit.html
create mode 100644 templates/training_main.html
create mode 100644 templates/user_changemail_mail.html
create mode 100644 templates/user_changemail_mail_sent.html
create mode 100644 templates/user_detail.html
create mode 100644 templates/user_login.html
create mode 100644 templates/user_logout.html
create mode 100644 templates/user_lostpass.html
create mode 100644 templates/user_lostpass_mail.html
create mode 100644 templates/user_lostpass_mail_sent.html
create mode 100644 templates/user_lostpass_with_code.html
create mode 100644 templates/user_register.html
create mode 100644 templates/user_register_mail.html
create mode 100644 templates/user_register_mail_sent.html
create mode 100644 templates/user_register_with_code.html
create mode 100644 templates/wiki_help.html
diff --git a/templates/about.html b/templates/about.html
new file mode 100644
index 000000000..490a3b79e
--- /dev/null
+++ b/templates/about.html
@@ -0,0 +1,137 @@
+{% extends "layout/wiki_base.html" %}
+{% block wiki_content %}
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos 全称为 Velocious Informatics Judge Online System (高效信息学在线评测系统),致力于为用户提供安全、完善、开放的在线评测及题目交流等服务。
+
Vijos 是一个非营利性的公益网站,由 Mrw、同济大学和北京市第八十中学共同赞助。PingCAP、Google 和清华大学提供技术支持。
+
+
+
+
+
+
{{ _('Discussion') }}:
+
{{ _('QQ Group') }}: 248452688
+
{{ _('Manager') }}:
+
{{ _('QQ') }}: 514649176 {{ _('Email') }}: mrw # vijos.org
+
{{ _('Development') }}:
+
{{ _('QQ') }}: 490241327 {{ _('Email') }}: dev $ vijos.org
+
{{ _('Ops') }}:
+
{{ _('QQ') }}: 459834574 {{ _('Email') }}: ops [at] vijos.org
+
{{ _('Feedback') }}:
+
{{ _('QQ') }}: 1744540592 {{ _('Email') }}: feedback @ vijos.org
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
1. 收集的信息
+
我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式:
+
+
2. 如何使用收集到的信息
+
我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Vijos 以及用户的隐私。
+
当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。
+
3. 访问和更新您的个人信息
+
无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。
+
我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。
+
4. 信息安全
+
我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。
+
对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Vijos 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
0. 欢迎使用 Vijos
+
注册 Vijos 帐户和/或使用 Vijos 提供的服务(包括网页提供的在线服务和题目评测的非在线服务等),即表示您已同意本条款。请您务必审慎阅读,充分理解条款各项内容。
+
1. 使用服务
+
您必须遵守各项服务中提供的所有政策(包括但不限于讨论和题解的版规)。
+
请勿滥用我们的服务。如,请勿干扰我们的服务,或尝试使用除我们提供的界面和指示以外的方法访问这些服务,或使用我们服务中出现的缺陷干扰其他网站或设施的正常运行。您仅能在法律允许的范围内使用我们的服务。
+
您在使用我们服务时须遵守我们服务器所在地的法律法规,不得利用我们服务从事违法违规行为,包括但不限于:
+
+ 发布、传送、传播、储存危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
+ 发布、传送、传播、储存侵害他人知识产权、商业秘密等合法权利的内容;
+ 恶意虚构事实、隐瞒真相以误导、欺骗他人;
+ 发布、传送、传播广告信息及垃圾信息;
+ 其他法律法规禁止的行为。
+
+
如果您违反了约定,相关国家相关机关或机构可能会对您提起诉讼、进行行政处罚或采取其他制裁措施,Vijos 将给于协助。造成损害的,您应依法予以赔偿,Vijos 不承担任何责任。
+
如果 Vijos 发现或收到他人举报您发布的信息违反约定,Vijos 有权进行独立判断并采取技术手段予以删除、屏蔽或断开链接。同时,Vijos 有权视用户的行为性质,采取包括但不限于暂停或终止服务,限制、冻结或终止账户使用,追究法律责任等措施。
+
2. 版权
+
使用我们的服务并不代表您拥有我们的服务或您所访问的内容的任何知识产权。网站上的所有材料(包括但不限于题目内容、用户界面、Wiki)版权均受保护,归 Vijos 所有。除非另有说明,本网站上的材料和服务仅用于个人和非商业用途,未经 Vijos 书面许可,不得复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发从本网站获得的任何信息、文件、产品或服务。
+
3. 您在我们服务中发布的内容
+
我们的某些服务允许您提交内容。您保留对该内容持有的任何知识产权的所有权。
+
当您上传内容或通过其他方式向我们的服务提交内容时,您授予 Vijos 使用、持有、存储、复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发此内容等权利。您在此许可中授予的权限,仅能用于运营、宣传和改进我们的服务,以及开发新的服务。该项许可在您停止使用我们的服务后依然有效。某些服务可能会向您提供一些方法,用于访问和删除您提供给该服务的内容。对于您提交至我们服务的任何内容,请确保您拥有向我们授予此许可的必要权利。我们有权在未通知您的情况下删除我们认为侵犯了知识产权或违反了相关法律法规的内容。
+
4. 对于发布题目的附加条款
+
您可以在 Vijos 上创建新题目。您上传到 Vijos 的题目,除了适用于本协议第三条(即“您在我们服务中发布的内容”)条款,还包含以下附加条款(若有冲突的条款,以附加条款中的优先):
+
+ 您上传到 Vijos 上的题目版权为 Vijos 和您共同拥有,我们会在相关页面或在对其进行分发、传播等操作时标明版权所有者。
+
+ Vijos 尊重他人知识产权和合法权益,请您在上传题目前确保拥有题目内容(包括但不限于题目描述、数据、图片等)的著作权及信息网络传播权或者已经取得上述全部权利人的许可并不存在任何著作权纠纷。Vijos有权在不通知的情况下删除被认为侵权的题目。
+
+ 您可以申请将自己上传的优质题目合并到题库主干。我们的管理员会对您创建的题目的内容(包括但不限于评测数据等对用户不可见的信息)进行人工审核和适当修改以确认其符合国家基本法律法规。出于质量的考虑,我们也可能会拒绝您完全合法的合并到题库主干的请求。
+
+ 我们会维护服务的稳定,并对数据(包括您递交的题目)进行定期的备份,并尽量在关闭服务前通知您,但我们仍然不对任何题目(包括主干和非主干)提供永久存储或保留的承诺,出于安全的考虑推荐您自行保留题目的内容。
+
+ 您有权决定 Vijos 是否公开您上传的题目的数据。公开题目数据意味着 Vijos 上的用户均有权利获取到您递交的题目的所有评测数据,但相关版权协议仍然生效。
+
+
+
5. 隐私保护
+
Vijos 隐私声明 介绍了您在使用我们的服务时,我们会如何处理您的个人数据和保护您的隐私。使用我们的服务即表示您同意 Vijos 可以按照我们的隐私权政策使用您的个人数据。
+
6. 修改和终止服务
+
我们始终在不断更改和改进我们的服务。我们可能会增加或删除功能,也可能暂停或彻底停止某项服务。
+
您可以随时停止使用我们的服务,尽管我们对此表示非常遗憾。Vijos 也可能随时停止向您提供服务,或随时对我们的服务增加或设置新的限制。
+
7. 保证和免责声明
+
我们对服务内容、服务的具体功能,或其可靠性、可用性或满足您需要的能力不作任何承诺。我们的服务是按照现有技术和条件所能达到的现状提供的。我们会尽最大努力向您提供服务,确保服务的连贯性和安全性。但我们不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。
+
8. 关于本条款
+
我们可以修改上述条款或任何适用于某项服务的附加条款,您应当定期查阅本条款。所有修改的适用不具有追溯力,且会在公布十四天或更长时间后方始生效。但是,对服务新功能的特别修改或由于法律原因所作的修改将立即生效。如果您不同意服务的修改条款,应停止使用服务。
+
9. 其他
+
如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。
+
您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定:
+
+ 第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。
+ 不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。
+ 发布(或回复)的所有内容不得包含会干扰 Vijos 用户界面呈现的相关内容。
+ 发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Vijos 明确禁止的网站的链接。
+ 特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。
+ 发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。
+ 打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。
+ 我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。
+
+
您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于:
+
+ 危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
+ 侵害他人知识产权、商业秘密等合法权利的内容;
+ 恶意虚构事实、隐瞒真相以误导、欺骗他人的内容;
+ 广告信息及垃圾信息;
+ 其他法律法规禁止的内容。
+
+
对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。
+
+
+{% endblock %}
diff --git a/templates/ac_mail.html b/templates/ac_mail.html
new file mode 100644
index 000000000..1509afda9
--- /dev/null
+++ b/templates/ac_mail.html
@@ -0,0 +1,10 @@
+{% extends "layout/mail.html" %}
+{% block title %}{{ _('P{0} - {1} Accepted!').format(pdoc['doc_id'], pdoc['title']) }}{% endblock %}
+{% block content %}
+{{ _('Congratulations! Your submission is accepted.') }}
+{{ _('Problem') }}: P{{ pdoc['doc_id'] }} {{ pdoc['title'] }}
+{{ _('Code') }}:
+
+{{ rdoc['code'] }}
+
+{% endblock %}
diff --git a/templates/bsod.html b/templates/bsod.html
new file mode 100644
index 000000000..8bee4016f
--- /dev/null
+++ b/templates/bsod.html
@@ -0,0 +1,28 @@
+
+
+
+ Vijos System Error
+
+
+
+
+#include <string.h>
+
+int main () {
+ char answer[ 42 ];
+ strcpy(answer, "twd2 will tell you the answer to life the universe and everything," );
+ strcpy(answer, "but first of all, he is very sorry that Vijos meets some issues now." );
+ strcpy(answer, "please wait patiently , or contact twd2 impatiently about this error." );
+ return 0 ;
+}
+
+
+
diff --git a/templates/components/comments.html b/templates/components/comments.html
new file mode 100644
index 000000000..2d83eb859
--- /dev/null
+++ b/templates/components/comments.html
@@ -0,0 +1,37 @@
+{% macro render(
+ view, docs, udict,
+ comment_ref,
+ reply_ref,
+ comment_post_perm,
+ comment_edit_perm,
+ comment_edit_self_perm,
+ comment_delete_perm,
+ comment_delete_self_perm,
+ reply_post_perm,
+ reply_edit_perm,
+ reply_edit_self_perm,
+ reply_delete_perm,
+ reply_delete_self_perm,
+ comment_placeholder = 'Write Your Comment',
+ comment_post_op = 'reply',
+ comment_edit_op = 'edit_reply',
+ comment_post_text = 'Comment',
+ comment_edit_text = 'Update',
+ reply_post_op = 'tail_reply',
+ reply_post_text = 'Reply',
+ reply_edit_op = 'edit_tail_reply',
+ reply_edit_text = 'Update',
+ comment_delete_op = 'delete_reply',
+ reply_delete_op = 'delete_tail_reply'
+) %}
+{% import "components/comments_base.html" as comment_base with context %}
+{% import "components/comments_"~view~".html" as comment_impl with context %}
+
+{% endmacro %}
diff --git a/templates/components/comments_base.html b/templates/components/comments_base.html
new file mode 100644
index 000000000..dfb41de59
--- /dev/null
+++ b/templates/components/comments_base.html
@@ -0,0 +1,46 @@
+{% macro comment_form() %}
+
+
+
+
+
+
+{% endmacro %}
+
+{% macro comment_operations(doc) %}
+
+{% endmacro %}
+
+{% macro reply_operations(doc, rdoc) %}
+
+{% endmacro %}
diff --git a/templates/components/comments_discussion.html b/templates/components/comments_discussion.html
new file mode 100644
index 000000000..88f873527
--- /dev/null
+++ b/templates/components/comments_discussion.html
@@ -0,0 +1,63 @@
+{% import "components/user.html" as user with context %}
+{% macro reply(mode_create, udoc, doc = {}, rdoc = {}) %}
+
+{% endmacro %}
+
+{% macro comment(mode_create, udoc, doc = {}) %}
+
+{% endmacro %}
diff --git a/templates/components/comments_solution.html b/templates/components/comments_solution.html
new file mode 100644
index 000000000..a9af76c41
--- /dev/null
+++ b/templates/components/comments_solution.html
@@ -0,0 +1,96 @@
+{% import "components/user.html" as user with context %}
+{% macro reply(mode_create, udoc, doc = {}, rdoc = {}) %}
+
+{% endmacro %}
+
+{% macro comment(mode_create, udoc, doc = {}) %}
+
+{% endmacro %}
diff --git a/templates/components/contest.html b/templates/components/contest.html
new file mode 100644
index 000000000..5faf27d95
--- /dev/null
+++ b/templates/components/contest.html
@@ -0,0 +1,8 @@
+{% import "components/user.html" as user with context %}
+{% macro render_time(tdoc_time) %}
+{{ datetime_span(tdoc_time, false, '%Y-%m-%d %H:%M') }}
+{% endmacro %}
+
+{% macro render_duration(tdoc) %}
+{{ ((tdoc['end_at'] - tdoc['begin_at']).total_seconds() / 3600)|round(1) }}
+{% endmacro %}
diff --git a/templates/components/form.html b/templates/components/form.html
new file mode 100644
index 000000000..11e38b64b
--- /dev/null
+++ b/templates/components/form.html
@@ -0,0 +1,201 @@
+{% macro form_begin() %}
+{% set label = kwargs.pop('label') %}
+{% set columns = kwargs.pop('columns') %}
+{% set last_column = kwargs.pop('last_column', true) %}
+{% set required = kwargs.pop('required', false) %}
+{% set hotkeys = kwargs.pop('hotkeys', none) %}
+{% set row = kwargs.pop('row', true) %}
+{% set no_label = kwargs.pop('no_label', false) %}
+{% set label_wrap = kwargs.pop('label_wrap', true) %}
+{% if row %}
+
+{% endif %}
+
+{% if row %}
+
+{% endif %}
+{% endmacro %}
+
+{% macro form_attr(form_class) %}
+{% set disabled = kwargs.pop('disabled', false) %}
+{% set required = kwargs.pop('required', false) %}
+{% set autofocus = kwargs.pop('autofocus', false) %}
+{% set date = kwargs.pop('date', false) %}
+{% set time = kwargs.pop('time', false) %}
+ class="{{ form_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
+ {% if disabled %}disabled{% endif %}
+ {% if required %}required{% endif %}
+ {% if autofocus %}autofocus data-autofocus{% endif %}
+ {% if date %}data-pick-date{% endif %}
+ {% if time %}data-pick-time{% endif %}
+{% endmacro %}
+
+{% macro container_attr(container_class) %}
+{% set extra_class = kwargs.pop('extra_class', none) %}
+ class="{{ container_class }}{% if extra_class %} {{ extra_class }}{% endif %}"
+{% endmacro %}
+
+{% macro select(options, name='', value='') %}
+
+
+ {% for k, v in options %}
+
+ {{ _(v) }}
+
+ {% endfor %}
+
+
+{% endmacro %}
+
+{% macro form_select(columns=5) %}
+{{ form_begin(columns=columns, **kwargs) }}
+{{ select(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, **kwargs) }}
+{% endmacro %}
+
+{% macro radio(options, name='', value='') %}
+
+{% for k, v in options %}
+
+ {{ _(v) }}
+
+{% endfor %}
+
+{% endmacro %}
+
+{% macro form_radio(columns=5) %}
+{{ form_begin(columns=columns, label_wrap=false, **kwargs) }}
+{{ radio(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, label_wrap=false, **kwargs) }}
+{% endmacro %}
+
+{% macro image_radio(options, name='', value='', image_class='') %}
+
+{% endmacro %}
+
+{% macro form_image_radio(columns=8) %}
+{{ form_begin(columns=columns, label_wrap=false, **kwargs) }}
+{{ image_radio(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, label_wrap=false, **kwargs) }}
+{% endmacro %}
+
+{% macro text(name='', value='', placeholder='', type='text') %}
+
+
+
+{% endmacro %}
+
+{% macro form_text(columns=5) %}
+{{ form_begin(columns=columns, **kwargs) }}
+{{ text(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, **kwargs) }}
+{% endmacro %}
+
+{% macro textarea(name='', value='', placeholder='') %}
+{% set markdown = kwargs.pop('markdown', false) %}
+
+
+
+{% endmacro %}
+
+{% macro form_textarea(columns=8) %}
+{{ form_begin(columns=columns, **kwargs) }}
+{{ textarea(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, **kwargs) }}
+{% endmacro %}
+
+{% macro checkbox(label='', name='', value=false) %}
+
+
+ {{ _(label) }}
+
+
+{% endmacro %}
+
+{% macro form_checkbox(columns=5) %}
+{{ form_begin(columns=columns, no_label=True, **kwargs) }}
+{{ checkbox(columns=columns, **kwargs) }}
+{{ form_end(columns=columns, no_label=True, **kwargs) }}
+{% endmacro %}
diff --git a/templates/components/home.html b/templates/components/home.html
new file mode 100644
index 000000000..0eaf984ca
--- /dev/null
+++ b/templates/components/home.html
@@ -0,0 +1,17 @@
+{% import "components/sidemenu.html" as sidemenu with context %}
+{% macro render_sidebar() %}
+
+
+
+{% endmacro %}
diff --git a/templates/components/homework.html b/templates/components/homework.html
new file mode 100644
index 000000000..96972a3da
--- /dev/null
+++ b/templates/components/homework.html
@@ -0,0 +1,8 @@
+{% import "components/user.html" as user with context %}
+{% macro render_time(tdoc_time) %}
+{{ datetime_span(tdoc_time, false, '%Y-%m-%d %H:%M') }}
+{% endmacro %}
+
+{% macro render_extension(tdoc) %}
+{{ ((tdoc['end_at'] - tdoc['penalty_since']).total_seconds() / 3600)|round(1) }}
+{% endmacro %}
diff --git a/templates/components/md_hint.html b/templates/components/md_hint.html
new file mode 100644
index 000000000..98602bd13
--- /dev/null
+++ b/templates/components/md_hint.html
@@ -0,0 +1,29 @@
+
+
+
+ {{ _('Inline codes') }}
+ `std::cout()`
+ {{ _('Code blocks') }}
+
+```c++
+int main() {
+ return 0;
+}
+```
+
+ {{ _('Inline formulas') }}
+ $ E=mc^2 $
+ {{ _('Formula blocks') }}
+ $$ E=mc^2 $$
+ {{ _('Links') }}
+ [{{ _('Text') }}](http://...)
+ {{ _('Images') }}
+ 
+
+
{{ _('Learn More') }}
+
+
+
diff --git a/templates/components/noscript_note.html b/templates/components/noscript_note.html
new file mode 100644
index 000000000..3bfa1c266
--- /dev/null
+++ b/templates/components/noscript_note.html
@@ -0,0 +1,7 @@
+{% macro render() %}
+
+
+ {{ _('This page needs JavaScript to work.') }}
+
+
+{% endmacro %}
diff --git a/templates/components/nothing.html b/templates/components/nothing.html
new file mode 100644
index 000000000..b4f3143e7
--- /dev/null
+++ b/templates/components/nothing.html
@@ -0,0 +1,6 @@
+{% macro render(text, compact=false) %}
+
+{% endmacro %}
diff --git a/templates/components/paginator.html b/templates/components/paginator.html
new file mode 100644
index 000000000..bd8136336
--- /dev/null
+++ b/templates/components/paginator.html
@@ -0,0 +1,25 @@
+{% macro render(page, num_pages, add_qs='') %}
+{% if num_pages > 0 %}
+
+{% endif %}
+{% endmacro %}
diff --git a/templates/components/problem.html b/templates/components/problem.html
new file mode 100644
index 000000000..c8bbbd526
--- /dev/null
+++ b/templates/components/problem.html
@@ -0,0 +1,40 @@
+{% macro render_problem_title(pdoc, tdoc=none, show_tags=true, show_invisible_flag=true, rp=none, invalid=false) %}
+ {%- if not invalid %}
+
+ {%- endif %}
+ {% if pdoc['doc_id']|string|length < 10 %}P{{ pdoc['doc_id'] }} {% endif %}{{ pdoc['title'] }}
+ {%- if not invalid %}
+
+ {%- endif %}
+{%- if pdoc['hidden'] and show_invisible_flag %}
+ ({{ _('Hidden') }})
+{%- endif %}
+{%- if not rp is none %}
+ RP+{{ rp|round|int }}
+{%- endif %}
+{%- if show_tags %}
+ {{ render_problem_tags(pdoc) }}
+{%- endif %}
+{% endmacro %}
+
+{% macro render_problem_tags(pdoc, show_none_label=false) %}
+{%- if pdoc['tag']|length > 0 %}
+
+{%- else %}
+{%- if show_none_label %}
+ {{ _('(None)') }}
+{%- endif %}
+{%- endif %}
+{% endmacro %}
diff --git a/templates/components/record.html b/templates/components/record.html
new file mode 100644
index 000000000..7148c2d77
--- /dev/null
+++ b/templates/components/record.html
@@ -0,0 +1,15 @@
+{% macro render_status_td(rdoc, rid_key='_id') %}
+
+
+{% if rdoc['status'] == vj4.constant.record.STATUS_JUDGING %}
+
+{% endif %}
+
+{% endmacro %}
diff --git a/templates/components/sidemenu.html b/templates/components/sidemenu.html
new file mode 100644
index 000000000..92bb8e498
--- /dev/null
+++ b/templates/components/sidemenu.html
@@ -0,0 +1,15 @@
+{% macro render_item(icon_name, page_name, label=none) %}
+
+{% endmacro %}
diff --git a/templates/components/user.html b/templates/components/user.html
new file mode 100644
index 000000000..588685cec
--- /dev/null
+++ b/templates/components/user.html
@@ -0,0 +1,26 @@
+{% macro render_inline(
+ udoc,
+ dudoc={},
+ avatar=true,
+ badge=true,
+ modbadge=true
+) %}
+
+{% if avatar %}
+
+{% endif %}
+
+ {% if dudoc['display_name'] %}
+ {{ dudoc['display_name'] }} ({{ udoc['uname'] }})
+ {% else %}
+ {{ udoc['uname'] }}
+ {% endif %}
+
+{% if badge %}
+ LV {{ dudoc['level']|default(0) }}
+{% if modbadge and handler.dudoc_has_perm(udoc, dudoc, vj4.model.builtin.PERM_MOD_BADGE) %}
+ MOD
+{% endif %}
+{% endif %}
+
+{% endmacro %}
diff --git a/templates/contest_detail.html b/templates/contest_detail.html
new file mode 100644
index 000000000..391666445
--- /dev/null
+++ b/templates/contest_detail.html
@@ -0,0 +1,81 @@
+{% extends "layout/basic.html" %}
+{% import "components/contest.html" as contest with context %}
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+{% block content %}
+
+
+
+
+ {{ tdoc['content']|markdown }}
+ {% if handler.is_ongoing(tdoc) %}
+
+ {{ _('We will check code similarity after this contest.') }}
+
+ {% endif %}
+
+
+ {% if handler.is_ongoing(tdoc) or handler.is_done(tdoc) %}
+
+
+ {% if attended or handler.is_done(tdoc) %}
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+
+ {% endif %}
+
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Status') }}
+ {{ _('Last Submit At') }}
+ {% endif %}
+ {{ _('Problem') }}
+
+
+
+ {% for pid in tdoc['pids'] %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {% if psdict[pid] and psdict[pid]['rid'] %}
+ {% with rdoc=rdict[psdict[pid]['rid']] %}
+ {% if handler.can_show_record(tdoc) %}
+ {{ record.render_status_td(rdoc) }}
+ {% else %}
+ {{ _('Submitted') }}
+ {% endif %}
+ {{ datetime_span(rdoc['_id'].generation_time) }}
+ {% endwith %}
+ {% else %}
+ {{ _('No Submissions') }}
+ -
+ {% endif %}
+ {% endif %}
+
+ #{{ loop.index }}:
+ {{ problem.render_problem_title(pdict[pid], tdoc=tdoc, show_invisible_flag=false, show_tags=false) }}
+
+
+ {% endfor %}
+
+
+
+ {% else %}
+ {{ nothing.render('Please attend contest to see the problems.') }}
+ {% endif %}
+
+ {% endif %}
+
+
+ {% with owner_udoc=udict[tdoc['owner_uid']], owner_dudoc=dudict[tdoc['owner_uid']] %}
+ {% include "partials/contest_sidebar.html" %}
+ {% endwith %}
+
+
+{% endblock %}
diff --git a/templates/contest_edit.html b/templates/contest_edit.html
new file mode 100644
index 000000000..a662518e7
--- /dev/null
+++ b/templates/contest_edit.html
@@ -0,0 +1,41 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+ {% include 'components/md_hint.html' %}
+
+
+{% endblock %}
diff --git a/templates/contest_main.html b/templates/contest_main.html
new file mode 100644
index 000000000..ac93c5e4f
--- /dev/null
+++ b/templates/contest_main.html
@@ -0,0 +1,132 @@
+{% extends "layout/basic.html" %}
+{% import "components/contest.html" as contest with context %}
+{% macro render_important_contest(view, title, tdoc) %}
+
+{% endmacro %}
+{% block content %}
+
+
+ {% for tdoc in tdocs %}
+ {% if handler.is_ongoing(tdoc) %}
+ {{ render_important_contest('live', 'Live...', tdoc) }}
+ {% elif handler.is_upcoming(tdoc) %}
+ {{ render_important_contest('ready', 'Ready (☆▽☆)', tdoc) }}
+ {% endif %}
+ {% endfor %}
+
+
+
+ {% if not tdocs %}
+ {{ nothing.render('There are no contests...') }}
+ {% else %}
+
+ {% for tdoc in tdocs %}
+
+
+
+ {% endfor %}
+
+ {{ paginator.render(page, tpcount, add_qs=qs) }}
+ {% endif %}
+
+
+
+
+ {% if handler.has_perm(vj4.model.builtin.PERM_CREATE_CONTEST) %}
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/contest_scoreboard.html b/templates/contest_scoreboard.html
new file mode 100644
index 000000000..202d460c2
--- /dev/null
+++ b/templates/contest_scoreboard.html
@@ -0,0 +1,58 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+ {%- for column in rows[0] -%}
+
+ {%- endfor -%}
+
+
+
+ {%- for column in rows[0] -%}
+
+ {% if column['type'] == 'problem_detail' %}
+ {{ column['value'] }}
+ {% else %}
+ {{ column['value'] }}
+ {% endif %}
+
+ {%- endfor -%}
+
+
+
+ {%- for row in rows[1:] -%}
+
+ {%- for column in row -%}
+
+ {% if column['type'] == 'user' %}
+ {{ user.render_inline(column['raw'], badge=false) }}
+ {% elif column['type'] == 'record' %}
+ {% if column['raw'] %}
+ {{ column['value']|nl2br }}
+ {% else %}
+ {{ column['value']|nl2br }}
+ {% endif %}
+ {% else %}
+ {{ column['value']|nl2br }}
+ {% endif %}
+
+ {%- endfor -%}
+
+ {%- endfor -%}
+
+
+
+
+
+{% endblock %}
diff --git a/templates/contest_scoreboard_download_html.html b/templates/contest_scoreboard_download_html.html
new file mode 100644
index 000000000..f925afee1
--- /dev/null
+++ b/templates/contest_scoreboard_download_html.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+ {%- for column in rows[0] -%}
+
+ {{ column['value'] }}
+
+ {%- endfor -%}
+
+
+
+ {%- for row in rows[1:] -%}
+
+ {%- for column in row -%}
+
+ {{ column['value'] }}
+
+ {%- endfor -%}
+
+ {%- endfor -%}
+
+
diff --git a/templates/discussion_create.html b/templates/discussion_create.html
new file mode 100644
index 000000000..6b2715732
--- /dev/null
+++ b/templates/discussion_create.html
@@ -0,0 +1,29 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+ {% include 'components/md_hint.html' %}
+
+
+{% endblock %}
diff --git a/templates/discussion_detail.html b/templates/discussion_detail.html
new file mode 100644
index 000000000..56182cd84
--- /dev/null
+++ b/templates/discussion_detail.html
@@ -0,0 +1,131 @@
+{% extends "layout/basic.html" %}
+{% import "components/comments.html" as comments with context %}
+{% block content %}
+
+
+
+
+
+
+ {{ ddoc['content']|markdown }}
+
+
+
+
+
+
+
+ {{ comments.render(
+ view = 'discussion',
+ docs = drdocs,
+ udict = udict,
+ comment_ref = 'drid',
+ reply_ref = 'drrid',
+ comment_post_perm = vj4.model.builtin.PERM_REPLY_DISCUSSION,
+ comment_edit_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY,
+ comment_edit_self_perm = vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF,
+ comment_delete_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY,
+ comment_delete_self_perm = vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF,
+ reply_post_perm = vj4.model.builtin.PERM_REPLY_DISCUSSION,
+ reply_edit_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY,
+ reply_edit_self_perm = vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF,
+ reply_delete_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY,
+ reply_delete_self_perm = vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF
+ ) }}
+ {{ paginator.render(page, pcount) }}
+ {% if drcount == 0 %}
+ {{ nothing.render('No comments so far...') }}
+ {% endif %}
+
+
+
+
+ {% with udoc = udict[ddoc['owner_uid']], dudoc = dudict[ddoc['owner_uid']] %}
+
+
+
+
+
+
+
+
+ {% endwith %}
+
+ {% if vnode['doc_type'] == vj4.model.document.TYPE_PROBLEM %}
+ {% with pdoc=vnode, owner_udoc=udict[vnode['owner_uid']], owner_dudoc=dudict[vnode['owner_uid']] %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/discussion_edit.html b/templates/discussion_edit.html
new file mode 100644
index 000000000..a6af86e3b
--- /dev/null
+++ b/templates/discussion_edit.html
@@ -0,0 +1,31 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+ {% include 'components/md_hint.html' %}
+
+
+{% endblock %}
diff --git a/templates/discussion_main_or_node.html b/templates/discussion_main_or_node.html
new file mode 100644
index 000000000..63c83d8c2
--- /dev/null
+++ b/templates/discussion_main_or_node.html
@@ -0,0 +1,44 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+ {% include "partials/discussion_list.html" %}
+
+
+
+ {% if vnode['doc_type'] == vj4.model.document.TYPE_PROBLEM %}
+ {% with pdoc=vnode, owner_udoc=udict[vnode['owner_uid']], owner_dudoc=dudict[vnode['owner_uid']] if dudict %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+ {% elif vnode['doc_type'] == vj4.model.document.TYPE_CONTEST %}
+ {% with tdoc=vnode, owner_udoc=udict[vnode['owner_uid']], owner_dudoc=dudict[vnode['owner_uid']] if dudict %}
+ {% include "partials/contest_sidebar.html" %}
+ {% endwith %}
+ {% elif vnode['doc_type'] == vj4.model.document.TYPE_DISCUSSION_NODE %}
+
+ {% endif %}
+ {% include 'discussion_nodes_widget.html' %}
+
+
+{% endblock %}
diff --git a/templates/discussion_nodes_widget.html b/templates/discussion_nodes_widget.html
new file mode 100644
index 000000000..d224338e9
--- /dev/null
+++ b/templates/discussion_nodes_widget.html
@@ -0,0 +1,17 @@
+
+
+
+ {% for category, nodes in discussion_nodes.items() %}
+
+ {{ category }}
+
+ {% for node in nodes %}
+ {{ node['name'] }}
+ {% endfor %}
+
+
+ {% endfor %}
+
+
diff --git a/templates/domain_base.html b/templates/domain_base.html
new file mode 100644
index 000000000..bd0618379
--- /dev/null
+++ b/templates/domain_base.html
@@ -0,0 +1,40 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+ {% block domain_content %}{% endblock %}
+
+
+
+{% endblock %}
diff --git a/templates/domain_join.html b/templates/domain_join.html
new file mode 100644
index 000000000..245501bba
--- /dev/null
+++ b/templates/domain_join.html
@@ -0,0 +1,26 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
{{ _('By clicking the button, you will become a member of the domain {0}.').format(handler.domain['name']) }}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/domain_main.html b/templates/domain_main.html
new file mode 100644
index 000000000..c9f3326e9
--- /dev/null
+++ b/templates/domain_main.html
@@ -0,0 +1,205 @@
+{% set no_path_section = true %}
+{% extends "layout/basic.html" %}
+{% import "components/contest.html" as contest with context %}
+{% block content %}
+{% if handler.domain['bulletin'] %}
+
+
+
+
+ {{ handler.domain['bulletin']|markdown }}
+
+
+
+
+{% endif %}
+
+
+ {% if not tdocs %}
+
+ {% else %}
+
+
+
+ {% for tdoc in tdocs %}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+ {% if not htdocs %}
+
+ {% else %}
+
+
+
+ {% for tdoc in htdocs %}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+ {% if not trdocs %}
+
+ {% else %}
+
+
+ {% with tdocs=trdocs, tsdict=trsdict %}
+
+ {% for tdoc in tdocs %}
+
+
+
+ {% endfor %}
+
+ {% endwith %}
+
+ {% endif %}
+ {% if not ddocs %}
+
+ {% else %}
+
+
+ {% include "partials/discussion_list.html" %}
+
+ {% endif %}
+
+
+ {% if handler.has_perm(vj4.model.builtin.PERM_VIEW_DISCUSSION) %}
+ {% include 'discussion_nodes_widget.html' %}
+ {% endif %}
+ {% if domain_id == vj4.model.builtin.DOMAIN_ID_SYSTEM %}
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/domain_manage_dashboard.html b/templates/domain_manage_dashboard.html
new file mode 100644
index 000000000..277842437
--- /dev/null
+++ b/templates/domain_manage_dashboard.html
@@ -0,0 +1,22 @@
+{% import "components/user.html" as user %}
+{% extends "domain_base.html" %}
+{% block domain_content %}
+{% if handler.domain['bulletin'] %}
+
+
+ {{ handler.domain['bulletin']|markdown }}
+
+
+{% endif %}
+
+
+
+
+ {{ _('Gravatar') }}
+ {{ _('Name') }} {{ handler.domain['name'] }}
+
+
+
+{% endblock %}
diff --git a/templates/domain_manage_discussion.html b/templates/domain_manage_discussion.html
new file mode 100644
index 000000000..836fc010f
--- /dev/null
+++ b/templates/domain_manage_discussion.html
@@ -0,0 +1,22 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+
+{% include 'discussion_nodes_widget.html' %}
+{% endblock %}
diff --git a/templates/domain_manage_edit.html b/templates/domain_manage_edit.html
new file mode 100644
index 000000000..b1f1b846b
--- /dev/null
+++ b/templates/domain_manage_edit.html
@@ -0,0 +1,21 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+
+{% endblock %}
diff --git a/templates/domain_manage_join_applications.html b/templates/domain_manage_join_applications.html
new file mode 100644
index 000000000..48040fd38
--- /dev/null
+++ b/templates/domain_manage_join_applications.html
@@ -0,0 +1,60 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+{% if join_settings != None %}
+
+
+
+
{{ _('User can join this domain by visiting the following URL') }}:
+
{{ handler.ui_context['url_prefix'] }}{{ reverse_url('domain_join') }}
+ {% if join_settings['method'] == vj4.constant.domain.JOIN_METHOD_CODE %}
+
{{ _('Or, with automatically filled invitation code') }}:
+
{{ handler.ui_context['url_prefix'] }}{{ reverse_url('domain_join') }}?code={{ join_settings['code']|urlencode }}
+ {% endif %}
+ {% if join_settings['expire'] != None %}
+
+
+ {{ (_('The link will be expired at {0}').format(datetime_span(join_settings['expire'], relative=false)))|safe }}
+
+ {% endif %}
+
+
+{% endif %}
+
+{% endblock %}
diff --git a/templates/domain_manage_permission.html b/templates/domain_manage_permission.html
new file mode 100644
index 000000000..a4a57a1de
--- /dev/null
+++ b/templates/domain_manage_permission.html
@@ -0,0 +1,60 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+
+{% endblock %}
diff --git a/templates/domain_manage_role.html b/templates/domain_manage_role.html
new file mode 100644
index 000000000..53001c74a
--- /dev/null
+++ b/templates/domain_manage_role.html
@@ -0,0 +1,90 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+
+
+
+
{{ _('Create Role') }}
+
+
+
+ {{ _('Role name can only contains numbers, letters and underscores.') }}
+
+ {{ form.form_text(columns=None, label='Name', name='role', autofocus=True) }}
+
+
+
+
+
+ {{ noscript_note.render() }}
+
+
+ {{ _('Delete Selected Roles') }}
+
+
+{% endblock %}
diff --git a/templates/domain_manage_user.html b/templates/domain_manage_user.html
new file mode 100644
index 000000000..0e26919a1
--- /dev/null
+++ b/templates/domain_manage_user.html
@@ -0,0 +1,101 @@
+{% extends "domain_base.html" %}
+{% block domain_content %}
+
+
+
+
+
+
+ {{ _('Username / UID') }}
+
+
+
+
+
+ {{ _('Role') }}
+ {{ form.select([('', _('Select a role'))] + roles_with_text, 'role') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ _('Set Roles for selected users') }}
+ {{ form.select([('', _('Select a role'))] + roles_with_text, 'role') }}
+
+
+
+
+
+
+
+ {{ noscript_note.render() }}
+
+
+ {{ _('Remove Selected User from Domain') }}
+ {{ _('Set Roles for Selected User') }}
+
+
+{% endblock %}
diff --git a/templates/error.html b/templates/error.html
new file mode 100644
index 000000000..acd7e928e
--- /dev/null
+++ b/templates/error.html
@@ -0,0 +1,22 @@
+{% set no_path_section = true %}
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
{{ _('Oops!') }}
+
{{ _(error.message).format(*error.args) }}
+
{{ _('Technical Information') }}:
+
{{ _('Type') }}: {{ error.__class__.__name__ }}
+
{{ _('Arguments') }}:
+
+ {% for arg in error.args %}
+ {{ arg }}
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/templates/fs_upload.html b/templates/fs_upload.html
new file mode 100644
index 000000000..b9ea34ace
--- /dev/null
+++ b/templates/fs_upload.html
@@ -0,0 +1,23 @@
+{% extends 'layout/simple.html' %}
+{% block body %}
+{% if fdoc %}
+{{ _('Uploaded file info') }}:
+{{ _('ID') }}: {{ fdoc['_id'] }}
+{{ _('Userfile doc_id') }}: {{ ufid }}
+{{ _('MD5') }}: {{ fdoc['md5'] }}
+{{ _('Secret (keep it secret)') }}: {{ fdoc['metadata']['secret'] }}
+{{ _('URL') }}: {{ reverse_url('fs_get', domain_id=vj4.model.builtin.DOMAIN_ID_SYSTEM, secret=fdoc['metadata']['secret']) }}
+{{ _('Image Markdown') }}:
 }})
+{% endif %}
+
+{% endblock %}
diff --git a/templates/home_domain.html b/templates/home_domain.html
new file mode 100644
index 000000000..fd2eecc60
--- /dev/null
+++ b/templates/home_domain.html
@@ -0,0 +1,99 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+
+{% if pending_ddocs|length > 0 %}
+
+
+ {{ _('You have uncompleted domain creation operation. You can click "Continue" to finish the creation.') }}
+
+
+{% endif %}
+
+
+
+
+
+
+
+
+
+
+
+ {{ _('Name') }} ({{ _('ID') }})
+ {{ _('My Role') }}
+ {{ _('Action') }}
+
+
+
+ {% for ddoc in pending_ddocs %}
+
+
+
+
+
+ {{ _('Uncompleted') }} : {{ ddoc['name'] }} ({{ ddoc['_id'] }})
+
+
+ --
+
+
+
+ {% endfor %}
+ {% for ddoc in vj4.model.builtin.DOMAINS %}
+
+
+
+
+
+ {{ ddoc['name'] }} ({{ ddoc['_id'] }})
+
+
+ {{ dudict.get(ddoc['_id'], {})['role']|default(vj4.model.builtin.ROLE_DEFAULT) }}
+
+
+ {{ _('Visit') }}
+ {% if can_manage[ddoc['_id']] %}
+ · {{ _('Manage') }}
+ {% endif %}
+
+
+ {% endfor %}
+ {% for ddoc in ddocs %}
+ {% if not ddoc['pending'] %}
+
+
+
+
+
+ {{ ddoc['name'] }} ({{ ddoc['_id'] }})
+
+
+ {{ dudict.get(ddoc['_id'], {})['role']|default(vj4.model.builtin.ROLE_DEFAULT) }}
+
+
+ {{ _('Visit') }}
+ {% if can_manage[ddoc['_id']] %}
+ · {{ _('Manage') }}
+ {% endif %}
+
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/templates/home_domain_create.html b/templates/home_domain_create.html
new file mode 100644
index 000000000..c7fde65b6
--- /dev/null
+++ b/templates/home_domain_create.html
@@ -0,0 +1,36 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+
+
+
+
+ {{ _('A domain ID cannot be changed after creation. It is supposed to be:') }}
+
+ {{ _('Unique') }}
+ {{ _('At least 4 characters') }}
+ {{ _('Not wrapped with space') }}
+ {{ _('Not started with a number') }}
+ {{ _('Only A-Z, a-z, 0-9 and _ are accepted') }}
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/home_file.html b/templates/home_file.html
new file mode 100644
index 000000000..6e3d9738a
--- /dev/null
+++ b/templates/home_file.html
@@ -0,0 +1,44 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ _('Description') }}
+ {{ _('Size') }}
+ {{ _('Hash') }}
+ {{ _('Action') }}
+
+
+
+ {% for ufdoc in ufdocs %}
+ {% with fdoc = fdict.get(ufdoc['file_id'], {}) %}
+
+ {{ ufdoc['content'] }}
+ {{ fdoc['length']|format_size if fdoc['length'] else '?' }}
+ {{ fdoc['md5']|default('?') }}
+ {{ _('Download') }} · {{ _('Code') }}
+
+ {% endwith %}
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/templates/home_messages.html b/templates/home_messages.html
new file mode 100644
index 000000000..6c96dd2ea
--- /dev/null
+++ b/templates/home_messages.html
@@ -0,0 +1,24 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+
+
+
{{ _('Select User') }}
+
+
+
+
+ {{ _('Username / UID') }}
+
+
+
+
+
+
+
+
+ {{ noscript_note.render() }}
+
+
+
+{% endblock %}
diff --git a/templates/home_security.html b/templates/home_security.html
new file mode 100644
index 000000000..fec3c826d
--- /dev/null
+++ b/templates/home_security.html
@@ -0,0 +1,99 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+
+
+
+
+
+
+
+ {% for session in sessions %}
+
+
+
+ {% endfor %}
+
+
+
+
+
+
IP geo-location data is provided by MaxMind .
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/home_settings.html b/templates/home_settings.html
new file mode 100644
index 000000000..e7e556d1a
--- /dev/null
+++ b/templates/home_settings.html
@@ -0,0 +1,69 @@
+{% extends "layout/home_base.html" %}
+{% block home_content %}
+
+{% endblock %}
diff --git a/templates/homework_detail.html b/templates/homework_detail.html
new file mode 100644
index 000000000..f992457ba
--- /dev/null
+++ b/templates/homework_detail.html
@@ -0,0 +1,78 @@
+{% extends "layout/basic.html" %}
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+{% block content %}
+
+
+
+
+
+ {{ tdoc['content']|markdown }}
+
+
+
+
+ {% if handler.is_not_started(tdoc) %}
+ {{ nothing.render('This homework is not open and you cannot view problems.') }}
+ {% else %}
+ {% if attended or handler.is_done(tdoc) %}
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+
+ {% endif %}
+
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Status') }}
+ {{ _('Last Submit At') }}
+ {% endif %}
+ {{ _('Problem') }}
+
+
+
+ {% for pid in tdoc['pids'] %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {% if psdict[pid] and psdict[pid]['rid'] %}
+ {% with rdoc=rdict[psdict[pid]['rid']] %}
+ {% if handler.can_show_record(tdoc) %}
+ {{ record.render_status_td(rdoc) }}
+ {% else %}
+ {{ _('Submitted') }}
+ {% endif %}
+ {{ datetime_span(rdoc['_id'].generation_time) }}
+ {% endwith %}
+ {% else %}
+ {{ _('No Submissions') }}
+ -
+ {% endif %}
+ {% endif %}
+
+ #{{ loop.index }}:
+ {{ problem.render_problem_title(pdict[pid], tdoc=tdoc, show_invisible_flag=false, show_tags=false) }}
+
+
+ {% endfor %}
+
+
+
+ {% else %}
+ {{ nothing.render('Please claim the assignment to see the problems.') }}
+ {% endif %}{# attended or handler.is_done(tdoc) #}
+ {% endif %}{# handler.is_not_started(tdoc) #}
+
+
+
+ {% include "partials/homework_sidebar.html" %}
+
+
+{% endblock %}
diff --git a/templates/homework_edit.html b/templates/homework_edit.html
new file mode 100644
index 000000000..b93c6252d
--- /dev/null
+++ b/templates/homework_edit.html
@@ -0,0 +1,48 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+ {% include 'components/md_hint.html' %}
+
+
+{% endblock %}
diff --git a/templates/homework_main.html b/templates/homework_main.html
new file mode 100644
index 000000000..7c88509dc
--- /dev/null
+++ b/templates/homework_main.html
@@ -0,0 +1,68 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+ {% if not tdocs %}
+ {{ nothing.render('There is no homework so far ╰(*°▽°*)╯') }}
+ {% else %}
+
+ {% for tdoc in tdocs %}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+
+
+{% endblock %}
diff --git a/templates/judge_playground.html b/templates/judge_playground.html
new file mode 100644
index 000000000..40dcc69b3
--- /dev/null
+++ b/templates/judge_playground.html
@@ -0,0 +1,6 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+{% endblock %}
diff --git a/templates/layout/basic.html b/templates/layout/basic.html
new file mode 100644
index 000000000..ef8bf6116
--- /dev/null
+++ b/templates/layout/basic.html
@@ -0,0 +1,19 @@
+{% set layout_name = "basic" %}
+{% extends "layout/html5.html" %}
+{% block body %}
+
+{% include "partials/nav.html" %}
+
+
+
+ {% include "partials/header_mobile.html" %}
+ {% include "partials/header.html" %}
+
+ {% block content %}{% endblock %}
+
+ {% include "partials/footer.html" %}
+
+
+{% include "partials/login_dialog.html" %}
+
+{% endblock %}
diff --git a/templates/layout/home_base.html b/templates/layout/home_base.html
new file mode 100644
index 000000000..b76cfae0f
--- /dev/null
+++ b/templates/layout/home_base.html
@@ -0,0 +1,13 @@
+{% import "components/home.html" as home with context %}
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+ {% block home_content %}{% endblock %}
+
+
+ {{ home.render_sidebar() }}
+ {% block home_sidebar %}{% endblock %}
+
+
+{% endblock %}
diff --git a/templates/layout/html5.html b/templates/layout/html5.html
new file mode 100644
index 000000000..5cbc1cfaa
--- /dev/null
+++ b/templates/layout/html5.html
@@ -0,0 +1,46 @@
+{% import "components/form.html" as form with context %}
+{% import "components/sidemenu.html" as sidemenu with context %}
+{% import "components/paginator.html" as paginator with context %}
+{% import "components/nothing.html" as nothing with context %}
+{% import "components/noscript_note.html" as noscript_note with context %}
+{% import "components/user.html" as user with context %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ handler.render_title(page_title) }}
+
+
+
+ {% block body %}{% endblock %}
+
+
+
+
+
+
+
+
diff --git a/templates/layout/immersive.html b/templates/layout/immersive.html
new file mode 100644
index 000000000..784cf7b8c
--- /dev/null
+++ b/templates/layout/immersive.html
@@ -0,0 +1,24 @@
+{% set layout_name = "immersive" %}
+{% set no_path_section = true %}
+{% extends "layout/html5.html" %}
+{% block body %}
+
+{% include "partials/nav.html" %}
+
+
+
+ {% include "partials/header_mobile.html" %}
+
+
+ {% block content %}{% endblock %}
+
+
+{% with show_topics = false %}
+ {% include "partials/footer.html" %}
+{% endwith %}
+
+
+
+{% include "partials/login_dialog.html" %}
+
+{% endblock %}
diff --git a/templates/layout/mail.html b/templates/layout/mail.html
new file mode 100644
index 000000000..658dd7ea7
--- /dev/null
+++ b/templates/layout/mail.html
@@ -0,0 +1,30 @@
+{% set layout_name = "mail" %}
+
+
+
+
+
+{% block content %}{% endblock %}
+
+
+
+
+
diff --git a/templates/layout/simple.html b/templates/layout/simple.html
new file mode 100644
index 000000000..a9ac9511b
--- /dev/null
+++ b/templates/layout/simple.html
@@ -0,0 +1,4 @@
+{% set layout_name = "basic" %}
+{% extends "layout/html5.html" %}
+{% block body %}
+{% endblock %}
diff --git a/templates/layout/wiki_base.html b/templates/layout/wiki_base.html
new file mode 100644
index 000000000..22e63272d
--- /dev/null
+++ b/templates/layout/wiki_base.html
@@ -0,0 +1,16 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+ {% block wiki_content %}{% endblock %}
+
+
+
+{% endblock %}
diff --git a/templates/partials/contest_sidebar.html b/templates/partials/contest_sidebar.html
new file mode 100644
index 000000000..bd99d6fa3
--- /dev/null
+++ b/templates/partials/contest_sidebar.html
@@ -0,0 +1,108 @@
+{% import "components/user.html" as user with context %}
+{% import "components/contest.html" as contest with context %}
+
+{% if page_name != 'contest_detail' %}
+
+{% endif %}
+
+
+
+
+
+ {{ _('Status') }} {{ _(handler.status_text(tdoc)) }}
+ {{ _('Rule') }} {{ vj4.constant.contest.RULE_TEXTS[tdoc['rule']] }}
+ {{ _('Problem') }} {{ tdoc['pids']|length }}
+ {{ _('Start at') }} {{ contest.render_time(tdoc['begin_at']) }}
+ {{ _('End at') }} {{ contest.render_time(tdoc['end_at']) }}
+ {{ _('Duration') }} {{ contest.render_duration(tdoc) }} {{ _('hour(s)') }}
+ {{ _('Host') }} {{ user.render_inline(owner_udoc, dudoc=owner_dudoc, badge=false) }}
+ {{ _('Partic.') }}
+
+ {{ tdoc['attend']|default(0) }}
+ {% if attended %}
+ ({{ _('Attended') }})
+ {% endif %}
+
+
+
+
diff --git a/templates/partials/discussion_edit_form.html b/templates/partials/discussion_edit_form.html
new file mode 100644
index 000000000..55b2c8d0b
--- /dev/null
+++ b/templates/partials/discussion_edit_form.html
@@ -0,0 +1,6 @@
+{% import "components/form.html" as form with context %}
+{% if ddoc['highlight'] or handler.has_perm(vj4.model.builtin.PERM_HIGHLIGHT_DISCUSSION) %}
+ {{ form.form_checkbox(label='Highlight', name='highlight', value=ddoc['highlight']|default(false)) }}
+{% endif %}
+ {{ form.form_text(label='Title', name='title', value=ddoc['title']|default(''), autofocus=true, required=true) }}
+ {{ form.form_textarea(columns=12, label='Content', name='content', value=ddoc['content']|default(''), hotkeys='ctrl+enter:submit', markdown=true, required=true) }}
diff --git a/templates/partials/discussion_list.html b/templates/partials/discussion_list.html
new file mode 100644
index 000000000..0853868fc
--- /dev/null
+++ b/templates/partials/discussion_list.html
@@ -0,0 +1,46 @@
+{% import "components/nothing.html" as nothing with context %}
+{% import "components/user.html" as user with context %}
+{% import "components/paginator.html" as paginator with context %}
+ {% if not ddocs %}
+ {{ nothing.render('no discussion yet...') }}
+ {% else %}
+
+ {% for ddoc in ddocs %}
+
+
+
+ {% endfor %}
+
+ {% if page != undefined and dpcount != undefined %}
+ {{ paginator.render(page, dpcount) }}
+ {% endif %}
+ {% endif %}
diff --git a/templates/partials/domain_edit_form.html b/templates/partials/domain_edit_form.html
new file mode 100644
index 000000000..8b3974ab2
--- /dev/null
+++ b/templates/partials/domain_edit_form.html
@@ -0,0 +1,9 @@
+{% import "components/form.html" as form with context %}
+{% if page_name == 'domain_manage_edit' %}
+ {{ form.form_text(label='ID', name='id', value=ddoc['_id'], disabled=true) }}
+{% elif page_name == 'home_domain_create' %}
+ {{ form.form_text(label='ID', name='id', autofocus=true, required=true) }}
+{% endif %}
+ {{ form.form_text(label='Name', name='name', value=ddoc['name']|default(''), autofocus=(page_name == 'domain_manage_edit'), required=true) }}
+ {{ form.form_text(label='Gravatar Email', help_text='Will be used as the domain icon.', name='gravatar', value=ddoc['gravatar']|default('')) }}
+ {{ form.form_textarea(columns=12, label='Bulletin', name='bulletin', value=ddoc['bulletin']|default(''), markdown=true, required=false) }}
diff --git a/templates/partials/footer.html b/templates/partials/footer.html
new file mode 100644
index 000000000..011f2f2fd
--- /dev/null
+++ b/templates/partials/footer.html
@@ -0,0 +1,74 @@
+
diff --git a/templates/partials/hamburger.html b/templates/partials/hamburger.html
new file mode 100644
index 000000000..d7ad263c2
--- /dev/null
+++ b/templates/partials/hamburger.html
@@ -0,0 +1,7 @@
+
diff --git a/templates/partials/header.html b/templates/partials/header.html
new file mode 100644
index 000000000..f869224d9
--- /dev/null
+++ b/templates/partials/header.html
@@ -0,0 +1,11 @@
+
diff --git a/templates/partials/header_mobile.html b/templates/partials/header_mobile.html
new file mode 100644
index 000000000..fa82920ec
--- /dev/null
+++ b/templates/partials/header_mobile.html
@@ -0,0 +1,17 @@
+{% if no_path_section %}
+
+{% endif %}
diff --git a/templates/partials/homework_default_penalty_rules.yaml b/templates/partials/homework_default_penalty_rules.yaml
new file mode 100644
index 000000000..689730941
--- /dev/null
+++ b/templates/partials/homework_default_penalty_rules.yaml
@@ -0,0 +1,6 @@
+# Format:
+# hours: coefficient
+1: 0.9
+3: 0.8
+12: 0.75
+9999: 0.5
diff --git a/templates/partials/homework_sidebar.html b/templates/partials/homework_sidebar.html
new file mode 100644
index 000000000..956d671d1
--- /dev/null
+++ b/templates/partials/homework_sidebar.html
@@ -0,0 +1,85 @@
+{% import "components/user.html" as user with context %}
+{% import "components/homework.html" as homework with context %}
+
+{% if page_name != 'homework_detail' %}
+
+{% endif %}
+
+
+
+
+
+ {{ _('Status') }} {{ _(handler.status_text(tdoc)) }}
+ {{ _('Problem') }} {{ tdoc['pids']|length }}
+ {{ _('Open Since') }} {{ homework.render_time(tdoc['begin_at']) }}
+ {{ _('Deadline') }} {{ homework.render_time(tdoc['penalty_since']) }}
+ {{ _('Can be Extended For') }} {{ homework.render_extension(tdoc) }} {{ _('hour(s)') }}
+
+
+
diff --git a/templates/partials/login_dialog.html b/templates/partials/login_dialog.html
new file mode 100644
index 000000000..5f5e9f291
--- /dev/null
+++ b/templates/partials/login_dialog.html
@@ -0,0 +1,45 @@
+
+
+
+
+
{{ _('Don\'t have an account?') }}
+
{{ _('By signing up a Vijos universal account, you can submit code and join discussions in all online judging services provided by us.') }}
+
+
+
+
+
+
+ {{ _('SIGN IN') }}
+ {{ _('Using your Vijos universal account') }}
+
+
+
+
+
+
+
+
+
diff --git a/templates/partials/nav.html b/templates/partials/nav.html
new file mode 100644
index 000000000..a1a0c4a7c
--- /dev/null
+++ b/templates/partials/nav.html
@@ -0,0 +1,97 @@
+{% macro nav_item(target_page_name, target_page_prefix) %}
+
+
+ {{ _(target_page_name) }}
+
+
+{% endmacro %}
+
+
+
diff --git a/templates/partials/path.html b/templates/partials/path.html
new file mode 100644
index 000000000..52c79795b
--- /dev/null
+++ b/templates/partials/path.html
@@ -0,0 +1,19 @@
+
+{% if not no_path_section %}
+
+{% endif %}
+
diff --git a/templates/partials/problem_default.md b/templates/partials/problem_default.md
new file mode 100644
index 000000000..b81f88638
--- /dev/null
+++ b/templates/partials/problem_default.md
@@ -0,0 +1,99 @@
+# Background
+Special for beginners, ^_^
+
+# Description
+Given two integers x and y, print the sum.
+
+# Format
+
+## Input
+Two integers x and y, satisfying 0 <= x, y <= 32767.
+
+## Output
+One integer, the sum of x and y.
+
+# Sample 1
+
+## Input
+```
+123 500
+```
+
+## Output
+```
+623
+```
+
+# Limitation
+1s, 1024KiB for each test case.
+
+# Hint
+
+## Free Pascal Code
+
+```pascal
+var a,b:longint;
+begin
+ readln(a,b);
+ writeln(a+b);
+end.
+```
+
+## C Code
+
+```c
+#include
+int main(void)
+{
+ int a, b;
+ scanf("%d%d", &a, &b);
+ printf("%d\n", a + b);
+ return 0;
+}
+```
+
+## C++ Code
+
+```cpp
+#include
+using namespace std;
+int main()
+{
+ int a, b;
+ cin >> a >> b;
+ cout << a + b << endl;
+ return 0;
+}
+```
+
+## Python Code
+
+```python
+a, b = [int(i) for i in raw_input().split()]
+print(a + b)
+```
+
+## Java Code
+
+```java
+import java.io.*;
+import java.util.Scanner;
+
+public class Main {
+
+ /**
+ * @param args
+ * @throws IOException
+ */
+ public static void main(String[] args) throws IOException {
+ Scanner sc = new Scanner(System.in);
+ int a = sc.nextInt();
+ int b = sc.nextInt();
+ System.out.println(a + b);
+ }
+}
+```
+
+# Source
+
+**Vijos Original**
diff --git a/templates/partials/problem_list.html b/templates/partials/problem_list.html
new file mode 100644
index 000000000..335e176fc
--- /dev/null
+++ b/templates/partials/problem_list.html
@@ -0,0 +1,69 @@
+{% import "components/paginator.html" as paginator with context %}
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+{% import "components/nothing.html" as nothing with context %}
+
+{% if not pdocs %}
+ {{ nothing.render('Sorry, there is no problem in the problem set') }}
+{% else %}
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+ {% endif %}
+
+
+
+
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Status') }}
+ {% endif %}
+ {{ _('Problem') }}
+ {{ _('Submit') }}
+ % {{ _('AC') }}
+ {{ _('Difficulty') }}
+
+
+
+ {% for pdoc in pdocs %}
+ {% with psdoc = psdict[pdoc['doc_id']] %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {% if psdoc['rid'] %}
+ {{ record.render_status_td(psdoc, rid_key='rid') }}
+ {% else %}
+
+
+ {% endif %}
+ {% endif %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+
+
+
+
+
+
+
+
+ {% endif %}
+ {{ problem.render_problem_title(
+ pdoc,
+ rp=vj4.job.rp.get_rp_expect(pdoc) if (not psdoc or psdoc['status'] != vj4.constant.record.STATUS_ACCEPTED) else none
+ ) }}
+
+ {{ pdoc['num_submit'] }}
+ {{ (100 * pdoc['num_accept'] / pdoc['num_submit'])|round|int if pdoc['num_submit'] > 0 else _('?') }}
+ {{ pdoc['difficulty'] or _('(None)') }}
+
+ {% endwith %}
+ {% endfor %}
+
+
+ {{ paginator.render(page, ppcount) }}
+{% endif %}
+
diff --git a/templates/partials/problem_lucky.html b/templates/partials/problem_lucky.html
new file mode 100644
index 000000000..2750ab0ae
--- /dev/null
+++ b/templates/partials/problem_lucky.html
@@ -0,0 +1,8 @@
+
+
+ {{ _('Lucky') }}
+
+
+
{{ _('Pick a problem randomly based on current filter') }}
+
+
diff --git a/templates/partials/problem_sidebar.html b/templates/partials/problem_sidebar.html
new file mode 100644
index 000000000..d0fdbb8a2
--- /dev/null
+++ b/templates/partials/problem_sidebar.html
@@ -0,0 +1,15 @@
+{% if tdoc %}
+ {% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
+ {% include "partials/problem_sidebar_contest.html" %}
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/contest_sidebar.html" %}
+ {% endwith %}
+ {% else %}
+ {% include "partials/problem_sidebar_homework.html" %}
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/homework_sidebar.html" %}
+ {% endwith %}
+ {% endif %}
+{% else %}
+ {% include "partials/problem_sidebar_normal.html" %}
+{% endif %}
diff --git a/templates/partials/problem_sidebar_contest.html b/templates/partials/problem_sidebar_contest.html
new file mode 100644
index 000000000..6d07ee396
--- /dev/null
+++ b/templates/partials/problem_sidebar_contest.html
@@ -0,0 +1,42 @@
+{% import "components/user.html" as user with context %}
+
diff --git a/templates/partials/problem_sidebar_homework.html b/templates/partials/problem_sidebar_homework.html
new file mode 100644
index 000000000..cf3d03172
--- /dev/null
+++ b/templates/partials/problem_sidebar_homework.html
@@ -0,0 +1,42 @@
+{% import "components/user.html" as user with context %}
+
diff --git a/templates/partials/problem_sidebar_normal.html b/templates/partials/problem_sidebar_normal.html
new file mode 100644
index 000000000..9497adab7
--- /dev/null
+++ b/templates/partials/problem_sidebar_normal.html
@@ -0,0 +1,192 @@
+{% import "components/user.html" as user with context %}
+{% import "components/problem.html" as problem with context %}
+
+
+
+
+
+
+ {% if pdoc['doc_id']|string|length < 10 %}
+ {{ _('ID') }}
+ {{ pdoc['doc_id'] }}
+ {% endif %}
+ {% if page_name != 'discussion_node' and page_name != 'discussion_detail' %}
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Submission') }}
+
+ {% if pdoc['psdoc']['status'] %}
+
+
+ {{ vj4.constant.record.STATUS_TEXTS[pdoc['psdoc']['status']] }}
+
+ {% else %}
+ {{ _('(None)') }}
+ {% endif %}
+
+ {% if pdoc['ac_msg'] and pdoc['psdoc']['status'] == vj4.constant.record.STATUS_ACCEPTED %}
+ {{ _('AC Message') }}
+ {{ pdoc['ac_msg'] }}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {{ _('Difficulty') }}
+ {{ pdoc['difficulty'] or _('(None)') }}
+ {{ _('Category') }}
+
+ {% if pdoc['category'] %}
+
+ {% for category in pdoc['category'] %}
+ {{ category }}
+ {% if loop.index < pdoc['category']|length %}
+ {% if category in vj4.model.builtin.PROBLEM_CATEGORIES %}
+ {{ _('problem-category-delim') }}
+ {% else %}
+ {{ _('problem-subcategory-delim') }}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+
+
+ {{ _('page.problem_detail.sidebar.show_category') }}
+
+ {% else %}
+ {{ _('(None)') }}
+ {% endif %}
+
+ {{ _('Tags') }}
+
+ {{ problem.render_problem_tags(pdoc, true) }}
+
+ {{ _('# Submissions') }}
+ {{ pdoc['num_submit'] }}
+ {% if page_name != 'discussion_node' and page_name != 'discussion_detail' %}
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('# My Submissions') }}
+ {{ pdoc['psdoc']['num_submit']|default(0) }}
+ {% endif %}
+ {% endif %}
+ {{ _('Accepted') }}
+ {{ pdoc['num_accept'] }}
+ {{ _('Accepted Ratio') }}
+ {% if pdoc['num_submit'] > 0 %}{{ (100 * pdoc['num_accept'] / pdoc['num_submit'])|round|int }}%{% else %}{{ _('?') }}{% endif %}
+ {% if pdoc['num_be_copied'] %}
+ {{ _('Be Copied') }}
+ {{ pdoc['num_be_copied'] }}
+ {% endif %}
+ {% if pdoc['owner_uid'] != 0 %}
+ {{ _('Uploaded By') }}
+ {{ user.render_inline(owner_udoc, owner_dudoc, badge=false) }}
+ {% endif %}
+
+
+
+{% if page_name == 'problem_detail' and (tdocs or ctdocs) %}
+
+
+
+ {% if tdocs %}
+
{{ _('In following training plans') }}:
+ {% for tdoc in tdocs %}
+
{{ tdoc['title'] }}
+ {% endfor %}
+ {% endif %}
+ {% if ctdocs %}
+
{{ _('In following contests') }}:
+ {% for tdoc in ctdocs %}
+
{{ tdoc['title'] }}
+ {% endfor %}
+ {% endif %}
+ {% if htdocs %}
+
{{ _('In following homework') }}:
+ {% for tdoc in htdocs %}
+
{{ tdoc['title'] }}
+ {% endfor %}
+ {% endif %}
+
+
+{% endif %}
diff --git a/templates/partials/problem_stat.html b/templates/partials/problem_stat.html
new file mode 100644
index 000000000..8ce43767d
--- /dev/null
+++ b/templates/partials/problem_stat.html
@@ -0,0 +1,3 @@
+
+
{{ _('{0} problems').format(pcount) }}
+
diff --git a/templates/partials/training_default.json b/templates/partials/training_default.json
new file mode 100644
index 000000000..b86ec296a
--- /dev/null
+++ b/templates/partials/training_default.json
@@ -0,0 +1,14 @@
+[
+ {
+ "_id": 1,
+ "title": "最初的最初 - A+B Problem",
+ "require_nids": [],
+ "pids": [1000, "56c52ade2fefd90539000005"]
+ },
+ {
+ "_id": 2,
+ "title": "最初的进阶",
+ "require_nids": [1],
+ "pids": [1001, 1002]
+ }
+]
diff --git a/templates/problem_copy.html b/templates/problem_copy.html
new file mode 100644
index 000000000..e70192a35
--- /dev/null
+++ b/templates/problem_copy.html
@@ -0,0 +1,63 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
+
+ {{ _('Problem ID List') }}
+
+
+
+
+
+
+ {{ _('Copy') }}
+
+
+ {{ _('Cancel') }}
+
+
+
+
+
+
+
+
+
+
{{ _('What\'s this?') }}
+
{{ _('With this feature, you can copy problems that you can view from a domain to some other domain. Their title, content, tags and categories will be copied. However, their test data are not copied directly.') }}
+
{{ _('About test data') }}
+
{{ _('Instead of copying the test data directly, the test data of the copied problems will be linked to the test data of the source problems (called the source test data). Thus, the copied problems can observe the changes in the source test data. The permissions of the test data of the copied problems follow the source test data, e.g., you still might not download them but the judges can. By uploading some new test data, the link will be broken and the new test data will be used.') }}
+
+
+
+
+{% endblock %}
diff --git a/templates/problem_detail.html b/templates/problem_detail.html
new file mode 100644
index 000000000..7782816c4
--- /dev/null
+++ b/templates/problem_detail.html
@@ -0,0 +1,94 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
{{ _('Copy Problem To') }}
+
+
+
+
+ {{ _('Destination Domain') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if not pdoc['data'] %}
+
+ {{ _('No dataset at present.') }}
+
+ {% endif %}
+ {% if pdoc['data'] is mapping %}
+
+ {{ _('Test data comes from') }} {{ pdoc['data']['domain'] }}/{{ pdoc['data']['pid'] }}
+
+ {% endif %}
+ {% if tdoc %}
+ {% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
+ {% if handler.is_done(tdoc) %}
+
+ {{ _('You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.') }}
+
+ {% endif %}{# handler.is_done(tdoc) #}
+ {% else %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
+ {% if handler.is_homework_extended(tdoc) %}
+
+ {{ _('The homework\'s deadline is due but in extension. You can still submit for this problem but your score will be penalized.') }}
+
+ {% elif handler.is_done(tdoc) %}{# handler.is_homework_extended(tdoc) #}
+
+ {{ _('You cannot submit for this problem because the homework\'s deadline is due.') }}
+
+ {% endif %}{# handler.is_homework_extended(tdoc) #}
+ {% endif %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
+ {% endif %}{# tdoc #}
+ {{ pdoc['content']|markdown }}
+
+
+
+
+
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+
+
+
+{% endblock %}
diff --git a/templates/problem_edit.html b/templates/problem_edit.html
new file mode 100644
index 000000000..ad0e614cb
--- /dev/null
+++ b/templates/problem_edit.html
@@ -0,0 +1,70 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
+
+ {{ _('Content') }}
+ {% if pdoc %}{{ pdoc['content'] }}{% else %}{% include 'partials/problem_default.md' %}{% endif %}
+
+
+
+
+ {% if page_name == 'problem_edit' %}
+
+ {{ _('Update') }}
+
+ {% else %}
+
+ {{ _('Create') }}
+
+ {% endif %}
+
+ {{ _('Cancel') }}
+
+
+
+
+
+
+
+ {% if page_name == 'problem_edit' %}
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+ {% else %}
+ {% include 'components/md_hint.html' %}
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/problem_main.html b/templates/problem_main.html
new file mode 100644
index 000000000..14f315512
--- /dev/null
+++ b/templates/problem_main.html
@@ -0,0 +1,85 @@
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+ {% include "partials/problem_list.html" %}
+
+
+
+
+
+
+
+ {% for category, sub_categories in categories.items() %}
+
+
+ {% if sub_categories|length > 0 %}
+
+ {% for sub_category in sub_categories %}
+ {{ sub_category }}
+ {% endfor %}
+
+ {% endif %}
+
+ {% endfor %}
+
+
+ {% include "partials/problem_lucky.html" %}
+
+
+
+
+
+
+
+
+
+
+ {{ _('Search') }}
+
+
+
+ {% if handler.has_perm(vj4.model.builtin.PERM_CREATE_PROBLEM) %}
+
+
+
+
+
+
{{ _('You have permissions to create problems for this domain.') }}
+
+
+
+ {% endif %}
+
+
+ {% include "partials/problem_stat.html" %}
+
+
+
+{% endblock %}
diff --git a/templates/problem_settings.html b/templates/problem_settings.html
new file mode 100644
index 000000000..26f75f251
--- /dev/null
+++ b/templates/problem_settings.html
@@ -0,0 +1,73 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
{{ _('Hint') }}: {{ _('Dataset Format') }} , {{ _('An example of dataset') }}: {{ _('Download') }}
+ {% if pdoc and (handler.own(pdoc, vj4.model.builtin.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(vj4.model.builtin.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
+
{{ _('Download Dataset') }}
+ {% endif %}
+
+
+
+
+
+
+ {{ form.form_checkbox(label='Hidden', help_text='Note: Problem title may not be hidden.', name='hidden', value=pdoc['hidden']) }}
+ {{ form.form_text(columns=12, label='Category', help_text='Format: category 1, sub category 1.1, sub category 1.2, ..., sub category 1.x, ..., category n, sub category n.1, sub category n.2, ..., sub category n.m, ...', name='category', value=pdoc['category']|join(', ')) }}
+ {{ form.form_text(columns=12, label='Tags', help_text='Splitted by \', \'.', name='tag', value=pdoc['tag']|join(', ')) }}
+ {{ form.form_text(columns=12, label='AC Message', help_text='This message will be presented to those whose submissions are accepted.', name='ac_msg', value=(pdoc['ac_msg'] or '' )) }}
+
+ {{ form.form_select(columns=4, label='Difficulty', name='difficulty_setting', options=vj4.model.adaptor.problem.SETTING_DIFFICULTY_RANGE.items(), value=pdoc['difficulty_setting']|default(0), row=false) }}
+ {{ form.form_text(columns=4, label='Evaluated difficulty', help_text='Effects only when Difficulty is not \'Use algorithm calculated\'.', name='difficulty_admin', placeholder='9', value=pdoc['difficulty_admin'] or '', row=False) }}
+
+
{{ _('Difficulty displayed') }}: {{ pdoc['difficulty'] or _('(None)') }}
+
{{ _('Difficulty by algorithm') }}: {{ pdoc['difficulty_algo'] or _('(None)') }}
+
{{ _('Difficulty by admin') }}: {{ pdoc['difficulty_admin'] or _('(None)') }}
+
+
+
+
+
+ {{ _('Update') }}
+
+
+ {{ _('Cancel') }}
+
+
+
+
+
+
+
+
+
+ {% for category, sub_categories in categories.items() %}
+
+ {% endfor %}
+
+
+
+
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+
+
+{% endblock %}
diff --git a/templates/problem_solution.html b/templates/problem_solution.html
new file mode 100644
index 000000000..3c7755057
--- /dev/null
+++ b/templates/problem_solution.html
@@ -0,0 +1,49 @@
+{% extends "layout/basic.html" %}
+{% import "components/comments.html" as comments with context %}
+{% block content %}
+
+
+
+
+
+ {{ comments.render(
+ view = 'solution',
+ docs = psdocs,
+ udict = udict,
+ comment_ref = 'psid',
+ reply_ref = 'psrid',
+ comment_placeholder = 'Write Your Solution',
+ comment_post_op = 'submit',
+ comment_edit_op = 'edit_solution',
+ comment_post_text = 'Share',
+ reply_post_op = 'reply',
+ reply_edit_op = 'edit_reply',
+ comment_delete_op = 'delete_solution',
+ reply_delete_op = 'delete_reply',
+ comment_post_perm = vj4.model.builtin.PERM_CREATE_PROBLEM_SOLUTION,
+ comment_edit_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION,
+ comment_edit_self_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_SELF,
+ comment_delete_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION,
+ comment_delete_self_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_SELF,
+ reply_post_perm = vj4.model.builtin.PERM_REPLY_PROBLEM_SOLUTION,
+ reply_edit_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_REPLY,
+ reply_edit_self_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_REPLY_SELF,
+ reply_delete_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_REPLY,
+ reply_delete_self_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_REPLY_SELF
+ ) }}
+ {{ paginator.render(page, pcount) }}
+ {% if drcount == 0 %}
+ {{ nothing.render('No solutions so far...') }}
+ {% endif %}
+
+
+
+
+ {% with owner_udoc=udict[pdoc['owner_uid']], owner_dudoc=dudict[pdoc['owner_uid']] %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+
+
+{% endblock %}
diff --git a/templates/problem_statistics.html b/templates/problem_statistics.html
new file mode 100644
index 000000000..754b90865
--- /dev/null
+++ b/templates/problem_statistics.html
@@ -0,0 +1,20 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+ {{ _('Swx Template') }}
+
+
+
+
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+
+
+{% endblock %}
diff --git a/templates/problem_submit.html b/templates/problem_submit.html
new file mode 100644
index 000000000..16b2bed0b
--- /dev/null
+++ b/templates/problem_submit.html
@@ -0,0 +1,64 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+ {% if not tdoc or rdocs %}
+
+
+
+ {% if not rdocs %}
+ {{ nothing.render('You have not submitted any solutions for this problem') }}
+ {% else %}
+
+
+
+
+
+
+
+
+
+
+ {{ _('Status') }}
+ {{ _('Pretest?') }}
+ {{ _('Peak Memory') }}
+ {{ _('Total Time') }}
+ {{ _('Submit At') }}
+
+
+
+ {% for rdoc in rdocs %}
+ {% include 'problem_submit_tr.html' %}
+ {% endfor %}
+
+
+ {% endif %}
+
+
+ {% endif %}
+
+
+
+
+ {{ form.form_select(label='Code language', options=vj4.constant.language.LANG_TEXTS.items(), name='lang', value=handler.get_setting('code_lang')) }}
+ {{ form.form_textarea(label='Code', columns=12, name='code', extra_class='monospace', autofocus=true) }}
+
+
+
+
+
+
+ {% with owner_udoc=udoc, owner_dudoc=dudoc %}
+ {% include "partials/problem_sidebar.html" %}
+ {% endwith %}
+
+
+
+{% endblock %}
diff --git a/templates/problem_submit_tr.html b/templates/problem_submit_tr.html
new file mode 100644
index 000000000..052c6d9df
--- /dev/null
+++ b/templates/problem_submit_tr.html
@@ -0,0 +1,18 @@
+{% import "components/record.html" as record with context %}
+
+ {{ record.render_status_td(rdoc) }}
+
+ {% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST %}
+ {{ _('Yes') }}
+ {% else %}
+ {{ _('No') }}
+ {% endif %}
+
+
+ {{ (rdoc['memory_kb'] / 1000)|round(0, 'ceil')|int }} MB
+
+
+ {{ (rdoc['time_ms'] / 1000)|round(1) }}s
+
+ {{ datetime_span(rdoc['_id'].generation_time) }}
+
diff --git a/templates/problem_upload.html b/templates/problem_upload.html
new file mode 100644
index 000000000..e534e73e9
--- /dev/null
+++ b/templates/problem_upload.html
@@ -0,0 +1,17 @@
+{% extends 'layout/simple.html' %}
+{% block body %}
+
+{% if pdoc['data'] is mapping %}
+{{ _('Current dataset comes from') }} {{ pdoc['data']['domain'] }}/{{ pdoc['data']['pid'] }}
+{% else %}
+{{ _('Current dataset: {0}').format(pdoc['data']|default(_('(None)'))) }}
+{{ _('MD5: {0}').format(md5|default(_('(None)'))) }}
+{% endif %}
+
+{{ _('New dataset') }}:
+
+
+
+
+
+{% endblock %}
diff --git a/templates/record_detail.html b/templates/record_detail.html
new file mode 100644
index 000000000..de5709a52
--- /dev/null
+++ b/templates/record_detail.html
@@ -0,0 +1,112 @@
+{% extends "layout/basic.html" %}
+{% import "components/problem.html" as problem with context %}
+{% block content %}
+
+
+
+ {% if show_status %}
+ {% include 'record_detail_status.html' %}
+ {% endif %}
+ {% if rdoc['code'] %}
+
+ {% endif %}
+
+
+
+
+ {% if handler.has_perm(vj4.model.builtin.PERM_REJUDGE) %}
+
+
+
+ {% endif %}
+
+
+ {{ _('Submit By') }}
+ {{ user.render_inline(udoc, dudoc, modbadge=false) }}
+ {{ _('Type') }}
+ {{ _(vj4.constant.record.TYPE_TEXTS[rdoc['type']]) }}
+ {% if pdoc %}
+ {{ _('Problem') }}
+
+ {{ problem.render_problem_title(pdoc, tdoc, show_tags=false, show_invisible_flag=false, rp=none) }}
+
+ {% endif %}
+ {% if tdoc %}
+ {% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
+ {{ _('Contest') }}
+
+ {{ tdoc['title'] }}
+
+ {% else %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
+ {{ _('Homework') }}
+
+ {{ tdoc['title'] }}
+
+ {% endif %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
+ {% endif %}{# tdoc #}
+ {% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST and (handler.own(rdoc, priv=vj4.model.builtin.PRIV_READ_PRETEST_DATA_SELF, field='uid') or handler.has_priv(vj4.model.builtin.PRIV_READ_PRETEST_DATA)) %}
+ {{ _('Pretest Data') }}
+ {{ _('Download') }}
+ {% elif rdoc['type'] == vj4.constant.record.TYPE_SUBMISSION and pdoc and (handler.own(pdoc, vj4.model.builtin.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(vj4.model.builtin.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
+ {{ _('Problem Data') }}
+ {{ _('Download') }}
+ {% endif %}
+ {{ _('Language') }}
+
+ {{ vj4.constant.language.LANG_TEXTS[rdoc['lang']] }}
+
+
+ {{ _('Submit At') }}
+
+
+ {{ datetime_span(rdoc['_id'].generation_time) }}
+
+ {% if rdoc['judge_at'] %}
+ {{ _('Judged At') }}
+ {{ datetime_span(rdoc['judge_at']) }}
+ {% endif %}
+ {% if judge_udoc %}
+ {{ _('Judged By') }}
+ {{ user.render_inline(judge_udoc, badge=false) }}
+ {% endif %}
+
+ {% if show_status %}
+ {% include 'record_detail_summary.html' %}
+ {% endif %}
+
+
+
+
+{% endblock %}
diff --git a/templates/record_detail_status.html b/templates/record_detail_status.html
new file mode 100644
index 000000000..773f00ed6
--- /dev/null
+++ b/templates/record_detail_status.html
@@ -0,0 +1,57 @@
+
+
+
+
{{ rdoc['compiler_texts']|join('\n') }}
+
+{% if rdoc['judge_texts'] %}
+
+
{{ rdoc['judge_texts']|join('\n') }}
+
+{% endif %}
+{% if rdoc['cases'] %}
+
+
+
+
+
+
+
+
+
+
+ #
+ {{ _('Status') }}
+ {{ _('Time Cost') }}
+ {{ _('Memory Cost') }}
+
+
+
+ {% for rcdoc in rdoc['cases'] %}
+
+
+ #{{ loop.index }}
+
+
+
+
+ {{ vj4.constant.record.STATUS_TEXTS[rcdoc['status']] }}
+
+ {{ rcdoc['judge_text'] }}
+
+
+ {% if rcdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rcdoc['time_ms'] }}ms
+ {% if rcdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rcdoc['memory_kb']|format_size(1024) }}
+
+ {% endfor %}
+
+
+
+{% endif %}
+
diff --git a/templates/record_detail_summary.html b/templates/record_detail_summary.html
new file mode 100644
index 000000000..dfc66d3fe
--- /dev/null
+++ b/templates/record_detail_summary.html
@@ -0,0 +1,10 @@
+
+ {% if rdoc['score'] is defined %}
+ {{ _('Score') }}
+ {{ rdoc['score'] }}
+ {% endif %}
+ {{ _('Total Time') }}
+ {% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc['time_ms'] }}ms
+ {{ _('Peak Memory') }}
+ {% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc['memory_kb']|format_size(1024) }}
+
diff --git a/templates/record_main.html b/templates/record_main.html
new file mode 100644
index 000000000..db52a4747
--- /dev/null
+++ b/templates/record_main.html
@@ -0,0 +1,110 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
+
+ {% if not rdocs %}
+ {% if not filter_uid_or_name and not filter_pid and not filter_tid %}
+ {{ nothing.render('Oh, there is no task in the queue!') }}
+ {% else %}
+ {{ nothing.render('Oh, there is no task that matches the filter!') }}
+ {% endif%}
+ {% else %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ _('Status') }}
+ {{ _('Problem') }}
+ {{ _('Submit By') }}
+ {{ _('Time') }}
+ {{ _('Memory') }}
+ {{ _('Language') }}
+ {{ _('Submit At') }}
+
+
+
+ {% for rdoc in rdocs %}
+ {% with udoc = udict[rdoc['uid']], dudoc = dudict[rdoc['uid']], pdoc = pdict[(rdoc['domain_id'], rdoc['pid'])] %}
+ {% include 'record_main_tr.html' %}
+ {% endwith %}
+ {% endfor %}
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_VIEW_JUDGE_STATISTICS) %}
+
+ {% endif %}
+ {% endif %}
+
+
+ {% if statistics %}
+
+
+
+
+ {{ _('Day') }} {{ statistics['day'] }}
+ {{ _('Week') }} {{ statistics['week'] }}
+ {{ _('Month') }} {{ statistics['month'] }}
+ {{ _('Year') }} {{ statistics['year'] }}
+ {{ _('Total') }} {{ statistics['total'] }}
+
+
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/record_main_tr.html b/templates/record_main_tr.html
new file mode 100644
index 000000000..f630c69ef
--- /dev/null
+++ b/templates/record_main_tr.html
@@ -0,0 +1,37 @@
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+
+ {{ record.render_status_td(rdoc) }}
+
+ {% if (rdoc['domain_id'] == handler.domain_id and handler.has_perm(vj4.model.builtin.PERM_REJUDGE)) or handler.has_priv(vj4.model.builtin.PRIV_REJUDGE) %}
+
+
+
+
+ {{ _('Rejudge') }}
+ |
+
+ {% endif %}
+ {% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST %}
+ ({{ _('Pretest') }})
+ {% endif %}
+ {% if pdoc and (not pdoc['hidden'] or (pdoc['domain_id'] == handler.domain_id and handler.has_perm(vj4.model.builtin.PERM_VIEW_PROBLEM_HIDDEN))) %}
+ {{ problem.render_problem_title(pdoc, show_tags=false) }}
+ {% else %}
+ *
+ {% endif %}
+
+
+
+ {% if dudoc['display_name'] %}
+ {{ dudoc['display_name'] }} ({{ udoc['uname'] }})
+ {% else %}
+ {{ udoc['uname'] }}
+ {% endif %}
+
+
+ {% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc['time_ms'] }}ms
+ {% if rdoc['status'] == vj4.constant.record.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == vj4.constant.record.STATUS_OUTPUT_LIMIT_EXCEEDED %}≥{% endif %}{{ rdoc['memory_kb']|format_size(1024) }}
+ {{ vj4.constant.language.LANG_TEXTS[rdoc['lang']] }}
+ {{ datetime_span(rdoc['_id'].generation_time) }}
+
diff --git a/templates/training_detail.html b/templates/training_detail.html
new file mode 100644
index 000000000..cff56ed7e
--- /dev/null
+++ b/templates/training_detail.html
@@ -0,0 +1,205 @@
+{% import "components/record.html" as record with context %}
+{% import "components/problem.html" as problem with context %}
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+ {{ tdoc['content'] }}
+
+
+ {{ tdoc['desc']|default('')|markdown }}
+
+
+
+ {% if not tsdoc['enroll'] %}
+
+
+ {{ _('page.training_detail.invalid_when_not_enrolled') }}
+
+
+ {% endif %}
+ {% for node in tdoc['dag'] %}
+
+
+
+
+ {% if nsdict[node['_id']]['is_invalid'] %}
+
+
+ {{ _('This section cannot be challenged at present, so please complete the following sections first') }}:
+
+ {% for nid in node['require_nids'] %}
+ {{ _('Section') }} {{ _(nid) }}. {{ ndict[nid]['title'] }} ({{ _('Completed') }} {{ nsdict[nid]['progress'] }}%)
+ {% endfor %}
+
+
+
+ {% endif %}
+ {% if node['content'] %}
+
+ {{ node['content']|markdown }}
+
+ {% endif %}
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+ {% endif %}
+
+
+
+
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Status') }}
+ {% endif %}
+ {{ _('Problem') }}
+ {{ _('Submit') }}
+ % {{ _('AC') }}
+ {{ _('Difficulty') }}
+
+
+
+ {% for pid in node['pids'] %}
+ {% if pid in pdict %}
+ {% with pdoc=pdict[pid], psdoc=psdict[pid] %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {% if psdoc['rid'] %}
+ {{ record.render_status_td(psdoc, rid_key='rid') }}
+ {% else %}
+
+ {% endif %}
+ {% endif %}
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+
+
+
+
+
+
+
+
+ {% endif %}
+ {{ problem.render_problem_title(
+ pdoc,
+ invalid=not tsdoc['enroll'],
+ show_tags=false,
+ rp=vj4.job.rp.get_rp_expect(pdoc) if (not psdoc or psdoc['status'] != vj4.constant.record.STATUS_ACCEPTED) else none
+ ) }}
+
+ {{ pdoc['num_submit'] }}
+ {{ (100 * pdoc['num_accept'] / pdoc['num_submit'])|round|int if pdoc['num_submit'] > 0 else _('?') }}
+ {{ pdoc['difficulty'] or _('(None)') }}
+
+ {% endwith %}
+ {% else %}
+ {% with pdoc = {'domain_id': handler.domain_id, 'doc_id': pid, 'hidden': true, 'title': '*'} %}
+
+
+
+
+ {{ problem.render_problem_title(pdoc, invalid=true) }}
+
+ *
+ *
+ *
+
+ {% endwith %}
+ {% endif %}
+ {% endfor %}
+
+
+
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+ {{ _('Status') }} {% if tsdoc['enroll'] %}{{ _('Completed' if tsdoc['done'] else 'In Progress') }}{% else %}{{ _('Not Enrolled') }}{% endif %}
+ {% endif %}
+ {% if tsdoc['enroll'] %}
+ {{ _('Progress') }} {{ _('Completed') }} {{ (100 * tsdoc['done_pids']|length / pids|length)|round|int }}%
+ {% endif %}
+ {{ _('Enrollees') }} {{ tdoc['enroll']|default(0) }}
+ {{ _('Created By') }}
+ {{ user.render_inline(owner_udoc, owner_dudoc, badge=false) }}
+
+
+
+
+
+{% endblock %}
diff --git a/templates/training_edit.html b/templates/training_edit.html
new file mode 100644
index 000000000..81911e786
--- /dev/null
+++ b/templates/training_edit.html
@@ -0,0 +1,58 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
+
+ {{ _('Title') }}
+
+
+
+
+
+
+ {{ _('Introduce') }}
+ {{ tdoc['content']|default('') }}
+ {{ _('Introduce must not exceed 500 characters and it will be shown in the list view.') }}
+
+
+
+
+ {{ _('Description') }}
+ {{ tdoc['desc']|default('') }}
+
+
+
+
+ {{ _('Plan') }}
+ {% if tdoc %}{{ dag }}{% else %}{% include 'partials/training_default.json' %}{% endif %}
+
+
+
+
+ {% if page_name == 'training_edit' %}
+
+ {{ _('Update') }}
+
+ {% else %}
+
+ {{ _('Create') }}
+
+ {% endif %}
+
+ {{ _('Cancel') }}
+
+
+
+
+
+
+
+ {% include 'components/md_hint.html' %}
+
+
+{% endblock %}
diff --git a/templates/training_main.html b/templates/training_main.html
new file mode 100644
index 000000000..ffae8b5c0
--- /dev/null
+++ b/templates/training_main.html
@@ -0,0 +1,98 @@
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+ {% if not tdocs %}
+ {{ nothing.render('Sorry, there is no training plan.') }}
+ {% else %}
+
+ {% for tdoc in tdocs %}
+
+
+
+ {% endfor %}
+
+ {{ paginator.render(page, tpcount, add_qs=qs) }}
+ {% endif %}
+
+
+
+ {% if handler.has_priv(vj4.model.builtin.PRIV_USER_PROFILE) %}
+
+
+
+
+ {% for tsdoc in tsdict.values() %}
+ {% if tsdoc['enroll'] %}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+ {% endif %}
+ {% if handler.has_perm(vj4.model.builtin.PERM_CREATE_TRAINING) %}
+
+
+
+
+
+
{{ _('You can create your own training plans and share with others.') }}
+
+
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/user_changemail_mail.html b/templates/user_changemail_mail.html
new file mode 100644
index 000000000..a3c4f19de
--- /dev/null
+++ b/templates/user_changemail_mail.html
@@ -0,0 +1,6 @@
+{% extends "layout/mail.html" %}
+{% block title %}{{ _('Change Email') }}{% endblock %}
+{% block content %}
+{{ _('Hello, {0}! You can click following link to active your new email of your Vijos account:').format(uname) }}
+{{ url_prefix }}{{ url }}
+{% endblock %}
diff --git a/templates/user_changemail_mail_sent.html b/templates/user_changemail_mail_sent.html
new file mode 100644
index 000000000..2475cf394
--- /dev/null
+++ b/templates/user_changemail_mail_sent.html
@@ -0,0 +1,9 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
{{ _('New Email') }}
+
+ {{ _('Confirmation mail has been sent to your new email.') }}
+
+
+{% endblock %}
diff --git a/templates/user_detail.html b/templates/user_detail.html
new file mode 100644
index 000000000..e7dd8a21e
--- /dev/null
+++ b/templates/user_detail.html
@@ -0,0 +1,231 @@
+{% import "components/home.html" as home with context %}
+{% extends "layout/basic.html" %}
+{% block content %}
+
+
+
+
+
+
+
+
+ {{ _('Discussions') }} ({{ dcount }})
+
+ {% if not ddocs %}
+ {{ nothing.render('Oh, the user hasn\'t created any discussions yet!') }}
+ {% else %}
+
+
+ {% with udict = {udoc['_id']: udoc} %}
+ {% include "partials/discussion_list.html" %}
+ {% endwith %}
+
+ {% endif %}
+
+
+
+ {{ _('Contributions') }} ({{ pcount + pscount }})
+
+ {% if not pdocs and not psdocs %}
+ {{ nothing.render('Oh, the user doesn\'t have any contributions!') }}
+ {% else %}
+ {% if pdocs %}
+
+
+ {% for pdoc in pdocs %}
+
{{ pdoc['title'] }}
+ {% endfor %}
+
+ {% endif %}{# if pdocs #}
+ {% if psdocs %}
+
+
+ {% for psdoc in psdocs_hot %}
+
PS{{ psdoc['doc_id'] }}
+ {% endfor %}
+
+
+
+ {% for psdoc in psdocs %}
+
PS{{ psdoc['doc_id'] }}
+ {% endfor %}
+
+ {% endif %}{# if psdocs #}
+ {% endif %}{# if not pdocs and not psdocs #}
+
+
+
+ {{ _('Submissions') }} ({{ dudoc['num_submit']|default(0) }})
+
+ {% if not rdocs %}
+ {{ nothing.render('Oh, the user hasn\'t submitted yet!') }}
+ {% else %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ _('Status') }}
+ {{ _('Problem') }}
+ {{ _('Submit By') }}
+ {{ _('Time') }}
+ {{ _('Memory') }}
+ {{ _('Language') }}
+ {{ _('Submit At') }}
+
+
+
+ {% for rdoc in rdocs %}
+ {% with pdoc = pdict[(rdoc['domain_id'], rdoc['pid'])] %}
+ {% include 'record_main_tr.html' %}
+ {% endwith %}
+ {% endfor %}
+
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+ {% if is_self_profile %}
+ {{ home.render_sidebar() }}
+ {% endif %}
+
+ {% if handler.can_view(udoc, 'bio') %}
+
+
+
+ {% if udoc['bio'] and udoc['bio']|length > 0 %}
+ {{ udoc['bio']|markdown }}
+ {% else %}
+ {{ _('The user is too lazy to leave something here...') }}
+ {% endif %}
+
+
+ {% endif %}
+
+
+{% endblock %}
diff --git a/templates/user_login.html b/templates/user_login.html
new file mode 100644
index 000000000..8136eb12b
--- /dev/null
+++ b/templates/user_login.html
@@ -0,0 +1,37 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
+
{{ _('Login') }}
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/user_logout.html b/templates/user_logout.html
new file mode 100644
index 000000000..5ca187d5a
--- /dev/null
+++ b/templates/user_logout.html
@@ -0,0 +1,14 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
+
{{ _('Logout') }}
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/user_lostpass.html b/templates/user_lostpass.html
new file mode 100644
index 000000000..6a6916036
--- /dev/null
+++ b/templates/user_lostpass.html
@@ -0,0 +1,21 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
+
{{ _('Lost Password') }}
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/user_lostpass_mail.html b/templates/user_lostpass_mail.html
new file mode 100644
index 000000000..8a011d0f9
--- /dev/null
+++ b/templates/user_lostpass_mail.html
@@ -0,0 +1,6 @@
+{% extends "layout/mail.html" %}
+{% block title %}{{ _('Lost Password') }}{% endblock %}
+{% block content %}
+{{ _('Hello, {0}! You can click following link to reset the password of your Vijos account:').format(uname) }}
+{{ url_prefix }}{{ url }}
+{% endblock %}
diff --git a/templates/user_lostpass_mail_sent.html b/templates/user_lostpass_mail_sent.html
new file mode 100644
index 000000000..bbeeb936e
--- /dev/null
+++ b/templates/user_lostpass_mail_sent.html
@@ -0,0 +1,9 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
{{ _('Lost Password') }}
+
+ {{ _('Password reset mail has been sent to your email.') }}
+
+
+{% endblock %}
diff --git a/templates/user_lostpass_with_code.html b/templates/user_lostpass_with_code.html
new file mode 100644
index 000000000..529fbb8d4
--- /dev/null
+++ b/templates/user_lostpass_with_code.html
@@ -0,0 +1,29 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+{% endblock %}
diff --git a/templates/user_register.html b/templates/user_register.html
new file mode 100644
index 000000000..b392d1a50
--- /dev/null
+++ b/templates/user_register.html
@@ -0,0 +1,21 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
+
{{ _('Sign Up') }}
+
+
+
+
+
+
+{% endblock %}
diff --git a/templates/user_register_mail.html b/templates/user_register_mail.html
new file mode 100644
index 000000000..50e9a38f0
--- /dev/null
+++ b/templates/user_register_mail.html
@@ -0,0 +1,6 @@
+{% extends "layout/mail.html" %}
+{% block title %}{{ _('Sign Up') }}{% endblock %}
+{% block content %}
+{{ _('Hello! You can click following link to sign up your Vijos account:') }}
+{{ url_prefix }}{{ url }}
+{% endblock %}
diff --git a/templates/user_register_mail_sent.html b/templates/user_register_mail_sent.html
new file mode 100644
index 000000000..1167c7c8f
--- /dev/null
+++ b/templates/user_register_mail_sent.html
@@ -0,0 +1,9 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+
{{ _('Sign Up') }}
+
+ {{ _('Sign up mail has been sent to your email.') }}
+
+
+{% endblock %}
diff --git a/templates/user_register_with_code.html b/templates/user_register_with_code.html
new file mode 100644
index 000000000..0b46a43e0
--- /dev/null
+++ b/templates/user_register_with_code.html
@@ -0,0 +1,35 @@
+{% extends "layout/immersive.html" %}
+{% block content %}
+
+{% endblock %}
diff --git a/templates/wiki_help.html b/templates/wiki_help.html
new file mode 100644
index 000000000..315aa3e4d
--- /dev/null
+++ b/templates/wiki_help.html
@@ -0,0 +1,198 @@
+{% extends "layout/wiki_base.html" %}
+{% block wiki_content %}
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
每个用户可以创建自己的域。比如,老师可以为课程创建一个域,然后把题目和学生加入到此域中。再如,可以把域作为团队功能。
+
通过合理的设置角色及其权限,可以把域设为公开或私有。
+
默认域为Vijos,用户直接访问Vijos域名就会访问此域,点击Vijos Logo会从任意域跳转回Vijos域。
+
每个域的题库、讨论、训练以及比赛是独立且自治的。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos使用jd4 进行评测,以docker镜像的形式安装至评测机。所使用的编译器均为创建镜像时debian testing 分支的最新版。编译参数如下:
+
+ Free Pascal fpc -O2 -o/out/foo /in/foo.pas
+ C gcc -O2 -Wall -std=c99 -o /out/foo /in/foo.c -lm
+ C++ g++ -O2 -Wall -std=c++11 -o /out/foo /in/foo.cc -lm
+ Java javac Main.java
+ Python python foo.py
+ Python 3 python3 foo.py
+ PHP php foo.php
+ Rust rustc -O -o /out/foo /in/foo.rs
+ Haskell ghc -O -outputdir /tmp -o /out/foo /in/foo.hs
+
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。
Vijos 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos 支持且仅支持标准输入输出(控制台输入输出,屏幕输入输出,STD I/O),不支持文件输入输出。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
+ Waiting 评测:评测请求正在等待被评测机抓取
+ Fetched 评测:评测请求已被评测机抓取,正在准备开始评测
+ Compiling 评测:正在编译中
+ Judging 评测:编译成功,正在评测中
+ Accepted 通过:程序输出完全正确
+ Wrong Answer 不通过:程序输出与标准答案不一致(不包括行末空格以及文件末空行)
+ Time Exceeded 不通过:程序运行时间超过了题目限制
+ Memory Exceeded 不通过:程序运行内存空间超过了题目限制
+ Runtime Error 不通过:程序运行时错误(如数组越界、被零除、运算溢出、栈溢出、无效指针等)
+ Compile Error 不通过:编译失败
+ System Error 错误:系统错误(如果您遇到此问题,请及时在讨论区进行反馈)
+ Canceled 其他:评测被取消
+ Unknown Error 其他:未知错误
+ Ignored 其他:被忽略
+
+
有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
可能有以下情况:
+
+ 1. 递交时选错了编程语言
+ 2. Java 的主类名没有使用 "Main"
+ 3. 对于 C/C++:见下
+ 4. 一般性的编译错误
+
+
+
+ 对 C/C++ 选手的特别提醒:
+
+ 1. __int64 在 GNU C++ 中应写成 long long 类型
+ 2. main() 返回值必须定义为 int ,而不是 void
+ 3. for 语句中的指标变量 i 将会在如"for (int i = 0...) {...}"语句之后变为无效
+ 4. itoa 不是一个通用 ANSI 函数(标准 C/C++ 中无此函数)
+ 5. printf 中使用 %lf 格式是不正确的
+
+
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入!
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
按照赛制不同,有不同的递交、排名规则。
+
OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。
+
OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。
+
ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。
+
ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。
+
时间与空间限制以题目说明为准,默认限制参见{{ _('Limitations') }} 。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
通过率的影响极其恶劣,现在 Vijos 不提供也不承认通过率。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。
+
浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。
+
每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
Vijos 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。
+
因此,请注意以下几点:
+
+ 0. 一般地,难度的数值越大,该题目越难。
+ 1. 新题目的难度可能不准确;在题目获得大量递交之后,难度才会变得较为准确。
+ 2. 越早递交评测的用户代码的评测结果对题目难度影响越大。
+ 3. 题目的难度由算法计算得出,有可能出现不准确的结果。
+
+
+
+
+
+
+ {{ _('no_translation_warn')|safe }}
+
我们只接受后缀名为zip的数据包上传,必须包含以下内容:
+
+ - Config.ini: 题目配置文件
+ + Input (目录): 放置所有标准测试输入文件
+ |- input0.txt
+ |- input1.txt
+ |- ...
+ + Output (目录): 放置所有标准测试输出文件
+ |- output0.txt
+ |- output1.txt
+ |- ...
+
+
Config.ini格式
+ 第一行包含一个整数n,表示总共有n组数据(即Input目录中文件总数等于Output目录中文件总数等于n);
+ 接下来n行,第k行代表第k个测试点,格式为:
[输入文件名]|[输出文件名]|[时限(单位为秒)]|[得分]|[内存限制(单位为KiB)]
+ 其中,输入和输出文件名为 Input 或者 Output 目录中的文件名(不包含Input或者Output目录),且所有数据点得分之和必须为100,如:
+ input0.txt|output0.txt|1|10|
+
+
+
+{% endblock %}