From 80ead7eabf1297d4a18f9aeee50c80e6a3553bde Mon Sep 17 00:00:00 2001 From: neauoire Date: Mon, 10 Feb 2020 09:42:55 -0500 Subject: [PATCH] * --- README.md | 8 +- desktop/icon.svg | 6 +- desktop/package-lock.json | 182 +++++++++--------- desktop/package.json | 9 +- desktop/sources/scripts/client.js | 4 +- desktop/sources/scripts/lib/acels.js | 13 +- desktop/sources/scripts/lib/source.js | 9 +- desktop/sources/scripts/library.js | 10 +- resources/MANUAL.txt | 22 +++ resources/PRELUDE.md | 46 +++++ resources/PREVIEW.jpg | Bin 0 -> 856120 bytes resources/PREVIEW2.jpg | Bin 0 -> 905484 bytes resources/PREVIEW3.jpg | Bin 0 -> 1162838 bytes resources/WORKSHOP.md | 261 ++++++++++++++++++++++++++ 14 files changed, 451 insertions(+), 119 deletions(-) create mode 100644 resources/MANUAL.txt create mode 100644 resources/PRELUDE.md create mode 100644 resources/PREVIEW.jpg create mode 100644 resources/PREVIEW2.jpg create mode 100644 resources/PREVIEW3.jpg create mode 100644 resources/WORKSHOP.md diff --git a/README.md b/README.md index 3a081da..6613832 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ronin is a procedural graphics tool designed to automate simple graphical The library updates is constantly revealing new applications to Ronin, you can see the list of available functions here. Most of our iconography and designs were created with both Ronin and Dotgrid. -Learn more by reading the manual, or have a look at some experiments on twitter. If you need help, visit the Community, follow the [workshop](https://github.com/hundredrabbits/Ronin/blob/master/WORKSHOP.md) or watch the [video tutorial](https://www.youtube.com/watch?v=SgAWGh1s9zg). +Learn more by reading the manual, or have a look at some experiments on twitter. If you need help, visit the Community, follow the [workshop](https://github.com/hundredrabbits/Ronin/blob/master/resources/WORKSHOP.md) or watch the [video tutorial](https://www.youtube.com/watch?v=SgAWGh1s9zg). ```lisp ; clear screen @@ -29,7 +29,7 @@ npm install npm start ``` - + ## Helpers @@ -152,9 +152,9 @@ To save an image in memory, open an image file with Ronin, or drag an image file - `(test name a b)` - `(benchmark fn)` Logs time taken to execute a function. - + - + ## Extras diff --git a/desktop/icon.svg b/desktop/icon.svg index 6c60788..ae2f668 100644 --- a/desktop/icon.svg +++ b/desktop/icon.svg @@ -1,4 +1,6 @@ - + - + + + \ No newline at end of file diff --git a/desktop/package-lock.json b/desktop/package-lock.json index ce75acb..5c622fd 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@electron/get": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.6.0.tgz", - "integrity": "sha512-xuvAzbN9iBApfAMvW0hKUpxHR5wPVbG9RaoSTbpu/WaHISDu0MVfMWYhfeU0X730CpBV0G2RkLgwAs9WDan3GA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.7.2.tgz", + "integrity": "sha512-LSE4LZGMjGS9TloDx0yO44D2UTbaeKRk+QjlhWLiQlikV6J4spgDCjb6z4YIcqmPAwNzlNCnWF4dubytwI+ATA==", "dev": true, "requires": { "debug": "^4.1.1", @@ -17,7 +17,7 @@ "global-tunnel-ng": "^2.7.1", "got": "^9.6.0", "sanitize-filename": "^1.6.2", - "sumchecker": "^3.0.0" + "sumchecker": "^3.0.1" } }, "@sindresorhus/is": { @@ -36,15 +36,15 @@ } }, "@types/node": { - "version": "12.12.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", - "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "version": "12.12.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.26.tgz", + "integrity": "sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA==", "dev": true }, "asar": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/asar/-/asar-2.0.1.tgz", - "integrity": "sha512-Vo9yTuUtyFahkVMFaI6uMuX6N7k5DWa6a/8+7ov0/f8Lq9TVR0tUjzSzxQSxT1Y+RJIZgnP7BVb6Uhi+9cjxqA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/asar/-/asar-2.0.3.tgz", + "integrity": "sha512-QdHKO+HOYVtE4B/M3up3i4LSJeJgsa2CTVBrjBf9GgLUPGGUFZowcdJ5yE4gOJuRAHNdqB9JFeRfFfaOu5x8Rw==", "dev": true, "requires": { "chromium-pickle-js": "^0.2.0", @@ -75,15 +75,15 @@ "dev": true }, "bluebird": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz", - "integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "boolean": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-2.0.3.tgz", - "integrity": "sha512-iHzXeFCXWrpjYE7DToXGCBPGZf0eVISqzL+4sgrOSYEKXnb59WHPFvGTTyCj6zJ/MuuLAxEn8zPkrTHHzlt3IA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.0.tgz", + "integrity": "sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ==", "dev": true, "optional": true }, @@ -220,9 +220,9 @@ } }, "core-js": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.6.tgz", - "integrity": "sha512-u4oM8SHwmDuh5mWZdDg9UwNVq5s1uqq6ZDLLIs07VY+VJU91i3h4f3K/pgFvtUQPGdeStrZ+odKyfyt4EnKHfA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", "dev": true, "optional": true }, @@ -233,18 +233,18 @@ "dev": true }, "cross-zip": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-2.1.6.tgz", - "integrity": "sha512-xLIETNkzRcU6jGRzenJyRFxahbtP4628xEKMTI/Ql0Vu8m4h8M7uRLVi7E5OYHuJ6VQPsG4icJumKAFUvfm0+A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-3.0.0.tgz", + "integrity": "sha512-cm+l8PJ6WiSQmKZ/x8DGvUm2u/3FX2JFs1AFd18gdHaVhP5Lf4oE6Jrj2Jd05JYSioz5x+nIRVp0zBQuzuCRcQ==", "dev": true, "requires": { "rimraf": "^3.0.0" }, "dependencies": { "rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -283,9 +283,9 @@ } }, "defer-to-connect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.0.tgz", - "integrity": "sha512-WE2sZoctWm/v4smfCAdjYbrfS55JiMRdlY9ZubFhsYbteCK9+BvAx4YV7nPjYM6ZnX5BcoVKwfmyx9sIFTgQMQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", "dev": true }, "define-properties": { @@ -312,9 +312,9 @@ "dev": true }, "electron": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-7.0.1.tgz", - "integrity": "sha512-eMFoZIO0+eOAE9FyNC/f0Vp8l/sJziTMK+axEt2XIpGCagom1IZgUKPGwmHUcftZCX5lNKh+Tv53T0GcNnNTKQ==", + "version": "7.1.11", + "resolved": "https://registry.npmjs.org/electron/-/electron-7.1.11.tgz", + "integrity": "sha512-YDXfnovKY+8iZ5ISQh1kRqYIRKbpOSxGXCx2WVxPFPutEQ7Q/Xzr3h4GePEY25/NXMytMfhKaAZAYjtWUm3r9Q==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -323,19 +323,19 @@ } }, "electron-notarize": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.1.1.tgz", - "integrity": "sha512-TpKfJcz4LXl5jiGvZTs5fbEx+wUFXV5u8voeG5WCHWfY/cdgdD8lDZIZRqLVOtR3VO+drgJ9aiSHIO9TYn/fKg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz", + "integrity": "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==", "dev": true, "requires": { "debug": "^4.1.1", - "fs-extra": "^8.0.1" + "fs-extra": "^8.1.0" } }, "electron-osx-sign": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.14.tgz", - "integrity": "sha512-72vtrz9I3dOeFDaNvO5thwIjrimDiXMmYEbN0hEBqnvcSSMOWugjim2wiY9ox3dhuBFUhxp3owmuZCoH3Ij08A==", + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.15.tgz", + "integrity": "sha512-1QtPNpjIji9bGZ0VRFwtJUyU1uHi7q3XUAOG0qFsvAUfs5H0T8hbgUfyg3xvPzmF1ruV8T8pQmQ86vNfLrcRiA==", "dev": true, "requires": { "bluebird": "^3.5.0", @@ -370,16 +370,16 @@ } }, "electron-packager": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-14.1.0.tgz", - "integrity": "sha512-4oGtQYYjSA/M4BGOwG0NBqEtThBf7aCV76C2AZsD71eGocYqZNvtvfzeeMnKkc3EW1nPq7iJ4Wge+GXma0kwIA==", + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-14.2.1.tgz", + "integrity": "sha512-g6y3BVrAOz/iavKD+VMFbehrQcwCWuA3CZvVbmmbQuCfegGA1ytwWn0BNIDDrEdbuz31Fti7mnNHhb5L+3Wq9A==", "dev": true, "requires": { "@electron/get": "^1.6.0", "asar": "^2.0.1", - "cross-zip": "^2.1.5", + "cross-zip": "^3.0.0", "debug": "^4.0.1", - "electron-notarize": "^0.1.1", + "electron-notarize": "^0.2.0", "electron-osx-sign": "^0.4.11", "fs-extra": "^8.1.0", "galactus": "^0.2.1", @@ -392,6 +392,14 @@ "sanitize-filename": "^1.6.0", "semver": "^6.0.0", "yargs-parser": "^16.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "encodeurl": { @@ -526,13 +534,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true, - "optional": true - }, "galactus": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz", @@ -605,9 +606,9 @@ } }, "glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -619,18 +620,18 @@ } }, "global-agent": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.5.tgz", - "integrity": "sha512-pYJjCxxNBzYxo6iNO62JZn8iCFVbvpiM0zE4w/G5hBNIvLjnvzIeCVQPMKc3aK8ju5L7Q8NNI/oBSosU0eeSYw==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz", + "integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==", "dev": true, "optional": true, "requires": { - "boolean": "^2.0.2", - "core-js": "^3.3.3", + "boolean": "^3.0.0", + "core-js": "^3.6.4", "es6-error": "^4.1.1", - "matcher": "^2.0.0", - "roarr": "^2.14.2", - "semver": "^6.3.0", + "matcher": "^2.1.0", + "roarr": "^2.15.2", + "semver": "^7.1.2", "serialize-error": "^5.0.0" } }, @@ -648,15 +649,13 @@ } }, "globalthis": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.0.tgz", - "integrity": "sha512-vcCAZTJ3r5Qcu5l8/2oyVdoFwxKgfYnMTR2vwWeux/NAVZK3PwcMaWkdUIn4GJbmKuRK7xcvDsLuK+CKcXyodg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", + "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", "dev": true, "optional": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "object-keys": "^1.0.12" + "define-properties": "^1.1.3" } }, "got": { @@ -827,9 +826,9 @@ "dev": true }, "matcher": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.0.0.tgz", - "integrity": "sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz", + "integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==", "dev": true, "optional": true, "requires": { @@ -1089,9 +1088,9 @@ } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -1104,9 +1103,9 @@ } }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -1131,15 +1130,15 @@ } }, "roarr": { - "version": "2.14.3", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.14.3.tgz", - "integrity": "sha512-D4BpKVruUDCJ9DJWcC7T+fx4o10IUYJ7MdmjM4Skx1aqc42CE7LGzPDUAfczibhavNGcnY1IHqJdq16NmiG4rQ==", + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.2.tgz", + "integrity": "sha512-jmaDhK9CO4YbQAV8zzCnq9vjAqeO489MS5ehZ+rXmFiPFFE6B+S9KYO6prjmLJ5A0zY3QxVlQdrIya7E/azz/Q==", "dev": true, "optional": true, "requires": { - "boolean": "^2.0.2", + "boolean": "^3.0.0", "detect-node": "^2.0.4", - "globalthis": "^1.0.0", + "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" @@ -1161,10 +1160,11 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz", + "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==", + "dev": true, + "optional": true }, "semver-compare": { "version": "1.0.0", @@ -1238,9 +1238,9 @@ "dev": true }, "sumchecker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.0.tgz", - "integrity": "sha512-yreseuC/z4iaodVoq07XULEOO9p4jnQazO7mbrnDSvWAU/y2cbyIKs+gWJptfcGu9R+1l27K8Rkj0bfvqnBpgQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", "dev": true, "requires": { "debug": "^4.1.0" @@ -1350,9 +1350,9 @@ "dev": true }, "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", "dev": true }, "yargs-parser": { diff --git a/desktop/package.json b/desktop/package.json index 9d8f23a..d223733 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -3,13 +3,14 @@ "version": "0.1.0", "main": "main.js", "scripts": { - "start": "electron .", + "start": "electron . --disable-gpu", "fix": "standard --fix", "clean": "rm -r ~/Documents/Ronin-darwin-x64/ ; rm -r ~/Documents/Ronin-linux-x64/ ; rm -r ~/Documents/Ronin-win32-x64/ ; echo 'cleaned build location'", "build_osx": "electron-packager . Ronin --platform=darwin --arch=x64 --out ~/Documents/ --overwrite --icon=icon.icns ; echo 'Built for OSX'", "build_linux": "electron-packager . Ronin --platform=linux --arch=x64 --out ~/Documents/ --overwrite --icon=icon.ico ; echo 'Built for LINUX'", "build_win": "electron-packager . Ronin --platform=win32 --arch=x64 --out ~/Documents/ --overwrite --icon=icon.ico ; echo 'Built for WIN'", - "build": "npm run clean ; npm run build_osx ; npm run build_linux ; npm run build_win", + "build": "npm run clean ; npm run build_osx ; npm run build_linux ; npm run build_win ; npm run add_manual", + "add_manual": "cp ../resources/MANUAL.txt ~/Documents/Ronin-darwin-x64/MANUAL.txt ; cp ../resources/MANUAL.txt ~/Documents/Ronin-linux-x64/MANUAL.txt ; cp ../resources/MANUAL.txt ~/Documents/Ronin-win32-x64/MANUAL.txt", "push_osx": "~/Applications/butler push ~/Documents/Ronin-darwin-x64/ hundredrabbits/ronin:osx-64", "push_linux": "~/Applications/butler push ~/Documents/Ronin-linux-x64/ hundredrabbits/ronin:linux-64", "push_win": "~/Applications/butler push ~/Documents/Ronin-win32-x64/ hundredrabbits/ronin:windows-64", @@ -17,8 +18,8 @@ "push": "npm run build ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run status" }, "devDependencies": { - "electron": "^7.1.5", - "electron-packager": "^14.1.1" + "electron": "^7.1.11", + "electron-packager": "^14.2.1" }, "standard": { "globals": [ diff --git a/desktop/sources/scripts/client.js b/desktop/sources/scripts/client.js index 3da2acd..0975bf2 100644 --- a/desktop/sources/scripts/client.js +++ b/desktop/sources/scripts/client.js @@ -39,8 +39,8 @@ function Client () { window.addEventListener('drop', this.onDrop) this.acels.set('File', 'New', 'CmdOrCtrl+N', () => { this.source.new(); this.surface.clear(); this.commander.clear() }) - this.acels.set('File', 'Save', 'CmdOrCtrl+S', () => { this.source.download('ronin', 'lisp', this.commander._input.value, 'text/plain') }) - this.acels.set('File', 'Export Image', 'CmdOrCtrl+E', () => { this.source.download('ronin', 'png', this.surface.el.toDataURL('image/png', 1.0), 'image/png') }) + this.acels.set('File', 'Save', 'CmdOrCtrl+S', () => { this.source.write('ronin', 'lisp', this.commander._input.value, 'text/plain') }) + this.acels.set('File', 'Export Image', 'CmdOrCtrl+E', () => { this.source.write('ronin', 'png', this.surface.el.toDataURL('image/png', 1.0), 'image/png') }) this.acels.set('File', 'Open', 'CmdOrCtrl+O', () => { this.source.open('lisp', this.whenOpen) }) this.acels.add('Edit', 'undo') diff --git a/desktop/sources/scripts/lib/acels.js b/desktop/sources/scripts/lib/acels.js index 40320bc..62f630c 100644 --- a/desktop/sources/scripts/lib/acels.js +++ b/desktop/sources/scripts/lib/acels.js @@ -37,10 +37,10 @@ function Acels (client) { if ((event.ctrlKey || event.metaKey) && event.shiftKey) { return `CmdOrCtrl+Shift+${accelerator}` } - if (event.shiftKey) { + if (event.shiftKey && event.key.toUpperCase() !== event.key) { return `Shift+${accelerator}` } - if (event.altKey) { + if (event.altKey && event.key.length !== 1) { return `Alt+${accelerator}` } if (event.ctrlKey || event.metaKey) { @@ -73,7 +73,7 @@ function Acels (client) { for (const cat in cats) { text += `\n### ${cat}\n\n` for (const item of cats[cat]) { - text += item.accelerator ? `- \`${item.accelerator}\`: ${item.info}\n` : '' + text += item.accelerator ? `- \`${item.accelerator.replace('`', 'tilde')}\`: ${item.name}\n` : '' } } return text.trim() @@ -83,8 +83,9 @@ function Acels (client) { const cats = this.sort() let text = '' for (const cat in cats) { + text += `\n${cat}\n\n` for (const item of cats[cat]) { - text += item.accelerator ? `${cat}: ${item.name} | ${item.accelerator}\n` : '' + text += item.accelerator ? `${item.name.padEnd(25, '.')} ${item.accelerator}\n` : '' } } return text.trim() @@ -105,13 +106,13 @@ function Acels (client) { submenu: [ { label: 'Download Themes', click: () => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes') } }, { label: 'Open Theme', click: () => { client.theme.open() } }, - { label: 'Reset Theme', click: () => { client.theme.reset() } } + { label: 'Reset Theme', accelerator: 'CmdOrCtrl+Escape', click: () => { client.theme.reset() } } ] }, { label: 'Fullscreen', accelerator: 'CmdOrCtrl+Enter', click: () => { app.toggleFullscreen() } }, { label: 'Hide', accelerator: 'CmdOrCtrl+H', click: () => { app.toggleVisible() } }, { label: 'Toggle Menubar', accelerator: 'Alt+H', click: () => { app.toggleMenubar() } }, - { label: 'Inspect', accelerator: 'CmdOrCtrl+.', click: () => { app.inspect() } }, + { label: 'Inspect', accelerator: 'CmdOrCtrl+Tab', click: () => { app.inspect() } }, { role: 'quit' } ] }) diff --git a/desktop/sources/scripts/lib/source.js b/desktop/sources/scripts/lib/source.js index f651b2e..ba2554c 100644 --- a/desktop/sources/scripts/lib/source.js +++ b/desktop/sources/scripts/lib/source.js @@ -18,14 +18,14 @@ function Source (client) { this.cache = {} } - this.open = (ext, callback) => { + this.open = (ext, callback, store = false) => { console.log('Source', 'Open file..') const input = document.createElement('input') input.type = 'file' input.onchange = (e) => { const file = e.target.files[0] if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); return } - this.read(file, callback) + this.read(file, callback, store) } input.click() } @@ -37,7 +37,7 @@ function Source (client) { input.setAttribute('multiple', 'multiple') input.onchange = (e) => { for (const file of e.target.files) { - if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); return } + if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); continue } this.read(file, this.store) } } @@ -60,11 +60,12 @@ function Source (client) { // I/O - this.read = (file, callback) => { + this.read = (file, callback, store = false) => { const reader = new FileReader() reader.onload = (event) => { const res = event.target.result if (callback) { callback(file, res) } + if (store) { this.store(file, res) } } reader.readAsText(file, 'UTF-8') } diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 187ca84..d7f412b 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -1,5 +1,6 @@ 'use strict' +/* global Image */ /* global Image */ function Library (client) { @@ -11,12 +12,9 @@ function Library (client) { return shape || this.rect(0, 0, img.width, img.height) } - this.export = async (name = 'export', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format. - const base64 = client.surface.el.toDataURL(type, quality) - const link = document.createElement('a') - link.setAttribute('href', base64) - link.setAttribute('download', type === 'image/png' ? name + '.png' : name + '.jpg') - link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })) + this.export = async (name = 'ronin', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format. + const ext = type === 'image/png' ? name + '.png' : name + '.jpg' + client.source.write(name, ext, client.surface.el.toDataURL(type, 1.0), type) } // Shapes diff --git a/resources/MANUAL.txt b/resources/MANUAL.txt new file mode 100644 index 0000000..f763f1a --- /dev/null +++ b/resources/MANUAL.txt @@ -0,0 +1,22 @@ +File + +New...................... CmdOrCtrl+N +Save..................... CmdOrCtrl+S +Export Image............. CmdOrCtrl+E +Open..................... CmdOrCtrl+O + +Edit + + +View + +Toggle Guides............ CmdOrCtrl+Shift+H +Toggle Commander......... CmdOrCtrl+K +Expand Commander......... CmdOrCtrl+Shift+K + +Project + +Run...................... CmdOrCtrl+R +Reload Run............... CmdOrCtrl+Shift+R +Re-Indent................ CmdOrCtrl+Shift+I +Clean.................... Escape \ No newline at end of file diff --git a/resources/PRELUDE.md b/resources/PRELUDE.md new file mode 100644 index 0000000..55fc238 --- /dev/null +++ b/resources/PRELUDE.md @@ -0,0 +1,46 @@ +# Prelude + +## Colors + +### Compare two Colors + +Use: `(if (color-eq (255 200 0) (200 255 0)) "yes" "no")`. + +``` +(defn color-eq + (a b) + (and + (eq a:0 b:0) + (eq a:1 b:1) + (eq a:2 b:2))) +``` + +## Pixels + +### Erase all pixels of a specific color + +Use: `(pixels erase-color (255 0 0))`. + +``` +(defn erase-color + (a b) + (a:0 a:1 a:2 + (if + (and + (eq a:0 b:0) + (eq a:1 b:1) + (eq a:2 b:2)) 0 255))) +``` + +### Posterize + +Use: `(pixels posterize 40)`. + +``` +(defn posterize + (a q) + ( + (step a:0 q) + (step a:1 q) + (step a:2 q) a:3)) +``` \ No newline at end of file diff --git a/resources/PREVIEW.jpg b/resources/PREVIEW.jpg new file mode 100644 index 0000000000000000000000000000000000000000..38781008ffc57d84884ac233e0201db185f98061 GIT binary patch literal 856120 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