diff --git a/files/classes/award.py b/files/classes/award.py
index 534157014..652126946 100644
--- a/files/classes/award.py
+++ b/files/classes/award.py
@@ -16,9 +16,10 @@ class AwardRelationship(Base):
user_id = Column(Integer, ForeignKey("users.id"))
submission_id = Column(Integer, ForeignKey("submissions.id"))
comment_id = Column(Integer, ForeignKey("comments.id"))
- kind = Column(String)
+ kind = Column(String, nullable=False)
awarded_utc = Column(Integer)
created_utc = Column(Integer)
+ price_paid = Column(Integer, default = 0, nullable=False)
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", back_populates="awards")
post = relationship("Submission", primaryjoin="AwardRelationship.submission_id==Submission.id", back_populates="awards")
diff --git a/files/classes/user.py b/files/classes/user.py
index 7ecb69b39..faa8af217 100644
--- a/files/classes/user.py
+++ b/files/classes/user.py
@@ -259,6 +259,10 @@ class User(Base):
if not FEATURES['HATS']:
return ''
+ if HOLIDAY_EVENT:
+ from files.events.helpers.const import EVENT_FORCED_HATS
+ if EVENT_FORCED_HATS: return random.choice(EVENT_FORCED_HATS)
+
if self.is_cakeday:
return '/i/hats/Cakeday.webp'
diff --git a/files/events/__init__.py b/files/events/__init__.py
index 10402b802..01b554aa1 100644
--- a/files/events/__init__.py
+++ b/files/events/__init__.py
@@ -1,6 +1,6 @@
from sqlalchemy import inspect
-from files.helpers.config.awards import AWARDS_ENABLED, AWARDS_DISABLED
+from files.helpers.config.awards import AWARDS, AWARDS_ENABLED, AWARDS_DISABLED
from files.__main__ import engine
from files.events.classes import *
@@ -22,6 +22,8 @@ def _populate_awards():
if award in AWARDS_DISABLED:
AWARDS_DISABLED.remove(award)
+ AWARDS.update(EVENT_AWARDS)
+
def event_init():
_build_table()
diff --git a/files/events/assets/css/banner.css b/files/events/assets/css/banner.css
new file mode 100644
index 000000000..a0b5dd73c
--- /dev/null
+++ b/files/events/assets/css/banner.css
@@ -0,0 +1,50 @@
+/* text */
+@font-face{
+ font-family: "Plakat-Fraktur";
+ src: url("/assets/fonts/event/Plakat-Fraktur-Black.woff") format("woff");
+}
+
+@media (max-width: 767.98px) {
+ #banner-title {
+ transform: scale(1.4) translate(-190px, -60px);
+ }
+}
+
+/* stars */
+.star {
+ animation: linear infinite snow;
+ animation-delay:-4s;
+}
+
+.star1 {animation-duration: 5s;}
+.star2 {animation-duration: 4.5s;}
+.star3 {animation-duration: 7s;}
+.star4 {animation-duration: 6s;}
+.star5 {animation-duration: 8s;}
+
+@media (max-width: 767.98px) {
+ .star {
+ animation: none;
+ fill-opacity: 0.5;
+ }
+ .star1 circle {
+ r: 1;
+ }
+ .star2 circle {
+ r: 1.5;
+ }
+ .star3 circle {
+ r: 2;
+ }
+ .star4 circle {
+ r: 2;
+ }
+ .star5 circle {
+ r: 2.5;
+ }
+}
+
+@keyframes snow {
+ from {transform: translateY(-60%)}
+ to {transform: translateY(60%)}
+}
diff --git a/files/events/assets/css/blizzard.css b/files/events/assets/css/blizzard.css
new file mode 100644
index 000000000..7eb017f81
--- /dev/null
+++ b/files/events/assets/css/blizzard.css
@@ -0,0 +1,571 @@
+@charset "UTF-8";
+
+/* Fonts */
+@font-face {
+ font-family: "Burbank Small Medium";
+ src: url("/assets/fonts/event/Burbank-Small-Medium.woff2") format("woff2"),
+ url("/assets/fonts/event/Burbank-Small-Medium.woff") format("woff"),
+ url("/assets/fonts/event/Burbank-Small-Medium.ttf") format("truetype");
+}
+
+:root {
+ --primary: #9b161a;
+ --secondary: #c7c7c7;
+ --dark: #c7c7c7;
+ --muted: #131512;
+ --gray: #c7c7c7;
+ --white: #131512;
+ --black: #131512;
+ --background: #c1f3ff;
+ --gray-100: #131512;
+ --gray-200: #131512;
+ --gray-400: #e6faff;
+ --gray-500: #e6faff;
+ --gray-600: #e6faff;
+ --gray-700: #e6faff;
+ --gray-800: #e6faff;
+ --gray-900: #e6faff;
+}
+
+#frontpage .posts .card, #userpage .posts .card, #search .posts .card {
+ border-color: #a7e5fb;
+}
+
+body {
+ font-family: 'Burbank Small Medium', sans-serif;
+ background-color: var(--background) !important;
+ background-image: url('/i/event/pattern.png') !important;
+ overflow-x: hidden;
+}
+
+* {
+ border-color: var(--primary);
+}
+
+.border {
+ border-color: var(--primary) !important;
+}
+
+.form-control {
+ background: transparent;
+ border-color: var(--primary) !important;
+}
+
+.btn {
+ background: var(--primary) !important;
+ border-color: var(--primary) !important;
+ border-width: 2px;
+ color: #fff !important;
+}
+
+.btn .fas {
+ color: #fff !important;
+}
+
+.form-control:disabled, .form-control[readonly] {
+ background: transparent;
+ border-color: var(--primary) !important;
+}
+
+.btn-success {
+ border-color: #38A169 !important;
+}
+
+.btn-danger {
+ border-color: #E53E3E !important;
+}
+
+#frontpage .pseudo-submit-form.card .card-body .form-control {
+border-color: transparent !important;
+}
+
+.btn-lg {
+ border-color: transparent !important;
+}
+
+pre {
+ color: #CFCFCF;
+}
+
+.transparent {
+ background: None !important;
+}
+
+#frontpage .post-title a:visited {
+color: #7a7a7a !important;
+}
+
+.post-title a, h1.post-title {
+ font-family: 'Burbank Small Medium', cursive;
+ font-size: 1.25rem;
+}
+
+.arrow-up::before, .arrow-down::before {
+ content: '\f7dc';
+ width: 20px;
+}
+
+.arrow-down::before {
+ display: inline-block;
+ transform: rotate(180deg);
+}
+
+.arrow-up.active::before, .arrow-down.active::before {
+ content: '\f7db';
+}
+
+.comment {
+ background-color: var(--gray-600);
+}
+
+.comment-actions .btn {
+ background-color: transparent !important;
+ color: var(--gray-200) !important;
+}
+
+.comment-actions .fas {
+ color: var(--gray-200) !important;
+}
+
+.comment-actions .btn::after{
+ background: none !important;
+}
+
+#thread .card {
+ padding: 0.5rem;
+}
+
+body {
+ cursor: url(/assets/images/event/cursor.png?v=1), auto !important;
+}
+
+textarea, input[type=textbox], input[type=search] {
+ cursor: url(/assets/images/event/text.png?v=1), auto !important;
+}
+
+.btn, input[type=button], button, a, img {
+ cursor: url(/assets/images/event/pointer.png?v=1), auto !important;
+}
+
+.fa-moon-over-sun:before{content:"\f74a"}
+.fa-temperature-snow:before{content:"\f768"}
+
+.award-name {
+ color: var(--gray-200)
+}
+
+.sidebar {
+ background-color: var(--gray-600);
+}
+
+.form-control {
+ background: var(--gray-600);
+}
+
+/* lights */
+
+.navbar::after, .lights::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 57px;
+ width: 100%;
+ background: url('/i/event/lights.png?v=1');
+ animation: lights 1s infinite steps(2);
+ pointer-events: none;
+ }
+
+ @keyframes lights {
+ 0% {
+ /*Two zeros, not one !!*/
+ /*[0] is equivalent to [0 50%] and will create a different animation */
+ background-position: 0 0;
+ }
+ 100% {
+ background-position: 0 -138px;
+ }
+ }
+
+/* snowcaps */
+
+.btn, .snow-cap {
+ position: relative;
+}
+
+.btn::after, .snow-cap::after {
+ content: '';
+ pointer-events: none;
+ background: url("/i/event/snowcap.png?v=1") repeat-x;
+ background-size: contain;
+ position: absolute;
+ bottom: -18px;
+ left: 0;
+ right: 0;
+ height: 23px;
+ border: none;
+ border-radius: 9999px;
+ }
+
+/* snow effect */
+
+body {
+ background-color: #1f1f1f;
+ background-blend-mode: soft-light;
+}
+
+ .color {
+ width: 20%;
+ height: 100%;
+ float: left
+ }
+
+ .color p {
+ position: relative;
+ z-index: 1231231;
+ text-align: center;
+ line-height: 90vh;
+ }
+
+ .color:nth-child(1){
+ background-color: #F5624D;
+ }
+
+ .color:nth-child(2){
+ background-color: #CC231E;
+ }
+
+ .color:nth-child(3){
+ background-color: #34A65F;
+ }
+
+ .color:nth-child(4){
+ background-color: #0F8A5F;
+ }
+
+ .color:nth-child(5){
+ background-color: #235E6F;
+ }
+
+ #snow {
+ height: 100%;
+ color: #FFF;
+ display: block;
+ }
+
+/* candy cane */
+.candy-cane {
+ height: 125px;
+ width: 125px;
+ position: fixed;
+ right: 0;
+ bottom: -9px;
+ transform: rotate(15deg);
+ transition: 200ms ease-out;
+ background-image: url("/i/event/candy-cane.svg");
+ background-repeat: no-repeat;
+ background-size: contain;
+ }
+
+ .candy-cane:hover {
+ transform: translateY(4px) rotate(17deg);
+ }
+
+ .candy-cane::before {
+ content: '';
+ width: 4px;
+ height: 80%;
+ background-color: rgba(255,255,255,0.7);
+ display: block;
+ position: absolute;
+ right: 39px;
+ bottom: 0;
+ border-radius: 9999px;
+ }
+
+/*sign */
+#sign {
+ position: fixed;
+ bottom: -0.75rem;
+ left: 1.5rem;
+ transform: rotate(-3deg);
+ pointer-events: none;
+
+}
+
+/* Need to account for small screens */
+@media screen and (min-height: 800px) {
+ #sign {
+ z-index: 999999;
+ }
+}
+
+#sign > img {
+ width: 156px;
+}
+#sign > ul {
+ position: absolute;
+ top: 4px;
+ left: 20px;
+ list-style: none;
+ display: flex;
+ gap: 4px;
+}
+#sign > ul li {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #FFFFFF;
+ font-size: 28px;
+ font-weight: bold;
+ transform: rotate(6deg);
+}
+#sign > ul li:nth-child(1) {
+ transform: rotate(-4deg);
+}
+
+.sign.snow-cap::after {
+ top: -6px;
+ left: 2px;
+ width: 97%;
+ height: 17px;
+}
+
+/* awards */
+
+/* gingerbread */
+.fall-snowflake {
+ color: #fff;
+ font-size: 1em;
+ font-family: Serif;
+ text-shadow: 0 0 1px #000;
+ pointer-events: none;
+}
+
+@-webkit-keyframes fall-snowflakes-fall {
+ 0% {
+ top: -20%
+ }
+ 100% {
+ top: 100%
+ }
+}
+
+@-webkit-keyframes fall-snowflakes-shake {
+ 0% {
+ -webkit-transform: translateX(0px);
+ transform: translateX(0px)
+ }
+ 50% {
+ -webkit-transform: translateX(80px);
+ transform: translateX(80px)
+ }
+ 100% {
+ -webkit-transform: translateX(0px) rotate(360deg);
+ transform: translateX(0px) rotate(360deg);
+ }
+}
+
+@keyframes fall-snowflakes-fall {
+ 0% {
+ top: -20%
+ }
+ 100% {
+ top: 100%
+ }
+}
+
+@keyframes fall-snowflakes-shake {
+ 0% {
+ transform: translateX(0px)
+ }
+ 50% {
+ transform: translateX(80px)
+ }
+ 100% {
+ transform: translateX(0px) rotate(360deg);
+ }
+}
+
+.fall-snowflake {
+ position: fixed;
+ top: -20%;
+ z-index: 9999;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+ -webkit-animation-name: fall-snowflakes-fall, fall-snowflakes-shake;
+ -webkit-animation-duration: 10s, 4s;
+ -webkit-animation-timing-function: linear, ease-in-out;
+ -webkit-animation-iteration-count: infinite, infinite;
+ -webkit-animation-play-state: running, running;
+ animation-name: fall-snowflakes-fall, fall-snowflakes-shake;
+ animation-duration: 10s, 4s;
+ animation-timing-function: linear, ease-in-out;
+ animation-iteration-count: infinite, infinite;
+ animation-play-state: running, running
+}
+
+.fall-snowflake:nth-of-type(0) {
+ left: 1%;
+ -webkit-animation-delay: 0s, 0s;
+ animation-delay: 0s, 0s
+}
+.fall-snowflake:nth-of-type(1) {
+ left: 10%;
+ -webkit-animation-delay: 1s, 1s;
+ animation-delay: 1s, 1s
+}
+.fall-snowflake:nth-of-type(2) {
+ left: 20%;
+ -webkit-animation-delay: 6s, .5s;
+ animation-delay: 6s, .5s
+}
+.fall-snowflake:nth-of-type(3) {
+ left: 30%;
+ -webkit-animation-delay: 4s, 2s;
+ animation-delay: 4s, 2s
+}
+.fall-snowflake:nth-of-type(4) {
+ left: 40%;
+ -webkit-animation-delay: 2s, 2s;
+ animation-delay: 2s, 2s
+}
+.fall-snowflake:nth-of-type(5) {
+ left: 50%;
+ -webkit-animation-delay: 8s, 3s;
+ animation-delay: 8s, 3s
+}
+.fall-snowflake:nth-of-type(6) {
+ left: 60%;
+ -webkit-animation-delay: 6s, 2s;
+ animation-delay: 6s, 2s
+}
+.fall-snowflake:nth-of-type(7) {
+ left: 70%;
+ -webkit-animation-delay: 2.5s, 1s;
+ animation-delay: 2.5s, 1s
+}
+.fall-snowflake:nth-of-type(8) {
+ left: 80%;
+ -webkit-animation-delay: 1s, 0s;
+ animation-delay: 1s, 0s
+}
+.fall-snowflake:nth-of-type(9) {
+ left: 90%;
+ -webkit-animation-delay: 3s, 1.5s;
+ animation delay: 3s, 1.5s
+}
+.fall-snowflake:nth-of-type(10) {
+ left: 100%;
+ -webkit-animation-delay: 3s, 2s;
+ animation-delay: 3s, 2s
+}
+.fall-snowflake:nth-of-type(11) {
+ left: 5%;
+ -webkit-animation-delay: 1s, 4s;
+ animation-delay: 1s, 4s
+}
+.fall-snowflake:nth-of-type(12) {
+ left: 15%;
+ -webkit-animation-delay: 1s, 1.5s;
+ animation-delay: 1s, 1.5s
+}
+.fall-snowflake:nth-of-type(13) {
+ left: 25%;
+ -webkit-animation-delay: 6s, 2.5s;
+ animation-delay: 6s, 2.5s
+}
+.fall-snowflake:nth-of-type(14) {
+ left: 35%;
+ -webkit-animation-delay: 4s, 1s;
+ animation-delay: 4s, 1s
+}
+.fall-snowflake:nth-of-type(15) {
+ left: 45%;
+ -webkit-animation-delay: 2s, 4s;
+ animation-delay: 2s, 4s
+}
+.fall-snowflake:nth-of-type(16) {
+ left: 55%;
+ -webkit-animation-delay: 8s, 3s;
+ animation-delay: 8s, 3s
+}
+.fall-snowflake:nth-of-type(17) {
+ left: 65%;
+ -webkit-animation-delay: 6s, 3s;
+ animation-delay: 6s, 3s
+}
+.fall-snowflake:nth-of-type(18) {
+ left: 75%;
+ -webkit-animation-delay: 2.5s, 4s;
+ animation-delay: 2.5s, 4s
+}
+.fall-snowflake:nth-of-type(19) {
+ left: 85%;
+ -webkit-animation-delay: 2s, 0s;
+ animation-delay: 2s, 0s
+}
+.fall-snowflake:nth-of-type(20) {
+ left: 95%;
+ -webkit-animation-delay: 3s, 1.5s;
+ animation delay: 3s, 1.5s
+}
+
+.animate-spin {
+ animation: spin 5600ms linear infinite;
+}
+
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+/* vvv kill yourself vscodelet vvv */
+/* */
+
+/* Change mobile navbar icon colors to basketball */
+#mobile-bottom-navigation-bar i {
+ color: var(--gray-200)!important;
+}
+
+#mobile-bottom-navigation-bar {
+ box-shadow: 0px 2px 5px #000000cc;
+ /* wtf??? */
+ z-index:9999999 !important;
+}
+
+/* Revert the snowcaps on it, is bad */
+#mobile-bottom-navigation-bar button:after {
+ background: unset;
+ /* Real work, lol */
+ display: none;
+}
+
+@media (max-width: 767.98px) {
+ .candy-cane, .sign {
+ bottom: 0.9rem !important;
+ }
+}
+
+/*footer*/
+footer::after {
+ content: "";
+ display: block;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ height: 320px;
+ width: 100%;
+ background-image: url("/i/event/footer.svg");
+ background-size: cover;
+ background-repeat: no-repeat;
+ pointer-events: none;
+ z-index: -1;
+}
diff --git a/files/events/assets/css/spooky.css b/files/events/assets/css/spooky.css
deleted file mode 100644
index e69de29bb..000000000
diff --git a/files/events/assets/css/themes/dark.css b/files/events/assets/css/themes/dark.css
new file mode 100644
index 000000000..2d4f8b945
--- /dev/null
+++ b/files/events/assets/css/themes/dark.css
@@ -0,0 +1,22 @@
+:root {
+ --primary: #9b161a;
+ --secondary: #101819;
+ --dark: #101819;
+ --muted: #e6faff;
+ --gray: #101819;
+ --white: #e6faff;
+ --black: #e6faff;
+ --background: #101819;
+ --gray-100: #e6faff;
+ --gray-200: #e6faff;
+ --gray-400: #101819;
+ --gray-500: #101819;
+ --gray-600: #101819;
+ --gray-700: #101819;
+ --gray-800: #101819;
+ --gray-900: #101819;
+}
+
+/*#banner-skybox {
+ fill: url(#skybox-gradient-night);
+}*/
diff --git a/files/events/assets/css/themes/light.css b/files/events/assets/css/themes/light.css
new file mode 100644
index 000000000..9d6f459ad
--- /dev/null
+++ b/files/events/assets/css/themes/light.css
@@ -0,0 +1 @@
+/**/
diff --git a/files/events/assets/fonts/Burbank-Small-Medium.eot b/files/events/assets/fonts/Burbank-Small-Medium.eot
new file mode 100644
index 000000000..d4c878bc5
Binary files /dev/null and b/files/events/assets/fonts/Burbank-Small-Medium.eot differ
diff --git a/files/events/assets/fonts/Burbank-Small-Medium.ttf b/files/events/assets/fonts/Burbank-Small-Medium.ttf
new file mode 100644
index 000000000..adf20980e
Binary files /dev/null and b/files/events/assets/fonts/Burbank-Small-Medium.ttf differ
diff --git a/files/events/assets/fonts/Burbank-Small-Medium.woff2 b/files/events/assets/fonts/Burbank-Small-Medium.woff2
new file mode 100644
index 000000000..bc81bfbb9
Binary files /dev/null and b/files/events/assets/fonts/Burbank-Small-Medium.woff2 differ
diff --git a/files/events/assets/fonts/GermaniaOne-Regular.woff b/files/events/assets/fonts/GermaniaOne-Regular.woff
new file mode 100644
index 000000000..721f40cd6
Binary files /dev/null and b/files/events/assets/fonts/GermaniaOne-Regular.woff differ
diff --git a/files/events/assets/fonts/Plakat-Fraktur-Black.woff b/files/events/assets/fonts/Plakat-Fraktur-Black.woff
new file mode 100644
index 000000000..0dddbd242
Binary files /dev/null and b/files/events/assets/fonts/Plakat-Fraktur-Black.woff differ
diff --git a/files/events/assets/images/awards/gingerbread.png b/files/events/assets/images/awards/gingerbread.png
new file mode 100644
index 000000000..a78c11205
Binary files /dev/null and b/files/events/assets/images/awards/gingerbread.png differ
diff --git a/files/events/assets/images/banner_new.webp b/files/events/assets/images/banner_new.webp
new file mode 100755
index 000000000..249810a26
Binary files /dev/null and b/files/events/assets/images/banner_new.webp differ
diff --git a/files/events/assets/images/candy-cane.svg b/files/events/assets/images/candy-cane.svg
new file mode 100644
index 000000000..cd75556f1
--- /dev/null
+++ b/files/events/assets/images/candy-cane.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/files/events/assets/images/cursor.png b/files/events/assets/images/cursor.png
new file mode 100644
index 000000000..8ced5683d
Binary files /dev/null and b/files/events/assets/images/cursor.png differ
diff --git a/files/events/assets/images/footer.svg b/files/events/assets/images/footer.svg
new file mode 100644
index 000000000..b8c34ff2b
--- /dev/null
+++ b/files/events/assets/images/footer.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/files/events/assets/images/hats/1.png b/files/events/assets/images/hats/1.png
new file mode 100644
index 000000000..f3a898519
Binary files /dev/null and b/files/events/assets/images/hats/1.png differ
diff --git a/files/events/assets/images/hats/2.png b/files/events/assets/images/hats/2.png
new file mode 100644
index 000000000..eda869f61
Binary files /dev/null and b/files/events/assets/images/hats/2.png differ
diff --git a/files/events/assets/images/hats/3.png b/files/events/assets/images/hats/3.png
new file mode 100644
index 000000000..3da243231
Binary files /dev/null and b/files/events/assets/images/hats/3.png differ
diff --git a/files/events/assets/images/icon/marseychristmaself2.webp b/files/events/assets/images/icon/marseychristmaself2.webp
new file mode 100644
index 000000000..8e84e15c6
Binary files /dev/null and b/files/events/assets/images/icon/marseychristmaself2.webp differ
diff --git a/files/events/assets/images/icon/marseypartyxmas.webp b/files/events/assets/images/icon/marseypartyxmas.webp
new file mode 100644
index 000000000..c5b091640
Binary files /dev/null and b/files/events/assets/images/icon/marseypartyxmas.webp differ
diff --git a/files/events/assets/images/icon/marseysanta3.webp b/files/events/assets/images/icon/marseysanta3.webp
new file mode 100644
index 000000000..41d2f833c
Binary files /dev/null and b/files/events/assets/images/icon/marseysanta3.webp differ
diff --git a/files/events/assets/images/icon/marseysnowman.webp b/files/events/assets/images/icon/marseysnowman.webp
new file mode 100644
index 000000000..ffc27bf56
Binary files /dev/null and b/files/events/assets/images/icon/marseysnowman.webp differ
diff --git a/files/events/assets/images/lights.png b/files/events/assets/images/lights.png
new file mode 100644
index 000000000..78c04e0a8
Binary files /dev/null and b/files/events/assets/images/lights.png differ
diff --git a/files/events/assets/images/pattern.png b/files/events/assets/images/pattern.png
new file mode 100644
index 000000000..824ab1c8c
Binary files /dev/null and b/files/events/assets/images/pattern.png differ
diff --git a/files/events/assets/images/pointer.png b/files/events/assets/images/pointer.png
new file mode 100644
index 000000000..8d6bb6aab
Binary files /dev/null and b/files/events/assets/images/pointer.png differ
diff --git a/files/events/assets/images/sidebar/1.webp b/files/events/assets/images/sidebar/1.webp
deleted file mode 100644
index 9066f22a3..000000000
Binary files a/files/events/assets/images/sidebar/1.webp and /dev/null differ
diff --git a/files/events/assets/images/sidebar/2.webp b/files/events/assets/images/sidebar/2.webp
new file mode 100644
index 000000000..c3b95aa45
Binary files /dev/null and b/files/events/assets/images/sidebar/2.webp differ
diff --git a/files/events/assets/images/sign.svg b/files/events/assets/images/sign.svg
new file mode 100644
index 000000000..da47389ec
--- /dev/null
+++ b/files/events/assets/images/sign.svg
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/files/events/assets/images/snowcap.png b/files/events/assets/images/snowcap.png
new file mode 100644
index 000000000..58758b06e
Binary files /dev/null and b/files/events/assets/images/snowcap.png differ
diff --git a/files/events/assets/images/snowflake.png b/files/events/assets/images/snowflake.png
new file mode 100644
index 000000000..c91a45185
Binary files /dev/null and b/files/events/assets/images/snowflake.png differ
diff --git a/files/events/assets/images/snowman.png b/files/events/assets/images/snowman.png
new file mode 100644
index 000000000..ac0e2965f
Binary files /dev/null and b/files/events/assets/images/snowman.png differ
diff --git a/files/events/assets/images/text.png b/files/events/assets/images/text.png
new file mode 100644
index 000000000..1ec8be573
Binary files /dev/null and b/files/events/assets/images/text.png differ
diff --git a/files/events/assets/js/darkmode.js b/files/events/assets/js/darkmode.js
new file mode 100644
index 000000000..217c9d08a
--- /dev/null
+++ b/files/events/assets/js/darkmode.js
@@ -0,0 +1,19 @@
+function postToastRoastEventDarkmode(t, url) {
+ const xhr = createXhrWithFormKey(url);
+ xhr[0].onload = function() {
+ postToastLoadEventDarkmode(xhr[0])
+ };
+ xhr[0].send(xhr[1]);
+}
+
+function postToastLoadEventDarkmode(xhr) {
+ let data
+ try {
+ data = JSON.parse(xhr.response)
+ }
+ catch (e) {
+ console.log(e)
+ }
+ success = xhr.status >= 200 && xhr.status < 300;
+ showToast(success, getMessageFromJsonData(success, data));
+}
diff --git a/files/events/assets/js/neko.js b/files/events/assets/js/neko.js
new file mode 100644
index 000000000..f0376f671
--- /dev/null
+++ b/files/events/assets/js/neko.js
@@ -0,0 +1,35 @@
+// NEKO FOR JAVASCRIPT
+// THIS SCRIPT CODE IS (C) 2004 GREGORY BELL, ALL RIGHTS RESERVED.
+// ANYONE IS GRANTED THE RIGHT TO EXECUTE THIS PROGRAM BY LINKING TO IT
+// IN THEIR WEB PAGE.
+//
+// THIS RIGHT DOES NOT EXTEND TO TAKING THE CODE AND HOSTING IT ON A DIFFERENT
+// SERVER.
+//
+// I WORKED HARD TO MAKE THIS AND WOULD LIKE TO KEEP IT, SO PLEASE HAVE FUN
+// BUT DON'T STEAL IT!
+//
+// THANK YOU
+//
+//⠀⠀⠘⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡜⠀⠀⠀
+//⠀⠀⠀⠑⡀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡔⠁⠀⠀⠀
+//⠀⠀⠀⠀⠈⠢⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠴⠊⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⢀⣀⣀⣀⣀⣀⡀⠤⠄⠒⠈⠀⠀⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⠘⣀⠄⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠔⠒⠒⠒⠒⠒⠢⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⡰⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⢄⡀⠀⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⡸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠙⠄⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⢀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠀⢠⠂⠀⠀⠘⡄⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠈⢤⡀⢂⠀⢨⠀⢀⡠⠈⢣⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⢀⢀⡖⠒⠶⠤⠭⢽⣟⣗⠲⠖⠺⣖⣴⣆⡤⠤⠤⠼⡄⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠘⡈⠃⠀⠀⠀⠘⣺⡟⢻⠻⡆⠀⡏⠀⡸⣿⢿⢞⠄⡇⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⢣⡀⠤⡀⡀⡔⠉⣏⡿⠛⠓⠊⠁⠀⢎⠛⡗⡗⢳⡏⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⢱⠀⠨⡇⠃⠀⢻⠁⡔⢡⠒⢀⠀⠀⡅⢹⣿⢨⠇⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⢸⠀⠠⢼⠀⠀⡎⡜⠒⢀⠭⡖⡤⢭⣱⢸⢙⠆⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⠀⡸⠀⠀⠸⢁⡀⠿⠈⠂⣿⣿⣿⣿⣿⡏⡍⡏⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⠸⢢⣫⢀⠘⣿⣿⡿⠏⣼⡏⠀⠀⠀⠀⠀⠀⠀
+//⠀⠀⠀⠀⣀⣠⠊⠀⣀⠎⠁⠀⠀⠀⠙⠳⢴⡦⡴⢶⣞⣁⣀⣀⡀⠀⠀⠀⠀⠀
+//⠀⠐⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⢀⠤⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀
+//
+
+function gE(e,i){if(l){var o=(i=i||self).document.layers;if(o[e])return o[e];for(var s=0;s ',Y=d.createElement("DIV"),Y?(Y.innerHTML=X,d.body.appendChild(Y)):void 0!==d.body.insertAdjacentHTML&&d.body.insertAdjacentHTML("BeforeEnd",X))}function byName(e,t){for(var i=0;i ";this.layer=createLayer(strLayer,x,y,32,32,strContent),this.layer.Neko=this,this.homeX=this.layer.myx,this.homeY=this.layer.myy,this.doc=this.layer.document,this.doc||(this.doc=document),this.image=byName(this.doc.images,strImage),this.image.Neko=this,window.delay&&window.delay>0?this.delay=window.delay+Math.floor(nDelayVariance*Math.random()-5):this.delay=250+Math.floor(nDelayVariance*Math.random()-5),this.delayMultiplier=1,window.stepsize&&window.stepsize>0?this.stepsize=window.stepsize:this.stepsize=16,active||(active=!1),this.active=active,this.SetBehavior("resting"),this.frame=nFirstRealFrame,this.direction="",this.looseDirection="",this.endx=0,this.endy,this.distx,this.disty,this.steps,this.caught=!0,this.dx,this.dy,this.boardX=-1,this.boardY=-1,this.eccX=Math.floor(checkerboardEccentricity*Math.random()-checkerboardEccentricity/2),this.eccY=Math.floor(checkerboardEccentricity*Math.random()-checkerboardEccentricity/2),this.Think()}function NekoMessage(){var e=this.caught?sNekoMessageCaught:sNekoMessage;window.status=e}function NekoTargetMouse(){var e=mouse.x+4,t=mouse.y-20;this.endx=e,this.endy=t,box.setBoard(this.whichNeko,this.endx,this.endy)}function NekoShow(){sE(this.layer)}function NekoHide(){hE(this.layer)}function NekoTargetHome(){this.endx=this.homeX,this.endy=this.homeY}function NekoCalculateDistance(){this.distx=this.endx-this.layer.myx,this.disty=this.endy-this.layer.myy,this.steps=Math.sqrt(Math.pow(this.distx,2)+Math.pow(this.disty,2))/this.stepsize,this.steps>=1?(this.caught&&eval(this.onUnCaught),this.caught=!1):(this.caught||eval(this.onCaught),this.caught=!0),this.dx=this.distx/this.steps,this.dy=this.disty/this.steps}function NekoSetBehavior(strNewBehavior){this.behavior=strNewBehavior,this.frame=nFirstRealFrame;var paImages=eval("aNekos["+this.whichNeko+"].a_"+this.behavior);this.onCaught=paImages[0],this.onUnCaught=paImages[1],this.onLoopEnd=paImages[2],this.loopTimes=paImages[3],this.delayMultiplier=paImages[4]}function NekoUpdateImage(){var paImages=eval("aNekos["+this.whichNeko+"].a_"+this.behavior);if(this.frame>=paImages.length)if(this.behaviorRepetition++,0!=this.loopTimes&&this.behaviorRepetition>=this.loopTimes){this.behaviorRepetition=0,eval(this.onLoopEnd);var paImages=eval("aNekos["+this.whichNeko+"].a_"+this.behavior)}else this.frame=nFirstRealFrame;if(this.aGifs[this.direction+paImages[this.frame]]){var strImage=this.aGifs[this.direction+paImages[this.frame]].src;this.image.src=strImage}else if(this.aGifs[paImages[this.frame]]){var strImage=this.aGifs[paImages[this.frame]].src;this.image.src=strImage}else if(this.looseDirection+this.aGifs[paImages[this.frame]]){var strImage=this.aGifs[this.looseDirection+paImages[this.frame]].src;this.image.src=strImage}else this.image.src=this.aGifs.alert.src;this.frame++}function NekoMoveAStep(){this.steps>=1?(this.layer.myx+=this.dx,this.layer.myy+=this.dy):(this.layer.myx=this.endx,this.layer.myy=this.endy),box.checkBoard(this.whichNeko,this.layer.myx,this.layer.myy)&&(this.layer.myx+=this.eccX,this.layer.myy+=this.eccY),sX(this.layer,this.layer.myx),sY(this.layer,this.layer.myy),box.setBoard(this.whichNeko,this.layer.myx,this.layer.myy)}function NekoFindDirection(){if(0!=t||0!=e){var e=-1*this.dy,t=this.dx,i=Math.abs(t),o="",s="",a=Math.abs(e)/i,r=a<.41421,h=a>2.4142;e>0?r||(o="n"):r||(o="s"),t>0?h||(s="e"):h||(s="w"),this.looseDirection=""!=s?s:o,this.direction=o+s}else this.direction=""}function NekoThink(){this.active?this.TargetMouse():this.TargetHome(),this.CalculateDistance(),this.FindDirection(),this.UpdateImage(),"chasing"==this.behavior&&this.MoveAStep();var e=Math.floor(this.delay*this.delayMultiplier);setTimeout("aNekos["+this.whichNeko+"].Think()",e)}function nekoChooseIdle(){var e=new Array("resting","yawning","itching","scratching"),t=Math.floor(Math.random()*e.length);this.SetBehavior(e[t])}function startANeko(){var e=0,t=0;window.startNekoX&&(e=window.startNekoX),window.startNekoY&&(t=window.startNekoY),parseInt(e)!=e&&(window.onresize=function(){for(var e=0;et&&(e=t),e}function boxBoundHeight(e){0==e||e||(e=this.height());var t=this.height()-12;return e<20&&(e=20),e>t&&(e=t),e}function boxSetBoard(e,t,i){var o=Math.floor(t/this.width()*checkerboardScale),s=Math.floor(i/this.height()*checkerboardScale);o<0&&(o=0),o>=checkerboardScale&&(o=checkerboardScale-1),s<0&&(s=0),s>=checkerboardScale&&(s=checkerboardScale-1);var a=aNekos[e];return a.boardX==o&&a.boardY==s||(-1!=a.boardX&&checkerboard[a.boardX][a.boardY]--,checkerboard[o][s]++,a.boardX=o,a.boardY=s),0==checkerboard[o][s]?0:checkerboard[o][s]-1}function boxCheckBoard(e,t,i){var o=Math.floor(t/this.width()*checkerboardScale),s=Math.floor(i/this.height()*checkerboardScale);o<0&&(o=0),o>=checkerboardScale&&(o=checkerboardScale-1),s<0&&(s=0),s>=checkerboardScale&&(s=checkerboardScale-1);var a=aNekos[e],r=0;return a.boardX==o&&a.boardY==s&&(r=1),checkerboard[o][s]-r}d=document,l=d.layers,op=-1!=navigator.userAgent.indexOf("Opera"),px="px",document.write('');var checkerboardEccentricity=10,checkerboardScale=20,nDelayVariance=20,nFirstRealFrame=5,sNekoMessage="Click Neko and he'll chase your mouse!",sNekoMessageCaught=sNekoMessage,aNekos=new Array;Neko.prototype.message=NekoMessage,Neko.prototype.TargetMouse=NekoTargetMouse,Neko.prototype.Show=NekoShow,Neko.prototype.Hide=NekoHide,Neko.prototype.TargetHome=NekoTargetHome,Neko.prototype.CalculateDistance=NekoCalculateDistance,Neko.prototype.SetBehavior=NekoSetBehavior,Neko.prototype.UpdateImage=NekoUpdateImage,Neko.prototype.MoveAStep=NekoMoveAStep,Neko.prototype.FindDirection=NekoFindDirection,Neko.prototype.Think=NekoThink,Neko.prototype.chooseIdle=nekoChooseIdle,window.onloadOriginal=new Function,window.onload&&(window.onloadOriginal=window.onload),window.NekoNoDefault||(window.onload=startANeko),mouse=new mouse,box.prototype.boundWidth=boxBoundWidth,box.prototype.boundHeight=boxBoundHeight,box.prototype.setBoard=boxSetBoard,box.prototype.checkBoard=boxCheckBoard,box=new box,document.onmousemove=function(e){var t=e?e.pageX:event.x+document.body.scrollLeft,i=e?e.pageY:event.y+document.body.scrollTop;mouse.x=box.boundWidth(t),mouse.y=box.boundHeight(i)},document.captureEvents&&document.captureEvents(Event.MOUSEMOVE);for(var checkerboard=new Array(checkerboardScale),i=0;i 3) {
+ args.pop(); // no capture
+ }
+ } else if (len === 3) {
+ args.push(false);
+ }
+ return args;
+ }
+
+ function apply(args, sType) {
+ var element = args.shift(),
+ method = [evt[sType]];
+ if (old) {
+ element[method](args[0], args[1]);
+ } else {
+ element[method].apply(element, args);
+ }
+ }
+
+ function addEvent() {
+ apply(getArgs(arguments), "add");
+ }
+
+ function removeEvent() {
+ apply(getArgs(arguments), "remove");
+ }
+
+ return {
+ add: addEvent,
+ remove: removeEvent
+ };
+ })();
+
+ function rnd(n, min) {
+ if (isNaN(min)) {
+ min = 0;
+ }
+ return Math.random() * n + min;
+ }
+
+ function plusMinus(n) {
+ return parseInt(rnd(2), 10) === 1 ? n * -1 : n;
+ }
+
+ this.randomizeWind = function () {
+ var i;
+ vRndX = plusMinus(rnd(storm.vMaxX, 0.2));
+ vRndY = rnd(storm.vMaxY, 0.2);
+ if (this.flakes) {
+ for (i = 0; i < this.flakes.length; i++) {
+ if (this.flakes[i].active) {
+ this.flakes[i].setVelocities();
+ }
+ }
+ }
+ };
+
+ this.scrollHandler = function () {
+ var i;
+ // "attach" snowflakes to bottom of window if no absolute bottom value was given
+ scrollY = storm.flakeBottom
+ ? 0
+ : parseInt(
+ window.scrollY ||
+ document.documentElement.scrollTop ||
+ (noFixed ? document.body.scrollTop : 0),
+ 10
+ );
+ if (isNaN(scrollY)) {
+ scrollY = 0; // Netscape 6 scroll fix
+ }
+ if (!fixedForEverything && !storm.flakeBottom && storm.flakes) {
+ for (i = 0; i < storm.flakes.length; i++) {
+ if (storm.flakes[i].active === 0) {
+ storm.flakes[i].stick();
+ }
+ }
+ }
+ };
+
+ this.resizeHandler = function () {
+ if (window.innerWidth || window.innerHeight) {
+ screenX = window.innerWidth - 16 - storm.flakeRightOffset;
+ screenY = storm.flakeBottom || window.innerHeight;
+ } else {
+ screenX =
+ (document.documentElement.clientWidth ||
+ document.body.clientWidth ||
+ document.body.scrollWidth) -
+ (!isIE ? 8 : 0) -
+ storm.flakeRightOffset;
+ screenY =
+ storm.flakeBottom ||
+ document.documentElement.clientHeight ||
+ document.body.clientHeight ||
+ document.body.scrollHeight;
+ }
+ docHeight = document.body.offsetHeight;
+ screenX2 = parseInt(screenX / 2, 10);
+ };
+
+ this.resizeHandlerAlt = function () {
+ screenX = storm.targetElement.offsetWidth - storm.flakeRightOffset;
+ screenY = storm.flakeBottom || storm.targetElement.offsetHeight;
+ screenX2 = parseInt(screenX / 2, 10);
+ docHeight = document.body.offsetHeight;
+ };
+
+ this.freeze = function () {
+ // pause animation
+ if (!storm.disabled) {
+ storm.disabled = 1;
+ } else {
+ return false;
+ }
+ storm.timer = null;
+ };
+
+ this.resume = function () {
+ if (storm.disabled) {
+ storm.disabled = 0;
+ } else {
+ return false;
+ }
+ storm.timerInit();
+ };
+
+ this.toggleSnow = function () {
+ if (!storm.flakes.length) {
+ // first run
+ storm.start();
+ } else {
+ storm.active = !storm.active;
+ if (storm.active) {
+ storm.show();
+ storm.resume();
+ } else {
+ storm.stop();
+ storm.freeze();
+ }
+ }
+ };
+
+ this.stop = function () {
+ var i;
+ this.freeze();
+ for (i = 0; i < this.flakes.length; i++) {
+ this.flakes[i].o.style.display = "none";
+ }
+ storm.events.remove(window, "scroll", storm.scrollHandler);
+ storm.events.remove(window, "resize", storm.resizeHandler);
+ if (storm.freezeOnBlur) {
+ if (isIE) {
+ storm.events.remove(document, "focusout", storm.freeze);
+ storm.events.remove(document, "focusin", storm.resume);
+ } else {
+ storm.events.remove(window, "blur", storm.freeze);
+ storm.events.remove(window, "focus", storm.resume);
+ }
+ }
+ };
+
+ this.show = function () {
+ var i;
+ for (i = 0; i < this.flakes.length; i++) {
+ this.flakes[i].o.style.display = "block";
+ }
+ };
+
+ this.SnowFlake = function (type, x, y) {
+ var s = this;
+ this.type = type;
+ this.x = x || parseInt(rnd(screenX - 20), 10);
+ this.y = !isNaN(y) ? y : -rnd(screenY) - 12;
+ this.vX = null;
+ this.vY = null;
+ this.vAmpTypes = [1, 1.2, 1.4, 1.6, 1.8]; // "amplification" for vX/vY (based on flake size/type)
+ this.vAmp = this.vAmpTypes[this.type] || 1;
+ this.melting = false;
+ this.meltFrameCount = storm.meltFrameCount;
+ this.meltFrames = storm.meltFrames;
+ this.meltFrame = 0;
+ this.twinkleFrame = 0;
+ this.active = 1;
+ this.fontSize = 10 + (this.type / 5) * 10;
+ this.o = document.createElement("div");
+ this.o.innerHTML = storm.snowCharacter;
+ if (storm.className) {
+ this.o.setAttribute("class", storm.className);
+ }
+ this.o.style.color = storm.snowColor;
+ this.o.style.position = fixedForEverything ? "fixed" : "absolute";
+ if (storm.useGPU && features.transform.prop) {
+ // GPU-accelerated snow.
+ this.o.style[features.transform.prop] = "translate3d(0px, 0px, 0px)";
+ }
+ this.o.style.width = storm.flakeWidth + "px";
+ this.o.style.height = storm.flakeHeight + "px";
+ this.o.style.fontFamily = "arial,verdana";
+ this.o.style.cursor = "default";
+ this.o.style.overflow = "hidden";
+ this.o.style.fontWeight = "normal";
+ this.o.style.zIndex = storm.zIndex;
+ docFrag.appendChild(this.o);
+
+ this.refresh = function () {
+ if (isNaN(s.x) || isNaN(s.y)) {
+ // safety check
+ return false;
+ }
+ storm.setXY(s.o, s.x, s.y);
+ };
+
+ this.stick = function () {
+ if (
+ noFixed ||
+ (storm.targetElement !== document.documentElement &&
+ storm.targetElement !== document.body)
+ ) {
+ s.o.style.top = screenY + scrollY - storm.flakeHeight + "px";
+ } else if (storm.flakeBottom) {
+ s.o.style.top = storm.flakeBottom + "px";
+ } else {
+ s.o.style.display = "none";
+ s.o.style.bottom = "0%";
+ s.o.style.position = "fixed";
+ s.o.style.display = "block";
+ }
+ };
+
+ this.vCheck = function () {
+ if (s.vX >= 0 && s.vX < 0.2) {
+ s.vX = 0.2;
+ } else if (s.vX < 0 && s.vX > -0.2) {
+ s.vX = -0.2;
+ }
+ if (s.vY >= 0 && s.vY < 0.2) {
+ s.vY = 0.2;
+ }
+ };
+
+ this.move = function () {
+ var vX = s.vX * windOffset,
+ yDiff;
+ s.x += vX;
+ s.y += s.vY * s.vAmp;
+ if (s.x >= screenX || screenX - s.x < storm.flakeWidth) {
+ // X-axis scroll check
+ s.x = 0;
+ } else if (vX < 0 && s.x - storm.flakeLeftOffset < -storm.flakeWidth) {
+ s.x = screenX - storm.flakeWidth - 1; // flakeWidth;
+ }
+ s.refresh();
+ yDiff = screenY + scrollY - s.y + storm.flakeHeight;
+ if (yDiff < storm.flakeHeight) {
+ s.active = 0;
+ if (storm.snowStick) {
+ s.stick();
+ } else {
+ s.recycle();
+ }
+ } else {
+ if (
+ storm.useMeltEffect &&
+ s.active &&
+ s.type < 3 &&
+ !s.melting &&
+ Math.random() > 0.998
+ ) {
+ // ~1/1000 chance of melting mid-air, with each frame
+ s.melting = true;
+ s.melt();
+ // only incrementally melt one frame
+ // s.melting = false;
+ }
+ if (storm.useTwinkleEffect) {
+ if (s.twinkleFrame < 0) {
+ if (Math.random() > 0.97) {
+ s.twinkleFrame = parseInt(Math.random() * 8, 10);
+ }
+ } else {
+ s.twinkleFrame--;
+ if (!opacitySupported) {
+ s.o.style.visibility =
+ s.twinkleFrame && s.twinkleFrame % 2 === 0
+ ? "hidden"
+ : "visible";
+ } else {
+ s.o.style.opacity =
+ s.twinkleFrame && s.twinkleFrame % 2 === 0 ? 0 : 1;
+ }
+ }
+ }
+ }
+ };
+
+ this.animate = function () {
+ // main animation loop
+ // move, check status, die etc.
+ s.move();
+ };
+
+ this.setVelocities = function () {
+ s.vX = vRndX + rnd(storm.vMaxX * 0.12, 0.1);
+ s.vY = vRndY + rnd(storm.vMaxY * 0.12, 0.1);
+ };
+
+ this.setOpacity = function (o, opacity) {
+ if (!opacitySupported) {
+ return false;
+ }
+ o.style.opacity = opacity;
+ };
+
+ this.melt = function () {
+ if (!storm.useMeltEffect || !s.melting) {
+ s.recycle();
+ } else {
+ if (s.meltFrame < s.meltFrameCount) {
+ s.setOpacity(s.o, s.meltFrames[s.meltFrame]);
+ s.o.style.fontSize =
+ s.fontSize - s.fontSize * (s.meltFrame / s.meltFrameCount) + "px";
+ s.o.style.lineHeight =
+ storm.flakeHeight +
+ 2 +
+ storm.flakeHeight * 0.75 * (s.meltFrame / s.meltFrameCount) +
+ "px";
+ s.meltFrame++;
+ } else {
+ s.recycle();
+ }
+ }
+ };
+
+ this.recycle = function () {
+ s.o.style.display = "none";
+ s.o.style.position = fixedForEverything ? "fixed" : "absolute";
+ s.o.style.bottom = "auto";
+ s.setVelocities();
+ s.vCheck();
+ s.meltFrame = 0;
+ s.melting = false;
+ s.setOpacity(s.o, 1);
+ s.o.style.padding = "0px";
+ s.o.style.margin = "0px";
+ s.o.style.fontSize = s.fontSize + "px";
+ s.o.style.lineHeight = storm.flakeHeight + 2 + "px";
+ s.o.style.textAlign = "center";
+ s.o.style.verticalAlign = "baseline";
+ s.x = parseInt(rnd(screenX - storm.flakeWidth - 20), 10);
+ s.y = parseInt(rnd(screenY) * -1, 10) - storm.flakeHeight;
+ s.refresh();
+ s.o.style.display = "block";
+ s.active = 1;
+ };
+
+ this.recycle(); // set up x/y coords etc.
+ this.refresh();
+ };
+
+ this.snow = function () {
+ var active = 0,
+ flake = null,
+ i,
+ j;
+ for (i = 0, j = storm.flakes.length; i < j; i++) {
+ if (storm.flakes[i].active === 1) {
+ storm.flakes[i].move();
+ active++;
+ }
+ if (storm.flakes[i].melting) {
+ storm.flakes[i].melt();
+ }
+ }
+ if (active < storm.flakesMaxActive) {
+ flake = storm.flakes[parseInt(rnd(storm.flakes.length), 10)];
+ if (flake.active === 0) {
+ flake.melting = true;
+ }
+ }
+ if (storm.timer) {
+ features.getAnimationFrame(storm.snow);
+ }
+ };
+
+ this.mouseMove = function (e) {
+ if (!storm.followMouse) {
+ return true;
+ }
+ var x = parseInt(e.clientX, 10);
+ if (x < screenX2) {
+ windOffset = -windMultiplier + (x / screenX2) * windMultiplier;
+ } else {
+ x -= screenX2;
+ windOffset = (x / screenX2) * windMultiplier;
+ }
+ };
+
+ this.createSnow = function (limit, allowInactive) {
+ var i;
+ for (i = 0; i < limit; i++) {
+ storm.flakes[storm.flakes.length] = new storm.SnowFlake(
+ parseInt(rnd(flakeTypes), 10)
+ );
+ if (allowInactive || i > storm.flakesMaxActive) {
+ storm.flakes[storm.flakes.length - 1].active = -1;
+ }
+ }
+ storm.targetElement.appendChild(docFrag);
+ };
+
+ this.timerInit = function () {
+ storm.timer = true;
+ storm.snow();
+ };
+
+ this.init = function () {
+ var i;
+ for (i = 0; i < storm.meltFrameCount; i++) {
+ storm.meltFrames.push(1 - i / storm.meltFrameCount);
+ }
+ storm.randomizeWind();
+ storm.createSnow(storm.flakesMax); // create initial batch
+ storm.events.add(window, "resize", storm.resizeHandler);
+ storm.events.add(window, "scroll", storm.scrollHandler);
+ if (storm.freezeOnBlur) {
+ if (isIE) {
+ storm.events.add(document, "focusout", storm.freeze);
+ storm.events.add(document, "focusin", storm.resume);
+ } else {
+ storm.events.add(window, "blur", storm.freeze);
+ storm.events.add(window, "focus", storm.resume);
+ }
+ }
+ storm.resizeHandler();
+ storm.scrollHandler();
+ if (storm.followMouse) {
+ storm.events.add(isIE ? document : window, "mousemove", storm.mouseMove);
+ }
+ storm.animationInterval = Math.max(20, storm.animationInterval);
+ storm.timerInit();
+ };
+
+ this.start = function (bFromOnLoad) {
+ if (!didInit) {
+ didInit = true;
+ } else if (bFromOnLoad) {
+ // already loaded and running
+ return true;
+ }
+ if (typeof storm.targetElement === "string") {
+ var targetID = storm.targetElement;
+ storm.targetElement = document.getElementById(targetID);
+ if (!storm.targetElement) {
+ throw new Error(
+ 'Snowstorm: Unable to get targetElement "' + targetID + '"'
+ );
+ }
+ }
+ if (!storm.targetElement) {
+ storm.targetElement = document.body || document.documentElement;
+ }
+ if (
+ storm.targetElement !== document.documentElement &&
+ storm.targetElement !== document.body
+ ) {
+ // re-map handler to get element instead of screen dimensions
+ storm.resizeHandler = storm.resizeHandlerAlt;
+ //and force-enable pixel positioning
+ storm.usePixelPosition = true;
+ }
+ storm.resizeHandler(); // get bounding box elements
+ storm.usePositionFixed =
+ storm.usePositionFixed && !noFixed && !storm.flakeBottom; // whether or not position:fixed is to be used
+ if (window.getComputedStyle) {
+ // attempt to determine if body or user-specified snow parent element is relatlively-positioned.
+ try {
+ targetElementIsRelative =
+ window
+ .getComputedStyle(storm.targetElement, null)
+ .getPropertyValue("position") === "relative";
+ } catch (e) {
+ // oh well
+ targetElementIsRelative = false;
+ }
+ }
+ fixedForEverything = storm.usePositionFixed;
+ if (screenX && screenY && !storm.disabled) {
+ storm.init();
+ storm.active = true;
+ }
+ };
+
+ function doDelayedStart() {
+ window.setTimeout(function () {
+ storm.start(true);
+ }, 20);
+ // event cleanup
+ storm.events.remove(isIE ? document : window, "mousemove", doDelayedStart);
+ }
+
+ function doStart() {
+ if (!storm.excludeMobile || !isMobile) {
+ doDelayedStart();
+ }
+ // event cleanup
+ storm.events.remove(window, "load", doStart);
+ }
+
+ // hooks for starting the snow
+ if (storm.autoStart) {
+ storm.events.add(window, "load", doStart, false);
+ }
+
+ return this;
+}
diff --git a/files/events/assets/js/snowed-in.js b/files/events/assets/js/snowed-in.js
new file mode 100644
index 000000000..7cfb2e173
--- /dev/null
+++ b/files/events/assets/js/snowed-in.js
@@ -0,0 +1,101 @@
+var canvas = document.querySelector('#canvas-snowed-in-overlay');
+var lineCanvas = document.querySelector('#canvas-snowed-in-lines');
+
+var canvasContext = canvas.getContext('2d');
+var lineCanvasContext = lineCanvas.getContext('2d');
+
+var pointLifetime = 4000;
+var points = [];
+
+//FILL CANVAS
+canvasContext.fillStyle="rgba(0, 0, 0, 0.1)";
+canvasContext.fillRect(0, 0, canvas.width, canvas.height);
+
+//INIT
+function init() {
+ document.addEventListener('mousemove', onMouseMove);
+ window.addEventListener('resize', resizeCanvases);
+ resizeCanvases();
+ tick();
+}
+
+init();
+
+//RESIZE CANVAS
+function resizeCanvases() {
+ canvas.width = lineCanvas.width = window.innerWidth;
+ canvas.height = lineCanvas.height = window.innerHeight;
+}
+
+function onMouseMove(event) {
+ points.push({
+ time: Date.now(),
+ x: event.clientX,
+ y: event.clientY
+ });
+}
+
+function tick() {
+ // Remove old points
+ // points = points.filter(function(point) {
+ // var age = Date.now() - point.time;
+ // return age < pointLifetime;
+ // });
+
+ drawLineCanvas();
+ drawImageCanvas();
+ requestAnimationFrame(tick);
+ //setTimeout(() => {
+ //tick();
+ //}, 1000 / 60);
+}
+
+function drawLineCanvas() {
+ var minimumLineWidth = 40;
+ var maximumLineWidth = 60;
+ var lineWidthRange = maximumLineWidth - minimumLineWidth;
+ var maximumSpeed = 200;
+
+ lineCanvasContext.clearRect(0, 0, lineCanvas.width, lineCanvas.height);
+ lineCanvasContext.lineCap = 'round';
+ lineCanvasContext.shadowBlur = 90;
+ lineCanvasContext.shadowColor = '#fff';
+
+ for (var i = 1; i < points.length; i++) {
+ var point = points[i];
+ var previousPoint = points[i - 1];
+
+ // Change line width based on speed
+ var distance = getDistanceBetween(point, previousPoint);
+ var speed = Math.max(0, Math.min(maximumSpeed, distance));
+ var percentageLineWidth = (maximumSpeed - speed) / maximumSpeed;
+ lineCanvasContext.lineWidth = minimumLineWidth + percentageLineWidth * lineWidthRange;
+
+ // Fade points as they age
+ // var age = Date.now() - point.time;
+ // var opacity = (pointLifetime - age) / pointLifetime;
+ // lineCanvasContext.strokeStyle = 'rgba(255, 255, 255, ' + opacity + ')';
+ lineCanvasContext.strokeStyle = 'rgba(255, 255, 255, 1)';
+
+ lineCanvasContext.beginPath();
+ lineCanvasContext.moveTo(previousPoint.x, previousPoint.y);
+ lineCanvasContext.lineTo(point.x, point.y);
+ lineCanvasContext.stroke();
+ }
+}
+
+function getDistanceBetween(a, b) {
+ return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
+}
+
+function drawImageCanvas() {
+ canvasContext.globalCompositeOperation = 'source-over';
+ canvasContext.save();
+ canvasContext.fillStyle="rgb(255,255,255)";
+ canvasContext.globalAlpha = 0.09;
+ canvasContext.fillRect(0, 0, canvas.width, canvas.height);
+ canvasContext.restore();
+ canvasContext.globalCompositeOperation = 'destination-out';
+ canvasContext.drawImage(lineCanvas, 0, 0);
+
+}
diff --git a/files/events/assets/media/music/arianalastxmas.mp3 b/files/events/assets/media/music/arianalastxmas.mp3
new file mode 100644
index 000000000..0a613d276
Binary files /dev/null and b/files/events/assets/media/music/arianalastxmas.mp3 differ
diff --git a/files/events/assets/media/music/avriloholy.mp3 b/files/events/assets/media/music/avriloholy.mp3
new file mode 100644
index 000000000..f81746605
Binary files /dev/null and b/files/events/assets/media/music/avriloholy.mp3 differ
diff --git a/files/events/assets/media/music/bandaidxmas.mp3 b/files/events/assets/media/music/bandaidxmas.mp3
new file mode 100644
index 000000000..5d0e041a4
Binary files /dev/null and b/files/events/assets/media/music/bandaidxmas.mp3 differ
diff --git a/files/events/assets/media/music/bells.mp3 b/files/events/assets/media/music/bells.mp3
new file mode 100644
index 000000000..534737453
Binary files /dev/null and b/files/events/assets/media/music/bells.mp3 differ
diff --git a/files/events/assets/media/music/bingcrosbells.mp3 b/files/events/assets/media/music/bingcrosbells.mp3
new file mode 100644
index 000000000..4c70b5e35
Binary files /dev/null and b/files/events/assets/media/music/bingcrosbells.mp3 differ
diff --git a/files/events/assets/media/music/bongshit.mp3 b/files/events/assets/media/music/bongshit.mp3
new file mode 100644
index 000000000..e2c325861
Binary files /dev/null and b/files/events/assets/media/music/bongshit.mp3 differ
diff --git a/files/events/assets/media/music/bows.mp3 b/files/events/assets/media/music/bows.mp3
new file mode 100644
index 000000000..8df31950a
Binary files /dev/null and b/files/events/assets/media/music/bows.mp3 differ
diff --git a/files/events/assets/media/music/buble.mp3 b/files/events/assets/media/music/buble.mp3
new file mode 100644
index 000000000..21475b703
Binary files /dev/null and b/files/events/assets/media/music/buble.mp3 differ
diff --git a/files/events/assets/media/music/bubleholly.mp3 b/files/events/assets/media/music/bubleholly.mp3
new file mode 100644
index 000000000..ea595cd6b
Binary files /dev/null and b/files/events/assets/media/music/bubleholly.mp3 differ
diff --git a/files/events/assets/media/music/carol.mp3 b/files/events/assets/media/music/carol.mp3
new file mode 100644
index 000000000..7bf6b935d
Binary files /dev/null and b/files/events/assets/media/music/carol.mp3 differ
diff --git a/files/events/assets/media/music/charliebrownxmas.mp3 b/files/events/assets/media/music/charliebrownxmas.mp3
new file mode 100644
index 000000000..8e887b27d
Binary files /dev/null and b/files/events/assets/media/music/charliebrownxmas.mp3 differ
diff --git a/files/events/assets/media/music/cold.mp3 b/files/events/assets/media/music/cold.mp3
new file mode 100644
index 000000000..d7749522f
Binary files /dev/null and b/files/events/assets/media/music/cold.mp3 differ
diff --git a/files/events/assets/media/music/crosbydrummer.mp3 b/files/events/assets/media/music/crosbydrummer.mp3
new file mode 100644
index 000000000..f53d1fac5
Binary files /dev/null and b/files/events/assets/media/music/crosbydrummer.mp3 differ
diff --git a/files/events/assets/media/music/crosbyrudolf.mp3 b/files/events/assets/media/music/crosbyrudolf.mp3
new file mode 100644
index 000000000..eb37cb137
Binary files /dev/null and b/files/events/assets/media/music/crosbyrudolf.mp3 differ
diff --git a/files/events/assets/media/music/deck.mp3 b/files/events/assets/media/music/deck.mp3
new file mode 100644
index 000000000..63d31c212
Binary files /dev/null and b/files/events/assets/media/music/deck.mp3 differ
diff --git a/files/events/assets/media/music/deckthehalls.mp3 b/files/events/assets/media/music/deckthehalls.mp3
new file mode 100644
index 000000000..3b7c3ec3e
Binary files /dev/null and b/files/events/assets/media/music/deckthehalls.mp3 differ
diff --git a/files/events/assets/media/music/deckthetrap.mp3 b/files/events/assets/media/music/deckthetrap.mp3
new file mode 100644
index 000000000..a6c090772
Binary files /dev/null and b/files/events/assets/media/music/deckthetrap.mp3 differ
diff --git a/files/events/assets/media/music/dinahsilent.mp3 b/files/events/assets/media/music/dinahsilent.mp3
new file mode 100644
index 000000000..bc512e394
Binary files /dev/null and b/files/events/assets/media/music/dinahsilent.mp3 differ
diff --git a/files/events/assets/media/music/earthasantabb.mp3 b/files/events/assets/media/music/earthasantabb.mp3
new file mode 100644
index 000000000..0a96f7fea
Binary files /dev/null and b/files/events/assets/media/music/earthasantabb.mp3 differ
diff --git a/files/events/assets/media/music/elsababy.mp3 b/files/events/assets/media/music/elsababy.mp3
new file mode 100644
index 000000000..3fa2d6b21
Binary files /dev/null and b/files/events/assets/media/music/elsababy.mp3 differ
diff --git a/files/events/assets/media/music/elton.mp3 b/files/events/assets/media/music/elton.mp3
new file mode 100644
index 000000000..9b384311a
Binary files /dev/null and b/files/events/assets/media/music/elton.mp3 differ
diff --git a/files/events/assets/media/music/elvisbethlehem.mp3 b/files/events/assets/media/music/elvisbethlehem.mp3
new file mode 100644
index 000000000..1a186e239
Binary files /dev/null and b/files/events/assets/media/music/elvisbethlehem.mp3 differ
diff --git a/files/events/assets/media/music/elviswhite.mp3 b/files/events/assets/media/music/elviswhite.mp3
new file mode 100644
index 000000000..17208d671
Binary files /dev/null and b/files/events/assets/media/music/elviswhite.mp3 differ
diff --git a/files/events/assets/media/music/fireplace.mp3 b/files/events/assets/media/music/fireplace.mp3
new file mode 100644
index 000000000..63ac9b306
Binary files /dev/null and b/files/events/assets/media/music/fireplace.mp3 differ
diff --git a/files/events/assets/media/music/firstnoelrem.mp3 b/files/events/assets/media/music/firstnoelrem.mp3
new file mode 100644
index 000000000..a1ea1ab46
Binary files /dev/null and b/files/events/assets/media/music/firstnoelrem.mp3 differ
diff --git a/files/events/assets/media/music/frosty.mp3 b/files/events/assets/media/music/frosty.mp3
new file mode 100644
index 000000000..99e7604e2
Binary files /dev/null and b/files/events/assets/media/music/frosty.mp3 differ
diff --git a/files/events/assets/media/music/grinch.mp3 b/files/events/assets/media/music/grinch.mp3
new file mode 100644
index 000000000..974b7e96f
Binary files /dev/null and b/files/events/assets/media/music/grinch.mp3 differ
diff --git a/files/events/assets/media/music/hark.mp3 b/files/events/assets/media/music/hark.mp3
new file mode 100644
index 000000000..1db947869
Binary files /dev/null and b/files/events/assets/media/music/hark.mp3 differ
diff --git a/files/events/assets/media/music/hark2.mp3 b/files/events/assets/media/music/hark2.mp3
new file mode 100644
index 000000000..9741ba746
Binary files /dev/null and b/files/events/assets/media/music/hark2.mp3 differ
diff --git a/files/events/assets/media/music/hark3.mp3 b/files/events/assets/media/music/hark3.mp3
new file mode 100644
index 000000000..71eafb013
Binary files /dev/null and b/files/events/assets/media/music/hark3.mp3 differ
diff --git a/files/events/assets/media/music/herecumssanta.mp3 b/files/events/assets/media/music/herecumssanta.mp3
new file mode 100644
index 000000000..a358519e0
Binary files /dev/null and b/files/events/assets/media/music/herecumssanta.mp3 differ
diff --git a/files/events/assets/media/music/herecumstrap.mp3 b/files/events/assets/media/music/herecumstrap.mp3
new file mode 100644
index 000000000..52452053e
Binary files /dev/null and b/files/events/assets/media/music/herecumstrap.mp3 differ
diff --git a/files/events/assets/media/music/holiday.mp3 b/files/events/assets/media/music/holiday.mp3
new file mode 100644
index 000000000..89112cf0b
Binary files /dev/null and b/files/events/assets/media/music/holiday.mp3 differ
diff --git a/files/events/assets/media/music/kissing.mp3 b/files/events/assets/media/music/kissing.mp3
new file mode 100644
index 000000000..6d4fbcd33
Binary files /dev/null and b/files/events/assets/media/music/kissing.mp3 differ
diff --git a/files/events/assets/media/music/lindplum.mp3 b/files/events/assets/media/music/lindplum.mp3
new file mode 100644
index 000000000..5c4ef8c8f
Binary files /dev/null and b/files/events/assets/media/music/lindplum.mp3 differ
diff --git a/files/events/assets/media/music/low.mp3 b/files/events/assets/media/music/low.mp3
new file mode 100644
index 000000000..a20b8dd81
Binary files /dev/null and b/files/events/assets/media/music/low.mp3 differ
diff --git a/files/events/assets/media/music/lowxmas.mp3 b/files/events/assets/media/music/lowxmas.mp3
new file mode 100644
index 000000000..c958665c0
Binary files /dev/null and b/files/events/assets/media/music/lowxmas.mp3 differ
diff --git a/files/events/assets/media/music/mariah.mp3 b/files/events/assets/media/music/mariah.mp3
new file mode 100644
index 000000000..c78afd773
Binary files /dev/null and b/files/events/assets/media/music/mariah.mp3 differ
diff --git a/files/events/assets/media/music/marysboykid.mp3 b/files/events/assets/media/music/marysboykid.mp3
new file mode 100644
index 000000000..332a87a40
Binary files /dev/null and b/files/events/assets/media/music/marysboykid.mp3 differ
diff --git a/files/events/assets/media/music/navidad.mp3 b/files/events/assets/media/music/navidad.mp3
new file mode 100644
index 000000000..f4df77532
Binary files /dev/null and b/files/events/assets/media/music/navidad.mp3 differ
diff --git a/files/events/assets/media/music/nightcore.mp3 b/files/events/assets/media/music/nightcore.mp3
new file mode 100644
index 000000000..896bab8c6
Binary files /dev/null and b/files/events/assets/media/music/nightcore.mp3 differ
diff --git a/files/events/assets/media/music/nightcore2.mp3 b/files/events/assets/media/music/nightcore2.mp3
new file mode 100644
index 000000000..68442a48d
Binary files /dev/null and b/files/events/assets/media/music/nightcore2.mp3 differ
diff --git a/files/events/assets/media/music/nightcore3.mp3 b/files/events/assets/media/music/nightcore3.mp3
new file mode 100644
index 000000000..22f1b1cbf
Binary files /dev/null and b/files/events/assets/media/music/nightcore3.mp3 differ
diff --git a/files/events/assets/media/music/nightmare.mp3 b/files/events/assets/media/music/nightmare.mp3
new file mode 100644
index 000000000..63fbfa61b
Binary files /dev/null and b/files/events/assets/media/music/nightmare.mp3 differ
diff --git a/files/events/assets/media/music/nkcchestnuts.mp3 b/files/events/assets/media/music/nkcchestnuts.mp3
new file mode 100644
index 000000000..ef5840b57
Binary files /dev/null and b/files/events/assets/media/music/nkcchestnuts.mp3 differ
diff --git a/files/events/assets/media/music/pentatonix.mp3 b/files/events/assets/media/music/pentatonix.mp3
new file mode 100644
index 000000000..b0ba9247d
Binary files /dev/null and b/files/events/assets/media/music/pentatonix.mp3 differ
diff --git a/files/events/assets/media/music/perryholy.mp3 b/files/events/assets/media/music/perryholy.mp3
new file mode 100644
index 000000000..d8b906c93
Binary files /dev/null and b/files/events/assets/media/music/perryholy.mp3 differ
diff --git a/files/events/assets/media/music/rockin.mp3 b/files/events/assets/media/music/rockin.mp3
new file mode 100644
index 000000000..1ce29d566
Binary files /dev/null and b/files/events/assets/media/music/rockin.mp3 differ
diff --git a/files/events/assets/media/music/rockintrap.mp3 b/files/events/assets/media/music/rockintrap.mp3
new file mode 100644
index 000000000..a3129089c
Binary files /dev/null and b/files/events/assets/media/music/rockintrap.mp3 differ
diff --git a/files/events/assets/media/music/rudolph.mp3 b/files/events/assets/media/music/rudolph.mp3
new file mode 100644
index 000000000..ff0961a9e
Binary files /dev/null and b/files/events/assets/media/music/rudolph.mp3 differ
diff --git a/files/events/assets/media/music/rudolphtrap.mp3 b/files/events/assets/media/music/rudolphtrap.mp3
new file mode 100644
index 000000000..a8e2c7882
Binary files /dev/null and b/files/events/assets/media/music/rudolphtrap.mp3 differ
diff --git a/files/events/assets/media/music/santa.mp3 b/files/events/assets/media/music/santa.mp3
new file mode 100644
index 000000000..feaece8e7
Binary files /dev/null and b/files/events/assets/media/music/santa.mp3 differ
diff --git a/files/events/assets/media/music/santababy.mp3 b/files/events/assets/media/music/santababy.mp3
new file mode 100644
index 000000000..8e5d8a5c6
Binary files /dev/null and b/files/events/assets/media/music/santababy.mp3 differ
diff --git a/files/events/assets/media/music/santacumtownn.mp3 b/files/events/assets/media/music/santacumtownn.mp3
new file mode 100644
index 000000000..3d68add49
Binary files /dev/null and b/files/events/assets/media/music/santacumtownn.mp3 differ
diff --git a/files/events/assets/media/music/simply.mp3 b/files/events/assets/media/music/simply.mp3
new file mode 100644
index 000000000..a7688d6aa
Binary files /dev/null and b/files/events/assets/media/music/simply.mp3 differ
diff --git a/files/events/assets/media/music/simplyhaving.mp3 b/files/events/assets/media/music/simplyhaving.mp3
new file mode 100644
index 000000000..8e5e76aca
Binary files /dev/null and b/files/events/assets/media/music/simplyhaving.mp3 differ
diff --git a/files/events/assets/media/music/sinatra.mp3 b/files/events/assets/media/music/sinatra.mp3
new file mode 100644
index 000000000..108034257
Binary files /dev/null and b/files/events/assets/media/music/sinatra.mp3 differ
diff --git a/files/events/assets/media/music/sinatra2.mp3 b/files/events/assets/media/music/sinatra2.mp3
new file mode 100644
index 000000000..317601ea2
Binary files /dev/null and b/files/events/assets/media/music/sinatra2.mp3 differ
diff --git a/files/events/assets/media/music/sinatramerry.mp3 b/files/events/assets/media/music/sinatramerry.mp3
new file mode 100644
index 000000000..128fbb509
Binary files /dev/null and b/files/events/assets/media/music/sinatramerry.mp3 differ
diff --git a/files/events/assets/media/music/steve.mp3 b/files/events/assets/media/music/steve.mp3
new file mode 100644
index 000000000..bf3eaf70b
Binary files /dev/null and b/files/events/assets/media/music/steve.mp3 differ
diff --git a/files/events/assets/media/music/sugarplum.mp3 b/files/events/assets/media/music/sugarplum.mp3
new file mode 100644
index 000000000..7bb4b4127
Binary files /dev/null and b/files/events/assets/media/music/sugarplum.mp3 differ
diff --git a/files/events/assets/media/music/sugartrap.mp3 b/files/events/assets/media/music/sugartrap.mp3
new file mode 100644
index 000000000..4507a59c7
Binary files /dev/null and b/files/events/assets/media/music/sugartrap.mp3 differ
diff --git a/files/events/assets/media/music/taytayxmas.mp3 b/files/events/assets/media/music/taytayxmas.mp3
new file mode 100644
index 000000000..adc1e0870
Binary files /dev/null and b/files/events/assets/media/music/taytayxmas.mp3 differ
diff --git a/files/events/assets/media/music/trans.mp3 b/files/events/assets/media/music/trans.mp3
new file mode 100644
index 000000000..02162b156
Binary files /dev/null and b/files/events/assets/media/music/trans.mp3 differ
diff --git a/files/events/assets/media/music/waitresses.mp3 b/files/events/assets/media/music/waitresses.mp3
new file mode 100644
index 000000000..b4e3b0da4
Binary files /dev/null and b/files/events/assets/media/music/waitresses.mp3 differ
diff --git a/files/events/assets/media/music/waitresseswrapping.mp3 b/files/events/assets/media/music/waitresseswrapping.mp3
new file mode 100644
index 000000000..72862e7c4
Binary files /dev/null and b/files/events/assets/media/music/waitresseswrapping.mp3 differ
diff --git a/files/events/assets/media/music/wham.mp3 b/files/events/assets/media/music/wham.mp3
new file mode 100644
index 000000000..78e55622a
Binary files /dev/null and b/files/events/assets/media/music/wham.mp3 differ
diff --git a/files/events/assets/media/music/womblexmas.mp3 b/files/events/assets/media/music/womblexmas.mp3
new file mode 100644
index 000000000..2520168dd
Binary files /dev/null and b/files/events/assets/media/music/womblexmas.mp3 differ
diff --git a/files/events/assets/media/music/wonderland.mp3 b/files/events/assets/media/music/wonderland.mp3
new file mode 100644
index 000000000..b70cab191
Binary files /dev/null and b/files/events/assets/media/music/wonderland.mp3 differ
diff --git a/files/events/classes/eventuser.py b/files/events/classes/eventuser.py
index d8e5d14dd..a275d827c 100644
--- a/files/events/classes/eventuser.py
+++ b/files/events/classes/eventuser.py
@@ -10,7 +10,7 @@ class EventUser(Base):
event_music = Column(Boolean, default=True, nullable=False)
# start event specific columns
-
+ event_darkmode = Column(Boolean, default=False, nullable=False)
# end event specific columns
def __init__(self, *args, **kwargs):
diff --git a/files/events/helpers/__init__.py b/files/events/helpers/__init__.py
index 3651c2473..f278f91f7 100644
--- a/files/events/helpers/__init__.py
+++ b/files/events/helpers/__init__.py
@@ -1,2 +1,3 @@
from .const import *
from .jinja import *
+from .get import *
diff --git a/files/events/helpers/const.py b/files/events/helpers/const.py
index ddda308de..874ecf65b 100644
--- a/files/events/helpers/const.py
+++ b/files/events/helpers/const.py
@@ -1,3 +1,80 @@
EVENT_AWARDS = {
-
+ "snow": {
+ "kind": "snow",
+ "title": "Snow",
+ "description": "",
+ "icon": "fas fa-snowflake",
+ "color": "text-lightblue",
+ "price": 300,
+ "deflectable": False,
+ "cosmetic": True
+ },
+ "gingerbread": {
+ "kind": "gingerbread",
+ "title": "Gingerbread",
+ "description": "",
+ "icon": "fas fa-gingerbread-man",
+ "color": "text-brown",
+ "price": 300,
+ "deflectable": False,
+ "cosmetic": True
+ },
+ "lights": {
+ "kind": "lights",
+ "title": "Lights",
+ "description": "",
+ "icon": "fas fa-lights-holiday",
+ "color": "text-success",
+ "price": 300,
+ "deflectable": False,
+ "cosmetic": True
+ },
+ "candycane": {
+ "kind": "candycane",
+ "title": "Candy Cane",
+ "description": "",
+ "icon": "fas fa-candy-cane",
+ "color": "text-danger",
+ "price": 400,
+ "deflectable": False,
+ "cosmetic": True
+ },
+ "fireplace": {
+ "kind": "fireplace",
+ "title": "Fireplace",
+ "description": "",
+ "icon": "fas fa-fireplace",
+ "color": "text-orange",
+ "price": 600,
+ "deflectable": False,
+ "cosmetic": True
+ },
+ "frostbite": {
+ "kind": "frostbite",
+ "title": "Frostbite",
+ "description": "",
+ "icon": "fas fa-temperature-snow",
+ "color": "text-blue",
+ "price": 300,
+ "deflectable": False,
+ "cosmetic": True
+ },
}
+
+"""
+ "snowed-in": {
+ "kind": "snowed-in",
+ "title": "Snowed In",
+ "description": "",
+ "icon": "fas fa-temperature-snow",
+ "color": "text-blue",
+ "price": 600,
+ "deflectable": False,
+ "cosmetic": True
+ },
+
+"""
+
+EVENT_FORCED_HATS = ['/i/hats/Santa Hat III.webp?h=1', \
+ '/i/hats/Winter Cap.webp?h=1', \
+ '/i/hats/Present Bow.webp?h=1']
diff --git a/files/events/helpers/jinja.py b/files/events/helpers/jinja.py
index 1ff785df3..68fca8d48 100644
--- a/files/events/helpers/jinja.py
+++ b/files/events/helpers/jinja.py
@@ -1,8 +1,36 @@
+import random
+from datetime import date
+from .get import get_or_create_event_user
+
+def days_till_christmas():
+ today = date.today()
+ christmas = date(today.year, 12, 25)
+ delta = abs(christmas - today)
+ return delta.days
+
+def user_event_darkmode(target, db):
+ user = get_or_create_event_user(target, db)
+ return user.event_darkmode
+
EVENT_JINJA_CONST = {
"EVENT_BANNER": "banner_rDrama.html",
+ "EVENT_ICONS": True,
"EVENT_SIDEBAR": True,
- "EVENT_STYLES": "spooky.css",
+ "EVENT_STYLES": "blizzard.css",
"EVENT_AWARDS": True,
"EVENT_MUSIC": "music.html",
+ "EVENT_VISITORS_HERE_FLAVOR": [
+ ' santa enjoyers kissing under a misletoe',
+ ' bringing up family drama at Christmas dinner',
+ ' least homoerotic dramanauts stroking their candy canes',
+ " dramanauts jingling each other's balls",
+ " average Santa deniers getting reamed by Rudolph the Red-Nosed Reindeer",
+ " naughty listers getting coal for fistmas",
+ " plus-sized dramanauts eating Santa's cookies",
+ " dramatards having their chimneys stuffed by Santa",
+ ],
+ "random": random,
+ "days_till_christmas": days_till_christmas,
+ "user_event_darkmode": user_event_darkmode,
}
diff --git a/files/events/routes/__init__.py b/files/events/routes/__init__.py
index d33dc9c13..3e97f7861 100644
--- a/files/events/routes/__init__.py
+++ b/files/events/routes/__init__.py
@@ -1,2 +1,3 @@
from .awards import *
from .jinja import *
+from .theme import *
diff --git a/files/events/routes/theme.py b/files/events/routes/theme.py
new file mode 100644
index 000000000..0b47f0c99
--- /dev/null
+++ b/files/events/routes/theme.py
@@ -0,0 +1,16 @@
+from files.events.helpers import get_or_create_event_user
+from files.__main__ import g, app
+from files.routes.wrappers import auth_required
+
+@app.post("/events/fistmas2022/darkmode")
+@auth_required
+def event_darkmode(v):
+ user = get_or_create_event_user(v, g.db)
+ if user.event_darkmode:
+ user.event_darkmode = False
+ else:
+ user.event_darkmode = True
+
+ g.db.add(user)
+
+ return {}
diff --git a/files/events/templates/awards.html b/files/events/templates/awards.html
index e69de29bb..d79580992 100644
--- a/files/events/templates/awards.html
+++ b/files/events/templates/awards.html
@@ -0,0 +1,121 @@
+
+ {% set gingerbread_count = p.award_count("gingerbread", v) * 2 if p.award_count("gingerbread", v) <= 10 else 20 %}
+ {% for i in range(gingerbread_count) %}
+
+
+
+ {% endfor %}
+
+ {# idk why snow isn't working vvvvvvvvvv #}
+ {% if p.award_count("snow", v) %}
+
+
+ {% endif %}
+
+ {% if p.award_count("frostbite", v) %}
+
+
+
+ {% endif %}
+
+ {% if p.award_count("snowed-in", v) %}
+
+
+
+
+ {% endif %}
+
+
+{% if p.award_count("lights", v) %}
+
+{% endif %}
+
+{% if p.award_count("candycane", v) %}
+
+{% endif %}
+
+{% if p.award_count("fireplace", v) %}
+
+{% endif %}
diff --git a/files/events/templates/banner.svg b/files/events/templates/banner.svg
new file mode 100644
index 000000000..d3a612d07
--- /dev/null
+++ b/files/events/templates/banner.svg
@@ -0,0 +1,234 @@
+
+
+
+
+
+ Merry Fistmas!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/files/events/templates/banner_rDrama.html b/files/events/templates/banner_rDrama.html
index 9c1abdd46..e5df8abb3 100644
--- a/files/events/templates/banner_rDrama.html
+++ b/files/events/templates/banner_rDrama.html
@@ -1,3 +1,28 @@
-
+{# #}
+{% if request.path == '/' %}
+
+
+{% endif %}
+
+
+
+
+
+
+ 0
+
+
+ {{days_till_christmas()}}
+
+
+
+
+
+ {% if random.randint(1,100) != 1 %}
+
+ {% include "event/banner.svg" %}
+ {% else %}
+
+ {% endif %}
diff --git a/files/events/templates/sidebar_rDrama.html b/files/events/templates/sidebar_rDrama.html
index 8ac2e4c0a..b54875d26 100644
--- a/files/events/templates/sidebar_rDrama.html
+++ b/files/events/templates/sidebar_rDrama.html
@@ -22,9 +22,12 @@
-
+
+
+
{% if sub %}
{% if sub.sidebar_html %}
{{sub.sidebar_html|safe}}
@@ -51,29 +54,11 @@
CREATE {{HOLE_NAME|upper}}
{%- endif %}
-
+
+{% include "event/music.html" %}
diff --git a/files/helpers/actions.py b/files/helpers/actions.py
index 2dcc385f3..e64c8a34f 100644
--- a/files/helpers/actions.py
+++ b/files/helpers/actions.py
@@ -56,14 +56,14 @@ def execute_snappy(post:Submission, v:User):
elif v.id == LAWLZ_ID:
if random.random() < 0.5: body = "wow, this lawlzpost sucks!"
else: body = "wow, a good lawlzpost for once!"
- elif not SNAPPY_MARSEYS and not SNAPPY_QUOTES:
- body = ""
elif post.sub == 'masterbaiters' and random.random() < 0.33:
body = "Can you people come up with any ideas that don't involve committing federal crimes"
else:
if SNAPPY_MARSEYS and SNAPPY_QUOTES:
- if random.random() < 0.5: SNAPPY_CHOICES = SNAPPY_MARSEYS
- else: SNAPPY_CHOICES = SNAPPY_QUOTES
+ if HOLIDAY_EVENT or random.random() > 0.5:
+ SNAPPY_CHOICES = SNAPPY_QUOTES
+ else:
+ SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_MARSEYS: SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_QUOTES: SNAPPY_CHOICES = SNAPPY_QUOTES
else: SNAPPY_CHOICES = [""]
diff --git a/files/helpers/config/awards.py b/files/helpers/config/awards.py
index 98054d890..9c14a94cc 100644
--- a/files/helpers/config/awards.py
+++ b/files/helpers/config/awards.py
@@ -675,6 +675,8 @@ AWARDS_DISABLED = [
'candy-corn', 'ectoplasm', 'bones', 'pumpkin', # Homoween '22 (cont'd)
]
+LOOTBOX_ITEM_COUNT = 5
+LOOTBOX_CONTENTS = ["firework", "confetti", "ricardo", "wholesome", "shit", "fireflies", "scooter", "train"]
HOUSE_AWARDS = {
"Furry": {
@@ -737,8 +739,6 @@ if SITE_NAME == 'PCM':
#AWARDS_DISABLED.extend(['ban','pizzashill','marsey','bird','grass','chud','unblockable'])
AWARDS_DISABLED.extend(['unblockable'])
AWARDS_DISABLED.remove('ghost')
-elif SITE_NAME == 'WPD':
- AWARDS_DISABLED.remove('lootbox')
if not FEATURES['MARSEYBUX']:
AWARDS_DISABLED.append('benefactor')
diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py
index 1539af5ea..cf33977a2 100644
--- a/files/helpers/config/const.py
+++ b/files/helpers/config/const.py
@@ -221,7 +221,7 @@ SUB_MARSEY_URL_LENGTH = 60
### SITE SPECIFIC CONSTANTS
################################################################################
-HOLIDAY_EVENT = None
+HOLIDAY_EVENT = True
PERMS = { # Minimum admin_level to perform action.
'ADMIN_ADD': 3,
diff --git a/files/helpers/const_stateful.py b/files/helpers/const_stateful.py
index 1a90c6336..2a2ae8b04 100644
--- a/files/helpers/const_stateful.py
+++ b/files/helpers/const_stateful.py
@@ -3,7 +3,7 @@ from os import path
from sqlalchemy.orm import scoped_session
from files.classes import Marsey
-from files.helpers.config.const import SITE_NAME
+from files.helpers.config.const import HOLIDAY_EVENT, SITE_NAME
marseys_const = []
marseys_const2 = []
@@ -32,6 +32,11 @@ def _initialize_snappy_marseys_and_quotes():
if SITE_NAME != 'PCM':
SNAPPY_MARSEYS = [f':#{x}:' for x in marseys_const2]
- if path.isfile(f'snappy_{SITE_NAME}.txt'):
- with open(f'snappy_{SITE_NAME}.txt', "r", encoding="utf-8") as f:
+ filename = f"snappy_{SITE_NAME}.txt"
+ if HOLIDAY_EVENT: filename = f"snappy_event_{SITE_NAME}.txt"
+
+ try:
+ with open(filename, "r", encoding="utf-8") as f:
SNAPPY_QUOTES = f.read().split("\n{[para]}\n")
+ except FileNotFoundError:
+ pass
diff --git a/files/routes/awards.py b/files/routes/awards.py
index 47794e04b..03b561cee 100644
--- a/files/routes/awards.py
+++ b/files/routes/awards.py
@@ -8,7 +8,7 @@ from files.classes.userblock import UserBlock
from files.helpers.actions import *
from files.helpers.alerts import *
from files.helpers.config.const import *
-from files.helpers.config.awards import AWARDS_ENABLED, HOUSE_AWARDS
+from files.helpers.config.awards import AWARDS_ENABLED, HOUSE_AWARDS, LOOTBOX_ITEM_COUNT, LOOTBOX_CONTENTS
from files.helpers.get import *
from files.helpers.marsify import marsify
from files.helpers.owoify import owoify
@@ -93,10 +93,10 @@ def buy(v:User, award):
if award == "lootbox":
lootbox_items = []
- for i in range(5): # five items per lootbox
- lb_award = random.choice(["firework", "confetti", "ricardo", "wholesome", "shit", "fireflies", "scooter", "train"])
+ for _ in range(LOOTBOX_ITEM_COUNT): # five items per lootbox
+ lb_award = random.choice(LOOTBOX_CONTENTS)
lootbox_items.append(AWARDS[lb_award]['title'])
- lb_award = AwardRelationship(user_id=v.id, kind=lb_award)
+ lb_award = AwardRelationship(user_id=v.id, kind=lb_award, price_paid=price // LOOTBOX_ITEM_COUNT)
g.db.add(lb_award)
g.db.flush()
@@ -112,7 +112,7 @@ def buy(v:User, award):
badge_grant(badge_id=78, user=v)
else:
- award_object = AwardRelationship(user_id=v.id, kind=award)
+ award_object = AwardRelationship(user_id=v.id, kind=award, price_paid=price)
g.db.add(award_object)
g.db.add(v)
diff --git a/files/templates/default.html b/files/templates/default.html
index b2af59758..c07202496 100644
--- a/files/templates/default.html
+++ b/files/templates/default.html
@@ -103,4 +103,8 @@
{% endif %}
+{% block footer %}
+
+{% endblock %}
+
{% endblock %}
diff --git a/files/templates/header.html b/files/templates/header.html
index 4d99af428..2052777ed 100644
--- a/files/templates/header.html
+++ b/files/templates/header.html
@@ -19,27 +19,30 @@
{% if range(1,5) | random == 1 %}
{% include "journoid_banner.html" %}
{% else %}
- {%-
- set VISITORS_HERE_FLAVOR = [
- ' incels currently stalking roasties',
- ' gooners currently edging to ',
- ' fanboys currently obsessing over Carp',
- ' NEETs currently LDARmaxxing',
- ' valid women currently dilating',
- ' negholes currently being pozzed',
- ' bussies currently on standby',
- ' gamers currently harassing women',
- ' dramanauts hurtling through Safe Space™',
- ' Soros shills currently plotting mayocide',
- ' furries currently yiffing',
- ' incels currently harassing women',
- ' chuds currently agendaposting',
- ' coomers currently gooning',
- ' bacons currently narwhaling',
- ' well-behaved rule-following goodthinkers',
- ' throwing shade right now',
- ]
- -%}
+ {% if EVENT_VISITORS_HERE_FLAVOR %}
+ {%- set VISITORS_HERE_FLAVOR = EVENT_VISITORS_HERE_FLAVOR -%}
+ {% else %}
+ {%- set VISITORS_HERE_FLAVOR = [
+ ' incels currently stalking roasties',
+ ' gooners currently edging to ',
+ ' fanboys currently obsessing over Carp',
+ ' NEETs currently LDARmaxxing',
+ ' valid women currently dilating',
+ ' negholes currently being pozzed',
+ ' bussies currently on standby',
+ ' gamers currently harassing women',
+ ' dramanauts hurtling through Safe Space™',
+ ' Soros shills currently plotting mayocide',
+ ' furries currently yiffing',
+ ' incels currently harassing women',
+ ' chuds currently agendaposting',
+ ' coomers currently gooning',
+ ' bacons currently narwhaling',
+ ' well-behaved rule-following goodthinkers',
+ ' throwing shade right now',
+ ]
+ -%}}
+ {% endif %}
{{loggedin_counter+loggedout_counter}} {{VISITORS_HERE_FLAVOR|random|safe}} ({{loggedin_counter}} logged in)
{% endif %}
{% else %}
@@ -59,11 +62,14 @@
- {% if SITE_NAME == 'WPD' %}{# Temporary event code, 2022-12-11 #}
-
+ {% if SITE_NAME == 'WPD' %} {# Temporary event code, 2022-12-11 #}
+ {% set icon_url = 'icons-event/2022-christmas.webp' | asset_siteimg %}
+ {% elif EVENT_ICONS %}
+ {% set icon_url = macros.random_image('event/icon', false) %}
{% else %}
-
+ {% set icon_url = 'headericon.webp' | asset_siteimg %}
{% endif %}
+
{% if sub %}
@@ -347,7 +353,8 @@
{% endif %}
{% if has_sidebar %}
- {% include "sidebar_" ~ SITE_NAME ~ ".html" %}
+ {% set sidebar = "sidebar_" ~ SITE_NAME ~ ".html" %}
+ {% include sidebar if not EVENT_SIDEBAR else 'event/' ~ sidebar %}
{% endif %}
diff --git a/files/templates/journoid_banner.html b/files/templates/journoid_banner.html
index ad9cd7e3d..f811c09be 100644
--- a/files/templates/journoid_banner.html
+++ b/files/templates/journoid_banner.html
@@ -5,11 +5,6 @@ set JOURNOID_BANNERS = [
"https://reddit.com/r/subredditdrama",
""
),
- (
- "A subsidiary of Open Society Foundations",
- "https://www.opensocietyfoundations.org",
- ""
- ),
(
"As seen on The Independent 📰✨💞",
"https://www.independent.co.uk/news/world/americas/us-politics/reddit-conservatives-post-trans-child-fake-b2060803.html",
diff --git a/files/templates/submission.html b/files/templates/submission.html
index 30d44d686..bbce12e73 100644
--- a/files/templates/submission.html
+++ b/files/templates/submission.html
@@ -16,6 +16,13 @@
{% include "awards.html" %}
+
+{# DO NOT REMOVE THIS #}
+{% if EVENT_AWARDS %}
+ {% include "event/awards.html" %}
+{% endif %}
+{# ^^ DO NOT REMOVE THIS ^^ #}
+
{% endblock %}
{% set ups=p.upvotes %}
{% set downs=p.downvotes %}
diff --git a/files/templates/util/html_head.html b/files/templates/util/html_head.html
index a29dd2df5..b477146b3 100644
--- a/files/templates/util/html_head.html
+++ b/files/templates/util/html_head.html
@@ -160,6 +160,10 @@
{% if EVENT_STYLES %}
{% set EVENT_STYLES = 'css/event/'+EVENT_STYLES %}
+
+ {% if v and user_event_darkmode(v, g.db)%}
+
+ {% endif %}
{% endif %}
{% if request.path == '/chat' %}
diff --git a/files/templates/util/macros.html b/files/templates/util/macros.html
index f475d677d..bd2dd3b65 100644
--- a/files/templates/util/macros.html
+++ b/files/templates/util/macros.html
@@ -21,8 +21,12 @@
{% endif %}
{%- endmacro -%}
-{%- macro random_image(assetdir) -%}
- {% set path = "assets/images/" ~ SITE_NAME ~ "/" ~ assetdir -%}
+{%- macro random_image(assetdir, include_site_name=true) -%}
+ {% if include_site_name %}
+ {% set path = "assets/images/" ~ SITE_NAME ~ "/" ~ assetdir %}
+ {% else %}
+ {% set path = "assets/images/" ~ assetdir %}
+ {% endif %}
{{- "/" ~ path ~ "/" ~ listdir('files/' ~ path)|random() ~ '?v=45' }}
{%- endmacro -%}
diff --git a/migrations/20221215-add-price-paid.sql b/migrations/20221215-add-price-paid.sql
new file mode 100644
index 000000000..e951fc9a1
--- /dev/null
+++ b/migrations/20221215-add-price-paid.sql
@@ -0,0 +1,86 @@
+BEGIN
+ALTER TABLE award_relationships ADD COLUMN price_paid INTEGER NOT NULL DEFAULT 0;
+ALTER TABLE award_relationships ALTER COLUMN kind SET NOT NULL;
+
+-- populate existing awards, this should match the values in files/helpers/config/awards.py
+
+-- deprecated
+UPDATE award_relationships SET price_paid = 3000 WHERE kind = 'ghost';
+UPDATE award_relationships SET price_paid = 10000 WHERE kind = 'nword';
+-- fistmas 2021
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'snow';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'gingerbread';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'lights';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'candycane';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'fireplace';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'grinch';
+-- homoween 2021 and 2022
+UPDATE award_relationships SET price_paid = 500 WHERE kind = 'haunt';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'upsidedown';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'stab';
+UPDATE award_relationships SET price_paid = 200 WHERE kind = 'spiders';
+UPDATE award_relationships SET price_paid = 200 WHERE kind = 'fog';
+-- homoween 2022
+UPDATE award_relationships SET price_paid = 600 WHERE kind = 'jumpscare';
+UPDATE award_relationships SET price_paid = 500 WHERE kind = 'hw-bite';
+UPDATE award_relationships SET price_paid = 500 WHERE kind = 'hw-vax';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'hw-grinch';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'flashlight';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'candy-corn';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'ectoplasm';
+UPDATE award_relationships SET price_paid = 200 WHERE kind = 'bones';
+UPDATE award_relationships SET price_paid = 200 WHERE kind = 'pumpkin';
+-- standard
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'marsify';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'shit';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'fireflies';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'train';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'scooter';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'wholesome';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'firework';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'confetti';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'ricardo';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'tilt';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'glowie';
+UPDATE award_relationships SET price_paid = 777 WHERE kind = 'rehab';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'agendaposter';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'offsitementions';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'lootbox';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'beano';
+UPDATE award_relationships SET price_paid = 1000 WHERE kind = 'unpin';
+UPDATE award_relationships SET price_paid = 1250 WHERE kind = 'flairlock';
+UPDATE award_relationships SET price_paid = 1500 WHERE kind = 'pin';
+UPDATE award_relationships SET price_paid = 1500 WHERE kind = 'progressivestack';
+UPDATE award_relationships SET price_paid = 1500 WHERE kind = 'pizzashill';
+UPDATE award_relationships SET price_paid = 1500 WHERE kind = 'bird';
+UPDATE award_relationships SET price_paid = 2000 WHERE kind = 'spider';
+UPDATE award_relationships SET price_paid = 2750 WHERE kind = 'deflector';
+UPDATE award_relationships SET price_paid = 3000 WHERE kind = 'marsey';
+UPDATE award_relationships SET price_paid = 3000 WHERE kind = 'ban';
+UPDATE award_relationships SET price_paid = 3500 WHERE kind = 'unban';
+UPDATE award_relationships SET price_paid = 4000 WHERE kind = 'benefactor';
+UPDATE award_relationships SET price_paid = 5000 WHERE kind = 'eye';
+UPDATE award_relationships SET price_paid = 10000 WHERE kind = 'grass';
+UPDATE award_relationships SET price_paid = 20000 WHERE kind = 'unblockable';
+UPDATE award_relationships SET price_paid = 20000 WHERE kind = 'fish';
+UPDATE award_relationships SET price_paid = 20000 WHERE kind = 'pause';
+UPDATE award_relationships SET price_paid = 40000 WHERE kind = 'unpausable';
+UPDATE award_relationships SET price_paid = 50000 WHERE kind = 'alt';
+UPDATE award_relationships SET price_paid = 50000 WHERE kind = 'checkmark';
+-- wpd and pcm
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'owoify';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'rainbow';
+-- pcm
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'croag';
+UPDATE award_relationships SET price_paid = 150 WHERE kind = 'toe';
+UPDATE award_relationships SET price_paid = 4000 WHERE kind = 'crab';
+-- house awards
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'Furry';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'Femboy';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'Vampire';
+UPDATE award_relationships SET price_paid = 400 WHERE kind = 'Racist';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'Furry Founder';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'Femboy Founder';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'Vampire Founder';
+UPDATE award_relationships SET price_paid = 300 WHERE kind = 'Racist Founder';
+COMMIT;
diff --git a/snappy_event_rDrama.txt b/snappy_event_rDrama.txt
new file mode 100644
index 000000000..f4f828b76
--- /dev/null
+++ b/snappy_event_rDrama.txt
@@ -0,0 +1,10 @@
+```
+ .-""-.
+ /,..___\
+() {_____}
+ (/-@-@-\)
+ {`-=^=-'}
+ { `-' } Merry Fistmas!
+ { }
+ `---'
+```
\ No newline at end of file