From 83c3f2d29651ac509e75a0986dc655406e757aca Mon Sep 17 00:00:00 2001 From: Alexey Date: Tue, 21 Apr 2026 09:31:11 +0500 Subject: [PATCH] Refresh Blue Marble UI --- dist/BlueMarble-For-GreasyFork.user.css | 809 +++++++++++++++++++++--- dist/BlueMarble-For-GreasyFork.user.js | 582 ++++++++--------- dist/BlueMarble-Standalone.user.js | 4 +- dist/BlueMarble.user.css | 4 +- dist/BlueMarble.user.js | 4 +- src/WindowFilter.css | 252 +++++++- src/WindowFilter.js | 82 ++- src/WindowMain.css | 173 +++++ src/WindowMain.js | 85 +-- src/apiManager.js | 123 ++-- src/main.css | 1 + src/main.js | 41 +- src/overlay.css | 367 ++++++++--- 13 files changed, 1889 insertions(+), 638 deletions(-) create mode 100644 src/WindowMain.css diff --git a/dist/BlueMarble-For-GreasyFork.user.css b/dist/BlueMarble-For-GreasyFork.user.css index 6accc48..e7dc47f 100644 --- a/dist/BlueMarble-For-GreasyFork.user.css +++ b/dist/BlueMarble-For-GreasyFork.user.css @@ -35,36 +35,141 @@ confetti-piece { border: 0; } .bm-window { + --bm-surface-strong: rgba(9, 20, 42, 0.5); + --bm-surface-soft: rgba(24, 41, 74, 0.28); + --bm-surface-glass: rgba(255, 255, 255, 0.1); + --bm-surface-glass-strong: rgba(255, 255, 255, 0.18); + --bm-border-soft: rgba(255, 255, 255, 0.18); + --bm-border-strong: rgba(163, 228, 255, 0.34); + --bm-text-primary: rgba(17, 36, 66, 0.96); + --bm-text-secondary: rgba(36, 57, 90, 0.84); + --bm-accent-start: #baf6ff; + --bm-accent-end: #81b6ff; + --bm-accent-shadow: rgba(132, 182, 255, 0.22); + --bm-font-body: + "Rajdhani", + "Segoe UI Variable Text", + "Segoe UI", + sans-serif; + --bm-font-display: + "Michroma", + "Orbitron", + "Segoe UI", + sans-serif; + --bm-font-mono: + "Roboto Mono", + "Rajdhani", + "Courier New", + monospace; position: fixed; - background-color: rgba(21, 48, 99, 0.9); - color: white; - padding: 10px; - border-radius: 8px; + isolation: isolate; + overflow: hidden; + background: + radial-gradient( + circle at 14% 12%, + rgba(255, 255, 255, 0.24), + transparent 18%), + radial-gradient( + circle at 86% 8%, + rgba(186, 246, 255, 0.22), + transparent 24%), + radial-gradient( + circle at 82% 84%, + rgba(129, 182, 255, 0.18), + transparent 28%), + linear-gradient( + 145deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.06) 22%, + rgba(105, 145, 212, 0.08) 54%, + rgba(9, 20, 42, 0.18)); + color: var(--bm-text-primary); + padding: 6px; + border-radius: 16px; + border: 1px solid var(--bm-border-soft); + box-shadow: + 0 18px 40px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.22), + inset 0 -1px 0 rgba(255, 255, 255, 0.05); z-index: 9000; - transition: all 0.3s ease, transform 0s; + transition: + background 320ms ease, + border-color 220ms ease, + box-shadow 220ms ease, + opacity 220ms ease, + transform 0s, + width 220ms ease, + max-width 220ms ease, + max-height 220ms ease; top: 75px; left: 60px; width: auto; max-height: fit-content; max-width: calc(100% - 135px); - font-family: - "Roboto Mono", - "Courier New", - "Monaco", - "DejaVu Sans Mono", - monospace, - "Arial"; - letter-spacing: 0.05em; + backdrop-filter: blur(26px) saturate(1.25); + font-family: var(--bm-font-body); + letter-spacing: 0.04em; +} +.bm-window::before, +.bm-window::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; +} +.bm-window::before { + border-radius: inherit; + padding: 1px; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.45), + rgba(255, 255, 255, 0.12) 24%, + rgba(186, 246, 255, 0.22) 58%, + rgba(129, 182, 255, 0.3)); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + opacity: 0.85; +} +.bm-window::after { + border-radius: inherit; + background: + linear-gradient( + 180deg, + rgba(255, 255, 255, 0.2), + transparent 24%), + radial-gradient( + circle at 18% 0%, + rgba(255, 255, 255, 0.22), + transparent 22%), + radial-gradient( + circle at 88% 16%, + rgba(186, 246, 255, 0.18), + transparent 18%); + opacity: 1; } .bm-dragbar { display: grid; grid-template-columns: auto 1fr auto; align-items: center; - gap: 0.5ch; - background: url('data:image/svg+xml;utf8,') repeat; + gap: 0.28ch; + padding: 0.18rem 0.24rem; + border-radius: 10px; + border: 1px solid rgba(255, 255, 255, 0.16); + background: + radial-gradient( + circle at 0 0, + rgba(255, 255, 255, 0.22) 0, + transparent 42%), + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.08)); cursor: grab; width: 100%; height: fit-content; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 6px 18px rgba(0, 0, 0, 0.1); } .bm-dragbar.bm-dragging { cursor: grabbing; @@ -81,46 +186,75 @@ confetti-piece { } .bm-favicon { display: inline-block; - height: 2.5em; - margin-right: 1ch; + height: 2.2em; + margin-right: 0.45ch; + padding: 0.2rem; + border-radius: 12px; vertical-align: middle; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.22), + rgba(255, 255, 255, 0.08)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 18px rgba(0, 0, 0, 0.12); } .bm-window h1 { display: inline-block; - font-size: x-large; - font-weight: bold; + font-size: 1rem; + font-weight: 700; vertical-align: middle; + font-family: var(--bm-font-display); + text-transform: uppercase; + letter-spacing: 0.14em; + color: rgba(16, 33, 60, 0.96); } .bm-dragbar h1, .bm-dragbar-text { - font-size: 1.2em; + font-size: 0.78rem; user-select: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - text-shadow: - 3px 0px rgba(21, 48, 99, 0.5), - -3px 0px rgba(21, 48, 99, 0.5), - 0px 3px rgba(21, 48, 99, 0.5), - 0px -3px rgba(21, 48, 99, 0.5), - 3px 3px rgba(21, 48, 99, 0.5), - -3px 3px rgba(21, 48, 99, 0.5), - 3px -3px rgba(21, 48, 99, 0.5), - -3px -3px rgba(21, 48, 99, 0.5); + font-family: var(--bm-font-display); + letter-spacing: 0.14em; + color: rgba(18, 37, 66, 0.95); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.28); } .bm-dragbar div:has(h1) { display: contents; } .bm-window h2 { display: inline-block; - font-size: larger; + font-size: 0.88rem; font-weight: 700; vertical-align: middle; + font-family: var(--bm-font-display); + letter-spacing: 0.1em; + color: rgba(18, 35, 64, 0.96); } .bm-window h3 { display: inline-block; font-size: large; font-weight: 700; + font-family: var(--bm-font-display); + letter-spacing: 0.08em; + color: rgba(18, 35, 64, 0.96); +} +.bm-window p { + color: var(--bm-text-secondary); + line-height: 1.5; + letter-spacing: 0.035em; +} +.bm-window hr { + border: none; + height: 1px; + margin: 0.32rem 0; + background: + linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.28), + transparent); } .bm-container.bm-center-vertically { width: fit-content; @@ -128,34 +262,133 @@ confetti-piece { margin-right: auto; } .bm-container { - margin: 0.5em 0; + margin: 0.24em 0; +} +.bm-window input, +.bm-window select, +.bm-window textarea, +.bm-window button { + font: inherit; } .bm-window button { - background-color: #144eb9; - border-radius: 1em; - padding: 0 0.75ch; + appearance: none; + color: var(--bm-text-primary); + font-family: var(--bm-font-display); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.22), + rgba(164, 208, 255, 0.14)); + border: 1px solid rgba(255, 255, 255, 0.22); + border-radius: 999px; + padding: 0.28em 0.62em; + min-height: 1.78em; + font-weight: 600; + letter-spacing: 0.1em; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 8px 20px rgba(0, 0, 0, 0.1); + transition: + background 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease, + filter 180ms ease, + opacity 180ms ease, + transform 180ms ease; } .bm-window button:hover, .bm-window button:focus-visible { - background-color: #1061e5; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.28), + rgba(186, 246, 255, 0.18)); + border-color: rgba(230, 245, 255, 0.36); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.26), 0 10px 22px rgba(0, 0, 0, 0.12); + transform: translateY(-1px); } -.bm-window button:active, -.bm-window button:disabled { - background-color: #2e97ff; +.bm-window button:focus-visible, +.bm-window input:focus-visible, +.bm-window select:focus-visible, +.bm-window textarea:focus-visible { + outline: none; + border-color: rgba(116, 231, 255, 0.62); + box-shadow: 0 0 0 3px rgba(116, 231, 255, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.12); +} +.bm-window button:active { + transform: translateY(0) scale(0.98); + filter: brightness(0.98); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 8px 16px rgba(18, 36, 78, 0.24); } -.bm-window button:disabled, .bm-window button:disabled { - text-decoration: line-through; + opacity: 0.56; cursor: not-allowed; + text-decoration: none; + transform: none; + filter: saturate(0.72); + box-shadow: none; +} +.bm-window button.bm-button-primary { + color: #07203b; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.42), + rgba(186, 246, 255, 0.34)); + border-color: rgba(239, 248, 255, 0.42); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.44), 0 10px 22px rgba(129, 182, 255, 0.14); +} +.bm-window button.bm-button-primary:hover, +.bm-window button.bm-button-primary:focus-visible { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.52), + rgba(204, 250, 255, 0.36)); +} +.bm-window button.bm-button-secondary { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.16), + rgba(255, 255, 255, 0.08)); + border-color: rgba(255, 255, 255, 0.18); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 8px 20px rgba(0, 0, 0, 0.08); +} +.bm-window button.bm-button-secondary:hover, +.bm-window button.bm-button-secondary:focus-visible { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.24), + rgba(186, 246, 255, 0.12)); } .bm-button-circle { - border: white 1px solid; - height: 1.5em; - width: 1.5em; - margin-top: 2px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid rgba(255, 255, 255, 0.16); + inline-size: 1.62rem; + block-size: 1.62rem; + min-height: 1.62rem !important; + min-width: 1.62rem; + margin-top: 0; text-align: center; - line-height: 1em; + line-height: 1; padding: 0 !important; + aspect-ratio: 1 / 1; + border-radius: 50% !important; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.24), + rgba(255, 255, 255, 0.1)) !important; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 8px 18px rgba(0, 0, 0, 0.1) !important; + overflow: hidden; + flex: 0 0 auto; + font-size: 0.74rem; +} +.bm-button-circle svg { + width: 70%; + height: 70%; } .bm-button-pin { vertical-align: middle; @@ -166,29 +399,44 @@ confetti-piece { fill: #111; } .bm-window button.bm-button-trans { - background-color: unset; + background: transparent !important; + box-shadow: none !important; + border-color: transparent !important; } .bm-button-trans.bm-button-hover-white:hover, .bm-button-trans.bm-button-hover-white:focus { - background-color: rgba(255, 255, 255, 0.17); + background-color: rgba(255, 255, 255, 0.18) !important; } .bm-button-trans.bm-button-hover-white:active { - background-color: rgba(255, 255, 255, 0.22); + background-color: rgba(255, 255, 255, 0.24) !important; } .bm-button-trans.bm-button-hover-black:hover, .bm-button-trans.bm-button-hover-black:focus { - background-color: rgba(0, 0, 0, 0.17); + background-color: rgba(0, 0, 0, 0.14) !important; } .bm-button-trans.bm-button-hover-black:active { - background-color: rgba(0, 0, 0, 0.22); + background-color: rgba(0, 0, 0, 0.2) !important; +} +.bm-window input[type=number], +.bm-window select, +.bm-window textarea { + color: var(--bm-text-primary); + font-family: var(--bm-font-body); + background: + linear-gradient( + 180deg, + rgba(255, 255, 255, 0.16), + rgba(255, 255, 255, 0.06)); + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 12px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12); } input[type=number].bm-input-coords { appearance: auto; -moz-appearance: textfield; - width: 5.5ch; + width: 5.9ch; margin-left: 1ch; - background-color: rgba(0, 0, 0, 0.2); - padding: 0 0.5ch; + padding: 0.2em 0.35ch; font-size: small; } input[type=number].bm-input-coords::-webkit-outer-spin-button, @@ -216,18 +464,18 @@ input[type=file] { pointer-events: none !important; } .bm-window select { - color: white; - background-color: #144eb9; - border-radius: 1em; - padding: 0 0.5ch; + padding: 0.22em 0.45ch; } .bm-window label:has(input[type=checkbox]) { display: flex; width: fit-content; gap: 1ch; + align-items: center; + color: var(--bm-text-secondary); } .bm-window input[type=checkbox] { width: 1em; + accent-color: #74e7ff; } .bm-window-content { overflow: hidden; @@ -236,17 +484,26 @@ input[type=file] { } .bm-window textarea { font-size: small; - background-color: rgba(0, 0, 0, 0.2); - padding: 0 0.5ch; - height: 5.25em; + padding: 0.38em 0.52em; + height: 4em; width: 100%; + resize: vertical; + line-height: 1.45; +} +.bm-window textarea::placeholder, +.bm-window input::placeholder { + color: rgba(47, 68, 102, 0.6); } .bm-window a:not(:has(*)) { + color: rgba(21, 88, 164, 0.94); text-decoration: underline; + text-decoration-color: rgba(21, 88, 164, 0.35); } .bm-window small { font-size: x-small; - color: lightgray; + font-family: var(--bm-font-display); + letter-spacing: 0.12em; + color: var(--bm-text-secondary); } .bm-window ul li { list-style: disc; @@ -255,20 +512,40 @@ input[type=file] { .bm-window .bm-container.bm-scrollable { max-height: var(--bm-scrollable-max-height, calc(80vh - 150px)); overflow: auto; + scrollbar-width: thin; + scrollbar-color: rgba(146, 221, 255, 0.42) rgba(255, 255, 255, 0.05); +} +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar { + width: 10px; + height: 10px; +} +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar-thumb { + background: + linear-gradient( + 180deg, + rgba(116, 231, 255, 0.48), + rgba(83, 141, 255, 0.4)); + border-radius: 999px; + border: 2px solid transparent; + background-clip: padding-box; +} +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.04); + border-radius: 999px; } .bm-flex-between { display: flex; align-content: center; justify-content: space-between; align-items: center; - gap: 0.5ch; + gap: 0.35ch; } .bm-flex-center { display: flex; align-content: center; justify-content: center; align-items: center; - gap: 0.5ch; + gap: 0.35ch; } .bm-ascii { white-space: pre; @@ -278,8 +555,8 @@ input[type=file] { font-family: monospace; } .bm-windowed .bm-container:not(#bm-window-main .bm-container) { - margin-top: 0.25em; - margin-bottom: 0.25em; + margin-top: 0.18em; + margin-bottom: 0.18em; } .bm-windowed h1:not(#bm-window-main h1) { font-size: 1em; @@ -291,32 +568,150 @@ input[type=file] { height: 1em; fill: white; } +#bm-window-filter:not(.bm-windowed) { + width: min(50rem, calc(100vw - 0.55rem)); + max-width: min(50rem, calc(100vw - 0.55rem)) !important; +} +#bm-window-filter .bm-filter-header { + padding-top: 0.08rem; +} +#bm-window-filter .bm-filter-toolbar { + gap: 0.22rem; + flex-wrap: wrap; + width: 100%; + padding: 0.16rem; +} +#bm-window-filter .bm-filter-toolbar > button { + flex: 1 1 10rem; +} +#bm-window-filter .bm-filter-scrollable { + padding-right: 0.08rem; +} +#bm-window-filter .bm-filter-insights { + display: grid; + grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr); + gap: 0.24rem 0.3rem; + align-items: stretch; +} +#bm-window-filter .bm-filter-insights > hr, +#bm-window-filter .bm-filter-sort-panel { + grid-column: 1 / -1; +} +#bm-window-filter .bm-filter-stats-card, +#bm-window-filter .bm-filter-note, +#bm-window-filter .bm-filter-sort-panel { + padding: 0.38rem 0.48rem; + border-radius: 13px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: + linear-gradient( + 155deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.07)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 20px rgba(0, 0, 0, 0.08); +} +#bm-window-filter .bm-filter-stats-card { + display: grid; + gap: 0.18rem; +} +#bm-window-filter .bm-filter-stats-card br { + display: none; +} +#bm-window-filter .bm-filter-stats-card span { + display: block; + padding: 0.28rem 0.38rem; + border-radius: 10px; + background: + linear-gradient( + 180deg, + rgba(255, 255, 255, 0.2), + rgba(255, 255, 255, 0.08)); +} +#bm-window-filter .bm-filter-note p { + margin: 0; +} +#bm-window-filter .bm-filter-sort-panel fieldset { + border: none; + padding: 0; + margin: 0; +} +#bm-window-filter .bm-filter-sort-panel legend { + margin-bottom: 0.12rem; +} +#bm-window-filter .bm-filter-sort-panel .bm-container { + margin-top: 0.1rem; + margin-bottom: 0.1rem; +} +#bm-window-filter .bm-filter-sort-actions { + display: flex; + justify-content: flex-start; +} +#bm-window-filter .bm-filter-sort-actions button { + min-width: 7.8rem; +} #bm-filter-flex { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; - gap: 1em 3ch; + align-items: stretch; + gap: 0.3rem; } #bm-window-filter .bm-filter-color { + position: relative; + overflow: hidden; width: fit-content; max-width: 35ch; - background-color: rgba(21, 48, 99, 0.9); - border-radius: 1em; - padding: 0.5em; - gap: 1ch; - transition: background-color 0.3s ease; + padding: 0.28rem; + gap: 0.28rem; + border-radius: 13px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: + linear-gradient( + 160deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.07)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 20px rgba(0, 0, 0, 0.08); + transition: + background 0.25s ease, + border-color 0.25s ease, + box-shadow 0.25s ease, + transform 0.25s ease; +} +#bm-window-filter .bm-filter-color::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient( + circle at top right, + rgba(255, 255, 255, 0.18), + transparent 24%), + radial-gradient( + circle at 18% 0%, + rgba(186, 246, 255, 0.12), + transparent 22%); } #bm-window-filter .bm-filter-color:hover, -#bm-window-filter.bm-filter-color:focus-within { - background-color: rgba(17, 40, 85, 0.9); +#bm-window-filter .bm-filter-color:focus-within { + transform: translateY(-2px); + border-color: rgba(146, 221, 255, 0.26); + background: + linear-gradient( + 160deg, + rgba(255, 255, 255, 0.22), + rgba(186, 246, 255, 0.1)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 10px 24px rgba(0, 0, 0, 0.1); } #bm-window-filter .bm-filter-container-rgb { display: block; - border: thick double darkslategray; width: fit-content; height: fit-content; - padding: 1ch; + padding: 0.26rem; + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 10px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 6px 16px rgba(0, 0, 0, 0.08); } #bm-window-filter .bm-filter-color[data-id="-2"] .bm-filter-container-rgb { background: @@ -340,7 +735,7 @@ input[type=file] { background-color: transparent !important; } #bm-window-filter .bm-filter-container-rgb button { - padding: 0.75em 0.5ch; + padding: 0.26em 0.14ch; } #bm-window-filter .bm-filter-container-rgb svg { width: 4ch; @@ -348,7 +743,13 @@ input[type=file] { #bm-window-filter .bm-filter-color > .bm-flex-between { flex-direction: column; align-items: flex-start; - gap: 0; + gap: 0.02rem; +} +#bm-window-filter .bm-filter-color h2 { + margin: 0.04rem 0 0; +} +#bm-window-filter .bm-filter-color .bm-filter-color-pxl-desc { + margin: 0.1rem 0 0; } #bm-window-filter .bm-filter-color small { font-size: 0.75em; @@ -360,29 +761,43 @@ input[type=file] { --bm-scrollable-max-height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); - width: 300px; - height: min(70vh, 32rem); - min-width: 260px; - min-height: 220px; + width: 268px; + height: min(60vh, 22rem); + min-width: 228px; + min-height: 180px; max-width: min(1000px, calc(100vw - 16px)) !important; max-height: min(1400px, calc(100vh - 16px)) !important; overflow: hidden; box-sizing: border-box; position: fixed; - transition: transform 0s; + transition: + background 320ms ease, + border-color 220ms ease, + box-shadow 220ms ease, + transform 0s; } #bm-window-filter.bm-windowed .bm-window-content { display: grid; - grid-template-rows: auto auto auto minmax(0, 1fr); + grid-template-rows: auto auto auto auto minmax(0, 1fr); grid-row: 2; min-height: 0; min-width: 0; overflow: hidden; } +#bm-window-filter.bm-windowed .bm-filter-toolbar { + gap: 0.16rem; + flex-wrap: nowrap; + width: 100%; + padding: 0.12rem; +} +#bm-window-filter.bm-windowed .bm-filter-toolbar > button { + flex: 1 1 0; + min-width: 0; +} #bm-window-filter.bm-windowed #bm-filter-flex { flex-direction: column; align-items: stretch; - gap: 0.25em; + gap: 0.16rem; width: 100%; align-self: stretch; min-width: 0; @@ -395,7 +810,8 @@ input[type=file] { flex: 1 1 auto; min-width: 0; margin: 0; - padding: 0; + padding: 0.12rem; + border-radius: 11px; box-sizing: border-box; } #bm-window-filter.bm-windowed .bm-filter-color > .bm-flex-between { @@ -405,7 +821,7 @@ input[type=file] { } #bm-window-filter.bm-windowed .bm-container.bm-scrollable { display: block; - grid-row: 4; + grid-row: 5; min-height: 0; min-width: 0; height: 100%; @@ -416,24 +832,37 @@ input[type=file] { } #bm-window-filter.bm-windowed .bm-resize-corner { position: absolute; - right: 0; - bottom: 0; - display: block; - width: 28px; - height: 28px; + right: 4px; + bottom: 4px; + display: flex; + width: 20px; + height: 20px; + align-items: flex-end; + justify-content: flex-end; + padding-right: 4px; + padding-bottom: 4px; + box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; - opacity: 1; + opacity: 0.78; touch-action: none; user-select: none; - background: transparent; - border: none; - box-shadow: none; + color: rgba(255, 255, 255, 0.86); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.14), + rgba(83, 141, 255, 0.14)); + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 8px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); } #bm-window-filter.bm-windowed .bm-resize-corner:hover, #bm-window-filter.bm-windowed .bm-resize-corner.bm-resizing { opacity: 1; + border-color: rgba(146, 221, 255, 0.36); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 8px 16px rgba(0, 0, 0, 0.16); } #bm-window-filter.bm-windowed .bm-filter-container-rgb { display: flex; @@ -442,28 +871,206 @@ input[type=file] { flex: 1 1 auto; gap: 0.5ch; align-items: center; - padding: 0.1em 0.5ch; + padding: 0.1rem 0.2rem; border: none; - border-radius: 1em; + border-radius: 8px; box-sizing: border-box; } #bm-window-filter.bm-windowed .bm-filter-container-rgb button { - padding: 0.5em 0.25ch; + padding: 0.2em 0.1ch; flex: 0 0 auto; } #bm-window-filter.bm-windowed .bm-filter-container-rgb svg { - width: 3ch; + width: 2.7ch; } #bm-window-filter.bm-windowed .bm-filter-color h2 { - font-size: 0.75em; + font-size: 0.78rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } #bm-window-filter #bm-filter-windowed-color-totals { + display: inline-flex; + align-items: center; + padding: 0.08rem 0.24rem; + border-radius: 999px; + background: rgba(255, 255, 255, 0.12); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); font-size: 1em; } +@media (max-width: 980px) { + #bm-window-filter:not(.bm-windowed) { + width: min(100vw - 0.35rem, 50rem); + max-width: min(100vw - 0.35rem, 50rem) !important; + } + #bm-window-filter .bm-filter-insights { + grid-template-columns: 1fr; + } + #bm-window-filter .bm-filter-note, + #bm-window-filter .bm-filter-sort-panel, + #bm-window-filter .bm-filter-insights > hr { + grid-column: auto; + } +} + +/* src/WindowMain.css */ +#bm-window-main { + width: min(25.5rem, calc(100vw - 0.65rem)); + max-width: min(25.5rem, calc(100vw - 0.65rem)) !important; +} +#bm-window-main .bm-window-content { + display: flex; + flex-direction: column; +} +#bm-window-main .bm-main-hero, +#bm-window-main .bm-main-shell { + position: relative; + overflow: hidden; + border-radius: 14px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: + linear-gradient( + 150deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.08)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 10px 24px rgba(0, 0, 0, 0.1); +} +#bm-window-main .bm-main-hero::before, +#bm-window-main .bm-main-shell::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient( + circle at top right, + rgba(255, 255, 255, 0.2), + transparent 26%), + radial-gradient( + circle at 20% 0%, + rgba(186, 246, 255, 0.16), + transparent 24%); +} +#bm-window-main .bm-main-hero { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.48rem 0.58rem; +} +#bm-window-main .bm-main-hero h1 { + margin: 0; +} +#bm-window-main .bm-main-stats { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.24rem; +} +#bm-window-main .bm-main-stat-card { + min-width: 0; + min-height: 2.55rem; + display: flex; + align-items: flex-start; + padding: 0.34rem 0.45rem; + border-radius: 11px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: + linear-gradient( + 160deg, + rgba(255, 255, 255, 0.18), + rgba(255, 255, 255, 0.07)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16); + color: rgba(18, 35, 63, 0.96); + line-height: 1.22; +} +#bm-window-main .bm-main-stat-card > span, +#bm-window-main .bm-main-stat-card > time { + min-width: 0; +} +#bm-window-main .bm-main-stat-card-value, +#bm-window-main .bm-main-stat-card-timer { + flex-direction: column; + justify-content: center; + gap: 0.08rem; +} +#bm-window-main .bm-main-stat-value { + display: inline-block; + font-size: 1.3em; + color: rgba(15, 31, 56, 0.96); + white-space: normal; + overflow-wrap: anywhere; +} +#bm-window-main .bm-main-stat-value b { + font-size: 1em; +} +#bm-window-main .bm-main-stat-label { + color: rgba(49, 71, 105, 0.82); + font-size: 0.62rem; + letter-spacing: 0.08em; + font-family: var(--bm-font-display); + text-transform: uppercase; +} +#bm-window-main .bm-main-stat-card time { + white-space: nowrap; + font-family: var(--bm-font-mono); + letter-spacing: 0.06em; +} +#bm-window-main .bm-main-shell { + padding: 0.48rem; +} +#bm-window-main .bm-main-coords { + display: grid; + grid-template-columns: auto repeat(4, minmax(0, 1fr)); + gap: 0.22rem; + align-items: center; +} +#bm-window-main .bm-main-coords .bm-button-pin { + width: 1.8rem; + height: 1.8rem; +} +#bm-window-main .bm-main-coords .bm-input-coords { + width: 100%; + margin-left: 0; + text-align: center; +} +#bm-window-main .bm-main-upload, +#bm-window-main .bm-main-status { + margin-top: 0.24rem; +} +#bm-window-main .bm-main-upload > div { + width: 100%; +} +#bm-window-main .bm-main-actions { + gap: 0.24rem; + margin-top: 0.3rem; +} +#bm-window-main .bm-main-actions > button { + flex: 1 1 0; +} +#bm-window-main .bm-main-status textarea { + min-height: 4.1rem; +} +@media (max-width: 720px) { + #bm-window-main { + width: min(100vw - 0.45rem, 25.5rem); + max-width: min(100vw - 0.45rem, 25.5rem) !important; + } + #bm-window-main .bm-main-stats { + grid-template-columns: 1fr; + } + #bm-window-main .bm-main-coords { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + #bm-window-main .bm-main-coords .bm-button-pin { + grid-column: 1 / -1; + width: 100%; + aspect-ratio: auto; + height: 1.8rem; + } + #bm-window-main .bm-main-actions { + flex-direction: column; + } +} /* src/WindowSettings.css */ #bm-window-settings div:has(> .bm-highlight-preset-container) { @@ -554,4 +1161,4 @@ input[type=file] { /* src/main.css */ -/* Build Hash: 4336138174a3 */ +/* Build Hash: 974f8e45028a */ diff --git a/dist/BlueMarble-For-GreasyFork.user.js b/dist/BlueMarble-For-GreasyFork.user.js index d77e574..3a2eff5 100644 --- a/dist/BlueMarble-For-GreasyFork.user.js +++ b/dist/BlueMarble-For-GreasyFork.user.js @@ -2300,65 +2300,8 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; customElements.define("confetti-piece", BlueMarbleConfettiPiece); - // src/WindowCredits.js - var WindowCredts = class extends Overlay { - /** Constructor for the Credits window - * @param {string} name - The name of the userscript - * @param {string} version - The version of the userscript - * @since 0.90.9 - * @see {@link Overlay#constructor} for examples - */ - constructor(name2, version2) { - super(name2, version2); - this.window = null; - this.windowID = "bm-window-credits"; - this.windowParent = document.body; - } - /** Spawns a Credits window. - * If another credits window already exists, we DON'T spawn another! - * Parent/child relationships in the DOM structure below are indicated by indentation. - * @since 0.90.9 - */ - buildWindow() { - const ascii = ` -\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 -\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D -\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 -\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D -\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 -\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D - -\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 -\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D -\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 -\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D -\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 -\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D -`; - if (document.querySelector(`#${this.windowID}`)) { - document.querySelector(`#${this.windowID}`).remove(); - return; - } - this.window = this.addDiv({ "id": this.windowID, "class": "bm-window" }, (instance, div) => { - }).addDragbar().addButton({ "class": "bm-button-circle", "textContent": "\u25BC", "aria-label": 'Minimize window "Credits"', "data-button-status": "expanded" }, (instance, button) => { - button.onclick = () => instance.handleMinimization(button); - button.ontouchend = () => { - button.click(); - }; - }).buildElement().addDiv().buildElement().addButton({ "class": "bm-button-circle", "textContent": "\u2716", "aria-label": 'Close window "Credits"' }, (instance, button) => { - button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); - }; - button.ontouchend = () => { - button.click(); - }; - }).buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically" }).addHeader(1, { "textContent": "Credits" }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-scrollable" }).addSpan({ "role": "img", "aria-label": this.name }).addSpan({ "innerHTML": ascii, "class": "bm-ascii", "aria-hidden": "true" }).buildElement().buildElement().addBr().buildElement().addHr().buildElement().addBr().buildElement().addSpan({ "textContent": '"Blue Marble" userscript is made by SwingTheVine.' }).buildElement().addBr().buildElement().addSpan({ "innerHTML": 'The Blue Marble Website is made by crqch.' }).buildElement().addBr().buildElement().addSpan({ "textContent": `The Blue Marble Website used until ${localizeDate(new Date(1756069320 * 1e3))} was made by Camille Daguin.` }).buildElement().addBr().buildElement().addSpan({ "textContent": 'The favicon "Blue Marble" is owned by NASA. (The image of the Earth is owned by NASA)' }).buildElement().addBr().buildElement().addSpan({ "textContent": "Special Thanks:" }).buildElement().addUl().addLi({ "textContent": "Espresso, Meqa, and Robot for moderating SwingTheVine's community." }).buildElement().addLi({ "innerHTML": 'nof, darkness for creating similar userscripts!' }).buildElement().addLi({ "innerHTML": 'Wonda for the Blue Marble banner image!' }).buildElement().addLi({ "innerHTML": 'BullStein, allanf181 for being early beta testers!' }).buildElement().addLi({ "innerHTML": 'guidu_ and Nick-machado for the original "Minimize" Button code!' }).buildElement().addLi({ "innerHTML": 'Nomad and Gustav for the tutorials!' }).buildElement().addLi({ "innerHTML": 'cfp for creating the template overlay that Blue Marble was based on!' }).buildElement().addLi({ "innerHTML": 'Force Network for hosting the telemetry server!' }).buildElement().addLi({ "innerHTML": 'TheBlueCorner for getting me interested in online pixel canvases!' }).buildElement().buildElement().addBr().buildElement().addSpan({ "innerHTML": 'Donators:' }).buildElement().addUl().addLi({ "textContent": "Soultree" }).buildElement().addLi({ "textContent": "Espresso" }).buildElement().addLi({ "textContent": "BEST FAN" }).buildElement().addLi({ "textContent": "FuchsDresden" }).buildElement().addLi({ "textContent": "Jack" }).buildElement().addLi({ "textContent": "raiken_au" }).buildElement().addLi({ "textContent": "Jacob" }).buildElement().addLi({ "textContent": "StupidOne" }).buildElement().addLi({ "textContent": "2 Anonymous Supporters" }).buildElement().buildElement().buildElement().buildElement().buildElement().buildOverlay(this.windowParent); - this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`); - } - }; - // src/WindowFilter.js - var _WindowFilter_instances, getWindowState_fn, prefersWindowedMode_fn, setWindowModePreference_fn, syncSortFormControls_fn, closeWindow_fn, cleanupWindowPersistence_fn, clampWindowDimension_fn, clampWindowPosition_fn, restoreWindowState_fn, saveWindowState_fn, scheduleWindowStateSave_fn, initializeWindowedPersistence_fn, buildColorList_fn, sortColorList_fn, selectColorList_fn, calculatePixelStatistics_fn; + var _WindowFilter_instances, getWindowState_fn, prefersWindowedMode_fn, setWindowModePreference_fn, syncSortFormControls_fn, closeWindow_fn, startAutoRefresh_fn, stopAutoRefresh_fn, cleanupWindowPersistence_fn, clampWindowDimension_fn, clampWindowPosition_fn, restoreWindowState_fn, saveWindowState_fn, scheduleWindowStateSave_fn, initializeWindowedPersistence_fn, buildColorList_fn, sortColorList_fn, selectColorList_fn, calculatePixelStatistics_fn; var WindowFilter = class extends Overlay { /** Constructor for the color filter window * @param {*} executor - The executing class @@ -2378,6 +2321,8 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); this.windowResizeObserver = null; this.windowViewportResizeHandler = null; this.windowSaveTimeout = null; + this.colorRefreshInterval = null; + this.colorRefreshIntervalMS = 1e4; this.windowMinWidth = 260; this.windowMinHeight = 220; this.windowMaxWidth = 1e3; @@ -2439,17 +2384,11 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); button.ontouchend = () => { button.click(); }; - }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically" }).addHeader(1, { "textContent": "Color Filter" }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-flex-between bm-center-vertically", "style": "gap: 1.5ch;" }).addButton({ "textContent": "Hide All Colors" }, (instance, button) => { + }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically bm-filter-header" }).addHeader(1, { "textContent": "Color Filter" }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-flex-between bm-center-vertically bm-filter-toolbar", "style": "gap: 1.5ch;" }).addButton({ "class": "bm-button-secondary", "textContent": "Hide All Colors" }, (instance, button) => { button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, false); - }).buildElement().addButton({ "textContent": "Refresh Data" }, (instance, button) => { - button.onclick = () => { - button.disabled = true; - this.updateColorList(); - button.disabled = false; - }; - }).buildElement().addButton({ "textContent": "Show All Colors" }, (instance, button) => { + }).buildElement().addButton({ "class": "bm-button-secondary", "textContent": "Show All Colors" }, (instance, button) => { button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, true); - }).buildElement().buildElement().addDiv({ "class": "bm-container bm-scrollable" }).addDiv({ "class": "bm-container", "style": "margin-left: 2.5ch; margin-right: 2.5ch;" }).addDiv({ "class": "bm-container" }).addSpan({ "id": "bm-filter-tile-load", "innerHTML": "Tiles Loaded: 0 / ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-correct", "innerHTML": "Correct Pixels: ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-total", "innerHTML": "Total Pixels: ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-remaining", "innerHTML": "Complete: ??? (???)" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-completed", "innerHTML": "??? ???" }).buildElement().buildElement().addDiv({ "class": "bm-container" }).addP({ "innerHTML": `Press the \u{1F5D7} button to make this window smaller. Colors with the icon ${this.eyeOpen.replace(" { + }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-scrollable bm-filter-scrollable" }).addDiv({ "class": "bm-container bm-filter-insights", "style": "margin-left: 2.5ch; margin-right: 2.5ch;" }).addDiv({ "class": "bm-container bm-filter-stats-card" }).addSpan({ "id": "bm-filter-tile-load", "innerHTML": "Tiles Loaded: 0 / ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-correct", "innerHTML": "Correct Pixels: ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-total", "innerHTML": "Total Pixels: ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-remaining", "innerHTML": "Complete: ??? (???)" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-completed", "innerHTML": "??? ???" }).buildElement().buildElement().addDiv({ "class": "bm-container bm-filter-note" }).addP({ "innerHTML": `Press the \u{1F5D7} button to make this window smaller. Colors with the icon ${this.eyeOpen.replace(" { button.onclick = (event) => { event.preventDefault(); const formData = new FormData(document.querySelector(`#${this.windowID} form`)); @@ -2471,6 +2410,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); this.updateInnerHTML("#bm-filter-tot-total", `Total Pixels: ${localizeNumber(this.allPixelsTotal)}`); this.updateInnerHTML("#bm-filter-tot-remaining", `Remaining: ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`); this.updateInnerHTML("#bm-filter-tot-completed", `Completed at: `); + __privateMethod(this, _WindowFilter_instances, startAutoRefresh_fn).call(this); } /** Spawns a windowed Color Filter window. * If another color filter window already exists, we DON'T spawn another! @@ -2511,17 +2451,11 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); button.ontouchend = () => { button.click(); }; - }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically" }).addHeader(1, { "textContent": "Color Filter" }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-flex-between bm-center-vertically", "style": "gap: 1.5ch;" }).addButton({ "textContent": "None" }, (instance, button) => { + }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically bm-filter-header" }).addHeader(1, { "textContent": "Color Filter" }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-flex-between bm-center-vertically bm-filter-toolbar", "style": "gap: 1.5ch;" }).addButton({ "class": "bm-button-secondary", "textContent": "None" }, (instance, button) => { button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, false); - }).buildElement().addButton({ "textContent": "Refresh" }, (instance, button) => { - button.onclick = () => { - button.disabled = true; - this.updateColorList(); - button.disabled = false; - }; - }).buildElement().addButton({ "textContent": "All" }, (instance, button) => { + }).buildElement().addButton({ "class": "bm-button-secondary", "textContent": "All" }, (instance, button) => { button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, true); - }).buildElement().buildElement().addDiv({ "class": "bm-container bm-scrollable" }).buildElement().buildElement().addDiv({ + }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-scrollable bm-filter-scrollable" }).buildElement().buildElement().addDiv({ "class": "bm-resize-corner", "title": "Resize Color Filter window", "aria-label": "Resize Color Filter window", @@ -2534,6 +2468,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); __privateMethod(this, _WindowFilter_instances, buildColorList_fn).call(this, scrollableContainer); __privateMethod(this, _WindowFilter_instances, syncSortFormControls_fn).call(this); __privateMethod(this, _WindowFilter_instances, sortColorList_fn).call(this, this.sortPrimary, this.sortSecondary, this.showUnused); + __privateMethod(this, _WindowFilter_instances, startAutoRefresh_fn).call(this); } /** The information about a specific color on the palette. * @typedef {Object} ColorData @@ -2584,6 +2519,11 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); const allTotal = this.allPixelsTotal.toString().length > 7 ? this.allPixelsTotal.toString().slice(0, 2) + "\u2026" + this.allPixelsTotal.toString().slice(-3) : this.allPixelsTotal.toString(); this.updateInnerHTML("#bm-filter-windowed-color-totals", `${allCorrect}/${allTotal}`, true); } + this.updateInnerHTML("#bm-filter-tile-load", `Tiles Loaded: ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`); + this.updateInnerHTML("#bm-filter-tot-correct", `Correct Pixels: ${localizeNumber(this.allPixelsCorrectTotal)}`); + this.updateInnerHTML("#bm-filter-tot-total", `Total Pixels: ${localizeNumber(this.allPixelsTotal)}`); + this.updateInnerHTML("#bm-filter-tot-remaining", `Remaining: ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`); + this.updateInnerHTML("#bm-filter-tot-completed", `Completed at: `); if (!colorList) { return colorStatistics; } @@ -2682,9 +2622,33 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); if (windowElement?.classList.contains("bm-windowed")) { __privateMethod(this, _WindowFilter_instances, saveWindowState_fn).call(this, windowElement); } + __privateMethod(this, _WindowFilter_instances, stopAutoRefresh_fn).call(this); __privateMethod(this, _WindowFilter_instances, cleanupWindowPersistence_fn).call(this); windowElement?.remove(); }; + /** Starts the automatic Color Filter statistics refresh loop. + * @since 0.92.1 + */ + startAutoRefresh_fn = function() { + __privateMethod(this, _WindowFilter_instances, stopAutoRefresh_fn).call(this); + this.colorRefreshInterval = setInterval(() => { + if (!document.querySelector(`#${this.windowID}`)) { + __privateMethod(this, _WindowFilter_instances, stopAutoRefresh_fn).call(this); + return; + } + this.updateColorList(); + }, this.colorRefreshIntervalMS); + }; + /** Stops the automatic Color Filter statistics refresh loop. + * @since 0.92.1 + */ + stopAutoRefresh_fn = function() { + if (!this.colorRefreshInterval) { + return; + } + clearInterval(this.colorRefreshInterval); + this.colorRefreshInterval = null; + }; /** Disconnects live observers used for window persistence. * @since 0.92.0 */ @@ -3051,6 +3015,164 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); this.timeRemainingLocalized = localizeDate(this.timeRemaining); }; + // src/WindowMain.js + var _WindowMain_instances, coordinateInputPaste_fn; + var WindowMain = class extends Overlay { + /** Constructor for the main Blue Marble window + * @param {string} name - The name of the userscript + * @param {string} version - The version of the userscript + * @since 0.88.326 + * @see {@link Overlay#constructor} + */ + constructor(name2, version2) { + super(name2, version2); + __privateAdd(this, _WindowMain_instances); + this.window = null; + this.windowID = "bm-window-main"; + this.windowParent = document.body; + } + /** Creates the main Blue Marble window. + * Parent/child relationships in the DOM structure below are indicated by indentation. + * @since 0.58.3 + */ + buildWindow() { + if (document.querySelector(`#${this.windowID}`)) { + this.handleDisplayError("Main window already exists!"); + return; + } + this.window = this.addDiv({ "id": this.windowID, "class": "bm-window bm-windowed", "style": "top: 10px; left: unset; right: 75px;" }, (instance, div) => { + }).addDragbar().addButton({ "class": "bm-button-circle", "textContent": "\u25BC", "aria-label": 'Minimize window "Blue Marble"', "data-button-status": "expanded" }, (instance, button) => { + button.onclick = () => instance.handleMinimization(button); + button.ontouchend = () => { + button.click(); + }; + }).buildElement().addDiv().buildElement().addDiv({ "class": "bm-flex-center" }).addButton({ "class": "bm-button-circle", "innerHTML": "\u2699\uFE0F", "title": "Settings" }, (instance, button) => { + button.onclick = () => { + instance.settingsManager.buildWindow(); + }; + }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-main-hero" }).addImg({ "class": "bm-favicon", "src": "https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png" }, (instance, img) => { + const date = /* @__PURE__ */ new Date(); + const dayOfTheYear = Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 1)) / (1e3 * 60 * 60 * 24)) + 1; + if (dayOfTheYear == 204) { + img.parentNode.style.position = "relative"; + img.parentNode.innerHTML = img.parentNode.innerHTML + ``; + img.onload = () => { + const confettiManager = new ConfettiManager(); + confettiManager.createConfetti(document.querySelector(`#${this.windowID}`)); + }; + } + }).buildElement().addHeader(1, { "textContent": this.name }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-main-stats" }).addDiv({ "class": "bm-main-stat-card bm-main-stat-card-value" }).addSpan({ "class": "bm-main-stat-label", "textContent": "Droplets" }).buildElement().addSpan({ "id": "bm-user-droplets", "class": "bm-main-stat-value", "textContent": "0" }).buildElement().buildElement().addDiv({ "class": "bm-main-stat-card bm-main-stat-card-value" }).addSpan({ "class": "bm-main-stat-label", "textContent": "Next Level" }).buildElement().addSpan({ "id": "bm-user-nextlevel", "class": "bm-main-stat-value", "textContent": "0 px" }).buildElement().buildElement().addDiv({ "class": "bm-main-stat-card bm-main-stat-card-timer" }).addSpan({ "class": "bm-main-stat-label", "textContent": "Charges" }).buildElement().addTimer(Date.now(), 1e3, { "class": "bm-main-stat-value", "style": "font-weight: 700;" }, (instance, timer) => { + instance.apiManager.chargeRefillTimerID = timer.id; + }).buildElement().buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-main-shell" }).addDiv({ "class": "bm-container bm-main-coords" }).addButton( + { "class": "bm-button-circle bm-button-pin", "style": "margin-top: 0;", "innerHTML": '' }, + (instance, button) => { + button.onclick = () => { + const coords2 = instance.apiManager?.coordsTilePixel; + if (!coords2?.[0]) { + instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); + return; + } + instance.updateInnerHTML("bm-input-tx", coords2?.[0] || ""); + instance.updateInnerHTML("bm-input-ty", coords2?.[1] || ""); + instance.updateInnerHTML("bm-input-px", coords2?.[2] || ""); + instance.updateInnerHTML("bm-input-py", coords2?.[3] || ""); + }; + } + ).buildElement().addInput({ "type": "number", "id": "bm-input-tx", "class": "bm-input-coords", "placeholder": "Tl X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { + input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); + }).buildElement().addInput({ "type": "number", "id": "bm-input-ty", "class": "bm-input-coords", "placeholder": "Tl Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { + input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); + }).buildElement().addInput({ "type": "number", "id": "bm-input-px", "class": "bm-input-coords", "placeholder": "Px X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { + input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); + }).buildElement().addInput({ "type": "number", "id": "bm-input-py", "class": "bm-input-coords", "placeholder": "Px Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { + input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); + }).buildElement().buildElement().addDiv({ "class": "bm-container bm-main-upload" }).addInputFile({ "class": "bm-input-file", "textContent": "Upload Template", "accept": "image/png, image/jpeg, image/webp, image/bmp, image/gif" }).buildElement().buildElement().addDiv({ "class": "bm-container bm-flex-between bm-main-actions" }).addButton({ "class": "bm-button-secondary", "textContent": "Disable", "data-button-status": "shown" }, (instance, button) => { + button.onclick = () => { + button.disabled = true; + if (button.dataset["buttonStatus"] == "shown") { + instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(false); + button.dataset["buttonStatus"] = "hidden"; + button.textContent = "Enable"; + instance.handleDisplayStatus(`Disabled templates!`); + } else { + instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(true); + button.dataset["buttonStatus"] = "shown"; + button.textContent = "Disable"; + instance.handleDisplayStatus(`Enabled templates!`); + } + button.disabled = false; + }; + }).buildElement().addButton({ "class": "bm-button-primary", "textContent": "Create" }, (instance, button) => { + button.onclick = () => { + const input = document.querySelector(`#${this.windowID} .bm-input-file`); + const coordTlX = document.querySelector("#bm-input-tx"); + if (!coordTlX.checkValidity()) { + coordTlX.reportValidity(); + instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); + return; + } + const coordTlY = document.querySelector("#bm-input-ty"); + if (!coordTlY.checkValidity()) { + coordTlY.reportValidity(); + instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); + return; + } + const coordPxX = document.querySelector("#bm-input-px"); + if (!coordPxX.checkValidity()) { + coordPxX.reportValidity(); + instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); + return; + } + const coordPxY = document.querySelector("#bm-input-py"); + if (!coordPxY.checkValidity()) { + coordPxY.reportValidity(); + instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); + return; + } + if (!input?.files[0]) { + instance.handleDisplayError(`No file selected!`); + return; + } + instance?.apiManager?.templateManager.createTemplate(input.files[0], input.files[0]?.name.replace(/\.[^/.]+$/, ""), [Number(coordTlX.value), Number(coordTlY.value), Number(coordPxX.value), Number(coordPxY.value)]); + instance.handleDisplayStatus(`Drew to canvas!`); + }; + }).buildElement().addButton({ "class": "bm-button-secondary", "textContent": "Filter" }, (instance, button) => { + button.onclick = () => this.buildWindowFilter(); + }).buildElement().buildElement().addDiv({ "class": "bm-container bm-main-status" }).addTextarea({ "id": this.outputStatusId, "placeholder": `Status: Sleeping... +Version: ${this.version}`, "readOnly": true }).buildElement().buildElement().buildElement().buildElement().buildElement().buildOverlay(this.windowParent); + this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`); + } + /** Displays a new color filter window. + * This is a helper function that creates a new class instance. + * This might cause a memory leak. I pray that this is not the case... + * @since 0.88.330 + */ + buildWindowFilter() { + const windowFilter = new WindowFilter(this); + windowFilter.buildPreferredWindow(); + } + }; + _WindowMain_instances = new WeakSet(); + coordinateInputPaste_fn = async function(instance, input, event) { + event.preventDefault(); + const data = await getClipboardData(event); + const coords2 = data.split(/[^a-zA-Z0-9]+/).filter((index) => index).map(Number).filter( + (number) => !isNaN(number) + // Removes NaN `[4]` + ); + if (coords2.length == 2 && input.id == "bm-input-px") { + instance.updateInnerHTML("bm-input-px", coords2?.[0] || ""); + instance.updateInnerHTML("bm-input-py", coords2?.[1] || ""); + } else if (coords2.length == 1) { + instance.updateInnerHTML(input.id, coords2?.[0] || ""); + } else { + instance.updateInnerHTML("bm-input-tx", coords2?.[0] || ""); + instance.updateInnerHTML("bm-input-ty", coords2?.[1] || ""); + instance.updateInnerHTML("bm-input-px", coords2?.[2] || ""); + instance.updateInnerHTML("bm-input-py", coords2?.[3] || ""); + } + }; + // src/WindowWizard.js var _WindowWizard_instances, displaySchemaHealth_fn, displayTemplateList_fn, convertSchema_1_x_x_To_2_x_x_fn; var _WindowWizard = class _WindowWizard extends Overlay { @@ -3216,187 +3338,6 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; var WindowWizard = _WindowWizard; - // src/WindowMain.js - var _WindowMain_instances, coordinateInputPaste_fn; - var WindowMain = class extends Overlay { - /** Constructor for the main Blue Marble window - * @param {string} name - The name of the userscript - * @param {string} version - The version of the userscript - * @since 0.88.326 - * @see {@link Overlay#constructor} - */ - constructor(name2, version2) { - super(name2, version2); - __privateAdd(this, _WindowMain_instances); - this.window = null; - this.windowID = "bm-window-main"; - this.windowParent = document.body; - } - /** Creates the main Blue Marble window. - * Parent/child relationships in the DOM structure below are indicated by indentation. - * @since 0.58.3 - */ - buildWindow() { - if (document.querySelector(`#${this.windowID}`)) { - this.handleDisplayError("Main window already exists!"); - return; - } - this.window = this.addDiv({ "id": this.windowID, "class": "bm-window bm-windowed", "style": "top: 10px; left: unset; right: 75px;" }, (instance, div) => { - }).addDragbar().addButton({ "class": "bm-button-circle", "textContent": "\u25BC", "aria-label": 'Minimize window "Blue Marble"', "data-button-status": "expanded" }, (instance, button) => { - button.onclick = () => instance.handleMinimization(button); - button.ontouchend = () => { - button.click(); - }; - }).buildElement().addDiv().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container" }).addImg({ "class": "bm-favicon", "src": "https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png" }, (instance, img) => { - const date = /* @__PURE__ */ new Date(); - const dayOfTheYear = Math.floor((date.getTime() - new Date(date.getFullYear(), 0, 1)) / (1e3 * 60 * 60 * 24)) + 1; - if (dayOfTheYear == 204) { - img.parentNode.style.position = "relative"; - img.parentNode.innerHTML = img.parentNode.innerHTML + ``; - img.onload = () => { - const confettiManager = new ConfettiManager(); - confettiManager.createConfetti(document.querySelector(`#${this.windowID}`)); - }; - } - }).buildElement().addHeader(1, { "textContent": this.name }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container" }).addSpan({ "id": "bm-user-droplets", "textContent": "Droplets:" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-user-nextlevel", "textContent": "Next level in..." }).buildElement().addBr().buildElement().addSpan({ "textContent": "Charges: " }).addTimer(Date.now(), 1e3, { "style": "font-weight: 700;" }, (instance, timer) => { - instance.apiManager.chargeRefillTimerID = timer.id; - }).buildElement().buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container" }).addDiv({ "class": "bm-container" }).addButton( - { "class": "bm-button-circle bm-button-pin", "style": "margin-top: 0;", "innerHTML": '' }, - (instance, button) => { - button.onclick = () => { - const coords2 = instance.apiManager?.coordsTilePixel; - if (!coords2?.[0]) { - instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); - return; - } - instance.updateInnerHTML("bm-input-tx", coords2?.[0] || ""); - instance.updateInnerHTML("bm-input-ty", coords2?.[1] || ""); - instance.updateInnerHTML("bm-input-px", coords2?.[2] || ""); - instance.updateInnerHTML("bm-input-py", coords2?.[3] || ""); - }; - } - ).buildElement().addInput({ "type": "number", "id": "bm-input-tx", "class": "bm-input-coords", "placeholder": "Tl X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { - input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); - }).buildElement().addInput({ "type": "number", "id": "bm-input-ty", "class": "bm-input-coords", "placeholder": "Tl Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { - input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); - }).buildElement().addInput({ "type": "number", "id": "bm-input-px", "class": "bm-input-coords", "placeholder": "Px X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { - input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); - }).buildElement().addInput({ "type": "number", "id": "bm-input-py", "class": "bm-input-coords", "placeholder": "Px Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => { - input.addEventListener("paste", (event) => __privateMethod(this, _WindowMain_instances, coordinateInputPaste_fn).call(this, instance, input, event)); - }).buildElement().buildElement().addDiv({ "class": "bm-container" }).addInputFile({ "class": "bm-input-file", "textContent": "Upload Template", "accept": "image/png, image/jpeg, image/webp, image/bmp, image/gif" }).buildElement().buildElement().addDiv({ "class": "bm-container bm-flex-between" }).addButton({ "textContent": "Disable", "data-button-status": "shown" }, (instance, button) => { - button.onclick = () => { - button.disabled = true; - if (button.dataset["buttonStatus"] == "shown") { - instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(false); - button.dataset["buttonStatus"] = "hidden"; - button.textContent = "Enable"; - instance.handleDisplayStatus(`Disabled templates!`); - } else { - instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(true); - button.dataset["buttonStatus"] = "shown"; - button.textContent = "Disable"; - instance.handleDisplayStatus(`Enabled templates!`); - } - button.disabled = false; - }; - }).buildElement().addButton({ "textContent": "Create" }, (instance, button) => { - button.onclick = () => { - const input = document.querySelector(`#${this.windowID} .bm-input-file`); - const coordTlX = document.querySelector("#bm-input-tx"); - if (!coordTlX.checkValidity()) { - coordTlX.reportValidity(); - instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); - return; - } - const coordTlY = document.querySelector("#bm-input-ty"); - if (!coordTlY.checkValidity()) { - coordTlY.reportValidity(); - instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); - return; - } - const coordPxX = document.querySelector("#bm-input-px"); - if (!coordPxX.checkValidity()) { - coordPxX.reportValidity(); - instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); - return; - } - const coordPxY = document.querySelector("#bm-input-py"); - if (!coordPxY.checkValidity()) { - coordPxY.reportValidity(); - instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?"); - return; - } - if (!input?.files[0]) { - instance.handleDisplayError(`No file selected!`); - return; - } - instance?.apiManager?.templateManager.createTemplate(input.files[0], input.files[0]?.name.replace(/\.[^/.]+$/, ""), [Number(coordTlX.value), Number(coordTlY.value), Number(coordPxX.value), Number(coordPxY.value)]); - instance.handleDisplayStatus(`Drew to canvas!`); - }; - }).buildElement().addButton({ "textContent": "Filter" }, (instance, button) => { - button.onclick = () => this.buildWindowFilter(); - }).buildElement().buildElement().addDiv({ "class": "bm-container" }).addTextarea({ "id": this.outputStatusId, "placeholder": `Status: Sleeping... -Version: ${this.version}`, "readOnly": true }).buildElement().buildElement().addDiv({ "class": "bm-container bm-flex-between", "style": "margin-bottom: 0; flex-direction: column;" }).addDiv({ "class": "bm-flex-between" }).addButton({ "class": "bm-button-circle", "innerHTML": "\u2699\uFE0F", "title": "Settings" }, (instance, button) => { - button.onclick = () => { - instance.settingsManager.buildWindow(); - }; - }).buildElement().addButton({ "class": "bm-button-circle", "innerHTML": "\u{1F9D9}", "title": "Template Wizard" }, (instance, button) => { - button.onclick = () => { - const templateManager2 = instance.apiManager?.templateManager; - const wizard = new WindowWizard(this.name, this.version, templateManager2?.schemaVersion, templateManager2); - wizard.buildWindow(); - }; - }).buildElement().addButton({ "class": "bm-button-circle", "innerHTML": "\u{1F3A8}", "title": "Template Color Converter" }, (instance, button) => { - button.onclick = () => { - window.open("https://pepoafonso.github.io/color_converter_wplace/", "_blank", "noopener noreferrer"); - }; - }).buildElement().addButton({ "class": "bm-button-circle", "innerHTML": "\u{1F310}", "title": "Official Blue Marble Website" }, (instance, button) => { - button.onclick = () => { - window.open("https://bluemarble.lol/", "_blank", "noopener noreferrer"); - }; - }).buildElement().addButton({ "class": "bm-button-circle", "title": "Donate to SwingTheVine", "innerHTML": '' }, (instance, button) => { - button.onclick = () => { - window.open("https://ko-fi.com/swingthevine", "_blank", "noopener noreferrer"); - }; - }).buildElement().addButton({ "class": "bm-button-circle", "innerHTML": "\u{1F91D}", "title": "Credits" }, (instance, button) => { - button.onclick = () => { - const credits = new WindowCredts(this.name, this.version); - credits.buildWindow(); - }; - }).buildElement().buildElement().addSmall({ "textContent": "Made by SwingTheVine", "style": "margin-top: auto;" }).buildElement().buildElement().buildElement().buildElement().buildElement().buildOverlay(this.windowParent); - this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`); - } - /** Displays a new color filter window. - * This is a helper function that creates a new class instance. - * This might cause a memory leak. I pray that this is not the case... - * @since 0.88.330 - */ - buildWindowFilter() { - const windowFilter = new WindowFilter(this); - windowFilter.buildPreferredWindow(); - } - }; - _WindowMain_instances = new WeakSet(); - coordinateInputPaste_fn = async function(instance, input, event) { - event.preventDefault(); - const data = await getClipboardData(event); - const coords2 = data.split(/[^a-zA-Z0-9]+/).filter((index) => index).map(Number).filter( - (number) => !isNaN(number) - // Removes NaN `[4]` - ); - if (coords2.length == 2 && input.id == "bm-input-px") { - instance.updateInnerHTML("bm-input-px", coords2?.[0] || ""); - instance.updateInnerHTML("bm-input-py", coords2?.[1] || ""); - } else if (coords2.length == 1) { - instance.updateInnerHTML(input.id, coords2?.[0] || ""); - } else { - instance.updateInnerHTML("bm-input-tx", coords2?.[0] || ""); - instance.updateInnerHTML("bm-input-ty", coords2?.[1] || ""); - instance.updateInnerHTML("bm-input-px", coords2?.[2] || ""); - instance.updateInnerHTML("bm-input-py", coords2?.[3] || ""); - } - }; - // src/templateManager.js var _TemplateManager_instances, restoreFilteredColorsFromSettings_fn, persistFilteredColors_fn, loadTemplate_fn, storeTemplates_fn, parseBlueMarble_fn, parseOSU_fn, calculateCorrectPixelsOnTile_And_FilterTile_fn; var TemplateManager = class { @@ -4063,29 +4004,7 @@ Use Blue Marble version ${scriptVersion} or load a new template.`); console.log(`%cBlue Marble%c: Recieved message about "%s"`, "color: cornflowerblue;", "", endpointText); switch (endpointText) { case "me": - if (dataJSON["status"] && dataJSON["status"]?.toString()[0] != "2") { - overlay.handleDisplayError(`You are not logged in or Wplace is offline! -Could not fetch userdata.`); - return; - } - const nextLevelPixels = Math.ceil(Math.pow(Math.floor(dataJSON["level"]) * Math.pow(30, 0.65), 1 / 0.65) - dataJSON["pixelsPainted"]); - console.log(dataJSON["id"]); - if (!!dataJSON["id"] || dataJSON["id"] === 0) { - console.log(numberToEncoded( - dataJSON["id"], - "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~" - )); - } - this.templateManager.userID = dataJSON["id"]; - if (this.chargeRefillTimerID.length != 0) { - const chargeRefillTimer = document.querySelector("#" + this.chargeRefillTimerID); - if (chargeRefillTimer) { - const chargeData = dataJSON["charges"]; - chargeRefillTimer.dataset["endDate"] = Date.now() + (chargeData["max"] - chargeData["count"]) * chargeData["cooldownMs"]; - } - } - overlay.updateInnerHTML("bm-user-droplets", `Droplets: ${localizeNumber(dataJSON["droplets"])}`); - overlay.updateInnerHTML("bm-user-nextlevel", `Next level in ${localizeNumber(nextLevelPixels)} pixel${nextLevelPixels == 1 ? "" : "s"}`); + this.applyUserDataToOverlay(overlay, dataJSON); break; case "pixel": const coordsTile = data["endpoint"].split("?")[0].split("/").filter((s) => s && !isNaN(Number(s))); @@ -4149,6 +4068,76 @@ Did you try clicking the canvas first?`); } }); } + /** Applies user data from the /me endpoint to the current overlay. + * @param {Overlay} overlay + * @param {Object.} dataJSON + * @since 0.92.1 + */ + applyUserDataToOverlay(overlay, dataJSON) { + if (dataJSON["status"] && dataJSON["status"]?.toString()[0] != "2") { + overlay.handleDisplayError(`You are not logged in or Wplace is offline! +Could not fetch userdata.`); + return; + } + const nextLevelPixels = Math.ceil(Math.pow(Math.floor(dataJSON["level"]) * Math.pow(30, 0.65), 1 / 0.65) - dataJSON["pixelsPainted"]); + console.log(dataJSON["id"]); + if (!!dataJSON["id"] || dataJSON["id"] === 0) { + console.log(numberToEncoded( + dataJSON["id"], + "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~" + )); + } + this.templateManager.userID = dataJSON["id"]; + if (this.chargeRefillTimerID.length != 0) { + const chargeRefillTimer = document.querySelector("#" + this.chargeRefillTimerID); + if (chargeRefillTimer) { + const chargeData = dataJSON["charges"]; + chargeRefillTimer.dataset["endDate"] = Date.now() + (chargeData["max"] - chargeData["count"]) * chargeData["cooldownMs"]; + } + } + overlay.updateInnerHTML("bm-user-droplets", `${localizeNumber(dataJSON["droplets"])}`); + overlay.updateInnerHTML("bm-user-nextlevel", `${localizeNumber(nextLevelPixels)} px`); + } + /** Requests the current /me payload directly so the overlay has initial user data + * even if the first network response was missed during startup. + * @param {Overlay} overlay + * @since 0.92.1 + */ + async requestCurrentUserData(overlay) { + try { + const response = await fetch(`${window.location.origin}/api/me`, { + credentials: "include" + }); + if (!response.ok) { + overlay.handleDisplayError(`Could not fetch userdata. +HTTP ${response.status}`); + return; + } + const dataJSON = await response.json(); + this.applyUserDataToOverlay(overlay, dataJSON); + } catch (error) { + consoleError("Failed to fetch current user data:", error); + } + } + /** Applies cached /me data from sessionStorage if it was captured during early startup. + * @param {Overlay} overlay + * @returns {boolean} + * @since 0.92.1 + */ + applyCachedUserData(overlay) { + try { + const cached = sessionStorage.getItem("bm-last-me"); + if (!cached) { + return false; + } + const dataJSON = JSON.parse(cached); + this.applyUserDataToOverlay(overlay, dataJSON); + return true; + } catch (error) { + consoleError("Failed to apply cached user data:", error); + return false; + } + } // Sends a heartbeat to the telemetry server async sendHeartbeat(version2) { console.log("Sending heartbeat to telemetry server..."); @@ -4329,6 +4318,14 @@ Did you try clicking the canvas first?`); if (contentType.includes("application/json")) { console.log(`%c${name2}%c: Sending JSON message about endpoint "${endpointName}"`, consoleStyle2, ""); cloned.json().then((jsonData) => { + const endpointText = endpointName?.split("?")[0].split("/").filter((s) => s && isNaN(Number(s))).filter((s) => s && !s.includes(".")).pop(); + if (endpointText == "me") { + try { + sessionStorage.setItem("bm-last-me", JSON.stringify(jsonData)); + } catch (error) { + console.warn(`%c${name2}%c: Failed to cache "/me" payload`, consoleStyle2, "", error); + } + } window.postMessage({ source: "blue-marble", endpoint: endpointName, @@ -4375,13 +4372,9 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String }); var cssOverlay = GM_getResourceText("CSS-BM-File"); GM_addStyle(cssOverlay); - var robotoMonoInjectionPoint = "robotoMonoInjectionPoint"; - if (!!(robotoMonoInjectionPoint.indexOf("@font-face") + 1)) { - console.log(`Loading Roboto Mono as a file...`); - GM_addStyle(robotoMonoInjectionPoint); - } else { - stylesheetLink = document.createElement("link"); - stylesheetLink.href = "https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap"; + function appendFontStylesheet(href) { + const stylesheetLink = document.createElement("link"); + stylesheetLink.href = href; stylesheetLink.rel = "preload"; stylesheetLink.as = "style"; stylesheetLink.onload = function() { @@ -4390,7 +4383,14 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String }; document.head?.appendChild(stylesheetLink); } - var stylesheetLink; + var robotoMonoInjectionPoint = "robotoMonoInjectionPoint"; + appendFontStylesheet("https://fonts.googleapis.com/css2?family=Michroma&family=Rajdhani:wght@400;500;600;700&display=swap"); + if (!!(robotoMonoInjectionPoint.indexOf("@font-face") + 1)) { + console.log(`Loading Roboto Mono as a file...`); + GM_addStyle(robotoMonoInjectionPoint); + } else { + appendFontStylesheet("https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap"); + } var userSettings = JSON.parse(GM_getValue("bmUserSettings", "{}")); var observers = new Observers(); var windowMain = new WindowMain(name, version); @@ -4424,9 +4424,11 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String void initializeBlueMarble(); async function initializeBlueMarble() { await templateManager.importJSON(storageTemplates); + apiManager.spontaneousResponseListener(windowMain); windowMain.buildWindow(); windowMain.buildWindowFilter(); - apiManager.spontaneousResponseListener(windowMain); + apiManager.applyCachedUserData(windowMain); + void apiManager.requestCurrentUserData(windowMain); observeBlack(); consoleLog(`%c${name}%c (${version}) userscript has loaded!`, "color: cornflowerblue;", ""); } @@ -4460,4 +4462,4 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String } })(); -// Build Hash: 94db4c70d9af +// Build Hash: afe38147b547 diff --git a/dist/BlueMarble-Standalone.user.js b/dist/BlueMarble-Standalone.user.js index 32f9e22..749290d 100644 --- a/dist/BlueMarble-Standalone.user.js +++ b/dist/BlueMarble-Standalone.user.js @@ -38,6 +38,6 @@ The "Blue Marble" image is owned by NASA. */ -(()=>{var t=t=>{throw TypeError(t)},e=(e,i,n)=>i.has(e)?t("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(e):i.set(e,n),i=(e,i,n)=>(((e,i)=>{i.has(e)||t("Cannot access private method")})(e,i),n);function n(t){return new Promise(e=>setTimeout(e,t))}function s(t){return(new Intl.NumberFormat).format(t)}function o(t){return new Intl.NumberFormat(void 0,{style:"percent",t:2,i:2}).format(t)}function a(t){return t.toLocaleString(void 0,{o:"long",l:"numeric",h:"2-digit",m:"2-digit",u:"2-digit"})}function r(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function l(...t){(0,console.log)(...t)}function h(...t){(0,console.error)(...t)}function c(...t){(0,console.warn)(...t)}function m(t,e){if(0===t)return e[0];let i="";const n=e.length;for(;t>0;)i=e[t%n]+i,t=Math.floor(t/n);return i}function d(t,e){let i=0;const n=e.length;for(const s of t){const t=e.indexOf(s);-1==t&&h(`Invalid character '${s}' encountered whilst decoding! Is the decode alphabet/base incorrect?`),i=i*n+t}return i}function u(t){let e="";for(let i=0;i(t/=255)<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*e[0]+.7152*e[1]+.0722*e[2]}function f(t,e,i){return Array.isArray(t)&&([t,e,i]=t),(1<<24|t<<16|e<<8|i).toString(16).slice(1)}var g,w,x,y,$,v=[{id:0,premium:!1,name:"Transparent",rgb:[0,0,0]},{id:1,premium:!1,name:"Black",rgb:[0,0,0]},{id:2,premium:!1,name:"Dark Gray",rgb:[60,60,60]},{id:3,premium:!1,name:"Gray",rgb:[120,120,120]},{id:4,premium:!1,name:"Light Gray",rgb:[210,210,210]},{id:5,premium:!1,name:"White",rgb:[255,255,255]},{id:6,premium:!1,name:"Deep Red",rgb:[96,0,24]},{id:7,premium:!1,name:"Red",rgb:[237,28,36]},{id:8,premium:!1,name:"Orange",rgb:[255,127,39]},{id:9,premium:!1,name:"Gold",rgb:[246,170,9]},{id:10,premium:!1,name:"Yellow",rgb:[249,221,59]},{id:11,premium:!1,name:"Light Yellow",rgb:[255,250,188]},{id:12,premium:!1,name:"Dark Green",rgb:[14,185,104]},{id:13,premium:!1,name:"Green",rgb:[19,230,123]},{id:14,premium:!1,name:"Light Green",rgb:[135,255,94]},{id:15,premium:!1,name:"Dark Teal",rgb:[12,129,110]},{id:16,premium:!1,name:"Teal",rgb:[16,174,166]},{id:17,premium:!1,name:"Light Teal",rgb:[19,225,190]},{id:18,premium:!1,name:"Dark Blue",rgb:[40,80,158]},{id:19,premium:!1,name:"Blue",rgb:[64,147,228]},{id:20,premium:!1,name:"Cyan",rgb:[96,247,242]},{id:21,premium:!1,name:"Indigo",rgb:[107,80,246]},{id:22,premium:!1,name:"Light Indigo",rgb:[153,177,251]},{id:23,premium:!1,name:"Dark Purple",rgb:[120,12,153]},{id:24,premium:!1,name:"Purple",rgb:[170,56,185]},{id:25,premium:!1,name:"Light Purple",rgb:[224,159,249]},{id:26,premium:!1,name:"Dark Pink",rgb:[203,0,122]},{id:27,premium:!1,name:"Pink",rgb:[236,31,128]},{id:28,premium:!1,name:"Light Pink",rgb:[243,141,169]},{id:29,premium:!1,name:"Dark Brown",rgb:[104,70,52]},{id:30,premium:!1,name:"Brown",rgb:[149,104,42]},{id:31,premium:!1,name:"Beige",rgb:[248,178,119]},{id:32,premium:!0,name:"Medium Gray",rgb:[170,170,170]},{id:33,premium:!0,name:"Dark Red",rgb:[165,14,30]},{id:34,premium:!0,name:"Light Red",rgb:[250,128,114]},{id:35,premium:!0,name:"Dark Orange",rgb:[228,92,26]},{id:36,premium:!0,name:"Light Tan",rgb:[214,181,148]},{id:37,premium:!0,name:"Dark Goldenrod",rgb:[156,132,49]},{id:38,premium:!0,name:"Goldenrod",rgb:[197,173,49]},{id:39,premium:!0,name:"Light Goldenrod",rgb:[232,212,95]},{id:40,premium:!0,name:"Dark Olive",rgb:[74,107,58]},{id:41,premium:!0,name:"Olive",rgb:[90,148,74]},{id:42,premium:!0,name:"Light Olive",rgb:[132,197,115]},{id:43,premium:!0,name:"Dark Cyan",rgb:[15,121,159]},{id:44,premium:!0,name:"Light Cyan",rgb:[187,250,242]},{id:45,premium:!0,name:"Light Blue",rgb:[125,199,255]},{id:46,premium:!0,name:"Dark Indigo",rgb:[77,49,184]},{id:47,premium:!0,name:"Dark Slate Blue",rgb:[74,66,132]},{id:48,premium:!0,name:"Slate Blue",rgb:[122,113,196]},{id:49,premium:!0,name:"Light Slate Blue",rgb:[181,174,241]},{id:50,premium:!0,name:"Light Brown",rgb:[219,164,99]},{id:51,premium:!0,name:"Dark Beige",rgb:[209,128,81]},{id:52,premium:!0,name:"Light Beige",rgb:[255,197,165]},{id:53,premium:!0,name:"Dark Peach",rgb:[155,82,73]},{id:54,premium:!0,name:"Peach",rgb:[209,128,120]},{id:55,premium:!0,name:"Light Peach",rgb:[250,182,164]},{id:56,premium:!0,name:"Dark Tan",rgb:[123,99,82]},{id:57,premium:!0,name:"Tan",rgb:[156,132,107]},{id:58,premium:!0,name:"Dark Slate",rgb:[51,57,65]},{id:59,premium:!0,name:"Slate",rgb:[109,117,141]},{id:60,premium:!0,name:"Light Slate",rgb:[179,185,209]},{id:61,premium:!0,name:"Dark Stone",rgb:[109,100,63]},{id:62,premium:!0,name:"Stone",rgb:[148,140,107]},{id:63,premium:!0,name:"Light Stone",rgb:[205,197,158]}],M=class{constructor(t,i){e(this,g),this.name=t,this.version=i,this.p=null,this.$=null,this.v="bm-r",this.M=null,this.C=null,this.T=[]}S(t){this.p=t}k(t){this.$=t}D(){return this.T.length>0&&(this.C=this.T.pop()),this}N(t){t?.appendChild(this.M),this.M=null,this.C=null,this.T=[]}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}L(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"p",{},t)),this}O(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"small",{},t)),this}B(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"span",{},t)),this}I(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"details",{},t)),this}A(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"summary",{},t)),this}P(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"img",{},t)),this}W(t,e={},n=()=>{}){return n(this,i(this,g,w).call(this,"h"+t,{},e)),this}F(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"form",{},t)),this}U(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"fieldset",{},t)),this}G(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"legend",{},t)),this}R(t={},e=()=>{}){const n={};t.textContent?(n.textContent=t.textContent,delete t.textContent):t.innerHTML&&(n.innerHTML=t.innerHTML,delete t.textContent);const s=i(this,g,w).call(this,"label",n),o=i(this,g,w).call(this,"input",{type:"checkbox"},t);return s.insertBefore(o,s.firstChild),this.D(),e(this,s,o),this}j(t={},e=()=>{}){const n=i(this,g,w).call(this,"label",{textContent:t.textContent??"",for:t.id??""});return delete t.textContent,this.D(),e(this,n,i(this,g,w).call(this,"select",{},t)),this}Y(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"option",{},t)),this}J(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ul",{},t)),this}q(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"menu",{},t)),this}Z(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"li",{},t)),this}K(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"table",{},t)),this}tt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"caption",{},t)),this}et(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"thead",{},t)),this}it(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tbody",{},t)),this}nt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tfoot",{},t)),this}st(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tr",{},t)),this}ot(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"th",{},t)),this}rt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"td",{},t)),this}lt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"button",{},t)),this}ht(t={},e=()=>{}){const n=t.title??t.textContent??"Help: No info";delete t.textContent,t.title=`Help: ${n}`;const s={textContent:"?",className:"bm-10",onclick:()=>{this.ct(this.v,n)}};return e(this,i(this,g,w).call(this,"button",s,t)),this}dt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"input",{},t)),this}ut(t={},e=()=>{}){const n=t.textContent??"";delete t.textContent;const s=i(this,g,w).call(this,"div"),o=i(this,g,w).call(this,"input",{type:"file",tabindex:"-1","aria-hidden":"true"},t);this.D();const a=i(this,g,w).call(this,"button",{textContent:n});return this.D(),this.D(),a.addEventListener("click",()=>{o.click()}),o.addEventListener("change",()=>{a.style.maxWidth=`${a.offsetWidth}px`,o.files.length>0?a.textContent=o.files[0].name:a.textContent=n}),e(this,s,o,a),this}bt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"textarea",{},t)),this}ft(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{class:"bm-S"},t)),this}gt(t=Date.now(),e=500,n={},s=()=>{}){const o="bm--",a=n?.id||o+"-"+crypto.randomUUID().slice(0,8),r={class:o},l=i(this,g,w).call(this,"time",r,n);return l.id=a,l.dataset.endDate=t,setInterval(()=>{if(!l.isConnected)return;const t=Math.max(l.dataset.endDate-Date.now(),0),e=Math.floor(t/1e3),i=Math.floor(e/3600),n=Math.floor(e%60),s=Math.floor(e%3600/60);l.setAttribute("datetime",`PT${i}H${s}M${n}S`),l.textContent=String(i).padStart(2,"0")+":"+String(s).padStart(2,"0")+":"+String(n).padStart(2,"0")},e),s(this,l),this}ct(t,e,i=!1){const n=document.getElementById(t.replace(/^#/,""));n&&(n instanceof HTMLInputElement?n.value=e:i?n.textContent=e:n.innerHTML=e)}wt(t){if(t.disabled)return;t.disabled=!0,t.style.textDecoration="none";const e=t.closest(".bm-W"),i=t.closest(".bm-S"),n=e.querySelector("h1"),s=e.querySelector(".bm-m");if(e.parentElement.append(e),"expanded"==t.dataset.buttonStatus){s.style.height=s.scrollHeight+"px",e.style.width=e.scrollWidth+"px",s.style.height="0",s.addEventListener("transitionend",function e(){s.style.display="none",t.disabled=!1,t.style.textDecoration="",s.removeEventListener("transitionend",e)});const i=n.cloneNode(!0),o=i.textContent;t.nextElementSibling.appendChild(i),t.textContent="▶",t.dataset.buttonStatus="collapsed",t.ariaLabel=`Unminimize window "${o}"`}else{const n=i.querySelector("h1"),o=n.textContent;n.remove(),s.style.display="",s.style.height="0",e.style.width="",s.style.height=s.scrollHeight+"px",s.addEventListener("transitionend",function e(){s.style.height="",t.disabled=!1,t.style.textDecoration="",s.removeEventListener("transitionend",e)}),t.textContent="▼",t.dataset.buttonStatus="expanded",t.ariaLabel=`Minimize window "${o}"`}}xt(t,e,i={}){const n=document.querySelector(t),s=document.querySelector(e),o=i?.yt??(()=>{});if(!n||!s)return void this.$t(`Can not drag! ${n?"":"moveMe"} ${n||s?"":"and "}${s?"":"iMoveThings "}was not found!`);let a,r=!1,l=0,h=null,c=0,m=0,d=0,u=0,b=null;const p=()=>{if(r){const t=Math.abs(c-d),e=Math.abs(m-u);(t>.5||e>.5)&&(c=d,m=u,n.style.transform=`translate(${c}px, ${m}px)`,n.style.left="0px",n.style.top="0px",n.style.right=""),h=requestAnimationFrame(p)}},f=(t,e)=>{r=!0,b=n.getBoundingClientRect(),a=t-b.left,l=e-b.top;const i=window.getComputedStyle(n).transform;if(i&&"none"!==i){const t=new DOMMatrix(i);c=t.m41,m=t.m42}else c=b.left,m=b.top;d=c,u=m,document.body.style.userSelect="none",s.classList.add("bm-M"),document.addEventListener("mousemove",w),document.addEventListener("touchmove",x,{passive:!1}),document.addEventListener("mouseup",g),document.addEventListener("touchend",g),document.addEventListener("touchcancel",g),h&&cancelAnimationFrame(h),p()},g=()=>{r=!1,h&&(cancelAnimationFrame(h),h=null),document.body.style.userSelect="",s.classList.remove("bm-M"),document.removeEventListener("mousemove",w),document.removeEventListener("touchmove",x),document.removeEventListener("mouseup",g),document.removeEventListener("touchend",g),document.removeEventListener("touchcancel",g),o({element:n,x:c,y:m}),b=null},w=t=>{r&&b&&(d=t.clientX-a,u=t.clientY-l)},x=t=>{if(r&&b){const e=t.touches[0];if(!e)return;d=e.clientX-a,u=e.clientY-l,t.preventDefault()}};s.addEventListener("mousedown",function(t){t.preventDefault(),f(t.clientX,t.clientY)}),s.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(f(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t,e,i={}){const n=document.querySelector(t),s=document.querySelector(e),o=i?.yt??(()=>{});if(!n||!s)return void this.$t(`Can not resize! ${n?"":"resizeMe"} ${n||s?"":"and "}${s?"":"iResizeThings "}was not found!`);let a=!1,r=0,l=0,h=0,c=0,m=0,d=0,u=0,b=0,p=null;const f=()=>Number.isFinite(i?.maxWidth)?i.maxWidth:window.innerWidth-16,g=()=>Number.isFinite(i?.maxHeight)?i.maxHeight:window.innerHeight-16,w=Number.isFinite(i?.minWidth)?i.minWidth:200,x=Number.isFinite(i?.minHeight)?i.minHeight:160,y=(t,e,i)=>Math.min(Math.max(t,e),Math.max(e,i)),$=()=>{if(a){const t=Math.abs(m-u),e=Math.abs(d-b);(t>.5||e>.5)&&(m=u,d=b,n.style.width=`${m}px`,n.style.height=`${d}px`),p=requestAnimationFrame($)}},v=(t,e)=>{a=!0,r=t,l=e,h=n.offsetWidth,c=n.offsetHeight,m=h,d=c,u=h,b=c,document.body.style.userSelect="none",s.classList.add("bm-1S"),document.addEventListener("mousemove",C),document.addEventListener("touchmove",T,{passive:!1}),document.addEventListener("mouseup",M),document.addEventListener("touchend",M),document.addEventListener("touchcancel",M),p&&cancelAnimationFrame(p),$()},M=()=>{a=!1,p&&(cancelAnimationFrame(p),p=null),document.body.style.userSelect="",s.classList.remove("bm-1S"),document.removeEventListener("mousemove",C),document.removeEventListener("touchmove",T),document.removeEventListener("mouseup",M),document.removeEventListener("touchend",M),document.removeEventListener("touchcancel",M),o({element:n,width:m,height:d})},C=t=>{a&&(u=y(h+(t.clientX-r),w,f()),b=y(c+(t.clientY-l),x,g()))},T=t=>{if(!a)return;const e=t?.touches?.[0];e&&(u=y(h+(e.clientX-r),w,f()),b=y(c+(e.clientY-l),x,g()),t.preventDefault())};s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),v(t.clientX,t.clientY)}),s.addEventListener("touchstart",t=>{const e=t?.touches?.[0];e&&(t.preventDefault(),t.stopPropagation(),v(e.clientX,e.clientY))},{passive:!1})}Mt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.v,"Status: "+t,!0)}$t(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.v,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},n={}){const s=document.createElement(t);this.M?(this.C?.appendChild(s),this.T.push(this.C),this.C=s):(this.M=s,this.C=s);for(const[t,n]of Object.entries(e))i(this,g,x).call(this,s,t,n);for(const[t,e]of Object.entries(n))i(this,g,x).call(this,s,t,e);return s},x=function(t,e,i){"class"==e?t.classList.add(...i.split(/\s+/)):"for"==e?t.htmlFor=i:"tabindex"==e?t.tabIndex=Number(i):"readonly"==e?t.readOnly="true"==i||"1"==i:"maxlength"==e?t.maxLength=Number(i):e.startsWith("data")?t.dataset[e.slice(5).split("-").map((t,e)=>0==e?t:t[0].toUpperCase()+t.slice(1)).join("")]=i:e.startsWith("aria")?t.setAttribute(e,i):t[e]=i};var C,T,S,k,D,N=class extends M{constructor(t,i){super(t,i),e(this,y),this.window=null,this.Ct="bm-l",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.H({id:this.Ct,class:"bm-W"}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Settings"}).D().D().F().D().L({textContent:"Settings take 5 seconds to save."}).D().H({class:"bm-L bm-H"},(t,e)=>{this.kt(),this.Dt()}).D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}kt(){i(this,y,$).call(this,"Pixel Highlight")}Dt(){i(this,y,$).call(this,"Template")}};y=new WeakSet,$=function(t){this.window=this.H({class:"bm-L"}).W(2,{textContent:t}).D().F().D().L({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).D().D()},C=new WeakSet,T=function(t,e){t.disabled=!0;const i=t.dataset.status,n=this.Nt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];let s=[2,0,0];const o=n;switch(i){case"Disabled":t.dataset.status="Incorrect",t.ariaLabel="Sub-pixel incorrect",s=[1,...e];break;case"Incorrect":t.dataset.status="Template",t.ariaLabel="Sub-pixel template",s=[2,...e];break;case"Template":t.dataset.status="Disabled",t.ariaLabel="Sub-pixel disabled",s=[0,...e];break}const a=n.findIndex(([,t,e])=>t==s[1]&&e==s[2]);0!=s[0]?-1!=a?o[a]=s:o.push(s):-1!=a&&o.splice(a,1),this.Nt.highlight=o,t.disabled=!1},S=async function(t){const e=document.querySelectorAll(".bm-3 button");for(const t of e)t.disabled=!0;let i=[0,0,0,0,2,0,0,0,0];switch(t){case"Cross":i=[0,1,0,1,2,1,0,1,0];break;case"X":i=[1,0,1,0,2,0,1,0,1];break;case"Full":i=[2,2,2,2,2,2,2,2,2];break}const s=document.querySelector(".bm-n")?.childNodes??[];for(let t=0;t{const[n,s,o,a]=e.split(",").map(Number);(s>>24==0?0:s.get(e)??-2;const a=o.get(n);o.set(n,a?a+1:1)}return console.log(o),o};var L=class{constructor(){this.Jt=Math.ceil(80/1300*window.innerWidth),this.Xt=v.slice(1)}qt(t){const e=document.createElement("div");for(let t=0;t{t.parentNode.childElementCount<=1?t.parentNode.remove():t.remove()},e.appendChild(t)}t.appendChild(e)}},O=class extends HTMLElement{};customElements.define("confetti-piece",O);var B,I,A,P,z,W,F,V,_,U,G,R,E,j,Y,J,X,q,Z,Q,K,tt=class extends M{constructor(t,e){super(t,e),this.window=null,this.Ct="bm-o",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.H({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Credits"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Credits"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Credits"}).D().D().F().D().H({class:"bm-L bm-H"}).B({role:"img","aria-label":this.name}).B({innerHTML:"\n██████╗ ██╗ ██╗ ██╗███████╗\n██╔══██╗██║ ██║ ██║██╔════╝\n██████╔╝██║ ██║ ██║█████╗ \n██╔══██╗██║ ██║ ██║██╔══╝ \n██████╔╝███████╗╚██████╔╝███████╗\n╚═════╝ ╚══════╝ ╚═════╝ ╚══════╝\n\n███╗ ███╗ █████╗ ██████╗ ██████╗ ██╗ ███████╗\n████╗ ████║██╔══██╗██╔══██╗██╔══██╗██║ ██╔════╝\n██╔████╔██║███████║██████╔╝██████╔╝██║ █████╗ \n██║╚██╔╝██║██╔══██║██╔══██╗██╔══██╗██║ ██╔══╝ \n██║ ╚═╝ ██║██║ ██║██║ ██║██████╔╝███████╗███████╗\n╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚══════╝\n",class:"bm-_","aria-hidden":"true"}).D().D().V().D().F().D().V().D().B({textContent:'"Blue Marble" userscript is made by SwingTheVine.'}).D().V().D().B({innerHTML:'The Blue Marble Website is made by crqch.'}).D().V().D().B({textContent:`The Blue Marble Website used until ${a(new Date(175606932e4))} was made by Camille Daguin.`}).D().V().D().B({textContent:'The favicon "Blue Marble" is owned by NASA. (The image of the Earth is owned by NASA)'}).D().V().D().B({textContent:"Special Thanks:"}).D().X().Z({textContent:"Espresso, Meqa, and Robot for moderating SwingTheVine's community."}).D().Z({innerHTML:'nof, darkness for creating similar userscripts!'}).D().Z({innerHTML:'Wonda for the Blue Marble banner image!'}).D().Z({innerHTML:'BullStein, allanf181 for being early beta testers!'}).D().Z({innerHTML:'guidu_ and Nick-machado for the original "Minimize" Button code!'}).D().Z({innerHTML:'Nomad and Gustav for the tutorials!'}).D().Z({innerHTML:'cfp for creating the template overlay that Blue Marble was based on!'}).D().Z({innerHTML:'Force Network for hosting the telemetry server!'}).D().Z({innerHTML:'TheBlueCorner for getting me interested in online pixel canvases!'}).D().D().V().D().B({innerHTML:'Donators:'}).D().X().Z({textContent:"Soultree"}).D().Z({textContent:"Espresso"}).D().Z({textContent:"BEST FAN"}).D().Z({textContent:"FuchsDresden"}).D().Z({textContent:"Jack"}).D().Z({textContent:"raiken_au"}).D().Z({textContent:"Jacob"}).D().Z({textContent:"StupidOne"}).D().Z({textContent:"2 Anonymous Supporters"}).D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}},et=class extends M{constructor(t){super(t.name,t.version),e(this,B),this.window=null,this.Ct="bm-t",this.Zt="bm-E",this.Tt=document.body,this.$=t.$??null,this.Qt="ftr-oWin",this.Kt="windowFilter",this.te=null,this.ee=null,this.ie=null,this.ne=260,this.se=220,this.oe=1e3,this.ae=1400,this.re=t.p?.re,this.le='',this.he='';const{palette:i,Yt:n}=this.re.ce;this.palette=i,this.me=0,this.de=0,this.ue=new Map,this.be=new Map,this.pe=0,this.fe=0,this.timeRemaining=0,this.ge="",this.sortPrimary="total",this.sortSecondary="descending",this.showUnused=!1}we(){i(this,B,A).call(this)?this.xe():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,W).call(this);this.window=this.H({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"🗗","aria-label":'Switch to windowed mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,B,P).call(this,!0),i(this,B,W).call(this),this.xe()},e.ontouchend=()=>{e.click()}}).D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,B,W).call(this),e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Color Filter"}).D().D().F().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"Hide All Colors"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!1)}).D().lt({textContent:"Refresh Data"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.ye(),e.disabled=!1}}).D().lt({textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).H({class:"bm-L",style:"margin-left: 2.5ch; margin-right: 2.5ch;"}).H({class:"bm-L"}).B({id:"bm-i",innerHTML:"Tiles Loaded: 0 / ???"}).D().V().D().B({id:"bm-d",innerHTML:"Correct Pixels: ???"}).D().V().D().B({id:"bm-j",innerHTML:"Total Pixels: ???"}).D().V().D().B({id:"bm-7",innerHTML:"Complete: ??? (???)"}).D().V().D().B({id:"bm-8",innerHTML:"??? ???"}).D().D().H({class:"bm-L"}).L({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.le.replace("{e.onclick=t=>{t.preventDefault();const e=new FormData(document.querySelector(`#${this.Ct} form`)),n={};for(const[t,i]of e)n[t]=i;console.log(`Primary: ${n.sortPrimary}; Secondary: ${n.sortSecondary}; Unused: ${"on"==n.showUnused}`),i(this,B,Y).call(this,n.sortPrimary,n.sortSecondary,"on"==n.showUnused)}}).D().D().D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,j).call(this,t),i(this,B,z).call(this),i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${s(this.me)} / ${s(this.de)}`),this.ct("#bm-d",`Correct Pixels: ${s(this.pe)}`),this.ct("#bm-j",`Total Pixels: ${s(this.fe)}`),this.ct("#bm-7",`Remaining: ${s((this.fe||0)-(this.pe||0))} (${o(((this.fe||0)-(this.pe||0))/(this.fe||1))})`),this.ct("#bm-8",`Completed at: `)}xe(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,W).call(this);this.window=this.H({id:this.Ct,class:"bm-W bm-N",style:`width: 300px; height: min(70vh, 32rem); min-width: ${this.ne}px; min-height: ${this.se}px; max-width: min(${this.oe}px, calc(100vw - 16px)); max-height: min(${this.ae}px, calc(100vh - 16px));`}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>{const i=document.querySelector("#bm-2");i&&(i.style.display="expanded"==e.dataset.buttonStatus?"none":""),t.wt(e)},e.ontouchend=()=>{e.click()}}).D().H().B({id:"bm-2",class:"bm-y",style:"font-weight: 700;"}).D().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"🗖","aria-label":'Switch to fullscreen mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,B,P).call(this,!1),i(this,B,W).call(this),this.St()},e.ontouchend=()=>{e.click()}}).D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,B,W).call(this),e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Color Filter"}).D().D().F().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"None"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!1)}).D().lt({textContent:"Refresh"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.ye(),e.disabled=!1}}).D().lt({textContent:"All"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).D().D().H({class:"bm-1y",title:"Resize Color Filter window","aria-label":"Resize Color Filter window",role:"presentation",textContent:"◢",style:"position: absolute; right: 0; bottom: 0; width: 28px; height: 28px; display: flex; align-items: flex-end; justify-content: flex-end; padding-right: 4px; padding-bottom: 4px; box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; touch-action: none; user-select: none; font-size: 8px; line-height: 1; color: rgba(255,255,255,0.95); background: transparent; border: none; box-shadow: none;"}).D().D().N(this.Tt),i(this,B,E).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,j).call(this,t),i(this,B,z).call(this),i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}ye(){i(this,B,X).call(this);const t=document.querySelector(`#${this.Zt}`),e={};for(const t of this.palette){const i=this.ue.get(t.id)??0,n=s(i);let a=0,r="0",l=o(1);0!=i&&(a=this.be.get(t.id)??"???","number"!=typeof a&&this.me==this.de&&t.id&&(a=0),r="string"==typeof a?a:s(a),l=isNaN(a/i)?"???":o(a/i));const h=parseInt(i)-parseInt(a);e[t.id]={$e:i,ve:n,Me:a,Ce:r,Te:l,Se:h}}if(document.querySelector("#bm-2")){const t=this.pe.toString().length>7?this.pe.toString().slice(0,2)+"…"+this.pe.toString().slice(-3):this.pe.toString(),e=this.fe.toString().length>7?this.fe.toString().slice(0,2)+"…"+this.fe.toString().slice(-3):this.fe.toString();this.ct("#bm-2",`${t}/${e}`,!0)}if(!t)return e;const n=Array.from(t.children);for(const t of n){const i=parseInt(t.dataset.id),{Me:n,Ce:s,Te:o,$e:a,ve:r,Se:l}=e[i];t.dataset.correct=Number.isNaN(parseInt(n))?"0":n,t.dataset.total=a,t.dataset.percent="%"==o.slice(-1)?o.slice(0,-1):"0",t.dataset.incorrect=l||0;const h=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-9`);h&&(h.textContent=`${s} / ${r}`);const c=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-6`);c&&(c.textContent=`${"number"!=typeof l||isNaN(l)?"???":l} incorrect pixel${1==l?"":"s"}. Completed: ${o}`)}i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};B=new WeakSet,I=function(){var t,e;return this.$?((t=this.$.Nt)[e=this.Kt]??(t[e]={}),this.$.Nt[this.Kt]):null},A=function(){const t=i(this,B,I).call(this);return"windowed"==t?.mode||"fullscreen"!=t?.mode},P=function(t){const e=i(this,B,I).call(this);e&&(e.mode=t?"windowed":"fullscreen"),this.$&&(this.$.ke(this.Qt,t),this.$.De())},z=function(){const t=document.querySelector(`#${this.Ct} #bm-c`),e=document.querySelector(`#${this.Ct} #bm-5`),i=document.querySelector(`#${this.Ct} #bm-e`);t instanceof HTMLSelectElement&&(t.value=this.sortPrimary),e instanceof HTMLSelectElement&&(e.value=this.sortSecondary),i instanceof HTMLInputElement&&(i.checked=this.showUnused)},W=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,B,G).call(this,t),i(this,B,F).call(this),t?.remove()},F=function(){this.te&&(this.te.disconnect(),this.te=null),this.ee&&(window.removeEventListener("resize",this.ee),this.ee=null),this.ie&&(clearTimeout(this.ie),this.ie=null)},V=function(t,e,i){const n=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),n)},_=function(t,e,i){const n=Math.max(8,window.innerWidth-t.offsetWidth-8),s=Math.max(8,window.innerHeight-t.offsetHeight-8);return{x:Math.min(Math.max(Math.round(Number(e)||8),8),n),y:Math.min(Math.max(Math.round(Number(i)||8),8),s)}},U=function(t){const e=i(this,B,I).call(this);if(!e||!t)return;const n=Number(e.width),s=Number(e.height),o=Number.isFinite(n),a=Number.isFinite(s);o&&(e.width=i(this,B,V).call(this,n,this.ne,Math.min(this.oe,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,B,V).call(this,s,this.se,Math.min(this.ae,window.innerHeight-16)),t.style.height=`${e.height}px`),requestAnimationFrame(()=>{if(!t.isConnected)return;const n=Number(e.x),s=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(s))return;const o=i(this,B,_).call(this,t,n,s);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${o.x}px, ${o.y}px)`,o.x==n&&o.y==s||(e.x=o.x,e.y=o.y,this.$?.De())})},G=function(t){const e=i(this,B,I).call(this);if(!e||!t?.isConnected||!t.classList.contains("bm-N"))return;const n=t.getBoundingClientRect(),s=i(this,B,V).call(this,n.width,this.ne,Math.min(this.oe,window.innerWidth-16)),o=i(this,B,V).call(this,n.height,this.se,Math.min(this.ae,window.innerHeight-16));Math.round(n.width)!=s&&(t.style.width=`${s}px`),Math.round(n.height)!=o&&(t.style.height=`${o}px`);const a=i(this,B,_).call(this,t,n.left,n.top);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${a.x}px, ${a.y}px)`,e.x=a.x,e.y=a.y,e.width=s,e.height=o,this.$?.De()},R=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,B,G).call(this,t)},e)},E=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,B,F).call(this),i(this,B,U).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{yt:({element:t})=>i(this,B,G).call(this,t)}),this.vt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-1y`,{minWidth:this.ne,minHeight:this.se,maxWidth:Math.min(this.oe,window.innerWidth-16),maxHeight:Math.min(this.ae,window.innerHeight-16),yt:({element:t})=>i(this,B,G).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,B,R).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,B,R).call(this,t,0),window.addEventListener("resize",this.ee))},j=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N");console.log(`Is Windowed Mode: ${e}`);const i=new M(this.name,this.version);i.H({id:this.Zt});const n=this.ye();for(const t of this.palette){const s="#"+f(t.rgb).toUpperCase(),o=p(t.rgb);let a=1.05/(o+.05)>(o+.05)/.05?"white":"black";t.id||(a="transparent");const r="white"==a?"bm-f":"bm-g",{Me:l,Ce:h,Te:c,$e:m,ve:d,Se:u}=n[t.id],b=!!this.re.Ne.get(t.id);if(e){const e=`background-size: auto 100%; background-repeat: repeat-x; background-image: url("data:image/svg+xml;utf8,");`;i.H({class:"bm-L bm-z bm-x","data-id":t.id,"data-name":t.name,"data-premium":+t.premium,"data-correct":Number.isNaN(parseInt(l))?"0":l,"data-total":m,"data-percent":"%"==c.slice(-1)?c.slice(0,-1):"0","data-incorrect":u||0}).H({class:"bm-a",style:`background-color: rgb(${t.rgb?.map(t=>Number(t)||0).join(",")});${t.premium?e:""}`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.he.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.he.replace("Number(t)||0).join(",")});`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.he.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.he.replace("{const o=n.getAttribute("data-"+t),a=s.getAttribute("data-"+t),r=parseFloat(o),l=parseFloat(a),h=!isNaN(r),c=!isNaN(l);if(i?n.classList.remove("bm-I"):Number(n.getAttribute("data-total"))||n.classList.add("bm-I"),h&&c)return"ascending"===e?r-l:l-r;{const t=o.toLowerCase(),i=a.toLowerCase();return ti?"ascending"===e?1:-1:0}}),s.forEach(t=>n.appendChild(t))},J=function(t){const e=document.querySelector(`#${this.Zt}`),i=Array.from(e.children);for(const e of i){if(e.classList?.contains("bm-I"))continue;const i=e.querySelector(".bm-a button");("hidden"!=i.dataset.state||t)&&("shown"==i.dataset.state&&t||i.click())}},X=function(){this.me=0,this.de=0,this.fe=0,this.pe=0,this.be=new Map,this.ue=new Map;for(const t of this.re.Le){const e=t.At?.total??0;this.fe+=e??0;const i=t.At?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,n=this.ue.get(t)??0;this.ue.set(t,n+i)}const n=t.At?.correct??{};this.me+=Object.keys(n).length,this.de+=Object.keys(t.Ot).length;for(const t of Object.values(n))for(const[e,i]of t){const t=Number(i)||0;this.pe+=t;const n=this.be.get(e)??0;this.be.set(e,n+t)}}console.log(`Tiles loaded: ${this.me} / ${this.de}`),this.pe>=this.fe&&this.fe&&this.me==this.de&&(new L).qt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.fe-this.pe)*1e3+Date.now()),this.ge=a(this.timeRemaining)};var it=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,q),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Oe=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Oe?.scriptVersion,this.schemaVersion=this.Oe?.schemaVersion,this.Be=void 0,this.Ie=n,this.re=s}St(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();let t="";document.querySelector("#bm-F")||(t=t.concat("z-index: 9001;").trim()),this.window=this.H({id:this.Ct,class:"bm-W",style:t},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Template Wizard"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Template Wizard"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Template Wizard"}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().L({id:"bm-v",textContent:"Loading template storage status..."}).D().D().H({class:"bm-L bm-H"}).W(2,{textContent:"Detected templates:"}).D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,q,Z).call(this),i(this,q,Q).call(this)}};q=new WeakSet,Z=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Ie.split(/[-\.\+]/);let n="";t[0]==e[0]?t[1]==e[1]?(n='Template storage health: Healthy!
No futher action required. (Reason: Semantic version matches)',this.Be="Good"):(n='Template storage health: Poor!
You can still use your template, but some features may not work. It is recommended that you update Blue Marble\'s template storage. (Reason: MINOR version mismatch)',this.Be="Poor"):t[0]Bad!
It is guaranteed that some features are broken. You might still be able to use the template. It is HIGHLY recommended that you download all templates and update Blue Marble\'s template storage before continuing. (Reason: MAJOR version mismatch)',this.Be="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Be="Dead");const s=`
If you want to continue using your current templates, then make sure the template storage (schema) is up-to-date.
If you don't want to update the template storage, then downgrade Blue Marble to version ${r(this.scriptVersion)} to continue using your templates.
Alternatively, if you don't care about corrupting the templates listed below, you can fix any issues with the template storage by uploading a new template.`,o=function(){const t=[...document.querySelectorAll("body > div > .hidden")].filter(t=>/version:/i.test(t.textContent));if(t[0]){const e=t[0].textContent?.match(/\d+/);return e?new Date(Number(e[0])):void 0}}();let l=o?a(o):"???";this.ct("#bm-v",`${n}
Your templates were created during Blue Marble version ${r(this.scriptVersion)} with schema version ${r(this.schemaVersion)}.
The current Blue Marble version is ${r(this.version)} and requires schema version ${r(this.Ie)}.
Wplace was last updated on ${l}.${"Good"!=this.Be?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.Be&&(h.H({class:"bm-L bm-D bm-h",style:"gap: 1.5ch;"}),h.lt({textContent:"Download all templates"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.re.Ae().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.Be&&"Bad"!=this.Be||h.lt({textContent:`Update template storage to ${this.Ie}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,q,K).call(this,!0)}}).D(),h.D().N(document.querySelector("#bm-v").parentNode)},Q=function(){const t=this.Oe?.templates;if(Object.keys(t).length>0){const e=document.querySelector(`#${this.Ct} .bm-H`),i=new M(this.name,this.version);i.H({id:"bm-B",class:"bm-L"});for(const e in t){const n=e,o=t[e];if(t.hasOwnProperty(e)){const t=n.split(" "),e=Number(t?.[0]),a=d(t?.[1]||"0",this.re.Pe),r=o.name||`Template ${e||""}`,l=o?.coords?.split(",").map(Number),h=o.pixels?.total??void 0,c=void 0,m="number"==typeof e?s(e):"???",u="number"==typeof a?s(a):"???",b="number"==typeof h?s(h):"???";i.H({class:"bm-L bm-D"}).H({class:"bm-D",style:"flex-direction: column; gap: 0;"}).H({class:"bm-1",textContent:c||"🖼️"}).D().O({textContent:`#${m}`}).D().D().H({class:"bm-D bm-0"}).W(3,{textContent:r}).D().B({textContent:`Uploaded by user #${u}`}).D().B({textContent:`Coordinates: ${l.join(", ")}`}).D().B({textContent:`Total Pixels: ${b}`}).D().D().D()}}i.D().N(e)}},K=async function(t){if(t){const t=document.querySelector(`#${this.Ct} .bm-m`);t.innerHTML="",new M(this.name,this.version).H({class:"bm-L"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Template Wizard"}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().L({textContent:"Updating template storage. Please wait..."}).D().D().D().N(t)}GM_deleteValue("bmCoords");const e=this.Oe?.templates;if(Object.keys(e).length>0)for(const[t,i]of Object.entries(e))if(e.hasOwnProperty(t)){const t=new H({displayName:i.name,Ot:i.tiles});t.jt();const e=await this.re.ze(t);await this.re.We(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new it(this.name,this.version,this.Ie,this.re).St())};var nt,st,ot,at,rt,lt,ht,ct,mt,dt,ut=it;nt=new WeakSet,st=async function(t,e,i){i.preventDefault();const n=await async function(t){let e="";return t&&(e=t.clipboardData.getData("text/plain")),0!=e.length||(await navigator.clipboard.readText().then(t=>{e=t}).catch(t=>{l("Failed to retrieve clipboard data using navigator! Using fallback methods...")}),0!=e.length||(e=window.clipboardData?.getData("Text"))),e}(i),s=n.split(/[^a-zA-Z0-9]+/).filter(t=>t).map(Number).filter(t=>!isNaN(t));2==s.length&&"bm-O"==e.id?(t.ct("bm-O",s?.[0]||""),t.ct("bm-P",s?.[1]||"")):1==s.length?t.ct(e.id,s?.[0]||""):(t.ct("bm-Q",s?.[0]||""),t.ct("bm-R",s?.[1]||""),t.ct("bm-O",s?.[2]||""),t.ct("bm-P",s?.[3]||""))},ot=new WeakSet,at=function(){const t=this.$?.Nt?.filter,e=Array.isArray(t)?t:[];this.Ne.clear();for(const t of e){const e=Number(t);Number.isFinite(e)&&this.Ne.set(e,!0)}},rt=function(){this.$&&(this.$.Nt.filter=Array.from(this.Ne.keys()).map(t=>Number(t)).filter(t=>Number.isFinite(t)).sort((t,e)=>t-e),this.$.De())},lt=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Fe))},ht=async function(t){console.log("Parsing BlueMarble...");const e=t.templates;console.log(`BlueMarble length: ${Object.keys(e).length}`);const i=t?.schemaVersion,n=i.split(/[-\.\+]/),s=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;console.log(`BlueMarble Template Schema: ${i}; Script Version: ${o}`),n[0]==s[0]?(n[1]!=s[1]&&new ut(this.name,this.version,this.schemaVersion,this).St(),this.Le=await async function({It:t,Ve:i,Le:n}){if(Object.keys(e).length>0)for(const s in e){const o=s,a=e[s];if(console.log(`Template Key: ${o}`),e.hasOwnProperty(s)){const e=o.split(" "),s=Number(e?.[0]),r=e?.[1]||"0",l=a.name||`Template ${s||""}`,h={total:a.pixels?.total,colors:new Map(Object.entries(a.pixels?.colors||{}).map(([t,e])=>[Number(t),e]))},c=a.tiles,m={},d={},u=t*i;for(const t in c)if(console.log(t),c.hasOwnProperty(t)){const e=b(c[t]),i=new Blob([e],{type:"image/png"}),n=await createImageBitmap(i);m[t]=n;const s=new OffscreenCanvas(u,u).getContext("2d");s.drawImage(n,0,0);const o=s.getImageData(0,0,n.width,n.height);d[t]=new Uint32Array(o.data.buffer)}const p=new H({displayName:l,Ht:s||this.Le?.length||0,Lt:r||""});p.At=h,p.Ot=m,p.Bt=d,n.push(p),console.log(this.Le),console.log("^^^ This ^^^")}}return n}({It:this.It,Ve:this.Ve,Le:this.Le})):n[0]>>24&255,y=g>>>24&255,$=b.get(w)??-2,v=b.get(g)??-2;if(this.Ne.get($)&&(e[i*h+c]=g),-1==$){const t=536870912;this.Ne.get($)?e[i*h+c]=0:(u/o&1)==(f/o&1)?(e[i*h+c]=t,e[(i-1)*h+(c-1)]=t,e[(i-1)*h+(c+1)]=t,e[(i+1)*h+(c-1)]=t,e[(i+1)*h+(c+1)]=t):(e[i*h+c]=0,e[(i-1)*h+c]=t,e[(i+1)*h+c]=t,e[i*h+(c-1)]=t,e[i*h+(c+1)]=t)}if(!s&&x>m&&v!=$&&(d||y>m)){const t=e[i*h+c];for(const s of n){const[n,o,a]=s,r=0!=n?1!=n?t:4278190335:0;e[(i+a)*h+(c+o)]=r}}if(-1==$&&g<=m){const t=p.get($);p.set($,t?t+1:1);continue}if(x<=m||y<=m)continue;if(v!=$)continue;const M=p.get($);p.set($,M?M+1:1)}return console.log("List of template pixels that match the tile:"),console.log(p),{Je:p,Xe:e}},mt=new WeakSet,dt=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var bt=GM_info.script.name.toString(),pt=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",bt),e.setAttribute("bm-X","color: cornflowerblue;"),e.textContent=`(${t})();`,document.documentElement?.appendChild(e),e.remove()}(()=>{const t=document.currentScript,e=t?.getAttribute("bm-11")||"Blue Marble",i=t?.getAttribute("bm-X")||"",n=new Map;window.addEventListener("message",t=>{const{source:s,endpoint:o,blobID:a,blobData:r,blink:l}=t.data,h=Date.now()-l;if(console.groupCollapsed(`%c${e}%c: ${n.size} Recieved IMAGE message about blob "${a}"`,i,""),console.log(`Blob fetch took %c${String(Math.floor(h/6e4)).padStart(2,"0")}:${String(Math.floor(h/1e3)%60).padStart(2,"0")}.${String(h%1e3).padStart(3,"0")}%c MM:SS.mmm`,i,""),console.log(n),console.groupEnd(),"blue-marble"==s&&a&&r&&!o){const t=n.get(a);"function"==typeof t?t(r):c(`%c${e}%c: Attempted to retrieve a blob (%s) from queue, but the blobID was not a function! Skipping...`,i,"",a),n.delete(a)}});const s=window.fetch;window.fetch=async function(...t){const o=await s.apply(this,t),a=o.clone(),r=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",l=a.headers.get("content-type")||"";if(l.includes("application/json"))console.log(`%c${e}%c: Sending JSON message about endpoint "${r}"`,i,""),a.json().then(t=>{window.postMessage({source:"blue-marble",endpoint:r,jsonData:t},"*")}).catch(t=>{console.error(`%c${e}%c: Failed to parse JSON: `,i,"",t)});else if(l.includes("image/")&&!r.includes("openfreemap")&&!r.includes("maps")){const t=Date.now(),s=await a.blob();return console.log(`%c${e}%c: ${n.size} Sending IMAGE message about endpoint "${r}"`,i,""),new Promise(o=>{const l=crypto.randomUUID();n.set(l,t=>{o(new Response(t,{headers:a.headers,status:a.status,statusText:a.statusText})),console.log(`%c${e}%c: ${n.size} Processed blob "${l}"`,i,"")}),window.postMessage({source:"blue-marble",endpoint:r,blobID:l,blobData:s,blink:t})}).catch(s=>{const o=Date.now();console.error(`%c${e}%c: Failed to Promise blob!`,i,""),console.groupCollapsed(`%c${e}%c: Details of failed blob Promise:`,i,""),console.log(`Endpoint: ${r}\nThere are ${n.size} blobs processing...\nBlink: ${t.toLocaleString()}\nTime Since Blink: ${String(Math.floor(o/6e4)).padStart(2,"0")}:${String(Math.floor(o/1e3)%60).padStart(2,"0")}.${String(o%1e3).padStart(3,"0")} MM:SS.mmm`),console.error("Exception stack:",s),console.groupEnd()})}return o}});var ft=`div:has(>confetti-piece){position:absolute;inset:0;overflow:hidden;pointer-events:none}confetti-piece{position:absolute;top:-10px;width:var(--size);height:var(--size);background:currentColor;transform:translate3d(var(--x),-10vh,0) rotate(var(--rot));animation:fall var(--duration) linear var(--delay);will-change:transform;pointer-events:none}@keyframes fall{to{transform:translate3d(var(--x),110vh,0) rotate(calc(var(--rot) + 720deg))}}.bm-screenreader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.bm-W{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000;transition:all .3s ease,transform 0s;top:75px;left:60px;width:auto;max-height:fit-content;max-width:calc(100% - 135px);font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}.bm-S{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5ch;background:url('data:image/svg+xml;utf8,') repeat;cursor:grab;width:100%;height:fit-content}.bm-S.bm-M{cursor:grabbing}.bm-W:has(.bm-S.bm-M){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-S.bm-M{pointer-events:auto}.bm-T{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}.bm-W h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}.bm-S h1,.bm-y{font-size:1.2em;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-shadow:3px 0px rgba(21,48,99,.5),-3px 0px rgba(21,48,99,.5),0px 3px rgba(21,48,99,.5),0px -3px rgba(21,48,99,.5),3px 3px rgba(21,48,99,.5),-3px 3px rgba(21,48,99,.5),3px -3px rgba(21,48,99,.5),-3px -3px rgba(21,48,99,.5)}.bm-S div:has(h1){display:contents}.bm-W h2{display:inline-block;font-size:larger;font-weight:700;vertical-align:middle}.bm-W h3{display:inline-block;font-size:large;font-weight:700}.bm-L.bm-h{width:fit-content;margin-left:auto;margin-right:auto}.bm-L{margin:.5em 0}.bm-W button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}.bm-W button:hover,.bm-W button:focus-visible{background-color:#1061e5}.bm-W button:active,.bm-W button:disabled{background-color:#2e97ff}.bm-W button:disabled{text-decoration:line-through;cursor:not-allowed}.bm-s{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}.bm-J{vertical-align:middle}.bm-J svg{width:50%;margin:0 auto;fill:#111}.bm-W button.bm-A{background-color:unset}.bm-A.bm-f:hover,.bm-A.bm-f:focus{background-color:#ffffff2b}.bm-A.bm-f:active{background-color:#ffffff38}.bm-A.bm-g:hover,.bm-A.bm-g:focus{background-color:#0000002b}.bm-A.bm-g:active{background-color:#00000038}input[type=number].bm-C{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}input[type=number].bm-C::-webkit-outer-spin-button,input[type=number].bm-C::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-K)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-K,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-W select{color:#fff;background-color:#144eb9;border-radius:1em;padding:0 .5ch}.bm-W label:has(input[type=checkbox]){display:flex;width:fit-content;gap:1ch}.bm-W input[type=checkbox]{width:1em}.bm-m{overflow:hidden;max-height:calc(100% - 5px);transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-W textarea{font-size:small;background-color:#0003;padding:0 .5ch;height:5.25em;width:100%}.bm-W a:not(:has(*)){text-decoration:underline}.bm-W small{font-size:x-small;color:#d3d3d3}.bm-W ul li{list-style:disc;margin-left:5ch}.bm-W .bm-L.bm-H{max-height:var(--bm-H-max-height, calc(80vh - 150px) );overflow:auto}.bm-x{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.5ch}.bm-D{display:flex;align-content:center;justify-content:center;align-items:center;gap:.5ch}.bm-_{white-space:pre;letter-spacing:0;line-height:1!important;font-size:1.6em;font-family:monospace}.bm-N .bm-L:not(#bm-F .bm-L){margin-top:.25em;margin-bottom:.25em}.bm-N h1:not(#bm-F h1){font-size:1em}#bm-t p svg{display:inline;height:1em;fill:#fff}#bm-E{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:1em 3ch}#bm-t .bm-z{width:fit-content;max-width:35ch;background-color:#153063e6;border-radius:1em;padding:.5em;gap:1ch;transition:background-color .3s ease}#bm-t .bm-z:hover,#bm-t.bm-z:focus-within{background-color:#112855e6}#bm-t .bm-a{display:block;border:thick double darkslategray;width:fit-content;height:fit-content;padding:1ch}#bm-t .bm-z[data-id="-2"] .bm-a{background:conic-gradient(#a00,#aa0 16.6%,#0a0,#0aa 50%,#00a 66.6%,#a0a,#a00)}#bm-t .bm-z[data-id="-1"] .bm-a{background:url('data:image/svg+xml;utf8,') repeat;background-color:transparent!important}#bm-t .bm-z[data-id="-1"] .bm-a svg{fill:#fff!important}#bm-t .bm-z[data-id="0"] .bm-a{background-color:transparent!important}#bm-t .bm-a button{padding:.75em .5ch}#bm-t .bm-a svg{width:4ch}#bm-t .bm-z>.bm-x{flex-direction:column;align-items:flex-start;gap:0}#bm-t .bm-z small{font-size:.75em}#bm-t .bm-z.bm-I{display:none}#bm-t.bm-N{--bm-H-max-height: 100%;display:grid;grid-template-rows:auto minmax(0,1fr);width:300px;height:min(70vh,32rem);min-width:260px;min-height:220px;max-width:min(1000px,calc(100vw - 16px))!important;max-height:min(1400px,calc(100vh - 16px))!important;overflow:hidden;box-sizing:border-box;position:fixed;transition:transform 0s}#bm-t.bm-N .bm-m{display:grid;grid-template-rows:auto auto auto minmax(0,1fr);grid-row:2;min-height:0;min-width:0;overflow:hidden}#bm-t.bm-N #bm-E{flex-direction:column;align-items:stretch;gap:.25em;width:100%;align-self:stretch;min-width:0;box-sizing:border-box}#bm-t.bm-N .bm-z{width:100%;max-width:none;align-self:stretch;flex:1 1 auto;min-width:0;margin:0;padding:0;box-sizing:border-box}#bm-t.bm-N .bm-z>.bm-x{width:100%;min-width:0;flex:1 1 auto}#bm-t.bm-N .bm-L.bm-H{display:block;grid-row:4;min-height:0;min-width:0;height:100%;width:100%;max-height:100%!important;overflow:auto;box-sizing:border-box}#bm-t.bm-N .bm-1y{position:absolute;right:0;bottom:0;display:block;width:28px;height:28px;z-index:5;cursor:nwse-resize;pointer-events:auto;opacity:1;touch-action:none;user-select:none;background:transparent;border:none;box-shadow:none}#bm-t.bm-N .bm-1y:hover,#bm-t.bm-N .bm-1y.bm-1S{opacity:1}#bm-t.bm-N .bm-a{display:flex;width:100%;min-width:0;flex:1 1 auto;gap:.5ch;align-items:center;padding:.1em .5ch;border:none;border-radius:1em;box-sizing:border-box}#bm-t.bm-N .bm-a button{padding:.5em .25ch;flex:0 0 auto}#bm-t.bm-N .bm-a svg{width:3ch}#bm-t.bm-N .bm-z h2{font-size:.75em;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#bm-t #bm-2{font-size:1em}#bm-l div:has(>.bm-3){width:fit-content;justify-content:flex-start}#bm-l .bm-3{display:flex;flex-direction:column;width:13%}#bm-l .bm-3 span{width:fit-content;margin:auto;font-size:.7em}#bm-l .bm-3 button{width:fit-content;padding:0;border-radius:0}#bm-l .bm-3 svg{stroke:#333;stroke-width:.02px;width:100%;min-width:1.5ch;max-width:14.5ch}#bm-l .bm-3 button:hover svg,#bm-l .bm-3 button:focus svg{opacity:.9}#bm-l .bm-n{display:grid;grid-template-columns:1fr 1fr 1fr;width:25%;min-width:3ch;max-width:15ch}#bm-l .bm-n>button{width:100%;padding:0;aspect-ratio:1 / 1;background-color:#fff;border:#333 1px solid;border-radius:0;box-sizing:border-box}#bm-l .bm-n>button[data-status=Incorrect]{background-color:brown}#bm-l .bm-n>button[data-status=Template]{background-color:#2f4f4f}#bm-l .bm-n>button:hover,#bm-l .bm-n>button:focus{opacity:.8}#bm-B{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}#bm-B>.bm-L{width:100%;justify-content:flex-start;background-color:#153063e6;border-radius:1em;padding:.5em;transition:background-color .3s ease}#bm-B>.bm-L:hover,#bm-B>.bm-L:focus-within{background-color:#112855e6}#bm-B .bm-1{height:100%;font-size:xxx-large}#bm-B .bm-0{flex-direction:column;align-items:flex-start;gap:0}`;GM_addStyle(ft);var gt,wt="@font-face{font-family:'Roboto Mono';font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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)format('woff2');}";wt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(wt)):((gt=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",gt.rel="preload",gt.as="style",gt.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(gt));var xt=JSON.parse(GM_getValue("bmUserSettings","{}")),yt=(new class{constructor(){this.qe=null,this.Ze=null,this.Qe="#bm-p"}Ke(t){return this.Ze=t,this.qe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.Qe)}),this}ti(){return this.qe}observe(t,e=!1,i=!1){t.observe(this.Ze,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,nt),this.window=null,this.Ct="bm-F",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?this.$t("Main window already exists!"):(this.window=this.H({id:this.Ct,class:"bm-W bm-N",style:"top: 10px; left: unset; right: 75px;"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Blue Marble"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().D().H({class:"bm-m"}).H({class:"bm-L"}).P({class:"bm-T",src:"data:image/png;base64,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"},(t,e)=>{const i=new Date;204==Math.floor((i.getTime()-new Date(i.getFullYear(),0,1))/864e5)+1&&(e.parentNode.style.position="relative",e.parentNode.innerHTML=e.parentNode.innerHTML+'',e.onload=()=>{(new L).qt(document.querySelector(`#${this.Ct}`))})}).D().W(1,{textContent:this.name}).D().D().F().D().H({class:"bm-L"}).B({id:"bm-w",textContent:"Droplets:"}).D().V().D().B({id:"bm-q",textContent:"Next level in..."}).D().V().D().B({textContent:"Charges: "}).gt(Date.now(),1e3,{style:"font-weight: 700;"},(t,e)=>{t.p.ei=e.id}).D().D().D().F().D().H({class:"bm-L"}).H({class:"bm-L"}).lt({class:"bm-s bm-J",style:"margin-top: 0;",innerHTML:''},(t,e)=>{e.onclick=()=>{const e=t.p?.ii;e?.[0]?(t.ct("bm-Q",e?.[0]||""),t.ct("bm-R",e?.[1]||""),t.ct("bm-O",e?.[2]||""),t.ct("bm-P",e?.[3]||"")):t.$t("Coordinates are malformed! Did you try clicking on the canvas first?")}}).D().dt({type:"number",id:"bm-Q",class:"bm-C",placeholder:"Tl X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-R",class:"bm-C",placeholder:"Tl Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-O",class:"bm-C",placeholder:"Px X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-P",class:"bm-C",placeholder:"Px Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().D().H({class:"bm-L"}).ut({class:"bm-K",textContent:"Upload Template",accept:"image/png, image/jpeg, image/webp, image/bmp, image/gif"}).D().D().H({class:"bm-L bm-x"}).lt({textContent:"Disable","data-button-status":"shown"},(t,e)=>{e.onclick=()=>{e.disabled=!0,"shown"==e.dataset.buttonStatus?(t.p?.re?.ni(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.re?.ni(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.Mt("Enabled templates!")),e.disabled=!1}}).D().lt({textContent:"Create"},(t,e)=>{e.onclick=()=>{const e=document.querySelector(`#${this.Ct} .bm-K`),i=document.querySelector("#bm-Q");if(!i.checkValidity())return i.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const n=document.querySelector("#bm-R");if(!n.checkValidity())return n.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const s=document.querySelector("#bm-O");if(!s.checkValidity())return s.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const o=document.querySelector("#bm-P");if(!o.checkValidity())return o.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");e?.files[0]?(t?.p?.re.We(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(n.value),Number(s.value),Number(o.value)]),t.Mt("Drew to canvas!")):t.$t("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>this.si()}).D().D().H({class:"bm-L"}).bt({id:this.v,placeholder:`Status: Sleeping...\nVersion: ${this.version}`,readOnly:!0}).D().D().H({class:"bm-L bm-x",style:"margin-bottom: 0; flex-direction: column;"}).H({class:"bm-x"}).lt({class:"bm-s",innerHTML:"⚙️",title:"Settings"},(t,e)=>{e.onclick=()=>{t.$.St()}}).D().lt({class:"bm-s",innerHTML:"🧙",title:"Template Wizard"},(t,e)=>{e.onclick=()=>{const e=t.p?.re;new ut(this.name,this.version,e?.schemaVersion,e).St()}}).D().lt({class:"bm-s",innerHTML:"🎨",title:"Template Color Converter"},(t,e)=>{e.onclick=()=>{window.open("https://pepoafonso.github.io/color_converter_wplace/","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",innerHTML:"🌐",title:"Official Blue Marble Website"},(t,e)=>{e.onclick=()=>{window.open("https://bluemarble.lol/","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",title:"Donate to SwingTheVine",innerHTML:''},(t,e)=>{e.onclick=()=>{window.open("https://ko-fi.com/swingthevine","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",innerHTML:"🤝",title:"Credits"},(t,e)=>{e.onclick=()=>{new tt(this.name,this.version).St()}}).D().D().O({textContent:"Made by SwingTheVine",style:"margin-top: auto;"}).D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}si(){new et(this).we()}}(bt,pt)),$t=new class{constructor(t,i){e(this,ot),this.name=t,this.version=i,this._e=null,this.$=null,this.schemaVersion="2.0.0",this.oi=null,this.Pe="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.It=1e3,this.Ve=3,this.Ye=3,this.ce=function(t){const e=v;e.unshift({id:-1,premium:!1,name:"Erased",rgb:[222,250,206]}),e.unshift({id:-2,premium:!1,name:"Other",rgb:[0,0,0]});const i=new Map;for(const n of e){if(0==n.id||-2==n.id)continue;const e=n.rgb[0],s=n.rgb[1],o=n.rgb[2];for(let a=-t;a<=t;a++)for(let r=-t;r<=t;r++)for(let l=-t;l<=t;l++){const t=e+a,h=s+r,c=o+l;if(t<0||t>255||h<0||h>255||c<0||c>255)continue;const m=(255<<24|c<<16|h<<8|t)>>>0;i.has(m)||i.set(m,n.id)}}return{palette:e,Yt:i}}(this.Ye),this.Ge=null,this.ai="",this.Le=[],this.Fe=null,this.ri=!0,this.li=null,this.Ne=new Map}hi(t){this._e=t}k(t){this.$=t,i(this,ot,at).call(this)}He(t,e){const n=Number(t);Number.isFinite(n)&&(e?this.Ne.set(n,!0):this.Ne.delete(n),i(this,ot,rt).call(this))}async ci(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async We(t,e,n){this.Fe||(this.Fe=await this.ci(),console.log("Creating JSON...")),this._e.Mt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Ht:0,Lt:m(this.oi||0,this.Pe),file:t,coords:n}),o=!this.$?.Nt?.flags?.includes("hl-noSkip"),a=this.$?.Nt?.flags?.includes("hl-agSkip");console.log(`Should Skip: ${o}; Should Agg Skip: ${a}`);const{Rt:r,Et:l}=await s.Wt(this.It,this.ce,o,a);s.Ot=r;const h={total:s.At.total,colors:Object.fromEntries(s.At.colors)};this.Fe.templates[`${s.Ht} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.Le=[],this.Le.push(s),this._e.Mt(`Template created at ${n.join(", ")}!`),console.log(Object.keys(this.Fe.templates).length),console.log(this.Fe),console.log(this.Le),console.log(JSON.stringify(this.Fe)),await i(this,ot,lt).call(this)}mi(){}async di(){this.Fe||(this.Fe=await this.ci(),console.log("Creating JSON..."))}async ui(){l("Downloading all templates..."),console.log(this.Le);for(const t of this.Le)await this.bi(t),await n(500)}async Ae(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(console.log(t),Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.bi(new H({displayName:i.name,Ht:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ot:i.tiles})),await n(500))}async bi(t){t.jt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.ze(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",pi:"uniquify",onload:()=>{l(`Download of template '${e}' complete!`)},onerror:(t,i)=>{h(`Download of template '${e}' failed because ${t}! Details: ${i}`)},ontimeout:()=>{c(`Download of template '${e}' has timed out!`)}})}async ze(t){console.log(t);const e=t.Ot,i=Object.keys(e).sort(),n=await Promise.all(i.map(t=>{return i=e[t],new Promise((t,e)=>{const n=new Image;n.onload=()=>t(n),n.onerror=e,n.src="data:image/png;base64,"+i});var i}));let s=1/0,o=1/0,a=0,r=0;i.forEach((t,e)=>{const[i,l,h,c]=t.split(",").map(Number),m=n[e],d=i*this.It+h,u=l*this.It+c;s=Math.min(s,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.Ve),r=Math.max(r,u+m.height/this.Ve)}),console.log(`Absolute coordinates: (${s}, ${o}) and (${a}, ${r})`);const l=a-s,h=r-o,c=l*this.Ve,m=h*this.Ve;console.log(`Template Width: ${l}\nTemplate Height: ${h}\nCanvas Width: ${c}\nCanvas Height: ${m}`);const d=new OffscreenCanvas(c,m),u=d.getContext("2d");i.forEach((t,e)=>{const[i,a,r,l]=t.split(",").map(Number),h=n[e],c=i*this.It+r,m=a*this.It+l;console.log(`Drawing tile (${i}, ${a}, ${r}, ${l}) (${c}, ${m}) at (${c-s}, ${m-o}) on the canvas...`),u.drawImage(h,(c-s)*this.Ve,(m-o)*this.Ve,h.width,h.height)}),u.globalCompositeOperation="destination-over",u.drawImage(d,0,-1),u.drawImage(d,0,1),u.drawImage(d,-1,0),u.drawImage(d,1,0);const b=new OffscreenCanvas(l,h),p=b.getContext("2d");return p.imageSmoothingEnabled=!1,p.drawImage(d,0,0,l*this.Ve,h*this.Ve,0,0,l,h),b.convertToBlob({type:"image/png"})}async fi(t,e){if(!this.ri)return t;const n=this.It*this.Ve;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.Le;console.log(o),o.sort((t,e)=>t.Ht-e.Ht),console.log(o);const a=o.map(t=>{const i=Object.keys(t.Ot).filter(t=>t.startsWith(e));if(0===i.length)return null;const n=i.map(e=>{const i=e.split(",");return{gi:t,Vt:t.Ot[e],Bt:t.Bt?.[e],wi:[i[0],i[1]],xi:[i[2],i[3]]}});return n?.[0]}).filter(Boolean);console.log(a);const r=a?.length||0;if(console.log(`templateCount = ${r}`),!(r>0))return this._e.Mt(`Sleeping\nVersion: ${this.version}`),t;{const t=s(o.filter(t=>Object.keys(t.Ot).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.At.total||0),0));this._e.Mt(`Displaying ${r} template${1==r?"":"s"}.\nTotal pixels: ${t}`)}const l=await createImageBitmap(t),h=new OffscreenCanvas(n,n),c=h.getContext("2d");c.imageSmoothingEnabled=!1,c.beginPath(),c.rect(0,0,n,n),c.clip(),c.clearRect(0,0,n,n),c.drawImage(l,0,0,n,n);const m=c.getImageData(0,0,n,n),d=new Uint32Array(m.data.buffer),u=this.$?.Nt?.highlight||[[2,0,0]],b=u?.[0],p=1==u?.length&&2==b?.[0]&&0==b?.[1]&&0==b?.[2];for(const t of a){console.log("Template:"),console.log(t);const n=!!t.gi.At?.colors?.get(-1);let s=t.Bt.slice();const o=Number(t.xi[0])*this.Ve,a=Number(t.xi[1])*this.Ve;if(0!=this.Ne.size||n||c.drawImage(t.Vt,o,a),!s){const e=c.getImageData(o,a,t.Vt.width,t.Vt.height);s=new Uint32Array(e.data.buffer)}const r=Date.now(),{Je:l,Xe:h}=i(this,ot,ct).call(this,{Ue:d,Ge:s,Re:[o,a,t.Vt.width,t.Vt.height],Ee:u,je:p});let m=0;const b=0;for(const[t,e]of l)t!=b&&(m+=e);0==this.Ne.size&&!n&&p||(console.log("Colors to filter: ",this.Ne),c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(h.buffer),t.Vt.width,t.Vt.height)),o,a)),console.log(`Finished calculating correct pixels & filtering colors for the tile ${e} in ${(Date.now()-r)/1e3} seconds!\nThere are ${m} correct pixels.`),void 0===t.gi.At.correct&&(t.gi.At.correct={}),t.gi.At.correct[e]=l}return await h.convertToBlob({type:"image/png"})}async yi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&await i(this,ot,ht).call(this,t)}ni(t){this.ri=t}}(bt,pt),vt=new class{constructor(t){this.re=t,this.$i=!1,this.ei="",this.ii=[],this.Mi=[]}Ci(t){window.addEventListener("message",async e=>{const i=e.data,n=i.jsonData;if(!i||"blue-marble"!==i.source)return;if(!i.endpoint)return;const o=i.endpoint?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();switch(console.log('%cBlue Marble%c: Recieved message about "%s"',"color: cornflowerblue;","",o),o){case"me":if(n.status&&"2"!=n.status?.toString()[0])return void t.$t("You are not logged in or Wplace is offline!\nCould not fetch userdata.");const e=Math.ceil(Math.pow(Math.floor(n.level)*Math.pow(30,.65),1/.65)-n.pixelsPainted);if(console.log(n.id),(n.id||0===n.id)&&console.log(m(n.id,"!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~")),this.re.oi=n.id,0!=this.ei.length){const t=document.querySelector("#"+this.ei);if(t){const e=n.charges;t.dataset.endDate=Date.now()+(e.max-e.count)*e.cooldownMs}}t.ct("bm-w",`Droplets: ${s(n.droplets)}`),t.ct("bm-q",`Next level in ${s(e)} pixel${1==e?"":"s"}`);break;case"pixel":const o=i.endpoint.split("?")[0].split("/").filter(t=>t&&!isNaN(Number(t))),l=new URLSearchParams(i.endpoint.split("?")[1]),h=[l.get("x"),l.get("y")];if(this.ii.length&&(!o.length||!h.length))return void t.$t("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ii=[...o,...h];const c=(a=o,r=h,[parseInt(a[0])%4*1e3+parseInt(r[0]),parseInt(a[1])%4*1e3+parseInt(r[1])]),d=document.querySelectorAll("span");for(const t of d){const e=t.textContent.trim();if(e.includes(c[0])&&e.includes(c[1])){let e=document.querySelector("#bm-p");o[0],o[1],h[0],h[1];const i=["Tl X:","Tl Y:","Px X:","Px Y:"],n=["bm-Y","bm-Z","bm-U","bm-V"],s=[...o,...h];if(e)for(const[t,e]of n.entries())document.getElementById(e).textContent=`${i[t]??"??:"} ${s[t]}`;else{e=document.createElement("span"),e.id="bm-p",e.style="display: flex; flex-wrap: wrap; gap: 0 1ch; font-size: small;";for(const[t,o]of s.entries()){const a=document.createElement("span");a.id=n[s.indexOf(o)??""],a.textContent=`${i[t]??"??:"} ${o}`,e.appendChild(a)}t.parentNode.parentNode.parentNode.insertAdjacentElement("afterend",e)}}}break;case"tile":case"tiles":let u=i.endpoint.split("/");u=[parseInt(u[u.length-2]),parseInt(u[u.length-1].replace(".png",""))];const b=i.blobID,p=i.blobData,f=Date.now(),g=await this.re.fi(p,u);console.log(`Finished loading the tile in ${(Date.now()-f)/1e3} seconds!`),window.postMessage({source:"blue-marble",blobID:b,blobData:g,blink:i.blink});break;case"robots":this.$i="false"==n.userscript?.toString().toLowerCase();break}var a,r})}async Ti(t){console.log("Sending heartbeat to telemetry server...");let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return void console.log("Telemetry is disabled, not sending heartbeat.");const i=navigator.userAgent;let n=await this.Si(i),s=this.ki(i);GM_xmlhttpRequest({method:"POST",url:"https://telemetry.thebluecorner.net/heartbeat",headers:{"Content-Type":"application/json"},data:JSON.stringify({uuid:e.uuid,version:t,browser:n,os:s}),onload:t=>{200!==t.status&&h("Failed to send heartbeat:",t.statusText)},onerror:t=>{h("Error sending heartbeat:",t)}})}async Si(t=navigator.userAgent){return(t=t||"").includes("OPR/")||t.includes("Opera")?"Opera":t.includes("Edg/")?"Edge":t.includes("Vivaldi")?"Vivaldi":t.includes("YaBrowser")?"Yandex":t.includes("Kiwi")?"Kiwi":t.includes("Brave")?"Brave":t.includes("Firefox/")?"Firefox":t.includes("Chrome/")?"Chrome":t.includes("Safari/")?"Safari":navigator.brave&&"function"==typeof navigator.brave.isBrave&&await navigator.brave.isBrave()?"Brave":"Unknown"}ki(t=navigator.userAgent){return/Windows NT 11/i.test(t=t||"")?"Windows 11":/Windows NT 10/i.test(t)?"Windows 10":/Windows NT 6\.3/i.test(t)?"Windows 8.1":/Windows NT 6\.2/i.test(t)?"Windows 8":/Windows NT 6\.1/i.test(t)?"Windows 7":/Windows NT 6\.0/i.test(t)?"Windows Vista":/Windows NT 5\.1|Windows XP/i.test(t)?"Windows XP":/Mac OS X 10[_\.]15/i.test(t)?"macOS Catalina":/Mac OS X 10[_\.]14/i.test(t)?"macOS Mojave":/Mac OS X 10[_\.]13/i.test(t)?"macOS High Sierra":/Mac OS X 10[_\.]12/i.test(t)?"macOS Sierra":/Mac OS X 10[_\.]11/i.test(t)?"OS X El Capitan":/Mac OS X 10[_\.]10/i.test(t)?"OS X Yosemite":/Mac OS X 10[_\.]/i.test(t)?"macOS":/Android/i.test(t)?"Android":/iPhone|iPad|iPod/i.test(t)?"iOS":/Linux/i.test(t)?"Linux":"Unknown"}}($t),Mt=new class extends N{constructor(t,i,n){var s;super(t,i),e(this,C),this.Nt=n,(s=this.Nt).flags??(s.flags=[]),this.Di=structuredClone(this.Nt),this.Ni="bmUserSettings",this.Hi=5e3,this.Li=0,setInterval(this.Oi.bind(this),this.Hi)}async Oi(){await this.Bi()}async Bi(t=!1){const e=JSON.stringify(this.Nt);e!=JSON.stringify(this.Di)&&(t||Date.now()-this.Li>this.Hi)&&(await GM.setValue(this.Ni,e),this.Di=structuredClone(this.Nt),this.Li=Date.now(),console.log(e))}async De(){await this.Bi(!0)}ke(t,e=void 0){const i=this.Nt?.flags?.indexOf(t)??-1;-1!=i&&!0!==e?this.Nt?.flags?.splice(i,1):-1==i&&!1!==e&&this.Nt?.flags?.push(t)}kt(){const t='',e='',n=this.Nt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().F().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.Nt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.ke("hl-noTrans",!t.target.checked)}).D().L({id:"bm-4",textContent:"Choose a preset:",style:"font-weight: 700;"}).D().H({class:"bm-D",role:"group","aria-labelledby":"bm-4"}).H({class:"bm-3"}).B({textContent:"None"}).D().lt({innerHTML:t,"aria-label":'Preset "None"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"None")}).D().D().H({class:"bm-3"}).B({textContent:"Cross"}).D().lt({innerHTML:e,"aria-label":'Preset "Cross Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Cross")}).D().D().H({class:"bm-3"}).B({textContent:"X"}).D().lt({innerHTML:e.replace('d="M1,0H2V1H3V2H2V3H1V2H0V1H1Z"','d="M0,0V1H3V0H2V3H3V2H0V3H1V0Z"'),"aria-label":'Preset "X Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"X")}).D().D().H({class:"bm-3"}).B({textContent:"Full"}).D().lt({innerHTML:t.replace("#fff","#2f4f4f"),"aria-label":'Preset "Full Template"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Full")}).D().D().D().L({id:"bm-b",textContent:"Create a custom pattern:",style:"font-weight: 700;"}).D().H({class:"bm-n",role:"group","aria-labelledby":"bm-b"});for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){const s=n[n.findIndex(([,i,n])=>i==e&&n==t)]?.[0]??0;let o="Disabled";1==s?o="Incorrect":2==s&&(o="Template"),this.window=this.lt({"data-status":o,"aria-label":`Sub-pixel ${o.toLowerCase()}`},(n,s)=>{s.onclick=()=>i(this,C,T).call(this,s,[e,t])}).D()}this.window=this.D().D().D()}Dt(){this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().F().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.Nt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.ke("hl-noSkip",!t.target.checked)}).D().R({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.Nt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.ke("hl-agSkip",t.target.checked)}).D().D().D()}}(bt,pt,xt);yt.k(Mt),yt.S(vt),$t.hi(yt),$t.k(Mt);var Ct=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(Ct),console.log(xt),console.log(Object.keys(xt).length),0==Object.keys(xt).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>vt.Ti(pt),18e5);var Tt=xt?.telemetry;if(console.log(`Telemetry is ${!(null==Tt)}`),null==Tt||Tt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,mt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Ii=n,this.uuid=s}async St(){if(document.querySelector(`#${this.Ct}`))return void this.$t("Telemetry window already exists!");const t=await this.p.Si(navigator.userAgent),e=this.p.ki(navigator.userAgent);this.window=this.H({id:this.Ct,class:"bm-W",style:"height: 80vh; z-index: 9998;"}).H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:`${this.name} Telemetry`}).D().D().F().D().H({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,mt,dt).call(this,this.Ii);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,mt,dt).call(this,0);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"More Information"},(t,e)=>{e.onclick=()=>{window.open("https://github.com/SwingTheVine/Wplace-TelemetryServer#telemetry-data","_blank","noopener noreferrer")}}).D().D().H({class:"bm-L bm-H"}).H({class:"bm-L"}).W(2,{textContent:"Legal"}).D().L({textContent:`We collect anonymous telemetry data such as your browser, OS, and script version to make the experience better for everyone. The data is never shared personally. The data is never sold. You can turn this off by pressing the "Disable" button, but keeping it on helps us improve features and reliability faster. Thank you for supporting ${this.name}!`}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Non-Legal Summary"}).D().L({innerHTML:'You can disable telemetry by pressing the "Disable" button. If you would like to read more about what information we collect, press the "More Information" button.
This is the data stored on our servers:'}).D().X().Z({innerHTML:`A unique identifier (UUIDv4) generated by Blue Marble. This enables our telemetry to function without tracking your actual user ID.
Your UUID is: ${r(this.uuid)}`}).D().Z({innerHTML:`The version of Blue Marble you are using.
Your version is: ${r(this.version)}`}).D().Z({innerHTML:`Your browser type, which is used to determine Blue Marble outages and browser popularity.
Your browser type is: ${r(t)}`}).D().Z({innerHTML:`Your OS type, which is used to determine Blue Marble outages and OS popularity.
Your OS type is: ${r(e)}`}).D().Z({innerHTML:"The date and time that Blue Marble sent the telemetry information."}).D().D().L({innerHTML:'All of the data mentioned above is aggregated every hour. This means every hour, anything that could even remotly be considered "personal data" is deleted from our server. Here, "aggregated" data means things like "42 people used Blue Marble on Google Chrome this hour", which can\'t be used to identify anyone in particular.'}).D().D().D().D().D().N(this.Tt)}}(bt,pt,1,xt?.uuid);t.S(vt),t.St()}!async function(){await $t.yi(Ct),yt.St(),yt.si(),vt.Ci(yt),new MutationObserver((t,e)=>{const i=document.querySelector("#color-1");if(!i)return;let n=document.querySelector("#bm-G");if(!n){n=document.createElement("button"),n.id="bm-G",n.textContent="Move ↑",n.className="btn btn-soft",n.onclick=function(){const t=this.parentNode.parentNode.parentNode.parentNode,e="Move ↑"==this.textContent;t.parentNode.className=t.parentNode.className.replace(e?"bottom":"top",e?"top":"bottom"),t.style.borderTopLeftRadius=e?"0px":"var(--radius-box)",t.style.borderTopRightRadius=e?"0px":"var(--radius-box)",t.style.borderBottomLeftRadius=e?"var(--radius-box)":"0px",t.style.borderBottomRightRadius=e?"var(--radius-box)":"0px",this.textContent=e?"Move ↓":"Move ↑"};const t=i.parentNode.parentNode.parentNode.parentNode.querySelector("h2");t.parentNode?.appendChild(n)}}).observe(document.body,{childList:!0,subtree:!0}),l(`%c${bt}%c (${pt}) userscript has loaded!`,"color: cornflowerblue;","")}()})(); +(()=>{var t=t=>{throw TypeError(t)},e=(e,i,s)=>i.has(e)?t("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(e):i.set(e,s),i=(e,i,s)=>(((e,i)=>{i.has(e)||t("Cannot access private method")})(e,i),s);function s(t){return new Promise(e=>setTimeout(e,t))}function n(t){return(new Intl.NumberFormat).format(t)}function o(t){return new Intl.NumberFormat(void 0,{style:"percent",t:2,i:2}).format(t)}function a(t){return t.toLocaleString(void 0,{o:"long",l:"numeric",h:"2-digit",m:"2-digit",u:"2-digit"})}function r(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function l(...t){(0,console.log)(...t)}function h(...t){(0,console.error)(...t)}function c(...t){(0,console.warn)(...t)}function m(t,e){if(0===t)return e[0];let i="";const s=e.length;for(;t>0;)i=e[t%s]+i,t=Math.floor(t/s);return i}function d(t,e){let i=0;const s=e.length;for(const n of t){const t=e.indexOf(n);-1==t&&h(`Invalid character '${n}' encountered whilst decoding! Is the decode alphabet/base incorrect?`),i=i*s+t}return i}function u(t){let e="";for(let i=0;i(t/=255)<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*e[0]+.7152*e[1]+.0722*e[2]}function f(t,e,i){return Array.isArray(t)&&([t,e,i]=t),(1<<24|t<<16|e<<8|i).toString(16).slice(1)}var g,w,x,$,y,v=[{id:0,premium:!1,name:"Transparent",rgb:[0,0,0]},{id:1,premium:!1,name:"Black",rgb:[0,0,0]},{id:2,premium:!1,name:"Dark Gray",rgb:[60,60,60]},{id:3,premium:!1,name:"Gray",rgb:[120,120,120]},{id:4,premium:!1,name:"Light Gray",rgb:[210,210,210]},{id:5,premium:!1,name:"White",rgb:[255,255,255]},{id:6,premium:!1,name:"Deep Red",rgb:[96,0,24]},{id:7,premium:!1,name:"Red",rgb:[237,28,36]},{id:8,premium:!1,name:"Orange",rgb:[255,127,39]},{id:9,premium:!1,name:"Gold",rgb:[246,170,9]},{id:10,premium:!1,name:"Yellow",rgb:[249,221,59]},{id:11,premium:!1,name:"Light Yellow",rgb:[255,250,188]},{id:12,premium:!1,name:"Dark Green",rgb:[14,185,104]},{id:13,premium:!1,name:"Green",rgb:[19,230,123]},{id:14,premium:!1,name:"Light Green",rgb:[135,255,94]},{id:15,premium:!1,name:"Dark Teal",rgb:[12,129,110]},{id:16,premium:!1,name:"Teal",rgb:[16,174,166]},{id:17,premium:!1,name:"Light Teal",rgb:[19,225,190]},{id:18,premium:!1,name:"Dark Blue",rgb:[40,80,158]},{id:19,premium:!1,name:"Blue",rgb:[64,147,228]},{id:20,premium:!1,name:"Cyan",rgb:[96,247,242]},{id:21,premium:!1,name:"Indigo",rgb:[107,80,246]},{id:22,premium:!1,name:"Light Indigo",rgb:[153,177,251]},{id:23,premium:!1,name:"Dark Purple",rgb:[120,12,153]},{id:24,premium:!1,name:"Purple",rgb:[170,56,185]},{id:25,premium:!1,name:"Light Purple",rgb:[224,159,249]},{id:26,premium:!1,name:"Dark Pink",rgb:[203,0,122]},{id:27,premium:!1,name:"Pink",rgb:[236,31,128]},{id:28,premium:!1,name:"Light Pink",rgb:[243,141,169]},{id:29,premium:!1,name:"Dark Brown",rgb:[104,70,52]},{id:30,premium:!1,name:"Brown",rgb:[149,104,42]},{id:31,premium:!1,name:"Beige",rgb:[248,178,119]},{id:32,premium:!0,name:"Medium Gray",rgb:[170,170,170]},{id:33,premium:!0,name:"Dark Red",rgb:[165,14,30]},{id:34,premium:!0,name:"Light Red",rgb:[250,128,114]},{id:35,premium:!0,name:"Dark Orange",rgb:[228,92,26]},{id:36,premium:!0,name:"Light Tan",rgb:[214,181,148]},{id:37,premium:!0,name:"Dark Goldenrod",rgb:[156,132,49]},{id:38,premium:!0,name:"Goldenrod",rgb:[197,173,49]},{id:39,premium:!0,name:"Light Goldenrod",rgb:[232,212,95]},{id:40,premium:!0,name:"Dark Olive",rgb:[74,107,58]},{id:41,premium:!0,name:"Olive",rgb:[90,148,74]},{id:42,premium:!0,name:"Light Olive",rgb:[132,197,115]},{id:43,premium:!0,name:"Dark Cyan",rgb:[15,121,159]},{id:44,premium:!0,name:"Light Cyan",rgb:[187,250,242]},{id:45,premium:!0,name:"Light Blue",rgb:[125,199,255]},{id:46,premium:!0,name:"Dark Indigo",rgb:[77,49,184]},{id:47,premium:!0,name:"Dark Slate Blue",rgb:[74,66,132]},{id:48,premium:!0,name:"Slate Blue",rgb:[122,113,196]},{id:49,premium:!0,name:"Light Slate Blue",rgb:[181,174,241]},{id:50,premium:!0,name:"Light Brown",rgb:[219,164,99]},{id:51,premium:!0,name:"Dark Beige",rgb:[209,128,81]},{id:52,premium:!0,name:"Light Beige",rgb:[255,197,165]},{id:53,premium:!0,name:"Dark Peach",rgb:[155,82,73]},{id:54,premium:!0,name:"Peach",rgb:[209,128,120]},{id:55,premium:!0,name:"Light Peach",rgb:[250,182,164]},{id:56,premium:!0,name:"Dark Tan",rgb:[123,99,82]},{id:57,premium:!0,name:"Tan",rgb:[156,132,107]},{id:58,premium:!0,name:"Dark Slate",rgb:[51,57,65]},{id:59,premium:!0,name:"Slate",rgb:[109,117,141]},{id:60,premium:!0,name:"Light Slate",rgb:[179,185,209]},{id:61,premium:!0,name:"Dark Stone",rgb:[109,100,63]},{id:62,premium:!0,name:"Stone",rgb:[148,140,107]},{id:63,premium:!0,name:"Light Stone",rgb:[205,197,158]}],M=class{constructor(t,i){e(this,g),this.name=t,this.version=i,this.p=null,this.$=null,this.v="bm-r",this.M=null,this.C=null,this.T=[]}S(t){this.p=t}D(t){this.$=t}N(){return this.T.length>0&&(this.C=this.T.pop()),this}k(t){t?.appendChild(this.M),this.M=null,this.C=null,this.T=[]}O(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}L(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"p",{},t)),this}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"small",{},t)),this}I(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"span",{},t)),this}B(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"details",{},t)),this}P(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"summary",{},t)),this}A(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"img",{},t)),this}F(t,e={},s=()=>{}){return s(this,i(this,g,w).call(this,"h"+t,{},e)),this}W(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}U(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"form",{},t)),this}G(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"fieldset",{},t)),this}R(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"legend",{},t)),this}j(t={},e=()=>{}){const s={};t.textContent?(s.textContent=t.textContent,delete t.textContent):t.innerHTML&&(s.innerHTML=t.innerHTML,delete t.textContent);const n=i(this,g,w).call(this,"label",s),o=i(this,g,w).call(this,"input",{type:"checkbox"},t);return n.insertBefore(o,n.firstChild),this.N(),e(this,n,o),this}Y(t={},e=()=>{}){const s=i(this,g,w).call(this,"label",{textContent:t.textContent??"",for:t.id??""});return delete t.textContent,this.N(),e(this,s,i(this,g,w).call(this,"select",{},t)),this}J(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"option",{},t)),this}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ul",{},t)),this}q(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"menu",{},t)),this}Z(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"li",{},t)),this}K(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"table",{},t)),this}tt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"caption",{},t)),this}et(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"thead",{},t)),this}it(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tbody",{},t)),this}st(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tfoot",{},t)),this}nt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tr",{},t)),this}ot(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"th",{},t)),this}rt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"td",{},t)),this}lt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"button",{},t)),this}ht(t={},e=()=>{}){const s=t.title??t.textContent??"Help: No info";delete t.textContent,t.title=`Help: ${s}`;const n={textContent:"?",className:"bm-10",onclick:()=>{this.ct(this.v,s)}};return e(this,i(this,g,w).call(this,"button",n,t)),this}dt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"input",{},t)),this}ut(t={},e=()=>{}){const s=t.textContent??"";delete t.textContent;const n=i(this,g,w).call(this,"div"),o=i(this,g,w).call(this,"input",{type:"file",tabindex:"-1","aria-hidden":"true"},t);this.N();const a=i(this,g,w).call(this,"button",{textContent:s});return this.N(),this.N(),a.addEventListener("click",()=>{o.click()}),o.addEventListener("change",()=>{a.style.maxWidth=`${a.offsetWidth}px`,o.files.length>0?a.textContent=o.files[0].name:a.textContent=s}),e(this,n,o,a),this}bt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"textarea",{},t)),this}ft(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{class:"bm-S"},t)),this}gt(t=Date.now(),e=500,s={},n=()=>{}){const o="bm--",a=s?.id||o+"-"+crypto.randomUUID().slice(0,8),r={class:o},l=i(this,g,w).call(this,"time",r,s);return l.id=a,l.dataset.endDate=t,setInterval(()=>{if(!l.isConnected)return;const t=Math.max(l.dataset.endDate-Date.now(),0),e=Math.floor(t/1e3),i=Math.floor(e/3600),s=Math.floor(e%60),n=Math.floor(e%3600/60);l.setAttribute("datetime",`PT${i}H${n}M${s}S`),l.textContent=String(i).padStart(2,"0")+":"+String(n).padStart(2,"0")+":"+String(s).padStart(2,"0")},e),n(this,l),this}ct(t,e,i=!1){const s=document.getElementById(t.replace(/^#/,""));s&&(s instanceof HTMLInputElement?s.value=e:i?s.textContent=e:s.innerHTML=e)}wt(t){if(t.disabled)return;t.disabled=!0,t.style.textDecoration="none";const e=t.closest(".bm-W"),i=t.closest(".bm-S"),s=e.querySelector("h1"),n=e.querySelector(".bm-m");if(e.parentElement.append(e),"expanded"==t.dataset.buttonStatus){n.style.height=n.scrollHeight+"px",e.style.width=e.scrollWidth+"px",n.style.height="0",n.addEventListener("transitionend",function e(){n.style.display="none",t.disabled=!1,t.style.textDecoration="",n.removeEventListener("transitionend",e)});const i=s.cloneNode(!0),o=i.textContent;t.nextElementSibling.appendChild(i),t.textContent="▶",t.dataset.buttonStatus="collapsed",t.ariaLabel=`Unminimize window "${o}"`}else{const s=i.querySelector("h1"),o=s.textContent;s.remove(),n.style.display="",n.style.height="0",e.style.width="",n.style.height=n.scrollHeight+"px",n.addEventListener("transitionend",function e(){n.style.height="",t.disabled=!1,t.style.textDecoration="",n.removeEventListener("transitionend",e)}),t.textContent="▼",t.dataset.buttonStatus="expanded",t.ariaLabel=`Minimize window "${o}"`}}xt(t,e,i={}){const s=document.querySelector(t),n=document.querySelector(e),o=i?.$t??(()=>{});if(!s||!n)return void this.yt(`Can not drag! ${s?"":"moveMe"} ${s||n?"":"and "}${n?"":"iMoveThings "}was not found!`);let a,r=!1,l=0,h=null,c=0,m=0,d=0,u=0,b=null;const p=()=>{if(r){const t=Math.abs(c-d),e=Math.abs(m-u);(t>.5||e>.5)&&(c=d,m=u,s.style.transform=`translate(${c}px, ${m}px)`,s.style.left="0px",s.style.top="0px",s.style.right=""),h=requestAnimationFrame(p)}},f=(t,e)=>{r=!0,b=s.getBoundingClientRect(),a=t-b.left,l=e-b.top;const i=window.getComputedStyle(s).transform;if(i&&"none"!==i){const t=new DOMMatrix(i);c=t.m41,m=t.m42}else c=b.left,m=b.top;d=c,u=m,document.body.style.userSelect="none",n.classList.add("bm-M"),document.addEventListener("mousemove",w),document.addEventListener("touchmove",x,{passive:!1}),document.addEventListener("mouseup",g),document.addEventListener("touchend",g),document.addEventListener("touchcancel",g),h&&cancelAnimationFrame(h),p()},g=()=>{r=!1,h&&(cancelAnimationFrame(h),h=null),document.body.style.userSelect="",n.classList.remove("bm-M"),document.removeEventListener("mousemove",w),document.removeEventListener("touchmove",x),document.removeEventListener("mouseup",g),document.removeEventListener("touchend",g),document.removeEventListener("touchcancel",g),o({element:s,x:c,y:m}),b=null},w=t=>{r&&b&&(d=t.clientX-a,u=t.clientY-l)},x=t=>{if(r&&b){const e=t.touches[0];if(!e)return;d=e.clientX-a,u=e.clientY-l,t.preventDefault()}};n.addEventListener("mousedown",function(t){t.preventDefault(),f(t.clientX,t.clientY)}),n.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(f(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t,e,i={}){const s=document.querySelector(t),n=document.querySelector(e),o=i?.$t??(()=>{});if(!s||!n)return void this.yt(`Can not resize! ${s?"":"resizeMe"} ${s||n?"":"and "}${n?"":"iResizeThings "}was not found!`);let a=!1,r=0,l=0,h=0,c=0,m=0,d=0,u=0,b=0,p=null;const f=()=>Number.isFinite(i?.maxWidth)?i.maxWidth:window.innerWidth-16,g=()=>Number.isFinite(i?.maxHeight)?i.maxHeight:window.innerHeight-16,w=Number.isFinite(i?.minWidth)?i.minWidth:200,x=Number.isFinite(i?.minHeight)?i.minHeight:160,$=(t,e,i)=>Math.min(Math.max(t,e),Math.max(e,i)),y=()=>{if(a){const t=Math.abs(m-u),e=Math.abs(d-b);(t>.5||e>.5)&&(m=u,d=b,s.style.width=`${m}px`,s.style.height=`${d}px`),p=requestAnimationFrame(y)}},v=(t,e)=>{a=!0,r=t,l=e,h=s.offsetWidth,c=s.offsetHeight,m=h,d=c,u=h,b=c,document.body.style.userSelect="none",n.classList.add("bm-2b"),document.addEventListener("mousemove",C),document.addEventListener("touchmove",T,{passive:!1}),document.addEventListener("mouseup",M),document.addEventListener("touchend",M),document.addEventListener("touchcancel",M),p&&cancelAnimationFrame(p),y()},M=()=>{a=!1,p&&(cancelAnimationFrame(p),p=null),document.body.style.userSelect="",n.classList.remove("bm-2b"),document.removeEventListener("mousemove",C),document.removeEventListener("touchmove",T),document.removeEventListener("mouseup",M),document.removeEventListener("touchend",M),document.removeEventListener("touchcancel",M),o({element:s,width:m,height:d})},C=t=>{a&&(u=$(h+(t.clientX-r),w,f()),b=$(c+(t.clientY-l),x,g()))},T=t=>{if(!a)return;const e=t?.touches?.[0];e&&(u=$(h+(e.clientX-r),w,f()),b=$(c+(e.clientY-l),x,g()),t.preventDefault())};n.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),v(t.clientX,t.clientY)}),n.addEventListener("touchstart",t=>{const e=t?.touches?.[0];e&&(t.preventDefault(),t.stopPropagation(),v(e.clientX,e.clientY))},{passive:!1})}Mt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.v,"Status: "+t,!0)}yt(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.v,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},s={}){const n=document.createElement(t);this.M?(this.C?.appendChild(n),this.T.push(this.C),this.C=n):(this.M=n,this.C=n);for(const[t,s]of Object.entries(e))i(this,g,x).call(this,n,t,s);for(const[t,e]of Object.entries(s))i(this,g,x).call(this,n,t,e);return n},x=function(t,e,i){"class"==e?t.classList.add(...i.split(/\s+/)):"for"==e?t.htmlFor=i:"tabindex"==e?t.tabIndex=Number(i):"readonly"==e?t.readOnly="true"==i||"1"==i:"maxlength"==e?t.maxLength=Number(i):e.startsWith("data")?t.dataset[e.slice(5).split("-").map((t,e)=>0==e?t:t[0].toUpperCase()+t.slice(1)).join("")]=i:e.startsWith("aria")?t.setAttribute(e,i):t[e]=i};var C,T,S,D,N,k=class extends M{constructor(t,i){super(t,i),e(this,$),this.window=null,this.Ct="bm-l",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.O({id:this.Ct,class:"bm-W"}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Settings"}).N().N().W().N().L({textContent:"Settings take 5 seconds to save."}).N().O({class:"bm-L bm-H"},(t,e)=>{this.Dt(),this.Nt()}).N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}Dt(){i(this,$,y).call(this,"Pixel Highlight")}Nt(){i(this,$,y).call(this,"Template")}};$=new WeakSet,y=function(t){this.window=this.O({class:"bm-L"}).F(2,{textContent:t}).N().W().N().L({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).N().N()},C=new WeakSet,T=function(t,e){t.disabled=!0;const i=t.dataset.status,s=this.kt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];let n=[2,0,0];const o=s;switch(i){case"Disabled":t.dataset.status="Incorrect",t.ariaLabel="Sub-pixel incorrect",n=[1,...e];break;case"Incorrect":t.dataset.status="Template",t.ariaLabel="Sub-pixel template",n=[2,...e];break;case"Template":t.dataset.status="Disabled",t.ariaLabel="Sub-pixel disabled",n=[0,...e];break}const a=s.findIndex(([,t,e])=>t==n[1]&&e==n[2]);0!=n[0]?-1!=a?o[a]=n:o.push(n):-1!=a&&o.splice(a,1),this.kt.highlight=o,t.disabled=!1},S=async function(t){const e=document.querySelectorAll(".bm-3 button");for(const t of e)t.disabled=!0;let i=[0,0,0,0,2,0,0,0,0];switch(t){case"Cross":i=[0,1,0,1,2,1,0,1,0];break;case"X":i=[1,0,1,0,2,0,1,0,1];break;case"Full":i=[2,2,2,2,2,2,2,2,2];break}const n=document.querySelector(".bm-n")?.childNodes??[];for(let t=0;t{const[s,n,o,a]=e.split(",").map(Number);(n>>24==0?0:n.get(e)??-2;const a=o.get(s);o.set(s,a?a+1:1)}return console.log(o),o};var L,H,I,B,P,A,z,F,W,U,V,G,R,j,E,Y,J,X,_,q=class{constructor(){this.Xt=Math.ceil(80/1300*window.innerWidth),this._t=v.slice(1)}qt(t){const e=document.createElement("div");for(let t=0;t{t.parentNode.childElementCount<=1?t.parentNode.remove():t.remove()},e.appendChild(t)}t.appendChild(e)}},Z=class extends HTMLElement{};customElements.define("confetti-piece",Z);var Q,K,tt,et,it,st,nt=class extends M{constructor(t){super(t.name,t.version),e(this,L),this.window=null,this.Ct="bm-t",this.Zt="bm-E",this.Tt=document.body,this.$=t.$??null,this.Qt="ftr-oWin",this.Kt="windowFilter",this.te=null,this.ee=null,this.ie=null,this.se=null,this.ne=1e4,this.oe=260,this.ae=220,this.re=1e3,this.le=1400,this.he=t.p?.he,this.ce='',this.me='';const{palette:i,Jt:s}=this.he.de;this.palette=i,this.ue=0,this.be=0,this.pe=new Map,this.fe=new Map,this.ge=0,this.we=0,this.timeRemaining=0,this.xe="",this.sortPrimary="total",this.sortSecondary="descending",this.showUnused=!1}$e(){i(this,L,I).call(this)?this.ye():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,L,A).call(this);this.window=this.O({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"🗗","aria-label":'Switch to windowed mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,L,B).call(this,!0),i(this,L,A).call(this),this.ye()},e.ontouchend=()=>{e.click()}}).N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,L,A).call(this),e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h bm-1K"}).F(1,{textContent:"Color Filter"}).N().N().W().N().O({class:"bm-L bm-x bm-h bm-1C",style:"gap: 1.5ch;"}).lt({class:"bm-1s",textContent:"Hide All Colors"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!1)}).N().lt({class:"bm-1s",textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!0)}).N().N().W().N().O({class:"bm-L bm-H bm-1p"}).O({class:"bm-L bm-1x",style:"margin-left: 2.5ch; margin-right: 2.5ch;"}).O({class:"bm-L bm-1q"}).I({id:"bm-i",innerHTML:"Tiles Loaded: 0 / ???"}).N().U().N().I({id:"bm-d",innerHTML:"Correct Pixels: ???"}).N().U().N().I({id:"bm-j",innerHTML:"Total Pixels: ???"}).N().U().N().I({id:"bm-7",innerHTML:"Complete: ??? (???)"}).N().U().N().I({id:"bm-8",innerHTML:"??? ???"}).N().N().O({class:"bm-L bm-1Y"}).L({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.ce.replace("{e.onclick=t=>{t.preventDefault();const e=new FormData(document.querySelector(`#${this.Ct} form`)),s={};for(const[t,i]of e)s[t]=i;console.log(`Primary: ${s.sortPrimary}; Secondary: ${s.sortSecondary}; Unused: ${"on"==s.showUnused}`),i(this,L,J).call(this,s.sortPrimary,s.sortSecondary,"on"==s.showUnused)}}).N().N().N().N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,L,Y).call(this,t),i(this,L,P).call(this),i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${n(this.ue)} / ${n(this.be)}`),this.ct("#bm-d",`Correct Pixels: ${n(this.ge)}`),this.ct("#bm-j",`Total Pixels: ${n(this.we)}`),this.ct("#bm-7",`Remaining: ${n((this.we||0)-(this.ge||0))} (${o(((this.we||0)-(this.ge||0))/(this.we||1))})`),this.ct("#bm-8",`Completed at: `),i(this,L,z).call(this)}ye(){if(document.querySelector(`#${this.Ct}`))return void i(this,L,A).call(this);this.window=this.O({id:this.Ct,class:"bm-W bm-N",style:`width: 300px; height: min(70vh, 32rem); min-width: ${this.oe}px; min-height: ${this.ae}px; max-width: min(${this.re}px, calc(100vw - 16px)); max-height: min(${this.le}px, calc(100vh - 16px));`}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>{const i=document.querySelector("#bm-2");i&&(i.style.display="expanded"==e.dataset.buttonStatus?"none":""),t.wt(e)},e.ontouchend=()=>{e.click()}}).N().O().I({id:"bm-2",class:"bm-y",style:"font-weight: 700;"}).N().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"🗖","aria-label":'Switch to fullscreen mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,L,B).call(this,!1),i(this,L,A).call(this),this.St()},e.ontouchend=()=>{e.click()}}).N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,L,A).call(this),e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h bm-1K"}).F(1,{textContent:"Color Filter"}).N().N().W().N().O({class:"bm-L bm-x bm-h bm-1C",style:"gap: 1.5ch;"}).lt({class:"bm-1s",textContent:"None"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!1)}).N().lt({class:"bm-1s",textContent:"All"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!0)}).N().N().W().N().O({class:"bm-L bm-H bm-1p"}).N().N().O({class:"bm-1L",title:"Resize Color Filter window","aria-label":"Resize Color Filter window",role:"presentation",textContent:"◢",style:"position: absolute; right: 0; bottom: 0; width: 28px; height: 28px; display: flex; align-items: flex-end; justify-content: flex-end; padding-right: 4px; padding-bottom: 4px; box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; touch-action: none; user-select: none; font-size: 8px; line-height: 1; color: rgba(255,255,255,0.95); background: transparent; border: none; box-shadow: none;"}).N().N().k(this.Tt),i(this,L,E).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,L,Y).call(this,t),i(this,L,P).call(this),i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),i(this,L,z).call(this)}ve(){i(this,L,_).call(this);const t=document.querySelector(`#${this.Zt}`),e={};for(const t of this.palette){const i=this.pe.get(t.id)??0,s=n(i);let a=0,r="0",l=o(1);0!=i&&(a=this.fe.get(t.id)??"???","number"!=typeof a&&this.ue==this.be&&t.id&&(a=0),r="string"==typeof a?a:n(a),l=isNaN(a/i)?"???":o(a/i));const h=parseInt(i)-parseInt(a);e[t.id]={Me:i,Ce:s,Te:a,Se:r,De:l,Ne:h}}if(document.querySelector("#bm-2")){const t=this.ge.toString().length>7?this.ge.toString().slice(0,2)+"…"+this.ge.toString().slice(-3):this.ge.toString(),e=this.we.toString().length>7?this.we.toString().slice(0,2)+"…"+this.we.toString().slice(-3):this.we.toString();this.ct("#bm-2",`${t}/${e}`,!0)}if(this.ct("#bm-i",`Tiles Loaded: ${n(this.ue)} / ${n(this.be)}`),this.ct("#bm-d",`Correct Pixels: ${n(this.ge)}`),this.ct("#bm-j",`Total Pixels: ${n(this.we)}`),this.ct("#bm-7",`Remaining: ${n((this.we||0)-(this.ge||0))} (${o(((this.we||0)-(this.ge||0))/(this.we||1))})`),this.ct("#bm-8",`Completed at: `),!t)return e;const s=Array.from(t.children);for(const t of s){const i=parseInt(t.dataset.id),{Te:s,Se:n,De:o,Me:a,Ce:r,Ne:l}=e[i];t.dataset.correct=Number.isNaN(parseInt(s))?"0":s,t.dataset.total=a,t.dataset.percent="%"==o.slice(-1)?o.slice(0,-1):"0",t.dataset.incorrect=l||0;const h=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-9`);h&&(h.textContent=`${n} / ${r}`);const c=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-6`);c&&(c.textContent=`${"number"!=typeof l||isNaN(l)?"???":l} incorrect pixel${1==l?"":"s"}. Completed: ${o}`)}i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};L=new WeakSet,H=function(){var t,e;return this.$?((t=this.$.kt)[e=this.Kt]??(t[e]={}),this.$.kt[this.Kt]):null},I=function(){const t=i(this,L,H).call(this);return"windowed"==t?.mode||"fullscreen"!=t?.mode},B=function(t){const e=i(this,L,H).call(this);e&&(e.mode=t?"windowed":"fullscreen"),this.$&&(this.$.ke(this.Qt,t),this.$.Oe())},P=function(){const t=document.querySelector(`#${this.Ct} #bm-c`),e=document.querySelector(`#${this.Ct} #bm-5`),i=document.querySelector(`#${this.Ct} #bm-e`);t instanceof HTMLSelectElement&&(t.value=this.sortPrimary),e instanceof HTMLSelectElement&&(e.value=this.sortSecondary),i instanceof HTMLInputElement&&(i.checked=this.showUnused)},A=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,L,R).call(this,t),i(this,L,F).call(this),i(this,L,W).call(this),t?.remove()},z=function(){i(this,L,F).call(this),this.se=setInterval(()=>{document.querySelector(`#${this.Ct}`)?this.ve():i(this,L,F).call(this)},this.ne)},F=function(){this.se&&(clearInterval(this.se),this.se=null)},W=function(){this.te&&(this.te.disconnect(),this.te=null),this.ee&&(window.removeEventListener("resize",this.ee),this.ee=null),this.ie&&(clearTimeout(this.ie),this.ie=null)},U=function(t,e,i){const s=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),s)},V=function(t,e,i){const s=Math.max(8,window.innerWidth-t.offsetWidth-8),n=Math.max(8,window.innerHeight-t.offsetHeight-8);return{x:Math.min(Math.max(Math.round(Number(e)||8),8),s),y:Math.min(Math.max(Math.round(Number(i)||8),8),n)}},G=function(t){const e=i(this,L,H).call(this);if(!e||!t)return;const s=Number(e.width),n=Number(e.height),o=Number.isFinite(s),a=Number.isFinite(n);o&&(e.width=i(this,L,U).call(this,s,this.oe,Math.min(this.re,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,L,U).call(this,n,this.ae,Math.min(this.le,window.innerHeight-16)),t.style.height=`${e.height}px`),requestAnimationFrame(()=>{if(!t.isConnected)return;const s=Number(e.x),n=Number(e.y);if(!Number.isFinite(s)||!Number.isFinite(n))return;const o=i(this,L,V).call(this,t,s,n);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${o.x}px, ${o.y}px)`,o.x==s&&o.y==n||(e.x=o.x,e.y=o.y,this.$?.Oe())})},R=function(t){const e=i(this,L,H).call(this);if(!e||!t?.isConnected||!t.classList.contains("bm-N"))return;const s=t.getBoundingClientRect(),n=i(this,L,U).call(this,s.width,this.oe,Math.min(this.re,window.innerWidth-16)),o=i(this,L,U).call(this,s.height,this.ae,Math.min(this.le,window.innerHeight-16));Math.round(s.width)!=n&&(t.style.width=`${n}px`),Math.round(s.height)!=o&&(t.style.height=`${o}px`);const a=i(this,L,V).call(this,t,s.left,s.top);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${a.x}px, ${a.y}px)`,e.x=a.x,e.y=a.y,e.width=n,e.height=o,this.$?.Oe()},j=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,L,R).call(this,t)},e)},E=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,L,W).call(this),i(this,L,G).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{$t:({element:t})=>i(this,L,R).call(this,t)}),this.vt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-1L`,{minWidth:this.oe,minHeight:this.ae,maxWidth:Math.min(this.re,window.innerWidth-16),maxHeight:Math.min(this.le,window.innerHeight-16),$t:({element:t})=>i(this,L,R).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,L,j).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,L,j).call(this,t,0),window.addEventListener("resize",this.ee))},Y=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N");console.log(`Is Windowed Mode: ${e}`);const i=new M(this.name,this.version);i.O({id:this.Zt});const s=this.ve();for(const t of this.palette){const n="#"+f(t.rgb).toUpperCase(),o=p(t.rgb);let a=1.05/(o+.05)>(o+.05)/.05?"white":"black";t.id||(a="transparent");const r="white"==a?"bm-f":"bm-g",{Te:l,Se:h,De:c,Me:m,Ce:d,Ne:u}=s[t.id],b=!!this.he.Le.get(t.id);if(e){const e=`background-size: auto 100%; background-repeat: repeat-x; background-image: url("data:image/svg+xml;utf8,");`;i.O({class:"bm-L bm-z bm-x","data-id":t.id,"data-name":t.name,"data-premium":+t.premium,"data-correct":Number.isNaN(parseInt(l))?"0":l,"data-total":m,"data-percent":"%"==c.slice(-1)?c.slice(0,-1):"0","data-incorrect":u||0}).O({class:"bm-a",style:`background-color: rgb(${t.rgb?.map(t=>Number(t)||0).join(",")});${t.premium?e:""}`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.me.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.me.replace("Number(t)||0).join(",")});`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.me.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.me.replace("{const o=s.getAttribute("data-"+t),a=n.getAttribute("data-"+t),r=parseFloat(o),l=parseFloat(a),h=!isNaN(r),c=!isNaN(l);if(i?s.classList.remove("bm-I"):Number(s.getAttribute("data-total"))||s.classList.add("bm-I"),h&&c)return"ascending"===e?r-l:l-r;{const t=o.toLowerCase(),i=a.toLowerCase();return ti?"ascending"===e?1:-1:0}}),n.forEach(t=>s.appendChild(t))},X=function(t){const e=document.querySelector(`#${this.Zt}`),i=Array.from(e.children);for(const e of i){if(e.classList?.contains("bm-I"))continue;const i=e.querySelector(".bm-a button");("hidden"!=i.dataset.state||t)&&("shown"==i.dataset.state&&t||i.click())}},_=function(){this.ue=0,this.be=0,this.we=0,this.ge=0,this.fe=new Map,this.pe=new Map;for(const t of this.he.Ie){const e=t.Pt?.total??0;this.we+=e??0;const i=t.Pt?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,s=this.pe.get(t)??0;this.pe.set(t,s+i)}const s=t.Pt?.correct??{};this.ue+=Object.keys(s).length,this.be+=Object.keys(t.Ht).length;for(const t of Object.values(s))for(const[e,i]of t){const t=Number(i)||0;this.ge+=t;const s=this.fe.get(e)??0;this.fe.set(e,s+t)}}console.log(`Tiles loaded: ${this.ue} / ${this.be}`),this.ge>=this.we&&this.we&&this.ue==this.be&&(new q).qt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.we-this.ge)*1e3+Date.now()),this.xe=a(this.timeRemaining)},Q=new WeakSet,K=async function(t,e,i){i.preventDefault();const s=await async function(t){let e="";return t&&(e=t.clipboardData.getData("text/plain")),0!=e.length||(await navigator.clipboard.readText().then(t=>{e=t}).catch(t=>{l("Failed to retrieve clipboard data using navigator! Using fallback methods...")}),0!=e.length||(e=window.clipboardData?.getData("Text"))),e}(i),n=s.split(/[^a-zA-Z0-9]+/).filter(t=>t).map(Number).filter(t=>!isNaN(t));2==n.length&&"bm-O"==e.id?(t.ct("bm-O",n?.[0]||""),t.ct("bm-P",n?.[1]||"")):1==n.length?t.ct(e.id,n?.[0]||""):(t.ct("bm-Q",n?.[0]||""),t.ct("bm-R",n?.[1]||""),t.ct("bm-O",n?.[2]||""),t.ct("bm-P",n?.[3]||""))};var ot=class extends M{constructor(t,i,s,n=void 0){super(t,i),e(this,tt),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Be=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Be?.scriptVersion,this.schemaVersion=this.Be?.schemaVersion,this.Pe=void 0,this.Ae=s,this.he=n}St(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();let t="";document.querySelector("#bm-F")||(t=t.concat("z-index: 9001;").trim()),this.window=this.O({id:this.Ct,class:"bm-W",style:t},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Template Wizard"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Template Wizard"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).N().N().O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Template Wizard"}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Status"}).N().L({id:"bm-v",textContent:"Loading template storage status..."}).N().N().O({class:"bm-L bm-H"}).F(2,{textContent:"Detected templates:"}).N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,tt,et).call(this),i(this,tt,it).call(this)}};tt=new WeakSet,et=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Ae.split(/[-\.\+]/);let s="";t[0]==e[0]?t[1]==e[1]?(s='Template storage health: Healthy!
No futher action required. (Reason: Semantic version matches)',this.Pe="Good"):(s='Template storage health: Poor!
You can still use your template, but some features may not work. It is recommended that you update Blue Marble\'s template storage. (Reason: MINOR version mismatch)',this.Pe="Poor"):t[0]Bad!
It is guaranteed that some features are broken. You might still be able to use the template. It is HIGHLY recommended that you download all templates and update Blue Marble\'s template storage before continuing. (Reason: MAJOR version mismatch)',this.Pe="Bad"):(s='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Pe="Dead");const n=`
If you want to continue using your current templates, then make sure the template storage (schema) is up-to-date.
If you don't want to update the template storage, then downgrade Blue Marble to version ${r(this.scriptVersion)} to continue using your templates.
Alternatively, if you don't care about corrupting the templates listed below, you can fix any issues with the template storage by uploading a new template.`,o=function(){const t=[...document.querySelectorAll("body > div > .hidden")].filter(t=>/version:/i.test(t.textContent));if(t[0]){const e=t[0].textContent?.match(/\d+/);return e?new Date(Number(e[0])):void 0}}();let l=o?a(o):"???";this.ct("#bm-v",`${s}
Your templates were created during Blue Marble version ${r(this.scriptVersion)} with schema version ${r(this.schemaVersion)}.
The current Blue Marble version is ${r(this.version)} and requires schema version ${r(this.Ae)}.
Wplace was last updated on ${l}.${"Good"!=this.Pe?n:""}`);const h=new M(this.name,this.version);"Dead"!=this.Pe&&(h.O({class:"bm-L bm-D bm-h",style:"gap: 1.5ch;"}),h.lt({textContent:"Download all templates"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.he.ze().then(()=>{e.disabled=!1})}}).N()),"Poor"!=this.Pe&&"Bad"!=this.Pe||h.lt({textContent:`Update template storage to ${this.Ae}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,tt,st).call(this,!0)}}).N(),h.N().k(document.querySelector("#bm-v").parentNode)},it=function(){const t=this.Be?.templates;if(Object.keys(t).length>0){const e=document.querySelector(`#${this.Ct} .bm-H`),i=new M(this.name,this.version);i.O({id:"bm-B",class:"bm-L"});for(const e in t){const s=e,o=t[e];if(t.hasOwnProperty(e)){const t=s.split(" "),e=Number(t?.[0]),a=d(t?.[1]||"0",this.he.Fe),r=o.name||`Template ${e||""}`,l=o?.coords?.split(",").map(Number),h=o.pixels?.total??void 0,c=void 0,m="number"==typeof e?n(e):"???",u="number"==typeof a?n(a):"???",b="number"==typeof h?n(h):"???";i.O({class:"bm-L bm-D"}).O({class:"bm-D",style:"flex-direction: column; gap: 0;"}).O({class:"bm-1",textContent:c||"🖼️"}).N().H({textContent:`#${m}`}).N().N().O({class:"bm-D bm-0"}).F(3,{textContent:r}).N().I({textContent:`Uploaded by user #${u}`}).N().I({textContent:`Coordinates: ${l.join(", ")}`}).N().I({textContent:`Total Pixels: ${b}`}).N().N().N()}}i.N().k(e)}},st=async function(t){if(t){const t=document.querySelector(`#${this.Ct} .bm-m`);t.innerHTML="",new M(this.name,this.version).O({class:"bm-L"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Template Wizard"}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Status"}).N().L({textContent:"Updating template storage. Please wait..."}).N().N().N().k(t)}GM_deleteValue("bmCoords");const e=this.Be?.templates;if(Object.keys(e).length>0)for(const[t,i]of Object.entries(e))if(e.hasOwnProperty(t)){const t=new O({displayName:i.name,Ht:i.tiles});t.Yt();const e=await this.he.We(t);await this.he.Ue(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new ot(this.name,this.version,this.Ae,this.he).St())};var at,rt,lt,ht,ct,mt,dt,ut,bt=ot;at=new WeakSet,rt=function(){const t=this.$?.kt?.filter,e=Array.isArray(t)?t:[];this.Le.clear();for(const t of e){const e=Number(t);Number.isFinite(e)&&this.Le.set(e,!0)}},lt=function(){this.$&&(this.$.kt.filter=Array.from(this.Le.keys()).map(t=>Number(t)).filter(t=>Number.isFinite(t)).sort((t,e)=>t-e),this.$.Oe())},ht=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Ve))},ct=async function(t){console.log("Parsing BlueMarble...");const e=t.templates;console.log(`BlueMarble length: ${Object.keys(e).length}`);const i=t?.schemaVersion,s=i.split(/[-\.\+]/),n=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;console.log(`BlueMarble Template Schema: ${i}; Script Version: ${o}`),s[0]==n[0]?(s[1]!=n[1]&&new bt(this.name,this.version,this.schemaVersion,this).St(),this.Ie=await async function({Bt:t,Ge:i,Ie:s}){if(Object.keys(e).length>0)for(const n in e){const o=n,a=e[n];if(console.log(`Template Key: ${o}`),e.hasOwnProperty(n)){const e=o.split(" "),n=Number(e?.[0]),r=e?.[1]||"0",l=a.name||`Template ${n||""}`,h={total:a.pixels?.total,colors:new Map(Object.entries(a.pixels?.colors||{}).map(([t,e])=>[Number(t),e]))},c=a.tiles,m={},d={},u=t*i;for(const t in c)if(console.log(t),c.hasOwnProperty(t)){const e=b(c[t]),i=new Blob([e],{type:"image/png"}),s=await createImageBitmap(i);m[t]=s;const n=new OffscreenCanvas(u,u).getContext("2d");n.drawImage(s,0,0);const o=n.getImageData(0,0,s.width,s.height);d[t]=new Uint32Array(o.data.buffer)}const p=new O({displayName:l,Ot:n||this.Ie?.length||0,Lt:r||""});p.Pt=h,p.Ht=m,p.It=d,s.push(p),console.log(this.Ie),console.log("^^^ This ^^^")}}return s}({Bt:this.Bt,Ge:this.Ge,Ie:this.Ie})):s[0]>>24&255,$=g>>>24&255,y=b.get(w)??-2,v=b.get(g)??-2;if(this.Le.get(y)&&(e[i*h+c]=g),-1==y){const t=536870912;this.Le.get(y)?e[i*h+c]=0:(u/o&1)==(f/o&1)?(e[i*h+c]=t,e[(i-1)*h+(c-1)]=t,e[(i-1)*h+(c+1)]=t,e[(i+1)*h+(c-1)]=t,e[(i+1)*h+(c+1)]=t):(e[i*h+c]=0,e[(i-1)*h+c]=t,e[(i+1)*h+c]=t,e[i*h+(c-1)]=t,e[i*h+(c+1)]=t)}if(!n&&x>m&&v!=y&&(d||$>m)){const t=e[i*h+c];for(const n of s){const[s,o,a]=n,r=0!=s?1!=s?t:4278190335:0;e[(i+a)*h+(c+o)]=r}}if(-1==y&&g<=m){const t=p.get(y);p.set(y,t?t+1:1);continue}if(x<=m||$<=m)continue;if(v!=y)continue;const M=p.get(y);p.set(y,M?M+1:1)}return console.log("List of template pixels that match the tile:"),console.log(p),{qe:p,Ze:e}},dt=new WeakSet,ut=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var pt=GM_info.script.name.toString(),ft=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",pt),e.setAttribute("bm-X","color: cornflowerblue;"),e.textContent=`(${t})();`,document.documentElement?.appendChild(e),e.remove()}(()=>{const t=document.currentScript,e=t?.getAttribute("bm-11")||"Blue Marble",i=t?.getAttribute("bm-X")||"",s=new Map;window.addEventListener("message",t=>{const{source:n,endpoint:o,blobID:a,blobData:r,blink:l}=t.data,h=Date.now()-l;if(console.groupCollapsed(`%c${e}%c: ${s.size} Recieved IMAGE message about blob "${a}"`,i,""),console.log(`Blob fetch took %c${String(Math.floor(h/6e4)).padStart(2,"0")}:${String(Math.floor(h/1e3)%60).padStart(2,"0")}.${String(h%1e3).padStart(3,"0")}%c MM:SS.mmm`,i,""),console.log(s),console.groupEnd(),"blue-marble"==n&&a&&r&&!o){const t=s.get(a);"function"==typeof t?t(r):c(`%c${e}%c: Attempted to retrieve a blob (%s) from queue, but the blobID was not a function! Skipping...`,i,"",a),s.delete(a)}});const n=window.fetch;window.fetch=async function(...t){const o=await n.apply(this,t),a=o.clone(),r=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",l=a.headers.get("content-type")||"";if(l.includes("application/json"))console.log(`%c${e}%c: Sending JSON message about endpoint "${r}"`,i,""),a.json().then(t=>{const s=r?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();if("me"==s)try{sessionStorage.setItem("bm-2i",JSON.stringify(t))}catch(t){console.warn(`%c${e}%c: Failed to cache "/me" payload`,i,"",t)}window.postMessage({source:"blue-marble",endpoint:r,jsonData:t},"*")}).catch(t=>{console.error(`%c${e}%c: Failed to parse JSON: `,i,"",t)});else if(l.includes("image/")&&!r.includes("openfreemap")&&!r.includes("maps")){const t=Date.now(),n=await a.blob();return console.log(`%c${e}%c: ${s.size} Sending IMAGE message about endpoint "${r}"`,i,""),new Promise(o=>{const l=crypto.randomUUID();s.set(l,t=>{o(new Response(t,{headers:a.headers,status:a.status,statusText:a.statusText})),console.log(`%c${e}%c: ${s.size} Processed blob "${l}"`,i,"")}),window.postMessage({source:"blue-marble",endpoint:r,blobID:l,blobData:n,blink:t})}).catch(n=>{const o=Date.now();console.error(`%c${e}%c: Failed to Promise blob!`,i,""),console.groupCollapsed(`%c${e}%c: Details of failed blob Promise:`,i,""),console.log(`Endpoint: ${r}\nThere are ${s.size} blobs processing...\nBlink: ${t.toLocaleString()}\nTime Since Blink: ${String(Math.floor(o/6e4)).padStart(2,"0")}:${String(Math.floor(o/1e3)%60).padStart(2,"0")}.${String(o%1e3).padStart(3,"0")} MM:SS.mmm`),console.error("Exception stack:",n),console.groupEnd()})}return o}});var gt=`div:has(>confetti-piece){position:absolute;inset:0;overflow:hidden;pointer-events:none}confetti-piece{position:absolute;top:-10px;width:var(--size);height:var(--size);background:currentColor;transform:translate3d(var(--x),-10vh,0) rotate(var(--rot));animation:fall var(--duration) linear var(--delay);will-change:transform;pointer-events:none}@keyframes fall{to{transform:translate3d(var(--x),110vh,0) rotate(calc(var(--rot) + 720deg))}}.bm-screenreader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.bm-W{--bm-surface-strong: rgba(9, 20, 42, .5);--bm-surface-soft: rgba(24, 41, 74, .28);--bm-surface-glass: rgba(255, 255, 255, .1);--bm-surface-glass-strong: rgba(255, 255, 255, .18);--bm-border-soft: rgba(255, 255, 255, .18);--bm-border-strong: rgba(163, 228, 255, .34);--bm-text-primary: rgba(17, 36, 66, .96);--bm-text-secondary: rgba(36, 57, 90, .84);--bm-accent-start: #baf6ff;--bm-accent-end: #81b6ff;--bm-accent-shadow: rgba(132, 182, 255, .22);--bm-font-body: "Rajdhani", "Segoe UI Variable Text", "Segoe UI", sans-serif;--bm-font-display: "Michroma", "Orbitron", "Segoe UI", sans-serif;--bm-font-mono: "Roboto Mono", "Rajdhani", "Courier New", monospace;position:fixed;isolation:isolate;overflow:hidden;background:radial-gradient(circle at 14% 12%,rgba(255,255,255,.24),transparent 18%),radial-gradient(circle at 86% 8%,rgba(186,246,255,.22),transparent 24%),radial-gradient(circle at 82% 84%,rgba(129,182,255,.18),transparent 28%),linear-gradient(145deg,#ffffff2e,#ffffff0f 22%,#6991d414 54%,#09142a2e);color:var(--bm-text-primary);padding:6px;border-radius:16px;border:1px solid var(--bm-border-soft);box-shadow:0 18px 40px #0003,inset 0 1px #ffffff38,inset 0 -1px #ffffff0d;z-index:9000;transition:background .32s ease,border-color .22s ease,box-shadow .22s ease,opacity .22s ease,transform 0s,width .22s ease,max-width .22s ease,max-height .22s ease;top:75px;left:60px;width:auto;max-height:fit-content;max-width:calc(100% - 135px);backdrop-filter:blur(26px) saturate(1.25);font-family:var(--bm-font-body);letter-spacing:.04em}.bm-W:before,.bm-W:after{content:"";position:absolute;inset:0;pointer-events:none}.bm-W:before{border-radius:inherit;padding:1px;background:linear-gradient(135deg,#ffffff73,#ffffff1f 24%,#baf6ff38 58%,#81b6ff4d);-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.85}.bm-W:after{border-radius:inherit;background:linear-gradient(180deg,rgba(255,255,255,.2),transparent 24%),radial-gradient(circle at 18% 0%,rgba(255,255,255,.22),transparent 22%),radial-gradient(circle at 88% 16%,rgba(186,246,255,.18),transparent 18%);opacity:1}.bm-S{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.28ch;padding:.18rem .24rem;border-radius:10px;border:1px solid rgba(255,255,255,.16);background:radial-gradient(circle at 0 0,rgba(255,255,255,.22) 0,transparent 42%),linear-gradient(135deg,#ffffff2e,#ffffff14);cursor:grab;width:100%;height:fit-content;box-shadow:inset 0 1px #ffffff29,0 6px 18px #0000001a}.bm-S.bm-M{cursor:grabbing}.bm-W:has(.bm-S.bm-M){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-S.bm-M{pointer-events:auto}.bm-T{display:inline-block;height:2.2em;margin-right:.45ch;padding:.2rem;border-radius:12px;vertical-align:middle;background:linear-gradient(135deg,#ffffff38,#ffffff14);box-shadow:inset 0 1px #ffffff29,0 8px 18px #0000001f}.bm-W h1{display:inline-block;font-size:1rem;font-weight:700;vertical-align:middle;font-family:var(--bm-font-display);text-transform:uppercase;letter-spacing:.14em;color:#10213cf5}.bm-S h1,.bm-y{font-size:.78rem;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-family:var(--bm-font-display);letter-spacing:.14em;color:#122542f2;text-shadow:0 1px 0 rgba(255,255,255,.28)}.bm-S div:has(h1){display:contents}.bm-W h2{display:inline-block;font-size:.88rem;font-weight:700;vertical-align:middle;font-family:var(--bm-font-display);letter-spacing:.1em;color:#122340f5}.bm-W h3{display:inline-block;font-size:large;font-weight:700;font-family:var(--bm-font-display);letter-spacing:.08em;color:#122340f5}.bm-W p{color:var(--bm-text-secondary);line-height:1.5;letter-spacing:.035em}.bm-W hr{border:none;height:1px;margin:.32rem 0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.28),transparent)}.bm-L.bm-h{width:fit-content;margin-left:auto;margin-right:auto}.bm-L{margin:.24em 0}.bm-W input,.bm-W select,.bm-W textarea,.bm-W button{font:inherit}.bm-W button{appearance:none;color:var(--bm-text-primary);font-family:var(--bm-font-display);background:linear-gradient(135deg,#ffffff38,#a4d0ff24);border:1px solid rgba(255,255,255,.22);border-radius:999px;padding:.28em .62em;min-height:1.78em;font-weight:600;letter-spacing:.1em;box-shadow:inset 0 1px #ffffff38,0 8px 20px #0000001a;transition:background .18s ease,border-color .18s ease,box-shadow .18s ease,filter .18s ease,opacity .18s ease,transform .18s ease}.bm-W button:hover,.bm-W button:focus-visible{background:linear-gradient(135deg,#ffffff47,#baf6ff2e);border-color:#e6f5ff5c;box-shadow:inset 0 1px #ffffff42,0 10px 22px #0000001f;transform:translateY(-1px)}.bm-W button:focus-visible,.bm-W input:focus-visible,.bm-W select:focus-visible,.bm-W textarea:focus-visible{outline:none;border-color:#74e7ff9e;box-shadow:0 0 0 3px #74e7ff26,inset 0 1px #ffffff1f}.bm-W button:active{transform:translateY(0) scale(.98);filter:brightness(.98);box-shadow:inset 0 1px #ffffff1f,0 8px 16px #12244e3d}.bm-W button:disabled{opacity:.56;cursor:not-allowed;text-decoration:none;transform:none;filter:saturate(.72);box-shadow:none}.bm-W button.bm-1D{color:#07203b;background:linear-gradient(135deg,#ffffff6b,#baf6ff57);border-color:#eff8ff6b;box-shadow:inset 0 1px #ffffff70,0 10px 22px #81b6ff24}.bm-W button.bm-1D:hover,.bm-W button.bm-1D:focus-visible{background:linear-gradient(135deg,#ffffff85,#ccfaff5c)}.bm-W button.bm-1s{background:linear-gradient(135deg,#ffffff29,#ffffff14);border-color:#ffffff2e;box-shadow:inset 0 1px #ffffff24,0 8px 20px #00000014}.bm-W button.bm-1s:hover,.bm-W button.bm-1s:focus-visible{background:linear-gradient(135deg,#ffffff3d,#baf6ff1f)}.bm-s{display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.16);inline-size:1.62rem;block-size:1.62rem;min-height:1.62rem!important;min-width:1.62rem;margin-top:0;text-align:center;line-height:1;padding:0!important;aspect-ratio:1 / 1;border-radius:50%!important;background:linear-gradient(135deg,#ffffff3d,#ffffff1a)!important;box-shadow:inset 0 1px #ffffff2e,0 8px 18px #0000001a!important;overflow:hidden;flex:0 0 auto;font-size:.74rem}.bm-s svg{width:70%;height:70%}.bm-J{vertical-align:middle}.bm-J svg{width:50%;margin:0 auto;fill:#111}.bm-W button.bm-A{background:transparent!important;box-shadow:none!important;border-color:transparent!important}.bm-A.bm-f:hover,.bm-A.bm-f:focus{background-color:#ffffff2e!important}.bm-A.bm-f:active{background-color:#ffffff3d!important}.bm-A.bm-g:hover,.bm-A.bm-g:focus{background-color:#00000024!important}.bm-A.bm-g:active{background-color:#0003!important}.bm-W input[type=number],.bm-W select,.bm-W textarea{color:var(--bm-text-primary);font-family:var(--bm-font-body);background:linear-gradient(180deg,#ffffff29,#ffffff0f);border:1px solid rgba(255,255,255,.18);border-radius:12px;box-shadow:inset 0 1px #ffffff1f}input[type=number].bm-C{appearance:auto;-moz-appearance:textfield;width:5.9ch;margin-left:1ch;padding:.2em .35ch;font-size:small}input[type=number].bm-C::-webkit-outer-spin-button,input[type=number].bm-C::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-K)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-K,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-W select{padding:.22em .45ch}.bm-W label:has(input[type=checkbox]){display:flex;width:fit-content;gap:1ch;align-items:center;color:var(--bm-text-secondary)}.bm-W input[type=checkbox]{width:1em;accent-color:#74e7ff}.bm-m{overflow:hidden;max-height:calc(100% - 5px);transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-W textarea{font-size:small;padding:.38em .52em;height:4em;width:100%;resize:vertical;line-height:1.45}.bm-W textarea::placeholder,.bm-W input::placeholder{color:#2f446699}.bm-W a:not(:has(*)){color:#1558a4f0;text-decoration:underline;text-decoration-color:#1558a459}.bm-W small{font-size:x-small;font-family:var(--bm-font-display);letter-spacing:.12em;color:var(--bm-text-secondary)}.bm-W ul li{list-style:disc;margin-left:5ch}.bm-W .bm-L.bm-H{max-height:var(--bm-H-max-height, calc(80vh - 150px) );overflow:auto;scrollbar-width:thin;scrollbar-color:rgba(146,221,255,.42) rgba(255,255,255,.05)}.bm-W .bm-L.bm-H::-webkit-scrollbar{width:10px;height:10px}.bm-W .bm-L.bm-H::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#74e7ff7a,#538dff66);border-radius:999px;border:2px solid transparent;background-clip:padding-box}.bm-W .bm-L.bm-H::-webkit-scrollbar-track{background:#ffffff0a;border-radius:999px}.bm-x{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.35ch}.bm-D{display:flex;align-content:center;justify-content:center;align-items:center;gap:.35ch}.bm-_{white-space:pre;letter-spacing:0;line-height:1!important;font-size:1.6em;font-family:monospace}.bm-N .bm-L:not(#bm-F .bm-L){margin-top:.18em;margin-bottom:.18em}.bm-N h1:not(#bm-F h1){font-size:1em}#bm-t p svg{display:inline;height:1em;fill:#fff}#bm-t:not(.bm-N){width:min(50rem,calc(100vw - .55rem));max-width:min(50rem,calc(100vw - .55rem))!important}#bm-t .bm-1K{padding-top:.08rem}#bm-t .bm-1C{gap:.22rem;flex-wrap:wrap;width:100%;padding:.16rem}#bm-t .bm-1C>button{flex:1 1 10rem}#bm-t .bm-1p{padding-right:.08rem}#bm-t .bm-1x{display:grid;grid-template-columns:minmax(16rem,20rem) minmax(0,1fr);gap:.24rem .3rem;align-items:stretch}#bm-t .bm-1x>hr,#bm-t .bm-1r{grid-column:1 / -1}#bm-t .bm-1q,#bm-t .bm-1Y,#bm-t .bm-1r{padding:.38rem .48rem;border-radius:13px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(155deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29,0 8px 20px #00000014}#bm-t .bm-1q{display:grid;gap:.18rem}#bm-t .bm-1q br{display:none}#bm-t .bm-1q span{display:block;padding:.28rem .38rem;border-radius:10px;background:linear-gradient(180deg,#fff3,#ffffff14)}#bm-t .bm-1Y p{margin:0}#bm-t .bm-1r fieldset{border:none;padding:0;margin:0}#bm-t .bm-1r legend{margin-bottom:.12rem}#bm-t .bm-1r .bm-L{margin-top:.1rem;margin-bottom:.1rem}#bm-t .bm-1j{display:flex;justify-content:flex-start}#bm-t .bm-1j button{min-width:7.8rem}#bm-E{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:stretch;gap:.3rem}#bm-t .bm-z{position:relative;overflow:hidden;width:fit-content;max-width:35ch;padding:.28rem;gap:.28rem;border-radius:13px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(160deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29,0 8px 20px #00000014;transition:background .25s ease,border-color .25s ease,box-shadow .25s ease,transform .25s ease}#bm-t .bm-z:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at top right,rgba(255,255,255,.18),transparent 24%),radial-gradient(circle at 18% 0%,rgba(186,246,255,.12),transparent 22%)}#bm-t .bm-z:hover,#bm-t .bm-z:focus-within{transform:translateY(-2px);border-color:#92ddff42;background:linear-gradient(160deg,#ffffff38,#baf6ff1a);box-shadow:inset 0 1px #fff3,0 10px 24px #0000001a}#bm-t .bm-a{display:block;width:fit-content;height:fit-content;padding:.26rem;border:1px solid rgba(255,255,255,.18);border-radius:10px;box-shadow:inset 0 1px #ffffff24,0 6px 16px #00000014}#bm-t .bm-z[data-id="-2"] .bm-a{background:conic-gradient(#a00,#aa0 16.6%,#0a0,#0aa 50%,#00a 66.6%,#a0a,#a00)}#bm-t .bm-z[data-id="-1"] .bm-a{background:url('data:image/svg+xml;utf8,') repeat;background-color:transparent!important}#bm-t .bm-z[data-id="-1"] .bm-a svg{fill:#fff!important}#bm-t .bm-z[data-id="0"] .bm-a{background-color:transparent!important}#bm-t .bm-a button{padding:.26em .14ch}#bm-t .bm-a svg{width:4ch}#bm-t .bm-z>.bm-x{flex-direction:column;align-items:flex-start;gap:.02rem}#bm-t .bm-z h2{margin:.04rem 0 0}#bm-t .bm-z .bm-6{margin:.1rem 0 0}#bm-t .bm-z small{font-size:.75em}#bm-t .bm-z.bm-I{display:none}#bm-t.bm-N{--bm-H-max-height: 100%;display:grid;grid-template-rows:auto minmax(0,1fr);width:268px;height:min(60vh,22rem);min-width:228px;min-height:180px;max-width:min(1000px,calc(100vw - 16px))!important;max-height:min(1400px,calc(100vh - 16px))!important;overflow:hidden;box-sizing:border-box;position:fixed;transition:background .32s ease,border-color .22s ease,box-shadow .22s ease,transform 0s}#bm-t.bm-N .bm-m{display:grid;grid-template-rows:auto auto auto auto minmax(0,1fr);grid-row:2;min-height:0;min-width:0;overflow:hidden}#bm-t.bm-N .bm-1C{gap:.16rem;flex-wrap:nowrap;width:100%;padding:.12rem}#bm-t.bm-N .bm-1C>button{flex:1 1 0;min-width:0}#bm-t.bm-N #bm-E{flex-direction:column;align-items:stretch;gap:.16rem;width:100%;align-self:stretch;min-width:0;box-sizing:border-box}#bm-t.bm-N .bm-z{width:100%;max-width:none;align-self:stretch;flex:1 1 auto;min-width:0;margin:0;padding:.12rem;border-radius:11px;box-sizing:border-box}#bm-t.bm-N .bm-z>.bm-x{width:100%;min-width:0;flex:1 1 auto}#bm-t.bm-N .bm-L.bm-H{display:block;grid-row:5;min-height:0;min-width:0;height:100%;width:100%;max-height:100%!important;overflow:auto;box-sizing:border-box}#bm-t.bm-N .bm-1L{position:absolute;right:4px;bottom:4px;display:flex;width:20px;height:20px;align-items:flex-end;justify-content:flex-end;padding-right:4px;padding-bottom:4px;box-sizing:border-box;z-index:5;cursor:nwse-resize;pointer-events:auto;opacity:.78;touch-action:none;user-select:none;color:#ffffffdb;background:linear-gradient(135deg,#ffffff24,#538dff24);border:1px solid rgba(255,255,255,.12);border-radius:8px;box-shadow:inset 0 1px #ffffff14}#bm-t.bm-N .bm-1L:hover,#bm-t.bm-N .bm-1L.bm-2b{opacity:1;border-color:#92ddff5c;box-shadow:inset 0 1px #ffffff1a,0 8px 16px #00000029}#bm-t.bm-N .bm-a{display:flex;width:100%;min-width:0;flex:1 1 auto;gap:.5ch;align-items:center;padding:.1rem .2rem;border:none;border-radius:8px;box-sizing:border-box}#bm-t.bm-N .bm-a button{padding:.2em .1ch;flex:0 0 auto}#bm-t.bm-N .bm-a svg{width:2.7ch}#bm-t.bm-N .bm-z h2{font-size:.78rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#bm-t #bm-2{display:inline-flex;align-items:center;padding:.08rem .24rem;border-radius:999px;background:#ffffff1f;box-shadow:inset 0 1px #ffffff14;font-size:1em}@media (max-width: 980px){#bm-t:not(.bm-N){width:min(100vw - .35rem,50rem);max-width:min(100vw - .35rem,50rem)!important}#bm-t .bm-1x{grid-template-columns:1fr}#bm-t .bm-1Y,#bm-t .bm-1r,#bm-t .bm-1x>hr{grid-column:auto}}#bm-F{width:min(25.5rem,calc(100vw - .65rem));max-width:min(25.5rem,calc(100vw - .65rem))!important}#bm-F .bm-m{display:flex;flex-direction:column}#bm-F .bm-29,#bm-F .bm-25{position:relative;overflow:hidden;border-radius:14px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(150deg,#ffffff2e,#ffffff14);box-shadow:inset 0 1px #fff3,0 10px 24px #0000001a}#bm-F .bm-29:before,#bm-F .bm-25:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at top right,rgba(255,255,255,.2),transparent 26%),radial-gradient(circle at 20% 0%,rgba(186,246,255,.16),transparent 24%)}#bm-F .bm-29{display:flex;align-items:center;gap:.5rem;padding:.48rem .58rem}#bm-F .bm-29 h1{margin:0}#bm-F .bm-24{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.24rem}#bm-F .bm-1F{min-width:0;min-height:2.55rem;display:flex;align-items:flex-start;padding:.34rem .45rem;border-radius:11px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(160deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29;color:#12233ff5;line-height:1.22}#bm-F .bm-1F>span,#bm-F .bm-1F>time{min-width:0}#bm-F .bm-1f,#bm-F .bm-1g{flex-direction:column;justify-content:center;gap:.08rem}#bm-F .bm-1z{display:inline-block;font-size:1.3em;color:#0f1f38f5;white-space:normal;overflow-wrap:anywhere}#bm-F .bm-1z b{font-size:1em}#bm-F .bm-1y{color:#314769d1;font-size:.62rem;letter-spacing:.08em;font-family:var(--bm-font-display);text-transform:uppercase}#bm-F .bm-1F time{white-space:nowrap;font-family:var(--bm-font-mono);letter-spacing:.06em}#bm-F .bm-25{padding:.48rem}#bm-F .bm-1-{display:grid;grid-template-columns:auto repeat(4,minmax(0,1fr));gap:.22rem;align-items:center}#bm-F .bm-1- .bm-J{width:1.8rem;height:1.8rem}#bm-F .bm-1- .bm-C{width:100%;margin-left:0;text-align:center}#bm-F .bm-1_,#bm-F .bm-20{margin-top:.24rem}#bm-F .bm-1_>div{width:100%}#bm-F .bm-1V{gap:.24rem;margin-top:.3rem}#bm-F .bm-1V>button{flex:1 1 0}#bm-F .bm-20 textarea{min-height:4.1rem}@media (max-width: 720px){#bm-F{width:min(100vw - .45rem,25.5rem);max-width:min(100vw - .45rem,25.5rem)!important}#bm-F .bm-24{grid-template-columns:1fr}#bm-F .bm-1-{grid-template-columns:repeat(2,minmax(0,1fr))}#bm-F .bm-1- .bm-J{grid-column:1 / -1;width:100%;aspect-ratio:auto;height:1.8rem}#bm-F .bm-1V{flex-direction:column}}#bm-l div:has(>.bm-3){width:fit-content;justify-content:flex-start}#bm-l .bm-3{display:flex;flex-direction:column;width:13%}#bm-l .bm-3 span{width:fit-content;margin:auto;font-size:.7em}#bm-l .bm-3 button{width:fit-content;padding:0;border-radius:0}#bm-l .bm-3 svg{stroke:#333;stroke-width:.02px;width:100%;min-width:1.5ch;max-width:14.5ch}#bm-l .bm-3 button:hover svg,#bm-l .bm-3 button:focus svg{opacity:.9}#bm-l .bm-n{display:grid;grid-template-columns:1fr 1fr 1fr;width:25%;min-width:3ch;max-width:15ch}#bm-l .bm-n>button{width:100%;padding:0;aspect-ratio:1 / 1;background-color:#fff;border:#333 1px solid;border-radius:0;box-sizing:border-box}#bm-l .bm-n>button[data-status=Incorrect]{background-color:brown}#bm-l .bm-n>button[data-status=Template]{background-color:#2f4f4f}#bm-l .bm-n>button:hover,#bm-l .bm-n>button:focus{opacity:.8}#bm-B{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}#bm-B>.bm-L{width:100%;justify-content:flex-start;background-color:#153063e6;border-radius:1em;padding:.5em;transition:background-color .3s ease}#bm-B>.bm-L:hover,#bm-B>.bm-L:focus-within{background-color:#112855e6}#bm-B .bm-1{height:100%;font-size:xxx-large}#bm-B .bm-0{flex-direction:column;align-items:flex-start;gap:0}`;function wt(t){const e=document.createElement("link");e.href=t,e.rel="preload",e.as="style",e.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(e)}GM_addStyle(gt);var xt="@font-face{font-family:'Roboto Mono';font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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)format('woff2');}";wt("https://fonts.googleapis.com/css2?family=Michroma&family=Rajdhani:wght@400;500;600;700&display=swap"),xt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(xt)):wt("https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap");var $t=JSON.parse(GM_getValue("bmUserSettings","{}")),yt=(new class{constructor(){this.Qe=null,this.Ke=null,this.ti="#bm-p"}ei(t){return this.Ke=t,this.Qe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.ti)}),this}ii(){return this.Qe}observe(t,e=!1,i=!1){t.observe(this.Ke,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,Q),this.window=null,this.Ct="bm-F",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?this.yt("Main window already exists!"):(this.window=this.O({id:this.Ct,class:"bm-W bm-N",style:"top: 10px; left: unset; right: 75px;"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Blue Marble"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",innerHTML:"⚙️",title:"Settings"},(t,e)=>{e.onclick=()=>{t.$.St()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-29"}).A({class:"bm-T",src:"data:image/png;base64,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"},(t,e)=>{const i=new Date;204==Math.floor((i.getTime()-new Date(i.getFullYear(),0,1))/864e5)+1&&(e.parentNode.style.position="relative",e.parentNode.innerHTML=e.parentNode.innerHTML+'',e.onload=()=>{(new q).qt(document.querySelector(`#${this.Ct}`))})}).N().F(1,{textContent:this.name}).N().N().W().N().O({class:"bm-L bm-24"}).O({class:"bm-1F bm-1f"}).I({class:"bm-1y",textContent:"Droplets"}).N().I({id:"bm-w",class:"bm-1z",textContent:"0"}).N().N().O({class:"bm-1F bm-1f"}).I({class:"bm-1y",textContent:"Next Level"}).N().I({id:"bm-q",class:"bm-1z",textContent:"0 px"}).N().N().O({class:"bm-1F bm-1g"}).I({class:"bm-1y",textContent:"Charges"}).N().gt(Date.now(),1e3,{class:"bm-1z",style:"font-weight: 700;"},(t,e)=>{t.p.si=e.id}).N().N().N().W().N().O({class:"bm-L bm-25"}).O({class:"bm-L bm-1-"}).lt({class:"bm-s bm-J",style:"margin-top: 0;",innerHTML:''},(t,e)=>{e.onclick=()=>{const e=t.p?.ni;e?.[0]?(t.ct("bm-Q",e?.[0]||""),t.ct("bm-R",e?.[1]||""),t.ct("bm-O",e?.[2]||""),t.ct("bm-P",e?.[3]||"")):t.yt("Coordinates are malformed! Did you try clicking on the canvas first?")}}).N().dt({type:"number",id:"bm-Q",class:"bm-C",placeholder:"Tl X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-R",class:"bm-C",placeholder:"Tl Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-O",class:"bm-C",placeholder:"Px X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-P",class:"bm-C",placeholder:"Px Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().N().O({class:"bm-L bm-1_"}).ut({class:"bm-K",textContent:"Upload Template",accept:"image/png, image/jpeg, image/webp, image/bmp, image/gif"}).N().N().O({class:"bm-L bm-x bm-1V"}).lt({class:"bm-1s",textContent:"Disable","data-button-status":"shown"},(t,e)=>{e.onclick=()=>{e.disabled=!0,"shown"==e.dataset.buttonStatus?(t.p?.he?.oi(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.he?.oi(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.Mt("Enabled templates!")),e.disabled=!1}}).N().lt({class:"bm-1D",textContent:"Create"},(t,e)=>{e.onclick=()=>{const e=document.querySelector(`#${this.Ct} .bm-K`),i=document.querySelector("#bm-Q");if(!i.checkValidity())return i.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const s=document.querySelector("#bm-R");if(!s.checkValidity())return s.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const n=document.querySelector("#bm-O");if(!n.checkValidity())return n.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const o=document.querySelector("#bm-P");if(!o.checkValidity())return o.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");e?.files[0]?(t?.p?.he.Ue(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(s.value),Number(n.value),Number(o.value)]),t.Mt("Drew to canvas!")):t.yt("No file selected!")}}).N().lt({class:"bm-1s",textContent:"Filter"},(t,e)=>{e.onclick=()=>this.ai()}).N().N().O({class:"bm-L bm-20"}).bt({id:this.v,placeholder:`Status: Sleeping...\nVersion: ${this.version}`,readOnly:!0}).N().N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}ai(){new nt(this).$e()}}(pt,ft)),vt=new class{constructor(t,i){e(this,at),this.name=t,this.version=i,this.Re=null,this.$=null,this.schemaVersion="2.0.0",this.ri=null,this.Fe="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.Bt=1e3,this.Ge=3,this._e=3,this.de=function(t){const e=v;e.unshift({id:-1,premium:!1,name:"Erased",rgb:[222,250,206]}),e.unshift({id:-2,premium:!1,name:"Other",rgb:[0,0,0]});const i=new Map;for(const s of e){if(0==s.id||-2==s.id)continue;const e=s.rgb[0],n=s.rgb[1],o=s.rgb[2];for(let a=-t;a<=t;a++)for(let r=-t;r<=t;r++)for(let l=-t;l<=t;l++){const t=e+a,h=n+r,c=o+l;if(t<0||t>255||h<0||h>255||c<0||c>255)continue;const m=(255<<24|c<<16|h<<8|t)>>>0;i.has(m)||i.set(m,s.id)}}return{palette:e,Jt:i}}(this._e),this.Ee=null,this.li="",this.Ie=[],this.Ve=null,this.hi=!0,this.ci=null,this.Le=new Map}mi(t){this.Re=t}D(t){this.$=t,i(this,at,rt).call(this)}He(t,e){const s=Number(t);Number.isFinite(s)&&(e?this.Le.set(s,!0):this.Le.delete(s),i(this,at,lt).call(this))}async di(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async Ue(t,e,s){this.Ve||(this.Ve=await this.di(),console.log("Creating JSON...")),this.Re.Mt(`Creating template at ${s.join(", ")}...`);const n=new O({displayName:e,Ot:0,Lt:m(this.ri||0,this.Fe),file:t,coords:s}),o=!this.$?.kt?.flags?.includes("hl-noSkip"),a=this.$?.kt?.flags?.includes("hl-agSkip");console.log(`Should Skip: ${o}; Should Agg Skip: ${a}`);const{jt:r,Et:l}=await n.Ft(this.Bt,this.de,o,a);n.Ht=r;const h={total:n.Pt.total,colors:Object.fromEntries(n.Pt.colors)};this.Ve.templates[`${n.Ot} ${n.Lt}`]={name:n.displayName,coords:s.join(", "),enabled:!0,pixels:h,tiles:l},this.Ie=[],this.Ie.push(n),this.Re.Mt(`Template created at ${s.join(", ")}!`),console.log(Object.keys(this.Ve.templates).length),console.log(this.Ve),console.log(this.Ie),console.log(JSON.stringify(this.Ve)),await i(this,at,ht).call(this)}ui(){}async bi(){this.Ve||(this.Ve=await this.di(),console.log("Creating JSON..."))}async pi(){l("Downloading all templates..."),console.log(this.Ie);for(const t of this.Ie)await this.fi(t),await s(500)}async ze(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(console.log(t),Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.fi(new O({displayName:i.name,Ot:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ht:i.tiles})),await s(500))}async fi(t){t.Yt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.We(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",gi:"uniquify",onload:()=>{l(`Download of template '${e}' complete!`)},onerror:(t,i)=>{h(`Download of template '${e}' failed because ${t}! Details: ${i}`)},ontimeout:()=>{c(`Download of template '${e}' has timed out!`)}})}async We(t){console.log(t);const e=t.Ht,i=Object.keys(e).sort(),s=await Promise.all(i.map(t=>{return i=e[t],new Promise((t,e)=>{const s=new Image;s.onload=()=>t(s),s.onerror=e,s.src="data:image/png;base64,"+i});var i}));let n=1/0,o=1/0,a=0,r=0;i.forEach((t,e)=>{const[i,l,h,c]=t.split(",").map(Number),m=s[e],d=i*this.Bt+h,u=l*this.Bt+c;n=Math.min(n,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.Ge),r=Math.max(r,u+m.height/this.Ge)}),console.log(`Absolute coordinates: (${n}, ${o}) and (${a}, ${r})`);const l=a-n,h=r-o,c=l*this.Ge,m=h*this.Ge;console.log(`Template Width: ${l}\nTemplate Height: ${h}\nCanvas Width: ${c}\nCanvas Height: ${m}`);const d=new OffscreenCanvas(c,m),u=d.getContext("2d");i.forEach((t,e)=>{const[i,a,r,l]=t.split(",").map(Number),h=s[e],c=i*this.Bt+r,m=a*this.Bt+l;console.log(`Drawing tile (${i}, ${a}, ${r}, ${l}) (${c}, ${m}) at (${c-n}, ${m-o}) on the canvas...`),u.drawImage(h,(c-n)*this.Ge,(m-o)*this.Ge,h.width,h.height)}),u.globalCompositeOperation="destination-over",u.drawImage(d,0,-1),u.drawImage(d,0,1),u.drawImage(d,-1,0),u.drawImage(d,1,0);const b=new OffscreenCanvas(l,h),p=b.getContext("2d");return p.imageSmoothingEnabled=!1,p.drawImage(d,0,0,l*this.Ge,h*this.Ge,0,0,l,h),b.convertToBlob({type:"image/png"})}async wi(t,e){if(!this.hi)return t;const s=this.Bt*this.Ge;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.Ie;console.log(o),o.sort((t,e)=>t.Ot-e.Ot),console.log(o);const a=o.map(t=>{const i=Object.keys(t.Ht).filter(t=>t.startsWith(e));if(0===i.length)return null;const s=i.map(e=>{const i=e.split(",");return{xi:t,Ut:t.Ht[e],It:t.It?.[e],$i:[i[0],i[1]],yi:[i[2],i[3]]}});return s?.[0]}).filter(Boolean);console.log(a);const r=a?.length||0;if(console.log(`templateCount = ${r}`),!(r>0))return this.Re.Mt(`Sleeping\nVersion: ${this.version}`),t;{const t=n(o.filter(t=>Object.keys(t.Ht).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.Pt.total||0),0));this.Re.Mt(`Displaying ${r} template${1==r?"":"s"}.\nTotal pixels: ${t}`)}const l=await createImageBitmap(t),h=new OffscreenCanvas(s,s),c=h.getContext("2d");c.imageSmoothingEnabled=!1,c.beginPath(),c.rect(0,0,s,s),c.clip(),c.clearRect(0,0,s,s),c.drawImage(l,0,0,s,s);const m=c.getImageData(0,0,s,s),d=new Uint32Array(m.data.buffer),u=this.$?.kt?.highlight||[[2,0,0]],b=u?.[0],p=1==u?.length&&2==b?.[0]&&0==b?.[1]&&0==b?.[2];for(const t of a){console.log("Template:"),console.log(t);const s=!!t.xi.Pt?.colors?.get(-1);let n=t.It.slice();const o=Number(t.yi[0])*this.Ge,a=Number(t.yi[1])*this.Ge;if(0!=this.Le.size||s||c.drawImage(t.Ut,o,a),!n){const e=c.getImageData(o,a,t.Ut.width,t.Ut.height);n=new Uint32Array(e.data.buffer)}const r=Date.now(),{qe:l,Ze:h}=i(this,at,mt).call(this,{je:d,Ee:n,Ye:[o,a,t.Ut.width,t.Ut.height],Je:u,Xe:p});let m=0;const b=0;for(const[t,e]of l)t!=b&&(m+=e);0==this.Le.size&&!s&&p||(console.log("Colors to filter: ",this.Le),c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(h.buffer),t.Ut.width,t.Ut.height)),o,a)),console.log(`Finished calculating correct pixels & filtering colors for the tile ${e} in ${(Date.now()-r)/1e3} seconds!\nThere are ${m} correct pixels.`),void 0===t.xi.Pt.correct&&(t.xi.Pt.correct={}),t.xi.Pt.correct[e]=l}return await h.convertToBlob({type:"image/png"})}async Mi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&await i(this,at,ct).call(this,t)}oi(t){this.hi=t}}(pt,ft),Mt=new class{constructor(t){this.he=t,this.Ci=!1,this.si="",this.ni=[],this.Ti=[]}Si(t){window.addEventListener("message",async e=>{const i=e.data,s=i.jsonData;if(!i||"blue-marble"!==i.source)return;if(!i.endpoint)return;const n=i.endpoint?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();switch(console.log('%cBlue Marble%c: Recieved message about "%s"',"color: cornflowerblue;","",n),n){case"me":this.Di(t,s);break;case"pixel":const e=i.endpoint.split("?")[0].split("/").filter(t=>t&&!isNaN(Number(t))),n=new URLSearchParams(i.endpoint.split("?")[1]),r=[n.get("x"),n.get("y")];if(this.ni.length&&(!e.length||!r.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ni=[...e,...r];const l=(o=e,a=r,[parseInt(o[0])%4*1e3+parseInt(a[0]),parseInt(o[1])%4*1e3+parseInt(a[1])]),h=document.querySelectorAll("span");for(const t of h){const i=t.textContent.trim();if(i.includes(l[0])&&i.includes(l[1])){let i=document.querySelector("#bm-p");e[0],e[1],r[0],r[1];const s=["Tl X:","Tl Y:","Px X:","Px Y:"],n=["bm-Y","bm-Z","bm-U","bm-V"],o=[...e,...r];if(i)for(const[t,e]of n.entries())document.getElementById(e).textContent=`${s[t]??"??:"} ${o[t]}`;else{i=document.createElement("span"),i.id="bm-p",i.style="display: flex; flex-wrap: wrap; gap: 0 1ch; font-size: small;";for(const[t,e]of o.entries()){const a=document.createElement("span");a.id=n[o.indexOf(e)??""],a.textContent=`${s[t]??"??:"} ${e}`,i.appendChild(a)}t.parentNode.parentNode.parentNode.insertAdjacentElement("afterend",i)}}}break;case"tile":case"tiles":let c=i.endpoint.split("/");c=[parseInt(c[c.length-2]),parseInt(c[c.length-1].replace(".png",""))];const m=i.blobID,d=i.blobData,u=Date.now(),b=await this.he.wi(d,c);console.log(`Finished loading the tile in ${(Date.now()-u)/1e3} seconds!`),window.postMessage({source:"blue-marble",blobID:m,blobData:b,blink:i.blink});break;case"robots":this.Ci="false"==s.userscript?.toString().toLowerCase();break}var o,a})}Di(t,e){if(e.status&&"2"!=e.status?.toString()[0])return void t.yt("You are not logged in or Wplace is offline!\nCould not fetch userdata.");const i=Math.ceil(Math.pow(Math.floor(e.level)*Math.pow(30,.65),1/.65)-e.pixelsPainted);if(console.log(e.id),(e.id||0===e.id)&&console.log(m(e.id,"!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~")),this.he.ri=e.id,0!=this.si.length){const t=document.querySelector("#"+this.si);if(t){const i=e.charges;t.dataset.endDate=Date.now()+(i.max-i.count)*i.cooldownMs}}t.ct("bm-w",`${n(e.droplets)}`),t.ct("bm-q",`${n(i)} px`)}async Ni(t){try{const e=await fetch(`${window.location.origin}/api/me`,{credentials:"include"});if(!e.ok)return void t.yt(`Could not fetch userdata.\nHTTP ${e.status}`);const i=await e.json();this.Di(t,i)}catch(t){h("Failed to fetch current user data:",t)}}ki(t){try{const e=sessionStorage.getItem("bm-2i");if(!e)return!1;const i=JSON.parse(e);return this.Di(t,i),!0}catch(t){return h("Failed to apply cached user data:",t),!1}}async Oi(t){console.log("Sending heartbeat to telemetry server...");let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return void console.log("Telemetry is disabled, not sending heartbeat.");const i=navigator.userAgent;let s=await this.Li(i),n=this.Hi(i);GM_xmlhttpRequest({method:"POST",url:"https://telemetry.thebluecorner.net/heartbeat",headers:{"Content-Type":"application/json"},data:JSON.stringify({uuid:e.uuid,version:t,browser:s,os:n}),onload:t=>{200!==t.status&&h("Failed to send heartbeat:",t.statusText)},onerror:t=>{h("Error sending heartbeat:",t)}})}async Li(t=navigator.userAgent){return(t=t||"").includes("OPR/")||t.includes("Opera")?"Opera":t.includes("Edg/")?"Edge":t.includes("Vivaldi")?"Vivaldi":t.includes("YaBrowser")?"Yandex":t.includes("Kiwi")?"Kiwi":t.includes("Brave")?"Brave":t.includes("Firefox/")?"Firefox":t.includes("Chrome/")?"Chrome":t.includes("Safari/")?"Safari":navigator.brave&&"function"==typeof navigator.brave.isBrave&&await navigator.brave.isBrave()?"Brave":"Unknown"}Hi(t=navigator.userAgent){return/Windows NT 11/i.test(t=t||"")?"Windows 11":/Windows NT 10/i.test(t)?"Windows 10":/Windows NT 6\.3/i.test(t)?"Windows 8.1":/Windows NT 6\.2/i.test(t)?"Windows 8":/Windows NT 6\.1/i.test(t)?"Windows 7":/Windows NT 6\.0/i.test(t)?"Windows Vista":/Windows NT 5\.1|Windows XP/i.test(t)?"Windows XP":/Mac OS X 10[_\.]15/i.test(t)?"macOS Catalina":/Mac OS X 10[_\.]14/i.test(t)?"macOS Mojave":/Mac OS X 10[_\.]13/i.test(t)?"macOS High Sierra":/Mac OS X 10[_\.]12/i.test(t)?"macOS Sierra":/Mac OS X 10[_\.]11/i.test(t)?"OS X El Capitan":/Mac OS X 10[_\.]10/i.test(t)?"OS X Yosemite":/Mac OS X 10[_\.]/i.test(t)?"macOS":/Android/i.test(t)?"Android":/iPhone|iPad|iPod/i.test(t)?"iOS":/Linux/i.test(t)?"Linux":"Unknown"}}(vt),Ct=new class extends k{constructor(t,i,s){var n;super(t,i),e(this,C),this.kt=s,(n=this.kt).flags??(n.flags=[]),this.Ii=structuredClone(this.kt),this.Bi="bmUserSettings",this.Pi=5e3,this.Ai=0,setInterval(this.zi.bind(this),this.Pi)}async zi(){await this.Fi()}async Fi(t=!1){const e=JSON.stringify(this.kt);e!=JSON.stringify(this.Ii)&&(t||Date.now()-this.Ai>this.Pi)&&(await GM.setValue(this.Bi,e),this.Ii=structuredClone(this.kt),this.Ai=Date.now(),console.log(e))}async Oe(){await this.Fi(!0)}ke(t,e=void 0){const i=this.kt?.flags?.indexOf(t)??-1;-1!=i&&!0!==e?this.kt?.flags?.splice(i,1):-1==i&&!1!==e&&this.kt?.flags?.push(t)}Dt(){const t='',e='',s=this.kt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];this.window=this.O({class:"bm-L"}).F(2,{textContent:"Pixel Highlight"}).N().W().N().O({class:"bm-L",style:"margin-left: 1.5ch;"}).j({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.ke("hl-noTrans",!t.target.checked)}).N().L({id:"bm-4",textContent:"Choose a preset:",style:"font-weight: 700;"}).N().O({class:"bm-D",role:"group","aria-labelledby":"bm-4"}).O({class:"bm-3"}).I({textContent:"None"}).N().lt({innerHTML:t,"aria-label":'Preset "None"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"None")}).N().N().O({class:"bm-3"}).I({textContent:"Cross"}).N().lt({innerHTML:e,"aria-label":'Preset "Cross Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Cross")}).N().N().O({class:"bm-3"}).I({textContent:"X"}).N().lt({innerHTML:e.replace('d="M1,0H2V1H3V2H2V3H1V2H0V1H1Z"','d="M0,0V1H3V0H2V3H3V2H0V3H1V0Z"'),"aria-label":'Preset "X Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"X")}).N().N().O({class:"bm-3"}).I({textContent:"Full"}).N().lt({innerHTML:t.replace("#fff","#2f4f4f"),"aria-label":'Preset "Full Template"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Full")}).N().N().N().L({id:"bm-b",textContent:"Create a custom pattern:",style:"font-weight: 700;"}).N().O({class:"bm-n",role:"group","aria-labelledby":"bm-b"});for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){const n=s[s.findIndex(([,i,s])=>i==e&&s==t)]?.[0]??0;let o="Disabled";1==n?o="Incorrect":2==n&&(o="Template"),this.window=this.lt({"data-status":o,"aria-label":`Sub-pixel ${o.toLowerCase()}`},(s,n)=>{n.onclick=()=>i(this,C,T).call(this,n,[e,t])}).N()}this.window=this.N().N().N()}Nt(){this.window=this.O({class:"bm-L"}).F(2,{textContent:"Pixel Highlight"}).N().W().N().O({class:"bm-L",style:"margin-left: 1.5ch;"}).j({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.ke("hl-noSkip",!t.target.checked)}).N().j({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.kt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.ke("hl-agSkip",t.target.checked)}).N().N().N()}}(pt,ft,$t);yt.D(Ct),yt.S(Mt),vt.mi(yt),vt.D(Ct);var Tt=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(Tt),console.log($t),console.log(Object.keys($t).length),0==Object.keys($t).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>Mt.Oi(ft),18e5);var St=$t?.telemetry;if(console.log(`Telemetry is ${!(null==St)}`),null==St||St>1){const t=new class extends M{constructor(t,i,s,n){super(t,i),e(this,dt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Wi=s,this.uuid=n}async St(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.Li(navigator.userAgent),e=this.p.Hi(navigator.userAgent);this.window=this.O({id:this.Ct,class:"bm-W",style:"height: 80vh; z-index: 9998;"}).O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:`${this.name} Telemetry`}).N().N().W().N().O({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,dt,ut).call(this,this.Wi);const t=document.getElementById(this.Ct);t?.remove()}}).N().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,dt,ut).call(this,0);const t=document.getElementById(this.Ct);t?.remove()}}).N().lt({textContent:"More Information"},(t,e)=>{e.onclick=()=>{window.open("https://github.com/SwingTheVine/Wplace-TelemetryServer#telemetry-data","_blank","noopener noreferrer")}}).N().N().O({class:"bm-L bm-H"}).O({class:"bm-L"}).F(2,{textContent:"Legal"}).N().L({textContent:`We collect anonymous telemetry data such as your browser, OS, and script version to make the experience better for everyone. The data is never shared personally. The data is never sold. You can turn this off by pressing the "Disable" button, but keeping it on helps us improve features and reliability faster. Thank you for supporting ${this.name}!`}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Non-Legal Summary"}).N().L({innerHTML:'You can disable telemetry by pressing the "Disable" button. If you would like to read more about what information we collect, press the "More Information" button.
This is the data stored on our servers:'}).N()._().Z({innerHTML:`A unique identifier (UUIDv4) generated by Blue Marble. This enables our telemetry to function without tracking your actual user ID.
Your UUID is: ${r(this.uuid)}`}).N().Z({innerHTML:`The version of Blue Marble you are using.
Your version is: ${r(this.version)}`}).N().Z({innerHTML:`Your browser type, which is used to determine Blue Marble outages and browser popularity.
Your browser type is: ${r(t)}`}).N().Z({innerHTML:`Your OS type, which is used to determine Blue Marble outages and OS popularity.
Your OS type is: ${r(e)}`}).N().Z({innerHTML:"The date and time that Blue Marble sent the telemetry information."}).N().N().L({innerHTML:'All of the data mentioned above is aggregated every hour. This means every hour, anything that could even remotly be considered "personal data" is deleted from our server. Here, "aggregated" data means things like "42 people used Blue Marble on Google Chrome this hour", which can\'t be used to identify anyone in particular.'}).N().N().N().N().N().k(this.Tt)}}(pt,ft,1,$t?.uuid);t.S(Mt),t.St()}!async function(){await vt.Mi(Tt),Mt.Si(yt),yt.St(),yt.ai(),Mt.ki(yt),Mt.Ni(yt),new MutationObserver((t,e)=>{const i=document.querySelector("#color-1");if(!i)return;let s=document.querySelector("#bm-G");if(!s){s=document.createElement("button"),s.id="bm-G",s.textContent="Move ↑",s.className="btn btn-soft",s.onclick=function(){const t=this.parentNode.parentNode.parentNode.parentNode,e="Move ↑"==this.textContent;t.parentNode.className=t.parentNode.className.replace(e?"bottom":"top",e?"top":"bottom"),t.style.borderTopLeftRadius=e?"0px":"var(--radius-box)",t.style.borderTopRightRadius=e?"0px":"var(--radius-box)",t.style.borderBottomLeftRadius=e?"var(--radius-box)":"0px",t.style.borderBottomRightRadius=e?"var(--radius-box)":"0px",this.textContent=e?"Move ↓":"Move ↑"};const t=i.parentNode.parentNode.parentNode.parentNode.querySelector("h2");t.parentNode?.appendChild(s)}}).observe(document.body,{childList:!0,subtree:!0}),l(`%c${pt}%c (${ft}) userscript has loaded!`,"color: cornflowerblue;","")}()})(); -// Build Hash: 0808688ad3f1 +// Build Hash: 4542d9663740 diff --git a/dist/BlueMarble.user.css b/dist/BlueMarble.user.css index f85f122..1401c56 100644 --- a/dist/BlueMarble.user.css +++ b/dist/BlueMarble.user.css @@ -1,3 +1,3 @@ -div:has(>confetti-piece){position:absolute;inset:0;overflow:hidden;pointer-events:none}confetti-piece{position:absolute;top:-10px;width:var(--size);height:var(--size);background:currentColor;transform:translate3d(var(--x),-10vh,0) rotate(var(--rot));animation:fall var(--duration) linear var(--delay);will-change:transform;pointer-events:none}@keyframes fall{to{transform:translate3d(var(--x),110vh,0) rotate(calc(var(--rot) + 720deg))}}.bm-screenreader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.bm-W{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000;transition:all .3s ease,transform 0s;top:75px;left:60px;width:auto;max-height:fit-content;max-width:calc(100% - 135px);font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}.bm-S{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5ch;background:url('data:image/svg+xml;utf8,') repeat;cursor:grab;width:100%;height:fit-content}.bm-S.bm-M{cursor:grabbing}.bm-W:has(.bm-S.bm-M){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-S.bm-M{pointer-events:auto}.bm-T{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}.bm-W h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}.bm-S h1,.bm-y{font-size:1.2em;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-shadow:3px 0px rgba(21,48,99,.5),-3px 0px rgba(21,48,99,.5),0px 3px rgba(21,48,99,.5),0px -3px rgba(21,48,99,.5),3px 3px rgba(21,48,99,.5),-3px 3px rgba(21,48,99,.5),3px -3px rgba(21,48,99,.5),-3px -3px rgba(21,48,99,.5)}.bm-S div:has(h1){display:contents}.bm-W h2{display:inline-block;font-size:larger;font-weight:700;vertical-align:middle}.bm-W h3{display:inline-block;font-size:large;font-weight:700}.bm-L.bm-h{width:fit-content;margin-left:auto;margin-right:auto}.bm-L{margin:.5em 0}.bm-W button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}.bm-W button:hover,.bm-W button:focus-visible{background-color:#1061e5}.bm-W button:active,.bm-W button:disabled{background-color:#2e97ff}.bm-W button:disabled{text-decoration:line-through;cursor:not-allowed}.bm-s{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}.bm-J{vertical-align:middle}.bm-J svg{width:50%;margin:0 auto;fill:#111}.bm-W button.bm-A{background-color:unset}.bm-A.bm-f:hover,.bm-A.bm-f:focus{background-color:#ffffff2b}.bm-A.bm-f:active{background-color:#ffffff38}.bm-A.bm-g:hover,.bm-A.bm-g:focus{background-color:#0000002b}.bm-A.bm-g:active{background-color:#00000038}input[type=number].bm-C{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}input[type=number].bm-C::-webkit-outer-spin-button,input[type=number].bm-C::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-K)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-K,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-W select{color:#fff;background-color:#144eb9;border-radius:1em;padding:0 .5ch}.bm-W label:has(input[type=checkbox]){display:flex;width:fit-content;gap:1ch}.bm-W input[type=checkbox]{width:1em}.bm-m{overflow:hidden;max-height:calc(100% - 5px);transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-W textarea{font-size:small;background-color:#0003;padding:0 .5ch;height:5.25em;width:100%}.bm-W a:not(:has(*)){text-decoration:underline}.bm-W small{font-size:x-small;color:#d3d3d3}.bm-W ul li{list-style:disc;margin-left:5ch}.bm-W .bm-L.bm-H{max-height:var(--bm-H-max-height, calc(80vh - 150px) );overflow:auto}.bm-x{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.5ch}.bm-D{display:flex;align-content:center;justify-content:center;align-items:center;gap:.5ch}.bm-_{white-space:pre;letter-spacing:0;line-height:1!important;font-size:1.6em;font-family:monospace}.bm-N .bm-L:not(#bm-F .bm-L){margin-top:.25em;margin-bottom:.25em}.bm-N h1:not(#bm-F h1){font-size:1em}#bm-t p svg{display:inline;height:1em;fill:#fff}#bm-E{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:1em 3ch}#bm-t .bm-z{width:fit-content;max-width:35ch;background-color:#153063e6;border-radius:1em;padding:.5em;gap:1ch;transition:background-color .3s ease}#bm-t .bm-z:hover,#bm-t.bm-z:focus-within{background-color:#112855e6}#bm-t .bm-a{display:block;border:thick double darkslategray;width:fit-content;height:fit-content;padding:1ch}#bm-t .bm-z[data-id="-2"] .bm-a{background:conic-gradient(#a00,#aa0 16.6%,#0a0,#0aa 50%,#00a 66.6%,#a0a,#a00)}#bm-t .bm-z[data-id="-1"] .bm-a{background:url('data:image/svg+xml;utf8,') repeat;background-color:transparent!important}#bm-t .bm-z[data-id="-1"] .bm-a svg{fill:#fff!important}#bm-t .bm-z[data-id="0"] .bm-a{background-color:transparent!important}#bm-t .bm-a button{padding:.75em .5ch}#bm-t .bm-a svg{width:4ch}#bm-t .bm-z>.bm-x{flex-direction:column;align-items:flex-start;gap:0}#bm-t .bm-z small{font-size:.75em}#bm-t .bm-z.bm-I{display:none}#bm-t.bm-N{--bm-H-max-height: 100%;display:grid;grid-template-rows:auto minmax(0,1fr);width:300px;height:min(70vh,32rem);min-width:260px;min-height:220px;max-width:min(1000px,calc(100vw - 16px))!important;max-height:min(1400px,calc(100vh - 16px))!important;overflow:hidden;box-sizing:border-box;position:fixed;transition:transform 0s}#bm-t.bm-N .bm-m{display:grid;grid-template-rows:auto auto auto minmax(0,1fr);grid-row:2;min-height:0;min-width:0;overflow:hidden}#bm-t.bm-N #bm-E{flex-direction:column;align-items:stretch;gap:.25em;width:100%;align-self:stretch;min-width:0;box-sizing:border-box}#bm-t.bm-N .bm-z{width:100%;max-width:none;align-self:stretch;flex:1 1 auto;min-width:0;margin:0;padding:0;box-sizing:border-box}#bm-t.bm-N .bm-z>.bm-x{width:100%;min-width:0;flex:1 1 auto}#bm-t.bm-N .bm-L.bm-H{display:block;grid-row:4;min-height:0;min-width:0;height:100%;width:100%;max-height:100%!important;overflow:auto;box-sizing:border-box}#bm-t.bm-N .bm-1y{position:absolute;right:0;bottom:0;display:block;width:28px;height:28px;z-index:5;cursor:nwse-resize;pointer-events:auto;opacity:1;touch-action:none;user-select:none;background:transparent;border:none;box-shadow:none}#bm-t.bm-N .bm-1y:hover,#bm-t.bm-N .bm-1y.bm-1S{opacity:1}#bm-t.bm-N .bm-a{display:flex;width:100%;min-width:0;flex:1 1 auto;gap:.5ch;align-items:center;padding:.1em .5ch;border:none;border-radius:1em;box-sizing:border-box}#bm-t.bm-N .bm-a button{padding:.5em .25ch;flex:0 0 auto}#bm-t.bm-N .bm-a svg{width:3ch}#bm-t.bm-N .bm-z h2{font-size:.75em;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#bm-t #bm-2{font-size:1em}#bm-l div:has(>.bm-3){width:fit-content;justify-content:flex-start}#bm-l .bm-3{display:flex;flex-direction:column;width:13%}#bm-l .bm-3 span{width:fit-content;margin:auto;font-size:.7em}#bm-l .bm-3 button{width:fit-content;padding:0;border-radius:0}#bm-l .bm-3 svg{stroke:#333;stroke-width:.02px;width:100%;min-width:1.5ch;max-width:14.5ch}#bm-l .bm-3 button:hover svg,#bm-l .bm-3 button:focus svg{opacity:.9}#bm-l .bm-n{display:grid;grid-template-columns:1fr 1fr 1fr;width:25%;min-width:3ch;max-width:15ch}#bm-l .bm-n>button{width:100%;padding:0;aspect-ratio:1 / 1;background-color:#fff;border:#333 1px solid;border-radius:0;box-sizing:border-box}#bm-l .bm-n>button[data-status=Incorrect]{background-color:brown}#bm-l .bm-n>button[data-status=Template]{background-color:#2f4f4f}#bm-l .bm-n>button:hover,#bm-l .bm-n>button:focus{opacity:.8}#bm-B{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}#bm-B>.bm-L{width:100%;justify-content:flex-start;background-color:#153063e6;border-radius:1em;padding:.5em;transition:background-color .3s ease}#bm-B>.bm-L:hover,#bm-B>.bm-L:focus-within{background-color:#112855e6}#bm-B .bm-1{height:100%;font-size:xxx-large}#bm-B .bm-0{flex-direction:column;align-items:flex-start;gap:0} +div:has(>confetti-piece){position:absolute;inset:0;overflow:hidden;pointer-events:none}confetti-piece{position:absolute;top:-10px;width:var(--size);height:var(--size);background:currentColor;transform:translate3d(var(--x),-10vh,0) rotate(var(--rot));animation:fall var(--duration) linear var(--delay);will-change:transform;pointer-events:none}@keyframes fall{to{transform:translate3d(var(--x),110vh,0) rotate(calc(var(--rot) + 720deg))}}.bm-screenreader{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.bm-W{--bm-surface-strong: rgba(9, 20, 42, .5);--bm-surface-soft: rgba(24, 41, 74, .28);--bm-surface-glass: rgba(255, 255, 255, .1);--bm-surface-glass-strong: rgba(255, 255, 255, .18);--bm-border-soft: rgba(255, 255, 255, .18);--bm-border-strong: rgba(163, 228, 255, .34);--bm-text-primary: rgba(17, 36, 66, .96);--bm-text-secondary: rgba(36, 57, 90, .84);--bm-accent-start: #baf6ff;--bm-accent-end: #81b6ff;--bm-accent-shadow: rgba(132, 182, 255, .22);--bm-font-body: "Rajdhani", "Segoe UI Variable Text", "Segoe UI", sans-serif;--bm-font-display: "Michroma", "Orbitron", "Segoe UI", sans-serif;--bm-font-mono: "Roboto Mono", "Rajdhani", "Courier New", monospace;position:fixed;isolation:isolate;overflow:hidden;background:radial-gradient(circle at 14% 12%,rgba(255,255,255,.24),transparent 18%),radial-gradient(circle at 86% 8%,rgba(186,246,255,.22),transparent 24%),radial-gradient(circle at 82% 84%,rgba(129,182,255,.18),transparent 28%),linear-gradient(145deg,#ffffff2e,#ffffff0f 22%,#6991d414 54%,#09142a2e);color:var(--bm-text-primary);padding:6px;border-radius:16px;border:1px solid var(--bm-border-soft);box-shadow:0 18px 40px #0003,inset 0 1px #ffffff38,inset 0 -1px #ffffff0d;z-index:9000;transition:background .32s ease,border-color .22s ease,box-shadow .22s ease,opacity .22s ease,transform 0s,width .22s ease,max-width .22s ease,max-height .22s ease;top:75px;left:60px;width:auto;max-height:fit-content;max-width:calc(100% - 135px);backdrop-filter:blur(26px) saturate(1.25);font-family:var(--bm-font-body);letter-spacing:.04em}.bm-W:before,.bm-W:after{content:"";position:absolute;inset:0;pointer-events:none}.bm-W:before{border-radius:inherit;padding:1px;background:linear-gradient(135deg,#ffffff73,#ffffff1f 24%,#baf6ff38 58%,#81b6ff4d);-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.85}.bm-W:after{border-radius:inherit;background:linear-gradient(180deg,rgba(255,255,255,.2),transparent 24%),radial-gradient(circle at 18% 0%,rgba(255,255,255,.22),transparent 22%),radial-gradient(circle at 88% 16%,rgba(186,246,255,.18),transparent 18%);opacity:1}.bm-S{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.28ch;padding:.18rem .24rem;border-radius:10px;border:1px solid rgba(255,255,255,.16);background:radial-gradient(circle at 0 0,rgba(255,255,255,.22) 0,transparent 42%),linear-gradient(135deg,#ffffff2e,#ffffff14);cursor:grab;width:100%;height:fit-content;box-shadow:inset 0 1px #ffffff29,0 6px 18px #0000001a}.bm-S.bm-M{cursor:grabbing}.bm-W:has(.bm-S.bm-M){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-S.bm-M{pointer-events:auto}.bm-T{display:inline-block;height:2.2em;margin-right:.45ch;padding:.2rem;border-radius:12px;vertical-align:middle;background:linear-gradient(135deg,#ffffff38,#ffffff14);box-shadow:inset 0 1px #ffffff29,0 8px 18px #0000001f}.bm-W h1{display:inline-block;font-size:1rem;font-weight:700;vertical-align:middle;font-family:var(--bm-font-display);text-transform:uppercase;letter-spacing:.14em;color:#10213cf5}.bm-S h1,.bm-y{font-size:.78rem;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-family:var(--bm-font-display);letter-spacing:.14em;color:#122542f2;text-shadow:0 1px 0 rgba(255,255,255,.28)}.bm-S div:has(h1){display:contents}.bm-W h2{display:inline-block;font-size:.88rem;font-weight:700;vertical-align:middle;font-family:var(--bm-font-display);letter-spacing:.1em;color:#122340f5}.bm-W h3{display:inline-block;font-size:large;font-weight:700;font-family:var(--bm-font-display);letter-spacing:.08em;color:#122340f5}.bm-W p{color:var(--bm-text-secondary);line-height:1.5;letter-spacing:.035em}.bm-W hr{border:none;height:1px;margin:.32rem 0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.28),transparent)}.bm-L.bm-h{width:fit-content;margin-left:auto;margin-right:auto}.bm-L{margin:.24em 0}.bm-W input,.bm-W select,.bm-W textarea,.bm-W button{font:inherit}.bm-W button{appearance:none;color:var(--bm-text-primary);font-family:var(--bm-font-display);background:linear-gradient(135deg,#ffffff38,#a4d0ff24);border:1px solid rgba(255,255,255,.22);border-radius:999px;padding:.28em .62em;min-height:1.78em;font-weight:600;letter-spacing:.1em;box-shadow:inset 0 1px #ffffff38,0 8px 20px #0000001a;transition:background .18s ease,border-color .18s ease,box-shadow .18s ease,filter .18s ease,opacity .18s ease,transform .18s ease}.bm-W button:hover,.bm-W button:focus-visible{background:linear-gradient(135deg,#ffffff47,#baf6ff2e);border-color:#e6f5ff5c;box-shadow:inset 0 1px #ffffff42,0 10px 22px #0000001f;transform:translateY(-1px)}.bm-W button:focus-visible,.bm-W input:focus-visible,.bm-W select:focus-visible,.bm-W textarea:focus-visible{outline:none;border-color:#74e7ff9e;box-shadow:0 0 0 3px #74e7ff26,inset 0 1px #ffffff1f}.bm-W button:active{transform:translateY(0) scale(.98);filter:brightness(.98);box-shadow:inset 0 1px #ffffff1f,0 8px 16px #12244e3d}.bm-W button:disabled{opacity:.56;cursor:not-allowed;text-decoration:none;transform:none;filter:saturate(.72);box-shadow:none}.bm-W button.bm-1D{color:#07203b;background:linear-gradient(135deg,#ffffff6b,#baf6ff57);border-color:#eff8ff6b;box-shadow:inset 0 1px #ffffff70,0 10px 22px #81b6ff24}.bm-W button.bm-1D:hover,.bm-W button.bm-1D:focus-visible{background:linear-gradient(135deg,#ffffff85,#ccfaff5c)}.bm-W button.bm-1s{background:linear-gradient(135deg,#ffffff29,#ffffff14);border-color:#ffffff2e;box-shadow:inset 0 1px #ffffff24,0 8px 20px #00000014}.bm-W button.bm-1s:hover,.bm-W button.bm-1s:focus-visible{background:linear-gradient(135deg,#ffffff3d,#baf6ff1f)}.bm-s{display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.16);inline-size:1.62rem;block-size:1.62rem;min-height:1.62rem!important;min-width:1.62rem;margin-top:0;text-align:center;line-height:1;padding:0!important;aspect-ratio:1 / 1;border-radius:50%!important;background:linear-gradient(135deg,#ffffff3d,#ffffff1a)!important;box-shadow:inset 0 1px #ffffff2e,0 8px 18px #0000001a!important;overflow:hidden;flex:0 0 auto;font-size:.74rem}.bm-s svg{width:70%;height:70%}.bm-J{vertical-align:middle}.bm-J svg{width:50%;margin:0 auto;fill:#111}.bm-W button.bm-A{background:transparent!important;box-shadow:none!important;border-color:transparent!important}.bm-A.bm-f:hover,.bm-A.bm-f:focus{background-color:#ffffff2e!important}.bm-A.bm-f:active{background-color:#ffffff3d!important}.bm-A.bm-g:hover,.bm-A.bm-g:focus{background-color:#00000024!important}.bm-A.bm-g:active{background-color:#0003!important}.bm-W input[type=number],.bm-W select,.bm-W textarea{color:var(--bm-text-primary);font-family:var(--bm-font-body);background:linear-gradient(180deg,#ffffff29,#ffffff0f);border:1px solid rgba(255,255,255,.18);border-radius:12px;box-shadow:inset 0 1px #ffffff1f}input[type=number].bm-C{appearance:auto;-moz-appearance:textfield;width:5.9ch;margin-left:1ch;padding:.2em .35ch;font-size:small}input[type=number].bm-C::-webkit-outer-spin-button,input[type=number].bm-C::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-K)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-K,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-W select{padding:.22em .45ch}.bm-W label:has(input[type=checkbox]){display:flex;width:fit-content;gap:1ch;align-items:center;color:var(--bm-text-secondary)}.bm-W input[type=checkbox]{width:1em;accent-color:#74e7ff}.bm-m{overflow:hidden;max-height:calc(100% - 5px);transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-W textarea{font-size:small;padding:.38em .52em;height:4em;width:100%;resize:vertical;line-height:1.45}.bm-W textarea::placeholder,.bm-W input::placeholder{color:#2f446699}.bm-W a:not(:has(*)){color:#1558a4f0;text-decoration:underline;text-decoration-color:#1558a459}.bm-W small{font-size:x-small;font-family:var(--bm-font-display);letter-spacing:.12em;color:var(--bm-text-secondary)}.bm-W ul li{list-style:disc;margin-left:5ch}.bm-W .bm-L.bm-H{max-height:var(--bm-H-max-height, calc(80vh - 150px) );overflow:auto;scrollbar-width:thin;scrollbar-color:rgba(146,221,255,.42) rgba(255,255,255,.05)}.bm-W .bm-L.bm-H::-webkit-scrollbar{width:10px;height:10px}.bm-W .bm-L.bm-H::-webkit-scrollbar-thumb{background:linear-gradient(180deg,#74e7ff7a,#538dff66);border-radius:999px;border:2px solid transparent;background-clip:padding-box}.bm-W .bm-L.bm-H::-webkit-scrollbar-track{background:#ffffff0a;border-radius:999px}.bm-x{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.35ch}.bm-D{display:flex;align-content:center;justify-content:center;align-items:center;gap:.35ch}.bm-_{white-space:pre;letter-spacing:0;line-height:1!important;font-size:1.6em;font-family:monospace}.bm-N .bm-L:not(#bm-F .bm-L){margin-top:.18em;margin-bottom:.18em}.bm-N h1:not(#bm-F h1){font-size:1em}#bm-t p svg{display:inline;height:1em;fill:#fff}#bm-t:not(.bm-N){width:min(50rem,calc(100vw - .55rem));max-width:min(50rem,calc(100vw - .55rem))!important}#bm-t .bm-1K{padding-top:.08rem}#bm-t .bm-1C{gap:.22rem;flex-wrap:wrap;width:100%;padding:.16rem}#bm-t .bm-1C>button{flex:1 1 10rem}#bm-t .bm-1p{padding-right:.08rem}#bm-t .bm-1x{display:grid;grid-template-columns:minmax(16rem,20rem) minmax(0,1fr);gap:.24rem .3rem;align-items:stretch}#bm-t .bm-1x>hr,#bm-t .bm-1r{grid-column:1 / -1}#bm-t .bm-1q,#bm-t .bm-1Y,#bm-t .bm-1r{padding:.38rem .48rem;border-radius:13px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(155deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29,0 8px 20px #00000014}#bm-t .bm-1q{display:grid;gap:.18rem}#bm-t .bm-1q br{display:none}#bm-t .bm-1q span{display:block;padding:.28rem .38rem;border-radius:10px;background:linear-gradient(180deg,#fff3,#ffffff14)}#bm-t .bm-1Y p{margin:0}#bm-t .bm-1r fieldset{border:none;padding:0;margin:0}#bm-t .bm-1r legend{margin-bottom:.12rem}#bm-t .bm-1r .bm-L{margin-top:.1rem;margin-bottom:.1rem}#bm-t .bm-1j{display:flex;justify-content:flex-start}#bm-t .bm-1j button{min-width:7.8rem}#bm-E{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;align-items:stretch;gap:.3rem}#bm-t .bm-z{position:relative;overflow:hidden;width:fit-content;max-width:35ch;padding:.28rem;gap:.28rem;border-radius:13px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(160deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29,0 8px 20px #00000014;transition:background .25s ease,border-color .25s ease,box-shadow .25s ease,transform .25s ease}#bm-t .bm-z:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at top right,rgba(255,255,255,.18),transparent 24%),radial-gradient(circle at 18% 0%,rgba(186,246,255,.12),transparent 22%)}#bm-t .bm-z:hover,#bm-t .bm-z:focus-within{transform:translateY(-2px);border-color:#92ddff42;background:linear-gradient(160deg,#ffffff38,#baf6ff1a);box-shadow:inset 0 1px #fff3,0 10px 24px #0000001a}#bm-t .bm-a{display:block;width:fit-content;height:fit-content;padding:.26rem;border:1px solid rgba(255,255,255,.18);border-radius:10px;box-shadow:inset 0 1px #ffffff24,0 6px 16px #00000014}#bm-t .bm-z[data-id="-2"] .bm-a{background:conic-gradient(#a00,#aa0 16.6%,#0a0,#0aa 50%,#00a 66.6%,#a0a,#a00)}#bm-t .bm-z[data-id="-1"] .bm-a{background:url('data:image/svg+xml;utf8,') repeat;background-color:transparent!important}#bm-t .bm-z[data-id="-1"] .bm-a svg{fill:#fff!important}#bm-t .bm-z[data-id="0"] .bm-a{background-color:transparent!important}#bm-t .bm-a button{padding:.26em .14ch}#bm-t .bm-a svg{width:4ch}#bm-t .bm-z>.bm-x{flex-direction:column;align-items:flex-start;gap:.02rem}#bm-t .bm-z h2{margin:.04rem 0 0}#bm-t .bm-z .bm-6{margin:.1rem 0 0}#bm-t .bm-z small{font-size:.75em}#bm-t .bm-z.bm-I{display:none}#bm-t.bm-N{--bm-H-max-height: 100%;display:grid;grid-template-rows:auto minmax(0,1fr);width:268px;height:min(60vh,22rem);min-width:228px;min-height:180px;max-width:min(1000px,calc(100vw - 16px))!important;max-height:min(1400px,calc(100vh - 16px))!important;overflow:hidden;box-sizing:border-box;position:fixed;transition:background .32s ease,border-color .22s ease,box-shadow .22s ease,transform 0s}#bm-t.bm-N .bm-m{display:grid;grid-template-rows:auto auto auto auto minmax(0,1fr);grid-row:2;min-height:0;min-width:0;overflow:hidden}#bm-t.bm-N .bm-1C{gap:.16rem;flex-wrap:nowrap;width:100%;padding:.12rem}#bm-t.bm-N .bm-1C>button{flex:1 1 0;min-width:0}#bm-t.bm-N #bm-E{flex-direction:column;align-items:stretch;gap:.16rem;width:100%;align-self:stretch;min-width:0;box-sizing:border-box}#bm-t.bm-N .bm-z{width:100%;max-width:none;align-self:stretch;flex:1 1 auto;min-width:0;margin:0;padding:.12rem;border-radius:11px;box-sizing:border-box}#bm-t.bm-N .bm-z>.bm-x{width:100%;min-width:0;flex:1 1 auto}#bm-t.bm-N .bm-L.bm-H{display:block;grid-row:5;min-height:0;min-width:0;height:100%;width:100%;max-height:100%!important;overflow:auto;box-sizing:border-box}#bm-t.bm-N .bm-1L{position:absolute;right:4px;bottom:4px;display:flex;width:20px;height:20px;align-items:flex-end;justify-content:flex-end;padding-right:4px;padding-bottom:4px;box-sizing:border-box;z-index:5;cursor:nwse-resize;pointer-events:auto;opacity:.78;touch-action:none;user-select:none;color:#ffffffdb;background:linear-gradient(135deg,#ffffff24,#538dff24);border:1px solid rgba(255,255,255,.12);border-radius:8px;box-shadow:inset 0 1px #ffffff14}#bm-t.bm-N .bm-1L:hover,#bm-t.bm-N .bm-1L.bm-2b{opacity:1;border-color:#92ddff5c;box-shadow:inset 0 1px #ffffff1a,0 8px 16px #00000029}#bm-t.bm-N .bm-a{display:flex;width:100%;min-width:0;flex:1 1 auto;gap:.5ch;align-items:center;padding:.1rem .2rem;border:none;border-radius:8px;box-sizing:border-box}#bm-t.bm-N .bm-a button{padding:.2em .1ch;flex:0 0 auto}#bm-t.bm-N .bm-a svg{width:2.7ch}#bm-t.bm-N .bm-z h2{font-size:.78rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#bm-t #bm-2{display:inline-flex;align-items:center;padding:.08rem .24rem;border-radius:999px;background:#ffffff1f;box-shadow:inset 0 1px #ffffff14;font-size:1em}@media (max-width: 980px){#bm-t:not(.bm-N){width:min(100vw - .35rem,50rem);max-width:min(100vw - .35rem,50rem)!important}#bm-t .bm-1x{grid-template-columns:1fr}#bm-t .bm-1Y,#bm-t .bm-1r,#bm-t .bm-1x>hr{grid-column:auto}}#bm-F{width:min(25.5rem,calc(100vw - .65rem));max-width:min(25.5rem,calc(100vw - .65rem))!important}#bm-F .bm-m{display:flex;flex-direction:column}#bm-F .bm-29,#bm-F .bm-25{position:relative;overflow:hidden;border-radius:14px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(150deg,#ffffff2e,#ffffff14);box-shadow:inset 0 1px #fff3,0 10px 24px #0000001a}#bm-F .bm-29:before,#bm-F .bm-25:before{content:"";position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at top right,rgba(255,255,255,.2),transparent 26%),radial-gradient(circle at 20% 0%,rgba(186,246,255,.16),transparent 24%)}#bm-F .bm-29{display:flex;align-items:center;gap:.5rem;padding:.48rem .58rem}#bm-F .bm-29 h1{margin:0}#bm-F .bm-24{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.24rem}#bm-F .bm-1F{min-width:0;min-height:2.55rem;display:flex;align-items:flex-start;padding:.34rem .45rem;border-radius:11px;border:1px solid rgba(255,255,255,.18);background:linear-gradient(160deg,#ffffff2e,#ffffff12);box-shadow:inset 0 1px #ffffff29;color:#12233ff5;line-height:1.22}#bm-F .bm-1F>span,#bm-F .bm-1F>time{min-width:0}#bm-F .bm-1f,#bm-F .bm-1g{flex-direction:column;justify-content:center;gap:.08rem}#bm-F .bm-1z{display:inline-block;font-size:1.3em;color:#0f1f38f5;white-space:normal;overflow-wrap:anywhere}#bm-F .bm-1z b{font-size:1em}#bm-F .bm-1y{color:#314769d1;font-size:.62rem;letter-spacing:.08em;font-family:var(--bm-font-display);text-transform:uppercase}#bm-F .bm-1F time{white-space:nowrap;font-family:var(--bm-font-mono);letter-spacing:.06em}#bm-F .bm-25{padding:.48rem}#bm-F .bm-1-{display:grid;grid-template-columns:auto repeat(4,minmax(0,1fr));gap:.22rem;align-items:center}#bm-F .bm-1- .bm-J{width:1.8rem;height:1.8rem}#bm-F .bm-1- .bm-C{width:100%;margin-left:0;text-align:center}#bm-F .bm-1_,#bm-F .bm-20{margin-top:.24rem}#bm-F .bm-1_>div{width:100%}#bm-F .bm-1V{gap:.24rem;margin-top:.3rem}#bm-F .bm-1V>button{flex:1 1 0}#bm-F .bm-20 textarea{min-height:4.1rem}@media (max-width: 720px){#bm-F{width:min(100vw - .45rem,25.5rem);max-width:min(100vw - .45rem,25.5rem)!important}#bm-F .bm-24{grid-template-columns:1fr}#bm-F .bm-1-{grid-template-columns:repeat(2,minmax(0,1fr))}#bm-F .bm-1- .bm-J{grid-column:1 / -1;width:100%;aspect-ratio:auto;height:1.8rem}#bm-F .bm-1V{flex-direction:column}}#bm-l div:has(>.bm-3){width:fit-content;justify-content:flex-start}#bm-l .bm-3{display:flex;flex-direction:column;width:13%}#bm-l .bm-3 span{width:fit-content;margin:auto;font-size:.7em}#bm-l .bm-3 button{width:fit-content;padding:0;border-radius:0}#bm-l .bm-3 svg{stroke:#333;stroke-width:.02px;width:100%;min-width:1.5ch;max-width:14.5ch}#bm-l .bm-3 button:hover svg,#bm-l .bm-3 button:focus svg{opacity:.9}#bm-l .bm-n{display:grid;grid-template-columns:1fr 1fr 1fr;width:25%;min-width:3ch;max-width:15ch}#bm-l .bm-n>button{width:100%;padding:0;aspect-ratio:1 / 1;background-color:#fff;border:#333 1px solid;border-radius:0;box-sizing:border-box}#bm-l .bm-n>button[data-status=Incorrect]{background-color:brown}#bm-l .bm-n>button[data-status=Template]{background-color:#2f4f4f}#bm-l .bm-n>button:hover,#bm-l .bm-n>button:focus{opacity:.8}#bm-B{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}#bm-B>.bm-L{width:100%;justify-content:flex-start;background-color:#153063e6;border-radius:1em;padding:.5em;transition:background-color .3s ease}#bm-B>.bm-L:hover,#bm-B>.bm-L:focus-within{background-color:#112855e6}#bm-B .bm-1{height:100%;font-size:xxx-large}#bm-B .bm-0{flex-direction:column;align-items:flex-start;gap:0} -/* Build Hash: 0fe5479ecc95 */ +/* Build Hash: 6b41fb875b79 */ diff --git a/dist/BlueMarble.user.js b/dist/BlueMarble.user.js index c22165c..1295261 100644 --- a/dist/BlueMarble.user.js +++ b/dist/BlueMarble.user.js @@ -39,6 +39,6 @@ The "Blue Marble" image is owned by NASA. */ -(()=>{var t=t=>{throw TypeError(t)},e=(e,i,n)=>i.has(e)?t("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(e):i.set(e,n),i=(e,i,n)=>(((e,i)=>{i.has(e)||t("Cannot access private method")})(e,i),n);function n(t){return new Promise(e=>setTimeout(e,t))}function s(t){return(new Intl.NumberFormat).format(t)}function o(t){return new Intl.NumberFormat(void 0,{style:"percent",t:2,i:2}).format(t)}function a(t){return t.toLocaleString(void 0,{o:"long",l:"numeric",h:"2-digit",m:"2-digit",u:"2-digit"})}function r(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function l(...t){(0,console.log)(...t)}function h(...t){(0,console.error)(...t)}function c(...t){(0,console.warn)(...t)}function m(t,e){if(0===t)return e[0];let i="";const n=e.length;for(;t>0;)i=e[t%n]+i,t=Math.floor(t/n);return i}function d(t,e){let i=0;const n=e.length;for(const s of t){const t=e.indexOf(s);-1==t&&h(`Invalid character '${s}' encountered whilst decoding! Is the decode alphabet/base incorrect?`),i=i*n+t}return i}function u(t){let e="";for(let i=0;i(t/=255)<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*e[0]+.7152*e[1]+.0722*e[2]}function f(t,e,i){return Array.isArray(t)&&([t,e,i]=t),(1<<24|t<<16|e<<8|i).toString(16).slice(1)}var g,w,x,y,$,v=[{id:0,premium:!1,name:"Transparent",rgb:[0,0,0]},{id:1,premium:!1,name:"Black",rgb:[0,0,0]},{id:2,premium:!1,name:"Dark Gray",rgb:[60,60,60]},{id:3,premium:!1,name:"Gray",rgb:[120,120,120]},{id:4,premium:!1,name:"Light Gray",rgb:[210,210,210]},{id:5,premium:!1,name:"White",rgb:[255,255,255]},{id:6,premium:!1,name:"Deep Red",rgb:[96,0,24]},{id:7,premium:!1,name:"Red",rgb:[237,28,36]},{id:8,premium:!1,name:"Orange",rgb:[255,127,39]},{id:9,premium:!1,name:"Gold",rgb:[246,170,9]},{id:10,premium:!1,name:"Yellow",rgb:[249,221,59]},{id:11,premium:!1,name:"Light Yellow",rgb:[255,250,188]},{id:12,premium:!1,name:"Dark Green",rgb:[14,185,104]},{id:13,premium:!1,name:"Green",rgb:[19,230,123]},{id:14,premium:!1,name:"Light Green",rgb:[135,255,94]},{id:15,premium:!1,name:"Dark Teal",rgb:[12,129,110]},{id:16,premium:!1,name:"Teal",rgb:[16,174,166]},{id:17,premium:!1,name:"Light Teal",rgb:[19,225,190]},{id:18,premium:!1,name:"Dark Blue",rgb:[40,80,158]},{id:19,premium:!1,name:"Blue",rgb:[64,147,228]},{id:20,premium:!1,name:"Cyan",rgb:[96,247,242]},{id:21,premium:!1,name:"Indigo",rgb:[107,80,246]},{id:22,premium:!1,name:"Light Indigo",rgb:[153,177,251]},{id:23,premium:!1,name:"Dark Purple",rgb:[120,12,153]},{id:24,premium:!1,name:"Purple",rgb:[170,56,185]},{id:25,premium:!1,name:"Light Purple",rgb:[224,159,249]},{id:26,premium:!1,name:"Dark Pink",rgb:[203,0,122]},{id:27,premium:!1,name:"Pink",rgb:[236,31,128]},{id:28,premium:!1,name:"Light Pink",rgb:[243,141,169]},{id:29,premium:!1,name:"Dark Brown",rgb:[104,70,52]},{id:30,premium:!1,name:"Brown",rgb:[149,104,42]},{id:31,premium:!1,name:"Beige",rgb:[248,178,119]},{id:32,premium:!0,name:"Medium Gray",rgb:[170,170,170]},{id:33,premium:!0,name:"Dark Red",rgb:[165,14,30]},{id:34,premium:!0,name:"Light Red",rgb:[250,128,114]},{id:35,premium:!0,name:"Dark Orange",rgb:[228,92,26]},{id:36,premium:!0,name:"Light Tan",rgb:[214,181,148]},{id:37,premium:!0,name:"Dark Goldenrod",rgb:[156,132,49]},{id:38,premium:!0,name:"Goldenrod",rgb:[197,173,49]},{id:39,premium:!0,name:"Light Goldenrod",rgb:[232,212,95]},{id:40,premium:!0,name:"Dark Olive",rgb:[74,107,58]},{id:41,premium:!0,name:"Olive",rgb:[90,148,74]},{id:42,premium:!0,name:"Light Olive",rgb:[132,197,115]},{id:43,premium:!0,name:"Dark Cyan",rgb:[15,121,159]},{id:44,premium:!0,name:"Light Cyan",rgb:[187,250,242]},{id:45,premium:!0,name:"Light Blue",rgb:[125,199,255]},{id:46,premium:!0,name:"Dark Indigo",rgb:[77,49,184]},{id:47,premium:!0,name:"Dark Slate Blue",rgb:[74,66,132]},{id:48,premium:!0,name:"Slate Blue",rgb:[122,113,196]},{id:49,premium:!0,name:"Light Slate Blue",rgb:[181,174,241]},{id:50,premium:!0,name:"Light Brown",rgb:[219,164,99]},{id:51,premium:!0,name:"Dark Beige",rgb:[209,128,81]},{id:52,premium:!0,name:"Light Beige",rgb:[255,197,165]},{id:53,premium:!0,name:"Dark Peach",rgb:[155,82,73]},{id:54,premium:!0,name:"Peach",rgb:[209,128,120]},{id:55,premium:!0,name:"Light Peach",rgb:[250,182,164]},{id:56,premium:!0,name:"Dark Tan",rgb:[123,99,82]},{id:57,premium:!0,name:"Tan",rgb:[156,132,107]},{id:58,premium:!0,name:"Dark Slate",rgb:[51,57,65]},{id:59,premium:!0,name:"Slate",rgb:[109,117,141]},{id:60,premium:!0,name:"Light Slate",rgb:[179,185,209]},{id:61,premium:!0,name:"Dark Stone",rgb:[109,100,63]},{id:62,premium:!0,name:"Stone",rgb:[148,140,107]},{id:63,premium:!0,name:"Light Stone",rgb:[205,197,158]}],M=class{constructor(t,i){e(this,g),this.name=t,this.version=i,this.p=null,this.$=null,this.v="bm-r",this.M=null,this.C=null,this.T=[]}S(t){this.p=t}k(t){this.$=t}D(){return this.T.length>0&&(this.C=this.T.pop()),this}N(t){t?.appendChild(this.M),this.M=null,this.C=null,this.T=[]}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}L(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"p",{},t)),this}O(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"small",{},t)),this}B(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"span",{},t)),this}I(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"details",{},t)),this}A(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"summary",{},t)),this}P(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"img",{},t)),this}W(t,e={},n=()=>{}){return n(this,i(this,g,w).call(this,"h"+t,{},e)),this}F(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"form",{},t)),this}U(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"fieldset",{},t)),this}G(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"legend",{},t)),this}R(t={},e=()=>{}){const n={};t.textContent?(n.textContent=t.textContent,delete t.textContent):t.innerHTML&&(n.innerHTML=t.innerHTML,delete t.textContent);const s=i(this,g,w).call(this,"label",n),o=i(this,g,w).call(this,"input",{type:"checkbox"},t);return s.insertBefore(o,s.firstChild),this.D(),e(this,s,o),this}j(t={},e=()=>{}){const n=i(this,g,w).call(this,"label",{textContent:t.textContent??"",for:t.id??""});return delete t.textContent,this.D(),e(this,n,i(this,g,w).call(this,"select",{},t)),this}Y(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"option",{},t)),this}J(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ul",{},t)),this}q(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"menu",{},t)),this}Z(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"li",{},t)),this}K(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"table",{},t)),this}tt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"caption",{},t)),this}et(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"thead",{},t)),this}it(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tbody",{},t)),this}nt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tfoot",{},t)),this}st(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tr",{},t)),this}ot(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"th",{},t)),this}rt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"td",{},t)),this}lt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"button",{},t)),this}ht(t={},e=()=>{}){const n=t.title??t.textContent??"Help: No info";delete t.textContent,t.title=`Help: ${n}`;const s={textContent:"?",className:"bm-10",onclick:()=>{this.ct(this.v,n)}};return e(this,i(this,g,w).call(this,"button",s,t)),this}dt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"input",{},t)),this}ut(t={},e=()=>{}){const n=t.textContent??"";delete t.textContent;const s=i(this,g,w).call(this,"div"),o=i(this,g,w).call(this,"input",{type:"file",tabindex:"-1","aria-hidden":"true"},t);this.D();const a=i(this,g,w).call(this,"button",{textContent:n});return this.D(),this.D(),a.addEventListener("click",()=>{o.click()}),o.addEventListener("change",()=>{a.style.maxWidth=`${a.offsetWidth}px`,o.files.length>0?a.textContent=o.files[0].name:a.textContent=n}),e(this,s,o,a),this}bt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"textarea",{},t)),this}ft(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{class:"bm-S"},t)),this}gt(t=Date.now(),e=500,n={},s=()=>{}){const o="bm--",a=n?.id||o+"-"+crypto.randomUUID().slice(0,8),r={class:o},l=i(this,g,w).call(this,"time",r,n);return l.id=a,l.dataset.endDate=t,setInterval(()=>{if(!l.isConnected)return;const t=Math.max(l.dataset.endDate-Date.now(),0),e=Math.floor(t/1e3),i=Math.floor(e/3600),n=Math.floor(e%60),s=Math.floor(e%3600/60);l.setAttribute("datetime",`PT${i}H${s}M${n}S`),l.textContent=String(i).padStart(2,"0")+":"+String(s).padStart(2,"0")+":"+String(n).padStart(2,"0")},e),s(this,l),this}ct(t,e,i=!1){const n=document.getElementById(t.replace(/^#/,""));n&&(n instanceof HTMLInputElement?n.value=e:i?n.textContent=e:n.innerHTML=e)}wt(t){if(t.disabled)return;t.disabled=!0,t.style.textDecoration="none";const e=t.closest(".bm-W"),i=t.closest(".bm-S"),n=e.querySelector("h1"),s=e.querySelector(".bm-m");if(e.parentElement.append(e),"expanded"==t.dataset.buttonStatus){s.style.height=s.scrollHeight+"px",e.style.width=e.scrollWidth+"px",s.style.height="0",s.addEventListener("transitionend",function e(){s.style.display="none",t.disabled=!1,t.style.textDecoration="",s.removeEventListener("transitionend",e)});const i=n.cloneNode(!0),o=i.textContent;t.nextElementSibling.appendChild(i),t.textContent="▶",t.dataset.buttonStatus="collapsed",t.ariaLabel=`Unminimize window "${o}"`}else{const n=i.querySelector("h1"),o=n.textContent;n.remove(),s.style.display="",s.style.height="0",e.style.width="",s.style.height=s.scrollHeight+"px",s.addEventListener("transitionend",function e(){s.style.height="",t.disabled=!1,t.style.textDecoration="",s.removeEventListener("transitionend",e)}),t.textContent="▼",t.dataset.buttonStatus="expanded",t.ariaLabel=`Minimize window "${o}"`}}xt(t,e,i={}){const n=document.querySelector(t),s=document.querySelector(e),o=i?.yt??(()=>{});if(!n||!s)return void this.$t(`Can not drag! ${n?"":"moveMe"} ${n||s?"":"and "}${s?"":"iMoveThings "}was not found!`);let a,r=!1,l=0,h=null,c=0,m=0,d=0,u=0,b=null;const p=()=>{if(r){const t=Math.abs(c-d),e=Math.abs(m-u);(t>.5||e>.5)&&(c=d,m=u,n.style.transform=`translate(${c}px, ${m}px)`,n.style.left="0px",n.style.top="0px",n.style.right=""),h=requestAnimationFrame(p)}},f=(t,e)=>{r=!0,b=n.getBoundingClientRect(),a=t-b.left,l=e-b.top;const i=window.getComputedStyle(n).transform;if(i&&"none"!==i){const t=new DOMMatrix(i);c=t.m41,m=t.m42}else c=b.left,m=b.top;d=c,u=m,document.body.style.userSelect="none",s.classList.add("bm-M"),document.addEventListener("mousemove",w),document.addEventListener("touchmove",x,{passive:!1}),document.addEventListener("mouseup",g),document.addEventListener("touchend",g),document.addEventListener("touchcancel",g),h&&cancelAnimationFrame(h),p()},g=()=>{r=!1,h&&(cancelAnimationFrame(h),h=null),document.body.style.userSelect="",s.classList.remove("bm-M"),document.removeEventListener("mousemove",w),document.removeEventListener("touchmove",x),document.removeEventListener("mouseup",g),document.removeEventListener("touchend",g),document.removeEventListener("touchcancel",g),o({element:n,x:c,y:m}),b=null},w=t=>{r&&b&&(d=t.clientX-a,u=t.clientY-l)},x=t=>{if(r&&b){const e=t.touches[0];if(!e)return;d=e.clientX-a,u=e.clientY-l,t.preventDefault()}};s.addEventListener("mousedown",function(t){t.preventDefault(),f(t.clientX,t.clientY)}),s.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(f(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t,e,i={}){const n=document.querySelector(t),s=document.querySelector(e),o=i?.yt??(()=>{});if(!n||!s)return void this.$t(`Can not resize! ${n?"":"resizeMe"} ${n||s?"":"and "}${s?"":"iResizeThings "}was not found!`);let a=!1,r=0,l=0,h=0,c=0,m=0,d=0,u=0,b=0,p=null;const f=()=>Number.isFinite(i?.maxWidth)?i.maxWidth:window.innerWidth-16,g=()=>Number.isFinite(i?.maxHeight)?i.maxHeight:window.innerHeight-16,w=Number.isFinite(i?.minWidth)?i.minWidth:200,x=Number.isFinite(i?.minHeight)?i.minHeight:160,y=(t,e,i)=>Math.min(Math.max(t,e),Math.max(e,i)),$=()=>{if(a){const t=Math.abs(m-u),e=Math.abs(d-b);(t>.5||e>.5)&&(m=u,d=b,n.style.width=`${m}px`,n.style.height=`${d}px`),p=requestAnimationFrame($)}},v=(t,e)=>{a=!0,r=t,l=e,h=n.offsetWidth,c=n.offsetHeight,m=h,d=c,u=h,b=c,document.body.style.userSelect="none",s.classList.add("bm-1S"),document.addEventListener("mousemove",C),document.addEventListener("touchmove",T,{passive:!1}),document.addEventListener("mouseup",M),document.addEventListener("touchend",M),document.addEventListener("touchcancel",M),p&&cancelAnimationFrame(p),$()},M=()=>{a=!1,p&&(cancelAnimationFrame(p),p=null),document.body.style.userSelect="",s.classList.remove("bm-1S"),document.removeEventListener("mousemove",C),document.removeEventListener("touchmove",T),document.removeEventListener("mouseup",M),document.removeEventListener("touchend",M),document.removeEventListener("touchcancel",M),o({element:n,width:m,height:d})},C=t=>{a&&(u=y(h+(t.clientX-r),w,f()),b=y(c+(t.clientY-l),x,g()))},T=t=>{if(!a)return;const e=t?.touches?.[0];e&&(u=y(h+(e.clientX-r),w,f()),b=y(c+(e.clientY-l),x,g()),t.preventDefault())};s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),v(t.clientX,t.clientY)}),s.addEventListener("touchstart",t=>{const e=t?.touches?.[0];e&&(t.preventDefault(),t.stopPropagation(),v(e.clientX,e.clientY))},{passive:!1})}Mt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.v,"Status: "+t,!0)}$t(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.v,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},n={}){const s=document.createElement(t);this.M?(this.C?.appendChild(s),this.T.push(this.C),this.C=s):(this.M=s,this.C=s);for(const[t,n]of Object.entries(e))i(this,g,x).call(this,s,t,n);for(const[t,e]of Object.entries(n))i(this,g,x).call(this,s,t,e);return s},x=function(t,e,i){"class"==e?t.classList.add(...i.split(/\s+/)):"for"==e?t.htmlFor=i:"tabindex"==e?t.tabIndex=Number(i):"readonly"==e?t.readOnly="true"==i||"1"==i:"maxlength"==e?t.maxLength=Number(i):e.startsWith("data")?t.dataset[e.slice(5).split("-").map((t,e)=>0==e?t:t[0].toUpperCase()+t.slice(1)).join("")]=i:e.startsWith("aria")?t.setAttribute(e,i):t[e]=i};var C,T,S,k,D,N=class extends M{constructor(t,i){super(t,i),e(this,y),this.window=null,this.Ct="bm-l",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.H({id:this.Ct,class:"bm-W"}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Settings"}).D().D().F().D().L({textContent:"Settings take 5 seconds to save."}).D().H({class:"bm-L bm-H"},(t,e)=>{this.kt(),this.Dt()}).D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}kt(){i(this,y,$).call(this,"Pixel Highlight")}Dt(){i(this,y,$).call(this,"Template")}};y=new WeakSet,$=function(t){this.window=this.H({class:"bm-L"}).W(2,{textContent:t}).D().F().D().L({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).D().D()},C=new WeakSet,T=function(t,e){t.disabled=!0;const i=t.dataset.status,n=this.Nt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];let s=[2,0,0];const o=n;switch(i){case"Disabled":t.dataset.status="Incorrect",t.ariaLabel="Sub-pixel incorrect",s=[1,...e];break;case"Incorrect":t.dataset.status="Template",t.ariaLabel="Sub-pixel template",s=[2,...e];break;case"Template":t.dataset.status="Disabled",t.ariaLabel="Sub-pixel disabled",s=[0,...e];break}const a=n.findIndex(([,t,e])=>t==s[1]&&e==s[2]);0!=s[0]?-1!=a?o[a]=s:o.push(s):-1!=a&&o.splice(a,1),this.Nt.highlight=o,t.disabled=!1},S=async function(t){const e=document.querySelectorAll(".bm-3 button");for(const t of e)t.disabled=!0;let i=[0,0,0,0,2,0,0,0,0];switch(t){case"Cross":i=[0,1,0,1,2,1,0,1,0];break;case"X":i=[1,0,1,0,2,0,1,0,1];break;case"Full":i=[2,2,2,2,2,2,2,2,2];break}const s=document.querySelector(".bm-n")?.childNodes??[];for(let t=0;t{const[n,s,o,a]=e.split(",").map(Number);(s>>24==0?0:s.get(e)??-2;const a=o.get(n);o.set(n,a?a+1:1)}return console.log(o),o};var L=class{constructor(){this.Jt=Math.ceil(80/1300*window.innerWidth),this.Xt=v.slice(1)}qt(t){const e=document.createElement("div");for(let t=0;t{t.parentNode.childElementCount<=1?t.parentNode.remove():t.remove()},e.appendChild(t)}t.appendChild(e)}},O=class extends HTMLElement{};customElements.define("confetti-piece",O);var B,I,A,P,z,W,F,V,_,U,G,R,E,j,Y,J,X,q,Z,Q,K,tt=class extends M{constructor(t,e){super(t,e),this.window=null,this.Ct="bm-o",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.H({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Credits"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Credits"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Credits"}).D().D().F().D().H({class:"bm-L bm-H"}).B({role:"img","aria-label":this.name}).B({innerHTML:"\n██████╗ ██╗ ██╗ ██╗███████╗\n██╔══██╗██║ ██║ ██║██╔════╝\n██████╔╝██║ ██║ ██║█████╗ \n██╔══██╗██║ ██║ ██║██╔══╝ \n██████╔╝███████╗╚██████╔╝███████╗\n╚═════╝ ╚══════╝ ╚═════╝ ╚══════╝\n\n███╗ ███╗ █████╗ ██████╗ ██████╗ ██╗ ███████╗\n████╗ ████║██╔══██╗██╔══██╗██╔══██╗██║ ██╔════╝\n██╔████╔██║███████║██████╔╝██████╔╝██║ █████╗ \n██║╚██╔╝██║██╔══██║██╔══██╗██╔══██╗██║ ██╔══╝ \n██║ ╚═╝ ██║██║ ██║██║ ██║██████╔╝███████╗███████╗\n╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚══════╝\n",class:"bm-_","aria-hidden":"true"}).D().D().V().D().F().D().V().D().B({textContent:'"Blue Marble" userscript is made by SwingTheVine.'}).D().V().D().B({innerHTML:'The Blue Marble Website is made by crqch.'}).D().V().D().B({textContent:`The Blue Marble Website used until ${a(new Date(175606932e4))} was made by Camille Daguin.`}).D().V().D().B({textContent:'The favicon "Blue Marble" is owned by NASA. (The image of the Earth is owned by NASA)'}).D().V().D().B({textContent:"Special Thanks:"}).D().X().Z({textContent:"Espresso, Meqa, and Robot for moderating SwingTheVine's community."}).D().Z({innerHTML:'nof, darkness for creating similar userscripts!'}).D().Z({innerHTML:'Wonda for the Blue Marble banner image!'}).D().Z({innerHTML:'BullStein, allanf181 for being early beta testers!'}).D().Z({innerHTML:'guidu_ and Nick-machado for the original "Minimize" Button code!'}).D().Z({innerHTML:'Nomad and Gustav for the tutorials!'}).D().Z({innerHTML:'cfp for creating the template overlay that Blue Marble was based on!'}).D().Z({innerHTML:'Force Network for hosting the telemetry server!'}).D().Z({innerHTML:'TheBlueCorner for getting me interested in online pixel canvases!'}).D().D().V().D().B({innerHTML:'Donators:'}).D().X().Z({textContent:"Soultree"}).D().Z({textContent:"Espresso"}).D().Z({textContent:"BEST FAN"}).D().Z({textContent:"FuchsDresden"}).D().Z({textContent:"Jack"}).D().Z({textContent:"raiken_au"}).D().Z({textContent:"Jacob"}).D().Z({textContent:"StupidOne"}).D().Z({textContent:"2 Anonymous Supporters"}).D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}},et=class extends M{constructor(t){super(t.name,t.version),e(this,B),this.window=null,this.Ct="bm-t",this.Zt="bm-E",this.Tt=document.body,this.$=t.$??null,this.Qt="ftr-oWin",this.Kt="windowFilter",this.te=null,this.ee=null,this.ie=null,this.ne=260,this.se=220,this.oe=1e3,this.ae=1400,this.re=t.p?.re,this.le='',this.he='';const{palette:i,Yt:n}=this.re.ce;this.palette=i,this.me=0,this.de=0,this.ue=new Map,this.be=new Map,this.pe=0,this.fe=0,this.timeRemaining=0,this.ge="",this.sortPrimary="total",this.sortSecondary="descending",this.showUnused=!1}we(){i(this,B,A).call(this)?this.xe():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,W).call(this);this.window=this.H({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"🗗","aria-label":'Switch to windowed mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,B,P).call(this,!0),i(this,B,W).call(this),this.xe()},e.ontouchend=()=>{e.click()}}).D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,B,W).call(this),e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Color Filter"}).D().D().F().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"Hide All Colors"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!1)}).D().lt({textContent:"Refresh Data"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.ye(),e.disabled=!1}}).D().lt({textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).H({class:"bm-L",style:"margin-left: 2.5ch; margin-right: 2.5ch;"}).H({class:"bm-L"}).B({id:"bm-i",innerHTML:"Tiles Loaded: 0 / ???"}).D().V().D().B({id:"bm-d",innerHTML:"Correct Pixels: ???"}).D().V().D().B({id:"bm-j",innerHTML:"Total Pixels: ???"}).D().V().D().B({id:"bm-7",innerHTML:"Complete: ??? (???)"}).D().V().D().B({id:"bm-8",innerHTML:"??? ???"}).D().D().H({class:"bm-L"}).L({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.le.replace("{e.onclick=t=>{t.preventDefault();const e=new FormData(document.querySelector(`#${this.Ct} form`)),n={};for(const[t,i]of e)n[t]=i;console.log(`Primary: ${n.sortPrimary}; Secondary: ${n.sortSecondary}; Unused: ${"on"==n.showUnused}`),i(this,B,Y).call(this,n.sortPrimary,n.sortSecondary,"on"==n.showUnused)}}).D().D().D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,j).call(this,t),i(this,B,z).call(this),i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${s(this.me)} / ${s(this.de)}`),this.ct("#bm-d",`Correct Pixels: ${s(this.pe)}`),this.ct("#bm-j",`Total Pixels: ${s(this.fe)}`),this.ct("#bm-7",`Remaining: ${s((this.fe||0)-(this.pe||0))} (${o(((this.fe||0)-(this.pe||0))/(this.fe||1))})`),this.ct("#bm-8",`Completed at: `)}xe(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,W).call(this);this.window=this.H({id:this.Ct,class:"bm-W bm-N",style:`width: 300px; height: min(70vh, 32rem); min-width: ${this.ne}px; min-height: ${this.se}px; max-width: min(${this.oe}px, calc(100vw - 16px)); max-height: min(${this.ae}px, calc(100vh - 16px));`}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>{const i=document.querySelector("#bm-2");i&&(i.style.display="expanded"==e.dataset.buttonStatus?"none":""),t.wt(e)},e.ontouchend=()=>{e.click()}}).D().H().B({id:"bm-2",class:"bm-y",style:"font-weight: 700;"}).D().D().H({class:"bm-D"}).lt({class:"bm-s",textContent:"🗖","aria-label":'Switch to fullscreen mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,B,P).call(this,!1),i(this,B,W).call(this),this.St()},e.ontouchend=()=>{e.click()}}).D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,B,W).call(this),e.ontouchend=()=>{e.click()}}).D().D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Color Filter"}).D().D().F().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"None"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!1)}).D().lt({textContent:"Refresh"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.ye(),e.disabled=!1}}).D().lt({textContent:"All"},(t,e)=>{e.onclick=()=>i(this,B,J).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).D().D().H({class:"bm-1y",title:"Resize Color Filter window","aria-label":"Resize Color Filter window",role:"presentation",textContent:"◢",style:"position: absolute; right: 0; bottom: 0; width: 28px; height: 28px; display: flex; align-items: flex-end; justify-content: flex-end; padding-right: 4px; padding-bottom: 4px; box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; touch-action: none; user-select: none; font-size: 8px; line-height: 1; color: rgba(255,255,255,0.95); background: transparent; border: none; box-shadow: none;"}).D().D().N(this.Tt),i(this,B,E).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,j).call(this,t),i(this,B,z).call(this),i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}ye(){i(this,B,X).call(this);const t=document.querySelector(`#${this.Zt}`),e={};for(const t of this.palette){const i=this.ue.get(t.id)??0,n=s(i);let a=0,r="0",l=o(1);0!=i&&(a=this.be.get(t.id)??"???","number"!=typeof a&&this.me==this.de&&t.id&&(a=0),r="string"==typeof a?a:s(a),l=isNaN(a/i)?"???":o(a/i));const h=parseInt(i)-parseInt(a);e[t.id]={$e:i,ve:n,Me:a,Ce:r,Te:l,Se:h}}if(document.querySelector("#bm-2")){const t=this.pe.toString().length>7?this.pe.toString().slice(0,2)+"…"+this.pe.toString().slice(-3):this.pe.toString(),e=this.fe.toString().length>7?this.fe.toString().slice(0,2)+"…"+this.fe.toString().slice(-3):this.fe.toString();this.ct("#bm-2",`${t}/${e}`,!0)}if(!t)return e;const n=Array.from(t.children);for(const t of n){const i=parseInt(t.dataset.id),{Me:n,Ce:s,Te:o,$e:a,ve:r,Se:l}=e[i];t.dataset.correct=Number.isNaN(parseInt(n))?"0":n,t.dataset.total=a,t.dataset.percent="%"==o.slice(-1)?o.slice(0,-1):"0",t.dataset.incorrect=l||0;const h=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-9`);h&&(h.textContent=`${s} / ${r}`);const c=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-6`);c&&(c.textContent=`${"number"!=typeof l||isNaN(l)?"???":l} incorrect pixel${1==l?"":"s"}. Completed: ${o}`)}i(this,B,Y).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};B=new WeakSet,I=function(){var t,e;return this.$?((t=this.$.Nt)[e=this.Kt]??(t[e]={}),this.$.Nt[this.Kt]):null},A=function(){const t=i(this,B,I).call(this);return"windowed"==t?.mode||"fullscreen"!=t?.mode},P=function(t){const e=i(this,B,I).call(this);e&&(e.mode=t?"windowed":"fullscreen"),this.$&&(this.$.ke(this.Qt,t),this.$.De())},z=function(){const t=document.querySelector(`#${this.Ct} #bm-c`),e=document.querySelector(`#${this.Ct} #bm-5`),i=document.querySelector(`#${this.Ct} #bm-e`);t instanceof HTMLSelectElement&&(t.value=this.sortPrimary),e instanceof HTMLSelectElement&&(e.value=this.sortSecondary),i instanceof HTMLInputElement&&(i.checked=this.showUnused)},W=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,B,G).call(this,t),i(this,B,F).call(this),t?.remove()},F=function(){this.te&&(this.te.disconnect(),this.te=null),this.ee&&(window.removeEventListener("resize",this.ee),this.ee=null),this.ie&&(clearTimeout(this.ie),this.ie=null)},V=function(t,e,i){const n=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),n)},_=function(t,e,i){const n=Math.max(8,window.innerWidth-t.offsetWidth-8),s=Math.max(8,window.innerHeight-t.offsetHeight-8);return{x:Math.min(Math.max(Math.round(Number(e)||8),8),n),y:Math.min(Math.max(Math.round(Number(i)||8),8),s)}},U=function(t){const e=i(this,B,I).call(this);if(!e||!t)return;const n=Number(e.width),s=Number(e.height),o=Number.isFinite(n),a=Number.isFinite(s);o&&(e.width=i(this,B,V).call(this,n,this.ne,Math.min(this.oe,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,B,V).call(this,s,this.se,Math.min(this.ae,window.innerHeight-16)),t.style.height=`${e.height}px`),requestAnimationFrame(()=>{if(!t.isConnected)return;const n=Number(e.x),s=Number(e.y);if(!Number.isFinite(n)||!Number.isFinite(s))return;const o=i(this,B,_).call(this,t,n,s);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${o.x}px, ${o.y}px)`,o.x==n&&o.y==s||(e.x=o.x,e.y=o.y,this.$?.De())})},G=function(t){const e=i(this,B,I).call(this);if(!e||!t?.isConnected||!t.classList.contains("bm-N"))return;const n=t.getBoundingClientRect(),s=i(this,B,V).call(this,n.width,this.ne,Math.min(this.oe,window.innerWidth-16)),o=i(this,B,V).call(this,n.height,this.se,Math.min(this.ae,window.innerHeight-16));Math.round(n.width)!=s&&(t.style.width=`${s}px`),Math.round(n.height)!=o&&(t.style.height=`${o}px`);const a=i(this,B,_).call(this,t,n.left,n.top);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${a.x}px, ${a.y}px)`,e.x=a.x,e.y=a.y,e.width=s,e.height=o,this.$?.De()},R=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,B,G).call(this,t)},e)},E=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,B,F).call(this),i(this,B,U).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{yt:({element:t})=>i(this,B,G).call(this,t)}),this.vt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-1y`,{minWidth:this.ne,minHeight:this.se,maxWidth:Math.min(this.oe,window.innerWidth-16),maxHeight:Math.min(this.ae,window.innerHeight-16),yt:({element:t})=>i(this,B,G).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,B,R).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,B,R).call(this,t,0),window.addEventListener("resize",this.ee))},j=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N");console.log(`Is Windowed Mode: ${e}`);const i=new M(this.name,this.version);i.H({id:this.Zt});const n=this.ye();for(const t of this.palette){const s="#"+f(t.rgb).toUpperCase(),o=p(t.rgb);let a=1.05/(o+.05)>(o+.05)/.05?"white":"black";t.id||(a="transparent");const r="white"==a?"bm-f":"bm-g",{Me:l,Ce:h,Te:c,$e:m,ve:d,Se:u}=n[t.id],b=!!this.re.Ne.get(t.id);if(e){const e=`background-size: auto 100%; background-repeat: repeat-x; background-image: url("data:image/svg+xml;utf8,");`;i.H({class:"bm-L bm-z bm-x","data-id":t.id,"data-name":t.name,"data-premium":+t.premium,"data-correct":Number.isNaN(parseInt(l))?"0":l,"data-total":m,"data-percent":"%"==c.slice(-1)?c.slice(0,-1):"0","data-incorrect":u||0}).H({class:"bm-a",style:`background-color: rgb(${t.rgb?.map(t=>Number(t)||0).join(",")});${t.premium?e:""}`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.he.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.he.replace("Number(t)||0).join(",")});`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.he.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.he.replace("{const o=n.getAttribute("data-"+t),a=s.getAttribute("data-"+t),r=parseFloat(o),l=parseFloat(a),h=!isNaN(r),c=!isNaN(l);if(i?n.classList.remove("bm-I"):Number(n.getAttribute("data-total"))||n.classList.add("bm-I"),h&&c)return"ascending"===e?r-l:l-r;{const t=o.toLowerCase(),i=a.toLowerCase();return ti?"ascending"===e?1:-1:0}}),s.forEach(t=>n.appendChild(t))},J=function(t){const e=document.querySelector(`#${this.Zt}`),i=Array.from(e.children);for(const e of i){if(e.classList?.contains("bm-I"))continue;const i=e.querySelector(".bm-a button");("hidden"!=i.dataset.state||t)&&("shown"==i.dataset.state&&t||i.click())}},X=function(){this.me=0,this.de=0,this.fe=0,this.pe=0,this.be=new Map,this.ue=new Map;for(const t of this.re.Le){const e=t.At?.total??0;this.fe+=e??0;const i=t.At?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,n=this.ue.get(t)??0;this.ue.set(t,n+i)}const n=t.At?.correct??{};this.me+=Object.keys(n).length,this.de+=Object.keys(t.Ot).length;for(const t of Object.values(n))for(const[e,i]of t){const t=Number(i)||0;this.pe+=t;const n=this.be.get(e)??0;this.be.set(e,n+t)}}console.log(`Tiles loaded: ${this.me} / ${this.de}`),this.pe>=this.fe&&this.fe&&this.me==this.de&&(new L).qt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.fe-this.pe)*1e3+Date.now()),this.ge=a(this.timeRemaining)};var it=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,q),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Oe=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Oe?.scriptVersion,this.schemaVersion=this.Oe?.schemaVersion,this.Be=void 0,this.Ie=n,this.re=s}St(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();let t="";document.querySelector("#bm-F")||(t=t.concat("z-index: 9001;").trim()),this.window=this.H({id:this.Ct,class:"bm-W",style:t},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Template Wizard"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Template Wizard"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).D().D().H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Template Wizard"}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().L({id:"bm-v",textContent:"Loading template storage status..."}).D().D().H({class:"bm-L bm-H"}).W(2,{textContent:"Detected templates:"}).D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,q,Z).call(this),i(this,q,Q).call(this)}};q=new WeakSet,Z=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Ie.split(/[-\.\+]/);let n="";t[0]==e[0]?t[1]==e[1]?(n='Template storage health: Healthy!
No futher action required. (Reason: Semantic version matches)',this.Be="Good"):(n='Template storage health: Poor!
You can still use your template, but some features may not work. It is recommended that you update Blue Marble\'s template storage. (Reason: MINOR version mismatch)',this.Be="Poor"):t[0]Bad!
It is guaranteed that some features are broken. You might still be able to use the template. It is HIGHLY recommended that you download all templates and update Blue Marble\'s template storage before continuing. (Reason: MAJOR version mismatch)',this.Be="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Be="Dead");const s=`
If you want to continue using your current templates, then make sure the template storage (schema) is up-to-date.
If you don't want to update the template storage, then downgrade Blue Marble to version ${r(this.scriptVersion)} to continue using your templates.
Alternatively, if you don't care about corrupting the templates listed below, you can fix any issues with the template storage by uploading a new template.`,o=function(){const t=[...document.querySelectorAll("body > div > .hidden")].filter(t=>/version:/i.test(t.textContent));if(t[0]){const e=t[0].textContent?.match(/\d+/);return e?new Date(Number(e[0])):void 0}}();let l=o?a(o):"???";this.ct("#bm-v",`${n}
Your templates were created during Blue Marble version ${r(this.scriptVersion)} with schema version ${r(this.schemaVersion)}.
The current Blue Marble version is ${r(this.version)} and requires schema version ${r(this.Ie)}.
Wplace was last updated on ${l}.${"Good"!=this.Be?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.Be&&(h.H({class:"bm-L bm-D bm-h",style:"gap: 1.5ch;"}),h.lt({textContent:"Download all templates"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.re.Ae().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.Be&&"Bad"!=this.Be||h.lt({textContent:`Update template storage to ${this.Ie}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,q,K).call(this,!0)}}).D(),h.D().N(document.querySelector("#bm-v").parentNode)},Q=function(){const t=this.Oe?.templates;if(Object.keys(t).length>0){const e=document.querySelector(`#${this.Ct} .bm-H`),i=new M(this.name,this.version);i.H({id:"bm-B",class:"bm-L"});for(const e in t){const n=e,o=t[e];if(t.hasOwnProperty(e)){const t=n.split(" "),e=Number(t?.[0]),a=d(t?.[1]||"0",this.re.Pe),r=o.name||`Template ${e||""}`,l=o?.coords?.split(",").map(Number),h=o.pixels?.total??void 0,c=void 0,m="number"==typeof e?s(e):"???",u="number"==typeof a?s(a):"???",b="number"==typeof h?s(h):"???";i.H({class:"bm-L bm-D"}).H({class:"bm-D",style:"flex-direction: column; gap: 0;"}).H({class:"bm-1",textContent:c||"🖼️"}).D().O({textContent:`#${m}`}).D().D().H({class:"bm-D bm-0"}).W(3,{textContent:r}).D().B({textContent:`Uploaded by user #${u}`}).D().B({textContent:`Coordinates: ${l.join(", ")}`}).D().B({textContent:`Total Pixels: ${b}`}).D().D().D()}}i.D().N(e)}},K=async function(t){if(t){const t=document.querySelector(`#${this.Ct} .bm-m`);t.innerHTML="",new M(this.name,this.version).H({class:"bm-L"}).H({class:"bm-L bm-h"}).W(1,{textContent:"Template Wizard"}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().L({textContent:"Updating template storage. Please wait..."}).D().D().D().N(t)}GM_deleteValue("bmCoords");const e=this.Oe?.templates;if(Object.keys(e).length>0)for(const[t,i]of Object.entries(e))if(e.hasOwnProperty(t)){const t=new H({displayName:i.name,Ot:i.tiles});t.jt();const e=await this.re.ze(t);await this.re.We(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new it(this.name,this.version,this.Ie,this.re).St())};var nt,st,ot,at,rt,lt,ht,ct,mt,dt,ut=it;nt=new WeakSet,st=async function(t,e,i){i.preventDefault();const n=await async function(t){let e="";return t&&(e=t.clipboardData.getData("text/plain")),0!=e.length||(await navigator.clipboard.readText().then(t=>{e=t}).catch(t=>{l("Failed to retrieve clipboard data using navigator! Using fallback methods...")}),0!=e.length||(e=window.clipboardData?.getData("Text"))),e}(i),s=n.split(/[^a-zA-Z0-9]+/).filter(t=>t).map(Number).filter(t=>!isNaN(t));2==s.length&&"bm-O"==e.id?(t.ct("bm-O",s?.[0]||""),t.ct("bm-P",s?.[1]||"")):1==s.length?t.ct(e.id,s?.[0]||""):(t.ct("bm-Q",s?.[0]||""),t.ct("bm-R",s?.[1]||""),t.ct("bm-O",s?.[2]||""),t.ct("bm-P",s?.[3]||""))},ot=new WeakSet,at=function(){const t=this.$?.Nt?.filter,e=Array.isArray(t)?t:[];this.Ne.clear();for(const t of e){const e=Number(t);Number.isFinite(e)&&this.Ne.set(e,!0)}},rt=function(){this.$&&(this.$.Nt.filter=Array.from(this.Ne.keys()).map(t=>Number(t)).filter(t=>Number.isFinite(t)).sort((t,e)=>t-e),this.$.De())},lt=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Fe))},ht=async function(t){console.log("Parsing BlueMarble...");const e=t.templates;console.log(`BlueMarble length: ${Object.keys(e).length}`);const i=t?.schemaVersion,n=i.split(/[-\.\+]/),s=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;console.log(`BlueMarble Template Schema: ${i}; Script Version: ${o}`),n[0]==s[0]?(n[1]!=s[1]&&new ut(this.name,this.version,this.schemaVersion,this).St(),this.Le=await async function({It:t,Ve:i,Le:n}){if(Object.keys(e).length>0)for(const s in e){const o=s,a=e[s];if(console.log(`Template Key: ${o}`),e.hasOwnProperty(s)){const e=o.split(" "),s=Number(e?.[0]),r=e?.[1]||"0",l=a.name||`Template ${s||""}`,h={total:a.pixels?.total,colors:new Map(Object.entries(a.pixels?.colors||{}).map(([t,e])=>[Number(t),e]))},c=a.tiles,m={},d={},u=t*i;for(const t in c)if(console.log(t),c.hasOwnProperty(t)){const e=b(c[t]),i=new Blob([e],{type:"image/png"}),n=await createImageBitmap(i);m[t]=n;const s=new OffscreenCanvas(u,u).getContext("2d");s.drawImage(n,0,0);const o=s.getImageData(0,0,n.width,n.height);d[t]=new Uint32Array(o.data.buffer)}const p=new H({displayName:l,Ht:s||this.Le?.length||0,Lt:r||""});p.At=h,p.Ot=m,p.Bt=d,n.push(p),console.log(this.Le),console.log("^^^ This ^^^")}}return n}({It:this.It,Ve:this.Ve,Le:this.Le})):n[0]>>24&255,y=g>>>24&255,$=b.get(w)??-2,v=b.get(g)??-2;if(this.Ne.get($)&&(e[i*h+c]=g),-1==$){const t=536870912;this.Ne.get($)?e[i*h+c]=0:(u/o&1)==(f/o&1)?(e[i*h+c]=t,e[(i-1)*h+(c-1)]=t,e[(i-1)*h+(c+1)]=t,e[(i+1)*h+(c-1)]=t,e[(i+1)*h+(c+1)]=t):(e[i*h+c]=0,e[(i-1)*h+c]=t,e[(i+1)*h+c]=t,e[i*h+(c-1)]=t,e[i*h+(c+1)]=t)}if(!s&&x>m&&v!=$&&(d||y>m)){const t=e[i*h+c];for(const s of n){const[n,o,a]=s,r=0!=n?1!=n?t:4278190335:0;e[(i+a)*h+(c+o)]=r}}if(-1==$&&g<=m){const t=p.get($);p.set($,t?t+1:1);continue}if(x<=m||y<=m)continue;if(v!=$)continue;const M=p.get($);p.set($,M?M+1:1)}return console.log("List of template pixels that match the tile:"),console.log(p),{Je:p,Xe:e}},mt=new WeakSet,dt=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var bt=GM_info.script.name.toString(),pt=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",bt),e.setAttribute("bm-X","color: cornflowerblue;"),e.textContent=`(${t})();`,document.documentElement?.appendChild(e),e.remove()}(()=>{const t=document.currentScript,e=t?.getAttribute("bm-11")||"Blue Marble",i=t?.getAttribute("bm-X")||"",n=new Map;window.addEventListener("message",t=>{const{source:s,endpoint:o,blobID:a,blobData:r,blink:l}=t.data,h=Date.now()-l;if(console.groupCollapsed(`%c${e}%c: ${n.size} Recieved IMAGE message about blob "${a}"`,i,""),console.log(`Blob fetch took %c${String(Math.floor(h/6e4)).padStart(2,"0")}:${String(Math.floor(h/1e3)%60).padStart(2,"0")}.${String(h%1e3).padStart(3,"0")}%c MM:SS.mmm`,i,""),console.log(n),console.groupEnd(),"blue-marble"==s&&a&&r&&!o){const t=n.get(a);"function"==typeof t?t(r):c(`%c${e}%c: Attempted to retrieve a blob (%s) from queue, but the blobID was not a function! Skipping...`,i,"",a),n.delete(a)}});const s=window.fetch;window.fetch=async function(...t){const o=await s.apply(this,t),a=o.clone(),r=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",l=a.headers.get("content-type")||"";if(l.includes("application/json"))console.log(`%c${e}%c: Sending JSON message about endpoint "${r}"`,i,""),a.json().then(t=>{window.postMessage({source:"blue-marble",endpoint:r,jsonData:t},"*")}).catch(t=>{console.error(`%c${e}%c: Failed to parse JSON: `,i,"",t)});else if(l.includes("image/")&&!r.includes("openfreemap")&&!r.includes("maps")){const t=Date.now(),s=await a.blob();return console.log(`%c${e}%c: ${n.size} Sending IMAGE message about endpoint "${r}"`,i,""),new Promise(o=>{const l=crypto.randomUUID();n.set(l,t=>{o(new Response(t,{headers:a.headers,status:a.status,statusText:a.statusText})),console.log(`%c${e}%c: ${n.size} Processed blob "${l}"`,i,"")}),window.postMessage({source:"blue-marble",endpoint:r,blobID:l,blobData:s,blink:t})}).catch(s=>{const o=Date.now();console.error(`%c${e}%c: Failed to Promise blob!`,i,""),console.groupCollapsed(`%c${e}%c: Details of failed blob Promise:`,i,""),console.log(`Endpoint: ${r}\nThere are ${n.size} blobs processing...\nBlink: ${t.toLocaleString()}\nTime Since Blink: ${String(Math.floor(o/6e4)).padStart(2,"0")}:${String(Math.floor(o/1e3)%60).padStart(2,"0")}.${String(o%1e3).padStart(3,"0")} MM:SS.mmm`),console.error("Exception stack:",s),console.groupEnd()})}return o}});var ft=GM_getResourceText("CSS-BM-File");GM_addStyle(ft);var gt,wt="robotoMonoInjectionPoint";wt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(wt)):((gt=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",gt.rel="preload",gt.as="style",gt.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(gt));var xt=JSON.parse(GM_getValue("bmUserSettings","{}")),yt=(new class{constructor(){this.qe=null,this.Ze=null,this.Qe="#bm-p"}Ke(t){return this.Ze=t,this.qe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.Qe)}),this}ti(){return this.qe}observe(t,e=!1,i=!1){t.observe(this.Ze,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,nt),this.window=null,this.Ct="bm-F",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?this.$t("Main window already exists!"):(this.window=this.H({id:this.Ct,class:"bm-W bm-N",style:"top: 10px; left: unset; right: 75px;"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Blue Marble"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).D().H().D().D().H({class:"bm-m"}).H({class:"bm-L"}).P({class:"bm-T",src:"https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png"},(t,e)=>{const i=new Date;204==Math.floor((i.getTime()-new Date(i.getFullYear(),0,1))/864e5)+1&&(e.parentNode.style.position="relative",e.parentNode.innerHTML=e.parentNode.innerHTML+'',e.onload=()=>{(new L).qt(document.querySelector(`#${this.Ct}`))})}).D().W(1,{textContent:this.name}).D().D().F().D().H({class:"bm-L"}).B({id:"bm-w",textContent:"Droplets:"}).D().V().D().B({id:"bm-q",textContent:"Next level in..."}).D().V().D().B({textContent:"Charges: "}).gt(Date.now(),1e3,{style:"font-weight: 700;"},(t,e)=>{t.p.ei=e.id}).D().D().D().F().D().H({class:"bm-L"}).H({class:"bm-L"}).lt({class:"bm-s bm-J",style:"margin-top: 0;",innerHTML:''},(t,e)=>{e.onclick=()=>{const e=t.p?.ii;e?.[0]?(t.ct("bm-Q",e?.[0]||""),t.ct("bm-R",e?.[1]||""),t.ct("bm-O",e?.[2]||""),t.ct("bm-P",e?.[3]||"")):t.$t("Coordinates are malformed! Did you try clicking on the canvas first?")}}).D().dt({type:"number",id:"bm-Q",class:"bm-C",placeholder:"Tl X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-R",class:"bm-C",placeholder:"Tl Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-O",class:"bm-C",placeholder:"Px X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().dt({type:"number",id:"bm-P",class:"bm-C",placeholder:"Px Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",n=>i(this,nt,st).call(this,t,e,n))}).D().D().H({class:"bm-L"}).ut({class:"bm-K",textContent:"Upload Template",accept:"image/png, image/jpeg, image/webp, image/bmp, image/gif"}).D().D().H({class:"bm-L bm-x"}).lt({textContent:"Disable","data-button-status":"shown"},(t,e)=>{e.onclick=()=>{e.disabled=!0,"shown"==e.dataset.buttonStatus?(t.p?.re?.ni(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.re?.ni(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.Mt("Enabled templates!")),e.disabled=!1}}).D().lt({textContent:"Create"},(t,e)=>{e.onclick=()=>{const e=document.querySelector(`#${this.Ct} .bm-K`),i=document.querySelector("#bm-Q");if(!i.checkValidity())return i.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const n=document.querySelector("#bm-R");if(!n.checkValidity())return n.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const s=document.querySelector("#bm-O");if(!s.checkValidity())return s.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");const o=document.querySelector("#bm-P");if(!o.checkValidity())return o.reportValidity(),void t.$t("Coordinates are malformed! Did you try clicking on the canvas first?");e?.files[0]?(t?.p?.re.We(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(n.value),Number(s.value),Number(o.value)]),t.Mt("Drew to canvas!")):t.$t("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>this.si()}).D().D().H({class:"bm-L"}).bt({id:this.v,placeholder:`Status: Sleeping...\nVersion: ${this.version}`,readOnly:!0}).D().D().H({class:"bm-L bm-x",style:"margin-bottom: 0; flex-direction: column;"}).H({class:"bm-x"}).lt({class:"bm-s",innerHTML:"⚙️",title:"Settings"},(t,e)=>{e.onclick=()=>{t.$.St()}}).D().lt({class:"bm-s",innerHTML:"🧙",title:"Template Wizard"},(t,e)=>{e.onclick=()=>{const e=t.p?.re;new ut(this.name,this.version,e?.schemaVersion,e).St()}}).D().lt({class:"bm-s",innerHTML:"🎨",title:"Template Color Converter"},(t,e)=>{e.onclick=()=>{window.open("https://pepoafonso.github.io/color_converter_wplace/","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",innerHTML:"🌐",title:"Official Blue Marble Website"},(t,e)=>{e.onclick=()=>{window.open("https://bluemarble.lol/","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",title:"Donate to SwingTheVine",innerHTML:''},(t,e)=>{e.onclick=()=>{window.open("https://ko-fi.com/swingthevine","_blank","noopener noreferrer")}}).D().lt({class:"bm-s",innerHTML:"🤝",title:"Credits"},(t,e)=>{e.onclick=()=>{new tt(this.name,this.version).St()}}).D().D().O({textContent:"Made by SwingTheVine",style:"margin-top: auto;"}).D().D().D().D().D().N(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}si(){new et(this).we()}}(bt,pt)),$t=new class{constructor(t,i){e(this,ot),this.name=t,this.version=i,this._e=null,this.$=null,this.schemaVersion="2.0.0",this.oi=null,this.Pe="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.It=1e3,this.Ve=3,this.Ye=3,this.ce=function(t){const e=v;e.unshift({id:-1,premium:!1,name:"Erased",rgb:[222,250,206]}),e.unshift({id:-2,premium:!1,name:"Other",rgb:[0,0,0]});const i=new Map;for(const n of e){if(0==n.id||-2==n.id)continue;const e=n.rgb[0],s=n.rgb[1],o=n.rgb[2];for(let a=-t;a<=t;a++)for(let r=-t;r<=t;r++)for(let l=-t;l<=t;l++){const t=e+a,h=s+r,c=o+l;if(t<0||t>255||h<0||h>255||c<0||c>255)continue;const m=(255<<24|c<<16|h<<8|t)>>>0;i.has(m)||i.set(m,n.id)}}return{palette:e,Yt:i}}(this.Ye),this.Ge=null,this.ai="",this.Le=[],this.Fe=null,this.ri=!0,this.li=null,this.Ne=new Map}hi(t){this._e=t}k(t){this.$=t,i(this,ot,at).call(this)}He(t,e){const n=Number(t);Number.isFinite(n)&&(e?this.Ne.set(n,!0):this.Ne.delete(n),i(this,ot,rt).call(this))}async ci(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async We(t,e,n){this.Fe||(this.Fe=await this.ci(),console.log("Creating JSON...")),this._e.Mt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Ht:0,Lt:m(this.oi||0,this.Pe),file:t,coords:n}),o=!this.$?.Nt?.flags?.includes("hl-noSkip"),a=this.$?.Nt?.flags?.includes("hl-agSkip");console.log(`Should Skip: ${o}; Should Agg Skip: ${a}`);const{Rt:r,Et:l}=await s.Wt(this.It,this.ce,o,a);s.Ot=r;const h={total:s.At.total,colors:Object.fromEntries(s.At.colors)};this.Fe.templates[`${s.Ht} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.Le=[],this.Le.push(s),this._e.Mt(`Template created at ${n.join(", ")}!`),console.log(Object.keys(this.Fe.templates).length),console.log(this.Fe),console.log(this.Le),console.log(JSON.stringify(this.Fe)),await i(this,ot,lt).call(this)}mi(){}async di(){this.Fe||(this.Fe=await this.ci(),console.log("Creating JSON..."))}async ui(){l("Downloading all templates..."),console.log(this.Le);for(const t of this.Le)await this.bi(t),await n(500)}async Ae(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(console.log(t),Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.bi(new H({displayName:i.name,Ht:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ot:i.tiles})),await n(500))}async bi(t){t.jt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.ze(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",pi:"uniquify",onload:()=>{l(`Download of template '${e}' complete!`)},onerror:(t,i)=>{h(`Download of template '${e}' failed because ${t}! Details: ${i}`)},ontimeout:()=>{c(`Download of template '${e}' has timed out!`)}})}async ze(t){console.log(t);const e=t.Ot,i=Object.keys(e).sort(),n=await Promise.all(i.map(t=>{return i=e[t],new Promise((t,e)=>{const n=new Image;n.onload=()=>t(n),n.onerror=e,n.src="data:image/png;base64,"+i});var i}));let s=1/0,o=1/0,a=0,r=0;i.forEach((t,e)=>{const[i,l,h,c]=t.split(",").map(Number),m=n[e],d=i*this.It+h,u=l*this.It+c;s=Math.min(s,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.Ve),r=Math.max(r,u+m.height/this.Ve)}),console.log(`Absolute coordinates: (${s}, ${o}) and (${a}, ${r})`);const l=a-s,h=r-o,c=l*this.Ve,m=h*this.Ve;console.log(`Template Width: ${l}\nTemplate Height: ${h}\nCanvas Width: ${c}\nCanvas Height: ${m}`);const d=new OffscreenCanvas(c,m),u=d.getContext("2d");i.forEach((t,e)=>{const[i,a,r,l]=t.split(",").map(Number),h=n[e],c=i*this.It+r,m=a*this.It+l;console.log(`Drawing tile (${i}, ${a}, ${r}, ${l}) (${c}, ${m}) at (${c-s}, ${m-o}) on the canvas...`),u.drawImage(h,(c-s)*this.Ve,(m-o)*this.Ve,h.width,h.height)}),u.globalCompositeOperation="destination-over",u.drawImage(d,0,-1),u.drawImage(d,0,1),u.drawImage(d,-1,0),u.drawImage(d,1,0);const b=new OffscreenCanvas(l,h),p=b.getContext("2d");return p.imageSmoothingEnabled=!1,p.drawImage(d,0,0,l*this.Ve,h*this.Ve,0,0,l,h),b.convertToBlob({type:"image/png"})}async fi(t,e){if(!this.ri)return t;const n=this.It*this.Ve;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.Le;console.log(o),o.sort((t,e)=>t.Ht-e.Ht),console.log(o);const a=o.map(t=>{const i=Object.keys(t.Ot).filter(t=>t.startsWith(e));if(0===i.length)return null;const n=i.map(e=>{const i=e.split(",");return{gi:t,Vt:t.Ot[e],Bt:t.Bt?.[e],wi:[i[0],i[1]],xi:[i[2],i[3]]}});return n?.[0]}).filter(Boolean);console.log(a);const r=a?.length||0;if(console.log(`templateCount = ${r}`),!(r>0))return this._e.Mt(`Sleeping\nVersion: ${this.version}`),t;{const t=s(o.filter(t=>Object.keys(t.Ot).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.At.total||0),0));this._e.Mt(`Displaying ${r} template${1==r?"":"s"}.\nTotal pixels: ${t}`)}const l=await createImageBitmap(t),h=new OffscreenCanvas(n,n),c=h.getContext("2d");c.imageSmoothingEnabled=!1,c.beginPath(),c.rect(0,0,n,n),c.clip(),c.clearRect(0,0,n,n),c.drawImage(l,0,0,n,n);const m=c.getImageData(0,0,n,n),d=new Uint32Array(m.data.buffer),u=this.$?.Nt?.highlight||[[2,0,0]],b=u?.[0],p=1==u?.length&&2==b?.[0]&&0==b?.[1]&&0==b?.[2];for(const t of a){console.log("Template:"),console.log(t);const n=!!t.gi.At?.colors?.get(-1);let s=t.Bt.slice();const o=Number(t.xi[0])*this.Ve,a=Number(t.xi[1])*this.Ve;if(0!=this.Ne.size||n||c.drawImage(t.Vt,o,a),!s){const e=c.getImageData(o,a,t.Vt.width,t.Vt.height);s=new Uint32Array(e.data.buffer)}const r=Date.now(),{Je:l,Xe:h}=i(this,ot,ct).call(this,{Ue:d,Ge:s,Re:[o,a,t.Vt.width,t.Vt.height],Ee:u,je:p});let m=0;const b=0;for(const[t,e]of l)t!=b&&(m+=e);0==this.Ne.size&&!n&&p||(console.log("Colors to filter: ",this.Ne),c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(h.buffer),t.Vt.width,t.Vt.height)),o,a)),console.log(`Finished calculating correct pixels & filtering colors for the tile ${e} in ${(Date.now()-r)/1e3} seconds!\nThere are ${m} correct pixels.`),void 0===t.gi.At.correct&&(t.gi.At.correct={}),t.gi.At.correct[e]=l}return await h.convertToBlob({type:"image/png"})}async yi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&await i(this,ot,ht).call(this,t)}ni(t){this.ri=t}}(bt,pt),vt=new class{constructor(t){this.re=t,this.$i=!1,this.ei="",this.ii=[],this.Mi=[]}Ci(t){window.addEventListener("message",async e=>{const i=e.data,n=i.jsonData;if(!i||"blue-marble"!==i.source)return;if(!i.endpoint)return;const o=i.endpoint?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();switch(console.log('%cBlue Marble%c: Recieved message about "%s"',"color: cornflowerblue;","",o),o){case"me":if(n.status&&"2"!=n.status?.toString()[0])return void t.$t("You are not logged in or Wplace is offline!\nCould not fetch userdata.");const e=Math.ceil(Math.pow(Math.floor(n.level)*Math.pow(30,.65),1/.65)-n.pixelsPainted);if(console.log(n.id),(n.id||0===n.id)&&console.log(m(n.id,"!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~")),this.re.oi=n.id,0!=this.ei.length){const t=document.querySelector("#"+this.ei);if(t){const e=n.charges;t.dataset.endDate=Date.now()+(e.max-e.count)*e.cooldownMs}}t.ct("bm-w",`Droplets: ${s(n.droplets)}`),t.ct("bm-q",`Next level in ${s(e)} pixel${1==e?"":"s"}`);break;case"pixel":const o=i.endpoint.split("?")[0].split("/").filter(t=>t&&!isNaN(Number(t))),l=new URLSearchParams(i.endpoint.split("?")[1]),h=[l.get("x"),l.get("y")];if(this.ii.length&&(!o.length||!h.length))return void t.$t("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ii=[...o,...h];const c=(a=o,r=h,[parseInt(a[0])%4*1e3+parseInt(r[0]),parseInt(a[1])%4*1e3+parseInt(r[1])]),d=document.querySelectorAll("span");for(const t of d){const e=t.textContent.trim();if(e.includes(c[0])&&e.includes(c[1])){let e=document.querySelector("#bm-p");o[0],o[1],h[0],h[1];const i=["Tl X:","Tl Y:","Px X:","Px Y:"],n=["bm-Y","bm-Z","bm-U","bm-V"],s=[...o,...h];if(e)for(const[t,e]of n.entries())document.getElementById(e).textContent=`${i[t]??"??:"} ${s[t]}`;else{e=document.createElement("span"),e.id="bm-p",e.style="display: flex; flex-wrap: wrap; gap: 0 1ch; font-size: small;";for(const[t,o]of s.entries()){const a=document.createElement("span");a.id=n[s.indexOf(o)??""],a.textContent=`${i[t]??"??:"} ${o}`,e.appendChild(a)}t.parentNode.parentNode.parentNode.insertAdjacentElement("afterend",e)}}}break;case"tile":case"tiles":let u=i.endpoint.split("/");u=[parseInt(u[u.length-2]),parseInt(u[u.length-1].replace(".png",""))];const b=i.blobID,p=i.blobData,f=Date.now(),g=await this.re.fi(p,u);console.log(`Finished loading the tile in ${(Date.now()-f)/1e3} seconds!`),window.postMessage({source:"blue-marble",blobID:b,blobData:g,blink:i.blink});break;case"robots":this.$i="false"==n.userscript?.toString().toLowerCase();break}var a,r})}async Ti(t){console.log("Sending heartbeat to telemetry server...");let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return void console.log("Telemetry is disabled, not sending heartbeat.");const i=navigator.userAgent;let n=await this.Si(i),s=this.ki(i);GM_xmlhttpRequest({method:"POST",url:"https://telemetry.thebluecorner.net/heartbeat",headers:{"Content-Type":"application/json"},data:JSON.stringify({uuid:e.uuid,version:t,browser:n,os:s}),onload:t=>{200!==t.status&&h("Failed to send heartbeat:",t.statusText)},onerror:t=>{h("Error sending heartbeat:",t)}})}async Si(t=navigator.userAgent){return(t=t||"").includes("OPR/")||t.includes("Opera")?"Opera":t.includes("Edg/")?"Edge":t.includes("Vivaldi")?"Vivaldi":t.includes("YaBrowser")?"Yandex":t.includes("Kiwi")?"Kiwi":t.includes("Brave")?"Brave":t.includes("Firefox/")?"Firefox":t.includes("Chrome/")?"Chrome":t.includes("Safari/")?"Safari":navigator.brave&&"function"==typeof navigator.brave.isBrave&&await navigator.brave.isBrave()?"Brave":"Unknown"}ki(t=navigator.userAgent){return/Windows NT 11/i.test(t=t||"")?"Windows 11":/Windows NT 10/i.test(t)?"Windows 10":/Windows NT 6\.3/i.test(t)?"Windows 8.1":/Windows NT 6\.2/i.test(t)?"Windows 8":/Windows NT 6\.1/i.test(t)?"Windows 7":/Windows NT 6\.0/i.test(t)?"Windows Vista":/Windows NT 5\.1|Windows XP/i.test(t)?"Windows XP":/Mac OS X 10[_\.]15/i.test(t)?"macOS Catalina":/Mac OS X 10[_\.]14/i.test(t)?"macOS Mojave":/Mac OS X 10[_\.]13/i.test(t)?"macOS High Sierra":/Mac OS X 10[_\.]12/i.test(t)?"macOS Sierra":/Mac OS X 10[_\.]11/i.test(t)?"OS X El Capitan":/Mac OS X 10[_\.]10/i.test(t)?"OS X Yosemite":/Mac OS X 10[_\.]/i.test(t)?"macOS":/Android/i.test(t)?"Android":/iPhone|iPad|iPod/i.test(t)?"iOS":/Linux/i.test(t)?"Linux":"Unknown"}}($t),Mt=new class extends N{constructor(t,i,n){var s;super(t,i),e(this,C),this.Nt=n,(s=this.Nt).flags??(s.flags=[]),this.Di=structuredClone(this.Nt),this.Ni="bmUserSettings",this.Hi=5e3,this.Li=0,setInterval(this.Oi.bind(this),this.Hi)}async Oi(){await this.Bi()}async Bi(t=!1){const e=JSON.stringify(this.Nt);e!=JSON.stringify(this.Di)&&(t||Date.now()-this.Li>this.Hi)&&(await GM.setValue(this.Ni,e),this.Di=structuredClone(this.Nt),this.Li=Date.now(),console.log(e))}async De(){await this.Bi(!0)}ke(t,e=void 0){const i=this.Nt?.flags?.indexOf(t)??-1;-1!=i&&!0!==e?this.Nt?.flags?.splice(i,1):-1==i&&!1!==e&&this.Nt?.flags?.push(t)}kt(){const t='',e='',n=this.Nt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().F().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.Nt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.ke("hl-noTrans",!t.target.checked)}).D().L({id:"bm-4",textContent:"Choose a preset:",style:"font-weight: 700;"}).D().H({class:"bm-D",role:"group","aria-labelledby":"bm-4"}).H({class:"bm-3"}).B({textContent:"None"}).D().lt({innerHTML:t,"aria-label":'Preset "None"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"None")}).D().D().H({class:"bm-3"}).B({textContent:"Cross"}).D().lt({innerHTML:e,"aria-label":'Preset "Cross Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Cross")}).D().D().H({class:"bm-3"}).B({textContent:"X"}).D().lt({innerHTML:e.replace('d="M1,0H2V1H3V2H2V3H1V2H0V1H1Z"','d="M0,0V1H3V0H2V3H3V2H0V3H1V0Z"'),"aria-label":'Preset "X Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"X")}).D().D().H({class:"bm-3"}).B({textContent:"Full"}).D().lt({innerHTML:t.replace("#fff","#2f4f4f"),"aria-label":'Preset "Full Template"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Full")}).D().D().D().L({id:"bm-b",textContent:"Create a custom pattern:",style:"font-weight: 700;"}).D().H({class:"bm-n",role:"group","aria-labelledby":"bm-b"});for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){const s=n[n.findIndex(([,i,n])=>i==e&&n==t)]?.[0]??0;let o="Disabled";1==s?o="Incorrect":2==s&&(o="Template"),this.window=this.lt({"data-status":o,"aria-label":`Sub-pixel ${o.toLowerCase()}`},(n,s)=>{s.onclick=()=>i(this,C,T).call(this,s,[e,t])}).D()}this.window=this.D().D().D()}Dt(){this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().F().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.Nt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.ke("hl-noSkip",!t.target.checked)}).D().R({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.Nt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.ke("hl-agSkip",t.target.checked)}).D().D().D()}}(bt,pt,xt);yt.k(Mt),yt.S(vt),$t.hi(yt),$t.k(Mt);var Ct=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(Ct),console.log(xt),console.log(Object.keys(xt).length),0==Object.keys(xt).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>vt.Ti(pt),18e5);var Tt=xt?.telemetry;if(console.log(`Telemetry is ${!(null==Tt)}`),null==Tt||Tt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,mt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Ii=n,this.uuid=s}async St(){if(document.querySelector(`#${this.Ct}`))return void this.$t("Telemetry window already exists!");const t=await this.p.Si(navigator.userAgent),e=this.p.ki(navigator.userAgent);this.window=this.H({id:this.Ct,class:"bm-W",style:"height: 80vh; z-index: 9998;"}).H({class:"bm-m"}).H({class:"bm-L bm-h"}).W(1,{textContent:`${this.name} Telemetry`}).D().D().F().D().H({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,mt,dt).call(this,this.Ii);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,mt,dt).call(this,0);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"More Information"},(t,e)=>{e.onclick=()=>{window.open("https://github.com/SwingTheVine/Wplace-TelemetryServer#telemetry-data","_blank","noopener noreferrer")}}).D().D().H({class:"bm-L bm-H"}).H({class:"bm-L"}).W(2,{textContent:"Legal"}).D().L({textContent:`We collect anonymous telemetry data such as your browser, OS, and script version to make the experience better for everyone. The data is never shared personally. The data is never sold. You can turn this off by pressing the "Disable" button, but keeping it on helps us improve features and reliability faster. Thank you for supporting ${this.name}!`}).D().D().F().D().H({class:"bm-L"}).W(2,{textContent:"Non-Legal Summary"}).D().L({innerHTML:'You can disable telemetry by pressing the "Disable" button. If you would like to read more about what information we collect, press the "More Information" button.
This is the data stored on our servers:'}).D().X().Z({innerHTML:`A unique identifier (UUIDv4) generated by Blue Marble. This enables our telemetry to function without tracking your actual user ID.
Your UUID is: ${r(this.uuid)}`}).D().Z({innerHTML:`The version of Blue Marble you are using.
Your version is: ${r(this.version)}`}).D().Z({innerHTML:`Your browser type, which is used to determine Blue Marble outages and browser popularity.
Your browser type is: ${r(t)}`}).D().Z({innerHTML:`Your OS type, which is used to determine Blue Marble outages and OS popularity.
Your OS type is: ${r(e)}`}).D().Z({innerHTML:"The date and time that Blue Marble sent the telemetry information."}).D().D().L({innerHTML:'All of the data mentioned above is aggregated every hour. This means every hour, anything that could even remotly be considered "personal data" is deleted from our server. Here, "aggregated" data means things like "42 people used Blue Marble on Google Chrome this hour", which can\'t be used to identify anyone in particular.'}).D().D().D().D().D().N(this.Tt)}}(bt,pt,1,xt?.uuid);t.S(vt),t.St()}!async function(){await $t.yi(Ct),yt.St(),yt.si(),vt.Ci(yt),new MutationObserver((t,e)=>{const i=document.querySelector("#color-1");if(!i)return;let n=document.querySelector("#bm-G");if(!n){n=document.createElement("button"),n.id="bm-G",n.textContent="Move ↑",n.className="btn btn-soft",n.onclick=function(){const t=this.parentNode.parentNode.parentNode.parentNode,e="Move ↑"==this.textContent;t.parentNode.className=t.parentNode.className.replace(e?"bottom":"top",e?"top":"bottom"),t.style.borderTopLeftRadius=e?"0px":"var(--radius-box)",t.style.borderTopRightRadius=e?"0px":"var(--radius-box)",t.style.borderBottomLeftRadius=e?"var(--radius-box)":"0px",t.style.borderBottomRightRadius=e?"var(--radius-box)":"0px",this.textContent=e?"Move ↓":"Move ↑"};const t=i.parentNode.parentNode.parentNode.parentNode.querySelector("h2");t.parentNode?.appendChild(n)}}).observe(document.body,{childList:!0,subtree:!0}),l(`%c${bt}%c (${pt}) userscript has loaded!`,"color: cornflowerblue;","")}()})(); +(()=>{var t=t=>{throw TypeError(t)},e=(e,i,s)=>i.has(e)?t("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(e):i.set(e,s),i=(e,i,s)=>(((e,i)=>{i.has(e)||t("Cannot access private method")})(e,i),s);function s(t){return new Promise(e=>setTimeout(e,t))}function n(t){return(new Intl.NumberFormat).format(t)}function o(t){return new Intl.NumberFormat(void 0,{style:"percent",t:2,i:2}).format(t)}function a(t){return t.toLocaleString(void 0,{o:"long",l:"numeric",h:"2-digit",m:"2-digit",u:"2-digit"})}function r(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}function l(...t){(0,console.log)(...t)}function h(...t){(0,console.error)(...t)}function c(...t){(0,console.warn)(...t)}function m(t,e){if(0===t)return e[0];let i="";const s=e.length;for(;t>0;)i=e[t%s]+i,t=Math.floor(t/s);return i}function d(t,e){let i=0;const s=e.length;for(const n of t){const t=e.indexOf(n);-1==t&&h(`Invalid character '${n}' encountered whilst decoding! Is the decode alphabet/base incorrect?`),i=i*s+t}return i}function u(t){let e="";for(let i=0;i(t/=255)<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*e[0]+.7152*e[1]+.0722*e[2]}function f(t,e,i){return Array.isArray(t)&&([t,e,i]=t),(1<<24|t<<16|e<<8|i).toString(16).slice(1)}var g,w,x,$,y,v=[{id:0,premium:!1,name:"Transparent",rgb:[0,0,0]},{id:1,premium:!1,name:"Black",rgb:[0,0,0]},{id:2,premium:!1,name:"Dark Gray",rgb:[60,60,60]},{id:3,premium:!1,name:"Gray",rgb:[120,120,120]},{id:4,premium:!1,name:"Light Gray",rgb:[210,210,210]},{id:5,premium:!1,name:"White",rgb:[255,255,255]},{id:6,premium:!1,name:"Deep Red",rgb:[96,0,24]},{id:7,premium:!1,name:"Red",rgb:[237,28,36]},{id:8,premium:!1,name:"Orange",rgb:[255,127,39]},{id:9,premium:!1,name:"Gold",rgb:[246,170,9]},{id:10,premium:!1,name:"Yellow",rgb:[249,221,59]},{id:11,premium:!1,name:"Light Yellow",rgb:[255,250,188]},{id:12,premium:!1,name:"Dark Green",rgb:[14,185,104]},{id:13,premium:!1,name:"Green",rgb:[19,230,123]},{id:14,premium:!1,name:"Light Green",rgb:[135,255,94]},{id:15,premium:!1,name:"Dark Teal",rgb:[12,129,110]},{id:16,premium:!1,name:"Teal",rgb:[16,174,166]},{id:17,premium:!1,name:"Light Teal",rgb:[19,225,190]},{id:18,premium:!1,name:"Dark Blue",rgb:[40,80,158]},{id:19,premium:!1,name:"Blue",rgb:[64,147,228]},{id:20,premium:!1,name:"Cyan",rgb:[96,247,242]},{id:21,premium:!1,name:"Indigo",rgb:[107,80,246]},{id:22,premium:!1,name:"Light Indigo",rgb:[153,177,251]},{id:23,premium:!1,name:"Dark Purple",rgb:[120,12,153]},{id:24,premium:!1,name:"Purple",rgb:[170,56,185]},{id:25,premium:!1,name:"Light Purple",rgb:[224,159,249]},{id:26,premium:!1,name:"Dark Pink",rgb:[203,0,122]},{id:27,premium:!1,name:"Pink",rgb:[236,31,128]},{id:28,premium:!1,name:"Light Pink",rgb:[243,141,169]},{id:29,premium:!1,name:"Dark Brown",rgb:[104,70,52]},{id:30,premium:!1,name:"Brown",rgb:[149,104,42]},{id:31,premium:!1,name:"Beige",rgb:[248,178,119]},{id:32,premium:!0,name:"Medium Gray",rgb:[170,170,170]},{id:33,premium:!0,name:"Dark Red",rgb:[165,14,30]},{id:34,premium:!0,name:"Light Red",rgb:[250,128,114]},{id:35,premium:!0,name:"Dark Orange",rgb:[228,92,26]},{id:36,premium:!0,name:"Light Tan",rgb:[214,181,148]},{id:37,premium:!0,name:"Dark Goldenrod",rgb:[156,132,49]},{id:38,premium:!0,name:"Goldenrod",rgb:[197,173,49]},{id:39,premium:!0,name:"Light Goldenrod",rgb:[232,212,95]},{id:40,premium:!0,name:"Dark Olive",rgb:[74,107,58]},{id:41,premium:!0,name:"Olive",rgb:[90,148,74]},{id:42,premium:!0,name:"Light Olive",rgb:[132,197,115]},{id:43,premium:!0,name:"Dark Cyan",rgb:[15,121,159]},{id:44,premium:!0,name:"Light Cyan",rgb:[187,250,242]},{id:45,premium:!0,name:"Light Blue",rgb:[125,199,255]},{id:46,premium:!0,name:"Dark Indigo",rgb:[77,49,184]},{id:47,premium:!0,name:"Dark Slate Blue",rgb:[74,66,132]},{id:48,premium:!0,name:"Slate Blue",rgb:[122,113,196]},{id:49,premium:!0,name:"Light Slate Blue",rgb:[181,174,241]},{id:50,premium:!0,name:"Light Brown",rgb:[219,164,99]},{id:51,premium:!0,name:"Dark Beige",rgb:[209,128,81]},{id:52,premium:!0,name:"Light Beige",rgb:[255,197,165]},{id:53,premium:!0,name:"Dark Peach",rgb:[155,82,73]},{id:54,premium:!0,name:"Peach",rgb:[209,128,120]},{id:55,premium:!0,name:"Light Peach",rgb:[250,182,164]},{id:56,premium:!0,name:"Dark Tan",rgb:[123,99,82]},{id:57,premium:!0,name:"Tan",rgb:[156,132,107]},{id:58,premium:!0,name:"Dark Slate",rgb:[51,57,65]},{id:59,premium:!0,name:"Slate",rgb:[109,117,141]},{id:60,premium:!0,name:"Light Slate",rgb:[179,185,209]},{id:61,premium:!0,name:"Dark Stone",rgb:[109,100,63]},{id:62,premium:!0,name:"Stone",rgb:[148,140,107]},{id:63,premium:!0,name:"Light Stone",rgb:[205,197,158]}],M=class{constructor(t,i){e(this,g),this.name=t,this.version=i,this.p=null,this.$=null,this.v="bm-r",this.M=null,this.C=null,this.T=[]}S(t){this.p=t}D(t){this.$=t}N(){return this.T.length>0&&(this.C=this.T.pop()),this}k(t){t?.appendChild(this.M),this.M=null,this.C=null,this.T=[]}O(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}L(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"p",{},t)),this}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"small",{},t)),this}I(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"span",{},t)),this}B(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"details",{},t)),this}P(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"summary",{},t)),this}A(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"img",{},t)),this}F(t,e={},s=()=>{}){return s(this,i(this,g,w).call(this,"h"+t,{},e)),this}W(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}U(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"form",{},t)),this}G(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"fieldset",{},t)),this}R(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"legend",{},t)),this}j(t={},e=()=>{}){const s={};t.textContent?(s.textContent=t.textContent,delete t.textContent):t.innerHTML&&(s.innerHTML=t.innerHTML,delete t.textContent);const n=i(this,g,w).call(this,"label",s),o=i(this,g,w).call(this,"input",{type:"checkbox"},t);return n.insertBefore(o,n.firstChild),this.N(),e(this,n,o),this}Y(t={},e=()=>{}){const s=i(this,g,w).call(this,"label",{textContent:t.textContent??"",for:t.id??""});return delete t.textContent,this.N(),e(this,s,i(this,g,w).call(this,"select",{},t)),this}J(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"option",{},t)),this}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ul",{},t)),this}q(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"menu",{},t)),this}Z(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"li",{},t)),this}K(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"table",{},t)),this}tt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"caption",{},t)),this}et(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"thead",{},t)),this}it(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tbody",{},t)),this}st(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tfoot",{},t)),this}nt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"tr",{},t)),this}ot(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"th",{},t)),this}rt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"td",{},t)),this}lt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"button",{},t)),this}ht(t={},e=()=>{}){const s=t.title??t.textContent??"Help: No info";delete t.textContent,t.title=`Help: ${s}`;const n={textContent:"?",className:"bm-10",onclick:()=>{this.ct(this.v,s)}};return e(this,i(this,g,w).call(this,"button",n,t)),this}dt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"input",{},t)),this}ut(t={},e=()=>{}){const s=t.textContent??"";delete t.textContent;const n=i(this,g,w).call(this,"div"),o=i(this,g,w).call(this,"input",{type:"file",tabindex:"-1","aria-hidden":"true"},t);this.N();const a=i(this,g,w).call(this,"button",{textContent:s});return this.N(),this.N(),a.addEventListener("click",()=>{o.click()}),o.addEventListener("change",()=>{a.style.maxWidth=`${a.offsetWidth}px`,o.files.length>0?a.textContent=o.files[0].name:a.textContent=s}),e(this,n,o,a),this}bt(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"textarea",{},t)),this}ft(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{class:"bm-S"},t)),this}gt(t=Date.now(),e=500,s={},n=()=>{}){const o="bm--",a=s?.id||o+"-"+crypto.randomUUID().slice(0,8),r={class:o},l=i(this,g,w).call(this,"time",r,s);return l.id=a,l.dataset.endDate=t,setInterval(()=>{if(!l.isConnected)return;const t=Math.max(l.dataset.endDate-Date.now(),0),e=Math.floor(t/1e3),i=Math.floor(e/3600),s=Math.floor(e%60),n=Math.floor(e%3600/60);l.setAttribute("datetime",`PT${i}H${n}M${s}S`),l.textContent=String(i).padStart(2,"0")+":"+String(n).padStart(2,"0")+":"+String(s).padStart(2,"0")},e),n(this,l),this}ct(t,e,i=!1){const s=document.getElementById(t.replace(/^#/,""));s&&(s instanceof HTMLInputElement?s.value=e:i?s.textContent=e:s.innerHTML=e)}wt(t){if(t.disabled)return;t.disabled=!0,t.style.textDecoration="none";const e=t.closest(".bm-W"),i=t.closest(".bm-S"),s=e.querySelector("h1"),n=e.querySelector(".bm-m");if(e.parentElement.append(e),"expanded"==t.dataset.buttonStatus){n.style.height=n.scrollHeight+"px",e.style.width=e.scrollWidth+"px",n.style.height="0",n.addEventListener("transitionend",function e(){n.style.display="none",t.disabled=!1,t.style.textDecoration="",n.removeEventListener("transitionend",e)});const i=s.cloneNode(!0),o=i.textContent;t.nextElementSibling.appendChild(i),t.textContent="▶",t.dataset.buttonStatus="collapsed",t.ariaLabel=`Unminimize window "${o}"`}else{const s=i.querySelector("h1"),o=s.textContent;s.remove(),n.style.display="",n.style.height="0",e.style.width="",n.style.height=n.scrollHeight+"px",n.addEventListener("transitionend",function e(){n.style.height="",t.disabled=!1,t.style.textDecoration="",n.removeEventListener("transitionend",e)}),t.textContent="▼",t.dataset.buttonStatus="expanded",t.ariaLabel=`Minimize window "${o}"`}}xt(t,e,i={}){const s=document.querySelector(t),n=document.querySelector(e),o=i?.$t??(()=>{});if(!s||!n)return void this.yt(`Can not drag! ${s?"":"moveMe"} ${s||n?"":"and "}${n?"":"iMoveThings "}was not found!`);let a,r=!1,l=0,h=null,c=0,m=0,d=0,u=0,b=null;const p=()=>{if(r){const t=Math.abs(c-d),e=Math.abs(m-u);(t>.5||e>.5)&&(c=d,m=u,s.style.transform=`translate(${c}px, ${m}px)`,s.style.left="0px",s.style.top="0px",s.style.right=""),h=requestAnimationFrame(p)}},f=(t,e)=>{r=!0,b=s.getBoundingClientRect(),a=t-b.left,l=e-b.top;const i=window.getComputedStyle(s).transform;if(i&&"none"!==i){const t=new DOMMatrix(i);c=t.m41,m=t.m42}else c=b.left,m=b.top;d=c,u=m,document.body.style.userSelect="none",n.classList.add("bm-M"),document.addEventListener("mousemove",w),document.addEventListener("touchmove",x,{passive:!1}),document.addEventListener("mouseup",g),document.addEventListener("touchend",g),document.addEventListener("touchcancel",g),h&&cancelAnimationFrame(h),p()},g=()=>{r=!1,h&&(cancelAnimationFrame(h),h=null),document.body.style.userSelect="",n.classList.remove("bm-M"),document.removeEventListener("mousemove",w),document.removeEventListener("touchmove",x),document.removeEventListener("mouseup",g),document.removeEventListener("touchend",g),document.removeEventListener("touchcancel",g),o({element:s,x:c,y:m}),b=null},w=t=>{r&&b&&(d=t.clientX-a,u=t.clientY-l)},x=t=>{if(r&&b){const e=t.touches[0];if(!e)return;d=e.clientX-a,u=e.clientY-l,t.preventDefault()}};n.addEventListener("mousedown",function(t){t.preventDefault(),f(t.clientX,t.clientY)}),n.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(f(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t,e,i={}){const s=document.querySelector(t),n=document.querySelector(e),o=i?.$t??(()=>{});if(!s||!n)return void this.yt(`Can not resize! ${s?"":"resizeMe"} ${s||n?"":"and "}${n?"":"iResizeThings "}was not found!`);let a=!1,r=0,l=0,h=0,c=0,m=0,d=0,u=0,b=0,p=null;const f=()=>Number.isFinite(i?.maxWidth)?i.maxWidth:window.innerWidth-16,g=()=>Number.isFinite(i?.maxHeight)?i.maxHeight:window.innerHeight-16,w=Number.isFinite(i?.minWidth)?i.minWidth:200,x=Number.isFinite(i?.minHeight)?i.minHeight:160,$=(t,e,i)=>Math.min(Math.max(t,e),Math.max(e,i)),y=()=>{if(a){const t=Math.abs(m-u),e=Math.abs(d-b);(t>.5||e>.5)&&(m=u,d=b,s.style.width=`${m}px`,s.style.height=`${d}px`),p=requestAnimationFrame(y)}},v=(t,e)=>{a=!0,r=t,l=e,h=s.offsetWidth,c=s.offsetHeight,m=h,d=c,u=h,b=c,document.body.style.userSelect="none",n.classList.add("bm-2b"),document.addEventListener("mousemove",C),document.addEventListener("touchmove",T,{passive:!1}),document.addEventListener("mouseup",M),document.addEventListener("touchend",M),document.addEventListener("touchcancel",M),p&&cancelAnimationFrame(p),y()},M=()=>{a=!1,p&&(cancelAnimationFrame(p),p=null),document.body.style.userSelect="",n.classList.remove("bm-2b"),document.removeEventListener("mousemove",C),document.removeEventListener("touchmove",T),document.removeEventListener("mouseup",M),document.removeEventListener("touchend",M),document.removeEventListener("touchcancel",M),o({element:s,width:m,height:d})},C=t=>{a&&(u=$(h+(t.clientX-r),w,f()),b=$(c+(t.clientY-l),x,g()))},T=t=>{if(!a)return;const e=t?.touches?.[0];e&&(u=$(h+(e.clientX-r),w,f()),b=$(c+(e.clientY-l),x,g()),t.preventDefault())};n.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),v(t.clientX,t.clientY)}),n.addEventListener("touchstart",t=>{const e=t?.touches?.[0];e&&(t.preventDefault(),t.stopPropagation(),v(e.clientX,e.clientY))},{passive:!1})}Mt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.v,"Status: "+t,!0)}yt(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.v,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},s={}){const n=document.createElement(t);this.M?(this.C?.appendChild(n),this.T.push(this.C),this.C=n):(this.M=n,this.C=n);for(const[t,s]of Object.entries(e))i(this,g,x).call(this,n,t,s);for(const[t,e]of Object.entries(s))i(this,g,x).call(this,n,t,e);return n},x=function(t,e,i){"class"==e?t.classList.add(...i.split(/\s+/)):"for"==e?t.htmlFor=i:"tabindex"==e?t.tabIndex=Number(i):"readonly"==e?t.readOnly="true"==i||"1"==i:"maxlength"==e?t.maxLength=Number(i):e.startsWith("data")?t.dataset[e.slice(5).split("-").map((t,e)=>0==e?t:t[0].toUpperCase()+t.slice(1)).join("")]=i:e.startsWith("aria")?t.setAttribute(e,i):t[e]=i};var C,T,S,D,N,k=class extends M{constructor(t,i){super(t,i),e(this,$),this.window=null,this.Ct="bm-l",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?document.querySelector(`#${this.Ct}`).remove():(this.window=this.O({id:this.Ct,class:"bm-W"}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Settings"}).N().N().W().N().L({textContent:"Settings take 5 seconds to save."}).N().O({class:"bm-L bm-H"},(t,e)=>{this.Dt(),this.Nt()}).N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}Dt(){i(this,$,y).call(this,"Pixel Highlight")}Nt(){i(this,$,y).call(this,"Template")}};$=new WeakSet,y=function(t){this.window=this.O({class:"bm-L"}).F(2,{textContent:t}).N().W().N().L({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).N().N()},C=new WeakSet,T=function(t,e){t.disabled=!0;const i=t.dataset.status,s=this.kt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];let n=[2,0,0];const o=s;switch(i){case"Disabled":t.dataset.status="Incorrect",t.ariaLabel="Sub-pixel incorrect",n=[1,...e];break;case"Incorrect":t.dataset.status="Template",t.ariaLabel="Sub-pixel template",n=[2,...e];break;case"Template":t.dataset.status="Disabled",t.ariaLabel="Sub-pixel disabled",n=[0,...e];break}const a=s.findIndex(([,t,e])=>t==n[1]&&e==n[2]);0!=n[0]?-1!=a?o[a]=n:o.push(n):-1!=a&&o.splice(a,1),this.kt.highlight=o,t.disabled=!1},S=async function(t){const e=document.querySelectorAll(".bm-3 button");for(const t of e)t.disabled=!0;let i=[0,0,0,0,2,0,0,0,0];switch(t){case"Cross":i=[0,1,0,1,2,1,0,1,0];break;case"X":i=[1,0,1,0,2,0,1,0,1];break;case"Full":i=[2,2,2,2,2,2,2,2,2];break}const n=document.querySelector(".bm-n")?.childNodes??[];for(let t=0;t{const[s,n,o,a]=e.split(",").map(Number);(n>>24==0?0:n.get(e)??-2;const a=o.get(s);o.set(s,a?a+1:1)}return console.log(o),o};var L,H,I,B,P,A,z,F,W,U,V,G,R,j,E,Y,J,X,_,q=class{constructor(){this.Xt=Math.ceil(80/1300*window.innerWidth),this._t=v.slice(1)}qt(t){const e=document.createElement("div");for(let t=0;t{t.parentNode.childElementCount<=1?t.parentNode.remove():t.remove()},e.appendChild(t)}t.appendChild(e)}},Z=class extends HTMLElement{};customElements.define("confetti-piece",Z);var Q,K,tt,et,it,st,nt=class extends M{constructor(t){super(t.name,t.version),e(this,L),this.window=null,this.Ct="bm-t",this.Zt="bm-E",this.Tt=document.body,this.$=t.$??null,this.Qt="ftr-oWin",this.Kt="windowFilter",this.te=null,this.ee=null,this.ie=null,this.se=null,this.ne=1e4,this.oe=260,this.ae=220,this.re=1e3,this.le=1400,this.he=t.p?.he,this.ce='',this.me='';const{palette:i,Jt:s}=this.he.de;this.palette=i,this.ue=0,this.be=0,this.pe=new Map,this.fe=new Map,this.ge=0,this.we=0,this.timeRemaining=0,this.xe="",this.sortPrimary="total",this.sortSecondary="descending",this.showUnused=!1}$e(){i(this,L,I).call(this)?this.ye():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,L,A).call(this);this.window=this.O({id:this.Ct,class:"bm-W"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"🗗","aria-label":'Switch to windowed mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,L,B).call(this,!0),i(this,L,A).call(this),this.ye()},e.ontouchend=()=>{e.click()}}).N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,L,A).call(this),e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h bm-1K"}).F(1,{textContent:"Color Filter"}).N().N().W().N().O({class:"bm-L bm-x bm-h bm-1C",style:"gap: 1.5ch;"}).lt({class:"bm-1s",textContent:"Hide All Colors"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!1)}).N().lt({class:"bm-1s",textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!0)}).N().N().W().N().O({class:"bm-L bm-H bm-1p"}).O({class:"bm-L bm-1x",style:"margin-left: 2.5ch; margin-right: 2.5ch;"}).O({class:"bm-L bm-1q"}).I({id:"bm-i",innerHTML:"Tiles Loaded: 0 / ???"}).N().U().N().I({id:"bm-d",innerHTML:"Correct Pixels: ???"}).N().U().N().I({id:"bm-j",innerHTML:"Total Pixels: ???"}).N().U().N().I({id:"bm-7",innerHTML:"Complete: ??? (???)"}).N().U().N().I({id:"bm-8",innerHTML:"??? ???"}).N().N().O({class:"bm-L bm-1Y"}).L({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.ce.replace("{e.onclick=t=>{t.preventDefault();const e=new FormData(document.querySelector(`#${this.Ct} form`)),s={};for(const[t,i]of e)s[t]=i;console.log(`Primary: ${s.sortPrimary}; Secondary: ${s.sortSecondary}; Unused: ${"on"==s.showUnused}`),i(this,L,J).call(this,s.sortPrimary,s.sortSecondary,"on"==s.showUnused)}}).N().N().N().N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,L,Y).call(this,t),i(this,L,P).call(this),i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${n(this.ue)} / ${n(this.be)}`),this.ct("#bm-d",`Correct Pixels: ${n(this.ge)}`),this.ct("#bm-j",`Total Pixels: ${n(this.we)}`),this.ct("#bm-7",`Remaining: ${n((this.we||0)-(this.ge||0))} (${o(((this.we||0)-(this.ge||0))/(this.we||1))})`),this.ct("#bm-8",`Completed at: `),i(this,L,z).call(this)}ye(){if(document.querySelector(`#${this.Ct}`))return void i(this,L,A).call(this);this.window=this.O({id:this.Ct,class:"bm-W bm-N",style:`width: 300px; height: min(70vh, 32rem); min-width: ${this.oe}px; min-height: ${this.ae}px; max-width: min(${this.re}px, calc(100vw - 16px)); max-height: min(${this.le}px, calc(100vh - 16px));`}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Color Filter"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>{const i=document.querySelector("#bm-2");i&&(i.style.display="expanded"==e.dataset.buttonStatus?"none":""),t.wt(e)},e.ontouchend=()=>{e.click()}}).N().O().I({id:"bm-2",class:"bm-y",style:"font-weight: 700;"}).N().N().O({class:"bm-D"}).lt({class:"bm-s",textContent:"🗖","aria-label":'Switch to fullscreen mode for "Color Filter"'},(t,e)=>{e.onclick=()=>{i(this,L,B).call(this,!1),i(this,L,A).call(this),this.St()},e.ontouchend=()=>{e.click()}}).N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Color Filter"'},(t,e)=>{e.onclick=()=>i(this,L,A).call(this),e.ontouchend=()=>{e.click()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-h bm-1K"}).F(1,{textContent:"Color Filter"}).N().N().W().N().O({class:"bm-L bm-x bm-h bm-1C",style:"gap: 1.5ch;"}).lt({class:"bm-1s",textContent:"None"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!1)}).N().lt({class:"bm-1s",textContent:"All"},(t,e)=>{e.onclick=()=>i(this,L,X).call(this,!0)}).N().N().W().N().O({class:"bm-L bm-H bm-1p"}).N().N().O({class:"bm-1L",title:"Resize Color Filter window","aria-label":"Resize Color Filter window",role:"presentation",textContent:"◢",style:"position: absolute; right: 0; bottom: 0; width: 28px; height: 28px; display: flex; align-items: flex-end; justify-content: flex-end; padding-right: 4px; padding-bottom: 4px; box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; touch-action: none; user-select: none; font-size: 8px; line-height: 1; color: rgba(255,255,255,0.95); background: transparent; border: none; box-shadow: none;"}).N().N().k(this.Tt),i(this,L,E).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,L,Y).call(this,t),i(this,L,P).call(this),i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),i(this,L,z).call(this)}ve(){i(this,L,_).call(this);const t=document.querySelector(`#${this.Zt}`),e={};for(const t of this.palette){const i=this.pe.get(t.id)??0,s=n(i);let a=0,r="0",l=o(1);0!=i&&(a=this.fe.get(t.id)??"???","number"!=typeof a&&this.ue==this.be&&t.id&&(a=0),r="string"==typeof a?a:n(a),l=isNaN(a/i)?"???":o(a/i));const h=parseInt(i)-parseInt(a);e[t.id]={Me:i,Ce:s,Te:a,Se:r,De:l,Ne:h}}if(document.querySelector("#bm-2")){const t=this.ge.toString().length>7?this.ge.toString().slice(0,2)+"…"+this.ge.toString().slice(-3):this.ge.toString(),e=this.we.toString().length>7?this.we.toString().slice(0,2)+"…"+this.we.toString().slice(-3):this.we.toString();this.ct("#bm-2",`${t}/${e}`,!0)}if(this.ct("#bm-i",`Tiles Loaded: ${n(this.ue)} / ${n(this.be)}`),this.ct("#bm-d",`Correct Pixels: ${n(this.ge)}`),this.ct("#bm-j",`Total Pixels: ${n(this.we)}`),this.ct("#bm-7",`Remaining: ${n((this.we||0)-(this.ge||0))} (${o(((this.we||0)-(this.ge||0))/(this.we||1))})`),this.ct("#bm-8",`Completed at: `),!t)return e;const s=Array.from(t.children);for(const t of s){const i=parseInt(t.dataset.id),{Te:s,Se:n,De:o,Me:a,Ce:r,Ne:l}=e[i];t.dataset.correct=Number.isNaN(parseInt(s))?"0":s,t.dataset.total=a,t.dataset.percent="%"==o.slice(-1)?o.slice(0,-1):"0",t.dataset.incorrect=l||0;const h=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-9`);h&&(h.textContent=`${n} / ${r}`);const c=document.querySelector(`#${this.Ct} .bm-z[data-id="${i}"] .bm-6`);c&&(c.textContent=`${"number"!=typeof l||isNaN(l)?"???":l} incorrect pixel${1==l?"":"s"}. Completed: ${o}`)}i(this,L,J).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};L=new WeakSet,H=function(){var t,e;return this.$?((t=this.$.kt)[e=this.Kt]??(t[e]={}),this.$.kt[this.Kt]):null},I=function(){const t=i(this,L,H).call(this);return"windowed"==t?.mode||"fullscreen"!=t?.mode},B=function(t){const e=i(this,L,H).call(this);e&&(e.mode=t?"windowed":"fullscreen"),this.$&&(this.$.ke(this.Qt,t),this.$.Oe())},P=function(){const t=document.querySelector(`#${this.Ct} #bm-c`),e=document.querySelector(`#${this.Ct} #bm-5`),i=document.querySelector(`#${this.Ct} #bm-e`);t instanceof HTMLSelectElement&&(t.value=this.sortPrimary),e instanceof HTMLSelectElement&&(e.value=this.sortSecondary),i instanceof HTMLInputElement&&(i.checked=this.showUnused)},A=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,L,R).call(this,t),i(this,L,F).call(this),i(this,L,W).call(this),t?.remove()},z=function(){i(this,L,F).call(this),this.se=setInterval(()=>{document.querySelector(`#${this.Ct}`)?this.ve():i(this,L,F).call(this)},this.ne)},F=function(){this.se&&(clearInterval(this.se),this.se=null)},W=function(){this.te&&(this.te.disconnect(),this.te=null),this.ee&&(window.removeEventListener("resize",this.ee),this.ee=null),this.ie&&(clearTimeout(this.ie),this.ie=null)},U=function(t,e,i){const s=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),s)},V=function(t,e,i){const s=Math.max(8,window.innerWidth-t.offsetWidth-8),n=Math.max(8,window.innerHeight-t.offsetHeight-8);return{x:Math.min(Math.max(Math.round(Number(e)||8),8),s),y:Math.min(Math.max(Math.round(Number(i)||8),8),n)}},G=function(t){const e=i(this,L,H).call(this);if(!e||!t)return;const s=Number(e.width),n=Number(e.height),o=Number.isFinite(s),a=Number.isFinite(n);o&&(e.width=i(this,L,U).call(this,s,this.oe,Math.min(this.re,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,L,U).call(this,n,this.ae,Math.min(this.le,window.innerHeight-16)),t.style.height=`${e.height}px`),requestAnimationFrame(()=>{if(!t.isConnected)return;const s=Number(e.x),n=Number(e.y);if(!Number.isFinite(s)||!Number.isFinite(n))return;const o=i(this,L,V).call(this,t,s,n);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${o.x}px, ${o.y}px)`,o.x==s&&o.y==n||(e.x=o.x,e.y=o.y,this.$?.Oe())})},R=function(t){const e=i(this,L,H).call(this);if(!e||!t?.isConnected||!t.classList.contains("bm-N"))return;const s=t.getBoundingClientRect(),n=i(this,L,U).call(this,s.width,this.oe,Math.min(this.re,window.innerWidth-16)),o=i(this,L,U).call(this,s.height,this.ae,Math.min(this.le,window.innerHeight-16));Math.round(s.width)!=n&&(t.style.width=`${n}px`),Math.round(s.height)!=o&&(t.style.height=`${o}px`);const a=i(this,L,V).call(this,t,s.left,s.top);t.style.left="0px",t.style.top="0px",t.style.right="",t.style.transform=`translate(${a.x}px, ${a.y}px)`,e.x=a.x,e.y=a.y,e.width=n,e.height=o,this.$?.Oe()},j=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,L,R).call(this,t)},e)},E=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,L,W).call(this),i(this,L,G).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{$t:({element:t})=>i(this,L,R).call(this,t)}),this.vt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-1L`,{minWidth:this.oe,minHeight:this.ae,maxWidth:Math.min(this.re,window.innerWidth-16),maxHeight:Math.min(this.le,window.innerHeight-16),$t:({element:t})=>i(this,L,R).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,L,j).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,L,j).call(this,t,0),window.addEventListener("resize",this.ee))},Y=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N");console.log(`Is Windowed Mode: ${e}`);const i=new M(this.name,this.version);i.O({id:this.Zt});const s=this.ve();for(const t of this.palette){const n="#"+f(t.rgb).toUpperCase(),o=p(t.rgb);let a=1.05/(o+.05)>(o+.05)/.05?"white":"black";t.id||(a="transparent");const r="white"==a?"bm-f":"bm-g",{Te:l,Se:h,De:c,Me:m,Ce:d,Ne:u}=s[t.id],b=!!this.he.Le.get(t.id);if(e){const e=`background-size: auto 100%; background-repeat: repeat-x; background-image: url("data:image/svg+xml;utf8,");`;i.O({class:"bm-L bm-z bm-x","data-id":t.id,"data-name":t.name,"data-premium":+t.premium,"data-correct":Number.isNaN(parseInt(l))?"0":l,"data-total":m,"data-percent":"%"==c.slice(-1)?c.slice(0,-1):"0","data-incorrect":u||0}).O({class:"bm-a",style:`background-color: rgb(${t.rgb?.map(t=>Number(t)||0).join(",")});${t.premium?e:""}`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.me.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.me.replace("Number(t)||0).join(",")});`}).lt({class:"bm-A "+r,"data-state":b?"hidden":"shown","aria-label":b?`Show the color ${t.name||""} on templates.`:`Hide the color ${t.name||""} on templates.`,innerHTML:b?this.me.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.me.replace("{const o=s.getAttribute("data-"+t),a=n.getAttribute("data-"+t),r=parseFloat(o),l=parseFloat(a),h=!isNaN(r),c=!isNaN(l);if(i?s.classList.remove("bm-I"):Number(s.getAttribute("data-total"))||s.classList.add("bm-I"),h&&c)return"ascending"===e?r-l:l-r;{const t=o.toLowerCase(),i=a.toLowerCase();return ti?"ascending"===e?1:-1:0}}),n.forEach(t=>s.appendChild(t))},X=function(t){const e=document.querySelector(`#${this.Zt}`),i=Array.from(e.children);for(const e of i){if(e.classList?.contains("bm-I"))continue;const i=e.querySelector(".bm-a button");("hidden"!=i.dataset.state||t)&&("shown"==i.dataset.state&&t||i.click())}},_=function(){this.ue=0,this.be=0,this.we=0,this.ge=0,this.fe=new Map,this.pe=new Map;for(const t of this.he.Ie){const e=t.Pt?.total??0;this.we+=e??0;const i=t.Pt?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,s=this.pe.get(t)??0;this.pe.set(t,s+i)}const s=t.Pt?.correct??{};this.ue+=Object.keys(s).length,this.be+=Object.keys(t.Ht).length;for(const t of Object.values(s))for(const[e,i]of t){const t=Number(i)||0;this.ge+=t;const s=this.fe.get(e)??0;this.fe.set(e,s+t)}}console.log(`Tiles loaded: ${this.ue} / ${this.be}`),this.ge>=this.we&&this.we&&this.ue==this.be&&(new q).qt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.we-this.ge)*1e3+Date.now()),this.xe=a(this.timeRemaining)},Q=new WeakSet,K=async function(t,e,i){i.preventDefault();const s=await async function(t){let e="";return t&&(e=t.clipboardData.getData("text/plain")),0!=e.length||(await navigator.clipboard.readText().then(t=>{e=t}).catch(t=>{l("Failed to retrieve clipboard data using navigator! Using fallback methods...")}),0!=e.length||(e=window.clipboardData?.getData("Text"))),e}(i),n=s.split(/[^a-zA-Z0-9]+/).filter(t=>t).map(Number).filter(t=>!isNaN(t));2==n.length&&"bm-O"==e.id?(t.ct("bm-O",n?.[0]||""),t.ct("bm-P",n?.[1]||"")):1==n.length?t.ct(e.id,n?.[0]||""):(t.ct("bm-Q",n?.[0]||""),t.ct("bm-R",n?.[1]||""),t.ct("bm-O",n?.[2]||""),t.ct("bm-P",n?.[3]||""))};var ot=class extends M{constructor(t,i,s,n=void 0){super(t,i),e(this,tt),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Be=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Be?.scriptVersion,this.schemaVersion=this.Be?.schemaVersion,this.Pe=void 0,this.Ae=s,this.he=n}St(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();let t="";document.querySelector("#bm-F")||(t=t.concat("z-index: 9001;").trim()),this.window=this.O({id:this.Ct,class:"bm-W",style:t},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Template Wizard"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().lt({class:"bm-s",textContent:"✖","aria-label":'Close window "Template Wizard"'},(t,e)=>{e.onclick=()=>{document.querySelector(`#${this.Ct}`)?.remove()},e.ontouchend=()=>{e.click()}}).N().N().O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Template Wizard"}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Status"}).N().L({id:"bm-v",textContent:"Loading template storage status..."}).N().N().O({class:"bm-L bm-H"}).F(2,{textContent:"Detected templates:"}).N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,tt,et).call(this),i(this,tt,it).call(this)}};tt=new WeakSet,et=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Ae.split(/[-\.\+]/);let s="";t[0]==e[0]?t[1]==e[1]?(s='Template storage health: Healthy!
No futher action required. (Reason: Semantic version matches)',this.Pe="Good"):(s='Template storage health: Poor!
You can still use your template, but some features may not work. It is recommended that you update Blue Marble\'s template storage. (Reason: MINOR version mismatch)',this.Pe="Poor"):t[0]Bad!
It is guaranteed that some features are broken. You might still be able to use the template. It is HIGHLY recommended that you download all templates and update Blue Marble\'s template storage before continuing. (Reason: MAJOR version mismatch)',this.Pe="Bad"):(s='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Pe="Dead");const n=`
If you want to continue using your current templates, then make sure the template storage (schema) is up-to-date.
If you don't want to update the template storage, then downgrade Blue Marble to version ${r(this.scriptVersion)} to continue using your templates.
Alternatively, if you don't care about corrupting the templates listed below, you can fix any issues with the template storage by uploading a new template.`,o=function(){const t=[...document.querySelectorAll("body > div > .hidden")].filter(t=>/version:/i.test(t.textContent));if(t[0]){const e=t[0].textContent?.match(/\d+/);return e?new Date(Number(e[0])):void 0}}();let l=o?a(o):"???";this.ct("#bm-v",`${s}
Your templates were created during Blue Marble version ${r(this.scriptVersion)} with schema version ${r(this.schemaVersion)}.
The current Blue Marble version is ${r(this.version)} and requires schema version ${r(this.Ae)}.
Wplace was last updated on ${l}.${"Good"!=this.Pe?n:""}`);const h=new M(this.name,this.version);"Dead"!=this.Pe&&(h.O({class:"bm-L bm-D bm-h",style:"gap: 1.5ch;"}),h.lt({textContent:"Download all templates"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.he.ze().then(()=>{e.disabled=!1})}}).N()),"Poor"!=this.Pe&&"Bad"!=this.Pe||h.lt({textContent:`Update template storage to ${this.Ae}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,tt,st).call(this,!0)}}).N(),h.N().k(document.querySelector("#bm-v").parentNode)},it=function(){const t=this.Be?.templates;if(Object.keys(t).length>0){const e=document.querySelector(`#${this.Ct} .bm-H`),i=new M(this.name,this.version);i.O({id:"bm-B",class:"bm-L"});for(const e in t){const s=e,o=t[e];if(t.hasOwnProperty(e)){const t=s.split(" "),e=Number(t?.[0]),a=d(t?.[1]||"0",this.he.Fe),r=o.name||`Template ${e||""}`,l=o?.coords?.split(",").map(Number),h=o.pixels?.total??void 0,c=void 0,m="number"==typeof e?n(e):"???",u="number"==typeof a?n(a):"???",b="number"==typeof h?n(h):"???";i.O({class:"bm-L bm-D"}).O({class:"bm-D",style:"flex-direction: column; gap: 0;"}).O({class:"bm-1",textContent:c||"🖼️"}).N().H({textContent:`#${m}`}).N().N().O({class:"bm-D bm-0"}).F(3,{textContent:r}).N().I({textContent:`Uploaded by user #${u}`}).N().I({textContent:`Coordinates: ${l.join(", ")}`}).N().I({textContent:`Total Pixels: ${b}`}).N().N().N()}}i.N().k(e)}},st=async function(t){if(t){const t=document.querySelector(`#${this.Ct} .bm-m`);t.innerHTML="",new M(this.name,this.version).O({class:"bm-L"}).O({class:"bm-L bm-h"}).F(1,{textContent:"Template Wizard"}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Status"}).N().L({textContent:"Updating template storage. Please wait..."}).N().N().N().k(t)}GM_deleteValue("bmCoords");const e=this.Be?.templates;if(Object.keys(e).length>0)for(const[t,i]of Object.entries(e))if(e.hasOwnProperty(t)){const t=new O({displayName:i.name,Ht:i.tiles});t.Yt();const e=await this.he.We(t);await this.he.Ue(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new ot(this.name,this.version,this.Ae,this.he).St())};var at,rt,lt,ht,ct,mt,dt,ut,bt=ot;at=new WeakSet,rt=function(){const t=this.$?.kt?.filter,e=Array.isArray(t)?t:[];this.Le.clear();for(const t of e){const e=Number(t);Number.isFinite(e)&&this.Le.set(e,!0)}},lt=function(){this.$&&(this.$.kt.filter=Array.from(this.Le.keys()).map(t=>Number(t)).filter(t=>Number.isFinite(t)).sort((t,e)=>t-e),this.$.Oe())},ht=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Ve))},ct=async function(t){console.log("Parsing BlueMarble...");const e=t.templates;console.log(`BlueMarble length: ${Object.keys(e).length}`);const i=t?.schemaVersion,s=i.split(/[-\.\+]/),n=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;console.log(`BlueMarble Template Schema: ${i}; Script Version: ${o}`),s[0]==n[0]?(s[1]!=n[1]&&new bt(this.name,this.version,this.schemaVersion,this).St(),this.Ie=await async function({Bt:t,Ge:i,Ie:s}){if(Object.keys(e).length>0)for(const n in e){const o=n,a=e[n];if(console.log(`Template Key: ${o}`),e.hasOwnProperty(n)){const e=o.split(" "),n=Number(e?.[0]),r=e?.[1]||"0",l=a.name||`Template ${n||""}`,h={total:a.pixels?.total,colors:new Map(Object.entries(a.pixels?.colors||{}).map(([t,e])=>[Number(t),e]))},c=a.tiles,m={},d={},u=t*i;for(const t in c)if(console.log(t),c.hasOwnProperty(t)){const e=b(c[t]),i=new Blob([e],{type:"image/png"}),s=await createImageBitmap(i);m[t]=s;const n=new OffscreenCanvas(u,u).getContext("2d");n.drawImage(s,0,0);const o=n.getImageData(0,0,s.width,s.height);d[t]=new Uint32Array(o.data.buffer)}const p=new O({displayName:l,Ot:n||this.Ie?.length||0,Lt:r||""});p.Pt=h,p.Ht=m,p.It=d,s.push(p),console.log(this.Ie),console.log("^^^ This ^^^")}}return s}({Bt:this.Bt,Ge:this.Ge,Ie:this.Ie})):s[0]>>24&255,$=g>>>24&255,y=b.get(w)??-2,v=b.get(g)??-2;if(this.Le.get(y)&&(e[i*h+c]=g),-1==y){const t=536870912;this.Le.get(y)?e[i*h+c]=0:(u/o&1)==(f/o&1)?(e[i*h+c]=t,e[(i-1)*h+(c-1)]=t,e[(i-1)*h+(c+1)]=t,e[(i+1)*h+(c-1)]=t,e[(i+1)*h+(c+1)]=t):(e[i*h+c]=0,e[(i-1)*h+c]=t,e[(i+1)*h+c]=t,e[i*h+(c-1)]=t,e[i*h+(c+1)]=t)}if(!n&&x>m&&v!=y&&(d||$>m)){const t=e[i*h+c];for(const n of s){const[s,o,a]=n,r=0!=s?1!=s?t:4278190335:0;e[(i+a)*h+(c+o)]=r}}if(-1==y&&g<=m){const t=p.get(y);p.set(y,t?t+1:1);continue}if(x<=m||$<=m)continue;if(v!=y)continue;const M=p.get(y);p.set(y,M?M+1:1)}return console.log("List of template pixels that match the tile:"),console.log(p),{qe:p,Ze:e}},dt=new WeakSet,ut=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var pt=GM_info.script.name.toString(),ft=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",pt),e.setAttribute("bm-X","color: cornflowerblue;"),e.textContent=`(${t})();`,document.documentElement?.appendChild(e),e.remove()}(()=>{const t=document.currentScript,e=t?.getAttribute("bm-11")||"Blue Marble",i=t?.getAttribute("bm-X")||"",s=new Map;window.addEventListener("message",t=>{const{source:n,endpoint:o,blobID:a,blobData:r,blink:l}=t.data,h=Date.now()-l;if(console.groupCollapsed(`%c${e}%c: ${s.size} Recieved IMAGE message about blob "${a}"`,i,""),console.log(`Blob fetch took %c${String(Math.floor(h/6e4)).padStart(2,"0")}:${String(Math.floor(h/1e3)%60).padStart(2,"0")}.${String(h%1e3).padStart(3,"0")}%c MM:SS.mmm`,i,""),console.log(s),console.groupEnd(),"blue-marble"==n&&a&&r&&!o){const t=s.get(a);"function"==typeof t?t(r):c(`%c${e}%c: Attempted to retrieve a blob (%s) from queue, but the blobID was not a function! Skipping...`,i,"",a),s.delete(a)}});const n=window.fetch;window.fetch=async function(...t){const o=await n.apply(this,t),a=o.clone(),r=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",l=a.headers.get("content-type")||"";if(l.includes("application/json"))console.log(`%c${e}%c: Sending JSON message about endpoint "${r}"`,i,""),a.json().then(t=>{const s=r?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();if("me"==s)try{sessionStorage.setItem("bm-2i",JSON.stringify(t))}catch(t){console.warn(`%c${e}%c: Failed to cache "/me" payload`,i,"",t)}window.postMessage({source:"blue-marble",endpoint:r,jsonData:t},"*")}).catch(t=>{console.error(`%c${e}%c: Failed to parse JSON: `,i,"",t)});else if(l.includes("image/")&&!r.includes("openfreemap")&&!r.includes("maps")){const t=Date.now(),n=await a.blob();return console.log(`%c${e}%c: ${s.size} Sending IMAGE message about endpoint "${r}"`,i,""),new Promise(o=>{const l=crypto.randomUUID();s.set(l,t=>{o(new Response(t,{headers:a.headers,status:a.status,statusText:a.statusText})),console.log(`%c${e}%c: ${s.size} Processed blob "${l}"`,i,"")}),window.postMessage({source:"blue-marble",endpoint:r,blobID:l,blobData:n,blink:t})}).catch(n=>{const o=Date.now();console.error(`%c${e}%c: Failed to Promise blob!`,i,""),console.groupCollapsed(`%c${e}%c: Details of failed blob Promise:`,i,""),console.log(`Endpoint: ${r}\nThere are ${s.size} blobs processing...\nBlink: ${t.toLocaleString()}\nTime Since Blink: ${String(Math.floor(o/6e4)).padStart(2,"0")}:${String(Math.floor(o/1e3)%60).padStart(2,"0")}.${String(o%1e3).padStart(3,"0")} MM:SS.mmm`),console.error("Exception stack:",n),console.groupEnd()})}return o}});var gt=GM_getResourceText("CSS-BM-File");function wt(t){const e=document.createElement("link");e.href=t,e.rel="preload",e.as="style",e.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(e)}GM_addStyle(gt);var xt="robotoMonoInjectionPoint";wt("https://fonts.googleapis.com/css2?family=Michroma&family=Rajdhani:wght@400;500;600;700&display=swap"),xt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(xt)):wt("https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap");var $t=JSON.parse(GM_getValue("bmUserSettings","{}")),yt=(new class{constructor(){this.Qe=null,this.Ke=null,this.ti="#bm-p"}ei(t){return this.Ke=t,this.Qe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.ti)}),this}ii(){return this.Qe}observe(t,e=!1,i=!1){t.observe(this.Ke,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,Q),this.window=null,this.Ct="bm-F",this.Tt=document.body}St(){document.querySelector(`#${this.Ct}`)?this.yt("Main window already exists!"):(this.window=this.O({id:this.Ct,class:"bm-W bm-N",style:"top: 10px; left: unset; right: 75px;"},(t,e)=>{}).ft().lt({class:"bm-s",textContent:"▼","aria-label":'Minimize window "Blue Marble"',"data-button-status":"expanded"},(t,e)=>{e.onclick=()=>t.wt(e),e.ontouchend=()=>{e.click()}}).N().O().N().O({class:"bm-D"}).lt({class:"bm-s",innerHTML:"⚙️",title:"Settings"},(t,e)=>{e.onclick=()=>{t.$.St()}}).N().N().N().O({class:"bm-m"}).O({class:"bm-L bm-29"}).A({class:"bm-T",src:"https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png"},(t,e)=>{const i=new Date;204==Math.floor((i.getTime()-new Date(i.getFullYear(),0,1))/864e5)+1&&(e.parentNode.style.position="relative",e.parentNode.innerHTML=e.parentNode.innerHTML+'',e.onload=()=>{(new q).qt(document.querySelector(`#${this.Ct}`))})}).N().F(1,{textContent:this.name}).N().N().W().N().O({class:"bm-L bm-24"}).O({class:"bm-1F bm-1f"}).I({class:"bm-1y",textContent:"Droplets"}).N().I({id:"bm-w",class:"bm-1z",textContent:"0"}).N().N().O({class:"bm-1F bm-1f"}).I({class:"bm-1y",textContent:"Next Level"}).N().I({id:"bm-q",class:"bm-1z",textContent:"0 px"}).N().N().O({class:"bm-1F bm-1g"}).I({class:"bm-1y",textContent:"Charges"}).N().gt(Date.now(),1e3,{class:"bm-1z",style:"font-weight: 700;"},(t,e)=>{t.p.si=e.id}).N().N().N().W().N().O({class:"bm-L bm-25"}).O({class:"bm-L bm-1-"}).lt({class:"bm-s bm-J",style:"margin-top: 0;",innerHTML:''},(t,e)=>{e.onclick=()=>{const e=t.p?.ni;e?.[0]?(t.ct("bm-Q",e?.[0]||""),t.ct("bm-R",e?.[1]||""),t.ct("bm-O",e?.[2]||""),t.ct("bm-P",e?.[3]||"")):t.yt("Coordinates are malformed! Did you try clicking on the canvas first?")}}).N().dt({type:"number",id:"bm-Q",class:"bm-C",placeholder:"Tl X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-R",class:"bm-C",placeholder:"Tl Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-O",class:"bm-C",placeholder:"Px X",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().dt({type:"number",id:"bm-P",class:"bm-C",placeholder:"Px Y",min:0,max:2047,step:1,required:!0},(t,e)=>{e.addEventListener("paste",s=>i(this,Q,K).call(this,t,e,s))}).N().N().O({class:"bm-L bm-1_"}).ut({class:"bm-K",textContent:"Upload Template",accept:"image/png, image/jpeg, image/webp, image/bmp, image/gif"}).N().N().O({class:"bm-L bm-x bm-1V"}).lt({class:"bm-1s",textContent:"Disable","data-button-status":"shown"},(t,e)=>{e.onclick=()=>{e.disabled=!0,"shown"==e.dataset.buttonStatus?(t.p?.he?.oi(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.he?.oi(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.Mt("Enabled templates!")),e.disabled=!1}}).N().lt({class:"bm-1D",textContent:"Create"},(t,e)=>{e.onclick=()=>{const e=document.querySelector(`#${this.Ct} .bm-K`),i=document.querySelector("#bm-Q");if(!i.checkValidity())return i.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const s=document.querySelector("#bm-R");if(!s.checkValidity())return s.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const n=document.querySelector("#bm-O");if(!n.checkValidity())return n.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");const o=document.querySelector("#bm-P");if(!o.checkValidity())return o.reportValidity(),void t.yt("Coordinates are malformed! Did you try clicking on the canvas first?");e?.files[0]?(t?.p?.he.Ue(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(s.value),Number(n.value),Number(o.value)]),t.Mt("Drew to canvas!")):t.yt("No file selected!")}}).N().lt({class:"bm-1s",textContent:"Filter"},(t,e)=>{e.onclick=()=>this.ai()}).N().N().O({class:"bm-L bm-20"}).bt({id:this.v,placeholder:`Status: Sleeping...\nVersion: ${this.version}`,readOnly:!0}).N().N().N().N().N().k(this.Tt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}ai(){new nt(this).$e()}}(pt,ft)),vt=new class{constructor(t,i){e(this,at),this.name=t,this.version=i,this.Re=null,this.$=null,this.schemaVersion="2.0.0",this.ri=null,this.Fe="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.Bt=1e3,this.Ge=3,this._e=3,this.de=function(t){const e=v;e.unshift({id:-1,premium:!1,name:"Erased",rgb:[222,250,206]}),e.unshift({id:-2,premium:!1,name:"Other",rgb:[0,0,0]});const i=new Map;for(const s of e){if(0==s.id||-2==s.id)continue;const e=s.rgb[0],n=s.rgb[1],o=s.rgb[2];for(let a=-t;a<=t;a++)for(let r=-t;r<=t;r++)for(let l=-t;l<=t;l++){const t=e+a,h=n+r,c=o+l;if(t<0||t>255||h<0||h>255||c<0||c>255)continue;const m=(255<<24|c<<16|h<<8|t)>>>0;i.has(m)||i.set(m,s.id)}}return{palette:e,Jt:i}}(this._e),this.Ee=null,this.li="",this.Ie=[],this.Ve=null,this.hi=!0,this.ci=null,this.Le=new Map}mi(t){this.Re=t}D(t){this.$=t,i(this,at,rt).call(this)}He(t,e){const s=Number(t);Number.isFinite(s)&&(e?this.Le.set(s,!0):this.Le.delete(s),i(this,at,lt).call(this))}async di(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async Ue(t,e,s){this.Ve||(this.Ve=await this.di(),console.log("Creating JSON...")),this.Re.Mt(`Creating template at ${s.join(", ")}...`);const n=new O({displayName:e,Ot:0,Lt:m(this.ri||0,this.Fe),file:t,coords:s}),o=!this.$?.kt?.flags?.includes("hl-noSkip"),a=this.$?.kt?.flags?.includes("hl-agSkip");console.log(`Should Skip: ${o}; Should Agg Skip: ${a}`);const{jt:r,Et:l}=await n.Ft(this.Bt,this.de,o,a);n.Ht=r;const h={total:n.Pt.total,colors:Object.fromEntries(n.Pt.colors)};this.Ve.templates[`${n.Ot} ${n.Lt}`]={name:n.displayName,coords:s.join(", "),enabled:!0,pixels:h,tiles:l},this.Ie=[],this.Ie.push(n),this.Re.Mt(`Template created at ${s.join(", ")}!`),console.log(Object.keys(this.Ve.templates).length),console.log(this.Ve),console.log(this.Ie),console.log(JSON.stringify(this.Ve)),await i(this,at,ht).call(this)}ui(){}async bi(){this.Ve||(this.Ve=await this.di(),console.log("Creating JSON..."))}async pi(){l("Downloading all templates..."),console.log(this.Ie);for(const t of this.Ie)await this.fi(t),await s(500)}async ze(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(console.log(t),Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.fi(new O({displayName:i.name,Ot:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ht:i.tiles})),await s(500))}async fi(t){t.Yt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.We(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",gi:"uniquify",onload:()=>{l(`Download of template '${e}' complete!`)},onerror:(t,i)=>{h(`Download of template '${e}' failed because ${t}! Details: ${i}`)},ontimeout:()=>{c(`Download of template '${e}' has timed out!`)}})}async We(t){console.log(t);const e=t.Ht,i=Object.keys(e).sort(),s=await Promise.all(i.map(t=>{return i=e[t],new Promise((t,e)=>{const s=new Image;s.onload=()=>t(s),s.onerror=e,s.src="data:image/png;base64,"+i});var i}));let n=1/0,o=1/0,a=0,r=0;i.forEach((t,e)=>{const[i,l,h,c]=t.split(",").map(Number),m=s[e],d=i*this.Bt+h,u=l*this.Bt+c;n=Math.min(n,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.Ge),r=Math.max(r,u+m.height/this.Ge)}),console.log(`Absolute coordinates: (${n}, ${o}) and (${a}, ${r})`);const l=a-n,h=r-o,c=l*this.Ge,m=h*this.Ge;console.log(`Template Width: ${l}\nTemplate Height: ${h}\nCanvas Width: ${c}\nCanvas Height: ${m}`);const d=new OffscreenCanvas(c,m),u=d.getContext("2d");i.forEach((t,e)=>{const[i,a,r,l]=t.split(",").map(Number),h=s[e],c=i*this.Bt+r,m=a*this.Bt+l;console.log(`Drawing tile (${i}, ${a}, ${r}, ${l}) (${c}, ${m}) at (${c-n}, ${m-o}) on the canvas...`),u.drawImage(h,(c-n)*this.Ge,(m-o)*this.Ge,h.width,h.height)}),u.globalCompositeOperation="destination-over",u.drawImage(d,0,-1),u.drawImage(d,0,1),u.drawImage(d,-1,0),u.drawImage(d,1,0);const b=new OffscreenCanvas(l,h),p=b.getContext("2d");return p.imageSmoothingEnabled=!1,p.drawImage(d,0,0,l*this.Ge,h*this.Ge,0,0,l,h),b.convertToBlob({type:"image/png"})}async wi(t,e){if(!this.hi)return t;const s=this.Bt*this.Ge;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.Ie;console.log(o),o.sort((t,e)=>t.Ot-e.Ot),console.log(o);const a=o.map(t=>{const i=Object.keys(t.Ht).filter(t=>t.startsWith(e));if(0===i.length)return null;const s=i.map(e=>{const i=e.split(",");return{xi:t,Ut:t.Ht[e],It:t.It?.[e],$i:[i[0],i[1]],yi:[i[2],i[3]]}});return s?.[0]}).filter(Boolean);console.log(a);const r=a?.length||0;if(console.log(`templateCount = ${r}`),!(r>0))return this.Re.Mt(`Sleeping\nVersion: ${this.version}`),t;{const t=n(o.filter(t=>Object.keys(t.Ht).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.Pt.total||0),0));this.Re.Mt(`Displaying ${r} template${1==r?"":"s"}.\nTotal pixels: ${t}`)}const l=await createImageBitmap(t),h=new OffscreenCanvas(s,s),c=h.getContext("2d");c.imageSmoothingEnabled=!1,c.beginPath(),c.rect(0,0,s,s),c.clip(),c.clearRect(0,0,s,s),c.drawImage(l,0,0,s,s);const m=c.getImageData(0,0,s,s),d=new Uint32Array(m.data.buffer),u=this.$?.kt?.highlight||[[2,0,0]],b=u?.[0],p=1==u?.length&&2==b?.[0]&&0==b?.[1]&&0==b?.[2];for(const t of a){console.log("Template:"),console.log(t);const s=!!t.xi.Pt?.colors?.get(-1);let n=t.It.slice();const o=Number(t.yi[0])*this.Ge,a=Number(t.yi[1])*this.Ge;if(0!=this.Le.size||s||c.drawImage(t.Ut,o,a),!n){const e=c.getImageData(o,a,t.Ut.width,t.Ut.height);n=new Uint32Array(e.data.buffer)}const r=Date.now(),{qe:l,Ze:h}=i(this,at,mt).call(this,{je:d,Ee:n,Ye:[o,a,t.Ut.width,t.Ut.height],Je:u,Xe:p});let m=0;const b=0;for(const[t,e]of l)t!=b&&(m+=e);0==this.Le.size&&!s&&p||(console.log("Colors to filter: ",this.Le),c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(h.buffer),t.Ut.width,t.Ut.height)),o,a)),console.log(`Finished calculating correct pixels & filtering colors for the tile ${e} in ${(Date.now()-r)/1e3} seconds!\nThere are ${m} correct pixels.`),void 0===t.xi.Pt.correct&&(t.xi.Pt.correct={}),t.xi.Pt.correct[e]=l}return await h.convertToBlob({type:"image/png"})}async Mi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&await i(this,at,ct).call(this,t)}oi(t){this.hi=t}}(pt,ft),Mt=new class{constructor(t){this.he=t,this.Ci=!1,this.si="",this.ni=[],this.Ti=[]}Si(t){window.addEventListener("message",async e=>{const i=e.data,s=i.jsonData;if(!i||"blue-marble"!==i.source)return;if(!i.endpoint)return;const n=i.endpoint?.split("?")[0].split("/").filter(t=>t&&isNaN(Number(t))).filter(t=>t&&!t.includes(".")).pop();switch(console.log('%cBlue Marble%c: Recieved message about "%s"',"color: cornflowerblue;","",n),n){case"me":this.Di(t,s);break;case"pixel":const e=i.endpoint.split("?")[0].split("/").filter(t=>t&&!isNaN(Number(t))),n=new URLSearchParams(i.endpoint.split("?")[1]),r=[n.get("x"),n.get("y")];if(this.ni.length&&(!e.length||!r.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ni=[...e,...r];const l=(o=e,a=r,[parseInt(o[0])%4*1e3+parseInt(a[0]),parseInt(o[1])%4*1e3+parseInt(a[1])]),h=document.querySelectorAll("span");for(const t of h){const i=t.textContent.trim();if(i.includes(l[0])&&i.includes(l[1])){let i=document.querySelector("#bm-p");e[0],e[1],r[0],r[1];const s=["Tl X:","Tl Y:","Px X:","Px Y:"],n=["bm-Y","bm-Z","bm-U","bm-V"],o=[...e,...r];if(i)for(const[t,e]of n.entries())document.getElementById(e).textContent=`${s[t]??"??:"} ${o[t]}`;else{i=document.createElement("span"),i.id="bm-p",i.style="display: flex; flex-wrap: wrap; gap: 0 1ch; font-size: small;";for(const[t,e]of o.entries()){const a=document.createElement("span");a.id=n[o.indexOf(e)??""],a.textContent=`${s[t]??"??:"} ${e}`,i.appendChild(a)}t.parentNode.parentNode.parentNode.insertAdjacentElement("afterend",i)}}}break;case"tile":case"tiles":let c=i.endpoint.split("/");c=[parseInt(c[c.length-2]),parseInt(c[c.length-1].replace(".png",""))];const m=i.blobID,d=i.blobData,u=Date.now(),b=await this.he.wi(d,c);console.log(`Finished loading the tile in ${(Date.now()-u)/1e3} seconds!`),window.postMessage({source:"blue-marble",blobID:m,blobData:b,blink:i.blink});break;case"robots":this.Ci="false"==s.userscript?.toString().toLowerCase();break}var o,a})}Di(t,e){if(e.status&&"2"!=e.status?.toString()[0])return void t.yt("You are not logged in or Wplace is offline!\nCould not fetch userdata.");const i=Math.ceil(Math.pow(Math.floor(e.level)*Math.pow(30,.65),1/.65)-e.pixelsPainted);if(console.log(e.id),(e.id||0===e.id)&&console.log(m(e.id,"!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~")),this.he.ri=e.id,0!=this.si.length){const t=document.querySelector("#"+this.si);if(t){const i=e.charges;t.dataset.endDate=Date.now()+(i.max-i.count)*i.cooldownMs}}t.ct("bm-w",`${n(e.droplets)}`),t.ct("bm-q",`${n(i)} px`)}async Ni(t){try{const e=await fetch(`${window.location.origin}/api/me`,{credentials:"include"});if(!e.ok)return void t.yt(`Could not fetch userdata.\nHTTP ${e.status}`);const i=await e.json();this.Di(t,i)}catch(t){h("Failed to fetch current user data:",t)}}ki(t){try{const e=sessionStorage.getItem("bm-2i");if(!e)return!1;const i=JSON.parse(e);return this.Di(t,i),!0}catch(t){return h("Failed to apply cached user data:",t),!1}}async Oi(t){console.log("Sending heartbeat to telemetry server...");let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return void console.log("Telemetry is disabled, not sending heartbeat.");const i=navigator.userAgent;let s=await this.Li(i),n=this.Hi(i);GM_xmlhttpRequest({method:"POST",url:"https://telemetry.thebluecorner.net/heartbeat",headers:{"Content-Type":"application/json"},data:JSON.stringify({uuid:e.uuid,version:t,browser:s,os:n}),onload:t=>{200!==t.status&&h("Failed to send heartbeat:",t.statusText)},onerror:t=>{h("Error sending heartbeat:",t)}})}async Li(t=navigator.userAgent){return(t=t||"").includes("OPR/")||t.includes("Opera")?"Opera":t.includes("Edg/")?"Edge":t.includes("Vivaldi")?"Vivaldi":t.includes("YaBrowser")?"Yandex":t.includes("Kiwi")?"Kiwi":t.includes("Brave")?"Brave":t.includes("Firefox/")?"Firefox":t.includes("Chrome/")?"Chrome":t.includes("Safari/")?"Safari":navigator.brave&&"function"==typeof navigator.brave.isBrave&&await navigator.brave.isBrave()?"Brave":"Unknown"}Hi(t=navigator.userAgent){return/Windows NT 11/i.test(t=t||"")?"Windows 11":/Windows NT 10/i.test(t)?"Windows 10":/Windows NT 6\.3/i.test(t)?"Windows 8.1":/Windows NT 6\.2/i.test(t)?"Windows 8":/Windows NT 6\.1/i.test(t)?"Windows 7":/Windows NT 6\.0/i.test(t)?"Windows Vista":/Windows NT 5\.1|Windows XP/i.test(t)?"Windows XP":/Mac OS X 10[_\.]15/i.test(t)?"macOS Catalina":/Mac OS X 10[_\.]14/i.test(t)?"macOS Mojave":/Mac OS X 10[_\.]13/i.test(t)?"macOS High Sierra":/Mac OS X 10[_\.]12/i.test(t)?"macOS Sierra":/Mac OS X 10[_\.]11/i.test(t)?"OS X El Capitan":/Mac OS X 10[_\.]10/i.test(t)?"OS X Yosemite":/Mac OS X 10[_\.]/i.test(t)?"macOS":/Android/i.test(t)?"Android":/iPhone|iPad|iPod/i.test(t)?"iOS":/Linux/i.test(t)?"Linux":"Unknown"}}(vt),Ct=new class extends k{constructor(t,i,s){var n;super(t,i),e(this,C),this.kt=s,(n=this.kt).flags??(n.flags=[]),this.Ii=structuredClone(this.kt),this.Bi="bmUserSettings",this.Pi=5e3,this.Ai=0,setInterval(this.zi.bind(this),this.Pi)}async zi(){await this.Fi()}async Fi(t=!1){const e=JSON.stringify(this.kt);e!=JSON.stringify(this.Ii)&&(t||Date.now()-this.Ai>this.Pi)&&(await GM.setValue(this.Bi,e),this.Ii=structuredClone(this.kt),this.Ai=Date.now(),console.log(e))}async Oe(){await this.Fi(!0)}ke(t,e=void 0){const i=this.kt?.flags?.indexOf(t)??-1;-1!=i&&!0!==e?this.kt?.flags?.splice(i,1):-1==i&&!1!==e&&this.kt?.flags?.push(t)}Dt(){const t='',e='',s=this.kt?.highlight??[[1,0,1],[2,0,0],[1,-1,0],[1,1,0],[1,0,-1]];this.window=this.O({class:"bm-L"}).F(2,{textContent:"Pixel Highlight"}).N().W().N().O({class:"bm-L",style:"margin-left: 1.5ch;"}).j({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.ke("hl-noTrans",!t.target.checked)}).N().L({id:"bm-4",textContent:"Choose a preset:",style:"font-weight: 700;"}).N().O({class:"bm-D",role:"group","aria-labelledby":"bm-4"}).O({class:"bm-3"}).I({textContent:"None"}).N().lt({innerHTML:t,"aria-label":'Preset "None"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"None")}).N().N().O({class:"bm-3"}).I({textContent:"Cross"}).N().lt({innerHTML:e,"aria-label":'Preset "Cross Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Cross")}).N().N().O({class:"bm-3"}).I({textContent:"X"}).N().lt({innerHTML:e.replace('d="M1,0H2V1H3V2H2V3H1V2H0V1H1Z"','d="M0,0V1H3V0H2V3H3V2H0V3H1V0Z"'),"aria-label":'Preset "X Shape"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"X")}).N().N().O({class:"bm-3"}).I({textContent:"Full"}).N().lt({innerHTML:t.replace("#fff","#2f4f4f"),"aria-label":'Preset "Full Template"'},(t,e)=>{e.onclick=()=>i(this,C,S).call(this,"Full")}).N().N().N().L({id:"bm-b",textContent:"Create a custom pattern:",style:"font-weight: 700;"}).N().O({class:"bm-n",role:"group","aria-labelledby":"bm-b"});for(let t=-1;t<=1;t++)for(let e=-1;e<=1;e++){const n=s[s.findIndex(([,i,s])=>i==e&&s==t)]?.[0]??0;let o="Disabled";1==n?o="Incorrect":2==n&&(o="Template"),this.window=this.lt({"data-status":o,"aria-label":`Sub-pixel ${o.toLowerCase()}`},(s,n)=>{n.onclick=()=>i(this,C,T).call(this,n,[e,t])}).N()}this.window=this.N().N().N()}Nt(){this.window=this.O({class:"bm-L"}).F(2,{textContent:"Pixel Highlight"}).N().W().N().O({class:"bm-L",style:"margin-left: 1.5ch;"}).j({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.ke("hl-noSkip",!t.target.checked)}).N().j({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.kt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.ke("hl-agSkip",t.target.checked)}).N().N().N()}}(pt,ft,$t);yt.D(Ct),yt.S(Mt),vt.mi(yt),vt.D(Ct);var Tt=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(Tt),console.log($t),console.log(Object.keys($t).length),0==Object.keys($t).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>Mt.Oi(ft),18e5);var St=$t?.telemetry;if(console.log(`Telemetry is ${!(null==St)}`),null==St||St>1){const t=new class extends M{constructor(t,i,s,n){super(t,i),e(this,dt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Wi=s,this.uuid=n}async St(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.Li(navigator.userAgent),e=this.p.Hi(navigator.userAgent);this.window=this.O({id:this.Ct,class:"bm-W",style:"height: 80vh; z-index: 9998;"}).O({class:"bm-m"}).O({class:"bm-L bm-h"}).F(1,{textContent:`${this.name} Telemetry`}).N().N().W().N().O({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,dt,ut).call(this,this.Wi);const t=document.getElementById(this.Ct);t?.remove()}}).N().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,dt,ut).call(this,0);const t=document.getElementById(this.Ct);t?.remove()}}).N().lt({textContent:"More Information"},(t,e)=>{e.onclick=()=>{window.open("https://github.com/SwingTheVine/Wplace-TelemetryServer#telemetry-data","_blank","noopener noreferrer")}}).N().N().O({class:"bm-L bm-H"}).O({class:"bm-L"}).F(2,{textContent:"Legal"}).N().L({textContent:`We collect anonymous telemetry data such as your browser, OS, and script version to make the experience better for everyone. The data is never shared personally. The data is never sold. You can turn this off by pressing the "Disable" button, but keeping it on helps us improve features and reliability faster. Thank you for supporting ${this.name}!`}).N().N().W().N().O({class:"bm-L"}).F(2,{textContent:"Non-Legal Summary"}).N().L({innerHTML:'You can disable telemetry by pressing the "Disable" button. If you would like to read more about what information we collect, press the "More Information" button.
This is the data stored on our servers:'}).N()._().Z({innerHTML:`A unique identifier (UUIDv4) generated by Blue Marble. This enables our telemetry to function without tracking your actual user ID.
Your UUID is: ${r(this.uuid)}`}).N().Z({innerHTML:`The version of Blue Marble you are using.
Your version is: ${r(this.version)}`}).N().Z({innerHTML:`Your browser type, which is used to determine Blue Marble outages and browser popularity.
Your browser type is: ${r(t)}`}).N().Z({innerHTML:`Your OS type, which is used to determine Blue Marble outages and OS popularity.
Your OS type is: ${r(e)}`}).N().Z({innerHTML:"The date and time that Blue Marble sent the telemetry information."}).N().N().L({innerHTML:'All of the data mentioned above is aggregated every hour. This means every hour, anything that could even remotly be considered "personal data" is deleted from our server. Here, "aggregated" data means things like "42 people used Blue Marble on Google Chrome this hour", which can\'t be used to identify anyone in particular.'}).N().N().N().N().N().k(this.Tt)}}(pt,ft,1,$t?.uuid);t.S(Mt),t.St()}!async function(){await vt.Mi(Tt),Mt.Si(yt),yt.St(),yt.ai(),Mt.ki(yt),Mt.Ni(yt),new MutationObserver((t,e)=>{const i=document.querySelector("#color-1");if(!i)return;let s=document.querySelector("#bm-G");if(!s){s=document.createElement("button"),s.id="bm-G",s.textContent="Move ↑",s.className="btn btn-soft",s.onclick=function(){const t=this.parentNode.parentNode.parentNode.parentNode,e="Move ↑"==this.textContent;t.parentNode.className=t.parentNode.className.replace(e?"bottom":"top",e?"top":"bottom"),t.style.borderTopLeftRadius=e?"0px":"var(--radius-box)",t.style.borderTopRightRadius=e?"0px":"var(--radius-box)",t.style.borderBottomLeftRadius=e?"var(--radius-box)":"0px",t.style.borderBottomRightRadius=e?"var(--radius-box)":"0px",this.textContent=e?"Move ↓":"Move ↑"};const t=i.parentNode.parentNode.parentNode.parentNode.querySelector("h2");t.parentNode?.appendChild(s)}}).observe(document.body,{childList:!0,subtree:!0}),l(`%c${pt}%c (${ft}) userscript has loaded!`,"color: cornflowerblue;","")}()})(); -// Build Hash: 4d2335d88d64 +// Build Hash: b0883c8b6094 diff --git a/src/WindowFilter.css b/src/WindowFilter.css index aec51eb..c6fdc70 100644 --- a/src/WindowFilter.css +++ b/src/WindowFilter.css @@ -7,39 +7,161 @@ fill: white; } +#bm-window-filter:not(.bm-windowed) { + width: min(50rem, calc(100vw - 0.55rem)); + max-width: min(50rem, calc(100vw - 0.55rem)) !important; +} + +#bm-window-filter .bm-filter-header { + padding-top: 0.08rem; +} + +#bm-window-filter .bm-filter-toolbar { + gap: 0.22rem; + flex-wrap: wrap; + width: 100%; + padding: 0.16rem; +} + +#bm-window-filter .bm-filter-toolbar > button { + flex: 1 1 10rem; +} + +#bm-window-filter .bm-filter-scrollable { + padding-right: 0.08rem; +} + +#bm-window-filter .bm-filter-insights { + display: grid; + grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr); + gap: 0.24rem 0.3rem; + align-items: stretch; +} + +#bm-window-filter .bm-filter-insights > hr, +#bm-window-filter .bm-filter-sort-panel { + grid-column: 1 / -1; +} + +#bm-window-filter .bm-filter-stats-card, +#bm-window-filter .bm-filter-note, +#bm-window-filter .bm-filter-sort-panel { + padding: 0.38rem 0.48rem; + border-radius: 13px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: linear-gradient(155deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.07)); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.16), + 0 8px 20px rgba(0, 0, 0, 0.08); +} + +#bm-window-filter .bm-filter-stats-card { + display: grid; + gap: 0.18rem; +} + +#bm-window-filter .bm-filter-stats-card br { + display: none; +} + +#bm-window-filter .bm-filter-stats-card span { + display: block; + padding: 0.28rem 0.38rem; + border-radius: 10px; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.08)); +} + +#bm-window-filter .bm-filter-note p { + margin: 0; +} + +#bm-window-filter .bm-filter-sort-panel fieldset { + border: none; + padding: 0; + margin: 0; +} + +#bm-window-filter .bm-filter-sort-panel legend { + margin-bottom: 0.12rem; +} + +#bm-window-filter .bm-filter-sort-panel .bm-container { + margin-top: 0.1rem; + margin-bottom: 0.1rem; +} + +#bm-window-filter .bm-filter-sort-actions { + display: flex; + justify-content: flex-start; +} + +#bm-window-filter .bm-filter-sort-actions button { + min-width: 7.8rem; +} + /* Filter flex */ #bm-filter-flex { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; - gap: 1em 3ch; + align-items: stretch; + gap: 0.3rem; } /* Filter color */ #bm-window-filter .bm-filter-color { + position: relative; + overflow: hidden; width: fit-content; max-width: 35ch; - background-color: rgba(21, 48, 99, 0.9); - border-radius: 1em; - padding: 0.5em; - gap: 1ch; - transition: background-color 0.3s ease; + padding: 0.28rem; + gap: 0.28rem; + border-radius: 13px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: linear-gradient(160deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.07)); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.16), + 0 8px 20px rgba(0, 0, 0, 0.08); + transition: + background 0.25s ease, + border-color 0.25s ease, + box-shadow 0.25s ease, + transform 0.25s ease; +} + +#bm-window-filter .bm-filter-color::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at top right, rgba(255, 255, 255, 0.18), transparent 24%), + radial-gradient(circle at 18% 0%, rgba(186, 246, 255, 0.12), transparent 22%); } /* Filter color on hover */ #bm-window-filter .bm-filter-color:hover, -#bm-window-filter.bm-filter-color:focus-within { - background-color: rgba(17, 40, 85, 0.9); +#bm-window-filter .bm-filter-color:focus-within { + transform: translateY(-2px); + border-color: rgba(146, 221, 255, 0.26); + background: linear-gradient(160deg, rgba(255, 255, 255, 0.22), rgba(186, 246, 255, 0.1)); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.2), + 0 10px 24px rgba(0, 0, 0, 0.1); } /* Filter window container for RGB color display */ #bm-window-filter .bm-filter-container-rgb { display: block; - border: thick double darkslategray; width: fit-content; height: fit-content; - padding: 1ch; + padding: 0.26rem; + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 10px; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.14), + 0 6px 16px rgba(0, 0, 0, 0.08); } /* Filter window container for RGB color display for Other color */ @@ -60,6 +182,7 @@ background: url('data:image/svg+xml;utf8,') repeat; background-color: transparent !important; } + #bm-window-filter .bm-filter-color[data-id="-1"] .bm-filter-container-rgb svg { fill: white !important; } @@ -71,7 +194,7 @@ /* Filter window hide color button */ #bm-window-filter .bm-filter-container-rgb button { - padding: 0.75em 0.5ch; + padding: 0.26em 0.14ch; } /* Filter window hide color button SVG */ @@ -83,7 +206,15 @@ #bm-window-filter .bm-filter-color > .bm-flex-between { flex-direction: column; align-items: flex-start; - gap: 0; + gap: 0.02rem; +} + +#bm-window-filter .bm-filter-color h2 { + margin: 0.04rem 0 0; +} + +#bm-window-filter .bm-filter-color .bm-filter-color-pxl-desc { + margin: 0.1rem 0 0; } /* Filter window color flavor text */ @@ -103,33 +234,49 @@ --bm-scrollable-max-height: 100%; display: grid; grid-template-rows: auto minmax(0, 1fr); - width: 300px; - height: min(70vh, 32rem); - min-width: 260px; - min-height: 220px; + width: 268px; + height: min(60vh, 22rem); + min-width: 228px; + min-height: 180px; max-width: min(1000px, calc(100vw - 16px)) !important; max-height: min(1400px, calc(100vh - 16px)) !important; overflow: hidden; box-sizing: border-box; position: fixed; - transition: transform 0s; + transition: + background 320ms ease, + border-color 220ms ease, + box-shadow 220ms ease, + transform 0s; } /* Keep the content area flexible inside the resizable window */ #bm-window-filter.bm-windowed .bm-window-content { display: grid; - grid-template-rows: auto auto auto minmax(0, 1fr); + grid-template-rows: auto auto auto auto minmax(0, 1fr); grid-row: 2; min-height: 0; min-width: 0; overflow: hidden; } +#bm-window-filter.bm-windowed .bm-filter-toolbar { + gap: 0.16rem; + flex-wrap: nowrap; + width: 100%; + padding: 0.12rem; +} + +#bm-window-filter.bm-windowed .bm-filter-toolbar > button { + flex: 1 1 0; + min-width: 0; +} + /* Filter flex in windowed mode */ #bm-window-filter.bm-windowed #bm-filter-flex { flex-direction: column; align-items: stretch; - gap: 0.25em; + gap: 0.16rem; width: 100%; align-self: stretch; min-width: 0; @@ -144,7 +291,8 @@ flex: 1 1 auto; min-width: 0; margin: 0; - padding: 0; + padding: 0.12rem; + border-radius: 11px; box-sizing: border-box; } @@ -157,7 +305,7 @@ /* Let the scroll area grow and shrink with the resizable window */ #bm-window-filter.bm-windowed .bm-container.bm-scrollable { display: block; - grid-row: 4; + grid-row: 5; min-height: 0; min-width: 0; height: 100%; @@ -170,25 +318,36 @@ /* Visible resize handle in the bottom-right corner */ #bm-window-filter.bm-windowed .bm-resize-corner { position: absolute; - right: 0; - bottom: 0; - display: block; - width: 28px; - height: 28px; + right: 4px; + bottom: 4px; + display: flex; + width: 20px; + height: 20px; + align-items: flex-end; + justify-content: flex-end; + padding-right: 4px; + padding-bottom: 4px; + box-sizing: border-box; z-index: 5; cursor: nwse-resize; pointer-events: auto; - opacity: 1; + opacity: 0.78; touch-action: none; user-select: none; - background: transparent; - border: none; - box-shadow: none; + color: rgba(255, 255, 255, 0.86); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.14), rgba(83, 141, 255, 0.14)); + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 8px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); } #bm-window-filter.bm-windowed .bm-resize-corner:hover, #bm-window-filter.bm-windowed .bm-resize-corner.bm-resizing { opacity: 1; + border-color: rgba(146, 221, 255, 0.36); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.1), + 0 8px 16px rgba(0, 0, 0, 0.16); } /* Filter window container for RGB color display in windowed mode */ @@ -199,26 +358,26 @@ flex: 1 1 auto; gap: 0.5ch; align-items: center; - padding: 0.1em 0.5ch; + padding: 0.1rem 0.2rem; border: none; - border-radius: 1em; + border-radius: 8px; box-sizing: border-box; } /* Filter window hide color button */ #bm-window-filter.bm-windowed .bm-filter-container-rgb button { - padding: 0.5em 0.25ch; + padding: 0.2em 0.1ch; flex: 0 0 auto; } /* Filter window hide color button SVG in windowed mode */ #bm-window-filter.bm-windowed .bm-filter-container-rgb svg { - width: 3ch; + width: 2.7ch; } /* Filter window header 2 in windowed mode */ #bm-window-filter.bm-windowed .bm-filter-color h2 { - font-size: 0.75em; + font-size: 0.78rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; @@ -227,5 +386,28 @@ /* Filter window dragbar text area in windowed mode */ #bm-window-filter #bm-filter-windowed-color-totals { + display: inline-flex; + align-items: center; + padding: 0.08rem 0.24rem; + border-radius: 999px; + background: rgba(255, 255, 255, 0.12); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); font-size: 1em; } + +@media (max-width: 980px) { + #bm-window-filter:not(.bm-windowed) { + width: min(100vw - 0.35rem, 50rem); + max-width: min(100vw - 0.35rem, 50rem) !important; + } + + #bm-window-filter .bm-filter-insights { + grid-template-columns: 1fr; + } + + #bm-window-filter .bm-filter-note, + #bm-window-filter .bm-filter-sort-panel, + #bm-window-filter .bm-filter-insights > hr { + grid-column: auto; + } +} diff --git a/src/WindowFilter.js b/src/WindowFilter.js index 752619c..180c24e 100644 --- a/src/WindowFilter.js +++ b/src/WindowFilter.js @@ -27,6 +27,8 @@ export default class WindowFilter extends Overlay { this.windowResizeObserver = null; // Resize observer for the windowed mode this.windowViewportResizeHandler = null; // Resize handler for viewport changes this.windowSaveTimeout = null; // Debounce timer for resize persistence + this.colorRefreshInterval = null; // Auto-refresh timer for live color statistics + this.colorRefreshIntervalMS = 10000; // Refresh Color Filter statistics every 10 seconds this.windowMinWidth = 260; // Minimum width for the windowed filter this.windowMinHeight = 220; // Minimum height for the windowed filter this.windowMaxWidth = 1000; // Maximum width for the windowed filter @@ -113,28 +115,22 @@ export default class WindowFilter extends Overlay { .buildElement() .buildElement() .addDiv({'class': 'bm-window-content'}) - .addDiv({'class': 'bm-container bm-center-vertically'}) + .addDiv({'class': 'bm-container bm-center-vertically bm-filter-header'}) .addHeader(1, {'textContent': 'Color Filter'}).buildElement() .buildElement() .addHr().buildElement() - .addDiv({'class': 'bm-container bm-flex-between bm-center-vertically', 'style': 'gap: 1.5ch;'}) - .addButton({'textContent': 'Hide All Colors'}, (instance, button) => { + .addDiv({'class': 'bm-container bm-flex-between bm-center-vertically bm-filter-toolbar', 'style': 'gap: 1.5ch;'}) + .addButton({'class': 'bm-button-secondary', 'textContent': 'Hide All Colors'}, (instance, button) => { button.onclick = () => this.#selectColorList(false); }).buildElement() - .addButton({'textContent': 'Refresh Data'}, (instance, button) => { - button.onclick = () => { - button.disabled = true; - this.updateColorList(); - button.disabled = false; - }; - }).buildElement() - .addButton({'textContent': 'Show All Colors'}, (instance, button) => { + .addButton({'class': 'bm-button-secondary', 'textContent': 'Show All Colors'}, (instance, button) => { button.onclick = () => this.#selectColorList(true); }).buildElement() .buildElement() - .addDiv({'class': 'bm-container bm-scrollable'}) - .addDiv({'class': 'bm-container', 'style': 'margin-left: 2.5ch; margin-right: 2.5ch;'}) - .addDiv({'class': 'bm-container'}) + .addHr().buildElement() + .addDiv({'class': 'bm-container bm-scrollable bm-filter-scrollable'}) + .addDiv({'class': 'bm-container bm-filter-insights', 'style': 'margin-left: 2.5ch; margin-right: 2.5ch;'}) + .addDiv({'class': 'bm-container bm-filter-stats-card'}) .addSpan({'id': 'bm-filter-tile-load', 'innerHTML': 'Tiles Loaded: 0 / ???'}).buildElement() .addBr().buildElement() .addSpan({'id': 'bm-filter-tot-correct', 'innerHTML': 'Correct Pixels: ???'}).buildElement() @@ -145,11 +141,11 @@ export default class WindowFilter extends Overlay { .addBr().buildElement() .addSpan({'id': 'bm-filter-tot-completed', 'innerHTML': '??? ???'}).buildElement() .buildElement() - .addDiv({'class': 'bm-container'}) + .addDiv({'class': 'bm-container bm-filter-note'}) .addP({'innerHTML': `Press the 🗗 button to make this window smaller. Colors with the icon ${this.eyeOpen.replace(' { + .addDiv({'class': 'bm-container bm-filter-sort-actions'}) + .addButton({'class': 'bm-button-primary', 'textContent': 'Sort Colors', 'type': 'submit'}, (instance, button) => { button.onclick = (event) => { event.preventDefault(); // Stop default form submission @@ -214,6 +210,7 @@ export default class WindowFilter extends Overlay { this.updateInnerHTML('#bm-filter-tot-total', `Total Pixels: ${localizeNumber(this.allPixelsTotal)}`); this.updateInnerHTML('#bm-filter-tot-remaining', `Remaining: ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`); this.updateInnerHTML('#bm-filter-tot-completed', `Completed at: `); + this.#startAutoRefresh(); } /** Spawns a windowed Color Filter window. @@ -266,26 +263,20 @@ export default class WindowFilter extends Overlay { .buildElement() .buildElement() .addDiv({'class': 'bm-window-content'}) - .addDiv({'class': 'bm-container bm-center-vertically'}) + .addDiv({'class': 'bm-container bm-center-vertically bm-filter-header'}) .addHeader(1, {'textContent': 'Color Filter'}).buildElement() .buildElement() .addHr().buildElement() - .addDiv({'class': 'bm-container bm-flex-between bm-center-vertically', 'style': 'gap: 1.5ch;'}) - .addButton({'textContent': 'None'}, (instance, button) => { + .addDiv({'class': 'bm-container bm-flex-between bm-center-vertically bm-filter-toolbar', 'style': 'gap: 1.5ch;'}) + .addButton({'class': 'bm-button-secondary', 'textContent': 'None'}, (instance, button) => { button.onclick = () => this.#selectColorList(false); }).buildElement() - .addButton({'textContent': 'Refresh'}, (instance, button) => { - button.onclick = () => { - button.disabled = true; - this.updateColorList(); - button.disabled = false; - }; - }).buildElement() - .addButton({'textContent': 'All'}, (instance, button) => { + .addButton({'class': 'bm-button-secondary', 'textContent': 'All'}, (instance, button) => { button.onclick = () => this.#selectColorList(true); }).buildElement() .buildElement() - .addDiv({'class': 'bm-container bm-scrollable'}) + .addHr().buildElement() + .addDiv({'class': 'bm-container bm-scrollable bm-filter-scrollable'}) // Color list will appear here .buildElement() .buildElement() @@ -308,6 +299,7 @@ export default class WindowFilter extends Overlay { this.#buildColorList(scrollableContainer); this.#syncSortFormControls(); this.#sortColorList(this.sortPrimary, this.sortSecondary, this.showUnused); + this.#startAutoRefresh(); } /** Retrieves the persisted window state object. @@ -373,10 +365,34 @@ export default class WindowFilter extends Overlay { if (windowElement?.classList.contains('bm-windowed')) { this.#saveWindowState(windowElement); } + this.#stopAutoRefresh(); this.#cleanupWindowPersistence(); windowElement?.remove(); } + /** Starts the automatic Color Filter statistics refresh loop. + * @since 0.92.1 + */ + #startAutoRefresh() { + this.#stopAutoRefresh(); + this.colorRefreshInterval = setInterval(() => { + if (!document.querySelector(`#${this.windowID}`)) { + this.#stopAutoRefresh(); + return; + } + this.updateColorList(); + }, this.colorRefreshIntervalMS); + } + + /** Stops the automatic Color Filter statistics refresh loop. + * @since 0.92.1 + */ + #stopAutoRefresh() { + if (!this.colorRefreshInterval) {return;} + clearInterval(this.colorRefreshInterval); + this.colorRefreshInterval = null; + } + /** Disconnects live observers used for window persistence. * @since 0.92.0 */ @@ -876,6 +892,12 @@ export default class WindowFilter extends Overlay { this.updateInnerHTML('#bm-filter-windowed-color-totals', `${allCorrect}/${allTotal}`, true); } + this.updateInnerHTML('#bm-filter-tile-load', `Tiles Loaded: ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`); + this.updateInnerHTML('#bm-filter-tot-correct', `Correct Pixels: ${localizeNumber(this.allPixelsCorrectTotal)}`); + this.updateInnerHTML('#bm-filter-tot-total', `Total Pixels: ${localizeNumber(this.allPixelsTotal)}`); + this.updateInnerHTML('#bm-filter-tot-remaining', `Remaining: ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`); + this.updateInnerHTML('#bm-filter-tot-completed', `Completed at: `); + // Return early if the color list does not exist. // We can't update DOM elements that don't exist, so we exit now. if (!colorList) {return colorStatistics;} diff --git a/src/WindowMain.css b/src/WindowMain.css new file mode 100644 index 0000000..5131a46 --- /dev/null +++ b/src/WindowMain.css @@ -0,0 +1,173 @@ +/* @since 0.92.2 */ + +#bm-window-main { + width: min(25.5rem, calc(100vw - 0.65rem)); + max-width: min(25.5rem, calc(100vw - 0.65rem)) !important; +} + +#bm-window-main .bm-window-content { + display: flex; + flex-direction: column; +} + +#bm-window-main .bm-main-hero, +#bm-window-main .bm-main-shell { + position: relative; + overflow: hidden; + border-radius: 14px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: linear-gradient(150deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.08)); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.2), + 0 10px 24px rgba(0, 0, 0, 0.1); +} + +#bm-window-main .bm-main-hero::before, +#bm-window-main .bm-main-shell::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: + radial-gradient(circle at top right, rgba(255, 255, 255, 0.2), transparent 26%), + radial-gradient(circle at 20% 0%, rgba(186, 246, 255, 0.16), transparent 24%); +} + +#bm-window-main .bm-main-hero { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.48rem 0.58rem; +} + +#bm-window-main .bm-main-hero h1 { + margin: 0; +} + +#bm-window-main .bm-main-stats { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.24rem; +} + +#bm-window-main .bm-main-stat-card { + min-width: 0; + min-height: 2.55rem; + display: flex; + align-items: flex-start; + padding: 0.34rem 0.45rem; + border-radius: 11px; + border: 1px solid rgba(255, 255, 255, 0.18); + background: linear-gradient(160deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.07)); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16); + color: rgba(18, 35, 63, 0.96); + line-height: 1.22; +} + +#bm-window-main .bm-main-stat-card > span, +#bm-window-main .bm-main-stat-card > time { + min-width: 0; +} + +#bm-window-main .bm-main-stat-card-value, +#bm-window-main .bm-main-stat-card-timer { + flex-direction: column; + justify-content: center; + gap: 0.08rem; +} + +#bm-window-main .bm-main-stat-value { + display: inline-block; + font-size: 1.3em; + color: rgba(15, 31, 56, 0.96); + white-space: normal; + overflow-wrap: anywhere; +} + +#bm-window-main .bm-main-stat-value b { + font-size: 1em; +} + +#bm-window-main .bm-main-stat-label { + color: rgba(49, 71, 105, 0.82); + font-size: 0.62rem; + letter-spacing: 0.08em; + font-family: var(--bm-font-display); + text-transform: uppercase; +} + +#bm-window-main .bm-main-stat-card time { + white-space: nowrap; + font-family: var(--bm-font-mono); + letter-spacing: 0.06em; +} + +#bm-window-main .bm-main-shell { + padding: 0.48rem; +} + +#bm-window-main .bm-main-coords { + display: grid; + grid-template-columns: auto repeat(4, minmax(0, 1fr)); + gap: 0.22rem; + align-items: center; +} + +#bm-window-main .bm-main-coords .bm-button-pin { + width: 1.8rem; + height: 1.8rem; +} + +#bm-window-main .bm-main-coords .bm-input-coords { + width: 100%; + margin-left: 0; + text-align: center; +} + +#bm-window-main .bm-main-upload, +#bm-window-main .bm-main-status { + margin-top: 0.24rem; +} + +#bm-window-main .bm-main-upload > div { + width: 100%; +} + +#bm-window-main .bm-main-actions { + gap: 0.24rem; + margin-top: 0.3rem; +} + +#bm-window-main .bm-main-actions > button { + flex: 1 1 0; +} + +#bm-window-main .bm-main-status textarea { + min-height: 4.1rem; +} + +@media (max-width: 720px) { + #bm-window-main { + width: min(100vw - 0.45rem, 25.5rem); + max-width: min(100vw - 0.45rem, 25.5rem) !important; + } + + #bm-window-main .bm-main-stats { + grid-template-columns: 1fr; + } + + #bm-window-main .bm-main-coords { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + #bm-window-main .bm-main-coords .bm-button-pin { + grid-column: 1 / -1; + width: 100%; + aspect-ratio: auto; + height: 1.8rem; + } + + #bm-window-main .bm-main-actions { + flex-direction: column; + } +} diff --git a/src/WindowMain.js b/src/WindowMain.js index d003229..b43b629 100644 --- a/src/WindowMain.js +++ b/src/WindowMain.js @@ -1,9 +1,7 @@ import ConfettiManager from "./confetttiManager"; import Overlay from "./Overlay"; import { getClipboardData } from "./utils"; -import WindowCredts from "./WindowCredits"; import WindowFilter from "./WindowFilter"; -import WindowWizard from "./WindowWizard"; /** The overlay builder for the main Blue Marble window. * @description This class handles the overlay UI for the main window of the Blue Marble userscript. @@ -50,9 +48,16 @@ export default class WindowMain extends Overlay { button.ontouchend = () => {button.click();}; // Needed ONLY to negate weird interaction with dragbar }).buildElement() .addDiv().buildElement() // Contains the minimized h1 element + .addDiv({'class': 'bm-flex-center'}) + .addButton({'class': 'bm-button-circle', 'innerHTML': '⚙️', 'title': 'Settings'}, (instance, button) => { + button.onclick = () => { + instance.settingsManager.buildWindow(); + } + }).buildElement() + .buildElement() .buildElement() .addDiv({'class': 'bm-window-content'}) - .addDiv({'class': 'bm-container'}) + .addDiv({'class': 'bm-container bm-main-hero'}) .addImg({'class': 'bm-favicon', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png'}, (instance, img) => { // Adds a birthday hat & confetti to the window if it is Blue Marble's birthday const date = new Date(); @@ -69,20 +74,25 @@ export default class WindowMain extends Overlay { .addHeader(1, {'textContent': this.name}).buildElement() .buildElement() .addHr().buildElement() - .addDiv({'class': 'bm-container'}) - .addSpan({'id': 'bm-user-droplets', 'textContent': 'Droplets:'}).buildElement() - .addBr().buildElement() - .addSpan({'id': 'bm-user-nextlevel', 'textContent': 'Next level in...'}).buildElement() - .addBr().buildElement() - .addSpan({'textContent': 'Charges: '}) - .addTimer(Date.now(), 1000, {'style': 'font-weight: 700;'}, (instance, timer) => { + .addDiv({'class': 'bm-container bm-main-stats'}) + .addDiv({'class': 'bm-main-stat-card bm-main-stat-card-value'}) + .addSpan({'class': 'bm-main-stat-label', 'textContent': 'Droplets'}).buildElement() + .addSpan({'id': 'bm-user-droplets', 'class': 'bm-main-stat-value', 'textContent': '0'}).buildElement() + .buildElement() + .addDiv({'class': 'bm-main-stat-card bm-main-stat-card-value'}) + .addSpan({'class': 'bm-main-stat-label', 'textContent': 'Next Level'}).buildElement() + .addSpan({'id': 'bm-user-nextlevel', 'class': 'bm-main-stat-value', 'textContent': '0 px'}).buildElement() + .buildElement() + .addDiv({'class': 'bm-main-stat-card bm-main-stat-card-timer'}) + .addSpan({'class': 'bm-main-stat-label', 'textContent': 'Charges'}).buildElement() + .addTimer(Date.now(), 1000, {'class': 'bm-main-stat-value', 'style': 'font-weight: 700;'}, (instance, timer) => { instance.apiManager.chargeRefillTimerID = timer.id; // Store the timer ID in apiManager so we can update the timer automatically }).buildElement() .buildElement() .buildElement() .addHr().buildElement() - .addDiv({'class': 'bm-container'}) - .addDiv({'class': 'bm-container'}) + .addDiv({'class': 'bm-container bm-main-shell'}) + .addDiv({'class': 'bm-container bm-main-coords'}) .addButton({'class': 'bm-button-circle bm-button-pin', 'style': 'margin-top: 0;', 'innerHTML': ''}, (instance, button) => { button.onclick = () => { @@ -111,11 +121,11 @@ export default class WindowMain extends Overlay { input.addEventListener("paste", event => this.#coordinateInputPaste(instance, input, event)); }).buildElement() .buildElement() - .addDiv({'class': 'bm-container'}) + .addDiv({'class': 'bm-container bm-main-upload'}) .addInputFile({'class': 'bm-input-file', 'textContent': 'Upload Template', 'accept': 'image/png, image/jpeg, image/webp, image/bmp, image/gif'}).buildElement() .buildElement() - .addDiv({'class': 'bm-container bm-flex-between'}) - .addButton({'textContent': 'Disable', 'data-button-status': 'shown'}, (instance, button) => { + .addDiv({'class': 'bm-container bm-flex-between bm-main-actions'}) + .addButton({'class': 'bm-button-secondary', 'textContent': 'Disable', 'data-button-status': 'shown'}, (instance, button) => { button.onclick = () => { button.disabled = true; // Disables the button until the transition ends if (button.dataset['buttonStatus'] == 'shown') { // If templates are currently being 'shown' then hide them @@ -132,7 +142,7 @@ export default class WindowMain extends Overlay { button.disabled = false; // Enables the button } }).buildElement() - .addButton({'textContent': 'Create'}, (instance, button) => { + .addButton({'class': 'bm-button-primary', 'textContent': 'Create'}, (instance, button) => { button.onclick = () => { const input = document.querySelector(`#${this.windowID} .bm-input-file`); @@ -153,52 +163,13 @@ export default class WindowMain extends Overlay { instance.handleDisplayStatus(`Drew to canvas!`); } }).buildElement() - .addButton({'textContent': 'Filter'}, (instance, button) => { + .addButton({'class': 'bm-button-secondary', 'textContent': 'Filter'}, (instance, button) => { button.onclick = () => this.buildWindowFilter(); }).buildElement() .buildElement() - .addDiv({'class': 'bm-container'}) + .addDiv({'class': 'bm-container bm-main-status'}) .addTextarea({'id': this.outputStatusId, 'placeholder': `Status: Sleeping...\nVersion: ${this.version}`, 'readOnly': true}).buildElement() .buildElement() - .addDiv({'class': 'bm-container bm-flex-between', 'style': 'margin-bottom: 0; flex-direction: column;'}) - .addDiv({'class': 'bm-flex-between'}) - // .addButton({'class': 'bm-button-circle', 'innerHTML': '🖌'}).buildElement() - .addButton({'class': 'bm-button-circle', 'innerHTML': '⚙️', 'title': 'Settings'}, (instance, button) => { - button.onclick = () => { - instance.settingsManager.buildWindow(); - } - }).buildElement() - .addButton({'class': 'bm-button-circle', 'innerHTML': '🧙', 'title': 'Template Wizard'}, (instance, button) => { - button.onclick = () => { - const templateManager = instance.apiManager?.templateManager; - const wizard = new WindowWizard(this.name, this.version, templateManager?.schemaVersion, templateManager); - wizard.buildWindow(); - } - }).buildElement() - .addButton({'class': 'bm-button-circle', 'innerHTML': '🎨', 'title': 'Template Color Converter'}, (instance, button) => { - button.onclick = () => { - window.open('https://pepoafonso.github.io/color_converter_wplace/', '_blank', 'noopener noreferrer'); - } - }).buildElement() - .addButton({'class': 'bm-button-circle', 'innerHTML': '🌐', 'title': 'Official Blue Marble Website'}, (instance, button) => { - button.onclick = () => { - window.open('https://bluemarble.lol/', '_blank', 'noopener noreferrer'); - } - }).buildElement() - .addButton({'class': 'bm-button-circle', 'title': 'Donate to SwingTheVine', 'innerHTML': ''}, (instance, button) => { - button.onclick = () => { - window.open('https://ko-fi.com/swingthevine', '_blank', 'noopener noreferrer'); - } - }).buildElement() - .addButton({'class': 'bm-button-circle', 'innerHTML': '🤝', 'title': 'Credits'}, (instance, button) => { - button.onclick = () => { - const credits = new WindowCredts(this.name, this.version); - credits.buildWindow(); - } - }).buildElement() - .buildElement() - .addSmall({'textContent': 'Made by SwingTheVine', 'style': 'margin-top: auto;'}).buildElement() - .buildElement() .buildElement() .buildElement() .buildElement().buildOverlay(this.windowParent); diff --git a/src/apiManager.js b/src/apiManager.js index a45bda2..522cb0e 100644 --- a/src/apiManager.js +++ b/src/apiManager.js @@ -54,44 +54,7 @@ export default class ApiManager { switch (endpointText) { case 'me': // Request to retrieve user data - - // If the game can not retrieve the userdata... - if (dataJSON['status'] && dataJSON['status']?.toString()[0] != '2') { - // The server is probably down (NOT a 2xx status) - - overlay.handleDisplayError(`You are not logged in or Wplace is offline!\nCould not fetch userdata.`); - return; // Kills itself before attempting to display null userdata - } - - const nextLevelPixels = Math.ceil(Math.pow(Math.floor(dataJSON['level']) * Math.pow(30, 0.65), (1/0.65)) - dataJSON['pixelsPainted']); // Calculates pixels to the next level - - console.log(dataJSON['id']); - if (!!dataJSON['id'] || dataJSON['id'] === 0) { - console.log(numberToEncoded( - dataJSON['id'], - '!#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~' - )); - } - this.templateManager.userID = dataJSON['id']; - - // Obtains the refill timer for charges - if (this.chargeRefillTimerID.length != 0) { - const chargeRefillTimer = document.querySelector('#' + this.chargeRefillTimerID); - - // If the refill timer exists... - if (chargeRefillTimer) { - - /** Obtains the information about the user's charges @type {{cooldownMs: number, count: number, max: number}} */ - const chargeData = dataJSON['charges']; - - // Date that the user's charges will be refilled - chargeRefillTimer.dataset['endDate'] = Date.now() + ((chargeData['max'] - chargeData['count']) * chargeData['cooldownMs']); - } - } - - // Updates displayed droplet information - overlay.updateInnerHTML('bm-user-droplets', `Droplets: ${localizeNumber(dataJSON['droplets'])}`); // Updates the text content of the droplets field - overlay.updateInnerHTML('bm-user-nextlevel', `Next level in ${localizeNumber(nextLevelPixels)} pixel${nextLevelPixels == 1 ? '' : 's'}`); // Updates the text content of the next level field + this.applyUserDataToOverlay(overlay, dataJSON); break; case 'pixel': // Request to retrieve pixel data @@ -195,6 +158,90 @@ export default class ApiManager { }); } + /** Applies user data from the /me endpoint to the current overlay. + * @param {Overlay} overlay + * @param {Object.} dataJSON + * @since 0.92.1 + */ + applyUserDataToOverlay(overlay, dataJSON) { + + // If the game can not retrieve the userdata... + if (dataJSON['status'] && dataJSON['status']?.toString()[0] != '2') { + overlay.handleDisplayError(`You are not logged in or Wplace is offline!\nCould not fetch userdata.`); + return; + } + + const nextLevelPixels = Math.ceil(Math.pow(Math.floor(dataJSON['level']) * Math.pow(30, 0.65), (1 / 0.65)) - dataJSON['pixelsPainted']); + + console.log(dataJSON['id']); + if (!!dataJSON['id'] || dataJSON['id'] === 0) { + console.log(numberToEncoded( + dataJSON['id'], + '!#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~' + )); + } + this.templateManager.userID = dataJSON['id']; + + // Obtains the refill timer for charges + if (this.chargeRefillTimerID.length != 0) { + const chargeRefillTimer = document.querySelector('#' + this.chargeRefillTimerID); + + // If the refill timer exists... + if (chargeRefillTimer) { + /** Obtains the information about the user's charges @type {{cooldownMs: number, count: number, max: number}} */ + const chargeData = dataJSON['charges']; + + // Date that the user's charges will be refilled + chargeRefillTimer.dataset['endDate'] = Date.now() + ((chargeData['max'] - chargeData['count']) * chargeData['cooldownMs']); + } + } + + overlay.updateInnerHTML('bm-user-droplets', `${localizeNumber(dataJSON['droplets'])}`); + overlay.updateInnerHTML('bm-user-nextlevel', `${localizeNumber(nextLevelPixels)} px`); + } + + /** Requests the current /me payload directly so the overlay has initial user data + * even if the first network response was missed during startup. + * @param {Overlay} overlay + * @since 0.92.1 + */ + async requestCurrentUserData(overlay) { + try { + const response = await fetch(`${window.location.origin}/api/me`, { + credentials: 'include' + }); + + if (!response.ok) { + overlay.handleDisplayError(`Could not fetch userdata.\nHTTP ${response.status}`); + return; + } + + const dataJSON = await response.json(); + this.applyUserDataToOverlay(overlay, dataJSON); + } catch (error) { + consoleError('Failed to fetch current user data:', error); + } + } + + /** Applies cached /me data from sessionStorage if it was captured during early startup. + * @param {Overlay} overlay + * @returns {boolean} + * @since 0.92.1 + */ + applyCachedUserData(overlay) { + try { + const cached = sessionStorage.getItem('bm-last-me'); + if (!cached) {return false;} + + const dataJSON = JSON.parse(cached); + this.applyUserDataToOverlay(overlay, dataJSON); + return true; + } catch (error) { + consoleError('Failed to apply cached user data:', error); + return false; + } + } + // Sends a heartbeat to the telemetry server async sendHeartbeat(version) { diff --git a/src/main.css b/src/main.css index bfa8ce9..1b19702 100644 --- a/src/main.css +++ b/src/main.css @@ -6,5 +6,6 @@ @import './confettiManager.css'; @import './overlay.css'; @import './WindowFilter.css'; +@import './WindowMain.css'; @import './WindowSettings.css'; @import './WindowWizard.css'; diff --git a/src/main.js b/src/main.js index a350fa0..a7ab136 100644 --- a/src/main.js +++ b/src/main.js @@ -92,6 +92,18 @@ inject(() => { // Sends a message about the endpoint it spied on cloned.json() .then(jsonData => { + const endpointText = endpointName?.split('?')[0].split('/').filter(s => s && isNaN(Number(s))).filter(s => s && !s.includes('.')).pop(); + + // Cache the latest /me payload so the userscript can hydrate its UI + // even if the first response arrives before listeners are attached. + if (endpointText == 'me') { + try { + sessionStorage.setItem('bm-last-me', JSON.stringify(jsonData)); + } catch (error) { + console.warn(`%c${name}%c: Failed to cache "/me" payload`, consoleStyle, '', error); + } + } + window.postMessage({ source: 'blue-marble', endpoint: endpointName, @@ -163,9 +175,23 @@ inject(() => { const cssOverlay = GM_getResourceText("CSS-BM-File"); GM_addStyle(cssOverlay); +function appendFontStylesheet(href) { + const stylesheetLink = document.createElement('link'); + stylesheetLink.href = href; + stylesheetLink.rel = 'preload'; + stylesheetLink.as = 'style'; + stylesheetLink.onload = function () { + this.onload = null; + this.rel = 'stylesheet'; + }; + document.head?.appendChild(stylesheetLink); +} + // Injection point for the Roboto Mono font file (only if this is the Standalone version) const robotoMonoInjectionPoint = 'robotoMonoInjectionPoint'; +appendFontStylesheet('https://fonts.googleapis.com/css2?family=Michroma&family=Rajdhani:wght@400;500;600;700&display=swap'); + // If the Roboto Mono injection point contains '@font-face'... if (!!(robotoMonoInjectionPoint.indexOf('@font-face') + 1)) { // A very hacky way of doing truthy/falsy logic @@ -176,15 +202,7 @@ if (!!(robotoMonoInjectionPoint.indexOf('@font-face') + 1)) { // Else, no Roboto Mono was found. We need to use a stylesheet. // Imports the Roboto Mono font family as a stylesheet - var stylesheetLink = document.createElement('link'); - stylesheetLink.href = 'https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap'; - stylesheetLink.rel = 'preload'; - stylesheetLink.as = 'style'; - stylesheetLink.onload = function () { - this.onload = null; - this.rel = 'stylesheet'; - }; - document.head?.appendChild(stylesheetLink); + appendFontStylesheet('https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap'); } const userSettings = JSON.parse(GM_getValue('bmUserSettings', '{}')); // Loads the user settings @@ -240,10 +258,13 @@ void initializeBlueMarble(); async function initializeBlueMarble() { await templateManager.importJSON(storageTemplates); // Loads the templates + apiManager.spontaneousResponseListener(windowMain); // Reads spontaneous fetch responces + windowMain.buildWindow(); // Builds the main Blue Marble window windowMain.buildWindowFilter(); // Opens the Color Filter window automatically on page load - apiManager.spontaneousResponseListener(windowMain); // Reads spontaneous fetch responces + apiManager.applyCachedUserData(windowMain); // Hydrates the UI from the earliest cached /me response if it exists + void apiManager.requestCurrentUserData(windowMain); // Ensures the main window gets current /me data even if startup missed it observeBlack(); // Observes the black palette color diff --git a/src/overlay.css b/src/overlay.css index 51c1388..1b1232a 100644 --- a/src/overlay.css +++ b/src/overlay.css @@ -15,27 +15,81 @@ /* The Blue Marble windows */ .bm-window { + --bm-surface-strong: rgba(9, 20, 42, 0.5); + --bm-surface-soft: rgba(24, 41, 74, 0.28); + --bm-surface-glass: rgba(255, 255, 255, 0.1); + --bm-surface-glass-strong: rgba(255, 255, 255, 0.18); + --bm-border-soft: rgba(255, 255, 255, 0.18); + --bm-border-strong: rgba(163, 228, 255, 0.34); + --bm-text-primary: rgba(17, 36, 66, 0.96); + --bm-text-secondary: rgba(36, 57, 90, 0.84); + --bm-accent-start: #baf6ff; + --bm-accent-end: #81b6ff; + --bm-accent-shadow: rgba(132, 182, 255, 0.22); + --bm-font-body: "Rajdhani", "Segoe UI Variable Text", "Segoe UI", sans-serif; + --bm-font-display: "Michroma", "Orbitron", "Segoe UI", sans-serif; + --bm-font-mono: "Roboto Mono", "Rajdhani", "Courier New", monospace; position: fixed; - background-color: rgba(21, 48, 99, 0.9); - color: white; - padding: 10px; - border-radius: 8px; + isolation: isolate; + overflow: hidden; + background: + radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.24), transparent 18%), + radial-gradient(circle at 86% 8%, rgba(186, 246, 255, 0.22), transparent 24%), + radial-gradient(circle at 82% 84%, rgba(129, 182, 255, 0.18), transparent 28%), + linear-gradient(145deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.06) 22%, rgba(105, 145, 212, 0.08) 54%, rgba(9, 20, 42, 0.18)); + color: var(--bm-text-primary); + padding: 6px; + border-radius: 16px; + border: 1px solid var(--bm-border-soft); + box-shadow: + 0 18px 40px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.22), + inset 0 -1px 0 rgba(255, 255, 255, 0.05); z-index: 9000; - transition: all 0.3s ease, transform 0s; + transition: + background 320ms ease, + border-color 220ms ease, + box-shadow 220ms ease, + opacity 220ms ease, + transform 0s, + width 220ms ease, + max-width 220ms ease, + max-height 220ms ease; top: 75px; left: 60px; width: auto; max-height: fit-content; max-width: calc(100% - 135px); - /* Font stack is as follows: - * Highest Priority (Roboto Mono) - * Windows fallback (Courier New) - * macOS fallback (Monaco) - * Linux fallback (DejaVu Sans Mono) - * Any possible monospace font (monospace) - * Last resort (Arial) */ - font-family: 'Roboto Mono', 'Courier New', 'Monaco', 'DejaVu Sans Mono', monospace, 'Arial'; - letter-spacing: 0.05em; + backdrop-filter: blur(26px) saturate(1.25); + font-family: var(--bm-font-body); + letter-spacing: 0.04em; +} + +.bm-window::before, +.bm-window::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; +} + +.bm-window::before { + border-radius: inherit; + padding: 1px; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.12) 24%, rgba(186, 246, 255, 0.22) 58%, rgba(129, 182, 255, 0.3)); + -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + -webkit-mask-composite: xor; + mask-composite: exclude; + opacity: 0.85; +} + +.bm-window::after { + border-radius: inherit; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.2), transparent 24%), + radial-gradient(circle at 18% 0%, rgba(255, 255, 255, 0.22), transparent 22%), + radial-gradient(circle at 88% 16%, rgba(186, 246, 255, 0.18), transparent 18%); + opacity: 1; } /* The drag bar */ @@ -43,12 +97,19 @@ display: grid; grid-template-columns: auto 1fr auto; align-items: center; - gap: 0.5ch; - /* For background circles, width & height should be odd, cx & cy should be half of width & height, and r should be less than or equal to cx & cy */ - background: url('data:image/svg+xml;utf8,') repeat; + gap: 0.28ch; + padding: 0.18rem 0.24rem; + border-radius: 10px; + border: 1px solid rgba(255, 255, 255, 0.16); + background: + radial-gradient(circle at 0 0, rgba(255, 255, 255, 0.22) 0, transparent 42%), + linear-gradient(135deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.08)); cursor: grab; width: 100%; height: fit-content; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.16), + 0 6px 18px rgba(0, 0, 0, 0.1); } /* When a window is being dragged */ @@ -73,37 +134,42 @@ /* The Blue Marble Favicon */ .bm-favicon { display: inline-block; - height: 2.5em; - margin-right: 1ch; + height: 2.2em; + margin-right: 0.45ch; + padding: 0.2rem; + border-radius: 12px; vertical-align: middle; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.08)); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.16), + 0 8px 18px rgba(0, 0, 0, 0.12); } /* Header 1 */ .bm-window h1 { display: inline-block; - font-size: x-large; - font-weight: bold; + font-size: 1rem; + font-weight: 700; vertical-align: middle; + font-family: var(--bm-font-display); + text-transform: uppercase; + letter-spacing: 0.14em; + color: rgba(16, 33, 60, 0.96); } /* Header 1 when inside dragbar */ /* Or, when the custom class is used */ .bm-dragbar h1, .bm-dragbar-text { - font-size: 1.2em; + font-size: 0.78rem; user-select: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - text-shadow: - 3px 0px rgba(21, 48, 99, 0.5), - -3px 0px rgba(21, 48, 99, 0.5), - 0px 3px rgba(21, 48, 99, 0.5), - 0px -3px rgba(21, 48, 99, 0.5), - 3px 3px rgba(21, 48, 99, 0.5), - -3px 3px rgba(21, 48, 99, 0.5), - 3px -3px rgba(21, 48, 99, 0.5), - -3px -3px rgba(21, 48, 99, 0.5); + font-family: var(--bm-font-display); + letter-spacing: 0.14em; + color: rgba(18, 37, 66, 0.95); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.28); } /* Container for Header 1 when inside dragbar */ @@ -114,9 +180,12 @@ /* Header 2 */ .bm-window h2 { display: inline-block; - font-size: larger; + font-size: 0.88rem; font-weight: 700; vertical-align: middle; + font-family: var(--bm-font-display); + letter-spacing: 0.1em; + color: rgba(18, 35, 64, 0.96); } /* Header 3 */ @@ -124,6 +193,24 @@ display: inline-block; font-size: large; font-weight: 700; + font-family: var(--bm-font-display); + letter-spacing: 0.08em; + color: rgba(18, 35, 64, 0.96); +} + +/* Paragraphs */ +.bm-window p { + color: var(--bm-text-secondary); + line-height: 1.5; + letter-spacing: 0.035em; +} + +/* Horizontal dividers */ +.bm-window hr { + border: none; + height: 1px; + margin: 0.32rem 0; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.28), transparent); } /* Container with a vertically centered header 1-6 */ @@ -135,42 +222,139 @@ /* Containers for "sections" of elements */ .bm-container { - margin: 0.5em 0; + margin: 0.24em 0; +} + +/* Shared form controls */ +.bm-window input, +.bm-window select, +.bm-window textarea, +.bm-window button { + font: inherit; } /* All window buttons */ .bm-window button { - background-color: #144eb9; - border-radius: 1em; - padding: 0 0.75ch; + appearance: none; + color: var(--bm-text-primary); + font-family: var(--bm-font-display); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.22), rgba(164, 208, 255, 0.14)); + border: 1px solid rgba(255, 255, 255, 0.22); + border-radius: 999px; + padding: 0.28em 0.62em; + min-height: 1.78em; + font-weight: 600; + letter-spacing: 0.1em; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.22), + 0 8px 20px rgba(0, 0, 0, 0.1); + transition: + background 180ms ease, + border-color 180ms ease, + box-shadow 180ms ease, + filter 180ms ease, + opacity 180ms ease, + transform 180ms ease; } /* All window buttons when hovered/focused */ -.bm-window button:hover, .bm-window button:focus-visible { - background-color: #1061e5; +.bm-window button:hover, +.bm-window button:focus-visible { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.28), rgba(186, 246, 255, 0.18)); + border-color: rgba(230, 245, 255, 0.36); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.26), + 0 10px 22px rgba(0, 0, 0, 0.12); + transform: translateY(-1px); } -/* All window buttons when pressed (plus disabled color) */ -.bm-window button:active, -.bm-window button:disabled { - background-color: #2e97ff; +/* Focus ring */ +.bm-window button:focus-visible, +.bm-window input:focus-visible, +.bm-window select:focus-visible, +.bm-window textarea:focus-visible { + outline: none; + border-color: rgba(116, 231, 255, 0.62); + box-shadow: + 0 0 0 3px rgba(116, 231, 255, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.12); +} + +/* All window buttons when pressed */ +.bm-window button:active { + transform: translateY(0) scale(0.98); + filter: brightness(0.98); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.12), + 0 8px 16px rgba(18, 36, 78, 0.24); } /* All window buttons when disabled */ -.bm-window button:disabled, .bm-window button:disabled { - text-decoration: line-through; +.bm-window button:disabled { + opacity: 0.56; cursor: not-allowed; + text-decoration: none; + transform: none; + filter: saturate(0.72); + box-shadow: none; +} + +/* Button variants */ +.bm-window button.bm-button-primary { + color: #07203b; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.42), rgba(186, 246, 255, 0.34)); + border-color: rgba(239, 248, 255, 0.42); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.44), + 0 10px 22px rgba(129, 182, 255, 0.14); +} + +.bm-window button.bm-button-primary:hover, +.bm-window button.bm-button-primary:focus-visible { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.52), rgba(204, 250, 255, 0.36)); +} + +.bm-window button.bm-button-secondary { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.08)); + border-color: rgba(255, 255, 255, 0.18); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.14), + 0 8px 20px rgba(0, 0, 0, 0.08); +} + +.bm-window button.bm-button-secondary:hover, +.bm-window button.bm-button-secondary:focus-visible { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.24), rgba(186, 246, 255, 0.12)); } /* Icon buttons (single character text content buttons) */ .bm-button-circle { - border: white 1px solid; - height: 1.5em; - width: 1.5em; - margin-top: 2px; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid rgba(255, 255, 255, 0.16); + inline-size: 1.62rem; + block-size: 1.62rem; + min-height: 1.62rem !important; + min-width: 1.62rem; + margin-top: 0; text-align: center; - line-height: 1em; - padding: 0 !important; /* Overrides the padding in ".bm-window button" */ + line-height: 1; + padding: 0 !important; + aspect-ratio: 1 / 1; + border-radius: 50% !important; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.24), rgba(255, 255, 255, 0.1)) !important; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.18), + 0 8px 18px rgba(0, 0, 0, 0.1) !important; + overflow: hidden; + flex: 0 0 auto; + font-size: 0.74rem; +} + +.bm-button-circle svg { + width: 70%; + height: 70%; } /* Pin button */ @@ -187,39 +371,52 @@ /* Transparent buttons */ .bm-window button.bm-button-trans { - background-color: unset; + background: transparent !important; + box-shadow: none !important; + border-color: transparent !important; } /* Transparent buttons on dark backgrounds when hovered */ .bm-button-trans.bm-button-hover-white:hover, .bm-button-trans.bm-button-hover-white:focus { - background-color: rgba(255, 255, 255, 0.17); + background-color: rgba(255, 255, 255, 0.18) !important; } /* Transparent buttons on dark backgrounds when pressed */ .bm-button-trans.bm-button-hover-white:active { - background-color: rgba(255, 255, 255, 0.22); + background-color: rgba(255, 255, 255, 0.24) !important; } /* Transparent buttons on light backgrounds when hovered */ .bm-button-trans.bm-button-hover-black:hover, .bm-button-trans.bm-button-hover-black:focus { - background-color: rgba(0, 0, 0, 0.17); + background-color: rgba(0, 0, 0, 0.14) !important; } /* Transparent buttons on light backgrounds when pressed */ .bm-button-trans.bm-button-hover-black:active { - background-color: rgba(0, 0, 0, 0.22); + background-color: rgba(0, 0, 0, 0.2) !important; +} + +/* Shared inputs */ +.bm-window input[type="number"], +.bm-window select, +.bm-window textarea { + color: var(--bm-text-primary); + font-family: var(--bm-font-body); + background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.06)); + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 12px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12); } /* Tile (x, y) & Pixel (x, y) input fields */ input[type="number"].bm-input-coords { appearance: auto; -moz-appearance: textfield; - width: 5.5ch; + width: 5.9ch; margin-left: 1ch; - background-color: rgba(0, 0, 0, 0.2); - padding: 0 0.5ch; + padding: 0.2em 0.35ch; font-size: small; } @@ -255,10 +452,7 @@ input[type="file"] { /* Dropdown selection & dropdown (::picker) menus */ .bm-window select { - color: white; - background-color: #144eb9; - border-radius: 1em; - padding: 0 0.5ch; + padding: 0.22em 0.45ch; } /* Checkbox container (the label element) */ @@ -266,11 +460,14 @@ input[type="file"] { display: flex; width: fit-content; gap: 1ch; + align-items: center; + color: var(--bm-text-secondary); } /* Checkbox */ .bm-window input[type="checkbox"] { width: 1em; + accent-color: #74e7ff; } /* Window content container */ @@ -283,21 +480,31 @@ input[type="file"] { /* Text areas */ .bm-window textarea { font-size: small; - background-color: rgba(0, 0, 0, 0.2); - padding: 0 0.5ch; - height: 5.25em; + padding: 0.38em 0.52em; + height: 4em; width: 100%; + resize: vertical; + line-height: 1.45; +} + +.bm-window textarea::placeholder, +.bm-window input::placeholder { + color: rgba(47, 68, 102, 0.6); } /* Anchor/Links with no children */ .bm-window a:not(:has(*)) { + color: rgba(21, 88, 164, 0.94); text-decoration: underline; + text-decoration-color: rgba(21, 88, 164, 0.35); } /* Small elements */ .bm-window small { font-size: x-small; - color: lightgray; + font-family: var(--bm-font-display); + letter-spacing: 0.12em; + color: var(--bm-text-secondary); } /* List items of unordered lists */ @@ -310,6 +517,25 @@ input[type="file"] { .bm-window .bm-container.bm-scrollable { max-height: var(--bm-scrollable-max-height, calc(80vh - 150px)); overflow: auto; + scrollbar-width: thin; + scrollbar-color: rgba(146, 221, 255, 0.42) rgba(255, 255, 255, 0.05); +} + +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar-thumb { + background: linear-gradient(180deg, rgba(116, 231, 255, 0.48), rgba(83, 141, 255, 0.4)); + border-radius: 999px; + border: 2px solid transparent; + background-clip: padding-box; +} + +.bm-window .bm-container.bm-scrollable::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.04); + border-radius: 999px; } /* Flex children space between */ @@ -318,7 +544,7 @@ input[type="file"] { align-content: center; justify-content: space-between; align-items: center; - gap: 0.5ch; + gap: 0.35ch; } /* Flex children space center */ @@ -327,7 +553,7 @@ input[type="file"] { align-content: center; justify-content: center; align-items: center; - gap: 0.5ch; + gap: 0.35ch; } /* ASCII Art */ @@ -344,9 +570,8 @@ input[type="file"] { /* Containers for "sections" of elements in windowed mode */ /* Does not apply to the main window */ .bm-windowed .bm-container:not(#bm-window-main .bm-container) { - margin-top: 0.25em; - margin-bottom: 0.25em; - /* Do not use 'margin' shorthand, as it will override left/right margin */ + margin-top: 0.18em; + margin-bottom: 0.18em; } /* Header 1 in windowed mode */