From 108525534c28013cfe1897c30e4565f9893f3766 Mon Sep 17 00:00:00 2001 From: Minteck Date: Mon, 10 Oct 2022 20:51:39 +0200 Subject: Update --- .gitignore | 3 +- api/app-images.php | 2 +- api/cloudburst-banners.php | 8 +- api/cloudburst-data.php | 6 +- api/cloudburst-scored.php | 8 +- api/cloudburst.php | 2 +- api/data.php | 4 +- api/docs.php | 2 +- api/emergency-real.php | 2 +- api/emergency.php | 2 +- api/eval.php | 2 +- api/fronter.php | 6 +- api/me-picture.php | 5 +- api/me.php | 2 +- api/pleasure-real.php | 6 +- api/pleasure.php | 6 +- api/pluralkit-integration.php | 10 +- api/raindrops-banners.php | 8 +- api/raindrops-data.php | 6 +- api/raindrops-img.php | 2 +- api/raindrops-scored.php | 8 +- api/raindrops.php | 2 +- api/save-private.php | 8 +- api/save.php | 8 +- api/session.php | 2 +- api/token.php | 2 +- api/video.php | 2 +- api/wakeup-real.php | 6 +- api/wakeup.php | 6 +- app.php | 22 +- app/banner.js | 6 +- app/bits/assets/graph.js | 11 +- app/demo/index.php | 2 +- app/emergency/index.php | 4 +- app/fronters/ponies/auvwc.png | Bin 0 -> 6074 bytes app/fronters/ponies/bbrig.png | Bin 0 -> 5945 bytes app/fronters/ponies/ghrby.png | Bin 0 -> 6337 bytes app/fronters/ponies/mvaws.png | Bin 0 -> 7189 bytes app/fronters/ponies/rirgf.png | Bin 24981 -> 5480 bytes app/fronters/profiles/auvwc.png | Bin 0 -> 504733 bytes app/fronters/profiles/ckqsw.png | Bin 237290 -> 237290 bytes app/fronters/profiles/cmeyc.png | Bin 0 -> 1542918 bytes app/fronters/profiles/dogwu.png | Bin 0 -> 2055 bytes app/fronters/profiles/epvhq.png | Bin 0 -> 825561 bytes app/fronters/profiles/erefx.png | Bin 826530 -> 826530 bytes app/fronters/profiles/erknz.png | Bin 56915 -> 56915 bytes app/fronters/profiles/exidq.png | Bin 0 -> 45898 bytes app/fronters/profiles/ezqym.png | Bin 0 -> 184686 bytes app/fronters/profiles/famxl.png | Bin 0 -> 825561 bytes app/fronters/profiles/gevde.png | Bin 100880 -> 100880 bytes app/fronters/profiles/gfhsr.png | Bin 2283131 -> 2283131 bytes app/fronters/profiles/ghrby.png | Bin 0 -> 167497 bytes app/fronters/profiles/ghuln.png | Bin 370233 -> 370233 bytes app/fronters/profiles/hpwyq.png | Bin 2770 -> 2770 bytes app/fronters/profiles/irxyh.png | Bin 26543 -> 26543 bytes app/fronters/profiles/jhemc.png | Bin 0 -> 100880 bytes app/fronters/profiles/jnbae.png | Bin 60223 -> 60223 bytes app/fronters/profiles/khsbb.png | Bin 249236 -> 249236 bytes app/fronters/profiles/kkhbw.png | Bin 40300 -> 40300 bytes app/fronters/profiles/lllfw.png | Bin 745786 -> 745786 bytes app/fronters/profiles/lzlaq.png | Bin 26543 -> 26543 bytes app/fronters/profiles/mglyq.png | Bin 91476 -> 91476 bytes app/fronters/profiles/mhnqy.png | Bin 27452 -> 27452 bytes app/fronters/profiles/mvaws.png | Bin 0 -> 473421 bytes app/fronters/profiles/pabmo.png | Bin 124750 -> 124750 bytes app/fronters/profiles/ppukh.png | Bin 0 -> 2843 bytes app/fronters/profiles/qbzxm.png | Bin 2843 -> 2843 bytes app/fronters/profiles/qraku.png | Bin 45898 -> 45898 bytes app/fronters/profiles/qzbpf.png | Bin 0 -> 56915 bytes app/fronters/profiles/rdstg.png | Bin 16881 -> 16881 bytes app/fronters/profiles/rirgf.png | Bin 825561 -> 825561 bytes app/fronters/profiles/rpjok.png | Bin 1542918 -> 1542918 bytes app/fronters/profiles/sbxze.png | Bin 50554 -> 50554 bytes app/fronters/profiles/sehke.png | Bin 1947 -> 1947 bytes app/fronters/profiles/sjuao.png | Bin 0 -> 1045570 bytes app/fronters/profiles/souga.png | Bin 0 -> 45898 bytes app/fronters/profiles/tfbob.png | Bin 14049 -> 14049 bytes app/fronters/profiles/tmgiu.png | Bin 260760 -> 260760 bytes app/fronters/profiles/trefr.png | Bin 0 -> 1947 bytes app/fronters/profiles/vahcl.png | Bin 0 -> 45898 bytes app/fronters/profiles/vncoa.png | Bin 46475 -> 46475 bytes app/fronters/profiles/vvsxf.png | Bin 61010 -> 61010 bytes app/fronters/profiles/wjovt.png | Bin 0 -> 2097 bytes app/fronters/profiles/xbvwt.png | Bin 70342 -> 70342 bytes app/fronters/profiles/xcjhj.png | Bin 107053 -> 107053 bytes app/fronters/profiles/ynpba.png | Bin 0 -> 69145 bytes app/fronters/profiles/zajrk.png | Bin 2097 -> 2097 bytes app/fronters/profiles/zdtsg.png | Bin 3046 -> 3046 bytes app/fronters/profiles/zhtzs.png | Bin 673763 -> 673763 bytes app/fronters/profiles/ztfjz.png | Bin 184686 -> 184686 bytes app/fronters/profiles/zzise.png | Bin 69145 -> 69145 bytes app/fronters/script.js | 2 +- app/functions.js | 4 +- app/index.html | 4 +- app/load.js | 105 +-- app/planner/index.php | 14 +- app/sw.js | 29 +- assets/editor/chart.js | 13 + assets/icons/about.svg | 2 +- assets/icons/actions.svg | 2 +- assets/icons/add.svg | 2 +- assets/icons/admin.svg | 2 +- assets/icons/bitset.svg | 2 +- assets/icons/byfront.svg | 2 +- assets/icons/compare.svg | 2 +- assets/icons/complete.svg | 2 +- assets/icons/dashboard.svg | 2 +- assets/icons/debug.svg | 2 +- assets/icons/delete.svg | 2 +- assets/icons/disclaimers.svg | 2 +- assets/icons/docs.svg | 2 +- assets/icons/down.svg | 2 +- assets/icons/emergency.svg | 2 +- assets/icons/favicon/about.png | Bin 596940 -> 0 bytes assets/icons/favicon/actions.png | Bin 441293 -> 0 bytes assets/icons/favicon/add.png | Bin 591800 -> 0 bytes assets/icons/favicon/admin.png | Bin 656859 -> 0 bytes assets/icons/favicon/bitset.png | Bin 446413 -> 0 bytes assets/icons/favicon/byfront.png | Bin 614768 -> 0 bytes assets/icons/favicon/compare.png | Bin 526904 -> 0 bytes assets/icons/favicon/complete.png | Bin 938661 -> 0 bytes assets/icons/favicon/dashboard.png | Bin 411540 -> 0 bytes assets/icons/favicon/debug.png | Bin 537769 -> 0 bytes assets/icons/favicon/delete.png | Bin 428605 -> 0 bytes assets/icons/favicon/disclaimers.png | Bin 595791 -> 0 bytes assets/icons/favicon/docs.png | Bin 431810 -> 0 bytes assets/icons/favicon/down.png | Bin 472767 -> 0 bytes assets/icons/favicon/emergency.png | Bin 647174 -> 0 bytes assets/icons/favicon/form.png | Bin 434475 -> 0 bytes assets/icons/favicon/fronting.png | Bin 460693 -> 0 bytes assets/icons/favicon/global.png | Bin 518499 -> 0 bytes assets/icons/favicon/history.png | Bin 580502 -> 0 bytes assets/icons/favicon/home.png | Bin 488436 -> 0 bytes assets/icons/favicon/login.png | Bin 478948 -> 0 bytes assets/icons/favicon/logout.png | Bin 472253 -> 0 bytes assets/icons/favicon/nicknames.png | Bin 550708 -> 0 bytes assets/icons/favicon/none.png | Bin 743266 -> 0 bytes assets/icons/favicon/page.png | Bin 442099 -> 0 bytes assets/icons/favicon/parser.png | Bin 420554 -> 0 bytes assets/icons/favicon/partial.png | Bin 628940 -> 0 bytes assets/icons/favicon/pleasure-0.png | Bin 0 -> 15175 bytes assets/icons/favicon/pleasure-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/pleasure.png | Bin 570067 -> 0 bytes assets/icons/favicon/prefix-0.png | Bin 0 -> 9983 bytes assets/icons/favicon/prefix-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/prefix.png | Bin 502208 -> 0 bytes assets/icons/favicon/relations-0.png | Bin 0 -> 10301 bytes assets/icons/favicon/relations-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/relations.png | Bin 505476 -> 0 bytes assets/icons/favicon/right-0.png | Bin 0 -> 19284 bytes assets/icons/favicon/right-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/right.png | Bin 512397 -> 0 bytes assets/icons/favicon/rules-0.png | Bin 0 -> 19622 bytes assets/icons/favicon/rules-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/rules.png | Bin 567258 -> 0 bytes assets/icons/favicon/score-0.png | Bin 0 -> 12593 bytes assets/icons/favicon/score-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/score.png | Bin 514720 -> 0 bytes assets/icons/favicon/shield-0.png | Bin 0 -> 13275 bytes assets/icons/favicon/shield-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/shield.png | Bin 556026 -> 0 bytes assets/icons/favicon/species-0.png | Bin 0 -> 15267 bytes assets/icons/favicon/species-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/species.png | Bin 630114 -> 0 bytes assets/icons/favicon/splitting-0.png | Bin 0 -> 10267 bytes assets/icons/favicon/splitting-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/splitting.png | Bin 434475 -> 0 bytes assets/icons/favicon/stats-0.png | Bin 0 -> 8683 bytes assets/icons/favicon/stats-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/terminology-0.png | Bin 0 -> 9447 bytes assets/icons/favicon/terminology-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/terminology.png | Bin 434068 -> 0 bytes assets/icons/favicon/together-0.png | Bin 0 -> 10297 bytes assets/icons/favicon/together-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/together.png | Bin 442299 -> 0 bytes assets/icons/favicon/toys-0.png | Bin 0 -> 14074 bytes assets/icons/favicon/toys-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/toys.png | Bin 516116 -> 0 bytes assets/icons/favicon/travel-0.png | Bin 0 -> 15968 bytes assets/icons/favicon/travel-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/travel.png | Bin 640477 -> 0 bytes assets/icons/favicon/travelling-0.png | Bin 0 -> 22918 bytes assets/icons/favicon/travelling-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/travelling.png | Bin 640477 -> 0 bytes assets/icons/favicon/tree-0.png | Bin 0 -> 8627 bytes assets/icons/favicon/tree-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/tree.png | Bin 405267 -> 0 bytes assets/icons/favicon/up-0.png | Bin 0 -> 19368 bytes assets/icons/favicon/up-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/up.png | Bin 481492 -> 0 bytes assets/icons/favicon/user-0.png | Bin 0 -> 13806 bytes assets/icons/favicon/user-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/user.png | Bin 527532 -> 0 bytes assets/icons/favicon/visibility-depends-0.png | Bin 0 -> 16975 bytes assets/icons/favicon/visibility-depends-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/visibility-depends.png | Bin 510495 -> 0 bytes assets/icons/favicon/visibility-private-0.png | Bin 0 -> 15429 bytes assets/icons/favicon/visibility-private-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/visibility-private.png | Bin 491609 -> 0 bytes assets/icons/favicon/visibility-public-0.png | Bin 0 -> 13935 bytes assets/icons/favicon/visibility-public-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/visibility-public.png | Bin 518499 -> 0 bytes assets/icons/favicon/wakeup-0.png | Bin 0 -> 14847 bytes assets/icons/favicon/wakeup-1.png | Bin 0 -> 249141 bytes assets/icons/favicon/wakeup.png | Bin 809231 -> 0 bytes assets/icons/form.svg | 2 +- assets/icons/fronting.svg | 2 +- assets/icons/global.svg | 2 +- assets/icons/government.svg | 1 + assets/icons/history.svg | 2 +- assets/icons/home.svg | 2 +- assets/icons/icongen.js | 12 +- assets/icons/login.svg | 2 +- assets/icons/logout.svg | 2 +- assets/icons/nicknames.svg | 2 +- assets/icons/none.svg | 2 +- assets/icons/page.svg | 2 +- assets/icons/parser.svg | 2 +- assets/icons/partial.svg | 2 +- assets/icons/pleasure.svg | 2 +- assets/icons/prefix.svg | 2 +- assets/icons/relations.svg | 2 +- assets/icons/right.svg | 2 +- assets/icons/rules.svg | 2 +- assets/icons/score.svg | 2 +- assets/icons/shield.svg | 2 +- assets/icons/species.svg | 2 +- assets/icons/splitting.svg | 2 +- assets/icons/stats.svg | 1 + assets/icons/terminology.svg | 2 +- assets/icons/together.svg | 2 +- assets/icons/toys.svg | 2 +- assets/icons/travel.svg | 2 +- assets/icons/travelling.svg | 2 +- assets/icons/tree.svg | 2 +- assets/icons/uncolored/complete.svg | 1 + assets/icons/uncolored/emergency.svg | 1 + assets/icons/uncolored/none.svg | 1 + assets/icons/uncolored/partial.svg | 1 + assets/icons/uncolored/pleasure.svg | 1 + assets/icons/uncolored/wakeup.svg | 1 + assets/icons/up.svg | 2 +- assets/icons/user.svg | 2 +- assets/icons/visibility-depends.svg | 2 +- assets/icons/visibility-private.svg | 2 +- assets/icons/visibility-public.svg | 2 +- assets/icons/wakeup.svg | 2 +- assets/logo/newlogo-template.png | Bin 0 -> 24959 bytes assets/logo/newlogo.png | Bin 0 -> 3982 bytes assets/uploads/pt-applebloom.png | Bin 0 -> 6219 bytes assets/uploads/pt-izzy.png | Bin 6379 -> 0 bytes assets/uploads/pt-izzymoonbow.png | Bin 0 -> 6379 bytes assets/uploads/pt-mistybrightdawn.png | Bin 0 -> 6142 bytes assets/uploads/pt-scootaloo.png | Bin 4287 -> 4147 bytes assets/uploads/pt-thunder.png | Bin 0 -> 5214 bytes assets/uploads/pt-zoomzephyrwing.png | Bin 0 -> 4696 bytes autoschedule/main.php | 13 +- autoschedule/ponies.php | 6 +- includes/ai.inc | 311 +++++++ includes/ai.php | 311 ------- includes/assets.inc | 55 ++ includes/backup.inc | 102 +++ includes/backup.php | 102 --- includes/banner.inc | 456 ++++++++++ includes/banner.php | 456 ---------- includes/bitset.inc | 110 +++ includes/bitset.php | 110 --- includes/edit-private.inc | 147 ++++ includes/edit-private.php | 147 ---- includes/edit.inc | 147 ++++ includes/edit.php | 147 ---- includes/emergency.inc | 194 +++++ includes/emergency.php | 194 ----- includes/footer.inc | 36 + includes/footer.php | 35 - includes/functions.inc | 477 +++++++++++ includes/functions.php | 319 ------- includes/header.inc | 1001 ++++++++++++++++++++++ includes/header.php | 963 --------------------- includes/icons.inc | 5 + includes/init.inc | 28 + includes/init.php | 18 - includes/keywords.inc | 110 +++ includes/keywords.php | 110 --- includes/logo.inc | 97 +++ includes/member.inc | 268 ++++++ includes/member.php | 268 ------ includes/member/hierarchy.inc | 177 ++++ includes/member/hierarchy.php | 177 ---- includes/member/tree.inc | 8 + includes/member/tree.php | 8 - includes/pages.json | 116 ++- includes/planner.inc | 1025 ++++++++++++++++++++++ includes/planner.php | 926 -------------------- includes/pleasure.inc | 114 +++ includes/pleasure.php | 114 --- includes/pronouns.inc | 149 ++++ includes/pronouns.php | 149 ---- includes/rail.inc | 176 ++++ includes/rainbow.inc | 57 ++ includes/rainbow.php | 97 --- includes/random.inc | 15 + includes/random.php | 15 - includes/refresh.php | 144 +++- includes/restore.inc | 130 +++ includes/restore.php | 130 --- includes/score.inc | 86 ++ includes/score.php | 81 -- includes/search.inc | 529 ++++++++++++ includes/search.php | 529 ------------ includes/session.inc | 41 + includes/session.php | 41 - includes/short.inc | 52 ++ includes/short.php | 52 -- includes/subsysbanner.inc | 70 ++ includes/subsysbanner.php | 69 -- includes/subsysedit.inc | 143 ++++ includes/subsysedit.php | 143 ---- includes/sysbanner.inc | 132 +++ includes/sysbanner.php | 132 --- includes/sysedit.inc | 143 ++++ includes/sysedit.php | 143 ---- includes/system.inc | 19 + includes/system.php | 19 - includes/system/compare.inc | 189 +++++ includes/system/compare.php | 189 ----- includes/system/history.inc | 528 ++++++++++++ includes/system/history.php | 460 ---------- includes/system/species.inc | 70 ++ includes/system/species.php | 70 -- includes/system/subsystem.inc | 100 +++ includes/system/subsystem.php | 100 --- includes/system/tree.inc | 114 +++ includes/system/tree.php | 114 --- includes/travelling.inc | 47 + includes/travelling.php | 47 - includes/wakeup.inc | 114 +++ includes/wakeup.php | 114 --- pages/about.inc | 96 +++ pages/actions.inc | 1116 ++++++++++++++++++++++++ pages/actions.php | 1130 ------------------------- pages/alphabet.inc | 38 + pages/alphabet.php | 38 - pages/api.inc | 17 + pages/api.php | 17 - pages/app.inc | 3 + pages/app.php | 3 - pages/bitset.inc | 409 +++++++++ pages/bitset.php | 409 --------- pages/byfront.inc | 160 ++++ pages/byfront.php | 160 ---- pages/dashboard.inc | 231 +++++ pages/dashboard.php | 321 ------- pages/debug.inc | 115 +++ pages/debug.php | 96 --- pages/demo.inc | 129 +++ pages/demo.php | 131 --- pages/disclaimers.inc | 15 + pages/disclaimers.php | 15 - pages/docs.inc | 361 ++++++++ pages/docs.php | 361 -------- pages/edit-private.inc | 68 ++ pages/edit-private.php | 68 -- pages/edit.inc | 68 ++ pages/edit.php | 68 -- pages/emergency.inc | 15 + pages/emergency.php | 15 - pages/fronting.inc | 15 + pages/fronting.php | 15 - pages/government.inc | 142 ++++ pages/home.inc | 73 ++ pages/home.php | 67 -- pages/login.inc | 49 ++ pages/login.php | 43 - pages/logout.inc | 15 + pages/logout.php | 15 - pages/nicknames.inc | 115 +++ pages/nicknames.php | 115 --- pages/page.inc | 102 +++ pages/page.php | 102 --- pages/parser.inc | 255 ++++++ pages/parser.php | 255 ------ pages/pleasure.inc | 15 + pages/pleasure.php | 15 - pages/prefix.inc | 451 ++++++++++ pages/prefix.php | 449 ---------- pages/relations.inc | 105 +++ pages/relations.php | 105 --- pages/rules.inc | 253 ++++++ pages/rules.php | 253 ------ pages/score.inc | 208 +++++ pages/score.php | 208 ----- pages/splitting.inc | 55 ++ pages/splitting.php | 55 -- pages/stats.inc | 441 ++++++++++ pages/terminology.inc | 15 + pages/terminology.php | 15 - pages/together-dev.inc | 4 + pages/together-dev.php | 4 - pages/together.inc | 939 ++++++++++++++++++++ pages/together.php | 939 -------------------- pages/toys.inc | 902 ++++++++++++++++++++ pages/toys.php | 915 -------------------- pages/travelling.inc | 175 ++++ pages/travelling.php | 175 ---- pages/wakeup.inc | 15 + pages/wakeup.php | 15 - 407 files changed, 15445 insertions(+), 13950 deletions(-) create mode 100644 app/fronters/ponies/auvwc.png create mode 100644 app/fronters/ponies/bbrig.png create mode 100644 app/fronters/ponies/ghrby.png create mode 100644 app/fronters/ponies/mvaws.png create mode 100644 app/fronters/profiles/auvwc.png create mode 100644 app/fronters/profiles/cmeyc.png create mode 100644 app/fronters/profiles/dogwu.png create mode 100644 app/fronters/profiles/epvhq.png create mode 100644 app/fronters/profiles/exidq.png create mode 100644 app/fronters/profiles/ezqym.png create mode 100644 app/fronters/profiles/famxl.png create mode 100644 app/fronters/profiles/ghrby.png create mode 100644 app/fronters/profiles/jhemc.png create mode 100644 app/fronters/profiles/mvaws.png create mode 100644 app/fronters/profiles/ppukh.png create mode 100644 app/fronters/profiles/qzbpf.png create mode 100644 app/fronters/profiles/sjuao.png create mode 100644 app/fronters/profiles/souga.png create mode 100644 app/fronters/profiles/trefr.png create mode 100644 app/fronters/profiles/vahcl.png create mode 100644 app/fronters/profiles/wjovt.png create mode 100644 app/fronters/profiles/ynpba.png create mode 100644 assets/editor/chart.js delete mode 100644 assets/icons/favicon/about.png delete mode 100644 assets/icons/favicon/actions.png delete mode 100644 assets/icons/favicon/add.png delete mode 100644 assets/icons/favicon/admin.png delete mode 100644 assets/icons/favicon/bitset.png delete mode 100644 assets/icons/favicon/byfront.png delete mode 100644 assets/icons/favicon/compare.png delete mode 100644 assets/icons/favicon/complete.png delete mode 100644 assets/icons/favicon/dashboard.png delete mode 100644 assets/icons/favicon/debug.png delete mode 100644 assets/icons/favicon/delete.png delete mode 100644 assets/icons/favicon/disclaimers.png delete mode 100644 assets/icons/favicon/docs.png delete mode 100644 assets/icons/favicon/down.png delete mode 100644 assets/icons/favicon/emergency.png delete mode 100644 assets/icons/favicon/form.png delete mode 100644 assets/icons/favicon/fronting.png delete mode 100644 assets/icons/favicon/global.png delete mode 100644 assets/icons/favicon/history.png delete mode 100644 assets/icons/favicon/home.png delete mode 100644 assets/icons/favicon/login.png delete mode 100644 assets/icons/favicon/logout.png delete mode 100644 assets/icons/favicon/nicknames.png delete mode 100644 assets/icons/favicon/none.png delete mode 100644 assets/icons/favicon/page.png delete mode 100644 assets/icons/favicon/parser.png delete mode 100644 assets/icons/favicon/partial.png create mode 100644 assets/icons/favicon/pleasure-0.png create mode 100644 assets/icons/favicon/pleasure-1.png delete mode 100644 assets/icons/favicon/pleasure.png create mode 100644 assets/icons/favicon/prefix-0.png create mode 100644 assets/icons/favicon/prefix-1.png delete mode 100644 assets/icons/favicon/prefix.png create mode 100644 assets/icons/favicon/relations-0.png create mode 100644 assets/icons/favicon/relations-1.png delete mode 100644 assets/icons/favicon/relations.png create mode 100644 assets/icons/favicon/right-0.png create mode 100644 assets/icons/favicon/right-1.png delete mode 100644 assets/icons/favicon/right.png create mode 100644 assets/icons/favicon/rules-0.png create mode 100644 assets/icons/favicon/rules-1.png delete mode 100644 assets/icons/favicon/rules.png create mode 100644 assets/icons/favicon/score-0.png create mode 100644 assets/icons/favicon/score-1.png delete mode 100644 assets/icons/favicon/score.png create mode 100644 assets/icons/favicon/shield-0.png create mode 100644 assets/icons/favicon/shield-1.png delete mode 100644 assets/icons/favicon/shield.png create mode 100644 assets/icons/favicon/species-0.png create mode 100644 assets/icons/favicon/species-1.png delete mode 100644 assets/icons/favicon/species.png create mode 100644 assets/icons/favicon/splitting-0.png create mode 100644 assets/icons/favicon/splitting-1.png delete mode 100644 assets/icons/favicon/splitting.png create mode 100644 assets/icons/favicon/stats-0.png create mode 100644 assets/icons/favicon/stats-1.png create mode 100644 assets/icons/favicon/terminology-0.png create mode 100644 assets/icons/favicon/terminology-1.png delete mode 100644 assets/icons/favicon/terminology.png create mode 100644 assets/icons/favicon/together-0.png create mode 100644 assets/icons/favicon/together-1.png delete mode 100644 assets/icons/favicon/together.png create mode 100644 assets/icons/favicon/toys-0.png create mode 100644 assets/icons/favicon/toys-1.png delete mode 100644 assets/icons/favicon/toys.png create mode 100644 assets/icons/favicon/travel-0.png create mode 100644 assets/icons/favicon/travel-1.png delete mode 100644 assets/icons/favicon/travel.png create mode 100644 assets/icons/favicon/travelling-0.png create mode 100644 assets/icons/favicon/travelling-1.png delete mode 100644 assets/icons/favicon/travelling.png create mode 100644 assets/icons/favicon/tree-0.png create mode 100644 assets/icons/favicon/tree-1.png delete mode 100644 assets/icons/favicon/tree.png create mode 100644 assets/icons/favicon/up-0.png create mode 100644 assets/icons/favicon/up-1.png delete mode 100644 assets/icons/favicon/up.png create mode 100644 assets/icons/favicon/user-0.png create mode 100644 assets/icons/favicon/user-1.png delete mode 100644 assets/icons/favicon/user.png create mode 100644 assets/icons/favicon/visibility-depends-0.png create mode 100644 assets/icons/favicon/visibility-depends-1.png delete mode 100644 assets/icons/favicon/visibility-depends.png create mode 100644 assets/icons/favicon/visibility-private-0.png create mode 100644 assets/icons/favicon/visibility-private-1.png delete mode 100644 assets/icons/favicon/visibility-private.png create mode 100644 assets/icons/favicon/visibility-public-0.png create mode 100644 assets/icons/favicon/visibility-public-1.png delete mode 100644 assets/icons/favicon/visibility-public.png create mode 100644 assets/icons/favicon/wakeup-0.png create mode 100644 assets/icons/favicon/wakeup-1.png delete mode 100644 assets/icons/favicon/wakeup.png create mode 100644 assets/icons/government.svg create mode 100644 assets/icons/stats.svg create mode 100644 assets/icons/uncolored/complete.svg create mode 100644 assets/icons/uncolored/emergency.svg create mode 100644 assets/icons/uncolored/none.svg create mode 100644 assets/icons/uncolored/partial.svg create mode 100644 assets/icons/uncolored/pleasure.svg create mode 100644 assets/icons/uncolored/wakeup.svg create mode 100644 assets/logo/newlogo-template.png create mode 100644 assets/logo/newlogo.png create mode 100644 assets/uploads/pt-applebloom.png delete mode 100644 assets/uploads/pt-izzy.png create mode 100644 assets/uploads/pt-izzymoonbow.png create mode 100644 assets/uploads/pt-mistybrightdawn.png create mode 100644 assets/uploads/pt-thunder.png create mode 100644 assets/uploads/pt-zoomzephyrwing.png create mode 100644 includes/ai.inc delete mode 100644 includes/ai.php create mode 100644 includes/assets.inc create mode 100644 includes/backup.inc delete mode 100644 includes/backup.php create mode 100644 includes/banner.inc delete mode 100644 includes/banner.php create mode 100644 includes/bitset.inc delete mode 100644 includes/bitset.php create mode 100644 includes/edit-private.inc delete mode 100644 includes/edit-private.php create mode 100644 includes/edit.inc delete mode 100644 includes/edit.php create mode 100644 includes/emergency.inc delete mode 100644 includes/emergency.php create mode 100644 includes/footer.inc delete mode 100644 includes/footer.php create mode 100644 includes/functions.inc delete mode 100644 includes/functions.php create mode 100644 includes/header.inc delete mode 100644 includes/header.php create mode 100644 includes/icons.inc create mode 100644 includes/init.inc delete mode 100644 includes/init.php create mode 100644 includes/keywords.inc delete mode 100644 includes/keywords.php create mode 100644 includes/logo.inc create mode 100644 includes/member.inc delete mode 100644 includes/member.php create mode 100644 includes/member/hierarchy.inc delete mode 100644 includes/member/hierarchy.php create mode 100644 includes/member/tree.inc delete mode 100644 includes/member/tree.php create mode 100644 includes/planner.inc delete mode 100644 includes/planner.php create mode 100644 includes/pleasure.inc delete mode 100644 includes/pleasure.php create mode 100644 includes/pronouns.inc delete mode 100644 includes/pronouns.php create mode 100644 includes/rail.inc create mode 100644 includes/rainbow.inc delete mode 100644 includes/rainbow.php create mode 100644 includes/random.inc delete mode 100644 includes/random.php create mode 100644 includes/restore.inc delete mode 100644 includes/restore.php create mode 100644 includes/score.inc delete mode 100644 includes/score.php create mode 100644 includes/search.inc delete mode 100644 includes/search.php create mode 100644 includes/session.inc delete mode 100644 includes/session.php create mode 100644 includes/short.inc delete mode 100644 includes/short.php create mode 100644 includes/subsysbanner.inc delete mode 100644 includes/subsysbanner.php create mode 100644 includes/subsysedit.inc delete mode 100644 includes/subsysedit.php create mode 100644 includes/sysbanner.inc delete mode 100644 includes/sysbanner.php create mode 100644 includes/sysedit.inc delete mode 100644 includes/sysedit.php create mode 100644 includes/system.inc delete mode 100644 includes/system.php create mode 100644 includes/system/compare.inc delete mode 100644 includes/system/compare.php create mode 100644 includes/system/history.inc delete mode 100644 includes/system/history.php create mode 100644 includes/system/species.inc delete mode 100644 includes/system/species.php create mode 100644 includes/system/subsystem.inc delete mode 100644 includes/system/subsystem.php create mode 100644 includes/system/tree.inc delete mode 100644 includes/system/tree.php create mode 100644 includes/travelling.inc delete mode 100644 includes/travelling.php create mode 100644 includes/wakeup.inc delete mode 100644 includes/wakeup.php create mode 100644 pages/about.inc create mode 100644 pages/actions.inc delete mode 100644 pages/actions.php create mode 100644 pages/alphabet.inc delete mode 100644 pages/alphabet.php create mode 100644 pages/api.inc delete mode 100644 pages/api.php create mode 100644 pages/app.inc delete mode 100644 pages/app.php create mode 100644 pages/bitset.inc delete mode 100644 pages/bitset.php create mode 100644 pages/byfront.inc delete mode 100644 pages/byfront.php create mode 100644 pages/dashboard.inc delete mode 100644 pages/dashboard.php create mode 100644 pages/debug.inc delete mode 100644 pages/debug.php create mode 100644 pages/demo.inc delete mode 100644 pages/demo.php create mode 100644 pages/disclaimers.inc delete mode 100644 pages/disclaimers.php create mode 100644 pages/docs.inc delete mode 100644 pages/docs.php create mode 100644 pages/edit-private.inc delete mode 100644 pages/edit-private.php create mode 100644 pages/edit.inc delete mode 100644 pages/edit.php create mode 100644 pages/emergency.inc delete mode 100644 pages/emergency.php create mode 100644 pages/fronting.inc delete mode 100644 pages/fronting.php create mode 100644 pages/government.inc create mode 100644 pages/home.inc delete mode 100644 pages/home.php create mode 100644 pages/login.inc delete mode 100644 pages/login.php create mode 100644 pages/logout.inc delete mode 100644 pages/logout.php create mode 100644 pages/nicknames.inc delete mode 100644 pages/nicknames.php create mode 100644 pages/page.inc delete mode 100644 pages/page.php create mode 100644 pages/parser.inc delete mode 100644 pages/parser.php create mode 100644 pages/pleasure.inc delete mode 100644 pages/pleasure.php create mode 100644 pages/prefix.inc delete mode 100644 pages/prefix.php create mode 100644 pages/relations.inc delete mode 100644 pages/relations.php create mode 100644 pages/rules.inc delete mode 100644 pages/rules.php create mode 100644 pages/score.inc delete mode 100644 pages/score.php create mode 100644 pages/splitting.inc delete mode 100644 pages/splitting.php create mode 100644 pages/stats.inc create mode 100644 pages/terminology.inc delete mode 100644 pages/terminology.php create mode 100644 pages/together-dev.inc delete mode 100644 pages/together-dev.php create mode 100644 pages/together.inc delete mode 100644 pages/together.php create mode 100644 pages/toys.inc delete mode 100644 pages/toys.php create mode 100644 pages/travelling.inc delete mode 100644 pages/travelling.php create mode 100644 pages/wakeup.inc delete mode 100644 pages/wakeup.php diff --git a/.gitignore b/.gitignore index a90dd41..1dadcd7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ includes/app.json includes/tokens together/build assets/editor/thing.mp4 -includes/_restore \ No newline at end of file +includes/_restore +includes/data.new \ No newline at end of file diff --git a/api/app-images.php b/api/app-images.php index 76b11a0..dea66cb 100644 --- a/api/app-images.php +++ b/api/app-images.php @@ -1,6 +1,6 @@ ${french ? (data['relations']['marefriends'].length > 1 ? 'Partenaires ' : 'Partenaire ') : `Marefriend${data['relations']['marefriends'].length > 1 ? 's' : ''}`}: ${data['relations']['marefriends'].length > 1 ? '
' : ''} ${data['relations']['marefriends'].map(relation => ` - `).join(``)} + `).join(``)} ${data['relations']['marefriends'].length === 0 ? '-' : ''} ${french ? (data['relations']['sisters'].length > 1 ? 'Sœurs ' : 'Sœur ') : `Sister${data['relations']['sisters'].length > 1 ? 's' : ''}`}: ${data['relations']['sisters'].length > 1 ? '
' : ''} ${data['relations']['sisters'].map(relation => ` - `).join(``)} + `).join(``)} ${data['relations']['sisters'].length === 0 ? '-' : ''}
${data['little'] ? ` ${french ? (data['relations']['sisters'].length > 1 ? 'Caretakers ' : 'Caretaker ') : `Caretaker${data['relations']['caretakers'].length > 1 ? 's' : ''}`}: ${data['relations']['caretakers'].length > 1 ? '
' : ''} ${data['relations']['caretakers'].map(relation => ` - `).join(``)} + `).join(``)} ${data['relations']['caretakers'].length === 0 ? '-' : ''}
` : ''} diff --git a/app/bits/assets/graph.js b/app/bits/assets/graph.js index 908c2e9..0503b99 100755 --- a/app/bits/assets/graph.js +++ b/app/bits/assets/graph.js @@ -25,14 +25,9 @@ const graph = new Chart(ctx, { } }, scaleLabel: "<%=value%>%", - legend: { - display: false - }, - tooltips: { - callbacks: { - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + '€'; - } + plugins: { + legend: { + display: false } } } diff --git a/app/demo/index.php b/app/demo/index.php index 154f099..cd54738 100644 --- a/app/demo/index.php +++ b/app/demo/index.php @@ -1,3 +1,3 @@ + @@ -26,7 +26,7 @@

- +
\ No newline at end of file diff --git a/app/fronters/ponies/auvwc.png b/app/fronters/ponies/auvwc.png new file mode 100644 index 0000000..c87a4f8 Binary files /dev/null and b/app/fronters/ponies/auvwc.png differ diff --git a/app/fronters/ponies/bbrig.png b/app/fronters/ponies/bbrig.png new file mode 100644 index 0000000..c5e2e3c Binary files /dev/null and b/app/fronters/ponies/bbrig.png differ diff --git a/app/fronters/ponies/ghrby.png b/app/fronters/ponies/ghrby.png new file mode 100644 index 0000000..f7fe2f8 Binary files /dev/null and b/app/fronters/ponies/ghrby.png differ diff --git a/app/fronters/ponies/mvaws.png b/app/fronters/ponies/mvaws.png new file mode 100644 index 0000000..5f51abe Binary files /dev/null and b/app/fronters/ponies/mvaws.png differ diff --git a/app/fronters/ponies/rirgf.png b/app/fronters/ponies/rirgf.png index 9f4096c..315321f 100644 Binary files a/app/fronters/ponies/rirgf.png and b/app/fronters/ponies/rirgf.png differ diff --git a/app/fronters/profiles/auvwc.png b/app/fronters/profiles/auvwc.png new file mode 100644 index 0000000..824a20f Binary files /dev/null and b/app/fronters/profiles/auvwc.png differ diff --git a/app/fronters/profiles/ckqsw.png b/app/fronters/profiles/ckqsw.png index aa8b705..c12493f 100644 Binary files a/app/fronters/profiles/ckqsw.png and b/app/fronters/profiles/ckqsw.png differ diff --git a/app/fronters/profiles/cmeyc.png b/app/fronters/profiles/cmeyc.png new file mode 100644 index 0000000..b13c2b1 Binary files /dev/null and b/app/fronters/profiles/cmeyc.png differ diff --git a/app/fronters/profiles/dogwu.png b/app/fronters/profiles/dogwu.png new file mode 100644 index 0000000..4404e65 Binary files /dev/null and b/app/fronters/profiles/dogwu.png differ diff --git a/app/fronters/profiles/epvhq.png b/app/fronters/profiles/epvhq.png new file mode 100644 index 0000000..30b1160 Binary files /dev/null and b/app/fronters/profiles/epvhq.png differ diff --git a/app/fronters/profiles/erefx.png b/app/fronters/profiles/erefx.png index e5175fb..afdef5c 100644 Binary files a/app/fronters/profiles/erefx.png and b/app/fronters/profiles/erefx.png differ diff --git a/app/fronters/profiles/erknz.png b/app/fronters/profiles/erknz.png index 4d1f0dd..2fbea15 100644 Binary files a/app/fronters/profiles/erknz.png and b/app/fronters/profiles/erknz.png differ diff --git a/app/fronters/profiles/exidq.png b/app/fronters/profiles/exidq.png new file mode 100644 index 0000000..9b72e5a Binary files /dev/null and b/app/fronters/profiles/exidq.png differ diff --git a/app/fronters/profiles/ezqym.png b/app/fronters/profiles/ezqym.png new file mode 100644 index 0000000..36d34f6 Binary files /dev/null and b/app/fronters/profiles/ezqym.png differ diff --git a/app/fronters/profiles/famxl.png b/app/fronters/profiles/famxl.png new file mode 100644 index 0000000..9a28b13 Binary files /dev/null and b/app/fronters/profiles/famxl.png differ diff --git a/app/fronters/profiles/gevde.png b/app/fronters/profiles/gevde.png index f08887d..b000840 100644 Binary files a/app/fronters/profiles/gevde.png and b/app/fronters/profiles/gevde.png differ diff --git a/app/fronters/profiles/gfhsr.png b/app/fronters/profiles/gfhsr.png index 1d12f37..72f5a89 100644 Binary files a/app/fronters/profiles/gfhsr.png and b/app/fronters/profiles/gfhsr.png differ diff --git a/app/fronters/profiles/ghrby.png b/app/fronters/profiles/ghrby.png new file mode 100644 index 0000000..c0d75f8 Binary files /dev/null and b/app/fronters/profiles/ghrby.png differ diff --git a/app/fronters/profiles/ghuln.png b/app/fronters/profiles/ghuln.png index d975de1..3856e60 100644 Binary files a/app/fronters/profiles/ghuln.png and b/app/fronters/profiles/ghuln.png differ diff --git a/app/fronters/profiles/hpwyq.png b/app/fronters/profiles/hpwyq.png index 6014172..447f028 100644 Binary files a/app/fronters/profiles/hpwyq.png and b/app/fronters/profiles/hpwyq.png differ diff --git a/app/fronters/profiles/irxyh.png b/app/fronters/profiles/irxyh.png index ff9b84a..652a951 100644 Binary files a/app/fronters/profiles/irxyh.png and b/app/fronters/profiles/irxyh.png differ diff --git a/app/fronters/profiles/jhemc.png b/app/fronters/profiles/jhemc.png new file mode 100644 index 0000000..4c71982 Binary files /dev/null and b/app/fronters/profiles/jhemc.png differ diff --git a/app/fronters/profiles/jnbae.png b/app/fronters/profiles/jnbae.png index 67a3cc6..0a9d069 100644 Binary files a/app/fronters/profiles/jnbae.png and b/app/fronters/profiles/jnbae.png differ diff --git a/app/fronters/profiles/khsbb.png b/app/fronters/profiles/khsbb.png index 4a19d1d..27a85bd 100644 Binary files a/app/fronters/profiles/khsbb.png and b/app/fronters/profiles/khsbb.png differ diff --git a/app/fronters/profiles/kkhbw.png b/app/fronters/profiles/kkhbw.png index db09107..62ff738 100644 Binary files a/app/fronters/profiles/kkhbw.png and b/app/fronters/profiles/kkhbw.png differ diff --git a/app/fronters/profiles/lllfw.png b/app/fronters/profiles/lllfw.png index 922ae6f..c09cfc1 100644 Binary files a/app/fronters/profiles/lllfw.png and b/app/fronters/profiles/lllfw.png differ diff --git a/app/fronters/profiles/lzlaq.png b/app/fronters/profiles/lzlaq.png index 19890f3..3341acf 100644 Binary files a/app/fronters/profiles/lzlaq.png and b/app/fronters/profiles/lzlaq.png differ diff --git a/app/fronters/profiles/mglyq.png b/app/fronters/profiles/mglyq.png index 2350ce9..9258fb2 100644 Binary files a/app/fronters/profiles/mglyq.png and b/app/fronters/profiles/mglyq.png differ diff --git a/app/fronters/profiles/mhnqy.png b/app/fronters/profiles/mhnqy.png index bbc296e..fdd5963 100644 Binary files a/app/fronters/profiles/mhnqy.png and b/app/fronters/profiles/mhnqy.png differ diff --git a/app/fronters/profiles/mvaws.png b/app/fronters/profiles/mvaws.png new file mode 100644 index 0000000..6a2cc05 Binary files /dev/null and b/app/fronters/profiles/mvaws.png differ diff --git a/app/fronters/profiles/pabmo.png b/app/fronters/profiles/pabmo.png index 855989d..5bda618 100644 Binary files a/app/fronters/profiles/pabmo.png and b/app/fronters/profiles/pabmo.png differ diff --git a/app/fronters/profiles/ppukh.png b/app/fronters/profiles/ppukh.png new file mode 100644 index 0000000..a0f10cd Binary files /dev/null and b/app/fronters/profiles/ppukh.png differ diff --git a/app/fronters/profiles/qbzxm.png b/app/fronters/profiles/qbzxm.png index 59cfdaf..21fd437 100644 Binary files a/app/fronters/profiles/qbzxm.png and b/app/fronters/profiles/qbzxm.png differ diff --git a/app/fronters/profiles/qraku.png b/app/fronters/profiles/qraku.png index 0935261..67fb221 100644 Binary files a/app/fronters/profiles/qraku.png and b/app/fronters/profiles/qraku.png differ diff --git a/app/fronters/profiles/qzbpf.png b/app/fronters/profiles/qzbpf.png new file mode 100644 index 0000000..904b914 Binary files /dev/null and b/app/fronters/profiles/qzbpf.png differ diff --git a/app/fronters/profiles/rdstg.png b/app/fronters/profiles/rdstg.png index 3a28375..ac28034 100644 Binary files a/app/fronters/profiles/rdstg.png and b/app/fronters/profiles/rdstg.png differ diff --git a/app/fronters/profiles/rirgf.png b/app/fronters/profiles/rirgf.png index 3fdf039..428032d 100644 Binary files a/app/fronters/profiles/rirgf.png and b/app/fronters/profiles/rirgf.png differ diff --git a/app/fronters/profiles/rpjok.png b/app/fronters/profiles/rpjok.png index 1475d47..283cd2a 100644 Binary files a/app/fronters/profiles/rpjok.png and b/app/fronters/profiles/rpjok.png differ diff --git a/app/fronters/profiles/sbxze.png b/app/fronters/profiles/sbxze.png index 4390c22..f70ee90 100644 Binary files a/app/fronters/profiles/sbxze.png and b/app/fronters/profiles/sbxze.png differ diff --git a/app/fronters/profiles/sehke.png b/app/fronters/profiles/sehke.png index efcdf4a..ef93187 100644 Binary files a/app/fronters/profiles/sehke.png and b/app/fronters/profiles/sehke.png differ diff --git a/app/fronters/profiles/sjuao.png b/app/fronters/profiles/sjuao.png new file mode 100644 index 0000000..16a4dd5 Binary files /dev/null and b/app/fronters/profiles/sjuao.png differ diff --git a/app/fronters/profiles/souga.png b/app/fronters/profiles/souga.png new file mode 100644 index 0000000..fdde626 Binary files /dev/null and b/app/fronters/profiles/souga.png differ diff --git a/app/fronters/profiles/tfbob.png b/app/fronters/profiles/tfbob.png index a63b6e3..edf68db 100644 Binary files a/app/fronters/profiles/tfbob.png and b/app/fronters/profiles/tfbob.png differ diff --git a/app/fronters/profiles/tmgiu.png b/app/fronters/profiles/tmgiu.png index acaf6f3..bb45dc3 100644 Binary files a/app/fronters/profiles/tmgiu.png and b/app/fronters/profiles/tmgiu.png differ diff --git a/app/fronters/profiles/trefr.png b/app/fronters/profiles/trefr.png new file mode 100644 index 0000000..fec4dc3 Binary files /dev/null and b/app/fronters/profiles/trefr.png differ diff --git a/app/fronters/profiles/vahcl.png b/app/fronters/profiles/vahcl.png new file mode 100644 index 0000000..aeb7ba9 Binary files /dev/null and b/app/fronters/profiles/vahcl.png differ diff --git a/app/fronters/profiles/vncoa.png b/app/fronters/profiles/vncoa.png index ac1596f..e49a38f 100644 Binary files a/app/fronters/profiles/vncoa.png and b/app/fronters/profiles/vncoa.png differ diff --git a/app/fronters/profiles/vvsxf.png b/app/fronters/profiles/vvsxf.png index df4566d..009b060 100644 Binary files a/app/fronters/profiles/vvsxf.png and b/app/fronters/profiles/vvsxf.png differ diff --git a/app/fronters/profiles/wjovt.png b/app/fronters/profiles/wjovt.png new file mode 100644 index 0000000..8d40347 Binary files /dev/null and b/app/fronters/profiles/wjovt.png differ diff --git a/app/fronters/profiles/xbvwt.png b/app/fronters/profiles/xbvwt.png index 2b94fa8..2d76e48 100644 Binary files a/app/fronters/profiles/xbvwt.png and b/app/fronters/profiles/xbvwt.png differ diff --git a/app/fronters/profiles/xcjhj.png b/app/fronters/profiles/xcjhj.png index 02a635f..31ca4b9 100644 Binary files a/app/fronters/profiles/xcjhj.png and b/app/fronters/profiles/xcjhj.png differ diff --git a/app/fronters/profiles/ynpba.png b/app/fronters/profiles/ynpba.png new file mode 100644 index 0000000..61e9a74 Binary files /dev/null and b/app/fronters/profiles/ynpba.png differ diff --git a/app/fronters/profiles/zajrk.png b/app/fronters/profiles/zajrk.png index ebfc4d8..3f960fb 100644 Binary files a/app/fronters/profiles/zajrk.png and b/app/fronters/profiles/zajrk.png differ diff --git a/app/fronters/profiles/zdtsg.png b/app/fronters/profiles/zdtsg.png index 1c1704d..e3aff68 100644 Binary files a/app/fronters/profiles/zdtsg.png and b/app/fronters/profiles/zdtsg.png differ diff --git a/app/fronters/profiles/zhtzs.png b/app/fronters/profiles/zhtzs.png index 2af80d2..b802367 100644 Binary files a/app/fronters/profiles/zhtzs.png and b/app/fronters/profiles/zhtzs.png differ diff --git a/app/fronters/profiles/ztfjz.png b/app/fronters/profiles/ztfjz.png index cb81f5f..e604ed1 100644 Binary files a/app/fronters/profiles/ztfjz.png and b/app/fronters/profiles/ztfjz.png differ diff --git a/app/fronters/profiles/zzise.png b/app/fronters/profiles/zzise.png index d200bdf..d767964 100644 Binary files a/app/fronters/profiles/zzise.png and b/app/fronters/profiles/zzise.png differ diff --git a/app/fronters/script.js b/app/fronters/script.js index 6450bba..4e51b22 100755 --- a/app/fronters/script.js +++ b/app/fronters/script.js @@ -1,7 +1,7 @@ function getMiniName(name) { let parts = name.split(" "); - if (parts[0].length > 3 && !parts[0].endsWith("e") && parts[0] !== "Filly" && parts[0] !== "Windy") { + if (parts[0].length > 3 && !parts[0].endsWith("e") && parts[0] !== "Filly" && parts[0] !== "Windy" && parts[1] !== "Brightdawn") { if (parts[0].includes("/")) { return parts[0].split("/")[0]; } else { diff --git a/app/functions.js b/app/functions.js index 207bc42..4d89e30 100644 --- a/app/functions.js +++ b/app/functions.js @@ -1,9 +1,9 @@ -// Function ported from /includes/header.php (line 18) +// Function ported from /includes/header.inc (line 18) // Ported function has matched behavior. function getMiniName(name) { let parts = name.split(" "); - if (parts[0].length > 3 && !parts[0].endsWith("e") && parts[0] !== "Filly" && parts[0] !== "Windy") { + if (parts[0].length > 3 && !parts[0].endsWith("e") && parts[0] !== "Filly" && parts[0] !== "Windy" && parts[1] !== "Brightdawn") { if (parts[0].includes("/")) { return parts[0].split("/")[0]; } else { diff --git a/app/index.html b/app/index.html index 22ee9a9..e8fd5a0 100644 --- a/app/index.html +++ b/app/index.html @@ -291,7 +291,7 @@


-

 Greetings Name!

+

 Greetings Name!


@@ -313,7 +313,7 @@
-

In the other system: Some member

+

In the other system: Some member

diff --git a/app/load.js b/app/load.js index 1be0b57..97b030a 100644 --- a/app/load.js +++ b/app/load.js @@ -17,32 +17,32 @@ window.connected = false; let valuesToGet = { "pluralkit-cloudburst-members": { - url: "/api/data?f=ynmuc-members.json", + url: "/api/data?f=ynmuc/members.json", limited: false, name: "Members at Cloudburst...", }, "pluralkit-cloudburst-fronters": { - url: "/api/data?f=ynmuc-fronters.json", + url: "/api/data?f=ynmuc/fronters.json", limited: false, name: "Fronters at Cloudburst...", }, "pluralkit-cloudburst-switches": { - url: "/api/data?f=ynmuc-switches.json", + url: "/api/data?f=ynmuc/switches.json", limited: false, name: "Switches at Cloudburst...", }, "pluralkit-raindrops-members": { - url: "/api/data?f=gdapd-members.json", + url: "/api/data?f=gdapd/members.json", limited: false, name: "Members at Raindrops...", }, "pluralkit-raindrops-fronters": { - url: "/api/data?f=gdapd-fronters.json", + url: "/api/data?f=gdapd/fronters.json", limited: false, name: "Fronters at Raindrops...", }, "pluralkit-raindrops-switches": { - url: "/api/data?f=gdapd-switches.json", + url: "/api/data?f=gdapd/switches.json", limited: false, name: "Switches at Raindrops...", }, @@ -243,55 +243,64 @@ async function postLoad() { try { let member = window.currentFronter; await (await window.fetch("/bits/Application/SetCurrentIdentity/index.php?Name=" + btoa(member['display_name'] ?? member['name']).replaceAll("+", "-").replaceAll("/", "_") + "&Picture=" + btoa(member['avatar_url'] ?? "./assets/default.png").replaceAll("+", "-").replaceAll("/", "_"))).text(); - } catch (e) {} + } catch (e) { + try { + await (await window.fetch("/bits/Application/SetCurrentIdentity/index.php?Name=" + btoa(window.data['pluralkit-' + window.data['identity'].id + '-members'].filter(i => i.name === "unknown")[0]['display_name']).replaceAll("+", "-").replaceAll("/", "_") + "&Picture=" + btoa(window.data['pluralkit-' + window.data['identity'].id + '-members'].filter(i => i.name === "unknown")[0]['avatar_url']).replaceAll("+", "-").replaceAll("/", "_"))).text(); + } catch (e) {} + } - document.getElementById("home-name").innerText = getMiniName(window.currentFronter['display_name'] ?? window.currentFronter['name']); - document.getElementById("home-avatar").src = window.data['image-me']; - - switch (new Date().getHours()) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - document.getElementById("home-greeting").innerText = "Good night"; - break; - - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - document.getElementById("home-greeting").innerText = "Good morning"; - break; - - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - document.getElementById("home-greeting").innerText = "Good afternoon"; - break; - - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - document.getElementById("home-greeting").innerText = "Good evening"; - break; + try { + document.getElementById("home-name").innerText = getMiniName(window.currentFronter['display_name'] ?? window.currentFronter['name']); + document.getElementById("home-avatar").src = window.data['image-me']; + + switch (new Date().getHours()) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + document.getElementById("home-greeting").innerText = "Good night"; + break; + + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + document.getElementById("home-greeting").innerText = "Good morning"; + break; + + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + document.getElementById("home-greeting").innerText = "Good afternoon"; + break; + + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + document.getElementById("home-greeting").innerText = "Good evening"; + break; + } + } catch (e) { + document.getElementById("home-front").style.display = "none"; } window.otherSystem = window.data.identity.id === "raindrops" ? "cloudburst" : "raindrops"; window.otherFronters = window.data["pluralkit-" + otherSystem + "-fronters"]; document.getElementById("home-other-system").innerText = otherSystem === "raindrops" ? "Raindrops System" : "Cloudburst System"; - document.getElementById("home-other-name").innerText = window.otherFronters.members[0].display_name ?? window.otherFronters.members[0].name; - document.getElementById("home-other-img").src = window.images.profile[otherSystem === "raindrops" ? "gdapd" : "ynmuc"][window.otherFronters.members[0].id]; + if (window.otherFronters.members[0]) document.getElementById("home-other-name").innerText = window.otherFronters.members[0].display_name ?? window.otherFronters.members[0].name; + if (window.otherFronters.members[0]) document.getElementById("home-other-img").src = window.images.profile[otherSystem === "raindrops" ? "gdapd" : "ynmuc"][window.otherFronters.members[0].id]; + if (!window.otherFronters.members[0]) document.getElementById("home-other").style.display = "none"; if (!window.connected) { document.getElementById("home-app-planner").classList.add("disabled"); diff --git a/app/planner/index.php b/app/planner/index.php index 775fec3..0ae3663 100644 --- a/app/planner/index.php +++ b/app/planner/index.php @@ -1,4 +1,4 @@ - + @@ -33,13 +33,13 @@
3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly" && $parts[0] !== "Windy") { + if (strlen($parts[0]) > 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly" && $parts[0] !== "Windy" && (isset($parts[1]) && $parts[1] !== "Brightdawn")) { if (str_contains($parts[0], "/")) { return explode("/", $parts[0])[0]; } else { @@ -53,17 +53,19 @@ function getSystemMember(string $system, string $id) { $systemID = $system; - $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true); + $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID/members.json"), true); $member = null; foreach ($members as $m) { if ($m["id"] === $id) $member = $m; } + $member["system"] = $member["_system"] = $system; + return $member; } - require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/planner.php"; ?> + require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/planner.inc"; ?>
\ No newline at end of file diff --git a/app/sw.js b/app/sw.js index f355509..bb275bb 100644 --- a/app/sw.js +++ b/app/sw.js @@ -57,11 +57,13 @@ let filesToCache = [ "/app/fronters/bootstrap/bootstrap.js", "/app/fronters/bootstrap/bootstrap.js.map", "/app/fronters/index.html", + "/app/fronters/ponies/auvwc.png", "/app/fronters/ponies/ckqsw.png", "/app/fronters/ponies/erefx.png", "/app/fronters/ponies/erknz.png", "/app/fronters/ponies/gevde.png", "/app/fronters/ponies/gfhsr.png", + "/app/fronters/ponies/ghrby.png", "/app/fronters/ponies/hpwyq.png", "/app/fronters/ponies/jnbae.png", "/app/fronters/ponies/khsbb.png", @@ -69,6 +71,7 @@ let filesToCache = [ "/app/fronters/ponies/lllfw.png", "/app/fronters/ponies/mglyq.png", "/app/fronters/ponies/mhnqy.png", + "/app/fronters/ponies/mvaws.png", "/app/fronters/ponies/nabky.png", "/app/fronters/ponies/pabmo.png", "/app/fronters/ponies/qbzxm.png", @@ -86,16 +89,25 @@ let filesToCache = [ "/app/fronters/ponies/zhtzs.png", "/app/fronters/ponies/ztfjz.png", "/app/fronters/ponies/zzise.png", + "/app/fronters/profiles/auvwc.png", "/app/fronters/profiles/ckqsw.png", + "/app/fronters/profiles/cmeyc.png", "/app/fronters/profiles/djnko.png", + "/app/fronters/profiles/dogwu.png", + "/app/fronters/profiles/epvhq.png", "/app/fronters/profiles/erefx.png", "/app/fronters/profiles/erknz.png", + "/app/fronters/profiles/exidq.png", + "/app/fronters/profiles/ezqym.png", + "/app/fronters/profiles/famxl.png", "/app/fronters/profiles/flukm.png", "/app/fronters/profiles/gevde.png", "/app/fronters/profiles/gfhsr.png", + "/app/fronters/profiles/ghrby.png", "/app/fronters/profiles/ghuln.png", "/app/fronters/profiles/hpwyq.png", "/app/fronters/profiles/irxyh.png", + "/app/fronters/profiles/jhemc.png", "/app/fronters/profiles/jnbae.png", "/app/fronters/profiles/khsbb.png", "/app/fronters/profiles/kkhbw.png", @@ -104,25 +116,34 @@ let filesToCache = [ "/app/fronters/profiles/lzlaq.png", "/app/fronters/profiles/mglyq.png", "/app/fronters/profiles/mhnqy.png", + "/app/fronters/profiles/mvaws.png", "/app/fronters/profiles/mxpxm.png", "/app/fronters/profiles/nabky.png", "/app/fronters/profiles/pabmo.png", + "/app/fronters/profiles/ppukh.png", "/app/fronters/profiles/qbzxm.png", "/app/fronters/profiles/qraku.png", + "/app/fronters/profiles/qzbpf.png", "/app/fronters/profiles/rdstg.png", "/app/fronters/profiles/rirgf.png", "/app/fronters/profiles/rmlbf.png", "/app/fronters/profiles/rpjok.png", "/app/fronters/profiles/sbxze.png", "/app/fronters/profiles/sehke.png", + "/app/fronters/profiles/sjuao.png", + "/app/fronters/profiles/souga.png", "/app/fronters/profiles/tfbob.png", "/app/fronters/profiles/tgxst.png", "/app/fronters/profiles/tmgiu.png", + "/app/fronters/profiles/trefr.png", + "/app/fronters/profiles/vahcl.png", "/app/fronters/profiles/vncoa.png", "/app/fronters/profiles/vvsxf.png", + "/app/fronters/profiles/wjovt.png", "/app/fronters/profiles/xbvwt.png", "/app/fronters/profiles/xcjhj.png", "/app/fronters/profiles/ybmig.png", + "/app/fronters/profiles/ynpba.png", "/app/fronters/profiles/zajrk.png", "/app/fronters/profiles/zdtsg.png", "/app/fronters/profiles/zhtzs.png", @@ -160,9 +181,11 @@ let filesToCache = [ "/assets/uploads/pt-duskrainbow.png", "/assets/uploads/pt-fluttershy.png", "/assets/uploads/pt-frostcrystals.png", - "/assets/uploads/pt-izzy.png", + "/assets/uploads/pt-izzymoonbow.png", "/assets/uploads/pt-lavender.png", + "/assets/uploads/pt-lilacbloom.png", "/assets/uploads/pt-mintygrape.png", + "/assets/uploads/pt-mistybrightdawn.png", "/assets/uploads/pt-mistycloud.png", "/assets/uploads/pt-mossystorm.png", "/assets/uploads/pt-pipppetals.png", @@ -172,20 +195,24 @@ let filesToCache = [ "/assets/uploads/pt-scootaloo.png", "/assets/uploads/pt-skydream.png", "/assets/uploads/pt-smolscoots.png", + "/assets/uploads/pt-smolsunny.png", "/assets/uploads/pt-smoltwi.png", "/assets/uploads/pt-starrynight.png", "/assets/uploads/pt-stuffie.png", "/assets/uploads/pt-sunnystarscout.png", "/assets/uploads/pt-sweetiebelle.png", "/assets/uploads/pt-sweetiebot.png", + "/assets/uploads/pt-thunder.png", "/assets/uploads/pt-twilight.png", "/assets/uploads/pt-velvet.png", "/assets/uploads/pt-violetdawn.png", "/assets/uploads/pt-windy.png", "/assets/uploads/pt-windyleaves.png", "/assets/uploads/pt-zippstorm.png", + "/assets/uploads/pt-zoomzephyrwing.png", "/assets/uploads/pt.png", "/assets/uploads/raindrops.png", + "/assets/uploads/ss-lostequestrians.png", "/assets/uploads/ss-sparkles.png" ]; diff --git a/assets/editor/chart.js b/assets/editor/chart.js new file mode 100644 index 0000000..92ce789 --- /dev/null +++ b/assets/editor/chart.js @@ -0,0 +1,13 @@ +/*! + * Chart.js v3.9.1 + * https://www.chartjs.org + * (c) 2022 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";function t(){}const e=function(){let t=0;return function(){return t++}}();function i(t){return null==t}function s(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function n(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const o=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function a(t,e){return o(t)?t:e}function r(t,e){return void 0===t?e:t}const l=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function c(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function d(t,e,i,o){let a,r,l;if(s(t))if(r=t.length,o)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;at,x:t=>t.x,y:t=>t.y};function y(t,e){const i=_[e]||(_[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const M=t=>void 0!==t,k=t=>"function"==typeof t,S=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function P(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const D=Math.PI,O=2*D,C=O+D,A=Number.POSITIVE_INFINITY,T=D/180,L=D/2,E=D/4,R=2*D/3,I=Math.log10,z=Math.sign;function F(t){const e=Math.round(t);t=N(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(I(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function V(t){const e=[],i=Math.sqrt(t);let s;for(s=1;st-e)).pop(),e}function B(t){return!isNaN(parseFloat(t))&&isFinite(t)}function N(t,e,i){return Math.abs(t-e)=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;sl&&h=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function tt(t,e,i){i=i||(i=>t[i]1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const et=(t,e,i,s)=>tt(t,i,s?s=>t[s][e]<=i:s=>t[s][e]tt(t,i,(s=>t[s][e]>=i));function st(t,e,i){let s=0,n=t.length;for(;ss&&t[n-1]>i;)n--;return s>0||n{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function at(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(nt.forEach((e=>{delete t[e]})),delete t._chartjs)}function rt(t){const e=new Set;let i,s;for(i=0,s=t.length;iArray.prototype.slice.call(t));let n=!1,o=[];return function(...i){o=s(i),n||(n=!0,lt.call(window,(()=>{n=!1,t.apply(e,o)})))}}function ct(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const dt=t=>"start"===t?"left":"end"===t?"right":"center",ut=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,ft=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;function gt(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=Z(Math.min(et(r,a.axis,h).lo,i?s:et(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?Z(Math.max(et(r,a.axis,c,!0).hi+1,i?0:et(e,l,a.getPixelForValue(c),!0).hi+1),n,s)-n:s-n}return{start:n,count:o}}function pt(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}var mt=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=lt.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}}; + /*! + * @kurkle/color v0.2.1 + * https://github.com/kurkle/color#readme + * (c) 2022 Jukka Kurkela + * Released under the MIT License + */function bt(t){return t+.5|0}const xt=(t,e,i)=>Math.max(Math.min(t,i),e);function _t(t){return xt(bt(2.55*t),0,255)}function yt(t){return xt(bt(255*t),0,255)}function vt(t){return xt(bt(t/2.55)/100,0,1)}function wt(t){return xt(bt(100*t),0,100)}const Mt={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},kt=[..."0123456789ABCDEF"],St=t=>kt[15&t],Pt=t=>kt[(240&t)>>4]+kt[15&t],Dt=t=>(240&t)>>4==(15&t);function Ot(t){var e=(t=>Dt(t.r)&&Dt(t.g)&&Dt(t.b)&&Dt(t.a))(t)?St:Pt;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Ct=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function At(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Tt(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Lt(t,e,i){const s=At(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function Et(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e>16&255,o>>8&255,255&o]}return t}(),Nt.transparent=[0,0,0,0]);const e=Nt[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const jt=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Ht=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,$t=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Yt(t,e,i){if(t){let s=Et(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=It(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function Ut(t,e){return t?Object.assign(e||{},t):t}function Xt(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=yt(t[3]))):(e=Ut(t,{r:0,g:0,b:0,a:1})).a=yt(e.a),e}function qt(t){return"r"===t.charAt(0)?function(t){const e=jt.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?_t(t):xt(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?_t(i):xt(i,0,255)),s=255&(e[4]?_t(s):xt(s,0,255)),n=255&(e[6]?_t(n):xt(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):Ft(t)}class Kt{constructor(t){if(t instanceof Kt)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=Xt(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*Mt[s[1]],g:255&17*Mt[s[2]],b:255&17*Mt[s[3]],a:5===o?17*Mt[s[4]]:255}:7!==o&&9!==o||(n={r:Mt[s[1]]<<4|Mt[s[2]],g:Mt[s[3]]<<4|Mt[s[4]],b:Mt[s[5]]<<4|Mt[s[6]],a:9===o?Mt[s[7]]<<4|Mt[s[8]]:255})),i=n||Wt(t)||qt(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=Ut(this._rgb);return t&&(t.a=vt(t.a)),t}set rgb(t){this._rgb=Xt(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${vt(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?Ot(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=Et(t),i=e[0],s=wt(e[1]),n=wt(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${vt(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=$t(vt(t.r)),n=$t(vt(t.g)),o=$t(vt(t.b));return{r:yt(Ht(s+i*($t(vt(e.r))-s))),g:yt(Ht(n+i*($t(vt(e.g))-n))),b:yt(Ht(o+i*($t(vt(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new Kt(this.rgb)}alpha(t){return this._rgb.a=yt(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=bt(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return Yt(this._rgb,2,t),this}darken(t){return Yt(this._rgb,2,-t),this}saturate(t){return Yt(this._rgb,1,t),this}desaturate(t){return Yt(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=Et(t);i[0]=zt(i[0]+e),i=It(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function Gt(t){return new Kt(t)}function Zt(t){if(t&&"object"==typeof t){const e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function Jt(t){return Zt(t)?t:Gt(t)}function Qt(t){return Zt(t)?t:Gt(t).saturate(.5).darken(.1).hexString()}const te=Object.create(null),ee=Object.create(null);function ie(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;et.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>Qt(e.backgroundColor),this.hoverBorderColor=(t,e)=>Qt(e.borderColor),this.hoverColor=(t,e)=>Qt(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return se(this,t,e)}get(t){return ie(this,t)}describe(t,e){return se(ee,t,e)}override(t,e){return se(te,t,e)}route(t,e,i,s){const o=ie(this,t),a=ie(this,i),l="_"+e;Object.defineProperties(o,{[l]:{value:o[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[l],e=a[s];return n(t)?Object.assign({},e,t):r(t,e)},set(t){this[l]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});function oe(){return"undefined"!=typeof window&&"undefined"!=typeof document}function ae(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function re(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const le=t=>window.getComputedStyle(t,null);function he(t,e){return le(t).getPropertyValue(e)}const ce=["top","right","bottom","left"];function de(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=ce[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ue(t,e){if("native"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=le(i),o="border-box"===n.boxSizing,a=de(n,"padding"),r=de(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const fe=t=>Math.round(10*t)/10;function ge(t,e,i,s){const n=le(t),o=de(n,"margin"),a=re(n.maxWidth,t,"clientWidth")||A,r=re(n.maxHeight,t,"clientHeight")||A,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=ae(t);if(o){const t=o.getBoundingClientRect(),a=le(o),r=de(a,"border","width"),l=de(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=re(a.maxWidth,o,"clientWidth"),n=re(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||A,maxHeight:n||A}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=de(n,"border","width"),e=de(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=fe(Math.min(h,a,l.maxWidth)),c=fe(Math.min(c,r,l.maxHeight)),h&&!c&&(c=fe(h/2)),{width:h,height:c}}function pe(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const me=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function be(t,e){const i=he(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function xe(t){return!t||i(t.size)||i(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function _e(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function ye(t,e,i,n){let o=(n=n||{}).data=n.data||{},a=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(o=n.data={},a=n.garbageCollect=[],n.font=e),t.save(),t.font=e;let r=0;const l=i.length;let h,c,d,u,f;for(h=0;hi.length){for(h=0;h0&&t.stroke()}}function Se(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.xe.top-i&&t.y0&&""!==r.strokeColor;let c,d;for(t.save(),t.font=a.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);i(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,r),c=0;ct[0])){M(s)||(s=$e("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>Ee([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>Ve(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=$e(ze(o,t),i),M(n))return Fe(t,n)?je(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>Ye(t).includes(e),ownKeys:t=>Ye(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function Re(t,e,i,o){const a={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Ie(t,o),setContext:e=>Re(t,e,i,o),override:s=>Re(t.override(s),e,i,o)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>Ve(t,e,(()=>function(t,e,i){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=t;let h=o[e];k(h)&&l.isScriptable(e)&&(h=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),Fe(t,e)&&(e=je(n._scopes,n,t,e));return e}(e,h,t,i));s(h)&&h.length&&(h=function(t,e,i,s){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=i;if(M(a.index)&&s(t))e=e[a.index%e.length];else if(n(e[0])){const i=e,s=o._scopes.filter((t=>t!==i));e=[];for(const n of i){const i=je(s,o,t,n);e.push(Re(i,a,r&&r[t],l))}}return e}(e,h,t,l.isIndexable));Fe(e,h)&&(h=Re(h,a,r&&r[e],l));return h}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Ie(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:k(i)?i:()=>i,isIndexable:k(s)?s:()=>s}}const ze=(t,e)=>t?t+w(e):e,Fe=(t,e)=>n(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function Ve(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function Be(t,e,i){return k(t)?t(e,i):t}const Ne=(t,e)=>!0===t?e:"string"==typeof t?y(e,t):void 0;function We(t,e,i,s,n){for(const o of e){const e=Ne(i,o);if(e){t.add(e);const o=Be(e._fallback,i,n);if(M(o)&&o!==i&&o!==s)return o}else if(!1===e&&M(s)&&i!==s)return null}return!1}function je(t,e,i,o){const a=e._rootScopes,r=Be(e._fallback,i,o),l=[...t,...a],h=new Set;h.add(o);let c=He(h,l,i,r||i,o);return null!==c&&((!M(r)||r===i||(c=He(h,l,r,c,o),null!==c))&&Ee(Array.from(h),[""],a,r,(()=>function(t,e,i){const o=t._getTarget();e in o||(o[e]={});const a=o[e];if(s(a)&&n(i))return i;return a}(e,i,o))))}function He(t,e,i,s,n){for(;i;)i=We(t,e,i,s,n);return i}function $e(t,e){for(const i of e){if(!i)continue;const e=i[t];if(M(e))return e}}function Ye(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}function Ue(t,e,i,s){const{iScale:n}=t,{key:o="r"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;re"x"===t?"y":"x";function Ge(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=X(o,n),l=X(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function Ze(t,e="x"){const i=Ke(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=qe(t,0);for(a=0;a!t.skip))),"monotone"===e.cubicInterpolationMode)Ze(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o0===t||1===t,ei=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*O/i),ii=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*O/i)+1,si={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*L),easeOutSine:t=>Math.sin(t*L),easeInOutSine:t=>-.5*(Math.cos(D*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>ti(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>ti(t)?t:ei(t,.075,.3),easeOutElastic:t=>ti(t)?t:ii(t,.075,.3),easeInOutElastic(t){const e=.1125;return ti(t)?t:t<.5?.5*ei(2*t,e,.45):.5+.5*ii(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-si.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*si.easeInBounce(2*t):.5*si.easeOutBounce(2*t-1)+.5};function ni(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function ai(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=ni(t,n,i),r=ni(n,o,i),l=ni(o,e,i),h=ni(a,r,i),c=ni(r,l,i);return ni(h,c,i)}const ri=new Map;function li(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=ri.get(i);return s||(s=new Intl.NumberFormat(t,e),ri.set(i,s)),s}(e,i).format(t)}const hi=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),ci=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function di(t,e){const i=(""+t).match(hi);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function ui(t,e){const i={},s=n(e),o=s?Object.keys(e):e,a=n(t)?s?i=>r(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of o)i[t]=+a(t)||0;return i}function fi(t){return ui(t,{top:"y",right:"x",bottom:"y",left:"x"})}function gi(t){return ui(t,["topLeft","topRight","bottomLeft","bottomRight"])}function pi(t){const e=fi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function mi(t,e){t=t||{},e=e||ne.font;let i=r(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=r(t.style,e.style);s&&!(""+s).match(ci)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:r(t.family,e.family),lineHeight:di(r(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:r(t.weight,e.weight),string:""};return n.string=xe(n),n}function bi(t,e,i,n){let o,a,r,l=!0;for(o=0,a=t.length;oi&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function _i(t,e){return Object.assign(Object.create(t),e)}function yi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function vi(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function wi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Mi(t){return"angle"===t?{between:G,compare:q,normalize:K}:{between:Q,compare:(t,e)=>t-e,normalize:t=>t}}function ki({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Si(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Mi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Mi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;hx||l(n,b,p)&&0!==r(n,b),v=()=>!x||0===r(o,p)||l(o,b,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==b&&(x=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(ki({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,b=p));return null!==_&&g.push(ki({start:_,end:d,loop:u,count:a,style:f})),g}function Pi(t,e){const i=[],s=t.segments;for(let n=0;nn&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Oi(t,[{start:a,end:r,loop:o}],i,e);return Oi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r{t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Vi={evaluateInteractionItems:Ei,modes:{index(t,e,i,s){const n=ue(e,t),o=i.axis||"x",a=i.includeInvisible||!1,r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=ue(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;let r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;tRi(t,ue(e,t),i.axis||"xy",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=ue(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;return zi(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>Fi(t,ue(e,t),"x",i.intersect,s),y:(t,e,i,s)=>Fi(t,ue(e,t),"y",i.intersect,s)}};const Bi=["left","top","right","bottom"];function Ni(t,e){return t.filter((t=>t.pos===e))}function Wi(t,e){return t.filter((t=>-1===Bi.indexOf(t.pos)&&t.box.axis===e))}function ji(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Hi(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Bi.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function qi(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;ot.box.fullSize)),!0),s=ji(Ni(e,"left"),!0),n=ji(Ni(e,"right")),o=ji(Ni(e,"top"),!0),a=ji(Ni(e,"bottom")),r=Wi(e,"x"),l=Wi(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ni(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;d(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,u=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),f=Object.assign({},n);Yi(f,pi(s));const g=Object.assign({maxPadding:f,w:o,h:a,x:n.left,y:n.top},n),p=Hi(l.concat(h),u);qi(r.fullSize,g,u,p),qi(l,g,u,p),qi(h,g,u,p)&&qi(l,g,u,p),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(g),Gi(r.leftAndTop,g,u,p),g.x+=g.w,g.y+=g.h,Gi(r.rightAndBottom,g,u,p),t.chartArea={left:g.left,top:g.top,right:g.left+g.w,bottom:g.top+g.h,height:g.h,width:g.w},d(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(g.w,g.h,{left:0,top:0,right:0,bottom:0})}))}};class Ji{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Qi extends Ji{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const ts={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},es=t=>null===t||""===t;const is=!!me&&{passive:!0};function ss(t,e,i){t.canvas.removeEventListener(e,i,is)}function ns(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function os(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.addedNodes,s),e=e&&!ns(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function as(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.removedNodes,s),e=e&&!ns(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const rs=new Map;let ls=0;function hs(){const t=window.devicePixelRatio;t!==ls&&(ls=t,rs.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function cs(t,e,i){const s=t.canvas,n=s&&ae(s);if(!n)return;const o=ht(((t,e)=>{const s=n.clientWidth;i(t,e),s{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||o(i,s)}));return a.observe(n),function(t,e){rs.size||window.addEventListener("resize",hs),rs.set(t,e)}(t,o),a}function ds(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){rs.delete(t),rs.size||window.removeEventListener("resize",hs)}(t)}function us(t,e,i){const s=t.canvas,n=ht((e=>{null!==t.ctx&&i(function(t,e){const i=ts[t.type]||t.type,{x:s,y:n}=ue(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,is)}(s,e,n),n}class fs extends Ji{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",es(n)){const e=be(t,"width");void 0!==e&&(t.width=e)}if(es(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=be(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const s=e.$chartjs.initial;["height","width"].forEach((t=>{const n=s[t];i(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=s.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:os,detach:as,resize:cs}[e]||us;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ds,detach:ds,resize:ds}[e]||ss)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return ge(t,e,i,s)}isAttached(t){const e=ae(t);return!(!e||!e.isConnected)}}function gs(t){return!oe()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Qi:fs}var ps=Object.freeze({__proto__:null,_detectPlatform:gs,BasePlatform:Ji,BasicPlatform:Qi,DomPlatform:fs});const ms="transparent",bs={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=Jt(t||ms),n=s.valid&&Jt(e||ms);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class xs{constructor(t,e,i,s){const n=e[i];s=bi([t.to,s,n,t.from]);const o=bi([t.from,n,s]);this._active=!0,this._fn=t.fn||bs[t.type||typeof o],this._easing=si[t.easing]||si.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=bi([t.to,e,s,t.from]),this._from=bi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),ne.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),ne.describe("animations",{_fallback:"animation"}),ne.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class ys{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!n(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const o=t[i];if(!n(o))return;const a={};for(const t of _s)a[t]=o[t];(s(o.properties)&&o.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,a)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new xs(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(mt.add(this._chart,i),!0):void 0}}function vs(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ws(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n0||!i&&e<0)return n.index}return null}function Ds(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;ti[t].axis===e)).shift()}function Cs(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const As=t=>"reset"===t||"none"===t,Ts=(t,e)=>e?t:Object.assign({},t);class Ls{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ks(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Cs(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=r(i.xAxisID,Os(t,"x")),o=e.yAxisID=r(i.yAxisID,Os(t,"y")),a=e.rAxisID=r(i.rAxisID,Os(t,"r")),l=e.indexAxis,h=e.iAxisID=s(l,n,o,a),c=e.vAxisID=s(l,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(h),e.vScale=this.getScaleForId(c)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&at(this._data,this),t._stacked&&Cs(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(n(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=o,i._sorted=!0,d=o;else{d=s(o[t])?this.parseArrayData(i,o,t,e):n(o[t])?this.parseObjectData(i,o,t,e):this.parsePrimitiveData(i,o,t,e);const a=()=>null===c[l]||f&&c[l]t&&!e.hidden&&e._stacked&&{keys:ws(i,!0),values:null})(e,i,this.chart),h={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:c,max:d}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(r);let u,f;function g(){f=s[u];const e=f[r.axis];return!o(f[t.axis])||c>e||d=0;--u)if(!g()){this.updateRangeFromParsed(h,t,f,l);break}return h}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,a;for(s=0,n=e.length;s=0&&tthis.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ts(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new ys(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||As(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const i=this.resolveDataElementOptions(t,e),s=this._sharedOptions,n=this.getSharedOptions(i),o=this.includeOptions(e,n)||n!==s;return this.updateSharedOptions(n,e,i),{sharedOptions:n,includeOptions:o}}updateElement(t,e,i,s){As(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!As(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Es.defaults={},Es.defaultRoutes=void 0;const Rs={values:t=>s(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=I(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),li(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(I(t)));return 1===s||2===s||5===s?Rs.numeric.call(this,t,e,i):""}};var Is={formatters:Rs};function zs(t,e){const s=t.options.ticks,n=s.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),o=s.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;in)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;nn)return e}return Math.max(n,1)}(o,e,n);if(a>0){let t,s;const n=a>1?Math.round((l-r)/(a-1)):null;for(Fs(e,h,c,i(n)?0:r-n,r),t=0,s=a-1;te.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Is.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),ne.route("scale.ticks","color","","color"),ne.route("scale.grid","color","","borderColor"),ne.route("scale.grid","borderColor","","borderColor"),ne.route("scale.title","color","","color"),ne.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),ne.describe("scales",{_fallback:"scale"}),ne.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Vs=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Bs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;oa+r)))return h}function Ws(t){return t.drawTicks?t.tickLength:0}function js(t,e){if(!t.display)return 0;const i=mi(t.font,e),n=pi(t.padding);return(s(t.text)?t.text.length:1)*i.lineHeight+n.height}function Hs(t,e,i){let s=dt(t);return(i&&"right"!==e||!i&&"right"===e)&&(s=(t=>"left"===t?"right":"right"===t?"left":t)(s)),s}class $s extends Es{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=a(t,Number.POSITIVE_INFINITY),e=a(e,Number.NEGATIVE_INFINITY),i=a(i,Number.POSITIVE_INFINITY),s=a(s,Number.NEGATIVE_INFINITY),{min:a(t,i),max:a(e,s),minDefined:o(t),maxDefined:o(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const r=this.getMatchingVisibleMetas();for(let a=0,l=r.length;as?s:i,s=n&&i>s?i:s,{min:a(i,a(s,i)),max:a(s,a(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){c(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=xi(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Z(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Ws(t.grid)-e.padding-js(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=$(Math.min(Math.asin(Z((h.highest.height+6)/o,-1,1)),Math.asin(Z(a/r,-1,1))-Math.asin(Z(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){c(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){c(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=js(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Ws(n)+o):(t.height=this.maxHeight,t.width=Ws(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=H(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:"inner"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){c(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,s;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,s=t.length;e{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n({width:a[t]||0,height:r[t]||0});return{first:k(0),last:k(e-1),widest:k(w),highest:k(M),widths:a,heights:r}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return J(this._alignToPixels?ve(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&ta*s?a/i:r/s:r*s0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:o,position:a}=s,l=o.offset,h=this.isHorizontal(),c=this.ticks.length+(l?1:0),d=Ws(o),u=[],f=o.setContext(this.getContext()),g=f.drawBorder?f.borderWidth:0,p=g/2,m=function(t){return ve(i,t,g)};let b,x,_,y,v,w,M,k,S,P,D,O;if("top"===a)b=m(this.bottom),w=this.bottom-d,k=b-p,P=m(t.top)+p,O=t.bottom;else if("bottom"===a)b=m(this.top),P=t.top,O=m(t.bottom)-p,w=b+p,k=this.top+d;else if("left"===a)b=m(this.right),v=this.right-d,M=b-p,S=m(t.left)+p,D=t.right;else if("right"===a)b=m(this.left),S=t.left,D=m(t.right)-p,v=b+p,M=this.left+d;else if("x"===e){if("center"===a)b=m((t.top+t.bottom)/2+.5);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}P=t.top,O=t.bottom,w=b+p,k=w+d}else if("y"===e){if("center"===a)b=m((t.left+t.right)/2);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}v=b-p,M=v-d,S=t.left,D=t.right}const C=r(s.ticks.maxTicksLimit,c),A=Math.max(1,Math.ceil(c/C));for(x=0;xe.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");ne.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&ne.describe(e,t.descriptors)}(t,o,i),this.override&&ne.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in ne[s]&&(delete ne[s][i],this.override&&delete te[i])}}var Us=new class{constructor(){this.controllers=new Ys(Ls,"datasets",!0),this.elements=new Ys(Es,"elements"),this.plugins=new Ys(Object,"plugins"),this.scales=new Ys($s,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):d(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=w(t);c(i["before"+s],[],i),e[t](i),c(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;et.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function qs(t,e){return e||!1!==t?!0===t?{}:t:null}function Ks(t,{plugin:e,local:i},s,n){const o=t.pluginScopeKeys(e),a=t.getOptionScopes(s,o);return i&&e.defaults&&a.push(e.defaults),t.createResolver(a,n,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function Gs(t,e){const i=ne.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Zs(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function Js(t){const e=t.options||(t.options={});e.plugins=r(e.plugins,{}),e.scales=function(t,e){const i=te[t.type]||{scales:{}},s=e.scales||{},o=Gs(t.type,e),a=Object.create(null),r=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!n(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const l=Zs(t,e),h=function(t,e){return t===e?"_index_":"_value_"}(l,o),c=i.scales||{};a[l]=a[l]||t,r[t]=b(Object.create(null),[{axis:l},e,c[l],c[h]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,o=i.indexAxis||Gs(n,e),l=(te[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,o),n=i[e+"AxisID"]||a[e]||e;r[n]=r[n]||Object.create(null),b(r[n],[{axis:e},s[n],l[t]])}))})),Object.keys(r).forEach((t=>{const e=r[t];b(e,[ne.scales[e.type],ne.scale])})),r}(t,e)}function Qs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const tn=new Map,en=new Set;function sn(t,e){let i=tn.get(t);return i||(i=e(),tn.set(t,i),en.add(i)),i}const nn=(t,e,i)=>{const s=y(e,i);void 0!==s&&t.add(s)};class on{constructor(t){this._config=function(t){return(t=t||{}).data=Qs(t.data),Js(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Qs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Js(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return sn(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return sn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return sn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return sn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>nn(r,t,e)))),e.forEach((t=>nn(r,s,t))),e.forEach((t=>nn(r,te[n]||{},t))),e.forEach((t=>nn(r,ne,t))),e.forEach((t=>nn(r,ee,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),en.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,te[e]||{},ne.datasets[e]||{},{type:e},ne,ee]}resolveNamedOptions(t,e,i,n=[""]){const o={$shared:!0},{resolver:a,subPrefixes:r}=an(this._resolverCache,t,n);let l=a;if(function(t,e){const{isScriptable:i,isIndexable:n}=Ie(t);for(const o of e){const e=i(o),a=n(o),r=(a||e)&&t[o];if(e&&(k(r)||rn(r))||a&&s(r))return!0}return!1}(a,e)){o.$shared=!1;l=Re(a,i=k(i)?i():i,this.createResolver(t,i,r))}for(const t of e)o[t]=l[t];return o}createResolver(t,e,i=[""],s){const{resolver:o}=an(this._resolverCache,t,i);return n(e)?Re(o,e,void 0,s):o}}function an(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:Ee(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const rn=t=>n(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||k(t[i])),!1);const ln=["top","bottom","left","right","chartArea"];function hn(t,e){return"top"===t||"bottom"===t||-1===ln.indexOf(t)&&"x"===e}function cn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function dn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),c(i&&i.onComplete,[t],e)}function un(t){const e=t.chart,i=e.options.animation;c(i&&i.onProgress,[t],e)}function fn(t){return oe()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const gn={},pn=t=>{const e=fn(t);return Object.values(gn).filter((t=>t.canvas===e)).pop()};function mn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class bn{constructor(t,i){const s=this.config=new on(i),n=fn(t),o=pn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas with ID '"+o.canvas.id+"' can be reused.");const a=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||gs(n)),this.platform.updateConfig(s);const r=this.platform.acquireContext(n,a.aspectRatio),l=r&&r.canvas,h=l&&l.height,c=l&&l.width;this.id=e(),this.ctx=r,this.canvas=l,this.width=c,this.height=h,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Xs,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=ct((t=>this.update(t)),a.resizeDelay||0),this._dataChanges=[],gn[this.id]=this,r&&l?(mt.listen(this,"complete",dn),mt.listen(this,"progress",un),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:s,height:n,_aspectRatio:o}=this;return i(t)?e&&o?o:n?s/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():pe(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return we(this.canvas,this.ctx),this}stop(){return mt.stop(this),this}resize(t,e){mt.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,pe(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),c(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){d(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Zs(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),d(n,(e=>{const n=e.options,o=n.id,a=Zs(o,n),l=r(n.type,e.dtype);void 0!==n.position&&hn(n.position,a)===hn(e.dposition)||(n.position=e.dposition),s[o]=!0;let h=null;if(o in i&&i[o].type===l)h=i[o];else{h=new(Us.getScale(l))({id:o,type:l,ctx:this.ctx,chart:this}),i[h.id]=h}h.init(n,t)})),d(s,((t,e)=>{t||delete i[e]})),d(i,(t=>{Zi.configure(this,t,t.options),Zi.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;te.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(cn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){d(this.scales,(t=>{Zi.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);S(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){mn(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;tt.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;Zi.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],d(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&Pe(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&De(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}isPointInArea(t){return Se(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Vi.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=_i(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);M(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),mt.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};d(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){d(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},d(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!u(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=P(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,c(n.onHover,[t,a,this],this),r&&c(n.onClick,[t,a,this],this));const h=!u(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const xn=()=>d(bn.instances,(t=>t._plugins.invalidate())),_n=!0;function yn(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(bn,{defaults:{enumerable:_n,value:ne},instances:{enumerable:_n,value:gn},overrides:{enumerable:_n,value:te},registry:{enumerable:_n,value:Us},version:{enumerable:_n,value:"3.9.1"},getChart:{enumerable:_n,value:pn},register:{enumerable:_n,value:(...t)=>{Us.add(...t),xn()}},unregister:{enumerable:_n,value:(...t)=>{Us.remove(...t),xn()}}});class vn{constructor(t){this.options=t||{}}init(t){}formats(){return yn()}parse(t,e){return yn()}format(t,e){return yn()}add(t,e,i){return yn()}diff(t,e,i){return yn()}startOf(t,e,i){return yn()}endOf(t,e){return yn()}}vn.override=function(t){Object.assign(vn.prototype,t)};var wn={_date:vn};function Mn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;et-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(M(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;sMath.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,n):e[i.axis]=i.parse(t,n),e}function Sn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;ht.x,i="left",s="right"):(e=t.baset.controller.options.grouped)),o=s.options.stacked,a=[],r=t=>{const s=t.controller.getParsed(e),n=s&&s[t.vScale.axis];if(i(n)||isNaN(n))return!0};for(const i of n)if((void 0===e||!r(i))&&((!1===o||-1===a.indexOf(i.stack)||void 0===o&&void 0===i.stack)&&a.push(i.stack),i.index===t))break;return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n=i?1:-1)}(d,e,a)*o,u===a&&(m-=d/2);const t=e.getPixelForDecimal(0),i=e.getPixelForDecimal(1),s=Math.min(t,i),n=Math.max(t,i);m=Math.max(Math.min(m,n),s),c=m+d}if(m===e.getPixelForValue(a)){const t=z(d)*e.getLineWidthForValue(a)/2;m+=t,d-=t}return{size:d,base:m,head:c,center:c+d/2}}_calculateBarIndexPixels(t,e){const s=e.scale,n=this.options,o=n.skipNull,a=r(n.maxBarThickness,1/0);let l,h;if(e.grouped){const s=o?this._getStackCount(t):e.stackCount,r="flex"===n.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,{sharedOptions:r,includeOptions:l}=this._getSharedOptions(e,s),h=o.axis,c=a.axis;for(let d=e;d""}}}};class En extends Ls{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let o,a,r=t=>+i[t];if(n(i[t])){const{key:t="value"}=this._parsing;r=e=>+y(i[e],t)}for(o=t,a=t+e;oG(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>G(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(L,c,u),b=g(D,h,d),x=g(D+L,c,u);s=(p-b)/2,n=(m-x)/2,o=-(p+b)/2,a=-(m+x)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(u,d,r),b=(i.width-o)/f,x=(i.height-o)/g,_=Math.max(Math.min(b,x)/2,0),y=h(this.options.radius,_),v=(y-Math.max(y*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=p*y,this.offsetY=m*y,s.total=this.calculateTotal(),this.outerRadius=y-v*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-v*c,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/O)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,{sharedOptions:f,includeOptions:g}=this._getSharedOptions(e,s);let p,m=this._getRotation();for(p=0;p0&&!isNaN(t)?O*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s"spacing"!==t,_indexable:t=>"spacing"!==t},En.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return s(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Rn extends Ls{initialize(){this.enableOptionSharing=!0,this.supportsDecimation=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=gt(e,s,o);this._drawStart=a,this._drawCount=r,pt(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,s,n){const o="reset"===n,{iScale:a,vScale:r,_stacked:l,_dataset:h}=this._cachedMeta,{sharedOptions:c,includeOptions:d}=this._getSharedOptions(e,n),u=a.axis,f=r.axis,{spanGaps:g,segment:p}=this.options,m=B(g)?g:Number.POSITIVE_INFINITY,b=this.chart._animationsDisabled||o||"none"===n;let x=e>0&&this.getParsed(e-1);for(let g=e;g0&&Math.abs(s[u]-x[u])>m,p&&(_.parsed=s,_.raw=h.data[g]),d&&(_.options=c||this.resolveDataElementOptions(g,e.active?"active":n)),b||this.updateElement(e,g,_,n),x=s}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Rn.id="line",Rn.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},Rn.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class In extends Ls{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(se.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*D;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?H(this.resolveDataElementOptions(t,e).angle||i):0}}In.id="polarArea",In.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},In.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class zn extends En{}zn.id="pie",zn.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class Fn extends Ls{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o="reset"===s;for(let a=e;a0&&this.getParsed(e-1);for(let c=e;c0&&Math.abs(s[f]-_[f])>b,m&&(p.parsed=s,p.raw=h.data[c]),u&&(p.options=d||this.resolveDataElementOptions(c,e.active?"active":n)),x||this.updateElement(e,c,p,n),_=s}this.updateSharedOptions(d,n,c)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let t=0;for(let i=e.length-1;i>=0;--i)t=Math.max(t,e[i].size(this.resolveDataElementOptions(i))/2);return t>0&&t}const i=t.dataset,s=i.options&&i.options.borderWidth||0;if(!e.length)return s;const n=e[0].size(this.resolveDataElementOptions(0)),o=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(s,n,o)/2}}Vn.id="scatter",Vn.defaults={datasetElementType:!1,dataElementType:"point",showLine:!1,fill:!1},Vn.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var Bn=Object.freeze({__proto__:null,BarController:Tn,BubbleController:Ln,DoughnutController:En,LineController:Rn,PolarAreaController:In,PieController:zn,RadarController:Fn,ScatterController:Vn});function Nn(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+L,s-L),t.closePath(),t.clip()}function Wn(t,e,i,s){const n=ui(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Z(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Z(n.innerStart,0,a),innerEnd:Z(n.innerEnd,0,a)}}function jn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Hn(t,e,i,s,n,o){const{x:a,y:r,startAngle:l,pixelMargin:h,innerRadius:c}=e,d=Math.max(e.outerRadius+s+i-h,0),u=c>0?c+s+i+h:0;let f=0;const g=n-l;if(s){const t=((c>0?c-s:0)+(d>0?d-s:0))/2;f=(g-(0!==t?g*t/(t+s):g))/2}const p=(g-Math.max(.001,g*d-i/D)/d)/2,m=l+p+f,b=n-p-f,{outerStart:x,outerEnd:_,innerStart:y,innerEnd:v}=Wn(e,u,d,b-m),w=d-x,M=d-_,k=m+x/w,S=b-_/M,P=u+y,O=u+v,C=m+y/P,A=b-v/O;if(t.beginPath(),o){if(t.arc(a,r,d,k,S),_>0){const e=jn(M,S,a,r);t.arc(e.x,e.y,_,S,b+L)}const e=jn(O,b,a,r);if(t.lineTo(e.x,e.y),v>0){const e=jn(O,A,a,r);t.arc(e.x,e.y,v,b+L,A+Math.PI)}if(t.arc(a,r,u,b-v/u,m+y/u,!0),y>0){const e=jn(P,C,a,r);t.arc(e.x,e.y,y,C+Math.PI,m-L)}const i=jn(w,m,a,r);if(t.lineTo(i.x,i.y),x>0){const e=jn(w,k,a,r);t.arc(e.x,e.y,x,m-L,k)}}else{t.moveTo(a,r);const e=Math.cos(k)*d+a,i=Math.sin(k)*d+r;t.lineTo(e,i);const s=Math.cos(S)*d+a,n=Math.sin(S)*d+r;t.lineTo(s,n)}t.closePath()}function $n(t,e,i,s,n,o){const{options:a}=e,{borderWidth:r,borderJoinStyle:l}=a,h="inner"===a.borderAlign;r&&(h?(t.lineWidth=2*r,t.lineJoin=l||"round"):(t.lineWidth=r,t.lineJoin=l||"bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&Nn(t,e,o+O),t.beginPath(),t.arc(s,n,h,o+O,o,!0),c=0;c=O||G(n,a,l),g=Q(o,h+u,c+u);return f&&g}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2,o=e.circular;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>O?Math.floor(i/O):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let a=0;if(s){a=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*a,Math.sin(e)*a),this.circumference>=D&&(a=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const r=function(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r}=e;let l=e.endAngle;if(o){Hn(t,e,i,s,a+O,n);for(let e=0;er&&o>r;return{count:s,start:l,loop:e.loop,ilen:h(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[x(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[x(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(ig&&(g=i),m=(b*m+e)/++b):(_(),t.lineTo(e,i),u=s,b=0,f=g=i),p=i}_()}function Zn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?Gn:Kn}Yn.id="arc",Yn.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0},Yn.defaultRoutes={backgroundColor:"backgroundColor"};const Jn="function"==typeof Path2D;function Qn(t,e,i,s){Jn&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Un(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Zn(e);for(const r of n)Un(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class to extends Es{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;Qe(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Di(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Pi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?oi:t.tension||"monotone"===t.cubicInterpolationMode?ai:ni}(i);let l,h;for(l=0,h=o.length;l"borderDash"!==t&&"fill"!==t};class io extends Es{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2){uo(t)}))}var go={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,s)=>{if(!s.enabled)return void fo(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:a,indexAxis:r}=e,l=t.getDatasetMeta(o),h=a||e.data;if("y"===bi([r,t.options.indexAxis]))return;if(!l.controller.supportsDecimation)return;const c=t.scales[l.xAxisID];if("linear"!==c.type&&"time"!==c.type)return;if(t.options.parsing)return;let{start:d,count:u}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Z(et(e,o.axis,a).lo,0,i-1)),s=h?Z(et(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(l,h);if(u<=(s.threshold||4*n))return void uo(e);let f;switch(i(a)&&(e._data=h,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),s.algorithm){case"lttb":f=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;cu&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(h,d,u,n,s);break;case"min-max":f=function(t,e,s,n){let o,a,r,l,h,c,d,u,f,g,p=0,m=0;const b=[],x=e+s-1,_=t[e].x,y=t[x].x-_;for(o=e;og&&(g=l,d=o),p=(m*p+a.x)/++m;else{const s=o-1;if(!i(c)&&!i(d)){const e=Math.min(c,d),i=Math.max(c,d);e!==u&&e!==s&&b.push({...t[e],x:p}),i!==u&&i!==s&&b.push({...t[i],x:p})}o>0&&s!==u&&b.push(t[s]),b.push(a),h=e,m=0,f=g=l,c=d=u=o}}return b}(h,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${s.algorithm}'`)}e._decimated=f}))},destroy(t){fo(t)}};function po(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=K(n),o=K(o)),{property:t,start:n,end:o}}function mo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function bo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function xo(t,e){let i=[],n=!1;return s(t)?(n=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=mo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new to({points:i,options:{tension:0},_loop:n,_fullLoop:n}):null}function _o(t){return t&&!1!==t.fill}function yo(t,e,i){let s=t[e].fill;const n=[e];let a;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!o(s))return s;if(a=t[s],!a)return!1;if(a.visible)return s;n.push(s),s=a.fill}return!1}function vo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=r(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return"origin";return s}(t);if(n(s))return!isNaN(s.value)&&s;let a=parseFloat(s);return o(a)&&Math.floor(a)===a?function(t,e,i,s){"-"!==t&&"+"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,a,i):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}function wo(t,e,i){const s=[];for(let n=0;n=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&i.fill&&Po(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;_o(i)&&Po(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;_o(s)&&"beforeDatasetDraw"===i.drawTime&&Po(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const Lo=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=t.pointStyleWidth||Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Eo extends Es{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=c(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=mi(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Lo(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:n}}=this,o=yi(n,this.left,this.width);if(this.isHorizontal()){let n=0,a=ut(i,this.left+s,this.right-this.lineWidths[n]);for(const r of e)n!==r.row&&(n=r.row,a=ut(i,this.left+s,this.right-this.lineWidths[n])),r.top+=this.top+t+s,r.left=o.leftForLtr(o.x(a),r.width),a+=r.width+s}else{let n=0,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height);for(const r of e)r.col!==n&&(n=r.col,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height)),r.top=a,r.left+=this.left+s,r.left=o.leftForLtr(o.x(r.left),r.width),a+=r.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Pe(t,this),this._draw(),De(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:n,labels:o}=t,a=ne.color,l=yi(t.rtl,this.left,this.width),h=mi(o.font),{color:c,padding:d}=o,u=h.size,f=u/2;let g;this.drawTitle(),s.textAlign=l.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=h.string;const{boxWidth:p,boxHeight:m,itemHeight:b}=Lo(o,u),x=this.isHorizontal(),_=this._computeTitleHeight();g=x?{x:ut(n,this.left+d,this.right-i[0]),y:this.top+d+_,line:0}:{x:this.left+d,y:ut(n,this.top+_+d,this.bottom-e[0].height),line:0},vi(this.ctx,t.textDirection);const y=b+d;this.legendItems.forEach(((v,w)=>{s.strokeStyle=v.fontColor||c,s.fillStyle=v.fontColor||c;const M=s.measureText(v.text).width,k=l.textAlign(v.textAlign||(v.textAlign=o.textAlign)),S=p+f+M;let P=g.x,D=g.y;l.setWidth(this.width),x?w>0&&P+S+d>this.right&&(D=g.y+=y,g.line++,P=g.x=ut(n,this.left+d,this.right-i[g.line])):w>0&&D+y>this.bottom&&(P=g.x=P+e[g.line].width+d,g.line++,D=g.y=ut(n,this.top+_+d,this.bottom-e[g.line].height));!function(t,e,i){if(isNaN(p)||p<=0||isNaN(m)||m<0)return;s.save();const n=r(i.lineWidth,1);if(s.fillStyle=r(i.fillStyle,a),s.lineCap=r(i.lineCap,"butt"),s.lineDashOffset=r(i.lineDashOffset,0),s.lineJoin=r(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=r(i.strokeStyle,a),s.setLineDash(r(i.lineDash,[])),o.usePointStyle){const a={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},r=l.xPlus(t,p/2);ke(s,a,r,e+f,o.pointStyleWidth&&p)}else{const o=e+Math.max((u-m)/2,0),a=l.leftForLtr(t,p),r=gi(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?Le(s,{x:a,y:o,w:p,h:m,radius:r}):s.rect(a,o,p,m),s.fill(),0!==n&&s.stroke()}s.restore()}(l.x(P),D,v),P=ft(k,P+p+f,x?P+S:this.right,t.rtl),function(t,e,i){Ae(s,i.text,t,e+b/2,h,{strikethrough:i.hidden,textAlign:l.textAlign(i.textAlign)})}(l.x(P),D,v),x?g.x+=S+d:g.y+=y})),wi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=mi(e.font),s=pi(e.padding);if(!e.display)return;const n=yi(t.rtl,this.left,this.width),o=this.ctx,a=e.position,r=i.size/2,l=s.top+r;let h,c=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),h=this.top+l,c=ut(t.align,c,this.right-d);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);h=l+ut(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const u=ut(a,c,c+d);o.textAlign=n.textAlign(dt(a)),o.textBaseline="middle",o.strokeStyle=e.color,o.fillStyle=e.color,o.font=i.string,Ae(o,e.text,u,h,i)}_computeTitleHeight(){const t=this.options.title,e=mi(t.font),i=pi(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Q(t,this.left,this.right)&&Q(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;it.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=pi(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Io extends Es{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const n=s(i.text)?i.text.length:1;this._padding=pi(i.padding);const o=n*mi(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:n,options:o}=this,a=o.align;let r,l,h,c=0;return this.isHorizontal()?(l=ut(a,i,n),h=e+t,r=n-i):("left"===o.position?(l=i+t,h=ut(a,s,e),c=-.5*D):(l=n-t,h=ut(a,e,s),c=.5*D),r=s-e),{titleX:l,titleY:h,maxWidth:r,rotation:c}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=mi(e.font),s=i.lineHeight/2+this._padding.top,{titleX:n,titleY:o,maxWidth:a,rotation:r}=this._drawArgs(s);Ae(t,e.text,0,0,i,{color:e.color,maxWidth:a,rotation:r,textAlign:dt(e.align),textBaseline:"middle",translation:[n,o]})}}var zo={id:"title",_element:Io,start(t,e,i){!function(t,e){const i=new Io({ctx:t.ctx,options:e,chart:t});Zi.configure(t,i,e),Zi.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;Zi.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;Zi.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Fo=new WeakMap;var Vo={id:"subtitle",start(t,e,i){const s=new Io({ctx:t.ctx,options:i,chart:t});Zi.configure(t,s,i),Zi.addBox(t,s),Fo.set(t,s)},stop(t){Zi.removeBox(t,Fo.get(t)),Fo.delete(t)},beforeUpdate(t,e,i){const s=Fo.get(t);Zi.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Bo={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e-1?t.split("\n"):t}function jo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Ho(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=mi(e.bodyFont),h=mi(e.titleFont),c=mi(e.footerFont),u=o.length,f=n.length,g=s.length,p=pi(e.padding);let m=p.height,b=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,u&&(m+=u*h.lineHeight+(u-1)*e.titleSpacing+e.titleMarginBottom),x){m+=g*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-g)*l.lineHeight+(x-1)*e.bodySpacing}f&&(m+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);let _=0;const y=function(t){b=Math.max(b,i.measureText(t).width+_)};return i.save(),i.font=h.string,d(t.title,y),i.font=l.string,d(t.beforeBody.concat(t.afterBody),y),_=e.displayColors?a+2+e.boxPadding:0,d(s,(t=>{d(t.before,y),d(t.lines,y),d(t.after,y)})),_=0,i.font=c.string,d(t.footer,y),i.restore(),b+=p.width,{width:b,height:m}}function $o(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Yo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return it.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||$o(t,e,i,s),yAlign:s}}function Uo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=gi(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:Z(g,0,s.width-e.width),y:Z(p,0,s.height-e.height)}}function Xo(t,e,i){const s=pi(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function qo(t){return No([],Wo(t))}function Ko(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Go extends Es{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new ys(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,_i(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}getBeforeBody(t,e){return qo(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return d(t,(t=>{const e={before:[],lines:[],after:[]},n=Ko(i,t);No(e.before,Wo(n.beforeLabel.call(this,t))),No(e.lines,n.label.call(this,t)),No(e.after,Wo(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return qo(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;at.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),d(l,(e=>{const i=Ko(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Bo[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Ho(this,i),a=Object.assign({},t,e),r=Yo(this.chart,i,a),l=Uo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=gi(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,b,x,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,x=_+o,y=_-o):(p=d+f,m=p+o,x=_-o,y=_+o),b=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(x=u,_=x-o,p=m-o,b=m+o):(x=u+g,_=x+o,p=m+o,b=m-o),y=x),{x1:p,x2:m,x3:b,y1:x,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=yi(i.rtl,this.x,this.width);for(t.x=Xo(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=mi(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r0!==t))?(t.beginPath(),t.fillStyle=o.multiKeyBackground,Le(t,{x:e,y:p,w:h,h:l,radius:r}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),Le(t,{x:i,y:p+1,w:h-2,h:l-2,radius:r}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(e,p,h,l),t.strokeRect(e,p,h,l),t.fillStyle=a.backgroundColor,t.fillRect(i,p+1,h-2,l-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=mi(i.bodyFont);let u=c.lineHeight,f=0;const g=yi(i.rtl,this.x,this.width),p=function(i){e.fillText(i,g.x(t.x+f),t.y+u/2),t.y+=u+n},m=g.textAlign(o);let b,x,_,y,v,w,M;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=Xo(this,m,i),e.fillStyle=i.bodyColor,d(this.beforeBody,p),f=a&&"right"!==m?"center"===o?l/2+h:l+2+h:0,y=0,w=s.length;y0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Bo[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Ho(this,t),a=Object.assign({},i,this._size),r=Yo(e,t,a),l=Uo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=pi(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),vi(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),wi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!u(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!u(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Bo[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}Go.positioners=Bo;var Zo={id:"tooltip",_element:Go,positioners:Bo,afterInit(t,e,i){i&&(t.tooltip=new Go({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",i))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:t,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Jo=Object.freeze({__proto__:null,Decimation:go,Filler:To,Legend:Ro,SubTitle:Vo,Title:zo,Tooltip:Zo});function Qo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class ta extends $s{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(i(t))return null;const s=this.getLabels();return((t,e)=>null===t?null:Z(Math.round(t),0,e))(e=isFinite(e)&&s[e]===t?e:Qo(s,t,r(e,t),this._addedLabels),s.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&te.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function ea(t,e,{horizontal:i,minRotation:s}){const n=H(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}ta.id="category",ta.defaults={ticks:{callback:ta.prototype.getLabelForValue}};class ia extends $s{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return i(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=z(s),e=z(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let s=this.getTickLimit();s=Math.max(2,s);const n=function(t,e){const s=[],{bounds:n,step:o,min:a,max:r,precision:l,count:h,maxTicks:c,maxDigits:d,includeBounds:u}=t,f=o||1,g=c-1,{min:p,max:m}=e,b=!i(a),x=!i(r),_=!i(h),y=(m-p)/(d+1);let v,w,M,k,S=F((m-p)/g/f)*f;if(S<1e-14&&!b&&!x)return[{value:p},{value:m}];k=Math.ceil(m/S)-Math.floor(p/S),k>g&&(S=F(k*S/g/f)*f),i(l)||(v=Math.pow(10,l),S=Math.ceil(S*v)/v),"ticks"===n?(w=Math.floor(p/S)*S,M=Math.ceil(m/S)*S):(w=p,M=m),b&&x&&o&&W((r-a)/o,S/1e3)?(k=Math.round(Math.min((r-a)/S,c)),S=(r-a)/k,w=a,M=r):_?(w=b?a:w,M=x?r:M,k=h-1,S=(M-w)/k):(k=(M-w)/S,k=N(k,Math.round(k),S/1e3)?Math.round(k):Math.ceil(k));const P=Math.max(Y(S),Y(w));v=Math.pow(10,i(l)?P:l),w=Math.round(w*v)/v,M=Math.round(M*v)/v;let D=0;for(b&&(u&&w!==a?(s.push({value:a}),w0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=o(t)?Math.max(0,t):null,this.max=o(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(I(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(I(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=a(t.min,Math.pow(10,Math.floor(I(e.min)))),r=Math.floor(I(o)),l=Math.floor(o/Math.pow(10,r)),h=r<0?Math.pow(10,Math.abs(r)):1;do{n.push({value:o,major:na(o)}),++l,10===l&&(l=1,++r,h=r>=0?1:h),o=Math.round(l*Math.pow(10,r)*h)/h}while(rn?{start:e-i,end:e}:{start:e,end:e+i}}function la(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),n=[],o=[],a=t._pointLabels.length,r=t.options.pointLabels,l=r.centerPointLabels?D/a:0;for(let u=0;ue.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.starte.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function ca(t){return 0===t||180===t?"center":t<180?"left":"right"}function da(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function ua(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function fa(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,O);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o{const i=c(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?la(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return K(t*(O/(this._pointLabels.length||1))+H(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(i(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(i(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t=0;o--){const e=n.setContext(t.getPointLabelContext(o)),a=mi(e.font),{x:r,y:l,textAlign:h,left:c,top:d,right:u,bottom:f}=t._pointLabelItems[o],{backdropColor:g}=e;if(!i(g)){const t=gi(e.borderRadius),i=pi(e.backdropPadding);s.fillStyle=g;const n=c-i.left,o=d-i.top,a=u-c+i.width,r=f-d+i.height;Object.values(t).some((t=>0!==t))?(s.beginPath(),Le(s,{x:n,y:o,w:a,h:r,radius:t}),s.fill()):s.fillRect(n,o,a,r)}Ae(s,t._pointLabels[o],r,l+a.lineHeight/2,a,{color:e.color,textAlign:h,textBaseline:"middle"})}}(this,o),n.display&&this.ticks.forEach(((t,e)=>{if(0!==e){r=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),fa(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,n.setContext(this.getContext(e-1)),r,o)}})),s.display){for(t.save(),a=o-1;a>=0;a--){const i=s.setContext(this.getPointLabelContext(a)),{color:n,lineWidth:o}=i;o&&n&&(t.lineWidth=o,t.strokeStyle=n,t.setLineDash(i.borderDash),t.lineDashOffset=i.borderDashOffset,r=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),l=this.getPointPosition(a,r),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(l.x,l.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=mi(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=pi(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Ae(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}ga.id="radialLinear",ga.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Is.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},ga.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},ga.descriptors={angleLines:{_fallback:"grid"}};const pa={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ma=Object.keys(pa);function ba(t,e){return t-e}function xa(t,e){if(i(e))return null;const s=t._adapter,{parser:n,round:a,isoWeekday:r}=t._parseOpts;let l=e;return"function"==typeof n&&(l=n(l)),o(l)||(l="string"==typeof n?s.parse(l,n):s.parse(l)),null===l?null:(a&&(l="week"!==a||!B(r)&&!0!==r?s.startOf(l,a):s.startOf(l,"isoWeek",r)),+l)}function _a(t,e,i,s){const n=ma.length;for(let o=ma.indexOf(t);o=e?i[s]:i[n]]=!0}}else t[e]=!0}function va(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a=0&&(e[l].major=!0);return e}(t,s,n,i):s}class wa extends $s{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new wn._date(t.adapters.date);s.init(e),b(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:xa(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:a,maxDefined:r}=this.getUserBounds();function l(t){a||isNaN(t.min)||(s=Math.min(s,t.min)),r||isNaN(t.max)||(n=Math.max(n,t.max))}a&&r||(l(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||l(this.getMinMax(!1))),s=o(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=o(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=st(s,n,this.max);return this._unit=e.unit||(i.autoSkip?_a(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ma.length-1;o>=ma.indexOf(i);o--){const i=ma[o];if(pa[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ma[i?ma.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=ma.indexOf(t)+1,i=ma.length;e+t.value)))}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Z(s,0,o),n=Z(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||_a(n.minUnit,e,i,this._getLabelCapacity(e)),a=r(n.stepSize,1),l="week"===o&&n.isoWeekday,h=B(l)||!0===l,c={};let d,u,f=e;if(h&&(f=+t.startOf(f,"isoWeek",l)),f=+t.startOf(f,h?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const g="data"===s.ticks.source&&this.getDataTimestamps();for(d=f,u=0;dt-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],d=i[e],u=r&&h&&d&&d.major,f=this._adapter.format(t,s||(u?h:l)),g=n.ticks.callback;return g?c(g,[f,e,i],this):f}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=et(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=et(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}wa.id="time",wa.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ka extends wa{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=Ma(e,this.min),this._tableRange=Ma(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/actions.svg b/assets/icons/actions.svg index 7b36d3d..3e73e7d 100644 --- a/assets/icons/actions.svg +++ b/assets/icons/actions.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/add.svg b/assets/icons/add.svg index a769676..79a2511 100644 --- a/assets/icons/add.svg +++ b/assets/icons/add.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/admin.svg b/assets/icons/admin.svg index a9426d4..fe00d1b 100644 --- a/assets/icons/admin.svg +++ b/assets/icons/admin.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/bitset.svg b/assets/icons/bitset.svg index c842261..632b184 100644 --- a/assets/icons/bitset.svg +++ b/assets/icons/bitset.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/byfront.svg b/assets/icons/byfront.svg index a3089f5..054d7b6 100644 --- a/assets/icons/byfront.svg +++ b/assets/icons/byfront.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/compare.svg b/assets/icons/compare.svg index db51639..e7b5ecf 100644 --- a/assets/icons/compare.svg +++ b/assets/icons/compare.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/complete.svg b/assets/icons/complete.svg index e6a8a86..b291037 100644 --- a/assets/icons/complete.svg +++ b/assets/icons/complete.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/dashboard.svg b/assets/icons/dashboard.svg index 984a8b7..8e5328f 100644 --- a/assets/icons/dashboard.svg +++ b/assets/icons/dashboard.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/debug.svg b/assets/icons/debug.svg index e147a29..ec074f1 100644 --- a/assets/icons/debug.svg +++ b/assets/icons/debug.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/delete.svg b/assets/icons/delete.svg index 0584654..ccfd685 100644 --- a/assets/icons/delete.svg +++ b/assets/icons/delete.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/disclaimers.svg b/assets/icons/disclaimers.svg index a2a71a5..03b9c57 100644 --- a/assets/icons/disclaimers.svg +++ b/assets/icons/disclaimers.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/docs.svg b/assets/icons/docs.svg index 2fff0cf..04b93d3 100644 --- a/assets/icons/docs.svg +++ b/assets/icons/docs.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/down.svg b/assets/icons/down.svg index f53b64f..ad28be7 100644 --- a/assets/icons/down.svg +++ b/assets/icons/down.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/emergency.svg b/assets/icons/emergency.svg index 498396c..03f278f 100644 --- a/assets/icons/emergency.svg +++ b/assets/icons/emergency.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/favicon/about.png b/assets/icons/favicon/about.png deleted file mode 100644 index e61e6ec..0000000 Binary files a/assets/icons/favicon/about.png and /dev/null differ diff --git a/assets/icons/favicon/actions.png b/assets/icons/favicon/actions.png deleted file mode 100644 index b953234..0000000 Binary files a/assets/icons/favicon/actions.png and /dev/null differ diff --git a/assets/icons/favicon/add.png b/assets/icons/favicon/add.png deleted file mode 100644 index a966c31..0000000 Binary files a/assets/icons/favicon/add.png and /dev/null differ diff --git a/assets/icons/favicon/admin.png b/assets/icons/favicon/admin.png deleted file mode 100644 index 05907fc..0000000 Binary files a/assets/icons/favicon/admin.png and /dev/null differ diff --git a/assets/icons/favicon/bitset.png b/assets/icons/favicon/bitset.png deleted file mode 100644 index 28c9b85..0000000 Binary files a/assets/icons/favicon/bitset.png and /dev/null differ diff --git a/assets/icons/favicon/byfront.png b/assets/icons/favicon/byfront.png deleted file mode 100644 index 2c9ea80..0000000 Binary files a/assets/icons/favicon/byfront.png and /dev/null differ diff --git a/assets/icons/favicon/compare.png b/assets/icons/favicon/compare.png deleted file mode 100644 index fc93e2e..0000000 Binary files a/assets/icons/favicon/compare.png and /dev/null differ diff --git a/assets/icons/favicon/complete.png b/assets/icons/favicon/complete.png deleted file mode 100644 index eb322db..0000000 Binary files a/assets/icons/favicon/complete.png and /dev/null differ diff --git a/assets/icons/favicon/dashboard.png b/assets/icons/favicon/dashboard.png deleted file mode 100644 index d3d90c8..0000000 Binary files a/assets/icons/favicon/dashboard.png and /dev/null differ diff --git a/assets/icons/favicon/debug.png b/assets/icons/favicon/debug.png deleted file mode 100644 index fe52f23..0000000 Binary files a/assets/icons/favicon/debug.png and /dev/null differ diff --git a/assets/icons/favicon/delete.png b/assets/icons/favicon/delete.png deleted file mode 100644 index 17cd8a3..0000000 Binary files a/assets/icons/favicon/delete.png and /dev/null differ diff --git a/assets/icons/favicon/disclaimers.png b/assets/icons/favicon/disclaimers.png deleted file mode 100644 index 079fcab..0000000 Binary files a/assets/icons/favicon/disclaimers.png and /dev/null differ diff --git a/assets/icons/favicon/docs.png b/assets/icons/favicon/docs.png deleted file mode 100644 index 8e1d623..0000000 Binary files a/assets/icons/favicon/docs.png and /dev/null differ diff --git a/assets/icons/favicon/down.png b/assets/icons/favicon/down.png deleted file mode 100644 index 0a91c5c..0000000 Binary files a/assets/icons/favicon/down.png and /dev/null differ diff --git a/assets/icons/favicon/emergency.png b/assets/icons/favicon/emergency.png deleted file mode 100644 index 2e9a5fb..0000000 Binary files a/assets/icons/favicon/emergency.png and /dev/null differ diff --git a/assets/icons/favicon/form.png b/assets/icons/favicon/form.png deleted file mode 100644 index 0e00af6..0000000 Binary files a/assets/icons/favicon/form.png and /dev/null differ diff --git a/assets/icons/favicon/fronting.png b/assets/icons/favicon/fronting.png deleted file mode 100644 index 581ee43..0000000 Binary files a/assets/icons/favicon/fronting.png and /dev/null differ diff --git a/assets/icons/favicon/global.png b/assets/icons/favicon/global.png deleted file mode 100644 index 9509623..0000000 Binary files a/assets/icons/favicon/global.png and /dev/null differ diff --git a/assets/icons/favicon/history.png b/assets/icons/favicon/history.png deleted file mode 100644 index 7c71320..0000000 Binary files a/assets/icons/favicon/history.png and /dev/null differ diff --git a/assets/icons/favicon/home.png b/assets/icons/favicon/home.png deleted file mode 100644 index 70ddef5..0000000 Binary files a/assets/icons/favicon/home.png and /dev/null differ diff --git a/assets/icons/favicon/login.png b/assets/icons/favicon/login.png deleted file mode 100644 index b5dfb88..0000000 Binary files a/assets/icons/favicon/login.png and /dev/null differ diff --git a/assets/icons/favicon/logout.png b/assets/icons/favicon/logout.png deleted file mode 100644 index 8481793..0000000 Binary files a/assets/icons/favicon/logout.png and /dev/null differ diff --git a/assets/icons/favicon/nicknames.png b/assets/icons/favicon/nicknames.png deleted file mode 100644 index cb66338..0000000 Binary files a/assets/icons/favicon/nicknames.png and /dev/null differ diff --git a/assets/icons/favicon/none.png b/assets/icons/favicon/none.png deleted file mode 100644 index e17635e..0000000 Binary files a/assets/icons/favicon/none.png and /dev/null differ diff --git a/assets/icons/favicon/page.png b/assets/icons/favicon/page.png deleted file mode 100644 index 38ef4b4..0000000 Binary files a/assets/icons/favicon/page.png and /dev/null differ diff --git a/assets/icons/favicon/parser.png b/assets/icons/favicon/parser.png deleted file mode 100644 index 980aec8..0000000 Binary files a/assets/icons/favicon/parser.png and /dev/null differ diff --git a/assets/icons/favicon/partial.png b/assets/icons/favicon/partial.png deleted file mode 100644 index 9715809..0000000 Binary files a/assets/icons/favicon/partial.png and /dev/null differ diff --git a/assets/icons/favicon/pleasure-0.png b/assets/icons/favicon/pleasure-0.png new file mode 100644 index 0000000..41ddd7d Binary files /dev/null and b/assets/icons/favicon/pleasure-0.png differ diff --git a/assets/icons/favicon/pleasure-1.png b/assets/icons/favicon/pleasure-1.png new file mode 100644 index 0000000..2c3f614 Binary files /dev/null and b/assets/icons/favicon/pleasure-1.png differ diff --git a/assets/icons/favicon/pleasure.png b/assets/icons/favicon/pleasure.png deleted file mode 100644 index 71cd148..0000000 Binary files a/assets/icons/favicon/pleasure.png and /dev/null differ diff --git a/assets/icons/favicon/prefix-0.png b/assets/icons/favicon/prefix-0.png new file mode 100644 index 0000000..890c978 Binary files /dev/null and b/assets/icons/favicon/prefix-0.png differ diff --git a/assets/icons/favicon/prefix-1.png b/assets/icons/favicon/prefix-1.png new file mode 100644 index 0000000..9309529 Binary files /dev/null and b/assets/icons/favicon/prefix-1.png differ diff --git a/assets/icons/favicon/prefix.png b/assets/icons/favicon/prefix.png deleted file mode 100644 index 0183a06..0000000 Binary files a/assets/icons/favicon/prefix.png and /dev/null differ diff --git a/assets/icons/favicon/relations-0.png b/assets/icons/favicon/relations-0.png new file mode 100644 index 0000000..e6a716a Binary files /dev/null and b/assets/icons/favicon/relations-0.png differ diff --git a/assets/icons/favicon/relations-1.png b/assets/icons/favicon/relations-1.png new file mode 100644 index 0000000..9309529 Binary files /dev/null and b/assets/icons/favicon/relations-1.png differ diff --git a/assets/icons/favicon/relations.png b/assets/icons/favicon/relations.png deleted file mode 100644 index eb7cea9..0000000 Binary files a/assets/icons/favicon/relations.png and /dev/null differ diff --git a/assets/icons/favicon/right-0.png b/assets/icons/favicon/right-0.png new file mode 100644 index 0000000..d656072 Binary files /dev/null and b/assets/icons/favicon/right-0.png differ diff --git a/assets/icons/favicon/right-1.png b/assets/icons/favicon/right-1.png new file mode 100644 index 0000000..9309529 Binary files /dev/null and b/assets/icons/favicon/right-1.png differ diff --git a/assets/icons/favicon/right.png b/assets/icons/favicon/right.png deleted file mode 100644 index 310abc7..0000000 Binary files a/assets/icons/favicon/right.png and /dev/null differ diff --git a/assets/icons/favicon/rules-0.png b/assets/icons/favicon/rules-0.png new file mode 100644 index 0000000..f1ce107 Binary files /dev/null and b/assets/icons/favicon/rules-0.png differ diff --git a/assets/icons/favicon/rules-1.png b/assets/icons/favicon/rules-1.png new file mode 100644 index 0000000..9309529 Binary files /dev/null and b/assets/icons/favicon/rules-1.png differ diff --git a/assets/icons/favicon/rules.png b/assets/icons/favicon/rules.png deleted file mode 100644 index cdfd45a..0000000 Binary files a/assets/icons/favicon/rules.png and /dev/null differ diff --git a/assets/icons/favicon/score-0.png b/assets/icons/favicon/score-0.png new file mode 100644 index 0000000..4aa9f70 Binary files /dev/null and b/assets/icons/favicon/score-0.png differ diff --git a/assets/icons/favicon/score-1.png b/assets/icons/favicon/score-1.png new file mode 100644 index 0000000..9309529 Binary files /dev/null and b/assets/icons/favicon/score-1.png differ diff --git a/assets/icons/favicon/score.png b/assets/icons/favicon/score.png deleted file mode 100644 index cd4c297..0000000 Binary files a/assets/icons/favicon/score.png and /dev/null differ diff --git a/assets/icons/favicon/shield-0.png b/assets/icons/favicon/shield-0.png new file mode 100644 index 0000000..6ecfe5e Binary files /dev/null and b/assets/icons/favicon/shield-0.png differ diff --git a/assets/icons/favicon/shield-1.png b/assets/icons/favicon/shield-1.png new file mode 100644 index 0000000..fd4b6da Binary files /dev/null and b/assets/icons/favicon/shield-1.png differ diff --git a/assets/icons/favicon/shield.png b/assets/icons/favicon/shield.png deleted file mode 100644 index 4574d62..0000000 Binary files a/assets/icons/favicon/shield.png and /dev/null differ diff --git a/assets/icons/favicon/species-0.png b/assets/icons/favicon/species-0.png new file mode 100644 index 0000000..fa5d95f Binary files /dev/null and b/assets/icons/favicon/species-0.png differ diff --git a/assets/icons/favicon/species-1.png b/assets/icons/favicon/species-1.png new file mode 100644 index 0000000..fd4b6da Binary files /dev/null and b/assets/icons/favicon/species-1.png differ diff --git a/assets/icons/favicon/species.png b/assets/icons/favicon/species.png deleted file mode 100644 index 770b510..0000000 Binary files a/assets/icons/favicon/species.png and /dev/null differ diff --git a/assets/icons/favicon/splitting-0.png b/assets/icons/favicon/splitting-0.png new file mode 100644 index 0000000..91d1c5c Binary files /dev/null and b/assets/icons/favicon/splitting-0.png differ diff --git a/assets/icons/favicon/splitting-1.png b/assets/icons/favicon/splitting-1.png new file mode 100644 index 0000000..fd4b6da Binary files /dev/null and b/assets/icons/favicon/splitting-1.png differ diff --git a/assets/icons/favicon/splitting.png b/assets/icons/favicon/splitting.png deleted file mode 100644 index afe2736..0000000 Binary files a/assets/icons/favicon/splitting.png and /dev/null differ diff --git a/assets/icons/favicon/stats-0.png b/assets/icons/favicon/stats-0.png new file mode 100644 index 0000000..f379879 Binary files /dev/null and b/assets/icons/favicon/stats-0.png differ diff --git a/assets/icons/favicon/stats-1.png b/assets/icons/favicon/stats-1.png new file mode 100644 index 0000000..fd4b6da Binary files /dev/null and b/assets/icons/favicon/stats-1.png differ diff --git a/assets/icons/favicon/terminology-0.png b/assets/icons/favicon/terminology-0.png new file mode 100644 index 0000000..cb4ae80 Binary files /dev/null and b/assets/icons/favicon/terminology-0.png differ diff --git a/assets/icons/favicon/terminology-1.png b/assets/icons/favicon/terminology-1.png new file mode 100644 index 0000000..fd4b6da Binary files /dev/null and b/assets/icons/favicon/terminology-1.png differ diff --git a/assets/icons/favicon/terminology.png b/assets/icons/favicon/terminology.png deleted file mode 100644 index 96bb455..0000000 Binary files a/assets/icons/favicon/terminology.png and /dev/null differ diff --git a/assets/icons/favicon/together-0.png b/assets/icons/favicon/together-0.png new file mode 100644 index 0000000..f48cb1a Binary files /dev/null and b/assets/icons/favicon/together-0.png differ diff --git a/assets/icons/favicon/together-1.png b/assets/icons/favicon/together-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/together-1.png differ diff --git a/assets/icons/favicon/together.png b/assets/icons/favicon/together.png deleted file mode 100644 index 98153e9..0000000 Binary files a/assets/icons/favicon/together.png and /dev/null differ diff --git a/assets/icons/favicon/toys-0.png b/assets/icons/favicon/toys-0.png new file mode 100644 index 0000000..2e2703a Binary files /dev/null and b/assets/icons/favicon/toys-0.png differ diff --git a/assets/icons/favicon/toys-1.png b/assets/icons/favicon/toys-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/toys-1.png differ diff --git a/assets/icons/favicon/toys.png b/assets/icons/favicon/toys.png deleted file mode 100644 index 43f7ad9..0000000 Binary files a/assets/icons/favicon/toys.png and /dev/null differ diff --git a/assets/icons/favicon/travel-0.png b/assets/icons/favicon/travel-0.png new file mode 100644 index 0000000..a8894fe Binary files /dev/null and b/assets/icons/favicon/travel-0.png differ diff --git a/assets/icons/favicon/travel-1.png b/assets/icons/favicon/travel-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/travel-1.png differ diff --git a/assets/icons/favicon/travel.png b/assets/icons/favicon/travel.png deleted file mode 100644 index af9cfc9..0000000 Binary files a/assets/icons/favicon/travel.png and /dev/null differ diff --git a/assets/icons/favicon/travelling-0.png b/assets/icons/favicon/travelling-0.png new file mode 100644 index 0000000..bd38437 Binary files /dev/null and b/assets/icons/favicon/travelling-0.png differ diff --git a/assets/icons/favicon/travelling-1.png b/assets/icons/favicon/travelling-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/travelling-1.png differ diff --git a/assets/icons/favicon/travelling.png b/assets/icons/favicon/travelling.png deleted file mode 100644 index 582e1fd..0000000 Binary files a/assets/icons/favicon/travelling.png and /dev/null differ diff --git a/assets/icons/favicon/tree-0.png b/assets/icons/favicon/tree-0.png new file mode 100644 index 0000000..5dd2df5 Binary files /dev/null and b/assets/icons/favicon/tree-0.png differ diff --git a/assets/icons/favicon/tree-1.png b/assets/icons/favicon/tree-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/tree-1.png differ diff --git a/assets/icons/favicon/tree.png b/assets/icons/favicon/tree.png deleted file mode 100644 index 2041ab5..0000000 Binary files a/assets/icons/favicon/tree.png and /dev/null differ diff --git a/assets/icons/favicon/up-0.png b/assets/icons/favicon/up-0.png new file mode 100644 index 0000000..400f4cd Binary files /dev/null and b/assets/icons/favicon/up-0.png differ diff --git a/assets/icons/favicon/up-1.png b/assets/icons/favicon/up-1.png new file mode 100644 index 0000000..d20f64b Binary files /dev/null and b/assets/icons/favicon/up-1.png differ diff --git a/assets/icons/favicon/up.png b/assets/icons/favicon/up.png deleted file mode 100644 index e036bfd..0000000 Binary files a/assets/icons/favicon/up.png and /dev/null differ diff --git a/assets/icons/favicon/user-0.png b/assets/icons/favicon/user-0.png new file mode 100644 index 0000000..0b30ce7 Binary files /dev/null and b/assets/icons/favicon/user-0.png differ diff --git a/assets/icons/favicon/user-1.png b/assets/icons/favicon/user-1.png new file mode 100644 index 0000000..1c7cf77 Binary files /dev/null and b/assets/icons/favicon/user-1.png differ diff --git a/assets/icons/favicon/user.png b/assets/icons/favicon/user.png deleted file mode 100644 index af87990..0000000 Binary files a/assets/icons/favicon/user.png and /dev/null differ diff --git a/assets/icons/favicon/visibility-depends-0.png b/assets/icons/favicon/visibility-depends-0.png new file mode 100644 index 0000000..9481aae Binary files /dev/null and b/assets/icons/favicon/visibility-depends-0.png differ diff --git a/assets/icons/favicon/visibility-depends-1.png b/assets/icons/favicon/visibility-depends-1.png new file mode 100644 index 0000000..1c7cf77 Binary files /dev/null and b/assets/icons/favicon/visibility-depends-1.png differ diff --git a/assets/icons/favicon/visibility-depends.png b/assets/icons/favicon/visibility-depends.png deleted file mode 100644 index 1601ee9..0000000 Binary files a/assets/icons/favicon/visibility-depends.png and /dev/null differ diff --git a/assets/icons/favicon/visibility-private-0.png b/assets/icons/favicon/visibility-private-0.png new file mode 100644 index 0000000..cb5616b Binary files /dev/null and b/assets/icons/favicon/visibility-private-0.png differ diff --git a/assets/icons/favicon/visibility-private-1.png b/assets/icons/favicon/visibility-private-1.png new file mode 100644 index 0000000..1c7cf77 Binary files /dev/null and b/assets/icons/favicon/visibility-private-1.png differ diff --git a/assets/icons/favicon/visibility-private.png b/assets/icons/favicon/visibility-private.png deleted file mode 100644 index 1fea0f6..0000000 Binary files a/assets/icons/favicon/visibility-private.png and /dev/null differ diff --git a/assets/icons/favicon/visibility-public-0.png b/assets/icons/favicon/visibility-public-0.png new file mode 100644 index 0000000..e5088f4 Binary files /dev/null and b/assets/icons/favicon/visibility-public-0.png differ diff --git a/assets/icons/favicon/visibility-public-1.png b/assets/icons/favicon/visibility-public-1.png new file mode 100644 index 0000000..1c7cf77 Binary files /dev/null and b/assets/icons/favicon/visibility-public-1.png differ diff --git a/assets/icons/favicon/visibility-public.png b/assets/icons/favicon/visibility-public.png deleted file mode 100644 index 0b24f95..0000000 Binary files a/assets/icons/favicon/visibility-public.png and /dev/null differ diff --git a/assets/icons/favicon/wakeup-0.png b/assets/icons/favicon/wakeup-0.png new file mode 100644 index 0000000..cb5b690 Binary files /dev/null and b/assets/icons/favicon/wakeup-0.png differ diff --git a/assets/icons/favicon/wakeup-1.png b/assets/icons/favicon/wakeup-1.png new file mode 100644 index 0000000..1c7cf77 Binary files /dev/null and b/assets/icons/favicon/wakeup-1.png differ diff --git a/assets/icons/favicon/wakeup.png b/assets/icons/favicon/wakeup.png deleted file mode 100644 index 966d4fa..0000000 Binary files a/assets/icons/favicon/wakeup.png and /dev/null differ diff --git a/assets/icons/form.svg b/assets/icons/form.svg index b1e150f..9f7c290 100644 --- a/assets/icons/form.svg +++ b/assets/icons/form.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/fronting.svg b/assets/icons/fronting.svg index 842f6cc..9c29c07 100644 --- a/assets/icons/fronting.svg +++ b/assets/icons/fronting.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/global.svg b/assets/icons/global.svg index 1872822..f5a35c3 100644 --- a/assets/icons/global.svg +++ b/assets/icons/global.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/government.svg b/assets/icons/government.svg new file mode 100644 index 0000000..1de282c --- /dev/null +++ b/assets/icons/government.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/history.svg b/assets/icons/history.svg index 96f25f0..47fc198 100644 --- a/assets/icons/history.svg +++ b/assets/icons/history.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/home.svg b/assets/icons/home.svg index 5b58c4a..c8e4131 100644 --- a/assets/icons/home.svg +++ b/assets/icons/home.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/icongen.js b/assets/icons/icongen.js index 694b063..1d591bf 100644 --- a/assets/icons/icongen.js +++ b/assets/icons/icongen.js @@ -7,9 +7,15 @@ let files = fs.readdirSync(".").filter(i => i.endsWith(".svg")); for (let file of files) { let name = file.substring(0, file.length - path.extname(file).length); - console.log(name); - exec("convert -density 1200 -resize 1000x1000 -channel RGB -depth 32 -negate -background none " + file + " ./favicon/" + name + "-pre.png"); - exec("convert -composite -compose Dst_Over -gravity center -depth 32 -geometry 1026x1026 ./favicon/" + name + "-pre.png ../logo/logo-template.png -set colorspace RGB ./favicon/" + name + ".png"); + if (fs.existsSync("./uncolored/" + name + ".svg")) { + console.log(name + "*"); + exec("convert -density 1200 -resize 448x448 -border 56x56 -bordercolor \"rgba(0,0,0,0)\" -channel RGB -depth 32 -negate -background none ./uncolored/" + file + " ./favicon/" + name + "-pre.png"); + exec("convert -composite -compose Dst_Over -gravity center -depth 32 -geometry 512x512 ./favicon/" + name + "-pre.png ../logo/newlogo-template.png -set colorspace RGB ./favicon/" + name + ".png"); + } else { + console.log(name); + exec("convert -density 1200 -resize 448x448 -border 56x56 -bordercolor \"rgba(0,0,0,0)\" -channel RGB -depth 32 -negate -background none " + file + " ./favicon/" + name + "-pre.png"); + exec("convert -composite -compose Dst_Over -gravity center -depth 32 -geometry 512x512 ./favicon/" + name + "-pre.png ../logo/newlogo-template.png -set colorspace RGB ./favicon/" + name + ".png"); + } fs.unlinkSync("./favicon/" + name + "-pre.png"); } \ No newline at end of file diff --git a/assets/icons/login.svg b/assets/icons/login.svg index 87d1622..d9a3995 100644 --- a/assets/icons/login.svg +++ b/assets/icons/login.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/logout.svg b/assets/icons/logout.svg index bbaddd0..47dcaff 100644 --- a/assets/icons/logout.svg +++ b/assets/icons/logout.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/nicknames.svg b/assets/icons/nicknames.svg index f1eef81..dab78cb 100644 --- a/assets/icons/nicknames.svg +++ b/assets/icons/nicknames.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/none.svg b/assets/icons/none.svg index db37798..62554a8 100644 --- a/assets/icons/none.svg +++ b/assets/icons/none.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/page.svg b/assets/icons/page.svg index 73094b6..b6721e6 100644 --- a/assets/icons/page.svg +++ b/assets/icons/page.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/parser.svg b/assets/icons/parser.svg index 7819a5a..94c2068 100644 --- a/assets/icons/parser.svg +++ b/assets/icons/parser.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/partial.svg b/assets/icons/partial.svg index d5411ee..0daec8d 100644 --- a/assets/icons/partial.svg +++ b/assets/icons/partial.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/pleasure.svg b/assets/icons/pleasure.svg index ff335e4..1ed49ed 100644 --- a/assets/icons/pleasure.svg +++ b/assets/icons/pleasure.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/prefix.svg b/assets/icons/prefix.svg index 1e73b37..b1b71db 100644 --- a/assets/icons/prefix.svg +++ b/assets/icons/prefix.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/relations.svg b/assets/icons/relations.svg index 8c51f14..14a54ad 100644 --- a/assets/icons/relations.svg +++ b/assets/icons/relations.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/right.svg b/assets/icons/right.svg index 3c933cf..3d68582 100644 --- a/assets/icons/right.svg +++ b/assets/icons/right.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/rules.svg b/assets/icons/rules.svg index 633f0b2..1dcb80a 100644 --- a/assets/icons/rules.svg +++ b/assets/icons/rules.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/score.svg b/assets/icons/score.svg index 742e211..fce0154 100644 --- a/assets/icons/score.svg +++ b/assets/icons/score.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/shield.svg b/assets/icons/shield.svg index 3e875bd..fe17693 100644 --- a/assets/icons/shield.svg +++ b/assets/icons/shield.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/species.svg b/assets/icons/species.svg index aede58d..2a885c3 100644 --- a/assets/icons/species.svg +++ b/assets/icons/species.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/splitting.svg b/assets/icons/splitting.svg index b1e150f..9f7c290 100644 --- a/assets/icons/splitting.svg +++ b/assets/icons/splitting.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/stats.svg b/assets/icons/stats.svg new file mode 100644 index 0000000..ed35af6 --- /dev/null +++ b/assets/icons/stats.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/terminology.svg b/assets/icons/terminology.svg index c9d1247..dd8771b 100644 --- a/assets/icons/terminology.svg +++ b/assets/icons/terminology.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/together.svg b/assets/icons/together.svg index e63da95..8353168 100644 --- a/assets/icons/together.svg +++ b/assets/icons/together.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/toys.svg b/assets/icons/toys.svg index 3fcc608..f21b085 100644 --- a/assets/icons/toys.svg +++ b/assets/icons/toys.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/travel.svg b/assets/icons/travel.svg index f2b1f9d..c41a26b 100644 --- a/assets/icons/travel.svg +++ b/assets/icons/travel.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/travelling.svg b/assets/icons/travelling.svg index f2b1f9d..4e701a8 100644 --- a/assets/icons/travelling.svg +++ b/assets/icons/travelling.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/tree.svg b/assets/icons/tree.svg index a0718e3..9c675fe 100644 --- a/assets/icons/tree.svg +++ b/assets/icons/tree.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/uncolored/complete.svg b/assets/icons/uncolored/complete.svg new file mode 100644 index 0000000..0cb3ff6 --- /dev/null +++ b/assets/icons/uncolored/complete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/uncolored/emergency.svg b/assets/icons/uncolored/emergency.svg new file mode 100644 index 0000000..27fc1b1 --- /dev/null +++ b/assets/icons/uncolored/emergency.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/uncolored/none.svg b/assets/icons/uncolored/none.svg new file mode 100644 index 0000000..edb63f7 --- /dev/null +++ b/assets/icons/uncolored/none.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/uncolored/partial.svg b/assets/icons/uncolored/partial.svg new file mode 100644 index 0000000..566d1eb --- /dev/null +++ b/assets/icons/uncolored/partial.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/uncolored/pleasure.svg b/assets/icons/uncolored/pleasure.svg new file mode 100644 index 0000000..4f2d0d7 --- /dev/null +++ b/assets/icons/uncolored/pleasure.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/uncolored/wakeup.svg b/assets/icons/uncolored/wakeup.svg new file mode 100644 index 0000000..e6b23f2 --- /dev/null +++ b/assets/icons/uncolored/wakeup.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/up.svg b/assets/icons/up.svg index eaae635..094d395 100644 --- a/assets/icons/up.svg +++ b/assets/icons/up.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/user.svg b/assets/icons/user.svg index 2540260..45d534d 100644 --- a/assets/icons/user.svg +++ b/assets/icons/user.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/visibility-depends.svg b/assets/icons/visibility-depends.svg index a94d92b..03aac83 100644 --- a/assets/icons/visibility-depends.svg +++ b/assets/icons/visibility-depends.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/visibility-private.svg b/assets/icons/visibility-private.svg index 717077d..5572b92 100644 --- a/assets/icons/visibility-private.svg +++ b/assets/icons/visibility-private.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/visibility-public.svg b/assets/icons/visibility-public.svg index 1872822..426047e 100644 --- a/assets/icons/visibility-public.svg +++ b/assets/icons/visibility-public.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/wakeup.svg b/assets/icons/wakeup.svg index 701611c..0f1c507 100644 --- a/assets/icons/wakeup.svg +++ b/assets/icons/wakeup.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/logo/newlogo-template.png b/assets/logo/newlogo-template.png new file mode 100644 index 0000000..36dfc83 Binary files /dev/null and b/assets/logo/newlogo-template.png differ diff --git a/assets/logo/newlogo.png b/assets/logo/newlogo.png new file mode 100644 index 0000000..7b5922d Binary files /dev/null and b/assets/logo/newlogo.png differ diff --git a/assets/uploads/pt-applebloom.png b/assets/uploads/pt-applebloom.png new file mode 100644 index 0000000..35f844f Binary files /dev/null and b/assets/uploads/pt-applebloom.png differ diff --git a/assets/uploads/pt-izzy.png b/assets/uploads/pt-izzy.png deleted file mode 100644 index e01ab3b..0000000 Binary files a/assets/uploads/pt-izzy.png and /dev/null differ diff --git a/assets/uploads/pt-izzymoonbow.png b/assets/uploads/pt-izzymoonbow.png new file mode 100644 index 0000000..e01ab3b Binary files /dev/null and b/assets/uploads/pt-izzymoonbow.png differ diff --git a/assets/uploads/pt-mistybrightdawn.png b/assets/uploads/pt-mistybrightdawn.png new file mode 100644 index 0000000..3afb56c Binary files /dev/null and b/assets/uploads/pt-mistybrightdawn.png differ diff --git a/assets/uploads/pt-scootaloo.png b/assets/uploads/pt-scootaloo.png index 591c35e..436d6a3 100644 Binary files a/assets/uploads/pt-scootaloo.png and b/assets/uploads/pt-scootaloo.png differ diff --git a/assets/uploads/pt-thunder.png b/assets/uploads/pt-thunder.png new file mode 100644 index 0000000..48ed462 Binary files /dev/null and b/assets/uploads/pt-thunder.png differ diff --git a/assets/uploads/pt-zoomzephyrwing.png b/assets/uploads/pt-zoomzephyrwing.png new file mode 100644 index 0000000..e75a6c3 Binary files /dev/null and b/assets/uploads/pt-zoomzephyrwing.png differ diff --git a/autoschedule/main.php b/autoschedule/main.php index 892ea02..e3ae2bf 100644 --- a/autoschedule/main.php +++ b/autoschedule/main.php @@ -2,9 +2,9 @@ $_SERVER['DOCUMENT_ROOT'] = ".."; -require_once "../includes/score.php"; -require_once "../includes/bitset.php"; -require_once "../includes/functions.php"; +require_once "../includes/score.inc"; +require_once "../includes/bitset.inc"; +require_once "../includes/functions.inc"; $days = []; $today_date = date('Y-m-d', time() + 86400); @@ -172,6 +172,7 @@ foreach (scoreOrderGlobal() as $pony) { ]; } +$runs = 0; while (!$correct) { $ponies = []; $fixed = false; @@ -270,6 +271,12 @@ while (!$correct) { } if (!$fixed) $correct = true; + + if ($runs > 8) { + $correct = true; + } + + $runs++; } echo("--------------\n"); diff --git a/autoschedule/ponies.php b/autoschedule/ponies.php index 3346452..d16e701 100644 --- a/autoschedule/ponies.php +++ b/autoschedule/ponies.php @@ -4,14 +4,14 @@ global $ponies_raindrops; global $ponies_cloudburst; global $weekend; -$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json"), true); +$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling/travelling.json"), true); function ponies(string $system): array { global $travelling; global $weekend; return array_map(function ($i) use ($system, $weekend) { - $switches = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-switches.json"), true); + $switches = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/switches.json"), true); $memberData = $i; $i["_lastFronted"] = -1; @@ -53,7 +53,7 @@ function ponies(string $system): array { $fronters = array_map(function ($item) { return $item["id"]; - }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-fronters.json"), true)["members"]); + }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/fronters.json"), true)["members"]); if (in_array($id, $fronters)) { $i["_lastFronted"] = time(); diff --git a/includes/ai.inc b/includes/ai.inc new file mode 100644 index 0000000..8f5f7ba --- /dev/null +++ b/includes/ai.inc @@ -0,0 +1,311 @@ + $metadata["robot"] ? + "robot earth pony" : + (!$metadata["plush"] ? "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : + "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), + "alicorn" => $metadata["robot"] ? + "robot alicorn" : + (!$metadata["plush"] ? "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : + "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), + "crystal" => $metadata["robot"] ? + "robot crystal pony" : + (!$metadata["plush"] ? "crystal pony" : + "crystal pony plush"), + "pegasus" => $metadata["robot"] ? + "robot pegasus" : + (!$metadata["plush"] ? "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : + "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), + "batpony" => $metadata["robot"] ? + "robot batpony" : + (!$metadata["plush"] ? "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : + "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), + "unicorn" => $metadata["robot"] ? + "robot unicorn" : + (!$metadata["plush"] ? "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : + "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), + default => $species . "_" . $metadata["robot"] + }; + } +} + +if (!function_exists("listing")) { + function listing(array $list): string { + $out = ""; + + foreach (array_values($list) as $index => $value) { + $mem = getSystemMember(explode("/", $value)[0], explode("/", $value)[1]); + $value = "" . getMiniName($mem["display_name"] ?? $mem["name"]) . ""; + + if ($index === 0) { + $out = $value; + } else if ($index < count(array_values($list)) - 1) { + $out .= ", " . $value; + } else { + $out .= " and " . $value; + } + } + + return $out; + } +} + +$iam = 0; +$multipleNames = count(explode("/", $memberData["display_name"])) > 1; + +$otherNames = explode("/", $memberData["display_name"]); +array_shift($otherNames); + +if ($memberData["name"] === "scootaloo" && ((int)date('N') - 1) % 2 === 0) { + $metadata["marefriends"] = array_reverse($metadata["marefriends"]); +} + +?> + + +

+ + Hello, + + Hi, + + Hey, + + Hey there!

+ + + + , + + + +the most common fronter +a protector + +of the , + 0): $source = getMember($metadata["median"]); ?> ">, + = 3) ? "and" : (component(2, 2, 1) ? "I'm" : "I am") ?> + + += 3 && component(2, 1, 4)): ?>also + +a and a + +a , a and a + +a = 3 && component(2, 2, 4)): ?> too +, +. + +

+ +

+ + + + Depending on the circumstances, I may not share memories with my headmates + + I may not share memories with my headmates depending on the circumstances + + I sometimes share memories with my headmates + + + + I share memories with my headmates + + I have access to my headmates' memories + + I have access to my headmates' memories + + + + + + + a fictive + + from Equestria + + I come from Equestria + + + + + + + fronting less often + + less often at front + + I like to front less often + + + + + + + nonverbal in real life + + not talking in real life + + I don't talk in real life + + + + + + + 0): ?> + an age regressor + + 0): ?> + capable of age regression + + I can age regress + + + + + + + 0): ?> + younger than the body is + + 0): ?> + younger but not enough to be considered a little + + I feel younger than my headmates + + + + + 0)): ?> + + 0): ?> + affected by spells to make me feel younger + + 0): ?> + affected by age spells + + age regression spells can affect me + + + + + + + 0): ?> + a lot younger than the body is + + 0): ?> + a little + + I feel a lot younger than my headmates + + + +

+ +

+ + + 0): ?> + + 0): ?> + 1): ?>in relationships within a relationship with + + 0): ?> + 1): ?>My marefriends areMy marefriend is + + 0): ?> + 1): ?>are my marefriendsis my marefriend + + I love + + + + + 0): ?> + + 0): ?> + 1): ?>in relationships within a relationship with + + 0): ?> + 1): ?> sisters are sister is + + 0): ?> + 1): ?>are my sistersis my sister + + + I also love as sister 1): ?>s + + 1): ?>are my familyis my family + + + + + + 0): ?> + + 0): ?> + being taken care of by + + 0): ?> + 1): ?> mares who take care of me are mare who takes care of me is + + 0): ?> + 1): ?>are my caretakersis my caretaker + + + I like having take care of me + + take care of me + + + + +

\ No newline at end of file diff --git a/includes/ai.php b/includes/ai.php deleted file mode 100644 index 8f5f7ba..0000000 --- a/includes/ai.php +++ /dev/null @@ -1,311 +0,0 @@ - $metadata["robot"] ? - "robot earth pony" : - (!$metadata["plush"] ? "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : - "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), - "alicorn" => $metadata["robot"] ? - "robot alicorn" : - (!$metadata["plush"] ? "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : - "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), - "crystal" => $metadata["robot"] ? - "robot crystal pony" : - (!$metadata["plush"] ? "crystal pony" : - "crystal pony plush"), - "pegasus" => $metadata["robot"] ? - "robot pegasus" : - (!$metadata["plush"] ? "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : - "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), - "batpony" => $metadata["robot"] ? - "robot batpony" : - (!$metadata["plush"] ? "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : - "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), - "unicorn" => $metadata["robot"] ? - "robot unicorn" : - (!$metadata["plush"] ? "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") : - "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"), - default => $species . "_" . $metadata["robot"] - }; - } -} - -if (!function_exists("listing")) { - function listing(array $list): string { - $out = ""; - - foreach (array_values($list) as $index => $value) { - $mem = getSystemMember(explode("/", $value)[0], explode("/", $value)[1]); - $value = "" . getMiniName($mem["display_name"] ?? $mem["name"]) . ""; - - if ($index === 0) { - $out = $value; - } else if ($index < count(array_values($list)) - 1) { - $out .= ", " . $value; - } else { - $out .= " and " . $value; - } - } - - return $out; - } -} - -$iam = 0; -$multipleNames = count(explode("/", $memberData["display_name"])) > 1; - -$otherNames = explode("/", $memberData["display_name"]); -array_shift($otherNames); - -if ($memberData["name"] === "scootaloo" && ((int)date('N') - 1) % 2 === 0) { - $metadata["marefriends"] = array_reverse($metadata["marefriends"]); -} - -?> - - -

- - Hello, - - Hi, - - Hey, - - Hey there!

- - - - , - - - -the most common fronter -a protector - -of the , - 0): $source = getMember($metadata["median"]); ?> ">, - = 3) ? "and" : (component(2, 2, 1) ? "I'm" : "I am") ?> - - -= 3 && component(2, 1, 4)): ?>also - -a and a - -a , a and a - -a = 3 && component(2, 2, 4)): ?> too -, -. - -

- -

- - - - Depending on the circumstances, I may not share memories with my headmates - - I may not share memories with my headmates depending on the circumstances - - I sometimes share memories with my headmates - - - - I share memories with my headmates - - I have access to my headmates' memories - - I have access to my headmates' memories - - - - - - - a fictive - - from Equestria - - I come from Equestria - - - - - - - fronting less often - - less often at front - - I like to front less often - - - - - - - nonverbal in real life - - not talking in real life - - I don't talk in real life - - - - - - - 0): ?> - an age regressor - - 0): ?> - capable of age regression - - I can age regress - - - - - - - 0): ?> - younger than the body is - - 0): ?> - younger but not enough to be considered a little - - I feel younger than my headmates - - - - - 0)): ?> - - 0): ?> - affected by spells to make me feel younger - - 0): ?> - affected by age spells - - age regression spells can affect me - - - - - - - 0): ?> - a lot younger than the body is - - 0): ?> - a little - - I feel a lot younger than my headmates - - - -

- -

- - - 0): ?> - - 0): ?> - 1): ?>in relationships within a relationship with - - 0): ?> - 1): ?>My marefriends areMy marefriend is - - 0): ?> - 1): ?>are my marefriendsis my marefriend - - I love - - - - - 0): ?> - - 0): ?> - 1): ?>in relationships within a relationship with - - 0): ?> - 1): ?> sisters are sister is - - 0): ?> - 1): ?>are my sistersis my sister - - - I also love as sister 1): ?>s - - 1): ?>are my familyis my family - - - - - - 0): ?> - - 0): ?> - being taken care of by - - 0): ?> - 1): ?> mares who take care of me are mare who takes care of me is - - 0): ?> - 1): ?>are my caretakersis my caretaker - - - I like having take care of me - - take care of me - - - - -

\ No newline at end of file diff --git a/includes/assets.inc b/includes/assets.inc new file mode 100644 index 0000000..9a0a9ac --- /dev/null +++ b/includes/assets.inc @@ -0,0 +1,55 @@ + date('c'), + "files" => [] +]; + +foreach ($root as $file) { + if ($file === "backup.poniesbackup" || $file === "backup.ponieskey" || $file === "encrypted" || str_ends_with($file, ".poniesbackup")) continue; + echo(" /$file\n"); + + if (is_dir("data/$file")) { + foreach (array_filter(scandir("data/$file"), function ($i) { + return !str_starts_with($i, "."); + }) as $dirfile) { + if ($dirfile === "backup.poniesbackup" || $dirfile === "backup.ponieskey" || $dirfile === "encrypted" || str_ends_with($dirfile, ".poniesbackup")) continue; + + echo(" /$dirfile/$file\n"); + $files[] = [ + "dir" => $file, + "file" => $dirfile + ]; + } + } else { + echo(" /$file\n"); + $files[] = [ + "dir" => "", + "file" => $file + ]; + } +} + +echo(" Reading files...\n"); +foreach ($files as $file) { + echo(" /$file[dir]/$file[file]\n"); + $file["mime"] = mime_content_type("data/$file[dir]/$file[file]"); + $file["checksum"] = [ + sha1_file("data/$file[dir]/$file[file]"), + md5_file("data/$file[dir]/$file[file]") + ]; + $file["content"] = base64_encode(file_get_contents("data/$file[dir]/$file[file]")); + + $data["files"][] = $file; +} + +function pkcs7_pad($data, $size) { + $length = $size - strlen($data) % $size; + return $data . str_repeat(chr($length), $length); +} + +if (!file_exists("./data/backup.ponieskey")) { + echo(" Reading encryption key...\n"); + $key = openssl_random_pseudo_bytes(512); + $iv = openssl_random_pseudo_bytes(16); + file_put_contents("./data/backup.ponieskey", base64_encode(json_encode([ + "iv" => bin2hex($iv), + "key" => bin2hex($key) + ]))); +} else { + echo(" Creating encryption key...\n"); + $key_raw = json_decode(base64_decode(file_get_contents("./data/backup.ponieskey")), true); + $key = hex2bin($key_raw["key"]); + $iv = hex2bin($key_raw["iv"]); +} + +echo(" Encrypting...\n"); +$payload = json_encode($data); +$encrypted = openssl_encrypt(pkcs7_pad($payload, 16), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); + +echo(" Writing backup...\n"); +file_put_contents("./data/backup.poniesbackup", $encrypted); +@mkdir("./data/encrypted"); + +$id = str_replace(":", "-", date('c')); +copy("./data/backup.poniesbackup", "./data/encrypted/" . $id . ".poniesbackup"); + +echo(" Uploading to servers...\n"); + +echo(" bridlewood... upload\n"); +exec("scp ./data/encrypted/" . $id . ".poniesbackup fedora@bridlewood.equestria.dev:/opt/ponies"); +echo(" bridlewood... cleaning up\n"); +exec('ssh fedora@bridlewood.equestria.dev bash /opt/clean.sh'); + +echo(" canterlot... upload\n"); +exec("scp ./data/encrypted/" . $id . ".poniesbackup root@canterlot.equestria.dev:/opt/ponies"); +echo(" canterlot... cleaning up\n"); +exec('ssh root@canterlot.equestria.dev bash /opt/clean.sh'); + +if (file_exists("/opt/ponies")) { + echo(" zephyrheights... copy\n"); + copy("./data/encrypted/" . $id . ".poniesbackup", "/opt/ponies/" . $id . ".poniesbackup"); + echo(" zephyrheights... cleaning up\n"); + exec('bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"'); +} + +echo(" Cleaning up...\n"); +unlink("./data/encrypted/" . $id . ".poniesbackup"); \ No newline at end of file diff --git a/includes/backup.php b/includes/backup.php deleted file mode 100644 index ad09617..0000000 --- a/includes/backup.php +++ /dev/null @@ -1,102 +0,0 @@ - date('c'), - "files" => [] -]; - -foreach ($root as $file) { - if ($file === "backup.poniesbackup" || $file === "backup.ponieskey" || $file === "encrypted" || str_ends_with($file, ".poniesbackup")) continue; - echo(" /$file\n"); - - if (is_dir("data/$file")) { - foreach (array_filter(scandir("data/$file"), function ($i) { - return !str_starts_with($i, "."); - }) as $dirfile) { - if ($dirfile === "backup.poniesbackup" || $dirfile === "backup.ponieskey" || $dirfile === "encrypted" || $dirfile === "oldactions" || str_ends_with($dirfile, ".poniesbackup")) continue; - - echo(" /$dirfile/$file\n"); - $files[] = [ - "dir" => $file, - "file" => $dirfile - ]; - } - } else { - echo(" /$file\n"); - $files[] = [ - "dir" => "", - "file" => $file - ]; - } -} - -echo(" Reading files...\n"); -foreach ($files as $file) { - echo(" /$file[dir]/$file[file]\n"); - $file["mime"] = mime_content_type("data/$file[dir]/$file[file]"); - $file["checksum"] = [ - sha1_file("data/$file[dir]/$file[file]"), - md5_file("data/$file[dir]/$file[file]") - ]; - $file["content"] = base64_encode(file_get_contents("data/$file[dir]/$file[file]")); - - $data["files"][] = $file; -} - -function pkcs7_pad($data, $size) { - $length = $size - strlen($data) % $size; - return $data . str_repeat(chr($length), $length); -} - -if (!file_exists("./data/backup.ponieskey")) { - echo(" Reading encryption key...\n"); - $key = openssl_random_pseudo_bytes(512); - $iv = openssl_random_pseudo_bytes(16); - file_put_contents("./data/backup.ponieskey", base64_encode(json_encode([ - "iv" => bin2hex($iv), - "key" => bin2hex($key) - ]))); -} else { - echo(" Creating encryption key...\n"); - $key_raw = json_decode(base64_decode(file_get_contents("./data/backup.ponieskey")), true); - $key = hex2bin($key_raw["key"]); - $iv = hex2bin($key_raw["iv"]); -} - -echo(" Encrypting...\n"); -$payload = json_encode($data); -$encrypted = openssl_encrypt(pkcs7_pad($payload, 16), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); - -echo(" Writing backup...\n"); -file_put_contents("./data/backup.poniesbackup", $encrypted); -@mkdir("./data/encrypted"); - -$id = str_replace(":", "-", date('c')); -copy("./data/backup.poniesbackup", "./data/encrypted/" . $id . ".poniesbackup"); - -echo(" Uploading to servers...\n"); - -echo(" bridlewood... upload\n"); -exec("scp ./data/encrypted/" . $id . ".poniesbackup fedora@bridlewood.equestria.dev:/opt/ponies"); -echo(" bridlewood... cleaning up\n"); -exec('ssh fedora@bridlewood.equestria.dev bash /opt/clean.sh'); - -echo(" canterlot... upload\n"); -exec("scp ./data/encrypted/" . $id . ".poniesbackup root@canterlot.equestria.dev:/opt/ponies"); -echo(" canterlot... cleaning up\n"); -exec('ssh root@canterlot.equestria.dev bash /opt/clean.sh'); - -if (file_exists("/opt/ponies")) { - echo(" zephyrheights... copy\n"); - copy("./data/encrypted/" . $id . ".poniesbackup", "/opt/ponies/" . $id . ".poniesbackup"); - echo(" zephyrheights... cleaning up\n"); - exec('bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"'); -} - -echo(" Cleaning up...\n"); -unlink("./data/encrypted/" . $id . ".poniesbackup"); \ No newline at end of file diff --git a/includes/banner.inc b/includes/banner.inc new file mode 100644 index 0000000..a3c6f10 --- /dev/null +++ b/includes/banner.inc @@ -0,0 +1,456 @@ + 4196352, + "regression" => null, + "median" => null, + "marefriends" => [], + "sisters" => [], + "caretakers" => [] + ]); + + $prefixes = []; + foreach ($member['proxy_tags'] as $proxy) { + if ($travelling[$member['id']]["travelling"]) { + $prefixes[] = "+" . $proxy["prefix"] . ($proxy["suffix"] !== "" && $proxy["suffix"] !== null ? "..." . $proxy["suffix"] : ""); + } else { + $prefixes[] = $proxy["prefix"] . ($proxy["suffix"] !== "" && $proxy["suffix"] !== null ? "..." . $proxy["suffix"] : ""); + } + } + + $lastFronted = null; + if (!$metadata["median"]) { + $fronters = array_map(function ($item) { + return $item["id"]; + }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/fronters.json"), true)["members"]); + + if (in_array($id, $fronters)) { + $lastFronted = [ + 'now' => true, + 'relative' => timeAgo(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/fronters.json"), true)["timestamp"]), + 'absolute' => date("D j M Y, G:i:s (e)", strtotime(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/fronters.json"), true)["timestamp"])), + 'timestamp' => strtotime(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/fronters.json"), true)["timestamp"]), + 'duration' => [ + 'seconds' => null, + 'pretty' => null + ] + ]; + } else { + $switches = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system/switches.json"), true); + + $thisMember = array_filter($switches, function ($item) { + global $memberData; + return in_array($memberData["id"], $item["members"]); + }); + + $thisMember = array_values($thisMember); + $frontingEnd = null; + + if (count($thisMember) > 0) { + $thisIndex = array_search($thisMember[0], $switches); + + $frontingStart = $thisMember[0]; + $frontingEnd = $switches[$thisIndex - 1]; + } + + if ($frontingEnd !== null && isset($frontingStart)) { + $seconds = (strtotime($frontingEnd["timestamp"]) - strtotime($frontingStart["timestamp"])); + + $lastFronted = [ + 'now' => false, + 'relative' => timeAgo($frontingEnd["timestamp"]), + 'absolute' => date("D j M Y, G:i:s (e)", strtotime($frontingEnd["timestamp"])), + 'timestamp' => strtotime($frontingEnd["timestamp"]), + 'duration' => [ + 'seconds' => $seconds, + 'pretty' => $seconds . ($french ? " secondes" : " seconds") + ] + ]; + if ($french) { + if ($seconds > 60) { + if ($seconds > 3600) { + $lastFronted['duration']['pretty'] = round($seconds / 3600) . " heures"; + } else { + $lastFronted['duration']['pretty'] = round($seconds / 60) . " minutes"; + } + } + } else { + if ($seconds > 60) { + if ($seconds > 3600) { + $lastFronted['duration']['pretty'] = round($seconds / 3600) . " hours"; + } else { + $lastFronted['duration']['pretty'] = round($seconds / 60) . " minutes"; + } + } + } + } + } + } + + $speciesList = []; + foreach ($metadata["species"] ?? [] as $species) { + if ($french) { + $name = match ($species) { + "earth" => $metadata["robot"] ? "Robot poney terrestre" : (!$metadata["plush"] ? "Poney terrestre" : "Poney terrestre en peluche"), + "alicorn" => $metadata["robot"] ? "Robot alicorne" : (!$metadata["plush"] ? "Alicorne" : "Alicorne en peluche"), + "crystal" => $metadata["robot"] ? "Robot poney de crystal" : (!$metadata["plush"] ? "Poney de crystal" : "Poney de crystal en peluche"), + "pegasus" => $metadata["robot"] ? "Robot pégase" : (!$metadata["plush"] ? "Pégase" : "Pégase en peluche"), + "batpony" => $metadata["robot"] ? "Robot Poney chauve souris" : (!$metadata["plush"] ? "Poney chauve souris" : "Poney chauve souris en peluche"), + "unicorn" => $metadata["robot"] ? "Robot licorne" : (!$metadata["plush"] ? "Licorne" : "Licorne en peluche"), + default => $species . "_" . $metadata["robot"] + }; + } else { + $name = match ($species) { + "earth" => $metadata["robot"] ? "Robot earth pony" : (!$metadata["plush"] ? "Earth pony" : "Earth pony plush"), + "alicorn" => $metadata["robot"] ? "Robot alicorn" : (!$metadata["plush"] ? "Alicorn" : "Alicorn plush"), + "crystal" => $metadata["robot"] ? "Robot crystal pony" : (!$metadata["plush"] ? "Crystal pony" : "Crystal pony plush"), + "pegasus" => $metadata["robot"] ? "Robot pegasus" : (!$metadata["plush"] ? "Pegasus" : "Pegasus plush"), + "batpony" => $metadata["robot"] ? "Robot bat pony" : (!$metadata["plush"] ? "Bat pony" : "Bat pony plush"), + "unicorn" => $metadata["robot"] ? "Robot unicorn" : (!$metadata["plush"] ? "Unicorn" : "Unicorn plush"), + default => $species . "_" . $metadata["robot"] + }; + } + + $speciesList[] = [ + "id" => $species, + "name" => $name, + "robot" => $metadata["robot"], + "plush" => $metadata["plush"], + "icon" => $species . ($metadata["robot"] ? "-robot" : ($metadata["plush"] ? "-plush" : "")) . ".png" + ]; + } + + $systemData = []; + $systemData['page'] = "/" . ($system === "gdapd" ? "raindrops" : "cloudburst"); + $systemData['icon'] = ($system === "gdapd" ? "raindrops" : "cloudburst") . ".png"; + $systemData['name'] = $system === "gdapd" ? "Raindrops" : "Cloudburst"; + $systemData['full_name'] = $system === "gdapd" ? "Raindrops System" : "Cloudburst System"; + $systemData['subsystem'] = null; + $systemData['temporary'] = false; + + if (_header_memberPartOfSubsystem($member) && _header_getSubsystemFromMember($member)["source_type"] !== "member") { + $subsystem = _header_getSubsystemFromMember($member); + $systemData['subsystem'] = [ + "page" => $systemData['page'] . "/-/subsystem/" . $subsystem["source"], + "icon" => "ss-$subsystem[source].png", + "name" => file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/subsystems/$system-$subsystem[source].json") ? json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/subsystems/$system-$subsystem[source].json"), true)["name"] : $subsystem["source"] + ]; + } + + if ($travelling[$member['id']]["travelling"]) { + $systemData['page'] = "/" . ($system === "gdapd" ? "cloudburst" : "raindrops"); + $systemData['icon'] = getAsset($system); + $systemData['name'] = $system === "gdapd" ? "Cloudburst" : "Raindrops"; + $systemData['full_name'] = $system === "gdapd" ? "Cloudburst System" : "Raindrops System"; + $systemData['subsystem'] = null; + $systemData['temporary'] = true; + } + + $marefriends = []; + foreach ($metadata["marefriends"] as $marefriend) { + $mfSystem = explode("/", $marefriend)[0]; + $mfMemberID = explode("/", $marefriend)[1]; + $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem/members.json"), true), function ($item) use ($mfMemberID) { + return $item["id"] === $mfMemberID; + }); + sort($mfMember); + $mfMember = $mfMember[0]; + + $marefriends[] = [ + "id" => $marefriend, + "link" => "/" . ($mfMember["name"]), + "icon" => getAsset($mfSystem, $mfMemberID, "heads"), + "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), + "full_name" => $mfMember["display_name"] ?? $mfMember["name"] + ]; + } + + $sisters = []; + foreach ($metadata["sisters"] as $marefriend) { + $mfSystem = explode("/", $marefriend)[0]; + $mfMemberID = explode("/", $marefriend)[1]; + $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem/members.json"), true), function ($item) use ($mfMemberID) { + return $item["id"] === $mfMemberID; + }); + sort($mfMember); + $mfMember = $mfMember[0]; + + $sisters[] = [ + "id" => $marefriend, + "link" => "/" . ($mfMember["name"]), + "icon" => getAsset($mfSystem, $mfMemberID, "heads"), + "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), + "full_name" => $mfMember["display_name"] ?? $mfMember["name"] + ]; + } + + $caretakers = null; + + if ($metadata["little"] === 2) { + $caretakers = []; + foreach ($metadata["caretakers"] as $marefriend) { + $mfSystem = explode("/", $marefriend)[0]; + $mfMemberID = explode("/", $marefriend)[1]; + $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem/members.json"), true), function ($item) use ($mfMemberID) { + return $item["id"] === $mfMemberID; + }); + sort($mfMember); + $mfMember = $mfMember[0]; + + $caretakers[] = [ + "id" => $marefriend, + "link" => "/" . ($mfMember["name"]), + "icon" => getAsset($mfSystem, $mfMemberID, "heads"), + "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), + "full_name" => $mfMember["display_name"] ?? $mfMember["name"] + ]; + } + } + + $badges = []; + + if ($metadata["host"] ?? false) { + if (!$travelling[$member['id']]["travelling"]) { + $badges[] = [ + "id" => "mcf", + "color" => "primary", + "html" => ( + $french + ? + 'Fronteuse la plus présente' + : + 'Most common fronter' + ) + ]; + } + } + + if (($metadata["age_spells"] ?? false) && !$french) { + $badges[] = [ + "id" => "age_spells", + "color" => "#6f42c1", + "html" => 'Affected by age spells' + ]; + } + + if ($metadata["fictive"] ?? false) { + $badges[] = [ + "id" => "fictive", + "color" => "info", + "html" => ( + $french + ? + 'Fictive' + : + 'Fictive' + ) + ]; + } + + if ($metadata["less_frequent"] ?? false) { + $badges[] = [ + "id" => "nonverbal", + "color" => "#fd7e14", + "html" => 'Fronts less often' + ]; + } + + if ($metadata["nonverbal"] ?? false) { + $badges[] = [ + "id" => "nonverbal", + "color" => "#20c997", + "html" => 'Non verbal IRL' + ]; + } + + if ($member["name"] === "fusion") { + $badges[] = [ + "id" => "fusion", + "color" => "d63384", + "html" => 'Fusion' + ]; + } + + if (($metadata["sexually_active"] ?? false) && !$french && $isLoggedIn) { + $badges[] = [ + "id" => "sexually_active", + "color" => "d6a833", + "html" => 'Sexually active' + ]; + } + + if ($metadata["protector"] ?? false) { + $badges[] = [ + "id" => "protector", + "color" => "black", + "html" => ( + $french + ? + '
' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($member['pronouns'])["third"] ? "is" : "are") . ' a protector in the system and will front when somepony cannot handle it anymore." class="badge rounded-pill bg-black">' . (getMemberPronouns($member['pronouns'])["gender"] === "female" ? "Protectrice" : (getMemberPronouns($member['pronouns'])["gender"] === "male" ? "Protecteur" : "Protecteur·ice")) . '
' + : + 'Protector' + ) + ]; + } + + if (($metadata["little"] ?? 0) === 2) { + $badges[] = [ + "id" => "little", + "color" => "success", + "html" => ( + $french + ? + '
' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($member['pronouns'])["third"] ? "is" : "are") . ' mentally younger, and therefore behaves and feels younger than the body is." class="badge rounded-pill bg-success">Petit' . (getMemberPronouns($member['pronouns'])["gender"] === "female" ? "e" : (getMemberPronouns($member['pronouns'])["gender"] === "male" ? "" : "·e")) . '
' + : + 'Little' + ) + ]; + } + + if (($metadata["little"] ?? 0) === 3) { + $badges[] = [ + "id" => "younger", + "color" => "dark", + "html" => ( + $french + ? + 'Plus jeune' + : + 'Younger' + ) + ]; + } + + if (($metadata["age_regressor"] ?? false)) { + if ($metadata["regression"] !== null && $metadata["regression"] !== false) { + $regression = _header_getMember($metadata["regression"], $system); + $badges[] = [ + "id" => "regressor_median", + "color" => "secondary", + "html" => ( + $french + ? + 'Régresse en âge en '. (getMiniName($regression["display_name"] ?? $regression["name"])) . '' + : + 'Age regresses into '. (getMiniName($regression["display_name"] ?? $regression["name"])) . '' + ) + ]; + } else { + $badges[] = [ + "id" => "regressor", + "color" => "secondary", + "html" => ( + $french + ? + 'Régresseur d\'âge' + : + 'Age regressor' + ) + ]; + } + } + + if ($metadata["median"] !== null && $metadata["median"] !== false) { + $source = _header_getMember($metadata["median"], $system); + if ($metadata["little"] > 0) { + $badges[] = [ + "id" => "regressed", + "color" => "warning", + "html" => ( + $french + ? + 'Régressé en âge de ' . (getMiniName($source["display_name"] ?? $source["name"])) . '' + : + 'Age regressed from ' . (getMiniName($source["display_name"] ?? $source["name"])) . '' + ) + ]; + } else { + $badges[] = [ + "id" => "facet", + "color" => "light", + "html" => ( + $french + ? + 'Facette de ' . getMiniName($source["display_name"] ?? $source["name"]) . '' + : + 'Facet of ' . getMiniName($source["display_name"] ?? $source["name"]) . '' + ) + ]; + } + } + + return [ + 'id' => $member['name'], + 'color' => $member["color"] ?? "000000", + 'icon' => [ + "online" => getAsset($system, $member["id"]), + "offline" => "pf-$system-$id.webp" + ], + 'median' => $metadata["median"], + 'little' => $metadata["little"] === 2, + 'name' => $member["display_name"] ?? $member["name"], + 'badges' => $badges, + 'prefixes' => $prefixes, + 'pronouns' => getTooltipsFromMark($member["pronouns"], $french) ?? "she/her", + 'pronouns_usage' => getMemberPronouns($member['pronouns']), + 'last_fronted' => $lastFronted, + 'species' => $speciesList, + 'system' => $systemData, + 'relations' => [ + 'marefriends' => $marefriends, + 'sisters' => $sisters, + 'caretakers' => $caretakers + ] + ]; +} \ No newline at end of file diff --git a/includes/banner.php b/includes/banner.php deleted file mode 100644 index 213863a..0000000 --- a/includes/banner.php +++ /dev/null @@ -1,456 +0,0 @@ - 4196352, - "regression" => null, - "median" => null, - "marefriends" => [], - "sisters" => [], - "caretakers" => [] - ]); - - $prefixes = []; - foreach ($member['proxy_tags'] as $proxy) { - if ($travelling[$member['id']]["travelling"]) { - $prefixes[] = "+" . $proxy["prefix"] . ($proxy["suffix"] !== "" && $proxy["suffix"] !== null ? "..." . $proxy["suffix"] : ""); - } else { - $prefixes[] = $proxy["prefix"] . ($proxy["suffix"] !== "" && $proxy["suffix"] !== null ? "..." . $proxy["suffix"] : ""); - } - } - - $lastFronted = null; - if (!$metadata["median"]) { - $fronters = array_map(function ($item) { - return $item["id"]; - }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-fronters.json"), true)["members"]); - - if (in_array($id, $fronters)) { - $lastFronted = [ - 'now' => true, - 'relative' => timeAgo(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-fronters.json"), true)["timestamp"]), - 'absolute' => date("D j M Y, G:i:s (e)", strtotime(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-fronters.json"), true)["timestamp"])), - 'timestamp' => strtotime(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-fronters.json"), true)["timestamp"]), - 'duration' => [ - 'seconds' => null, - 'pretty' => null - ] - ]; - } else { - $switches = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-switches.json"), true); - - $thisMember = array_filter($switches, function ($item) { - global $memberData; - return in_array($memberData["id"], $item["members"]); - }); - - $thisMember = array_values($thisMember); - $frontingEnd = null; - - if (count($thisMember) > 0) { - $thisIndex = array_search($thisMember[0], $switches); - - $frontingStart = $thisMember[0]; - $frontingEnd = $switches[$thisIndex - 1]; - } - - if ($frontingEnd !== null && isset($frontingStart)) { - $seconds = (strtotime($frontingEnd["timestamp"]) - strtotime($frontingStart["timestamp"])); - - $lastFronted = [ - 'now' => false, - 'relative' => timeAgo($frontingEnd["timestamp"]), - 'absolute' => date("D j M Y, G:i:s (e)", strtotime($frontingEnd["timestamp"])), - 'timestamp' => strtotime($frontingEnd["timestamp"]), - 'duration' => [ - 'seconds' => $seconds, - 'pretty' => $seconds . ($french ? " secondes" : " seconds") - ] - ]; - if ($french) { - if ($seconds > 60) { - if ($seconds > 3600) { - $lastFronted['duration']['pretty'] = round($seconds / 3600) . " heures"; - } else { - $lastFronted['duration']['pretty'] = round($seconds / 60) . " minutes"; - } - } - } else { - if ($seconds > 60) { - if ($seconds > 3600) { - $lastFronted['duration']['pretty'] = round($seconds / 3600) . " hours"; - } else { - $lastFronted['duration']['pretty'] = round($seconds / 60) . " minutes"; - } - } - } - } - } - } - - $speciesList = []; - foreach ($metadata["species"] ?? [] as $species) { - if ($french) { - $name = match ($species) { - "earth" => $metadata["robot"] ? "Robot poney terrestre" : (!$metadata["plush"] ? "Poney terrestre" : "Poney terrestre en peluche"), - "alicorn" => $metadata["robot"] ? "Robot alicorne" : (!$metadata["plush"] ? "Alicorne" : "Alicorne en peluche"), - "crystal" => $metadata["robot"] ? "Robot poney de crystal" : (!$metadata["plush"] ? "Poney de crystal" : "Poney de crystal en peluche"), - "pegasus" => $metadata["robot"] ? "Robot pégase" : (!$metadata["plush"] ? "Pégase" : "Pégase en peluche"), - "batpony" => $metadata["robot"] ? "Robot Poney chauve souris" : (!$metadata["plush"] ? "Poney chauve souris" : "Poney chauve souris en peluche"), - "unicorn" => $metadata["robot"] ? "Robot licorne" : (!$metadata["plush"] ? "Licorne" : "Licorne en peluche"), - default => $species . "_" . $metadata["robot"] - }; - } else { - $name = match ($species) { - "earth" => $metadata["robot"] ? "Robot earth pony" : (!$metadata["plush"] ? "Earth pony" : "Earth pony plush"), - "alicorn" => $metadata["robot"] ? "Robot alicorn" : (!$metadata["plush"] ? "Alicorn" : "Alicorn plush"), - "crystal" => $metadata["robot"] ? "Robot crystal pony" : (!$metadata["plush"] ? "Crystal pony" : "Crystal pony plush"), - "pegasus" => $metadata["robot"] ? "Robot pegasus" : (!$metadata["plush"] ? "Pegasus" : "Pegasus plush"), - "batpony" => $metadata["robot"] ? "Robot bat pony" : (!$metadata["plush"] ? "Bat pony" : "Bat pony plush"), - "unicorn" => $metadata["robot"] ? "Robot unicorn" : (!$metadata["plush"] ? "Unicorn" : "Unicorn plush"), - default => $species . "_" . $metadata["robot"] - }; - } - - $speciesList[] = [ - "id" => $species, - "name" => $name, - "robot" => $metadata["robot"], - "plush" => $metadata["plush"], - "icon" => $species . ($metadata["robot"] ? "-robot" : ($metadata["plush"] ? "-plush" : "")) . ".png" - ]; - } - - $systemData = []; - $systemData['page'] = "/" . ($system === "gdapd" ? "raindrops" : "cloudburst"); - $systemData['icon'] = ($system === "gdapd" ? "raindrops" : "cloudburst") . ".png"; - $systemData['name'] = $system === "gdapd" ? "Raindrops" : "Cloudburst"; - $systemData['full_name'] = $system === "gdapd" ? "Raindrops System" : "Cloudburst System"; - $systemData['subsystem'] = null; - $systemData['temporary'] = false; - - if (_header_memberPartOfSubsystem($member) && _header_getSubsystemFromMember($member)["source_type"] !== "member") { - $subsystem = _header_getSubsystemFromMember($member); - $systemData['subsystem'] = [ - "page" => $systemData['page'] . "/-/subsystem/" . $subsystem["source"], - "icon" => "ss-$subsystem[source].png", - "name" => file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-subsystem-$subsystem[source].json") ? json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-subsystem-$subsystem[source].json"), true)["name"] : $subsystem["source"] - ]; - } - - if ($travelling[$member['id']]["travelling"]) { - $systemData['page'] = "/" . ($system === "gdapd" ? "cloudburst" : "raindrops"); - $systemData['icon'] = ($system === "gdapd" ? "cloudburst" : "raindrops") . ".png"; - $systemData['name'] = $system === "gdapd" ? "Cloudburst" : "Raindrops"; - $systemData['full_name'] = $system === "gdapd" ? "Cloudburst System" : "Raindrops System"; - $systemData['subsystem'] = null; - $systemData['temporary'] = true; - } - - $marefriends = []; - foreach ($metadata["marefriends"] as $marefriend) { - $mfSystem = explode("/", $marefriend)[0]; - $mfMemberID = explode("/", $marefriend)[1]; - $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem-members.json"), true), function ($item) use ($mfMemberID) { - return $item["id"] === $mfMemberID; - }); - sort($mfMember); - $mfMember = $mfMember[0]; - - $marefriends[] = [ - "id" => $marefriend, - "link" => "/" . ($mfMember["name"]), - "icon" => "pt" . (file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . $mfMember['name'] . ".png") ? "-" . $mfMember['name'] : "") . ".png", - "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), - "full_name" => $mfMember["display_name"] ?? $mfMember["name"] - ]; - } - - $sisters = []; - foreach ($metadata["sisters"] as $marefriend) { - $mfSystem = explode("/", $marefriend)[0]; - $mfMemberID = explode("/", $marefriend)[1]; - $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem-members.json"), true), function ($item) use ($mfMemberID) { - return $item["id"] === $mfMemberID; - }); - sort($mfMember); - $mfMember = $mfMember[0]; - - $sisters[] = [ - "id" => $marefriend, - "link" => "/" . ($mfMember["name"]), - "icon" => "pt" . (file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . $mfMember['name'] . ".png") ? "-" . $mfMember['name'] : "") . ".png", - "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), - "full_name" => $mfMember["display_name"] ?? $mfMember["name"] - ]; - } - - $caretakers = null; - - if ($metadata["little"] === 2) { - $caretakers = []; - foreach ($metadata["caretakers"] as $marefriend) { - $mfSystem = explode("/", $marefriend)[0]; - $mfMemberID = explode("/", $marefriend)[1]; - $mfMember = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$mfSystem-members.json"), true), function ($item) use ($mfMemberID) { - return $item["id"] === $mfMemberID; - }); - sort($mfMember); - $mfMember = $mfMember[0]; - - $caretakers[] = [ - "id" => $marefriend, - "link" => "/" . ($mfMember["name"]), - "icon" => "pt" . (file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . $mfMember['name'] . ".png") ? "-" . $mfMember['name'] : "") . ".png", - "name" => getMiniName($mfMember["display_name"] ?? $mfMember["name"]), - "full_name" => $mfMember["display_name"] ?? $mfMember["name"] - ]; - } - } - - $badges = []; - - if ($metadata["host"] ?? false) { - if (!$travelling[$member['id']]["travelling"]) { - $badges[] = [ - "id" => "mcf", - "color" => "primary", - "html" => ( - $french - ? - 'Fronteuse la plus présente' - : - 'Most common fronter' - ) - ]; - } - } - - if (($metadata["age_spells"] ?? false) && !$french) { - $badges[] = [ - "id" => "age_spells", - "color" => "#6f42c1", - "html" => 'Affected by age spells' - ]; - } - - if ($metadata["fictive"] ?? false) { - $badges[] = [ - "id" => "fictive", - "color" => "info", - "html" => ( - $french - ? - 'Fictive' - : - 'Fictive' - ) - ]; - } - - if ($metadata["less_frequent"] ?? false) { - $badges[] = [ - "id" => "nonverbal", - "color" => "#fd7e14", - "html" => 'Fronts less often' - ]; - } - - if ($metadata["nonverbal"] ?? false) { - $badges[] = [ - "id" => "nonverbal", - "color" => "#20c997", - "html" => 'Non verbal IRL' - ]; - } - - if ($member["name"] === "fusion") { - $badges[] = [ - "id" => "fusion", - "color" => "d63384", - "html" => 'Fusion' - ]; - } - - if (($metadata["sexually_active"] ?? false) && !$french && $isLoggedIn) { - $badges[] = [ - "id" => "sexually_active", - "color" => "d6a833", - "html" => 'Sexually active' - ]; - } - - if ($metadata["protector"] ?? false) { - $badges[] = [ - "id" => "protector", - "color" => "black", - "html" => ( - $french - ? - '
' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($member['pronouns'])["third"] ? "is" : "are") . ' a protector in the system and will front when somepony cannot handle it anymore." class="badge rounded-pill bg-black">' . (getMemberPronouns($member['pronouns'])["gender"] === "female" ? "Protectrice" : (getMemberPronouns($member['pronouns'])["gender"] === "male" ? "Protecteur" : "Protecteur·ice")) . '
' - : - 'Protector' - ) - ]; - } - - if (($metadata["little"] ?? 0) === 2) { - $badges[] = [ - "id" => "little", - "color" => "success", - "html" => ( - $french - ? - '
' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($member['pronouns'])["third"] ? "is" : "are") . ' mentally younger, and therefore behaves and feels younger than the body is." class="badge rounded-pill bg-success">Petit' . (getMemberPronouns($member['pronouns'])["gender"] === "female" ? "e" : (getMemberPronouns($member['pronouns'])["gender"] === "male" ? "" : "·e")) . '
' - : - 'Little' - ) - ]; - } - - if (($metadata["little"] ?? 0) === 3) { - $badges[] = [ - "id" => "younger", - "color" => "dark", - "html" => ( - $french - ? - 'Plus jeune' - : - 'Younger' - ) - ]; - } - - if (($metadata["age_regressor"] ?? false)) { - if ($metadata["regression"] !== null && $metadata["regression"] !== false) { - $regression = _header_getMember($metadata["regression"], $system); - $badges[] = [ - "id" => "regressor_median", - "color" => "secondary", - "html" => ( - $french - ? - 'Régresse en âge en '. (getMiniName($regression["display_name"] ?? $regression["name"])) . '' - : - 'Age regresses into '. (getMiniName($regression["display_name"] ?? $regression["name"])) . '' - ) - ]; - } else { - $badges[] = [ - "id" => "regressor", - "color" => "secondary", - "html" => ( - $french - ? - 'Régresseur d\'âge' - : - 'Age regressor' - ) - ]; - } - } - - if ($metadata["median"] !== null && $metadata["median"] !== false) { - $source = _header_getMember($metadata["median"], $system); - if ($metadata["little"] > 0) { - $badges[] = [ - "id" => "regressed", - "color" => "warning", - "html" => ( - $french - ? - 'Régressé en âge de ' . (getMiniName($source["display_name"] ?? $source["name"])) . '' - : - 'Age regressed from ' . (getMiniName($source["display_name"] ?? $source["name"])) . '' - ) - ]; - } else { - $badges[] = [ - "id" => "facet", - "color" => "light", - "html" => ( - $french - ? - 'Facette de ' . getMiniName($source["display_name"] ?? $source["name"]) . '' - : - 'Facet of ' . getMiniName($source["display_name"] ?? $source["name"]) . '' - ) - ]; - } - } - - return [ - 'id' => $member['name'], - 'color' => $member["color"] ?? "000000", - 'icon' => [ - "online" => $member['avatar_url'], - "offline" => "pf-$system-$id.webp" - ], - 'median' => $metadata["median"], - 'little' => $metadata["little"] === 2, - 'name' => $member["display_name"] ?? $member["name"], - 'badges' => $badges, - 'prefixes' => $prefixes, - 'pronouns' => getTooltipsFromMark($member["pronouns"], $french) ?? "she/her", - 'pronouns_usage' => getMemberPronouns($member['pronouns']), - 'last_fronted' => $lastFronted, - 'species' => $speciesList, - 'system' => $systemData, - 'relations' => [ - 'marefriends' => $marefriends, - 'sisters' => $sisters, - 'caretakers' => $caretakers - ] - ]; -} \ No newline at end of file diff --git a/includes/bitset.inc b/includes/bitset.inc new file mode 100644 index 0000000..1d026e5 --- /dev/null +++ b/includes/bitset.inc @@ -0,0 +1,110 @@ + "earth", + "0010" => "unicorn", + "0011" => "pegasus", + "0100" => "alicorn", + "0101" => "batpony", + "0110" => "crystal", + default => null, + }; + + $species2 = match ($species2) { + "0001" => "earth", + "0010" => "unicorn", + "0011" => "pegasus", + "0100" => "alicorn", + "0101" => "batpony", + "0110" => "crystal", + default => null, + }; + + $species3 = match ($species3) { + "0001" => "earth", + "0010" => "unicorn", + "0011" => "pegasus", + "0100" => "alicorn", + "0101" => "batpony", + "0110" => "crystal", + default => null, + }; + + if ($little === 1) { + $ageRegressor = true; + $little = 0; + } + + return [ + 'shared_memory' => $sharedMemory, + 'median' => $median, + 'protector' => $protector, + 'fictive' => $fictive, + 'little' => $little, + 'not_talking' => $notTalking, + 'host' => $host, + 'robot' => $robot, + 'magic' => $magic, + 'sensitivity' => $sensitivity, + 'food' => $food, + 'plush' => $plush, + 'nonverbal' => $nonverbal, + 'less_frequent' => $lessFrequent, + 'age_spells' => $age, + 'age_regressor' => $ageRegressor, + 'sexually_active' => $sexuallyActive, + 'species' => array_filter([ + $species1, + $species2, + $species3 + ], function ($i) { + return isset($i); + }) + ]; +} + +function parseMetadata ($metadata) { + if (isset($metadata)) { + if ($metadata["bitset"]) { + $m = parseBitset($metadata["bitset"]); + $m["marefriends"] = $metadata["marefriends"] ?? []; + $m["bitset"] = $metadata["bitset"] ?? []; + $m["sisters"] = $metadata["sisters"] ?? []; + $m["regression"] = $metadata["regression"] ?? null; + $m["caretakers"] = $metadata["caretakers"] ?? []; + $m["median"] = $metadata["median"] ?? null; + $m["birth"] = $metadata["birth"] ?? null; + $m["heat"] = $metadata["heat"] ?? null; + } else { + $m = $metadata; + } + + return $m; + } else { + return $metadata; + } +} \ No newline at end of file diff --git a/includes/bitset.php b/includes/bitset.php deleted file mode 100644 index 1d026e5..0000000 --- a/includes/bitset.php +++ /dev/null @@ -1,110 +0,0 @@ - "earth", - "0010" => "unicorn", - "0011" => "pegasus", - "0100" => "alicorn", - "0101" => "batpony", - "0110" => "crystal", - default => null, - }; - - $species2 = match ($species2) { - "0001" => "earth", - "0010" => "unicorn", - "0011" => "pegasus", - "0100" => "alicorn", - "0101" => "batpony", - "0110" => "crystal", - default => null, - }; - - $species3 = match ($species3) { - "0001" => "earth", - "0010" => "unicorn", - "0011" => "pegasus", - "0100" => "alicorn", - "0101" => "batpony", - "0110" => "crystal", - default => null, - }; - - if ($little === 1) { - $ageRegressor = true; - $little = 0; - } - - return [ - 'shared_memory' => $sharedMemory, - 'median' => $median, - 'protector' => $protector, - 'fictive' => $fictive, - 'little' => $little, - 'not_talking' => $notTalking, - 'host' => $host, - 'robot' => $robot, - 'magic' => $magic, - 'sensitivity' => $sensitivity, - 'food' => $food, - 'plush' => $plush, - 'nonverbal' => $nonverbal, - 'less_frequent' => $lessFrequent, - 'age_spells' => $age, - 'age_regressor' => $ageRegressor, - 'sexually_active' => $sexuallyActive, - 'species' => array_filter([ - $species1, - $species2, - $species3 - ], function ($i) { - return isset($i); - }) - ]; -} - -function parseMetadata ($metadata) { - if (isset($metadata)) { - if ($metadata["bitset"]) { - $m = parseBitset($metadata["bitset"]); - $m["marefriends"] = $metadata["marefriends"] ?? []; - $m["bitset"] = $metadata["bitset"] ?? []; - $m["sisters"] = $metadata["sisters"] ?? []; - $m["regression"] = $metadata["regression"] ?? null; - $m["caretakers"] = $metadata["caretakers"] ?? []; - $m["median"] = $metadata["median"] ?? null; - $m["birth"] = $metadata["birth"] ?? null; - $m["heat"] = $metadata["heat"] ?? null; - } else { - $m = $metadata; - } - - return $m; - } else { - return $metadata; - } -} \ No newline at end of file diff --git a/includes/edit-private.inc b/includes/edit-private.inc new file mode 100644 index 0000000..e760b94 --- /dev/null +++ b/includes/edit-private.inc @@ -0,0 +1,147 @@ + + +
+
+ +
+ +
+ +

+ Saved · bytes · ">View page +

+ + + + + + + + +
+ + \ No newline at end of file diff --git a/includes/edit-private.php b/includes/edit-private.php deleted file mode 100644 index 58e9ed5..0000000 --- a/includes/edit-private.php +++ /dev/null @@ -1,147 +0,0 @@ - - -
-
- -
- -
- -

- Saved · bytes · ">View page -

- - - - - - - - -
- - \ No newline at end of file diff --git a/includes/edit.inc b/includes/edit.inc new file mode 100644 index 0000000..d8cf673 --- /dev/null +++ b/includes/edit.inc @@ -0,0 +1,147 @@ + + +
+
+ +
+ +
+ +

+ Saved · bytes · ">View page +

+ + + + + + + + +
+ + \ No newline at end of file diff --git a/includes/edit.php b/includes/edit.php deleted file mode 100644 index 5bbd38a..0000000 --- a/includes/edit.php +++ /dev/null @@ -1,147 +0,0 @@ - - -
-
- -
- -
- -

- Saved · bytes · ">View page -

- - - - - - - - -
- - \ No newline at end of file diff --git a/includes/emergency.inc b/includes/emergency.inc new file mode 100644 index 0000000..5490985 --- /dev/null +++ b/includes/emergency.inc @@ -0,0 +1,194 @@ +

Emergency alert +
+ + · +
+

+ +Turn ON + +

Sending next notification never

+ + + + + + + + \ No newline at end of file diff --git a/includes/emergency.php b/includes/emergency.php deleted file mode 100644 index 5490985..0000000 --- a/includes/emergency.php +++ /dev/null @@ -1,194 +0,0 @@ -

Emergency alert -
- - · -
-

- -Turn ON - -

Sending next notification never

- - - - - - - - \ No newline at end of file diff --git a/includes/footer.inc b/includes/footer.inc new file mode 100644 index 0000000..303b6f0 --- /dev/null +++ b/includes/footer.inc @@ -0,0 +1,36 @@ + + +
+ + + + + + + + \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php deleted file mode 100644 index 720881a..0000000 --- a/includes/footer.php +++ /dev/null @@ -1,35 +0,0 @@ - - -
- - - - - - - - \ No newline at end of file diff --git a/includes/functions.inc b/includes/functions.inc new file mode 100644 index 0000000..386d2b2 --- /dev/null +++ b/includes/functions.inc @@ -0,0 +1,477 @@ + $g) { + $h += 360; + } + break; + + case $g: + $h = 60 * (($b - $r) / $d + 2); + break; + + case $b: + $h = 60 * (($r - $g) / $d + 4); + break; + } + } + + return array(round($h, 2), round($s, 2), round($l, 2)); + } +} + +if (!function_exists("imageCreateCorners")) { + function imageCreateCorners($sourceImageFile, $radius) { + # test source image + if (file_exists($sourceImageFile)) { + $res = is_array($info = getimagesize($sourceImageFile)); + } + else $res = false; + + # open image + if ($res) { + $w = $info[0]; + $h = $info[1]; + switch ($info['mime']) { + case 'image/jpeg': $src = imagecreatefromjpeg($sourceImageFile); + break; + case 'image/gif': $src = imagecreatefromgif($sourceImageFile); + break; + case 'image/png': $src = imagecreatefrompng($sourceImageFile); + break; + default: + $res = false; + } + } + + # create corners + if ($res) { + + $q = 10; # change this if you want + $radius *= $q; + + # find unique color + do { + $r = rand(0, 255); + $g = rand(0, 255); + $b = rand(0, 255); + } + while (imagecolorexact($src, $r, $g, $b) < 0); + + $nw = $w*$q; + $nh = $h*$q; + + $img = imagecreatetruecolor($nw, $nh); + $alphacolor = imagecolorallocatealpha($img, $r, $g, $b, 127); + imagealphablending($img, false); + imagesavealpha($img, true); + imagefilledrectangle($img, 0, 0, $nw, $nh, $alphacolor); + + imagefill($img, 0, 0, $alphacolor); + imagecopyresampled($img, $src, 0, 0, 0, 0, $nw, $nh, $w, $h); + + imagearc($img, $radius-1, $radius-1, $radius*2, $radius*2, 180, 270, $alphacolor); + imagefilltoborder($img, 0, 0, $alphacolor, $alphacolor); + imagearc($img, $nw-$radius, $radius-1, $radius*2, $radius*2, 270, 0, $alphacolor); + imagefilltoborder($img, $nw-1, 0, $alphacolor, $alphacolor); + imagearc($img, $radius-1, $nh-$radius, $radius*2, $radius*2, 90, 180, $alphacolor); + imagefilltoborder($img, 0, $nh-1, $alphacolor, $alphacolor); + imagearc($img, $nw-$radius, $nh-$radius, $radius*2, $radius*2, 0, 90, $alphacolor); + imagefilltoborder($img, $nw-1, $nh-1, $alphacolor, $alphacolor); + imagealphablending($img, true); + imagecolortransparent($img, $alphacolor); + + # resize image down + $dest = imagecreatetruecolor($w, $h); + imagealphablending($dest, false); + imagesavealpha($dest, true); + imagefilledrectangle($dest, 0, 0, $w, $h, $alphacolor); + imagecopyresampled($dest, $img, 0, 0, 0, 0, $w, $h, $nw, $nh); + + # output image + $res = $dest; + imagedestroy($src); + imagedestroy($img); + } + + return $res; + } +} + +if (!function_exists("getMiniName")) { + function getMiniName(string $name) { + $parts = explode(" ", $name); + + if (strlen($parts[0]) > 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly" && $parts[0] !== "Windy" && (isset($parts[1]) && $parts[1] !== "Brightdawn")) { + if (str_contains($parts[0], "/")) { + return explode("/", $parts[0])[0]; + } else { + return $parts[0]; + } + } else { + return $name; + } + } +} + +if (!function_exists("withCaretakersDown")) { + function withCaretakersDown(array $ordered): array { + $caretakersNo = []; + $caretakersYes = []; + + foreach ($ordered as $item) { + if ($item["_metadata"]["little"] === 2) { + $caretakersYes[] = $item; + } else { + $caretakersNo[] = $item; + } + } + + return [...$caretakersNo, ...$caretakersYes]; + } +} + +if (!function_exists("getSystemMember")) { + function getSystemMember(string $system, string $id) { + $systemID = $system; + + $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID/members.json"), true); + $member = null; + + foreach ($members as $m) { + if ($m["id"] === $id) $member = $m; + } + + $member["system"] = $member["_system"] = $system; + + return $member; + } +} + +if (!function_exists("getMemberWithoutSystem")) { + function getMemberWithoutSystem(string $id) { + $member = null; + + $members1 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true); + foreach ($members1 as $m) { + $m["_system"] = "ynmuc"; + $m["system"] = "ynmuc"; + if ($m["id"] === $id) $member = $m; + } + + $members2 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true); + foreach ($members2 as $m) { + $m["_system"] = "gdapd"; + $m["system"] = "gdapd"; + if ($m["id"] === $id) $member = $m; + } + + return $member; + } +} + +if (!function_exists("showMembersFromList")) { + function showMembersFromList(array $list) { + foreach ($list as $member) { if ($member['name'] !== "unknown" && $member['name'] !== "fusion") { + echo(' +
+ +
' . ($member['display_name'] ?? $member['name']) . '
+
' . (isset($member['travelling']) && $member['travelling'] ? "+" . ($member['proxy_tags'][0]['prefix'] ?? " ") : ($member['proxy_tags'][0]['prefix'] ?? " ")) . '
+
'); + }} + } +} + +if (!function_exists("showSubsystem")) { + function showSubsystem(array $data, string $parentSystem) { + $subsystemData = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/subsystems/$parentSystem-$data[source].json"), true); + + echo(' +
'); + echo('
'); + + showMembersFromList(scoreOrder(array_map(function ($i) use ($parentSystem) { + return getSystemMember($parentSystem, $i); + }, $data["members"]), $parentSystem)); + + echo('
+ +
'); + } +} + +if (!function_exists("showSystem")) { + function showSystem(string $id, string $name, string $color, bool $hideTitle) { + global $travelling; + + $global = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$id/general.json"), true); + + if ($hideTitle) { + echo(' +
'); + } else { + echo(' +
'); + } + if (!$hideTitle) echo(' + +

' . $name . '
+
'); + + if ($hideTitle) { + echo('
'); + } else { + echo('
'); + } + + showMembersFromList(scoreOrder([...array_map(function ($i) use ($id) { + $i["travelling"] = false; + $i["system"] = $id; + return $i; + }, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$id/members.json"), true), function ($i) use ($travelling) { + return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']); + })), ...array_map(function ($i) use ($id) { + $i["travelling"] = true; + $i["system"] = ($id === "gdapd" ? "ynmuc" : "gdapd"); + return $i; + }, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($id === "gdapd" ? "ynmuc" : "gdapd") . "/members.json"), true), function ($i) use ($travelling) { + return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']; + }))], $id)); + + echo('
+ +
'); + } +} + +if (!function_exists("cloudburst")) { + function cloudburst(bool $hideTitle): void { + showSystem("ynmuc", "Cloudburst System", "#5f08a9a6", $hideTitle); + } +} + +if (!function_exists("raindrops")) { + function raindrops(bool $hideTitle): void { + showSystem("gdapd", "Raindrops System", "#a95f08a6", $hideTitle); + } +} + +if (!function_exists("getMember")) { + function getMember(string $id) { + global $systemID; + + $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID/members.json"), true); + $member = null; + + foreach ($members as $m) { + if ($m["id"] === $id) $member = $m; + } + + return $member; + } +} + +if (!function_exists("timeAgo")) { + function timeAgo($time): string { + if (!is_numeric($time)) { + $time = strtotime($time); + } + + $periods = ["sec.", "mn.", "hr.", "d.", "wk.", "mo.", "y.", "ages"]; + $lengths = array("60", "60", "24", "7", "4.35", "12", "100"); + + $now = time(); + + $difference = $now - $time; + if ($difference <= 10 && $difference >= 0) { + return $tense = "now"; + } elseif ($difference > 0) { + $tense = "ago"; + } else { + $tense = "later"; + } + + for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { + $difference /= $lengths[$j]; + } + + $difference = round($difference); + + $period = $periods[$j]; + return "{$difference} {$period} {$tense}"; + } +} + +if (!function_exists("timeIn")) { + function timeIn($time): string { + if (!is_numeric($time)) { + $time = strtotime($time); + } + + $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"]; + $lengths = array("60", "60", "24", "7", "4.35", "12", "100"); + + $now = time(); + + $difference = $time - $now; + if ($difference <= 10 && $difference >= 0) { + return $tense = "now"; + } elseif ($difference > 0) { + $tense = "in"; + } else { + $tense = "ago"; + } + + for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { + $difference /= $lengths[$j]; + } + + $difference = round($difference); + + $period = $periods[$j] . ($difference >1 ? "s" :''); + return "{$tense} {$difference} {$period}"; + } +} + +if (!function_exists("duration")) { + function duration($seconds) { + if ($seconds >= 60) { + if (floor($seconds / 60) >= 60) { + if (floor($seconds / 3600) >= 24) { + $days = floor($seconds / 86400); + return $days . " day" . ($days > 1 ? "s" : ""); + } else { + $hours = floor($seconds / 3600); + return $hours . " hour" . ($hours > 1 ? "s" : ""); + } + } else { + $minutes = floor($seconds / 60); + return $minutes . " minute" . ($minutes > 1 ? "s" : ""); + } + } else { + return $seconds . " seconds"; + } + } +} + +if (!function_exists("relativeDate")) { + function relativeDate($date, $showTime = true) { + if (!is_numeric($date)) $date = strtotime($date); + + if (!$showTime) { + if (date('Y-m-d', $date) === date('Y-m-d')) { + return "today"; + } elseif (date('Y-m-d', $date) === date('Y-m-d', time() + 86400)) { + return "tomorrow"; + } elseif ($date < time() + 518400) { + return date('l', $date); + } else { + return date('D j M', $date); + } + } else { + if (date('Y-m-d', $date) === date('Y-m-d')) { + return "today, " . date('H:i', $date) . ""; + } elseif (date('Y-m-d', $date) === date('Y-m-d', time() + 86400)) { + return "tomorrow, " . date('H:i', $date) . ""; + } elseif ($date < time() + 518400) { + return date('l', $date) . ", " . date('H:i', $date) . ""; + } else { + return date('D j M', $date) . ", " . date('H:i', $date) . ""; + } + } + } +} + +if (!function_exists("getMemberSystem")) { + function getMemberSystem(string $id) { + $list = scoreOrderGlobal(); + + foreach ($list as $item) { + if ($item["id"] === $id) return $item["_system"]; + } + } +} + +if (!function_exists("getMemberFromName")) { + function getMemberFromName(string $name) { + $list = [...json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true), ...json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true)]; + + foreach ($list as $item) { + if ($item["name"] === $name) return $item; + } + } +} + +if (!function_exists("resolveMember")) { + function resolveMember(mixed $name) { + if (is_string($name)) { + if (str_ends_with($name, "-travelling")) { + return substr($name, 0, strlen($name) - 11); + } else { + return $name; + } + } else { + return $name; + } + } +} \ No newline at end of file diff --git a/includes/functions.php b/includes/functions.php deleted file mode 100644 index 1a2bf4c..0000000 --- a/includes/functions.php +++ /dev/null @@ -1,319 +0,0 @@ - 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly" && $parts[0] !== "Windy") { - if (str_contains($parts[0], "/")) { - return explode("/", $parts[0])[0]; - } else { - return $parts[0]; - } - } else { - return $name; - } - } -} - -if (!function_exists("withCaretakersDown")) { - function withCaretakersDown(array $ordered): array { - $caretakersNo = []; - $caretakersYes = []; - - foreach ($ordered as $item) { - if ($item["_metadata"]["little"] === 2) { - $caretakersYes[] = $item; - } else { - $caretakersNo[] = $item; - } - } - - return [...$caretakersNo, ...$caretakersYes]; - } -} - -if (!function_exists("getSystemMember")) { - function getSystemMember(string $system, string $id) { - $systemID = $system; - - $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true); - $member = null; - - foreach ($members as $m) { - if ($m["id"] === $id) $member = $m; - } - - return $member; - } -} - -if (!function_exists("getMemberWithoutSystem")) { - function getMemberWithoutSystem(string $id) { - $member = null; - - $members1 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true); - foreach ($members1 as $m) { - $m["_system"] = "ynmuc"; - if ($m["id"] === $id) $member = $m; - } - - $members2 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true); - foreach ($members2 as $m) { - $m["_system"] = "gdapd"; - if ($m["id"] === $id) $member = $m; - } - - return $member; - } -} - -if (!function_exists("showMembersFromList")) { - function showMembersFromList(array $list) { - foreach ($list as $member) { if ($member['name'] !== "unknown" && $member['name'] !== "fusion") { - echo(' -
- -
' . ($member['display_name'] ?? $member['name']) . '
-
' . (isset($member['travelling']) && $member['travelling'] ? "+" . ($member['proxy_tags'][0]['prefix'] ?? " ") : ($member['proxy_tags'][0]['prefix'] ?? " ")) . '
-
'); - }} - } -} - -if (!function_exists("showSubsystem")) { - function showSubsystem(array $data, string $parentSystem) { - $subsystemData = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$parentSystem-subsystem-$data[source].json"), true); - - echo(' -
'); - echo('
'); - - showMembersFromList(scoreOrder(array_map(function ($i) use ($parentSystem) { - return getSystemMember($parentSystem, $i); - }, $data["members"]), $parentSystem)); - - echo('
- -
'); - } -} - -if (!function_exists("showSystem")) { - function showSystem(string $id, string $name, string $color, bool $hideTitle) { - global $travelling; - - $global = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$id-general.json"), true); - - if ($hideTitle) { - echo(' -
'); - } else { - echo(' -
'); - } - if (!$hideTitle) echo(' - -

' . $name . '
-
'); - - if ($hideTitle) { - echo('
'); - } else { - echo('
'); - } - - showMembersFromList(scoreOrder([...array_map(function ($i) use ($id) { - $i["travelling"] = false; - $i["system"] = $id; - return $i; - }, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$id-members.json"), true), function ($i) use ($travelling) { - return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']); - })), ...array_map(function ($i) use ($id) { - $i["travelling"] = true; - $i["system"] = ($id === "gdapd" ? "ynmuc" : "gdapd"); - return $i; - }, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($id === "gdapd" ? "ynmuc" : "gdapd") . "-members.json"), true), function ($i) use ($travelling) { - return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']; - }))], $id)); - - echo('
- -
'); - } -} - -if (!function_exists("cloudburst")) { - function cloudburst(bool $hideTitle): void { - showSystem("ynmuc", "Cloudburst System", "#5f08a9a6", $hideTitle); - } -} - -if (!function_exists("raindrops")) { - function raindrops(bool $hideTitle): void { - showSystem("gdapd", "Raindrops System", "#a95f08a6", $hideTitle); - } -} - -if (!function_exists("getMember")) { - function getMember(string $id) { - global $systemID; - - $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true); - $member = null; - - foreach ($members as $m) { - if ($m["id"] === $id) $member = $m; - } - - return $member; - } -} - -if (!function_exists("timeAgo")) { - function timeAgo($time): string { - if (!is_numeric($time)) { - $time = strtotime($time); - } - - $periods = ["sec.", "mn.", "hr.", "d.", "wk.", "mo.", "y.", "ages"]; - $lengths = array("60", "60", "24", "7", "4.35", "12", "100"); - - $now = time(); - - $difference = $now - $time; - if ($difference <= 10 && $difference >= 0) { - return $tense = "now"; - } elseif ($difference > 0) { - $tense = "ago"; - } else { - $tense = "later"; - } - - for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { - $difference /= $lengths[$j]; - } - - $difference = round($difference); - - $period = $periods[$j]; - return "{$difference} {$period} {$tense}"; - } -} - -if (!function_exists("timeIn")) { - function timeIn($time): string { - if (!is_numeric($time)) { - $time = strtotime($time); - } - - $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"]; - $lengths = array("60", "60", "24", "7", "4.35", "12", "100"); - - $now = time(); - - $difference = $time - $now; - if ($difference <= 10 && $difference >= 0) { - return $tense = "now"; - } elseif ($difference > 0) { - $tense = "in"; - } else { - $tense = "ago"; - } - - for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { - $difference /= $lengths[$j]; - } - - $difference = round($difference); - - $period = $periods[$j] . ($difference >1 ? "s" :''); - return "{$tense} {$difference} {$period}"; - } -} - -if (!function_exists("duration")) { - function duration($seconds) { - if ($seconds >= 60) { - if (floor($seconds / 60) >= 60) { - if (floor($seconds / 3600) >= 24) { - $days = floor($seconds / 86400); - return $days . " day" . ($days > 1 ? "s" : ""); - } else { - $hours = floor($seconds / 3600); - return $hours . " hour" . ($hours > 1 ? "s" : ""); - } - } else { - $minutes = floor($seconds / 60); - return $minutes . " minute" . ($minutes > 1 ? "s" : ""); - } - } else { - return $seconds . " seconds"; - } - } -} - -if (!function_exists("relativeDate")) { - function relativeDate($date, $showTime = true) { - if (!is_numeric($date)) $date = strtotime($date); - - if (!$showTime) { - if (date('Y-m-d', $date) === date('Y-m-d')) { - return "today"; - } elseif (date('Y-m-d', $date) === date('Y-m-d', time() + 86400)) { - return "tomorrow"; - } elseif ($date < time() + 518400) { - return date('l', $date); - } else { - return date('D j M', $date); - } - } else { - if (date('Y-m-d', $date) === date('Y-m-d')) { - return "today, " . date('H:i', $date) . ""; - } elseif (date('Y-m-d', $date) === date('Y-m-d', time() + 86400)) { - return "tomorrow, " . date('H:i', $date) . ""; - } elseif ($date < time() + 518400) { - return date('l', $date) . ", " . date('H:i', $date) . ""; - } else { - return date('D j M', $date) . ", " . date('H:i', $date) . ""; - } - } - } -} - -if (!function_exists("getMemberSystem")) { - function getMemberSystem(string $id) { - $list = scoreOrderGlobal(); - - foreach ($list as $item) { - if ($item["id"] === $id) return $item["_system"]; - } - } -} - -if (!function_exists("getMemberFromName")) { - function getMemberFromName(string $name) { - $list = [...json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true), ...json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true)]; - - foreach ($list as $item) { - if ($item["name"] === $name) return $item; - } - } -} - -if (!function_exists("resolveMember")) { - function resolveMember(mixed $name) { - if (is_string($name)) { - if (str_ends_with($name, "-travelling")) { - return substr($name, 0, strlen($name) - 11); - } else { - return $name; - } - } else { - return $name; - } - } -} \ No newline at end of file diff --git a/includes/header.inc b/includes/header.inc new file mode 100644 index 0000000..e851c85 --- /dev/null +++ b/includes/header.inc @@ -0,0 +1,1001 @@ +"> +
+ Error ' . $errno . ': ' . $errstr . ' [' . $file . ':' . $line . '] +
'); +} + +if (isset($_GET['errors'])) { + ini_set('display_errors', '1'); + ini_set('display_startup_errors', '1'); + error_reporting(E_ALL); + set_error_handler("error", E_ALL); +} + +global $_MemberName; +global $_MemberPage; +global $_SystemName; +global $_SystemPage; +global $toplevel; + +$pages = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/pages.json"), true); +$page = $pages[$toplevel] ?? [ + "rail" => false +]; + +require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/travelling.inc"; global $travelling; +require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/score.inc"; +require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/pronouns.inc"; +require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/bitset.inc"; +require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/banner.inc"; +require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/rainbow.inc"; +require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.inc"; +require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php"; + +?> + + + + + + + + <?= $title ? $title . " · " : "" ?>Cold Haze + + + + + + + + + + + + + + + + + + + + + + + + id="admin-page"> + + + + + diff --git a/includes/header.php b/includes/header.php deleted file mode 100644 index 91d0aee..0000000 --- a/includes/header.php +++ /dev/null @@ -1,963 +0,0 @@ -"> -
- Error ' . $errno . ': ' . $errstr . ' [' . $file . ':' . $line . '] -
'); -} - -if (isset($_GET['errors'])) { - ini_set('display_errors', '1'); - ini_set('display_startup_errors', '1'); - error_reporting(E_ALL); - set_error_handler("error", E_ALL); -} - -global $_MemberName; -global $_MemberPage; -global $_SystemName; -global $_SystemPage; -global $toplevel; - -require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/travelling.php"; global $travelling; -require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/score.php"; -require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/pronouns.php"; -require_once $_SERVER["DOCUMENT_ROOT"] . "/includes/bitset.php"; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $isLoggedIn; global $isUserLoggedIn; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/banner.php"; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/rainbow.php"; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php"; -require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php"; - -?> - - - - - - - - <?= $title ? $title . " · " : "" ?>Cold Haze - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/includes/icons.inc b/includes/icons.inc new file mode 100644 index 0000000..ec433b2 --- /dev/null +++ b/includes/icons.inc @@ -0,0 +1,5 @@ + array_unique($keywords), + "link" => "/-/actions/$action[id]" + ]; + } + + foreach ($toys as $toy) { + $base = strtolower($toy["name"]); + $addKeywords = $toy["keywords"] ?? []; + $keywords = [ + $base, + ucfirst($base), + ucwords($base) + ]; + + for ($i = 0; $i < strlen($base); $i++) { + $keywords[] = substr($base, 0, $i) . strtoupper(substr($base, $i, 1)) . substr($base, $i + 1, strlen($base) - $i - 1); + + for ($j = 0; $j < strlen($base); $j++) { + $keywords[] = substr($base, 0, $i) . strtoupper(substr($base, $i, $j)) . substr($base, $i + $j, strlen($base) - $i - $j); + } + } + + foreach ($addKeywords as $keyword) { + $keywords[] = $keyword; + $keywords[] = ucfirst($keyword); + $keywords[] = ucwords($keyword); + + for ($i = 0; $i < strlen($keyword); $i++) { + $keywords[] = substr($keyword, 0, $i) . strtoupper(substr($keyword, $i, 1)) . substr($keyword, $i + 1, strlen($keyword) - $i - 1); + + for ($j = 0; $j < strlen($keyword); $j++) { + $keywords[] = substr($keyword, 0, $i) . strtoupper(substr($keyword, $i, $j)) . substr($keyword, $i + $j, strlen($keyword) - $i - $j); + } + } + } + + $pages[$toy["id"]] = [ + "keywords" => array_unique($keywords), + "link" => "/-/toys/$toy[id]" + ]; + } + + $keywords = []; + foreach ($pages as $page) { + foreach ($page["keywords"] as $keyword) { + $keywords[] = [ + "keyword" => $keyword, + "link" => $page["link"] + ]; + } + } + + uasort($keywords, function ($a, $b) { + return strlen($b["keyword"]) - strlen($a["keyword"]); + }); + + return $keywords; +} + +function replaceKeyWords(string $input): string { + $keywords = getKeyWords(); + + foreach ($keywords as $data) { + $keyword = $data["keyword"]; + $url = $data["link"]; + + $input = str_replace($keyword, "$keyword", $input); + } + + return $input; +} \ No newline at end of file diff --git a/includes/keywords.php b/includes/keywords.php deleted file mode 100644 index 270d905..0000000 --- a/includes/keywords.php +++ /dev/null @@ -1,110 +0,0 @@ - array_unique($keywords), - "link" => "/-/actions/$action[id]" - ]; - } - - foreach ($toys as $toy) { - $base = strtolower($toy["name"]); - $addKeywords = $toy["keywords"] ?? []; - $keywords = [ - $base, - ucfirst($base), - ucwords($base) - ]; - - for ($i = 0; $i < strlen($base); $i++) { - $keywords[] = substr($base, 0, $i) . strtoupper(substr($base, $i, 1)) . substr($base, $i + 1, strlen($base) - $i - 1); - - for ($j = 0; $j < strlen($base); $j++) { - $keywords[] = substr($base, 0, $i) . strtoupper(substr($base, $i, $j)) . substr($base, $i + $j, strlen($base) - $i - $j); - } - } - - foreach ($addKeywords as $keyword) { - $keywords[] = $keyword; - $keywords[] = ucfirst($keyword); - $keywords[] = ucwords($keyword); - - for ($i = 0; $i < strlen($keyword); $i++) { - $keywords[] = substr($keyword, 0, $i) . strtoupper(substr($keyword, $i, 1)) . substr($keyword, $i + 1, strlen($keyword) - $i - 1); - - for ($j = 0; $j < strlen($keyword); $j++) { - $keywords[] = substr($keyword, 0, $i) . strtoupper(substr($keyword, $i, $j)) . substr($keyword, $i + $j, strlen($keyword) - $i - $j); - } - } - } - - $pages[$toy["id"]] = [ - "keywords" => array_unique($keywords), - "link" => "/-/toys/$toy[id]" - ]; - } - - $keywords = []; - foreach ($pages as $page) { - foreach ($page["keywords"] as $keyword) { - $keywords[] = [ - "keyword" => $keyword, - "link" => $page["link"] - ]; - } - } - - uasort($keywords, function ($a, $b) { - return strlen($b["keyword"]) - strlen($a["keyword"]); - }); - - return $keywords; -} - -function replaceKeyWords(string $input): string { - $keywords = getKeyWords(); - - foreach ($keywords as $data) { - $keyword = $data["keyword"]; - $url = $data["link"]; - - $input = str_replace($keyword, "$keyword", $input); - } - - return $input; -} \ No newline at end of file diff --git a/includes/logo.inc b/includes/logo.inc new file mode 100644 index 0000000..442ff2b --- /dev/null +++ b/includes/logo.inc @@ -0,0 +1,97 @@ += $columns) { + $packs[] = $currentPack; + $currentPack = []; + } + + $currentPack[] = $member["color"]; +} + +if (count($currentPack) > 0) $packs[] = $currentPack; + +$newPacks = []; +foreach ($packs as $pack) { + usort($pack, function ($a, $b) { + $vra = hexdec(substr($a, 0, 2)); + $vga = hexdec(substr($a, 2, 2)); + $vba = hexdec(substr($a, 4, 2)); + + $hsla = rgbToHsl($vra, $vga, $vba); + $ra = $hsla[2] * $hsla[1]; + + $vrb = hexdec(substr($b, 0, 2)); + $vgb = hexdec(substr($b, 2, 2)); + $vbb = hexdec(substr($b, 4, 2)); + + $hslb = rgbToHsl($vrb, $vgb, $vbb); + $rb = $hslb[2] * $hslb[1]; + + return $rb < $ra; + }); + + while (count($pack) < $columns) $pack[] = "ffffff"; + + $newPacks[] = $pack; +} + +$img = imagecreatetruecolor($columns, $columns); +$factor = 64; + +for ($y = 0; $y < $columns; ++$y) { + for ($x = 0; $x < $columns; ++$x) { + imagesetpixel($img, $x, $y, imagecolorallocate($img, hexdec(substr($newPacks[$y][$x], 0, 2)), hexdec(substr($newPacks[$y][$x], 2, 2)), hexdec(substr($newPacks[$y][$x], 4, 2)))); + } +} + +$img2 = imagecreatetruecolor($columns * $factor, $columns * $factor); +imagecopyresampled($img2, $img, 0, 0, 0, 0, $columns * $factor, $columns * $factor, $columns, $columns); + +imagepng($img2, "/tmp/image.png"); +$img3 = imageCreateCorners("/tmp/image.png", $columns * 10); +unlink("/tmp/image.png"); + +imagepng($img3, $_SERVER['DOCUMENT_ROOT'] . "/assets/logo/newlogo.png"); + +for ($x = 1; $x <= 120; $x++) { + imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR); +} + +imagefilter($img2, IMG_FILTER_BRIGHTNESS, -100); + +imagepng($img2, "/tmp/image.png"); +$img3 = imageCreateCorners("/tmp/image.png", $columns * 10); +unlink("/tmp/image.png"); + +imagepng($img3, $_SERVER['DOCUMENT_ROOT'] . "/assets/logo/newlogo-template.png"); \ No newline at end of file diff --git a/includes/member.inc b/includes/member.inc new file mode 100644 index 0000000..2a0c346 --- /dev/null +++ b/includes/member.inc @@ -0,0 +1,268 @@ + + +
+
+ + +
+
+
"> +
+ Food:
+ "Not needed", + 1 => "Not animals", + 2 => "Not meat", + 3 => "All", + } ?> +
+
+ Shared memory:
+ "None", + 1 => "Partial", + 2 => "Full", + } ?> +
+
+ Magic:
+ "None", + 1 => "In some cases", + 2 => "Horn", + 3 => "Wings", + 4 => "Horn and wings", + 5 => "Yes", + } ?> +
+ +
+ Sensitivity:
+ "None", + 1 => "Maybe", + 2 => "Affectionate", + 3 => "Sexual", + 4 => "Affectionate and sexual", + } ?> +
+
+ Age:
+ + + - + + " . $metadata["birth"]["age"] . "* years old" ?> + + + + - + + + " . $age . " years old" ?> + + +
+
+ Birthday:
+ + + + - + +
+ +
+
+ +
+ + + +
+ + + +
+ This member's metadata needs an update. It still uses the old JSON metadata system instead of the new 24bit integer-based system. Contact a developer to request an update. (only administrators can see this; file: /includes/data/metadata/.json) +
+ +
+
+ Private administrator information +
    +
  • ID: (, )
  • +
  • Files: +
      +
    • ()
    • +
    • ()
    • +
    • ()
    • +
    +
  • +
  • Date added: (, )
  • +
  • Pronouns:
  • +
  • Pronouns usage:
      $usage) { + if (is_string($usage) && $type !== "color") { + echo("
    • " . $type . ": " . $usage . "
    • "); + } + } + + ?>
  • +
  • Color: ;display:inline-block;width:16px;height:16px;border-radius:5px;vertical-align: middle;filter: invert(1) hue-rotate(180deg);"> # +
  • Bitset: (0x, )
  • Not using bitset; please update. +
  • Reduced name:
  • +
  • Shared memory access: ()
  • +
  • Protector: ()
  • +
  • Little: ()
  • +
  • Relations count:
  • + +
  • + Score breakdown: +
      +
    • Most common fronter score:
    • +
    • Relationships score:
    • +
    • Fictive score:
    • +
    • Median score:
    • +
    • Species score:
    • +
    • Little score:
    • +
    • Not talking score:
    • +
    • Protector score:
    • +
    • Name score:
    • +
    • Shared memory score:
    • +
    +
  • +
  • Full metadata:
      $usage) { + if (is_string($usage)) { + echo("
    • " . $type . ": " . $usage . "
    • "); + } else { + echo("
    • " . $type . ": " . json_encode($usage, JSON_UNESCAPED_SLASHES) . "
    • "); + } + } + + ?>
  • +
+ +
+
+ AI-generated page: + +
+
+
+ + +
+ is visiting the since , therefore currently not in the . +
+ + +
+

Hello there!

+

I'm currently a new headmate slowly figuring myself out.

+

Give me some time to figure myself out and see this page change as I find new stuff about my identity. Don't be too worried if I accidentally get pushed to front, it's something that can happen sometimes.

+ Thanks! +
+ + +
+ +
+

Hello there!

+

I'm currently not totally sure who I am (it's a thing that can happen with plurality), but I am using as a temporary identity to stay calm and not panic while I figure out what is going on and who I am.

+

I can either be an existing headmate who cannot work out they are fronting (this can sometimes happen when one of us gets pushed out of front), multiple headmates blurring who cannot work out who we are, or a new pony trying to figure out their identity (this can sometimes take a while).

+ In all cases, feel free to ask! +
+ +
+

Hello there!

+

I'm the result of more than one pony temporarily merging together to the point they are unable to be told apart (this can be done for various reasons). We have not registered this switch for the "Unknown" member since this merge is made on purpose.

+

Below is the list of who is merged, we can be either from a single system or from different systems.

+ + + No members are currently merged. + +
+ + + (edit: public, private) + + + + +
+ + + + + +

This page is automatically generated and may not be 100% accurate.

+ + + +
+
+ + \ No newline at end of file diff --git a/includes/member.php b/includes/member.php deleted file mode 100644 index d0120d5..0000000 --- a/includes/member.php +++ /dev/null @@ -1,268 +0,0 @@ - - -
-
- - -
-
-
"> -
- Food:
- "Not needed", - 1 => "Not animals", - 2 => "Not meat", - 3 => "All", - } ?> -
-
- Shared memory:
- "None", - 1 => "Partial", - 2 => "Full", - } ?> -
-
- Magic:
- "None", - 1 => "In some cases", - 2 => "Horn", - 3 => "Wings", - 4 => "Horn and wings", - 5 => "Yes", - } ?> -
- -
- Sensitivity:
- "None", - 1 => "Maybe", - 2 => "Affectionate", - 3 => "Sexual", - 4 => "Affectionate and sexual", - } ?> -
-
- Age:
- - - - - - " . $metadata["birth"]["age"] . "* years old" ?> - - - - - - - - " . $age . " years old" ?> - - -
-
- Birthday:
- - - - - - -
- -
-
- -
- - - -
- - - -
- This member's metadata needs an update. It still uses the old JSON metadata system instead of the new 24bit integer-based system. Contact a developer to request an update. (only administrators can see this; file: /includes/data/--metadata.json) -
- -
-
- Private administrator information -
    -
  • ID: (, )
  • -
  • Files: -
      -
    • ()
    • -
    • ()
    • -
    • ()
    • -
    -
  • -
  • Date added: (, )
  • -
  • Pronouns:
  • -
  • Pronouns usage:
      $usage) { - if (is_string($usage) && $type !== "color") { - echo("
    • " . $type . ": " . $usage . "
    • "); - } - } - - ?>
  • -
  • Color: ;display:inline-block;width:16px;height:16px;border-radius:5px;vertical-align: middle;filter: invert(1) hue-rotate(180deg);"> # -
  • Bitset: (0x, )
  • Not using bitset; please update. -
  • Reduced name:
  • -
  • Shared memory access: ()
  • -
  • Protector: ()
  • -
  • Little: ()
  • -
  • Relations count:
  • - -
  • - Score breakdown: -
      -
    • Most common fronter score:
    • -
    • Relationships score:
    • -
    • Fictive score:
    • -
    • Median score:
    • -
    • Species score:
    • -
    • Little score:
    • -
    • Not talking score:
    • -
    • Protector score:
    • -
    • Name score:
    • -
    • Shared memory score:
    • -
    -
  • -
  • Full metadata:
      $usage) { - if (is_string($usage)) { - echo("
    • " . $type . ": " . $usage . "
    • "); - } else { - echo("
    • " . $type . ": " . json_encode($usage, JSON_UNESCAPED_SLASHES) . "
    • "); - } - } - - ?>
  • -
- -
-
- AI-generated page: - -
-
-
- - -
- is visiting the since , therefore currently not in the . -
- - -
-

Hello there!

-

I'm currently a new headmate slowly figuring myself out.

-

Give me some time to figure myself out and see this page change as I find new stuff about my identity. Don't be too worried if I accidentally get pushed to front, it's something that can happen sometimes.

- Thanks! -
- - -
- -
-

Hello there!

-

I'm currently not totally sure who I am (it's a thing that can happen with plurality), but I am using as a temporary identity to stay calm and not panic while I figure out what is going on and who I am.

-

I can either be an existing headmate who cannot work out they are fronting (this can sometimes happen when one of us gets pushed out of front), multiple headmates blurring who cannot work out who we are, or a new pony trying to figure out their identity (this can sometimes take a while).

- In all cases, feel free to ask! -
- -
-

Hello there!

-

I'm the result of more than one pony temporarily merging together to the point they are unable to be told apart (this can be done for various reasons). We have not registered this switch for the "Unknown" member since this merge is made on purpose.

-

Below is the list of who is merged, we can be either from a single system or from different systems.

- - - No members are currently merged. - -
- - - (edit: public, private) - - - - -
- - - - - -

This page is automatically generated and may not be 100% accurate.

- - - -
-
- - \ No newline at end of file diff --git a/includes/member/hierarchy.inc b/includes/member/hierarchy.inc new file mode 100644 index 0000000..dfb42c9 --- /dev/null +++ b/includes/member/hierarchy.inc @@ -0,0 +1,177 @@ + + +
+
+

's hierarchy

+
+ + + +

Part of:

+ + +
+ + 0): ?> +

Protected by:

+
+ +
+ +
+ +
+ +
+ + + 0): ?> +

Taken care of by:

+
+ +
+ +
+ +
+ +
+ + +

Member:

+
+
+ +
+
+ + 0): ?> +
+ +

Taking care of:

+
+ +
+ +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/includes/member/hierarchy.php b/includes/member/hierarchy.php deleted file mode 100644 index 301bd1c..0000000 --- a/includes/member/hierarchy.php +++ /dev/null @@ -1,177 +0,0 @@ - - -
-
-

's hierarchy

-
- - - -

Part of:

- - -
- - 0): ?> -

Protected by:

-
- -
- -
- -
- -
- - - 0): ?> -

Taken care of by:

-
- -
- -
- -
- -
- - -

Member:

-
-
- -
-
- - 0): ?> -
- -

Taking care of:

-
- -
- -
- -
- -
- - - - \ No newline at end of file diff --git a/includes/member/tree.inc b/includes/member/tree.inc new file mode 100644 index 0000000..2e94951 --- /dev/null +++ b/includes/member/tree.inc @@ -0,0 +1,8 @@ + $day) { + foreach ($day as $index => $fronter) { + if (is_string($fronter)) { + $cloudburst[$id][$index] = [$fronter]; + } else if (is_array($fronter)) { + if (count($fronter) < 2) { + if (!isset($cloudburst[$id][$index][0])) $cloudburst[$id][$index][0] = null; + $cloudburst[$id][$index][1] = null; + } else if (count($fronter) > 2) { + $array = []; + + if (isset($cloudburst[$id][$index][0])) { + $array[0] = $cloudburst[$id][$index][0]; + } else { + $array[0] = null; + } + + if (isset($cloudburst[$id][$index][1])) { + $array[1] = $cloudburst[$id][$index][1]; + } else { + $array[1] = null; + } + + $cloudburst[$id][$index] = $array; + } + } + } +} + +foreach ($raindrops as $id => $day) { + foreach ($day as $index => $fronter) { + if (is_string($fronter)) { + $raindrops[$id][$index] = [$fronter]; + } else if (is_array($fronter)) { + if (count($fronter) < 2) { + if (!isset($raindrops[$id][$index][0])) $raindrops[$id][$index][0] = null; + $raindrops[$id][$index][1] = null; + } else if (count($fronter) > 2) { + $array = []; + + if (isset($raindrops[$id][$index][0])) { + $array[0] = $raindrops[$id][$index][0]; + } else { + $array[0] = null; + } + + if (isset($raindrops[$id][$index][1])) { + $array[1] = $raindrops[$id][$index][1]; + } else { + $array[1] = null; + } + + $raindrops[$id][$index] = $array; + } + } + } +} + +function day($display, $diff): void { if ($diff < 0) $disabled = true; else $disabled = false; global $cloudburst; global $raindrops; ?> + + style="opacity: .75; pointer-events: none;"> + + + + style="opacity: .75; pointer-events: none;"> + Cloudburst System + Raindrops System + + + style="opacity: .75; pointer-events: none;"> + + + + + colspan="3" colspan="2"> + + + Multiple merged membersMerge + + " style="width:24px;"> + + + + + + + + + + + + + Multiple merged membersMerge + + " style="width:24px;"> + + + + + + + + Add new fronter + + + + + + + + + + + colspan="3" colspan="2"> + + Multiple merged membersMerge + + " style="width:24px;"> + + + + + + + + + + + + + Multiple merged membersMerge + + " style="width:24px;"> + + + + + + + + Add new fronter + + + + + + + + style="opacity: .75; pointer-events: none;"> + + 0 && count($dayRaindrops) > 0): ?> + will sleep with + + Unable to calculate who will sleep with who + + + + + + +

Front planner

+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/includes/planner.php b/includes/planner.php deleted file mode 100644 index f98d83b..0000000 --- a/includes/planner.php +++ /dev/null @@ -1,926 +0,0 @@ - $day) { - foreach ($day as $index => $fronter) { - if (is_string($fronter)) { - $cloudburst[$id][$index] = [$fronter]; - } else if (is_array($fronter)) { - if (count($fronter) < 2) { - if (!isset($cloudburst[$id][$index][0])) $cloudburst[$id][$index][0] = null; - $cloudburst[$id][$index][1] = null; - } else if (count($fronter) > 2) { - $array = []; - - if (isset($cloudburst[$id][$index][0])) { - $array[0] = $cloudburst[$id][$index][0]; - } else { - $array[0] = null; - } - - if (isset($cloudburst[$id][$index][1])) { - $array[1] = $cloudburst[$id][$index][1]; - } else { - $array[1] = null; - } - - $cloudburst[$id][$index] = $array; - } - } - } -} - -foreach ($raindrops as $id => $day) { - foreach ($day as $index => $fronter) { - if (is_string($fronter)) { - $raindrops[$id][$index] = [$fronter]; - } else if (is_array($fronter)) { - if (count($fronter) < 2) { - if (!isset($raindrops[$id][$index][0])) $raindrops[$id][$index][0] = null; - $raindrops[$id][$index][1] = null; - } else if (count($fronter) > 2) { - $array = []; - - if (isset($raindrops[$id][$index][0])) { - $array[0] = $raindrops[$id][$index][0]; - } else { - $array[0] = null; - } - - if (isset($raindrops[$id][$index][1])) { - $array[1] = $raindrops[$id][$index][1]; - } else { - $array[1] = null; - } - - $raindrops[$id][$index] = $array; - } - } - } -} - -function day($display, $diff): void { global $cloudburst; global $raindrops; ?> - - - - - - - Cloudburst System - Raindrops System - - - - - - - - colspan="3" colspan="2"> - - - Multiple merged membersMerge - - .png" style="width:24px;"> - - - - - - - - - - - - - Multiple merged membersMerge - - .png" style="width:24px;"> - - - - - - - - Add new fronter - - - - - - - - - - - colspan="3" colspan="2"> - - Multiple merged membersMerge - - .png" style="width:24px;"> - - - - - - - - - - - - - Multiple merged membersMerge - - .png" style="width:24px;"> - - - - - - - - Add new fronter - - - - - - - - - - 0 && count($dayRaindrops) > 0): ?> - will sleep with - - Unable to calculate who will sleep with who - - - - - - -

Front planner

- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/includes/pleasure.inc b/includes/pleasure.inc new file mode 100644 index 0000000..8b4835b --- /dev/null +++ b/includes/pleasure.inc @@ -0,0 +1,114 @@ +

Pleasure alert +
+ + · +
+

+ +Turn ON + +

Sending next notification never

+ + + + + + \ No newline at end of file diff --git a/includes/pleasure.php b/includes/pleasure.php deleted file mode 100644 index 8b4835b..0000000 --- a/includes/pleasure.php +++ /dev/null @@ -1,114 +0,0 @@ -

Pleasure alert -
- - · -
-

- -Turn ON - -

Sending next notification never

- - - - - - \ No newline at end of file diff --git a/includes/pronouns.inc b/includes/pronouns.inc new file mode 100644 index 0000000..6ab2487 --- /dev/null +++ b/includes/pronouns.inc @@ -0,0 +1,149 @@ + [ + "gender" => "ponygender", + "gender:fr" => "poneygenre", + "object" => "pony", + "person" => "pony", + "possessive_det" => "pony's", + "possessive_pro" => "pony's", + "reflexive" => "ponyself", + "subjective" => "pony", + "third" => true, + "color" => "warning" + ], + "she" => [ + "gender" => "female", + "gender:fr" => "fille", + "object" => "her", + "person" => "girl", + "possessive_det" => "her", + "possessive_pro" => "hers", + "reflexive" => "herself", + "subjective" => "she", + "third" => true, + "color" => "success" + ], + "he" => [ + "gender" => "male", + "gender:fr" => "garçon", + "object" => "him", + "person" => "boy", + "possessive_det" => "his", + "possessive_pro" => "his", + "reflexive" => "himself", + "subjective" => "he", + "third" => true, + "color" => "info" + ], + "it" => [ + "gender" => "agender", + "gender:fr" => "agenre", + "object" => "it", + "person" => "person", + "possessive_det" => "its", + "possessive_pro" => "its", + "reflexive" => "itself", + "subjective" => "it", + "third" => true, + "color" => "light" + ], + "they" => [ + "gender" => "non binary", + "gender:fr" => "non binaire", + "object" => "them", + "person" => "person", + "possessive_det" => "their", + "possessive_pro" => "theirs", + "reflexive" => "themself", + "subjective" => "they", + "third" => false, + "color" => "primary" + ] +]; + +$pronounGetCount = 0; + +$possibilitiesPerSet = []; +foreach ($pronounsSets as $name => $set) { + if (!isset($possibilitiesPerSet[$name])) $possibilitiesPerSet[$name] = []; + $possibilitiesPerSet[$name][] = $name; + + foreach ($set as $category => $value) { + if (is_string($value)) $possibilitiesPerSet[$name][] = $value; + } +} + +function getSetFromValue(string $value) { + global $possibilitiesPerSet; + + foreach ($possibilitiesPerSet as $name => $set) { + if (in_array($value, $set)) { + return $name; + } + } + + return null; +} + +function getPronounsFromMark(?string $mark = null): array { + if (!isset($mark) || trim($mark) === "") { + return ["they"]; + } else { + $parts = array_unique(array_map(function ($i) { + return getSetFromValue($i); + }, explode("/", $mark))); + return $parts; + } +} + +function getMemberPronouns(?string $pronouns): ?array { + global $pronounsSets; + $list = getPronounsFromMark($pronouns); + return $pronounsSets[$list[array_rand($list)]] ?? $pronounsSets["she"]; +} + +function getGenderFromPronoun(string $pronoun, bool $french = false) { + global $pronounsSets; + $set = getPronounsFromMark($pronoun)[0]; + + if ($french) { + return ($pronounsSets[$set] ?? $pronounsSets["they"])["gender:fr"]; + } else { + return ($pronounsSets[$set] ?? $pronounsSets["they"])["gender"]; + } +} + +function pronounInFrench(string $pronoun): string { + return match ($pronoun) { + "she" => "elle", + "her" => "elle", + "he" => "il", + "him" => "lui", + "they" => "iel", + "them" => "iel", + "it" => "iel", + "its" => "iel", + "pony" => "poney", + "pony's" => "à poney", + "ponys" => "à poney", + default => $pronoun, + }; +} + +function getTooltipsFromMark(string $mark = null, bool $french = false): ?string { + if (!isset($mark)) { + return null; + } else { + if ($french) { + return implode("/", array_map(function ($i) { + return "" . pronounInFrench($i) . ""; + }, explode("/", $mark))); + } else { + return implode("/", array_map(function ($i) { + return "" . $i . ""; + }, explode("/", $mark))); + } + } +} \ No newline at end of file diff --git a/includes/pronouns.php b/includes/pronouns.php deleted file mode 100644 index 6ab2487..0000000 --- a/includes/pronouns.php +++ /dev/null @@ -1,149 +0,0 @@ - [ - "gender" => "ponygender", - "gender:fr" => "poneygenre", - "object" => "pony", - "person" => "pony", - "possessive_det" => "pony's", - "possessive_pro" => "pony's", - "reflexive" => "ponyself", - "subjective" => "pony", - "third" => true, - "color" => "warning" - ], - "she" => [ - "gender" => "female", - "gender:fr" => "fille", - "object" => "her", - "person" => "girl", - "possessive_det" => "her", - "possessive_pro" => "hers", - "reflexive" => "herself", - "subjective" => "she", - "third" => true, - "color" => "success" - ], - "he" => [ - "gender" => "male", - "gender:fr" => "garçon", - "object" => "him", - "person" => "boy", - "possessive_det" => "his", - "possessive_pro" => "his", - "reflexive" => "himself", - "subjective" => "he", - "third" => true, - "color" => "info" - ], - "it" => [ - "gender" => "agender", - "gender:fr" => "agenre", - "object" => "it", - "person" => "person", - "possessive_det" => "its", - "possessive_pro" => "its", - "reflexive" => "itself", - "subjective" => "it", - "third" => true, - "color" => "light" - ], - "they" => [ - "gender" => "non binary", - "gender:fr" => "non binaire", - "object" => "them", - "person" => "person", - "possessive_det" => "their", - "possessive_pro" => "theirs", - "reflexive" => "themself", - "subjective" => "they", - "third" => false, - "color" => "primary" - ] -]; - -$pronounGetCount = 0; - -$possibilitiesPerSet = []; -foreach ($pronounsSets as $name => $set) { - if (!isset($possibilitiesPerSet[$name])) $possibilitiesPerSet[$name] = []; - $possibilitiesPerSet[$name][] = $name; - - foreach ($set as $category => $value) { - if (is_string($value)) $possibilitiesPerSet[$name][] = $value; - } -} - -function getSetFromValue(string $value) { - global $possibilitiesPerSet; - - foreach ($possibilitiesPerSet as $name => $set) { - if (in_array($value, $set)) { - return $name; - } - } - - return null; -} - -function getPronounsFromMark(?string $mark = null): array { - if (!isset($mark) || trim($mark) === "") { - return ["they"]; - } else { - $parts = array_unique(array_map(function ($i) { - return getSetFromValue($i); - }, explode("/", $mark))); - return $parts; - } -} - -function getMemberPronouns(?string $pronouns): ?array { - global $pronounsSets; - $list = getPronounsFromMark($pronouns); - return $pronounsSets[$list[array_rand($list)]] ?? $pronounsSets["she"]; -} - -function getGenderFromPronoun(string $pronoun, bool $french = false) { - global $pronounsSets; - $set = getPronounsFromMark($pronoun)[0]; - - if ($french) { - return ($pronounsSets[$set] ?? $pronounsSets["they"])["gender:fr"]; - } else { - return ($pronounsSets[$set] ?? $pronounsSets["they"])["gender"]; - } -} - -function pronounInFrench(string $pronoun): string { - return match ($pronoun) { - "she" => "elle", - "her" => "elle", - "he" => "il", - "him" => "lui", - "they" => "iel", - "them" => "iel", - "it" => "iel", - "its" => "iel", - "pony" => "poney", - "pony's" => "à poney", - "ponys" => "à poney", - default => $pronoun, - }; -} - -function getTooltipsFromMark(string $mark = null, bool $french = false): ?string { - if (!isset($mark)) { - return null; - } else { - if ($french) { - return implode("/", array_map(function ($i) { - return "" . pronounInFrench($i) . ""; - }, explode("/", $mark))); - } else { - return implode("/", array_map(function ($i) { - return "" . $i . ""; - }, explode("/", $mark))); - } - } -} \ No newline at end of file diff --git a/includes/rail.inc b/includes/rail.inc new file mode 100644 index 0000000..b2ed467 --- /dev/null +++ b/includes/rail.inc @@ -0,0 +1,176 @@ + + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ + + + \ No newline at end of file diff --git a/includes/rainbow.inc b/includes/rainbow.inc new file mode 100644 index 0000000..470f288 --- /dev/null +++ b/includes/rainbow.inc @@ -0,0 +1,57 @@ + $member + ]; + + if (isset($member["color"])) { + $data[$member["name"]]["rgb"] = [ + hexdec(substr($member["color"], 0, 2)), + hexdec(substr($member["color"], 2, 2)), + hexdec(substr($member["color"], 4, 2)) + ]; + $data[$member["name"]]["hsl"] = rgbToHsl( + $data[$member["name"]]["rgb"][0], + $data[$member["name"]]["rgb"][1], + $data[$member["name"]]["rgb"][2] + ); + } else { + $data[$member["name"]]["rgb"] = [255, 255, 255]; + $data[$member["name"]]["hsl"] = rgbToHsl(255, 255, 255); + } + } + + return $data; +} + +function getMembersByColor(): array { + $members = rainbow(); + uasort($members, function ($a, $b) { + return $a['hsl'][0] - $b['hsl'][0]; + }); + $members = [ + ...array_filter($members, function ($i) { + return $i['hsl'][2] < 0.9 || $i['hsl'][1] > 0.2; + }), + ...array_filter($members, function ($i) { + return $i['hsl'][2] >= 0.9 || $i['hsl'][1] <= 0.2; + }) + ]; + + $sorted = []; + foreach ($members as $data) { + $data["_data"]["hue"] = $data["hsl"][0]; + $sorted[] = $data["_data"]; + } + + return $sorted; +} \ No newline at end of file diff --git a/includes/rainbow.php b/includes/rainbow.php deleted file mode 100644 index c710be0..0000000 --- a/includes/rainbow.php +++ /dev/null @@ -1,97 +0,0 @@ - $g) { - $h += 360; - } - break; - - case $g: - $h = 60 * (($b - $r) / $d + 2); - break; - - case $b: - $h = 60 * (($r - $g) / $d + 4); - break; - } - } - - return array(round($h, 2), round($s, 2), round($l, 2)); -} - -function rainbow(): array { - $members = scoreOrderGlobal(); - $data = []; - - foreach ($members as $member) { - $data[$member["name"]] = [ - "_data" => $member - ]; - - if (isset($member["color"])) { - $data[$member["name"]]["rgb"] = [ - hexdec(substr($member["color"], 0, 2)), - hexdec(substr($member["color"], 2, 2)), - hexdec(substr($member["color"], 4, 2)) - ]; - $data[$member["name"]]["hsl"] = rgbToHsl( - $data[$member["name"]]["rgb"][0], - $data[$member["name"]]["rgb"][1], - $data[$member["name"]]["rgb"][2] - ); - } else { - $data[$member["name"]]["rgb"] = [255, 255, 255]; - $data[$member["name"]]["hsl"] = rgbToHsl(255, 255, 255); - } - } - - return $data; -} - -function getMembersByColor(): array { - $members = rainbow(); - uasort($members, function ($a, $b) { - return $a['hsl'][0] - $b['hsl'][0]; - }); - $members = [ - ...array_filter($members, function ($i) { - return $i['hsl'][2] < 0.9 || $i['hsl'][1] > 0.2; - }), - ...array_filter($members, function ($i) { - return $i['hsl'][2] >= 0.9 || $i['hsl'][1] <= 0.2; - }) - ]; - - $sorted = []; - foreach ($members as $data) { - $data["_data"]["hue"] = $data["hsl"][0]; - $sorted[] = $data["_data"]; - } - - return $sorted; -} \ No newline at end of file diff --git a/includes/random.inc b/includes/random.inc new file mode 100644 index 0000000..b6e7905 --- /dev/null +++ b/includes/random.inc @@ -0,0 +1,15 @@ + $versionHash[1], + "old" => isset($version["list"]) ? $version["list"]["current"] ?? null : null + ]; + $version["build"]++; +} else { + $version["revision"]++; +} + +file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/version.json", json_encode($version)); +$times["version"] = microtime(true) - $currentOpStart; + $currentOpStart = microtime(true); foreach (array_filter(scandir("./data"), function ($i) { - return !str_starts_with($i, ".") && $i !== "backup" && is_file("./data/" . $i); + return !str_starts_with($i, ".") && $i !== "backup" && (is_file("./data/" . $i) || is_dir("./data/" . $i)); }) as $file) { - $files[] = $file; + if (is_dir("./data/" . $file)) { + foreach (array_filter(scandir("./data"), function ($i) use ($file) { + return !str_starts_with($i, ".") && $i !== "backup" && is_file("./data/" . $file . "/" . $i); + }) as $file2) { + @mkdir("./data/backup/" . $file); + $files[] = $file . "/" . $file2; + } + } else { + $files[] = $file; + } } @mkdir("./data/backup"); @@ -57,17 +132,28 @@ function getSystem(string $id) { echo(" Base system info\n"); $currentOpStart = microtime(true); - file_put_contents("./data/$id-general.json", file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id")); + $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id"); + + if (trim($data) !== "" && $data !== false) { + file_put_contents("./data/$id/general.json", $data); + } $times["system-general-$id"] = microtime(true) - $currentOpStart; echo(" System members\n"); $currentOpStart = microtime(true); - file_put_contents("./data/$id-members.json", file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/members")); + $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/members"); + + if (trim($data) !== "" && $data !== false) { + file_put_contents("./data/$id/members.json", $data); + } $times["system-members-$id"] = microtime(true) - $currentOpStart; echo(" Fronters\n"); - $currentOpStart = microtime(true); - file_put_contents("./data/$id-fronters.json", file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/fronters")); + $data = file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/fronters"); + + if (trim($data) !== "" && $data !== false) { + file_put_contents("./data/$id/fronters.json", $data); + } $times["system-fronters-$id"] = microtime(true) - $currentOpStart; echo(" Switches\n"); @@ -84,8 +170,10 @@ function getSystem(string $id) { echo(" Part 3/3\n"); $switches3 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches?before=$oldest"), true); - file_put_contents("./data/$id-switches.json", json_encode([...$switches1, ...$switches2, ...$switches3], JSON_PRETTY_PRINT)); - $times["system-switches-$id"] = microtime(true) - $currentOpStart; + if ($switches1 !== null && $switches2 !== null && $switches3 !== null) { + file_put_contents("./data/$id/switches.json", json_encode([...$switches1, ...$switches2, ...$switches3], JSON_PRETTY_PRINT)); + $times["system-switches-$id"] = microtime(true) - $currentOpStart; + } } getSystem("gdapd"); // Raindrops @@ -93,13 +181,13 @@ getSystem("ynmuc"); // Cloudburst echo("Calendar\n"); $currentOpStart = microtime(true); -file_put_contents("./data/calendar.ics", file_get_contents($app["calendar"])); +file_put_contents("./data/calendar/calendar.ics", file_get_contents($app["calendar"])); $times["calendar"] = microtime(true) - $currentOpStart; echo("Downloading images.\n"); if (!file_exists("./data/images")) mkdir("./data/images"); -foreach (json_decode(file_get_contents("./data/gdapd-members.json"), true) as $member) { +foreach (json_decode(file_get_contents("./data/gdapd/members.json"), true) as $member) { $currentOpStart2 = microtime(true); echo(" " . $member['id'] . "\n"); @@ -117,7 +205,7 @@ foreach (json_decode(file_get_contents("./data/gdapd-members.json"), true) as $m $times["images-gdapd-" . $member['id']] = microtime(true) - $currentOpStart2; } -foreach (json_decode(file_get_contents("./data/ynmuc-members.json"), true) as $member) { +foreach (json_decode(file_get_contents("./data/ynmuc/members.json"), true) as $member) { $currentOpStart2 = microtime(true); echo(" " . $member['id'] . "\n"); @@ -152,12 +240,36 @@ $times["restore"] = microtime(true) - $currentOpStart; echo("Backing up...\n"); if (date('i') === "00") { - require_once "./backup.php"; + require_once "./backup.inc"; echo("Backup completed\n"); } else { echo("Backup skipped\n"); } +echo("Generating logo...\n"); + +$currentOpStart = microtime(true); +require_once "./logo.inc"; +$times["logo"] = microtime(true) - $currentOpStart; + +echo("Generated logo\n"); + +echo("Generating favicons...\n"); + +$currentOpStart = microtime(true); +require_once "./icons.inc"; +$times["favicons"] = microtime(true) - $currentOpStart; + +echo("Generated favicons\n"); + +echo("Downloading assets...\n"); + +$currentOpStart = microtime(true); +require_once "./assets.inc"; +$times["assets"] = microtime(true) - $currentOpStart; + +echo("Downloading assets\n"); + $time = array_sum($times); echo("Completed in " . $time . " seconds.\n"); diff --git a/includes/restore.inc b/includes/restore.inc new file mode 100644 index 0000000..72748ab --- /dev/null +++ b/includes/restore.inc @@ -0,0 +1,130 @@ += 0) { + return $tense = "now"; + } elseif ($difference > 0) { + $tense = "ago"; + } else { + $tense = "later"; + } + + for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { + $difference /= $lengths[$j]; + } + + $difference = round($difference); + + $period = $periods[$j] . ($difference >1 ? "s" :''); + return "{$difference} {$period} {$tense}"; +} + +if (!isset($_SERVER['argv'][1]) || !isset($_SERVER['argv'][2])) { + echo("Usage: php " . $_SERVER['argv'][0] . " \n"); + die(); +} else { + $file = @file_get_contents($_SERVER['argv'][1]); + $raw = @file_get_contents($_SERVER['argv'][2]); + + if ($file === false) { + echo("Unable to open backup file\n"); + die(); + } + + if ($raw === false) { + echo("Unable to open key file\n"); + die(); + } + + $raw2 = base64_decode($raw); + + if (!isJson($raw2)) { + echo("Key file is corrupt\n"); + die(); + } + + $keydata = json_decode($raw2, true); + + if (!is_array($keydata) || !isset($keydata["iv"]) || !isset($keydata["key"])) { + echo("Key file is invalid\n"); + die(); + } + + $iv = hex2bin($keydata["iv"]); + $key = hex2bin($keydata["key"]); + + $decrypted = openssl_decrypt($file, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); + + if ($decrypted === false) { + echo("Unable to decrypt backup\n"); + die(); + } + + $unpadded = pkcs7_unpad($decrypted); + + if (!is_string($unpadded)) { + echo("Unable to decrypt backup\n"); + die(); + } + + if (!isJson($unpadded)) { + echo("Backup is corrupt\n"); + die(); + } + + $data = json_decode($unpadded, true); + + if (!is_array($data) || !isset($data["date"]) || !isset($data["files"])) { + echo("Backup is invalid\n"); + die(); + } + + echo(realpath($_SERVER['argv'][1]) . "\n Key: " . $_SERVER['argv'][2] . "\n Date: " . date('r', strtotime($data["date"])) . " (" . timeAgo($data["date"]) . ")" . "\n Contents: " . count($data["files"]) . " files\n"); + + @mkdir("./_restored"); + + $index = 0; + foreach ($data["files"] as $file) { + if ($file["dir"] === "") { + print("[$index] /" . $file["file"] . "\n"); + } else { + print("[$index] /" . $file["dir"] . "/" . $file["file"] . "\n"); + } + + $content = base64_decode($file["content"]); + if (sha1($content) !== $file["checksum"][0]) { + print(" Backed up file is corrupted (SHA1 mismatch)\n Expected: " . $file["checksum"][0] . "\n Got: " . sha1($content) . "\n"); + die("Backup aborted.\n"); + } + if (md5($content) !== $file["checksum"][1]) { + print(" Backed up file is corrupted (MD5 mismatch)\n Expected: " . $file["checksum"][1] . "\n Got: " . md5($content) . "\n"); + die("Backup aborted.\n"); + } + + @mkdir("./_restored/" . $file["dir"], 0777, true); + file_put_contents("./_restored/" . $file["dir"] . "/" . $file["file"], $content); + + $index++; + } + + print("Restored backup to ./_restored; review files before restoring to production\n"); +} \ No newline at end of file diff --git a/includes/restore.php b/includes/restore.php deleted file mode 100644 index 72748ab..0000000 --- a/includes/restore.php +++ /dev/null @@ -1,130 +0,0 @@ -= 0) { - return $tense = "now"; - } elseif ($difference > 0) { - $tense = "ago"; - } else { - $tense = "later"; - } - - for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { - $difference /= $lengths[$j]; - } - - $difference = round($difference); - - $period = $periods[$j] . ($difference >1 ? "s" :''); - return "{$difference} {$period} {$tense}"; -} - -if (!isset($_SERVER['argv'][1]) || !isset($_SERVER['argv'][2])) { - echo("Usage: php " . $_SERVER['argv'][0] . " \n"); - die(); -} else { - $file = @file_get_contents($_SERVER['argv'][1]); - $raw = @file_get_contents($_SERVER['argv'][2]); - - if ($file === false) { - echo("Unable to open backup file\n"); - die(); - } - - if ($raw === false) { - echo("Unable to open key file\n"); - die(); - } - - $raw2 = base64_decode($raw); - - if (!isJson($raw2)) { - echo("Key file is corrupt\n"); - die(); - } - - $keydata = json_decode($raw2, true); - - if (!is_array($keydata) || !isset($keydata["iv"]) || !isset($keydata["key"])) { - echo("Key file is invalid\n"); - die(); - } - - $iv = hex2bin($keydata["iv"]); - $key = hex2bin($keydata["key"]); - - $decrypted = openssl_decrypt($file, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv); - - if ($decrypted === false) { - echo("Unable to decrypt backup\n"); - die(); - } - - $unpadded = pkcs7_unpad($decrypted); - - if (!is_string($unpadded)) { - echo("Unable to decrypt backup\n"); - die(); - } - - if (!isJson($unpadded)) { - echo("Backup is corrupt\n"); - die(); - } - - $data = json_decode($unpadded, true); - - if (!is_array($data) || !isset($data["date"]) || !isset($data["files"])) { - echo("Backup is invalid\n"); - die(); - } - - echo(realpath($_SERVER['argv'][1]) . "\n Key: " . $_SERVER['argv'][2] . "\n Date: " . date('r', strtotime($data["date"])) . " (" . timeAgo($data["date"]) . ")" . "\n Contents: " . count($data["files"]) . " files\n"); - - @mkdir("./_restored"); - - $index = 0; - foreach ($data["files"] as $file) { - if ($file["dir"] === "") { - print("[$index] /" . $file["file"] . "\n"); - } else { - print("[$index] /" . $file["dir"] . "/" . $file["file"] . "\n"); - } - - $content = base64_decode($file["content"]); - if (sha1($content) !== $file["checksum"][0]) { - print(" Backed up file is corrupted (SHA1 mismatch)\n Expected: " . $file["checksum"][0] . "\n Got: " . sha1($content) . "\n"); - die("Backup aborted.\n"); - } - if (md5($content) !== $file["checksum"][1]) { - print(" Backed up file is corrupted (MD5 mismatch)\n Expected: " . $file["checksum"][1] . "\n Got: " . md5($content) . "\n"); - die("Backup aborted.\n"); - } - - @mkdir("./_restored/" . $file["dir"], 0777, true); - file_put_contents("./_restored/" . $file["dir"] . "/" . $file["file"], $content); - - $index++; - } - - print("Restored backup to ./_restored; review files before restoring to production\n"); -} \ No newline at end of file diff --git a/includes/score.inc b/includes/score.inc new file mode 100644 index 0000000..c35e9bc --- /dev/null +++ b/includes/score.inc @@ -0,0 +1,86 @@ + $scoreHost, + "fictive" => $scoreFictive, + "little" => $scoreLittle, + "median" => $scoreMedian, + "not_talking" => $scoreNotTalking, + "name" => $scoreName, + "protector" => $scoreProtector, + "shared_memory" => $scoreSharedMemory, + "relations" => $scoreRelations, + "species" => $scoreSpecies, + "additional" => $scoreAdd, + "total" => $score + ]; +} + +function scoreOrder($members, $system) { + $ordered = []; + foreach ($members as $member) { + if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json")) { + $systemID = $member["system"] ?? $system; + + $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)); + $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)), $member["display_name"] ?? $member["name"]); + $ordered[] = $member; + } + } + + uasort($ordered, function($a, $b) { + return $b["_score"]["total"] - $a["_score"]["total"]; + }); + + return $ordered; +} + +function scoreOrderGlobal() { + $ordered = []; + foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true) as $member) { + if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json")) { + $member["_system"] = "gdapd"; + $member["system"] = "gdapd"; + $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)); + $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)), $member["display_name"] ?? $member["name"]); + $ordered[] = $member; + } + } + + foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true) as $member) { + if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json")) { + $member["_system"] = "ynmuc"; + $member["system"] = "ynmuc"; + $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)); + $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)), $member["display_name"] ?? $member["name"]); + $ordered[] = $member; + } + } + + uasort($ordered, function($a, $b) { + return $b["_score"]["total"] - $a["_score"]["total"]; + }); + + return array_values($ordered); +} \ No newline at end of file diff --git a/includes/score.php b/includes/score.php deleted file mode 100644 index cd8c389..0000000 --- a/includes/score.php +++ /dev/null @@ -1,81 +0,0 @@ - $scoreHost, - "fictive" => $scoreFictive, - "little" => $scoreLittle, - "median" => $scoreMedian, - "not_talking" => $scoreNotTalking, - "name" => $scoreName, - "protector" => $scoreProtector, - "shared_memory" => $scoreSharedMemory, - "relations" => $scoreRelations, - "species" => $scoreSpecies, - "additional" => $scoreAdd, - "total" => $score - ]; -} - -function scoreOrder($members, $system) { - $ordered = []; - foreach ($members as $member) { - if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($member["system"] ?? $system) . "-$member[id]-metadata.json")) { - $systemID = $member["system"] ?? $system; - - $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$member[id]-metadata.json"), true)); - $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$member[id]-metadata.json"), true)), $member["display_name"] ?? $member["name"]); - $ordered[] = $member; - } - } - - uasort($ordered, function($a, $b) { - return $b["_score"]["total"] - $a["_score"]["total"]; - }); - - return $ordered; -} - -function scoreOrderGlobal() { - $ordered = []; - foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true) as $member) { - if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json")) { - $member["_system"] = "gdapd"; - $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json"), true)); - $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json"), true)), $member["display_name"] ?? $member["name"]); - $ordered[] = $member; - } - } - foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true) as $member) { - if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json")) { - $member["_system"] = "ynmuc"; - $member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json"), true)); - $member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json"), true)), $member["display_name"] ?? $member["name"]); - $ordered[] = $member; - } - } - - uasort($ordered, function($a, $b) { - return $b["_score"]["total"] - $a["_score"]["total"]; - }); - - return $ordered; -} \ No newline at end of file diff --git a/includes/search.inc b/includes/search.inc new file mode 100644 index 0000000..d8e573f --- /dev/null +++ b/includes/search.inc @@ -0,0 +1,529 @@ + + + + + + + + \ No newline at end of file diff --git a/includes/search.php b/includes/search.php deleted file mode 100644 index 037b6de..0000000 --- a/includes/search.php +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/includes/session.inc b/includes/session.inc new file mode 100644 index 0000000..b440c9c --- /dev/null +++ b/includes/session.inc @@ -0,0 +1,41 @@ + "/raindrops", + "cb" => "/cloudburst", + "minty" => "/cloudydreams", + "cloudy" => "/cloudydreams", + "zipp" => "/zippstorm", + "babs" => "/babsseed", + "frost" => "/frostcrystals", + "violet" => "/violetdawn" +]; + +foreach ($members as $member) { + for ($i = 1; $i < strlen($member["name"]); $i++) { + $part = substr($member["name"], 0, $i); + + if (in_array($part, array_keys($list))) { + $list[$part] = false; + } else { + $list[$part] = "/" . $member["name"]; + } + } + + foreach ($member["proxy_tags"] as $proxy) { + $system = $member["_system"] === "gdapd" ? "rd" : "cb"; + $list[$system . preg_replace("/[^a-z]/m", "", $proxy["prefix"])] = "/" . $member["name"]; + } + + $list[$member["id"]] = "/" . $member["name"]; + $list[$member["uuid"]] = "/" . $member["name"]; +} + +$list["minty"] = "/cloudy"; + +if (in_array($toplevel, array_keys($list)) && $list[$toplevel]) { + if ($toplevel !== "unknown") { + header("Location: " . $list[$toplevel]); + } else { + header("Location: /?error=Page not found: " . strip_tags($toplevel)) and die(); + } +} else { + header("Location: /?error=Page not found: " . strip_tags($toplevel)) and die(); +} \ No newline at end of file diff --git a/includes/short.php b/includes/short.php deleted file mode 100644 index 59b3cae..0000000 --- a/includes/short.php +++ /dev/null @@ -1,52 +0,0 @@ - "/raindrops", - "cb" => "/cloudburst", - "minty" => "/cloudydreams", - "cloudy" => "/cloudydreams", - "zipp" => "/zippstorm", - "babs" => "/babsseed", - "frost" => "/frostcrystals", - "violet" => "/violetdawn" -]; - -foreach ($members as $member) { - for ($i = 1; $i < strlen($member["name"]); $i++) { - $part = substr($member["name"], 0, $i); - - if (in_array($part, array_keys($list))) { - $list[$part] = false; - } else { - $list[$part] = "/" . $member["name"]; - } - } - - foreach ($member["proxy_tags"] as $proxy) { - $system = $member["_system"] === "gdapd" ? "rd" : "cb"; - $list[$system . preg_replace("/[^a-z]/m", "", $proxy["prefix"])] = "/" . $member["name"]; - } - - $list[$member["id"]] = "/" . $member["name"]; - $list[$member["uuid"]] = "/" . $member["name"]; -} - -$list["minty"] = "/cloudy"; - -if (in_array($toplevel, array_keys($list)) && $list[$toplevel]) { - if ($toplevel !== "unknown") { - header("Location: " . $list[$toplevel]); - } else { - header("Location: /?error=Page not found: " . strip_tags($toplevel)) and die(); - } -} else { - header("Location: /?error=Page not found: " . strip_tags($toplevel)) and die(); -} \ No newline at end of file diff --git a/includes/subsysbanner.inc b/includes/subsysbanner.inc new file mode 100644 index 0000000..176380f --- /dev/null +++ b/includes/subsysbanner.inc @@ -0,0 +1,70 @@ + + +
+ +
+
+

+
+ + Fronter: + + ">" style="width:24px;"> + + N/A + + + + + Last fronter: ">" style="width:24px;"> + + + Members: + + + Parent system: + +
+
+
+
+ +
+
+ You are viewing the page of a subsystem of the . +
+
\ No newline at end of file diff --git a/includes/subsysbanner.php b/includes/subsysbanner.php deleted file mode 100644 index 7788155..0000000 --- a/includes/subsysbanner.php +++ /dev/null @@ -1,69 +0,0 @@ - - -
- -
-
-

-
- - Fronter: - - ">.png" style="width:24px;"> - - N/A - - - - - Last fronter: ">.png" style="width:24px;"> - - - Members: - - - Parent system: - -
-
-
-
- -
-
- You are viewing the page of a subsystem of the . -
-
\ No newline at end of file diff --git a/includes/subsysedit.inc b/includes/subsysedit.inc new file mode 100644 index 0000000..e9c4b4c --- /dev/null +++ b/includes/subsysedit.inc @@ -0,0 +1,143 @@ + + +
+
+ +
+ +

+ Saved · bytes +

+ + + + + + + + +
+ + \ No newline at end of file diff --git a/includes/subsysedit.php b/includes/subsysedit.php deleted file mode 100644 index e6aa9ca..0000000 --- a/includes/subsysedit.php +++ /dev/null @@ -1,143 +0,0 @@ - - -
-
- -
- -

- Saved · bytes -

- - - - - - - - -
- - \ No newline at end of file diff --git a/includes/sysbanner.inc b/includes/sysbanner.inc new file mode 100644 index 0000000..d3caecd --- /dev/null +++ b/includes/sysbanner.inc @@ -0,0 +1,132 @@ + + +
+ +
+
+

+
+ + + + Fronter: + + + ">" style="width:24px;"> More than one" : $member["name"])) ?> + + +
(with + ">" style="width:24px;"> More than one" : $member2["name"])) ?>) + + - +
+ + Last fronter: + + ">" style="width:24px;"> More than one" : $member["name"])) ?> + +
(with + ">" style="width:24px;"> More than one" : $member2["name"])) ?>) + + - +
+ + + Members: 0) { + echo("
+ " . count($travellers) . " traveller" . (count($travellers) > 1 ? "s" : "")); + } + + ?> +
+ + Last switch: "> + +
+
+
+
+ + \ No newline at end of file diff --git a/includes/sysbanner.php b/includes/sysbanner.php deleted file mode 100644 index 45c1c16..0000000 --- a/includes/sysbanner.php +++ /dev/null @@ -1,132 +0,0 @@ - - -
- -
-
-

-
- - - - Fronter: - - - ">.png" style="width:24px;"> More than one" : $member["name"])) ?> - - -
(with - ">.png" style="width:24px;"> More than one" : $member2["name"])) ?>) - - - - -
- - Last fronter: - - ">.png" style="width:24px;"> More than one" : $member["name"])) ?> - -
(with - ">.png" style="width:24px;"> More than one" : $member2["name"])) ?>) - - - - -
- - - Members: 0) { - echo("
+ " . count($travellers) . " traveller" . (count($travellers) > 1 ? "s" : "")); - } - - ?> -
- - Last switch: "> - -
-
-
-
- - \ No newline at end of file diff --git a/includes/sysedit.inc b/includes/sysedit.inc new file mode 100644 index 0000000..95a0b5b --- /dev/null +++ b/includes/sysedit.inc @@ -0,0 +1,143 @@ + + +
+
+ +
+ +

+ Saved · bytes +

+ + + + + + + + +
+ + \ No newline at end of file diff --git a/includes/sysedit.php b/includes/sysedit.php deleted file mode 100644 index 0eca518..0000000 --- a/includes/sysedit.php +++ /dev/null @@ -1,143 +0,0 @@ - - -
-
- -
- -

- Saved · bytes -

- - - - - - - - -
- - \ No newline at end of file diff --git a/includes/system.inc b/includes/system.inc new file mode 100644 index 0000000..099f522 --- /dev/null +++ b/includes/system.inc @@ -0,0 +1,19 @@ + + +
+
+ +
+ +
+ + (edit) + + +
+ +
+ + \ No newline at end of file diff --git a/includes/system.php b/includes/system.php deleted file mode 100644 index 46adeb1..0000000 --- a/includes/system.php +++ /dev/null @@ -1,19 +0,0 @@ - - -
-
- -
- -
- - (edit) - - -
- -
- - \ No newline at end of file diff --git a/includes/system/compare.inc b/includes/system/compare.inc new file mode 100644 index 0000000..de777aa --- /dev/null +++ b/includes/system/compare.inc @@ -0,0 +1,189 @@ + + +
+
+

Compare members of the

+
+ + Member + Member + Member + Member + Member + Mmbr. + + + Species + Species + Species + Species + Spec. + Spec. + + + Relations + Relations + Relations + Relations + Relt. + Relt. + + + MCF + MCF + MCF + MCF + MCF + MCF + + + Fictive + Fictive + Fictive + Fictive + Fic. + Fic. + + + Little + Little + Little + Little + Ltl. + Ltl. + + + Protector + Protector + Protect. + Protect. + Prt. + Prt. + + + + " data-bs-toggle="tooltip" class="member-link comparison-item comparison-item-clickable" href="/"> + " style="width:24px;"> + ; height: 16px; width: 16px;display: inline-block;vertical-align: middle;border-radius:2px;"> + + + + " style="width:24px;vertical-align: middle;position:relative;top:-5px;" src="/assets/species/.png" alt=""> + + + + + + 0 ? count($metadata["marefriends"]) + count($metadata["sisters"]) : "" ?> + + +
Marefriend" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">" style="width:24px;">

Sister" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">" style="width:24px;">

Caretaker" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">" style="width:24px;">
+
+
+ + + + Yes, but currently travelling + + Yes + + + No + + + + + Yes + + No + + + + = 2): ?> + Yes + + Partial + + No + + + + + + Yes, but currently travelling + + Yes + + + No + + + +
+
+ + \ No newline at end of file diff --git a/includes/system/compare.php b/includes/system/compare.php deleted file mode 100644 index 9714488..0000000 --- a/includes/system/compare.php +++ /dev/null @@ -1,189 +0,0 @@ - - -
-
-

Compare members of the

-
- - Member - Member - Member - Member - Member - Mmbr. - - - Species - Species - Species - Species - Spec. - Spec. - - - Relations - Relations - Relations - Relations - Relt. - Relt. - - - MCF - MCF - MCF - MCF - MCF - MCF - - - Fictive - Fictive - Fictive - Fictive - Fic. - Fic. - - - Little - Little - Little - Little - Ltl. - Ltl. - - - Protector - Protector - Protect. - Protect. - Prt. - Prt. - - - - " data-bs-toggle="tooltip" class="member-link comparison-item comparison-item-clickable" href="/"> - .png" style="width:24px;"> - ; height: 16px; width: 16px;display: inline-block;vertical-align: middle;border-radius:2px;"> - - - - " style="width:24px;vertical-align: middle;position:relative;top:-5px;" src="/assets/species/.png" alt=""> - - - - - - 0 ? count($metadata["marefriends"]) + count($metadata["sisters"]) : "" ?> - - -
Marefriend" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">.png" style="width:24px;">

Sister" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">.png" style="width:24px;">

Caretaker" data-bs-toggle="tooltip" data-bs-html="true" class="member-link tooltip-nohelp" href="/">.png" style="width:24px;">
-
-
- - - - Yes, but currently travelling - - Yes - - - No - - - - - Yes - - No - - - - = 2): ?> - Yes - - Partial - - No - - - - - - Yes, but currently travelling - - Yes - - - No - - - -
-
- - \ No newline at end of file diff --git a/includes/system/history.inc b/includes/system/history.inc new file mode 100644 index 0000000..ee687d7 --- /dev/null +++ b/includes/system/history.inc @@ -0,0 +1,528 @@ + + +
+
+ (86400 * ($day - 1)); + })); + + uksort($filtered, function ($a, $b) { + if (isset($b["timestamp"]) && isset($a["timestamp"])) { + return strtotime($b["timestamp"]) - strtotime($a["timestamp"]); + } else { + return null; + } + }); + + return $filtered; + } + + function getSwitchBefore(string $id) { + global $switches; + + $currentPassed = false; + $before = null; + + foreach ($switches as $switch) { + if ($currentPassed) { + $before = $switch; + break; + } else { + if ($switch["id"] === $id) { + $currentPassed = true; + } + } + } + + return $before; + } + + function isNotToday(int $timestamp, int $offset) { + if (date('Y-m-d', $timestamp) !== date('Y-m-d', time() - (86400 * $offset))) { + return true; + } else { + return false; + } + } + + $switches1 = getSwitchesForDay(0); + $switches2 = getSwitchesForDay(1); + $switches3 = getSwitchesForDay(2); + $switches4 = getSwitchesForDay(3); + $switches5 = getSwitchesForDay(4); + $switches6 = getSwitchesForDay(5); + $switches7 = getSwitchesForDay(6); + $switches8 = getSwitchesForDay(7); + $switches9 = getSwitchesForDay(8); + $switches10 = getSwitchesForDay(9); + + ?> +

Front history in the

+ +

Today

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches1); + + $fronters[] = [ + "member" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][0]) ? $switches2[0]["members"][0] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))))), + "member2" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][1]) ? $switches2[0]["members"][1] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))))), + "date" => strtotime(isset($switches2[0]) ? $switches2[0]["timestamp"] : (isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

Yesterday

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches2); + + $fronters[] = [ + "member" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))))), + "member2" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))))), + "date" => strtotime(isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches3); + + $fronters[] = [ + "member" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))), + "member2" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))), + "date" => strtotime(isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches4); + + $fronters[] = [ + "member" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))), + "member2" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))), + "date" => strtotime(isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches5); + + $fronters[] = [ + "member" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))), + "member2" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))), + "date" => strtotime(isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches6); + + $fronters[] = [ + "member" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])), + "member2" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])), + "date" => strtotime(isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches7); + + $fronters[] = [ + "member" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]), + "member2" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]), + "date" => strtotime(isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches8); + + $fronters[] = [ + "member" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0], + "member2" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1], + "date" => strtotime(isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches9); + + $fronters[] = [ + "member" => isset($switches10[0]) ? $switches10[0]["members"][0] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][0], + "member2" => isset($switches10[0]) && isset($switches10[0]["members"]) && isset($switches10[0]["members"][1]) ? $switches10[0]["members"][1] : (isset(getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1]) ? getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1] : null), + "date" => strtotime(isset($switches10[0]) ? $switches10[0]["timestamp"] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["timestamp"]) + ]; + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +

+ $i["members"][0] ?? null, + "member2" => $i["members"][1] ?? null, + "date" => strtotime($i["timestamp"]) + ]; + }, $switches10); + + foreach ($fronters as $fronter): if (isset($fronter["member"])): $member = getMember($fronter["member"]); + ?> +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + "> + " style="width:24px;"> + + + (with "> + " style="width:24px;"> ) + + +
+ +
+ " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> + + + + Fallback pony + +
+ +
+ + + \ No newline at end of file diff --git a/includes/system/history.php b/includes/system/history.php deleted file mode 100644 index a13a3e1..0000000 --- a/includes/system/history.php +++ /dev/null @@ -1,460 +0,0 @@ - - -
-
- (86400 * ($day - 1)); - })); - - uksort($filtered, function ($a, $b) { - if (isset($b["timestamp"]) && isset($a["timestamp"])) { - return strtotime($b["timestamp"]) - strtotime($a["timestamp"]); - } else { - return null; - } - }); - - return $filtered; - } - - function getSwitchBefore(string $id) { - global $switches; - - $currentPassed = false; - $before = null; - - foreach ($switches as $switch) { - if ($currentPassed) { - $before = $switch; - break; - } else { - if ($switch["id"] === $id) { - $currentPassed = true; - } - } - } - - return $before; - } - - function isNotToday(int $timestamp, int $offset) { - if (date('Y-m-d', $timestamp) !== date('Y-m-d', time() - (86400 * $offset))) { - return true; - } else { - return false; - } - } - - $switches1 = getSwitchesForDay(0); - $switches2 = getSwitchesForDay(1); - $switches3 = getSwitchesForDay(2); - $switches4 = getSwitchesForDay(3); - $switches5 = getSwitchesForDay(4); - $switches6 = getSwitchesForDay(5); - $switches7 = getSwitchesForDay(6); - $switches8 = getSwitchesForDay(7); - $switches9 = getSwitchesForDay(8); - $switches10 = getSwitchesForDay(9); - - ?> -

Front history in the

- -

Today

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches1); - - $fronters[] = [ - "member" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][0]) ? $switches2[0]["members"][0] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))))), - "member2" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][1]) ? $switches2[0]["members"][1] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))))), - "date" => strtotime(isset($switches2[0]) ? $switches2[0]["timestamp"] : (isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

Yesterday

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches2); - - $fronters[] = [ - "member" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))))), - "member2" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))))), - "date" => strtotime(isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches3); - - $fronters[] = [ - "member" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))), - "member2" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))), - "date" => strtotime(isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches4); - - $fronters[] = [ - "member" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))), - "member2" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))), - "date" => strtotime(isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches5); - - $fronters[] = [ - "member" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))), - "member2" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))), - "date" => strtotime(isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches6); - - $fronters[] = [ - "member" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])), - "member2" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])), - "date" => strtotime(isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches7); - - $fronters[] = [ - "member" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]), - "member2" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]), - "date" => strtotime(isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches8); - - $fronters[] = [ - "member" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0], - "member2" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1], - "date" => strtotime(isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches9); - - $fronters[] = [ - "member" => isset($switches10[0]) ? $switches10[0]["members"][0] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][0], - "member2" => isset($switches10[0]) && isset($switches10[0]["members"]) && isset($switches10[0]["members"][1]) ? $switches10[0]["members"][1] : (isset(getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1]) ? getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1] : null), - "date" => strtotime($switches10[0] ? $switches10[0]["timestamp"] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["timestamp"]) - ]; - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -

- $i["members"][0], - "member2" => $i["members"][1] ?? null, - "date" => strtotime($i["timestamp"]) - ]; - }, $switches10); - - $fronters = array_unique($fronters, SORT_REGULAR); - - foreach ($fronters as $fronter): $member = getMember($fronter["member"]); - ?> -
- " style="opacity:.5;font-family: monospace;font-size:14px;vertical-align: middle;"> - - - - "> - .png" style="width:24px;"> - - - (with "> - .png" style="width:24px;"> ) - - -
- -
- - - \ No newline at end of file diff --git a/includes/system/species.inc b/includes/system/species.inc new file mode 100644 index 0000000..bd37d7b --- /dev/null +++ b/includes/system/species.inc @@ -0,0 +1,70 @@ + + +
+
+ () +
+ +
+ 0): ?> + + ">" style="width:24px;"> ,  
'); $index++; endforeach; ?> + - +
+
+ + +
+
+

members by species

+ + + + + + + + +
+ + \ No newline at end of file diff --git a/includes/system/species.php b/includes/system/species.php deleted file mode 100644 index a35e811..0000000 --- a/includes/system/species.php +++ /dev/null @@ -1,70 +0,0 @@ - - -
-
- () -
- -
- 0): ?> - - ">.png" style="width:24px;"> ,  
'); $index++; endforeach; ?> - - -
-
- - -
-
-

members by species

- - - - - - - - -
- - \ No newline at end of file diff --git a/includes/system/subsystem.inc b/includes/system/subsystem.inc new file mode 100644 index 0000000..b7d73f1 --- /dev/null +++ b/includes/system/subsystem.inc @@ -0,0 +1,100 @@ + + +
+
+ +
+ +
+ + (edit) + + +
+ +
+ + \ No newline at end of file diff --git a/includes/system/subsystem.php b/includes/system/subsystem.php deleted file mode 100644 index 372ad08..0000000 --- a/includes/system/subsystem.php +++ /dev/null @@ -1,100 +0,0 @@ - - -
-
- -
- -
- - (edit) - - -
- -
- - \ No newline at end of file diff --git a/includes/system/tree.inc b/includes/system/tree.inc new file mode 100644 index 0000000..c3cc5c4 --- /dev/null +++ b/includes/system/tree.inc @@ -0,0 +1,114 @@ + + +
+
+

System tree for the

+ + .png" style="width:24px;"> + + + + + +
+
"> 
+ + + +
+
 
+
"> 
+ +
+ + +
+ +
+ + \ No newline at end of file diff --git a/includes/system/tree.php b/includes/system/tree.php deleted file mode 100644 index 21d146b..0000000 --- a/includes/system/tree.php +++ /dev/null @@ -1,114 +0,0 @@ - - -
- - - \ No newline at end of file diff --git a/includes/travelling.inc b/includes/travelling.inc new file mode 100644 index 0000000..edcb267 --- /dev/null +++ b/includes/travelling.inc @@ -0,0 +1,47 @@ + false, + "history" => [] + ]; + } +} + +function withTravelers(array $members, string $system): array { + global $travelling; + + return [ + ...array_map(function ($i) use ($system) { + $i['system'] = $system; + return $i; + }, array_filter($members, function ($i) use ($travelling) { + return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']); + })), + ...array_filter(array_map(function ($i) use ($system) { + $i['system'] = $system === "gdapd" ? "ynmuc" : "gdapd"; + return $i; + }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($system === "gdapd" ? "ynmuc" : "gdapd") . "/members.json"), true)), function ($i) use ($travelling) { + return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']; + }) + ]; +} + +@file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling/travelling.json", utf8_encode(json_encode($travelling, JSON_PRETTY_PRINT))); \ No newline at end of file diff --git a/includes/travelling.php b/includes/travelling.php deleted file mode 100644 index b74c826..0000000 --- a/includes/travelling.php +++ /dev/null @@ -1,47 +0,0 @@ - false, - "history" => [] - ]; - } -} - -function withTravelers(array $members, string $system): array { - global $travelling; - - return [ - ...array_map(function ($i) use ($system) { - $i['system'] = $system; - return $i; - }, array_filter($members, function ($i) use ($travelling) { - return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']); - })), - ...array_filter(array_map(function ($i) use ($system) { - $i['system'] = $system === "gdapd" ? "ynmuc" : "gdapd"; - return $i; - }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($system === "gdapd" ? "ynmuc" : "gdapd") . "-members.json"), true)), function ($i) use ($travelling) { - return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']; - }) - ]; -} - -file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json", utf8_encode(json_encode($travelling, JSON_PRETTY_PRINT))); \ No newline at end of file diff --git a/includes/wakeup.inc b/includes/wakeup.inc new file mode 100644 index 0000000..587e705 --- /dev/null +++ b/includes/wakeup.inc @@ -0,0 +1,114 @@ +

Wake-up alert +
+ + · +
+

+ +Turn ON + +

Sending next notification never

+ + + + + + \ No newline at end of file diff --git a/includes/wakeup.php b/includes/wakeup.php deleted file mode 100644 index 587e705..0000000 --- a/includes/wakeup.php +++ /dev/null @@ -1,114 +0,0 @@ -

Wake-up alert -
- - · -
-

- -Turn ON - -

Sending next notification never

- - - - - - \ No newline at end of file diff --git a/pages/about.inc b/pages/about.inc new file mode 100644 index 0000000..d6b0eeb --- /dev/null +++ b/pages/about.inc @@ -0,0 +1,96 @@ + 1024) { + if ($bytes > 1024**2) { + if ($bytes > 1024**3) { + return round($bytes / 1024**3, 1) . " MB"; + } else { + return round($bytes / 1024**2, 1) . " MB"; + } + } else { + return round($bytes / 1024, 1) . " KB"; + } + } else { + return $bytes . " B"; + } +} + +?> + +
+
+
+

About Cold Haze

+

+ Cold Haze Engine version 2...
+ Version date:
+ Version ID:
+ Install path:
+ Server software: , via
+ Transport protocol: +

+ +

+ PHP
+ Zend Engine:
+ Server API:
+ Memory usage:
+ Server OS:
+ Server domain name:
+ Server architecture: +

+ +

+ Disk space usage
+ Engine:
+ Database: +

+
+
+ + diff --git a/pages/actions.inc b/pages/actions.inc new file mode 100644 index 0000000..527b336 --- /dev/null +++ b/pages/actions.inc @@ -0,0 +1,1116 @@ + $item) { + if ($item["id"] === $id) { + $selectedIndex = $index; + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/actions"); + die(); + } + + unset($data[$selectedIndex]); + @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions"); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/" . date('Y-m-d_H-i-s') . ".json", utf8_encode(json_encode($data))); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json", utf8_encode(json_encode($data))); + header("Location: /-/actions/?d&id=" . $id); + die(); +} + +if (isset($_POST['updateAction'])) { + $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json"), true); + + $selected = null; + $selectedIndex = -1; + $id = $_POST['action']; + + foreach ($data as $index => $item) { + if ($item["id"] === $id) { + $selectedIndex = $index; + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/actions"); + die(); + } + + if (isset($_POST["consent"])) { + $selected["consent"] = true; + } else { + $selected["consent"] = false; + } + + if (isset($_POST["name"])) $selected["name"] = strip_tags(trim($_POST["name"])); + if (isset($_POST["example"])) $selected["example"] = strip_tags(trim($_POST["example"])); + if (isset($_POST["irl"])) $selected["irl"] = strip_tags(trim($_POST["irl"])); + if (isset($_POST["keywords"])) $selected["keywords"] = array_map(function ($i) { + return trim($i); + }, explode(",", strip_tags(trim($_POST["keywords"])))); + if (isset($_POST["description"])) $selected["description"] = strip_tags(trim($_POST["description"])); + if (isset($_POST["type"])) $selected["type"] = match ($_POST["type"]) { + "0" => "affectionate", + "1" => "sexual", + "2" => "mixed" + }; + + if (isset($_POST["relations"])) { + $ponies = []; + + foreach ($_POST["relations"] as $relation => $d) { + $ponies[] = [ + "members" => explode("-", $relation), + "deprecated" => isset($d["deprecated"]), + "sexual" => isset($d["sexual"]) + ]; + } + + $selected["ponies"] = $ponies; + } + + global $_PROFILE; + if ($_PROFILE['login'] === "raindrops" && isset($_POST["verified"])) { + $selected["verified"] = true; + } else { + unset($selected["verified"]); + } + + if (isset($_POST["untested"])) { + $selected["untested"] = true; + } else { + unset($selected["untested"]); + } + + $data[$selectedIndex] = $selected; + @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions"); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/" . date('Y-m-d_H-i-s') . ".json", utf8_encode(json_encode($data))); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json", utf8_encode(json_encode($data))); + + header("Location: /-/actions/" . $id); + die(); +} + +if (isset($_POST['createAction'])) { + require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/random.inc"; + $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json"), true); + + if (!isset($_POST["name"]) || !isset($_POST["type"])) { + header("Location: /-/actions"); + die(); + } + if (trim($_POST["name"]) === "" || !is_numeric($_POST["type"])) { + header("Location: /-/actions"); + die(); + } + + $type = match ($_POST["type"]) { + "0" => "affectionate", + "1" => "sexual", + "2" => "mixed" + }; + $name = strip_tags(trim($_POST["name"])); + $id = random(); + + $ponies = []; + + if (isset($_POST["relations"])) { + foreach ($_POST["relations"] as $relation => $_) { + $ponies[] = [ + "members" => explode("-", $relation), + "deprecated" => false, + "sexual" => false + ]; + } + } + + if (isset($_POST["consent"])) { + $consent = true; + } else { + $consent = false; + } + + $data[] = [ + "id" => $id, + "name" => $name, + "type" => $type, + "description" => null, + "ponies" => $ponies, + "example" => null, + "irl" => null, + "keywords" => [], + "consent" => $consent + ]; + + @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions"); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/" . date('Y-m-d_H-i-s') . ".json", utf8_encode(json_encode($data))); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json", utf8_encode(json_encode($data))); + header("Location: /-/actions/" . $id); + die(); +} + +global $pagename; +$parts = explode("/", $pagename); +$data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json"), true); +$toys = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json"), true); + +$selected = null; + +if (isset($parts[1])) { + $id = $parts[1]; + + foreach ($data as $item) { + if ($item["id"] === $id) { + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/actions/?nf&id=" . $id); + die(); + } else { + $title = $selected["name"] . " · " . $title; + } +} + +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/keywords.inc'; + +if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions/actions.json", "[]"); + +global $_PROFILE; + +?> + + + +
+
+
"> + +
+ + Error: The requested action () was not found, it may have been deleted or has never existed. +
+ + + +
+ + Success: The action with ID has been successfully deleted. +
+ + + + +

+ + Back +

+

+ Edit · + + Affectionate + + + Sexual + + + Affectionate Sexual + + Unverified + Untested +

+ +
+ +
+ This action requires consent. Since this action constitues a sexual act, verbal consent from both parties is absolutely required. Both parties must be in a mental state where they are able to consent. Furthermore, if one of the parties involved wishes to stop, the request must be immediately honoured. +
+ +
+ This action is better with consent. This action is extremely personal to all parties involved, and it is best to ask if they wish to do this. If they ask to stop the action, you must stop immediately and reverse any potential effects. +
+ + + + ", strip_tags($selected["description"]))); ?> + +

No description provided for this action. Enter edit mode to add a description to this action.

+ + + +
+

Available toys:

+ + + + + +
+ + 1; ?> + Example:
+ + +
    + +
  • + +
+ + + + +

No example provided for this action. Enter edit mode to add an example to this action.

+ + +
+ + Steps to reproduce in real life:
+ + + +

This action is not reproducible in real life.

+ + +
+ +

Similar actions

+
+ $action["id"], + "type" => $action["type"], + "ponies" => $action["ponies"] + ]; + } + + foreach ($names as $name => $data) { + if ($data["type"] === $selected["type"] || $selected["type"] !== "affectionate") { + $namesByDistance[] = [ + "name" => $name, + "distance" => levenshtein($currentName, $name) + ((int)($data["type"] !== $selected["type"]) * 2), + "id" => $data["id"], + "type" => $data["type"], + "ponies" => $data["ponies"] + ]; + } + } + + uasort($namesByDistance, function ($a, $b) use ($selected) { + return $a["distance"] - $b["distance"]; + }); + + foreach ($namesByDistance as $item) { + echo(""); + } + + $index = 0; + foreach ($namesByDistance as $item): if ($index < 3): + ?> + + +
+ + + + + +

Actions database

+

actions ( affectionate, sexual, untested, incomplete)

+ +

TODO: fill everything and add keywords

+ + + + + +
+ +
+
+

Not finding what you are looking for? Create an action.

+
+ + + + + + +
+
+ + + + + + + diff --git a/pages/actions.php b/pages/actions.php deleted file mode 100644 index 939ed7e..0000000 --- a/pages/actions.php +++ /dev/null @@ -1,1130 +0,0 @@ - $item) { - if ($item["id"] === $id) { - $selectedIndex = $index; - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/actions"); - die(); - } - - unset($data[$selectedIndex]); - @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions"); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions/" . date('c') . ".json", utf8_encode(json_encode($data))); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json", utf8_encode(json_encode($data))); - header("Location: /-/actions/?d&id=" . $id); - die(); -} - -if (isset($_POST['updateAction'])) { - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json"), true); - - $selected = null; - $selectedIndex = -1; - $id = $_POST['action']; - - foreach ($data as $index => $item) { - if ($item["id"] === $id) { - $selectedIndex = $index; - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/actions"); - die(); - } - - if (isset($_POST["consent"])) { - $selected["consent"] = true; - } else { - $selected["consent"] = false; - } - - if (isset($_POST["name"])) $selected["name"] = strip_tags(trim($_POST["name"])); - if (isset($_POST["example"])) $selected["example"] = strip_tags(trim($_POST["example"])); - if (isset($_POST["irl"])) $selected["irl"] = strip_tags(trim($_POST["irl"])); - if (isset($_POST["keywords"])) $selected["keywords"] = array_map(function ($i) { - return trim($i); - }, explode(",", strip_tags(trim($_POST["keywords"])))); - if (isset($_POST["description"])) $selected["description"] = strip_tags(trim($_POST["description"])); - if (isset($_POST["type"])) $selected["type"] = match ($_POST["type"]) { - "0" => "affectionate", - "1" => "sexual", - "2" => "mixed" - }; - - if (isset($_POST["relations"])) { - $ponies = []; - - foreach ($_POST["relations"] as $relation => $d) { - $ponies[] = [ - "members" => explode("-", $relation), - "deprecated" => isset($d["deprecated"]), - "sexual" => isset($d["sexual"]) - ]; - } - - $selected["ponies"] = $ponies; - } - - global $_PROFILE; - if ($_PROFILE['login'] === "raindrops" && isset($_POST["verified"])) { - $selected["verified"] = true; - } else { - unset($selected["verified"]); - } - - if (isset($_POST["untested"])) { - $selected["untested"] = true; - } else { - unset($selected["untested"]); - } - - $data[$selectedIndex] = $selected; - @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions"); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions/" . date('c') . ".json", utf8_encode(json_encode($data))); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json", utf8_encode(json_encode($data))); - - header("Location: /-/actions/" . $id); - die(); -} - -if (isset($_POST['createAction'])) { - require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/random.php"; - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json"), true); - - if (!isset($_POST["name"]) || !isset($_POST["type"])) { - header("Location: /-/actions"); - die(); - } - if (trim($_POST["name"]) === "" || !is_numeric($_POST["type"])) { - header("Location: /-/actions"); - die(); - } - - $type = match ($_POST["type"]) { - "0" => "affectionate", - "1" => "sexual", - "2" => "mixed" - }; - $name = strip_tags(trim($_POST["name"])); - $id = random(); - - $ponies = []; - - if (isset($_POST["relations"])) { - foreach ($_POST["relations"] as $relation => $_) { - $ponies[] = [ - "members" => explode("-", $relation), - "deprecated" => false, - "sexual" => false - ]; - } - } - - if (isset($_POST["consent"])) { - $consent = true; - } else { - $consent = false; - } - - $data[] = [ - "id" => $id, - "name" => $name, - "type" => $type, - "description" => null, - "ponies" => $ponies, - "example" => null, - "irl" => null, - "keywords" => [], - "consent" => $consent - ]; - - @mkdir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions"); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/oldactions/" . date('c') . ".json", utf8_encode(json_encode($data))); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json", utf8_encode(json_encode($data))); - header("Location: /-/actions/" . $id); - die(); -} - -global $pagename; -$parts = explode("/", $pagename); -$data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json"), true); -$toys = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json"), true); - -$selected = null; - -if (isset($parts[1])) { - $id = $parts[1]; - - foreach ($data as $item) { - if ($item["id"] === $id) { - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/actions/?nf&id=" . $id); - die(); - } else { - $title = $selected["name"] . " · " . $title; - } -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/keywords.php'; - -if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json", "[]"); - -global $_PROFILE; - -?> - - - -
-
-
"> - -
- - Error: The requested action () was not found, it may have been deleted or has never existed. -
- - - -
- - Success: The action with ID has been successfully deleted. -
- - - - -

- - Back -

-

- Edit · - - Affectionate - - - Sexual - - - Affectionate Sexual - - Unverified - Untested -

- -
- -
- This action requires consent. Since this action constitues a sexual act, verbal consent from both parties is absolutely required. Both parties must be in a mental state where they are able to consent. Furthermore, if one of the parties involved wishes to stop, the request must be immediately honoured. -
- -
- This action is better with consent. This action is extremely personal to all parties involved, and it is best to ask if they wish to do this. If they ask to stop the action, you must stop immediately and reverse any potential effects. -
- - - - ", strip_tags($selected["description"]))); ?> - -

No description provided for this action. Enter edit mode to add a description to this action.

- - - -
-

Available toys:

- - - -
- Can be done by: - - -
    -
  • - Affectionately: -
      - -
    • - .png"> - .png"> - - and -
    • - - -
    • - - .png"> - .png"> - - and - - Deprecated -
    • - -
    -
  • -
  • - Sexually: -
      - -
    • - .png"> - .png"> - - and -
    • - - -
    • - - .png"> - .png"> - - and - - Deprecated -
    • - -
    -
  • -
- -
    - -
  • - .png"> - .png"> - - and -
  • - - -
  • - - .png"> - .png"> - - and - - Deprecated -
  • - -
- - -
- - 1; ?> - Example:
- - -
    - -
  • - -
- - - - -

No example provided for this action. Enter edit mode to add an example to this action.

- - -
- - Steps to reproduce in real life:
- - - -

This action is not reproducible in real life.

- - -
- -

Similar actions

-
- $action["id"], - "type" => $action["type"], - "ponies" => $action["ponies"] - ]; - } - - foreach ($names as $name => $data) { - if ($data["type"] === $selected["type"] || $selected["type"] !== "affectionate") { - $namesByDistance[] = [ - "name" => $name, - "distance" => levenshtein($currentName, $name) + ((int)($data["type"] !== $selected["type"]) * 2), - "id" => $data["id"], - "type" => $data["type"], - "ponies" => $data["ponies"] - ]; - } - } - - uasort($namesByDistance, function ($a, $b) use ($selected) { - return $a["distance"] - $b["distance"]; - }); - - foreach ($namesByDistance as $item) { - echo(""); - } - - $index = 0; - foreach ($namesByDistance as $item): if ($index < 3): - ?> - - -
- - - - - -

Actions database

-

actions ( affectionate, sexual, untested, incomplete)

- -

TODO: add ponies for all actions (+ keywords)

- - - - - -
- -
-
-

Not finding what you are looking for? Create an action.

-
- - - - - - -
-
- - - - - - - diff --git a/pages/alphabet.inc b/pages/alphabet.inc new file mode 100644 index 0000000..167ba92 --- /dev/null +++ b/pages/alphabet.inc @@ -0,0 +1,38 @@ + + +
+ + + diff --git a/pages/alphabet.php b/pages/alphabet.php deleted file mode 100644 index b59772d..0000000 --- a/pages/alphabet.php +++ /dev/null @@ -1,38 +0,0 @@ - - -
- - - diff --git a/pages/api.inc b/pages/api.inc new file mode 100644 index 0000000..1d83985 --- /dev/null +++ b/pages/api.inc @@ -0,0 +1,17 @@ + + +
+
+
+

Bitset calculator

+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
1
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+

+ Input:
+ Output: 0b000000000000000000000000000000000000100000000000, 0x000008000000, 2048 +

+ + +

+ Shared memory access: + +
+ Food: + +
+ Little/younger: + +
+ Species: + + + +
+ Magic: + +
+ Sensitivity: + +

+

+
+
+
+
+
+
+
+
+
+
+
+
+

+
+ + diff --git a/pages/bitset.php b/pages/bitset.php deleted file mode 100644 index 0d2d10e..0000000 --- a/pages/bitset.php +++ /dev/null @@ -1,409 +0,0 @@ - - -
-
-
-

Bitset calculator

-
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
1
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
-
-

- Input:
- Output: 0b000000000000000000000000000000000000100000000000, 0x000008000000, 2048 -

- - -

- Shared memory access: - -
- Food: - -
- Little/younger: - -
- Species: - - - -
- Magic: - -
- Sensitivity: - -

-

-
-
-
-
-
-
-
-
-
-
-
-
-

-
- - diff --git a/pages/byfront.inc b/pages/byfront.inc new file mode 100644 index 0000000..280d981 --- /dev/null +++ b/pages/byfront.inc @@ -0,0 +1,160 @@ + + +
+
+
+

Members by last fronted

+ +

Cloudburst System

+ 0) { + $thisIndex = array_search($thisMember[0], $switches); + + $frontingStart = $thisMember[0]; + $frontingEnd = $switches[$thisIndex - 1]; + } + + if ($frontingEnd !== null && isset($frontingStart)) { + $i["_lastFronted"] = strtotime($frontingEnd["timestamp"]); + } + } + + return $i; + }, array_values(array_filter(scoreOrderGlobal(), function ($i) { + return $i["_system"] === "ynmuc"; + }))); uasort($members, function ($a, $b) { + return $b["_lastFronted"] - $a["_lastFronted"]; + }); foreach ($members as $member): ?> +
+ "> + " style="width:24px;">  + +  Not sharing memory + + + +
+ + Never fronted + + Last fronted () + +
+
+ + +
+

Raindrops System

+ 0) { + $thisIndex = array_search($thisMember[0], $switches); + + $frontingStart = $thisMember[0]; + $frontingEnd = $switches[$thisIndex - 1]; + } + + if ($frontingEnd !== null && isset($frontingStart)) { + $i["_lastFronted"] = strtotime($frontingEnd["timestamp"]); + } + } + + return $i; + }, array_values(array_filter(scoreOrderGlobal(), function ($i) { + return $i["_system"] === "gdapd"; + }))); uasort($members, function ($a, $b) { + return $b["_lastFronted"] - $a["_lastFronted"]; + }); foreach ($members as $member): ?> +
+ "> + " style="width:24px;">  + +  Not sharing memory + + + +
+ + Never fronted + + Last fronted () + +
+
+ +
+ + +
+ + diff --git a/pages/byfront.php b/pages/byfront.php deleted file mode 100644 index eb9050c..0000000 --- a/pages/byfront.php +++ /dev/null @@ -1,160 +0,0 @@ - - -
-
-
-

Members by last fronted

- -

Cloudburst System

- 0) { - $thisIndex = array_search($thisMember[0], $switches); - - $frontingStart = $thisMember[0]; - $frontingEnd = $switches[$thisIndex - 1]; - } - - if ($frontingEnd !== null && isset($frontingStart)) { - $i["_lastFronted"] = strtotime($frontingEnd["timestamp"]); - } - } - - return $i; - }, array_values(array_filter(scoreOrderGlobal(), function ($i) { - return $i["_system"] === "ynmuc"; - }))); uasort($members, function ($a, $b) { - return $b["_lastFronted"] - $a["_lastFronted"]; - }); foreach ($members as $member): ?> -
- "> - .png" style="width:24px;">  - -  Not sharing memory - - - -
- - Never fronted - - Last fronted () - -
-
- - -
-

Raindrops System

- 0) { - $thisIndex = array_search($thisMember[0], $switches); - - $frontingStart = $thisMember[0]; - $frontingEnd = $switches[$thisIndex - 1]; - } - - if ($frontingEnd !== null && isset($frontingStart)) { - $i["_lastFronted"] = strtotime($frontingEnd["timestamp"]); - } - } - - return $i; - }, array_values(array_filter(scoreOrderGlobal(), function ($i) { - return $i["_system"] === "gdapd"; - }))); uasort($members, function ($a, $b) { - return $b["_lastFronted"] - $a["_lastFronted"]; - }); foreach ($members as $member): ?> -
- "> - .png" style="width:24px;">  - -  Not sharing memory - - - -
- - Never fronted - - Last fronted () - -
-
- -
- - -
- - diff --git a/pages/dashboard.inc b/pages/dashboard.inc new file mode 100644 index 0000000..59396e5 --- /dev/null +++ b/pages/dashboard.inc @@ -0,0 +1,231 @@ + + +
+
+
+

Date

+ + +
+

Next fronters (edit)

+ + +
Fronters today
+
    + $id): $member = getMemberWithoutSystem($id[0]); ?> +
  • + + Merged members + + " style="width:24px; height: 24px; vertical-align: middle;"> + + + and " style="width:24px; height: 24px; vertical-align: middle;"> + + with " style="width:24px; height: 24px; vertical-align: middle;"> + and " style="width:24px; height: 24px; vertical-align: middle;"> + +
  • + +
+ +
Fronters tomorrow
+
    + $id): $member = getSystemMember($_PROFILE["login"] === "raindrops" ? "gdapd" : "ynmuc", $id[0]); ?> +
  • + + Merged members + + " style="width:24px; height: 24px; vertical-align: middle;"> + + + and " style="width:24px; height: 24px; vertical-align: middle;"> + + with " style="width:24px; height: 24px; vertical-align: middle;"> + and " style="width:24px; height: 24px; vertical-align: middle;"> + +
  • + +
+ +
Fronters on
+
    + $id): $member = getSystemMember($_PROFILE["login"] === "raindrops" ? "gdapd" : "ynmuc", $id[0]); ?> +
  • + + Merged members + + " style="width:24px; height: 24px; vertical-align: middle;"> + + + and " style="width:24px; height: 24px; vertical-align: middle;"> + + with " style="width:24px; height: 24px; vertical-align: middle;"> + and " style="width:24px; height: 24px; vertical-align: middle;"> + +
  • + +
+ +
+

Next events

+ parseFile($_SERVER['DOCUMENT_ROOT'] . "/includes/data/calendar/calendar.ics"); + $events = []; + + foreach ($cal->getEvents()->sorted() as $event) { + $events[] = [ + "id" => $event['UID'], + "date" => [ + "created" => $event['CREATED']->format('c'), + "modified" => $event['LAST-MODIFIED']->format('c'), + "start" => $event['DTSTART']->format('c'), + "end" => $event['DTEND']->format('c'), + "duration" => strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')), + "full_day" => strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')) >= 86400, + "days" => ( + strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')) >= 86400 ? + round((strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c'))) / 86400) : + null + ) + ], + "name" => $event['SUMMARY'], + "description" => $event['DESCRIPTION'] ?? "", + ]; + } + + $events = array_values(array_filter($events, function ($i) { + return ( + strtotime($i["date"]["end"]) > time() && + strtotime($i["date"]["start"]) < time() + 2629800 + ); + })); + + ?> +
    + +
  • + + + + Started , ends + + + + · + + + + + · + + + for + · + +
  • + +
+
+
+ + diff --git a/pages/dashboard.php b/pages/dashboard.php deleted file mode 100644 index a861636..0000000 --- a/pages/dashboard.php +++ /dev/null @@ -1,321 +0,0 @@ - - -
-
-
-

Date

- - -
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
-
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
- -
-
" data-bs-toggle="tooltip"> - -
-
-
-
-
- -
- -
-

Next fronters (edit)

- - -
Fronters today
-
    - $id): $member = getMemberWithoutSystem($id); ?> -
  • - - Merged members - - .png" style="width:24px; height: 24px; vertical-align: middle;"> - - with .png" style="width:24px; height: 24px; vertical-align: middle;"> -
  • - -
- -
Fronters tomorrow
-
    - $id): $member = getSystemMember($_PROFILE["login"] === "raindrops" ? "gdapd" : "ynmuc", $id); ?> -
  • - - Merged members - - .png" style="width:24px; height: 24px; vertical-align: middle;"> - - with .png" style="width:24px; height: 24px; vertical-align: middle;"> -
  • - -
- -
-

Next events

- parseFile($_SERVER['DOCUMENT_ROOT'] . "/includes/data/calendar.ics"); - $events = []; - - foreach ($cal->getEvents()->sorted() as $event) { - $events[] = [ - "id" => $event['UID'], - "date" => [ - "created" => $event['CREATED']->format('c'), - "modified" => $event['LAST-MODIFIED']->format('c'), - "start" => $event['DTSTART']->format('c'), - "end" => $event['DTEND']->format('c'), - "duration" => strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')), - "full_day" => strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')) >= 86400, - "days" => ( - strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c')) >= 86400 ? - round((strtotime($event['DTEND']->format('c')) - strtotime($event['DTSTART']->format('c'))) / 86400) : - null - ) - ], - "name" => $event['SUMMARY'], - "description" => $event['DESCRIPTION'], - ]; - } - - $events = array_values(array_filter($events, function ($i) { - return ( - strtotime($i["date"]["end"]) > time() && - strtotime($i["date"]["start"]) < time() + 2629800 - ); - })); - - ?> -
    - -
  • - - - - Started , ends - - - - · - - - - - · - - - for - · - -
  • - -
-
-
- - - - diff --git a/pages/debug.inc b/pages/debug.inc new file mode 100644 index 0000000..77001d0 --- /dev/null +++ b/pages/debug.inc @@ -0,0 +1,115 @@ + "General info about $systemName", + "members" => "Members in the $systemName", + "fronters" => "Current fronter(s) in the $systemName", + "switches" => "Switch history from the $systemName", + default => "$type in $systemName", + }; + } + + if (str_starts_with($item, "images-")) { + $system = explode("-", $item)[1]; + $id = explode("-", $item)[2]; + $systemName = $system === "gdapd" ? "Raindrops" : "Cloudburst"; + $member = getSystemMember($system, $id) ?? [ "name" => $id, "display_name" => $id, "id" => $id ]; + + if ($member["name"] === "unknown") { + return "Unknown (" . $systemName . ")'s images"; + } else { + return getMiniName($member["display_name"] ?? $member["name"]) . "'s images"; + } + } + + return "$item"; +} + +?> + +
+
+ + +
+

Data updater debugging

+

This page provides debugging information to troubleshoot unexpectedly long update times or reported failures.

+ + 360): ?> +
+

+ The data is not updated periodically anymore. +

+ This can be due to multiple things: +
    +
  • the data updater has been disabled temporarily for maintenance;
  • +
  • the data updater cannot start on the server;
  • +
  • the server was down for an extended period of time
  • +
+ If you are an administrator and think this is not normal, you may investigate the issue. +
+ + +

General information

+
    +
  • Update date: format("l j F Y, G:i:s.u T")); ?>
  • +
  • Total duration: ms
  • +
  • Longest operation: ( ms, %)
  • +
+ +

Processing times

+
+ $time): ?>%"> +
+
    + $time): ?> +
  • : ms
  • + +
+ +

Reported failures

+ +

The data updater has not reported any update failure in the last run.

+ +

The following files have failed to update:

+
    + +
  • + +
+ +
+
+ + + + diff --git a/pages/debug.php b/pages/debug.php deleted file mode 100644 index fdd6fec..0000000 --- a/pages/debug.php +++ /dev/null @@ -1,96 +0,0 @@ - "General info about $systemName", - "members" => "Members in the $systemName", - "fronters" => "Current fronter(s) in the $systemName", - "switches" => "Switch history from the $systemName", - default => "$type in $systemName", - }; - } - - if (str_starts_with($item, "images-")) { - $system = explode("-", $item)[1]; - $id = explode("-", $item)[2]; - $systemName = $system === "gdapd" ? "Raindrops" : "Cloudburst"; - $member = getSystemMember($system, $id) ?? [ "name" => $id, "display_name" => $id, "id" => $id ]; - - if ($member["name"] === "unknown") { - return "Unknown (" . $systemName . ")'s images"; - } else { - return getMiniName($member["display_name"] ?? $member["name"]) . "'s images"; - } - } - - return "$item"; -} - -?> - -
-
- - -
-

Data updater debugging

-

This page provides debugging information to troubleshoot unexpectedly long update times or reported failures.

- -

General information

-
    -
  • Update date: format("l j F Y, G:i:s.u T")); ?>
  • -
  • Total duration: ms
  • -
  • Longest operation: ( ms, %)
  • -
- -

Processing times

-
- $time): ?>%"> -
-
    - $time): ?> -
  • : ms
  • - -
- -

Reported failures

- -

The data updater has not reported any update failure in the last run.

- -

The following files have failed to update:

-
    - -
  • - -
- -
-
- - - - diff --git a/pages/demo.inc b/pages/demo.inc new file mode 100644 index 0000000..d469908 --- /dev/null +++ b/pages/demo.inc @@ -0,0 +1,129 @@ + + + +
+
+
+ + + +
+
+ + + + + + + + diff --git a/pages/demo.php b/pages/demo.php deleted file mode 100644 index 381a7e4..0000000 --- a/pages/demo.php +++ /dev/null @@ -1,131 +0,0 @@ - - - -
-
-
- - -
-

Cliquez sur quelqu'un pour avoir plus d'information sur elle.

- -
-
-
- - - - - - - - diff --git a/pages/disclaimers.inc b/pages/disclaimers.inc new file mode 100644 index 0000000..ae3d04e --- /dev/null +++ b/pages/disclaimers.inc @@ -0,0 +1,15 @@ + + +
+
+
+ +
+
+ + diff --git a/pages/disclaimers.php b/pages/disclaimers.php deleted file mode 100644 index b47e33a..0000000 --- a/pages/disclaimers.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - diff --git a/pages/docs.inc b/pages/docs.inc new file mode 100644 index 0000000..f893e95 --- /dev/null +++ b/pages/docs.inc @@ -0,0 +1,361 @@ + "Untitled document ($id)", + "category" => null, + "contents" => "
This is a new document you just created.
", + "last" => [ + "author" => $_PROFILE["login"], + "date" => time() + ] + ])); + + header("Location: /-/docs/$id"); + die(); +} elseif (isset($select)) { + if (ctype_alnum($select) && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json")) { + $id = $select; + $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json"), true); + $titleBase = " · " . $title . " · Cold Haze"; + $title = $data["name"] . " · " . $title; + } else { + header("Location: /-/docs"); + die(); + } +} + +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; + +?> + +
+
+
+
+

+ + Back +

+

Category:

+

+ + Last modified never + + Last modified "> + + by + + + · Saved +

+ + + + + + + + +
+

Documents

+
+ substr($i, 0, -5), + ...(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $i), true) ?? []) + ]; + }, array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs"), function ($i) { + return !str_starts_with($i, ".") && str_ends_with($i, ".json"); + })); + + $deletable = array_values(array_filter($documents, function ($i) { + return strip_tags($i["contents"]) === "/delete"; + })); + $unsorted_pre = array_values(array_filter($documents, function ($i) { + return strip_tags($i["contents"]) !== "/delete"; + })); + + $unsorted = []; + $categories = []; + foreach ($unsorted_pre as $item) { + if (isset($item["category"])) { + $existing_categories = array_keys($categories); + $matched_category = null; + + foreach ($existing_categories as $existing_category) { + if (levenshtein($item["category"], $existing_category) < 3) { + $matched_category = $existing_category; + } + } + + $selected_category = $matched_category ?? $item["category"]; + if (!isset($categories[$selected_category])) $categories[$selected_category] = []; + $categories[$selected_category][] = $item; + } else { + $unsorted[] = $item; + } + } + + uasort($unsorted, function ($a, $b) { + return $b["last"]["date"] - $a["last"]["date"]; + }); + + uasort($deletable, function ($a, $b) { + return $b["last"]["date"] - $a["last"]["date"]; + }); + + ?> + + $items): ?> +

+
+ + +

Unsorted

+ +
+

Marked for deletion

+
+ +
+ + +
+
+ + + + + diff --git a/pages/docs.php b/pages/docs.php deleted file mode 100644 index bbc3054..0000000 --- a/pages/docs.php +++ /dev/null @@ -1,361 +0,0 @@ - "Untitled document ($id)", - "category" => null, - "contents" => "
This is a new document you just created.
", - "last" => [ - "author" => $_PROFILE["login"], - "date" => time() - ] - ])); - - header("Location: /-/docs/$id"); - die(); -} elseif (isset($select)) { - if (ctype_alnum($select) && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json")) { - $id = $select; - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json"), true); - $titleBase = " · " . $title . " · Cold Haze"; - $title = $data["name"] . " · " . $title; - } else { - header("Location: /-/docs"); - die(); - } -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; - -?> - -
-
-
-
-

- - Back -

-

Category:

-

- - Last modified never - - Last modified "> - - by - - - · Saved -

- - - - - - - - -
-

Documents

-
- substr($i, 0, -5), - ...(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $i), true) ?? []) - ]; - }, array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs"), function ($i) { - return !str_starts_with($i, ".") && str_ends_with($i, ".json"); - })); - - $deletable = array_values(array_filter($documents, function ($i) { - return strip_tags($i["contents"]) === "/delete"; - })); - $unsorted_pre = array_values(array_filter($documents, function ($i) { - return strip_tags($i["contents"]) !== "/delete"; - })); - - $unsorted = []; - $categories = []; - foreach ($unsorted_pre as $item) { - if (isset($item["category"])) { - $existing_categories = array_keys($categories); - $matched_category = null; - - foreach ($existing_categories as $existing_category) { - if (levenshtein($item["category"], $existing_category) < 3) { - $matched_category = $existing_category; - } - } - - $selected_category = $matched_category ?? $item["category"]; - if (!isset($categories[$selected_category])) $categories[$selected_category] = []; - $categories[$selected_category][] = $item; - } else { - $unsorted[] = $item; - } - } - - uasort($unsorted, function ($a, $b) { - return $b["last"]["date"] - $a["last"]["date"]; - }); - - uasort($deletable, function ($a, $b) { - return $b["last"]["date"] - $a["last"]["date"]; - }); - - ?> - - $items): ?> -

-
- - -

Unsorted

- -
-

Marked for deletion

-
- -
- - -
-
- - - - - diff --git a/pages/edit-private.inc b/pages/edit-private.inc new file mode 100644 index 0000000..880effe --- /dev/null +++ b/pages/edit-private.inc @@ -0,0 +1,68 @@ + + +
+
+
+ +
+
+ + diff --git a/pages/emergency.php b/pages/emergency.php deleted file mode 100644 index 55ed49a..0000000 --- a/pages/emergency.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - diff --git a/pages/fronting.inc b/pages/fronting.inc new file mode 100644 index 0000000..c1d8ead --- /dev/null +++ b/pages/fronting.inc @@ -0,0 +1,15 @@ + + +
+
+
+ +
+
+ + diff --git a/pages/fronting.php b/pages/fronting.php deleted file mode 100644 index 3e613c6..0000000 --- a/pages/fronting.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - diff --git a/pages/government.inc b/pages/government.inc new file mode 100644 index 0000000..4698c55 --- /dev/null +++ b/pages/government.inc @@ -0,0 +1,142 @@ + + +
+ + + + + diff --git a/pages/home.inc b/pages/home.inc new file mode 100644 index 0000000..4f4b0f6 --- /dev/null +++ b/pages/home.inc @@ -0,0 +1,73 @@ + + +
+
+ +
+ + Error: +
+ + + +
+ Notice: This website is temporarily under maintenance and the administrators have locked the database. Although you are logged in as , you cannot access any of the logged-in features while the website is under maintenance. Alerts dispatching remains possible in case of an emergency. +
+ + + +
+ +

+
" data-bs-toggle="tooltip" style="overflow: hidden;" href="/">" style="width:32px;height:32px;position:absolute;z-index:99;">
+

+
+
+ ;z-index: 9;margin-left: 8px;opacity: .75;"> +
+
+
+

Cold Haze

+

ponies in 2 plural systems

+
+
+
+ +
+ + + + + +
+
+ + + Cold Haze
+ + + Just a small safe place for two plural systems + +
+
+ +
+ + + = 20 || (int)date('H') < 6)): ?> + +
+ Are you in need of help? If you need immediate help from a loved one, you may want to enable the emergency alert by clicking here, even if that will wake up the . Use it as you need. +
+
+ + +
+ + + + +
+
+ + \ No newline at end of file diff --git a/pages/home.php b/pages/home.php deleted file mode 100644 index a2fe0c3..0000000 --- a/pages/home.php +++ /dev/null @@ -1,67 +0,0 @@ - - -
-
- -
- - Error: -
- - - -
- -

-
" data-bs-toggle="tooltip" style="overflow: hidden;" href="/">.png" style="width:32px;height:32px;position:absolute;z-index:99;">
-

-
-
- ;z-index: 9;margin-left: 8px;opacity: .75;"> -
-
-
-

Cold Haze

-

ponies in 2 plural systems

-
-
-
- -
- - - - - -
-
- - - Cold Haze
- - - Just a small safe place for two plural systems - -
-
- -
- - - = 20 || (int)date('H') < 6)): ?> - -
- Are you in need of help? If you need immediate help from a loved one, you may want to enable the emergency alert by clicking here, even if that will wake up the . Use it as you need. -
-
- - -
- - - - -
-
- - \ No newline at end of file diff --git a/pages/login.inc b/pages/login.inc new file mode 100644 index 0000000..ffbe2d7 --- /dev/null +++ b/pages/login.inc @@ -0,0 +1,49 @@ + + +
+
+
+

Login

+ +
+ Login is temporarily disabled. Login on this website has been temporarily disabled by the administrators for maintenance purposes. +
+ + +
+ You are already logged in. If you want to login to a different account or using a different authentication method, you may do so now. +
+ +

Select how you want to log into Cold Haze.

+
+
+
+
+ +

Equestria.dev Private Authentication

+

For website administrators, allows to change content and access private information.

+ Continue +
+
+
+
+
+
+ +

Equestria.horse/GitLab/GitHub

+

For website users, allows to view more content, ask questions, and set notes for members.

+ Continue +
+
+
+
+ +
+
+ + diff --git a/pages/login.php b/pages/login.php deleted file mode 100644 index ebae1ae..0000000 --- a/pages/login.php +++ /dev/null @@ -1,43 +0,0 @@ - - -
-
-
-

Login

- -
- You are already logged in. If you want to login to a different account or using a different authentication method, you may do so now. -
- -

Select how you want to log into Cold Haze.

-
-
-
-
- -

Equestria.dev Private Authentication

-

For website administrators, allows to change content and access private information.

- Continue -
-
-
-
-
-
- -

Equestria.horse/GitLab/GitHub

-

For website users, allows to view more content, ask questions, and set notes for members.

- Continue -
-
-
-
-
-
- - diff --git a/pages/logout.inc b/pages/logout.inc new file mode 100644 index 0000000..0263278 --- /dev/null +++ b/pages/logout.inc @@ -0,0 +1,15 @@ + $i + ]; + $r["type"] = "marefriends"; + return $r; + }, $member["_metadata"]["marefriends"] ?? []), + ...array_map(function ($i) { + $r = [ + "name" => $i + ]; + $r["type"] = "sisters"; + return $r; + }, $member["_metadata"]["sisters"] ?? []), + ...array_map(function ($i) { + $r = [ + "name" => $i + ]; + $r["type"] = "caretaking"; + return $r; + }, $member["_metadata"]["caretakers"] ?? []) + ] as $rel) { + $id = $rel["name"]; + $otherMember = getSystemMember(explode("/", $id)[0], explode("/", $id)[1]); + + $parts = [ + $member["id"], + $otherMember["id"] + ]; + + asort($parts); + + $relations[implode("-", $parts)] = [ + "id" => implode("", $parts), + "name" => getMiniName($member["display_name"] ?? $member["name"]) . " and " . getMiniName($otherMember["display_name"] ?? $otherMember["name"]), + "type" => $rel["type"], + "images" => [ + getAsset($member['system'], $member["id"], "heads"), + getAsset($otherMember['system'], $otherMember["id"], "heads") + ] + ]; + } +} + +$nicknames = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/nicknames/nicknames.json"), true); + +?> + +
+ + + + + diff --git a/pages/nicknames.php b/pages/nicknames.php deleted file mode 100644 index 4c06818..0000000 --- a/pages/nicknames.php +++ /dev/null @@ -1,115 +0,0 @@ - $i - ]; - $r["type"] = "marefriends"; - return $r; - }, $member["_metadata"]["marefriends"] ?? []), - ...array_map(function ($i) { - $r = [ - "name" => $i - ]; - $r["type"] = "sisters"; - return $r; - }, $member["_metadata"]["sisters"] ?? []), - ...array_map(function ($i) { - $r = [ - "name" => $i - ]; - $r["type"] = "caretaking"; - return $r; - }, $member["_metadata"]["caretakers"] ?? []) - ] as $rel) { - $id = $rel["name"]; - $otherMember = getSystemMember(explode("/", $id)[0], explode("/", $id)[1]); - - $parts = [ - $member["id"], - $otherMember["id"] - ]; - - asort($parts); - - $relations[implode("-", $parts)] = [ - "id" => implode("", $parts), - "name" => getMiniName($member["display_name"] ?? $member["name"]) . " and " . getMiniName($otherMember["display_name"] ?? $otherMember["name"]), - "type" => $rel["type"], - "images" => [ - file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-$member[name].png") ? "/assets/uploads/pt-$member[name].png" : "/assets/uploads/pt.png", - file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-$otherMember[name].png") ? "/assets/uploads/pt-$otherMember[name].png" : "/assets/uploads/pt.png", - ] - ]; - } -} - -$nicknames = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/nicknames.json"), true); - -?> - -
- - - - - diff --git a/pages/page.inc b/pages/page.inc new file mode 100644 index 0000000..22291e2 --- /dev/null +++ b/pages/page.inc @@ -0,0 +1,102 @@ + 2) || $parts[1] === "-")) { + $namesCloudburst = [...array_map(function ($i) { + return $i['name']; + }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true)), "unknown-cb"]; + $namesRaindrops = [...array_map(function ($i) { + return $i['name']; + }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true)), "unknown-rd"]; + + $parts = explode("/", $_GET['_']); + array_unshift($parts, ""); + $parts = array_values($parts); + + if (in_array($parts[1], $namesCloudburst)) { + $parts[0] = "cloudburst"; + } else if (in_array($parts[1], $namesRaindrops)) { + $parts[0] = "raindrops"; + } + + if ($parts[1] === "unknown-rd" || $parts[1] === "unknown-cb") $parts[1] = "unknown"; +} + +$system = $parts[0]; +$member = (isset($parts[1]) ? $parts[1] : null) === "" ? null : (isset($parts[1]) ? $parts[1] : null); + +if ($system !== "cloudburst" && $system !== "raindrops") header("Location: /?error=Invalid system ID") and die(); +$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : "Raindrops System"; +$systemID = $system === "cloudburst" ? "ynmuc" : "gdapd"; + +if ($member === null) { + global $_SystemName; + $_SystemName = $system; + require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/system.inc'; +} else if ($member === "-" && isset($parts[2])) { + if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/includes/system/' . $parts[2] . '.inc')) { + global $_SystemPage; + $_SystemPage = $parts[2]; + require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/system/' . $parts[2] . '.inc'; + } else { + header("Location: /?error=Page not found: " . $parts[2]) and die(); + } +} else { + $memberFoundInAnotherSystem = false; + $traveller = false; + + $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "/members.json"), true); + $members2 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($systemID === "gdapd" ? "ynmuc" : "gdapd") . "/members.json"), true); + $memberData = null; + $memberCommonName = null; + $memberID = null; + + foreach ($members as $m) { + if ($m['name'] === $member) { + $memberData = $m; + $memberCommonName = $m['display_name'] ?? $m['name']; + $memberID = $m['id']; + } + } + + foreach ($members2 as $m) { + if ($m['name'] === $member && $travelling[$m['id']]['travelling']) { + $traveller = true; + $memberData = $m; + $memberCommonName = $m['display_name'] ?? $m['name']; + $memberID = $m['id']; + $system = $systemID === "gdapd" ? "cloudburst" : "raindrops"; + $systemID = $system === "cloudburst" ? "ynmuc" : "gdapd"; + } else if ($m['name'] === $member) { + $memberFoundInAnotherSystem = true; + } + } + + global $_SystemName; + $_SystemName = $system; + + if (str_ends_with($member, "-travelling")) { + header("Location: /" . substr($member, 0, strlen($member) - 11)) and die(); + } + + if (isset($parts[2]) && $parts[2] === "-" && isset($parts[3])) { + if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/includes/member/' . $parts[3] . '.inc')) { + global $_MemberPage; + $_MemberPage = $parts[3]; + require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/member/' . $parts[3] . '.inc'; + } else { + header("Location: /?error=Page not found: " . $parts[3]) and die(); + } + die(); + } + + global $_MemberName; + $_MemberName = $member; + require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/member.inc'; +} + +exit; \ No newline at end of file diff --git a/pages/page.php b/pages/page.php deleted file mode 100644 index cab5dcd..0000000 --- a/pages/page.php +++ /dev/null @@ -1,102 +0,0 @@ - 2) || $parts[1] === "-")) { - $namesCloudburst = [...array_map(function ($i) { - return $i['name']; - }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true)), "unknown-cb"]; - $namesRaindrops = [...array_map(function ($i) { - return $i['name']; - }, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true)), "unknown-rd"]; - - $parts = explode("/", $_GET['_']); - array_unshift($parts, ""); - $parts = array_values($parts); - - if (in_array($parts[1], $namesCloudburst)) { - $parts[0] = "cloudburst"; - } else if (in_array($parts[1], $namesRaindrops)) { - $parts[0] = "raindrops"; - } - - if ($parts[1] === "unknown-rd" || $parts[1] === "unknown-cb") $parts[1] = "unknown"; -} - -$system = $parts[0]; -$member = (isset($parts[1]) ? $parts[1] : null) === "" ? null : (isset($parts[1]) ? $parts[1] : null); - -if ($system !== "cloudburst" && $system !== "raindrops") header("Location: /?error=Invalid system ID") and die(); -$systemCommonName = $system === "cloudburst" ? "Cloudburst System" : "Raindrops System"; -$systemID = $system === "cloudburst" ? "ynmuc" : "gdapd"; - -if ($member === null) { - global $_SystemName; - $_SystemName = $system; - require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/system.php'; -} else if ($member === "-" && isset($parts[2])) { - if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/includes/system/' . $parts[2] . '.php')) { - global $_SystemPage; - $_SystemPage = $parts[2]; - require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/system/' . $parts[2] . '.php'; - } else { - header("Location: /?error=Page not found: " . $parts[2]) and die(); - } -} else { - $memberFoundInAnotherSystem = false; - $traveller = false; - - $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-members.json"), true); - $members2 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($systemID === "gdapd" ? "ynmuc" : "gdapd") . "-members.json"), true); - $memberData = null; - $memberCommonName = null; - $memberID = null; - - foreach ($members as $m) { - if ($m['name'] === $member) { - $memberData = $m; - $memberCommonName = $m['display_name'] ?? $m['name']; - $memberID = $m['id']; - } - } - - foreach ($members2 as $m) { - if ($m['name'] === $member && $travelling[$m['id']]['travelling']) { - $traveller = true; - $memberData = $m; - $memberCommonName = $m['display_name'] ?? $m['name']; - $memberID = $m['id']; - $system = $systemID === "gdapd" ? "cloudburst" : "raindrops"; - $systemID = $system === "cloudburst" ? "ynmuc" : "gdapd"; - } else if ($m['name'] === $member) { - $memberFoundInAnotherSystem = true; - } - } - - global $_SystemName; - $_SystemName = $system; - - if (str_ends_with($member, "-travelling")) { - header("Location: /" . substr($member, 0, strlen($member) - 11)) and die(); - } - - if (isset($parts[2]) && $parts[2] === "-" && isset($parts[3])) { - if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/includes/member/' . $parts[3] . '.php')) { - global $_MemberPage; - $_MemberPage = $parts[3]; - require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/member/' . $parts[3] . '.php'; - } else { - header("Location: /?error=Page not found: " . $parts[3]) and die(); - } - die(); - } - - global $_MemberName; - $_MemberName = $member; - require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/member.php'; -} - -exit; \ No newline at end of file diff --git a/pages/parser.inc b/pages/parser.inc new file mode 100644 index 0000000..dc07744 --- /dev/null +++ b/pages/parser.inc @@ -0,0 +1,255 @@ + + +
+
+
+

Message parser

+

Enter a message here, and we will tell you which system member this message came from.

+ +
+ + + +
+ +
+ +
+ Cloudburst System +
+
+ +
+
+
+ Name + (Prefix) +
+
+
+
+ +
+ Raindrops System +
+
+ +
+
+
+ Name + (Prefix) +
+
+
+
+
+ +
+
+ The entered message does not contain a prefix/suffix corresponding to a member of the selected system(s); therefore, the most common fronter was selected as a fallback. While the most common fronter is supposed to use their prefix too, we assume they are talking when there is no prefix/suffix in the current message. +
+ + + +
+ + diff --git a/pages/parser.php b/pages/parser.php deleted file mode 100644 index 1c3dea4..0000000 --- a/pages/parser.php +++ /dev/null @@ -1,255 +0,0 @@ - - -
-
-
-

Message parser

-

Enter a message here, and we will tell you which system member this message came from.

- -
- - - -
- -
- -
- Cloudburst System -
-
- -
-
-
- Name - (Prefix) -
-
-
-
- -
- Raindrops System -
-
- -
-
-
- Name - (Prefix) -
-
-
-
-
- -
-
- The entered message does not contain a prefix/suffix corresponding to a member of the selected system(s); therefore, the most common fronter was selected as a fallback. While the most common fronter is supposed to use their prefix too, we assume they are talking when there is no prefix/suffix in the current message. -
- - - -
- - diff --git a/pages/pleasure.inc b/pages/pleasure.inc new file mode 100644 index 0000000..f59d187 --- /dev/null +++ b/pages/pleasure.inc @@ -0,0 +1,15 @@ + + +
+
+
+ +
+
+ + diff --git a/pages/pleasure.php b/pages/pleasure.php deleted file mode 100644 index 14b5440..0000000 --- a/pages/pleasure.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - diff --git a/pages/prefix.inc b/pages/prefix.inc new file mode 100644 index 0000000..d7d8a40 --- /dev/null +++ b/pages/prefix.inc @@ -0,0 +1,451 @@ + + +
+
+
+

Prefix generator

+

This prefix generator will take into account the prefixes from the existing members to try to generate new original prefixes for a potential new member.

+ +
+ + + +
+ +
+ + +
+

Generated Prefix

+

We couldn't generate a prefix for a member who goes by this name, try tuning your settings.

+
+ +
    +
  1. {...}
  2. +
+ +
+ + + +
+ + diff --git a/pages/prefix.php b/pages/prefix.php deleted file mode 100644 index 2b1149b..0000000 --- a/pages/prefix.php +++ /dev/null @@ -1,449 +0,0 @@ - - -
-
-
-

Prefix generator

-

This prefix generator will take into account the prefixes from the existing members to try to generate new original prefixes for a potential new member.

- -
- - - -
- -
- - -
-

Generated Prefix

-

We couldn't generate a prefix for a member who goes by this name, try tuning your settings.

-
- -
    -
  1. {...}
  2. -
- -
- - - -
- - diff --git a/pages/relations.inc b/pages/relations.inc new file mode 100644 index 0000000..80520da --- /dev/null +++ b/pages/relations.inc @@ -0,0 +1,105 @@ + + +
+
+
+

Relations

+ 0 || count($member["_metadata"]["sisters"]) > 0): ?> + + +
+ + +
+ + diff --git a/pages/relations.php b/pages/relations.php deleted file mode 100644 index aac2839..0000000 --- a/pages/relations.php +++ /dev/null @@ -1,105 +0,0 @@ - - -
-
-
-

Relations

- 0 || count($member["_metadata"]["sisters"]) > 0): ?> - - -
- - -
- - diff --git a/pages/rules.inc b/pages/rules.inc new file mode 100644 index 0000000..21ae7e6 --- /dev/null +++ b/pages/rules.inc @@ -0,0 +1,253 @@ + $rule) { + if (!isset($rule["name"]) || !isset($rule["content"]) && !is_numeric($index)) { + header("Location: /-/rules"); + die(); + } + + if (trim($rule["name"]) === "") { + unset($_POST["payload"][$index]); + continue; + } + + if (!isset($rule["approved"])) $rule["approved"] = []; + if (isset($rule["approved"][0])) $rule["approved"][0] = true; else $rule["approved"][0] = false; + if (isset($rule["approved"][1])) $rule["approved"][1] = true; else $rule["approved"][1] = false; + + $_POST["payload"][$index] = $rule; + } + + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/rules/rules.json", utf8_encode(json_encode($_POST["payload"]))); + + header("Location: /-/rules"); + die(); +} + +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; + +?> + +
+
+
+

Systems rules

+

Click on a rule to view additional details. Edit rules

+ + + +
    + +
  • +
    + + . + + Unapproved + + + +
    + This rule has not yet been approved. All rules need to be approved by the leaders from both systems. This rule is still missing approval from . +
    + +
    class="list-group-item"> + +
    +
    +
  • + +
+
+
+ + + + + + + + diff --git a/pages/rules.php b/pages/rules.php deleted file mode 100644 index 9148d89..0000000 --- a/pages/rules.php +++ /dev/null @@ -1,253 +0,0 @@ - $rule) { - if (!isset($rule["name"]) || !isset($rule["content"]) && !is_numeric($index)) { - header("Location: /-/rules"); - die(); - } - - if (trim($rule["name"]) === "") { - unset($_POST["payload"][$index]); - continue; - } - - if (!isset($rule["approved"])) $rule["approved"] = []; - if (isset($rule["approved"][0])) $rule["approved"][0] = true; else $rule["approved"][0] = false; - if (isset($rule["approved"][1])) $rule["approved"][1] = true; else $rule["approved"][1] = false; - - $_POST["payload"][$index] = $rule; - } - - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/rules.json", utf8_encode(json_encode($_POST["payload"]))); - - header("Location: /-/rules"); - die(); -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; - -?> - -
-
-
-

Systems rules

-

Click on a rule to view additional details. Edit rules

- - - -
    - -
  • -
    - - . - - Unapproved - - - -
    - This rule has not yet been approved. All rules need to be approved by the primary protectors from both systems. This rule is still missing approval from . -
    - -
    class="list-group-item"> - -
    -
    -
  • - -
-
-
- - - - - - - - diff --git a/pages/score.inc b/pages/score.inc new file mode 100644 index 0000000..e04f9e7 --- /dev/null +++ b/pages/score.inc @@ -0,0 +1,208 @@ + + +
+
+
+

Score system testing

+ +

Raindrops System ()

+
    + $name, + "page" => "/" . $member["name"], + "score" => $score["total"], + "details" => $score + ]; + } + } + + uasort($scores, function($a, $b) { + return $b["score"] - $a["score"]; + }); + + ?> + + +
  • +
    + "> () +
    +
    +
  • + +
+ + +

Cloudburst System ()

+
    + $name, + "page" => "/" . $member["name"], + "score" => $score["total"], + "details" => $score + ]; + } + } + + uasort($scores, function($a, $b) { + return $b["score"] - $a["score"]; + }); + + ?> + + +
  • +
    + "> () +
    +
    +
  • + +
+ +

Global ()

+
    + $name, + "page" => "/" . $member["name"], + "score" => $score["total"], + "details" => $score + ]; + } + } + foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc/members.json"), true) as $member) { + if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling")) { + $name = $member["display_name"] ?? $member["name"]; + require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/score.inc"; + $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$member[id].json"), true)); + $score = calculateScore($metadata, $member["display_name"] ?? $member["name"]); + + $scores[] = [ + "name" => $name, + "page" => "/" . $member["name"], + "score" => $score["total"], + "details" => $score + ]; + } + } + + uasort($scores, function($a, $b) { + return $b["score"] - $a["score"]; + }); + + ?> + + +
  • +
    + "> () +
    +
    +
  • + +
+
+
+ + diff --git a/pages/score.php b/pages/score.php deleted file mode 100644 index 370d757..0000000 --- a/pages/score.php +++ /dev/null @@ -1,208 +0,0 @@ - - -
-
-
-

Score system testing

- -

Raindrops System ()

-
    - $name, - "page" => "/" . $member["name"], - "score" => $score["total"], - "details" => $score - ]; - } - } - - uasort($scores, function($a, $b) { - return $b["score"] - $a["score"]; - }); - - ?> - - -
  • -
    - "> () -
    -
    -
  • - -
- - -

Cloudburst System ()

-
    - $name, - "page" => "/" . $member["name"], - "score" => $score["total"], - "details" => $score - ]; - } - } - - uasort($scores, function($a, $b) { - return $b["score"] - $a["score"]; - }); - - ?> - - -
  • -
    - "> () -
    -
    -
  • - -
- -

Global ()

-
    - $name, - "page" => "/" . $member["name"], - "score" => $score["total"], - "details" => $score - ]; - } - } - foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true) as $member) { - if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling")) { - $name = $member["display_name"] ?? $member["name"]; - require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/score.php"; - $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json"), true)); - $score = calculateScore($metadata, $member["display_name"] ?? $member["name"]); - - $scores[] = [ - "name" => $name, - "page" => "/" . $member["name"], - "score" => $score["total"], - "details" => $score - ]; - } - } - - uasort($scores, function($a, $b) { - return $b["score"] - $a["score"]; - }); - - ?> - - -
  • -
    - "> () -
    -
    -
  • - -
-
-
- - diff --git a/pages/splitting.inc b/pages/splitting.inc new file mode 100644 index 0000000..1ea2d70 --- /dev/null +++ b/pages/splitting.inc @@ -0,0 +1,55 @@ + + +
+
+
+

Members by splitting date

+ +
+ "> + " style="width:24px;">  + + +
+ Formed at least () +
+
+ +
+ + +
+ + diff --git a/pages/splitting.php b/pages/splitting.php deleted file mode 100644 index d50ede8..0000000 --- a/pages/splitting.php +++ /dev/null @@ -1,55 +0,0 @@ - - -
-
-
-

Members by splitting date

- -
- "> - .png" style="width:24px;">  - - -
- Formed at least () -
-
- -
- - -
- - diff --git a/pages/stats.inc b/pages/stats.inc new file mode 100644 index 0000000..19d4453 --- /dev/null +++ b/pages/stats.inc @@ -0,0 +1,441 @@ + + + + +
+
+
+

Statistics

+ 0, + "raindrops" => 0, + "total" => 0, + "end" => strtotime($switch["timestamp"]), + "start" => null + ]; + + if ($week !== $lastWeek) { + if (isset($weeks[$lastWeek])) { + $weeks[$lastWeek]["start"] = strtotime($switch["timestamp"]); + $lastWeek = $week; + } + } + + $weeks[$week]["raindrops"]++; + $weeks[$week]["total"]++; + } + + $lastWeek = 0; + foreach ($switchesCloudburst as $switch) { + $week = date('YW', strtotime($switch["timestamp"])); + if ($lastWeek === 0) $lastWeek = $week; + + if (!isset($weeks[$week])) $weeks[$week] = [ + "cloudburst" => 0, + "raindrops" => 0, + "total" => 0, + "end" => strtotime($switch["timestamp"]), + "start" => null + ]; + + if ($week !== $lastWeek) { + if (isset($weeks[$lastWeek])) { + $weeks[$lastWeek]["start"] = strtotime($switch["timestamp"]); + $lastWeek = $week; + } + } + + $weeks[$week]["cloudburst"]++; + $weeks[$week]["total"]++; + } + + $index = 0; + foreach ($weeks as $id => $week) { + if ($index >= 20) continue; + $weeksRectified[$id] = $week; + $index++; + } + + $weeksRectified = array_filter(array_reverse($weeksRectified), function ($i) { + return $i["start"] > 1651363200; + }); + + $members = []; + $frontersMonth = []; + + $fronts = []; + $lastFrontIDs = []; + + foreach (array_reverse($switchesRaindrops) as $switch) { + foreach ($lastFrontIDs as $frontID) { + $fronts[$frontID]["end"] = strtotime($switch["timestamp"]); + } + $lastFrontIDs = []; + + $index = 0; foreach ($switch["members"] as $member) { + if (strtotime($switch["timestamp"]) - (time() - 86400*30) < 0) continue; + $fronts[$switch["id"] . ":" . $index] = [ + "member" => $member, + "start" => strtotime($switch["timestamp"]), + "end" => strtotime(date('c')), + "duration" => null + ]; + $lastFrontIDs[] = $switch["id"] . ":" . $index; + } $index++; + } + + foreach ($fronts as $id => $front) { + $fronts[$id]["duration"] = $front["end"] - $front["start"]; + + if (!($front["start"] - (time() - 86400*30) < 0)) { + if (!isset($members[$front["member"]])) $members[$front["member"]] = [ + "time" => 0, + "name" => getMemberWithoutSystem($front["member"])["display_name"], + "color" => getMemberWithoutSystem($front["member"])["color"], + ]; + $members[$front["member"]]["time"] += $fronts[$id]["duration"]; + } + } + + foreach ($fronts as $front) { + if (!isset($frontersMonth[date('Y-m', $front["start"])])) $frontersMonth[date('Y-m', $front["start"])] = []; + if (!isset($frontersMonth[date('Y-m', $front["start"])][$front["member"]])) $frontersMonth[date('Y-m', $front["start"])][$front["member"]] = 0; + $frontersMonth[date('Y-m', $front["start"])][$front["member"]] += $front["duration"]; + } + + $fronts = []; + $lastFrontIDs = []; + + foreach (array_reverse($switchesCloudburst) as $switch) { + foreach ($lastFrontIDs as $frontID) { + $fronts[$frontID]["end"] = strtotime($switch["timestamp"]); + } + $lastFrontIDs = []; + + $index = 0; foreach ($switch["members"] as $member) { + $fronts[$switch["id"] . ":" . $index] = [ + "member" => $member, + "start" => strtotime($switch["timestamp"]), + "end" => strtotime(date('c')), + "duration" => null + ]; + $lastFrontIDs[] = $switch["id"] . ":" . $index; + } $index++; + } + + foreach ($fronts as $id => $front) { + $fronts[$id]["duration"] = $front["end"] - $front["start"]; + + if (!($front["start"] - (time() - 86400*30) < 0)) { + if (!isset($members[$front["member"]])) $members[$front["member"]] = [ + "time" => 0, + "name" => getMemberWithoutSystem($front["member"])["display_name"], + "color" => getMemberWithoutSystem($front["member"])["color"], + ]; + $members[$front["member"]]["time"] += $fronts[$id]["duration"]; + } + } + + foreach ($fronts as $front) { + if (!isset($frontersMonth[date('Y-m', $front["start"])])) $frontersMonth[date('Y-m', $front["start"])] = []; + if (!isset($frontersMonth[date('Y-m', $front["start"])][$front["member"]])) $frontersMonth[date('Y-m', $front["start"])][$front["member"]] = 0; + $frontersMonth[date('Y-m', $front["start"])][$front["member"]] += $front["duration"]; + } + + $fronts = array_reverse($fronts); + uasort($members, function ($a, $b) { + return $b["time"] - $a["time"]; + }); + + $frontersMonthRectified = []; + foreach ($frontersMonth as $monthID => $month) { + $thisMonth = []; + + foreach ($month as $id => $time) { + $thisMonth[$id] = [ + "duration" => $time, + "name" => getMemberWithoutSystem($id)["display_name"], + "color" => getMemberWithoutSystem($id)["color"] + ]; + } + + $frontersMonthRectified[$monthID] = $thisMonth; + } + + uasort($frontersMonthRectified, function ($a, $b) use ($frontersMonthRectified) { + return strtotime(array_search($a, $frontersMonthRectified) . "-01") - strtotime(array_search($b, $frontersMonthRectified) . "-01"); + }); + + $frontersMonthMembers = []; + foreach ($frontersMonthRectified as $month => $fronters) { + foreach ($fronters as $fronter => $data) { + foreach (scoreOrderGlobal() as $member) { + if (!isset($frontersMonthMembers[$member["id"]])) $frontersMonthMembers[$member["id"]] = []; + } + } + + foreach ($frontersMonthMembers as $key => $member) { + $frontersMonthMembers[$key][$month] = $frontersMonthRectified[$month][$key] ?? [ + "duration" => 0 + ]; + /*$frontersMonthMembers[$key][$month] = array_map(function ($i) { + return $i["duration"]; + }, $frontersMonthMembers[$key][$month]);*/ + } + } + + ?> + +

Switches per week

+ + + +
+

Time at front in the last 30 days

+ + + +
+

Time at front per month

+ + +
+
+ + diff --git a/pages/terminology.inc b/pages/terminology.inc new file mode 100644 index 0000000..c115bcf --- /dev/null +++ b/pages/terminology.inc @@ -0,0 +1,15 @@ + + +
+
+
+ +
+
+ + \ No newline at end of file diff --git a/pages/terminology.php b/pages/terminology.php deleted file mode 100644 index 955e470..0000000 --- a/pages/terminology.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - \ No newline at end of file diff --git a/pages/together-dev.inc b/pages/together-dev.inc new file mode 100644 index 0000000..6ea9704 --- /dev/null +++ b/pages/together-dev.inc @@ -0,0 +1,4 @@ + + + + + + + + + + + + + +
+
+ +
+ + +
+ +
+ Notification. +
+Skip +
+
+
+ +
+
+
+
+
+
+
+
+
+ -0:00 +
+ + + +
+
+ +
+ \ No newline at end of file diff --git a/pages/together.php b/pages/together.php deleted file mode 100644 index 65786f5..0000000 --- a/pages/together.php +++ /dev/null @@ -1,939 +0,0 @@ - - - - - - - - - - - - - -
-
- -
- - -
- -
- Notification. -
-Skip -
-
-
- -
-
-
-
-
-
-
-
-
- -0:00 -
- - - -
-
- -
- \ No newline at end of file diff --git a/pages/toys.inc b/pages/toys.inc new file mode 100644 index 0000000..8e9ba57 --- /dev/null +++ b/pages/toys.inc @@ -0,0 +1,902 @@ + $item) { + if ($item["id"] === $id) { + $selectedIndex = $index; + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/toys"); + die(); + } + + unset($data[$selectedIndex]); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json", utf8_encode(json_encode($data))); + header("Location: /-/toys/?d&id=" . $id); + die(); +} + +if (isset($_POST['updateAction'])) { + $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json"), true); + + $selected = null; + $selectedIndex = -1; + $id = $_POST['action']; + + foreach ($data as $index => $item) { + if ($item["id"] === $id) { + $selectedIndex = $index; + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/toys"); + die(); + } + + if (isset($_POST["sexual"])) { + $selected["sexual"] = true; + } else { + $selected["sexual"] = false; + } + + if (isset($_POST["name"])) $selected["name"] = strip_tags(trim($_POST["name"])); + if (isset($_POST["usage"])) $selected["usage"] = strip_tags(trim($_POST["usage"])); + if (isset($_POST["irl"])) $selected["irl"] = strip_tags(trim($_POST["irl"])); + if (isset($_POST["keywords"])) $selected["keywords"] = array_map(function ($i) { + return trim($i); + }, explode(",", strip_tags(trim($_POST["keywords"])))); + if (isset($_POST["description"])) $selected["description"] = strip_tags(trim($_POST["description"])); + if (isset($_POST["water"])) $selected["water"] = match ($_POST["water"]) { + "0" => "out", + "1" => "in", + "2" => "both", + "3" => "playground" + }; + + if (isset($_POST["relations"])) { + $ponies = []; + + foreach ($_POST["relations"] as $relation => $d) { + $ponies[] = [ + "members" => explode("-", $relation), + "deprecated" => isset($d["deprecated"]), + "sexual" => isset($d["sexual"]) + ]; + } + + $selected["ponies"] = $ponies; + } + + global $_PROFILE; + if ($_PROFILE['login'] === "raindrops" && isset($_POST["verified"])) { + $selected["verified"] = true; + } else { + unset($selected["verified"]); + } + + if (isset($_POST["untested"])) { + $selected["untested"] = true; + } else { + unset($selected["untested"]); + } + + $data[$selectedIndex] = $selected; + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json", utf8_encode(json_encode($data))); + + header("Location: /-/toys/" . $id); + die(); +} + +if (isset($_POST['createAction'])) { + require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/random.inc"; + $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json"), true); + + if (!isset($_POST["name"]) || !isset($_POST["water"])) { + header("Location: /-/toys"); + die(); + } + if (trim($_POST["name"]) === "" || !is_numeric($_POST["water"])) { + header("Location: /-/toys"); + die(); + } + + $water = match ($_POST["water"]) { + "0" => "out", + "1" => "in", + "2" => "both", + "3" => "playground" + }; + $name = strip_tags(trim($_POST["name"])); + $id = random(); + + $ponies = []; + + if (isset($_POST["relations"])) { + foreach ($_POST["relations"] as $relation => $_) { + $ponies[] = [ + "members" => explode("-", $relation), + "deprecated" => false + ]; + } + } + + if (isset($_POST["sexual"])) { + $sexual = true; + } else { + $sexual = false; + } + + $data[] = [ + "id" => $id, + "name" => $name, + "water" => $water, + "description" => null, + "ponies" => $ponies, + "usage" => null, + "irl" => null, + "keywords" => [], + "sexual" => $sexual + ]; + + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json", utf8_encode(json_encode($data))); + header("Location: /-/toys/" . $id); + die(); +} + +global $pagename; +$parts = explode("/", $pagename); +$data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json"), true); + +$selected = null; + +if (isset($parts[1])) { + $id = $parts[1]; + + foreach ($data as $item) { + if ($item["id"] === $id) { + $selected = $item; + break; + } + } + + if ($selected === null) { + header("Location: /-/toys/?nf&id=" . $id); + die(); + } else { + $title = $selected["name"] . " · " . $title; + } +} + +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/keywords.inc'; + +if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys/toys.json", "[]"); + +global $_PROFILE; + +?> + + + +
+
+
"> + +
+ + Error: The requested toy () was not found, it may have been deleted or has never existed. +
+ + + +
+ + Success: The toy with ID has been successfully deleted. +
+ + + + +

+ + Back +

+

+ Edit · + + Sexual + + Pleasurable + + Unverified + Untested + + Underwater + + Outside of water + + In playground + + Underwater + Outside of water + +

+ + + ", strip_tags($selected["description"]))); ?> + +

No description provided for this toy. Enter edit mode to add a description to this toy.

+ + +
+ + +
+ + Usage:
+ + 1) echo("
    "); + + foreach ($lines as $line) { + if (count($lines) > 1) echo("
  • "); + + $parts = explode(":", $line); + + if (count($parts) > 1 && strlen($parts[0]) < 30) { + $p0 = $parts[0]; array_shift($parts); + echo(replaceKeyWords("" . $p0 . ":" . implode(":", $parts))); + } else { + echo(replaceKeyWords(implode(":", $parts))); + } + + if (count($lines) > 1) echo("
  • "); + } + + if (count($lines) > 1) echo("
"); + + ?> + +

No usage provided for this toy. Enter edit mode to add usage information to this toy.

+ + +
+ + Instructions to craft in real life:
+ + + +

This toy is not craftable in real life.

+ + +
+ +

Similar toys

+
+ $action["id"], + "water" => $action["water"], + "ponies" => $action["ponies"], + "sexual" => $action["sexual"] + ]; + } + + foreach ($names as $name => $data) { + $namesByDistance[] = [ + "name" => $name, + "distance" => levenshtein($currentName, $name) + ((int)($data["water"] !== $selected["water"]) * 2), + "id" => $data["id"], + "water" => $data["water"], + "ponies" => $data["ponies"], + "sexual" => $data["sexual"] + ]; + } + + uasort($namesByDistance, function ($a, $b) use ($selected) { + return $a["distance"] - $b["distance"]; + }); + + foreach ($namesByDistance as $item) { + echo(""); + } + + $index = 0; + foreach ($namesByDistance as $item): if ($index < 3): + ?> + + +
+ + + + + +

Toys database

+

toys ( non-sexual, sexual, untested, incomplete)

+ + + + + +
+ +
+
+

Not finding what you are looking for? Add a toy.

+
+ + + + + + +
+
+ + + + + + + diff --git a/pages/toys.php b/pages/toys.php deleted file mode 100644 index e0fb1fe..0000000 --- a/pages/toys.php +++ /dev/null @@ -1,915 +0,0 @@ - $item) { - if ($item["id"] === $id) { - $selectedIndex = $index; - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/toys"); - die(); - } - - unset($data[$selectedIndex]); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json", utf8_encode(json_encode($data))); - header("Location: /-/toys/?d&id=" . $id); - die(); -} - -if (isset($_POST['updateAction'])) { - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json"), true); - - $selected = null; - $selectedIndex = -1; - $id = $_POST['action']; - - foreach ($data as $index => $item) { - if ($item["id"] === $id) { - $selectedIndex = $index; - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/toys"); - die(); - } - - if (isset($_POST["sexual"])) { - $selected["sexual"] = true; - } else { - $selected["sexual"] = false; - } - - if (isset($_POST["name"])) $selected["name"] = strip_tags(trim($_POST["name"])); - if (isset($_POST["usage"])) $selected["usage"] = strip_tags(trim($_POST["usage"])); - if (isset($_POST["irl"])) $selected["irl"] = strip_tags(trim($_POST["irl"])); - if (isset($_POST["keywords"])) $selected["keywords"] = array_map(function ($i) { - return trim($i); - }, explode(",", strip_tags(trim($_POST["keywords"])))); - if (isset($_POST["description"])) $selected["description"] = strip_tags(trim($_POST["description"])); - if (isset($_POST["water"])) $selected["water"] = match ($_POST["water"]) { - "0" => "out", - "1" => "in", - "2" => "both", - "3" => "playground" - }; - - if (isset($_POST["relations"])) { - $ponies = []; - - foreach ($_POST["relations"] as $relation => $d) { - $ponies[] = [ - "members" => explode("-", $relation), - "deprecated" => isset($d["deprecated"]), - "sexual" => isset($d["sexual"]) - ]; - } - - $selected["ponies"] = $ponies; - } - - global $_PROFILE; - if ($_PROFILE['login'] === "raindrops" && isset($_POST["verified"])) { - $selected["verified"] = true; - } else { - unset($selected["verified"]); - } - - if (isset($_POST["untested"])) { - $selected["untested"] = true; - } else { - unset($selected["untested"]); - } - - $data[$selectedIndex] = $selected; - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json", utf8_encode(json_encode($data))); - - header("Location: /-/toys/" . $id); - die(); -} - -if (isset($_POST['createAction'])) { - require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/random.php"; - $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json"), true); - - if (!isset($_POST["name"]) || !isset($_POST["water"])) { - header("Location: /-/toys"); - die(); - } - if (trim($_POST["name"]) === "" || !is_numeric($_POST["water"])) { - header("Location: /-/toys"); - die(); - } - - $water = match ($_POST["water"]) { - "0" => "out", - "1" => "in", - "2" => "both", - "3" => "playground" - }; - $name = strip_tags(trim($_POST["name"])); - $id = random(); - - $ponies = []; - - if (isset($_POST["relations"])) { - foreach ($_POST["relations"] as $relation => $_) { - $ponies[] = [ - "members" => explode("-", $relation), - "deprecated" => false - ]; - } - } - - if (isset($_POST["sexual"])) { - $sexual = true; - } else { - $sexual = false; - } - - $data[] = [ - "id" => $id, - "name" => $name, - "water" => $water, - "description" => null, - "ponies" => $ponies, - "usage" => null, - "irl" => null, - "keywords" => [], - "sexual" => $sexual - ]; - - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json", utf8_encode(json_encode($data))); - header("Location: /-/toys/" . $id); - die(); -} - -global $pagename; -$parts = explode("/", $pagename); -$data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json"), true); - -$selected = null; - -if (isset($parts[1])) { - $id = $parts[1]; - - foreach ($data as $item) { - if ($item["id"] === $id) { - $selected = $item; - break; - } - } - - if ($selected === null) { - header("Location: /-/toys/?nf&id=" . $id); - die(); - } else { - $title = $selected["name"] . " · " . $title; - } -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/keywords.php'; - -if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json")) file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json", "[]"); - -global $_PROFILE; - -?> - - - -
-
-
"> - -
- - Error: The requested toy () was not found, it may have been deleted or has never existed. -
- - - -
- - Success: The toy with ID has been successfully deleted. -
- - - - -

- - Back -

-

- Edit · - - Sexual - - Pleasurable - - Unverified - Untested - - Underwater - - Outside of water - - In playground - - Underwater - Outside of water - -

- - - ", strip_tags($selected["description"]))); ?> - -

No description provided for this toy. Enter edit mode to add a description to this toy.

- - -
- Can be used by: - -
    - -
  • - .png"> - .png"> - - and -
  • - - -
  • - - .png"> - .png"> - - and - - Deprecated -
  • - -
- -
- - Usage:
- - 1) echo("
    "); - - foreach ($lines as $line) { - if (count($lines) > 1) echo("
  • "); - - $parts = explode(":", $line); - - if (count($parts) > 1 && strlen($parts[0]) < 30) { - $p0 = $parts[0]; array_shift($parts); - echo(replaceKeyWords("" . $p0 . ":" . implode(":", $parts))); - } else { - echo(replaceKeyWords(implode(":", $parts))); - } - - if (count($lines) > 1) echo("
  • "); - } - - if (count($lines) > 1) echo("
"); - - ?> - -

No usage provided for this toy. Enter edit mode to add usage information to this toy.

- - -
- - Instructions to craft in real life:
- - - -

This toy is not craftable in real life.

- - -
- -

Similar toys

-
- $action["id"], - "water" => $action["water"], - "ponies" => $action["ponies"], - "sexual" => $action["sexual"] - ]; - } - - foreach ($names as $name => $data) { - $namesByDistance[] = [ - "name" => $name, - "distance" => levenshtein($currentName, $name) + ((int)($data["water"] !== $selected["water"]) * 2), - "id" => $data["id"], - "water" => $data["water"], - "ponies" => $data["ponies"], - "sexual" => $data["sexual"] - ]; - } - - uasort($namesByDistance, function ($a, $b) use ($selected) { - return $a["distance"] - $b["distance"]; - }); - - foreach ($namesByDistance as $item) { - echo(""); - } - - $index = 0; - foreach ($namesByDistance as $item): if ($index < 3): - ?> - - -
- - - - - -

Toys database

-

toys ( non-sexual, sexual, untested, incomplete)

- - - - - -
- -
-
-

Not finding what you are looking for? Add a toy.

-
- - - - - - -
-
- - - - - - - diff --git a/pages/travelling.inc b/pages/travelling.inc new file mode 100644 index 0000000..e808063 --- /dev/null +++ b/pages/travelling.inc @@ -0,0 +1,175 @@ + [ + 'method' => "DELETE", + 'header' => "Authorization: " . $app["pluralkit"][$travellingSystem === "gdapd" ? "raindrops" : "cloudburst"] + ] + ]; + + $reqContext = stream_context_create($reqOptions); + + // No actual data is received on DELETE, so we don't even bother trying to collect req response; if it fails it will put a warning in the logs anyway. + sleep(1); + file_get_contents("https://api.pluralkit.me/v2/members/$travellingMember", false, $reqContext); + } + } else { + $travelling[$_GET['member']]["travelling"] = true; + $travelling[$_GET['member']]["pluralkit"] = null; + $travelling[$_GET['member']]["history"][] = [ + "start" => date("c"), + "end" => null + ]; + + // Insert code here to run after a travelling member is ADDED. + // $id is the member ID (e.g. rirgf) + // $member is the member + // $system is the system the member comes from + // $metadata is the ponies.equestria.horse metadata + // $travellingMember is unset here + // Store the travelling member ID in $travelling[$id]['pluralkit'] + $reqOptions = [ + 'http' => [ + 'method' => "POST", + 'header' => "Authorization: " . $app["pluralkit"][$travellingSystem === "gdapd" ? "raindrops" : "cloudburst"] . "\r\n" . + "Content-Type: application/json", + 'content' => json_encode([ + 'name' => "$member[name]-travelling", + 'display_name' => $member["display_name"], + 'color' => $member["color"], + 'birthday' => $member["birthday"], + 'created' => $member["created"], + 'pronouns' => $member["pronouns"], + 'avatar_url' => $member["avatar_url"], + 'banner' => $member["banner"], + 'description' => "**This pony is visiting this system from the " . ($system === "gdapd" ? "Raindrops System" : "Cloudburst System") . ". They are not a permanent member of this system**\n\n$member[description]", + 'proxy_tags' => array_map(function ($i) { + $i["prefix"] = "+" . $i['prefix']; + return $i; + }, $member["proxy_tags"]), + 'privacy' => $member["privacy"] + ]) + ] + ]; + + $reqContext = stream_context_create($reqOptions); + + sleep(1); + $member = json_decode(file_get_contents("https://api.pluralkit.me/v2/members", false, $reqContext), true); + + // Member exists? + if (isset($member)) { + $travelling[$id]['pluralkit'] = $member["id"]; + } + } + } + + header("Location: /-/travelling"); + file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling/travelling.json", utf8_encode(json_encode($travelling, JSON_PRETTY_PRINT))); + die(); +} + +require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.inc'; +global $travelling; + +?> + + + +
+
+
+

System travelling

+ +
+ "> + " style="width:24px;">  + + +
+
+ Current system:
+ + ">.png"> System + + () + +
+
+ + +
+ +
+ + +
+ + diff --git a/pages/travelling.php b/pages/travelling.php deleted file mode 100644 index 95c7851..0000000 --- a/pages/travelling.php +++ /dev/null @@ -1,175 +0,0 @@ - [ - 'method' => "DELETE", - 'header' => "Authorization: " . $app["pluralkit"][$travellingSystem === "gdapd" ? "raindrops" : "cloudburst"] - ] - ]; - - $reqContext = stream_context_create($reqOptions); - - // No actual data is received on DELETE, so we don't even bother trying to collect req response; if it fails it will put a warning in the logs anyway. - sleep(1); - file_get_contents("https://api.pluralkit.me/v2/members/$travellingMember", false, $reqContext); - } - } else { - $travelling[$_GET['member']]["travelling"] = true; - $travelling[$_GET['member']]["pluralkit"] = null; - $travelling[$_GET['member']]["history"][] = [ - "start" => date("c"), - "end" => null - ]; - - // Insert code here to run after a travelling member is ADDED. - // $id is the member ID (e.g. rirgf) - // $member is the member - // $system is the system the member comes from - // $metadata is the ponies.equestria.horse metadata - // $travellingMember is unset here - // Store the travelling member ID in $travelling[$id]['pluralkit'] - $reqOptions = [ - 'http' => [ - 'method' => "POST", - 'header' => "Authorization: " . $app["pluralkit"][$travellingSystem === "gdapd" ? "raindrops" : "cloudburst"] . "\r\n" . - "Content-Type: application/json", - 'content' => json_encode([ - 'name' => "$member[name]-travelling", - 'display_name' => $member["display_name"], - 'color' => $member["color"], - 'birthday' => $member["birthday"], - 'created' => $member["created"], - 'pronouns' => $member["pronouns"], - 'avatar_url' => $member["avatar_url"], - 'banner' => $member["banner"], - 'description' => "**This pony is visiting this system from the " . ($system === "gdapd" ? "Raindrops System" : "Cloudburst System") . ". They are not a permanent member of this system**\n\n$member[description]", - 'proxy_tags' => array_map(function ($i) { - $i["prefix"] = "+" . $i['prefix']; - return $i; - }, $member["proxy_tags"]), - 'privacy' => $member["privacy"] - ]) - ] - ]; - - $reqContext = stream_context_create($reqOptions); - - sleep(1); - $member = json_decode(file_get_contents("https://api.pluralkit.me/v2/members", false, $reqContext), true); - - // Member exists? - if (isset($member)) { - $travelling[$id]['pluralkit'] = $member["id"]; - } - } - } - - header("Location: /-/travelling"); - file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json", utf8_encode(json_encode($travelling, JSON_PRETTY_PRINT))); - die(); -} - -require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php'; -global $travelling; - -?> - - - -
-
-
-

System travelling

- -
- "> - .png" style="width:24px;">  - - -
-
- Current system:
- - ">.png"> System - - () - -
-
- - -
- -
- - -
- - diff --git a/pages/wakeup.inc b/pages/wakeup.inc new file mode 100644 index 0000000..2438a27 --- /dev/null +++ b/pages/wakeup.inc @@ -0,0 +1,15 @@ + + +
+
+
+ +
+
+ + diff --git a/pages/wakeup.php b/pages/wakeup.php deleted file mode 100644 index c90d93e..0000000 --- a/pages/wakeup.php +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- -
-
- - -- cgit