diff --git a/build/buildModule.js b/build/buildModule.js index f798c24a9..b1b0c2da9 100644 --- a/build/buildModule.js +++ b/build/buildModule.js @@ -1,4 +1,6 @@ +/* eslint-disable import/no-dynamic-require */ /* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable no-await-in-loop */ const fs = require('fs'); const webpack = require('webpack'); const yaml = require('js-yaml'); @@ -59,12 +61,17 @@ const build = async (type) => { const lang = {}; for (const j of locales) { const content = fs.readFileSync(root(`module/${i}/locale/${j}`)).toString(); - lang[i.split('.')[0]] = yaml.safeLoad(content); + lang[j.split('.')[0]] = yaml.safeLoad(content); } const file = root(`.build/module/${i}/locale.json`); fs.writeFileSync(file, JSON.stringify(lang)); } - if (exist(`module/${i}/template`)) { + if (exist(`module/${i}/template.build.js`)) { + const builder = require(root(`module/${i}/template.build.js`)); + const [templates, exclude] = await builder.prebuild(); + const file = root(`.build/module/${i}/template.yaml`); + fs.writeFileSync(file, yaml.safeDump(template(templates, exclude))); + } else if (exist(`module/${i}/template`)) { const file = root(`.build/module/${i}/template.yaml`); fs.writeFileSync(file, yaml.safeDump(template(`module/${i}/template`))); } diff --git a/build/template.js b/build/template.js index 6f3ec9e26..086170e45 100644 --- a/build/template.js +++ b/build/template.js @@ -15,13 +15,18 @@ function getFiles(folder) { return files; } -const build = (dir, exclude = []) => { - const files = getFiles(dir); - const templates = {}; - for (const i of files) { - let template = fs.readFileSync(root(`${dir}/${i}`)).toString(); +const build = (dirOrObject, exclude = []) => { + let templates = {}; + if (typeof dirOrObject === 'string') { + const files = getFiles(dirOrObject); + for (const i of files) { + const template = fs.readFileSync(root(`${dirOrObject}/${i}`)).toString(); + templates[i] = template; + } + } else templates = dirOrObject; + for (const i in templates) { if (!exclude.includes(i)) { - template = template + templates[i] = templates[i] .trim() .replace(/ *\n */gmi, ' ') .replace(/, /gmi, ',') @@ -35,7 +40,6 @@ const build = (dir, exclude = []) => { .replace(/ }}/gmi, '}}') .trim(); } - templates[i] = template; } return templates; }; diff --git a/hydro/handler/discussion.js b/hydro/handler/discussion.js index 504d75f72..addd03f06 100644 --- a/hydro/handler/discussion.js +++ b/hydro/handler/discussion.js @@ -68,9 +68,13 @@ class DiscussionMainHandler extends DiscussionHandler { constants.DISCUSSION_PER_PAGE, ); const udict = await user.getList(ddocs.map((ddoc) => ddoc.owner)); + const path = [ + ['Hydro', '/'], + ['discussion_main', null], + ]; this.response.template = 'discussion_main_or_node.html'; this.response.body = { - ddocs, dpcount, udict, page, page_name: 'discussion_main', vnode: {}, + ddocs, dpcount, udict, page, page_name: 'discussion_main', vnode: {}, path, }; } } diff --git a/hydro/handler/training.js b/hydro/handler/training.js index 568dbfccb..94a4cff14 100644 --- a/hydro/handler/training.js +++ b/hydro/handler/training.js @@ -80,9 +80,13 @@ class TrainingMainHandler extends TrainingHandler { if (enrolledTids.size) tdict = await training.getList(Array.from(enrolledTids)); } for (const tdoc in tdocs) tdict[tdoc._id] = tdoc; + const path = [ + ['Hydro', '/'], + ['training_main', null], + ]; this.response.template = 'training_main.html'; this.response.body = { - tdocs, page, tpcount, qs, tsdict, tdict, + tdocs, page, tpcount, qs, tsdict, tdict, path, }; } } @@ -154,8 +158,13 @@ class TrainingCreateHandler extends TrainingHandler { } async get() { + const path = [ + ['Hydro', '/'], + ['problem_main', '/t'], + ['problem_create', null], + ]; this.response.template = 'training_edit.html'; - this.response.body = { page_name: 'training_create' }; + this.response.body = { page_name: 'training_create', path }; } async post({ diff --git a/hydro/lib/i18n.js b/hydro/lib/i18n.js index 04626397b..6dd42558a 100644 --- a/hydro/lib/i18n.js +++ b/hydro/lib/i18n.js @@ -28,7 +28,9 @@ String.prototype.rawformat = function rawFormat(object) { }; String.prototype.translate = function translate(language = 'zh_CN') { - if (locales[language]) return locales[language][this] || this; + if (locales[language]) { + if (locales[language][this] !== undefined) return locales[language][this]; + } return this; }; diff --git a/hydro/lib/template.js b/hydro/lib/template.js index 66e1c997a..05aab58f8 100644 --- a/hydro/lib/template.js +++ b/hydro/lib/template.js @@ -7,7 +7,7 @@ const misc = require('./misc'); function Loader() { } Loader.prototype.getSource = function getSource(name) { - if (!global.Hydro.template[name]) throw new Error(); + if (!global.Hydro.template[name]) throw new Error(`Cannot get template ${name}`); return { src: global.Hydro.template[name], path: name, diff --git a/hydro/loader.js b/hydro/loader.js index ec63046e4..0eed0b4f1 100644 --- a/hydro/loader.js +++ b/hydro/loader.js @@ -35,13 +35,13 @@ async function handler() { } async function locale() { - if (exist('.build/locale.js')) { - global.Hydro.lib.i18n(superRequire('.build/locale.js')); + if (exist('.build/locale.json')) { + global.Hydro.lib.i18n(superRequire('.build/locale.json')); console.log('Locale init: builtin'); } for (const i of installed) { - if (exist(`.build/module/${i}/locale.js`)) { - global.Hydro.lib.i18n(superRequire(`.build/module/${i}/locale.js`)); + if (exist(`.build/module/${i}/locale.json`)) { + global.Hydro.lib.i18n(superRequire(`.build/module/${i}/locale.json`)); console.log(`Locale init: ${i}`); } } @@ -54,7 +54,7 @@ async function template() { console.log('Template init: builtin'); } for (const i of installed) { - if (exist(`.build/module/${i}/locale.js`)) { + if (exist(`.build/module/${i}/template.yaml`)) { const file = fs.readFileSync(root(`.build/module/${i}/template.yaml`)).toString(); Object.assign(global.Hydro.template, yaml.safeLoad(file)); console.log(`Template init: ${i}`); diff --git a/module/wiki/handler.js b/module/wiki/handler.js new file mode 100644 index 000000000..1ee29bc85 --- /dev/null +++ b/module/wiki/handler.js @@ -0,0 +1,34 @@ +const { Route, Handler } = global.Hydro.service.server; + +class WikiHelpHandler extends Handler { + async get() { + const path = [ + ['Hydro', '/'], + ['wiki', '/wiki'], + ['wiki_help', null], + ]; + this.response.body = { path }; + this.response.template = 'wiki_help.html'; + } +} + +class WikiAboutHandler extends Handler { + async get() { + const path = [ + ['Hydro', '/'], + ['wiki', '/wiki'], + ['wiki_about', null], + ]; + this.response.body = { path }; + this.response.template = 'wiki_about.html'; + } +} + +async function apply() { + Route('/wiki/help', module.exports.WikiHelpHandler); + Route('/wiki/about', module.exports.WikiAboutHandler); +} + +global.Hydro.handler.wiki = module.exports = { + WikiHelpHandler, WikiAboutHandler, apply, +}; diff --git a/module/wiki/locale/en.yaml b/module/wiki/locale/en.yaml new file mode 100644 index 000000000..5882404be --- /dev/null +++ b/module/wiki/locale/en.yaml @@ -0,0 +1,2 @@ +wiki_about: About +wiki_help: Help diff --git a/module/wiki/locale/zh_CN.yaml b/module/wiki/locale/zh_CN.yaml new file mode 100644 index 000000000..c0ad88167 --- /dev/null +++ b/module/wiki/locale/zh_CN.yaml @@ -0,0 +1,2 @@ +wiki_about: 关于 +wiki_help: 帮助 diff --git a/module/wiki/raw/about.yaml b/module/wiki/raw/about.yaml new file mode 100644 index 000000000..6ea844721 --- /dev/null +++ b/module/wiki/raw/about.yaml @@ -0,0 +1,97 @@ +data-heading-extract-to: '#menu-item-wiki_about' +section: +- id: privacy + title: Privacy + content: | + {{ _('no_translation_warn')|safe }} +
我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式:
+您向我们提供信息。在您注册 Hydro 帐户时,我们会要求您提供个人信息,例如您的电子邮件地址、QQ号码等。
+我们在您使用服务的过程中获取信息。我们会收集关于您使用的服务以及使用方式的信息,例如您在何时使用了我们服务。
+我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Hydro 以及用户的隐私。
+当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。
+无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。
+我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。
+我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。
+对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Hydro 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。
+- id: tos + title: Terms of Service + content: | +注册 Hydro 帐户和/或使用 Hydro 提供的服务(包括网页提供的在线服务和题目评测的非在线服务等),即表示您已同意本条款。请您务必审慎阅读,充分理解条款各项内容。
+您必须遵守各项服务中提供的所有政策(包括但不限于讨论和题解的版规)。
+请勿滥用我们的服务。如,请勿干扰我们的服务,或尝试使用除我们提供的界面和指示以外的方法访问这些服务,或使用我们服务中出现的缺陷干扰其他网站或设施的正常运行。您仅能在法律允许的范围内使用我们的服务。
+您在使用我们服务时须遵守我们服务器所在地的法律法规,不得利用我们服务从事违法违规行为,包括但不限于:
+如果您违反了约定,相关国家相关机关或机构可能会对您提起诉讼、进行行政处罚或采取其他制裁措施,Hydro 将给于协助。造成损害的,您应依法予以赔偿,Hydro 不承担任何责任。
+如果 Hydro 发现或收到他人举报您发布的信息违反约定,Hydro 有权进行独立判断并采取技术手段予以删除、屏蔽或断开链接。同时,Hydro 有权视用户的行为性质,采取包括但不限于暂停或终止服务,限制、冻结或终止账户使用,追究法律责任等措施。
+使用我们的服务并不代表您拥有我们的服务或您所访问的内容的任何知识产权。网站上的所有材料(包括但不限于题目内容、用户界面、Wiki)版权均受保护,归 Hydro 所有。除非另有说明,本网站上的材料和服务仅用于个人和非商业用途,未经 Hydro 书面许可,不得复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发从本网站获得的任何信息、文件、产品或服务。
+我们的某些服务允许您提交内容。您保留对该内容持有的任何知识产权的所有权。
+当您上传内容或通过其他方式向我们的服务提交内容时,您授予 Hydro 使用、持有、存储、复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发此内容等权利。您在此许可中授予的权限,仅能用于运营、宣传和改进我们的服务,以及开发新的服务。该项许可在您停止使用我们的服务后依然有效。某些服务可能会向您提供一些方法,用于访问和删除您提供给该服务的内容。对于您提交至我们服务的任何内容,请确保您拥有向我们授予此许可的必要权利。我们有权在未通知您的情况下删除我们认为侵犯了知识产权或违反了相关法律法规的内容。
+您可以在 Hydro 上创建新题目。您上传到 Hydro 的题目,除了适用于本协议第三条(即“您在我们服务中发布的内容”)条款,还包含以下附加条款(若有冲突的条款,以附加条款中的优先):
+您上传到 Hydro 上的题目版权为 Hydro 和您共同拥有,我们会在相关页面或在对其进行分发、传播等操作时标明版权所有者。 +
Hydro 尊重他人知识产权和合法权益,请您在上传题目前确保拥有题目内容(包括但不限于题目描述、数据、图片等)的著作权及信息网络传播权或者已经取得上述全部权利人的许可并不存在任何著作权纠纷。Hydro有权在不通知的情况下删除被认为侵权的题目。 +
您可以申请将自己上传的优质题目合并到题库主干。我们的管理员会对您创建的题目的内容(包括但不限于评测数据等对用户不可见的信息)进行人工审核和适当修改以确认其符合国家基本法律法规。出于质量的考虑,我们也可能会拒绝您完全合法的合并到题库主干的请求。 +
我们会维护服务的稳定,并对数据(包括您递交的题目)进行定期的备份,并尽量在关闭服务前通知您,但我们仍然不对任何题目(包括主干和非主干)提供永久存储或保留的承诺,出于安全的考虑推荐您自行保留题目的内容。 +
您有权决定 Hydro 是否公开您上传的题目的数据。公开题目数据意味着 Hydro 上的用户均有权利获取到您递交的题目的所有评测数据,但相关版权协议仍然生效。
+Hydro 隐私声明介绍了您在使用我们的服务时,我们会如何处理您的个人数据和保护您的隐私。使用我们的服务即表示您同意 Hydro 可以按照我们的隐私权政策使用您的个人数据。
+我们始终在不断更改和改进我们的服务。我们可能会增加或删除功能,也可能暂停或彻底停止某项服务。
+您可以随时停止使用我们的服务,尽管我们对此表示非常遗憾。Hydro 也可能随时停止向您提供服务,或随时对我们的服务增加或设置新的限制。
+我们对服务内容、服务的具体功能,或其可靠性、可用性或满足您需要的能力不作任何承诺。我们的服务是按照现有技术和条件所能达到的现状提供的。我们会尽最大努力向您提供服务,确保服务的连贯性和安全性。但我们不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。
+我们可以修改上述条款或任何适用于某项服务的附加条款,您应当定期查阅本条款。所有修改的适用不具有追溯力,且会在公布十四天或更长时间后方始生效。但是,对服务新功能的特别修改或由于法律原因所作的修改将立即生效。如果您不同意服务的修改条款,应停止使用服务。
+如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。
+- id: discuss + title: 'Discussion: Terms Of Service' + content: | +为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。
+您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定:
+++第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。
+不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。
+发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。
+发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。
+特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。
+发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。
+打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。
+我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。
+
您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于:
+++危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
+侵害他人知识产权、商业秘密等合法权利的内容;
+恶意虚构事实、隐瞒真相以误导、欺骗他人的内容;
+广告信息及垃圾信息;
+其他法律法规禁止的内容。
+
对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。
\ No newline at end of file diff --git a/module/wiki/raw/help.yaml b/module/wiki/raw/help.yaml new file mode 100644 index 000000000..6fd3f8433 --- /dev/null +++ b/module/wiki/raw/help.yaml @@ -0,0 +1,93 @@ +data-heading-extract-to: '#menu-item-wiki_help' +section: +- id: compiler + title: Compilers' Version and Parameters + content: | +Hydro使用HydroJudger进行评测,以docker镜像的形式安装至评测机。所使用的编译器均为创建镜像时debian testing分支的最新版。编译参数如下:
++- id: limits + title: Limitations + content: | ++
- 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
Hydro 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。
+Hydro 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。
+- id: io + title: IO + content:若无特殊说明,Hydro 使用标准输入输出(控制台输入输出,屏幕输入输出,STD I/O)。
+- id: status + title: Judge Status + content: | +有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。+- id: ce + title: Compile Error + content: | +
可能有以下情况:
+++
- 1. 递交时选错了编程语言
+- 2. Java 的主类名没有使用 "Main"
+- 3. 对于 C/C++:见下
+- 4. 一般性的编译错误
+
++- id: training + title: Training + content:对 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 格式是不正确的
+
我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入!
+- id: contest + title: Contest + content: | +按照赛制不同,有不同的递交、排名规则。 +
OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。
+OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。
+ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。
+ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。
+时间与空间限制以题目说明为准,默认限制参见{{ _('Limitations') }}。
+- id: acratio + title: Accepted Ratio + content:通过率的影响极其恶劣,现在 Hydro 不提供也不承认通过率。
+- id: rp + title: RP + content: | +Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。
+浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。
+每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。+- id: upload + title: Dataset Format + content: TODO +- id: lostpass + title: Forgot Password and/or Username + content: | +
如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。
+如果您确信您的账号被盗或者忘记了账号和/或密码,请及时{{ _('Reset Password or Find Username') }}。
\ No newline at end of file diff --git a/module/wiki/template.build.js b/module/wiki/template.build.js new file mode 100644 index 000000000..8a25adb2e --- /dev/null +++ b/module/wiki/template.build.js @@ -0,0 +1,29 @@ +const yaml = require('js-yaml'); +const fs = require('fs'); +const path = require('path'); + +exports.prebuild = () => { + const templates = {}; + templates['layout/wiki_base.html'] = fs.readFileSync(`${__dirname}/wiki_base.html`).toString(); + const pages = fs.readdirSync(path.resolve(__dirname, 'raw')); + for (const page of pages) { + const f = fs.readFileSync(path.resolve(__dirname, 'raw', page)).toString(); + const file = yaml.safeLoad(f); + let template = ` + {% set page_name="wiki_${page.split('.')[0]}" %} + {% extends "layout/wiki_base.html" %} + {% block wiki_content %}`; + for (const section of file.section) { + template += ` +我们收集信息是为了向所有用户提供更好的服务。我们有两种信息收集方式:
-您向我们提供信息。在您注册 Hydro 帐户时,我们会要求您提供个人信息,例如您的电子邮件地址、QQ号码等。
-我们在您使用服务的过程中获取信息。我们会收集关于您使用的服务以及使用方式的信息,例如您在何时使用了我们服务。
-我们利用从所有服务中收集的信息来提供、维护、保护和改进这些服务,同时开发新的服务并保护 Hydro 以及用户的隐私。
-当我们要将信息用于本隐私权政策未载明的其它用途时,则会事先征求您的同意。
-无论您在何时使用我们的服务,我们都力求让您能够访问自己的个人信息。如果这些信息有误,我们会努力通过各种方式让您快速更新信息或删除信息。在更新您的个人信息时,我们可能会要求您先验证自己的身份,然后再处理您的请求。
-我们力求对服务进行完善的维护,以保护信息免遭意外或恶意的破坏。因此,当您从我们的服务中删除信息后,我们可能不会立即从在用的服务器中删除这些信息的残留副本,也可能不会从备份系统中删除相应的信息。
-我们为您提供SSL加密访问服务,您可以通过SSL(https)使用我们的服务,这可以很大程度上保障在传输过程中您信息的安全。
-对于敏感数据(如您的密码),我们承诺在存储时进行高强度不可逆加密。Hydro 的管理员、维护人员等均不能够访问到敏感数据的明文,所有操作均无人工介入。
-注册 Hydro 帐户和/或使用 Hydro 提供的服务(包括网页提供的在线服务和题目评测的非在线服务等),即表示您已同意本条款。请您务必审慎阅读,充分理解条款各项内容。
-您必须遵守各项服务中提供的所有政策(包括但不限于讨论和题解的版规)。
-请勿滥用我们的服务。如,请勿干扰我们的服务,或尝试使用除我们提供的界面和指示以外的方法访问这些服务,或使用我们服务中出现的缺陷干扰其他网站或设施的正常运行。您仅能在法律允许的范围内使用我们的服务。
-您在使用我们服务时须遵守我们服务器所在地的法律法规,不得利用我们服务从事违法违规行为,包括但不限于:
-如果您违反了约定,相关国家相关机关或机构可能会对您提起诉讼、进行行政处罚或采取其他制裁措施,Hydro 将给于协助。造成损害的,您应依法予以赔偿,Hydro 不承担任何责任。
-如果 Hydro 发现或收到他人举报您发布的信息违反约定,Hydro 有权进行独立判断并采取技术手段予以删除、屏蔽或断开链接。同时,Hydro 有权视用户的行为性质,采取包括但不限于暂停或终止服务,限制、冻结或终止账户使用,追究法律责任等措施。
-使用我们的服务并不代表您拥有我们的服务或您所访问的内容的任何知识产权。网站上的所有材料(包括但不限于题目内容、用户界面、Wiki)版权均受保护,归 Hydro 所有。除非另有说明,本网站上的材料和服务仅用于个人和非商业用途,未经 Hydro 书面许可,不得复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发从本网站获得的任何信息、文件、产品或服务。
-我们的某些服务允许您提交内容。您保留对该内容持有的任何知识产权的所有权。
-当您上传内容或通过其他方式向我们的服务提交内容时,您授予 Hydro 使用、持有、存储、复制、修改、创建衍生作品、传播、出版、公开演示、公开展示和分发此内容等权利。您在此许可中授予的权限,仅能用于运营、宣传和改进我们的服务,以及开发新的服务。该项许可在您停止使用我们的服务后依然有效。某些服务可能会向您提供一些方法,用于访问和删除您提供给该服务的内容。对于您提交至我们服务的任何内容,请确保您拥有向我们授予此许可的必要权利。我们有权在未通知您的情况下删除我们认为侵犯了知识产权或违反了相关法律法规的内容。
-您可以在 Hydro 上创建新题目。您上传到 Hydro 的题目,除了适用于本协议第三条(即“您在我们服务中发布的内容”)条款,还包含以下附加条款(若有冲突的条款,以附加条款中的优先):
-您上传到 Hydro 上的题目版权为 Hydro 和您共同拥有,我们会在相关页面或在对其进行分发、传播等操作时标明版权所有者。 -
Hydro 尊重他人知识产权和合法权益,请您在上传题目前确保拥有题目内容(包括但不限于题目描述、数据、图片等)的著作权及信息网络传播权或者已经取得上述全部权利人的许可并不存在任何著作权纠纷。Hydro有权在不通知的情况下删除被认为侵权的题目。 -
您可以申请将自己上传的优质题目合并到题库主干。我们的管理员会对您创建的题目的内容(包括但不限于评测数据等对用户不可见的信息)进行人工审核和适当修改以确认其符合国家基本法律法规。出于质量的考虑,我们也可能会拒绝您完全合法的合并到题库主干的请求。 -
我们会维护服务的稳定,并对数据(包括您递交的题目)进行定期的备份,并尽量在关闭服务前通知您,但我们仍然不对任何题目(包括主干和非主干)提供永久存储或保留的承诺,出于安全的考虑推荐您自行保留题目的内容。 -
您有权决定 Hydro 是否公开您上传的题目的数据。公开题目数据意味着 Hydro 上的用户均有权利获取到您递交的题目的所有评测数据,但相关版权协议仍然生效。
-Hydro 隐私声明介绍了您在使用我们的服务时,我们会如何处理您的个人数据和保护您的隐私。使用我们的服务即表示您同意 Hydro 可以按照我们的隐私权政策使用您的个人数据。
-我们始终在不断更改和改进我们的服务。我们可能会增加或删除功能,也可能暂停或彻底停止某项服务。
-您可以随时停止使用我们的服务,尽管我们对此表示非常遗憾。Hydro 也可能随时停止向您提供服务,或随时对我们的服务增加或设置新的限制。
-我们对服务内容、服务的具体功能,或其可靠性、可用性或满足您需要的能力不作任何承诺。我们的服务是按照现有技术和条件所能达到的现状提供的。我们会尽最大努力向您提供服务,确保服务的连贯性和安全性。但我们不能随时预见和防范法律、技术以及其他风险,包括但不限于不可抗力、病毒、木马、黑客攻击、系统不稳定、第三方服务瑕疵、政府行为等原因可能导致的服务中断、数据丢失以及其他的损失和风险。
-我们可以修改上述条款或任何适用于某项服务的附加条款,您应当定期查阅本条款。所有修改的适用不具有追溯力,且会在公布十四天或更长时间后方始生效。但是,对服务新功能的特别修改或由于法律原因所作的修改将立即生效。如果您不同意服务的修改条款,应停止使用服务。
-如果您对这个协议或我们的服务有意见或建议,可与我们联系,我们会给予您必要的帮助。
-为了更好地发挥讨论、题解的积极作用,使广大用户学到知识、获得利益,进一步规范讨论和题解功能的使用,我们制定了《讨论和题解版规》(简称《版规》)。您在发布(或回复)讨论和题解时,即代表您已充分阅读、理解、接受并保证遵守此版规。
-您在发布(或回复)讨论和题解或使用相关功能时须遵守以下规定:
---第一次使用编辑器前,要先阅读编辑器快速入门和 Markdown 详细帮助。
-不得将讨论、题解混淆。例如,不得将题解发布到讨论中,题解应发布在相应题目的题解区中。
-发布(或回复)的所有内容不得包含会干扰 Hydro 用户界面呈现的相关内容。
-发布(或回复)的所有内容不得包含恶意代码和指向恶意网站或 Hydro 明确禁止的网站的链接。
-特别地,发布(或回复)含有代码的内容时,应当将代码高亮。一个简单的方法是选中代码块然后按下 Tab 键。
-发布的题解禁止只包含无详细注释的代码。题解中难以理解的代码应当有尽可能详细的注释。
-打分、投票和评价应当客观。例如,对于题解的打分、投票和评价应当关注于题解本身的质量。
-我们欢迎原创作品,并会对其作者给予数量不等的 RP 奖励。
-
您在发布、回复讨论和题解时还须遵守法律法规,不得发布违法违规内容,包括但不限于:
---危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
-侵害他人知识产权、商业秘密等合法权利的内容;
-恶意虚构事实、隐瞒真相以误导、欺骗他人的内容;
-广告信息及垃圾信息;
-其他法律法规禁止的内容。
-
对于违反《版规》的,我们将进行警告并删除相关内容、临时冻结用户、永久冻结用户等操作。
-{{ _('Congratulations! Your submission is accepted.') }}
-{{ _('Problem') }}: P{{ pdoc['_id'] }} {{ pdoc['title'] }}
-{{ _('Code') }}:
-
-{{ rdoc['code'] }}
-
-{% endblock %}
diff --git a/templates/components/noscript_note.html b/templates/components/noscript_note.html
index 3bfa1c266..8f4e1c3bb 100644
--- a/templates/components/noscript_note.html
+++ b/templates/components/noscript_note.html
@@ -1,7 +1,15 @@
{% macro render() %}
+{% if not isIE(handler.request.headers['user-agent']) %}
+{% else %}
+++{{ _('This page needs JavaScript to work.') }}
+
- {{ _('You have uncompleted domain creation operation. You can click "Continue" to finish the creation.') }} --
| - | {{ _('Name') }} ({{ _('ID') }}) | -{{ _('My Role') }} | -{{ _('Action') }} | -
|---|---|---|---|
|
- |
- - {{ _('Uncompleted') }}: {{ ddoc['name'] }} ({{ ddoc['_id'] }}) - | -- -- - | -- |
|
- |
- - {{ ddoc['name'] }} ({{ ddoc['_id'] }}) - | -- {{ udict.get(ddoc['_id'], {})['role']|default(model.builtin.ROLE_DEFAULT) }} - | -- {{ _('Visit') }} - {% if can_manage[ddoc['_id']] %} - · {{ _('Manage') }} - {% endif %} - | -
|
- |
- - {{ ddoc['name'] }} ({{ ddoc['_id'] }}) - | -- {{ udict.get(ddoc['_id'], {})['role']|default(model.builtin.ROLE_DEFAULT) }} - | -- {{ _('Visit') }} - {% if can_manage[ddoc['_id']] %} - · {{ _('Manage') }} - {% endif %} - | -
每个用户可以创建自己的域。比如,老师可以为课程创建一个域,然后把题目和学生加入到此域中。再如,可以把域作为团队功能。
-通过合理的设置角色及其权限,可以把域设为公开或私有。
-默认域为Hydro,用户直接访问Hydro域名就会访问此域,点击Hydro Logo会从任意域跳转回Hydro域。
-每个域的题库、讨论、训练以及比赛是独立且自治的。
-Hydro使用HydroJudger进行评测,以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
Hydro 评测机使用进程的CPU时间计算时间消耗,时间的限定为题目中评测点所指定的时间。
-Hydro 评测机使用进程虚拟内存与物理内存总和计算内存空间消耗。内存空间默认限定为256MiB,题目中特别指明的,限定为题目中评测点所指定的内存空间。
-若无特殊说明,Hydro 使用标准输入输出(控制台输入输出,屏幕输入输出,STD I/O)。
-有“成绩取消”字样则说明管理员手动标记此记录为取消,可能违反了服务条款,比如代码被发现与其他用户的代码十分相似。-
可能有以下情况:
-- --
- 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 格式是不正确的
-
我们精心挑选了一些题目组成了训练计划。单击导航栏的“训练”即可进入!
-按照赛制不同,有不同的递交、排名规则。 -
OI 赛制所有题目均以最后一次递交为准,特别地,请避免编译错误。
-OI 赛制排名规则为:总分高的排在前面,总分相等则排名相同。
-ACM/ICPC 赛制所有题目递交后立即评测,以是否通过为准。
-ACM/ICPC 赛制排名规则为:通过题目数多的排在前面,通过题目数相同的做题耗时(含罚时)少的排在前。
-时间与空间限制以题目说明为准,默认限制参见{{ _('Limitations') }}。
-通过率的影响极其恶劣,现在 Hydro 不提供也不承认通过率。
-Hydro RP 分为固定 RP 与浮动 RP ,固定 RP 可由活动、比赛等的奖励获得,浮动 RP 由一般性通过题目获得。
-浮动 RP 是一个动态的数值,每个用户在每道题上获得的 RP 都不一样,并且未来也不固定(即浮动之意)。
-每道题的浮动 RP 由该题通过总人数与该用户通过此题的名次计算得来。-
Hydro 中题目的难度,根据递交数、通过率以及每个递交的递交时间和评测结果,通过算法计算得出。
-因此,请注意以下几点:
-我们只接受后缀名为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|
如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。
-如果您确信您的账号被盗或者忘记了账号和/或密码,请及时{{ _('Reset Password or Find Username') }}。
-