Commits vergleichen

...

25 Commits

Autor SHA1 Nachricht Datum
TheBreadBeard
437dfa223b Update neujahrsevent-2025-eventplan.md
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2025-01-01 18:34:35 +01:00
012a56e177 Merge remote-tracking branch 'origin/master'
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2025-01-01 17:09:02 +01:00
9f60071e48 Some (alot) of fixes 2025-01-01 17:08:55 +01:00
3bcadde949 Merge pull request 'Merge branch neujahrsevent-2025-eventplan' (#23) from neujahrsevent-2025-eventplan into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #23
2025-01-01 15:20:47 +01:00
f5332411d2 Fixes
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2025-01-01 14:25:33 +01:00
TheBreadBeard
b546c7b2b2 Update neujahrsevent-2025-eventplan.md
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2025-01-01 13:45:48 +01:00
TheBreadBeard
7716aa1e89 Create page announcements/de/neujahrsevent-2025-eventplan.md
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
2025-01-01 13:42:09 +01:00
a7e961fc0c Fixes
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-21 16:13:33 +01:00
8c6f5f5729 Fix Render
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-21 16:06:23 +01:00
41a3b75c97 Fix Render
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-21 16:03:45 +01:00
fe9610a970 Kampfplan
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-21 15:58:22 +01:00
6b38f37711 Add Redirects
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-17 20:44:53 +01:00
68b8e92661 Add latest announcements
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-15 14:51:55 +01:00
a29689da0a Add latest announcements
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
2024-12-15 14:50:32 +01:00
292d1b6bcc Fixes
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-15 12:02:54 +01:00
9e6ef73ccb Fixes
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
2024-12-15 11:59:28 +01:00
02ab822801 Fixes
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
2024-12-15 11:49:43 +01:00
d7000c084b Fixes
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed
2024-12-14 18:10:50 +01:00
d4ac123654 Fix Modal
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-08 17:21:17 +01:00
e93445d933 Merge branch 'kick-ai-bots'
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-08 17:10:32 +01:00
2383cd6472 Fix Styles
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-12-08 17:10:01 +01:00
d86a8493d1 Merge pull request 'Give AI bots the boot' (#22) from kick-ai-bots into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #22
Reviewed-by: Chaoscaot <chaos@chaoscaot.de>
2024-11-26 15:34:50 +01:00
5f90025493 Give AI bots the boot
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Mix of

- https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click/
- https://www.google.com/robots.txt
2024-11-26 15:31:44 +01:00
bbb6d87ccc Fix Build
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-11-24 23:05:29 +01:00
0ab7d204f2 Fix Build
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2024-11-24 23:00:44 +01:00
43 geänderte Dateien mit 728 neuen und 298 gelöschten Zeilen

Datei anzeigen

@ -15,7 +15,6 @@ export default defineConfig({
output: "static",
image: {
service: sharpImageService(),
domains: [ "vzge.me" ]
},
compressHTML: true,
site: "https://steamwar.de",
@ -34,9 +33,27 @@ export default defineConfig({
},
}),
robotsTxt({
policy: [{
userAgent: "*", disallow: ["/admin", "/login", "/dashboard", "/de", "/_astro"],
}],
policy: [
{ userAgent: "*", disallow: ["/admin", "/login", "/dashboard", "/de", "/_astro"] },
{ userAgent: "anthropic-ai", disallow: "/" },
{ userAgent: "Applebot-Extended", disallow: "/" },
{ userAgent: "Bytespider", disallow: "/" },
{ userAgent: "CCBot", disallow: "/" },
{ userAgent: "ChatGPT-User", disallow: "/" },
{ userAgent: "ClaudeBot", disallow: "/" },
{ userAgent: "Claude-Web", disallow: "/" },
{ userAgent: "cohere-ai", disallow: "/" },
{ userAgent: "Diffbot", disallow: "/" },
{ userAgent: "FacebookBot", disallow: "/" },
{ userAgent: "GPTBot", disallow: "/" },
{ userAgent: "ImagesiftBot", disallow: "/" },
{ userAgent: "Meta-ExternalAgent", disallow: "/" },
{ userAgent: "Meta-ExternalFetcher", disallow: "/" },
{ userAgent: "omgili", disallow: "/" },
{ userAgent: "OmigliBot", disallow: "/" },
{ userAgent: "PerplexityBot", disallow: "/" },
{ userAgent: "Timpibot", disallow: "/" }
],
}),
mdx(),
],

Datei anzeigen

@ -34,7 +34,7 @@
"eslint-plugin-svelte": "^2.46.0",
"postcss-nesting": "^13.0.1",
"sass": "^1.81.0",
"svelte": "^5.2.7",
"svelte": "^5.16.0",
"tailwind-merge": "^2.5.5",
"tailwindcss": "^3.4.15",
"three": "^0.170.0",

162
pnpm-lock.yaml generiert
Datei anzeigen

@ -55,10 +55,10 @@ dependencies:
version: 2.5.2
flowbite-svelte:
specifier: ^0.47.3
version: 0.47.3(svelte@5.2.7)
version: 0.47.3(svelte@5.16.0)
flowbite-svelte-icons:
specifier: ^2.0.2
version: 2.0.2(svelte@5.2.7)(tailwind-merge@2.5.5)(tailwindcss@3.4.15)
version: 2.0.2(svelte@5.16.0)(tailwind-merge@2.5.5)(tailwindcss@3.4.15)
qs:
specifier: ^6.13.1
version: 6.13.1
@ -67,10 +67,10 @@ dependencies:
version: 0.33.5
svelte-awesome:
specifier: ^3.3.5
version: 3.3.5(svelte@5.2.7)
version: 3.3.5(svelte@5.16.0)
svelte-codemirror-editor:
specifier: ^1.4.1
version: 1.4.1(codemirror@6.0.1)(svelte@5.2.7)
version: 1.4.1(codemirror@6.0.1)(svelte@5.16.0)
svelte-spa-router:
specifier: ^4.0.1
version: 4.0.1
@ -81,7 +81,7 @@ dependencies:
devDependencies:
'@astrojs/svelte':
specifier: ^6.0.2
version: 6.0.2(@types/node@22.9.3)(astro@4.16.14)(sass@1.81.0)(svelte@5.2.7)(typescript@5.7.2)
version: 6.0.2(@types/node@22.9.3)(astro@4.16.14)(sass@1.81.0)(svelte@5.16.0)(typescript@5.7.2)
'@astrojs/tailwind':
specifier: ^5.1.2
version: 5.1.2(astro@4.16.14)(tailwindcss@3.4.15)
@ -123,7 +123,7 @@ devDependencies:
version: 6.10.2(eslint@9.15.0)
eslint-plugin-svelte:
specifier: ^2.46.0
version: 2.46.0(eslint@9.15.0)(svelte@5.2.7)
version: 2.46.0(eslint@9.15.0)(svelte@5.16.0)
postcss-nesting:
specifier: ^13.0.1
version: 13.0.1(postcss@8.4.49)
@ -131,8 +131,8 @@ devDependencies:
specifier: ^1.81.0
version: 1.81.0
svelte:
specifier: ^5.2.7
version: 5.2.7
specifier: ^5.16.0
version: 5.16.0
tailwind-merge:
specifier: ^2.5.5
version: 2.5.5
@ -279,7 +279,7 @@ packages:
zod: 3.23.8
dev: false
/@astrojs/svelte@6.0.2(@types/node@22.9.3)(astro@4.16.14)(sass@1.81.0)(svelte@5.2.7)(typescript@5.7.2):
/@astrojs/svelte@6.0.2(@types/node@22.9.3)(astro@4.16.14)(sass@1.81.0)(svelte@5.16.0)(typescript@5.7.2):
resolution: {integrity: sha512-Jn60LLH+AbjtLIOQuL0SUI0fxMwpT89VraoGkEwF33ZgCT59H8fMQOj9eNf632P/SHRbKpD+Q+PJjODn5OcKoQ==}
engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
peerDependencies:
@ -287,10 +287,10 @@ packages:
svelte: ^5.1.16
typescript: ^5.3.3
dependencies:
'@sveltejs/vite-plugin-svelte': 4.0.1(svelte@5.2.7)(vite@5.4.11)
'@sveltejs/vite-plugin-svelte': 4.0.1(svelte@5.16.0)(vite@5.4.11)
astro: 4.16.14(@types/node@22.9.3)(sass@1.81.0)(typescript@5.7.2)
svelte: 5.2.7
svelte2tsx: 0.7.28(svelte@5.2.7)(typescript@5.7.2)
svelte: 5.16.0
svelte2tsx: 0.7.28(svelte@5.16.0)(typescript@5.7.2)
typescript: 5.7.2
vite: 5.4.11(@types/node@22.9.3)(sass@1.81.0)
transitivePeerDependencies:
@ -513,26 +513,21 @@ packages:
'@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
/@codemirror/autocomplete@6.18.3(@codemirror/language@6.10.4)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0)(@lezer/common@1.2.3):
resolution: {integrity: sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==}
peerDependencies:
'@codemirror/language': ^6.0.0
'@codemirror/state': ^6.0.0
'@codemirror/view': ^6.0.0
'@lezer/common': ^1.0.0
/@codemirror/autocomplete@6.18.4:
resolution: {integrity: sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA==}
dependencies:
'@codemirror/language': 6.10.4
'@codemirror/state': 6.4.1
'@codemirror/view': 6.35.0
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
'@lezer/common': 1.2.3
dev: false
/@codemirror/commands@6.7.1:
resolution: {integrity: sha512-llTrboQYw5H4THfhN4U3qCnSZ1SOJ60ohhz+SzU0ADGtwlc533DtklQP0vSFaQuCPDn3BPpOd1GbbnUtwNjsrw==}
dependencies:
'@codemirror/language': 6.10.4
'@codemirror/state': 6.4.1
'@codemirror/view': 6.35.0
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
'@lezer/common': 1.2.3
dev: false
@ -554,19 +549,30 @@ packages:
style-mod: 4.1.2
dev: false
/@codemirror/lint@6.8.3:
resolution: {integrity: sha512-GSGfKxCo867P7EX1k2LoCrjuQFeqVgPGRRsSl4J4c0KMkD+k1y6WYvTQkzv0iZ8JhLJDujEvlnMchv4CZQLh3Q==}
/@codemirror/language@6.10.8:
resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==}
dependencies:
'@codemirror/state': 6.4.1
'@codemirror/view': 6.35.0
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
'@lezer/common': 1.2.3
'@lezer/highlight': 1.2.1
'@lezer/lr': 1.4.2
style-mod: 4.1.2
dev: false
/@codemirror/lint@6.8.4:
resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==}
dependencies:
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
crelt: 1.0.6
dev: false
/@codemirror/search@6.5.8:
resolution: {integrity: sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig==}
dependencies:
'@codemirror/state': 6.4.1
'@codemirror/view': 6.35.0
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
crelt: 1.0.6
dev: false
@ -574,6 +580,12 @@ packages:
resolution: {integrity: sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==}
dev: false
/@codemirror/state@6.5.0:
resolution: {integrity: sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==}
dependencies:
'@marijn/find-cluster-break': 1.0.2
dev: false
/@codemirror/view@6.35.0:
resolution: {integrity: sha512-I0tYy63q5XkaWsJ8QRv5h6ves7kvtrBWjBcnf/bzohFJQc5c14a1AQRdE8QpPF9eMp5Mq2FMm59TCj1gDfE7kw==}
dependencies:
@ -582,6 +594,14 @@ packages:
w3c-keyname: 2.2.8
dev: false
/@codemirror/view@6.36.1:
resolution: {integrity: sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==}
dependencies:
'@codemirror/state': 6.5.0
style-mod: 4.1.2
w3c-keyname: 2.2.8
dev: false
/@csstools/selector-resolve-nested@3.0.0(postcss-selector-parser@7.0.0):
resolution: {integrity: sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==}
engines: {node: '>=18'}
@ -1364,6 +1384,10 @@ packages:
'@lezer/common': 1.2.3
dev: false
/@marijn/find-cluster-break@1.0.2:
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
dev: false
/@mdx-js/mdx@3.1.0(acorn@8.14.0):
resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==}
dependencies:
@ -1796,7 +1820,7 @@ packages:
/@shikijs/vscode-textmate@9.3.0:
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
/@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.1)(svelte@5.2.7)(vite@5.4.11):
/@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.1)(svelte@5.16.0)(vite@5.4.11):
resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
@ -1804,27 +1828,27 @@ packages:
svelte: ^5.0.0-next.96 || ^5.0.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 4.0.1(svelte@5.2.7)(vite@5.4.11)
'@sveltejs/vite-plugin-svelte': 4.0.1(svelte@5.16.0)(vite@5.4.11)
debug: 4.3.7
svelte: 5.2.7
svelte: 5.16.0
vite: 5.4.11(@types/node@22.9.3)(sass@1.81.0)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte@4.0.1(svelte@5.2.7)(vite@5.4.11):
/@sveltejs/vite-plugin-svelte@4.0.1(svelte@5.16.0)(vite@5.4.11):
resolution: {integrity: sha512-prXoAE/GleD2C4pKgHa9vkdjpzdYwCSw/kmjw6adIyu0vk5YKCfqIztkLg10m+kOYnzZu3bb0NaPTxlWre2a9Q==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22}
peerDependencies:
svelte: ^5.0.0-next.96 || ^5.0.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.1)(svelte@5.2.7)(vite@5.4.11)
'@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.1)(svelte@5.16.0)(vite@5.4.11)
debug: 4.3.7
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.13
svelte: 5.2.7
svelte: 5.16.0
vite: 5.4.11(@types/node@22.9.3)(sass@1.81.0)
vitefu: 1.0.3(vite@5.4.11)
transitivePeerDependencies:
@ -2762,18 +2786,16 @@ packages:
resolution: {integrity: sha512-Gaz4gHnkbHMGgahNt3CA5HBk5lLQBqmD/pBgeB4kQU6OedZmqMBjlRF0LSrp2tJ4wlLNPm2FfaUd1pDy0mdlpA==}
dev: false
/codemirror@6.0.1(@lezer/common@1.2.3):
/codemirror@6.0.1:
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
dependencies:
'@codemirror/autocomplete': 6.18.3(@codemirror/language@6.10.4)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0)(@lezer/common@1.2.3)
'@codemirror/autocomplete': 6.18.4
'@codemirror/commands': 6.7.1
'@codemirror/language': 6.10.4
'@codemirror/lint': 6.8.3
'@codemirror/language': 6.10.8
'@codemirror/lint': 6.8.4
'@codemirror/search': 6.5.8
'@codemirror/state': 6.4.1
'@codemirror/view': 6.35.0
transitivePeerDependencies:
- '@lezer/common'
'@codemirror/state': 6.5.0
'@codemirror/view': 6.36.1
dev: false
/collapse-white-space@2.1.0:
@ -3404,7 +3426,7 @@ packages:
string.prototype.includes: 2.0.1
dev: true
/eslint-plugin-svelte@2.46.0(eslint@9.15.0)(svelte@5.2.7):
/eslint-plugin-svelte@2.46.0(eslint@9.15.0)(svelte@5.16.0):
resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
@ -3425,8 +3447,8 @@ packages:
postcss-safe-parser: 6.0.0(postcss@8.4.49)
postcss-selector-parser: 6.1.2
semver: 7.6.3
svelte: 5.2.7
svelte-eslint-parser: 0.43.0(svelte@5.2.7)
svelte: 5.16.0
svelte-eslint-parser: 0.43.0(svelte@5.16.0)
transitivePeerDependencies:
- ts-node
dev: true
@ -3505,8 +3527,8 @@ packages:
- supports-color
dev: true
/esm-env@1.1.4:
resolution: {integrity: sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==}
/esm-env@1.2.1:
resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==}
/espree@10.3.0:
resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
@ -3538,11 +3560,10 @@ packages:
estraverse: 5.3.0
dev: true
/esrap@1.2.2:
resolution: {integrity: sha512-F2pSJklxx1BlQIQgooczXCPHmcWpn6EsP5oo73LQfonG9fIlIENQ8vMmfGXeojP9MrkzUNAfyU5vdFlR9shHAw==}
/esrap@1.3.2:
resolution: {integrity: sha512-C4PXusxYhFT98GjLSmb20k9PREuUdporer50dhzGuJu9IJXktbMddVCMLAERl5dAHyAi73GWWCE4FVHGP1794g==}
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
'@types/estree': 1.0.6
/esrecurse@4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
@ -3724,7 +3745,7 @@ packages:
- rollup
dev: false
/flowbite-svelte-icons@2.0.2(svelte@5.2.7)(tailwind-merge@2.5.5)(tailwindcss@3.4.15):
/flowbite-svelte-icons@2.0.2(svelte@5.16.0)(tailwind-merge@2.5.5)(tailwindcss@3.4.15):
resolution: {integrity: sha512-Vkmduy2867Rk8R7TziPirsWkixJnToFBEXRaN4ouJabOx62NQjiBbHFe+HTaMOQmdp4FNMI2Nhtk2I2CQ8r3RQ==}
engines: {node: '>=18.0.0', npm: '>=7.0.0'}
peerDependencies:
@ -3732,12 +3753,12 @@ packages:
tailwind-merge: ^2.3.0
tailwindcss: ^3.4.3
dependencies:
svelte: 5.2.7
svelte: 5.16.0
tailwind-merge: 2.5.5
tailwindcss: 3.4.15
dev: false
/flowbite-svelte@0.47.3(svelte@5.2.7):
/flowbite-svelte@0.47.3(svelte@5.16.0):
resolution: {integrity: sha512-1Wdbx+YV6S20dnnMERr/XFNjO+sb22QOrZtIK0Wa8SXxxuYPmbkT3b4mR4TYwUWvWheXsWvlcPLSlV8YGJgItw==}
engines: {node: '>=18.0.0', pnpm: '>=8.0.0'}
peerDependencies:
@ -3746,7 +3767,7 @@ packages:
'@floating-ui/dom': 1.6.12
apexcharts: 3.54.1
flowbite: 2.5.2
svelte: 5.2.7
svelte: 5.16.0
tailwind-merge: 2.5.5
transitivePeerDependencies:
- rollup
@ -6542,25 +6563,25 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/svelte-awesome@3.3.5(svelte@5.2.7):
/svelte-awesome@3.3.5(svelte@5.16.0):
resolution: {integrity: sha512-RIi+OI6CEn+fTdYy7UOgImEUWvdQSwP9SiMC44UKyFO+8+gjj+NgTG67hI8j2rTHQVvCP820Uj+4UoZG8CCUfA==}
peerDependencies:
svelte: '>= 3.43.1 < 6'
dependencies:
svelte: 5.2.7
svelte: 5.16.0
dev: false
/svelte-codemirror-editor@1.4.1(codemirror@6.0.1)(svelte@5.2.7):
/svelte-codemirror-editor@1.4.1(codemirror@6.0.1)(svelte@5.16.0):
resolution: {integrity: sha512-Pv350iro0Y/AZTT/y2OLaonheQqAwl50Hdfipa2Jv1Z04TSP5kPUyxQnRjqxeRW7DXOX9s5Nd11tHdBl9iYSzw==}
peerDependencies:
codemirror: ^6.0.0
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0
dependencies:
codemirror: 6.0.1(@lezer/common@1.2.3)
svelte: 5.2.7
codemirror: 6.0.1
svelte: 5.16.0
dev: false
/svelte-eslint-parser@0.43.0(svelte@5.2.7):
/svelte-eslint-parser@0.43.0(svelte@5.16.0):
resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -6574,7 +6595,7 @@ packages:
espree: 9.6.1
postcss: 8.4.49
postcss-scss: 4.0.9(postcss@8.4.49)
svelte: 5.2.7
svelte: 5.16.0
dev: true
/svelte-spa-router@4.0.1:
@ -6583,7 +6604,7 @@ packages:
regexparam: 2.0.2
dev: false
/svelte2tsx@0.7.28(svelte@5.2.7)(typescript@5.7.2):
/svelte2tsx@0.7.28(svelte@5.16.0)(typescript@5.7.2):
resolution: {integrity: sha512-TJjA+kU8AnkyoprZPgQACMfTX8N0MA5NsIL//h9IuHOxmmaCLluqhcZU+fCkWipi5c/pooHLFOMpqjhq4v7JLQ==}
peerDependencies:
svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0
@ -6591,12 +6612,12 @@ packages:
dependencies:
dedent-js: 1.0.1
pascal-case: 3.1.2
svelte: 5.2.7
svelte: 5.16.0
typescript: 5.7.2
dev: true
/svelte@5.2.7:
resolution: {integrity: sha512-cEhPGuLHiH2+Z8B1FwQgiZJgA39uUmJR4516TKrM5zrp0/cuwJkfhUfcTxhAkznanAF5fXUKzvYR4o+Ksx3ZCQ==}
/svelte@5.16.0:
resolution: {integrity: sha512-Ygqsiac6UogVED2ruKclU+pOeMThxWtp9LG+li7BXeDKC2paVIsRTMkNmcON4Zejerd1s5sZHWx6ZtU85xklVg==}
engines: {node: '>=18'}
dependencies:
'@ampproject/remapping': 2.3.0
@ -6606,8 +6627,9 @@ packages:
acorn-typescript: 1.4.13(acorn@8.14.0)
aria-query: 5.3.2
axobject-query: 4.1.0
esm-env: 1.1.4
esrap: 1.2.2
clsx: 2.1.1
esm-env: 1.2.1
esrap: 1.3.2
is-reference: 3.0.3
locate-character: 3.0.0
magic-string: 0.30.13

Datei anzeigen

@ -37,13 +37,9 @@
<p>{t("status.loading")}</p>
{:then user}
<UserInfo {user} />
<hr>
<div class="flex flex-col justify-center">
<SWButton on:click={() => uploadOpen = true}>
{t("dashboard.schematic.upload")}
</SWButton>
</div>
<SWButton onclick={() => uploadOpen = true}>
{t("dashboard.schematic.upload")}
</SWButton>
{:catch error}
<p>error: {error.message}</p>
{/await}

Datei anzeigen

@ -42,34 +42,32 @@
}
</script>
<div>
<div class="p-3 bg-gray-200 dark:bg-neutral-800 rounded-2xl w-3/4 mx-auto">
<table>
<tr class="font-bold border-b">
{#each Array(rows) as i (i)}
<td>{t("announcements.table.time")}</td>
<td>{t("announcements.table.blue")}</td>
<td>{t("announcements.table.red")}</td>
<td>{t("announcements.table.winner")}</td>
{/each}
</tr>
{#each window(event.fights.filter(f => f.group === group), rows) as fights}
<tr>
{#each fights as fight (fight.id)}
<td>{Intl.DateTimeFormat(astroI18n.locale, {
hour: "numeric",
minute: "numeric",
}).format(new Date(fight.start))}</td>
<td class:font-bold={fight.ergebnis === 1} class:italic={fight.ergebnis === 3}>{fight.blueTeam.kuerzel}</td>
<td class:font-bold={fight.ergebnis === 2} class:italic={fight.ergebnis === 3}>{fight.redTeam.kuerzel}</td>
<td>{getWinner(fight)}</td>
<thead>
<tr class="font-bold border-b">
{#each Array(rows) as i (i)}
<td>{t("announcements.table.time")}</td>
<td>{t("announcements.table.blue")}</td>
<td>{t("announcements.table.red")}</td>
<td>{t("announcements.table.winner")}</td>
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each window(event.fights.filter(f => f.group === group), rows) as fights}
<tr>
{#each fights as fight (fight.id)}
<td>{Intl.DateTimeFormat(astroI18n.locale, {
hour: "numeric",
minute: "numeric",
}).format(new Date(fight.start))}</td>
<td class:font-bold={fight.ergebnis === 1} class:italic={fight.ergebnis === 3}>{fight.blueTeam.kuerzel}</td>
<td class:font-bold={fight.ergebnis === 2} class:italic={fight.ergebnis === 3}>{fight.redTeam.kuerzel}</td>
<td>{getWinner(fight)}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
<style lang="scss">
div {
@apply p-3 bg-gray-200 dark:bg-neutral-800 rounded-2xl w-3/4 mx-auto;
}
</style>

Datei anzeigen

@ -48,30 +48,25 @@
}).sort((a, b) => b.points - a.points);
</script>
<div>
<table>
<tr class="font-bold border-b">
{#each Array(rows) as i (i)}
<td>{t("announcements.table.team")}</td>
<td>{t("announcements.table.points")}</td>
{/each}
</tr>
{#each window(teamPoints, rows) as teams}
<tr>
{#each teams as team (team.team.id)}
<td>{team.team.name}</td>
<td>{team.points}</td>
<div class="p-3 bg-gray-200 dark:bg-neutral-800 rounded-2xl w-3/4 mx-auto">
<table class="w-full">
<thead>
<tr class="font-bold border-b">
{#each Array(rows) as i (i)}
<td>{t("announcements.table.team")}</td>
<td>{t("announcements.table.points")}</td>
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each window(teamPoints, rows) as teams}
<tr>
{#each teams as team (team.team.id)}
<td>{team.team.name}</td>
<td>{team.points}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
<style lang="scss">
table {
@apply w-full;
}
div {
@apply p-3 bg-gray-200 dark:bg-neutral-800 rounded-2xl w-3/4 mx-auto;
}
</style>

Datei anzeigen

@ -110,7 +110,7 @@
<span class="btn__text">{t("navbar.links.account")}</span>
</a>
<!--
<button class="btn my-1" on:click={() => searchOpen = true}>
<button class="btn my-1" onclick={() => searchOpen = true}>
<SearchOutline ariaLabel="Site Search" class="inline-block h-6"/>
</button>
-->

Datei anzeigen

@ -32,7 +32,7 @@
<Modal bind:open title={error.message}>
<p>{error.stack}</p>
{#snippet footer()}
<Button on:click={() => open = false}>Close</Button>
<Button onclick={() => open = false}>Close</Button>
{/snippet}
</Modal>
{/if}

Datei anzeigen

@ -36,25 +36,22 @@
leftText = false,
searchValue = $bindable(items.find(item => item.value === selected)?.name || "")
}: Props = $props();
let open = $state(false);
let filteredItems = $derived(items.filter(item => item.name.toLowerCase().includes(searchValue.toLowerCase())).filter((value, index) => index < maxItems));
function selectItem(item: { name: string, value: string }) {
selected = item.value;
searchValue = "";
open = false;
}
</script>
<Button color="light"
on:click={() => open = true}>{selected === null ? 'Auswählen' : items.find(value => value.value === selected)?.name}</Button>
<Dropdown bind:open class="w-60">
<Button color="light">{selected === null ? 'Auswählen' : items.find(value => value.value === selected)?.name}</Button>
<Dropdown class="w-60">
{#snippet header()}
<div class="overflow-y-auto p-3 text-sm w-60" >
<Search bind:value={searchValue} on:focus={() => open = true} on:keydown={() => open = true}/>
</div>
{/snippet}
<div class="overflow-y-auto p-3 text-sm w-60" >
<Search bind:value={searchValue} />
</div>
{/snippet}
{#each filteredItems as item (item)}
<button onclick={() => selectItem(item)}
class="rounded p-2 hover:bg-gray-100 dark:hover:bg-gray-600 w-full cursor-pointer border-b border-b-gray-600"

Datei anzeigen

@ -168,11 +168,11 @@
</div>
<div>
{#if selectedBranch !== "master"}
<Button on:click={createFile} color="alternative" disabled={!selectedPath}>Create File
<Button onclick={createFile} color="alternative" disabled={!selectedPath}>Create File
</Button>
<Button on:click={() => deleteBranch(false)} color="none">Delete Branch</Button>
<Button onclick={() => deleteBranch(false)} color="none">Delete Branch</Button>
{:else}
<Button on:click={createBranch}>Create Branch</Button>
<Button onclick={createBranch}>Create Branch</Button>
{/if}
</div>
</div>
@ -193,7 +193,7 @@
</li>
{/each}
{:else}
<Button on:click={newAnnouncement}>Neue Ankündigung</Button>
<Button onclick={newAnnouncement}>Neue Ankündigung</Button>
{/if}
</ul>
{:catch error}

Datei anzeigen

@ -36,7 +36,7 @@
Mod-Tool
</span>
</NavBrand>
<NavHamburger on:click={toggle}/>
<NavHamburger onclick={toggle}/>
<NavUl {hidden}>
<NavLi href="#/edit">Edit Pages</NavLi>
<NavLi href="#/perms">Permissions</NavLi>
@ -51,7 +51,7 @@
<Spinner size={16}/>
</div>
{:then data}
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" on:click={() => showAdd = true}>
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" onclick={() => showAdd = true}>
<PlusOutline/>
</Button>

Datei anzeigen

@ -155,14 +155,14 @@
<h1>Permissions</h1>
{#each perms.perms as perm}
<Checkbox checked={activePerms.includes(perm)}
on:click={togglePerm(perm)}>{capitalize(perm.toLowerCase())}</Checkbox>
onclick={togglePerm(perm)}>{capitalize(perm.toLowerCase())}</Checkbox>
{/each}
<div class="mt-4">
<Button disabled={prefixEdit === (player?.prefix.name ?? "") && activePerms === (player?.perms ?? [])}
on:click={save}>Save
onclick={save}>Save
</Button>
{#if $me != null && $me.perms.includes("ADMINISTRATION")}
<Button on:click={() => resetPasswordModal = true}>
<Button onclick={() => resetPasswordModal = true}>
Reset Password
</Button>
@ -174,10 +174,10 @@
{#snippet footer()}
<Button class="ml-auto mr-4" on:click={resetResetPassword}>
<Button class="ml-auto mr-4" onclick={resetResetPassword}>
Cancel
</Button>
<Button disabled={resetPassword === "" || resetPassword !== resetPasswordRepeat} on:click={resetPW}>
<Button disabled={resetPassword === "" || resetPassword !== resetPasswordRepeat} onclick={resetPW}>
Reset Password
</Button>

Datei anzeigen

@ -84,10 +84,10 @@
<Toolbar class="!bg-gray-900">
{#snippet end()}
<ToolbarGroup >
<ToolbarButton on:click={deletePage}>
<ToolbarButton onclick={deletePage}>
Delete
</ToolbarButton>
<ToolbarButton color="primary" on:click={savePage}>
<ToolbarButton color="primary" onclick={savePage}>
Save
</ToolbarButton>
</ToolbarGroup>

Datei anzeigen

@ -43,8 +43,6 @@
let member = $state(event.maxTeamMembers);
let schemType = $state(event.schemType);
let publicOnly = $state(event.publicSchemsOnly);
let addReferee: {name: string, id: number}[] = [];
let removeReferee: {name: string, id: number}[] = [];
let errorOpen = $state(false);
let error: any = $state(undefined);
@ -69,9 +67,7 @@
endDate.diff(dayjs(event.end)) !== 0 ||
member !== event.maxTeamMembers ||
schemType != event.schemType ||
publicOnly !== event.publicSchemsOnly ||
addReferee.length > 0 ||
removeReferee.length > 0);
publicOnly !== event.publicSchemsOnly);
async function del() {
@ -95,8 +91,8 @@
publicSchemsOnly: publicOnly,
schemType: schemType ?? "null",
start: startDate,
addReferee: addReferee.map((ref) => ref.id),
removeReferee: removeReferee.map((ref) => ref.id)
addReferee: [],
removeReferee: []
};
try {
@ -153,8 +149,8 @@
</div>
<Toggle bind:checked={publicOnly} class="mt-4">Public Schematics Only</Toggle>
<div class="flex mt-4">
<Button disabled={!changed} on:click={update}>Update</Button>
<Button class="ml-4" color="red" on:click={() => deleteOpen = true}>Delete</Button>
<Button disabled={!changed} onclick={update}>Update</Button>
<Button class="ml-4" color="red" onclick={() => deleteOpen = true}>Delete</Button>
</div>
</form>
@ -163,8 +159,8 @@
<Modal bind:open={deleteOpen} outsideclose title="Delete {event.name}?">
<p>Are you sure you want to delete {event.name}?</p>
<div class="flex justify-end">
<Button on:click={() => deleteOpen = false}>Cancel</Button>
<Button class="ml-4" color="red" on:click={del}>Delete</Button>
<Button onclick={() => deleteOpen = false}>Cancel</Button>
<Button class="ml-4" color="red" onclick={del}>Delete</Button>
</div>
</Modal>

Datei anzeigen

@ -19,7 +19,7 @@
<script lang="ts">
import {EditOutline, TrashBinOutline} from "flowbite-svelte-icons";
import {Button, Modal, Toolbar, ToolbarButton} from "flowbite-svelte";
import {Button, Checkbox, Modal, Toolbar, ToolbarButton} from "flowbite-svelte";
import type {EventFight, ExtendedEvent} from "@type/event.ts";
import FightEditModal from "./modals/FightEditModal.svelte";
import {createEventDispatcher} from "svelte";
@ -32,6 +32,8 @@
i: number;
selected?: boolean;
hideEdit?: boolean;
select: () => void;
update: () => void;
}
let {
@ -39,29 +41,34 @@
data = $bindable(),
i,
selected = false,
hideEdit = false
hideEdit = false,
select,
update,
}: Props = $props();
let deleteOpen = $state(false);
let editOpen = $state(false);
let dispatcher = createEventDispatcher();
function dispatchSelect() {
setTimeout(() => {
if (!deleteOpen && !editOpen) {
dispatcher("select");
select();
}
}, 1);
}
async function deleteFight() {
await $fightRepo.deleteFight(fight.id);
dispatcher("update");
update();
}
let isUneven = $derived(i % 2 === 0);
</script>
<div class="flex h-16 {i % 2 === 0 ? 'bg-gray-800' : ''} mx-4 mt-6 rounded border {selected ? 'border-orange-700' : 'border-gray-700'} p-2 hover:bg-gray-700 transition justify-between shadow-lg cursor-pointer"
<div class={{"flex h-16 mx-4 mt-6 rounded border p-2 hover:bg-gray-700 transition justify-between shadow-lg cursor-pointer": true,
"bg-gray-800": isUneven,
"border-orange-700": selected,
"border-gray-700": !selected}}
onclick={dispatchSelect} onkeypress={dispatchSelect} role="checkbox" aria-checked={selected} tabindex="0"
>
<div class="flex">
@ -99,10 +106,10 @@
</div>
{#if !hideEdit}
<Toolbar embedded>
<ToolbarButton on:click={() => editOpen = true}>
<ToolbarButton onclick={() => editOpen = true}>
<EditOutline/>
</ToolbarButton>
<ToolbarButton color="red" on:click={() => deleteOpen = true}>
<ToolbarButton color="red" onclick={() => deleteOpen = true}>
<TrashBinOutline/>
</ToolbarButton>
</Toolbar>
@ -116,7 +123,7 @@
<p class="mb-5">
Are you sure you want to delete this fight?
</p>
<Button color="red" on:click={deleteFight}>Delete Fight</Button>
<Button color="red" onclick={deleteFight}>Delete Fight</Button>
<Button color="alternative">Cancel</Button>
</div>
</Modal>

Datei anzeigen

@ -82,7 +82,7 @@
} else {
groupFights.forEach(fight => selectedFights.add(fight));
}
selectedFights = selectedFights;
selectedFights = new Set(selectedFights);
}
let deleteOpen = $state(false);
@ -194,27 +194,27 @@
<div class="pb-28">
<Toolbar class="mx-4 mt-2 w-fit">
<ToolbarGroup>
<Checkbox class="ml-2" checked={selectedFights.size === fights.length} on:click={cycleSelect}/>
<Checkbox class="ml-2" checked={selectedFights.size === fights.length} onclick={cycleSelect}/>
<Tooltip>Select Upcoming</Tooltip>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarButton on:click={() => selectedFights.size > 0 ? changeTimeOpen = true : changeTimeOpen = false}>
<ToolbarButton onclick={() => selectedFights.size > 0 ? changeTimeOpen = true : changeTimeOpen = false}>
<CalendarWeekOutline/>
</ToolbarButton>
<Tooltip>Reschedule Fights</Tooltip>
<ToolbarButton on:click={() => selectedFights.size > 0 ? spectatePortOpen = true : spectatePortOpen = false}
<ToolbarButton onclick={() => selectedFights.size > 0 ? spectatePortOpen = true : spectatePortOpen = false}
disabled={changedTime === undefined}>
<ProfileCardOutline/>
</ToolbarButton>
<Tooltip>Change Spectate Port</Tooltip>
<ToolbarButton on:click={() => selectedFights.size > 0 ? groupChangeOpen = true : groupChangeOpen = false}>
<ToolbarButton onclick={() => selectedFights.size > 0 ? groupChangeOpen = true : groupChangeOpen = false}>
<UsersGroupOutline/>
</ToolbarButton>
<Tooltip>Change Group</Tooltip>
</ToolbarGroup>
<ToolbarGroup>
<ToolbarButton color="red"
on:click={() => selectedFights.size > 0 ? deleteOpen = true : deleteOpen = false}>
onclick={() => selectedFights.size > 0 ? deleteOpen = true : deleteOpen = false}>
<TrashBinOutline/>
</ToolbarButton>
<Tooltip>Delete</Tooltip>
@ -223,20 +223,21 @@
{#each groupedFights as group}
<div class="flex mt-4">
<Checkbox class="ml-2 text-center" checked={group.fights.every(gf => selectedFights.has(gf))}
on:click={() => cycleGroup(group.fights)}/>
onclick={() => cycleGroup(group.fights)}/>
<h1 class="ml-4 text-2xl">{group.group ?? "Ungrouped"}</h1>
</div>
{#each group.fights.sort((a, b) => a.start - b.start) as fight, i (fight.id)}
<FightCard {fight} {i} {data} selected={selectedFights.has(fight)}
on:select={() => {
{@const isSelected = selectedFights.has(fight)}
<FightCard {fight} {i} {data} selected={isSelected}
select={() => {
if (selectedFights.has(fight)) {
selectedFights.delete(fight);
} else {
selectedFights.add(fight);
}
selectedFights = selectedFights;
}}
on:update={async () => fights = await $fightRepo.listFights(data.event.id)}
selectedFights = new Set(selectedFights);
}} update={async () => fights = await $fightRepo.listFights(data.event.id)}
/>
{/each}
{/each}
@ -249,8 +250,8 @@
<p>Are you sure you want to delete {selectedFights.size} fights?</p>
{#snippet footer()}
<Button color="red" class="ml-auto" on:click={deleteFights}>Delete</Button>
<Button on:click={() => deleteOpen = false} color="alternative">Cancel</Button>
<Button color="red" class="ml-auto" onclick={deleteFights}>Delete</Button>
<Button onclick={() => deleteOpen = false} color="alternative">Cancel</Button>
{/snippet}
</Modal>
@ -262,8 +263,8 @@
</div>
{#snippet footer()}
<Button class="ml-auto" on:click={updateSpectatePort}>Change</Button>
<Button on:click={() => spectatePortOpen = false} color="alternative">Cancel</Button>
<Button class="ml-auto" onclick={updateSpectatePort}>Change</Button>
<Button onclick={() => spectatePortOpen = false} color="alternative">Cancel</Button>
{/snippet}
</Modal>
@ -276,8 +277,8 @@
</div>
{#snippet footer()}
<Button class="ml-auto" on:click={updateGroup}>Change</Button>
<Button on:click={() => groupChangeOpen = false} color="alternative">Cancel</Button>
<Button class="ml-auto" onclick={updateGroup}>Change</Button>
<Button onclick={() => groupChangeOpen = false} color="alternative">Cancel</Button>
{/snippet}
</Modal>
@ -295,14 +296,14 @@
:{("0" + deltaTime.minutes()).slice(-2)}</p>
{#snippet footer()}
<Button class="ml-auto" on:click={updateStartTime}>Update</Button>
<Button on:click={() => changeTimeOpen = false} color="alternative">Cancel</Button>
<Button class="ml-auto" onclick={updateStartTime}>Update</Button>
<Button onclick={() => changeTimeOpen = false} color="alternative">Cancel</Button>
{/snippet}
</Modal>
<SpeedDial>
<SpeedDialButton name="Add" on:click={() => createOpen = true}>
<SpeedDialButton name="Add" onclick={() => createOpen = true}>
<PlusOutline/>
</SpeedDialButton>
<SpeedDialButton name="Generate" href="#/event/{data.event.id}/generate">

Datei anzeigen

@ -43,6 +43,14 @@
async function addReferee() {
if (selectedPlayer) {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), {
deadline: null,
end: null,
maxTeamMembers: null,
name: null,
publicSchemsOnly: null,
removeReferee: null,
schemType: null,
start: null,
addReferee: [selectedPlayer]
})).referees;
}
@ -53,7 +61,15 @@
function removeReferee(id: string) {
return async () => {
referees = (await $eventRepo.updateEvent(data.event.id.toString(), {
removeReferee: [id]
deadline: null,
end: null,
maxTeamMembers: null,
name: null,
publicSchemsOnly: null,
addReferee: null,
schemType: null,
start: null,
removeReferee: [id],
})).referees;
}
}
@ -68,7 +84,7 @@
{#each referees as referee}
<li class="flex flex-grow justify-between">
{referee.name}
<SWButton on:click={removeReferee(referee.uuid)}>
<SWButton onclick={removeReferee(referee.uuid)}>
Entfernen
</SWButton>
</li>
@ -79,7 +95,7 @@
{/if}
</ul>
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" on:click={() => showAdd = true}>
<Button class="fixed bottom-6 right-6 !p-4 z-10 shadow-lg" onclick={() => showAdd = true}>
<PlusOutline/>
</Button>
@ -92,8 +108,8 @@
</div>
{#snippet footer()}
<div class="flex flex-grow justify-end">
<SWButton on:click={reset} type="gray">Abbrechen</SWButton>
<SWButton on:click={addReferee}>Hinzufügen</SWButton>
<SWButton onclick={reset} type="gray">Abbrechen</SWButton>
<SWButton onclick={addReferee}>Hinzufügen</SWButton>
</div>
{/snippet}
</SWModal>

Datei anzeigen

@ -102,8 +102,8 @@
</div>
{#snippet footer()}
<Button on:click={create} class="mr-auto" disabled={!canCreate}>Create</Button>
<Button color="light" on:click={() => open = false}>Cancel</Button>
<Button onclick={create} class="mr-auto" disabled={!canCreate}>Create</Button>
<Button color="light" onclick={() => open = false}>Cancel</Button>
{/snippet}
</Modal>

Datei anzeigen

@ -35,12 +35,13 @@
open?: boolean;
}
let { fight = $bindable(), data, open = $bindable(false) }: Props = $props();
let { fight = $bindable(), data = $bindable(), open = $bindable(false) }: Props = $props();
let redTeam = $state(fight.redTeam.id.toString());
let blueTeam = $state(fight.blueTeam.id.toString());
let start = $state(dayjs(fight.start).utc(true).toISOString().slice(0, -1));
let spectatePort = $state(fight.spectatePort?.toString() ?? null);
$inspect(spectatePort, fight.spectatePort)
let gamemode = $state(fight.spielmodus);
let map = $state(fight.map);
let group = $state(fight.group);
@ -62,6 +63,8 @@
start: dayjs(start)
};
console.log(update)
$fightRepo.updateFight(fight.id, update)
.then(value => {
open = false;
@ -90,8 +93,8 @@
/>
</div>
<div class="flex">
<Button on:click={save}>Save</Button>
<Button color="light" class="ml-auto" on:click={() => open = false}>Cancel</Button>
<Button onclick={save}>Save</Button>
<Button color="light" class="ml-auto" onclick={() => open = false}>Cancel</Button>
</div>
</Modal>

Datei anzeigen

@ -176,7 +176,7 @@
</div>
<div class="flex items-center mr-4">
<Button on:click={() => showAutoGrouping = true}>Automatic Grouping</Button>
<Button onclick={() => showAutoGrouping = true}>Automatic Grouping</Button>
</div>
</div>
@ -238,7 +238,7 @@
{/each}
</div>
<Button class="!p-4 fixed bottom-4 right-4" pill disabled={!generateDisabled} on:click={generateFights}>
<Button class="!p-4 fixed bottom-4 right-4" pill disabled={!generateDisabled} onclick={generateFights}>
<PlusOutline/>
</Button>
@ -248,8 +248,8 @@
{#snippet footer()}
<Button class="ml-auto" on:click={createGroups}>Create</Button>
<Button color="alternative" on:click={() => showAutoGrouping = false}>Cancel</Button>
<Button class="ml-auto" onclick={createGroups}>Create</Button>
<Button color="alternative" onclick={() => showAutoGrouping = false}>Cancel</Button>
{/snippet}
</Modal>

Datei anzeigen

@ -90,8 +90,8 @@
</div>
{#snippet footer()}
<Button color="alternative" on:click={() => open = false} class="mr-auto">Cancel</Button>
<Button on:click={createEvent} disabled={!canSubmit}>Create</Button>
<Button color="alternative" onclick={() => open = false} class="mr-auto">Cancel</Button>
<Button onclick={createEvent} disabled={!canSubmit}>Create</Button>
{/snippet}
</Modal>

Datei anzeigen

@ -130,7 +130,7 @@
</tr>
{/if}
{#each pagedSchematics as schem (schem.id)}
<SchematicListTile schem={schem} players={schematics.players} on:click={schemListClick(schem.type == null, schem.id)} />
<SchematicListTile schem={schem} players={schematics.players} onclick={schemListClick(schem.type == null, schem.id)} />
{/each}
</tbody>
</table>

Datei anzeigen

@ -31,15 +31,15 @@ export interface CreateEvent {
}
export interface UpdateEvent {
name?: string;
start?: Dayjs;
end?: Dayjs;
deadline?: Dayjs;
maxTeamMembers?: number;
schemType?: string | null;
publicSchemsOnly?: boolean;
addReferee?: string[];
removeReferee?: string[];
name: string | null;
start: Dayjs | null;
end: Dayjs | null;
deadline: Dayjs | null;
maxTeamMembers: number | null;
schemType: string | null;
publicSchemsOnly: boolean | null;
addReferee: string[] | null;
removeReferee: string[] | null;
}
export class EventRepo {

Datei anzeigen

@ -80,7 +80,7 @@ export class FightRepo {
blueTeam: fight.blueTeam,
redTeam: fight.redTeam,
start: fight.start?.valueOf(),
spectatePort: fight.spectatePort ?? 0,
spectatePort: fight.spectatePort,
group: fight.group,
}),
}).then(value => value.json())

Datei anzeigen

@ -29,7 +29,7 @@ import {pageRepo} from "@repo/page.ts";
import {dataRepo} from "@repo/data.ts";
export const schemTypes = cached<SchematicType[]>([], () =>
fetchWithToken(get(tokenStore), "/data/schematicTypes")
fetchWithToken(get(tokenStore), "/data/admin/schematicTypes")
.then(res => res.json()));
export const players = cached<Player[]>([], async () => {

Datei anzeigen

@ -18,19 +18,17 @@
-->
<script lang="ts">
import { createBubbler } from 'svelte/legacy';
const bubble = createBubbler();
import "@styles/button.css"
interface Props {
type?: "primary" | "ghost" | "gray";
children?: import('svelte').Snippet;
}
interface Props {
type?: "primary" | "ghost" | "gray";
children: import('svelte').Snippet;
onclick: () => void;
}
let { type = "primary", children }: Props = $props();
let { type = "primary", onclick, children }: Props = $props();
</script>
<button onclick={bubble('click')} class="btn" class:btn-gray={type === "gray"} class:btn-text={type === "ghost"}>
{@render children?.()}
<button onclick={onclick} class="btn" class:btn-gray={type === "gray"} class:btn-text={type === "ghost"}>
{@render children()}
</button>

Datei anzeigen

@ -18,28 +18,29 @@
-->
<script lang="ts">
import { run, createBubbler, stopPropagation } from 'svelte/legacy';
const bubble = createBubbler();
import {createEventDispatcher, onMount} from "svelte";
import {onMount} from "svelte";
import {stopPropagation} from "@components/util.ts";
interface Props {
title: string;
open: boolean;
children?: import('svelte').Snippet;
footer?: import('svelte').Snippet;
onclose?: () => void;
onclick?: () => void;
}
let {
title,
open = $bindable(),
children,
footer
footer,
onclose = () => {},
onclick = () => {}
}: Props = $props();
let internalOpen = $state(open);
const dispatch = createEventDispatcher();
let dialog: HTMLDialogElement = $state();
@ -53,52 +54,30 @@
function close() {
open = false;
internalOpen = false;
dispatch("close");
onclose()
}
run(() => {
if (open && !internalOpen) {
dialog.showModal();
internalOpen = true;
} else if (!open && internalOpen) {
dialog.close();
internalOpen = false;
}
});
$effect(() => {
if (open && !internalOpen) {
dialog.showModal();
internalOpen = true;
} else if (!open && internalOpen) {
dialog.close();
internalOpen = false;
}
})
</script>
<dialog bind:this={dialog} onclose={close} oncancel={close} onclick={() => dialog.close()} aria-hidden="true">
<div onclick={stopPropagation(bubble('click'))} aria-hidden="true">
<div class="spaced bordered">
<h1>{title}</h1>
<dialog bind:this={dialog} onclose={close} onclick={(e) => dialog.close()} aria-hidden="true" class="max-h-full max-w-md w-full rounded-lg shadow-lg dark:bg-neutral-800 dark:text-neutral-100">
<div onclick={stopPropagation(onclick)} aria-hidden="true">
<div class="p-6 border-b border-neutral-200 dark:border-neutral-700">
<h1 class="text-4xl font-bold">{title}</h1>
</div>
<div class="spaced main bordered">
<div class="p-6 main border-b border-neutral-200 dark:border-neutral-700">
{@render children?.()}
</div>
<div class="footer spaced" onclick={() => dialog.close()} aria-hidden="true">
<div class="flex mx-4 my-2 p-6" onclick={() => dialog.close()} aria-hidden="true">
{@render footer?.()}
</div>
</div>
</dialog>
<style lang="scss">
h1 {
@apply text-4xl font-bold;
}
dialog {
@apply max-h-full max-w-md w-full rounded-lg shadow-lg
dark:bg-neutral-800 dark:text-neutral-100;
}
.spaced {
@apply p-6;
}
.bordered {
@apply border-b border-neutral-200 dark:border-neutral-700;
}
.footer {
@apply flex mx-4 my-2;
}
</style>

Datei anzeigen

@ -24,3 +24,10 @@ export function window<T>(arr: T[], len: number): T[][] {
}
return result;
}
export function stopPropagation(a: any) {
return (e: Event) => {
e.stopPropagation();
a(e);
};
}

Datei anzeigen

@ -0,0 +1,22 @@
---
title: Adventskalender Schems
key: adventskalender-schems
description: Gesucht werden Schematics für den Adventskalender 2024.
created: 2024-10-13
tags:
- offtopic
---
**Hallo Liebe Community,**
auch dieses Jahr möchten wir einen Adventskalender organisieren. Dafür sind wir nach wie vor auf der Suche nach Technik welch wir hinter den Türchen verstecken können. Es werden keine Fertige MWGs, WS, WGs oder AS gesucht. sondern nur Technik. Es ist egal ob es sich dabei über Verteidigungs- oder Angriffstechnik handelt. (Schilde, Missels, Kanonen etc..)
Schems von Spielern welch angenommen werden bekommen nach dem Adventskalender automatisch alle Schems zur Verfügung.
Ihr könnt die Schematics entweder über unsere Discordfunktion im Bereich Support mit dem Raster Questions einreichen, oder bei **YoyoNow** persönlich abgeben. Idealerweise über Discord oder per private Nachricht auf dem Minecraftserver.
Wir benötigen diese Schems bis zum **1.11.2024** um noch Zeit zu haben diese zu Prüfen und zu Testen. Es wäre sehr schade, wenn wir auf Grund fehlender Schems dieses Jahr keinen Adventskalender zustande bekommen und bedanke mich schon im voraus für Eure mithilfe.
Viele Grüße
Steamwar Serverteam

Datei anzeigen

@ -0,0 +1,44 @@
---
title: HalloweenFN Kampfplan Abstimmung
key: halloween-fn-kampfplan-abstimmung
description: Abstimmung über den Kampfplan für die Halloween Fight Night.
created: 2024-10-23
tags:
- event
- wargear
image: ../../../images/SwFightNightLogoHalloween.png
---
Ahoi Community.
Es gab mehr Anmeldungen am Event als erwartet. Dies führt über eine sehr lange Laufzeit der Kämpfe. Hier werden auch beide offene Arenen benutzt.
wie im DC Bereich angekündigt eine Auswahl an Optionen vom Kampfplan.
## Option 1: All vs All
Geschätzte maximale Dauer 11 Stunden. auf zwei Tage verteilt
- Samstag 26.10.2024 und Sonntag 27.10.2024 Stimme 1
- Samstag 26.10.2024 und Samstag 2.11.2024 Stimme 2
## Option 2 Gruppenphase + Kleines KO Halbfinale, Platz 3, Finale
Geschätzte maximale Dauer 5 Stunden Gruppe + 1 Stunde KO
- Samstag 26.10.2024 und Sonntag 27.10.2024 Stimme 3
- Samstag 26.10.2024 und Sonntag 2.11.2024 Stimme 4
- Samstag 26.10.2024 In einem Stück Stimme 5
## Option 3 Gruppenphase + großes KO Viertelfinale, Halbfinale, Platz 3, Finale
Geschätzte maximale Dauer 5 Stunden Gruppe + 2 Stunden KO
- Samstag 26.10.2024 und Sonntag 27.10.2024 Stimme 6
- Samstag 26.10.2024 und Sonntag 2.11.2024 Stimme 7
Die Kampftage würden um jeweils 17 Uhr starten.
Beachtet, bei der geschätzten Dauer, dass es durchaus die Möglichkeit gibt Fights vorzuschieben um die Dauer zu reduzieren. Die Kämpfe wurde mit max. 30 Min versehen.
Ich Bitte nur Spieler abstimmen zu lassen welch am Event Teilnehmen. Vielen Dank.

Datei anzeigen

@ -0,0 +1,64 @@
---
title: Halloween Fight Night
key: halloween-fight-night
description: Halloween Event im Wargear Modus.
created: 2024-08-31
tags:
- event
- wargear
image: ../../../images/SwFightNightLogoHalloween.png
---
**Liebe Community,**
die Tage werden langsam kürzer und die Nächte länger. Es geht auf dem Herbst zu und erinnert
daran, dass das Jahr wieder halb vorbei ist. Wie im letzten Jahr wird wieder ein Halloween Event
veranstaltet. Dieses Mal im Spielmodus **Wargear**. Es wird ein Wargear Event sein ohne Automatiks,
zusätzlich wird es mit einem Designcontest begleitet.
- Das Event wird am **26.10.2024** Stattfinden
- Standard Wargear Regelwerk ohne Automatische Kanonen
- Design Regel: **Halloween**
- Anmelde + Einsendeschluss **21.10.2024**
- Ernennung des Teamvertreter **21.10.2024**
- Hot fixes bis **24.10.2024** möglich
Neben dem eigentlichen Turnier wird das Außendesign bewertet. Die Bewertung des Außendedigns
wird zu **70% Das SW Builderteam** übernehmen und **30% die Userbewertung**. Die prozentuale
Bewertung soll dazu dienen, dass große Teams Ihr eigenes Design nicht hoch puschen können.
---
## Fight Bewertung
- Klassisches Alle vs Alle Turnier
- Sieg 1 Punkt
- Niederlage 0 Punkte
- Kampfleiter kann TechKO ermitteln
- Bei unentschieden (Beide WGs besitzen noch funktionsfähige Kanonen), wird das WG welch im besseren zustand ist zum Sieger ernannt.
## Design Bewertung
- **Userbewertung (30%)** wird über den Discord Community Server von SW organisiert. (Bilder vom Außendesign werden gepostet und per Abstimmung ausgelost)
---
- **Builderbewertung (70%)** läuft nach folgende Kriterien ab.
- Form des WGs
- Farbgestaltung
- Muster
- Thematisierung: Thema Halloween / Gruse
---
Es wird also 3 Sieges- Plätze geben welch wie Folgt ermittelt wird.
- Gesamtsieger: Höchste Fight Platzierung und Design Platzierung im Durchschnitt
- FN- Sieger : Höchste Fight Platzierung
- Designsieger: Bestes Design
**Das Wargeardesign vom Gesamtsieger wird bis zum nächsten Halloween in der Lobby ausgestellt.**
Wir wünschen alle Teilnehmenden Teams viel Spaß und Erfolg. Natürlich auch
**HAPPY HALLOWEEN**

Datei anzeigen

@ -0,0 +1,99 @@
---
title: Halloween Fight Night Abschluss
key: halloween-fn-abschluss
description: Abschluss des Halloween Fight Night Events.
created: 2024-11-11
tags:
- event
- wargear
image: ../../../images/SwFightNightLogoHalloween.png
---
**Geehrte Community.**
die Userbewertungen, Builderbwertungen und der Kampftag liegen schon eine weile zurück und die Auswertung wurde abgeschlossen.
## Builderbewertung Design:
1. GG
2. AD
3. GP
4. Hlcy
5. FK
6. WT
7. LKT
8. DFD
9. WF
10. Ouro
## Userbewertung Design:
1. GG
2. GP
3. Hlcy
4. FK
5. WT
6. AD
7. DFD
8. LKT
9. WF
10. Ouro
## Zusammenrechnung.
Die Punkte wurden wie folgt vergeben. Sowohl Designplatz als auch Fightplatz
1. Platz 10 Punkte
2. Platz 9 Punkte
3. Platz 8 Punkte
4. Platz 7 Punkte
5. Platz 6 Punkte
6. Platz 5 Punkte
7. Platz 4 Punkte
8. Platz 3 Punkte
9. Platz 2 Punkte
10. Platz 1 Punkt
(Builderbwertung Punktzahl * 7) + (Userbewertung Punktzahl *3)
## Designgesamtergebnis
| Platz | Team | Punkte |
|-------|----------------------|--------|
| 1 | GG | 100 |
| 2 | GP | 83 |
| 3 | AD | 78 |
| 4 | Hlcy | 73 |
| 5 | FK | 63 |
| 6 | WT | 53 |
| 7 | LKT | 37 |
| 8 | DFD | 33 |
| 9 | WF | 20 |#
| 10 | Ouro (Publicwargear) | 10 |
Somit gewinnt GG den Designcontest
## Gesamtsieger
Designpunkte + (Kampfplatzierung * 100) : 2 Bei gleicher Punktzahl erhält das Team welch im Durchschnitt der 3 Bewertungen besser abgeschlossen hat einen extra Punkt. Teams welch trotz Anmeldung nicht anwesend waren bekommen alle Punkte abgezogen.
| Platz | Team | Punkte |
|-------|--------------|--------|
| 1 | GP | 91,5 |
| 2 | GG | 90 |
| 3 | Hlcy | 81,5 |
| 4 | AD | 64 |
| 5 | FK | 57,5 |
| 6 | WT | 56,5 |
| 7 | DFD | 51,5 |
| 8 | LKT | 48,5 |
| 9 | WF | 30 |
| 10 | Ouro | 0 |
Somit ist **GurkenParade** der Sieger des Events.
In den kommenden Tagen wird mit GP Rücksprache gehalten um Ihr EventWG zu Modifizieren sodass es auf der Lobby ausgestellt werden kann. Wir bedanken uns für die rege Teilnahme und wünschen weiterhin viel Spaß bei unseren kommenden Events.
**Liebe Grüße**
Steamwar Team

Datei anzeigen

@ -0,0 +1,85 @@
---
title: HalloweenFN Kampfplan
key: halloween-fn-kampfplan
description: Der Kampfplan für die Halloween Fight Night.
created: 2024-10-25
tags:
- event
- wargear
image: ../../../images/SwFightNightLogoHalloween.png
---
Info: 2 Gruppen. Kampftag 26.10.2024
## Gruppenphase
| Gruppe A | Punkte | Gruppe B | Punkte |
|----------|--------|----------|--------|
| GP | 4 | Hlcy | 4 |
| DFD | 3 | GG | 3 |
| LKT | 2 | WT | 2 |
| FK | 1 | AD | 1 |
| WF | 0 | Our | 0 |
## Kampfplan Gruppe A
| Begegnung | Zeit | Ergebnis |
|------------|-------|----------|
| LKT vs GP | 17:00 | GP |
| FK vs WF | 17:30 | FK |
| DFD vs GP | 18:00 | GP |
| WF vs LKT | 18:30 | LKT |
| FK vs DFD | 19:00 | DFD |
| WF vs GP | 19:30 | GP |
| LKT vs DFD | 20:00 | DFD |
| GP vs FK | 20:30 | GP |
| WF vs DFD | 21:00 | DFD |
| LKT vs FK | 21:30 | LKT |
## Kampfplan Gruppe B
| Begegnung | Zeit | Ergebnis |
|--------------|-------|----------|
| GG vs WT | 17:15 | GG |
| AD vs Ouro | 17:45 | AD |
| GG vs Hlcy | 18:15 | Hlcy |
| AD vs WT | 18:45 | WT |
| Hlcy vs Ouro | 19:15 | Hlcy |
| AD vs GG | 19:45 | GG |
| WT vs Hlcy | 20:15 | Hlcy |
| Ouro vs GG | 20:45 | GG |
| AD vs Hlcy | 21:15 | Hlcy |
| Ouro vs WT | 21:45 | WT |
## KO Phase.
### Erste beiden einer Gruppe kommen weiter.
| Begegnung | Zeit | Ergebnis |
|-------------|-------|----------|
| GP vs GG | 22:00 | GP |
| Hlcy vs DFD | 22:15 | Hlcy |
| GG vs DFD | 22:30 | GG |
| GP vs Hlcy | 23:15 | GP |
## Endergebnis Fight Tag
1. GP
2. Hlcy
3. GG
## Endergebnis Design Contest
1. GG
2. GP
3. AD
4. Hlcy
5. FK
6. WT
7. DFD
8. LKT
9. WF
10. Ouro
# Gesamtsieger
**GP**

Datei anzeigen

@ -0,0 +1,17 @@
---
title: Neujahrsevent 2025 Eventplan
key: Neujahrsevent-2025-eventplan
description: Der Kampfplan für das Neujahrsevent 2025.
created: 2025-01-01
tags:
- event
- microwargear
---
# Gruppenphase
<group-table data-event="64"> </group-table>
## Kampfplan
<fight-table data-event="64" data-group="Gruppe 1"> </fight-table>

Datei anzeigen

@ -0,0 +1,18 @@
---
title: Schneeballschlacht Kampfplan
key: schneeballschlacht-eventplan
description: Der Kampfplan für die Schneeballschlacht.
created: 2024-12-21
tags:
- event
- miniwargear
image: ../../../images/SchneeballschlachtMWG.png
---
# Gruppenphase
<group-table data-event="65"> </group-table>
## Kampfplan
<fight-table data-event="65" data-group="Gruppe 1"> </fight-table>

Datei anzeigen

@ -0,0 +1,38 @@
---
title: Schneeballschlacht
key: schneeballschlacht
description: Die Schneeballschlacht auf SteamWar.
created: 2024-11-17
tags:
- event
- miniwargear
image: ../../../images/SchneeballschlachtMWG.png
---
**Ahoi Liebe Community,**
Die Tage werden kürzer und kälter, es geht auf die weiße Jahreszeit zu. Wenn der erste Schnee liegt, wird es Zeit, sich mit Mütze und Handschuhen zu bewaffnen und nach draußen zu eilen. Auch auf SteamWar wird dieses Jahr eine Schneeballschlacht stattfinden, im Modus MiniWarGear. Das Event wird, wie auch schon das Halloween-Event, von einer Community-Abstimmung begleitet, Das MWG-Regelwerk wurde mit einigen zusätzlichen Regeln erweitert.
- Das Event wird am **22.12.2024** stattfinden
- Einsendeschluss **18.12.2024**, Hotfixes dürfen bis zum **20.12.2024** Eingesendet werden
- Design-Regel: **Weihnachtliches/Winterliches Design**
## Regeln:
- Regelwerk: **MiniWarGear**, ohne MGs, 120 TNT trotzdem erlaubt
- **Weißer Trockenbeton**/**White Concrete Powder** darf zum Gegner geschossen und/oder geboosted werden, beginnend ab der Ausfahrzeit
- Solche „Schneeballkanonen“ zählen nicht zum Kanonenlimit und dürfen vorbeladen sein, solange sie keine Projektile schießen können
- Schneeballkanonen dürfen Wasser für ihre Treibladungen benutzen
- Der Turnieraufbau ist wie folgt:
- Alle 20 min Start, jeweils zwei Fights je 10 min versetzt
- Struktur: Ranglistenturnier (Gruppenphase, in KO-Phase wird jeder Platz (1, 2, 3, 4, 5, 6, …) umkämpft
## Die beste „Schneeballkanone“ wird per Uservoting wie folgt besimmt
- Jedes Team muss am Tag des Turnieres (z.B. nach Ende der Fights) Bild/Videomaterial von ihrer Schneeballkanone per Discord an Zent4rus oder zSalos schicken, diese werden danach unter einem Thread zur Abstimmung veröffentlicht
- Die Darstellung der Schneeballkanone (mit/ohne Techhider, mit/ohne MWG außen rum) obliegt den Teams selbst
- Sieger von bester Schneeballkanone wird durch Uservote bestimmt (ähnlich wie bei WG – Designcontest)
- Die Abstimmung endet drei Tage nach Veröffentlichung der Abstimmung
Der Gesamtsieger wird mit folgender Formel bestimmt: 0,66 * Fightplatzierung + 0,33 * Platzierung Uservoting, bei Gleichstand bestimmt die Fightplatzierung
**Wir wünschen allen teilnehmenden Teams viel Erfolg!**

Datei anzeigen

@ -146,7 +146,8 @@
"winner": "Sieger",
"notPlayed": "Nicht gespielt",
"draw": "Unentschieden",
"points": "Punkte"
"points": "Punkte",
"team": "Team"
}
},
"blog": {

Binäre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  Größe: 387 KiB

Binäre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  Größe: 83 KiB

Datei anzeigen

@ -105,48 +105,48 @@ const ogImage = await getImage({
<Content/>
<script>
import FightTable from "@components/FightTable.svelte";
// @ts-expect-error Import Schenanigans
import {get} from "svelte/store";
import GroupTable from "@components/GroupTable.svelte";
import {eventRepo} from "../../components/repo/event";
import type {ExtendedEvent} from "@type/event";
import {mount} from "svelte";
const eventMounts: Map<string, ((ev: ExtendedEvent) => void)[]> = new Map();
class FightTableElement extends HTMLElement {
connectedCallback(): void {
if (!eventMounts.has(this.dataset["event"])) {
eventMounts.set(this.dataset["event"], []);
if (!eventMounts.has(this.dataset["event"]!)) {
eventMounts.set(this.dataset["event"]!, []);
}
const rows = Number.parseInt(this.dataset["rows"]);
eventMounts.get(this.dataset["event"]).push(ev => {
new FightTable({
const rows = Number.parseInt(this.dataset["rows"]!);
eventMounts.get(this.dataset["event"]!)!.push(ev => {
mount(FightTable, {
target: this,
props: {
event: ev,
group: this.dataset["group"],
rows: !isNaN(rows) ? rows : 1,
},
});
});
});
}
}
class GroupTableElement extends HTMLElement {
connectedCallback(): void {
if (!eventMounts.has(this.dataset["event"])) {
eventMounts.set(this.dataset["event"], []);
if (!eventMounts.has(this.dataset["event"]!)) {
eventMounts.set(this.dataset["event"]!, []);
}
const rows = Number.parseInt(this.dataset["rows"]);
eventMounts.get(this.dataset["event"]).push(ev => {
new GroupTable({
const rows = Number.parseInt(this.dataset["rows"]!);
eventMounts.get(this.dataset["event"]!)!.push(ev => {
mount(GroupTable, {
target: this,
props: {
event: ev,
group: this.dataset["group"],
rows: !isNaN(rows) ? rows : 1,
},
});
});
});
}
}
@ -157,7 +157,7 @@ const ogImage = await getImage({
function mountEvent() {
for (const key of eventMounts.keys()) {
get(eventRepo).getEvent(key).then(ev => {
for (const mount of eventMounts.get(key)) {
for (const mount of eventMounts.get(key)!) {
mount(ev);
}
});

5
src/pages/discord.astro Normale Datei
Datei anzeigen

@ -0,0 +1,5 @@
---
import Redirect from "../layouts/Redirect.astro";
---
<Redirect url="https://discord.gg/prFBhCe4Rt" />

5
src/pages/youtube.astro Normale Datei
Datei anzeigen

@ -0,0 +1,5 @@
---
import Redirect from "../layouts/Redirect.astro";
---
<Redirect url="https://www.youtube.com/channel/UCCLzHkbVfs6TQh3dskWDGgQ" />

Datei anzeigen

@ -18,7 +18,7 @@
*/
table {
@apply w-full rounded-2xl shadow-lg overflow-clip;
@apply w-full overflow-clip;
:not(:has([data-no-head])) {
}