diff --git a/www/package.json b/www/package.json index 26d2871..e860f45 100644 --- a/www/package.json +++ b/www/package.json @@ -46,10 +46,15 @@ "ace-code": "^1.32.7", "ace-linters": "^1.1.1", "bootstrap": "^5.3.3", + "bson": "^6.5.0", + "buffer": "^6.0.3", + "crypto-browserify": "^3.12.0", "ic10emu_wasm": "file:../ic10emu_wasm/pkg", "ic10lsp_wasm": "file:../ic10lsp_wasm/pkg", "jquery": "^3.7.1", "lzma-web": "^3.0.1", - "uuid": "^9.0.1" + "stream-browserify": "^3.0.0", + "uuid": "^9.0.1", + "vm-browserify": "^1.1.2" } } diff --git a/www/pnpm-lock.yaml b/www/pnpm-lock.yaml index cc71ae7..9e0b77a 100644 --- a/www/pnpm-lock.yaml +++ b/www/pnpm-lock.yaml @@ -17,6 +17,15 @@ dependencies: bootstrap: specifier: ^5.3.3 version: 5.3.3(@popperjs/core@2.11.8) + bson: + specifier: ^6.5.0 + version: 6.5.0 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + crypto-browserify: + specifier: ^3.12.0 + version: 3.12.0 ic10emu_wasm: specifier: file:../ic10emu_wasm/pkg version: file:../ic10emu_wasm/pkg @@ -29,9 +38,15 @@ dependencies: lzma-web: specifier: ^3.0.1 version: 3.0.1 + stream-browserify: + specifier: ^3.0.0 + version: 3.0.0 uuid: specifier: ^9.0.1 version: 9.0.1 + vm-browserify: + specifier: ^1.1.2 + version: 1.1.2 devDependencies: '@oneidentity/zstd-js': @@ -709,6 +724,14 @@ packages: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: true + /asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: false + /async@3.2.3: resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==} dev: false @@ -732,6 +755,10 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + /batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} dev: true @@ -742,6 +769,14 @@ packages: requiresBuild: true dev: true + /bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: false + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: false + /body-parser@1.20.2: resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -802,6 +837,61 @@ packages: fill-range: 7.0.1 dev: true + /brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + dev: false + + /browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + + /browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + dev: false + + /browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + dependencies: + cipher-base: 1.0.4 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + + /browserify-rsa@4.1.0: + resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + dev: false + + /browserify-sign@4.2.3: + resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} + engines: {node: '>= 0.12'} + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.5 + hash-base: 3.0.4 + inherits: 2.0.4 + parse-asn1: 5.1.7 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + dev: false + /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -813,10 +903,26 @@ packages: update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true + /bson@6.5.0: + resolution: {integrity: sha512-DXf1BTAS8vKyR90BO4x5v3rKVarmkdkzwOrnYDFdjAY694ILNDkmA3uRh1xXJEl+C1DAh8XCvAQ+Gh3kzubtpg==} + engines: {node: '>=16.20.1'} + dev: false + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true + /buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} @@ -908,6 +1014,13 @@ packages: engines: {node: '>=6.0'} dev: true + /cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + /clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} @@ -1035,7 +1148,6 @@ packages: /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true /cosmiconfig@9.0.0(typescript@5.4.2): resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} @@ -1053,6 +1165,34 @@ packages: typescript: 5.4.2 dev: true + /create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.5 + dev: false + + /create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + dev: false + + /create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1062,6 +1202,22 @@ packages: which: 2.0.2 dev: true + /crypto-browserify@3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.3 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + dev: false + /css-loader@6.10.0(webpack@5.90.3): resolution: {integrity: sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==} engines: {node: '>= 12.13.0'} @@ -1173,6 +1329,13 @@ packages: engines: {node: '>= 0.8'} dev: true + /des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: false + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -1182,6 +1345,14 @@ packages: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: true + /diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + dev: false + /dns-packet@5.6.1: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} @@ -1241,6 +1412,18 @@ packages: resolution: {integrity: sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==} dev: true + /elliptic@6.5.5: + resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==} + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true @@ -1352,6 +1535,13 @@ packages: engines: {node: '>=0.8.x'} dev: true + /evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + dev: false + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -1636,6 +1826,30 @@ packages: engines: {node: '>= 0.4'} dev: true + /hash-base@3.0.4: + resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==} + engines: {node: '>=4'} + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + + /hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + dev: false + + /hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: false + /hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1652,6 +1866,14 @@ packages: resolution: {integrity: sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w==} dev: true + /hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: false + /hpack.js@2.1.6: resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} dependencies: @@ -1804,6 +2026,10 @@ packages: postcss: 8.4.38 dev: true + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -1943,7 +2169,6 @@ packages: /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2066,6 +2291,14 @@ packages: resolution: {integrity: sha512-sb5cdfd+PLNljK/HUgYzvnz4G7r0GFK8sonyGrqJS0FVyUQjFYcnmU2LqTWFi6r48lH1ZBstnxyLWepKM/t7QA==} dev: false + /md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -2104,6 +2337,14 @@ packages: picomatch: 2.3.1 dev: true + /miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + dev: false + /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -2140,7 +2381,10 @@ packages: /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - dev: true + + /minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + dev: false /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2331,6 +2575,18 @@ packages: callsites: 3.1.0 dev: true + /parse-asn1@5.1.7: + resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} + engines: {node: '>= 0.10'} + dependencies: + asn1.js: 4.10.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + hash-base: 3.0.4 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + dev: false + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -2389,6 +2645,17 @@ packages: engines: {node: '>=12'} dev: true + /pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: false + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true @@ -2499,7 +2766,6 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} @@ -2509,6 +2775,17 @@ packages: ipaddr.js: 1.9.1 dev: true + /public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + parse-asn1: 5.1.7 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: false + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2529,7 +2806,13 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 - dev: true + + /randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: false /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} @@ -2556,7 +2839,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -2565,7 +2847,6 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: true /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} @@ -2654,6 +2935,13 @@ packages: glob: 10.3.10 dev: true + /ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + dev: false + /run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} @@ -2667,11 +2955,9 @@ packages: /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -2826,6 +3112,14 @@ packages: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: true + /sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: false + /shallow-clone@3.0.1: resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} engines: {node: '>=8'} @@ -2946,6 +3240,13 @@ packages: engines: {node: '>= 0.8'} dev: true + /stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2968,13 +3269,11 @@ packages: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 - dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 - dev: true /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -3162,7 +3461,6 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /utila@0.4.0: resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} @@ -3188,6 +3486,10 @@ packages: engines: {node: '>= 0.8'} dev: true + /vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + dev: false + /vscode-css-languageservice@6.2.12: resolution: {integrity: sha512-PS9r7HgNjqzRl3v91sXpCyZPc8UDotNo6gntFNtGCKPhGA9Frk7g/VjX1Mbv3F00pn56D+rxrFzR9ep4cawOgA==} dependencies: diff --git a/www/src/js/editor/index.js b/www/src/js/editor/index.js index b545922..c6a01cc 100644 --- a/www/src/js/editor/index.js +++ b/www/src/js/editor/index.js @@ -8,62 +8,6 @@ import { IC10EditorUI } from './ui.js'; import _ace_ext_langue_tools from "ace-code/src/ext/language_tools"; -const demoCode = `# Highlighting Demo -# This is a comment - -# Hover a define id anywhere to see it's definition -define a_def 10 - -# Hover HASH("String")'s to see computed crc32 -# hover here vvvvvvvvvvvvvvvv -define a_hash HASH("This is a String") - -# hover over an alias anywhere in the code -# to see it's definition -alias a_var r0 -alias a_device d0 - -# instructions have Auto Completion, -# numeric logic types are identified on hover -s db 12 0 -# ^^ -# hover here - -# Enums and their values are Known, Hover them! -# vvvvvvvvvvvvvvvvvv -move r2 LogicType.Temperature - -# same with constants -# vvvv -move r3 pinf - -# Labels are known -main: -l r1 dr15 RatioWater -move r2 100000.001 - -# Hover Hash Strings of Known prefab names -# to get their documentation -# vvvvvvvvvvvvvvv -move r0 HASH("AccessCardBlack") -beqz r1 test - -# -2045627372 is the crc32 hash of a SolarPanel, -# hover it to see the documentation! -# vvvvvvvvvv -move r1 -2045627372 -jal test -move r1 $FF -beqz 0 test -move r1 %1000 -yield -j main - -test: -add r15 r15 1 -j ra - -` async function setupLspWorker() { // Create a web worker let worker = new Worker(new URL('./lspWorker.js', import.meta.url)); @@ -80,8 +24,6 @@ async function setupLspWorker() { function IC10Editor(session_id) { this.mode = new IC10Mode() - - this.settings = { keyboard: "ace", cursor: "ace", @@ -104,11 +46,35 @@ function IC10Editor(session_id) { this.sessions = {}; this.sessions[session_id] = this.editor.getSession(); this.active_session = session_id; - this.editor.session.setValue(demoCode) + this.bindSession(session_id, this.sessions[session_id]); this.languageProvider = null; this.ui = new IC10EditorUI(this); + + const self = this; + + App.session.onLoad((session) => { + const updated_ids = []; + for (const id in session.programs) { + updated_ids.push(id); + self.createOrSetSession(id, session.programs[id]); + } + for (const id in self.sessions) { + if (!updated_ids.includes(id)) { + self.destroySession(id); + } + } + }) + App.session.loadFromFragment(); + +} + +IC10Editor.prototype.createOrSetSession = function(session_id, content) { + if (!this.sessions.hasOwnProperty(session_id)) { + this.newSession(session_id); + } + this.sessions[session_id].setValue(content); } IC10Editor.prototype.newSession = function(session_id) { @@ -116,6 +82,7 @@ IC10Editor.prototype.newSession = function(session_id) { return false; } this.sessions[session_id] = ace.createEditSession("", this.mode); + this.bindSession(session_id, this.sessions[session_id]); } IC10Editor.prototype.setupLsp = function(lsp_worker) { @@ -136,17 +103,19 @@ IC10Editor.prototype.setupLsp = function(lsp_worker) { } -IC10Editor.prototype.activateSession = function (session_id) { +IC10Editor.prototype.activateSession = function(session_id) { if (!this.sessions.hasOwnProperty(session_id)) { return false; } this.editor.setSession(this.sessions[session_id]); let options = this.mode.options ?? {}; - this.languageProvider.setSessionOptions(this.sessions[session_id], options); + if (this.languageProvider !== null) { + this.languageProvider.setSessionOptions(this.sessions[session_id], options); + } return true; } -IC10Editor.prototype.loadEditorSettings = function () { +IC10Editor.prototype.loadEditorSettings = function() { const saved_settings = window.localStorage.getItem("editorSettings"); if (saved_settings !== null && saved_settings.length > 0) { try { @@ -159,7 +128,7 @@ IC10Editor.prototype.loadEditorSettings = function () { } } -IC10Editor.prototype.saveEditorSettings = function () { +IC10Editor.prototype.saveEditorSettings = function() { const toSave = JSON.stringify(this.settings); window.localStorage.setItem("editorSettings", toSave); } @@ -171,9 +140,20 @@ IC10Editor.prototype.destroySession = function(session_id) { if (!(Object.keys(this.sessions).length > 1)) { return false; } - this.sessions[session_id].destroy(); + const session = this.sessions[session_id]; delete this.sessions[session_id]; + if (this.active_session = session_id) { + this.activateSession(Object.keys(this.sessions)[0]); + } + session.destroy(); return true; } +IC10Editor.prototype.bindSession = function(session_id, session) { + session.on('change', () => { + var val = session.getValue(); + window.App.session.setProgramCode(session_id, val); + }); +} + export { IC10Editor, setupLspWorker }; diff --git a/www/src/js/editor/ui.js b/www/src/js/editor/ui.js index 221a29a..a65b2d8 100644 --- a/www/src/js/editor/ui.js +++ b/www/src/js/editor/ui.js @@ -56,37 +56,16 @@ function IC10EditorUI(ic10editor) { console.log(self.ic10editor.editor.getOption('keyboardHandler')); - // let sessionChangeTimeout = 0; - // editor.getSession().on('change', () => { - // if (sessionChangeTimeout) clearTimeout(sessionChangeTimeout); - // sessionChangeTimeout = setTimeout(() => { - // var val = editor.getSession().getValue(); - // setDocFragment(val); - // sessionChangeTimeout = 0; - // }, 1000); - // }); - self.ic10editor.editor.setTheme("ace/theme/one_dark"); ace.config.loadModule("ace/ext/statusbar", function(module) { const statusBar = new module.StatusBar(self.ic10editor.editor, document.getElementById("statusBar")); statusBar.updateStatus(self.ic10editor.editor); }) - // ace_ext_keybinding_menu.init(editor); - // editor.setOption("keyboardHandler", "ace/keyboard/vim"); self.ic10editor.editor.setAutoScrollEditorIntoView(true); - - - - // getContentFromFragment(editor, demoCode); - - // window.addEventListener('hashchange', (_event) => { - // getContentFromFragment(editor, ""); - // }); - } -IC10EditorUI.prototype.updateEditorSettings = function () { +IC10EditorUI.prototype.updateEditorSettings = function() { const settings = this.ic10editor.settings; const editor = this.ic10editor.editor; if (settings.keyboard === 'ace') { @@ -99,7 +78,7 @@ IC10EditorUI.prototype.updateEditorSettings = function () { editor.setOption('relativeLineNumbers', settings.relativeLineNumbers); } -IC10EditorUI.prototype.displayEditorSettings = function () { +IC10EditorUI.prototype.displayEditorSettings = function() { const settings = this.ic10editor.settings; document.getElementsByName("editorKeybindRadio").forEach((el) => { el.checked = el.value === settings.keyboard; @@ -111,7 +90,7 @@ IC10EditorUI.prototype.displayEditorSettings = function () { document.getElementById("editorSettingsRelativeLineNumbers").checked = settings.relativeLineNumbers; } -IC10EditorUI.prototype.reCalcEditorSize = function () { +IC10EditorUI.prototype.reCalcEditorSize = function() { const editor = this.ic10editor.editor; const navBar = document.getElementById("navBar"); const statusBarContainer = document.getElementById("statusBarContainer"); diff --git a/www/src/js/index.js b/www/src/js/index.js index 56765b0..b0eb842 100644 --- a/www/src/js/index.js +++ b/www/src/js/index.js @@ -1,13 +1,11 @@ import { init } from "ic10emu_wasm"; import { IC10Editor, setupLspWorker } from "./editor"; +import { Session } from './session'; const App = { editor: null, - sessions: [], - languageProvider: null, - editorSettings: { - } + session: new Session() }; window.App = App; diff --git a/www/src/js/session.js b/www/src/js/session.js index b585557..eac5738 100644 --- a/www/src/js/session.js +++ b/www/src/js/session.js @@ -1,65 +1,155 @@ +import { BSON } from 'bson'; -async function setDocFragment(content) { - const obj = JSON.stringify({ sessions: [{ content }] }) - const bytes = new TextEncoder().encode(obj); - try { - const c_bytes = await compress(bytes); - const fragment = base64url_encode(c_bytes); - window.history.replaceState(null, "", `#${fragment}`); - } catch (e) { - console.log("Error compressing content fragment:", e); - return; +const demoCode = `# Highlighting Demo +# This is a comment + +# Hover a define id anywhere to see it's definition +define a_def 10 + +# Hover HASH("String")'s to see computed crc32 +# hover here vvvvvvvvvvvvvvvv +define a_hash HASH("This is a String") + +# hover over an alias anywhere in the code +# to see it's definition +alias a_var r0 +alias a_device d0 + +# instructions have Auto Completion, +# numeric logic types are identified on hover +s db 12 0 +# ^^ +# hover here + +# Enums and their values are Known, Hover them! +# vvvvvvvvvvvvvvvvvv +move r2 LogicType.Temperature + +# same with constants +# vvvv +move r3 pinf + +# Labels are known +main: +l r1 dr15 RatioWater +move r2 100000.001 + +# Hover Hash Strings of Known prefab names +# to get their documentation +# vvvvvvvvvvvvvvv +move r0 HASH("AccessCardBlack") +beqz r1 test + +# -2045627372 is the crc32 hash of a SolarPanel, +# hover it to see the documentation! +# vvvvvvvvvv +move r1 -2045627372 +jal test +move r1 $FF +beqz 0 test +move r1 %1000 +yield +j main + +test: +add r15 r15 1 +j ra + +` + +class Session { + constructor() { + this._programs = {}; + this._save_timeout = 0; + this._onLoadCallbacks = []; + this.loadFromFragment(); + + const self = this; + window.addEventListener('hashchange', (_event) => { + self.loadFromFragment(); + }); + } + + get programs() { + return this._programs; + } + + set programs(programs) { + Object.assign(this._programs, programs); + } + + setProgramCode(id, code) { + this._programs[id] = code; + this.save(); + } + + onLoad(callback) { + this._onLoadCallbacks.push(callback); + } + + _fireOnLoad() { + for (const i in this._onLoadCallbacks) { + const callback = this._onLoadCallbacks[i]; + callback(this); + } + } + + save() { + if (this._save_timeout) clearTimeout(this._save_timeout); + this._save_timeout = setTimeout(() => { + this.saveToFragment(); + }, 1000); + } + + async saveToFragment() { + const toSave = { programs: this._programs }; + const bytes = BSON.serialize(toSave); + try { + const c_bytes = await compress(bytes); + const fragment = base64url_encode(c_bytes); + window.history.replaceState(null, "", `#${fragment}`); + } catch (e) { + console.log("Error compressing content fragment:", e); + return; + } + + } + + async loadFromFragment() { + const fragment = window.location.hash.slice(1); + if (fragment === "demo") { + this._programs = { 0: demoCode }; + this._fireOnLoad(); + return; + } + if (fragment.length > 0) { + const c_bytes = base64url_decode(fragment); + const bytes = await decompressFragment(c_bytes); + if (bytes !== null) { + const data = BSON.deserialize(bytes); + try { + this._programs = Object.assign({}, data.programs); + this._fireOnLoad(); + return; + } catch (e) { + console.log("Bad session data:", e); + } + } + } } } - -async function decompressFragment(c_bytes) { + async function decompressFragment(c_bytes) { try { const bytes = await decompress(c_bytes); - const content = new TextDecoder().decode(bytes); - return content; + return bytes; } catch (e) { console.log("Error decompressing content fragment:", e); return null; } } -function isJsonContent(content) { - try { - const obj = JSON.parse(content); - return [true, obj]; - } catch (_) { - return [false, null]; - } -} - -async function getContentFromFragment() { - const fragment = window.location.hash.slice(1); - if (fragment.length > 0) { - const c_bytes = base64url_decode(fragment); - const data = await decompressFragment(c_bytes); - if (data !== null) { - const [is_json, session] = isJsonContent(data); - if (is_json) { - try { - const content = session.sessions[0].content - editor.getSession().setValue(content); - return; - } catch (e) { - console.log("Bad session data:", e); - } - } else { - editor.getSession().setValue(data); - return; - } - } - } - - editor.getSession().setValue(default_content); -} - - async function* streamAsyncIterator(stream) { // Get a lock on the stream const reader = stream.getReader(); @@ -122,3 +212,5 @@ async function decompress(bytes) { } return await concatUintArrays(chunks); } + +export { Session }; diff --git a/www/webpack.config.js b/www/webpack.config.js index beaccee..601c2f6 100644 --- a/www/webpack.config.js +++ b/www/webpack.config.js @@ -19,7 +19,7 @@ module.exports = { mode: "development", plugins: [ new CopyWebpackPlugin({ patterns: ['img/*.png', 'img/*/*.png'] }), - new HtmlWebpackPlugin({ template: './src/index.html'}), + new HtmlWebpackPlugin({ template: './src/index.html' }), new miniCssExtractPlugin() ], module: { @@ -63,6 +63,12 @@ module.exports = { }, resolve: { extensions: ['.tsx', '.ts', '.js'], + fallback: { + "crypto": require.resolve("crypto-browserify"), + "buffer": require.resolve("buffer"), + "stream": require.resolve("stream-browserify"), + "vm": require.resolve("vm-browserify"), + }, }, experiments: { asyncWebAssembly: true,