Merge branch 'master' into backend-dependency-update

This commit is contained in:
Mawoka
2025-08-01 13:36:52 +02:00
53 changed files with 8577 additions and 5722 deletions
+1
View File
@@ -12,3 +12,4 @@ node_modules/
survey.json survey.json
.coverage .coverage
export_deta.py export_deta.py
target/
+15
View File
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
//
// SPDX-License-Identifier: MPL-2.0
{
"sqltools.connections": [
{
"previewLimit": 50,
"server": "localhost",
"driver": "PostgreSQL",
"connectString": "postgresql://postgres:mysecretpassword@localhost:5432/classquiz",
"name": "ClassQuiz"
}
]
}
+1 -1
View File
@@ -4,7 +4,7 @@
#* { #* {
:8080 { :8080 {
# tls /home/mawoka/certs/cert.pem /home/mawoka/certs/key.pem # tls /home/mawoka/certs/cert.pem /home/mawoka/certs/key.pem
reverse_proxy /* localhost:3000 reverse_proxy /* localhost:3000
reverse_proxy /api* localhost:8000 reverse_proxy /api* localhost:8000
reverse_proxy /rapidoc* localhost:8000 reverse_proxy /rapidoc* localhost:8000
Generated
+314 -140
View File
@@ -20,6 +20,8 @@
"hashes": [ "hashes": [
"sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c",
"sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5" "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"
"sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c",
"sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
@@ -547,9 +549,12 @@
"hashes": [ "hashes": [
"sha256:cf5da4b8a3e3cd038c459529725ebb64931cbbb7a091102664f20ef8f6cefd0d", "sha256:cf5da4b8a3e3cd038c459529725ebb64931cbbb7a091102664f20ef8f6cefd0d",
"sha256:ea2d419d3d2eb80595b7ceb8f282056f080af62efe2fb9bcd83562f93ec4b674" "sha256:ea2d419d3d2eb80595b7ceb8f282056f080af62efe2fb9bcd83562f93ec4b674"
"sha256:cf5da4b8a3e3cd038c459529725ebb64931cbbb7a091102664f20ef8f6cefd0d",
"sha256:ea2d419d3d2eb80595b7ceb8f282056f080af62efe2fb9bcd83562f93ec4b674"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==0.7.0" "version": "==0.7.0"
"version": "==0.7.0"
}, },
"dnspython": { "dnspython": {
"hashes": [ "hashes": [
@@ -571,10 +576,13 @@
"hashes": [ "hashes": [
"sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631",
"sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7" "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"
"sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631",
"sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.2.0" "version": "==2.2.0"
"version": "==2.2.0"
}, },
"et-xmlfile": { "et-xmlfile": {
"hashes": [ "hashes": [
@@ -924,10 +932,14 @@
"hashes": [ "hashes": [
"sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef",
"sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"
"sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef",
"sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.2.0" "version": "==2.2.0"
"markers": "python_version >= '3.8'",
"version": "==2.2.0"
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
@@ -1167,6 +1179,8 @@
"hashes": [ "hashes": [
"sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2",
"sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050" "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"
"sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2",
"sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
@@ -1279,9 +1293,90 @@
"sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27", "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
"sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e", "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
"sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1" "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
"sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885",
"sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea",
"sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df",
"sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5",
"sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c",
"sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d",
"sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd",
"sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06",
"sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908",
"sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a",
"sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be",
"sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0",
"sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b",
"sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80",
"sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a",
"sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e",
"sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9",
"sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696",
"sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b",
"sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309",
"sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e",
"sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab",
"sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d",
"sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060",
"sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d",
"sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d",
"sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4",
"sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3",
"sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6",
"sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb",
"sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94",
"sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b",
"sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496",
"sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0",
"sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319",
"sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b",
"sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856",
"sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef",
"sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680",
"sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b",
"sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42",
"sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e",
"sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597",
"sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a",
"sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8",
"sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3",
"sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736",
"sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da",
"sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126",
"sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd",
"sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5",
"sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b",
"sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026",
"sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b",
"sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc",
"sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46",
"sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2",
"sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c",
"sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe",
"sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984",
"sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a",
"sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70",
"sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca",
"sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b",
"sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91",
"sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3",
"sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84",
"sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1",
"sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5",
"sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be",
"sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f",
"sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc",
"sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9",
"sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e",
"sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141",
"sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef",
"sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22",
"sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
"sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
"sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==10.4.0" "version": "==10.4.0"
"version": "==10.4.0"
}, },
"propcache": { "propcache": {
"hashes": [ "hashes": [
@@ -1572,7 +1667,7 @@
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==2.10.1" "version": "==2.10.1"
}, },
"pygments": { "pydantic-core": {
"hashes": [ "hashes": [
"sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887",
"sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"
@@ -1877,9 +1972,12 @@
"hashes": [ "hashes": [
"sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb", "sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb",
"sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926" "sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926"
"sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb",
"sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.11.1" "version": "==1.11.1"
"version": "==1.11.1"
}, },
"webencodings": { "webencodings": {
"hashes": [ "hashes": [
@@ -1888,6 +1986,83 @@
], ],
"version": "==0.5.1" "version": "==0.5.1"
}, },
"websockets": {
"hashes": [
"sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b",
"sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6",
"sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df",
"sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b",
"sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205",
"sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892",
"sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53",
"sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2",
"sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed",
"sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c",
"sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd",
"sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b",
"sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931",
"sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30",
"sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370",
"sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be",
"sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec",
"sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf",
"sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62",
"sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b",
"sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402",
"sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f",
"sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123",
"sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9",
"sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603",
"sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45",
"sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558",
"sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4",
"sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438",
"sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137",
"sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480",
"sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447",
"sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8",
"sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04",
"sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c",
"sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb",
"sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967",
"sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b",
"sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d",
"sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def",
"sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c",
"sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92",
"sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2",
"sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113",
"sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b",
"sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28",
"sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7",
"sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d",
"sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f",
"sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468",
"sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8",
"sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae",
"sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611",
"sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d",
"sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9",
"sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca",
"sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f",
"sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2",
"sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077",
"sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2",
"sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6",
"sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374",
"sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc",
"sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e",
"sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53",
"sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399",
"sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547",
"sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3",
"sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870",
"sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5",
"sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8",
"sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"
],
"version": "==12.0"
},
"wsproto": { "wsproto": {
"hashes": [ "hashes": [
"sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065", "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065",
@@ -2158,40 +2333,40 @@
}, },
"black": { "black": {
"hashes": [ "hashes": [
"sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f", "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474",
"sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93", "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1",
"sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11", "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0",
"sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0", "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8",
"sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9", "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96",
"sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5", "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1",
"sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213", "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04",
"sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d", "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021",
"sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7", "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94",
"sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837", "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d",
"sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f", "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c",
"sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395", "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7",
"sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995", "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c",
"sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f", "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc",
"sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597", "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7",
"sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959", "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d",
"sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5", "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c",
"sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb", "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741",
"sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4", "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce",
"sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7", "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb",
"sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd", "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063",
"sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==24.3.0" "version": "==24.4.2"
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b",
"sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==2024.2.2" "version": "==2024.7.4"
}, },
"cfgv": { "cfgv": {
"hashes": [ "hashes": [
@@ -2307,62 +2482,62 @@
}, },
"coverage": { "coverage": {
"hashes": [ "hashes": [
"sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c", "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f",
"sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63", "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d",
"sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7", "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747",
"sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f", "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f",
"sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8", "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d",
"sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf", "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f",
"sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0", "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47",
"sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384", "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e",
"sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76", "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba",
"sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7", "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c",
"sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d", "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b",
"sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70", "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4",
"sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f", "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7",
"sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818", "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555",
"sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b", "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233",
"sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d", "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace",
"sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec", "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805",
"sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083", "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136",
"sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2", "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4",
"sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9", "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d",
"sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd", "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806",
"sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade", "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99",
"sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e", "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8",
"sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a", "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b",
"sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227", "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5",
"sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87", "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da",
"sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c", "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0",
"sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e", "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078",
"sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c", "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f",
"sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e", "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029",
"sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd", "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353",
"sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec", "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638",
"sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562", "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9",
"sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8", "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f",
"sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677", "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7",
"sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357", "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3",
"sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c", "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e",
"sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd", "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016",
"sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49", "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088",
"sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286", "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4",
"sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1", "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882",
"sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf", "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7",
"sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51", "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53",
"sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409", "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d",
"sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384", "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080",
"sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e", "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5",
"sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978", "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d",
"sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57", "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c",
"sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e", "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8",
"sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2", "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633",
"sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48", "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9",
"sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4" "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==7.4.4" "version": "==7.5.4"
}, },
"distlib": { "distlib": {
"hashes": [ "hashes": [
@@ -2373,20 +2548,20 @@
}, },
"filelock": { "filelock": {
"hashes": [ "hashes": [
"sha256:5ffa845303983e7a0b7ae17636509bc97997d58afeafa72fb141a17b152284cb", "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb",
"sha256:a79895a25bbefdf55d1a2a0a80968f7dbb28edcd6d4234a0afb3f37ecde4b546" "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==3.13.3" "version": "==3.15.4"
}, },
"flake8": { "flake8": {
"hashes": [ "hashes": [
"sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132", "sha256:2e416edcc62471a64cea09353f4e7bdba32aeb079b6e360554c659a122b1bc6a",
"sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3" "sha256:48a07b626b55236e0fb4784ee69a465fbf59d79eec1f5b4785c3d3bc57d17aa5"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_full_version >= '3.8.1'", "markers": "python_full_version >= '3.8.1'",
"version": "==7.0.0" "version": "==7.1.0"
}, },
"h11": { "h11": {
"hashes": [ "hashes": [
@@ -2398,19 +2573,19 @@
}, },
"identify": { "identify": {
"hashes": [ "hashes": [
"sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791", "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf",
"sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e" "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.5.35" "version": "==2.6.0"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
"sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc",
"sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"
], ],
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==3.6" "version": "==3.7"
}, },
"iniconfig": { "iniconfig": {
"hashes": [ "hashes": [
@@ -2438,19 +2613,19 @@
}, },
"nodeenv": { "nodeenv": {
"hashes": [ "hashes": [
"sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2", "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f",
"sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec" "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'",
"version": "==1.8.0" "version": "==1.9.1"
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
"sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==24.0" "version": "==24.1"
}, },
"pathspec": { "pathspec": {
"hashes": [ "hashes": [
@@ -2462,36 +2637,36 @@
}, },
"platformdirs": { "platformdirs": {
"hashes": [ "hashes": [
"sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee",
"sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==4.2.0" "version": "==4.2.2"
}, },
"pluggy": { "pluggy": {
"hashes": [ "hashes": [
"sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1",
"sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==1.4.0" "version": "==1.5.0"
}, },
"pre-commit": { "pre-commit": {
"hashes": [ "hashes": [
"sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab", "sha256:8ca3ad567bc78a4972a3f1a477e94a79d4597e8140a6e0b651c5e33899c3654a",
"sha256:e209d61b8acdcf742404408531f0c37d49d2c734fd7cff2d6076083d191cb060" "sha256:fae36fd1d7ad7d6a5a1c0b0d5adb2ed1a3bda5a21bf6c3e5372073d7a11cd4c5"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==3.7.0" "version": "==3.7.1"
}, },
"pycodestyle": { "pycodestyle": {
"hashes": [ "hashes": [
"sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f", "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c",
"sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67" "sha256:949a39f6b86c3e1515ba1787c2022131d165a8ad271b11370a8819aa070269e4"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.11.1" "version": "==2.12.0"
}, },
"pyflakes": { "pyflakes": {
"hashes": [ "hashes": [
@@ -2503,21 +2678,21 @@
}, },
"pytest": { "pytest": {
"hashes": [ "hashes": [
"sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7", "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343",
"sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044" "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==8.1.1" "version": "==8.2.2"
}, },
"pytest-asyncio": { "pytest-asyncio": {
"hashes": [ "hashes": [
"sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a", "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b",
"sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f" "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==0.23.6" "version": "==0.23.7"
}, },
"pytest-dependency": { "pytest-dependency": {
"hashes": [ "hashes": [
@@ -2538,20 +2713,20 @@
}, },
"python-engineio": { "python-engineio": {
"hashes": [ "hashes": [
"sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c", "sha256:7631cf5563086076611e494c643b3fa93dd3a854634b5488be0bba0ef9b99709",
"sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7" "sha256:f995e702b21f6b9ebde4e2000cd2ad0112ba0e5116ec8d22fe3515e76ba9dddd"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==4.9.0" "version": "==4.9.1"
}, },
"python-socketio": { "python-socketio": {
"hashes": [ "hashes": [
"sha256:ae6a1de5c5209ca859dc574dccc8931c4be17ee003e74ce3b8d1306162bb4a37", "sha256:194af8cdbb7b0768c2e807ba76c7abc288eb5bb85559b7cddee51a6bc7a65737",
"sha256:b9f22a8ff762d7a6e123d16a43ddb1a27d50f07c3c88ea999334f2f89b0ad52b" "sha256:2a923a831ff70664b7c502df093c423eb6aa93c1ce68b8319e840227a26d8b69"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==5.11.2" "version": "==5.11.3"
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
@@ -2607,24 +2782,23 @@
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
], ],
"markers": "python_version >= '3.6'",
"version": "==6.0.1" "version": "==6.0.1"
}, },
"requests": { "requests": {
"hashes": [ "hashes": [
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==2.31.0" "version": "==2.32.3"
}, },
"setuptools": { "setuptools": {
"hashes": [ "hashes": [
"sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e", "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05",
"sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c" "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==69.2.0" "version": "==70.2.0"
}, },
"simple-websocket": { "simple-websocket": {
"hashes": [ "hashes": [
@@ -2636,26 +2810,26 @@
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
"sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19" "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.2.1" "version": "==2.2.2"
}, },
"virtualenv": { "virtualenv": {
"hashes": [ "hashes": [
"sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a", "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a",
"sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197" "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==20.25.1" "version": "==20.26.3"
}, },
"websocket-client": { "websocket-client": {
"hashes": [ "hashes": [
"sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6", "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526",
"sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588" "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da"
], ],
"version": "==1.7.0" "version": "==1.8.0"
}, },
"wsproto": { "wsproto": {
"hashes": [ "hashes": [
+1 -2
View File
@@ -36,7 +36,7 @@ from classquiz.routers import (
moderation, moderation,
) )
from classquiz.socket_server import sio from classquiz.socket_server import sio
from classquiz.helpers import meilisearch_init, telemetry_ping from classquiz.helpers import meilisearch_init
settings = settings() settings = settings()
if settings.sentry_dsn: if settings.sentry_dsn:
@@ -63,7 +63,6 @@ async def startup() -> None:
if not database_.is_connected: if not database_.is_connected:
await database_.connect() await database_.connect()
await meilisearch_init() await meilisearch_init()
await telemetry_ping()
@app.on_event("shutdown") @app.on_event("shutdown")
+14 -12
View File
@@ -8,9 +8,8 @@ from functools import lru_cache
from redis import asyncio as redis_lib from redis import asyncio as redis_lib
import redis as redis_base_lib import redis as redis_base_lib
from pydantic import RedisDsn, PostgresDsn, BaseModel from pydantic import RedisDsn, PostgresDsn, BaseModel
from pydantic_settings import BaseSettings from pydantic_settings import BaseSettings, SettingsConfigDict
import meilisearch as MeiliSearch import meilisearch as MeiliSearch
from typing import Optional
from arq import create_pool from arq import create_pool
from arq.connections import RedisSettings, ArqRedis from arq.connections import RedisSettings, ArqRedis
@@ -29,10 +28,13 @@ class Settings(BaseSettings):
Settings class for the shop app. Settings class for the shop app.
""" """
model_config = SettingsConfigDict(
env_file=".env", extra="ignore", env_nested_delimiter="__", env_file_encoding="utf-8"
)
root_address: str = "http://127.0.0.1:8000" root_address: str = "http://127.0.0.1:8000"
redis: RedisDsn = "redis://localhost:6379/0?decode_responses=True" redis: RedisDsn = "redis://localhost:6379/0?decode_responses=True"
skip_email_verification: bool = False skip_email_verification: bool = False
db_url: str | PostgresDsn = "postgresql://postgres:mysecretpassword@localhost:5432/classquiz" db_url: PostgresDsn | str = "postgresql://postgres:mysecretpassword@localhost:5432/classquiz"
hcaptcha_key: str | None = None hcaptcha_key: str | None = None
recaptcha_key: str | None = None recaptcha_key: str | None = None
mail_address: str mail_address: str
@@ -43,13 +45,13 @@ class Settings(BaseSettings):
secret_key: str secret_key: str
access_token_expire_minutes: int = 30 access_token_expire_minutes: int = 30
cache_expiry: int = 86400 cache_expiry: int = 86400
sentry_dsn: str | None sentry_dsn: str | None = None
meilisearch_url: str = "http://127.0.0.1:7700" meilisearch_url: str = "http://127.0.0.1:7700"
meilisearch_index: str = "classquiz" meilisearch_index: str = "classquiz"
google_client_id: Optional[str] google_client_id: str | None = None
google_client_secret: Optional[str] google_client_secret: str | None = None
github_client_id: Optional[str] github_client_id: str | None = None
github_client_secret: Optional[str] github_client_secret: str | None = None
custom_openid_provider: CustomOpenIDProvider | None = None custom_openid_provider: CustomOpenIDProvider | None = None
telemetry_enabled: bool = True telemetry_enabled: bool = True
free_storage_limit: int = 1074000000 free_storage_limit: int = 1074000000
@@ -58,14 +60,14 @@ class Settings(BaseSettings):
registration_disabled: bool = False registration_disabled: bool = False
# storage_backend # storage_backend
storage_backend: str | None = "local" storage_backend: str # either "local" or "s3"
# if storage_backend == "local": # if storage_backend == "local":
storage_path: str | None storage_path: str | None = None
# if storage_backend == "s3": # if storage_backend == "s3":
s3_access_key: str | None s3_access_key: str | None = None
s3_secret_key: str | None s3_secret_key: str | None = None
s3_bucket_name: str = "classquiz" s3_bucket_name: str = "classquiz"
s3_base_url: str | None s3_base_url: str | None
+2 -1
View File
@@ -139,6 +139,7 @@ class QuizQuestion(BaseModel):
type: None | QuizQuestionType = QuizQuestionType.ABCD type: None | QuizQuestionType = QuizQuestionType.ABCD
answers: list[ABCDQuizAnswer] | RangeQuizAnswer | list[TextQuizAnswer] | list[VotingQuizAnswer] | str answers: list[ABCDQuizAnswer] | RangeQuizAnswer | list[TextQuizAnswer] | list[VotingQuizAnswer] | str
image: str | None = None image: str | None = None
hide_results: bool | None = False
@field_validator("answers") @field_validator("answers")
def answers_not_none_if_abcd_type(cls, v, info: ValidationInfo): def answers_not_none_if_abcd_type(cls, v, info: ValidationInfo):
@@ -416,7 +417,7 @@ class PublicStorageItem(BaseModel):
id: uuid.UUID id: uuid.UUID
uploaded_at: datetime uploaded_at: datetime
mime_type: str mime_type: str
hash: str | None hash: str | None = None
size: int size: int
deleted_at: datetime | None = None deleted_at: datetime | None = None
alt_text: str | None = None alt_text: str | None = None
+2 -2
View File
@@ -146,7 +146,7 @@ async def handle_import_from_excel(data: BinaryIO, user: User) -> Quiz:
for a, answer in enumerate(answers): for a, answer in enumerate(answers):
if answer is None: if answer is None:
continue continue
if len(answer) > 150: if len(str(answer)) > 150:
raise HTTPException(status_code=400, detail=f"Answer {a + 1} in Question {i + 1} is longer than 150") raise HTTPException(status_code=400, detail=f"Answer {a + 1} in Question {i + 1} is longer than 150")
if len(answers) < 2: if len(answers) < 2:
raise HTTPException(status_code=400, detail=f"Less than 2 answers in Question {i + 1}") raise HTTPException(status_code=400, detail=f"Less than 2 answers in Question {i + 1}")
@@ -155,7 +155,7 @@ async def handle_import_from_excel(data: BinaryIO, user: User) -> Quiz:
for a, answer in enumerate(answers): for a, answer in enumerate(answers):
if answer is None: if answer is None:
continue continue
answers_list.append(ABCDQuizAnswer(answer=answer, right=str(a + 1) in correct_answers)) answers_list.append(ABCDQuizAnswer(answer=str(answer), right=str(a + 1) in correct_answers))
existing_question: dict | None = None existing_question: dict | None = None
if existing_quiz is not None: if existing_quiz is not None:
+1 -1
View File
@@ -60,7 +60,7 @@ class _Card(BaseModel):
cover: str | None = None cover: str | None = None
coverMetadata: _CoverMetadata | dict[None, None] | None = None coverMetadata: _CoverMetadata | dict[None, None] | None = None
draftExists: bool draftExists: bool
inventoryItemIds: List[Any] inventoryItemIds: List[Any] = None
number_of_questions: int number_of_questions: int
creator: UUID creator: UUID
creator_username: str creator_username: str
+1 -1
View File
@@ -20,7 +20,7 @@ class _Response(BaseModel):
async def search( async def search(
query: str | None, query: str | None = None,
limit: int | None = 9, limit: int | None = 9,
cursor: int | None = 1, cursor: int | None = 1,
search_cluster: int | None = 1, search_cluster: int | None = 1,
+1 -1
View File
@@ -54,7 +54,7 @@ class PublicQuizResponseUser(BaseModel):
id: uuid.UUID id: uuid.UUID
class PublicQuizResponse(Quiz.get_pydantic()): class PublicQuizResponse(Quiz.get_pydantic(exclude={"questions"})):
user_id: PublicQuizResponseUser user_id: PublicQuizResponseUser
questions: list[QuizQuestion] questions: list[QuizQuestion]
likes: int likes: int
+63 -28
View File
@@ -28,6 +28,7 @@ from pydantic import BaseModel, ValidationError, field_validator, ValidationInfo
from datetime import datetime from datetime import datetime
from classquiz.socket_server.export_helpers import save_quiz_to_storage from classquiz.socket_server.export_helpers import save_quiz_to_storage
from classquiz.socket_server.session import get_session, save_session
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins=[]) sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins=[])
settings = settings() settings = settings()
@@ -117,7 +118,7 @@ async def rejoin_game(sid: str, data: dict):
"sid_custom": sid, "sid_custom": sid,
"admin": False, "admin": False,
} }
await sio.save_session(sid, session) await save_session(sid, sio, session)
await sio.enter_room(sid, data.game_pin) await sio.enter_room(sid, data.game_pin)
await sio.emit( await sio.emit(
"rejoined_game", "rejoined_game",
@@ -153,7 +154,10 @@ async def join_game(sid: str, data: dict):
try: try:
async with session.post( async with session.post(
"https://hcaptcha.com/siteverify", "https://hcaptcha.com/siteverify",
data={"response": data.captcha, "secret": settings.hcaptcha_key}, data={
"response": data.captcha,
"secret": settings.hcaptcha_key,
},
) as resp: ) as resp:
resp_data = await resp.model_dump_json() resp_data = await resp.model_dump_json()
if not resp_data["success"]: if not resp_data["success"]:
@@ -165,7 +169,10 @@ async def join_game(sid: str, data: dict):
elif settings.recaptcha_key is not None: elif settings.recaptcha_key is not None:
async with session.post( async with session.post(
"https://www.google.com/recaptcha/api/siteverify", "https://www.google.com/recaptcha/api/siteverify",
data={"secret": settings.recaptcha_key, "response": data.captcha}, data={
"secret": settings.recaptcha_key,
"response": data.captcha,
},
) as resp: ) as resp:
try: try:
resp_data = await resp.model_dump_json() resp_data = await resp.model_dump_json()
@@ -188,7 +195,7 @@ async def join_game(sid: str, data: dict):
"sid_custom": sid, "sid_custom": sid,
"admin": False, "admin": False,
} }
await sio.save_session(sid, session) await save_session(sid, sio, session)
await sio.emit( await sio.emit(
"joined_game", "joined_game",
{ {
@@ -206,7 +213,11 @@ async def join_game(sid: str, data: dict):
if data.custom_field == "": if data.custom_field == "":
data.custom_field = None data.custom_field = None
if data.custom_field is not None: if data.custom_field is not None:
await redis.hset(f"game:{data.game_pin}:players:custom_fields", data.username, data.custom_field) await redis.hset(
f"game:{data.game_pin}:players:custom_fields",
data.username,
data.custom_field,
)
await sio.emit( await sio.emit(
"player_joined", "player_joined",
@@ -222,7 +233,7 @@ async def join_game(sid: str, data: dict):
@sio.event @sio.event
async def start_game(sid: str, _data: dict): async def start_game(sid: str, _data: dict):
session = await sio.get_session(sid) session = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
game_data = PlayGame.model_validate_json(await redis.get(f"game:{session['game_pin']}")) game_data = PlayGame.model_validate_json(await redis.get(f"game:{session['game_pin']}"))
@@ -259,10 +270,11 @@ async def register_as_admin(sid: str, data: dict):
{"game_id": game_id, "game": await redis.get(f"game:{game_pin}")}, {"game_id": game_id, "game": await redis.get(f"game:{game_pin}")},
room=sid, room=sid,
) )
async with sio.session(sid) as session: session = {}
session["game_pin"] = game_pin session["game_pin"] = game_pin
session["admin"] = True session["admin"] = True
session["remote"] = False session["remote"] = False
await save_session(sid, sio, session)
await sio.enter_room(sid, game_pin) await sio.enter_room(sid, game_pin)
await sio.enter_room(sid, f"admin:{data.game_pin}") await sio.enter_room(sid, f"admin:{data.game_pin}")
else: else:
@@ -271,7 +283,7 @@ async def register_as_admin(sid: str, data: dict):
@sio.event @sio.event
async def get_question_results(sid: str, data: dict): async def get_question_results(sid: str, data: dict):
session = await sio.get_session(sid) session = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
@@ -317,7 +329,7 @@ class ReturnQuestion(QuizQuestion):
@sio.event @sio.event
async def set_question_number(sid, data: str): async def set_question_number(sid, data: str):
# data is just a number (as a str) of the question # data is just a number (as a str) of the question
session = await sio.get_session(sid) session = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
game_pin = session["game_pin"] game_pin = session["game_pin"]
@@ -423,14 +435,15 @@ async def submit_answer(sid: str, data: dict):
answer_right = bool(correct_string == data.answer) answer_right = bool(correct_string == data.answer)
else: else:
raise NotImplementedError raise NotImplementedError
latency = int(float((await sio.get_session(sid))["ping"])) latency = int(float((await get_session(sid, sio))["ping"]))
time_q_started = datetime.fromisoformat(await redis.get(f"game:{session['game_pin']}:current_time")) time_q_started = datetime.fromisoformat(await redis.get(f"game:{session['game_pin']}:current_time"))
diff = (time_q_started - now).total_seconds() * 1000 # - timedelta(milliseconds=latency) diff = (time_q_started - now).total_seconds() * 1000 # - timedelta(milliseconds=latency)
score = 0 score = 0
if answer_right: if answer_right:
score = calculate_score( score = calculate_score(
abs(diff) - latency, int(float(game_data.questions[int(float(data.question_index))].time)) abs(diff) - latency,
int(float(game_data.questions[int(float(data.question_index))].time)),
) )
if score > 1000: if score > 1000:
score = 1000 score = 1000
@@ -444,7 +457,10 @@ async def submit_answer(sid: str, data: dict):
) )
answers = await redis.get(f"game_session:{session['game_pin']}:{data.question_index}") answers = await redis.get(f"game_session:{session['game_pin']}:{data.question_index}")
answers = await set_answer( answers = await set_answer(
answers, game_pin=session["game_pin"], data=answer_data, q_index=int(float(data.question_index)) answers,
game_pin=session["game_pin"],
data=answer_data,
q_index=int(float(data.question_index)),
) )
player_count = await redis.scard(f"game_session:{session['game_pin']}:players") player_count = await redis.scard(f"game_session:{session['game_pin']}:players")
await sio.emit("player_answer", {}) await sio.emit("player_answer", {})
@@ -465,7 +481,7 @@ async def submit_answer(sid: str, data: dict):
@sio.event @sio.event
async def get_final_results(sid: str, _data: dict): async def get_final_results(sid: str, _data: dict):
session: dict = await sio.get_session(sid) session: dict = await get_session(sid, sio)
game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}"))) game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}")))
if not session["admin"]: if not session["admin"]:
return return
@@ -475,7 +491,7 @@ async def get_final_results(sid: str, _data: dict):
@sio.event @sio.event
async def get_export_token(sid: str): async def get_export_token(sid: str):
session = await sio.get_session(sid) session = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}"))) game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}")))
@@ -487,7 +503,7 @@ async def get_export_token(sid: str):
@sio.event @sio.event
async def show_solutions(sid: str, _data: dict): async def show_solutions(sid: str, _data: dict):
session: dict = await sio.get_session(sid) session: dict = await get_session(sid, sio)
game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}"))) game_data = PlayGame(**json.loads(await redis.get(f"game:{session['game_pin']}")))
if not session["admin"]: if not session["admin"]:
return return
@@ -500,8 +516,9 @@ async def echo_time_sync(sid: str, data: str):
then = datetime.fromisoformat(then_dec) then = datetime.fromisoformat(then_dec)
now = datetime.now() now = datetime.now()
delta = now - then delta = now - then
async with sio.session(sid) as session: session = await get_session(sid, sio)
session["ping"] = delta.microseconds / 1000 session["ping"] = delta.microseconds / 1000
await save_session(sid, sio, session)
class _KickPlayerInput(BaseModel): class _KickPlayerInput(BaseModel):
@@ -517,7 +534,7 @@ async def kick_player(sid: str, data: dict):
print(e) print(e)
return return
session: dict = await sio.get_session(sid) session: dict = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
@@ -549,10 +566,11 @@ async def register_as_remote(sid: str, data: dict):
room=sid, room=sid,
) )
await sio.emit("control_visibility", {"visible": False}, room=f"admin:{data.game_pin}") await sio.emit("control_visibility", {"visible": False}, room=f"admin:{data.game_pin}")
async with sio.session(sid) as session: session = await get_session(sid, sio)
session["game_pin"] = data.game_pin session["game_pin"] = data.game_pin
session["admin"] = True session["admin"] = True
session["remote"] = True session["remote"] = True
await save_session(sid, sio, session)
await sio.enter_room(sid, data.game_pin) await sio.enter_room(sid, data.game_pin)
await sio.enter_room(sid, f"admin:{data.game_pin}") await sio.enter_room(sid, f"admin:{data.game_pin}")
@@ -569,14 +587,31 @@ async def set_control_visibility(sid: str, data: dict):
await sio.emit("error", room=sid) await sio.emit("error", room=sid)
print(e) print(e)
return return
session: dict = await sio.get_session(sid) session: dict = await get_session(sid, sio)
await sio.emit("control_visibility", {"visible": data.visible}, room=f"admin:{session['game_pin']}") await sio.emit(
"control_visibility",
{"visible": data.visible},
room=f"admin:{session['game_pin']}",
)
@sio.event @sio.event
async def save_quiz(sid: str): async def save_quiz(sid: str):
session: dict = await sio.get_session(sid) session: dict = await get_session(sid, sio)
if not session["admin"]: if not session["admin"]:
return return
await save_quiz_to_storage(session["game_pin"]) await save_quiz_to_storage(session["game_pin"])
await sio.emit("results_saved_successfully") await sio.emit("results_saved_successfully")
class ConnectSessionIdEvent(BaseModel):
session_id: str
@sio.event
async def connect(sid: str, _environ, _auth):
session_id = os.urandom(16).hex()
print("Connection opened with handler")
sio_session = {"session_id": session_id}
await sio.save_session(sid, sio_session)
await sio.emit("session_id", ConnectSessionIdEvent(session_id=session_id).dict())
+26
View File
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
from classquiz.config import redis
import json
from typing import Any
from socketio import AsyncServer
from socketio.exceptions import ConnectionRefusedError
async def get_session(sid: str, sio: AsyncServer, disconnect_on_error: bool = True) -> dict:
session_id = (await sio.get_session(sid)).get("session_id")
if session_id is None:
raise ConnectionRefusedError("Session not configured")
val = await redis.get(f"socket_io_session:{session_id}")
if disconnect_on_error and val is None:
raise ConnectionRefusedError("session not available")
return json.loads(val)
async def save_session(sid: str, sio: AsyncServer, data: Any, disconnect_on_error: bool = True) -> None:
session_id = (await sio.get_session(sid)).get("session_id")
if session_id is None:
raise ConnectionRefusedError("Session not configured")
await redis.set(f"socket_io_session:{session_id}", json.dumps(data), ex=3600)
+1 -1
View File
@@ -27,4 +27,4 @@ class WorkerSettings:
cron_jobs = [cron(clean_editor_images_up, hour={0, 6, 12, 18}, minute=0)] cron_jobs = [cron(clean_editor_images_up, hour={0, 6, 12, 18}, minute=0)]
on_startup = startup on_startup = startup
on_shutdown = shutdown on_shutdown = shutdown
redis_settings = RedisSettings.from_dsn(settings.redis) redis_settings = RedisSettings.from_dsn(str(settings.redis))
+5 -5
View File
@@ -35,7 +35,7 @@ services:
MEILISEARCH_URL: "http://meilisearch:7700" # DON'T CHANGE MEILISEARCH_URL: "http://meilisearch:7700" # DON'T CHANGE
# -- DON'T CHANGE TILL HERE --- # -- DON'T CHANGE TILL HERE ---
# --- GENERAL CONFI --- # --- GENERAL CONFIG ---
ROOT_ADDRESS: "https://classquiz.de" # CHANGE IT (without a "/" at the end) ROOT_ADDRESS: "https://classquiz.de" # CHANGE IT (without a "/" at the end)
# --- MAIL CONFIG --- # --- MAIL CONFIG ---
@@ -43,11 +43,11 @@ services:
MAIL_ADDRESS: "email@email@email.email" MAIL_ADDRESS: "email@email@email.email"
MAIL_PASSWORD: "PASSWORT" MAIL_PASSWORD: "PASSWORT"
MAIL_USERNAME: "email@email@email.email" MAIL_USERNAME: "email@email@email.email"
MAIL_SERVER: "email@email@email.emai" MAIL_SERVER: "smtp.email.email"
SKIP_EMAIL_VERIFICATION: "True" # Does the user have to confirm its email by clicking a link? SKIP_EMAIL_VERIFICATION: "True" # Does the user have to confirm its email by clicking a link?
# --- EXTERNAL API CONFIG --- # --- EXTERNAL API CONFIG ---
# HCAPTCHA_KEY: "HCAPTCHA_PRIVATE_KEY" # HCAPTCHA_KEY: ""
# PIXABAY_API_KEY: "" # Get it from here: https://pixabay.com/api/docs/ # PIXABAY_API_KEY: "" # Get it from here: https://pixabay.com/api/docs/
# RECAPTCHA_KEY: "" Get it from Google for the Captcha. # RECAPTCHA_KEY: "" Get it from Google for the Captcha.
@@ -73,7 +73,7 @@ services:
#CUSTOM_OPENID_PROVIDER__SERVER_METADATA_URL: "/.well-known/openid-configuration" # Adjust if needed #CUSTOM_OPENID_PROVIDER__SERVER_METADATA_URL: "/.well-known/openid-configuration" # Adjust if needed
volumes: # Only needed if you chose the "local" storage-backend volumes: # Only needed if you chose the "local" storage-backend
- ./uploads:/var/storage - ./uploads:/app/data
redis: redis:
image: redis:alpine image: redis:alpine
@@ -105,7 +105,7 @@ services:
image: getmeili/meilisearch:v0.28.0 image: getmeili/meilisearch:v0.28.0
restart: always restart: always
environment: environment:
MEILI_NO_ANALYTICS: true MEILI_NO_ANALYTICS: "true"
volumes: volumes:
- meilisearch-data:/data.ms - meilisearch-data:/data.ms
worker: worker:
+2 -1
View File
@@ -12,10 +12,11 @@ ENV REDIS_URL=redis://localhost:6379
ENV VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoibWF3b2thIiwiYSI6ImNsMjBob3d4ZjBhcGszYnE0bWp4aXB1ZW4ifQ.IByxV1qeIuEWpHCWsuB88A ENV VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoibWF3b2thIiwiYSI6ImNsMjBob3d4ZjBhcGszYnE0bWp4aXB1ZW4ifQ.IByxV1qeIuEWpHCWsuB88A
# This Mapbox-token is restricted to the following urls: classquiz.de, classquiz.mawoka.eu, test.com # This Mapbox-token is restricted to the following urls: classquiz.de, classquiz.mawoka.eu, test.com
ENV VITE_HCAPTCHA=ee81b2a1-acf3-4d20-b2a4-a7ea94c7eba5 ENV VITE_HCAPTCHA=ee81b2a1-acf3-4d20-b2a4-a7ea94c7eba5
# Hacaptcha secret ES_e0f8139cb5ad467d892e8d73a020cd2b
# ENV VITE_SENTRY=https://75cb4ef1be624d8f81bbaf864b722f8a@glitch.mawoka.eu/2 # ENV VITE_SENTRY=https://75cb4ef1be624d8f81bbaf864b722f8a@glitch.mawoka.eu/2
#ENV VITE_GOOGLE_AUTH_ENABLED=true #ENV VITE_GOOGLE_AUTH_ENABLED=true
#ENV VITE_GITHUB_AUTH_ENABLED=true #ENV VITE_GITHUB_AUTH_ENABLED=true
#ENV VITE_CAPTCHA_ENABLED=true ENV VITE_CAPTCHA_ENABLED=false
#ENV VITE_REGISTRATION_DISABLED=True #ENV VITE_REGISTRATION_DISABLED=True
#ENV VITE_PLAUSIBLE_DATA_URL= #ENV VITE_PLAUSIBLE_DATA_URL=
# change working directory # change working directory
+6 -6
View File
@@ -16,12 +16,12 @@
}, },
"devDependencies": { "devDependencies": {
"@beyonk/svelte-mapbox": "^9.0.5", "@beyonk/svelte-mapbox": "^9.0.5",
"@ckeditor/ckeditor5-autoformat": "^37.1.0", "@ckeditor/ckeditor5-autoformat": "^41.1.0",
"@ckeditor/ckeditor5-basic-styles": "^37.1.0", "@ckeditor/ckeditor5-basic-styles": "^41.1.0",
"@ckeditor/ckeditor5-build-balloon": "^37.1.0", "@ckeditor/ckeditor5-build-balloon": "^41.1.0",
"@ckeditor/ckeditor5-editor-balloon": "^37.1.0", "@ckeditor/ckeditor5-editor-balloon": "^41.1.0",
"@ckeditor/ckeditor5-essentials": "^37.1.0", "@ckeditor/ckeditor5-essentials": "^41.1.0",
"@ckeditor/ckeditor5-theme-lark": "^37.1.0", "@ckeditor/ckeditor5-theme-lark": "^41.1.0",
"@felte/reporter-tippy": "^1.1.5", "@felte/reporter-tippy": "^1.1.5",
"@felte/validator-yup": "^1.0.11", "@felte/validator-yup": "^1.0.11",
"@ffmpeg/core": "^0.11.0", "@ffmpeg/core": "^0.11.0",
+6415 -4744
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -130,7 +130,7 @@ SPDX-License-Identifier: MPL-2.0
{/if} {/if}
{/if} {/if}
<br /> <br />
{#if timer_res === '0' && JSON.stringify(final_results) === JSON.stringify( [null] ) && quiz_data.questions[selected_question].type !== QuizQuestionType.SLIDE && question_results !== null} {#if timer_res === '0' && JSON.stringify(final_results) === JSON.stringify( [null] ) && quiz_data.questions[selected_question].type !== QuizQuestionType.SLIDE && question_results !== null && quiz_data.questions[selected_question]?.hide_results !== true}
{#if question_results === undefined} {#if question_results === undefined}
{#if !final_results_clicked} {#if !final_results_clicked}
<div class="w-full flex justify-center"> <div class="w-full flex justify-center">
@@ -4,6 +4,10 @@ SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0 SPDX-License-Identifier: MPL-2.0
--> -->
<!--
This should be okay, right?
-->
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { tinykeys } from '$lib/tinykeys'; import { tinykeys } from '$lib/tinykeys';
@@ -194,7 +198,6 @@ SPDX-License-Identifier: MPL-2.0
}; };
const on_enter = (e: KeyboardEvent) => { const on_enter = (e: KeyboardEvent) => {
e.preventDefault();
if (selected === null) { if (selected === null) {
return; return;
} }
@@ -231,6 +234,7 @@ SPDX-License-Identifier: MPL-2.0
<div <div
class="fixed top-0 left-0 w-screen h-screen flex bg-black bg-opacity-50 z-50" class="fixed top-0 left-0 w-screen h-screen flex bg-black bg-opacity-50 z-50"
on:click={close_on_outside} on:click={close_on_outside}
on:keyup={close_on_outside}
transition:fade={{ duration: 60 }} transition:fade={{ duration: 60 }}
> >
<div class="m-auto w-1/3 h-2/3 rounded bg-black flex flex-col"> <div class="m-auto w-1/3 h-2/3 rounded bg-black flex flex-col">
@@ -242,7 +246,6 @@ SPDX-License-Identifier: MPL-2.0
</p> </p>
<input <input
type="text" type="text"
autofocus
class="col-start-1 row-start-1 bg-transparent w-full p-4 outline-none bg-gray-700 rounded" class="col-start-1 row-start-1 bg-transparent w-full p-4 outline-none bg-gray-700 rounded"
bind:value={input} bind:value={input}
/> />
+56 -6
View File
@@ -11,23 +11,27 @@ SPDX-License-Identifier: MPL-2.0
import { reach } from 'yup'; import { reach } from 'yup';
import { dataSchema } from '$lib/yupSchemas'; import { dataSchema } from '$lib/yupSchemas';
import Spinner from '../Spinner.svelte'; import Spinner from '../Spinner.svelte';
// import { createTippy } from 'svelte-tippy'; import { createTippy } from 'svelte-tippy';
import { getLocalization } from '$lib/i18n'; import { getLocalization } from '$lib/i18n';
import MediaComponent from '$lib/editor/MediaComponent.svelte'; import MediaComponent from '$lib/editor/MediaComponent.svelte';
import { fade } from 'svelte/transition';
import BrownButton from '$lib/components/buttons/brown.svelte';
// import MediaComponent from "$lib/editor/MediaComponent.svelte"; // import MediaComponent from "$lib/editor/MediaComponent.svelte";
const { t } = getLocalization(); const { t } = getLocalization();
/* const tippy = createTippy({ const tippy = createTippy({
arrow: true, arrow: true,
animation: 'perspective-subtle', animation: 'perspective-subtle',
placement: 'top' placement: 'top'
});*/ });
export let data: EditorData; export let data: EditorData;
export let selected_question: number; export let selected_question: number;
export let edit_id: string; export let edit_id: string;
let advanced_options_open = false;
let uppyOpen = false; let uppyOpen = false;
let unique = {}; let unique = {};
@@ -93,6 +97,33 @@ SPDX-License-Identifier: MPL-2.0
<span <span
class="inline-block bg-gray-600 w-4 h-4 rounded-full hover:bg-green-400 transition" class="inline-block bg-gray-600 w-4 h-4 rounded-full hover:bg-green-400 transition"
/> />
<button
class="ml-auto"
type="button"
use:tippy={{ content: $t('editor.advanced_settings') }}
on:click={() => (advanced_options_open = true)}
>
<svg
class="text-white w-5 h-5"
aria-hidden="true"
fill="none"
stroke="white"
stroke-width="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>
</button>
</div> </div>
</div> </div>
{#if data.questions[selected_question].type === QuizQuestionType.SLIDE} {#if data.questions[selected_question].type === QuizQuestionType.SLIDE}
@@ -233,3 +264,22 @@ SPDX-License-Identifier: MPL-2.0
{/if} {/if}
</div> </div>
</div> </div>
{#if advanced_options_open}
<div
class="fixed top-0 left-0 w-full h-full bg-black/60 flex"
transition:fade={{ duration: 150 }}
>
<div class="w-1/4 h-1/3 m-auto bg-white dark:bg-gray-700 rounded-lg flex flex-col p-2 gap-2">
<h1 class="text-3xl mx-auto">{$t('editor.advanced_settings')}</h1>
<label class="flex justify-around text-lg">
<span class="my-auto">{$t('editor.hide_question_results')}</span>
<input type="checkbox" bind:checked={data.questions[selected_question]["hide_results"]} />
</label>
<div class="mt-auto w-full">
<BrownButton on:click={() => (advanced_options_open = false)}>{$t('words.close')}</BrownButton>
</div>
</div>
</div>
{/if}
+49 -45
View File
@@ -144,7 +144,7 @@
"login": "تسجيل الدخول", "login": "تسجيل الدخول",
"create": "صنع", "create": "صنع",
"report": "تقرير", "report": "تقرير",
"quiztivity": "", "quiztivity": "مسابقة",
"library": "المكتبة", "library": "المكتبة",
"finish": "إنهاء", "finish": "إنهاء",
"normal": "عادي", "normal": "عادي",
@@ -170,36 +170,40 @@
"success_update_title": "تم تحديث الاختبار." "success_update_title": "تم تحديث الاختبار."
}, },
"admin_page": { "admin_page": {
"stop_time_and_solutions": "", "stop_time_and_solutions": "توقف وشاهد الحلول",
"already_registered_as_admin": "يوجد بالفعل مسؤول مسجل لهذه اللعبة.", "already_registered_as_admin": "يوجد بالفعل مسؤول مسجل لهذه اللعبة.",
"no_answers": "", "no_answers": "لا يوجد إجابة!",
"start_by_showing_first_question": "", "start_by_showing_first_question": "ابدأ وشاهد السؤال الأول",
"request_export_results": "", "request_export_results": "اطلب تنزيل النتيجة",
"time_left": "الوقت المتبقي", "time_left": "الوقت المتبقي",
"show_next_question": "", "show_next_question": "السؤال التالي",
"stop_time": "", "stop_time": "زمن الوقوف",
"show_results": "", "show_results": "عرض النتائج",
"save_results": "", "save_results": "احفظ النتيجة",
"enter_answer_into_field": "", "enter_answer_into_field": "أدخل إجابتك في الحقل!",
"get_results_and_stop_time": "", "get_results_and_stop_time": "توقف واحصل على النتيجة",
"start_game": "بدء اللعبة", "start_game": "بدء اللعبة",
"answers_submitted": "", "answers_submitted": "الإجابات المسلّمة {{answer_count}}",
"download_export_results": "", "download_export_results": "تنزيل النتائج",
"next_question": "", "next_question": "السؤال التالي ({{question}})",
"get_results": "الحصول على النتائج", "get_results": "الحصول على النتائج",
"get_final_results": "" "get_final_results": "النتيجة النهائية",
"export_results": "تصدير النتائج"
}, },
"play_page": { "play_page": {
"2nd_place": "", "2nd_place": "المركز الثاني",
"join_description": "", "join_description": "انضم عن طريق الرابط {{url}} وأدخل {{pin}}.",
"1st_place": "", "1st_place": "المركز الأول",
"points_added": "", "points_added": "نقاط مضافة",
"final_result_rank": "", "final_result_rank": "المركز: {{username}}، النقاط {{points}} نقطة",
"your_score": "", "your_score": "نتيجتك: {{score}}",
"end_sentence": "", "end_sentence": "أخيراّ ،انتهت المسابقة.",
"with_out_of": "", "with_out_of": "تم {{correct_questions}} من أصل {{total_question_count}}",
"3rd place": "", "3rd place": "المركز الثالث",
"join_by_entering_code": "" "join_by_entering_code": "انضم عن طريق اخال الرقم التالي",
"your_place": "أنت في المركز {{place}}!",
"players_waiting": "هناك {{count}} لاعب ينتظرون",
"players_waiting_plural": "{{count}} من اللاعبين ينتظرون"
}, },
"file_dashboard": { "file_dashboard": {
"unset": "", "unset": "",
@@ -240,17 +244,17 @@
"no_quizzes": "انقر فوق الزر \"إنشاء\" أو قم باستيراد اختبار للبدء." "no_quizzes": "انقر فوق الزر \"إنشاء\" أو قم باستيراد اختبار للبدء."
}, },
"settings_page": { "settings_page": {
"change_avatar": "", "change_avatar": "تغيير الصورة الرمزية",
"change_password_submit": "", "change_password_submit": "تغيير كلمة المرور!",
"security_settings": "", "security_settings": "إعدادت الأمان",
"delete_this_session": "", "delete_this_session": "حذف هذه الجلسة",
"old_password": "", "old_password": "كلمة المرور القديمة",
"check_location": "", "check_location": "تأكد من الموقع",
"last_seen": "", "last_seen": "زمن آخر ظهور",
"this_session?": "", "this_session?": "هذه الجلسة؟",
"repeat_password": "", "repeat_password": "أعد كلمة المرور",
"new_password": "", "new_password": "كلمة مرور جديدة",
"add_api_key": "" "add_api_key": "أضف مفتاح API"
}, },
"footer": { "footer": {
"donate": "", "donate": "",
@@ -413,15 +417,15 @@
"welcome_back": "مرحبًا بعودتك!" "welcome_back": "مرحبًا بعودتك!"
}, },
"password_reset_page": { "password_reset_page": {
"reset_password": "" "reset_password": "إعادة تعيين كلمة المرور"
}, },
"video_uploader": { "video_uploader": {
"time_remaining": "", "time_remaining": "",
"time_elapsed": "" "time_elapsed": ""
}, },
"explore_page": { "explore_page": {
"imported_by": "", "imported_by": "تم استيراده عن طريق",
"made_by": "" "made_by": "تم عن طريق"
}, },
"create_page": { "create_page": {
"success": { "success": {
@@ -446,21 +450,21 @@
"upload_video": "" "upload_video": ""
}, },
"search_page": { "search_page": {
"nothing_here": "", "nothing_here": "لا يوجد شيء هنا ...",
"at_least_3_characters": "" "at_least_3_characters": "أدخل على الأقل ثلاث محارف .."
}, },
"dashboard": { "dashboard": {
"commandpalette_notice": "", "commandpalette_notice": "",
"views_n_plays": "", "views_n_plays": "المشاهدات و الألعاب",
"search_for_own_quizzes": "", "search_for_own_quizzes": "ابحث عن مسابقاتك الخاصة",
"info_analytics": "" "info_analytics": ""
}, },
"navbar": { "navbar": {
"donate": "" "donate": ""
}, },
"editor_page": { "editor_page": {
"add_an_answer": "", "add_an_answer": "أضف إجابة",
"right_click_to_delete": "" "right_click_to_delete": "انقر بالزر الأيمن على الإجابة ليتم حذفها!"
}, },
"public_user_page": { "public_user_page": {
"no_original_quizzes": "", "no_original_quizzes": "",
+30 -30
View File
@@ -150,50 +150,50 @@
"index_page": { "index_page": {
"meta": { "meta": {
"title": "Inici", "title": "Inici",
"description": "ClassQuiz és una aplicació de preguntes i respostes com KAHOOT! per a estudiants, que és de codi obert i d'ús gratuït" "description": "ClassQuiz és una aplicació de qüestionaris interactius d'aprenentatge, per a estudiants, de codi obert i d'ús gratuït"
}, },
"features_description": { "features_description": {
"1": "ClassQuiz és una plataforma de preguntes i respostes que us permet crear i gestionar qüestionaris.", "1": "ClassQuiz és una plataforma de preguntes i respostes que us permet crear i gestionar qüestionaris.",
"2": "La principal característica és una funció d'importació de KAHOOT! que us permet d'importar qüestionaris de KAHOOT!" "2": "La principal característica és una funció d'importació de KAHOOT! que us permet d'importar qüestionaris de KAHOOT!"
}, },
"stats": "Ja hi ha {{user_count}} usuaris i {{quiz_count}} qüestionaris a ClassQuiz.", "stats": "Ja hi ha {{user_count}} usuaris i {{quiz_count}} qüestionaris a ClassQuiz.",
"slogan": "La plataforma de preguntes i respostes de codi obert!", "slogan": "La plataforma de qüestionaris de codi obert!",
"quiz_results_downloadable": "", "quiz_results_downloadable": "Els resultats dels qüestionaris es poden descarregar",
"how_does_classquiz_work": "", "how_does_classquiz_work": "",
"select_answer": "", "select_answer": "Selecciona la resposta",
"user_friendly": "", "user_friendly": "D'ús amigable",
"no_tracking": "", "no_tracking": "Sense seguiment",
"find_or_explore": "", "find_or_explore": "Cerca (o explora) qüestionaris fets o importats per altres persones",
"see_how_many_true_and_false": "", "see_how_many_true_and_false": "Mostra quants l'han encertat o s'han equivocat",
"download_quizzes": "", "download_quizzes": "",
"dark_mode_content": "", "dark_mode_content": "",
"multilingual": "", "multilingual": "Multilingüe",
"community_driven_content": "", "community_driven_content": "",
"get_a_quiz": "", "get_a_quiz": "1. Obté un qüestionari",
"quiz_results_downloadable_content": "", "quiz_results_downloadable_content": "",
"view_results": "", "view_results": "Mostra els resultats",
"choose_answer_wisely": "", "choose_answer_wisely": "Escull bé la teva resposta",
"self_hostable_content": "", "self_hostable_content": "ClassQuiz es pot autoallotjar fàcilment, de manera que les dades queden totalment sota el vostre control!",
"german_server_content": "", "german_server_content": "",
"get_ranking_and_winners": "", "get_ranking_and_winners": "Obté la classificació i mira qui ha guanyat",
"list_winners": "", "list_winners": "Mostra qui ha guanyat",
"students_site": "", "students_site": "Portal d'estudiants",
"self_hostable": "", "self_hostable": "Autoallotjable",
"see_what_true_and_false": "", "see_what_true_and_false": "Mostra què era correcte o incorrecte",
"german_server": "", "german_server": "Servidor a Alemanya",
"create_a_quiz_from_scratch": "", "create_a_quiz_from_scratch": "Crea un qüestionari des de zero amb l'editor, incloent-hi imatges i més coses",
"teachers_site": "", "teachers_site": "Portal de docents",
"check_if_chosen_wisely": "", "check_if_chosen_wisely": "Comprova si has escollit bé",
"create_or_import": "", "create_or_import": "Crea o importa",
"dark_mode": "", "dark_mode": "Mode fosc",
"why_classquiz": "", "why_classquiz": "Per què ClassQuiz?",
"community_driven": "", "community_driven": "",
"play_quiz": "", "play_quiz": "2. Resol el qüestionari",
"see_all_quizzes": "", "see_all_quizzes": "Mostra tots els teus qüestionaris",
"completely_free": "", "completely_free": "Completament gratuït",
"completely_free_content": "", "completely_free_content": "",
"user_friendly_content": "", "user_friendly_content": "ClassQuiz pretén ser senzill, per tal de poder ser emprat per tothom.",
"no_tracking_content": "", "no_tracking_content": "Altres aplicacions registren el que feu i envien aquesta informació a terceres parts. ClassQuiz no ho fa.",
"multilingual_content": "", "multilingual_content": "",
"download_quizzes_content": "" "download_quizzes_content": ""
}, },
+2 -2
View File
@@ -122,7 +122,7 @@
}, },
"index_page": { "index_page": {
"quiz_results_downloadable": "", "quiz_results_downloadable": "",
"slogan": "", "slogan": "Open-source kvízová platforma!",
"completely_free": "", "completely_free": "",
"how_does_classquiz_work": "", "how_does_classquiz_work": "",
"select_answer": "", "select_answer": "",
@@ -144,7 +144,7 @@
"german_server_content": "", "german_server_content": "",
"get_ranking_and_winners": "", "get_ranking_and_winners": "",
"meta": { "meta": {
"description": "", "description": "ClassQuiz je kvízová aplikace podobná aplikaci Kahoot! pro studenty, která má otevřený zdrojový kód a je zdarma.",
"title": "" "title": ""
}, },
"list_winners": "", "list_winners": "",
+3 -1
View File
@@ -231,7 +231,9 @@
"enter_answer": "Gib eine Antwort ein", "enter_answer": "Gib eine Antwort ein",
"visit_docs": "Besuche die Dokumentation.", "visit_docs": "Besuche die Dokumentation.",
"enable_reorder": "Fragen Umsortieren", "enable_reorder": "Fragen Umsortieren",
"disable_reorder": "Umsortieren beenden" "disable_reorder": "Umsortieren beenden",
"advanced_settings": "Erweiterte Einstellungen",
"hide_question_results": "Frageergebnisse ausblenden?"
}, },
"import": { "import": {
"need_help": "", "need_help": "",
+4 -2
View File
@@ -46,7 +46,7 @@
"how_does_classquiz_work": "How does ClassQuiz even work?", "how_does_classquiz_work": "How does ClassQuiz even work?",
"no_player_limit": "No player limit", "no_player_limit": "No player limit",
"no_player_limit_content": "ClassQuiz doesn't have an artificial player limit. In theory, 1000+ players could play the same quiz, but it's tested with up to 300 players per quiz.", "no_player_limit_content": "ClassQuiz doesn't have an artificial player limit. In theory, 1000+ players could play the same quiz, but it's tested with up to 300 players per quiz.",
"import_quiz_from_kahoot_and_edit": "" "import_quiz_from_kahoot_and_edit": "Import quizzes from Kahoot! and edit them in ClassQuiz"
}, },
"overview_page": { "overview_page": {
"created_at": "Created at", "created_at": "Created at",
@@ -226,7 +226,9 @@
"visit_docs": "Visit the docs.", "visit_docs": "Visit the docs.",
"enter_answer": "Enter an answer", "enter_answer": "Enter an answer",
"enable_reorder": "Enable reorder mode", "enable_reorder": "Enable reorder mode",
"disable_reorder": "Disable reorder mode" "disable_reorder": "Disable reorder mode",
"advanced_settings": "Advanced Settings",
"hide_question_results": "Hide question resuluts?"
}, },
"import_page": { "import_page": {
"need_help": "Need help?", "need_help": "Need help?",
+3 -1
View File
@@ -293,7 +293,9 @@
"enter_answer": "Escribe una respuesta", "enter_answer": "Escribe una respuesta",
"visit_docs": "Visita los documentos.", "visit_docs": "Visita los documentos.",
"disable_reorder": "Desactivar el modo reordenar", "disable_reorder": "Desactivar el modo reordenar",
"enable_reorder": "Activar el modo reordenar" "enable_reorder": "Activar el modo reordenar",
"hide_question_results": "¿Ocultar los resultados de la pregunta?",
"advanced_settings": "Ajustes avanzados"
}, },
"import_page": { "import_page": {
"need_help": "¿Necesitas ayuda?", "need_help": "¿Necesitas ayuda?",
+12
View File
@@ -0,0 +1,12 @@
{
"index_page": {
"slogan": "Avatud tarkvaral põhinev mälumängu- ja küsitlusplatvorm!",
"meta": {
"title": "Avaleht",
"description": "ClassQuiz on avatud lähtekoodiga ja vaba tarkvara, mis pakub võimaluse korraldada õpilatele ning muudele huvilistele interaktiivseid mälumänge, viktoriine ja küsitlusi"
},
"stats": "ClassQuizis on juba {{user_count}} kasutajat ning {{quiz_count}} mängu.",
"teachers_site": "Õpetaja vaade",
"students_site": "Õpilase vaade"
}
}
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
+34
View File
@@ -0,0 +1,34 @@
{
"index_page": {
"meta": {
"description": "ClassQuiz ikasleentzat modu interaktiboan ikasteko galdera-lehiaketa aplikazio bat da, kode irekikoa eta doakoa dena",
"title": "Hasiera"
},
"completely_free": "Dohainik",
"german_server": "Zerbitzari alemana",
"dark_mode": "Modu iluna",
"user_friendly": "Erabilerraza",
"select_answer": "Erantzuna hautatu",
"find_or_explore": "Bilatu (edo esploratu) beste pertsona batzuek egindako edo inportatutako galdetegiak",
"stats": "Dagoeneko{{user_count}} erabiltzaile eta {{quiz_count}} galdetegi daude.",
"see_what_true_and_false": "Ikusi zeintzuk diren okerrak eta zeintzuk zuzenak",
"see_how_many_true_and_false": "Ikusi zenbat diren zuzenak eta zenbat okerrak",
"see_all_quizzes": "Galdera-lehiaketa guztiak ikusi",
"teachers_site": "Irakaslearen lekua",
"students_site": "Ikaslearen lekua",
"no_tracking": "Ez du aztarnarik",
"self_hostable": "Auto hostagarri",
"quiz_results_downloadable": "Lehiaketaren emaitzak deskargatu daitezke",
"get_a_quiz": "1. Lortu lehiaketa",
"play_quiz": "2. Jolastu",
"choose_answer_wisely": "Aukeratu zure erantzuna zentzuz",
"view_results": "Emaitzak ikusi",
"list_winners": "Irabazleen zerrenda",
"get_ranking_and_winners": "Rankinga lortu eta ikusi zeinek irabazi duen",
"slogan": "Kode irekiko galdera-lehiaketa plataforma!",
"create_or_import": "Sortu edo Inportatu",
"create_a_quiz_from_scratch": "Editorearekin hutsetik galdetegi bat sortu eta irudiak eta gehiago sartu",
"check_if_chosen_wisely": "Egiaztatu, zuhur aukeratu duzun",
"multilingual": "Hizkuntza anitzak"
}
}
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
+34 -14
View File
@@ -31,7 +31,7 @@
"get_a_quiz": "1. Ottieni un quiz", "get_a_quiz": "1. Ottieni un quiz",
"create_a_quiz_from_scratch": "Crea un quiz da zero con l'editor, includi immagini e altro ancora", "create_a_quiz_from_scratch": "Crea un quiz da zero con l'editor, includi immagini e altro ancora",
"find_or_explore": "Trova (o esplora) dei quiz fatti o importati da altre persone", "find_or_explore": "Trova (o esplora) dei quiz fatti o importati da altre persone",
"import_quiz_from_kahoot_and_edit": "Importa un quiz da Kahoot! e modificalo su ClassQuiz", "import_quiz_from_kahoot_and_edit": "Importa quiz da Kahoot! e modificali in ClassQuiz",
"play_quiz": "2. Gioca al quiz", "play_quiz": "2. Gioca al quiz",
"select_answer": "Seleziona la risposta", "select_answer": "Seleziona la risposta",
"choose_answer_wisely": "Scegli la risposta attentamente", "choose_answer_wisely": "Scegli la risposta attentamente",
@@ -49,7 +49,9 @@
"community_driven": "Guidati dalla comunità", "community_driven": "Guidati dalla comunità",
"community_driven_content": "ClassQuiz dipende dalla sua comunità per finanziamenti, idee di test, richieste di funzionalità, traduzioni e altro! Anche tu puoi far parte della comunità di ClassQuiz!", "community_driven_content": "ClassQuiz dipende dalla sua comunità per finanziamenti, idee di test, richieste di funzionalità, traduzioni e altro! Anche tu puoi far parte della comunità di ClassQuiz!",
"completely_free_content": "ClassQuiz è completamente gratuito (per l'utente), senza piani a pagamento o fastidiose richieste di aggiornamento. Le donazioni sono molto apprezzate.", "completely_free_content": "ClassQuiz è completamente gratuito (per l'utente), senza piani a pagamento o fastidiose richieste di aggiornamento. Le donazioni sono molto apprezzate.",
"how_does_classquiz_work": "Come funziona ClassQuiz?" "how_does_classquiz_work": "Come funziona ClassQuiz?",
"no_player_limit": "Nessun limite di giocatori",
"no_player_limit_content": "ClassQuiz non ha un limite artificiale di giocatori. In teoria, 1000+ giocatori potrebbero giocare allo stesso quiz, ma è stato testato con un massimo di 300 giocatori per quiz."
}, },
"overview_page": { "overview_page": {
"created_at": "Creato il", "created_at": "Creato il",
@@ -197,7 +199,8 @@
"dislike_plural": "Non mi piace", "dislike_plural": "Non mi piace",
"dislike": "Non mi piace", "dislike": "Non mi piace",
"like_plural": "Mi piace", "like_plural": "Mi piace",
"check_choice": "" "check_choice": "Controlla la scelta",
"player": "Giocatore"
}, },
"editor": { "editor": {
"right_or_true?": "Corretto?", "right_or_true?": "Corretto?",
@@ -223,7 +226,14 @@
"empty": "Vuoto...", "empty": "Vuoto...",
"abcd_description": "Si può scegliere solo una risposta", "abcd_description": "Si può scegliere solo una risposta",
"bg_image": "Immagine di sfondo", "bg_image": "Immagine di sfondo",
"no_title": "Nessun titolo..." "no_title": "Nessun titolo...",
"visit_docs": "Visita la documentazione.",
"enter_answer": "Inserisci una risposta",
"need_more_help": "Hai bisogno di ulteriore aiuto?",
"disable_reorder": "Disabilita la modalità di riordino",
"enable_reorder": "Abilita la modalità di riordino",
"hide_question_results": "Nascondere i risultati della domanda?",
"advanced_settings": "Impostazioni avanzate"
}, },
"import_page": { "import_page": {
"need_help": "Hai bisogno di aiuto?", "need_help": "Hai bisogno di aiuto?",
@@ -234,7 +244,7 @@
"a_kahoot_quiz": "Un quiz di Kahoot", "a_kahoot_quiz": "Un quiz di Kahoot",
"classquiz_quiz": "Un quiz di ClassQuiz", "classquiz_quiz": "Un quiz di ClassQuiz",
"upload_file_ending": "Carica il file che termina con .cqa o .xlsx", "upload_file_ending": "Carica il file che termina con .cqa o .xlsx",
"this_side_classquiz_excel": "Puoi anche caricare un file excel se hai compilato il seguente modello.", "this_side_classquiz_excel": "Puoi anche caricare file excel, se hai compilato il seguente modello. Se esiste già un quiz con il titolo, aggiungerà le domande al quiz esistente.",
"download_template_here": "Scarica il modello" "download_template_here": "Scarica il modello"
}, },
"admin_page": { "admin_page": {
@@ -288,7 +298,10 @@
"points_added": "Punti aggiunti", "points_added": "Punti aggiunti",
"final_result_rank": "{{place}}: {{username}} con {{points}} punti", "final_result_rank": "{{place}}: {{username}} con {{points}} punti",
"your_score": "Il tuo punteggio: {{score}}", "your_score": "Il tuo punteggio: {{score}}",
"join_by_entering_code": "Entra inserendo il seguente codice" "join_by_entering_code": "Entra inserendo il seguente codice",
"players_waiting": "{{count}} giocatore è in attesa",
"players_waiting_plural": "{{count}} giocatori sono in attesa",
"your_place": "Sei nel posto {{place}}!"
}, },
"editor_page": { "editor_page": {
"add_an_answer": "Aggiungi una risposta", "add_an_answer": "Aggiungi una risposta",
@@ -363,7 +376,7 @@
"security_settings": { "security_settings": {
"get_backup_code": "Ottieni codice backup", "get_backup_code": "Ottieni codice backup",
"enable_totp": "Abilita TOTP", "enable_totp": "Abilita TOTP",
"disable_totp": "Disabilita Totp", "disable_totp": "Disabilita TOTP",
"backup_code": "Codice backp", "backup_code": "Codice backp",
"2fa_deactivated": "L'autenticazione a due fattori è disattivata", "2fa_deactivated": "L'autenticazione a due fattori è disattivata",
"backup_codes": { "backup_codes": {
@@ -371,21 +384,21 @@
"your_backup_code": "Il tuo codice di backup", "your_backup_code": "Il tuo codice di backup",
"save_somewhere_save": "Salvalo in un posto sicuro!" "save_somewhere_save": "Salvalo in un posto sicuro!"
}, },
"totp_unavailable": "Totp non è disponibile", "totp_unavailable": "TOTP non è disponibile",
"2fa_activated": "L'autenticazione a due fattori è attivata", "2fa_activated": "L'autenticazione a due fattori è attivata",
"add_security_key": "Aggiungi una chiave di sicurezza", "add_security_key": "Aggiungi una chiave di sicurezza",
"activate_2fa": "Attiva autenticazione a due fattori", "activate_2fa": "Attiva autenticazione a due fattori",
"webauthn_unavailable": "Webauthn non è disponibile", "webauthn_unavailable": "Webauthn non è disponibile",
"totp_available": "Totp è disponibile", "totp_available": "TOTP è disponibile",
"webauthn_available": "Webauthn è disponibile", "webauthn_available": "Webauthn è disponibile",
"totp_setup": { "totp_setup": {
"do_not_forget_backup_code": "Non dimenticare di salvare il tuo codice di recupero!", "do_not_forget_backup_code": "Non dimenticare di salvare il tuo codice di recupero!",
"enter_as_secret_if_no_see_code": "Inserisci questo come segreto se non puoi scansionare il codice QR", "enter_as_secret_if_no_see_code": "Inserisci questo come segreto se non puoi scansionare il codice QR",
"scan_to_set_up": "Scansiona questo codice QR per impostare il codice", "scan_to_set_up": "Scansiona questo codice QR per impostare il codice",
"totp_setup": "Impostazione Topt" "totp_setup": "Impostazione TOTP"
}, },
"webauthn": "Webauthn", "webauthn": "Webauthn",
"totp": "Password momentanea" "totp": "TOTP"
}, },
"view_quiz_page": { "view_quiz_page": {
"made_by": "Creato da", "made_by": "Creato da",
@@ -444,7 +457,7 @@
"file_dashboard": { "file_dashboard": {
"unset": "Non impostato", "unset": "Non impostato",
"missing": "MANCANTE!", "missing": "MANCANTE!",
"size": "Dimensione: {{size}} Mb", "size": "Dimensione: {{size}} MiB",
"not_available": "Non disponibile", "not_available": "Non disponibile",
"caption": "Didascalia: {{caption}}", "caption": "Didascalia: {{caption}}",
"imported": "Importato: {{yes_or_no}}", "imported": "Importato: {{yes_or_no}}",
@@ -455,11 +468,12 @@
"delete_image": "Elimina immagine", "delete_image": "Elimina immagine",
"edit_the_image": "Modifica immagine", "edit_the_image": "Modifica immagine",
"alt_text": "Testo alternativo/Didascalia", "alt_text": "Testo alternativo/Didascalia",
"storage_usage": "Hai utilizzato {{used}} Mb su {{total}} Mb di spazio disponibile. Corrisponde a {{percent}}% dello spazio." "storage_usage": "Hai utilizzato {{used}} MiB su {{total}} MiB di spazio di archiviazione. Ciò equivale a {{percent}}% del tuo spazio di archiviazione."
}, },
"public_user_page": { "public_user_page": {
"no_original_quizzes": "Questo utente non ha nessun quiz originale", "no_original_quizzes": "Questo utente non ha nessun quiz originale",
"joined_on": "Iscritto il {{date}}" "joined_on": "Iscritto il {{date}}",
"user_not_found": "Utente non trovato"
}, },
"components": { "components": {
"popover": { "popover": {
@@ -469,5 +483,11 @@
"video_uploader": { "video_uploader": {
"time_remaining": "Tempo rimanente", "time_remaining": "Tempo rimanente",
"time_elapsed": "Tempo trascorso" "time_elapsed": "Tempo trascorso"
},
"downloader": {
"select_download_type": "Seleziona il tipo di download",
"own_format": "Formato proprio",
"excel_format": "Formato Excel",
"help": "Il formato (.cqa) include anche le immagini e supporta ogni tipo di domanda, mentre il formato Excel supporta solo domande a risposta multipla e il voto."
} }
} }
+5 -4
View File
@@ -199,7 +199,8 @@
"analytics": "Analityka", "analytics": "Analityka",
"dislike_plural": "Nie lubię", "dislike_plural": "Nie lubię",
"rating": "Ocena", "rating": "Ocena",
"like": "Lubię" "like": "Lubię",
"player": "Odtwarzacz"
}, },
"settings_page": { "settings_page": {
"last_seen": "Ostatnio widziany", "last_seen": "Ostatnio widziany",
@@ -388,7 +389,7 @@
"do_not_forget_backup_code": "Nie zapomnij zapisać swojego kodu odzyskiwania!", "do_not_forget_backup_code": "Nie zapomnij zapisać swojego kodu odzyskiwania!",
"scan_to_set_up": "Zeskanuj ten kod QR, aby ustawić kod", "scan_to_set_up": "Zeskanuj ten kod QR, aby ustawić kod",
"enter_as_secret_if_no_see_code": "Wpisz kod, jeśli nie możesz zeskanować kodu QR", "enter_as_secret_if_no_see_code": "Wpisz kod, jeśli nie możesz zeskanować kodu QR",
"totp_setup": "" "totp_setup": "Konfiguracja TOTP"
}, },
"webauthn_unavailable": "Webauthn nie jest dostępny", "webauthn_unavailable": "Webauthn nie jest dostępny",
"add_security_key": "Dodaj Security-Key", "add_security_key": "Dodaj Security-Key",
@@ -396,7 +397,7 @@
"webauthn": "Webauthn", "webauthn": "Webauthn",
"enable_totp": "Włącz Totp", "enable_totp": "Włącz Totp",
"disable_totp": "Wyłączenie Totp", "disable_totp": "Wyłączenie Totp",
"totp": "", "totp": "TOTP",
"totp_unavailable": "Totp nie jest dostępny", "totp_unavailable": "Totp nie jest dostępny",
"totp_available": "Totp jest dostępny" "totp_available": "Totp jest dostępny"
}, },
@@ -409,7 +410,7 @@
"normal_mode_description": "Pytanie i odpowiedź będą wyświetlane tylko na ekranie administratora, jak w Kahoot! Gracze będą mieli do dyspozycji jedynie kolorowe przyciski z symbolami odpowiadającymi tym na ekranie administratora.", "normal_mode_description": "Pytanie i odpowiedź będą wyświetlane tylko na ekranie administratora, jak w Kahoot! Gracze będą mieli do dyspozycji jedynie kolorowe przyciski z symbolami odpowiadającymi tym na ekranie administratora.",
"old_school_mode_description": "Pytania i obrazy będą wyświetlane zarówno na ekranie administratora, jak i na ekranie graczy", "old_school_mode_description": "Pytania i obrazy będą wyświetlane zarówno na ekranie administratora, jak i na ekranie graczy",
"start_game": "Rozpocznij grę", "start_game": "Rozpocznij grę",
"old_school_mode": "" "old_school_mode": "Retro"
}, },
"quiztivity": { "quiztivity": {
"editor": { "editor": {
+41 -39
View File
@@ -1,64 +1,64 @@
{ {
"words": { "words": {
"dashboard": "Painel", "dashboard": "Painel",
"search": "Pesquisa", "search": "Procurar",
"screenshot": "Captura de ecrã", "screenshot": "Captura de ecrã",
"screenshot_plural": "Capturas de Ecrã", "screenshot_plural": "Capturas de Tela",
"question_plural": "Perguntas", "question_plural": "Perguntas",
"note": "Nota", "note": "Nota",
"question": "Pergunta", "question": "Pergunta",
"answer": "Resposta", "answer": "Resposta",
"stats": "Estatísticas", "stats": "Estatísticas",
"features": "Características", "features": "Funcionalidades",
"login": "Iniciar sessão", "login": "Entrar",
"email": "Email", "email": "Endereço de email",
"password": "Password", "password": "Senha",
"edit": "Editar", "edit": "Editar",
"delete": "Apagar", "delete": "Apagar",
"public": "Público", "public": "Público",
"start": "Iniciar", "start": "Iniciar",
"create": "Criar", "create": "Criar",
"import": "Importar", "import": "Importar",
"logout": "Encerrar a sessão", "logout": "Sair",
"title": "Título", "title": "Título",
"url": "URL", "url": "URL",
"submit": "Submeter", "submit": "Enviar",
"connect": "Conectar", "connect": "Conectar",
"pin": "PIN", "pin": "PIN",
"register": "Registar-se", "register": "Inscrever-se",
"docs": "Documentos", "docs": "Documentos",
"close": "Fechar", "close": "Fechar",
"image": "Imagem", "image": "Imagem",
"settings": "Definições", "settings": "Definições",
"repeat_password": "Repetir password", "repeat_password": "Repetir a senha",
"overview": "Resumo", "overview": "Visão geral",
"explore": "Explorar", "explore": "Explorar",
"browser": "Navegador", "browser": "Navegador",
"view": "Ver", "view": "Ver",
"correct": "Correto", "correct": "Correto",
"result": "Resultado", "result": "Resultado",
"count": "Conta", "count": "Contagem",
"range": "Intervalo", "range": "Intervalo",
"multiple_choice": "Escolha múltipla", "multiple_choice": "Escolha múltipla",
"private": "Privado", "private": "Privado",
"other": "outro", "other": "outro",
"other_plural": "Outros", "other_plural": "outros",
"donating": "Doar", "donating": "doar",
"find": "Localizar", "find": "Localizar",
"practice": "Praticar", "practice": "Praticar",
"error": "Erro", "error": "Erro",
"voting": "Votar", "voting": "Votando",
"download": "Descarregar", "download": "Baixar",
"continue": "Continuar", "continue": "Continuar",
"totp": "password de uso único (Totp)", "totp": "password de uso único (Totp)",
"text": "Texto", "text": "Texto",
"order": "Ordenar", "order": "Ordem",
"results": "Resultados", "results": "Resultados",
"player_plural": "Jogadores", "player_plural": "Jogadores",
"score": "Pontuação", "score": "Pontuação",
"username": "Username", "username": "Usuário",
"play": "Jogar", "play": "Reproduzir",
"save": "Guardar", "save": "Salvar",
"description": "Descrição", "description": "Descrição",
"upload": "Upload", "upload": "Upload",
"next": "Próximo", "next": "Próximo",
@@ -89,14 +89,14 @@
"select": "Selecionar", "select": "Selecionar",
"like_plural": "Gosteis", "like_plural": "Gosteis",
"name": "Nome", "name": "Nome",
"report": "Denunciar", "report": "Relatório",
"quiztivity": "Quiztividade", "quiztivity": "Quiztividade",
"library": "Biblioteca", "library": "Biblioteca",
"finish": "Finalizar", "finish": "Finalizar",
"normal": "Normal", "normal": "Normal",
"selected": "Selecionado", "selected": "Selecionado",
"unknown": "Desconhecido", "unknown": "Desconhecido",
"back": "Voltar", "back": "Anterior",
"result_plural": "Resultados", "result_plural": "Resultados",
"never": "Nunca", "never": "Nunca",
"quiz": "Questionário", "quiz": "Questionário",
@@ -105,7 +105,7 @@
"index_page": { "index_page": {
"meta": { "meta": {
"title": "Início", "title": "Início",
"description": "ClassQuiz é uma aplicação de quiz para aprender de forma interactiva para os alunos, que é de código aberto e de utilização gratuita" "description": "ClassQuiz é uma aplicação de quiz para aprender de forma interativa para os estudantes, de código aberto e de utilização gratuita"
}, },
"features_description": { "features_description": {
"1": "ClassQuiz é uma plataforma de quiz que permite criar e gerir quizzes.", "1": "ClassQuiz é uma plataforma de quiz que permite criar e gerir quizzes.",
@@ -121,16 +121,16 @@
"students_site": "Portal do estudante", "students_site": "Portal do estudante",
"self_hostable": "Auto hospedagem", "self_hostable": "Auto hospedagem",
"german_server": "Servidor na Alemanha", "german_server": "Servidor na Alemanha",
"no_tracking": "Sem deixar rasto", "no_tracking": "Sem deixar rastro",
"user_friendly": "Fácil de usar", "user_friendly": "Fácil de usar",
"completely_free": "Completamente grátis", "completely_free": "Completamente grátis",
"quiz_results_downloadable": "Os resultados dos quizzes podem ser descarregados", "quiz_results_downloadable": "Os resultados dos quizzes podem ser descarregados",
"multilingual": "Multilingue", "multilingual": "Multilíngue",
"dark_mode": "Modo escuro", "dark_mode": "Modo escuro",
"get_a_quiz": "1. Obter um quiz", "get_a_quiz": "1. Obter um quiz",
"create_a_quiz_from_scratch": "Criar um quiz do zero com o editor, incluir imagens e mais", "create_a_quiz_from_scratch": "Criar um quiz do zero com o editor, incluir imagens e mais",
"find_or_explore": "Pesquisar (ou explorar) quizzes criados ou importados por outros", "find_or_explore": "Pesquisar (ou explorar) quizzes criados ou importados por outros",
"import_quiz_from_kahoot_and_edit": "importar um quiz Kahoot! e editá-lo em ClassQuiz", "import_quiz_from_kahoot_and_edit": "Importar um quiz Kahoot! e editá-lo em ClassQuiz",
"play_quiz": "2. Preencher o quiz", "play_quiz": "2. Preencher o quiz",
"select_answer": "Selecionar a resposta", "select_answer": "Selecionar a resposta",
"choose_answer_wisely": "Escolha a resposta cuidadosamente", "choose_answer_wisely": "Escolha a resposta cuidadosamente",
@@ -148,8 +148,8 @@
"community_driven": "Guiado pela comunidade", "community_driven": "Guiado pela comunidade",
"community_driven_content": "ClassQuiz depende da sua comunidade para o financiamento, testes, solicitação de funções, traduções e mais! Podes também fazer parte da comunidade ativa ClassQuiz!", "community_driven_content": "ClassQuiz depende da sua comunidade para o financiamento, testes, solicitação de funções, traduções e mais! Podes também fazer parte da comunidade ativa ClassQuiz!",
"slogan": "A plataforma de quiz código-aberto!", "slogan": "A plataforma de quiz código-aberto!",
"no_tracking_content": "Outros aplicativos gravam o seu perfil e o partilham com terceiros, mas ClassQuiz não.", "no_tracking_content": "Outros aplicativos gravam suas informações e compartilham com terceiros, mas ClassQuiz não.",
"completely_free_content": "ClassQuiz é gratuito para o utilizador, sem planos pagos nem redirecionamentos irritantes para versões paga.\nPortanto os donativos são bem-vindos.", "completely_free_content": "ClassQuiz é gratuito para o utilizador, sem planos pagos nem redirecionamentos irritantes para versões paga. Donativos são bem-vindos.",
"german_server_content": "Os servidores de ClassQuiz encontram-se na Alemanha e estão alojados com netcup.", "german_server_content": "Os servidores de ClassQuiz encontram-se na Alemanha e estão alojados com netcup.",
"download_quizzes_content": "Os questionários podem em qualquer altura, ser descarregados como um ficheiro único. Isto permite fácil migração para outras instâncias ClassQuiz.", "download_quizzes_content": "Os questionários podem em qualquer altura, ser descarregados como um ficheiro único. Isto permite fácil migração para outras instâncias ClassQuiz.",
"how_does_classquiz_work": "Como é que o ClassQuiz funciona?", "how_does_classquiz_work": "Como é que o ClassQuiz funciona?",
@@ -173,15 +173,15 @@
}, },
"register_page": { "register_page": {
"greeting": "Muito gosto em conhecê-lo!", "greeting": "Muito gosto em conhecê-lo!",
"create_account": "Criar uma conta", "create_account": "Criar conta",
"already_have_account?": "Já tem conta?", "already_have_account?": "Já tem uma conta?",
"forgot_password?": "Esqueceu-se da password?" "forgot_password?": "Esqueceu a senha?"
}, },
"login_page": { "login_page": {
"welcome_back": "Benvindo de volta.", "welcome_back": "Bem vindo de volta.",
"login_or_create_account": "Login ou criar uma conta", "login_or_create_account": "Login ou criar uma conta",
"already_have_account": "Ainda não tem conta?", "already_have_account": "Não possui uma conta?",
"email_or_username": "Email ou Username", "email_or_username": "Email ou Usuário",
"modal": { "modal": {
"success": { "success": {
"success": "Conectado.", "success": "Conectado.",
@@ -231,7 +231,9 @@
"visit_docs": "Veja a documentação.", "visit_docs": "Veja a documentação.",
"enter_answer": "Insira uma resposta", "enter_answer": "Insira uma resposta",
"disable_reorder": "Desativar modo reordenador", "disable_reorder": "Desativar modo reordenador",
"enable_reorder": "Ativar modo reordenador" "enable_reorder": "Ativar modo reordenador",
"hide_question_results": "Ocultar o resultado das respostas?",
"advanced_settings": "Configurações Avançadas"
}, },
"result_page": { "result_page": {
"correct_answer_plural": "{{count}} respostas corretas", "correct_answer_plural": "{{count}} respostas corretas",
@@ -387,7 +389,7 @@
"totp": "password de uso único (Totp)", "totp": "password de uso único (Totp)",
"totp_unavailable": "TOTP não está disponível", "totp_unavailable": "TOTP não está disponível",
"2fa_activated": "A autenticação de dois factores está activada", "2fa_activated": "A autenticação de dois factores está activada",
"webauthn": "Webauthn", "webauthn": "WebAuthn",
"add_security_key": "Adicionar chave de segurança", "add_security_key": "Adicionar chave de segurança",
"activate_2fa": "Activar a autenticação de dois factores", "activate_2fa": "Activar a autenticação de dois factores",
"webauthn_unavailable": "Webauthn não está disponível", "webauthn_unavailable": "Webauthn não está disponível",
@@ -400,7 +402,7 @@
"add_new_controller": "Adicionar novo controlador", "add_new_controller": "Adicionar novo controlador",
"player_name": "Nome do jogador", "player_name": "Nome do jogador",
"controller_name": "Nome do controlador", "controller_name": "Nome do controlador",
"already_latest_version": " está na versão mais recente.", "already_latest_version": "Você está na versão mais recente",
"update_from_to": "Atualizar de {{current_version}} para {{newest_version}}", "update_from_to": "Atualizar de {{current_version}} para {{newest_version}}",
"first_seen": "Visto pela primeira vez", "first_seen": "Visto pela primeira vez",
"version_overview": "A versão mais recente disponível é {{newest_version}} e a versão {{current_version}} está instalada." "version_overview": "A versão mais recente disponível é {{newest_version}} e a versão {{current_version}} está instalada."
@@ -415,7 +417,7 @@
"download_template_here": "Baixar o modelo", "download_template_here": "Baixar o modelo",
"classquiz_quiz": "Um quiz do ClassQuiz", "classquiz_quiz": "Um quiz do ClassQuiz",
"this_side_classquiz": "Neste canto você consegue importar questionários que foram exportados do ClassQuiz.", "this_side_classquiz": "Neste canto você consegue importar questionários que foram exportados do ClassQuiz.",
"a_kahoot_quiz": "Um Quiz do Kahoot!", "a_kahoot_quiz": "Um Kahoot!-Quiz",
"side_import_kahoot": "Neste canto você consegue importar quizzes que estão no Kahoot!.", "side_import_kahoot": "Neste canto você consegue importar quizzes que estão no Kahoot!.",
"url_should_look_like_this": "A URL deve estar assim: https://create.kahoot.it/details/...", "url_should_look_like_this": "A URL deve estar assim: https://create.kahoot.it/details/...",
"need_help": "Precisa de ajuda?", "need_help": "Precisa de ajuda?",
@@ -479,7 +481,7 @@
}, },
"components": { "components": {
"popover": { "popover": {
"copied_to_clipboard": "Copiado para a área de transferência" "copied_to_clipboard": "Copiado para a área de transferência!"
} }
}, },
"downloader": { "downloader": {
+208
View File
@@ -0,0 +1,208 @@
{
"index_page": {
"slogan": "Open-source квиз-платформа!",
"meta": {
"description": "ClassQuiz - это приложение quiz для интерактивного обучения студентов, которое является открытым исходным кодом и бесплатным для использования",
"title": "Домой"
},
"stats": "Уже есть {{user_count}} пользователи и {{quiz_count}} квизы на ClassQuiz.",
"see_how_many_true_and_false": "Посмотрите, сколько из них были правы или неправы",
"completely_free": "Полностью бесплатный",
"play_quiz": "2. Играть квиз",
"select_answer": "Выберите ответ",
"choose_answer_wisely": "Выберите свой ответ осознанно",
"list_winners": "Список победителей",
"get_ranking_and_winners": "Получить рейтинг и посмотреть, кто выиграл",
"why_classquiz": "Почему ClassQuiz?",
"no_tracking_content": "Другие отслеживают вас и передают эту информацию третьим сторонам, но ClassQuiz этого не делает.",
"see_what_true_and_false": "Посмотрите, что правильно или неправильно",
"create_or_import": "Создание или импорт",
"see_all_quizzes": "Смотрите все ваши квизы",
"teachers_site": "Сайт учителя",
"students_site": "Сайт студента",
"no_tracking": "Без отслеживания",
"self_hostable": "Собственный хостинг",
"german_server": "Немецкий сервер",
"user_friendly": "Дружественный к пользователю",
"quiz_results_downloadable": "Можно скачать результаты квиза",
"multilingual": "Многоязычный",
"dark_mode": "Тёмный режим",
"get_a_quiz": "1. Получить викторину",
"create_a_quiz_from_scratch": "Создать квиз при помощи редактора, добавить картинки и другое",
"find_or_explore": "Найти (или исследовать) викторины, сделанные или импортированные другими людьми",
"view_results": "Просмотр результатов",
"check_if_chosen_wisely": "Проверьте, если вы выбрали осознанно",
"self_hostable_content": "ClassQuiz легко можно легко хостить самостоятельно, и все ваши данные будут находятся только под вашим контролем!",
"user_friendly_content": "ClassQuiz стремится быть простым, поэтому он может быть использован всеми.",
"completely_free_content": "ClassQuiz полностью бесплатен (для пользователя), без каких-либо платных планов или раздражающих перенаправлений на страницу обновления. Пожертвования высоко ценятся и приветствуются.",
"quiz_results_downloadable_content": "Результаты квизов можно легко экспортировать в Excel-таблицу. (Не знал, что другие не могут этого сделать.).",
"multilingual_content": "ClassQuiz доступен на английском, французском, немецком, итальянском, норвежском Bokmål, турецком и частично индонезийском , каталонском и русском языках.",
"dark_mode_content": "Одна из самых важных особенностей которую может иметь веб-сайт!",
"german_server_content": "Серверы ClassQuiz расположены в Германии и размещены в Netcup.",
"download_quizzes": "Скачать квизы",
"community_driven": "Разрабатываемые сообществом",
"community_driven_content": "ClassQuiz зависит от его сообщества в финансировании, тестировании идей, запросов на характеристики, переводов и многом другом! Вы также можете быть частью сообщества ClassQuiz!",
"no_player_limit": "Нет ограничений для игрока",
"download_quizzes_content": "Квизы можно загрузить как один файл и импортировать в любое время. Это также позволяет вам переместить ваши квизы в другие экземпляры ClassQuiz.",
"how_does_classquiz_work": "Как вообще работает ClassQuiz?",
"no_player_limit_content": "ClassQuiz не имеет искусственных лимитов игроков. Теоретически, 1000 + игроков могут играть один и тот же квиз, но он тестируется количеством до 300 игроков за квиз."
},
"overview_page": {
"created_at": "Создано",
"question_count": "Количество вопросов",
"no_quizzes": "Нажмите на кнопку \"Создать\" или импортируйте викторину."
},
"edit_page": {
"success_update_body": "Никого не будет ожидать расправа инквизиции.",
"success_update_title": "Квиз обновился."
},
"create_page": {
"success": {
"title": "Квиз создан.",
"body": "Пусть начнутся игры."
}
},
"register_page": {
"greeting": "Приятно познакомиться!",
"forgot_password?": "Забыл пароль?",
"already_have_account?": "Уже имеется учётная запись?",
"create_account": "Создать учетную запись"
},
"login_page": {
"welcome_back": "С возвращением!",
"login_or_create_account": "Войти или создать учетную запись",
"already_have_account": "Нет учётной записи?",
"modal": {
"success": {
"success_check_mail": "Вы вошли. Проверьте почтовый ящик.",
"success": "Успешный вход",
"description": {
"success": "Успешный вход",
"success_check_mail": "Пожалуйста, проверьте свой почтовый ящик для электронной почты. Туда придет письмо со ссылкой, которую вы можете нажать, чтобы войти."
}
},
"error": {
"unexpected": "Непредвиденная ошибка",
"description": {
"unexpected": "Была старая непредвиденная ошибка!",
"wrong_creds": "Пожалуйста, убедитесь, что ваш пароль и адрес электронной почты правильные."
},
"wrong_creds": "Неверный адрес электронной почты или пароль."
}
},
"email_or_username": "Email или имя пользователя",
"use_backup_code": "Использовать резервный код"
},
"words": {
"question": "Вопрос",
"stats": "Статистика",
"password": "Пароль",
"features": "Возможности",
"login": "Вход",
"username": "Имя пользователя",
"delete": "Удалить",
"public": "Общественное общество",
"start": "Начало",
"create": "Создать",
"import": "Импорт",
"title": "Заголовок",
"url": "URL",
"submit": "Подтвердить",
"pin": "PIN",
"register": "Зарегистрировать",
"docs": "Документация",
"search": "Поиск",
"screenshot": "Снимок экрана",
"screenshot_plural": "Снимки экрана",
"view_plural": "Просмотры",
"result_plural": "Результаты",
"count": "Счет",
"range": "Диапазон",
"multiple_choice": "Несколько вариантов",
"private": "Личный",
"dashboard": "Информпанель",
"question_plural": "Вопросы",
"other_plural": "другие",
"game_pin": "PIN игры",
"other": "другие",
"donating": "пожертвование",
"find": "Найти",
"practice": "Практика",
"error": "Ошибка",
"voting": "Голосование",
"download": "Скачать",
"continue": "Продолжить",
"backup_code": "Резервный код",
"totp": "",
"text": "Текст",
"order": "Заказ",
"results": "Результаты",
"note": "Заметка",
"player_plural": "Игроки",
"version": "Версия",
"never": "Никогда",
"unknown": "Неизвестный",
"update": "Обновление",
"score": "Оценка",
"slide": "Слайд",
"name": "Имя",
"point": "Пункт",
"point_plural": "Пункты",
"back": "Назад",
"finish": "Финиш",
"normal": "Нормальный",
"selected": "Выбрано",
"select": "Выберите",
"quiz": "Квиз",
"next": "Следующий",
"check_choice": "Проверьте выбор",
"video": "Ролик",
"library": "Библиотека",
"progress": "Прогресс",
"speed": "Скорость",
"upload": "Загрузка",
"files_library": "Библиотека файлов",
"answer_plural": "Ответы",
"yes": "Да",
"no": "нет",
"analytics": "Аналитика",
"rating": "Рейтинг",
"like": "Нравится",
"like_plural": "Лайки",
"dislike": "Не нравится",
"dislike_plural": "Не нравится",
"play_plural": "Игры",
"play": "Играть",
"edit": "Редактировать",
"answer": "Ответ",
"email": "Адрес электронной почты",
"logout": "Выход",
"kick": "Выгнать",
"correct": "Верно",
"connect": "Соединить",
"close": "Закрыть",
"result": "Результат",
"save": "Сохранить",
"description": "Описание",
"settings": "Настройка",
"image": "Изображения",
"repeat_password": "Повторить пароль",
"overview": "Обзор",
"report": "Отчет",
"explore": "Обзор",
"browser": "Браузер",
"view": "Вид",
"info": "Информация",
"player": "Плеер"
},
"editor": {
"time_in_seconds": "Время в секундах",
"add_new_question": "Добавить вопрос",
"delete_answer": "Удалить ответ",
"bg_image": "Фоновое изображение",
"slide": {
"headline": "Заголовок",
"text": "Текст"
}
}
}
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
+486
View File
@@ -0,0 +1,486 @@
{
"index_page": {
"community_driven": "சமூகம் உந்துதல்",
"slogan": "திறந்த மூல நொடி வினா-தளம்!",
"meta": {
"description": "ClassQuiz என்பது மாணவர்களுக்காக ஊடாடும் வகையில் கற்றுக்கொள்ள ஒரு நொடி வினா பயன்பாடாகும், இது திறந்த மூலமாகவும் பயன்படுத்தவும் இலவசம்",
"title": "வீடு"
},
"stats": "ஏற்கனவே {{user_count}} பயனர்கள் மற்றும் {{quiz_count}}} நொடி வினாக்கள் உள்ளன.",
"see_what_true_and_false": "எது சரி தவறு என்று பாருங்கள்",
"see_how_many_true_and_false": "எத்தனை சரி அல்லது தவறு என்று பாருங்கள்",
"create_or_import": "உருவாக்க அல்லது இறக்குமதி",
"see_all_quizzes": "உங்கள் நொடி வினாக்கள் அனைத்தையும் காண்க",
"teachers_site": "ஆசிரியரின் தளம்",
"students_site": "மாணவர்களின் தளம்",
"no_tracking": "கண்காணிப்பு இல்லை",
"self_hostable": "தன்வய ஓச்டபிள்",
"german_server": "செர்மன் சேவையகம்",
"user_friendly": "பயனர் நட்பு",
"completely_free": "முற்றிலும் விலை இலவசம்",
"quiz_results_downloadable": "நொடி வினா-முடிவுகளை பதிவிறக்கம் செய்யலாம்",
"multilingual": "பன்மொழி",
"dark_mode": "இருண்ட முறை",
"get_a_quiz": "1. ஒரு நொடி வினா கிடைக்கும்",
"create_a_quiz_from_scratch": "எடிட்டருடன் புதிதாக ஒரு நொடி வினாவை உருவாக்கி, படங்கள் மற்றும் பலவற்றைச் சேர்க்கவும்",
"find_or_explore": "மற்றவர்களால் செய்யப்பட்ட அல்லது இறக்குமதி செய்யப்பட்ட நொடி வினாக்களைக் கண்டுபிடி (அல்லது ஆராயுங்கள்)",
"play_quiz": "2. நொடி வினா விளையாடுங்கள்",
"select_answer": "பதிலைத் தேர்ந்தெடுக்கவும்",
"choose_answer_wisely": "உங்கள் பதிலை புத்திசாலித்தனமாகத் தேர்வுசெய்க",
"view_results": "முடிவுகளைக் காண்க",
"check_if_chosen_wisely": "சரிபார்க்கவும், நீங்கள் புத்திசாலித்தனமாக தேர்ந்தெடுத்திருந்தால்",
"list_winners": "பட்டியல் வெற்றியாளர்கள்",
"get_ranking_and_winners": "தரவரிசையைப் பெற்று யார் வென்றார்கள் என்று பாருங்கள்",
"why_classquiz": "ஏன் கிளாச் க்விச்?",
"no_tracking_content": "மற்றவர்கள் உங்களைக் கண்காணித்து, அந்த தகவலை மூன்றாம் தரப்பினருக்கு அனுப்புகிறார்கள், ஆனால் கிளாச்க்விச் இல்லை.",
"self_hostable_content": "ClassQuiz எளிதில் சுய-ஓச்டாக இருக்க முடியும், எனவே தரவு உங்கள் கட்டுப்பாட்டில் மட்டுமே உள்ளது!",
"user_friendly_content": "ClassQuiz எளிமையானதாக இருப்பதை நோக்கமாகக் கொண்டுள்ளது, எனவே இது அனைவராலும் பயன்படுத்தப்படலாம்.",
"completely_free_content": "எந்தவொரு கட்டணத் திட்டங்களும் அல்லது மேம்படுத்தல்-பக்கத்திற்கு எரிச்சலூட்டும் வழிமாற்றுகள் இல்லாமல், கிளாச் க்விச் முற்றிலும் இலவசம் (பயனருக்கு). நன்கொடைகள் மிகவும் பாராட்டப்படுகின்றன.",
"quiz_results_downloadable_content": "நொடி வினா-முடிவுகளை எக்செல்-ச்ப்ரெட்சீட்டில் எளிதாக ஏற்றுமதி செய்யலாம். (மற்றவர்களுக்கு அதைச் செய்ய முடியாது என்று தெரியாது)",
"multilingual_content": "கிளாச் க்விச் ஆங்கிலம், பிரஞ்சு, செர்மன், இத்தாலியன், நோர்வே போக்மால், துருக்கிய மற்றும் ஓரளவு இந்தோனேசிய மற்றும் கற்றலான் ஆகியவற்றில் கிடைக்கிறது.",
"dark_mode_content": "ஒரு வலைத்தளம் கொண்டிருக்கக்கூடிய மிக முக்கியமான அம்சங்களில் ஒன்று!",
"german_server_content": "கிளாச்க்விசின் சேவையகங்கள் செர்மனியில் அமைந்துள்ளன மற்றும் நெட்கூப் வழங்குகின்றன.",
"download_quizzes": "நொடி வினாக்களைப் பதிவிறக்குக",
"download_quizzes_content": "நொடி வினாக்களை ஒரு கோப்பாக பதிவிறக்கம் செய்து எந்த நேரத்திலும் இறக்குமதி செய்யலாம். இது உங்கள் நொடி வினாக்களை மற்ற கிளாச் க்விச் நிகழ்வுகளுக்கு நகர்த்தவும் உதவுகிறது.",
"community_driven_content": "ClassQuiz பொருள், சோதனை சிந்தனைகள், அம்ச கோரிக்கைகள், மொழிபெயர்ப்புகள் மற்றும் பலவற்றிற்காக அதன் சமூகத்தைப் பொறுத்தது! நீங்கள் கிளாச்க்விச்-சமூகத்தின் ஒரு பகுதியாகவும் இருக்கலாம்!",
"how_does_classquiz_work": "கிளாச் க்விச் கூட எவ்வாறு செயல்படுகிறது?",
"no_player_limit": "வீரர் வரம்பு இல்லை",
"no_player_limit_content": "ClassQuiz க்கு செயற்கை வீரர் வரம்பு இல்லை. கோட்பாட்டில், 1000+ வீரர்கள் ஒரே நொடி வினாவை விளையாட முடியும், ஆனால் இது ஒரு நொடி வினா வரை 300 வீரர்களுடன் சோதிக்கப்படுகிறது.",
"import_quiz_from_kahoot_and_edit": "ஏற்றுமதி"
},
"play_page": {
"join_description": "{{pin} at இல் சேரவும், {{url}}} ஐ உள்ளிடவும்.",
"end_sentence": "அவ்வளவுதான்! இது நொடி வினா.",
"1st_place": "1 வது இடம்",
"2nd_place": "2 வது இடம்",
"3rd place": "3 வது இடம்",
"with_out_of": "{{correct_questions}} fout {{total_question_count}}} உடன்",
"final_result_rank": "{{place}} புள்ளிகளுடன் {{{{username}}",
"your_score": "உங்கள் மதிப்பெண்: {{score}}",
"join_by_entering_code": "பின்வரும் குறியீட்டை உள்ளிட்டு சேரவும்",
"points_added": "புள்ளிகள் சேர்க்கப்பட்டன",
"your_place": "நீங்கள் இடத்தில் {{place}}!",
"players_waiting": "{{count}}} பிளேயர் காத்திருக்கிறார்",
"players_waiting_plural": "{{count}} வீரர்கள் காத்திருக்கிறார்கள்"
},
"downloader": {
"help": "சொந்த வடிவம் (.CQA) ஒவ்வொரு கேள்வி வகையையும் படங்களை உள்ளடக்கியது மற்றும் ஆதரிக்கிறது, அதேசமயம் எக்செல் வடிவம் வாக்களிப்பு மற்றும் பல தேர்வு கேள்விகளை மட்டுமே ஆதரிக்கிறது.",
"select_download_type": "பதிவிறக்க வகை என்பதைத் தேர்ந்தெடுக்கவும்",
"own_format": "சொந்த வடிவம்",
"excel_format": "எக்செல் வடிவம்"
},
"overview_page": {
"created_at": "உருவாக்கப்பட்டது",
"question_count": "கேள்வி எண்ணிக்கை",
"no_quizzes": "\"உருவாக்கு\" -பட்டன் என்பதைக் சொடுக்கு செய்க அல்லது செல்ல ஒரு நொடி வினாவை இறக்குமதி செய்க."
},
"edit_page": {
"success_update_title": "நொடி வினா புதுப்பிக்கப்பட்டது.",
"success_update_body": "விசாரணையை யாரும் எதிர்பார்க்க மாட்டார்கள்."
},
"create_page": {
"success": {
"title": "நொடி வினா உருவாக்கப்பட்டது.",
"body": "விளையாட்டுகள் தொடங்கட்டும்."
}
},
"register_page": {
"greeting": "உங்களை சந்தித்ததில் மகிழ்ச்சி!",
"create_account": "கணக்கை உருவாக்கவும்",
"forgot_password?": "கடவுச்சொல்லை மறந்துவிட்டீர்களா?",
"already_have_account?": "ஏற்கனவே ஒரு கணக்கு இருக்கிறதா?"
},
"login_page": {
"welcome_back": "மீண்டும் வருக.",
"login_or_create_account": "உள்நுழைக அல்லது ஒரு கணக்கை உருவாக்கவும்",
"already_have_account": "கணக்கு இல்லையா?",
"email_or_username": "மின்னஞ்சல் அல்லது பயனர்பெயர்",
"modal": {
"success": {
"success_check_mail": "உள்நுழைந்தது. உங்கள் மின்னஞ்சல் இன்பாக்சை சரிபார்க்கவும்.",
"success": "உள்நுழைந்தது.",
"description": {
"success_check_mail": "உள்நுழைய நீங்கள் சொடுக்கு செய்யக்கூடிய இணைப்பைக் கொண்ட மின்னஞ்சலுக்கு உங்கள் மின்னஞ்சல் இன்பாக்சை சரிபார்க்கவும்.",
"success": "உள்நுழைந்தது."
}
},
"error": {
"wrong_creds": "தவறான மின்னஞ்சல் முகவரி அல்லது கடவுச்சொல்.",
"unexpected": "எதிர்பாராத பிழை!",
"description": {
"wrong_creds": "உங்கள் கடவுச்சொல் மற்றும் மின்னஞ்சல் முகவரி சரியானது என்பதை உறுதிப்படுத்தவும்.",
"unexpected": "நல்ல பழைய எதிர்பாராத பிழை இருந்தது!"
}
}
},
"use_backup_code": "காப்பு குறியீட்டைப் பயன்படுத்தவும்"
},
"words": {
"question": "கேள்வி",
"answer": "பதில்",
"stats": "புள்ளிவிவரங்கள்",
"features": "நற்பொருத்தங்கள்",
"login": "புகுபதிகை",
"email": "மின்னஞ்சல் முகவரி",
"username": "பயனர்பெயர்",
"password": "கடவுச்சொல்",
"play": "விளையாடுங்கள்",
"edit": "தொகு",
"delete": "அழி",
"public": "பொது",
"start": "தொடங்கு",
"create": "உருவாக்கு",
"import": "இறக்குமதி",
"logout": "விடுபதிகை",
"title": "தலைப்பு",
"url": "முகவரி",
"submit": "சமர்ப்பிக்கவும்",
"connect": "இணை",
"pin": "முள்",
"kick": "கிக்",
"register": "பதிவு செய்யுங்கள்",
"docs": "கோப்புகள்",
"close": "மூடு",
"save": "சேமி",
"description": "விவரம்",
"image": "படம்",
"settings": "அமைப்புகள்",
"repeat_password": "கடவுச்சொல்லை மீண்டும் செய்யவும்",
"overview": "கண்ணோட்டம்",
"report": "அறிக்கை",
"explore": "ஆராயுங்கள்",
"search": "தேடு",
"screenshot": "திரைக்காட்சி",
"screenshot_plural": "திரைப்படிப்புகள்",
"browser": "உலாவி",
"view": "பார்வை",
"view_plural": "காட்சிகள்",
"correct": "சரியான",
"result": "முடிவு",
"result_plural": "முடிவுகள்",
"count": "எண்ணுங்கள்",
"range": "வீச்சு",
"multiple_choice": "பல தேர்வு",
"private": "தனிப்பட்ட",
"dashboard": "முகப்புப்பெட்டி",
"question_plural": "கேள்விகள்",
"game_pin": "விளையாட்டு முள்",
"other": "மற்றொன்று",
"other_plural": "மற்றவர்கள்",
"donating": "நன்கொடைஅளி",
"find": "கண்டுபிடி",
"practice": "பயிற்சி",
"error": "பிழை",
"voting": "வாக்களிப்பு",
"download": "பதிவிறக்கம்",
"continue": "தொடரவும்",
"backup_code": "காப்பு-குறியீடு",
"totp": "நேஒமுக",
"text": "உரை",
"order": "ஒழுங்கு",
"results": "முடிவுகள்",
"note": "குறிப்பு",
"player_plural": "வீரர்கள்",
"version": "பதிப்பு",
"never": "ஒருபோதும் இல்லை",
"unknown": "தெரியாத",
"update": "புதுப்பிப்பு",
"score": "கெலிப்பெண்",
"slide": "சருக்கு",
"name": "பெயர்",
"point": "புள்ளி",
"point_plural": "புள்ளிகள்",
"back": "பின்",
"finish": "முடிக்க",
"normal": "சாதாரண",
"selected": "தேர்ந்தெடுக்கப்பட்டது",
"select": "தேர்ந்தெடு",
"quiz": "நொடி வினா",
"quiztivity": "விநாடிவினா",
"next": "அடுத்தது",
"check_choice": "தேர்வு சரிபார்க்கவும்",
"video": "காணொளி",
"library": "நூலகம்",
"progress": "முன்னேற்றம்",
"speed": "வேகம்",
"upload": "பதிவேற்றும்",
"files_library": "கோப்புகள் நூலகம்",
"answer_plural": "பதில்கள்",
"yes": "ஆம்",
"no": "இல்லை",
"analytics": "பகுப்பாய்வு",
"rating": "செயல்வரம்பு",
"like": "போன்ற",
"like_plural": "விருப்பங்கள்",
"dislike": "வெறுப்பு",
"dislike_plural": "வெறுப்புகள்",
"play_plural": "நாடகங்கள்",
"info": "தகவல்",
"player": "வீரர்"
},
"editor": {
"time_in_seconds": "நொடிகளில் நேரம்",
"right_or_true?": "சரி?",
"add_new_answer": "புதிய பதிலைச் சேர்க்கவும்",
"add_new_question": "புதிய கேள்வியைச் சேர்க்கவும்",
"delete_question": "கேள்வியை நீக்கு",
"delete_answer": "பதிலை நீக்கு",
"not_all_links_imgur_links": "எல்லா இணைப்புகளும் இம்குர்-இணைப்புகள் அல்ல!",
"no_title": "தலைப்பு இல்லை ...",
"empty": "காலியாக ...",
"bg_image": "பின்னணி படம்",
"slide": {
"headline": "தலைப்புவரி",
"headline_description": "தலைப்புச் செய்திகளுக்கான தைரியமான உரை",
"text": "உரை",
"text_description": "சிறிய நீண்ட உரை",
"rectangle": "செவ்வகம்",
"rectangle_description": "ஒரு செவ்வகம்"
},
"abcd_description": "ஒரே ஒரு பதிலை மட்டுமே தேர்வு செய்யலாம்",
"voting_description": "பதில்கள் எந்த புள்ளிகளையும் சேர்க்காது",
"check_choice_description": "அனைத்து சரியான பதில்களும் புள்ளிகளைப் பெற தேர்வு செய்யப்பட வேண்டும்",
"order_description": "பதில்களை சரியான வரிசையில் கொண்டு வரலாம்",
"text_description": "வீரர்கள் உரையை உள்ளிடலாம்",
"range_description": "ச்லைடருடன் ஒரு எண்-வரம்பைத் தேர்ந்தெடுக்கலாம்",
"need_more_help": "மேலும் உதவி தேவையா?",
"visit_docs": "டாக்சைப் பார்வையிடவும்.",
"enter_answer": "ஒரு பதிலை உள்ளிடவும்",
"enable_reorder": "மறுதொடக்கம் பயன்முறையை இயக்கவும்",
"disable_reorder": "மறுதொடக்கம் பயன்முறையை முடக்கு"
},
"import_page": {
"need_help": "உதவி தேவையா?",
"visit_docs": "ஆவணங்களைப் பார்வையிடவும்",
"a_kahoot_quiz": "ஒரு கஊட்! -Quiz",
"url_should_look_like_this": "முகவரி இப்படி இருக்க வேண்டும்: https: //create.kahoot.it/details/...",
"side_import_kahoot": "இந்த பக்கத்தில் நீங்கள் கஊட்டில் வசிக்கும் நொடி வினாக்களை இறக்குமதி செய்யலாம்.",
"classquiz_quiz": "ஒரு கிளாச் க்விச்-க்விச்",
"upload_file_ending": ".Cqa அல்லது .xlsx இல் முடிவடையும் கோப்பை பதிவேற்றவும்",
"this_side_classquiz": "இந்த பக்கத்தில் நீங்கள் நொடி வினாக்களை இறக்குமதி செய்யலாம், அவை ClassQuiz இலிருந்து ஏற்றுமதி செய்யப்பட்டன.",
"this_side_classquiz_excel": "பின்வரும் வார்ப்புருவை நீங்கள் நிரப்பினால், எக்செல் கோப்புகளையும் பதிவேற்றலாம். தலைப்பைக் கொண்ட நொடி வினா ஏற்கனவே இருந்தால், அது கேள்விகளை ஏற்கனவே உள்ள நொடி வினாவுடன் சேர்க்கும்.",
"download_template_here": "வார்ப்புருவைப் பதிவிறக்கவும்"
},
"admin_page": {
"already_registered_as_admin": "இந்த விளையாட்டுக்கு ஏற்கனவே ஒரு நிர்வாகி பதிவு செய்யப்பட்டுள்ளது.",
"start_game": "விளையாட்டைத் தொடங்கவும்",
"time_left": "நேரம் மீதமுள்ளது",
"get_results": "முடிவுகளைப் பெறுங்கள்",
"get_results_and_stop_time": "முடிவுகளைப் பெற்று நேரத்தை நிறுத்துங்கள்",
"get_final_results": "இறுதி முடிவுகளைப் பெறுங்கள்",
"show_next_question": "அடுத்த கேள்வியைக் காட்டு",
"start_by_showing_first_question": "முதல் கேள்வியைக் காண்பிப்பதன் மூலம் தொடங்கவும்.",
"no_answers": "பதில்கள் இல்லை!",
"stop_time": "நேரம் நிறுத்துங்கள்",
"save_results": "முடிவுகளைச் சேமிக்கவும்",
"next_question": "அடுத்த கேள்வி ({{question}})",
"show_results": "முடிவுகளை காட்டு",
"stop_time_and_solutions": "நேரத்தை நிறுத்தி தீர்வுகளைக் காட்டுங்கள்",
"enter_answer_into_field": "உள்ளீட்டு புலத்தில் உங்கள் பதிலை உள்ளிடவும்!",
"answers_submitted": "{{answer_count}} பதில்கள் சமர்ப்பிக்கப்பட்டன",
"request_export_results": "கோரிக்கை முடிவு பதிவிறக்கம்",
"download_export_results": "முடிவுகளைப் பதிவிறக்கவும்",
"export_results": "ஏற்றுமதி முடிவுகள்"
},
"password_reset_page": {
"reset_password": "கடவுச்சொல்லை மீட்டமை"
},
"settings_page": {
"old_password": "பழைய கடவுச்சொல்",
"new_password": "புதிய கடவுச்சொல்",
"repeat_password": "கடவுச்சொல்லை மீண்டும் செய்யவும்",
"change_password_submit": "கடவுச்சொல்லை மாற்று!",
"last_seen": "கடைசியாக பார்த்தேன்",
"check_location": "இருப்பிடத்தை சரிபார்க்கவும்",
"delete_this_session": "இந்த அமர்வை நீக்கு",
"this_session?": "இந்த அமர்வு?",
"change_avatar": "அவதாரத்தை மாற்றவும்",
"security_settings": "பாதுகாப்பு-அமைவுகள்",
"add_api_key": "பநிஇ விசையைச் சேர்க்கவும்"
},
"explore_page": {
"made_by": "தயாரிக்கப்பட்டது",
"imported_by": "இறக்குமதி செய்யப்பட்டது"
},
"search_page": {
"at_least_3_characters": "குறைந்தது 3 எழுத்துக்களை உள்ளிடவும் ...",
"nothing_here": "இங்கே எதுவும் இல்லை ..."
},
"editor_page": {
"add_an_answer": "ஒரு பதிலைச் சேர்க்கவும்",
"right_click_to_delete": "அதை நீக்க ஒரு பதிலில் வலது சொடுக்கு செய்யவும்!"
},
"dashboard": {
"search_for_own_quizzes": "உங்கள் சொந்த நொடி வினாக்களைத் தேடுங்கள்",
"views_n_plays": "காட்சிகள் மற்றும் நாடகங்கள்",
"info_analytics": "\"நாடகங்கள்\" நொடி வினா எவ்வளவு அடிக்கடி தொடங்கப்பட்டது என்பதை மட்டுமே காட்டுகிறது (நீங்கள் சேர்த்துள்ளீர்கள்), அதேசமயம் \"காட்சிகள்\" \"பார்வை\"-பக்கம் எவ்வளவு அடிக்கடி பார்வையிடப்பட்டது என்பதை கணக்கிடுகிறது, எனவே இது போட்களையும் கணக்கிடுகிறது (அதற்காக மன்னிக்கவும்).",
"commandpalette_notice": "கட்டளைத் தட்டுகளைத் திறக்க <kbd> ctr </kbd>+<kbd> k </kbd> அல்லது <kbd> மேவு </kbd>+<kbd> k </kbd> ஐ அழுத்தவும்"
},
"footer": {
"self_ads": "{{mawoka_link} by மற்றும் {{others_link} of உதவியுடன் தயாரிக்கப்பட்டது.",
"more_details_here": "மேலும் விவரங்கள் இங்கே",
"donate": "இது பயனுள்ளதாக இருந்தால், தயவுசெய்து {{donate_link}} ஐக் கவனியுங்கள்."
},
"error_page": {
"404_text": "நீங்கள் தேடிக்கொண்டிருந்த பக்கம் போய்விட்டது அல்லது ஒருபோதும் இருந்ததில்லை. யாருக்குத் தெரியும்?",
"unknown_error_text": "அது நடக்கக்கூடாது. இது அநேகமாக என் தவறு, உங்களுடையது அல்ல, ஆனால் பொருட்களை உடைக்க உங்களுக்கு ஒரு மந்திர ஆற்றல் இருக்கலாம் ..."
},
"uploader": {
"add_image": "ஊடகத்தைச் சேர்",
"select_upload_type": "பதிவேற்ற வகையைத் தேர்ந்தெடுக்கவும்",
"upload_a_video": "வீடியோவைப் பதிவேற்றவும்",
"upload_video_popup_notice": "பாப்அப் திறந்திருக்கும்; மேலும் தகவலுக்கு இதைப் பாருங்கள்",
"upload_video": "காணொலியைப் பதிவேற்றவும்",
"visit_pixabay": "பிக்சாபேவைப் பார்வையிடவும்",
"images_by_pixabay": "பிக்சாபே வழங்கிய படங்கள்",
"search_english_only": "தேடல் ஆங்கிலத்தில் மட்டுமே வேலை செய்கிறது",
"next_page": "அடுத்த பக்கம்",
"previous_page": "முந்தைய பக்கம்"
},
"avatar_settings": {
"skin_color": "தோல் நிறம்",
"top_type": "மேல்",
"hair_color": "முடி நிறம்",
"facial_hair_type": "முக முடி",
"facial_hair_color": "முக முடி நிறம்",
"mouth_type": "வாய்",
"eyebrow_type": "புருவம்",
"accessories_type": "கண்ணாடிகள்",
"hat_color": "தொப்பி நிறம்",
"clothe_type": "ஆடைகள்",
"clothe_color": "ஆடை நிறம்",
"clothe_graphic_type": "வரைகலை",
"thats_you": "அது நீங்கள்!",
"start_over": "தொடக்க",
"go_back": "திரும்பிச் செல்லுங்கள்"
},
"results_page": {
"no_results_so_far": "இதுவரை எந்த முடிவுகளும் சேமிக்கப்படவில்லை ...",
"quiz_title": "நொடி வினா தலைப்பு",
"date_played": "விளையாடிய தேதி",
"player_count": "வீரர் எண்ணிக்கை",
"general_overview": {
"sentence": "{{average_score} at இல் விளையாடிய \"{{title}}\" நொடி வினா {{date}}} {{player_count}}}}} வீரர்களைக் கொண்டிருந்தது."
}
},
"result_page": {
"player_name": "வீரர் பெயர்",
"custom_field": "தனிப்பயன் புலம்",
"average_score": "சராசரி மதிப்பெண்: {{average_score}}",
"correct_answer": "{{count}} சரியான பதில்",
"correct_answer_plural": "{{count}} சரியான பதில்கள்",
"time_taken": "எடுக்கப்பட்ட நேரம்",
"player_score": "பிளேயர் ச்கோர்"
},
"controllers": {
"add_new_controller": "புதிய கட்டுப்படுத்தியைச் சேர்க்கவும்",
"player_name": "வீரர் பெயர்",
"first_seen": "முதலில் பார்த்தேன்",
"last_seen": "கடைசியாக பார்த்தேன்",
"controller_name": "கட்டுப்படுத்தி பெயர்",
"version_overview": "கிடைக்கக்கூடிய புதிய பதிப்பு {{newest_version}} மற்றும் பதிப்பு {{current_version}} நிறுவப்பட்டுள்ளது.",
"already_latest_version": "நீங்கள் ஏற்கனவே அண்மைக் கால பதிப்பில் இருக்கிறீர்கள்",
"cancel_update": "புதுப்பிப்பை ரத்துசெய்!",
"update_from_to": "{{current_version}}} முதல் {{{{newest_version} பெறுநர் வரை புதுப்பிக்கவும்"
},
"navbar": {
"donate": "நன்கொடை"
},
"security_settings": {
"backup_code": "காப்பு-குறியீடு",
"get_backup_code": "காப்புப்பிரதி குறியீட்டைப் பெறுங்கள்",
"activate_2fa": "இரண்டு காரணி அங்கீகாரத்தை செயல்படுத்தவும்",
"2fa_activated": "இரண்டு காரணி ஏற்பு செயல்படுத்தப்படுகிறது",
"2fa_deactivated": "இரண்டு காரணி ஏற்பு செயலிழக்கப்படுகிறது",
"webauthn": "வலை கார்",
"webauthn_available": "வெப்அத்ன் கிடைக்கிறது",
"webauthn_unavailable": "வெப்அத்ன் கிடைக்கவில்லை",
"add_security_key": "பாதுகாப்பு-விசையைச் சேர்க்கவும்",
"totp": "நேஒமுக",
"totp_available": "TOTP கிடைக்கிறது",
"totp_unavailable": "TOTP கிடைக்கவில்லை",
"disable_totp": "TOTP ஐ அணைக்கவும்",
"enable_totp": "TOTP ஐ இயக்கவும்",
"backup_codes": {
"your_backup_code": "உங்கள் காப்பு குறியீடு",
"save_somewhere_save": "இதை எங்காவது பாதுகாப்பாக சேமிக்கவும்!",
"download_code": "குறியீட்டைப் பதிவிறக்கவும்"
},
"totp_setup": {
"scan_to_set_up": "குறியீட்டை அமைக்க இந்த QR-குறியீட்டை ச்கேன் செய்யுங்கள்",
"enter_as_secret_if_no_see_code": "QR-குறியீட்டை ச்கேன் செய்ய முடியாவிட்டால் இதை ரகசியமாக உள்ளிடவும்",
"totp_setup": "TOTP-SETUP",
"do_not_forget_backup_code": "உங்கள் மீட்பு-குறியீட்டைக் காப்பாற்ற மறக்காதீர்கள்!"
}
},
"view_quiz_page": {
"made_by": "தயாரிக்கப்பட்டது",
"view_on_kahoot": "அசல் மீது காண்க"
},
"start_game": {
"captcha_message": "இயக்கப்பட்டால், கூகிளின் ரெக்காப்ட்சா வீரர்களின் உலாவியில் ஏற்றப்படும். உங்களுக்கு உண்மையிலேயே தேவைப்பட்டால் மட்டுமே இயக்கவும், ஏனென்றால் கேப்ட்சாவை ஏற்ற ஒவ்வொரு வீரரின் ஒப்புதல் உங்களுக்குத் தேவை.",
"normal_mode_description": "கேள்வி மற்றும் பதில் நிர்வாகிகள் திரையில் மட்டுமே காண்பிக்கப்படும். நிர்வாகியின் திரையில் இவை பொருந்தக்கூடிய சின்னங்களுடன் மட்டுமே வண்ண பொத்தான்கள் மட்டுமே இருக்கும்.",
"old_school_mode": "பழைய பள்ளி",
"old_school_mode_description": "நிர்வாகிகள் திரை மற்றும் பிளேயர்களின் திரையில் கேள்விகள் மற்றும் படங்கள் காண்பிக்கப்படும்",
"start_game": "விளையாட்டைத் தொடங்கு"
},
"quiztivity": {
"editor": {
"select_page_type": "பக்க வகையைத் தேர்ந்தெடுக்கவும்",
"move_left": "இடதுபுறம் நகர்த்தவும்",
"move_right": "வலதுபுறம் நகர்த்தவும்",
"title_placeholder": "தலைப்பை இங்கே உள்ளிடவும்",
"add_new": "புதியதைச் சேர்க்கவும்",
"delete": "அழி",
"open_shares_menu": "பங்குகள் மெனுவைத் திறக்கவும்",
"shares": {
"add_new_share": "புதிய பங்கைச் சேர்க்கவும்",
"expires_on": "{{date}} இல் காலாவதியாகிறது",
"never_expires": "ஒருபோதும் காலாவதியாகாது"
}
},
"memory": {
"editor": {
"add_card": "அட்டை சேர்க்கவும்",
"upload_image": "படத்தைப் பதிவேற்றவும்",
"add_pair": "இணை சேர்க்கவும்"
}
},
"play": {
"memory": {
"try_count": "முயற்சிக்கிறது: {{try_count}}}"
}
},
"share_expired": "பங்கு காலாவதியானது"
},
"components": {
"popover": {
"copied_to_clipboard": "கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது!"
}
},
"public_user_page": {
"joined_on": "{{date}} இல் இணைந்தது",
"no_original_quizzes": "இந்த பயனருக்கு அசல் நொடி வினாக்கள் இல்லை",
"user_not_found": "பயனர் கண்டுபிடிக்கப்படவில்லை"
},
"file_dashboard": {
"not_available": "கிடைக்கவில்லை",
"missing": "இல்லை!",
"unset": "அமைக்கப்படாதது",
"size": "அளவு: {{size}} mib",
"caption": "தலைப்பு: {{caption}}",
"filename": "கோப்பு பெயர்: {{filename}}}",
"uploaded": "பதிவேற்றப்பட்டது: {{date}}",
"imported": "இறக்குமதி: {{yes_or_no}}}",
"edit_details": "விவரங்களைத் திருத்தவும்",
"delete_image": "படத்தை நீக்கு",
"edit_the_image": "படத்தைத் திருத்தவும்",
"filename_word": "கோப்புப்பெயர்",
"alt_text": "மாற்று (ernate) உரை / தலைப்பு",
"storage_usage": "சேமிப்பகத்தின் {{used}} mib இலிருந்து {{total}} mib ஐப் பயன்படுத்தினீர்கள். இது உங்கள் சேமிப்பகத்தின் {{percent}}% க்கு சமம்."
},
"video_uploader": {
"time_elapsed": "நேரம் கடந்துவிட்டது",
"time_remaining": "மீதமுள்ள நேரம்"
}
}
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
+369 -347
View File
@@ -2,7 +2,7 @@
"index_page": { "index_page": {
"meta": { "meta": {
"title": "Додому", "title": "Додому",
"description": "ClassQuiz - це додаток-вікторина для студентів як Kahoot! Який має відкритий вихідний код і безкоштовний для використання" "description": "ClassQuiz це програма вікторини для інтерактивного навчання для студентів, яка має відкритий вихідний код і є безкоштовною для використання"
}, },
"features_description": { "features_description": {
"1": "ClassQuiz - це платформа, яка дозволяє створювати та керувати вікторини.", "1": "ClassQuiz - це платформа, яка дозволяє створювати та керувати вікторини.",
@@ -23,449 +23,471 @@
"stats": "На ClassQuiz вже є {{user_count}} користувачів та {{quiz_count}} вікторин.", "stats": "На ClassQuiz вже є {{user_count}} користувачів та {{quiz_count}} вікторин.",
"create_or_import": "Створюйте або імпортуйте", "create_or_import": "Створюйте або імпортуйте",
"see_how_many_true_and_false": "Переглядайте, скільки було правильних або неправильних відповідей", "see_how_many_true_and_false": "Переглядайте, скільки було правильних або неправильних відповідей",
"how_does_classquiz_work": "", "how_does_classquiz_work": "Як взагалі працює ClassQuiz?",
"select_answer": "", "select_answer": "Виберіть відповідь",
"find_or_explore": "", "find_or_explore": "Знайдіть (або досліджуйте) тести, створені або імпортовані іншими людьми",
"completely_free_content": "", "completely_free_content": "ClassQuiz повністю безкоштовний (для користувача), без будь-яких платних планів або дратівливих перенаправлень на сторінку оновлення. Пожертви високо цінуються.",
"download_quizzes": "", "download_quizzes": "Завантажте вікторини",
"dark_mode_content": "", "dark_mode_content": "Одна з найважливіших функцій веб-сайту!",
"multilingual": "", "multilingual": "Багатомовний",
"community_driven_content": "", "community_driven_content": "ClassQuiz залежить від своєї спільноти щодо фінансування, тестування ідей, запитів на функції, перекладів тощо! Ви також можете стати частиною ClassQuiz-спільноти!",
"get_a_quiz": "", "get_a_quiz": "1. Пройдіть тест",
"quiz_results_downloadable_content": "", "quiz_results_downloadable_content": "Результати тестів можна легко експортувати в електронну таблицю Excel. (Не знав, що інші не можуть цього зробити)",
"view_results": "", "view_results": "Переглянути результати",
"choose_answer_wisely": "", "choose_answer_wisely": "Вибирайте відповідь мудро",
"self_hostable_content": "", "self_hostable_content": "ClassQuiz можна легко розмістити самостійно, тож дані знаходяться лише у вас!",
"german_server_content": "", "german_server_content": "Сервери ClassQuiz розташовані в Німеччині та розміщені на netcup.",
"get_ranking_and_winners": "", "get_ranking_and_winners": "Отримайте рейтинг і подивіться, хто переміг",
"list_winners": "", "list_winners": "Список переможців",
"create_a_quiz_from_scratch": "", "create_a_quiz_from_scratch": "Створіть вікторину з нуля за допомогою редактора та додайте зображення тощо",
"check_if_chosen_wisely": "", "check_if_chosen_wisely": "Перевірте, чи мудро ви вибрали",
"user_friendly_content": "", "user_friendly_content": "ClassQuiz має бути простим, тому ним може користуватися кожен.",
"no_tracking_content": "", "no_tracking_content": "Інші відстежують вас і надсилають цю інформацію третім сторонам, але ClassQuiz цього не робить.",
"multilingual_content": "", "multilingual_content": "ClassQuiz доступний англійською, французькою, німецькою, італійською, норвезькою (букмол), турецькою та частково індонезійською та каталонською мовами.",
"dark_mode": "", "dark_mode": "Темний режим",
"why_classquiz": "", "why_classquiz": "Чому ClassQuiz?",
"community_driven": "", "community_driven": "Керується спільнотою",
"play_quiz": "", "play_quiz": "2. Пограйте у вікторину",
"download_quizzes_content": "" "download_quizzes_content": "Тести можна завантажити як один файл і імпортувати в будь-який час. Це також дозволяє переміщувати ваші тести в інші екземпляри ClassQuiz.",
"import_quiz_from_kahoot_and_edit": "Імпортуйте тести з Kahoot! і редагуйте їх у ClassQuiz",
"no_player_limit_content": "ClassQuiz не має штучного обмеження гравців. Теоретично в одну вікторину можуть грати понад 1000 гравців, але в тесті брали участь до 300 гравців.",
"no_player_limit": "Немає обмежень гравців"
}, },
"result_page": { "result_page": {
"correct_answer_plural": "", "correct_answer_plural": "{{count}} правильні відповіді",
"player_score": "", "player_score": "Очки гравця",
"correct_answer": "", "correct_answer": "{{count}} правильна відповідь",
"time_taken": "", "time_taken": "Витрачений час",
"player_name": "", "player_name": "Ім'я гравця",
"average_score": "", "average_score": "Середній бал: {{average_score}}",
"custom_field": "" "custom_field": "Спеціальне поле"
}, },
"register_page": { "register_page": {
"create_account": "", "create_account": "Створити акаунт",
"greeting": "", "greeting": "Приємно познайомитися!",
"forgot_password?": "", "forgot_password?": "Забули пароль?",
"already_have_account?": "" "already_have_account?": "Вже маєте акаунт?"
}, },
"words": { "words": {
"delete": "", "delete": "Видалити",
"import": "", "import": "Імпорт",
"public": "", "public": "Громадський",
"upload": "", "upload": "Завантаження",
"player_plural": "", "player_plural": "Гравці",
"next": "", "next": "Далі",
"totp": "", "totp": "Тотп",
"score": "", "score": "Оцінка",
"analytics": "", "analytics": "Аналітика",
"no": "", "no": "Ні",
"speed": "", "speed": "швидкість",
"play": "", "play": "грати",
"email": "", "email": "Адреса електронної пошти",
"backup_code": "", "backup_code": "Резервний код",
"question": "", "question": "Питання",
"files_library": "", "files_library": "Бібліотека файлів",
"check_choice": "", "check_choice": "Перевірте вибір",
"start": "", "start": "старт",
"voting": "", "voting": "Голосування",
"pin": "", "pin": "PIN",
"point": "", "point": "точка",
"docs": "", "docs": "Документи",
"description": "", "description": "Опис",
"settings": "", "settings": "Налаштування",
"features": "", "features": "особливості",
"other": "", "other": "інші",
"title": "", "title": "Назва",
"text": "", "text": "текст",
"register": "", "register": "Журнал",
"username": "", "username": "Ім'я користувача",
"practice": "", "practice": "Практика",
"find": "", "find": "знайти",
"private": "", "private": "Приватнi",
"answer_plural": "", "answer_plural": "Відповіді",
"version": "", "version": "Версія",
"update": "", "update": "оновлення",
"download": "", "download": "Завантажити",
"slide": "", "slide": "слайд",
"repeat_password": "", "repeat_password": "Повторіть пароль",
"kick": "", "kick": "удар ногою",
"url": "", "url": "URL",
"explore": "", "explore": "Дослідити",
"close": "", "close": "Закрити",
"error": "", "error": "Помилка",
"play_plural": "", "play_plural": "П'єси",
"rating": "", "rating": "Рейтинг",
"video": "", "video": "відео",
"browser": "", "browser": "Браузер",
"stats": "", "stats": "статистика",
"password": "", "password": "Пароль",
"donating": "", "donating": "пожертвування",
"save": "", "save": "Зберегти",
"note": "", "note": "Примітка",
"order": "", "order": "порядок",
"dislike_plural": "", "dislike_plural": "Не сподобалося",
"multiple_choice": "", "multiple_choice": "Мульти-Хайце",
"info": "", "info": "Інформація",
"question_plural": "", "question_plural": ";Питання",
"results": "", "results": "Результати",
"view_plural": "", "view_plural": "Перегляди",
"yes": "", "yes": "Так",
"point_plural": "", "point_plural": "Очки",
"continue": "", "continue": "Продовжити",
"game_pin": "", "game_pin": "Гра PIN",
"like": "", "like": "Подобається",
"dislike": "", "dislike": "Не подобається",
"search": "", "search": "Пошук",
"progress": "", "progress": "Прогрес",
"select": "", "select": "Виберіть",
"screenshot": "", "screenshot": "Знімок екрана",
"correct": "", "correct": "Правильно",
"like_plural": "", "like_plural": "Лайки",
"screenshot_plural": "", "screenshot_plural": "Знімки екрана",
"view": "", "view": "Вид",
"name": "", "name": "Ім'я",
"answer": "", "answer": "Відповідь",
"other_plural": "", "other_plural": "Інші",
"count": "", "count": "Кількість",
"login": "", "login": "авторизуватися",
"create": "", "create": "Створити",
"report": "", "report": "Звіт",
"quiztivity": "", "quiztivity": "Допитливість",
"library": "", "library": "Бібліотека",
"finish": "", "finish": "Закінчити",
"normal": "", "normal": "нормальний",
"selected": "", "selected": "Вибране",
"result": "", "result": "Результат",
"unknown": "", "unknown": "Невідомий",
"dashboard": "", "dashboard": "Дашборд",
"back": "", "back": "Назад",
"edit": "", "edit": "Редагувати",
"overview": "", "overview": "Огляд",
"image": "", "image": "Зображення",
"result_plural": "", "result_plural": "Результати",
"submit": "", "submit": "Надіслати",
"never": "", "never": "Ніколи",
"connect": "", "connect": "Підключитися",
"quiz": "", "quiz": "Вікторина",
"range": "", "range": "Діапазон",
"logout": "" "logout": "Вийти",
"player": "гравець"
}, },
"edit_page": { "edit_page": {
"success_update_body": "", "success_update_body": "Інквізиції ніхто не чекатиме.",
"success_update_title": "" "success_update_title": "Тест оновлено."
}, },
"admin_page": { "admin_page": {
"stop_time_and_solutions": "", "stop_time_and_solutions": "Зупиніть час і покажіть рішення",
"already_registered_as_admin": "", "already_registered_as_admin": "Для цієї гри вже зареєстрований адмін.",
"no_answers": "", "no_answers": "Немає відповідей!",
"start_by_showing_first_question": "", "start_by_showing_first_question": "Почніть із показу першого запитання.",
"request_export_results": "", "request_export_results": "Запит на завантаження результатів",
"time_left": "", "time_left": "Час залишився",
"show_next_question": "", "show_next_question": "Показати наступне запитання",
"stop_time": "", "stop_time": "Зупинити час",
"show_results": "", "show_results": "Показати результати",
"save_results": "", "save_results": "Зберегти результати",
"enter_answer_into_field": "", "enter_answer_into_field": "Введіть свою відповідь у поле введення!",
"get_results_and_stop_time": "", "get_results_and_stop_time": "Отримайте результат і зупиніть час",
"start_game": "", "start_game": "Почати гру",
"answers_submitted": "", "answers_submitted": "{{answer_count}} Відповіді надіслано",
"download_export_results": "", "download_export_results": "Завантажити результати",
"next_question": "", "next_question": "Наступне запитання ({{question}})",
"get_results": "", "get_results": "Отримати результати",
"get_final_results": "" "get_final_results": "Отримайте остаточні результати",
"export_results": "Експорт результатів"
}, },
"play_page": { "play_page": {
"2nd_place": "", "2nd_place": "2 місце",
"join_description": "", "join_description": "Приєднайтеся до {{url}} і введіть {{pin}}.",
"1st_place": "", "1st_place": "1 місце",
"points_added": "", "points_added": "Додано бали",
"final_result_rank": "", "final_result_rank": "{{place}}: {{username}} з {{points}} балів",
"your_score": "", "your_score": "Ваша оцінка: {{score}}",
"end_sentence": "", "end_sentence": "Ось і все! Це була вікторина.",
"with_out_of": "", "with_out_of": "з {{correct_questions}} із {{total_question_count}}",
"3rd place": "", "3rd place": "3 місце",
"join_by_entering_code": "" "join_by_entering_code": "Приєднайтеся, ввівши наступний код",
"your_place": "Ви на місці {{place}}!",
"players_waiting": "{{count}} гравець чекає",
"players_waiting_plural": "{{count}} гравці чекають"
}, },
"file_dashboard": { "file_dashboard": {
"unset": "", "unset": "Не встановлено",
"filename_word": "", "filename_word": "Ім'я файлу",
"imported": "", "imported": "Імпортовано: {{yes_or_no}}",
"filename": "", "filename": "Ім'я файлу: {{filename}}",
"missing": "", "missing": "ВІДСУТИЙ!",
"delete_image": "", "delete_image": "Видалити зображення",
"size": "", "size": "Розмір: {{size}} MiB",
"storage_usage": "", "storage_usage": "Ви використали {{used}} MiB із {{total}} MiB пам’яті. Це еквівалентно {{percent}}% вашого обсягу пам’яті.",
"alt_text": "", "alt_text": "Альтернативний текст / Підпис",
"edit_details": "", "edit_details": "Редагувати деталі",
"uploaded": "", "uploaded": "Завантажено: {{date}}",
"not_available": "", "not_available": "Не доступний",
"caption": "", "caption": "Підпис: {{caption}}",
"edit_the_image": "" "edit_the_image": "Відредагуйте зображення"
}, },
"avatar_settings": { "avatar_settings": {
"accessories_type": "", "accessories_type": "Окуляри",
"go_back": "", "go_back": "Іди назад",
"hair_color": "", "hair_color": "Колір волосся",
"clothe_graphic_type": "", "clothe_graphic_type": "Графічний",
"facial_hair_type": "", "facial_hair_type": "Волосся на обличчі",
"facial_hair_color": "", "facial_hair_color": "Колір волосся на обличчі",
"skin_color": "", "skin_color": "Колір шкіри",
"clothe_color": "", "clothe_color": "Колір одягу",
"thats_you": "", "thats_you": "Це ти!",
"start_over": "", "start_over": "Почніть спочатку",
"clothe_type": "", "clothe_type": "Одяг",
"mouth_type": "", "mouth_type": "Рот",
"top_type": "", "top_type": "Топ",
"eyebrow_type": "", "eyebrow_type": "Брова",
"hat_color": "" "hat_color": "Колір капелюха"
}, },
"overview_page": { "overview_page": {
"question_count": "", "question_count": "Кількість питань",
"created_at": "", "created_at": "Створено в",
"no_quizzes": "" "no_quizzes": "Натисніть кнопку «Створити» або імпортуйте тест, щоб почати."
}, },
"settings_page": { "settings_page": {
"change_avatar": "", "change_avatar": "Змінити аватар",
"change_password_submit": "", "change_password_submit": "Змінити пароль!",
"security_settings": "", "security_settings": "Налаштування безпеки",
"delete_this_session": "", "delete_this_session": "Видалити цей сеанс",
"old_password": "", "old_password": "Старий пароль",
"check_location": "", "check_location": "Перевірте місцезнаходження",
"last_seen": "", "last_seen": "Востаннє бачили",
"this_session?": "", "this_session?": "Ця сесія?",
"repeat_password": "", "repeat_password": "Повторіть пароль",
"new_password": "", "new_password": "Новий пароль",
"add_api_key": "" "add_api_key": "Додайте ключ API"
}, },
"footer": { "footer": {
"donate": "", "donate": "Якщо ви вважаєте це корисним, спробуйте {{donate_link}}.",
"more_details_here": "", "more_details_here": "Детальніше тут",
"self_ads": "" "self_ads": "Створено з ❤️ {{mawoka_link}} та за допомогою {{others_link}}."
}, },
"quiztivity": { "quiztivity": {
"editor": { "editor": {
"add_new": "", "add_new": "Додати новий",
"move_left": "", "move_left": "Рух ліворуч",
"shares": { "shares": {
"never_expires": "", "never_expires": "Ніколи не закінчується",
"expires_on": "", "expires_on": "Термін дії закінчується {{date}}",
"add_new_share": "" "add_new_share": "Додати новий спільний доступ"
}, },
"title_placeholder": "", "title_placeholder": "Введіть назву тут",
"delete": "", "delete": "Видалити",
"open_shares_menu": "", "open_shares_menu": "Відкрийте меню «Спільний доступ»",
"select_page_type": "", "select_page_type": "Виберіть Тип сторінки",
"move_right": "" "move_right": "Рух праворуч"
}, },
"share_expired": "", "share_expired": "Термін дії частки минув",
"play": { "play": {
"memory": { "memory": {
"try_count": "" "try_count": "Спроб: {{try_count}}"
} }
}, },
"memory": { "memory": {
"editor": { "editor": {
"add_card": "", "add_card": "Додати картку",
"add_pair": "", "add_pair": "Додайте пару",
"upload_image": "" "upload_image": "Завантажити зображення"
} }
} }
}, },
"results_page": { "results_page": {
"no_results_so_far": "", "no_results_so_far": "Результати поки що не збережено...",
"quiz_title": "", "quiz_title": "Назва вікторини",
"player_count": "", "player_count": "Кількість гравців",
"date_played": "", "date_played": "Дата гри",
"general_overview": { "general_overview": {
"sentence": "" "sentence": "У вікторині \"{{title}}\", яка проходила {{date}}, брали участь {{player_count}} гравців із середнім балом {{average_score}}."
} }
}, },
"security_settings": { "security_settings": {
"get_backup_code": "", "get_backup_code": "Отримати резервний код",
"enable_totp": "", "enable_totp": "Увімкніть TOTP",
"disable_totp": "", "disable_totp": "Вимкніть TOTP",
"totp_setup": { "totp_setup": {
"enter_as_secret_if_no_see_code": "", "enter_as_secret_if_no_see_code": "Введіть це як секрет, якщо ви не можете відсканувати QR-код",
"scan_to_set_up": "", "scan_to_set_up": "Відскануйте цей QR-код, щоб налаштувати код",
"totp_setup": "", "totp_setup": "TOTP-налаштування",
"do_not_forget_backup_code": "" "do_not_forget_backup_code": "Не забудьте зберегти свій код відновлення!"
}, },
"backup_code": "", "backup_code": "Резервний код",
"2fa_deactivated": "", "2fa_deactivated": "Двофакторну автентифікацію вимкнено",
"backup_codes": { "backup_codes": {
"download_code": "", "download_code": "Завантажити код",
"your_backup_code": "", "your_backup_code": "Ваш резервний код",
"save_somewhere_save": "" "save_somewhere_save": "Збережіть це в безпечному місці!"
}, },
"totp": "", "totp": "TOTP",
"totp_unavailable": "", "totp_unavailable": "TOTP недоступний",
"2fa_activated": "", "2fa_activated": "Двофакторна аутентифікація активована",
"webauthn": "", "webauthn": "Webauthn",
"add_security_key": "", "add_security_key": "Додайте ключ безпеки",
"activate_2fa": "", "activate_2fa": "Активуйте двофакторну автентифікацію",
"webauthn_unavailable": "", "webauthn_unavailable": "Webauthn недоступний",
"totp_available": "", "totp_available": "TOTP доступний",
"webauthn_available": "" "webauthn_available": "Webauthn доступний"
}, },
"editor": { "editor": {
"delete_answer": "", "delete_answer": "Видалити відповідь",
"check_choice_description": "", "check_choice_description": "Щоб набрати бали, потрібно вибрати всі правильні відповіді",
"text_description": "", "text_description": "Гравці можуть вводити текст",
"order_description": "", "order_description": "Відповіді можна привести в правильний порядок",
"add_new_answer": "", "add_new_answer": "Додайте нову відповідь",
"slide": { "slide": {
"headline": "", "headline": "Заголовок",
"headline_description": "", "headline_description": "Жирний текст для заголовків",
"rectangle": "", "rectangle": "Прямокутник",
"rectangle_description": "", "rectangle_description": "Просто прямокутник",
"text": "", "text": "текст",
"text_description": "" "text_description": "Менший довший текст"
}, },
"voting_description": "", "voting_description": "Відповіді не додають балів",
"not_all_links_imgur_links": "", "not_all_links_imgur_links": "Не всі посилання є посиланнями на Imgur!",
"delete_question": "", "delete_question": "Видалити запитання",
"range_description": "", "range_description": "Діапазон чисел можна вибрати за допомогою повзунка",
"empty": "", "empty": "Порожній...",
"right_or_true?": "", "right_or_true?": "правильно?",
"abcd_description": "", "abcd_description": "Можна вибрати лише одну відповідь",
"time_in_seconds": "", "time_in_seconds": "Час у секундах",
"add_new_question": "", "add_new_question": "Додайте нове питання",
"bg_image": "", "bg_image": "Фонове зображення",
"no_title": "" "no_title": "Без назви...",
"advanced_settings": "Розширені налаштування",
"hide_question_results": "Приховати результати запитання?",
"need_more_help": "Потрібна додаткова допомога?",
"visit_docs": "Відвідайте документи.",
"enter_answer": "Введіть відповідь",
"enable_reorder": "Увімкнути режим зміни порядку",
"disable_reorder": "Вимкнути режим зміни порядку"
}, },
"controllers": { "controllers": {
"last_seen": "", "last_seen": "Востаннє бачили",
"cancel_update": "", "cancel_update": "Скасувати оновлення!",
"add_new_controller": "", "add_new_controller": "Додайте новий контролер",
"player_name": "", "player_name": "Ім'я гравця",
"controller_name": "", "controller_name": "Ім'я контролера",
"already_latest_version": "", "already_latest_version": "Ви вже використовуєте останню версію",
"update_from_to": "", "update_from_to": "Оновлення з {{current_version}} на {{newest_version}}",
"first_seen": "", "first_seen": "Перший побачений",
"version_overview": "" "version_overview": "Найновішою доступною версією є {{newest_version}}, а встановлено версію {{current_version}}."
}, },
"view_quiz_page": { "view_quiz_page": {
"made_by": "", "made_by": "Зроблено",
"view_on_kahoot": "" "view_on_kahoot": "Переглянути на оригіналі"
}, },
"import_page": { "import_page": {
"this_side_classquiz_excel": "", "this_side_classquiz_excel": "Ви також можете завантажити файли Excel, якщо ви заповнили наведений нижче шаблон. Якщо вікторина з назвою вже існує, вона додасть запитання до наявної вікторини.",
"visit_docs": "", "visit_docs": "Відвідайте документацію",
"download_template_here": "", "download_template_here": "Завантажте шаблон",
"classquiz_quiz": "", "classquiz_quiz": "А ClassQuiz-вікторина",
"this_side_classquiz": "", "this_side_classquiz": "На цій стороні ви можете імпортувати тести, які були експортовані з ClassQuiz.",
"a_kahoot_quiz": "", "a_kahoot_quiz": "Вікторина Kahoot",
"side_import_kahoot": "", "side_import_kahoot": "На цій стороні ви можете імпортувати тести, які живуть на Kahoot!.",
"url_should_look_like_this": "", "url_should_look_like_this": "URL-адреса має виглядати так: https://create.kahoot.it/details/...",
"need_help": "", "need_help": "Потрібна допомога?",
"upload_file_ending": "" "upload_file_ending": "Завантажте файл із розширенням .cqa або .xlsx"
}, },
"start_game": { "start_game": {
"old_school_mode_description": "", "old_school_mode_description": "Запитання та зображення відображатимуться як на екрані адміністратора, так і на екрані гравців",
"old_school_mode": "", "old_school_mode": "Стара школа",
"start_game": "", "start_game": "Почати гру",
"captcha_message": "", "captcha_message": "Якщо ввімкнено, ReCaptcha Google завантажуватиметься у браузері гравців. Увімкніть лише якщо вам це дійсно потрібно, оскільки вам потрібна згода КОЖНОГО гравця для завантаження капчі.",
"normal_mode_description": "" "normal_mode_description": "Питання та відповідь відображатимуться лише на екрані адміністратора. На екрані адміністратора гравці матимуть лише кольорові кнопки з відповідними символами."
}, },
"login_page": { "login_page": {
"use_backup_code": "", "use_backup_code": "Використовуйте резервний код",
"email_or_username": "", "email_or_username": "Електронна пошта або ім'я користувача",
"already_have_account": "", "already_have_account": "Немає облікового запису?",
"modal": { "modal": {
"error": { "error": {
"description": { "description": {
"unexpected": "", "unexpected": "Сталася стара добра несподівана помилка!",
"wrong_creds": "" "wrong_creds": "Переконайтеся, що ваш пароль та адреса електронної пошти правильні."
}, },
"wrong_creds": "", "wrong_creds": "Неправильна адреса електронної пошти або пароль.",
"unexpected": "" "unexpected": "Несподівана помилка!"
}, },
"success": { "success": {
"success": "", "success": "Увійшли в систему.",
"description": { "description": {
"success": "", "success": "Увійшли в систему.",
"success_check_mail": "" "success_check_mail": "Будь ласка, перевірте свою електронну скриньку на наявність електронного листа з посиланням, на яке можна натиснути, щоб увійти."
}, },
"success_check_mail": "" "success_check_mail": "Увійшли. Перевірте свою електронну скриньку."
} }
}, },
"login_or_create_account": "", "login_or_create_account": "Увійдіть або створіть обліковий запис",
"welcome_back": "" "welcome_back": "Ласкаво просимо назад."
}, },
"password_reset_page": { "password_reset_page": {
"reset_password": "" "reset_password": "Скинути пароль"
}, },
"video_uploader": { "video_uploader": {
"time_remaining": "", "time_remaining": "Час, що залишився",
"time_elapsed": "" "time_elapsed": "Минув час"
}, },
"explore_page": { "explore_page": {
"imported_by": "", "imported_by": "Імпортовано",
"made_by": "" "made_by": "Зроблено"
}, },
"create_page": { "create_page": {
"success": { "success": {
"title": "", "title": "Вікторину створено.",
"body": "" "body": "Нехай ігри починаються."
} }
}, },
"error_page": { "error_page": {
"unknown_error_text": "", "unknown_error_text": "Такого не повинно бути. Можливо, це моя вина, а не твоя, але, можливо, ти маєш магічну силу ламати щось...",
"404_text": "" "404_text": "Сторінка, яку ви шукали, зникла або взагалі не існувала. хто знає?"
}, },
"uploader": { "uploader": {
"images_by_pixabay": "", "images_by_pixabay": "Зображення надано Pixabay",
"upload_video_popup_notice": "", "upload_video_popup_notice": "Спливаюче вікно відкрито; перегляньте його для отримання додаткової інформації",
"add_image": "", "add_image": "Додати медіа",
"select_upload_type": "", "select_upload_type": "Виберіть тип завантаження",
"upload_a_video": "", "upload_a_video": "Завантажте відео",
"next_page": "", "next_page": "Наступна сторінка",
"visit_pixabay": "", "visit_pixabay": "Відвідайте Pixabay",
"previous_page": "", "previous_page": "Попередня сторінка",
"search_english_only": "", "search_english_only": "Пошук працює лише англійською мовою",
"upload_video": "" "upload_video": "Завантажити відео"
}, },
"search_page": { "search_page": {
"nothing_here": "", "nothing_here": "Тут немає нічого...",
"at_least_3_characters": "" "at_least_3_characters": "Введіть принаймні 3 символи..."
}, },
"dashboard": { "dashboard": {
"commandpalette_notice": "", "commandpalette_notice": "Натисніть <kbd>Ctr</kbd>+<kbd>k</kbd> або <kbd>Meta</kbd>+<kbd>k</kbd>, щоб відкрити панель команд",
"views_n_plays": "", "views_n_plays": "Перегляди та відтворення",
"search_for_own_quizzes": "", "search_for_own_quizzes": "Шукайте власні тести",
"info_analytics": "" "info_analytics": "«Відтворення» показують лише те, як часто запускали вікторину (включно з вами), тоді як «Перегляди» підраховують, як часто відвідували сторінку «Перегляд», тому також враховуються роботи (вибачте за це)."
}, },
"navbar": { "navbar": {
"donate": "" "donate": "Пожертвуйте"
}, },
"editor_page": { "editor_page": {
"add_an_answer": "", "add_an_answer": "Додайте відповідь",
"right_click_to_delete": "" "right_click_to_delete": "Клацніть правою кнопкою миші на відповідь, щоб видалити її!"
}, },
"public_user_page": { "public_user_page": {
"no_original_quizzes": "", "no_original_quizzes": "Цей користувач не має оригінальних тестів",
"joined_on": "" "joined_on": "Приєднався {{date}}",
"user_not_found": "Користувача не знайдено"
}, },
"components": { "components": {
"popover": { "popover": {
"copied_to_clipboard": "" "copied_to_clipboard": "Скопійовано в буфер обміну!"
} }
},
"downloader": {
"select_download_type": "Виберіть тип завантаження",
"own_format": "Власний формат",
"excel_format": "Формат Excel",
"help": "Власний формат (.cqa) також містить зображення та підтримує всі типи запитань, тоді як формат excel підтримує лише голосування та запитання з кількома варіантами відповідей."
} }
} }
+31 -31
View File
@@ -2,47 +2,47 @@
"index_page": { "index_page": {
"meta": { "meta": {
"title": "首页", "title": "首页",
"description": "ClassQuiz是提供给学生的一个类似Kahoot!的测试应用,其开源且可免费使用" "description": "ClassQuiz是一个类似Kahoot!的学生测验应用,它是开源的,可以免费使用"
}, },
"slogan": "提供测试的开源平台!", "slogan": "开源的测验平台!",
"quiz_results_downloadable": "", "quiz_results_downloadable": "测验结果可供下载",
"completely_free": "", "completely_free": "完全免费",
"how_does_classquiz_work": "", "how_does_classquiz_work": "",
"select_answer": "", "select_answer": "选择答案",
"user_friendly": "", "user_friendly": "用户友好型",
"no_tracking": "", "no_tracking": "没有跟踪",
"find_or_explore": "", "find_or_explore": "查找(或探索)由其他人制作或导入的测验",
"completely_free_content": "", "completely_free_content": "",
"stats": "", "stats": "ClassQuiz上已经有{{user_count}}个用户和{{quiz_count}个测验。",
"see_how_many_true_and_false": "", "see_how_many_true_and_false": "看看对了几个,错了几个",
"download_quizzes": "", "download_quizzes": "",
"dark_mode_content": "", "dark_mode_content": "",
"multilingual": "", "multilingual": "多语言",
"community_driven_content": "", "community_driven_content": "",
"get_a_quiz": "", "get_a_quiz": "1. 获取一个测验",
"quiz_results_downloadable_content": "", "quiz_results_downloadable_content": "",
"view_results": "", "view_results": "查看结果",
"choose_answer_wisely": "", "choose_answer_wisely": "明智地选择你的答案",
"self_hostable_content": "", "self_hostable_content": "ClassQuiz可以很容易的自行部署,所以数据只在你的控制之下!",
"german_server_content": "", "german_server_content": "",
"get_ranking_and_winners": "", "get_ranking_and_winners": "查看排名,看看谁赢了",
"list_winners": "", "list_winners": "列出获胜者",
"students_site": "", "students_site": "学生网站",
"self_hostable": "", "self_hostable": "可自行部署",
"see_what_true_and_false": "", "see_what_true_and_false": "看看什么是对的,什么是错的",
"german_server": "", "german_server": "德国服务器",
"create_a_quiz_from_scratch": "", "create_a_quiz_from_scratch": "用编辑器从头开始创建一个测验,包括图片和更多内容",
"teachers_site": "", "teachers_site": "教师网站",
"check_if_chosen_wisely": "", "check_if_chosen_wisely": "检查你是否明智选择了",
"user_friendly_content": "", "user_friendly_content": "ClassQuiz的目标是简约方便,以便所有人使用。",
"create_or_import": "", "create_or_import": "创建或导入",
"no_tracking_content": "", "no_tracking_content": "其他工具会跟踪你并将这些信息发送给第三方,但ClassQuiz不会。",
"multilingual_content": "", "multilingual_content": "",
"dark_mode": "", "dark_mode": "暗黑模式",
"why_classquiz": "", "why_classquiz": "为什么选择ClassQuiz",
"community_driven": "", "community_driven": "",
"play_quiz": "", "play_quiz": "2. 开始测验",
"see_all_quizzes": "", "see_all_quizzes": "查看您的所有测验",
"download_quizzes_content": "" "download_quizzes_content": ""
}, },
"result_page": { "result_page": {
+245 -225
View File
@@ -2,58 +2,60 @@
"index_page": { "index_page": {
"meta": { "meta": {
"title": "首頁", "title": "首頁",
"description": "ClassQuiz 是一款為學生設計的似 Kahoot! 測驗應用程式,不僅開源還免費" "description": "ClassQuiz 是一款為學生設計的學習測驗應用程式,不僅開源而且還可以免費使用"
}, },
"slogan": "開的測驗平台!", "slogan": "開放原始碼的測驗平台!",
"create_or_import": "建立或匯入", "create_or_import": "建立或匯入",
"see_all_quizzes": "查看你所有的測驗", "see_all_quizzes": "檢視你所有的測驗",
"teachers_site": "教師頁面", "teachers_site": "教師專區",
"students_site": "學生頁面", "students_site": "學生專區",
"no_tracking": "追蹤", "no_tracking": "追蹤",
"self_hostable": "可自行架設", "self_hostable": "可自行架設",
"german_server": "德國伺服器", "german_server": "德國伺服器",
"user_friendly": "易於使用", "user_friendly": "使用者友善",
"completely_free": "完全免費", "completely_free": "完全免費",
"multilingual": "多語言", "multilingual": "多語言",
"dark_mode": "深色模式", "dark_mode": "深色模式",
"get_a_quiz": "1. 取得測驗", "get_a_quiz": "1. 取得測驗",
"create_a_quiz_from_scratch": "使用編輯器建立測驗並加入圖片和更多內容", "create_a_quiz_from_scratch": "使用編輯器從頭開始建立測驗並加入圖片和更多內容",
"import_quiz_from_kahoot_and_edit": "從 Kahoot! 匯入測驗並在 ClassQuiz 上進行編輯", "import_quiz_from_kahoot_and_edit": "從 Kahoot! 匯入測驗並在 ClassQuiz 上進行編輯",
"play_quiz": "2. 遊玩測驗", "play_quiz": "2. 進行測驗",
"select_answer": "選擇答案", "select_answer": "選擇答案",
"choose_answer_wisely": "明智地選擇你的答案", "choose_answer_wisely": "謹慎選擇你的答案",
"view_results": "檢視結果", "view_results": "檢視結果",
"check_if_chosen_wisely": "驗證你的選擇是否正確", "check_if_chosen_wisely": "檢查你是否做了明智的選擇",
"list_winners": "列出贏家", "list_winners": "列出獲勝者",
"get_ranking_and_winners": "取得排名和贏家", "get_ranking_and_winners": "檢視排名和獲勝者",
"why_classquiz": "為什麼選擇 ClassQuiz", "why_classquiz": "為選擇 ClassQuiz",
"download_quizzes": "下載測驗", "download_quizzes": "下載測驗",
"stats": "ClassQuiz 上已有 {{user_count}} 位使用者和 {{quiz_count}} 個測驗。", "stats": "ClassQuiz 上已有 {{user_count}} 位使用者和 {{quiz_count}} 個測驗。",
"features_description": { "features_description": {
"1": "ClassQuiz 是一個可以讓你建立和管理測驗的測驗平台。", "1": "ClassQuiz 是一個可以讓你建立和管理測驗的測驗平台。",
"2": "最主要的功能之一是允許你匯入 Kahoot! 上的測驗。", "2": "最主要的功能之一是允許你匯入 Kahoot! 上的測驗。",
"3": "編輯器和可將測驗結果匯出為 Excel 檔為此軟體的幾個亮點。" "3": "編輯器和可將測驗結果匯出為 Excel 檔為此軟體的幾個亮點。"
}, },
"quiz_results_downloadable": "可被下載的測驗結果", "quiz_results_downloadable": "可被下載的測驗結果",
"find_or_explore": "搜尋 (或瀏覽) 其他人建立匯入的測驗", "find_or_explore": "尋找(或探索)其他人建立匯入的測驗",
"no_tracking_content": "Kahoot! 會追蹤並將你的資料分享給第三方,但 ClassQuiz 不會。", "no_tracking_content": "其他測驗平台會追蹤並將你的資料分享給第三方,但 ClassQuiz 不會。",
"user_friendly_content": "ClassQuiz 旨在簡單,每個人都可以輕鬆使用。", "user_friendly_content": "ClassQuiz 以簡潔易用為目標,讓每個人都能輕鬆上手。",
"dark_mode_content": "一個網站重要功能之一", "dark_mode_content": "一個網站必備的重要功能!",
"german_server_content": "ClassQuiz 的伺服器位於德國,並由 netcup 提供。", "german_server_content": "ClassQuiz 的伺服器位於德國,並由 netcup 提供代管服務。",
"how_does_classquiz_work": "ClassQuiz 是如何運作的?", "how_does_classquiz_work": "ClassQuiz 究竟是如何運作的?",
"see_how_many_true_and_false": "看看有多少人是對的或錯的", "see_how_many_true_and_false": "看看有多少人答對或答錯",
"completely_free_content": "ClassQuiz 完全免費 (對用戶而言),沒有任何訂閱機制,也不會惱人地重新定向至升級頁面。你的捐贈我們不勝感激。", "completely_free_content": "ClassQuiz 完全免費(對使用者而言,沒有任何付費訂閱機制,也不會出現惱人的升級頁面。歡迎捐款贊助支持。",
"see_what_true_and_false": "看看什麼是對的,什麼是錯的", "see_what_true_and_false": "看看哪些問題答對或答錯",
"self_hostable_content": "輕鬆地自行架設 ClassQuiz ,資料只由你掌控!", "self_hostable_content": "輕鬆地自行架設 ClassQuiz,資料只由你掌控!",
"quiz_results_downloadable_content": "測驗結果可以簡單地被匯出 Excel 試算表。(不知道其他類似的服務沒有提供此功能)", "quiz_results_downloadable_content": "測驗結果可以輕鬆匯出 Excel 試算表。(沒想到其他服務竟然沒有這個功能",
"community_driven": "社群驅動", "community_driven": "社群驅動",
"community_driven_content": "ClassQuiz 依靠它的社群提供援、測試想法、功能求、翻譯...等!你也可以成為 ClassQuiz 社群成員之一", "community_driven_content": "ClassQuiz 仰賴社群提供資金支援、測試想法、功能求、翻譯等!你也可以成為 ClassQuiz 社群的一份子",
"multilingual_content": "", "multilingual_content": "ClassQuiz 提供英文、法文、德文、義大利文、挪威語(書面語)、土耳其文,以及部分印尼文和加泰隆尼亞文版本。",
"download_quizzes_content": "" "download_quizzes_content": "測驗可以下載成一個檔案,並隨時匯入。這也讓你能夠將測驗移動到其他的 ClassQuiz 站台。",
"no_player_limit_content": "ClassQuiz 沒有任何人為的玩家人數限制。理論上可以讓超過 1000 位玩家同時進行測驗,不過目前在單一測驗中只有測試過最多 300 位玩家。",
"no_player_limit": "無人數限制"
}, },
"edit_page": { "edit_page": {
"success_update_title": "測驗已更新。", "success_update_title": "測驗已更新。",
"success_update_body": "" "success_update_body": "沒有人會預料到這次的測驗突襲。"
}, },
"create_page": { "create_page": {
"success": { "success": {
@@ -62,35 +64,35 @@
} }
}, },
"register_page": { "register_page": {
"create_account": "建立帳", "create_account": "建立帳",
"forgot_password?": "忘記密碼?", "forgot_password?": "忘記密碼?",
"already_have_account?": "已經有帳", "already_have_account?": "已經有帳號了",
"greeting": "很高興見到你!" "greeting": "很高興見到你!"
}, },
"login_page": { "login_page": {
"login_or_create_account": "登入或建立帳", "login_or_create_account": "登入或建立帳",
"already_have_account": "沒有帳", "already_have_account": "沒有帳",
"modal": { "modal": {
"error": { "error": {
"wrong_creds": "電子信箱地址或密碼錯誤。", "wrong_creds": "電子郵件地址或密碼錯誤。",
"unexpected": "預期錯誤!", "unexpected": "發生無法預期錯誤!",
"description": { "description": {
"wrong_creds": "請確認你的密碼和電子信箱地址是否正確。", "wrong_creds": "請確認你的密碼和電子郵件地址正確無誤。",
"unexpected": "非預期錯誤" "unexpected": "那個熟悉的意外錯誤又出現了"
} }
}, },
"success": { "success": {
"success": "已登入。", "success": "已登入。",
"success_check_mail": "已登入。請檢查你的電子信箱收件匣。", "success_check_mail": "已登入。請檢查你的電子郵件收件匣。",
"description": { "description": {
"success": "已登入。", "success": "已登入。",
"success_check_mail": "" "success_check_mail": "請檢查你的電子郵件收件匣,裡面有一封包含登入連結的郵件。"
} }
} }
}, },
"welcome_back": "歡迎回來。", "welcome_back": "歡迎回來。",
"use_backup_code": "使用備用代碼", "use_backup_code": "使用備用代碼",
"email_or_username": "電子信箱或使用者名稱" "email_or_username": "電子郵件或使用者名稱"
}, },
"editor": { "editor": {
"delete_question": "刪除問題", "delete_question": "刪除問題",
@@ -103,32 +105,39 @@
"bg_image": "背景圖片", "bg_image": "背景圖片",
"slide": { "slide": {
"rectangle": "長方形", "rectangle": "長方形",
"headline": "", "headline": "標題",
"headline_description": "", "headline_description": "用於標題的粗體文字",
"rectangle_description": "", "rectangle_description": "就是個長方形",
"text": "", "text": "文字",
"text_description": "" "text_description": "較小、較長的文字"
}, },
"check_choice_description": "", "check_choice_description": "必須選出所有正確答案才能得分",
"text_description": "", "text_description": "玩家可以輸入文字",
"order_description": "", "order_description": "可以將答案排列成正確的順序",
"voting_description": "", "voting_description": "答案不計分",
"range_description": "", "range_description": "可以使用滑桿選擇數字範圍",
"empty": "", "empty": "空白...",
"abcd_description": "", "abcd_description": "只能選擇一個答案",
"time_in_seconds": "" "time_in_seconds": "時間(秒)",
"advanced_settings": "進階設定",
"hide_question_results": "隱藏問題結果?",
"enter_answer": "輸入答案",
"need_more_help": "需要更多協助嗎?",
"visit_docs": "查看說明文件。",
"enable_reorder": "啟用重新排序模式",
"disable_reorder": "停用重新排序模式"
}, },
"import_page": { "import_page": {
"need_help": "需要幫助", "need_help": "需要協助嗎",
"visit_docs": "檢視說明文件", "visit_docs": "查看說明文件",
"url_should_look_like_this": "URL 看起來應該像這樣:https://create.kahoot.it/details/...", "url_should_look_like_this": "網址格式應該像這樣:https://create.kahoot.it/details/...",
"a_kahoot_quiz": "一個 Kahoot! 測驗", "a_kahoot_quiz": "Kahoot! 測驗",
"this_side_classquiz": "你可以在這邊匯入 ClassQuiz 測驗。", "this_side_classquiz": "你可以在這邊匯入 ClassQuiz 匯出的測驗。",
"side_import_kahoot": "你可以在這邊匯入 Kahoot! 測驗。", "side_import_kahoot": "你可以在這邊匯入 Kahoot! 上的測驗。",
"upload_file_ending": "上傳副檔名為 cqa 的檔案", "upload_file_ending": "上傳副檔名為 .cqa 或 .xlsx 的檔案",
"classquiz_quiz": "一個 ClassQui 測驗", "classquiz_quiz": "ClassQuiz 測驗",
"this_side_classquiz_excel": "", "this_side_classquiz_excel": "如果你已經填好範本,也可以直接上傳 Excel 檔案。如果已存在相同標題的測驗,則會將問題附加到現有的測驗中。",
"download_template_here": "" "download_template_here": "下載範本"
}, },
"admin_page": { "admin_page": {
"start_game": "開始遊戲", "start_game": "開始遊戲",
@@ -140,16 +149,16 @@
"time_left": "剩餘時間", "time_left": "剩餘時間",
"stop_time": "停止計時", "stop_time": "停止計時",
"no_answers": "沒有答案!", "no_answers": "沒有答案!",
"start_by_showing_first_question": "開始時顯示第一個問題。", "start_by_showing_first_question": "顯示第一個問題開始。",
"save_results": "儲存結果", "save_results": "儲存結果",
"already_registered_as_admin": "此遊戲已有一位管理員。", "already_registered_as_admin": "此遊戲已有一位管理員。",
"stop_time_and_solutions": "停止計時並顯示解答", "stop_time_and_solutions": "停止計時並顯示解答",
"enter_answer_into_field": "在輸入欄輸入你的答案!", "enter_answer_into_field": "在輸入欄位中輸入你的答案!",
"show_results": "顯示結果", "show_results": "顯示結果",
"next_question": "下個問題 ({{question}})", "next_question": "下個問題{{question}}",
"request_export_results": "", "request_export_results": "請求下載結果",
"answers_submitted": "", "answers_submitted": "已提交 {{answer_count}} 個答案",
"download_export_results": "" "download_export_results": "下載結果"
}, },
"password_reset_page": { "password_reset_page": {
"reset_password": "重設密碼" "reset_password": "重設密碼"
@@ -163,9 +172,9 @@
"delete_this_session": "刪除此工作階段", "delete_this_session": "刪除此工作階段",
"this_session?": "這個工作階段?", "this_session?": "這個工作階段?",
"security_settings": "安全性設定", "security_settings": "安全性設定",
"change_avatar": "", "change_avatar": "變更頭像",
"last_seen": "", "last_seen": "最後上線時間",
"add_api_key": "" "add_api_key": "新增 API 金鑰"
}, },
"explore_page": { "explore_page": {
"made_by": "作者為", "made_by": "作者為",
@@ -177,32 +186,35 @@
"with_out_of": "{{total_question_count}} 題中答對 {{correct_questions}} 題", "with_out_of": "{{total_question_count}} 題中答對 {{correct_questions}} 題",
"1st_place": "第一名", "1st_place": "第一名",
"end_sentence": "完成!本次測驗結束。", "end_sentence": "完成!本次測驗結束。",
"your_score": "", "your_score": "你的分數:{{score}}",
"join_description": " {{url}} 加入並輸入 {{pin}}。", "join_description": "前往 {{url}} 並輸入 {{pin}} 加入。",
"points_added": "", "points_added": "已加分",
"final_result_rank": "", "final_result_rank": "第 {{place}} 名:{{username}},得到 {{points}} 分",
"join_by_entering_code": "" "join_by_entering_code": "輸入以下代碼加入",
"your_place": "你目前排名第 {{place}}",
"players_waiting": "有 {{count}} 位玩家正在等待",
"players_waiting_plural": "有 {{count}} 位玩家正在等待"
}, },
"editor_page": { "editor_page": {
"add_an_answer": "新增一個答案", "add_an_answer": "新增一個答案",
"right_click_to_delete": "右鍵點擊一個答案即可將它刪除!" "right_click_to_delete": "在答案上按一下右鍵即可刪除!"
}, },
"footer": { "footer": {
"more_details_here": "更多詳細資訊", "more_details_here": "更多詳細資訊請見此處",
"self_ads": "由 {{mawoka_link}} 在 {{other_link}} 的協助下 ❤️ 製作。", "self_ads": "由 {{mawoka_link}} 在 {{others_link}} 的協助下 ❤️ 製作。",
"donate": "若你覺得這很實用,請考慮 {{donate_link}}。" "donate": "若你覺得這很實用,請考慮 {{donate_link}}。"
}, },
"uploader": { "uploader": {
"add_image": "新增圖片", "add_image": "新增媒體",
"images_by_pixabay": "", "images_by_pixabay": "圖片由 Pixabay 提供",
"upload_video_popup_notice": "", "upload_video_popup_notice": "彈出視窗已開啟;請檢視以取得更多資訊",
"select_upload_type": "", "select_upload_type": "選擇上傳類型",
"upload_a_video": "", "upload_a_video": "上傳影片",
"next_page": "", "next_page": "下一頁",
"visit_pixabay": "", "visit_pixabay": "前往 Pixabay",
"previous_page": "", "previous_page": "上一頁",
"search_english_only": "", "search_english_only": "搜尋只支援英文",
"upload_video": "" "upload_video": "上傳影片"
}, },
"words": { "words": {
"find": "尋找", "find": "尋找",
@@ -211,7 +223,7 @@
"stats": "統計資料", "stats": "統計資料",
"features": "功能", "features": "功能",
"login": "登入", "login": "登入",
"email": "電子信箱地址", "email": "電子郵件地址",
"username": "使用者名稱", "username": "使用者名稱",
"password": "密碼", "password": "密碼",
"edit": "編輯", "edit": "編輯",
@@ -221,9 +233,9 @@
"import": "匯入", "import": "匯入",
"logout": "登出", "logout": "登出",
"title": "標題", "title": "標題",
"url": "URL", "url": "網址",
"submit": "提交", "submit": "提交",
"pin": "PIN", "pin": "PIN",
"kick": "踢出", "kick": "踢出",
"register": "註冊", "register": "註冊",
"close": "關閉", "close": "關閉",
@@ -232,7 +244,7 @@
"image": "圖片", "image": "圖片",
"settings": "設定", "settings": "設定",
"repeat_password": "再次輸入密碼", "repeat_password": "再次輸入密碼",
"explore": "發現", "explore": "探索",
"screenshot": "螢幕截圖", "screenshot": "螢幕截圖",
"screenshot_plural": "螢幕截圖", "screenshot_plural": "螢幕截圖",
"browser": "瀏覽器", "browser": "瀏覽器",
@@ -244,10 +256,10 @@
"private": "私人", "private": "私人",
"dashboard": "儀錶板", "dashboard": "儀錶板",
"question_plural": "問題", "question_plural": "問題",
"game_pin": "遊戲 PIN", "game_pin": "遊戲 PIN",
"other": "其他", "other": "其他",
"search": "搜尋", "search": "搜尋",
"other_plural": "其他", "other_plural": "其他",
"download": "下載", "download": "下載",
"voting": "投票", "voting": "投票",
"docs": "文件", "docs": "文件",
@@ -256,8 +268,8 @@
"error": "錯誤", "error": "錯誤",
"continue": "繼續", "continue": "繼續",
"backup_code": "備用代碼", "backup_code": "備用代碼",
"totp": "基於時間的一次性密碼演算法 (TOTP)", "totp": "動態密碼 (TOTP)",
"play": "遊玩", "play": "開始測驗",
"text": "文字", "text": "文字",
"start": "開始", "start": "開始",
"connect": "連線", "connect": "連線",
@@ -265,82 +277,83 @@
"score": "分數", "score": "分數",
"player_plural": "玩家", "player_plural": "玩家",
"finish": "完成", "finish": "完成",
"point": "", "point": "",
"name": "名", "name": "名",
"slide": "投影片", "slide": "投影片",
"note": "筆記", "note": "筆記",
"back": "返回", "back": "返回",
"point_plural": "", "point_plural": "",
"upload": "", "upload": "上傳",
"next": "", "next": "下一步",
"analytics": "", "analytics": "分析",
"no": "", "no": "",
"speed": "", "speed": "速度",
"files_library": "", "files_library": "檔案庫",
"check_choice": "", "check_choice": "檢查選項",
"answer_plural": "", "answer_plural": "答案",
"version": "", "version": "版本",
"update": "", "update": "更新",
"play_plural": "", "play_plural": "參與次數",
"rating": "", "rating": "評分",
"video": "", "video": "影片",
"order": "", "order": "順序",
"dislike_plural": "", "dislike_plural": "",
"info": "", "info": "資訊",
"view_plural": "", "view_plural": "檢視次數",
"yes": "", "yes": "",
"like": "", "like": "",
"dislike": "", "dislike": "",
"progress": "", "progress": "進度",
"select": "", "select": "選取",
"like_plural": "", "like_plural": "",
"view": "", "view": "檢視",
"count": "", "count": "數量",
"report": "", "report": "回報",
"quiztivity": "", "quiztivity": "測驗活動",
"library": "", "library": "媒體庫",
"normal": "", "normal": "一般",
"selected": "", "selected": "已選取",
"unknown": "", "unknown": "未知",
"overview": "", "overview": "總覽",
"never": "", "never": "永不",
"quiz": "" "quiz": "測驗",
"player": "玩家"
}, },
"search_page": { "search_page": {
"at_least_3_characters": "輸入至少 3 個字元...", "at_least_3_characters": "輸入至少 3 個字元...",
"nothing_here": "這裡空無一物..." "nothing_here": "這裡空無一物..."
}, },
"dashboard": { "dashboard": {
"search_for_own_quizzes": "搜尋你的測驗", "search_for_own_quizzes": "搜尋你的測驗",
"commandpalette_notice": "", "commandpalette_notice": "按下 <kbd>Ctr</kbd>+<kbd>k</kbd> 或 <kbd>Meta</kbd>+<kbd>k</kbd> 開啟指令面板",
"views_n_plays": "", "views_n_plays": "瀏覽和參與次數",
"info_analytics": "" "info_analytics": "「參與次數」只會顯示測驗開始的次數(包含你自己),而「瀏覽次數」則計算「檢視」頁面被造訪的次數,因此也包含了機器人(很抱歉)。"
}, },
"overview_page": { "overview_page": {
"created_at": "建立於", "created_at": "建立於",
"question_count": "問題數", "question_count": "問題數",
"no_quizzes": "點「建立」按鈕或從 Kahoot! 匯入測驗。" "no_quizzes": "點「建立」按鈕或匯入測驗以開始。"
}, },
"error_page": { "error_page": {
"unknown_error_text": "這不應該發生。這可能是我的問題而不是你的,不過說不定你擁有破壞東西的魔法能力...", "unknown_error_text": "這不應該發生。這可能是我的問題而不是你的,不過說不定你擁有神奇的破壞力量...",
"404_text": "你正在尋找的頁面以刪除或不存在。誰知道發生了什麼事" "404_text": "你正在尋找的頁面已經消失或從來就不存在。誰知道"
}, },
"avatar_settings": { "avatar_settings": {
"skin_color": "膚色", "skin_color": "膚色",
"eyebrow_type": "毛", "eyebrow_type": "毛",
"accessories_type": "眼鏡", "accessories_type": "眼鏡",
"facial_hair_color": "鬍子顏色", "facial_hair_color": "鬍子顏色",
"mouth_type": "嘴巴", "mouth_type": "嘴巴",
"start_over": "重新開始", "start_over": "重新開始",
"thats_you": "這是你!", "thats_you": "這是你!",
"hair_color": "髮色", "hair_color": "髮色",
"facial_hair_type": "鬍子", "facial_hair_type": "鬍子",
"hat_color": "帽子顏色", "hat_color": "帽子顏色",
"clothe_type": "服", "clothe_type": "服",
"clothe_color": "服顏色", "clothe_color": "服顏色",
"go_back": "返回", "go_back": "返回",
"clothe_graphic_type": "", "clothe_graphic_type": "圖案",
"top_type": "" "top_type": "頭部"
}, },
"results_page": { "results_page": {
"quiz_title": "測驗標題", "quiz_title": "測驗標題",
@@ -348,7 +361,7 @@
"date_played": "測驗日期", "date_played": "測驗日期",
"no_results_so_far": "尚未儲存任何結果...", "no_results_so_far": "尚未儲存任何結果...",
"general_overview": { "general_overview": {
"sentence": "" "sentence": "測驗「{{title}}」於 {{date}} 進行,共有 {{player_count}} 位玩家參加,平均分數為 {{average_score}}。"
} }
}, },
"result_page": { "result_page": {
@@ -358,116 +371,123 @@
"time_taken": "花費時間", "time_taken": "花費時間",
"correct_answer": "{{count}} 個正確答案", "correct_answer": "{{count}} 個正確答案",
"correct_answer_plural": "{{count}} 個正確答案", "correct_answer_plural": "{{count}} 個正確答案",
"player_score": "" "player_score": "玩家分數"
}, },
"security_settings": { "security_settings": {
"activate_2fa": "啟用兩步驟驗證", "activate_2fa": "啟用兩步驟驗證",
"2fa_deactivated": "兩步驟驗證未啟用", "2fa_deactivated": "已停用兩步驟驗證",
"2fa_activated": "兩步驟驗證已啟用", "2fa_activated": "已啟用兩步驟驗證",
"get_backup_code": "", "get_backup_code": "取得備用代碼",
"enable_totp": "", "enable_totp": "開啟 TOTP",
"disable_totp": "", "disable_totp": "關閉 TOTP",
"totp_setup": { "totp_setup": {
"enter_as_secret_if_no_see_code": "", "enter_as_secret_if_no_see_code": "如果無法掃描 QR Code,請將此輸入作為金鑰",
"scan_to_set_up": "", "scan_to_set_up": "掃描此 QR Code 以進行設定",
"totp_setup": "", "totp_setup": "TOTP 設定",
"do_not_forget_backup_code": "" "do_not_forget_backup_code": "請務必儲存你的救援碼!"
}, },
"backup_code": "", "backup_code": "備用代碼",
"backup_codes": { "backup_codes": {
"download_code": "", "download_code": "下載代碼",
"your_backup_code": "", "your_backup_code": "你的備用代碼",
"save_somewhere_save": "" "save_somewhere_save": "請將它儲存在安全的地方!"
}, },
"totp": "", "totp": "TOTP",
"totp_unavailable": "", "totp_unavailable": "無法使用 TOTP",
"webauthn": "", "webauthn": "WebAuthn",
"add_security_key": "", "add_security_key": "新增安全金鑰",
"webauthn_unavailable": "", "webauthn_unavailable": "無法使用 WebAuthn",
"totp_available": "", "totp_available": "可使用 TOTP",
"webauthn_available": "" "webauthn_available": "可使用 WebAuthn"
}, },
"file_dashboard": { "file_dashboard": {
"unset": "", "unset": "未設定",
"filename_word": "", "filename_word": "檔案名稱",
"imported": "", "imported": "已匯入:{{yes_or_no}}",
"filename": "", "filename": "檔名:{{filename}}",
"missing": "", "missing": "遺失!",
"delete_image": "", "delete_image": "刪除圖片",
"size": "", "size": "大小:{{size}} MiB",
"storage_usage": "", "storage_usage": "你已使用 {{total}} MiB 儲存空間中的 {{used}} MiB,相當於儲存空間的 {{percent}}%。",
"alt_text": "", "alt_text": "替代文字/說明",
"edit_details": "", "edit_details": "編輯詳細資訊",
"uploaded": "", "uploaded": "上傳時間:{{date}}",
"not_available": "", "not_available": "無法使用",
"caption": "", "caption": "說明:{{caption}}",
"edit_the_image": "" "edit_the_image": "編輯圖片"
}, },
"quiztivity": { "quiztivity": {
"editor": { "editor": {
"add_new": "", "add_new": "新增",
"move_left": "", "move_left": "向左移動",
"shares": { "shares": {
"never_expires": "", "never_expires": "永不到期",
"expires_on": "", "expires_on": "於 {{date}} 到期",
"add_new_share": "" "add_new_share": "新增分享"
}, },
"title_placeholder": "", "title_placeholder": "在此輸入標題",
"delete": "", "delete": "刪除",
"open_shares_menu": "", "open_shares_menu": "開啟分享選單",
"select_page_type": "", "select_page_type": "選擇頁面類型",
"move_right": "" "move_right": "向右移動"
}, },
"share_expired": "", "share_expired": "分享已過期",
"play": { "play": {
"memory": { "memory": {
"try_count": "" "try_count": "嘗試次數:{{try_count}}"
} }
}, },
"memory": { "memory": {
"editor": { "editor": {
"add_card": "", "add_card": "新增卡片",
"add_pair": "", "add_pair": "新增配對",
"upload_image": "" "upload_image": "上傳圖片"
} }
} }
}, },
"controllers": { "controllers": {
"last_seen": "", "last_seen": "最後出現",
"cancel_update": "", "cancel_update": "取消更新!",
"add_new_controller": "", "add_new_controller": "新增控制器",
"player_name": "", "player_name": "玩家名稱",
"controller_name": "", "controller_name": "控制器名稱",
"already_latest_version": "", "already_latest_version": "你已在使用最新版本",
"update_from_to": "", "update_from_to": "從 {{current_version}} 更新至 {{newest_version}}",
"first_seen": "", "first_seen": "首次出現",
"version_overview": "" "version_overview": "目前安裝的版本為 {{current_version}},最新版本為 {{newest_version}}。"
}, },
"view_quiz_page": { "view_quiz_page": {
"made_by": "", "made_by": "作者為",
"view_on_kahoot": "" "view_on_kahoot": "檢視原始內容"
}, },
"start_game": { "start_game": {
"old_school_mode_description": "", "old_school_mode_description": "問題和圖片會同時顯示在管理員和玩家的畫面上",
"old_school_mode": "", "old_school_mode": "傳統模式",
"start_game": "", "start_game": "開始遊戲",
"captcha_message": "", "captcha_message": "如果啟用,Google reCAPTCHA 將會在玩家的瀏覽器中載入。由於載入 reCAPTCHA 需要每位玩家的同意,請只在必要時啟用。",
"normal_mode_description": "" "normal_mode_description": "問題和答案只會顯示在管理員的畫面上。玩家只會看到與管理員畫面上相對應的彩色按鈕和符號。"
}, },
"video_uploader": { "video_uploader": {
"time_remaining": "", "time_remaining": "剩餘時間",
"time_elapsed": "" "time_elapsed": "經過時間"
}, },
"navbar": { "navbar": {
"donate": "" "donate": "贊助"
}, },
"public_user_page": { "public_user_page": {
"no_original_quizzes": "", "no_original_quizzes": "這位使用者沒有任何原創測驗",
"joined_on": "" "joined_on": "加入日期:{{date}}",
"user_not_found": "找不到使用者"
}, },
"components": { "components": {
"popover": { "popover": {
"copied_to_clipboard": "" "copied_to_clipboard": "已複製到剪貼簿!"
} }
},
"downloader": {
"select_download_type": "選擇下載類型",
"own_format": "專有格式",
"excel_format": "Excel 格式",
"help": "專有格式(.cqa)包含圖片並支援所有題型,而 Excel 格式僅支援投票和選擇題。"
} }
} }
@@ -79,6 +79,17 @@ SPDX-License-Identifier: MPL-2.0
class="admin-button" class="admin-button"
>{$t('admin_page.next_question', { question: selected_question + 2 })} >{$t('admin_page.next_question', { question: selected_question + 2 })}
</button> </button>
{:else if quiz_data.questions[selected_question]?.hide_results === true}
<button
on:click={() => {
get_question_results();
setTimeout(() => {
set_question_number(selected_question + 1);
}, 200);
}}
class="admin-button"
>{$t('admin_page.next_question', { question: selected_question + 2 })}
</button>
{:else} {:else}
<button on:click={get_question_results} class="admin-button" <button on:click={get_question_results} class="admin-button"
>{$t('admin_page.show_results')} >{$t('admin_page.show_results')}
+1
View File
@@ -61,6 +61,7 @@ export interface Question {
type?: QuizQuestionType; type?: QuizQuestionType;
image?: string; image?: string;
answers: Answers; answers: Answers;
hide_results?: boolean;
} }
export type Answers = export type Answers =
+2 -14
View File
@@ -67,20 +67,8 @@ SPDX-License-Identifier: MPL-2.0
<svelte:head> <svelte:head>
{#if plausible_data_url} {#if plausible_data_url}
<link rel="prefetch" href="https://sugar.mawoka.eu.org/" /> <script defer data-domain={plausible_data_url} src="https://plausible.nexus.mawoka.eu/js/script.file-downloads.outbound-links.pageview-props.tagged-events.js"></script>
<script <script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
async=""
defer=""
data-domain={plausible_data_url}
src="https://sugar.mawoka.eu.org/js/plausible.hash.outbound-links.js"
></script>
<script>
window.plausible =
window.plausible ||
function () {
(window.plausible.q = window.plausible.q || []).push(arguments);
};
</script>
{/if} {/if}
</svelte:head> </svelte:head>
+18
View File
@@ -259,6 +259,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_create_thing = SelectedCreateThing.Create; selected_create_thing = SelectedCreateThing.Create;
}} }}
on:keyup={() => {
selected_create_thing = SelectedCreateThing.Create;
}}
class:shadow-2xl={selected_create_thing === SelectedCreateThing.Create} class:shadow-2xl={selected_create_thing === SelectedCreateThing.Create}
class:opacity-70={selected_create_thing !== SelectedCreateThing.Create} class:opacity-70={selected_create_thing !== SelectedCreateThing.Create}
> >
@@ -289,6 +292,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_create_thing = SelectedCreateThing.Find; selected_create_thing = SelectedCreateThing.Find;
}} }}
on:keyup={() => {
selected_create_thing = SelectedCreateThing.Find;
}}
class:shadow-2xl={selected_create_thing === SelectedCreateThing.Find} class:shadow-2xl={selected_create_thing === SelectedCreateThing.Find}
class:opacity-70={selected_create_thing !== SelectedCreateThing.Find} class:opacity-70={selected_create_thing !== SelectedCreateThing.Find}
> >
@@ -396,6 +402,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_play_thing = SelectedPlayThing.Select; selected_play_thing = SelectedPlayThing.Select;
}} }}
on:keyup={() => {
selected_play_thing = SelectedPlayThing.Select;
}}
class:shadow-2xl={selected_play_thing === SelectedPlayThing.Select} class:shadow-2xl={selected_play_thing === SelectedPlayThing.Select}
class:opacity-70={selected_play_thing !== SelectedPlayThing.Select} class:opacity-70={selected_play_thing !== SelectedPlayThing.Select}
> >
@@ -426,6 +435,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_play_thing = SelectedPlayThing.Results; selected_play_thing = SelectedPlayThing.Results;
}} }}
on:keyup={() => {
selected_play_thing = SelectedPlayThing.Results;
}}
class:shadow-2xl={selected_play_thing === SelectedPlayThing.Results} class:shadow-2xl={selected_play_thing === SelectedPlayThing.Results}
class:opacity-70={selected_play_thing !== SelectedPlayThing.Results} class:opacity-70={selected_play_thing !== SelectedPlayThing.Results}
> >
@@ -456,6 +468,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_play_thing = SelectedPlayThing.Winners; selected_play_thing = SelectedPlayThing.Winners;
}} }}
on:keyup={() => {
selected_play_thing = SelectedPlayThing.Winners;
}}
class:shadow-2xl={selected_play_thing === SelectedPlayThing.Winners} class:shadow-2xl={selected_play_thing === SelectedPlayThing.Winners}
class:opacity-70={selected_play_thing !== SelectedPlayThing.Winners} class:opacity-70={selected_play_thing !== SelectedPlayThing.Winners}
> >
@@ -511,6 +526,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_classquiz_reason = index; selected_classquiz_reason = index;
}} }}
on:keyup={() => {
selected_classquiz_reason = index;
}}
class:shadow-2xl={selected_classquiz_reason === index} class:shadow-2xl={selected_classquiz_reason === index}
class:opacity-70={selected_classquiz_reason !== index} class:opacity-70={selected_classquiz_reason !== index}
> >
@@ -33,6 +33,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_method = 'PASSKEY'; selected_method = 'PASSKEY';
}} }}
on:keyup={() => {
selected_method = 'PASSKEY';
}}
> >
<!-- heroicons/key --> <!-- heroicons/key -->
<svg <svg
@@ -61,6 +64,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_method = 'PASSWORD'; selected_method = 'PASSWORD';
}} }}
on:keyup={() => {
selected_method = 'PASSWORD';
}}
> >
<!-- iconoir/password-cursor --> <!-- iconoir/password-cursor -->
<svg <svg
@@ -104,6 +110,9 @@ SPDX-License-Identifier: MPL-2.0
on:click={() => { on:click={() => {
selected_method = 'TOTP'; selected_method = 'TOTP';
}} }}
on:keyup={() => {
selected_method = 'TOTP';
}}
> >
<!-- heroicons/clock --> <!-- heroicons/clock -->
<svg <svg
@@ -4,6 +4,8 @@ SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0 SPDX-License-Identifier: MPL-2.0
--> -->
<script lang="ts"> <script lang="ts">
import { getLocalization } from '$lib/i18n'; import { getLocalization } from '$lib/i18n';
import OAuthBlock from './oauth_block.svelte'; import OAuthBlock from './oauth_block.svelte';
@@ -17,11 +19,13 @@ SPDX-License-Identifier: MPL-2.0
let isSubmitting = false; let isSubmitting = false;
$: emailEmpty = email === ''; $: emailEmpty = email === '';
const start_login = async (): Promise<void> => { const start_login = async (): Promise<void> => {
if (emailEmpty) { if (emailEmpty) {
return; return;
} }
isSubmitting = true; isSubmitting = true;
const res = await fetch('/api/v1/login/start', { const res = await fetch('/api/v1/login/start', {
method: 'post', method: 'post',
headers: { headers: {
+3
View File
@@ -60,6 +60,9 @@ SPDX-License-Identifier: MPL-2.0
connect(); connect();
} }
}); });
socket.on("session_id", (d) => {
const session_id = d.session_id
})
socket.on('registered_as_admin', (data) => { socket.on('registered_as_admin', (data) => {
quiz_data = JSON.parse(data['game']); quiz_data = JSON.parse(data['game']);
+1 -1
View File
@@ -227,7 +227,7 @@ SPDX-License-Identifier: MPL-2.0
<a <a
class="text-sm underline font-bold text-blue-500 dark:text-blue-400" class="text-sm underline font-bold text-blue-500 dark:text-blue-400"
download download
href="https://ncs3.classquiz.de/blog/classquiz/ClassQuizImportTemplate.xlsx" href="https://s3.realux.mawoka.eu/blog/classquiz/ClassQuizImportTemplate.xlsx"
>{$t('import_page.download_template_here')}</a >{$t('import_page.download_template_here')}</a
> >
</div> </div>
+3
View File
@@ -72,6 +72,9 @@ SPDX-License-Identifier: MPL-2.0
socket.on('time_sync', (data) => { socket.on('time_sync', (data) => {
socket.emit('echo_time_sync', data); socket.emit('echo_time_sync', data);
}); });
socket.on("session_id", (d) => {
const session_id = d.session_id
})
socket.on('connect', async () => { socket.on('connect', async () => {
console.log('Connected!'); console.log('Connected!');
+8
View File
@@ -32,6 +32,14 @@ const config = {
build: { build: {
sourcemap: true sourcemap: true
} }
/* Trying
ssr: {
noExternal: ['@ckeditor/*'],
}
end trying*/
}; };
export default config; export default config;
+8
View File
@@ -0,0 +1,8 @@
<!--
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
-->
# Migration of the Backend to Rust (long term goal)
+8 -11
View File
@@ -9,18 +9,15 @@ run_tests() {
} }
stop() { stop() {
$CONTAINER_BIN container stop classquiz_db $CONTAINER_BIN compose -f docker-compose.dev.yml down --volumes
$CONTAINER_BIN container stop test_redis
$CONTAINER_BIN container stop test_meili
} }
init() { init() {
mkdir /tmp/storage if [ ! -d /tmp/storage ]; then
$CONTAINER_BIN run --rm -d -p 6379:6379 --name test_redis redis:alpine mkdir /tmp/storage
$CONTAINER_BIN run -it --rm -d -p 7700:7700 --name test_meili getmeili/meilisearch:v0.28.0 fi
$CONTAINER_BIN volume create classquiz_db_data $CONTAINER_BIN compose -f docker-compose.dev.yml up -d
$CONTAINER_BIN run --name classquiz_db -p 5432:5432 --rm -d -e POSTGRES_PASSWORD=mysecretpassword -v classquiz_db_data:/var/lib/postgresql/data -e POSTGRES_DB=classquiz postgres sleep 2
sleep 1
pipenv run alembic upgrade head pipenv run alembic upgrade head
} }
@@ -28,14 +25,14 @@ case $1 in
+) init ;; +) init ;;
-) stop ;; -) stop ;;
a) a)
$CONTAINER_BIN volume rm classquiz_db_data $CONTAINER_BIN volume rm classquiz_db
init init
run_tests run_tests
stop stop
;; ;;
prepare) prepare)
stop stop
$CONTAINER_BIN volume rm classquiz_db_data $CONTAINER_BIN volume rm classquiz_db
init init
;; ;;
*) *)