diff --git a/events/__init__.py b/events/__init__.py new file mode 100644 index 000000000..42a2ca7ea --- /dev/null +++ b/events/__init__.py @@ -0,0 +1,66 @@ +from os import path +import subprocess +from importlib import import_module + +from files.__main__ import app, db_session, engine +from flask import g +from sqlalchemy import inspect + +from files.helpers.const import AWARDS2, AWARDS_DISABLED + +from .table import Event +from .columns import * + +from events.classes import * +from events.helpers import * +from events.routes import * + +def link_assets(): + asset_dirs = { # We assume WD is always in root of repository + "files/assets/css": "../../../events/assets/css", + "files/assets/js": "../../../events/assets/js", + "files/assets/fonts": "../../../events/assets/fonts", + "files/assets/images": "../../../events/assets/images", + "files/assets/media": "../../../events/assets/media", + "files/templates": "../../events/templates", + } + + print("[EVENT] Linking event assets...") + + for link_dir in asset_dirs: + target = asset_dirs[link_dir] + link = link_dir + "/event" + + try: + if path.exists(link): + subprocess.run(["rm", link]) + + subprocess.run(["ln", "-s", target, link]) + print("[EVENT] Linked " + link + " -> " + target) + except Exception as e: + print(e) + +def build_table(): + if not inspect(engine).has_table("event", schema="public"): + print("[EVENT] Building event table...") + + with app.app_context(): + g.db = db_session() + + Event.__table__.create(bind=g.db.bind, checkfirst=True) + g.db.commit() + +def populate_awards(): + temp = {x: AWARDS2[x] for x in AWARDS2 if x not in EVENT_AWARDS} + AWARDS2.clear() + AWARDS2.update(EVENT_AWARDS) + AWARDS2.update(temp) + + for award in EVENT_AWARDS: + if award in AWARDS_DISABLED: + AWARDS_DISABLED.remove(award) + +def init_event(): + link_assets() + build_table() + populate_awards() diff --git a/events/assets/css/banner.css b/events/assets/css/banner.css new file mode 100644 index 000000000..a2656d65e --- /dev/null +++ b/events/assets/css/banner.css @@ -0,0 +1,224 @@ +/* text */ +#banner-halloween-title.life > tspan { + opacity: 1; +} +#banner-halloween-title-II { + text-shadow: 0 4px 10px #ff000060; +} +#banner-halloween-title.life > #banner-halloween-title-II { + animation: blinker 0.5s forwards; +} +@media (max-width: 767.98px) { + #banner-halloween-title { + transform: scale(1.4) translate(-90px, -120px); + animation:none !important; + } + #banner-halloween-presenting { + transform: scale(1.4) translate(-90px, -120px); + } + #banner-halloween-bats { + display:none; + } +} + +@keyframes float { + 0% { + transform: translateY(0px); + } + 50% { + transform: translateY(-6px); + } + 100% { + transform: translateY(0px); + } +} +@keyframes blinker { + 10% { + opacity: 0; + } + , + 30% { + opacity: 0.4; + } + , + 60% { + opacity: 0.2; + } + , + 85% { + opacity: 0.5; + } + , + 100% { + opacity: 0.9; + } +} + +/*days*/ +:root { + /*sky*/ + --sky-gradient-day1: radial-gradient(at bottom, #d43a27 25%, #761ab3 100%); + --sky-gradient-day2: radial-gradient(at bottom, #bf055c 25%, #6b007d 70%); + --sky-gradient-day3: radial-gradient(at bottom, #bf0583 5%, #560272 60%); + --sky-gradient-day4: radial-gradient(at bottom, #930184 -15%, #490272 60%); + --sky-gradient-day5: radial-gradient(at bottom, #800073 -55%, #400179 60%); + --sky-gradient-day6: radial-gradient(at bottom, #69017a 25%, #390271 70%); + --sky-gradient-day7: radial-gradient(at bottom, #69017a 25%, #2d005b 70%); + --sky-gradient-day8: radial-gradient(at bottom, #af00a6 -20%, #270146 70%); + --sky-gradient-day9: radial-gradient(at bottom, #69047b -10%, #1e0037 70%); + --sky-gradient-day10: radial-gradient(at bottom, #59047b 10%, #150026 70%); + + /*moon*/ + --moon-fill-day1:gold; + --moon-fill-day2:gold; + --moon-fill-day3:goldenrod; + --moon-fill-day4:none; + --moon-fill-day5:none; + --moon-fill-day6:#e4e4e4; + --moon-fill-day7:#e4e4e4; + --moon-fill-day8:#e4e4e4; + --moon-fill-day9:#e4e4e4; + --moon-fill-day10:#e4e4e4; + + --moon-shadow-day1:drop-shadow(0px 0px 20px yellow); + --moon-shadow-day2:drop-shadow(0px 0px 20px yellow); + --moon-shadow-day3:drop-shadow(0px 0px 20px gold); + --moon-shadow-day4:none; + --moon-shadow-day5:none; + --moon-shadow-day6:drop-shadow(0px 0px 5px #deddcf); + --moon-shadow-day7:drop-shadow(0px 0px 10px #deddcf); + --moon-shadow-day8:drop-shadow(0px 0px 10px #deddcf); + --moon-shadow-day9:drop-shadow(0px 0px 10px #deddcf); + --moon-shadow-day10:drop-shadow(0px 0px 10px #deddcf); + + --moon-position-day1:303; + --moon-position-day2:308; + --moon-position-day3:320; + --moon-position-day4:350; + --moon-position-day5:350; + --moon-position-day6:322; + --moon-position-day7:312; + --moon-position-day8:308; + --moon-position-day9:303; + --moon-position-day10:300; + + /*ground*/ + --ground-shadow-day1:#5818bd; + --ground-shadow-day2:#5818bd; + --ground-shadow-day3:#5818bd; + --ground-shadow-day4:#5818bd; + --ground-shadow-day5:#5818bd; + --ground-shadow-day6:#5818bd; + --ground-shadow-day7:#4e16a6; + --ground-shadow-day8:#51009a; + --ground-shadow-day9:#4b028c; + --ground-shadow-day10:#41017b; + + --house-shadow-day1:#5818bd; + --house-shadow-day2:#5818bd; + --house-shadow-day3:#5818bd; + --house-shadow-day4:#5818bd; + --house-shadow-day5:#5818bd; + --house-shadow-day6:#5818bd; + --house-shadow-day7:#5818bd; + --house-shadow-day8:#4a149f; + --house-shadow-day9:#431290; + --house-shadow-day10:#3a1476; + + --object-fill-day1:#240441; + --object-fill-day2:#240441; + --object-fill-day3:#240441; + --object-fill-day4:#240441; + --object-fill-day5:#240441; + --object-fill-day6:#240441; + --object-fill-day7:#240441; + --object-fill-day8:#1e0538; + --object-fill-day9:#18042c; + --object-fill-day10:#18042c; + + --star-opacity-day1: 0; + --star-opacity-day2: 0; + --star-opacity-day3: 0; + --star-opacity-day4: 0.2; + --star-opacity-day5: 0.3; + --star-opacity-day6: 0.4; + --star-opacity-day7: 0.5; + --star-opacity-day8: 0.5; + --star-opacity-day9: 0.6; + --star-opacity-day10: 0.7; +} + +/* stars */ +.star { + animation: linear infinite alternate twinkle; +} + +.star1 { + animation-duration: 3s; +} + +.star2 { + animation-duration: 4s; +} + +.star3 { + animation-duration: 3.5s; +} + +.star4 { + animation-duration: 2s; +} + +.star5 { + animation-duration: 4s; +} + +.star1 circle { + r: 0.5; +} +.star2 circle { + r: 0.75; +} +.star3 circle { + r: 1.0; +} +.star4 circle { + r: 1.2; +} +.star5 circle { + r: 1.5; +} + +@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 twinkle { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/events/assets/css/spooky.css b/events/assets/css/spooky.css new file mode 100644 index 000000000..e779ae4b6 --- /dev/null +++ b/events/assets/css/spooky.css @@ -0,0 +1,872 @@ +@charset "UTF-8"; + +/* Fonts */ +@import url("https://fonts.googleapis.com/css2?family=Creepster&display=swap"); + +@font-face { + font-family: "DoubleFeature"; + src: url("/assets/fonts/event/DoubleFeature.woff") format("woff"); +} + +@font-face { + font-family: "Jo_wrote_a_lovesong"; + src: url("/assets/fonts/event/Jo_wrote_a_lovesong.woff") format("woff"); +} + +@font-face { + font-family: "XTypewriter-Regular"; + src: url("/assets/fonts/event/XTypewriter-Regular.woff") format("woff"); +} + +@font-face { + font-family: "SpecialElite-Regular"; + src: url("/assets/fonts/event/SpecialElite-Regular.woff") format("woff"); +} + +/* Halloween Theming */ +:root { + --primary: #F66A3C; + --dark: #140224; + --secondary: #820263; + --white: #E1E1E1; + --black: #CFCFCF; + --light: #170535; + --muted: #E1E1E1; + --gray: #383838; + --gray-100: #E1E1E1; + --gray-200: #E1E1E1; + --gray-300: #291720; + --gray-400: #303030; + --gray-500: var(--dark); + --gray-600: var(--dark); + --gray-700: var(--dark); + --gray-800: var(--dark); + --gray-900: var(--dark); + --background: var(--dark); +} + +body { + overflow-x: hidden; +} + +#header--icon { + height: 33px; + width: 33px; + object-fit: contain; +} + +* { + border-color: var(--primary); +} + +a:hover.user-name { + cursor: url('/assets/images/event/machete.webp'), auto !important; +} + +.border { + border-color: var(--primary) !important; +} + +.form-control { + background: transparent; + border-color: var(--primary) !important; +} + +.btn { + background: transparent; + border-color: var(--primary) !important; + border-width: 2px; +} + +.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: 'SpecialElite-Regular'; + font-size: 1.25rem; +} + +.arrow-up::before, .arrow-down::before { + content: '\f720'; + width: 20px; +} + +.arrow-down::before { + display: inline-block; + transform: rotate(180deg); +} + +#thread .arrow-up::before, #thread .arrow-down::before { + content: '\f720'; + width: 17px; + } + +/* Cob Webs */ +body::before { + content: ''; + position: fixed; + background-image: url('/assets/images/event/cobweb-bl.webp'); + background-size: contain; + background-repeat: no-repeat; + left: -1.5rem; + bottom: -1.5rem; + width: 170px; + height: 230px; + z-index: 10001; + pointer-events: none; + transform: rotate(180deg); + opacity: .5; +} + +body::after { + content: ''; + position: fixed; + background-image: url('/assets/images/event/cobweb-tr.webp'); + background-size: contain; + background-repeat: no-repeat; + right: -1.5rem; + top: -1.5rem; + width: 160px; + height: 160px; + z-index: 10001; + pointer-events: none; + opacity: .45; +} + +/* Blood Effect */ +.blood::before { + content: ''; + position: absolute; + background-image: url('/assets/images/event/blood-anim.webp'); + width: 100%; + height: 55px; + background-repeat: repeat-x; + top: 0; + left: 0; +} + +.blood { + position: relative; +} + +.blood .comment-text { + color: #dc3545 !important; + font-family: 'DoubleFeature'; +} + +.sketch { + z-index: 10000; + position: fixed; + top: 0; + left: 0; + pointer-events: none; +} + +/* Haunted Effect */ +.haunt > div:not(.modal) { + animation: haunted 10s infinite; +} + +@keyframes haunted { + 0% { + backdrop-filter: brightness(20%); + } + 1% { + backdrop-filter: brightness(20%); + } + 2% { + backdrop-filter: sepia(0.8) contrast(1.5) brightness(200%); + } + 3% { + backdrop-filter: sepia(0.8) contrast(1.5) brightness(20%); + } + 4% { + backdrop-filter: brightness(300%); + } + 7% { + backdrop-filter: brightness(1); + } + 100% { + backdrop-filter: brightness(1); + } +} + +@keyframes haunted-upsidedown { + 0% { + backdrop-filter: brightness(20%) sepia(1) saturate(3) hue-rotate(180deg); + } + 1% { + backdrop-filter: brightness(20%) sepia(1) saturate(3) hue-rotate(180deg); + } + 2% { + backdrop-filter: sepia(1) contrast(1.5) brightness(200%) saturate(3) hue-rotate(180deg); + } + 3% { + backdrop-filter: sepia(1) contrast(1.5) brightness(20%) saturate(3) hue-rotate(180deg); + } + 4% { + backdrop-filter: brightness(300%) sepia(1) saturate(3) hue-rotate(180deg); + } + 7% { + backdrop-filter: brightness(1) sepia(1) saturate(3) hue-rotate(180deg); + } + 100% { + backdrop-filter: brightness(1) sepia(1) saturate(3) hue-rotate(180deg); + } +} + +/* Spiders */ +.spider:nth-child(odd) { + animation-name: swingFast; +} + +.spider:nth-child(2) { + animation-delay: 250ms; + animation-duration: 2100ms; + left: 20%; +} + +.spider:nth-child(3) { + animation-delay: 300ms; + animation-duration: 1600ms; + left: 30%; +} + +.spider:nth-child(4) { + animation-delay: 400ms; + animation-duration: 1800ms; + left: 40%; +} + +.spider:nth-child(5) { + animation-delay: 240ms; + animation-duration: 1900ms; + left: 50%; +} + +.spider:nth-child(6) { + animation-delay: 250ms; + animation-duration: 2300ms; + left: 60%; +} + +.spider:nth-child(7) { + animation-delay: 400ms; + animation-duration: 2100ms; + left: 70%; +} + +.spider:nth-child(8) { + animation-delay: 4000ms; + animation-duration: 200ms; + left: 80%; +} + +.spider { + z-index: 10; + position: fixed; + display: inline-block; + top: 0; + left: 10%; + + animation: swing 2s infinite; + transform-origin: top; + + transition: 0.8s ease-in-out; + pointer-events: none; +} + +.spider:hover .body { + transform: rotate(20deg); + transition: 0.4s ease-in-out; +} + +.spider:nth-child(odd):hover .body { + transform: rotate(-10deg); + transition: 0.2s ease-in-out; +} + +.spider .spiderweb { + width: 2px; + height: 200px; + margin-left: 49px; + background: rgba(255, 255, 255, 0.7); +} + +.spider .body { + width: 100px; + height: 80px; + background: #222; + position: relative; + border-radius: 50%; +} + +.spider .body .eye { + width: 28px; + height: 28px; + position: absolute; + bottom: 24px; + background: #fff; + border-radius: 50%; +} + +.spider .body .eye.left { + left: 20px; +} + +.spider .body .eye.right { + right: 20px; +} + +.spider .body .eye:after { + background: #222; + width: 7px; + height: 7px; + content: ""; + display: block; + margin: 55%; + border-radius: 50%; + + animation: look 4s infinite; +} + +.spider:nth-child(8) .body .eye { + background-color: #FF0000; + background: radial-gradient(#FF9B9B, #FF0000); +} + +.spider:nth-child(odd) .body .eye:after { + animation-delay: 1400ms; + animation-duration: 3600ms; +} + +.spider .legs .leg { + width: 80px; + height: 40px; + margin-top: -20px; + border: 5px solid transparent; + border-top-color: #333; + border-radius: 40px 40px 0 0; +} + +.spider .legs { + position: absolute; + bottom: -10%; + z-index: -1; +} + +.spider .legs.left { + left: -70%; +} +.spider .legs.right { + right: -60%; +} + +.legs.left .leg:nth-child(1) { + transform: rotate(10deg); + margin-left: 10px; +} +.legs.right .leg:nth-child(1) { + transform: rotate(-10deg); + margin-left: -10px; +} + +.legs.left .leg:nth-child(2) { + transform: rotate(-20deg); + margin-left: 20px; +} +.legs.right .leg:nth-child(2) { + transform: rotate(20deg); + margin-left: -20px; +} + +.legs.left .leg:nth-child(3) { + transform: rotate(-50deg); + margin-left: 30px; +} +.legs.right .leg:nth-child(3) { + transform: rotate(50deg); + margin-left: -30px; +} + +@keyframes look { + 0%, + 40%, + 100% { + transform: translateX(0); + } + + 45%, + 95% { + transform: translateX(-100%); + } +} + +@keyframes swing { + 0%, + 100% { + transform: translateY(0); + } + + 50% { + transform: translateY(-24px); + } +} + +@keyframes swingFast { + 0%, + 100% { + transform: translateY(0); + } + + 55% { + transform: translateY(-36px); + } +} + +/* Fog effect */ +.fog-effect { + opacity: 0.35; +} + +#fog-effect { + pointer-events: none; + position:fixed; + bottom:0; + left: 0; + width:100%; + height: 100%; + z-index: 1031; +} + +/* Eyes */ +.eye { + position: relative; + width: 26px; + height: 26px; +} + +/* Candy Corn */ +.candy-corn { + --color3: #FBED21; + --color2: #F66A3C; + --color1: #FDFBDA; + font-family: "Open Sans", sans-serif; + background: repeating-linear-gradient( + 45deg, + var(--color1), + var(--color1) 10px, + var(--color2) 20px, + var(--color2) 20px, + var(--color3) 60px, + var(--color3) 60px + ); + background-clip: text; + color: transparent; + -webkit-background-clip: text; + animation: 32s linear 0s infinite candycorn-move; +} + +.candy-corn:not(a) > p { + color: transparent !important; +} + +#post-title > a.candy-corn { + color: transparent; +} + +.candy-corn:hover { + animation-duration: 10s; +} + +@keyframes candycorn-move { + from { + background-position: 0px; + } + to { + background-position: 1000px; + } +} + +/* Ectoplasm */ +.ectoplasm { + text-shadow: 0 0 20px #3AE63A; +} + +.ectoplasm .comment-text > p, .ectoplasm .post-body, h1.ectoplasm { + font-family: 'Creepster'; + color: #90ee90; + letter-spacing: 0.15em; +} + +.ectoplasm .candy-corn { + --color3: rgb(140, 255, 0); + --color2: rgb(0, 111, 0); + --color1: rgb(131, 255, 131); + text-shadow: none; +} + +.ectoplasm.blood .comment-text > p { + font-family: 'DoubleFeature'; + letter-spacing: initial; +} + +.ectoplasm .rainbow-text > p { + color: #90ee90 !important; + font-weight: initial; +} + +.ectoplasm .comment-text, .ectoplasm .post-body, h1.ectoplasm { + overflow:visible !important; +} + +/* Upsidedown */ +#canvas { + position:absolute; + pointer-events:none; +} + +/* Bones */ +#animate{ + margin-left:45%; + margin-top:-5%; + position: fixed; + z-index:999; + pointer-events: none; + opacity:0.9; +} + +/* Pumpkin */ +.fall-pumpkin { + color: #fff; + font-size: 1em; + font-family: Serif; + text-shadow: 0 0 1px #000; + pointer-events: none; +} + +@-webkit-keyframes fall-pumpkins-fall { + 0% { + top: -20% + } + 100% { + top: 100% + } +} + +@-webkit-keyframes fall-pumpkins-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-pumpkins-fall { + 0% { + top: -20% + } + 100% { + top: 100% + } +} + +@keyframes fall-pumpkins-shake { + 0% { + transform: translateX(0px) + } + 50% { + transform: translateX(80px) + } + 100% { + transform: translateX(0px) rotate(360deg); + } +} + +.fall-pumpkin { + position: fixed; + top: -20%; + z-index: 999; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: default; + -webkit-animation-name: fall-pumpkins-fall, fall-pumpkins-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-pumpkins-fall, fall-pumpkins-shake; + animation-duration: 10s, 4s; + animation-timing-function: linear, ease-in-out; + animation-iteration-count: infinite, infinite; + animation-play-state: running, running +} + +.fall-pumpkin:nth-of-type(0) { + left: 1%; + -webkit-animation-delay: 0s, 0s; + animation-delay: 0s, 0s +} +.fall-pumpkin:nth-of-type(1) { + left: 10%; + -webkit-animation-delay: 1s, 1s; + animation-delay: 1s, 1s +} +.fall-pumpkin:nth-of-type(2) { + left: 20%; + -webkit-animation-delay: 6s, .5s; + animation-delay: 6s, .5s +} +.fall-pumpkin:nth-of-type(3) { + left: 30%; + -webkit-animation-delay: 4s, 2s; + animation-delay: 4s, 2s +} +.fall-pumpkin:nth-of-type(4) { + left: 40%; + -webkit-animation-delay: 2s, 2s; + animation-delay: 2s, 2s +} +.fall-pumpkin:nth-of-type(5) { + left: 50%; + -webkit-animation-delay: 8s, 3s; + animation-delay: 8s, 3s +} +.fall-pumpkin:nth-of-type(6) { + left: 60%; + -webkit-animation-delay: 6s, 2s; + animation-delay: 6s, 2s +} +.fall-pumpkin:nth-of-type(7) { + left: 70%; + -webkit-animation-delay: 2.5s, 1s; + animation-delay: 2.5s, 1s +} +.fall-pumpkin:nth-of-type(8) { + left: 80%; + -webkit-animation-delay: 1s, 0s; + animation-delay: 1s, 0s +} +.fall-pumpkin:nth-of-type(9) { + left: 90%; + -webkit-animation-delay: 3s, 1.5s; + animation delay: 3s, 1.5s +} +.fall-pumpkin:nth-of-type(10) { + left: 100%; + -webkit-animation-delay: 3s, 2s; + animation-delay: 3s, 2s +} +.fall-pumpkin:nth-of-type(11) { + left: 5%; + -webkit-animation-delay: 1s, 4s; + animation-delay: 1s, 4s +} +.fall-pumpkin:nth-of-type(12) { + left: 15%; + -webkit-animation-delay: 1s, 1.5s; + animation-delay: 1s, 1.5s +} +.fall-pumpkin:nth-of-type(13) { + left: 25%; + -webkit-animation-delay: 6s, 2.5s; + animation-delay: 6s, 2.5s +} +.fall-pumpkin:nth-of-type(14) { + left: 35%; + -webkit-animation-delay: 4s, 1s; + animation-delay: 4s, 1s +} +.fall-pumpkin:nth-of-type(15) { + left: 45%; + -webkit-animation-delay: 2s, 4s; + animation-delay: 2s, 4s +} +.fall-pumpkin:nth-of-type(16) { + left: 55%; + -webkit-animation-delay: 8s, 3s; + animation-delay: 8s, 3s +} +.fall-pumpkin:nth-of-type(17) { + left: 65%; + -webkit-animation-delay: 6s, 3s; + animation-delay: 6s, 3s +} +.fall-pumpkin:nth-of-type(18) { + left: 75%; + -webkit-animation-delay: 2.5s, 4s; + animation-delay: 2.5s, 4s +} +.fall-pumpkin:nth-of-type(19) { + left: 85%; + -webkit-animation-delay: 2s, 0s; + animation-delay: 2s, 0s +} +.fall-pumpkin: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); + } +} + +/* Trick or Treat */ +#trick-or-treat { + font-family: Jo_wrote_a_lovesong; + font-size: 2rem; + letter-spacing: 0.5rem; + border-color: var(--primary) !important; +} + +#trick-or-treat::before { + content:""; + background-image:url('/e/marseyface.webp'); ; + background-size: cover; + height:28px; + width:32px; + display:inline-block; +} + +#trick-or-treat::after { + content:""; + background-image:url('/e/marseytrickortreat.webp'); ; + background-size: cover; + height:28px; + width:32px; + display:inline-block; +} + +#jump-scare-img { + position: fixed; + left: 0; + top: 0; + height: 100%; + width: 100%; + z-index: 9999; + object-fit: cover; + pointer-events: none; + } + +/* progressbar */ +.progress { + background-color: #1d9bf0; + background-image: linear-gradient(0deg, #1d9bf0 0%, #59b1ec 100%); + width: 270px; + height: 24px; + border-radius: 4px; + box-shadow: inset 0px 12px 2px #ffffff10; + backdrop-filter: blur(2px) brightness(101%); + margin-bottom: 40px; +} + +.progress::before { + content: "\f48e"; + font-family: "Font Awesome 6 Pro"; + position: absolute; + left: 6px; + top: 2px; + font-size: 13px; + color: #fff; +} +.progress::after { + content: "\f780"; + font-family: "Font Awesome 6 Pro"; + position: absolute; + right: 6px; + top: 2px; + font-size: 13px; + color: #fff; +} + +.progress > .legend { + display: flex; + justify-content: space-between; + margin-top: 6px; + padding: 0 6px; + color: #dc3545; + font-family: -apple-system,BlinkMacSystemFont,segoe ui,Helvetica,Arial,sans-serif,apple color emoji,segoe ui emoji,segoe ui symbol; + font-size: 12px; + font-weight: bold; +} + +.progress > .legend span:nth-child(1) { + color: #d3bc00; +} + +.bar-left { + display: inline-block; + width: var(--width); + height: 24px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + background-color: #d3bc00; + background-image: linear-gradient(180deg, #d3bc00 50%, #877800 100%); + box-shadow: inset 0px 12px 2px #ffffff20; + color: white; + text-align: center; +} + +.bar-right { + display: inline-block; + width: var(--width); + height: 24px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + background-color: #dc3545; + background-image: linear-gradient(180deg, #dc3545 50%, #9e1b32 100%); + box-shadow: inset 2px 12px 0px #ffffff20; + color: white; + text-align: center; + position: absolute; + right: 0; +} diff --git a/events/assets/css/upsidedown.css b/events/assets/css/upsidedown.css new file mode 100644 index 000000000..8bcf69d58 --- /dev/null +++ b/events/assets/css/upsidedown.css @@ -0,0 +1,56 @@ +/* tag 'background-color' is boilerplate here. We only care about the box-shadow and filter effects. We can add a woods background-image for added effect. */ + +body { + background-size: cover; + background-attachment: fixed; + background-color: #000; + filter: sepia(100%) hue-rotate(180deg) saturate(300%); + box-shadow: 0 0 900px rgba(0, 0, 0, 0.9) inset; + overflow-x: hidden; +} + +canvas.particles { + pointer-events: none; + position: fixed; + left: 0; + top: 0; + z-index: 1; + filter: blur(1.5px); + animation: flicker 4s infinite; +} + +@keyframes flicker { + 0% { + filter: brightness(30%); + } + 48% { + filter: brightness(30%); + } + 50% { + filter: contrast(1.5) brightness(40%); + } + 60% { + filter: contrast(1.5) brightness(40%); + } + 62% { + filter: brightness(30%); + } + 78% { + filter: brightness(20%); + } + 84% { + filter: brightness(40%); + } + 88% { + filter: brightness(30%); + } + 96% { + filter: brightness(80%); + } + 98% { + filter: brightness(30%); + } + 100% { + filter: brightness(90%); + } +} diff --git a/events/assets/fonts/DoubleFeature.woff b/events/assets/fonts/DoubleFeature.woff new file mode 100644 index 000000000..ec42c9a5b Binary files /dev/null and b/events/assets/fonts/DoubleFeature.woff differ diff --git a/events/assets/fonts/Jo_wrote_a_lovesong.woff b/events/assets/fonts/Jo_wrote_a_lovesong.woff new file mode 100644 index 000000000..986b74160 Binary files /dev/null and b/events/assets/fonts/Jo_wrote_a_lovesong.woff differ diff --git a/events/assets/fonts/SpecialElite-Regular.woff b/events/assets/fonts/SpecialElite-Regular.woff new file mode 100644 index 000000000..c32b2a007 Binary files /dev/null and b/events/assets/fonts/SpecialElite-Regular.woff differ diff --git a/events/assets/fonts/Unutterable.woff b/events/assets/fonts/Unutterable.woff new file mode 100644 index 000000000..fae2f6aaa Binary files /dev/null and b/events/assets/fonts/Unutterable.woff differ diff --git a/events/assets/fonts/XTypewriter-Regular.woff b/events/assets/fonts/XTypewriter-Regular.woff new file mode 100644 index 000000000..f0b3d36bd Binary files /dev/null and b/events/assets/fonts/XTypewriter-Regular.woff differ diff --git a/events/assets/images/agendaposter/1.webp b/events/assets/images/agendaposter/1.webp new file mode 100644 index 000000000..b3362f36f Binary files /dev/null and b/events/assets/images/agendaposter/1.webp differ diff --git a/events/assets/images/agendaposter/10.webp b/events/assets/images/agendaposter/10.webp new file mode 100644 index 000000000..260db4baa Binary files /dev/null and b/events/assets/images/agendaposter/10.webp differ diff --git a/events/assets/images/agendaposter/11.webp b/events/assets/images/agendaposter/11.webp new file mode 100644 index 000000000..2a92c4577 Binary files /dev/null and b/events/assets/images/agendaposter/11.webp differ diff --git a/events/assets/images/agendaposter/12.webp b/events/assets/images/agendaposter/12.webp new file mode 100644 index 000000000..b51fa12ec Binary files /dev/null and b/events/assets/images/agendaposter/12.webp differ diff --git a/events/assets/images/agendaposter/13.webp b/events/assets/images/agendaposter/13.webp new file mode 100644 index 000000000..f18ebc634 Binary files /dev/null and b/events/assets/images/agendaposter/13.webp differ diff --git a/events/assets/images/agendaposter/14.webp b/events/assets/images/agendaposter/14.webp new file mode 100644 index 000000000..f1e66a64f Binary files /dev/null and b/events/assets/images/agendaposter/14.webp differ diff --git a/events/assets/images/agendaposter/15.webp b/events/assets/images/agendaposter/15.webp new file mode 100644 index 000000000..39ba39244 Binary files /dev/null and b/events/assets/images/agendaposter/15.webp differ diff --git a/events/assets/images/agendaposter/16.webp b/events/assets/images/agendaposter/16.webp new file mode 100644 index 000000000..6e5f87977 Binary files /dev/null and b/events/assets/images/agendaposter/16.webp differ diff --git a/events/assets/images/agendaposter/17.webp b/events/assets/images/agendaposter/17.webp new file mode 100644 index 000000000..7f8fffa95 Binary files /dev/null and b/events/assets/images/agendaposter/17.webp differ diff --git a/events/assets/images/agendaposter/18.webp b/events/assets/images/agendaposter/18.webp new file mode 100644 index 000000000..0981cc483 Binary files /dev/null and b/events/assets/images/agendaposter/18.webp differ diff --git a/events/assets/images/agendaposter/19.webp b/events/assets/images/agendaposter/19.webp new file mode 100644 index 000000000..92376f495 Binary files /dev/null and b/events/assets/images/agendaposter/19.webp differ diff --git a/events/assets/images/agendaposter/2.webp b/events/assets/images/agendaposter/2.webp new file mode 100644 index 000000000..85365ef14 Binary files /dev/null and b/events/assets/images/agendaposter/2.webp differ diff --git a/events/assets/images/agendaposter/3.webp b/events/assets/images/agendaposter/3.webp new file mode 100644 index 000000000..24679eaaf Binary files /dev/null and b/events/assets/images/agendaposter/3.webp differ diff --git a/events/assets/images/agendaposter/4.webp b/events/assets/images/agendaposter/4.webp new file mode 100644 index 000000000..1f0f990b7 Binary files /dev/null and b/events/assets/images/agendaposter/4.webp differ diff --git a/events/assets/images/agendaposter/5.webp b/events/assets/images/agendaposter/5.webp new file mode 100644 index 000000000..ee3a8b345 Binary files /dev/null and b/events/assets/images/agendaposter/5.webp differ diff --git a/events/assets/images/agendaposter/6.webp b/events/assets/images/agendaposter/6.webp new file mode 100644 index 000000000..e7a07b52f Binary files /dev/null and b/events/assets/images/agendaposter/6.webp differ diff --git a/events/assets/images/agendaposter/7.webp b/events/assets/images/agendaposter/7.webp new file mode 100644 index 000000000..ac5e4603b Binary files /dev/null and b/events/assets/images/agendaposter/7.webp differ diff --git a/events/assets/images/agendaposter/8.webp b/events/assets/images/agendaposter/8.webp new file mode 100644 index 000000000..aa592f338 Binary files /dev/null and b/events/assets/images/agendaposter/8.webp differ diff --git a/events/assets/images/agendaposter/9.webp b/events/assets/images/agendaposter/9.webp new file mode 100644 index 000000000..51a7d4b28 Binary files /dev/null and b/events/assets/images/agendaposter/9.webp differ diff --git a/events/assets/images/blood-anim.webp b/events/assets/images/blood-anim.webp new file mode 100644 index 000000000..c511faa3f Binary files /dev/null and b/events/assets/images/blood-anim.webp differ diff --git a/events/assets/images/cobweb-bl.webp b/events/assets/images/cobweb-bl.webp new file mode 100644 index 000000000..4b19cf162 Binary files /dev/null and b/events/assets/images/cobweb-bl.webp differ diff --git a/events/assets/images/cobweb-tr.webp b/events/assets/images/cobweb-tr.webp new file mode 100644 index 000000000..16873a7f4 Binary files /dev/null and b/events/assets/images/cobweb-tr.webp differ diff --git a/events/assets/images/eco/blood.webp b/events/assets/images/eco/blood.webp new file mode 100644 index 000000000..a9aa4c5a0 Binary files /dev/null and b/events/assets/images/eco/blood.webp differ diff --git a/events/assets/images/eco/flashlight.webp b/events/assets/images/eco/flashlight.webp new file mode 100644 index 000000000..8d72b97da Binary files /dev/null and b/events/assets/images/eco/flashlight.webp differ diff --git a/events/assets/images/eco/fog.webp b/events/assets/images/eco/fog.webp new file mode 100644 index 000000000..55bba55b7 Binary files /dev/null and b/events/assets/images/eco/fog.webp differ diff --git a/events/assets/images/eye.webp b/events/assets/images/eye.webp new file mode 100644 index 000000000..68fb609b0 Binary files /dev/null and b/events/assets/images/eye.webp differ diff --git a/events/assets/images/jumpscares/1.webp b/events/assets/images/jumpscares/1.webp new file mode 100644 index 000000000..6a1133423 Binary files /dev/null and b/events/assets/images/jumpscares/1.webp differ diff --git a/events/assets/images/jumpscares/3.webp b/events/assets/images/jumpscares/3.webp new file mode 100644 index 000000000..b6adabe4c Binary files /dev/null and b/events/assets/images/jumpscares/3.webp differ diff --git a/events/assets/images/machete.webp b/events/assets/images/machete.webp new file mode 100644 index 000000000..c5098b8b3 Binary files /dev/null and b/events/assets/images/machete.webp differ diff --git a/events/assets/images/pcm.webp b/events/assets/images/pcm.webp new file mode 100644 index 000000000..8f383ae4d Binary files /dev/null and b/events/assets/images/pcm.webp differ diff --git a/events/assets/images/ricardo.webp b/events/assets/images/ricardo.webp new file mode 100644 index 000000000..2362ee244 Binary files /dev/null and b/events/assets/images/ricardo.webp differ diff --git a/events/assets/images/ricardo2.webp b/events/assets/images/ricardo2.webp new file mode 100644 index 000000000..004cb3d99 Binary files /dev/null and b/events/assets/images/ricardo2.webp differ diff --git a/events/assets/images/ricardo3.webp b/events/assets/images/ricardo3.webp new file mode 100644 index 000000000..ed58c42df Binary files /dev/null and b/events/assets/images/ricardo3.webp differ diff --git a/events/assets/images/sidebar/1.webp b/events/assets/images/sidebar/1.webp new file mode 100644 index 000000000..9066f22a3 Binary files /dev/null and b/events/assets/images/sidebar/1.webp differ diff --git a/events/assets/images/sidebar/2.webp b/events/assets/images/sidebar/2.webp new file mode 100644 index 000000000..d53dac38e Binary files /dev/null and b/events/assets/images/sidebar/2.webp differ diff --git a/events/assets/images/sidebar/3.webp b/events/assets/images/sidebar/3.webp new file mode 100644 index 000000000..b1f2a52c2 Binary files /dev/null and b/events/assets/images/sidebar/3.webp differ diff --git a/events/assets/images/sidebar/4.webp b/events/assets/images/sidebar/4.webp new file mode 100644 index 000000000..ae7d4d84c Binary files /dev/null and b/events/assets/images/sidebar/4.webp differ diff --git a/events/assets/images/sidebar/5.webp b/events/assets/images/sidebar/5.webp new file mode 100644 index 000000000..bddfcc89c Binary files /dev/null and b/events/assets/images/sidebar/5.webp differ diff --git a/events/assets/images/sidebar/6.webp b/events/assets/images/sidebar/6.webp new file mode 100644 index 000000000..8613c9707 Binary files /dev/null and b/events/assets/images/sidebar/6.webp differ diff --git a/events/assets/images/skeletons/skeleton1.webp b/events/assets/images/skeletons/skeleton1.webp new file mode 100644 index 000000000..8bbf7d7c0 Binary files /dev/null and b/events/assets/images/skeletons/skeleton1.webp differ diff --git a/events/assets/images/skeletons/skeleton2.webp b/events/assets/images/skeletons/skeleton2.webp new file mode 100644 index 000000000..9821bec66 Binary files /dev/null and b/events/assets/images/skeletons/skeleton2.webp differ diff --git a/events/assets/images/skeletons/skeleton3.webp b/events/assets/images/skeletons/skeleton3.webp new file mode 100644 index 000000000..5914c1a71 Binary files /dev/null and b/events/assets/images/skeletons/skeleton3.webp differ diff --git a/events/assets/images/skeletons/skeleton4.webp b/events/assets/images/skeletons/skeleton4.webp new file mode 100644 index 000000000..3d675b35d Binary files /dev/null and b/events/assets/images/skeletons/skeleton4.webp differ diff --git a/events/assets/images/skeletons/skeleton5.webp b/events/assets/images/skeletons/skeleton5.webp new file mode 100644 index 000000000..8f341aa31 Binary files /dev/null and b/events/assets/images/skeletons/skeleton5.webp differ diff --git a/events/assets/images/skeletons/skeleton6.webp b/events/assets/images/skeletons/skeleton6.webp new file mode 100644 index 000000000..2515e6aa3 Binary files /dev/null and b/events/assets/images/skeletons/skeleton6.webp differ diff --git a/events/assets/images/smoke.webp b/events/assets/images/smoke.webp new file mode 100644 index 000000000..ac3bb3327 Binary files /dev/null and b/events/assets/images/smoke.webp differ diff --git a/events/assets/images/zombies/1.webp b/events/assets/images/zombies/1.webp new file mode 100644 index 000000000..6f0ceec12 Binary files /dev/null and b/events/assets/images/zombies/1.webp differ diff --git a/events/assets/images/zombies/10.webp b/events/assets/images/zombies/10.webp new file mode 100644 index 000000000..8e5bdcf9e Binary files /dev/null and b/events/assets/images/zombies/10.webp differ diff --git a/events/assets/images/zombies/2.webp b/events/assets/images/zombies/2.webp new file mode 100644 index 000000000..e3958e640 Binary files /dev/null and b/events/assets/images/zombies/2.webp differ diff --git a/events/assets/images/zombies/3.webp b/events/assets/images/zombies/3.webp new file mode 100644 index 000000000..5c679389a Binary files /dev/null and b/events/assets/images/zombies/3.webp differ diff --git a/events/assets/images/zombies/4.webp b/events/assets/images/zombies/4.webp new file mode 100644 index 000000000..5b03ba332 Binary files /dev/null and b/events/assets/images/zombies/4.webp differ diff --git a/events/assets/images/zombies/5.webp b/events/assets/images/zombies/5.webp new file mode 100644 index 000000000..7db37a694 Binary files /dev/null and b/events/assets/images/zombies/5.webp differ diff --git a/events/assets/images/zombies/6.webp b/events/assets/images/zombies/6.webp new file mode 100644 index 000000000..9b588222c Binary files /dev/null and b/events/assets/images/zombies/6.webp differ diff --git a/events/assets/images/zombies/7.webp b/events/assets/images/zombies/7.webp new file mode 100644 index 000000000..86b2ce7b9 Binary files /dev/null and b/events/assets/images/zombies/7.webp differ diff --git a/events/assets/images/zombies/8.webp b/events/assets/images/zombies/8.webp new file mode 100644 index 000000000..fcdf0f776 Binary files /dev/null and b/events/assets/images/zombies/8.webp differ diff --git a/events/assets/images/zombies/9.webp b/events/assets/images/zombies/9.webp new file mode 100644 index 000000000..b22063054 Binary files /dev/null and b/events/assets/images/zombies/9.webp differ diff --git a/events/assets/js/banner-debug.js b/events/assets/js/banner-debug.js new file mode 100644 index 000000000..98534a5c2 --- /dev/null +++ b/events/assets/js/banner-debug.js @@ -0,0 +1,26 @@ +function setBannerDay(day){ + let sky = document.getElementById("banner-halloween-svg"), + moon = document.getElementById("banner-halloween-moon"), + house = document.getElementById("house-fill-gradient-stop"), + ground = document.getElementById("ground-gradient-stop"), + objects = document.getElementById("banner-halloween-objects"), + stars = document.getElementById("banner-halloween-stars") + + sky.style.backgroundImage = "var(--sky-gradient-day"+day+")" + moon.style.fill = "var(--moon-fill-day"+day+")" + moon.style.filter = "var(--moon-shadow-day"+day+")" + moon.style.cy = "var(--moon-position-day"+day+")" + house.style.stopColor = "var(--house-shadow-day"+day+")" + ground.style.stopColor = "var(--ground-shadow-day"+day+")" + objects.style.fill = "var(--object-fill-day"+day+")" + stars.style.opacity = "var(--star-opacity-day"+day+")" +} + +function cycleBanner(){ + i=1 + asdf = setInterval(function(){ + setBannerDay(i) + if (i > 9){clearInterval(asdf)} + i++ + }, 250) +} diff --git a/events/assets/js/banner.js b/events/assets/js/banner.js new file mode 100644 index 000000000..e4be65caf --- /dev/null +++ b/events/assets/js/banner.js @@ -0,0 +1,13 @@ +const el = document.getElementById("banner-halloween-title"); + +function animateBannerText() { + const letters = el.getElementsByTagName("tspan"); + + for (let i = 0; i < letters.length; i++) { + letters.item(i).style.transition = `all 600ms ${600 + i * 40}ms`; + } + + setTimeout(() => el.classList.add("life"), 1000); +} + +animateBannerText(); \ No newline at end of file diff --git a/events/assets/js/blood.js b/events/assets/js/blood.js new file mode 100644 index 000000000..aab76e16e --- /dev/null +++ b/events/assets/js/blood.js @@ -0,0 +1,51 @@ +/* + A Bloody Mess by Rob Glazebrook + By default, canvas does not clear between frames. I'm taking advantage of that to create the running blood effect. + This pen was inspired by Katy Decorah's BLOOD: https://codepen.io/katydecorah/pen/Lkogi +*/ + + +var i = 0; + +var blood = Sketch.create({autoclear: false, autopause: false}), + drops = [], + dropCount = stabs*10, + maxDrops = dropCount+1, + Drop = function() { + this.x = random(0,blood.width); + this.radius = random(10,20); + this.y = -this.radius - random(50,100); + this.vy = this.radius/6; + this.r = ~~random(240,255); + this.g = ~~random(0,20); + this.b = ~~random(0,20); + }; + +blood.update = function() { + var d = drops.length; + while(d < dropCount && i < maxDrops) { + var drop = new Drop(); + drops.push(drop); + d++; + i++; + } + while(d-- && i < maxDrops) { + var drop = drops[d]; + drop.y += drop.vy; + if(drop.y - drop.radius > blood.height) { + drops.splice(d,1); + } + } +} + +blood.draw = function() { + var d = drops.length; + while(d-- && i < maxDrops) { + var drop = drops[d]; + blood.beginPath(); + blood.fillStyle = 'rgba('+drop.r+','+drop.g+','+drop.b+',.8)'; + blood.arc(drop.x,drop.y,drop.radius,0,TWO_PI); + blood.fill(); + } +} + diff --git a/events/assets/js/bones.js b/events/assets/js/bones.js new file mode 100644 index 000000000..6f4bc9045 --- /dev/null +++ b/events/assets/js/bones.js @@ -0,0 +1,75 @@ +function bones(number){ + var container = document.getElementById('animate'); + + // Stackable + // With each award, append a new image to array + const sources = ['skeleton1.webp','skeleton2.webp','skeleton3.webp','skeleton4.webp','skeleton5.webp','skeleton6.webp']; + + if(number > sources.length){ + number = sources.length + } + + const n = sources.length - number, + emoji = sources.slice(n), + pw = screen.availWidth/6 + + let circles = []; + + for (var i = 0; i < 3; i++) { + addCircle(i * 150, [10 + 0, pw], emoji[Math.floor(Math.random() * emoji.length)]); + addCircle(i * 150, [10 + 0, -pw], emoji[Math.floor(Math.random() * emoji.length)]); + addCircle(i * 150, [10 - (0.5*pw), -pw], emoji[Math.floor(Math.random() * emoji.length)]); + addCircle(i * 150, [10 + (0.5*pw), pw], emoji[Math.floor(Math.random() * emoji.length)]); + addCircle(i * 150, [10 - (1.5*pw), -pw], emoji[Math.floor(Math.random() * emoji.length)]); + addCircle(i * 150, [10 + (1.5*pw), pw], emoji[Math.floor(Math.random() * emoji.length)]); + } + + + function addCircle(delay, range, color) { + setTimeout(function() { + var c = new Circle(range[0] + Math.random() * range[1], 80 + Math.random() * 4, color, { + x: -0.15 + Math.random() * 0.3, + y: 1 + Math.random() * 1 + }, range); + circles.push(c); + }, delay); + } + + function Circle(x, y, c, v, range) { + var _this = this; + this.x = x; + this.y = y; + this.color = c; + this.v = v; + this.range = range; + this.element = document.createElement('img'); + /*this.element.style.display = 'block';*/ + this.element.style.opacity = 0; + this.element.style.position = 'absolute'; + this.element.style.height = '3rem'; + this.element.src = "/assets/images/event/skeletons/"+c; + container.appendChild(this.element); + + this.update = function() { + if (_this.y > window.innerHeight) { + _this.y = 80 + Math.random() * 4; + _this.x = _this.range[0] + Math.random() * _this.range[1]; + } + _this.y += _this.v.y; + _this.x += _this.v.x; + this.element.style.opacity = 1; + this.element.style.transform = 'translate3d(' + _this.x + 'px, ' + _this.y + 'px, 0px)'; + this.element.style.webkitTransform = 'translate3d(' + _this.x + 'px, ' + _this.y + 'px, 0px)'; + this.element.style.mozTransform = 'translate3d(' + _this.x + 'px, ' + _this.y + 'px, 0px)'; + }; + } + + function animate() { + for (var i in circles) { + circles[i].update(); + } + requestAnimationFrame(animate); + } + + animate(); +} diff --git a/events/assets/js/eye-tracking.js b/events/assets/js/eye-tracking.js new file mode 100644 index 000000000..fd6b13afb --- /dev/null +++ b/events/assets/js/eye-tracking.js @@ -0,0 +1,42 @@ +if (innerWidth >= 992) +{ + /*init*/ + let sidebar = document.getElementById("main-content-row") + sidebar = sidebar.getElementsByClassName("sidebar")[0].firstElementChild + + const eye_left = sidebar.getElementsByClassName("eye")[0], + eye_right = sidebar.getElementsByClassName("eye")[1] + + /*eye movement*/ + document.onmousemove = function(event) { + let click = {x: event.clientX, y: event.clientY}, + /*recalculating eye position on every mousemove is less efficient + but ensures eyes track properly upon pageload even if script doesnt fire*/ + eye_left_center = getCenter(eye_left), + eye_right_center = getCenter(eye_right) + + eye_left.style.transform = 'rotate('+getAngle(click, eye_left_center)+'rad)' + eye_right.style.transform = 'rotate('+getAngle(click, eye_right_center)+'rad)' + } + + function getCenter(element) { + const bounds = element.getBoundingClientRect() + + let centerX = bounds["left"] + bounds["width"]/2, + centerY = bounds["top"] + bounds["height"]/2 + + return({x: centerX, y: centerY}) + } + + function getAngle(point1, point2) { + let x = point1["x"] - point2["x"], + y = point1["y"] - point2["y"], + angle = Math.atan(y/x) + + if(point1["x"] < point2["x"]) { + angle += Math.PI + } + + return(angle) + } +} diff --git a/events/assets/js/flashlight.js b/events/assets/js/flashlight.js new file mode 100644 index 000000000..db1a2d8bc --- /dev/null +++ b/events/assets/js/flashlight.js @@ -0,0 +1,30 @@ +// Original codepen: https://codepen.io/Coding-Artist/pen/ExLyRJg + +let mouseX = 0; +let mouseY = 0; + +// Detect touch device +const isTouchDevice = () => { + try { + // We try to create TouchEvent (it would fail for desktops and throw error) + document.createEvent("TouchEvent"); + return true; + } catch (e) { + return false; + } +}; +function getMousePosition(e) { + try { + // Get position of mouse or touch + mouseX = !isTouchDevice() ? e.clientX : e.touches[0].clientX; + mouseY = !isTouchDevice() ? e.clientY : e.touches[0].clientY; + + // Set the Xpos and Ypos variables to current mouse/touch position + document.getElementById("flashlight-effect").style.setProperty("--Xpos", mouseX + "px"); +document.getElementById("flashlight-effect").style.setProperty("--Ypos", mouseY + "px"); + } catch (e) {} +} + +// Update mouse position on mouse move / touch move +document.addEventListener("mousemove", getMousePosition); +document.addEventListener("touchmove", getMousePosition); diff --git a/events/assets/js/fog.js b/events/assets/js/fog.js new file mode 100644 index 000000000..b3934018e --- /dev/null +++ b/events/assets/js/fog.js @@ -0,0 +1,139 @@ +console.clear(); + +canvasWidth = 1600; +canvasHeight = 200; + +pCount = 0; + + +pCollection = new Array(); + +var puffs = 1; +var particlesPerPuff = 1000; +var img = '/assets/images/event/smoke.webp'; + +var smokeImage = new Image(); +smokeImage.src = img; + +for (var i1 = 0 ; i1 < puffs; i1++) +{ + var puffDelay = i1 * 1500; //300 ms between puffs + + for (var i2 = 0 ; i2 < particlesPerPuff; i2++) + { + addNewParticle((i2*50) + puffDelay); + } +} + + +draw(new Date().getTime(), 3000) + + + +function addNewParticle(delay) +{ + + var p = {}; + p.top = canvasHeight; + p.left = randBetween(-200,800); + + p.start = new Date().getTime() + delay; + p.life = 16000; + p.speedUp = 30; + + + p.speedRight = randBetween(0,20); + + p.rot = randBetween(-1,1); + p.red = Math.floor(randBetween(0,255)); + p.blue = Math.floor(randBetween(0,255)); + p.green = Math.floor(randBetween(0,255)); + + + p.startOpacity = .3 + p.newTop = p.top; + p.newLeft = p.left; + p.size = 200; + p.growth = 10; + + pCollection[pCount] = p; + pCount++; + + +} + +function draw(startT, totalT) +{ + //Timing + var timeDelta = new Date().getTime() - startT; + var stillAlive = false; + + //Grab and clear the canvas + var c=document.getElementById("fog-effect"); + var ctx=c.getContext("2d"); + ctx.clearRect(0, 0, c.width, c.height); + c.width = c.width; + + //Loop through particles + for (var i= 0; i < pCount; i++) + { + //Grab the particle + var p = pCollection[i]; + + //Timing + var td = new Date().getTime() - p.start; + var frac = td/p.life + + if (td > 0) + { + if (td <= p.life ) + { stillAlive = true; } + + //attributes that change over time + var newTop = p.top - (p.speedUp * (td/1000)); + var newLeft = p.left + (p.speedRight * (td/1000)); + var newOpacity = Math.max(p.startOpacity * (1-frac),0); + + var newSize = p.size + (p.growth * (td/1000)); + p.newTop = newTop; + p.newLeft = newLeft; + + //Draw! + ctx.fillStyle = 'rgba(150,150,150,' + newOpacity + ')'; + ctx.globalAlpha = newOpacity; + ctx.drawImage(smokeImage, newLeft, newTop, newSize, newSize); + } + } + + + + //Repeat if there's still a living particle + if (stillAlive) + { + requestAnimationFrame(function(){draw(startT,totalT);}); + } + else + { + clog(timeDelta + ": stopped"); + } +} + +function randBetween(n1,n2) +{ + var r = (Math.random() * (n2 - n1)) + n1; + return r; +} + +function randOffset(n, variance) +{ + //e.g. variance could be 0.1 to go between 0.9 and 1.1 + var max = 1 + variance; + var min = 1 - variance; + var r = Math.random() * (max - min) + min; + return n * r; +} + +function clog(s) +{ + console.log(s); +} diff --git a/events/assets/js/haunted.js b/events/assets/js/haunted.js new file mode 100644 index 000000000..629c5f4b3 --- /dev/null +++ b/events/assets/js/haunted.js @@ -0,0 +1,45 @@ +const thunder1 = new Audio(`/assets/media/event/haunted/thunder1.mp3`), + thunder2 = new Audio(`/assets/media/event/haunted/thunder2.mp3`), + stylesheet_haunted = document.createElement("STYLE"), + is_upsidedown = localStorage.getItem('setting_upsidedown'), + div = document.getElementById("haunted-effect") + +window.onload = function(){ + temp = document.createTextNode("#banner-halloween-title {opacity:0;}#banner-halloween-text-evil {opacity:1!important;}img {filter: invert(1);}") + stylesheet_haunted.appendChild(temp) + document.head.appendChild(stylesheet_haunted) + stylesheet_haunted.disabled = true + + thunder2.volume = 0.5 + + lightningStrike("normal") +} + +setInterval(function(){ + if(Math.floor(Math.random()*3) > 1){ + lightningStrike("haunted") + } else { + lightningStrike("normal") + } +},14000) + +function lightningStrike(strike) { + if(is_upsidedown == 'true'){ + div.style.animation = "haunted-upsidedown 20s" + } else { + div.style.animation = "haunted 20s" + } + + if(strike == "haunted"){ + stylesheet_haunted.disabled = false + thunder2.play() + setTimeout(function(){ + stylesheet_haunted.disabled = true + },700) + } + + thunder1.play() + setTimeout(function(){ + div.style.animation = "none" + },1000) +} diff --git a/events/assets/js/jumpscare.js b/events/assets/js/jumpscare.js new file mode 100644 index 000000000..bf3ae379e --- /dev/null +++ b/events/assets/js/jumpscare.js @@ -0,0 +1,14 @@ +// Jump scare function +const scare = () => { + const image = document.getElementById("jump-scare-img"); + + jumpscare_audio.play(); + image.style.display = "block"; + + // Hide image and reset sound + setTimeout(function () { + image.style.display = "none"; + jumpscare_audio.pause() + jumpscare_audio.currentTime = 0; + }, 3000); +} diff --git a/events/assets/js/sketch.js b/events/assets/js/sketch.js new file mode 100644 index 000000000..2d0fc9782 --- /dev/null +++ b/events/assets/js/sketch.js @@ -0,0 +1,630 @@ +/* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */ + +(function ( root, factory ) { + + if ( typeof exports === 'object' ) { + + // CommonJS like + module.exports = factory(root, root.document); + + } else if ( typeof define === 'function' && define.amd ) { + + // AMD + define( function() { return factory( root, root.document ); }); + + } else { + + // Browser global + root.Sketch = factory( root, root.document ); + } + +}( typeof window !== "undefined" ? window : this, function ( window, document ) { + + + "use strict"; + + /* + ---------------------------------------------------------------------- + + Config + + ---------------------------------------------------------------------- + */ + + var MATH_PROPS = 'E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan ceil cos exp floor log round sin sqrt tan atan2 pow max min'.split( ' ' ); + var HAS_SKETCH = '__hasSketch'; + var M = Math; + + var CANVAS = 'canvas'; + var WEBGL = 'webgl'; + var DOM = 'dom'; + + var doc = document; + var win = window; + + var instances = []; + + var defaults = { + + fullscreen: true, + autostart: true, + autoclear: true, + autopause: true, + container: doc.body, + interval: 1, + globals: true, + retina: false, + type: CANVAS + }; + + var keyMap = { + + 8: 'BACKSPACE', + 9: 'TAB', + 13: 'ENTER', + 16: 'SHIFT', + 27: 'ESCAPE', + 32: 'SPACE', + 37: 'LEFT', + 38: 'UP', + 39: 'RIGHT', + 40: 'DOWN' + }; + + /* + ---------------------------------------------------------------------- + + Utilities + + ---------------------------------------------------------------------- + */ + + function isArray( object ) { + + return Object.prototype.toString.call( object ) == '[object Array]'; + } + + function isFunction( object ) { + + return typeof object == 'function'; + } + + function isNumber( object ) { + + return typeof object == 'number'; + } + + function isString( object ) { + + return typeof object == 'string'; + } + + function keyName( code ) { + + return keyMap[ code ] || String.fromCharCode( code ); + } + + function extend( target, source, overwrite ) { + + for ( var key in source ) + + if ( overwrite || !( key in target ) ) + + target[ key ] = source[ key ]; + + return target; + } + + function proxy( method, context ) { + + return function() { + + method.apply( context, arguments ); + }; + } + + function clone( target ) { + + var object = {}; + + for ( var key in target ) { + + if ( key === 'webkitMovementX' || key === 'webkitMovementY' ) + continue; + + if ( isFunction( target[ key ] ) ) + + object[ key ] = proxy( target[ key ], target ); + + else + + object[ key ] = target[ key ]; + } + + return object; + } + + /* + ---------------------------------------------------------------------- + + Constructor + + ---------------------------------------------------------------------- + */ + + function constructor( context ) { + + var request, handler, target, parent, bounds, index, suffix, clock, node, copy, type, key, val, min, max, w, h; + + var counter = 0; + var touches = []; + var resized = false; + var setup = false; + var ratio = win.devicePixelRatio || 1; + var isDiv = context.type == DOM; + var is2D = context.type == CANVAS; + + var mouse = { + x: 0.0, y: 0.0, + ox: 0.0, oy: 0.0, + dx: 0.0, dy: 0.0 + }; + + var eventMap = [ + + context.eventTarget || context.element, + + pointer, 'mousedown', 'touchstart', + pointer, 'mousemove', 'touchmove', + pointer, 'mouseup', 'touchend', + pointer, 'click', + pointer, 'mouseout', + pointer, 'mouseover', + + doc, + + keypress, 'keydown', 'keyup', + + win, + + active, 'focus', 'blur', + resize, 'resize' + ]; + + var keys = {}; for ( key in keyMap ) keys[ keyMap[ key ] ] = false; + + function trigger( method ) { + + if ( isFunction( method ) ) + + method.apply( context, [].splice.call( arguments, 1 ) ); + } + + function bind( on ) { + + for ( index = 0; index < eventMap.length; index++ ) { + + node = eventMap[ index ]; + + if ( isString( node ) ) + + target[ ( on ? 'add' : 'remove' ) + 'EventListener' ].call( target, node, handler, false ); + + else if ( isFunction( node ) ) + + handler = node; + + else target = node; + } + } + + function update() { + + cAF( request ); + request = rAF( update ); + + if ( !setup ) { + + trigger( context.setup ); + setup = isFunction( context.setup ); + } + + if ( !resized ) { + trigger( context.resize ); + resized = isFunction( context.resize ); + } + + if ( context.running && !counter ) { + + context.dt = ( clock = +new Date() ) - context.now; + context.millis += context.dt; + context.now = clock; + + trigger( context.update ); + + // Pre draw + + if ( is2D ) { + + if ( context.retina ) { + + context.save(); + + if (context.autoclear) { + context.scale( ratio, ratio ); + } + } + + if ( context.autoclear ) + + context.clear(); + } + + // Draw + + trigger( context.draw ); + + // Post draw + + if ( is2D && context.retina ) + + context.restore(); + } + + counter = ++counter % context.interval; + } + + function resize() { + + target = isDiv ? context.style : context.canvas; + suffix = isDiv ? 'px' : ''; + + w = context.width; + h = context.height; + + if ( context.fullscreen ) { + + h = context.height = win.innerHeight; + w = context.width = win.innerWidth; + } + + if ( context.retina && is2D && ratio ) { + + target.style.height = h + 'px'; + target.style.width = w + 'px'; + + w *= ratio; + h *= ratio; + } + + if ( target.height !== h ) + + target.height = h + suffix; + + if ( target.width !== w ) + + target.width = w + suffix; + + if ( is2D && !context.autoclear && context.retina ) + + context.scale( ratio, ratio ); + + if ( setup ) trigger( context.resize ); + } + + function align( touch, target ) { + + bounds = target.getBoundingClientRect(); + + touch.x = touch.pageX - bounds.left - (win.scrollX || win.pageXOffset); + touch.y = touch.pageY - bounds.top - (win.scrollY || win.pageYOffset); + + return touch; + } + + function augment( touch, target ) { + + align( touch, context.element ); + + target = target || {}; + + target.ox = target.x || touch.x; + target.oy = target.y || touch.y; + + target.x = touch.x; + target.y = touch.y; + + target.dx = target.x - target.ox; + target.dy = target.y - target.oy; + + return target; + } + + function process( event ) { + + event.preventDefault(); + + copy = clone( event ); + copy.originalEvent = event; + + if ( copy.touches ) { + + touches.length = copy.touches.length; + + for ( index = 0; index < copy.touches.length; index++ ) + + touches[ index ] = augment( copy.touches[ index ], touches[ index ] ); + + } else { + + touches.length = 0; + touches[0] = augment( copy, mouse ); + } + + extend( mouse, touches[0], true ); + + return copy; + } + + function pointer( event ) { + + event = process( event ); + + min = ( max = eventMap.indexOf( type = event.type ) ) - 1; + + context.dragging = + + /down|start/.test( type ) ? true : + + /up|end/.test( type ) ? false : + + context.dragging; + + while( min ) + + isString( eventMap[ min ] ) ? + + trigger( context[ eventMap[ min-- ] ], event ) : + + isString( eventMap[ max ] ) ? + + trigger( context[ eventMap[ max++ ] ], event ) : + + min = 0; + } + + function keypress( event ) { + + key = event.keyCode; + val = event.type == 'keyup'; + keys[ key ] = keys[ keyName( key ) ] = !val; + + trigger( context[ event.type ], event ); + } + + function active( event ) { + + if ( context.autopause ) + + ( event.type == 'blur' ? stop : start )(); + + trigger( context[ event.type ], event ); + } + + // Public API + + function start() { + + context.now = +new Date(); + context.running = true; + } + + function stop() { + + context.running = false; + } + + function toggle() { + + ( context.running ? stop : start )(); + } + + function clear() { + + if ( is2D ) + + context.clearRect( 0, 0, context.width * ratio, context.height * ratio ); + } + + function destroy() { + + parent = context.element.parentNode; + index = instances.indexOf( context ); + + if ( parent ) parent.removeChild( context.element ); + if ( ~index ) instances.splice( index, 1 ); + + bind( false ); + stop(); + } + + extend( context, { + + touches: touches, + mouse: mouse, + keys: keys, + + dragging: false, + running: false, + millis: 0, + now: NaN, + dt: NaN, + + destroy: destroy, + toggle: toggle, + clear: clear, + start: start, + stop: stop + }); + + instances.push( context ); + + return ( context.autostart && start(), bind( true ), resize(), update(), context ); + } + + /* + ---------------------------------------------------------------------- + + Global API + + ---------------------------------------------------------------------- + */ + + var element, context, Sketch = { + + CANVAS: CANVAS, + WEB_GL: WEBGL, + WEBGL: WEBGL, + DOM: DOM, + + instances: instances, + + install: function( context ) { + + if ( !context[ HAS_SKETCH ] ) { + + for ( var i = 0; i < MATH_PROPS.length; i++ ) + + context[ MATH_PROPS[i] ] = M[ MATH_PROPS[i] ]; + + extend( context, { + + TWO_PI: M.PI * 2, + HALF_PI: M.PI / 2, + QUARTER_PI: M.PI / 4, + + random: function( min, max ) { + + if ( isArray( min ) ) + + return min[ ~~( M.random() * min.length ) ]; + + if ( !isNumber( max ) ) + + max = min || 1, min = 0; + + return min + M.random() * ( max - min ); + }, + + lerp: function( min, max, amount ) { + + return min + amount * ( max - min ); + }, + + map: function( num, minA, maxA, minB, maxB ) { + + return ( num - minA ) / ( maxA - minA ) * ( maxB - minB ) + minB; + } + }); + + context[ HAS_SKETCH ] = true; + } + }, + + create: function( options ) { + + options = extend( options || {}, defaults ); + + if ( options.globals ) Sketch.install( self ); + + element = options.element = options.element || doc.createElement( options.type === DOM ? 'div' : 'canvas' ); + + context = options.context = options.context || (function() { + + switch( options.type ) { + + case CANVAS: + + return element.getContext( '2d', options ); + + case WEBGL: + + return element.getContext( 'webgl', options ) || element.getContext( 'experimental-webgl', options ); + + case DOM: + + return element.canvas = element; + } + + })(); + + ( options.container || doc.body ).appendChild( element ); + + return Sketch.augment( context, options ); + }, + + augment: function( context, options ) { + + options = extend( options || {}, defaults ); + + options.element = context.canvas || context; + options.element.className += ' sketch'; + + extend( context, options, true ); + + return constructor( context ); + } + }; + + /* + ---------------------------------------------------------------------- + + Shims + + ---------------------------------------------------------------------- + */ + + var vendors = [ 'ms', 'moz', 'webkit', 'o' ]; + var scope = self; + var then = 0; + + var a = 'AnimationFrame'; + var b = 'request' + a; + var c = 'cancel' + a; + + var rAF = scope[ b ]; + var cAF = scope[ c ]; + + for ( var i = 0; i < vendors.length && !rAF; i++ ) { + + rAF = scope[ vendors[ i ] + 'Request' + a ]; + cAF = scope[ vendors[ i ] + 'Cancel' + a ]; + } + + scope[ b ] = rAF = rAF || function( callback ) { + + var now = +new Date(); + var dt = M.max( 0, 16 - ( now - then ) ); + var id = setTimeout( function() { + callback( now + dt ); + }, dt ); + + then = now + dt; + return id; + }; + + scope[ c ] = cAF = cAF || function( id ) { + clearTimeout( id ); + }; + + /* + ---------------------------------------------------------------------- + + Output + + ---------------------------------------------------------------------- + */ + + return Sketch; + +})); diff --git a/events/assets/js/trickortreat.js b/events/assets/js/trickortreat.js new file mode 100644 index 000000000..ddcd2c086 --- /dev/null +++ b/events/assets/js/trickortreat.js @@ -0,0 +1,24 @@ +function postToastTrickOrTreat(t, url) { + const xhr = createXhrWithFormKey(url); + xhr[0].onload = function() { + postToastLoadTrickOrTreat(xhr[0]) + }; + xhr[0].send(xhr[1]); +} + +function postToastLoadTrickOrTreat(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)); + + if (data["result"] == 0){ + scare() + } +} + diff --git a/events/assets/js/upsidedown.js b/events/assets/js/upsidedown.js new file mode 100644 index 000000000..f005dd0b9 --- /dev/null +++ b/events/assets/js/upsidedown.js @@ -0,0 +1,81 @@ +let st = init("canvas"), // stranger things var + w = (canvas.width = window.innerWidth), + h = (canvas.height = window.innerHeight); +//initiation + +class firefly { + constructor() { + this.x = Math.random() * w; + this.y = Math.random() * h; + this.s = Math.random() * 2; + this.ang = Math.random() * 2 * Math.PI; + this.v = (this.s * this.s) / 4; + } + move() { + this.x += this.v * Math.cos(this.ang); + this.y += this.v * Math.sin(this.ang); + this.ang += (Math.random() * 20 * Math.PI) / 180 - (10 * Math.PI) / 180; + } + show() { + st.beginPath(); + st.arc(this.x, this.y, this.s, 0, 2 * Math.PI); + st.fillStyle = "#fff"; + st.fill(); + } +} + +let f = []; + +function draw() { + if (f.length < 100) { + for (let j = 0; j < 10; j++) { + f.push(new firefly()); + } + } + //animation + for (let i = 0; i < f.length; i++) { + f[i].move(); + f[i].show(); + if (f[i].x < 0 || f[i].x > w || f[i].y < 0 || f[i].y > h) { + f.splice(i, 1); + } + } +} + +function init(elemid) { + let canvas = document.getElementById(elemid), + st = canvas.getContext("2d"), + w = (canvas.width = window.innerWidth), + h = (canvas.height = window.innerHeight); + st.fillStyle = "rgba(30,30,30,1)"; + st.fillRect(0, 0, w, h); + return st; +} + +window.requestAnimFrame = function () { + return ( + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + window.setTimeout(callback); + } + ); +}; + +function loop() { + window.requestAnimFrame(loop); + st.clearRect(0, 0, w, h); + draw(); +} + +window.addEventListener("resize", function () { + (w = canvas.width = window.innerWidth), + (h = canvas.height = window.innerHeight); + loop(); +}); + +loop(); +setInterval(loop, 1000 / 60); diff --git a/events/assets/media/Spooky_Scary_Skeletons.mp3 b/events/assets/media/Spooky_Scary_Skeletons.mp3 new file mode 100644 index 000000000..219223675 Binary files /dev/null and b/events/assets/media/Spooky_Scary_Skeletons.mp3 differ diff --git a/events/assets/media/ghostbusters.mp3 b/events/assets/media/ghostbusters.mp3 new file mode 100644 index 000000000..fdbb8539c Binary files /dev/null and b/events/assets/media/ghostbusters.mp3 differ diff --git a/events/assets/media/haunted/thunder1.mp3 b/events/assets/media/haunted/thunder1.mp3 new file mode 100644 index 000000000..2430c44c1 Binary files /dev/null and b/events/assets/media/haunted/thunder1.mp3 differ diff --git a/events/assets/media/haunted/thunder2.mp3 b/events/assets/media/haunted/thunder2.mp3 new file mode 100644 index 000000000..fb7a57062 Binary files /dev/null and b/events/assets/media/haunted/thunder2.mp3 differ diff --git a/events/assets/media/jumpscares/Ambush jumpscare but animated.mp3 b/events/assets/media/jumpscares/Ambush jumpscare but animated.mp3 new file mode 100644 index 000000000..7c264ffff Binary files /dev/null and b/events/assets/media/jumpscares/Ambush jumpscare but animated.mp3 differ diff --git a/events/assets/media/jumpscares/Doors Rush jumpscare.mp3 b/events/assets/media/jumpscares/Doors Rush jumpscare.mp3 new file mode 100644 index 000000000..93dca87b3 Binary files /dev/null and b/events/assets/media/jumpscares/Doors Rush jumpscare.mp3 differ diff --git a/events/assets/media/jumpscares/Fnaf 2 jumpscare sound effect.mp3 b/events/assets/media/jumpscares/Fnaf 2 jumpscare sound effect.mp3 new file mode 100644 index 000000000..d6415bf60 Binary files /dev/null and b/events/assets/media/jumpscares/Fnaf 2 jumpscare sound effect.mp3 differ diff --git a/events/assets/media/jumpscares/dancing rat jumpscare.mp3 b/events/assets/media/jumpscares/dancing rat jumpscare.mp3 new file mode 100644 index 000000000..727d42a70 Binary files /dev/null and b/events/assets/media/jumpscares/dancing rat jumpscare.mp3 differ diff --git a/events/assets/media/jumpscares/scream_test_1.mp3 b/events/assets/media/jumpscares/scream_test_1.mp3 new file mode 100644 index 000000000..32ae5bb59 Binary files /dev/null and b/events/assets/media/jumpscares/scream_test_1.mp3 differ diff --git a/events/assets/media/music/CARPENTER_MASTER.mp3 b/events/assets/media/music/CARPENTER_MASTER.mp3 new file mode 100644 index 000000000..7cef0148a Binary files /dev/null and b/events/assets/media/music/CARPENTER_MASTER.mp3 differ diff --git a/events/assets/media/music/Stranger Things Theme Song (C418 REMIX)_edit.mp3 b/events/assets/media/music/Stranger Things Theme Song (C418 REMIX)_edit.mp3 new file mode 100644 index 000000000..6a1496e53 Binary files /dev/null and b/events/assets/media/music/Stranger Things Theme Song (C418 REMIX)_edit.mp3 differ diff --git a/events/assets/media/music/burton.mp3 b/events/assets/media/music/burton.mp3 new file mode 100644 index 000000000..687739c1b Binary files /dev/null and b/events/assets/media/music/burton.mp3 differ diff --git a/events/assets/media/music/exorcist.mp3 b/events/assets/media/music/exorcist.mp3 new file mode 100644 index 000000000..dd72bbd25 Binary files /dev/null and b/events/assets/media/music/exorcist.mp3 differ diff --git a/events/assets/media/music/ghostly-music-box.mp3 b/events/assets/media/music/ghostly-music-box.mp3 new file mode 100644 index 000000000..ec9821382 Binary files /dev/null and b/events/assets/media/music/ghostly-music-box.mp3 differ diff --git a/events/assets/media/music/goosebumps-original-theme-song.mp3 b/events/assets/media/music/goosebumps-original-theme-song.mp3 new file mode 100644 index 000000000..6b8b3b177 Binary files /dev/null and b/events/assets/media/music/goosebumps-original-theme-song.mp3 differ diff --git a/events/assets/media/music/halloween-II-theme.mp3 b/events/assets/media/music/halloween-II-theme.mp3 new file mode 100644 index 000000000..26ccfddfd Binary files /dev/null and b/events/assets/media/music/halloween-II-theme.mp3 differ diff --git a/events/assets/media/music/headsroll.mp3 b/events/assets/media/music/headsroll.mp3 new file mode 100644 index 000000000..0ddb28fb0 Binary files /dev/null and b/events/assets/media/music/headsroll.mp3 differ diff --git a/events/assets/media/music/hereditary-soundtrack-reborn.mp3 b/events/assets/media/music/hereditary-soundtrack-reborn.mp3 new file mode 100644 index 000000000..c228118e9 Binary files /dev/null and b/events/assets/media/music/hereditary-soundtrack-reborn.mp3 differ diff --git a/events/assets/media/music/i-put-a-spell-on-you.mp3 b/events/assets/media/music/i-put-a-spell-on-you.mp3 new file mode 100644 index 000000000..437d22125 Binary files /dev/null and b/events/assets/media/music/i-put-a-spell-on-you.mp3 differ diff --git a/events/assets/media/music/jack-the-ripper.mp3 b/events/assets/media/music/jack-the-ripper.mp3 new file mode 100644 index 000000000..41e613c13 Binary files /dev/null and b/events/assets/media/music/jack-the-ripper.mp3 differ diff --git a/events/assets/media/music/koopsta-knicca-stash-pot-remix.mp3 b/events/assets/media/music/koopsta-knicca-stash-pot-remix.mp3 new file mode 100644 index 000000000..28637f0fc Binary files /dev/null and b/events/assets/media/music/koopsta-knicca-stash-pot-remix.mp3 differ diff --git a/events/assets/media/music/monstermash.mp3 b/events/assets/media/music/monstermash.mp3 new file mode 100644 index 000000000..af42afa84 Binary files /dev/null and b/events/assets/media/music/monstermash.mp3 differ diff --git a/events/assets/media/music/nightmare-on-elm-street-theme.mp3 b/events/assets/media/music/nightmare-on-elm-street-theme.mp3 new file mode 100644 index 000000000..3609221ba Binary files /dev/null and b/events/assets/media/music/nightmare-on-elm-street-theme.mp3 differ diff --git a/events/assets/media/music/owo.mp3 b/events/assets/media/music/owo.mp3 new file mode 100644 index 000000000..ce21a32a8 Binary files /dev/null and b/events/assets/media/music/owo.mp3 differ diff --git a/events/assets/media/music/pyscho.mp3 b/events/assets/media/music/pyscho.mp3 new file mode 100644 index 000000000..eaf47e0a2 Binary files /dev/null and b/events/assets/media/music/pyscho.mp3 differ diff --git a/events/assets/media/music/rats.mp3 b/events/assets/media/music/rats.mp3 new file mode 100644 index 000000000..e62ea0549 Binary files /dev/null and b/events/assets/media/music/rats.mp3 differ diff --git a/events/assets/media/music/scooby.mp3 b/events/assets/media/music/scooby.mp3 new file mode 100644 index 000000000..c3a78e6a0 Binary files /dev/null and b/events/assets/media/music/scooby.mp3 differ diff --git a/events/assets/media/music/scoops-troop.mp3 b/events/assets/media/music/scoops-troop.mp3 new file mode 100644 index 000000000..d3934b47d Binary files /dev/null and b/events/assets/media/music/scoops-troop.mp3 differ diff --git a/events/assets/media/music/signs-main-titles-theme.mp3 b/events/assets/media/music/signs-main-titles-theme.mp3 new file mode 100644 index 000000000..eaa350ca0 Binary files /dev/null and b/events/assets/media/music/signs-main-titles-theme.mp3 differ diff --git a/events/assets/media/music/strangerintro.mp3 b/events/assets/media/music/strangerintro.mp3 new file mode 100644 index 000000000..79f0b527a Binary files /dev/null and b/events/assets/media/music/strangerintro.mp3 differ diff --git a/events/assets/media/music/this-is-halloween.mp3 b/events/assets/media/music/this-is-halloween.mp3 new file mode 100644 index 000000000..da6c59d03 Binary files /dev/null and b/events/assets/media/music/this-is-halloween.mp3 differ diff --git a/events/assets/media/music/thriller.mp3 b/events/assets/media/music/thriller.mp3 new file mode 100644 index 000000000..ea5e7729d Binary files /dev/null and b/events/assets/media/music/thriller.mp3 differ diff --git a/events/assets/media/music/twilightzone.mp3 b/events/assets/media/music/twilightzone.mp3 new file mode 100644 index 000000000..113d864cb Binary files /dev/null and b/events/assets/media/music/twilightzone.mp3 differ diff --git a/events/assets/media/music/welcome-to-crystal-lake.mp3 b/events/assets/media/music/welcome-to-crystal-lake.mp3 new file mode 100644 index 000000000..e0c1014fe Binary files /dev/null and b/events/assets/media/music/welcome-to-crystal-lake.mp3 differ diff --git a/events/assets/media/unused/Stranger things demogorgon theme.mp3 b/events/assets/media/unused/Stranger things demogorgon theme.mp3 new file mode 100644 index 000000000..1d0348823 Binary files /dev/null and b/events/assets/media/unused/Stranger things demogorgon theme.mp3 differ diff --git a/events/assets/media/unused/halloween.mp3 b/events/assets/media/unused/halloween.mp3 new file mode 100644 index 000000000..583a07e27 Binary files /dev/null and b/events/assets/media/unused/halloween.mp3 differ diff --git a/events/assets/media/unused/headsroll_edit.mp3 b/events/assets/media/unused/headsroll_edit.mp3 new file mode 100644 index 000000000..4e5aa9bcc Binary files /dev/null and b/events/assets/media/unused/headsroll_edit.mp3 differ diff --git a/events/assets/media/unused/psycho.mp3 b/events/assets/media/unused/psycho.mp3 new file mode 100644 index 000000000..db1e70a4a Binary files /dev/null and b/events/assets/media/unused/psycho.mp3 differ diff --git a/events/classes/__init__.py b/events/classes/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/events/columns.py b/events/columns.py new file mode 100644 index 000000000..034cddd66 --- /dev/null +++ b/events/columns.py @@ -0,0 +1,6 @@ +from sqlalchemy import Column, Integer, Boolean +from .table import Event + +Event.hw_zombie = Column(Integer, default=0, nullable=False) +Event.jumpscare = Column(Integer, default=0) +Event.hwmusic = Column(Boolean, default=False) diff --git a/events/helpers/__init__.py b/events/helpers/__init__.py new file mode 100644 index 000000000..3651c2473 --- /dev/null +++ b/events/helpers/__init__.py @@ -0,0 +1,2 @@ +from .const import * +from .jinja import * diff --git a/events/helpers/const.py b/events/helpers/const.py new file mode 100644 index 000000000..328dccebe --- /dev/null +++ b/events/helpers/const.py @@ -0,0 +1,142 @@ +EVENT_AWARDS = { + "jumpscare": { + "kind": "jumpscare", + "title": "Jumpscare", + "description": "", + "icon": "fas fa-coffin-cross", + "color": "text-purple", + "price": 600, + "deflectable": True, + "cosmetic": False + }, + "hw-bite": { + "kind": "hw-bite", + "title": "Zombie Bite", + "description": "", + "icon": "fas fa-biohazard", + "color": "text-danger", + "price": 500, + "deflectable": True, + "cosmetic": False + }, + "hw-vax": { + "kind": "hw-vax", + "title": "Vaxxmaxx", + "description": "", + "icon": "fas fa-syringe", + "color": "text-blue", + "price": 500, + "deflectable": True, + "cosmetic": False + }, + "hw-grinch": { + "kind": "hw-grinch", + "title": "Hallowgrinch", + "description": "", + "icon": "fas fa-angry", + "color": "text-orange", + "price": 1000, + "deflectable": True, + "cosmetic": False + }, + "haunt": { + "kind": "haunt", + "title": "Haunt", + "description": "", + "icon": "fas fa-book-dead", + "color": "text-warning", + "price": 500, + "deflectable": False, + "cosmetic": True + }, + "stab": { + "kind": "stab", + "title": "Stab", + "description": "", + "icon": "fas fa-knife-kitchen", + "color": "text-danger", + "price": 300, + "deflectable": False, + "cosmetic": True + }, + "spiders": { + "kind": "spiders", + "title": "Spiders", + "description": "", + "icon": "fas fa-spider-web", + "color": "text-black", + "price": 200, + "deflectable": False, + "cosmetic": True + }, + "fog": { + "kind": "fog", + "title": "Fog", + "description": "", + "icon": "fas fa-smoke", + "color": "text-gray", + "price": 200, + "deflectable": False, + "cosmetic": True + }, + "flashlight": { + "kind": "flashlight", + "title": "Flashlight", + "description": "", + "icon": "fas fa-flashlight", + "color": "text-black", + "price": 400, + "deflectable": False, + "cosmetic": True + }, + "candy-corn": { + "kind": "candy-corn", + "title": "Candy Corn", + "description": "", + "icon": "fas fa-candy-corn", + "color": "text-orange", + "price": 400, + "deflectable": False, + "cosmetic": True + }, + "ectoplasm": { + "kind": "ectoplasm", + "title": "Ectoplasm", + "description": "", + "icon": "fas fa-ghost", + "color": "text-success", + "price": 400, + "deflectable": False, + "cosmetic": True + }, + "test_award": { + "kind": "test_award", + "title": "TEST", + "description": "", + "icon": "fas fa-lights-holiday", + "color": "", + "price": 400, + "deflectable": False, + "cosmetic": True + }, + "bones": { + "kind": "bones", + "title": "Bones", + "description": "", + "icon": "fas fa-bone", + "color": "text-white", + "price": 500, + "deflectable": False, + "cosmetic": True + }, + "pumpkin": { + "kind": "pumpkin", + "title": "Pumpkin", + "description": "", + "icon": "fas fa-jack-o-lantern", + "color": "text-orange", + "price": 200, + "deflectable": False, + "cosmetic": True + } +} diff --git a/events/helpers/jinja.py b/events/helpers/jinja.py new file mode 100644 index 000000000..3c099a73a --- /dev/null +++ b/events/helpers/jinja.py @@ -0,0 +1,26 @@ +def bar_position(): + """ + db = db_session() + vaxxed = db.execute(text("SELECT COUNT(*) FROM event WHERE hw_zombie > 0")).one()[0] + zombie = db.execute(text("SELECT COUNT(*) FROM event WHERE hw_zombie < 0")).one()[0] + total = db.execute(text("SELECT COUNT(*) FROM " + "(SELECT DISTINCT ON (author_id) author_id AS uid FROM comments " + "WHERE created_utc > 1666402200) AS q1 " + "FULL OUTER JOIN (SELECT id AS uid FROM event WHERE hw_zombie != 0) as q2 " + "ON q1.uid = q2.uid")).one()[0] + total = max(total, 1) + + return [int((vaxxed * 100) / total), int((zombie * 100) / total), vaxxed, zombie] + """ + + return [1,1,1,1] + +EVENT_JINJA_CONST = { + "EVENT_BANNER": "banner_rDrama.html", + "EVENT_SIDEBAR": True, + "EVENT_STYLES": "spooky.css", + "EVENT_AWARDS": True, + "EVENT_MUSIC": "music.html", + "bar_position": bar_position() +} + diff --git a/events/routes/__init__.py b/events/routes/__init__.py new file mode 100644 index 000000000..de6679372 --- /dev/null +++ b/events/routes/__init__.py @@ -0,0 +1,3 @@ +from .routes import * +from .awards import * +from .jinja import * diff --git a/events/routes/awards.py b/events/routes/awards.py new file mode 100644 index 000000000..75888a1d8 --- /dev/null +++ b/events/routes/awards.py @@ -0,0 +1,55 @@ +from flask import g +from events import Event + +def award_thing_event(v, kind, author): + event_author = g.db.get(Event, author.id) + event_v = g.db.get(Event, v.id) + + if not event_author: + event_author = Event(id=author.id) + g.db.add(event_author) + + if not event_v: + event_v = Event(id=v.id) + g.db.add(event_v) + + g.db.flush() + + if kind == "hw-bite": + if event_author.hw_zombie < 0: + event_author = event_v + + if event_author.hw_zombie == 0: + event_author.hw_zombie = -1 + badge_grant(user=author, badge_id=181) + + award_object = AwardRelationship(user_id=author.id, kind='hw-bite') + g.db.add(award_object) + send_repeatable_notification(author.id, + "As the zombie virus washes over your mind, you feel the urge " + "to… BITE YUMMY BRAINS :marseyzombie:
" + "You receive a free **Zombie Bite** award: pass it on!") + + elif event_author.hw_zombie > 0: + event_author.hw_zombie -= 1 + if event_author.hw_zombie == 0: + send_repeatable_notification(author.id, "You are no longer **VAXXMAXXED**! Time for another booster!") + + badge = author.has_badge(182) + if badge: g.db.delete(badge) + elif kind == "hw-vax": + if event_author.hw_zombie < 0: + event_author.hw_zombie = 0 + send_repeatable_notification(author.id, "You are no longer **INFECTED**! Praise Fauci!") + + badge = author.has_badge(181) + if badge: g.db.delete(badge) + elif event_author.hw_zombie >= 0: + event_author.hw_zombie += 2 + event_author.hw_zombie = min(event_author.hw_zombie, 10) + + badge_grant(user=author, badge_id=182) + elif kind == "jumpscare": + event_author.jumpscare += 1 + + g.db.add(event_author) diff --git a/events/routes/jinja.py b/events/routes/jinja.py new file mode 100644 index 000000000..4217430ee --- /dev/null +++ b/events/routes/jinja.py @@ -0,0 +1,6 @@ +from files.__main__ import app +from events import EVENT_JINJA_CONST + +@app.context_processor +def event_constants(): + return EVENT_JINJA_CONST diff --git a/events/routes/routes.py b/events/routes/routes.py new file mode 100644 index 000000000..5329b6eb0 --- /dev/null +++ b/events/routes/routes.py @@ -0,0 +1,33 @@ +from files.__main__ import * + +@app.post("/trick-or-treat") +@limiter.limit("1/hour", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@auth_required +def trick_or_treat(v): + if v.client: abort(403, "Not allowed from the API") + + result = random.choice([0,1]) + + if result == 0: + message = "Trick!" + else: + AWARDS = deepcopy(AWARDS2) + award = random.choice(["haunt", "stab", "spiders", "fog", "flashlight", "candy-corn", "ectoplasm", "bones", "pumpkin", "jumpscare", "hw-bite", "hw-vax"]) + award_title = AWARDS[award]['title'] + award_object = AwardRelationship(user_id=v.id, kind=award) + g.db.add(award_object) + + g.db.add(v) + message = f"Treat! You got a {award_title} award!" + + return {"message": f"{message}", "result": f"{result}"} + +@app.post("/jumpscare") +@auth_required +def execute_jumpscare(v): + if v.client: abort(403, "Not allowed from the API") + if v.jumpscare > 0: + v.jumpscare -= 1 + g.db.add(v) + + return {} diff --git a/events/table.py b/events/table.py new file mode 100644 index 000000000..986a64abd --- /dev/null +++ b/events/table.py @@ -0,0 +1,15 @@ +from sqlalchemy import * +from sqlalchemy.orm import relationship + +from files.classes import Base + +class Event(Base): + + __tablename__ = "event" + id = Column(Integer, ForeignKey("users.id"), primary_key=True) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def __repr__(self): + return f"" diff --git a/events/templates/awards.html b/events/templates/awards.html new file mode 100644 index 000000000..3905ede4e --- /dev/null +++ b/events/templates/awards.html @@ -0,0 +1,130 @@ + + +{% if p.award_count("haunt", v) %} + +
+ +{% endif %} + +{% set stab = p.award_count("stab", v) %} +{% if stab %} + {% if stab > 3 %} + {% set stab = 3 %} + {% endif %} + + + + +{% endif %} + +{% if p.award_count("spiders", v) %} + {% set spiders = p.award_count("spiders", v) %} + + {% for i in range(spiders) %} + {% include "event/spider.html" %} + {% endfor %} +{% endif %} + +{% if p.award_count("fog", v) %} + + +{% endif %} + +{% if p.award_count("flashlight", v) %} + +
+ +{% endif %} + +{% if p.award_count("ectoplasm", v) %} + +{% endif %} + +{% if p.award_count("bones", v) %} +
+ + +{% endif %} + +{% if p.award_count("pumpkin", v) %} +{% set count = p.award_count("pumpkin", v) * 2 if p.award_count("pumpkin", v) <= 10 else 20 %} +
+ {% for i in range(count) %} +
+ animate marsey pumpkin icon +
+ {% endfor %} +
+{% endif %} diff --git a/events/templates/awards_eco.html b/events/templates/awards_eco.html new file mode 100644 index 000000000..2c2ec7160 --- /dev/null +++ b/events/templates/awards_eco.html @@ -0,0 +1,50 @@ + + +{% if p.award_count("fog", v) %} + +
+{% endif %} + +{% if p.award_count("stab", v) %} + +
+{% endif %} + +{% if p.award_count("haunt", v) %} + +{% endif %} + +{% if p.award_count("flashlight", v) %} + +
+{% endif %} diff --git a/events/templates/banner.html b/events/templates/banner.html new file mode 100644 index 000000000..b626d843e --- /dev/null +++ b/events/templates/banner.html @@ -0,0 +1,204 @@ + + {% set banner_day = time.gmtime()[2]-21 %} + {% if banner_day < 1 %} + {% set banner_day = 1 %} + {% endif %} + + {% if '/post/' not in request.path %} + + + {% endif %} + + + + +{% if SITE == 'localhost' or SITE == 'devrama.net' %} + +{% endif %} diff --git a/events/templates/banner_rDrama.html b/events/templates/banner_rDrama.html new file mode 100644 index 000000000..74e97e99c --- /dev/null +++ b/events/templates/banner_rDrama.html @@ -0,0 +1,219 @@ + + {% set banner_day = time.gmtime()[2]-21 %} + {% if banner_day < 1 %} + {% set banner_day = 1 %} + {% endif %} + + {% if '/post/' not in request.path %} + + + {% endif %} + + + + +{% if SITE == 'localhost' or SITE == 'devrama.net' %} + +{% endif %} diff --git a/events/templates/lights.html b/events/templates/lights.html new file mode 100644 index 000000000..946d10652 --- /dev/null +++ b/events/templates/lights.html @@ -0,0 +1,44 @@ + diff --git a/events/templates/music.html b/events/templates/music.html new file mode 100644 index 000000000..ab8fc59d3 --- /dev/null +++ b/events/templates/music.html @@ -0,0 +1,24 @@ +{% if not (v and v.poorcel) and not (v and v.hwmusic) and not (sub and sub.name == 'music') %} + {% if not song %} + {% set path = "assets/media/event/music" %} + {% set song = "/" + path + "/" + listdir('files/' + path)|random() + '?v=45' %} + {% endif %} + +{% endif %} diff --git a/events/templates/sidebar_rDrama.html b/events/templates/sidebar_rDrama.html new file mode 100644 index 000000000..b9dbd87be --- /dev/null +++ b/events/templates/sidebar_rDrama.html @@ -0,0 +1,158 @@ + + + diff --git a/events/templates/spider.html b/events/templates/spider.html new file mode 100644 index 000000000..dc88c46cd --- /dev/null +++ b/events/templates/spider.html @@ -0,0 +1,17 @@ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/files/__main__.py b/files/__main__.py index 94ec12a2d..2a027e4f1 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -26,14 +26,16 @@ app.jinja_env.auto_reload = True app.jinja_env.add_extension('jinja2.ext.do') faulthandler.enable() +is_localhost = SITE == "localhost" + app.config['SERVER_NAME'] = SITE app.config['SECRET_KEY'] = environ.get('SECRET_KEY').strip() app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 3153600 -if not IS_LOCALHOST: +if not is_localhost: app.config['SESSION_COOKIE_DOMAIN'] = f'.{SITE}' - app.config["SESSION_COOKIE_SECURE"] = True app.config["SESSION_COOKIE_NAME"] = "session_" + environ.get("SITE_NAME").strip().lower() app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 +app.config["SESSION_COOKIE_SECURE"] = True app.config["SESSION_COOKIE_SAMESITE"] = "Lax" app.config["PERMANENT_SESSION_LIFETIME"] = 60 * 60 * 24 * 365 app.config['SESSION_REFRESH_EACH_REQUEST'] = False @@ -84,4 +86,8 @@ if "load_chat" in argv: else: from files.routes import * +if FEATURES['HOLIDAY_EVENT']: + from events import * + init_event() + stdout.flush() diff --git a/files/assets/app_PCM_v2.7.apk b/files/assets/app_PCM_v2.7.apk new file mode 100644 index 000000000..2ba815ce6 Binary files /dev/null and b/files/assets/app_PCM_v2.7.apk differ diff --git a/files/assets/app_WPD_v2.7.apk b/files/assets/app_WPD_v2.7.apk new file mode 100644 index 000000000..2e9e4b80f Binary files /dev/null and b/files/assets/app_WPD_v2.7.apk differ diff --git a/files/assets/app_rDrama_v2.7.apk b/files/assets/app_rDrama_v2.7.apk new file mode 100644 index 000000000..b6b566834 Binary files /dev/null and b/files/assets/app_rDrama_v2.7.apk differ diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 959ff605c..2fb8dff40 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -1692,10 +1692,10 @@ button.close { } .modal-dialog-scrollable { display: flex; - max-height: calc(100% - 3.5rem); + max-height: calc(100% - 1rem); } .modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 3.5rem); + max-height: calc(100vh - 1rem); overflow: hidden; } .modal-dialog-scrollable .modal-header, .modal-dialog-scrollable .modal-footer { @@ -1707,11 +1707,11 @@ button.close { .modal-dialog-centered { display: flex; align-items: center; - max-height: calc(100% - 3.5rem); + min-height: calc(100% - 1rem); } .modal-dialog-centered::before { display: block; - height: calc(100vh - 3.5rem); + height: calc(100vh - 1rem); content: ""; } .modal-dialog-centered.modal-dialog-scrollable { @@ -1788,16 +1788,16 @@ button.close { margin: 0.25rem; } .modal-dialog-scrollable { - max-height: calc(100% - 3.5rem); + max-height: calc(100% - 5rem); } .modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 3.5rem); + max-height: calc(100vh - 5rem); } .modal-dialog-centered { - max-height: calc(100% - 3.5rem); + max-height: calc(100% - 5rem); } .modal-dialog-centered::before { - height: calc(100vh - 3.5rem); + height: calc(100vh - 5rem); } @media (min-width: 992px) { .modal-xl { @@ -4694,7 +4694,7 @@ textarea { } } .container, .container-fluid { - padding-bottom: 8vh; + padding-bottom: 50px; } .navbar { padding: 0.2rem 0 0 0.2rem; @@ -5022,22 +5022,6 @@ img[src="/i/hand.webp"]+img[glow]:not([data-src]) { pat-pfp-anim .3s infinite; } -@keyframes rb { - 10% { color: red; } - 20% { color: orange; } - 30% { color: yellow; } - 40% { color: green; } - 50% { color: cyan; } - 70% { color: blue; } - 80% { color: indigo; } - 90% { color: violet; } -} - -.zozbot { - font-weight: bold; - animation: rb 8s linear infinite; -} - .text-black { color: var(--black); } @@ -5280,8 +5264,8 @@ li > .sidebar { } .navsettings { - padding-left: 1.2rem !important; - padding-right: 1.2rem !important; + padding-left: 0.9rem !important; + padding-right: 0.9rem !important; } @media (max-width: 768px) { @@ -5995,11 +5979,10 @@ g { .fa-volume:before{content:"\f6a8"} .fa-volume-mute:before{content:"\f6a9"} .fa-times:before{content:"\f00d"} -.fa-mobile:before{content:"\f3ce"} +.fa-android:before{content:"\f17b"} .fa-discord:before{content:"\f392"} .fa-github:before{content:"\f09b"} .fa-twitter:before{content:"\f099"} -.fa-git-alt:before{content:"\f841"} .fa-head-side:before{content:"\f6e9"} .fa-crab:before{content:"\e3ff"} .fa-socks:before{content:"\f696"} @@ -6100,11 +6083,15 @@ g { font-size: 20px; } -@media (max-width: 374px) { +@media (max-width: 370px) { .smol-fp { - font-size: 3.3vw; - padding-left: 2.4vw; - padding-right: 2.4vw; + font-size: 0.9rem; + } +} + +@media (max-width: 345px) { + .smol-fp { + font-size: 0.7rem; } } @@ -6356,7 +6343,7 @@ div.markdown { margin-bottom: 10px !important; } #desktop-expanded-image { - max-height:80vh; + max-height:90vh; border:5px white solid; -o-object-fit: contain; object-fit: contain; diff --git a/files/assets/images/emojis/marseyjunkie.webp b/files/assets/images/emojis/marseyjunkie.webp index 7fb119dee..bba1790b2 100644 Binary files a/files/assets/images/emojis/marseyjunkie.webp and b/files/assets/images/emojis/marseyjunkie.webp differ diff --git a/files/assets/images/emojis/marseyllama1.webp b/files/assets/images/emojis/marseyllama1.webp index 9aa52cdc8..8acfe3f3f 100644 Binary files a/files/assets/images/emojis/marseyllama1.webp and b/files/assets/images/emojis/marseyllama1.webp differ diff --git a/files/assets/images/emojis/marseyllama2.webp b/files/assets/images/emojis/marseyllama2.webp index 5c4ff487e..ef61da86a 100644 Binary files a/files/assets/images/emojis/marseyllama2.webp and b/files/assets/images/emojis/marseyllama2.webp differ diff --git a/files/assets/images/emojis/marseyllama3.webp b/files/assets/images/emojis/marseyllama3.webp index ed5a10e98..97e62fdbe 100644 Binary files a/files/assets/images/emojis/marseyllama3.webp and b/files/assets/images/emojis/marseyllama3.webp differ diff --git a/files/assets/images/emojis/marseylong1.webp b/files/assets/images/emojis/marseylong1.webp index dd02c02de..130f4ab4b 100644 Binary files a/files/assets/images/emojis/marseylong1.webp and b/files/assets/images/emojis/marseylong1.webp differ diff --git a/files/assets/images/emojis/marseylong2.webp b/files/assets/images/emojis/marseylong2.webp index 885e55e7a..75355d638 100644 Binary files a/files/assets/images/emojis/marseylong2.webp and b/files/assets/images/emojis/marseylong2.webp differ diff --git a/files/assets/images/emojis/marseylong3.webp b/files/assets/images/emojis/marseylong3.webp index ed1e917b6..1cb2079f9 100644 Binary files a/files/assets/images/emojis/marseylong3.webp and b/files/assets/images/emojis/marseylong3.webp differ diff --git a/files/assets/images/emojis/marseyonemediumsnekvibing.webp b/files/assets/images/emojis/marseyonemediumsnekvibing.webp index b3b7167e8..7dc468b7b 100644 Binary files a/files/assets/images/emojis/marseyonemediumsnekvibing.webp and b/files/assets/images/emojis/marseyonemediumsnekvibing.webp differ diff --git a/files/assets/images/emojis/marseysnek.webp b/files/assets/images/emojis/marseysnek.webp index 3f9aced52..8c55e2d2f 100644 Binary files a/files/assets/images/emojis/marseysnek.webp and b/files/assets/images/emojis/marseysnek.webp differ diff --git a/files/assets/images/emojis/marseysoycrytremble.webp b/files/assets/images/emojis/marseysoycrytremble.webp index edbd39ffd..ea04f3f11 100644 Binary files a/files/assets/images/emojis/marseysoycrytremble.webp and b/files/assets/images/emojis/marseysoycrytremble.webp differ diff --git a/files/assets/images/emojis/marseyzoomer.webp b/files/assets/images/emojis/marseyzoomer.webp index eeb36b445..518631466 100644 Binary files a/files/assets/images/emojis/marseyzoomer.webp and b/files/assets/images/emojis/marseyzoomer.webp differ diff --git a/files/assets/js/bootstrap.js b/files/assets/js/bootstrap.js new file mode 100644 index 000000000..b045941de --- /dev/null +++ b/files/assets/js/bootstrap.js @@ -0,0 +1 @@ +!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).bootstrap=e()}(this,(function(){"use strict";const t=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i="#"+i.split("#")[1]),e=i&&"#"!==i?i.trim():null}return e},e=e=>{const i=t(e);return i&&document.querySelector(i)?i:null},i=e=>{const i=t(e);return i?document.querySelector(i):null},n=t=>{t.dispatchEvent(new Event("transitionend"))},s=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),o=t=>s(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,r=(t,e,i)=>{Object.keys(i).forEach(n=>{const o=i[n],r=e[n],a=r&&s(r)?"element":null==(l=r)?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(o).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${o}".`)})},a=t=>!(!s(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",()=>{f.forEach(t=>t())}),f.push(e)):e()},g=t=>{"function"==typeof t&&t()},_=(t,e,i=!0)=>{if(!i)return void g(t);const s=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let o=!1;const r=({target:i})=>{i===e&&(o=!0,e.removeEventListener("transitionend",r),g(t))};e.addEventListener("transitionend",r),setTimeout(()=>{o||n(e)},s)},b=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,E={};let A=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},O=/^(mouseenter|mouseleave)/i,C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function k(t,e){return e&&`${e}::${A++}`||t.uidEvent||A++}function L(t){const e=k(t);return t.uidEvent=e,E[e]=E[e]||{},E[e]}function x(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=D(e,i,n),l=L(t),c=l[a]||(l[a]={}),h=x(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=k(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&P.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&P.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function N(t,e,i,n,s){const o=x(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function I(t){return t=t.replace(y,""),T[t]||t}const P={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=D(e,i,n),a=r!==e,l=L(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void N(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach(i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach(o=>{if(o.includes(n)){const n=s[o];N(t,e,i,n.originalHandler,n.delegationSelector)}})}(t,l,i,e.slice(1))});const h=l[r]||{};Object.keys(h).forEach(i=>{const n=i.replace(w,"");if(!a||e.includes(n)){const e=h[i];N(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u(),s=I(e),o=e!==s,r=C.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach(t=>{Object.defineProperty(d,t,{get:()=>i[t]})}),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},j=new Map;var M={set(t,e,i){j.has(t)||j.set(t,new Map);const n=j.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>j.has(t)&&j.get(t).get(e)||null,remove(t,e){if(!j.has(t))return;const i=j.get(t);i.delete(e),0===i.size&&j.delete(t)}};class H{constructor(t){(t=o(t))&&(this._element=t,M.set(this._element,this.constructor.DATA_KEY,this))}dispose(){M.remove(this._element,this.constructor.DATA_KEY),P.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach(t=>{this[t]=null})}_queueCallback(t,e,i=!0){_(t,e,i)}static getInstance(t){return M.get(o(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.1"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return"bs."+this.NAME}static get EVENT_KEY(){return"."+this.DATA_KEY}}const B=(t,e="hide")=>{const n="click.dismiss"+t.EVENT_KEY,s=t.NAME;P.on(document,n,`[data-bs-dismiss="${s}"]`,(function(n){if(["A","AREA"].includes(this.tagName)&&n.preventDefault(),l(this))return;const o=i(this)||this.closest("."+s);t.getOrCreateInstance(o)[e]()}))};class R extends H{static get NAME(){return"alert"}close(){if(P.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback(()=>this._destroyElement(),this._element,t)}_destroyElement(){this._element.remove(),P.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=R.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}B(R,"close"),m(R);class W extends H{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function z(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function q(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}P.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');W.getOrCreateInstance(e).toggle()}),m(W);const F={setDataAttribute(t,e,i){t.setAttribute("data-bs-"+q(e),i)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+q(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=z(t.dataset[i])}),e},getDataAttribute:(t,e)=>z(t.getAttribute("data-bs-"+q(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},U={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map(t=>t+':not([tabindex^="-"])').join(", ");return this.find(e,t).filter(t=>!l(t)&&a(t))}},$={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},V={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},K="next",X="prev",Y="left",Q="right",G={ArrowLeft:Q,ArrowRight:Y};class Z extends H{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=U.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return $}static get NAME(){return"carousel"}next(){this._slide(K)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(X)}pause(t){t||(this._isPaused=!0),U.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(n(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=U.findOne(".active.carousel-item",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void P.one(this._element,"slid.bs.carousel",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const i=t>e?K:X;this._slide(i,this._items[t])}_getConfig(t){return t={...$,...F.getDataAttributes(this._element),..."object"==typeof t?t:{}},r("carousel",t,V),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?Q:Y)}_addEventListeners(){this._config.keyboard&&P.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&(P.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),P.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};U.find(".carousel-item img",this._element).forEach(t=>{P.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?(P.on(this._element,"pointerdown.bs.carousel",t=>e(t)),P.on(this._element,"pointerup.bs.carousel",t=>n(t)),this._element.classList.add("pointer-event")):(P.on(this._element,"touchstart.bs.carousel",t=>e(t)),P.on(this._element,"touchmove.bs.carousel",t=>i(t)),P.on(this._element,"touchend.bs.carousel",t=>n(t)))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=G[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?U.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===K;return b(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(U.findOne(".active.carousel-item",this._element));return P.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=U.findOne(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");const i=U.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{P.trigger(this._element,"slid.bs.carousel",{relatedTarget:o,direction:u,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),d(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add("active"),n.classList.remove("active",h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove("active"),o.classList.add("active"),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[Q,Y].includes(t)?p()?t===Y?X:K:t===Y?K:X:t}_orderToDirection(t){return[K,X].includes(t)?p()?t===X?Y:Q:t===X?Q:Y:t}static carouselInterface(t,e){const i=Z.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){Z.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=i(this);if(!e||!e.classList.contains("carousel"))return;const n={...F.getDataAttributes(e),...F.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(n.interval=!1),Z.carouselInterface(e,n),s&&Z.getInstance(e).to(s),t.preventDefault()}}P.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",Z.dataApiClickHandler),P.on(window,"load.bs.carousel.data-api",()=>{const t=U.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element);null!==s&&o.length&&(this._selector=s,this._triggerArray.push(i))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return J}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=U.find(".collapse .collapse",this._config.parent);e=U.find(".collapse.show, .collapse.collapsing",this._config.parent).filter(e=>!t.includes(e))}const i=U.findOne(this._selector);if(e.length){const n=e.find(t=>i!==t);if(t=n?et.getInstance(n):null,t&&t._isTransitioning)return}if(P.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach(e=>{i!==e&&et.getOrCreateInstance(e,{toggle:!1}).hide(),t||M.set(e,"bs.collapse",null)});const n=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s="scroll"+(n[0].toUpperCase()+n.slice(1));this._queueCallback(()=>{this._isTransitioning=!1,this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[n]="",P.trigger(this._element,"shown.bs.collapse")},this._element,!0),this._element.style[n]=this._element[s]+"px"}hide(){if(this._isTransitioning||!this._isShown())return;if(P.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",d(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),P.trigger(this._element,"hidden.bs.collapse")},this._element,!0)}_isShown(t=this._element){return t.classList.contains("show")}_getConfig(t){return(t={...J,...F.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=o(t.parent),r("collapse",t,tt),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=U.find(".collapse .collapse",this._config.parent);U.find('[data-bs-toggle="collapse"]',this._config.parent).filter(e=>!t.includes(e)).forEach(t=>{const e=i(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))})}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach(t=>{e?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",e)})}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=et.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}P.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const i=e(this);U.find(i).forEach(t=>{et.getOrCreateInstance(t,{toggle:!1}).toggle()})})),m(et);var it="top",nt="bottom",st="right",ot="left",rt=[it,nt,st,ot],at="end",lt=rt.reduce((function(t,e){return t.concat([e+"-start",e+"-"+at])}),[]),ct=[].concat(rt,["auto"]).reduce((function(t,e){return t.concat([e,e+"-start",e+"-"+at])}),[]),ht=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function dt(t){return t?(t.nodeName||"").toLowerCase():null}function ut(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ft(t){return t instanceof ut(t).Element||t instanceof Element}function pt(t){return t instanceof ut(t).HTMLElement||t instanceof HTMLElement}function mt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof ut(t).ShadowRoot||t instanceof ShadowRoot)}var gt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];pt(s)&&dt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});pt(n)&&dt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function _t(t){return t.split("-")[0]}var bt=Math.round;function vt(t,e){void 0===e&&(e=!1);var i=t.getBoundingClientRect(),n=1,s=1;if(pt(t)&&e){var o=t.offsetHeight,r=t.offsetWidth;r>0&&(n=i.width/r||1),o>0&&(s=i.height/o||1)}return{width:bt(i.width/n),height:bt(i.height/s),top:bt(i.top/s),right:bt(i.right/n),bottom:bt(i.bottom/s),left:bt(i.left/n),x:bt(i.left/n),y:bt(i.top/s)}}function yt(t){var e=vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function wt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&mt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Et(t){return ut(t).getComputedStyle(t)}function At(t){return["table","td","th"].indexOf(dt(t))>=0}function Tt(t){return((ft(t)?t.ownerDocument:t.document)||window.document).documentElement}function Ot(t){return"html"===dt(t)?t:t.assignedSlot||t.parentNode||(mt(t)?t.host:null)||Tt(t)}function Ct(t){return pt(t)&&"fixed"!==Et(t).position?t.offsetParent:null}function kt(t){for(var e=ut(t),i=Ct(t);i&&At(i)&&"static"===Et(i).position;)i=Ct(i);return i&&("html"===dt(i)||"body"===dt(i)&&"static"===Et(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&pt(t)&&"fixed"===Et(t).position)return null;for(var i=Ot(t);pt(i)&&["html","body"].indexOf(dt(i))<0;){var n=Et(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Lt(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var xt=Math.max,Dt=Math.min,St=Math.round;function Nt(t,e,i){return xt(t,Dt(e,i))}function It(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Pt(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}var jt={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=_t(i.placement),l=Lt(a),c=[ot,st].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return It("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Pt(t,rt))}(s.padding,i),d=yt(o),u="y"===l?it:ot,f="y"===l?nt:st,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=kt(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=Nt(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&wt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Mt(t){return t.split("-")[1]}var Ht={top:"auto",right:"auto",bottom:"auto",left:"auto"};function Bt(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:St(St(e*n)/n)||0,y:St(St(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=ot,v=it,y=window;if(c){var w=kt(i),E="clientHeight",A="clientWidth";w===ut(i)&&"static"!==Et(w=Tt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==it&&(s!==ot&&s!==st||o!==at)||(v=nt,m-=w[E]-n.height,m*=l?1:-1),s!==ot&&(s!==it&&s!==nt||o!==at)||(b=st,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&Ht);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}var Rt={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:_t(e.placement),variation:Mt(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,Bt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,Bt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}},Wt={passive:!0},zt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=ut(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,Wt)})),a&&l.addEventListener("resize",i.update,Wt),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,Wt)})),a&&l.removeEventListener("resize",i.update,Wt)}},data:{}},qt={left:"right",right:"left",bottom:"top",top:"bottom"};function Ft(t){return t.replace(/left|right|bottom|top/g,(function(t){return qt[t]}))}var Ut={start:"end",end:"start"};function $t(t){return t.replace(/start|end/g,(function(t){return Ut[t]}))}function Vt(t){var e=ut(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Kt(t){return vt(Tt(t)).left+Vt(t).scrollLeft}function Xt(t){var e=Et(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Yt(t,e){var i;void 0===e&&(e=[]);var n=function t(e){return["html","body","#document"].indexOf(dt(e))>=0?e.ownerDocument.body:pt(e)&&Xt(e)?e:t(Ot(e))}(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=ut(n),r=s?[o].concat(o.visualViewport||[],Xt(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Yt(Ot(r)))}function Qt(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Gt(t,e){return"viewport"===e?Qt(function(t){var e=ut(t),i=Tt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+Kt(t),y:a}}(t)):pt(e)?function(t){var e=vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Qt(function(t){var e,i=Tt(t),n=Vt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=xt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=xt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Kt(t),l=-n.scrollTop;return"rtl"===Et(s||i).direction&&(a+=xt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Tt(t)))}function Zt(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?_t(s):null,r=s?Mt(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case it:e={x:a,y:i.y-n.height};break;case nt:e={x:a,y:i.y+i.height};break;case st:e={x:i.x+i.width,y:l};break;case ot:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Lt(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case"start":e[c]=e[c]-(i[h]/2-n[h]/2);break;case at:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function Jt(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?"clippingParents":o,a=i.rootBoundary,l=void 0===a?"viewport":a,c=i.elementContext,h=void 0===c?"popper":c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=It("number"!=typeof p?p:Pt(p,rt)),g="popper"===h?"reference":"popper",_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Yt(Ot(t)),i=["absolute","fixed"].indexOf(Et(t).position)>=0&&pt(t)?kt(t):t;return ft(i)?e.filter((function(t){return ft(t)&&wt(t,i)&&"body"!==dt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Gt(t,i);return e.top=xt(n.top,e.top),e.right=Dt(n.right,e.right),e.bottom=Dt(n.bottom,e.bottom),e.left=xt(n.left,e.left),e}),Gt(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}(ft(b)?b:b.contextElement||Tt(t.elements.popper),r,l),y=vt(t.elements.reference),w=Zt({reference:y,element:_,strategy:"absolute",placement:s}),E=Qt(Object.assign({},_,w)),A="popper"===h?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if("popper"===h&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[st,nt].indexOf(t)>=0?1:-1,i=[it,nt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function te(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ct:l,h=Mt(n),d=h?a?lt:lt.filter((function(t){return Mt(t)===h})):rt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=Jt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[_t(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}var ee={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=_t(g),b=l||(_!==g&&p?function(t){if("auto"===_t(t))return[];var e=Ft(t);return[$t(t),e,$t(e)]}(g):[Ft(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat("auto"===_t(i)?te(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=Jt(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?st:ot:L?nt:it;y[D]>w[D]&&(N=Ft(N));var I=Ft(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ie(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ne(t){return[it,st,nt,ot].some((function(e){return t[e]>=0}))}var se={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=Jt(e,{elementContext:"reference"}),a=Jt(e,{altBoundary:!0}),l=ie(r,n),c=ie(a,s,o),h=ne(l),d=ne(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},oe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ct.reduce((function(t,i){return t[i]=function(t,e,i){var n=_t(t),s=[ot,it].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[ot,st].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},re={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Zt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},ae={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=Jt(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=_t(e.placement),b=Mt(e.placement),v=!b,y=Lt(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?it:ot,L="y"===y?nt:st,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P="start"===b?A[x]:T[x],j="start"===b?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?yt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],z=Nt(0,A[x],H[x]),q=v?A[x]/2-I-z-R-O:P-z-R-O,F=v?-A[x]/2+I+z+W+O:j+z+W+O,U=e.elements.arrow&&kt(e.elements.arrow),$=U?"y"===y?U.clientTop||0:U.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+q-V-$,X=E[y]+F-V;if(o){var Y=Nt(f?Dt(S,K):S,D,f?xt(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?it:ot,G="x"===y?nt:st,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=Nt(f?Dt(J,K):J,Z,f?xt(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function le(t,e,i){void 0===i&&(i=!1);var n,s,o=pt(e),r=pt(e)&&function(t){var e=t.getBoundingClientRect(),i=e.width/t.offsetWidth||1,n=e.height/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Tt(e),l=vt(t,r),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==dt(e)||Xt(a))&&(c=(n=e)!==ut(n)&&pt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Vt(n)),pt(e)?((h=vt(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Kt(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}var ce={placement:"bottom",modifiers:[],strategy:"absolute"};function he(){for(var t=arguments.length,e=new Array(t),i=0;iP.on(t,"mouseover",h)),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add("show"),this._element.classList.add("show"),P.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(l(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){P.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>P.off(t,"mouseover",h)),this._popper&&this._popper.destroy(),this._menu.classList.remove("show"),this._element.classList.remove("show"),this._element.setAttribute("aria-expanded","false"),F.removeDataAttribute(this._menu,"popper"),P.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...F.getDataAttributes(this._element),...t},r("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!s(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_createPopper(t){if(void 0===me)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:s(this._config.reference)?e=o(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find(t=>"applyStyles"===t.name&&!1===t.enabled);this._popper=pe(e,this._menu,i),n&&F.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains("show")}_getMenuElement(){return U.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return we;if(t.classList.contains("dropstart"))return Ee;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?be:_e:e?ye:ve}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=U.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(a);i.length&&b(i,e,"ArrowDown"===t,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Oe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=U.find('[data-bs-toggle="dropdown"]');for(let i=0,n=e.length;ie+t),this._setElementAttributes(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight",e=>e+t),this._setElementAttributes(".sticky-top","marginRight",e=>e-t)}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=i(Number.parseFloat(s))+"px"})}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),this._resetElementAttributes(".sticky-top","marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,t=>{const i=F.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(F.removeDataAttribute(t,e),t.style[e]=i)})}_applyManipulationCallback(t,e){s(t)?e(t):U.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const ke={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},Le={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"};class xe{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&d(this._getElement()),this._getElement().classList.add("show"),this._emulateAnimation(()=>{g(t)})):g(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove("show"),this._emulateAnimation(()=>{this.dispose(),g(t)})):g(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...ke,..."object"==typeof t?t:{}}).rootElement=o(t.rootElement),r("backdrop",t,Le),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),P.on(this._getElement(),"mousedown.bs.backdrop",()=>{g(this._config.clickCallback)}),this._isAppended=!0)}dispose(){this._isAppended&&(P.off(this._element,"mousedown.bs.backdrop"),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const De={trapElement:null,autofocus:!0},Se={trapElement:"element",autofocus:"boolean"};class Ne{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),P.off(document,".bs.focustrap"),P.on(document,"focusin.bs.focustrap",t=>this._handleFocusin(t)),P.on(document,"keydown.tab.bs.focustrap",t=>this._handleKeydown(t)),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,P.off(document,".bs.focustrap"))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=U.focusableChildren(i);0===n.length?i.focus():"backward"===this._lastTabNavDirection?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?"backward":"forward")}_getConfig(t){return t={...De,..."object"==typeof t?t:{}},r("focustrap",t,Se),t}}const Ie={backdrop:!0,keyboard:!0,focus:!0},Pe={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"};class je extends H{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=U.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new Ce}static get Default(){return Ie}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||P.trigger(this._element,"show.bs.modal",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add("modal-open"),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),P.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{P.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(){if(!this._isShown||this._isTransitioning)return;if(P.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove("show"),P.off(this._element,"click.dismiss.bs.modal"),P.off(this._dialog,"mousedown.dismiss.bs.modal"),this._queueCallback(()=>this._hideModal(),this._element,t)}dispose(){[window,this._dialog].forEach(t=>P.off(t,".bs.modal")),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new xe({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ne({trapElement:this._element})}_getConfig(t){return t={...Ie,...F.getDataAttributes(this._element),..."object"==typeof t?t:{}},r("modal",t,Pe),t}_showElement(t){const e=this._isAnimated(),i=U.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&d(this._element),this._element.classList.add("show"),this._queueCallback(()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,P.trigger(this._element,"shown.bs.modal",{relatedTarget:t})},this._dialog,e)}_setEscapeEvent(){this._isShown?P.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):P.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?P.on(window,"resize.bs.modal",()=>this._adjustDialog()):P.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),this._scrollBar.reset(),P.trigger(this._element,"hidden.bs.modal")})}_showBackdrop(t){P.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())}),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(P.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains("modal-static")||(n||(i.overflowY="hidden"),t.add("modal-static"),this._queueCallback(()=>{t.remove("modal-static"),n||this._queueCallback(()=>{i.overflowY=""},this._dialog)},this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!p()||i&&!t&&p())&&(this._element.style.paddingLeft=e+"px"),(i&&!t&&!p()||!i&&t&&p())&&(this._element.style.paddingRight=e+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=je.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}P.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=i(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),P.one(e,"show.bs.modal",t=>{t.defaultPrevented||P.one(e,"hidden.bs.modal",()=>{a(this)&&this.focus()})});const n=U.findOne(".modal.show");n&&je.getInstance(n).hide(),je.getOrCreateInstance(e).toggle(this)})),B(je),m(je);const Me={backdrop:!0,keyboard:!0,scroll:!1},He={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class Be extends H{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return"offcanvas"}static get Default(){return Me}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||P.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new Ce).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show"),this._queueCallback(()=>{this._config.scroll||this._focustrap.activate(),P.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})},this._element,!0))}hide(){this._isShown&&(P.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),this._backdrop.hide(),this._queueCallback(()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new Ce).reset(),P.trigger(this._element,"hidden.bs.offcanvas")},this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Me,...F.getDataAttributes(this._element),..."object"==typeof t?t:{}},r("offcanvas",t,He),t}_initializeBackDrop(){return new xe({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ne({trapElement:this._element})}_addEventListeners(){P.on(this._element,"keydown.dismiss.bs.offcanvas",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()})}static jQueryInterface(t){return this.each((function(){const e=Be.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}P.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=i(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;P.one(e,"hidden.bs.offcanvas",()=>{a(this)&&this.focus()});const n=U.findOne(".offcanvas.show");n&&n!==e&&Be.getInstance(n).hide(),Be.getOrCreateInstance(e).toggle(this)})),P.on(window,"load.bs.offcanvas.data-api",()=>U.find(".offcanvas.show").forEach(t=>Be.getOrCreateInstance(t).show())),B(Be),m(Be);const Re=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),We=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,ze=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,qe=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Re.has(i)||Boolean(We.test(t.nodeValue)||ze.test(t.nodeValue));const n=e.filter(t=>t instanceof RegExp);for(let t=0,e=n.length;t{qe(t,a)||i.removeAttribute(t.nodeName)})}return n.body.innerHTML}const Ue=new Set(["sanitize","allowList","sanitizeFn"]),$e={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ve={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},Ke={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Xe={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class Ye extends H{constructor(t,e){if(void 0===me)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Ke}static get NAME(){return"tooltip"}static get Event(){return Xe}static get DefaultType(){return $e}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),P.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=P.trigger(this._element,this.constructor.Event.SHOW),e=c(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(".tooltip-inner").innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add("fade");const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;M.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),P.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=pe(this._element,n,this._getPopperConfig(r)),n.classList.add("show");const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{P.on(t,"mouseover",h)});const d=this.tip.classList.contains("fade");this._queueCallback(()=>{const t=this._hoverState;this._hoverState=null,P.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)},this.tip,d)}hide(){if(!this._popper)return;const t=this.getTipElement();if(P.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>P.off(t,"mouseover",h)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains("fade");this._queueCallback(()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),P.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())},this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove("fade","show"),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".tooltip-inner")}_sanitizeAndSetContent(t,e,i){const n=U.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return s(e)?(e=o(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Fe(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ve[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach(t=>{if("click"===t)P.on(this._element,this.constructor.Event.CLICK,this._config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;P.on(this._element,e,this._config.selector,t=>this._enter(t)),P.on(this._element,i,this._config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},P.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e._config.delay&&e._config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e._config.delay&&e._config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=F.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{Ue.has(t)&&delete e[t]}),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:o(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),r("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=Fe(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=Ye.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(Ye);const Qe={...Ye.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},Ge={...Ye.DefaultType,content:"(string|element|function)"},Ze={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Je extends Ye{static get Default(){return Qe}static get NAME(){return"popover"}static get Event(){return Ze}static get DefaultType(){return Ge}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=Je.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(Je);const ti={offset:10,method:"auto",target:""},ei={offset:"number",method:"string",target:"(string|element)"},ii=".nav-link, .list-group-item, .dropdown-item";class ni extends H{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,P.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return ti}static get NAME(){return"scrollspy"}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?t:this._config.method,n="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),U.find(ii,this._config.target).map(t=>{const s=e(t),o=s?U.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[F[i](o).top+n,s]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){P.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...ti,...F.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=o(t.target)||document.documentElement,r("scrollspy",t,ei),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`),i=U.findOne(e.join(","),this._config.target);i.classList.add("active"),i.classList.contains("dropdown-item")?U.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add("active"):U.parents(i,".nav, .list-group").forEach(t=>{U.prev(t,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),U.prev(t,".nav-item").forEach(t=>{U.children(t,".nav-link").forEach(t=>t.classList.add("active"))})}),P.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){U.find(ii,this._config.target).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){const e=ni.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(window,"load.bs.scrollspy.data-api",()=>{U.find('[data-bs-spy="scroll"]').forEach(t=>new ni(t))}),m(ni);class si extends H{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active"))return;let t;const e=i(this._element),n=this._element.closest(".nav, .list-group");if(n){const e="UL"===n.nodeName||"OL"===n.nodeName?":scope > li > .active":".active";t=U.find(e,n),t=t[t.length-1]}const s=t?P.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(P.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,n);const o=()=>{P.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),P.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?U.children(e,".active"):U.find(":scope > li > .active",e))[0],s=i&&n&&n.classList.contains("fade"),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove("show"),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove("active");const t=U.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),d(t),t.classList.contains("fade")&&t.classList.add("show");let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&U.find(".dropdown-toggle",e).forEach(t=>t.classList.add("active")),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=si.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}P.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||si.getOrCreateInstance(this).show()})),m(si);const oi={animation:"boolean",autohide:"boolean",delay:"number"},ri={animation:!0,autohide:!0,delay:5e3};class ai extends H{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return oi}static get Default(){return ri}static get NAME(){return"toast"}show(){P.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove("hide"),d(this._element),this._element.classList.add("show"),this._element.classList.add("showing"),this._queueCallback(()=>{this._element.classList.remove("showing"),P.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()},this._element,this._config.animation))}hide(){this._element.classList.contains("show")&&(P.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add("showing"),this._queueCallback(()=>{this._element.classList.add("hide"),this._element.classList.remove("showing"),this._element.classList.remove("show"),P.trigger(this._element,"hidden.bs.toast")},this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),super.dispose()}_getConfig(t){return t={...ri,...F.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},r("toast",t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout(()=>{this.hide()},this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){P.on(this._element,"mouseover.bs.toast",t=>this._onInteraction(t,!0)),P.on(this._element,"mouseout.bs.toast",t=>this._onInteraction(t,!1)),P.on(this._element,"focusin.bs.toast",t=>this._onInteraction(t,!0)),P.on(this._element,"focusout.bs.toast",t=>this._onInteraction(t,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ai.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return B(ai),m(ai),{Alert:R,Button:W,Carousel:Z,Collapse:et,Dropdown:Oe,Modal:je,Offcanvas:Be,Popover:Je,ScrollSpy:ni,Tab:si,Toast:ai,Tooltip:Ye}})); \ No newline at end of file diff --git a/files/assets/js/clipboard.js b/files/assets/js/clipboard.js new file mode 100644 index 000000000..774c9aa00 --- /dev/null +++ b/files/assets/js/clipboard.js @@ -0,0 +1,7 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={134:function(t,e,n){"use strict";n.d(e,{default:function(){return r}});var e=n(279),i=n.n(e),e=n(370),a=n.n(e),e=n(817),o=n.n(e);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t,e){for(var n=0;n { - for(let el of document.getElementsByClassName('bet')) { - el.disabled = true; - } - for(let el of document.getElementsByClassName('cost')) { - el.classList.add('d-none') - } - var scoretext = document.getElementById('option-' + oid); - var score = Number(scoretext.textContent); - scoretext.textContent = score + 1; +function bet_vote(oid) { + for(let el of document.getElementsByClassName('bet')) { + el.disabled = true; + } + for(let el of document.getElementsByClassName('cost')) { + el.classList.add('d-none') + } + var scoretext = document.getElementById('option-' + oid); + var score = Number(scoretext.textContent); + scoretext.textContent = score + 1; + post(`/vote/post/option/${oid}`); - document.getElementById("user-coins-amount").innerText = parseInt(document.getElementById("user-coins-amount").innerText) - 200; - } - ); + document.getElementById("user-coins-amount").innerText = parseInt(document.getElementById("user-coins-amount").innerText) - 200; } diff --git a/files/assets/js/comments_v.js b/files/assets/js/comments_v.js index 30b5337e4..acc8e586c 100644 --- a/files/assets/js/comments_v.js +++ b/files/assets/js/comments_v.js @@ -27,13 +27,22 @@ function report_commentModal(id, author) { reportCommentButton.onclick = function() { this.innerHTML='Reporting comment'; + this.disabled = true; + this.classList.add('disabled'); + const form = new FormData(); + form.append("reason", reason_comment.value); + const xhr = createXhrWithFormKey("/report/comment/" + id, "POST", form); - postToast(this, `/report/comment/${id}`, - { - "reason": reason_comment.value - }, - () => {} - ); + xhr[0].onload = function() { + let data + try {data = JSON.parse(xhr[0].response)} + catch(e) {console.log(e)} + success = xhr[0].status >= 200 && xhr[0].status < 300; + showToast(success, getMessageFromJsonData(success, data)); + }; + + xhr[0].onerror=function(){alert(errortext)}; + xhr[0].send(xhr[1]); } }; @@ -86,12 +95,14 @@ function toggleEdit(id){ }; -function delete_commentModal(t, id) { +function delete_commentModal(id) { document.getElementById("deleteCommentButton").onclick = function() { - postToast(t, `/delete/comment/${id}`, - { - }, - () => { + const xhr = createXhrWithFormKey(`/delete/comment/${id}`); + xhr[0].onload = function() { + let data + try {data = JSON.parse(xhr[0].response)} + catch(e) {console.log(e)} + if (xhr[0].status >= 200 && xhr[0].status < 300 && data && data['message']) { if (window.location.pathname == '/admin/reported/comments') { document.getElementById("post-info-"+id).remove() @@ -105,8 +116,12 @@ function delete_commentModal(t, id) { document.getElementById(`delete2-${id}`).classList.add('d-none'); document.getElementById(`undelete2-${id}`).classList.remove('d-none'); } + showToast(true, getMessageFromJsonData(true, data)); + } else { + showToast(false, getMessageFromJsonData(false, data)); } - ); + }; + xhr[0].send(xhr[1]); }; } @@ -234,7 +249,6 @@ function post_comment(fullname, hide){ document.getElementById('reply-form-body-'+fullname).value = '' document.getElementById('form-preview-'+fullname).innerHTML = '' - document.getElementById('charcount-'+fullname).innerHTML = '' document.getElementById('filename-show-reply-' + fullname).innerHTML = ''; } else { diff --git a/files/assets/js/core.js b/files/assets/js/core.js index 228fbaa0b..0e91b0ec6 100644 --- a/files/assets/js/core.js +++ b/files/assets/js/core.js @@ -180,14 +180,19 @@ function smoothScrollTop() } // Click navbar to scroll back to top -document.getElementsByTagName('nav')[0].addEventListener('click', (e) => { - if (e.target.id === "navbar" || - e.target.classList.contains("container-fluid") || - e.target.id == "navbarResponsive" || - e.target.id == "logo-container" || - e.target.classList.contains("srd")) - smoothScrollTop(); -}, false); +(() => { + for (const i of document.querySelectorAll('nav')) + { + i.addEventListener('click', (e) => { + if (e.target.id === "navbar" || + e.target.classList.contains("container-fluid") || + e.target.id == "navbarResponsive" || + e.target.id == "logo-container" || + e.target.classList.contains("srd")) + smoothScrollTop(); + }, false); + } +})(); // Dynamic shadow when the user scrolls document.addEventListener('scroll',function (event) { @@ -255,7 +260,7 @@ function bs_trigger(e) { } }) - if (typeof update_speed_emoji_modal == 'function') { + if (typeof update_speed_emoji_modal != 'undefined') { let forms = e.querySelectorAll("textarea, .allow-emojis"); forms.forEach(i => { let pseudo_div = document.createElement("div"); @@ -353,9 +358,12 @@ function prepare_to_pause(audio) { }); } - window.addEventListener('click', (e) => { - if (e.target.tagName.toLowerCase() == "lite-youtube" && !audio.paused) audio.pause(); - }); + for (const e of document.getElementsByTagName('lite-youtube')) + { + e.addEventListener('click', (event) => { + if (!audio.paused) audio.pause(); + }); + } } function sendFormXHR(e, extraActionsOnSuccess) { @@ -404,9 +412,3 @@ function sendFormXHRSwitch(e) { } ) } - -if ("serviceWorker" in navigator) { - navigator.serviceWorker.register("/service-worker.js?v=3") - .then((registration) => registration.update()) - .catch((e) => console.log("Service worker update failed with error", e)); -} diff --git a/files/assets/js/critters.js b/files/assets/js/critters.js new file mode 100644 index 000000000..6a773f778 --- /dev/null +++ b/files/assets/js/critters.js @@ -0,0 +1,33 @@ +var BugDispatch={options:{minDelay:500,maxDelay:1E4,minBugs:2,maxBugs:20,minSpeed:5,maxSpeed:10,maxLargeTurnDeg:150,maxSmallTurnDeg:10,maxWiggleDeg:5,imageSprite:"fireflies.webp",bugWidth:13,bugHeight:14,num_frames:5,zoom:10,canFly:!0,canDie:!0,numDeathTypes:3,monitorMouseMovement:!1,eventDistanceToBug:40,minTimeBetweenMultipy:1E3,mouseOver:"random"},initialize:function(a){this.options=mergeOptions(this.options,a);this.options.minBugs>this.options.maxBugs&&(this.options.minBugs=this.options.maxBugs); +this.modes=["multiply","nothing"];this.options.canFly&&this.modes.push("fly","flyoff");this.options.canDie&&this.modes.push("die");-1==this.modes.indexOf(this.options.mouseOver)&&(this.options.mouseOver="random");this.transform=null;this.transforms={Moz:function(a){this.bug.style.MozTransform=a},webkit:function(a){this.bug.style.webkitTransform=a},O:function(a){this.bug.style.OTransform=a},ms:function(a){this.bug.style.msTransform=a},Khtml:function(a){this.bug.style.KhtmlTransform=a},w3c:function(a){this.bug.style.transform= +a}};if("transform"in document.documentElement.style)this.transform=this.transforms.w3c;else{var b=["Moz","webkit","O","ms","Khtml"],c=0;for(c=0;cb?d=b:dc||(200=--this.toggle_stationary_counter&&this.toggleStationary(),this.stationary))){if(0>=--this.edge_test_counter&&this.bug_near_window_edge()&&(this.angle_deg%=360,0>this.angle_deg&&(this.angle_deg+=360),15=--this.large_turn_counter&&(this.large_turn_angle_deg=this.random(1,this.options.maxLargeTurnDeg,!0),this.next_large_turn());if(0>=--this.small_turn_counter)this.angle_deg+=this.random(1,this.options.maxSmallTurnDeg),this.next_small_turn();else{a=this.random(1,this.options.maxWiggleDeg,!0);if(0a||0>this.large_turn_angle_deg&&0=this.options.num_frames&&(this.walkIndex=0)},fly:function(a){var b=this.bug.top,c=this.bug.left,d=c-a.left,e=b-a.top,f=Math.atan(e/d);50>Math.abs(d)+Math.abs(e)&&(this.bug.style.backgroundPosition=-2*this.options.bugWidth+ +"px -"+2*this.options.bugHeight+"px");30>Math.abs(d)+Math.abs(e)&&(this.bug.style.backgroundPosition=-1*this.options.bugWidth+"px -"+2*this.options.bugHeight+"px");if(10>Math.abs(d)+Math.abs(e))this.bug.style.backgroundPosition="0 0",this.stop(),this.go();else{var g=Math.cos(f)*this.options.flySpeed;f=Math.sin(f)*this.options.flySpeed;if(c>a.left&&0a.left&&0>g)g*=-1,Math.abs(d)f||b>a.top&&0a&&(a=0);0===a?(a=-2*this.options.bugHeight,b*=Math.random()):1===a?(a=Math.random()*c,b+=2*this.options.bugWidth): +2===a?(a=c+2*this.options.bugHeight,b*=Math.random()):(a=Math.random()*c,b=-3*this.options.bugWidth);this.bug.style.backgroundPosition=-3*this.options.bugWidth+"px "+(this.wingsOpen?"0":"-"+this.options.bugHeight+"px");this.bug.top=a;this.bug.left=b;this.drawBug();a={};a.top=this.random(this.options.edge_resistance,document.documentElement.clientHeight-this.options.edge_resistance);a.left=this.random(this.options.edge_resistance,document.documentElement.clientWidth-this.options.edge_resistance);this.startFlying(a)}}, +walkIn:function(){this.bug||this.makeBug();if(this.bug){this.stop();var a=Math.round(4*Math.random()-.5),b=document,c=b.documentElement,d=b.getElementsByTagName("body")[0];b=window.innerWidth||c.clientWidth||d.clientWidth;c=window.innerHeight||c.clientHeight||d.clientHeight;3a&&(a=0);0===a?(a=-1.3*this.options.bugHeight,b*=Math.random()):1===a?(a=Math.random()*c,b+=.3*this.options.bugWidth):2===a?(a=c+.3*this.options.bugHeight,b*=Math.random()):(a=Math.random()*c,b=-1.3*this.options.bugWidth); +this.bug.style.backgroundPosition=-3*this.options.bugWidth+"px "+(this.wingsOpen?"0":"-"+this.options.bugHeight+"px");this.bug.top=a;this.bug.left=b;this.drawBug();this.go()}},flyOff:function(){this.stop();var a=this.random(0,3),b={},c=document,d=c.documentElement,e=c.getElementsByTagName("body")[0];c=window.innerWidth||d.clientWidth||e.clientWidth;d=window.innerHeight||d.clientHeight||e.clientHeight;0===a?(b.top=-200,b.left=Math.random()*c):1===a?(b.top=Math.random()*d,b.left=c+200):2===a?(b.top= +d+200,b.left=Math.random()*c):(b.top=Math.random()*d,b.left=-200);this.startFlying(b)},die:function(){this.stop();var a=this.random(0,this.options.numDeathTypes-1);this.alive=!1;this.drop(a)},drop:function(a){var b=this.bug.top,c=document,d=c.documentElement;c=c.getElementsByTagName("body")[0];var e=window.innerHeight||d.clientHeight||c.clientHeight;e-=this.options.bugHeight;var f=this.random(0,20,!0);Date.now();var g=this;this.bug.classList.add("bug-dead");this.dropTimer=requestAnimFrame(function(c){g._lastTimestamp= +c;g.dropping(c,b,e,f,a)})},dropping:function(a,b,c,d,e){a-=this._lastTimestamp;var f=b+.002*a*a,g=this;f>=c?(f=c,clearTimeout(this.dropTimer),this.angle_deg=0,this.angle_rad=this.deg2rad(this.angle_deg),this.transform("rotate("+(90-this.angle_deg)+"deg) scale("+this.zoom+")"),this.bug.style.top=null,this.bug.style.bottom=Math.ceil((this.options.bugWidth*this.zoom-this.options.bugHeight*this.zoom)/2-this.options.bugHeight/2*(1-this.zoom))+"px",this.bug.style.left=this.bug.left+"px",this.bug.style.backgroundPosition= +"-"+2*e*this.options.bugWidth+"px 100%",this.twitch(e)):(this.dropTimer=requestAnimFrame(function(a){g.dropping(a,b,c,d,e)}),20>a||(this.angle_deg=(this.angle_deg+d)%360,this.angle_rad=this.deg2rad(this.angle_deg),this.moveBug(this.bug.left,f,this.angle_deg)))},twitch:function(a,b){b||(b=0);var c=this;if(0===a||1===a)c.twitchTimer=setTimeout(function(){c.bug.style.backgroundPosition="-"+(2*a+b%2)*c.options.bugWidth+"px 100%";c.twitchTimer=setTimeout(function(){b++;c.bug.style.backgroundPosition="-"+ +(2*a+b%2)*c.options.bugWidth+"px 100%";c.twitch(a,++b)},c.random(300,800))},this.random(1E3,1E4))},rad2deg:function(a){return a*this.rad2deg_k},deg2rad:function(a){return a*this.deg2rad_k},random:function(a,b,c){if(a==b)return a;a=Math.round(a-.5+Math.random()*(b-a+1));return c?.5document.documentElement.clientHeight-this.options.edge_resistance&&(this.near_edge|=this.NEAR_BOTTOM_EDGE);this.bug.leftdocument.documentElement.clientWidth-this.options.edge_resistance&&(this.near_edge|=this.NEAR_RIGHT_EDGE);return this.near_edge},getPos:function(){return this.inserted&& +this.bug&&this.bug.style?{top:parseInt(this.bug.top,10),left:parseInt(this.bug.left,10)}:null}},SpawnBug=function(){var a={},b;for(b in Bug)Bug.hasOwnProperty(b)&&(a[b]=Bug[b]);return a},mergeOptions=function(a,b,c){"undefined"==typeof c&&(c=!0);a=c?cloneOf(a):a;for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);return a},cloneOf=function(a){if(null==a||"object"!=typeof a)return a;var b=a.constructor(),c;for(c in a)a.hasOwnProperty(c)&&(b[c]=cloneOf(a[c]));return b}; +window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a,b){window.setTimeout(a,1E3/60)}}(); \ No newline at end of file diff --git a/files/assets/js/delete_post_modal.js b/files/assets/js/delete_post_modal.js index 1bf02b2cc..16554f16b 100644 --- a/files/assets/js/delete_post_modal.js +++ b/files/assets/js/delete_post_modal.js @@ -1,9 +1,13 @@ -function delete_postModal(t, id) { +function delete_postModal(id) { document.getElementById("deletePostButton").onclick = function() { - postToast(t, `/delete_post/${id}`, - { - }, - () => { + const xhr = createXhrWithFormKey(`/delete_post/${id}`); + xhr[0].onload = function() { + let data + try {data = JSON.parse(xhr[0].response)} + catch(e) {console.log(e)} + success = xhr[0].status >= 200 && xhr[0].status < 300; + showToast(success, getMessageFromJsonData(success, data)); + if (success && data["message"]) { if (window.location.pathname == '/admin/reported/posts') { document.getElementById("flaggers-"+id).remove() @@ -17,7 +21,10 @@ function delete_postModal(t, id) { document.getElementById(`delete2-${id}`).classList.add('d-none'); document.getElementById(`undelete2-${id}`).classList.remove('d-none'); } + } else { + showToast(false, getMessageFromJsonData(false, data)); } - ); + }; + xhr[0].send(xhr[1]); }; } diff --git a/files/assets/js/fp.js b/files/assets/js/fp.js new file mode 100644 index 000000000..6d9cd6cab --- /dev/null +++ b/files/assets/js/fp.js @@ -0,0 +1 @@ +var FingerprintJS=function(e){"use strict";var t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]e.length)return-1;for(var n=0;n>2]+y[(3&t[i])<<4|t[i+1]>>4]+y[(15&t[i+1])<<2|t[i+2]>>6]+y[63&t[i+2]];return n%3==2?r.slice(0,-1)+"=":n%3==1?r.slice(0,-2)+"==":r}function C(e){for(var t="",n=0;n0){var r=e[n].toLowerCase();r!==e[n]?t+=" "+r:t+=e[n]}else t+=e[n].toUpperCase();return t}function _(e){return void 0===e?void 0:""+e}function I(e,t){for(var n="",r=0;r=r+n?(r=a,[4,W(0)]):[3,3]):[3,4];case 2:i.sent(),i.label=3;case 3:return++o,[3,1];case 4:return[2]}}))}))}function K(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]+t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]+t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]+t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]+t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function J(e,t){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],t=[t[0]>>>16,65535&t[0],t[1]>>>16,65535&t[1]];var n=[0,0,0,0];return n[3]+=e[3]*t[3],n[2]+=n[3]>>>16,n[3]&=65535,n[2]+=e[2]*t[3],n[1]+=n[2]>>>16,n[2]&=65535,n[2]+=e[3]*t[2],n[1]+=n[2]>>>16,n[2]&=65535,n[1]+=e[1]*t[3],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[2]*t[2],n[0]+=n[1]>>>16,n[1]&=65535,n[1]+=e[3]*t[1],n[0]+=n[1]>>>16,n[1]&=65535,n[0]+=e[0]*t[3]+e[1]*t[2]+e[2]*t[1]+e[3]*t[0],n[0]&=65535,[n[0]<<16|n[1],n[2]<<16|n[3]]}function X(e,t){return 32===(t%=64)?[e[1],e[0]]:t<32?[e[0]<>>32-t,e[1]<>>32-t]:(t-=32,[e[1]<>>32-t,e[0]<>>32-t])}function Y(e,t){return 0===(t%=64)?e:t<32?[e[0]<>>32-t,e[1]<>>1]),e=Z(e=J(e,[4283543511,3981806797]),[0,e[0]>>>1]),e=Z(e=J(e,[3301882366,444984403]),[0,e[0]>>>1])}function ee(e){return parseInt(e)}function te(e){return parseFloat(e)}function ne(e,t){return"number"==typeof e&&isNaN(e)?t:e}function re(e){return e.reduce((function(e,t){return e+(t?1:0)}),0)}function ie(e){return e&&"object"==typeof e&&"message"in e?e:{message:e}}function oe(e,t,n){var o=Object.keys(e).filter((function(e){return!function(e,t){for(var n=0,r=e.length;n=4}function ue(){var e=window,t=navigator;return re(["msWriteProfilerMark"in e,"MSStream"in e,"msLaunchUri"in t,"msSaveBlob"in t])>=3&&!ae()}function se(){var e=window,t=navigator;return re(["webkitPersistentStorage"in t,"webkitTemporaryStorage"in t,0===t.vendor.indexOf("Google"),"webkitResolveLocalFileSystemURL"in e,"BatteryManager"in e,"webkitMediaStream"in e,"webkitSpeechGrammar"in e])>=5}function ce(){var e=window,t=navigator;return re(["ApplePayError"in e,"CSSPrimitiveValue"in e,"Counter"in e,0===t.vendor.indexOf("Apple"),"getStorageUpdates"in t,"WebKitMediaKeys"in e])>=4}function le(){var e=window;return re(["safari"in e,!("DeviceMotionEvent"in e),!("ongestureend"in e),!("standalone"in navigator)])>=3}function fe(){var e,t,n=window;return re(["buildID"in navigator,"MozAppearance"in(null!==(t=null===(e=document.documentElement)||void 0===e?void 0:e.style)&&void 0!==t?t:{}),"onmozfullscreenchange"in n,"mozInnerScreenX"in n,"CSSMozDocumentRule"in n,"CanvasCaptureMediaStream"in n])>=4}function de(){var e=document;return e.fullscreenElement||e.msFullscreenElement||e.mozFullScreenElement||e.webkitFullscreenElement||null}function ve(){var e=se(),t=fe();if(!e&&!t)return!1;var n=window;return re(["onorientationchange"in n,"orientation"in n,e&&!("SharedWorker"in n),t&&/android/i.test(navigator.appVersion)])>=2}function he(e){var t=new Error(e);return t.name=e,t}function me(e,t,n){var o,a,u;return void 0===n&&(n=50),r(this,void 0,void 0,(function(){var r,s;return i(this,(function(i){switch(i.label){case 0:r=document,i.label=1;case 1:return r.body?[3,3]:[4,W(n)];case 2:return i.sent(),[3,1];case 3:s=r.createElement("iframe"),i.label=4;case 4:return i.trys.push([4,,10,11]),[4,new Promise((function(e,n){var i=!1,o=function(){i=!0,e()};s.onload=o,s.onerror=function(e){i=!0,n(e)};var a=s.style;a.setProperty("display","block","important"),a.position="absolute",a.top="0",a.left="0",a.visibility="hidden",t&&"srcdoc"in s?s.srcdoc=t:s.src="about:blank",r.body.appendChild(s);var u=function(){var e,t;i||("complete"===(null===(t=null===(e=s.contentWindow)||void 0===e?void 0:e.document)||void 0===t?void 0:t.readyState)?o():setTimeout(u,10))};u()}))];case 5:i.sent(),i.label=6;case 6:return(null===(a=null===(o=s.contentWindow)||void 0===o?void 0:o.document)||void 0===a?void 0:a.body)?[3,8]:[4,W(n)];case 7:return i.sent(),[3,6];case 8:return[4,e(s,s.contentWindow)];case 9:return[2,i.sent()];case 10:return null===(u=s.parentNode)||void 0===u||u.removeChild(s),[7];case 11:return[2]}}))}))}function pe(e){for(var t=function(e){for(var t,n,r="Unexpected syntax '"+e+"'",i=/^\s*([a-z-]*)(.*)$/i.exec(e),o=i[1]||void 0,a={},u=/([.:#][\w-]+|\[.+?\])/gi,s=function(e,t){a[e]=a[e]||[],a[e].push(t)};;){var c=u.exec(i[2]);if(!c)break;var l=c[0];switch(l[0]){case".":s("class",l.slice(1));break;case"#":s("id",l.slice(1));break;case"[":var f=/^\[([\w-]+)([~|^$*]?=("(.*?)"|([\w-]+)))?(\s+[is])?\]$/.exec(l);if(!f)throw new Error(r);s(f[1],null!==(n=null!==(t=f[4])&&void 0!==t?t:f[5])&&void 0!==n?n:"");break;default:throw new Error(r)}}return[o,a]}(e),n=t[0],r=t[1],i=document.createElement(null!=n?n:"div"),o=0,a=Object.keys(r);o.6*t.length}))).sort(),[2,r]}}))}))},fontPreferences:function(){return function(e,t){void 0===t&&(t=4e3);return me((function(n,r){var i=r.document,a=i.body,u=a.style;u.width=t+"px",u.webkitTextSizeAdjust=u.textSizeAdjust="none",se()?a.style.zoom=""+1/r.devicePixelRatio:ce()&&(a.style.zoom="reset");var s=i.createElement("div");return s.textContent=o(Array(t/20<<0)).map((function(){return"word"})).join(" "),a.appendChild(s),e(i,a)}),'')}((function(e,t){for(var n={},r={},i=0,o=Object.keys(Fe);i=3}())return-1;var n=new t(1,5e3,44100),r=n.createOscillator();r.type="triangle",r.frequency.value=1e4;var i=n.createDynamicsCompressor();i.threshold.value=-50,i.knee.value=40,i.ratio.value=12,i.attack.value=0,i.release.value=.25,r.connect(i),i.connect(n.destination),r.start(0);var o=function(e){var t=3,n=500,r=500,i=5e3,o=function(){};return[new Promise((function(a,u){var s=!1,c=0,l=0;e.oncomplete=function(e){return a(e.renderedBuffer)};var f=function(){setTimeout((function(){return u(he("timeout"))}),Math.min(r,l+i-Date.now()))},d=function(){try{switch(e.startRendering(),e.state){case"running":l=Date.now(),s&&f();break;case"suspended":document.hidden||c++,s&&c>=t?u(he("suspended")):setTimeout(d,n)}}catch(r){u(r)}};d(),o=function(){s||(s=!0,l>0&&f())}})),o]}(n),a=o[0],u=o[1],s=a.then((function(e){return function(e){for(var t=0,n=0;n=1)return Math.round(e/t)*t;var n=1/t;return Math.round(e*n)/n}(e,10)})(e[0]),n(e[1]),n(e[2]),n(e[3])]]}}))}))}},osCpu:function(){return navigator.oscpu},languages:function(){var e,t=navigator,n=[],r=t.language||t.userLanguage||t.browserLanguage||t.systemLanguage;if(void 0!==r&&n.push([r]),Array.isArray(t.languages))se()&&re([!("MediaSettingsRange"in(e=window)),"RTCEncodedAudioFrame"in e,""+e.Intl=="[object Intl]",""+e.Reflect=="[object Reflect]"])>=3||n.push(t.languages);else if("string"==typeof t.languages){var i=t.languages;i&&n.push(i.split(","))}return n},colorDepth:function(){return window.screen.colorDepth},deviceMemory:function(){return ne(te(navigator.deviceMemory),void 0)},screenResolution:function(){var e=screen,t=function(e){return ne(ee(e),null)},n=[t(e.width),t(e.height)];return n.sort().reverse(),n},hardwareConcurrency:function(){return ne(ee(navigator.hardwareConcurrency),void 0)},timezone:function(){var e,t=null===(e=window.Intl)||void 0===e?void 0:e.DateTimeFormat;if(t){var n=(new t).resolvedOptions().timeZone;if(n)return n}var r,i=(r=(new Date).getFullYear(),-Math.max(te(new Date(r,0,1).getTimezoneOffset()),te(new Date(r,6,1).getTimezoneOffset())));return"UTC"+(i>=0?"+":"")+Math.abs(i)},sessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},localStorage:function(){try{return!!window.localStorage}catch(e){return!0}},indexedDB:function(){if(!ae()&&!ue())try{return!!window.indexedDB}catch(e){return!0}},openDatabase:function(){return!!window.openDatabase},cpuClass:function(){return navigator.cpuClass},platform:function(){var e=navigator.platform;return"MacIntel"===e&&ce()&&!le()?function(){if("iPad"===navigator.platform)return!0;var e=screen,t=e.width/e.height;return re(["MediaSource"in window,!!Element.prototype.webkitRequestFullscreen,t>.65&&t<1.53])>=2}()?"iPad":"iPhone":e},plugins:function(){var e=navigator.plugins;if(e){for(var t=[],n=0;n>>0).toString(16)).slice(-8)+("00000000"+(o[1]>>>0).toString(16)).slice(-8)+("00000000"+(a[0]>>>0).toString(16)).slice(-8)+("00000000"+(a[1]>>>0).toString(16)).slice(-8)};function qe(){var e=window,t=navigator;return k(["maxTouchPoints"in t,"mediaCapabilities"in t,"PointerEvent"in e,"visualViewport"in e,"onafterprint"in e])>=4}function Ve(){var e=window;return k([!("PushManager"in e),!("AudioBuffer"in e),!("RTCPeerConnection"in e),!("geolocation"in navigator),!("ServiceWorker"in e)])>=3}var ze=function(e){return new We(e).addEvent},We=function(){function e(e){var t=this;this.onReportReady=e,this.isStopped=!1,this.pageStartTimestamp=function(){var e,t,n=performance;if(n.timeOrigin){var r=null===(t=null===(e=n.getEntriesByType)||void 0===e?void 0:e.call(n,"navigation"))||void 0===t?void 0:t[0];if(r)return n.timeOrigin+(r.responseStart||r.unloadEventEnd)}return n.timing.domLoading||n.timing.responseStart||n.timing.unloadEventEnd}(),this.events={},this.addEvent=function(e){if(!t.isStopped){var n={time:new Date,type:"agentEvent",event:e};switch(0===e.e&&(n.documentReadyState=document.readyState,n.isPageVisible=Qe(),n.isFullscreen=et(),n.network=tt()),t.storeAgentEvent(n),e.e){case 2:t.submitReport(e.agentId,void 0);break;case 4:case 5:t.submitReport(e.agentId,e.getCallId)}}};for(var n=window,r=document,i=[[r,"readystatechange",function(){return t.handleDocumentReadyStateChange()}],[r,"visibilitychange",function(){return t.handleVisibilityChange()}],[r,"pageshow",function(){return t.handlePageTransition(!0)}],[r,"pagehide",function(){return t.handlePageTransition(!1)}],[n,"unload",function(){return t.handlePageUnload()}]],o=0,a=i;o=o)break;var v=d&&d.time.getTime()<=o,h=((null==d?void 0:d.time)||i).getTime()-f.time.getTime();u.triesCount++,u.triesTotalDuration+=h,v&&(u.completeTriesCount++,u.completeTriesTotalDuration+=h)}}return u}function Xe(e,n){return e?t(t({},e),n()):void 0}function Ye(e){for(var t={},n=0,r=Object.keys(e);n1800?A(new Uint8Array(c,0,1800))+"...":A(c))}return s(t(t({},u),{body:c}))}}function at(e){if(!e||"incomplete"===e.state||"fail"===e.state)return e;e.componentDurations;var r=n(e,["componentDurations"]),i=Object.keys(e.failedComponents),o=i.length?","+i.join(",")+",":void 0;return t(t({},r),{failedComponents:o})}function ut(e,n){void 0===n&&(n="_");for(var r=t({},e),i=0,o=Object.keys(e);i=500)return t;throw t}function Mt(e,t,n,r,i){void 0===i&&(i=P);var o=i()%(n+1),a=function(e){if("function"==typeof TextEncoder)return(new TextEncoder).encode(e);for(var t=unescape(encodeURI(e)),n=new Uint8Array(t.length),r=0;r=2?function(){return r(this,void 0,void 0,(function(){var e,t,n,r,o;return i(this,(function(i){switch(i.label){case 0:return e=Gt(),t=navigator,n=t[e[3]],(r=t[e[4]])?[4,new Promise((function(t){r[e[5]]((function(e,n){return t(n)}))}))]:[3,2];case 1:return o=i.sent(),[3,4];case 2:return(null==n?void 0:n[e[6]])?[4,n[e[6]]().then((function(e){return e.quota}))]:[3,4];case 3:o=i.sent(),i.label=4;case 4:return o?[2,ot?a0?d.push(C+"("+w+")="+e.getParameter(w)):d.push(C+"="+w)}}for(var _=0,I=fn;_0&&t(n),[2]}}))}))}),30))},s.createOffer().then((function(n){var r=n.sdp;if(!r)return t(-5);for(var i=[],c=0;c=4)?[2,-2]:[4,Sn(t=An())];case 1:return n=r.sent(),null==e||e(),"number"==typeof n?[2,n]:n.length===t.length?[2,-3]:n.length>1?[2,Tn(n)]:1===n.length?[2,n[0]]:[2,-1]}var i}))}))}function _n(){var e,t,n,r=((n=new Promise((function(n,r){e=n,t=r}))).resolve=e,n.reject=t,n),i=f(le()?310:410);return h(Promise.race([r,i]).then((function(e){if(void 0!==e)return f(e+100-Date.now())})).then((function(){return-4})),(function(){return Cn((function(){return r.resolve(Date.now())}))}))}var In=["brands","mobile","platform","platformVersion","architecture","bitness","model","uaFullVersion"];function On(){var e;return r(this,void 0,void 0,(function(){var t,n,o,a=this;return i(this,(function(u){switch(u.label){case 0:return(t=navigator.userAgentData)&&"object"==typeof t?(n={},o=[],"function"!=typeof t.getHighEntropyValues?[3,2]:[4,Promise.all(In.map((function(e){return r(a,void 0,void 0,(function(){var r,a;return i(this,(function(i){switch(i.label){case 0:return i.trys.push([0,2,,3]),[4,t.getHighEntropyValues([e])];case 1:return void 0!==(r=i.sent()[e])&&(n[e]="string"==typeof r?r:JSON.stringify(r)),[3,3];case 2:if("NotAllowedError"!==(a=i.sent()).name)throw a;return o.push(e),[3,3];case 3:return[2]}}))}))})))]):[2,void 0];case 1:u.sent(),u.label=2;case 2:return[2,{b:t.brands.map((function(e){return{b:e.brand,v:e.version}})),m:t.mobile,p:null!==(e=t.platform)&&void 0!==e?e:null,h:n,nah:o}]}}))}))}function Pn(){var e=document.createElement("a").attributionsourceid;return void 0===e?void 0:String(e)}function xn(){return function(e){for(var t,n,r=[],i=e;;)try{var o=null===(t=i.location)||void 0===t?void 0:t.href,a=null===(n=i.document)||void 0===n?void 0:n.referrer;if(void 0===o||void 0===a)return{s:1,v:r};r.push({l:o,f:a});var u=i.parent;if(!u||u===i)return{s:0,v:r};i=u}catch(s){if(Dn(s))return{s:1,v:r};throw s}}(window)}function Dn(e){if(!e||"object"!=typeof e)return!1;var t=e;return!(!ae()&&!ue()||"Error"!==t.name&&"TypeError"!==t.name||"Permission denied"!==t.message)||"SecurityError"===t.name}function Mn(){return function(e){var t=e.location,n=e.origin,r=t.origin,i=t.ancestorOrigins,o=null;if(i){o=new Array(i.length);for(var a=0;a=0;--n)if(n%4096==0){var r=Math.random();e.push((t-r)*Math.pow(2,31)|0),t=r}return e}function qn(){var e;return r(this,void 0,void 0,(function(){var t,n,o,a,u,s,c=this;return i(this,(function(l){switch(l.label){case 0:if(!(t=null===(e=window.crypto)||void 0===e?void 0:e.subtle)||!t.generateKey||!t.exportKey)return[2,-1];n=function(){return r(c,void 0,void 0,(function(){var e,n;return i(this,(function(r){switch(r.label){case 0:return[4,t.generateKey({name:"AES-GCM",length:128},!0,["encrypt"])];case 1:return e=r.sent(),[4,t.exportKey("raw",e)];case 2:return n=r.sent(),[2,new Uint8Array(n)]}}))}))},l.label=1;case 1:return l.trys.push([1,3,,4]),[4,Promise.all([n(),n()])];case 2:for(o=l.sent(),a=new Uint8Array(o[0].length),u=0;u0?e.lastIndexOf(".",n-1):-1,!1===t(e.slice(n+1)))return!1}while(n>=0);return!0}function Kn(e,t){Hn(t,e,365),function(e,t){var n;try{null===(n=null===localStorage||void 0===localStorage?void 0:localStorage.setItem)||void 0===n||n.call(localStorage,e,t)}catch(r){}}(t,e)}function Jn(e){var t,n;try{return null!==(n=null===(t=null===localStorage||void 0===localStorage?void 0:localStorage.getItem)||void 0===t?void 0:t.call(localStorage,e))&&void 0!==n?n:void 0}catch(r){}}function Xn(e,t,n,r,i){if(!t){var o=function(e,t){return t||(Object.prototype.hasOwnProperty.call(ct,e)||(e="us"),"https://tls-"+ct[e]+".fpapi.io")}(e,n);return G(i,(function(){return{e:6,endpoint:o}})),[lt(o,r,i),Date.now()]}}function Yn(e,n,o,a,u,s,c,l){var d=this,v=function(e,t,n,l,v,p,g){return r(d,void 0,void 0,(function(){var r,d,b,w,y,E,R,k,S;return i(this,(function(i){switch(i.label){case 0:return r=f(l).then((function(){throw new Error(dt)})),[4,Promise.race([r,Promise.all([m(g),h(l,n,g)])])];case 1:return d=i.sent(),b=d[0],w=d[1],E=function(e){return[zn(e),Jn(e)]}(y=c+"_t"),[4,jt({token:o,endpoint:Ft(a,u),components:b,customComponent:p,tag:e,visitorToken:E,tls:w,linkedId:t,extendedResult:v,algorithm:s},r,g)];case 2:return R=i.sent(),k=R[0],(S=R[1])&&Kn(S,y),[2,k]}}))}))},h=function(e,t,o){return r(d,void 0,void 0,(function(){var r,a,u,s,c;return i(this,(function(i){switch(i.label){case 0:if(!n||t)return[2,void 0];r=n[0],a=n[1],u=Math.min(Math.max(.1*e,a+1e4-Date.now()),.4*e),i.label=1;case 1:return i.trys.push([1,3,,4]),[4,r(f(u))];case 2:return s=i.sent(),G(o,(function(){return{e:7,result:s}})),[2,{value:s}];case 3:return c=i.sent(),G(o,(function(){return{e:8,error:c}})),[2,{error:c}];case 4:return[2]}}))}))},m=function(t){return r(d,void 0,void 0,(function(){var n,r;return i(this,(function(i){switch(i.label){case 0:return i.trys.push([0,2,,3]),[4,e()];case 1:return n=i.sent(),G(t,(function(){return{e:13,result:n}})),[2,n];case 2:throw r=i.sent(),G(t,(function(){return{e:14,error:r}})),r;case 3:return[2]}}))}))};return{get:function(e){void 0===e&&(e={});var n=l&&function(e,n){return function(r){return e(t(t({},r),{getCallId:n}))}}(l,O(8));return q(n,(function(){return{e:3,options:e}}),(function(e){return{e:4,result:e}}),(function(e){return{e:5,error:e}}),(function(){var t=e.timeout,r=void 0===t?1e4:t,i=e.tag,o=e.linkedId,a=e.disableTls,u=e.extendedResult,s=e.environment;return v(i,_(o),a,r,u,s,n)}))}}}function Zn(e,n,o){var u,s=this,c=x([null==o?void 0:o.debug,(u=/{(.*?)}/.exec(location.hash),!!u&&1915004642===function(e){for(var t=0,n=0;ne.length)&&(t=e.length);for(var u=0,n=new Array(t);u=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var n={exports:{}};function r(){return{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}n.exports={defaults:{baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1},getDefaults:r,changeDefaults:function(e){n.exports.defaults=e}};var i=/[&<>"']/,s=/[&<>"']/g,l=/[<>"']|&(?!#?\w+;)/,a=/[<>"']|&(?!#?\w+;)/g,o={"&":"&","<":"<",">":">",'"':""","'":"'"},D=function(e){return o[e]};var c=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function h(e){return e.replace(c,(function(e,t){return"colon"===(t=t.toLowerCase())?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""}))}var p=/(^|[^\[])\^/g;var f=/[^\w:]/g,g=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var F={},A=/^[^:]+:\/*[^/]*$/,d=/^([^:]+:)[\s\S]*$/,C=/^([^:]+:\/*[^/]*)[\s\S]*$/;function k(e,t){F[" "+e]||(A.test(e)?F[" "+e]=e+"/":F[" "+e]=E(e,"/",!0));var u=-1===(e=F[" "+e]).indexOf(":");return"//"===t.substring(0,2)?u?t:e.replace(d,"$1")+t:"/"===t.charAt(0)?u?t:e.replace(C,"$1")+t:e+t}function E(e,t,u){var n=e.length;if(0===n)return"";for(var r=0;r=0&&"\\"===u[r];)n=!n;return n?"|":" |"})).split(/ \|/),n=0;if(u[0].trim()||u.shift(),u[u.length-1].trim()||u.pop(),u.length>t)u.splice(t);else for(;u.length1;)1&t&&(u+=e),t>>=1,e+=e;return u+e},T=n.exports.defaults,R=_,I=y,Z=x,q=z;function O(e,t,u,n){var r=t.href,i=t.title?Z(t.title):null,s=e[1].replace(/\\([\[\]])/g,"$1");if("!"!==e[0].charAt(0)){n.state.inLink=!0;var l={type:"link",raw:u,href:r,title:i,text:s,tokens:n.inlineTokens(s,[])};return n.state.inLink=!1,l}return{type:"image",raw:u,href:r,title:i,text:Z(s)}}var L=function(){function e(e){this.options=e||T}var t=e.prototype;return t.space=function(e){var t=this.rules.block.newline.exec(e);if(t)return t[0].length>1?{type:"space",raw:t[0]}:{raw:"\n"}},t.code=function(e){var t=this.rules.block.code.exec(e);if(t){var u=t[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?u:R(u,"\n")}}},t.fences=function(e){var t=this.rules.block.fences.exec(e);if(t){var u=t[0],n=function(e,t){var u=e.match(/^(\s+)(?:```)/);if(null===u)return t;var n=u[1];return t.split("\n").map((function(e){var t=e.match(/^\s+/);return null===t?e:t[0].length>=n.length?e.slice(n.length):e})).join("\n")}(u,t[3]||"");return{type:"code",raw:u,lang:t[2]?t[2].trim():t[2],text:n}}},t.heading=function(e){var t=this.rules.block.heading.exec(e);if(t){var u=t[2].trim();if(/#$/.test(u)){var n=R(u,"#");this.options.pedantic?u=n.trim():n&&!/ $/.test(n)||(u=n.trim())}var r={type:"heading",raw:t[0],depth:t[1].length,text:u,tokens:[]};return this.lexer.inline(r.text,r.tokens),r}},t.hr=function(e){var t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:t[0]}},t.blockquote=function(e){var t=this.rules.block.blockquote.exec(e);if(t){var u=t[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:t[0],tokens:this.lexer.blockTokens(u,[]),text:u}}},t.list=function(e){var t=this.rules.block.list.exec(e);if(t){var u,n,r,i,s,l,a,o,D,c,h=t[1].trim(),p=h.length>1,f={type:"list",raw:"",ordered:p,start:p?+h.slice(0,-1):"",loose:!1,items:[]};h=p?"\\d{1,9}\\"+h.slice(-1):"\\"+h,this.options.pedantic&&(h=p?h:"[*+-]");for(var g=new RegExp("^( {0,3}"+h+")((?: [^\\n]*| *)(?:\\n[^\\n]*)*(?:\\n|$))");e&&!this.rules.block.hr.test(e)&&(t=g.exec(e));){D=t[2].split("\n"),this.options.pedantic?(i=2,c=D[0].trimLeft()):(i=t[2].search(/[^ ]/),i=t[1].length+(i>4?1:i),c=D[0].slice(i-t[1].length)),l=!1,u=t[0],!D[0]&&/^ *$/.test(D[1])&&(u=t[1]+D.slice(0,2).join("\n")+"\n",f.loose=!0,D=[]);var F=new RegExp("^ {0,"+Math.min(3,i-1)+"}(?:[*+-]|\\d{1,9}[.)])");for(s=1;s=i)&&o.trim()){u=t[1]+D.slice(0,s).join("\n")+"\n";break}c+="\n"+o.slice(i)}else o.trim()||(l=!0),o.search(/[^ ]/)>=i?c+="\n"+o.slice(i):c+="\n"+o}f.loose||(a?f.loose=!0:/\n *\n *$/.test(u)&&(a=!0)),this.options.gfm&&(n=/^\[[ xX]\] /.exec(c))&&(r="[ ] "!==n[0],c=c.replace(/^\[[ xX]\] +/,"")),f.items.push({type:"list_item",raw:u,task:!!n,checked:r,loose:!1,text:c}),f.raw+=u,e=e.slice(u.length)}f.items[f.items.length-1].raw=u.trimRight(),f.items[f.items.length-1].text=c.trimRight(),f.raw=f.raw.trimRight();var A=f.items.length;for(s=0;s/i.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(t[0]):Z(t[0]):t[0]}},t.link=function(e){var t=this.rules.inline.link.exec(e);if(t){var u=t[2].trim();if(!this.options.pedantic&&/^$/.test(u))return;var n=R(u.slice(0,-1),"\\");if((u.length-n.length)%2==0)return}else{var r=q(t[2],"()");if(r>-1){var i=(0===t[0].indexOf("!")?5:4)+t[1].length+r;t[2]=t[2].substring(0,r),t[0]=t[0].substring(0,i).trim(),t[3]=""}}var s=t[2],l="";if(this.options.pedantic){var a=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(s);a&&(s=a[1],l=a[3])}else l=t[3]?t[3].slice(1,-1):"";return s=s.trim(),/^$/.test(u)?s.slice(1):s.slice(1,-1)),O(t,{href:s?s.replace(this.rules.inline._escapes,"$1"):s,title:l?l.replace(this.rules.inline._escapes,"$1"):l},t[0],this.lexer)}},t.reflink=function(e,t){var u;if((u=this.rules.inline.reflink.exec(e))||(u=this.rules.inline.nolink.exec(e))){var n=(u[2]||u[1]).replace(/\s+/g," ");if(!(n=t[n.toLowerCase()])||!n.href){var r=u[0].charAt(0);return{type:"text",raw:r,text:r}}return O(u,n,u[0],this.lexer)}},t.emStrong=function(e,t,u){void 0===u&&(u="");var n=this.rules.inline.emStrong.lDelim.exec(e);if(n&&(!n[3]||!u.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/))){var r=n[1]||n[2]||"";if(!r||r&&(""===u||this.rules.inline.punctuation.exec(u))){var i,s,l=n[0].length-1,a=l,o=0,D="*"===n[0][0]?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(D.lastIndex=0,t=t.slice(-1*e.length+l);null!=(n=D.exec(t));)if(i=n[1]||n[2]||n[3]||n[4]||n[5]||n[6])if(s=i.length,n[3]||n[4])a+=s;else if(!((n[5]||n[6])&&l%3)||(l+s)%3){if(!((a-=s)>0)){if(s=Math.min(s,s+a+o),Math.min(l,s)%2){var c=e.slice(1,l+n.index+s);return{type:"em",raw:e.slice(0,l+n.index+s+1),text:c,tokens:this.lexer.inlineTokens(c,[])}}var h=e.slice(2,l+n.index+s-1);return{type:"strong",raw:e.slice(0,l+n.index+s+1),text:h,tokens:this.lexer.inlineTokens(h,[])}}}else o+=s}}},t.codespan=function(e){var t=this.rules.inline.code.exec(e);if(t){var u=t[2].replace(/\n/g," "),n=/[^ ]/.test(u),r=/^ /.test(u)&&/ $/.test(u);return n&&r&&(u=u.substring(1,u.length-1)),u=Z(u,!0),{type:"codespan",raw:t[0],text:u}}},t.br=function(e){var t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}},t.del=function(e){var t=this.rules.inline.del.exec(e);if(t)return{type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2],[])}},t.autolink=function(e,t){var u,n,r=this.rules.inline.autolink.exec(e);if(r)return n="@"===r[2]?"mailto:"+(u=Z(this.options.mangle?t(r[1]):r[1])):u=Z(r[1]),{type:"link",raw:r[0],text:u,href:n,tokens:[{type:"text",raw:u,text:u}]}},t.url=function(e,t){var u;if(u=this.rules.inline.url.exec(e)){var n,r;if("@"===u[2])r="mailto:"+(n=Z(this.options.mangle?t(u[0]):u[0]));else{var i;do{i=u[0],u[0]=this.rules.inline._backpedal.exec(u[0])[0]}while(i!==u[0]);n=Z(u[0]),r="www."===u[1]?"http://"+n:n}return{type:"link",raw:u[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}},t.inlineText=function(e,t){var u,n=this.rules.inline.text.exec(e);if(n)return u=this.lexer.state.inRawBlock?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(n[0]):Z(n[0]):n[0]:Z(this.options.smartypants?t(n[0]):n[0]),{type:"text",raw:n[0],text:u}},e}(),j=w,U=b,P=v,Q={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)( [^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:j,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};Q.def=U(Q.def).replace("label",Q._label).replace("title",Q._title).getRegex(),Q.bullet=/(?:[*+-]|\d{1,9}[.)])/,Q.listItemStart=U(/^( *)(bull) */).replace("bull",Q.bullet).getRegex(),Q.list=U(Q.list).replace(/bull/g,Q.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+Q.def.source+")").getRegex(),Q._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",Q._comment=/|$)/,Q.html=U(Q.html,"i").replace("comment",Q._comment).replace("tag",Q._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Q.paragraph=U(Q._paragraph).replace("hr",Q.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Q._tag).getRegex(),Q.blockquote=U(Q.blockquote).replace("paragraph",Q.paragraph).getRegex(),Q.normal=P({},Q),Q.gfm=P({},Q.normal,{table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),Q.gfm.table=U(Q.gfm.table).replace("hr",Q.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",Q._tag).getRegex(),Q.pedantic=P({},Q.normal,{html:U("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",Q._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:j,paragraph:U(Q.normal._paragraph).replace("hr",Q.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",Q.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});var M={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:j,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,rDelimUnd:/^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:j,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~"};M.punctuation=U(M.punctuation).replace(/punctuation/g,M._punctuation).getRegex(),M.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g,M.escapedEmSt=/\\\*|\\_/g,M._comment=U(Q._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),M.emStrong.lDelim=U(M.emStrong.lDelim).replace(/punct/g,M._punctuation).getRegex(),M.emStrong.rDelimAst=U(M.emStrong.rDelimAst,"g").replace(/punct/g,M._punctuation).getRegex(),M.emStrong.rDelimUnd=U(M.emStrong.rDelimUnd,"g").replace(/punct/g,M._punctuation).getRegex(),M._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,M._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,M._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,M.autolink=U(M.autolink).replace("scheme",M._scheme).replace("email",M._email).getRegex(),M._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,M.tag=U(M.tag).replace("comment",M._comment).replace("attribute",M._attribute).getRegex(),M._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,M._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,M._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,M.link=U(M.link).replace("label",M._label).replace("href",M._href).replace("title",M._title).getRegex(),M.reflink=U(M.reflink).replace("label",M._label).getRegex(),M.reflinkSearch=U(M.reflinkSearch,"g").replace("reflink",M.reflink).replace("nolink",M.nolink).getRegex(),M.normal=P({},M),M.pedantic=P({},M.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:U(/^!?\[(label)\]\((.*?)\)/).replace("label",M._label).getRegex(),reflink:U(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",M._label).getRegex()}),M.gfm=P({},M.normal,{escape:U(M.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\.5&&(u="x"+u.toString(16)),n+="&#"+u+";";return n}var Y=function(){function t(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||G,this.options.tokenizer=this.options.tokenizer||new X,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};var t={block:V.normal,inline:H.normal};this.options.pedantic?(t.block=V.pedantic,t.inline=H.pedantic):this.options.gfm&&(t.block=V.gfm,this.options.breaks?t.inline=H.breaks:t.inline=H.gfm),this.tokenizer.rules=t}t.lex=function(e,u){return new t(u).lex(e)},t.lexInline=function(e,u){return new t(u).inlineTokens(e)};var u,n,r,i=t.prototype;return i.lex=function(e){var t;for(e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this.tokens);t=this.inlineQueue.shift();)this.inlineTokens(t.src,t.tokens);return this.tokens},i.blockTokens=function(e,t){var u,n,r,i,s=this;for(void 0===t&&(t=[]),this.options.pedantic&&(e=e.replace(/^ +$/gm,""));e;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some((function(n){return!!(u=n.call({lexer:s},e,t))&&(e=e.substring(u.raw.length),t.push(u),!0)}))))if(u=this.tokenizer.space(e))e=e.substring(u.raw.length),u.type&&t.push(u);else if(u=this.tokenizer.code(e))e=e.substring(u.raw.length),!(n=t[t.length-1])||"paragraph"!==n.type&&"text"!==n.type?t.push(u):(n.raw+="\n"+u.raw,n.text+="\n"+u.text,this.inlineQueue[this.inlineQueue.length-1].src=n.text);else if(u=this.tokenizer.fences(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.heading(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.hr(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.blockquote(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.list(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.html(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.def(e))e=e.substring(u.raw.length),!(n=t[t.length-1])||"paragraph"!==n.type&&"text"!==n.type?this.tokens.links[u.tag]||(this.tokens.links[u.tag]={href:u.href,title:u.title}):(n.raw+="\n"+u.raw,n.text+="\n"+u.raw,this.inlineQueue[this.inlineQueue.length-1].src=n.text);else if(u=this.tokenizer.table(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.lheading(e))e=e.substring(u.raw.length),t.push(u);else if(r=e,this.options.extensions&&this.options.extensions.startBlock&&function(){var t=1/0,u=e.slice(1),n=void 0;s.options.extensions.startBlock.forEach((function(e){"number"==typeof(n=e.call({lexer:this},u))&&n>=0&&(t=Math.min(t,n))})),t<1/0&&t>=0&&(r=e.substring(0,t+1))}(),this.state.top&&(u=this.tokenizer.paragraph(r)))n=t[t.length-1],i&&"paragraph"===n.type?(n.raw+="\n"+u.raw,n.text+="\n"+u.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=n.text):t.push(u),i=r.length!==e.length,e=e.substring(u.raw.length);else if(u=this.tokenizer.text(e))e=e.substring(u.raw.length),(n=t[t.length-1])&&"text"===n.type?(n.raw+="\n"+u.raw,n.text+="\n"+u.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=n.text):t.push(u);else if(e){var l="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(l);break}throw new Error(l)}return this.state.top=!0,t},i.inline=function(e,t){this.inlineQueue.push({src:e,tokens:t})},i.inlineTokens=function(e,t){var u,n,r,i=this;void 0===t&&(t=[]);var s,l,a,o=e;if(this.tokens.links){var D=Object.keys(this.tokens.links);if(D.length>0)for(;null!=(s=this.tokenizer.rules.inline.reflinkSearch.exec(o));)D.includes(s[0].slice(s[0].lastIndexOf("[")+1,-1))&&(o=o.slice(0,s.index)+"["+J("a",s[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(s=this.tokenizer.rules.inline.blockSkip.exec(o));)o=o.slice(0,s.index)+"["+J("a",s[0].length-2)+"]"+o.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(s=this.tokenizer.rules.inline.escapedEmSt.exec(o));)o=o.slice(0,s.index)+"++"+o.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);for(;e;)if(l||(a=""),l=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((function(n){return!!(u=n.call({lexer:i},e,t))&&(e=e.substring(u.raw.length),t.push(u),!0)}))))if(u=this.tokenizer.escape(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.tag(e))e=e.substring(u.raw.length),(n=t[t.length-1])&&"text"===u.type&&"text"===n.type?(n.raw+=u.raw,n.text+=u.text):t.push(u);else if(u=this.tokenizer.link(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(u.raw.length),(n=t[t.length-1])&&"text"===u.type&&"text"===n.type?(n.raw+=u.raw,n.text+=u.text):t.push(u);else if(u=this.tokenizer.emStrong(e,o,a))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.codespan(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.br(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.del(e))e=e.substring(u.raw.length),t.push(u);else if(u=this.tokenizer.autolink(e,W))e=e.substring(u.raw.length),t.push(u);else if(this.state.inLink||!(u=this.tokenizer.url(e,W))){if(r=e,this.options.extensions&&this.options.extensions.startInline&&function(){var t=1/0,u=e.slice(1),n=void 0;i.options.extensions.startInline.forEach((function(e){"number"==typeof(n=e.call({lexer:this},u))&&n>=0&&(t=Math.min(t,n))})),t<1/0&&t>=0&&(r=e.substring(0,t+1))}(),u=this.tokenizer.inlineText(r,K))e=e.substring(u.raw.length),"_"!==u.raw.slice(-1)&&(a=u.raw.slice(-1)),l=!0,(n=t[t.length-1])&&"text"===n.type?(n.raw+=u.raw,n.text+=u.text):t.push(u);else if(e){var c="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(c);break}throw new Error(c)}}else e=e.substring(u.raw.length),t.push(u);return t},u=t,r=[{key:"rules",get:function(){return{block:V,inline:H}}}],(n=null)&&e(u.prototype,n),r&&e(u,r),t}(),ee=n.exports.defaults,te=B,ue=x,ne=function(){function e(e){this.options=e||ee}var t=e.prototype;return t.code=function(e,t,u){var n=(t||"").match(/\S*/)[0];if(this.options.highlight){var r=this.options.highlight(e,n);null!=r&&r!==e&&(u=!0,e=r)}return e=e.replace(/\n$/,"")+"\n",n?'
'+(u?e:ue(e,!0))+"
\n":"
"+(u?e:ue(e,!0))+"
\n"},t.blockquote=function(e){return"
\n"+e+"
\n"},t.html=function(e){return e},t.heading=function(e,t,u,n){return this.options.headerIds?"'+e+"\n":""+e+"\n"},t.hr=function(){return this.options.xhtml?"
\n":"
\n"},t.list=function(e,t,u){var n=t?"ol":"ul";return"<"+n+(t&&1!==u?' start="'+u+'"':"")+">\n"+e+"\n"},t.listitem=function(e){return"
  • "+e+"
  • \n"},t.checkbox=function(e){return" "},t.paragraph=function(e){return"

    "+e+"

    \n"},t.table=function(e,t){return t&&(t=""+t+""),"\n\n"+e+"\n"+t+"
    \n"},t.tablerow=function(e){return"\n"+e+"\n"},t.tablecell=function(e,t){var u=t.header?"th":"td";return(t.align?"<"+u+' align="'+t.align+'">':"<"+u+">")+e+"\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+""},t.br=function(){return this.options.xhtml?"
    ":"
    "},t.del=function(e){return""+e+""},t.link=function(e,t,u){if(null===(e=te(this.options.sanitize,this.options.baseUrl,e)))return u;var n='"},t.image=function(e,t,u){if(null===(e=te(this.options.sanitize,this.options.baseUrl,e)))return u;var n=''+u+'":">"},t.text=function(e){return e},e}(),re=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,u){return""+u},t.image=function(e,t,u){return""+u},t.br=function(){return""},e}(),ie=function(){function e(){this.seen={}}var t=e.prototype;return t.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},t.getNextSafeSlug=function(e,t){var u=e,n=0;if(this.seen.hasOwnProperty(u)){n=this.seen[e];do{u=e+"-"+ ++n}while(this.seen.hasOwnProperty(u))}return t||(this.seen[e]=n,this.seen[u]=0),u},t.slug=function(e,t){void 0===t&&(t={});var u=this.serialize(e);return this.getNextSafeSlug(u,t.dryrun)},e}(),se=ne,le=re,ae=ie,oe=n.exports.defaults,De=m,ce=Y,he=function(){function e(e){this.options=e||oe,this.options.renderer=this.options.renderer||new se,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new le,this.slugger=new ae}e.parse=function(t,u){return new e(u).parse(t)},e.parseInline=function(t,u){return new e(u).parseInline(t)};var t=e.prototype;return t.parse=function(e,t){void 0===t&&(t=!0);var u,n,r,i,s,l,a,o,D,c,h,p,f,g,F,A,d,C,k,E="",x=e.length;for(u=0;u0&&"paragraph"===F.tokens[0].type?(F.tokens[0].text=C+" "+F.tokens[0].text,F.tokens[0].tokens&&F.tokens[0].tokens.length>0&&"text"===F.tokens[0].tokens[0].type&&(F.tokens[0].tokens[0].text=C+" "+F.tokens[0].tokens[0].text)):F.tokens.unshift({type:"text",text:C}):g+=C),g+=this.parse(F.tokens,f),D+=this.renderer.listitem(g,d,A);E+=this.renderer.list(D,h,p);continue;case"html":E+=this.renderer.html(c.text);continue;case"paragraph":E+=this.renderer.paragraph(this.parseInline(c.tokens));continue;case"text":for(D=c.tokens?this.parseInline(c.tokens):c.text;u+1An error occurred:

    "+Ce(e.message+"",!0)+"
    ";throw e}}return me.options=me.setOptions=function(e){return Ae(me.defaults,e),Ee(me.defaults),me},me.getDefaults=ke,me.defaults=xe,me.use=function(){for(var e=arguments.length,t=new Array(e),u=0;uAn error occurred:

    "+Ce(e.message+"",!0)+"
    ";throw e}},me.Parser=he,me.parser=he.parse,me.Renderer=fe,me.TextRenderer=ge,me.Lexer=ce,me.lexer=ce.lex,me.Tokenizer=pe,me.Slugger=Fe,me.parse=me,me})); + +marked.use({ + extensions: [ + { + name: 'mention', + level: 'inline', + start: function(src){ + const match = src.match(/@[a-zA-Z0-9_\-]+/); + return match != null ? match.index : -1; + }, + tokenizer: function(src) { + const rule = /^@[a-zA-Z0-9_\-]+/; + const match = rule.exec(src); + if(match){ + return { + type: 'mention', + raw: match[0], + text: match[0].trim().slice(1), + tokens: [] + }; + } + }, + renderer(token) { + const u = token.raw; + return `
    ${u}`; + } + } + ] +}); + +const reDisableBeforeUnload = /^\/submit|^\/h\/[a-zA-Z0-9_\-]{3,20}\/submit/; + +function markdown(t) { + let input = t.value; + + if (!reDisableBeforeUnload.test(location.pathname)) + { + if (!window.onbeforeunload) + { + window.onbeforeunload = function (e) { + e = e || window.event; + if (e) { + e.returnValue = 'Any string'; + } + return 'Any string'; + }; + } + else if (!input) { + window.onbeforeunload = null + } + } + + if (!input.includes('```') && !input.includes('
    '))
    +		input = input.replace(/\n/g, '\n\n')
    +	input = input.replace(/\|\|(.*?)\|\|/g, '$1')
    +	input = input.replace(/(\n|^)>([^ >][^\n]*)/g, '$1\>$2')
    +
    +	var emojis = Array.from(input.matchAll(/:([a-z0-9_\-!#@]{1,36}):(?!\/)/gi))
    +	if(emojis != null){
    +		for(i = 0; i < emojis.length; i++){
    +			var old = emojis[i][0];
    +			if (old.includes('marseyrandom')) continue
    +			var emoji = old.replace(/[:!@#]/g,'').toLowerCase();
    +			var mirroredClass = old.indexOf('!') == -1 ? '' : 'mirrored';
    +			var emojiClass = old.indexOf('#') == -1 ? 'emoji' : 'emoji-lg';
    +			if (emoji.endsWith('pat') && emoji != 'marseyunpettablepat') {
    +				emoji = emoji.substr(0, emoji.length - 3);
    +				var url = old.indexOf('@') != -1 ? `/@${emoji}/pic` : `/e/${emoji}.webp`;
    +				input = input.replace(old, ``);
    +			} else {
    +				input = input.replace(old, ``);
    +			}
    +		}
    +	}
    +
    +	let options = Array.from(input.matchAll(/\s*\$\$([^\$\n]+)\$\$\s*/gi))
    +	if(options != null){
    +		for(i = 0; i < options.length; i++){
    +			var option = options[i][0];
    +			var option2 = option.replace(/\$\$/g, '').replace(/\n/g, '')
    +			input = input.replace(option, '');
    +			input += `
    `; + } + } + + options = Array.from(input.matchAll(/\s*&&([^\$\n]+)&&\s*/gi)) + if(options != null){ + for(i = 0; i < options.length; i++){ + var option = options[i][0]; + var option2 = option.replace(/&&/g, '').replace(/\n/g, '') + input = input.replace(option, ''); + input += `
    `; + } + } + + input = marked(input) + input = input.replace(/\n\n/g, '
    ') + + document.getElementById(t.dataset.preview).innerHTML = input +} + +function charLimit(form, text) { + + var input = document.getElementById(form); + + var text = document.getElementById(text); + + var length = input.value.length; + + var maxLength = input.getAttribute("maxlength"); + + if (length >= maxLength) { + text.style.color = "#E53E3E"; + } + else if (length >= maxLength * .72){ + text.style.color = "#FFC107"; + } + else { + text.style.color = "#A0AEC0"; + } + + text.innerText = length + ' / ' + maxLength; +} + +function remove_dialog() { + window.onbeforeunload = null; +} \ No newline at end of file diff --git a/files/assets/js/pinpost.js b/files/assets/js/pinpost.js index bc12e77f7..9e02b15be 100644 --- a/files/assets/js/pinpost.js +++ b/files/assets/js/pinpost.js @@ -3,7 +3,9 @@ function pinPost(t, id) { { }, (xhr) => { - if(xhr.status == 201) { + response = JSON.parse(xhr.response); + length = response["length"]; + if (length == "permanently") { t.innerHTML = t.innerHTML.replace(t.textContent, 'Pin for 1 hour'); t.classList.add('d-none'); } else { diff --git a/files/assets/js/pusher.js b/files/assets/js/pusher.js new file mode 100644 index 000000000..4b9d91e3b --- /dev/null +++ b/files/assets/js/pusher.js @@ -0,0 +1,2614 @@ +var PusherPushNotifications = (function (exports) { + 'use strict'; + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { + arr2[i] = arr[i]; + } + + return arr2; + } + } + + var arrayWithoutHoles = _arrayWithoutHoles; + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + var iterableToArray = _iterableToArray; + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + var nonIterableSpread = _nonIterableSpread; + + function _toConsumableArray(arr) { + return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread(); + } + + var toConsumableArray = _toConsumableArray; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var runtime_1 = createCommonjsModule(function (module) { + /** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + var runtime = (function (exports) { + + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined$1; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); + + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); + + return generator; + } + exports.wrap = wrap; + + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; + } + } + + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; + + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; + + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + + // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. + var IteratorPrototype = {}; + IteratorPrototype[iteratorSymbol] = function () { + return this; + }; + + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + if (NativeIteratorPrototype && + NativeIteratorPrototype !== Op && + hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; + } + + var Gp = GeneratorFunctionPrototype.prototype = + Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunctionPrototype[toStringTagSymbol] = + GeneratorFunction.displayName = "GeneratorFunction"; + + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function(method) { + prototype[method] = function(arg) { + return this._invoke(method, arg); + }; + }); + } + + exports.isGeneratorFunction = function(genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor + ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" + : false; + }; + + exports.mark = function(genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + if (!(toStringTagSymbol in genFun)) { + genFun[toStringTagSymbol] = "GeneratorFunction"; + } + } + genFun.prototype = Object.create(Gp); + return genFun; + }; + + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + exports.awrap = function(arg) { + return { __await: arg }; + }; + + function AsyncIterator(generator) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value && + typeof value === "object" && + hasOwn.call(value, "__await")) { + return Promise.resolve(value.__await).then(function(value) { + invoke("next", value, resolve, reject); + }, function(err) { + invoke("throw", err, resolve, reject); + }); + } + + return Promise.resolve(value).then(function(unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function(error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } + } + + var previousPromise; + + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new Promise(function(resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then( + callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg + ) : callInvokeWithMethodAndArg(); + } + + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; + } + + defineIteratorMethods(AsyncIterator.prototype); + AsyncIterator.prototype[asyncIteratorSymbol] = function () { + return this; + }; + exports.AsyncIterator = AsyncIterator; + + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + exports.async = function(innerFn, outerFn, self, tryLocsList) { + var iter = new AsyncIterator( + wrap(innerFn, outerFn, self, tryLocsList) + ); + + return exports.isGeneratorFunction(outerFn) + ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function(result) { + return result.done ? result.value : iter.next(); + }); + }; + + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } + + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } + + context.method = method; + context.arg = arg; + + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } + + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; + + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } + + context.dispatchException(context.arg); + + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } + + state = GenStateExecuting; + + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done + ? GenStateCompleted + : GenStateSuspendedYield; + + if (record.arg === ContinueSentinel) { + continue; + } + + return { + value: record.arg, + done: context.done + }; + + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; + } + } + }; + } + + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined$1) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; + + if (context.method === "throw") { + // Note: ["return"] must be used for ES3 parsing compatibility. + if (delegate.iterator["return"]) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined$1; + maybeInvokeDelegate(delegate, context); + + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } + + context.method = "throw"; + context.arg = new TypeError( + "The iterator does not provide a 'throw' method"); + } + + return ContinueSentinel; + } + + var record = tryCatch(method, delegate.iterator, context.arg); + + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } + + var info = record.arg; + + if (! info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } + + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; + + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; + + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined$1; + } + + } else { + // Re-yield the result returned by the delegate method. + return info; + } + + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; + } + + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + + Gp[toStringTagSymbol] = "Generator"; + + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + Gp[iteratorSymbol] = function() { + return this; + }; + + Gp.toString = function() { + return "[object Generator]"; + }; + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; + } + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } + + this.tryEntries.push(entry); + } + + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } + + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); + } + + exports.keys = function(object) { + var keys = []; + for (var key in object) { + keys.push(key); + } + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + + if (typeof iterable.next === "function") { + return iterable; + } + + if (!isNaN(iterable.length)) { + var i = -1, next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + + next.value = undefined$1; + next.done = true; + + return next; + }; + + return next.next = next; + } + } + + // Return an iterator with no values. + return { next: doneResult }; + } + exports.values = values; + + function doneResult() { + return { value: undefined$1, done: true }; + } + + Context.prototype = { + constructor: Context, + + reset: function(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined$1; + this.done = false; + this.delegate = null; + + this.method = "next"; + this.arg = undefined$1; + + this.tryEntries.forEach(resetTryEntry); + + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && + hasOwn.call(this, name) && + !isNaN(+name.slice(1))) { + this[name] = undefined$1; + } + } + } + }, + + stop: function() { + this.done = true; + + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + + return this.rval; + }, + + dispatchException: function(exception) { + if (this.done) { + throw exception; + } + + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined$1; + } + + return !! caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } + + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + + abrupt: function(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && + hasOwn.call(entry, "finallyLoc") && + this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + + if (finallyEntry && + (type === "break" || + type === "continue") && + finallyEntry.tryLoc <= arg && + arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } + + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; + + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } + + return this.complete(record); + }, + + complete: function(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } + + if (record.type === "break" || + record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } + + return ContinueSentinel; + }, + + finish: function(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, + + "catch": function(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, + + delegateYield: function(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined$1; + } + + return ContinueSentinel; + } + }; + + // Regardless of whether this script is executing as a CommonJS module + // or not, return the runtime object so that we can declare the variable + // regeneratorRuntime in the outer scope, which allows this module to be + // injected easily by `bin/regenerator --include-runtime script.js`. + return exports; + + }( + // If this script is executing as a CommonJS module, use module.exports + // as the regeneratorRuntime namespace. Otherwise create a new empty + // object. Either way, the resulting object will be used to initialize + // the regeneratorRuntime variable at the top of this file. + module.exports + )); + + try { + regeneratorRuntime = runtime; + } catch (accidentalStrictMode) { + // This module should not be running in strict mode, so the above + // assignment should always work unless something is misconfigured. Just + // in case runtime.js accidentally runs in strict mode, we can escape + // strict mode using a global Function call. This could conceivably fail + // if a Content Security Policy forbids using Function, but in that case + // the proper solution is to fix the accidental strict mode problem. If + // you've misconfigured your bundler to force strict mode and applied a + // CSP to forbid Function, and you're not willing to fix either of those + // problems, please detail your unique predicament in a GitHub issue. + Function("r", "regeneratorRuntime = r")(runtime); + } + }); + + var regenerator = runtime_1; + + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } + } + + function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + + _next(undefined); + }); + }; + } + + var asyncToGenerator = _asyncToGenerator; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + var classCallCheck = _classCallCheck; + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + var createClass = _createClass; + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + var defineProperty = _defineProperty; + + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + defineProperty(target, key, source[key]); + }); + } + + return target; + } + + var objectSpread = _objectSpread; + + function doRequest(_ref) { + var method = _ref.method, + path = _ref.path, + _ref$body = _ref.body, + body = _ref$body === void 0 ? null : _ref$body, + _ref$headers = _ref.headers, + headers = _ref$headers === void 0 ? {} : _ref$headers; + var options = { + method: method, + headers: headers + }; + + if (body !== null) { + options.body = JSON.stringify(body); + options.headers = objectSpread({ + 'Content-Type': 'application/json' + }, headers); + } + + return fetch(path, options).then( + /*#__PURE__*/ + function () { + var _ref2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee(response) { + return regenerator.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (response.ok) { + _context.next = 3; + break; + } + + _context.next = 3; + return handleError(response); + + case 3: + _context.prev = 3; + _context.next = 6; + return response.json(); + + case 6: + return _context.abrupt("return", _context.sent); + + case 9: + _context.prev = 9; + _context.t0 = _context["catch"](3); + return _context.abrupt("return", null); + + case 12: + case "end": + return _context.stop(); + } + } + }, _callee, null, [[3, 9]]); + })); + + return function (_x) { + return _ref2.apply(this, arguments); + }; + }()); + } + + function handleError(_x2) { + return _handleError.apply(this, arguments); + } + + function _handleError() { + _handleError = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee2(response) { + var errorMessage, _ref3, _ref3$error, error, _ref3$description, description; + + return regenerator.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.prev = 0; + _context2.next = 3; + return response.json(); + + case 3: + _ref3 = _context2.sent; + _ref3$error = _ref3.error; + error = _ref3$error === void 0 ? 'Unknown error' : _ref3$error; + _ref3$description = _ref3.description; + description = _ref3$description === void 0 ? 'No description' : _ref3$description; + errorMessage = "Unexpected status code ".concat(response.status, ": ").concat(error, ", ").concat(description); + _context2.next = 14; + break; + + case 11: + _context2.prev = 11; + _context2.t0 = _context2["catch"](0); + errorMessage = "Unexpected status code ".concat(response.status, ": Cannot parse error response"); + + case 14: + throw new Error(errorMessage); + + case 15: + case "end": + return _context2.stop(); + } + } + }, _callee2, null, [[0, 11]]); + })); + return _handleError.apply(this, arguments); + } + + var TokenProvider = + /*#__PURE__*/ + function () { + function TokenProvider() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + url = _ref.url, + queryParams = _ref.queryParams, + headers = _ref.headers; + + classCallCheck(this, TokenProvider); + + this.url = url; + this.queryParams = queryParams; + this.headers = headers; + } + + createClass(TokenProvider, [{ + key: "fetchToken", + value: function () { + var _fetchToken = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee(userId) { + var queryParams, encodedParams, options, response; + return regenerator.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + queryParams = objectSpread({ + user_id: userId + }, this.queryParams); + encodedParams = Object.entries(queryParams).map(function (kv) { + return kv.map(encodeURIComponent).join('='); + }).join('&'); + options = { + method: 'GET', + path: "".concat(this.url, "?").concat(encodedParams), + headers: this.headers + }; + _context.next = 5; + return doRequest(options); + + case 5: + response = _context.sent; + return _context.abrupt("return", response); + + case 7: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function fetchToken(_x) { + return _fetchToken.apply(this, arguments); + } + + return fetchToken; + }() + }]); + + return TokenProvider; + }(); + + var DeviceStateStore = + /*#__PURE__*/ + function () { + function DeviceStateStore(instanceId) { + classCallCheck(this, DeviceStateStore); + + this._instanceId = instanceId; + this._dbConn = null; + } + + createClass(DeviceStateStore, [{ + key: "connect", + value: function connect() { + var _this = this; + + return new Promise(function (resolve, reject) { + var request = indexedDB.open(_this._dbName); + + request.onsuccess = function (event) { + var db = event.target.result; + _this._dbConn = db; + + _this._readState().then(function (state) { + return state === null ? _this.clear() : Promise.resolve(); + }).then(resolve); + }; + + request.onupgradeneeded = function (event) { + var db = event.target.result; + db.createObjectStore('beams', { + keyPath: 'instance_id' + }); + }; + + request.onerror = function (event) { + var error = new Error("Database error: ".concat(event.target.error)); + reject(error); + }; + }); + } + }, { + key: "clear", + value: function clear() { + return this._writeState({ + instance_id: this._instanceId, + device_id: null, + token: null, + user_id: null + }); + } + }, { + key: "_readState", + value: function _readState() { + var _this2 = this; + + if (!this.isConnected) { + throw new Error('Cannot read value: DeviceStateStore not connected to IndexedDB'); + } + + return new Promise(function (resolve, reject) { + var request = _this2._dbConn.transaction('beams').objectStore('beams').get(_this2._instanceId); + + request.onsuccess = function (event) { + var state = event.target.result; + + if (!state) { + resolve(null); + } + + resolve(state); + }; + + request.onerror = function (event) { + reject(event.target.error); + }; + }); + } + }, { + key: "_readProperty", + value: function () { + var _readProperty2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee(name) { + var state; + return regenerator.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return this._readState(); + + case 2: + state = _context.sent; + + if (!(state === null)) { + _context.next = 5; + break; + } + + return _context.abrupt("return", null); + + case 5: + return _context.abrupt("return", state[name] || null); + + case 6: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function _readProperty(_x) { + return _readProperty2.apply(this, arguments); + } + + return _readProperty; + }() + }, { + key: "_writeState", + value: function _writeState(state) { + var _this3 = this; + + if (!this.isConnected) { + throw new Error('Cannot write value: DeviceStateStore not connected to IndexedDB'); + } + + return new Promise(function (resolve, reject) { + var request = _this3._dbConn.transaction('beams', 'readwrite').objectStore('beams').put(state); + + request.onsuccess = function (_) { + resolve(); + }; + + request.onerror = function (event) { + reject(event.target.error); + }; + }); + } + }, { + key: "_writeProperty", + value: function () { + var _writeProperty2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee2(name, value) { + var state; + return regenerator.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return this._readState(); + + case 2: + state = _context2.sent; + state[name] = value; + _context2.next = 6; + return this._writeState(state); + + case 6: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function _writeProperty(_x2, _x3) { + return _writeProperty2.apply(this, arguments); + } + + return _writeProperty; + }() + }, { + key: "getToken", + value: function getToken() { + return this._readProperty('token'); + } + }, { + key: "setToken", + value: function setToken(token) { + return this._writeProperty('token', token); + } + }, { + key: "getDeviceId", + value: function getDeviceId() { + return this._readProperty('device_id'); + } + }, { + key: "setDeviceId", + value: function setDeviceId(deviceId) { + return this._writeProperty('device_id', deviceId); + } + }, { + key: "getUserId", + value: function getUserId() { + return this._readProperty('user_id'); + } + }, { + key: "setUserId", + value: function setUserId(userId) { + return this._writeProperty('user_id', userId); + } + }, { + key: "getLastSeenSdkVersion", + value: function getLastSeenSdkVersion() { + return this._readProperty('last_seen_sdk_version'); + } + }, { + key: "setLastSeenSdkVersion", + value: function setLastSeenSdkVersion(sdkVersion) { + return this._writeProperty('last_seen_sdk_version', sdkVersion); + } + }, { + key: "getLastSeenUserAgent", + value: function getLastSeenUserAgent() { + return this._readProperty('last_seen_user_agent'); + } + }, { + key: "setLastSeenUserAgent", + value: function setLastSeenUserAgent(userAgent) { + return this._writeProperty('last_seen_user_agent', userAgent); + } + }, { + key: "_dbName", + get: function get() { + return "beams-".concat(this._instanceId); + } + }, { + key: "isConnected", + get: function get() { + return this._dbConn !== null; + } + }]); + + return DeviceStateStore; + }(); + + var version = "1.0.3"; + + var INTERESTS_REGEX = new RegExp('^(_|\\-|=|@|,|\\.|;|[A-Z]|[a-z]|[0-9])*$'); + var MAX_INTEREST_LENGTH = 164; + var MAX_INTERESTS_NUM = 5000; + var SERVICE_WORKER_URL = "/service-worker.js?v=1&pusherBeamsWebSDKVersion=".concat(version); + var RegistrationState = Object.freeze({ + PERMISSION_PROMPT_REQUIRED: 'PERMISSION_PROMPT_REQUIRED', + PERMISSION_GRANTED_NOT_REGISTERED_WITH_BEAMS: 'PERMISSION_GRANTED_NOT_REGISTERED_WITH_BEAMS', + PERMISSION_GRANTED_REGISTERED_WITH_BEAMS: 'PERMISSION_GRANTED_REGISTERED_WITH_BEAMS', + PERMISSION_DENIED: 'PERMISSION_DENIED' + }); + var Client = + /*#__PURE__*/ + function () { + function Client(config) { + classCallCheck(this, Client); + + if (!config) { + throw new Error('Config object required'); + } + + var instanceId = config.instanceId, + _config$endpointOverr = config.endpointOverride, + endpointOverride = _config$endpointOverr === void 0 ? null : _config$endpointOverr, + _config$serviceWorker = config.serviceWorkerRegistration, + serviceWorkerRegistration = _config$serviceWorker === void 0 ? null : _config$serviceWorker; + + if (instanceId === undefined) { + throw new Error('Instance ID is required'); + } + + if (typeof instanceId !== 'string') { + throw new Error('Instance ID must be a string'); + } + + if (instanceId.length === 0) { + throw new Error('Instance ID cannot be empty'); + } + + if (!('indexedDB' in window)) { + throw new Error('Pusher Beams does not support this browser version (IndexedDB not supported)'); + } + + if (!window.isSecureContext) { + throw new Error('Pusher Beams relies on Service Workers, which only work in secure contexts. Check that your page is being served from localhost/over HTTPS'); + } + + if (!('serviceWorker' in navigator)) { + throw new Error('Pusher Beams does not support this browser version (Service Workers not supported)'); + } + + if (!('PushManager' in window)) { + throw new Error('Pusher Beams does not support this browser version (Web Push not supported)'); + } + + if (serviceWorkerRegistration) { + var serviceWorkerScope = serviceWorkerRegistration.scope; + var currentURL = location.href; + var scopeMatchesCurrentPage = currentURL.startsWith(serviceWorkerScope); + + if (!scopeMatchesCurrentPage) { + throw new Error("Could not initialize Pusher web push: current page not in serviceWorkerRegistration scope (".concat(serviceWorkerScope, ")")); + } + } + + this.instanceId = instanceId; + this._deviceId = null; + this._token = null; + this._userId = null; + this._serviceWorkerRegistration = serviceWorkerRegistration; + this._deviceStateStore = new DeviceStateStore(instanceId); + this._endpoint = endpointOverride; // Internal only + + this._ready = this._init(); + } + + createClass(Client, [{ + key: "_init", + value: function () { + var _init2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee() { + return regenerator.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(this._deviceId !== null)) { + _context.next = 2; + break; + } + + return _context.abrupt("return"); + + case 2: + _context.next = 4; + return this._deviceStateStore.connect(); + + case 4: + if (!this._serviceWorkerRegistration) { + _context.next = 9; + break; + } + + _context.next = 7; + return window.navigator.serviceWorker.ready; + + case 7: + _context.next = 12; + break; + + case 9: + _context.next = 11; + return getServiceWorkerRegistration(); + + case 11: + this._serviceWorkerRegistration = _context.sent; + + case 12: + _context.next = 14; + return this._detectSubscriptionChange(); + + case 14: + _context.next = 16; + return this._deviceStateStore.getDeviceId(); + + case 16: + this._deviceId = _context.sent; + _context.next = 19; + return this._deviceStateStore.getToken(); + + case 19: + this._token = _context.sent; + _context.next = 22; + return this._deviceStateStore.getUserId(); + + case 22: + this._userId = _context.sent; + + case 23: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + + function _init() { + return _init2.apply(this, arguments); + } + + return _init; + }() // Ensure SDK is loaded and is consistent + + }, { + key: "_resolveSDKState", + value: function () { + var _resolveSDKState2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee2() { + return regenerator.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + _context2.next = 2; + return this._ready; + + case 2: + _context2.next = 4; + return this._detectSubscriptionChange(); + + case 4: + case "end": + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function _resolveSDKState() { + return _resolveSDKState2.apply(this, arguments); + } + + return _resolveSDKState; + }() + }, { + key: "_detectSubscriptionChange", + value: function () { + var _detectSubscriptionChange2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee3() { + var storedToken, actualToken, pushTokenHasChanged; + return regenerator.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.next = 2; + return this._deviceStateStore.getToken(); + + case 2: + storedToken = _context3.sent; + _context3.next = 5; + return getWebPushToken(this._serviceWorkerRegistration); + + case 5: + actualToken = _context3.sent; + pushTokenHasChanged = storedToken !== actualToken; + + if (!pushTokenHasChanged) { + _context3.next = 13; + break; + } + + _context3.next = 10; + return this._deviceStateStore.clear(); + + case 10: + this._deviceId = null; + this._token = null; + this._userId = null; + + case 13: + case "end": + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function _detectSubscriptionChange() { + return _detectSubscriptionChange2.apply(this, arguments); + } + + return _detectSubscriptionChange; + }() + }, { + key: "getDeviceId", + value: function () { + var _getDeviceId = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee4() { + var _this = this; + + return regenerator.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return this._resolveSDKState(); + + case 2: + return _context4.abrupt("return", this._ready.then(function () { + return _this._deviceId; + })); + + case 3: + case "end": + return _context4.stop(); + } + } + }, _callee4, this); + })); + + function getDeviceId() { + return _getDeviceId.apply(this, arguments); + } + + return getDeviceId; + }() + }, { + key: "getToken", + value: function () { + var _getToken = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee5() { + var _this2 = this; + + return regenerator.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.next = 2; + return this._resolveSDKState(); + + case 2: + return _context5.abrupt("return", this._ready.then(function () { + return _this2._token; + })); + + case 3: + case "end": + return _context5.stop(); + } + } + }, _callee5, this); + })); + + function getToken() { + return _getToken.apply(this, arguments); + } + + return getToken; + }() + }, { + key: "getUserId", + value: function () { + var _getUserId = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee6() { + var _this3 = this; + + return regenerator.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.next = 2; + return this._resolveSDKState(); + + case 2: + return _context6.abrupt("return", this._ready.then(function () { + return _this3._userId; + })); + + case 3: + case "end": + return _context6.stop(); + } + } + }, _callee6, this); + })); + + function getUserId() { + return _getUserId.apply(this, arguments); + } + + return getUserId; + }() + }, { + key: "_throwIfNotStarted", + value: function _throwIfNotStarted(message) { + if (!this._deviceId) { + throw new Error("".concat(message, ". SDK not registered with Beams. Did you call .start?")); + } + } + }, { + key: "start", + value: function () { + var _start = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee7() { + var _ref, publicKey, token, deviceId; + + return regenerator.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + _context7.next = 2; + return this._resolveSDKState(); + + case 2: + if (isSupportedBrowser()) { + _context7.next = 4; + break; + } + + return _context7.abrupt("return", this); + + case 4: + if (!(this._deviceId !== null)) { + _context7.next = 6; + break; + } + + return _context7.abrupt("return", this); + + case 6: + _context7.next = 8; + return this._getPublicKey(); + + case 8: + _ref = _context7.sent; + publicKey = _ref.vapidPublicKey; + _context7.next = 12; + return this._getPushToken(publicKey); + + case 12: + token = _context7.sent; + _context7.next = 15; + return this._registerDevice(token); + + case 15: + deviceId = _context7.sent; + _context7.next = 18; + return this._deviceStateStore.setToken(token); + + case 18: + _context7.next = 20; + return this._deviceStateStore.setDeviceId(deviceId); + + case 20: + _context7.next = 22; + return this._deviceStateStore.setLastSeenSdkVersion(version); + + case 22: + _context7.next = 24; + return this._deviceStateStore.setLastSeenUserAgent(window.navigator.userAgent); + + case 24: + this._token = token; + this._deviceId = deviceId; + return _context7.abrupt("return", this); + + case 27: + case "end": + return _context7.stop(); + } + } + }, _callee7, this); + })); + + function start() { + return _start.apply(this, arguments); + } + + return start; + }() + }, { + key: "getRegistrationState", + value: function () { + var _getRegistrationState = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee8() { + return regenerator.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + _context8.next = 2; + return this._resolveSDKState(); + + case 2: + if (!(Notification.permission === 'denied')) { + _context8.next = 4; + break; + } + + return _context8.abrupt("return", RegistrationState.PERMISSION_DENIED); + + case 4: + if (!(Notification.permission === 'granted' && this._deviceId !== null)) { + _context8.next = 6; + break; + } + + return _context8.abrupt("return", RegistrationState.PERMISSION_GRANTED_REGISTERED_WITH_BEAMS); + + case 6: + if (!(Notification.permission === 'granted' && this._deviceId === null)) { + _context8.next = 8; + break; + } + + return _context8.abrupt("return", RegistrationState.PERMISSION_GRANTED_NOT_REGISTERED_WITH_BEAMS); + + case 8: + return _context8.abrupt("return", RegistrationState.PERMISSION_PROMPT_REQUIRED); + + case 9: + case "end": + return _context8.stop(); + } + } + }, _callee8, this); + })); + + function getRegistrationState() { + return _getRegistrationState.apply(this, arguments); + } + + return getRegistrationState; + }() + }, { + key: "addDeviceInterest", + value: function () { + var _addDeviceInterest = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee9(interest) { + var path, options; + return regenerator.wrap(function _callee9$(_context9) { + while (1) { + switch (_context9.prev = _context9.next) { + case 0: + _context9.next = 2; + return this._resolveSDKState(); + + case 2: + this._throwIfNotStarted('Could not add Device Interest'); + + validateInterestName(interest); + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/interests/").concat(encodeURIComponent(interest)); + options = { + method: 'POST', + path: path + }; + _context9.next = 8; + return doRequest(options); + + case 8: + case "end": + return _context9.stop(); + } + } + }, _callee9, this); + })); + + function addDeviceInterest(_x) { + return _addDeviceInterest.apply(this, arguments); + } + + return addDeviceInterest; + }() + }, { + key: "removeDeviceInterest", + value: function () { + var _removeDeviceInterest = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee10(interest) { + var path, options; + return regenerator.wrap(function _callee10$(_context10) { + while (1) { + switch (_context10.prev = _context10.next) { + case 0: + _context10.next = 2; + return this._resolveSDKState(); + + case 2: + this._throwIfNotStarted('Could not remove Device Interest'); + + validateInterestName(interest); + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/interests/").concat(encodeURIComponent(interest)); + options = { + method: 'DELETE', + path: path + }; + _context10.next = 8; + return doRequest(options); + + case 8: + case "end": + return _context10.stop(); + } + } + }, _callee10, this); + })); + + function removeDeviceInterest(_x2) { + return _removeDeviceInterest.apply(this, arguments); + } + + return removeDeviceInterest; + }() + }, { + key: "getDeviceInterests", + value: function () { + var _getDeviceInterests = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee11() { + var path, options; + return regenerator.wrap(function _callee11$(_context11) { + while (1) { + switch (_context11.prev = _context11.next) { + case 0: + _context11.next = 2; + return this._resolveSDKState(); + + case 2: + this._throwIfNotStarted('Could not get Device Interests'); + + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/interests"); + options = { + method: 'GET', + path: path + }; + _context11.next = 7; + return doRequest(options); + + case 7: + _context11.t0 = _context11.sent['interests']; + + if (_context11.t0) { + _context11.next = 10; + break; + } + + _context11.t0 = []; + + case 10: + return _context11.abrupt("return", _context11.t0); + + case 11: + case "end": + return _context11.stop(); + } + } + }, _callee11, this); + })); + + function getDeviceInterests() { + return _getDeviceInterests.apply(this, arguments); + } + + return getDeviceInterests; + }() + }, { + key: "setDeviceInterests", + value: function () { + var _setDeviceInterests = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee12(interests) { + var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, interest, uniqueInterests, path, options; + + return regenerator.wrap(function _callee12$(_context12) { + while (1) { + switch (_context12.prev = _context12.next) { + case 0: + _context12.next = 2; + return this._resolveSDKState(); + + case 2: + this._throwIfNotStarted('Could not set Device Interests'); + + if (!(interests === undefined || interests === null)) { + _context12.next = 5; + break; + } + + throw new Error('interests argument is required'); + + case 5: + if (Array.isArray(interests)) { + _context12.next = 7; + break; + } + + throw new Error('interests argument must be an array'); + + case 7: + if (!(interests.length > MAX_INTERESTS_NUM)) { + _context12.next = 9; + break; + } + + throw new Error("Number of interests (".concat(interests.length, ") exceeds maximum of ").concat(MAX_INTERESTS_NUM)); + + case 9: + _iteratorNormalCompletion = true; + _didIteratorError = false; + _iteratorError = undefined; + _context12.prev = 12; + + for (_iterator = interests[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + interest = _step.value; + validateInterestName(interest); + } + + _context12.next = 20; + break; + + case 16: + _context12.prev = 16; + _context12.t0 = _context12["catch"](12); + _didIteratorError = true; + _iteratorError = _context12.t0; + + case 20: + _context12.prev = 20; + _context12.prev = 21; + + if (!_iteratorNormalCompletion && _iterator["return"] != null) { + _iterator["return"](); + } + + case 23: + _context12.prev = 23; + + if (!_didIteratorError) { + _context12.next = 26; + break; + } + + throw _iteratorError; + + case 26: + return _context12.finish(23); + + case 27: + return _context12.finish(20); + + case 28: + uniqueInterests = Array.from(new Set(interests)); + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/interests"); + options = { + method: 'PUT', + path: path, + body: { + interests: uniqueInterests + } + }; + _context12.next = 33; + return doRequest(options); + + case 33: + case "end": + return _context12.stop(); + } + } + }, _callee12, this, [[12, 16, 20, 28], [21,, 23, 27]]); + })); + + function setDeviceInterests(_x3) { + return _setDeviceInterests.apply(this, arguments); + } + + return setDeviceInterests; + }() + }, { + key: "clearDeviceInterests", + value: function () { + var _clearDeviceInterests = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee13() { + return regenerator.wrap(function _callee13$(_context13) { + while (1) { + switch (_context13.prev = _context13.next) { + case 0: + _context13.next = 2; + return this._resolveSDKState(); + + case 2: + this._throwIfNotStarted('Could not clear Device Interests'); + + _context13.next = 5; + return this.setDeviceInterests([]); + + case 5: + case "end": + return _context13.stop(); + } + } + }, _callee13, this); + })); + + function clearDeviceInterests() { + return _clearDeviceInterests.apply(this, arguments); + } + + return clearDeviceInterests; + }() + }, { + key: "setUserId", + value: function () { + var _setUserId = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee14(userId, tokenProvider) { + var error, path, _ref2, beamsAuthToken, options; + + return regenerator.wrap(function _callee14$(_context14) { + while (1) { + switch (_context14.prev = _context14.next) { + case 0: + _context14.next = 2; + return this._resolveSDKState(); + + case 2: + if (isSupportedBrowser()) { + _context14.next = 4; + break; + } + + return _context14.abrupt("return"); + + case 4: + if (!(this._deviceId === null)) { + _context14.next = 7; + break; + } + + error = new Error('.start must be called before .setUserId'); + return _context14.abrupt("return", Promise.reject(error)); + + case 7: + if (!(typeof userId !== 'string')) { + _context14.next = 9; + break; + } + + throw new Error("User ID must be a string (was ".concat(userId, ")")); + + case 9: + if (!(userId === '')) { + _context14.next = 11; + break; + } + + throw new Error('User ID cannot be the empty string'); + + case 11: + if (!(this._userId !== null && this._userId !== userId)) { + _context14.next = 13; + break; + } + + throw new Error('Changing the `userId` is not allowed.'); + + case 13: + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/user"); + _context14.next = 16; + return tokenProvider.fetchToken(userId); + + case 16: + _ref2 = _context14.sent; + beamsAuthToken = _ref2.token; + options = { + method: 'PUT', + path: path, + headers: { + Authorization: "Bearer ".concat(beamsAuthToken) + } + }; + _context14.next = 21; + return doRequest(options); + + case 21: + this._userId = userId; + return _context14.abrupt("return", this._deviceStateStore.setUserId(userId)); + + case 23: + case "end": + return _context14.stop(); + } + } + }, _callee14, this); + })); + + function setUserId(_x4, _x5) { + return _setUserId.apply(this, arguments); + } + + return setUserId; + }() + }, { + key: "stop", + value: function () { + var _stop = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee15() { + return regenerator.wrap(function _callee15$(_context15) { + while (1) { + switch (_context15.prev = _context15.next) { + case 0: + _context15.next = 2; + return this._resolveSDKState(); + + case 2: + if (isSupportedBrowser()) { + _context15.next = 4; + break; + } + + return _context15.abrupt("return"); + + case 4: + if (!(this._deviceId === null)) { + _context15.next = 6; + break; + } + + return _context15.abrupt("return"); + + case 6: + _context15.next = 8; + return this._deleteDevice(); + + case 8: + _context15.next = 10; + return this._deviceStateStore.clear(); + + case 10: + this._clearPushToken()["catch"](function () {}); // Not awaiting this, best effort. + + + this._deviceId = null; + this._token = null; + this._userId = null; + + case 14: + case "end": + return _context15.stop(); + } + } + }, _callee15, this); + })); + + function stop() { + return _stop.apply(this, arguments); + } + + return stop; + }() + }, { + key: "clearAllState", + value: function () { + var _clearAllState = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee16() { + return regenerator.wrap(function _callee16$(_context16) { + while (1) { + switch (_context16.prev = _context16.next) { + case 0: + if (isSupportedBrowser()) { + _context16.next = 2; + break; + } + + return _context16.abrupt("return"); + + case 2: + _context16.next = 4; + return this.stop(); + + case 4: + _context16.next = 6; + return this.start(); + + case 6: + case "end": + return _context16.stop(); + } + } + }, _callee16, this); + })); + + function clearAllState() { + return _clearAllState.apply(this, arguments); + } + + return clearAllState; + }() + }, { + key: "_getPublicKey", + value: function () { + var _getPublicKey2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee17() { + var path, options; + return regenerator.wrap(function _callee17$(_context17) { + while (1) { + switch (_context17.prev = _context17.next) { + case 0: + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/web-vapid-public-key"); + options = { + method: 'GET', + path: path + }; + return _context17.abrupt("return", doRequest(options)); + + case 3: + case "end": + return _context17.stop(); + } + } + }, _callee17, this); + })); + + function _getPublicKey() { + return _getPublicKey2.apply(this, arguments); + } + + return _getPublicKey; + }() + }, { + key: "_getPushToken", + value: function () { + var _getPushToken2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee18(publicKey) { + var sub; + return regenerator.wrap(function _callee18$(_context18) { + while (1) { + switch (_context18.prev = _context18.next) { + case 0: + _context18.prev = 0; + _context18.next = 3; + return this._clearPushToken(); + + case 3: + _context18.next = 5; + return this._serviceWorkerRegistration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUInt8Array(publicKey) + }); + + case 5: + sub = _context18.sent; + return _context18.abrupt("return", btoa(JSON.stringify(sub))); + + case 9: + _context18.prev = 9; + _context18.t0 = _context18["catch"](0); + return _context18.abrupt("return", Promise.reject(_context18.t0)); + + case 12: + case "end": + return _context18.stop(); + } + } + }, _callee18, this, [[0, 9]]); + })); + + function _getPushToken(_x6) { + return _getPushToken2.apply(this, arguments); + } + + return _getPushToken; + }() + }, { + key: "_clearPushToken", + value: function () { + var _clearPushToken2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee19() { + return regenerator.wrap(function _callee19$(_context19) { + while (1) { + switch (_context19.prev = _context19.next) { + case 0: + return _context19.abrupt("return", navigator.serviceWorker.ready.then(function (reg) { + return reg.pushManager.getSubscription(); + }).then(function (sub) { + if (sub) sub.unsubscribe(); + })); + + case 1: + case "end": + return _context19.stop(); + } + } + }, _callee19); + })); + + function _clearPushToken() { + return _clearPushToken2.apply(this, arguments); + } + + return _clearPushToken; + }() + }, { + key: "_registerDevice", + value: function () { + var _registerDevice2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee20(token) { + var path, device, options, response; + return regenerator.wrap(function _callee20$(_context20) { + while (1) { + switch (_context20.prev = _context20.next) { + case 0: + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web"); + device = { + token: token, + metadata: { + sdkVersion: version + } + }; + options = { + method: 'POST', + path: path, + body: device + }; + _context20.next = 5; + return doRequest(options); + + case 5: + response = _context20.sent; + return _context20.abrupt("return", response.id); + + case 7: + case "end": + return _context20.stop(); + } + } + }, _callee20, this); + })); + + function _registerDevice(_x7) { + return _registerDevice2.apply(this, arguments); + } + + return _registerDevice; + }() + }, { + key: "_deleteDevice", + value: function () { + var _deleteDevice2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee21() { + var path, options; + return regenerator.wrap(function _callee21$(_context21) { + while (1) { + switch (_context21.prev = _context21.next) { + case 0: + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(encodeURIComponent(this._deviceId)); + options = { + method: 'DELETE', + path: path + }; + _context21.next = 4; + return doRequest(options); + + case 4: + case "end": + return _context21.stop(); + } + } + }, _callee21, this); + })); + + function _deleteDevice() { + return _deleteDevice2.apply(this, arguments); + } + + return _deleteDevice; + }() + /** + * Submit SDK version and browser details (via the user agent) to Pusher Beams. + */ + + }, { + key: "_updateDeviceMetadata", + value: function () { + var _updateDeviceMetadata2 = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee22() { + var userAgent, storedUserAgent, storedSdkVersion, path, metadata, options; + return regenerator.wrap(function _callee22$(_context22) { + while (1) { + switch (_context22.prev = _context22.next) { + case 0: + userAgent = window.navigator.userAgent; + _context22.next = 3; + return this._deviceStateStore.getLastSeenUserAgent(); + + case 3: + storedUserAgent = _context22.sent; + _context22.next = 6; + return this._deviceStateStore.getLastSeenSdkVersion(); + + case 6: + storedSdkVersion = _context22.sent; + + if (!(userAgent === storedUserAgent && version === storedSdkVersion)) { + _context22.next = 9; + break; + } + + return _context22.abrupt("return"); + + case 9: + path = "".concat(this._baseURL, "/device_api/v1/instances/").concat(encodeURIComponent(this.instanceId), "/devices/web/").concat(this._deviceId, "/metadata"); + metadata = { + sdkVersion: version + }; + options = { + method: 'PUT', + path: path, + body: metadata + }; + _context22.next = 14; + return doRequest(options); + + case 14: + _context22.next = 16; + return this._deviceStateStore.setLastSeenSdkVersion(version); + + case 16: + _context22.next = 18; + return this._deviceStateStore.setLastSeenUserAgent(userAgent); + + case 18: + case "end": + return _context22.stop(); + } + } + }, _callee22, this); + })); + + function _updateDeviceMetadata() { + return _updateDeviceMetadata2.apply(this, arguments); + } + + return _updateDeviceMetadata; + }() + }, { + key: "_baseURL", + get: function get() { + if (this._endpoint !== null) { + return this._endpoint; + } + + return "https://".concat(this.instanceId, ".pushnotifications.pusher.com"); + } + }]); + + return Client; + }(); + + var validateInterestName = function validateInterestName(interest) { + if (interest === undefined || interest === null) { + throw new Error('Interest name is required'); + } + + if (typeof interest !== 'string') { + throw new Error("Interest ".concat(interest, " is not a string")); + } + + if (!INTERESTS_REGEX.test(interest)) { + throw new Error("interest \"".concat(interest, "\" contains a forbidden character. ") + 'Allowed characters are: ASCII upper/lower-case letters, ' + 'numbers or one of _-=@,.;'); + } + + if (interest.length > MAX_INTEREST_LENGTH) { + throw new Error("Interest is longer than the maximum of ".concat(MAX_INTEREST_LENGTH, " chars")); + } + }; + + function getServiceWorkerRegistration() { + return _getServiceWorkerRegistration.apply(this, arguments); + } + + function _getServiceWorkerRegistration() { + _getServiceWorkerRegistration = asyncToGenerator( + /*#__PURE__*/ + regenerator.mark(function _callee23() { + var _ref3, swStatusCode; + + return regenerator.wrap(function _callee23$(_context23) { + while (1) { + switch (_context23.prev = _context23.next) { + case 0: + _context23.next = 2; + return fetch(SERVICE_WORKER_URL); + + case 2: + _ref3 = _context23.sent; + swStatusCode = _ref3.status; + + if (!(swStatusCode !== 200)) { + _context23.next = 6; + break; + } + + throw new Error('Cannot start SDK, service worker missing: No file found at /service-worker.js'); + + case 6: + window.navigator.serviceWorker.register(SERVICE_WORKER_URL, { + // explicitly opting out of `importScripts` caching just in case our + // customers decides to host and serve the imported scripts and + // accidentally set `Cache-Control` to something other than `max-age=0` + updateViaCache: 'none' + }); + return _context23.abrupt("return", window.navigator.serviceWorker.ready); + + case 8: + case "end": + return _context23.stop(); + } + } + }, _callee23); + })); + return _getServiceWorkerRegistration.apply(this, arguments); + } + + function getWebPushToken(swReg) { + return swReg.pushManager.getSubscription().then(function (sub) { + return !sub ? null : encodeSubscription(sub); + }); + } + + function encodeSubscription(sub) { + return btoa(JSON.stringify(sub)); + } + + function urlBase64ToUInt8Array(base64String) { + var padding = '='.repeat((4 - base64String.length % 4) % 4); + var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); + var rawData = window.atob(base64); + return Uint8Array.from(toConsumableArray(rawData).map(function (_char) { + return _char.charCodeAt(0); + })); + } + + function isSupportedBrowser() { + var winNav = window.navigator; + var vendorName = winNav.vendor; + var isChromium = window.chrome !== null && typeof window.chrome !== 'undefined'; + var isOpera = winNav.userAgent.indexOf('OPR') > -1; + var isEdge = winNav.userAgent.indexOf('Edg') > -1; + var isFirefox = winNav.userAgent.indexOf('Firefox') > -1; + var isChrome = isChromium && vendorName === 'Google Inc.' && !isEdge && !isOpera; + var isSupported = isChrome || isOpera || isFirefox || isEdge; + + if (!isSupported) { + console.warn('Pusher Web Push Notifications supports Chrome, Firefox, Edge and Opera.'); + } + + return isSupported; + } + + exports.Client = Client; + exports.RegistrationState = RegistrationState; + exports.TokenProvider = TokenProvider; + + return exports; + + }({})); + + +const pusherid = document.getElementById('pusherid').innerHTML; +const beamsClient = new PusherPushNotifications.Client({instanceId: pusherid}); +const strid = document.getElementById('strid').innerHTML; + +beamsClient.start() +.then((beamsClient) => beamsClient.getDeviceId()) +.then(() => beamsClient.addDeviceInterest(strid)) +.then(() => beamsClient.getDeviceInterests()) +.catch(console.error); \ No newline at end of file diff --git a/files/assets/js/service-worker.js b/files/assets/js/service-worker.js index 80103200d..68edf801a 100644 --- a/files/assets/js/service-worker.js +++ b/files/assets/js/service-worker.js @@ -1,51 +1 @@ importScripts("https://js.pusher.com/beams/service-worker.js"); - -// offline static page handler -// @crgd - -const CACHE_NAME = "offlineCache-v1"; -const OFFLINE_URL = "/assets/offline.html"; - -self.addEventListener("install", (event) => { - const cacheOfflinePage = async () => { - const cache = await caches.open(CACHE_NAME); - await cache.add(new Request(OFFLINE_URL, {cache: "reload"})); - }; - - cacheOfflinePage().then(() => { - this.skipWaiting(); - }); -}); - -self.addEventListener("activate", (event) => { - const expectedCaches = [CACHE_NAME]; - - event.waitUntil( - caches.keys().then(keys => Promise.all( - keys.map(key => { - if (!expectedCaches.includes(key)) { - return caches.delete(key); - } - }) - )) - ); -}); - -self.addEventListener("fetch", (event) => { - if (event.request.mode === "navigate") { - event.respondWith((async () => { - try { - const preloadResponse = await event.preloadResponse; - if (preloadResponse) return preloadResponse; - - const networkResponse = await fetch(event.request); - return networkResponse; - } catch (error) { - console.log("Fetch failed; returning offline page instead.", error); - - const cachedResponse = await caches.match(OFFLINE_URL); - return cachedResponse; - } - })()); - } -}); diff --git a/files/assets/js/submit.js b/files/assets/js/submit.js index 93df4c15d..1102578eb 100644 --- a/files/assets/js/submit.js +++ b/files/assets/js/submit.js @@ -166,7 +166,7 @@ function ghost_toggle(t) { function checkRepost() { const system = document.getElementById('system') - system.innerHTML = ""; + system.innerHTML = `To post an image, use a direct image link such as i.imgur.com`; const url = document.getElementById('post-url').value const min_repost_check = 9; @@ -185,7 +185,7 @@ function checkRepost() { const permalinkText = escapeHTML(data["permalink"]); const permalinkURI = encodeURI(data["permalink"]); if (permalinkText) { - system.innerHTML = `This is a repost of ${permalinkText}`; + system.innerHTML = `This is a repost of ${permalinkText}`; } } } diff --git a/files/assets/js/twitter.js b/files/assets/js/twitter.js new file mode 100644 index 000000000..d5c0bf21c --- /dev/null +++ b/files/assets/js/twitter.js @@ -0,0 +1,8 @@ +Function&&Function.prototype&&Function.prototype.bind&&(/(MSIE ([6789]|10|11))|Trident/.test(navigator.userAgent)||(window.__twttr&&window.__twttr.widgets&&window.__twttr.widgets.loaded&&window.twttr.widgets.load&&window.twttr.widgets.load(),window.__twttr&&window.__twttr.widgets&&window.__twttr.widgets.init||function(t){function e(e){for(var n,i,o=e[0],s=e[1],a=0,c=[];a-1},forIn:i,isObject:s,isEmptyObject:a,toType:o,isType:function(t,e){return t==o(e)},toRealArray:u}},function(t,e){t.exports=window},function(t,e,n){var r=n(6);t.exports=function(){var t=this;this.promise=new r(function(e,n){t.resolve=e,t.reject=n})}},function(t,e,n){var r=n(11),i=/(?:^|(?:https?:)?\/\/(?:www\.)?twitter\.com(?::\d+)?(?:\/intent\/(?:follow|user)\/?\?screen_name=|(?:\/#!)?\/))@?([\w]+)(?:\?|&|$)/i,o=/(?:^|(?:https?:)?\/\/(?:www\.)?twitter\.com(?::\d+)?\/(?:#!\/)?[\w_]+\/status(?:es)?\/)(\d+)/i,s=/^http(s?):\/\/(\w+\.)*twitter\.com([:/]|$)/i,a=/^http(s?):\/\/(ton|pbs)\.twimg\.com/,u=/^#?([^.,<>!\s/#\-()'"]+)$/,c=/twitter\.com(?::\d{2,4})?\/intent\/(\w+)/,d=/^https?:\/\/(?:www\.)?twitter\.com\/\w+\/timelines\/(\d+)/i,l=/^https?:\/\/(?:www\.)?twitter\.com\/i\/moments\/(\d+)/i,f=/^https?:\/\/(?:www\.)?twitter\.com\/(\w+)\/(?:likes|favorites)/i,h=/^https?:\/\/(?:www\.)?twitter\.com\/(\w+)\/lists\/([\w-%]+)/i,p=/^https?:\/\/(?:www\.)?twitter\.com\/i\/live\/(\d+)/i,m=/^https?:\/\/syndication\.twitter\.com\/settings/i,v=/^https?:\/\/(localhost|platform)\.twitter\.com(?::\d+)?\/widgets\/widget_iframe\.(.+)/i,g=/^https?:\/\/(?:www\.)?twitter\.com\/search\?q=(\w+)/i;function w(t){return"string"==typeof t&&i.test(t)&&RegExp.$1.length<=20}function y(t){if(w(t))return RegExp.$1}function b(t,e){var n=r.decodeURL(t);if(e=e||!1,n.screen_name=y(t),n.screen_name)return r.url("https://twitter.com/intent/"+(e?"follow":"user"),n)}function _(t){return"string"==typeof t&&u.test(t)}function E(t){return"string"==typeof t&&o.test(t)}t.exports={isHashTag:_,hashTag:function(t,e){if(e=void 0===e||e,_(t))return(e?"#":"")+RegExp.$1},isScreenName:w,screenName:y,isStatus:E,status:function(t){return E(t)&&RegExp.$1},intentForProfileURL:b,intentForFollowURL:function(t){return b(t,!0)},isTwitterURL:function(t){return s.test(t)},isTwimgURL:function(t){return a.test(t)},isIntentURL:function(t){return c.test(t)},isSettingsURL:function(t){return m.test(t)},isWidgetIframeURL:function(t){return v.test(t)},isSearchUrl:function(t){return g.test(t)},regexen:{profile:i},momentId:function(t){return l.test(t)&&RegExp.$1},collectionId:function(t){return d.test(t)&&RegExp.$1},intentType:function(t){return c.test(t)&&RegExp.$1},likesScreenName:function(t){return f.test(t)&&RegExp.$1},listScreenNameAndSlug:function(t){var e,n,r;if(h.test(t)){e=RegExp.$1,n=RegExp.$2;try{r=decodeURIComponent(n)}catch(t){}return{ownerScreenName:e,slug:r||n}}return!1},eventId:function(t){return p.test(t)&&RegExp.$1}}},function(t,e){t.exports=document},function(t,e,n){var r=n(0),i=[!0,1,"1","on","ON","true","TRUE","yes","YES"],o=[!1,0,"0","off","OFF","false","FALSE","no","NO"];function s(t){return void 0!==t&&null!==t&&""!==t}function a(t){return c(t)&&t%1==0}function u(t){return c(t)&&!a(t)}function c(t){return s(t)&&!isNaN(t)}function d(t){return r.contains(o,t)}function l(t){return r.contains(i,t)}t.exports={hasValue:s,isInt:a,isFloat:u,isNumber:c,isString:function(t){return"string"===r.toType(t)},isArray:function(t){return s(t)&&"array"==r.toType(t)},isTruthValue:l,isFalseValue:d,asInt:function(t){if(a(t))return parseInt(t,10)},asFloat:function(t){if(u(t))return t},asNumber:function(t){if(c(t))return t},asBoolean:function(t){return!(!s(t)||!l(t)&&(d(t)||!t))}}},function(t,e,n){var r=n(1),i=n(21),o=n(49);i.hasPromiseSupport()||(r.Promise=o),t.exports=r.Promise},function(t,e,n){var r=n(0);t.exports=function(t,e){var n=Array.prototype.slice.call(arguments,2);return function(){var i=r.toRealArray(arguments);return t.apply(e,n.concat(i))}}},function(t,e,n){var r=n(51);t.exports=new r("__twttr")},function(t,e){t.exports=location},function(t,e,n){var r=n(0),i=/\b([\w-_]+)\b/g;function o(t){return new RegExp("\\b"+t+"\\b","g")}function s(t,e){t.classList?t.classList.add(e):o(e).test(t.className)||(t.className+=" "+e)}function a(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(o(e)," ")}function u(t,e){return t.classList?t.classList.contains(e):r.contains(c(t),e)}function c(t){return r.toRealArray(t.classList?t.classList:t.className.match(i))}t.exports={add:s,remove:a,replace:function(t,e,n){if(t.classList&&u(t,e))return a(t,e),void s(t,n);t.className=t.className.replace(o(e),n)},toggle:function(t,e,n){return void 0===n&&t.classList&&t.classList.toggle?t.classList.toggle(e,n):(n?s(t,e):a(t,e),n)},present:u,list:c}},function(t,e,n){var r=n(5),i=n(0);function o(t){return encodeURIComponent(t).replace(/\+/g,"%2B").replace(/'/g,"%27")}function s(t){return decodeURIComponent(t)}function a(t){var e=[];return i.forIn(t,function(t,n){var s=o(t);i.isType("array",n)||(n=[n]),n.forEach(function(t){r.hasValue(t)&&e.push(s+"="+o(t))})}),e.sort().join("&")}function u(t){var e={};return t?(t.split("&").forEach(function(t){var n=t.split("="),r=s(n[0]),o=s(n[1]);if(2==n.length){if(!i.isType("array",e[r]))return r in e?(e[r]=[e[r]],void e[r].push(o)):void(e[r]=o);e[r].push(o)}}),e):{}}t.exports={url:function(t,e){return a(e).length>0?i.contains(t,"?")?t+"&"+a(e):t+"?"+a(e):t},decodeURL:function(t){var e=t&&t.split("?");return 2==e.length?u(e[1]):{}},decode:u,encode:a,encodePart:o,decodePart:s}},function(t,e,n){var r=n(9),i=n(1),o=n(0),s={},a=o.contains(r.href,"tw_debug=true");function u(){}function c(){}function d(){return i.performance&&+i.performance.now()||+new Date}function l(t,e){if(i.console&&i.console[t])switch(e.length){case 1:i.console[t](e[0]);break;case 2:i.console[t](e[0],e[1]);break;case 3:i.console[t](e[0],e[1],e[2]);break;case 4:i.console[t](e[0],e[1],e[2],e[3]);break;case 5:i.console[t](e[0],e[1],e[2],e[3],e[4]);break;default:0!==e.length&&i.console.warn&&i.console.warn("too many params passed to logger."+t)}}t.exports={devError:u,devInfo:c,devObject:function(t,e){},publicError:function(){l("error",o.toRealArray(arguments))},publicLog:function(){l("info",o.toRealArray(arguments))},publicWarn:function(){l("warn",o.toRealArray(arguments))},time:function(t){a&&(s[t]=d())},timeEnd:function(t){a&&s[t]&&(d(),s[t])}}},function(t,e,n){var r=n(19),i=n(5),o=n(11),s=n(0),a=n(115);t.exports=function(t){var e=t.href&&t.href.split("?")[1],n=e?o.decode(e):{},u={lang:a(t),width:t.getAttribute("data-bs-width")||t.getAttribute("width"),height:t.getAttribute("data-bs-height")||t.getAttribute("height"),related:t.getAttribute("data-bs-related"),partner:t.getAttribute("data-bs-partner")};return i.asBoolean(t.getAttribute("data-bs-dnt"))&&r.setOn(),s.forIn(u,function(t,e){var r=n[t];n[t]=i.hasValue(r)?r:e}),s.compact(n)}},function(t,e,n){var r=n(77),i=n(22);t.exports=function(){var t="data-bs-twitter-extracted-"+i.generate();return function(e,n){return r(e,n).filter(function(e){return!e.hasAttribute(t)}).map(function(e){return e.setAttribute(t,"true"),e})}}},function(t,e){function n(t,e,n,r,i,o,s){this.factory=t,this.Sandbox=e,this.srcEl=o,this.targetEl=i,this.parameters=r,this.className=n,this.options=s}n.prototype.destroy=function(){this.srcEl=this.targetEl=null},t.exports=n},function(t,e){t.exports={DM_BUTTON:"twitter-dm-button",FOLLOW_BUTTON:"twitter-follow-button",HASHTAG_BUTTON:"twitter-hashtag-button",MENTION_BUTTON:"twitter-mention-button",MOMENT:"twitter-moment",PERISCOPE:"periscope-on-air",SHARE_BUTTON:"twitter-share-button",TIMELINE:"twitter-timeline",TWEET:"twitter-tweet"}},function(t,e,n){var r=n(6),i=n(19),o=n(53),s=n(36),a=n(5),u=n(0);t.exports=function(t,e,n){var c;return t=t||[],e=e||{},c="ƒ("+t.join(", ")+", target, [options]);",function(){var d,l,f,h,p=Array.prototype.slice.apply(arguments,[0,t.length]),m=Array.prototype.slice.apply(arguments,[t.length]);return m.forEach(function(t){t&&(t.nodeType!==Node.ELEMENT_NODE?u.isType("function",t)?d=t:u.isType("object",t)&&(l=t):f=t)}),p.length!==t.length||0===m.length?(d&&u.async(function(){d(!1)}),r.reject(new Error("Not enough parameters. Expected: "+c))):f?(l=u.aug({},l||{},e),t.forEach(function(t){l[t]=p.shift()}),a.asBoolean(l.dnt)&&i.setOn(),h=s.getExperiments().then(function(t){return o.addWidget(n(l,f,void 0,t))}),d&&h.then(d,function(){d(!1)}),h):(d&&u.async(function(){d(!1)}),r.reject(new Error("No target element specified. Expected: "+c)))}}},function(t,e,n){var r=n(98),i=n(2),o=n(0);function s(t,e){return function(){try{e.resolve(t.call(this))}catch(t){e.reject(t)}}}t.exports={sync:function(t,e){t.call(e)},read:function(t,e){var n=new i;return r.read(s(t,n),e),n.promise},write:function(t,e){var n=new i;return r.write(s(t,n),e),n.promise},defer:function(t,e,n){var a=new i;return o.isType("function",t)&&(n=e,e=t,t=1),r.defer(t,s(e,a),n),a.promise}}},function(t,e,n){var r=n(4),i=n(9),o=n(38),s=n(102),a=n(5),u=n(33),c=!1,d=/https?:\/\/([^/]+).*/i;t.exports={setOn:function(){c=!0},enabled:function(t,e){return!!(c||a.asBoolean(u.val("dnt"))||s.isUrlSensitive(e||i.host)||o.isFramed()&&s.isUrlSensitive(o.rootDocumentLocation())||(t=d.test(t||r.referrer)&&RegExp.$1)&&s.isUrlSensitive(t))}}},function(t,e,n){var r=n(8),i=n(59),o="https://platform.twitter.com",s=["https://syndication.twitter.com","https://cdn.syndication.twimg.com","https://localhost.twitter.com:8444"],a=["https://syndication.twitter.com","https://localhost.twitter.com:8445"],u=["https://platform.twitter.com","https://localhost.twitter.com",/^https:\/\/ton\.smf1\.twitter\.com\/syndication-internal\/embed-iframe\/[0-9A-Za-z_-]+\/app/],c=function(t,e){return t.some(function(t){return t instanceof RegExp?t.test(e):t===e})},d=function(){var t=r.get("backendHost");return t&&c(s,t)?t:"https://cdn.syndication.twimg.com"},l=function(){var t=r.get("settingsSvcHost");return t&&c(a,t)?t:"https://syndication.twitter.com"};function f(t,e){var n=[t];return e.forEach(function(t){n.push(function(t){var e=(t||"").toString(),n="/"===e.slice(0,1)?1:0,r=function(t){return"/"===t.slice(-1)}(e)?-1:void 0;return e.slice(n,r)}(t))}),n.join("/")}t.exports={cookieConsent:function(t){var e=t||[];return e.unshift("cookie/consent"),f(l(),e)},embedIframe:function(t,e){var n=t||[],s=o,a=r.get("embedIframeURL");return a&&c(u,a)?f(a,n)+".html":(n.unshift(i.getBaseURLPath(e)),f(s,n)+".html")},eventVideo:function(t){var e=t||[];return e.unshift("video/event"),f(d(),e)},grid:function(t){var e=t||[];return e.unshift("grid/collection"),f(d(),e)},moment:function(t){var e=t||[];return e.unshift("moments"),f(d(),e)},settings:function(t){var e=t||[];return e.unshift("settings"),f(l(),e)},timeline:function(t){var e=t||[];return e.unshift("timeline"),f(d(),e)},tweetBatch:function(t){var e=t||[];return e.unshift("tweets.json"),f(d(),e)},video:function(t){var e=t||[];return e.unshift("widgets/video"),f(d(),e)}}},function(t,e,n){var r=n(4),i=n(92),o=n(1),s=n(0),a=i.userAgent;function u(t){return/(Trident|MSIE|Edge[/ ]?\d)/.test(t=t||a)}t.exports={retina:function(t){return(t=t||o).devicePixelRatio?t.devicePixelRatio>=1.5:!!t.matchMedia&&t.matchMedia("only screen and (min-resolution: 144dpi)").matches},anyIE:u,ie9:function(t){return/MSIE 9/.test(t=t||a)},ie10:function(t){return/MSIE 10/.test(t=t||a)},ios:function(t){return/(iPad|iPhone|iPod)/.test(t=t||a)},android:function(t){return/^Mozilla\/5\.0 \(Linux; (U; )?Android/.test(t=t||a)},canPostMessage:function(t,e){return t=t||o,e=e||a,t.postMessage&&!(u(e)&&t.opener)},touch:function(t,e,n){return t=t||o,e=e||i,n=n||a,"ontouchstart"in t||/Opera Mini/.test(n)||e.msMaxTouchPoints>0},cssTransitions:function(){var t=r.body.style;return void 0!==t.transition||void 0!==t.webkitTransition||void 0!==t.mozTransition||void 0!==t.oTransition||void 0!==t.msTransition},hasPromiseSupport:function(){return!!(o.Promise&&o.Promise.resolve&&o.Promise.reject&&o.Promise.all&&o.Promise.race&&(new o.Promise(function(e){t=e}),s.isType("function",t)));var t},hasIntersectionObserverSupport:function(){return!!o.IntersectionObserver},hasPerformanceInformation:function(){return o.performance&&o.performance.getEntriesByType}}},function(t,e){var n="i",r=0,i=0;t.exports={generate:function(){return n+String(+new Date)+Math.floor(1e5*Math.random())+r++},deterministic:function(){return n+String(i++)}}},function(t,e,n){var r=n(50),i=n(52),o=n(0);t.exports=o.aug(r.get("events")||{},i.Emitter)},function(t,e,n){var r=n(6),i=n(2);function o(t,e){return t.then(e,e)}function s(t){return t instanceof r}t.exports={always:o,allResolved:function(t){var e;return void 0===t?r.reject(new Error("undefined is not an object")):Array.isArray(t)?(e=t.length)?new r(function(n,r){var i=0,o=[];function a(){(i+=1)===e&&(0===o.length?r():n(o))}function u(t){o.push(t),a()}t.forEach(function(t){s(t)?t.then(u,a):u(t)})}):r.resolve([]):r.reject(new Error("Type error"))},some:function(t){var e;return e=(t=t||[]).length,t=t.filter(s),e?e!==t.length?r.reject("non-Promise passed to .some"):new r(function(e,n){var r=0;function i(){(r+=1)===t.length&&n()}t.forEach(function(t){t.then(e,i)})}):r.reject("no promises passed to .some")},isPromise:s,allSettled:function(t){function e(){}return r.all((t||[]).map(function(t){return o(t,e)}))},timeout:function(t,e){var n=new i;return setTimeout(function(){n.reject(new Error("Promise timed out"))},e),t.then(function(t){n.resolve(t)},function(t){n.reject(t)}),n.promise}}},function(t,e,n){var r=n(1).JSON;t.exports={stringify:r.stringify||r.encode,parse:r.parse||r.decode}},function(t,e,n){var r=n(27),i=n(108);t.exports=r.build([i])},function(t,e,n){var r=n(39),i=n(105),o=n(7);(r=Object.create(r)).build=o(r.build,null,i),t.exports=r},function(t,e,n){var r=n(39),i=n(40),o=n(7);(r=Object.create(r)).build=o(r.build,null,i),t.exports=r},function(t,e,n){var r=n(79),i=n(80),o=n(81),s=n(9),a=n(71),u=n(82),c=n(19),d=n(5),l=n(22),f=n(0);function h(t){if(!t||!t.headers)throw new Error("unexpected response schema");return{html:t.body,config:t.config,pollInterval:1e3*parseInt(t.headers.xPolling,10)||null,maxCursorPosition:t.headers.maxPosition,minCursorPosition:t.headers.minPosition}}function p(t){if(t&&t.headers)throw new Error(t.headers.status);throw t instanceof Error?t:new Error(t)}t.exports=function(t){t.params({instanceId:{required:!0,fallback:l.deterministic},lang:{required:!0,transform:a.matchLanguage,fallback:"en"},tweetLimit:{transform:d.asInt}}),t.defineProperty("endpoint",{get:function(){throw new Error("endpoint not specified")}}),t.defineProperty("pollEndpoint",{get:function(){return this.endpoint}}),t.define("cbId",function(t){var e=t?"_new":"_old";return"tl_"+this.params.instanceId+"_"+this.id+e}),t.define("queryParams",function(){return{lang:this.params.lang,tz:u.getTimezoneOffset(),t:r(),domain:s.host,tweet_limit:this.params.tweetLimit,dnt:c.enabled()}}),t.define("fetch",function(){return i.fetch(this.endpoint,this.queryParams(),o,this.cbId()).then(h,p)}),t.define("poll",function(t,e){var n,r;return n={since_id:(t=t||{}).sinceId,max_id:t.maxId,min_position:t.minPosition,max_position:t.maxPosition},r=f.aug(this.queryParams(),n),i.fetch(this.pollEndpoint,r,o,this.cbId(e)).then(h,p)})}},function(t,e,n){var r=n(52).makeEmitter();t.exports={emitter:r,START:"start",ALL_WIDGETS_RENDER_START:"all_widgets_render_start",ALL_WIDGETS_RENDER_END:"all_widgets_render_end",ALL_WIDGETS_AND_IMAGES_LOADED:"all_widgets_and_images_loaded"}},function(t,e,n){var r=n(4),i=n(0);t.exports=function(t,e,n){var o;if(n=n||r,t=t||{},e=e||{},t.name){try{o=n.createElement('')}catch(e){(o=n.createElement("iframe")).name=t.name}delete t.name}else o=n.createElement("iframe");return t.id&&(o.id=t.id,delete t.id),o.allowtransparency="true",o.scrolling="no",o.setAttribute("frameBorder",0),o.setAttribute("allowTransparency",!0),i.forIn(t,function(t,e){o.setAttribute(t,e)}),i.forIn(e,function(t,e){o.style[t]=e}),o}},function(t,e,n){var r=n(27),i=n(122);t.exports=r.build([i])},function(t,e,n){var r,i=n(4);function o(t){var e,n,o,s=0;for(r={},e=(t=t||i).getElementsByTagName("meta");e[s];s++){if(n=e[s],/^twitter:/.test(n.getAttribute("name")))o=n.getAttribute("name").replace(/^twitter:/,"");else{if(!/^twitter:/.test(n.getAttribute("property")))continue;o=n.getAttribute("property").replace(/^twitter:/,"")}r[o]=n.getAttribute("content")||n.getAttribute("value")}}o(),t.exports={init:o,val:function(t){return r[t]}}},function(t,e,n){var r=n(0),i=n(45);t.exports={closest:function t(e,n,o){var s;if(n)return o=o||n&&n.ownerDocument,s=r.isType("function",e)?e:function(t){return function(e){return!!e.tagName&&i(e,t)}}(e),n===o?s(n)?n:void 0:s(n)?n:t(s,n.parentNode,o)}}},function(t,e,n){var r=n(10),i={},o=-1,s={};function a(t){var e=t.getAttribute("data-bs-twitter-event-id");return e||(t.setAttribute("data-bs-twitter-event-id",++o),o)}function u(t,e,n){var r=0,i=t&&t.length||0;for(r=0;r1?(e=Math.floor(t.item_ids.length/2),n=t.item_ids.slice(0,e),r={},i=t.item_ids.slice(e),o={},n.forEach(function(e){r[e]=t.item_details[e]}),i.forEach(function(e){o[e]=t.item_details[e]}),[l.aug({},t,{item_ids:n,item_details:r}),l.aug({},t,{item_ids:i,item_details:o})]):[t]},stringify:function(t){var e,n=Array.prototype.toJSON;return delete Array.prototype.toJSON,e=u.stringify(t),n&&(Array.prototype.toJSON=n),e},CLIENT_EVENT_ENDPOINT:p,RUFOUS_REDIRECT:"https://platform.twitter.com/jot.html"}},function(t,e,n){var r=n(9),i=n(75),o=n(0),s=i.getCanonicalURL()||r.href,a=s;t.exports={isFramed:function(){return s!==a},rootDocumentLocation:function(t){return t&&o.isType("string",t)&&(s=t),s},currentDocumentLocation:function(){return a}}},function(t,e,n){var r=n(103),i=n(104),o=n(0);t.exports={couple:function(){return o.toRealArray(arguments)},build:function(t,e,n){var o=new t;return(e=i(r(e||[]))).forEach(function(t){t.call(null,o)}),o.build(n)}}},function(t,e,n){var r=n(106),i=n(0),o=n(41);function s(){this.Component=this.factory(),this._adviceArgs=[],this._lastArgs=[]}i.aug(s.prototype,{factory:o,build:function(t){var e=this;return this.Component,i.aug(this.Component.prototype.boundParams,t),this._adviceArgs.concat(this._lastArgs).forEach(function(t){(function(t,e,n){var r=this[e];if(!r)throw new Error(e+" does not exist");this[e]=t(r,n)}).apply(e.Component.prototype,t)}),delete this._lastArgs,delete this._adviceArgs,this.Component},params:function(t){var e=this.Component.prototype.paramConfigs;t=t||{},this.Component.prototype.paramConfigs=i.aug({},t,e)},define:function(t,e){if(t in this.Component.prototype)throw new Error(t+" has previously been defined");this.override(t,e)},defineStatic:function(t,e){this.Component[t]=e},override:function(t,e){this.Component.prototype[t]=e},defineProperty:function(t,e){if(t in this.Component.prototype)throw new Error(t+" has previously been defined");this.overrideProperty(t,e)},overrideProperty:function(t,e){var n=i.aug({configurable:!0},e);Object.defineProperty(this.Component.prototype,t,n)},before:function(t,e){this._adviceArgs.push([r.before,t,e])},after:function(t,e){this._adviceArgs.push([r.after,t,e])},around:function(t,e){this._adviceArgs.push([r.around,t,e])},last:function(t,e){this._lastArgs.push([r.after,t,e])}}),t.exports=s},function(t,e,n){var r=n(0);function i(){return!0}function o(t){return t}t.exports=function(){function t(t){var e=this;t=t||{},this.params=Object.keys(this.paramConfigs).reduce(function(n,s){var a=[],u=e.boundParams,c=e.paramConfigs[s],d=c.validate||i,l=c.transform||o;if(s in u&&a.push(u[s]),s in t&&a.push(t[s]),a="fallback"in c?a.concat(c.fallback):a,n[s]=function(t,e,n){var i=null;return t.some(function(t){if(t=r.isType("function",t)?t():t,e(t))return i=n(t),!0}),i}(a,d,l),c.required&&null==n[s])throw new Error(s+" is a required parameter");return n},{}),this.initialize()}return r.aug(t.prototype,{paramConfigs:{},boundParams:{},initialize:function(){}}),t}},function(t,e,n){var r=n(101),i=n(76),o=new(n(110))(function(t){(!function(t){return 1===t.length&&i.canFlushOneItem(t[0])}(t)?function(t){r.init(),t.forEach(function(t){var e=t.input.namespace,n=t.input.data,i=t.input.offsite,o=t.input.version;r.clientEvent(e,n,i,o)}),r.flush().then(function(){t.forEach(function(t){t.taskDoneDeferred.resolve()})},function(){t.forEach(function(t){t.taskDoneDeferred.reject()})})}:function(t){t.forEach(function(t){var e=t.input.namespace,n=t.input.data,r=t.input.offsite,o=t.input.version;i.clientEvent(e,n,r,o),t.taskDoneDeferred.resolve()})})(t)});t.exports={scribe:function(t,e,n,r){return o.add({namespace:t,data:e,offsite:n,version:r})},pause:function(){o.pause()},resume:function(){o.resume()}}},function(t,e,n){var r,i=n(10),o=n(4),s=n(1),a=n(33),u=n(54),c=n(5),d=n(22),l="csptest";t.exports={inlineStyle:function(){var t=l+d.generate(),e=o.createElement("div"),n=o.createElement("style"),f="."+t+" { visibility: hidden; }";return!!o.body&&(c.asBoolean(a.val("widgets:csp"))&&(r=!1),void 0!==r?r:(e.style.display="none",i.add(e,t),n.type="text/css",n.appendChild(o.createTextNode(f)),o.body.appendChild(n),o.body.appendChild(e),r="hidden"===s.getComputedStyle(e).visibility,u(e),u(n),r))}}},function(t,e,n){var r=n(1);t.exports=function(t,e,n){var i,o=0;return n=n||null,function s(){var a=n||this,u=arguments,c=+new Date;if(r.clearTimeout(i),c-o>e)return o=c,void t.apply(a,u);i=r.setTimeout(function(){s.apply(a,u)},e)}}},function(t,e,n){var r=n(1).HTMLElement,i=r.prototype.matches||r.prototype.matchesSelector||r.prototype.webkitMatchesSelector||r.prototype.mozMatchesSelector||r.prototype.msMatchesSelector||r.prototype.oMatchesSelector;t.exports=function(t,e){if(i)return i.call(t,e)}},function(t){t.exports={version:"82e1070:1619632193066"}},function(t,e){t.exports=function(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height}}},function(t,e,n){var r=n(12).publicWarn;t.exports=function(){r("Warning: This Timeline type belongs to a group that will not be supported in the future (Likes, Collections, & Moments). It is not recommended for use. \n\t","* Twitter will continue to support Profile and List Timelines \n\t","* You can learn more about this change in our announcement: \n\t","https://twittercommunity.com/t/removing-support-for-embedded-like-collection-and-moment-timelines/150313 \n\t","* In order to create a new Embedded Timeline, visit: https://publish.twitter.com")}},function(t,e,n){ +/*! +* @overview es6-promise - a tiny implementation of Promises/A+. +* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) +* @license Licensed under MIT license +* See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE +* @version v4.2.5+7f2b526d +*/var r;r=function(){"use strict";function t(t){return"function"==typeof t}var e=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},n=0,r=void 0,i=void 0,o=function(t,e){f[n]=t,f[n+1]=e,2===(n+=2)&&(i?i(h):w())},s="undefined"!=typeof window?window:void 0,a=s||{},u=a.MutationObserver||a.WebKitMutationObserver,c="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),d="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function l(){var t=setTimeout;return function(){return t(h,1)}}var f=new Array(1e3);function h(){for(var t=0;t=0&&this._handlers[t].splice(n,1):this._handlers[t]=[])},trigger:function(t,e){var n=this._handlers&&this._handlers[t];(e=e||{}).type=t,n&&n.forEach(function(t){r.async(i(t,this,e))})}};t.exports={Emitter:o,makeEmitter:function(){return r.aug(function(){},o)}}},function(t,e,n){var r=n(97),i=n(99),o=n(6),s=n(24),a=n(7),u=n(0),c=new i(function(t){var e=function(t){return t.reduce(function(t,e){return t[e._className]=t[e._className]||[],t[e._className].push(e),t},{})}(t.map(r.fromRawTask));u.forIn(e,function(t,e){s.allSettled(e.map(function(t){return t.initialize()})).then(function(){e.forEach(function(t){o.all([t.hydrate(),t.insertIntoDom()]).then(a(t.render,t)).then(a(t.success,t),a(t.fail,t))})})})});t.exports={addWidget:function(t){return c.add(t)}}},function(t,e,n){var r=n(18);t.exports=function(t){return r.write(function(){t&&t.parentNode&&t.parentNode.removeChild(t)})}},function(t,e,n){n(12),t.exports={log:function(t,e){}}},function(t,e,n){var r=n(1);function i(t){return(t=t||r).getSelection&&t.getSelection()}t.exports={getSelection:i,getSelectedText:function(t){var e=i(t);return e?e.toString():""}}},function(t,e,n){var r=n(4),i=n(1),o=n(2),s=2e4;t.exports=function(t){var e=new o,n=r.createElement("img");return n.onload=n.onerror=function(){i.setTimeout(e.resolve,50)},n.src=t,i.setTimeout(e.reject,s),e.promise}},function(t,e,n){var r=n(109);t.exports=function(t){t.define("createElement",r),t.define("createFragment",r),t.define("htmlToElement",r),t.define("hasSelectedText",r),t.define("addRootClass",r),t.define("removeRootClass",r),t.define("hasRootClass",r),t.define("prependStyleSheet",r),t.define("appendStyleSheet",r),t.define("prependCss",r),t.define("appendCss",r),t.define("makeVisible",r),t.define("injectWidgetEl",r),t.define("matchHeightToContent",r),t.define("matchWidthToContent",r)}},function(t,e){var n="tfw_horizon_tweet_embed_9555";t.exports={getBaseURLPath:function(t){switch(t&&t.tfw_team_holdback_11929&&t.tfw_team_holdback_11929.bucket){case"control":return"embed-holdback";case"holdback_prod":return"embed-holdback-prod";default:return"embed"}},isHorizonTweetEnabled:function(t){return!(t&&t[n]&&"control"===t[n].bucket)},isHorizonTimelineEnabled:function(){return!1}}},function(t,e){t.exports=function(t){var e,n=!1;return function(){return n?e:(n=!0,e=t.apply(this,arguments))}}},function(t,e,n){var r=n(15),i=n(116),o=n(117),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.DM_BUTTON,t,e,n)}},function(t,e,n){var r=n(27),i=n(118);t.exports=r.build([i])},function(t,e,n){var r=n(15),i=n(121),o=n(32),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.FOLLOW_BUTTON,t,e,n)}},function(t,e,n){var r=n(15),i=n(129),o=n(26),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.MOMENT,t,e,n)}},function(t,e,n){var r=n(15),i=n(131),o=n(26),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.PERISCOPE,t,e,n)}},function(t,e,n){var r=n(78),i=n(133),o=n(137),s=n(139),a=n(141),u=n(143),c={collection:i,event:o,likes:s,list:a,profile:u,url:l},d=[u,s,i,a,o];function l(t){return r(d,function(e){try{return new e(t)}catch(t){}})}t.exports=function(t){return t?function(t){var e,n;return e=(t.sourceType+"").toLowerCase(),(n=c[e])?new n(t):null}(t)||l(t):null}},function(t,e,n){var r=n(4),i=n(59),o=n(15),s=n(32),a=n(145),u=n(26),c=n(146),d=n(16);t.exports=function(t,e,n,l){var f;return i.isHorizonTimelineEnabled(l,t)?(f=r.createElement("div"),new o(a,s,d.TIMELINE,t,e,n,{sandboxWrapperEl:f})):new o(c,u,d.TIMELINE,t,e,n)}},function(t,e,n){var r=n(4),i=n(15),o=n(32),s=n(148),a=n(16);t.exports=function(t,e,n){var u=r.createElement("div");return new i(s,o,a.TWEET,t,e,n,{sandboxWrapperEl:u})}},function(t,e,n){var r=n(15),i=n(150),o=n(32),s=n(16);t.exports=function(t,e,n){var a=t&&t.type||"share",u="hashtag"==a?s.HASHTAG_BUTTON:"mention"==a?s.MENTION_BUTTON:s.SHARE_BUTTON;return new r(i,o,u,t,e,n)}},function(t,e,n){var r=n(42),i=n(38),o=n(0);t.exports=function(t){var e={widget_origin:i.rootDocumentLocation(),widget_frame:i.isFramed()?i.currentDocumentLocation():null,duration_ms:t.duration,item_ids:t.widgetIds||[]},n=o.aug(t.namespace,{page:"page",component:"performance"});r.scribe(n,e)}},function(t,e,n){var r=n(0),i=n(134),o=["ar","fa","he","ur"];t.exports={isRtlLang:function(t){return t=String(t).toLowerCase(),r.contains(o,t)},matchLanguage:function(t){return t=(t=(t||"").toLowerCase()).replace("_","-"),i(t)?t:(t=t.replace(/-.*/,""),i(t)?t:"en")}}},function(t){t.exports={tweetButtonHtmlPath:"/widgets/tweet_button.06c6ee58c3810956b7509218508c7b56.{{lang}}.html",followButtonHtmlPath:"/widgets/follow_button.06c6ee58c3810956b7509218508c7b56.{{lang}}.html",hubHtmlPath:"/widgets/hub.html",widgetIframeHtmlPath:"/widgets/widget_iframe.06c6ee58c3810956b7509218508c7b56.html",resourceBaseUrl:"https://platform.twitter.com"}},function(t){t.exports={TWEET:0,RETWEET:10,CUSTOM_TIMELINE:17,LIVE_VIDEO_EVENT:28,QUOTE_TWEET:23}},function(t,e,n){var r=n(3),i=n(95),o=n(23),s=n(11),a={favorite:["favorite","like"],follow:["follow"],like:["favorite","like"],retweet:["retweet"],tweet:["tweet"]};function u(t){this.srcEl=[],this.element=t}u.open=function(t,e,n){var u=(r.intentType(t)||"").toLowerCase();r.isTwitterURL(t)&&(function(t,e){i.open(t,e)}(t,n),e&&o.trigger("click",{target:e,region:"intent",type:"click",data:{}}),e&&a[u]&&a[u].forEach(function(n){o.trigger(n,{target:e,region:"intent",type:n,data:function(t,e){var n=s.decodeURL(e);switch(t){case"favorite":case"like":return{tweet_id:n.tweet_id};case"follow":return{screen_name:n.screen_name,user_id:n.user_id};case"retweet":return{source_tweet_id:n.tweet_id};default:return{}}}(u,t)})}))},t.exports=u},function(t,e,n){var r=n(4),i=n(9),o=n(3);function s(t,e){var n,r;return e=e||i,/^https?:\/\//.test(t)?t:/^\/\//.test(t)?e.protocol+t:(n=e.host+(e.port.length?":"+e.port:""),0!==t.indexOf("/")&&((r=e.pathname.split("/")).pop(),r.push(t),t="/"+r.join("/")),[e.protocol,"//",n,t].join(""))}t.exports={absolutize:s,getCanonicalURL:function(){for(var t,e=r.getElementsByTagName("link"),n=0;e[n];n++)if("canonical"==(t=e[n]).rel)return s(t.href)},getScreenNameFromPage:function(){for(var t,e,n,i=[r.getElementsByTagName("a"),r.getElementsByTagName("link")],s=0,a=0,u=/\bme\b/;t=i[s];s++)for(a=0;e=t[a];a++)if(u.test(e.rel)&&(n=o.screenName(e.href)))return n}}},function(t,e,n){var r=n(19),i=n(55),o=n(11),s=n(37),a=n(0),u=n(8).get("scribeCallback"),c=2083,d=[],l=o.url(s.CLIENT_EVENT_ENDPOINT,{dnt:0,l:""}),f=encodeURIComponent(l).length;function h(t,e,n,r,i){var o=!a.isObject(t),c=!!e&&!a.isObject(e);o||c||(u&&u(arguments),p(s.formatClientEventNamespace(t),s.formatClientEventData(e,n,r),s.CLIENT_EVENT_ENDPOINT,i))}function p(t,e,n,r){var u;n&&a.isObject(t)&&a.isObject(e)&&(i.log(t,e),u=s.flattenClientEventPayload(t,e),r=a.aug({},r,{l:s.stringify(u)}),u.dnt&&(r.dnt=1),w(o.url(n,r)))}function m(t,e,n,r){var i=!a.isObject(t),o=!!e&&!a.isObject(e);if(!i&&!o)return v(s.flattenClientEventPayload(s.formatClientEventNamespace(t),s.formatClientEventData(e,n,r)))}function v(t){return d.push(t),d}function g(t){return encodeURIComponent(t).length+3}function w(t){return(new Image).src=t}t.exports={canFlushOneItem:function(t){var e=g(s.stringify(t));return f+e1&&m({page:"widgets_js",component:"scribe_pixel",action:"batch_log"},{}),t=d,d=[],t.reduce(function(e,n,r){var i=e.length,o=i&&e[i-1];return r+1==t.length&&n.event_namespace&&"batch_log"==n.event_namespace.action&&(n.message=["entries:"+r,"requests:"+i].join("/")),function t(e){return Array.isArray(e)||(e=[e]),e.reduce(function(e,n){var r,i=s.stringify(n),o=g(i);return f+o1&&(e=e.concat(t(r))),e},[])}(n).forEach(function(t){var n=g(t);(!o||o.urlLength+n>c)&&(o={urlLength:f,items:[]},e.push(o)),o.urlLength+=n,o.items.push(t)}),e},[]).map(function(t){var e={l:t.items};return r.enabled()&&(e.dnt=1),w(o.url(s.CLIENT_EVENT_ENDPOINT,e))})},interaction:function(t,e,n,r){var i=s.extractTermsFromDOM(t.target||t.srcElement);i.action=r||"click",h(i,e,n)}}},function(t,e,n){var r=n(0),i=n(45);t.exports=function(t,e){return i(t,e)?[t]:r.toRealArray(t.querySelectorAll(e))}},function(t,e){t.exports=function(t,e,n){for(var r,i=0;i")}).then(function(){t.close(),a.resolve(c)})}),c.src=["javascript:",'document.write("");',"try { window.parent.document; }",'catch (e) { document.domain="'+r.domain+'"; }',"window.parent."+g.fullPath(["sandbox",u])+"();"].join(""),c.addEventListener("error",a.reject,!1),o.write(function(){i.parentNode.replaceChild(c,i)}),a.promise}t.exports=a.couple(n(58),function(t){t.overrideProperty("id",{get:function(){return this.sandboxEl&&this.sandboxEl.id}}),t.overrideProperty("initialized",{get:function(){return!!this.win}}),t.overrideProperty("width",{get:function(){return this._width}}),t.overrideProperty("height",{get:function(){return this._height}}),t.overrideProperty("sandboxEl",{get:function(){return this.iframeEl}}),t.defineProperty("iframeEl",{get:function(){return this._iframe}}),t.defineProperty("rootEl",{get:function(){return this.doc&&this.doc.documentElement}}),t.defineProperty("widgetEl",{get:function(){return this.doc&&this.doc.body.firstElementChild}}),t.defineProperty("win",{get:function(){return this.iframeEl&&this.iframeEl.contentWindow}}),t.defineProperty("doc",{get:function(){return this.win&&this.win.document}}),t.define("_updateCachedDimensions",function(){var t=this;return o.read(function(){var e,n=h(t.sandboxEl);"visible"==t.sandboxEl.style.visibility?t._width=n.width:(e=h(t.sandboxEl.parentElement).width,t._width=Math.min(n.width,e)),t._height=n.height})}),t.define("_setTargetToBlank",function(){var t=this.createElement("base");t.target="_blank",this.doc.head.appendChild(t)}),t.define("_didResize",function(){var t=this,e=this._resizeHandlers.slice(0);return this._updateCachedDimensions().then(function(){e.forEach(function(e){e(t)})})}),t.define("setTitle",function(t){this.iframeEl.title=t}),t.override("createElement",function(t){return this.doc.createElement(t)}),t.override("createFragment",function(){return this.doc.createDocumentFragment()}),t.override("htmlToElement",function(t){var e;return(e=this.createElement("div")).innerHTML=t,e.firstElementChild}),t.override("hasSelectedText",function(){return!!s.getSelectedText(this.win)}),t.override("addRootClass",function(t){var e=this.rootEl;return t=Array.isArray(t)?t:[t],this.initialized?o.write(function(){t.forEach(function(t){i.add(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("removeRootClass",function(t){var e=this.rootEl;return t=Array.isArray(t)?t:[t],this.initialized?o.write(function(){t.forEach(function(t){i.remove(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("hasRootClass",function(t){return i.present(this.rootEl,t)}),t.define("addStyleSheet",function(t,e){var n,r=new p;return this.initialized?((n=this.createElement("link")).type="text/css",n.rel="stylesheet",n.href=t,n.addEventListener("load",r.resolve,!1),n.addEventListener("error",r.reject,!1),o.write(y(e,null,n)).then(function(){return u(t).then(r.resolve,r.reject),r.promise})):m.reject(new Error("sandbox not initialized"))}),t.override("prependStyleSheet",function(t){var e=this.doc;return this.addStyleSheet(t,function(t){var n=e.head.firstElementChild;return n?e.head.insertBefore(t,n):e.head.appendChild(t)})}),t.override("appendStyleSheet",function(t){var e=this.doc;return this.addStyleSheet(t,function(t){return e.head.appendChild(t)})}),t.define("addCss",function(t,e){var n;return c.inlineStyle()?((n=this.createElement("style")).type="text/css",n.appendChild(this.doc.createTextNode(t)),o.write(y(e,null,n))):(f.devError("CSP enabled; cannot embed inline styles"),m.resolve())}),t.override("prependCss",function(t){var e=this.doc;return this.addCss(t,function(t){var n=e.head.firstElementChild;return n?e.head.insertBefore(t,n):e.head.appendChild(t)})}),t.override("appendCss",function(t){var e=this.doc;return this.addCss(t,function(t){return e.head.appendChild(t)})}),t.override("makeVisible",function(){var t=this;return this.styleSelf(E).then(function(){t._updateCachedDimensions()})}),t.override("injectWidgetEl",function(t){var e=this;return this.initialized?this.widgetEl?m.reject(new Error("widget already injected")):o.write(function(){e.doc.body.appendChild(t)}):m.reject(new Error("sandbox not initialized"))}),t.override("matchHeightToContent",function(){var t,e=this;return o.read(function(){t=e.widgetEl?h(e.widgetEl).height:0}),o.write(function(){e.sandboxEl.style.height=t+"px"}).then(function(){return e._updateCachedDimensions()})}),t.override("matchWidthToContent",function(){var t,e=this;return o.read(function(){t=e.widgetEl?h(e.widgetEl).width:0}),o.write(function(){e.sandboxEl.style.width=t+"px"}).then(function(){return e._updateCachedDimensions()})}),t.after("initialize",function(){this._iframe=null,this._width=this._height=0,this._resizeHandlers=[]}),t.override("insert",function(t,e,n,r){var i=this,s=new p,a=this.targetGlobal.document,u=S(t,e,n,a);return o.write(y(r,null,u)),u.addEventListener("load",function(){(function(t){try{t.contentWindow.document}catch(t){return m.reject(t)}return m.resolve(t)})(u).then(null,y(R,null,t,e,n,u,a)).then(s.resolve,s.reject)},!1),u.addEventListener("error",s.reject,!1),s.promise.then(function(t){var e=d(i._didResize,A,i);return i._iframe=t,i.win.addEventListener("resize",e,!1),m.all([i._setTargetToBlank(),i.addRootClass(x),i.prependCss(T)])})}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("styleSelf",function(){return this._updateCachedDimensions()})})},function(t,e){t.exports=function(){throw new Error("unimplemented method")}},function(t,e,n){var r=n(2),i=n(7),o=100,s=3e3;function a(t,e){this._inputsQueue=[],this._task=t,this._isPaused=!1,this._flushDelay=e&&e.flushDelay||o,this._pauseLength=e&&e.pauseLength||s,this._flushTimeout=void 0}a.prototype.add=function(t){var e=new r;return this._inputsQueue.push({input:t,taskDoneDeferred:e}),this._scheduleFlush(),e.promise},a.prototype._scheduleFlush=function(){this._isPaused||(clearTimeout(this._flushTimeout),this._flushTimeout=setTimeout(i(this._flush,this),this._flushDelay))},a.prototype._flush=function(){try{this._task.call(null,this._inputsQueue)}catch(t){this._inputsQueue.forEach(function(e){e.taskDoneDeferred.reject(t)})}this._inputsQueue=[],this._flushTimeout=void 0},a.prototype.pause=function(t){clearTimeout(this._flushTimeout),this._isPaused=!0,!t&&this._pauseLength&&setTimeout(i(this.resume,this),this._pauseLength)},a.prototype.resume=function(){this._isPaused=!1,this._scheduleFlush()},t.exports=a},function(t,e,n){var r=n(72),i=n(31),o=n(2),s=n(4),a=n(20),u=n(21),c=n(25),d=n(9),l=n(12),f=n(112),h=n(60),p=n(8),m=n(11),v=n(3),g=n(0),w=n(1),y=h(function(){return new o}),b={shouldObtainCookieConsent:!1,features:{}};t.exports={load:function(){var t,e,n,o;if(u.ie9()||u.ie10()||"http:"!==d.protocol&&"https:"!==d.protocol)return l.devError("Using default settings due to unsupported browser or protocol."),void y().resolve();t={origin:d.origin},a.settings().indexOf("localhost")>-1&&(t.localSettings=!0),e=m.url(r.resourceBaseUrl+r.widgetIframeHtmlPath,t),n=function(t){var n,r,i,o;if(r=v.isTwitterURL(t.origin),i=e.substr(0,t.origin.length)===t.origin,o=v.isTwimgURL(t.origin),i&&r||o)try{(n="string"==typeof t.data?c.parse(t.data):t.data).namespace===f.settings&&(b=g.aug(b,{features:n.settings.features,sessionId:n.sessionId}),y().resolve())}catch(t){l.devError(t)}},w.addEventListener("message",n),o=i({src:e,title:"Twitter settings iframe"},{display:"none"}),s.body.appendChild(o)},settingsLoaded:function(){var t,e;return t=p.get("experimentOverride"),y().promise.then(function(){return t&&t.name&&t.assignment&&((e={})[t.name]={bucket:t.assignment},b.features=g.aug(b.features,e)),b})}}},function(t,e){t.exports={settings:"twttr.settings"}},function(t,e,n){t.exports=[n(114),n(120),n(128),n(130),n(132),n(147),n(149)]},function(t,e,n){var r=n(11),i=n(5),o=n(0),s=n(13),a=n(14)(),u=n(61),c="a.twitter-dm-button";t.exports=function(t){return a(t,c).map(function(t){return u(function(t){var e=t.getAttribute("data-bs-show-screen-name"),n=s(t),a=t.getAttribute("href"),u=t.getAttribute("data-bs-screen-name"),c=e?i.asBoolean(e):null,d=t.getAttribute("data-bs-size"),l=r.decodeURL(a),f=l.recipient_id,h=t.getAttribute("data-bs-text")||l.text,p=t.getAttribute("data-bs-welcome-message-id")||l.welcomeMessageId;return o.aug(n,{screenName:u,showScreenName:c,size:d,text:h,userId:f,welcomeMessageId:p})}(t),t.parentNode,t)})}},function(t,e,n){var r=n(0);t.exports=function t(e){var n;if(e)return n=e.lang||e.getAttribute("data-bs-lang"),r.isType("string",n)?n:t(e.parentElement)}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(2).then(function(r){var o;try{o=n(83),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(62),i=n(26);t.exports=r.isSupported()?r:i},function(t,e,n){var r=n(119),i=n(1),o=n(10),s=n(35),a=n(18),u=n(56),c=n(27),d=n(57),l=n(43),f=n(47),h=n(7),p=n(44),m=n(6),v=n(0),g=50,w={position:"absolute",visibility:"hidden",display:"block",transform:"rotate(0deg)"},y={position:"static",visibility:"visible"},b="twitter-widget",_="open",E="SandboxRoot",x=".SandboxRoot { display: none; max-height: 10000px; }";t.exports=c.couple(n(58),function(t){t.defineStatic("isSupported",function(){return!!i.HTMLElement.prototype.attachShadow&&l.inlineStyle()}),t.overrideProperty("id",{get:function(){return this.sandboxEl&&this.sandboxEl.id}}),t.overrideProperty("initialized",{get:function(){return!!this._shadowHost}}),t.overrideProperty("width",{get:function(){return this._width}}),t.overrideProperty("height",{get:function(){return this._height}}),t.overrideProperty("sandboxEl",{get:function(){return this._shadowHost}}),t.define("_updateCachedDimensions",function(){var t=this;return a.read(function(){var e,n=f(t.sandboxEl);"visible"==t.sandboxEl.style.visibility?t._width=n.width:(e=f(t.sandboxEl.parentElement).width,t._width=Math.min(n.width,e)),t._height=n.height})}),t.define("_didResize",function(){var t=this,e=this._resizeHandlers.slice(0);return this._updateCachedDimensions().then(function(){e.forEach(function(e){e(t)})})}),t.override("createElement",function(t){return this.targetGlobal.document.createElement(t)}),t.override("createFragment",function(){return this.targetGlobal.document.createDocumentFragment()}),t.override("htmlToElement",function(t){var e;return(e=this.createElement("div")).innerHTML=t,e.firstElementChild}),t.override("hasSelectedText",function(){return!!u.getSelectedText(this.targetGlobal)}),t.override("addRootClass",function(t){var e=this._shadowRootBody;return t=Array.isArray(t)?t:[t],this.initialized?a.write(function(){t.forEach(function(t){o.add(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("removeRootClass",function(t){var e=this._shadowRootBody;return t=Array.isArray(t)?t:[t],this.initialized?a.write(function(){t.forEach(function(t){o.remove(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("hasRootClass",function(t){return o.present(this._shadowRootBody,t)}),t.override("addStyleSheet",function(t,e){return this.addCss('@import url("'+t+'");',e).then(function(){return d(t)})}),t.override("prependStyleSheet",function(t){var e=this._shadowRoot;return this.addStyleSheet(t,function(t){var n=e.firstElementChild;return n?e.insertBefore(t,n):e.appendChild(t)})}),t.override("appendStyleSheet",function(t){var e=this._shadowRoot;return this.addStyleSheet(t,function(t){return e.appendChild(t)})}),t.override("addCss",function(t,e){var n;return this.initialized?l.inlineStyle()?((n=this.createElement("style")).type="text/css",n.appendChild(this.targetGlobal.document.createTextNode(t)),a.write(h(e,null,n))):m.resolve():m.reject(new Error("sandbox not initialized"))}),t.override("prependCss",function(t){var e=this._shadowRoot;return this.addCss(t,function(t){var n=e.firstElementChild;return n?e.insertBefore(t,n):e.appendChild(t)})}),t.override("appendCss",function(t){var e=this._shadowRoot;return this.addCss(t,function(t){return e.appendChild(t)})}),t.override("makeVisible",function(){return this.styleSelf(y)}),t.override("injectWidgetEl",function(t){var e=this;return this.initialized?this._shadowRootBody.firstElementChild?m.reject(new Error("widget already injected")):a.write(function(){e._shadowRootBody.appendChild(t)}).then(function(){return e._updateCachedDimensions()}).then(function(){var t=p(e._didResize,g,e);new r(e._shadowRootBody,t)}):m.reject(new Error("sandbox not initialized"))}),t.override("matchHeightToContent",function(){return m.resolve()}),t.override("matchWidthToContent",function(){return m.resolve()}),t.override("insert",function(t,e,n,r){var i=this.targetGlobal.document,o=this._shadowHost=i.createElement(b),u=this._shadowRoot=o.attachShadow({mode:_}),c=this._shadowRootBody=i.createElement("div");return v.forIn(e||{},function(t,e){o.setAttribute(t,e)}),o.id=t,u.appendChild(c),s.delegate(c,"click","A",function(t,e){e.hasAttribute("target")||e.setAttribute("target","_blank")}),m.all([this.styleSelf(w),this.addRootClass(E),this.prependCss(x),a.write(r.bind(null,o))])}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("initialize",function(){this._shadowHost=this._shadowRoot=this._shadowRootBody=null,this._width=this._height=0,this._resizeHandlers=[]}),t.after("styleSelf",function(){return this._updateCachedDimensions()})})},function(t,e){var n;(n=function(t,e){function r(t,e){if(t.resizedAttached){if(t.resizedAttached)return void t.resizedAttached.add(e)}else t.resizedAttached=new function(){var t,e;this.q=[],this.add=function(t){this.q.push(t)},this.call=function(){for(t=0,e=this.q.length;t
    ',t.appendChild(t.resizeSensor),{fixed:1,absolute:1}[function(t,e){return t.currentStyle?t.currentStyle[e]:window.getComputedStyle?window.getComputedStyle(t,null).getPropertyValue(e):t.style[e]}(t,"position")]||(t.style.position="relative");var i,o,s=t.resizeSensor.childNodes[0],a=s.childNodes[0],u=t.resizeSensor.childNodes[1],c=(u.childNodes[0],function(){a.style.width=s.offsetWidth+10+"px",a.style.height=s.offsetHeight+10+"px",s.scrollLeft=s.scrollWidth,s.scrollTop=s.scrollHeight,u.scrollLeft=u.scrollWidth,u.scrollTop=u.scrollHeight,i=t.offsetWidth,o=t.offsetHeight});c();var d=function(t,e,n){t.attachEvent?t.attachEvent("on"+e,n):t.addEventListener(e,n)},l=function(){t.offsetWidth==i&&t.offsetHeight==o||t.resizedAttached&&t.resizedAttached.call(),c()};d(s,"scroll",l),d(u,"scroll",l)}var i=Object.prototype.toString.call(t),o="[object Array]"===i||"[object NodeList]"===i||"[object HTMLCollection]"===i||"undefined"!=typeof jQuery&&t instanceof jQuery||"undefined"!=typeof Elements&&t instanceof Elements;if(o)for(var s=0,a=t.length;s0;return this.updateCachedDimensions().then(function(){e&&t._resizeHandlers.forEach(function(e){e(t)})})}),t.define("loadDocument",function(t){var e=new a;return this.initialized?this.iframeEl.src?u.reject(new Error("widget already loaded")):(this.iframeEl.addEventListener("load",e.resolve,!1),this.iframeEl.addEventListener("error",e.reject,!1),this.iframeEl.src=t,e.promise):u.reject(new Error("sandbox not initialized"))}),t.after("initialize",function(){var t=new a,e=new a;this._iframe=null,this._iframeVersion=null,this._width=this._height=0,this._resizeHandlers=[],this._rendered=t,this._results=e,this._waitToSwapUntilRendered=!1}),t.override("insert",function(t,e,n,i){var a=this;return e=d.aug({id:t},l,e),n=d.aug({},f,n),this._iframe=s(e,n),p[t]=this,a._waitToSwapUntilRendered||this.onResize(o(function(){a.makeVisible()})),r.write(c(i,null,this._iframe))}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("styleSelf",function(){return this.updateCachedDimensions()})}},function(t,e,n){var r=n(1),i=n(124),o=n(126),s=n(23),a=n(5),u=n(127);t.exports=function(t,e,n,c,d){function l(t){var e=u(this);s.trigger(t.type,{target:e,region:t.region,type:t.type,data:t.data||{}})}function f(e){var n=u(this),r=n&&n.id,i=a.asInt(e.width),o=a.asInt(e.height);r&&void 0!==i&&void 0!==o&&t(r,i,o)}(new i).attachReceiver(new o.Receiver(r,"twttr.button")).bind("twttr.private.trigger",l).bind("twttr.private.resizeButton",f),(new i).attachReceiver(new o.Receiver(r,"twttr.embed")).bind("twttr.private.initialized",function(t){var e=u(this),n=e&&e.id,r=t.iframe_version;n&&r&&c&&c(n,r)}).bind("twttr.private.trigger",l).bind("twttr.private.results",function(){var t=u(this),n=t&&t.id;n&&e&&e(n)}).bind("twttr.private.rendered",function(){var t=u(this),e=t&&t.id;e&&n&&n(e)}).bind("twttr.private.no_results",function(){var t=u(this),e=t&&t.id;e&&d&&d(e)}).bind("twttr.private.resize",f)}},function(t,e,n){var r=n(25),i=n(125),o=n(0),s=n(6),a=n(24),u="2.0";function c(t){this.registry=t||{}}function d(t){var e,n;return e=o.isType("string",t),n=o.isType("number",t),e||n||null===t}function l(t,e){return{jsonrpc:u,id:d(t)?t:null,error:e}}c.prototype._invoke=function(t,e){var n,r,i;n=this.registry[t.method],r=t.params||[],r=o.isType("array",r)?r:[r];try{i=n.apply(e.source||null,r)}catch(t){i=s.reject(t.message)}return a.isPromise(i)?i:s.resolve(i)},c.prototype._processRequest=function(t,e){var n,r;return function(t){var e,n,r;return!!o.isObject(t)&&(e=t.jsonrpc===u,n=o.isType("string",t.method),r=!("id"in t)||d(t.id),e&&n&&r)}(t)?(n="params"in t&&(r=t.params,!o.isObject(r)||o.isType("function",r))?s.resolve(l(t.id,i.INVALID_PARAMS)):this.registry[t.method]?this._invoke(t,{source:e}).then(function(e){return n=t.id,{jsonrpc:u,id:n,result:e};var n},function(){return l(t.id,i.INTERNAL_ERROR)}):s.resolve(l(t.id,i.METHOD_NOT_FOUND)),null!=t.id?n:s.resolve()):s.resolve(l(t.id,i.INVALID_REQUEST))},c.prototype.attachReceiver=function(t){return t.attachTo(this),this},c.prototype.bind=function(t,e){return this.registry[t]=e,this},c.prototype.receive=function(t,e){var n,a,u,c=this;try{u=t,t=o.isType("string",u)?r.parse(u):u}catch(t){return s.resolve(l(null,i.PARSE_ERROR))}return e=e||null,a=((n=o.isType("array",t))?t:[t]).map(function(t){return c._processRequest(t,e)}),n?function(t){return s.all(t).then(function(t){return(t=t.filter(function(t){return void 0!==t})).length?t:void 0})}(a):a[0]},t.exports=c},function(t){t.exports={PARSE_ERROR:{code:-32700,message:"Parse error"},INVALID_REQUEST:{code:-32600,message:"Invalid Request"},INVALID_PARAMS:{code:-32602,message:"Invalid params"},METHOD_NOT_FOUND:{code:-32601,message:"Method not found"},INTERNAL_ERROR:{code:-32603,message:"Internal error"}}},function(t,e,n){var r=n(9),i=n(1),o=n(25),s=n(2),a=n(21),u=n(0),c=n(3),d=n(7),l=a.ie9();function f(t,e,n){var r;t&&t.postMessage&&(l?r=(n||"")+o.stringify(e):n?(r={})[n]=e:r=e,t.postMessage(r,"*"))}function h(t){return u.isType("string",t)?t:"JSONRPC"}function p(t,e){return e?u.isType("string",t)&&0===t.indexOf(e)?t.substring(e.length):t&&t[e]?t[e]:void 0:t}function m(t,e){var n=t.document;this.filter=h(e),this.server=null,this.isTwitterFrame=c.isTwitterURL(n.location.href),t.addEventListener("message",d(this._onMessage,this),!1)}function v(t,e){this.pending={},this.target=t,this.isTwitterHost=c.isTwitterURL(r.href),this.filter=h(e),i.addEventListener("message",d(this._onMessage,this),!1)}u.aug(m.prototype,{_onMessage:function(t){var e,n=this;this.server&&(this.isTwitterFrame&&!c.isTwitterURL(t.origin)||(e=p(t.data,this.filter))&&this.server.receive(e,t.source).then(function(e){e&&f(t.source,e,n.filter)}))},attachTo:function(t){this.server=t},detach:function(){this.server=null}}),u.aug(v.prototype,{_processResponse:function(t){var e=this.pending[t.id];e&&(e.resolve(t),delete this.pending[t.id])},_onMessage:function(t){var e;if((!this.isTwitterHost||c.isTwitterURL(t.origin))&&(e=p(t.data,this.filter))){if(u.isType("string",e))try{e=o.parse(e)}catch(t){return}(e=u.isType("array",e)?e:[e]).forEach(d(this._processResponse,this))}},send:function(t){var e=new s;return t.id?this.pending[t.id]=e:e.resolve(),f(this.target,t,this.filter),e.promise}}),t.exports={Receiver:m,Dispatcher:v,_stringifyPayload:function(t){return arguments.length>0&&(l=!!t),l}}},function(t,e,n){var r=n(4);t.exports=function(t){for(var e,n=r.getElementsByTagName("iframe"),i=0;n[i];i++)if((e=n[i]).contentWindow===t)return e}},function(t,e,n){var r=n(5),i=n(0),o=n(3),s=n(13),a=n(14)(),u=n(64),c="a.twitter-moment";t.exports=function(t){return a(t,c).map(function(t){return u(function(t){var e=s(t),n={momentId:o.momentId(t.href),chrome:t.getAttribute("data-bs-chrome"),limit:t.getAttribute("data-bs-limit")};return i.forIn(n,function(t,n){var i=e[t];e[t]=r.hasValue(i)?i:n}),e}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return Promise.all([n.e(0),n.e(4)]).then(function(r){var o;try{o=n(85),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(0),i=n(13),o=n(14)(),s=n(65),a="a.periscope-on-air",u=/^https?:\/\/(?:www\.)?(?:periscope|pscp)\.tv\/@?([a-zA-Z0-9_]+)\/?$/i;t.exports=function(t){return o(t,a).map(function(t){return s(function(t){var e=i(t),n=t.getAttribute("href"),o=t.getAttribute("data-bs-size"),s=u.exec(n)[1];return r.aug(e,{username:s,size:o})}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(5).then(function(r){var o;try{o=n(86),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(5),i=n(0),o=n(66),s=n(13),a=n(14)(),u=n(67),c=n(3),d=n(12),l="a.twitter-timeline,div.twitter-timeline,a.twitter-grid",f="Embedded Search timelines have been deprecated. See https://twittercommunity.com/t/deprecating-widget-settings/102295.",h="You may have been affected by an update to settings in embedded timelines. See https://twittercommunity.com/t/deprecating-widget-settings/102295.",p="Embedded grids have been deprecated and will now render as timelines. Please update your embed code to use the twitter-timeline class. More info: https://twittercommunity.com/t/update-on-the-embedded-grid-display-type/119564.";t.exports=function(t){return a(t,l).map(function(t){return u(function(t){var e=s(t),n=t.getAttribute("data-bs-show-replies"),a={isPreconfigured:!!t.getAttribute("data-bs-widget-id"),chrome:t.getAttribute("data-bs-chrome"),tweetLimit:t.getAttribute("data-bs-tweet-limit")||t.getAttribute("data-bs-limit"),ariaLive:t.getAttribute("data-bs-aria-polite"),theme:"dark",borderColor:t.getAttribute("data-bs-border-color"),showReplies:n?r.asBoolean(n):null,profileScreenName:t.getAttribute("data-bs-screen-name"),profileUserId:t.getAttribute("data-bs-user-id"),favoritesScreenName:t.getAttribute("data-bs-favorites-screen-name"),favoritesUserId:t.getAttribute("data-bs-favorites-user-id"),likesScreenName:t.getAttribute("data-bs-likes-screen-name"),likesUserId:t.getAttribute("data-bs-likes-user-id"),listOwnerScreenName:t.getAttribute("data-bs-list-owner-screen-name"),listOwnerUserId:t.getAttribute("data-bs-list-owner-id"),listId:t.getAttribute("data-bs-list-id"),listSlug:t.getAttribute("data-bs-list-slug"),customTimelineId:t.getAttribute("data-bs-custom-timeline-id"),staticContent:t.getAttribute("data-bs-static-content"),url:t.href};return a.isPreconfigured&&(c.isSearchUrl(a.url)?d.publicError(f,t):d.publicLog(h,t)),"twitter-grid"===t.className&&d.publicLog(p,t),(a=i.aug(a,e)).dataSource=o(a),a.id=a.dataSource&&a.dataSource.id,a}(t),t.parentNode,t)})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(136)])},function(t,e,n){var r=n(0),i=n(135);t.exports=function(t){return"en"===t||r.contains(i,t)}},function(t,e){t.exports=["hi","zh-cn","fr","zh-tw","msa","fil","fi","sv","pl","ja","ko","de","it","pt","es","ru","id","tr","da","no","nl","hu","fa","ar","ur","he","th","cs","uk","vi","ro","bn","el","en-gb","gu","kn","mr","ta","bg","ca","hr","sr","sk"]},function(t,e,n){var r=n(3),i=n(0),o=n(20),s=n(48),a="collection:";function u(t,e){return r.collectionId(t)||e}t.exports=function(t){t.params({id:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params.url,this.params.id);return a+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["collection"])}}),t.around("queryParams",function(t){return i.aug(t(),{collection_id:u(this.params.url,this.params.id)})}),t.before("initialize",function(){if(!u(this.params.url,this.params.id))throw new Error("one of url or id is required");s()})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(138)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s="event:";function a(t,e){return r.eventId(t)||e}t.exports=function(t){t.params({id:{},url:{}}),t.overrideProperty("id",{get:function(){var t=a(this.params.url,this.params.id);return s+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["event"])}}),t.around("queryParams",function(t){return i.aug(t(),{event_id:a(this.params.url,this.params.id)})}),t.before("initialize",function(){if(!a(this.params.url,this.params.id))throw new Error("one of url or id is required")})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(140)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s=n(48),a="likes:";function u(t){return r.likesScreenName(t.url)||t.screenName}t.exports=function(t){t.params({screenName:{},userId:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params)||this.params.userId;return a+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["likes"])}}),t.define("_getLikesQueryParam",function(){var t=u(this.params);return t?{screen_name:t}:{user_id:this.params.userId}}),t.around("queryParams",function(t){return i.aug(t(),this._getLikesQueryParam())}),t.before("initialize",function(){if(!u(this.params)&&!this.params.userId)throw new Error("screen name or user id is required");s()})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(142)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s="list:";function a(t){var e=r.listScreenNameAndSlug(t.url)||t;return i.compact({screen_name:e.ownerScreenName,user_id:e.ownerUserId,list_slug:e.slug})}t.exports=function(t){t.params({id:{},ownerScreenName:{},ownerUserId:{},slug:{},url:{}}),t.overrideProperty("id",{get:function(){var t,e,n;return this.params.id?s+this.params.id:(e=(t=a(this.params))&&t.list_slug.replace(/-/g,"_"),n=t&&(t.screen_name||t.user_id),s+(n+":")+e)}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["list"])}}),t.define("_getListQueryParam",function(){return this.params.id?{list_id:this.params.id}:a(this.params)}),t.around("queryParams",function(t){return i.aug(t(),this._getListQueryParam())}),t.before("initialize",function(){var t=a(this.params);if(i.isEmptyObject(t)&&!this.params.id)throw new Error("qualified slug or list id required")})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(144)])},function(t,e,n){var r=n(3),i=n(5),o=n(0),s=n(20),a="profile:";function u(t,e){return r.screenName(t)||e}t.exports=function(t){t.params({showReplies:{fallback:!1,transform:i.asBoolean},screenName:{},userId:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params.url,this.params.screenName);return a+(t||this.params.userId)}}),t.overrideProperty("endpoint",{get:function(){return s.timeline(["profile"])}}),t.define("_getProfileQueryParam",function(){var t=u(this.params.url,this.params.screenName),e=t?{screen_name:t}:{user_id:this.params.userId};return o.aug(e,{with_replies:this.params.showReplies?"true":"false"})}),t.around("queryParams",function(t){return o.aug(t(),this._getProfileQueryParam())}),t.before("initialize",function(){if(!u(this.params.url,this.params.screenName)&&!this.params.userId)throw new Error("screen name or user id is required")})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(6).then(function(r){var o;try{o=n(87),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return Promise.all([n.e(0),n.e(7)]).then(function(r){var o;try{o=n(88),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(10),i=n(3),o=n(0),s=n(13),a=n(14)(),u=n(68),c="blockquote.twitter-tweet, blockquote.twitter-video",d=/\btw-align-(left|right|center)\b/;t.exports=function(t,e){return a(t,c).map(function(t){return u(function(t){var e=s(t),n=t.getElementsByTagName("A"),a=n&&n[n.length-1],u=a&&i.status(a.href),c=t.getAttribute("data-bs-conversation"),l="none"==c||"hidden"==c||r.present(t,"tw-hide-thread"),f=t.getAttribute("data-bs-cards"),h="none"==f||"hidden"==f||r.present(t,"tw-hide-media"),p=t.getAttribute("data-bs-align")||t.getAttribute("align"),m="dark";return!p&&d.test(t.className)&&(p=RegExp.$1),o.aug(e,{tweetId:u,hideThread:l,hideCard:h,align:p,theme:m,id:u})}(t),t.parentNode,t,e)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(8).then(function(r){var o;try{o=n(89),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(10),i=n(0),o=n(13),s=n(14)(),a=n(69),u=n(5),c="a.twitter-share-button, a.twitter-mention-button, a.twitter-hashtag-button",d="twitter-hashtag-button",l="twitter-mention-button";t.exports=function(t){return s(t,c).map(function(t){return a(function(t){var e=o(t),n={screenName:t.getAttribute("data-bs-button-screen-name"),text:t.getAttribute("data-bs-text"),type:t.getAttribute("data-bs-type"),size:t.getAttribute("data-bs-size"),url:t.getAttribute("data-bs-url"),hashtags:t.getAttribute("data-bs-hashtags"),via:t.getAttribute("data-bs-via"),buttonHashtag:t.getAttribute("data-bs-button-hashtag")};return i.forIn(n,function(t,n){var r=e[t];e[t]=u.hasValue(r)?r:n}),e.screenName=e.screenName||e.screen_name,e.buttonHashtag=e.buttonHashtag||e.button_hashtag||e.hashtag,r.present(t,d)&&(e.type="hashtag"),r.present(t,l)&&(e.type="mention"),e}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(3).then(function(r){var o;try{o=n(90),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(0);t.exports=r.aug({},n(152),n(153),n(154),n(155),n(156),n(157),n(158))},function(t,e,n){var r=n(61),i=n(17)(["userId"],{},r);t.exports={createDMButton:i}},function(t,e,n){var r=n(63),i=n(17)(["screenName"],{},r);t.exports={createFollowButton:i}},function(t,e,n){var r=n(64),i=n(17)(["momentId"],{},r);t.exports={createMoment:i}},function(t,e,n){var r=n(65),i=n(17)(["username"],{},r);t.exports={createPeriscopeOnAirButton:i}},function(t,e,n){var r=n(9),i=n(12),o=n(3),s=n(0),a=n(5),u=n(66),c=n(67),d=n(17)([],{},c),l=n(6),f="Embedded grids have been deprecated. Please use twttr.widgets.createTimeline instead. More info: https://twittercommunity.com/t/update-on-the-embedded-grid-display-type/119564.",h={createTimeline:p,createGridFromCollection:function(t){var e=s.toRealArray(arguments).slice(1),n={sourceType:"collection",id:t};return e.unshift(n),i.publicLog(f),p.apply(this,e)}};function p(t){var e,n=s.toRealArray(arguments).slice(1);return a.isString(t)||a.isNumber(t)?l.reject("Embedded timelines with widget settings have been deprecated. See https://twittercommunity.com/t/deprecating-widget-settings/102295."):s.isObject(t)?(t=t||{},n.forEach(function(t){s.isType("object",t)&&function(t){t.ariaLive=t.ariaPolite}(e=t)}),e||(e={},n.push(e)),t.lang=e.lang,t.tweetLimit=e.tweetLimit,t.showReplies=e.showReplies,e.dataSource=u(t),d.apply(this,n)):l.reject("data source must be an object.")}o.isTwitterURL(r.href)&&(h.createTimelinePreview=function(t,e,n){var r={previewParams:t,useLegacyDefaults:!0,isPreviewTimeline:!0};return r.dataSource=u(r),d(e,r,n)}),t.exports=h},function(t,e,n){var r,i=n(0),o=n(68),s=n(17),a=(r=s(["tweetId"],{},o),function(){return i.toRealArray(arguments).slice(1).forEach(function(t){i.isType("object",t)&&(t.hideCard="none"==t.cards||"hidden"==t.cards,t.hideThread="none"==t.conversation||"hidden"==t.conversation)}),r.apply(this,arguments)});t.exports={createTweet:a,createTweetEmbed:a,createVideo:a}},function(t,e,n){var r=n(0),i=n(69),o=n(17),s=o(["url"],{type:"share"},i),a=o(["buttonHashtag"],{type:"hashtag"},i),u=o(["screenName"],{type:"mention"},i);function c(t){return function(){return r.toRealArray(arguments).slice(1).forEach(function(t){r.isType("object",t)&&(t.screenName=t.screenName||t.screen_name,t.buttonHashtag=t.buttonHashtag||t.button_hashtag||t.hashtag)}),t.apply(this,arguments)}}t.exports={createShareButton:c(s),createHashtagButton:c(a),createMentionButton:c(u)}},function(t,e,n){var r,i,o,s=n(4),a=n(1),u=0,c=[],d=s.createElement("a");function l(){var t,e;for(u=1,t=0,e=c.length;t-1},forIn:i,isObject:s,isEmptyObject:a,toType:o,isType:function(t,e){return t==o(e)},toRealArray:u}},function(t,e){t.exports=window},function(t,e,n){var r=n(6);t.exports=function(){var t=this;this.promise=new r(function(e,n){t.resolve=e,t.reject=n})}},function(t,e,n){var r=n(11),i=/(?:^|(?:https?:)?\/\/(?:www\.)?twitter\.com(?::\d+)?(?:\/intent\/(?:follow|user)\/?\?screen_name=|(?:\/#!)?\/))@?([\w]+)(?:\?|&|$)/i,o=/(?:^|(?:https?:)?\/\/(?:www\.)?twitter\.com(?::\d+)?\/(?:#!\/)?[\w_]+\/status(?:es)?\/)(\d+)/i,s=/^http(s?):\/\/(\w+\.)*twitter\.com([:/]|$)/i,a=/^http(s?):\/\/(ton|pbs)\.twimg\.com/,u=/^#?([^.,<>!\s/#\-()'"]+)$/,c=/twitter\.com(?::\d{2,4})?\/intent\/(\w+)/,d=/^https?:\/\/(?:www\.)?twitter\.com\/\w+\/timelines\/(\d+)/i,l=/^https?:\/\/(?:www\.)?twitter\.com\/i\/moments\/(\d+)/i,f=/^https?:\/\/(?:www\.)?twitter\.com\/(\w+)\/(?:likes|favorites)/i,h=/^https?:\/\/(?:www\.)?twitter\.com\/(\w+)\/lists\/([\w-%]+)/i,p=/^https?:\/\/(?:www\.)?twitter\.com\/i\/live\/(\d+)/i,m=/^https?:\/\/syndication\.twitter\.com\/settings/i,v=/^https?:\/\/(localhost|platform)\.twitter\.com(?::\d+)?\/widgets\/widget_iframe\.(.+)/i,g=/^https?:\/\/(?:www\.)?twitter\.com\/search\?q=(\w+)/i;function w(t){return"string"==typeof t&&i.test(t)&&RegExp.$1.length<=20}function y(t){if(w(t))return RegExp.$1}function b(t,e){var n=r.decodeURL(t);if(e=e||!1,n.screen_name=y(t),n.screen_name)return r.url("https://twitter.com/intent/"+(e?"follow":"user"),n)}function _(t){return"string"==typeof t&&u.test(t)}function E(t){return"string"==typeof t&&o.test(t)}t.exports={isHashTag:_,hashTag:function(t,e){if(e=void 0===e||e,_(t))return(e?"#":"")+RegExp.$1},isScreenName:w,screenName:y,isStatus:E,status:function(t){return E(t)&&RegExp.$1},intentForProfileURL:b,intentForFollowURL:function(t){return b(t,!0)},isTwitterURL:function(t){return s.test(t)},isTwimgURL:function(t){return a.test(t)},isIntentURL:function(t){return c.test(t)},isSettingsURL:function(t){return m.test(t)},isWidgetIframeURL:function(t){return v.test(t)},isSearchUrl:function(t){return g.test(t)},regexen:{profile:i},momentId:function(t){return l.test(t)&&RegExp.$1},collectionId:function(t){return d.test(t)&&RegExp.$1},intentType:function(t){return c.test(t)&&RegExp.$1},likesScreenName:function(t){return f.test(t)&&RegExp.$1},listScreenNameAndSlug:function(t){var e,n,r;if(h.test(t)){e=RegExp.$1,n=RegExp.$2;try{r=decodeURIComponent(n)}catch(t){}return{ownerScreenName:e,slug:r||n}}return!1},eventId:function(t){return p.test(t)&&RegExp.$1}}},function(t,e){t.exports=document},function(t,e,n){var r=n(0),i=[!0,1,"1","on","ON","true","TRUE","yes","YES"],o=[!1,0,"0","off","OFF","false","FALSE","no","NO"];function s(t){return void 0!==t&&null!==t&&""!==t}function a(t){return c(t)&&t%1==0}function u(t){return c(t)&&!a(t)}function c(t){return s(t)&&!isNaN(t)}function d(t){return r.contains(o,t)}function l(t){return r.contains(i,t)}t.exports={hasValue:s,isInt:a,isFloat:u,isNumber:c,isString:function(t){return"string"===r.toType(t)},isArray:function(t){return s(t)&&"array"==r.toType(t)},isTruthValue:l,isFalseValue:d,asInt:function(t){if(a(t))return parseInt(t,10)},asFloat:function(t){if(u(t))return t},asNumber:function(t){if(c(t))return t},asBoolean:function(t){return!(!s(t)||!l(t)&&(d(t)||!t))}}},function(t,e,n){var r=n(1),i=n(21),o=n(49);i.hasPromiseSupport()||(r.Promise=o),t.exports=r.Promise},function(t,e,n){var r=n(0);t.exports=function(t,e){var n=Array.prototype.slice.call(arguments,2);return function(){var i=r.toRealArray(arguments);return t.apply(e,n.concat(i))}}},function(t,e,n){var r=n(51);t.exports=new r("__twttr")},function(t,e){t.exports=location},function(t,e,n){var r=n(0),i=/\b([\w-_]+)\b/g;function o(t){return new RegExp("\\b"+t+"\\b","g")}function s(t,e){t.classList?t.classList.add(e):o(e).test(t.className)||(t.className+=" "+e)}function a(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(o(e)," ")}function u(t,e){return t.classList?t.classList.contains(e):r.contains(c(t),e)}function c(t){return r.toRealArray(t.classList?t.classList:t.className.match(i))}t.exports={add:s,remove:a,replace:function(t,e,n){if(t.classList&&u(t,e))return a(t,e),void s(t,n);t.className=t.className.replace(o(e),n)},toggle:function(t,e,n){return void 0===n&&t.classList&&t.classList.toggle?t.classList.toggle(e,n):(n?s(t,e):a(t,e),n)},present:u,list:c}},function(t,e,n){var r=n(5),i=n(0);function o(t){return encodeURIComponent(t).replace(/\+/g,"%2B").replace(/'/g,"%27")}function s(t){return decodeURIComponent(t)}function a(t){var e=[];return i.forIn(t,function(t,n){var s=o(t);i.isType("array",n)||(n=[n]),n.forEach(function(t){r.hasValue(t)&&e.push(s+"="+o(t))})}),e.sort().join("&")}function u(t){var e={};return t?(t.split("&").forEach(function(t){var n=t.split("="),r=s(n[0]),o=s(n[1]);if(2==n.length){if(!i.isType("array",e[r]))return r in e?(e[r]=[e[r]],void e[r].push(o)):void(e[r]=o);e[r].push(o)}}),e):{}}t.exports={url:function(t,e){return a(e).length>0?i.contains(t,"?")?t+"&"+a(e):t+"?"+a(e):t},decodeURL:function(t){var e=t&&t.split("?");return 2==e.length?u(e[1]):{}},decode:u,encode:a,encodePart:o,decodePart:s}},function(t,e,n){var r=n(9),i=n(1),o=n(0),s={},a=o.contains(r.href,"tw_debug=true");function u(){}function c(){}function d(){return i.performance&&+i.performance.now()||+new Date}function l(t,e){if(i.console&&i.console[t])switch(e.length){case 1:i.console[t](e[0]);break;case 2:i.console[t](e[0],e[1]);break;case 3:i.console[t](e[0],e[1],e[2]);break;case 4:i.console[t](e[0],e[1],e[2],e[3]);break;case 5:i.console[t](e[0],e[1],e[2],e[3],e[4]);break;default:0!==e.length&&i.console.warn&&i.console.warn("too many params passed to logger."+t)}}t.exports={devError:u,devInfo:c,devObject:function(t,e){},publicError:function(){l("error",o.toRealArray(arguments))},publicLog:function(){l("info",o.toRealArray(arguments))},publicWarn:function(){l("warn",o.toRealArray(arguments))},time:function(t){a&&(s[t]=d())},timeEnd:function(t){a&&s[t]&&(d(),s[t])}}},function(t,e,n){var r=n(19),i=n(5),o=n(11),s=n(0),a=n(115);t.exports=function(t){var e=t.href&&t.href.split("?")[1],n=e?o.decode(e):{},u={lang:a(t),width:t.getAttribute("data-width")||t.getAttribute("width"),height:t.getAttribute("data-height")||t.getAttribute("height"),related:t.getAttribute("data-related"),partner:t.getAttribute("data-partner")};return i.asBoolean(t.getAttribute("data-dnt"))&&r.setOn(),s.forIn(u,function(t,e){var r=n[t];n[t]=i.hasValue(r)?r:e}),s.compact(n)}},function(t,e,n){var r=n(77),i=n(22);t.exports=function(){var t="data-twitter-extracted-"+i.generate();return function(e,n){return r(e,n).filter(function(e){return!e.hasAttribute(t)}).map(function(e){return e.setAttribute(t,"true"),e})}}},function(t,e){function n(t,e,n,r,i,o,s){this.factory=t,this.Sandbox=e,this.srcEl=o,this.targetEl=i,this.parameters=r,this.className=n,this.options=s}n.prototype.destroy=function(){this.srcEl=this.targetEl=null},t.exports=n},function(t,e){t.exports={DM_BUTTON:"twitter-dm-button",FOLLOW_BUTTON:"twitter-follow-button",HASHTAG_BUTTON:"twitter-hashtag-button",MENTION_BUTTON:"twitter-mention-button",MOMENT:"twitter-moment",PERISCOPE:"periscope-on-air",SHARE_BUTTON:"twitter-share-button",TIMELINE:"twitter-timeline",TWEET:"twitter-tweet"}},function(t,e,n){var r=n(6),i=n(19),o=n(53),s=n(36),a=n(5),u=n(0);t.exports=function(t,e,n){var c;return t=t||[],e=e||{},c="ƒ("+t.join(", ")+", target, [options]);",function(){var d,l,f,h,p=Array.prototype.slice.apply(arguments,[0,t.length]),m=Array.prototype.slice.apply(arguments,[t.length]);return m.forEach(function(t){t&&(t.nodeType!==Node.ELEMENT_NODE?u.isType("function",t)?d=t:u.isType("object",t)&&(l=t):f=t)}),p.length!==t.length||0===m.length?(d&&u.async(function(){d(!1)}),r.reject(new Error("Not enough parameters. Expected: "+c))):f?(l=u.aug({},l||{},e),t.forEach(function(t){l[t]=p.shift()}),a.asBoolean(l.dnt)&&i.setOn(),h=s.getExperiments().then(function(t){return o.addWidget(n(l,f,void 0,t))}),d&&h.then(d,function(){d(!1)}),h):(d&&u.async(function(){d(!1)}),r.reject(new Error("No target element specified. Expected: "+c)))}}},function(t,e,n){var r=n(98),i=n(2),o=n(0);function s(t,e){return function(){try{e.resolve(t.call(this))}catch(t){e.reject(t)}}}t.exports={sync:function(t,e){t.call(e)},read:function(t,e){var n=new i;return r.read(s(t,n),e),n.promise},write:function(t,e){var n=new i;return r.write(s(t,n),e),n.promise},defer:function(t,e,n){var a=new i;return o.isType("function",t)&&(n=e,e=t,t=1),r.defer(t,s(e,a),n),a.promise}}},function(t,e,n){var r=n(4),i=n(9),o=n(38),s=n(102),a=n(5),u=n(33),c=!1,d=/https?:\/\/([^/]+).*/i;t.exports={setOn:function(){c=!0},enabled:function(t,e){return!!(c||a.asBoolean(u.val("dnt"))||s.isUrlSensitive(e||i.host)||o.isFramed()&&s.isUrlSensitive(o.rootDocumentLocation())||(t=d.test(t||r.referrer)&&RegExp.$1)&&s.isUrlSensitive(t))}}},function(t,e,n){var r=n(8),i=n(59),o="https://syndication.twitter.com",s="https://platform.twitter.com",a=["https://syndication.twitter.com","https://cdn.syndication.twimg.com","https://localhost.twitter.com:8444"],u=["https://syndication.twitter.com","https://localhost.twitter.com:8445"],c=["https://platform.twitter.com","https://localhost.twitter.com",/^https:\/\/ton\.smf1\.twitter\.com\/syndication-internal\/embed-iframe\/[0-9A-Za-z_-]+\/app/],d=function(t,e){return t.some(function(t){return t instanceof RegExp?t.test(e):t===e})},l=function(){var t=r.get("backendHost");return t&&d(a,t)?t:"https://cdn.syndication.twimg.com"},f=function(){var t=r.get("settingsSvcHost");return t&&d(u,t)?t:o};function h(t,e){var n=[t];return e.forEach(function(t){n.push(function(t){var e=(t||"").toString(),n="/"===e.slice(0,1)?1:0,r=function(t){return"/"===t.slice(-1)}(e)?-1:void 0;return e.slice(n,r)}(t))}),n.join("/")}t.exports={cookieConsent:function(t){var e=t||[];return e.unshift("cookie/consent"),h(f(),e)},embedIframe:function(t,e){var n=t||[],o=s,a=r.get("embedIframeURL");return a&&d(c,a)?h(a,n)+".html":(n.unshift(i.getBaseURLPath(e)),h(o,n)+".html")},embedService:function(t){var e=t||[],n=o;return e.unshift("srv"),h(n,e)},eventVideo:function(t){var e=t||[];return e.unshift("video/event"),h(l(),e)},grid:function(t){var e=t||[];return e.unshift("grid/collection"),h(l(),e)},moment:function(t){var e=t||[];return e.unshift("moments"),h(l(),e)},settings:function(t){var e=t||[];return e.unshift("settings"),h(f(),e)},timeline:function(t){var e=t||[];return e.unshift("timeline"),h(l(),e)},tweetBatch:function(t){var e=t||[];return e.unshift("tweets.json"),h(l(),e)},video:function(t){var e=t||[];return e.unshift("widgets/video"),h(l(),e)}}},function(t,e,n){var r=n(4),i=n(92),o=n(1),s=n(0),a=i.userAgent;function u(t){return/(Trident|MSIE|Edge[/ ]?\d)/.test(t=t||a)}t.exports={retina:function(t){return(t=t||o).devicePixelRatio?t.devicePixelRatio>=1.5:!!t.matchMedia&&t.matchMedia("only screen and (min-resolution: 144dpi)").matches},anyIE:u,ie9:function(t){return/MSIE 9/.test(t=t||a)},ie10:function(t){return/MSIE 10/.test(t=t||a)},ios:function(t){return/(iPad|iPhone|iPod)/.test(t=t||a)},android:function(t){return/^Mozilla\/5\.0 \(Linux; (U; )?Android/.test(t=t||a)},canPostMessage:function(t,e){return t=t||o,e=e||a,t.postMessage&&!(u(e)&&t.opener)},touch:function(t,e,n){return t=t||o,e=e||i,n=n||a,"ontouchstart"in t||/Opera Mini/.test(n)||e.msMaxTouchPoints>0},cssTransitions:function(){var t=r.body.style;return void 0!==t.transition||void 0!==t.webkitTransition||void 0!==t.mozTransition||void 0!==t.oTransition||void 0!==t.msTransition},hasPromiseSupport:function(){return!!(o.Promise&&o.Promise.resolve&&o.Promise.reject&&o.Promise.all&&o.Promise.race&&(new o.Promise(function(e){t=e}),s.isType("function",t)));var t},hasIntersectionObserverSupport:function(){return!!o.IntersectionObserver},hasPerformanceInformation:function(){return o.performance&&o.performance.getEntriesByType}}},function(t,e){var n="i",r=0,i=0;t.exports={generate:function(){return n+String(+new Date)+Math.floor(1e5*Math.random())+r++},deterministic:function(){return n+String(i++)}}},function(t,e,n){var r=n(50),i=n(52),o=n(0);t.exports=o.aug(r.get("events")||{},i.Emitter)},function(t,e,n){var r=n(6),i=n(2);function o(t,e){return t.then(e,e)}function s(t){return t instanceof r}t.exports={always:o,allResolved:function(t){var e;return void 0===t?r.reject(new Error("undefined is not an object")):Array.isArray(t)?(e=t.length)?new r(function(n,r){var i=0,o=[];function a(){(i+=1)===e&&(0===o.length?r():n(o))}function u(t){o.push(t),a()}t.forEach(function(t){s(t)?t.then(u,a):u(t)})}):r.resolve([]):r.reject(new Error("Type error"))},some:function(t){var e;return e=(t=t||[]).length,t=t.filter(s),e?e!==t.length?r.reject("non-Promise passed to .some"):new r(function(e,n){var r=0;function i(){(r+=1)===t.length&&n()}t.forEach(function(t){t.then(e,i)})}):r.reject("no promises passed to .some")},isPromise:s,allSettled:function(t){function e(){}return r.all((t||[]).map(function(t){return o(t,e)}))},timeout:function(t,e){var n=new i;return setTimeout(function(){n.reject(new Error("Promise timed out"))},e),t.then(function(t){n.resolve(t)},function(t){n.reject(t)}),n.promise}}},function(t,e,n){var r=n(1).JSON;t.exports={stringify:r.stringify||r.encode,parse:r.parse||r.decode}},function(t,e,n){var r=n(27),i=n(108);t.exports=r.build([i])},function(t,e,n){var r=n(39),i=n(105),o=n(7);(r=Object.create(r)).build=o(r.build,null,i),t.exports=r},function(t,e,n){var r=n(39),i=n(40),o=n(7);(r=Object.create(r)).build=o(r.build,null,i),t.exports=r},function(t,e,n){var r=n(79),i=n(80),o=n(81),s=n(9),a=n(71),u=n(82),c=n(19),d=n(5),l=n(22),f=n(0);function h(t){if(!t||!t.headers)throw new Error("unexpected response schema");return{html:t.body,config:t.config,pollInterval:1e3*parseInt(t.headers.xPolling,10)||null,maxCursorPosition:t.headers.maxPosition,minCursorPosition:t.headers.minPosition}}function p(t){if(t&&t.headers)throw new Error(t.headers.status);throw t instanceof Error?t:new Error(t)}t.exports=function(t){t.params({height:{transform:d.asInt},instanceId:{required:!0,fallback:l.deterministic},lang:{required:!0,transform:a.matchLanguage,fallback:"en"},theme:{},tweetLimit:{transform:d.asInt}}),t.defineProperty("endpoint",{get:function(){throw new Error("endpoint not specified")}}),t.defineProperty("pollEndpoint",{get:function(){return this.endpoint}}),t.define("cbId",function(t){var e=t?"_new":"_old";return"tl_"+this.params.instanceId+"_"+this.id+e}),t.define("queryParams",function(){return{lang:this.params.lang,tz:u.getTimezoneOffset(),t:r(),domain:s.host,tweet_limit:this.params.tweetLimit,dnt:c.enabled()}}),t.define("horizonQueryParams",function(){return f.compact({dnt:c.enabled(),limit:this.params.tweetLimit,lang:this.params.lang,maxHeight:this.params.height,theme:this.params.theme})}),t.define("fetch",function(){return i.fetch(this.endpoint,this.queryParams(),o,this.cbId()).then(h,p)}),t.define("poll",function(t,e){var n,r;return n={since_id:(t=t||{}).sinceId,max_id:t.maxId,min_position:t.minPosition,max_position:t.maxPosition},r=f.aug(this.queryParams(),n),i.fetch(this.pollEndpoint,r,o,this.cbId(e)).then(h,p)})}},function(t,e,n){var r=n(52).makeEmitter();t.exports={emitter:r,START:"start",ALL_WIDGETS_RENDER_START:"all_widgets_render_start",ALL_WIDGETS_RENDER_END:"all_widgets_render_end",ALL_WIDGETS_AND_IMAGES_LOADED:"all_widgets_and_images_loaded"}},function(t,e,n){var r=n(4),i=n(0);t.exports=function(t,e,n){var o;if(n=n||r,t=t||{},e=e||{},t.name){try{o=n.createElement('')}catch(e){(o=n.createElement("iframe")).name=t.name}delete t.name}else o=n.createElement("iframe");return t.id&&(o.id=t.id,delete t.id),o.allowtransparency="true",o.scrolling="no",o.setAttribute("frameBorder",0),o.setAttribute("allowTransparency",!0),i.forIn(t,function(t,e){o.setAttribute(t,e)}),i.forIn(e,function(t,e){o.style[t]=e}),o}},function(t,e,n){var r=n(27),i=n(122);t.exports=r.build([i])},function(t,e,n){var r,i=n(4);function o(t){var e,n,o,s=0;for(r={},e=(t=t||i).getElementsByTagName("meta");e[s];s++){if(n=e[s],/^twitter:/.test(n.getAttribute("name")))o=n.getAttribute("name").replace(/^twitter:/,"");else{if(!/^twitter:/.test(n.getAttribute("property")))continue;o=n.getAttribute("property").replace(/^twitter:/,"")}r[o]=n.getAttribute("content")||n.getAttribute("value")}}o(),t.exports={init:o,val:function(t){return r[t]}}},function(t,e,n){var r=n(0),i=n(45);t.exports={closest:function t(e,n,o){var s;if(n)return o=o||n&&n.ownerDocument,s=r.isType("function",e)?e:function(t){return function(e){return!!e.tagName&&i(e,t)}}(e),n===o?s(n)?n:void 0:s(n)?n:t(s,n.parentNode,o)}}},function(t,e,n){var r=n(10),i={},o=-1,s={};function a(t){var e=t.getAttribute("data-twitter-event-id");return e||(t.setAttribute("data-twitter-event-id",++o),o)}function u(t,e,n){var r=0,i=t&&t.length||0;for(r=0;r1?(e=Math.floor(t.item_ids.length/2),n=t.item_ids.slice(0,e),r={},i=t.item_ids.slice(e),o={},n.forEach(function(e){r[e]=t.item_details[e]}),i.forEach(function(e){o[e]=t.item_details[e]}),[l.aug({},t,{item_ids:n,item_details:r}),l.aug({},t,{item_ids:i,item_details:o})]):[t]},stringify:function(t){var e,n=Array.prototype.toJSON;return delete Array.prototype.toJSON,e=u.stringify(t),n&&(Array.prototype.toJSON=n),e},CLIENT_EVENT_ENDPOINT:p,RUFOUS_REDIRECT:"https://platform.twitter.com/jot.html"}},function(t,e,n){var r=n(9),i=n(75),o=n(0),s=i.getCanonicalURL()||r.href,a=s;t.exports={isFramed:function(){return s!==a},rootDocumentLocation:function(t){return t&&o.isType("string",t)&&(s=t),s},currentDocumentLocation:function(){return a}}},function(t,e,n){var r=n(103),i=n(104),o=n(0);t.exports={couple:function(){return o.toRealArray(arguments)},build:function(t,e,n){var o=new t;return(e=i(r(e||[]))).forEach(function(t){t.call(null,o)}),o.build(n)}}},function(t,e,n){var r=n(106),i=n(0),o=n(41);function s(){this.Component=this.factory(),this._adviceArgs=[],this._lastArgs=[]}i.aug(s.prototype,{factory:o,build:function(t){var e=this;return this.Component,i.aug(this.Component.prototype.boundParams,t),this._adviceArgs.concat(this._lastArgs).forEach(function(t){(function(t,e,n){var r=this[e];if(!r)throw new Error(e+" does not exist");this[e]=t(r,n)}).apply(e.Component.prototype,t)}),delete this._lastArgs,delete this._adviceArgs,this.Component},params:function(t){var e=this.Component.prototype.paramConfigs;t=t||{},this.Component.prototype.paramConfigs=i.aug({},t,e)},define:function(t,e){if(t in this.Component.prototype)throw new Error(t+" has previously been defined");this.override(t,e)},defineStatic:function(t,e){this.Component[t]=e},override:function(t,e){this.Component.prototype[t]=e},defineProperty:function(t,e){if(t in this.Component.prototype)throw new Error(t+" has previously been defined");this.overrideProperty(t,e)},overrideProperty:function(t,e){var n=i.aug({configurable:!0},e);Object.defineProperty(this.Component.prototype,t,n)},before:function(t,e){this._adviceArgs.push([r.before,t,e])},after:function(t,e){this._adviceArgs.push([r.after,t,e])},around:function(t,e){this._adviceArgs.push([r.around,t,e])},last:function(t,e){this._lastArgs.push([r.after,t,e])}}),t.exports=s},function(t,e,n){var r=n(0);function i(){return!0}function o(t){return t}t.exports=function(){function t(t){var e=this;t=t||{},this.params=Object.keys(this.paramConfigs).reduce(function(n,s){var a=[],u=e.boundParams,c=e.paramConfigs[s],d=c.validate||i,l=c.transform||o;if(s in u&&a.push(u[s]),s in t&&a.push(t[s]),a="fallback"in c?a.concat(c.fallback):a,n[s]=function(t,e,n){var i=null;return t.some(function(t){if(t=r.isType("function",t)?t():t,e(t))return i=n(t),!0}),i}(a,d,l),c.required&&null==n[s])throw new Error(s+" is a required parameter");return n},{}),this.initialize()}return r.aug(t.prototype,{paramConfigs:{},boundParams:{},initialize:function(){}}),t}},function(t,e,n){var r=n(101),i=n(76),o=new(n(110))(function(t){(!function(t){return 1===t.length&&i.canFlushOneItem(t[0])}(t)?function(t){r.init(),t.forEach(function(t){var e=t.input.namespace,n=t.input.data,i=t.input.offsite,o=t.input.version;r.clientEvent(e,n,i,o)}),r.flush().then(function(){t.forEach(function(t){t.taskDoneDeferred.resolve()})},function(){t.forEach(function(t){t.taskDoneDeferred.reject()})})}:function(t){t.forEach(function(t){var e=t.input.namespace,n=t.input.data,r=t.input.offsite,o=t.input.version;i.clientEvent(e,n,r,o),t.taskDoneDeferred.resolve()})})(t)});t.exports={scribe:function(t,e,n,r){return o.add({namespace:t,data:e,offsite:n,version:r})},pause:function(){o.pause()},resume:function(){o.resume()}}},function(t,e,n){var r,i=n(10),o=n(4),s=n(1),a=n(33),u=n(54),c=n(5),d=n(22),l="csptest";t.exports={inlineStyle:function(){var t=l+d.generate(),e=o.createElement("div"),n=o.createElement("style"),f="."+t+" { visibility: hidden; }";return!!o.body&&(c.asBoolean(a.val("widgets:csp"))&&(r=!1),void 0!==r?r:(e.style.display="none",i.add(e,t),n.type="text/css",n.appendChild(o.createTextNode(f)),o.body.appendChild(n),o.body.appendChild(e),r="hidden"===s.getComputedStyle(e).visibility,u(e),u(n),r))}}},function(t,e,n){var r=n(1);t.exports=function(t,e,n){var i,o=0;return n=n||null,function s(){var a=n||this,u=arguments,c=+new Date;if(r.clearTimeout(i),c-o>e)return o=c,void t.apply(a,u);i=r.setTimeout(function(){s.apply(a,u)},e)}}},function(t,e,n){var r=n(1).HTMLElement,i=r.prototype.matches||r.prototype.matchesSelector||r.prototype.webkitMatchesSelector||r.prototype.mozMatchesSelector||r.prototype.msMatchesSelector||r.prototype.oMatchesSelector;t.exports=function(t,e){if(i)return i.call(t,e)}},function(t){t.exports={version:"9fd78d5:1638479056965"}},function(t,e){t.exports=function(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height}}},function(t,e,n){var r=n(12).publicWarn;t.exports=function(){r("Warning: This Timeline type belongs to a group that will not be supported in the future (Likes, Collections, & Moments). It is not recommended for use. \n\t","* Twitter will continue to support Profile and List Timelines \n\t","* You can learn more about this change in our announcement: \n\t","https://twittercommunity.com/t/removing-support-for-embedded-like-collection-and-moment-timelines/150313 \n\t","* In order to create a new Embedded Timeline, visit: https://publish.twitter.com")}},function(t,e,n){ +/*! +* @overview es6-promise - a tiny implementation of Promises/A+. +* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) +* @license Licensed under MIT license +* See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE +* @version v4.2.5+7f2b526d +*/var r;r=function(){"use strict";function t(t){return"function"==typeof t}var e=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},n=0,r=void 0,i=void 0,o=function(t,e){f[n]=t,f[n+1]=e,2===(n+=2)&&(i?i(h):w())},s="undefined"!=typeof window?window:void 0,a=s||{},u=a.MutationObserver||a.WebKitMutationObserver,c="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),d="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function l(){var t=setTimeout;return function(){return t(h,1)}}var f=new Array(1e3);function h(){for(var t=0;t=0&&this._handlers[t].splice(n,1):this._handlers[t]=[])},trigger:function(t,e){var n=this._handlers&&this._handlers[t];(e=e||{}).type=t,n&&n.forEach(function(t){r.async(i(t,this,e))})}};t.exports={Emitter:o,makeEmitter:function(){return r.aug(function(){},o)}}},function(t,e,n){var r=n(97),i=n(99),o=n(6),s=n(24),a=n(7),u=n(0),c=new i(function(t){var e=function(t){return t.reduce(function(t,e){return t[e._className]=t[e._className]||[],t[e._className].push(e),t},{})}(t.map(r.fromRawTask));u.forIn(e,function(t,e){s.allSettled(e.map(function(t){return t.initialize()})).then(function(){e.forEach(function(t){o.all([t.hydrate(),t.insertIntoDom()]).then(a(t.render,t)).then(a(t.success,t),a(t.fail,t))})})})});t.exports={addWidget:function(t){return c.add(t)}}},function(t,e,n){var r=n(18);t.exports=function(t){return r.write(function(){t&&t.parentNode&&t.parentNode.removeChild(t)})}},function(t,e,n){n(12),t.exports={log:function(t,e){}}},function(t,e,n){var r=n(1);function i(t){return(t=t||r).getSelection&&t.getSelection()}t.exports={getSelection:i,getSelectedText:function(t){var e=i(t);return e?e.toString():""}}},function(t,e,n){var r=n(4),i=n(1),o=n(2),s=2e4;t.exports=function(t){var e=new o,n=r.createElement("img");return n.onload=n.onerror=function(){i.setTimeout(e.resolve,50)},n.src=t,i.setTimeout(e.reject,s),e.promise}},function(t,e,n){var r=n(109);t.exports=function(t){t.define("createElement",r),t.define("createFragment",r),t.define("htmlToElement",r),t.define("hasSelectedText",r),t.define("addRootClass",r),t.define("removeRootClass",r),t.define("hasRootClass",r),t.define("prependStyleSheet",r),t.define("appendStyleSheet",r),t.define("prependCss",r),t.define("appendCss",r),t.define("makeVisible",r),t.define("injectWidgetEl",r),t.define("matchHeightToContent",r),t.define("matchWidthToContent",r)}},function(t,e){var n="tfw_horizon_tweet_embed_9555",r="tfw_horizon_timeline_12034";t.exports={getBaseURLPath:function(t){switch(t&&t.tfw_team_holdback_11929&&t.tfw_team_holdback_11929.bucket){case"control":return"embed-holdback";case"holdback_prod":return"embed-holdback-prod";default:return"embed"}},isHorizonTweetEnabled:function(t){return!(t&&t[n]&&"control"===t[n].bucket)},isHorizonTimelineEnabled:function(t,e){return t&&t[r]&&"treatment"===t[r].bucket&&("profile"===e||"list"===e)}}},function(t,e){t.exports=function(t){var e,n=!1;return function(){return n?e:(n=!0,e=t.apply(this,arguments))}}},function(t,e,n){var r=n(15),i=n(116),o=n(117),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.DM_BUTTON,t,e,n)}},function(t,e,n){var r=n(27),i=n(118);t.exports=r.build([i])},function(t,e,n){var r=n(15),i=n(121),o=n(32),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.FOLLOW_BUTTON,t,e,n)}},function(t,e,n){var r=n(15),i=n(129),o=n(26),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.MOMENT,t,e,n)}},function(t,e,n){var r=n(15),i=n(131),o=n(26),s=n(16);t.exports=function(t,e,n){return new r(i,o,s.PERISCOPE,t,e,n)}},function(t,e,n){var r=n(78),i=n(133),o=n(137),s=n(139),a=n(141),u=n(143),c={collection:i,event:o,likes:s,list:a,profile:u,url:l},d=[u,s,i,a,o];function l(t){return r(d,function(e){try{return new e(t)}catch(t){}})}t.exports=function(t){return t?function(t){var e,n;return e=(t.sourceType+"").toLowerCase(),(n=c[e])?new n(t):null}(t)||l(t):null}},function(t,e,n){var r=n(4),i=n(59),o=n(15),s=n(145),a=n(32),u=n(146),c=n(26),d=n(147),l=n(16);t.exports=function(t,e,n,f){var h,p=s.get(t.id);return i.isHorizonTimelineEnabled(f,p)?(h=r.createElement("div"),new o(u,a,l.TIMELINE,t,e,n,{sandboxWrapperEl:h})):new o(d,c,l.TIMELINE,t,e,n)}},function(t,e,n){var r=n(4),i=n(15),o=n(32),s=n(149),a=n(16);t.exports=function(t,e,n){var u=r.createElement("div");return new i(s,o,a.TWEET,t,e,n,{sandboxWrapperEl:u})}},function(t,e,n){var r=n(15),i=n(151),o=n(32),s=n(16);t.exports=function(t,e,n){var a=t&&t.type||"share",u="hashtag"==a?s.HASHTAG_BUTTON:"mention"==a?s.MENTION_BUTTON:s.SHARE_BUTTON;return new r(i,o,u,t,e,n)}},function(t,e,n){var r=n(42),i=n(38),o=n(0);t.exports=function(t){var e={widget_origin:i.rootDocumentLocation(),widget_frame:i.isFramed()?i.currentDocumentLocation():null,duration_ms:t.duration,item_ids:t.widgetIds||[]},n=o.aug(t.namespace,{page:"page",component:"performance"});r.scribe(n,e)}},function(t,e,n){var r=n(0),i=n(134),o=["ar","fa","he","ur"];t.exports={isRtlLang:function(t){return t=String(t).toLowerCase(),r.contains(o,t)},matchLanguage:function(t){return t=(t=(t||"").toLowerCase()).replace("_","-"),i(t)?t:(t=t.replace(/-.*/,""),i(t)?t:"en")}}},function(t){t.exports={tweetButtonHtmlPath:"/widgets/tweet_button.21f942bb866c2823339b839747a0c50c.{{lang}}.html",followButtonHtmlPath:"/widgets/follow_button.21f942bb866c2823339b839747a0c50c.{{lang}}.html",hubHtmlPath:"/widgets/hub.html",widgetIframeHtmlPath:"/widgets/widget_iframe.21f942bb866c2823339b839747a0c50c.html",resourceBaseUrl:"https://platform.twitter.com"}},function(t){t.exports={TWEET:0,RETWEET:10,CUSTOM_TIMELINE:17,LIVE_VIDEO_EVENT:28,QUOTE_TWEET:23}},function(t,e,n){var r=n(3),i=n(95),o=n(23),s=n(11),a={favorite:["favorite","like"],follow:["follow"],like:["favorite","like"],retweet:["retweet"],tweet:["tweet"]};function u(t){this.srcEl=[],this.element=t}u.open=function(t,e,n){var u=(r.intentType(t)||"").toLowerCase();r.isTwitterURL(t)&&(function(t,e){i.open(t,e)}(t,n),e&&o.trigger("click",{target:e,region:"intent",type:"click",data:{}}),e&&a[u]&&a[u].forEach(function(n){o.trigger(n,{target:e,region:"intent",type:n,data:function(t,e){var n=s.decodeURL(e);switch(t){case"favorite":case"like":return{tweet_id:n.tweet_id};case"follow":return{screen_name:n.screen_name,user_id:n.user_id};case"retweet":return{source_tweet_id:n.tweet_id};default:return{}}}(u,t)})}))},t.exports=u},function(t,e,n){var r=n(4),i=n(9),o=n(3);function s(t,e){var n,r;return e=e||i,/^https?:\/\//.test(t)?t:/^\/\//.test(t)?e.protocol+t:(n=e.host+(e.port.length?":"+e.port:""),0!==t.indexOf("/")&&((r=e.pathname.split("/")).pop(),r.push(t),t="/"+r.join("/")),[e.protocol,"//",n,t].join(""))}t.exports={absolutize:s,getCanonicalURL:function(){for(var t,e=r.getElementsByTagName("link"),n=0;e[n];n++)if("canonical"==(t=e[n]).rel)return s(t.href)},getScreenNameFromPage:function(){for(var t,e,n,i=[r.getElementsByTagName("a"),r.getElementsByTagName("link")],s=0,a=0,u=/\bme\b/;t=i[s];s++)for(a=0;e=t[a];a++)if(u.test(e.rel)&&(n=o.screenName(e.href)))return n}}},function(t,e,n){var r=n(19),i=n(55),o=n(11),s=n(37),a=n(0),u=n(8).get("scribeCallback"),c=2083,d=[],l=o.url(s.CLIENT_EVENT_ENDPOINT,{dnt:0,l:""}),f=encodeURIComponent(l).length;function h(t,e,n,r,i){var o=!a.isObject(t),c=!!e&&!a.isObject(e);o||c||(u&&u(arguments),p(s.formatClientEventNamespace(t),s.formatClientEventData(e,n,r),s.CLIENT_EVENT_ENDPOINT,i))}function p(t,e,n,r){var u;n&&a.isObject(t)&&a.isObject(e)&&(i.log(t,e),u=s.flattenClientEventPayload(t,e),r=a.aug({},r,{l:s.stringify(u)}),u.dnt&&(r.dnt=1),w(o.url(n,r)))}function m(t,e,n,r){var i=!a.isObject(t),o=!!e&&!a.isObject(e);if(!i&&!o)return v(s.flattenClientEventPayload(s.formatClientEventNamespace(t),s.formatClientEventData(e,n,r)))}function v(t){return d.push(t),d}function g(t){return encodeURIComponent(t).length+3}function w(t){return(new Image).src=t}t.exports={canFlushOneItem:function(t){var e=g(s.stringify(t));return f+e1&&m({page:"widgets_js",component:"scribe_pixel",action:"batch_log"},{}),t=d,d=[],t.reduce(function(e,n,r){var i=e.length,o=i&&e[i-1];return r+1==t.length&&n.event_namespace&&"batch_log"==n.event_namespace.action&&(n.message=["entries:"+r,"requests:"+i].join("/")),function t(e){return Array.isArray(e)||(e=[e]),e.reduce(function(e,n){var r,i=s.stringify(n),o=g(i);return f+o1&&(e=e.concat(t(r))),e},[])}(n).forEach(function(t){var n=g(t);(!o||o.urlLength+n>c)&&(o={urlLength:f,items:[]},e.push(o)),o.urlLength+=n,o.items.push(t)}),e},[]).map(function(t){var e={l:t.items};return r.enabled()&&(e.dnt=1),w(o.url(s.CLIENT_EVENT_ENDPOINT,e))})},interaction:function(t,e,n,r){var i=s.extractTermsFromDOM(t.target||t.srcElement);i.action=r||"click",h(i,e,n)}}},function(t,e,n){var r=n(0),i=n(45);t.exports=function(t,e){return i(t,e)?[t]:r.toRealArray(t.querySelectorAll(e))}},function(t,e){t.exports=function(t,e,n){for(var r,i=0;i")}).then(function(){t.close(),a.resolve(c)})}),c.src=["javascript:",'document.write("");',"try { window.parent.document; }",'catch (e) { document.domain="'+r.domain+'"; }',"window.parent."+g.fullPath(["sandbox",u])+"();"].join(""),c.addEventListener("error",a.reject,!1),o.write(function(){i.parentNode.replaceChild(c,i)}),a.promise}t.exports=a.couple(n(58),function(t){t.overrideProperty("id",{get:function(){return this.sandboxEl&&this.sandboxEl.id}}),t.overrideProperty("initialized",{get:function(){return!!this.win}}),t.overrideProperty("width",{get:function(){return this._width}}),t.overrideProperty("height",{get:function(){return this._height}}),t.overrideProperty("sandboxEl",{get:function(){return this.iframeEl}}),t.defineProperty("iframeEl",{get:function(){return this._iframe}}),t.defineProperty("rootEl",{get:function(){return this.doc&&this.doc.documentElement}}),t.defineProperty("widgetEl",{get:function(){return this.doc&&this.doc.body.firstElementChild}}),t.defineProperty("win",{get:function(){return this.iframeEl&&this.iframeEl.contentWindow}}),t.defineProperty("doc",{get:function(){return this.win&&this.win.document}}),t.define("_updateCachedDimensions",function(){var t=this;return o.read(function(){var e,n=h(t.sandboxEl);"visible"==t.sandboxEl.style.visibility?t._width=n.width:(e=h(t.sandboxEl.parentElement).width,t._width=Math.min(n.width,e)),t._height=n.height})}),t.define("_setTargetToBlank",function(){var t=this.createElement("base");t.target="_blank",this.doc.head.appendChild(t)}),t.define("_didResize",function(){var t=this,e=this._resizeHandlers.slice(0);return this._updateCachedDimensions().then(function(){e.forEach(function(e){e(t)})})}),t.define("setTitle",function(t){this.iframeEl.title=t}),t.override("createElement",function(t){return this.doc.createElement(t)}),t.override("createFragment",function(){return this.doc.createDocumentFragment()}),t.override("htmlToElement",function(t){var e;return(e=this.createElement("div")).innerHTML=t,e.firstElementChild}),t.override("hasSelectedText",function(){return!!s.getSelectedText(this.win)}),t.override("addRootClass",function(t){var e=this.rootEl;return t=Array.isArray(t)?t:[t],this.initialized?o.write(function(){t.forEach(function(t){i.add(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("removeRootClass",function(t){var e=this.rootEl;return t=Array.isArray(t)?t:[t],this.initialized?o.write(function(){t.forEach(function(t){i.remove(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("hasRootClass",function(t){return i.present(this.rootEl,t)}),t.define("addStyleSheet",function(t,e){var n,r=new p;return this.initialized?((n=this.createElement("link")).type="text/css",n.rel="stylesheet",n.href=t,n.addEventListener("load",r.resolve,!1),n.addEventListener("error",r.reject,!1),o.write(y(e,null,n)).then(function(){return u(t).then(r.resolve,r.reject),r.promise})):m.reject(new Error("sandbox not initialized"))}),t.override("prependStyleSheet",function(t){var e=this.doc;return this.addStyleSheet(t,function(t){var n=e.head.firstElementChild;return n?e.head.insertBefore(t,n):e.head.appendChild(t)})}),t.override("appendStyleSheet",function(t){var e=this.doc;return this.addStyleSheet(t,function(t){return e.head.appendChild(t)})}),t.define("addCss",function(t,e){var n;return c.inlineStyle()?((n=this.createElement("style")).type="text/css",n.appendChild(this.doc.createTextNode(t)),o.write(y(e,null,n))):(f.devError("CSP enabled; cannot embed inline styles"),m.resolve())}),t.override("prependCss",function(t){var e=this.doc;return this.addCss(t,function(t){var n=e.head.firstElementChild;return n?e.head.insertBefore(t,n):e.head.appendChild(t)})}),t.override("appendCss",function(t){var e=this.doc;return this.addCss(t,function(t){return e.head.appendChild(t)})}),t.override("makeVisible",function(){var t=this;return this.styleSelf(E).then(function(){t._updateCachedDimensions()})}),t.override("injectWidgetEl",function(t){var e=this;return this.initialized?this.widgetEl?m.reject(new Error("widget already injected")):o.write(function(){e.doc.body.appendChild(t)}):m.reject(new Error("sandbox not initialized"))}),t.override("matchHeightToContent",function(){var t,e=this;return o.read(function(){t=e.widgetEl?h(e.widgetEl).height:0}),o.write(function(){e.sandboxEl.style.height=t+"px"}).then(function(){return e._updateCachedDimensions()})}),t.override("matchWidthToContent",function(){var t,e=this;return o.read(function(){t=e.widgetEl?h(e.widgetEl).width:0}),o.write(function(){e.sandboxEl.style.width=t+"px"}).then(function(){return e._updateCachedDimensions()})}),t.after("initialize",function(){this._iframe=null,this._width=this._height=0,this._resizeHandlers=[]}),t.override("insert",function(t,e,n,r){var i=this,s=new p,a=this.targetGlobal.document,u=S(t,e,n,a);return o.write(y(r,null,u)),u.addEventListener("load",function(){(function(t){try{t.contentWindow.document}catch(t){return m.reject(t)}return m.resolve(t)})(u).then(null,y(R,null,t,e,n,u,a)).then(s.resolve,s.reject)},!1),u.addEventListener("error",s.reject,!1),s.promise.then(function(t){var e=d(i._didResize,A,i);return i._iframe=t,i.win.addEventListener("resize",e,!1),m.all([i._setTargetToBlank(),i.addRootClass(x),i.prependCss(T)])})}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("styleSelf",function(){return this._updateCachedDimensions()})})},function(t,e){t.exports=function(){throw new Error("unimplemented method")}},function(t,e,n){var r=n(2),i=n(7),o=100,s=3e3;function a(t,e){this._inputsQueue=[],this._task=t,this._isPaused=!1,this._flushDelay=e&&e.flushDelay||o,this._pauseLength=e&&e.pauseLength||s,this._flushTimeout=void 0}a.prototype.add=function(t){var e=new r;return this._inputsQueue.push({input:t,taskDoneDeferred:e}),this._scheduleFlush(),e.promise},a.prototype._scheduleFlush=function(){this._isPaused||(clearTimeout(this._flushTimeout),this._flushTimeout=setTimeout(i(this._flush,this),this._flushDelay))},a.prototype._flush=function(){try{this._task.call(null,this._inputsQueue)}catch(t){this._inputsQueue.forEach(function(e){e.taskDoneDeferred.reject(t)})}this._inputsQueue=[],this._flushTimeout=void 0},a.prototype.pause=function(t){clearTimeout(this._flushTimeout),this._isPaused=!0,!t&&this._pauseLength&&setTimeout(i(this.resume,this),this._pauseLength)},a.prototype.resume=function(){this._isPaused=!1,this._scheduleFlush()},t.exports=a},function(t,e,n){var r=n(72),i=n(31),o=n(2),s=n(4),a=n(20),u=n(21),c=n(25),d=n(9),l=n(12),f=n(112),h=n(60),p=n(8),m=n(11),v=n(3),g=n(0),w=n(1),y=h(function(){return new o}),b={shouldObtainCookieConsent:!1,features:{}};t.exports={load:function(){var t,e,n,o;if(u.ie9()||u.ie10()||"http:"!==d.protocol&&"https:"!==d.protocol)return l.devError("Using default settings due to unsupported browser or protocol."),void y().resolve();t={origin:d.origin},a.settings().indexOf("localhost")>-1&&(t.localSettings=!0),e=m.url(r.resourceBaseUrl+r.widgetIframeHtmlPath,t),n=function(t){var n,r,i,o;if(r=v.isTwitterURL(t.origin),i=e.substr(0,t.origin.length)===t.origin,o=v.isTwimgURL(t.origin),i&&r||o)try{(n="string"==typeof t.data?c.parse(t.data):t.data).namespace===f.settings&&(b=g.aug(b,{features:n.settings.features,sessionId:n.sessionId}),y().resolve())}catch(t){l.devError(t)}},w.addEventListener("message",n),o=i({src:e,title:"Twitter settings iframe"},{display:"none"}),s.body.appendChild(o)},settingsLoaded:function(){var t,e;return t=p.get("experimentOverride"),y().promise.then(function(){return t&&t.name&&t.assignment&&((e={})[t.name]={bucket:t.assignment},b.features=g.aug(b.features,e)),b})}}},function(t,e){t.exports={settings:"twttr.settings"}},function(t,e,n){t.exports=[n(114),n(120),n(128),n(130),n(132),n(148),n(150)]},function(t,e,n){var r=n(11),i=n(5),o=n(0),s=n(13),a=n(14)(),u=n(61),c="a.twitter-dm-button";t.exports=function(t){return a(t,c).map(function(t){return u(function(t){var e=t.getAttribute("data-show-screen-name"),n=s(t),a=t.getAttribute("href"),u=t.getAttribute("data-screen-name"),c=e?i.asBoolean(e):null,d=t.getAttribute("data-size"),l=r.decodeURL(a),f=l.recipient_id,h=t.getAttribute("data-text")||l.text,p=t.getAttribute("data-welcome-message-id")||l.welcomeMessageId;return o.aug(n,{screenName:u,showScreenName:c,size:d,text:h,userId:f,welcomeMessageId:p})}(t),t.parentNode,t)})}},function(t,e,n){var r=n(0);t.exports=function t(e){var n;if(e)return n=e.lang||e.getAttribute("data-lang"),r.isType("string",n)?n:t(e.parentElement)}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(2).then(function(r){var o;try{o=n(83),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(62),i=n(26);t.exports=r.isSupported()?r:i},function(t,e,n){var r=n(119),i=n(1),o=n(10),s=n(35),a=n(18),u=n(56),c=n(27),d=n(57),l=n(43),f=n(47),h=n(7),p=n(44),m=n(6),v=n(0),g=50,w={position:"absolute",visibility:"hidden",display:"block",transform:"rotate(0deg)"},y={position:"static",visibility:"visible"},b="twitter-widget",_="open",E="SandboxRoot",x=".SandboxRoot { display: none; max-height: 10000px; }";t.exports=c.couple(n(58),function(t){t.defineStatic("isSupported",function(){return!!i.HTMLElement.prototype.attachShadow&&l.inlineStyle()}),t.overrideProperty("id",{get:function(){return this.sandboxEl&&this.sandboxEl.id}}),t.overrideProperty("initialized",{get:function(){return!!this._shadowHost}}),t.overrideProperty("width",{get:function(){return this._width}}),t.overrideProperty("height",{get:function(){return this._height}}),t.overrideProperty("sandboxEl",{get:function(){return this._shadowHost}}),t.define("_updateCachedDimensions",function(){var t=this;return a.read(function(){var e,n=f(t.sandboxEl);"visible"==t.sandboxEl.style.visibility?t._width=n.width:(e=f(t.sandboxEl.parentElement).width,t._width=Math.min(n.width,e)),t._height=n.height})}),t.define("_didResize",function(){var t=this,e=this._resizeHandlers.slice(0);return this._updateCachedDimensions().then(function(){e.forEach(function(e){e(t)})})}),t.override("createElement",function(t){return this.targetGlobal.document.createElement(t)}),t.override("createFragment",function(){return this.targetGlobal.document.createDocumentFragment()}),t.override("htmlToElement",function(t){var e;return(e=this.createElement("div")).innerHTML=t,e.firstElementChild}),t.override("hasSelectedText",function(){return!!u.getSelectedText(this.targetGlobal)}),t.override("addRootClass",function(t){var e=this._shadowRootBody;return t=Array.isArray(t)?t:[t],this.initialized?a.write(function(){t.forEach(function(t){o.add(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("removeRootClass",function(t){var e=this._shadowRootBody;return t=Array.isArray(t)?t:[t],this.initialized?a.write(function(){t.forEach(function(t){o.remove(e,t)})}):m.reject(new Error("sandbox not initialized"))}),t.override("hasRootClass",function(t){return o.present(this._shadowRootBody,t)}),t.override("addStyleSheet",function(t,e){return this.addCss('@import url("'+t+'");',e).then(function(){return d(t)})}),t.override("prependStyleSheet",function(t){var e=this._shadowRoot;return this.addStyleSheet(t,function(t){var n=e.firstElementChild;return n?e.insertBefore(t,n):e.appendChild(t)})}),t.override("appendStyleSheet",function(t){var e=this._shadowRoot;return this.addStyleSheet(t,function(t){return e.appendChild(t)})}),t.override("addCss",function(t,e){var n;return this.initialized?l.inlineStyle()?((n=this.createElement("style")).type="text/css",n.appendChild(this.targetGlobal.document.createTextNode(t)),a.write(h(e,null,n))):m.resolve():m.reject(new Error("sandbox not initialized"))}),t.override("prependCss",function(t){var e=this._shadowRoot;return this.addCss(t,function(t){var n=e.firstElementChild;return n?e.insertBefore(t,n):e.appendChild(t)})}),t.override("appendCss",function(t){var e=this._shadowRoot;return this.addCss(t,function(t){return e.appendChild(t)})}),t.override("makeVisible",function(){return this.styleSelf(y)}),t.override("injectWidgetEl",function(t){var e=this;return this.initialized?this._shadowRootBody.firstElementChild?m.reject(new Error("widget already injected")):a.write(function(){e._shadowRootBody.appendChild(t)}).then(function(){return e._updateCachedDimensions()}).then(function(){var t=p(e._didResize,g,e);new r(e._shadowRootBody,t)}):m.reject(new Error("sandbox not initialized"))}),t.override("matchHeightToContent",function(){return m.resolve()}),t.override("matchWidthToContent",function(){return m.resolve()}),t.override("insert",function(t,e,n,r){var i=this.targetGlobal.document,o=this._shadowHost=i.createElement(b),u=this._shadowRoot=o.attachShadow({mode:_}),c=this._shadowRootBody=i.createElement("div");return v.forIn(e||{},function(t,e){o.setAttribute(t,e)}),o.id=t,u.appendChild(c),s.delegate(c,"click","A",function(t,e){e.hasAttribute("target")||e.setAttribute("target","_blank")}),m.all([this.styleSelf(w),this.addRootClass(E),this.prependCss(x),a.write(r.bind(null,o))])}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("initialize",function(){this._shadowHost=this._shadowRoot=this._shadowRootBody=null,this._width=this._height=0,this._resizeHandlers=[]}),t.after("styleSelf",function(){return this._updateCachedDimensions()})})},function(t,e){var n;(n=function(t,e){function r(t,e){if(t.resizedAttached){if(t.resizedAttached)return void t.resizedAttached.add(e)}else t.resizedAttached=new function(){var t,e;this.q=[],this.add=function(t){this.q.push(t)},this.call=function(){for(t=0,e=this.q.length;t
    ',t.appendChild(t.resizeSensor),{fixed:1,absolute:1}[function(t,e){return t.currentStyle?t.currentStyle[e]:window.getComputedStyle?window.getComputedStyle(t,null).getPropertyValue(e):t.style[e]}(t,"position")]||(t.style.position="relative");var i,o,s=t.resizeSensor.childNodes[0],a=s.childNodes[0],u=t.resizeSensor.childNodes[1],c=(u.childNodes[0],function(){a.style.width=s.offsetWidth+10+"px",a.style.height=s.offsetHeight+10+"px",s.scrollLeft=s.scrollWidth,s.scrollTop=s.scrollHeight,u.scrollLeft=u.scrollWidth,u.scrollTop=u.scrollHeight,i=t.offsetWidth,o=t.offsetHeight});c();var d=function(t,e,n){t.attachEvent?t.attachEvent("on"+e,n):t.addEventListener(e,n)},l=function(){t.offsetWidth==i&&t.offsetHeight==o||t.resizedAttached&&t.resizedAttached.call(),c()};d(s,"scroll",l),d(u,"scroll",l)}var i=Object.prototype.toString.call(t),o="[object Array]"===i||"[object NodeList]"===i||"[object HTMLCollection]"===i||"undefined"!=typeof jQuery&&t instanceof jQuery||"undefined"!=typeof Elements&&t instanceof Elements;if(o)for(var s=0,a=t.length;s0;return this.updateCachedDimensions().then(function(){e&&t._resizeHandlers.forEach(function(e){e(t)})})}),t.define("loadDocument",function(t){var e=new a;return this.initialized?this.iframeEl.src?u.reject(new Error("widget already loaded")):(this.iframeEl.addEventListener("load",e.resolve,!1),this.iframeEl.addEventListener("error",e.reject,!1),this.iframeEl.src=t,e.promise):u.reject(new Error("sandbox not initialized"))}),t.after("initialize",function(){var t=new a,e=new a;this._iframe=null,this._iframeVersion=null,this._width=this._height=0,this._resizeHandlers=[],this._rendered=t,this._results=e,this._waitToSwapUntilRendered=!1}),t.override("insert",function(t,e,n,i){var a=this;return e=d.aug({id:t},l,e),n=d.aug({},f,n),this._iframe=s(e,n),p[t]=this,a._waitToSwapUntilRendered||this.onResize(o(function(){a.makeVisible()})),r.write(c(i,null,this._iframe))}),t.override("onResize",function(t){this._resizeHandlers.push(t)}),t.after("styleSelf",function(){return this.updateCachedDimensions()})}},function(t,e,n){var r=n(1),i=n(124),o=n(126),s=n(23),a=n(5),u=n(127);t.exports=function(t,e,n,c,d){function l(t){var e=u(this);s.trigger(t.type,{target:e,region:t.region,type:t.type,data:t.data||{}})}function f(e){var n=u(this),r=n&&n.id,i=a.asInt(e.width),o=a.asInt(e.height);r&&void 0!==i&&void 0!==o&&t(r,i,o)}(new i).attachReceiver(new o.Receiver(r,"twttr.button")).bind("twttr.private.trigger",l).bind("twttr.private.resizeButton",f),(new i).attachReceiver(new o.Receiver(r,"twttr.embed")).bind("twttr.private.initialized",function(t){var e=u(this),n=e&&e.id,r=t.iframe_version;n&&r&&c&&c(n,r)}).bind("twttr.private.trigger",l).bind("twttr.private.results",function(){var t=u(this),n=t&&t.id;n&&e&&e(n)}).bind("twttr.private.rendered",function(){var t=u(this),e=t&&t.id;e&&n&&n(e)}).bind("twttr.private.no_results",function(){var t=u(this),e=t&&t.id;e&&d&&d(e)}).bind("twttr.private.resize",f)}},function(t,e,n){var r=n(25),i=n(125),o=n(0),s=n(6),a=n(24),u="2.0";function c(t){this.registry=t||{}}function d(t){var e,n;return e=o.isType("string",t),n=o.isType("number",t),e||n||null===t}function l(t,e){return{jsonrpc:u,id:d(t)?t:null,error:e}}c.prototype._invoke=function(t,e){var n,r,i;n=this.registry[t.method],r=t.params||[],r=o.isType("array",r)?r:[r];try{i=n.apply(e.source||null,r)}catch(t){i=s.reject(t.message)}return a.isPromise(i)?i:s.resolve(i)},c.prototype._processRequest=function(t,e){var n,r;return function(t){var e,n,r;return!!o.isObject(t)&&(e=t.jsonrpc===u,n=o.isType("string",t.method),r=!("id"in t)||d(t.id),e&&n&&r)}(t)?(n="params"in t&&(r=t.params,!o.isObject(r)||o.isType("function",r))?s.resolve(l(t.id,i.INVALID_PARAMS)):this.registry[t.method]?this._invoke(t,{source:e}).then(function(e){return n=t.id,{jsonrpc:u,id:n,result:e};var n},function(){return l(t.id,i.INTERNAL_ERROR)}):s.resolve(l(t.id,i.METHOD_NOT_FOUND)),null!=t.id?n:s.resolve()):s.resolve(l(t.id,i.INVALID_REQUEST))},c.prototype.attachReceiver=function(t){return t.attachTo(this),this},c.prototype.bind=function(t,e){return this.registry[t]=e,this},c.prototype.receive=function(t,e){var n,a,u,c=this;try{u=t,t=o.isType("string",u)?r.parse(u):u}catch(t){return s.resolve(l(null,i.PARSE_ERROR))}return e=e||null,a=((n=o.isType("array",t))?t:[t]).map(function(t){return c._processRequest(t,e)}),n?function(t){return s.all(t).then(function(t){return(t=t.filter(function(t){return void 0!==t})).length?t:void 0})}(a):a[0]},t.exports=c},function(t){t.exports={PARSE_ERROR:{code:-32700,message:"Parse error"},INVALID_REQUEST:{code:-32600,message:"Invalid Request"},INVALID_PARAMS:{code:-32602,message:"Invalid params"},METHOD_NOT_FOUND:{code:-32601,message:"Method not found"},INTERNAL_ERROR:{code:-32603,message:"Internal error"}}},function(t,e,n){var r=n(9),i=n(1),o=n(25),s=n(2),a=n(21),u=n(0),c=n(3),d=n(7),l=a.ie9();function f(t,e,n){var r;t&&t.postMessage&&(l?r=(n||"")+o.stringify(e):n?(r={})[n]=e:r=e,t.postMessage(r,"*"))}function h(t){return u.isType("string",t)?t:"JSONRPC"}function p(t,e){return e?u.isType("string",t)&&0===t.indexOf(e)?t.substring(e.length):t&&t[e]?t[e]:void 0:t}function m(t,e){var n=t.document;this.filter=h(e),this.server=null,this.isTwitterFrame=c.isTwitterURL(n.location.href),t.addEventListener("message",d(this._onMessage,this),!1)}function v(t,e){this.pending={},this.target=t,this.isTwitterHost=c.isTwitterURL(r.href),this.filter=h(e),i.addEventListener("message",d(this._onMessage,this),!1)}u.aug(m.prototype,{_onMessage:function(t){var e,n=this;this.server&&(this.isTwitterFrame&&!c.isTwitterURL(t.origin)||(e=p(t.data,this.filter))&&this.server.receive(e,t.source).then(function(e){e&&f(t.source,e,n.filter)}))},attachTo:function(t){this.server=t},detach:function(){this.server=null}}),u.aug(v.prototype,{_processResponse:function(t){var e=this.pending[t.id];e&&(e.resolve(t),delete this.pending[t.id])},_onMessage:function(t){var e;if((!this.isTwitterHost||c.isTwitterURL(t.origin))&&(e=p(t.data,this.filter))){if(u.isType("string",e))try{e=o.parse(e)}catch(t){return}(e=u.isType("array",e)?e:[e]).forEach(d(this._processResponse,this))}},send:function(t){var e=new s;return t.id?this.pending[t.id]=e:e.resolve(),f(this.target,t,this.filter),e.promise}}),t.exports={Receiver:m,Dispatcher:v,_stringifyPayload:function(t){return arguments.length>0&&(l=!!t),l}}},function(t,e,n){var r=n(4);t.exports=function(t){for(var e,n=r.getElementsByTagName("iframe"),i=0;n[i];i++)if((e=n[i]).contentWindow===t)return e}},function(t,e,n){var r=n(5),i=n(0),o=n(3),s=n(13),a=n(14)(),u=n(64),c="a.twitter-moment";t.exports=function(t){return a(t,c).map(function(t){return u(function(t){var e=s(t),n={momentId:o.momentId(t.href),chrome:t.getAttribute("data-chrome"),limit:t.getAttribute("data-limit")};return i.forIn(n,function(t,n){var i=e[t];e[t]=r.hasValue(i)?i:n}),e}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return Promise.all([n.e(0),n.e(4)]).then(function(r){var o;try{o=n(85),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(0),i=n(13),o=n(14)(),s=n(65),a="a.periscope-on-air",u=/^https?:\/\/(?:www\.)?(?:periscope|pscp)\.tv\/@?([a-zA-Z0-9_]+)\/?$/i;t.exports=function(t){return o(t,a).map(function(t){return s(function(t){var e=i(t),n=t.getAttribute("href"),o=t.getAttribute("data-size"),s=u.exec(n)[1];return r.aug(e,{username:s,size:o})}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(5).then(function(r){var o;try{o=n(86),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(5),i=n(0),o=n(66),s=n(13),a=n(14)(),u=n(67),c=n(3),d=n(12),l="a.twitter-timeline,div.twitter-timeline,a.twitter-grid",f="Embedded Search timelines have been deprecated. See https://twittercommunity.com/t/deprecating-widget-settings/102295.",h="You may have been affected by an update to settings in embedded timelines. See https://twittercommunity.com/t/deprecating-widget-settings/102295.",p="Embedded grids have been deprecated and will now render as timelines. Please update your embed code to use the twitter-timeline class. More info: https://twittercommunity.com/t/update-on-the-embedded-grid-display-type/119564.";t.exports=function(t,e){return a(t,l).map(function(t){return u(function(t){var e=s(t),n=t.getAttribute("data-show-replies"),a={isPreconfigured:!!t.getAttribute("data-widget-id"),chrome:t.getAttribute("data-chrome"),tweetLimit:t.getAttribute("data-tweet-limit")||t.getAttribute("data-limit"),ariaLive:t.getAttribute("data-aria-polite"),theme:t.getAttribute("data-theme"),borderColor:t.getAttribute("data-border-color"),showReplies:n?r.asBoolean(n):null,profileScreenName:t.getAttribute("data-screen-name"),profileUserId:t.getAttribute("data-user-id"),favoritesScreenName:t.getAttribute("data-favorites-screen-name"),favoritesUserId:t.getAttribute("data-favorites-user-id"),likesScreenName:t.getAttribute("data-likes-screen-name"),likesUserId:t.getAttribute("data-likes-user-id"),listOwnerScreenName:t.getAttribute("data-list-owner-screen-name"),listOwnerUserId:t.getAttribute("data-list-owner-id"),listId:t.getAttribute("data-list-id"),listSlug:t.getAttribute("data-list-slug"),customTimelineId:t.getAttribute("data-custom-timeline-id"),staticContent:t.getAttribute("data-static-content"),url:t.href};return a.isPreconfigured&&(c.isSearchUrl(a.url)?d.publicError(f,t):d.publicLog(h,t)),"twitter-grid"===t.className&&d.publicLog(p,t),(a=i.aug(a,e)).dataSource=o(a),a.id=a.dataSource&&a.dataSource.id,a}(t),t.parentNode,t,e)})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(136)])},function(t,e,n){var r=n(0),i=n(135);t.exports=function(t){return"en"===t||r.contains(i,t)}},function(t,e){t.exports=["hi","zh-cn","fr","zh-tw","msa","fil","fi","sv","pl","ja","ko","de","it","pt","es","ru","id","tr","da","no","nl","hu","fa","ar","ur","he","th","cs","uk","vi","ro","bn","el","en-gb","gu","kn","mr","ta","bg","ca","hr","sr","sk"]},function(t,e,n){var r=n(3),i=n(0),o=n(20),s=n(48),a="collection:";function u(t,e){return r.collectionId(t)||e}t.exports=function(t){t.params({id:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params.url,this.params.id);return a+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["collection"])}}),t.around("queryParams",function(t){return i.aug(t(),{collection_id:u(this.params.url,this.params.id)})}),t.before("initialize",function(){if(!u(this.params.url,this.params.id))throw new Error("one of url or id is required");s()})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(138)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s="event:";function a(t,e){return r.eventId(t)||e}t.exports=function(t){t.params({id:{},url:{}}),t.overrideProperty("id",{get:function(){var t=a(this.params.url,this.params.id);return s+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["event"])}}),t.around("queryParams",function(t){return i.aug(t(),{event_id:a(this.params.url,this.params.id)})}),t.before("initialize",function(){if(!a(this.params.url,this.params.id))throw new Error("one of url or id is required")})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(140)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s=n(48),a="likes:";function u(t){return r.likesScreenName(t.url)||t.screenName}t.exports=function(t){t.params({screenName:{},userId:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params)||this.params.userId;return a+t}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["likes"])}}),t.define("_getLikesQueryParam",function(){var t=u(this.params);return t?{screen_name:t}:{user_id:this.params.userId}}),t.around("queryParams",function(t){return i.aug(t(),this._getLikesQueryParam())}),t.before("initialize",function(){if(!u(this.params)&&!this.params.userId)throw new Error("screen name or user id is required");s()})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(142)])},function(t,e,n){var r=n(3),i=n(0),o=n(20),s="list:";function a(t){var e=r.listScreenNameAndSlug(t.url)||t;return i.compact({screen_name:e.ownerScreenName,user_id:e.ownerUserId,list_slug:e.slug})}t.exports=function(t){t.params({id:{},ownerScreenName:{},ownerUserId:{},slug:{},url:{}}),t.overrideProperty("id",{get:function(){var t,e,n;return this.params.id?s+this.params.id:(e=(t=a(this.params))&&t.list_slug.replace(/-/g,"_"),n=t&&(t.screen_name||t.user_id),s+(n+":")+e)}}),t.overrideProperty("endpoint",{get:function(){return o.timeline(["list"])}}),t.define("_getListQueryParam",function(){return this.params.id?{list_id:this.params.id}:a(this.params)}),t.around("queryParams",function(t){return i.aug(t(),this._getListQueryParam())}),t.defineProperty("horizonEndpoint",{get:function(){var t,e=["timeline-list"];return this.params.id?e.push("list-id",this.params.id):(t=a(this.params),e.push("screen-name",t.screen_name,"slug",t.list_slug)),o.embedService(e)}}),t.before("initialize",function(){var t=a(this.params);if(i.isEmptyObject(t)&&!this.params.id)throw new Error("qualified slug or list id required")})}},function(t,e,n){var r=n(28);t.exports=r.build([n(29),n(144)])},function(t,e,n){var r=n(3),i=n(5),o=n(0),s=n(20),a="profile:";function u(t,e){return r.screenName(t)||e}t.exports=function(t){t.params({showReplies:{fallback:!1,transform:i.asBoolean},screenName:{},userId:{},url:{}}),t.overrideProperty("id",{get:function(){var t=u(this.params.url,this.params.screenName);return a+(t||this.params.userId)}}),t.overrideProperty("endpoint",{get:function(){return s.timeline(["profile"])}}),t.define("_getProfileQueryParam",function(){var t=u(this.params.url,this.params.screenName),e=t?{screen_name:t}:{user_id:this.params.userId};return o.aug(e,{with_replies:this.params.showReplies?"true":"false"})}),t.around("queryParams",function(t){return o.aug(t(),this._getProfileQueryParam())}),t.defineProperty("horizonEndpoint",{get:function(){var t=["timeline-profile"],e=u(this.params.url,this.params.screenName);return e?t.push("screen-name",e):t.push("user-id",this.params.userId),s.embedService(t)}}),t.around("horizonQueryParams",function(t){return o.aug(t(),{showReplies:this.params.showReplies?"true":"false"})}),t.before("initialize",function(){if(!u(this.params.url,this.params.screenName)&&!this.params.userId)throw new Error("screen name or user id is required")})}},function(t,e){var n={collection:"collection",moment:"moment",event:"event",likes:"likes",list:"list",profile:"profile"};t.exports={get:function(t){var e;return!!t&&(e=t.slice(0,t.indexOf(":")),-1!==Object.keys(n).indexOf(e)&&e)},DATASOURCE_MAP:n}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(6).then(function(r){var o;try{o=n(87),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return Promise.all([n.e(0),n.e(7)]).then(function(r){var o;try{o=n(88),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(10),i=n(3),o=n(0),s=n(13),a=n(14)(),u=n(68),c="blockquote.twitter-tweet, blockquote.twitter-video",d=/\btw-align-(left|right|center)\b/;t.exports=function(t,e){return a(t,c).map(function(t){return u(function(t){var e=s(t),n=t.getElementsByTagName("A"),a=n&&n[n.length-1],u=a&&i.status(a.href),c=t.getAttribute("data-conversation"),l="none"==c||"hidden"==c||r.present(t,"tw-hide-thread"),f=t.getAttribute("data-cards"),h="none"==f||"hidden"==f||r.present(t,"tw-hide-media"),p=t.getAttribute("data-align")||t.getAttribute("align"),m=t.getAttribute("data-theme");return!p&&d.test(t.className)&&(p=RegExp.$1),o.aug(e,{tweetId:u,hideThread:l,hideCard:h,align:p,theme:m,id:u})}(t),t.parentNode,t,e)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(8).then(function(r){var o;try{o=n(89),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(10),i=n(0),o=n(13),s=n(14)(),a=n(69),u=n(5),c="a.twitter-share-button, a.twitter-mention-button, a.twitter-hashtag-button",d="twitter-hashtag-button",l="twitter-mention-button";t.exports=function(t){return s(t,c).map(function(t){return a(function(t){var e=o(t),n={screenName:t.getAttribute("data-button-screen-name"),text:t.getAttribute("data-text"),type:t.getAttribute("data-type"),size:t.getAttribute("data-size"),url:t.getAttribute("data-url"),hashtags:t.getAttribute("data-hashtags"),via:t.getAttribute("data-via"),buttonHashtag:t.getAttribute("data-button-hashtag")};return i.forIn(n,function(t,n){var r=e[t];e[t]=u.hasValue(r)?r:n}),e.screenName=e.screenName||e.screen_name,e.buttonHashtag=e.buttonHashtag||e.button_hashtag||e.hashtag,r.present(t,d)&&(e.type="hashtag"),r.present(t,l)&&(e.type="mention"),e}(t),t.parentNode,t)})}},function(t,e,n){var r=n(2);t.exports=function(t,e){var i=new r;return n.e(3).then(function(r){var o;try{o=n(90),i.resolve(new o(t,e))}catch(t){i.reject(t)}}.bind(null,n)).catch(function(t){i.reject(t)}),i.promise}},function(t,e,n){var r=n(0);t.exports=r.aug({},n(153),n(154),n(155),n(156),n(157),n(158),n(159))},function(t,e,n){var r=n(61),i=n(17)(["userId"],{},r);t.exports={createDMButton:i}},function(t,e,n){var r=n(63),i=n(17)(["screenName"],{},r);t.exports={createFollowButton:i}},function(t,e,n){var r=n(64),i=n(17)(["momentId"],{},r);t.exports={createMoment:i}},function(t,e,n){var r=n(65),i=n(17)(["username"],{},r);t.exports={createPeriscopeOnAirButton:i}},function(t,e,n){var r=n(9),i=n(12),o=n(3),s=n(0),a=n(5),u=n(66),c=n(67),d=n(17)([],{},c),l=n(6),f="Embedded grids have been deprecated. Please use twttr.widgets.createTimeline instead. More info: https://twittercommunity.com/t/update-on-the-embedded-grid-display-type/119564.",h={createTimeline:p,createGridFromCollection:function(t){var e=s.toRealArray(arguments).slice(1),n={sourceType:"collection",id:t};return e.unshift(n),i.publicLog(f),p.apply(this,e)}};function p(t){var e,n=s.toRealArray(arguments).slice(1);return a.isString(t)||a.isNumber(t)?l.reject("Embedded timelines with widget settings have been deprecated. See https://twittercommunity.com/t/deprecating-widget-settings/102295."):s.isObject(t)?(t=t||{},n.forEach(function(t){s.isType("object",t)&&function(t){t.ariaLive=t.ariaPolite}(e=t)}),e||(e={},n.push(e)),t.lang=e.lang,t.tweetLimit=e.tweetLimit,t.showReplies=e.showReplies,e.dataSource=u(t),d.apply(this,n)):l.reject("data source must be an object.")}o.isTwitterURL(r.href)&&(h.createTimelinePreview=function(t,e,n){var r={previewParams:t,useLegacyDefaults:!0,isPreviewTimeline:!0};return r.dataSource=u(r),d(e,r,n)}),t.exports=h},function(t,e,n){var r,i=n(0),o=n(68),s=n(17),a=(r=s(["tweetId"],{},o),function(){return i.toRealArray(arguments).slice(1).forEach(function(t){i.isType("object",t)&&(t.hideCard="none"==t.cards||"hidden"==t.cards,t.hideThread="none"==t.conversation||"hidden"==t.conversation)}),r.apply(this,arguments)});t.exports={createTweet:a,createTweetEmbed:a,createVideo:a}},function(t,e,n){var r=n(0),i=n(69),o=n(17),s=o(["url"],{type:"share"},i),a=o(["buttonHashtag"],{type:"hashtag"},i),u=o(["screenName"],{type:"mention"},i);function c(t){return function(){return r.toRealArray(arguments).slice(1).forEach(function(t){r.isType("object",t)&&(t.screenName=t.screenName||t.screen_name,t.buttonHashtag=t.buttonHashtag||t.button_hashtag||t.hashtag)}),t.apply(this,arguments)}}t.exports={createShareButton:c(s),createHashtagButton:c(a),createMentionButton:c(u)}},function(t,e,n){var r,i,o,s=n(4),a=n(1),u=0,c=[],d=s.createElement("a");function l(){var t,e;for(u=1,t=0,e=c.length;t { + document.getElementById('userpage').addEventListener('click', () => { if (audio.paused) audio.play(); }, {once : true}); @@ -57,7 +57,7 @@ else } function badge_timestamp(t) { - const date = formatDate(new Date(t.dataset.until*1000)); + const date = new Date(t.dataset.until*1000); const text = t.getAttribute("data-bs-original-title") t.setAttribute("data-bs-original-title", `${text} ${date.toString()}`); t.removeAttribute("onmouseover") diff --git a/files/assets/manifest_PCM.json b/files/assets/manifest_PCM.json index c9011b8b8..82a00ab28 100644 --- a/files/assets/manifest_PCM.json +++ b/files/assets/manifest_PCM.json @@ -1,22 +1,8 @@ { - "name": "PCM", - "short_name": "PCM", - "start_url": "https://pcmemes.net", - "display": "minimal-ui", - "background_color": "#805AD5", - "description": "PCM", - "offline_enabled": true, - "icons": [ - { - "src": "/i/PCM/192.png?v=2001", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/i/PCM/512.png?v=2001", - "sizes": "512x512", - "type": "image/png" - } - ] -} + "name": "PCM", + "short_name": "PCM", + "start_url": "https://pcmemes.net", + "display": "standalone", + "background_color": "#805AD5", + "description": "PCM" +} \ No newline at end of file diff --git a/files/assets/manifest_WPD.json b/files/assets/manifest_WPD.json index 40fd74167..1bd81a7d3 100644 --- a/files/assets/manifest_WPD.json +++ b/files/assets/manifest_WPD.json @@ -1,22 +1,8 @@ { - "name": "WPD", - "short_name": "WPD", - "start_url": "https://watchpeopledie.tv", - "display": "minimal-ui", - "background_color": "#805AD5", - "description": "WPD", - "offline_enabled": true, - "icons": [ - { - "src": "/i/WPD/192.png?v=2001", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/i/WPD/512.png?v=2001", - "sizes": "512x512", - "type": "image/png" - } - ] + "name": "WPD", + "short_name": "WPD", + "start_url": "https://watchpeopledie.tv", + "display": "standalone", + "background_color": "#2A96F3", + "description": "WPD" } diff --git a/files/assets/manifest_rDrama.json b/files/assets/manifest_rDrama.json index 5d04b0bc4..51139ecc2 100644 --- a/files/assets/manifest_rDrama.json +++ b/files/assets/manifest_rDrama.json @@ -2,7 +2,7 @@ "name": "rDrama", "short_name": "rDrama", "start_url": "https://rdrama.net", - "display": "minimal-ui", + "display": "standalone", "background_color": "#FF66AC", "description": "rDrama", "offline_enabled": true, @@ -10,8 +10,7 @@ { "src": "/i/rDrama/192.png?v=2000", "sizes": "192x192", - "type": "image/png", - "purpose": "any" + "type": "image/png" }, { "src": "/i/rDrama/512.png?v=2000", @@ -19,4 +18,4 @@ "type": "image/png" } ] -} +} \ No newline at end of file diff --git a/files/classes/__init__.py b/files/classes/__init__.py index dd1f6f2e1..5890d4a2a 100644 --- a/files/classes/__init__.py +++ b/files/classes/__init__.py @@ -33,5 +33,6 @@ if KOFI_TOKEN: from .transactions import * from .sub_logs import * from .media import * + if FEATURES['STREAMERS']: from .streamers import * diff --git a/files/classes/award.py b/files/classes/award.py index 147607f91..7c0f189dc 100644 --- a/files/classes/award.py +++ b/files/classes/award.py @@ -35,7 +35,8 @@ class AwardRelationship(Base): @lazy def type(self): if self.kind in AWARDS: return AWARDS[self.kind] - else: return HOUSE_AWARDS[self.kind] + elif self.kind in HOUSE_AWARDS: return HOUSE_AWARDS[self.kind] + else: return AWARDS['fallback'] @property @lazy diff --git a/files/classes/sub.py b/files/classes/sub.py index 495a2fb58..22c1a5c7c 100644 --- a/files/classes/sub.py +++ b/files/classes/sub.py @@ -7,10 +7,14 @@ from sqlalchemy.sql.sqltypes import * from files.classes import Base from files.helpers.lazy import lazy -from files.helpers.const import * from .sub_relationship import * +SITE_NAME = environ.get("SITE_NAME", '').strip() +SITE = environ.get("SITE", '').strip() +if SITE == "localhost": SITE_FULL = 'http://' + SITE +else: SITE_FULL = 'https://' + SITE + class Sub(Base): __tablename__ = "subs" name = Column(String, primary_key=True) diff --git a/files/classes/submission.py b/files/classes/submission.py index 655ef47ee..6f895f7d5 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -288,7 +288,7 @@ class Submission(Base): for o in self.options: if o.exclusive > 1: - body += f'''
    = POLL_BET_COINS) or self.total_bet_voted(v): body += " disabled " diff --git a/files/classes/user.py b/files/classes/user.py index 71d4fc5fb..898962bdd 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -113,7 +113,7 @@ class User(Base): login_nonce = Column(Integer, default=0) coins = Column(Integer, default=0) truescore = Column(Integer, default=0) - marseybux = Column(Integer, default=0) + procoins = Column(Integer, default=0) mfa_secret = deferred(Column(String)) is_private = Column(Boolean, default=False) stored_subscriber_count = Column(Integer, default=0) @@ -175,7 +175,7 @@ class User(Base): if currency == 'coins': g.db.query(User).filter(User.id == self.id).update({ User.coins: User.coins + amount }) else: - g.db.query(User).filter(User.id == self.id).update({ User.marseybux: User.marseybux + amount }) + g.db.query(User).filter(User.id == self.id).update({ User.procoins: User.procoins + amount }) g.db.flush() @@ -192,11 +192,11 @@ class User(Base): if not should_check_balance or account_balance >= amount: g.db.query(User).filter(User.id == self.id).update({ User.coins: User.coins - amount }) succeeded = True - elif currency == 'marseybux': - account_balance = in_db.marseybux + elif currency == 'procoins': + account_balance = in_db.procoins if not should_check_balance or account_balance >= amount: - g.db.query(User).filter(User.id == self.id).update({ User.marseybux: User.marseybux - amount }) + g.db.query(User).filter(User.id == self.id).update({ User.procoins: User.procoins - amount }) succeeded = True if succeeded: g.db.flush() @@ -261,9 +261,6 @@ class User(Base): if self.is_cakeday: return '/i/hats/Cakeday.webp' - if self.age < 86400 * 7: - return '/i/new-user.webp' - if self.forced_hat: return f'/i/hats/{self.forced_hat[0]}.webp' @@ -280,9 +277,6 @@ class User(Base): if self.is_cakeday: return "I've spent another year rotting my brain with dramaposting, please ridicule me 🤓" - if self.age < 86400 * 7: - return "Hi, I'm new here! Please be gentle :)" - if self.forced_hat: return self.forced_hat[1] @@ -309,7 +303,6 @@ class User(Base): @lazy def mods(self, sub): if self.is_suspended_permanently or self.shadowbanned: return False - if self.id in (AEVANN_ID, SNAKES_ID): return True try: return any(map(lambda x: x.sub == sub, self.sub_mods)) except: @@ -591,7 +584,7 @@ class User(Base): Notification.user_id == self.id, Comment.is_banned == False, Comment.deleted_utc == 0, - not_(and_(Comment.sentto != None, Comment.sentto == MODMAIL_ID, User.is_muted)), + not_(and_(Comment.sentto == MODMAIL_ID, User.is_muted)), )) if not self.can_see_shadowbanned: diff --git a/files/classes/votes.py b/files/classes/votes.py index 024bc1e3d..cfb6b1889 100644 --- a/files/classes/votes.py +++ b/files/classes/votes.py @@ -30,12 +30,12 @@ class Vote(Base): @property @lazy def json(self): - return { - "user_id": self.user_id, - "submission_id": self.submission_id, - "vote_type": self.vote_type, - "user": self.user.json, - } + return {"user_id": self.user_id, + "submission_id":self.submission_id, + "vote_type":self.vote_type, + "user":self.user.json, + "post":self.post.json + } class CommentVote(Base): @@ -61,9 +61,9 @@ class CommentVote(Base): @property @lazy def json(self): - return { - "user_id": self.user_id, - "submission_id": self.submission_id, - "vote_type": self.vote_type, - "user": self.user.json, - } + return {"user_id": self.user_id, + "submission_id":self.submission_id, + "vote_type":self.vote_type, + "user":self.user.json, + "comment":self.comment.json + } diff --git a/files/helpers/actions.py b/files/helpers/actions.py index 472e938e2..f05b4db62 100644 --- a/files/helpers/actions.py +++ b/files/helpers/actions.py @@ -16,17 +16,12 @@ from files.helpers.get import * from files.helpers.sanitize import * from files.helpers.slots import check_slots_command +headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} def _archiveorg(url): - headers = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'} - try: - requests.get(f'https://web.archive.org/save/{url}', - headers=headers, timeout=10, proxies=proxies) - except: pass - try: - requests.post('https://ghostarchive.org/archive2', data={"archive": url}, - headers=headers, timeout=10, proxies=proxies) + try: requests.get(f'https://web.archive.org/save/{url}', headers=headers, timeout=10, proxies=proxies) except: pass + requests.post('https://ghostarchive.org/archive2', data={"archive": url}, headers=headers, timeout=10, proxies=proxies) def archive_url(url): @@ -79,7 +74,7 @@ def execute_snappy(post, v): elif body.startswith('You had your chance. Downvoted and reported'): flag = Flag(post_id=post.id, user_id=SNAPPY_ID, reason='Retard') g.db.add(flag) - elif body.startswith('▲') or body.startswith(':#marseyupvote'): + elif body.startswith('▲'): body = body[1:] vote = Vote(user_id=SNAPPY_ID, vote_type=1, @@ -164,7 +159,7 @@ def execute_snappy(post, v): check_slots_command(v, snappy, c) snappy.comment_count += 1 - snappy.pay_account('coins', 1) + snappy.coins += 1 g.db.add(snappy) if FEATURES['PINS'] and (body.startswith(':#marseypin:') or body.startswith(':#marseypin2:')): @@ -203,7 +198,7 @@ def execute_zozbot(c, level, parent_submission, v): level=level+1, is_bot=True, body="zoz", - body_html='

    zoz

    ', + body_html="

    zoz

    ", top_comment_id=c.top_comment_id, ghost=c.ghost, distinguish_level=6 @@ -220,7 +215,7 @@ def execute_zozbot(c, level, parent_submission, v): level=level+2, is_bot=True, body="zle", - body_html='

    zle

    ', + body_html="

    zle

    ", top_comment_id=c.top_comment_id, ghost=c.ghost, distinguish_level=6 @@ -236,7 +231,7 @@ def execute_zozbot(c, level, parent_submission, v): level=level+3, is_bot=True, body="zozzle", - body_html='

    zozzle

    ', + body_html="

    zozzle

    ", top_comment_id=c.top_comment_id, ghost=c.ghost, distinguish_level=6 @@ -246,7 +241,7 @@ def execute_zozbot(c, level, parent_submission, v): zozbot = get_account(ZOZBOT_ID) zozbot.comment_count += 3 - zozbot.pay_account('coins', 1) + zozbot.coins += 3 g.db.add(zozbot) def execute_longpostbot(c, level, body, body_html, parent_submission, v): @@ -278,7 +273,7 @@ def execute_longpostbot(c, level, body, body_html, parent_submission, v): longpostbot = get_account(LONGPOSTBOT_ID) longpostbot.comment_count += 1 - longpostbot.pay_account('coins', 1) + longpostbot.coins += 1 g.db.add(longpostbot) g.db.flush() n = Notification(comment_id=c2.id, user_id=v.id) diff --git a/files/helpers/assetcache.py b/files/helpers/assetcache.py index 8fdb24f90..ba5061760 100644 --- a/files/helpers/assetcache.py +++ b/files/helpers/assetcache.py @@ -6,7 +6,7 @@ import gevent import gevent_inotifyx as inotify ASSET_DIR = 'files/assets' -ASSET_SUBDIRS = ['/css', '/js', '/js/vendor'] +ASSET_SUBDIRS = ['/css', '/js'] ASSET_URL = '/assets/' ASSET_CACHE = defaultdict(lambda: None) diff --git a/files/helpers/casino.py b/files/helpers/casino.py index 92441e784..7aae15893 100644 --- a/files/helpers/casino.py +++ b/files/helpers/casino.py @@ -23,14 +23,8 @@ def get_game_feed(game, db): return list(map(format_game, games)) -def get_user_stats(u:User, game:str, db:scoped_session, include_ties=False): - games = db.query(Casino_Game.user_id, Casino_Game.winnings).filter(Casino_Game.kind == game, Casino_Game.user_id == u.id) - wins = games.filter(Casino_Game.winnings > 0).count() - ties = games.filter(Casino_Game.winnings == 0).count() if include_ties else 0 - losses = games.filter(Casino_Game.winnings < 0).count() - return (wins, ties, losses) -def get_game_leaderboard(game, db:scoped_session): +def get_game_leaderboard(game, db): timestamp_24h_ago = time.time() - 86400 timestamp_all_time = CASINO_RELEASE_DAY # "All Time" starts on release day diff --git a/files/helpers/const.py b/files/helpers/const.py index d85d5d025..e9de61482 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -58,9 +58,7 @@ DEFAULT_RATELIMIT_USER = DEFAULT_RATELIMIT_SLOWER PUSHER_LIMIT = 1000 # API allows 10 KB but better safe than sorry -IS_LOCALHOST = SITE == "localhost" or SITE == "127.0.0.1" or SITE.startswith("192.168.") or SITE.endswith(".local") - -if IS_LOCALHOST: SITE_FULL = 'http://' + SITE +if SITE == "localhost": SITE_FULL = 'http://' + SITE else: SITE_FULL = 'https://' + SITE @@ -150,8 +148,8 @@ if SITE_NAME == 'rDrama': PROFANITIES = { 'motherfucker': 'motherlover', - 'fuck': 'frick', - ' ass ': ' butt ', + 'fuck': ['frick', 'fudge', 'freak'], + ' ass ': [' butt ', ' backside ', ' bum '], 'shitting': 'pooping', 'lmao': 'lmbo', 'damn': 'darn', @@ -170,7 +168,7 @@ PROFANITIES = { 'penis': 'peepee', 'pussy': 'girl peepee', 'vagina': 'girl peepee', - ' twat ': ' girl peepee ', + ' twat': ' girl peepee', } slur_single_words = "|".join([slur.lower() for slur in SLURS.keys()]) @@ -283,7 +281,7 @@ PERMS = { # Minimum admin_level to perform action. } FEATURES = { - 'MARSEYBUX': True, + 'PROCOINS': True, 'AWARDS': True, 'CHAT': True, 'PINS': True, @@ -304,6 +302,7 @@ FEATURES = { 'PATRON_ICONS': False, 'ASSET_SUBMISSIONS': False, 'STREAMERS': False, + 'HOLIDAY_EVENT': True, } WERKZEUG_ERROR_DESCRIPTIONS = { @@ -642,6 +641,17 @@ COLORS = {'ff66ac','805ad5','62ca56','38a169','80ffff','2a96f3','eb4963','ff0000 BAN_EVASION_DOMAIN = 'rdrama.life' AWARDS = { + ###FALLBACK + "fallback": { + "kind": "fallback", + "title": "", + "description": "", + "icon": "fas fa-circle", + "color": "text-white", + "price": 0, + "deflectable": False, + "cosmetic": False + }, ### Deprecated "ghost": { "kind": "ghost", @@ -1297,7 +1307,7 @@ AWARDS['unpin']['ghost'] = True # Disable unused awards, and site-specific award inclusion/exclusion. AWARDS_DISABLED = [ - 'ghost', 'nword', 'lootbox', # Generic + 'fallback', 'ghost', 'nword', 'lootbox', # Generic 'snow', 'gingerbread', 'lights', 'candycane', 'fireplace', 'grinch', # Fistmas 'haunt', 'upsidedown', 'stab', 'spiders', 'fog', # Homoween '21 'jumpscare', 'hw-bite', 'hw-vax', 'hw-grinch', 'flashlight', # Homoween '22 @@ -1314,8 +1324,7 @@ HOUSE_AWARDS = { "color": "text-purple", "price": 400, "deflectable": True, - "cosmetic": False, - "ghost": False, + "cosmetic": False }, "Femboy": { "kind": "Femboy", @@ -1325,8 +1334,7 @@ HOUSE_AWARDS = { "color": "text-pink", "price": 400, "deflectable": True, - "cosmetic": False, - "ghost": False, + "cosmetic": False }, "Vampire": { "kind": "Vampire", @@ -1336,8 +1344,7 @@ HOUSE_AWARDS = { "color": "text-gray", "price": 400, "deflectable": True, - "cosmetic": False, - "ghost": False, + "cosmetic": False }, "Racist": { "kind": "Racist", @@ -1347,8 +1354,7 @@ HOUSE_AWARDS = { "color": "text-yellow", "price": 400, "deflectable": True, - "cosmetic": False, - "ghost": False, + "cosmetic": False }, } @@ -1368,7 +1374,7 @@ if SITE_NAME == 'PCM': AWARDS_DISABLED.remove('ghost') elif SITE_NAME == 'WPD': AWARDS_DISABLED.remove('lootbox') -if not FEATURES['MARSEYBUX']: +if not FEATURES['PROCOINS']: AWARDS_DISABLED.append('benefactor') AWARDS2 = {x: AWARDS[x] for x in AWARDS if x not in AWARDS_DISABLED} @@ -1424,7 +1430,7 @@ REDDIT_NOTIFS_USERS = {} if len(SITE_NAME) > 5: REDDIT_NOTIFS_SITE.add(SITE_NAME.lower()) -if not IS_LOCALHOST: +if SITE != 'localhost': REDDIT_NOTIFS_SITE.add(SITE) if SITE == 'rdrama.net': @@ -1458,7 +1464,9 @@ discounts = { CF_HEADERS = {"Authorization": f"Bearer {CF_KEY}", "Content-Type": "application/json"} -WORDLE_LIST = ('aaron','about','above','abuse','acids','acres','actor','acute','adams','added','admin','admit','adopt','adult','after','again','agent','aging','agree','ahead','aimed','alarm','album','alert','alias','alice','alien','align','alike','alive','allah','allan','allen','allow','alloy','alone','along','alpha','alter','amber','amend','amino','among','angel','anger','angle','angry','anime','annex','annie','apart','apple','apply','april','areas','arena','argue','arise','armed','armor','array','arrow','aruba','ascii','asian','aside','asked','asset','atlas','audio','audit','autos','avoid','award','aware','awful','babes','bacon','badge','badly','baker','balls','bands','banks','barry','based','bases','basic','basin','basis','batch','baths','beach','beads','beans','bears','beast','beats','began','begin','begun','being','belle','belly','below','belts','bench','berry','betty','bible','bikes','bills','billy','bingo','birds','birth','bitch','black','blade','blair','blake','blame','blank','blast','blend','bless','blind','blink','block','blogs','blond','blood','bloom','blues','board','boats','bobby','bonds','bones','bonus','boobs','books','boost','booth','boots','booty','bored','bound','boxed','boxes','brain','brake','brand','brass','brave','bread','break','breed','brian','brick','bride','brief','bring','broad','broke','brook','brown','bruce','brush','bryan','bucks','buddy','build','built','bunch','bunny','burke','burns','burst','buses','busty','butts','buyer','bytes','cabin','cable','cache','cakes','calif','calls','camel','camps','canal','candy','canon','cards','carey','cargo','carlo','carol','carry','cases','casey','casio','catch','cause','cedar','cells','cents','chain','chair','chaos','charm','chart','chase','cheap','cheat','check','chess','chest','chevy','chick','chief','child','chile','china','chips','choir','chose','chris','chuck','cindy','cisco','cited','civic','civil','claim','clara','clark','class','clean','clear','clerk','click','cliff','climb','clips','clock','clone','close','cloth','cloud','clubs','coach','coast','cocks','codes','cohen','coins','colin','colon','color','combo','comes','comic','condo','congo','const','coral','corps','costa','costs','could','count','court','cover','crack','craft','craig','craps','crash','crazy','cream','creek','crest','crime','crops','cross','crowd','crown','crude','cubic','curve','cyber','cycle','czech','daddy','daily','dairy','daisy','dance','danny','dated','dates','david','davis','deals','dealt','death','debug','debut','decor','delay','delhi','delta','dense','depot','depth','derby','derek','devel','devil','devon','diana','diane','diary','dicke','dicks','diego','diffs','digit','dildo','dirty','disco','discs','disks','dodge','doing','dolls','donna','donor','doors','doubt','dover','dozen','draft','drain','rDrama','drawn','draws','dream','dress','dried','drill','drink','drive','drops','drove','drugs','drums','drunk','dryer','dubai','dutch','dying','dylan','eagle','early','earth','ebony','ebook','eddie','edgar','edges','egypt','eight','elder','elect','elite','ellen','ellis','elvis','emacs','email','emily','empty','ended','endif','enemy','enjoy','enter','entry','epson','equal','error','essay','essex','euros','evans','event','every','exact','exams','excel','exist','extra','faced','faces','facts','fails','fairy','faith','falls','false','fancy','fares','farms','fatal','fatty','fault','favor','fears','feeds','feels','fence','ferry','fever','fewer','fiber','fibre','field','fifth','fifty','fight','filed','files','filme','films','final','finds','fired','fires','firms','first','fixed','fixes','flags','flame','flash','fleet','flesh','float','flood','floor','flour','flows','floyd','fluid','flush','flyer','focal','focus','folks','fonts','foods','force','forge','forms','forth','forty','forum','found','frame','frank','fraud','fresh','front','frost','fruit','fully','funds','funky','funny','fuzzy','gains','games','gamma','gates','gauge','genes','genre','ghana','ghost','giant','gifts','girls','given','gives','glass','glenn','globe','glory','gnome','goals','going','gonna','goods','gotta','grace','grade','grain','grams','grand','grant','graph','grass','grave','great','greek','green','grill','gross','group','grove','grown','grows','guard','guess','guest','guide','guild','hairy','haiti','hands','handy','happy','harry','haven','hayes','heads','heard','heart','heath','heavy','helen','hello','helps','hence','henry','herbs','highs','hills','hindu','hints','hired','hobby','holds','holes','holly','homes','honda','honey','honor','hoped','hopes','horny','horse','hosts','hotel','hours','house','human','humor','icons','idaho','ideal','ideas','image','inbox','index','india','indie','inner','input','intel','inter','intro','iraqi','irish','isaac','islam','issue','italy','items','ivory','jacob','james','jamie','janet','japan','jason','jeans','jenny','jerry','jesse','jesus','jewel','jimmy','johns','joins','joint','jokes','jones','joyce','judge','juice','julia','julie','karen','karma','kathy','katie','keeps','keith','kelly','kenny','kenya','kerry','kevin','kills','kinda','kinds','kings','kitty','klein','knife','knock','known','knows','kodak','korea','label','labor','laden','lakes','lamps','lance','lands','lanes','lanka','large','larry','laser','later','latex','latin','laugh','laura','layer','leads','learn','lease','least','leave','leeds','legal','lemon','leone','level','lewis','lexus','light','liked','likes','limit','linda','lined','lines','links','linux','lions','lists','lived','liver','lives','lloyd','loads','loans','lobby','local','locks','lodge','logan','logic','login','logos','looks','loops','loose','lopez','lotus','louis','loved','lover','loves','lower','lucas','lucia','lucky','lunch','lycos','lying','lyric','macro','magic','mails','maine','major','maker','makes','males','malta','mambo','manga','manor','maple','march','marco','mardi','maria','marie','mario','marks','mason','match','maybe','mayor','mazda','meals','means','meant','medal','media','meets','menus','mercy','merge','merit','merry','metal','meter','metro','meyer','miami','micro','might','milan','miles','milfs','mills','minds','mines','minor','minus','mixed','mixer','model','modem','modes','money','monte','month','moore','moral','moses','motel','motor','mount','mouse','mouth','moved','moves','movie','mpegs','msgid','multi','music','myers','nails','naked','named','names','nancy','nasty','naval','needs','nepal','nerve','never','newer','newly','niger','night','nikon','noble','nodes','noise','nokia','north','noted','notes','notre','novel','nurse','nylon','oasis','occur','ocean','offer','often','older','olive','omaha','omega','onion','opens','opera','orbit','order','organ','oscar','other','ought','outer','owned','owner','oxide','ozone','packs','pages','paint','pairs','panel','panic','pants','paper','papua','paris','parks','parts','party','pasta','paste','patch','paths','patio','paxil','peace','pearl','peers','penis','penny','perry','perth','peter','phase','phone','photo','phpbb','piano','picks','piece','pills','pilot','pipes','pitch','pixel','pizza','place','plain','plane','plans','plant','plate','plays','plaza','plots','poems','point','poker','polar','polls','pools','porno','ports','posts','pound','power','press','price','pride','prime','print','prior','prize','probe','promo','proof','proud','prove','proxy','pulse','pumps','punch','puppy','purse','pussy','qatar','queen','query','quest','queue','quick','quiet','quilt','quite','quote','races','racks','radar','radio','raise','rally','ralph','ranch','randy','range','ranks','rapid','rated','rates','ratio','reach','reads','ready','realm','rebel','refer','rehab','relax','relay','remix','renew','reply','reset','retro','rhode','rider','rides','ridge','right','rings','risks','river','roads','robin','robot','rocks','rocky','roger','roles','rolls','roman','rooms','roots','roses','rouge','rough','round','route','rover','royal','rugby','ruled','rules','rural','safer','sagem','saint','salad','salem','sales','sally','salon','samba','samoa','sandy','santa','sanyo','sarah','satin','sauce','saudi','saved','saver','saves','sbjct','scale','scary','scene','scoop','scope','score','scott','scout','screw','scuba','seats','seeds','seeks','seems','sells','sends','sense','serum','serve','setup','seven','shade','shaft','shake','shall','shame','shape','share','shark','sharp','sheep','sheer','sheet','shelf','shell','shift','shine','ships','shirt','shock','shoes','shoot','shops','shore','short','shots','shown','shows','sides','sight','sigma','signs','silly','simon','since','singh','sites','sixth','sized','sizes','skill','skins','skirt','skype','slave','sleep','slide','slope','slots','sluts','small','smart','smell','smile','smith','smoke','snake','socks','solar','solid','solve','songs','sonic','sorry','sorts','souls','sound','south','space','spain','spank','sparc','spare','speak','specs','speed','spell','spend','spent','sperm','spice','spies','spine','split','spoke','sport','spots','spray','squad','stack','staff','stage','stamp','stand','stars','start','state','stats','stays','steal','steam','steel','steps','steve','stick','still','stock','stone','stood','stops','store','storm','story','strap','strip','stuck','study','stuff','style','sucks','sudan','sugar','suite','suits','sunny','super','surge','susan','sweet','swift','swing','swiss','sword','syria','table','tahoe','taken','takes','tales','talks','tamil','tampa','tanks','tapes','tasks','taste','taxes','teach','teams','tears','teddy','teens','teeth','tells','terms','terry','tests','texas','texts','thank','thats','theft','their','theme','there','these','thick','thing','think','third','thong','those','three','throw','thumb','tiger','tight','tiles','timer','times','tions','tired','tires','title','today','token','tokyo','tommy','toner','tones','tools','tooth','topic','total','touch','tough','tours','tower','towns','toxic','trace','track','tract','tracy','trade','trail','train','trans','trash','treat','trees','trend','trial','tribe','trick','tried','tries','trips','trout','truck','truly','trunk','trust','truth','tubes','tulsa','tumor','tuner','tunes','turbo','turns','tvcom','twice','twiki','twins','twist','tyler','types','ultra','uncle','under','union','units','unity','until','upper','upset','urban','usage','users','using','usual','utils','valid','value','valve','vault','vegas','venue','verde','verse','video','views','villa','vinyl','viral','virus','visit','vista','vital','vocal','voice','volvo','voted','votes','vsnet','wages','wagon','wales','walks','walls','wanna','wants','waste','watch','water','watts','waves','wayne','weeks','weird','wells','welsh','wendy','whale','whats','wheat','wheel','where','which','while','white','whole','whore','whose','wider','width','wiley','winds','wines','wings','wired','wires','witch','wives','woman','women','woods','words','works','world','worry','worse','worst','worth','would','wound','wrist','write','wrong','wrote','xanax','xerox','xhtml','yacht','yahoo','yards','years','yeast','yemen','yield','young','yours','youth','yukon','zones','gypsy','etika','funko','abort','gabby','soros','twink','biden','janny','chapo','4chan','tariq','tweet','trump','bussy','sneed','chink','nigga','wigga','caulk','putin','negus','gussy','soren') +WORDLE_LIST = ('aaron','about','above','abuse','acids','acres','actor','acute','adams','added','admin','admit','adopt','adult','after','again','agent','aging','agree','ahead','aimed','alarm','album','alert','alias','alice','alien','align','alike','alive','allah','allan','allen','allow','alloy','alone','along','alpha','alter','amber','amend','amino','among','angel','anger','angle','angry','anime','annex','annie','apart','apple','apply','april','areas','arena','argue','arise','armed','armor','array','arrow','aruba','ascii','asian','aside','asked','asset','atlas','audio','audit','autos','avoid','award','aware','awful','babes','bacon','badge','badly','baker','balls','bands','banks','barry','based','bases','basic','basin','basis','batch','baths','beach','beads','beans','bears','beast','beats','began','begin','begun','being','belle','belly','below','belts','bench','berry','betty','bible','bikes','bills','billy','bingo','birds','birth','bitch','black','blade','blair','blake','blame','blank','blast','blend','bless','blind','blink','block','blogs','blond','blood','bloom','blues','board','boats','bobby','bonds','bones','bonus','boobs','books','boost','booth','boots','booty','bored','bound','boxed','boxes','brain','brake','brand','brass','brave','bread','break','breed','brian','brick','bride','brief','bring','broad','broke','brook','brown','bruce','brush','bryan','bucks','buddy','build','built','bunch','bunny','burke','burns','burst','buses','busty','butts','buyer','bytes','cabin','cable','cache','cakes','calif','calls','camel','camps','canal','candy','canon','cards','carey','cargo','carlo','carol','carry','cases','casey','casio','catch','cause','cedar','cells','cents','chain','chair','chaos','charm','chart','chase','cheap','cheat','check','chess','chest','chevy','chick','chief','child','chile','china','chips','choir','chose','chris','chuck','cindy','cisco','cited','civic','civil','claim','clara','clark','class','clean','clear','clerk','click','cliff','climb','clips','clock','clone','close','cloth','cloud','clubs','coach','coast','cocks','codes','cohen','coins','colin','colon','color','combo','comes','comic','condo','congo','const','coral','corps','costa','costs','could','count','court','cover','crack','craft','craig','craps','crash','crazy','cream','creek','crest','crime','crops','cross','crowd','crown','crude','cubic','curve','cyber','cycle','czech','daddy','daily','dairy','daisy','dance','danny','dated','dates','david','davis','deals','dealt','death','debug','debut','decor','delay','delhi','delta','dense','depot','depth','derby','derek','devel','devil','devon','diana','diane','diary','dicke','dicks','diego','diffs','digit','dildo','dirty','disco','discs','disks','dodge','doing','dolls','donna','donor','doors','doubt','dover','dozen','draft','drain','rDrama','drawn','draws','dream','dress','dried','drill','drink','drive','drops','drove','drugs','drums','drunk','dryer','dubai','dutch','dying','dylan','eagle','early','earth','ebony','ebook','eddie','edgar','edges','egypt','eight','elder','elect','elite','ellen','ellis','elvis','emacs','email','emily','empty','ended','endif','enemy','enjoy','enter','entry','epson','equal','error','essay','essex','euros','evans','event','every','exact','exams','excel','exist','extra','faced','faces','facts','fails','fairy','faith','falls','false','fancy','fares','farms','fatal','fatty','fault','favor','fears','feeds','feels','fence','ferry','fever','fewer','fiber','fibre','field','fifth','fifty','fight','filed','files','filme','films','final','finds','fired','fires','firms','first','fixed','fixes','flags','flame','flash','fleet','flesh','float','flood','floor','flour','flows','floyd','fluid','flush','flyer','focal','focus','folks','fonts','foods','force','forge','forms','forth','forty','forum','found','frame','frank','fraud','fresh','front','frost','fruit','fully','funds','funky','funny','fuzzy','gains','games','gamma','gates','gauge','genes','genre','ghana','ghost','giant','gifts','girls','given','gives','glass','glenn','globe','glory','gnome','goals','going','gonna','goods','gotta','grace','grade','grain', +'grams','grand','grant','graph','grass','grave','great','greek','green','grill','gross','group','grove','grown','grows','guard','guess','guest','guide','guild','hairy','haiti','hands','handy','happy','harry','haven','hayes','heads','heard','heart','heath','heavy','helen','hello','helps','hence','henry','herbs','highs','hills','hindu','hints','hired','hobby','holds','holes','holly','homes','honda','honey','honor','hoped','hopes','horny','horse','hosts','hotel','hours','house','human','humor','icons','idaho','ideal','ideas','image','inbox','index','india','indie','inner','input','intel','inter','intro','iraqi','irish','isaac','islam','issue','italy','items','ivory','jacob','james','jamie','janet','japan','jason','jeans','jenny','jerry','jesse','jesus','jewel','jimmy','johns','joins','joint','jokes','jones','joyce','judge','juice','julia','julie','karen','karma','kathy','katie','keeps','keith','kelly','kenny','kenya','kerry','kevin','kills','kinda','kinds','kings','kitty','klein','knife','knock','known','knows','kodak','korea','label','labor','laden','lakes','lamps','lance','lands','lanes','lanka','large','larry','laser','later','latex','latin','laugh','laura','layer','leads','learn','lease','least','leave','leeds','legal','lemon','leone','level','lewis','lexus','light','liked','likes','limit','linda','lined','lines','links','linux','lions','lists','lived','liver','lives','lloyd','loads','loans','lobby','local','locks','lodge','logan','logic','login','logos','looks','loops','loose','lopez','lotus','louis','loved','lover','loves','lower','lucas','lucia','lucky','lunch','lycos','lying','lyric','macro','magic','mails','maine','major','maker','makes','males','malta','mambo','manga','manor','maple','march','marco','mardi','maria','marie','mario','marks','mason','match','maybe','mayor','mazda','meals','means','meant','medal','media','meets','menus','mercy','merge','merit','merry','metal','meter','metro','meyer','miami','micro','might','milan','miles','milfs','mills','minds','mines','minor','minus','mixed','mixer','model','modem','modes','money','monte','month','moore','moral','moses','motel','motor','mount','mouse','mouth','moved','moves','movie','mpegs','msgid','multi','music','myers','nails','naked','named','names','nancy','nasty','naval','needs','nepal','nerve','never','newer','newly','niger','night','nikon','noble','nodes','noise','nokia','north','noted','notes','notre','novel','nurse','nylon','oasis','occur','ocean','offer','often','older','olive','omaha','omega','onion','opens','opera','orbit','order','organ','oscar','other','ought','outer','owned','owner','oxide','ozone','packs','pages','paint','pairs','panel','panic','pants','paper','papua','paris','parks','parts','party','pasta','paste','patch','paths','patio','paxil','peace','pearl','peers','penis','penny','perry','perth','peter','phase','phone','photo','phpbb','piano','picks','piece','pills','pilot','pipes','pitch','pixel','pizza','place','plain','plane','plans','plant','plate','plays','plaza','plots','poems','point','poker','polar','polls','pools','porno','ports','posts','pound','power','press','price','pride','prime','print','prior','prize','probe','promo','proof','proud','prove','proxy','pulse','pumps','punch','puppy','purse','pussy','qatar','queen','query','quest','queue','quick','quiet','quilt','quite','quote','races','racks','radar','radio','raise','rally','ralph','ranch','randy','range','ranks','rapid','rated','rates','ratio','reach','reads','ready','realm','rebel','refer','rehab','relax','relay','remix','renew','reply','reset','retro','rhode','rider','rides','ridge','right','rings','risks','river','roads','robin','robot','rocks','rocky','roger','roles','rolls','roman','rooms','roots','roses','rouge','rough','round','route','rover','royal','rugby','ruled','rules','rural','safer','sagem','saint','salad','salem','sales','sally','salon','samba','samoa','sandy','santa','sanyo','sarah','satin','sauce','saudi','saved','saver','saves','sbjct','scale','scary','scene','scoop','scope','score','scott','scout','screw','scuba','seats','seeds','seeks','seems','sells','sends', +'sense','serum','serve','setup','seven','shade','shaft','shake','shall','shame','shape','share','shark','sharp','sheep','sheer','sheet','shelf','shell','shift','shine','ships','shirt','shock','shoes','shoot','shops','shore','short','shots','shown','shows','sides','sight','sigma','signs','silly','simon','since','singh','sites','sixth','sized','sizes','skill','skins','skirt','skype','slave','sleep','slide','slope','slots','sluts','small','smart','smell','smile','smith','smoke','snake','socks','solar','solid','solve','songs','sonic','sorry','sorts','souls','sound','south','space','spain','spank','sparc','spare','speak','specs','speed','spell','spend','spent','sperm','spice','spies','spine','split','spoke','sport','spots','spray','squad','stack','staff','stage','stamp','stand','stars','start','state','stats','stays','steal','steam','steel','steps','steve','stick','still','stock','stone','stood','stops','store','storm','story','strap','strip','stuck','study','stuff','style','sucks','sudan','sugar','suite','suits','sunny','super','surge','susan','sweet','swift','swing','swiss','sword','syria','table','tahoe','taken','takes','tales','talks','tamil','tampa','tanks','tapes','tasks','taste','taxes','teach','teams','tears','teddy','teens','teeth','tells','terms','terry','tests','texas','texts','thank','thats','theft','their','theme','there','these','thick','thing','think','third','thong','those','three','throw','thumb','tiger','tight','tiles','timer','times','tions','tired','tires','title','today','token','tokyo','tommy','toner','tones','tools','tooth','topic','total','touch','tough','tours','tower','towns','toxic','trace','track','tract','tracy','trade','trail','train','trans','trash','treat','trees','trend','trial','tribe','trick','tried','tries','trips','trout','truck','truly','trunk','trust','truth','tubes','tulsa','tumor','tuner','tunes','turbo','turns','tvcom','twice','twiki','twins','twist','tyler','types','ultra','uncle','under','union','units','unity','until','upper','upset','urban','usage','users','using','usual','utils','valid','value','valve','vault','vegas','venue','verde','verse','video','views','villa','vinyl','viral','virus','visit','vista','vital','vocal','voice','volvo','voted','votes','vsnet','wages','wagon','wales','walks','walls','wanna','wants','waste','watch','water','watts','waves','wayne','weeks','weird','wells','welsh','wendy','whale','whats','wheat','wheel','where','which','while','white','whole','whore','whose','wider','width','wiley','winds','wines','wings','wired','wires','witch','wives','woman','women','woods','words','works','world','worry','worse','worst','worth','would','wound','wrist','write','wrong','wrote','xanax','xerox','xhtml','yacht','yahoo','yards','years','yeast','yemen','yield','young','yours','youth','yukon','zones','gypsy','etika','funko','abort','gabby','soros','twink','biden','janny','chapo','4chan','tariq','tweet','trump','bussy','sneed','chink','nigga','wigga','caulk','putin','negus','gussy','soren') christian_emojis = [':#marseyjesus:',':#marseyimmaculate:',':#marseymothermary:', ':#marseyfatherjoseph:',':#gigachadorthodox:',':#marseyorthodox:',':#marseyorthodoxpat:', @@ -1475,7 +1483,6 @@ approved_embed_hosts = { BAN_EVASION_DOMAIN, 'pcmemes.net', 'watchpeopledie.tv', - 'fsdfsd.net', 'imgur.com', 'lain.la', 'pngfind.com', @@ -1567,6 +1574,7 @@ tiers={ has_sidebar = path.exists(f'files/templates/sidebar_{SITE_NAME}.html') has_logo = path.exists(f'files/assets/images/{SITE_NAME}/logo.webp') +has_app = path.exists(f'files/assets/app_{SITE_NAME}_v2.7.apk') ONLINE_STR = f'{SITE}_online' @@ -1609,18 +1617,23 @@ if SITE_NAME == 'rDrama': 'givesendgo.com', 'thepinkpill.com', 'ovarit.com', + 'rdrama.cc', 'lolcow.farm', 'truthsocial.com', 'rumble.com', 'saidit.net', + 'kiwifarms.cc', '8kun.top', 'goyimtv.tv', 'poal.co', 'stormfront.org', 'arete.network', + 'poa.st', 'lbry.com', 'crystal.cafe', 'tribel.com', + 'mstdn.social', + 'mastodon.online', 'steemit.com', 'hexbear.net', 'raddle.me', @@ -1645,29 +1658,19 @@ if SITE_NAME == 'rDrama': 'resetera.com', 'steamcommunity.com', 'nairaland.com', + 'marsey.club', 'odysee.com', 'trp.red', 'forums.red', + 'shitposter.club', + 'sneed.social', + 'seal.cafe', 'lobste.rs', 'stacker.news', 'breitbart.com', 'tattle.life', 'wolfballs.com', 'backloggd.com', - 'tildes.net', - 'blacktwitterapp.com', - - #fediverse - 'rdrama.cc', - 'marsey.club', - 'kiwifarms.cc', - 'freespeechextremist.com' - 'mstdn.social', - 'mastodon.online', - 'poa.st', - 'shitposter.club', - 'sneed.social', - 'seal.cafe', } BOOSTED_HOLES = { @@ -1688,12 +1691,10 @@ if SITE_NAME == 'rDrama': 2008, #TransGirlTradWife } - BOOSTED_USERS_EXCLUDED = {8768, 5214, 12719, 3402} - IMAGE_FORMATS = ['png','gif','jpg','jpeg','webp'] VIDEO_FORMATS = ['mp4','webm','mov','avi','mkv','flv','m4v','3gp'] AUDIO_FORMATS = ['mp3','wav','ogg','aac','m4a','flac'] -if not IS_LOCALHOST and SECRET_KEY == DEFAULT_CONFIG_VALUE: +if SECRET_KEY == DEFAULT_CONFIG_VALUE: from warnings import warn warn("Secret key is the default value! Please change it to a secure random number. Thanks <3", RuntimeWarning) diff --git a/files/helpers/cron.py b/files/helpers/cron.py index 687b9b316..6ecf39345 100644 --- a/files/helpers/cron.py +++ b/files/helpers/cron.py @@ -91,7 +91,6 @@ def _sub_inactive_purge_task(): posts = g.db.query(Submission).filter(Submission.sub.in_(names)).all() for post in posts: post.sub = None - post.hole_pinned = None g.db.add(post) to_delete = mods \ @@ -119,10 +118,10 @@ def _give_monthly_marseybux_task(): emails = [x['email'] for x in requests.get(f'https://api.gumroad.com/v2/products/{GUMROAD_ID}/subscribers', data=data, timeout=5).json()["subscribers"]] - def give_marseybux(u): - marseybux_reward = marseybux_li[u.patron] - u.pay_account('marseybux', marseybux_reward) - send_repeatable_notification(u.id, f"@AutoJanny has given you {marseybux_reward} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).") + def give_procoins(u): + procoins = procoins_li[u.patron] + u.procoins += procoins + send_repeatable_notification(u.id, f"@AutoJanny has given you {procoins} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).") for badge in g.db.query(Badge).filter(Badge.badge_id > 20, Badge.badge_id < 28).all(): g.db.delete(badge) @@ -130,7 +129,7 @@ def _give_monthly_marseybux_task(): for u in g.db.query(User).filter(User.patron > 0, User.patron_utc == 0).all(): g.db.add(u) if u.admin_level or u.id in GUMROAD_MESSY: - give_marseybux(u) + give_procoins(u) elif u.email and u.is_activated and u.email.lower() in emails: data = {'access_token': GUMROAD_TOKEN, 'email': u.email} try: @@ -147,7 +146,7 @@ def _give_monthly_marseybux_task(): tier = tiers[response["variants_and_quantity"]] u.patron = tier badge_grant(badge_id=20+tier, user=u, notify=False) - give_marseybux(u) + give_procoins(u) else: u.patron = 0 @@ -173,9 +172,9 @@ def _give_monthly_marseybux_task_kofi(): u.patron = 0 continue - marseybux_reward = marseybux_li[u.patron] - u.pay_account('marseybux', marseybux_reward) - send_repeatable_notification(u.id, f"@AutoJanny has given you {marseybux_reward} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).") + procoins = procoins_li[u.patron] + u.procoins += procoins + send_repeatable_notification(u.id, f"@AutoJanny has given you {procoins} Marseybux for the month of {month}! You can use them to buy awards in the [shop](/shop).") ma = ModAction( kind="monthly", diff --git a/files/helpers/lottery.py b/files/helpers/lottery.py index 8c70e95d2..5cf680b23 100644 --- a/files/helpers/lottery.py +++ b/files/helpers/lottery.py @@ -48,7 +48,7 @@ def end_lottery_session(): winner = choice(raffle) active_lottery.winner_id = winner winning_user = next(filter(lambda x: x.id == winner, participating_users)) - winning_user.pay_account('coins', active_lottery.prize) + winning_user.coins += active_lottery.prize winning_user.total_lottery_winnings += active_lottery.prize badge_grant(user=winning_user, badge_id=LOTTERY_WINNER_BADGE_ID) @@ -65,10 +65,6 @@ def end_lottery_session(): active_lottery.is_active = False - g.db.add(winning_user) - g.db.add(active_lottery) - g.db.commit() # Intentionally commit early because cron runs with other tasks - return True, f'{winning_user.username} won {active_lottery.prize} coins!' @@ -84,7 +80,6 @@ def start_new_lottery_session(): lottery.is_active = True g.db.add(lottery) - g.db.commit() # Intentionally commit early, not autocommitted from cron def check_if_end_lottery_task(): diff --git a/files/helpers/media.py b/files/helpers/media.py index 8c4eb2e07..5e68cbd1e 100644 --- a/files/helpers/media.py +++ b/files/helpers/media.py @@ -69,6 +69,7 @@ def webm_to_mp4(old, new, vid, db): subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-nostats", "-threads:v", "1", "-i", old, "-map_metadata", "-1", tmp], check=True, stderr=subprocess.STDOUT) os.replace(tmp, new) os.remove(old) + purge_files_in_cache(f"{SITE_FULL}{new}") media = db.query(Media).filter_by(filename=new, kind='video').one_or_none() if media: db.delete(media) @@ -83,9 +84,6 @@ def webm_to_mp4(old, new, vid, db): db.commit() db.close() - purge_files_in_cache(f"{SITE_FULL}{new}") - - def process_video(file, v): old = f'/videos/{time.time()}'.replace('.','') @@ -142,9 +140,7 @@ def process_image(filename:str, v, resize=0, trim=False, uploader_id:Optional[in try: with Image.open(filename) as i: - params = ["magick", filename, "-strip", "-auto-orient"] - if i.format.lower() != 'webp': - params.extend(["-coalesce", "-quality", "88", "-define", "webp:method=5"]) + params = ["convert", "-coalesce", filename, "-quality", "88", "-define", "webp:method=5", "-strip", "-auto-orient"] if trim and len(list(Iterator(i))) == 1: params.append("-trim") if resize and i.width > resize: diff --git a/files/helpers/offsitementions.py b/files/helpers/offsitementions.py index 701ca6979..b4a236c4c 100644 --- a/files/helpers/offsitementions.py +++ b/files/helpers/offsitementions.py @@ -23,10 +23,7 @@ from files.helpers.sanitize import sanitize def offsite_mentions_task(cache:Cache): if const.REDDIT_NOTIFS_SITE: row_send_to = g.db.query(Badge.user_id).filter_by(badge_id=140).all() - row_send_to += g.db.query(User.id).filter( - User.admin_level >= const.PERMS['NOTIFICATIONS_REDDIT'], - User.id != const.AEVANN_ID, - ).all() + row_send_to += g.db.query(User.id).filter(or_(User.admin_level >= const.PERMS['NOTIFICATIONS_REDDIT'])).all() send_to = [x[0] for x in row_send_to] send_to = set(send_to) @@ -52,12 +49,7 @@ def get_mentions(cache:Cache, queries:Iterable[str], reddit_notifs_users=False): size = 1 if reddit_notifs_users else 100 for kind in kinds: try: - data = requests.get(( - f'https://api.pushshift.io/reddit/{kind}/search?html_decode=true' - f'&q={"%7C".join(queries)}' - f'&subreddit=!{",!".join(exclude_subreddits)}' - f'&after={after}' - f'&size={size}'), timeout=15).json()['data'] + data = requests.get(f'https://api.pushshift.io/reddit/{kind}/search?html_decode=true&q={"%7C".join(queries)}&subreddit=!{",!".join(exclude_subreddits)}&after={after}&size={size}', timeout=15).json()['data'] except: continue @@ -96,14 +88,8 @@ def notify_mentions(send_to, mentions, mention_str='site mention'): author = m['author'] permalink = m['permalink'] text = sanitize(m['text'], golden=False) - notif_text = ( - f'

    New {mention_str} by /u/{author}

    ' - f'

    ' - f'https://old.reddit.com{permalink}?context=89

    ' - f'{text}' - ) + notif_text = \ + f"""

    New {mention_str} by /u/{author}

    https://old.reddit.com{permalink}?context=89

    {text}""" existing_comment = g.db.query(Comment.id).filter_by( author_id=const.AUTOJANNY_ID, diff --git a/files/helpers/regex.py b/files/helpers/regex.py index a36860477..32dfb5778 100644 --- a/files/helpers/regex.py +++ b/files/helpers/regex.py @@ -92,7 +92,7 @@ link_fix_regex = re.compile("(\[.*?\]\()(?!http|/)(.*?\))", flags=re.A) css_url_regex = re.compile('url\(\s*[\'"]?(.*?)[\'"]?\s*\)', flags=re.I|re.A) -marseybux_li = (0,2500,5000,10000,25000,50000,100000,250000) +procoins_li = (0,2500,5000,10000,25000,50000,100000,250000) linefeeds_regex = re.compile("([^\n])\n([^\n])", flags=re.A) @@ -126,6 +126,8 @@ def sub_matcher(match:re.Match, upper=False, replace_with:Union[dict[str, str], return match_str else: repl = replace_with[match_str.lower()] + if not isinstance(repl, str): + repl = random.choice(repl) return repl if not upper or "= 0 and x <= 37 - if self == self.__class__.LINE_BET: return lambda x: x in LINES - if self == self.__class__.COLUMN_BET: return lambda x: x in COLUMNS - if self == self.__class__.DOZEN_BET: return lambda x: x in DOZENS - if self == self.__class__.EVEN_ODD_BET: return lambda x: x in [y.value for y in RouletteEvenOdd] - if self == self.__class__.RED_BLACK_BET: return lambda x: x in [y.value for y in RouletteRedBlack] - if self == self.__class__.HIGH_LOW_BET: return lambda x: x in [y.value for y in RouletteHighLow] - raise ValueError("Unhandled validation function for RouletteAction") - class RouletteEvenOdd(str, Enum): EVEN = "EVEN" @@ -167,7 +156,12 @@ def spin_roulette_wheel(): if len(participants) > 0: number = randint(0, 37) # 37 is 00 - winners, payouts, rewards_by_game_id = determine_roulette_winners(number, bets) + if number > 0 and number < 37: # 0 and 00 do not pay anything + winners, payouts, rewards_by_game_id = determine_roulette_winners(number, bets) + else: + winners = [] + payouts = {} + rewards_by_game_id = {} if number == 37: number = '00' @@ -176,10 +170,10 @@ def spin_roulette_wheel(): gambler = get_account(user_id) gambler_payout = payouts[user_id] coin_winnings = gambler_payout['coins'] - procoin_winnings = gambler_payout['marseybux'] + procoin_winnings = gambler_payout['procoins'] gambler.pay_account('coins', coin_winnings) - gambler.pay_account('marseybux', procoin_winnings) + gambler.pay_account('procoins', procoin_winnings) # Notify the winners. notification_text = f"Winning number: {number}\nCongratulations! One or more of your roulette bets paid off!\n" @@ -236,7 +230,7 @@ def determine_roulette_winners(number, bets): if not payouts.get(gambler_id): payouts[gambler_id] = { 'coins': 0, - 'marseybux': 0 + 'procoins': 0 } if not rewards_by_game_id.get(game_id): @@ -249,10 +243,6 @@ def determine_roulette_winners(number, bets): if int(bet['which']) == number: add_to_winnings(bet) - if number == 0 or number == 37: - return winners, payouts, rewards_by_game_id - - # Line Bet line = -1 for i in range(1, 7): diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 21b3315f5..3cb7fb2bf 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -38,7 +38,7 @@ TLDS = ( # Original gTLDs and ccTLDs # New gTLDs 'app','cleaning','club','dev','farm','florist','fun','gay','lgbt','life','lol', 'moe','mom','monster','new','news','online','pics','press','pub','site', - 'vip','win','world','wtf','xyz','video','host','art', + 'vip','win','world','wtf','xyz', 'video', ) allowed_tags = ('b','blockquote','br','code','del','em','h1','h2','h3','h4','h5','h6','hr','i', @@ -362,9 +362,7 @@ def sanitize(sanitized, golden=True, limit_pings=0, showmore=True, count_marseys if isinstance(t, str): t = t.replace('s','') htmlsource = f'{i.group(1)}' sanitized = sanitized.replace(i.group(0), htmlsource) diff --git a/files/helpers/slots.py b/files/helpers/slots.py index 651e01a39..d78df5c4e 100644 --- a/files/helpers/slots.py +++ b/files/helpers/slots.py @@ -126,7 +126,7 @@ def check_slots_command(v:User, u:User, c:Comment): if '!slotsmb' in body: command_word = '!slotsmb' - currency = 'marseybux' + currency = 'procoins' elif '!slots' in body: command_word = '!slots' currency = 'coins' @@ -151,7 +151,7 @@ def check_slots_command(v:User, u:User, c:Comment): abort(400, f"Wager must be 100 {currency} or more") return - if (currency == "coins" and wager > u.coins) or (currency == "marseybux" and wager > u.marseybux): + if (currency == "coins" and wager > u.coins) or (currency == "procoins" and wager > u.procoins): if v.id == u.id: abort(400, f"Not enough {currency} to make that bet") return diff --git a/files/helpers/treasure.py b/files/helpers/treasure.py index 6bf4a7099..b8aee95d6 100644 --- a/files/helpers/treasure.py +++ b/files/helpers/treasure.py @@ -42,5 +42,6 @@ def check_for_treasure(in_text, from_comment): from_comment.treasure_amount = f'l{ticket_count}' return - user.pay_account('coins', amount) + + user.coins += amount from_comment.treasure_amount = str(amount) diff --git a/files/routes/admin.py b/files/routes/admin.py index 3be5fb03e..2ce248bdc 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -24,7 +24,7 @@ from .front import frontlist def kippy(v): if SITE != 'pcmemes.net': abort(404) kippy = get_account(KIPPY_ID) - kippy.pay_account('marseybux', 10000) + kippy.procoins += 10000 g.db.add(kippy) return '10k marseybux printed!' @@ -88,7 +88,7 @@ def merge(v, id1, id2): g.db.add(exile) g.db.flush() - for kind in ('comment_count', 'post_count', 'winnings', 'received_award_count', 'coins_spent', 'lootboxes_bought', 'coins', 'truescore', 'marseybux'): + for kind in ('comment_count', 'post_count', 'winnings', 'received_award_count', 'coins_spent', 'lootboxes_bought', 'coins', 'truescore', 'procoins'): amount = getattr(user1, kind) + getattr(user2, kind) setattr(user1, kind, amount) setattr(user2, kind, 0) @@ -138,7 +138,7 @@ def merge_all(v, id): g.db.flush() for alt in user.alts_unique: - for kind in ('comment_count', 'post_count', 'winnings', 'received_award_count', 'coins_spent', 'lootboxes_bought', 'coins', 'truescore', 'marseybux'): + for kind in ('comment_count', 'post_count', 'winnings', 'received_award_count', 'coins_spent', 'lootboxes_bought', 'coins', 'truescore', 'procoins'): amount = getattr(user, kind) + getattr(alt, kind) setattr(user, kind, amount) setattr(alt, kind, 0) @@ -224,7 +224,7 @@ def distribute(v, option_id): cid = notif_comment(f"You won {coinsperperson} coins betting on [{post.title}]({post.shortlink}) :marseyparty:") for vote in votes: u = vote.user - u.pay_account('coins', coinsperperson) + u.coins += coinsperperson add_notif(cid, u.id) @@ -449,8 +449,8 @@ def admin_git_head(): with open('.git/' + head_path, encoding='utf_8') as ref_f: gitref = ref_f.read()[0:short_len] except: - return '', '' - return (gitref, head_txt) + return '' + return gitref @app.post("/admin/site_settings/") @admin_level_required(PERMS['SITE_SETTINGS']) @@ -619,7 +619,6 @@ def users_list(v): users=users, next_exists=next_exists, page=page, - user_cards_title="Users Feed", ) @@ -880,7 +879,13 @@ def shadowban(user_id, v): reason = request.values.get("reason").strip()[:256] user.ban_reason = reason g.db.add(user) - check_for_alts(user, False) + + if request.values.get("alts"): + for alt in user.alts: + if alt.admin_level: continue + alt.shadowbanned = v.username + alt.ban_reason = reason + g.db.add(alt) ma = ModAction( kind="shadowban", @@ -1098,7 +1103,7 @@ def unban_user(user_id, v): if not user.is_banned: abort(400) - if FEATURES['AWARDS'] and user.ban_reason and user.ban_reason.startswith('1-Day ban award'): + if FEATURES["AWARDS"] and user.ban_reason and user.ban_reason.startswith('1-Day ban award'): abort(403, "You can't undo a ban award!") user.is_banned = 0 @@ -1168,7 +1173,7 @@ def remove_post(post_id, v): post = get_post(post_id) post.is_banned = True post.is_approved = None - if not FEATURES['AWARDS'] or not post.stickied or not post.stickied.endswith(PIN_AWARD_TEXT): + if FEATURES["AWARDS"] and post.stickied and not post.stickied.endswith(PIN_AWARD_TEXT): post.stickied = None post.is_pinned = False post.ban_reason = v.username @@ -1183,7 +1188,7 @@ def remove_post(post_id, v): cache.delete_memoized(frontlist) - v.pay_account('coins', 1) + v.coins += 1 g.db.add(v) purge_files_in_cache(f"https://{SITE}/") return {"message": "Post removed!"} @@ -1252,23 +1257,24 @@ def distinguish_post(post_id, v): def sticky_post(post_id, v): post = get_post(post_id) if post.is_banned: abort(403, "Can't sticky removed posts!") - if FEATURES['AWARDS'] and post.stickied and post.stickied.endswith(PIN_AWARD_TEXT): + if FEATURES["AWARDS"] and post.stickied and post.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't pin award pins!") pins = g.db.query(Submission).filter(Submission.stickied != None, Submission.is_banned == False).count() + extra_pin_slots = 1 if post.stickied else 0 + sticky_time = int(time.time()) + 3600 if not post.stickied else None + + if pins >= PIN_LIMIT + extra_pin_slots and not sticky_time: + abort(403, f"Can't exceed {PIN_LIMIT} pinned posts limit!") if not post.stickied_utc: - post.stickied_utc = int(time.time()) + 3600 + post.stickied_utc = sticky_time pin_time = 'for 1 hour' - code = 200 if v.id != post.author_id: send_repeatable_notification(post.author_id, f"@{v.username} (Admin) has pinned [{post.title}](/post/{post_id})!") else: - if pins >= PIN_LIMIT + 1: - abort(403, f"Can't exceed {PIN_LIMIT} pinned posts limit!") - post.stickied_utc = None + post.stickied_utc = sticky_time pin_time = 'permanently' - code = 201 post.stickied = v.username @@ -1284,15 +1290,14 @@ def sticky_post(post_id, v): cache.delete_memoized(frontlist) - return {"message": f"Post pinned {pin_time}!"}, code - + return {"message": f"Post pinned {pin_time}!", "length": pin_time}, 201 @app.post("/unsticky/") @admin_level_required(PERMS['POST_COMMENT_MODERATION']) def unsticky_post(post_id, v): post = get_post(post_id) if post.stickied: - if FEATURES['AWARDS'] and post.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!") + if FEATURES["AWARDS"] and post.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!") if post.author_id == LAWLZ_ID and post.stickied_utc and SITE_NAME == 'rDrama': abort(403, "Can't unpin lawlzposts!") post.stickied = None @@ -1315,6 +1320,7 @@ def unsticky_post(post_id, v): @app.post("/sticky_comment/") @admin_level_required(PERMS['POST_COMMENT_MODERATION']) def sticky_comment(cid, v): + comment = get_comment(cid, v=v) if not comment.stickied: @@ -1341,7 +1347,7 @@ def unsticky_comment(cid, v): comment = get_comment(cid, v=v) if comment.stickied: - if FEATURES['AWARDS'] and comment.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!") + if FEATURES["AWARDS"] and comment.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!") comment.stickied = None g.db.add(comment) @@ -1384,7 +1390,9 @@ def remove_comment(c_id, v): @limiter.limit(DEFAULT_RATELIMIT_SLOWER) @admin_level_required(PERMS['POST_COMMENT_MODERATION']) def approve_comment(c_id, v): + comment = get_comment(c_id) + if not comment: abort(404) if comment.author.id == v.id and comment.author.agendaposter and AGENDAPOSTER_PHRASE not in comment.body.lower() and comment.post.sub != 'chudrama': abort(400, "You can't bypass the chud award!") @@ -1409,6 +1417,8 @@ def approve_comment(c_id, v): @app.post("/distinguish_comment/") @admin_level_required(PERMS['POST_COMMENT_DISTINGUISH']) def admin_distinguish_comment(c_id, v): + + comment = get_comment(c_id, v=v) if comment.distinguish_level: diff --git a/files/routes/allroutes.py b/files/routes/allroutes.py index 6f19c5e9b..fece39fc0 100644 --- a/files/routes/allroutes.py +++ b/files/routes/allroutes.py @@ -1,3 +1,4 @@ +import secrets from files.helpers.const import * from files.helpers.settings import get_setting from files.helpers.cloudflare import CLOUDFLARE_AVAILABLE @@ -25,41 +26,29 @@ def before_request(): g.db = db_session() g.webview = '; wv) ' in ua - - if ' firefox/' in ua: - g.type = 'firefox' - g.inferior_browser = True - elif 'iphone' in ua or 'ipad' in ua or 'ipod' in ua or 'mac os' in ua: - g.type = 'apple' - g.inferior_browser = True - else: - g.type = 'chromium' - g.inferior_browser = False - + g.inferior_browser = 'iphone' in ua or 'ipad' in ua or 'ipod' in ua or 'mac os' in ua or ' firefox/' in ua g.is_tor = request.headers.get("cf-ipcountry") == "T1" request.path = request.path.rstrip('/') if not request.path: request.path = '/' request.full_path = request.full_path.rstrip('?').rstrip('/') if not request.full_path: request.full_path = '/' - - session_init() - + if not session.get("session_id"): + session.permanent = True + session["session_id"] = secrets.token_hex(49) @app.after_request def after_request(response): if response.status_code < 400: if CLOUDFLARE_AVAILABLE and CLOUDFLARE_COOKIE_VALUE and getattr(g, 'desires_auth', False): logged_in = bool(getattr(g, 'v', None)) - response.set_cookie("lo", CLOUDFLARE_COOKIE_VALUE if logged_in else '', - max_age=60*60*24*365 if logged_in else 1, samesite="Lax") + response.set_cookie("lo", CLOUDFLARE_COOKIE_VALUE if logged_in else '', max_age=60*60*24*365 if logged_in else 1) if getattr(g, 'db', None): g.db.commit() g.db.close() del g.db return response - @app.teardown_appcontext def teardown_request(error): if getattr(g, 'db', None): diff --git a/files/routes/asset_submissions.py b/files/routes/asset_submissions.py index 620cf1348..54fbdadbc 100644 --- a/files/routes/asset_submissions.py +++ b/files/routes/asset_submissions.py @@ -153,7 +153,7 @@ def approve_marsey(v, name): new_path = f'/asset_submissions/marseys/original/{name}.{i.format.lower()}' rename(highquality, new_path) - author.pay_account('coins', 250) + author.coins += 250 g.db.add(author) if v.id != author.id: @@ -264,7 +264,6 @@ def submit_hat(v): @app.post("/admin/approve/hat/") -@limiter.limit("3/second;120/minute;200/hour;1000/day") @admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_HATS']) def approve_hat(v, name): hat = verify_permissions_and_get_asset(HatDef, "hat", v, name, False) diff --git a/files/routes/awards.py b/files/routes/awards.py index 6b3a18d9f..df87f7811 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -68,7 +68,7 @@ def buy(v, award): if award == "grass": abort(403, "You can't buy the grass award with marseybux.") - charged = v.charge_account('marseybux', price) + charged = v.charge_account('procoins', price) if not charged: abort(400, "Not enough marseybux.") else: @@ -163,7 +163,7 @@ def award_thing(v, thing_type, id): note = request.values.get("note", "").strip() - if SITE == 'rdrama.net' and author.id in (PIZZASHILL_ID, CARP_ID) and v.id not in (AEVANN_ID, SNAKES_ID): + if SITE == 'rdrama.net' and author.id in (PIZZASHILL_ID, CARP_ID): abort(403, f"@{author.username} is immune to awards.") if kind == "benefactor" and author.id == v.id: @@ -201,7 +201,7 @@ def award_thing(v, thing_type, id): elif kind != 'spider': awarded_coins = int(AWARDS[kind]['price'] * COSMETIC_AWARD_COIN_AWARD_PCT) if AWARDS[kind]['cosmetic'] else 0 if AWARDS[kind]['cosmetic']: - author.pay_account('coins', awarded_coins) + author.coins += awarded_coins msg = f"@{v.username} has given your [{thing_type}]({thing.shortlink}) the {AWARDS[kind]['title']} Award" if awarded_coins > 0: @@ -331,7 +331,7 @@ def award_thing(v, thing_type, id): author.patron = 1 if author.patron_utc: author.patron_utc += 2629746 else: author.patron_utc = int(time.time()) + 2629746 - author.pay_account('marseybux', 2500) + author.procoins += 2500 badge_grant(user=v, badge_id=103) elif kind == "rehab": if author.rehab: author.rehab += 86400 @@ -390,6 +390,10 @@ def award_thing(v, thing_type, id): if author.spider: author.spider += 86400 else: author.spider = int(time.time()) + 86400 badge_grant(user=author, badge_id=179, notify=False) + elif FEATURES['HOLIDAY_EVENT']: + from events import EVENT_AWARDS, award_thing_event + if kind in EVENT_AWARDS: + award_thing_event(v, kind, author) if author.received_award_count: author.received_award_count += 1 else: author.received_award_count = 1 diff --git a/files/routes/casino.py b/files/routes/casino.py index 93e1a830e..ac72f5c0f 100644 --- a/files/routes/casino.py +++ b/files/routes/casino.py @@ -16,7 +16,7 @@ from files.__main__ import app, limiter @auth_required def casino(v): if v.rehab: - return render_template("casino/rehab.html", v=v), 403 + return render_template("casino/rehab.html", v=v) return render_template("casino.html", v=v) @@ -26,13 +26,12 @@ def casino(v): @auth_required def casino_game_page(v, game): if v.rehab: - return render_template("casino/rehab.html", v=v), 403 + return render_template("casino/rehab.html", v=v) elif game not in CASINO_GAME_KINDS: abort(404) feed = json.dumps(get_game_feed(game, g.db)) leaderboard = json.dumps(get_game_leaderboard(game, g.db)) - v_stats = get_user_stats(v, game, g.db, game == 'blackjack') game_state = '' if game == 'blackjack': @@ -45,7 +44,6 @@ def casino_game_page(v, game): game=game, feed=feed, leaderboard=leaderboard, - v_stats=v_stats, game_state=game_state ) @@ -89,20 +87,22 @@ def pull_slots(v): try: currency = request.values.get("currency", "").lower() - if currency not in ('coins', 'marseybux'): raise ValueError() + if currency not in ('coins', 'procoins'): raise ValueError() except: - abort(400, "Invalid currency (expected 'coins' or 'marseybux').") + abort(400, "Invalid currency (expected 'coins' or 'procoins').") - if (currency == "coins" and wager > v.coins) or (currency == "marseybux" and wager > v.marseybux): - abort(400, f"Not enough {currency} to make that bet") + friendly_currency_name = "coins" if currency == "coins" else "marseybux" + + if (currency == "coins" and wager > v.coins) or (currency == "procoins" and wager > v.procoins): + abort(400, f"Not enough {friendly_currency_name} to make that bet") game_id, game_state = casino_slot_pull(v, wager, currency) success = bool(game_id) if success: - return {"game_state": game_state, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"game_state": game_state, "gambler": {"coins": v.coins, "procoins": v.procoins}} else: - abort(400, f"Wager must be 5 {currency} or more") + abort(400, f"Wager must be 5 {friendly_currency_name} or more") # 21 @@ -120,7 +120,7 @@ def blackjack_deal_to_player(v): state = dispatch_action(v, BlackjackAction.DEAL) feed = get_game_feed('blackjack', g.db) - return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}} except Exception as e: abort(400, str(e)) @@ -135,7 +135,7 @@ def blackjack_player_hit(v): try: state = dispatch_action(v, BlackjackAction.HIT) feed = get_game_feed('blackjack', g.db) - return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}} except: abort(400, "Unable to hit.") @@ -150,7 +150,7 @@ def blackjack_player_stay(v): try: state = dispatch_action(v, BlackjackAction.STAY) feed = get_game_feed('blackjack', g.db) - return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}} except: abort(400, "Unable to stay.") @@ -165,7 +165,7 @@ def blackjack_player_doubled_down(v): try: state = dispatch_action(v, BlackjackAction.DOUBLE_DOWN) feed = get_game_feed('blackjack', g.db) - return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}} except: abort(400, "Unable to double down.") @@ -180,7 +180,7 @@ def blackjack_player_bought_insurance(v): try: state = dispatch_action(v, BlackjackAction.BUY_INSURANCE) feed = get_game_feed('blackjack', g.db) - return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "state": state, "feed": feed, "gambler": {"coins": v.coins, "procoins": v.procoins}} except: abort(403, "Unable to buy insurance.") @@ -194,7 +194,7 @@ def roulette_get_bets(v): bets = get_roulette_bets() - return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}} @app.post("/casino/roulette/place-bet") @@ -204,26 +204,19 @@ def roulette_player_placed_bet(v): if v.rehab: abort(403, "You are under Rehab award effect!") - bet = request.values.get("bet") - which = request.values.get("which", None) - amount = request.values.get("wager", None, int) - currency = request.values.get("currency") - - try: bet_type = RouletteAction(bet) - except: abort(400, "Not a valid roulette bet type") - - if not amount or amount < 5: abort(400, f"Minimum bet is 5 {currency}.") - if not which: abort(400, "Not a valid roulette bet") - - try: which_int = int(which) - except: which_int = None - - if not bet_type.validation_function(which if which_int is None else which_int): - abort(400, f"Not a valid roulette bet for bet type {bet_type.value[0]}") - try: + bet = request.values.get("bet") + which = request.values.get("which") + amount = int(request.values.get("wager")) + currency = request.values.get("currency") + + if amount < 5: + abort(400, f"Minimum bet is 5 {currency}.") + gambler_placed_roulette_bet(v, bet, which, amount, currency) + bets = get_roulette_bets() - return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "marseybux": v.marseybux}} + + return {"success": True, "bets": bets, "gambler": {"coins": v.coins, "procoins": v.procoins}} except: abort(400, "Unable to place a bet.") diff --git a/files/routes/chat.py b/files/routes/chat.py index 1fe22bd89..39355b99b 100644 --- a/files/routes/chat.py +++ b/files/routes/chat.py @@ -13,7 +13,7 @@ from files.routes.wrappers import * from files.__main__ import app, cache, limiter -if IS_LOCALHOST: +if SITE == 'localhost': socketio = SocketIO( app, async_mode='gevent', diff --git a/files/routes/comments.py b/files/routes/comments.py index 5dc148383..16426e10a 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -73,7 +73,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None): execute_shadowban_viewers_and_voters(v, post) execute_shadowban_viewers_and_voters(v, comment) - if v and v.client: return top_comment.json(db=g.db) + if v and v.client: return top_comment.json else: if post.is_banned and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)): template = "submission_banned.html" else: template = "submission.html" @@ -81,7 +81,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None): @app.post("/comment") @limiter.limit("1/second;20/minute;200/hour;1000/day") -@ratelimit_user("1/second;20/minute;200/hour;1000/day") +@limiter.limit("1/second;20/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def comment(v): if v.is_suspended: abort(403, "You can't perform this action while banned.") @@ -361,14 +361,14 @@ def comment(v): g.db.flush() - if v.client: return c.json(db=g.db) + if v.client: return c.json(g.db) return {"comment": render_template("comments.html", v=v, comments=[c])} @app.post("/edit_comment/") @limiter.limit("1/second;10/minute;100/hour;200/day") -@ratelimit_user("1/second;10/minute;100/hour;200/day") +@limiter.limit("1/second;10/minute;100/hour;200/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def edit_comment(cid, v): c = get_comment(cid, v=v) diff --git a/files/routes/hats.py b/files/routes/hats.py index 0641efb73..3eb8f10d6 100644 --- a/files/routes/hats.py +++ b/files/routes/hats.py @@ -48,17 +48,17 @@ def buy_hat(v, hat_id): abort(403, "This hat is not for sale.") if request.values.get("mb"): - charged = v.charge_account('marseybux', hat.price) + charged = v.charge_account('procoins', hat.price) if not charged: abort(400, "Not enough marseybux.") - hat.author.pay_account('marseybux', hat.price * 0.1) + hat.author.procoins += hat.price * 0.1 currency = "marseybux" else: charged = v.charge_account('coins', hat.price) if not charged: abort(400, "Not enough coins.") v.coins_spent_on_hats += hat.price - hat.author.pay_account('coins', hat.price * 0.1) + hat.author.coins += hat.price * 0.1 currency = "coins" new_hat = Hat(user_id=v.id, hat_id=hat.id) @@ -129,5 +129,4 @@ def hat_owners(v, hat_id): users=users, next_exists=next_exists, page=page, - user_cards_title="Hat Owners", ) diff --git a/files/routes/jinja2.py b/files/routes/jinja2.py index 5017cc3c4..77177c3a2 100644 --- a/files/routes/jinja2.py +++ b/files/routes/jinja2.py @@ -43,14 +43,14 @@ def timestamp(timestamp): @app.context_processor def inject_constants(): - return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, + constants = {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "MODMAIL_ID":MODMAIL_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "os_path":path, "AEVANN_ID":AEVANN_ID, "PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES, "HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED, "GUMROAD_LINK":GUMROAD_LINK, "DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION, - "has_sidebar":has_sidebar, "has_logo":has_logo, + "has_sidebar":has_sidebar, "has_logo":has_logo, "has_app":has_app, "FP":FP, "cache":cache, "ONLINE_STR":ONLINE_STR, "patron":patron, "DUES":DUES, "SIDEBAR_THREAD":SIDEBAR_THREAD, "BANNER_THREAD":BANNER_THREAD, "BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD, @@ -66,5 +66,6 @@ def inject_constants(): "HOUSE_JOIN_COST":HOUSE_JOIN_COST, "HOUSE_SWITCH_COST":HOUSE_SWITCH_COST, "IMAGE_FORMATS":IMAGE_FORMATS, "PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS, "TIME_FILTERS":TIME_FILTERS, "HOUSES":HOUSES, "TIERS_ID_TO_NAME":TIERS_ID_TO_NAME, - "DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE, "IS_LOCALHOST":IS_LOCALHOST, + "DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE, } + return constants diff --git a/files/routes/login.py b/files/routes/login.py index 6cd003703..4fefcbd16 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -16,18 +16,15 @@ from files.helpers.useractions import badge_grant from files.routes.routehelpers import check_for_alts from files.routes.wrappers import * - -NO_LOGIN_REDIRECT_URLS = ("/login", "/logout", "/signup", "/forgot", "/reset", "/reset_2fa", "/request_2fa_disable") - @app.get("/login") @auth_desired def login_get(v): - redir = request.values.get("redirect", "/").strip().rstrip('?').lower() + redir = request.values.get("redirect", "/").strip().rstrip('?') if redir: - if not is_site_url(redir) or redir in NO_LOGIN_REDIRECT_URLS: - redir = "/" + if not is_site_url(redir): redir = "/" if v: return redirect(redir) - return render_template("login/login.html", failed=False, redirect=redir), 401 + + return render_template("login.html", failed=False, redirect=redir) def login_deduct_when(resp): if not g: @@ -57,20 +54,20 @@ def login_post(): if not account: time.sleep(random.uniform(0, 2)) - return render_template("login/login.html", failed=True), 401 + return render_template("login.html", failed=True) if request.values.get("password"): if not account.verifyPass(request.values.get("password")): log_failed_admin_login_attempt(account, "password") time.sleep(random.uniform(0, 2)) - return render_template("login/login.html", failed=True), 401 + return render_template("login.html", failed=True) if account.mfa_secret: now = int(time.time()) hash = generate_hash(f"{account.id}+{now}+2fachallenge") g.login_failed = False - return render_template("login/login_2fa.html", + return render_template("login_2fa.html", v=account, time=now, hash=hash, @@ -92,22 +89,21 @@ def login_post(): if not account.validate_2fa(request.values.get("2fa_token", "").strip()): hash = generate_hash(f"{account.id}+{now}+2fachallenge") log_failed_admin_login_attempt(account, "2FA token") - return render_template("login/login_2fa.html", + return render_template("login_2fa.html", v=account, time=now, hash=hash, failed=True, - ), 401 + ) else: abort(400) g.login_failed = False on_login(account) - redir = request.values.get("redirect", "").strip().rstrip('?').lower() + redir = request.values.get("redirect", "").strip().rstrip('?') if redir: - if is_site_url(redir) and redir in NO_LOGIN_REDIRECT_URLS: - return redirect(redir) + if is_site_url(redir): return redirect(redir) return redirect('/') def log_failed_admin_login_attempt(account:User, type:str): @@ -165,7 +161,7 @@ def sign_up_get(v): ref_user = None if ref_user and (ref_user.id in session.get("history", [])): - return render_template("login/sign_up_failed_ref.html"), 403 + return render_template("sign_up_failed_ref.html") now = int(time.time()) token = secrets.token_hex(16) @@ -184,16 +180,14 @@ def sign_up_get(v): if redir: if not is_site_url(redir): redir = "/" - status_code = 200 if not error else 400 - - return render_template("login/sign_up.html", + return render_template("sign_up.html", formkey=formkey, now=now, ref_user=ref_user, turnstile=TURNSTILE_SITEKEY, error=error, redirect=redir - ), status_code + ) @app.post("/signup") @@ -337,16 +331,15 @@ def sign_up_post(v): if JUSTCOOL_ID: send_notification(JUSTCOOL_ID, f"A new user - @{new_user.username} - has signed up!") - redir = request.values.get("redirect", "").strip().rstrip('?').lower() + redir = request.values.get("redirect", "").strip().rstrip('?') if redir: - if is_site_url(redir) or redir in NO_LOGIN_REDIRECT_URLS: - return redirect(redir) + if is_site_url(redir): return redirect(redir) return redirect('/') @app.get("/forgot") def get_forgot(): - return render_template("login/forgot_password.html") + return render_template("forgot_password.html") @app.post("/forgot") @@ -359,7 +352,7 @@ def post_forgot(): email = request.values.get("email",'').strip().lower() if not email_regex.fullmatch(email): - return render_template("login/forgot_password.html", error="Invalid email."), 400 + return render_template("forgot_password.html", error="Invalid email.") username = username.lstrip('@').replace('\\', '').replace('_', '\_').replace('%', '').strip() @@ -381,8 +374,8 @@ def post_forgot(): v=user) ) - return render_template("login/forgot_password.html", - msg="If the username and email matches an account, you will be sent a password reset email. You have ten minutes to complete the password reset process."), 202 + return render_template("forgot_password.html", + msg="If the username and email matches an account, you will be sent a password reset email. You have ten minutes to complete the password reset process.") @app.get("/reset") @@ -406,7 +399,7 @@ def get_reset(): reset_token = generate_hash(f"{user.id}+{timestamp}+reset+{user.login_nonce}") - return render_template("login/reset_password.html", + return render_template("reset_password.html", v=user, token=reset_token, time=timestamp, @@ -438,11 +431,11 @@ def post_reset(v): abort(400) if password != confirm_password: - return render_template("login/reset_password.html", + return render_template("reset_password.html", v=user, token=token, time=timestamp, - error="Passwords didn't match."), 400 + error="Passwords didn't match.") user.passhash = hash_password(password) g.db.add(user) @@ -456,7 +449,10 @@ def post_reset(v): @auth_desired def lost_2fa(v): if v and not v.mfa_secret: abort(400, "You don't have 2FA enabled") - return render_template("login/lost_2fa.html", v=v) + return render_template( + "lost_2fa.html", + v=v + ) @app.post("/request_2fa_disable") @limiter.limit("1/second;6/minute;200/hour;1000/day") @@ -466,7 +462,7 @@ def request_2fa_disable(): if not user or not user.email or not user.mfa_secret: return render_template("message.html", title="Removal request received", - message="If username, password, and email match, we will send you an email."), 202 + message="If username, password, and email match, we will send you an email.") email=request.values.get("email").strip().lower() @@ -478,7 +474,7 @@ def request_2fa_disable(): if not user.verifyPass(password): return render_template("message.html", title="Removal request received", - message="If username, password, and email match, we will send you an email."), 202 + message="If username, password, and email match, we will send you an email.") valid=int(time.time()) token=generate_hash(f"{user.id}+{user.username}+disable2fa+{valid}+{user.mfa_secret}+{user.login_nonce}") @@ -494,7 +490,7 @@ def request_2fa_disable(): return render_template("message.html", title="Removal request received", - message="If username, password, and email match, we will send you an email."), 202 + message="If username, password, and email match, we will send you an email.") @app.get("/reset_2fa") def reset_2fa(): @@ -518,8 +514,10 @@ def reset_2fa(): abort(403) user.mfa_secret=None + g.db.add(user) + return render_template("message_success.html", title="Two-factor authentication removed.", message="Login normally to access your account.") diff --git a/files/routes/notifications.py b/files/routes/notifications.py index 0654abc7d..696a72c34 100644 --- a/files/routes/notifications.py +++ b/files/routes/notifications.py @@ -273,7 +273,7 @@ def notifications(v): Comment.deleted_utc == 0, Comment.body_html.notlike('%

    New site mention%") @auth_required diff --git a/files/routes/posts.py b/files/routes/posts.py index e145c9002..e8e6c7581 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -206,7 +206,7 @@ def post_id(pid, anything=None, v=None, sub=None): g.db.add(pin) elif pin.level > 1: pinned2.add(pin.top_comment(g.db)) - if pin.top_comment(g.db) in comments: + if pin.top_comment in comments: comments.remove(pin.top_comment(g.db)) else: pinned2.add(pin) @@ -310,7 +310,7 @@ def morecomments(v, cid): @app.post("/edit_post/") @limiter.limit("1/second;10/minute;100/hour;200/day") -@ratelimit_user("1/second;10/minute;100/hour;200/day") +@limiter.limit("1/second;10/minute;100/hour;200/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def edit_post(pid, v): p = get_post(pid) @@ -712,16 +712,18 @@ def submit_post(v, sub=None): yt_id = url.split('https://youtube.com/watch?v=')[1].split('&')[0].split('%')[0] if yt_id_regex.fullmatch(yt_id): - params = parse_qs(urlparse(url).query, keep_blank_values=True) - t = params.get('t', params.get('start', [0]))[0] - if isinstance(t, str): t = t.replace('s','') - - embed = f'' + req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={yt_id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json() + if req.get('items'): + params = parse_qs(urlparse(url).query, keep_blank_values=True) + t = params.get('t', params.get('start', [0]))[0] + if isinstance(t, str): t = t.replace('s','') + embed = f'' + elif SITE in domain and "/post/" in url and "context" not in url and url.count('/') < 6: id = url.split("/post/")[1] if "/" in id: id = id.split("/")[0] @@ -731,7 +733,7 @@ def submit_post(v, sub=None): if not url and not body and not request.files.get("file") and not request.files.get("file-url"): return error("Please enter a url or some text.") - if not IS_LOCALHOST: + if SITE != 'localhost': dup = g.db.query(Submission).filter( Submission.author_id == v.id, Submission.deleted_utc == 0, @@ -788,6 +790,9 @@ def submit_post(v, sub=None): if url and url.startswith(SITE_FULL): url = url.split(SITE_FULL)[1] + if SITE == 'rdrama.net' and v.agendaposter == 1: + sub = 'chudrama' + post = Submission( private=flag_private, notify=flag_notify, @@ -1072,7 +1077,7 @@ extensions = IMAGE_FORMATS + VIDEO_FORMATS + AUDIO_FORMATS @app.get("/submit/title") @limiter.limit("3/minute") -@ratelimit_user("3/minute") +@limiter.limit("3/minute", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def get_post_title(v): url = request.values.get("url") diff --git a/files/routes/reporting.py b/files/routes/reporting.py index 865bd2476..fa51de293 100644 --- a/files/routes/reporting.py +++ b/files/routes/reporting.py @@ -156,7 +156,6 @@ def move_post(post:Submission, v:User, reason:str) -> Union[bool, str]: abort(403, f"@{post.author.username} needs to be a member of House {sub_to.capitalize()} for their post to be moved to /h/{sub_to}") post.sub = sub_to - post.hole_pinned = None g.db.add(post) if v.id != post.author_id: diff --git a/files/routes/routehelpers.py b/files/routes/routehelpers.py index a4077aec6..2321cf5f9 100644 --- a/files/routes/routehelpers.py +++ b/files/routes/routehelpers.py @@ -1,5 +1,4 @@ import time -import secrets from random import randint from typing import Optional, Union @@ -11,10 +10,6 @@ from files.helpers.const import * from files.helpers.security import generate_hash, validate_hash def get_raw_formkey(u:User): - if not session.get("session_id"): - session.permanent = True - session["session_id"] = secrets.token_hex(49) - return f"{session['session_id']}+{u.id}+{u.login_nonce}" def get_formkey(u:Optional[User]): diff --git a/files/routes/search.py b/files/routes/search.py index 6b848b525..2a910a001 100644 --- a/files/routes/search.py +++ b/files/routes/search.py @@ -216,8 +216,6 @@ def searchcomments(v): if 'q' in criteria: tokens = map(lambda x: re.sub(r'[\0():|&*!<>]', '', x), criteria['q']) tokens = filter(lambda x: len(x) > 0, tokens) - tokens = map(lambda x: re.sub(r"'", "\\'", x), tokens) - tokens = map(lambda x: x.strip(), tokens) tokens = map(lambda x: re.sub(r'\s+', ' <-> ', x), tokens) comments = comments.filter(Comment.body_ts.match( ' & '.join(tokens), @@ -270,7 +268,7 @@ def searchcomments(v): comments = get_comments(ids, v=v) - if v.client: return {"total":total, "data":[x.json(db=g.db) for x in comments]} + if v.client: return {"total":total, "data":[x.json for x in comments]} return render_template("search_comments.html", v=v, query=query, total=total, page=page, comments=comments, sort=sort, t=t, next_exists=next_exists, standalone=True) diff --git a/files/routes/settings.py b/files/routes/settings.py index cfe3f02fd..d16af09e1 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -281,7 +281,7 @@ def settings_personal_post(v): success = v.charge_account('coins', cost) if not success: - success = v.charge_account('marseybux', cost) + success = v.charge_account('procoins', cost) if not success: abort(403) if house == "None": house = '' @@ -358,16 +358,16 @@ def gumroad(v): tier = tiers[response["variants_and_quantity"]] if v.patron == tier: abort(400, f"{patron} rewards already claimed") - marseybux = marseybux_li[tier] - marseybux_li[v.patron] - if marseybux < 0: abort(400, f"{patron} rewards already claimed") + procoins = procoins_li[tier] - procoins_li[v.patron] + if procoins < 0: abort(400, f"{patron} rewards already claimed") existing = g.db.query(User.id).filter(User.email == v.email, User.is_activated == True, User.patron >= tier).first() if existing: abort(400, f"{patron} rewards already claimed on another account") v.patron = tier - v.pay_account('marseybux', marseybux) - send_repeatable_notification(v.id, f"You have received {marseybux} Marseybux! You can use them to buy awards in the [shop](/shop).") + v.procoins += procoins + send_repeatable_notification(v.id, f"You have received {procoins} Marseybux! You can use them to buy awards in the [shop](/shop).") g.db.add(v) @@ -462,7 +462,6 @@ def settings_security_post(v): v.mfa_secret = None g.db.add(v) - g.db.commit() return render_template("settings/security.html", v=v, msg="Two-factor authentication disabled.") @app.post("/settings/log_out_all_others") @@ -581,7 +580,7 @@ def settings_security(v): @app.post("/settings/block") @limiter.limit("1/second;20/day") -@ratelimit_user("1/second;20/day") +@limiter.limit("1/second;20/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def settings_block_user(v): user = get_user(request.values.get("username"), graceful=True) @@ -671,7 +670,7 @@ def settings_name_change(v): @app.post("/settings/song_change_mp3") @feature_required('USERS_PROFILE_SONG') @limiter.limit("3/second;10/day") -@ratelimit_user("3/second;10/day") +@limiter.limit("3/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def settings_song_change_mp3(v): file = request.files['file'] @@ -699,7 +698,7 @@ def settings_song_change_mp3(v): @app.post("/settings/song_change") @feature_required('USERS_PROFILE_SONG') @limiter.limit("3/second;10/day") -@ratelimit_user("3/second;10/day") +@limiter.limit("3/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def settings_song_change(v): song=request.values.get("song").strip() @@ -717,13 +716,11 @@ def settings_song_change(v): elif song.startswith("https://youtu.be/"): id = song.split("https://youtu.be/")[1] else: - return render_template("settings/personal.html", v=v, error="Not a YouTube link"), 400 + return render_template("settings/personal.html", v=v, error="Not a youtube link.") if "?" in id: id = id.split("?")[0] if "&" in id: id = id.split("&")[0] - if not yt_id_regex.fullmatch(id): - return render_template("settings/personal.html", v=v, error="Not a YouTube link"), 400 if path.isfile(f'/songs/{id}.mp3'): v.song = id g.db.add(v) @@ -733,15 +730,15 @@ def settings_song_change(v): req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json() duration = req['items'][0]['contentDetails']['duration'] if duration == 'P0D': - return render_template("settings/personal.html", v=v, error="Can't use a live youtube video!"), 400 + return render_template("settings/personal.html", v=v, error="Can't use a live youtube video!") if "H" in duration: - return render_template("settings/personal.html", v=v, error="Duration of the video must not exceed 15 minutes."), 400 + return render_template("settings/personal.html", v=v, error="Duration of the video must not exceed 15 minutes.") if "M" in duration: duration = int(duration.split("PT")[1].split("M")[0]) if duration > 15: - return render_template("settings/personal.html", v=v, error="Duration of the video must not exceed 15 minutes."), 400 + return render_template("settings/personal.html", v=v, error="Duration of the video must not exceed 15 minutes.") if v.song and path.isfile(f"/songs/{v.song}.mp3") and g.db.query(User).filter_by(song=v.song).count() == 1: @@ -763,7 +760,7 @@ def settings_song_change(v): print(e, flush=True) return render_template("settings/personal.html", v=v, - error="Age-restricted videos aren't allowed."), 400 + error="Age-restricted videos aren't allowed.") files = os.listdir("/songs/") paths = [path.join("/songs/", basename) for basename in files] diff --git a/files/routes/static.py b/files/routes/static.py index 6c90bc49f..65f34bd77 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -208,7 +208,7 @@ def contact(v): @app.post("/send_admin") @limiter.limit("1/second;1/2 minutes;10/day") -@ratelimit_user("1/second;1/2 minutes;10/day") +@limiter.limit("1/second;1/2 minutes;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def submit_contact(v): body = request.values.get("message") @@ -283,8 +283,6 @@ def image(path): @app.get('/static/assets/') @limiter.exempt def static_service(path): - if path.startswith(f'app_{SITE_NAME}_v'): - return redirect('/app') is_webp = path.endswith('.webp') return static_file('assets', path, is_webp or path.endswith('.gif') or path.endswith('.ttf') or path.endswith('.woff2'), is_webp) @@ -365,11 +363,6 @@ def banned(v): def formatting(v): return render_template("formatting.html", v=v) -@app.get("/app") -@auth_desired -def mobile_app(v): - return render_template("app.html", v=v) - @app.get("/service-worker.js") def serviceworker(): with open("files/assets/js/service-worker.js", "r", encoding="utf-8") as f: diff --git a/files/routes/subs.py b/files/routes/subs.py index 55c5348b4..e9a49d41d 100644 --- a/files/routes/subs.py +++ b/files/routes/subs.py @@ -232,7 +232,7 @@ def sub_followers(v, sub): @app.post("/h//add_mod") @limiter.limit("1/second;30/day") -@ratelimit_user("1/second;30/day") +@limiter.limit("1/second;30/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def add_mod(v, sub): if SITE_NAME == 'WPD': abort(403) @@ -360,8 +360,7 @@ def kick(v, pid): old = post.sub post.sub = None - post.hole_pinned = None - + ma = SubAction( sub=old, kind='kick_post', @@ -457,7 +456,7 @@ def get_sub_css(sub): @app.post("/h//banner") @limiter.limit("1/second;10/day") -@ratelimit_user("1/second;10/day") +@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def sub_banner(v, sub): if g.is_tor: abort(403, "Image uploads are not allowed through TOR.") @@ -490,7 +489,7 @@ def sub_banner(v, sub): @app.post("/h//sidebar_image") @limiter.limit("1/second;10/day") -@ratelimit_user("1/second;10/day") +@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def sub_sidebar(v, sub): if g.is_tor: abort(403, "Image uploads are not allowed through TOR.") @@ -522,7 +521,7 @@ def sub_sidebar(v, sub): @app.post("/h//marsey_image") @limiter.limit("1/second;10/day") -@ratelimit_user("1/second;10/day") +@limiter.limit("1/second;10/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def sub_marsey(v, sub): if g.is_tor: abort(403, "Image uploads are not allowed through TOR.") diff --git a/files/routes/users.py b/files/routes/users.py index 605cc1178..4defe8212 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -128,7 +128,7 @@ def downvoting_posts(v, username, uid): def downvoting_comments(v, username, uid): return upvoting_downvoting(v, username, uid, Comment, CommentVote, -1, "userpage/voted_comments.html", True) -def user_voted(v, username, cls, vote_cls, template, standalone): +def user_voted(v, username, cls, vote_cls, vote_dir, template, standalone): u = get_user(username, v=v, include_shadowbanned=False) if not u.is_visible_to(v): abort(403) if not (v.id == u.id or v.admin_level >= PERMS['USER_VOTERS_VISIBLE']): abort(403) @@ -142,6 +142,7 @@ def user_voted(v, username, cls, vote_cls, template, standalone): cls.deleted_utc == 0, cls.author_id != u.id, vote_cls.user_id == u.id, + vote_cls.vote_type == vote_dir ).order_by(cls.created_utc.desc()).offset(PAGE_SIZE * (page - 1)).limit(PAGE_SIZE + 1).all() listing = [p.id for p in listing] @@ -156,16 +157,16 @@ def user_voted(v, username, cls, vote_cls, template, standalone): return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone) -@app.get("/@/voted/posts") +@app.get("/@/upvoted/posts") @auth_required -def user_voted_posts(v, username): - return user_voted(v, username, Submission, Vote, "userpage/voted_posts.html", None) +def user_upvoted_posts(v, username): + return user_voted(v, username, Submission, Vote, 1, "userpage/voted_posts.html", None) -@app.get("/@/voted/comments") +@app.get("/@/upvoted/comments") @auth_required -def user_voted_comments(v, username): - return user_voted(v, username, Comment, CommentVote, "userpage/voted_comments.html", True) +def user_upvoted_comments(v, username): + return user_voted(v, username, Comment, CommentVote, 1, "userpage/voted_comments.html", True) @app.get("/grassed") @@ -180,7 +181,7 @@ def grassed(v): @app.get("/chuds") @auth_required def chuds(v): - users = g.db.query(User).filter(User.agendaposter == 1) + users = g.db.query(User).filter(User.agendaposter > 0) if not v.can_see_shadowbanned: users = users.filter(User.shadowbanned == None) users = users.order_by(User.username).all() @@ -254,7 +255,7 @@ def downvoting(v, username): @app.post("/@/suicide") @feature_required('USERS_SUICIDE') @limiter.limit("1/second;5/day") -@ratelimit_user("1/second;5/day") +@limiter.limit("1/second;5/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def suicide(v, username): @@ -272,23 +273,24 @@ def get_coins(v, username): user = get_user(username, v=v, include_shadowbanned=False) return {"coins": user.coins} -def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'marseybux'], apply_tax:bool): +def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'procoins'], apply_tax:bool): MIN_CURRENCY_TRANSFER = 100 TAX_PCT = 0.03 + friendly_currency_name = 'marseybux' if currency_name == 'procoins' else 'coins' receiver = get_user(username, v=v, include_shadowbanned=False) - if receiver.id == v.id: abort(400, f"You can't transfer {currency_name} to yourself!") + if receiver.id == v.id: abort(400, f"You can't transfer {friendly_currency_name} to yourself!") amount = request.values.get("amount", "").strip() amount = int(amount) if amount.isdigit() else None - if amount is None or amount <= 0: abort(400, f"Invalid number of {currency_name}") - if amount < MIN_CURRENCY_TRANSFER: abort(400, f"You have to gift at least {MIN_CURRENCY_TRANSFER} {currency_name}") + if amount is None or amount <= 0: abort(400, f"Invalid number of {friendly_currency_name}") + if amount < MIN_CURRENCY_TRANSFER: abort(400, f"You have to gift at least {MIN_CURRENCY_TRANSFER} {friendly_currency_name}") tax = 0 if apply_tax and not v.patron and not receiver.patron and not v.alts_patron and not receiver.alts_patron: tax = math.ceil(amount*TAX_PCT) reason = request.values.get("reason", "").strip() - log_message = f"@{v.username} has transferred {amount} {currency_name} to @{receiver.username}" - notif_text = f":marseycapitalistmanlet: @{v.username} has gifted you {amount-tax} {currency_name}!" + log_message = f"@{v.username} has transferred {amount} {friendly_currency_name} to @{receiver.username}" + notif_text = f":marseycapitalistmanlet: @{v.username} has gifted you {amount-tax} {friendly_currency_name}!" if reason: if len(reason) > TRANSFER_MESSAGE_LENGTH_LIMIT: abort(400, f"Reason is too long, max {TRANSFER_MESSAGE_LENGTH_LIMIT} characters") @@ -296,20 +298,20 @@ def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'mars log_message += f"\n\n> {reason}" if not v.charge_account(currency_name, amount): - abort(400, f"You don't have enough {currency_name}") + abort(400, f"You don't have enough {friendly_currency_name}") if not v.shadowbanned: - if currency_name == 'marseybux': - receiver.pay_account('marseybux', amount - tax) + if currency_name == 'procoins': + receiver.procoins += amount - tax elif currency_name == 'coins': - receiver.pay_account('coins', amount - tax) + receiver.coins += amount - tax else: raise ValueError(f"Invalid currency '{currency_name}' got when transferring {amount} from {v.id} to {receiver.id}") g.db.add(receiver) if GIFT_NOTIF_ID: send_repeatable_notification(GIFT_NOTIF_ID, log_message) send_repeatable_notification(receiver.id, notif_text) g.db.add(v) - return {"message": f"{amount - tax} {currency_name} have been transferred to @{receiver.username}"} + return {"message": f"{amount - tax} {friendly_currency_name} have been transferred to @{receiver.username}"} @app.post("/@/transfer_coins") @limiter.limit(DEFAULT_RATELIMIT_SLOWER) @@ -319,12 +321,12 @@ def transfer_coins(v, username): return transfer_currency(v, username, 'coins', True) @app.post("/@/transfer_bux") -@feature_required('MARSEYBUX') +@feature_required('PROCOINS') @limiter.limit(DEFAULT_RATELIMIT_SLOWER) @is_not_permabanned @ratelimit_user() def transfer_bux(v, username): - return transfer_currency(v, username, 'marseybux', False) + return transfer_currency(v, username, 'procoins', False) @app.get("/leaderboard") @auth_required @@ -414,7 +416,7 @@ def unsubscribe(v, post_id): @app.post("/@/message") @limiter.limit("1/second;10/minute;20/hour;50/day") -@ratelimit_user("1/second;10/minute;20/hour;50/day") +@limiter.limit("1/second;10/minute;20/hour;50/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned def message2(v, username): user = get_user(username, v=v, include_blocks=True, include_shadowbanned=False) @@ -479,7 +481,7 @@ def message2(v, username): @app.post("/reply") @limiter.limit("1/second;6/minute;50/hour;200/day") -@ratelimit_user("1/second;6/minute;50/hour;200/day") +@limiter.limit("1/second;6/minute;50/hour;200/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @auth_required def messagereply(v): body = sanitize_raw_body(request.values.get("body"), False) @@ -1050,7 +1052,6 @@ def bid_list(v, bid): users=users, next_exists=next_exists, page=page, - user_cards_title="Badge Owners", ) @@ -1106,9 +1107,9 @@ def settings_kofi(v): tier = kofi_tiers[transaction.amount] - marseybux = marseybux_li[tier] - v.pay_account('marseybux', marseybux) - send_repeatable_notification(v.id, f"You have received {marseybux} Marseybux! You can use them to buy awards in the [shop](/shop).") + procoins = procoins_li[tier] + v.procoins += procoins + send_repeatable_notification(v.id, f"You have received {procoins} Marseybux! You can use them to buy awards in the [shop](/shop).") g.db.add(v) if tier > v.patron: diff --git a/files/routes/votes.py b/files/routes/votes.py index 5d6d21e4e..e67e15cfd 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -82,7 +82,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): if existing and existing.vote_type == new: return "", 204 if existing: if existing.vote_type == 0 and new != 0: - target.author.pay_account('coins', coin_value) + target.author.coins += coin_value target.author.truescore += coin_delta g.db.add(target.author) existing.vote_type = new @@ -97,7 +97,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): existing.vote_type = new g.db.add(existing) elif new != 0: - target.author.pay_account('coins', coin_value) + target.author.coins += coin_value target.author.truescore += coin_delta g.db.add(target.author) @@ -148,13 +148,14 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): if target.author.progressivestack or target.author.id in BOOSTED_USERS: mul = 2 elif cls == Submission: - if target.domain.endswith('.win') or (target.domain in BOOSTED_SITES and not target.url.startswith('/')) or target.sub in BOOSTED_HOLES: + if target.domain.endswith('.win') or target.domain in BOOSTED_SITES or target.sub in BOOSTED_HOLES: mul = 2 - elif not target.sub and target.body_html and target.author.id not in BOOSTED_USERS_EXCLUDED: + elif target.sub and target.sub not in ('space','istory','dino','slackernews'): + mul = 0.7 + elif not target.sub and target.body_html: x = target.body_html.count('" target="_blank" rel="nofollow noopener">') x += target.body_html.count('/") @limiter.limit("5/second;60/minute;1000/hour;2000/day") +@limiter.limit("5/second;60/minute;1000/hour;2000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned -@ratelimit_user("5/second;60/minute;1000/hour;2000/day") -@limiter.limit("1/second", key_func=lambda:f'{g.v.id}-{request.full_path}') def vote_post(post_id, new, v): return vote_post_comment(post_id, new, v, Submission, Vote) @app.post("/vote/comment//") @limiter.limit("5/second;60/minute;1000/hour;2000/day") +@limiter.limit("5/second;60/minute;1000/hour;2000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') @is_not_permabanned -@ratelimit_user("5/second;60/minute;1000/hour;2000/day") -@limiter.limit("1/second", key_func=lambda:f'{g.v.id}-{request.full_path}') def vote_comment(comment_id, new, v): return vote_post_comment(comment_id, new, v, Comment, CommentVote) diff --git a/files/routes/wrappers.py b/files/routes/wrappers.py index 7a979058e..984bae7f3 100644 --- a/files/routes/wrappers.py +++ b/files/routes/wrappers.py @@ -1,5 +1,4 @@ import time -import secrets import user_agents from flask import g, request, session @@ -12,17 +11,10 @@ from files.helpers.settings import get_setting from files.routes.routehelpers import validate_formkey from files.__main__ import app, cache, db_session, limiter -def session_init(): - if not session.get("session_id"): - session.permanent = True - session["session_id"] = secrets.token_hex(49) - def calc_users(v): loggedin = cache.get(f'{SITE}_loggedin') or {} loggedout = cache.get(f'{SITE}_loggedout') or {} timestamp = int(time.time()) - - session_init() if v: if session["session_id"] in loggedout: del loggedout[session["session_id"]] loggedin[v.id] = timestamp diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index e220af5c8..ccd7fd80a 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -1,6 +1,12 @@ {% extends "default.html" %} -{% block pagetitle %}Admin Home{% endblock %} + +{% block title %} +{{SITE_NAME}} + +{% endblock %} + {% block customPadding %}px-3{% endblock %} + {% block content %}

    Admin Tools

    @@ -48,10 +54,10 @@ {% endif %}
  • Permabanned Users
  • {% if FEATURES['AWARDS'] -%} -
  • Permachudded Users
  • +
  • Chudded Users
  • Currently Grassed Users
  • {%- endif %} - {% if FEATURES['MARSEYBUX'] and (not AEVANN_ID or v.id in (AEVANN_ID, CARP_ID, SNAKES_ID)) -%} + {% if FEATURES['PROCOINS'] and (not AEVANN_ID or v.id in (AEVANN_ID, CARP_ID, SNAKES_ID)) -%}
  • Patrons
  • {%- endif %} {% if v.admin_level >= PERMS['VIEW_ACTIVE_USERS'] %} @@ -71,7 +77,7 @@ {% endif %} -{% if FEATURES['BADGES'] -%} +{% if FEATURES['BADGES'] or FEATURES['AWARDS'] -%}

    Grant

      {% if FEATURES['BADGES'] and v.admin_level >= PERMS['USER_BADGES'] -%} @@ -85,6 +91,7 @@

      Casino

      {%- endif %} @@ -137,7 +144,7 @@
    {% endif %}
    - {% if SITE == 'pcmemes.net' and v.admin_level >= PERMS['PRINT_MARSEYBUX_FOR_KIPPY_ON_PCMEMES'] %} + {% if SITE_NAME == 'PCM' and v.admin_level >= PERMS['PRINT_MARSEYBUX_FOR_KIPPY_ON_PCMEMES'] %} {% endif %} {% endif %} @@ -154,7 +161,7 @@

    Server Status

    - Live Revision: {{gitref[0]}}{{gitref[1]}} + Live Revision: {{gitref}}
    {% endblock %} diff --git a/files/templates/admin/alts.html b/files/templates/admin/alts.html index 2ef58ed52..fc78dbffa 100644 --- a/files/templates/admin/alts.html +++ b/files/templates/admin/alts.html @@ -1,11 +1,11 @@ {% extends "settings2.html" %} -{% block pagetitle %}Alts{% if u %} for @{{u.username}}{% endif %}{% endblock %} {% block content %} {% if u %}
    Alts for @{{u.username}}
    {% else %}
    Alts
    {% endif %} +{%- import 'util/macros.html' as macros with context -%}
    @@ -67,7 +67,7 @@
    {% endif %} - + {% endif %} {% if p.award_count("fireflies", v) %} - + {% endif %} diff --git a/files/templates/badges.html b/files/templates/badges.html index c547c7383..14245323e 100644 --- a/files/templates/badges.html +++ b/files/templates/badges.html @@ -1,5 +1,4 @@ {% extends "default.html" %} -{% block pagetitle %}User Badges{% endblock %} {% block content %}

    User Badges

    This page describes the requirements for obtaining all profile badges.
    diff --git a/files/templates/banned.html b/files/templates/banned.html index 0a96d0471..0e0d49d88 100644 --- a/files/templates/banned.html +++ b/files/templates/banned.html @@ -1,5 +1,5 @@ {% extends "settings2.html" %} -{% block pagetitle %}Permabanned Users{% endblock %} + {% block content %}
    diff --git a/files/templates/blocks.html b/files/templates/blocks.html index e8f051245..0820b51cf 100644 --- a/files/templates/blocks.html +++ b/files/templates/blocks.html @@ -1,5 +1,7 @@ {% extends "settings2.html" %} + {% block pagetitle %}Blocks{% endblock %} + {% block content %}

    Blocks

    diff --git a/files/templates/casino.html b/files/templates/casino.html index 9ea9b21b5..0801dbadf 100644 --- a/files/templates/casino.html +++ b/files/templates/casino.html @@ -1,5 +1,5 @@ {% extends "default.html" %} -{% block pagetitle %}Casino{% endblock %} + {# Title (~25char max), Description (~80char max), Icon (fa-foo-bar), Color (#ff0000), URL (/post/12345/) #} {%- set GAME_INDEX = [ diff --git a/files/templates/casino/game_screen.html b/files/templates/casino/game_screen.html index 9aab40c72..3b41b1b80 100644 --- a/files/templates/casino/game_screen.html +++ b/files/templates/casino/game_screen.html @@ -1,6 +1,6 @@ -{% extends "default.html" %} -{% block pagetitle %}{{game.capitalize()}}{% endblock %} -{% block content %} +{% extends "default.html" %} {% block title %} +{{game.capitalize()}} +{% endblock %} {% block content %}
    -
    +
    + +{% endmacro %} + +{% macro page_meta (title) %} + {% set title = SITE_NAME if not title %} + + {% if 'post/' in request.path and p %} + {% set title = [p.plaintitle(v), ' - ', title] | join %} + + {% if not v_forbid_deleted -%} + {% set image = p.thumb_url if p.has_thumb %} + {% set image = p.realurl(v) if p.is_image %} + {% set video = p.realurl(v) if p.is_video %} + {% set audio = p.realurl(v) if p.is_audio %} + {% endif %} + + {% if comment_info and not comment_info.is_banned and not comment_info.deleted_utc %} + {% set p, title = comment_info, ['@', comment_info.author_name, ' comments on ', + '"', title, '"'] | join %} + {% endif %} + + {% set author, description, a_author, published, modified, url = + '@'+p.author_name, p.plainbody(v), '@'+p.author_name, + p.created_datetime, p.edited_string, p.permalink %} + + {% elif '@' in request.path and u %} + {% set author, a_author, published, url, title, image, section = + '@'+u.username, '@'+u.username, u.created_date, + u.url, u.username, u.banner_url, + [u.username, "'s profile - ", SITE_NAME] | join %} + + {% set description %} + "{{u.coins}} coins - Joined {{u.created_date}} - + {% if u.stored_subscriber_count >=1 and not u.is_private %} + {{u.stored_subscriber_count}} Followers - + {% endif %} + {% if not u.is_private %} + {{0 if u.shadowbanned else u.post_count}} + Posts - + {{0 if u.shadowbanned else u.comment_count}} + Comments + {% endif %} + {% if u.bio %} + - {{u.bio}} + {% endif %}" + {% endset %} + + {% elif sub %} + {% set title, description = + '/h/'+sub.name, sub.sidebar if sub.sidebar %} + {% endif %} + + {{title}} + + {{ meta_tags(title, author, description, image, + video, audio, a_author, published, modified, section, url) }} +{% endmacro %} + +{% macro meta_tags(title, author, description, image, video, audio, a_author, published, modified, section, url ) %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% endmacro %} + +{% macro stylesheets(include_user_css) %} + + + {% if v %} + + {% if v.agendaposter %} + + {% endif %} + {% if include_user_css %} + {% if not EVENT_STYLES %} + + {% endif %} + {% if v.css and not request.path.startswith('/settings/css') %} + + {% endif %} + {% if v.themecolor == '30409f' %} + + {% endif %} + {% else %} + {{default_theme()}} + {% endif %} + {% else %} + {{default_theme()}} + {% endif %} + + + {% if sub and sub.css and not request.path.endswith('settings') and not request.values.get('nocss') %} + + {% endif %} + + {% if SITE_NAME == 'rDrama' %} + + {% endif %} + + {% if EVENT_STYLES %} + + {% endif %} + + {% if 'chat' in request.path %} + {% if SITE == 'localhost' %} + + {% else %} + + {% endif %} + {% endif %} +{% endmacro %} + +{% macro default_theme() %} + + +{% endmacro %} + +{% macro seo() %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% endmacro %} diff --git a/files/templates/live.html b/files/templates/live.html index dcd2005fc..155c6c082 100644 --- a/files/templates/live.html +++ b/files/templates/live.html @@ -1,5 +1,9 @@ {% extends "default.html" %} -{% block pagetitle %}Live{% endblock %} + +{% block title %} + {{SITE_NAME}} - Live +{% endblock %} + {% block content %} {% endblock %} -{% block GIFpicker %}{% endblock %} +{% block GIFpicker %} +{% endblock %} diff --git a/files/templates/oauth.html b/files/templates/oauth.html index 6e2097e09..e2f60dde9 100644 --- a/files/templates/oauth.html +++ b/files/templates/oauth.html @@ -1,19 +1,34 @@ {% extends "login.html" %} -{% block pagetitle %}Application Request for Access{% endblock %} + +{% block title %} +Application Request for Access +{% endblock %} + {% block content %} +
    +

    {{application.app_name}}

    +

    wants to access your @{{v.username}} account.

    +

    It will not be able to see your password, or change your account settings.

    + + + + No, back to {{SITE_NAME}} + +
    + {% endblock %} diff --git a/files/templates/patrons.html b/files/templates/patrons.html index 2522a98fc..137859737 100644 --- a/files/templates/patrons.html +++ b/files/templates/patrons.html @@ -1,5 +1,5 @@ {% extends "settings2.html" %} -{% block pagetitle %}Patrons{% endblock %} + {% block content %}
    diff --git a/files/templates/poll_votes.html b/files/templates/poll_votes.html index 1e621c6bf..834b982d4 100644 --- a/files/templates/poll_votes.html +++ b/files/templates/poll_votes.html @@ -1,7 +1,14 @@ {% extends "default.html" %} -{% block pagetitle %}Poll Votes{% endblock %} + +{% block title %} +{{SITE_NAME}} + +{% endblock %} + {% block content %} + {% if thing %} +

    {{thing.body_html | safe}} - {{ups | length}} {% if thing.exclusive == 2 %}bets{% else %}votes{% endif %}

    @@ -28,6 +35,10 @@ {% endfor %}
    + + {% endif %} + + {% endblock %} diff --git a/files/templates/popover.html b/files/templates/popover.html index f99a9a29c..58221b773 100644 --- a/files/templates/popover.html +++ b/files/templates/popover.html @@ -38,7 +38,7 @@ coins - + View diff --git a/files/templates/post_actions.html b/files/templates/post_actions.html index 94a5cc9ee..ac411b471 100644 --- a/files/templates/post_actions.html +++ b/files/templates/post_actions.html @@ -34,7 +34,7 @@ - + {% endif %} {% if v %} diff --git a/files/templates/post_actions_mobile.html b/files/templates/post_actions_mobile.html index 2810f0238..4c3a4eab6 100644 --- a/files/templates/post_actions_mobile.html +++ b/files/templates/post_actions_mobile.html @@ -41,7 +41,7 @@ - + {% if FEATURES['COUNTRY_CLUB'] -%} diff --git a/files/templates/reset_password.html b/files/templates/reset_password.html new file mode 100644 index 000000000..f3027aecb --- /dev/null +++ b/files/templates/reset_password.html @@ -0,0 +1,33 @@ +{% extends "authforms.html" %} + +{% block pagetitle %}{{SITE_NAME}} Password Reset{% endblock %} + +{% block authtitle %}Change your password.{% endblock %} + +{% block content %} + +
    + +
    + + + + + + + + + + + + + + + +
    + +
    + +{% endblock %} diff --git a/files/templates/search.html b/files/templates/search.html index a5d4d3854..c919e67f7 100644 --- a/files/templates/search.html +++ b/files/templates/search.html @@ -1,8 +1,9 @@ {% extends "default.html" %} + {% block pagetype %}search{% endblock %} -{% block pagetitle %}Search for "{{query}}"{% endblock %} -{% block head_final %} - + +{% block title %} +Search for "{{query}}" - {{SITE_NAME}}" {% endblock %} {% block PseudoSubmitForm %} @@ -15,10 +16,16 @@ {% endblock %} -{% block navbar %}{% endblock %} + +{% block navbar %} +{% endblock %} + {% block content %} +
    +
    +
    @@ -125,13 +132,20 @@
    {% endif %} + +
    + + + {% if not '/users' in request.path %} +
    + +
    {% endif %} +
    @@ -174,16 +190,22 @@
    +
    +
    +
    + {% block listing_template %} {% include "submission_listing.html" %} {% endblock %} +
    {% endblock %} + {% block pagenav %} + {% endblock %} diff --git a/files/templates/search_users.html b/files/templates/search_users.html index 792ef570f..7cc49361d 100644 --- a/files/templates/search_users.html +++ b/files/templates/search_users.html @@ -1,7 +1,9 @@ {% extends "search.html" %} + {% block listing_template %}
    {% include "user_listing.html" %}
    {% endblock %} + {% block listinglength %}{{users | length}}{% endblock %} \ No newline at end of file diff --git a/files/templates/settings.html b/files/templates/settings.html index b52b0f06a..3393572b5 100644 --- a/files/templates/settings.html +++ b/files/templates/settings.html @@ -1,8 +1,13 @@ -{%- extends 'root.html' -%} -{% import 'settings/common.html' as common with context %} -{% block pagetitle %}Settings{% endblock %} -{% block body_attributes %}id="settings" {% if SITE_NAME == 'rDrama' and v and (v.is_banned or v.agendaposter) %}style="overflow-x: hidden;background:url(/assets/images/backgrounds/anime/1.webp?v=3) center center fixed; background-color: var(--background)"{% elif v and v.background %}style="overflow-x: hidden;background:url(/assets/images/backgrounds/{{v.background}}?v=3) center center fixed; background-color: var(--background){% if 'anime' not in v.background %};background-size: cover{% endif %}"{% endif %}{% endblock %} -{% block body %} +{%- import 'util/macros.html' as macros with context -%} +{%- import 'html_head.html' as html_head with context -%} + + + + {% block pagetitle %}Settings - {{SITE_NAME}}{% endblock %} + +{{html_head.html_head(true, false, true, none, "Settings", false)}} + + {% include "header.html" %}
    @@ -57,10 +62,80 @@
    - {% block content %}{% endblock %} + {% block content %} + {% endblock %}
    - + + + + {% if request.path == '/settings/security' %} + +{% endif %} {% block clipboard %} {% block onload %}{% endblock %} - -{% endblock %} + + + diff --git a/files/templates/settings/advanced.html b/files/templates/settings/advanced.html index 1ce94f837..40fa26433 100644 --- a/files/templates/settings/advanced.html +++ b/files/templates/settings/advanced.html @@ -1,6 +1,7 @@ {% extends "settings.html" %} -{% block pagetitle %}Advanced Settings{% endblock %} +{% block pagetitle %}Advanced Settings - {{SITE_NAME}}{% endblock %} {% block content %} +{% import 'settings/common.html' as common with context %}
    diff --git a/files/templates/settings/apps.html b/files/templates/settings/apps.html index d4dfcc42c..3e451bd42 100644 --- a/files/templates/settings/apps.html +++ b/files/templates/settings/apps.html @@ -1,5 +1,5 @@ {% extends "settings.html" %} -{% block pagetitle %}Apps/Bots{% endblock %} +{% block pagetitle %}Apps/Bots - {{SITE_NAME}}{% endblock %} {% block content %}
    diff --git a/files/templates/settings/common.html b/files/templates/settings/common.html index 9ee5d951c..1cb2aba31 100644 --- a/files/templates/settings/common.html +++ b/files/templates/settings/common.html @@ -50,20 +50,20 @@
    {% endmacro %} -{% macro line_text_section(id, form_action, form_name, section_title, contents, below_text, placeholder_text, button_text, show_marseys, minlength, maxlength, pattern, show_if, disabled) %} +{% macro line_text_section(id, form_action, form_name, section_title, contents, below_text, placeholder_text, button_text, show_marseys, minlength, maxlength, pattern, show_if) %} {% if show_if -%}
    - +
    {% if show_marseys %}
    {% endif %} {{below_text}} - +
    diff --git a/files/templates/settings/css.html b/files/templates/settings/css.html index 9d3bbfeb8..ba1ffbac1 100644 --- a/files/templates/settings/css.html +++ b/files/templates/settings/css.html @@ -1,5 +1,5 @@ {% extends "settings.html" %} -{% block pagetitle %}Custom CSS{% endblock %} +{% block pagetitle %}Custom CSS - {{SITE_NAME}}{% endblock %} {% block content %}
    diff --git a/files/templates/settings/personal.html b/files/templates/settings/personal.html index f9ad5d342..02500537d 100644 --- a/files/templates/settings/personal.html +++ b/files/templates/settings/personal.html @@ -1,5 +1,6 @@ {% extends "settings.html" %} -{% block pagetitle %}Personal Settings{% endblock %} +{% block pagetitle %}Personal Settings - {{SITE_NAME}}{% endblock %} +{% import 'settings/common.html' as common with context %} {% block content %} - -{% include "awards.html" %} -{% if SITE_NAME == 'PCM' %} - {% include "awards_PCM.html" %} -{% endif %} -{% endblock %} {% set ups=p.upvotes %} {% set downs=p.downvotes %} {% set score=ups-downs %} @@ -31,6 +10,28 @@ {% endif %} {% set v_forbid_deleted = (p.deleted_utc != 0) and not (v and v.admin_level >= PERMS['POST_COMMENT_MODERATION']) and not (v and v.id == p.author_id) %} + +{% block title %} + + + +{% include "awards.html" %} +{% if SITE_NAME == 'PCM' %} + {% include "awards_PCM.html" %} +{% endif %} +{% if EVENT_AWARDS %} + {% include "event/awards.html" %} +{% endif %} + +{% endblock %} + +{% block pagetype %}thread{% endblock %} + {% block actionsModal %} {% if v %} @@ -89,10 +90,86 @@
    {% if p.active_flags(v) %} -
    +
    Reported by:
      {% for f in p.filtered_flags(v) %} @@ -135,9 +212,9 @@ {% if p.domain == "twitter.com" %} {{p.embed_url | safe}} {% if v and v.theme.split("_")[0] in ["light", "coffee", "4chan"] %} - + {% else %} - + {% endif %} {% elif p.domain in ['youtu.be','youtube.com'] and p.embed_url and p.embed_url.startswith('Cancel
      - +
    {% endif %} @@ -225,7 +302,7 @@
      - + {{p.comment_count}} @@ -258,10 +335,10 @@ {% else %}
      -
      +
      {{score}} -
      +
      {% endif %} @@ -307,7 +384,7 @@ {% else %} - + {% endif %} @@ -317,7 +394,7 @@ {% if v %} {% else %} - + {% endif %} @@ -367,9 +444,9 @@ - + -
      +
      {% else %}
      - +
      @@ -398,8 +475,8 @@
      Jump in the discussion.

      No email address required.

      @@ -459,7 +536,7 @@ {% if v %}

      This comment section is a ghost town...

      {% else %} -

      This comment section is a ghost town. Sign in

      +

      This comment section is a ghost town. Sign in

      {% endif %}
    @@ -489,26 +566,28 @@ {% endif %} - + {% if not p.replies %} {% include "comments.html" %} {% endif %} {% if success %} @@ -547,3 +626,10 @@ {% endif %} {% endblock %} + + +{% block music %} + {% if EVENT_MUSIC %} + {% include 'event/' + EVENT_MUSIC %} + {% endif %} +{% endblock %} diff --git a/files/templates/submission_listing.html b/files/templates/submission_listing.html index a406159e6..bffd74cc5 100644 --- a/files/templates/submission_listing.html +++ b/files/templates/submission_listing.html @@ -65,11 +65,11 @@ {% else %} -
    +
    {{score}} -
    +
    {% endif %} @@ -80,26 +80,26 @@ {% if not v_forbid_deleted %}
    {% if p.club and not (v and (v.paid_dues or v.id == p.author_id)) %} - post thumbnail + post thumnail {% elif not p.url %} - - post thumbnail + + post thumnail {% elif p.is_image %} - post thumbnail + post thumnail {% elif p.is_video or p.is_audio %} - post thumbnail + post thumnail {% elif p.is_youtube %} - post thumbnail + post thumnail {% else %} - post thumbnail + post thumnail {% endif %} @@ -111,13 +111,95 @@
    + +
    - + {% if p.club %}{{CC}}{% endif %} {% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}} @@ -131,7 +213,7 @@ {% if p.realbody(v, listing=True) %} {% endif %} - + {{p.comment_count}} @@ -143,7 +225,7 @@
    • - + {{p.comment_count}} @@ -188,13 +270,13 @@
    • {% else %}
    • - + {{score}} - +
    • @@ -246,7 +328,7 @@ {% if p.is_image and not p.over_18 and ((v and v.cardview) or (not v and CARD_VIEW)) %} @@ -340,7 +422,7 @@ {% endif %} {% endif %} - + {% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} diff --git a/files/templates/submit.html b/files/templates/submit.html index 67ae18674..42e268bd9 100644 --- a/files/templates/submit.html +++ b/files/templates/submit.html @@ -1,25 +1,32 @@ -{%- extends 'default.html' -%} -{% block pagetitle %}Create a Post{% endblock %} -{% block pagetype %}submit{% endblock %} -{% block template_config %} - {% set root_scope.js = true %} - {% set root_scope.include_user_css = true %} - {% set root_scope.include_seo = false %} - {% set root_scope.include_cf_2fa_verify = false %} -{% endblock %} -{% block banner %}{% endblock %} -{% block mobilenavbar %}{% endblock %} -{% block content %} +{%- import 'util/macros.html' as macros with context -%} +{%- import 'html_head.html' as html_head with context -%} + + +{{html_head.html_head(true, false, true, none, "Create a post", false)}} + + + {% include "header.html" %} + {% block form %} + +
      +
      +
      +
      +

      Create a post

      +
      + + +
      {%- set hole_placeholder = 'Required' if HOLE_REQUIRED else 'Optional' -%} @@ -28,14 +35,20 @@ {% endfor %} +
      + + + + +
      - + To post an image, use a direct image link such as i.imgur.com
      @@ -49,32 +62,44 @@ You can upload images, videos, or audio.
      + + +
      +

      +
      Toggle preview
      +   - + + +
      - + + +
      +
      +
      @@ -83,12 +108,14 @@
      + {% if FEATURES['COUNTRY_CLUB'] -%}
      {%- endif %} +
      {% if v.can_post_in_ghost_threads %} @@ -96,8 +123,11 @@ {% endif %}
      +
      +
      +
      @@ -109,18 +139,24 @@
      +
      +
      {% endblock %} + {% if request.path == '/submit' %} {% endif %} - - + + {% include "modals/emoji.html" %} {% include "modals/gif.html" %} -{% endblock %} + + + + diff --git a/files/templates/submit_hats.html b/files/templates/submit_hats.html index 1be920cbf..5d2e799d1 100644 --- a/files/templates/submit_hats.html +++ b/files/templates/submit_hats.html @@ -1,6 +1,11 @@ {% extends "default.html" %} -{% block pagetitle %}Submit Hats{% endblock %} + +{% block title %} +Submit Hats +{% endblock %} + {% block pagetype %}message{% endblock %} + {% block content %} {% if error %}