Reformat html files
This commit is contained in:
parent
9a208ca108
commit
52f1e77fe1
205 changed files with 11096 additions and 11086 deletions
9
.pre-commit-config.yaml
Normal file
9
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
repos:
|
||||
- repo: https://github.com/rtts/djhtml
|
||||
rev: 'main' # replace with the latest tag on GitHub
|
||||
hooks:
|
||||
- id: djhtml
|
||||
entry: djhtml -i -t 2
|
||||
files: templates/.
|
||||
- id: djcss
|
||||
types: [scss]
|
|
@ -42,3 +42,4 @@ bleach
|
|||
pymdown-extensions
|
||||
mdx-breakless-lists
|
||||
beautifulsoup4
|
||||
pre-commit
|
|
@ -1,19 +1,19 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
{% if request.organization %}
|
||||
{% if request.organization %}
|
||||
{% cache 3600 'organization_html' request.organization.id MATH_ENGINE %}
|
||||
{{ request.organization.about|markdown|reference|str|safe }}
|
||||
{{ request.organization.about|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
{% else %}
|
||||
{% else %}
|
||||
<h4>
|
||||
<a target="_blank" href="">LQDOJ (Le Quy Don Online Judge)</a> là một trang web chấm bài tự động được phát triển dựa trên nền tảng mã nguồn mở <a target="_blank" href="https://dmoj.ca/">DMOJ</a>. Được xây dựng với mục đích ban đầu là tạo ra một môi trường học tập cho học sinh khối chuyên Tin <a target="_blank" href="http://thpt-lequydon-danang.edu.vn/">trường THPT chuyên Lê Quý Đôn (TP Đà Nẵng)</a>, hiện nay LQDOJ đã cho phép đăng ký tự do để trở thành một sân chơi rộng mở cho toàn bộ cộng đồng học sinh yêu Tin học. Trang web cung cấp lượng bài luyện tập đồ sộ từ các kỳ thi HSG Quốc Gia, ACM ICPC, Olympic Duyên Hải Bắc Bộ, etc. cho đến các contest định kỳ để xếp loại khả năng (rating) giúp các bạn có thêm động lực cạnh tranh và khí thế phấn đấu rèn luyện nâng cao trình độ lập trình. Các bạn có thể tham khảo mã nguồn của trang web tại <a target="_blank" href="https://github.com/LQDJudge/online-judge">Github repo chính thức</a>. Mọi ý kiến đóng góp và thắc mắc xin gửi về:
|
||||
<ul>
|
||||
<a target="_blank" href="">LQDOJ (Le Quy Don Online Judge)</a> là một trang web chấm bài tự động được phát triển dựa trên nền tảng mã nguồn mở <a target="_blank" href="https://dmoj.ca/">DMOJ</a>. Được xây dựng với mục đích ban đầu là tạo ra một môi trường học tập cho học sinh khối chuyên Tin <a target="_blank" href="http://thpt-lequydon-danang.edu.vn/">trường THPT chuyên Lê Quý Đôn (TP Đà Nẵng)</a>, hiện nay LQDOJ đã cho phép đăng ký tự do để trở thành một sân chơi rộng mở cho toàn bộ cộng đồng học sinh yêu Tin học. Trang web cung cấp lượng bài luyện tập đồ sộ từ các kỳ thi HSG Quốc Gia, ACM ICPC, Olympic Duyên Hải Bắc Bộ, etc. cho đến các contest định kỳ để xếp loại khả năng (rating) giúp các bạn có thêm động lực cạnh tranh và khí thế phấn đấu rèn luyện nâng cao trình độ lập trình. Các bạn có thể tham khảo mã nguồn của trang web tại <a target="_blank" href="https://github.com/LQDJudge/online-judge">Github repo chính thức</a>. Mọi ý kiến đóng góp và thắc mắc xin gửi về:
|
||||
<ul>
|
||||
<li>Thầy <a target="_blank" href="https://www.facebook.com/dovannho">Đỗ Văn Nhỏ</a> (handle: <span class="rating rate-none user"><a target="_blank" href="../user/Small">Small</a></span>), giáo viên Tin học trường THPT chuyên Lê Quý Đôn, email: <a href="mailto:admin@lqdoj.edu.vn">admin@lqdoj.edu.vn</a></li>
|
||||
<li><a target="_blank" href="https://www.facebook.com/floweronstone">Nguyễn Đức Thuận</a> (handle: <span class="rating rate-master user"><a target="_blank" href="../user/Flower_On_Stone">Flower_On_Stone</a></span>), email: <a href="mailto:thuanbn03@gmail.com">thuanbn03@gmail.com</a></li>
|
||||
<li><a target="_blank" href="https://www.facebook.com/profile.php?id=100011662657075">Lê Phước Định</a> (handle: <span class="rating rate-grandmaster user"><a target="_blank" href="../user/cuom1999">cuom1999</a></span>), email: <a href="mailto:dinh@lqdoj.edu.vn">dinh@lqdoj.edu.vn</a></li>
|
||||
<li><a target="_blank" href="https://www.facebook.com/doannguyenthanhluong">Đoàn Nguyễn Thành Lương</a> (handle: <span class="rating rate-master user"><a target="_blank" href="../user/CaiWinDao">CaiWinDao</a></span>), email: <a href="mailto:luong@lqdoj.edu.vn">luong@lqdoj.edu.vn</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</h4>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,62 +1,62 @@
|
|||
{% extends "common-content.html" %}
|
||||
{% block description %}
|
||||
<style>
|
||||
article {
|
||||
padding: 2.5em 3.5em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
li {
|
||||
padding: 0.2em;
|
||||
}
|
||||
#content-right {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<article id="py">
|
||||
<h2>1. Custom checker (PY)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
Đây là checker mặc định của website, cho phép người dùng cập nhật được nhiều thông tin nhất (chi tiết xem ở bên dưới). Chúng ta cần hoàn thành hàm check dưới đây:
|
||||
</p>
|
||||
<style>
|
||||
article {
|
||||
padding: 2.5em 3.5em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
li {
|
||||
padding: 0.2em;
|
||||
}
|
||||
#content-right {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<article id="py">
|
||||
<h2>1. Custom checker (PY)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
Đây là checker mặc định của website, cho phép người dùng cập nhật được nhiều thông tin nhất (chi tiết xem ở bên dưới). Chúng ta cần hoàn thành hàm check dưới đây:
|
||||
</p>
|
||||
|
||||
{{
|
||||
"""
|
||||
def check(process_output, judge_output, **kwargs):
|
||||
{{
|
||||
"""
|
||||
def check(process_output, judge_output, **kwargs):
|
||||
# return True/False
|
||||
"""|highlight('py')}}
|
||||
"""|highlight('py')}}
|
||||
|
||||
<p>
|
||||
Trong đó, <code>**kwargs</code> có thể chứa các biến sau:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>process_output:</code> output</li>
|
||||
<li><code>judge_output:</code> đáp án</li>
|
||||
<li><code>submission_source</code>: Code bài nộp</li>
|
||||
<li><code>judge_input</code>: input</li>
|
||||
<li><code>point_value:</code> điểm của test đang chấm</li>
|
||||
<li><code>case_position:</code> thứ tự của test</li>
|
||||
<li><code>submission_language:</code> ngôn ngữ của bài nộp</li>
|
||||
<li><code>execution_time:</code> thời gian chạy</li>
|
||||
</ul>
|
||||
<h2>Return: </h2>
|
||||
<ul>
|
||||
<li>Cách 1: Trả về True/False</li>
|
||||
<li>Cách 2: Trả về một object <code>CheckerResult</code> có thể được gọi như sau <pre class="code2">CheckerResult(case_passed_bool, points_awarded, feedback='')</pre></li>
|
||||
</ul>
|
||||
<p>
|
||||
Trong đó, <code>**kwargs</code> có thể chứa các biến sau:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>process_output:</code> output</li>
|
||||
<li><code>judge_output:</code> đáp án</li>
|
||||
<li><code>submission_source</code>: Code bài nộp</li>
|
||||
<li><code>judge_input</code>: input</li>
|
||||
<li><code>point_value:</code> điểm của test đang chấm</li>
|
||||
<li><code>case_position:</code> thứ tự của test</li>
|
||||
<li><code>submission_language:</code> ngôn ngữ của bài nộp</li>
|
||||
<li><code>execution_time:</code> thời gian chạy</li>
|
||||
</ul>
|
||||
<h2>Return: </h2>
|
||||
<ul>
|
||||
<li>Cách 1: Trả về True/False</li>
|
||||
<li>Cách 2: Trả về một object <code>CheckerResult</code> có thể được gọi như sau <pre class="code2">CheckerResult(case_passed_bool, points_awarded, feedback='')</pre></li>
|
||||
</ul>
|
||||
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Dưới đây là ví dụ cho bài toán: Input gồm 1 số nguyên n. In ra 2 số nguyên a, b sao cho a + b = n.
|
||||
</p>
|
||||
{{
|
||||
"""
|
||||
from dmoj.result import CheckerResult
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Dưới đây là ví dụ cho bài toán: Input gồm 1 số nguyên n. In ra 2 số nguyên a, b sao cho a + b = n.
|
||||
</p>
|
||||
{{
|
||||
"""
|
||||
from dmoj.result import CheckerResult
|
||||
|
||||
|
||||
def wa(feedback):
|
||||
def wa(feedback):
|
||||
return CheckerResult(False, 0, feedback)
|
||||
|
||||
|
||||
def check(process_output, judge_output, judge_input, **kwargs):
|
||||
def check(process_output, judge_output, judge_input, **kwargs):
|
||||
# process the input
|
||||
input_arr = judge_input.split()
|
||||
assert(len(input_arr) == 1)
|
||||
|
@ -66,143 +66,143 @@ def check(process_output, judge_output, judge_input, **kwargs):
|
|||
output_arr = process_output.split()
|
||||
|
||||
if (len(output_arr) != 2):
|
||||
return wa('Wrong output format')
|
||||
return wa('Wrong output format')
|
||||
|
||||
try:
|
||||
a, b = int(output_arr[0]), int(output_arr[1])
|
||||
a, b = int(output_arr[0]), int(output_arr[1])
|
||||
except:
|
||||
return wa('Wrong output format')
|
||||
return wa('Wrong output format')
|
||||
|
||||
if (n == a + b):
|
||||
return True
|
||||
return True
|
||||
return wa('a + b != n')
|
||||
"""| highlight('py')}}
|
||||
</article>
|
||||
<article id="cpp">
|
||||
<h2>2. Custom validator (CPP)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
Để sử dụng chức năng này, cần viết một chương trình C++ pass vào 3 arguments theo thứ tự <code>input_file</code>, <code>output_file</code>, <code>ans_file</code> tương ứng với các file input, output, đáp án.
|
||||
</p>
|
||||
<p>
|
||||
Để test chương trình trên máy tính, có thể dùng lệnh như sau (Windows):
|
||||
<pre class="code2">
|
||||
"""| highlight('py')}}
|
||||
</article>
|
||||
<article id="cpp">
|
||||
<h2>2. Custom validator (CPP)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
Để sử dụng chức năng này, cần viết một chương trình C++ pass vào 3 arguments theo thứ tự <code>input_file</code>, <code>output_file</code>, <code>ans_file</code> tương ứng với các file input, output, đáp án.
|
||||
</p>
|
||||
<p>
|
||||
Để test chương trình trên máy tính, có thể dùng lệnh như sau (Windows):
|
||||
<pre class="code2">
|
||||
main.exe [input_file] [output_file] [ans_file]</pre>
|
||||
hoặc thay bằng <code>./main</code> trên Linux/MacOS.
|
||||
</p>
|
||||
<h2>Return: </h2>
|
||||
<p>
|
||||
Chương trình trả về giá trị:
|
||||
<ul>
|
||||
<li> 0 nếu AC (100% điểm)</li>
|
||||
<li> 1 nếu WA (0 điểm)</li>
|
||||
<li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC. </li>
|
||||
</ul>
|
||||
Những thông tin được viết ra stdout (bằng cout) sẽ được in ra màn hình cho người nộp bài(feedback)
|
||||
</p>
|
||||
hoặc thay bằng <code>./main</code> trên Linux/MacOS.
|
||||
</p>
|
||||
<h2>Return: </h2>
|
||||
<p>
|
||||
Chương trình trả về giá trị:
|
||||
<ul>
|
||||
<li> 0 nếu AC (100% điểm)</li>
|
||||
<li> 1 nếu WA (0 điểm)</li>
|
||||
<li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC. </li>
|
||||
</ul>
|
||||
Những thông tin được viết ra stdout (bằng cout) sẽ được in ra màn hình cho người nộp bài(feedback)
|
||||
</p>
|
||||
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Chương trình sau dùng để chấm bài toán: Cho n là một số nguyên dương. In ra hai số tự nhiên a, b sao cho a + b = n. </p>
|
||||
<p>Nếu in ra a + b = n và a, b >= 0 thì được 100% số điểm, nếu a + b = n nhưng một trong 2 số a, b âm thì được 50% số điểm. </p>
|
||||
{{
|
||||
"""
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Chương trình sau dùng để chấm bài toán: Cho n là một số nguyên dương. In ra hai số tự nhiên a, b sao cho a + b = n. </p>
|
||||
<p>Nếu in ra a + b = n và a, b >= 0 thì được 100% số điểm, nếu a + b = n nhưng một trong 2 số a, b âm thì được 50% số điểm. </p>
|
||||
{{
|
||||
"""
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
ifstream inp(argv[1]);
|
||||
ifstream out(argv[2]);
|
||||
ifstream ans(argv[3]);
|
||||
int main(int argc, char** argv) {
|
||||
ifstream inp(argv[1]);
|
||||
ifstream out(argv[2]);
|
||||
ifstream ans(argv[3]);
|
||||
|
||||
int n, a, b, c, d;
|
||||
int n, a, b, c, d;
|
||||
|
||||
inp >> n;
|
||||
out >> a >> b;
|
||||
ans >> c >> d;
|
||||
inp >> n;
|
||||
out >> a >> b;
|
||||
ans >> c >> d;
|
||||
|
||||
if (a + b == c + d) {
|
||||
cout << a << \" + \" << b << \" = \" << c << \" + \" << d << endl;
|
||||
if (a + b == c + d) {
|
||||
cout << a << \" + \" << b << \" = \" << c << \" + \" << d << endl;
|
||||
|
||||
if (a >= 0 && b >= 0) {
|
||||
return 0; // AC
|
||||
}
|
||||
else {
|
||||
cerr << 0.5;
|
||||
return 2; // PARTIAL
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << \"a + b = \" << a + b << \" != \" << n << endl;
|
||||
return 1; // WA
|
||||
}
|
||||
}
|
||||
""" | highlight('cpp')}}
|
||||
if (a >= 0 && b >= 0) {
|
||||
return 0; // AC
|
||||
}
|
||||
else {
|
||||
cerr << 0.5;
|
||||
return 2; // PARTIAL
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << \"a + b = \" << a + b << \" != \" << n << endl;
|
||||
return 1; // WA
|
||||
}
|
||||
}
|
||||
""" | highlight('cpp')}}
|
||||
</article>
|
||||
<article id="interactive">
|
||||
<h2>3. Interactive (CPP)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
<h2>3. Interactive (CPP)</h2>
|
||||
<hr>
|
||||
<p>
|
||||
Để sử dụng chức năng này, cần viết một chương trình C++ pass vào 2 arguments <code>input_file</code> <code>answer_file</code> tương ứng file input và đáp án (nếu cần thiết).
|
||||
</p>
|
||||
<p>
|
||||
Để test chương trình trên máy tính với tư cách thí sinh, có thể dùng lệnh như sau (Windows):
|
||||
<pre class="code2">
|
||||
</p>
|
||||
<p>
|
||||
Để test chương trình trên máy tính với tư cách thí sinh, có thể dùng lệnh như sau (Windows):
|
||||
<pre class="code2">
|
||||
main.exe [input_file] [answer_file]</pre>
|
||||
hoặc thay bằng <code>./main</code> trên Linux/MacOS.
|
||||
</p>
|
||||
<h2>Return: </h2>
|
||||
<p>
|
||||
Chương trình trả về giá trị:
|
||||
<ul>
|
||||
<li> 0 nếu AC (100% điểm)</li>
|
||||
<li> 1 nếu WA (0 điểm)</li>
|
||||
<li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC. </li>
|
||||
</ul>
|
||||
Thông tin được in ra trong stderr (bằng cerr) sẽ là feedback hiển thị cho người dùng.
|
||||
</p>
|
||||
hoặc thay bằng <code>./main</code> trên Linux/MacOS.
|
||||
</p>
|
||||
<h2>Return: </h2>
|
||||
<p>
|
||||
Chương trình trả về giá trị:
|
||||
<ul>
|
||||
<li> 0 nếu AC (100% điểm)</li>
|
||||
<li> 1 nếu WA (0 điểm)</li>
|
||||
<li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC. </li>
|
||||
</ul>
|
||||
Thông tin được in ra trong stderr (bằng cerr) sẽ là feedback hiển thị cho người dùng.
|
||||
</p>
|
||||
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Chương trình sau dùng để chấm bài toán guessgame: Người chơi phải tìm 1 số bí mật n (n chứa trong file input). Mỗi lần họ được hỏi một số x, và chương trình sẽ trả về "SMALLER", "BIGGER" hoặc "HOLA" dựa trên giá trị của n và x. Cần tìm ra n sau không quá 31 câu hỏi. </p>
|
||||
{{
|
||||
"""
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
<h2>Ví dụ: </h2>
|
||||
<p>Chương trình sau dùng để chấm bài toán guessgame: Người chơi phải tìm 1 số bí mật n (n chứa trong file input). Mỗi lần họ được hỏi một số x, và chương trình sẽ trả về "SMALLER", "BIGGER" hoặc "HOLA" dựa trên giá trị của n và x. Cần tìm ra n sau không quá 31 câu hỏi. </p>
|
||||
{{
|
||||
"""
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
void quit(string reason) {
|
||||
cerr << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
void quit(string reason) {
|
||||
cerr << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void read(long long& guess) {
|
||||
if (!(cin >> guess)) exit(1); // Nếu không có dòng này, chương trình sẽ chờ vô hạn
|
||||
if (guess < 1 || guess > 2e9) exit(1);
|
||||
}
|
||||
void read(long long& guess) {
|
||||
if (!(cin >> guess)) exit(1); // Nếu không có dòng này, chương trình sẽ chờ vô hạn
|
||||
if (guess < 1 || guess > 2e9) exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
ifstream inp(argv[1]);
|
||||
int N, guesses = 0;
|
||||
long long guess;
|
||||
inp >> N;
|
||||
int main(int argc, char *argv[]) {
|
||||
ifstream inp(argv[1]);
|
||||
int N, guesses = 0;
|
||||
long long guess;
|
||||
inp >> N;
|
||||
|
||||
while (guess != N && guesses <= 31) {
|
||||
while (guess != N && guesses <= 31) {
|
||||
read(guess);
|
||||
if (guess == N) {
|
||||
cout << \"HOLA\" << endl;
|
||||
cout << \"HOLA\" << endl;
|
||||
} else if (guess > N) {
|
||||
cout << \"SMALLER\" << endl;
|
||||
cout << \"SMALLER\" << endl;
|
||||
} else {
|
||||
cout << \"BIGGER\" << endl;
|
||||
cout << \"BIGGER\" << endl;
|
||||
}
|
||||
guesses++;
|
||||
}
|
||||
cerr << \"Number of used guesses: \" << guesses << endl;
|
||||
if (guesses <= 31)
|
||||
}
|
||||
cerr << \"Number of used guesses: \" << guesses << endl;
|
||||
if (guesses <= 31)
|
||||
return 0; // AC
|
||||
else {
|
||||
else {
|
||||
cerr << \"Used too many guesses\" << endl;
|
||||
return 1; // WA
|
||||
}
|
||||
}
|
||||
""" | highlight('cpp')}}
|
||||
</article>
|
||||
}
|
||||
}
|
||||
""" | highlight('cpp')}}
|
||||
</article>
|
||||
{% endblock %}
|
|
@ -1,51 +1,51 @@
|
|||
{% set logged_in = request.user.is_authenticated %}
|
||||
{% set profile = request.profile if logged_in else None %}
|
||||
{% if logged_in %}
|
||||
{% if include_hr %}<hr>{% endif %}
|
||||
<div class="page-vote actionbar">
|
||||
{% if include_hr %}<hr>{% endif %}
|
||||
<div class="page-vote actionbar">
|
||||
<span class="actionbar-block" style="justify-content: flex-start;">
|
||||
<span id="like-button-{{pagevote.id}}"
|
||||
class="like-button actionbar-button {% if pagevote.vote_score(request.profile) == 1 %}voted{% endif %}"
|
||||
onclick="javascript:pagevote_upvote({{ pagevote.id }})"
|
||||
>
|
||||
<span class="pagevote-score" id="pagevote-score-{{pagevote.id}}">{{ pagevote.score }}</span>
|
||||
<i class="fa fa-thumbs-o-up" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Like")}}</span>
|
||||
</span>
|
||||
<span id="dislike-button-{{pagevote.id}}" class="dislike-button actionbar-button {% if pagevote.vote_score(request.profile) == -1 %}voted{% endif %}" onclick="javascript:pagevote_downvote({{ pagevote.id }})">
|
||||
<i class="fa fa-thumbs-o-down" style="font-size: large;"></i>
|
||||
</span>
|
||||
<span id="like-button-{{pagevote.id}}"
|
||||
class="like-button actionbar-button {% if pagevote.vote_score(request.profile) == 1 %}voted{% endif %}"
|
||||
onclick="javascript:pagevote_upvote({{ pagevote.id }})"
|
||||
>
|
||||
<span class="pagevote-score" id="pagevote-score-{{pagevote.id}}">{{ pagevote.score }}</span>
|
||||
<i class="fa fa-thumbs-o-up" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Like")}}</span>
|
||||
</span>
|
||||
<span id="dislike-button-{{pagevote.id}}" class="dislike-button actionbar-button {% if pagevote.vote_score(request.profile) == -1 %}voted{% endif %}" onclick="javascript:pagevote_downvote({{ pagevote.id }})">
|
||||
<i class="fa fa-thumbs-o-down" style="font-size: large;"></i>
|
||||
</span>
|
||||
</span>
|
||||
{% if not hide_actionbar_comment %}
|
||||
<span class="actionbar-block">
|
||||
<span class="actionbar-block">
|
||||
<span class="actionbar-button actionbar-comment">
|
||||
<i class="fa fa-comment-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Comment")}} {% if comment_list.count() %} ({{comment_list.count()}}) {% endif %}</span>
|
||||
<i class="fa fa-comment-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Comment")}} {% if comment_list.count() %} ({{comment_list.count()}}) {% endif %}</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span class="actionbar-block">
|
||||
<span id="bookmark-button-{{bookmark.id}}"
|
||||
class="bookmark-button actionbar-button {% if bookmark.get_bookmark(request.profile) == True %} bookmarked {% endif %}"
|
||||
onclick="javascript:bookmark({{ bookmark.id }})"
|
||||
>
|
||||
<i class="fa fa-bookmark-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Bookmark")}}</span>
|
||||
</span>
|
||||
<span id="bookmark-button-{{bookmark.id}}"
|
||||
class="bookmark-button actionbar-button {% if bookmark.get_bookmark(request.profile) == True %} bookmarked {% endif %}"
|
||||
onclick="javascript:bookmark({{ bookmark.id }})"
|
||||
>
|
||||
<i class="fa fa-bookmark-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Bookmark")}}</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="actionbar-block" >
|
||||
<span class="actionbar-button actionbar-share" style="position: relative" {{"share-url=" + share_url if share_url else ""}}>
|
||||
<i class="fa fa-share" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Share")}}</span>
|
||||
</span>
|
||||
<span class="actionbar-button actionbar-share" style="position: relative" {{"share-url=" + share_url if share_url else ""}}>
|
||||
<i class="fa fa-share" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Share")}}</span>
|
||||
</span>
|
||||
</span>
|
||||
{% if actionbar_report_url %}
|
||||
<span class="actionbar-block">
|
||||
<a class="actionbar-button black" href="{{actionbar_report_url}}">
|
||||
<i class="fa fa-flag-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Report")}}</span>
|
||||
</a>
|
||||
</span>
|
||||
<span class="actionbar-block">
|
||||
<a class="actionbar-button black" href="{{actionbar_report_url}}">
|
||||
<i class="fa fa-flag-o" style="font-size: large;"></i>
|
||||
<span class="actionbar-text">{{_("Report")}}</span>
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
|
@ -1,7 +1,7 @@
|
|||
<style>
|
||||
@media (max-width: 799px) {
|
||||
.actionbar-text {
|
||||
display: none;
|
||||
}
|
||||
@media (max-width: 799px) {
|
||||
.actionbar-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,124 +1,124 @@
|
|||
{% compress js %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
function ajax_vote(url, id, delta, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var score = $('#pagevote-score-' + id);
|
||||
score.text(parseInt(score.text()) + delta);
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not vote: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ajax_bookmark(url, id, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not bookmark: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.bookmark = function(id) {
|
||||
var $bookmark = $('#bookmark-button-' + id);
|
||||
if ($bookmark.hasClass('bookmarked')) {
|
||||
ajax_bookmark('{{ url('undobookmark') }}', id, function () {
|
||||
$bookmark.removeClass('bookmarked');
|
||||
});
|
||||
} else {
|
||||
ajax_bookmark('{{ url('dobookmark') }}', id, function () {
|
||||
if ($bookmark.hasClass('bookmarked'))
|
||||
$bookmark.removeClass('bookmarked');
|
||||
$bookmark.addClass('bookmarked');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var get_$votes = function (id) {
|
||||
var $post = $('#page-vote-' + id);
|
||||
return {
|
||||
upvote: $('#like-button-' + id),
|
||||
downvote: $('#dislike-button-' + id),
|
||||
};
|
||||
};
|
||||
|
||||
window.pagevote_upvote = function (id) {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.upvote.hasClass('voted')) {
|
||||
ajax_vote('{{ url('pagevote_downvote') }}', id, -1, function () {
|
||||
$votes.upvote.removeClass('voted');
|
||||
});
|
||||
}
|
||||
else {
|
||||
var delta = 1;
|
||||
if ($votes.downvote.hasClass('voted')) {
|
||||
delta = 2;
|
||||
}
|
||||
for (let i = 0; i < delta; i++) {
|
||||
ajax_vote('{{ url('pagevote_upvote') }}', id, 1, function () {
|
||||
if ($votes.downvote.hasClass('voted'))
|
||||
$votes.downvote.removeClass('voted');
|
||||
$votes.upvote.addClass('voted');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.pagevote_downvote = function (id) {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.downvote.hasClass('voted')) {
|
||||
ajax_vote('{{ url('pagevote_upvote') }}', id, 1, function () {
|
||||
$votes.downvote.removeClass('voted');
|
||||
});
|
||||
}
|
||||
else {
|
||||
var delta = -1;
|
||||
if ($votes.upvote.hasClass('voted')) {
|
||||
delta = -2;
|
||||
}
|
||||
for (let i = 0; i > delta; i--) {
|
||||
ajax_vote('{{ url('pagevote_downvote') }}', id, -1, function () {
|
||||
if ($votes.upvote.hasClass('voted'))
|
||||
$votes.upvote.removeClass('voted');
|
||||
$votes.downvote.addClass('voted');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
$(".actionbar-share").click( function() {
|
||||
link = $(this).attr("share-url") || window.location.href;
|
||||
navigator.clipboard
|
||||
.writeText(link)
|
||||
.then(() => {
|
||||
showTooltip(this, "Copied link", 'n');
|
||||
});
|
||||
});
|
||||
|
||||
$('.actionbar-comment').on('click', function() {
|
||||
if ($('#comment-announcement').length) {
|
||||
$('#comment-announcement').click();
|
||||
}
|
||||
$('#write-comment').click();
|
||||
})
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
function ajax_vote(url, id, delta, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var score = $('#pagevote-score-' + id);
|
||||
score.text(parseInt(score.text()) + delta);
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not vote: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
}
|
||||
|
||||
function ajax_bookmark(url, id, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not bookmark: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.bookmark = function(id) {
|
||||
var $bookmark = $('#bookmark-button-' + id);
|
||||
if ($bookmark.hasClass('bookmarked')) {
|
||||
ajax_bookmark('{{ url('undobookmark') }}', id, function () {
|
||||
$bookmark.removeClass('bookmarked');
|
||||
});
|
||||
} else {
|
||||
ajax_bookmark('{{ url('dobookmark') }}', id, function () {
|
||||
if ($bookmark.hasClass('bookmarked'))
|
||||
$bookmark.removeClass('bookmarked');
|
||||
$bookmark.addClass('bookmarked');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var get_$votes = function (id) {
|
||||
var $post = $('#page-vote-' + id);
|
||||
return {
|
||||
upvote: $('#like-button-' + id),
|
||||
downvote: $('#dislike-button-' + id),
|
||||
};
|
||||
};
|
||||
|
||||
window.pagevote_upvote = function (id) {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.upvote.hasClass('voted')) {
|
||||
ajax_vote('{{ url('pagevote_downvote') }}', id, -1, function () {
|
||||
$votes.upvote.removeClass('voted');
|
||||
});
|
||||
}
|
||||
else {
|
||||
var delta = 1;
|
||||
if ($votes.downvote.hasClass('voted')) {
|
||||
delta = 2;
|
||||
}
|
||||
for (let i = 0; i < delta; i++) {
|
||||
ajax_vote('{{ url('pagevote_upvote') }}', id, 1, function () {
|
||||
if ($votes.downvote.hasClass('voted'))
|
||||
$votes.downvote.removeClass('voted');
|
||||
$votes.upvote.addClass('voted');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.pagevote_downvote = function (id) {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.downvote.hasClass('voted')) {
|
||||
ajax_vote('{{ url('pagevote_upvote') }}', id, 1, function () {
|
||||
$votes.downvote.removeClass('voted');
|
||||
});
|
||||
}
|
||||
else {
|
||||
var delta = -1;
|
||||
if ($votes.upvote.hasClass('voted')) {
|
||||
delta = -2;
|
||||
}
|
||||
for (let i = 0; i > delta; i--) {
|
||||
ajax_vote('{{ url('pagevote_downvote') }}', id, -1, function () {
|
||||
if ($votes.upvote.hasClass('voted'))
|
||||
$votes.upvote.removeClass('voted');
|
||||
$votes.downvote.addClass('voted');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
$(".actionbar-share").click( function() {
|
||||
link = $(this).attr("share-url") || window.location.href;
|
||||
navigator.clipboard
|
||||
.writeText(link)
|
||||
.then(() => {
|
||||
showTooltip(this, "Copied link", 'n');
|
||||
});
|
||||
});
|
||||
|
||||
$('.actionbar-comment').on('click', function() {
|
||||
if ($('#comment-announcement').length) {
|
||||
$('#comment-announcement').click();
|
||||
}
|
||||
$('#write-comment').click();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endcompress %}
|
|
@ -2,19 +2,19 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.profilelink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.profilelink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Edit profile" %}" href="{% url 'admin:judge_profile_change' original.profile.pk %}"
|
||||
class="button profilelink">
|
||||
<i class="fa fa-lg fa-user-plus"></i>
|
||||
<span class="text">{% trans "Edit profile" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Edit profile" %}" href="{% url 'admin:judge_profile_change' original.profile.pk %}"
|
||||
class="button profilelink">
|
||||
<i class="fa fa-lg fa-user-plus"></i>
|
||||
<span class="text">{% trans "Edit profile" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,22 +2,22 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.rerate-link').appendTo('div#bottombar').show();
|
||||
$('.rejudge-link').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to rejudge ALL the submissions?') }}');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.rerate-link').appendTo('div#bottombar').show();
|
||||
$('.rejudge-link').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to rejudge ALL the submissions?') }}');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original and original.is_rated and original.ended and perms.judge.contest_rating %}
|
||||
<a style="display: none" title="{% trans "Rate" %}" href="{% url 'admin:judge_contest_rate' original.pk %}"
|
||||
class="button rerate-link">
|
||||
<i class="fa fa-lg fa-signal"></i>
|
||||
<span class="text">{% trans "Rate" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original and original.is_rated and original.ended and perms.judge.contest_rating %}
|
||||
<a style="display: none" title="{% trans "Rate" %}" href="{% url 'admin:judge_contest_rate' original.pk %}"
|
||||
class="button rerate-link">
|
||||
<i class="fa fa-lg fa-signal"></i>
|
||||
<span class="text">{% trans "Rate" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block object-tools-items %}
|
||||
{{ block.super }}
|
||||
{% if not is_popup and perms.judge.contest_rating %}
|
||||
<li>
|
||||
<a href="{% url 'admin:judge_contest_rate_all' %}" class="ratealllink">
|
||||
<i class="fa fa-signal"></i> {% trans "Rate all ratable contests" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{{ block.super }}
|
||||
{% if not is_popup and perms.judge.contest_rating %}
|
||||
<li>
|
||||
<a href="{% url 'admin:judge_contest_rate_all' %}" class="ratealllink">
|
||||
<i class="fa fa-signal"></i> {% trans "Rate all ratable contests" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.disconnect-link').appendTo('div#bottombar').show();
|
||||
$('.terminate-link').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.disconnect-link').appendTo('div#bottombar').show();
|
||||
$('.terminate-link').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Disconnect" %}" href="{% url 'admin:judge_judge_disconnect' original.pk %}"
|
||||
class="button disconnect-link">
|
||||
<i class="fa fa-lg fa-power-off"></i>
|
||||
<span class="text">{% trans "Disconnect" %}</span>
|
||||
</a>
|
||||
<a style="display: none" title="{% trans "Terminate" %}" href="{% url 'admin:judge_judge_terminate' original.pk %}"
|
||||
class="button terminate-link">
|
||||
<i class="fa fa-lg fa-plug"></i>
|
||||
<span class="text">{% trans "Terminate" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Disconnect" %}" href="{% url 'admin:judge_judge_disconnect' original.pk %}"
|
||||
class="button disconnect-link">
|
||||
<i class="fa fa-lg fa-power-off"></i>
|
||||
<span class="text">{% trans "Disconnect" %}</span>
|
||||
</a>
|
||||
<a style="display: none" title="{% trans "Terminate" %}" href="{% url 'admin:judge_judge_terminate' original.pk %}"
|
||||
class="button terminate-link">
|
||||
<i class="fa fa-lg fa-plug"></i>
|
||||
<span class="text">{% trans "Terminate" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,24 +2,24 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.submissions-link').appendTo('div#bottombar').show();
|
||||
$('.votes-link').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.submissions-link').appendTo('div#bottombar').show();
|
||||
$('.votes-link').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "View Submissions" %}" class="button submissions-link"
|
||||
href="{% url 'admin:judge_submission_changelist' %}?problem__code={{ original.code }}">
|
||||
<i class="fa fa-lg fa-search-plus"></i>
|
||||
<span class="text">{% trans "View submissions" %}</span>
|
||||
<a style="display: none" title="{{ _('View votes') }}" class="button votes-link"
|
||||
href="{% url 'admin:judge_problempointsvote_changelist' %}?problem__code={{ original.code }}">
|
||||
<i class="fa fa-lg fa-envelope"></i>
|
||||
<span class="text">{{ _('View votes') }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "View Submissions" %}" class="button submissions-link"
|
||||
href="{% url 'admin:judge_submission_changelist' %}?problem__code={{ original.code }}">
|
||||
<i class="fa fa-lg fa-search-plus"></i>
|
||||
<span class="text">{% trans "View submissions" %}</span>
|
||||
<a style="display: none" title="{{ _('View votes') }}" class="button votes-link"
|
||||
href="{% url 'admin:judge_problempointsvote_changelist' %}?problem__code={{ original.code }}">
|
||||
<i class="fa fa-lg fa-envelope"></i>
|
||||
<span class="text">{{ _('View votes') }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.userlink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.userlink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Edit user" %}" href="{% url 'admin:auth_user_change' original.user.pk %}"
|
||||
class="button userlink">
|
||||
<i class="fa fa-lg fa-user"></i>
|
||||
<span class="text">{% trans "Edit user" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Edit user" %}" href="{% url 'admin:auth_user_change' original.user.pk %}"
|
||||
class="button userlink">
|
||||
<i class="fa fa-lg fa-user"></i>
|
||||
<span class="text">{% trans "Edit user" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.rejudgelink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
django.jQuery(function ($) {
|
||||
$('.rejudgelink').appendTo('div#bottombar').show();
|
||||
});
|
||||
</script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block after_field_sets %}{{ block.super }}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Rejudge" %}" href="{% url 'admin:judge_submission_rejudge' original.pk %}"
|
||||
class="button rejudgelink">
|
||||
<i class="fa fa-lg fa-refresh"></i>
|
||||
<span class="text">{% trans "Rejudge" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if original %}
|
||||
<a style="display: none" title="{% trans "Rejudge" %}" href="{% url 'admin:judge_submission_rejudge' original.pk %}"
|
||||
class="button rejudgelink">
|
||||
<i class="fa fa-lg fa-refresh"></i>
|
||||
<span class="text">{% trans "Rejudge" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,13 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ LANGUAGE_CODE }}">
|
||||
<head>
|
||||
<head>
|
||||
<title>{% block title %}{{ title }} - {{ SITE_LONG_NAME }}{% endblock %}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
{% if misc_config.meta_keywords %}
|
||||
<meta name="keywords" content="{{ misc_config.meta_keywords }}">
|
||||
<meta name="keywords" content="{{ misc_config.meta_keywords }}">
|
||||
{% endif %}
|
||||
{% if meta_description %}
|
||||
<meta name="description" content="{{ meta_description }}">
|
||||
<meta name="description" content="{{ meta_description }}">
|
||||
{% endif %}
|
||||
<meta id="viewport" name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- Favicons-->
|
||||
|
@ -30,14 +30,14 @@
|
|||
{# Chrome 39 for Android colour #}
|
||||
<meta name="theme-color" content="#FFBB33">
|
||||
{% if og_image %}
|
||||
<meta property="og:image" content="{{ request.build_absolute_uri(og_image) }}">
|
||||
<meta property="og:image" content="{{ request.build_absolute_uri(og_image) }}">
|
||||
{% endif %}
|
||||
{% block og_title %}{% endblock %}
|
||||
<meta property="og:site_name" content="{{ SITE_LONG_NAME }}">
|
||||
<meta property="og:url"
|
||||
content="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||
content="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||
{% if meta_description %}
|
||||
<meta property="og:description" content="{{ meta_description }}">
|
||||
<meta property="og:description" content="{{ meta_description }}">
|
||||
{% endif %}
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
|
@ -45,337 +45,337 @@
|
|||
<![endif]-->
|
||||
{% block meta %}{% endblock %}
|
||||
{% if not INLINE_FONTAWESOME %}
|
||||
<link rel="stylesheet" href="{{ FONTAWESOME_CSS }}">
|
||||
<link rel="stylesheet" href="{{ FONTAWESOME_CSS }}">
|
||||
{% endif %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('markdown.css') }}">
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" href="{{ static('style.css') }}">
|
||||
{% if PYGMENT_THEME %}
|
||||
<link rel="stylesheet" href="{{ static(PYGMENT_THEME) }}">
|
||||
{% endif %}{% if INLINE_FONTAWESOME %}
|
||||
<link rel="stylesheet" href="{{ static('style.css') }}">
|
||||
{% if PYGMENT_THEME %}
|
||||
<link rel="stylesheet" href="{{ static(PYGMENT_THEME) }}">
|
||||
{% endif %}{% if INLINE_FONTAWESOME %}
|
||||
<link rel="stylesheet" href="{{ static('libs/fontawesome/font-awesome.css') }}">{% endif %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/featherlight/featherlight.min.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/clipboard/tooltip.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/select2/select2.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('icofont/icofont.min.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/featherlight/featherlight.min.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/clipboard/tooltip.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('libs/select2/select2.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ static('icofont/icofont.min.css') }}">
|
||||
{% endcompress %}
|
||||
<link rel="canonical"
|
||||
href="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||
href="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||
{% if request.user.is_impersonate %}
|
||||
<style>
|
||||
#nav-container {
|
||||
background: #893e89 !important;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
#nav-container {
|
||||
background: #893e89 !important;
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% block media %}{% endblock %}
|
||||
{% if use_darkmode %}
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" href="{{ static('darkmode.css') }}">
|
||||
<link rel="stylesheet" href="{{ static('darkmode-svg.css') }}">
|
||||
{% endcompress %}
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" href="{{ static('darkmode.css') }}">
|
||||
<link rel="stylesheet" href="{{ static('darkmode-svg.css') }}">
|
||||
{% endcompress %}
|
||||
{% endif %}
|
||||
{% if not INLINE_JQUERY %}
|
||||
<script src="{{ JQUERY_JS }}"></script>
|
||||
<script src="{{ JQUERY_JS }}"></script>
|
||||
{% endif %}
|
||||
<script src="https://unpkg.com/@popperjs/core@2"></script>
|
||||
{% compress js %}
|
||||
<script>{{ inlinei18n(LANGUAGE_CODE)|safe }}</script>
|
||||
{% if INLINE_JQUERY %}
|
||||
<script src="{{ static('libs/jquery-3.4.1.min.js') }}"></script>
|
||||
{% endif %}
|
||||
<script src="{{ static('libs/jquery-cookie.js') }}"></script>
|
||||
<script src="{{ static('libs/jquery-taphold.js') }}"></script>
|
||||
<script src="{{ static('libs/jquery.unveil.js') }}"></script>
|
||||
<script src="{{ static('libs/moment.js') }}"></script>
|
||||
<script src="{{ static('libs/select2/select2.js') }}"></script>
|
||||
{% include "extra_js.html" %}
|
||||
<script src="{{ static('common.js') }}"></script>
|
||||
<script src="{{ static('libs/clipboard/tooltip.js') }}"></script>
|
||||
<script>
|
||||
moment.locale('{{ LANGUAGE_CODE }}');
|
||||
$(function () {
|
||||
$('img.unveil').unveil(200);
|
||||
});
|
||||
const loading_page = `{% include "loading-page.html" %}`;
|
||||
</script>
|
||||
<script>{{ inlinei18n(LANGUAGE_CODE)|safe }}</script>
|
||||
{% if INLINE_JQUERY %}
|
||||
<script src="{{ static('libs/jquery-3.4.1.min.js') }}"></script>
|
||||
{% endif %}
|
||||
<script src="{{ static('libs/jquery-cookie.js') }}"></script>
|
||||
<script src="{{ static('libs/jquery-taphold.js') }}"></script>
|
||||
<script src="{{ static('libs/jquery.unveil.js') }}"></script>
|
||||
<script src="{{ static('libs/moment.js') }}"></script>
|
||||
<script src="{{ static('libs/select2/select2.js') }}"></script>
|
||||
{% include "extra_js.html" %}
|
||||
<script src="{{ static('common.js') }}"></script>
|
||||
<script src="{{ static('libs/clipboard/tooltip.js') }}"></script>
|
||||
<script>
|
||||
moment.locale('{{ LANGUAGE_CODE }}');
|
||||
$(function () {
|
||||
$('img.unveil').unveil(200);
|
||||
});
|
||||
const loading_page = `{% include "loading-page.html" %}`;
|
||||
</script>
|
||||
{% endcompress %}
|
||||
|
||||
{% block js_media %}{% endblock %}
|
||||
{% if request.in_contest %}
|
||||
<script>$(function () {
|
||||
if ($("#contest-time-remaining").length) {
|
||||
count_down($("#contest-time-remaining"));
|
||||
}
|
||||
<script>$(function () {
|
||||
if ($("#contest-time-remaining").length) {
|
||||
count_down($("#contest-time-remaining"));
|
||||
}
|
||||
|
||||
var selected = null,
|
||||
x_pos = 0, y_pos = 0,
|
||||
x_elem = 0, y_elem = 0;
|
||||
var selected = null,
|
||||
x_pos = 0, y_pos = 0,
|
||||
x_elem = 0, y_elem = 0;
|
||||
|
||||
$('#contest-info').mousedown(function () {
|
||||
selected = $(this);
|
||||
x_elem = x_pos - selected.offset().left;
|
||||
y_elem = y_pos - (selected.offset().top - $(window).scrollTop());
|
||||
return false;
|
||||
});
|
||||
|
||||
if (localStorage.getItem("contest_timer_position")) {
|
||||
data = localStorage.getItem("contest_timer_position").split(":");
|
||||
$("#contest-info").css({
|
||||
left: data[0],
|
||||
top: data[1]
|
||||
});
|
||||
}
|
||||
|
||||
$("#contest-info").show();
|
||||
|
||||
$("#contest-info-toggle").on('click', function() {
|
||||
$.post("{{url('contest_mode_ajax')}}", function() {
|
||||
window.location.reload();
|
||||
})
|
||||
});
|
||||
|
||||
$(document).mousemove(function (e) {
|
||||
x_pos = e.screenX;
|
||||
y_pos = e.screenY;
|
||||
|
||||
if (selected !== null) {
|
||||
left_px = (x_pos - x_elem);
|
||||
top_px = (y_pos - y_elem);
|
||||
left_px = Math.max(Math.min(left_px, window.innerWidth), 0) / window.innerWidth * 100 + '%';
|
||||
top_px = Math.max(Math.min(top_px, window.innerHeight), 0) / window.innerHeight * 100 + '%';
|
||||
localStorage.setItem("contest_timer_position", left_px + ":" + top_px);
|
||||
|
||||
selected.css({
|
||||
left: left_px,
|
||||
top: top_px
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(document).mouseup(function () {
|
||||
selected = null;
|
||||
})
|
||||
$('#contest-info').mousedown(function () {
|
||||
selected = $(this);
|
||||
x_elem = x_pos - selected.offset().left;
|
||||
y_elem = y_pos - (selected.offset().top - $(window).scrollTop());
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
|
||||
if (localStorage.getItem("contest_timer_position")) {
|
||||
data = localStorage.getItem("contest_timer_position").split(":");
|
||||
$("#contest-info").css({
|
||||
left: data[0],
|
||||
top: data[1]
|
||||
});
|
||||
}
|
||||
|
||||
$("#contest-info").show();
|
||||
|
||||
$("#contest-info-toggle").on('click', function() {
|
||||
$.post("{{url('contest_mode_ajax')}}", function() {
|
||||
window.location.reload();
|
||||
})
|
||||
});
|
||||
|
||||
$(document).mousemove(function (e) {
|
||||
x_pos = e.screenX;
|
||||
y_pos = e.screenY;
|
||||
|
||||
if (selected !== null) {
|
||||
left_px = (x_pos - x_elem);
|
||||
top_px = (y_pos - y_elem);
|
||||
left_px = Math.max(Math.min(left_px, window.innerWidth), 0) / window.innerWidth * 100 + '%';
|
||||
top_px = Math.max(Math.min(top_px, window.innerHeight), 0) / window.innerHeight * 100 + '%';
|
||||
localStorage.setItem("contest_timer_position", left_px + ":" + top_px);
|
||||
|
||||
selected.css({
|
||||
left: left_px,
|
||||
top: top_px
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(document).mouseup(function () {
|
||||
selected = null;
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<script>
|
||||
window.user = {
|
||||
email: '{{ request.user.email|escapejs }}',
|
||||
id: '{{ request.user.id|escapejs }}',
|
||||
name: '{{ request.user.username|escapejs }}'
|
||||
};
|
||||
</script>
|
||||
<script>
|
||||
window.user = {
|
||||
email: '{{ request.user.email|escapejs }}',
|
||||
id: '{{ request.user.id|escapejs }}',
|
||||
name: '{{ request.user.username|escapejs }}'
|
||||
};
|
||||
</script>
|
||||
{% else %}
|
||||
<script>window.user = {};</script>
|
||||
<script>window.user = {};</script>
|
||||
{% endif %}
|
||||
|
||||
{% if misc_config.analytics %}
|
||||
{{ misc_config.analytics|safe }}
|
||||
{{ misc_config.analytics|safe }}
|
||||
{% endif %}
|
||||
|
||||
{# Don't run userscript since it may be malicious #}
|
||||
{% if request.user.is_authenticated and request.profile.user_script and not request.user.is_impersonate %}
|
||||
<script type="text/javascript">{{ request.profile.user_script|safe }}</script>
|
||||
<script type="text/javascript">{{ request.profile.user_script|safe }}</script>
|
||||
{% endif %}
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
#content {
|
||||
margin: 80px auto auto;
|
||||
}
|
||||
<style>
|
||||
#content {
|
||||
margin: 80px auto auto;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
top: 27px;
|
||||
}
|
||||
</style>
|
||||
#navigation {
|
||||
top: 27px;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
</head>
|
||||
<body>
|
||||
<svg width="0" height="0" style="display: block">
|
||||
<defs>
|
||||
</head>
|
||||
<body>
|
||||
<svg width="0" height="0" style="display: block">
|
||||
<defs>
|
||||
<clipPath id="rating-clip"><circle cx="8" cy="8" r="7"/></clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<nav id="navigation" class="unselectable">
|
||||
<div id="nav-container">
|
||||
</defs>
|
||||
</svg>
|
||||
<nav id="navigation" class="unselectable">
|
||||
<div id="nav-container">
|
||||
<a id="navicon" href="javascript:void(0)"><i class="fa fa-bars"></i></a>
|
||||
<ul id="nav-list">
|
||||
<li class="home-nav-element"><a href="{{ url('home') }}">{% include "site-logo-fragment.html" %}</a></li>
|
||||
<li class="home-nav-element"><span class="nav-divider"></span></li>
|
||||
<li class="home-menu-item"><a href="{{ url('home') }}" class="nav-home">{{ _('Home') }}</a></li>
|
||||
{% for node in mptt_tree(nav_bar) recursive %}
|
||||
<li>
|
||||
<a href="{{ node.path }}" class="nav-{{ node.key }}{% if node.key in nav_tab %} active{% endif %}">
|
||||
{{ user_trans(node.label) }}
|
||||
{% if not node.is_leaf_node %}
|
||||
<div href="javascript:void(0)" class="nav-expand">></div>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% with children=node.get_children() %}
|
||||
{% if children %}<ul>{{ loop(children) }}</ul>{% endif %}
|
||||
{% endwith %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="home-nav-element"><a href="{{ url('home') }}">{% include "site-logo-fragment.html" %}</a></li>
|
||||
<li class="home-nav-element"><span class="nav-divider"></span></li>
|
||||
<li class="home-menu-item"><a href="{{ url('home') }}" class="nav-home">{{ _('Home') }}</a></li>
|
||||
{% for node in mptt_tree(nav_bar) recursive %}
|
||||
<li>
|
||||
<a href="{{ node.path }}" class="nav-{{ node.key }}{% if node.key in nav_tab %} active{% endif %}">
|
||||
{{ user_trans(node.label) }}
|
||||
{% if not node.is_leaf_node %}
|
||||
<div href="javascript:void(0)" class="nav-expand">></div>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% with children=node.get_children() %}
|
||||
{% if children %}<ul>{{ loop(children) }}</ul>{% endif %}
|
||||
{% endwith %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div style="float: right; display: inline-flex; font-size: larger; align-items: center; height: 100%;">
|
||||
<span class="navbar-icons">
|
||||
{% if request.user.is_authenticated %}
|
||||
<span title="{{_('Chat')}}">
|
||||
<a id="chat-icon" href="{{ url('chat', '') }}" class="icofont-wechat navbar-icon" aria-hidden="true">
|
||||
{% set unread_chat = request.profile.count_unread_chat_boxes %}
|
||||
{% if unread_chat %}
|
||||
<sub class="unread_boxes">{{unread_chat}}</sub>
|
||||
{% endif %}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
{% set unseen_cnt = request.profile.count_unseen_notifications %}
|
||||
<span title="{{_('Notification')}}" class="{{ 'notification-open' if unseen_cnt > 0 }}">
|
||||
<a href="{{ url('notification') }}" class="icofont-alarm navbar-icon" id="notification" aria-hidden="true">
|
||||
{% if unseen_cnt > 0 %}
|
||||
<sub class="unread_boxes">{{unseen_cnt}}</sub>
|
||||
{% endif %}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span title="{{_('Language')}}">
|
||||
<a class="icofont-globe navbar-icon" id="nav-lang-icon" aria-hidden="true">
|
||||
<sub class="sub-lang">{{LANGUAGE_CODE}}</sub>
|
||||
</a>
|
||||
<div id="lang-dropdown" class="dropdown" role="tooltip">
|
||||
{% for language in language_info_list(LANGUAGES) %}
|
||||
<div value="{{ language.code }}"
|
||||
class="dropdown-item lang-dropdown-item" style="{{'font-weight: bold' if language.code == LANGUAGE_CODE}}">
|
||||
{{ language.name_local }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</span>
|
||||
<span title="{{_('Dark Mode')}}">
|
||||
<a class="icofont-adjust navbar-icon black" id="nav-darkmode-icon" aria-hidden="true" href="?darkmode=1"></a>
|
||||
</span>
|
||||
</span>
|
||||
<span class="navbar-icons">
|
||||
{% if request.user.is_authenticated %}
|
||||
<span id="user-links">
|
||||
<ul><li><a href="javascript:void(0)">
|
||||
<span>
|
||||
<img src="{{ gravatar(request.user, 32) }}" height="24" width="24">{# -#}
|
||||
<span>
|
||||
<b class="{{request.profile.css_class}}">{{ request.user.username }}</b>
|
||||
</span>
|
||||
</span>
|
||||
</a></li></ul>
|
||||
</span>
|
||||
<div class="dropdown" id="userlink_dropdown" role="tooptip">
|
||||
<div class="dropdown-item"><a href="{{ url('user_page') }}">{{ _('Profile') }}</a></div>
|
||||
{% if request.user.is_staff or request.user.is_superuser %}
|
||||
<div class="dropdown-item"><a href="{{ url('admin:index') }}">{{ _('Admin') }}</a></div>
|
||||
{% endif %}
|
||||
{% if request.user.is_superuser %}
|
||||
<div class="dropdown-item"><a href="{{ url('internal_problem') }}">{{ _('Internal') }}</a></div>
|
||||
<div class="dropdown-item"><a href="{{ url('site_stats') }}">{{ _('Stats') }}</a></div>
|
||||
{% endif %}
|
||||
<div class="dropdown-item"><a href="{{ url('user_edit_profile') }}">{{ _('Edit profile') }}</a></div>
|
||||
{% if request.user.is_impersonate %}
|
||||
<div class="dropdown-item"><a href="{{ url('impersonate-stop') }}">Stop impersonating</a></div>
|
||||
{% else %}
|
||||
<div class="dropdown-item">
|
||||
<a href="#" id="logout" class="red">{{ _('Log out') }}</a>
|
||||
<form id="logout-form" action="{{ url('auth_logout') }}" method="POST">
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="anon">
|
||||
<a href="{{ url('auth_login') }}?next={{ LOGIN_RETURN_PATH|urlencode }}"><b>{{ _('Log in') }}</b></a>
|
||||
{{ _('or') }}
|
||||
<a href="{{ url('registration_register') }}"><b>{{ _('Sign up') }}</b></a>
|
||||
</span>
|
||||
<span title="{{_('Chat')}}">
|
||||
<a id="chat-icon" href="{{ url('chat', '') }}" class="icofont-wechat navbar-icon" aria-hidden="true">
|
||||
{% set unread_chat = request.profile.count_unread_chat_boxes %}
|
||||
{% if unread_chat %}
|
||||
<sub class="unread_boxes">{{unread_chat}}</sub>
|
||||
{% endif %}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
{% set unseen_cnt = request.profile.count_unseen_notifications %}
|
||||
<span title="{{_('Notification')}}" class="{{ 'notification-open' if unseen_cnt > 0 }}">
|
||||
<a href="{{ url('notification') }}" class="icofont-alarm navbar-icon" id="notification" aria-hidden="true">
|
||||
{% if unseen_cnt > 0 %}
|
||||
<sub class="unread_boxes">{{unseen_cnt}}</sub>
|
||||
{% endif %}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span title="{{_('Language')}}">
|
||||
<a class="icofont-globe navbar-icon" id="nav-lang-icon" aria-hidden="true">
|
||||
<sub class="sub-lang">{{LANGUAGE_CODE}}</sub>
|
||||
</a>
|
||||
<div id="lang-dropdown" class="dropdown" role="tooltip">
|
||||
{% for language in language_info_list(LANGUAGES) %}
|
||||
<div value="{{ language.code }}"
|
||||
class="dropdown-item lang-dropdown-item" style="{{'font-weight: bold' if language.code == LANGUAGE_CODE}}">
|
||||
{{ language.name_local }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</span>
|
||||
<span title="{{_('Dark Mode')}}">
|
||||
<a class="icofont-adjust navbar-icon black" id="nav-darkmode-icon" aria-hidden="true" href="?darkmode=1"></a>
|
||||
</span>
|
||||
</span>
|
||||
{% if request.user.is_authenticated %}
|
||||
<span id="user-links">
|
||||
<ul><li><a href="javascript:void(0)">
|
||||
<span>
|
||||
<img src="{{ gravatar(request.user, 32) }}" height="24" width="24">{# -#}
|
||||
<span>
|
||||
<b class="{{request.profile.css_class}}">{{ request.user.username }}</b>
|
||||
</span>
|
||||
</span>
|
||||
</a></li></ul>
|
||||
</span>
|
||||
<div class="dropdown" id="userlink_dropdown" role="tooptip">
|
||||
<div class="dropdown-item"><a href="{{ url('user_page') }}">{{ _('Profile') }}</a></div>
|
||||
{% if request.user.is_staff or request.user.is_superuser %}
|
||||
<div class="dropdown-item"><a href="{{ url('admin:index') }}">{{ _('Admin') }}</a></div>
|
||||
{% endif %}
|
||||
{% if request.user.is_superuser %}
|
||||
<div class="dropdown-item"><a href="{{ url('internal_problem') }}">{{ _('Internal') }}</a></div>
|
||||
<div class="dropdown-item"><a href="{{ url('site_stats') }}">{{ _('Stats') }}</a></div>
|
||||
{% endif %}
|
||||
<div class="dropdown-item"><a href="{{ url('user_edit_profile') }}">{{ _('Edit profile') }}</a></div>
|
||||
{% if request.user.is_impersonate %}
|
||||
<div class="dropdown-item"><a href="{{ url('impersonate-stop') }}">Stop impersonating</a></div>
|
||||
{% else %}
|
||||
<div class="dropdown-item">
|
||||
<a href="#" id="logout" class="red">{{ _('Log out') }}</a>
|
||||
<form id="logout-form" action="{{ url('auth_logout') }}" method="POST">
|
||||
{% csrf_token %}
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="anon">
|
||||
<a href="{{ url('auth_login') }}?next={{ LOGIN_RETURN_PATH|urlencode }}"><b>{{ _('Log in') }}</b></a>
|
||||
{{ _('or') }}
|
||||
<a href="{{ url('registration_register') }}"><b>{{ _('Sign up') }}</b></a>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav-shadow"></div>
|
||||
</nav>
|
||||
{% if request.in_contest %}
|
||||
<div id="contest-info">
|
||||
</div>
|
||||
<div id="nav-shadow"></div>
|
||||
</nav>
|
||||
{% if request.in_contest %}
|
||||
<div id="contest-info">
|
||||
<div id="contest-info-main">
|
||||
<a href="{{ url('contest_view', request.participation.contest.key) }}" style="vertical-align: middle; display: inline">
|
||||
{{ request.participation.contest.name }} -
|
||||
{% if request.participation.spectate %}
|
||||
{{ _('spectating') }}
|
||||
{% elif request.participation.end_time %}
|
||||
<div id="contest-time-remaining" data-secs="{{request.participation.end_time}}">
|
||||
{{ request.participation.time_remaining|timedelta("localized") }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _('virtual') }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a href="{{ url('contest_view', request.participation.contest.key) }}" style="vertical-align: middle; display: inline">
|
||||
{{ request.participation.contest.name }} -
|
||||
{% if request.participation.spectate %}
|
||||
{{ _('spectating') }}
|
||||
{% elif request.participation.end_time %}
|
||||
<div id="contest-time-remaining" data-secs="{{request.participation.end_time}}">
|
||||
{{ request.participation.time_remaining|timedelta("localized") }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ _('virtual') }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
<div id="contest-info-toggle" class="{{'contest-info-toggle-mode-on' if request.contest_mode else 'contest-info-toggle-mode-off'}}">
|
||||
{% if request.contest_mode %}
|
||||
<i class="fa fa-toggle-on white"></i> {{_('Compete')}}
|
||||
{% else %}
|
||||
<i class="fa fa-toggle-off white"></i> {{_('General')}}
|
||||
{% endif %}
|
||||
{% if request.contest_mode %}
|
||||
<i class="fa fa-toggle-on white"></i> {{_('Compete')}}
|
||||
{% else %}
|
||||
<i class="fa fa-toggle-off white"></i> {{_('General')}}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="page-container">
|
||||
<noscript>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="page-container">
|
||||
<noscript>
|
||||
<div id="noscript">{{ _('This site works best with JavaScript enabled.') }}</div>
|
||||
</noscript>
|
||||
<br>
|
||||
<main id="content">
|
||||
</noscript>
|
||||
<br>
|
||||
<main id="content">
|
||||
{% block title_row %}
|
||||
<h2 class="title-row">
|
||||
{% block content_title %}
|
||||
{% if content_title %}{{ content_title }}{% else %}{{ title }}{% endif %}
|
||||
{% endblock %}
|
||||
</h2>
|
||||
<h2 class="title-row">
|
||||
{% block content_title %}
|
||||
{% if content_title %}{{ content_title }}{% else %}{{ title }}{% endif %}
|
||||
{% endblock %}
|
||||
</h2>
|
||||
{% endblock %}
|
||||
{% block header %}{% endblock %}
|
||||
{% block title_ruler %}
|
||||
<hr>
|
||||
<hr>
|
||||
{% endblock %}
|
||||
<div id="content-body">{% block body %}{% endblock %}</div>
|
||||
</main>
|
||||
</main>
|
||||
|
||||
{% if i18n_config.announcement %}
|
||||
{% if i18n_config.announcement %}
|
||||
<div id="announcement">{{ i18n_config.announcement|safe }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% block bodyend %}{% endblock %}
|
||||
{% block footer %}
|
||||
<footer>
|
||||
<span id="footer-content">
|
||||
{% block bodyend %}{% endblock %}
|
||||
{% block footer %}
|
||||
<footer>
|
||||
<span id="footer-content">
|
||||
<br>
|
||||
<a class="background-footer" target="_blank" href="https://dmoj.ca">proudly powered by <b>DMOJ</b></a><a target="_blank" href="https://github.com/LQDJudge/online-judge"> | developed by LQDJudge team</a> |
|
||||
{% if i18n_config.footer %}
|
||||
{{ i18n_config.footer|safe }} |
|
||||
{{ i18n_config.footer|safe }} |
|
||||
{% endif %}
|
||||
<form action="{{ url('set_language') }}" method="post" style="display: inline" id="form-lang">
|
||||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="{{ request.get_full_path() }}">
|
||||
<select name="language" onchange="form.submit()" style="height: 1.5em">
|
||||
{% csrf_token %}
|
||||
<input name="next" type="hidden" value="{{ request.get_full_path() }}">
|
||||
<select name="language" onchange="form.submit()" style="height: 1.5em">
|
||||
{% for language in language_info_list(LANGUAGES) %}
|
||||
<option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %}selected{% endif %}>
|
||||
{{ language.name_local }} ({{ language.code }})
|
||||
</option>
|
||||
<option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %}selected{% endif %}>
|
||||
{{ language.name_local }} ({{ language.code }})
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
</span>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</select>
|
||||
</form>
|
||||
</span>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&family=Noto+Sans&display=swap" rel="stylesheet">
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block js_media %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block media %}
|
||||
{% include "comments/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% include "comments/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block title_row %}
|
||||
|
@ -17,41 +17,41 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="post-full">
|
||||
<div class="post-title">{{ title }}</div>
|
||||
<div class="time">
|
||||
{% with authors=post.authors.all() %}
|
||||
{% if authors %}
|
||||
<span class="post-authors">{{ link_users(authors) }}</span>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<span class="post-time">
|
||||
{% trans time=post.publish_on|date(_("N j, Y, g:i a")) %} posted on {{ time }}{% endtrans %}
|
||||
</span>
|
||||
{% if post.is_editable_by(request.user) %}
|
||||
<span> [<a href="{{ url('admin:judge_blogpost_change', post.id) }}">{{ _('Edit') }}</a>]</span>
|
||||
{% endif %}
|
||||
{% if valid_user_to_show_edit %}
|
||||
{% for org in valid_org_to_show_edit %}
|
||||
<span> [<a href="{{ url('edit_organization_blog', org.id , org.slug , post.id) }}">{{ _('Edit in') }} {{org.slug}}</a>]</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="body content-description">
|
||||
{% cache 86400 'post_content' post.id MATH_ENGINE %}
|
||||
{{ post.content|markdown|reference|str|safe}}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% include "actionbar/list.html" %}
|
||||
<div class="post-full">
|
||||
<div class="post-title">{{ title }}</div>
|
||||
<div class="time">
|
||||
{% with authors=post.authors.all() %}
|
||||
{% if authors %}
|
||||
<span class="post-authors">{{ link_users(authors) }}</span>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<span class="post-time">
|
||||
{% trans time=post.publish_on|date(_("N j, Y, g:i a")) %} posted on {{ time }}{% endtrans %}
|
||||
</span>
|
||||
{% if post.is_editable_by(request.user) %}
|
||||
<span> [<a href="{{ url('admin:judge_blogpost_change', post.id) }}">{{ _('Edit') }}</a>]</span>
|
||||
{% endif %}
|
||||
{% if valid_user_to_show_edit %}
|
||||
{% for org in valid_org_to_show_edit %}
|
||||
<span> [<a href="{{ url('edit_organization_blog', org.id , org.slug , post.id) }}">{{ _('Edit in') }} {{org.slug}}</a>]</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<hr style="width: 60%; margin:4em auto;">
|
||||
{% include "comments/list.html" %}
|
||||
<div class="body content-description">
|
||||
{% cache 86400 'post_content' post.id MATH_ENGINE %}
|
||||
{{ post.content|markdown|reference|str|safe}}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% include "actionbar/list.html" %}
|
||||
</div>
|
||||
<hr style="width: 60%; margin:4em auto;">
|
||||
{% include "comments/list.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyend %}
|
||||
{{ super() }}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% include "comments/math.html" %}
|
||||
{{ super() }}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% include "comments/math.html" %}
|
||||
{% endblock %}
|
|
@ -1,52 +1,52 @@
|
|||
<section class="{% if post.sticky %}sticky {% endif %}blog-box">
|
||||
<div style="margin-bottom: 0.5em">
|
||||
<span class="time">
|
||||
{% with authors=post.authors.all() %}
|
||||
{%- if authors -%}
|
||||
<img src="{{gravatar(authors[0])}}" style="width: 1.5em; border-radius: 50%; margin-bottom: -0.3em">
|
||||
<span class="post-authors">{{ link_users(authors) }}</span>
|
||||
{%- endif -%}
|
||||
{% endwith %}
|
||||
•
|
||||
{{ relative_time(post.publish_on, abs=_('on {time}'), rel=_('{time}')) -}}
|
||||
{%- if post.sticky %} •
|
||||
<i title="Sticky" class="fa fa-star fa-fw"></i>{% endif -%}
|
||||
{% if post.is_organization_private and show_organization_private_icon %}
|
||||
•
|
||||
<span>
|
||||
{% for org in post.organizations.all() %}
|
||||
<span class="organization-tag" style="display: inherit;">
|
||||
<a href="{{ org.get_absolute_url() }}">
|
||||
<i class="fa fa-lock"></i> {{ org.name }}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
<div style="margin-bottom: 0.5em">
|
||||
<span class="time">
|
||||
{% with authors=post.authors.all() %}
|
||||
{%- if authors -%}
|
||||
<img src="{{gravatar(authors[0])}}" style="width: 1.5em; border-radius: 50%; margin-bottom: -0.3em">
|
||||
<span class="post-authors">{{ link_users(authors) }}</span>
|
||||
{%- endif -%}
|
||||
{% endwith %}
|
||||
•
|
||||
{{ relative_time(post.publish_on, abs=_('on {time}'), rel=_('{time}')) -}}
|
||||
{%- if post.sticky %} •
|
||||
<i title="Sticky" class="fa fa-star fa-fw"></i>{% endif -%}
|
||||
{% if post.is_organization_private and show_organization_private_icon %}
|
||||
•
|
||||
<span>
|
||||
{% for org in post.organizations.all() %}
|
||||
<span class="organization-tag" style="display: inherit;">
|
||||
<a href="{{ org.get_absolute_url() }}">
|
||||
<i class="fa fa-lock"></i> {{ org.name }}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</span>
|
||||
<span style="float: right">
|
||||
<a href="{{ url('blog_post', post.id, post.slug) }}#comments" class="blog-comment-count-link">
|
||||
<i class="fa fa-comments blog-comment-icon"></i>
|
||||
<span class="blog-comment-count">
|
||||
{{- post_comment_counts[post.id] or 0 -}}
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
<span style="float: right">
|
||||
<a href="{{ url('blog_post', post.id, post.slug) }}#comments" class="blog-comment-count-link">
|
||||
<i class="fa fa-comments blog-comment-icon"></i>
|
||||
<span class="blog-comment-count">
|
||||
{{- post_comment_counts[post.id] or 0 -}}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<h2 class="title">
|
||||
<a href="{{ url('blog_post', post.id, post.slug) }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
<div class="blog-description">
|
||||
<div class="summary content-description">
|
||||
{% cache 86400 'post_summary' post.id %}
|
||||
{{ post.summary|default(post.content, true)|markdown(lazy_load=True)|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
<h2 class="title">
|
||||
<a href="{{ url('blog_post', post.id, post.slug) }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
<div class="blog-description">
|
||||
<div class="summary content-description">
|
||||
{% cache 86400 'post_summary' post.id %}
|
||||
{{ post.summary|default(post.content, true)|markdown(lazy_load=True)|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% set pagevote = post.pagevote %}
|
||||
{% set bookmark = post.bookmark %}
|
||||
{% set hide_actionbar_comment = True %}
|
||||
{% set include_hr = True %}
|
||||
{% set share_url = request.build_absolute_uri(post.get_absolute_url()) %}
|
||||
{% include "actionbar/list.html" %}
|
||||
</div>
|
||||
{% set pagevote = post.pagevote %}
|
||||
{% set bookmark = post.bookmark %}
|
||||
{% set hide_actionbar_comment = True %}
|
||||
{% set include_hr = True %}
|
||||
{% set share_url = request.build_absolute_uri(post.get_absolute_url()) %}
|
||||
{% include "actionbar/list.html" %}
|
||||
</div>
|
||||
</section>
|
|
@ -1,34 +1,34 @@
|
|||
<div class="sidebox dashboard">
|
||||
<h3>Dashboard <i class="fa fa-dashboard"></i>
|
||||
</h3>
|
||||
<div class="sidebox-content">
|
||||
<div class="user-gravatar">
|
||||
<img src="{{ gravatar(request.user, 135) }}"
|
||||
alt="gravatar" width="135px" height="135px">
|
||||
</div>
|
||||
<div class="recently-attempted">
|
||||
<h4>Recently attempted problems</h4>
|
||||
<ul>
|
||||
{% for code, name, problem_points, user_points, s_date in recently_attempted_problems %}
|
||||
<li>
|
||||
<a href="{{ url('problem_detail', code) }}">{{ name }}</a>
|
||||
[<a href="{{ url('user_submissions', code, request.user.username }}">
|
||||
{{- user_points }}/{{ problem_points|floatformat }}</a>]
|
||||
|
||||
<span class="time">
|
||||
<span data-unix="{{ submission.date|utc|date("c") }}"
|
||||
class="recent-time moment-time-toggle">
|
||||
{% trans time=submission.date|date(_("N j, Y, g:i a")) %}
|
||||
on {{ time }}
|
||||
{% endtrans %}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="recommended-problems">
|
||||
<h4>Recommended problems</h4><i>Coming soon.</i>
|
||||
</div>
|
||||
<h3>Dashboard <i class="fa fa-dashboard"></i>
|
||||
</h3>
|
||||
<div class="sidebox-content">
|
||||
<div class="user-gravatar">
|
||||
<img src="{{ gravatar(request.user, 135) }}"
|
||||
alt="gravatar" width="135px" height="135px">
|
||||
</div>
|
||||
<div class="recently-attempted">
|
||||
<h4>Recently attempted problems</h4>
|
||||
<ul>
|
||||
{% for code, name, problem_points, user_points, s_date in recently_attempted_problems %}
|
||||
<li>
|
||||
<a href="{{ url('problem_detail', code) }}">{{ name }}</a>
|
||||
[<a href="{{ url('user_submissions', code, request.user.username }}">
|
||||
{{- user_points }}/{{ problem_points|floatformat }}</a>]
|
||||
|
||||
<span class="time">
|
||||
<span data-unix="{{ submission.date|utc|date("c") }}"
|
||||
class="recent-time moment-time-toggle">
|
||||
{% trans time=submission.date|date(_("N j, Y, g:i a")) %}
|
||||
on {{ time }}
|
||||
{% endtrans %}
|
||||
</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="recommended-problems">
|
||||
<h4>Recommended problems</h4><i>Coming soon.</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,115 +1,115 @@
|
|||
{% extends "three-column-content.html" %}
|
||||
{% block three_col_media %}
|
||||
{% include "blog/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
<style>
|
||||
@media (max-width: 799px) {
|
||||
.title {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
margin-left: 0;
|
||||
}
|
||||
{% include "blog/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
<style>
|
||||
@media (max-width: 799px) {
|
||||
.title {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.no-clarifications-message {
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
.no-clarifications-message {
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
{% include "actionbar/media-js.html" %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
|
||||
$('.right-sidebar').hide();
|
||||
$('#event-tab').click(function (e) {
|
||||
e.preventDefault();
|
||||
$('.left-sidebar-item').removeClass('active');
|
||||
$('#event-tab').addClass('active');
|
||||
$('.middle-content').hide();
|
||||
$('.right-sidebar').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
$('.right-sidebar').hide();
|
||||
$('#event-tab').click(function (e) {
|
||||
e.preventDefault();
|
||||
$('.left-sidebar-item').removeClass('active');
|
||||
$('#event-tab').addClass('active');
|
||||
$('.middle-content').hide();
|
||||
$('.right-sidebar').show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('blog', 'fa fa-rss', url('home'), _('News')) }}
|
||||
{{ make_tab_item('comment', 'fa fa-comments', url('comment_feed'), _('Comments')) }}
|
||||
{{ make_tab_item('ticket', 'fa fa-question-circle', url('ticket_feed'), _('Tickets')) }}
|
||||
{{ make_tab_item('event', 'fa fa-calendar', '#', _('Events')) }}
|
||||
</div>
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('blog', 'fa fa-rss', url('home'), _('News')) }}
|
||||
{{ make_tab_item('comment', 'fa fa-comments', url('comment_feed'), _('Comments')) }}
|
||||
{{ make_tab_item('ticket', 'fa fa-question-circle', url('ticket_feed'), _('Tickets')) }}
|
||||
{{ make_tab_item('event', 'fa fa-calendar', '#', _('Events')) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% set show_organization_private_icon=True %}
|
||||
{% if page_type == 'blog' %}
|
||||
{% for post in posts %}
|
||||
{% include "blog/content.html" %}
|
||||
{% endfor %}
|
||||
{% elif page_type == 'ticket' %}
|
||||
{% if tickets %}
|
||||
{% for ticket in tickets %}
|
||||
{% include "ticket/feed.html" %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
|
||||
{% endif %}
|
||||
{% elif page_type == 'comment' %}
|
||||
{% for comment in comments %}
|
||||
{% include "comments/feed.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if page_obj.num_pages > 1 %}
|
||||
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
|
||||
{% set show_organization_private_icon=True %}
|
||||
{% if page_type == 'blog' %}
|
||||
{% for post in posts %}
|
||||
{% include "blog/content.html" %}
|
||||
{% endfor %}
|
||||
{% elif page_type == 'ticket' %}
|
||||
{% if tickets %}
|
||||
{% for ticket in tickets %}
|
||||
{% include "ticket/feed.html" %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
|
||||
{% endif %}
|
||||
{% elif page_type == 'comment' %}
|
||||
{% for comment in comments %}
|
||||
{% include "comments/feed.html" %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if page_obj.num_pages > 1 %}
|
||||
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block right_sidebar %}
|
||||
<div class="right-sidebar">
|
||||
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Clarifications') }}
|
||||
<i class="fa fa-question-circle"></i>
|
||||
{% if can_edit_contest %}
|
||||
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
|
||||
class="fa fa-plus-circle"
|
||||
id="add-clarification"
|
||||
title="{{_('Add')}}"
|
||||
style="color: lightcyan">
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
<div class="sidebox-content">
|
||||
{% if has_clarifications %}
|
||||
<ul>
|
||||
{% for clarification in clarifications %}
|
||||
<li class="clarification">
|
||||
<a href="{{ url('problem_detail', clarification.problem.problem.code) }}"
|
||||
class="problem">
|
||||
{{ clarification.problem.problem.name }}
|
||||
</a>
|
||||
<span class="time">{{ relative_time(clarification.date) }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="no-clarifications-message">
|
||||
{{ _('No clarifications have been made at this time.') }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% include 'contests-countdown.html' %}
|
||||
{% include 'recent-organization.html' %}
|
||||
{% include 'top-users.html' %}
|
||||
</div>
|
||||
<div class="right-sidebar">
|
||||
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Clarifications') }}
|
||||
<i class="fa fa-question-circle"></i>
|
||||
{% if can_edit_contest %}
|
||||
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
|
||||
class="fa fa-plus-circle"
|
||||
id="add-clarification"
|
||||
title="{{_('Add')}}"
|
||||
style="color: lightcyan">
|
||||
</a>
|
||||
{% endif %}
|
||||
</h3>
|
||||
<div class="sidebox-content">
|
||||
{% if has_clarifications %}
|
||||
<ul>
|
||||
{% for clarification in clarifications %}
|
||||
<li class="clarification">
|
||||
<a href="{{ url('problem_detail', clarification.problem.problem.code) }}"
|
||||
class="problem">
|
||||
{{ clarification.problem.problem.name }}
|
||||
</a>
|
||||
<span class="time">{{ relative_time(clarification.date) }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="no-clarifications-message">
|
||||
{{ _('No clarifications have been made at this time.') }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% include 'contests-countdown.html' %}
|
||||
{% include 'recent-organization.html' %}
|
||||
{% include 'top-users.html' %}
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,30 +1,30 @@
|
|||
<style>
|
||||
.user-gravatar {
|
||||
display: inline-block;
|
||||
padding-right: 15px;
|
||||
padding-top: 8px;
|
||||
width: 135px;
|
||||
}
|
||||
.user-gravatar {
|
||||
display: inline-block;
|
||||
padding-right: 15px;
|
||||
padding-top: 8px;
|
||||
width: 135px;
|
||||
}
|
||||
|
||||
.user-gravatar img {
|
||||
width: 135px;
|
||||
height: 135px;
|
||||
display: block;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.user-gravatar img {
|
||||
width: 135px;
|
||||
height: 135px;
|
||||
display: block;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.recently-attempted, .recommended-problems {
|
||||
display: inline-block;
|
||||
}
|
||||
.recently-attempted, .recommended-problems {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.recently-attempted ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
padding-right: .5em;
|
||||
margin: 0.2em;
|
||||
}
|
||||
.recently-attempted ul {
|
||||
list-style: none;
|
||||
padding-left: 1em;
|
||||
padding-right: .5em;
|
||||
margin: 0.2em;
|
||||
}
|
||||
|
||||
.recently-attempted h4, .recommended-problems h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
.recently-attempted h4, .recommended-problems h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load diff
|
@ -1,134 +1,134 @@
|
|||
<style>
|
||||
footer {
|
||||
display: none;
|
||||
}
|
||||
footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 2.5em 1em 0 0;
|
||||
}
|
||||
#content {
|
||||
margin: 2.5em 1em 0 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 20px;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #d6dee1;
|
||||
border-radius: 20px;
|
||||
border: 6px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #d6dee1;
|
||||
border-radius: 20px;
|
||||
border: 6px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #a8bbbf;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #a8bbbf;
|
||||
}
|
||||
|
||||
#page-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.body-message img{
|
||||
max-height: 12em;
|
||||
}
|
||||
|
||||
.tooltip:not(.shown) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
left: 120vh !important;
|
||||
transform: translate(100px, 0) !important;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#loader {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 4%;
|
||||
}
|
||||
.profile-pic {
|
||||
height: 2.6em;
|
||||
width: 2.6em;
|
||||
border-radius: 0.3em;
|
||||
margin-top: 0.1em;
|
||||
float: left;
|
||||
}
|
||||
.body-message {
|
||||
padding-left: 3em;
|
||||
padding-bottom: 0.5em;
|
||||
border-bottom: 1px dotted lightgray;
|
||||
}
|
||||
.user-time {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
.time {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.content-message {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.content-message p {
|
||||
margin: 0;
|
||||
}
|
||||
#content {
|
||||
width: 100%;
|
||||
}
|
||||
#content-body {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
#page-container {
|
||||
min-height: 0;
|
||||
}
|
||||
.sidebox h3 {
|
||||
border-radius: 0;
|
||||
margin: -1px -5.5px 0 -5.8px;
|
||||
}
|
||||
.body-block {
|
||||
border-radius: 4px;
|
||||
padding: 0.05em 0.6em;
|
||||
width: 100%;
|
||||
}
|
||||
#search-form {
|
||||
float: inherit;
|
||||
}
|
||||
#search-container {
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
#setting {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 800px) {
|
||||
#page-container {
|
||||
width: 100%;
|
||||
position:fixed;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.body-message img{
|
||||
max-height: 12em;
|
||||
}
|
||||
@media (max-width: 799px) {
|
||||
html, body {
|
||||
max-width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.tooltip:not(.shown) {
|
||||
display: none;
|
||||
#mobile ul {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
.info-pic {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
left: 120vh !important;
|
||||
transform: translate(100px, 0) !important;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#loader {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 4%;
|
||||
}
|
||||
.profile-pic {
|
||||
height: 2.6em;
|
||||
width: 2.6em;
|
||||
border-radius: 0.3em;
|
||||
margin-top: 0.1em;
|
||||
float: left;
|
||||
}
|
||||
.body-message {
|
||||
padding-left: 3em;
|
||||
padding-bottom: 0.5em;
|
||||
border-bottom: 1px dotted lightgray;
|
||||
}
|
||||
.user-time {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
.time {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.content-message {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.content-message p {
|
||||
margin: 0;
|
||||
}
|
||||
#content {
|
||||
width: 100%;
|
||||
}
|
||||
#content-body {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
#page-container {
|
||||
min-height: 0;
|
||||
}
|
||||
.sidebox h3 {
|
||||
border-radius: 0;
|
||||
margin: -1px -5.5px 0 -5.8px;
|
||||
}
|
||||
.body-block {
|
||||
border-radius: 4px;
|
||||
padding: 0.05em 0.6em;
|
||||
width: 100%;
|
||||
}
|
||||
#search-form {
|
||||
float: inherit;
|
||||
}
|
||||
#search-container {
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
#setting {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 800px) {
|
||||
#page-container {
|
||||
position:fixed;
|
||||
overflow:hidden;
|
||||
}
|
||||
}
|
||||
@media (max-width: 799px) {
|
||||
html, body {
|
||||
max-width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
#mobile ul {
|
||||
width: 100%;
|
||||
}
|
||||
.info-pic {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.active-span {
|
||||
display: none;
|
||||
}
|
||||
.active-span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
<li class="message" id="message-{{ message.id }}">
|
||||
<a href="{{ url('user_page', message.author.user.username) }}">
|
||||
<img src="{{ gravatar(message.author, 135) }}" class="profile-pic">
|
||||
</a>
|
||||
<div class="body-message">
|
||||
<div class="user-time">
|
||||
<span class="username {{ message.author.css_class }}">
|
||||
<a href="{{ url('user_page', message.author.user.username) }}">
|
||||
{{ message.author }}
|
||||
</a>
|
||||
</span>
|
||||
<span class="time">
|
||||
{{ relative_time(message.time, abs=_('{time}'), rel=_('{time}'), format=_('g:i a d/m/Y')) }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="content-message">
|
||||
<div class="body-block" id="body-block-{{ message.id }}" title="{{ message.time|date('g:i a') }}">
|
||||
{% if request.user.is_staff %}
|
||||
<a class="red chatbtn_remove_mess" value="{{message.id}}" style="cursor: pointer;">
|
||||
{{_('Delete')}}
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="message-text message-text-other">
|
||||
{{message.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<a href="{{ url('user_page', message.author.user.username) }}">
|
||||
<img src="{{ gravatar(message.author, 135) }}" class="profile-pic">
|
||||
</a>
|
||||
<div class="body-message">
|
||||
<div class="user-time">
|
||||
<span class="username {{ message.author.css_class }}">
|
||||
<a href="{{ url('user_page', message.author.user.username) }}">
|
||||
{{ message.author }}
|
||||
</a>
|
||||
</span>
|
||||
<span class="time">
|
||||
{{ relative_time(message.time, abs=_('{time}'), rel=_('{time}'), format=_('g:i a d/m/Y')) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<span class="content-message">
|
||||
<div class="body-block" id="body-block-{{ message.id }}" title="{{ message.time|date('g:i a') }}">
|
||||
{% if request.user.is_staff %}
|
||||
<a class="red chatbtn_remove_mess" value="{{message.id}}" style="cursor: pointer;">
|
||||
{{_('Delete')}}
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="message-text message-text-other">
|
||||
{{message.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</li>
|
|
@ -1,12 +1,12 @@
|
|||
{% if object_list %}
|
||||
<div style="display: none" id="num_pages">{{num_pages}}</div>
|
||||
{% for message in object_list | reverse%}
|
||||
<div style="display: none" id="num_pages">{{num_pages}}</div>
|
||||
{% for message in object_list | reverse%}
|
||||
{% include "chat/message.html" %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<center id="empty_msg">{{_('You are connect now. Say something to start the conversation.')}}</center>
|
||||
<center id="empty_msg">{{_('You are connect now. Say something to start the conversation.')}}</center>
|
||||
{% endif %}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% include "comments/math.html" %}
|
|
@ -1,40 +1,40 @@
|
|||
<li class="status-row" id="lobby_row">
|
||||
<div class="status-container">
|
||||
<img src="{{ static('icons/logo.png') }}" style="height:1.3em">
|
||||
</div>
|
||||
<span style="padding-left:0.5em">
|
||||
<b>{{_('Lobby')}}</b>
|
||||
</span>
|
||||
<span class="spacer">
|
||||
<span class="unread-count" id="unread-count-lobby">{{unread_count_lobby if unread_count_lobby}}</span>
|
||||
</span>
|
||||
<div class="status-container">
|
||||
<img src="{{ static('icons/logo.png') }}" style="height:1.3em">
|
||||
</div>
|
||||
<span style="padding-left:0.5em">
|
||||
<b>{{_('Lobby')}}</b>
|
||||
</span>
|
||||
<span class="spacer">
|
||||
<span class="unread-count" id="unread-count-lobby">{{unread_count_lobby if unread_count_lobby}}</span>
|
||||
</span>
|
||||
</li>
|
||||
{% for section in status_sections %}
|
||||
{% if section.user_list %}
|
||||
<div class="status-section-title toggle open">
|
||||
<h4>
|
||||
<i class="fa fa-chevron-right fa-fw"></i>{{_(section.title)}}
|
||||
</h4>
|
||||
<hr/>
|
||||
</div>
|
||||
<ul class="status-list toggled">
|
||||
{% for user in section.user_list %}
|
||||
<li class="click_space status-row" id="click_space_{{user.user.id}}" value="{{user.url}}">
|
||||
<div class="status-container">
|
||||
<img src="{{ gravatar(user.user, 135) }}" class="status-pic">
|
||||
<svg style="position:absolute;" height="32" width="32">
|
||||
<circle class="status-circle"
|
||||
fill="{{'green' if user.is_online else 'red'}}"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span style="padding-left:0.3em" class="username {{ user.user.css_class }}">
|
||||
{{ user.user.username }}
|
||||
</span>
|
||||
<span class="spacer">
|
||||
<span class="unread-count" id="unread-count-{{user.user.id}}">{{user.unread_count if user.unread_count}}</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if section.user_list %}
|
||||
<div class="status-section-title toggle open">
|
||||
<h4>
|
||||
<i class="fa fa-chevron-right fa-fw"></i>{{_(section.title)}}
|
||||
</h4>
|
||||
<hr/>
|
||||
</div>
|
||||
<ul class="status-list toggled">
|
||||
{% for user in section.user_list %}
|
||||
<li class="click_space status-row" id="click_space_{{user.user.id}}" value="{{user.url}}">
|
||||
<div class="status-container">
|
||||
<img src="{{ gravatar(user.user, 135) }}" class="status-pic">
|
||||
<svg style="position:absolute;" height="32" width="32">
|
||||
<circle class="status-circle"
|
||||
fill="{{'green' if user.is_online else 'red'}}"/>
|
||||
</svg>
|
||||
</div>
|
||||
<span style="padding-left:0.3em" class="username {{ user.user.css_class }}">
|
||||
{{ user.user.username }}
|
||||
</span>
|
||||
<span class="spacer">
|
||||
<span class="unread-count" id="unread-count-{{user.user.id}}">{{user.unread_count if user.unread_count}}</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
{% if other_user %}
|
||||
<div class="status-container" style="height: 100%">
|
||||
<div class="status-container" style="height: 100%">
|
||||
<img src="{{ gravatar(other_user.user, 135) }}" class="info-pic">
|
||||
<svg style="position:absolute; height:100%; width: 110%">
|
||||
<circle class="info-circle"
|
||||
fill="{{'green' if other_online else 'red'}}"/>
|
||||
<circle class="info-circle"
|
||||
fill="{{'green' if other_online else 'red'}}"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<span class="info-name username">
|
||||
{% if other_user %}
|
||||
{% if other_user %}
|
||||
<a href="{{url('user_page', other_user)}}">{{other_user.user.username}}</a>
|
||||
{% else%}
|
||||
{% else%}
|
||||
<a href="#" style="margin-left: 3em">{{ _('Lobby') }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
{% if other_user and not other_online %}
|
||||
<span class="active-span">{{ relative_time(other_user.last_access, abs=_('Last online on {time}'), rel=_('Online {time}'), format=_('g:i a d/m/Y')) }}</span>
|
||||
<span class="active-span">{{ relative_time(other_user.last_access, abs=_('Last online on {time}'), rel=_('Online {time}'), format=_('g:i a d/m/Y')) }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if other_user %}
|
||||
<span style="margin-right: 0.3em" id="setting">
|
||||
<span style="margin-right: 0.3em" id="setting">
|
||||
<button class="control-button small" style="height:100%;" id="setting-button">
|
||||
<i class="fa fa-ellipsis-h"></i>
|
||||
<i class="fa fa-ellipsis-h"></i>
|
||||
</button>
|
||||
<div id="setting-content">
|
||||
<li>
|
||||
<a href="{{url('toggle_ignore', other_user.id)}}" class=" {{'green' if is_ignored else 'red'}}">
|
||||
{% if is_ignored %}
|
||||
{{_('Unignore')}}
|
||||
{% else %}
|
||||
{{_('Ignore')}}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{url('toggle_ignore', other_user.id)}}" class=" {{'green' if is_ignored else 'red'}}">
|
||||
{% if is_ignored %}
|
||||
{{_('Unignore')}}
|
||||
{% else %}
|
||||
{{_('Ignore')}}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="active-span">{{online_count}} {{_('users are online')}}</span>
|
||||
<span class="active-span">{{online_count}} {{_('users are online')}}</span>
|
||||
{% endif %}
|
|
@ -1,14 +1,14 @@
|
|||
<div class="comment-submit">
|
||||
<form id="comment-edit" action="{{ request.get_full_path() }}" method="post">
|
||||
<span style="display: none" class="comment-id">{{ comment.id }}</span>
|
||||
<span style="display: none" class="read-back">{{ url('comment_content', comment.id) }}</span>
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.body.errors }}
|
||||
<div class="comment-post-wrapper">
|
||||
<div id="comment-form-body">{{ form.body }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<input style="float: right" type="submit" value="Post!" class="button">
|
||||
</form>
|
||||
<form id="comment-edit" action="{{ request.get_full_path() }}" method="post">
|
||||
<span style="display: none" class="comment-id">{{ comment.id }}</span>
|
||||
<span style="display: none" class="read-back">{{ url('comment_content', comment.id) }}</span>
|
||||
{% csrf_token %}
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.body.errors }}
|
||||
<div class="comment-post-wrapper">
|
||||
<div id="comment-form-body">{{ form.body }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<input style="float: right" type="submit" value="Post!" class="button">
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
{% block media %}
|
||||
{% compress css %}
|
||||
{{ form.media.css }}
|
||||
{% endcompress %}
|
||||
{% compress css %}
|
||||
{{ form.media.css }}
|
||||
{% endcompress %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js_media %}
|
||||
{{ form.media.js }}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div class="form-area">{% include "comments/edit-ajax.html" %}</div>
|
||||
<div class="form-area">{% include "comments/edit-ajax.html" %}</div>
|
||||
{% endblock %}
|
|
@ -1,18 +1,18 @@
|
|||
<div class="blog-box">
|
||||
<h3 class="problem-feed-name">
|
||||
<a href="{{ comment.link }}#comment-{{ comment.id }}">
|
||||
{{ page_titles[comment.page] }}
|
||||
</a>
|
||||
</h3>
|
||||
{% with author=comment.author %}
|
||||
{% if author %}
|
||||
<div class="problem-feed-info-entry">
|
||||
<i class="fa fa-pencil-square-o fa-fw"></i>
|
||||
<span class="pi-value">{{ link_user(author) }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class='blog-description content-description'>
|
||||
{{ comment.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
<h3 class="problem-feed-name">
|
||||
<a href="{{ comment.link }}#comment-{{ comment.id }}">
|
||||
{{ page_titles[comment.page] }}
|
||||
</a>
|
||||
</h3>
|
||||
{% with author=comment.author %}
|
||||
{% if author %}
|
||||
<div class="problem-feed-info-entry">
|
||||
<i class="fa fa-pencil-square-o fa-fw"></i>
|
||||
<span class="pi-value">{{ link_user(author) }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<div class='blog-description content-description'>
|
||||
{{ comment.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
</div>
|
|
@ -1,165 +1,165 @@
|
|||
{% set can_comment = request.user.is_authenticated and comment_form and not comment_lock %}
|
||||
<div id="comments" class="comment-area">
|
||||
<h2 id="comment-header">
|
||||
<i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }}
|
||||
{% if can_comment %}
|
||||
<a href="" id="write-comment" style="float: right; font-size: 0.6em; margin-right: -26px;"> {{ _('Write comment') }} </a>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<h2 id="comment-header">
|
||||
<i style="padding-right: 0.3em" class="fa fa-comments"></i>{{ _('Comments') }}
|
||||
{% if can_comment %}
|
||||
<div id="new-comment" class="form-area comment-submit" style="display: none;" >
|
||||
{% block comment_submit_title %}
|
||||
<h3>{{ _('New comment') }}</h3>
|
||||
<hr>
|
||||
{% endblock %}
|
||||
{% if is_new_user %}
|
||||
<div style="margin-bottom: 0" class="alert alert-info">
|
||||
{{ _('You need to have solved at least one problem before your voice can be heard.') }}
|
||||
<a href="" id="write-comment" style="float: right; font-size: 0.6em; margin-right: -26px;"> {{ _('Write comment') }} </a>
|
||||
{% endif %}
|
||||
</h2>
|
||||
{% if can_comment %}
|
||||
<div id="new-comment" class="form-area comment-submit" style="display: none;" >
|
||||
{% block comment_submit_title %}
|
||||
<h3>{{ _('New comment') }}</h3>
|
||||
<hr>
|
||||
{% endblock %}
|
||||
{% if is_new_user %}
|
||||
<div style="margin-bottom: 0" class="alert alert-info">
|
||||
{{ _('You need to have solved at least one problem before your voice can be heard.') }}
|
||||
</div>
|
||||
{% else %}
|
||||
<form class="comment-submit-form" action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if comment_form.errors %}
|
||||
<div id="form-errors">
|
||||
{{ comment_form.non_field_errors() }}
|
||||
{{ comment_form.parent.errors }}
|
||||
{% if comment_form.body.errors %}{{ _('Invalid comment body.') }}{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ comment_form.parent }}
|
||||
<div class="comment-post-wrapper">
|
||||
<div id="comment-form-body">{{ comment_form.body }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<input style="float:right" type="submit" value="{{ _('Post!') }}" class="button">
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if has_comments %}
|
||||
<ul class="comments top-level-comments new-comments">
|
||||
{% set logged_in = request.user.is_authenticated %}
|
||||
{% set profile = request.profile if logged_in else None %}
|
||||
{% for node in mptt_tree(comment_list) recursive %}
|
||||
<li id="comment-{{ node.id }}" data-revision="{{ node.revisions - 1 }}"
|
||||
data-max-revision="{{ node.revisions - 1 }}"
|
||||
data-revision-ajax="{{ url('comment_revision_ajax', node.id) }}" class="comment">
|
||||
<div class="comment-display{% if node.score <= vote_hide_threshold %} bad-comment{% endif %}">
|
||||
<div class="info">
|
||||
<div class="vote">
|
||||
{% if logged_in %}
|
||||
<a href="javascript:comment_upvote({{ node.id }})"
|
||||
class="upvote-link fa fa-chevron-up fa-fw{% if node.vote_score == 1 %} voted{% endif %}"></a>
|
||||
{% else %}
|
||||
<a href="javascript:alert('{{ _('Please login to vote')|escapejs }}')" title="{{ _('Please login to vote') }}"
|
||||
class="upvote-link fa fa-chevron-up fa-fw"></a>
|
||||
{% endif %}
|
||||
<br>
|
||||
<div class="comment-score">{{ node.score }}</div>
|
||||
{% if logged_in %}
|
||||
<a href="javascript:comment_downvote({{ node.id }})"
|
||||
class="downvote-link fa fa-chevron-down fa-fw{% if node.vote_score == -1 %} voted{% endif %}"></a>
|
||||
{% else %}
|
||||
<a href="javascript:alert('{{ _('Please login to vote')|escapejs }}')" title="{{ _('Please login to vote') }}"
|
||||
class="downvote-link fa fa-chevron-down fa-fw"></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with author=node.author, user=node.author.user %}
|
||||
<a href="{{ url('user_page', user.username) }}" class="user">
|
||||
<img src="{{ gravatar(author, 135) }}" class="gravatar">
|
||||
</a>
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="header">
|
||||
{{ link_user(node.author) }}
|
||||
{{ relative_time(node.time, abs=_('commented on {time}'), rel=_('commented {time}')) }}
|
||||
<span class="comment-spacer"></span>
|
||||
<span class="comment-operation">
|
||||
{% if node.revisions > 1 %}
|
||||
<span class="comment-edits">
|
||||
<a href="javascript:show_revision({{ node.id }}, -1)"
|
||||
class="previous-revision">←</a>
|
||||
<span class="comment-edit-text">
|
||||
{% if node.revisions > 2 %}
|
||||
{% trans edits=node.revisions - 1 %}edit {{ edits }}{% endtrans %}
|
||||
{% else %}
|
||||
{{ _('edited') }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<a href="javascript:show_revision({{ node.id }}, 1)" style="visibility: hidden"
|
||||
class="next-revision">→</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="comment-edits"></span>
|
||||
{% endif %}
|
||||
<a href="#comment-{{ node.id }}" title="{{ _('Link') }}" class="comment-link">
|
||||
<i class="fa fa-link fa-fw"></i>
|
||||
</a>
|
||||
{% if logged_in and not comment_lock %}
|
||||
{% set can_edit = node.author.id == profile.id and not profile.mute %}
|
||||
{% if can_edit %}
|
||||
<a data-featherlight="{{ url('comment_edit_ajax', node.id) }}"
|
||||
href="{{ url('comment_edit', node.id) }}"
|
||||
title="{{ _('Edit') }}" class="edit-link">
|
||||
<i class="fa fa-pencil fa-fw"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="javascript:reply_comment({{ node.id }})"
|
||||
title="{{ _('Reply') }}">
|
||||
<i class="fa fa-reply fa-fw"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.judge.change_comment %}
|
||||
{% if can_edit %}
|
||||
<a href="javascript:reply_comment({{ node.id }})"
|
||||
title="{{ _('Reply') }}"><i class="fa fa-reply fa-fw"></i></a>
|
||||
{% else %}
|
||||
<a data-featherlight="{{ url('comment_edit_ajax', node.id) }}"
|
||||
href="{{ url('comment_edit', node.id) }}" title="{{ _('Edit') }}"
|
||||
class="edit-link"><i class="fa fa-pencil fa-fw"></i></a>
|
||||
{% endif %}
|
||||
<a href="javascript:" title="{{ _('Hide') }}" data-id="{{ node.id }}"
|
||||
class="hide-comment"><i class="fa fa-trash fa-fw"></i></a>
|
||||
<a href="{{ url('admin:judge_comment_change', node.id) }}"
|
||||
title="{{ _('Admin') }}"><i class="fa fa-cog fa-fw"></i></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="content content-description">
|
||||
<div class="comment-body"{% if node.score <= vote_hide_threshold %} style="display:none"{% endif %}>
|
||||
{{ node.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
{% else %}
|
||||
<form class="comment-submit-form" action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if comment_form.errors %}
|
||||
<div id="form-errors">
|
||||
{{ comment_form.non_field_errors() }}
|
||||
{{ comment_form.parent.errors }}
|
||||
{% if comment_form.body.errors %}{{ _('Invalid comment body.') }}{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ comment_form.parent }}
|
||||
<div class="comment-post-wrapper">
|
||||
<div id="comment-form-body">{{ comment_form.body }}</div>
|
||||
</div>
|
||||
<hr>
|
||||
<input style="float:right" type="submit" value="{{ _('Post!') }}" class="button">
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if has_comments %}
|
||||
<ul class="comments top-level-comments new-comments">
|
||||
{% set logged_in = request.user.is_authenticated %}
|
||||
{% set profile = request.profile if logged_in else None %}
|
||||
{% for node in mptt_tree(comment_list) recursive %}
|
||||
<li id="comment-{{ node.id }}" data-revision="{{ node.revisions - 1 }}"
|
||||
data-max-revision="{{ node.revisions - 1 }}"
|
||||
data-revision-ajax="{{ url('comment_revision_ajax', node.id) }}" class="comment">
|
||||
<div class="comment-display{% if node.score <= vote_hide_threshold %} bad-comment{% endif %}">
|
||||
<div class="info">
|
||||
<div class="vote">
|
||||
{% if logged_in %}
|
||||
<a href="javascript:comment_upvote({{ node.id }})"
|
||||
class="upvote-link fa fa-chevron-up fa-fw{% if node.vote_score == 1 %} voted{% endif %}"></a>
|
||||
{% else %}
|
||||
<a href="javascript:alert('{{ _('Please login to vote')|escapejs }}')" title="{{ _('Please login to vote') }}"
|
||||
class="upvote-link fa fa-chevron-up fa-fw"></a>
|
||||
{% endif %}
|
||||
<br>
|
||||
<div class="comment-score">{{ node.score }}</div>
|
||||
{% if logged_in %}
|
||||
<a href="javascript:comment_downvote({{ node.id }})"
|
||||
class="downvote-link fa fa-chevron-down fa-fw{% if node.vote_score == -1 %} voted{% endif %}"></a>
|
||||
{% else %}
|
||||
<a href="javascript:alert('{{ _('Please login to vote')|escapejs }}')" title="{{ _('Please login to vote') }}"
|
||||
class="downvote-link fa fa-chevron-down fa-fw"></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% with author=node.author, user=node.author.user %}
|
||||
<a href="{{ url('user_page', user.username) }}" class="user">
|
||||
<img src="{{ gravatar(author, 135) }}" class="gravatar">
|
||||
</a>
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="detail">
|
||||
<div class="header">
|
||||
{{ link_user(node.author) }}
|
||||
{{ relative_time(node.time, abs=_('commented on {time}'), rel=_('commented {time}')) }}
|
||||
<span class="comment-spacer"></span>
|
||||
<span class="comment-operation">
|
||||
{% if node.revisions > 1 %}
|
||||
<span class="comment-edits">
|
||||
<a href="javascript:show_revision({{ node.id }}, -1)"
|
||||
class="previous-revision">←</a>
|
||||
<span class="comment-edit-text">
|
||||
{% if node.revisions > 2 %}
|
||||
{% trans edits=node.revisions - 1 %}edit {{ edits }}{% endtrans %}
|
||||
{% else %}
|
||||
{{ _('edited') }}
|
||||
{% endif %}
|
||||
</span>
|
||||
<a href="javascript:show_revision({{ node.id }}, 1)" style="visibility: hidden"
|
||||
class="next-revision">→</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="comment-edits"></span>
|
||||
{% endif %}
|
||||
<a href="#comment-{{ node.id }}" title="{{ _('Link') }}" class="comment-link">
|
||||
<i class="fa fa-link fa-fw"></i>
|
||||
</a>
|
||||
{% if logged_in and not comment_lock %}
|
||||
{% set can_edit = node.author.id == profile.id and not profile.mute %}
|
||||
{% if can_edit %}
|
||||
<a data-featherlight="{{ url('comment_edit_ajax', node.id) }}"
|
||||
href="{{ url('comment_edit', node.id) }}"
|
||||
title="{{ _('Edit') }}" class="edit-link">
|
||||
<i class="fa fa-pencil fa-fw"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="javascript:reply_comment({{ node.id }})"
|
||||
title="{{ _('Reply') }}">
|
||||
<i class="fa fa-reply fa-fw"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.judge.change_comment %}
|
||||
{% if can_edit %}
|
||||
<a href="javascript:reply_comment({{ node.id }})"
|
||||
title="{{ _('Reply') }}"><i class="fa fa-reply fa-fw"></i></a>
|
||||
{% else %}
|
||||
<a data-featherlight="{{ url('comment_edit_ajax', node.id) }}"
|
||||
href="{{ url('comment_edit', node.id) }}" title="{{ _('Edit') }}"
|
||||
class="edit-link"><i class="fa fa-pencil fa-fw"></i></a>
|
||||
{% endif %}
|
||||
<a href="javascript:" title="{{ _('Hide') }}" data-id="{{ node.id }}"
|
||||
class="hide-comment"><i class="fa fa-trash fa-fw"></i></a>
|
||||
<a href="{{ url('admin:judge_comment_change', node.id) }}"
|
||||
title="{{ _('Admin') }}"><i class="fa fa-cog fa-fw"></i></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="content content-description">
|
||||
<div class="comment-body"{% if node.score <= vote_hide_threshold %} style="display:none"{% endif %}>
|
||||
{{ node.body|markdown(lazy_load=True)|reference|str|safe }}
|
||||
</div>
|
||||
{% if node.score <= vote_hide_threshold %}
|
||||
<div class="comment-body bad-comment-body">
|
||||
<p>
|
||||
{% trans id=node.id %}
|
||||
This comment is hidden due to too much negative feedback.
|
||||
Click <a href="javascript:comment_show_content({{ id }})">here</a> to view it.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<ul id="comment-{{ node.id }}-reply" class="reply-comment" hidden></ul>
|
||||
{% with children=node.get_children() %}
|
||||
{% if children %}
|
||||
<ul id="comment-{{ node.id }}-children" class="comments">{{ loop(children) }}</ul>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not comment_lock %}
|
||||
<p class="no-comments-message">{{ _('There are no comments at the moment.') }}</p>
|
||||
{% endif %}
|
||||
{% if node.score <= vote_hide_threshold %}
|
||||
<div class="comment-body bad-comment-body">
|
||||
<p>
|
||||
{% trans id=node.id %}
|
||||
This comment is hidden due to too much negative feedback.
|
||||
Click <a href="javascript:comment_show_content({{ id }})">here</a> to view it.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<ul id="comment-{{ node.id }}-reply" class="reply-comment" hidden></ul>
|
||||
{% with children=node.get_children() %}
|
||||
{% if children %}
|
||||
<ul id="comment-{{ node.id }}-children" class="comments">{{ loop(children) }}</ul>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elif not comment_lock %}
|
||||
<p class="no-comments-message">{{ _('There are no comments at the moment.') }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if comment_lock %}
|
||||
<div class="alert alert-warning comment-lock">
|
||||
{{ _('Comments are disabled on this page.') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if comment_lock %}
|
||||
<div class="alert alert-warning comment-lock">
|
||||
{{ _('Comments are disabled on this page.') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{% compress js, inline %}
|
||||
<script src="{{ static('pagedown_math.js') }}"></script>
|
||||
<script src="{{ static('pagedown_math.js') }}"></script>
|
||||
{% endcompress %}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{% compress css %}
|
||||
{{ comment_form.media.css }}
|
||||
{{ comment_form.media.css }}
|
||||
{% endcompress %}
|
||||
|
|
|
@ -1,231 +1,231 @@
|
|||
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
|
||||
{% compress js %}
|
||||
{{ comment_form.media.js }}
|
||||
{% if not REQUIRE_JAX %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#id_body').keypress(function () {
|
||||
if (!("MathJax" in window)) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: '{{ static('mathjax3_config.js') }}',
|
||||
dataType: "script",
|
||||
cache: true,
|
||||
success: function () {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js',
|
||||
dataType: "script",
|
||||
cache: true,
|
||||
success: function () {
|
||||
mathjax_pagedown($);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{{ comment_form.media.js }}
|
||||
{% if not REQUIRE_JAX %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
window.reply_comment = function (parent) {
|
||||
var $comment_reply = $('#comment-' + parent + '-reply');
|
||||
var reply_id = 'reply-' + parent;
|
||||
var new_id = 'id' + parent + '_body';
|
||||
if ($comment_reply.find('#' + reply_id).length == 0) {
|
||||
var $reply_form = $('#new-comment').clone(true).prop('id', reply_id).css("display", "");
|
||||
$reply_form.find('h3').html('{{ _('Replying to comment') }}');
|
||||
$reply_form.prepend('<a class="close">x</a>');
|
||||
$reply_form.find('form.comment-submit-form input#id_parent').val(parent);
|
||||
$reply_form.find('div#wmd-button-bar-id_body').empty().prop('id','wmd-button-bar-' + new_id);
|
||||
$reply_form.find('textarea.wmd-input').val('').prop('id', 'wmd-input-' + new_id);
|
||||
$reply_form.find('div#id_body-preview').attr('data-textarea-id', 'wmd-input-' + new_id).prop('id', new_id + '-preview');
|
||||
$reply_form.appendTo($comment_reply);
|
||||
register_dmmd_preview($reply_form.find('div#' + new_id + '-preview'));
|
||||
if ('DjangoPagedown' in window) {
|
||||
window.DjangoPagedown.createEditor($reply_form.find('div.wmd-wrapper').get(0));
|
||||
}
|
||||
}
|
||||
$comment_reply.fadeIn();
|
||||
|
||||
$('html, body').animate({
|
||||
scrollTop: $comment_reply.offset().top - $('#navigation').height() - 4
|
||||
}, 500);
|
||||
};
|
||||
|
||||
$(document).on('click', '.close', function() {
|
||||
$(this).closest('.reply-comment').fadeOut();
|
||||
$(function () {
|
||||
$('#id_body').keypress(function () {
|
||||
if (!("MathJax" in window)) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: '{{ static('mathjax3_config.js') }}',
|
||||
dataType: "script",
|
||||
cache: true,
|
||||
success: function () {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js',
|
||||
dataType: "script",
|
||||
cache: true,
|
||||
success: function () {
|
||||
mathjax_pagedown($);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function update_math($comment) {
|
||||
if ('MathJax' in window) {
|
||||
var $body = $comment.find('.comment-body');
|
||||
MathJax.typeset($body[0]);
|
||||
}
|
||||
}
|
||||
|
||||
window.show_revision = function (comment_id, offset) {
|
||||
var $comment = $("#comment-" + comment_id);
|
||||
|
||||
// If .comment-body is hidden, then this is a bad comment that the user has not clicked
|
||||
// Thus the revision retrieval should do nothing
|
||||
if (!$comment.find('.comment-body').is(':visible'))
|
||||
return;
|
||||
|
||||
var cur_revision = parseInt($comment.attr("data-revision"));
|
||||
var max_revision = parseInt($comment.attr("data-max-revision"));
|
||||
var revision_ajax = $comment.attr("data-revision-ajax");
|
||||
var show_revision = cur_revision + offset;
|
||||
|
||||
$comment.attr("data-revision", show_revision);
|
||||
|
||||
$.get(revision_ajax, {
|
||||
revision: show_revision
|
||||
}).done(function (body) {
|
||||
$comment.find('.previous-revision').css({visibility: show_revision == 0 ? 'hidden' : ''});
|
||||
$comment.find('.next-revision').css({visibility: show_revision == max_revision ? 'hidden' : ''});
|
||||
$comment.find('.content').html(body);
|
||||
|
||||
var edit_text = '{{ _('edit {edits}') }}'.replace("{edits}", show_revision);
|
||||
|
||||
if (show_revision == 0) {
|
||||
edit_text = '{{ _('original') }}';
|
||||
} else if (show_revision == max_revision && max_revision == 1) {
|
||||
edit_text = '{{ _('edited') }}';
|
||||
}
|
||||
|
||||
$comment.find('.comment-edit-text').text(' ' + edit_text + ' ');
|
||||
update_math($comment);
|
||||
});
|
||||
};
|
||||
|
||||
function ajax_vote(url, id, delta, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var score = $('#comment-' + id + ' .comment-score').first();
|
||||
score.text(parseInt(score.text()) + delta);
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not vote: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var get_$votes = function (id) {
|
||||
var $comment = $('#comment-' + id);
|
||||
return {
|
||||
upvote: $comment.find('.upvote-link').first(),
|
||||
downvote: $comment.find('.downvote-link').first()
|
||||
};
|
||||
};
|
||||
|
||||
window.comment_upvote = function (id) {
|
||||
ajax_vote('{{ url('comment_upvote') }}', id, 1, function () {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.downvote.hasClass('voted'))
|
||||
$votes.downvote.removeClass('voted');
|
||||
else
|
||||
$votes.upvote.addClass('voted');
|
||||
});
|
||||
};
|
||||
|
||||
window.comment_downvote = function (id) {
|
||||
ajax_vote('{{ url('comment_downvote') }}', id, -1, function () {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.upvote.hasClass('voted'))
|
||||
$votes.upvote.removeClass('voted');
|
||||
else
|
||||
$votes.downvote.addClass('voted');
|
||||
});
|
||||
};
|
||||
|
||||
var $comments = $('.comments');
|
||||
$comments.find('a.hide-comment').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (!(e.ctrlKey || e.metaKey || confirm('Are you sure you want to hide this comment?')))
|
||||
return;
|
||||
|
||||
var id = $(this).attr('data-id');
|
||||
$.post('{{ url('comment_hide') }}', {id: id}).then(function () {
|
||||
$('#comment-' + id).remove();
|
||||
$('#comment-' + id + '-children').remove();
|
||||
}).catch(function () {
|
||||
alert('Failed.');
|
||||
});
|
||||
});
|
||||
|
||||
$comments.find('a.edit-link').featherlight({
|
||||
afterOpen: function () {
|
||||
register_dmmd_preview($('#id-edit-comment-body-preview'));
|
||||
if ('DjangoPagedown' in window) {
|
||||
var $wmd = $('.featherlight .wmd-wrapper');
|
||||
if ($wmd.length) {
|
||||
window.DjangoPagedown.createEditor($wmd.get(0));
|
||||
if ('MathJax' in window) {
|
||||
var preview = $('.featherlight div.wmd-preview')[0];
|
||||
MathJax.typeset(preview);
|
||||
}
|
||||
}
|
||||
}
|
||||
$('#comment-edit').submit(function (event) {
|
||||
event.preventDefault();
|
||||
var id = $('#comment-edit').find('.comment-id').text();
|
||||
var readback = $('#comment-edit').find('.read-back').text();
|
||||
$.post($(this).attr('action'), $(this).serialize()).done(function (data) {
|
||||
$.featherlight.current().close();
|
||||
$.ajax({
|
||||
url: readback
|
||||
}).done(function (data) {
|
||||
var $comment = $('#comment-' + id);
|
||||
var $area = $comment.find('.comment-body').first();
|
||||
$area.html(data);
|
||||
update_math($comment);
|
||||
var $edits = $comment.find('.comment-edits').first();
|
||||
$edits.text('updated');
|
||||
}).fail(function () {
|
||||
console.log('Failed to update comment:' + id);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
variant: 'featherlight-edit'
|
||||
});
|
||||
|
||||
var $root = $('html, body');
|
||||
$comments.find('a.comment-link').click(function () {
|
||||
var href = $.attr(this, 'href');
|
||||
$root.animate({
|
||||
scrollTop: $(href).offset().top
|
||||
}, 500, function () {
|
||||
window.location.hash = href;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('img.unveil').unveil(200);
|
||||
|
||||
window.comment_show_content = function (comment_id) {
|
||||
var $comment = $('#comment-' + comment_id);
|
||||
$comment.find('.comment-body').show();
|
||||
$comment.find('.bad-comment-body').hide();
|
||||
};
|
||||
|
||||
$("#write-comment").click( function(event) {
|
||||
event.preventDefault();
|
||||
$("#new-comment").show("slow");
|
||||
$("#write-comment").hide();
|
||||
$(".no-comments-message").hide();
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
window.reply_comment = function (parent) {
|
||||
var $comment_reply = $('#comment-' + parent + '-reply');
|
||||
var reply_id = 'reply-' + parent;
|
||||
var new_id = 'id' + parent + '_body';
|
||||
if ($comment_reply.find('#' + reply_id).length == 0) {
|
||||
var $reply_form = $('#new-comment').clone(true).prop('id', reply_id).css("display", "");
|
||||
$reply_form.find('h3').html('{{ _('Replying to comment') }}');
|
||||
$reply_form.prepend('<a class="close">x</a>');
|
||||
$reply_form.find('form.comment-submit-form input#id_parent').val(parent);
|
||||
$reply_form.find('div#wmd-button-bar-id_body').empty().prop('id','wmd-button-bar-' + new_id);
|
||||
$reply_form.find('textarea.wmd-input').val('').prop('id', 'wmd-input-' + new_id);
|
||||
$reply_form.find('div#id_body-preview').attr('data-textarea-id', 'wmd-input-' + new_id).prop('id', new_id + '-preview');
|
||||
$reply_form.appendTo($comment_reply);
|
||||
register_dmmd_preview($reply_form.find('div#' + new_id + '-preview'));
|
||||
if ('DjangoPagedown' in window) {
|
||||
window.DjangoPagedown.createEditor($reply_form.find('div.wmd-wrapper').get(0));
|
||||
}
|
||||
}
|
||||
$comment_reply.fadeIn();
|
||||
|
||||
$('html, body').animate({
|
||||
scrollTop: $comment_reply.offset().top - $('#navigation').height() - 4
|
||||
}, 500);
|
||||
};
|
||||
|
||||
$(document).on('click', '.close', function() {
|
||||
$(this).closest('.reply-comment').fadeOut();
|
||||
});
|
||||
|
||||
function update_math($comment) {
|
||||
if ('MathJax' in window) {
|
||||
var $body = $comment.find('.comment-body');
|
||||
MathJax.typeset($body[0]);
|
||||
}
|
||||
}
|
||||
|
||||
window.show_revision = function (comment_id, offset) {
|
||||
var $comment = $("#comment-" + comment_id);
|
||||
|
||||
// If .comment-body is hidden, then this is a bad comment that the user has not clicked
|
||||
// Thus the revision retrieval should do nothing
|
||||
if (!$comment.find('.comment-body').is(':visible'))
|
||||
return;
|
||||
|
||||
var cur_revision = parseInt($comment.attr("data-revision"));
|
||||
var max_revision = parseInt($comment.attr("data-max-revision"));
|
||||
var revision_ajax = $comment.attr("data-revision-ajax");
|
||||
var show_revision = cur_revision + offset;
|
||||
|
||||
$comment.attr("data-revision", show_revision);
|
||||
|
||||
$.get(revision_ajax, {
|
||||
revision: show_revision
|
||||
}).done(function (body) {
|
||||
$comment.find('.previous-revision').css({visibility: show_revision == 0 ? 'hidden' : ''});
|
||||
$comment.find('.next-revision').css({visibility: show_revision == max_revision ? 'hidden' : ''});
|
||||
$comment.find('.content').html(body);
|
||||
|
||||
var edit_text = '{{ _('edit {edits}') }}'.replace("{edits}", show_revision);
|
||||
|
||||
if (show_revision == 0) {
|
||||
edit_text = '{{ _('original') }}';
|
||||
} else if (show_revision == max_revision && max_revision == 1) {
|
||||
edit_text = '{{ _('edited') }}';
|
||||
}
|
||||
|
||||
$comment.find('.comment-edit-text').text(' ' + edit_text + ' ');
|
||||
update_math($comment);
|
||||
});
|
||||
};
|
||||
|
||||
function ajax_vote(url, id, delta, on_success) {
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: id
|
||||
},
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
var score = $('#comment-' + id + ' .comment-score').first();
|
||||
score.text(parseInt(score.text()) + delta);
|
||||
if (typeof on_success !== 'undefined')
|
||||
on_success();
|
||||
},
|
||||
error: function (data, textStatus, jqXHR) {
|
||||
alert('Could not vote: ' + data.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var get_$votes = function (id) {
|
||||
var $comment = $('#comment-' + id);
|
||||
return {
|
||||
upvote: $comment.find('.upvote-link').first(),
|
||||
downvote: $comment.find('.downvote-link').first()
|
||||
};
|
||||
};
|
||||
|
||||
window.comment_upvote = function (id) {
|
||||
ajax_vote('{{ url('comment_upvote') }}', id, 1, function () {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.downvote.hasClass('voted'))
|
||||
$votes.downvote.removeClass('voted');
|
||||
else
|
||||
$votes.upvote.addClass('voted');
|
||||
});
|
||||
};
|
||||
|
||||
window.comment_downvote = function (id) {
|
||||
ajax_vote('{{ url('comment_downvote') }}', id, -1, function () {
|
||||
var $votes = get_$votes(id);
|
||||
if ($votes.upvote.hasClass('voted'))
|
||||
$votes.upvote.removeClass('voted');
|
||||
else
|
||||
$votes.downvote.addClass('voted');
|
||||
});
|
||||
};
|
||||
|
||||
var $comments = $('.comments');
|
||||
$comments.find('a.hide-comment').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (!(e.ctrlKey || e.metaKey || confirm('Are you sure you want to hide this comment?')))
|
||||
return;
|
||||
|
||||
var id = $(this).attr('data-id');
|
||||
$.post('{{ url('comment_hide') }}', {id: id}).then(function () {
|
||||
$('#comment-' + id).remove();
|
||||
$('#comment-' + id + '-children').remove();
|
||||
}).catch(function () {
|
||||
alert('Failed.');
|
||||
});
|
||||
});
|
||||
|
||||
$comments.find('a.edit-link').featherlight({
|
||||
afterOpen: function () {
|
||||
register_dmmd_preview($('#id-edit-comment-body-preview'));
|
||||
if ('DjangoPagedown' in window) {
|
||||
var $wmd = $('.featherlight .wmd-wrapper');
|
||||
if ($wmd.length) {
|
||||
window.DjangoPagedown.createEditor($wmd.get(0));
|
||||
if ('MathJax' in window) {
|
||||
var preview = $('.featherlight div.wmd-preview')[0];
|
||||
MathJax.typeset(preview);
|
||||
}
|
||||
}
|
||||
}
|
||||
$('#comment-edit').submit(function (event) {
|
||||
event.preventDefault();
|
||||
var id = $('#comment-edit').find('.comment-id').text();
|
||||
var readback = $('#comment-edit').find('.read-back').text();
|
||||
$.post($(this).attr('action'), $(this).serialize()).done(function (data) {
|
||||
$.featherlight.current().close();
|
||||
$.ajax({
|
||||
url: readback
|
||||
}).done(function (data) {
|
||||
var $comment = $('#comment-' + id);
|
||||
var $area = $comment.find('.comment-body').first();
|
||||
$area.html(data);
|
||||
update_math($comment);
|
||||
var $edits = $comment.find('.comment-edits').first();
|
||||
$edits.text('updated');
|
||||
}).fail(function () {
|
||||
console.log('Failed to update comment:' + id);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
variant: 'featherlight-edit'
|
||||
});
|
||||
|
||||
var $root = $('html, body');
|
||||
$comments.find('a.comment-link').click(function () {
|
||||
var href = $.attr(this, 'href');
|
||||
$root.animate({
|
||||
scrollTop: $(href).offset().top
|
||||
}, 500, function () {
|
||||
window.location.hash = href;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('img.unveil').unveil(200);
|
||||
|
||||
window.comment_show_content = function (comment_id) {
|
||||
var $comment = $('#comment-' + comment_id);
|
||||
$comment.find('.comment-body').show();
|
||||
$comment.find('.bad-comment-body').hide();
|
||||
};
|
||||
|
||||
$("#write-comment").click( function(event) {
|
||||
event.preventDefault();
|
||||
$("#new-comment").show("slow");
|
||||
$("#write-comment").hide();
|
||||
$(".no-comments-message").hide();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endcompress %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{ preview_data|markdown|reference|str|safe }}
|
||||
{% if REQUIRE_JAX %}
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
{% endif %}
|
|
@ -1,3 +1,3 @@
|
|||
{% with node=revision.field_dict %}
|
||||
<div class="comment-body">{{ node.body|markdown|reference|str|safe }}</div>
|
||||
<div class="comment-body">{{ node.body|markdown|reference|str|safe }}</div>
|
||||
{% endwith %}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<h2>Votes</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Voter</th>
|
||||
<th>Score</th>
|
||||
<th>Voter</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for vote in votes %}
|
||||
<tr>
|
||||
<td>{{ link_user(vote.voter) }}</td>
|
||||
<td>{{ vote.score }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ link_user(vote.voter) }}</td>
|
||||
<td>{{ vote.score }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,80 +1,80 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block media %}
|
||||
{% block content_media %}{% endblock %}
|
||||
{% block content_media %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js_media %}
|
||||
{% compress js %}
|
||||
<script src="{{ static('libs/clipboard/clipboard.js') }}"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var info_float = $('.info-float');
|
||||
if (info_float.length) {
|
||||
var container = $('#content-right');
|
||||
if (window.bad_browser) {
|
||||
container.css('float', 'right');
|
||||
} else if (!featureTest('position', 'sticky')) {
|
||||
fix_div(info_float, 55);
|
||||
$(window).resize(function () {
|
||||
info_float.width(container.width());
|
||||
});
|
||||
info_float.width(container.width());
|
||||
}
|
||||
}
|
||||
|
||||
var copyButton;
|
||||
$('pre code').each(function () {
|
||||
$(this).parent().before($('<div>', {'class': 'copy-clipboard'})
|
||||
.append(copyButton = $('<span>', {
|
||||
'class': 'btn-clipboard',
|
||||
'data-clipboard-text': $(this).text(),
|
||||
'title': 'Click to copy'
|
||||
}).text('Copy')));
|
||||
|
||||
$(copyButton.get(0)).mouseleave(function () {
|
||||
$(this).attr('class', 'btn-clipboard');
|
||||
$(this).removeAttr('aria-label');
|
||||
});
|
||||
|
||||
var curClipboard = new Clipboard(copyButton.get(0));
|
||||
|
||||
curClipboard.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
showTooltip(e.trigger, 'Copied!');
|
||||
});
|
||||
|
||||
curClipboard.on('error', function (e) {
|
||||
showTooltip(e.trigger, fallbackMessage(e.action));
|
||||
});
|
||||
|
||||
});
|
||||
{% compress js %}
|
||||
<script src="{{ static('libs/clipboard/clipboard.js') }}"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var info_float = $('.info-float');
|
||||
if (info_float.length) {
|
||||
var container = $('#content-right');
|
||||
if (window.bad_browser) {
|
||||
container.css('float', 'right');
|
||||
} else if (!featureTest('position', 'sticky')) {
|
||||
fix_div(info_float, 55);
|
||||
$(window).resize(function () {
|
||||
info_float.width(container.width());
|
||||
});
|
||||
</script>
|
||||
{% endcompress %}
|
||||
{% block content_js_media %}{% endblock %}
|
||||
info_float.width(container.width());
|
||||
}
|
||||
}
|
||||
|
||||
var copyButton;
|
||||
$('pre code').each(function () {
|
||||
$(this).parent().before($('<div>', {'class': 'copy-clipboard'})
|
||||
.append(copyButton = $('<span>', {
|
||||
'class': 'btn-clipboard',
|
||||
'data-clipboard-text': $(this).text(),
|
||||
'title': 'Click to copy'
|
||||
}).text('Copy')));
|
||||
|
||||
$(copyButton.get(0)).mouseleave(function () {
|
||||
$(this).attr('class', 'btn-clipboard');
|
||||
$(this).removeAttr('aria-label');
|
||||
});
|
||||
|
||||
var curClipboard = new Clipboard(copyButton.get(0));
|
||||
|
||||
curClipboard.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
showTooltip(e.trigger, 'Copied!');
|
||||
});
|
||||
|
||||
curClipboard.on('error', function (e) {
|
||||
showTooltip(e.trigger, fallbackMessage(e.action));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endcompress %}
|
||||
{% block content_js_media %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="common-content">
|
||||
<div id="content-right">
|
||||
<div class="info-float">{% block info_float %}{% endblock %}</div>
|
||||
</div>
|
||||
<div id="content-left" class="split-common-content">
|
||||
<div class="content-description screen">
|
||||
{% block description %}{% endblock %}
|
||||
{% block description_end %}
|
||||
<hr>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block post_description_end %}{% endblock %}
|
||||
{% block comments %}{% endblock %}
|
||||
</div>
|
||||
<div id="common-content">
|
||||
<div id="content-right">
|
||||
<div class="info-float">{% block info_float %}{% endblock %}</div>
|
||||
</div>
|
||||
<div id="content-left" class="split-common-content">
|
||||
<div class="content-description screen">
|
||||
{% block description %}{% endblock %}
|
||||
{% block description_end %}
|
||||
<hr>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block post_description_end %}{% endblock %}
|
||||
{% block comments %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyend %}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% if REQUIRE_JAX %}
|
||||
{% include "mathjax-load.html" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block media %}
|
||||
<style>
|
||||
#access-code-form {
|
||||
margin: 50px auto 0;
|
||||
display: block;
|
||||
max-width: 500px;
|
||||
}
|
||||
<style>
|
||||
#access-code-form {
|
||||
margin: 50px auto 0;
|
||||
display: block;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
#id_access_code {
|
||||
width: 100%;
|
||||
}
|
||||
#id_access_code {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button-line {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
.button-line {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form id="access-code-form" action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.errors or wrong_code %}
|
||||
<div id="form-errors">
|
||||
<p class="error">{{ _('Invalid access code.') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>{{ _('Please enter your access code:') }}</p>
|
||||
<p>{{ form.access_code }}</p>
|
||||
<p class="button-line">
|
||||
<button type="submit">{{ _('Join Contest') }}</button>
|
||||
</p>
|
||||
</form>
|
||||
<form id="access-code-form" action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.errors or wrong_code %}
|
||||
<div id="form-errors">
|
||||
<p class="error">{{ _('Invalid access code.') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>{{ _('Please enter your access code:') }}</p>
|
||||
<p>{{ form.access_code }}</p>
|
||||
<p class="button-line">
|
||||
<button type="submit">{{ _('Join Contest') }}</button>
|
||||
</p>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -2,55 +2,55 @@
|
|||
{% set page_type = 'calendar' %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "contest/contest-list-tabs.html" %}
|
||||
{% include "contest/contest-list-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<center style="font-size: 1.6em; margin-top: 0.3em;">
|
||||
{% if prev_month %}
|
||||
<a href="{{ url('contest_calendar', prev_month.year, prev_month.month) }}">« {{ _('Prev') }}</a>
|
||||
{% endif %}
|
||||
{% if not (curr_month.year == now.year and curr_month.month == now.month) %}
|
||||
<a href="{{ url('contest_calendar', now.year, now.month) }}"> {{ _('Today') }}</a>
|
||||
{% endif %}
|
||||
{% if next_month %}
|
||||
<a href="{{ url('contest_calendar', next_month.year, next_month.month) }}">{{ _('Next') }} »</a>
|
||||
{% endif %}
|
||||
</center>
|
||||
<table id="contest-calendar">
|
||||
<tr>
|
||||
<th>{{ _('Sunday') }}</th>
|
||||
<th>{{ _('Monday') }}</th>
|
||||
<th>{{ _('Tuesday') }}</th>
|
||||
<th>{{ _('Wednesday') }}</th>
|
||||
<th>{{ _('Thursday') }}</th>
|
||||
<th>{{ _('Friday') }}</th>
|
||||
<th>{{ _('Saturday') }}</th>
|
||||
</tr>
|
||||
{% for week in calendar %}
|
||||
<tr>{% for day in week %}
|
||||
<td class="{{ day.weekday }}{% if day.is_today %} today{% endif %}{% if day.is_pad %} noday{% endif %}">
|
||||
<span class="num">{{ day.date.day }}</span>
|
||||
<ul class="fa-ul">
|
||||
{% for contest in day.starts %}
|
||||
<li class="start"><i class="fa fa-li fa-lg fa-step-forward"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for contest in day.oneday %}
|
||||
<li class="oneday">
|
||||
<i class="fa fa-li fa-lg fa-play"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for contest in day.ends %}
|
||||
<li class="end"><i class="fa fa-li fa-lg fa-step-backward"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
{% endfor %}</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<center style="font-size: 1.6em; margin-top: 0.3em;">
|
||||
{% if prev_month %}
|
||||
<a href="{{ url('contest_calendar', prev_month.year, prev_month.month) }}">« {{ _('Prev') }}</a>
|
||||
{% endif %}
|
||||
{% if not (curr_month.year == now.year and curr_month.month == now.month) %}
|
||||
<a href="{{ url('contest_calendar', now.year, now.month) }}"> {{ _('Today') }}</a>
|
||||
{% endif %}
|
||||
{% if next_month %}
|
||||
<a href="{{ url('contest_calendar', next_month.year, next_month.month) }}">{{ _('Next') }} »</a>
|
||||
{% endif %}
|
||||
</center>
|
||||
<table id="contest-calendar">
|
||||
<tr>
|
||||
<th>{{ _('Sunday') }}</th>
|
||||
<th>{{ _('Monday') }}</th>
|
||||
<th>{{ _('Tuesday') }}</th>
|
||||
<th>{{ _('Wednesday') }}</th>
|
||||
<th>{{ _('Thursday') }}</th>
|
||||
<th>{{ _('Friday') }}</th>
|
||||
<th>{{ _('Saturday') }}</th>
|
||||
</tr>
|
||||
{% for week in calendar %}
|
||||
<tr>{% for day in week %}
|
||||
<td class="{{ day.weekday }}{% if day.is_today %} today{% endif %}{% if day.is_pad %} noday{% endif %}">
|
||||
<span class="num">{{ day.date.day }}</span>
|
||||
<ul class="fa-ul">
|
||||
{% for contest in day.starts %}
|
||||
<li class="start"><i class="fa fa-li fa-lg fa-step-forward"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for contest in day.oneday %}
|
||||
<li class="oneday">
|
||||
<i class="fa fa-li fa-lg fa-play"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% for contest in day.ends %}
|
||||
<li class="end"><i class="fa fa-li fa-lg fa-step-backward"></i>
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
{% endfor %}</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block media %}
|
||||
{{ form.media.css }}
|
||||
<style>
|
||||
form#clarification-form {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
padding-top: 1em;
|
||||
}
|
||||
{{ form.media.css }}
|
||||
<style>
|
||||
form#clarification-form {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 750px;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#id_title {
|
||||
width: 100%;
|
||||
}
|
||||
#id_title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
form#clarification-form .submit {
|
||||
margin: 10px 0 0 auto;
|
||||
}
|
||||
</style>
|
||||
form#clarification-form .submit {
|
||||
margin: 10px 0 0 auto;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block js_media %}
|
||||
{{ form.media.js }}
|
||||
<script>
|
||||
{{ form.media.js }}
|
||||
<script>
|
||||
$(function() {
|
||||
$('#problem-select').select2({width: '40em'});
|
||||
$('#problem-select').select2({width: '40em'});
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form id="clarification-form" action="" method="POST" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.body.errors %}
|
||||
<div class="form-errors">
|
||||
{{ form.body.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<h4>
|
||||
<span>{{_('Problem')}}: </span>
|
||||
<select name="problem" id="problem-select">
|
||||
{% for problem in problems %}
|
||||
<option value="{{ problem.problem.code }}" class="point-dropdown">
|
||||
{{ problem.order }}. {{problem.problem.name}}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</h4>
|
||||
<div class="body-block">{{ form.body }}</div>
|
||||
<button type="submit" class="submit">{{ _('Create') }}</button>
|
||||
</form>
|
||||
<form id="clarification-form" action="" method="POST" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.body.errors %}
|
||||
<div class="form-errors">
|
||||
{{ form.body.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<h4>
|
||||
<span>{{_('Problem')}}: </span>
|
||||
<select name="problem" id="problem-select">
|
||||
{% for problem in problems %}
|
||||
<option value="{{ problem.problem.code }}" class="point-dropdown">
|
||||
{{ problem.order }}. {{problem.problem.name}}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</h4>
|
||||
<div class="body-block">{{ form.body }}</div>
|
||||
<button type="submit" class="submit">{{ _('Create') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block media %}
|
||||
<style>
|
||||
#contest-clone-panel {
|
||||
position: relative;
|
||||
margin: 5em auto auto -10em;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
<style>
|
||||
#contest-clone-panel {
|
||||
position: relative;
|
||||
margin: 5em auto auto -10em;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
#contest-key-container {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
#contest-key-container {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
#id_key {
|
||||
width: 100%;
|
||||
}
|
||||
#id_key {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ul.errorlist {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
ul.errorlist {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form id="contest-clone-panel" action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div id="form-errors">
|
||||
{{ form.key.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form id="contest-clone-panel" action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div id="form-errors">
|
||||
{{ form.key.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div><label class="inline-header grayed">{{ _('Enter a new key for the cloned contest:') }}</label></div>
|
||||
<div id="contest-key-container"><span class="fullwidth">{{ form.key }}</span></div>
|
||||
<hr>
|
||||
<button style="float: right;" type="submit">{{ _('Clone!') }}</button>
|
||||
</form>
|
||||
<div><label class="inline-header grayed">{{ _('Enter a new key for the cloned contest:') }}</label></div>
|
||||
<div id="contest-key-container"><span class="fullwidth">{{ form.key }}</span></div>
|
||||
<hr>
|
||||
<button style="float: right;" type="submit">{{ _('Clone!') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id="banner">
|
||||
<a href="https://www.timeanddate.com/worldclock/fixedtime.html?msg={{ contest.name|urlquote('') }}&iso=
|
||||
{{- contest.start_time|utc|date('Y-m-d\TH:i:s') }}" class="date">
|
||||
{%- if contest.is_in_contest(request.user) and not request.participation.live -%}
|
||||
{% if request.participation.spectate %}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Spectating, contest ends in {{countdown}}.{% endtrans %}
|
||||
{% elif request.participation.end_time %}
|
||||
{% trans countdown=request.participation.end_time|as_countdown %}Participating virtually, {{countdown}} remaining.{% endtrans %}
|
||||
{% else %}
|
||||
{{- _('Participating virtually.') -}}
|
||||
{% endif %}
|
||||
<a href="https://www.timeanddate.com/worldclock/fixedtime.html?msg={{ contest.name|urlquote('') }}&iso=
|
||||
{{- contest.start_time|utc|date('Y-m-d\TH:i:s') }}" class="date">
|
||||
{%- if contest.is_in_contest(request.user) and not request.participation.live -%}
|
||||
{% if request.participation.spectate %}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Spectating, contest ends in {{countdown}}.{% endtrans %}
|
||||
{% elif request.participation.end_time %}
|
||||
{% trans countdown=request.participation.end_time|as_countdown %}Participating virtually, {{countdown}} remaining.{% endtrans %}
|
||||
{% else %}
|
||||
{{- _('Participating virtually.') -}}
|
||||
{% endif %}
|
||||
{%- else -%}
|
||||
{% if contest.start_time > now %}
|
||||
{% trans countdown=contest.start_time|as_countdown %}Starting in {{countdown}}.{% endtrans %}
|
||||
{% elif contest.end_time < now %}
|
||||
{{- _('Contest is over.') -}}
|
||||
{% else %}
|
||||
{%- if has_joined -%}
|
||||
{% if live_participation.ended %}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Your time is up! Contest ends in {{countdown}}.{% endtrans %}
|
||||
{% else %}
|
||||
{% trans countdown=live_participation.end_time|as_countdown %}You have {{countdown}} remaining.{% endtrans %}
|
||||
{% endif %}
|
||||
{%- else -%}
|
||||
{% if contest.start_time > now %}
|
||||
{% trans countdown=contest.start_time|as_countdown %}Starting in {{countdown}}.{% endtrans %}
|
||||
{% elif contest.end_time < now %}
|
||||
{{- _('Contest is over.') -}}
|
||||
{% else %}
|
||||
{%- if has_joined -%}
|
||||
{% if live_participation.ended %}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Your time is up! Contest ends in {{countdown}}.{% endtrans %}
|
||||
{% else %}
|
||||
{% trans countdown=live_participation.end_time|as_countdown %}You have {{countdown}} remaining.{% endtrans %}
|
||||
{% endif %}
|
||||
{%- else -%}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Contest ends in {{countdown}}.{% endtrans %}
|
||||
{%- endif -%}
|
||||
{% endif %}
|
||||
{% trans countdown=contest.end_time|as_countdown %}Contest ends in {{countdown}}.{% endtrans %}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
<div class="time">
|
||||
{% if contest.time_limit %}
|
||||
{% trans trimmed start_time=contest.start_time|date(_("F j, Y, G:i T")), end_time=contest.end_time|date(_("F j, Y, G:i T")), time_limit=contest.time_limit|timedelta('localized-no-seconds') %}
|
||||
<b>{{ time_limit }}</b> window between <b>{{ start_time }}</b> and <b>{{ end_time }}</b>
|
||||
{% endtrans %}
|
||||
{% else %}
|
||||
{% trans trimmed length=contest.contest_window_length|timedelta("localized-no-seconds"), start_time=contest.start_time|date(_("F j, Y, G:i T")) %}
|
||||
<b>{{ length }}</b> long starting on <b>{{ start_time }}</b>
|
||||
{% endtrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if contest.freeze_after and contest.freeze_after + contest.start_time < now %}
|
||||
<div class="time" style="margin-top: 0.2em">
|
||||
<b>{{_("Standing was frozen")}}</b> {{_("at")}} <b>{{ (contest.freeze_after + contest.start_time) | date(_("F j, Y, G:i T")) }}</b>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
</a>
|
||||
<div class="time">
|
||||
{% if contest.time_limit %}
|
||||
{% trans trimmed start_time=contest.start_time|date(_("F j, Y, G:i T")), end_time=contest.end_time|date(_("F j, Y, G:i T")), time_limit=contest.time_limit|timedelta('localized-no-seconds') %}
|
||||
<b>{{ time_limit }}</b> window between <b>{{ start_time }}</b> and <b>{{ end_time }}</b>
|
||||
{% endtrans %}
|
||||
{% else %}
|
||||
{% trans trimmed length=contest.contest_window_length|timedelta("localized-no-seconds"), start_time=contest.start_time|date(_("F j, Y, G:i T")) %}
|
||||
<b>{{ length }}</b> long starting on <b>{{ start_time }}</b>
|
||||
{% endtrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if contest.freeze_after and contest.freeze_after + contest.start_time < now %}
|
||||
<div class="time" style="margin-top: 0.2em">
|
||||
<b>{{_("Standing was frozen")}}</b> {{_("at")}} <b>{{ (contest.freeze_after + contest.start_time) | date(_("F j, Y, G:i T")) }}</b>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
|
@ -1,5 +1,5 @@
|
|||
<div class="left-sidebar">
|
||||
{{ make_tab_item('list', 'fa fa-list', url('contest_list'), _('List')) }}
|
||||
{{ make_tab_item('calendar', 'fa fa-calendar', url('contest_calendar', now.year, now.month), _('Calendar')) }}
|
||||
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_contest_changelist'), _('Admin')) }}
|
||||
{{ make_tab_item('list', 'fa fa-list', url('contest_list'), _('List')) }}
|
||||
{{ make_tab_item('calendar', 'fa fa-calendar', url('contest_calendar', now.year, now.month), _('Calendar')) }}
|
||||
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_contest_changelist'), _('Admin')) }}
|
||||
</div>
|
|
@ -1,40 +1,40 @@
|
|||
<style>
|
||||
@media(max-width: 799px) {
|
||||
.middle-right-content {
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
@media(max-width: 799px) {
|
||||
.middle-right-content {
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('detail', 'fa fa-info-circle', url('contest_view', contest.key), _('Info')) }}
|
||||
{% if contest.ended or can_edit %}
|
||||
{{ make_tab_item('stats', 'fa fa-pie-chart', url('contest_stats', contest.key), _('Statistics')) }}
|
||||
{% endif %}
|
||||
{{ make_tab_item('detail', 'fa fa-info-circle', url('contest_view', contest.key), _('Info')) }}
|
||||
{% if contest.ended or can_edit %}
|
||||
{{ make_tab_item('stats', 'fa fa-pie-chart', url('contest_stats', contest.key), _('Statistics')) }}
|
||||
{% endif %}
|
||||
|
||||
{% if contest.start_time <= now or perms.judge.see_private_contest %}
|
||||
{% if contest.can_see_own_scoreboard(request.user) %}
|
||||
{{ make_tab_item('ranking', 'fa fa-bar-chart', url('contest_ranking', contest.key), _('Rankings')) }}
|
||||
{% if request.user.is_authenticated %}
|
||||
{{ make_tab_item('participation', 'fa fa-users', url('contest_participation_own', contest.key), _('Participation')) }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ make_tab_item('ranking', 'fa fa-bar-chart', None, _('Hidden Rankings')) }}
|
||||
{% endif %}
|
||||
{% if contest.start_time <= now or perms.judge.see_private_contest %}
|
||||
{% if contest.can_see_own_scoreboard(request.user) %}
|
||||
{{ make_tab_item('ranking', 'fa fa-bar-chart', url('contest_ranking', contest.key), _('Rankings')) }}
|
||||
{% if request.user.is_authenticated %}
|
||||
{{ make_tab_item('participation', 'fa fa-users', url('contest_participation_own', contest.key), _('Participation')) }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ make_tab_item('ranking', 'fa fa-bar-chart', None, _('Hidden Rankings')) }}
|
||||
{% endif %}
|
||||
{% if request.user.is_superuser and contest_has_hidden_subtasks %}
|
||||
{{ make_tab_item('resolver', 'fa fa-check', url('resolver', contest.key), _('Resolver')) }}
|
||||
{% endif %}
|
||||
{% if show_final_ranking %}
|
||||
{{ make_tab_item('final_ranking', 'fa fa-bar-chart', url('contest_final_ranking', contest.key), _('Final rankings')) }}
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
{% if perms.judge.moss_contest and has_moss_api_key %}
|
||||
{{ make_tab_item('moss', 'fa fa-gavel', url('contest_moss', contest.key), _('MOSS')) }}
|
||||
{% endif %}
|
||||
{{ make_tab_item('edit', 'fa fa-edit', url('admin:judge_contest_change', contest.id), _('Edit')) }}
|
||||
{% endif %}
|
||||
{% if perms.judge.clone_contest %}
|
||||
{{ make_tab_item('clone', 'fa fa-copy', url('contest_clone', contest.key), _('Clone')) }}
|
||||
{% endif %}
|
||||
{% if request.user.is_superuser and contest_has_hidden_subtasks %}
|
||||
{{ make_tab_item('resolver', 'fa fa-check', url('resolver', contest.key), _('Resolver')) }}
|
||||
{% endif %}
|
||||
{% if show_final_ranking %}
|
||||
{{ make_tab_item('final_ranking', 'fa fa-bar-chart', url('contest_final_ranking', contest.key), _('Final rankings')) }}
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
{% if perms.judge.moss_contest and has_moss_api_key %}
|
||||
{{ make_tab_item('moss', 'fa fa-gavel', url('contest_moss', contest.key), _('MOSS')) }}
|
||||
{% endif %}
|
||||
{{ make_tab_item('edit', 'fa fa-edit', url('admin:judge_contest_change', contest.id), _('Edit')) }}
|
||||
{% endif %}
|
||||
{% if perms.judge.clone_contest %}
|
||||
{{ make_tab_item('clone', 'fa fa-copy', url('contest_clone', contest.key), _('Clone')) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -2,141 +2,141 @@
|
|||
{% set page_type = 'detail' %}
|
||||
|
||||
{% block middle_title %}
|
||||
<h2>{{contest.name}}</h2>
|
||||
<h2>{{contest.name}}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% set title = contest.name %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% set title = contest.name %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
{% include "contest/media-js.html" %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% include "contest/media-js.html" %}
|
||||
{% include "comments/media-js.html" %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_media %}
|
||||
{% include "comments/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% include "comments/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% include "contest/contest-datetime.html" %}
|
||||
{% include "contest/contest-datetime.html" %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if contest.can_join or is_editor or is_tester %}
|
||||
{% set in_contest = contest.is_in_contest(request.user) %}
|
||||
{% if contest.ended %}
|
||||
{# Allow users to leave the virtual contest #}
|
||||
{% if in_contest %}
|
||||
<form action="{{ url('contest_leave', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab btn-red">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="leaving-forever" value="{{ _('Leave contest') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
{# Allow users to virtual join #}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab btn-midnightblue">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{{ _('Virtual join') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{# Allow users to leave the contest #}
|
||||
{% if in_contest %}
|
||||
<form action="{{ url('contest_leave', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue" value="
|
||||
{%- if request.participation.spectate %}
|
||||
{{- _('Stop spectating') -}}
|
||||
{% else %}
|
||||
{{- _('Leave contest') -}}
|
||||
{% endif %}">
|
||||
</form>
|
||||
{% elif is_editor or is_tester or live_participation.ended %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post" class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue" value="{{ _('Spectate contest') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post" class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue {% if not has_joined %}first-join{% endif %}"
|
||||
value="{{ _('Join contest') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if contest.can_join or is_editor or is_tester %}
|
||||
{% set in_contest = contest.is_in_contest(request.user) %}
|
||||
{% if contest.ended %}
|
||||
{# Allow users to leave the virtual contest #}
|
||||
{% if in_contest %}
|
||||
<form action="{{ url('contest_leave', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab btn-red">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="leaving-forever" value="{{ _('Leave contest') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
{# Allow users to virtual join #}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab btn-midnightblue">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="{{ _('Virtual join') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% elif contest.can_join %}
|
||||
<form action="{{ url('auth_login') }}" method="get"
|
||||
class="contest-join-pseudotab unselectable">
|
||||
<input type="hidden" name="next" value="{{ LOGIN_RETURN_PATH|urlencode }}">
|
||||
<input type="submit" class="btn-midnightblue" value="{{ _('Login to participate') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
{# Allow users to leave the contest #}
|
||||
{% if in_contest %}
|
||||
<form action="{{ url('contest_leave', contest.key) }}" method="post"
|
||||
class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue" value="
|
||||
{%- if request.participation.spectate %}
|
||||
{{- _('Stop spectating') -}}
|
||||
{% else %}
|
||||
{{- _('Leave contest') -}}
|
||||
{% endif %}">
|
||||
</form>
|
||||
{% elif is_editor or is_tester or live_participation.ended %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post" class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue" value="{{ _('Spectate contest') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post" class="contest-join-pseudotab">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn-midnightblue {% if not has_joined %}first-join{% endif %}"
|
||||
value="{{ _('Join contest') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% elif contest.can_join %}
|
||||
<form action="{{ url('auth_login') }}" method="get"
|
||||
class="contest-join-pseudotab unselectable">
|
||||
<input type="hidden" name="next" value="{{ LOGIN_RETURN_PATH|urlencode }}">
|
||||
<input type="submit" class="btn-midnightblue" value="{{ _('Login to participate') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<div class="content-description">
|
||||
{% cache 3600 'contest_html' contest.id MATH_ENGINE %}
|
||||
{{ contest.description|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
<div class="content-description">
|
||||
{% cache 3600 'contest_html' contest.id MATH_ENGINE %}
|
||||
{{ contest.description|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% if editable_organizations %}
|
||||
<div>
|
||||
{% for org in editable_organizations %}
|
||||
<span> [<a href="{{ url('organization_contest_edit', org.id , org.slug , contest.key) }}">{{ _('Edit in') }} {{org.slug}}</a>]</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if editable_organizations %}
|
||||
<div>
|
||||
{% for org in editable_organizations %}
|
||||
<span> [<a href="{{ url('organization_contest_edit', org.id , org.slug , contest.key) }}">{{ _('Edit in') }} {{org.slug}}</a>]</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if contest.ended or request.user.is_superuser or is_editor or is_tester %}
|
||||
<hr>
|
||||
<div class="contest-problems">
|
||||
<h2 style="margin-bottom: 0.2em"><i class="fa fa-fw fa-question-circle"></i>{{ _('Problems') }} </h2>
|
||||
<table id="contest-problems" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _('Problem') }}</th>
|
||||
<th>{{ _('Points') }}</th>
|
||||
<th>{{ _('AC Rate') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem in contest_problems %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if problem.is_public %}
|
||||
<a href="{{ url('problem_detail', problem.code) }}">{{ problem.i18n_name }}</a>
|
||||
{% else %}
|
||||
{{ problem.i18n_name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ problem.points|floatformat }}{% if problem.partial %}p{% endif %}</td>
|
||||
<td>{{ problem.ac_rate|floatformat(1) }}%</td>
|
||||
<td>
|
||||
{% if problem.is_public %}
|
||||
<a href="{{ url('ranked_submissions', problem.code) }}">{{ problem.user_count }}</a>
|
||||
{% else %}
|
||||
{{ problem.user_count }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if problem.is_public and problem.has_public_editorial %}
|
||||
<a href="{{ url('problem_editorial', problem.code) }}">{{ _('Editorial') }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
{% endif %}
|
||||
{% include "actionbar/list.html" %}
|
||||
<br>
|
||||
{% include "comments/list.html" %}
|
||||
{% if contest.ended or request.user.is_superuser or is_editor or is_tester %}
|
||||
<hr>
|
||||
<div class="contest-problems">
|
||||
<h2 style="margin-bottom: 0.2em"><i class="fa fa-fw fa-question-circle"></i>{{ _('Problems') }} </h2>
|
||||
<table id="contest-problems" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _('Problem') }}</th>
|
||||
<th>{{ _('Points') }}</th>
|
||||
<th>{{ _('AC Rate') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem in contest_problems %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if problem.is_public %}
|
||||
<a href="{{ url('problem_detail', problem.code) }}">{{ problem.i18n_name }}</a>
|
||||
{% else %}
|
||||
{{ problem.i18n_name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ problem.points|floatformat }}{% if problem.partial %}p{% endif %}</td>
|
||||
<td>{{ problem.ac_rate|floatformat(1) }}%</td>
|
||||
<td>
|
||||
{% if problem.is_public %}
|
||||
<a href="{{ url('ranked_submissions', problem.code) }}">{{ problem.user_count }}</a>
|
||||
{% else %}
|
||||
{{ problem.user_count }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if problem.is_public and problem.has_public_editorial %}
|
||||
<a href="{{ url('problem_editorial', problem.code) }}">{{ _('Editorial') }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
{% endif %}
|
||||
{% include "actionbar/list.html" %}
|
||||
<br>
|
||||
{% include "comments/list.html" %}
|
||||
{% endblock %}
|
|
@ -1,404 +1,404 @@
|
|||
{% extends "two-column-content.html" %}
|
||||
{% block meta %}
|
||||
<meta name="description" content="The {{ SITE_NAME }}'s contest list - past, present, and future.">
|
||||
<meta name="description" content="The {{ SITE_NAME }}'s contest list - past, present, and future.">
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style>
|
||||
.content-description ul {
|
||||
padding: 0 !important;
|
||||
}
|
||||
<style>
|
||||
.content-description ul {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.btn-contest {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
}
|
||||
.btn-contest {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
}
|
||||
|
||||
.contest-group-header {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
.contest-group-header {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
{% if page_obj and page_obj.number > 1%}
|
||||
#ongoing-table {
|
||||
display: none;
|
||||
}
|
||||
{% endif %}
|
||||
{% if page_obj and page_obj.number > 1%}
|
||||
#ongoing-table {
|
||||
display: none;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
#search-contest, #search-org, #search-btn {
|
||||
width: 100%;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
#search-contest {
|
||||
height: 2.5em;
|
||||
}
|
||||
#search-btn {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
#filter-form input {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 500px) {
|
||||
#search-contest, #search-org, #search-btn {
|
||||
width: 100%;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
#search-contest {
|
||||
height: 2.5em;
|
||||
}
|
||||
#search-btn {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
#filter-form input {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
#filter-form input {
|
||||
margin: 0 0.5em 0 0!important;
|
||||
padding-left: 8px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
#search-contest {
|
||||
width: 30%;
|
||||
height: 2.3em;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 0;
|
||||
padding-top: 4px !important;
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
#filter-form input {
|
||||
margin: 0 0.5em 0 0!important;
|
||||
padding-left: 8px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
#search-contest {
|
||||
width: 30%;
|
||||
height: 2.3em;
|
||||
margin-right: 1em;
|
||||
margin-bottom: 0;
|
||||
padding-top: 4px !important;
|
||||
}
|
||||
|
||||
#search-org {
|
||||
width: 40%;
|
||||
}
|
||||
#search-org {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
#search-btn {
|
||||
display: inline-block;
|
||||
height: 2.3em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
#search-btn {
|
||||
display: inline-block;
|
||||
height: 2.3em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
|
||||
$('.contest-tag').find('a[data-featherlight]').featherlight();
|
||||
$('.contest-tag').find('a[data-featherlight]').featherlight();
|
||||
|
||||
$('.join-warning').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to join?') }}\n' +
|
||||
'{{ _('Joining a contest for the first time starts your timer, after which it becomes unstoppable.') }}');
|
||||
});
|
||||
$('.join-warning').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to join?') }}\n' +
|
||||
'{{ _('Joining a contest for the first time starts your timer, after which it becomes unstoppable.') }}');
|
||||
});
|
||||
|
||||
$('#search-org').select2({multiple: 1, placeholder: '{{ _('Groups') }}...'})
|
||||
.css({'visibility': 'visible'});
|
||||
$('#search-org').select2({multiple: 1, placeholder: '{{ _('Groups') }}...'})
|
||||
.css({'visibility': 'visible'});
|
||||
|
||||
// var tooltip_classes = 'tooltipped tooltipped-e';
|
||||
//
|
||||
// $('.contest-tag').each(function () {
|
||||
// var link = $(this);//
|
||||
// link.mouseenter(function (e) {
|
||||
// link.addClass(tooltip_classes).attr('aria-label', link.attr('data-description'));
|
||||
// }).mouseleave(function (e) {
|
||||
// link.removeClass(tooltip_classes).removeAttr('aria-label');
|
||||
// });
|
||||
// });
|
||||
});
|
||||
</script>
|
||||
// var tooltip_classes = 'tooltipped tooltipped-e';
|
||||
//
|
||||
// $('.contest-tag').each(function () {
|
||||
// var link = $(this);//
|
||||
// link.mouseenter(function (e) {
|
||||
// link.addClass(tooltip_classes).attr('aria-label', link.attr('data-description'));
|
||||
// }).mouseleave(function (e) {
|
||||
// link.removeClass(tooltip_classes).removeAttr('aria-label');
|
||||
// });
|
||||
// });
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "contest/contest-list-tabs.html" %}
|
||||
{% include "contest/contest-list-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% macro contest_head(contest) %}
|
||||
{% spaceless %}
|
||||
<a href="{{ url('contest_view', contest.key) }}" class="contest-list-title">
|
||||
{{- contest.name -}}
|
||||
</a>
|
||||
<span class="contest-tags">
|
||||
{% if not contest.is_visible %}
|
||||
<span class="contest-tag contest-tag-hidden">
|
||||
<i class="fa fa-eye-slash"></i> {{ _('hidden') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if contest.is_editable %}
|
||||
<span class="contest-tag contest-tag-edit">
|
||||
<a href="{{ url('organization_contest_edit', organization.id, organization.slug, contest.key) }}" class="white">
|
||||
<i class="fa fa-edit"></i> {{ _('Edit') }}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if contest.is_private %}
|
||||
<span class="contest-tag contest-tag-private">
|
||||
<i class="fa fa-lock"></i> {{ _('private') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if not hide_contest_orgs %}
|
||||
{% if contest.is_organization_private %}
|
||||
{% for org in contest.organizations.all() %}
|
||||
<span class="contest-tag contest-tag-org">
|
||||
<a href="{{ org.get_absolute_url() }}">
|
||||
<i class="fa fa-lock"></i> {{ org.name }}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if contest.is_rated %}
|
||||
<span class="contest-tag-rated">
|
||||
<i class="fa fa-bar-chart"></i> {{ _('rated') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% for tag in contest.tags.all() %}
|
||||
<span style="background-color: {{ tag.color }}" class="contest-tag">
|
||||
<a href="{{ url('contest_tag', tag.name) }}"
|
||||
style="color: {{ tag.text_color }}"
|
||||
data-featherlight="{{ url('contest_tag_ajax', tag.name) }}">
|
||||
{{- tag.name -}}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% spaceless %}
|
||||
<a href="{{ url('contest_view', contest.key) }}" class="contest-list-title">
|
||||
{{- contest.name -}}
|
||||
</a>
|
||||
<span class="contest-tags">
|
||||
{% if not contest.is_visible %}
|
||||
<span class="contest-tag contest-tag-hidden">
|
||||
<i class="fa fa-eye-slash"></i> {{ _('hidden') }}
|
||||
</span>
|
||||
{% endspaceless %}
|
||||
{% endif %}
|
||||
{% if contest.is_editable %}
|
||||
<span class="contest-tag contest-tag-edit">
|
||||
<a href="{{ url('organization_contest_edit', organization.id, organization.slug, contest.key) }}" class="white">
|
||||
<i class="fa fa-edit"></i> {{ _('Edit') }}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if contest.is_private %}
|
||||
<span class="contest-tag contest-tag-private">
|
||||
<i class="fa fa-lock"></i> {{ _('private') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if not hide_contest_orgs %}
|
||||
{% if contest.is_organization_private %}
|
||||
{% for org in contest.organizations.all() %}
|
||||
<span class="contest-tag contest-tag-org">
|
||||
<a href="{{ org.get_absolute_url() }}">
|
||||
<i class="fa fa-lock"></i> {{ org.name }}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if contest.is_rated %}
|
||||
<span class="contest-tag-rated">
|
||||
<i class="fa fa-bar-chart"></i> {{ _('rated') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% for tag in contest.tags.all() %}
|
||||
<span style="background-color: {{ tag.color }}" class="contest-tag">
|
||||
<a href="{{ url('contest_tag', tag.name) }}"
|
||||
style="color: {{ tag.text_color }}"
|
||||
data-featherlight="{{ url('contest_tag_ajax', tag.name) }}">
|
||||
{{- tag.name -}}
|
||||
</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endspaceless %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro time_left(contest) %}
|
||||
<div class="time time-left">
|
||||
{% if contest.time_limit %}
|
||||
{{ contest.start_time|date(_("M j, Y, G:i")) }} -
|
||||
{{ contest.end_time|date(_("M j, Y, G:i")) }}
|
||||
{% else %}
|
||||
{{ contest.start_time|date(_("M j, Y, G:i")) }}
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if contest.time_limit %}
|
||||
{% trans time_limit=contest.time_limit|timedelta('localized-no-seconds') %}{{ time_limit }} window{% endtrans %}
|
||||
{% else %}
|
||||
{% trans duration=contest.contest_window_length|timedelta('localized-no-seconds') %}{{ duration }} long{% endtrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="time time-left">
|
||||
{% if contest.time_limit %}
|
||||
{{ contest.start_time|date(_("M j, Y, G:i")) }} -
|
||||
{{ contest.end_time|date(_("M j, Y, G:i")) }}
|
||||
{% else %}
|
||||
{{ contest.start_time|date(_("M j, Y, G:i")) }}
|
||||
{% endif %}
|
||||
<br>
|
||||
{% if contest.time_limit %}
|
||||
{% trans time_limit=contest.time_limit|timedelta('localized-no-seconds') %}{{ time_limit }} window{% endtrans %}
|
||||
{% else %}
|
||||
{% trans duration=contest.contest_window_length|timedelta('localized-no-seconds') %}{{ duration }} long{% endtrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro user_count(contest, user) %}
|
||||
{% if contest.can_see_own_scoreboard(user) %}
|
||||
<a href="{{ url('contest_ranking', contest.key) }}">{{ contest.user_count }}</a>
|
||||
{% else %}
|
||||
{{ contest.user_count }}
|
||||
{% endif %}
|
||||
{% if contest.can_see_own_scoreboard(user) %}
|
||||
<a href="{{ url('contest_ranking', contest.key) }}">{{ contest.user_count }}</a>
|
||||
{% else %}
|
||||
{{ contest.user_count }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro contest_join(contest, request) %}
|
||||
{% if not request.in_contest %}
|
||||
<td>
|
||||
{% if request.profile in contest.authors.all() or request.profile in contest.curators.all() or request.profile in contest.testers.all() %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small"
|
||||
value="{{ _('Spectate') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small join-warning"
|
||||
value="{{ _('Join') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if not request.in_contest %}
|
||||
<td>
|
||||
{% if request.profile in contest.authors.all() or request.profile in contest.curators.all() or request.profile in contest.testers.all() %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small"
|
||||
value="{{ _('Spectate') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small join-warning"
|
||||
value="{{ _('Join') }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block middle_content %}
|
||||
<div class="content-description">
|
||||
<form id="filter-form">
|
||||
<input id="search-contest" type="text" name="contest" value="{{ contest_query or '' }}"
|
||||
placeholder="{{ _('Search contests...') }}">
|
||||
{% if organizations %}
|
||||
<select id="search-org" name="orgs" multiple>
|
||||
{% for org in organizations %}
|
||||
<option value="{{ org.id }}"{% if org.id in org_query %} selected{% endif %}>
|
||||
{{ org.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
<button id="search-btn" class="btn-green small"> {{ _('Search')}} </button>
|
||||
{% if create_url %}
|
||||
<a href="{{create_url}}" class="button small" style="float: right"><i class="fa fa-plus"></i> {{ _('Create')}}</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% if active_participations %}
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Active Contests') }}
|
||||
</h3>
|
||||
<div class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90%">{{ _('Contest') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for participation in active_participations %}
|
||||
{% with contest=participation.contest %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_limit %}
|
||||
<span class="time">
|
||||
{% trans countdown=participation.end_time|as_countdown %}Window ends in {{countdown}}{% endtrans %}
|
||||
</span>
|
||||
{% elif contest.time_before_end %}
|
||||
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
||||
{% endif %}
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{{ contest_join(contest, request) }}
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
{% if current_contests %}
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Ongoing Contests') }}
|
||||
</h3>
|
||||
<div id="ongoing-table" class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90%">{{ _('Contest') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in current_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_before_end %}
|
||||
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
||||
{% endif %}
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{{ contest_join(contest, request) }}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Upcoming Contests') }}
|
||||
</h3>
|
||||
{% if future_contests %}
|
||||
<div class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _('Contest') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in future_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_before_start %}
|
||||
<span class="time">{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}</span>
|
||||
{% endif %}
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<i>{{ _('There are no scheduled contests at this time.') }}</i>
|
||||
<br>
|
||||
{% endif %}
|
||||
<br>
|
||||
|
||||
{% if past_contests %}
|
||||
<h3 class="contest-group-header">{{ _('Past Contests') }}</h3>
|
||||
{% if page_obj and page_obj.num_pages > 1 %}
|
||||
<div style="margin-bottom: 4px;">
|
||||
{% include "list-pages.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<div class="content-description">
|
||||
<form id="filter-form">
|
||||
<input id="search-contest" type="text" name="contest" value="{{ contest_query or '' }}"
|
||||
placeholder="{{ _('Search contests...') }}">
|
||||
{% if organizations %}
|
||||
<select id="search-org" name="orgs" multiple>
|
||||
{% for org in organizations %}
|
||||
<option value="{{ org.id }}"{% if org.id in org_query %} selected{% endif %}>
|
||||
{{ org.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
<button id="search-btn" class="btn-green small"> {{ _('Search')}} </button>
|
||||
{% if create_url %}
|
||||
<a href="{{create_url}}" class="button small" style="float: right"><i class="fa fa-plus"></i> {{ _('Create')}}</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% if active_participations %}
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Active Contests') }}
|
||||
</h3>
|
||||
<div class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90%">{{ _('Contest') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for participation in active_participations %}
|
||||
{% with contest=participation.contest %}
|
||||
<tr>
|
||||
<th style="width:90%">
|
||||
<a class="contest-list-sort" href="{{ sort_links.name }}">{{ _('Contest') }}{{ sort_order.name }}</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="contest-list-sort" href="{{ sort_links.user_count }}">{{ _('Users') }}{{ sort_order.user_count }}</a>
|
||||
</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in past_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{{ time_left(contest) }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{% if not request.in_contest %}
|
||||
<td><form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small"
|
||||
value="{{ _('Virtual join') }}">
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_limit %}
|
||||
<span class="time">
|
||||
{% trans countdown=participation.end_time|as_countdown %}Window ends in {{countdown}}{% endtrans %}
|
||||
</span>
|
||||
{% elif contest.time_before_end %}
|
||||
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if page_obj and page_obj.num_pages > 1 %}
|
||||
<div style="margin-top: 10px;">
|
||||
{% include "list-pages.html" %}
|
||||
</div>
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{{ contest_join(contest, request) }}
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br>
|
||||
{% endif %}
|
||||
|
||||
{% if current_contests %}
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Ongoing Contests') }}
|
||||
</h3>
|
||||
<div id="ongoing-table" class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90%">{{ _('Contest') }}</th>
|
||||
<th>{{ _('Users') }}</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in current_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_before_end %}
|
||||
<span class="time">{% trans countdown=contest.end_time|as_countdown %}Ends in {{countdown}}{% endtrans %}</span>
|
||||
{% endif %}
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{{ contest_join(contest, request) }}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3 class="toggle open contest-group-header">
|
||||
<i class="fa fa-chevron-right fa-fw"></i>
|
||||
{{ _('Upcoming Contests') }}
|
||||
</h3>
|
||||
{% if future_contests %}
|
||||
<div class="toggled">
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _('Contest') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in future_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{% if contest.start_time %}
|
||||
<br>
|
||||
{% if contest.time_before_start %}
|
||||
<span class="time">{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}</span>
|
||||
{% endif %}
|
||||
{{ time_left(contest) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<i>{{ _('There are no scheduled contests at this time.') }}</i>
|
||||
<br>
|
||||
{% endif %}
|
||||
<br>
|
||||
|
||||
{% if past_contests %}
|
||||
<h3 class="contest-group-header">{{ _('Past Contests') }}</h3>
|
||||
{% if page_obj and page_obj.num_pages > 1 %}
|
||||
<div style="margin-bottom: 4px;">
|
||||
{% include "list-pages.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="contest-list table striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:90%">
|
||||
<a class="contest-list-sort" href="{{ sort_links.name }}">{{ _('Contest') }}{{ sort_order.name }}</a>
|
||||
</th>
|
||||
<th>
|
||||
<a class="contest-list-sort" href="{{ sort_links.user_count }}">{{ _('Users') }}{{ sort_order.user_count }}</a>
|
||||
</th>
|
||||
{% if not request.in_contest %}
|
||||
<th style="width:15%"></th>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for contest in past_contests %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="contest-block">
|
||||
{{ contest_head(contest) }}
|
||||
{{ time_left(contest) }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ user_count(contest, request.user) }}
|
||||
</td>
|
||||
{% if not request.in_contest %}
|
||||
<td><form action="{{ url('contest_join', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full small"
|
||||
value="{{ _('Virtual join') }}">
|
||||
</form>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if page_obj and page_obj.num_pages > 1 %}
|
||||
<div style="margin-top: 10px;">
|
||||
{% include "list-pages.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,212 +1,212 @@
|
|||
<script src="//cdn.jsdelivr.net/npm/featherlight@1.7.14/release/featherlight.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script type="text/javascript">
|
||||
function isFaster(time1, time2) {
|
||||
let arr1 = time1.split(':');
|
||||
let arr2 = time2.split(':');
|
||||
function isFaster(time1, time2) {
|
||||
let arr1 = time1.split(':');
|
||||
let arr2 = time2.split(':');
|
||||
|
||||
for (let i in arr1) {
|
||||
let val1 = parseInt(arr1[i]);
|
||||
let val2 = parseInt(arr2[i]);
|
||||
if (val1 < val2) return true;
|
||||
if (val1 > val2) return false;
|
||||
}
|
||||
return false;
|
||||
for (let i in arr1) {
|
||||
let val1 = parseInt(arr1[i]);
|
||||
let val2 = parseInt(arr2[i]);
|
||||
if (val1 < val2) return true;
|
||||
if (val1 > val2) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function scoretimeComparison(sub1, sub2) {
|
||||
if (!sub2) return true;
|
||||
return sub1['score'] > sub2['score'] || (sub1['score'] === sub2['score'] && isFaster(sub1['time'], sub2['time']));
|
||||
}
|
||||
function scoretimeComparison(sub1, sub2) {
|
||||
if (!sub2) return true;
|
||||
return sub1['score'] > sub2['score'] || (sub1['score'] === sub2['score'] && isFaster(sub1['time'], sub2['time']));
|
||||
}
|
||||
|
||||
function highlightFirstSolve() {
|
||||
// bucket to store submissions by problems
|
||||
let bestSubmissions = {};
|
||||
function highlightFirstSolve() {
|
||||
// bucket to store submissions by problems
|
||||
let bestSubmissions = {};
|
||||
|
||||
// get information
|
||||
$('td a').each(function() {
|
||||
var td = $(this)[0];
|
||||
var link = $(this).attr('data-featherlight');
|
||||
if (link && link.includes('submissions')) {
|
||||
let scoreAndTime = (td.innerText.split('\n'))
|
||||
let linkElements = link.split('/')
|
||||
|
||||
// get information
|
||||
$('td a').each(function() {
|
||||
var td = $(this)[0];
|
||||
var link = $(this).attr('data-featherlight');
|
||||
if (link && link.includes('submissions')) {
|
||||
let scoreAndTime = (td.innerText.split('\n'))
|
||||
let linkElements = link.split('/')
|
||||
let problem = linkElements[linkElements.length - 2];
|
||||
let score = parseFloat(scoreAndTime[0].replace(',', '.'));
|
||||
let time = scoreAndTime[1];
|
||||
|
||||
// get information
|
||||
let problem = linkElements[linkElements.length - 2];
|
||||
let score = parseFloat(scoreAndTime[0].replace(',', '.'));
|
||||
let time = scoreAndTime[1];
|
||||
if (time) {
|
||||
let curSubmission = {
|
||||
'td': $(this).parent(),
|
||||
'score': score,
|
||||
'time': time
|
||||
}
|
||||
|
||||
if (time) {
|
||||
let curSubmission = {
|
||||
'td': $(this).parent(),
|
||||
'score': score,
|
||||
'time': time
|
||||
}
|
||||
// update best submissions
|
||||
let curBest = bestSubmissions[problem]
|
||||
|
||||
// update best submissions
|
||||
let curBest = bestSubmissions[problem]
|
||||
|
||||
if (scoretimeComparison(curSubmission, curBest) && score) {
|
||||
bestSubmissions[problem] = curSubmission;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
for (let problem in bestSubmissions) {
|
||||
bestSubmissions[problem]['td'].addClass('first-solve')
|
||||
if (scoretimeComparison(curSubmission, curBest) && score) {
|
||||
bestSubmissions[problem] = curSubmission;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
for (let problem in bestSubmissions) {
|
||||
bestSubmissions[problem]['td'].addClass('first-solve')
|
||||
}
|
||||
}
|
||||
|
||||
function renew_filter(need_update=true) {
|
||||
var checkboxes = [
|
||||
'#show-schools-checkbox',
|
||||
'#show-fullnames-checkbox',
|
||||
'#show-total-score-checkbox',
|
||||
];
|
||||
|
||||
var checkboxes2 = [
|
||||
'#show-friends-checkbox',
|
||||
'#show-virtual-checkbox'
|
||||
]
|
||||
|
||||
for (var i of checkboxes) {
|
||||
var $box = $(i);
|
||||
if ($box.is(':checked')) {
|
||||
$box.prop('checked', false);
|
||||
$box.click();
|
||||
$box.prop('checked', true);
|
||||
}
|
||||
}
|
||||
|
||||
function renew_filter(need_update=true) {
|
||||
var checkboxes = [
|
||||
'#show-schools-checkbox',
|
||||
'#show-fullnames-checkbox',
|
||||
'#show-total-score-checkbox',
|
||||
];
|
||||
|
||||
var checkboxes2 = [
|
||||
'#show-friends-checkbox',
|
||||
'#show-virtual-checkbox'
|
||||
]
|
||||
|
||||
for (var i of checkboxes) {
|
||||
var $box = $(i);
|
||||
if ($box.is(':checked')) {
|
||||
$box.prop('checked', false);
|
||||
$box.click();
|
||||
$box.prop('checked', true);
|
||||
}
|
||||
}
|
||||
|
||||
var to_update = false;
|
||||
for (var i of checkboxes2) {
|
||||
var $box = $(i);
|
||||
if ($box.is(':checked')) {
|
||||
to_update = true;
|
||||
}
|
||||
}
|
||||
if (to_update && need_update) {
|
||||
update_ranking();
|
||||
}
|
||||
var to_update = false;
|
||||
for (var i of checkboxes2) {
|
||||
var $box = $(i);
|
||||
if ($box.is(':checked')) {
|
||||
to_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
function get_initial_rank() {
|
||||
var ranks = $('.rank-td').map(function() {return this.innerHTML}).get();
|
||||
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
|
||||
window.user_rank = new Map();
|
||||
for (var i = 0; i < ranks.length; i++) {
|
||||
window.user_rank[usernames[i]] = ranks[i];
|
||||
}
|
||||
if (to_update && need_update) {
|
||||
update_ranking();
|
||||
}
|
||||
}
|
||||
|
||||
function add_initial_friend_rank() {
|
||||
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
|
||||
|
||||
var is_virtual = [];
|
||||
$('.user-name').each(function() {
|
||||
if($(this).children('sub').length) {
|
||||
is_virtual.push(1);
|
||||
}
|
||||
else is_virtual.push(0);
|
||||
});
|
||||
|
||||
$('.rank-td').each(function(i) {
|
||||
if (!is_virtual[i]) this.innerHTML += ' (' + window.user_rank[usernames[i]] + ')';
|
||||
});
|
||||
function get_initial_rank() {
|
||||
var ranks = $('.rank-td').map(function() {return this.innerHTML}).get();
|
||||
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
|
||||
window.user_rank = new Map();
|
||||
for (var i = 0; i < ranks.length; i++) {
|
||||
window.user_rank[usernames[i]] = ranks[i];
|
||||
}
|
||||
}
|
||||
|
||||
function update_ranking() {
|
||||
var friend = $('#show-friends-checkbox').is(':checked');
|
||||
var virtual = $('#show-virtual-checkbox').is(':checked');
|
||||
$('#loading-gif').show();
|
||||
var url = `{{url('contest_ranking_ajax', contest.key)}}?friend=${friend}&virtual=${virtual}`;
|
||||
{% if page_type == 'final_ranking' %}
|
||||
url += "&final=true";
|
||||
{% endif %}
|
||||
$.get({
|
||||
url: url,
|
||||
success: function(HTML) {
|
||||
$('#users-table').html(HTML);
|
||||
highlightFirstSolve();
|
||||
renew_filter(false);
|
||||
$('#loading-gif').hide();
|
||||
if (!virtual && !friend) {
|
||||
get_initial_rank();
|
||||
}
|
||||
if (friend) {
|
||||
add_initial_friend_rank();
|
||||
}
|
||||
},
|
||||
fail: function() {
|
||||
console.log('Fail to update ranking');
|
||||
}
|
||||
});
|
||||
}
|
||||
function add_initial_friend_rank() {
|
||||
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
|
||||
|
||||
$(function () {
|
||||
$('.leaving-forever').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to leave?') }}\n' +
|
||||
'{{ _('You cannot come back to a virtual participation. You will have to start a new one.') }}');
|
||||
});
|
||||
|
||||
$('.first-join').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to join?') }}\n' +
|
||||
'{{ _('Joining a contest starts your timer, after which it becomes unstoppable.') }}');
|
||||
});
|
||||
|
||||
var url = '{{ url('contest_participation', contest.key, '__username__') }}';
|
||||
var placeholder = $('#search-contest').replaceWith($('<select>').attr({
|
||||
id: 'search-contest'
|
||||
})).attr('placeholder');
|
||||
|
||||
$('#search-contest').select2({
|
||||
placeholder: placeholder,
|
||||
ajax: {
|
||||
url: '{{ url('contest_user_search_select2_ajax', contest.key) }}'
|
||||
},
|
||||
minimumInputLength: 1,
|
||||
escapeMarkup: function (markup) {
|
||||
return markup;
|
||||
},
|
||||
templateResult: function (data, container) {
|
||||
return ('<img class="user-search-image" src="' + data.gravatar_url + '" width="24" height="24">' +
|
||||
'<span class="' + data.display_rank + ' user-search-name">' + data.text + '</span>');
|
||||
}
|
||||
}).on('change', function () {
|
||||
window.location.href = url.replace('__username__', $(this).val());
|
||||
});
|
||||
|
||||
$('#show-schools-checkbox').click(function () {
|
||||
$('.school').toggle();
|
||||
});
|
||||
$('#show-fullnames-checkbox').click(function () {
|
||||
$('.fullname').toggle();
|
||||
});
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
$('#show-friends-checkbox').click(function() {
|
||||
update_ranking();
|
||||
})
|
||||
{% endif %}
|
||||
$('#show-virtual-checkbox').click(function() {
|
||||
update_ranking();
|
||||
})
|
||||
$('#show-total-score-checkbox').click(function() {
|
||||
$('.problem-score-col').toggle();
|
||||
})
|
||||
|
||||
highlightFirstSolve();
|
||||
renew_filter();
|
||||
get_initial_rank();
|
||||
|
||||
{% if participation_tab %}
|
||||
$('#show-virtual-checkbox').hide();
|
||||
$('#show-virtual-label').hide();
|
||||
{% else %}
|
||||
{% if request.in_contest %}
|
||||
clearInterval(window.rankingInterval);
|
||||
window.rankingInterval = setInterval(update_ranking, 60 * 1000);
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
var is_virtual = [];
|
||||
$('.user-name').each(function() {
|
||||
if($(this).children('sub').length) {
|
||||
is_virtual.push(1);
|
||||
}
|
||||
else is_virtual.push(0);
|
||||
});
|
||||
|
||||
$('.rank-td').each(function(i) {
|
||||
if (!is_virtual[i]) this.innerHTML += ' (' + window.user_rank[usernames[i]] + ')';
|
||||
});
|
||||
}
|
||||
|
||||
function update_ranking() {
|
||||
var friend = $('#show-friends-checkbox').is(':checked');
|
||||
var virtual = $('#show-virtual-checkbox').is(':checked');
|
||||
$('#loading-gif').show();
|
||||
var url = `{{url('contest_ranking_ajax', contest.key)}}?friend=${friend}&virtual=${virtual}`;
|
||||
{% if page_type == 'final_ranking' %}
|
||||
url += "&final=true";
|
||||
{% endif %}
|
||||
$.get({
|
||||
url: url,
|
||||
success: function(HTML) {
|
||||
$('#users-table').html(HTML);
|
||||
highlightFirstSolve();
|
||||
renew_filter(false);
|
||||
$('#loading-gif').hide();
|
||||
if (!virtual && !friend) {
|
||||
get_initial_rank();
|
||||
}
|
||||
if (friend) {
|
||||
add_initial_friend_rank();
|
||||
}
|
||||
},
|
||||
fail: function() {
|
||||
console.log('Fail to update ranking');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function () {
|
||||
$('.leaving-forever').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to leave?') }}\n' +
|
||||
'{{ _('You cannot come back to a virtual participation. You will have to start a new one.') }}');
|
||||
});
|
||||
|
||||
$('.first-join').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to join?') }}\n' +
|
||||
'{{ _('Joining a contest starts your timer, after which it becomes unstoppable.') }}');
|
||||
});
|
||||
|
||||
var url = '{{ url('contest_participation', contest.key, '__username__') }}';
|
||||
var placeholder = $('#search-contest').replaceWith($('<select>').attr({
|
||||
id: 'search-contest'
|
||||
})).attr('placeholder');
|
||||
|
||||
$('#search-contest').select2({
|
||||
placeholder: placeholder,
|
||||
ajax: {
|
||||
url: '{{ url('contest_user_search_select2_ajax', contest.key) }}'
|
||||
},
|
||||
minimumInputLength: 1,
|
||||
escapeMarkup: function (markup) {
|
||||
return markup;
|
||||
},
|
||||
templateResult: function (data, container) {
|
||||
return ('<img class="user-search-image" src="' + data.gravatar_url + '" width="24" height="24">' +
|
||||
'<span class="' + data.display_rank + ' user-search-name">' + data.text + '</span>');
|
||||
}
|
||||
}).on('change', function () {
|
||||
window.location.href = url.replace('__username__', $(this).val());
|
||||
});
|
||||
|
||||
$('#show-schools-checkbox').click(function () {
|
||||
$('.school').toggle();
|
||||
});
|
||||
$('#show-fullnames-checkbox').click(function () {
|
||||
$('.fullname').toggle();
|
||||
});
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
$('#show-friends-checkbox').click(function() {
|
||||
update_ranking();
|
||||
})
|
||||
{% endif %}
|
||||
$('#show-virtual-checkbox').click(function() {
|
||||
update_ranking();
|
||||
})
|
||||
$('#show-total-score-checkbox').click(function() {
|
||||
$('.problem-score-col').toggle();
|
||||
})
|
||||
|
||||
highlightFirstSolve();
|
||||
renew_filter();
|
||||
get_initial_rank();
|
||||
|
||||
{% if participation_tab %}
|
||||
$('#show-virtual-checkbox').hide();
|
||||
$('#show-virtual-label').hide();
|
||||
{% else %}
|
||||
{% if request.in_contest %}
|
||||
clearInterval(window.rankingInterval);
|
||||
window.rankingInterval = setInterval(update_ranking, 60 * 1000);
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
</script>
|
|
@ -2,84 +2,84 @@
|
|||
{% set page_type = 'moss' %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style>
|
||||
.panes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.pane {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.panes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
.pane {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('.contest-moss').click(function () {
|
||||
return confirm('{{ _('Are you sure you want MOSS the contest?') }}');
|
||||
});
|
||||
});
|
||||
$(function () {
|
||||
$('.contest-moss-delete').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to delete the MOSS results?') }}');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('.contest-moss').click(function () {
|
||||
return confirm('{{ _('Are you sure you want MOSS the contest?') }}');
|
||||
});
|
||||
});
|
||||
$(function () {
|
||||
$('.contest-moss-delete').click(function () {
|
||||
return confirm('{{ _('Are you sure you want to delete the MOSS results?') }}');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% if has_results %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="header">{{ _('Problem') }}</th>
|
||||
{% for lang in languages %}
|
||||
<th class="header">{{ lang }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem, results in moss_results %}
|
||||
<tr id="problem-{{ problem.code }}">
|
||||
<td>
|
||||
<a href="{{ url('problem_detail', problem.code) }}">{{ problem.name }}</a>
|
||||
</td>
|
||||
{% for result in results %}
|
||||
<td>
|
||||
{% if result.submission_count %}
|
||||
<a href="{{ result.url }}">{{ result.submission_count }} {{_('submissions')}}</a>
|
||||
{% else %}
|
||||
{{ _('No submissions') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<div class="panes">
|
||||
<div class="pane">
|
||||
<form method="post" action="{{ url('contest_moss', contest.key) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full contest-moss" style="padding: 10px;"
|
||||
value="{% if has_results %} {{ _('Re-MOSS contest') }} {% else %} {{ _('MOSS contest') }} {% endif %}">
|
||||
</form>
|
||||
</div>
|
||||
{% if has_results %}
|
||||
<div class="pane">
|
||||
<form method="post" action="{{ url('contest_moss_delete', contest.key) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full contest-moss-delete" style="padding: 10px;"
|
||||
value="{{ _('Delete MOSS results') }}">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if has_results %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="header">{{ _('Problem') }}</th>
|
||||
{% for lang in languages %}
|
||||
<th class="header">{{ lang }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem, results in moss_results %}
|
||||
<tr id="problem-{{ problem.code }}">
|
||||
<td>
|
||||
<a href="{{ url('problem_detail', problem.code) }}">{{ problem.name }}</a>
|
||||
</td>
|
||||
{% for result in results %}
|
||||
<td>
|
||||
{% if result.submission_count %}
|
||||
<a href="{{ result.url }}">{{ result.submission_count }} {{_('submissions')}}</a>
|
||||
{% else %}
|
||||
{{ _('No submissions') }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<div class="panes">
|
||||
<div class="pane">
|
||||
<form method="post" action="{{ url('contest_moss', contest.key) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full contest-moss" style="padding: 10px;"
|
||||
value="{% if has_results %} {{ _('Re-MOSS contest') }} {% else %} {{ _('MOSS contest') }} {% endif %}">
|
||||
</form>
|
||||
</div>
|
||||
{% if has_results %}
|
||||
<div class="pane">
|
||||
<form method="post" action="{{ url('contest_moss_delete', contest.key) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button full contest-moss-delete" style="padding: 10px;"
|
||||
value="{{ _('Delete MOSS results') }}">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{ preview_data|markdown|reference|str|safe }}
|
||||
{% if REQUIRE_JAX %}
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
{% endif %}
|
|
@ -1,20 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
{% if error.is_private %}
|
||||
<p><i>{{ _('This contest is private to specific users.') }}</i></p>
|
||||
{% endif %}
|
||||
{% if error.is_private %}
|
||||
<p><i>{{ _('This contest is private to specific users.') }}</i></p>
|
||||
{% endif %}
|
||||
|
||||
{% if error.is_organization_private %}
|
||||
{% if error.is_private %}
|
||||
<p>{{ _('Additionally, only the following organizations may access this contest:') }}</p>
|
||||
{% else %}
|
||||
<p>{{ _('Only the following organizations may access this contest:') }}</p>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% for org in error.orgs %}
|
||||
<li><a href="{{ org.get_absolute_url() }}">{{ org.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if error.is_organization_private %}
|
||||
{% if error.is_private %}
|
||||
<p>{{ _('Additionally, only the following organizations may access this contest:') }}</p>
|
||||
{% else %}
|
||||
<p>{{ _('Only the following organizations may access this contest:') }}</p>
|
||||
{% endif %}
|
||||
<ul>
|
||||
{% for org in error.orgs %}
|
||||
<li><a href="{{ org.get_absolute_url() }}">{{ org.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,102 +1,102 @@
|
|||
<style>
|
||||
#users-table .username {
|
||||
min-width: 15em;
|
||||
}
|
||||
#users-table .username {
|
||||
min-width: 15em;
|
||||
}
|
||||
|
||||
#users-table td {
|
||||
height: 2.5em;
|
||||
}
|
||||
#users-table td {
|
||||
height: 2.5em;
|
||||
}
|
||||
|
||||
#users-table a {
|
||||
display: block;
|
||||
}
|
||||
#users-table a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.userinfo a, .user-name a, .user-name form {
|
||||
display: inline !important;
|
||||
}
|
||||
.userinfo a, .user-name a, .user-name form {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
#users-table td a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#users-table td a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.rank {
|
||||
min-width: 2.5em
|
||||
}
|
||||
.rank {
|
||||
min-width: 2.5em
|
||||
}
|
||||
|
||||
.points {
|
||||
min-width: 2.5em;
|
||||
}
|
||||
.points {
|
||||
min-width: 2.5em;
|
||||
}
|
||||
|
||||
.start-time {
|
||||
display: none;
|
||||
}
|
||||
.start-time {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
position: relative;
|
||||
padding-left: 2em !important;
|
||||
}
|
||||
.user-name {
|
||||
position: relative;
|
||||
padding-left: 2em !important;
|
||||
}
|
||||
|
||||
.organization-column {
|
||||
display: none;
|
||||
text-align: left !important;
|
||||
border-right: none !important;
|
||||
}
|
||||
.organization-column {
|
||||
display: none;
|
||||
text-align: left !important;
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
.featherlight-content {
|
||||
border-radius: 10px;
|
||||
height: 80%;
|
||||
width: 60%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.select2-selection__arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-selection__rendered {
|
||||
cursor: text;
|
||||
overflow: initial !important
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#search-contest, #search-contest + .select2 {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#search-contest {
|
||||
width: 200px;
|
||||
height: 2.3em;
|
||||
}
|
||||
html.with-featherlight {
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
@media (max-width: 799px) {
|
||||
.featherlight-content {
|
||||
border-radius: 10px;
|
||||
height: 80%;
|
||||
width: 60%;
|
||||
overflow: auto;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.select2-selection__arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-selection__rendered {
|
||||
cursor: text;
|
||||
overflow: initial !important
|
||||
}
|
||||
|
||||
.select2-results__option {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#search-contest, #search-contest + .select2 {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#search-contest {
|
||||
width: 200px;
|
||||
height: 2.3em;
|
||||
}
|
||||
html.with-featherlight {
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
@media (max-width: 799px) {
|
||||
.featherlight-content {
|
||||
width: 95%;
|
||||
}
|
||||
#users-table .username {
|
||||
min-width: fit-content;
|
||||
}
|
||||
#users-table .username {
|
||||
min-width: fit-content;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{% if has_rating %}
|
||||
<style>#users-table .rate-box {
|
||||
font-size: 0.85em;
|
||||
float: left;
|
||||
}
|
||||
<style>#users-table .rate-box {
|
||||
font-size: 0.85em;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#users-table td:nth-child(1) .rating {
|
||||
margin-left: 1.25em;
|
||||
display: block;
|
||||
margin-left: 1.25em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#users-table td:nth-child(2) a {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
{% endif %}
|
||||
|
|
|
@ -3,77 +3,77 @@
|
|||
{% set friends = request.profile.get_friends() if request.user.is_authenticated else {} %}
|
||||
|
||||
{% block after_rank_head %}
|
||||
{% if has_rating %}
|
||||
<th class="rating-column">{{ _('Rating') }}</th>
|
||||
{% endif %}
|
||||
{% if has_rating %}
|
||||
<th class="rating-column">{{ _('Rating') }}</th>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block after_rank %}
|
||||
{% if has_rating %}
|
||||
<td class="rating-column">{% if user.participation_rating %}{{ rating_number(user.participation_rating) }}{% endif %}</td>
|
||||
{% endif %}
|
||||
{% if has_rating %}
|
||||
<td class="rating-column">{% if user.participation_rating %}{{ rating_number(user.participation_rating) }}{% endif %}</td>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block user_footer %}
|
||||
{% if user.user.first_name %}
|
||||
<div style="font-weight: 600; display: none" class="fullname gray">
|
||||
{{ user.user.first_name if user.user.first_name else ''}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user.user.last_name %}
|
||||
<div class="school gray" style="display: none"><a style="font-weight: 600">
|
||||
{{- user.user.last_name -}}
|
||||
</a></div>
|
||||
{% endif %}
|
||||
{% if user.user.first_name %}
|
||||
<div style="font-weight: 600; display: none" class="fullname gray">
|
||||
{{ user.user.first_name if user.user.first_name else ''}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if user.user.last_name %}
|
||||
<div class="school gray" style="display: none"><a style="font-weight: 600">
|
||||
{{- user.user.last_name -}}
|
||||
</a></div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block user_data %}
|
||||
{% if user.participation.virtual %}
|
||||
<sub class="gray">[{{user.participation.virtual}}]</sub>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<span class="contest-participation-operation">
|
||||
<form action="{{ url('contest_participation_disqualify', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="participation" value="{{ user.participation.id }}">
|
||||
{% if user.participation.is_disqualified %}
|
||||
<a href="#" title="{{ _('Un-Disqualify') }}"
|
||||
class="un-disqualify-participation"><i class="fa fa-undo fa-fw"></i></a>
|
||||
{% else %}
|
||||
<a href="#" title="{{ _('Disqualify') }}"
|
||||
class="disqualify-participation"><i class="fa fa-trash fa-fw"></i></a>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% if perms.judge.change_contestparticipation %}
|
||||
<a href="{{ url('admin:judge_contestparticipation_change', user.participation.id) }}"
|
||||
title="{{ _('Admin') }}" class="edit-participation"><i class="fa fa-cog fa-fw"></i></a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if user.participation.virtual %}
|
||||
<sub class="gray">[{{user.participation.virtual}}]</sub>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<span class="contest-participation-operation">
|
||||
<form action="{{ url('contest_participation_disqualify', contest.key) }}" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="participation" value="{{ user.participation.id }}">
|
||||
{% if user.participation.is_disqualified %}
|
||||
<a href="#" title="{{ _('Un-Disqualify') }}"
|
||||
class="un-disqualify-participation"><i class="fa fa-undo fa-fw"></i></a>
|
||||
{% else %}
|
||||
<a href="#" title="{{ _('Disqualify') }}"
|
||||
class="disqualify-participation"><i class="fa fa-trash fa-fw"></i></a>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% if perms.judge.change_contestparticipation %}
|
||||
<a href="{{ url('admin:judge_contestparticipation_change', user.participation.id) }}"
|
||||
title="{{ _('Admin') }}" class="edit-participation"><i class="fa fa-cog fa-fw"></i></a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block before_point_head %}
|
||||
<th class="full-name" style="display:none;">{{ _('Fullname') }}</th>
|
||||
<th style="display:none;">{{ _('School') }}</th>
|
||||
{% for problem in problems %}
|
||||
<th class="points header problem-score-col" title="{{ problem.problem.name }}"><a href="{{ url('problem_detail', problem.problem.code) }}">
|
||||
{{- contest.get_label_for_problem(loop.index0) }}
|
||||
<div class="point-denominator">{{ problem.points }}</div>
|
||||
<div class="problem-code" style="display: none;">{{ problem.problem.code }}</div>
|
||||
</a></th>
|
||||
{% endfor %}
|
||||
<th class="full-name" style="display:none;">{{ _('Fullname') }}</th>
|
||||
<th style="display:none;">{{ _('School') }}</th>
|
||||
{% for problem in problems %}
|
||||
<th class="points header problem-score-col" title="{{ problem.problem.name }}"><a href="{{ url('problem_detail', problem.problem.code) }}">
|
||||
{{- contest.get_label_for_problem(loop.index0) }}
|
||||
<div class="point-denominator">{{ problem.points }}</div>
|
||||
<div class="problem-code" style="display: none;">{{ problem.problem.code }}</div>
|
||||
</a></th>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block row_extra %}
|
||||
class="{{ 'disqualified' if user.participation.is_disqualified }} {{'highlight' if user.username == request.user.username}}"
|
||||
class="{{ 'disqualified' if user.participation.is_disqualified }} {{'highlight' if user.username == request.user.username}}"
|
||||
{% endblock %}
|
||||
|
||||
{% block before_point %}
|
||||
{% for cell in user.problem_cells %}
|
||||
{{ cell }}
|
||||
{% endfor %}
|
||||
{% for cell in user.problem_cells %}
|
||||
{{ cell }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block point %}
|
||||
{{ user.result_cell }}
|
||||
{{ user.result_cell }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,160 +1,160 @@
|
|||
{% extends "user/base-users-two-col.html" %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block users_media %}
|
||||
{% include "contest/ranking-css.html" %}
|
||||
{% include "contest/ranking-css.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block users_js_media %}
|
||||
{% if can_edit %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('a.disqualify-participation').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to disqualify this participation?') }}"))
|
||||
$(this).closest('form').submit();
|
||||
})
|
||||
$('a.un-disqualify-participation').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to un-disqualify this participation?') }}"))
|
||||
$(this).closest('form').submit();
|
||||
})
|
||||
{% if can_edit %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('a.disqualify-participation').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to disqualify this participation?') }}"))
|
||||
$(this).closest('form').submit();
|
||||
})
|
||||
$('a.un-disqualify-participation').click(function (e) {
|
||||
e.preventDefault();
|
||||
if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to un-disqualify this participation?') }}"))
|
||||
$(this).closest('form').submit();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if perms.judge.change_contestparticipation %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('td.user').find('a.user-name').click(function (e) {
|
||||
var data = $(this).siblings('.edit-participation');
|
||||
if (e.altKey && data.length) {
|
||||
window.open(data.attr('data-link'), '_blank');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if not contest.ended %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
window.install_tooltips = function () {
|
||||
$('td.user').find('a.user-name').each(function () {
|
||||
var link = $(this);
|
||||
link.mouseenter(function (e) {
|
||||
var start_time = link.siblings('.start-time').text();
|
||||
link.addClass('tooltipped tooltipped-e').attr('aria-label', start_time);
|
||||
}).mouseleave(function (e) {
|
||||
link.removeClass('tooltipped tooltipped-e').removeAttr('aria-label');
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if perms.judge.change_contestparticipation %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('td.user').find('a.user-name').click(function (e) {
|
||||
var data = $(this).siblings('.edit-participation');
|
||||
if (e.altKey && data.length) {
|
||||
window.open(data.attr('data-link'), '_blank');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if not contest.ended %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
window.install_tooltips = function () {
|
||||
$('td.user').find('a.user-name').each(function () {
|
||||
var link = $(this);
|
||||
link.mouseenter(function (e) {
|
||||
var start_time = link.siblings('.start-time').text();
|
||||
link.addClass('tooltipped tooltipped-e').attr('aria-label', start_time);
|
||||
}).mouseleave(function (e) {
|
||||
link.removeClass('tooltipped tooltipped-e').removeAttr('aria-label');
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
install_tooltips();
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if page_type == 'ranking' or page_type == 'final_ranking' %}
|
||||
<script type="text/javascript">
|
||||
$.fn.ignore = function(sel) {
|
||||
return this.clone().find(sel || '>*').remove().end();
|
||||
};
|
||||
install_tooltips();
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if page_type == 'ranking' or page_type == 'final_ranking' %}
|
||||
<script type="text/javascript">
|
||||
$.fn.ignore = function(sel) {
|
||||
return this.clone().find(sel || '>*').remove().end();
|
||||
};
|
||||
|
||||
function download_ranking_as_csv() {
|
||||
function clean_text(text) {
|
||||
// Remove new line and leading/trailing spaces
|
||||
text = text.replace(/(\r\n|\n|\r)/gm, '').trim();
|
||||
// Escape double-quote with double-double-quote
|
||||
text = text.replace(/"/g, '""');
|
||||
function download_ranking_as_csv() {
|
||||
function clean_text(text) {
|
||||
// Remove new line and leading/trailing spaces
|
||||
text = text.replace(/(\r\n|\n|\r)/gm, '').trim();
|
||||
// Escape double-quote with double-double-quote
|
||||
text = text.replace(/"/g, '""');
|
||||
|
||||
return '"' + text + '"';
|
||||
}
|
||||
return '"' + text + '"';
|
||||
}
|
||||
|
||||
var csv = [];
|
||||
var csv = [];
|
||||
|
||||
$('table#users-table thead tr').each(function () {
|
||||
var header = [];
|
||||
$(this).find('th').each(function () {
|
||||
var $col = $(this);
|
||||
$('table#users-table thead tr').each(function () {
|
||||
var header = [];
|
||||
$(this).find('th').each(function () {
|
||||
var $col = $(this);
|
||||
|
||||
if ($col.hasClass('rating-column')) {
|
||||
return;
|
||||
} else if ($col.hasClass('problem-score-col')) {
|
||||
header.push(clean_text($col.find('.problem-code').text()));
|
||||
} else {
|
||||
header.push(clean_text($col.text()));
|
||||
}
|
||||
});
|
||||
csv.push(header.join(','));
|
||||
});
|
||||
|
||||
$('table#users-table tbody tr').each(function () {
|
||||
var row_data = [];
|
||||
|
||||
$(this).find('td').each(function () {
|
||||
var $col = $(this);
|
||||
if ($col.hasClass('rating-column')) {
|
||||
return;
|
||||
} else if ($col.hasClass('user-name')) {
|
||||
row_data.push(clean_text($col.ignore('.fullname').ignore('.school').text()));
|
||||
row_data.push(clean_text($col.ignore('.user').ignore('.school').text()));
|
||||
row_data.push(clean_text($col.ignore('.user').ignore('.fullname').text()));
|
||||
} else {
|
||||
row_data.push(clean_text($col.ignore('.solving-time').text()));
|
||||
}
|
||||
});
|
||||
csv.push(row_data.join(','));
|
||||
});
|
||||
|
||||
csv = csv.join('\n');
|
||||
var filename = '{{ contest.key }}_' + moment().format('MMMM Do YYYY, h:mm:ss a'); + '.csv';
|
||||
var link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
link.setAttribute('target', '_blank');
|
||||
link.setAttribute('href', 'data:text/csv;charset=utf-8,\uFEFF' + encodeURIComponent(csv));
|
||||
link.setAttribute('download', filename);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
if ($col.hasClass('rating-column')) {
|
||||
return;
|
||||
} else if ($col.hasClass('problem-score-col')) {
|
||||
header.push(clean_text($col.find('.problem-code').text()));
|
||||
} else {
|
||||
header.push(clean_text($col.text()));
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% include "contest/media-js.html" %}
|
||||
});
|
||||
csv.push(header.join(','));
|
||||
});
|
||||
|
||||
$('table#users-table tbody tr').each(function () {
|
||||
var row_data = [];
|
||||
|
||||
$(this).find('td').each(function () {
|
||||
var $col = $(this);
|
||||
if ($col.hasClass('rating-column')) {
|
||||
return;
|
||||
} else if ($col.hasClass('user-name')) {
|
||||
row_data.push(clean_text($col.ignore('.fullname').ignore('.school').text()));
|
||||
row_data.push(clean_text($col.ignore('.user').ignore('.school').text()));
|
||||
row_data.push(clean_text($col.ignore('.user').ignore('.fullname').text()));
|
||||
} else {
|
||||
row_data.push(clean_text($col.ignore('.solving-time').text()));
|
||||
}
|
||||
});
|
||||
csv.push(row_data.join(','));
|
||||
});
|
||||
|
||||
csv = csv.join('\n');
|
||||
var filename = '{{ contest.key }}_' + moment().format('MMMM Do YYYY, h:mm:ss a'); + '.csv';
|
||||
var link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
link.setAttribute('target', '_blank');
|
||||
link.setAttribute('href', 'data:text/csv;charset=utf-8,\uFEFF' + encodeURIComponent(csv));
|
||||
link.setAttribute('download', filename);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% include "contest/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block before_table %}
|
||||
{% include "contest/contest-datetime.html" %}
|
||||
<div style="margin-bottom: 0.5em">
|
||||
{% if page_type == 'participation' %}
|
||||
{% if contest.can_see_full_scoreboard(request.user) %}
|
||||
<input id="search-contest" type="text" placeholder="{{ _('View user participation') }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<input id="show-schools-checkbox" type="checkbox" style="vertical-align: bottom">
|
||||
<label for="show-schools-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show schools') }}</label>
|
||||
{% include "contest/contest-datetime.html" %}
|
||||
<div style="margin-bottom: 0.5em">
|
||||
{% if page_type == 'participation' %}
|
||||
{% if contest.can_see_full_scoreboard(request.user) %}
|
||||
<input id="search-contest" type="text" placeholder="{{ _('View user participation') }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<input id="show-schools-checkbox" type="checkbox" style="vertical-align: bottom">
|
||||
<label for="show-schools-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show schools') }}</label>
|
||||
|
||||
<input id="show-fullnames-checkbox" type="checkbox" style="vertical-align: bottom">
|
||||
<input id="show-fullnames-checkbox" type="checkbox" style="vertical-align: bottom">
|
||||
|
||||
<label for="show-fullnames-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show full name') }}</label>
|
||||
{% if request.user.is_authenticated %}
|
||||
<input id="show-friends-checkbox" type="checkbox" style="vertical-align: bottom;">
|
||||
<label for="show-friends-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show friends only') }}</label>
|
||||
{% endif %}
|
||||
<input id="show-total-score-checkbox" type="checkbox" style="vertical-align: bottom; ">
|
||||
<label for="show-total-score-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Total score only') }}</label>
|
||||
<input id="show-virtual-checkbox" type="checkbox" style="vertical-align: bottom;">
|
||||
<label id="show-virtual-label" for="show-virtual-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show virtual participation') }}</label>
|
||||
<img src="{{static('loading.gif')}}" style="height: 1em; display:none;" id="loading-gif"></img>
|
||||
<a href="#" onclick="download_ranking_as_csv()" style="float: right;">
|
||||
<i class="fa fa-download" aria-hidden="true"></i>
|
||||
{{ _('Download as CSV') }}
|
||||
</a>
|
||||
</div>
|
||||
<label for="show-fullnames-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show full name') }}</label>
|
||||
{% if request.user.is_authenticated %}
|
||||
<input id="show-friends-checkbox" type="checkbox" style="vertical-align: bottom;">
|
||||
<label for="show-friends-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show friends only') }}</label>
|
||||
{% endif %}
|
||||
<input id="show-total-score-checkbox" type="checkbox" style="vertical-align: bottom; ">
|
||||
<label for="show-total-score-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Total score only') }}</label>
|
||||
<input id="show-virtual-checkbox" type="checkbox" style="vertical-align: bottom;">
|
||||
<label id="show-virtual-label" for="show-virtual-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show virtual participation') }}</label>
|
||||
<img src="{{static('loading.gif')}}" style="height: 1em; display:none;" id="loading-gif"></img>
|
||||
<a href="#" onclick="download_ranking_as_csv()" style="float: right;">
|
||||
<i class="fa fa-download" aria-hidden="true"></i>
|
||||
{{ _('Download as CSV') }}
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block users_table %}
|
||||
{% include "contest/ranking-table.html" %}
|
||||
{% include "contest/ranking-table.html" %}
|
||||
{% endblock %}
|
|
@ -2,82 +2,82 @@
|
|||
{% set page_type = 'stats' %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% include "contest/contest-tabs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_js %}
|
||||
<script type="text/javascript">
|
||||
window.stats = {{ stats }};
|
||||
</script>
|
||||
{% compress js %}
|
||||
{% include "stats/media-js.html" %}
|
||||
<script type="text/javascript">
|
||||
window.stats = {{ stats }};
|
||||
$(function () {
|
||||
draw_stacked_bar_chart(window.stats.problem_status_count, $('#problem-status-count'));
|
||||
draw_bar_chart(window.stats.problem_ac_rate, $('#problem-ac-rate'));
|
||||
pts_hist = draw_histogram(window.stats.problem_point[0], $('#problem-point'));
|
||||
draw_pie_chart(window.stats.language_count, $('#language-count'));
|
||||
draw_bar_chart(window.stats.language_ac_rate, $('#language-ac-rate'));
|
||||
|
||||
$('#problem-point-select').change(function() {
|
||||
pts_hist.destroy();
|
||||
problem = $(this).val();
|
||||
pts_hist = draw_histogram(window.stats.problem_point[problem],
|
||||
$('#problem-point'));
|
||||
})
|
||||
|
||||
$('#problem-point-select').select2({
|
||||
width: '10em',
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% compress js %}
|
||||
{% include "stats/media-js.html" %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
draw_stacked_bar_chart(window.stats.problem_status_count, $('#problem-status-count'));
|
||||
draw_bar_chart(window.stats.problem_ac_rate, $('#problem-ac-rate'));
|
||||
pts_hist = draw_histogram(window.stats.problem_point[0], $('#problem-point'));
|
||||
draw_pie_chart(window.stats.language_count, $('#language-count'));
|
||||
draw_bar_chart(window.stats.language_ac_rate, $('#language-ac-rate'));
|
||||
|
||||
$('#problem-point-select').change(function() {
|
||||
pts_hist.destroy();
|
||||
problem = $(this).val();
|
||||
pts_hist = draw_histogram(window.stats.problem_point[problem],
|
||||
$('#problem-point'));
|
||||
})
|
||||
|
||||
$('#problem-point-select').select2({
|
||||
width: '10em',
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endcompress %}
|
||||
{% include "contest/media-js.html" %}
|
||||
{% endcompress %}
|
||||
{% include "contest/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style>
|
||||
.chart {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.chart {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<h3>{{ _('Problem Status Distribution') }}</h3>
|
||||
<div id="problem-status-count" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
<h3>{{ _('Problem Status Distribution') }}</h3>
|
||||
<div id="problem-status-count" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
|
||||
<h3>{{ _('Problem AC Rate') }}</h3>
|
||||
<div id="problem-ac-rate" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
<h3>{{ _('Problem AC Rate') }}</h3>
|
||||
<div id="problem-ac-rate" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
{{ _('Problem Point Distribution') }}:
|
||||
<select id="problem-point-select">
|
||||
{% for name in problems %}
|
||||
<option value="{{ loop.index0 }}" class="point-dropdown">
|
||||
{{ name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</h3>
|
||||
<h3>
|
||||
{{ _('Problem Point Distribution') }}:
|
||||
<select id="problem-point-select">
|
||||
{% for name in problems %}
|
||||
<option value="{{ loop.index0 }}" class="point-dropdown">
|
||||
{{ name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</h3>
|
||||
|
||||
<div id="problem-point" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
<div id="problem-point" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
|
||||
<h3>{{ _('Submissions by Language') }}</h3>
|
||||
<div id="language-count" class="chart">
|
||||
<canvas width="400" height="300"></canvas>
|
||||
<ul class="legend"></ul>
|
||||
</div>
|
||||
<h3>{{ _('Submissions by Language') }}</h3>
|
||||
<div id="language-count" class="chart">
|
||||
<canvas width="400" height="300"></canvas>
|
||||
<ul class="legend"></ul>
|
||||
</div>
|
||||
|
||||
<h3>{{ _('Language AC Rate') }}</h3>
|
||||
<div id="language-ac-rate" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
<h3>{{ _('Language AC Rate') }}</h3>
|
||||
<div id="language-ac-rate" class="chart">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% if not title %}
|
||||
{% include "contest/tag-title.html" %}
|
||||
<br><br>
|
||||
<hr>
|
||||
{% include "contest/tag-title.html" %}
|
||||
<br><br>
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
{{ tag.description|markdown }}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<h2 style="display:inline">
|
||||
<span style="background-color: {{ tag.color }}; color: {{ tag.text_color }}" class="contest-tag">
|
||||
{{- tag.name -}}
|
||||
</span>
|
||||
<span style="background-color: {{ tag.color }}; color: {{ tag.text_color }}" class="contest-tag">
|
||||
{{- tag.name -}}
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
{% if perms.judge.change_contesttag %}
|
||||
<div class="title-line-action">
|
||||
[<a href="{{ url('admin:judge_contesttag_change', tag.id) }}">{{ _('Edit') }}</a>]
|
||||
</div>
|
||||
<div class="title-line-action">
|
||||
[<a href="{{ url('admin:judge_contesttag_change', tag.id) }}">{{ _('Edit') }}</a>]
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content_title %}
|
||||
{% include "contest/tag-title.html" %}
|
||||
{% include "contest/tag-title.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% include "contest/tag-ajax.html" %}
|
||||
{% include "contest/tag-ajax.html" %}
|
||||
{% endblock %}
|
|
@ -1,35 +1,35 @@
|
|||
{% if current_contests %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
{% for contest in current_contests %}
|
||||
<div class="contest">
|
||||
<div class="contest-list-title">
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</div>
|
||||
<div class="time">
|
||||
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
{% for contest in current_contests %}
|
||||
<div class="contest">
|
||||
<div class="contest-list-title">
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</div>
|
||||
<div class="time">
|
||||
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if future_contests %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
{% for contest in future_contests %}
|
||||
<div class="contest">
|
||||
<div class="contest-list-title">
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</div>
|
||||
<div class="time">
|
||||
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
{% for contest in future_contests %}
|
||||
<div class="contest">
|
||||
<div class="contest-list-title">
|
||||
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
|
||||
</div>
|
||||
<div class="time">
|
||||
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<title>{{ code }} - {{ id }}</title>
|
||||
<style>
|
||||
body {
|
||||
font-size: 16px;
|
||||
font-smooth: never;
|
||||
-webkit-font-smoothing: none;
|
||||
margin-left: 50px;
|
||||
margin-right: 50px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
body {
|
||||
font-size: 16px;
|
||||
font-smooth: never;
|
||||
-webkit-font-smoothing: none;
|
||||
margin-left: 50px;
|
||||
margin-right: 50px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.3;
|
||||
font-smooth: never;
|
||||
-webkit-font-smoothing: none;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
pre {
|
||||
line-height: 1.3;
|
||||
font-smooth: never;
|
||||
-webkit-font-smoothing: none;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>SIGSEGV: {{ id }}</h2>
|
||||
<hr/>
|
||||
<pre>{{ description }}
|
||||
</head>
|
||||
<body>
|
||||
<h2>SIGSEGV: {{ id }}</h2>
|
||||
<hr/>
|
||||
<pre>{{ description }}
|
||||
site: fatal signal: Segmentation fault
|
||||
site died (signal <b>{{ code }}</b>, exit -11)<br><br><a href="javascript:history.back()">Go back</a></pre>
|
||||
{% if request.user.is_superuser and traceback %}
|
||||
<pre>{{ traceback }}</pre>
|
||||
{% endif %}
|
||||
</body>
|
||||
{% if request.user.is_superuser and traceback %}
|
||||
<pre>{{ traceback }}</pre>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
<script type="text/template" id="qq-template">
|
||||
<div class="qq-uploader-selector qq-uploader">
|
||||
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
|
||||
<span>{{_('Drop files here to upload')}}</span>
|
||||
</div>
|
||||
<div class="qq-upload-button-selector qq-upload-button">
|
||||
<div>{{_('Upload file')}}</div>
|
||||
</div>
|
||||
<span class="qq-drop-processing-selector qq-drop-processing">
|
||||
<span>Processing dropped files...</span>
|
||||
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
|
||||
</span>
|
||||
<ul class="qq-upload-list-selector qq-upload-list">
|
||||
<li>
|
||||
<div class="qq-progress-bar-container-selector">
|
||||
<div class="qq-progress-bar-selector qq-progress-bar"></div>
|
||||
</div>
|
||||
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
|
||||
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
|
||||
<span class="qq-upload-file-selector qq-upload-file"></span>
|
||||
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
|
||||
<span class="qq-upload-size-selector qq-upload-size"></span>
|
||||
<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">{{_('Cancel')}}</a>
|
||||
<a class="qq-upload-retry-selector qq-upload-retry" href="#">{{_('Retry')}}</a>
|
||||
<a class="qq-upload-delete-selector qq-upload-delete" href="#">{{_('Delete')}}</a>
|
||||
<button class="qq-upload-pause-selector qq-upload-pause">{{_('Pause')}}</button>
|
||||
<button class="qq-upload-continue-selector qq-upload-continue">{{_('Continue')}}</button>
|
||||
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="qq-uploader-selector qq-uploader">
|
||||
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
|
||||
<span>{{_('Drop files here to upload')}}</span>
|
||||
</div>
|
||||
<div class="qq-upload-button-selector qq-upload-button">
|
||||
<div>{{_('Upload file')}}</div>
|
||||
</div>
|
||||
<span class="qq-drop-processing-selector qq-drop-processing">
|
||||
<span>Processing dropped files...</span>
|
||||
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
|
||||
</span>
|
||||
<ul class="qq-upload-list-selector qq-upload-list">
|
||||
<li>
|
||||
<div class="qq-progress-bar-container-selector">
|
||||
<div class="qq-progress-bar-selector qq-progress-bar"></div>
|
||||
</div>
|
||||
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
|
||||
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
|
||||
<span class="qq-upload-file-selector qq-upload-file"></span>
|
||||
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
|
||||
<span class="qq-upload-size-selector qq-upload-size"></span>
|
||||
<a class="qq-upload-cancel-selector qq-upload-cancel" href="#">{{_('Cancel')}}</a>
|
||||
<a class="qq-upload-retry-selector qq-upload-retry" href="#">{{_('Retry')}}</a>
|
||||
<a class="qq-upload-delete-selector qq-upload-delete" href="#">{{_('Delete')}}</a>
|
||||
<button class="qq-upload-pause-selector qq-upload-pause">{{_('Pause')}}</button>
|
||||
<button class="qq-upload-continue-selector qq-upload-continue">{{_('Continue')}}</button>
|
||||
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
{% if perms.flatpages.change_flatpage %}
|
||||
<div class="title-line-action">
|
||||
[<a href="{{ url('admin:flatpages_flatpage_change', flatpage.id) }}">{{ _('Edit') }}</a>]
|
||||
</div>
|
||||
<div class="title-line-action">
|
||||
[<a href="{{ url('admin:flatpages_flatpage_change', flatpage.id) }}">{{ _('Edit') }}</a>]
|
||||
</div>
|
||||
{% endif %}
|
|
@ -1,15 +1,15 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ flatpage.title }} - {{ SITE_LONG_NAME }}{% endblock %}
|
||||
{% block og_title %}
|
||||
<meta property="og:title" content="{{ flatpage.title }} - {{ SITE_LONG_NAME }}">
|
||||
<meta property="og:title" content="{{ flatpage.title }} - {{ SITE_LONG_NAME }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content_title %}{{ flatpage.title }}{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% include "flatpages/admin_link.html" %}
|
||||
{% include "flatpages/admin_link.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{{ render_django(flatpage.content) }}
|
||||
{{ render_django(flatpage.content) }}
|
||||
{% endblock %}
|
|
@ -2,7 +2,7 @@
|
|||
{% block title %}{{ flatpage.title }} - {{ SITE_LONG_NAME }}{% endblock %}
|
||||
|
||||
{% block og_title %}
|
||||
<meta property="og:title" content="{{ flatpage.title }} - {{ SITE_LONG_NAME }}">
|
||||
<meta property="og:title" content="{{ flatpage.title }} - {{ SITE_LONG_NAME }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content_title %}{{ flatpage.title }}{% endblock %}
|
||||
|
@ -10,5 +10,5 @@
|
|||
{% block header %}{% include "flatpages/admin_link.html" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="content-description">{{ flatpage.content|markdown|reference|str|safe }}</div>
|
||||
<div class="content-description">{{ flatpage.content|markdown|reference|str|safe }}</div>
|
||||
{% endblock %}
|
|
@ -1,9 +1,9 @@
|
|||
{% extends "flatpages/markdown.html" %}
|
||||
|
||||
{% block body %}
|
||||
<div class="content-description">{{ flatpage.content|markdown|reference }}</div>
|
||||
<div class="content-description">{{ flatpage.content|markdown|reference }}</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyend %}
|
||||
{% if REQUIRE_JAX %}{% include "mathjax-load.html" %}{% endif %}
|
||||
{% if REQUIRE_JAX %}{% include "mathjax-load.html" %}{% endif %}
|
||||
{% endblock %}
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h3>{{ message }}</h3>
|
||||
<h3>{{ message }}</h3>
|
||||
{% endblock %}
|
|
@ -1,23 +1,23 @@
|
|||
{% extends "blog/list.html" %}
|
||||
{% block before_posts %}
|
||||
{% if i18n_config.home_page_top %}
|
||||
{{ render_django(i18n_config.home_page_top, request=request, user_count=user_count, problem_count=problem_count, submission_count=submission_count, language_count=language_count, perms=perms) }}
|
||||
{% endif %}
|
||||
{% if i18n_config.home_page_top %}
|
||||
{{ render_django(i18n_config.home_page_top, request=request, user_count=user_count, problem_count=problem_count, submission_count=submission_count, language_count=language_count, perms=perms) }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block meta %}
|
||||
{% if i18n_config.meta_description %}
|
||||
<meta name="description" content="{{ i18n_config['meta_description'] }}">
|
||||
{% endif %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"url": "{{ DMOJ_SCHEME }}://{{ site.domain }}/",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "{{ DMOJ_SCHEME }}://{{ site.domain }}/problems/?search={search_term_string}",
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% if i18n_config.meta_description %}
|
||||
<meta name="description" content="{{ i18n_config['meta_description'] }}">
|
||||
{% endif %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"url": "{{ DMOJ_SCHEME }}://{{ site.domain }}/",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "{{ DMOJ_SCHEME }}://{{ site.domain }}/problems/?search={search_term_string}",
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
{% extends "three-column-content.html" %}
|
||||
{% block three_col_media %}
|
||||
<style>
|
||||
.middle-content {
|
||||
max-width: 50%;
|
||||
}
|
||||
ol {
|
||||
padding-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.middle-content {
|
||||
max-width: 50%;
|
||||
}
|
||||
ol {
|
||||
padding-left: 1em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_js %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('.vote-detail').each(function() {
|
||||
$(this).on('click', function() {
|
||||
var pid = $(this).attr('pid');
|
||||
$('.detail').hide();
|
||||
$('#detail-'+pid).show();
|
||||
})
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('.vote-detail').each(function() {
|
||||
$(this).on('click', function() {
|
||||
var pid = $(this).attr('pid');
|
||||
$('.detail').hide();
|
||||
$('#detail-'+pid).show();
|
||||
})
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('problem', 'fa fa-list', url('internal_problem'), _('Problem')) }}
|
||||
</div>
|
||||
<div class="left-sidebar">
|
||||
{{ make_tab_item('problem', 'fa fa-list', url('internal_problem'), _('Problem')) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{_('Problem')}}</th>
|
||||
<th>{{_('Code')}}</th>
|
||||
<th>{{_('Vote count')}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem in problems %}
|
||||
<tr>
|
||||
<td><a href="{{url('problem_detail', problem.code)}}">{{problem.name}}</a></td>
|
||||
<td><a href="{{url('admin:judge_problem_change', problem.id)}}">{{problem.code}}</a></td>
|
||||
<td><a href="#" class="vote-detail" pid="{{problem.id}}">{{problem.vote_count}}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if page_obj.num_pages > 1 %}
|
||||
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
|
||||
{% endif %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{_('Problem')}}</th>
|
||||
<th>{{_('Code')}}</th>
|
||||
<th>{{_('Vote count')}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for problem in problems %}
|
||||
<tr>
|
||||
<td><a href="{{url('problem_detail', problem.code)}}">{{problem.name}}</a></td>
|
||||
<td><a href="{{url('admin:judge_problem_change', problem.id)}}">{{problem.code}}</a></td>
|
||||
<td><a href="#" class="vote-detail" pid="{{problem.id}}">{{problem.vote_count}}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if page_obj.num_pages > 1 %}
|
||||
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block right_sidebar %}
|
||||
<div style="display: block; width: 100%">
|
||||
<div style="display: block; width: 100%">
|
||||
<div><a href="{{url('admin:judge_volunteerproblemvote_changelist')}}">{{_('Admin')}}</a></div>
|
||||
{% for problem in problems %}
|
||||
<div class="detail" id="detail-{{problem.id}}" style="display: none;">
|
||||
<h3>{{_('Votes for problem') }} {{problem.name}}</h3>
|
||||
<ol>
|
||||
{% for vote in problem.volunteer_user_votes.order_by('id') %}
|
||||
<li>
|
||||
<h4> {{link_user(vote.voter)}} </h4>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:10%">{{_('Knowledge')}}</td>
|
||||
<td>{{vote.knowledge_points}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Thinking')}}</td>
|
||||
<td>{{vote.thinking_points}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Types')}}</td>
|
||||
<td>{{vote.types.all() | join(', ')}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Feedback')}}</td>
|
||||
<td>{{vote.feedback}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="detail" id="detail-{{problem.id}}" style="display: none;">
|
||||
<h3>{{_('Votes for problem') }} {{problem.name}}</h3>
|
||||
<ol>
|
||||
{% for vote in problem.volunteer_user_votes.order_by('id') %}
|
||||
<li>
|
||||
<h4> {{link_user(vote.voter)}} </h4>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:10%">{{_('Knowledge')}}</td>
|
||||
<td>{{vote.knowledge_points}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Thinking')}}</td>
|
||||
<td>{{vote.thinking_points}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Types')}}</td>
|
||||
<td>{{vote.types.all() | join(', ')}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{_('Feedback')}}</td>
|
||||
<td>{{vote.feedback}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -1,13 +1,13 @@
|
|||
{% extends "common-content.html" %}
|
||||
{% block description %}
|
||||
{% cache 3600 'license_html' license.id %}
|
||||
{{ license.text|markdown }}
|
||||
{% endcache %}
|
||||
{% cache 3600 'license_html' license.id %}
|
||||
{{ license.text|markdown }}
|
||||
{% endcache %}
|
||||
{% endblock %}
|
||||
|
||||
{% block info_float %}
|
||||
{% if perms.judge.change_license %}
|
||||
<div><a href="{{ url('admin:judge_license_change', license.id) }}">{{ _('Edit') }}</a></div>
|
||||
{% endif %}
|
||||
<div><b>{{ _('Source:') }}</b> <a href="{{ license.link }}">{{ license.link }}</a></div>
|
||||
{% if perms.judge.change_license %}
|
||||
<div><a href="{{ url('admin:judge_license_change', license.id) }}">{{ _('Edit') }}</a></div>
|
||||
{% endif %}
|
||||
<div><b>{{ _('Source:') }}</b> <a href="{{ license.link }}">{{ license.link }}</a></div>
|
||||
{% endblock %}
|
|
@ -1,31 +1,31 @@
|
|||
<ul class="pagination">
|
||||
{% if page_obj.has_previous() %}
|
||||
{% if page_obj.previous_page_number() == 1 and first_page_href != None %}
|
||||
<li><a href="{{ first_page_href }}">«</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ page_prefix or '' }}{{ page_obj.previous_page_number() }}{{ page_suffix or '' }}">«</a></li>
|
||||
{% endif %}
|
||||
{% if page_obj.has_previous() %}
|
||||
{% if page_obj.previous_page_number() == 1 and first_page_href != None %}
|
||||
<li><a href="{{ first_page_href }}">«</a></li>
|
||||
{% else %}
|
||||
<li class="disabled-page"><span>«</span></li>
|
||||
<li><a href="{{ page_prefix or '' }}{{ page_obj.previous_page_number() }}{{ page_suffix or '' }}">«</a></li>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<li class="disabled-page"><span>«</span></li>
|
||||
{% endif %}
|
||||
|
||||
{% for page in page_obj.page_range %}
|
||||
{% if not page %}
|
||||
<li class="disabled-page"><span>...</span></li>
|
||||
{% else %}
|
||||
<li{% if page == page_obj.number %} class="active-page"{% endif %}><a href="
|
||||
{%- if page == 1 and first_page_href != None -%}
|
||||
{{ first_page_href }}
|
||||
{%- else -%}
|
||||
{{ page_prefix or '' }}{{ page }}{{ page_suffix or '' }}
|
||||
{%- endif -%}
|
||||
">{{ page }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next() %}
|
||||
<li><a href="{{ page_prefix or '' }}{{ page_obj.next_page_number() }}{{ page_suffix or '' }}">»</a></li>
|
||||
{% for page in page_obj.page_range %}
|
||||
{% if not page %}
|
||||
<li class="disabled-page"><span>...</span></li>
|
||||
{% else %}
|
||||
<li class="disabled-page"><span>»</span></li>
|
||||
<li{% if page == page_obj.number %} class="active-page"{% endif %}><a href="
|
||||
{%- if page == 1 and first_page_href != None -%}
|
||||
{{ first_page_href }}
|
||||
{%- else -%}
|
||||
{{ page_prefix or '' }}{{ page }}{{ page_suffix or '' }}
|
||||
{%- endif -%}
|
||||
">{{ page }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next() %}
|
||||
<li><a href="{{ page_prefix or '' }}{{ page_obj.next_page_number() }}{{ page_suffix or '' }}">»</a></li>
|
||||
{% else %}
|
||||
<li class="disabled-page"><span>»</span></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% if messages %}
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li class="{{ message.tags }}">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<ul class="messages">
|
||||
{% for message in messages %}
|
||||
<li class="{{ message.tags }}">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
|
|
@ -2,47 +2,47 @@
|
|||
|
||||
{% block body %}
|
||||
|
||||
{% if not has_notifications %}
|
||||
{% if not has_notifications %}
|
||||
|
||||
<h2 style="text-align: center;">{{ _('You have no notifications') }}</h2>
|
||||
<h2 style="text-align: center;">{{ _('You have no notifications') }}</h2>
|
||||
|
||||
{% else %}
|
||||
{% else %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<tr>
|
||||
<th>{{ _('User') }}</th>
|
||||
<th>{{ _('Activity') }}</th>
|
||||
<th>{{ _('Link') }}</th>
|
||||
<th>{{ _('Time') }}</th>
|
||||
</tr>
|
||||
{% for notification in notifications %}
|
||||
<tr class="{{ 'highlight' if not notification.seen }}">
|
||||
<td>
|
||||
</tr>
|
||||
{% for notification in notifications %}
|
||||
<tr class="{{ 'highlight' if not notification.seen }}">
|
||||
<td>
|
||||
{% if notification.comment %}
|
||||
{{ link_user(notification.comment.author) }}
|
||||
{{ link_user(notification.comment.author) }}
|
||||
{% else %}
|
||||
{{ link_user(notification.author) }}
|
||||
{{ link_user(notification.author) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
{{ notification.category }}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
{% if notification.comment %}
|
||||
<a href="{{ notification.comment.link }}#comment-{{ notification.comment.id }}">{{ page_titles[notification.comment.page] }}</a>
|
||||
<a href="{{ notification.comment.link }}#comment-{{ notification.comment.id }}">{{ page_titles[notification.comment.page] }}</a>
|
||||
{% else %}
|
||||
{% autoescape off %}
|
||||
{{notification.html_link}}
|
||||
{% endautoescape %}
|
||||
{% autoescape off %}
|
||||
{{notification.html_link}}
|
||||
{% endautoescape %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
{{ relative_time(notification.time) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block org_js %}
|
||||
{{ form.media.js }}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% include "organization/form.html" %}
|
||||
{% include "organization/form.html" %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
{% extends "two-column-content.html" %}
|
||||
|
||||
{% block two_col_js %}
|
||||
{{ form.media.js }}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block two_col_media %}
|
||||
{{ form.media.css }}
|
||||
{{ form.media.css }}
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "user/user-left-sidebar.html" %}
|
||||
{% include "user/user-left-sidebar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<center><h2>{{title}}</h2></center>
|
||||
{% include "organization/form.html" %}
|
||||
<center><h2>{{title}}</h2></center>
|
||||
{% include "organization/form.html" %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{{ form.media.js }}
|
||||
{% include "organization/home-js.html" %}
|
||||
{{ form.media.js }}
|
||||
{% include "organization/home-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{{ form.media.css }}
|
||||
{{ form.media.css }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% include "organization/form.html" %}
|
||||
{% include "organization/form.html" %}
|
||||
{% endblock %}
|
|
@ -1,39 +1,39 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{{ form.media.js }}
|
||||
{% include "organization/home-js.html" %}
|
||||
{{ form.media.js }}
|
||||
{% include "organization/home-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{{ form.media.css }}
|
||||
{{ form.media.css }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<form action="" method="post">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span style="color:red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span style="color:red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<button type="submit" style="display: inline;" name="action" value="Save" >{{ _('Save') }} </button>
|
||||
<button type="submit" style="background-color: red; float: right;" name="action" value="Delete" > {{ _('Delete') }} </button>
|
||||
</form>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,28 +1,28 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block middle_content %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
{{_('Blog')}}
|
||||
</th>
|
||||
<th>
|
||||
{{_('Author')}}
|
||||
</th>
|
||||
<th>
|
||||
{{_('Post time')}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for blog in blogs %}
|
||||
<tr>
|
||||
<td><a href="{{url('edit_organization_blog', organization.id, organization.slug, blog.id)}}">{{blog.title}}</a></td>
|
||||
<td>{{link_users(blog.authors.all())}}</td>
|
||||
<td>{{- blog.publish_on|date(_("N j, Y, g:i a")) -}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
{{_('Blog')}}
|
||||
</th>
|
||||
<th>
|
||||
{{_('Author')}}
|
||||
</th>
|
||||
<th>
|
||||
{{_('Post time')}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for blog in blogs %}
|
||||
<tr>
|
||||
<td><a href="{{url('edit_organization_blog', organization.id, organization.slug, blog.id)}}">{{blog.title}}</a></td>
|
||||
<td>{{link_users(blog.authors.all())}}</td>
|
||||
<td>{{- blog.publish_on|date(_("N j, Y, g:i a")) -}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -1,38 +1,38 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{{ form.media.js }}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{{ form.media.css }}
|
||||
{{ form.media.css }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<button type="submit">{{ _('Save') }}</button>
|
||||
</form>
|
||||
<button type="submit">{{ _('Save') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,88 +1,88 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{{ form.media.js }}
|
||||
{{ form.media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{{ form.media.css }}
|
||||
<style>
|
||||
#org-field-wrapper-scoreboard_visibility,
|
||||
#org-field-wrapper-points_precision,
|
||||
#org-field-wrapper-start_time,
|
||||
#org-field-wrapper-end_time,
|
||||
#org-field-wrapper-time_limit,
|
||||
#org-field-wrapper-format_name {
|
||||
display: inline-flex;
|
||||
}
|
||||
.problems-problem {
|
||||
width: 40%;
|
||||
}
|
||||
input[type=number] {
|
||||
width: 5em;
|
||||
}
|
||||
.middle-content {
|
||||
z-index: 1;
|
||||
}
|
||||
#three-col-container {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
{{ form.media.css }}
|
||||
<style>
|
||||
#org-field-wrapper-scoreboard_visibility,
|
||||
#org-field-wrapper-points_precision,
|
||||
#org-field-wrapper-start_time,
|
||||
#org-field-wrapper-end_time,
|
||||
#org-field-wrapper-time_limit,
|
||||
#org-field-wrapper-format_name {
|
||||
display: inline-flex;
|
||||
}
|
||||
.problems-problem {
|
||||
width: 40%;
|
||||
}
|
||||
input[type=number] {
|
||||
width: 5em;
|
||||
}
|
||||
.middle-content {
|
||||
z-index: 1;
|
||||
}
|
||||
#three-col-container {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<hr><br>
|
||||
{{ problems_form.management_form }}
|
||||
<i>{{_('If you run out of rows, click Save')}}</i>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for field in problems_form[0] %}
|
||||
{% if not field.is_hidden %}
|
||||
<th>
|
||||
{{field.label}}
|
||||
</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in problems_form %}
|
||||
<tr>
|
||||
{% for field in form %}
|
||||
<td class="problems-{{field.name}}" title="
|
||||
{{ field.help_text|safe if field.help_text }}"
|
||||
style="{{ 'display:none' if field.is_hidden }}"
|
||||
>{{field}}<div class="red">{{field.errors}}</div></td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
<hr><br>
|
||||
{{ problems_form.management_form }}
|
||||
<i>{{_('If you run out of rows, click Save')}}</i>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for field in problems_form[0] %}
|
||||
{% if not field.is_hidden %}
|
||||
<th>
|
||||
{{field.label}}
|
||||
</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in problems_form %}
|
||||
<tr>
|
||||
{% for field in form %}
|
||||
<td class="problems-{{field.name}}" title="
|
||||
{{ field.help_text|safe if field.help_text }}"
|
||||
style="{{ 'display:none' if field.is_hidden }}"
|
||||
>{{field}}<div class="red">{{field.errors}}</div></td>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit">{{ _('Save') }}</button>
|
||||
</form>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit">{{ _('Save') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "contest/list.html" %}
|
||||
{% block left_sidebar %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% endblock %}
|
|
@ -1,36 +1,36 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block org_js %}
|
||||
{{ form.media.js }}
|
||||
<script type="text/javascript">
|
||||
window.django = {jQuery: $};
|
||||
{{ form.media.js }}
|
||||
<script type="text/javascript">
|
||||
window.django = {jQuery: $};
|
||||
|
||||
function pluralidx(count) {
|
||||
return (count == 1) ? 0 : 1;
|
||||
}
|
||||
function pluralidx(count) {
|
||||
return (count == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
function gettext(msgid) {
|
||||
return msgid;
|
||||
}
|
||||
function gettext(msgid) {
|
||||
return msgid;
|
||||
}
|
||||
|
||||
function interpolate(fmt, obj, named) {
|
||||
if (named) {
|
||||
return fmt.replace(/%\(\w+\)s/g, function (match) {
|
||||
return String(obj[match.slice(2, -2)])
|
||||
});
|
||||
} else {
|
||||
return fmt.replace(/%s/g, function (match) {
|
||||
return String(obj.shift())
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
function interpolate(fmt, obj, named) {
|
||||
if (named) {
|
||||
return fmt.replace(/%\(\w+\)s/g, function (match) {
|
||||
return String(obj[match.slice(2, -2)])
|
||||
});
|
||||
} else {
|
||||
return fmt.replace(/%s/g, function (match) {
|
||||
return String(obj.shift())
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{{ form.media.css }}
|
||||
{{ form.media.css }}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% include "organization/form.html" %}
|
||||
{% include "organization/form.html" %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
{% csrf_token %}
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger alert-dismissable">
|
||||
<a href="#" class="close">x</a>
|
||||
{{ form.non_field_errors() }}
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for field in form %}
|
||||
{% if not field.is_hidden %}
|
||||
<div style="margin-bottom: 1em;">
|
||||
{{ field.errors }}
|
||||
<label for="{{field.id_for_label }}"><b>{{ field.label }}{% if field.field.required %}<span class="red"> * </span>{% endif %}:</b> </label>
|
||||
<div class="org-field-wrapper" id="org-field-wrapper-{{field.html_name }}">
|
||||
{{ field }}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if field.help_text %}
|
||||
<i style="display: block">{{ field.help_text|safe }}</i>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<button type="submit" style="display: inline;" name="action" value="Save" >{{ _('Save') }} </button>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<button type="submit" style="display: inline;" name="action" value="Save" >{{ _('Save') }} </button>
|
||||
</form>
|
|
@ -1,21 +1,21 @@
|
|||
{% extends "three-column-content.html" %}
|
||||
|
||||
{% block three_col_js %}
|
||||
{% include "organization/home-js.html" %}
|
||||
{% block org_js %}{% endblock %}
|
||||
{% include "organization/home-js.html" %}
|
||||
{% block org_js %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block right_sidebar %}
|
||||
{% include "organization/org-right-sidebar.html" %}
|
||||
{% include "organization/org-right-sidebar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_title %}
|
||||
{% if title or content_title %}
|
||||
<center><h2>{{ content_title if content_title else title }}</h2></center>
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% if title or content_title %}
|
||||
<center><h2>{{ content_title if content_title else title }}</h2></center>
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
$('.leave-organization').click(function () {
|
||||
if (confirm('{{ _('Are you sure you want to leave this organization?') }}\n' +
|
||||
{% if organization.is_open %}
|
||||
'{{ _('You will have to rejoin to show up on the organization leaderboard.') }}'
|
||||
{% else %}
|
||||
'{{ _('You will have to request membership in order to join again.') }}'
|
||||
{% endif %}
|
||||
)) {
|
||||
$(this).parent().submit();
|
||||
}
|
||||
});
|
||||
|
||||
$('#control-panel a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
navigateTo($(this));
|
||||
})
|
||||
$(function () {
|
||||
$('.time-remaining').each(function () {
|
||||
count_down($(this));
|
||||
});
|
||||
$('.leave-organization').click(function () {
|
||||
if (confirm('{{ _('Are you sure you want to leave this organization?') }}\n' +
|
||||
{% if organization.is_open %}
|
||||
'{{ _('You will have to rejoin to show up on the organization leaderboard.') }}'
|
||||
{% else %}
|
||||
'{{ _('You will have to request membership in order to join again.') }}'
|
||||
{% endif %}
|
||||
)) {
|
||||
$(this).parent().submit();
|
||||
}
|
||||
});
|
||||
|
||||
$('#control-panel a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
navigateTo($(this));
|
||||
})
|
||||
});
|
||||
</script>
|
|
@ -3,62 +3,62 @@
|
|||
{% block title_ruler %}{% endblock %}
|
||||
|
||||
{% block org_js %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% include "actionbar/media-js.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block three_col_media %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% include "actionbar/media-css.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_title %}
|
||||
<div class="page-title">
|
||||
<div class="tabs" style="border: none;">
|
||||
<h2><img src="{{logo_override_image}}" style="height: 3rem; vertical-align: middle">
|
||||
{{title}}
|
||||
</h2>
|
||||
{% if is_member %}
|
||||
<div>
|
||||
<a href="{{organization_subdomain}}" target="_blank">(Subdomain)</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<span class="spacer"></span>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if is_member %}
|
||||
{% elif organization.is_open or can_edit %}
|
||||
<form method="post" action="{{ url('join_organization', organization.id, organization.slug) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button" value="{{ _('Join') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="{{ url('request_organization', organization.id, organization.slug) }}"
|
||||
class="unselectable button">{{ _('Request membership') }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<div class="page-title">
|
||||
<div class="tabs" style="border: none;">
|
||||
<h2><img src="{{logo_override_image}}" style="height: 3rem; vertical-align: middle">
|
||||
{{title}}
|
||||
</h2>
|
||||
{% if is_member %}
|
||||
<div>
|
||||
<a href="{{organization_subdomain}}" target="_blank">(Subdomain)</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<span class="spacer"></span>
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if is_member %}
|
||||
{% elif organization.is_open or can_edit %}
|
||||
<form method="post" action="{{ url('join_organization', organization.id, organization.slug) }}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="unselectable button" value="{{ _('Join') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<a href="{{ url('request_organization', organization.id, organization.slug) }}"
|
||||
class="unselectable button">{{ _('Request membership') }}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% block before_posts %}{% endblock %}
|
||||
{% if is_member or can_edit %}
|
||||
{% for post in posts %}
|
||||
{% include "blog/content.html" %}
|
||||
{% endfor %}
|
||||
{% if posts.paginator.num_pages > 1 %}
|
||||
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('About') }}<i class="fa fa-info-circle"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
<div style="margin: 0.3em;">
|
||||
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
|
||||
{{ organization.about|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% block before_posts %}{% endblock %}
|
||||
{% if is_member or can_edit %}
|
||||
{% for post in posts %}
|
||||
{% include "blog/content.html" %}
|
||||
{% endfor %}
|
||||
{% if posts.paginator.num_pages > 1 %}
|
||||
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
|
||||
{% endif %}
|
||||
{% block after_posts %}{% endblock %}
|
||||
{% else %}
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('About') }}<i class="fa fa-info-circle"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
<div style="margin: 0.3em;">
|
||||
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
|
||||
{{ organization.about|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block after_posts %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
{% extends "two-column-content.html" %}
|
||||
|
||||
{% block two_col_media %}
|
||||
<style>
|
||||
.organization-container .organization-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
<style>
|
||||
.organization-container .organization-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.org-logo {
|
||||
vertical-align: middle;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
.org-logo {
|
||||
vertical-align: middle;
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
.toggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block title_ruler %}{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "user/user-left-sidebar.html" %}
|
||||
{% include "user/user-left-sidebar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% macro org_list(title, queryset) %}
|
||||
{% if queryset %}
|
||||
<h3 style="padding-bottom: 1em" class="toggle open"><i class="fa fa-chevron-right fa-fw"></i> {{title}} ({{queryset.count()}})</h3>
|
||||
<div class="organization-container toggled">
|
||||
{% for org in queryset %}
|
||||
<a href="{{ org.get_absolute_url() }}" class="organization-row" title="{{org.about}}">
|
||||
<img class="org-logo" data-src="{{ org.logo_override_image or static('icons/icon.png') }}">
|
||||
<span style="margin-right: auto">{{ org.name }}</span>
|
||||
<span style="font-weight: normal"><i>{{ org.member_count }} {{_('members')}}</i></span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if queryset %}
|
||||
<h3 style="padding-bottom: 1em" class="toggle open"><i class="fa fa-chevron-right fa-fw"></i> {{title}} ({{queryset.count()}})</h3>
|
||||
<div class="organization-container toggled">
|
||||
{% for org in queryset %}
|
||||
<a href="{{ org.get_absolute_url() }}" class="organization-row" title="{{org.about}}">
|
||||
<img class="org-logo" data-src="{{ org.logo_override_image or static('icons/icon.png') }}">
|
||||
<span style="margin-right: auto">{{ org.name }}</span>
|
||||
<span style="font-weight: normal"><i>{{ org.member_count }} {{_('members')}}</i></span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block middle_content %}
|
||||
<a style="float: right" class="button small" href="{{url('organization_add')}}">{{_("Create group")}}</a>
|
||||
{{ org_list(_('My groups'), my_organizations) }}
|
||||
{{ org_list(_('Open groups'), open_organizations) }}
|
||||
{{ org_list(_('Private groups'), private_organizations) }}
|
||||
<a style="float: right" class="button small" href="{{url('organization_add')}}">{{_("Create group")}}</a>
|
||||
{{ org_list(_('My groups'), my_organizations) }}
|
||||
{{ org_list(_('Open groups'), open_organizations) }}
|
||||
{{ org_list(_('Private groups'), private_organizations) }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
{% block media %}{{ form.media.css }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
<table border="0" style="text-align:left">{{ form.as_table() }}</table>
|
||||
<button type="submit">{{ _('Create') }}</button>
|
||||
</form>
|
||||
<form action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
<table border="0" style="text-align:left">{{ form.as_table() }}</table>
|
||||
<button type="submit">{{ _('Create') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,14 +1,14 @@
|
|||
<div class="left-sidebar">
|
||||
{{ make_tab_item('home', 'fa fa-home', organization.get_absolute_url(), _('Home')) }}
|
||||
{% if is_member or can_edit %}
|
||||
{{ make_tab_item('problems', 'fa fa-list', organization.get_problems_url(), _('Problems')) }}
|
||||
{{ make_tab_item('contests', 'fa fa-trophy', organization.get_contests_url(), _('Contests')) }}
|
||||
{{ make_tab_item('submissions', 'fa fa-book', organization.get_submissions_url(), _('Submissions')) }}
|
||||
{% endif %}
|
||||
{% if is_member or can_edit or organization.is_open %}
|
||||
{{ make_tab_item('users', 'fa fa-user', organization.get_users_url(), _('Members')) }}
|
||||
{% endif %}
|
||||
{% if perms.judge.change_organization %}
|
||||
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_organization_change', organization.id), _('Admin')) }}
|
||||
{% endif %}
|
||||
{{ make_tab_item('home', 'fa fa-home', organization.get_absolute_url(), _('Home')) }}
|
||||
{% if is_member or can_edit %}
|
||||
{{ make_tab_item('problems', 'fa fa-list', organization.get_problems_url(), _('Problems')) }}
|
||||
{{ make_tab_item('contests', 'fa fa-trophy', organization.get_contests_url(), _('Contests')) }}
|
||||
{{ make_tab_item('submissions', 'fa fa-book', organization.get_submissions_url(), _('Submissions')) }}
|
||||
{% endif %}
|
||||
{% if is_member or can_edit or organization.is_open %}
|
||||
{{ make_tab_item('users', 'fa fa-user', organization.get_users_url(), _('Members')) }}
|
||||
{% endif %}
|
||||
{% if perms.judge.change_organization %}
|
||||
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_organization_change', organization.id), _('Admin')) }}
|
||||
{% endif %}
|
||||
</div>
|
|
@ -1,83 +1,83 @@
|
|||
<div class="right-sidebar">
|
||||
{% if (is_member or can_edit) %}
|
||||
{% include 'contests-countdown.html' %}
|
||||
{% endif %}
|
||||
{% if can_edit or is_member %}
|
||||
<div id="control-panel" class="blog-sidebox sidebox no-dot-blog-sidebox">
|
||||
<h3>{{ _('Controls') }} <i class="fa fa-cog"></i></h3>
|
||||
<ul id="control-list" class="sidebox-content" style="padding: 1em;">
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('edit_organization', organization.id, organization.slug) }}">{{ _('Edit group') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if can_edit and not organization.is_open %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_requests_pending', organization.id, organization.slug) }}">{{ _('View requests') }}</a>
|
||||
{% if pending_count > 0 %}
|
||||
<span id="pending-count-box">
|
||||
{{pending_count}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('add_organization_member', organization.id, organization.slug) }}">{{ _('Add members') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_member %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('add_organization_blog', organization.id, organization.slug) }}">{{ _('Add blog') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_pending_blogs', organization.id, organization.slug) }}">{{ _('Pending blogs') }}</a>
|
||||
{% if pending_blog_count > 0 %}
|
||||
<span id="pending-count-box">
|
||||
{{pending_blog_count}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_contest_add', organization.id, organization.slug) }}">{{ _('Add contest') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_member and not can_edit %}
|
||||
<li>
|
||||
<form method="post" action="{{ url('leave_organization', organization.id, organization.slug) }}">
|
||||
{% csrf_token %}
|
||||
<a href="#" class="leave-organization">{{ _('Leave group') }}</a>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('About') }}<i class="fa fa-info-circle"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
<div style="margin: 0.3em;">
|
||||
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
|
||||
{{ organization.about|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% if (is_member or can_edit) %}
|
||||
{% include 'contests-countdown.html' %}
|
||||
{% endif %}
|
||||
{% if can_edit or is_member %}
|
||||
<div id="control-panel" class="blog-sidebox sidebox no-dot-blog-sidebox">
|
||||
<h3>{{ _('Controls') }} <i class="fa fa-cog"></i></h3>
|
||||
<ul id="control-list" class="sidebox-content" style="padding: 1em;">
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('edit_organization', organization.id, organization.slug) }}">{{ _('Edit group') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if can_edit and not organization.is_open %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_requests_pending', organization.id, organization.slug) }}">{{ _('View requests') }}</a>
|
||||
{% if pending_count > 0 %}
|
||||
<span id="pending-count-box">
|
||||
{{pending_count}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('add_organization_member', organization.id, organization.slug) }}">{{ _('Add members') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_member %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('add_organization_blog', organization.id, organization.slug) }}">{{ _('Add blog') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_pending_blogs', organization.id, organization.slug) }}">{{ _('Pending blogs') }}</a>
|
||||
{% if pending_blog_count > 0 %}
|
||||
<span id="pending-count-box">
|
||||
{{pending_blog_count}}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% if can_edit %}
|
||||
<li>
|
||||
<div>
|
||||
<a href="{{ url('organization_contest_add', organization.id, organization.slug) }}">{{ _('Add contest') }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_member and not can_edit %}
|
||||
<li>
|
||||
<form method="post" action="{{ url('leave_organization', organization.id, organization.slug) }}">
|
||||
{% csrf_token %}
|
||||
<a href="#" class="leave-organization">{{ _('Leave group') }}</a>
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="blog-sidebox sidebox">
|
||||
<h3>{{ _('About') }}<i class="fa fa-info-circle"></i></h3>
|
||||
<div class="sidebox-content">
|
||||
<div style="margin: 0.3em;">
|
||||
{% cache 3600 'organization_html' organization.id MATH_ENGINE %}
|
||||
{{ organization.about|markdown|reference|str|safe }}
|
||||
{% endcache %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_member or can_edit or organization.is_open %}
|
||||
{% include 'top-users.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_member or can_edit or organization.is_open %}
|
||||
{% include 'top-users.html' %}
|
||||
{% endif %}
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
{{ preview_data|markdown|reference|str|safe }}
|
||||
{% if REQUIRE_JAX %}
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
<div data-config="{{ static('mathjax3_config.js') }}" class="require-mathjax-support"></div>
|
||||
{% endif %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "problem/list.html" %}
|
||||
{% block left_sidebar %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% endblock %}
|
|
@ -1,26 +1,26 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block middle_content %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User:') }}</th>
|
||||
<td>{{ link_user(object.user) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Organization:') }}</th>
|
||||
<td>
|
||||
{% with org=object.organization %}
|
||||
<a href="{{ org.get_absolute_url() }}">{{ org.name }}</a>
|
||||
{% endwith %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Time:') }}</th>
|
||||
<td>{{ object.time|date(_("N j, Y, g:i a")) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Reason:') }}</th>
|
||||
<td>{{ object.reason }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User:') }}</th>
|
||||
<td>{{ link_user(object.user) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Organization:') }}</th>
|
||||
<td>
|
||||
{% with org=object.organization %}
|
||||
<a href="{{ org.get_absolute_url() }}">{{ org.name }}</a>
|
||||
{% endwith %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Time:') }}</th>
|
||||
<td>{{ object.time|date(_("N j, Y, g:i a")) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ _('Reason:') }}</th>
|
||||
<td>{{ object.reason }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -1,30 +1,30 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block middle_content %}
|
||||
{% include "organization/requests/tabs.html" %}
|
||||
{% include "organization/requests/tabs.html" %}
|
||||
|
||||
{% if requests %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User') }}</th>
|
||||
<th>{{ _('Time') }}</th>
|
||||
<th>{{ _('State') }}</th>
|
||||
<th>{{ _('Reason') }}</th>
|
||||
</tr>
|
||||
{% for r in requests %}
|
||||
<tr id="request-{{ r.id }}">
|
||||
<td>{{ link_user(r.user) }}</td>
|
||||
<td>
|
||||
<a href="{{ url('request_organization_detail', object.id, object.slug, r.id) }}">
|
||||
{{- r.time|date(_("N j, Y, g:i a")) -}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ r.state }}</td>
|
||||
<td>{{ r.reason|truncatechars(50) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{{ _('There are no requests to approve.') }}</p>
|
||||
{% endif %}
|
||||
{% if requests %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User') }}</th>
|
||||
<th>{{ _('Time') }}</th>
|
||||
<th>{{ _('State') }}</th>
|
||||
<th>{{ _('Reason') }}</th>
|
||||
</tr>
|
||||
{% for r in requests %}
|
||||
<tr id="request-{{ r.id }}">
|
||||
<td>{{ link_user(r.user) }}</td>
|
||||
<td>
|
||||
<a href="{{ url('request_organization_detail', object.id, object.slug, r.id) }}">
|
||||
{{- r.time|date(_("N j, Y, g:i a")) -}}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ r.state }}</td>
|
||||
<td>{{ r.reason|truncatechars(50) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{{ _('There are no requests to approve.') }}</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
{% block org_js %}
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("select").select2();
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("select").select2();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block middle_content %}
|
||||
{% include "messages.html" %}
|
||||
{% include "organization/requests/tabs.html" %}
|
||||
{% include "messages.html" %}
|
||||
{% include "organization/requests/tabs.html" %}
|
||||
|
||||
{% if formset.forms %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User') }}</th>
|
||||
<th>{{ _('Time') }}</th>
|
||||
<th>{{ _('State') }}</th>
|
||||
<th>{{ _('Reason') }}</th>
|
||||
{% if formset.can_delete %}
|
||||
<th>{{ _('Delete?') }}</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for form in formset %}
|
||||
<tr id="request-{{ form.instance.id }}">
|
||||
<td>{{ form.id }}{{ link_user(form.instance.user) }}</td>
|
||||
<td><a href="{{ url('request_organization_detail', object.id, object.slug, form.instance.id) }}">
|
||||
{{ form.instance.time|date(_("N j, Y, g:i a")) }}
|
||||
</a></td>
|
||||
<td>{{ form.state }}</td>
|
||||
<td>{{ form.instance.reason|truncatechars(50) }}</td>
|
||||
{% if formset.can_delete %}
|
||||
<td>{{ form.DELETE }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<button type="submit">{{ _('Update') }}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>{{ _('There are no requests to approve.') }}</p>
|
||||
{% endif %}
|
||||
{% if formset.forms %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ _('User') }}</th>
|
||||
<th>{{ _('Time') }}</th>
|
||||
<th>{{ _('State') }}</th>
|
||||
<th>{{ _('Reason') }}</th>
|
||||
{% if formset.can_delete %}
|
||||
<th>{{ _('Delete?') }}</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for form in formset %}
|
||||
<tr id="request-{{ form.instance.id }}">
|
||||
<td>{{ form.id }}{{ link_user(form.instance.user) }}</td>
|
||||
<td><a href="{{ url('request_organization_detail', object.id, object.slug, form.instance.id) }}">
|
||||
{{ form.instance.time|date(_("N j, Y, g:i a")) }}
|
||||
</a></td>
|
||||
<td>{{ form.state }}</td>
|
||||
<td>{{ form.instance.reason|truncatechars(50) }}</td>
|
||||
{% if formset.can_delete %}
|
||||
<td>{{ form.DELETE }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<button type="submit">{{ _('Update') }}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>{{ _('There are no requests to approve.') }}</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,22 +1,22 @@
|
|||
{% extends "organization/home-base.html" %}
|
||||
|
||||
{% block org_js %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#id_reason').keydown(function (e) {
|
||||
if (e.ctrlKey && (e.keyCode === 13 || e.keyCode === 10)) {
|
||||
$(this).closest('form').submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#id_reason').keydown(function (e) {
|
||||
if (e.ctrlKey && (e.keyCode === 13 || e.keyCode === 10)) {
|
||||
$(this).closest('form').submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block middle_content %}
|
||||
<form action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
<p><label for="{{ form.reason.id_for_label }}"><b>{{ _('Your reason for joining:') }}</b></label></p>
|
||||
<p>{{ form.reason }}</p>
|
||||
<button type="submit">{{ _('Request') }}</button>
|
||||
</form>
|
||||
<form action="" method="post" class="form-area">
|
||||
{% csrf_token %}
|
||||
<p><label for="{{ form.reason.id_for_label }}"><b>{{ _('Your reason for joining:') }}</b></label></p>
|
||||
<p>{{ form.reason }}</p>
|
||||
<button type="submit">{{ _('Request') }}</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<div class="tabs">
|
||||
<ul>
|
||||
<li{% if tab == 'pending' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_pending', object.id, object.slug) }}">{{ _('Pending') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'log' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_log', object.id, object.slug) }}">{{ _('Log') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'approved' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_approved', object.id, object.slug) }}">{{ _('Approved') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'rejected' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_rejected', object.id, object.slug) }}">{{ _('Rejected') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li{% if tab == 'pending' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_pending', object.id, object.slug) }}">{{ _('Pending') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'log' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_log', object.id, object.slug) }}">{{ _('Log') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'approved' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_approved', object.id, object.slug) }}">{{ _('Approved') }}</a>
|
||||
</li>
|
||||
<li{% if tab == 'rejected' %} class="active"{% endif %}>
|
||||
<a href="{{ url('organization_requests_rejected', object.id, object.slug) }}">{{ _('Rejected') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "submission/list.html" %}
|
||||
{% block left_sidebar %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% endblock %}
|
|
@ -1,19 +1,19 @@
|
|||
{% extends "user/users-table.html" %}
|
||||
|
||||
{% block before_point_head %}
|
||||
{% if can_edit %}
|
||||
<th class="header"></th>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<th class="header"></th>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block before_point %}
|
||||
{% if can_edit %}
|
||||
<td>
|
||||
<form action="{{ kick_url }}" method="POST" class="kick-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ user.id }}">
|
||||
<a href="#" class="button small">{{ _('Kick') }}</a>
|
||||
</form>
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<td>
|
||||
<form action="{{ kick_url }}" method="POST" class="kick-form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="user" value="{{ user.id }}">
|
||||
<a href="#" class="button small">{{ _('Kick') }}</a>
|
||||
</form>
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
{% extends "user/base-users-two-col.html" %}
|
||||
{% block users_media %}
|
||||
<style>
|
||||
.kick-form .button {
|
||||
margin: -8px 0;
|
||||
padding: 3px 12px;
|
||||
}
|
||||
#users-table td:nth-child(3), #users-table th:nth-child(3) {
|
||||
text-align: left;
|
||||
}
|
||||
#users-table td:nth-child(2), #users-table th:nth-child(2) {
|
||||
border-right: none;
|
||||
}
|
||||
.rank-td {
|
||||
font-family: "Jersey M54";
|
||||
font-size: large;
|
||||
}
|
||||
.user-points, .user-problem-count, .rating-td {
|
||||
font-family: cursive;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.kick-form .button {
|
||||
margin: -8px 0;
|
||||
padding: 3px 12px;
|
||||
}
|
||||
#users-table td:nth-child(3), #users-table th:nth-child(3) {
|
||||
text-align: left;
|
||||
}
|
||||
#users-table td:nth-child(2), #users-table th:nth-child(2) {
|
||||
border-right: none;
|
||||
}
|
||||
.rank-td {
|
||||
font-family: "Jersey M54";
|
||||
font-size: large;
|
||||
}
|
||||
.user-points, .user-problem-count, .rating-td {
|
||||
font-family: cursive;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% if can_edit %}
|
||||
<style>#users-table td:nth-child(3), #users-table th:nth-child(3) {
|
||||
border-right: none;
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<style>#users-table td:nth-child(3), #users-table th:nth-child(3) {
|
||||
border-right: none;
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block users_js_media %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('form.kick-form').find('a.button').click(function () {
|
||||
$(this).parent().submit();
|
||||
return false;
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('form.kick-form').find('a.button').click(function () {
|
||||
$(this).parent().submit();
|
||||
return false;
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block left_sidebar %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% include "organization/org-left-sidebar.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block users_table %}{% include "organization/users-table.html" %}{% endblock %}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
<div class="wmd-wrapper {% if image_upload_enabled %}image-upload-enabled{% endif %}">
|
||||
<div class="wmd-panel">
|
||||
<div id="wmd-button-bar-{{ postfix }}"></div>
|
||||
<textarea id="wmd-input-{{ postfix }}" {{ attrs|safe }}>{{ body }}</textarea>
|
||||
<div class="wmd-panel">
|
||||
<div id="wmd-button-bar-{{ postfix }}"></div>
|
||||
<textarea id="wmd-input-{{ postfix }}" {{ attrs|safe }}>{{ body }}</textarea>
|
||||
</div>
|
||||
{% if show_preview %}
|
||||
<div id="{{ postfix|safe }}-preview" data-preview-url="{{ preview_url }}" data-textarea-id="wmd-input-{{ postfix }}"
|
||||
data-timeout="{{ preview_timeout or '' }}" class="wmd-panel wmd-preview dmmd-preview {{ extra_classes }}">
|
||||
<div class="dmmd-preview-update"><i class="fa fa-refresh"></i> Update Preview</div>
|
||||
<div class="dmmd-preview-content content-description"></div>
|
||||
</div>
|
||||
{% if show_preview %}
|
||||
<div id="{{ postfix|safe }}-preview" data-preview-url="{{ preview_url }}" data-textarea-id="wmd-input-{{ postfix }}"
|
||||
data-timeout="{{ preview_timeout or '' }}" class="wmd-panel wmd-preview dmmd-preview {{ extra_classes }}">
|
||||
<div class="dmmd-preview-update"><i class="fa fa-refresh"></i> Update Preview</div>
|
||||
<div class="dmmd-preview-content content-description"></div>
|
||||
{% endif %}
|
||||
{% if image_upload_enabled %}
|
||||
<div class="pagedown-image-upload">
|
||||
<h2>Insert Image</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="label">From the web</label>
|
||||
<input class="url-input" type="text" placeholder="http://" />
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if image_upload_enabled %}
|
||||
<div class="pagedown-image-upload">
|
||||
<h2>Insert Image</h2>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="label">From the web</label>
|
||||
<input class="url-input" type="text" placeholder="http://" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="label">From your computer</label>
|
||||
<input class="file-input" type="file" name="image" id="file" data-action="{{ url('pagedown-image-upload') }}" accept="image/*"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="submit-row">
|
||||
<div class="submit-loading"></div>
|
||||
<input class="submit-input show" type="submit" value="Save" name="_addanother">
|
||||
<p class="deletelink-box"><a href="#" class="close-image-upload deletelink">Cancel</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div>
|
||||
<label class="label">From your computer</label>
|
||||
<input class="file-input" type="file" name="image" id="file" data-action="{{ url('pagedown-image-upload') }}" accept="image/*"/>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="submit-row">
|
||||
<div class="submit-loading"></div>
|
||||
<input class="submit-input show" type="submit" value="Save" name="_addanother">
|
||||
<p class="deletelink-box"><a href="#" class="close-image-upload deletelink">Cancel</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
|
@ -1,9 +1,9 @@
|
|||
<div class="wmd-wrapper" id="{{ id }}-wmd-wrapper">
|
||||
<div class="wmd-panel">
|
||||
<div id="{{ id|safe }}_wmd_button_bar"></div>
|
||||
<textarea{{ attrs|safe }}>{{ body }}</textarea>
|
||||
</div>
|
||||
{% if show_preview %}
|
||||
<div id="{{ id|safe }}_wmd_preview" class="wmd-panel wmd-preview content-description"></div>
|
||||
{% endif %}
|
||||
<div class="wmd-panel">
|
||||
<div id="{{ id|safe }}_wmd_button_bar"></div>
|
||||
<textarea{{ attrs|safe }}>{{ body }}</textarea>
|
||||
</div>
|
||||
{% if show_preview %}
|
||||
<div id="{{ id|safe }}_wmd_preview" class="wmd-panel wmd-preview content-description"></div>
|
||||
{% endif %}
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue