From 503d748443253b69733e398d0f804b68a3f71f9e Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 17 Feb 2025 22:19:37 -0800 Subject: [PATCH 01/17] Create Popup-Phoenix.js --- extensions/SharkPool/Popup-Phoenix.js | 1506 +++++++++++++++++++++++++ 1 file changed, 1506 insertions(+) create mode 100644 extensions/SharkPool/Popup-Phoenix.js diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js new file mode 100644 index 0000000000..273bf57160 --- /dev/null +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -0,0 +1,1506 @@ +// Name: Popup Phoenix +// ID: SPpopups +// Description: Create custom Popups. Inspired by 'Better Input'. +// By: SharkPool +// Licence: MIT + +// Version V.1.0.0 + +(function (Scratch) { + "use strict"; + if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + + const menuIconURI = +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + const getBlockIcon = (name) => { + // lower file size moment + const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return start + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" + }[name]; + }; + + const Cast = Scratch.Cast; + const vm = Scratch.vm; + const runtime = vm.runtime; + const render = vm.renderer; + + const defaultFonts = [ + "Sans Serif", "Serif", "Handwriting", + "Marker", "Curly", "Pixel", "Scratch" + ]; + const translatedInputs = { + popup: Scratch.translate("default-popup"), + label: Scratch.translate("new-label"), + input: Scratch.translate("new-input"), + btnRow: Scratch.translate("default-button-row"), + button: Scratch.translate("submit-button") + }; + + const validInputs = [ + createMenuItem("text", "text"), + createMenuItem("multi-line text", "textarea"), + createMenuItem("password", "password"), + createMenuItem("number", "number"), + createMenuItem("color", "color"), + createMenuItem("date", "date"), + createMenuItem("dropdown", "select"), + createMenuItem("multi-select dropdown", "multiSelect"), + createMenuItem("horizontal slider", "rangeHorz"), + createMenuItem("vertical slider", "rangeVert") + ]; + const validBorders = [ + createMenuItem("none", "none"), + createMenuItem("solid", "solid"), + createMenuItem("dotted", "dotted"), + createMenuItem("dashed", "dashed"), + createMenuItem("double", "double"), + createMenuItem("groove", "groove"), + createMenuItem("ridge", "ridge"), + createMenuItem("inset", "inset"), + createMenuItem("outset", "outset") + ]; + const validEffects = [ + createMenuItem("blur", "blur"), + createMenuItem("brightness", "brightness"), + createMenuItem("opacity", "opacity"), + createMenuItem("saturation", "saturate"), + createMenuItem("hue", "hue-rotate"), + createMenuItem("invert", "invert"), + createMenuItem("sepia", "sepia"), + createMenuItem("contrast", "contrast"), + createMenuItem("direction", "rotate"), + createMenuItem("scale x", "scaleX"), + createMenuItem("scale y", "scaleY"), + createMenuItem("skew x", "skewX"), + createMenuItem("skew y", "skewY") + ]; + + // internals + const styleStorage = { + popups: Object.create(null), + labels: Object.create(null), + inputs: Object.create(null), + buttons: Object.create(null) + } + const elementStorage = { + popups: Object.create(null), + labels: Object.create(null), + inputs: Object.create(null), + buttonRows: Object.create(null), + buttons: Object.create(null) + } + + const xmlEscape = function (unsafe) { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + switch (c) { + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; + } + }); + }; + + const createLabel = (id, text) => { + const element = document.createElement("div"); + element.style.width = "max-content"; + const label = document.createElement("pre"); + label.id = xmlEscape(id); + label.innerHTML = xmlEscape(text).replace(/\n/g, "
"); + label.setAttribute("style", compileStyles(id, "label")); + + element.appendChild(label); + return { + type: "label", + data: { id, text }, + DOMelement: element, + }; + }; + + const createInput = (id, type, options) => { + const inputHolder = document.createElement("div"); + inputHolder.id = xmlEscape(id); + inputHolder.style.width = "max-content"; + let element; + + const setElementValue = (value) => { + inputHolder.setAttribute("returnValue", JSON.stringify(value)); + }; + + if (type === "select") { + const selectors = options.selectors ?? ["no options created"]; + element = document.createElement("select"); + selectors.forEach((option) => { + let opt = document.createElement("option"); + opt.value = option; opt.text = option; + element.appendChild(opt); + }); + + element.addEventListener("focus", () => { options.menuOpened = true }); + element.addEventListener("blur", () => { options.menuOpened = false }); + element.addEventListener("change", (e) => setElementValue([e.target.value])); + setElementValue([selectors[0]]); + } else if (type === "multiSelect") { + const createOption = (text, index) => { + const holder = document.createElement("div"); + holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + + const check = document.createElement("input"); + check.type = "checkbox"; + check.checked = index === 0 ? true : false; + const label = document.createElement("pre"); + label.innerHTML = xmlEscape(text).replace(/\n/g, "
"); + label.setAttribute("style", "margin:0 0 0 5px; font-family: inherit;"); + + holder.append(check, label); + return holder; + }; + + const selectors = options.selectors ?? ["no options created"]; + let response = [selectors[0]]; + options.menuOpened = true; + + element = document.createElement("div"); + const optionsDiv = document.createElement("div"); + optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + element.appendChild(optionsDiv); + + setElementValue(response); + for (let i = 0; i < selectors.length; i++) { + const option = createOption(selectors[i], i); + optionsDiv.appendChild(option); + + option.addEventListener("click", (e) => { + if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + else if (e.target.tagName === "INPUT") { + if (e.target.checked) response.push(selectors[i]); + else response.splice(response.indexOf(selectors[i]), 1); + setElementValue(response); + } + e.stopPropagation(); + }); + } + } else if (type === "textarea") { + element = document.createElement("textarea"); + element.value = options.defaultValue ?? ""; + } else if (type.startsWith("range")) { + element = document.createElement("div"); + + const counter = document.createElement("div"); + counter.setAttribute("style", "text-align: center"); + counter.innerText = options.defaultValue ?? 0; + + const range = document.createElement("input"); + range.setAttribute("style", "display: block; margin: auto;"); + range.type = "range"; + if (type.endsWith("Vert")) range.style.writingMode = "sideways-lr"; + + range.setAttribute("max", options.maxV ?? 100); + range.setAttribute("min", options.minV ?? 0); + range.value = options.defaultValue ?? 0; + range.addEventListener("input", (e) => { + const value = e.target.value; + setElementValue([value]); + counter.innerText = value; + }); + + element.append(range, counter); + setElementValue([counter.innerText]); + } else { + element = document.createElement("input"); + element.type = type; + element.value = options.defaultValue ?? ""; + + if (type === "color") { + inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + const colorStyle = document.createElement("style"); + colorStyle.textContent = ` + input[type="color"] { + cursor: pointer; + } + input[type="color"]::-webkit-color-swatch { + border: black solid 1px; + margin: 1px; + border-radius: 5px; + } + input[type="color"]::-moz-color-swatch { + border: black solid 1px; + margin: 1px; + border-radius: 5px; + } + input[type="color"]::-webkit-color-swatch-wrapper { + padding: 0px; + } + `; + element.append(colorStyle); + } + } + + element.setAttribute("style", compileStyles(id, "input")); + inputHolder.appendChild(element); + return { + type: "input", + data: { id, type, options }, + DOMelement: inputHolder + }; + }; + + const createButtonRow = (id) => { + const buttonRow = document.createElement("div"); + buttonRow.id = xmlEscape(id); + buttonRow.style.width = "max-content"; + + return { + type: "buttonRow", + data: { id, buttons: [] }, + DOMelement: buttonRow + }; + }; + + const createButton = (id, text) => { + const element = document.createElement("button"); + element.id = xmlEscape(id); + element.innerHTML = xmlEscape(text).replace(/\n/g, "
"); + element.setAttribute("returnValue", id); + element.setAttribute("style", compileStyles(id, "button")); + + return { + type: "button", + data: { id, text }, + DOMelement: element + }; + }; + + const genDefaultStyles = (id, type) => { + if (type.endsWith("s")) type = type.substring(0, type.length - 1); + if (type === "popup") { + styleStorage.popups[id] = { + SPstorage: {}, + "display": "flex", + "flex-direction": "column", + "position": "absolute", + "pointer-events": "auto", + "transform": "translate(-50%, -50%)", + "filter": "", + "left": "calc(50% + 0px)", + "top": "calc(50% + 0px)", + "width": "max-content", + "height": "auto", + "padding": "15px", + "background": "#fff", + "box-shadow": "#000 0px 0px 5px", + "border": "1px none #000", + "border-radius": "5px", + }; + } else if (type === "label") { + styleStorage.labels[id] = { + SPstorage: {}, + "font-size": "14px", + "font-family": "Sans Serif", + "margin": "5px", + "color": "#000", + "text-shadow": "none", + "-webkit-text-stroke-width": "0px", + "transform": "", + "filter": "" + }; + } else if (type === "input") { + styleStorage.inputs[id] = { + SPstorage: {}, + "width": "max-content", + "height": "auto", + "margin": "5px", + "padding": "5px", + "border": "1px solid #000", + "border-radius": "4px", + "text-align": "left", + "font-size": "14px", + "font-family": "Sans Serif", + "background": "#a5aec3", + "accent-color": "#9f50d9", + "color": "#000", + "text-shadow": "none", + "-webkit-text-stroke-width": "0px", + "transform": "", + "filter": "" + }; + } else if (type === "button") { + styleStorage.buttons[id] = { + SPstorage: {}, + "width": "auto", + "height": "auto", + "cursor": "pointer", + "margin": "5px", + "padding": "5px 10px", + "border-radius": "5px", + "border": "1px none #fff", + "background": "#0074d9", + "font-size": "14px", + "font-family": "Sans Serif", + "color": "#fff", + "text-shadow": "none", + "-webkit-text-stroke-width": "0px", + "transform": "", + "filter": "" + }; + } + return styleStorage[type + "s"][id]; + } + + const genDefaultBox = (id, optEmptyElements) => { + genDefaultStyles(id, "popup"); + const defaultElements = []; + let submitBtn, cancelBtn; + if (!optEmptyElements) { + defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); + defaultElements.push(createInput( + "default-input", "text", + { defaultValue: Scratch.translate("...type your name") } + )); + + const buttonRow = createButtonRow("default-button-row"); + submitBtn = createButton("submit-button", Scratch.translate("Submit")); + cancelBtn = createButton("cancel-button", Scratch.translate("Cancel")); + buttonRow.data.buttons.push(submitBtn.data, cancelBtn.data); + buttonRow.DOMelement.append(submitBtn.DOMelement, cancelBtn.DOMelement); + defaultElements.push(buttonRow); + } + + const defaultBox = { + waiting: false, + isWindowed: false, + focused: false, + autoControl: true, + forceKey: undefined, + lastBtnPressed: undefined, + value: undefined, + DOMelement: undefined, + elements: defaultElements + }; + if (!optEmptyElements) { + elementStorage.labels["default-label"] = defaultElements[0]; + elementStorage.inputs["default-input"] = defaultElements[1]; + elementStorage.buttons["submit-button"] = submitBtn; + elementStorage.buttons["cancel-button"] = cancelBtn; + elementStorage.buttonRows["default-button-row"] = defaultElements[2]; + } + elementStorage.popups[id] = defaultBox; + return defaultBox; + } + + // popup box GUI + const compileStyles = (id, type) => { + const boxInfo = elementStorage[type + "s"][id]; + const styleObj = styleStorage[type + "s"][id] ?? genDefaultStyles(id, type); + if (type === "input" && boxInfo?.data.type === "color") { + // color inputs with these options look weird + if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; + if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + } + + let styleString = ""; + Object.entries(styleObj).forEach((style) => { + styleString += `${style[0]}: ${style[1]};`; + }); + return styleString; + }; + + const compileBox = (id) => { + const boxInfo = elementStorage.popups[id]; + boxInfo.waiting = true; + let boxInputs = []; + + const popupContainer = document.createElement("div"); + popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; + else { + popupContainer.style.left = "-50%"; + popupContainer.style.top = "-50%"; + } + + const popupPanel = document.createElement("div"); + popupPanel.classList.add("SP-Popup-Box"); + popupPanel.id = xmlEscape(id); + popupPanel.setAttribute("style", compileStyles(id, "popup")); + + // various element utils + const handleClose = (event) => { + // if theres no input, set the value to the button name + if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; + else compileInputValues(); + runtime.off("KEY_PRESSED", forceKeyHandler); + closeBox(id); + }; + const forceKeyHandler = (key) => { + if (boxInfo.forceKey === "shiftEnter") { + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + return; + } + if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); + }; + + const compileInputValues = () => { + if (boxInputs.length === 0) boxInfo.value = ""; + else if (boxInputs.length === 1) { + const input = boxInputs[0]; + const element = input.DOMelement; + + const returnValue = element.getAttribute("returnValue"); + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + } else { + boxInfo.value = Object.create(null); + for (let i = 0; i < boxInputs.length; i++) { + const input = boxInputs[i]; + const element = input.DOMelement; + + const returnValue = element.getAttribute("returnValue"); + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + } + } + }; + + // append elements to panel + for (let i = 0; i < boxInfo.elements.length; i++) { + const item = boxInfo.elements[i]; + let element = item.DOMelement; + if (item.type === "label") { + const refreshedLabel = elementStorage.labels[item.data.id]; + element = refreshedLabel.DOMelement; + } else if (item.type === "input") { + boxInputs.push(item); + + const refreshedInput = elementStorage.inputs[item.data.id]; + const recentData = refreshedInput.data; + element = createInput( + recentData.id, recentData.type, recentData.options + ).DOMelement; + item.DOMelement = element; + } + popupPanel.appendChild(element) + + // add event listeners + if (item.type === "input") element.addEventListener("change", compileInputValues); + else if (item.type === "buttonRow") { + element.addEventListener("click", (e) => { + if (e.target.tagName === "BUTTON") handleClose(e); + e.stopPropagation(); + }); + } + } + + popupContainer.appendChild(popupPanel); + if (boxInfo.isWindowed) document.body.appendChild(popupContainer); + else render.addOverlay(popupContainer, "scale-centered"); + compileInputValues(); + boxInfo.DOMelement = popupContainer; + + // extra event listeners + if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + }; + + const closeBox = (id, optForce) => { + const boxInfo = elementStorage.popups[id]; + boxInfo.waiting = false; + + if (optForce || boxInfo.autoControl) { + if (boxInfo.isWindowed) boxInfo.DOMelement?.remove(); + else render.removeOverlay(boxInfo.DOMelement); + boxInfo.DOMelement = undefined; + } + }; + + const updateBoxVisuals = (id, type) => { + const boxInfo = elementStorage[type][id]; + if (!boxInfo || !boxInfo.DOMelement) return; + const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + element.setAttribute( + "style", + compileStyles(id, type.slice(0, type.length - 1)) + ); + }; + + // extension utilities + function createBlockLabel(text) { + return { + blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + }; + }; + + function createMenuItem(text, value) { + return { + text: Scratch.translate(text), value + }; + }; + + genDefaultBox("default-popup", false); + + class SPpopups { + getInfo() { + return { + id: "SPpopups", + name: Scratch.translate("Popup Phoenix"), + color1: "#a812ff", + color2: "#941cd9", + color3: "#8219bf", + menuIconURI, + blockIconURI: getBlockIcon("main"), + blocks: [ + { + opcode: "showPopup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("show popup with ID [ID] and [TYPE]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + }, + }, + { + opcode: "showPopupReport", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("show popup with ID [ID] and wait"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "userInput", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("response from [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + "---", + { + opcode: "removePopup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove popup with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "removeAllPopups", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove all popups") + }, + createBlockLabel("Popups"), + { + opcode: "createPopup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("create new popup with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + }, + }, + { + opcode: "deletePopup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("delete popup with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + "---", + { + opcode: "append2Popup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + arguments: { + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "removeFromPopup", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + arguments: { + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "removePopupContent", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove all elements from popup [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + "---", + { + opcode: "setPopupPos", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + X: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER } + }, + }, + { + opcode: "getPos", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("[TYPE] position of [ID]"), + arguments: { + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + createBlockLabel("Labels"), + { + opcode: "createPopLabel", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + }, + }, + { + opcode: "deletePopLabel", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("delete label with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + }, + }, + createBlockLabel("Inputs"), + { + opcode: "createPopInput", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("create new [TYPE] input with ID [ID]"), + arguments: { + TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + }, + }, + { + opcode: "deletePopInput", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("delete popup with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + }, + }, + "---", + { + opcode: "setDefaultValue", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set default value of input [ID] to [VALUE]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + }, + }, + "---", + { + opcode: "setSliderParams", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, + MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, + }, + }, + "---", + { + opcode: "setDropOptions", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + }, + }, + { + opcode: "isDropOpen", + blockType: Scratch.BlockType.BOOLEAN, + text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + arguments: { + DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + createBlockLabel("Buttons"), + { + opcode: "createBtnRow", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("create new button row with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + }, + }, + { + opcode: "createPopBtn", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + }, + }, + { + opcode: "deleteBtnRow", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("delete button row with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + }, + }, + { + opcode: "deletePopBtn", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("delete button with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + }, + }, + "---", + { + opcode: "append2Row", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), + arguments: { + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + }, + }, + { + opcode: "removeFromRow", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), + arguments: { + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + }, + }, + { + opcode: "removeRowContent", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("remove all buttons from row [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + }, + }, + createBlockLabel("Operators"), + { + opcode: "allElements", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("all [TYPE] IDs"), + arguments: { + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + }, + }, + { + opcode: "popupWaiting", + blockType: Scratch.BlockType.BOOLEAN, + text: Scratch.translate("is popup [ID] waiting?"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "lastButtonPress", + blockType: Scratch.BlockType.REPORTER, + text: Scratch.translate("last button pressed in [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + "---", + { + opcode: "setPopupTarget", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + }, + }, + { + opcode: "toggleOption", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), + arguments: { + OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + }, + }, + { + opcode: "setForceClose", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + }, + }, + createBlockLabel("Customization"), + { + opcode: "setPopupAlign", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + }, + }, + { + opcode: "setInputAlign", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set alignment of input [ID] to [TYPE]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + }, + }, + "---", + { + opcode: "setInputFont", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + }, + }, + { + opcode: "setInputFontSZ", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + }, + }, + { + opcode: "setElementOutline", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + COLOR: { type: Scratch.ArgumentType.COLOR }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + }, + }, + "---", + { + opcode: "setElementAtt", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set [PARAM] of [ELEMENT] [ID] to [VALUE]"), + arguments: { + PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + }, + }, + { + opcode: "setElementBorder", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, + COLOR: { type: Scratch.ArgumentType.COLOR }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + }, + }, + { + opcode: "setElementShadow", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("color"), + text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + X: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER }, + COLOR: { type: Scratch.ArgumentType.COLOR }, + AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + }, + }, + "---", + { + opcode: "resetElementEffect", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("effect"), + text: Scratch.translate("reset effects of [ELEMENT] [ID]"), + arguments: { + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "setElementEffect", + blockType: Scratch.BlockType.COMMAND, + blockIconURI: getBlockIcon("effect"), + text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + arguments: { + EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + }, + }, + { + opcode: "getElementEffect", + blockType: Scratch.BlockType.REPORTER, + blockIconURI: getBlockIcon("effect"), + text: Scratch.translate("[EFFECT] of [ELEMENT] [ID]"), + arguments: { + EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, + ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + ], + menus: { + FONTS: { acceptReporters: true, items: "getFonts" }, + POP_STYLES: { acceptReporters: true, items: this.genStyleList("popup") }, + LAB_STYLES: { acceptReporters: true, items: this.genStyleList("label") }, + INP_STYLES: { acceptReporters: true, items: this.genStyleList("input") }, + BUT_STYLES: { acceptReporters: true, items: this.genStyleList("button") }, + INPUTS: { acceptReporters: true, items: validInputs }, + BORDERS: { acceptReporters: true, items: validBorders }, + EFFECTS: { acceptReporters: true, items: validEffects }, + UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, + UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, + UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, + UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + AWAITS: { + acceptReporters: false, + items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + }, + TOGGLER: { + acceptReporters: false, + items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + }, + POSITION: { + acceptReporters: false, + items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + }, + POPUP_LOCATION: { + acceptReporters: false, + items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + }, + ALIGNMENT: { + acceptReporters: false, + items: [ + createMenuItem("left", "left"), + createMenuItem("right", "flex-end"), + createMenuItem("center", "center") + ] + }, + FORCE_KEY: { + acceptReporters: true, + items: [ + createMenuItem("none", "none"), + createMenuItem("enter", "enter"), + createMenuItem("shift & enter", "shiftEnter") + ] + }, + EXTRA_OPTS: { + acceptReporters: true, + items: [ + createMenuItem("focus mode", "focus"), + createMenuItem("auto close", "autoClose") + ] + }, + }, + }; + } + + // Helper Funcs + getFonts() { + const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [ ...defaultFonts, ...custFonts ]; + } + + genElementList(addPopup, addRow, addButton) { + const list = []; + if (addPopup) list.push(createMenuItem("popup", "popup")); + list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + if (addRow) list.push(createMenuItem("button row", "buttonRow")); + if (addButton) list.push(createMenuItem("button", "button")); + return list; + } + + genStyleList() { + return [ + createMenuItem("background color", "background"), + createMenuItem("text color", "color"), + createMenuItem("accent color", "accent-color"), + createMenuItem("margins", "margin"), + createMenuItem("padding", "padding"), + createMenuItem("width", "width"), + createMenuItem("height", "height"), + createMenuItem("border radius", "border-radius") + ]; + } + + getElementPath(path, useBtn, usePopup) { + const validPaths = ["label", "input", useBtn ? "button" : "buttonRow"]; + if (usePopup) validPaths.push("popup"); + return validPaths.includes(path) ? path : "label"; + } + + openPopupHandler(args, util, reportResponse) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (!util.stackFrame.awaitingInput) { + if (popup === undefined) popup = genDefaultBox(id, false); + if (popup.DOMelement) closeBox(id, true); + compileBox(id); + util.stackFrame.awaitingInput = true; + } + + if ((reportResponse ? true : args.TYPE === "wait") && popup.waiting) util.yield(); + if (reportResponse) return typeof popup.value === "object" ? + JSON.stringify(popup.value) : popup.value || ""; + } + + // Block Funcs + /* main */ + showPopup(args, util) { + this.openPopupHandler(args, util, false); + } + + showPopupReport(args, util) { + return this.openPopupHandler(args, util, true); + } + + userInput(args) { + const id = Cast.toString(args.ID); + const popup = elementStorage.popups[id]; + if (popup === undefined) return ""; + return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + } + + removePopup(args) { + const id = Cast.toString(args.ID); + const popup = elementStorage.popups[id]; + if (popup !== undefined && popup.DOMelement) closeBox(id, true); + } + + removeAllPopups() { + const allPopups = Object.entries(elementStorage.popups); + for (let i = 0; i < allPopups.length; i++) { + const entry = allPopups[i]; + if (entry[1].DOMelement) closeBox(entry[0], true); + } + } + + /* popups */ + createPopup(args) { + const id = Cast.toString(args.ID); + genDefaultBox(id, true); + } + + deletePopup(args) { + const id = Cast.toString(args.ID); + delete styleStorage.popups[id]; + delete elementStorage.popups[id]; + } + + append2Popup(args) { + const popup = elementStorage.popups[Cast.toString(args.POP_ID)]; + const path = this.getElementPath(Cast.toString(args.TYPE)); + const elementID = Cast.toString(args.ELEMENT_ID); + const element = elementStorage[path + "s"][elementID]; + if (popup === undefined || element === undefined) return; + + const elementIndex = popup.elements.findIndex((i) => { + return i.type === path && i.data.id === elementID + }); + if (elementIndex === -1) popup.elements.push(element); + } + + removeFromPopup(args) { + const popup = elementStorage.popups[Cast.toString(args.POP_ID)]; + const path = this.getElementPath(Cast.toString(args.TYPE)); + const elementID = Cast.toString(args.ELEMENT_ID); + if (popup === undefined) return; + + const elementIndex = popup.elements.findIndex((i) => { + return i.type === path && i.data.id === elementID + }); + if (elementIndex > -1) popup.elements.splice(elementIndex, 1); + } + + removePopupContent(args) { + const id = Cast.toString(args.ID); + const popup = elementStorage.popups[id]; + if (popup !== undefined) popup.elements = []; + } + + setPopupPos(args) { + const id = Cast.toString(args.ID); + const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); + styles.left = `calc(50% + ${Cast.toNumber(args.X)}px)`; + styles.top = `calc(50% + ${Cast.toNumber(args.Y) * -1}px)`; + updateBoxVisuals(id, "popups"); + } + + getPos(args) { + const id = Cast.toString(args.ID); + const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); + if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; + } + + /* labels */ + createPopLabel(args) { + const id = Cast.toString(args.ID); + const text = Cast.toString(args.TEXT); + elementStorage.labels[id] = createLabel(id, text); + } + + deletePopLabel(args) { + const id = Cast.toString(args.ID); + delete styleStorage.labels[id]; + delete elementStorage.labels[id]; + } + + /* inputs */ + createPopInput(args) { + const id = Cast.toString(args.ID); + let type = Cast.toString(args.TYPE); + + const isValidInput = validInputs.findIndex((i) => { return i.value === type }); + if (isValidInput === -1) type = "text"; + elementStorage.inputs[id] = createInput(id, type, {}); + } + + deletePopInput(args) { + const id = Cast.toString(args.ID); + delete styleStorage.inputs[id]; + delete elementStorage.inputs[id]; + } + + setDefaultValue(args) { + const input = elementStorage.inputs[Cast.toString(args.ID)]; + if (input) input.data.options.defaultValue = Cast.toString(args.VALUE); + } + + setSliderParams(args) { + const input = elementStorage.inputs[Cast.toString(args.ID)]; + if (input) { + input.data.options.minV = Cast.toNumber(args.MIN); + input.data.options.maxV = Cast.toNumber(args.MAX); + } + } + + setDropOptions(args) { + try { + const array = JSON.parse(args.ARRAY); + if (array.length === 0) array.push("no options created"); + const id = Cast.toString(args.ID); + const input = elementStorage.inputs[id]; + if (input) input.data.options.selectors = array; + } catch { + console.warn("Failed to set Dropdown Options, invalid Array!"); + } + } + + isDropOpen(args) { + const popup = elementStorage.popups[Cast.toString(args.POP_ID)]; + const dropID = Cast.toString(args.DROP_ID); + if (popup === undefined || !popup.waiting) return false; + const dropdown = popup.elements.find((e) => { + return e.type === "input" && e.data.id === dropID + }); + if (dropdown) return dropdown.data.options.menuOpened ?? false; + return false; + } + + /* buttons */ + createBtnRow(args) { + const id = Cast.toString(args.ID); + elementStorage.buttonRows[id] = createButtonRow(id); + } + + createPopBtn(args) { + const id = Cast.toString(args.ID); + const text = Cast.toString(args.TEXT); + elementStorage.buttons[id] = createButton(id, text); + } + + deleteBtnRow(args) { + const id = Cast.toString(args.ID); + delete elementStorage.buttonRows[id]; + } + + deletePopBtn(args) { + const id = Cast.toString(args.ID); + delete styleStorage.buttons[id]; + delete elementStorage.buttons[id]; + } + + append2Row(args) { + const btn = elementStorage.buttons[Cast.toString(args.BTN_ID)]; + const row = elementStorage.buttonRows[Cast.toString(args.ROW_ID)]; + if (row === undefined || btn === undefined) return; + + const btnList = row.data.buttons; + const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + if (btnIndex > -1) return; + btnList.push(btn.data); + row.DOMelement.appendChild(btn.DOMelement); + } + + removeFromRow(args) { + const btn = elementStorage.buttons[Cast.toString(args.BTN_ID)]; + const row = elementStorage.buttonRows[Cast.toString(args.ROW_ID)]; + if (row === undefined || btn === undefined) return; + + const btnList = row.data.buttons; + const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + if (btnIndex === -1) return; + btnList.splice(btnIndex, 1); + row.DOMelement.children[btnIndex].remove(); + } + + removeRowContent(args) { + const row = elementStorage.buttonRows[Cast.toString(args.ID)]; + if (row === undefined) return; + + Array.from(row.DOMelement.children).forEach((button) => button.remove()); + row.data.buttons = []; + } + + /* operations */ + allElements(args) { + const namespace = Cast.toString(args.TYPE) + "s"; + const items = elementStorage[namespace]; + if (!items) return "[]"; + else return JSON.stringify(Object.keys(items)); + } + + popupWaiting(args) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (popup === undefined) return false; + return popup.waiting; + } + + lastButtonPress(args) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (popup === undefined) return ""; + return popup.lastBtnPressed ?? ""; + } + + setPopupTarget(args) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (popup === undefined) return; + popup.isWindowed = args.TYPE === "window"; + } + + toggleOption(args) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (popup === undefined) return; + + const option = Cast.toString(args.OPTION); + popup[ + option === "focus" ? "focused" : "autoControl" + ] = args.TYPE === "on"; + } + + setForceClose(args) { + const id = Cast.toString(args.ID); + let popup = elementStorage.popups[id]; + if (popup === undefined) return; + + const key = Cast.toString(args.KEY); + popup.forceKey = key === "none" ? undefined : key; + } + + /* customization */ + setPopupAlign(args) { + const id = Cast.toString(args.ID); + const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); + styles["align-items"] = args.TYPE; + styles["justify-content"] = args.TYPE; + updateBoxVisuals(id, "popups"); + } + + setInputAlign(args) { + const id = Cast.toString(args.ID); + const styles = styleStorage.inputs[id] ?? genDefaultStyles(id, "input"); + styles["text-align"] = args.TYPE === "flex-end" ? "right" : args.TYPE; + updateBoxVisuals(id, "inputs"); + } + + setInputFont(args) { + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + styles["font-family"] = Cast.toString(args.FONT); + updateBoxVisuals(id, path); + } + + setInputFontSZ(args) { + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + styles["font-size"] = `${Cast.toNumber(args.SIZE)}px`; + updateBoxVisuals(id, path); + } + + setElementOutline(args) { + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + styles["-webkit-text-stroke-width"] = `${Cast.toNumber(args.WEIGHT)}px`; + styles["-webkit-text-stroke-color"] = args.COLOR; + updateBoxVisuals(id, path); + } + + setElementAtt(args) { + const id = Cast.toString(args.ID); + const param = Cast.toString(args.PARAM); + let value = Cast.toString(args.VALUE); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + const isValidStyle = this.genStyleList().findIndex((i) => { return i.value === param }); + + if (!param.includes("color") && param !== "background") { + if (param === "width" || param === "height") { + // allow users to input things like "auto" while still adding "px" to numbers + value = /^\d+$/.test(value) ? `${value}px` : value; + } else { + // handle cases where users to input specific attributes like "margin-left" + if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + else value = `${value}px`; + } + } + + if (isValidStyle > -1) styles[param] = value; + updateBoxVisuals(id, path); + } + + setElementBorder(args) { + const id = Cast.toString(args.ID); + const weight = Cast.toNumber(args.WEIGHT); + const isBorderValid = validBorders.findIndex((i) => { return i.value === args.TYPE }); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + styles[path === "labels" ? "border-bottom" : "border"] = + `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; + updateBoxVisuals(id, path); + } + + setElementShadow(args) { + const id = Cast.toString(args.ID); + const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; + const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + updateBoxVisuals(id, path); + } + + resetElementEffect(args) { + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; + styles["filter"] = ""; + updateBoxVisuals(id, path); + } + + setElementEffect(args) { + const effect = Cast.toString(args.EFFECT); + const effectIndex = validEffects.findIndex((i) => { return i.value === effect }); + if (effectIndex === -1) return; + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + + let value = Cast.toNumber(args.VALUE); + const cssTarget = effectIndex > 7 ? "transform" : "filter"; + const regex = new RegExp(`${effect}\\(([^)]*)\\)`); + styles["SPstorage"][effect] = value; + + switch (effect) { + case "blur": + value += "px"; + break; + case "brightness": + value = `${100 - (value * -1)}%`; + break; + case "opacity": + value = 1 - (value / 100); + break; + case "saturate": + case "sepia": + case "invert": + value += "%"; + break; + case "hue-rotate": + value += "deg"; + break; + case "contrast": + value = `${100 + value}%`; + break; + case "rotate": + value = `${value - 90}deg`; + break; + case "scaleX": + case "scaleY": + value /= 100; + break; + case "skewX": + case "skewY": + value += "deg"; + break; + } + + const newCSS = styles[cssTarget].replace(regex, ""); + styles[cssTarget] = newCSS + `${effect}(${value})`; + updateBoxVisuals(id, path); + } + + getElementEffect(args) { + const effect = Cast.toString(args.EFFECT); + const isValidEffect = validEffects.findIndex((i) => { return i.value === effect }); + if (isValidEffect === -1) return ""; + + const id = Cast.toString(args.ID); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); + return styles["SPstorage"][effect] ?? ""; + } + } + + Scratch.extensions.register(new SPpopups()); +})(Scratch); From c1c28c99164d862cd6e8e20214808fb7002664df Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Tue, 18 Feb 2025 06:21:55 +0000 Subject: [PATCH 02/17] [Automated] Format code --- extensions/SharkPool/Popup-Phoenix.js | 764 ++++++++++++++++++-------- 1 file changed, 537 insertions(+), 227 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 273bf57160..fa4f7f94b6 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,18 +8,25 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) + throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return start + { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" - }[name]; + const start = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return ( + start + + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: + "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: + "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", + }[name] + ); }; const Cast = Scratch.Cast; @@ -28,15 +35,20 @@ const render = vm.renderer; const defaultFonts = [ - "Sans Serif", "Serif", "Handwriting", - "Marker", "Curly", "Pixel", "Scratch" + "Sans Serif", + "Serif", + "Handwriting", + "Marker", + "Curly", + "Pixel", + "Scratch", ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button") + button: Scratch.translate("submit-button"), }; const validInputs = [ @@ -49,7 +61,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert") + createMenuItem("vertical slider", "rangeVert"), ]; const validBorders = [ createMenuItem("none", "none"), @@ -60,7 +72,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset") + createMenuItem("outset", "outset"), ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -75,7 +87,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY") + createMenuItem("skew y", "skewY"), ]; // internals @@ -83,24 +95,29 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { switch (c) { - case "<": return "<"; - case ">": return ">"; - case "&": return "&"; - case "'": return "'"; - case "\"": return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; } }); }; @@ -136,18 +153,28 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; opt.text = option; + opt.value = option; + opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { options.menuOpened = true }); - element.addEventListener("blur", () => { options.menuOpened = false }); - element.addEventListener("change", (e) => setElementValue([e.target.value])); + element.addEventListener("focus", () => { + options.menuOpened = true; + }); + element.addEventListener("blur", () => { + options.menuOpened = false; + }); + element.addEventListener("change", (e) => + setElementValue([e.target.value]) + ); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + holder.setAttribute( + "style", + "display: flex; padding: 5px; cursor: pointer" + ); const check = document.createElement("input"); check.type = "checkbox"; @@ -166,7 +193,10 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + optionsDiv.setAttribute( + "style", + "overflow-y: scroll; height: calc(100% - 1px);" + ); element.appendChild(optionsDiv); setElementValue(response); @@ -175,7 +205,8 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") + e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -216,7 +247,10 @@ element.value = options.defaultValue ?? ""; if (type === "color") { - inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + inputHolder.setAttribute( + "style", + "display: flex; justify-content: center; width: 100%;" + ); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -245,7 +279,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder + DOMelement: inputHolder, }; }; @@ -257,7 +291,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow + DOMelement: buttonRow, }; }; @@ -271,7 +305,7 @@ return { type: "button", data: { id, text }, - DOMelement: element + DOMelement: element, }; }; @@ -280,20 +314,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - "display": "flex", + display: "flex", "flex-direction": "column", - "position": "absolute", + position: "absolute", "pointer-events": "auto", - "transform": "translate(-50%, -50%)", - "filter": "", - "left": "calc(50% + 0px)", - "top": "calc(50% + 0px)", - "width": "max-content", - "height": "auto", - "padding": "15px", - "background": "#fff", + transform: "translate(-50%, -50%)", + filter: "", + left: "calc(50% + 0px)", + top: "calc(50% + 0px)", + width: "max-content", + height: "auto", + padding: "15px", + background: "#fff", "box-shadow": "#000 0px 0px 5px", - "border": "1px none #000", + border: "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -301,66 +335,69 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - "margin": "5px", - "color": "#000", + margin: "5px", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - "width": "max-content", - "height": "auto", - "margin": "5px", - "padding": "5px", - "border": "1px solid #000", + width: "max-content", + height: "auto", + margin: "5px", + padding: "5px", + border: "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - "background": "#a5aec3", + background: "#a5aec3", "accent-color": "#9f50d9", - "color": "#000", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - "width": "auto", - "height": "auto", - "cursor": "pointer", - "margin": "5px", - "padding": "5px 10px", + width: "auto", + height: "auto", + cursor: "pointer", + margin: "5px", + padding: "5px 10px", "border-radius": "5px", - "border": "1px none #fff", - "background": "#0074d9", + border: "1px none #fff", + background: "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - "color": "#fff", + color: "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } return styleStorage[type + "s"][id]; - } + }; const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); - defaultElements.push(createInput( - "default-input", "text", - { defaultValue: Scratch.translate("...type your name") } - )); + defaultElements.push( + createLabel("default-label", Scratch.translate("Whats Your Name?")) + ); + defaultElements.push( + createInput("default-input", "text", { + defaultValue: Scratch.translate("...type your name"), + }) + ); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -379,7 +416,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements + elements: defaultElements, }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -390,7 +427,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - } + }; // popup box GUI const compileStyles = (id, type) => { @@ -399,7 +436,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + if (styleObj["height"] === "auto") styleObj["height"] = "30px"; } let styleString = ""; @@ -415,9 +452,13 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute( + "style", + "position: fixed; width: 100%; height: 100%;" + ); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) + popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -432,7 +473,8 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) + boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -440,7 +482,8 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) + handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -453,7 +496,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -461,7 +506,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } } }; @@ -479,14 +526,17 @@ const refreshedInput = elementStorage.inputs[item.data.id]; const recentData = refreshedInput.data; element = createInput( - recentData.id, recentData.type, recentData.options + recentData.id, + recentData.type, + recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element) + popupPanel.appendChild(element); // add event listeners - if (item.type === "input") element.addEventListener("change", compileInputValues); + if (item.type === "input") + element.addEventListener("change", compileInputValues); else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -502,7 +552,8 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) + runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -519,9 +570,10 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = + type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -529,15 +581,17 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + blockType: Scratch.BlockType.LABEL, + text: Scratch.translate(text), }; - }; + } function createMenuItem(text, value) { return { - text: Scratch.translate(text), value + text: Scratch.translate(text), + value, }; - }; + } genDefaultBox("default-popup", false); @@ -557,8 +611,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, }, }, { @@ -566,7 +623,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -574,7 +634,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -583,13 +646,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups") + text: Scratch.translate("remove all popups"), }, createBlockLabel("Popups"), { @@ -597,7 +663,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("new-popup"), + }, }, }, { @@ -605,28 +674,47 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + text: Scratch.translate( + "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + text: Scratch.translate( + "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -634,7 +722,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -643,9 +734,12 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER } + Y: { type: Scratch.ArgumentType.NUMBER }, }, }, { @@ -654,17 +748,28 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new label with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("whats your name?"), + }, }, }, { @@ -672,7 +777,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, }, }, createBlockLabel("Inputs"), @@ -682,7 +790,10 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, { @@ -690,17 +801,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set default value of input [ID] to [VALUE]"), + text: Scratch.translate( + "set default value of input [ID] to [VALUE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate(`...type here`), + }, }, }, "---", @@ -709,7 +831,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -720,17 +845,33 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + ARRAY: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate( + `["Option 1", "Option 2", "Option 3"]` + ), + }, }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + text: Scratch.translate( + "is dropdown [DROP_ID] in popup [POP_ID] open?" + ), arguments: { - DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + DROP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Buttons"), @@ -739,16 +880,27 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new button with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("Submit"), + }, }, }, { @@ -756,7 +908,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -764,7 +919,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, }, }, "---", @@ -773,8 +931,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -782,8 +946,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -791,7 +961,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, createBlockLabel("Operators"), @@ -800,7 +973,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, }, }, { @@ -808,7 +981,10 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -816,17 +992,28 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + text: Scratch.translate( + "show next popup with ID [ID] on the [TYPE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "POPUP_LOCATION", + }, }, }, { @@ -835,17 +1022,25 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + text: Scratch.translate( + "set auto-close action in popup [ID] to [KEY] key" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, }, }, createBlockLabel("Customization"), @@ -855,8 +1050,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, { @@ -865,8 +1063,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, "---", @@ -877,31 +1078,44 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + text: Scratch.translate( + "set font size of [ELEMENT] [ID] to [SIZE]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -913,36 +1127,52 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "#ff0000", + }, }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + text: Scratch.translate( + "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -953,19 +1183,27 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + text: Scratch.translate( + "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" + ), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { @@ -976,61 +1214,94 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, ], menus: { FONTS: { acceptReporters: true, items: "getFonts" }, - POP_STYLES: { acceptReporters: true, items: this.genStyleList("popup") }, - LAB_STYLES: { acceptReporters: true, items: this.genStyleList("label") }, - INP_STYLES: { acceptReporters: true, items: this.genStyleList("input") }, - BUT_STYLES: { acceptReporters: true, items: this.genStyleList("button") }, + POP_STYLES: { + acceptReporters: true, + items: this.genStyleList("popup"), + }, + LAB_STYLES: { + acceptReporters: true, + items: this.genStyleList("label"), + }, + INP_STYLES: { + acceptReporters: true, + items: this.genStyleList("input"), + }, + BUT_STYLES: { + acceptReporters: true, + items: this.genStyleList("button"), + }, INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, - UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, - UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, - UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + UI_ELEMENTS: { + acceptReporters: true, + items: this.genElementList(false, true, false), + }, + UI_MAIN: { + acceptReporters: true, + items: this.genElementList(true, false, true), + }, + UI_MAIN2: { + acceptReporters: true, + items: this.genElementList(false, false, true), + }, + UI_SELECT: { + acceptReporters: true, + items: this.genElementList(true, true, true), + }, AWAITS: { acceptReporters: false, - items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + items: [ + createMenuItem("wait", "wait"), + createMenuItem("continue", "continue"), + ], }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + items: [createMenuItem("on", "on"), createMenuItem("off", "off")], }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + items: [createMenuItem("x", "x"), createMenuItem("y", "y")], }, POPUP_LOCATION: { acceptReporters: false, - items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + items: [ + createMenuItem("window", "window"), + createMenuItem("canvas", "canvas"), + ], }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center") - ] + createMenuItem("center", "center"), + ], }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter") - ] + createMenuItem("shift & enter", "shiftEnter"), + ], }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose") - ] + createMenuItem("auto close", "autoClose"), + ], }, }, }; @@ -1038,14 +1309,21 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; - return [ ...defaultFonts, ...custFonts ]; + const custFonts = runtime.fontManager + ? runtime.fontManager + .getFonts() + .map((i) => ({ text: i.name, value: i.family })) + : []; + return [...defaultFonts, ...custFonts]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + list.push( + createMenuItem("label", "label"), + createMenuItem("input", "input") + ); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1060,7 +1338,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius") + createMenuItem("border radius", "border-radius"), ]; } @@ -1080,9 +1358,12 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup.waiting) util.yield(); - if (reportResponse) return typeof popup.value === "object" ? - JSON.stringify(popup.value) : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup.waiting) + util.yield(); + if (reportResponse) + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } // Block Funcs @@ -1099,7 +1380,9 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } removePopup(args) { @@ -1136,7 +1419,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex === -1) popup.elements.push(element); } @@ -1148,7 +1431,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1170,7 +1453,8 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") + return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1192,7 +1476,9 @@ const id = Cast.toString(args.ID); let type = Cast.toString(args.TYPE); - const isValidInput = validInputs.findIndex((i) => { return i.value === type }); + const isValidInput = validInputs.findIndex((i) => { + return i.value === type; + }); if (isValidInput === -1) type = "text"; elementStorage.inputs[id] = createInput(id, type, {}); } @@ -1233,7 +1519,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID + return e.type === "input" && e.data.id === dropID; }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1268,7 +1554,9 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + const btnIndex = btnList.findIndex((i) => { + return i.id === btn.data.id; + }); if (btnIndex > -1) return; btnList.push(btn.data); row.DOMelement.appendChild(btn.DOMelement); @@ -1280,7 +1568,9 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + const btnIndex = btnList.findIndex((i) => { + return i.id === btn.data.id; + }); if (btnIndex === -1) return; btnList.splice(btnIndex, 1); row.DOMelement.children[btnIndex].remove(); @@ -1329,9 +1619,8 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[ - option === "focus" ? "focused" : "autoControl" - ] = args.TYPE === "on"; + popup[option === "focus" ? "focused" : "autoControl"] = + args.TYPE === "on"; } setForceClose(args) { @@ -1388,9 +1677,12 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => { return i.value === param }); + const isValidStyle = this.genStyleList().findIndex((i) => { + return i.value === param; + }); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1398,7 +1690,10 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + if (value.includes(" ")) + value = /^\d+$/.test(value.replaceAll(" ", "")) + ? value.replaceAll(" ", "px ") + : value; else value = `${value}px`; } } @@ -1410,10 +1705,13 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => { return i.value === args.TYPE }); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => { + return i.value === args.TYPE; + }); + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1422,16 +1720,22 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") + styles["text-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else + styles["box-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1440,10 +1744,13 @@ setElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const effectIndex = validEffects.findIndex((i) => { return i.value === effect }); + const effectIndex = validEffects.findIndex((i) => { + return i.value === effect; + }); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1456,10 +1763,10 @@ value += "px"; break; case "brightness": - value = `${100 - (value * -1)}%`; + value = `${100 - value * -1}%`; break; case "opacity": - value = 1 - (value / 100); + value = 1 - value / 100; break; case "saturate": case "sepia": @@ -1492,11 +1799,14 @@ getElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const isValidEffect = validEffects.findIndex((i) => { return i.value === effect }); + const isValidEffect = validEffects.findIndex((i) => { + return i.value === effect; + }); if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From 6f0547d0679391426eb6384d2e5cd02c2e7313eb Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Tue, 18 Feb 2025 10:25:42 -0800 Subject: [PATCH 03/17] Popup-Phoenix.js -- close popups on project start/stop --- extensions/SharkPool/Popup-Phoenix.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index fa4f7f94b6..6302d92c4b 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -596,6 +596,10 @@ genDefaultBox("default-popup", false); class SPpopups { + constructor() { + runtime.on("PROJECT_START", () => this.removeAllPopups()); + runtime.on("PROJECT_STOP_ALL", () => this.removeAllPopups()); + } getInfo() { return { id: "SPpopups", From 120e8ea65881c8d24b384f92b0dd8b60bf54be96 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 19 Feb 2025 00:16:35 -0800 Subject: [PATCH 04/17] Create Popup-Phoenix.svg --- images/SharkPool/Popup-Phoenix.svg | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 images/SharkPool/Popup-Phoenix.svg diff --git a/images/SharkPool/Popup-Phoenix.svg b/images/SharkPool/Popup-Phoenix.svg new file mode 100644 index 0000000000..80dbf09dc3 --- /dev/null +++ b/images/SharkPool/Popup-Phoenix.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From d09304bf7b3e7cffcea06705df1edce834c777a9 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 19 Feb 2025 20:00:29 -0800 Subject: [PATCH 05/17] Popup-Phoenix -- Delete Popups should remove them from the DOM too --- extensions/SharkPool/Popup-Phoenix.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 6302d92c4b..dd6e924c6f 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,7 +4,7 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.0 +// Version V.1.0.01 (function (Scratch) { "use strict"; @@ -1362,7 +1362,7 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup.waiting) + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); if (reportResponse) return typeof popup.value === "object" @@ -1405,11 +1405,13 @@ /* popups */ createPopup(args) { + this.removePopup(args); const id = Cast.toString(args.ID); genDefaultBox(id, true); } deletePopup(args) { + this.removePopup(args); const id = Cast.toString(args.ID); delete styleStorage.popups[id]; delete elementStorage.popups[id]; From 0955eb051546d73bf51c20a3f5847b975e6c8952 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 19 Feb 2025 20:38:57 -0800 Subject: [PATCH 06/17] Popup-Phoenix -- Clipboard messed this up --- extensions/SharkPool/Popup-Phoenix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index dd6e924c6f..660e998899 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -506,7 +506,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue + boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } From 0b115872ca416bdb15cc8076b46dec5300dc1cf7 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 2 May 2025 23:14:05 -0700 Subject: [PATCH 07/17] Popup-Phoenix.js -- Minor Fixes --- extensions/SharkPool/Popup-Phoenix.js | 776 ++++++++------------------ 1 file changed, 237 insertions(+), 539 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 660e998899..748d470701 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,51 +4,40 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.01 +// Version V.1.0.03 (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) - throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return ( - start + - { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: - "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: - "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", - }[name] - ); + const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return start + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" + }[name]; }; const Cast = Scratch.Cast; const vm = Scratch.vm; const runtime = vm.runtime; const render = vm.renderer; + const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", - "Serif", - "Handwriting", - "Marker", - "Curly", - "Pixel", - "Scratch", + "Sans Serif", "Serif", "Handwriting", + "Marker", "Curly", "Pixel", "Scratch" ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button"), + button: Scratch.translate("submit-button") }; const validInputs = [ @@ -61,7 +50,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert"), + createMenuItem("vertical slider", "rangeVert") ]; const validBorders = [ createMenuItem("none", "none"), @@ -72,7 +61,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset"), + createMenuItem("outset", "outset") ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -87,7 +76,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY"), + createMenuItem("skew y", "skewY") ]; // internals @@ -95,29 +84,24 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { switch (c) { - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - case "'": - return "'"; - case '"': - return """; + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; } }); }; @@ -153,28 +137,18 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; - opt.text = option; + opt.value = option; opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { - options.menuOpened = true; - }); - element.addEventListener("blur", () => { - options.menuOpened = false; - }); - element.addEventListener("change", (e) => - setElementValue([e.target.value]) - ); + element.addEventListener("focus", () => { options.menuOpened = true }); + element.addEventListener("blur", () => { options.menuOpened = false }); + element.addEventListener("change", (e) => setElementValue([e.target.value])); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute( - "style", - "display: flex; padding: 5px; cursor: pointer" - ); + holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); const check = document.createElement("input"); check.type = "checkbox"; @@ -193,10 +167,7 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute( - "style", - "overflow-y: scroll; height: calc(100% - 1px);" - ); + optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); element.appendChild(optionsDiv); setElementValue(response); @@ -205,8 +176,7 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") - e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -247,10 +217,7 @@ element.value = options.defaultValue ?? ""; if (type === "color") { - inputHolder.setAttribute( - "style", - "display: flex; justify-content: center; width: 100%;" - ); + inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -279,7 +246,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder, + DOMelement: inputHolder }; }; @@ -291,7 +258,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow, + DOMelement: buttonRow }; }; @@ -305,7 +272,7 @@ return { type: "button", data: { id, text }, - DOMelement: element, + DOMelement: element }; }; @@ -314,20 +281,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - display: "flex", + "display": "flex", "flex-direction": "column", - position: "absolute", + "position": "absolute", "pointer-events": "auto", - transform: "translate(-50%, -50%)", - filter: "", - left: "calc(50% + 0px)", - top: "calc(50% + 0px)", - width: "max-content", - height: "auto", - padding: "15px", - background: "#fff", + "transform": "translate(-50%, -50%)", + "filter": "", + "left": "calc(50% + 0px)", + "top": "calc(50% + 0px)", + "width": "max-content", + "height": "auto", + "padding": "15px", + "background": "#fff", "box-shadow": "#000 0px 0px 5px", - border: "1px none #000", + "border": "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -335,69 +302,66 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - margin: "5px", - color: "#000", + "margin": "5px", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - width: "max-content", - height: "auto", - margin: "5px", - padding: "5px", - border: "1px solid #000", + "width": "max-content", + "height": "auto", + "margin": "5px", + "padding": "5px", + "border": "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - background: "#a5aec3", + "background": "#a5aec3", "accent-color": "#9f50d9", - color: "#000", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - width: "auto", - height: "auto", - cursor: "pointer", - margin: "5px", - padding: "5px 10px", + "width": "auto", + "height": "auto", + "cursor": "pointer", + "margin": "5px", + "padding": "5px 10px", "border-radius": "5px", - border: "1px none #fff", - background: "#0074d9", + "border": "1px none #fff", + "background": "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - color: "#fff", + "color": "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } return styleStorage[type + "s"][id]; - }; + } const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push( - createLabel("default-label", Scratch.translate("Whats Your Name?")) - ); - defaultElements.push( - createInput("default-input", "text", { - defaultValue: Scratch.translate("...type your name"), - }) - ); + defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); + defaultElements.push(createInput( + "default-input", "text", + { defaultValue: Scratch.translate("...type your name") } + )); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -416,7 +380,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements, + elements: defaultElements }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -427,7 +391,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - }; + } // popup box GUI const compileStyles = (id, type) => { @@ -436,7 +400,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto") styleObj["height"] = "30px"; + if (styleObj["height"] === "auto")styleObj["height"] = "30px"; } let styleString = ""; @@ -452,13 +416,9 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute( - "style", - "position: fixed; width: 100%; height: 100%;" - ); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) - popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -473,8 +433,7 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) - boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -482,8 +441,7 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) - handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -496,9 +454,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -506,9 +462,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } } }; @@ -526,18 +480,22 @@ const refreshedInput = elementStorage.inputs[item.data.id]; const recentData = refreshedInput.data; element = createInput( - recentData.id, - recentData.type, - recentData.options + recentData.id, recentData.type, recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element); + popupPanel.appendChild(element) // add event listeners - if (item.type === "input") + if (item.type === "input") { element.addEventListener("change", compileInputValues); - else if (item.type === "buttonRow") { + if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); + } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); e.stopPropagation(); @@ -552,8 +510,7 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) - runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -570,10 +527,9 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = - type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -581,17 +537,15 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, - text: Scratch.translate(text), + blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) }; - } + }; function createMenuItem(text, value) { return { - text: Scratch.translate(text), - value, + text: Scratch.translate(text), value }; - } + }; genDefaultBox("default-popup", false); @@ -615,11 +569,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } }, }, { @@ -627,10 +578,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -638,10 +586,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -650,16 +595,13 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups"), + text: Scratch.translate("remove all popups") }, createBlockLabel("Popups"), { @@ -667,10 +609,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("new-popup"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } }, }, { @@ -678,47 +617,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" - ), + text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" - ), + text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -726,10 +646,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -738,12 +655,9 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER } }, }, { @@ -752,28 +666,17 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new label with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("whats your name?"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } }, }, { @@ -781,10 +684,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } }, }, createBlockLabel("Inputs"), @@ -794,39 +694,25 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, { opcode: "deletePopInput", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("delete popup with ID [ID]"), + text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set default value of input [ID] to [VALUE]" - ), + text: Scratch.translate("set default value of input [ID] to [VALUE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate(`...type here`), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } }, }, "---", @@ -835,10 +721,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -849,33 +732,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - ARRAY: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate( - `["Option 1", "Option 2", "Option 3"]` - ), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate( - "is dropdown [DROP_ID] in popup [POP_ID] open?" - ), + text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), arguments: { - DROP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Buttons"), @@ -884,27 +751,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new button with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("Submit"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } }, }, { @@ -912,10 +768,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -923,10 +776,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } }, }, "---", @@ -935,14 +785,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -950,14 +794,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -965,10 +803,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, createBlockLabel("Operators"), @@ -977,7 +812,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } }, }, { @@ -985,10 +820,7 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -996,28 +828,17 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "show next popup with ID [ID] on the [TYPE]" - ), + text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { - type: Scratch.ArgumentType.STRING, - menu: "POPUP_LOCATION", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } }, }, { @@ -1026,25 +847,17 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set auto-close action in popup [ID] to [KEY] key" - ), + text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } }, }, createBlockLabel("Customization"), @@ -1054,11 +867,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, { @@ -1067,11 +877,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, "---", @@ -1082,44 +889,31 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set font size of [ELEMENT] [ID] to [SIZE]" - ), + text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1131,52 +925,36 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "#ff0000", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" - ), + text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1187,27 +965,19 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate( - "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" - ), + text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { @@ -1218,94 +988,61 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, ], menus: { FONTS: { acceptReporters: true, items: "getFonts" }, - POP_STYLES: { - acceptReporters: true, - items: this.genStyleList("popup"), - }, - LAB_STYLES: { - acceptReporters: true, - items: this.genStyleList("label"), - }, - INP_STYLES: { - acceptReporters: true, - items: this.genStyleList("input"), - }, - BUT_STYLES: { - acceptReporters: true, - items: this.genStyleList("button"), - }, + POP_STYLES: { acceptReporters: true, items: this.genStyleList("popup") }, + LAB_STYLES: { acceptReporters: true, items: this.genStyleList("label") }, + INP_STYLES: { acceptReporters: true, items: this.genStyleList("input") }, + BUT_STYLES: { acceptReporters: true, items: this.genStyleList("button") }, INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { - acceptReporters: true, - items: this.genElementList(false, true, false), - }, - UI_MAIN: { - acceptReporters: true, - items: this.genElementList(true, false, true), - }, - UI_MAIN2: { - acceptReporters: true, - items: this.genElementList(false, false, true), - }, - UI_SELECT: { - acceptReporters: true, - items: this.genElementList(true, true, true), - }, + UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, + UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, + UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, + UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, AWAITS: { acceptReporters: false, - items: [ - createMenuItem("wait", "wait"), - createMenuItem("continue", "continue"), - ], + items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")], + items: [createMenuItem("on", "on"), createMenuItem("off", "off")] }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")], + items: [createMenuItem("x", "x"), createMenuItem("y", "y")] }, POPUP_LOCATION: { acceptReporters: false, - items: [ - createMenuItem("window", "window"), - createMenuItem("canvas", "canvas"), - ], + items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center"), - ], + createMenuItem("center", "center") + ] }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter"), - ], + createMenuItem("shift & enter", "shiftEnter") + ] }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose"), - ], + createMenuItem("auto close", "autoClose") + ] }, }, }; @@ -1313,21 +1050,14 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager - ? runtime.fontManager - .getFonts() - .map((i) => ({ text: i.name, value: i.family })) - : []; - return [...defaultFonts, ...custFonts]; + const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [ ...defaultFonts, ...custFonts ]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push( - createMenuItem("label", "label"), - createMenuItem("input", "input") - ); + list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1342,7 +1072,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius"), + createMenuItem("border radius", "border-radius") ]; } @@ -1362,12 +1092,9 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) - util.yield(); - if (reportResponse) - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); + if (reportResponse) return typeof popup.value === "object" ? + JSON.stringify(popup.value) : popup.value || ""; } // Block Funcs @@ -1384,9 +1111,7 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; } removePopup(args) { @@ -1425,7 +1150,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex === -1) popup.elements.push(element); } @@ -1437,7 +1162,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1459,8 +1184,7 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") - return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1482,9 +1206,7 @@ const id = Cast.toString(args.ID); let type = Cast.toString(args.TYPE); - const isValidInput = validInputs.findIndex((i) => { - return i.value === type; - }); + const isValidInput = validInputs.findIndex((i) => { return i.value === type }); if (isValidInput === -1) type = "text"; elementStorage.inputs[id] = createInput(id, type, {}); } @@ -1525,7 +1247,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID; + return e.type === "input" && e.data.id === dropID }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1560,9 +1282,7 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { - return i.id === btn.data.id; - }); + const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); if (btnIndex > -1) return; btnList.push(btn.data); row.DOMelement.appendChild(btn.DOMelement); @@ -1574,9 +1294,7 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { - return i.id === btn.data.id; - }); + const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); if (btnIndex === -1) return; btnList.splice(btnIndex, 1); row.DOMelement.children[btnIndex].remove(); @@ -1625,8 +1343,9 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[option === "focus" ? "focused" : "autoControl"] = - args.TYPE === "on"; + popup[ + option === "focus" ? "focused" : "autoControl" + ] = args.TYPE === "on"; } setForceClose(args) { @@ -1683,12 +1402,9 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => { - return i.value === param; - }); + const isValidStyle = this.genStyleList().findIndex((i) => { return i.value === param }); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1696,10 +1412,7 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) - value = /^\d+$/.test(value.replaceAll(" ", "")) - ? value.replaceAll(" ", "px ") - : value; + if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; else value = `${value}px`; } } @@ -1711,13 +1424,10 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => { - return i.value === args.TYPE; - }); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => { return i.value === args.TYPE }); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1726,22 +1436,16 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") - styles["text-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else - styles["box-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1750,13 +1454,10 @@ setElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const effectIndex = validEffects.findIndex((i) => { - return i.value === effect; - }); + const effectIndex = validEffects.findIndex((i) => { return i.value === effect }); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1769,10 +1470,10 @@ value += "px"; break; case "brightness": - value = `${100 - value * -1}%`; + value = `${100 - (value * -1)}%`; break; case "opacity": - value = 1 - value / 100; + value = 1 - (value / 100); break; case "saturate": case "sepia": @@ -1805,14 +1506,11 @@ getElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const isValidEffect = validEffects.findIndex((i) => { - return i.value === effect; - }); + const isValidEffect = validEffects.findIndex((i) => { return i.value === effect }); if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From d7f4074c4411c1ec8f15d6882a76d521a45e243e Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Sat, 3 May 2025 06:16:09 +0000 Subject: [PATCH 08/17] [Automated] Format code --- extensions/SharkPool/Popup-Phoenix.js | 774 ++++++++++++++++++-------- 1 file changed, 542 insertions(+), 232 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 748d470701..fc09fc0aed 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,18 +8,25 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) + throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return start + { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" - }[name]; + const start = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return ( + start + + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: + "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: + "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", + }[name] + ); }; const Cast = Scratch.Cast; @@ -29,15 +36,20 @@ const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", "Serif", "Handwriting", - "Marker", "Curly", "Pixel", "Scratch" + "Sans Serif", + "Serif", + "Handwriting", + "Marker", + "Curly", + "Pixel", + "Scratch", ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button") + button: Scratch.translate("submit-button"), }; const validInputs = [ @@ -50,7 +62,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert") + createMenuItem("vertical slider", "rangeVert"), ]; const validBorders = [ createMenuItem("none", "none"), @@ -61,7 +73,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset") + createMenuItem("outset", "outset"), ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -76,7 +88,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY") + createMenuItem("skew y", "skewY"), ]; // internals @@ -84,24 +96,29 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { switch (c) { - case "<": return "<"; - case ">": return ">"; - case "&": return "&"; - case "'": return "'"; - case "\"": return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; } }); }; @@ -137,18 +154,28 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; opt.text = option; + opt.value = option; + opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { options.menuOpened = true }); - element.addEventListener("blur", () => { options.menuOpened = false }); - element.addEventListener("change", (e) => setElementValue([e.target.value])); + element.addEventListener("focus", () => { + options.menuOpened = true; + }); + element.addEventListener("blur", () => { + options.menuOpened = false; + }); + element.addEventListener("change", (e) => + setElementValue([e.target.value]) + ); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + holder.setAttribute( + "style", + "display: flex; padding: 5px; cursor: pointer" + ); const check = document.createElement("input"); check.type = "checkbox"; @@ -167,7 +194,10 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + optionsDiv.setAttribute( + "style", + "overflow-y: scroll; height: calc(100% - 1px);" + ); element.appendChild(optionsDiv); setElementValue(response); @@ -176,7 +206,8 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") + e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -217,7 +248,10 @@ element.value = options.defaultValue ?? ""; if (type === "color") { - inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + inputHolder.setAttribute( + "style", + "display: flex; justify-content: center; width: 100%;" + ); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -246,7 +280,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder + DOMelement: inputHolder, }; }; @@ -258,7 +292,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow + DOMelement: buttonRow, }; }; @@ -272,7 +306,7 @@ return { type: "button", data: { id, text }, - DOMelement: element + DOMelement: element, }; }; @@ -281,20 +315,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - "display": "flex", + display: "flex", "flex-direction": "column", - "position": "absolute", + position: "absolute", "pointer-events": "auto", - "transform": "translate(-50%, -50%)", - "filter": "", - "left": "calc(50% + 0px)", - "top": "calc(50% + 0px)", - "width": "max-content", - "height": "auto", - "padding": "15px", - "background": "#fff", + transform: "translate(-50%, -50%)", + filter: "", + left: "calc(50% + 0px)", + top: "calc(50% + 0px)", + width: "max-content", + height: "auto", + padding: "15px", + background: "#fff", "box-shadow": "#000 0px 0px 5px", - "border": "1px none #000", + border: "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -302,66 +336,69 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - "margin": "5px", - "color": "#000", + margin: "5px", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - "width": "max-content", - "height": "auto", - "margin": "5px", - "padding": "5px", - "border": "1px solid #000", + width: "max-content", + height: "auto", + margin: "5px", + padding: "5px", + border: "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - "background": "#a5aec3", + background: "#a5aec3", "accent-color": "#9f50d9", - "color": "#000", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - "width": "auto", - "height": "auto", - "cursor": "pointer", - "margin": "5px", - "padding": "5px 10px", + width: "auto", + height: "auto", + cursor: "pointer", + margin: "5px", + padding: "5px 10px", "border-radius": "5px", - "border": "1px none #fff", - "background": "#0074d9", + border: "1px none #fff", + background: "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - "color": "#fff", + color: "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } return styleStorage[type + "s"][id]; - } + }; const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); - defaultElements.push(createInput( - "default-input", "text", - { defaultValue: Scratch.translate("...type your name") } - )); + defaultElements.push( + createLabel("default-label", Scratch.translate("Whats Your Name?")) + ); + defaultElements.push( + createInput("default-input", "text", { + defaultValue: Scratch.translate("...type your name"), + }) + ); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -380,7 +417,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements + elements: defaultElements, }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -391,7 +428,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - } + }; // popup box GUI const compileStyles = (id, type) => { @@ -400,7 +437,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + if (styleObj["height"] === "auto") styleObj["height"] = "30px"; } let styleString = ""; @@ -416,9 +453,13 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute( + "style", + "position: fixed; width: 100%; height: 100%;" + ); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) + popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -433,7 +474,8 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) + boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -441,7 +483,8 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) + handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -454,7 +497,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -462,7 +507,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } } }; @@ -480,21 +527,24 @@ const refreshedInput = elementStorage.inputs[item.data.id]; const recentData = refreshedInput.data; element = createInput( - recentData.id, recentData.type, recentData.options + recentData.id, + recentData.type, + recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element) + popupPanel.appendChild(element); // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) + element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -510,7 +560,8 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) + runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -527,9 +578,10 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = + type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -537,15 +589,17 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + blockType: Scratch.BlockType.LABEL, + text: Scratch.translate(text), }; - }; + } function createMenuItem(text, value) { return { - text: Scratch.translate(text), value + text: Scratch.translate(text), + value, }; - }; + } genDefaultBox("default-popup", false); @@ -569,8 +623,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, }, }, { @@ -578,7 +635,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -586,7 +646,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -595,13 +658,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups") + text: Scratch.translate("remove all popups"), }, createBlockLabel("Popups"), { @@ -609,7 +675,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("new-popup"), + }, }, }, { @@ -617,28 +686,47 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + text: Scratch.translate( + "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + text: Scratch.translate( + "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -646,7 +734,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -655,9 +746,12 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER } + Y: { type: Scratch.ArgumentType.NUMBER }, }, }, { @@ -666,17 +760,28 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new label with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("whats your name?"), + }, }, }, { @@ -684,7 +789,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, }, }, createBlockLabel("Inputs"), @@ -694,7 +802,10 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, { @@ -702,17 +813,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set default value of input [ID] to [VALUE]"), + text: Scratch.translate( + "set default value of input [ID] to [VALUE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate(`...type here`), + }, }, }, "---", @@ -721,7 +843,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -732,17 +857,33 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + ARRAY: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate( + `["Option 1", "Option 2", "Option 3"]` + ), + }, }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + text: Scratch.translate( + "is dropdown [DROP_ID] in popup [POP_ID] open?" + ), arguments: { - DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + DROP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Buttons"), @@ -751,16 +892,27 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new button with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("Submit"), + }, }, }, { @@ -768,7 +920,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -776,7 +931,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, }, }, "---", @@ -785,8 +943,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -794,8 +958,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -803,7 +973,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, createBlockLabel("Operators"), @@ -812,7 +985,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, }, }, { @@ -820,7 +993,10 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -828,17 +1004,28 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + text: Scratch.translate( + "show next popup with ID [ID] on the [TYPE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "POPUP_LOCATION", + }, }, }, { @@ -847,17 +1034,25 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + text: Scratch.translate( + "set auto-close action in popup [ID] to [KEY] key" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, }, }, createBlockLabel("Customization"), @@ -867,8 +1062,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, { @@ -877,8 +1075,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, "---", @@ -889,31 +1090,44 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + text: Scratch.translate( + "set font size of [ELEMENT] [ID] to [SIZE]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -925,36 +1139,52 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "#ff0000", + }, }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + text: Scratch.translate( + "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -965,19 +1195,27 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + text: Scratch.translate( + "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" + ), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { @@ -988,61 +1226,94 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, ], menus: { FONTS: { acceptReporters: true, items: "getFonts" }, - POP_STYLES: { acceptReporters: true, items: this.genStyleList("popup") }, - LAB_STYLES: { acceptReporters: true, items: this.genStyleList("label") }, - INP_STYLES: { acceptReporters: true, items: this.genStyleList("input") }, - BUT_STYLES: { acceptReporters: true, items: this.genStyleList("button") }, + POP_STYLES: { + acceptReporters: true, + items: this.genStyleList("popup"), + }, + LAB_STYLES: { + acceptReporters: true, + items: this.genStyleList("label"), + }, + INP_STYLES: { + acceptReporters: true, + items: this.genStyleList("input"), + }, + BUT_STYLES: { + acceptReporters: true, + items: this.genStyleList("button"), + }, INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, - UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, - UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, - UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + UI_ELEMENTS: { + acceptReporters: true, + items: this.genElementList(false, true, false), + }, + UI_MAIN: { + acceptReporters: true, + items: this.genElementList(true, false, true), + }, + UI_MAIN2: { + acceptReporters: true, + items: this.genElementList(false, false, true), + }, + UI_SELECT: { + acceptReporters: true, + items: this.genElementList(true, true, true), + }, AWAITS: { acceptReporters: false, - items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + items: [ + createMenuItem("wait", "wait"), + createMenuItem("continue", "continue"), + ], }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + items: [createMenuItem("on", "on"), createMenuItem("off", "off")], }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + items: [createMenuItem("x", "x"), createMenuItem("y", "y")], }, POPUP_LOCATION: { acceptReporters: false, - items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + items: [ + createMenuItem("window", "window"), + createMenuItem("canvas", "canvas"), + ], }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center") - ] + createMenuItem("center", "center"), + ], }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter") - ] + createMenuItem("shift & enter", "shiftEnter"), + ], }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose") - ] + createMenuItem("auto close", "autoClose"), + ], }, }, }; @@ -1050,14 +1321,21 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; - return [ ...defaultFonts, ...custFonts ]; + const custFonts = runtime.fontManager + ? runtime.fontManager + .getFonts() + .map((i) => ({ text: i.name, value: i.family })) + : []; + return [...defaultFonts, ...custFonts]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + list.push( + createMenuItem("label", "label"), + createMenuItem("input", "input") + ); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1072,7 +1350,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius") + createMenuItem("border radius", "border-radius"), ]; } @@ -1092,9 +1370,12 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); - if (reportResponse) return typeof popup.value === "object" ? - JSON.stringify(popup.value) : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) + util.yield(); + if (reportResponse) + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } // Block Funcs @@ -1111,7 +1392,9 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } removePopup(args) { @@ -1150,7 +1433,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex === -1) popup.elements.push(element); } @@ -1162,7 +1445,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1184,7 +1467,8 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") + return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1206,7 +1490,9 @@ const id = Cast.toString(args.ID); let type = Cast.toString(args.TYPE); - const isValidInput = validInputs.findIndex((i) => { return i.value === type }); + const isValidInput = validInputs.findIndex((i) => { + return i.value === type; + }); if (isValidInput === -1) type = "text"; elementStorage.inputs[id] = createInput(id, type, {}); } @@ -1247,7 +1533,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID + return e.type === "input" && e.data.id === dropID; }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1282,7 +1568,9 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + const btnIndex = btnList.findIndex((i) => { + return i.id === btn.data.id; + }); if (btnIndex > -1) return; btnList.push(btn.data); row.DOMelement.appendChild(btn.DOMelement); @@ -1294,7 +1582,9 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { return i.id === btn.data.id}); + const btnIndex = btnList.findIndex((i) => { + return i.id === btn.data.id; + }); if (btnIndex === -1) return; btnList.splice(btnIndex, 1); row.DOMelement.children[btnIndex].remove(); @@ -1343,9 +1633,8 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[ - option === "focus" ? "focused" : "autoControl" - ] = args.TYPE === "on"; + popup[option === "focus" ? "focused" : "autoControl"] = + args.TYPE === "on"; } setForceClose(args) { @@ -1402,9 +1691,12 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => { return i.value === param }); + const isValidStyle = this.genStyleList().findIndex((i) => { + return i.value === param; + }); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1412,7 +1704,10 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + if (value.includes(" ")) + value = /^\d+$/.test(value.replaceAll(" ", "")) + ? value.replaceAll(" ", "px ") + : value; else value = `${value}px`; } } @@ -1424,10 +1719,13 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => { return i.value === args.TYPE }); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => { + return i.value === args.TYPE; + }); + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1436,16 +1734,22 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") + styles["text-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else + styles["box-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1454,10 +1758,13 @@ setElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const effectIndex = validEffects.findIndex((i) => { return i.value === effect }); + const effectIndex = validEffects.findIndex((i) => { + return i.value === effect; + }); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1470,10 +1777,10 @@ value += "px"; break; case "brightness": - value = `${100 - (value * -1)}%`; + value = `${100 - value * -1}%`; break; case "opacity": - value = 1 - (value / 100); + value = 1 - value / 100; break; case "saturate": case "sepia": @@ -1506,11 +1813,14 @@ getElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const isValidEffect = validEffects.findIndex((i) => { return i.value === effect }); + const isValidEffect = validEffects.findIndex((i) => { + return i.value === effect; + }); if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From aa63fc75c2cc4aae72d4541075ea6abba938c716 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sun, 1 Jun 2025 21:54:31 -0700 Subject: [PATCH 09/17] Popup-Phoenix.js -- fix a bug --- extensions/SharkPool/Popup-Phoenix.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index fc09fc0aed..d1c2c823b5 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,7 +4,7 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.03 +// Version V.1.0.04 (function (Scratch) { "use strict"; @@ -525,6 +525,7 @@ boxInputs.push(item); const refreshedInput = elementStorage.inputs[item.data.id]; + if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( recentData.id, From ed8416eefe920f6e50d5a377c89d649ffb721c1d Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sat, 12 Jul 2025 15:40:48 -0700 Subject: [PATCH 10/17] Popup-Phoenix.js -- do not autocomplete passwords --- extensions/SharkPool/Popup-Phoenix.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index d1c2c823b5..dbb0c59780 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,7 +4,7 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.04 +// Version V.1.0.05 (function (Scratch) { "use strict"; @@ -247,7 +247,8 @@ element.type = type; element.value = options.defaultValue ?? ""; - if (type === "color") { + if (type === "password") element.setAttribute("autocomplete", "off"); + else if (type === "color") { inputHolder.setAttribute( "style", "display: flex; justify-content: center; width: 100%;" From dd975d70e91465b0b2612c4966b59bfd49514c8b Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:56:07 -0700 Subject: [PATCH 11/17] Popup-Phoenix.js -- force hide password? --- extensions/SharkPool/Popup-Phoenix.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index dbb0c59780..4137206602 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,7 +4,7 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.05 +// Version V.1.0.06 (function (Scratch) { "use strict"; @@ -247,8 +247,10 @@ element.type = type; element.value = options.defaultValue ?? ""; - if (type === "password") element.setAttribute("autocomplete", "off"); - else if (type === "color") { + if (type === "password") { + element.setAttribute("autocomplete", "off"); + element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); + } else if (type === "color") { inputHolder.setAttribute( "style", "display: flex; justify-content: center; width: 100%;" From b60f9f900f94b13ce064f6892f67a04895164fa2 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sun, 24 Aug 2025 00:05:44 -0700 Subject: [PATCH 12/17] Popup-Phoenix.js -- label alignment support + format --- extensions/SharkPool/Popup-Phoenix.js | 784 ++++++++------------------ 1 file changed, 239 insertions(+), 545 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 4137206602..208c60e2d3 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,29 +4,22 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.06 +// Version V.1.0.07 (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) - throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return ( - start + - { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: - "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: - "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", - }[name] - ); + const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return start + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" + }[name]; }; const Cast = Scratch.Cast; @@ -36,20 +29,15 @@ const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", - "Serif", - "Handwriting", - "Marker", - "Curly", - "Pixel", - "Scratch", + "Sans Serif", "Serif", "Handwriting", + "Marker", "Curly", "Pixel", "Scratch" ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button"), + button: Scratch.translate("submit-button") }; const validInputs = [ @@ -62,7 +50,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert"), + createMenuItem("vertical slider", "rangeVert") ]; const validBorders = [ createMenuItem("none", "none"), @@ -73,7 +61,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset"), + createMenuItem("outset", "outset") ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -88,7 +76,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY"), + createMenuItem("skew y", "skewY") ]; // internals @@ -96,29 +84,24 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { switch (c) { - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - case "'": - return "'"; - case '"': - return """; + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; } }); }; @@ -154,28 +137,18 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; - opt.text = option; + opt.value = option; opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { - options.menuOpened = true; - }); - element.addEventListener("blur", () => { - options.menuOpened = false; - }); - element.addEventListener("change", (e) => - setElementValue([e.target.value]) - ); + element.addEventListener("focus", () => { options.menuOpened = true }); + element.addEventListener("blur", () => { options.menuOpened = false }); + element.addEventListener("change", (e) => setElementValue([e.target.value])); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute( - "style", - "display: flex; padding: 5px; cursor: pointer" - ); + holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); const check = document.createElement("input"); check.type = "checkbox"; @@ -194,10 +167,7 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute( - "style", - "overflow-y: scroll; height: calc(100% - 1px);" - ); + optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); element.appendChild(optionsDiv); setElementValue(response); @@ -206,8 +176,7 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") - e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -251,10 +220,7 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute( - "style", - "display: flex; justify-content: center; width: 100%;" - ); + inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -283,7 +249,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder, + DOMelement: inputHolder }; }; @@ -295,7 +261,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow, + DOMelement: buttonRow }; }; @@ -309,7 +275,7 @@ return { type: "button", data: { id, text }, - DOMelement: element, + DOMelement: element }; }; @@ -318,20 +284,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - display: "flex", + "display": "flex", "flex-direction": "column", - position: "absolute", + "position": "absolute", "pointer-events": "auto", - transform: "translate(-50%, -50%)", - filter: "", - left: "calc(50% + 0px)", - top: "calc(50% + 0px)", - width: "max-content", - height: "auto", - padding: "15px", - background: "#fff", + "transform": "translate(-50%, -50%)", + "filter": "", + "left": "calc(50% + 0px)", + "top": "calc(50% + 0px)", + "width": "max-content", + "height": "auto", + "padding": "15px", + "background": "#fff", "box-shadow": "#000 0px 0px 5px", - border: "1px none #000", + "border": "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -339,69 +305,66 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - margin: "5px", - color: "#000", + "margin": "5px", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - width: "max-content", - height: "auto", - margin: "5px", - padding: "5px", - border: "1px solid #000", + "width": "max-content", + "height": "auto", + "margin": "5px", + "padding": "5px", + "border": "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - background: "#a5aec3", + "background": "#a5aec3", "accent-color": "#9f50d9", - color: "#000", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - width: "auto", - height: "auto", - cursor: "pointer", - margin: "5px", - padding: "5px 10px", + "width": "auto", + "height": "auto", + "cursor": "pointer", + "margin": "5px", + "padding": "5px 10px", "border-radius": "5px", - border: "1px none #fff", - background: "#0074d9", + "border": "1px none #fff", + "background": "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - color: "#fff", + "color": "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } return styleStorage[type + "s"][id]; - }; + } const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push( - createLabel("default-label", Scratch.translate("Whats Your Name?")) - ); - defaultElements.push( - createInput("default-input", "text", { - defaultValue: Scratch.translate("...type your name"), - }) - ); + defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); + defaultElements.push(createInput( + "default-input", "text", + { defaultValue: Scratch.translate("...type your name") } + )); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -420,7 +383,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements, + elements: defaultElements }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -431,7 +394,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - }; + } // popup box GUI const compileStyles = (id, type) => { @@ -440,7 +403,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto") styleObj["height"] = "30px"; + if (styleObj["height"] === "auto")styleObj["height"] = "30px"; } let styleString = ""; @@ -456,13 +419,9 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute( - "style", - "position: fixed; width: 100%; height: 100%;" - ); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) - popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -477,8 +436,7 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) - boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -486,8 +444,7 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) - handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -500,9 +457,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -510,9 +465,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } } }; @@ -531,24 +484,21 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, - recentData.type, - recentData.options + recentData.id, recentData.type, recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element); + popupPanel.appendChild(element) // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) - element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -564,8 +514,7 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) - runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -582,10 +531,9 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = - type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -593,17 +541,15 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, - text: Scratch.translate(text), + blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) }; - } + }; function createMenuItem(text, value) { return { - text: Scratch.translate(text), - value, + text: Scratch.translate(text), value }; - } + }; genDefaultBox("default-popup", false); @@ -627,11 +573,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } }, }, { @@ -639,10 +582,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -650,10 +590,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -662,16 +599,13 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups"), + text: Scratch.translate("remove all popups") }, createBlockLabel("Popups"), { @@ -679,10 +613,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("new-popup"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } }, }, { @@ -690,47 +621,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" - ), + text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" - ), + text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -738,10 +650,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -750,12 +659,9 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER } }, }, { @@ -764,28 +670,17 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new label with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("whats your name?"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } }, }, { @@ -793,10 +688,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } }, }, createBlockLabel("Inputs"), @@ -806,10 +698,7 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, { @@ -817,28 +706,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set default value of input [ID] to [VALUE]" - ), + text: Scratch.translate("set default value of input [ID] to [VALUE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate(`...type here`), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } }, }, "---", @@ -847,10 +725,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -861,33 +736,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - ARRAY: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate( - `["Option 1", "Option 2", "Option 3"]` - ), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate( - "is dropdown [DROP_ID] in popup [POP_ID] open?" - ), + text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), arguments: { - DROP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Buttons"), @@ -896,27 +755,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new button with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("Submit"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } }, }, { @@ -924,10 +772,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -935,10 +780,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } }, }, "---", @@ -947,14 +789,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -962,14 +798,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -977,10 +807,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, createBlockLabel("Operators"), @@ -989,7 +816,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } }, }, { @@ -997,10 +824,7 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -1008,28 +832,17 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "show next popup with ID [ID] on the [TYPE]" - ), + text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { - type: Scratch.ArgumentType.STRING, - menu: "POPUP_LOCATION", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } }, }, { @@ -1038,25 +851,17 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set auto-close action in popup [ID] to [KEY] key" - ), + text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } }, }, createBlockLabel("Customization"), @@ -1066,11 +871,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, { @@ -1079,11 +881,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, "---", @@ -1094,44 +893,31 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set font size of [ELEMENT] [ID] to [SIZE]" - ), + text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1143,52 +929,36 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "#ff0000", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" - ), + text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1199,27 +969,19 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate( - "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" - ), + text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { @@ -1230,94 +992,58 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, ], menus: { FONTS: { acceptReporters: true, items: "getFonts" }, - POP_STYLES: { - acceptReporters: true, - items: this.genStyleList("popup"), - }, - LAB_STYLES: { - acceptReporters: true, - items: this.genStyleList("label"), - }, - INP_STYLES: { - acceptReporters: true, - items: this.genStyleList("input"), - }, - BUT_STYLES: { - acceptReporters: true, - items: this.genStyleList("button"), - }, + POP_STYLES: { acceptReporters: true, items: this.genStyleList() }, INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { - acceptReporters: true, - items: this.genElementList(false, true, false), - }, - UI_MAIN: { - acceptReporters: true, - items: this.genElementList(true, false, true), - }, - UI_MAIN2: { - acceptReporters: true, - items: this.genElementList(false, false, true), - }, - UI_SELECT: { - acceptReporters: true, - items: this.genElementList(true, true, true), - }, + UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, + UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, + UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, + UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, AWAITS: { acceptReporters: false, - items: [ - createMenuItem("wait", "wait"), - createMenuItem("continue", "continue"), - ], + items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")], + items: [createMenuItem("on", "on"), createMenuItem("off", "off")] }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")], + items: [createMenuItem("x", "x"), createMenuItem("y", "y")] }, POPUP_LOCATION: { acceptReporters: false, - items: [ - createMenuItem("window", "window"), - createMenuItem("canvas", "canvas"), - ], + items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center"), - ], + createMenuItem("center", "center") + ] }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter"), - ], + createMenuItem("shift & enter", "shiftEnter") + ] }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose"), - ], + createMenuItem("auto close", "autoClose") + ] }, }, }; @@ -1325,21 +1051,14 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager - ? runtime.fontManager - .getFonts() - .map((i) => ({ text: i.name, value: i.family })) - : []; - return [...defaultFonts, ...custFonts]; + const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [ ...defaultFonts, ...custFonts ]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push( - createMenuItem("label", "label"), - createMenuItem("input", "input") - ); + list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1354,7 +1073,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius"), + createMenuItem("border radius", "border-radius") ]; } @@ -1374,12 +1093,9 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) - util.yield(); - if (reportResponse) - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); + if (reportResponse) return typeof popup.value === "object" ? + JSON.stringify(popup.value) : popup.value || ""; } // Block Funcs @@ -1396,9 +1112,7 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; } removePopup(args) { @@ -1437,7 +1151,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex === -1) popup.elements.push(element); } @@ -1449,7 +1163,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1471,8 +1185,7 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") - return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1494,9 +1207,7 @@ const id = Cast.toString(args.ID); let type = Cast.toString(args.TYPE); - const isValidInput = validInputs.findIndex((i) => { - return i.value === type; - }); + const isValidInput = validInputs.findIndex((i) => i.value === type); if (isValidInput === -1) type = "text"; elementStorage.inputs[id] = createInput(id, type, {}); } @@ -1537,7 +1248,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID; + return e.type === "input" && e.data.id === dropID }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1572,9 +1283,7 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { - return i.id === btn.data.id; - }); + const btnIndex = btnList.findIndex((i) => i.id === btn.data.id); if (btnIndex > -1) return; btnList.push(btn.data); row.DOMelement.appendChild(btn.DOMelement); @@ -1586,9 +1295,7 @@ if (row === undefined || btn === undefined) return; const btnList = row.data.buttons; - const btnIndex = btnList.findIndex((i) => { - return i.id === btn.data.id; - }); + const btnIndex = btnList.findIndex((i) => i.id === btn.data.id); if (btnIndex === -1) return; btnList.splice(btnIndex, 1); row.DOMelement.children[btnIndex].remove(); @@ -1637,8 +1344,9 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[option === "focus" ? "focused" : "autoControl"] = - args.TYPE === "on"; + popup[ + option === "focus" ? "focused" : "autoControl" + ] = args.TYPE === "on"; } setForceClose(args) { @@ -1661,9 +1369,16 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - const styles = styleStorage.inputs[id] ?? genDefaultStyles(id, "input"); + let isLabel = false + let styles = styleStorage.inputs[id]; + if (!styles) { + styles = styleStorage.labels[id]; + if (styles) isLabel = true; + else styles = genDefaultStyles(id, "input"); + } + styles["text-align"] = args.TYPE === "flex-end" ? "right" : args.TYPE; - updateBoxVisuals(id, "inputs"); + updateBoxVisuals(id, isLabel ? "labels" : "inputs"); } setInputFont(args) { @@ -1695,12 +1410,9 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => { - return i.value === param; - }); + const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1708,10 +1420,7 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) - value = /^\d+$/.test(value.replaceAll(" ", "")) - ? value.replaceAll(" ", "px ") - : value; + if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; else value = `${value}px`; } } @@ -1723,13 +1432,10 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => { - return i.value === args.TYPE; - }); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1738,22 +1444,16 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") - styles["text-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else - styles["box-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1762,13 +1462,10 @@ setElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const effectIndex = validEffects.findIndex((i) => { - return i.value === effect; - }); + const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1781,10 +1478,10 @@ value += "px"; break; case "brightness": - value = `${100 - value * -1}%`; + value = `${100 - (value * -1)}%`; break; case "opacity": - value = 1 - value / 100; + value = 1 - (value / 100); break; case "saturate": case "sepia": @@ -1817,14 +1514,11 @@ getElementEffect(args) { const effect = Cast.toString(args.EFFECT); - const isValidEffect = validEffects.findIndex((i) => { - return i.value === effect; - }); + const isValidEffect = validEffects.findIndex((i) => i.value === effect); if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From acbcb7dcbffb8c82cda6eb9a8d38db5b9fd8c5aa Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Sun, 24 Aug 2025 07:07:01 +0000 Subject: [PATCH 13/17] [Automated] Format code --- extensions/SharkPool/Popup-Phoenix.js | 736 ++++++++++++++++++-------- 1 file changed, 512 insertions(+), 224 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 208c60e2d3..760d324abc 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,18 +8,25 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) + throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return start + { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" - }[name]; + const start = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return ( + start + + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: + "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: + "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", + }[name] + ); }; const Cast = Scratch.Cast; @@ -29,15 +36,20 @@ const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", "Serif", "Handwriting", - "Marker", "Curly", "Pixel", "Scratch" + "Sans Serif", + "Serif", + "Handwriting", + "Marker", + "Curly", + "Pixel", + "Scratch", ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button") + button: Scratch.translate("submit-button"), }; const validInputs = [ @@ -50,7 +62,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert") + createMenuItem("vertical slider", "rangeVert"), ]; const validBorders = [ createMenuItem("none", "none"), @@ -61,7 +73,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset") + createMenuItem("outset", "outset"), ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -76,7 +88,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY") + createMenuItem("skew y", "skewY"), ]; // internals @@ -84,24 +96,29 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { switch (c) { - case "<": return "<"; - case ">": return ">"; - case "&": return "&"; - case "'": return "'"; - case "\"": return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; } }); }; @@ -137,18 +154,28 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; opt.text = option; + opt.value = option; + opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { options.menuOpened = true }); - element.addEventListener("blur", () => { options.menuOpened = false }); - element.addEventListener("change", (e) => setElementValue([e.target.value])); + element.addEventListener("focus", () => { + options.menuOpened = true; + }); + element.addEventListener("blur", () => { + options.menuOpened = false; + }); + element.addEventListener("change", (e) => + setElementValue([e.target.value]) + ); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + holder.setAttribute( + "style", + "display: flex; padding: 5px; cursor: pointer" + ); const check = document.createElement("input"); check.type = "checkbox"; @@ -167,7 +194,10 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + optionsDiv.setAttribute( + "style", + "overflow-y: scroll; height: calc(100% - 1px);" + ); element.appendChild(optionsDiv); setElementValue(response); @@ -176,7 +206,8 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") + e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -220,7 +251,10 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + inputHolder.setAttribute( + "style", + "display: flex; justify-content: center; width: 100%;" + ); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -249,7 +283,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder + DOMelement: inputHolder, }; }; @@ -261,7 +295,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow + DOMelement: buttonRow, }; }; @@ -275,7 +309,7 @@ return { type: "button", data: { id, text }, - DOMelement: element + DOMelement: element, }; }; @@ -284,20 +318,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - "display": "flex", + display: "flex", "flex-direction": "column", - "position": "absolute", + position: "absolute", "pointer-events": "auto", - "transform": "translate(-50%, -50%)", - "filter": "", - "left": "calc(50% + 0px)", - "top": "calc(50% + 0px)", - "width": "max-content", - "height": "auto", - "padding": "15px", - "background": "#fff", + transform: "translate(-50%, -50%)", + filter: "", + left: "calc(50% + 0px)", + top: "calc(50% + 0px)", + width: "max-content", + height: "auto", + padding: "15px", + background: "#fff", "box-shadow": "#000 0px 0px 5px", - "border": "1px none #000", + border: "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -305,66 +339,69 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - "margin": "5px", - "color": "#000", + margin: "5px", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - "width": "max-content", - "height": "auto", - "margin": "5px", - "padding": "5px", - "border": "1px solid #000", + width: "max-content", + height: "auto", + margin: "5px", + padding: "5px", + border: "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - "background": "#a5aec3", + background: "#a5aec3", "accent-color": "#9f50d9", - "color": "#000", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - "width": "auto", - "height": "auto", - "cursor": "pointer", - "margin": "5px", - "padding": "5px 10px", + width: "auto", + height: "auto", + cursor: "pointer", + margin: "5px", + padding: "5px 10px", "border-radius": "5px", - "border": "1px none #fff", - "background": "#0074d9", + border: "1px none #fff", + background: "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - "color": "#fff", + color: "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } return styleStorage[type + "s"][id]; - } + }; const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); - defaultElements.push(createInput( - "default-input", "text", - { defaultValue: Scratch.translate("...type your name") } - )); + defaultElements.push( + createLabel("default-label", Scratch.translate("Whats Your Name?")) + ); + defaultElements.push( + createInput("default-input", "text", { + defaultValue: Scratch.translate("...type your name"), + }) + ); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -383,7 +420,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements + elements: defaultElements, }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -394,7 +431,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - } + }; // popup box GUI const compileStyles = (id, type) => { @@ -403,7 +440,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + if (styleObj["height"] === "auto") styleObj["height"] = "30px"; } let styleString = ""; @@ -419,9 +456,13 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute( + "style", + "position: fixed; width: 100%; height: 100%;" + ); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) + popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -436,7 +477,8 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) + boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -444,7 +486,8 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) + handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -457,7 +500,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -465,7 +510,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } } }; @@ -484,21 +531,24 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, recentData.type, recentData.options + recentData.id, + recentData.type, + recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element) + popupPanel.appendChild(element); // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) + element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -514,7 +564,8 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) + runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -531,9 +582,10 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = + type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -541,15 +593,17 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + blockType: Scratch.BlockType.LABEL, + text: Scratch.translate(text), }; - }; + } function createMenuItem(text, value) { return { - text: Scratch.translate(text), value + text: Scratch.translate(text), + value, }; - }; + } genDefaultBox("default-popup", false); @@ -573,8 +627,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, }, }, { @@ -582,7 +639,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -590,7 +650,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -599,13 +662,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups") + text: Scratch.translate("remove all popups"), }, createBlockLabel("Popups"), { @@ -613,7 +679,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("new-popup"), + }, }, }, { @@ -621,28 +690,47 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + text: Scratch.translate( + "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + text: Scratch.translate( + "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -650,7 +738,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -659,9 +750,12 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER } + Y: { type: Scratch.ArgumentType.NUMBER }, }, }, { @@ -670,17 +764,28 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new label with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("whats your name?"), + }, }, }, { @@ -688,7 +793,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, }, }, createBlockLabel("Inputs"), @@ -698,7 +806,10 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, { @@ -706,17 +817,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set default value of input [ID] to [VALUE]"), + text: Scratch.translate( + "set default value of input [ID] to [VALUE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate(`...type here`), + }, }, }, "---", @@ -725,7 +847,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -736,17 +861,33 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + ARRAY: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate( + `["Option 1", "Option 2", "Option 3"]` + ), + }, }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + text: Scratch.translate( + "is dropdown [DROP_ID] in popup [POP_ID] open?" + ), arguments: { - DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + DROP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Buttons"), @@ -755,16 +896,27 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new button with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("Submit"), + }, }, }, { @@ -772,7 +924,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -780,7 +935,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, }, }, "---", @@ -789,8 +947,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -798,8 +962,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -807,7 +977,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, createBlockLabel("Operators"), @@ -816,7 +989,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, }, }, { @@ -824,7 +997,10 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -832,17 +1008,28 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + text: Scratch.translate( + "show next popup with ID [ID] on the [TYPE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "POPUP_LOCATION", + }, }, }, { @@ -851,17 +1038,25 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + text: Scratch.translate( + "set auto-close action in popup [ID] to [KEY] key" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, }, }, createBlockLabel("Customization"), @@ -871,8 +1066,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, { @@ -881,8 +1079,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, "---", @@ -893,31 +1094,44 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + text: Scratch.translate( + "set font size of [ELEMENT] [ID] to [SIZE]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -929,36 +1143,52 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "#ff0000", + }, }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + text: Scratch.translate( + "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -969,19 +1199,27 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + text: Scratch.translate( + "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" + ), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { @@ -992,7 +1230,10 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, ], @@ -1002,48 +1243,66 @@ INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, - UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, - UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, - UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + UI_ELEMENTS: { + acceptReporters: true, + items: this.genElementList(false, true, false), + }, + UI_MAIN: { + acceptReporters: true, + items: this.genElementList(true, false, true), + }, + UI_MAIN2: { + acceptReporters: true, + items: this.genElementList(false, false, true), + }, + UI_SELECT: { + acceptReporters: true, + items: this.genElementList(true, true, true), + }, AWAITS: { acceptReporters: false, - items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + items: [ + createMenuItem("wait", "wait"), + createMenuItem("continue", "continue"), + ], }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + items: [createMenuItem("on", "on"), createMenuItem("off", "off")], }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + items: [createMenuItem("x", "x"), createMenuItem("y", "y")], }, POPUP_LOCATION: { acceptReporters: false, - items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + items: [ + createMenuItem("window", "window"), + createMenuItem("canvas", "canvas"), + ], }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center") - ] + createMenuItem("center", "center"), + ], }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter") - ] + createMenuItem("shift & enter", "shiftEnter"), + ], }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose") - ] + createMenuItem("auto close", "autoClose"), + ], }, }, }; @@ -1051,14 +1310,21 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; - return [ ...defaultFonts, ...custFonts ]; + const custFonts = runtime.fontManager + ? runtime.fontManager + .getFonts() + .map((i) => ({ text: i.name, value: i.family })) + : []; + return [...defaultFonts, ...custFonts]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + list.push( + createMenuItem("label", "label"), + createMenuItem("input", "input") + ); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1073,7 +1339,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius") + createMenuItem("border radius", "border-radius"), ]; } @@ -1093,9 +1359,12 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); - if (reportResponse) return typeof popup.value === "object" ? - JSON.stringify(popup.value) : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) + util.yield(); + if (reportResponse) + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } // Block Funcs @@ -1112,7 +1381,9 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } removePopup(args) { @@ -1151,7 +1422,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex === -1) popup.elements.push(element); } @@ -1163,7 +1434,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1185,7 +1456,8 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") + return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1248,7 +1520,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID + return e.type === "input" && e.data.id === dropID; }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1344,9 +1616,8 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[ - option === "focus" ? "focused" : "autoControl" - ] = args.TYPE === "on"; + popup[option === "focus" ? "focused" : "autoControl"] = + args.TYPE === "on"; } setForceClose(args) { @@ -1369,7 +1640,7 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - let isLabel = false + let isLabel = false; let styles = styleStorage.inputs[id]; if (!styles) { styles = styleStorage.labels[id]; @@ -1410,9 +1681,12 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); + const isValidStyle = this.genStyleList().findIndex( + (i) => i.value === param + ); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1420,7 +1694,10 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + if (value.includes(" ")) + value = /^\d+$/.test(value.replaceAll(" ", "")) + ? value.replaceAll(" ", "px ") + : value; else value = `${value}px`; } } @@ -1432,10 +1709,13 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex( + (i) => i.value === args.TYPE + ); + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1444,16 +1724,22 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") + styles["text-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else + styles["box-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1465,7 +1751,8 @@ const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1478,10 +1765,10 @@ value += "px"; break; case "brightness": - value = `${100 - (value * -1)}%`; + value = `${100 - value * -1}%`; break; case "opacity": - value = 1 - (value / 100); + value = 1 - value / 100; break; case "saturate": case "sepia": @@ -1518,7 +1805,8 @@ if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From af472af1632ffdf3d0e89882c719cfd327192414 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sat, 25 Oct 2025 17:30:19 -0700 Subject: [PATCH 14/17] add focus input block --- extensions/SharkPool/Popup-Phoenix.js | 754 ++++++++------------------ 1 file changed, 241 insertions(+), 513 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 760d324abc..acdc127f89 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -4,29 +4,22 @@ // By: SharkPool // Licence: MIT -// Version V.1.0.07 +// Version V.1.0.1 (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) - throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return ( - start + - { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: - "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: - "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", - }[name] - ); + const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return start + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" + }[name]; }; const Cast = Scratch.Cast; @@ -36,20 +29,15 @@ const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", - "Serif", - "Handwriting", - "Marker", - "Curly", - "Pixel", - "Scratch", + "Sans Serif", "Serif", "Handwriting", + "Marker", "Curly", "Pixel", "Scratch" ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button"), + button: Scratch.translate("submit-button") }; const validInputs = [ @@ -62,7 +50,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert"), + createMenuItem("vertical slider", "rangeVert") ]; const validBorders = [ createMenuItem("none", "none"), @@ -73,7 +61,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset"), + createMenuItem("outset", "outset") ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -88,7 +76,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY"), + createMenuItem("skew y", "skewY") ]; // internals @@ -96,29 +84,24 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { switch (c) { - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - case "'": - return "'"; - case '"': - return """; + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; } }); }; @@ -154,28 +137,18 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; - opt.text = option; + opt.value = option; opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { - options.menuOpened = true; - }); - element.addEventListener("blur", () => { - options.menuOpened = false; - }); - element.addEventListener("change", (e) => - setElementValue([e.target.value]) - ); + element.addEventListener("focus", () => { options.menuOpened = true }); + element.addEventListener("blur", () => { options.menuOpened = false }); + element.addEventListener("change", (e) => setElementValue([e.target.value])); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute( - "style", - "display: flex; padding: 5px; cursor: pointer" - ); + holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); const check = document.createElement("input"); check.type = "checkbox"; @@ -194,10 +167,7 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute( - "style", - "overflow-y: scroll; height: calc(100% - 1px);" - ); + optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); element.appendChild(optionsDiv); setElementValue(response); @@ -206,8 +176,7 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") - e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -251,10 +220,7 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute( - "style", - "display: flex; justify-content: center; width: 100%;" - ); + inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -283,7 +249,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder, + DOMelement: inputHolder }; }; @@ -295,7 +261,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow, + DOMelement: buttonRow }; }; @@ -309,7 +275,7 @@ return { type: "button", data: { id, text }, - DOMelement: element, + DOMelement: element }; }; @@ -318,20 +284,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - display: "flex", + "display": "flex", "flex-direction": "column", - position: "absolute", + "position": "absolute", "pointer-events": "auto", - transform: "translate(-50%, -50%)", - filter: "", - left: "calc(50% + 0px)", - top: "calc(50% + 0px)", - width: "max-content", - height: "auto", - padding: "15px", - background: "#fff", + "transform": "translate(-50%, -50%)", + "filter": "", + "left": "calc(50% + 0px)", + "top": "calc(50% + 0px)", + "width": "max-content", + "height": "auto", + "padding": "15px", + "background": "#fff", "box-shadow": "#000 0px 0px 5px", - border: "1px none #000", + "border": "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -339,69 +305,66 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - margin: "5px", - color: "#000", + "margin": "5px", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - width: "max-content", - height: "auto", - margin: "5px", - padding: "5px", - border: "1px solid #000", + "width": "max-content", + "height": "auto", + "margin": "5px", + "padding": "5px", + "border": "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - background: "#a5aec3", + "background": "#a5aec3", "accent-color": "#9f50d9", - color: "#000", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - width: "auto", - height: "auto", - cursor: "pointer", - margin: "5px", - padding: "5px 10px", + "width": "auto", + "height": "auto", + "cursor": "pointer", + "margin": "5px", + "padding": "5px 10px", "border-radius": "5px", - border: "1px none #fff", - background: "#0074d9", + "border": "1px none #fff", + "background": "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - color: "#fff", + "color": "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } return styleStorage[type + "s"][id]; - }; + } const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push( - createLabel("default-label", Scratch.translate("Whats Your Name?")) - ); - defaultElements.push( - createInput("default-input", "text", { - defaultValue: Scratch.translate("...type your name"), - }) - ); + defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); + defaultElements.push(createInput( + "default-input", "text", + { defaultValue: Scratch.translate("...type your name") } + )); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -420,7 +383,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements, + elements: defaultElements }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -431,7 +394,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - }; + } // popup box GUI const compileStyles = (id, type) => { @@ -440,7 +403,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto") styleObj["height"] = "30px"; + if (styleObj["height"] === "auto")styleObj["height"] = "30px"; } let styleString = ""; @@ -456,13 +419,9 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute( - "style", - "position: fixed; width: 100%; height: 100%;" - ); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) - popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -477,8 +436,7 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) - boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -486,8 +444,7 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) - handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -500,9 +457,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -510,9 +465,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } } }; @@ -531,24 +484,21 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, - recentData.type, - recentData.options + recentData.id, recentData.type, recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element); + popupPanel.appendChild(element) // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) - element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -564,8 +514,7 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) - runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -582,10 +531,9 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = - type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -593,17 +541,15 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, - text: Scratch.translate(text), + blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) }; - } + }; function createMenuItem(text, value) { return { - text: Scratch.translate(text), - value, + text: Scratch.translate(text), value }; - } + }; genDefaultBox("default-popup", false); @@ -627,11 +573,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } }, }, { @@ -639,10 +582,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -650,10 +590,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -662,16 +599,13 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups"), + text: Scratch.translate("remove all popups") }, createBlockLabel("Popups"), { @@ -679,10 +613,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("new-popup"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } }, }, { @@ -690,47 +621,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" - ), + text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" - ), + text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -738,10 +650,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -750,12 +659,9 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER } }, }, { @@ -764,28 +670,17 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new label with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("whats your name?"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } }, }, { @@ -793,10 +688,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } }, }, createBlockLabel("Inputs"), @@ -806,10 +698,7 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, { @@ -817,28 +706,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set default value of input [ID] to [VALUE]" - ), + text: Scratch.translate("set default value of input [ID] to [VALUE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate(`...type here`), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } }, }, "---", @@ -847,10 +725,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -861,33 +736,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - ARRAY: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate( - `["Option 1", "Option 2", "Option 3"]` - ), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate( - "is dropdown [DROP_ID] in popup [POP_ID] open?" - ), + text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), arguments: { - DROP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Buttons"), @@ -896,27 +755,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new button with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("Submit"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } }, }, { @@ -924,10 +772,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -935,10 +780,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } }, }, "---", @@ -947,14 +789,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -962,14 +798,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -977,10 +807,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, createBlockLabel("Operators"), @@ -989,7 +816,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } }, }, { @@ -997,10 +824,7 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -1008,28 +832,25 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + }, + }, + { + opcode: "focusInput", + blockType: Scratch.BlockType.COMMAND, + text: Scratch.translate("focus on input with ID [ID]"), + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "show next popup with ID [ID] on the [TYPE]" - ), + text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { - type: Scratch.ArgumentType.STRING, - menu: "POPUP_LOCATION", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } }, }, { @@ -1038,25 +859,17 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set auto-close action in popup [ID] to [KEY] key" - ), + text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } }, }, createBlockLabel("Customization"), @@ -1066,11 +879,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, { @@ -1079,11 +889,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, "---", @@ -1094,44 +901,31 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set font size of [ELEMENT] [ID] to [SIZE]" - ), + text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1143,52 +937,36 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "#ff0000", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" - ), + text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1199,27 +977,19 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate( - "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" - ), + text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { @@ -1230,10 +1000,7 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, ], @@ -1243,66 +1010,48 @@ INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { - acceptReporters: true, - items: this.genElementList(false, true, false), - }, - UI_MAIN: { - acceptReporters: true, - items: this.genElementList(true, false, true), - }, - UI_MAIN2: { - acceptReporters: true, - items: this.genElementList(false, false, true), - }, - UI_SELECT: { - acceptReporters: true, - items: this.genElementList(true, true, true), - }, + UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, + UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, + UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, + UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, AWAITS: { acceptReporters: false, - items: [ - createMenuItem("wait", "wait"), - createMenuItem("continue", "continue"), - ], + items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")], + items: [createMenuItem("on", "on"), createMenuItem("off", "off")] }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")], + items: [createMenuItem("x", "x"), createMenuItem("y", "y")] }, POPUP_LOCATION: { acceptReporters: false, - items: [ - createMenuItem("window", "window"), - createMenuItem("canvas", "canvas"), - ], + items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center"), - ], + createMenuItem("center", "center") + ] }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter"), - ], + createMenuItem("shift & enter", "shiftEnter") + ] }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose"), - ], + createMenuItem("auto close", "autoClose") + ] }, }, }; @@ -1310,21 +1059,14 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager - ? runtime.fontManager - .getFonts() - .map((i) => ({ text: i.name, value: i.family })) - : []; - return [...defaultFonts, ...custFonts]; + const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [ ...defaultFonts, ...custFonts ]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push( - createMenuItem("label", "label"), - createMenuItem("input", "input") - ); + list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1339,7 +1081,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius"), + createMenuItem("border radius", "border-radius") ]; } @@ -1359,12 +1101,9 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) - util.yield(); - if (reportResponse) - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); + if (reportResponse) return typeof popup.value === "object" ? + JSON.stringify(popup.value) : popup.value || ""; } // Block Funcs @@ -1381,9 +1120,7 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; } removePopup(args) { @@ -1422,7 +1159,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex === -1) popup.elements.push(element); } @@ -1434,7 +1171,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1456,8 +1193,7 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") - return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1520,7 +1256,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID; + return e.type === "input" && e.data.id === dropID }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1603,6 +1339,14 @@ return popup.lastBtnPressed ?? ""; } + focusInput(args) { + const input = elementStorage.inputs[Cast.toString(args.ID)]; + if (input) { + input.DOMelement.firstChild.focus(); + } + } + + setPopupTarget(args) { const id = Cast.toString(args.ID); let popup = elementStorage.popups[id]; @@ -1616,8 +1360,9 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[option === "focus" ? "focused" : "autoControl"] = - args.TYPE === "on"; + popup[ + option === "focus" ? "focused" : "autoControl" + ] = args.TYPE === "on"; } setForceClose(args) { @@ -1640,7 +1385,7 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - let isLabel = false; + let isLabel = false let styles = styleStorage.inputs[id]; if (!styles) { styles = styleStorage.labels[id]; @@ -1681,12 +1426,9 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex( - (i) => i.value === param - ); + const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1694,10 +1436,7 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) - value = /^\d+$/.test(value.replaceAll(" ", "")) - ? value.replaceAll(" ", "px ") - : value; + if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; else value = `${value}px`; } } @@ -1709,13 +1448,10 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex( - (i) => i.value === args.TYPE - ); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1724,22 +1460,16 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") - styles["text-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else - styles["box-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1751,8 +1481,7 @@ const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1765,10 +1494,10 @@ value += "px"; break; case "brightness": - value = `${100 - value * -1}%`; + value = `${100 - (value * -1)}%`; break; case "opacity": - value = 1 - value / 100; + value = 1 - (value / 100); break; case "saturate": case "sepia": @@ -1805,8 +1534,7 @@ if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From 7898a2f6f65856178d412242b890854d81f44612 Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Sun, 26 Oct 2025 00:32:28 +0000 Subject: [PATCH 15/17] [Automated] Format code --- extensions/SharkPool/Popup-Phoenix.js | 742 ++++++++++++++++++-------- 1 file changed, 516 insertions(+), 226 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index acdc127f89..ff7b4ef2f1 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,18 +8,25 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) + throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return start + { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" - }[name]; + const start = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return ( + start + + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: + "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: + "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", + }[name] + ); }; const Cast = Scratch.Cast; @@ -29,15 +36,20 @@ const keyUtil = runtime.ioDevices.keyboard; const defaultFonts = [ - "Sans Serif", "Serif", "Handwriting", - "Marker", "Curly", "Pixel", "Scratch" + "Sans Serif", + "Serif", + "Handwriting", + "Marker", + "Curly", + "Pixel", + "Scratch", ]; const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button") + button: Scratch.translate("submit-button"), }; const validInputs = [ @@ -50,7 +62,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert") + createMenuItem("vertical slider", "rangeVert"), ]; const validBorders = [ createMenuItem("none", "none"), @@ -61,7 +73,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset") + createMenuItem("outset", "outset"), ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -76,7 +88,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY") + createMenuItem("skew y", "skewY"), ]; // internals @@ -84,24 +96,29 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { switch (c) { - case "<": return "<"; - case ">": return ">"; - case "&": return "&"; - case "'": return "'"; - case "\"": return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; } }); }; @@ -137,18 +154,28 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; opt.text = option; + opt.value = option; + opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { options.menuOpened = true }); - element.addEventListener("blur", () => { options.menuOpened = false }); - element.addEventListener("change", (e) => setElementValue([e.target.value])); + element.addEventListener("focus", () => { + options.menuOpened = true; + }); + element.addEventListener("blur", () => { + options.menuOpened = false; + }); + element.addEventListener("change", (e) => + setElementValue([e.target.value]) + ); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + holder.setAttribute( + "style", + "display: flex; padding: 5px; cursor: pointer" + ); const check = document.createElement("input"); check.type = "checkbox"; @@ -167,7 +194,10 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + optionsDiv.setAttribute( + "style", + "overflow-y: scroll; height: calc(100% - 1px);" + ); element.appendChild(optionsDiv); setElementValue(response); @@ -176,7 +206,8 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") + e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -220,7 +251,10 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + inputHolder.setAttribute( + "style", + "display: flex; justify-content: center; width: 100%;" + ); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -249,7 +283,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder + DOMelement: inputHolder, }; }; @@ -261,7 +295,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow + DOMelement: buttonRow, }; }; @@ -275,7 +309,7 @@ return { type: "button", data: { id, text }, - DOMelement: element + DOMelement: element, }; }; @@ -284,20 +318,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - "display": "flex", + display: "flex", "flex-direction": "column", - "position": "absolute", + position: "absolute", "pointer-events": "auto", - "transform": "translate(-50%, -50%)", - "filter": "", - "left": "calc(50% + 0px)", - "top": "calc(50% + 0px)", - "width": "max-content", - "height": "auto", - "padding": "15px", - "background": "#fff", + transform: "translate(-50%, -50%)", + filter: "", + left: "calc(50% + 0px)", + top: "calc(50% + 0px)", + width: "max-content", + height: "auto", + padding: "15px", + background: "#fff", "box-shadow": "#000 0px 0px 5px", - "border": "1px none #000", + border: "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -305,66 +339,69 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - "margin": "5px", - "color": "#000", + margin: "5px", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - "width": "max-content", - "height": "auto", - "margin": "5px", - "padding": "5px", - "border": "1px solid #000", + width: "max-content", + height: "auto", + margin: "5px", + padding: "5px", + border: "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - "background": "#a5aec3", + background: "#a5aec3", "accent-color": "#9f50d9", - "color": "#000", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - "width": "auto", - "height": "auto", - "cursor": "pointer", - "margin": "5px", - "padding": "5px 10px", + width: "auto", + height: "auto", + cursor: "pointer", + margin: "5px", + padding: "5px 10px", "border-radius": "5px", - "border": "1px none #fff", - "background": "#0074d9", + border: "1px none #fff", + background: "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - "color": "#fff", + color: "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } return styleStorage[type + "s"][id]; - } + }; const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); - defaultElements.push(createInput( - "default-input", "text", - { defaultValue: Scratch.translate("...type your name") } - )); + defaultElements.push( + createLabel("default-label", Scratch.translate("Whats Your Name?")) + ); + defaultElements.push( + createInput("default-input", "text", { + defaultValue: Scratch.translate("...type your name"), + }) + ); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -383,7 +420,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements + elements: defaultElements, }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -394,7 +431,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - } + }; // popup box GUI const compileStyles = (id, type) => { @@ -403,7 +440,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + if (styleObj["height"] === "auto") styleObj["height"] = "30px"; } let styleString = ""; @@ -419,9 +456,13 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute( + "style", + "position: fixed; width: 100%; height: 100%;" + ); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) + popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -436,7 +477,8 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) + boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -444,7 +486,8 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) + handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -457,7 +500,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -465,7 +510,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } } }; @@ -484,21 +531,24 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, recentData.type, recentData.options + recentData.id, + recentData.type, + recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element) + popupPanel.appendChild(element); // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) + element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -514,7 +564,8 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) + runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -531,9 +582,10 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = + type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -541,15 +593,17 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + blockType: Scratch.BlockType.LABEL, + text: Scratch.translate(text), }; - }; + } function createMenuItem(text, value) { return { - text: Scratch.translate(text), value + text: Scratch.translate(text), + value, }; - }; + } genDefaultBox("default-popup", false); @@ -573,8 +627,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, }, }, { @@ -582,7 +639,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -590,7 +650,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -599,13 +662,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups") + text: Scratch.translate("remove all popups"), }, createBlockLabel("Popups"), { @@ -613,7 +679,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("new-popup"), + }, }, }, { @@ -621,28 +690,47 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + text: Scratch.translate( + "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + text: Scratch.translate( + "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -650,7 +738,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -659,9 +750,12 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER } + Y: { type: Scratch.ArgumentType.NUMBER }, }, }, { @@ -670,17 +764,28 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new label with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("whats your name?"), + }, }, }, { @@ -688,7 +793,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, }, }, createBlockLabel("Inputs"), @@ -698,7 +806,10 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, { @@ -706,17 +817,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set default value of input [ID] to [VALUE]"), + text: Scratch.translate( + "set default value of input [ID] to [VALUE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate(`...type here`), + }, }, }, "---", @@ -725,7 +847,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -736,17 +861,33 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + ARRAY: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate( + `["Option 1", "Option 2", "Option 3"]` + ), + }, }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + text: Scratch.translate( + "is dropdown [DROP_ID] in popup [POP_ID] open?" + ), arguments: { - DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + DROP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Buttons"), @@ -755,16 +896,27 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new button with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("Submit"), + }, }, }, { @@ -772,7 +924,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -780,7 +935,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, }, }, "---", @@ -789,8 +947,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -798,8 +962,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -807,7 +977,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, createBlockLabel("Operators"), @@ -816,7 +989,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, }, }, { @@ -824,7 +997,10 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -832,7 +1008,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -840,17 +1019,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("focus on input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + text: Scratch.translate( + "show next popup with ID [ID] on the [TYPE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "POPUP_LOCATION", + }, }, }, { @@ -859,17 +1049,25 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + text: Scratch.translate( + "set auto-close action in popup [ID] to [KEY] key" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, }, }, createBlockLabel("Customization"), @@ -879,8 +1077,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, { @@ -889,8 +1090,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, "---", @@ -901,31 +1105,44 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + text: Scratch.translate( + "set font size of [ELEMENT] [ID] to [SIZE]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -937,36 +1154,52 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "#ff0000", + }, }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + text: Scratch.translate( + "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -977,19 +1210,27 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + text: Scratch.translate( + "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" + ), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { @@ -1000,7 +1241,10 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, ], @@ -1010,48 +1254,66 @@ INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, - UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, - UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, - UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + UI_ELEMENTS: { + acceptReporters: true, + items: this.genElementList(false, true, false), + }, + UI_MAIN: { + acceptReporters: true, + items: this.genElementList(true, false, true), + }, + UI_MAIN2: { + acceptReporters: true, + items: this.genElementList(false, false, true), + }, + UI_SELECT: { + acceptReporters: true, + items: this.genElementList(true, true, true), + }, AWAITS: { acceptReporters: false, - items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + items: [ + createMenuItem("wait", "wait"), + createMenuItem("continue", "continue"), + ], }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + items: [createMenuItem("on", "on"), createMenuItem("off", "off")], }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + items: [createMenuItem("x", "x"), createMenuItem("y", "y")], }, POPUP_LOCATION: { acceptReporters: false, - items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + items: [ + createMenuItem("window", "window"), + createMenuItem("canvas", "canvas"), + ], }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center") - ] + createMenuItem("center", "center"), + ], }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter") - ] + createMenuItem("shift & enter", "shiftEnter"), + ], }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose") - ] + createMenuItem("auto close", "autoClose"), + ], }, }, }; @@ -1059,14 +1321,21 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; - return [ ...defaultFonts, ...custFonts ]; + const custFonts = runtime.fontManager + ? runtime.fontManager + .getFonts() + .map((i) => ({ text: i.name, value: i.family })) + : []; + return [...defaultFonts, ...custFonts]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + list.push( + createMenuItem("label", "label"), + createMenuItem("input", "input") + ); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1081,7 +1350,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius") + createMenuItem("border radius", "border-radius"), ]; } @@ -1101,9 +1370,12 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); - if (reportResponse) return typeof popup.value === "object" ? - JSON.stringify(popup.value) : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) + util.yield(); + if (reportResponse) + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } // Block Funcs @@ -1120,7 +1392,9 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } removePopup(args) { @@ -1159,7 +1433,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex === -1) popup.elements.push(element); } @@ -1171,7 +1445,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1193,7 +1467,8 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") + return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1256,7 +1531,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID + return e.type === "input" && e.data.id === dropID; }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1346,7 +1621,6 @@ } } - setPopupTarget(args) { const id = Cast.toString(args.ID); let popup = elementStorage.popups[id]; @@ -1360,9 +1634,8 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[ - option === "focus" ? "focused" : "autoControl" - ] = args.TYPE === "on"; + popup[option === "focus" ? "focused" : "autoControl"] = + args.TYPE === "on"; } setForceClose(args) { @@ -1385,7 +1658,7 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - let isLabel = false + let isLabel = false; let styles = styleStorage.inputs[id]; if (!styles) { styles = styleStorage.labels[id]; @@ -1426,9 +1699,12 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); + const isValidStyle = this.genStyleList().findIndex( + (i) => i.value === param + ); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1436,7 +1712,10 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + if (value.includes(" ")) + value = /^\d+$/.test(value.replaceAll(" ", "")) + ? value.replaceAll(" ", "px ") + : value; else value = `${value}px`; } } @@ -1448,10 +1727,13 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex( + (i) => i.value === args.TYPE + ); + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1460,16 +1742,22 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") + styles["text-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else + styles["box-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1481,7 +1769,8 @@ const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1494,10 +1783,10 @@ value += "px"; break; case "brightness": - value = `${100 - (value * -1)}%`; + value = `${100 - value * -1}%`; break; case "opacity": - value = 1 - (value / 100); + value = 1 - value / 100; break; case "saturate": case "sepia": @@ -1534,7 +1823,8 @@ if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From 06dca26dd48bcc13e60989c5e6c867fecc08ef18 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Thu, 14 May 2026 21:56:48 -0700 Subject: [PATCH 16/17] Better font grabbing --- extensions/SharkPool/Popup-Phoenix.js | 746 ++++++++------------------ 1 file changed, 228 insertions(+), 518 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index ff7b4ef2f1..1d152f2192 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,25 +8,18 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) - throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = - "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return ( - start + - { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: - "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: - "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", - }[name] - ); + const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return start + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" + }[name]; }; const Cast = Scratch.Cast; @@ -35,21 +28,16 @@ const render = vm.renderer; const keyUtil = runtime.ioDevices.keyboard; - const defaultFonts = [ - "Sans Serif", - "Serif", - "Handwriting", - "Marker", - "Curly", - "Pixel", - "Scratch", - ]; + const BUILT_IN_FONTS = [...new Set( + Array.from(document.fonts).map(f => f.family) + )].map((f) => ({ text: Scratch.translate(f), value: f })); + const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button"), + button: Scratch.translate("submit-button") }; const validInputs = [ @@ -62,7 +50,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert"), + createMenuItem("vertical slider", "rangeVert") ]; const validBorders = [ createMenuItem("none", "none"), @@ -73,7 +61,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset"), + createMenuItem("outset", "outset") ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -88,7 +76,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY"), + createMenuItem("skew y", "skewY") ]; // internals @@ -96,29 +84,24 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null), - }; + buttons: Object.create(null) + } const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { switch (c) { - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - case "'": - return "'"; - case '"': - return """; + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; } }); }; @@ -154,28 +137,18 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; - opt.text = option; + opt.value = option; opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { - options.menuOpened = true; - }); - element.addEventListener("blur", () => { - options.menuOpened = false; - }); - element.addEventListener("change", (e) => - setElementValue([e.target.value]) - ); + element.addEventListener("focus", () => { options.menuOpened = true }); + element.addEventListener("blur", () => { options.menuOpened = false }); + element.addEventListener("change", (e) => setElementValue([e.target.value])); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute( - "style", - "display: flex; padding: 5px; cursor: pointer" - ); + holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); const check = document.createElement("input"); check.type = "checkbox"; @@ -194,10 +167,7 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute( - "style", - "overflow-y: scroll; height: calc(100% - 1px);" - ); + optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); element.appendChild(optionsDiv); setElementValue(response); @@ -206,8 +176,7 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") - e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -251,10 +220,7 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute( - "style", - "display: flex; justify-content: center; width: 100%;" - ); + inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -283,7 +249,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder, + DOMelement: inputHolder }; }; @@ -295,7 +261,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow, + DOMelement: buttonRow }; }; @@ -309,7 +275,7 @@ return { type: "button", data: { id, text }, - DOMelement: element, + DOMelement: element }; }; @@ -318,20 +284,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - display: "flex", + "display": "flex", "flex-direction": "column", - position: "absolute", + "position": "absolute", "pointer-events": "auto", - transform: "translate(-50%, -50%)", - filter: "", - left: "calc(50% + 0px)", - top: "calc(50% + 0px)", - width: "max-content", - height: "auto", - padding: "15px", - background: "#fff", + "transform": "translate(-50%, -50%)", + "filter": "", + "left": "calc(50% + 0px)", + "top": "calc(50% + 0px)", + "width": "max-content", + "height": "auto", + "padding": "15px", + "background": "#fff", "box-shadow": "#000 0px 0px 5px", - border: "1px none #000", + "border": "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -339,69 +305,66 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - margin: "5px", - color: "#000", + "margin": "5px", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - width: "max-content", - height: "auto", - margin: "5px", - padding: "5px", - border: "1px solid #000", + "width": "max-content", + "height": "auto", + "margin": "5px", + "padding": "5px", + "border": "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - background: "#a5aec3", + "background": "#a5aec3", "accent-color": "#9f50d9", - color: "#000", + "color": "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - width: "auto", - height: "auto", - cursor: "pointer", - margin: "5px", - padding: "5px 10px", + "width": "auto", + "height": "auto", + "cursor": "pointer", + "margin": "5px", + "padding": "5px 10px", "border-radius": "5px", - border: "1px none #fff", - background: "#0074d9", + "border": "1px none #fff", + "background": "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - color: "#fff", + "color": "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - transform: "", - filter: "", + "transform": "", + "filter": "" }; } return styleStorage[type + "s"][id]; - }; + } const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push( - createLabel("default-label", Scratch.translate("Whats Your Name?")) - ); - defaultElements.push( - createInput("default-input", "text", { - defaultValue: Scratch.translate("...type your name"), - }) - ); + defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); + defaultElements.push(createInput( + "default-input", "text", + { defaultValue: Scratch.translate("...type your name") } + )); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -420,7 +383,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements, + elements: defaultElements }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -431,7 +394,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - }; + } // popup box GUI const compileStyles = (id, type) => { @@ -440,7 +403,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto") styleObj["height"] = "30px"; + if (styleObj["height"] === "auto")styleObj["height"] = "30px"; } let styleString = ""; @@ -456,13 +419,9 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute( - "style", - "position: fixed; width: 100%; height: 100%;" - ); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) - popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -477,8 +436,7 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) - boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -486,8 +444,7 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) - handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -500,9 +457,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -510,9 +465,7 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue - ? JSON.parse(returnValue) - : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; } } }; @@ -531,24 +484,21 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, - recentData.type, - recentData.options + recentData.id, recentData.type, recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element); + popupPanel.appendChild(element) // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) - element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -564,8 +514,7 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) - runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -582,10 +531,9 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = - type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -593,17 +541,15 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, - text: Scratch.translate(text), + blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) }; - } + }; function createMenuItem(text, value) { return { - text: Scratch.translate(text), - value, + text: Scratch.translate(text), value }; - } + }; genDefaultBox("default-popup", false); @@ -627,11 +573,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } }, }, { @@ -639,10 +582,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -650,10 +590,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -662,16 +599,13 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups"), + text: Scratch.translate("remove all popups") }, createBlockLabel("Popups"), { @@ -679,10 +613,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("new-popup"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } }, }, { @@ -690,47 +621,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" - ), + text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" - ), + text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -738,10 +650,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, "---", @@ -750,12 +659,9 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER }, + Y: { type: Scratch.ArgumentType.NUMBER } }, }, { @@ -764,28 +670,17 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new label with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("whats your name?"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } }, }, { @@ -793,10 +688,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } }, }, createBlockLabel("Inputs"), @@ -806,10 +698,7 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, { @@ -817,28 +706,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set default value of input [ID] to [VALUE]" - ), + text: Scratch.translate("set default value of input [ID] to [VALUE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate(`...type here`), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } }, }, "---", @@ -847,10 +725,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -861,33 +736,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - ARRAY: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate( - `["Option 1", "Option 2", "Option 3"]` - ), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate( - "is dropdown [DROP_ID] in popup [POP_ID] open?" - ), + text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), arguments: { - DROP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - POP_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, createBlockLabel("Buttons"), @@ -896,27 +755,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "create new button with ID [ID] and text [TEXT]" - ), + text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - TEXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: Scratch.translate("Submit"), - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } }, }, { @@ -924,10 +772,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -935,10 +780,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } }, }, "---", @@ -947,14 +789,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -962,14 +798,8 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.button, - }, - ROW_ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, + ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, { @@ -977,10 +807,7 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.btnRow, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } }, }, createBlockLabel("Operators"), @@ -989,7 +816,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } }, }, { @@ -997,10 +824,7 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -1008,10 +832,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { @@ -1019,28 +840,17 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("focus on input with ID [ID]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "show next popup with ID [ID] on the [TYPE]" - ), + text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { - type: Scratch.ArgumentType.STRING, - menu: "POPUP_LOCATION", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } }, }, { @@ -1049,25 +859,17 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate( - "set auto-close action in popup [ID] to [KEY] key" - ), + text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } }, }, createBlockLabel("Customization"), @@ -1077,11 +879,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, { @@ -1090,11 +889,8 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.input, - }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } }, }, "---", @@ -1105,44 +901,31 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set font size of [ELEMENT] [ID] to [SIZE]" - ), + text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.label, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1154,52 +937,36 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { - type: Scratch.ArgumentType.STRING, - defaultValue: "#ff0000", - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" - ), + text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate( - "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" - ), + text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, "---", @@ -1210,27 +977,19 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate( - "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" - ), + text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } }, }, { @@ -1241,10 +1000,7 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { - type: Scratch.ArgumentType.STRING, - defaultValue: translatedInputs.popup, - }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } }, }, ], @@ -1254,66 +1010,48 @@ INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { - acceptReporters: true, - items: this.genElementList(false, true, false), - }, - UI_MAIN: { - acceptReporters: true, - items: this.genElementList(true, false, true), - }, - UI_MAIN2: { - acceptReporters: true, - items: this.genElementList(false, false, true), - }, - UI_SELECT: { - acceptReporters: true, - items: this.genElementList(true, true, true), - }, + UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, + UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, + UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, + UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, AWAITS: { acceptReporters: false, - items: [ - createMenuItem("wait", "wait"), - createMenuItem("continue", "continue"), - ], + items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")], + items: [createMenuItem("on", "on"), createMenuItem("off", "off")] }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")], + items: [createMenuItem("x", "x"), createMenuItem("y", "y")] }, POPUP_LOCATION: { acceptReporters: false, - items: [ - createMenuItem("window", "window"), - createMenuItem("canvas", "canvas"), - ], + items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center"), - ], + createMenuItem("center", "center") + ] }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter"), - ], + createMenuItem("shift & enter", "shiftEnter") + ] }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose"), - ], + createMenuItem("auto close", "autoClose") + ] }, }, }; @@ -1321,21 +1059,14 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager - ? runtime.fontManager - .getFonts() - .map((i) => ({ text: i.name, value: i.family })) - : []; - return [...defaultFonts, ...custFonts]; + const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [ ...BUILT_IN_FONTS, ...custFonts ]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push( - createMenuItem("label", "label"), - createMenuItem("input", "input") - ); + list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1350,7 +1081,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius"), + createMenuItem("border radius", "border-radius") ]; } @@ -1370,12 +1101,9 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) - util.yield(); - if (reportResponse) - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); + if (reportResponse) return typeof popup.value === "object" ? + JSON.stringify(popup.value) : popup.value || ""; } // Block Funcs @@ -1392,9 +1120,7 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" - ? JSON.stringify(popup.value) - : popup.value || ""; + return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; } removePopup(args) { @@ -1433,7 +1159,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex === -1) popup.elements.push(element); } @@ -1445,7 +1171,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID; + return i.type === path && i.data.id === elementID }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1467,8 +1193,7 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") - return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1531,7 +1256,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID; + return e.type === "input" && e.data.id === dropID }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1621,6 +1346,7 @@ } } + setPopupTarget(args) { const id = Cast.toString(args.ID); let popup = elementStorage.popups[id]; @@ -1634,8 +1360,9 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[option === "focus" ? "focused" : "autoControl"] = - args.TYPE === "on"; + popup[ + option === "focus" ? "focused" : "autoControl" + ] = args.TYPE === "on"; } setForceClose(args) { @@ -1658,7 +1385,7 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - let isLabel = false; + let isLabel = false let styles = styleStorage.inputs[id]; if (!styles) { styles = styleStorage.labels[id]; @@ -1699,12 +1426,9 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex( - (i) => i.value === param - ); + const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1712,10 +1436,7 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) - value = /^\d+$/.test(value.replaceAll(" ", "")) - ? value.replaceAll(" ", "px ") - : value; + if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; else value = `${value}px`; } } @@ -1727,13 +1448,10 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex( - (i) => i.value === args.TYPE - ); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1742,22 +1460,16 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") - styles["text-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else - styles["box-shadow"] = - `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1769,8 +1481,7 @@ const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1783,10 +1494,10 @@ value += "px"; break; case "brightness": - value = `${100 - value * -1}%`; + value = `${100 - (value * -1)}%`; break; case "opacity": - value = 1 - value / 100; + value = 1 - (value / 100); break; case "saturate": case "sepia": @@ -1823,8 +1534,7 @@ if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = - this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; } From 1ec446439309c6525695bf9b1455dd8084e1339d Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Fri, 15 May 2026 04:59:27 +0000 Subject: [PATCH 17/17] [Automated] Format code --- extensions/SharkPool/Popup-Phoenix.js | 741 ++++++++++++++++++-------- 1 file changed, 513 insertions(+), 228 deletions(-) diff --git a/extensions/SharkPool/Popup-Phoenix.js b/extensions/SharkPool/Popup-Phoenix.js index 1d152f2192..6b53f5c52b 100644 --- a/extensions/SharkPool/Popup-Phoenix.js +++ b/extensions/SharkPool/Popup-Phoenix.js @@ -8,18 +8,25 @@ (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Popup Phoenix must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) + throw new Error("Popup Phoenix must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4Ny41MzIiIGhlaWdodD0iODcuNTMyIiB2aWV3Qm94PSIwIDAgODcuNTMyIDg3LjUzMiI+PGcgc3Ryb2tlLXdpZHRoPSIwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0uMDAxIDQzLjc2N0MuMDAxIDE5LjU5NSAxOS41OTQuMDAxIDQzLjc2Ni4wMDFzNDMuNzY2IDE5LjU5NCA0My43NjYgNDMuNzY2LTE5LjU5NCA0My43NjYtNDMuNzY2IDQzLjc2NlMwIDY3LjkzOSAwIDQzLjc2NyIgZmlsbD0iIzgyMTliZiIvPjxwYXRoIGQ9Ik01LjE2NSA0My43NjdjMC0yMS4zMiAxNy4yODItMzguNjAyIDM4LjYwMi0zOC42MDJzMzguNjAyIDE3LjI4MiAzOC42MDIgMzguNjAyLTE3LjI4MiAzOC42MDItMzguNjAyIDM4LjYwMlM1LjE2NSA2NS4wODcgNS4xNjUgNDMuNzY3IiBmaWxsPSIjYTgxMmZmIi8+PHBhdGggZD0ibTQwLjM5NyA1OC4wODctMy44NS42MDctLjE4MSA0Ljg3LTMuMTYgMS44MjUtMS40NDQtNi4yMS00LjEzOS0yLjU1NiAxLjkwNC0zLjMzNCA0LjQ3NiAyLjAwOCA0LjQ3NS0xLjQ0MS0zLjM4NC00LjUyNi0yLjY4OSAyLjAwMS00LjkyNy0uODc0IDIuNDY1LTMuNTktOC40NjUgMi4yOTItMi41NTYtNC4wNDUgOC4wNi0xLjgyOC0xMC4wNjgtLjc2My0xLjg0Ni01LjQ1MSAxMC4yOTEgMS4yMjctMTAuMzYtMy45OC45Ny02Ljc3OCA5LjQ4MyA1LjkzNC04LjA3NS05Ljc0NSAzLjI5Ni01LjM1NiAxMi40MjYgMTQuODA4LS4zNzQgNy41OCA1LjMzOSAxLjAyMSA1LjM2NS0xMS4xOTggOC4wMDMgMS41ODQtLjI5IDQuMzk3LTIuODk5LTEuMDM1LS4yMzMgMy43MSAxLjgzNSAyLjU0MiA0Ljc1Ny0xLjEtLjE2Mi02LjY5NCA3LjAyMy03LjY2OCA1LjI5Ny03LjQwOCAzLjI3MiAzLjkzNS03LjgxMSAxMS4yNDcgOS4xNzUtNy4wNi4xODggNy40MzMtOS40MDEgNC4yNTEgMTAuMzUtMS41My0xLjYyMSA2LjAzLTEwLjEzMy4xNDkgOS4xMTUgMS41Ni0zLjkwNyA0Ljc0OC04LjktMi45MTYgMi4zNDggMy4zODctNC43MDMgMS41Mi0yLjI4LTIuMjIzLTMuNjc5IDQuOTU0IDQuMTQ3LjcwMiA1LjEwNy0yLjMgMS41NjUgMy44NC00LjMyMyAyLS45NzEgNi41MzgtMy41ODgtMS4xMzMuMDM5LTUuMDY1LTMuOTM3LS42MzMuNDMgMi43MDMgNC4zIDYuNTI4LTIuODMyIDMuMzQtMi45NzMtMy4wMjMuNzUgNS4zNy0zLjE5NyAyLjg5NC0yLjk0LTIuOTYuNTI2LTUuMjk3LTIuNzggMy4xNTUtMi41NjQtMy42NCA0LjM2OS02LjU2NHoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+"; const getBlockIcon = (name) => { // lower file size moment - const start = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; - return start + { - main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", - color: "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", - effect: "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+" - }[name]; + const start = + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI"; + return ( + start + + { + main: "3OS4xOTkiIGhlaWdodD0iODcuOTIyIiB2aWV3Qm94PSIwIDAgNzkuMTk5IDg3LjkyMiI+PHBhdGggZD0ibTI1LjkwMSA2NS41MDctNS4yNTUtLjA4Yy0xMS4wMy0uMDgtMTEuNzA3LS4wOC0xMi44ODktLjU5OC0uMzctLjE1Mi0yLjc1OC0yLjQyOS0yLjc1OC0yLjQyOVYyNS40NzdzMi4wODMtMi4xNSAyLjc1OC0yLjQzYzEuMTI2LS40NzggMS44NTgtLjUxOCAxMi44OS0uNTk3bDUuMjUzLS4wOHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxMCIgb3BhY2l0eT0iLjI1Ii8+PHBhdGggZD0iTTMwLjQ2OSA2NS41MDdzLTIxLjUzLS4xNi0yMi43MS0uNjc3Yy0uNjc3LS4yOC0yLjc2LTIuNDMtMi43Ni0yLjQzVjI1LjQ3OHMyLjA4My0yLjE1MSAyLjc1OC0yLjQzYzEuMTI3LS40NzggMjIuNzEyLS42NzcgMjIuNzEyLS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTUzLjYyOCAyMi4zNyA0LjkyMy4wOGMxMS4wMzEuMDggMTEuNzYzLjEyIDEyLjg5LjU5OC42NzQuMjc5IDIuNzU3IDIuNDMgMi43NTcgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0xLjg1OC41MTgtMTIuODg5LjU5OGwtNC45MjMuMDh6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Ik00OC44OTUgMjIuMzdzMjEuNTg1LjIgMjIuNzEuNjc4Yy42NzYuMjc5IDIuNzU5IDIuNDMgMi43NTkgMi40M3YzNi45MjNzLTIuMDgzIDIuMTUtMi43NTggMi40MjljLTEuMTgyLjUxOC0yMi43MTEuNjc3LTIyLjcxMS42Nzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0ibTI5LjI3OCA1LjAwNSAxMC44MzIuMDRjMTAuNTE2LjA4IDEwLjgzNC4xMiAxMS41MTEuNTk2IDIuNDMgMS44NzIgMi4zOSA0Ljk0LS4xNTkgNi42NTItLjc1Ny41MTgtMS4xMTUuNTU3LTQuMzQuNTU3aC0zLjUwNnY2Mi4xNzZoMy40NjVjMy45NDMgMCA0LjkuMzE4IDUuODE1IDEuOTUxIDEuMDM2IDEuODMzLjUxOCAzLjk0NC0xLjI3NSA1LjI1OC0uNjc3LjUxOC0uOTk1LjUxOC0xMS41MS41OThsLTEwLjgzNC4wOC0xLjExNi0uNTU4Yy0xLjE1NS0uNjM4LTIuMTktMi4xNS0yLjE5LTMuMzg2IDAtLjg3NS45OTUtMi42NjggMS43OTItMy4yNjUuNTk3LS40NzggMS4xMTUtLjUxOCA0LjM0Mi0uNTk4bDMuNjY0LS4wOFYxMi44OWwtMy42NjQtLjA4Yy0zLjIyNy0uMDgtMy43NDUtLjExOS00LjM0Mi0uNTk3LS43OTctLjU1OC0xLjc5Mi0yLjM1LTEuNzkyLTMuMjY2IDAtMS4yMzUuOTk1LTIuNzg4IDIuMTktMy4zODZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMTAiIG9wYWNpdHk9Ii4yNSIvPjxwYXRoIGQ9Im0yOS4yNzggNS4wMDUgMTAuODMyLjA0YzEwLjUxNi4wOCAxMC44MzQuMTIgMTEuNTExLjU5NiAyLjQzIDEuODcyIDIuMzkgNC45NC0uMTU5IDYuNjUyLS43NTcuNTE4LTEuMTE1LjU1Ny00LjM0LjU1N2gtMy41MDZ2NjIuMTc2aDMuNDY1YzMuOTQzIDAgNC45LjMxOCA1LjgxNSAxLjk1MSAxLjAzNiAxLjgzMy41MTggMy45NDQtMS4yNzUgNS4yNTgtLjY3Ny41MTgtLjk5NS41MTgtMTEuNTEuNTk4bC0xMC44MzQuMDgtMS4xMTYtLjU1OGMtMS4xNTUtLjYzOC0yLjE5LTIuMTUtMi4xOS0zLjM4NiAwLS44NzUuOTk1LTIuNjY4IDEuNzkyLTMuMjY1LjU5Ny0uNDc4IDEuMTE1LS41MTggNC4zNDItLjU5OGwzLjY2NC0uMDhWMTIuODlsLTMuNjY0LS4wOGMtMy4yMjctLjA4LTMuNzQ1LS4xMTktNC4zNDItLjU5Ny0uNzk3LS41NTgtMS43OTItMi4zNS0xLjc5Mi0zLjI2NiAwLTEuMjM1Ljk5NS0yLjc4OCAyLjE5LTMuMzg2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==", + color: + "3NS41MzUiIGhlaWdodD0iNzEuNDk3IiB2aWV3Qm94PSIwIDAgNzUuNTM1IDcxLjQ5NyI+PHBhdGggZD0iTTIxLjMwNyAyMS40NjJDMjEuMzA3IDEyLjM3IDI4LjY3NyA1IDM3Ljc2OCA1czE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjItNy4zNyAxNi40NjEtMTYuNDYxIDE2LjQ2MS0xNi40NjEtNy4zNy0xNi40NjEtMTYuNDYxeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBkPSJNNSA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjItMTYuNDYxczE2LjQ2MSA3LjM3IDE2LjQ2MSAxNi40NjFjMCA5LjA5Mi03LjM3IDE2LjQ2Mi0xNi40NjEgMTYuNDYyQzEyLjM3IDY2LjQ5OCA1IDU5LjEyOCA1IDUwLjAzNnoiIHN0cm9rZT0iIzAwMCIgb3BhY2l0eT0iLjI1IiBzdHJva2Utd2lkdGg9IjEwIi8+PHBhdGggZD0iTTM3LjYxMyA1MC4wMzZjMC05LjA5MSA3LjM3LTE2LjQ2MSAxNi40NjEtMTYuNDYxIDkuMDkyIDAgMTYuNDYyIDcuMzcgMTYuNDYyIDE2LjQ2MSAwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MiAxNi40NjJzLTE2LjQ2MS03LjM3LTE2LjQ2MS0xNi40NjJ6IiBzdHJva2U9IiMwMDAiIG9wYWNpdHk9Ii4yNSIgc3Ryb2tlLXdpZHRoPSIxMCIvPjxwYXRoIGQ9Ik0yMS4zMDcgMjEuNDYyQzIxLjMwNyAxMi4zNyAyOC42NzcgNSAzNy43NjggNXMxNi40NjEgNy4zNyAxNi40NjEgMTYuNDYyLTcuMzcgMTYuNDYxLTE2LjQ2MSAxNi40NjEtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MSIgZmlsbD0iIzBmMCIvPjxwYXRoIGQ9Ik01IDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2Mi0xNi40NjFzMTYuNDYxIDcuMzcgMTYuNDYxIDE2LjQ2MWMwIDkuMDkyLTcuMzcgMTYuNDYyLTE2LjQ2MSAxNi40NjJDMTIuMzcgNjYuNDk4IDUgNTkuMTI4IDUgNTAuMDM2IiBmaWxsPSJyZWQiLz48cGF0aCBkPSJNMzcuNjEzIDUwLjAzNmMwLTkuMDkxIDcuMzctMTYuNDYxIDE2LjQ2MS0xNi40NjEgOS4wOTIgMCAxNi40NjIgNy4zNyAxNi40NjIgMTYuNDYxIDAgOS4wOTItNy4zNyAxNi40NjItMTYuNDYyIDE2LjQ2MnMtMTYuNDYxLTcuMzctMTYuNDYxLTE2LjQ2MiIgZmlsbD0iIzAwZiIvPjwvc3ZnPg==", + effect: + "1Ny40NDIiIGhlaWdodD0iNzAuNDUiIHZpZXdCb3g9IjAgMCA1Ny40NDIgNzAuNDUiPjxwYXRoIGQ9Ik01IDQ5LjA0N2MtMy45ODgtOC4xMTctMy45OTYtMTguMjQzLjE1My0yNi40MUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1IDAgMC0uODIxLTEuNDE4LTEuMTgzLTIuMTUzeiIgc3Ryb2tlPSIjMDAwIiBvcGFjaXR5PSIuMjUiIHN0cm9rZS13aWR0aD0iMTAiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNNi4xODIgNTEuMjAxYy01LjEzNC04LjQyLTUuNTUzLTE5LjY1Ny0xLjAzLTI4LjU2NUM5Ljg0IDEzLjA2MiAxNy43MyA4LjgxOCAyMC45IDcuNDM4YTMxLjQgMzEuNCAwIDAgMSA2LjA3Ni0yLjA4M2wyLjEyLS40NTdjMS41NTgtLjMyIDMuMTEuNjQ2IDMuNDQ3IDIuMTg3LjM0IDEuNTQ1LS42NTEgMy4wNjYtMi4yMTYgMy40MDJsLTIuMDYzLjQ0NWEyNS40IDI1LjQgMCAwIDAtNC45NiAxLjcxNmMtMi4wODMuOTAyLTguOTc0IDQuMzkyLTEyLjk0OSAxMi41MTUtMy4wMTcgNS45MzMtMy45MTcgMTUuMzY2LjgzMiAyMy4xNSA0LjMwMyA3LjQ5OCAxMy4xMTIgMTIuMDk1IDIxLjQ2OCAxMS4zMjEgNy45MDMtLjU2OCAxNS4xNTUtNS44MjggMTcuNjk4LTEyLjc5NSAyLjU4MS02LjU1Mi44NjYtMTMuMjY5LTEuOTY3LTE3LjA1Mi0zLjQxMy00LjY2LTcuNjYtNi4wOTQtOS4zMjgtNi40OTUtLjI0OS0uMDc0LTYuMDg1LTEuODI3LTExLjI0Ljc1NC0yLjIyIDEuMDY0LTUuMDkgMy40NTYtNi42MjggNy4wNS0xLjY2IDMuNzEyLTEuMjMgOC40ODQgMS4wMiAxMS42NTUgMi4yNjMgMy4zOTkgNi41MzIgNS4zMjMgMTAuMjAzIDQuNjcgMy42NTUtLjU3NSA2LjEyNy0zLjI5NCA2LjcxMy01LjY4My42ODktMi41NjgtLjM2OC00LjczOS0xLjE5My01LjUyLTEuNDAxLTEuMzgzLTIuNjExLTEuNDA2LTIuNjYzLTEuNDFhNSA1IDAgMCAwLTEuMDI2LjA1NGMtLjY1NC4yNC0xLjU4Mi43NjQtMS44NTQgMS4zMTYtLjA0OC4wOS0uMTcuMzQuMDY0Ljk2My41NjMgMS40NzctLjE5NyAzLjEzLTEuNjk0IDMuNjg1LTEuNDkuNTU4LTMuMTY3LS4xOTItMy43MzMtMS42NzMtLjkzMS0yLjQ1LS40MTYtNC4zNjguMTgtNS41NDYgMS41NTgtMy4wNjYgNS4xNzYtNC4xNzYgNS41ODUtNC4yOTQuMTg3LS4wNTcuMzg1LS4wOTEuNTgtLjEwOC4zOTgtLjA2IDEuMS0uMTU1IDIuMDUyLS4xMTggMi4xNzguMDI3IDQuNjYgMS4xNjUgNi41NjMgMy4wNDYgMi4yNDYgMi4xMiA0LjAwNiA2LjM4IDIuNzU4IDExLjAxMS0xLjIxNyA0Ljk1Ny01Ljg5NSA5LjA1Ni0xMS4zNTMgOS45MTQtNS44NyAxLjA0Ny0xMi40ODItMS44NDctMTUuOTczLTcuMDk0LTMuMzY1LTQuNzI4LTQuMDA5LTExLjY0Ny0xLjU0OC0xNy4xMzYgMi43LTYuMzIgNy44NTktOS4xOCA5LjM3My05LjkwNyA3LjI3OS0zLjYzNSAxNS4wNTktMS4yMzUgMTUuMzg2LTEuMTM0IDIuMDkzLjQ5NCA3LjkxMyAyLjQ0MyAxMi40MzcgOC42MjUgMy40NzcgNC42NSA2LjI5NyAxMy4zMzcgMi43MTQgMjIuNDMtMy4yNzMgOC45NjItMTIuNTkgMTUuNzctMjIuNjM4IDE2LjQ5My0uNzg4LjA3NC0xLjU4NS4xMTUtMi4zOC4xMTUtOS43NSAwLTE5LjYyNy01LjYyLTI0LjU4LTE0LjI1Ii8+PC9zdmc+", + }[name] + ); }; const Cast = Scratch.Cast; @@ -28,16 +35,16 @@ const render = vm.renderer; const keyUtil = runtime.ioDevices.keyboard; - const BUILT_IN_FONTS = [...new Set( - Array.from(document.fonts).map(f => f.family) - )].map((f) => ({ text: Scratch.translate(f), value: f })); - + const BUILT_IN_FONTS = [ + ...new Set(Array.from(document.fonts).map((f) => f.family)), + ].map((f) => ({ text: Scratch.translate(f), value: f })); + const translatedInputs = { popup: Scratch.translate("default-popup"), label: Scratch.translate("new-label"), input: Scratch.translate("new-input"), btnRow: Scratch.translate("default-button-row"), - button: Scratch.translate("submit-button") + button: Scratch.translate("submit-button"), }; const validInputs = [ @@ -50,7 +57,7 @@ createMenuItem("dropdown", "select"), createMenuItem("multi-select dropdown", "multiSelect"), createMenuItem("horizontal slider", "rangeHorz"), - createMenuItem("vertical slider", "rangeVert") + createMenuItem("vertical slider", "rangeVert"), ]; const validBorders = [ createMenuItem("none", "none"), @@ -61,7 +68,7 @@ createMenuItem("groove", "groove"), createMenuItem("ridge", "ridge"), createMenuItem("inset", "inset"), - createMenuItem("outset", "outset") + createMenuItem("outset", "outset"), ]; const validEffects = [ createMenuItem("blur", "blur"), @@ -76,7 +83,7 @@ createMenuItem("scale x", "scaleX"), createMenuItem("scale y", "scaleY"), createMenuItem("skew x", "skewX"), - createMenuItem("skew y", "skewY") + createMenuItem("skew y", "skewY"), ]; // internals @@ -84,24 +91,29 @@ popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const elementStorage = { popups: Object.create(null), labels: Object.create(null), inputs: Object.create(null), buttonRows: Object.create(null), - buttons: Object.create(null) - } + buttons: Object.create(null), + }; const xmlEscape = function (unsafe) { - return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), c => { + return Cast.toString(unsafe).replace(new RegExp(`[<>&'"]`, "g"), (c) => { switch (c) { - case "<": return "<"; - case ">": return ">"; - case "&": return "&"; - case "'": return "'"; - case "\"": return """; + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; } }); }; @@ -137,18 +149,28 @@ element = document.createElement("select"); selectors.forEach((option) => { let opt = document.createElement("option"); - opt.value = option; opt.text = option; + opt.value = option; + opt.text = option; element.appendChild(opt); }); - element.addEventListener("focus", () => { options.menuOpened = true }); - element.addEventListener("blur", () => { options.menuOpened = false }); - element.addEventListener("change", (e) => setElementValue([e.target.value])); + element.addEventListener("focus", () => { + options.menuOpened = true; + }); + element.addEventListener("blur", () => { + options.menuOpened = false; + }); + element.addEventListener("change", (e) => + setElementValue([e.target.value]) + ); setElementValue([selectors[0]]); } else if (type === "multiSelect") { const createOption = (text, index) => { const holder = document.createElement("div"); - holder.setAttribute("style", "display: flex; padding: 5px; cursor: pointer"); + holder.setAttribute( + "style", + "display: flex; padding: 5px; cursor: pointer" + ); const check = document.createElement("input"); check.type = "checkbox"; @@ -167,7 +189,10 @@ element = document.createElement("div"); const optionsDiv = document.createElement("div"); - optionsDiv.setAttribute("style", "overflow-y: scroll; height: calc(100% - 1px);"); + optionsDiv.setAttribute( + "style", + "overflow-y: scroll; height: calc(100% - 1px);" + ); element.appendChild(optionsDiv); setElementValue(response); @@ -176,7 +201,8 @@ optionsDiv.appendChild(option); option.addEventListener("click", (e) => { - if (e.target.tagName === "PRE") e.target.parentNode.querySelector("input").click(); + if (e.target.tagName === "PRE") + e.target.parentNode.querySelector("input").click(); else if (e.target.tagName === "INPUT") { if (e.target.checked) response.push(selectors[i]); else response.splice(response.indexOf(selectors[i]), 1); @@ -220,7 +246,10 @@ element.setAttribute("autocomplete", "off"); element.setAttribute("name", `SPpopupPheonixPass-${Math.random()}`); } else if (type === "color") { - inputHolder.setAttribute("style", "display: flex; justify-content: center; width: 100%;"); + inputHolder.setAttribute( + "style", + "display: flex; justify-content: center; width: 100%;" + ); const colorStyle = document.createElement("style"); colorStyle.textContent = ` input[type="color"] { @@ -249,7 +278,7 @@ return { type: "input", data: { id, type, options }, - DOMelement: inputHolder + DOMelement: inputHolder, }; }; @@ -261,7 +290,7 @@ return { type: "buttonRow", data: { id, buttons: [] }, - DOMelement: buttonRow + DOMelement: buttonRow, }; }; @@ -275,7 +304,7 @@ return { type: "button", data: { id, text }, - DOMelement: element + DOMelement: element, }; }; @@ -284,20 +313,20 @@ if (type === "popup") { styleStorage.popups[id] = { SPstorage: {}, - "display": "flex", + display: "flex", "flex-direction": "column", - "position": "absolute", + position: "absolute", "pointer-events": "auto", - "transform": "translate(-50%, -50%)", - "filter": "", - "left": "calc(50% + 0px)", - "top": "calc(50% + 0px)", - "width": "max-content", - "height": "auto", - "padding": "15px", - "background": "#fff", + transform: "translate(-50%, -50%)", + filter: "", + left: "calc(50% + 0px)", + top: "calc(50% + 0px)", + width: "max-content", + height: "auto", + padding: "15px", + background: "#fff", "box-shadow": "#000 0px 0px 5px", - "border": "1px none #000", + border: "1px none #000", "border-radius": "5px", }; } else if (type === "label") { @@ -305,66 +334,69 @@ SPstorage: {}, "font-size": "14px", "font-family": "Sans Serif", - "margin": "5px", - "color": "#000", + margin: "5px", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "input") { styleStorage.inputs[id] = { SPstorage: {}, - "width": "max-content", - "height": "auto", - "margin": "5px", - "padding": "5px", - "border": "1px solid #000", + width: "max-content", + height: "auto", + margin: "5px", + padding: "5px", + border: "1px solid #000", "border-radius": "4px", "text-align": "left", "font-size": "14px", "font-family": "Sans Serif", - "background": "#a5aec3", + background: "#a5aec3", "accent-color": "#9f50d9", - "color": "#000", + color: "#000", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } else if (type === "button") { styleStorage.buttons[id] = { SPstorage: {}, - "width": "auto", - "height": "auto", - "cursor": "pointer", - "margin": "5px", - "padding": "5px 10px", + width: "auto", + height: "auto", + cursor: "pointer", + margin: "5px", + padding: "5px 10px", "border-radius": "5px", - "border": "1px none #fff", - "background": "#0074d9", + border: "1px none #fff", + background: "#0074d9", "font-size": "14px", "font-family": "Sans Serif", - "color": "#fff", + color: "#fff", "text-shadow": "none", "-webkit-text-stroke-width": "0px", - "transform": "", - "filter": "" + transform: "", + filter: "", }; } return styleStorage[type + "s"][id]; - } + }; const genDefaultBox = (id, optEmptyElements) => { genDefaultStyles(id, "popup"); const defaultElements = []; let submitBtn, cancelBtn; if (!optEmptyElements) { - defaultElements.push(createLabel("default-label", Scratch.translate("Whats Your Name?"))); - defaultElements.push(createInput( - "default-input", "text", - { defaultValue: Scratch.translate("...type your name") } - )); + defaultElements.push( + createLabel("default-label", Scratch.translate("Whats Your Name?")) + ); + defaultElements.push( + createInput("default-input", "text", { + defaultValue: Scratch.translate("...type your name"), + }) + ); const buttonRow = createButtonRow("default-button-row"); submitBtn = createButton("submit-button", Scratch.translate("Submit")); @@ -383,7 +415,7 @@ lastBtnPressed: undefined, value: undefined, DOMelement: undefined, - elements: defaultElements + elements: defaultElements, }; if (!optEmptyElements) { elementStorage.labels["default-label"] = defaultElements[0]; @@ -394,7 +426,7 @@ } elementStorage.popups[id] = defaultBox; return defaultBox; - } + }; // popup box GUI const compileStyles = (id, type) => { @@ -403,7 +435,7 @@ if (type === "input" && boxInfo?.data.type === "color") { // color inputs with these options look weird if (styleObj["width"] === "max-content") styleObj["width"] = "80%"; - if (styleObj["height"] === "auto")styleObj["height"] = "30px"; + if (styleObj["height"] === "auto") styleObj["height"] = "30px"; } let styleString = ""; @@ -419,9 +451,13 @@ let boxInputs = []; const popupContainer = document.createElement("div"); - popupContainer.setAttribute("style", "position: fixed; width: 100%; height: 100%;"); - popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; - if (boxInfo.focused) popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; + popupContainer.setAttribute( + "style", + "position: fixed; width: 100%; height: 100%;" + ); + popupContainer.style.pointerEvents = boxInfo.focused ? "auto" : "none"; + if (boxInfo.focused) + popupContainer.style.backgroundColor = "rgba(0,0,0,0.5)"; if (boxInfo.isWindowed) popupContainer.style.zIndex = "9999"; else { popupContainer.style.left = "-50%"; @@ -436,7 +472,8 @@ // various element utils const handleClose = (event) => { // if theres no input, set the value to the button name - if (event) boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); + if (event) + boxInfo.lastBtnPressed = event.target.getAttribute("returnValue"); if (boxInputs.length === 0) boxInfo.value = boxInfo.lastBtnPressed ?? ""; else compileInputValues(); runtime.off("KEY_PRESSED", forceKeyHandler); @@ -444,7 +481,8 @@ }; const forceKeyHandler = (key) => { if (boxInfo.forceKey === "shiftEnter") { - if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) handleClose(); + if (key === "enter" && runtime.ioDevices.keyboard.getKeyIsDown("shift")) + handleClose(); return; } if (key.toLowerCase() == boxInfo.forceKey.toLowerCase()) handleClose(); @@ -457,7 +495,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } else { boxInfo.value = Object.create(null); for (let i = 0; i < boxInputs.length; i++) { @@ -465,7 +505,9 @@ const element = input.DOMelement; const returnValue = element.getAttribute("returnValue"); - boxInfo.value[input.data.id] = returnValue ? JSON.parse(returnValue) : element.firstChild.value; + boxInfo.value[input.data.id] = returnValue + ? JSON.parse(returnValue) + : element.firstChild.value; } } }; @@ -484,21 +526,24 @@ if (!refreshedInput) continue; const recentData = refreshedInput.data; element = createInput( - recentData.id, recentData.type, recentData.options + recentData.id, + recentData.type, + recentData.options ).DOMelement; item.DOMelement = element; } - popupPanel.appendChild(element) + popupPanel.appendChild(element); // add event listeners if (item.type === "input") { element.addEventListener("change", compileInputValues); - if (boxInfo.forceKey !== undefined) element.addEventListener("keydown", (e) => { - if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { - handleClose(); - e.preventDefault(); - } - }); + if (boxInfo.forceKey !== undefined) + element.addEventListener("keydown", (e) => { + if (boxInfo.forceKey === keyUtil._keyStringToScratchKey(e.key)) { + handleClose(); + e.preventDefault(); + } + }); } else if (item.type === "buttonRow") { element.addEventListener("click", (e) => { if (e.target.tagName === "BUTTON") handleClose(e); @@ -514,7 +559,8 @@ boxInfo.DOMelement = popupContainer; // extra event listeners - if (boxInfo.forceKey !== undefined) runtime.on("KEY_PRESSED", forceKeyHandler); + if (boxInfo.forceKey !== undefined) + runtime.on("KEY_PRESSED", forceKeyHandler); }; const closeBox = (id, optForce) => { @@ -531,9 +577,10 @@ const updateBoxVisuals = (id, type) => { const boxInfo = elementStorage[type][id]; if (!boxInfo || !boxInfo.DOMelement) return; - const element = type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; + const element = + type === "buttons" ? boxInfo.DOMelement : boxInfo.DOMelement.firstChild; element.setAttribute( - "style", + "style", compileStyles(id, type.slice(0, type.length - 1)) ); }; @@ -541,15 +588,17 @@ // extension utilities function createBlockLabel(text) { return { - blockType: Scratch.BlockType.LABEL, text: Scratch.translate(text) + blockType: Scratch.BlockType.LABEL, + text: Scratch.translate(text), }; - }; + } function createMenuItem(text, value) { return { - text: Scratch.translate(text), value + text: Scratch.translate(text), + value, }; - }; + } genDefaultBox("default-popup", false); @@ -573,8 +622,11 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("show popup with ID [ID] and [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "AWAITS" }, }, }, { @@ -582,7 +634,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("show popup with ID [ID] and wait"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -590,7 +645,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("response from [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -599,13 +657,16 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeAllPopups", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove all popups") + text: Scratch.translate("remove all popups"), }, createBlockLabel("Popups"), { @@ -613,7 +674,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("new-popup") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("new-popup"), + }, }, }, { @@ -621,28 +685,47 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete popup with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", { opcode: "append2Popup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]"), + text: Scratch.translate( + "append [TYPE] with ID [ELEMENT_ID] to popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "removeFromPopup", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]"), + text: Scratch.translate( + "remove [TYPE] with ID [ELEMENT_ID] from popup [POP_ID]" + ), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_ELEMENTS" }, - ELEMENT_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ELEMENT_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -650,7 +733,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all elements from popup [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, "---", @@ -659,9 +745,12 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set position of [ID] to x: [X] y: [Y]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, - Y: { type: Scratch.ArgumentType.NUMBER } + Y: { type: Scratch.ArgumentType.NUMBER }, }, }, { @@ -670,17 +759,28 @@ text: Scratch.translate("[TYPE] position of [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "POSITION" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Labels"), { opcode: "createPopLabel", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new label with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new label with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("whats your name?") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("whats your name?"), + }, }, }, { @@ -688,7 +788,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete label with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, }, }, createBlockLabel("Inputs"), @@ -698,7 +801,10 @@ text: Scratch.translate("create new [TYPE] input with ID [ID]"), arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: "INPUTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, { @@ -706,17 +812,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setDefaultValue", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set default value of input [ID] to [VALUE]"), + text: Scratch.translate( + "set default value of input [ID] to [VALUE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`...type here`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate(`...type here`), + }, }, }, "---", @@ -725,7 +842,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set slider [ID] min [MIN] max [MAX]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, MIN: { type: Scratch.ArgumentType.NUMBER, defaultValue: -100 }, MAX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, }, @@ -736,17 +856,33 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("set options of dropdown [ID] to [ARRAY]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - ARRAY: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate(`["Option 1", "Option 2", "Option 3"]`) } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + ARRAY: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate( + `["Option 1", "Option 2", "Option 3"]` + ), + }, }, }, { opcode: "isDropOpen", blockType: Scratch.BlockType.BOOLEAN, - text: Scratch.translate("is dropdown [DROP_ID] in popup [POP_ID] open?"), + text: Scratch.translate( + "is dropdown [DROP_ID] in popup [POP_ID] open?" + ), arguments: { - DROP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - POP_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + DROP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + POP_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, createBlockLabel("Buttons"), @@ -755,16 +891,27 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("create new button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { opcode: "createPopBtn", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("create new button with ID [ID] and text [TEXT]"), + text: Scratch.translate( + "create new button with ID [ID] and text [TEXT]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: Scratch.translate("Submit") } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + TEXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: Scratch.translate("Submit"), + }, }, }, { @@ -772,7 +919,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button row with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -780,7 +930,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("delete button with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, }, }, "---", @@ -789,8 +942,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("append button [BTN_ID] to row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -798,8 +957,14 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove button [BTN_ID] from row [ROW_ID]"), arguments: { - BTN_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.button }, - ROW_ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + BTN_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.button, + }, + ROW_ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, { @@ -807,7 +972,10 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("remove all buttons from row [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.btnRow } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.btnRow, + }, }, }, createBlockLabel("Operators"), @@ -816,7 +984,7 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("all [TYPE] IDs"), arguments: { - TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "UI_SELECT" }, }, }, { @@ -824,7 +992,10 @@ blockType: Scratch.BlockType.BOOLEAN, text: Scratch.translate("is popup [ID] waiting?"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -832,7 +1003,10 @@ blockType: Scratch.BlockType.REPORTER, text: Scratch.translate("last button pressed in [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { @@ -840,17 +1014,28 @@ blockType: Scratch.BlockType.COMMAND, text: Scratch.translate("focus on input with ID [ID]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, }, }, "---", { opcode: "setPopupTarget", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("show next popup with ID [ID] on the [TYPE]"), + text: Scratch.translate( + "show next popup with ID [ID] on the [TYPE]" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "POPUP_LOCATION" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: "POPUP_LOCATION", + }, }, }, { @@ -859,17 +1044,25 @@ text: Scratch.translate("toggle [OPTION] in popup [ID] [TYPE]"), arguments: { OPTION: { type: Scratch.ArgumentType.STRING, menu: "EXTRA_OPTS" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLER" }, }, }, { opcode: "setForceClose", blockType: Scratch.BlockType.COMMAND, - text: Scratch.translate("set auto-close action in popup [ID] to [KEY] key"), + text: Scratch.translate( + "set auto-close action in popup [ID] to [KEY] key" + ), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + KEY: { type: Scratch.ArgumentType.STRING, menu: "FORCE_KEY" }, }, }, createBlockLabel("Customization"), @@ -879,8 +1072,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of popup [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, { @@ -889,8 +1085,11 @@ blockIconURI: getBlockIcon("color"), text: Scratch.translate("set alignment of input [ID] to [TYPE]"), arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.input }, - TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.input, + }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENT" }, }, }, "---", @@ -901,31 +1100,44 @@ text: Scratch.translate("set font of [ELEMENT] [ID] to [FONT]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" }, }, }, { opcode: "setInputFontSZ", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set font size of [ELEMENT] [ID] to [SIZE]"), + text: Scratch.translate( + "set font size of [ELEMENT] [ID] to [SIZE]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, - SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 15 }, }, }, { opcode: "setElementOutline", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set text outline of [ELEMENT] [ID] to color [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN2" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.label }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.label, + }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -937,36 +1149,52 @@ arguments: { PARAM: { type: Scratch.ArgumentType.STRING, menu: "POP_STYLES" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.STRING, defaultValue: "#ff0000" } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { + type: Scratch.ArgumentType.STRING, + defaultValue: "#ff0000", + }, }, }, { opcode: "setElementBorder", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]"), + text: Scratch.translate( + "set border of [ELEMENT] [ID] to [TYPE] [COLOR] weight [WEIGHT]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, TYPE: { type: Scratch.ArgumentType.STRING, menu: "BORDERS" }, COLOR: { type: Scratch.ArgumentType.COLOR }, - WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + WEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { opcode: "setElementShadow", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("color"), - text: Scratch.translate("set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]"), + text: Scratch.translate( + "set shadow of [ELEMENT] [ID] to x: [X] y: [Y] color [COLOR] blur [AMT] strength [BLUR]" + ), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, X: { type: Scratch.ArgumentType.NUMBER }, Y: { type: Scratch.ArgumentType.NUMBER }, COLOR: { type: Scratch.ArgumentType.COLOR }, AMT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, - BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + BLUR: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, "---", @@ -977,19 +1205,27 @@ text: Scratch.translate("reset effects of [ELEMENT] [ID]"), arguments: { ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, { opcode: "setElementEffect", blockType: Scratch.BlockType.COMMAND, blockIconURI: getBlockIcon("effect"), - text: Scratch.translate("set [EFFECT] of [ELEMENT] [ID] to [VALUE]"), + text: Scratch.translate( + "set [EFFECT] of [ELEMENT] [ID] to [VALUE]" + ), arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup }, - VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, }, }, { @@ -1000,7 +1236,10 @@ arguments: { EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, ELEMENT: { type: Scratch.ArgumentType.STRING, menu: "UI_MAIN" }, - ID: { type: Scratch.ArgumentType.STRING, defaultValue: translatedInputs.popup } + ID: { + type: Scratch.ArgumentType.STRING, + defaultValue: translatedInputs.popup, + }, }, }, ], @@ -1010,48 +1249,66 @@ INPUTS: { acceptReporters: true, items: validInputs }, BORDERS: { acceptReporters: true, items: validBorders }, EFFECTS: { acceptReporters: true, items: validEffects }, - UI_ELEMENTS: { acceptReporters: true, items: this.genElementList(false, true, false) }, - UI_MAIN: { acceptReporters: true, items: this.genElementList(true, false, true) }, - UI_MAIN2: { acceptReporters: true, items: this.genElementList(false, false, true) }, - UI_SELECT: { acceptReporters: true, items: this.genElementList(true, true, true) }, + UI_ELEMENTS: { + acceptReporters: true, + items: this.genElementList(false, true, false), + }, + UI_MAIN: { + acceptReporters: true, + items: this.genElementList(true, false, true), + }, + UI_MAIN2: { + acceptReporters: true, + items: this.genElementList(false, false, true), + }, + UI_SELECT: { + acceptReporters: true, + items: this.genElementList(true, true, true), + }, AWAITS: { acceptReporters: false, - items: [createMenuItem("wait", "wait"), createMenuItem("continue", "continue")] + items: [ + createMenuItem("wait", "wait"), + createMenuItem("continue", "continue"), + ], }, TOGGLER: { acceptReporters: false, - items: [createMenuItem("on", "on"), createMenuItem("off", "off")] + items: [createMenuItem("on", "on"), createMenuItem("off", "off")], }, POSITION: { acceptReporters: false, - items: [createMenuItem("x", "x"), createMenuItem("y", "y")] + items: [createMenuItem("x", "x"), createMenuItem("y", "y")], }, POPUP_LOCATION: { acceptReporters: false, - items: [createMenuItem("window", "window"), createMenuItem("canvas", "canvas")] + items: [ + createMenuItem("window", "window"), + createMenuItem("canvas", "canvas"), + ], }, ALIGNMENT: { acceptReporters: false, items: [ createMenuItem("left", "left"), createMenuItem("right", "flex-end"), - createMenuItem("center", "center") - ] + createMenuItem("center", "center"), + ], }, FORCE_KEY: { acceptReporters: true, items: [ createMenuItem("none", "none"), createMenuItem("enter", "enter"), - createMenuItem("shift & enter", "shiftEnter") - ] + createMenuItem("shift & enter", "shiftEnter"), + ], }, EXTRA_OPTS: { acceptReporters: true, items: [ createMenuItem("focus mode", "focus"), - createMenuItem("auto close", "autoClose") - ] + createMenuItem("auto close", "autoClose"), + ], }, }, }; @@ -1059,14 +1316,21 @@ // Helper Funcs getFonts() { - const custFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; - return [ ...BUILT_IN_FONTS, ...custFonts ]; + const custFonts = runtime.fontManager + ? runtime.fontManager + .getFonts() + .map((i) => ({ text: i.name, value: i.family })) + : []; + return [...BUILT_IN_FONTS, ...custFonts]; } genElementList(addPopup, addRow, addButton) { const list = []; if (addPopup) list.push(createMenuItem("popup", "popup")); - list.push(createMenuItem("label", "label"), createMenuItem("input", "input")); + list.push( + createMenuItem("label", "label"), + createMenuItem("input", "input") + ); if (addRow) list.push(createMenuItem("button row", "buttonRow")); if (addButton) list.push(createMenuItem("button", "button")); return list; @@ -1081,7 +1345,7 @@ createMenuItem("padding", "padding"), createMenuItem("width", "width"), createMenuItem("height", "height"), - createMenuItem("border radius", "border-radius") + createMenuItem("border radius", "border-radius"), ]; } @@ -1101,9 +1365,12 @@ util.stackFrame.awaitingInput = true; } - if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) util.yield(); - if (reportResponse) return typeof popup.value === "object" ? - JSON.stringify(popup.value) : popup.value || ""; + if ((reportResponse ? true : args.TYPE === "wait") && popup?.waiting) + util.yield(); + if (reportResponse) + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } // Block Funcs @@ -1120,7 +1387,9 @@ const id = Cast.toString(args.ID); const popup = elementStorage.popups[id]; if (popup === undefined) return ""; - return typeof popup.value === "object" ? JSON.stringify(popup.value) : popup.value || ""; + return typeof popup.value === "object" + ? JSON.stringify(popup.value) + : popup.value || ""; } removePopup(args) { @@ -1159,7 +1428,7 @@ if (popup === undefined || element === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex === -1) popup.elements.push(element); } @@ -1171,7 +1440,7 @@ if (popup === undefined) return; const elementIndex = popup.elements.findIndex((i) => { - return i.type === path && i.data.id === elementID + return i.type === path && i.data.id === elementID; }); if (elementIndex > -1) popup.elements.splice(elementIndex, 1); } @@ -1193,7 +1462,8 @@ getPos(args) { const id = Cast.toString(args.ID); const styles = styleStorage.popups[id] ?? genDefaultStyles(id, "popup"); - if (args.TYPE === "x") return parseFloat(styles.left.replace("calc(50% + ", "")); + if (args.TYPE === "x") + return parseFloat(styles.left.replace("calc(50% + ", "")); else return parseFloat(styles.top.replace("calc(50% + ", "")) * -1; } @@ -1256,7 +1526,7 @@ const dropID = Cast.toString(args.DROP_ID); if (popup === undefined || !popup.waiting) return false; const dropdown = popup.elements.find((e) => { - return e.type === "input" && e.data.id === dropID + return e.type === "input" && e.data.id === dropID; }); if (dropdown) return dropdown.data.options.menuOpened ?? false; return false; @@ -1346,7 +1616,6 @@ } } - setPopupTarget(args) { const id = Cast.toString(args.ID); let popup = elementStorage.popups[id]; @@ -1360,9 +1629,8 @@ if (popup === undefined) return; const option = Cast.toString(args.OPTION); - popup[ - option === "focus" ? "focused" : "autoControl" - ] = args.TYPE === "on"; + popup[option === "focus" ? "focused" : "autoControl"] = + args.TYPE === "on"; } setForceClose(args) { @@ -1385,7 +1653,7 @@ setInputAlign(args) { const id = Cast.toString(args.ID); - let isLabel = false + let isLabel = false; let styles = styleStorage.inputs[id]; if (!styles) { styles = styleStorage.labels[id]; @@ -1426,9 +1694,12 @@ const id = Cast.toString(args.ID); const param = Cast.toString(args.PARAM); let value = Cast.toString(args.VALUE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - const isValidStyle = this.genStyleList().findIndex((i) => i.value === param); + const isValidStyle = this.genStyleList().findIndex( + (i) => i.value === param + ); if (!param.includes("color") && param !== "background") { if (param === "width" || param === "height") { @@ -1436,7 +1707,10 @@ value = /^\d+$/.test(value) ? `${value}px` : value; } else { // handle cases where users to input specific attributes like "margin-left" - if (value.includes(" ")) value = /^\d+$/.test(value.replaceAll(" ", "")) ? value.replaceAll(" ", "px ") : value; + if (value.includes(" ")) + value = /^\d+$/.test(value.replaceAll(" ", "")) + ? value.replaceAll(" ", "px ") + : value; else value = `${value}px`; } } @@ -1448,10 +1722,13 @@ setElementBorder(args) { const id = Cast.toString(args.ID); const weight = Cast.toNumber(args.WEIGHT); - const isBorderValid = validBorders.findIndex((i) => i.value === args.TYPE); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const isBorderValid = validBorders.findIndex( + (i) => i.value === args.TYPE + ); + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - styles[path === "labels" ? "border-bottom" : "border"] = + styles[path === "labels" ? "border-bottom" : "border"] = `${isBorderValid > -1 ? args.TYPE : "none"} ${args.COLOR} ${weight}px`; updateBoxVisuals(id, path); } @@ -1460,16 +1737,22 @@ const id = Cast.toString(args.ID); const pos = [Cast.toNumber(args.X), Cast.toNumber(args.Y)]; const weight = [Cast.toNumber(args.AMT), Cast.toNumber(args.BLUR)]; - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); - if (path === "labels") styles["text-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; - else styles["box-shadow"] = `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; + if (path === "labels") + styles["text-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px`; + else + styles["box-shadow"] = + `${args.COLOR} ${pos[0]}px ${pos[1]}px ${weight[0]}px ${weight[1]}px`; updateBoxVisuals(id, path); } resetElementEffect(args) { const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); if (path === "popups") styles["transform"] = "translate(-50%, -50%)"; styles["filter"] = ""; @@ -1481,7 +1764,8 @@ const effectIndex = validEffects.findIndex((i) => i.value === effect); if (effectIndex === -1) return; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); let value = Cast.toNumber(args.VALUE); @@ -1494,10 +1778,10 @@ value += "px"; break; case "brightness": - value = `${100 - (value * -1)}%`; + value = `${100 - value * -1}%`; break; case "opacity": - value = 1 - (value / 100); + value = 1 - value / 100; break; case "saturate": case "sepia": @@ -1534,7 +1818,8 @@ if (isValidEffect === -1) return ""; const id = Cast.toString(args.ID); - const path = this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; + const path = + this.getElementPath(Cast.toString(args.ELEMENT), true, true) + "s"; const styles = styleStorage[path][id] ?? genDefaultStyles(id, path); return styles["SPstorage"][effect] ?? ""; }