This commit is contained in:
Lennart J. Kurzweg (Nx2)
2024-08-16 19:28:51 +02:00
commit 9d75757fec
20 changed files with 287594 additions and 0 deletions

1
app/.envrc Normal file
View File

@@ -0,0 +1 @@
use nix

5
app/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.venv
*/__pycache__/*
.direnv
.vscode

53
app/app.py Normal file
View File

@@ -0,0 +1,53 @@
from flask import Flask, render_template, jsonify, request
import random
import json
from res.name_cc import name_cc
def name_to_image_url(country_name: str) -> str:
try:
cc = name_cc[country_name]
except:
cc = None
if cc != None:
return f"https://gstatic.olympics.com/s1/f_auto/static/light/flag/paris-2024/olympic/3x2/{cc}.png"
else: return "https://gstatic.olympics.com/s1/f_auto/static/light/flag/paris-2024/olympic/3x2/EOR.png"
app = Flask(__name__)
# Load data from JSON file
with open('data/data.json') as f:
data = json.load(f)
# Route to display the game
@app.route('/')
def index():
return render_template('index.html')
# API to get a random discipline and participants
@app.route('/get_random_discipline', methods=['GET'])
def get_random_discipline():
discipline = random.choice(list(data.keys()))
category = random.choice(list(data[discipline].keys()))
participants = data[discipline][category]['participants']
# Prepare the data to send to the frontend
response = {
"participants": [
{
"country_name": participant["country"] if participant["country"] != "EOR" else "Équipe olympique des réfugiés",
"country_img_url": name_to_image_url(participant["country"]),
"athlete_name": participant.get("athlete", {}).get("name", None),
"athlete_img_url": participant.get("athlete", {}).get("image", None),
"athlete_meta_url": participant.get("athlete", {}).get("meta_url", None)
} for participant in participants
],
"answer": f"{discipline.capitalize()} {' '.join(category.split('-'))}"
}
return jsonify(response)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)

22545
app/data/data.json Normal file

File diff suppressed because it is too large Load Diff

1
app/requirements.txt Normal file
View File

@@ -0,0 +1 @@
flask

0
app/res/__init__.py Normal file
View File

128
app/res/name_cc.py Normal file
View File

@@ -0,0 +1,128 @@
name_cc = {
"Albania" : "ALB",
"Algeria" : "ALG",
"Argentina" : "ARG",
"Armenia" : "ARM",
"Australia" : "AUS",
"Austria" : "AUT",
"Azerbaijan" : "AZE",
"Bahamas" : "BAH",
"Bahrain" : "BHR",
"Bangladesh" : "BAN",
"Barbados" : "BAR",
"Belarus" : "BLR",
"Belgium" : "BEL",
"Bermuda" : "BMU",
"Bosnia & Herzegovina": "BIH",
"Botswana" : "BOT",
"Brazil" : "BRA",
"Bulgaria" : "BUL",
"Burkina Faso" : "BUR",
"Burundi" : "BUR",
"Cameroon" : "CMR",
"Canada" : "CAN",
"Chile" : "CHI",
"Chinese Taipei" : "TPE",
"Colombia" : "COL",
"Costa Rica" : "CRC",
"Côte d'Ivoire" : "CIV",
"Croatia" : "CRO",
"Cuba" : "CUB",
"Cyprus" : "CYP",
"Czechia" : "CZE",
"Denmark" : "DEN",
"Djibouti" : "DJI",
"Dominican Rep" : "DOM",
"Ecuador" : "ECU",
"Egypt" : "EGY",
"EOR" : "EOR",
"Eritrea" : "ERI",
"Estonia" : "EST",
"Ethiopia" : "ETH",
"Fiji" : "FIJ",
"Finland" : "FIN",
"France" : "FRA",
"Georgia" : "GEO",
"Germany" : "GER",
"Ghana" : "GHA",
"Great Britain" : "GBR",
"Greece" : "GRE",
"Grenada" : "GRN",
"Guatemala" : "GUA",
"Haiti" : "HAI",
"Hong Kong China" : "HKG",
"Hungary" : "HUN",
"India" : "IND",
"Indonesia" : "INA",
"Ireland" : "IRL",
"Isl Rep of Iran" : "IRI",
"Israel" : "ISR",
"Italy" : "ITA",
"Jamaica" : "JAM",
"Japan" : "JPN",
"Jordan" : "JOR",
"Kazakhstan" : "KAZ",
"Kenya" : "KEN",
"Korea" : "KOR",
"Kosovo" : "KOS",
"Kuwait" : "KUW",
"Kyrgyzstan" : "KGZ",
"Latvia" : "LAT",
"Lebanon" : "LBN",
"Liberia" : "LBR",
"Lithuania" : "LTU",
"Malaysia" : "MAS",
"Mauritius" : "MRI",
"Mexico" : "MEX",
"Mongolia" : "MGL",
"Montenegro" : "MNE",
"Morocco" : "MAR",
"Mozambique" : "MOZ",
"Namibia" : "NAM",
"Netherlands" : "NED",
"New Zealand" : "NZL",
"Niger" : "NGR",
"Nigeria" : "NIG",
"North Macedonia" : "MKD",
"Norway" : "NOR",
"Pakistan" : "PAK",
"Panama" : "PAN",
"Peru" : "PER",
"Philippines" : "PHI",
"Poland" : "POL",
"Portugal" : "POR",
"P. R. China" : "CHN",
"Puerto Rico" : "PUR",
"Qatar" : "QAT",
"Rep of Moldova" : "MDA",
"ROC" : "ROC",
"Romania" : "ROU",
"San Marino" : "SMR",
"Saudi Arabia" : "KSA",
"Serbia" : "SRB",
"Singapore" : "SGP",
"Slovakia" : "SVK",
"Slovenia" : "SLO",
"South Africa" : "RSA",
"Spain" : "ESP",
"Suriname" : "SUR",
"Sweden" : "SWE",
"Switzerland" : "SUI",
"Syria" : "SYR",
"Tanzania" : "TAN",
"Thailand" : "THA",
"Tonga" : "TGA",
"Tri. & Tobago" : "TTO",
"Tunisia" : "TUN",
"Türkiye" : "TUR",
"Turkmenistan" : "TKM",
"Uganda" : "UGA",
"Ukraine" : "UKR",
"United States" : "USA",
"Uruguay" : "URU",
"Uzbekistan" : "UZB",
"Venezuela" : "VEN",
"Vietnam" : "VIE",
"Virgin Isl Brit" : "IVB",
"Zambia" : "ZAM",
}

32
app/shell.nix Normal file
View File

@@ -0,0 +1,32 @@
{ pkgs ? import <nixpkgs> { } }:
let
my-python = pkgs.python312;
python-with-my-packages = my-python.withPackages
(p: with p; [
# flask
]);
lib-path = with pkgs; lib.makeLibraryPath [
];
in pkgs.mkShell {
buildInputs = [
python-with-my-packages
];
shellHook = ''
SOURCE_DATE_EPOCH=$(date +%s)
export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib-path}"
VENV=.venv
if test ! -d $VENV; then
python3 -m venv $VENV
fi
source ./$VENV/bin/activate
export PYTHONPATH=`pwd`/$VENV/${python-with-my-packages.sitePackages}/
# export PYTHONPATH=`pwd`/$VENV/${python-with-my-packages.sitePackages}/:$PYTHONPATH
pip install -r requirements.txt
'';
postShellHook = ''
ln -sf ${python-with-my-packages.sitePackages}/* ./.venv/lib/python3.12/site-packages
'';
}

521
app/static/style.css Normal file
View File

@@ -0,0 +1,521 @@
:root {
--gradient_hue: 69;
--gradient_hue2: 69;
--grad-trans: linear-gradient(to right, hsla(var(--gradient_hue), 100%, 50%, 0.3), hsla(var(--gradient_hue2), 100%, 60%, 0.3), hsla(var(--gradient_hue), 100%, 50%, 0.3));
--grad: linear-gradient(to right, hsla(var(--gradient_hue), 100%, 50%, 1.0), hsla(var(--gradient_hue2), 100%, 60%, 1.0), hsla(var(--gradient_hue), 100%, 50%, 1.0));
--grad2: linear-gradient(to right, hsla(var(--gradient_hue), 100%, 50%, 1.0), hsla(var(--gradient_hue2), 100%, 60%, 1.0), hsla(var(--gradient_hue), 100%, 50%, 1.0));
--bgsize: 400%
}
/* latin-ext */
@font-face {
font-family: 'Atkinson Hyperlegible';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/atkinsonhyperlegible/v11/9Bt23C1KxNDXMspQ1lPyU89-1h6ONRlW45G07JIoSwQ.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Atkinson Hyperlegible';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/atkinsonhyperlegible/v11/9Bt23C1KxNDXMspQ1lPyU89-1h6ONRlW45G04pIo.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtMRrTEUc.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtM1rTEUc.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtMVrTEUc.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtMprTEUc.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtMZrTEUc.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/sourcecodepro/v23/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DCuXtMdrTEUc.woff2) format('woff2');
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(/SourceCodePro-nx2.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@keyframes background-pan {
from {
background-position: 0% center;
}
to {
background-position: -400% center;
}
}
/* Base */
html {
/* background-image: url("pumpkin.png");
background-size: 7vmin 7vmin;
background-repeat: repeat;
background-position: 0% 0%; */
background: radial-gradient(rgba(255, 255, 255, 0.8) 5%, black 5%);
background-size: 2vmin 2vmin;
height: 100%;
}
body {
display: flex;
flex-direction: column;
color: white;
background-color: rgba(0, 0, 0, 0.8);
font-family: "Atkinson Hyperlegible", Arial, Helvetica, sans-serif;
max-width: 60rem;
margin: 1em auto 1em auto;
min-height: 97%;
border: 0.2em solid hsla(var(--gradient_hue), 100%, 50%, 1.0);
border-radius: 1em;
padding: 1em;
box-sizing: border-box;
}
#gradient-me {
display: inherit;
flex-direction: inherit;
height: inherit;
min-height: inherit;
}
div.inline-img {
display: flex;
flex-direction: row;
}
div.inline-img>div {
margin-right: 1em;
}
@media screen and (max-width: 1000px) {
body {
min-height: 100%;
border: none;
margin: 0em;
}
html {
background-color: black;
/* background: none; */
background-size: 5vmin 5vmin;
}
div.inline-img {
flex-direction: column;
}
div.inline-img>div {
margin: 0px auto;
}
}
.MathJax_Display,
span.math.inline {
overflow: scroll;
}
#flex-grow-div {
min-height: 2em;
flex-grow: 1;
}
footer {
justify-self: end;
}
.footer-column {
display: inline-block;
margin: 0em 1em 0em 0em;
vertical-align: text-top;
}
.footer-row>pre {
font-size: 1em;
margin: 0.3em;
}
.footer-row {
display: flex;
flex-direction: row;
}
.footer-row>p {
margin: 0.5em 0em;
line-height: 1em;
}
p {
line-height: 1.5em;
}
hr {
width: 100%;
}
ol {
margin: 0px;
line-height: 1.5em;
}
textarea {
background-color: rgb(20, 20, 20);
color: white;
width: 100%;
min-height: 28.5em;
font-family: "Atkinson Hyperlegible", Arial, Helvetica, sans-serif;
font-size: 1em;
border-radius: 1em;
padding: 1em;
box-sizing: border-box;
}
blockquote {
animation: background-pan 12s linear infinite;
background: var(--grad-trans);
background-size: var(--bgsize);
border-width: 0.2em;
border-color: transparent transparent transparent hsl(var(--gradient_hue), 100%, 50%);
border-radius: 0.5em;
border-style: solid;
margin: 0.5em 0em;
padding: 0em 1em;
}
input,
select {
background: black;
border-radius: 0.2em;
color: white;
}
h2+p {
margin-top: 0px;
}
h2,
h3,
h4,
h5,
h6 {
margin-bottom: 0.3em;
}
li::marker {
color: hsl(var(--gradient_hue) 100% 50%);
}
table {
border-collapse: collapse;
overflow-x: scroll;
margin: 1em 0px;
width: 100%;
}
table td, table th { border: 0.1em solid grey; }
table tr:first-child th { border-top: 0; }
table tr:last-child td { border-bottom: 0; }
table tr td:first-child,
table tr th:first-child { border-left: 0; }
table tr td:last-child,
table tr th:last-child { border-right: 0; }
table tr {
padding: 0.3em 0.4em;
}
table tr td {
padding: 0.1em 0.4em;
border-radius: 0.2em;
}
table tr th {
animation: background-pan 12s linear infinite;
background: var(--grad-trans);
background-size: var(--bgsize);
}
pre code {
font-family: "Source Code Pro";
line-height: 1;
}
:not(pre)>code {
font-family: "Source Code Pro";
font-size: 0.9em;
padding: 0.1em;
background-color: #202020;
border-radius: 0.2em;
}
.ascii {
overflow: hidden;
font-weight: bold;
display: block;
width: fit-content;
max-width: 100%;
height: fit-content;
margin: 0.1em auto 1em auto;
overflow-x: hidden;
}
.ascii>pre {
overflow-x: hidden;
max-width: 100%;
}
.ccode,
.sourceCode>pre {
overflow: auto;
width: 100%;
max-height: 50em;
border-radius: 1.5em;
background-color: #202020;
padding: 1em;
box-sizing: border-box;
}
.ljk-code {
font-weight: bold;
line-height: 1.2em;
font-size: 0.9em;
}
.ascii,
h1,
h2,
h3,
h4,
h5,
h6,
.ljk-code,
p>a:link,
li>a:link,
td>a:link,
th>a:link,
li>em>a:link,
span.fu,
strong>a:link {
animation: background-pan 12s linear infinite;
background:
var(--grad2);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
background-size: var(--bgsize);
}
/* Links */
a:link {
text-decoration: none;
}
p>a:hover,
td>a:hover,
th>a:hover,
li>a:hover {
text-decoration: underline;
text-decoration-color: hsl(var(--gradient_hue), 100%, 75%);
animation: background-pan 12s linear infinite;
background: var(--grad);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
background-size: var(--bgsize);
}
a:active {
color: rgb(17, 255, 0);
}
/* Boxes */
/* Background Color Box */
div.color-box,
div.color-box-4-img,
div.color-box-4-img2,
div.color-box-img3 {
display: inline-block;
text-align: center;
animation: background-pan 12s linear infinite;
background: var(--grad);
background-size: var(--bgsize);
width: fit-content;
height: fit-content;
padding: 0.18em;
margin: 0.3em 0.2em;
border-radius: 0.9em;
}
/* Text in the Box */
div.color-box>div>p {
animation: background-pan 12s linear infinite;
background: var(--grad);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
background-size: var(--bgsize);
margin: 0px;
padding: 0px;
font-size: large;
}
div.color-box>div:hover>p {
-webkit-text-fill-color: black;
text-decoration: none;
}
a:hover:has(+a > div) {
text-decoration: none;
}
/* On Top Box General */
div.color-box>div {
border-radius: 0.8em;
width: fit-content;
background: black;
}
/* this is for the random p pandoc puts inbeteen div and img */
div.color-box>p {
margin: 0px;
line-height: 0px;
}
div.color-box>div:hover {
background: transparent;
text-decoration: none;
}
/* On Top Boxes Types */
div.color-box>div.about-box {
padding: 0.6em 1.5em;
}
div.color-box>div.blog-box {
padding: 0.4em 1em;
}
div.color-box>div.nav-box {
padding: 0.1em 0.8em;
}
/* Images */
div.color-box-4-img {
height: 95%;
}
div.color-box-4-img>div.plain-box {
background: black;
height: 100%;
border-radius: 0.7em;
}
div.color-box-4-img>div.plain-box>div.color-box-4-img2 {
padding: 0px;
height: 94%;
margin: 0px;
box-sizing: border-box;
}
div.color-box-4-img>div.plain-box>div.color-box-4-img2>div.checker-box {
background: repeating-conic-gradient(rgba(0, 0, 0, 0.3) 0% 25%, rgba(0, 0, 0, 0.6) 0% 50%) 50% / 20px 20px;
border-radius: 0.7em;
height: 100%;
border: 0.3em solid black;
}
div.color-box-4-img>div.plain-box>div.color-box-4-img2>div.checker-box>p {
height: 100%;
padding-top: 0px;
margin: 0px;
width: 100%;
box-sizing: border-box;
}
div.color-box-4-img>div.plain-box>div.color-box-4-img2>div.checker-box>p>img {
height: 90%;
border: 0.1em solid white;
box-shadow: 0em 0em 0.5em black;
margin-top: 1em;
margin-bottom: 1em;
margin-right: 1em;
margin-left: 1em;
box-sizing: border-box;
}
div.color-box-4-img>div.plain-box>p {
margin: 0px 0.3em;
}

142
app/templates/index.html Normal file
View File

@@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Olympic Guessing Game</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<style>
div.entry {
padding: 0.4em 1em;
margin: 0.2em;
background-color: hsla(var(--gradient_hue), 100%, 50%, 0.2);
border-radius: 0.8em;
display: flex;
gap: 1em;
}
img.image {
height: 3em;
width: 4.5em;
object-fit: cover;
border: 0.1em solid white;
border-radius: 0.5em;
}
p.country_name {
width: 7em;
margin-top: auto;
margin-bottom: auto;
margin-left: 0px;
margin-right: 0px;
padding: 0px;
height: 100%;
box-sizing: border-box;
}
a.athlete {
margin: auto;
margin-left: 0px;
padding: 0px;
height: 100%;
box-sizing: border-box;
color: white;
}
button.state {
background-color: hsla(var(--gradient_hue), 100%, 50%, 0.1);
border: 0.2em solid hsl(var(--gradient_hue), 100%, 50%);
border-radius: 0.8em;
color: white;
padding: 0.5em;
margin: 0.6em 0px;
}
</style>
<script>
let lastAnswer = "";
function fetchDiscipline() {
fetch('/get_random_discipline')
.then(response => response.json())
.then(data => {
const participantsList = document.getElementById('participants-list');
participantsList.innerHTML = '';
data.participants.forEach(participant => {
const entry = document.createElement('div');
const img = document.createElement('img');
img.src = participant.country_img_url;
img.setAttribute("class", "image");
entry.appendChild(img);
const p = document.createElement('p');
p.textContent = participant.country_name;
p.setAttribute("class", "country_name");
entry.appendChild(p);
if (participant.athlete_name) {
const athlete = document.createElement('a');
athlete.textContent = participant.athlete_name;
athlete.setAttribute("class", "athlete");
athlete.style.display = "None";
athlete.setAttribute("href", participant.athlete_meta_url);
athlete.setAttribute("target", "_blank");
entry.appendChild(athlete);
img.setAttribute('athlete_img', participant.athlete_img_url)
}
entry.setAttribute("class", "entry");
participantsList.appendChild(entry);
});
try { // if it is a team sport
const athletes = document.getElementsByClassName("athlete");
atletes.forEach(athlete => athlete.style.display = 'None');
} catch { }
document.getElementById('reveal').style.display = 'none';
document.getElementById('reveal').textContent = data.answer;
document.getElementById('reveal-wrapper').style.display = 'none';
document.getElementById('reveal-button').style.display = 'block';
document.getElementById('next-button').style.display = 'none';
var root = document.querySelector(':root')
var r_int = (Math.floor(Math.random() * 250) + 145) % 360
root.style.setProperty('--gradient_hue', r_int);
root.style.setProperty('--gradient_hue2', (r_int + 20 ) % 360 );
});
}
function revealAnswer() {
document.getElementById('reveal').style.display = 'block';
document.getElementById('reveal-wrapper').style.display = 'block';
// Now show the athletes' names if available
const participantsList = document.getElementById('participants-list');
Array.from(participantsList.children).forEach(entry => {
const athlete = entry.querySelector('a.athlete');
if (athlete) {
const img = entry.querySelector('img');
img.setAttribute("src", img.getAttribute("athlete_img"));
athlete.style.display = "Block";
}
});
document.getElementById('reveal-button').style.display = 'none';
document.getElementById('next-button').style.display = 'block';
}
window.onload = fetchDiscipline;
</script>
</head>
<body>
<h1 style="margin: 0.1em auto;">Guess the Olympic Discipline</h1>
<div id="participants-list">
<!-- Participants -->
</div>
<button class="state" id="reveal-button" onclick="revealAnswer()">Reveal Answer</button>
<button class="state" id="next-button" style="display:none;" onclick="fetchDiscipline()">Next</button>
<blockquote id="reveal-wrapper" style="display:none;">
<p id="reveal" style="display:none;"></p>
</blockquote>
</body>
</html>