diff --git a/README.md b/README.md index 84be6af7..4a042cd9 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ You can use [Gitpod](https://www.gitpod.io/) (an Online Open Source VS Code-like - install all of the dependencies. - start `gulp` in `gulp/` directory. -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/) +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/tobspr/shapez.io) ## Helping translate diff --git a/electron_wegame/README.md b/electron_wegame/README.md new file mode 100644 index 00000000..70736caf --- /dev/null +++ b/electron_wegame/README.md @@ -0,0 +1 @@ +To build, place the lib64 folder from the wegame sdk for electron 13 in `wegame_sdk` and run the `wegame.main.standalone` gulp task. diff --git a/electron_wegame/index.js b/electron_wegame/index.js index e58c30d9..57d1f43e 100644 --- a/electron_wegame/index.js +++ b/electron_wegame/index.js @@ -51,8 +51,9 @@ function createWindow() { webPreferences: { nodeIntegration: true, webSecurity: false, + contextIsolation: false, }, - // allowRunningInsecureContent: false, + allowRunningInsecureContent: false, }); if (isLocal) { diff --git a/electron_wegame/package.json b/electron_wegame/package.json index 173379b6..aba5bb6a 100644 --- a/electron_wegame/package.json +++ b/electron_wegame/package.json @@ -10,7 +10,7 @@ "start": "electron --disable-direct-composition --in-process-gpu ." }, "devDependencies": { - "electron": "3.1.13" + "electron": "^13.1.6" }, "dependencies": { "async-lock": "^1.2.8" diff --git a/electron_wegame/wegame.js b/electron_wegame/wegame.js index 69f121e1..05a0e186 100644 --- a/electron_wegame/wegame.js +++ b/electron_wegame/wegame.js @@ -1,5 +1,5 @@ const railsdk = require("./wegame_sdk/railsdk.js"); -const { dialog } = require("electron"); +const { dialog, app, remote, ipcMain } = require("electron"); function init(isDev) { console.log("Step 1: wegame: init"); @@ -39,7 +39,7 @@ function init(isDev) { event.state === railsdk.RailSystemState.kSystemStatePlatformExit || event.state === railsdk.RailSystemState.kSystemStateGameExitByAntiAddiction ) { - remote.app.exit(); + app.exit(); } } }); @@ -47,6 +47,17 @@ function init(isDev) { function listen() { console.log("wegame: listen"); + ipcMain.handle("profanity-check", async (event, data) => { + if (data.length === 0) { + return ""; + } + const result = railsdk.RailUtils.DirtyWordsFilter(data, true); + if (result.check_result.dirty_type !== 0 /** kRailDirtyWordsTypeNormalAllowWords */) { + return result.check_result.replace_string; + } + + return data; + }); } module.exports = { init, listen }; diff --git a/electron_wegame/yarn.lock b/electron_wegame/yarn.lock index 025549d9..69c595ea 100644 --- a/electron_wegame/yarn.lock +++ b/electron_wegame/yarn.lock @@ -2,69 +2,48 @@ # yarn lockfile v1 -"@types/node@^10.1.4": - version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" - integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - -ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== +"@electron/get@^1.0.1": + version "1.12.4" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.4.tgz#a5971113fc1bf8fa12a8789dc20152a7359f06ab" + integrity sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg== dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" + debug "^4.1.1" + env-paths "^2.2.0" + fs-extra "^8.1.0" + got "^9.6.0" + progress "^2.0.3" + semver "^6.2.0" + sumchecker "^3.0.1" + optionalDependencies: + global-agent "^2.0.2" + global-tunnel-ng "^2.7.1" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== dependencies: - safer-buffer "~2.1.0" + defer-to-connect "^1.0.1" -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +"@types/node@^14.6.2": + version "14.17.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0" + integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A== async-lock@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c" integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" +boolean@^3.0.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2" + integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw== buffer-crc32@~0.2.3: version "0.2.13" @@ -76,35 +55,25 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= dependencies: - delayed-stream "~1.0.0" + mimic-response "^1.0.0" concat-stream@^1.6.2: version "1.6.2" @@ -116,102 +85,102 @@ concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -core-util-is@1.0.2, core-util-is@~1.0.0: +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +core-js@^3.6.5: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" + integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q== + +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@^2.1.3, debug@^2.2.0, debug@^2.6.9: +debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^3.0.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== +debug@^4.1.0, debug@^4.1.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: - ms "^2.1.1" + ms "2.1.2" -decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" + mimic-response "^1.0.0" -electron-download@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-4.1.1.tgz#02e69556705cc456e520f9e035556ed5a015ebe8" - integrity sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg== - dependencies: - debug "^3.0.0" - env-paths "^1.0.0" - fs-extra "^4.0.1" - minimist "^1.2.0" - nugget "^2.0.1" - path-exists "^3.0.0" - rc "^1.2.1" - semver "^5.4.1" - sumchecker "^2.0.2" +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -electron@3.1.13: - version "3.1.13" - resolved "https://registry.yarnpkg.com/electron/-/electron-3.1.13.tgz#aeb276f4cf5e3785078b6495e982ee46d553a5d2" - integrity sha512-aRNywoUSO1Va/lpU4nz3K6GDyFqYtlOnHGLcERAAHfhB+IJrJ34cUJW4FVBpm43AwvUdAeuCkVKRLtOmrgx5CA== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: - "@types/node" "^10.1.4" - electron-download "^4.1.0" + object-keys "^1.0.12" + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +electron@^13.1.6: + version "13.1.6" + resolved "https://registry.yarnpkg.com/electron/-/electron-13.1.6.tgz#6ecaf969255d62ce82cc0b5c948bf26e7dfb489b" + integrity sha512-XiB55/JTaQpDFQrD9pulYnOGwaWeMyRIub5ispvoE2bWBvM5zVMLptwMLb0m3KTMrfSkzhedZvOu7fwYvR7L7Q== + dependencies: + "@electron/get" "^1.0.1" + "@types/node" "^14.6.2" extract-zip "^1.0.3" -env-paths@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" - integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA= +encodeurl@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -error-ex@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: - is-arrayish "^0.2.1" + once "^1.4.0" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +es6-error@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== extract-zip@^1.0.3: version "1.7.0" @@ -223,26 +192,6 @@ extract-zip@^1.0.3: mkdirp "^0.5.4" yauzl "^2.10.0" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -250,175 +199,107 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-extra@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" + graceful-fs "^4.2.0" jsonfile "^4.0.0" universalify "^0.1.0" -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: - assert-plus "^1.0.0" + pump "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6: +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +global-agent@^2.0.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc" + integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg== + dependencies: + boolean "^3.0.1" + core-js "^3.6.5" + es6-error "^4.1.1" + matcher "^3.0.0" + roarr "^2.15.3" + semver "^7.3.2" + serialize-error "^7.0.1" + +global-tunnel-ng@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" + integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== + dependencies: + encodeurl "^1.0.2" + lodash "^4.17.10" + npm-conf "^1.1.3" + tunnel "^0.0.6" + +globalthis@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" + integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== + dependencies: + define-properties "^1.1.3" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - -inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@~1.3.0: +ini@^1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== - dependencies: - has "^1.0.3" - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -430,69 +311,48 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" + json-buffer "3.0.0" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" +lodash@^4.17.10: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -map-obj@^1.0.0, map-obj@^1.0.1: +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== -meow@^3.1.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" + yallist "^4.0.0" -mime-db@1.47.0: - version "1.47.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" - integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.30" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" - integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== +matcher@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" + integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== dependencies: - mime-db "1.47.0" + escape-string-regexp "^4.0.0" -minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -509,176 +369,78 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +npm-conf@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" + config-chain "^1.1.11" + pify "^3.0.0" -nugget@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0" - integrity sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA= +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: - debug "^2.1.3" - minimist "^1.1.0" - pretty-bytes "^1.0.2" - progress-stream "^1.1.0" - request "^2.45.0" - single-line-log "^1.1.2" - throttleit "0.0.2" + wrappy "1" -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-type@^1.0.0: +p-cancelable@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pretty-bytes@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" - integrity sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ= - dependencies: - get-stdin "^4.0.1" - meow "^3.1.0" +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -progress-stream@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77" - integrity sha1-LNPP6jO6OonJwSHsM0er6asSX3c= +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: - speedometer "~0.1.2" - through2 "~0.2.3" - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -rc@^1.2.1: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" + end-of-stream "^1.1.0" + once "^1.3.1" readable-stream@^2.2.2: version "2.3.7" @@ -693,156 +455,58 @@ readable-stream@^2.2.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" + lowercase-keys "^1.0.0" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= +roarr@^2.15.3: + version "2.15.4" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" + integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request@^2.45.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -resolve@^1.10.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + boolean "^3.0.1" + detect-node "^2.0.4" + globalthis "^1.0.1" + json-stringify-safe "^5.0.1" + semver-compare "^1.0.0" + sprintf-js "^1.1.2" safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -"semver@2 || 3 || 4 || 5", semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -signal-exit@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +semver@^7.3.2: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" -single-line-log@^1.1.2: +serialize-error@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" + integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== + dependencies: + type-fest "^0.13.1" + +sprintf-js@^1.1.2: version "1.1.2" - resolved "https://registry.yarnpkg.com/single-line-log/-/single-line-log-1.1.2.tgz#c2f83f273a3e1a16edb0995661da0ed5ef033364" - integrity sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q= - dependencies: - string-width "^1.0.1" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" - integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== - -speedometer@~0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" - integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== string_decoder@~1.1.1: version "1.1.1" @@ -851,76 +515,27 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: +sumchecker@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" + integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg== dependencies: - ansi-regex "^2.0.0" + debug "^4.1.0" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -sumchecker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-2.0.2.tgz#0f42c10e5d05da5d42eea3e56c3399a37d6c5b3e" - integrity sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4= - dependencies: - debug "^2.2.0" - -throttleit@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" - integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= - -through2@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" - integrity sha1-6zKE2k6jEbbMis42U3SKUqvyWj8= - dependencies: - readable-stream "~1.1.9" - xtend "~2.1.1" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -trim-newlines@^1.0.0: +to-readable-stream@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-fest@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" + integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== typedarray@^0.0.6: version "0.0.6" @@ -932,46 +547,27 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= dependencies: - punycode "^2.1.0" + prepend-http "^2.0.0" util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= - dependencies: - object-keys "~0.4.0" +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yauzl@^2.10.0: version "2.10.0" diff --git a/res/logo_wegame.png b/res/logo_wegame.png index eb7d35fe..ac9092b3 100644 Binary files a/res/logo_wegame.png and b/res/logo_wegame.png differ diff --git a/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif b/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif new file mode 100644 index 00000000..c7208ac2 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/1_1_extractor.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif b/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif new file mode 100644 index 00000000..8432b676 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/1_2_conveyor.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif b/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif new file mode 100644 index 00000000..9c655ab1 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/1_3_expand.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif b/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif new file mode 100644 index 00000000..ea854cf2 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/21_1_place_quad_painter.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif b/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif new file mode 100644 index 00000000..78ab6fd2 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/21_2_switch_to_wires.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif b/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif new file mode 100644 index 00000000..52ffb076 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/21_3_place_button.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif b/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif new file mode 100644 index 00000000..5d79f1e3 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/21_4_press_button.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif b/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif new file mode 100644 index 00000000..1678c0b2 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/2_1_place_cutter.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif b/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif new file mode 100644 index 00000000..0d60fa9f Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/2_2_place_trash.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif b/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif new file mode 100644 index 00000000..50ce88f9 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/2_3_more_cutters.gif differ diff --git a/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif b/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif new file mode 100644 index 00000000..81668af8 Binary files /dev/null and b/res/ui/interactive_tutorial.cn.noinline/3_1_rectangles.gif differ diff --git a/res/ui/wegame_isbn_rating.jpg b/res/ui/wegame_isbn_rating.jpg new file mode 100644 index 00000000..581dd744 Binary files /dev/null and b/res/ui/wegame_isbn_rating.jpg differ diff --git a/src/css/ingame_hud/puzzle_complete_notification.scss b/src/css/ingame_hud/puzzle_complete_notification.scss index 5f36df82..a35da83d 100644 --- a/src/css/ingame_hud/puzzle_complete_notification.scss +++ b/src/css/ingame_hud/puzzle_complete_notification.scss @@ -137,16 +137,20 @@ button.continue { background: #555; - @include S(margin-right, 10px); } button.menu { + background: #555; + } + + button.nextPuzzle { background-color: $colorGreenBright; } > button { @include S(min-width, 100px); - @include S(padding, 10px, 20px); + @include S(padding, 8px, 16px); + @include S(margin, 0, 6px); @include IncreasedClickArea(0px); } } diff --git a/src/css/ingame_hud/puzzle_next.scss b/src/css/ingame_hud/puzzle_next.scss new file mode 100644 index 00000000..ee0f664f --- /dev/null +++ b/src/css/ingame_hud/puzzle_next.scss @@ -0,0 +1,41 @@ +#ingame_HUD_PuzzleNextPuzzle { + position: absolute; + @include S(top, 17px); + @include S(right, 10px); + + display: flex; + flex-direction: column; + align-items: flex-end; + backdrop-filter: blur(D(1px)); + padding: D(3px); + + > .button { + @include ButtonText; + @include IncreasedClickArea(0px); + pointer-events: all; + cursor: pointer; + position: relative; + color: #333438; + transition: all 0.12s ease-in-out; + text-transform: uppercase; + transition-property: opacity, transform; + @include PlainText; + @include S(padding-right, 25px); + opacity: 1; + + @include DarkThemeInvert; + + &:hover { + opacity: 0.9 !important; + } + + &.pressed { + transform: scale(0.95) !important; + } + + & { + /* @load-async */ + background: uiResource("icons/state_next_button.png") right center / D(15px) no-repeat; + } + } +} diff --git a/src/css/main.scss b/src/css/main.scss index 1bd82828..1ac4f537 100644 --- a/src/css/main.scss +++ b/src/css/main.scss @@ -21,6 +21,7 @@ @import "adinplay"; @import "changelog_skins"; +@import "states/wegame_splash"; @import "states/preload"; @import "states/main_menu"; @import "states/ingame"; @@ -64,6 +65,7 @@ @import "ingame_hud/puzzle_play_settings"; @import "ingame_hud/puzzle_play_metadata"; @import "ingame_hud/puzzle_complete_notification"; +@import "ingame_hud/puzzle_next"; // prettier-ignore $elements: @@ -82,6 +84,7 @@ ingame_HUD_PinnedShapes, ingame_HUD_GameMenu, ingame_HUD_KeybindingOverlay, ingame_HUD_PuzzleBackToMenu, +ingame_HUD_PuzzleNextPuzzle, ingame_HUD_PuzzleEditorReview, ingame_HUD_PuzzleEditorControls, ingame_HUD_PuzzleEditorTitle, @@ -133,6 +136,7 @@ body.uiHidden { #ingame_HUD_GameMenu, #ingame_HUD_PinnedShapes, #ingame_HUD_PuzzleBackToMenu, + #ingame_HUD_PuzzleNextPuzzle, #ingame_HUD_PuzzleEditorReview, #ingame_HUD_Notifications, #ingame_HUD_TutorialHints, diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index 2b44b56e..15cdbe1c 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -550,6 +550,16 @@ } } + #crosspromo { + position: absolute; + @include S(bottom, 50px); + @include S(right, 20px); + @include S(width, 190px); + @include S(height, 100px); + pointer-events: all; + border: 0; + } + .footer { display: grid; flex-grow: 1; @@ -561,10 +571,45 @@ box-sizing: border-box; @include S(grid-gap, 4px); - &.china { + &.noLinks { grid-template-columns: auto 1fr; } + &.wegameDisclaimer { + @include SuperSmallText; + display: grid; + justify-content: center; + grid-template-columns: 1fr auto 1fr; + text-align: center; + + > .disclaimer { + grid-column: 2 / 3; + + @include DarkThemeOverride { + color: #fff; + } + } + + > .rating { + grid-column: 3 / 4; + justify-self: end; + align-self: end; + + @include S(width, 32px); + @include S(height, 40px); + background: green; + cursor: pointer !important; + pointer-events: all; + @include S(border-radius, 4px); + overflow: hidden; + + & { + /* @load-async */ + background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat; + } + } + } + .author { flex-grow: 1; text-align: right; diff --git a/src/css/states/puzzle_menu.scss b/src/css/states/puzzle_menu.scss index e2deacf0..44f5d7ce 100644 --- a/src/css/states/puzzle_menu.scss +++ b/src/css/states/puzzle_menu.scss @@ -15,8 +15,81 @@ } > .container { + .searchForm { + display: flex; + align-items: center; + justify-content: center; + + color: #333; + background: $accentColorBright; + @include S(padding, 5px); + @include S(border-radius, $globalBorderRadius); + flex-wrap: wrap; + + @include DarkThemeOverride { + background: $accentColorDark; + } + + input.search { + color: #333; + margin: 0; + display: inline-block; + flex-grow: 1; + @include S(padding, 5px, 10px); + @include S(min-width, 50px); + + &::placeholder { + color: #aaa; + } + } + + select { + color: #333; + border: 0; + @include S(padding, 5px); + @include S(border-radius, $globalBorderRadius); + @include S(padding, 7px, 10px); + @include S(margin-left, 5px); + @include PlainText; + } + + .filterCompleted { + @include S(margin-left, 20px); + pointer-events: all; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + text-transform: uppercase; + @include PlainText; + @include S(margin-right, 10px); + + @include DarkThemeOverride { + color: #bbbbc4; + } + + input { + @include S(width, 15px); + @include S(height, 15px); + @include S(margin-right, 5px); + @include S(border-radius, $globalBorderRadius); + border: 0; + } + } + + button[type="submit"] { + @include S(padding, 7px, 10px, 5px); + @include S(margin-left, 20px); + @include S(margin-top, 4px); + @include S(margin-bottom, 4px); + margin-left: auto; + } + } + > .mainContent { overflow: hidden; + display: flex; + flex-direction: column; > .categoryChooser { > .categories { @@ -79,8 +152,8 @@ @include S(grid-gap, 7px); @include S(margin-top, 10px); @include S(padding-right, 4px); - @include S(height, 320px); overflow-y: scroll; + flex-grow: 1; pointer-events: all; position: relative; @@ -246,6 +319,9 @@ &.stage--hard { color: $colorRedBright; } + &.stage--unknown { + color: #888; + } } } diff --git a/src/css/states/settings.scss b/src/css/states/settings.scss index 50afcaa3..5b36c677 100644 --- a/src/css/states/settings.scss +++ b/src/css/states/settings.scss @@ -50,7 +50,8 @@ } button.categoryButton, - button.about { + button.about, + button.privacy { background-color: $colorCategoryButton; color: #777a7f; @@ -68,6 +69,10 @@ } } + button.privacy { + @include S(margin-top, 4px); + } + .versionbar { @include S(margin-top, 10px); @@ -180,7 +185,8 @@ .container .content { .sidebar { button.categoryButton, - button.about { + button.about, + button.privacy { color: #ccc; background-color: darken($darkModeControlsBackground, 5); diff --git a/src/css/states/wegame_splash.scss b/src/css/states/wegame_splash.scss new file mode 100644 index 00000000..961cfa67 --- /dev/null +++ b/src/css/states/wegame_splash.scss @@ -0,0 +1,38 @@ +#state_WegameSplashState { + background: #000 !important; + display: flex; + align-items: center; + justify-content: center; + + .wrapper { + opacity: 0; + @include InlineAnimation(5.9s ease-in-out) { + 0% { + opacity: 0; + } + 20% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + opacity: 0; + } + } + + text-align: center; + color: #fff; + @include Heading; + + strong { + display: block; + @include SuperHeading; + @include S(margin-bottom, 20px); + } + + div { + @include S(margin-bottom, 10px); + } + } +} diff --git a/src/js/application.js b/src/js/application.js index 4e74b014..c49b7027 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -34,6 +34,7 @@ import { RestrictionManager } from "./core/restriction_manager"; import { PuzzleMenuState } from "./states/puzzle_menu"; import { ClientAPI } from "./platform/api"; import { LoginState } from "./states/login"; +import { WegameSplashState } from "./states/wegame_splash"; /** * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface @@ -155,6 +156,7 @@ export class Application { registerStates() { /** @type {Array} */ const states = [ + WegameSplashState, PreloadState, MobileWarningState, MainMenuState, @@ -330,8 +332,12 @@ export class Application { Loader.linkAppAfterBoot(this); + if (G_WEGAME_VERSION) { + this.stateMgr.moveToState("WegameSplashState"); + } + // Check for mobile - if (IS_MOBILE) { + else if (IS_MOBILE) { this.stateMgr.moveToState("MobileWarningState"); } else { this.stateMgr.moveToState("PreloadState"); diff --git a/src/js/changelog.js b/src/js/changelog.js index 9b497ff8..ec9a317c 100644 --- a/src/js/changelog.js +++ b/src/js/changelog.js @@ -1,4 +1,27 @@ export const CHANGELOG = [ + { + version: "1.4.4", + date: "29.08.2021", + entries: [ + "Hotfix: Fixed the balancer not distributing items evenly, caused by the 1.4.3 update. Sorry for any inconveniences!", + ], + }, + { + version: "1.4.3", + date: "28.08.2021", + entries: [ + "You can now hold 'ALT' while hovering a building to see its output! (Thanks to Sense101) (PS: There is now a setting to have it always on!)", + "The map overview should now be much more performant! As a consequence, you can now zoom out farther! (Thanks to PFedak)", + "Puzzle DLC: There is now a 'next puzzle' button!", + "Puzzle DLC: There is now a search function!", + "Edit signal dialog now has the previous signal filled (Thanks to EmeraldBlock)", + "Further performance improvements (Thanks to PFedak)", + "Improved puzzle validation (Thanks to Sense101)", + "Input fields in dialogs should now automatically focus", + "Fix selected building being deselected at level up (Thanks to EmeraldBlock)", + "Updated translations", + ], + }, { version: "1.4.2", date: "24.06.2021", diff --git a/src/js/core/buffer_maintainer.js b/src/js/core/buffer_maintainer.js index 1d506803..3eaf1f8a 100644 --- a/src/js/core/buffer_maintainer.js +++ b/src/js/core/buffer_maintainer.js @@ -167,4 +167,25 @@ export class BufferMaintainer { }); return canvas; } + + /** + * @param {object} param0 + * @param {string} param0.key + * @param {string} param0.subKey + * @returns {HTMLCanvasElement?} + * + */ + getForKeyOrNullNoUpdate({ key, subKey }) { + let parent = this.cache.get(key); + if (!parent) { + return null; + } + + // Now search for sub key + const cacheHit = parent.get(subKey); + if (cacheHit) { + return cacheHit.canvas; + } + return null; + } } diff --git a/src/js/core/config.js b/src/js/core/config.js index 005e2719..bc2e2460 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -7,7 +7,7 @@ export const IS_DEBUG = export const SUPPORT_TOUCH = false; -export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0; +export const IS_MAC = navigator.platform.toLowerCase().indexOf("mac") >= 0 && !G_IS_DEV; const smoothCanvas = true; @@ -17,6 +17,8 @@ export const THIRDPARTY_URLS = { reddit: "https://www.reddit.com/r/shapezio", shapeViewer: "https://viewer.shapez.io", + privacyPolicy: "https://tobspr.io/privacy.html", + standaloneStorePage: "https://store.steampowered.com/app/1318690/shapezio/", stanaloneCampaignLink: "https://get.shapez.io", puzzleDlcStorePage: "https://store.steampowered.com/app/1625400/shapezio__Puzzle_DLC", @@ -55,6 +57,7 @@ export const globalConfig = { // Map mapChunkSize: 16, + chunkAggregateSize: 4, mapChunkOverviewMinZoom: 0.9, mapChunkWorldSize: null, // COMPUTED diff --git a/src/js/core/config.local.template.js b/src/js/core/config.local.template.js index fc71c01e..41677997 100644 --- a/src/js/core/config.local.template.js +++ b/src/js/core/config.local.template.js @@ -53,7 +53,7 @@ export default { // Replace all translations with emojis to see which texts are translateable // testTranslations: true, // ----------------------------------------------------------------------------------- - // Enables an inspector which shows information about the entity below the curosr + // Enables an inspector which shows information about the entity below the cursor // enableEntityInspector: true, // ----------------------------------------------------------------------------------- // Enables ads in the local build (normally they are deactivated there) diff --git a/src/js/core/error_handler.js b/src/js/core/error_handler.js index c149ba76..686e4e4e 100644 --- a/src/js/core/error_handler.js +++ b/src/js/core/error_handler.js @@ -123,6 +123,4 @@ function catchErrors(message, source, lineno, colno, error) { return true; } -if (!G_IS_DEV) { - window.onerror = catchErrors; -} +window.onerror = catchErrors; diff --git a/src/js/core/game_state.js b/src/js/core/game_state.js index cee962f5..b08bef77 100644 --- a/src/js/core/game_state.js +++ b/src/js/core/game_state.js @@ -91,26 +91,6 @@ export class GameState { } } - /** - * - * @param {string} nextStateId - * @param {object=} nextStatePayload - */ - watchAdAndMoveToState(nextStateId, nextStatePayload = {}) { - if (this.app.adProvider.getCanShowVideoAd() && this.app.isRenderable()) { - this.moveToState( - "WatchAdState", - { - nextStateId, - nextStatePayload, - }, - true - ); - } else { - this.moveToState(nextStateId, nextStatePayload); - } - } - /** * Tracks clicks on a given element and calls the given callback *on this state*. * If you want to call another function wrap it inside a lambda. diff --git a/src/js/core/modal_dialog_forms.js b/src/js/core/modal_dialog_forms.js index aac81d82..ccf9bfb2 100644 --- a/src/js/core/modal_dialog_forms.js +++ b/src/js/core/modal_dialog_forms.js @@ -1,6 +1,7 @@ import { BaseItem } from "../game/base_item"; import { ClickDetector } from "./click_detector"; import { Signal } from "./signal"; +import { getIPCRenderer } from "./utils"; /* * *************************************************** @@ -107,6 +108,19 @@ export class FormElementInput extends FormElement { updateErrorState() { this.element.classList.toggle("errored", !this.isValid()); + + // profanity filter + if (G_WEGAME_VERSION) { + const value = String(this.element.value); + + getIPCRenderer() + .invoke("profanity-check", value) + .then(newValue => { + if (value !== newValue && this.element) { + this.element.value = newValue; + } + }); + } } isValid() { @@ -124,6 +138,7 @@ export class FormElementInput extends FormElement { focus() { this.element.focus(); + this.element.select(); } } diff --git a/src/js/core/restriction_manager.js b/src/js/core/restriction_manager.js index 2912d30f..c899b494 100644 --- a/src/js/core/restriction_manager.js +++ b/src/js/core/restriction_manager.js @@ -89,6 +89,11 @@ export class RestrictionManager extends ReadWriteProxy { return false; } + if (queryParamOptions.embedProvider === "gamedistribution") { + // also full version on gamedistribution + return false; + } + if (G_IS_DEV) { return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0; } diff --git a/src/js/core/utils.js b/src/js/core/utils.js index 842e6151..1d1b0b02 100644 --- a/src/js/core/utils.js +++ b/src/js/core/utils.js @@ -734,6 +734,10 @@ const romanLiteralsCache = ["0"]; * @returns {string} */ export function getRomanNumber(number) { + if (G_WEGAME_VERSION) { + return String(number); + } + number = Math.max(0, Math.round(number)); if (romanLiteralsCache[number]) { return romanLiteralsCache[number]; diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index 719925af..bfc54cd8 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -11,6 +11,7 @@ import { typeItemSingleton } from "../item_resolver"; * pos: Vector, * direction: enumDirection, * item: BaseItem, + * lastItem: BaseItem, * progress: number?, * cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot, * cachedBeltPath?: BeltPath, @@ -51,6 +52,7 @@ export class ItemEjectorComponent extends Component { clear() { for (const slot of this.slots) { slot.item = null; + slot.lastItem = null; slot.progress = 0; } } @@ -67,6 +69,7 @@ export class ItemEjectorComponent extends Component { pos: slot.pos, direction: slot.direction, item: null, + lastItem: null, progress: 0, cachedDestSlot: null, cachedTargetEntity: null, @@ -131,6 +134,7 @@ export class ItemEjectorComponent extends Component { return false; } this.slots[slotIndex].item = item; + this.slots[slotIndex].lastItem = item; this.slots[slotIndex].progress = 0; return true; } diff --git a/src/js/game/components/item_processor.js b/src/js/game/components/item_processor.js index 4c0e1835..f7dddec1 100644 --- a/src/js/game/components/item_processor.js +++ b/src/js/game/components/item_processor.js @@ -73,6 +73,12 @@ export class ItemProcessorComponent extends Component { // Type of processing requirement this.processingRequirement = processingRequirement; + /** + * Our current inputs + * @type {Map} + */ + this.inputSlots = new Map(); + this.clear(); } @@ -82,11 +88,13 @@ export class ItemProcessorComponent extends Component { // sure the outputs always match this.nextOutputSlot = 0; + this.inputSlots.clear(); + /** - * Our current inputs - * @type {Array<{ item: BaseItem, sourceSlot: number }>} + * Current input count + * @type {number} */ - this.inputSlots = []; + this.inputCount = 0; /** * What we are currently processing, empty if we don't produce anything rn @@ -115,19 +123,17 @@ export class ItemProcessorComponent extends Component { this.type === enumItemProcessorTypes.goal ) { // Hub has special logic .. not really nice but efficient. - this.inputSlots.push({ item, sourceSlot }); + this.inputSlots.set(this.inputCount, item); + this.inputCount++; return true; } // Check that we only take one item per slot - for (let i = 0; i < this.inputSlots.length; ++i) { - const slot = this.inputSlots[i]; - if (slot.sourceSlot === sourceSlot) { - return false; - } + if (this.inputSlots.has(sourceSlot)) { + return false; } - - this.inputSlots.push({ item, sourceSlot }); + this.inputSlots.set(sourceSlot, item); + this.inputCount++; return true; } } diff --git a/src/js/game/game_mode.js b/src/js/game/game_mode.js index bb60d8a6..5414306c 100644 --- a/src/js/game/game_mode.js +++ b/src/js/game/game_mode.js @@ -119,7 +119,7 @@ export class GameMode extends BasicSerializableObject { /** @returns {number} */ getMinimumZoom() { - return 0.1; + return 0.06; } /** @returns {number} */ diff --git a/src/js/game/hud/hud.js b/src/js/game/hud/hud.js index f35fe018..3d22787c 100644 --- a/src/js/game/hud/hud.js +++ b/src/js/game/hud/hud.js @@ -16,6 +16,7 @@ import { HUDEntityDebugger } from "./parts/entity_debugger"; import { HUDModalDialogs } from "./parts/modal_dialogs"; import { enumNotificationType } from "./parts/notifications"; import { HUDSettingsMenu } from "./parts/settings_menu"; +import { HUDShapeTooltip } from "./parts/shape_tooltip"; import { HUDVignetteOverlay } from "./parts/vignette_overlay"; import { TrailerMaker } from "./trailer_maker"; @@ -49,6 +50,8 @@ export class GameHUD { blueprintPlacer: new HUDBlueprintPlacer(this.root), buildingPlacer: new HUDBuildingPlacer(this.root), + shapeTooltip: new HUDShapeTooltip(this.root), + // Must always exist settingsMenu: new HUDSettingsMenu(this.root), debugInfo: new HUDDebugInfo(this.root), @@ -189,6 +192,7 @@ export class GameHUD { "colorBlindHelper", "changesDebugger", "minerHighlight", + "shapeTooltip", ]; for (let i = 0; i < partsOrder.length; ++i) { diff --git a/src/js/game/hud/parts/HUDPuzzleNextPuzzle.js b/src/js/game/hud/parts/HUDPuzzleNextPuzzle.js new file mode 100644 index 00000000..f0187d0d --- /dev/null +++ b/src/js/game/hud/parts/HUDPuzzleNextPuzzle.js @@ -0,0 +1,25 @@ +import { makeDiv } from "../../../core/utils"; +import { T } from "../../../translations"; +import { PuzzlePlayGameMode } from "../../modes/puzzle_play"; +import { BaseHUDPart } from "../base_hud_part"; + +export class HUDPuzzleNextPuzzle extends BaseHUDPart { + createElements(parent) { + this.element = makeDiv(parent, "ingame_HUD_PuzzleNextPuzzle"); + this.button = document.createElement("button"); + this.button.classList.add("button"); + this.button.innerText = T.ingame.puzzleCompletion.nextPuzzle; + this.element.appendChild(this.button); + + this.trackClicks(this.button, this.nextPuzzle); + } + + initialize() {} + + nextPuzzle() { + const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode); + this.root.gameState.moveToState("PuzzleMenuState", { + continueQueue: gameMode.nextPuzzles, + }); + } +} diff --git a/src/js/game/hud/parts/building_placer_logic.js b/src/js/game/hud/parts/building_placer_logic.js index 9e91f372..7ed412f6 100644 --- a/src/js/game/hud/parts/building_placer_logic.js +++ b/src/js/game/hud/parts/building_placer_logic.js @@ -128,7 +128,6 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart { this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this); this.root.hud.signals.pasteBlueprintRequested.add(this.abortPlacement, this); this.root.signals.storyGoalCompleted.add(() => this.signals.variantChanged.dispatch()); - this.root.signals.storyGoalCompleted.add(() => this.currentMetaBuilding.set(null)); this.root.signals.upgradePurchased.add(() => this.signals.variantChanged.dispatch()); this.root.signals.editModeChanged.add(this.onEditModeChanged, this); diff --git a/src/js/game/hud/parts/interactive_tutorial.js b/src/js/game/hud/parts/interactive_tutorial.js index ec0ffacc..282e6d43 100644 --- a/src/js/game/hud/parts/interactive_tutorial.js +++ b/src/js/game/hud/parts/interactive_tutorial.js @@ -158,8 +158,13 @@ export class HUDInteractiveTutorial extends BaseHUDPart { onHintChanged(hintId) { this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId]; + + const folder = G_WEGAME_VERSION + ? "interactive_tutorial.cn.noinline" + : "interactive_tutorial.noinline"; + this.elementGif.style.backgroundImage = - "url('" + cachebust("res/ui/interactive_tutorial.noinline/" + hintId + ".gif") + "')"; + "url('" + cachebust("res/ui/" + folder + "/" + hintId + ".gif") + "')"; this.element.classList.toggle("animEven"); this.element.classList.toggle("animOdd"); } diff --git a/src/js/game/hud/parts/puzzle_complete_notification.js b/src/js/game/hud/parts/puzzle_complete_notification.js index f223c1d6..d83e33f1 100644 --- a/src/js/game/hud/parts/puzzle_complete_notification.js +++ b/src/js/game/hud/parts/puzzle_complete_notification.js @@ -6,13 +6,8 @@ import { InputReceiver } from "../../../core/input_receiver"; import { makeDiv } from "../../../core/utils"; import { SOUNDS } from "../../../platform/sound"; import { T } from "../../../translations"; -import { enumColors } from "../../colors"; -import { ColorItem } from "../../items/color_item"; -import { finalGameShape, rocketShape } from "../../modes/regular"; import { BaseHUDPart } from "../base_hud_part"; import { DynamicDomAttach } from "../dynamic_dom_attach"; -import { ShapeItem } from "../../items/shape_item"; -import { ShapeDefinition } from "../../shape_definition"; export class HUDPuzzleCompleteNotification extends BaseHUDPart { initialize() { @@ -68,10 +63,21 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { this.menuBtn.classList.add("menu", "styledButton"); this.menuBtn.innerText = T.ingame.puzzleCompletion.menuBtn; buttonBar.appendChild(this.menuBtn); - this.trackClicks(this.menuBtn, () => { this.close(true); }); + + const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode); + if (gameMode.nextPuzzles.length > 0) { + this.nextPuzzleBtn = document.createElement("button"); + this.nextPuzzleBtn.classList.add("nextPuzzle", "styledButton"); + this.nextPuzzleBtn.innerText = T.ingame.puzzleCompletion.nextPuzzle; + buttonBar.appendChild(this.nextPuzzleBtn); + + this.trackClicks(this.nextPuzzleBtn, () => { + this.nextPuzzle(); + }); + } } updateState() { @@ -93,6 +99,15 @@ export class HUDPuzzleCompleteNotification extends BaseHUDPart { return this.visible; } + nextPuzzle() { + const gameMode = /** @type {PuzzlePlayGameMode} */ (this.root.gameMode); + gameMode.trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion)).then(() => { + this.root.gameState.moveToState("PuzzleMenuState", { + continueQueue: gameMode.nextPuzzles, + }); + }); + } + close(toMenu) { /** @type {PuzzlePlayGameMode} */ (this.root.gameMode) .trackCompleted(this.userDidLikePuzzle, Math.round(this.timeOfCompletion)) diff --git a/src/js/game/hud/parts/puzzle_editor_review.js b/src/js/game/hud/parts/puzzle_editor_review.js index 727006d6..4a044ba5 100644 --- a/src/js/game/hud/parts/puzzle_editor_review.js +++ b/src/js/game/hud/parts/puzzle_editor_review.js @@ -81,7 +81,7 @@ export class HUDPuzzleEditorReview extends BaseHUDPart { closeLoading(); //if it took so little ticks that it must have autocompeted - if (simulatedTicks <= 300) { + if (simulatedTicks <= 500) { this.root.hud.parts.dialogs.showWarning( T.puzzleMenu.validation.title, T.puzzleMenu.validation.autoComplete diff --git a/src/js/game/hud/parts/puzzle_editor_settings.js b/src/js/game/hud/parts/puzzle_editor_settings.js index 13564da4..bd738198 100644 --- a/src/js/game/hud/parts/puzzle_editor_settings.js +++ b/src/js/game/hud/parts/puzzle_editor_settings.js @@ -149,8 +149,9 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart { assertAlways(false, "Failed to re-place building in trim"); } - if (building.components.ConstantSignal) { - result.components.ConstantSignal.signal = building.components.ConstantSignal.signal; + for (const key in building.components) { + /** @type {import("../../../core/global_registries").Component} */ (building + .components[key]).copyAdditionalStateTo(result.components[key]); } } }); diff --git a/src/js/game/hud/parts/shape_tooltip.js b/src/js/game/hud/parts/shape_tooltip.js new file mode 100644 index 00000000..aabe7fa1 --- /dev/null +++ b/src/js/game/hud/parts/shape_tooltip.js @@ -0,0 +1,100 @@ +import { DrawParameters } from "../../../core/draw_parameters"; +import { enumDirectionToVector, Vector } from "../../../core/vector"; +import { Entity } from "../../entity"; +import { KEYMAPPINGS } from "../../key_action_mapper"; +import { THEME } from "../../theme"; +import { BaseHUDPart } from "../base_hud_part"; + +export class HUDShapeTooltip extends BaseHUDPart { + createElements(parent) {} + + initialize() { + /** @type {Vector} */ + this.currentTile = new Vector(0, 0); + + /** @type {Entity} */ + this.currentEntity = null; + + this.isPlacingBuilding = false; + + this.root.signals.entityQueuedForDestroy.add(() => { + this.currentEntity = null; + }, this); + + this.root.hud.signals.selectedPlacementBuildingChanged.add(metaBuilding => { + this.isPlacingBuilding = metaBuilding; + }, this); + } + + isActive() { + const hudParts = this.root.hud.parts; + + const active = + this.root.app.settings.getSetting("shapeTooltipAlwaysOn") || + this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.showShapeTooltip).pressed; + + // return false if any other placer is active + return ( + active && + !this.isPlacingBuilding && + !hudParts.massSelector.currentSelectionStartWorld && + hudParts.massSelector.selectedUids.size < 1 && + !hudParts.blueprintPlacer.currentBlueprint.get() + ); + } + + /** + * + * @param {DrawParameters} parameters + */ + draw(parameters) { + if (this.isActive()) { + const mousePos = this.root.app.mousePosition; + + if (mousePos) { + const tile = this.root.camera.screenToWorld(mousePos.copy()).toTileSpace(); + if (!tile.equals(this.currentTile)) { + this.currentTile = tile; + + const entity = this.root.map.getLayerContentXY(tile.x, tile.y, this.root.currentLayer); + + if (entity && entity.components.ItemProcessor && entity.components.ItemEjector) { + this.currentEntity = entity; + } else { + this.currentEntity = null; + } + } + } + + if (!this.currentEntity) { + return; + } + + const ejectorComp = this.currentEntity.components.ItemEjector; + const staticComp = this.currentEntity.components.StaticMapEntity; + + const bounds = staticComp.getTileSize(); + const totalArea = bounds.x * bounds.y; + const maxSlots = totalArea < 2 ? 1 : 1e10; + + let slotsDrawn = 0; + + for (let i = 0; i < ejectorComp.slots.length; ++i) { + const slot = ejectorComp.slots[i]; + + if (!slot.lastItem) { + continue; + } + + if (++slotsDrawn > maxSlots) { + continue; + } + + /** @type {Vector} */ + const drawPos = staticComp.localTileToWorld(slot.pos).toWorldSpaceCenterOfTile(); + + slot.lastItem.drawItemCenteredClipped(drawPos.x, drawPos.y, parameters, 25); + } + } + } +} diff --git a/src/js/game/hud/parts/waypoints.js b/src/js/game/hud/parts/waypoints.js index 2e0bc159..f973a925 100644 --- a/src/js/game/hud/parts/waypoints.js +++ b/src/js/game/hud/parts/waypoints.js @@ -45,7 +45,7 @@ export class HUDWaypoints extends BaseHUDPart { */ createElements(parent) { // Create the helper box on the lower right when zooming out - if (this.root.app.settings.getAllSettings().offerHints) { + if (this.root.app.settings.getAllSettings().offerHints && !G_WEGAME_VERSION) { this.hintElement = makeDiv( parent, "ingame_HUD_Waypoints_Hint", @@ -121,10 +121,12 @@ export class HUDWaypoints extends BaseHUDPart { } // Catch mouse and key events - this.root.camera.downPreHandler.add(this.onMouseDown, this); - this.root.keyMapper - .getBinding(KEYMAPPINGS.navigation.createMarker) - .add(() => this.requestSaveMarker({})); + if (!G_WEGAME_VERSION) { + this.root.camera.downPreHandler.add(this.onMouseDown, this); + this.root.keyMapper + .getBinding(KEYMAPPINGS.navigation.createMarker) + .add(() => this.requestSaveMarker({})); + } /** * Stores at how much opacity the markers should be rendered on the map. diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 41208d13..090b8b83 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -32,6 +32,8 @@ export const KEYMAPPINGS = { toggleFPSInfo: { keyCode: 115 }, // F4 switchLayers: { keyCode: key("E") }, + + showShapeTooltip: { keyCode: 18 }, // ALT }, navigation: { diff --git a/src/js/game/logic.js b/src/js/game/logic.js index 20caca31..79104958 100644 --- a/src/js/game/logic.js +++ b/src/js/game/logic.js @@ -80,6 +80,15 @@ export class GameLogic { } // Perform additional placement checks + if (this.root.gameMode.getIsEditor()) { + const toolbar = this.root.hud.parts.buildingsToolbar; + const id = entity.components.StaticMapEntity.getMetaBuilding().getId(); + + if (toolbar.buildingHandles[id].puzzleLocked) { + return false; + } + } + if (this.root.signals.prePlacementCheck.dispatch(entity, offset) === STOP_PROPAGATION) { return false; } diff --git a/src/js/game/map.js b/src/js/game/map.js index a5ec8f21..67df7db3 100644 --- a/src/js/game/map.js +++ b/src/js/game/map.js @@ -3,6 +3,7 @@ import { Vector } from "../core/vector"; import { BasicSerializableObject, types } from "../savegame/serialization"; import { BaseItem } from "./base_item"; import { Entity } from "./entity"; +import { MapChunkAggregate } from "./map_chunk_aggregate"; import { MapChunkView } from "./map_chunk_view"; import { GameRoot } from "./root"; @@ -31,6 +32,11 @@ export class BaseMap extends BasicSerializableObject { * Mapping of 'X|Y' to chunk * @type {Map} */ this.chunksById = new Map(); + + /** + * Mapping of 'X|Y' to chunk aggregate + * @type {Map} */ + this.aggregatesById = new Map(); } /** @@ -55,6 +61,39 @@ export class BaseMap extends BasicSerializableObject { return null; } + /** + * Returns the chunk aggregate containing a given chunk + * @param {number} chunkX + * @param {number} chunkY + */ + getAggregateForChunk(chunkX, chunkY, createIfNotExistent = false) { + const aggX = Math.floor(chunkX / globalConfig.chunkAggregateSize); + const aggY = Math.floor(chunkY / globalConfig.chunkAggregateSize); + return this.getAggregate(aggX, aggY, createIfNotExistent); + } + + /** + * Returns the given chunk aggregate by index + * @param {number} aggX + * @param {number} aggY + */ + getAggregate(aggX, aggY, createIfNotExistent = false) { + const aggIdentifier = aggX + "|" + aggY; + let storedAggregate; + + if ((storedAggregate = this.aggregatesById.get(aggIdentifier))) { + return storedAggregate; + } + + if (createIfNotExistent) { + const instance = new MapChunkAggregate(this.root, aggX, aggY); + this.aggregatesById.set(aggIdentifier, instance); + return instance; + } + + return null; + } + /** * Gets or creates a new chunk if not existent for the given tile * @param {number} tileX diff --git a/src/js/game/map_chunk_aggregate.js b/src/js/game/map_chunk_aggregate.js new file mode 100644 index 00000000..de15362d --- /dev/null +++ b/src/js/game/map_chunk_aggregate.js @@ -0,0 +1,154 @@ +import { globalConfig } from "../core/config"; +import { DrawParameters } from "../core/draw_parameters"; +import { drawSpriteClipped } from "../core/draw_utils"; +import { safeModulo } from "../core/utils"; +import { GameRoot } from "./root"; + +export const CHUNK_OVERLAY_RES = 3; + +export class MapChunkAggregate { + /** + * + * @param {GameRoot} root + * @param {number} x + * @param {number} y + */ + constructor(root, x, y) { + this.root = root; + this.x = x; + this.y = y; + + /** + * Whenever something changes, we increase this number - so we know we need to redraw + */ + this.renderIteration = 0; + this.dirty = false; + /** @type {Array} */ + this.dirtyList = new Array(globalConfig.chunkAggregateSize ** 2).fill(true); + this.markDirty(0, 0); + } + + /** + * Marks this chunk as dirty, rerendering all caches + * @param {number} chunkX + * @param {number} chunkY + */ + markDirty(chunkX, chunkY) { + const relX = safeModulo(chunkX, globalConfig.chunkAggregateSize); + const relY = safeModulo(chunkY, globalConfig.chunkAggregateSize); + this.dirtyList[relY * globalConfig.chunkAggregateSize + relX] = true; + if (this.dirty) { + return; + } + this.dirty = true; + ++this.renderIteration; + this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration; + } + + /** + * + * @param {HTMLCanvasElement} canvas + * @param {CanvasRenderingContext2D} context + * @param {number} w + * @param {number} h + * @param {number} dpi + */ + generateOverlayBuffer(canvas, context, w, h, dpi) { + const prevKey = this.x + "/" + this.y + "@" + (this.renderIteration - 1); + const prevBuffer = this.root.buffers.getForKeyOrNullNoUpdate({ + key: "agg@" + this.root.currentLayer, + subKey: prevKey, + }); + + const overlaySize = globalConfig.mapChunkSize * CHUNK_OVERLAY_RES; + let onlyDirty = false; + if (prevBuffer) { + context.drawImage(prevBuffer, 0, 0); + onlyDirty = true; + } + + for (let x = 0; x < globalConfig.chunkAggregateSize; x++) { + for (let y = 0; y < globalConfig.chunkAggregateSize; y++) { + if (onlyDirty && !this.dirtyList[globalConfig.chunkAggregateSize * y + x]) continue; + this.root.map + .getChunk( + this.x * globalConfig.chunkAggregateSize + x, + this.y * globalConfig.chunkAggregateSize + y, + true + ) + .generateOverlayBuffer( + context, + overlaySize, + overlaySize, + x * overlaySize, + y * overlaySize + ); + } + } + + this.dirty = false; + this.dirtyList.fill(false); + } + + /** + * Overlay + * @param {DrawParameters} parameters + */ + drawOverlay(parameters) { + const aggregateOverlaySize = + globalConfig.mapChunkSize * globalConfig.chunkAggregateSize * CHUNK_OVERLAY_RES; + const sprite = this.root.buffers.getForKey({ + key: "agg@" + this.root.currentLayer, + subKey: this.renderKey, + w: aggregateOverlaySize, + h: aggregateOverlaySize, + dpi: 1, + redrawMethod: this.generateOverlayBuffer.bind(this), + }); + + const dims = globalConfig.mapChunkWorldSize * globalConfig.chunkAggregateSize; + const extrude = 0.05; + + // Draw chunk "pixel" art + parameters.context.imageSmoothingEnabled = false; + drawSpriteClipped({ + parameters, + sprite, + x: this.x * dims - extrude, + y: this.y * dims - extrude, + w: dims + 2 * extrude, + h: dims + 2 * extrude, + originalW: aggregateOverlaySize, + originalH: aggregateOverlaySize, + }); + + parameters.context.imageSmoothingEnabled = true; + const resourcesScale = this.root.app.settings.getAllSettings().mapResourcesScale; + + // Draw patch items + if ( + this.root.currentLayer === "regular" && + resourcesScale > 0.05 && + this.root.camera.zoomLevel > 0.1 + ) { + const diameter = (70 / Math.pow(parameters.zoomLevel, 0.35)) * (0.2 + 2 * resourcesScale); + + for (let x = 0; x < globalConfig.chunkAggregateSize; x++) { + for (let y = 0; y < globalConfig.chunkAggregateSize; y++) { + this.root.map + .getChunk( + this.x * globalConfig.chunkAggregateSize + x, + this.y * globalConfig.chunkAggregateSize + y, + true + ) + .drawOverlayPatches( + parameters, + this.x * dims + x * globalConfig.mapChunkWorldSize, + this.y * dims + y * globalConfig.mapChunkWorldSize, + diameter + ); + } + } + } + } +} diff --git a/src/js/game/map_chunk_view.js b/src/js/game/map_chunk_view.js index 131ce37b..947b7a9f 100644 --- a/src/js/game/map_chunk_view.js +++ b/src/js/game/map_chunk_view.js @@ -33,6 +33,7 @@ export class MapChunkView extends MapChunk { markDirty() { ++this.renderIteration; this.renderKey = this.x + "/" + this.y + "@" + this.renderIteration; + this.root.map.getAggregateForChunk(this.x, this.y, true).markDirty(this.x, this.y); } /** @@ -82,73 +83,41 @@ export class MapChunkView extends MapChunk { } /** - * Overlay * @param {DrawParameters} parameters + * @param {number} xoffs + * @param {number} yoffs + * @param {number} diameter */ - drawOverlay(parameters) { - const overlaySize = globalConfig.mapChunkSize * CHUNK_OVERLAY_RES; - const sprite = this.root.buffers.getForKey({ - key: "chunk@" + this.root.currentLayer, - subKey: this.renderKey, - w: overlaySize, - h: overlaySize, - dpi: 1, - redrawMethod: this.generateOverlayBuffer.bind(this), - }); - - const dims = globalConfig.mapChunkWorldSize; - const extrude = 0.05; - - // Draw chunk "pixel" art - parameters.context.imageSmoothingEnabled = false; - drawSpriteClipped({ - parameters, - sprite, - x: this.x * dims - extrude, - y: this.y * dims - extrude, - w: dims + 2 * extrude, - h: dims + 2 * extrude, - originalW: overlaySize, - originalH: overlaySize, - }); - - parameters.context.imageSmoothingEnabled = true; - const resourcesScale = this.root.app.settings.getAllSettings().mapResourcesScale; - - // Draw patch items - if (this.root.currentLayer === "regular" && resourcesScale > 0.05) { - const diameter = (70 / Math.pow(parameters.zoomLevel, 0.35)) * (0.2 + 2 * resourcesScale); - - for (let i = 0; i < this.patches.length; ++i) { - const patch = this.patches[i]; - if (patch.item.getItemType() === "shape") { - const destX = this.x * dims + patch.pos.x * globalConfig.tileSize; - const destY = this.y * dims + patch.pos.y * globalConfig.tileSize; - patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter); - } + drawOverlayPatches(parameters, xoffs, yoffs, diameter) { + for (let i = 0; i < this.patches.length; ++i) { + const patch = this.patches[i]; + if (patch.item.getItemType() === "shape") { + const destX = xoffs + patch.pos.x * globalConfig.tileSize; + const destY = yoffs + patch.pos.y * globalConfig.tileSize; + patch.item.drawItemCenteredClipped(destX, destY, parameters, diameter); } } } /** * - * @param {HTMLCanvasElement} canvas * @param {CanvasRenderingContext2D} context * @param {number} w * @param {number} h - * @param {number} dpi + * @param {number=} xoffs + * @param {number=} yoffs */ - generateOverlayBuffer(canvas, context, w, h, dpi) { + generateOverlayBuffer(context, w, h, xoffs, yoffs) { context.fillStyle = this.containedEntities.length > 0 ? THEME.map.chunkOverview.filled : THEME.map.chunkOverview.empty; - context.fillRect(0, 0, w, h); + context.fillRect(xoffs, yoffs, w, h); if (this.root.app.settings.getAllSettings().displayChunkBorders) { context.fillStyle = THEME.map.chunkBorders; - context.fillRect(0, 0, w, 1); - context.fillRect(0, 1, 1, h); + context.fillRect(xoffs, yoffs, w, 1); + context.fillRect(xoffs, yoffs + 1, 1, h); } for (let x = 0; x < globalConfig.mapChunkSize; ++x) { @@ -174,8 +143,8 @@ export class MapChunkView extends MapChunk { if (lowerContent) { context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillRect( - x * CHUNK_OVERLAY_RES, - y * CHUNK_OVERLAY_RES, + xoffs + x * CHUNK_OVERLAY_RES, + yoffs + y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); @@ -190,8 +159,8 @@ export class MapChunkView extends MapChunk { const isFilled = overlayMatrix[dx + dy * 3]; if (isFilled) { context.fillRect( - x * CHUNK_OVERLAY_RES + dx, - y * CHUNK_OVERLAY_RES + dy, + xoffs + x * CHUNK_OVERLAY_RES + dx, + yoffs + y * CHUNK_OVERLAY_RES + dy, 1, 1 ); @@ -206,8 +175,8 @@ export class MapChunkView extends MapChunk { data.rotationVariant ); context.fillRect( - x * CHUNK_OVERLAY_RES, - y * CHUNK_OVERLAY_RES, + xoffs + x * CHUNK_OVERLAY_RES, + yoffs + y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); @@ -220,8 +189,8 @@ export class MapChunkView extends MapChunk { if (lowerContent) { context.fillStyle = lowerContent.getBackgroundColorAsResource(); context.fillRect( - x * CHUNK_OVERLAY_RES, - y * CHUNK_OVERLAY_RES, + xoffs + x * CHUNK_OVERLAY_RES, + yoffs + y * CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES, CHUNK_OVERLAY_RES ); @@ -233,7 +202,7 @@ export class MapChunkView extends MapChunk { // Draw wires overlay context.fillStyle = THEME.map.wires.overlayColor; - context.fillRect(0, 0, w, h); + context.fillRect(xoffs, yoffs, w, h); for (let x = 0; x < globalConfig.mapChunkSize; ++x) { const wiresArray = this.wireContents[x]; @@ -244,8 +213,8 @@ export class MapChunkView extends MapChunk { } MapChunkView.drawSingleWiresOverviewTile({ context, - x: x * CHUNK_OVERLAY_RES, - y: y * CHUNK_OVERLAY_RES, + x: xoffs + x * CHUNK_OVERLAY_RES, + y: yoffs + y * CHUNK_OVERLAY_RES, entity: content, tileSizePixels: CHUNK_OVERLAY_RES, }); diff --git a/src/js/game/map_view.js b/src/js/game/map_view.js index f4372a51..c6078ea9 100644 --- a/src/js/game/map_view.js +++ b/src/js/game/map_view.js @@ -5,6 +5,7 @@ import { freeCanvas, makeOffscreenBuffer } from "../core/buffer_utils"; import { Entity } from "./entity"; import { THEME } from "./theme"; import { MapChunkView } from "./map_chunk_view"; +import { MapChunkAggregate } from "./map_chunk_aggregate"; /** * This is the view of the map, it extends the map which is the raw model and allows @@ -164,6 +165,40 @@ export class MapView extends BaseMap { } } + /** + * Calls a given method on all given chunks + * @param {DrawParameters} parameters + * @param {function} method + */ + drawVisibleAggregates(parameters, method) { + const cullRange = parameters.visibleRect.allScaled(1 / globalConfig.tileSize); + const top = cullRange.top(); + const right = cullRange.right(); + const bottom = cullRange.bottom(); + const left = cullRange.left(); + + const border = 0; + const minY = top - border; + const maxY = bottom + border; + const minX = left - border; + const maxX = right + border; + + const aggregateTiles = globalConfig.chunkAggregateSize * globalConfig.mapChunkSize; + const aggStartX = Math.floor(minX / aggregateTiles); + const aggStartY = Math.floor(minY / aggregateTiles); + + const aggEndX = Math.floor(maxX / aggregateTiles); + const aggEndY = Math.floor(maxY / aggregateTiles); + + // Render y from top down for proper blending + for (let aggX = aggStartX; aggX <= aggEndX; ++aggX) { + for (let aggY = aggStartY; aggY <= aggEndY; ++aggY) { + const aggregate = this.root.map.getAggregate(aggX, aggY, true); + method.call(aggregate, parameters); + } + } + } + /** * Draws the wires foreground * @param {DrawParameters} parameters @@ -177,7 +212,7 @@ export class MapView extends BaseMap { * @param {DrawParameters} parameters */ drawOverlay(parameters) { - this.drawVisibleChunks(parameters, MapChunkView.prototype.drawOverlay); + this.drawVisibleAggregates(parameters, MapChunkAggregate.prototype.drawOverlay); } /** diff --git a/src/js/game/modes/puzzle_play.js b/src/js/game/modes/puzzle_play.js index 46480c51..fc9a8f11 100644 --- a/src/js/game/modes/puzzle_play.js +++ b/src/js/game/modes/puzzle_play.js @@ -30,6 +30,7 @@ import { HUDPuzzlePlaySettings } from "../hud/parts/puzzle_play_settings"; import { MetaBlockBuilding } from "../buildings/block"; import { MetaBuilding } from "../meta_building"; import { gMetaBuildingRegistry } from "../../core/global_registries"; +import { HUDPuzzleNextPuzzle } from "../hud/parts/HUDPuzzleNextPuzzle"; const logger = createLogger("puzzle-play"); const copy = require("clipboard-copy"); @@ -43,8 +44,9 @@ export class PuzzlePlayGameMode extends PuzzleGameMode { * @param {GameRoot} root * @param {object} payload * @param {import("../../savegame/savegame_typedefs").PuzzleFullData} payload.puzzle + * @param {Array | undefined} payload.nextPuzzles */ - constructor(root, { puzzle }) { + constructor(root, { puzzle, nextPuzzles }) { super(root); /** @type {Array} */ @@ -95,6 +97,15 @@ export class PuzzlePlayGameMode extends PuzzleGameMode { root.signals.postLoadHook.add(this.loadPuzzle, this); this.puzzle = puzzle; + + /** + * @type {Array} + */ + this.nextPuzzles = nextPuzzles || []; + + if (this.nextPuzzles.length > 0) { + this.additionalHudParts.puzzleNext = HUDPuzzleNextPuzzle; + } } loadPuzzle() { diff --git a/src/js/game/modes/regular.js b/src/js/game/modes/regular.js index 8a5988b3..be3dcc7c 100644 --- a/src/js/game/modes/regular.js +++ b/src/js/game/modes/regular.js @@ -344,61 +344,61 @@ export function generateLevelDefinitions(limitedVersion = false) { reward: enumHubGoalRewards.reward_rotater_ccw, }, - // 8 - { - shapes: [{ key: "RbRb----", amount: 480 }], // painter t2 - reward: enumHubGoalRewards.reward_mixer, - }, - - // 9 - // Mixing (purple) - { - shapes: [{ key: "CpCpCpCp", amount: 600 }], // belts t3 - reward: enumHubGoalRewards.reward_merger, - }, - - // 10 - // STACKER: Star shapes + cyan - { - shapes: [{ key: "ScScScSc", amount: 800 }], // miners t3 - reward: enumHubGoalRewards.reward_stacker, - }, - - // 11 - // Chainable miner - { - shapes: [{ key: "CgScScCg", amount: 1000 }], // processors t3 - reward: enumHubGoalRewards.reward_miner_chainable, - }, - - // 12 - // Blueprints - { - shapes: [{ key: "CbCbCbRb:CwCwCwCw", amount: 1000 }], - reward: enumHubGoalRewards.reward_blueprints, - }, - - // 13 - // Tunnel Tier 2 - { - shapes: [{ key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", amount: 3800 }], // painting t3 - reward: enumHubGoalRewards.reward_underground_belt_tier_2, - }, - // DEMO STOPS HERE ...(limitedVersion ? [ { - shapes: [ - { - key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", - amount: 0, - }, - ], + shapes: [{ key: "CrCrCrCr", amount: 0 }], reward: enumHubGoalRewards.reward_demo_end, }, ] : [ + // 8 + { + shapes: [{ key: "RbRb----", amount: 480 }], // painter t2 + reward: enumHubGoalRewards.reward_mixer, + }, + + // 9 + // Mixing (purple) + { + shapes: [{ key: "CpCpCpCp", amount: 600 }], // belts t3 + reward: enumHubGoalRewards.reward_merger, + }, + + // 10 + // STACKER: Star shapes + cyan + { + shapes: [{ key: "ScScScSc", amount: 800 }], // miners t3 + reward: enumHubGoalRewards.reward_stacker, + }, + + // 11 + // Chainable miner + { + shapes: [{ key: "CgScScCg", amount: 1000 }], // processors t3 + reward: enumHubGoalRewards.reward_miner_chainable, + }, + + // 12 + // Blueprints + { + shapes: [{ key: "CbCbCbRb:CwCwCwCw", amount: 1000 }], + reward: enumHubGoalRewards.reward_blueprints, + }, + + // 13 + // Tunnel Tier 2 + { + shapes: [ + { + key: chinaShapes ? "CuCuCuCu:CwCwCwCw:Sb--Sr--" : "RpRpRpRp:CwCwCwCw", + amount: 3800, + }, + ], // painting t3 + reward: enumHubGoalRewards.reward_underground_belt_tier_2, + }, + // 14 // Belt reader { @@ -585,7 +585,9 @@ export class RegularGameMode extends GameMode { } if (this.root.app.settings.getAllSettings().offerHints) { - this.additionalHudParts.tutorialHints = HUDPartTutorialHints; + if (!G_WEGAME_VERSION) { + this.additionalHudParts.tutorialHints = HUDPartTutorialHints; + } this.additionalHudParts.interactiveTutorial = HUDInteractiveTutorial; } @@ -595,12 +597,12 @@ export class RegularGameMode extends GameMode { } /** @type {(typeof MetaBuilding)[]} */ - this.hiddenBuildings = [ - MetaConstantProducerBuilding, - MetaGoalAcceptorBuilding, - MetaBlockBuilding, - MetaItemProducerBuilding, - ]; + this.hiddenBuildings = [MetaConstantProducerBuilding, MetaGoalAcceptorBuilding, MetaBlockBuilding]; + + // @ts-expect-error + if (!(G_IS_DEV || window.sandboxMode || queryParamOptions.sandboxMode)) { + this.hiddenBuildings.push(MetaItemProducerBuilding); + } } /** diff --git a/src/js/game/systems/constant_signal.js b/src/js/game/systems/constant_signal.js index d437f072..2bb1b7fe 100644 --- a/src/js/game/systems/constant_signal.js +++ b/src/js/game/systems/constant_signal.js @@ -49,11 +49,12 @@ export class ConstantSignalSystem extends GameSystemWithFilter { // Ok, query, but also save the uid because it could get stale const uid = entity.uid; + const signal = entity.components.ConstantSignal.signal; const signalValueInput = new FormElementInput({ id: "signalValue", label: fillInLinkIntoTranslation(T.dialogs.editSignal.descShortKey, THIRDPARTY_URLS.shapeViewer), placeholder: "", - defaultValue: "", + defaultValue: signal ? signal.getAsCopyableKey() : "", validator: val => this.parseSignalCode(entity, val), }); diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index 3794473f..525c242c 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -32,8 +32,8 @@ const MAX_QUEUED_CHARGES = 2; * Type of a processor implementation * @typedef {{ * entity: Entity, - * items: Array<{ item: BaseItem, sourceSlot: number }>, - * itemsBySlot: Object, + * items: Map, + * inputCount: number, * outItems: Array * }} ProcessorImplementationPayload */ @@ -189,7 +189,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // DEFAULT // By default, we can start processing once all inputs are there case null: { - return processorComp.inputSlots.length >= processorComp.inputsPerCharge; + return processorComp.inputCount >= processorComp.inputsPerCharge; } // QUAD PAINTER @@ -197,18 +197,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter { case enumItemProcessorRequirements.painterQuad: { const pinsComp = entity.components.WiredPins; - /** @type {Object.} */ - const itemsBySlot = {}; - for (let i = 0; i < processorComp.inputSlots.length; ++i) { - itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i]; - } - // First slot is the shape, so if it's not there we can't do anything - if (!itemsBySlot[0]) { + const shapeItem = /** @type {ShapeItem} */ (processorComp.inputSlots.get(0)); + if (!shapeItem) { return false; } - const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); const slotStatus = []; // Check which slots are enabled @@ -233,7 +227,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // Check if all colors of the enabled slots are there for (let i = 0; i < slotStatus.length; ++i) { - if (slotStatus[i] && !itemsBySlot[1 + i]) { + if (slotStatus[i] && !processorComp.inputSlots.get(1 + i)) { // A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, // it is not possible to paint, but if there is nothing we can ignore it for (let j = 0; j < 4; ++j) { @@ -262,13 +256,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter { // First, take items const items = processorComp.inputSlots; - processorComp.inputSlots = []; - - /** @type {Object} */ - const itemsBySlot = {}; - for (let i = 0; i < items.length; ++i) { - itemsBySlot[items[i].sourceSlot] = items[i].item; - } /** @type {Array} */ const outItems = []; @@ -281,8 +268,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { handler({ entity, items, - itemsBySlot, outItems, + inputCount: processorComp.inputCount, }); // Track produced items @@ -304,6 +291,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { items: outItems, remainingTime: timeToProcess, }); + + processorComp.inputSlots.clear(); + processorComp.inputCount = 0; } /** @@ -317,12 +307,14 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const availableSlots = payload.entity.components.ItemEjector.slots.length; const processorComp = payload.entity.components.ItemProcessor; - const nextSlot = processorComp.nextOutputSlot++ % availableSlots; - - for (let i = 0; i < payload.items.length; ++i) { + for (let i = 0; i < 2; ++i) { + const item = payload.items.get(i); + if (!item) { + continue; + } payload.outItems.push({ - item: payload.items[i].item, - preferredSlot: (nextSlot + i) % availableSlots, + item, + preferredSlot: processorComp.nextOutputSlot++ % availableSlots, doNotTrack: true, }); } @@ -333,20 +325,25 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition); + const ejectorComp = payload.entity.components.ItemEjector; for (let i = 0; i < cutDefinitions.length; ++i) { const definition = cutDefinitions[i]; - if (!definition.isEntirelyEmpty()) { - payload.outItems.push({ - item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), - requiredSlot: i, - }); + + if (definition.isEntirelyEmpty()) { + ejectorComp.slots[i].lastItem = null; + continue; } + + payload.outItems.push({ + item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), + requiredSlot: i, + }); } } @@ -354,20 +351,25 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_CUTTER_QUAD(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for cut is not a shape"); const inputDefinition = inputItem.definition; const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition); + const ejectorComp = payload.entity.components.ItemEjector; for (let i = 0; i < cutDefinitions.length; ++i) { const definition = cutDefinitions[i]; - if (!definition.isEntirelyEmpty()) { - payload.outItems.push({ - item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), - requiredSlot: i, - }); + + if (definition.isEntirelyEmpty()) { + ejectorComp.slots[i].lastItem = null; + continue; } + + payload.outItems.push({ + item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition), + requiredSlot: i, + }); } } @@ -375,7 +377,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -389,7 +391,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_CCW(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -403,7 +405,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_ROTATER_180(payload) { - const inputItem = /** @type {ShapeItem} */ (payload.items[0].item); + const inputItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(inputItem instanceof ShapeItem, "Input for rotation is not a shape"); const inputDefinition = inputItem.definition; @@ -417,8 +419,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_STACKER(payload) { - const lowerItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const upperItem = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); + const lowerItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const upperItem = /** @type {ShapeItem} */ (payload.items.get(1)); assert(lowerItem instanceof ShapeItem, "Input for lower stack is not a shape"); assert(upperItem instanceof ShapeItem, "Input for upper stack is not a shape"); @@ -444,8 +446,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_MIXER(payload) { // Find both colors and combine them - const item1 = /** @type {ColorItem} */ (payload.items[0].item); - const item2 = /** @type {ColorItem} */ (payload.items[1].item); + const item1 = /** @type {ColorItem} */ (payload.items.get(0)); + const item2 = /** @type {ColorItem} */ (payload.items.get(1)); assert(item1 instanceof ColorItem, "Input for color mixer is not a color"); assert(item2 instanceof ColorItem, "Input for color mixer is not a color"); @@ -467,8 +469,8 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[1]); + const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); + const colorItem = /** @type {ColorItem} */ (payload.items.get(1)); const colorizedDefinition = this.root.shapeDefinitionMgr.shapeActionPaintWith( shapeItem.definition, @@ -484,9 +486,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_DOUBLE(payload) { - const shapeItem1 = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); - const shapeItem2 = /** @type {ShapeItem} */ (payload.itemsBySlot[1]); - const colorItem = /** @type {ColorItem} */ (payload.itemsBySlot[2]); + const shapeItem1 = /** @type {ShapeItem} */ (payload.items.get(0)); + const shapeItem2 = /** @type {ShapeItem} */ (payload.items.get(1)); + const colorItem = /** @type {ColorItem} */ (payload.items.get(2)); assert(shapeItem1 instanceof ShapeItem, "Input for painter is not a shape"); assert(shapeItem2 instanceof ShapeItem, "Input for painter is not a shape"); @@ -514,14 +516,15 @@ export class ItemProcessorSystem extends GameSystemWithFilter { * @param {ProcessorImplementationPayload} payload */ process_PAINTER_QUAD(payload) { - const shapeItem = /** @type {ShapeItem} */ (payload.itemsBySlot[0]); + const shapeItem = /** @type {ShapeItem} */ (payload.items.get(0)); assert(shapeItem instanceof ShapeItem, "Input for painter is not a shape"); /** @type {Array} */ const colors = [null, null, null, null]; for (let i = 0; i < 4; ++i) { - if (payload.itemsBySlot[i + 1]) { - colors[i] = /** @type {ColorItem} */ (payload.itemsBySlot[i + 1]).color; + const colorItem = /** @type {ColorItem} */ (payload.items.get(i + 1)); + if (colorItem) { + colors[i] = colorItem.color; } } @@ -540,7 +543,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_READER(payload) { // Pass through the item - const item = payload.itemsBySlot[0]; + const item = payload.items.get(0); payload.outItems.push({ item, doNotTrack: true, @@ -559,8 +562,12 @@ export class ItemProcessorSystem extends GameSystemWithFilter { const hubComponent = payload.entity.components.Hub; assert(hubComponent, "Hub item processor has no hub component"); - for (let i = 0; i < payload.items.length; ++i) { - const item = /** @type {ShapeItem} */ (payload.items[i].item); + // Hardcoded + for (let i = 0; i < payload.inputCount; ++i) { + const item = /** @type {ShapeItem} */ (payload.items.get(i)); + if (!item) { + continue; + } this.root.hubGoals.handleDefinitionDelivered(item.definition); } } @@ -570,7 +577,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { */ process_GOAL(payload) { const goalComp = payload.entity.components.GoalAcceptor; - const item = payload.items[0].item; + const item = payload.items.get(0); const now = this.root.time.now(); if (goalComp.item && !item.equals(goalComp.item)) { @@ -584,7 +591,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter { if (this.root.gameMode.getIsEditor()) { // while playing in editor, assign the item - goalComp.item = payload.items[0].item; + goalComp.item = item; } goalComp.lastDelivery = { diff --git a/src/js/game/themes/dark.json b/src/js/game/themes/dark.json index cb111430..fec42e28 100644 --- a/src/js/game/themes/dark.json +++ b/src/js/game/themes/dark.json @@ -59,5 +59,10 @@ "outline": "#111418", "outlineWidth": 0.75, "circleBackground": "rgba(20, 30, 40, 0.3)" + }, + + "shapeTooltip": { + "background": "rgba(242, 245, 254, 0.9)", + "outline": "#44464e" } } diff --git a/src/js/game/themes/light.json b/src/js/game/themes/light.json index 0962eb93..d44a15ab 100644 --- a/src/js/game/themes/light.json +++ b/src/js/game/themes/light.json @@ -60,5 +60,10 @@ "outline": "#55575a", "outlineWidth": 0.75, "circleBackground": "rgba(40, 50, 65, 0.1)" + }, + + "shapeTooltip": { + "background": "#dee1ea", + "outline": "#54565e" } } diff --git a/src/js/languages.js b/src/js/languages.js index 4dfb15d4..b36b172f 100644 --- a/src/js/languages.js +++ b/src/js/languages.js @@ -12,7 +12,9 @@ export const LANGUAGES = { "zh-CN": { // simplified chinese name: "简体中文", - data: require("./built-temp/base-zh-CN.json"), + data: G_WEGAME_VERSION + ? require("./built-temp/base-zh-CN-ISBN.json") + : require("./built-temp/base-zh-CN.json"), code: "zh", region: "CN", }, diff --git a/src/js/platform/ad_providers/gamedistribution.js b/src/js/platform/ad_providers/gamedistribution.js index 6ff031f0..5a91646f 100644 --- a/src/js/platform/ad_providers/gamedistribution.js +++ b/src/js/platform/ad_providers/gamedistribution.js @@ -95,6 +95,10 @@ export class GamedistributionAdProvider extends AdProviderInterface { document.body.classList.add("externalAdOpen"); + logger.log("Set sound volume to 0"); + this.app.sound.setMusicVolume(0); + this.app.sound.setSoundVolume(0); + return new Promise(resolve => { // So, wait for the remove call but also remove after N seconds this.videoAdResolveFunction = () => { @@ -119,6 +123,11 @@ export class GamedistributionAdProvider extends AdProviderInterface { }) .then(() => { document.body.classList.remove("externalAdOpen"); + + logger.log("Restored sound volume"); + + this.app.sound.setMusicVolume(this.app.settings.getSetting("musicVolume")); + this.app.sound.setSoundVolume(this.app.settings.getSetting("soundVolume")); }); } } diff --git a/src/js/platform/api.js b/src/js/platform/api.js index db27360d..d518c98a 100644 --- a/src/js/platform/api.js +++ b/src/js/platform/api.js @@ -143,6 +143,20 @@ export class ClientAPI { return this._request("/v1/puzzles/list/" + category, {}); } + /** + * @param {{ searchTerm: string; difficulty: string; duration: string }} searchOptions + * @returns {Promise} + */ + apiSearchPuzzles(searchOptions) { + if (!this.isLoggedIn()) { + return Promise.reject("not-logged-in"); + } + return this._request("/v1/puzzles/search", { + method: "POST", + body: searchOptions, + }); + } + /** * @param {number} puzzleId * @returns {Promise} @@ -169,7 +183,7 @@ export class ClientAPI { } /** - * @param {number} shortKey + * @param {string} shortKey * @returns {Promise} */ apiDownloadPuzzleByKey(shortKey) { diff --git a/src/js/platform/browser/game_analytics.js b/src/js/platform/browser/game_analytics.js index 80e19c7a..9411b258 100644 --- a/src/js/platform/browser/game_analytics.js +++ b/src/js/platform/browser/game_analytics.js @@ -111,6 +111,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface { * @returns {Promise} */ sendToApi(endpoint, data) { + if (G_WEGAME_VERSION) { + return Promise.resolve(); + } + return new Promise((resolve, reject) => { const timeout = setTimeout(() => reject("Request to " + endpoint + " timed out"), 20000); diff --git a/src/js/platform/browser/wrapper.js b/src/js/platform/browser/wrapper.js index 3f4930d6..3610b533 100644 --- a/src/js/platform/browser/wrapper.js +++ b/src/js/platform/browser/wrapper.js @@ -135,15 +135,7 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface { openExternalLink(url, force = false) { logger.log("Opening external:", url); - if (force || this.embedProvider.externalLinks) { - window.open(url); - } else { - // Do nothing - alert( - "This platform does not allow opening external links. You can play on https://shapez.io directly to open them.\n\nClicked Link: " + - url - ); - } + window.open(url); } performRestart() { diff --git a/src/js/profile/application_settings.js b/src/js/profile/application_settings.js index 68abf5bb..22074eae 100644 --- a/src/js/profile/application_settings.js +++ b/src/js/profile/application_settings.js @@ -257,6 +257,7 @@ export const allApplicationSettings = [ }), new BoolSetting("enableMousePan", enumCategories.advanced, (app, value) => {}), + new BoolSetting("shapeTooltipAlwaysOn", enumCategories.advanced, (app, value) => {}), new BoolSetting("alwaysMultiplace", enumCategories.advanced, (app, value) => {}), new BoolSetting("zoomToCursor", enumCategories.advanced, (app, value) => {}), new BoolSetting("clearCursorOnDeleteWhilePlacing", enumCategories.advanced, (app, value) => {}), @@ -272,7 +273,7 @@ export const allApplicationSettings = [ new EnumSetting("refreshRate", { options: refreshRateOptions, valueGetter: rate => rate, - textGetter: rate => rate + " Hz", + textGetter: rate => T.settings.tickrateHz.replace("", rate), category: enumCategories.performance, restartRequired: false, changeCb: (app, id) => {}, @@ -307,6 +308,7 @@ class SettingsStorage { this.autosaveInterval = "two_minutes"; this.alwaysMultiplace = false; + this.shapeTooltipAlwaysOn = false; this.offerHints = true; this.enableTunnelSmartplace = true; this.vignette = true; @@ -536,7 +538,7 @@ export class ApplicationSettings extends ReadWriteProxy { } getCurrentVersion() { - return 30; + return 31; } /** @param {{settings: SettingsStorage, version: number}} data */ @@ -683,6 +685,11 @@ export class ApplicationSettings extends ReadWriteProxy { data.version = 30; } + if (data.version < 31) { + data.settings.shapeTooltipAlwaysOn = false; + data.version = 31; + } + return ExplainedResult.good(); } } diff --git a/src/js/savegame/savegame.js b/src/js/savegame/savegame.js index 999b90ec..36ed884f 100644 --- a/src/js/savegame/savegame.js +++ b/src/js/savegame/savegame.js @@ -64,6 +64,24 @@ export class Savegame extends ReadWriteProxy { return savegameInterfaces[Savegame.getCurrentVersion()]; } + /** + * + * @param {Application} app + * @returns + */ + static createPuzzleSavegame(app) { + return new Savegame(app, { + internalId: "puzzle", + metaDataRef: { + internalId: "puzzle", + lastUpdate: 0, + version: 0, + level: 0, + name: "puzzle", + }, + }); + } + /** * @returns {number} */ diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index 21a32211..1572beaf 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -17,6 +17,7 @@ import { waitNextFrame, } from "../core/utils"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; +import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper"; import { PlatformWrapperImplElectron } from "../platform/electron/wrapper"; import { getApplicationSettingById } from "../profile/application_settings"; import { T } from "../translations"; @@ -34,35 +35,57 @@ export class MainMenuState extends GameState { } getInnerHTML() { + const showLanguageIcon = !G_CHINA_VERSION && !G_WEGAME_VERSION; + const showExitAppButton = G_IS_STANDALONE; + const showUpdateLabel = !G_WEGAME_VERSION; + const showBrowserWarning = !G_IS_STANDALONE && !isSupportedBrowser(); + const showPuzzleDLC = !G_WEGAME_VERSION && (G_IS_STANDALONE || G_IS_DEV); + const showWegameFooter = G_WEGAME_VERSION; + + let showExternalLinks = true; + + if (G_IS_STANDALONE) { + if (G_WEGAME_VERSION || G_CHINA_VERSION) { + showExternalLinks = false; + } + } else { + const wrapper = /** @type {PlatformWrapperImplBrowser} */ (this.app.platformWrapper); + if (!wrapper.embedProvider.externalLinks) { + showExternalLinks = false; + } + } + + let showDiscordLink = showExternalLinks; + if (G_CHINA_VERSION) { + showDiscordLink = true; + } + + const showCrosspromo = !G_IS_STANDALONE && showExternalLinks; + const showDemoAdvertisement = + showExternalLinks && this.app.restrictionMgr.getIsStandaloneMarketingActive(); + + const ownsPuzzleDLC = + G_IS_DEV || + (G_IS_STANDALONE && + /** @type { PlatformWrapperImplElectron}*/ (this.app.platformWrapper).dlcs.puzzle); + const bannerHtml = `

${T.demoBanners.title}

${T.demoBanners.intro}

- Get the shapez.io standalone! + + Get the shapez.io standalone! `; - const showDemoBadges = this.app.restrictionMgr.getIsStandaloneMarketingActive(); - - const puzzleDlc = - G_IS_STANDALONE && - /** @type { PlatformWrapperImplElectron - }*/ (this.app.platformWrapper).dlcs.puzzle; - return `
${ - G_CHINA_VERSION || G_WEGAME_VERSION - ? "" - : `` + showLanguageIcon + ? `` + : "" } - ${ - G_IS_STANDALONE || G_IS_DEV - ? ` - - ` - : "" - } + ${showExitAppButton ? `` : ""}