From ba68c17898d47f641a65ec28ff8a50d4dd8f649b Mon Sep 17 00:00:00 2001 From: AnthonyDuan Date: Tue, 28 Jul 2026 13:05:53 +0800 Subject: [PATCH] Initial taiko.su easter-egg site --- .devcontainer/devcontainer.json | 3 + .dockerignore | 14 + .gitattributes | 17 + .github/ISSUE_TEMPLATE.md | 3 + .gitignore | 25 + ...mize Loading with Multi-Process Workers.md | 20 + ...emove Delete Option and Redirect Upload.md | 9 + Dockerfile | 12 + MONGODB_SAFETY.md | 40 + README.md | 68 + app.py | 774 ++++++ config.example.py | 24 + config.py | 19 + docker-compose.yml | 48 + gunicorn.conf.py | 18 + public/assets/audio/neiro_1_don.ogg | Bin 0 -> 9691 bytes public/assets/audio/neiro_1_ka.ogg | Bin 0 -> 6814 bytes public/assets/audio/se_balloon.ogg | Bin 0 -> 7139 bytes public/assets/audio/se_calibration.ogg | Bin 0 -> 4704 bytes public/assets/audio/se_cancel.ogg | Bin 0 -> 7876 bytes public/assets/audio/se_don.ogg | Bin 0 -> 10361 bytes public/assets/audio/se_gameclear.ogg | Bin 0 -> 42228 bytes public/assets/audio/se_gamefail.ogg | Bin 0 -> 22502 bytes public/assets/audio/se_gamefullcombo.ogg | Bin 0 -> 60036 bytes public/assets/audio/se_jump.ogg | Bin 0 -> 9732 bytes public/assets/audio/se_ka.ogg | Bin 0 -> 5487 bytes public/assets/audio/se_pause.ogg | Bin 0 -> 6621 bytes public/assets/audio/v_combo_100.ogg | Bin 0 -> 11885 bytes public/assets/audio/v_combo_1000.ogg | Bin 0 -> 19829 bytes public/assets/audio/v_combo_1100.ogg | Bin 0 -> 13412 bytes public/assets/audio/v_combo_1200.ogg | Bin 0 -> 14889 bytes public/assets/audio/v_combo_1300.ogg | Bin 0 -> 14707 bytes public/assets/audio/v_combo_1400.ogg | Bin 0 -> 14309 bytes public/assets/audio/v_combo_1500.ogg | Bin 0 -> 14158 bytes public/assets/audio/v_combo_1600.ogg | Bin 0 -> 13380 bytes public/assets/audio/v_combo_1700.ogg | Bin 0 -> 14410 bytes public/assets/audio/v_combo_1800.ogg | Bin 0 -> 14091 bytes public/assets/audio/v_combo_1900.ogg | Bin 0 -> 14096 bytes public/assets/audio/v_combo_200.ogg | Bin 0 -> 15012 bytes public/assets/audio/v_combo_2000.ogg | Bin 0 -> 23718 bytes public/assets/audio/v_combo_2100.ogg | Bin 0 -> 13263 bytes public/assets/audio/v_combo_2200.ogg | Bin 0 -> 14401 bytes public/assets/audio/v_combo_2300.ogg | Bin 0 -> 15264 bytes public/assets/audio/v_combo_2400.ogg | Bin 0 -> 16289 bytes public/assets/audio/v_combo_2500.ogg | Bin 0 -> 14666 bytes public/assets/audio/v_combo_2600.ogg | Bin 0 -> 15675 bytes public/assets/audio/v_combo_2700.ogg | Bin 0 -> 15717 bytes public/assets/audio/v_combo_2800.ogg | Bin 0 -> 15551 bytes public/assets/audio/v_combo_2900.ogg | Bin 0 -> 15298 bytes public/assets/audio/v_combo_300.ogg | Bin 0 -> 15927 bytes public/assets/audio/v_combo_3000.ogg | Bin 0 -> 21456 bytes public/assets/audio/v_combo_3100.ogg | Bin 0 -> 14239 bytes public/assets/audio/v_combo_3200.ogg | Bin 0 -> 16286 bytes public/assets/audio/v_combo_3300.ogg | Bin 0 -> 17666 bytes public/assets/audio/v_combo_3400.ogg | Bin 0 -> 16443 bytes public/assets/audio/v_combo_3500.ogg | Bin 0 -> 16237 bytes public/assets/audio/v_combo_3600.ogg | Bin 0 -> 15308 bytes public/assets/audio/v_combo_3700.ogg | Bin 0 -> 16500 bytes public/assets/audio/v_combo_3800.ogg | Bin 0 -> 16155 bytes public/assets/audio/v_combo_3900.ogg | Bin 0 -> 18696 bytes public/assets/audio/v_combo_400.ogg | Bin 0 -> 14717 bytes public/assets/audio/v_combo_4000.ogg | Bin 0 -> 22173 bytes public/assets/audio/v_combo_4100.ogg | Bin 0 -> 14009 bytes public/assets/audio/v_combo_4200.ogg | Bin 0 -> 17077 bytes public/assets/audio/v_combo_4300.ogg | Bin 0 -> 17091 bytes public/assets/audio/v_combo_4400.ogg | Bin 0 -> 17495 bytes public/assets/audio/v_combo_4500.ogg | Bin 0 -> 15505 bytes public/assets/audio/v_combo_4600.ogg | Bin 0 -> 16341 bytes public/assets/audio/v_combo_4700.ogg | Bin 0 -> 16766 bytes public/assets/audio/v_combo_4800.ogg | Bin 0 -> 16828 bytes public/assets/audio/v_combo_4900.ogg | Bin 0 -> 17697 bytes public/assets/audio/v_combo_50.ogg | Bin 0 -> 13698 bytes public/assets/audio/v_combo_500.ogg | Bin 0 -> 15179 bytes public/assets/audio/v_combo_5000.ogg | Bin 0 -> 29351 bytes public/assets/audio/v_combo_600.ogg | Bin 0 -> 14333 bytes public/assets/audio/v_combo_700.ogg | Bin 0 -> 14855 bytes public/assets/audio/v_combo_800.ogg | Bin 0 -> 15360 bytes public/assets/audio/v_combo_900.ogg | Bin 0 -> 15752 bytes public/assets/audio/v_donder_fullcombo.ogg | Bin 0 -> 27941 bytes public/assets/audio/v_fullcombo.ogg | Bin 0 -> 16616 bytes public/assets/audio/v_renda.ogg | Bin 0 -> 19529 bytes public/assets/audio/v_start.ogg | Bin 0 -> 22266 bytes public/assets/fonts/Kozuka.otf | Bin 0 -> 20528 bytes public/assets/fonts/TnT.ttf | Bin 0 -> 4718572 bytes public/assets/img/apple-touch-icon.png | Bin 0 -> 59888 bytes public/assets/img/balloon.png | Bin 0 -> 1691 bytes public/assets/img/bg_don_1a.png | Bin 0 -> 78522 bytes public/assets/img/bg_don_1b.png | Bin 0 -> 5341 bytes public/assets/img/bg_don_2a.png | Bin 0 -> 4986 bytes public/assets/img/bg_don_2b.png | Bin 0 -> 72600 bytes public/assets/img/bg_don_3a.png | Bin 0 -> 33278 bytes public/assets/img/bg_don_3b.png | Bin 0 -> 49344 bytes public/assets/img/bg_don_4a.png | Bin 0 -> 54710 bytes public/assets/img/bg_don_4b.png | Bin 0 -> 37069 bytes public/assets/img/bg_don_5a.png | Bin 0 -> 33661 bytes public/assets/img/bg_don_5b.png | Bin 0 -> 28787 bytes public/assets/img/bg_don_6a.png | Bin 0 -> 69233 bytes public/assets/img/bg_don_6b.png | Bin 0 -> 57015 bytes public/assets/img/bg_pause.png | Bin 0 -> 3801 bytes public/assets/img/bg_score_p1.png | Bin 0 -> 11713 bytes public/assets/img/bg_song_1a.png | Bin 0 -> 738901 bytes public/assets/img/bg_song_1b.png | Bin 0 -> 139289 bytes public/assets/img/bg_song_2a.png | Bin 0 -> 925410 bytes public/assets/img/bg_song_2b.png | Bin 0 -> 177030 bytes public/assets/img/bg_song_3a.png | Bin 0 -> 1120556 bytes public/assets/img/bg_song_3b.png | Bin 0 -> 200501 bytes public/assets/img/bg_song_4a.png | Bin 0 -> 515648 bytes public/assets/img/bg_song_4b.png | Bin 0 -> 17309 bytes public/assets/img/bg_song_5a.png | Bin 0 -> 664932 bytes public/assets/img/bg_song_5b.png | Bin 0 -> 143848 bytes public/assets/img/bg_stage_1.png | Bin 0 -> 351 bytes public/assets/img/bg_stage_2.png | Bin 0 -> 4607 bytes public/assets/img/bg_stage_3.png | Bin 0 -> 8397 bytes public/assets/img/dancing-don.gif | Bin 0 -> 5433 bytes public/assets/img/difficulty.png | Bin 0 -> 48870 bytes public/assets/img/don_anim_10combo_a.png | Bin 0 -> 831897 bytes public/assets/img/don_anim_10combo_b1.png | Bin 0 -> 8979 bytes public/assets/img/don_anim_10combo_b2.png | Bin 0 -> 5041 bytes public/assets/img/don_anim_clear_a.png | Bin 0 -> 1044030 bytes public/assets/img/don_anim_clear_b1.png | Bin 0 -> 12614 bytes public/assets/img/don_anim_clear_b2.png | Bin 0 -> 7035 bytes public/assets/img/don_anim_gogo_a.png | Bin 0 -> 1978020 bytes public/assets/img/don_anim_gogo_b1.png | Bin 0 -> 23339 bytes public/assets/img/don_anim_gogo_b2.png | Bin 0 -> 12189 bytes public/assets/img/don_anim_gogostart_a.png | Bin 0 -> 852034 bytes public/assets/img/don_anim_gogostart_b1.png | Bin 0 -> 10180 bytes public/assets/img/don_anim_gogostart_b2.png | Bin 0 -> 5205 bytes public/assets/img/don_anim_normal_a.png | Bin 0 -> 558127 bytes public/assets/img/don_anim_normal_b1.png | Bin 0 -> 5906 bytes public/assets/img/don_anim_normal_b2.png | Bin 0 -> 3900 bytes public/assets/img/favicon-16.png | Bin 0 -> 909 bytes public/assets/img/favicon-192.png | Bin 0 -> 67029 bytes public/assets/img/favicon-32.png | Bin 0 -> 2935 bytes public/assets/img/favicon-512.png | Bin 0 -> 388867 bytes public/assets/img/favicon.ico | Bin 0 -> 164474 bytes public/assets/img/favicon.png | Bin 0 -> 9856 bytes public/assets/img/fire_anim.png | Bin 0 -> 95905 bytes public/assets/img/fireworks_anim.png | Bin 0 -> 1057821 bytes public/assets/img/loader-stage.jpg | Bin 0 -> 398392 bytes public/assets/img/mimizu.png | Bin 0 -> 10913 bytes public/assets/img/notes.png | Bin 0 -> 34073 bytes public/assets/img/notes_drumroll.png | Bin 0 -> 25624 bytes public/assets/img/notes_explosion.png | Bin 0 -> 362675 bytes public/assets/img/notes_hit.png | Bin 0 -> 41498 bytes public/assets/img/roll_count_bubble.png | Bin 0 -> 94588 bytes public/assets/img/taiko.png | Bin 0 -> 13900 bytes public/assets/img/touch_drum.png | Bin 0 -> 34417 bytes public/assets/img/touch_fullscreen.png | Bin 0 -> 667 bytes public/assets/img/touch_pause.png | Bin 0 -> 659 bytes public/assets/img/vectors.json | 29 + public/manifest.json | 26 + public/src/css/admin.css | 1215 +++++++++ public/src/css/experience.css | 164 ++ public/src/css/game.css | 476 ++++ public/src/css/loader.css | 264 ++ public/src/css/loadsong.css | 77 + public/src/css/main.css | 29 + public/src/css/songbg.css | 364 +++ public/src/css/view.css | 472 ++++ public/src/js/abstractfile.js | 41 + public/src/js/assets.js | 106 + public/src/js/autoscore.js | 212 ++ public/src/js/browsersupport.js | 203 ++ public/src/js/canvasasset.js | 151 ++ public/src/js/canvascache.js | 129 + public/src/js/canvasdraw.js | 1758 ++++++++++++ public/src/js/circle.js | 45 + public/src/js/controller.js | 296 ++ public/src/js/experience.js | 210 ++ public/src/js/game.js | 1009 +++++++ public/src/js/gameinput.js | 253 ++ public/src/js/gamepad.js | 153 ++ public/src/js/gamerules.js | 77 + public/src/js/keyboard.js | 124 + public/src/js/kiosk-main.js | 81 + public/src/js/lib/oggmented-wasm.js | 46 + public/src/js/lib/oggmented-wasm.wasm | Bin 0 -> 158512 bytes public/src/js/loader.js | 503 ++++ public/src/js/loadsong.js | 250 ++ public/src/js/mekadon.js | 121 + public/src/js/pageevents.js | 182 ++ public/src/js/parseosu.js | 381 +++ public/src/js/parsetja.js | 715 +++++ public/src/js/settings-lite.js | 44 + public/src/js/soundbuffer.js | 467 ++++ public/src/js/strings-lite.js | 53 + public/src/js/view.js | 2389 +++++++++++++++++ public/src/js/viewassets.js | 190 ++ public/src/views/experience.html | 24 + public/src/views/game.html | 15 + public/src/views/loader.html | 20 + public/src/views/loadsong.html | 12 + requirements.txt | 8 + setup.sh | 1168 ++++++++ templates/admin.html | 29 + templates/admin_experience.html | 132 + templates/admin_login.html | 31 + templates/index.html | 112 + tests/test_pageevents.js | 75 + update.sh | 73 + 200 files changed, 16098 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .gitignore create mode 100644 .trae/documents/Optimize Loading with Multi-Process Workers.md create mode 100644 .trae/documents/Remove Delete Option and Redirect Upload.md create mode 100644 Dockerfile create mode 100644 MONGODB_SAFETY.md create mode 100644 README.md create mode 100644 app.py create mode 100644 config.example.py create mode 100644 config.py create mode 100644 docker-compose.yml create mode 100644 gunicorn.conf.py create mode 100644 public/assets/audio/neiro_1_don.ogg create mode 100644 public/assets/audio/neiro_1_ka.ogg create mode 100644 public/assets/audio/se_balloon.ogg create mode 100644 public/assets/audio/se_calibration.ogg create mode 100644 public/assets/audio/se_cancel.ogg create mode 100644 public/assets/audio/se_don.ogg create mode 100644 public/assets/audio/se_gameclear.ogg create mode 100644 public/assets/audio/se_gamefail.ogg create mode 100644 public/assets/audio/se_gamefullcombo.ogg create mode 100644 public/assets/audio/se_jump.ogg create mode 100644 public/assets/audio/se_ka.ogg create mode 100644 public/assets/audio/se_pause.ogg create mode 100644 public/assets/audio/v_combo_100.ogg create mode 100644 public/assets/audio/v_combo_1000.ogg create mode 100644 public/assets/audio/v_combo_1100.ogg create mode 100644 public/assets/audio/v_combo_1200.ogg create mode 100644 public/assets/audio/v_combo_1300.ogg create mode 100644 public/assets/audio/v_combo_1400.ogg create mode 100644 public/assets/audio/v_combo_1500.ogg create mode 100644 public/assets/audio/v_combo_1600.ogg create mode 100644 public/assets/audio/v_combo_1700.ogg create mode 100644 public/assets/audio/v_combo_1800.ogg create mode 100644 public/assets/audio/v_combo_1900.ogg create mode 100644 public/assets/audio/v_combo_200.ogg create mode 100644 public/assets/audio/v_combo_2000.ogg create mode 100644 public/assets/audio/v_combo_2100.ogg create mode 100644 public/assets/audio/v_combo_2200.ogg create mode 100644 public/assets/audio/v_combo_2300.ogg create mode 100644 public/assets/audio/v_combo_2400.ogg create mode 100644 public/assets/audio/v_combo_2500.ogg create mode 100644 public/assets/audio/v_combo_2600.ogg create mode 100644 public/assets/audio/v_combo_2700.ogg create mode 100644 public/assets/audio/v_combo_2800.ogg create mode 100644 public/assets/audio/v_combo_2900.ogg create mode 100644 public/assets/audio/v_combo_300.ogg create mode 100644 public/assets/audio/v_combo_3000.ogg create mode 100644 public/assets/audio/v_combo_3100.ogg create mode 100644 public/assets/audio/v_combo_3200.ogg create mode 100644 public/assets/audio/v_combo_3300.ogg create mode 100644 public/assets/audio/v_combo_3400.ogg create mode 100644 public/assets/audio/v_combo_3500.ogg create mode 100644 public/assets/audio/v_combo_3600.ogg create mode 100644 public/assets/audio/v_combo_3700.ogg create mode 100644 public/assets/audio/v_combo_3800.ogg create mode 100644 public/assets/audio/v_combo_3900.ogg create mode 100644 public/assets/audio/v_combo_400.ogg create mode 100644 public/assets/audio/v_combo_4000.ogg create mode 100644 public/assets/audio/v_combo_4100.ogg create mode 100644 public/assets/audio/v_combo_4200.ogg create mode 100644 public/assets/audio/v_combo_4300.ogg create mode 100644 public/assets/audio/v_combo_4400.ogg create mode 100644 public/assets/audio/v_combo_4500.ogg create mode 100644 public/assets/audio/v_combo_4600.ogg create mode 100644 public/assets/audio/v_combo_4700.ogg create mode 100644 public/assets/audio/v_combo_4800.ogg create mode 100644 public/assets/audio/v_combo_4900.ogg create mode 100644 public/assets/audio/v_combo_50.ogg create mode 100644 public/assets/audio/v_combo_500.ogg create mode 100644 public/assets/audio/v_combo_5000.ogg create mode 100644 public/assets/audio/v_combo_600.ogg create mode 100644 public/assets/audio/v_combo_700.ogg create mode 100644 public/assets/audio/v_combo_800.ogg create mode 100644 public/assets/audio/v_combo_900.ogg create mode 100644 public/assets/audio/v_donder_fullcombo.ogg create mode 100644 public/assets/audio/v_fullcombo.ogg create mode 100644 public/assets/audio/v_renda.ogg create mode 100644 public/assets/audio/v_start.ogg create mode 100644 public/assets/fonts/Kozuka.otf create mode 100644 public/assets/fonts/TnT.ttf create mode 100644 public/assets/img/apple-touch-icon.png create mode 100644 public/assets/img/balloon.png create mode 100644 public/assets/img/bg_don_1a.png create mode 100644 public/assets/img/bg_don_1b.png create mode 100644 public/assets/img/bg_don_2a.png create mode 100644 public/assets/img/bg_don_2b.png create mode 100644 public/assets/img/bg_don_3a.png create mode 100644 public/assets/img/bg_don_3b.png create mode 100644 public/assets/img/bg_don_4a.png create mode 100644 public/assets/img/bg_don_4b.png create mode 100644 public/assets/img/bg_don_5a.png create mode 100644 public/assets/img/bg_don_5b.png create mode 100644 public/assets/img/bg_don_6a.png create mode 100644 public/assets/img/bg_don_6b.png create mode 100644 public/assets/img/bg_pause.png create mode 100644 public/assets/img/bg_score_p1.png create mode 100644 public/assets/img/bg_song_1a.png create mode 100644 public/assets/img/bg_song_1b.png create mode 100644 public/assets/img/bg_song_2a.png create mode 100644 public/assets/img/bg_song_2b.png create mode 100644 public/assets/img/bg_song_3a.png create mode 100644 public/assets/img/bg_song_3b.png create mode 100644 public/assets/img/bg_song_4a.png create mode 100644 public/assets/img/bg_song_4b.png create mode 100644 public/assets/img/bg_song_5a.png create mode 100644 public/assets/img/bg_song_5b.png create mode 100644 public/assets/img/bg_stage_1.png create mode 100644 public/assets/img/bg_stage_2.png create mode 100644 public/assets/img/bg_stage_3.png create mode 100644 public/assets/img/dancing-don.gif create mode 100644 public/assets/img/difficulty.png create mode 100644 public/assets/img/don_anim_10combo_a.png create mode 100644 public/assets/img/don_anim_10combo_b1.png create mode 100644 public/assets/img/don_anim_10combo_b2.png create mode 100644 public/assets/img/don_anim_clear_a.png create mode 100644 public/assets/img/don_anim_clear_b1.png create mode 100644 public/assets/img/don_anim_clear_b2.png create mode 100644 public/assets/img/don_anim_gogo_a.png create mode 100644 public/assets/img/don_anim_gogo_b1.png create mode 100644 public/assets/img/don_anim_gogo_b2.png create mode 100644 public/assets/img/don_anim_gogostart_a.png create mode 100644 public/assets/img/don_anim_gogostart_b1.png create mode 100644 public/assets/img/don_anim_gogostart_b2.png create mode 100644 public/assets/img/don_anim_normal_a.png create mode 100644 public/assets/img/don_anim_normal_b1.png create mode 100644 public/assets/img/don_anim_normal_b2.png create mode 100644 public/assets/img/favicon-16.png create mode 100644 public/assets/img/favicon-192.png create mode 100644 public/assets/img/favicon-32.png create mode 100644 public/assets/img/favicon-512.png create mode 100644 public/assets/img/favicon.ico create mode 100644 public/assets/img/favicon.png create mode 100644 public/assets/img/fire_anim.png create mode 100644 public/assets/img/fireworks_anim.png create mode 100644 public/assets/img/loader-stage.jpg create mode 100644 public/assets/img/mimizu.png create mode 100644 public/assets/img/notes.png create mode 100644 public/assets/img/notes_drumroll.png create mode 100644 public/assets/img/notes_explosion.png create mode 100644 public/assets/img/notes_hit.png create mode 100644 public/assets/img/roll_count_bubble.png create mode 100644 public/assets/img/taiko.png create mode 100644 public/assets/img/touch_drum.png create mode 100644 public/assets/img/touch_fullscreen.png create mode 100644 public/assets/img/touch_pause.png create mode 100644 public/assets/img/vectors.json create mode 100644 public/manifest.json create mode 100644 public/src/css/admin.css create mode 100644 public/src/css/experience.css create mode 100644 public/src/css/game.css create mode 100644 public/src/css/loader.css create mode 100644 public/src/css/loadsong.css create mode 100644 public/src/css/main.css create mode 100644 public/src/css/songbg.css create mode 100644 public/src/css/view.css create mode 100644 public/src/js/abstractfile.js create mode 100644 public/src/js/assets.js create mode 100644 public/src/js/autoscore.js create mode 100644 public/src/js/browsersupport.js create mode 100644 public/src/js/canvasasset.js create mode 100644 public/src/js/canvascache.js create mode 100644 public/src/js/canvasdraw.js create mode 100644 public/src/js/circle.js create mode 100644 public/src/js/controller.js create mode 100644 public/src/js/experience.js create mode 100644 public/src/js/game.js create mode 100644 public/src/js/gameinput.js create mode 100644 public/src/js/gamepad.js create mode 100644 public/src/js/gamerules.js create mode 100644 public/src/js/keyboard.js create mode 100644 public/src/js/kiosk-main.js create mode 100644 public/src/js/lib/oggmented-wasm.js create mode 100644 public/src/js/lib/oggmented-wasm.wasm create mode 100644 public/src/js/loader.js create mode 100644 public/src/js/loadsong.js create mode 100644 public/src/js/mekadon.js create mode 100644 public/src/js/pageevents.js create mode 100644 public/src/js/parseosu.js create mode 100644 public/src/js/parsetja.js create mode 100644 public/src/js/settings-lite.js create mode 100644 public/src/js/soundbuffer.js create mode 100644 public/src/js/strings-lite.js create mode 100644 public/src/js/view.js create mode 100644 public/src/js/viewassets.js create mode 100644 public/src/views/experience.html create mode 100644 public/src/views/game.html create mode 100644 public/src/views/loader.html create mode 100644 public/src/views/loadsong.html create mode 100644 requirements.txt create mode 100644 setup.sh create mode 100644 templates/admin.html create mode 100644 templates/admin_experience.html create mode 100644 templates/admin_login.html create mode 100644 templates/index.html create mode 100644 tests/test_pageevents.js create mode 100644 update.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..a30e3af --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,3 @@ +{ + "postCreateCommand": "" +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8f8a142 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +/.git +/__pycache__ +**/__pycache__ +/.venv +/venv +/env +/backups +/.taiko-secret-key +/flask_session +/public/songs +*.pyc +*.pyo +*.log +debug-*.png diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..bdb0cab --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..0b1ad1d --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,3 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b61db37 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +__pycache__/ +*.pyc +.DS_Store +.venv/ +.taiko-secret-key +flask_session/ +build/ +dist/ + +# build/version artifacts +version.json + +# large assets not meant for VCS +public/songs/ +public/songs/** +public/preview/ +*.log + +# local editor project artifacts +taiko-editor/.venv/ +taiko-editor/build/ +taiko-editor/dist/ +taiko-editor/__pycache__/ +taiko-editor/build_log.txt +taiko-editor/run_log.txt diff --git a/.trae/documents/Optimize Loading with Multi-Process Workers.md b/.trae/documents/Optimize Loading with Multi-Process Workers.md new file mode 100644 index 0000000..c1d42ec --- /dev/null +++ b/.trae/documents/Optimize Loading with Multi-Process Workers.md @@ -0,0 +1,20 @@ +I will optimize the loading process by implementing a **Multi-Threaded Worker Loader**. This involves creating a pool of Web Workers to fetch assets (JavaScript, Audio, Images, Views) in parallel, offloading the network initiation and handling from the main thread. + +### Plan: +1. **Create `public/src/js/loader-worker.js`**: + * This worker will handle `fetch` requests for different resource types (`text`, `blob`, `arraybuffer`). + * It will transfer the data back to the main thread (using zero-copy transfer for `ArrayBuffer`). + +2. **Modify `public/src/js/loader.js`**: + * **Initialize Worker Pool**: Create a pool of workers (defaulting to 4) in the `Loader` class. + * **Implement `workerFetch(url, type)`**: A method to distribute fetch tasks to the worker pool. + * **Override `ajax(url, ...)`**: Intercept requests for static assets (`src/`, `assets/`, etc.) and route them through `workerFetch`. Keep API calls (`api/`) on the main thread to ensure session stability. + * **Update `loadScript(url)`**: Change it to fetch the script content via `workerFetch` and inject it using a ` + + + + + + + + +
+
+
+
taiko.su
+
+
Loading
+
+
+
+ {% if version.version and version.commit_short and version.commit %} + vSU? ??.??.?? + {% else %} + vSU? ??.??.?? + {% endif %} +
+ + + + + + diff --git a/tests/test_pageevents.js b/tests/test_pageevents.js new file mode 100644 index 0000000..9925ed0 --- /dev/null +++ b/tests/test_pageevents.js @@ -0,0 +1,75 @@ +const assert = require("node:assert/strict") +const fs = require("node:fs") +const path = require("node:path") +const vm = require("node:vm") + +class EventTargetStub { + constructor() { + this.listeners = new Map() + } + + addEventListener(type, callback) { + if (!this.listeners.has(type)) this.listeners.set(type, new Set()) + this.listeners.get(type).add(callback) + } + + removeEventListener(type, callback) { + if (this.listeners.has(type)) this.listeners.get(type).delete(callback) + } + + dispatch(type, event) { + for (const callback of Array.from(this.listeners.get(type) || [])) callback(event) + } + + listenerCount(type) { + return this.listeners.has(type) ? this.listeners.get(type).size : 0 + } +} + +const root = path.resolve(__dirname, "..") +const source = fs.readFileSync(path.join(root, "public/src/js/pageevents.js"), "utf8") +const window = new EventTargetStub() +const context = vm.createContext({window, Map, Date}) +vm.runInContext(source + "; this.PageEvents = PageEvents", context) + +const pageEvents = new context.PageEvents() +let keyboardCalls = 0 +let firstOverlayCalls = 0 +let secondOverlayCalls = 0 + +pageEvents.keyAdd({}, "all", "both", () => keyboardCalls++) +assert.equal(window.listenerCount("keydown"), 1) + +pageEvents.add(window, "keydown", () => firstOverlayCalls++, "library-escape") +assert.equal(window.listenerCount("keydown"), 2, "a named overlay listener must not replace the global keyboard dispatcher") + +const keydown = { + key: "d", + keyCode: 68, + type: "keydown", + target: {tagName: "DIV"}, + ctrlKey: false, + preventDefault() {} +} +window.dispatch("keydown", keydown) +assert.equal(keyboardCalls, 1) +assert.equal(firstOverlayCalls, 1) + +pageEvents.add(window, "keydown", () => secondOverlayCalls++, "library-escape") +assert.equal(window.listenerCount("keydown"), 2, "replacing a named listener must not create duplicates") +window.dispatch("keydown", keydown) +assert.equal(keyboardCalls, 2) +assert.equal(firstOverlayCalls, 1) +assert.equal(secondOverlayCalls, 1) + +pageEvents.remove(window, "keydown", "library-escape") +assert.equal(window.listenerCount("keydown"), 1) +window.dispatch("keydown", keydown) +assert.equal(keyboardCalls, 3, "removing an overlay listener must leave keyboard input active") + +let keyupCalls = 0 +pageEvents.keyAdd({}, "all", "up", () => keyupCalls++) +window.dispatch("keyup", {...keydown, type: "keyup"}) +assert.equal(keyupCalls, 1) + +console.log("page event listener isolation ok") diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..2c8914e --- /dev/null +++ b/update.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +case "$0" in + */*) SCRIPT_PATH="$0" ;; + *) SCRIPT_PATH="./$0" ;; +esac + +SCRIPT_DIR=$(CDPATH= cd -- "${SCRIPT_PATH%/*}" && pwd) +INSTALL_DIR=${INSTALL_DIR:-/srv/taiko-web} +UPDATE_MODE=${TAIKO_WEB_UPDATE_MODE:-auto} + +if [ ! -r "$SCRIPT_DIR/setup.sh" ]; then + echo "Update source is incomplete: $SCRIPT_DIR/setup.sh is missing or unreadable." >&2 + exit 1 +fi + +detect_update_mode() { + if command -v docker >/dev/null 2>&1 && + docker ps --format '{{.Names}}' 2>/dev/null | grep -q '^taiko-web-app$'; then + echo container + return + fi + + if command -v systemctl >/dev/null 2>&1 && + systemctl is-active --quiet taiko-web 2>/dev/null; then + echo direct + return + fi + + if command -v docker >/dev/null 2>&1 && + docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q '^taiko-web-app$'; then + echo container + return + fi + + if command -v systemctl >/dev/null 2>&1 && + { systemctl is-enabled --quiet taiko-web 2>/dev/null || + [ -f /etc/systemd/system/taiko-web.service ]; }; then + echo direct + return + fi + + if command -v docker >/dev/null 2>&1 && [ -f "$INSTALL_DIR/docker-compose.yml" ]; then + echo container + return + fi + + # Preserve the historical behavior for installations that cannot be detected. + echo container +} + +case "$UPDATE_MODE" in + auto) UPDATE_MODE=$(detect_update_mode) ;; + container|direct) ;; + *) + echo "Invalid TAIKO_WEB_UPDATE_MODE: $UPDATE_MODE (expected auto, container, or direct)" + exit 2 + ;; +esac + +echo "[taiko-web] Detected update mode: $UPDATE_MODE" +UPDATE_ACTION="upgrade-$UPDATE_MODE" +if [ "${TAIKO_WEB_UPDATE_DRY_RUN:-0}" = "1" ]; then + printf '[taiko-web] Dry run: %s %s %s' "${BASH:-bash}" "$SCRIPT_DIR/setup.sh" "$UPDATE_ACTION" + if [ "$#" -gt 0 ]; then + printf ' %s' "$@" + fi + printf '\n' + exit 0 +fi + +exec "${BASH:-bash}" "$SCRIPT_DIR/setup.sh" "$UPDATE_ACTION" "$@"