From 61e7d27f309638382067deea4cbd1fa6e9e3ed3c Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 13 Dec 2023 20:18:40 -0800 Subject: [PATCH 01/25] Create Display-Text.js --- extensions/SharkPool/Display-Text.js | 676 +++++++++++++++++++++++++++ 1 file changed, 676 insertions(+) create mode 100644 extensions/SharkPool/Display-Text.js diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js new file mode 100644 index 0000000000..f8cb552284 --- /dev/null +++ b/extensions/SharkPool/Display-Text.js @@ -0,0 +1,676 @@ +// Name: Display Text +// ID: SPdisText +// Description: Display Text in Your Projects! +// By: SharkPool + +// Version V.1.0.0 + +(function (Scratch) { + "use strict"; + if (!Scratch.extensions.unsandboxed) throw new Error("Display Text Extension must run unsandboxed!"); + + const menuIconURI = +"data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI2NS4yMzM5NiIgaGVpZ2h0PSI2NS4yMzM5NiIgdmlld0JveD0iMCwwLDY1LjIzMzk2LDY1LjIzMzk2Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjA3LjM4MzAyLC0xNDcuMzgzMDIpIj48ZyBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpc1BhaW50aW5nTGF5ZXImcXVvdDs6dHJ1ZX0iIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWRhc2hhcnJheT0iIiBzdHJva2UtZGFzaG9mZnNldD0iMCIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0yMDcuMzgzMDIsMTgwYzAsLTE4LjAxMzg2IDE0LjYwMzEyLC0zMi42MTY5OCAzMi42MTY5OCwtMzIuNjE2OThjMTguMDEzODYsMCAzMi42MTY5OCwxNC42MDMxMiAzMi42MTY5OCwzMi42MTY5OGMwLDE4LjAxMzg2IC0xNC42MDMxMiwzMi42MTY5OCAtMzIuNjE2OTgsMzIuNjE2OThjLTE4LjAxMzg2LDAgLTMyLjYxNjk4LC0xNC42MDMxMiAtMzIuNjE2OTgsLTMyLjYxNjk4eiIgZmlsbD0iIzNjNGU1YyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjEwLjc3MzYyLDE4MGMwLC0xNi4xNDEyOSAxMy4wODUxLC0yOS4yMjYzOCAyOS4yMjYzOCwtMjkuMjI2MzhjMTYuMTQxMjksMCAyOS4yMjYzOCwxMy4wODUxIDI5LjIyNjM4LDI5LjIyNjM4YzAsMTYuMTQxMjkgLTEzLjA4NTEsMjkuMjI2MzggLTI5LjIyNjM4LDI5LjIyNjM4Yy0xNi4xNDEyOSwwIC0yOS4yMjYzOCwtMTMuMDg1MSAtMjkuMjI2MzgsLTI5LjIyNjM4eiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmwxLjYyNjMxLDBjMC41MTI3MiwwIDAuOTI4MzYsMC40MTU2NCAwLjkyODM2LDAuOTI4MzZsMCwxMy42MTE5OWMwLDAuNTEyNzIgLTAuNDE1NjQsMC45MjgzNiAtMC45MjgzNiwwLjkyODM2aC0xLjYyNjMxYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMS41Ii8+PC9nPjwvZz48L3N2Zz4="; + + const blockIconURI = +"data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI0OS42MjQ0MSIgaGVpZ2h0PSI0OS42MjQ0MSIgdmlld0JveD0iMCwwLDQ5LjYyNDQxLDQ5LjYyNDQxIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjE1LjE4NzgsLTE1NS4xODc4KSI+PGcgZGF0YS1wYXBlci1kYXRhPSJ7JnF1b3Q7aXNQYWludGluZ0xheWVyJnF1b3Q7OnRydWV9IiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48cGF0aCBkPSJNMjE1LjE4NzgsMjA0LjgxMjJ2LTQ5LjYyNDQxaDQ5LjYyNDQxdjQ5LjYyNDQxeiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxLjYyNjMxYzAuNTEyNzIsMCAwLjkyODM2LDAuNDE1NjQgMC45MjgzNiwwLjkyODM2djEzLjYxMTk5YzAsMC41MTI3MiAtMC40MTU2NCwwLjkyODM2IC0wLjkyODM2LDAuOTI4MzZoLTEuNjI2MzFjLTAuNTEyNzIsMCAtMC45MjgzNiwtMC40MTU2NCAtMC45MjgzNiwtMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L2c+PC9nPjwvc3ZnPg=="; + const render = Scratch.vm.renderer; + let allText = []; + let lastRecdVals = {}; + const fontMenu = [ + "Scratch", "Sans Serif", + "Serif", "Handwriting", + "Marker", "Curly", "Pixel" + ]; + + class SPdisText { + getInfo() { + return { + id: "SPdisText", + name: "Display Text", + color1: "#778899", + color2: "#5E707F", + color3: "#3C4E5C", + menuIconURI, + blockIconURI, + blocks: [ + { + opcode: "printTxt", + blockType: Scratch.BlockType.COMMAND, + text: "print text [TXT] with ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: "hello world" + } + }, + }, + { + opcode: "replaceTxt", + blockType: Scratch.BlockType.COMMAND, + text: "replace text of ID [ID] with [TXT]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TXT: { + type: Scratch.ArgumentType.STRING, + defaultValue: "lorem ipsum" + } + }, + }, + { + opcode: "removeTxt", + blockType: Scratch.BlockType.COMMAND, + text: "remove text with ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + { + opcode: "removeAllTxt", + blockType: Scratch.BlockType.COMMAND, + text: "remove all text" + }, + "---", + { + opcode: "displayedTexts", + blockType: Scratch.BlockType.REPORTER, + text: "printed texts from ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + { + opcode: "existingID", + blockType: Scratch.BlockType.BOOLEAN, + text: "does text with ID [ID] exist?", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + { + opcode: "allIDs", + blockType: Scratch.BlockType.REPORTER, + text: "all text IDs" + }, + { blockType: Scratch.BlockType.LABEL, text: "Formatting" }, + { + opcode: "setTextFont", + blockType: Scratch.BlockType.COMMAND, + text: "set font of ID [ID] to [FONT]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + FONT: { type: Scratch.ArgumentType.STRING, menu: "FONTS" } + }, + }, + { + opcode: "setFontSize", + blockType: Scratch.BlockType.COMMAND, + text: "set font size of ID [ID] to [SIZE]px", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 30 } + }, + }, + { + opcode: "setTextAlignment", + blockType: Scratch.BlockType.COMMAND, + text: "set text alignment of ID [ID] to [ALIGNMENT]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + ALIGNMENT: { type: Scratch.ArgumentType.STRING, menu: "ALIGNMENTS" } + }, + }, + { + opcode: "setMargins", + blockType: Scratch.BlockType.COMMAND, + text: "set margins of ID [ID] to width [WIDTH] height [HEIGHT]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + WIDTH: { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, + HEIGHT: { type: Scratch.ArgumentType.NUMBER, defaultValue: 30 } + }, + }, + { + opcode: "setTextSpacing", + blockType: Scratch.BlockType.COMMAND, + text: "set [ATT] spacing of ID [ID] to [SPACING] px", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + SPACING: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + ATT: { type: Scratch.ArgumentType.STRING, menu: "TEXT_ATT" } + }, + }, + "---", + { + opcode: "attOfText", + blockType: Scratch.BlockType.REPORTER, + text: "[ATT] of text with ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + ATT: { type: Scratch.ArgumentType.STRING, menu: "FORMATS" } + }, + }, + { blockType: Scratch.BlockType.LABEL, text: "Text Visuals" }, + { + opcode: "setTextColor", + blockType: Scratch.BlockType.COMMAND, + text: "set text color of ID [ID] to [COLOR]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + COLOR: { type: Scratch.ArgumentType.COLOR, defaultValue: "#000000" } + }, + }, + { + opcode: "setTextDropShadow", + blockType: Scratch.BlockType.COMMAND, + text: "set text shadow of ID [ID] to x [x] y [y] z [z] color [COLOR]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + x: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 }, + y: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 }, + z: { type: Scratch.ArgumentType.NUMBER, defaultValue: 2 }, + COLOR: { type: Scratch.ArgumentType.COLOR, defaultValue: "#ff0000" } + }, + }, + { + opcode: "setTextOutline", + blockType: Scratch.BlockType.COMMAND, + text: "set outline of ID [ID] to [COLOR] with thickness [THICKNESS]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + COLOR: { type: Scratch.ArgumentType.COLOR, defaultValue: "#ff0000" }, + THICKNESS: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3 } + }, + }, + "---", + { + opcode: "makeGradient", + blockType: Scratch.BlockType.REPORTER, + text: "make a [TYPE] gradient with [COLOR1] and [COLOR2] at angle [ANGLE]", + arguments: { + COLOR1: { type: Scratch.ArgumentType.COLOR, defaultValue: "#ff0000" }, + COLOR2: { type: Scratch.ArgumentType.COLOR, defaultValue: "#00ff00" }, + ANGLE: { type: Scratch.ArgumentType.ANGLE, defaultValue: 90 }, + TYPE: { type: Scratch.ArgumentType.NUMBER, menu: "GRADIENTS" } + }, + }, + "---", + { + opcode: "setTextCurve", + blockType: Scratch.BlockType.COMMAND, + text: "set text curve of ID [ID] to [ARC]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + ARC: { type: Scratch.ArgumentType.STRING, defaultValue: "" } + }, + }, + { + opcode: "presetCurve", + blockType: Scratch.BlockType.REPORTER, + text: "preset curve [ARC]", + disableMonitor: true, + arguments: { + ARC: { type: Scratch.ArgumentType.STRING, menu: "ARCS" } + }, + }, + { blockType: Scratch.BlockType.LABEL, text: "Positioning" }, + { + opcode: "setTextPosition", + blockType: Scratch.BlockType.COMMAND, + text: "set position of ID [ID] to x: [X] y: [Y]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + X: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 }, + Y: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 } + }, + }, + { + opcode: "setTextZIndex", + blockType: Scratch.BlockType.COMMAND, + text: "set layer of ID [ID] to [Z_INDEX]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + Z_INDEX: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 } + }, + }, + { + opcode: "textPosition", + blockType: Scratch.BlockType.REPORTER, + text: "[ATT] of ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + ATT: { type: Scratch.ArgumentType.NUMBER, menu: "POS" } + }, + }, + { blockType: Scratch.BlockType.LABEL, text: "Effects" }, + { + opcode: "setEffect", + blockType: Scratch.BlockType.COMMAND, + text: "set [EFFECT] of ID [ID] to [VALUE]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + VALUE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 5 }, + EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" } + }, + }, + { + opcode: "amtOfEffect", + blockType: Scratch.BlockType.REPORTER, + text: "current [EFFECT] of ID [ID]", + arguments: { + EFFECT: { type: Scratch.ArgumentType.STRING, menu: "EFFECTS" }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + { + opcode: "resetEffect", + blockType: Scratch.BlockType.COMMAND, + text: "reset effects of ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + ], + menus: { + FONTS: { + acceptReporters: true, + items: "allFonts" + }, + ALIGNMENTS: { + acceptReporters: true, + items: ["left", "right", "center"] + }, + TEXT_ATT: ["letter", "line"], + GRADIENTS: { + acceptReporters: true, // conic gradients exist but are complex + items: ["linear", "radial"] + }, + POS: ["x position", "y position", "z layer"], + ARCS: ["circle", "hill", "dip", "wave"], + FORMATS: { + acceptReporters: true, + items: [ + { text: "font", value: "fontFamily" }, + { text: "font size", value: "fontSize" }, + { text: "alignment", value: "textAlign" }, + { text: "margin width", value: "width" }, + { text: "margin height", value: "height" }, + { text: "letter spacing", value: "letterSpacing" }, + { text: "text spacing", value: "lineHeight" } + ] + }, + EFFECTS: { + acceptReporters: true, + items: [ + { text: "blur", value: "blur" }, + { text: "saturation", value: "saturate" }, + { text: "contrast", value: "contrast" }, + { text: "brightness", value: "brightness" }, + { text: "hue", value: "hue-rotate" }, + { text: "opacity", value: "opacity" }, + { text: "sepia", value: "sepia" }, + { text: "invert", value: "invert" }, + { text: "direction", value: "rotate" }, + { text: "scale x", value: "scaleX" }, + { text: "scale y", value: "scaleY" }, + { text: "skew x", value: "skewX" }, + { text: "skew y", value: "skewY" }, + ] + } + } + }; + } + + allFonts() { + const customFonts = Scratch.vm.runtime.fontManager ? Scratch.vm.runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + return [...fontMenu, ...customFonts]; + } + + printTxt(args) { + const newTextElement = document.createElement("div"); + newTextElement.textContent = args.TXT; + newTextElement.id = `SP_Text-Ext-${args.ID}`; + newTextElement.classList.add(args.ID); + render.addOverlay(newTextElement, "scale-centered"); + allText.push(`#SP_Text-Ext-${args.ID}`); + + // add formatting (if any) + if (lastRecdVals["textCLR"]) this.setTextColor(lastRecdVals["textCLR"].inputs); + if (lastRecdVals["textOUT"]) this.setTextOutline(lastRecdVals["textOUT"].inputs); + if (lastRecdVals["textSHA"]) this.setTextDropShadow(lastRecdVals["textSHA"].inputs); + if (lastRecdVals["txtFont"]) this.setTextFont(lastRecdVals["txtFont"].inputs); + if (lastRecdVals["txtFontSZ"]) this.setFontSize(lastRecdVals["txtFontSZ"].inputs); + if (lastRecdVals["txtALI"]) this.setTextAlignment(lastRecdVals["txtALI"].inputs); + if (lastRecdVals["lineDIS"]) this.setTextSpacing(lastRecdVals["lineDIS"].inputs); + if (lastRecdVals["letDIS"]) this.setTextSpacing(lastRecdVals["letDIS"].inputs); + + const box = newTextElement.getBoundingClientRect(); + this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); + } + + replaceTxt(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.textContent = args.TXT }); + } + + removeTxt(args) { + const elementsToRemove = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elementsToRemove.forEach((element) => { + render.removeOverlay(element) + const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); + if (index !== -1) allText.splice(index, 1); + }); + } + + removeAllTxt() { + for (let i = 0; i < allText.length; i++) { + const elementsToRemove = document.querySelectorAll(allText[i]); + elementsToRemove.forEach((element) => { render.removeOverlay(element) }); + } + allText = []; + } + + displayedTexts(args) { + let texts = []; + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { texts.push(element.textContent) }); + return JSON.stringify(texts); + } + + allIDs() { + const cleanedIDs = allText.map((item) => item.replace(/^#SP_Text-Ext-/, "")); + return JSON.stringify(cleanedIDs); + } + + existingID(args) { + const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); + return Scratch.Cast.toBoolean(allText[index]); + } + + makeGradient(args) { return `${args.TYPE}-gradient(${args.ANGLE}deg, ${args.COLOR1}, ${args.COLOR2})` } + + setTextColor(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style.color = args.COLOR; + if (args.COLOR.includes("gradient")) { + element.style.background = args.COLOR; + element.style.color = "transparent"; + element.style.webkitTextFillColor = "transparent"; + element.style.webkitBackgroundClip = "text"; + } else { + element.style.color = args.COLOR; + element.style.background = "none"; + element.style.webkitTextFillColor = "initial"; + element.style.webkitBackgroundClip = "initial"; + } + }); + lastRecdVals["textCLR"] = {inputs: args}; + } + + setTextDropShadow(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style.textShadow = `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; + }); + lastRecdVals["textSHA"] = {inputs: args}; + } + + setTextOutline(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style.webkitTextStrokeColor = args.COLOR; + element.style.webkitTextStrokeWidth = `${args.THICKNESS}px`; + //multi-platform support cuz we cant have nice things + element.style.textStrokeColor = args.COLOR; + element.style.textStrokeWidth = `${args.THICKNESS}px`; + element.style.mozTextStrokeColor = args.COLOR; + element.style.mozTextStrokeWidth = `${args.THICKNESS}px`; + }); + lastRecdVals["textOUT"] = {inputs: args}; + } + + setMargins(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style.width = `${args.WIDTH}px`; + element.style.height = `${args.HEIGHT}px`; + }); + } + + setTextAlignment(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.style.textAlign = args.ALIGNMENT }); + lastRecdVals["txtALI"] = {inputs: args}; + } + + setTextFont(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.style.fontFamily = args.FONT }); + lastRecdVals["txtFont"] = {inputs: args}; + } + + setFontSize(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.style.fontSize = `${args.SIZE}px` }); + lastRecdVals["txtFontSZ"] = {inputs: args}; + } + + setTextSpacing(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style[args.ATT === "letter" ? "letterSpacing" : "lineHeight"] = `${args.SPACING}px`; + }); + lastRecdVals["letDIS"] = {inputs: {ID : args.ID, SPACING : args.SPACING, ATT : "letter"}}; + lastRecdVals["lineDIS"] = {inputs: {ID : args.ID, SPACING : args.SPACING, ATT : "line"}}; + } + + setTextPosition(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + const box = element.getBoundingClientRect(); + element.style.position = "absolute"; + element.style.left = `${args.X - (box.width / 2)}px`; + element.style.top = `${(args.Y * -1) - (box.height / 2)}px`; + }); + } + + textPosition(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + let value; + elements.forEach((element) => { + const box = element.getBoundingClientRect(); + if (args.ATT === "z layer") { + value = element.parentNode.style.zIndex; + } else { + value = parseFloat(element.style[args.ATT.includes("x") ? "left" : "top"]); + value = ((box[args.ATT.includes("x") ? "width" : "height"] / 2) + value) * (args.ATT.includes("x") ? 1 : -1); + } + }); + return value || 0; + } + + attOfText(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + let value; + elements.forEach((element) => { value = element.style[args.ATT] }); + value = args.ATT === "fontFamily" || args.ATT === "textAlign" ? value : parseFloat(value); + return value || ""; + } + + setTextZIndex(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.parentNode.style.zIndex = Math.round(args.Z_INDEX) }); + } + + setEffect(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + const currentStyleArray = [ + element.style.filter || "", + element.parentNode.style.transform || "", + element.style.opacity || "" + ]; + const regex = new RegExp(`${args.EFFECT}\\([^)]+\\)`, "g"); + currentStyleArray.forEach((currentStyle, index) => { + currentStyleArray[index] = currentStyle.replace(regex, ""); + }); + switch (args.EFFECT) { + case "saturate": + element.style.filter = `${currentStyleArray[0]} saturate(${args.VALUE}%)`; + break; + case "contrast": + element.style.filter = `${currentStyleArray[0]} contrast(${args.VALUE + 100}%)`; + break; + case "brightness": + element.style.filter = `${currentStyleArray[0]} brightness(${args.VALUE + 100}%)`; + break; + case "hue-rotate": + element.style.filter = `${currentStyleArray[0]} hue-rotate(${args.VALUE}deg)`; + break; + case "opacity": + element.style.opacity = (100 - args.VALUE) / 100; + break; + case "sepia": + element.style.filter = `${currentStyleArray[0]} sepia(${args.VALUE}%)`; + break; + case "invert": + element.style.filter = `${currentStyleArray[0]} invert(${args.VALUE}%)`; + break; + case "rotate": + element.parentNode.style.transform = `${currentStyleArray[1]} rotate(${args.VALUE - 90}deg)`; + break; + case "scaleX": + element.parentNode.style.transform = `${currentStyleArray[1]} scaleX(${args.VALUE / 100})`; + break; + case "scaleY": + element.parentNode.style.transform = `${currentStyleArray[1]} scaleY(${args.VALUE / 100})`; + break; + case "skewX": + element.parentNode.style.transform = `${currentStyleArray[1]} skewX(${args.VALUE}deg)`; + break; + case "skewY": + element.parentNode.style.transform = `${currentStyleArray[1]} skewY(${args.VALUE}deg)`; + break; + default: + element.style.filter = `${currentStyleArray[0]} blur(${args.VALUE}px)`; + break; + } + }); + } + + resetEffect(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + const currentTransform = element.parentNode.style.transform || ""; + const updatedTransform = currentTransform + .replace(/rotate\([^)]*\)/, "rotate(0deg)") + .replace(/scaleX\([^)]*\)/, "scaleX(1)") + .replace(/scaleY\([^)]*\)/, "scaleY(1)") + .replace(/skewX\([^)]*\)/, "skewX(0deg)") + .replace(/skewY\([^)]*\)/, "skewY(0deg)"); + element.parentNode.style.transform = updatedTransform; + element.style.filter = ""; + element.style.opacity = 1; + }); + } + + amtOfEffect(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + let effectValue = args.EFFECT === "rotate" ? 90 : args.EFFECT.includes("scale") ? 100 : 0; + elements.forEach((element) => { + if (args.EFFECT === "rotate" || args.EFFECT.includes("scale") || args.EFFECT.includes("skew")) { + const transformV = element.parentNode.style.transform.split(" "); + const effectIndex = transformV.findIndex(value => value.includes(args.EFFECT)); + if (effectIndex !== -1) { + effectValue = transformV[effectIndex].replace(/[^\d.-]/g, ""); + effectValue = args.EFFECT === "rotate" ? parseFloat(effectValue) + 90 : + parseFloat(effectValue) * (args.EFFECT.includes("scale") ? 100 : 1); + } + } else if (args.EFFECT === "opacity") { + effectValue = 100 - (parseFloat(element.style.opacity || 0) * 100); + } else { + const filterV = element.style.filter.split(" "); + const effectIndex = filterV.findIndex((value) => value.includes(args.EFFECT)); + if (effectIndex !== -1) { + effectValue = + args.EFFECT === "contrast" || args.EFFECT === "brightness" + ? parseFloat(filterV[effectIndex].replace(/[^\d.-]/g, "")) - 100 + : parseFloat(filterV[effectIndex].replace(/[^\d.-]/g, "")); + } + } + }); + return effectValue; + } + + setTextCurve(args) { + const regex = args.ARC.includes("]*d="([^"]*)"/ : /]*d="([^"]*)"/; + const match = args.ARC.match(regex); + const outline = lastRecdVals["textOUT"] !== undefined ? lastRecdVals["textOUT"] : ""; + if (match && match[1]) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + const existingSvg = element.querySelector("svg"); + if (existingSvg) { + const path = existingSvg.querySelector("path"); + path.setAttribute("d", match[1]); + const textFill = existingSvg.querySelector("text"); + textFill.setAttribute("fill", element.style.color === "transparent" ? "#000000" : element.style.color); + const textPathFill = existingSvg.querySelector("textPath"); + textPathFill.setAttribute("href", `#MyPath-${args.ID}`); + textPathFill.textContent = element.textContent; + + const textStroke = existingSvg.querySelector("text"); + textStroke.setAttribute("fill", outline ? outline.inputs.COLOR ?? "#00000000" : "#00000000"); + textStroke.setAttribute("stroke", outline ? outline.inputs.COLOR ?? "#00000000" : "#00000000"); + textStroke.setAttribute("stroke-width", outline ? outline.inputs.THICKNESS ?? 1 : 1); + const textPathStroke = existingSvg.querySelector("textPath"); + textPathStroke.setAttribute("href", `#MyPath-${args.ID}`); + textPathStroke.textContent = element.textContent; + } else { + const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs"); + const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + path.setAttribute("id", `MyPath-${args.ID}`); + path.setAttribute("d", match[1]); + defs.appendChild(path); + + const textStroke = document.createElementNS("http://www.w3.org/2000/svg", "text"); + textStroke.setAttribute("fill", outline ? outline.inputs.COLOR : "#00000000"); + textStroke.setAttribute("stroke", outline ? outline.inputs.COLOR : "#00000000"); + textStroke.setAttribute("stroke-width", outline ? outline.inputs.THICKNESS : 1); + const textPathStroke = document.createElementNS("http://www.w3.org/2000/svg", "textPath"); + textPathStroke.setAttribute("href", `#MyPath-${args.ID}`); + textPathStroke.textContent = element.textContent; + textStroke.appendChild(textPathStroke); + + svg.appendChild(defs); + svg.appendChild(textStroke); + const textFill = document.createElementNS("http://www.w3.org/2000/svg", "text"); + textFill.setAttribute("fill", element.style.color === "transparent" ? "#000000" : element.style.color); + const textPathFill = document.createElementNS("http://www.w3.org/2000/svg", "textPath"); + textPathFill.setAttribute("href", `#MyPath-${args.ID}`); + textPathFill.textContent = element.textContent; + textFill.appendChild(textPathFill); + svg.appendChild(textFill); + element.innerHTML = ""; + element.appendChild(svg); + } + }); + } + } + + presetCurve(args) { + const presets = { + circle : ``, + wave : `` + }; + return presets[args.ARC]; + } + } + + Scratch.extensions.register(new SPdisText()); +})(Scratch); From fa82f66148ffc4c6eba3455354702ded2dc26289 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 13 Dec 2023 20:20:15 -0800 Subject: [PATCH 02/25] Create Display-Text.svg --- images/SharkPool/Display-Text.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/SharkPool/Display-Text.svg diff --git a/images/SharkPool/Display-Text.svg b/images/SharkPool/Display-Text.svg new file mode 100644 index 0000000000..8fc4cbca5e --- /dev/null +++ b/images/SharkPool/Display-Text.svg @@ -0,0 +1 @@ + From dc11c36fcbbba524a3581f96400179acdf36351a Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 15 Dec 2023 14:45:25 -0800 Subject: [PATCH 03/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 58 +++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index f8cb552284..ea79a75773 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.0.0 +// Version V.1.0.1 (function (Scratch) { "use strict"; @@ -141,6 +141,15 @@ ATT: { type: Scratch.ArgumentType.STRING, menu: "TEXT_ATT" } }, }, + { + opcode: "setOverflow", + blockType: Scratch.BlockType.COMMAND, + text: "set text overflow of ID [ID] to [TYPE]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "OVERFLOW" } + }, + }, "---", { opcode: "attOfText", @@ -192,7 +201,7 @@ COLOR1: { type: Scratch.ArgumentType.COLOR, defaultValue: "#ff0000" }, COLOR2: { type: Scratch.ArgumentType.COLOR, defaultValue: "#00ff00" }, ANGLE: { type: Scratch.ArgumentType.ANGLE, defaultValue: 90 }, - TYPE: { type: Scratch.ArgumentType.NUMBER, menu: "GRADIENTS" } + TYPE: { type: Scratch.ArgumentType.STRING, menu: "GRADIENTS" } }, }, "---", @@ -215,6 +224,16 @@ }, }, { blockType: Scratch.BlockType.LABEL, text: "Positioning" }, + { + opcode: "presetTextPosition", + blockType: Scratch.BlockType.COMMAND, + text: "preset position of ID [ID] to x: [X] y: [Y]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + X: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 }, + Y: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0 } + }, + }, { opcode: "setTextPosition", blockType: Scratch.BlockType.COMMAND, @@ -240,7 +259,7 @@ text: "[ATT] of ID [ID]", arguments: { ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, - ATT: { type: Scratch.ArgumentType.NUMBER, menu: "POS" } + ATT: { type: Scratch.ArgumentType.STRING, menu: "POS" } }, }, { blockType: Scratch.BlockType.LABEL, text: "Effects" }, @@ -287,6 +306,7 @@ items: ["linear", "radial"] }, POS: ["x position", "y position", "z layer"], + OVERFLOW: ["visible", "hidden"], ARCS: ["circle", "hill", "dip", "wave"], FORMATS: { acceptReporters: true, @@ -297,7 +317,8 @@ { text: "margin width", value: "width" }, { text: "margin height", value: "height" }, { text: "letter spacing", value: "letterSpacing" }, - { text: "text spacing", value: "lineHeight" } + { text: "text spacing", value: "lineHeight" }, + { text: "overflow type", value: "overflow" } ] }, EFFECTS: { @@ -344,6 +365,8 @@ if (lastRecdVals["txtALI"]) this.setTextAlignment(lastRecdVals["txtALI"].inputs); if (lastRecdVals["lineDIS"]) this.setTextSpacing(lastRecdVals["lineDIS"].inputs); if (lastRecdVals["letDIS"]) this.setTextSpacing(lastRecdVals["letDIS"].inputs); + if (lastRecdVals["textOVR"]) this.setOverflow(lastRecdVals["textOVR"].inputs); + if (lastRecdVals["preTxt1"]) this.presetTextPosition(lastRecdVals["preTxt1"].inputs,); const box = newTextElement.getBoundingClientRect(); this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); @@ -351,7 +374,11 @@ replaceTxt(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); - elements.forEach((element) => { element.textContent = args.TXT }); + if (elements.length > 0) { + elements.forEach((element) => { element.textContent = args.TXT }); + } else { + this.printTxt(args); + } } removeTxt(args) { @@ -417,6 +444,12 @@ lastRecdVals["textSHA"] = {inputs: args}; } + setOverflow(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.style.overflow = args.TYPE }); + lastRecdVals["textOVR"] = {inputs: args}; + } + setTextOutline(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { @@ -466,6 +499,19 @@ lastRecdVals["lineDIS"] = {inputs: {ID : args.ID, SPACING : args.SPACING, ATT : "line"}}; } + presetTextPosition(args) { + if (args.isPrint === undefined) { + lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; + } else { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const element = elements[elements.length - 1]; + const box = element.getBoundingClientRect(); + element.style.position = "absolute"; + element.style.left = `${(args.X - (box.width / 2)) + (parseFloat(Scratch.vm.renderer.canvas.style.width) / 2)}px`; + element.style.top = `${(args.Y * -1) - (box.height / 2)}px`; + } + } + setTextPosition(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { @@ -495,7 +541,7 @@ const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); let value; elements.forEach((element) => { value = element.style[args.ATT] }); - value = args.ATT === "fontFamily" || args.ATT === "textAlign" ? value : parseFloat(value); + value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); return value || ""; } From 47d1c2e9db7c3a8a34eef05a13c44f20103a9f52 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:01:05 -0800 Subject: [PATCH 04/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index ea79a75773..217f69a22b 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.0.1 +// Version V.1.1.0 (function (Scratch) { "use strict"; @@ -160,6 +160,14 @@ ATT: { type: Scratch.ArgumentType.STRING, menu: "FORMATS" } }, }, + { + opcode: "lineCnt", + blockType: Scratch.BlockType.REPORTER, + text: "# of lines in text ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, { blockType: Scratch.BlockType.LABEL, text: "Text Visuals" }, { opcode: "setTextColor", @@ -317,7 +325,7 @@ { text: "margin width", value: "width" }, { text: "margin height", value: "height" }, { text: "letter spacing", value: "letterSpacing" }, - { text: "text spacing", value: "lineHeight" }, + { text: "line spacing", value: "lineHeight" }, { text: "overflow type", value: "overflow" } ] }, @@ -349,8 +357,9 @@ } printTxt(args) { + args.ID = args.ID.replaceAll(" ", "_"); const newTextElement = document.createElement("div"); - newTextElement.textContent = args.TXT; + newTextElement.innerHTML = args.TXT.replace(/\n/g, "
"); newTextElement.id = `SP_Text-Ext-${args.ID}`; newTextElement.classList.add(args.ID); render.addOverlay(newTextElement, "scale-centered"); @@ -375,7 +384,7 @@ replaceTxt(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); if (elements.length > 0) { - elements.forEach((element) => { element.textContent = args.TXT }); + elements.forEach((element) => { element.innerHTML = args.TXT.replace(/\n/g, "
"); }); } else { this.printTxt(args); } @@ -439,7 +448,7 @@ setTextDropShadow(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { - element.style.textShadow = `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; + element.style.textShadow = args.z === 0 ? "none" : `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; }); lastRecdVals["textSHA"] = {inputs: args}; } @@ -544,6 +553,17 @@ value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); return value || ""; } + + lineCnt(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + let value = []; + elements.forEach((element) => { + value.push(element.querySelectorAll("br").length + 1 || 1); + }); + console.log(value); + value = value.length > 1 ? JSON.stringify(value) : (value[0] || 0); + return value; + } setTextZIndex(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); From 840b40221ce6849f1de3eef09663a0133d4fc27f Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:04:10 -0800 Subject: [PATCH 05/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 217f69a22b..d4b2092d4f 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -560,7 +560,6 @@ elements.forEach((element) => { value.push(element.querySelectorAll("br").length + 1 || 1); }); - console.log(value); value = value.length > 1 ? JSON.stringify(value) : (value[0] || 0); return value; } From d10594271a3a6b44d310cd19d52e4764c3e8d9b0 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:19:21 -0800 Subject: [PATCH 06/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index d4b2092d4f..b4a980e7b4 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -23,6 +23,19 @@ "Marker", "Curly", "Pixel" ]; + const xmlEscape = function (unsafe) { + unsafe = String(unsafe); + return unsafe.replace(/[<>&'"]/g, c => { + switch (c) { + case "<": return "<"; + case ">": return ">"; + case "&": return "&"; + case "'": return "'"; + case "\"": return """; + } + }); + }; + class SPdisText { getInfo() { return { @@ -359,7 +372,7 @@ printTxt(args) { args.ID = args.ID.replaceAll(" ", "_"); const newTextElement = document.createElement("div"); - newTextElement.innerHTML = args.TXT.replace(/\n/g, "
"); + newTextElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); newTextElement.id = `SP_Text-Ext-${args.ID}`; newTextElement.classList.add(args.ID); render.addOverlay(newTextElement, "scale-centered"); @@ -384,7 +397,7 @@ replaceTxt(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); if (elements.length > 0) { - elements.forEach((element) => { element.innerHTML = args.TXT.replace(/\n/g, "
"); }); + elements.forEach((element) => { element.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
") }); } else { this.printTxt(args); } From fe5f45e33e9c4a87aff91beb01da3e22b7cfcf56 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Tue, 19 Dec 2023 20:34:03 -0800 Subject: [PATCH 07/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index b4a980e7b4..09201eba08 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.1.0 +// Version V.1.1.1 (function (Scratch) { "use strict"; @@ -37,6 +37,10 @@ }; class SPdisText { + constructor() { + Scratch.vm.runtime.on("PROJECT_START", () => { this.removeAllTxt() }); + Scratch.vm.runtime.on("PROJECT_STOP_ALL", () => { this.removeAllTxt() }); + } getInfo() { return { id: "SPdisText", From de3c3dd1aaa9ca498aa240f2d12cd4a109ce75cb Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 27 Dec 2023 19:48:10 -0800 Subject: [PATCH 08/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 09201eba08..e349180aaf 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.1.1 +// Version V.1.1.2 (function (Scratch) { "use strict"; @@ -373,6 +373,11 @@ return [...fontMenu, ...customFonts]; } + isScreen() { + const values = [parseFloat(Scratch.vm.renderer.canvas.style.width), Scratch.vm.runtime.stageWidth]; + return values[0] > values[1] ? [3.78, 7] : [2, 2]; + } + printTxt(args) { args.ID = args.ID.replaceAll(" ", "_"); const newTextElement = document.createElement("div"); @@ -543,8 +548,8 @@ elements.forEach((element) => { const box = element.getBoundingClientRect(); element.style.position = "absolute"; - element.style.left = `${args.X - (box.width / 2)}px`; - element.style.top = `${(args.Y * -1) - (box.height / 2)}px`; + element.style.left = `${args.X - (box.width / this.isScreen()[0])}px`; + element.style.top = `${(args.Y * -1) - (box.height / this.isScreen()[1])}px`; }); } From 28c663b93e26482a3e87675306fbd556d09b4f84 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:19:54 -0800 Subject: [PATCH 09/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 65 ++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index e349180aaf..20d246ecaa 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.1.2 +// Version V.1.2.0 (function (Scratch) { "use strict"; @@ -14,6 +14,7 @@ const blockIconURI = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI0OS42MjQ0MSIgaGVpZ2h0PSI0OS42MjQ0MSIgdmlld0JveD0iMCwwLDQ5LjYyNDQxLDQ5LjYyNDQxIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjE1LjE4NzgsLTE1NS4xODc4KSI+PGcgZGF0YS1wYXBlci1kYXRhPSJ7JnF1b3Q7aXNQYWludGluZ0xheWVyJnF1b3Q7OnRydWV9IiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48cGF0aCBkPSJNMjE1LjE4NzgsMjA0LjgxMjJ2LTQ5LjYyNDQxaDQ5LjYyNDQxdjQ5LjYyNDQxeiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxLjYyNjMxYzAuNTEyNzIsMCAwLjkyODM2LDAuNDE1NjQgMC45MjgzNiwwLjkyODM2djEzLjYxMTk5YzAsMC41MTI3MiAtMC40MTU2NCwwLjkyODM2IC0wLjkyODM2LDAuOTI4MzZoLTEuNjI2MzFjLTAuNTEyNzIsMCAtMC45MjgzNiwtMC40MTU2NCAtMC45MjgzNiwtMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L2c+PC9nPjwvc3ZnPg=="; + const render = Scratch.vm.renderer; let allText = []; let lastRecdVals = {}; @@ -129,6 +130,15 @@ SIZE: { type: Scratch.ArgumentType.NUMBER, defaultValue: 30 } }, }, + { + opcode: "setThick", + blockType: Scratch.BlockType.COMMAND, + text: "set boldness of ID [ID] to [NUM]", + arguments: { + NUM : { type: Scratch.ArgumentType.NUMBER, defaultValue: 100 }, + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + } + }, { opcode: "setTextAlignment", blockType: Scratch.BlockType.COMMAND, @@ -333,6 +343,11 @@ POS: ["x position", "y position", "z layer"], OVERFLOW: ["visible", "hidden"], ARCS: ["circle", "hill", "dip", "wave"], + THICK: [ + { text : "thick", value : "900" }, + { text : "medium", value : "600" }, + { text : "none", value : "1" }, + ], FORMATS: { acceptReporters: true, items: [ @@ -375,7 +390,7 @@ isScreen() { const values = [parseFloat(Scratch.vm.renderer.canvas.style.width), Scratch.vm.runtime.stageWidth]; - return values[0] > values[1] ? [3.78, 7] : [2, 2]; + return values[0] > values[1] || Scratch.vm.runtime.isPackaged; } printTxt(args) { @@ -397,8 +412,9 @@ if (lastRecdVals["lineDIS"]) this.setTextSpacing(lastRecdVals["lineDIS"].inputs); if (lastRecdVals["letDIS"]) this.setTextSpacing(lastRecdVals["letDIS"].inputs); if (lastRecdVals["textOVR"]) this.setOverflow(lastRecdVals["textOVR"].inputs); - if (lastRecdVals["preTxt1"]) this.presetTextPosition(lastRecdVals["preTxt1"].inputs,); + if (lastRecdVals["txtFontTK"]) this.setThick(lastRecdVals["txtFontTK"].inputs); + if (lastRecdVals["preTxt1"]) this.presetTextPosition(lastRecdVals["preTxt1"].inputs); const box = newTextElement.getBoundingClientRect(); this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); } @@ -521,6 +537,12 @@ lastRecdVals["txtFontSZ"] = {inputs: args}; } + setThick(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { element.style.fontWeight = args.NUM * 9 }); + lastRecdVals["txtFontTK"] = {inputs: args}; + } + setTextSpacing(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { @@ -534,12 +556,19 @@ if (args.isPrint === undefined) { lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; } else { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); - const element = elements[elements.length - 1]; - const box = element.getBoundingClientRect(); - element.style.position = "absolute"; - element.style.left = `${(args.X - (box.width / 2)) + (parseFloat(Scratch.vm.renderer.canvas.style.width) / 2)}px`; - element.style.top = `${(args.Y * -1) - (box.height / 2)}px`; + setTimeout(function() { + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const element = elements[elements.length - 1]; + const box = element.getBoundingClientRect(); + const transformValue = element.parentNode.style.transform; + const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); + const scales = [parseFloat(match[1]), parseFloat(match[2])]; + const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; + const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; + element.style.position = "absolute"; + element.style.left = `${args.X - centerW}px`; + element.style.top = `${(args.Y * -1) - centerH}px`; + }.bind(this), 0); } } @@ -547,9 +576,14 @@ const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { const box = element.getBoundingClientRect(); + const transformValue = element.parentNode.style.transform; + const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); + const scales = [parseFloat(match[1]), parseFloat(match[2])]; + const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; + const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; element.style.position = "absolute"; - element.style.left = `${args.X - (box.width / this.isScreen()[0])}px`; - element.style.top = `${(args.Y * -1) - (box.height / this.isScreen()[1])}px`; + element.style.left = `${args.X - centerW}px`; + element.style.top = `${(args.Y * -1) - centerH}px`; }); } @@ -558,14 +592,19 @@ let value; elements.forEach((element) => { const box = element.getBoundingClientRect(); + const transformValue = element.parentNode.style.transform; + const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); + const scales = [parseFloat(match[1]), parseFloat(match[2])]; + const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; + const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; if (args.ATT === "z layer") { value = element.parentNode.style.zIndex; } else { value = parseFloat(element.style[args.ATT.includes("x") ? "left" : "top"]); - value = ((box[args.ATT.includes("x") ? "width" : "height"] / 2) + value) * (args.ATT.includes("x") ? 1 : -1); + value = ((args.ATT.includes("x") ? centerW : centerH) + value) * (args.ATT.includes("x") ? 1 : -1); } }); - return value || 0; + return Math.round(value * 100) / 100 || 0; } attOfText(args) { From b8e2349a4047ea2a885b084dd1aeab0559a98448 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:25:08 -0800 Subject: [PATCH 10/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 20d246ecaa..e02dc6e519 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -353,6 +353,7 @@ items: [ { text: "font", value: "fontFamily" }, { text: "font size", value: "fontSize" }, + { text: "boldness", value: "fontWeight" }, { text: "alignment", value: "textAlign" }, { text: "margin width", value: "width" }, { text: "margin height", value: "height" }, @@ -612,6 +613,7 @@ let value; elements.forEach((element) => { value = element.style[args.ATT] }); value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); + value = args.ATT === "fontWeight" ? value / 9 : value return value || ""; } From 8c1023996f9bba1fc8ba9596e1ed7a955ced7292 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sat, 6 Jan 2024 16:29:46 -0800 Subject: [PATCH 11/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 40 +++++++++++----------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index e02dc6e519..1c079e179e 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.2.0 +// Version V.1.2.1 (function (Scratch) { "use strict"; @@ -389,11 +389,6 @@ return [...fontMenu, ...customFonts]; } - isScreen() { - const values = [parseFloat(Scratch.vm.renderer.canvas.style.width), Scratch.vm.runtime.stageWidth]; - return values[0] > values[1] || Scratch.vm.runtime.isPackaged; - } - printTxt(args) { args.ID = args.ID.replaceAll(" ", "_"); const newTextElement = document.createElement("div"); @@ -560,12 +555,11 @@ setTimeout(function() { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); const element = elements[elements.length - 1]; - const box = element.getBoundingClientRect(); - const transformValue = element.parentNode.style.transform; - const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); - const scales = [parseFloat(match[1]), parseFloat(match[2])]; - const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; - const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; + const centerW = parseFloat(element.style.width) / 2; + const computedStyle = window.getComputedStyle(element); + const lineHeight = computedStyle.getPropertyValue("line-height"); + const fontSize = computedStyle.getPropertyValue("font-size"); + const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; element.style.position = "absolute"; element.style.left = `${args.X - centerW}px`; element.style.top = `${(args.Y * -1) - centerH}px`; @@ -576,12 +570,11 @@ setTextPosition(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { - const box = element.getBoundingClientRect(); - const transformValue = element.parentNode.style.transform; - const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); - const scales = [parseFloat(match[1]), parseFloat(match[2])]; - const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; - const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; + const centerW = parseFloat(element.style.width) / 2; + const computedStyle = window.getComputedStyle(element); + const lineHeight = computedStyle.getPropertyValue("line-height"); + const fontSize = computedStyle.getPropertyValue("font-size"); + const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; element.style.position = "absolute"; element.style.left = `${args.X - centerW}px`; element.style.top = `${(args.Y * -1) - centerH}px`; @@ -592,12 +585,11 @@ const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); let value; elements.forEach((element) => { - const box = element.getBoundingClientRect(); - const transformValue = element.parentNode.style.transform; - const match = transformValue.match(/scale\(([^,]+),\s*([^)]+)\)/); - const scales = [parseFloat(match[1]), parseFloat(match[2])]; - const centerW = this.isScreen() ? box.width / 2 / scales[0] : box.width / 2; - const centerH = this.isScreen() ? box.height / 2 / (scales[1] * scales[1]): box.height / 2; + const centerW = parseFloat(element.style.width) / 2; + const computedStyle = window.getComputedStyle(element); + const lineHeight = computedStyle.getPropertyValue("line-height"); + const fontSize = computedStyle.getPropertyValue("font-size"); + const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; if (args.ATT === "z layer") { value = element.parentNode.style.zIndex; } else { From 6205857a8a49cfabc5d9af23193b8e11f5add774 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sun, 14 Jan 2024 20:01:10 -0800 Subject: [PATCH 12/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 58 +++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 1c079e179e..de2323d958 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.2.1 +// Version V.1.3.0 (function (Scratch) { "use strict"; @@ -111,6 +111,15 @@ blockType: Scratch.BlockType.REPORTER, text: "all text IDs" }, + "---", + { + opcode: "debug", + blockType: Scratch.BlockType.COMMAND, + text: "toggle debug mode [TOGGLE]", + arguments: { + TOGGLE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } + }, + }, { blockType: Scratch.BlockType.LABEL, text: "Formatting" }, { opcode: "setTextFont", @@ -227,6 +236,18 @@ THICKNESS: { type: Scratch.ArgumentType.NUMBER, defaultValue: 3 } }, }, + { + opcode: "setLine", + blockType: Scratch.BlockType.COMMAND, + text: "set text line of ID [ID] to [TYPE1] [TYPE2] colored [COLOR] thickness [THICK]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TYPE1: { type: Scratch.ArgumentType.STRING, menu: "STYLE" }, + TYPE2: { type: Scratch.ArgumentType.STRING, menu: "LINE_TYPE" }, + COLOR: { type: Scratch.ArgumentType.COLOR, defaultValue: "#ff0000" }, + THICK: { type: Scratch.ArgumentType.NUMBER, defaultValue: 2 } + }, + }, "---", { opcode: "makeGradient", @@ -327,10 +348,19 @@ }, ], menus: { + TOGGLE: ["on", "off"], FONTS: { acceptReporters: true, items: "allFonts" }, + STYLE: { + acceptReporters: true, + items: ["solid", "wavy", "dashed", "double"] + }, + LINE_TYPE: { + acceptReporters: true, + items: ["underline", "strikethrough"] + }, ALIGNMENTS: { acceptReporters: true, items: ["left", "right", "center"] @@ -389,6 +419,17 @@ return [...fontMenu, ...customFonts]; } + debug(args) { + const toggle = args.TOGGLE === "on" ? "solid" : "none"; + const elements = document.querySelectorAll(`[id^="SP_Text-Ext-"]`); + elements.forEach((element) => { + element.style.border = toggle; + element.style.borderWidth = "1px"; + const color = element.style.textAlign === "center" ? "#00ff00" : element.style.textAlign === "right" ? "#0000ff" : "#ff0000"; + element.style.borderColor = color; + }); + } + printTxt(args) { args.ID = args.ID.replaceAll(" ", "_"); const newTextElement = document.createElement("div"); @@ -409,6 +450,7 @@ if (lastRecdVals["letDIS"]) this.setTextSpacing(lastRecdVals["letDIS"].inputs); if (lastRecdVals["textOVR"]) this.setOverflow(lastRecdVals["textOVR"].inputs); if (lastRecdVals["txtFontTK"]) this.setThick(lastRecdVals["txtFontTK"].inputs); + if (lastRecdVals["textLIN"]) this.setLine(lastRecdVals["textLIN"].inputs); if (lastRecdVals["preTxt1"]) this.presetTextPosition(lastRecdVals["preTxt1"].inputs); const box = newTextElement.getBoundingClientRect(); @@ -427,7 +469,7 @@ removeTxt(args) { const elementsToRemove = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elementsToRemove.forEach((element) => { - render.removeOverlay(element) + render.removeOverlay(element); const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); if (index !== -1) allText.splice(index, 1); }); @@ -507,6 +549,18 @@ lastRecdVals["textOUT"] = {inputs: args}; } + setLine(args) { + const lineType = args.TYPE2.replace("strike", "line-"); + const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + elements.forEach((element) => { + element.style.textDecorationLine = lineType; + element.style.textDecorationStyle = args.TYPE1; + element.style.textDecorationThickness = `${args.THICK}px`; + element.style.textDecorationColor = args.COLOR; + }); + lastRecdVals["textLIN"] = {inputs: args}; + } + setMargins(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elements.forEach((element) => { From 41b9f7b811d05ef3d75aa937fa9a66ea68abe025 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 17 Jan 2024 20:26:35 -0800 Subject: [PATCH 13/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 142 ++++++++++++++++----------- 1 file changed, 84 insertions(+), 58 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index de2323d958..024daf5974 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.3.0 +// Version V.1.3.1 (function (Scratch) { "use strict"; @@ -101,7 +101,7 @@ { opcode: "existingID", blockType: Scratch.BlockType.BOOLEAN, - text: "does text with ID [ID] exist?", + text: "text with ID [ID] exist?", arguments: { ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, @@ -260,7 +260,7 @@ TYPE: { type: Scratch.ArgumentType.STRING, menu: "GRADIENTS" } }, }, - "---", + { blockType: Scratch.BlockType.LABEL, text: "↓ Will Lose Some Formatting ↓" }, { opcode: "setTextCurve", blockType: Scratch.BlockType.COMMAND, @@ -367,7 +367,7 @@ }, TEXT_ATT: ["letter", "line"], GRADIENTS: { - acceptReporters: true, // conic gradients exist but are complex + acceptReporters: true, items: ["linear", "radial"] }, POS: ["x position", "y position", "z layer"], @@ -419,6 +419,11 @@ return [...fontMenu, ...customFonts]; } + fixID(ID) { + return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_") + .replaceAll(/[#%(),.{}[\]$@^*&'";:]/g, "-")); + } + debug(args) { const toggle = args.TOGGLE === "on" ? "solid" : "none"; const elements = document.querySelectorAll(`[id^="SP_Text-Ext-"]`); @@ -428,37 +433,55 @@ const color = element.style.textAlign === "center" ? "#00ff00" : element.style.textAlign === "right" ? "#0000ff" : "#ff0000"; element.style.borderColor = color; }); + const cross = document.getElementById(`SP_Text-Debug-Cross`); + if (toggle === "none" && cross) { + cross.parentNode.removeChild(cross); + } else if (toggle === "solid" && !cross) { + const imageUrl = + "data:image/png;base64,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"; + const crossElement = document.createElement("img"); + crossElement.src = imageUrl; + crossElement.id = "SP_Text-Debug-Cross"; + crossElement.style.position = "absolute"; + crossElement.style.width = "480px"; + crossElement.style.height = "360px"; + crossElement.style.transform = "translate(-50%, -50%)"; + crossElement.style.zIndex = "0"; + render.addOverlay(crossElement, "scale-centered"); + allText.push(`#SP_Text-Debug-Cross`); + } } printTxt(args) { - args.ID = args.ID.replaceAll(" ", "_"); + args.ID = this.fixID(args.ID); const newTextElement = document.createElement("div"); newTextElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); newTextElement.id = `SP_Text-Ext-${args.ID}`; newTextElement.classList.add(args.ID); render.addOverlay(newTextElement, "scale-centered"); allText.push(`#SP_Text-Ext-${args.ID}`); + const box = newTextElement.getBoundingClientRect(); + if (!lastRecdVals.textMAR) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); // add formatting (if any) - if (lastRecdVals["textCLR"]) this.setTextColor(lastRecdVals["textCLR"].inputs); - if (lastRecdVals["textOUT"]) this.setTextOutline(lastRecdVals["textOUT"].inputs); - if (lastRecdVals["textSHA"]) this.setTextDropShadow(lastRecdVals["textSHA"].inputs); - if (lastRecdVals["txtFont"]) this.setTextFont(lastRecdVals["txtFont"].inputs); - if (lastRecdVals["txtFontSZ"]) this.setFontSize(lastRecdVals["txtFontSZ"].inputs); - if (lastRecdVals["txtALI"]) this.setTextAlignment(lastRecdVals["txtALI"].inputs); - if (lastRecdVals["lineDIS"]) this.setTextSpacing(lastRecdVals["lineDIS"].inputs); - if (lastRecdVals["letDIS"]) this.setTextSpacing(lastRecdVals["letDIS"].inputs); - if (lastRecdVals["textOVR"]) this.setOverflow(lastRecdVals["textOVR"].inputs); - if (lastRecdVals["txtFontTK"]) this.setThick(lastRecdVals["txtFontTK"].inputs); - if (lastRecdVals["textLIN"]) this.setLine(lastRecdVals["textLIN"].inputs); - - if (lastRecdVals["preTxt1"]) this.presetTextPosition(lastRecdVals["preTxt1"].inputs); - const box = newTextElement.getBoundingClientRect(); - this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); + const propertiesAndMethods = [ + ["textMAR", "setMargins"], ["preTxt1", "presetTextPosition"], + ["textCLR", "setTextColor"], ["textLIN", "setLine"], + ["textOUT", "setTextOutline"], ["textSHA", "setTextDropShadow"], + ["txtFont", "setTextFont"], ["txtFontSZ", "setFontSize"], + ["txtALI", "setTextAlignment"], ["lineDIS", "setTextSpacing"], + ["letDIS", "setTextSpacing"], ["textOVR", "setOverflow"], + ["txtFontTK", "setThick"] + ]; + for (const [property, method] of propertiesAndMethods) { + if (lastRecdVals[property] && lastRecdVals[property].inputs.ID === args.ID) { + this[method](lastRecdVals[property].inputs); + } + } } replaceTxt(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); if (elements.length > 0) { elements.forEach((element) => { element.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
") }); } else { @@ -467,6 +490,7 @@ } removeTxt(args) { + args.ID = this.fixID(args.ID); const elementsToRemove = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elementsToRemove.forEach((element) => { render.removeOverlay(element); @@ -485,7 +509,7 @@ displayedTexts(args) { let texts = []; - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { texts.push(element.textContent) }); return JSON.stringify(texts); } @@ -496,14 +520,14 @@ } existingID(args) { - const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); + const index = allText.indexOf(`#SP_Text-Ext-${this.fixID(args.ID)}`); return Scratch.Cast.toBoolean(allText[index]); } makeGradient(args) { return `${args.TYPE}-gradient(${args.ANGLE}deg, ${args.COLOR1}, ${args.COLOR2})` } setTextColor(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.color = args.COLOR; if (args.COLOR.includes("gradient")) { @@ -522,7 +546,7 @@ } setTextDropShadow(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.textShadow = args.z === 0 ? "none" : `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; }); @@ -530,13 +554,13 @@ } setOverflow(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.overflow = args.TYPE }); lastRecdVals["textOVR"] = {inputs: args}; } setTextOutline(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.webkitTextStrokeColor = args.COLOR; element.style.webkitTextStrokeWidth = `${args.THICKNESS}px`; @@ -551,7 +575,7 @@ setLine(args) { const lineType = args.TYPE2.replace("strike", "line-"); - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.textDecorationLine = lineType; element.style.textDecorationStyle = args.TYPE1; @@ -562,39 +586,40 @@ } setMargins(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.width = `${args.WIDTH}px`; element.style.height = `${args.HEIGHT}px`; }); + lastRecdVals["textMAR"] = {inputs: args}; } setTextAlignment(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.textAlign = args.ALIGNMENT }); lastRecdVals["txtALI"] = {inputs: args}; } setTextFont(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.fontFamily = args.FONT }); lastRecdVals["txtFont"] = {inputs: args}; } setFontSize(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.fontSize = `${args.SIZE}px` }); lastRecdVals["txtFontSZ"] = {inputs: args}; } setThick(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style.fontWeight = args.NUM * 9 }); lastRecdVals["txtFontTK"] = {inputs: args}; } setTextSpacing(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.style[args.ATT === "letter" ? "letterSpacing" : "lineHeight"] = `${args.SPACING}px`; }); @@ -607,7 +632,7 @@ lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; } else { setTimeout(function() { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); const element = elements[elements.length - 1]; const centerW = parseFloat(element.style.width) / 2; const computedStyle = window.getComputedStyle(element); @@ -622,7 +647,7 @@ } setTextPosition(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { const centerW = parseFloat(element.style.width) / 2; const computedStyle = window.getComputedStyle(element); @@ -636,7 +661,7 @@ } textPosition(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); let value; elements.forEach((element) => { const centerW = parseFloat(element.style.width) / 2; @@ -655,7 +680,7 @@ } attOfText(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); let value; elements.forEach((element) => { value = element.style[args.ATT] }); value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); @@ -664,7 +689,7 @@ } lineCnt(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); let value = []; elements.forEach((element) => { value.push(element.querySelectorAll("br").length + 1 || 1); @@ -674,68 +699,68 @@ } setTextZIndex(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { element.parentNode.style.zIndex = Math.round(args.Z_INDEX) }); } setEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { - const currentStyleArray = [ + const curStyles = [ element.style.filter || "", element.parentNode.style.transform || "", element.style.opacity || "" ]; const regex = new RegExp(`${args.EFFECT}\\([^)]+\\)`, "g"); - currentStyleArray.forEach((currentStyle, index) => { - currentStyleArray[index] = currentStyle.replace(regex, ""); + curStyles.forEach((curStyle, index) => { + curStyles[index] = curStyle.replace(regex, ""); }); switch (args.EFFECT) { case "saturate": - element.style.filter = `${currentStyleArray[0]} saturate(${args.VALUE}%)`; + element.style.filter = `${curStyles[0]} saturate(${args.VALUE}%)`; break; case "contrast": - element.style.filter = `${currentStyleArray[0]} contrast(${args.VALUE + 100}%)`; + element.style.filter = `${curStyles[0]} contrast(${args.VALUE + 100}%)`; break; case "brightness": - element.style.filter = `${currentStyleArray[0]} brightness(${args.VALUE + 100}%)`; + element.style.filter = `${curStyles[0]} brightness(${args.VALUE + 100}%)`; break; case "hue-rotate": - element.style.filter = `${currentStyleArray[0]} hue-rotate(${args.VALUE}deg)`; + element.style.filter = `${curStyles[0]} hue-rotate(${args.VALUE}deg)`; break; case "opacity": element.style.opacity = (100 - args.VALUE) / 100; break; case "sepia": - element.style.filter = `${currentStyleArray[0]} sepia(${args.VALUE}%)`; + element.style.filter = `${curStyles[0]} sepia(${args.VALUE}%)`; break; case "invert": - element.style.filter = `${currentStyleArray[0]} invert(${args.VALUE}%)`; + element.style.filter = `${curStyles[0]} invert(${args.VALUE}%)`; break; case "rotate": - element.parentNode.style.transform = `${currentStyleArray[1]} rotate(${args.VALUE - 90}deg)`; + element.parentNode.style.transform = `${curStyles[1]} rotate(${args.VALUE - 90}deg)`; break; case "scaleX": - element.parentNode.style.transform = `${currentStyleArray[1]} scaleX(${args.VALUE / 100})`; + element.parentNode.style.transform = `${curStyles[1]} scaleX(${args.VALUE / 100})`; break; case "scaleY": - element.parentNode.style.transform = `${currentStyleArray[1]} scaleY(${args.VALUE / 100})`; + element.parentNode.style.transform = `${curStyles[1]} scaleY(${args.VALUE / 100})`; break; case "skewX": - element.parentNode.style.transform = `${currentStyleArray[1]} skewX(${args.VALUE}deg)`; + element.parentNode.style.transform = `${curStyles[1]} skewX(${args.VALUE}deg)`; break; case "skewY": - element.parentNode.style.transform = `${currentStyleArray[1]} skewY(${args.VALUE}deg)`; + element.parentNode.style.transform = `${curStyles[1]} skewY(${args.VALUE}deg)`; break; default: - element.style.filter = `${currentStyleArray[0]} blur(${args.VALUE}px)`; + element.style.filter = `${curStyles[0]} blur(${args.VALUE}px)`; break; } }); } resetEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { const currentTransform = element.parentNode.style.transform || ""; const updatedTransform = currentTransform @@ -751,7 +776,7 @@ } amtOfEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); let effectValue = args.EFFECT === "rotate" ? 90 : args.EFFECT.includes("scale") ? 100 : 0; elements.forEach((element) => { if (args.EFFECT === "rotate" || args.EFFECT.includes("scale") || args.EFFECT.includes("skew")) { @@ -779,6 +804,7 @@ } setTextCurve(args) { + args.ID = this.fixID(args.ID) const regex = args.ARC.includes("]*d="([^"]*)"/ : /]*d="([^"]*)"/; const match = args.ARC.match(regex); const outline = lastRecdVals["textOUT"] !== undefined ? lastRecdVals["textOUT"] : ""; From 327ae382dbc5a5e7f343d611fe144d68253e1bca Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:05:38 -0800 Subject: [PATCH 14/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 024daf5974..ab1bb1ea61 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.3.1 +// Version V.1.3.2 (function (Scratch) { "use strict"; @@ -387,6 +387,8 @@ { text: "alignment", value: "textAlign" }, { text: "margin width", value: "width" }, { text: "margin height", value: "height" }, + { text: "display width", value: "box2w" }, + { text: "display height", value: "box2h" }, { text: "letter spacing", value: "letterSpacing" }, { text: "line spacing", value: "lineHeight" }, { text: "overflow type", value: "overflow" } @@ -682,10 +684,25 @@ attOfText(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); let value; - elements.forEach((element) => { value = element.style[args.ATT] }); - value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); - value = args.ATT === "fontWeight" ? value / 9 : value - return value || ""; + if (args.ATT.includes("box2")) { + const calcs = []; + elements.forEach((element) => { + const tempSpan = document.createElement("span"); + tempSpan.innerHTML = element.textContent; + tempSpan.style.fontSize = element.style.fontSize; + tempSpan.style.fontFamily = getComputedStyle(element).fontFamily; + tempSpan.style.display = "inline"; + document.body.appendChild(tempSpan); + calcs.push(tempSpan[`offset${args.ATT.includes("w") ? "Width" : "Height"}`]); + document.body.removeChild(tempSpan); + }); + return JSON.stringify(calcs); + } else { + elements.forEach((element) => { value = element.style[args.ATT] }); + value = args.ATT === "fontFamily" || args.ATT === "textAlign" || args.ATT === "overflow" ? value : parseFloat(value); + value = args.ATT === "fontWeight" ? value / 9 : value; + return value || ""; + } } lineCnt(args) { From b3c46a5fc43a25e08c4fcbf22fe9ae6234e96b25 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Tue, 27 Feb 2024 21:27:49 -0800 Subject: [PATCH 15/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index ab1bb1ea61..785b39c8bf 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.3.2 +// Version V.1.3.3 (function (Scratch) { "use strict"; @@ -19,8 +19,7 @@ let allText = []; let lastRecdVals = {}; const fontMenu = [ - "Scratch", "Sans Serif", - "Serif", "Handwriting", + "Sans Serif", "Serif", "Handwriting", "Marker", "Curly", "Pixel" ]; @@ -423,7 +422,7 @@ fixID(ID) { return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_") - .replaceAll(/[#%(),.{}[\]$@^*&'";:]/g, "-")); + .replaceAll(/[#%(),.{}[\/\]$@^*&'";:]/g, "-")); } debug(args) { @@ -463,7 +462,7 @@ render.addOverlay(newTextElement, "scale-centered"); allText.push(`#SP_Text-Ext-${args.ID}`); const box = newTextElement.getBoundingClientRect(); - if (!lastRecdVals.textMAR) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); + if (lastRecdVals.textMAR === undefined) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); // add formatting (if any) const propertiesAndMethods = [ @@ -518,6 +517,8 @@ allIDs() { const cleanedIDs = allText.map((item) => item.replace(/^#SP_Text-Ext-/, "")); + let index = cleanedIDs.indexOf("#SP_Text-Debug-Cross"); + if (index !== -1) cleanedIDs.splice(index, 1); return JSON.stringify(cleanedIDs); } From 33fae31e345f9db045d7243cdd241e1ed98c9407 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Tue, 27 Feb 2024 21:29:29 -0800 Subject: [PATCH 16/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 785b39c8bf..dea4cec599 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -422,7 +422,7 @@ fixID(ID) { return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_") - .replaceAll(/[#%(),.{}[\/\]$@^*&'";:]/g, "-")); + .replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); } debug(args) { From b5f9df79b32e3d152b4527d22734ae36d0378fee Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 13 Mar 2024 22:22:44 -0700 Subject: [PATCH 17/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index dea4cec599..27f752dc0d 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.3.3 +// Version V.1.3.4 (function (Scratch) { "use strict"; @@ -517,8 +517,9 @@ allIDs() { const cleanedIDs = allText.map((item) => item.replace(/^#SP_Text-Ext-/, "")); - let index = cleanedIDs.indexOf("#SP_Text-Debug-Cross"); - if (index !== -1) cleanedIDs.splice(index, 1); + for (let i = cleanedIDs.length - 1; i >= 0; i--) { + if (cleanedIDs[i] === "#SP_Text-Debug-Cross") cleanedIDs.splice(i, 1); + } return JSON.stringify(cleanedIDs); } @@ -652,7 +653,8 @@ setTextPosition(args) { const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); elements.forEach((element) => { - const centerW = parseFloat(element.style.width) / 2; + let centerW = parseFloat(element.style.width) / 2; + if (isNaN(centerW)) centerW = (element.getBoundingClientRect().width ?? 0 ) / 2; const computedStyle = window.getComputedStyle(element); const lineHeight = computedStyle.getPropertyValue("line-height"); const fontSize = computedStyle.getPropertyValue("font-size"); From 61f6fd1c65e72ee3a7089474789b0959fb7af549 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sun, 12 May 2024 00:18:50 -0700 Subject: [PATCH 18/25] Update Display-Text.js --- extensions/SharkPool/Display-Text.js | 97 +++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 27f752dc0d..1c356867dc 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.3.4 +// Version V.1.4.0 (function (Scratch) { "use strict"; @@ -17,10 +17,11 @@ const render = Scratch.vm.renderer; let allText = []; + let clickedTxts = []; let lastRecdVals = {}; const fontMenu = [ - "Sans Serif", "Serif", "Handwriting", - "Marker", "Curly", "Pixel" + "Scratch", "Sans Serif", "Serif", + "Handwriting", "Marker", "Curly", "Pixel" ]; const xmlEscape = function (unsafe) { @@ -83,6 +84,14 @@ ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, }, + { + opcode: "resetTxt", + blockType: Scratch.BlockType.COMMAND, + text: "reset text settings with ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, { opcode: "removeAllTxt", blockType: Scratch.BlockType.COMMAND, @@ -110,15 +119,6 @@ blockType: Scratch.BlockType.REPORTER, text: "all text IDs" }, - "---", - { - opcode: "debug", - blockType: Scratch.BlockType.COMMAND, - text: "toggle debug mode [TOGGLE]", - arguments: { - TOGGLE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } - }, - }, { blockType: Scratch.BlockType.LABEL, text: "Formatting" }, { opcode: "setTextFont", @@ -203,7 +203,7 @@ ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, }, - { blockType: Scratch.BlockType.LABEL, text: "Text Visuals" }, + "---", { opcode: "setTextColor", blockType: Scratch.BlockType.COMMAND, @@ -345,6 +345,32 @@ ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, }, + { blockType: Scratch.BlockType.LABEL, text: "Advanced" }, + { + opcode: "debug", + blockType: Scratch.BlockType.COMMAND, + text: "toggle debug mode [TOGGLE]", + arguments: { + TOGGLE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } + }, + }, + { + opcode: "makeClick", + blockType: Scratch.BlockType.COMMAND, + text: "toggle clicking for ID [ID] [TYPE]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } + }, + }, + { + opcode: "isClicked", + blockType: Scratch.BlockType.BOOLEAN, + text: "ID [ID] clicked?", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + } ], menus: { TOGGLE: ["on", "off"], @@ -408,7 +434,7 @@ { text: "scale x", value: "scaleX" }, { text: "scale y", value: "scaleY" }, { text: "skew x", value: "skewX" }, - { text: "skew y", value: "skewY" }, + { text: "skew y", value: "skewY" } ] } } @@ -455,11 +481,14 @@ printTxt(args) { args.ID = this.fixID(args.ID); + const textDiv = document.createElement("div"); + textDiv.style.transformOrigin = "left top"; const newTextElement = document.createElement("div"); newTextElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); newTextElement.id = `SP_Text-Ext-${args.ID}`; newTextElement.classList.add(args.ID); - render.addOverlay(newTextElement, "scale-centered"); + textDiv.appendChild(newTextElement); + render.addOverlay(textDiv, "scale-centered"); allText.push(`#SP_Text-Ext-${args.ID}`); const box = newTextElement.getBoundingClientRect(); if (lastRecdVals.textMAR === undefined) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); @@ -494,18 +523,29 @@ args.ID = this.fixID(args.ID); const elementsToRemove = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); elementsToRemove.forEach((element) => { - render.removeOverlay(element); + render.removeOverlay(element.parentNode); + element.removeEventListener("click", this.handleClick); const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); if (index !== -1) allText.splice(index, 1); }); } + resetTxt(args) { + Object.keys(lastRecdVals).forEach(key => { + if (lastRecdVals[key].inputs.ID === args.ID) delete lastRecdVals[key]; + }); + } + removeAllTxt() { for (let i = 0; i < allText.length; i++) { const elementsToRemove = document.querySelectorAll(allText[i]); - elementsToRemove.forEach((element) => { render.removeOverlay(element) }); + elementsToRemove.forEach((element) => { + render.removeOverlay(element.parentNode) + element.removeEventListener("click", this.handleClick); + }); } allText = []; + clickedTxts = []; } displayedTexts(args) { @@ -890,6 +930,29 @@ }; return presets[args.ARC]; } + + makeClick(args) { + const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + elements.forEach((element) => { + if (args.TYPE === "on") { + element.style.pointerEvents = "auto"; + element.style.cursor = "pointer"; + } else { + element.style.pointerEvents = "none"; + element.style.cursor = "none"; + } + element.removeEventListener("click", this.handleClick); + if (args.TYPE === "on") element.addEventListener("click", this.handleClick); + }); + } + + isClicked(args) { return clickedTxts.indexOf(this.fixID(args.ID)) > -1 } + + handleClick(event) { + clickedTxts.push(event.target.className); + const index = clickedTxts.length - 1; + setTimeout(function() { clickedTxts.splice(index, 1) }, 100); + } } Scratch.extensions.register(new SPdisText()); From 850e4ab48d3338bbb0b91fc1fd4a4f372b233361 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:04:06 -0700 Subject: [PATCH 19/25] Display-Text -- Boost Speed and Fix Positioning Forever --- extensions/SharkPool/Display-Text.js | 144 ++++++++++++--------------- 1 file changed, 62 insertions(+), 82 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 1c356867dc..1e04fb72cb 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,11 +3,11 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.4.0 +// Version V.1.4.1 (function (Scratch) { "use strict"; - if (!Scratch.extensions.unsandboxed) throw new Error("Display Text Extension must run unsandboxed!"); + if (!Scratch.extensions.unsandboxed) throw new Error("Display Text must run unsandboxed!"); const menuIconURI = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI2NS4yMzM5NiIgaGVpZ2h0PSI2NS4yMzM5NiIgdmlld0JveD0iMCwwLDY1LjIzMzk2LDY1LjIzMzk2Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjA3LjM4MzAyLC0xNDcuMzgzMDIpIj48ZyBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpc1BhaW50aW5nTGF5ZXImcXVvdDs6dHJ1ZX0iIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWRhc2hhcnJheT0iIiBzdHJva2UtZGFzaG9mZnNldD0iMCIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0yMDcuMzgzMDIsMTgwYzAsLTE4LjAxMzg2IDE0LjYwMzEyLC0zMi42MTY5OCAzMi42MTY5OCwtMzIuNjE2OThjMTguMDEzODYsMCAzMi42MTY5OCwxNC42MDMxMiAzMi42MTY5OCwzMi42MTY5OGMwLDE4LjAxMzg2IC0xNC42MDMxMiwzMi42MTY5OCAtMzIuNjE2OTgsMzIuNjE2OThjLTE4LjAxMzg2LDAgLTMyLjYxNjk4LC0xNC42MDMxMiAtMzIuNjE2OTgsLTMyLjYxNjk4eiIgZmlsbD0iIzNjNGU1YyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjEwLjc3MzYyLDE4MGMwLC0xNi4xNDEyOSAxMy4wODUxLC0yOS4yMjYzOCAyOS4yMjYzOCwtMjkuMjI2MzhjMTYuMTQxMjksMCAyOS4yMjYzOCwxMy4wODUxIDI5LjIyNjM4LDI5LjIyNjM4YzAsMTYuMTQxMjkgLTEzLjA4NTEsMjkuMjI2MzggLTI5LjIyNjM4LDI5LjIyNjM4Yy0xNi4xNDEyOSwwIC0yOS4yMjYzOCwtMTMuMDg1MSAtMjkuMjI2MzgsLTI5LjIyNjM4eiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmwxLjYyNjMxLDBjMC41MTI3MiwwIDAuOTI4MzYsMC40MTU2NCAwLjkyODM2LDAuOTI4MzZsMCwxMy42MTE5OWMwLDAuNTEyNzIgLTAuNDE1NjQsMC45MjgzNiAtMC45MjgzNiwwLjkyODM2aC0xLjYyNjMxYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMS41Ii8+PC9nPjwvZz48L3N2Zz4="; @@ -15,7 +15,9 @@ const blockIconURI = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI0OS42MjQ0MSIgaGVpZ2h0PSI0OS42MjQ0MSIgdmlld0JveD0iMCwwLDQ5LjYyNDQxLDQ5LjYyNDQxIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjE1LjE4NzgsLTE1NS4xODc4KSI+PGcgZGF0YS1wYXBlci1kYXRhPSJ7JnF1b3Q7aXNQYWludGluZ0xheWVyJnF1b3Q7OnRydWV9IiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48cGF0aCBkPSJNMjE1LjE4NzgsMjA0LjgxMjJ2LTQ5LjYyNDQxaDQ5LjYyNDQxdjQ5LjYyNDQxeiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxLjYyNjMxYzAuNTEyNzIsMCAwLjkyODM2LDAuNDE1NjQgMC45MjgzNiwwLjkyODM2djEzLjYxMTk5YzAsMC41MTI3MiAtMC40MTU2NCwwLjkyODM2IC0wLjkyODM2LDAuOTI4MzZoLTEuNjI2MzFjLTAuNTEyNzIsMCAtMC45MjgzNiwtMC40MTU2NCAtMC45MjgzNiwtMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L2c+PC9nPjwvc3ZnPg=="; - const render = Scratch.vm.renderer; + const vm = Scratch.vm; + const runtime = vm.runtime; + const render = vm.renderer; let allText = []; let clickedTxts = []; let lastRecdVals = {}; @@ -39,8 +41,8 @@ class SPdisText { constructor() { - Scratch.vm.runtime.on("PROJECT_START", () => { this.removeAllTxt() }); - Scratch.vm.runtime.on("PROJECT_STOP_ALL", () => { this.removeAllTxt() }); + runtime.on("PROJECT_START", () => { this.removeAllTxt() }); + runtime.on("PROJECT_STOP_ALL", () => { this.removeAllTxt() }); } getInfo() { return { @@ -58,10 +60,7 @@ text: "print text [TXT] with ID [ID]", arguments: { ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, - TXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: "hello world" - } + TXT: { type: Scratch.ArgumentType.STRING, defaultValue: "hello world" } }, }, { @@ -70,10 +69,7 @@ text: "replace text of ID [ID] with [TXT]", arguments: { ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, - TXT: { - type: Scratch.ArgumentType.STRING, - defaultValue: "lorem ipsum" - } + TXT: { type: Scratch.ArgumentType.STRING, defaultValue: "lorem ipsum" } }, }, { @@ -374,10 +370,7 @@ ], menus: { TOGGLE: ["on", "off"], - FONTS: { - acceptReporters: true, - items: "allFonts" - }, + FONTS: { acceptReporters: true, items: "allFonts" }, STYLE: { acceptReporters: true, items: ["solid", "wavy", "dashed", "double"] @@ -447,13 +440,12 @@ } fixID(ID) { - return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_") - .replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); + return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_").replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); } debug(args) { const toggle = args.TOGGLE === "on" ? "solid" : "none"; - const elements = document.querySelectorAll(`[id^="SP_Text-Ext-"]`); + const elements = document.querySelectorAll(`div[id^="SP_Text-Ext-"]`); elements.forEach((element) => { element.style.border = toggle; element.style.borderWidth = "1px"; @@ -461,9 +453,8 @@ element.style.borderColor = color; }); const cross = document.getElementById(`SP_Text-Debug-Cross`); - if (toggle === "none" && cross) { - cross.parentNode.removeChild(cross); - } else if (toggle === "solid" && !cross) { + if (toggle === "none" && cross) cross.parentNode.removeChild(cross); + else if (toggle === "solid" && !cross) { const imageUrl = "data:image/png;base64,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"; const crossElement = document.createElement("img"); @@ -483,14 +474,15 @@ args.ID = this.fixID(args.ID); const textDiv = document.createElement("div"); textDiv.style.transformOrigin = "left top"; - const newTextElement = document.createElement("div"); - newTextElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); - newTextElement.id = `SP_Text-Ext-${args.ID}`; - newTextElement.classList.add(args.ID); - textDiv.appendChild(newTextElement); + const txtElement = document.createElement("div"); + txtElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); + txtElement.id = `SP_Text-Ext-${args.ID}`; + txtElement.classList.add(args.ID); + txtElement.setAttribute("sptxtpos", "120|-10"); + textDiv.appendChild(txtElement); render.addOverlay(textDiv, "scale-centered"); allText.push(`#SP_Text-Ext-${args.ID}`); - const box = newTextElement.getBoundingClientRect(); + const box = txtElement.getBoundingClientRect(); if (lastRecdVals.textMAR === undefined) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); // add formatting (if any) @@ -511,17 +503,14 @@ } replaceTxt(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); - if (elements.length > 0) { - elements.forEach((element) => { element.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
") }); - } else { - this.printTxt(args); - } + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + if (elements.length > 0) elements.forEach((element) => { element.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
") }); + else this.printTxt(args); } removeTxt(args) { args.ID = this.fixID(args.ID); - const elementsToRemove = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elementsToRemove = document.querySelectorAll(`div[id="SP_Text-Ext-${args.ID}"]`); elementsToRemove.forEach((element) => { render.removeOverlay(element.parentNode); element.removeEventListener("click", this.handleClick); @@ -550,7 +539,7 @@ displayedTexts(args) { let texts = []; - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { texts.push(element.textContent) }); return JSON.stringify(texts); } @@ -571,7 +560,7 @@ makeGradient(args) { return `${args.TYPE}-gradient(${args.ANGLE}deg, ${args.COLOR1}, ${args.COLOR2})` } setTextColor(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.color = args.COLOR; if (args.COLOR.includes("gradient")) { @@ -590,7 +579,7 @@ } setTextDropShadow(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.textShadow = args.z === 0 ? "none" : `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; }); @@ -598,13 +587,13 @@ } setOverflow(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.overflow = args.TYPE }); lastRecdVals["textOVR"] = {inputs: args}; } setTextOutline(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.webkitTextStrokeColor = args.COLOR; element.style.webkitTextStrokeWidth = `${args.THICKNESS}px`; @@ -619,7 +608,7 @@ setLine(args) { const lineType = args.TYPE2.replace("strike", "line-"); - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.textDecorationLine = lineType; element.style.textDecorationStyle = args.TYPE1; @@ -630,7 +619,7 @@ } setMargins(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.width = `${args.WIDTH}px`; element.style.height = `${args.HEIGHT}px`; @@ -639,31 +628,31 @@ } setTextAlignment(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.textAlign = args.ALIGNMENT }); lastRecdVals["txtALI"] = {inputs: args}; } setTextFont(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.fontFamily = args.FONT }); lastRecdVals["txtFont"] = {inputs: args}; } setFontSize(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.fontSize = `${args.SIZE}px` }); lastRecdVals["txtFontSZ"] = {inputs: args}; } setThick(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style.fontWeight = args.NUM * 9 }); lastRecdVals["txtFontTK"] = {inputs: args}; } setTextSpacing(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.style[args.ATT === "letter" ? "letterSpacing" : "lineHeight"] = `${args.SPACING}px`; }); @@ -672,11 +661,10 @@ } presetTextPosition(args) { - if (args.isPrint === undefined) { - lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; - } else { - setTimeout(function() { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + if (args.isPrint === undefined) lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; + else { + setTimeout(() => { + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); const element = elements[elements.length - 1]; const centerW = parseFloat(element.style.width) / 2; const computedStyle = window.getComputedStyle(element); @@ -684,14 +672,14 @@ const fontSize = computedStyle.getPropertyValue("font-size"); const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; element.style.position = "absolute"; - element.style.left = `${args.X - centerW}px`; - element.style.top = `${(args.Y * -1) - centerH}px`; - }.bind(this), 0); + element.style.transform = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); + }, 0); } } setTextPosition(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { let centerW = parseFloat(element.style.width) / 2; if (isNaN(centerW)) centerW = (element.getBoundingClientRect().width ?? 0 ) / 2; @@ -700,13 +688,13 @@ const fontSize = computedStyle.getPropertyValue("font-size"); const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; element.style.position = "absolute"; - element.style.left = `${args.X - centerW}px`; - element.style.top = `${(args.Y * -1) - centerH}px`; + element.style.transform = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); }); } textPosition(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value; elements.forEach((element) => { const centerW = parseFloat(element.style.width) / 2; @@ -714,18 +702,14 @@ const lineHeight = computedStyle.getPropertyValue("line-height"); const fontSize = computedStyle.getPropertyValue("font-size"); const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; - if (args.ATT === "z layer") { - value = element.parentNode.style.zIndex; - } else { - value = parseFloat(element.style[args.ATT.includes("x") ? "left" : "top"]); - value = ((args.ATT.includes("x") ? centerW : centerH) + value) * (args.ATT.includes("x") ? 1 : -1); - } + if (args.ATT === "z layer") value = element.parentNode.style.zIndex; + else value = element.getAttribute("sptxtpos")?.split("|", 2)[args.ATT.includes("x") ? 0 : 1]; }); - return Math.round(value * 100) / 100 || 0; + return value || 0; } attOfText(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value; if (args.ATT.includes("box2")) { const calcs = []; @@ -749,22 +733,20 @@ } lineCnt(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value = []; - elements.forEach((element) => { - value.push(element.querySelectorAll("br").length + 1 || 1); - }); + elements.forEach((element) => { value.push(element.querySelectorAll("br").length + 1 || 1) }); value = value.length > 1 ? JSON.stringify(value) : (value[0] || 0); return value; } setTextZIndex(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { element.parentNode.style.zIndex = Math.round(args.Z_INDEX) }); } setEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { const curStyles = [ element.style.filter || "", @@ -772,9 +754,7 @@ element.style.opacity || "" ]; const regex = new RegExp(`${args.EFFECT}\\([^)]+\\)`, "g"); - curStyles.forEach((curStyle, index) => { - curStyles[index] = curStyle.replace(regex, ""); - }); + curStyles.forEach((curStyle, index) => { curStyles[index] = curStyle.replace(regex, "") }); switch (args.EFFECT) { case "saturate": element.style.filter = `${curStyles[0]} saturate(${args.VALUE}%)`; @@ -820,7 +800,7 @@ } resetEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { const currentTransform = element.parentNode.style.transform || ""; const updatedTransform = currentTransform @@ -836,7 +816,7 @@ } amtOfEffect(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let effectValue = args.EFFECT === "rotate" ? 90 : args.EFFECT.includes("scale") ? 100 : 0; elements.forEach((element) => { if (args.EFFECT === "rotate" || args.EFFECT.includes("scale") || args.EFFECT.includes("skew")) { @@ -869,7 +849,7 @@ const match = args.ARC.match(regex); const outline = lastRecdVals["textOUT"] !== undefined ? lastRecdVals["textOUT"] : ""; if (match && match[1]) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${args.ID}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${args.ID}"]`) elements.forEach((element) => { const existingSvg = element.querySelector("svg"); if (existingSvg) { @@ -932,7 +912,7 @@ } makeClick(args) { - const elements = document.querySelectorAll(`#SP_Text-Ext-${this.fixID(args.ID)}`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { if (args.TYPE === "on") { element.style.pointerEvents = "auto"; @@ -951,7 +931,7 @@ handleClick(event) { clickedTxts.push(event.target.className); const index = clickedTxts.length - 1; - setTimeout(function() { clickedTxts.splice(index, 1) }, 100); + setTimeout(() => { clickedTxts.splice(index, 1) }, 100); } } From fbffbd252f5249fe84803b2dcb17f0c2e57bb49f Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:06:21 -0700 Subject: [PATCH 20/25] Display-Text -- Boost Speed and Fix Positioning Forever --- extensions/SharkPool/Display-Text.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 1e04fb72cb..24f99898ba 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -697,11 +697,6 @@ const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value; elements.forEach((element) => { - const centerW = parseFloat(element.style.width) / 2; - const computedStyle = window.getComputedStyle(element); - const lineHeight = computedStyle.getPropertyValue("line-height"); - const fontSize = computedStyle.getPropertyValue("font-size"); - const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; if (args.ATT === "z layer") value = element.parentNode.style.zIndex; else value = element.getAttribute("sptxtpos")?.split("|", 2)[args.ATT.includes("x") ? 0 : 1]; }); From 22de101d960237667c8368f1649439a1d99394a3 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:48:25 -0700 Subject: [PATCH 21/25] layering fix --- extensions/SharkPool/Display-Text.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 24f99898ba..16fffbce4d 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,28 +3,28 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.4.1 +// Version V.1.4.2 (function (Scratch) { "use strict"; if (!Scratch.extensions.unsandboxed) throw new Error("Display Text must run unsandboxed!"); const menuIconURI = -"data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI2NS4yMzM5NiIgaGVpZ2h0PSI2NS4yMzM5NiIgdmlld0JveD0iMCwwLDY1LjIzMzk2LDY1LjIzMzk2Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjA3LjM4MzAyLC0xNDcuMzgzMDIpIj48ZyBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpc1BhaW50aW5nTGF5ZXImcXVvdDs6dHJ1ZX0iIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWRhc2hhcnJheT0iIiBzdHJva2UtZGFzaG9mZnNldD0iMCIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOiBub3JtYWwiPjxwYXRoIGQ9Ik0yMDcuMzgzMDIsMTgwYzAsLTE4LjAxMzg2IDE0LjYwMzEyLC0zMi42MTY5OCAzMi42MTY5OCwtMzIuNjE2OThjMTguMDEzODYsMCAzMi42MTY5OCwxNC42MDMxMiAzMi42MTY5OCwzMi42MTY5OGMwLDE4LjAxMzg2IC0xNC42MDMxMiwzMi42MTY5OCAtMzIuNjE2OTgsMzIuNjE2OThjLTE4LjAxMzg2LDAgLTMyLjYxNjk4LC0xNC42MDMxMiAtMzIuNjE2OTgsLTMyLjYxNjk4eiIgZmlsbD0iIzNjNGU1YyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjEwLjc3MzYyLDE4MGMwLC0xNi4xNDEyOSAxMy4wODUxLC0yOS4yMjYzOCAyOS4yMjYzOCwtMjkuMjI2MzhjMTYuMTQxMjksMCAyOS4yMjYzOCwxMy4wODUxIDI5LjIyNjM4LDI5LjIyNjM4YzAsMTYuMTQxMjkgLTEzLjA4NTEsMjkuMjI2MzggLTI5LjIyNjM4LDI5LjIyNjM4Yy0xNi4xNDEyOSwwIC0yOS4yMjYzOCwtMTMuMDg1MSAtMjkuMjI2MzgsLTI5LjIyNjM4eiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmwxLjYyNjMxLDBjMC41MTI3MiwwIDAuOTI4MzYsMC40MTU2NCAwLjkyODM2LDAuOTI4MzZsMCwxMy42MTE5OWMwLDAuNTEyNzIgLTAuNDE1NjQsMC45MjgzNiAtMC45MjgzNiwwLjkyODM2aC0xLjYyNjMxYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMS41Ii8+PC9nPjwvZz48L3N2Zz4="; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NS4yMzQiIGhlaWdodD0iNjUuMjM0IiB2aWV3Qm94PSIwIDAgNjUuMjM0IDY1LjIzNCI+PGcgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48cGF0aCBkPSJNMCAzMi42MTdDMCAxNC42MDMgMTQuNjAzIDAgMzIuNjE3IDBzMzIuNjE3IDE0LjYwMyAzMi42MTcgMzIuNjE3LTE0LjYwMyAzMi42MTctMzIuNjE3IDMyLjYxN1MwIDUwLjYzMSAwIDMyLjYxNyIgZmlsbD0iIzNjNGU1YyIvPjxwYXRoIGQ9Ik0zLjM5MSAzMi42MTdjMC0xNi4xNDEgMTMuMDg1LTI5LjIyNiAyOS4yMjYtMjkuMjI2czI5LjIyNiAxMy4wODUgMjkuMjI2IDI5LjIyNi0xMy4wODUgMjkuMjI2LTI5LjIyNiAyOS4yMjZTMy4zOTEgNDguNzU4IDMuMzkxIDMyLjYxNyIgZmlsbD0iIzc4OSIvPjxwYXRoIGQ9Ik0xOS4wNzYgNDkuNDc5YTMuMzIgMy4zMiAwIDAgMS0zLjMyMS0zLjMydi00Ljk1aDIuNjA3djIuODU1YTIuODEgMi44MSAwIDAgMCAyLjgwOCAyLjgwOGgyLjg1NHYyLjYwN3ptMjQuOTg4LTIuNjA3YTIuODEgMi44MSAwIDAgMCAyLjgwOC0yLjgwOFY0MS4yMWgyLjYwN3Y0Ljk0OGEzLjMyIDMuMzIgMCAwIDEtMy4zMiAzLjMyMWgtNC45NXYtMi42MDd6bS0yOC4zMS0yNy43OTZhMy4zMiAzLjMyIDAgMCAxIDMuMzIyLTMuMzIxaDQuOTQ4djIuNjA3SDIxLjE3YTIuODEgMi44MSAwIDAgMC0yLjgwOCAyLjgwOHYyLjg1NGgtMi42MDd6bTMwLjQwNC0zLjMyMWEzLjMyIDMuMzIgMCAwIDEgMy4zMjEgMy4zMnY0Ljk1aC0yLjYwN1YyMS4xN2EyLjgxIDIuODEgMCAwIDAtMi44MDgtMi44MDhINDEuMjF2LTIuNjA3eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIuNSIvPjxwYXRoIGQ9Ik0yNS44MTEgMjcuNTIxYS45My45MyAwIDAgMS0uOTI4LS45Mjl2LTEuNjI2YzAtLjUxMy40MTUtLjkyOC45MjgtLjkyOGgxMy42MTJjLjUxMyAwIC45MjguNDE1LjkyOC45Mjh2MS42MjZhLjkzLjkzIDAgMCAxLS45MjguOTI5eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxwYXRoIGQ9Ik0zMC44NzUgMjYuNjU3YS45My45MyAwIDAgMSAuOTI5LS45M2gxLjYyNmEuOTMuOTMgMCAwIDEgLjkyOS45M3YxMy42MTFhLjkzLjkzIDAgMCAxLS45MjkuOTI4aC0xLjYyNmEuOTMuOTMgMCAwIDEtLjkyOS0uOTI4eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjwvZz48L3N2Zz4="; const blockIconURI = -"data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI0OS42MjQ0MSIgaGVpZ2h0PSI0OS42MjQ0MSIgdmlld0JveD0iMCwwLDQ5LjYyNDQxLDQ5LjYyNDQxIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjE1LjE4NzgsLTE1NS4xODc4KSI+PGcgZGF0YS1wYXBlci1kYXRhPSJ7JnF1b3Q7aXNQYWludGluZ0xheWVyJnF1b3Q7OnRydWV9IiBmaWxsLXJ1bGU9Im5vbnplcm8iIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1kYXNoYXJyYXk9IiIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAiIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTogbm9ybWFsIj48cGF0aCBkPSJNMjE1LjE4NzgsMjA0LjgxMjJ2LTQ5LjYyNDQxaDQ5LjYyNDQxdjQ5LjYyNDQxeiIgZmlsbD0iIzc3ODg5OSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjAiLz48cGF0aCBkPSJNMjI2LjQ1ODg1LDE5Ni44NjIzNmMtMS44MzQyNSwwIC0zLjMyMTIxLC0xLjQ4Njk2IC0zLjMyMTIxLC0zLjMyMTIydi00Ljk0ODIyaDIuNjA3NTR2Mi44NTQyNmMwLDEuNTUwNjEgMS4yNTcwMiwyLjgwNzY0IDIuODA3NjMsMi44MDc2NGgyLjg1NDI2djIuNjA3NTR6TTI1MS40NDcxOSwxOTQuMjU0ODJjMS41NTA2MSwwIDIuODA3NjMsLTEuMjU3MDIgMi44MDc2MywtMi44MDc2NHYtMi44NTQyNmgyLjYwNzU0djQuOTQ4MjJjMCwxLjgzNDI2IC0xLjQ4Njk2LDMuMzIxMjIgLTMuMzIxMjIsMy4zMjEyMmgtNC45NDgyMnYtMi42MDc1NHpNMjIzLjEzNzY0LDE2Ni40NTg4NWMwLC0xLjgzNDI2IDEuNDg2OTUsLTMuMzIxMjEgMy4zMjEyMSwtMy4zMjEyMWg0Ljk0ODIydjIuNjA3NTRoLTIuODU0MjZjLTEuNTUwNjEsMCAtMi44MDc2MywxLjI1NzAyIC0yLjgwNzYzLDIuODA3NjN2Mi44NTQyNmgtMi42MDc1NHpNMjUzLjU0MTE1LDE2My4xMzc2NGMxLjgzNDI2LDAgMy4zMjEyMiwxLjQ4Njk1IDMuMzIxMjIsMy4zMjEyMXY0Ljk0ODIyaC0yLjYwNzU0di0yLjg1NDI2YzAsLTEuNTUwNjEgLTEuMjU3MDIsLTIuODA3NjMgLTIuODA3NjMsLTIuODA3NjNoLTIuODU0MjZ2LTIuNjA3NTR6IiBmaWxsPSIjZmZmZmZmIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMi41Ii8+PHBhdGggZD0iTTIzMy4xOTQsMTc0LjkwMzUyYy0wLjUxMjcyLDAgLTAuOTI4MzYsLTAuNDE1NjQgLTAuOTI4MzYsLTAuOTI4MzZ2LTEuNjI2M2MwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxMy42MTE5OWMwLjUxMjcyLDAgMC45MjgzNiwwLjQxNTY0IDAuOTI4MzYsMC45MjgzNnYxLjYyNjNjMCwwLjUxMjcyIC0wLjQxNTY0LDAuOTI4MzYgLTAuOTI4MzYsMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjM4LjI1ODQ5LDE3NC4wMzkxNWMwLC0wLjUxMjcyIDAuNDE1NjQsLTAuOTI4MzYgMC45MjgzNiwtMC45MjgzNmgxLjYyNjMxYzAuNTEyNzIsMCAwLjkyODM2LDAuNDE1NjQgMC45MjgzNiwwLjkyODM2djEzLjYxMTk5YzAsMC41MTI3MiAtMC40MTU2NCwwLjkyODM2IC0wLjkyODM2LDAuOTI4MzZoLTEuNjI2MzFjLTAuNTEyNzIsMCAtMC45MjgzNiwtMC40MTU2NCAtMC45MjgzNiwtMC45MjgzNnoiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0iI2ZmZmZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L2c+PC9nPjwvc3ZnPg=="; +"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OS42MjQiIGhlaWdodD0iNDkuNjI0IiB2aWV3Qm94PSIwIDAgNDkuNjI0IDQ5LjYyNCI+PGcgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48cGF0aCBkPSJNMCA0OS42MjRWMGg0OS42MjR2NDkuNjI0eiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMS4yNzEgNDEuNjc0YTMuMzIgMy4zMiAwIDAgMS0zLjMyMS0zLjMydi00Ljk1aDIuNjA3djIuODU1YTIuODEgMi44MSAwIDAgMCAyLjgwOCAyLjgwOGgyLjg1NHYyLjYwN3ptMjQuOTg4LTIuNjA3YTIuODEgMi44MSAwIDAgMCAyLjgwOC0yLjgwOHYtMi44NTRoMi42MDd2NC45NDhhMy4zMiAzLjMyIDAgMCAxLTMuMzIgMy4zMjFoLTQuOTV2LTIuNjA3ek03Ljk0OSAxMS4yNzFhMy4zMiAzLjMyIDAgMCAxIDMuMzIyLTMuMzIxaDQuOTQ4djIuNjA3aC0yLjg1NGEyLjgxIDIuODEgMCAwIDAtMi44MDggMi44MDh2Mi44NTRINy45NXpNMzguMzUzIDcuOTVhMy4zMiAzLjMyIDAgMCAxIDMuMzIxIDMuMzJ2NC45NWgtMi42MDd2LTIuODU1YTIuODEgMi44MSAwIDAgMC0yLjgwOC0yLjgwOGgtMi44NTRWNy45NXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyLjUiLz48cGF0aCBkPSJNMTguMDA2IDE5LjcxNmEuOTMuOTMgMCAwIDEtLjkyOC0uOTI5di0xLjYyNmMwLS41MTMuNDE1LS45MjguOTI4LS45MjhoMTMuNjEyYy41MTMgMCAuOTI4LjQxNS45MjguOTI4djEuNjI2YS45My45MyAwIDAgMS0uOTI4LjkyOXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBkPSJNMjMuMDcgMTguODUyYS45My45MyAwIDAgMSAuOTI5LS45M2gxLjYyNmEuOTMuOTMgMCAwIDEgLjkyOS45M3YxMy42MTFhLjkzLjkzIDAgMCAxLS45MjkuOTI4aC0xLjYyNmEuOTMuOTMgMCAwIDEtLjkyOS0uOTI4eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjwvZz48L3N2Zz4="; const vm = Scratch.vm; const runtime = vm.runtime; const render = vm.renderer; + const fontMenu = [ + "Scratch", "Sans Serif", "Serif", "Handwriting", "Marker", "Curly", "Pixel" + ]; + let allText = []; let clickedTxts = []; let lastRecdVals = {}; - const fontMenu = [ - "Scratch", "Sans Serif", "Serif", - "Handwriting", "Marker", "Curly", "Pixel" - ]; const xmlEscape = function (unsafe) { unsafe = String(unsafe); @@ -697,7 +697,7 @@ const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value; elements.forEach((element) => { - if (args.ATT === "z layer") value = element.parentNode.style.zIndex; + if (args.ATT === "z layer") value = element.parentNode.parentNode.style.zIndex; else value = element.getAttribute("sptxtpos")?.split("|", 2)[args.ATT.includes("x") ? 0 : 1]; }); return value || 0; @@ -737,7 +737,7 @@ setTextZIndex(args) { const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); - elements.forEach((element) => { element.parentNode.style.zIndex = Math.round(args.Z_INDEX) }); + elements.forEach((element) => { element.parentNode.parentNode.style.zIndex = Math.round(args.Z_INDEX) }); } setEffect(args) { From 1b655ecc3dcc197a24244c5941a0fa8f570468bc Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:11:37 -0700 Subject: [PATCH 22/25] Display-Text -- Content Drop --- extensions/SharkPool/Display-Text.js | 197 +++++++++++++-------------- 1 file changed, 95 insertions(+), 102 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 16fffbce4d..bf4cec3823 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.4.2 +// Version V.1.4.3 (function (Scratch) { "use strict"; @@ -22,9 +22,7 @@ "Scratch", "Sans Serif", "Serif", "Handwriting", "Marker", "Curly", "Pixel" ]; - let allText = []; - let clickedTxts = []; - let lastRecdVals = {}; + let allText = [], clickedTxts = [], lastRecdVals = {}; const xmlEscape = function (unsafe) { unsafe = String(unsafe); @@ -366,31 +364,34 @@ arguments: { ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, - } - ], - menus: { - TOGGLE: ["on", "off"], - FONTS: { acceptReporters: true, items: "allFonts" }, - STYLE: { - acceptReporters: true, - items: ["solid", "wavy", "dashed", "double"] }, - LINE_TYPE: { - acceptReporters: true, - items: ["underline", "strikethrough"] + { + opcode: "whenClick", + blockType: Scratch.BlockType.EVENT, + isEdgeActivated: false, + text: "when any text clicked" }, - ALIGNMENTS: { - acceptReporters: true, - items: ["left", "right", "center"] + { + opcode: "clickedID", + blockType: Scratch.BlockType.REPORTER, + disableMonitor: true, + text: "clicked text ID" }, + ], + menus: { + FONTS: { acceptReporters: true, items: "allFonts" }, + TOGGLE: ["on", "off"], TEXT_ATT: ["letter", "line"], - GRADIENTS: { - acceptReporters: true, - items: ["linear", "radial"] - }, POS: ["x position", "y position", "z layer"], OVERFLOW: ["visible", "hidden"], ARCS: ["circle", "hill", "dip", "wave"], + STYLE: { + acceptReporters: true, + items: ["solid", "wavy", "dashed", "double"] + }, + LINE_TYPE: { acceptReporters: true, items: ["underline", "strikethrough"] }, + ALIGNMENTS: { acceptReporters: true, items: ["left", "right", "center"] }, + GRADIENTS: { acceptReporters: true, items: ["linear", "radial"] }, THICK: [ { text : "thick", value : "900" }, { text : "medium", value : "600" }, @@ -434,6 +435,7 @@ }; } + // Helper Funcs allFonts() { const customFonts = Scratch.vm.runtime.fontManager ? Scratch.vm.runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; return [...fontMenu, ...customFonts]; @@ -443,6 +445,15 @@ return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_").replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); } + handleClick(e) { + clickedTxts.push(e.target.className); + const index = clickedTxts.length - 1; + const threads = runtime.startHats("SPdisText_whenClick"); + for (let i = 0; i < threads.length; i++) threads[i].SPdisTxtClickID = e.target.className; + setTimeout(() => { clickedTxts.splice(index, 1) }, 100); + } + + // Block Funcs debug(args) { const toggle = args.TOGGLE === "on" ? "solid" : "none"; const elements = document.querySelectorAll(`div[id^="SP_Text-Ext-"]`); @@ -455,14 +466,12 @@ const cross = document.getElementById(`SP_Text-Debug-Cross`); if (toggle === "none" && cross) cross.parentNode.removeChild(cross); else if (toggle === "solid" && !cross) { - const imageUrl = - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8AAAALQCAYAAABfdxm0AAAAAXNSR0IArs4c6QAAIABJREFUeF7t3b+ubPl23ffTgCM/hKjYqUKBEd/AoRKDBnEDZYwEPYGgiBmDC8IXThj6DRQRCp06FvUQjgy0wdu9r+6p7t1rrVFz1585Ph2Rt9Zv1hrfseacNU6dvc8P3/7dv//xm/8QQAABBBBAAAEEEEAAAQQQWE7gBwF4ucPkIYAAAggggAACCCCAAAII/JHA/wjA//j3P2ByncA///M///Eb9L/4i7/A7zo+J5YT0B/LDSbvEoG//pvfnfobV3/4h9/bJ5fIungTAXtjk5u0fBUBfRKS/flvPgvAIb+PYx7AOwE6vpqA/lhtL3EXCQjAF4G5vJKAvVFpO9EXCeiTi8A+LheAQ3A3xzyAMxxV2UlAf+z0lar7CHwWhH3zex9Xp3cQsDd2+EjF1xLQJyFfATgEJwDPgFOlgoABXWEzkRcJCMAXgbm8ioC9UWU3sSEBfRKCE4BDcALwDDhVKggY0BU2ExkS+C/ffvzjzwT/1bcf/MxvyNCxfQTsjX2eUjRPQJ+ETAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJHBvAL79ZVp+i3RoxJse2+q/vfGmD6TbfigBfRLiFoBDcALwDDhVKggY0BU2ExkSEIBDcI79kYAA7EFAoJeAz1eh9wJwCE4AngGnSgUBA7rCZiJDAmkAPht8fvynb3/8LdMf//3wl9+++23TR6+flXVb5/bc7fuerfvB5+P629+WffT62ff5uC6td3vu9n2Pfsv3vefPPg9XeTzrenvjWeS97zsR0CehWwJwCE4AngGnSgUBA7rCZiJDAgLwb4M7CqRHr1+1Ja13b4C997wAfNVp1yPw/gR8vgo9FIBDcALwDDhVKggY0BU2ExkSePcAfPQN8tHrR9iOAunR60f1P17/LIBe/eb26jfUR/d/9PrH/QvAZ512HQJ7CPh8FXopAIfgBOAZcKpUEDCgK2wmMiQgAL/GN8ACcPgAf9Exe+OLwCq7ioA+Ce0UgENwAvAMOFUqCBjQFTa/rciz37B9JnDq/NE3jfd+05f+jO7RN7j3vn72wUn/ivBVf6avP6p37+u3/LZ8E2xvnO0M1zUT0Ceh+wJwCE4AngGnSgUBA7rC5rcVeRRAjoRNnReAr30TfHv1Z/yu+jN9/VG9e18XgI861OsI7CXg81XorQAcghOAZ8CpUkHAgK6w+e1FHgWRW4FXrz/6BvmrA/DH+x99Y3t7n0fX3/v62QfnVb8B/rj/r7q/q8+Zb4DPPlGuQ+D9Cfh8FXooAIfgBOAZcKpUEDCgK2x+e5FXg8bV6wXgnwhM/XNItzyf9Q2wAPw1rW9vfA1XVXcR0CehnwJwCE4AngGnSgUBA7rC5rcXeTXQXr3+XQPwkbGP+gb4s6B59pvzIx1p/aPn4Ktfv9XlG+CzTrsOgfcn4PNV6KEAHIITgGfAqVJBwICusPntRR4FlVuBV68XgH8ikH4DnAbUqw/mVV+Prv/q1wXgqw67HoE9BHy+Cr0UgENwAvAMOFUqCBjQFTavEXlvYLkK4uo/g5R+w5f+FugjPb4B/vHHP2f0rH8H+OMe0ufjyOdHv25vPJq493tHAvokdE0ADsEJwDPgVKkgYEBX2LxGpAB8zUoBWAC+9sScu9reOMfJVd0E9EnovwAcghOAZ8CpUkHAgK6weZ3I9Lf6XgXx1d8A3xtQv/r81W8sj/6A4pb/s68/ev97X7/Ve5Xn1ef1UdfbG48i7X3emYA+Cd0TgENwAvAMOFUqCBjQFTavEykA/2SpAPzDD7/1cN8bYO89LwCvGz0EIXCagM9Xp1F9f6EAHIITgGfAqVJBwICusHmtyKOAcq/wq98Af7zf2W/6vjrAftxP+jPGZ3V8vM9VP85ef+8feDz7/FWO9z63X33e3vhqwupvIKBPQhcF4BCcADwDTpUKAgZ0hc1rRZ4NUCkAAfh33/0SqT/8w+/v+sb11oez/j07wN77/gJw2oHOIfC+BHy+Cr0TgENwAvAMOFUqCBjQFTavFXk2QKUAvjoAp/f1qHPbgtujuN2+zzaO9sazniTv+04E9EnolgAcghOAZ8CpUkHAgK6wea1IAfhrrd0W3L6W1ufVt3G0N571JHnfdyKgT0K3BOAQnAA8A06VCgIGdIXNa0W+agD+AP7uwefj/o/+6vPaB+xOYe/u/2fy7Y07HwzHKwjok9BmATgEJwDPgFOlgoABXWHzWpEC8NdaKwDfx1cAvo+f0wi8MwGfr0L3BOAQnAA8A06VCgIGdIXNa0W+egBeC56wagL2RrX9xJ8koE9Ogrq9TAAOwQnAM+BUqSBgQFfYvFakALzWWsJemIC98cLmuLWXIaBPQisE4BCcADwDTpUKAgZ0hc1rRQrAa60l7IUJ2BsvbI5bexkC+iS0QgAOwQnAM+BUqSBgQFfYvFakALzWWsJemIC98cLmuLWXIaBPQisE4BCcADwDTpUKAgZ0hc1EhgTSfwc4fDvHEHgLAvbGW9jkJp9MQJ+EBgjAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SgrwNwP/8n/5DWMkxBBBAAAEEELhK4G//9r/98cjf/d2/vnrU9QgggAACCCBwkcBf/Mf//McTP3z7OQkLwBcJuhwBBBBAAIE7CAjAd8BzFAEEEEAAgYsEfhGAv/3j3/9wsYbLv3375q8geAwQ+JyA/vB0IPA5AX8F2tOBwC8J2BueCgSOCeiTY0a/eoWfAQ7B3RzzAM5wVGUnAf2x01eqZggIwDMcVdlFwN7Y5Sc1X0NAn4RcBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU214v8r//044//AuHf/uUPl36XhgBc/+gA8CsE7A2PBQLHBPTJMaNfvUIADsEJwDPgVKkgYEBX2FwvUgCufwQAGCRgbwzCVGotAX0SWisAh+AE4BlwqlQQMKArbK4T+RF4j4QffSPsG+Ajgl5vJGBvNLpO81UC+uQqsZ+vF4BDcALwDDhVKggY0BU214kUgOssJ/iBBOyNB8L2Vm9LQJ+E1gnAITgBeAacKhUEDOgKm2tE3gbf2294PwvGn30T7BvgmkeH0AsE7I0LsFxaS0CfhNYLwCE4AXgGnCoVBAzoCptrRArANVYT+kQC9sYT4XvrtyGgT0KrBOAQnAA8A06VCgIGdIXNNSKPAvAHiLPX+Qa45tEh9AIBe+MCLJfWEtAnofUCcAhOAJ4Bp0oFAQO6wuYakWeD7dnrBOCaR4fQCwTsjQuwXFpLQJ+E1gvAITgBeAacKhUEDOgKm2tEng22Z38WWACueXQIvUDA3rgAy6W1BPRJaL0AHIITgGfAqVJBwICusLlGpABcYzWhTyRgbzwRvrd+GwL6JLRKAA7BCcAz4FSpIGBAV9i8TuRH0P3stzenQfi2nm+A1z06BA0QsDcGICqxnoA+CS0WgENwAvAMOFUqCBjQFTavEykAr7OUoDciYG+8kVlu9WkE9EmIXgAOwQnAM+BUqSBgQFfY/PYiP/uZ3VthH9/gnv0Z36Nvin0D/PaPDgFfQMDe+AKoSq4joE9CSwXgEJwAPANOlQoCBnSFzW8vUgB+ewsJWETA3lhkJilfRkCfhGgF4BCcADwDTpUKAgZ0hc1vK/LoG9qjb3qvBudbUL4BfttHx41/IQF74wvhKr2GgD4JrRSAQ3AC8Aw4VSoIGNAVNr+tSAH4ba1z44sJ2BuLzSVtjIA+CVEKwCE4AXgGnCoVBAzoCpvfVuRRAP4QdvW6z357tG+A3/ZRceMPJGBvPBC2t3pbAvoktE4ADsEJwDPgVKkgYEBX2Py2Iq8G2w+hR/88kgD8to+EG38BAvbGC5jgFl6egD4JLRKAQ3AC8Aw4VSoIGNAVNr+tyDQAHwXhs0D8DPBZUq5rImBvNLlNa0pAn4TkBOAQnAA8A06VCgIGdIXNbytSAH5b69z4YgL2xmJzSRsjoE9ClAJwCE4AngGnSgUBA7rC5pcReTbQ3t7w2XNnrzsLxDfAZ0m5romAvdHkNq0pAX0SkhOAQ3AC8Aw4VSoIGNAVNr+MyDSgnj139rqzQATgs6Rc10TA3mhym9aUgD4JyQnAITgBeAacKhUEDOgKm19G5NG/2/vZjZ49JwC/jNVuZDEBe2OxuaSNEdAnIUoBOAQnAM+AU6WCgAFdYfPLiDwbZG9v+Ow5AfhlrHYjiwnYG4vNJW2MgD4JUQrAITgBeAacKhUEDOgKm58u8rMAe3tjR/880VSds0D8FeizpFzXRMDeaHKb1pSAPgnJCcAhOAF4BpwqFQQM6Aqbny5yKrhO1TkLRAA+S8p1TQTsjSa3aU0J6JOQnAAcghOAZ8CpUkHAgK6w+ekiP4Lr7Te89/6V5c/qTgkWgKdIqrOJgL2xyU1avoqAPgnJCsAhOAF4BpwqFQQM6Aqbny5SAH66BW4AgTEC9sYYSoUWE9AnobkCcAhOAJ4Bp0oFAQO6wuaXF/nZN8Ff/Q3vERjfAB8R8nojAXuj0XWarxLQJ1eJ/Xy9AByCE4BnwKlSQcCArrD55UUKwC9vkRtE4E8E7A0PAwLHBPTJMaNfvUIADsEJwDPgVKkgYEBX2PzyIh/9y63OAvEN8FlSrmsiYG80uU1rSkCfhOQE4BCcADwDTpUKAgZ0hc0vL1IAfnmL3CACvgH2DCBwgYDPVxdg/fmlAnAITgCeAadKBQEDusLmlxf5WQA++neBv1qYb4C/mrD670jA3nhH19zzownok5C4AByCE4BnwKlSQcCArrD55UUKwC9vkRtEwDfAngEELhDw+eoCLN8Ah7B+45gHcJ6pinsI6I89Xr6jknv/HeCv1uwb4K8mrP47ErA33tE19/xoAvokJO4b4BCcb4BnwKlSQcCArrD5ZUUKwC9rjRtD4FMC9oaHA4FjAvrkmNGvXiEAh+AE4BlwqlQQMKArbCYyJOAb4BCcY6tRtCQ1AAAgAElEQVQJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyHINAD/9d/87sc/f8s//MPvfwhvYcUxD+Bv2+h5WfGYxyL0R4zOwQICVwOwefrchwL/x/C3Nx7D+V3eRd/9ulMtfTLuvwA80/otD2BKa/zBTW/EuacQ0B9Pwe5N34SAAPwmRv18m/bZY/yyNx7D+V3eRd8JwKNfvF4NwGcfwB//6dt33xD/8JffvvuG+Oj1r2rI2/e9fZ/b+zx7Hx91j85/1ft/fID6uN+/+vbDd7yPXj+r87bO7bnb9719/ezzc/Z+XPceBHyQeQ+f3OVzCJwNwGfn59F+PXr9LAX7zN+EO/usJNfZGwm1fWda5p4c8dOz+7AcIQB/PyyOAuxno8WD++AHd9+MX63IB5nV9hJ3JwEB+HuAR39ge/T6WTv8ge5ZUs+5zt54DvdXe1cB+HtH/MHj0B88tgTgoz/xPnr9KPh+vP5ZgD6qf/T60UA6+kBw9Pqj6p8dZEf34/X3IuCDzHv55W4fS+DdAvDRvjp6/Yju0b46ev1R9e2zI9L3vW5v3Mdvy+mzfXY0d45eP+J1dP7o9a/KER998q/++1989xZXv9A7mqtHrx/xOzp/9PpH/bPPw9H9fBOAf0L0rAf3w6D0/T/OHz04R68fPShH549eH39wj27Y6y9FwAeZl7LDzbwYAQH4e0OO9snR60f2Hp0/et0+OyI887q9McPx3aucDTxHn6OPXj/idHT+6HUB+MfvfjQ2/VHNs8/DkZ+nA3D6hulX9emDdCj4kwuuvt9nup71DfBnQfhW7md/t/5o4d/7+u19pM9T6q9zzyXgg8xz+Xv31yZwFIDTeflV+/doXx69ftaN9K8o37uvjs7bZ2cdvO86e+M+fu9++tXm3hHPq3NvKkdMfQNclyPOfgP8bg/i0YN6+/qzHtyP+7j6/p/p84HhqvOufwQBH2QeQdl7vCsBAfjXnbPP3vWJnrlve2OG47tWebfccfVzvAB83y/rTZ+PP/XDVwfgNOBdfZDSBr/6Ph/Xf3zTe/b80XVHr5/V5wPDWVKueyQBH2QeSdt7vRuBrwrAX7V/j/bV0etn/bHPzpLaeZ29sdPXs6ruDThX59DV6++dr1M5wjfAPznxh3/4/Xf/+s3hcyYA//Y/13QLUAD+iUj6d/c/eN472A4fbBe8FAEfZF7KDjfzYgQE4F83RAB+sQf1wbdjbzwY+Iu93b2fE68G2qvXC8DfPzBHPzpy7+u3j+e9z8eX/wxw+oAc9WH6s03p/dwG36t1jhrr6PUjHrevHz1o0/Wuvt/dD+5VAa5/KgEfZJ6K35u/OIFXC8BHuI721dHrR/Xts6uEdl5vb+z09ayqez8nTs+h2/u+Wv+rcsT0N8AfOq9+rj/y9aje0esC8M8EBODfftSuPkhv9+Ae3bDXX4qADzIvZYebeTECArB99mKP5Evcjr3xEjY87SYE4O/Rfxa4BeCfOL3cX4G+N6hOd97VP7H5eP8jHbf3efvboI/e9+j1qxwE4KvEXP+VBHyQ+Uq6ar87ga8KwEd76+q/E/nZPry67676ZZ9dJbbjentjh4+pijQAf9XcOzv/PtN7dF9pjhCABeBTPZYGza96cO9tqM9E+8Bw6nFw0YMI+CDzINDe5i0JCMC/bZt99paP9d03bW/cjfCtCwjA3777pU6+Af7+cU6fjz9V+apfgnUUNO99/WpXH73f1XpXg+vR+x+9ftXoqx8Yjq6/9/Vbvlf1pP449xoEfJB5DR/cxWsSmA7AR/vk2a9fnf9H++fW1aPr733dPntMH9kbj+H8qu9ydU48e66lHI/u+yhvnP0G+CrPozn59nNXAE4f2Z/O3fvgHj3YH697cO/zyennEvBB5rn8vftrExCAf/ufr1j/Qey1H8+n3Z298TT0L/HGVz/3Hn0e/+rXU2hH93WUEwTgnwh92c8AXw1iR4be+/rVB+3ev8L82fsd6bg9d3Qfn/1M1tVBMP2B4UNH+s9SXH1+rvrr+tcm4IPMa/vj7p5L4CgAX52fR3vp3tc/+0B2S9E+e+5z9e7vbm+8u4Mz93/28++9c+3q+SN1Z3/HwtH7yhHfEzj7PBz5c/qfQXrVBXwo8OcLjoLn2cV99CAePfBH9+EDw1lHXfdOBHyQeSe33OujCQjAj/0G2B/oPvoJz97P3si4bTt1NvAcBcnp1484H+WBz/4g8eicHPG7H/+c/eVvfj8On/0r0FcD8NGDse31rx7UZwfAq3PdouPVOb/a/X11f7yaXveDwBUC0wH4yns/49ote2CLjmc8A2fe0944Q2n/Nfrstz0+2ydbOI7pEIBnhsfZBzB9tzHD0xsYOrdFxxCOmjJf3R81IAldSUAA/u1vgF/VdPvsa52xN76W77tU12cC8J8TGHsergZg3wT/+oP41YP6w/D4q/4nT7qxB/bJOrx9RuCr+yO7K6cQeA0CZwPwlv1rn73Gc/fqd2FvvLpDj70/nyPvyx/m7g0/AXimgb96UHtwZ3xS5TkEvro/nqPKuyIwQ0AAnuH4qCo+iD+GtL3xGM7v8i76TgD+cwJ3fyGYBuB3aZhH3adB/SjS3ucdCeiPd3TNPT+KwNUA/Kj78j4IPJOAvfFM+t77XQjok9ApATgEd3PMAzjDUZWdBPTHTl+pmiEgAM9wVGUXAXtjl5/UfA0BfRJyFYBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTORFAre/1OXj+N2/3OPifbgcgVckYG+8oivu6dUI6JPQEQE4BCcAz4BTpYKAAV1hM5EXCQjAF4G5vIqAvVFlN7EhAX0SgrsNwH/9P/9/f6zkT6CvAfUAXuPl6i4C+qPLb2p/m8Bnwff2lD3sSWomYG80u0/7WQL65Cypn6770z8r+//+T3/8/3/49nMSFoCvgfy42gOYcXOqg4D+6PCZynMEBOBznFzVTcDe6Paf+nME9Mk5Th9XHQbgjwv9CfQ5sB7Ac5xc1UlAf3T6TvX3BM4G31tu9rAnqZGAvdHoOs1XCeiTc8Ru9+8fPvsGWAA+B9Q3wNc4ubqTgAHd6TvVArBnAIGUgL2RknOuiYA+Oef25QD8f/xvvz9Xufyq//7//K9/JPCv/pf/q5wE+Qj8koD+8FQg8O3b//5//i7CYA9H2Bx6cwL2xpsb6PYfQkCfnMN8u38PvwG2eM+B9QCe4+SqTgL6o9N3qr8nIAB7IhA4T8DeOM/Klb0E9Mk57y8HYD97dA6sv4JwjpOrOgnoj07fqf6egJ8B9kQgcJ6AvXGelSt7CeiTc95f/ivQAvA5sB7Ac5xc1UlAf3T6TrUA7BlAICVgb6TknGsioE/OuX06AAu+54B+XOUBvMbL1V0E9EeX39T+NoGz3wTbw56kZgL2RrP7tJ8loE/OkvrpusN/BsnivQbUA3iNl6u7COiPLr+pFYA9AwjcS8DeuJeg8w0E9Mk1lz8NwN/+8e9/uFbK1f9CwAPoOUDgcwL6w9OBwC8JfPZNsD+A9rRsIvDj//2HH/9Fzw//5q8vfb60NzY9BbQcEdAnR4SGX/93//6nufTt5/9DAM4AG9QZN6c6COiPDp+pvEZAAL7Gy9XvScAH+/f0zV0/loA+eSzvj9wrAP/M3QP44AfQ270lgat9IgC/pc1u+kEE/su3H//4J9F/9e2HS9+QPej2vA0Clwh87IejQ0ffCNsbRwS9/s4E9MmT3fMN8PcGXP1g/3HaoH7yg+ztH0rgap/oj4fa483ejIAA/GaGud3fJOCDvQcEgWMC+uSY0Zde0R6APYBf+ngpvoTAvX0iAC95EMj4EgIC8JdgVfTBBG73xO03vJ/tkc++CbY3Hmygt3sIAX3yEMzHbyIA//TLGY7+81d1jgh5fTMBAXizu7Q9m4AA/GwHvP8EAR/sJyiqsZ2APnkRh1sDsAfwRR5At/HSBKb6xJ/kv7TNbu7JBATgJxvg7UcIHO2Ljzc5e529MWKLIi9G4Ozzf/Y6fRIaLAD/BM5f1QkfIMdWEzgawGf/SpsBvfoxIe5OAgLwnQAdfwkCR/tCAH4Jm9zEkwnokycb8PH2AvCvB2CD+kUeULfxVAJTg1oAfqqN3vzFCQjAL26Q2ztFIN0XH8Vvv4iwN05hd9GbEdAnL2KYACwAv8ij6DZekEA6qH2QeUEz3dLLEhCAX9YaN3aBQLovBOALkF369gT0yYtYKABfC8AG9Ys8uG7jIQSmBrU/yX+IXd7kTQkIwG9qXOltH/0zeOne8AenpQ/UUtn6JDP2x3/69t0vJ/7hL7/9cKbS5XMCsAB85sFyTSeB9IPM7R8UCcCdzw/V5wgIwOc4ueo1CPhg/xo+uIvXJqBPMn8uB9mf3+byua0B+OjB+7Al/YDvTyqzB9up1yLwqD4RgF/Ld3fzWgQE4Nfyw918T+DqP4N39pcjHn3+sjc8ie9EQJ/MunU20J697hd3JwB//+8Af/bv/RrUsw+2aq9BQAB+DR/cRTcBAbjb/1dX74P9qzvk/l6BgD6ZdeFssD173doAfPXB++wb4I///eifRfIN8OyDrtpjCDyrT/xJ/mP89S7vSUAAfk/ftt/10R/8H33Tm+6bD672xvYnbIc+ffI1Pp4NtmevE4D/zV9/98PURwP8s6AsAH/NA6/q1xJIP5Dc2yc+yHytr6q/NwEB+L3923r3PthvdZauSQL6ZJLm/6h1NtievW5dAL73wTv6JvgW2Gd/RdoH/K9pAFVnCDy7T/THjI+q7CQgAO/09d1VHe2Ns18Q3F732eeoW172xrs/QR33r0++1ufPAm4cfD9u991/BvjowUu/ufrMTgH4ax901b+GwLP7xAeZr/FV1R0EBOAdPm5TcSfM/4MAACAASURBVLQ3BOBtjtOTENAnCbXzZwTgT1hNP3j+pPL8Q+nK9yHw7D4RgN/nWXGnjycgAD+euXc8JpDujY/KZ7/p/exO7I1jj1zx9QSOflmoPvl6D/7lHW6D8J/mzMl/J/gXd7n9G+Crf0IpAD/mQfYujyWQDuijDzBHi+FDpQ8yj/Xbu70XAQH4vfxqudt0bwjALU9Ih86jzzn65DHPQW0A/uwBfPaD5wP+Yx5873IfgWf3iQB8n39O7yYgAO/291XUnd0Dt/d79tzZ687ysDfOknLdJIGjXxaa/nOp6RdyR9pa+kQAPvgtzmcfzKk/oRSAj1rT669A4OwHk7M/M39VU8uAvsrF9Qj8CwEB2HPwCAJn94AA/Ag3vMerEhCAX9OZmgB89QE8O9jPXnfVfh/wrxJz/QSBq8/z2evPXndWg/44S8p1jQQE4EbXH685/QPOs+fsjcd76h3nCBw9v1df/+yLtqM6VxVt/3xV90uwBOCrLeD6RgJXB+nZ689ed5b59gF9loPrEPg1AgKw5+IRBM4G2aNvgH2wf4Rb3uPRBI4+91x9XZ/MOFgTgK8+YB9/5fnsYD+qn9rlA35Kzrl7CJx97j/e4+z1032iP+5x2dntBATg7Q4/V9/RFwqffVA/G4Rvrzv65YlnadgbZ0m5boLAR5+c/VHKs9d9dm/65LddO/vv/J697hfv9mq/Bfrog/dnrz/rg/0HUIN6YvyocZXA2edeAL5K1vUIPI6AAPw41o3vJAA3uk7zVQIC8FViX3v92WB79rq3CcBn/2Tl9rqpQX/VVgH4KjHX30Pg3uf83vNX711/XCXm+iYCAnCT24/X+tkH+6MvHI7u9CgwHJ0/et3eOCLk9UkCR89z2i9Hde/VsLVPzgbbs9cJwD8TmPqrBx9Atz6A9zam819D4N4Ae+/5q6r0x1Virm8iIAA3uf14rQLw45l7x/cjcBRUBeDHeno22J69bn0AvhV49EBP2ekD/hRJdc4QmP5A89V9oj/OuOqaVgICcKvzr6H76EfLpr8wOKva3jhLynWPIHDUJx/38Oh+2dYnaaC9fO5VfwY4/SvQAvAjxoD3eDYBAfjZDnh/BOYICMBzLFW6TuDog/2jP9B/KNj2wf66M068EoGjPhGAZ9y6HGR/ftvL514tAB/h8wAeEfI6At++HfXJoz/Q+CDjqUTgcwICsKfjmQQe/SMxZ7XaG2dJue4RBI765NGfq/xB0Z2uC8B3Avz5uEE9w1GVGQIC8AxHVRB4BAEB+BGUvcdnBI4+2Ptmy7ODwC+/WLhlIgC/2VPy7gHYA/hmD5zbfQiBV/tA4w+IHmK7N3lTAgLwmxq35Lav/nN6j5JtbzyKtPf5LQJHn6eeFXx9A3zncysA3wnQN8AzAFUZJXA0sB/9J/o+yIzaq9gyAgLwMkPfTI4A/GaGud2HEjj6PCUAP9SOuTd7lwDsAZzzXKX9BF7tA40AvP+ZozAnIADn7JzMCaT/rEv+jtdO2hvXeLn6awjok6/h+vSqAvCMBQb1DEdVZggIwDMcVUHgEQQE4EdQ9h63BHyw90wgcExAnxwzessrnh2Azz5YZ697lgkC8LPId7zv2ef/7HWPpqY/Hk3c+70TAQH4ndxyr48iYG88irT3eWcC+iR0TwAOwd0c8wDOcFTl1wmcDbZnr3s0Z/3xaOLe750ICMDv5JZ7fRQBe+NRpL3POxPQJ6F7zwrAr/ZXNEN8fzrmAbyXoPO/RmBLn+gPzzcCnxMQgD0dCPySgL3hqUDgmIA+OWb0q1cIwCE43wDPgFPlNwkIwB4QBPYTEID3e0zhdQI+2F9n5kQfAX0Sev7oAPyqf0UzxOcb4HvBOf+rBLb1iQHtQUfAN8CeAQSuELA3rtBybSsBfRI6LwCH4HwDPANOFQHYM4BAOQHfAJc/AOT/KgEf7D0YCBwT0CfHjH71ikcH4PA2X/6YB/DlLXKDTySgP54I31u/PAEB+OUtcoNPIGBvPAG6t3w7AvoktEwADsH5BngGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgbwPwP/+n/xBWcgwBBBBAAAEErhL427/9b3888nd/96+vHnU9AggggAACCFwk8Bf/8T//8cQP335OwgLwRYIuRwABBBBA4A4CAvAd8BxFAAEEEEDgIoFfBOBv//j3P1ys4fJv3775KwgeAwQ+J6A/PB0IfE7AX4H2dCDwSwL2hqcCgWMC+uSY0a9e4WeAQ3A3xzyAMxxV2UlAf+z0laoZAgLwDEdVdhGwN3b5Sc3XENAnIVcBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc31Iv/rP/34479A+Ld/+cOl36UhANc/OgD8CgF7w2OBwDEBfXLM6FevEIBDcALwDDhVKggY0BU214sUgOsfAQAGCdgbgzCVWktAn4TWCsAhOAF4BpwqFQQM6Aqb60R+BN4j4UffCPsG+Iig1xsJ2BuNrtN8lYA+uUrs5+sF4BCcADwDTpUKAgZ0hc11IgXgOssJfiABe+OBsL3V2xLQJ6F1AnAITgCeAadKBQEDusLmGpG3wff2G97PgvFn3wT7Brjm0SH0AgF74wIsl9YS0Ceh9QJwCE4AngGnSgUBA7rC5hqRAnCN1YQ+kYC98UT43vptCOiT0CoBOAQnAM+AU6WCgAFdYXONyKMA/AHi7HW+Aa55dAi9QMDeuADLpbUE9ElovQAcghOAZ8CpUkHAgK6wuUbk2WB79joBuObRIfQCAXvjAiyX1hLQJ6H1AnAITgCeAadKBQEDusLmGpFng+3ZnwUWgGseHUIvELA3LsByaS0BfRJaLwCH4ATgGXCqVBAwoCtsrhEpANdYTegTCdgbT4Tvrd+GgD4JrRKAQ3AC8Aw4VSoIGNAVNq8R+RFwj/793jQI39b1DfCaR4eQQQL2xiBMpdYS0CehtQJwCE4AngGnSgUBA7rC5jUiBeA1VhLyxgTsjTc2z60/jIA+CVELwCE4AXgGnCoVBAzoCpvfVuRnP6t7Kyj9936Pvin2DfDbPjpu/AsJ2BtfCFfpNQT0SWilAByCE4BnwKlSQcCArrD5bUUKwG9rnRtfTMDeWGwuaWME9EmIUgAOwQnAM+BUqSBgQFfY/HYij76ZPftbnNMA/QHMN8Bv9+i44QcQsDceANlbvD0BfRJaKACH4ATgGXCqVBAwoCtsfjuRAvDbWeaGiwjYG0VmkxoT0CchOgE4BCcAz4BTpYKAAV1h89uJPArAH4LOXnd7/dFvkfYN8Ns9Mm74gQTsjQfC9lZvS0CfhNYJwCE4AXgGnCoVBAzoCpvfTuTZYHv2OgH47R4BN/zCBOyNFzbHrb0MAX0SWiEAh+AE4BlwqlQQMKArbH47kWeD7dmfBU4B+BnglJxzmwnYG5vdpW2KgD4JSQrAITgBeAacKhUEDOgKm99OpAD8dpa54SIC9kaR2aTGBPRJiE4ADsEJwDPgVKkgYEBX2PwyIs8G248bPnv92euugvAN8FVirm8gYG80uEzjvQT0SUhQAA7BCcAz4FSpIGBAV9j8MiKvBtWz15+97ioIAfgqMdc3ELA3Glym8V4C+iQkKACH4ATgGXCqVBAwoCtsfhmRV39m9+z1AvDLWOxGO/m6HAAAFSBJREFUCgjYGwUmk3g3AX0SIhSAQ3AC8Aw4VSoIGNAVNr+MyLOB9uOGz14vAL+MxW6kgIC9UWAyiXcT0CchQgE4BCcAz4BTpYKAAV1h89NFfhZkb2/ss3+f997zKQB/BTol59xmAvbGZndpmyKgT0KSAnAITgCeAadKBQEDusLmp4u8N8Deez4FIACn5JzbTMDe2OwubVME9ElIUgAOwQnAM+BUqSBgQFfY/HSRHwH29hve9K8uf1ZvWqgAPE1UvQ0E7I0NLtLw1QT0SUhYAA7BCcAz4FSpIGBAV9j8dJEC8NMtcAMIjBGwN8ZQKrSYgD4JzRWAQ3AC8Aw4VSoIGNAVNr+8yM++CX7UN72fAfIN8Ms/Om7wCQTsjSdA95ZvR0CfhJYJwCE4AXgGnCoVBAzoCptfXqQA/PIWuUEE/kTA3vAwIHBMQJ8cM/rVKwTgEJwAPANOlQoCBnSFzS8v8lm/5OoIjG+Ajwh5vZGAvdHoOs1XCeiTq8R+vl4ADsEJwDPgVKkgYEBX2PzyIgXgl7fIDSLgG2DPAAIXCPh8dQHWn18qAIfgBOAZcKpUEDCgK2x+eZGfBeDP/l3gRwnyDfCjSHufdyJgb7yTW+71WQT0SUheAA7BCcAz4FSpIGBAV9j88iIF4Je3yA0i4BtgzwACFwj4fHUBlm+AQ1i/ccwDOM9UxT0E9MceL19Jydl/3/fsdc/S5hvgZ5H3vq9MwN54ZXfc26sQ0CehE74BDsH5BngGnCoVBAzoCpsfLvJssD173cMF/PyGAvCzyHvfVyZgb7yyO+7tVQjok9AJATgEJwDPgFOlgoABXWHzw0S+6l9lTgEIwCk55zYTsDc2u0vbFAF9EpIUgENwAvAMOFUqCBjQFTY/TKQA/DDU3giBpxGwN56G3hu/EQF9EpolAIfgBOAZcKpUEDCgK2z+cpGv/leZUwC+AU7JObeZgL2x2V3apgjok5CkAByCE4BnwKlSQcCArrD5y0UKwF+O2Bsg8DIE7I2XscKNvDABfRKaIwCH4ATgGXCqVBAwoCtsJjIk4BvgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSEBATgE59hqAvbGanuJGyKgT0KQAnAITgCeAadKBQEDusJmIkMCAnAIzrHVBOyN1fYSN0RAn4QgBeAQnAA8A06VCgIGdIXNRIYEBOAQnGOrCdgbq+0lboiAPglBCsAhOAF4BpwqFQQM6AqbiQwJCMAhOMdWE7A3VttL3BABfRKCFIBDcALwDDhVKggY0BU2ExkSEIBDcI6tJmBvrLaXuCEC+iQEKQCH4ATgGXCqVBAwoCtsJjIkIACH4BxbTcDeWG0vcUME9EkIUgAOwQnAM+BUqSBgQFfYTGRIQAAOwTm2moC9sdpe4oYI6JMQpAAcghOAZ8CpUkHAgK6wmciQgAAcgnNsNQF7Y7W9xA0R0CchSAE4BCcAz4BTpYKAAV1hM5EhAQE4BOfYagL2xmp7iRsioE9CkAJwCE4AngGnSgUBA7rCZiJDAgJwCM6x1QTsjdX2EjdEQJ+EIAXgEJwAPANOlQoCBnSFzUSGBATgEJxjqwnYG6vtJW6IgD4JQQrAITgBeAacKhUEDOgKm4kMCQjAITjHVhOwN1bbS9wQAX0SghSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3COrSZgb6y2l7ghAvokBCkAh+AE4BlwqlQQMKArbCYyJCAAh+AcW03A3lhtL3FDBPRJCFIADsEJwDPgVKkgYEBX2ExkSEAADsE5tpqAvbHaXuKGCOiTEKQAHIITgGfAqVJBwICusJnIkIAAHIJzbDUBe2O1vcQNEdAnIUgBOAQnAM+AU6WCgAFdYTORIQEBOATn2GoC9sZqe4kbIqBPQpACcAhOAJ4Bp0oFAQO6wmYiQwICcAjOsdUE7I3V9hI3RECfhCAF4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJDAkIwCE4x1YTsDdW20vcEAF9EoIUgENwAvAMOFUqCBjQFTYTGRIQgENwjq0mYG+stpe4IQL6JAQpAIfgBOAZcKpUEDCgK2wmMiQgAIfgHFtNwN5YbS9xQwT0SQhSAA7BCcAz4FSpIGBAV9hMZEhAAA7BObaagL2x2l7ihgjokxCkAByCE4BnwKlSQcCArrCZyJCAAByCc2w1AXtjtb3EDRHQJyFIATgEJwDPgFOlgoABXWEzkSGBewPwX//N737887f+wz/8/ofwVhwrIPAuz4u9UfAwkng3AX0SIhSAQ3AC8Aw4VSoIGNAVNhMZEhCAQ3CORQQE4AibQwi8JAGfr0JbBOAQnAA8A06VCgIGdIXNRIYE0gB8Nsj8+E/fvvuG+Ie//PbdN8RHr5+VdVvn9tzt+56t+8Hn4/q/+vbDd/d/9PrZ90mvS9//9tzt+9/qvH393vNnn5+Uy73n7I17CTrfQECfhC4LwCE4AXgGnCoVBAzoCpuJDAkIwL8N7ihgHr0e2nL6WPr+9wbYe88LwKctdiECL0vA56vQGgE4BCcAz4BTpYKAAV1hM5EhgXcPwEffIB+9foTtKGAevX5UP339swB69Zvbq99oH+k9ev1DrwCcOu8cAq9DwOer0AsBOAQnAM+AU6WCgAFdYTORIQEB+LfBHQW6o9dDWw6PCcCHiO66wN64C5/DJQT0SWi0AByCE4BnwKlSQcCArrCZyJDA1QCcfnOX/ozu0Te4975+Flv6V36/OiBfrX90/Ve/fss7fZ7O+pZeZ2+k5JxrIqBPQrcF4BCcADwDTpUKAgZ0hc1EhgQE4HPgBOCfON0bkAXgc8+bqxB4BwI+X4UuCcAhOAF4BpwqFQQM6AqbiQwJPCoAf9ze0Te2tzKOrr/39bPYtgTgD71fpecoIAvAZ5841yHw+gR8vgo9EoBDcALwDDhVKggY0BU2ExkSEIDPgfuqwHju3T+/6mrgFIDPEbc3znFyVTcBfRL6LwCH4ATgGXCqVBAwoCtsJjIk8OoB+EjWo74B/iw4Hv3W5aP7T4N1ej9HgfmrX7/l4WeAj54QryPwugR8vgq9EYBDcALwDDhVKggY0BU2ExkSEICvgTsKiNeq/fJnam/PHwXsq/dzdP1Xvy4AX31CXI/A6xLw+Sr0RgAOwQnAM+BUqSBgQFfYTGRI4FEBOP0t0Eey3v0b4CN9R68fBdbb80fXf/XrAvCRo15H4H0I+HwVeiUAh+AE4BlwqlQQMKArbCYyJCAAXwN3FBCvVbv/6qv3c3T9V78uAN/vuQoIvAoBn69CJwTgEJwAPANOlQoCBnSFzUSGBL46AN/7De1Xn7/6M6hHAfHqN66hbX86Nn0/R/XufV0Avtdx5xF4HQI+X4VeCMAhOAF4BpwqFQQM6AqbiQwJCMC/+/HP0f3hH37/w2+hPAqAAvCP3/E8+hnmq38AET7ml4/ZG5eROVBIQJ+EpgvAITgBeAacKhUEDOgKm4kMCVwNwB9vcza4fPU3uB/3k/6M8VkdH+/zKgF4+rdH3z4+R8H13ve/yj18vONj9kaMzsEiAvokNFsADsEJwDPgVKkgYEBX2ExkSEAAfs9vgO8NoM8+LwCHDesYAi9EwOer0AwBOAQnAM+AU6WCgAFdYTORIYGvDsDhbT3s2KsHsYeBePAbvTp3e+PBD4S3e0sC+iS0TQAOwQnAM+BUqSBgQFfYTGRIQAC+9g1wiNmxGwICsEcCgfcn4PNV6KEAHIITgGfAqVJBwICusJnIkEAagD/e7tWDzBGWj/s/+uVXR3W8fo7Auzwv9sY5P13VTUCfhP4LwCE4AXgGnCoVBAzoCpuJDAkIwD99AywAhw/QxWMC8EVgLkfghQn4fBWaIwCH4ATgGXCqVBAwoCtsJjIkcG8ADt/WMQRemoC98dL2uLkXIaBPQiME4BCcADwDTpUKAgZ0hc1EhgQE4BCcY6sJ2Bur7SVuiIA+CUEKwCE4AXgGnCoVBAzoCpuJvEjg9q+ifhz3V4EvgnT5SgL2xkpbiRomoE9CoAJwCE4AngGnSgUBA7rCZiIvEhCALwJzeRUBe6PKbmJDAvokBCcAh+AE4BlwqlQQMKArbCbyJIHPgu/tcd8EnwTqspUE7I2VthI1TECfhEAF4BCcADwDTpUKAgZ0hc1EniQgAJ8E5bJqAvZGtf3EnySgT06Cur3sFwE4rOMYAggggAACCCCAAAIIIIAAAu9A4IdvPyfhd7hZ94gAAggggAACCCCAAAIIIIBASuD/BznmLlqmzjvmAAAAAElFTkSuQmCC"; const crossElement = document.createElement("img"); - crossElement.src = imageUrl; + crossElement.src = + "data:image/png;base64,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"; crossElement.id = "SP_Text-Debug-Cross"; crossElement.style.position = "absolute"; - crossElement.style.width = "480px"; - crossElement.style.height = "360px"; + crossElement.style.width = "480px"; crossElement.style.height = "360px"; crossElement.style.transform = "translate(-50%, -50%)"; crossElement.style.zIndex = "0"; render.addOverlay(crossElement, "scale-centered"); @@ -533,8 +542,7 @@ element.removeEventListener("click", this.handleClick); }); } - allText = []; - clickedTxts = []; + allText = []; clickedTxts = []; } displayedTexts(args) { @@ -663,7 +671,7 @@ presetTextPosition(args) { if (args.isPrint === undefined) lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; else { - setTimeout(() => { + runtime.once("AFTER_EXECUTE", () => { const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); const element = elements[elements.length - 1]; const centerW = parseFloat(element.style.width) / 2; @@ -671,10 +679,15 @@ const lineHeight = computedStyle.getPropertyValue("line-height"); const fontSize = computedStyle.getPropertyValue("font-size"); const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; + + let transform = element.style.transform; + const string = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + if (transform.includes("translate")) transform = transform.replace(/translate\([^)]*\)/, string); + else transform += ` ${string}`; + element.style.transform = transform.trim(); element.style.position = "absolute"; - element.style.transform = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); - }, 0); + }); } } @@ -687,8 +700,13 @@ const lineHeight = computedStyle.getPropertyValue("line-height"); const fontSize = computedStyle.getPropertyValue("font-size"); const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; + + let transform = element.style.transform; + const string = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + if (transform.includes("translate")) transform = transform.replace(/translate\([^)]*\)/, string); + else transform += ` ${string}`; + element.style.transform = transform.trim(); element.style.position = "absolute"; - element.style.transform = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); }); } @@ -731,8 +749,7 @@ const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); let value = []; elements.forEach((element) => { value.push(element.querySelectorAll("br").length + 1 || 1) }); - value = value.length > 1 ? JSON.stringify(value) : (value[0] || 0); - return value; + return value.length > 1 ? JSON.stringify(value) : (value[0] || 0); } setTextZIndex(args) { @@ -742,7 +759,9 @@ setEffect(args) { const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const val = Scratch.Cast.toNumber(args.VALUE); elements.forEach((element) => { + const parent = element.parentNode; const curStyles = [ element.style.filter || "", element.parentNode.style.transform || "", @@ -751,45 +770,25 @@ const regex = new RegExp(`${args.EFFECT}\\([^)]+\\)`, "g"); curStyles.forEach((curStyle, index) => { curStyles[index] = curStyle.replace(regex, "") }); switch (args.EFFECT) { - case "saturate": - element.style.filter = `${curStyles[0]} saturate(${args.VALUE}%)`; - break; - case "contrast": - element.style.filter = `${curStyles[0]} contrast(${args.VALUE + 100}%)`; - break; - case "brightness": - element.style.filter = `${curStyles[0]} brightness(${args.VALUE + 100}%)`; - break; - case "hue-rotate": - element.style.filter = `${curStyles[0]} hue-rotate(${args.VALUE}deg)`; - break; - case "opacity": - element.style.opacity = (100 - args.VALUE) / 100; - break; - case "sepia": - element.style.filter = `${curStyles[0]} sepia(${args.VALUE}%)`; - break; - case "invert": - element.style.filter = `${curStyles[0]} invert(${args.VALUE}%)`; - break; - case "rotate": - element.parentNode.style.transform = `${curStyles[1]} rotate(${args.VALUE - 90}deg)`; - break; - case "scaleX": - element.parentNode.style.transform = `${curStyles[1]} scaleX(${args.VALUE / 100})`; - break; - case "scaleY": - element.parentNode.style.transform = `${curStyles[1]} scaleY(${args.VALUE / 100})`; - break; - case "skewX": - element.parentNode.style.transform = `${curStyles[1]} skewX(${args.VALUE}deg)`; - break; - case "skewY": - element.parentNode.style.transform = `${curStyles[1]} skewY(${args.VALUE}deg)`; - break; - default: - element.style.filter = `${curStyles[0]} blur(${args.VALUE}px)`; - break; + case "saturate": return element.style.filter = `${curStyles[0]} saturate(${val}%)`; + case "contrast": return element.style.filter = `${curStyles[0]} contrast(${val + 100}%)`; + case "brightness": return element.style.filter = `${curStyles[0]} brightness(${val + 100}%)`; + case "hue-rotate": return element.style.filter = `${curStyles[0]} hue-rotate(${val}deg)`; + case "opacity": return element.style.opacity = (100 - val) / 100; + case "sepia": return element.style.filter = `${curStyles[0]} sepia(${val}%)`; + case "invert": return element.style.filter = `${curStyles[0]} invert(${val}%)`; + case "scaleX": return parent.style.transform = `${curStyles[1]} scaleX(${val / 100})`; + case "scaleY": return parent.style.transform = `${curStyles[1]} scaleY(${val / 100})`; + case "skewX": return parent.style.transform = `${curStyles[1]} skewX(${val}deg)`; + case "skewY": return parent.style.transform = `${curStyles[1]} skewY(${val}deg)`; + case "rotate": { + let transform = element.style.transform; + if (transform.includes("rotate")) transform = transform.replace(/rotate\([^)]*\)/, `rotate(${val - 90}deg)`); + else transform += ` rotate(${val - 90}deg)`; + element.style.transform = transform.trim(); + return element.style.transformOrigin = "center"; + } + default: return element.style.filter = `${curStyles[0]} blur(${val}px)`; } }); } @@ -797,41 +796,39 @@ resetEffect(args) { const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); elements.forEach((element) => { - const currentTransform = element.parentNode.style.transform || ""; - const updatedTransform = currentTransform - .replace(/rotate\([^)]*\)/, "rotate(0deg)") - .replace(/scaleX\([^)]*\)/, "scaleX(1)") - .replace(/scaleY\([^)]*\)/, "scaleY(1)") - .replace(/skewX\([^)]*\)/, "skewX(0deg)") - .replace(/skewY\([^)]*\)/, "skewY(0deg)"); - element.parentNode.style.transform = updatedTransform; + element.parentNode.style.transform = (element.parentNode.style.transform || "") + .replace(/scaleX\([^)]*\)/, "scaleX(1)").replace(/scaleY\([^)]*\)/, "scaleY(1)") + .replace(/skewX\([^)]*\)/, "skewX(0deg)").replace(/skewY\([^)]*\)/, "skewY(0deg)"); + element.style.transform = (element.style.transform || "") + .replace(/rotate\([^)]*\)/, "rotate(0deg)"); element.style.filter = ""; element.style.opacity = 1; }); } amtOfEffect(args) { + const effect = args.EFFECT; const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); - let effectValue = args.EFFECT === "rotate" ? 90 : args.EFFECT.includes("scale") ? 100 : 0; + let effectValue = effect === "rotate" ? 90 : effect.includes("scale") ? 100 : 0; elements.forEach((element) => { - if (args.EFFECT === "rotate" || args.EFFECT.includes("scale") || args.EFFECT.includes("skew")) { - const transformV = element.parentNode.style.transform.split(" "); - const effectIndex = transformV.findIndex(value => value.includes(args.EFFECT)); - if (effectIndex !== -1) { - effectValue = transformV[effectIndex].replace(/[^\d.-]/g, ""); - effectValue = args.EFFECT === "rotate" ? parseFloat(effectValue) + 90 : - parseFloat(effectValue) * (args.EFFECT.includes("scale") ? 100 : 1); + if (effect === "rotate" || effect.includes("scale") || effect.includes("skew")) { + const thisElement = effect === "rotate" ? element : element.parentNode; + const transformV = element.style.transform.split(" "); + const index = transformV.findIndex(value => value.includes(effect)); + if (index !== -1) { + effectValue = transformV[index].replace(/[^\d.-]/g, ""); + effectValue = effect === "rotate" ? parseFloat(effectValue) + 90 : + parseFloat(effectValue) * (effect.includes("scale") ? 100 : 1); } - } else if (args.EFFECT === "opacity") { + } else if (effect === "opacity") { effectValue = 100 - (parseFloat(element.style.opacity || 0) * 100); } else { const filterV = element.style.filter.split(" "); - const effectIndex = filterV.findIndex((value) => value.includes(args.EFFECT)); - if (effectIndex !== -1) { - effectValue = - args.EFFECT === "contrast" || args.EFFECT === "brightness" - ? parseFloat(filterV[effectIndex].replace(/[^\d.-]/g, "")) - 100 - : parseFloat(filterV[effectIndex].replace(/[^\d.-]/g, "")); + const index = filterV.findIndex((value) => value.includes(effect)); + if (index !== -1) { + effectValue = effect === "contrast" || effect === "brightness" + ? parseFloat(filterV[index].replace(/[^\d.-]/g, "")) - 100 + : parseFloat(filterV[index].replace(/[^\d.-]/g, "")); } } }); @@ -923,11 +920,7 @@ isClicked(args) { return clickedTxts.indexOf(this.fixID(args.ID)) > -1 } - handleClick(event) { - clickedTxts.push(event.target.className); - const index = clickedTxts.length - 1; - setTimeout(() => { clickedTxts.splice(index, 1) }, 100); - } + clickedID(_, util) { return util.thread.SPdisTxtClickID ?? "" } } Scratch.extensions.register(new SPdisText()); From c538f743eb493af7ecaf474fcb38c4517ba1d6b2 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 26 Aug 2024 17:13:23 -0700 Subject: [PATCH 23/25] fix thing --- extensions/SharkPool/Display-Text.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index bf4cec3823..921ebe0278 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -813,7 +813,7 @@ elements.forEach((element) => { if (effect === "rotate" || effect.includes("scale") || effect.includes("skew")) { const thisElement = effect === "rotate" ? element : element.parentNode; - const transformV = element.style.transform.split(" "); + const transformV = thisElement.style.transform.split(" "); const index = transformV.findIndex(value => value.includes(effect)); if (index !== -1) { effectValue = transformV[index].replace(/[^\d.-]/g, ""); From 791cc6de857c092620d0575a0bb3d785c474dcdb Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:36:12 -0700 Subject: [PATCH 24/25] Display-Text -- V1.4.4 --- extensions/SharkPool/Display-Text.js | 240 ++++++++++++++++----------- 1 file changed, 147 insertions(+), 93 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 921ebe0278..7c14f14568 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -3,7 +3,7 @@ // Description: Display Text in Your Projects! // By: SharkPool -// Version V.1.4.3 +// Version V.1.4.4 (function (Scratch) { "use strict"; @@ -22,7 +22,7 @@ "Scratch", "Sans Serif", "Serif", "Handwriting", "Marker", "Curly", "Pixel" ]; - let allText = [], clickedTxts = [], lastRecdVals = {}; + let allText = [], clickedTxts = [], txtSettings = {}; const xmlEscape = function (unsafe) { unsafe = String(unsafe); @@ -78,14 +78,6 @@ ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } }, }, - { - opcode: "resetTxt", - blockType: Scratch.BlockType.COMMAND, - text: "reset text settings with ID [ID]", - arguments: { - ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } - }, - }, { opcode: "removeAllTxt", blockType: Scratch.BlockType.COMMAND, @@ -348,6 +340,34 @@ TOGGLE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } }, }, + "---", + { + opcode: "resetTxt", + blockType: Scratch.BlockType.COMMAND, + text: "reset text settings with ID [ID]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" } + }, + }, + { + opcode: "reuseStyle", + blockType: Scratch.BlockType.COMMAND, + text: "reuse text settings in ID [ID] for ID [ID2]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + ID2: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text2" } + }, + }, + "---", + { + opcode: "toggleSelect", + blockType: Scratch.BlockType.COMMAND, + text: "toggle highlighting for ID [ID] [TYPE]", + arguments: { + ID: { type: Scratch.ArgumentType.STRING, defaultValue: "my-text" }, + TYPE: { type: Scratch.ArgumentType.STRING, menu: "TOGGLE" } + }, + }, { opcode: "makeClick", blockType: Scratch.BlockType.COMMAND, @@ -437,12 +457,14 @@ // Helper Funcs allFonts() { - const customFonts = Scratch.vm.runtime.fontManager ? Scratch.vm.runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; + const customFonts = runtime.fontManager ? runtime.fontManager.getFonts().map((i) => ({ text: i.name, value: i.family })) : []; return [...fontMenu, ...customFonts]; } fixID(ID) { - return xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_").replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); + ID = xmlEscape(Scratch.Cast.toString(ID).replaceAll(" ", "_").replaceAll(/[#%(),.{}[/\]$@^*&'";:]/g, "-")); + txtSettings[ID] = { ...txtSettings[ID] }; + return ID; } handleClick(e) { @@ -453,15 +475,34 @@ setTimeout(() => { clickedTxts.splice(index, 1) }, 100); } + updateStyles(txtSetting, optOverrideName) { + const propsd2Func = [ + ["textMAR", "setMargins"], ["preTxt1", "presetTextPosition"], + ["textCLR", "setTextColor"], ["textLIN", "setLine"], + ["textOUT", "setTextOutline"], ["textSHA", "setTextDropShadow"], + ["txtFont", "setTextFont"], ["txtFontSZ", "setFontSize"], + ["txtALI", "setTextAlignment"], ["lineDIS", "setTextSpacing"], + ["letDIS", "setTextSpacing"], ["textOVR", "setOverflow"], + ["txtFontTK", "setThick"] + ]; + if (optOverrideName) { + for (const [id, func] of propsd2Func) { + if (txtSetting[id]) this[func]({ ...txtSetting[id], ID: optOverrideName }); + } + } else { + for (const [id, func] of propsd2Func) { + if (txtSetting[id]) this[func](txtSetting[id]); + } + } + } + // Block Funcs debug(args) { const toggle = args.TOGGLE === "on" ? "solid" : "none"; const elements = document.querySelectorAll(`div[id^="SP_Text-Ext-"]`); elements.forEach((element) => { - element.style.border = toggle; - element.style.borderWidth = "1px"; - const color = element.style.textAlign === "center" ? "#00ff00" : element.style.textAlign === "right" ? "#0000ff" : "#ff0000"; - element.style.borderColor = color; + element.style.border = toggle; element.style.borderWidth = "1px"; + element.style.borderColor = element.style.textAlign === "center" ? "#00ff00" : element.style.textAlign === "right" ? "blue" : "red"; }); const cross = document.getElementById(`SP_Text-Debug-Cross`); if (toggle === "none" && cross) cross.parentNode.removeChild(cross); @@ -480,35 +521,22 @@ } printTxt(args) { - args.ID = this.fixID(args.ID); + const ID = this.fixID(args.ID); + const settings = txtSettings[ID]; const textDiv = document.createElement("div"); textDiv.style.transformOrigin = "left top"; const txtElement = document.createElement("div"); txtElement.innerHTML = xmlEscape(args.TXT).replace(/\n/g, "
"); - txtElement.id = `SP_Text-Ext-${args.ID}`; - txtElement.classList.add(args.ID); + txtElement.id = `SP_Text-Ext-${ID}`; + txtElement.classList.add(ID); + txtElement.style.userSelect = "none"; txtElement.setAttribute("sptxtpos", "120|-10"); textDiv.appendChild(txtElement); render.addOverlay(textDiv, "scale-centered"); - allText.push(`#SP_Text-Ext-${args.ID}`); + allText.push(`#SP_Text-Ext-${ID}`); const box = txtElement.getBoundingClientRect(); - if (lastRecdVals.textMAR === undefined) this.setMargins({ ID : args.ID, WIDTH : box.width / 2, HEIGHT : box.height }); - - // add formatting (if any) - const propertiesAndMethods = [ - ["textMAR", "setMargins"], ["preTxt1", "presetTextPosition"], - ["textCLR", "setTextColor"], ["textLIN", "setLine"], - ["textOUT", "setTextOutline"], ["textSHA", "setTextDropShadow"], - ["txtFont", "setTextFont"], ["txtFontSZ", "setFontSize"], - ["txtALI", "setTextAlignment"], ["lineDIS", "setTextSpacing"], - ["letDIS", "setTextSpacing"], ["textOVR", "setOverflow"], - ["txtFontTK", "setThick"] - ]; - for (const [property, method] of propertiesAndMethods) { - if (lastRecdVals[property] && lastRecdVals[property].inputs.ID === args.ID) { - this[method](lastRecdVals[property].inputs); - } - } + if (settings.textMAR === undefined) this.setMargins({ ID, WIDTH : box.width / 2, HEIGHT : box.height }); + this.updateStyles(settings); // add formatting (if any) } replaceTxt(args) { @@ -518,27 +546,21 @@ } removeTxt(args) { - args.ID = this.fixID(args.ID); - const elementsToRemove = document.querySelectorAll(`div[id="SP_Text-Ext-${args.ID}"]`); + const ID = this.fixID(args.ID); + const elementsToRemove = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elementsToRemove.forEach((element) => { render.removeOverlay(element.parentNode); element.removeEventListener("click", this.handleClick); - const index = allText.indexOf(`#SP_Text-Ext-${args.ID}`); + const index = allText.indexOf(`#SP_Text-Ext-${ID}`); if (index !== -1) allText.splice(index, 1); }); } - resetTxt(args) { - Object.keys(lastRecdVals).forEach(key => { - if (lastRecdVals[key].inputs.ID === args.ID) delete lastRecdVals[key]; - }); - } - removeAllTxt() { for (let i = 0; i < allText.length; i++) { const elementsToRemove = document.querySelectorAll(allText[i]); elementsToRemove.forEach((element) => { - render.removeOverlay(element.parentNode) + render.removeOverlay(element.parentNode); element.removeEventListener("click", this.handleClick); }); } @@ -568,7 +590,8 @@ makeGradient(args) { return `${args.TYPE}-gradient(${args.ANGLE}deg, ${args.COLOR1}, ${args.COLOR2})` } setTextColor(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.color = args.COLOR; if (args.COLOR.includes("gradient")) { @@ -583,25 +606,28 @@ element.style.webkitBackgroundClip = "initial"; } }); - lastRecdVals["textCLR"] = {inputs: args}; + txtSettings[ID]["textCLR"] = { ...args }; } setTextDropShadow(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.textShadow = args.z === 0 ? "none" : `${args.x}px ${args.y * -1}px ${args.z}px ${args.COLOR}`; }); - lastRecdVals["textSHA"] = {inputs: args}; + txtSettings[ID]["textSHA"] = { ...args }; } setOverflow(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.overflow = args.TYPE }); - lastRecdVals["textOVR"] = {inputs: args}; + txtSettings[ID]["textOVR"] = { ...args }; } setTextOutline(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.webkitTextStrokeColor = args.COLOR; element.style.webkitTextStrokeWidth = `${args.THICKNESS}px`; @@ -611,68 +637,77 @@ element.style.mozTextStrokeColor = args.COLOR; element.style.mozTextStrokeWidth = `${args.THICKNESS}px`; }); - lastRecdVals["textOUT"] = {inputs: args}; + txtSettings[ID]["textOUT"] = { ...args }; } setLine(args) { + const ID = this.fixID(args.ID); const lineType = args.TYPE2.replace("strike", "line-"); - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.textDecorationLine = lineType; element.style.textDecorationStyle = args.TYPE1; element.style.textDecorationThickness = `${args.THICK}px`; element.style.textDecorationColor = args.COLOR; }); - lastRecdVals["textLIN"] = {inputs: args}; + txtSettings[ID]["textLIN"] = { ...args }; } setMargins(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.width = `${args.WIDTH}px`; element.style.height = `${args.HEIGHT}px`; }); - lastRecdVals["textMAR"] = {inputs: args}; + txtSettings[ID]["textMAR"] = { ...args }; } setTextAlignment(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.textAlign = args.ALIGNMENT }); - lastRecdVals["txtALI"] = {inputs: args}; + txtSettings[ID]["txtALI"] = { ...args }; } setTextFont(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.fontFamily = args.FONT }); - lastRecdVals["txtFont"] = {inputs: args}; + txtSettings[ID]["txtFont"] = { ...args }; } setFontSize(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.fontSize = `${args.SIZE}px` }); - lastRecdVals["txtFontSZ"] = {inputs: args}; + txtSettings[ID]["txtFontSZ"] = { ...args }; } setThick(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style.fontWeight = args.NUM * 9 }); - lastRecdVals["txtFontTK"] = {inputs: args}; + txtSettings[ID]["txtFontTK"] = { ...args }; } setTextSpacing(args) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const ID = this.fixID(args.ID); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); elements.forEach((element) => { element.style[args.ATT === "letter" ? "letterSpacing" : "lineHeight"] = `${args.SPACING}px`; }); - lastRecdVals["letDIS"] = {inputs: {ID : args.ID, SPACING : args.SPACING, ATT : "letter"}}; - lastRecdVals["lineDIS"] = {inputs: {ID : args.ID, SPACING : args.SPACING, ATT : "line"}}; + txtSettings[ID]["letDIS"] = { ID, SPACING : args.SPACING, ATT : "letter" }; + txtSettings[ID]["lineDIS"] = { ID, SPACING : args.SPACING, ATT : "line" }; } presetTextPosition(args) { - if (args.isPrint === undefined) lastRecdVals["preTxt1"] = {inputs: {...args, isPrint: true}}; + const ID = this.fixID(args.ID); + if (args.isPrint === undefined) txtSettings[ID]["preTxt1"] = { ...args, isPrint: true }; else { + const pos = [Scratch.Cast.toNumber(args.X), Scratch.Cast.toNumber(args.Y)]; runtime.once("AFTER_EXECUTE", () => { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`); const element = elements[elements.length - 1]; const centerW = parseFloat(element.style.width) / 2; const computedStyle = window.getComputedStyle(element); @@ -681,18 +716,19 @@ const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; let transform = element.style.transform; - const string = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + const string = `translate(${pos[0] - centerW}px, ${(pos[1] * -1) - centerH}px)`; if (transform.includes("translate")) transform = transform.replace(/translate\([^)]*\)/, string); else transform += ` ${string}`; element.style.transform = transform.trim(); element.style.position = "absolute"; - element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); + element.setAttribute("sptxtpos", `${pos[0]}|${pos[1]}`); }); } } setTextPosition(args) { const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + const pos = [Scratch.Cast.toNumber(args.X), Scratch.Cast.toNumber(args.Y)]; elements.forEach((element) => { let centerW = parseFloat(element.style.width) / 2; if (isNaN(centerW)) centerW = (element.getBoundingClientRect().width ?? 0 ) / 2; @@ -702,12 +738,12 @@ const centerH = (lineHeight === "normal" ? parseFloat(fontSize) * 1.2 : parseFloat(lineHeight)) / 2; let transform = element.style.transform; - const string = `translate(${args.X - centerW}px, ${(args.Y * -1) - centerH}px)`; + const string = `translate(${pos[0] - centerW}px, ${(pos[1] * -1) - centerH}px)`; if (transform.includes("translate")) transform = transform.replace(/translate\([^)]*\)/, string); else transform += ` ${string}`; element.style.transform = transform.trim(); element.style.position = "absolute"; - element.setAttribute("sptxtpos", `${args.X}|${args.Y}`); + element.setAttribute("sptxtpos", `${pos[0]}|${pos[1]}`); }); } @@ -836,21 +872,24 @@ } setTextCurve(args) { - args.ID = this.fixID(args.ID) + // TODO clean this up and add more availiable text stylings + // Perhaps make the entire extension rely on svgs? + const ID = this.fixID(args.ID); + const settings = txtSettings[ID]; const regex = args.ARC.includes("]*d="([^"]*)"/ : /]*d="([^"]*)"/; const match = args.ARC.match(regex); - const outline = lastRecdVals["textOUT"] !== undefined ? lastRecdVals["textOUT"] : ""; + const outline = settings["textOUT"] !== undefined ? settings["textOUT"] : ""; if (match && match[1]) { - const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${args.ID}"]`) + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${ID}"]`) elements.forEach((element) => { const existingSvg = element.querySelector("svg"); if (existingSvg) { const path = existingSvg.querySelector("path"); path.setAttribute("d", match[1]); const textFill = existingSvg.querySelector("text"); - textFill.setAttribute("fill", element.style.color === "transparent" ? "#000000" : element.style.color); + textFill.setAttribute("fill", element.style.color === "transparent" ? "#000" : element.style.color); const textPathFill = existingSvg.querySelector("textPath"); - textPathFill.setAttribute("href", `#MyPath-${args.ID}`); + textPathFill.setAttribute("href", `#MyPath-${ID}`); textPathFill.textContent = element.textContent; const textStroke = existingSvg.querySelector("text"); @@ -858,13 +897,13 @@ textStroke.setAttribute("stroke", outline ? outline.inputs.COLOR ?? "#00000000" : "#00000000"); textStroke.setAttribute("stroke-width", outline ? outline.inputs.THICKNESS ?? 1 : 1); const textPathStroke = existingSvg.querySelector("textPath"); - textPathStroke.setAttribute("href", `#MyPath-${args.ID}`); + textPathStroke.setAttribute("href", `#MyPath-${ID}`); textPathStroke.textContent = element.textContent; } else { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs"); const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); - path.setAttribute("id", `MyPath-${args.ID}`); + path.setAttribute("id", `MyPath-${ID}`); path.setAttribute("d", match[1]); defs.appendChild(path); @@ -873,16 +912,16 @@ textStroke.setAttribute("stroke", outline ? outline.inputs.COLOR : "#00000000"); textStroke.setAttribute("stroke-width", outline ? outline.inputs.THICKNESS : 1); const textPathStroke = document.createElementNS("http://www.w3.org/2000/svg", "textPath"); - textPathStroke.setAttribute("href", `#MyPath-${args.ID}`); + textPathStroke.setAttribute("href", `#MyPath-${ID}`); textPathStroke.textContent = element.textContent; textStroke.appendChild(textPathStroke); svg.appendChild(defs); svg.appendChild(textStroke); const textFill = document.createElementNS("http://www.w3.org/2000/svg", "text"); - textFill.setAttribute("fill", element.style.color === "transparent" ? "#000000" : element.style.color); + textFill.setAttribute("fill", element.style.color === "transparent" ? "#000" : element.style.color); const textPathFill = document.createElementNS("http://www.w3.org/2000/svg", "textPath"); - textPathFill.setAttribute("href", `#MyPath-${args.ID}`); + textPathFill.setAttribute("href", `#MyPath-${ID}`); textPathFill.textContent = element.textContent; textFill.appendChild(textPathFill); svg.appendChild(textFill); @@ -894,13 +933,28 @@ } presetCurve(args) { - const presets = { - circle : ``, - wave : `` - }; - return presets[args.ARC]; + return { + circle: ``, + hill: ``, + dip: ``, + wave: `` + }[args.ARC]; + } + + resetTxt(args) { delete txtSettings[this.fixID(args.ID)] } + + reuseStyle(args) { + const ID = this.fixID(args.ID2); + this.updateStyles(txtSettings[this.fixID(args.ID)], this.fixID(args.ID2)); + } + + toggleSelect(args) { + const type = args.TYPE === "on" ? "auto" : "none"; + const elements = document.querySelectorAll(`div[id="SP_Text-Ext-${this.fixID(args.ID)}"]`); + elements.forEach((element) => { + element.style.userSelect = type; element.style.webkitUserSelect = type; element.style.mozUserSelect = type; + element.style.pointerEvents = type; + }); } makeClick(args) { From 06605367ebdd614b099fa0e39ee6e87c09bd1322 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:41:06 -0700 Subject: [PATCH 25/25] Display-Text -- V1.4.4 --- extensions/SharkPool/Display-Text.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/SharkPool/Display-Text.js b/extensions/SharkPool/Display-Text.js index 7c14f14568..5a9e188115 100644 --- a/extensions/SharkPool/Display-Text.js +++ b/extensions/SharkPool/Display-Text.js @@ -697,8 +697,7 @@ elements.forEach((element) => { element.style[args.ATT === "letter" ? "letterSpacing" : "lineHeight"] = `${args.SPACING}px`; }); - txtSettings[ID]["letDIS"] = { ID, SPACING : args.SPACING, ATT : "letter" }; - txtSettings[ID]["lineDIS"] = { ID, SPACING : args.SPACING, ATT : "line" }; + txtSettings[ID][args.ATT === "letter" ? "letDIS" : "lineDIS"] = { ...args, ID }; } presetTextPosition(args) { @@ -944,7 +943,6 @@ resetTxt(args) { delete txtSettings[this.fixID(args.ID)] } reuseStyle(args) { - const ID = this.fixID(args.ID2); this.updateStyles(txtSettings[this.fixID(args.ID)], this.fixID(args.ID2)); }