From 803fb97f97285badcd3bc0562c485e1e7a71f13b Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Apr 2026 22:51:30 +0500 Subject: [PATCH] Release 0.92.1 --- build/build.js | 31 ++ dist/BlueMarble-For-GreasyFork.user.css | 464 ++++++++++++++---------- dist/BlueMarble-For-GreasyFork.user.js | 400 +++++++++++++++++++- dist/BlueMarble-Standalone.user.js | 6 +- dist/BlueMarble.user.css | 4 +- dist/BlueMarble.user.js | 6 +- package-lock.json | 8 +- package.json | 2 +- src/BlueMarble.meta.js | 2 +- src/Overlay.js | 142 +++++++- src/WindowFilter.css | 92 ++++- src/WindowFilter.js | 254 ++++++++++++- src/WindowMain.js | 4 +- src/overlay.css | 8 +- src/settingsManager.js | 22 +- 15 files changed, 1196 insertions(+), 249 deletions(-) diff --git a/build/build.js b/build/build.js index 488e83b..d21237a 100644 --- a/build/build.js +++ b/build/build.js @@ -10,6 +10,7 @@ // ES Module imports import esbuild from 'esbuild'; +import crypto from 'crypto'; import fs from 'fs'; import { execSync } from 'child_process'; import { consoleStyle } from './utils.js'; @@ -22,6 +23,24 @@ const terser = require('terser'); const isGitHub = !!process.env?.GITHUB_ACTIONS; // Is this running in a GitHub Action Workflow?' +/** Appends a build hash comment to an output file. + * The hash is based on the file contents before the hash comment is added. + * @param {string} path - Path to the file + * @param {'js' | 'css'} type - Output type for comment syntax + * @returns {string} The short build hash + * @since 0.92.0 + */ +function appendBuildHashComment(path, type = 'js') { + const content = fs.readFileSync(path, 'utf8').trimEnd(); + const hash = crypto.createHash('sha256').update(content, 'utf8').digest('hex').slice(0, 12); + const comment = (type == 'css') + ? `/* Build Hash: ${hash} */` + : `// Build Hash: ${hash}`; + + fs.writeFileSync(path, `${content}\n\n${comment}\n`, 'utf8'); + return hash; +} + console.log(`${consoleStyle.BLUE}Starting build...${consoleStyle.RESET}`); // Tries to build the wiki if build.js is run in a GitHub Workflow @@ -214,4 +233,16 @@ esbuild.build({ fs.writeFileSync(`dist/${greasyForkName}.user.js`, greasyForkBMjs, 'utf-8'); +const buildHashes = { + 'BlueMarble.user.css': appendBuildHashComment('dist/BlueMarble.user.css', 'css'), + 'BlueMarble.user.js': appendBuildHashComment('dist/BlueMarble.user.js', 'js'), + [`${standaloneName}.user.js`]: appendBuildHashComment(`dist/${standaloneName}.user.js`, 'js'), + [`${greasyForkName}.user.css`]: appendBuildHashComment(`dist/${greasyForkName}.user.css`, 'css'), + [`${greasyForkName}.user.js`]: appendBuildHashComment(`dist/${greasyForkName}.user.js`, 'js') +}; + console.log(`${consoleStyle.GREEN + consoleStyle.BOLD + consoleStyle.UNDERLINE}Building complete!${consoleStyle.RESET}`); +console.log(`Build hashes:`); +for (const [file, hash] of Object.entries(buildHashes)) { + console.log(`- ${file}: ${hash}`); +} diff --git a/dist/BlueMarble-For-GreasyFork.user.css b/dist/BlueMarble-For-GreasyFork.user.css index bb285a5..6accc48 100644 --- a/dist/BlueMarble-For-GreasyFork.user.css +++ b/dist/BlueMarble-For-GreasyFork.user.css @@ -1,192 +1,3 @@ -/* src/WindowFilter.css */ -#bm-window-filter p svg { - display: inline; - height: 1em; - fill: white; -} -#bm-filter-flex { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; - gap: 1em 3ch; -} -#bm-window-filter .bm-filter-color { - 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; -} -#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-container-rgb { - display: block; - border: thick double darkslategray; - width: fit-content; - height: fit-content; - padding: 1ch; -} -#bm-window-filter .bm-filter-color[data-id="-2"] .bm-filter-container-rgb { - background: - conic-gradient( - #aa0000 0%, - #aaaa00 16.6%, - #00aa00 33.3%, - #00aaaa 50%, - #0000aa 66.6%, - #aa00aa 83.3%, - #aa0000 100%); -} -#bm-window-filter .bm-filter-color[data-id="-1"] .bm-filter-container-rgb { - 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; -} -#bm-window-filter .bm-filter-color[data-id="0"] .bm-filter-container-rgb { - background-color: transparent !important; -} -#bm-window-filter .bm-filter-container-rgb button { - padding: 0.75em 0.5ch; -} -#bm-window-filter .bm-filter-container-rgb svg { - width: 4ch; -} -#bm-window-filter .bm-filter-color > .bm-flex-between { - flex-direction: column; - align-items: flex-start; - gap: 0; -} -#bm-window-filter .bm-filter-color small { - font-size: 0.75em; -} -#bm-window-filter .bm-filter-color.bm-color-hide { - display: none; -} -#bm-window-filter.bm-windowed #bm-filter-flex { - flex-direction: column; - gap: 0.25em; -} -#bm-window-filter.bm-windowed .bm-filter-color { - width: auto; - margin: 0; - padding: 0; -} -#bm-window-filter.bm-windowed .bm-filter-container-rgb { - display: flex; - width: 100%; - gap: 0.5ch; - align-items: center; - padding: 0.1em 0.5ch; - border: none; - border-radius: 1em; -} -#bm-window-filter.bm-windowed .bm-filter-container-rgb button { - padding: 0.5em 0.25ch; -} -#bm-window-filter.bm-windowed .bm-filter-container-rgb svg { - width: 3ch; -} -#bm-window-filter.bm-windowed .bm-filter-color h2 { - font-size: 0.75em; -} -#bm-window-filter #bm-filter-windowed-color-totals { - font-size: 1em; -} - -/* src/WindowSettings.css */ -#bm-window-settings div:has(> .bm-highlight-preset-container) { - width: fit-content; - justify-content: flex-start; -} -#bm-window-settings .bm-highlight-preset-container { - display: flex; - flex-direction: column; - width: 13%; -} -#bm-window-settings .bm-highlight-preset-container span { - width: fit-content; - margin: auto; - font-size: 0.7em; -} -#bm-window-settings .bm-highlight-preset-container button { - width: fit-content; - padding: 0; - border-radius: 0; -} -#bm-window-settings .bm-highlight-preset-container svg { - stroke: #333; - stroke-width: 0.02px; - width: 100%; - min-width: 1.5ch; - max-width: 14.5ch; -} -#bm-window-settings .bm-highlight-preset-container button:hover svg, -#bm-window-settings .bm-highlight-preset-container button:focus svg { - opacity: 0.9; -} -#bm-window-settings .bm-highlight-grid { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - width: 25%; - min-width: 3ch; - max-width: 15ch; -} -#bm-window-settings .bm-highlight-grid > button { - width: 100%; - padding: 0; - aspect-ratio: 1 / 1; - background-color: white; - border: #333 1px solid; - border-radius: 0; - box-sizing: border-box; -} -#bm-window-settings .bm-highlight-grid > button[data-status=Incorrect] { - background-color: brown; -} -#bm-window-settings .bm-highlight-grid > button[data-status=Template] { - background-color: darkslategray; -} -#bm-window-settings .bm-highlight-grid > button:hover, -#bm-window-settings .bm-highlight-grid > button:focus { - opacity: 0.8; -} - -/* src/WindowWizard.css */ -#bm-wizard-tlist { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: flex-start; -} -#bm-wizard-tlist > .bm-container { - width: 100%; - justify-content: flex-start; - background-color: rgba(21, 48, 99, 0.9); - border-radius: 1em; - padding: 0.5em; - transition: background-color 0.3s ease; -} -#bm-wizard-tlist > .bm-container:hover, -#bm-wizard-tlist > .bm-container:focus-within { - background-color: rgba(17, 40, 85, 0.9); -} -#bm-wizard-tlist .bm-wizard-template-container-image { - height: 100%; - font-size: xxx-large; -} -#bm-wizard-tlist .bm-wizard-template-container-flavor { - flex-direction: column; - align-items: flex-start; - gap: 0; -} - /* src/confettiManager.css */ div:has(> confetti-piece) { position: absolute; @@ -245,9 +56,6 @@ confetti-piece { "Arial"; letter-spacing: 0.05em; } -.bm-window.bm-windowed { - max-width: 300px; -} .bm-dragbar { display: grid; grid-template-columns: auto 1fr auto; @@ -423,6 +231,7 @@ input[type=file] { } .bm-window-content { overflow: hidden; + max-height: calc(100% - 5px); transition: height 300ms cubic-bezier(.4, 0, .2, 1); } .bm-window textarea { @@ -444,7 +253,7 @@ input[type=file] { margin-left: 5ch; } .bm-window .bm-container.bm-scrollable { - max-height: calc(80vh - 150px); + max-height: var(--bm-scrollable-max-height, calc(80vh - 150px)); overflow: auto; } .bm-flex-between { @@ -476,4 +285,273 @@ input[type=file] { font-size: 1em; } +/* src/WindowFilter.css */ +#bm-window-filter p svg { + display: inline; + height: 1em; + fill: white; +} +#bm-filter-flex { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + gap: 1em 3ch; +} +#bm-window-filter .bm-filter-color { + 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; +} +#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-container-rgb { + display: block; + border: thick double darkslategray; + width: fit-content; + height: fit-content; + padding: 1ch; +} +#bm-window-filter .bm-filter-color[data-id="-2"] .bm-filter-container-rgb { + background: + conic-gradient( + #aa0000 0%, + #aaaa00 16.6%, + #00aa00 33.3%, + #00aaaa 50%, + #0000aa 66.6%, + #aa00aa 83.3%, + #aa0000 100%); +} +#bm-window-filter .bm-filter-color[data-id="-1"] .bm-filter-container-rgb { + 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; +} +#bm-window-filter .bm-filter-color[data-id="0"] .bm-filter-container-rgb { + background-color: transparent !important; +} +#bm-window-filter .bm-filter-container-rgb button { + padding: 0.75em 0.5ch; +} +#bm-window-filter .bm-filter-container-rgb svg { + width: 4ch; +} +#bm-window-filter .bm-filter-color > .bm-flex-between { + flex-direction: column; + align-items: flex-start; + gap: 0; +} +#bm-window-filter .bm-filter-color small { + font-size: 0.75em; +} +#bm-window-filter .bm-filter-color.bm-color-hide { + display: none; +} +#bm-window-filter.bm-windowed { + --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; + 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-window-filter.bm-windowed .bm-window-content { + display: grid; + grid-template-rows: auto auto auto minmax(0, 1fr); + grid-row: 2; + min-height: 0; + min-width: 0; + overflow: hidden; +} +#bm-window-filter.bm-windowed #bm-filter-flex { + flex-direction: column; + align-items: stretch; + gap: 0.25em; + width: 100%; + align-self: stretch; + min-width: 0; + box-sizing: border-box; +} +#bm-window-filter.bm-windowed .bm-filter-color { + width: 100%; + max-width: none; + align-self: stretch; + flex: 1 1 auto; + min-width: 0; + margin: 0; + padding: 0; + box-sizing: border-box; +} +#bm-window-filter.bm-windowed .bm-filter-color > .bm-flex-between { + width: 100%; + min-width: 0; + flex: 1 1 auto; +} +#bm-window-filter.bm-windowed .bm-container.bm-scrollable { + 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-window-filter.bm-windowed .bm-resize-corner { + 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-window-filter.bm-windowed .bm-resize-corner:hover, +#bm-window-filter.bm-windowed .bm-resize-corner.bm-resizing { + opacity: 1; +} +#bm-window-filter.bm-windowed .bm-filter-container-rgb { + display: flex; + width: 100%; + min-width: 0; + flex: 1 1 auto; + gap: 0.5ch; + align-items: center; + padding: 0.1em 0.5ch; + border: none; + border-radius: 1em; + box-sizing: border-box; +} +#bm-window-filter.bm-windowed .bm-filter-container-rgb button { + padding: 0.5em 0.25ch; + flex: 0 0 auto; +} +#bm-window-filter.bm-windowed .bm-filter-container-rgb svg { + width: 3ch; +} +#bm-window-filter.bm-windowed .bm-filter-color h2 { + font-size: 0.75em; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +#bm-window-filter #bm-filter-windowed-color-totals { + font-size: 1em; +} + +/* src/WindowSettings.css */ +#bm-window-settings div:has(> .bm-highlight-preset-container) { + width: fit-content; + justify-content: flex-start; +} +#bm-window-settings .bm-highlight-preset-container { + display: flex; + flex-direction: column; + width: 13%; +} +#bm-window-settings .bm-highlight-preset-container span { + width: fit-content; + margin: auto; + font-size: 0.7em; +} +#bm-window-settings .bm-highlight-preset-container button { + width: fit-content; + padding: 0; + border-radius: 0; +} +#bm-window-settings .bm-highlight-preset-container svg { + stroke: #333; + stroke-width: 0.02px; + width: 100%; + min-width: 1.5ch; + max-width: 14.5ch; +} +#bm-window-settings .bm-highlight-preset-container button:hover svg, +#bm-window-settings .bm-highlight-preset-container button:focus svg { + opacity: 0.9; +} +#bm-window-settings .bm-highlight-grid { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + width: 25%; + min-width: 3ch; + max-width: 15ch; +} +#bm-window-settings .bm-highlight-grid > button { + width: 100%; + padding: 0; + aspect-ratio: 1 / 1; + background-color: white; + border: #333 1px solid; + border-radius: 0; + box-sizing: border-box; +} +#bm-window-settings .bm-highlight-grid > button[data-status=Incorrect] { + background-color: brown; +} +#bm-window-settings .bm-highlight-grid > button[data-status=Template] { + background-color: darkslategray; +} +#bm-window-settings .bm-highlight-grid > button:hover, +#bm-window-settings .bm-highlight-grid > button:focus { + opacity: 0.8; +} + +/* src/WindowWizard.css */ +#bm-wizard-tlist { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; +} +#bm-wizard-tlist > .bm-container { + width: 100%; + justify-content: flex-start; + background-color: rgba(21, 48, 99, 0.9); + border-radius: 1em; + padding: 0.5em; + transition: background-color 0.3s ease; +} +#bm-wizard-tlist > .bm-container:hover, +#bm-wizard-tlist > .bm-container:focus-within { + background-color: rgba(17, 40, 85, 0.9); +} +#bm-wizard-tlist .bm-wizard-template-container-image { + height: 100%; + font-size: xxx-large; +} +#bm-wizard-tlist .bm-wizard-template-container-flavor { + flex-direction: column; + align-items: flex-start; + gap: 0; +} + /* src/main.css */ + +/* Build Hash: 4336138174a3 */ diff --git a/dist/BlueMarble-For-GreasyFork.user.js b/dist/BlueMarble-For-GreasyFork.user.js index 6eaa865..3e3c89b 100644 --- a/dist/BlueMarble-For-GreasyFork.user.js +++ b/dist/BlueMarble-For-GreasyFork.user.js @@ -2,14 +2,14 @@ // @name Blue Marble // @name:en Blue Marble // @namespace https://github.com/SwingTheVine/ -// @version 0.92.0 +// @version 0.92.1 // @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @author SwingTheVine // @license MPL-2.0 // @supportURL https://discord.gg/tpeBPy46hf // @homepageURL https://bluemarble.lol/ -// @icon https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/78477321232b29c09e3794c360068d7d23a0172c/dist/assets/Favicon.png +// @icon https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/2cd51bf91944ae2acb253ea5bbd76f79b7a2edd3/dist/assets/Favicon.png // @updateURL https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/BlueMarble-For-GreasyFork.user.js // @downloadURL https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/BlueMarble-For-GreasyFork.user.js // @match https://wplace.live/* @@ -21,7 +21,7 @@ // @grant GM_xmlhttpRequest // @grant GM.download // @connect telemetry.thebluecorner.net -// @resource CSS-BM-File https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/78477321232b29c09e3794c360068d7d23a0172c/dist/BlueMarble-For-GreasyFork.user.css +// @resource CSS-BM-File https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/2cd51bf91944ae2acb253ea5bbd76f79b7a2edd3/dist/BlueMarble-For-GreasyFork.user.css // @antifeature tracking Anonymous opt-in telemetry data // @noframes // ==/UserScript== @@ -1366,9 +1366,11 @@ * @param {string} iMoveThingsSelector - The drag handle element * @since 0.8.2 */ - handleDrag(moveMeSelector, iMoveThingsSelector) { + handleDrag(moveMeSelector, iMoveThingsSelector, options = {}) { const moveMe = document.querySelector(moveMeSelector); const iMoveThings = document.querySelector(iMoveThingsSelector); + const onEnd = options?.onEnd ?? (() => { + }); if (!moveMe || !iMoveThings) { this.handleDisplayError(`Can not drag! ${!moveMe ? "moveMe" : ""} ${!moveMe && !iMoveThings ? "and " : ""}${!iMoveThings ? "iMoveThings " : ""}was not found!`); return; @@ -1438,6 +1440,12 @@ document.removeEventListener("mouseup", endDrag); document.removeEventListener("touchend", endDrag); document.removeEventListener("touchcancel", endDrag); + onEnd({ + element: moveMe, + x: currentX, + y: currentY + }); + initialRect = null; }; const onMouseMove = (event) => { if (isDragging && initialRect) { @@ -1467,6 +1475,124 @@ event.preventDefault(); }, { passive: false }); } + /** Handles resizing of an overlay window from a resize handle. + * @param {string} resizeMeSelector - The element to resize + * @param {string} iResizeThingsSelector - The resize handle element + * @param {{onEnd?: function({element: HTMLElement, width: number, height: number}): void, minWidth?: number, minHeight?: number, maxWidth?: number, maxHeight?: number}} [options={}] + * @since 0.92.0 + */ + handleResize(resizeMeSelector, iResizeThingsSelector, options = {}) { + const resizeMe = document.querySelector(resizeMeSelector); + const iResizeThings = document.querySelector(iResizeThingsSelector); + const onEnd = options?.onEnd ?? (() => { + }); + if (!resizeMe || !iResizeThings) { + this.handleDisplayError(`Can not resize! ${!resizeMe ? "resizeMe" : ""} ${!resizeMe && !iResizeThings ? "and " : ""}${!iResizeThings ? "iResizeThings " : ""}was not found!`); + return; + } + let isResizing = false; + let startX = 0; + let startY = 0; + let startWidth = 0; + let startHeight = 0; + let currentWidth = 0; + let currentHeight = 0; + let targetWidth = 0; + let targetHeight = 0; + let animationFrame = null; + const getMaximumWidth = () => Number.isFinite(options?.maxWidth) ? options.maxWidth : window.innerWidth - 16; + const getMaximumHeight = () => Number.isFinite(options?.maxHeight) ? options.maxHeight : window.innerHeight - 16; + const minimumWidth = Number.isFinite(options?.minWidth) ? options.minWidth : 200; + const minimumHeight = Number.isFinite(options?.minHeight) ? options.minHeight : 160; + const clamp = (value, minimum, maximum) => Math.min(Math.max(value, minimum), Math.max(minimum, maximum)); + const updateSize = () => { + if (isResizing) { + const deltaWidth = Math.abs(currentWidth - targetWidth); + const deltaHeight = Math.abs(currentHeight - targetHeight); + if (deltaWidth > 0.5 || deltaHeight > 0.5) { + currentWidth = targetWidth; + currentHeight = targetHeight; + resizeMe.style.width = `${currentWidth}px`; + resizeMe.style.height = `${currentHeight}px`; + } + animationFrame = requestAnimationFrame(updateSize); + } + }; + const startResize = (clientX, clientY) => { + isResizing = true; + startX = clientX; + startY = clientY; + startWidth = resizeMe.offsetWidth; + startHeight = resizeMe.offsetHeight; + currentWidth = startWidth; + currentHeight = startHeight; + targetWidth = startWidth; + targetHeight = startHeight; + document.body.style.userSelect = "none"; + iResizeThings.classList.add("bm-resizing"); + document.addEventListener("mousemove", onMouseMove); + document.addEventListener("touchmove", onTouchMove, { passive: false }); + document.addEventListener("mouseup", endResize); + document.addEventListener("touchend", endResize); + document.addEventListener("touchcancel", endResize); + if (animationFrame) { + cancelAnimationFrame(animationFrame); + } + updateSize(); + }; + const endResize = () => { + isResizing = false; + if (animationFrame) { + cancelAnimationFrame(animationFrame); + animationFrame = null; + } + document.body.style.userSelect = ""; + iResizeThings.classList.remove("bm-resizing"); + document.removeEventListener("mousemove", onMouseMove); + document.removeEventListener("touchmove", onTouchMove); + document.removeEventListener("mouseup", endResize); + document.removeEventListener("touchend", endResize); + document.removeEventListener("touchcancel", endResize); + onEnd({ + element: resizeMe, + width: currentWidth, + height: currentHeight + }); + }; + const onMouseMove = (event) => { + if (!isResizing) { + return; + } + targetWidth = clamp(startWidth + (event.clientX - startX), minimumWidth, getMaximumWidth()); + targetHeight = clamp(startHeight + (event.clientY - startY), minimumHeight, getMaximumHeight()); + }; + const onTouchMove = (event) => { + if (!isResizing) { + return; + } + const touch = event?.touches?.[0]; + if (!touch) { + return; + } + targetWidth = clamp(startWidth + (touch.clientX - startX), minimumWidth, getMaximumWidth()); + targetHeight = clamp(startHeight + (touch.clientY - startY), minimumHeight, getMaximumHeight()); + event.preventDefault(); + }; + iResizeThings.addEventListener("mousedown", (event) => { + event.preventDefault(); + event.stopPropagation(); + startResize(event.clientX, event.clientY); + }); + iResizeThings.addEventListener("touchstart", (event) => { + const touch = event?.touches?.[0]; + if (!touch) { + return; + } + event.preventDefault(); + event.stopPropagation(); + startResize(touch.clientX, touch.clientY); + }, { passive: false }); + } /** Handles status display. * This will output plain text into the output Status box. * Additionally, this will output an info message to the console. @@ -1637,15 +1763,28 @@ * @since 0.91.39 */ async updateUserStorage() { + await this.saveUserStorage(); + } + /** Saves the user settings in userscript storage. + * @param {boolean} [force=false] - Should the throttle be ignored? + * @since 0.92.0 + */ + async saveUserStorage(force = false) { const userSettingsCurrent = JSON.stringify(this.userSettings); const userSettingsOld = JSON.stringify(this.userSettingsOld); - if (userSettingsCurrent != userSettingsOld && Date.now() - this.lastUpdateTime > this.updateFrequency) { + if (userSettingsCurrent != userSettingsOld && (force || Date.now() - this.lastUpdateTime > this.updateFrequency)) { await GM.setValue(this.userSettingsSaveLocation, userSettingsCurrent); this.userSettingsOld = structuredClone(this.userSettings); this.lastUpdateTime = Date.now(); console.log(userSettingsCurrent); } } + /** Immediately saves the user settings in userscript storage. + * @since 0.92.0 + */ + async saveUserStorageNow() { + await this.saveUserStorage(true); + } /** Toggles a boolean flag to the state that was passed in. * If no state was passed in, the flag will flip to the opposite state. * The existence of the flag determines its state. If it exists, it is `true`. @@ -2219,7 +2358,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; // src/WindowFilter.js - var _WindowFilter_instances, buildColorList_fn, sortColorList_fn, selectColorList_fn, calculatePixelStatistics_fn; + var _WindowFilter_instances, getWindowState_fn, setWindowModePreference_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 = class extends Overlay { /** Constructor for the color filter window * @param {*} executor - The executing class @@ -2233,6 +2372,16 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); this.windowID = "bm-window-filter"; this.colorListID = "bm-filter-flex"; this.windowParent = document.body; + this.settingsManager = executor.settingsManager ?? null; + this.windowModeFlag = "ftr-oWin"; + this.windowStateKey = "windowFilter"; + this.windowResizeObserver = null; + this.windowViewportResizeHandler = null; + this.windowSaveTimeout = null; + this.windowMinWidth = 260; + this.windowMinHeight = 220; + this.windowMaxWidth = 1e3; + this.windowMaxHeight = 1400; this.templateManager = executor.apiManager?.templateManager; this.eyeOpen = ''; this.eyeClosed = ''; @@ -2250,6 +2399,16 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); this.sortSecondary = "ascending"; this.showUnused = false; } + /** Builds the preferred filter window mode for the user. + * @since 0.92.0 + */ + buildPreferredWindow() { + if (this.settingsManager?.userSettings?.flags?.includes(this.windowModeFlag)) { + this.buildWindowed(); + return; + } + this.buildWindow(); + } /** Spawns a Color Filter window. * If another color filter window already exists, we DON'T spawn another! * Parent/child relationships in the DOM structure below are indicated by indentation. @@ -2257,7 +2416,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); */ buildWindow() { if (document.querySelector(`#${this.windowID}`)) { - document.querySelector(`#${this.windowID}`).remove(); + __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); return; } this.window = this.addDiv({ "id": this.windowID, "class": "bm-window" }, (instance, div) => { @@ -2268,16 +2427,15 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; }).buildElement().addDiv().buildElement().addDiv({ "class": "bm-flex-center" }).addButton({ "class": "bm-button-circle", "textContent": "\u{1F5D7}", "aria-label": 'Switch to windowed mode for "Color Filter"' }, (instance, button) => { button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); + __privateMethod(this, _WindowFilter_instances, setWindowModePreference_fn).call(this, true); + __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); this.buildWindowed(); }; button.ontouchend = () => { button.click(); }; }).buildElement().addButton({ "class": "bm-button-circle", "textContent": "\u2716", "aria-label": 'Close window "Color Filter"' }, (instance, button) => { - button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); - }; + button.onclick = () => __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); button.ontouchend = () => { button.click(); }; @@ -2320,10 +2478,14 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); */ buildWindowed() { if (document.querySelector(`#${this.windowID}`)) { - document.querySelector(`#${this.windowID}`).remove(); + __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); return; } - this.window = this.addDiv({ "id": this.windowID, "class": "bm-window bm-windowed" }).addDragbar().addButton({ "class": "bm-button-circle", "textContent": "\u25BC", "aria-label": 'Minimize window "Color Filter"', "data-button-status": "expanded" }, (instance, button) => { + this.window = this.addDiv({ + "id": this.windowID, + "class": "bm-window bm-windowed", + "style": `width: 300px; height: min(70vh, 32rem); min-width: ${this.windowMinWidth}px; min-height: ${this.windowMinHeight}px; max-width: min(${this.windowMaxWidth}px, calc(100vw - 16px)); max-height: min(${this.windowMaxHeight}px, calc(100vh - 16px));` + }).addDragbar().addButton({ "class": "bm-button-circle", "textContent": "\u25BC", "aria-label": 'Minimize window "Color Filter"', "data-button-status": "expanded" }, (instance, button) => { button.onclick = () => { const windowedColorTotals = document.querySelector("#bm-filter-windowed-color-totals"); if (windowedColorTotals) { @@ -2336,16 +2498,15 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; }).buildElement().addDiv().addSpan({ "id": "bm-filter-windowed-color-totals", "class": "bm-dragbar-text", "style": "font-weight: 700;" }).buildElement().buildElement().addDiv({ "class": "bm-flex-center" }).addButton({ "class": "bm-button-circle", "textContent": "\u{1F5D6}", "aria-label": 'Switch to fullscreen mode for "Color Filter"' }, (instance, button) => { button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); + __privateMethod(this, _WindowFilter_instances, setWindowModePreference_fn).call(this, false); + __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); this.buildWindow(); }; button.ontouchend = () => { button.click(); }; }).buildElement().addButton({ "class": "bm-button-circle", "textContent": "\u2716", "aria-label": 'Close window "Color Filter"' }, (instance, button) => { - button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); - }; + button.onclick = () => __privateMethod(this, _WindowFilter_instances, closeWindow_fn).call(this); button.ontouchend = () => { button.click(); }; @@ -2359,8 +2520,15 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); }; }).buildElement().addButton({ "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().buildElement().buildOverlay(this.windowParent); - this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`); + }).buildElement().buildElement().addDiv({ "class": "bm-container bm-scrollable" }).buildElement().buildElement().addDiv({ + "class": "bm-resize-corner", + "title": "Resize Color Filter window", + "aria-label": "Resize Color Filter window", + "role": "presentation", + "textContent": "\u25E2", + "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;" + }).buildElement().buildElement().buildOverlay(this.windowParent); + __privateMethod(this, _WindowFilter_instances, initializeWindowedPersistence_fn).call(this); const scrollableContainer = document.querySelector(`#${this.windowID} .bm-container.bm-scrollable`); __privateMethod(this, _WindowFilter_instances, buildColorList_fn).call(this, scrollableContainer); __privateMethod(this, _WindowFilter_instances, sortColorList_fn).call(this, this.sortPrimary, this.sortSecondary, this.showUnused); @@ -2445,6 +2613,196 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`); } }; _WindowFilter_instances = new WeakSet(); + /** Retrieves the persisted window state object. + * @returns {Object | null} + * @since 0.92.0 + */ + getWindowState_fn = function() { + var _a, _b; + if (!this.settingsManager) { + return null; + } + (_a = this.settingsManager.userSettings)[_b = this.windowStateKey] ?? (_a[_b] = {}); + return this.settingsManager.userSettings[this.windowStateKey]; + }; + /** Updates the preferred window mode setting. + * @param {boolean} shouldBeWindowed + * @since 0.92.0 + */ + setWindowModePreference_fn = function(shouldBeWindowed) { + if (!this.settingsManager) { + return; + } + this.settingsManager.toggleFlag(this.windowModeFlag, shouldBeWindowed); + void this.settingsManager.saveUserStorageNow(); + }; + /** Immediately closes the filter window and cleans up persistence observers. + * @since 0.92.0 + */ + closeWindow_fn = function() { + const windowElement = document.querySelector(`#${this.windowID}`); + if (windowElement?.classList.contains("bm-windowed")) { + __privateMethod(this, _WindowFilter_instances, saveWindowState_fn).call(this, windowElement); + } + __privateMethod(this, _WindowFilter_instances, cleanupWindowPersistence_fn).call(this); + windowElement?.remove(); + }; + /** Disconnects live observers used for window persistence. + * @since 0.92.0 + */ + cleanupWindowPersistence_fn = function() { + if (this.windowResizeObserver) { + this.windowResizeObserver.disconnect(); + this.windowResizeObserver = null; + } + if (this.windowViewportResizeHandler) { + window.removeEventListener("resize", this.windowViewportResizeHandler); + this.windowViewportResizeHandler = null; + } + if (this.windowSaveTimeout) { + clearTimeout(this.windowSaveTimeout); + this.windowSaveTimeout = null; + } + }; + /** Returns a clamped dimension value for the window. + * @param {number} size - The size in pixels + * @param {number} minimum - Minimum allowed size + * @param {number} maximum - Maximum allowed size + * @returns {number} + * @since 0.92.0 + */ + clampWindowDimension_fn = function(size, minimum, maximum) { + const resolvedMaximum = Math.max(minimum, maximum); + return Math.min(Math.max(Math.round(Number(size) || minimum), minimum), resolvedMaximum); + }; + /** Returns a viewport-safe position for the window. + * @param {HTMLElement} windowElement + * @param {number} x + * @param {number} y + * @returns {{x: number, y: number}} + * @since 0.92.0 + */ + clampWindowPosition_fn = function(windowElement, x, y) { + const margin = 8; + const maxX = Math.max(margin, window.innerWidth - windowElement.offsetWidth - margin); + const maxY = Math.max(margin, window.innerHeight - windowElement.offsetHeight - margin); + return { + x: Math.min(Math.max(Math.round(Number(x) || margin), margin), maxX), + y: Math.min(Math.max(Math.round(Number(y) || margin), margin), maxY) + }; + }; + /** Applies the persisted size and position to the windowed filter. + * @param {HTMLElement} windowElement + * @since 0.92.0 + */ + restoreWindowState_fn = function(windowElement) { + const windowState = __privateMethod(this, _WindowFilter_instances, getWindowState_fn).call(this); + if (!windowState || !windowElement) { + return; + } + const width = Number(windowState.width); + const height = Number(windowState.height); + const hasWidth = Number.isFinite(width); + const hasHeight = Number.isFinite(height); + if (hasWidth) { + windowState.width = __privateMethod(this, _WindowFilter_instances, clampWindowDimension_fn).call(this, width, this.windowMinWidth, Math.min(this.windowMaxWidth, window.innerWidth - 16)); + windowElement.style.width = `${windowState.width}px`; + } + if (hasHeight) { + windowState.height = __privateMethod(this, _WindowFilter_instances, clampWindowDimension_fn).call(this, height, this.windowMinHeight, Math.min(this.windowMaxHeight, window.innerHeight - 16)); + windowElement.style.height = `${windowState.height}px`; + } + requestAnimationFrame(() => { + if (!windowElement.isConnected) { + return; + } + const x = Number(windowState.x); + const y = Number(windowState.y); + if (!Number.isFinite(x) || !Number.isFinite(y)) { + return; + } + const clampedPosition = __privateMethod(this, _WindowFilter_instances, clampWindowPosition_fn).call(this, windowElement, x, y); + windowElement.style.left = "0px"; + windowElement.style.top = "0px"; + windowElement.style.right = ""; + windowElement.style.transform = `translate(${clampedPosition.x}px, ${clampedPosition.y}px)`; + if (clampedPosition.x != x || clampedPosition.y != y) { + windowState.x = clampedPosition.x; + windowState.y = clampedPosition.y; + void this.settingsManager?.saveUserStorageNow(); + } + }); + }; + /** Saves the current size and position of the windowed filter. + * @param {HTMLElement} windowElement + * @since 0.92.0 + */ + saveWindowState_fn = function(windowElement) { + const windowState = __privateMethod(this, _WindowFilter_instances, getWindowState_fn).call(this); + if (!windowState || !windowElement?.isConnected || !windowElement.classList.contains("bm-windowed")) { + return; + } + const rect = windowElement.getBoundingClientRect(); + const width = __privateMethod(this, _WindowFilter_instances, clampWindowDimension_fn).call(this, rect.width, this.windowMinWidth, Math.min(this.windowMaxWidth, window.innerWidth - 16)); + const height = __privateMethod(this, _WindowFilter_instances, clampWindowDimension_fn).call(this, rect.height, this.windowMinHeight, Math.min(this.windowMaxHeight, window.innerHeight - 16)); + if (Math.round(rect.width) != width) { + windowElement.style.width = `${width}px`; + } + if (Math.round(rect.height) != height) { + windowElement.style.height = `${height}px`; + } + const clampedPosition = __privateMethod(this, _WindowFilter_instances, clampWindowPosition_fn).call(this, windowElement, rect.left, rect.top); + windowElement.style.left = "0px"; + windowElement.style.top = "0px"; + windowElement.style.right = ""; + windowElement.style.transform = `translate(${clampedPosition.x}px, ${clampedPosition.y}px)`; + windowState.x = clampedPosition.x; + windowState.y = clampedPosition.y; + windowState.width = width; + windowState.height = height; + void this.settingsManager?.saveUserStorageNow(); + }; + /** Debounces persisting the current window size and position. + * @param {HTMLElement} windowElement + * @param {number} [delay=150] + * @since 0.92.0 + */ + scheduleWindowStateSave_fn = function(windowElement, delay = 150) { + if (this.windowSaveTimeout) { + clearTimeout(this.windowSaveTimeout); + } + this.windowSaveTimeout = setTimeout(() => { + this.windowSaveTimeout = null; + __privateMethod(this, _WindowFilter_instances, saveWindowState_fn).call(this, windowElement); + }, delay); + }; + /** Enables persistence and resize handling for the windowed filter. + * @since 0.92.0 + */ + initializeWindowedPersistence_fn = function() { + const windowElement = document.querySelector(`#${this.windowID}.bm-window`); + if (!windowElement) { + return; + } + __privateMethod(this, _WindowFilter_instances, cleanupWindowPersistence_fn).call(this); + __privateMethod(this, _WindowFilter_instances, restoreWindowState_fn).call(this, windowElement); + this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`, { + onEnd: ({ element }) => __privateMethod(this, _WindowFilter_instances, saveWindowState_fn).call(this, element) + }); + this.handleResize(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-resize-corner`, { + minWidth: this.windowMinWidth, + minHeight: this.windowMinHeight, + maxWidth: Math.min(this.windowMaxWidth, window.innerWidth - 16), + maxHeight: Math.min(this.windowMaxHeight, window.innerHeight - 16), + onEnd: ({ element }) => __privateMethod(this, _WindowFilter_instances, saveWindowState_fn).call(this, element) + }); + if (typeof ResizeObserver == "function") { + this.windowResizeObserver = new ResizeObserver(() => __privateMethod(this, _WindowFilter_instances, scheduleWindowStateSave_fn).call(this, windowElement)); + this.windowResizeObserver.observe(windowElement); + } + this.windowViewportResizeHandler = () => __privateMethod(this, _WindowFilter_instances, scheduleWindowStateSave_fn).call(this, windowElement, 0); + window.addEventListener("resize", this.windowViewportResizeHandler); + }; /** Creates the color list container. * @param {HTMLElement} parentElement - Parent element to add the color list to as a child * @since 0.88.222 @@ -2977,7 +3335,7 @@ Version: ${this.version}`, "readOnly": true }).buildElement().buildElement().add */ buildWindowFilter_fn = function() { const windowFilter = new WindowFilter(this); - windowFilter.buildWindow(); + windowFilter.buildPreferredWindow(); }; coordinateInputPaste_fn = async function(instance, input, event) { event.preventDefault(); @@ -4014,3 +4372,5 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String observer.observe(document.body, { childList: true, subtree: true }); } })(); + +// Build Hash: f5ff285a601e diff --git a/dist/BlueMarble-Standalone.user.js b/dist/BlueMarble-Standalone.user.js index 8401e77..00ff70a 100644 --- a/dist/BlueMarble-Standalone.user.js +++ b/dist/BlueMarble-Standalone.user.js @@ -2,7 +2,7 @@ // @name Blue Marble // @name:en Blue Marble // @namespace https://github.com/SwingTheVine/ -// @version 0.92.0 +// @version 0.92.1 // @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @author SwingTheVine @@ -38,4 +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,C=[{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.v=null,this.C="bm-r",this.M=null,this.T=null,this.$=[]}S(t){this.p=t}k(t){this.v=t}D(){return this.$.length>0&&(this.T=this.$.pop()),this}L(t){t?.appendChild(this.M),this.M=null,this.T=null,this.$=[]}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}N(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}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}W(t,e={},n=()=>{}){return n(this,i(this,g,w).call(this,"h"+t,{},e)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}F(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}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}J(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.C,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){const i=document.querySelector(t),n=document.querySelector(e);if(!i||!n)return void this.yt(`Can not drag! ${i?"":"moveMe"} ${i||n?"":"and "}${n?"":"iMoveThings "}was not found!`);let s,o=!1,a=0,r=null,l=0,h=0,c=0,m=0,d=null;const u=()=>{if(o){const t=Math.abs(l-c),e=Math.abs(h-m);(t>.5||e>.5)&&(l=c,h=m,i.style.transform=`translate(${l}px, ${h}px)`,i.style.left="0px",i.style.top="0px",i.style.right=""),r=requestAnimationFrame(u)}},b=(t,e)=>{o=!0,d=i.getBoundingClientRect(),s=t-d.left,a=e-d.top;const b=window.getComputedStyle(i).transform;if(b&&"none"!==b){const t=new DOMMatrix(b);l=t.m41,h=t.m42}else l=d.left,h=d.top;c=l,m=h,document.body.style.userSelect="none",n.classList.add("bm-M"),document.addEventListener("mousemove",f),document.addEventListener("touchmove",g,{passive:!1}),document.addEventListener("mouseup",p),document.addEventListener("touchend",p),document.addEventListener("touchcancel",p),r&&cancelAnimationFrame(r),u()},p=()=>{o=!1,r&&(cancelAnimationFrame(r),r=null),document.body.style.userSelect="",n.classList.remove("bm-M"),document.removeEventListener("mousemove",f),document.removeEventListener("touchmove",g),document.removeEventListener("mouseup",p),document.removeEventListener("touchend",p),document.removeEventListener("touchcancel",p)},f=t=>{o&&d&&(c=t.clientX-s,m=t.clientY-a)},g=t=>{if(o&&d){const e=t.touches[0];if(!e)return;c=e.clientX-s,m=e.clientY-a,t.preventDefault()}};n.addEventListener("mousedown",function(t){t.preventDefault(),b(t.clientX,t.clientY)}),n.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(b(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.C,"Status: "+t,!0)}yt(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.C,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},n={}){const s=document.createElement(t);this.M?(this.T?.appendChild(s),this.$.push(this.T),this.T=s):(this.M=s,this.T=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 T,$,S,k,D,L=class extends M{constructor(t,i){super(t,i),e(this,y),this.window=null,this.Ct="bm-l",this.Mt=document.body}Tt(){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().V().D().N({textContent:"Settings take 5 seconds to save."}).D().H({class:"bm-L bm-H"},(t,e)=>{this.$t(),this.St()}).D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}$t(){i(this,y,v).call(this,"Pixel Highlight")}St(){i(this,y,v).call(this,"Template")}};y=new WeakSet,v=function(t){this.window=this.H({class:"bm-L"}).W(2,{textContent:t}).D().V().D().N({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).D().D()},T=new WeakSet,$=function(t,e){t.disabled=!0;const i=t.dataset.status,n=this.kt?.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]}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.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]}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 o};var N=class{constructor(){this.Et=Math.ceil(80/1300*window.innerWidth),this.Yt=C.slice(1)}Xt(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,P,A,W,V,_,z,F,U=class extends M{constructor(t,e){super(t,e),this.window=null,this.Ct="bm-o",this.Mt=document.body}Tt(){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().V().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()._().D().V().D()._().D().B({textContent:'"Blue Marble" userscript is made by SwingTheVine.'}).D()._().D().B({innerHTML:'The Blue Marble Website is made by crqch.'}).D()._().D().B({textContent:`The Blue Marble Website used until ${a(new Date(175606932e4))} was made by Camille Daguin.`}).D()._().D().B({textContent:'The favicon "Blue Marble" is owned by NASA. (The image of the Earth is owned by NASA)'}).D()._().D().B({textContent:"Special Thanks:"}).D().J().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()._().D().B({innerHTML:'Donators:'}).D().J().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().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}},G=class extends M{constructor(t){super(t.name,t.version),e(this,B),this.window=null,this.Ct="bm-t",this.Jt="bm-E",this.Mt=document.body,this.qt=t.p?.qt,this.Zt='',this.Qt='';const{palette:i,jt:n}=this.qt.Kt;this.palette=i,this.te=0,this.ee=0,this.ie=new Map,this.ne=new Map,this.se=0,this.oe=0,this.timeRemaining=0,this.ae="",this.sortPrimary="id",this.sortSecondary="ascending",this.showUnused=!1}Tt(){if(document.querySelector(`#${this.Ct}`))return void 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 "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=()=>{document.querySelector(`#${this.Ct}`)?.remove(),this.re()},e.ontouchend=()=>{e.click()}}).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:"Color Filter"}).D().D().V().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,A).call(this,!1)}).D().lt({textContent:"Refresh Data"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.le(),e.disabled=!1}}).D().lt({textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,B,A).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()._().D().B({id:"bm-d",innerHTML:"Correct Pixels: ???"}).D()._().D().B({id:"bm-j",innerHTML:"Total Pixels: ???"}).D()._().D().B({id:"bm-7",innerHTML:"Complete: ??? (???)"}).D()._().D().B({id:"bm-8",innerHTML:"??? ???"}).D().D().H({class:"bm-L"}).N({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.Zt.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;i(this,B,P).call(this,n.sortPrimary,n.sortSecondary,"on"==n.showUnused)}}).D().D().D().D().D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,I).call(this,t),i(this,B,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${s(this.te)} / ${s(this.ee)}`),this.ct("#bm-d",`Correct Pixels: ${s(this.se)}`),this.ct("#bm-j",`Total Pixels: ${s(this.oe)}`),this.ct("#bm-7",`Remaining: ${s((this.oe||0)-(this.se||0))} (${o(((this.oe||0)-(this.se||0))/(this.oe||1))})`),this.ct("#bm-8",`Completed at: `)}re(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();this.window=this.H({id:this.Ct,class:"bm-W bm-N"}).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=()=>{document.querySelector(`#${this.Ct}`)?.remove(),this.Tt()},e.ontouchend=()=>{e.click()}}).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:"Color Filter"}).D().D().V().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"None"},(t,e)=>{e.onclick=()=>i(this,B,A).call(this,!1)}).D().lt({textContent:"Refresh"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.le(),e.disabled=!1}}).D().lt({textContent:"All"},(t,e)=>{e.onclick=()=>i(this,B,A).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,I).call(this,t),i(this,B,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}le(){i(this,B,W).call(this);const t=document.querySelector(`#${this.Jt}`),e={};for(const t of this.palette){const i=this.ie.get(t.id)??0,n=s(i);let a=0,r="0",l=o(1);0!=i&&(a=this.ne.get(t.id)??"???","number"!=typeof a&&this.te==this.ee&&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]={he:i,ce:n,me:a,de:r,ue:l,be:h}}if(document.querySelector("#bm-2")){const t=this.se.toString().length>7?this.se.toString().slice(0,2)+"…"+this.se.toString().slice(-3):this.se.toString(),e=this.oe.toString().length>7?this.oe.toString().slice(0,2)+"…"+this.oe.toString().slice(-3):this.oe.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,de:s,ue:o,he:a,ce:r,be: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,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};B=new WeakSet,I=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N"),i=new M(this.name,this.version);i.H({id:this.Jt});const n=this.le();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,de:h,ue:c,he:m,ce:d,be:u}=n[t.id],b=!!this.qt.pe.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.Qt.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.Qt.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.Qt.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.Qt.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))},A=function(t){const e=document.querySelector(`#${this.Jt}`),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())}},W=function(){this.oe=0,this.se=0,this.ne=new Map,this.ie=new Map;for(const t of this.qt.fe){const e=t.Bt?.total??0;this.oe+=e??0;const i=t.Bt?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,n=this.ie.get(t)??0;this.ie.set(t,n+i)}const n=t.Bt?.correct??{};this.te+=Object.keys(n).length,this.ee+=Object.keys(t.Ht).length;for(const t of Object.values(n))for(const[e,i]of t){const t=Number(i)||0;this.se+=t;const n=this.ne.get(e)??0;this.ne.set(e,n+t)}}this.se>=this.oe&&this.oe&&this.te==this.ee&&(new N).Xt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.oe-this.se)*1e3+Date.now()),this.ae=a(this.timeRemaining)};var R=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,V),this.window=null,this.Ct="bm-u",this.Mt=document.body,this.ge=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.ge?.scriptVersion,this.schemaVersion=this.ge?.schemaVersion,this.we=void 0,this.xe=n,this.qt=s}Tt(){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().V().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().N({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().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,V,_).call(this),i(this,V,z).call(this)}};V=new WeakSet,_=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.xe.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.we="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.we="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.we="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.we="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.xe)}.
Wplace was last updated on ${l}.${"Good"!=this.we?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.we&&(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.qt.ye().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.we&&"Bad"!=this.we||h.lt({textContent:`Update template storage to ${this.xe}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,V,F).call(this,!0)}}).D(),h.D().L(document.querySelector("#bm-v").parentNode)},z=function(){const t=this.ge?.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.qt.ve),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().L(e)}},F=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().V().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().N({textContent:"Updating template storage. Please wait..."}).D().D().D().L(t)}GM_deleteValue("bmCoords");const e=this.ge?.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,Ht:i.tiles});t.Rt();const e=await this.qt.Ce(t);await this.qt.Me(e,t.displayName,t.coords)}t&&(document.querySelector(`#${this.Ct}`).remove(),new R(this.name,this.version,this.xe,this.qt).Tt())};var j,E,Y,X,J,q,Z,Q,K,tt=R;j=new WeakSet,E=function(){new G(this).Tt()},Y=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]||""))},X=new WeakSet,J=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Te))},q=async function(t){const e=t.templates,i=t?.schemaVersion,n=i.split(/[-\.\+]/),s=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;n[0]==s[0]?(n[1]!=s[1]&&new tt(this.name,this.version,this.schemaVersion,this).Tt(),this.fe=await async function({Ot:t,$e:i,fe:n}){if(Object.keys(e).length>0)for(const s in e){const o=s,a=e[s];if(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(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,Dt:s||this.fe?.length||0,Lt:r||""});p.Bt=h,p.Ht=m,p.Nt=d,n.push(p)}}return n}({Ot:this.Ot,$e:this.$e,fe:this.fe})):n[0]>>24&255,y=g>>>24&255,v=b.get(w)??-2,C=b.get(g)??-2;if(this.pe.get(v)&&(e[i*h+c]=g),-1==v){const t=536870912;this.pe.get(v)?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&&C!=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==v&&g<=m){const t=p.get(v);p.set(v,t?t+1:1);continue}if(x<=m||y<=m)continue;if(C!=v)continue;const M=p.get(v);p.set(v,M?M+1:1)}return{Be:p,Ie:e}},Q=new WeakSet,K=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var et=GM_info.script.name.toString(),it=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",et),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;if(Date.now(),"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 e=await s.apply(this,t),i=e.clone(),o=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",a=i.headers.get("content-type")||"";if(a.includes("application/json"))i.json().then(t=>{window.postMessage({source:"blue-marble",endpoint:o,jsonData:t},"*")}).catch(t=>{});else if(a.includes("image/")&&!o.includes("openfreemap")&&!o.includes("maps")){const t=Date.now(),e=await i.blob();return new Promise(s=>{const a=crypto.randomUUID();n.set(a,t=>{s(new Response(t,{headers:i.headers,status:i.status,statusText:i.statusText}))}),window.postMessage({source:"blue-marble",endpoint:o,blobID:a,blobData:e,blink:t})}).catch(t=>{Date.now()})}return e}});var nt=`#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-E{flex-direction:column;gap:.25em}#bm-t.bm-N .bm-z{width:auto;margin:0;padding:0}#bm-t.bm-N .bm-a{display:flex;width:100%;gap:.5ch;align-items:center;padding:.1em .5ch;border:none;border-radius:1em}#bm-t.bm-N .bm-a button{padding:.5em .25ch}#bm-t.bm-N .bm-a svg{width:3ch}#bm-t.bm-N .bm-z h2{font-size:.75em}#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{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-W.bm-N{max-width:300px}.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;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: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}`;GM_addStyle(nt);var st,ot="@font-face{font-family:'Roboto Mono';font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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)format('woff2');}";ot.indexOf("@font-face")+1?GM_addStyle(ot):((st=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",st.rel="preload",st.as="style",st.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(st));var at=JSON.parse(GM_getValue("bmUserSettings","{}")),rt=(new class{constructor(){this.Pe=null,this.Ae=null,this.We="#bm-p"}Ve(t){return this.Ae=t,this.Pe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.We)}),this}_e(){return this.Pe}observe(t,e=!1,i=!1){t.observe(this.Ae,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,j),this.window=null,this.Ct="bm-F",this.Mt=document.body}Tt(){document.querySelector(`#${this.Ct}`)?this.yt("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"}).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 N).Xt(document.querySelector(`#${this.Ct}`))})}).D().W(1,{textContent:this.name}).D().D().V().D().H({class:"bm-L"}).B({id:"bm-w",textContent:"Droplets:"}).D()._().D().B({id:"bm-q",textContent:"Next level in..."}).D()._().D().B({textContent:"Charges: "}).gt(Date.now(),1e3,{style:"font-weight: 700;"},(t,e)=>{t.p.ze=e.id}).D().D().D().V().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?.Fe;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?")}}).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,j,Y).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,j,Y).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,j,Y).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,j,Y).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?.qt?.Ue(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.vt("Disabled templates!")):(t.p?.qt?.Ue(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.vt("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.yt("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.yt("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.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?.qt.Me(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(n.value),Number(s.value),Number(o.value)]),t.vt("Drew to canvas!")):t.yt("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>i(this,j,E).call(this)}).D().D().H({class:"bm-L"}).bt({id:this.C,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.v.Tt()}}).D().lt({class:"bm-s",innerHTML:"🧙",title:"Template Wizard"},(t,e)=>{e.onclick=()=>{const e=t.p?.qt;new tt(this.name,this.version,e?.schemaVersion,e).Tt()}}).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 U(this.name,this.version).Tt()}}).D().D().O({textContent:"Made by SwingTheVine",style:"margin-top: auto;"}).D().D().D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}}(et,it)),lt=new class{constructor(t,i){e(this,X),this.name=t,this.version=i,this.Se=null,this.v=null,this.schemaVersion="2.0.0",this.Ge=null,this.ve="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.Ot=1e3,this.$e=3,this.Oe=3,this.Kt=function(t){const e=C;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,jt:i}}(this.Oe),this.De=null,this.Re="",this.fe=[],this.Te=null,this.je=!0,this.Ee=null,this.pe=new Map}Ye(t){this.Se=t}k(t){this.v=t}async Xe(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async Me(t,e,n){this.Te||(this.Te=await this.Xe()),this.Se.vt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Dt:0,Lt:m(this.Ge||0,this.ve),file:t,coords:n}),o=!this.v?.kt?.flags?.includes("hl-noSkip"),a=this.v?.kt?.flags?.includes("hl-agSkip"),{Ut:r,Gt:l}=await s.At(this.Ot,this.Kt,o,a);s.Ht=r;const h={total:s.Bt.total,colors:Object.fromEntries(s.Bt.colors)};this.Te.templates[`${s.Dt} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.fe=[],this.fe.push(s),this.Se.vt(`Template created at ${n.join(", ")}!`),await i(this,X,J).call(this)}Je(){}async qe(){this.Te||(this.Te=await this.Xe())}async Ze(){l("Downloading all templates...");for(const t of this.fe)await this.Qe(t),await n(500)}async ye(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.Qe(new H({displayName:i.name,Dt:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ht:i.tiles})),await n(500))}async Qe(t){t.Rt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.Ce(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",Ke:"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 Ce(t){const e=t.Ht,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.Ot+h,u=l*this.Ot+c;s=Math.min(s,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.$e),r=Math.max(r,u+m.height/this.$e)});const l=a-s,h=r-o,c=l*this.$e,m=h*this.$e,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.Ot+r,m=a*this.Ot+l;u.drawImage(h,(c-s)*this.$e,(m-o)*this.$e,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.$e,h*this.$e,0,0,l,h),b.convertToBlob({type:"image/png"})}async ti(t,e){if(!this.je)return t;const n=this.Ot*this.$e;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0");const o=this.fe;o.sort((t,e)=>t.Dt-e.Dt);const a=o.map(t=>{const i=Object.keys(t.Ht).filter(t=>t.startsWith(e));if(0===i.length)return null;const n=i.map(e=>{const i=e.split(",");return{ei:t,Vt:t.Ht[e],Nt:t.Nt?.[e],ii:[i[0],i[1]],ni:[i[2],i[3]]}});return n?.[0]}).filter(Boolean),r=a?.length||0;if(!(r>0))return this.Se.vt(`Sleeping\nVersion: ${this.version}`),t;{const t=s(o.filter(t=>Object.keys(t.Ht).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.Bt.total||0),0));this.Se.vt(`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.v?.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){const n=!!t.ei.Bt?.colors?.get(-1);let s=t.Nt.slice();const o=Number(t.ni[0])*this.$e,a=Number(t.ni[1])*this.$e;if(0!=this.pe.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)}Date.now();const{Be:r,Ie:l}=i(this,X,Z).call(this,{ke:d,De:s,Le:[o,a,t.Vt.width,t.Vt.height],He:u,Ne:p});let h=0;const m=0;for(const[t,e]of r)t!=m&&(h+=e);0==this.pe.size&&!n&&p||c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(l.buffer),t.Vt.width,t.Vt.height)),o,a),void 0===t.ei.Bt.correct&&(t.ei.Bt.correct={}),t.ei.Bt.correct[e]=r}return await h.convertToBlob({type:"image/png"})}si(t){"BlueMarble"==t?.whoami&&i(this,X,q).call(this,t)}Ue(t){this.je=t}}(et,it),ht=new class{constructor(t){this.qt=t,this.oi=!1,this.ze="",this.Fe=[],this.ai=[]}ri(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(o){case"me":if(n.status&&"2"!=n.status?.toString()[0])return void t.yt("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(n.id||n.id,this.qt.Ge=n.id,0!=this.ze.length){const t=document.querySelector("#"+this.ze);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.Fe.length&&(!o.length||!h.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.Fe=[...o,...h];const c=(a=o,r=h,[parseInt(a[0])%4*1e3+parseInt(r[0]),parseInt(a[1])%4*1e3+parseInt(r[1])]),m=document.querySelectorAll("span");for(const t of m){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 d=i.endpoint.split("/");d=[parseInt(d[d.length-2]),parseInt(d[d.length-1].replace(".png",""))];const u=i.blobID,b=i.blobData,p=(Date.now(),await this.qt.ti(b,d));window.postMessage({source:"blue-marble",blobID:u,blobData:p,blink:i.blink});break;case"robots":this.oi="false"==n.userscript?.toString().toLowerCase()}var a,r})}async li(t){let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return;const i=navigator.userAgent;let n=await this.hi(i),s=this.ci(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 hi(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"}ci(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"}}(lt),ct=new class extends L{constructor(t,i,n){var s;super(t,i),e(this,T),this.kt=n,(s=this.kt).flags??(s.flags=[]),this.mi=structuredClone(this.kt),this.di="bmUserSettings",this.ui=5e3,this.bi=0,setInterval(this.pi.bind(this),this.ui)}async pi(){const t=JSON.stringify(this.kt);t!=JSON.stringify(this.mi)&&Date.now()-this.bi>this.ui&&(await GM.setValue(this.di,t),this.mi=structuredClone(this.kt),this.bi=Date.now())}fi(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)}$t(){const t='',e='',n=this.kt?.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().V().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.fi("hl-noTrans",!t.target.checked)}).D().N({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,T,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,T,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,T,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,T,S).call(this,"Full")}).D().D().D().N({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,T,$).call(this,s,[e,t])}).D()}this.window=this.D().D().D()}St(){this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().V().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.fi("hl-noSkip",!t.target.checked)}).D().R({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.kt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.fi("hl-agSkip",t.target.checked)}).D().D().D()}}(et,it,at);rt.k(ct),rt.S(ht),lt.Ye(rt),lt.k(ct);var mt=JSON.parse(GM_getValue("bmTemplates","{}"));if(lt.si(mt),0==Object.keys(at).length){const t=crypto.randomUUID();GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>ht.li(it),18e5);var dt=at?.telemetry;if(null==dt||dt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,Q),this.window=null,this.Ct="bm-k",this.Mt=document.body,this.gi=n,this.uuid=s}async Tt(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.hi(navigator.userAgent),e=this.p.ci(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().V().D().H({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,Q,K).call(this,this.gi);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,Q,K).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().N({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().V().D().H({class:"bm-L"}).W(2,{textContent:"Non-Legal Summary"}).D().N({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().J().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().N({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().L(this.Mt)}}(et,it,1,at?.uuid);t.S(ht),t.Tt()}rt.Tt(),ht.ri(rt),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${et}%c (${it}) userscript has loaded!`,"color: cornflowerblue;","")})(); \ No newline at end of file +(()=>{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?.$t??(()=>{});if(!n||!s)return void this.yt(`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?.$t??(()=>{});if(!n||!s)return void this.yt(`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,$=(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,n.style.width=`${m}px`,n.style.height=`${d}px`),p=requestAnimationFrame(y)}},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),y()},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=$(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())};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)}yt(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,$),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")}};$=new WeakSet,y=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=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`))}},K=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="id",this.sortSecondary="ascending",this.showUnused=!1}we(){this.$?.Nt?.flags?.includes(this.Qt)?this.xe():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,P).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,A).call(this,!0),i(this,B,P).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,P).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.$e(),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,E).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,R).call(this,t),i(this,B,E).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,P).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,A).call(this,!1),i(this,B,P).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,P).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.$e(),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,G).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,R).call(this,t),i(this,B,E).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}$e(){i(this,B,Y).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]={ye: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,ye: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,E).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(t){this.$&&(this.$.ke(this.Qt,t),this.$.De())},P=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,B,_).call(this,t),i(this,B,z).call(this),t?.remove()},z=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)},W=function(t,e,i){const n=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),n)},F=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)}},V=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,W).call(this,n,this.ne,Math.min(this.oe,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,B,W).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,F).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())})},_=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,W).call(this,n.width,this.ne,Math.min(this.oe,window.innerWidth-16)),o=i(this,B,W).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,F).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()},U=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,B,_).call(this,t)},e)},G=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,B,z).call(this),i(this,B,V).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{$t:({element:t})=>i(this,B,_).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),$t:({element:t})=>i(this,B,_).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,B,U).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,B,U).call(this,t,0),window.addEventListener("resize",this.ee))},R=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.$e();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,ye: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())}},Y=function(){this.fe=0,this.pe=0,this.be=new Map,this.ue=new Map;for(const t of this.re.He){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 tt=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,J),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Le=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Le?.scriptVersion,this.schemaVersion=this.Le?.schemaVersion,this.Oe=void 0,this.Be=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,J,X).call(this),i(this,J,q).call(this)}};J=new WeakSet,X=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Be.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.Oe="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.Oe="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.Oe="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Oe="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.Be)}.
Wplace was last updated on ${l}.${"Good"!=this.Oe?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.Oe&&(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.Ie().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.Oe&&"Bad"!=this.Oe||h.lt({textContent:`Update template storage to ${this.Be}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,J,Z).call(this,!0)}}).D(),h.D().N(document.querySelector("#bm-v").parentNode)},q=function(){const t=this.Le?.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.Ae),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)}},Z=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.Le?.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.Pe(t);await this.re.ze(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new tt(this.name,this.version,this.Be,this.re).St())};var et,it,nt,st,ot,at,rt,lt,ht,ct=tt;et=new WeakSet,it=function(){new K(this).we()},nt=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]||""))},st=new WeakSet,ot=async function(){GM.setValue("bmTemplates",JSON.stringify(this.We))},at=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 ct(this.name,this.version,this.schemaVersion,this).St(),this.He=await async function({It:t,Fe:i,He: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.He?.length||0,Lt:r||""});p.At=h,p.Ot=m,p.Bt=d,n.push(p),console.log(this.He),console.log("^^^ This ^^^")}}return n}({It:this.It,Fe:this.Fe,He:this.He})):n[0]>>24&255,$=g>>>24&255,y=b.get(w)??-2,v=b.get(g)??-2;if(this.Ne.get(y)&&(e[i*h+c]=g),-1==y){const t=536870912;this.Ne.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(!s&&x>m&&v!=y&&(d||$>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==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),{Ye:p,Je:e}},lt=new WeakSet,ht=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var mt=GM_info.script.name.toString(),dt=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",mt),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 ut=`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(ut);var bt,pt="@font-face{font-family:'Roboto Mono';font-style:normal;font-weight:400;src:url(data:font/woff2;base64,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)format('woff2');}";pt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(pt)):((bt=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",bt.rel="preload",bt.as="style",bt.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(bt));var ft=JSON.parse(GM_getValue("bmUserSettings","{}")),gt=(new class{constructor(){this.Xe=null,this.qe=null,this.Ze="#bm-p"}Qe(t){return this.qe=t,this.Xe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.Ze)}),this}Ke(){return this.Xe}observe(t,e=!1,i=!1){t.observe(this.qe,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,et),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.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.ti=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?.ei;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?")}}).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,et,nt).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,et,nt).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,et,nt).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,et,nt).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?.ii(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.re?.ii(!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.yt("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.yt("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.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?.re.ze(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.yt("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>i(this,et,it).call(this)}).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 ct(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 Q(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`))}}(mt,dt)),wt=new class{constructor(t,i){e(this,st),this.name=t,this.version=i,this.Ve=null,this.$=null,this.schemaVersion="2.0.0",this.ni=null,this.Ae="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.It=1e3,this.Fe=3,this.je=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.je),this.Ue=null,this.si="",this.He=[],this.We=null,this.oi=!0,this.ai=null,this.Ne=new Map}ri(t){this.Ve=t}k(t){this.$=t}async li(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async ze(t,e,n){this.We||(this.We=await this.li(),console.log("Creating JSON...")),this.Ve.Mt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Ht:0,Lt:m(this.ni||0,this.Ae),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.We.templates[`${s.Ht} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.He=[],this.He.push(s),this.Ve.Mt(`Template created at ${n.join(", ")}!`),console.log(Object.keys(this.We.templates).length),console.log(this.We),console.log(this.He),console.log(JSON.stringify(this.We)),await i(this,st,ot).call(this)}hi(){}async ci(){this.We||(this.We=await this.li(),console.log("Creating JSON..."))}async mi(){l("Downloading all templates..."),console.log(this.He);for(const t of this.He)await this.di(t),await n(500)}async Ie(){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.di(new H({displayName:i.name,Ht:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ot:i.tiles})),await n(500))}async di(t){t.jt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.Pe(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",ui:"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 Pe(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.Fe),r=Math.max(r,u+m.height/this.Fe)}),console.log(`Absolute coordinates: (${s}, ${o}) and (${a}, ${r})`);const l=a-s,h=r-o,c=l*this.Fe,m=h*this.Fe;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.Fe,(m-o)*this.Fe,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.Fe,h*this.Fe,0,0,l,h),b.convertToBlob({type:"image/png"})}async bi(t,e){if(!this.oi)return t;const n=this.It*this.Fe;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.He;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{pi:t,Vt:t.Ot[e],Bt:t.Bt?.[e],fi:[i[0],i[1]],gi:[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.Ve.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.Ve.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.pi.At?.colors?.get(-1);let s=t.Bt.slice();const o=Number(t.gi[0])*this.Fe,a=Number(t.gi[1])*this.Fe;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(),{Ye:l,Je:h}=i(this,st,rt).call(this,{_e:d,Ue:s,Ge:[o,a,t.Vt.width,t.Vt.height],Re:u,Ee: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.pi.At.correct&&(t.pi.At.correct={}),t.pi.At.correct[e]=l}return await h.convertToBlob({type:"image/png"})}wi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&i(this,st,at).call(this,t)}ii(t){this.oi=t}}(mt,dt),xt=new class{constructor(t){this.re=t,this.xi=!1,this.ti="",this.ei=[],this.$i=[]}yi(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.yt("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.ni=n.id,0!=this.ti.length){const t=document.querySelector("#"+this.ti);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.ei.length&&(!o.length||!h.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ei=[...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.bi(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.xi="false"==n.userscript?.toString().toLowerCase();break}var a,r})}async Mi(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.Ci(i),s=this.Ti(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 Ci(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"}Ti(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"}}(wt),$t=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.Si=structuredClone(this.Nt),this.ki="bmUserSettings",this.Di=5e3,this.Ni=0,setInterval(this.Hi.bind(this),this.Di)}async Hi(){await this.Li()}async Li(t=!1){const e=JSON.stringify(this.Nt);e!=JSON.stringify(this.Si)&&(t||Date.now()-this.Ni>this.Di)&&(await GM.setValue(this.ki,e),this.Si=structuredClone(this.Nt),this.Ni=Date.now(),console.log(e))}async De(){await this.Li(!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()}}(mt,dt,ft);gt.k($t),gt.S(xt),wt.ri(gt),wt.k($t);var yt=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(yt),wt.wi(yt),console.log(ft),console.log(Object.keys(ft).length),0==Object.keys(ft).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>xt.Mi(dt),18e5);var vt=ft?.telemetry;if(console.log(`Telemetry is ${!(null==vt)}`),null==vt||vt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,lt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Oi=n,this.uuid=s}async St(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.Ci(navigator.userAgent),e=this.p.Ti(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,lt,ht).call(this,this.Oi);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,lt,ht).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)}}(mt,dt,1,ft?.uuid);t.S(xt),t.St()}gt.St(),xt.yi(gt),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${mt}%c (${dt}) userscript has loaded!`,"color: cornflowerblue;","")})(); + +// Build Hash: 0a66f6218f02 diff --git a/dist/BlueMarble.user.css b/dist/BlueMarble.user.css index e2e47fa..f85f122 100644 --- a/dist/BlueMarble.user.css +++ b/dist/BlueMarble.user.css @@ -1 +1,3 @@ -#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-E{flex-direction:column;gap:.25em}#bm-t.bm-N .bm-z{width:auto;margin:0;padding:0}#bm-t.bm-N .bm-a{display:flex;width:100%;gap:.5ch;align-items:center;padding:.1em .5ch;border:none;border-radius:1em}#bm-t.bm-N .bm-a button{padding:.5em .25ch}#bm-t.bm-N .bm-a svg{width:3ch}#bm-t.bm-N .bm-z h2{font-size:.75em}#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{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-W.bm-N{max-width:300px}.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;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: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} +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} + +/* Build Hash: 0fe5479ecc95 */ diff --git a/dist/BlueMarble.user.js b/dist/BlueMarble.user.js index 6fecec5..d9f0847 100644 --- a/dist/BlueMarble.user.js +++ b/dist/BlueMarble.user.js @@ -2,7 +2,7 @@ // @name Blue Marble // @name:en Blue Marble // @namespace https://github.com/SwingTheVine/ -// @version 0.92.0 +// @version 0.92.1 // @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @author SwingTheVine @@ -39,4 +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,C=[{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.v=null,this.C="bm-r",this.M=null,this.T=null,this.$=[]}S(t){this.p=t}k(t){this.v=t}D(){return this.$.length>0&&(this.T=this.$.pop()),this}L(t){t?.appendChild(this.M),this.M=null,this.T=null,this.$=[]}H(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"div",{},t)),this}N(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}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}W(t,e={},n=()=>{}){return n(this,i(this,g,w).call(this,"h"+t,{},e)),this}V(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"hr",{},t)),this}_(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"br",{},t)),this}F(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}X(t={},e=()=>{}){return e(this,i(this,g,w).call(this,"ol",{},t)),this}J(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.C,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){const i=document.querySelector(t),n=document.querySelector(e);if(!i||!n)return void this.yt(`Can not drag! ${i?"":"moveMe"} ${i||n?"":"and "}${n?"":"iMoveThings "}was not found!`);let s,o=!1,a=0,r=null,l=0,h=0,c=0,m=0,d=null;const u=()=>{if(o){const t=Math.abs(l-c),e=Math.abs(h-m);(t>.5||e>.5)&&(l=c,h=m,i.style.transform=`translate(${l}px, ${h}px)`,i.style.left="0px",i.style.top="0px",i.style.right=""),r=requestAnimationFrame(u)}},b=(t,e)=>{o=!0,d=i.getBoundingClientRect(),s=t-d.left,a=e-d.top;const b=window.getComputedStyle(i).transform;if(b&&"none"!==b){const t=new DOMMatrix(b);l=t.m41,h=t.m42}else l=d.left,h=d.top;c=l,m=h,document.body.style.userSelect="none",n.classList.add("bm-M"),document.addEventListener("mousemove",f),document.addEventListener("touchmove",g,{passive:!1}),document.addEventListener("mouseup",p),document.addEventListener("touchend",p),document.addEventListener("touchcancel",p),r&&cancelAnimationFrame(r),u()},p=()=>{o=!1,r&&(cancelAnimationFrame(r),r=null),document.body.style.userSelect="",n.classList.remove("bm-M"),document.removeEventListener("mousemove",f),document.removeEventListener("touchmove",g),document.removeEventListener("mouseup",p),document.removeEventListener("touchend",p),document.removeEventListener("touchcancel",p)},f=t=>{o&&d&&(c=t.clientX-s,m=t.clientY-a)},g=t=>{if(o&&d){const e=t.touches[0];if(!e)return;c=e.clientX-s,m=e.clientY-a,t.preventDefault()}};n.addEventListener("mousedown",function(t){t.preventDefault(),b(t.clientX,t.clientY)}),n.addEventListener("touchstart",function(t){const e=t?.touches?.[0];e&&(b(e.clientX,e.clientY),t.preventDefault())},{passive:!1})}vt(t){(0,console.info)(`${this.name}: ${t}`),this.ct(this.C,"Status: "+t,!0)}yt(t){(0,console.error)(`${this.name}: ${t}`),this.ct(this.C,"Error: "+t,!0)}};g=new WeakSet,w=function(t,e={},n={}){const s=document.createElement(t);this.M?(this.T?.appendChild(s),this.$.push(this.T),this.T=s):(this.M=s,this.T=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 T,$,S,k,D,L=class extends M{constructor(t,i){super(t,i),e(this,y),this.window=null,this.Ct="bm-l",this.Mt=document.body}Tt(){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().V().D().N({textContent:"Settings take 5 seconds to save."}).D().H({class:"bm-L bm-H"},(t,e)=>{this.$t(),this.St()}).D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}$t(){i(this,y,v).call(this,"Pixel Highlight")}St(){i(this,y,v).call(this,"Template")}};y=new WeakSet,v=function(t){this.window=this.H({class:"bm-L"}).W(2,{textContent:t}).D().V().D().N({innerHTML:`An error occured loading the ${t} category. SettingsManager failed to override the ${t} function inside WindowSettings.`}).D().D()},T=new WeakSet,$=function(t,e){t.disabled=!0;const i=t.dataset.status,n=this.kt?.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]}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.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]}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 o};var N=class{constructor(){this.Et=Math.ceil(80/1300*window.innerWidth),this.Yt=C.slice(1)}Xt(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,P,A,W,V,_,z,F,U=class extends M{constructor(t,e){super(t,e),this.window=null,this.Ct="bm-o",this.Mt=document.body}Tt(){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().V().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()._().D().V().D()._().D().B({textContent:'"Blue Marble" userscript is made by SwingTheVine.'}).D()._().D().B({innerHTML:'The Blue Marble Website is made by crqch.'}).D()._().D().B({textContent:`The Blue Marble Website used until ${a(new Date(175606932e4))} was made by Camille Daguin.`}).D()._().D().B({textContent:'The favicon "Blue Marble" is owned by NASA. (The image of the Earth is owned by NASA)'}).D()._().D().B({textContent:"Special Thanks:"}).D().J().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()._().D().B({innerHTML:'Donators:'}).D().J().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().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}},G=class extends M{constructor(t){super(t.name,t.version),e(this,B),this.window=null,this.Ct="bm-t",this.Jt="bm-E",this.Mt=document.body,this.qt=t.p?.qt,this.Zt='',this.Qt='';const{palette:i,jt:n}=this.qt.Kt;this.palette=i,this.te=0,this.ee=0,this.ie=new Map,this.ne=new Map,this.se=0,this.oe=0,this.timeRemaining=0,this.ae="",this.sortPrimary="id",this.sortSecondary="ascending",this.showUnused=!1}Tt(){if(document.querySelector(`#${this.Ct}`))return void 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 "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=()=>{document.querySelector(`#${this.Ct}`)?.remove(),this.re()},e.ontouchend=()=>{e.click()}}).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:"Color Filter"}).D().D().V().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,A).call(this,!1)}).D().lt({textContent:"Refresh Data"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.le(),e.disabled=!1}}).D().lt({textContent:"Show All Colors"},(t,e)=>{e.onclick=()=>i(this,B,A).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()._().D().B({id:"bm-d",innerHTML:"Correct Pixels: ???"}).D()._().D().B({id:"bm-j",innerHTML:"Total Pixels: ???"}).D()._().D().B({id:"bm-7",innerHTML:"Complete: ??? (???)"}).D()._().D().B({id:"bm-8",innerHTML:"??? ???"}).D().D().H({class:"bm-L"}).N({innerHTML:`Press the 🗗 button to make this window smaller. Colors with the icon ${this.Zt.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;i(this,B,P).call(this,n.sortPrimary,n.sortSecondary,"on"==n.showUnused)}}).D().D().D().D().D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,I).call(this,t),i(this,B,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused),this.ct("#bm-i",`Tiles Loaded: ${s(this.te)} / ${s(this.ee)}`),this.ct("#bm-d",`Correct Pixels: ${s(this.se)}`),this.ct("#bm-j",`Total Pixels: ${s(this.oe)}`),this.ct("#bm-7",`Remaining: ${s((this.oe||0)-(this.se||0))} (${o(((this.oe||0)-(this.se||0))/(this.oe||1))})`),this.ct("#bm-8",`Completed at: `)}re(){if(document.querySelector(`#${this.Ct}`))return void document.querySelector(`#${this.Ct}`).remove();this.window=this.H({id:this.Ct,class:"bm-W bm-N"}).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=()=>{document.querySelector(`#${this.Ct}`)?.remove(),this.Tt()},e.ontouchend=()=>{e.click()}}).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:"Color Filter"}).D().D().V().D().H({class:"bm-L bm-x bm-h",style:"gap: 1.5ch;"}).lt({textContent:"None"},(t,e)=>{e.onclick=()=>i(this,B,A).call(this,!1)}).D().lt({textContent:"Refresh"},(t,e)=>{e.onclick=()=>{e.disabled=!0,this.le(),e.disabled=!1}}).D().lt({textContent:"All"},(t,e)=>{e.onclick=()=>i(this,B,A).call(this,!0)}).D().D().H({class:"bm-L bm-H"}).D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,I).call(this,t),i(this,B,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}le(){i(this,B,W).call(this);const t=document.querySelector(`#${this.Jt}`),e={};for(const t of this.palette){const i=this.ie.get(t.id)??0,n=s(i);let a=0,r="0",l=o(1);0!=i&&(a=this.ne.get(t.id)??"???","number"!=typeof a&&this.te==this.ee&&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]={he:i,ce:n,me:a,de:r,ue:l,be:h}}if(document.querySelector("#bm-2")){const t=this.se.toString().length>7?this.se.toString().slice(0,2)+"…"+this.se.toString().slice(-3):this.se.toString(),e=this.oe.toString().length>7?this.oe.toString().slice(0,2)+"…"+this.oe.toString().slice(-3):this.oe.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,de:s,ue:o,he:a,ce:r,be: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,P).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}};B=new WeakSet,I=function(t){const e=t.closest(`#${this.Ct}`)?.classList.contains("bm-N"),i=new M(this.name,this.version);i.H({id:this.Jt});const n=this.le();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,de:h,ue:c,he:m,ce:d,be:u}=n[t.id],b=!!this.qt.pe.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.Qt.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.Qt.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.Qt.replace("{i.onclick=()=>{i.style.textDecoration="none",i.disabled=!0,"shown"==i.dataset.state?(i.innerHTML=this.Qt.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))},A=function(t){const e=document.querySelector(`#${this.Jt}`),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())}},W=function(){this.oe=0,this.se=0,this.ne=new Map,this.ie=new Map;for(const t of this.qt.fe){const e=t.Bt?.total??0;this.oe+=e??0;const i=t.Bt?.colors??new Map;for(const[t,e]of i){const i=Number(e)||0,n=this.ie.get(t)??0;this.ie.set(t,n+i)}const n=t.Bt?.correct??{};this.te+=Object.keys(n).length,this.ee+=Object.keys(t.Ht).length;for(const t of Object.values(n))for(const[e,i]of t){const t=Number(i)||0;this.se+=t;const n=this.ne.get(e)??0;this.ne.set(e,n+t)}}this.se>=this.oe&&this.oe&&this.te==this.ee&&(new N).Xt(document.querySelector(`#${this.Ct}`)),this.timeRemaining=new Date(30*(this.oe-this.se)*1e3+Date.now()),this.ae=a(this.timeRemaining)};var R=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,V),this.window=null,this.Ct="bm-u",this.Mt=document.body,this.ge=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.ge?.scriptVersion,this.schemaVersion=this.ge?.schemaVersion,this.we=void 0,this.xe=n,this.qt=s}Tt(){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().V().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().N({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().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`),i(this,V,_).call(this),i(this,V,z).call(this)}};V=new WeakSet,_=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.xe.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.we="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.we="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.we="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.we="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.xe)}.
Wplace was last updated on ${l}.${"Good"!=this.we?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.we&&(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.qt.ye().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.we&&"Bad"!=this.we||h.lt({textContent:`Update template storage to ${this.xe}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,V,F).call(this,!0)}}).D(),h.D().L(document.querySelector("#bm-v").parentNode)},z=function(){const t=this.ge?.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.qt.ve),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().L(e)}},F=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().V().D().H({class:"bm-L"}).W(2,{textContent:"Status"}).D().N({textContent:"Updating template storage. Please wait..."}).D().D().D().L(t)}GM_deleteValue("bmCoords");const e=this.ge?.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,Ht:i.tiles});t.Rt();const e=await this.qt.Ce(t);await this.qt.Me(e,t.displayName,t.coords)}t&&(document.querySelector(`#${this.Ct}`).remove(),new R(this.name,this.version,this.xe,this.qt).Tt())};var j,E,Y,X,J,q,Z,Q,K,tt=R;j=new WeakSet,E=function(){new G(this).Tt()},Y=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]||""))},X=new WeakSet,J=async function(){GM.setValue("bmTemplates",JSON.stringify(this.Te))},q=async function(t){const e=t.templates,i=t?.schemaVersion,n=i.split(/[-\.\+]/),s=this.schemaVersion.split(/[-\.\+]/),o=t?.scriptVersion;n[0]==s[0]?(n[1]!=s[1]&&new tt(this.name,this.version,this.schemaVersion,this).Tt(),this.fe=await async function({Ot:t,$e:i,fe:n}){if(Object.keys(e).length>0)for(const s in e){const o=s,a=e[s];if(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(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,Dt:s||this.fe?.length||0,Lt:r||""});p.Bt=h,p.Ht=m,p.Nt=d,n.push(p)}}return n}({Ot:this.Ot,$e:this.$e,fe:this.fe})):n[0]>>24&255,y=g>>>24&255,v=b.get(w)??-2,C=b.get(g)??-2;if(this.pe.get(v)&&(e[i*h+c]=g),-1==v){const t=536870912;this.pe.get(v)?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&&C!=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==v&&g<=m){const t=p.get(v);p.set(v,t?t+1:1);continue}if(x<=m||y<=m)continue;if(C!=v)continue;const M=p.get(v);p.set(v,M?M+1:1)}return{Be:p,Ie:e}},Q=new WeakSet,K=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var et=GM_info.script.name.toString(),it=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",et),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;if(Date.now(),"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 e=await s.apply(this,t),i=e.clone(),o=(t[0]instanceof Request?t[0]?.url:t[0])||"ignore",a=i.headers.get("content-type")||"";if(a.includes("application/json"))i.json().then(t=>{window.postMessage({source:"blue-marble",endpoint:o,jsonData:t},"*")}).catch(t=>{});else if(a.includes("image/")&&!o.includes("openfreemap")&&!o.includes("maps")){const t=Date.now(),e=await i.blob();return new Promise(s=>{const a=crypto.randomUUID();n.set(a,t=>{s(new Response(t,{headers:i.headers,status:i.status,statusText:i.statusText}))}),window.postMessage({source:"blue-marble",endpoint:o,blobID:a,blobData:e,blink:t})}).catch(t=>{Date.now()})}return e}});var nt=GM_getResourceText("CSS-BM-File");GM_addStyle(nt);var st,ot="robotoMonoInjectionPoint";ot.indexOf("@font-face")+1?GM_addStyle(ot):((st=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",st.rel="preload",st.as="style",st.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(st));var at=JSON.parse(GM_getValue("bmUserSettings","{}")),rt=(new class{constructor(){this.Pe=null,this.Ae=null,this.We="#bm-p"}Ve(t){return this.Ae=t,this.Pe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.We)}),this}_e(){return this.Pe}observe(t,e=!1,i=!1){t.observe(this.Ae,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,j),this.window=null,this.Ct="bm-F",this.Mt=document.body}Tt(){document.querySelector(`#${this.Ct}`)?this.yt("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"}).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 N).Xt(document.querySelector(`#${this.Ct}`))})}).D().W(1,{textContent:this.name}).D().D().V().D().H({class:"bm-L"}).B({id:"bm-w",textContent:"Droplets:"}).D()._().D().B({id:"bm-q",textContent:"Next level in..."}).D()._().D().B({textContent:"Charges: "}).gt(Date.now(),1e3,{style:"font-weight: 700;"},(t,e)=>{t.p.ze=e.id}).D().D().D().V().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?.Fe;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?")}}).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,j,Y).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,j,Y).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,j,Y).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,j,Y).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?.qt?.Ue(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.vt("Disabled templates!")):(t.p?.qt?.Ue(!0),e.dataset.buttonStatus="shown",e.textContent="Disable",t.vt("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.yt("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.yt("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.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?.qt.Me(e.files[0],e.files[0]?.name.replace(/\.[^/.]+$/,""),[Number(i.value),Number(n.value),Number(s.value),Number(o.value)]),t.vt("Drew to canvas!")):t.yt("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>i(this,j,E).call(this)}).D().D().H({class:"bm-L"}).bt({id:this.C,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.v.Tt()}}).D().lt({class:"bm-s",innerHTML:"🧙",title:"Template Wizard"},(t,e)=>{e.onclick=()=>{const e=t.p?.qt;new tt(this.name,this.version,e?.schemaVersion,e).Tt()}}).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 U(this.name,this.version).Tt()}}).D().D().O({textContent:"Made by SwingTheVine",style:"margin-top: auto;"}).D().D().D().D().D().L(this.Mt),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`))}}(et,it)),lt=new class{constructor(t,i){e(this,X),this.name=t,this.version=i,this.Se=null,this.v=null,this.schemaVersion="2.0.0",this.Ge=null,this.ve="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.Ot=1e3,this.$e=3,this.Oe=3,this.Kt=function(t){const e=C;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,jt:i}}(this.Oe),this.De=null,this.Re="",this.fe=[],this.Te=null,this.je=!0,this.Ee=null,this.pe=new Map}Ye(t){this.Se=t}k(t){this.v=t}async Xe(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async Me(t,e,n){this.Te||(this.Te=await this.Xe()),this.Se.vt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Dt:0,Lt:m(this.Ge||0,this.ve),file:t,coords:n}),o=!this.v?.kt?.flags?.includes("hl-noSkip"),a=this.v?.kt?.flags?.includes("hl-agSkip"),{Ut:r,Gt:l}=await s.At(this.Ot,this.Kt,o,a);s.Ht=r;const h={total:s.Bt.total,colors:Object.fromEntries(s.Bt.colors)};this.Te.templates[`${s.Dt} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.fe=[],this.fe.push(s),this.Se.vt(`Template created at ${n.join(", ")}!`),await i(this,X,J).call(this)}Je(){}async qe(){this.Te||(this.Te=await this.Xe())}async Ze(){l("Downloading all templates...");for(const t of this.fe)await this.Qe(t),await n(500)}async ye(){const t=JSON.parse(GM_getValue("bmTemplates","{}"))?.templates;if(Object.keys(t).length>0)for(const[e,i]of Object.entries(t))t.hasOwnProperty(e)&&(await this.Qe(new H({displayName:i.name,Dt:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ht:i.tiles})),await n(500))}async Qe(t){t.Rt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.Ce(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",Ke:"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 Ce(t){const e=t.Ht,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.Ot+h,u=l*this.Ot+c;s=Math.min(s,d),o=Math.min(o,u),a=Math.max(a,d+m.width/this.$e),r=Math.max(r,u+m.height/this.$e)});const l=a-s,h=r-o,c=l*this.$e,m=h*this.$e,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.Ot+r,m=a*this.Ot+l;u.drawImage(h,(c-s)*this.$e,(m-o)*this.$e,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.$e,h*this.$e,0,0,l,h),b.convertToBlob({type:"image/png"})}async ti(t,e){if(!this.je)return t;const n=this.Ot*this.$e;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0");const o=this.fe;o.sort((t,e)=>t.Dt-e.Dt);const a=o.map(t=>{const i=Object.keys(t.Ht).filter(t=>t.startsWith(e));if(0===i.length)return null;const n=i.map(e=>{const i=e.split(",");return{ei:t,Vt:t.Ht[e],Nt:t.Nt?.[e],ii:[i[0],i[1]],ni:[i[2],i[3]]}});return n?.[0]}).filter(Boolean),r=a?.length||0;if(!(r>0))return this.Se.vt(`Sleeping\nVersion: ${this.version}`),t;{const t=s(o.filter(t=>Object.keys(t.Ht).filter(t=>t.startsWith(e)).length>0).reduce((t,e)=>t+(e.Bt.total||0),0));this.Se.vt(`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.v?.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){const n=!!t.ei.Bt?.colors?.get(-1);let s=t.Nt.slice();const o=Number(t.ni[0])*this.$e,a=Number(t.ni[1])*this.$e;if(0!=this.pe.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)}Date.now();const{Be:r,Ie:l}=i(this,X,Z).call(this,{ke:d,De:s,Le:[o,a,t.Vt.width,t.Vt.height],He:u,Ne:p});let h=0;const m=0;for(const[t,e]of r)t!=m&&(h+=e);0==this.pe.size&&!n&&p||c.drawImage(await createImageBitmap(new ImageData(new Uint8ClampedArray(l.buffer),t.Vt.width,t.Vt.height)),o,a),void 0===t.ei.Bt.correct&&(t.ei.Bt.correct={}),t.ei.Bt.correct[e]=r}return await h.convertToBlob({type:"image/png"})}si(t){"BlueMarble"==t?.whoami&&i(this,X,q).call(this,t)}Ue(t){this.je=t}}(et,it),ht=new class{constructor(t){this.qt=t,this.oi=!1,this.ze="",this.Fe=[],this.ai=[]}ri(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(o){case"me":if(n.status&&"2"!=n.status?.toString()[0])return void t.yt("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(n.id||n.id,this.qt.Ge=n.id,0!=this.ze.length){const t=document.querySelector("#"+this.ze);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.Fe.length&&(!o.length||!h.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.Fe=[...o,...h];const c=(a=o,r=h,[parseInt(a[0])%4*1e3+parseInt(r[0]),parseInt(a[1])%4*1e3+parseInt(r[1])]),m=document.querySelectorAll("span");for(const t of m){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 d=i.endpoint.split("/");d=[parseInt(d[d.length-2]),parseInt(d[d.length-1].replace(".png",""))];const u=i.blobID,b=i.blobData,p=(Date.now(),await this.qt.ti(b,d));window.postMessage({source:"blue-marble",blobID:u,blobData:p,blink:i.blink});break;case"robots":this.oi="false"==n.userscript?.toString().toLowerCase()}var a,r})}async li(t){let e=GM_getValue("bmUserSettings","{}");if(e=JSON.parse(e),!e||!e.telemetry||!e.uuid)return;const i=navigator.userAgent;let n=await this.hi(i),s=this.ci(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 hi(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"}ci(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"}}(lt),ct=new class extends L{constructor(t,i,n){var s;super(t,i),e(this,T),this.kt=n,(s=this.kt).flags??(s.flags=[]),this.mi=structuredClone(this.kt),this.di="bmUserSettings",this.ui=5e3,this.bi=0,setInterval(this.pi.bind(this),this.ui)}async pi(){const t=JSON.stringify(this.kt);t!=JSON.stringify(this.mi)&&Date.now()-this.bi>this.ui&&(await GM.setValue(this.di,t),this.mi=structuredClone(this.kt),this.bi=Date.now())}fi(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)}$t(){const t='',e='',n=this.kt?.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().V().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Highlight transparent pixels"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noTrans"),i.onchange=t=>this.fi("hl-noTrans",!t.target.checked)}).D().N({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,T,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,T,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,T,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,T,S).call(this,"Full")}).D().D().D().N({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,T,$).call(this,s,[e,t])}).D()}this.window=this.D().D().D()}St(){this.window=this.H({class:"bm-L"}).W(2,{textContent:"Pixel Highlight"}).D().V().D().H({class:"bm-L",style:"margin-left: 1.5ch;"}).R({textContent:"Template creation should skip transparent tiles"},(t,e,i)=>{i.checked=!this.kt?.flags?.includes("hl-noSkip"),i.onchange=t=>this.fi("hl-noSkip",!t.target.checked)}).D().R({innerHTML:"Experimental: Template creation should aggressively skip transparent tiles"},(t,e,i)=>{i.checked=this.kt?.flags?.includes("hl-agSkip"),i.onchange=t=>this.fi("hl-agSkip",t.target.checked)}).D().D().D()}}(et,it,at);rt.k(ct),rt.S(ht),lt.Ye(rt),lt.k(ct);var mt=JSON.parse(GM_getValue("bmTemplates","{}"));if(lt.si(mt),0==Object.keys(at).length){const t=crypto.randomUUID();GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>ht.li(it),18e5);var dt=at?.telemetry;if(null==dt||dt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,Q),this.window=null,this.Ct="bm-k",this.Mt=document.body,this.gi=n,this.uuid=s}async Tt(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.hi(navigator.userAgent),e=this.p.ci(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().V().D().H({class:"bm-L bm-D",style:"gap: 1.5ch; flex-wrap: wrap;"}).lt({textContent:"Enable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,Q,K).call(this,this.gi);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,Q,K).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().N({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().V().D().H({class:"bm-L"}).W(2,{textContent:"Non-Legal Summary"}).D().N({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().J().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().N({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().L(this.Mt)}}(et,it,1,at?.uuid);t.S(ht),t.Tt()}rt.Tt(),ht.ri(rt),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${et}%c (${it}) userscript has loaded!`,"color: cornflowerblue;","")})(); \ No newline at end of file +(()=>{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?.$t??(()=>{});if(!n||!s)return void this.yt(`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?.$t??(()=>{});if(!n||!s)return void this.yt(`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,$=(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,n.style.width=`${m}px`,n.style.height=`${d}px`),p=requestAnimationFrame(y)}},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),y()},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=$(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())};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)}yt(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,$),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")}};$=new WeakSet,y=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=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`))}},K=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="id",this.sortSecondary="ascending",this.showUnused=!1}we(){this.$?.Nt?.flags?.includes(this.Qt)?this.xe():this.St()}St(){if(document.querySelector(`#${this.Ct}`))return void i(this,B,P).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,A).call(this,!0),i(this,B,P).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,P).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.$e(),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,E).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,R).call(this,t),i(this,B,E).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,P).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,A).call(this,!1),i(this,B,P).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,P).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.$e(),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,G).call(this);const t=document.querySelector(`#${this.Ct} .bm-L.bm-H`);i(this,B,R).call(this,t),i(this,B,E).call(this,this.sortPrimary,this.sortSecondary,this.showUnused)}$e(){i(this,B,Y).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]={ye: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,ye: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,E).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(t){this.$&&(this.$.ke(this.Qt,t),this.$.De())},P=function(){const t=document.querySelector(`#${this.Ct}`);t?.classList.contains("bm-N")&&i(this,B,_).call(this,t),i(this,B,z).call(this),t?.remove()},z=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)},W=function(t,e,i){const n=Math.max(e,i);return Math.min(Math.max(Math.round(Number(t)||e),e),n)},F=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)}},V=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,W).call(this,n,this.ne,Math.min(this.oe,window.innerWidth-16)),t.style.width=`${e.width}px`),a&&(e.height=i(this,B,W).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,F).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())})},_=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,W).call(this,n.width,this.ne,Math.min(this.oe,window.innerWidth-16)),o=i(this,B,W).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,F).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()},U=function(t,e=150){this.ie&&clearTimeout(this.ie),this.ie=setTimeout(()=>{this.ie=null,i(this,B,_).call(this,t)},e)},G=function(){const t=document.querySelector(`#${this.Ct}.bm-W`);t&&(i(this,B,z).call(this),i(this,B,V).call(this,t),this.xt(`#${this.Ct}.bm-W`,`#${this.Ct} .bm-S`,{$t:({element:t})=>i(this,B,_).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),$t:({element:t})=>i(this,B,_).call(this,t)}),"function"==typeof ResizeObserver&&(this.te=new ResizeObserver(()=>i(this,B,U).call(this,t)),this.te.observe(t)),this.ee=()=>i(this,B,U).call(this,t,0),window.addEventListener("resize",this.ee))},R=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.$e();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,ye: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())}},Y=function(){this.fe=0,this.pe=0,this.be=new Map,this.ue=new Map;for(const t of this.re.He){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 tt=class extends M{constructor(t,i,n,s=void 0){super(t,i),e(this,J),this.window=null,this.Ct="bm-u",this.Tt=document.body,this.Le=JSON.parse(GM_getValue("bmTemplates","{}")),this.scriptVersion=this.Le?.scriptVersion,this.schemaVersion=this.Le?.schemaVersion,this.Oe=void 0,this.Be=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,J,X).call(this),i(this,J,q).call(this)}};J=new WeakSet,X=function(){const t=this.schemaVersion.split(/[-\.\+]/),e=this.Be.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.Oe="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.Oe="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.Oe="Bad"):(n='Template storage health: Dead!
Blue Marble can not load the template storage. (Reason: MAJOR version unknown)',this.Oe="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.Be)}.
Wplace was last updated on ${l}.${"Good"!=this.Oe?s:""}`);const h=new M(this.name,this.version);"Dead"!=this.Oe&&(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.Ie().then(()=>{e.disabled=!1})}}).D()),"Poor"!=this.Oe&&"Bad"!=this.Oe||h.lt({textContent:`Update template storage to ${this.Be}`},(t,e)=>{e.onclick=()=>{e.disabled=!0,i(this,J,Z).call(this,!0)}}).D(),h.D().N(document.querySelector("#bm-v").parentNode)},q=function(){const t=this.Le?.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.Ae),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)}},Z=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.Le?.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.Pe(t);await this.re.ze(e,t.displayName,t.coords)}t&&(console.log("Restarting Template Wizard..."),document.querySelector(`#${this.Ct}`).remove(),new tt(this.name,this.version,this.Be,this.re).St())};var et,it,nt,st,ot,at,rt,lt,ht,ct=tt;et=new WeakSet,it=function(){new K(this).we()},nt=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]||""))},st=new WeakSet,ot=async function(){GM.setValue("bmTemplates",JSON.stringify(this.We))},at=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 ct(this.name,this.version,this.schemaVersion,this).St(),this.He=await async function({It:t,Fe:i,He: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.He?.length||0,Lt:r||""});p.At=h,p.Ot=m,p.Bt=d,n.push(p),console.log(this.He),console.log("^^^ This ^^^")}}return n}({It:this.It,Fe:this.Fe,He:this.He})):n[0]>>24&255,$=g>>>24&255,y=b.get(w)??-2,v=b.get(g)??-2;if(this.Ne.get(y)&&(e[i*h+c]=g),-1==y){const t=536870912;this.Ne.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(!s&&x>m&&v!=y&&(d||$>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==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),{Ye:p,Je:e}},lt=new WeakSet,ht=function(t){const e=JSON.parse(GM_getValue("bmUserSettings","{}"));e.telemetry=t,GM.setValue("bmUserSettings",JSON.stringify(e))};var mt=GM_info.script.name.toString(),dt=GM_info.script.version.toString();!function(t){const e=document.createElement("script");e.setAttribute("bm-11",mt),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 ut=GM_getResourceText("CSS-BM-File");GM_addStyle(ut);var bt,pt="robotoMonoInjectionPoint";pt.indexOf("@font-face")+1?(console.log("Loading Roboto Mono as a file..."),GM_addStyle(pt)):((bt=document.createElement("link")).href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap",bt.rel="preload",bt.as="style",bt.onload=function(){this.onload=null,this.rel="stylesheet"},document.head?.appendChild(bt));var ft=JSON.parse(GM_getValue("bmUserSettings","{}")),gt=(new class{constructor(){this.Xe=null,this.qe=null,this.Ze="#bm-p"}Qe(t){return this.qe=t,this.Xe=new MutationObserver(t=>{for(const e of t)for(const t of e.addedNodes)t instanceof HTMLElement&&t.matches?.(this.Ze)}),this}Ke(){return this.Xe}observe(t,e=!1,i=!1){t.observe(this.qe,{childList:e,subtree:i})}},new class extends M{constructor(t,i){super(t,i),e(this,et),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.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.ti=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?.ei;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?")}}).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,et,nt).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,et,nt).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,et,nt).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,et,nt).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?.ii(!1),e.dataset.buttonStatus="hidden",e.textContent="Enable",t.Mt("Disabled templates!")):(t.p?.re?.ii(!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.yt("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.yt("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.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?.re.ze(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.yt("No file selected!")}}).D().lt({textContent:"Filter"},(t,e)=>{e.onclick=()=>i(this,et,it).call(this)}).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 ct(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 Q(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`))}}(mt,dt)),wt=new class{constructor(t,i){e(this,st),this.name=t,this.version=i,this.Ve=null,this.$=null,this.schemaVersion="2.0.0",this.ni=null,this.Ae="!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",this.It=1e3,this.Fe=3,this.je=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.je),this.Ue=null,this.si="",this.He=[],this.We=null,this.oi=!0,this.ai=null,this.Ne=new Map}ri(t){this.Ve=t}k(t){this.$=t}async li(){return{whoami:this.name.replace(" ",""),scriptVersion:this.version,schemaVersion:this.schemaVersion,templates:{}}}async ze(t,e,n){this.We||(this.We=await this.li(),console.log("Creating JSON...")),this.Ve.Mt(`Creating template at ${n.join(", ")}...`);const s=new H({displayName:e,Ht:0,Lt:m(this.ni||0,this.Ae),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.We.templates[`${s.Ht} ${s.Lt}`]={name:s.displayName,coords:n.join(", "),enabled:!0,pixels:h,tiles:l},this.He=[],this.He.push(s),this.Ve.Mt(`Template created at ${n.join(", ")}!`),console.log(Object.keys(this.We.templates).length),console.log(this.We),console.log(this.He),console.log(JSON.stringify(this.We)),await i(this,st,ot).call(this)}hi(){}async ci(){this.We||(this.We=await this.li(),console.log("Creating JSON..."))}async mi(){l("Downloading all templates..."),console.log(this.He);for(const t of this.He)await this.di(t),await n(500)}async Ie(){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.di(new H({displayName:i.name,Ht:e.split(" ")?.[0],Lt:e.split(" ")?.[1],Ot:i.tiles})),await n(500))}async di(t){t.jt();const e=`${t.coords.join("-")}_${t.displayName.replaceAll(" ","-")}`,i=await this.Pe(t);await GM.download({url:URL.createObjectURL(i),name:e+".png",ui:"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 Pe(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.Fe),r=Math.max(r,u+m.height/this.Fe)}),console.log(`Absolute coordinates: (${s}, ${o}) and (${a}, ${r})`);const l=a-s,h=r-o,c=l*this.Fe,m=h*this.Fe;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.Fe,(m-o)*this.Fe,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.Fe,h*this.Fe,0,0,l,h),b.convertToBlob({type:"image/png"})}async bi(t,e){if(!this.oi)return t;const n=this.It*this.Fe;e=e[0].toString().padStart(4,"0")+","+e[1].toString().padStart(4,"0"),console.log(`Searching for templates in tile: "${e}"`);const o=this.He;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{pi:t,Vt:t.Ot[e],Bt:t.Bt?.[e],fi:[i[0],i[1]],gi:[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.Ve.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.Ve.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.pi.At?.colors?.get(-1);let s=t.Bt.slice();const o=Number(t.gi[0])*this.Fe,a=Number(t.gi[1])*this.Fe;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(),{Ye:l,Je:h}=i(this,st,rt).call(this,{_e:d,Ue:s,Ge:[o,a,t.Vt.width,t.Vt.height],Re:u,Ee: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.pi.At.correct&&(t.pi.At.correct={}),t.pi.At.correct[e]=l}return await h.convertToBlob({type:"image/png"})}wi(t){console.log("Importing JSON..."),console.log(t),"BlueMarble"==t?.whoami&&i(this,st,at).call(this,t)}ii(t){this.oi=t}}(mt,dt),xt=new class{constructor(t){this.re=t,this.xi=!1,this.ti="",this.ei=[],this.$i=[]}yi(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.yt("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.ni=n.id,0!=this.ti.length){const t=document.querySelector("#"+this.ti);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.ei.length&&(!o.length||!h.length))return void t.yt("Coordinates are malformed!\nDid you try clicking the canvas first?");this.ei=[...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.bi(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.xi="false"==n.userscript?.toString().toLowerCase();break}var a,r})}async Mi(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.Ci(i),s=this.Ti(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 Ci(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"}Ti(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"}}(wt),$t=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.Si=structuredClone(this.Nt),this.ki="bmUserSettings",this.Di=5e3,this.Ni=0,setInterval(this.Hi.bind(this),this.Di)}async Hi(){await this.Li()}async Li(t=!1){const e=JSON.stringify(this.Nt);e!=JSON.stringify(this.Si)&&(t||Date.now()-this.Ni>this.Di)&&(await GM.setValue(this.ki,e),this.Si=structuredClone(this.Nt),this.Ni=Date.now(),console.log(e))}async De(){await this.Li(!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()}}(mt,dt,ft);gt.k($t),gt.S(xt),wt.ri(gt),wt.k($t);var yt=JSON.parse(GM_getValue("bmTemplates","{}"));if(console.log(yt),wt.wi(yt),console.log(ft),console.log(Object.keys(ft).length),0==Object.keys(ft).length){const t=crypto.randomUUID();console.log(t),GM.setValue("bmUserSettings",JSON.stringify({uuid:t}))}setInterval(()=>xt.Mi(dt),18e5);var vt=ft?.telemetry;if(console.log(`Telemetry is ${!(null==vt)}`),null==vt||vt>1){const t=new class extends M{constructor(t,i,n,s){super(t,i),e(this,lt),this.window=null,this.Ct="bm-k",this.Tt=document.body,this.Oi=n,this.uuid=s}async St(){if(document.querySelector(`#${this.Ct}`))return void this.yt("Telemetry window already exists!");const t=await this.p.Ci(navigator.userAgent),e=this.p.Ti(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,lt,ht).call(this,this.Oi);const t=document.getElementById(this.Ct);t?.remove()}}).D().lt({textContent:"Disable Telemetry"},(t,e)=>{e.onclick=()=>{i(this,lt,ht).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)}}(mt,dt,1,ft?.uuid);t.S(xt),t.St()}gt.St(),xt.yi(gt),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${mt}%c (${dt}) userscript has loaded!`,"color: cornflowerblue;","")})(); + +// Build Hash: 68129f2f0f9c diff --git a/package-lock.json b/package-lock.json index f078be1..00f5750 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wplace-bluemarble", - "version": "0.91.116", + "version": "0.92.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wplace-bluemarble", - "version": "0.91.116", + "version": "0.92.1", "devDependencies": { "esbuild": "^0.25.0", "jsdoc": "^4.0.5", @@ -37,6 +37,7 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "dev": true, + "peer": true, "dependencies": { "@babel/types": "^7.28.0" }, @@ -52,6 +53,7 @@ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "dev": true, + "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" @@ -544,7 +546,6 @@ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "dev": true, - "peer": true, "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" @@ -741,7 +742,6 @@ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, - "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", diff --git a/package.json b/package.json index 95f85fa..1f4f3e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wplace-bluemarble", - "version": "0.92.0", + "version": "0.92.1", "type": "module", "homepage": "https://bluemarble.lol/", "repository": { diff --git a/src/BlueMarble.meta.js b/src/BlueMarble.meta.js index d08e900..e6b6798 100644 --- a/src/BlueMarble.meta.js +++ b/src/BlueMarble.meta.js @@ -2,7 +2,7 @@ // @name Blue Marble // @name:en Blue Marble // @namespace https://github.com/SwingTheVine/ -// @version 0.92.0 +// @version 0.92.1 // @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features. // @author SwingTheVine diff --git a/src/Overlay.js b/src/Overlay.js index 96ceb2a..9dc51a9 100644 --- a/src/Overlay.js +++ b/src/Overlay.js @@ -1278,11 +1278,12 @@ export default class Overlay { * @param {string} iMoveThingsSelector - The drag handle element * @since 0.8.2 */ - handleDrag(moveMeSelector, iMoveThingsSelector) { + handleDrag(moveMeSelector, iMoveThingsSelector, options = {}) { // Retrieves the elements const moveMe = document.querySelector(moveMeSelector); const iMoveThings = document.querySelector(iMoveThingsSelector); + const onEnd = options?.onEnd ?? (() => {}); // What to do when one of the two elements are not found if (!moveMe || !iMoveThings) { @@ -1375,6 +1376,14 @@ export default class Overlay { document.removeEventListener('mouseup', endDrag); document.removeEventListener('touchend', endDrag); document.removeEventListener('touchcancel', endDrag); + + onEnd({ + element: moveMe, + x: currentX, + y: currentY + }); + + initialRect = null; }; // Mouse move @@ -1411,6 +1420,135 @@ export default class Overlay { }, { passive: false }); } + /** Handles resizing of an overlay window from a resize handle. + * @param {string} resizeMeSelector - The element to resize + * @param {string} iResizeThingsSelector - The resize handle element + * @param {{onEnd?: function({element: HTMLElement, width: number, height: number}): void, minWidth?: number, minHeight?: number, maxWidth?: number, maxHeight?: number}} [options={}] + * @since 0.92.0 + */ + handleResize(resizeMeSelector, iResizeThingsSelector, options = {}) { + + const resizeMe = document.querySelector(resizeMeSelector); + const iResizeThings = document.querySelector(iResizeThingsSelector); + const onEnd = options?.onEnd ?? (() => {}); + + if (!resizeMe || !iResizeThings) { + this.handleDisplayError(`Can not resize! ${!resizeMe ? 'resizeMe' : ''} ${!resizeMe && !iResizeThings ? 'and ' : ''}${!iResizeThings ? 'iResizeThings ' : ''}was not found!`); + return; + } + + let isResizing = false; + let startX = 0; + let startY = 0; + let startWidth = 0; + let startHeight = 0; + let currentWidth = 0; + let currentHeight = 0; + let targetWidth = 0; + let targetHeight = 0; + let animationFrame = null; + + const getMaximumWidth = () => Number.isFinite(options?.maxWidth) ? options.maxWidth : window.innerWidth - 16; + const getMaximumHeight = () => Number.isFinite(options?.maxHeight) ? options.maxHeight : window.innerHeight - 16; + const minimumWidth = Number.isFinite(options?.minWidth) ? options.minWidth : 200; + const minimumHeight = Number.isFinite(options?.minHeight) ? options.minHeight : 160; + + const clamp = (value, minimum, maximum) => Math.min(Math.max(value, minimum), Math.max(minimum, maximum)); + + const updateSize = () => { + if (isResizing) { + const deltaWidth = Math.abs(currentWidth - targetWidth); + const deltaHeight = Math.abs(currentHeight - targetHeight); + + if (deltaWidth > 0.5 || deltaHeight > 0.5) { + currentWidth = targetWidth; + currentHeight = targetHeight; + resizeMe.style.width = `${currentWidth}px`; + resizeMe.style.height = `${currentHeight}px`; + } + + animationFrame = requestAnimationFrame(updateSize); + } + }; + + const startResize = (clientX, clientY) => { + isResizing = true; + startX = clientX; + startY = clientY; + startWidth = resizeMe.offsetWidth; + startHeight = resizeMe.offsetHeight; + currentWidth = startWidth; + currentHeight = startHeight; + targetWidth = startWidth; + targetHeight = startHeight; + + document.body.style.userSelect = 'none'; + iResizeThings.classList.add('bm-resizing'); + + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('touchmove', onTouchMove, { passive: false }); + document.addEventListener('mouseup', endResize); + document.addEventListener('touchend', endResize); + document.addEventListener('touchcancel', endResize); + + if (animationFrame) { + cancelAnimationFrame(animationFrame); + } + updateSize(); + }; + + const endResize = () => { + isResizing = false; + if (animationFrame) { + cancelAnimationFrame(animationFrame); + animationFrame = null; + } + document.body.style.userSelect = ''; + iResizeThings.classList.remove('bm-resizing'); + + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('touchmove', onTouchMove); + document.removeEventListener('mouseup', endResize); + document.removeEventListener('touchend', endResize); + document.removeEventListener('touchcancel', endResize); + + onEnd({ + element: resizeMe, + width: currentWidth, + height: currentHeight + }); + }; + + const onMouseMove = event => { + if (!isResizing) {return;} + targetWidth = clamp(startWidth + (event.clientX - startX), minimumWidth, getMaximumWidth()); + targetHeight = clamp(startHeight + (event.clientY - startY), minimumHeight, getMaximumHeight()); + }; + + const onTouchMove = event => { + if (!isResizing) {return;} + const touch = event?.touches?.[0]; + if (!touch) {return;} + targetWidth = clamp(startWidth + (touch.clientX - startX), minimumWidth, getMaximumWidth()); + targetHeight = clamp(startHeight + (touch.clientY - startY), minimumHeight, getMaximumHeight()); + event.preventDefault(); + }; + + iResizeThings.addEventListener('mousedown', event => { + event.preventDefault(); + event.stopPropagation(); + startResize(event.clientX, event.clientY); + }); + + iResizeThings.addEventListener('touchstart', event => { + const touch = event?.touches?.[0]; + if (!touch) {return;} + event.preventDefault(); + event.stopPropagation(); + startResize(touch.clientX, touch.clientY); + }, { passive: false }); + } + /** Handles status display. * This will output plain text into the output Status box. * Additionally, this will output an info message to the console. @@ -1434,4 +1572,4 @@ export default class Overlay { consoleError(`${this.name}: ${text}`); // Outputs something like "ScriptName: text" as an error message to the console this.updateInnerHTML(this.outputStatusId, 'Error: ' + text, true); // Update output Status box } -} \ No newline at end of file +} diff --git a/src/WindowFilter.css b/src/WindowFilter.css index bc5135f..aec51eb 100644 --- a/src/WindowFilter.css +++ b/src/WindowFilter.css @@ -98,33 +98,117 @@ /* WINDOWED MODE */ +/* Resizable filter window in windowed mode */ +#bm-window-filter.bm-windowed { + --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; + 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; +} + +/* 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-row: 2; + min-height: 0; + min-width: 0; + overflow: hidden; +} + /* Filter flex in windowed mode */ #bm-window-filter.bm-windowed #bm-filter-flex { flex-direction: column; + align-items: stretch; gap: 0.25em; + width: 100%; + align-self: stretch; + min-width: 0; + box-sizing: border-box; } /* Filter color in windowed mode */ #bm-window-filter.bm-windowed .bm-filter-color { - width: auto; + width: 100%; + max-width: none; + align-self: stretch; + flex: 1 1 auto; + min-width: 0; margin: 0; padding: 0; + box-sizing: border-box; +} + +#bm-window-filter.bm-windowed .bm-filter-color > .bm-flex-between { + width: 100%; + min-width: 0; + flex: 1 1 auto; +} + +/* 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; + min-height: 0; + min-width: 0; + height: 100%; + width: 100%; + max-height: 100% !important; + overflow: auto; + box-sizing: border-box; +} + +/* 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; + 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-window-filter.bm-windowed .bm-resize-corner:hover, +#bm-window-filter.bm-windowed .bm-resize-corner.bm-resizing { + opacity: 1; } /* Filter window container for RGB color display in windowed mode */ #bm-window-filter.bm-windowed .bm-filter-container-rgb { display: flex; width: 100%; + min-width: 0; + flex: 1 1 auto; gap: 0.5ch; align-items: center; padding: 0.1em 0.5ch; border: none; border-radius: 1em; + box-sizing: border-box; } /* Filter window hide color button */ #bm-window-filter.bm-windowed .bm-filter-container-rgb button { padding: 0.5em 0.25ch; + flex: 0 0 auto; } /* Filter window hide color button SVG in windowed mode */ @@ -135,9 +219,13 @@ /* Filter window header 2 in windowed mode */ #bm-window-filter.bm-windowed .bm-filter-color h2 { font-size: 0.75em; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } /* Filter window dragbar text area in windowed mode */ #bm-window-filter #bm-filter-windowed-color-totals { font-size: 1em; -} \ No newline at end of file +} diff --git a/src/WindowFilter.js b/src/WindowFilter.js index 9cedaa8..b9c54a2 100644 --- a/src/WindowFilter.js +++ b/src/WindowFilter.js @@ -21,6 +21,16 @@ export default class WindowFilter extends Overlay { this.windowID = 'bm-window-filter'; // The ID attribute for this window this.colorListID = 'bm-filter-flex'; // The ID attribute for the color list this.windowParent = document.body; // The parent of the window DOM tree + this.settingsManager = executor.settingsManager ?? null; // Settings manager from the executor + this.windowModeFlag = 'ftr-oWin'; // User setting flag for opening the filter in windowed mode + this.windowStateKey = 'windowFilter'; // User setting key for the persisted window state + 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.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 + this.windowMaxHeight = 1400; // Maximum height for the windowed filter /** The templateManager instance currently being used. @type {TemplateManager} */ this.templateManager = executor.apiManager?.templateManager; @@ -51,6 +61,17 @@ export default class WindowFilter extends Overlay { this.showUnused = false; // Were unused colors shown the last time the user sorted the color list? } + /** Builds the preferred filter window mode for the user. + * @since 0.92.0 + */ + buildPreferredWindow() { + if (this.settingsManager?.userSettings?.flags?.includes(this.windowModeFlag)) { + this.buildWindowed(); + return; + } + this.buildWindow(); + } + /** Spawns a Color Filter window. * If another color filter window already exists, we DON'T spawn another! * Parent/child relationships in the DOM structure below are indicated by indentation. @@ -60,7 +81,7 @@ export default class WindowFilter extends Overlay { // If a color filter wizard window already exists, close it if (document.querySelector(`#${this.windowID}`)) { - document.querySelector(`#${this.windowID}`).remove(); + this.#closeWindow(); return; } @@ -79,13 +100,14 @@ export default class WindowFilter extends Overlay { .addDiv({'class': 'bm-flex-center'}) .addButton({'class': 'bm-button-circle', 'textContent': '🗗', 'aria-label': 'Switch to windowed mode for "Color Filter"'}, (instance, button) => { button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); + this.#setWindowModePreference(true); + this.#closeWindow(); this.buildWindowed(); }; button.ontouchend = () => {button.click();}; // Needed only to negate weird interaction with dragbar }).buildElement() .addButton({'class': 'bm-button-circle', 'textContent': '✖', 'aria-label': 'Close window "Color Filter"'}, (instance, button) => { - button.onclick = () => {document.querySelector(`#${this.windowID}`)?.remove();}; + button.onclick = () => this.#closeWindow(); button.ontouchend = () => {button.click();}; // Needed only to negate weird interaction with dragbar }).buildElement() .buildElement() @@ -202,12 +224,16 @@ export default class WindowFilter extends Overlay { // If a color filter wizard window already exists, close it if (document.querySelector(`#${this.windowID}`)) { - document.querySelector(`#${this.windowID}`).remove(); + this.#closeWindow(); return; } // Creates a new windowed color filter window - this.window = this.addDiv({'id': this.windowID, 'class': 'bm-window bm-windowed'}) + this.window = this.addDiv({ + 'id': this.windowID, + 'class': 'bm-window bm-windowed', + 'style': `width: 300px; height: min(70vh, 32rem); min-width: ${this.windowMinWidth}px; min-height: ${this.windowMinHeight}px; max-width: min(${this.windowMaxWidth}px, calc(100vw - 16px)); max-height: min(${this.windowMaxHeight}px, calc(100vh - 16px));` + }) .addDragbar() .addButton({'class': 'bm-button-circle', 'textContent': '▼', 'aria-label': 'Minimize window "Color Filter"', 'data-button-status': 'expanded'}, (instance, button) => { button.onclick = () => { @@ -226,13 +252,14 @@ export default class WindowFilter extends Overlay { .addDiv({'class': 'bm-flex-center'}) .addButton({'class': 'bm-button-circle', 'textContent': '🗖', 'aria-label': 'Switch to fullscreen mode for "Color Filter"'}, (instance, button) => { button.onclick = () => { - document.querySelector(`#${this.windowID}`)?.remove(); + this.#setWindowModePreference(false); + this.#closeWindow(); this.buildWindow(); }; button.ontouchend = () => {button.click();}; // Needed only to negate weird interaction with dragbar }).buildElement() .addButton({'class': 'bm-button-circle', 'textContent': '✖', 'aria-label': 'Close window "Color Filter"'}, (instance, button) => { - button.onclick = () => {document.querySelector(`#${this.windowID}`)?.remove();}; + button.onclick = () => this.#closeWindow(); button.ontouchend = () => {button.click();}; // Needed only to negate weird interaction with dragbar }).buildElement() .buildElement() @@ -261,10 +288,17 @@ export default class WindowFilter extends Overlay { // Color list will appear here .buildElement() .buildElement() + .addDiv({ + 'class': 'bm-resize-corner', + '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;' + }).buildElement() .buildElement().buildOverlay(this.windowParent); - // Creates dragging capability on the drag bar for dragging the window - this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`); + this.#initializeWindowedPersistence(); // Obtains the scrollable container to put the color filter in const scrollableContainer = document.querySelector(`#${this.windowID} .bm-container.bm-scrollable`); @@ -274,6 +308,206 @@ export default class WindowFilter extends Overlay { this.#sortColorList(this.sortPrimary, this.sortSecondary, this.showUnused); } + /** Retrieves the persisted window state object. + * @returns {Object | null} + * @since 0.92.0 + */ + #getWindowState() { + if (!this.settingsManager) {return null;} + this.settingsManager.userSettings[this.windowStateKey] ??= {}; + return this.settingsManager.userSettings[this.windowStateKey]; + } + + /** Updates the preferred window mode setting. + * @param {boolean} shouldBeWindowed + * @since 0.92.0 + */ + #setWindowModePreference(shouldBeWindowed) { + if (!this.settingsManager) {return;} + this.settingsManager.toggleFlag(this.windowModeFlag, shouldBeWindowed); + void this.settingsManager.saveUserStorageNow(); + } + + /** Immediately closes the filter window and cleans up persistence observers. + * @since 0.92.0 + */ + #closeWindow() { + const windowElement = document.querySelector(`#${this.windowID}`); + if (windowElement?.classList.contains('bm-windowed')) { + this.#saveWindowState(windowElement); + } + this.#cleanupWindowPersistence(); + windowElement?.remove(); + } + + /** Disconnects live observers used for window persistence. + * @since 0.92.0 + */ + #cleanupWindowPersistence() { + if (this.windowResizeObserver) { + this.windowResizeObserver.disconnect(); + this.windowResizeObserver = null; + } + if (this.windowViewportResizeHandler) { + window.removeEventListener('resize', this.windowViewportResizeHandler); + this.windowViewportResizeHandler = null; + } + if (this.windowSaveTimeout) { + clearTimeout(this.windowSaveTimeout); + this.windowSaveTimeout = null; + } + } + + /** Returns a clamped dimension value for the window. + * @param {number} size - The size in pixels + * @param {number} minimum - Minimum allowed size + * @param {number} maximum - Maximum allowed size + * @returns {number} + * @since 0.92.0 + */ + #clampWindowDimension(size, minimum, maximum) { + const resolvedMaximum = Math.max(minimum, maximum); + return Math.min(Math.max(Math.round(Number(size) || minimum), minimum), resolvedMaximum); + } + + /** Returns a viewport-safe position for the window. + * @param {HTMLElement} windowElement + * @param {number} x + * @param {number} y + * @returns {{x: number, y: number}} + * @since 0.92.0 + */ + #clampWindowPosition(windowElement, x, y) { + const margin = 8; + const maxX = Math.max(margin, window.innerWidth - windowElement.offsetWidth - margin); + const maxY = Math.max(margin, window.innerHeight - windowElement.offsetHeight - margin); + return { + x: Math.min(Math.max(Math.round(Number(x) || margin), margin), maxX), + y: Math.min(Math.max(Math.round(Number(y) || margin), margin), maxY) + }; + } + + /** Applies the persisted size and position to the windowed filter. + * @param {HTMLElement} windowElement + * @since 0.92.0 + */ + #restoreWindowState(windowElement) { + const windowState = this.#getWindowState(); + if (!windowState || !windowElement) {return;} + + const width = Number(windowState.width); + const height = Number(windowState.height); + const hasWidth = Number.isFinite(width); + const hasHeight = Number.isFinite(height); + + if (hasWidth) { + windowState.width = this.#clampWindowDimension(width, this.windowMinWidth, Math.min(this.windowMaxWidth, window.innerWidth - 16)); + windowElement.style.width = `${windowState.width}px`; + } + if (hasHeight) { + windowState.height = this.#clampWindowDimension(height, this.windowMinHeight, Math.min(this.windowMaxHeight, window.innerHeight - 16)); + windowElement.style.height = `${windowState.height}px`; + } + + requestAnimationFrame(() => { + if (!windowElement.isConnected) {return;} + + const x = Number(windowState.x); + const y = Number(windowState.y); + if (!Number.isFinite(x) || !Number.isFinite(y)) {return;} + + const clampedPosition = this.#clampWindowPosition(windowElement, x, y); + windowElement.style.left = '0px'; + windowElement.style.top = '0px'; + windowElement.style.right = ''; + windowElement.style.transform = `translate(${clampedPosition.x}px, ${clampedPosition.y}px)`; + + if ((clampedPosition.x != x) || (clampedPosition.y != y)) { + windowState.x = clampedPosition.x; + windowState.y = clampedPosition.y; + void this.settingsManager?.saveUserStorageNow(); + } + }); + } + + /** Saves the current size and position of the windowed filter. + * @param {HTMLElement} windowElement + * @since 0.92.0 + */ + #saveWindowState(windowElement) { + const windowState = this.#getWindowState(); + if (!windowState || !windowElement?.isConnected || !windowElement.classList.contains('bm-windowed')) {return;} + + const rect = windowElement.getBoundingClientRect(); + const width = this.#clampWindowDimension(rect.width, this.windowMinWidth, Math.min(this.windowMaxWidth, window.innerWidth - 16)); + const height = this.#clampWindowDimension(rect.height, this.windowMinHeight, Math.min(this.windowMaxHeight, window.innerHeight - 16)); + + if (Math.round(rect.width) != width) { + windowElement.style.width = `${width}px`; + } + if (Math.round(rect.height) != height) { + windowElement.style.height = `${height}px`; + } + + const clampedPosition = this.#clampWindowPosition(windowElement, rect.left, rect.top); + windowElement.style.left = '0px'; + windowElement.style.top = '0px'; + windowElement.style.right = ''; + windowElement.style.transform = `translate(${clampedPosition.x}px, ${clampedPosition.y}px)`; + + windowState.x = clampedPosition.x; + windowState.y = clampedPosition.y; + windowState.width = width; + windowState.height = height; + + void this.settingsManager?.saveUserStorageNow(); + } + + /** Debounces persisting the current window size and position. + * @param {HTMLElement} windowElement + * @param {number} [delay=150] + * @since 0.92.0 + */ + #scheduleWindowStateSave(windowElement, delay = 150) { + if (this.windowSaveTimeout) { + clearTimeout(this.windowSaveTimeout); + } + this.windowSaveTimeout = setTimeout(() => { + this.windowSaveTimeout = null; + this.#saveWindowState(windowElement); + }, delay); + } + + /** Enables persistence and resize handling for the windowed filter. + * @since 0.92.0 + */ + #initializeWindowedPersistence() { + const windowElement = document.querySelector(`#${this.windowID}.bm-window`); + if (!windowElement) {return;} + + this.#cleanupWindowPersistence(); + this.#restoreWindowState(windowElement); + + this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`, { + onEnd: ({element}) => this.#saveWindowState(element) + }); + this.handleResize(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-resize-corner`, { + minWidth: this.windowMinWidth, + minHeight: this.windowMinHeight, + maxWidth: Math.min(this.windowMaxWidth, window.innerWidth - 16), + maxHeight: Math.min(this.windowMaxHeight, window.innerHeight - 16), + onEnd: ({element}) => this.#saveWindowState(element) + }); + + if (typeof ResizeObserver == 'function') { + this.windowResizeObserver = new ResizeObserver(() => this.#scheduleWindowStateSave(windowElement)); + this.windowResizeObserver.observe(windowElement); + } + + this.windowViewportResizeHandler = () => this.#scheduleWindowStateSave(windowElement, 0); + window.addEventListener('resize', this.windowViewportResizeHandler); + } + /** Creates the color list container. * @param {HTMLElement} parentElement - Parent element to add the color list to as a child * @since 0.88.222 @@ -705,4 +939,4 @@ export default class WindowFilter extends Overlay { this.timeRemaining = new Date(((this.allPixelsTotal - this.allPixelsCorrectTotal) * 30 * 1000) + Date.now()); this.timeRemainingLocalized = localizeDate(this.timeRemaining); } -} \ No newline at end of file +} diff --git a/src/WindowMain.js b/src/WindowMain.js index 3474085..20c4023 100644 --- a/src/WindowMain.js +++ b/src/WindowMain.js @@ -214,7 +214,7 @@ export default class WindowMain extends Overlay { */ #buildWindowFilter() { const windowFilter = new WindowFilter(this); // Creates a new color filter window instance - windowFilter.buildWindow(); + windowFilter.buildPreferredWindow(); } /** Handles pasting into the coordinate input boxes in the main Blue Marble window. @@ -254,4 +254,4 @@ export default class WindowMain extends Overlay { instance.updateInnerHTML('bm-input-py', coords?.[3] || ''); } } -} \ No newline at end of file +} diff --git a/src/overlay.css b/src/overlay.css index 69320ab..51c1388 100644 --- a/src/overlay.css +++ b/src/overlay.css @@ -38,11 +38,6 @@ letter-spacing: 0.05em; } -/* The Blue Marble windowed windows */ -.bm-window.bm-windowed { - max-width: 300px; -} - /* The drag bar */ .bm-dragbar { display: grid; @@ -281,6 +276,7 @@ input[type="file"] { /* Window content container */ .bm-window-content { overflow: hidden; + max-height: calc(100% - 5px); transition: height 300ms cubic-bezier(.4, 0, .2, 1); } @@ -312,7 +308,7 @@ input[type="file"] { /* Scrollable container */ .bm-window .bm-container.bm-scrollable { - max-height: calc(80vh - 150px); + max-height: var(--bm-scrollable-max-height, calc(80vh - 150px)); overflow: auto; } diff --git a/src/settingsManager.js b/src/settingsManager.js index 849e999..21cb975 100644 --- a/src/settingsManager.js +++ b/src/settingsManager.js @@ -16,7 +16,8 @@ import WindowSettings from "./WindowSettings"; * "telemetry": 1, * "flags": ["hl-noTrans", "ftr-oWin", "te-noSkip"], * "highlight": [[1,0,-1],[1,-1,0],[2,1,0],[1,0,1]], - * "filter": [-2,0,4,5,6,29,63] + * "filter": [-2,0,4,5,6,29,63], + * "windowFilter": {"x": 60, "y": 75, "width": 300, "height": 420} * } */ export default class SettingsManager extends WindowSettings { @@ -45,13 +46,21 @@ export default class SettingsManager extends WindowSettings { * @since 0.91.39 */ async updateUserStorage() { + await this.saveUserStorage(); + } + + /** Saves the user settings in userscript storage. + * @param {boolean} [force=false] - Should the throttle be ignored? + * @since 0.92.0 + */ + async saveUserStorage(force = false) { // Turns the objects into a string const userSettingsCurrent = JSON.stringify(this.userSettings); const userSettingsOld = JSON.stringify(this.userSettingsOld); // If the user settings have changed, AND the last update to user storage was over 5 seconds ago (5sec throttle)... - if ((userSettingsCurrent != userSettingsOld) && ((Date.now() - this.lastUpdateTime) > this.updateFrequency)) { + if ((userSettingsCurrent != userSettingsOld) && (force || ((Date.now() - this.lastUpdateTime) > this.updateFrequency))) { await GM.setValue(this.userSettingsSaveLocation, userSettingsCurrent); // Updates user storage this.userSettingsOld = structuredClone(this.userSettings); // Updates the old user settings with a duplicate of the current user settings this.lastUpdateTime = Date.now(); // Updates the variable that contains the last time updated @@ -59,6 +68,13 @@ export default class SettingsManager extends WindowSettings { } } + /** Immediately saves the user settings in userscript storage. + * @since 0.92.0 + */ + async saveUserStorageNow() { + await this.saveUserStorage(true); + } + /** Toggles a boolean flag to the state that was passed in. * If no state was passed in, the flag will flip to the opposite state. * The existence of the flag determines its state. If it exists, it is `true`. @@ -328,4 +344,4 @@ export default class SettingsManager extends WindowSettings { .buildElement() .buildElement() } -} \ No newline at end of file +}