From cd3213e074725817c750c553d4ef94e73d62d407 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:30:31 +0100 Subject: [PATCH 1/6] Refactor patch-gui.js for improved readability and maintainability; update README.md for Arduino Modulino library to enhance clarity and formatting --- .github/workflows/release.yaml | 12 +-- .gitignore | 3 +- README.md | 5 +- Taskfile.yaml | 43 ++++++---- app.yaml | 4 +- dprint.json | 24 ++++++ python/main.py | 35 ++++---- .../src/extensions/arduino_basics/index.js | 82 ++++++++++--------- .../src/extensions/arduino_modulino/index.js | 53 ++++++------ .../src/extensions/socket.io.min.js | 3 +- .../scripts/patch-gui.js | 32 ++++---- sketch/Arduino_Modulino/README.md | 6 +- 12 files changed, 176 insertions(+), 126 deletions(-) create mode 100644 dprint.json diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bbd333c..aa08413 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -14,10 +14,10 @@ jobs: uses: actions/checkout@v5 with: fetch-depth: 0 - + - name: Show tag info run: echo "Building release for tag ${{ github.ref_name }}" - + - name: Install Go uses: actions/setup-go@v5 with: @@ -26,20 +26,20 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v6 with: - node-version: '18' + node-version: "18" - name: Install Task uses: arduino/setup-task@v2 - - name: Scratch init + - name: Scratch init run: | task scratch:init - - name: Create build + - name: Create build run: | task app:build - - name: Create zip + - name: Create zip run: task app:zip env: APP_VERSION: ${{ github.ref_name }} diff --git a/.gitignore b/.gitignore index 751dd4d..40793c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ scratch-editor -build/ \ No newline at end of file +build/ +.bin/ diff --git a/README.md b/README.md index 190978a..b9dacd7 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,18 @@ - Connect to the board using `adb` following https://docs.arduino.cc/software/app-lab/tutorials/cli/ and open the `adb shell` - From inside the board, Install the latest `scratch-arduino-app` into the board running the command: + ``` curl -sSL https://raw.githubusercontent.com/dido18/scratch-arduino-app/main/install.sh | bash ``` + - Open the `ArduinoAppLab` and start the app - Visit the `:7000` to open the Scratch App. ### Local development + - `task scratch:init` - `task scratch:local:start` - `ŧask board:upload` -- change the `const wsServerURL = `ws://:7000`;` in the `index.js` +- change the `const wsServerURL =`ws://:7000`;` in the `index.js` - Open local scratch on http://localhost:8601/ diff --git a/Taskfile.yaml b/Taskfile.yaml index fc69883..cd083c2 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -1,8 +1,14 @@ version: "3" vars: SCRATCH_EDITOR_VERSION: v12.0.1 + DPRINT_VERSION: 0.48.0 tasks: + fmt: + desc: Run format + cmds: + - ${PWD}/.bin/dprint fmt + scratch:init: cmds: - rm -rf scratch-editor @@ -10,6 +16,10 @@ tasks: - cd scratch-editor && npm install - cd scratch-editor && npm run build - task scratch:patch + install:dprint: + cmds: + - curl -fsSL https://dprint.dev/install.sh | sh -s {{ .DPRINT_VERSION }} + - mkdir -p .bin && cp $HOME/.dprint/bin/dprint .bin/dprint # workaround for local install scratch:patch: cmds: @@ -33,8 +43,8 @@ tasks: - cp scratch-editor/packages/scratch-gui/build/gui.js build/scratch-arduino-app/assets/gui.js - mkdir -p build/scratch-arduino-app/assets/static - cp -r scratch-editor/packages/scratch-gui/build/static/blocks-media build/scratch-arduino-app/assets/static/blocks-media - - scratch:build: + + scratch:build: desc: "Build Scratch GUI files" dir: scratch-editor/packages/scratch-gui cmds: @@ -45,16 +55,16 @@ tasks: cmds: - task app:zip - | - ZIP_FILE=$(ls -t build/scratch-arduino-app-*.zip 2>/dev/null | head -n1) - if [ -z "$ZIP_FILE" ]; then - echo "No zip file found. Run 'task app:zip' first." - exit 1 - fi - adb push "$ZIP_FILE" /tmp/ - ZIP_BASENAME=$(basename "$ZIP_FILE") - adb shell "cd /tmp && unzip -o $ZIP_BASENAME && mkdir -p /home/arduino/ArduinoApps && rm -rf /home/arduino/ArduinoApps/scratch-arduino-app && mv scratch-arduino-app /home/arduino/ArduinoApps/ && rm $ZIP_BASENAME" - echo "App deployed to /home/arduino/ArduinoApps/scratch-arduino-app" - + ZIP_FILE=$(ls -t build/scratch-arduino-app-*.zip 2>/dev/null | head -n1) + if [ -z "$ZIP_FILE" ]; then + echo "No zip file found. Run 'task app:zip' first." + exit 1 + fi + adb push "$ZIP_FILE" /tmp/ + ZIP_BASENAME=$(basename "$ZIP_FILE") + adb shell "cd /tmp && unzip -o $ZIP_BASENAME && mkdir -p /home/arduino/ArduinoApps && rm -rf /home/arduino/ArduinoApps/scratch-arduino-app && mv scratch-arduino-app /home/arduino/ArduinoApps/ && rm $ZIP_BASENAME" + echo "App deployed to /home/arduino/ArduinoApps/scratch-arduino-app" + app:zip: desc: "Create a zip file with version (defaults to git commit hash)" vars: @@ -62,10 +72,9 @@ tasks: sh: echo "${APP_VERSION:-$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')}" cmds: - | - if [ ! -d "build/scratch-arduino-app" ]; then - echo "Build folder does not exist. Run 'task app:build' first." - exit 1 - fi + if [ ! -d "build/scratch-arduino-app" ]; then + echo "Build folder does not exist. Run 'task app:build' first." + exit 1 + fi - echo "Creating zip with version {{.APP_VERSION}}" - cd build && zip -r scratch-arduino-app-{{.APP_VERSION}}.zip scratch-arduino-app && cd .. - \ No newline at end of file diff --git a/app.yaml b/app.yaml index fd30e72..54a0235 100644 --- a/app.yaml +++ b/app.yaml @@ -1,7 +1,7 @@ name: scratch-arduino-app description: Control the Uno-Q board using Scratch blocks ports: - - 7000 + - 7000 bricks: - - arduino:web_ui + - arduino:web_ui icon: 🐱 diff --git a/dprint.json b/dprint.json new file mode 100644 index 0000000..2ce8791 --- /dev/null +++ b/dprint.json @@ -0,0 +1,24 @@ +{ + "typescript": {}, + "json": {}, + "markdown": {}, + "yaml": {}, + "ruff": { + "indentStyle": "space", + "lineLength": 100, + "indentWidth": 4 + }, + "excludes": [ + "**/.venv/**", + "**/assets/**", + "**/scratch-editor/**", + "**/build/**" + ], + "plugins": [ + "https://plugins.dprint.dev/json-0.19.4.wasm", + "https://plugins.dprint.dev/markdown-0.17.8.wasm", + "https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.0.wasm", + "https://plugins.dprint.dev/ruff-0.3.9.wasm", + "https://plugins.dprint.dev/typescript-0.95.12.wasm" + ] +} diff --git a/python/main.py b/python/main.py index 554091d..4e13889 100644 --- a/python/main.py +++ b/python/main.py @@ -3,33 +3,31 @@ import time ui = WebUI() -ui.on_connect( - lambda sid: ( - print(f"Client connected: {sid} "), - ) -) +ui.on_connect(lambda sid: (print(f"Client connected: {sid} "),)) def on_matrix_draw(_, data): print(f"Received frame to draw on matrix: {data}") # from 5x5 to 8x13 matrix - frame_5x5 = data.get('frame') - row0 = "0"*13 - row1 = "0"*4 + frame_5x5[0:5] + "0"*4 - row2 = "0"*4 + frame_5x5[5:10] + "0"*4 - row3 = "0"*4 + frame_5x5[10:15] + "0"*4 - row4 = "0"*4 + frame_5x5[15:20] + "0"*4 - row5 = "0"*4 + frame_5x5[20:25] + "0"*4 - row6 = "0"*13 - row7 = "0"*13 + frame_5x5 = data.get("frame") + row0 = "0" * 13 + row1 = "0" * 4 + frame_5x5[0:5] + "0" * 4 + row2 = "0" * 4 + frame_5x5[5:10] + "0" * 4 + row3 = "0" * 4 + frame_5x5[10:15] + "0" * 4 + row4 = "0" * 4 + frame_5x5[15:20] + "0" * 4 + row5 = "0" * 4 + frame_5x5[20:25] + "0" * 4 + row6 = "0" * 13 + row7 = "0" * 13 frame_8x13 = row0 + row1 + row2 + row3 + row4 + row5 + row6 + row7 print(f"Transformed frame to draw on 8x13 matrix: {frame_8x13}") Bridge.call("matrix_draw", frame_8x13) + def rgb_to_digital(value, threshold=128) -> bool: """Convert RGB value (0-255) to digital HIGH(1) or LOW(0)""" return value >= threshold + def on_set_led_rgb(_, data): led = data.get("led") r = data.get("r") @@ -41,14 +39,19 @@ def on_set_led_rgb(_, data): g_digital = rgb_to_digital(g) b_digital = rgb_to_digital(b) - print(f"Setting LED {led} to color: RGB({r},{g},{b}) -> Digital({r_digital},{g_digital},{b_digital})") + print( + f"Setting LED {led} to color: RGB({r},{g},{b}) -> Digital({r_digital},{g_digital},{b_digital})" + ) Bridge.call("set_led_rgb", led, r_digital, g_digital, b_digital) + ui.on_message("matrix_draw", on_matrix_draw) ui.on_message("set_led_rgb", on_set_led_rgb) + def on_modulino_button_pressed(btn): - ui.send_message('modulino_buttons_pressed', {"btn": btn}) + ui.send_message("modulino_buttons_pressed", {"btn": btn}) + Bridge.provide("modulino_button_pressed", on_modulino_button_pressed) diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js index b2e6376..c45b3ce 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js @@ -1,21 +1,23 @@ // const formatMessage = require('../../../../../../scratch-editor/node_modules/format-message'); -const BlockType = require('../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/block-type'); -const ArgumentType = require('../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/argument-type'); -const io = require('../socket.io.min.js'); +const BlockType = require("../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/block-type"); +const ArgumentType = require( + "../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/argument-type", +); +const io = require("../socket.io.min.js"); /** * Url of icon to be displayed at the left edge of each extension block. * @type {string} */ // eslint-disable-next-line max-len -const iconURI = ''; +const iconURI = ""; /** * Url of icon to be displayed in the toolbox menu for the extension category. * @type {string} */ // eslint-disable-next-line max-len -const menuIconURI = '' +const menuIconURI = ""; const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; @@ -24,81 +26,81 @@ class ArduinoBasics { this.runtime = runtime; this.io = io(wsServerURL, { - path: '/socket.io', - transports: ['polling', 'websocket'], - autoConnect: true + path: "/socket.io", + transports: ["polling", "websocket"], + autoConnect: true, }); } -}; +} -ArduinoBasics.prototype.getInfo = function () { +ArduinoBasics.prototype.getInfo = function() { return { - id: 'arduinobasics', + id: "arduinobasics", name: "Arduino Basics", menuIconURI: menuIconURI, blockIconURI: iconURI, blocks: [ { - opcode: 'matrixDraw', + opcode: "matrixDraw", blockType: BlockType.COMMAND, - text: 'draw [FRAME] on matrix', - func: 'matrixDraw', + text: "draw [FRAME] on matrix", + func: "matrixDraw", arguments: { FRAME: { type: ArgumentType.MATRIX, - defaultValue: '0101010101100010101000100' - } - } + defaultValue: "0101010101100010101000100", + }, + }, }, { - opcode: 'setLed3', + opcode: "setLed3", blockType: BlockType.COMMAND, - text: 'set LED 3 to [HEX]', - func: 'setLed3', + text: "set LED 3 to [HEX]", + func: "setLed3", arguments: { HEX: { type: ArgumentType.COLOR, - defaultValue: '#ff0000' - } - } + defaultValue: "#ff0000", + }, + }, }, - { - opcode: 'setLed4', + { + opcode: "setLed4", blockType: BlockType.COMMAND, - text: 'set LED 4 to [HEX]', - func: 'setLed4', + text: "set LED 4 to [HEX]", + func: "setLed4", arguments: { HEX: { type: ArgumentType.COLOR, - defaultValue: '#0000ff' - } - } - } - ] + defaultValue: "#0000ff", + }, + }, + }, + ], }; -} +}; -ArduinoBasics.prototype.matrixDraw = function (args) { +ArduinoBasics.prototype.matrixDraw = function(args) { console.log(`Drawing frame on matrix: ${args}`); this.io.emit("matrix_draw", { frame: args.FRAME }); }; -ArduinoBasics.prototype.setLed3 = function (args) { +ArduinoBasics.prototype.setLed3 = function(args) { const hexColor = args.HEX; const rgb = this.hexToRgb(hexColor); console.log(`Setting led 3 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`); - this.io.emit("set_led_rgb", {led: "LED3", r: rgb.r, g: rgb.g,b: rgb.b}); + this.io.emit("set_led_rgb", { led: "LED3", r: rgb.r, g: rgb.g, b: rgb.b }); }; -ArduinoBasics.prototype.setLed4 = function (args) { +ArduinoBasics.prototype.setLed4 = function(args) { const hexColor = args.HEX; const rgb = this.hexToRgb(hexColor); console.log(`Setting led 4 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`); - this.io.emit("set_led_rgb", {led: "LED4", r: rgb.r, g: rgb.g,b: rgb.b}); + this.io.emit("set_led_rgb", { led: "LED4", r: rgb.r, g: rgb.g, b: rgb.b }); }; -ArduinoBasics.prototype.hexToRgb = function (hex) { - hex = hex.replace('#', ''); +ArduinoBasics.prototype.hexToRgb = function(hex) { + hex = hex.replace("#", ""); const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_modulino/index.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_modulino/index.js index adb39e0..4b3fb5a 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_modulino/index.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_modulino/index.js @@ -1,21 +1,22 @@ -const BlockType = require('../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/block-type'); -const ArgumentType = require('../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/argument-type'); -const io = require('../socket.io.min.js'); - +const BlockType = require("../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/block-type"); +const ArgumentType = require( + "../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/argument-type", +); +const io = require("../socket.io.min.js"); /** * Url of icon to be displayed at the left edge of each extension block. * @type {string} */ // eslint-disable-next-line max-len -const iconURI = ''; +const iconURI = ""; /** * Url of icon to be displayed in the toolbox menu for the extension category. * @type {string} */ // eslint-disable-next-line max-len -const menuIconURI = '' +const menuIconURI = ""; const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; @@ -23,50 +24,50 @@ class ArduinoModulino { constructor(runtime) { this.runtime = runtime; this.io = io(wsServerURL, { - path: '/socket.io', - transports: ['polling', 'websocket'], - autoConnect: true + path: "/socket.io", + transports: ["polling", "websocket"], + autoConnect: true, }); // TODO: move to ModulinoPeripheral - this._button_pressed = ''; - this.io.on('modulino_buttons_pressed', (data) => { + this._button_pressed = ""; + this.io.on("modulino_buttons_pressed", (data) => { console.log(`Modulino button pressed event received: ${data.btn}`); this._button_pressed = data.btn.toUpperCase(); }); } -}; +} -ArduinoModulino.prototype.getInfo = function () { +ArduinoModulino.prototype.getInfo = function() { return { - id: 'arduinomodulino', + id: "arduinomodulino", name: "Arduino Modulino", menuIconURI: menuIconURI, blockIconURI: iconURI, blocks: [ { - opcode: 'whenModulinoButtonsPressed', + opcode: "whenModulinoButtonsPressed", blockType: BlockType.HAT, - text: 'when modulino button [BTN] pressed', - func: 'whenModulinoButtonsPressed', + text: "when modulino button [BTN] pressed", + func: "whenModulinoButtonsPressed", arguments: { BTN: { type: ArgumentType.STRING, - menu: 'modulinoButtons', - defaultValue: "A" - } - } + menu: "modulinoButtons", + defaultValue: "A", + }, + }, }, ], menus: { - modulinoButtons: ["A", "B", "C"] - } + modulinoButtons: ["A", "B", "C"], + }, }; -} +}; -ArduinoModulino.prototype.whenModulinoButtonsPressed = function (args) { +ArduinoModulino.prototype.whenModulinoButtonsPressed = function(args) { if (args.BTN === this._button_pressed) { - this._button_pressed = ''; + this._button_pressed = ""; return true; } return false; diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/socket.io.min.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/socket.io.min.js index 530b185..8cd21de 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/socket.io.min.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/socket.io.min.js @@ -1,6 +1,7 @@ +// dprint-ignore-file /*! * Socket.IO v4.8.1 * (c) 2014-2024 Guillermo Rauch * Released under the MIT License. */ -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).io=n()}(this,(function(){"use strict";function t(t,n){(null==n||n>t.length)&&(n=t.length);for(var i=0,r=Array(n);i=n.length?{done:!0}:{done:!1,value:n[e++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,u=!0,h=!1;return{s:function(){r=r.call(n)},n:function(){var t=r.next();return u=t.done,t},e:function(t){h=!0,s=t},f:function(){try{u||null==r.return||r.return()}finally{if(h)throw s}}}}function e(){return e=Object.assign?Object.assign.bind():function(t){for(var n=1;n1?{type:l[i],data:t.substring(1)}:{type:l[i]}:d},N=function(t,n){if(B){var i=function(t){var n,i,r,e,o,s=.75*t.length,u=t.length,h=0;"="===t[t.length-1]&&(s--,"="===t[t.length-2]&&s--);var f=new ArrayBuffer(s),c=new Uint8Array(f);for(n=0;n>4,c[h++]=(15&r)<<4|e>>2,c[h++]=(3&e)<<6|63&o;return f}(t);return C(i,n)}return{base64:!0,data:t}},C=function(t,n){return"blob"===n?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer},T=String.fromCharCode(30);function U(){return new TransformStream({transform:function(t,n){!function(t,n){y&&t.data instanceof Blob?t.data.arrayBuffer().then(k).then(n):b&&(t.data instanceof ArrayBuffer||w(t.data))?n(k(t.data)):g(t,!1,(function(t){p||(p=new TextEncoder),n(p.encode(t))}))}(t,(function(i){var r,e=i.length;if(e<126)r=new Uint8Array(1),new DataView(r.buffer).setUint8(0,e);else if(e<65536){r=new Uint8Array(3);var o=new DataView(r.buffer);o.setUint8(0,126),o.setUint16(1,e)}else{r=new Uint8Array(9);var s=new DataView(r.buffer);s.setUint8(0,127),s.setBigUint64(1,BigInt(e))}t.data&&"string"!=typeof t.data&&(r[0]|=128),n.enqueue(r),n.enqueue(i)}))}})}function M(t){return t.reduce((function(t,n){return t+n.length}),0)}function x(t,n){if(t[0].length===n)return t.shift();for(var i=new Uint8Array(n),r=0,e=0;e1?n-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:{};return t+"://"+this.i()+this.o()+this.opts.path+this.u(n)},i.i=function(){var t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"},i.o=function(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""},i.u=function(t){var n=function(t){var n="";for(var i in t)t.hasOwnProperty(i)&&(n.length&&(n+="&"),n+=encodeURIComponent(i)+"="+encodeURIComponent(t[i]));return n}(t);return n.length?"?"+n:""},n}(I),X=function(t){function n(){var n;return(n=t.apply(this,arguments)||this).h=!1,n}s(n,t);var r=n.prototype;return r.doOpen=function(){this.v()},r.pause=function(t){var n=this;this.readyState="pausing";var i=function(){n.readyState="paused",t()};if(this.h||!this.writable){var r=0;this.h&&(r++,this.once("pollComplete",(function(){--r||i()}))),this.writable||(r++,this.once("drain",(function(){--r||i()})))}else i()},r.v=function(){this.h=!0,this.doPoll(),this.emitReserved("poll")},r.onData=function(t){var n=this;(function(t,n){for(var i=t.split(T),r=[],e=0;e0&&void 0!==arguments[0]?arguments[0]:{};return e(t,{xd:this.xd},this.opts),new Y(tt,this.uri(),t)},n}(K);function tt(t){var n=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!n||z))return new XMLHttpRequest}catch(t){}if(!n)try{return new(L[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}var nt="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),it=function(t){function n(){return t.apply(this,arguments)||this}s(n,t);var r=n.prototype;return r.doOpen=function(){var t=this.uri(),n=this.opts.protocols,i=nt?{}:_(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(i.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,n,i)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()},r.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.opts.autoUnref&&t.ws.C.unref(),t.onOpen()},this.ws.onclose=function(n){return t.onClose({description:"websocket connection closed",context:n})},this.ws.onmessage=function(n){return t.onData(n.data)},this.ws.onerror=function(n){return t.onError("websocket error",n)}},r.write=function(t){var n=this;this.writable=!1;for(var i=function(){var i=t[r],e=r===t.length-1;g(i,n.supportsBinary,(function(t){try{n.doWrite(i,t)}catch(t){}e&&R((function(){n.writable=!0,n.emitReserved("drain")}),n.setTimeoutFn)}))},r=0;rMath.pow(2,21)-1){u.enqueue(d);break}e=v*Math.pow(2,32)+a.getUint32(4),r=3}else{if(M(i)t){u.enqueue(d);break}}}})}(Number.MAX_SAFE_INTEGER,t.socket.binaryType),r=n.readable.pipeThrough(i).getReader(),e=U();e.readable.pipeTo(n.writable),t.U=e.writable.getWriter();!function n(){r.read().then((function(i){var r=i.done,e=i.value;r||(t.onPacket(e),n())})).catch((function(t){}))}();var o={type:"open"};t.query.sid&&(o.data='{"sid":"'.concat(t.query.sid,'"}')),t.U.write(o).then((function(){return t.onOpen()}))}))}))},r.write=function(t){var n=this;this.writable=!1;for(var i=function(){var i=t[r],e=r===t.length-1;n.U.write(i).then((function(){e&&R((function(){n.writable=!0,n.emitReserved("drain")}),n.setTimeoutFn)}))},r=0;r8e3)throw"URI too long";var n=t,i=t.indexOf("["),r=t.indexOf("]");-1!=i&&-1!=r&&(t=t.substring(0,i)+t.substring(i,r).replace(/:/g,";")+t.substring(r,t.length));for(var e,o,s=ut.exec(t||""),u={},h=14;h--;)u[ht[h]]=s[h]||"";return-1!=i&&-1!=r&&(u.source=n,u.host=u.host.substring(1,u.host.length-1).replace(/;/g,":"),u.authority=u.authority.replace("[","").replace("]","").replace(/;/g,":"),u.ipv6uri=!0),u.pathNames=function(t,n){var i=/\/{2,9}/g,r=n.replace(i,"/").split("/");"/"!=n.slice(0,1)&&0!==n.length||r.splice(0,1);"/"==n.slice(-1)&&r.splice(r.length-1,1);return r}(0,u.path),u.queryKey=(e=u.query,o={},e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,n,i){n&&(o[n]=i)})),o),u}var ct="function"==typeof addEventListener&&"function"==typeof removeEventListener,at=[];ct&&addEventListener("offline",(function(){at.forEach((function(t){return t()}))}),!1);var vt=function(t){function n(n,i){var r;if((r=t.call(this)||this).binaryType="arraybuffer",r.writeBuffer=[],r.M=0,r.I=-1,r.R=-1,r.L=-1,r._=1/0,n&&"object"===c(n)&&(i=n,n=null),n){var o=ft(n);i.hostname=o.host,i.secure="https"===o.protocol||"wss"===o.protocol,i.port=o.port,o.query&&(i.query=o.query)}else i.host&&(i.hostname=ft(i.host).host);return $(r,i),r.secure=null!=i.secure?i.secure:"undefined"!=typeof location&&"https:"===location.protocol,i.hostname&&!i.port&&(i.port=r.secure?"443":"80"),r.hostname=i.hostname||("undefined"!=typeof location?location.hostname:"localhost"),r.port=i.port||("undefined"!=typeof location&&location.port?location.port:r.secure?"443":"80"),r.transports=[],r.D={},i.transports.forEach((function(t){var n=t.prototype.name;r.transports.push(n),r.D[n]=t})),r.opts=e({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},i),r.opts.path=r.opts.path.replace(/\/$/,"")+(r.opts.addTrailingSlash?"/":""),"string"==typeof r.opts.query&&(r.opts.query=function(t){for(var n={},i=t.split("&"),r=0,e=i.length;r1))return this.writeBuffer;for(var t,n=1,i=0;i=57344?i+=3:(r++,i+=4);return i}(t):Math.ceil(1.33*(t.byteLength||t.size))),i>0&&n>this.L)return this.writeBuffer.slice(0,i);n+=2}return this.writeBuffer},i.W=function(){var t=this;if(!this._)return!0;var n=Date.now()>this._;return n&&(this._=0,R((function(){t.F("ping timeout")}),this.setTimeoutFn)),n},i.write=function(t,n,i){return this.J("message",t,n,i),this},i.send=function(t,n,i){return this.J("message",t,n,i),this},i.J=function(t,n,i,r){if("function"==typeof n&&(r=n,n=void 0),"function"==typeof i&&(r=i,i=null),"closing"!==this.readyState&&"closed"!==this.readyState){(i=i||{}).compress=!1!==i.compress;var e={type:t,data:n,options:i};this.emitReserved("packetCreate",e),this.writeBuffer.push(e),r&&this.once("flush",r),this.flush()}},i.close=function(){var t=this,n=function(){t.F("forced close"),t.transport.close()},i=function i(){t.off("upgrade",i),t.off("upgradeError",i),n()},r=function(){t.once("upgrade",i),t.once("upgradeError",i)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",(function(){t.upgrading?r():n()})):this.upgrading?r():n()),this},i.B=function(t){if(n.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this.q();this.emitReserved("error",t),this.F("transport error",t)},i.F=function(t,n){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this.Y),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),ct&&(this.P&&removeEventListener("beforeunload",this.P,!1),this.$)){var i=at.indexOf(this.$);-1!==i&&at.splice(i,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,n),this.writeBuffer=[],this.M=0}},n}(I);vt.protocol=4;var lt=function(t){function n(){var n;return(n=t.apply(this,arguments)||this).Z=[],n}s(n,t);var i=n.prototype;return i.onOpen=function(){if(t.prototype.onOpen.call(this),"open"===this.readyState&&this.opts.upgrade)for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},r="object"===c(n)?n:i;return(!r.transports||r.transports&&"string"==typeof r.transports[0])&&(r.transports=(r.transports||["polling","websocket","webtransport"]).map((function(t){return st[t]})).filter((function(t){return!!t}))),t.call(this,n,r)||this}return s(n,t),n}(lt);pt.protocol;var dt="function"==typeof ArrayBuffer,yt=function(t){return"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer},bt=Object.prototype.toString,wt="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===bt.call(Blob),gt="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===bt.call(File);function mt(t){return dt&&(t instanceof ArrayBuffer||yt(t))||wt&&t instanceof Blob||gt&&t instanceof File}function kt(t,n){if(!t||"object"!==c(t))return!1;if(Array.isArray(t)){for(var i=0,r=t.length;i=0&&t.num1?e-1:0),s=1;s1?i-1:0),e=1;ei.l.retries&&(i.it.shift(),n&&n(t));else if(i.it.shift(),n){for(var e=arguments.length,o=new Array(e>1?e-1:0),s=1;s0&&void 0!==arguments[0]&&arguments[0];if(this.connected&&0!==this.it.length){var n=this.it[0];n.pending&&!t||(n.pending=!0,n.tryCount++,this.flags=n.flags,this.emit.apply(this,n.args))}},o.packet=function(t){t.nsp=this.nsp,this.io.ct(t)},o.onopen=function(){var t=this;"function"==typeof this.auth?this.auth((function(n){t.vt(n)})):this.vt(this.auth)},o.vt=function(t){this.packet({type:Bt.CONNECT,data:this.lt?e({pid:this.lt,offset:this.dt},t):t})},o.onerror=function(t){this.connected||this.emitReserved("connect_error",t)},o.onclose=function(t,n){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,n),this.yt()},o.yt=function(){var t=this;Object.keys(this.acks).forEach((function(n){if(!t.sendBuffer.some((function(t){return String(t.id)===n}))){var i=t.acks[n];delete t.acks[n],i.withError&&i.call(t,new Error("socket has been disconnected"))}}))},o.onpacket=function(t){if(t.nsp===this.nsp)switch(t.type){case Bt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case Bt.EVENT:case Bt.BINARY_EVENT:this.onevent(t);break;case Bt.ACK:case Bt.BINARY_ACK:this.onack(t);break;case Bt.DISCONNECT:this.ondisconnect();break;case Bt.CONNECT_ERROR:this.destroy();var n=new Error(t.data.message);n.data=t.data.data,this.emitReserved("connect_error",n)}},o.onevent=function(t){var n=t.data||[];null!=t.id&&n.push(this.ack(t.id)),this.connected?this.emitEvent(n):this.receiveBuffer.push(Object.freeze(n))},o.emitEvent=function(n){if(this.bt&&this.bt.length){var i,e=r(this.bt.slice());try{for(e.s();!(i=e.n()).done;){i.value.apply(this,n)}}catch(t){e.e(t)}finally{e.f()}}t.prototype.emit.apply(this,n),this.lt&&n.length&&"string"==typeof n[n.length-1]&&(this.dt=n[n.length-1])},o.ack=function(t){var n=this,i=!1;return function(){if(!i){i=!0;for(var r=arguments.length,e=new Array(r),o=0;o0&&t.jitter<=1?t.jitter:0,this.attempts=0}_t.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var n=Math.random(),i=Math.floor(n*this.jitter*t);t=1&Math.floor(10*n)?t+i:t-i}return 0|Math.min(t,this.max)},_t.prototype.reset=function(){this.attempts=0},_t.prototype.setMin=function(t){this.ms=t},_t.prototype.setMax=function(t){this.max=t},_t.prototype.setJitter=function(t){this.jitter=t};var Dt=function(t){function n(n,i){var r,e;(r=t.call(this)||this).nsps={},r.subs=[],n&&"object"===c(n)&&(i=n,n=void 0),(i=i||{}).path=i.path||"/socket.io",r.opts=i,$(r,i),r.reconnection(!1!==i.reconnection),r.reconnectionAttempts(i.reconnectionAttempts||1/0),r.reconnectionDelay(i.reconnectionDelay||1e3),r.reconnectionDelayMax(i.reconnectionDelayMax||5e3),r.randomizationFactor(null!==(e=i.randomizationFactor)&&void 0!==e?e:.5),r.backoff=new _t({min:r.reconnectionDelay(),max:r.reconnectionDelayMax(),jitter:r.randomizationFactor()}),r.timeout(null==i.timeout?2e4:i.timeout),r.st="closed",r.uri=n;var o=i.parser||xt;return r.encoder=new o.Encoder,r.decoder=new o.Decoder,r.et=!1!==i.autoConnect,r.et&&r.open(),r}s(n,t);var i=n.prototype;return i.reconnection=function(t){return arguments.length?(this.kt=!!t,t||(this.skipReconnect=!0),this):this.kt},i.reconnectionAttempts=function(t){return void 0===t?this.At:(this.At=t,this)},i.reconnectionDelay=function(t){var n;return void 0===t?this.jt:(this.jt=t,null===(n=this.backoff)||void 0===n||n.setMin(t),this)},i.randomizationFactor=function(t){var n;return void 0===t?this.Et:(this.Et=t,null===(n=this.backoff)||void 0===n||n.setJitter(t),this)},i.reconnectionDelayMax=function(t){var n;return void 0===t?this.Ot:(this.Ot=t,null===(n=this.backoff)||void 0===n||n.setMax(t),this)},i.timeout=function(t){return arguments.length?(this.Bt=t,this):this.Bt},i.maybeReconnectOnOpen=function(){!this.ot&&this.kt&&0===this.backoff.attempts&&this.reconnect()},i.open=function(t){var n=this;if(~this.st.indexOf("open"))return this;this.engine=new pt(this.uri,this.opts);var i=this.engine,r=this;this.st="opening",this.skipReconnect=!1;var e=It(i,"open",(function(){r.onopen(),t&&t()})),o=function(i){n.cleanup(),n.st="closed",n.emitReserved("error",i),t?t(i):n.maybeReconnectOnOpen()},s=It(i,"error",o);if(!1!==this.Bt){var u=this.Bt,h=this.setTimeoutFn((function(){e(),o(new Error("timeout")),i.close()}),u);this.opts.autoUnref&&h.unref(),this.subs.push((function(){n.clearTimeoutFn(h)}))}return this.subs.push(e),this.subs.push(s),this},i.connect=function(t){return this.open(t)},i.onopen=function(){this.cleanup(),this.st="open",this.emitReserved("open");var t=this.engine;this.subs.push(It(t,"ping",this.onping.bind(this)),It(t,"data",this.ondata.bind(this)),It(t,"error",this.onerror.bind(this)),It(t,"close",this.onclose.bind(this)),It(this.decoder,"decoded",this.ondecoded.bind(this)))},i.onping=function(){this.emitReserved("ping")},i.ondata=function(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}},i.ondecoded=function(t){var n=this;R((function(){n.emitReserved("packet",t)}),this.setTimeoutFn)},i.onerror=function(t){this.emitReserved("error",t)},i.socket=function(t,n){var i=this.nsps[t];return i?this.et&&!i.active&&i.connect():(i=new Lt(this,t,n),this.nsps[t]=i),i},i.wt=function(t){for(var n=0,i=Object.keys(this.nsps);n=this.At)this.backoff.reset(),this.emitReserved("reconnect_failed"),this.ot=!1;else{var i=this.backoff.duration();this.ot=!0;var r=this.setTimeoutFn((function(){n.skipReconnect||(t.emitReserved("reconnect_attempt",n.backoff.attempts),n.skipReconnect||n.open((function(i){i?(n.ot=!1,n.reconnect(),t.emitReserved("reconnect_error",i)):n.onreconnect()})))}),i);this.opts.autoUnref&&r.unref(),this.subs.push((function(){t.clearTimeoutFn(r)}))}},i.onreconnect=function(){var t=this.backoff.attempts;this.ot=!1,this.backoff.reset(),this.emitReserved("reconnect",t)},n}(I),Pt={};function $t(t,n){"object"===c(t)&&(n=t,t=void 0);var i,r=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2?arguments[2]:void 0,r=t;i=i||"undefined"!=typeof location&&location,null==t&&(t=i.protocol+"//"+i.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?i.protocol+t:i.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==i?i.protocol+"//"+t:"https://"+t),r=ft(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var e=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+e+":"+r.port+n,r.href=r.protocol+"://"+e+(i&&i.port===r.port?"":":"+r.port),r}(t,(n=n||{}).path||"/socket.io"),e=r.source,o=r.id,s=r.path,u=Pt[o]&&s in Pt[o].nsps;return n.forceNew||n["force new connection"]||!1===n.multiplex||u?i=new Dt(e,n):(Pt[o]||(Pt[o]=new Dt(e,n)),i=Pt[o]),r.query&&!n.query&&(n.query=r.queryKey),i.socket(r.path,n)}return e($t,{Manager:Dt,Socket:Lt,io:$t,connect:$t}),$t})); \ No newline at end of file +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).io=n()}(this,(function(){"use strict";function t(t,n){(null==n||n>t.length)&&(n=t.length);for(var i=0,r=Array(n);i=n.length?{done:!0}:{done:!1,value:n[e++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,u=!0,h=!1;return{s:function(){r=r.call(n)},n:function(){var t=r.next();return u=t.done,t},e:function(t){h=!0,s=t},f:function(){try{u||null==r.return||r.return()}finally{if(h)throw s}}}}function e(){return e=Object.assign?Object.assign.bind():function(t){for(var n=1;n1?{type:l[i],data:t.substring(1)}:{type:l[i]}:d},N=function(t,n){if(B){var i=function(t){var n,i,r,e,o,s=.75*t.length,u=t.length,h=0;"="===t[t.length-1]&&(s--,"="===t[t.length-2]&&s--);var f=new ArrayBuffer(s),c=new Uint8Array(f);for(n=0;n>4,c[h++]=(15&r)<<4|e>>2,c[h++]=(3&e)<<6|63&o;return f}(t);return C(i,n)}return{base64:!0,data:t}},C=function(t,n){return"blob"===n?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer},T=String.fromCharCode(30);function U(){return new TransformStream({transform:function(t,n){!function(t,n){y&&t.data instanceof Blob?t.data.arrayBuffer().then(k).then(n):b&&(t.data instanceof ArrayBuffer||w(t.data))?n(k(t.data)):g(t,!1,(function(t){p||(p=new TextEncoder),n(p.encode(t))}))}(t,(function(i){var r,e=i.length;if(e<126)r=new Uint8Array(1),new DataView(r.buffer).setUint8(0,e);else if(e<65536){r=new Uint8Array(3);var o=new DataView(r.buffer);o.setUint8(0,126),o.setUint16(1,e)}else{r=new Uint8Array(9);var s=new DataView(r.buffer);s.setUint8(0,127),s.setBigUint64(1,BigInt(e))}t.data&&"string"!=typeof t.data&&(r[0]|=128),n.enqueue(r),n.enqueue(i)}))}})}function M(t){return t.reduce((function(t,n){return t+n.length}),0)}function x(t,n){if(t[0].length===n)return t.shift();for(var i=new Uint8Array(n),r=0,e=0;e1?n-1:0),r=1;r1&&void 0!==arguments[1]?arguments[1]:{};return t+"://"+this.i()+this.o()+this.opts.path+this.u(n)},i.i=function(){var t=this.opts.hostname;return-1===t.indexOf(":")?t:"["+t+"]"},i.o=function(){return this.opts.port&&(this.opts.secure&&Number(443!==this.opts.port)||!this.opts.secure&&80!==Number(this.opts.port))?":"+this.opts.port:""},i.u=function(t){var n=function(t){var n="";for(var i in t)t.hasOwnProperty(i)&&(n.length&&(n+="&"),n+=encodeURIComponent(i)+"="+encodeURIComponent(t[i]));return n}(t);return n.length?"?"+n:""},n}(I),X=function(t){function n(){var n;return(n=t.apply(this,arguments)||this).h=!1,n}s(n,t);var r=n.prototype;return r.doOpen=function(){this.v()},r.pause=function(t){var n=this;this.readyState="pausing";var i=function(){n.readyState="paused",t()};if(this.h||!this.writable){var r=0;this.h&&(r++,this.once("pollComplete",(function(){--r||i()}))),this.writable||(r++,this.once("drain",(function(){--r||i()})))}else i()},r.v=function(){this.h=!0,this.doPoll(),this.emitReserved("poll")},r.onData=function(t){var n=this;(function(t,n){for(var i=t.split(T),r=[],e=0;e0&&void 0!==arguments[0]?arguments[0]:{};return e(t,{xd:this.xd},this.opts),new Y(tt,this.uri(),t)},n}(K);function tt(t){var n=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!n||z))return new XMLHttpRequest}catch(t){}if(!n)try{return new(L[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}var nt="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),it=function(t){function n(){return t.apply(this,arguments)||this}s(n,t);var r=n.prototype;return r.doOpen=function(){var t=this.uri(),n=this.opts.protocols,i=nt?{}:_(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(i.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(t,n,i)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()},r.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.opts.autoUnref&&t.ws.C.unref(),t.onOpen()},this.ws.onclose=function(n){return t.onClose({description:"websocket connection closed",context:n})},this.ws.onmessage=function(n){return t.onData(n.data)},this.ws.onerror=function(n){return t.onError("websocket error",n)}},r.write=function(t){var n=this;this.writable=!1;for(var i=function(){var i=t[r],e=r===t.length-1;g(i,n.supportsBinary,(function(t){try{n.doWrite(i,t)}catch(t){}e&&R((function(){n.writable=!0,n.emitReserved("drain")}),n.setTimeoutFn)}))},r=0;rMath.pow(2,21)-1){u.enqueue(d);break}e=v*Math.pow(2,32)+a.getUint32(4),r=3}else{if(M(i)t){u.enqueue(d);break}}}})}(Number.MAX_SAFE_INTEGER,t.socket.binaryType),r=n.readable.pipeThrough(i).getReader(),e=U();e.readable.pipeTo(n.writable),t.U=e.writable.getWriter();!function n(){r.read().then((function(i){var r=i.done,e=i.value;r||(t.onPacket(e),n())})).catch((function(t){}))}();var o={type:"open"};t.query.sid&&(o.data='{"sid":"'.concat(t.query.sid,'"}')),t.U.write(o).then((function(){return t.onOpen()}))}))}))},r.write=function(t){var n=this;this.writable=!1;for(var i=function(){var i=t[r],e=r===t.length-1;n.U.write(i).then((function(){e&&R((function(){n.writable=!0,n.emitReserved("drain")}),n.setTimeoutFn)}))},r=0;r8e3)throw"URI too long";var n=t,i=t.indexOf("["),r=t.indexOf("]");-1!=i&&-1!=r&&(t=t.substring(0,i)+t.substring(i,r).replace(/:/g,";")+t.substring(r,t.length));for(var e,o,s=ut.exec(t||""),u={},h=14;h--;)u[ht[h]]=s[h]||"";return-1!=i&&-1!=r&&(u.source=n,u.host=u.host.substring(1,u.host.length-1).replace(/;/g,":"),u.authority=u.authority.replace("[","").replace("]","").replace(/;/g,":"),u.ipv6uri=!0),u.pathNames=function(t,n){var i=/\/{2,9}/g,r=n.replace(i,"/").split("/");"/"!=n.slice(0,1)&&0!==n.length||r.splice(0,1);"/"==n.slice(-1)&&r.splice(r.length-1,1);return r}(0,u.path),u.queryKey=(e=u.query,o={},e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,n,i){n&&(o[n]=i)})),o),u}var ct="function"==typeof addEventListener&&"function"==typeof removeEventListener,at=[];ct&&addEventListener("offline",(function(){at.forEach((function(t){return t()}))}),!1);var vt=function(t){function n(n,i){var r;if((r=t.call(this)||this).binaryType="arraybuffer",r.writeBuffer=[],r.M=0,r.I=-1,r.R=-1,r.L=-1,r._=1/0,n&&"object"===c(n)&&(i=n,n=null),n){var o=ft(n);i.hostname=o.host,i.secure="https"===o.protocol||"wss"===o.protocol,i.port=o.port,o.query&&(i.query=o.query)}else i.host&&(i.hostname=ft(i.host).host);return $(r,i),r.secure=null!=i.secure?i.secure:"undefined"!=typeof location&&"https:"===location.protocol,i.hostname&&!i.port&&(i.port=r.secure?"443":"80"),r.hostname=i.hostname||("undefined"!=typeof location?location.hostname:"localhost"),r.port=i.port||("undefined"!=typeof location&&location.port?location.port:r.secure?"443":"80"),r.transports=[],r.D={},i.transports.forEach((function(t){var n=t.prototype.name;r.transports.push(n),r.D[n]=t})),r.opts=e({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},i),r.opts.path=r.opts.path.replace(/\/$/,"")+(r.opts.addTrailingSlash?"/":""),"string"==typeof r.opts.query&&(r.opts.query=function(t){for(var n={},i=t.split("&"),r=0,e=i.length;r1))return this.writeBuffer;for(var t,n=1,i=0;i=57344?i+=3:(r++,i+=4);return i}(t):Math.ceil(1.33*(t.byteLength||t.size))),i>0&&n>this.L)return this.writeBuffer.slice(0,i);n+=2}return this.writeBuffer},i.W=function(){var t=this;if(!this._)return!0;var n=Date.now()>this._;return n&&(this._=0,R((function(){t.F("ping timeout")}),this.setTimeoutFn)),n},i.write=function(t,n,i){return this.J("message",t,n,i),this},i.send=function(t,n,i){return this.J("message",t,n,i),this},i.J=function(t,n,i,r){if("function"==typeof n&&(r=n,n=void 0),"function"==typeof i&&(r=i,i=null),"closing"!==this.readyState&&"closed"!==this.readyState){(i=i||{}).compress=!1!==i.compress;var e={type:t,data:n,options:i};this.emitReserved("packetCreate",e),this.writeBuffer.push(e),r&&this.once("flush",r),this.flush()}},i.close=function(){var t=this,n=function(){t.F("forced close"),t.transport.close()},i=function i(){t.off("upgrade",i),t.off("upgradeError",i),n()},r=function(){t.once("upgrade",i),t.once("upgradeError",i)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",(function(){t.upgrading?r():n()})):this.upgrading?r():n()),this},i.B=function(t){if(n.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&"opening"===this.readyState)return this.transports.shift(),this.q();this.emitReserved("error",t),this.F("transport error",t)},i.F=function(t,n){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){if(this.clearTimeoutFn(this.Y),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),ct&&(this.P&&removeEventListener("beforeunload",this.P,!1),this.$)){var i=at.indexOf(this.$);-1!==i&&at.splice(i,1)}this.readyState="closed",this.id=null,this.emitReserved("close",t,n),this.writeBuffer=[],this.M=0}},n}(I);vt.protocol=4;var lt=function(t){function n(){var n;return(n=t.apply(this,arguments)||this).Z=[],n}s(n,t);var i=n.prototype;return i.onOpen=function(){if(t.prototype.onOpen.call(this),"open"===this.readyState&&this.opts.upgrade)for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},r="object"===c(n)?n:i;return(!r.transports||r.transports&&"string"==typeof r.transports[0])&&(r.transports=(r.transports||["polling","websocket","webtransport"]).map((function(t){return st[t]})).filter((function(t){return!!t}))),t.call(this,n,r)||this}return s(n,t),n}(lt);pt.protocol;var dt="function"==typeof ArrayBuffer,yt=function(t){return"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer},bt=Object.prototype.toString,wt="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===bt.call(Blob),gt="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===bt.call(File);function mt(t){return dt&&(t instanceof ArrayBuffer||yt(t))||wt&&t instanceof Blob||gt&&t instanceof File}function kt(t,n){if(!t||"object"!==c(t))return!1;if(Array.isArray(t)){for(var i=0,r=t.length;i=0&&t.num1?e-1:0),s=1;s1?i-1:0),e=1;ei.l.retries&&(i.it.shift(),n&&n(t));else if(i.it.shift(),n){for(var e=arguments.length,o=new Array(e>1?e-1:0),s=1;s0&&void 0!==arguments[0]&&arguments[0];if(this.connected&&0!==this.it.length){var n=this.it[0];n.pending&&!t||(n.pending=!0,n.tryCount++,this.flags=n.flags,this.emit.apply(this,n.args))}},o.packet=function(t){t.nsp=this.nsp,this.io.ct(t)},o.onopen=function(){var t=this;"function"==typeof this.auth?this.auth((function(n){t.vt(n)})):this.vt(this.auth)},o.vt=function(t){this.packet({type:Bt.CONNECT,data:this.lt?e({pid:this.lt,offset:this.dt},t):t})},o.onerror=function(t){this.connected||this.emitReserved("connect_error",t)},o.onclose=function(t,n){this.connected=!1,delete this.id,this.emitReserved("disconnect",t,n),this.yt()},o.yt=function(){var t=this;Object.keys(this.acks).forEach((function(n){if(!t.sendBuffer.some((function(t){return String(t.id)===n}))){var i=t.acks[n];delete t.acks[n],i.withError&&i.call(t,new Error("socket has been disconnected"))}}))},o.onpacket=function(t){if(t.nsp===this.nsp)switch(t.type){case Bt.CONNECT:t.data&&t.data.sid?this.onconnect(t.data.sid,t.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case Bt.EVENT:case Bt.BINARY_EVENT:this.onevent(t);break;case Bt.ACK:case Bt.BINARY_ACK:this.onack(t);break;case Bt.DISCONNECT:this.ondisconnect();break;case Bt.CONNECT_ERROR:this.destroy();var n=new Error(t.data.message);n.data=t.data.data,this.emitReserved("connect_error",n)}},o.onevent=function(t){var n=t.data||[];null!=t.id&&n.push(this.ack(t.id)),this.connected?this.emitEvent(n):this.receiveBuffer.push(Object.freeze(n))},o.emitEvent=function(n){if(this.bt&&this.bt.length){var i,e=r(this.bt.slice());try{for(e.s();!(i=e.n()).done;){i.value.apply(this,n)}}catch(t){e.e(t)}finally{e.f()}}t.prototype.emit.apply(this,n),this.lt&&n.length&&"string"==typeof n[n.length-1]&&(this.dt=n[n.length-1])},o.ack=function(t){var n=this,i=!1;return function(){if(!i){i=!0;for(var r=arguments.length,e=new Array(r),o=0;o0&&t.jitter<=1?t.jitter:0,this.attempts=0}_t.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var n=Math.random(),i=Math.floor(n*this.jitter*t);t=1&Math.floor(10*n)?t+i:t-i}return 0|Math.min(t,this.max)},_t.prototype.reset=function(){this.attempts=0},_t.prototype.setMin=function(t){this.ms=t},_t.prototype.setMax=function(t){this.max=t},_t.prototype.setJitter=function(t){this.jitter=t};var Dt=function(t){function n(n,i){var r,e;(r=t.call(this)||this).nsps={},r.subs=[],n&&"object"===c(n)&&(i=n,n=void 0),(i=i||{}).path=i.path||"/socket.io",r.opts=i,$(r,i),r.reconnection(!1!==i.reconnection),r.reconnectionAttempts(i.reconnectionAttempts||1/0),r.reconnectionDelay(i.reconnectionDelay||1e3),r.reconnectionDelayMax(i.reconnectionDelayMax||5e3),r.randomizationFactor(null!==(e=i.randomizationFactor)&&void 0!==e?e:.5),r.backoff=new _t({min:r.reconnectionDelay(),max:r.reconnectionDelayMax(),jitter:r.randomizationFactor()}),r.timeout(null==i.timeout?2e4:i.timeout),r.st="closed",r.uri=n;var o=i.parser||xt;return r.encoder=new o.Encoder,r.decoder=new o.Decoder,r.et=!1!==i.autoConnect,r.et&&r.open(),r}s(n,t);var i=n.prototype;return i.reconnection=function(t){return arguments.length?(this.kt=!!t,t||(this.skipReconnect=!0),this):this.kt},i.reconnectionAttempts=function(t){return void 0===t?this.At:(this.At=t,this)},i.reconnectionDelay=function(t){var n;return void 0===t?this.jt:(this.jt=t,null===(n=this.backoff)||void 0===n||n.setMin(t),this)},i.randomizationFactor=function(t){var n;return void 0===t?this.Et:(this.Et=t,null===(n=this.backoff)||void 0===n||n.setJitter(t),this)},i.reconnectionDelayMax=function(t){var n;return void 0===t?this.Ot:(this.Ot=t,null===(n=this.backoff)||void 0===n||n.setMax(t),this)},i.timeout=function(t){return arguments.length?(this.Bt=t,this):this.Bt},i.maybeReconnectOnOpen=function(){!this.ot&&this.kt&&0===this.backoff.attempts&&this.reconnect()},i.open=function(t){var n=this;if(~this.st.indexOf("open"))return this;this.engine=new pt(this.uri,this.opts);var i=this.engine,r=this;this.st="opening",this.skipReconnect=!1;var e=It(i,"open",(function(){r.onopen(),t&&t()})),o=function(i){n.cleanup(),n.st="closed",n.emitReserved("error",i),t?t(i):n.maybeReconnectOnOpen()},s=It(i,"error",o);if(!1!==this.Bt){var u=this.Bt,h=this.setTimeoutFn((function(){e(),o(new Error("timeout")),i.close()}),u);this.opts.autoUnref&&h.unref(),this.subs.push((function(){n.clearTimeoutFn(h)}))}return this.subs.push(e),this.subs.push(s),this},i.connect=function(t){return this.open(t)},i.onopen=function(){this.cleanup(),this.st="open",this.emitReserved("open");var t=this.engine;this.subs.push(It(t,"ping",this.onping.bind(this)),It(t,"data",this.ondata.bind(this)),It(t,"error",this.onerror.bind(this)),It(t,"close",this.onclose.bind(this)),It(this.decoder,"decoded",this.ondecoded.bind(this)))},i.onping=function(){this.emitReserved("ping")},i.ondata=function(t){try{this.decoder.add(t)}catch(t){this.onclose("parse error",t)}},i.ondecoded=function(t){var n=this;R((function(){n.emitReserved("packet",t)}),this.setTimeoutFn)},i.onerror=function(t){this.emitReserved("error",t)},i.socket=function(t,n){var i=this.nsps[t];return i?this.et&&!i.active&&i.connect():(i=new Lt(this,t,n),this.nsps[t]=i),i},i.wt=function(t){for(var n=0,i=Object.keys(this.nsps);n=this.At)this.backoff.reset(),this.emitReserved("reconnect_failed"),this.ot=!1;else{var i=this.backoff.duration();this.ot=!0;var r=this.setTimeoutFn((function(){n.skipReconnect||(t.emitReserved("reconnect_attempt",n.backoff.attempts),n.skipReconnect||n.open((function(i){i?(n.ot=!1,n.reconnect(),t.emitReserved("reconnect_error",i)):n.onreconnect()})))}),i);this.opts.autoUnref&&r.unref(),this.subs.push((function(){t.clearTimeoutFn(r)}))}},i.onreconnect=function(){var t=this.backoff.attempts;this.ot=!1,this.backoff.reset(),this.emitReserved("reconnect",t)},n}(I),Pt={};function $t(t,n){"object"===c(t)&&(n=t,t=void 0);var i,r=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",i=arguments.length>2?arguments[2]:void 0,r=t;i=i||"undefined"!=typeof location&&location,null==t&&(t=i.protocol+"//"+i.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?i.protocol+t:i.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==i?i.protocol+"//"+t:"https://"+t),r=ft(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var e=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+e+":"+r.port+n,r.href=r.protocol+"://"+e+(i&&i.port===r.port?"":":"+r.port),r}(t,(n=n||{}).path||"/socket.io"),e=r.source,o=r.id,s=r.path,u=Pt[o]&&s in Pt[o].nsps;return n.forceNew||n["force new connection"]||!1===n.multiplex||u?i=new Dt(e,n):(Pt[o]||(Pt[o]=new Dt(e,n)),i=Pt[o]),r.query&&!n.query&&(n.query=r.queryKey),i.socket(r.path,n)}return e($t,{Manager:Dt,Socket:Lt,io:$t,connect:$t}),$t})); diff --git a/scratch-arduino-extensions/scripts/patch-gui.js b/scratch-arduino-extensions/scripts/patch-gui.js index 6da7d94..9e89210 100644 --- a/scratch-arduino-extensions/scripts/patch-gui.js +++ b/scratch-arduino-extensions/scripts/patch-gui.js @@ -3,26 +3,32 @@ const fs = require("fs"); const extensions = [ { name: "ArduinoBasics", directory: "arduino_basics" }, - { name: "ArduinoModulino", directory: "arduino_modulino" } + { name: "ArduinoModulino", directory: "arduino_modulino" }, ]; - // base dir is the 'scratch-arduino-extensions' folder -const BaseDir = path.resolve(__dirname, "../"); +// base dir is the 'scratch-arduino-extensions' folder +const BaseDir = path.resolve(__dirname, "../"); extensions.forEach(extension => { console.log(`\n${extension.name} (${extension.directory})`); process.stdout.write("\t - add symbolic link: "); - const scratchVmExtensionsDir = path.resolve(BaseDir,"../scratch-editor/packages/scratch-vm/src/extensions",extension.directory); + const scratchVmExtensionsDir = path.resolve( + BaseDir, + "../scratch-editor/packages/scratch-vm/src/extensions", + extension.directory, + ); if (!fs.existsSync(scratchVmExtensionsDir)) { - const patchedExtensionDir = path.resolve(BaseDir,"./packages/scratch-vm/src/extensions/",extension.directory); + const patchedExtensionDir = path.resolve(BaseDir, "./packages/scratch-vm/src/extensions/", extension.directory); fs.symlinkSync(patchedExtensionDir, scratchVmExtensionsDir, "dir"); process.stdout.write("done"); - } else process.stdout.write("skip"); - + } else process.stdout.write("skip"); process.stdout.write("\n\t - register builtin: "); - const scratchVmExtensionsManagerFile = path.resolve(BaseDir, "../scratch-editor/packages/scratch-vm/src/extension-support/extension-manager.js"); + const scratchVmExtensionsManagerFile = path.resolve( + BaseDir, + "../scratch-editor/packages/scratch-vm/src/extension-support/extension-manager.js", + ); let managerCode = fs.readFileSync(scratchVmExtensionsManagerFile, "utf-8"); if (!managerCode.includes(extension.name)) { fs.copyFileSync(scratchVmExtensionsManagerFile, `${scratchVmExtensionsManagerFile}.orig`); @@ -35,7 +41,10 @@ extensions.forEach(extension => { } else process.stdout.write("skip"); process.stdout.write("\n\t - register core: "); - const scratchVmVirtualMachineFile = path.resolve(BaseDir, "../scratch-editor/packages/scratch-vm/src/virtual-machine.js"); + const scratchVmVirtualMachineFile = path.resolve( + BaseDir, + "../scratch-editor/packages/scratch-vm/src/virtual-machine.js", + ); let vmCode = fs.readFileSync(scratchVmVirtualMachineFile, "utf-8"); if (!vmCode.includes(extension.name)) { fs.copyFileSync(scratchVmVirtualMachineFile, `${scratchVmVirtualMachineFile}.orig`); @@ -47,8 +56,3 @@ extensions.forEach(extension => { process.stdout.write("done\n"); } else process.stdout.write("skip"); }); - - - - - diff --git a/sketch/Arduino_Modulino/README.md b/sketch/Arduino_Modulino/README.md index 45f68f1..2d7a088 100644 --- a/sketch/Arduino_Modulino/README.md +++ b/sketch/Arduino_Modulino/README.md @@ -1,13 +1,15 @@ # 🧩 Arduino Modulino® Library -The Arduino Modulino® Library simplifies the integration and management of Modulino® modules on Arduino boards. +The Arduino Modulino® Library simplifies the integration and management of Modulino® modules on Arduino boards. A Modulino® is a compact, modular electronic device that connects easily to Arduino via the Qwiic connector and communicates using the I2C (`Wire`) protocol. These modules include sensors, actuators, and more. 📖 For more information about this library please read the documentation [here](./docs/). ## Hardware Compatibility + This library is compatible with all Arduino boards that feature an I2C interface (`Wire`). ## Support and Contributions -If you find this library helpful, consider supporting us through [donations](https://www.arduino.cc/en/donate/), [sponsorship](https://github.com/sponsors/arduino) or check out our [store](https://store.arduino.cc/). \ No newline at end of file + +If you find this library helpful, consider supporting us through [donations](https://www.arduino.cc/en/donate/), [sponsorship](https://github.com/sponsors/arduino) or check out our [store](https://store.arduino.cc/). From d6bd82c10c4f308683ed608a59224d5125c0d3e6 Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 29 Oct 2025 00:40:50 +0100 Subject: [PATCH 2/6] fix: change set_led_rgb parameters from uint8_t to bool for LED control (#20) --- sketch/sketch.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sketch/sketch.ino b/sketch/sketch.ino index a191a9e..694d40e 100644 --- a/sketch/sketch.ino +++ b/sketch/sketch.ino @@ -62,7 +62,7 @@ void matrix_draw(String frame){ matrix.draw(shades); } -void set_led_rgb(String pin, uint8_t r, uint8_t g, uint8_t b) { +void set_led_rgb(String pin, bool r, bool g, bool b) { if (pin == "LED3") { digitalWrite(LED_BUILTIN, r ? LOW : HIGH ); digitalWrite(LED_BUILTIN + 1, g ? LOW : HIGH ); From 1e3187e2e05958de219bbf569a3b1e41ec1d0f17 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:43:57 +0100 Subject: [PATCH 3/6] feat: add format check task to Taskfile and release workflow --- .github/workflows/release.yaml | 4 ++++ Taskfile.yaml | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index aa08413..9be9890 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -31,6 +31,10 @@ jobs: - name: Install Task uses: arduino/setup-task@v2 + - name: Fmt check + run: | + task fmt-check + - name: Scratch init run: | task scratch:init diff --git a/Taskfile.yaml b/Taskfile.yaml index cd083c2..2166e43 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -9,6 +9,11 @@ tasks: cmds: - ${PWD}/.bin/dprint fmt + fmt-check: + desc: Check format + cmds: + - ${PWD}/.bin/dprint check + scratch:init: cmds: - rm -rf scratch-editor From 9bef0bd703ea7a88956de98b49b880f7fd9e37be Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:45:27 +0100 Subject: [PATCH 4/6] fix: update format check task name to use correct syntax in Taskfile and release workflow --- .github/workflows/release.yaml | 2 +- Taskfile.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9be9890..3122679 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -33,7 +33,7 @@ jobs: - name: Fmt check run: | - task fmt-check + task fmt:check - name: Scratch init run: | diff --git a/Taskfile.yaml b/Taskfile.yaml index 2166e43..9bf09d4 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -9,7 +9,7 @@ tasks: cmds: - ${PWD}/.bin/dprint fmt - fmt-check: + fmt:check: desc: Check format cmds: - ${PWD}/.bin/dprint check From 7d6e1cdb82fb3ecedb61dabce1ede73814188753 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:47:02 +0100 Subject: [PATCH 5/6] feat: add format checks workflow for automated code formatting --- .github/workflows/check.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/check.yaml diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml new file mode 100644 index 0000000..de05b6d --- /dev/null +++ b/.github/workflows/check.yaml @@ -0,0 +1,23 @@ +name: Format Checks + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Install Task + uses: arduino/setup-task@v2 + + - name: Fmt check + run: | + task fmt:check From eb333011e9b21a9dae4d31453b70de1a21ee57b4 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:49:21 +0100 Subject: [PATCH 6/6] feat: add dprint installation to workflows and Taskfile for code formatting --- .github/workflows/check.yaml | 4 ++++ .github/workflows/release.yaml | 4 ++++ Taskfile.yaml | 9 +++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index de05b6d..543bccd 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -18,6 +18,10 @@ jobs: - name: Install Task uses: arduino/setup-task@v2 + - name: Install dprint + run: | + task install + - name: Fmt check run: | task fmt:check diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3122679..7aad246 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -31,6 +31,10 @@ jobs: - name: Install Task uses: arduino/setup-task@v2 + - name: Install dprint + run: | + task install + - name: Fmt check run: | task fmt:check diff --git a/Taskfile.yaml b/Taskfile.yaml index 9bf09d4..f5db440 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -4,6 +4,11 @@ vars: DPRINT_VERSION: 0.48.0 tasks: + install: + cmds: + - curl -fsSL https://dprint.dev/install.sh | sh -s {{ .DPRINT_VERSION }} + - mkdir -p .bin && cp $HOME/.dprint/bin/dprint .bin/dprint # workaround for local install + fmt: desc: Run format cmds: @@ -21,10 +26,6 @@ tasks: - cd scratch-editor && npm install - cd scratch-editor && npm run build - task scratch:patch - install:dprint: - cmds: - - curl -fsSL https://dprint.dev/install.sh | sh -s {{ .DPRINT_VERSION }} - - mkdir -p .bin && cp $HOME/.dprint/bin/dprint .bin/dprint # workaround for local install scratch:patch: cmds: