diff --git a/build.js b/build.js index ee98caf..c09bf3e 100644 --- a/build.js +++ b/build.js @@ -52,6 +52,12 @@ async function main(dev) { entryPoints: [scriptInput], bundle: true, minify: !dev, + alias: { + zlib: "browserify-zlib", + buffer: "buffer", + stream: "stream-browserify", + process: "process" + }, platform: "browser", } @@ -61,7 +67,7 @@ async function main(dev) { sourcemap: !dev, define: { DEV: JSON.stringify(dev), - ENVIRONMENT: JSON.stringify("user-script") + ENVIRONMENT: JSON.stringify("user-script"), }, outfile: injectScriptOutput, }); @@ -81,9 +87,9 @@ async function main(dev) { const manifest = readJson(manifestTemplateLocation); manifest.version = package.version; fs.writeFileSync(manifestLocation, JSON.stringify(manifest)) - await esbuild.build({ ...common, + bundle: true, define: { DEV: JSON.stringify(dev), ENVIRONMENT: JSON.stringify("user-script") @@ -92,12 +98,14 @@ async function main(dev) { }); [scriptOutput, userScriptOutput].forEach(path => { - fs.writeFileSync(path, fs.readFileSync(path, "utf-8").replace("/* CROSS_WORLD_INJECT_CODE */", injectCode)); + fs.writeFileSync(path, fs.readFileSync(path, "utf-8") + .replace("/* CROSS_WORLD_INJECT_CODE */", injectCode)); }); const code = fs.readFileSync(userScriptOutput, "utf-8"); let template = fs.readFileSync(userScriptTemplateLocation, "utf-8"); const date = new Date(); - const version = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${(date.getDate() + 1).toString().padStart(2, "0")}`; + const version = `${date.getFullYear()}-${(date.getMonth() + 1).toString() + .padStart(2, "0")}-${(date.getDate() + 1).toString().padStart(2, "0")}`; template = template.replace("$VERSION$", version); template += code; fs.writeFileSync(userScriptOutput, template); diff --git a/package-lock.json b/package-lock.json index da8bdb9..01e342f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pixelcanvas-overlay", - "version": "1.0.4", + "version": "1.0.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "pixelcanvas-overlay", - "version": "1.0.4", + "version": "1.0.5", "license": "MIT", "dependencies": { "@fortawesome/fontawesome-free": "^6.5.1", @@ -15,14 +15,19 @@ "@types/chrome": "0.0.260", "@types/file-saver": "^2.0.7", "@types/lodash": "^4.14.202", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", "chokidar": "^3.6.0", "copy-dir": "^1.3.0", "esbuild": "^0.20.0", "file-saver": "^2.0.5", "lodash": "^4.17.21", + "process": "^0.11.10", "react": "^18.2.0", "react-dom": "^18.2.0", "rgbquant": "^1.1.2", + "stream": "^0.0.3", + "stream-browserify": "^3.0.0", "styled-components": "^6.1.8", "typescript": "^5.3.3" }, @@ -1113,6 +1118,26 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1142,6 +1167,39 @@ "node": ">=8" } }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "license": "MIT", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -1246,6 +1304,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/component-emitter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz", + "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2160,6 +2230,26 @@ "node": ">= 0.4" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2207,8 +2297,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.7", @@ -2926,6 +3015,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3037,6 +3132,15 @@ "node": ">= 0.8.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -3104,6 +3208,20 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3251,6 +3369,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -3383,6 +3521,34 @@ "node": ">=0.10.0" } }, + "node_modules/stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.3.tgz", + "integrity": "sha512-aMsbn7VKrl4A2T7QAQQbzgN7NVc70vgF5INQrBXqn4dCXN1zy3L9HGgLO5s7PExmdrzTJ8uR/27aviW8or8/+A==", + "license": "MIT", + "dependencies": { + "component-emitter": "^2.0.0" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "license": "MIT", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", @@ -3692,6 +3858,12 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4464,6 +4636,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4487,6 +4664,23 @@ "fill-range": "^7.0.1" } }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -4561,6 +4755,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "component-emitter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz", + "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5247,6 +5446,11 @@ "function-bind": "^1.1.2" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -5282,8 +5486,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { "version": "1.0.7", @@ -5791,6 +5994,11 @@ "p-limit": "^3.0.2" } }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5861,6 +6069,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5905,6 +6118,16 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -5998,6 +6221,11 @@ "isarray": "^2.0.5" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -6094,6 +6322,31 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, + "stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.3.tgz", + "integrity": "sha512-aMsbn7VKrl4A2T7QAQQbzgN7NVc70vgF5INQrBXqn4dCXN1zy3L9HGgLO5s7PExmdrzTJ8uR/27aviW8or8/+A==", + "requires": { + "component-emitter": "^2.0.0" + } + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string.prototype.matchall": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", @@ -6316,6 +6569,11 @@ "punycode": "^2.1.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 72a48db..48614cf 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,10 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], - "authors": ["0xa663", "Terncode"], + "authors": [ + "0xa663", + "Terncode" + ], "license": "MIT", "dependencies": { "@fortawesome/fontawesome-free": "^6.5.1", @@ -18,14 +21,19 @@ "@types/chrome": "0.0.260", "@types/file-saver": "^2.0.7", "@types/lodash": "^4.14.202", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", "chokidar": "^3.6.0", "copy-dir": "^1.3.0", "esbuild": "^0.20.0", "file-saver": "^2.0.5", "lodash": "^4.17.21", + "process": "^0.11.10", "react": "^18.2.0", "react-dom": "^18.2.0", "rgbquant": "^1.1.2", + "stream": "^0.0.3", + "stream-browserify": "^3.0.0", "styled-components": "^6.1.8", "typescript": "^5.3.3" }, diff --git a/src/UI/components/muralView.tsx b/src/UI/components/muralView.tsx index d5b9745..ece3cc7 100644 --- a/src/UI/components/muralView.tsx +++ b/src/UI/components/muralView.tsx @@ -1,10 +1,10 @@ import React from "react"; import { Store } from "../../lib/store"; -import { Mural, MuralEx, MuralStatus } from "../../interfaces"; +import { MuralEx, MuralOld, MuralStatus } from "../../interfaces"; import styled from "styled-components"; import { A, Border, Btn, Flex, SELECTED_COLOR } from "../styles"; import { CanvasToCanvasJSX } from "./canvasToCanvasJSX"; -import { formatNumber, getMuralHeight, getMuralWidth, getPixelStatusMural } from "../../lib/utils"; +import { convertOldMuralToNewMural, formatNumber, getMuralHeight, getMuralWidth, getPixelStatusMural } from "../../lib/utils"; import { IconDefinition, faDownload, faLayerGroup, faLocation, faPenToSquare, faRefresh, faTrash } from "@fortawesome/free-solid-svg-icons"; @@ -14,7 +14,7 @@ import { BIN_FORMATS } from "../importMural"; import saveAs from "file-saver"; import { Popup } from "./Popup"; import { Palette } from "../../lib/palette"; -import { serializeMural } from "../serializer"; +import { Mural } from "../../lib/mural"; const Margin = styled.div` margin: 2px; @@ -212,14 +212,15 @@ export class MuralView extends React.Component { // this.props.store.updateMural(this.props.mural); // } }; - onExport = () => { - const rawMural: Mural = { + onExport = async () => { + const rawMural: MuralOld = { name: this.props.mural.name, x: this.props.mural.x, y: this.props.mural.y, pixels: this.props.mural.pixels, }; - const buffer = serializeMural(rawMural); + const mural = convertOldMuralToNewMural(rawMural); + const buffer = await mural.getBuffer(); const blob = new Blob([buffer], { type: "octet/stream" }); const saveName = rawMural.name diff --git a/src/UI/importMural.tsx b/src/UI/importMural.tsx index ea728b9..9682524 100644 --- a/src/UI/importMural.tsx +++ b/src/UI/importMural.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { Mural, RGB } from "../interfaces"; +import { MuralOld, RGB } from "../interfaces"; import { canvasToImageData, get2DArrHeight, get2DArrWidth, getColorScore, getExtension, imageDataToPaletteIndices, imageToCanvas, loadImageSource, processNumberEvent, readAsArrayBuffer, @@ -14,7 +14,7 @@ import { Palette } from "../lib/palette"; import { FileInput } from "../lib/fileinput"; import { Store } from "../lib/store"; import { Coordinates } from "../lib/coordinates"; -import { deserializeMural } from "./serializer"; +import { Mural } from "../lib/mural"; export const TEXT_FORMATS = ["muraljson", "json"]; export const BIN_FORMATS = ["pcm", "bin"]; @@ -89,11 +89,11 @@ export async function importArtWork(store: Store, cords: Coordinates, palette: P const file = await importFile(); if (file) { if (file.type === "mural") { - return file.data as Mural; + return file.data as MuralOld; } else { const img = file.data as HTMLImageElement; const pixels = await imageToMural(img, palette); - const mural = await new Promise((resolve, reject)=> { + const mural = await new Promise((resolve, reject)=> { store.setOverlayModify({ pixels, muralObj: { @@ -483,23 +483,49 @@ async function importFile() { const name = ex.text; if (TEXT_FORMATS.includes(etn)) { const content = await readAsString(fileData); - const mural = JSON.parse(content) as Mural; + const mural = JSON.parse(content) as MuralOld; if (!mural.name) { mural.name = await Popup .prompt("Missing name for this mural. Please enter it manually", name) || ""; } - validateMural(mural); + return { type: "mural", data: mural, }; } else if (BIN_FORMATS.includes(etn)) { const buffer = await readAsArrayBuffer(fileData); - const mural = deserializeMural(buffer); - validateMural(mural); + const mural = await Mural.from(new Uint8Array(buffer)); + const pixelBuffer = mural.pixelBuffer; + const pixels = Array.from({ length: mural.h }, () => Array(mural.w).fill(0)); + let i = 0; + let yy = -1; + leg: + for (;;) { + yy++; + if (pixelBuffer[i] === undefined) { + break; + } + // const ref = []; + // pixels.push(ref); + for (let xx = 0; xx < mural.w; xx++) { + const item = pixelBuffer[i++]; + if (item != undefined) { + pixels[yy][xx] = item; + if(item > 15) { + console.log(item); + } + //ref.push(item); + } else { + break leg; + } + } + } return { type: "mural", - data: mural, + data: { + name, x: mural.x, y: mural.y, pixels, + }, }; } else { const readData = await readAsDataUrl(fileData); diff --git a/src/UI/serializer.tsx b/src/UI/serializer.tsx deleted file mode 100644 index 49b3bcf..0000000 --- a/src/UI/serializer.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { Mural } from "../interfaces"; - -const MAGIC_REPEATING = 200; -const TRANSPARENT = 201; - -const VERSION = 1; - -export function compressRepeatingArray(index: number, buffer: number[] /* 0xFF */) { - const a = buffer[index]; - const b = buffer[index + 1]; - const c = buffer[index + 2]; - const pixelIndex = a === -1 ? TRANSPARENT : a; - if (a === b && b === c) { - let i = 0; - for (; i < Math.min(buffer.length - index, 0xFF); i++) { - if (a !== buffer[index + i]) { - break; - } - } - return [MAGIC_REPEATING, i - 1, pixelIndex]; - } - return [pixelIndex]; -} - -export function decompressRepeatingArray(buffer: ArrayLike) { - const output: number[] = []; - const addValue = (value: number) => { - output.push(value === TRANSPARENT ? -1 : value); - }; - - for (let i = 0; i < buffer.length; i++) { - const item = buffer[i]; - if (item === MAGIC_REPEATING) { - const length = buffer[++i]; - const value = buffer[++i]; - for (let j = 0; j < length; j++) { - addValue(value); - } - } else { - addValue(item); - } - } - return output; -} - -export function serializeMural(mural: Mural) { - const encoder = new TextEncoder(); - const nameBinary = encoder.encode(mural.name); - const array: number[] = []; - for (let i = 0; i < mural.pixels.length; i++) { - for (let j = 0; j < mural.pixels[i].length; j++) { - array.push(mural.pixels[i][j]); - } - } - const pixelEncodeBuffer: number[] = []; - for (let i = 0; i < array.length; i++) { - const rtn = compressRepeatingArray(i, array); - if (rtn.length === 1) { - pixelEncodeBuffer.push(rtn[0]); - } else { - pixelEncodeBuffer.push(rtn[0], rtn[1], rtn[2]); - i += rtn[1] - 1; - } - } - - const pixelBuffer = new Uint8Array(pixelEncodeBuffer); - const firstHalf = 1 + 4 + 4 + 1 + 2 + nameBinary.byteLength; - const buffer = new ArrayBuffer(firstHalf + pixelBuffer.byteLength); - const view = new DataView(buffer); - view.setUint8(0, VERSION); - view.setInt32(1, mural.x, true); - view.setInt32(5, mural.y, true); - view.setUint16(9, mural.pixels[0].length, true); - view.setUint8(11, nameBinary.length); - new Uint8Array(buffer).set(nameBinary, 12); - new Uint8Array(buffer).set(pixelBuffer, firstHalf); - - return buffer; -} - -export function deserializeMural(buffer: ArrayBuffer): Mural { - const view = new DataView(buffer); - const version = view.getUint8(0); - if (version !== VERSION) { - throw new Error("Unknown version"); - } - const x = view.getInt32(1, true); - const y = view.getInt32(5, true); - const width = view.getUint16(9, true); - const nameLength = view.getUint8(11); - - const nameBytes = new Uint8Array(buffer, 12, nameLength); - const decoder = new TextDecoder(); - const name = decoder.decode(nameBytes); - const pixelBuffer = new Uint8Array(buffer, 12 + nameLength); - const pixelArray: number[] = decompressRepeatingArray(pixelBuffer); - - const pixels: number[][] = []; - - leg: - for (;;) { - if (!pixelArray.length) { - break; - } - const ref: number[] = []; - pixels.push(ref); - for (let j = 0; j < width; j++) { - const item = pixelArray.shift(); - if (item != undefined) { - ref.push(item); - } else { - break leg; - } - } - } - - return { - name, - x, - y, - pixels - } as Mural; -} diff --git a/src/index.ts b/src/index.ts index 16eb5c7..d9e26cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,8 +6,11 @@ import { waitForDraw } from "./lib/utils"; import { Storage } from "./lib/storage"; import { Store } from "./lib/store"; import { PixelPlaced } from "./lib/pixelPlaced"; +import process from "process"; async function main() { + globalThis.process = process; + const palette = new Palette(); while(!palette.init()) { await waitForDraw();} const storage = new Storage(ENVIRONMENT === "browser-extension"); diff --git a/src/interfaces.ts b/src/interfaces.ts index fc3d2f2..ffbcc06 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -4,7 +4,7 @@ export interface RGB { b: number; } -export interface Mural { +export interface MuralOld { name: string; pixels: number[][]; x: number; @@ -28,7 +28,7 @@ export interface SelectedMural { h: number; } -export interface MuralEx extends Mural { +export interface MuralEx extends MuralOld { ref: HTMLCanvasElement; pixelCount: number; } diff --git a/src/lib/coordinates.ts b/src/lib/coordinates.ts index 1e4be52..7cc9379 100644 --- a/src/lib/coordinates.ts +++ b/src/lib/coordinates.ts @@ -56,7 +56,10 @@ export class Coordinates { private get centerCanvas() { const hww = window.innerWidth / 2; const hhw = window.innerHeight / 2; - const canvasObject = [...document.getElementsByTagName("canvas")].filter(c => c.classList.contains("leaflet-tile")).map(c => { + const canvasObject = [ + ...document.getElementsByTagName("canvas")] + .filter(c => c.classList.contains("leaflet-tile")) + .map(c => { const bounds = c.getBoundingClientRect(); return { canvas: c, @@ -70,6 +73,7 @@ export class Coordinates { }, }; }).find(r => hww > r.bounds.left && hww < r.bounds.right && hhw > r.bounds.top && hhw < r.bounds.bottom); + if (canvasObject) { const ratio = canvasObject.canvas.width / CHUNK_SIZE; if (ratio === 2) { // scale -1 @@ -137,12 +141,16 @@ export class Coordinates { const pathNames = location.pathname.split("/").filter(e => e); const cordsRaw = pathNames[0]; if (cordsRaw) { - const cords = cordsRaw.match(/-?\d+/g)!.map(n => parseInt(n)); - if (typeof cords[0] === "number" && typeof cords[1] === "number" && typeof cords[2] === "number") { - this._ux = cords[0]; - this._uy = cords[1]; - this._uScale = cords[2]; - return cords; + const cordsMatch = cordsRaw.match(/-?\d+/g); + if (cordsMatch) { + const cords = cordsMatch.map(n => parseInt(n)); + if (typeof cords[0] === "number" && typeof cords[1] === "number" && typeof cords[2] === "number") { + this._ux = cords[0]; + this._uy = cords[1]; + this._uScale = cords[2]; + return cords; + } + console.log(cordsMatch); } } return null; diff --git a/src/lib/mural.ts b/src/lib/mural.ts new file mode 100644 index 0000000..ebedb4d --- /dev/null +++ b/src/lib/mural.ts @@ -0,0 +1,178 @@ +import zlib from "zlib"; +import { Buffer } from "buffer"; + +export class Mural { + private static readonly ENCODE_VERSION = 1; + constructor( + private _name: string, + private _x: number, + private _y: number, + private _w: number, + private _h: number, + private _b: Int8Array + ) { + this.validate(); + } + + getBuffer() { + this.validate(); + const encoder = new TextEncoder(); + const nameBinary = encoder.encode(this._name); + const pixelBuffer = this._b; + const firstHalf = 1 + 4 + 4 + 1 + 2 + 2 + 1 + nameBinary.byteLength; + const buffer = new ArrayBuffer(firstHalf + pixelBuffer.byteLength); + const view = new DataView(buffer); + view.setUint8(0, Mural.ENCODE_VERSION); + view.setInt32(1, this._x); + view.setInt32(5, this._y); + view.setUint16(9, this._h); + view.setUint16(11, this._w); + view.setUint8(13, nameBinary.length); + new Uint8Array(buffer).set(nameBinary, 15); + new Uint8Array(buffer) + .set(new Uint8Array(this._b.buffer, this._b.byteOffset, this._b.byteLength), firstHalf); + return new Promise((resolve, reject) => { + zlib.deflate(Buffer.from(buffer), (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + } + static async from(raw: Uint8Array) { + const buffer = await new Promise((resolve, reject) => { + zlib.inflate(raw, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + const view = new DataView(buffer.buffer); + const version = view.getUint8(0); + if (version !== Mural.ENCODE_VERSION) { + throw new Error("Unknown version"); + } + const x = view.getInt32(1); + const y = view.getInt32(5); + const height = view.getUint16(9); + const width = view.getUint16(11); + const nameLength = view.getUint8(13); + const nameBytes = buffer.subarray(15, 15 + nameLength); + const decoder = new TextDecoder(); + const name = decoder.decode(nameBytes); + const pixelBuffer = new Int8Array( + buffer.buffer, + buffer.byteOffset + 15 + nameLength, + buffer.byteLength - (15 + nameLength) + ); + + return new Mural(name, x, y, width, height, pixelBuffer); + } + private validate2() { + try { + this.validate(); + return true; + } catch (_) { + return false; + } + } + + private validate() { + if (this._w * this._h > 0x7FFFFFFF) { + throw new Error("Size too big"); + } + if (this._w > 0xFFFF) { + throw new Error("Width to big"); + } + if (this._h > 0xFFFF) { + throw new Error("Height to big"); + } + if (Math.abs(this._x) > 0x7FFFFFFF) { + throw new Error("X to big"); + } + if (Math.abs(this._y) > 0x7FFFFFFF) { + throw new Error("X to big"); + } + } + getPixel(x: number, y: number) { + return this._b[this.getIndex(x, y)]; + } + setPixel(x: number, y: number, value: number) { + this._b[this.getIndex(x, y)] = value; + } + private getIndex(x: number, y: number) { + return (y * this._w) + x; + } + private fixBuffer() { + const size = this._w * this._h; + if (this._b.length !== size){ + const copy = this._b; + this._b = new Int8Array(size); + this._b.set(copy.subarray(0, size)); + } + } + + get name() { + return this._name; + } + set name(value: string) { + const copy = this._name; + this._name = value; + if (!this.validate2()) { + this._name = copy; + } + } + get x() { + return this._x; + } + set x(value: number) { + const copy = this._x; + this._x = value; + if (!this.validate2()) { + this._x = copy; + } + } + get y() { + return this._y; + } + set y(value: number) { + const copy = this._y; + this._y = value; + if (!this.validate2()) { + this._y = copy; + } + } + get w() { + return this._w; + } + set w(value: number) { + const copy = this._w; + this._w = value; + if (!this.validate2()) { + this.fixBuffer(); + } else { + this._w = copy; + } + } + get h() { + return this._h; + } + set h(value: number) { + const copy = this._h; + this._h = value; + if (!this.validate2()) { + this.fixBuffer(); + } else { + this._h = copy; + } + + } + + get pixelBuffer() { + return this._b; + } +} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts index eb3b643..05df32a 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,7 @@ import { clone, isInteger } from "lodash"; -import { Mural, MuralStatus, RGB } from "../interfaces"; +import { MuralOld, MuralStatus, RGB } from "../interfaces"; import { fetchCombineTiledImage } from "./canvashot"; +import { Mural } from "./mural"; export const CHUNK_SIZE = 512; @@ -129,11 +130,11 @@ export function get2DArrWidth(arr2D: number[][]) { return (arr2D[0] && arr2D[0].length) || 0; } -export function getMuralHeight(mural: Mural) { +export function getMuralHeight(mural: MuralOld) { return get2DArrHeight(mural.pixels); } -export function getMuralWidth(mural: Mural) { +export function getMuralWidth(mural: MuralOld) { return get2DArrWidth(mural.pixels); } @@ -161,7 +162,7 @@ export function canvasToImage(canvas: HTMLCanvasElement, alt?: string) { }); } -export function validateMural(mural: Mural) { +export function validateMural(mural: MuralOld) { if (typeof mural === "object") { const muralClone = clone(mural); if (Array.isArray(muralClone)) { @@ -239,7 +240,7 @@ export function flatQuantizeImageData(imageData: ImageData, palette: RGB[]) { } } -export async function getPixelStatusMural(mural: Mural, palette: RGB[]): Promise { +export async function getPixelStatusMural(mural: MuralOld, palette: RGB[]): Promise { const width = getMuralWidth(mural); const height = getMuralHeight(mural); const tile = await fetchCombineTiledImage(mural.x, mural.y, width, height); @@ -424,3 +425,22 @@ export async function fetchTile(x: number, y: number) { }); }); } + +export function isOldMural(mural: MuralOld | Mural): mural is MuralOld { + return "pixels" in mural; +} + +export function convertOldMuralToNewMural(mural: MuralOld) { + const height = mural.pixels.length; + const width = mural.pixels[0].length; + const predictedSize = mural.pixels.length * mural.pixels[0].length; + const array = new Int8Array(predictedSize); + let k = 0; + for (let i = 0; i < mural.pixels.length; i++) { + for (let j = 0; j < mural.pixels[i].length; j++) { + array[k++] = mural.pixels[i][j]; + } + } + return new Mural(mural.name, mural.x, mural.y, width, height, array); +} +