diff --git a/Cargo.lock b/Cargo.lock index 24c9e51db..311fff713 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,30 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" +dependencies = [ + "const-random", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -102,6 +126,17 @@ dependencies = [ "wait-timeout", ] +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "attohttpc" version = "0.27.0" @@ -115,18 +150,70 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -177,6 +264,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chumsky" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4" +dependencies = [ + "ahash", +] + [[package]] name = "ciborium" version = "0.2.2" @@ -292,6 +388,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -378,6 +494,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "difflib" version = "0.4.0" @@ -439,6 +568,19 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -496,6 +638,83 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -517,6 +736,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "glob" version = "0.3.1" @@ -554,6 +779,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -589,6 +823,18 @@ dependencies = [ "itoa", ] +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.5.0" @@ -599,6 +845,20 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "im-rc" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" +dependencies = [ + "bitmaps", + "rand_core", + "rand_xoshiro", + "sized-chunks", + "typenum", + "version_check", +] + [[package]] name = "indexmap" version = "2.2.6" @@ -627,7 +887,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -716,7 +976,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags", + "bitflags 2.6.0", "libc", ] @@ -732,12 +992,35 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lsp-types" +version = "0.94.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" +dependencies = [ + "bitflags 1.3.2", + "serde", + "serde_json", + "serde_repr", + "url", +] + [[package]] name = "memchr" version = "2.7.4" @@ -753,6 +1036,27 @@ dependencies = [ "serde", ] +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -768,7 +1072,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags", + "bitflags 2.6.0", "cfg-if", "libc", ] @@ -889,6 +1193,33 @@ dependencies = [ "quick-xml", ] +[[package]] +name = "numbat-lsp" +version = "0.1.0" +dependencies = [ + "chumsky", + "dashmap", + "dirs", + "env_logger", + "im-rc", + "log", + "numbat", + "ropey", + "serde", + "serde_json", + "tokio", + "tower-lsp", +] + +[[package]] +name = "object" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -907,12 +1238,67 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "plotters" version = "0.3.6" @@ -1053,6 +1439,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + [[package]] name = "rayon" version = "1.10.0" @@ -1073,6 +1468,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" version = "0.4.5" @@ -1128,6 +1532,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ropey" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5" +dependencies = [ + "smallvec", + "str_indices", +] + [[package]] name = "rust-embed" version = "8.4.0" @@ -1163,13 +1577,19 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1213,7 +1633,7 @@ version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" dependencies = [ - "bitflags", + "bitflags 2.6.0", "cfg-if", "clipboard-win", "fd-lock", @@ -1262,6 +1682,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.203" @@ -1293,6 +1719,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.6" @@ -1322,24 +1759,68 @@ dependencies = [ "dirs", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "similar" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "str_indices" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" + [[package]] name = "strfmt" version = "0.2.4" @@ -1414,6 +1895,15 @@ dependencies = [ "syn", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -1439,6 +1929,48 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.8.14" @@ -1473,6 +2005,97 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-lsp" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ba052b54a6627628d9b3c34c176e7eda8359b7da9acd497b9f20998d118508" +dependencies = [ + "async-trait", + "auto_impl", + "bytes", + "dashmap", + "futures", + "httparse", + "lsp-types", + "memchr", + "serde", + "serde_json", + "tokio", + "tokio-util", + "tower", + "tower-lsp-macros", + "tracing", +] + +[[package]] +name = "tower-lsp-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + [[package]] name = "typenum" version = "1.17.0" @@ -1527,6 +2150,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fe3161e2c..994a3d7cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "numbat", "numbat-exchange-rates", "numbat-cli", + "numbat-lsp", ] exclude = [ @@ -12,6 +13,6 @@ exclude = [ ] [profile.release] -lto = true -strip = true -codegen-units = 1 +# lto = true +# strip = true +# codegen-units = 1 diff --git a/numbat-lsp/.cargo/config.toml b/numbat-lsp/.cargo/config.toml new file mode 100644 index 000000000..67f18aace --- /dev/null +++ b/numbat-lsp/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +lint = "clippy --workspace --all-targets -- --deny warnings" diff --git a/numbat-lsp/.gitignore b/numbat-lsp/.gitignore new file mode 100644 index 000000000..32e72ec68 --- /dev/null +++ b/numbat-lsp/.gitignore @@ -0,0 +1,7 @@ +/target +node_modules +out/ +.pnpm-debug.log +*.ast +dist/ +*.vsix \ No newline at end of file diff --git a/numbat-lsp/.vscode/launch.json b/numbat-lsp/.vscode/launch.json new file mode 100644 index 000000000..58583acef --- /dev/null +++ b/numbat-lsp/.vscode/launch.json @@ -0,0 +1,56 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +{ + "version": "0.2.0", + "configurations": [ + { + "type": "extensionHost", + "request": "launch", + "name": "Launch Client", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}" + ], + "outFiles": [ + "${workspaceRoot}/client/out/**/*.js" + ], + "preLaunchTask": { + "type": "npm", + "script": "watch" + }, + "env": { + "SERVER_PATH": "${workspaceRoot}/target/debug/nrs-language-server" + } + }, + // { + // "type": "node", + // "request": "attach", + // "name": "Attach to Server", + // "port": 6009, + // "restart": true, + // "outFiles": ["${workspaceRoot}/server/out/**/*.js"] + // }, + { + "name": "Language Server E2E Test", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}", + "--extensionTestsPath=${workspaceRoot}/client/out/test/index", + "${workspaceRoot}/client/testFixture" + ], + "outFiles": [ + "${workspaceRoot}/client/out/test/**/*.js" + ] + } + ], + "compounds": [ + { + "name": "Client + Server", + "configurations": [ + "Launch Client", + // "Attach to Server" + ] + } + ] +} \ No newline at end of file diff --git a/numbat-lsp/.vscode/settings.json b/numbat-lsp/.vscode/settings.json new file mode 100644 index 000000000..30bf8c2d3 --- /dev/null +++ b/numbat-lsp/.vscode/settings.json @@ -0,0 +1,11 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" +} \ No newline at end of file diff --git a/numbat-lsp/.vscode/tasks.json b/numbat-lsp/.vscode/tasks.json new file mode 100644 index 000000000..442c31d30 --- /dev/null +++ b/numbat-lsp/.vscode/tasks.json @@ -0,0 +1,35 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "compile", + "group": "build", + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc" + ] + }, + { + "type": "npm", + "script": "watch", + "isBackground": true, + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc-watch" + ] + } + ] +} \ No newline at end of file diff --git a/numbat-lsp/.vscodeignore b/numbat-lsp/.vscodeignore new file mode 100644 index 000000000..9a8e830eb --- /dev/null +++ b/numbat-lsp/.vscodeignore @@ -0,0 +1,8 @@ +.vscode +node_modules +out/ +src/ +tsconfig.json +webpack.config.js +client/** +target \ No newline at end of file diff --git a/numbat-lsp/Cargo.toml b/numbat-lsp/Cargo.toml new file mode 100644 index 000000000..18c549e33 --- /dev/null +++ b/numbat-lsp/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "numbat-lsp" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +chumsky = "0.8.0" +env_logger = "0.9.0" +ropey = "1.5.0" +serde_json = "1.0.78" +tokio = { version = "1.17.0", features = ["full"] } +tower-lsp = { version = "0.20.0", features = ["proposed"]} +serde = { version = "1.0", features = ["derive"] } +dashmap = "5.1.0" +dirs = "5" +log = "0.4.14" +im-rc = "15.0.0" +numbat = { path = "../numbat" } + diff --git a/numbat-lsp/LICENSE b/numbat-lsp/LICENSE new file mode 100644 index 000000000..ca0fcdf4d --- /dev/null +++ b/numbat-lsp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 IWANABETHATGUY + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/numbat-lsp/README.md b/numbat-lsp/README.md new file mode 100644 index 000000000..650567821 --- /dev/null +++ b/numbat-lsp/README.md @@ -0,0 +1,84 @@ +# boilerplate for a rust language server powered by `tower-lsp` +## Introduction +This repo is a template for `tower-lsp`, a useful github project template which makes writing new language servers easier. +## Development using VSCode +1. `pnpm i` +2. `cargo build` +3. Open the project in VSCode: `code .` +4. In VSCode, press F5 or change to the Debug panel and click Launch Client. +5. In the newly launched VSCode instance, open the file `examples/test.nrs` from this project. +6. If the LSP is working correctly you should see syntax highlighting and the features described below should work. +> **Note** +> +> If encountered errors like `Cannot find module '/xxx/xxx/dist/extension.js'` +> please try run command `tsc -b` manually, you could refer https://github.com/IWANABETHATGUY/tower-lsp-boilerplate/issues/6 for more details +## A valid program in nano rust +```rust +fn factorial(x) { + // Conditionals are supported! + if x == 0 { + 1 + } else { + x * factorial(x - 1) + } +} + +// The main function +fn main() { + let three = 3; + let meaning_of_life = three * 14 + 1; + + print("Hello, world!"); + print("The meaning of life is..."); + + if meaning_of_life == 42 { + print(meaning_of_life); + } else { + print("...something we cannot know"); + + print("However, I can tell you that the factorial of 10 is..."); + // Function calling + print(factorial(10)); + } +} +``` +## Features +This repo use a language `nano rust` which first introduced by [ chumsky ](https://github.com/zesterer/chumsky/blob/master/examples/nano_rust.rs). Most common language feature has been implemented, you could preview via the video below. + +- [x] InlayHint for LiteralType +![inlay hint](https://user-images.githubusercontent.com/17974631/156926412-c3823dac-664e-430e-96c1-c003a86eabb2.gif) + +- [x] semantic token +make sure your semantic token is enabled, you could enable your `semantic token` by +adding this line to your `settings.json` +```json +{ + "editor.semanticHighlighting.enabled": true, +} +``` +- [x] syntactic error diagnostic + +https://user-images.githubusercontent.com/17974631/156926382-a1c4c911-7ea1-4d3a-8e08-3cf7271da170.mp4 + +- [x] code completion + +https://user-images.githubusercontent.com/17974631/156926355-010ef2cd-1d04-435b-bd1e-8b0dab9f44f1.mp4 + +- [x] go to definition + +https://user-images.githubusercontent.com/17974631/156926103-94d90bd3-f31c-44e7-a2ce-4ddfde89bc33.mp4 + +- [x] find reference + +https://user-images.githubusercontent.com/17974631/157367235-7091a36c-631a-4347-9c1e-a3b78db81714.mp4 + +- [x] rename + +https://user-images.githubusercontent.com/17974631/157367229-99903896-5583-4f67-a6da-1ae1cf206876.mp4 + + + + + + + diff --git a/numbat-lsp/client/package.json b/numbat-lsp/client/package.json new file mode 100644 index 000000000..02b35068e --- /dev/null +++ b/numbat-lsp/client/package.json @@ -0,0 +1,15 @@ +{ + "name": "nrs-language-client", + "description": "VSCode part of a language server", + "license": "MIT", + "version": "0.0.1", + "engines": { + "vscode": "^1.85.0" + }, + "dependencies": {}, + "devDependencies": { + "@types/node": "^17.0.18", + "vscode-test": "^1.3.0", + "@types/vscode": "1.86.0" + } +} diff --git a/numbat-lsp/client/pnpm-lock.yaml b/numbat-lsp/client/pnpm-lock.yaml new file mode 100644 index 000000000..f23a7dbcf --- /dev/null +++ b/numbat-lsp/client/pnpm-lock.yaml @@ -0,0 +1,294 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@types/node': + specifier: ^17.0.18 + version: 17.0.21 + '@types/vscode': + specifier: 1.86.0 + version: 1.86.0 + vscode-test: + specifier: ^1.3.0 + version: 1.6.1 + +packages: + + /@tootallnate/once@1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: true + + /@types/node@17.0.21: + resolution: {integrity: sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==} + dev: true + + /@types/vscode@1.86.0: + resolution: {integrity: sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==} + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + + /binary@0.3.0: + resolution: {integrity: sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=} + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + dev: true + + /bluebird@3.4.7: + resolution: {integrity: sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + dev: true + + /buffers@0.1.1: + resolution: {integrity: sha1-skV5w77U1tOWru5tmorn9Ugqt7s=} + engines: {node: '>=0.2.0'} + dev: true + + /chainsaw@0.1.0: + resolution: {integrity: sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=} + dependencies: + traverse: 0.3.9 + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=} + dependencies: + readable-stream: 2.3.7 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + dev: true + + /fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + dependencies: + graceful-fs: 4.2.9 + inherits: 2.0.4 + mkdirp: 0.5.5 + rimraf: 2.7.1 + dev: true + + /glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /graceful-fs@4.2.9: + resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} + dev: true + + /http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@5.0.0: + resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} + dev: true + + /listenercount@1.0.1: + resolution: {integrity: sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist@1.2.5: + resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} + dev: true + + /mkdirp@0.5.5: + resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /once@1.4.0: + resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + dependencies: + wrappy: 1.0.2 + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} + engines: {node: '>=0.10.0'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /setimmediate@1.0.5: + resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=} + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /traverse@0.3.9: + resolution: {integrity: sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=} + dev: true + + /unzipper@0.10.11: + resolution: {integrity: sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==} + dependencies: + big-integer: 1.6.51 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.9 + listenercount: 1.0.1 + readable-stream: 2.3.7 + setimmediate: 1.0.5 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} + dev: true + + /vscode-test@1.6.1: + resolution: {integrity: sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==} + engines: {node: '>=8.9.3'} + deprecated: This package has been renamed to @vscode/test-electron, please update to the new name + dependencies: + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.0 + rimraf: 3.0.2 + unzipper: 0.10.11 + transitivePeerDependencies: + - supports-color + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + dev: true diff --git a/numbat-lsp/client/src/extension.ts b/numbat-lsp/client/src/extension.ts new file mode 100644 index 000000000..04c8f4ebf --- /dev/null +++ b/numbat-lsp/client/src/extension.ts @@ -0,0 +1,172 @@ +/* -------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + * ------------------------------------------------------------------------------------------ */ + +import { + languages, + workspace, + EventEmitter, + ExtensionContext, + window, + InlayHintsProvider, + TextDocument, + CancellationToken, + Range, + InlayHint, + TextDocumentChangeEvent, + ProviderResult, + commands, + WorkspaceEdit, + TextEdit, + Selection, + Uri, +} from "vscode"; + +import { + Disposable, + Executable, + LanguageClient, + LanguageClientOptions, + ServerOptions, +} from "vscode-languageclient/node"; + +let client: LanguageClient; +// type a = Parameters<>; + +export async function activate(context: ExtensionContext) { + let disposable = commands.registerCommand("helloworld.helloWorld", async uri => { + // The code you place here will be executed every time your command is executed + // Display a message box to the user + const url = Uri.parse('/home/victor/Documents/test-dir/nrs/another.nrs') + let document = await workspace.openTextDocument(uri); + await window.showTextDocument(document); + + // console.log(uri) + window.activeTextEditor.document + let editor = window.activeTextEditor; + let range = new Range(1, 1, 1, 1) + editor.selection = new Selection(range.start, range.end); + }); + + context.subscriptions.push(disposable); + + const traceOutputChannel = window.createOutputChannel("Nrs Language Server trace"); + const command = process.env.SERVER_PATH || "nrs-language-server"; + const run: Executable = { + command, + options: { + env: { + ...process.env, + // eslint-disable-next-line @typescript-eslint/naming-convention + RUST_LOG: "debug", + }, + }, + }; + const serverOptions: ServerOptions = { + run, + debug: run, + }; + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + // Options to control the language client + let clientOptions: LanguageClientOptions = { + // Register the server for plain text documents + documentSelector: [{ scheme: "file", language: "nrs" }], + synchronize: { + // Notify the server about file changes to '.clientrc files contained in the workspace + fileEvents: workspace.createFileSystemWatcher("**/.clientrc"), + }, + traceOutputChannel, + }; + + // Create the language client and start the client. + client = new LanguageClient("nrs-language-server", "nrs language server", serverOptions, clientOptions); + // activateInlayHints(context); + client.start(); +} + +export function deactivate(): Thenable | undefined { + if (!client) { + return undefined; + } + return client.stop(); +} + +export function activateInlayHints(ctx: ExtensionContext) { + const maybeUpdater = { + hintsProvider: null as Disposable | null, + updateHintsEventEmitter: new EventEmitter(), + + async onConfigChange() { + this.dispose(); + + const event = this.updateHintsEventEmitter.event; + // this.hintsProvider = languages.registerInlayHintsProvider( + // { scheme: "file", language: "nrs" }, + // // new (class implements InlayHintsProvider { + // // onDidChangeInlayHints = event; + // // resolveInlayHint(hint: InlayHint, token: CancellationToken): ProviderResult { + // // const ret = { + // // label: hint.label, + // // ...hint, + // // }; + // // return ret; + // // } + // // async provideInlayHints( + // // document: TextDocument, + // // range: Range, + // // token: CancellationToken + // // ): Promise { + // // const hints = (await client + // // .sendRequest("custom/inlay_hint", { path: document.uri.toString() }) + // // .catch(err => null)) as [number, number, string][]; + // // if (hints == null) { + // // return []; + // // } else { + // // return hints.map(item => { + // // const [start, end, label] = item; + // // let startPosition = document.positionAt(start); + // // let endPosition = document.positionAt(end); + // // return { + // // position: endPosition, + // // paddingLeft: true, + // // label: [ + // // { + // // value: `${label}`, + // // // location: { + // // // uri: document.uri, + // // // range: new Range(1, 0, 1, 0) + // // // } + // // command: { + // // title: "hello world", + // // command: "helloworld.helloWorld", + // // arguments: [document.uri], + // // }, + // // }, + // // ], + // // }; + // // }); + // // } + // // } + // // })() + // ); + }, + + onDidChangeTextDocument({ contentChanges, document }: TextDocumentChangeEvent) { + // debugger + // this.updateHintsEventEmitter.fire(); + }, + + dispose() { + this.hintsProvider?.dispose(); + this.hintsProvider = null; + this.updateHintsEventEmitter.dispose(); + }, + }; + + workspace.onDidChangeConfiguration(maybeUpdater.onConfigChange, maybeUpdater, ctx.subscriptions); + workspace.onDidChangeTextDocument(maybeUpdater.onDidChangeTextDocument, maybeUpdater, ctx.subscriptions); + + maybeUpdater.onConfigChange().catch(console.error); +} diff --git a/numbat-lsp/client/tsconfig.json b/numbat-lsp/client/tsconfig.json new file mode 100644 index 000000000..0d3e0cb72 --- /dev/null +++ b/numbat-lsp/client/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2019", + "lib": ["ES2019"], + "outDir": "../dist", + "rootDir": "src", + "sourceMap": true + }, + "include": ["src"], + "exclude": ["node_modules", ".vscode-test"] +} diff --git a/numbat-lsp/package.json b/numbat-lsp/package.json new file mode 100644 index 000000000..e002bf930 --- /dev/null +++ b/numbat-lsp/package.json @@ -0,0 +1,86 @@ +{ + "name": "nrs-language-server", + "description": "nano rust language server", + "license": "MIT", + "version": "1.5.0", + "categories": [], + "keywords": [ + "language-server", + "tower-lsp" + ], + "repository": { + "url": "https://github.com/IWANABETHATGUY/tower-lsp-boilerplate" + }, + "engines": { + "vscode": "^1.66.0" + }, + "enabledApiProposals": [], + "activationEvents": [ + "onLanguage:nrs" + ], + "main": "./dist/extension.js", + "contributes": { + "languages": [ + { + "id": "nrs", + "extensions": [ + ".nrs" + ] + } + ], + "configuration": { + "type": "object", + "title": "nrs-language-server", + "properties": { + "nrs-language-server.trace.server": { + "type": "string", + "scope": "window", + "enum": [ + "off", + "messages", + "verbose" + ], + "enumDescriptions": [ + "No traces", + "Error only", + "Full log" + ], + "default": "off", + "description": "Traces the communication between VS Code and the language server." + } + } + } + }, + "scripts": { + "postinstall": "cd client && pnpm i", + "vscode:prepublish": "npm run esbuild-base -- --minify", + "test-compile": "tsc -p ./", + "compile": "cross-env NODE_ENV=production tsc -b", + "watch": "rm -rf dist && tsc -b -w", + "lint": "eslint src --ext ts", + "pretest": "npm run compile && npm run lint", + "test": "node ./out/test/runTest.js", + "build": "webpack --config webpack.config.js", + "package": "vsce package --no-dependencies", + "publish": "vsce publish --no-dependencies" + }, + "devDependencies": { + "@types/glob": "^7.1.3", + "@types/mocha": "^8.0.0", + "@types/node": "^12.12.0", + "@typescript-eslint/eslint-plugin": "^3.8.0", + "@typescript-eslint/parser": "^3.8.0", + "cross-env": "^7.0.2", + "electron-rebuild": "^1.11.0", + "eslint": "^7.6.0", + "glob": "^7.1.7", + "mocha": "^8.0.1", + "typescript": "5.4.5", + "vscode-test": "^1.4.0", + "vscode-uri": "^3.0.2", + "webpack": "^5.82.1" + }, + "dependencies": { + "vscode-languageclient": "9.0.1" + } +} diff --git a/numbat-lsp/pnpm-lock.yaml b/numbat-lsp/pnpm-lock.yaml new file mode 100644 index 000000000..6053352c0 --- /dev/null +++ b/numbat-lsp/pnpm-lock.yaml @@ -0,0 +1,2715 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + vscode-languageclient: + specifier: 9.0.1 + version: 9.0.1 + +devDependencies: + '@types/glob': + specifier: ^7.1.3 + version: 7.2.0 + '@types/mocha': + specifier: ^8.0.0 + version: 8.2.3 + '@types/node': + specifier: ^12.12.0 + version: 12.20.47 + '@typescript-eslint/eslint-plugin': + specifier: ^3.8.0 + version: 3.10.1(@typescript-eslint/parser@3.10.1)(eslint@7.32.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^3.8.0 + version: 3.10.1(eslint@7.32.0)(typescript@5.4.5) + cross-env: + specifier: ^7.0.2 + version: 7.0.3 + electron-rebuild: + specifier: ^1.11.0 + version: 1.11.0 + eslint: + specifier: ^7.6.0 + version: 7.32.0 + glob: + specifier: ^7.1.7 + version: 7.2.0 + mocha: + specifier: ^8.0.1 + version: 8.4.0 + typescript: + specifier: 5.4.5 + version: 5.4.5 + vscode-test: + specifier: ^1.4.0 + version: 1.6.1 + vscode-uri: + specifier: ^3.0.2 + version: 3.0.3 + webpack: + specifier: ^5.82.1 + version: 5.82.1 + +packages: + + /@babel/code-frame@7.12.11: + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} + dependencies: + '@babel/highlight': 7.16.10 + dev: true + + /@babel/helper-validator-identifier@7.16.7: + resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/highlight@7.16.10: + resolution: {integrity: sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@eslint/eslintrc@0.4.3: + resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.3 + espree: 7.3.1 + globals: 13.12.1 + ignore: 4.0.6 + import-fresh: 3.3.0 + js-yaml: 3.14.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/config-array@0.5.0: + resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.3: + resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@jridgewell/sourcemap-codec@1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@tootallnate/once@1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: true + + /@types/eslint-scope@3.7.4: + resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} + dependencies: + '@types/eslint': 8.37.0 + '@types/estree': 1.0.1 + dev: true + + /@types/eslint-visitor-keys@1.0.0: + resolution: {integrity: sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==} + dev: true + + /@types/eslint@8.37.0: + resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==} + dependencies: + '@types/estree': 1.0.1 + '@types/json-schema': 7.0.9 + dev: true + + /@types/estree@1.0.1: + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + dev: true + + /@types/glob@7.2.0: + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + dependencies: + '@types/minimatch': 3.0.5 + '@types/node': 12.20.47 + dev: true + + /@types/json-schema@7.0.9: + resolution: {integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==} + dev: true + + /@types/minimatch@3.0.5: + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + dev: true + + /@types/mocha@8.2.3: + resolution: {integrity: sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==} + dev: true + + /@types/node@12.20.47: + resolution: {integrity: sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==} + dev: true + + /@typescript-eslint/eslint-plugin@3.10.1(@typescript-eslint/parser@3.10.1)(eslint@7.32.0)(typescript@5.4.5): + resolution: {integrity: sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + '@typescript-eslint/parser': ^3.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/experimental-utils': 3.10.1(eslint@7.32.0)(typescript@5.4.5) + '@typescript-eslint/parser': 3.10.1(eslint@7.32.0)(typescript@5.4.5) + debug: 4.3.3 + eslint: 7.32.0 + functional-red-black-tree: 1.0.1 + regexpp: 3.2.0 + semver: 7.3.5 + tsutils: 3.21.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/experimental-utils@3.10.1(eslint@7.32.0)(typescript@5.4.5): + resolution: {integrity: sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: '*' + dependencies: + '@types/json-schema': 7.0.9 + '@typescript-eslint/types': 3.10.1 + '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.4.5) + eslint: 7.32.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/parser@3.10.1(eslint@7.32.0)(typescript@5.4.5): + resolution: {integrity: sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@types/eslint-visitor-keys': 1.0.0 + '@typescript-eslint/experimental-utils': 3.10.1(eslint@7.32.0)(typescript@5.4.5) + '@typescript-eslint/types': 3.10.1 + '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.4.5) + eslint: 7.32.0 + eslint-visitor-keys: 1.3.0 + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@3.10.1: + resolution: {integrity: sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dev: true + + /@typescript-eslint/typescript-estree@3.10.1(typescript@5.4.5): + resolution: {integrity: sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 3.10.1 + '@typescript-eslint/visitor-keys': 3.10.1 + debug: 4.3.3 + glob: 7.2.0 + is-glob: 4.0.3 + lodash: 4.17.21 + semver: 7.3.8 + tsutils: 3.21.0(typescript@5.4.5) + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys@3.10.1: + resolution: {integrity: sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /@ungap/promise-all-settled@1.1.2: + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + dev: true + + /@webassemblyjs/ast@1.11.6: + resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + dev: true + + /@webassemblyjs/floating-point-hex-parser@1.11.6: + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + dev: true + + /@webassemblyjs/helper-api-error@1.11.6: + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + dev: true + + /@webassemblyjs/helper-buffer@1.11.6: + resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} + dev: true + + /@webassemblyjs/helper-numbers@1.11.6: + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode@1.11.6: + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + dev: true + + /@webassemblyjs/helper-wasm-section@1.11.6: + resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + dev: true + + /@webassemblyjs/ieee754@1.11.6: + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128@1.11.6: + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8@1.11.6: + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + dev: true + + /@webassemblyjs/wasm-edit@1.11.6: + resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-opt': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + '@webassemblyjs/wast-printer': 1.11.6 + dev: true + + /@webassemblyjs/wasm-gen@1.11.6: + resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wasm-opt@1.11.6: + resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + dev: true + + /@webassemblyjs/wasm-parser@1.11.6: + resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + dev: true + + /@webassemblyjs/wast-printer@1.11.6: + resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@xtuc/long': 4.2.2 + dev: true + + /@xtuc/ieee754@1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long@4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /acorn-import-assertions@1.9.0(acorn@8.8.2): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.8.2 + dev: true + + /acorn-jsx@5.3.2(acorn@7.4.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 7.4.1 + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /ajv-keywords@3.5.2(ajv@6.12.6): + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.10.0: + resolution: {integrity: sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + dev: true + + /ansi-regex@2.1.1: + resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=} + engines: {node: '>=0.10.0'} + dev: true + + /ansi-regex@3.0.0: + resolution: {integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=} + engines: {node: '>=4'} + dev: true + + /ansi-regex@4.1.0: + resolution: {integrity: sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==} + engines: {node: '>=6'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch@3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + dev: true + + /are-we-there-yet@1.1.7: + resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==} + dependencies: + delegates: 1.0.0 + readable-stream: 2.3.7 + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=} + engines: {node: '>=0.8'} + dev: true + + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + dev: true + + /aws-sign2@0.7.0: + resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=} + dev: true + + /aws4@1.11.0: + resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=} + dependencies: + tweetnacl: 0.14.5 + dev: true + + /big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /binary@0.3.0: + resolution: {integrity: sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=} + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + dev: true + + /bluebird@3.4.7: + resolution: {integrity: sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true + + /browserslist@4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001486 + electron-to-chromium: 1.4.392 + node-releases: 2.0.10 + update-browserslist-db: 1.0.11(browserslist@4.21.5) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + dev: true + + /buffers@0.1.1: + resolution: {integrity: sha1-skV5w77U1tOWru5tmorn9Ugqt7s=} + engines: {node: '>=0.2.0'} + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001486: + resolution: {integrity: sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==} + dev: true + + /caseless@0.12.0: + resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=} + dev: true + + /chainsaw@0.1.0: + resolution: {integrity: sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=} + dependencies: + traverse: 0.3.9 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chokidar@3.5.1: + resolution: {integrity: sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.5.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chrome-trace-event@1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + dev: true + + /cli-cursor@2.1.0: + resolution: {integrity: sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=} + engines: {node: '>=4'} + dependencies: + restore-cursor: 2.0.0 + dev: true + + /cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + dev: true + + /cliui@5.0.0: + resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + dependencies: + string-width: 3.1.0 + strip-ansi: 5.2.0 + wrap-ansi: 5.1.0 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=} + engines: {node: '>=0.8'} + dev: true + + /code-point-at@1.1.0: + resolution: {integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=} + engines: {node: '>=0.10.0'} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=} + dev: true + + /core-util-is@1.0.2: + resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /dashdash@1.14.1: + resolution: {integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@4.3.1(supports-color@8.1.1): + resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 8.1.1 + dev: true + + /debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} + engines: {node: '>=0.10.0'} + dev: true + + /decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /defaults@1.0.3: + resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=} + dependencies: + clone: 1.0.4 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} + engines: {node: '>=0.4.0'} + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + dev: true + + /detect-libc@1.0.3: + resolution: {integrity: sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=} + dependencies: + readable-stream: 2.3.7 + dev: true + + /ecc-jsbn@0.1.2: + resolution: {integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + + /electron-rebuild@1.11.0: + resolution: {integrity: sha512-cn6AqZBQBVtaEyj5jZW1/LOezZZ22PA1HvhEP7asvYPJ8PDF4i4UFt9be4i9T7xJKiSiomXvY5Fd+dSq3FXZxA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + colors: 1.4.0 + debug: 4.3.3 + detect-libc: 1.0.3 + fs-extra: 8.1.0 + node-abi: 2.30.1 + node-gyp: 6.1.0 + ora: 3.4.0 + spawn-rx: 3.0.0 + yargs: 14.2.3 + transitivePeerDependencies: + - supports-color + dev: true + + /electron-to-chromium@1.4.392: + resolution: {integrity: sha512-TXQOMW9tnhIms3jGy/lJctLjICOgyueZFJ1KUtm6DTQ+QpxX3p7ZBwB6syuZ9KBuT5S4XX7bgY1ECPgfxKUdOg==} + dev: true + + /emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /enhanced-resolve@5.14.0: + resolution: {integrity: sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.9 + tapable: 2.2.1 + dev: true + + /enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.1 + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /es-module-lexer@1.2.1: + resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==} + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint@7.32.0: + resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} + engines: {node: ^10.12.0 || >=12.0.0} + hasBin: true + dependencies: + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.3 + '@humanwhocodes/config-array': 0.5.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.3 + doctrine: 3.0.0 + enquirer: 2.3.6 + escape-string-regexp: 4.0.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 13.12.1 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.3.5 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 6.8.0 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.4.0: + resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=} + engines: {'0': node >=0.6.0} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.5 + rimraf: 3.0.2 + dev: true + + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + + /flatted@3.2.5: + resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} + dev: true + + /forever-agent@0.6.1: + resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=} + dev: true + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.34 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.9 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-minipass@1.2.7: + resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} + dependencies: + minipass: 2.9.0 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + dependencies: + graceful-fs: 4.2.9 + inherits: 2.0.4 + mkdirp: 0.5.5 + rimraf: 2.7.1 + dev: true + + /functional-red-black-tree@1.0.1: + resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} + dev: true + + /gauge@2.7.4: + resolution: {integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=} + dependencies: + aproba: 1.2.0 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 1.0.2 + strip-ansi: 3.0.1 + wide-align: 1.1.5 + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=} + dependencies: + assert-plus: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@13.12.1: + resolution: {integrity: sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + requiresBuild: true + dev: true + optional: true + + /graceful-fs@4.2.9: + resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} + dev: true + + /growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + dev: true + + /har-schema@2.0.0: + resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=} + engines: {node: '>=4'} + dev: true + + /har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=} + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /http-signature@1.2.0: + resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.17.0 + dev: true + + /https-proxy-agent@5.0.0: + resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=} + engines: {node: '>=0.10.0'} + dependencies: + number-is-nan: 1.0.1 + dev: true + + /is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=} + engines: {node: '>=4'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} + dev: true + + /isstream@0.1.2: + resolution: {integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=} + dev: true + + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 12.20.47 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml@4.0.0: + resolution: {integrity: sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsbn@0.1.1: + resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=} + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /listenercount@1.0.1: + resolution: {integrity: sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=} + dev: true + + /loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + dev: true + + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.assign@4.2.0: + resolution: {integrity: sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.truncate@4.4.2: + resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@2.2.0: + resolution: {integrity: sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==} + engines: {node: '>=4'} + dependencies: + chalk: 2.4.2 + dev: true + + /log-symbols@4.0.0: + resolution: {integrity: sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /mime-db@1.51.0: + resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.34: + resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.51.0 + dev: true + + /mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minimist@1.2.5: + resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} + dev: true + + /minipass@2.9.0: + resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + dependencies: + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: true + + /minizlib@1.3.3: + resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} + dependencies: + minipass: 2.9.0 + dev: true + + /mkdirp@0.5.5: + resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /mocha@8.4.0: + resolution: {integrity: sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==} + engines: {node: '>= 10.12.0'} + hasBin: true + dependencies: + '@ungap/promise-all-settled': 1.1.2 + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.1 + debug: 4.3.1(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.1.6 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 4.0.0 + log-symbols: 4.0.0 + minimatch: 3.0.4 + ms: 2.1.3 + nanoid: 3.1.20 + serialize-javascript: 5.0.1 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + which: 2.0.2 + wide-align: 1.1.3 + workerpool: 6.1.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + dev: true + + /ms@2.0.0: + resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nanoid@3.1.20: + resolution: {integrity: sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /node-abi@2.30.1: + resolution: {integrity: sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==} + dependencies: + semver: 5.7.1 + dev: true + + /node-gyp@6.1.0: + resolution: {integrity: sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==} + engines: {node: '>= 6.0.0'} + hasBin: true + dependencies: + env-paths: 2.2.1 + glob: 7.2.0 + graceful-fs: 4.2.9 + mkdirp: 0.5.5 + nopt: 4.0.3 + npmlog: 4.1.2 + request: 2.88.2 + rimraf: 2.7.1 + semver: 5.7.1 + tar: 4.4.19 + which: 1.3.1 + dev: true + + /node-releases@2.0.10: + resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + dev: true + + /nopt@4.0.3: + resolution: {integrity: sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==} + hasBin: true + dependencies: + abbrev: 1.1.1 + osenv: 0.1.5 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npmlog@4.1.2: + resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==} + dependencies: + are-we-there-yet: 1.1.7 + console-control-strings: 1.1.0 + gauge: 2.7.4 + set-blocking: 2.0.0 + dev: true + + /number-is-nan@1.0.1: + resolution: {integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=} + engines: {node: '>=0.10.0'} + dev: true + + /oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} + engines: {node: '>=0.10.0'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@2.0.1: + resolution: {integrity: sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=} + engines: {node: '>=4'} + dependencies: + mimic-fn: 1.2.0 + dev: true + + /optionator@0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /ora@3.4.0: + resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} + engines: {node: '>=6'} + dependencies: + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-spinners: 2.6.1 + log-symbols: 2.2.0 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + dev: true + + /os-homedir@1.0.2: + resolution: {integrity: sha1-/7xJiDNuDoM94MFox+8VISGqf7M=} + engines: {node: '>=0.10.0'} + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=} + engines: {node: '>=0.10.0'} + dev: true + + /osenv@0.1.5: + resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /performance-now@2.1.0: + resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: true + + /psl@1.8.0: + resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} + dev: true + + /punycode@2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readdirp@3.5.0: + resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.11.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.34 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} + engines: {node: '>=0.10.0'} + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /restore-cursor@2.0.0: + resolution: {integrity: sha1-n37ih/gv0ybU/RYpI9YhKe7g368=} + engines: {node: '>=4'} + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + dependencies: + tslib: 1.14.1 + dev: true + + /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==} + dev: true + + /schema-utils@3.1.2: + resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.9 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + dev: true + + /semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver@7.3.5: + resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /semver@7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + + /serialize-javascript@5.0.1: + resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serialize-javascript@6.0.1: + resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} + dependencies: + randombytes: 2.1.0 + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} + dev: true + + /setimmediate@1.0.5: + resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=} + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /spawn-rx@3.0.0: + resolution: {integrity: sha512-dw4Ryg/KMNfkKa5ezAR5aZe9wNwPdKlnHEXtHOjVnyEDSPQyOpIPPRtcIiu7127SmtHhaCjw21yC43HliW0iIg==} + dependencies: + debug: 2.6.9 + lodash.assign: 4.2.0 + rxjs: 6.6.7 + transitivePeerDependencies: + - supports-color + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} + dev: true + + /sshpk@1.17.0: + resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + + /string-width@1.0.2: + resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=} + engines: {node: '>=0.10.0'} + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + dev: true + + /string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: true + + /string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /strip-ansi@3.0.1: + resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=} + engines: {node: '>=0.10.0'} + dependencies: + ansi-regex: 2.1.1 + dev: true + + /strip-ansi@4.0.0: + resolution: {integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8=} + engines: {node: '>=4'} + dependencies: + ansi-regex: 3.0.0 + dev: true + + /strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /table@6.8.0: + resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.10.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + dev: true + + /tar@4.4.19: + resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} + engines: {node: '>=4.5'} + dependencies: + chownr: 1.1.4 + fs-minipass: 1.2.7 + minipass: 2.9.0 + minizlib: 1.3.3 + mkdirp: 0.5.5 + safe-buffer: 5.2.1 + yallist: 3.1.1 + dev: true + + /terser-webpack-plugin@5.3.8(webpack@5.82.1): + resolution: {integrity: sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.18 + jest-worker: 27.5.1 + schema-utils: 3.1.2 + serialize-javascript: 6.0.1 + terser: 5.17.3 + webpack: 5.82.1 + dev: true + + /terser@5.17.3: + resolution: {integrity: sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.3 + acorn: 8.8.2 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.8.0 + punycode: 2.1.1 + dev: true + + /traverse@0.3.9: + resolution: {integrity: sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=} + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tsutils@3.21.0(typescript@5.4.5): + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 5.4.5 + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /tweetnacl@0.14.5: + resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=} + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /unzipper@0.10.11: + resolution: {integrity: sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==} + dependencies: + big-integer: 1.6.51 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.9 + listenercount: 1.0.1 + readable-stream: 2.3.7 + setimmediate: 1.0.5 + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.5): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} + dev: true + + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: true + + /v8-compile-cache@2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + dev: true + + /verror@1.10.0: + resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + dev: false + + /vscode-languageclient@9.0.1: + resolution: {integrity: sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==} + engines: {vscode: ^1.82.0} + dependencies: + minimatch: 5.1.6 + semver: 7.3.8 + vscode-languageserver-protocol: 3.17.5 + dev: false + + /vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + dev: false + + /vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + dev: false + + /vscode-test@1.6.1: + resolution: {integrity: sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA==} + engines: {node: '>=8.9.3'} + deprecated: This package has been renamed to @vscode/test-electron, please update to the new name + dependencies: + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.0 + rimraf: 3.0.2 + unzipper: 0.10.11 + transitivePeerDependencies: + - supports-color + dev: true + + /vscode-uri@3.0.3: + resolution: {integrity: sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==} + dev: true + + /watchpack@2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.9 + dev: true + + /wcwidth@1.0.1: + resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=} + dependencies: + defaults: 1.0.3 + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack@5.82.1: + resolution: {integrity: sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 1.0.1 + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/wasm-edit': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + acorn: 8.8.2 + acorn-import-assertions: 1.9.0(acorn@8.8.2) + browserslist: 4.21.5 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.14.0 + es-module-lexer: 1.2.1 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.9 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.34 + neo-async: 2.6.2 + schema-utils: 3.1.2 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.8(webpack@5.82.1) + watchpack: 2.4.0 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + + /which-module@2.0.0: + resolution: {integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=} + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wide-align@1.1.3: + resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} + dependencies: + string-width: 2.1.1 + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 1.0.2 + dev: true + + /word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /workerpool@6.1.0: + resolution: {integrity: sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==} + dev: true + + /wrap-ansi@5.1.0: + resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} + engines: {node: '>=6'} + dependencies: + ansi-styles: 3.2.1 + string-width: 3.1.0 + strip-ansi: 5.2.0 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + dev: true + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yargs-parser@15.0.3: + resolution: {integrity: sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + dev: true + + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + dev: true + + /yargs@14.2.3: + resolution: {integrity: sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==} + dependencies: + cliui: 5.0.0 + decamelize: 1.2.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.0 + y18n: 4.0.3 + yargs-parser: 15.0.3 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/numbat-lsp/rust-toolchains.toml b/numbat-lsp/rust-toolchains.toml new file mode 100644 index 000000000..7eb23c42c --- /dev/null +++ b/numbat-lsp/rust-toolchains.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.72.1" diff --git a/numbat-lsp/src/chumsky.rs b/numbat-lsp/src/chumsky.rs new file mode 100644 index 000000000..43c2a2fc2 --- /dev/null +++ b/numbat-lsp/src/chumsky.rs @@ -0,0 +1,619 @@ +use chumsky::Parser; +use chumsky::{prelude::*, stream::Stream}; +use core::fmt; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use tower_lsp::lsp_types::SemanticTokenType; + +use crate::semantic_token::LEGEND_TYPE; + +/// This is the parser and interpreter for the 'Foo' language. See `tutorial.md` in the repository's root to learn +/// about it. +pub type Span = std::ops::Range; +#[derive(Debug)] +pub struct ImCompleteSemanticToken { + pub start: usize, + pub length: usize, + pub token_type: usize, +} +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum Token { + Null, + Bool(bool), + Num(String), + Str(String), + Op(String), + Ctrl(char), + Ident(String), + Fn, + Let, + Print, + If, + Else, +} + +impl fmt::Display for Token { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Token::Null => write!(f, "null"), + Token::Bool(x) => write!(f, "{}", x), + Token::Num(n) => write!(f, "{}", n), + Token::Str(s) => write!(f, "{}", s), + Token::Op(s) => write!(f, "{}", s), + Token::Ctrl(c) => write!(f, "{}", c), + Token::Ident(s) => write!(f, "{}", s), + Token::Fn => write!(f, "fn"), + Token::Let => write!(f, "let"), + Token::Print => write!(f, "print"), + Token::If => write!(f, "if"), + Token::Else => write!(f, "else"), + } + } +} + +fn lexer() -> impl Parser, Error = Simple> { + // A parser for numbers + let num = text::int(10) + .chain::(just('.').chain(text::digits(10)).or_not().flatten()) + .collect::() + .map(Token::Num); + + // A parser for strings + let str_ = just('"') + .ignore_then(filter(|c| *c != '"').repeated()) + .then_ignore(just('"')) + .collect::() + .map(Token::Str); + + // A parser for operators + let op = one_of("+-*/!=") + .repeated() + .at_least(1) + .collect::() + .map(Token::Op); + + // A parser for control characters (delimiters, semicolons, etc.) + let ctrl = one_of("()[]{};,").map(Token::Ctrl); + + // A parser for identifiers and keywords + let ident = text::ident().map(|ident: String| match ident.as_str() { + "fn" => Token::Fn, + "let" => Token::Let, + "print" => Token::Print, + "if" => Token::If, + "else" => Token::Else, + "true" => Token::Bool(true), + "false" => Token::Bool(false), + "null" => Token::Null, + _ => Token::Ident(ident), + }); + + // A single token can be one of the above + let token = num + .or(str_) + .or(op) + .or(ctrl) + .or(ident) + .recover_with(skip_then_retry_until([])); + + let comment = just("//").then(take_until(just('\n'))).padded(); + + token + .padded_by(comment.repeated()) + .map_with_span(|tok, span| (tok, span)) + .padded() + .repeated() +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum Value { + Null, + Bool(bool), + Num(f64), + Str(String), + List(Vec), + Func(String), +} + +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Null => write!(f, "null"), + Self::Bool(x) => write!(f, "{}", x), + Self::Num(x) => write!(f, "{}", x), + Self::Str(x) => write!(f, "{}", x), + Self::List(xs) => write!( + f, + "[{}]", + xs.iter() + .map(|x| x.to_string()) + .collect::>() + .join(", ") + ), + Self::Func(name) => write!(f, "", name), + } + } +} + +#[derive(Clone, Debug)] +pub enum BinaryOp { + Add, + Sub, + Mul, + Div, + Eq, + NotEq, +} + +pub type Spanned = (T, Span); + +// An expression node in the AST. Children are spanned so we can generate useful runtime errors. +#[derive(Debug)] +pub enum Expr { + Error, + Value(Value), + List(Vec>), + Local(Spanned), + Let(String, Box>, Box>, Span), + Then(Box>, Box>), + Binary(Box>, BinaryOp, Box>), + Call(Box>, Spanned>>), + If(Box>, Box>, Box>), + Print(Box>), +} + +#[allow(unused)] +impl Expr { + /// Returns `true` if the expr is [`Error`]. + /// + /// [`Error`]: Expr::Error + fn is_error(&self) -> bool { + matches!(self, Self::Error) + } + + /// Returns `true` if the expr is [`Let`]. + /// + /// [`Let`]: Expr::Let + fn is_let(&self) -> bool { + matches!(self, Self::Let(..)) + } + + /// Returns `true` if the expr is [`Value`]. + /// + /// [`Value`]: Expr::Value + fn is_value(&self) -> bool { + matches!(self, Self::Value(..)) + } + + fn try_into_value(self) -> Result { + if let Self::Value(v) = self { + Ok(v) + } else { + Err(self) + } + } + + fn as_value(&self) -> Option<&Value> { + if let Self::Value(v) = self { + Some(v) + } else { + None + } + } +} + +// A function node in the AST. +#[derive(Debug)] +pub struct Func { + pub args: Vec>, + pub body: Spanned, + pub name: Spanned, + pub span: Span, +} + +fn expr_parser() -> impl Parser, Error = Simple> + Clone { + recursive(|expr| { + let raw_expr = recursive(|raw_expr| { + let val = filter_map(|span, tok| match tok { + Token::Null => Ok(Expr::Value(Value::Null)), + Token::Bool(x) => Ok(Expr::Value(Value::Bool(x))), + Token::Num(n) => Ok(Expr::Value(Value::Num(n.parse().unwrap()))), + Token::Str(s) => Ok(Expr::Value(Value::Str(s))), + _ => Err(Simple::expected_input_found(span, Vec::new(), Some(tok))), + }) + .labelled("value"); + + let ident = filter_map(|span, tok| match tok { + Token::Ident(ident) => Ok((ident, span)), + _ => Err(Simple::expected_input_found(span, Vec::new(), Some(tok))), + }) + .labelled("identifier"); + + // A list of expressions + let items = expr + .clone() + .chain(just(Token::Ctrl(',')).ignore_then(expr.clone()).repeated()) + .then_ignore(just(Token::Ctrl(',')).or_not()) + .or_not() + .map(|item| item.unwrap_or_default()); + + // A let expression + let let_ = just(Token::Let) + .ignore_then(ident) + .then_ignore(just(Token::Op("=".to_string()))) + .then(raw_expr) + .then_ignore(just(Token::Ctrl(';'))) + .then(expr.clone()) + .map(|((name, val), body)| { + Expr::Let(name.0, Box::new(val), Box::new(body), name.1) + }); + + let list = items + .clone() + .delimited_by(just(Token::Ctrl('[')), just(Token::Ctrl(']'))) + .map(Expr::List); + + // 'Atoms' are expressions that contain no ambiguity + let atom = val + .or(ident.map(Expr::Local)) + .or(let_) + .or(list) + // In Nano Rust, `print` is just a keyword, just like Python 2, for simplicity + .or(just(Token::Print) + .ignore_then( + expr.clone() + .delimited_by(just(Token::Ctrl('(')), just(Token::Ctrl(')'))), + ) + .map(|expr| Expr::Print(Box::new(expr)))) + .map_with_span(|expr, span| (expr, span)) + // Atoms can also just be normal expressions, but surrounded with parentheses + .or(expr + .clone() + .delimited_by(just(Token::Ctrl('(')), just(Token::Ctrl(')')))) + // Attempt to recover anything that looks like a parenthesised expression but contains errors + .recover_with(nested_delimiters( + Token::Ctrl('('), + Token::Ctrl(')'), + [ + (Token::Ctrl('['), Token::Ctrl(']')), + (Token::Ctrl('{'), Token::Ctrl('}')), + ], + |span| (Expr::Error, span), + )) + // Attempt to recover anything that looks like a list but contains errors + .recover_with(nested_delimiters( + Token::Ctrl('['), + Token::Ctrl(']'), + [ + (Token::Ctrl('('), Token::Ctrl(')')), + (Token::Ctrl('{'), Token::Ctrl('}')), + ], + |span| (Expr::Error, span), + )); + + // Function calls have very high precedence so we prioritise them + let call = atom + .then( + items + .delimited_by(just(Token::Ctrl('(')), just(Token::Ctrl(')'))) + .map_with_span(|args, span| (args, span)) + .repeated(), + ) + .foldl(|f, args| { + let span = f.1.start..args.1.end; + (Expr::Call(Box::new(f), args), span) + }); + + // Product ops (multiply and divide) have equal precedence + let op = just(Token::Op("*".to_string())) + .to(BinaryOp::Mul) + .or(just(Token::Op("/".to_string())).to(BinaryOp::Div)); + let product = call + .clone() + .then(op.then(call).repeated()) + .foldl(|a, (op, b)| { + let span = a.1.start..b.1.end; + (Expr::Binary(Box::new(a), op, Box::new(b)), span) + }); + + // Sum ops (add and subtract) have equal precedence + let op = just(Token::Op("+".to_string())) + .to(BinaryOp::Add) + .or(just(Token::Op("-".to_string())).to(BinaryOp::Sub)); + let sum = product + .clone() + .then(op.then(product).repeated()) + .foldl(|a, (op, b)| { + let span = a.1.start..b.1.end; + (Expr::Binary(Box::new(a), op, Box::new(b)), span) + }); + + // Comparison ops (equal, not-equal) have equal precedence + let op = just(Token::Op("==".to_string())) + .to(BinaryOp::Eq) + .or(just(Token::Op("!=".to_string())).to(BinaryOp::NotEq)); + + sum.clone() + .then(op.then(sum).repeated()) + .foldl(|a, (op, b)| { + let span = a.1.start..b.1.end; + (Expr::Binary(Box::new(a), op, Box::new(b)), span) + }) + }); + + // Blocks are expressions but delimited with braces + let block = expr + .clone() + .delimited_by(just(Token::Ctrl('{')), just(Token::Ctrl('}'))) + // Attempt to recover anything that looks like a block but contains errors + .recover_with(nested_delimiters( + Token::Ctrl('{'), + Token::Ctrl('}'), + [ + (Token::Ctrl('('), Token::Ctrl(')')), + (Token::Ctrl('['), Token::Ctrl(']')), + ], + |span| (Expr::Error, span), + )); + + let if_ = recursive(|if_| { + just(Token::If) + .ignore_then(expr.clone()) + .then(block.clone()) + .then( + just(Token::Else) + .ignore_then(block.clone().or(if_)) + .or_not(), + ) + .map_with_span(|((cond, a), b), span| { + ( + Expr::If( + Box::new(cond), + Box::new(a), + Box::new(match b { + Some(b) => b, + // If an `if` expression has no trailing `else` block, we magic up one that just produces null + None => (Expr::Value(Value::Null), span.clone()), + }), + ), + span, + ) + }) + }); + + // Both blocks and `if` are 'block expressions' and can appear in the place of statements + let block_expr = block.or(if_).labelled("block"); + + let block_chain = block_expr + .clone() + .then(block_expr.clone().repeated()) + .foldl(|a, b| { + let span = a.1.start..b.1.end; + (Expr::Then(Box::new(a), Box::new(b)), span) + }); + + block_chain + // Expressions, chained by semicolons, are statements + .or(raw_expr.clone()) + .then(just(Token::Ctrl(';')).ignore_then(expr.or_not()).repeated()) + .foldl(|a, b| { + let span = a.1.clone(); // TODO: Not correct + ( + Expr::Then( + Box::new(a), + Box::new(match b { + Some(b) => b, + None => (Expr::Value(Value::Null), span.clone()), + }), + ), + span, + ) + }) + }) +} + +pub fn funcs_parser() -> impl Parser, Error = Simple> + Clone { + let ident = filter_map(|span, tok| match tok { + Token::Ident(ident) => Ok(ident), + _ => Err(Simple::expected_input_found(span, Vec::new(), Some(tok))), + }); + + // Argument lists are just identifiers separated by commas, surrounded by parentheses + let args = ident + .map_with_span(|name, span| (name, span)) + .separated_by(just(Token::Ctrl(','))) + .allow_trailing() + .delimited_by(just(Token::Ctrl('(')), just(Token::Ctrl(')'))) + .labelled("function args"); + + let func = just(Token::Fn) + .ignore_then( + ident + .map_with_span(|name, span| (name, span)) + .labelled("function name"), + ) + .then(args) + .then( + expr_parser() + .delimited_by(just(Token::Ctrl('{')), just(Token::Ctrl('}'))) + // Attempt to recover anything that looks like a function body but contains errors + .recover_with(nested_delimiters( + Token::Ctrl('{'), + Token::Ctrl('}'), + [ + (Token::Ctrl('('), Token::Ctrl(')')), + (Token::Ctrl('['), Token::Ctrl(']')), + ], + |span| (Expr::Error, span), + )), + ) + .map_with_span(|((name, args), body), span| { + ( + name.clone(), + Func { + args, + body, + name, + span, + }, + ) + }) + .labelled("function"); + + func.repeated() + .try_map(|fs, _| { + let mut funcs = HashMap::new(); + for ((name, name_span), f) in fs { + if funcs.insert(name.clone(), f).is_some() { + return Err(Simple::custom( + name_span, + format!("Function '{}' already exists", name), + )); + } + } + Ok(funcs) + }) + .then_ignore(end()) +} + +pub fn type_inference(expr: &Spanned, symbol_type_table: &mut HashMap) { + match &expr.0 { + Expr::Error => {} + Expr::Value(_) => {} + Expr::List(exprs) => exprs + .iter() + .for_each(|expr| type_inference(expr, symbol_type_table)), + Expr::Local(_) => {} + Expr::Let(_name, lhs, rest, name_span) => { + if let Some(value) = lhs.0.as_value() { + symbol_type_table.insert(name_span.clone(), value.clone()); + } + type_inference(rest, symbol_type_table); + } + Expr::Then(first, second) => { + type_inference(first, symbol_type_table); + type_inference(second, symbol_type_table); + } + Expr::Binary(_, _, _) => {} + Expr::Call(_, _) => {} + Expr::If(_test, consequent, alternative) => { + type_inference(consequent, symbol_type_table); + type_inference(alternative, symbol_type_table); + } + Expr::Print(expr) => { + type_inference(expr, symbol_type_table); + } + } +} + +#[derive(Debug)] +pub struct ParserResult { + pub ast: Option>, + pub parse_errors: Vec>, + pub semantic_tokens: Vec, +} + +pub fn parse(src: &str) -> ParserResult { + let (tokens, errs) = lexer().parse_recovery(src); + + let (ast, tokenize_errors, semantic_tokens) = if let Some(tokens) = tokens { + // info!("Tokens = {:?}", tokens); + let semantic_tokens = tokens + .iter() + .filter_map(|(token, span)| match token { + Token::Null => None, + Token::Bool(_) => None, + + Token::Num(_) => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::NUMBER) + .unwrap(), + }), + Token::Str(_) => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::STRING) + .unwrap(), + }), + Token::Op(_) => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::OPERATOR) + .unwrap(), + }), + Token::Ctrl(_) => None, + Token::Ident(_) => None, + Token::Fn => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::KEYWORD) + .unwrap(), + }), + Token::Let => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::KEYWORD) + .unwrap(), + }), + Token::Print => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::FUNCTION) + .unwrap(), + }), + Token::If => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::KEYWORD) + .unwrap(), + }), + Token::Else => Some(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::KEYWORD) + .unwrap(), + }), + }) + .collect::>(); + let len = src.chars().count(); + let (ast, parse_errs) = + funcs_parser().parse_recovery(Stream::from_iter(len..len + 1, tokens.into_iter())); + + (ast, parse_errs, semantic_tokens) + } else { + (None, Vec::new(), vec![]) + }; + + let parse_errors = errs + .into_iter() + .map(|e| e.map(|c| c.to_string())) + .chain( + tokenize_errors + .into_iter() + .map(|e| e.map(|tok| tok.to_string())), + ) + .collect::>(); + + ParserResult { + ast, + parse_errors, + semantic_tokens, + } +} diff --git a/numbat-lsp/src/completion.rs b/numbat-lsp/src/completion.rs new file mode 100644 index 000000000..4565ac7ec --- /dev/null +++ b/numbat-lsp/src/completion.rs @@ -0,0 +1,107 @@ +use std::collections::HashMap; + +use crate::chumsky::{Expr, Func, Spanned}; +pub enum ImCompleteCompletionItem { + Variable(String), + Function(String, Vec), +} +/// return (need_to_continue_search, founded reference) +pub fn completion( + ast: &HashMap, + ident_offset: usize, +) -> HashMap { + let mut map = HashMap::new(); + for (_, v) in ast.iter() { + if v.name.1.end < ident_offset { + map.insert( + v.name.0.clone(), + ImCompleteCompletionItem::Function( + v.name.0.clone(), + v.args.clone().into_iter().map(|(name, _)| name).collect(), + ), + ); + } + } + + // collect params variable + for (_, v) in ast.iter() { + if v.span.end > ident_offset && v.span.start < ident_offset { + // log::debug!("this is completion from body {}", name); + v.args.iter().for_each(|(item, _)| { + map.insert( + item.clone(), + ImCompleteCompletionItem::Variable(item.clone()), + ); + }); + get_completion_of(&v.body, &mut map, ident_offset); + } + } + map +} + +pub fn get_completion_of( + expr: &Spanned, + definition_map: &mut HashMap, + ident_offset: usize, +) -> bool { + match &expr.0 { + Expr::Error => true, + Expr::Value(_) => true, + // Expr::List(exprs) => exprs + // .iter() + // .for_each(|expr| get_definition(expr, definition_ass_list)), + Expr::Local(local) => !(ident_offset >= local.1.start && ident_offset < local.1.end), + Expr::Let(name, lhs, rest, _name_span) => { + definition_map.insert( + name.clone(), + ImCompleteCompletionItem::Variable(name.clone()), + ); + match get_completion_of(lhs, definition_map, ident_offset) { + true => get_completion_of(rest, definition_map, ident_offset), + false => false, + } + } + Expr::Then(first, second) => match get_completion_of(first, definition_map, ident_offset) { + true => get_completion_of(second, definition_map, ident_offset), + false => false, + }, + Expr::Binary(lhs, _op, rhs) => match get_completion_of(lhs, definition_map, ident_offset) { + true => get_completion_of(rhs, definition_map, ident_offset), + false => false, + }, + Expr::Call(callee, args) => { + match get_completion_of(callee, definition_map, ident_offset) { + true => {} + false => return false, + } + for expr in &args.0 { + match get_completion_of(expr, definition_map, ident_offset) { + true => continue, + false => return false, + } + } + true + } + Expr::If(test, consequent, alternative) => { + match get_completion_of(test, definition_map, ident_offset) { + true => {} + false => return false, + } + match get_completion_of(consequent, definition_map, ident_offset) { + true => {} + false => return false, + } + get_completion_of(alternative, definition_map, ident_offset) + } + Expr::Print(expr) => get_completion_of(expr, definition_map, ident_offset), + Expr::List(lst) => { + for expr in lst { + match get_completion_of(expr, definition_map, ident_offset) { + true => continue, + false => return false, + } + } + true + } + } +} diff --git a/numbat-lsp/src/jump_definition.rs b/numbat-lsp/src/jump_definition.rs new file mode 100644 index 000000000..84524cd64 --- /dev/null +++ b/numbat-lsp/src/jump_definition.rs @@ -0,0 +1,129 @@ +use std::collections::HashMap; + +use im_rc::Vector; + +use crate::chumsky::{Expr, Func, Spanned}; +/// return (need_to_continue_search, founded reference) +pub fn get_definition(ast: &HashMap, ident_offset: usize) -> Option> { + let mut vector = Vector::new(); + for (_, v) in ast.iter() { + if v.name.1.start < ident_offset && v.name.1.end > ident_offset { + return Some(v.name.clone()); + } + if v.name.1.end < ident_offset { + vector.push_back(v.name.clone()); + } + } + + for (_, v) in ast.iter() { + let args = v.args.iter().cloned().collect::>(); + if let (_, Some(value)) = + get_definition_of_expr(&v.body, args + vector.clone(), ident_offset) + { + return Some(value); + } + } + None +} + +pub fn get_definition_of_expr( + expr: &Spanned, + definition_ass_list: Vector>, + ident_offset: usize, +) -> (bool, Option>) { + match &expr.0 { + Expr::Error => (true, None), + Expr::Value(_) => (true, None), + // Expr::List(exprs) => exprs + // .iter() + // .for_each(|expr| get_definition(expr, definition_ass_list)), + Expr::Local(local) => { + if ident_offset >= local.1.start && ident_offset < local.1.end { + let index = definition_ass_list + .iter() + .position(|decl| decl.0 == local.0); + ( + false, + index.map(|i| definition_ass_list.get(i).unwrap().clone()), + ) + } else { + (true, None) + } + } + Expr::Let(name, lhs, rest, name_span) => { + let new_decl = Vector::unit((name.clone(), name_span.clone())); + + match get_definition_of_expr(lhs, definition_ass_list.clone(), ident_offset) { + (true, None) => { + get_definition_of_expr(rest, new_decl + definition_ass_list, ident_offset) + } + (true, Some(value)) => (false, Some(value)), + (false, None) => (false, None), + (false, Some(value)) => (false, Some(value)), + } + } + Expr::Then(first, second) => { + match get_definition_of_expr(first, definition_ass_list.clone(), ident_offset) { + (true, None) => get_definition_of_expr(second, definition_ass_list, ident_offset), + (false, None) => (false, None), + (true, Some(value)) | (false, Some(value)) => (false, Some(value)), + } + } + Expr::Binary(lhs, _, rhs) => { + match get_definition_of_expr(lhs, definition_ass_list.clone(), ident_offset) { + (true, None) => get_definition_of_expr(rhs, definition_ass_list, ident_offset), + (false, None) => (false, None), + (true, Some(value)) | (false, Some(value)) => (false, Some(value)), + } + } + Expr::Call(callee, args) => { + match get_definition_of_expr(callee, definition_ass_list.clone(), ident_offset) { + (true, None) => {} + (true, Some(value)) => return (false, Some(value)), + (false, None) => return (false, None), + (false, Some(value)) => return (false, Some(value)), + } + for expr in &args.0 { + match get_definition_of_expr(expr, definition_ass_list.clone(), ident_offset) { + (true, None) => continue, + (true, Some(value)) => return (false, Some(value)), + (false, None) => return (false, None), + (false, Some(value)) => return (false, Some(value)), + } + } + (true, None) + } + Expr::If(test, consequent, alternative) => { + match get_definition_of_expr(test, definition_ass_list.clone(), ident_offset) { + (true, None) => {} + (true, Some(value)) => return (false, Some(value)), + (false, None) => return (false, None), + (false, Some(value)) => return (false, Some(value)), + } + match get_definition_of_expr(consequent, definition_ass_list.clone(), ident_offset) { + (true, None) => {} + (true, Some(value)) => return (false, Some(value)), + (false, None) => return (false, None), + (false, Some(value)) => return (false, Some(value)), + } + match get_definition_of_expr(alternative, definition_ass_list, ident_offset) { + (true, None) => (true, None), + (true, Some(value)) => (false, Some(value)), + (false, None) => (false, None), + (false, Some(value)) => (false, Some(value)), + } + } + Expr::Print(expr) => get_definition_of_expr(expr, definition_ass_list, ident_offset), + Expr::List(lst) => { + for expr in lst { + match get_definition_of_expr(expr, definition_ass_list.clone(), ident_offset) { + (true, None) => continue, + (true, Some(value)) => return (false, Some(value)), + (false, None) => return (false, None), + (false, Some(value)) => return (false, Some(value)), + } + } + (true, None) + } + } +} diff --git a/numbat-lsp/src/lib.rs b/numbat-lsp/src/lib.rs new file mode 100644 index 000000000..da29ba3bb --- /dev/null +++ b/numbat-lsp/src/lib.rs @@ -0,0 +1,5 @@ +pub mod chumsky; +pub mod completion; +pub mod jump_definition; +pub mod reference; +pub mod semantic_token; diff --git a/numbat-lsp/src/main.rs b/numbat-lsp/src/main.rs new file mode 100644 index 000000000..9fc1e0ae5 --- /dev/null +++ b/numbat-lsp/src/main.rs @@ -0,0 +1,842 @@ +use std::collections::HashMap; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; + +use dashmap::DashMap; +use numbat::module_importer::{BuiltinModuleImporter, ChainedImporter, FileSystemImporter}; +use numbat::resolver::{CodeSource, ResolverError}; +use numbat::{ + Context, IncompatibleDimensionsError, InterpreterSettings, NameResolutionError, NumbatError, + Span, TypeCheckError, +}; +use numbat_lsp::chumsky::{type_inference, Func, ImCompleteSemanticToken}; +use numbat_lsp::completion::completion; +use numbat_lsp::jump_definition::get_definition; +use numbat_lsp::reference::get_reference; +use numbat_lsp::semantic_token::{semantic_token_from_ast, LEGEND_TYPE}; +use ropey::Rope; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tokio::sync::Mutex; +use tower_lsp::jsonrpc::Result; +use tower_lsp::lsp_types::*; +use tower_lsp::{Client, LanguageServer, LspService, Server}; + +struct Backend { + client: Client, + ast_map: DashMap>, + document_map: DashMap, + semantic_token_map: DashMap>, + + context: Arc>, +} + +#[tower_lsp::async_trait] +impl LanguageServer for Backend { + async fn initialize(&self, _: InitializeParams) -> Result { + Ok(InitializeResult { + server_info: None, + offset_encoding: None, + capabilities: ServerCapabilities { + inlay_hint_provider: Some(OneOf::Left(true)), + text_document_sync: Some(TextDocumentSyncCapability::Kind( + TextDocumentSyncKind::FULL, + )), + completion_provider: Some(CompletionOptions { + resolve_provider: Some(false), + trigger_characters: Some(vec!["|>".to_string()]), + work_done_progress_options: Default::default(), + all_commit_characters: None, + completion_item: None, + }), + execute_command_provider: Some(ExecuteCommandOptions { + commands: vec!["dummy.do_something".to_string()], + work_done_progress_options: Default::default(), + }), + + workspace: Some(WorkspaceServerCapabilities { + workspace_folders: Some(WorkspaceFoldersServerCapabilities { + supported: Some(true), + change_notifications: Some(OneOf::Left(true)), + }), + file_operations: None, + }), + semantic_tokens_provider: Some( + SemanticTokensServerCapabilities::SemanticTokensRegistrationOptions( + SemanticTokensRegistrationOptions { + text_document_registration_options: { + TextDocumentRegistrationOptions { + document_selector: Some(vec![DocumentFilter { + language: Some("numbat".to_string()), + scheme: Some("file".to_string()), + pattern: Some("*.nbt".to_string()), + }]), + } + }, + semantic_tokens_options: SemanticTokensOptions { + work_done_progress_options: WorkDoneProgressOptions::default(), + legend: SemanticTokensLegend { + token_types: LEGEND_TYPE.into(), + token_modifiers: vec![], + }, + range: Some(true), + full: Some(SemanticTokensFullOptions::Bool(true)), + }, + static_registration_options: StaticRegistrationOptions::default(), + }, + ), + ), + // definition: Some(GotoCapability::default()), + definition_provider: Some(OneOf::Left(true)), + references_provider: Some(OneOf::Left(true)), + rename_provider: Some(OneOf::Left(true)), + ..ServerCapabilities::default() + }, + }) + } + async fn initialized(&self, _: InitializedParams) { + self.client + .log_message(MessageType::INFO, "initialized!") + .await; + } + + async fn shutdown(&self) -> Result<()> { + Ok(()) + } + + async fn did_open(&self, params: DidOpenTextDocumentParams) { + self.client + .log_message(MessageType::INFO, "file opened!") + .await; + self.on_change(TextDocumentItem { + uri: params.text_document.uri, + text: params.text_document.text, + version: params.text_document.version, + }) + .await + } + + async fn did_change(&self, mut params: DidChangeTextDocumentParams) { + self.on_change(TextDocumentItem { + uri: params.text_document.uri, + text: std::mem::take(&mut params.content_changes[0].text), + version: params.text_document.version, + }) + .await + } + + async fn did_save(&self, _: DidSaveTextDocumentParams) { + self.client + .log_message(MessageType::INFO, "file saved!") + .await; + } + async fn did_close(&self, _: DidCloseTextDocumentParams) { + self.client + .log_message(MessageType::INFO, "file closed!") + .await; + } + + async fn goto_definition( + &self, + params: GotoDefinitionParams, + ) -> Result> { + let definition = async { + let uri = params.text_document_position_params.text_document.uri; + let ast = self.ast_map.get(uri.as_str())?; + let rope = self.document_map.get(uri.as_str())?; + + let position = params.text_document_position_params.position; + let char = rope.try_line_to_char(position.line as usize).ok()?; + let offset = char + position.character as usize; + // self.client.log_message(MessageType::INFO, &format!("{:#?}, {}", ast.value(), offset)).await; + let span = get_definition(&ast, offset); + self.client + .log_message(MessageType::INFO, &format!("{:?}, ", span)) + .await; + span.and_then(|(_, range)| { + let start_position = offset_to_position(range.start, &rope)?; + let end_position = offset_to_position(range.end, &rope)?; + + let range = Range::new(start_position, end_position); + + Some(GotoDefinitionResponse::Scalar(Location::new(uri, range))) + }) + } + .await; + Ok(definition) + } + async fn references(&self, params: ReferenceParams) -> Result>> { + let reference_list = || -> Option> { + let uri = params.text_document_position.text_document.uri; + let ast = self.ast_map.get(&uri.to_string())?; + let rope = self.document_map.get(&uri.to_string())?; + + let position = params.text_document_position.position; + let char = rope.try_line_to_char(position.line as usize).ok()?; + let offset = char + position.character as usize; + let reference_list = get_reference(&ast, offset, false); + let ret = reference_list + .into_iter() + .filter_map(|(_, range)| { + let start_position = offset_to_position(range.start, &rope)?; + let end_position = offset_to_position(range.end, &rope)?; + + let range = Range::new(start_position, end_position); + + Some(Location::new(uri.clone(), range)) + }) + .collect::>(); + Some(ret) + }(); + Ok(reference_list) + } + + async fn semantic_tokens_full( + &self, + params: SemanticTokensParams, + ) -> Result> { + let uri = params.text_document.uri.to_string(); + self.client + .log_message(MessageType::LOG, "semantic_token_full") + .await; + let semantic_tokens = || -> Option> { + let mut im_complete_tokens = self.semantic_token_map.get_mut(&uri)?; + let rope = self.document_map.get(&uri)?; + let ast = self.ast_map.get(&uri)?; + let extends_tokens = semantic_token_from_ast(&ast); + im_complete_tokens.extend(extends_tokens); + im_complete_tokens.sort_by(|a, b| a.start.cmp(&b.start)); + let mut pre_line = 0; + let mut pre_start = 0; + let semantic_tokens = im_complete_tokens + .iter() + .filter_map(|token| { + let line = rope.try_byte_to_line(token.start).ok()? as u32; + let first = rope.try_line_to_char(line as usize).ok()? as u32; + let start = rope.try_byte_to_char(token.start).ok()? as u32 - first; + let delta_line = line - pre_line; + let delta_start = if delta_line == 0 { + start - pre_start + } else { + start + }; + let ret = Some(SemanticToken { + delta_line, + delta_start, + length: token.length as u32, + token_type: token.token_type as u32, + token_modifiers_bitset: 0, + }); + pre_line = line; + pre_start = start; + ret + }) + .collect::>(); + Some(semantic_tokens) + }(); + if let Some(semantic_token) = semantic_tokens { + return Ok(Some(SemanticTokensResult::Tokens(SemanticTokens { + result_id: None, + data: semantic_token, + }))); + } + Ok(None) + } + + async fn semantic_tokens_range( + &self, + params: SemanticTokensRangeParams, + ) -> Result> { + let uri = params.text_document.uri.to_string(); + let semantic_tokens = || -> Option> { + let im_complete_tokens = self.semantic_token_map.get(&uri)?; + let rope = self.document_map.get(&uri)?; + let mut pre_line = 0; + let mut pre_start = 0; + let semantic_tokens = im_complete_tokens + .iter() + .filter_map(|token| { + let line = rope.try_byte_to_line(token.start).ok()? as u32; + let first = rope.try_line_to_char(line as usize).ok()? as u32; + let start = rope.try_byte_to_char(token.start).ok()? as u32 - first; + let ret = Some(SemanticToken { + delta_line: line - pre_line, + delta_start: if start >= pre_start { + start - pre_start + } else { + start + }, + length: token.length as u32, + token_type: token.token_type as u32, + token_modifiers_bitset: 0, + }); + pre_line = line; + pre_start = start; + ret + }) + .collect::>(); + Some(semantic_tokens) + }(); + if let Some(semantic_token) = semantic_tokens { + return Ok(Some(SemanticTokensRangeResult::Tokens(SemanticTokens { + result_id: None, + data: semantic_token, + }))); + } + Ok(None) + } + + async fn inlay_hint( + &self, + params: tower_lsp::lsp_types::InlayHintParams, + ) -> Result>> { + self.client + .log_message(MessageType::INFO, "inlay hint") + .await; + let uri = ¶ms.text_document.uri; + let mut hashmap = HashMap::new(); + if let Some(ast) = self.ast_map.get(uri.as_str()) { + ast.iter().for_each(|(_, v)| { + type_inference(&v.body, &mut hashmap); + }); + } + + let document = match self.document_map.get(uri.as_str()) { + Some(rope) => rope, + None => return Ok(None), + }; + let inlay_hint_list = hashmap + .into_iter() + .map(|(k, v)| { + ( + k.start, + k.end, + match v { + numbat_lsp::chumsky::Value::Null => "null".to_string(), + numbat_lsp::chumsky::Value::Bool(_) => "bool".to_string(), + numbat_lsp::chumsky::Value::Num(_) => "number".to_string(), + numbat_lsp::chumsky::Value::Str(_) => "string".to_string(), + numbat_lsp::chumsky::Value::List(_) => "[]".to_string(), + numbat_lsp::chumsky::Value::Func(_) => v.to_string(), + }, + ) + }) + .filter_map(|item| { + // let start_position = offset_to_position(item.0, document)?; + let end_position = offset_to_position(item.1, &document)?; + let inlay_hint = InlayHint { + text_edits: None, + tooltip: None, + kind: Some(InlayHintKind::TYPE), + padding_left: None, + padding_right: None, + data: None, + position: end_position, + label: InlayHintLabel::LabelParts(vec![InlayHintLabelPart { + value: item.2, + tooltip: None, + location: Some(Location { + uri: params.text_document.uri.clone(), + range: Range { + start: Position::new(0, 4), + end: Position::new(0, 5), + }, + }), + command: None, + }]), + }; + Some(inlay_hint) + }) + .collect::>(); + + Ok(Some(inlay_hint_list)) + } + + async fn completion(&self, params: CompletionParams) -> Result> { + let uri = params.text_document_position.text_document.uri; + let position = params.text_document_position.position; + let completions = || -> Option> { + let rope = self.document_map.get(&uri.to_string())?; + let ast = self.ast_map.get(&uri.to_string())?; + let char = rope.try_line_to_char(position.line as usize).ok()?; + let offset = char + position.character as usize; + let completions = completion(&ast, offset); + let mut ret = Vec::with_capacity(completions.len()); + for (_, item) in completions { + match item { + numbat_lsp::completion::ImCompleteCompletionItem::Variable(var) => { + ret.push(CompletionItem { + label: var.clone(), + insert_text: Some(var.clone()), + kind: Some(CompletionItemKind::VARIABLE), + detail: Some(var), + ..Default::default() + }); + } + numbat_lsp::completion::ImCompleteCompletionItem::Function(name, args) => { + ret.push(CompletionItem { + label: name.clone(), + kind: Some(CompletionItemKind::FUNCTION), + detail: Some(name.clone()), + insert_text: Some(format!( + "{}({})", + name, + args.iter() + .enumerate() + .map(|(index, item)| { format!("${{{}:{}}}", index + 1, item) }) + .collect::>() + .join(",") + )), + insert_text_format: Some(InsertTextFormat::SNIPPET), + ..Default::default() + }); + } + } + } + Some(ret) + }(); + Ok(completions.map(CompletionResponse::Array)) + } + + async fn rename(&self, params: RenameParams) -> Result> { + let workspace_edit = || -> Option { + let uri = params.text_document_position.text_document.uri; + let ast = self.ast_map.get(&uri.to_string())?; + let rope = self.document_map.get(&uri.to_string())?; + + let position = params.text_document_position.position; + let char = rope.try_line_to_char(position.line as usize).ok()?; + let offset = char + position.character as usize; + let reference_list = get_reference(&ast, offset, true); + let new_name = params.new_name; + if !reference_list.is_empty() { + let edit_list = reference_list + .into_iter() + .filter_map(|(_, range)| { + let start_position = offset_to_position(range.start, &rope)?; + let end_position = offset_to_position(range.end, &rope)?; + Some(TextEdit::new( + Range::new(start_position, end_position), + new_name.clone(), + )) + }) + .collect::>(); + let mut map = HashMap::new(); + map.insert(uri, edit_list); + let workspace_edit = WorkspaceEdit::new(map); + Some(workspace_edit) + } else { + None + } + }(); + Ok(workspace_edit) + } + + async fn did_change_configuration(&self, _: DidChangeConfigurationParams) { + self.client + .log_message(MessageType::INFO, "configuration changed!") + .await; + } + + async fn did_change_workspace_folders(&self, _: DidChangeWorkspaceFoldersParams) { + self.client + .log_message(MessageType::INFO, "workspace folders changed!") + .await; + } + + async fn did_change_watched_files(&self, _: DidChangeWatchedFilesParams) { + self.client + .log_message(MessageType::INFO, "watched files have changed!") + .await; + } + + async fn execute_command(&self, _: ExecuteCommandParams) -> Result> { + self.client + .log_message(MessageType::INFO, "command executed!") + .await; + + match self.client.apply_edit(WorkspaceEdit::default()).await { + Ok(res) if res.applied => self.client.log_message(MessageType::INFO, "applied").await, + Ok(_) => self.client.log_message(MessageType::INFO, "rejected").await, + Err(err) => self.client.log_message(MessageType::ERROR, err).await, + } + + Ok(None) + } +} +#[derive(Debug, Deserialize, Serialize)] +struct InlayHintParams { + path: String, +} + +struct TextDocumentItem { + uri: Url, + text: String, + version: i32, +} + +impl Backend { + async fn on_change(&self, params: TextDocumentItem) { + let rope = ropey::Rope::from_str(¶ms.text); + self.document_map + .insert(params.uri.to_string(), rope.clone()); + + let Ok(filepath) = params.uri.to_file_path() else { + return; + }; + let diagnostics = match self.context.lock().await.interpret_with_settings( + &mut InterpreterSettings { + print_fn: Box::new(move |_s| ()), + }, + ¶ms.text, + CodeSource::File(filepath), + ) { + Ok((_stmts, _results)) => { + vec![] + } + Err(err) => self.err_to_diagnostic(err).await, + }; + + self.client + .publish_diagnostics(params.uri.clone(), diagnostics, Some(params.version)) + .await; + + // if let Some(ast) = ast { + // self.ast_map.insert(params.uri.to_string(), ast); + // } + // self.client + // .log_message(MessageType::INFO, &format!("{:?}", semantic_tokens)) + // .await; + // self.semantic_token_map + // .insert(params.uri.to_string(), semantic_tokens); + } + + async fn err_to_diagnostic(&self, error: NumbatError) -> Vec { + match error { + NumbatError::ResolverError(err) => match err { + ResolverError::UnknownModule(span, ref _path) => { + self.simple_diagnostic(span, err).await + } + ResolverError::ParseErrors(errors) => errors + .iter() + .map(|error| Diagnostic { + range: span_to_range(error.span), + severity: Some(DiagnosticSeverity::ERROR), + code: None, + code_description: None, + source: Some("numbat".to_string()), + message: error.to_string(), + related_information: None, + tags: None, + data: None, + }) + .collect(), + }, + NumbatError::NameResolutionError(err) => self.name_resolution_diagnostic(err).await, + NumbatError::TypeCheckError(err) => self.typecheck_diagnostic(err).await, + NumbatError::RuntimeError(err) => self.diagnostic_without_location(err).await, + } + } + + async fn diagnostic_without_location(&self, error: impl std::error::Error) -> Vec { + vec![Diagnostic { + // When we don't have a location to display the error, we + // always show the errors on the first line. + range: Range::new(Position::new(0, 0), Position::new(1, 0)), + severity: Some(DiagnosticSeverity::ERROR), + code: None, + code_description: None, + source: Some("numbat".to_string()), + message: error.to_string(), + related_information: None, + tags: None, + data: None, + }] + } + + async fn simple_diagnostic( + &self, + location: Span, + error: impl std::error::Error, + ) -> Vec { + vec![Diagnostic { + range: span_to_range(location), + severity: Some(DiagnosticSeverity::ERROR), + code: None, + code_description: None, + source: Some("numbat".to_string()), + message: error.to_string(), + related_information: None, + tags: None, + data: None, + }] + } + + async fn defined_here_diagnostic( + &self, + error_location: Span, + defined_here: Span, + error: impl std::error::Error, + ) -> Vec { + vec![Diagnostic { + range: span_to_range(error_location), + severity: Some(DiagnosticSeverity::ERROR), + code: None, + code_description: None, + source: Some("numbat".to_string()), + message: error.to_string(), + related_information: Some(vec![DiagnosticRelatedInformation { + location: self.span_to_location(defined_here).await, + message: "Defined here".to_string(), + }]), + tags: None, + data: None, + }] + } + + async fn name_resolution_diagnostic(&self, error: NameResolutionError) -> Vec { + match error { + NameResolutionError::IdentifierClash { + conflicting_identifier: _, + conflict_span, + original_span, + original_item_type: _, + } => { + self.defined_here_diagnostic(conflict_span, original_span, error) + .await + } + NameResolutionError::ReservedIdentifier(span) => { + self.simple_diagnostic(span, error).await + } + } + } + + async fn typecheck_diagnostic(&self, error: TypeCheckError) -> Vec { + match error { + TypeCheckError::UnknownIdentifier(span, _, _) + | TypeCheckError::NonScalarExponent(span, _) + | TypeCheckError::NonScalarFactorialArgument(span, _) + | TypeCheckError::UnsupportedConstEvalExpression(span, _) + | TypeCheckError::DivisionByZeroInConstEvalExpression(span) + | TypeCheckError::TypeParameterNameClash(span, _) + | TypeCheckError::ForeignFunctionNeedsTypeAnnotations(span, _) + | TypeCheckError::UnknownForeignFunction(span, _) + | TypeCheckError::NonRationalExponent(span) + | TypeCheckError::OverflowInConstExpr(span) + | TypeCheckError::ExpectedDimensionType(span, _) + | TypeCheckError::ExpectedBool(span) + | TypeCheckError::MissingDimension(span, _) + | TypeCheckError::NoFunctionReferenceToGenericFunction(span) + | TypeCheckError::OnlyFunctionsAndReferencesCanBeCalled(span) + | TypeCheckError::NoDimensionlessBaseUnit(span, _) + | TypeCheckError::UnknownStruct(span, _) + | TypeCheckError::MissingDimBound(span) + | TypeCheckError::ExponentiationNeedsTypeAnnotation(span) + | TypeCheckError::DerivedUnitDefinitionMustNotBeGeneric(span) + | TypeCheckError::TypedHoleInStatement(span, _, _, _) + | TypeCheckError::MultipleTypedHoles(span) + | TypeCheckError::WrongArity { + callable_span: span, + callable_name: _, + callable_definition_span: None, + arity: _, + num_args: _, + } + | TypeCheckError::IncompatibleAlternativeDimensionExpression(_, span, _, _, _) => { + self.simple_diagnostic(span, error).await + } + + // Defined here stuff + TypeCheckError::WrongArity { + callable_span: span, + callable_name: _, + callable_definition_span: Some(here), + arity: _, + num_args: _, + } => self.defined_here_diagnostic(span, here, error).await, + + // Stuff with no span + TypeCheckError::ConstraintSolverError(_, _) + | TypeCheckError::RegistryError(_) + | TypeCheckError::SubstitutionError(_, _) => { + self.diagnostic_without_location(error).await + } + + // Complex stuff + TypeCheckError::IncompatibleDimensions(IncompatibleDimensionsError { + span_operation, + operation: _, + span_expected, + expected_name: _, + expected_type: _, + expected_dimensions: _, + span_actual, + actual_name: _, + actual_name_for_fix, + actual_type: _, + actual_dimensions: _, + }) => { + vec![Diagnostic { + range: span_to_range(span_operation), + severity: Some(DiagnosticSeverity::ERROR), + code: None, + code_description: None, + source: Some("numbat".to_string()), + message: error.to_string(), + related_information: Some(vec![ + DiagnosticRelatedInformation { + location: self.span_to_location(span_actual).await, + message: format!("Expected {actual_name_for_fix}"), + }, + DiagnosticRelatedInformation { + location: self.span_to_location(span_expected).await, + message: "Defined here".to_string(), + }, + ]), + tags: None, + data: None, + }] + } + TypeCheckError::NameResolutionError(err) => self.name_resolution_diagnostic(err).await, + + // TODO: Should be improved + TypeCheckError::IncompatibleTypesInCondition(span, _, _, _, _) + | TypeCheckError::IncompatibleTypeInAssert(span, _, _) + | TypeCheckError::IncompatibleTypesInAssertEq(span, _, _, _, _) + | TypeCheckError::IncompatibleTypesInAnnotation(_, span, _, _, _, _) + | TypeCheckError::IncompatibleTypesInComparison(span, _, _, _, _) + | TypeCheckError::IncompatibleTypesInOperator(span, _, _, _, _, _) + | TypeCheckError::IncompatibleTypesInFunctionCall(_, _, span, _) + | TypeCheckError::IncompatibleTypesForStructField(span, _, _, _) + | TypeCheckError::UnknownFieldInStructInstantiation(span, _, _, _) + | TypeCheckError::DuplicateFieldInStructDefinition(span, _, _) + | TypeCheckError::DuplicateFieldInStructInstantiation(span, _, _) + | TypeCheckError::FieldAccessOfNonStructType(span, _, _, _) + | TypeCheckError::UnknownFieldAccess(span, _, _, _) + | TypeCheckError::MissingFieldsInStructInstantiation(span, _, _) + | TypeCheckError::IncompatibleTypesInList(span, _, _, _) => { + self.simple_diagnostic(span, error).await + } + } + } + + async fn span_to_location(&self, span: Span) -> Location { + let code_source = self + .context + .lock() + .await + .resolver() + .get_code_source(span.code_source_id); + let uri = match code_source { + CodeSource::Text => unreachable!("You cannot run the lsp without a file right?"), + CodeSource::Internal => PathBuf::from_str("").unwrap(), + CodeSource::File(path) | CodeSource::Module(_, Some(path)) => path, + CodeSource::Module(_, None) => todo!(), + }; + + Location { + uri: Url::from_file_path(uri).unwrap(), + range: span_to_range(span), + } + } +} + +fn span_to_range(span: Span) -> Range { + Range { + start: Position { + line: span.start.line - 1, + character: span.start.position - 1, + }, + end: Position { + line: span.end.line - 1, + character: span.end.position - 1, + }, + } +} + +#[tokio::main] +async fn main() { + env_logger::init(); + + let stdin = tokio::io::stdin(); + let stdout = tokio::io::stdout(); + + let mut fs_importer = FileSystemImporter::default(); + for path in get_modules_paths().await { + fs_importer.add_path(path); + } + + let importer = ChainedImporter::new( + Box::new(fs_importer), + Box::::default(), + ); + + let mut context = Context::new(importer); + context.set_terminal_width(Some(60)); + /// TODO: Store everything for the goto-definition maybe? + let _result = context + .interpret("use prelude", CodeSource::Internal) + .unwrap(); + + /// TODO: Store everything for the goto-definition maybe? + let user_init_path = get_config_path().await.join("init.nbt"); + if let Ok(user_init_code) = tokio::fs::read_to_string(&user_init_path).await { + let _result = context + .interpret(&user_init_code, CodeSource::File(user_init_path)) + .unwrap(); + } + + let (service, socket) = LspService::build(|client| Backend { + client, + ast_map: Default::default(), + document_map: Default::default(), + semantic_token_map: Default::default(), + + context: Arc::new(Mutex::new(context)), + }) + .finish(); + + Server::new(stdin, stdout, socket).serve(service).await; +} + +fn offset_to_position(offset: usize, rope: &Rope) -> Option { + let line = rope.try_char_to_line(offset).ok()?; + let first_char_of_line = rope.try_line_to_char(line).ok()?; + let column = offset - first_char_of_line; + Some(Position::new(line as u32, column as u32)) +} + +async fn get_modules_paths() -> Vec { + let mut paths = vec![]; + + if let Some(modules_path) = std::env::var_os("NUMBAT_MODULES_PATH") { + for path in modules_path.to_string_lossy().split(':') { + paths.push(path.into()); + } + } + + paths.push(get_config_path().await.join("modules")); + + // We read the value of this environment variable at compile time to + // allow package maintainers to control the system-wide module path + // for Numbat. + if let Some(system_module_path) = option_env!("NUMBAT_SYSTEM_MODULE_PATH") { + if !system_module_path.is_empty() { + paths.push(system_module_path.into()); + } + } else if cfg!(unix) { + paths.push("/usr/share/numbat/modules".into()); + } else { + paths.push("C:\\Program Files\\numbat\\modules".into()); + } + paths +} + +async fn get_config_path() -> PathBuf { + let config_dir = tokio::task::spawn_blocking(dirs::config_dir) + .await + .unwrap() + .unwrap_or_else(|| PathBuf::from(".")); + config_dir.join("numbat") +} diff --git a/numbat-lsp/src/reference.rs b/numbat-lsp/src/reference.rs new file mode 100644 index 000000000..16f03d70c --- /dev/null +++ b/numbat-lsp/src/reference.rs @@ -0,0 +1,218 @@ +use std::collections::HashMap; + +use chumsky::Span; +use im_rc::Vector; + +use crate::chumsky::{Expr, Func, Spanned}; +#[derive(Debug, Clone)] +pub enum ReferenceSymbol { + Founded(Spanned), + Founding(usize), +} +use ReferenceSymbol::*; +pub fn get_reference( + ast: &HashMap, + ident_offset: usize, + include_self: bool, +) -> Vec> { + let mut vector = Vector::new(); + let mut reference_list = vec![]; + // for (_, v) in ast.iter() { + // if v.name.1.end < ident_offset { + // vector.push_back(v.name.clone()); + // } + // } + let mut kv_list = ast.iter().collect::>(); + kv_list.sort_by(|a, b| a.1.name.start().cmp(&b.1.name.start())); + let mut reference_symbol = ReferenceSymbol::Founding(ident_offset); + // let mut fn_vector = Vector::new(); + for (_, v) in kv_list { + let (_, range) = &v.name; + if ident_offset >= range.start && ident_offset < range.end { + reference_symbol = ReferenceSymbol::Founded(v.name.clone()); + if include_self { + reference_list.push(v.name.clone()); + } + }; + vector.push_back(v.name.clone()); + let args = v + .args + .iter() + .map(|arg| { + if ident_offset >= arg.1.start && ident_offset < arg.1.end { + reference_symbol = ReferenceSymbol::Founded(arg.clone()); + if include_self { + reference_list.push(arg.clone()); + } + } + arg.clone() + }) + .collect::>(); + get_reference_of_expr( + &v.body, + args + vector.clone(), + reference_symbol.clone(), + &mut reference_list, + include_self, + ); + } + reference_list +} + +pub fn get_reference_of_expr( + expr: &Spanned, + definition_ass_list: Vector>, + reference_symbol: ReferenceSymbol, + reference_list: &mut Vec>, + include_self: bool, +) { + match &expr.0 { + Expr::Error => {} + Expr::Value(_) => {} + Expr::Local((name, span)) => { + if let Founded((symbol_name, symbol_span)) = reference_symbol { + if &symbol_name == name { + let index = definition_ass_list + .iter() + .position(|decl| decl.0 == symbol_name); + if let Some(symbol) = index.map(|i| definition_ass_list.get(i).unwrap().clone()) + { + if symbol == (symbol_name, symbol_span) { + reference_list.push((name.clone(), span.clone())); + } + }; + } + } + // if ident_offset >= local.1.start && ident_offset < local.1.end { + // let index = definition_ass_list + // .iter() + // .position(|decl| decl.0 == local.0); + // ( + // false, + // index.map(|i| definition_ass_list.get(i).unwrap().clone()), + // ) + // } else { + // (true, None) + // } + } + Expr::Let(name, lhs, rest, name_span) => { + let new_decl = Vector::unit((name.clone(), name_span.clone())); + let next_symbol = match reference_symbol { + Founding(ident) if ident >= name_span.start && ident < name_span.end => { + let spanned_name = (name.clone(), name_span.clone()); + if include_self { + reference_list.push(spanned_name.clone()); + } + ReferenceSymbol::Founded(spanned_name) + } + _ => reference_symbol, + }; + + get_reference_of_expr( + lhs, + definition_ass_list.clone(), + next_symbol.clone(), + reference_list, + include_self, + ); + get_reference_of_expr( + rest, + new_decl + definition_ass_list, + next_symbol, + reference_list, + include_self, + ); + } + Expr::Then(first, second) => { + get_reference_of_expr( + first, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + get_reference_of_expr( + second, + definition_ass_list, + reference_symbol, + reference_list, + include_self, + ); + } + Expr::Binary(lhs, _op, rhs) => { + get_reference_of_expr( + lhs, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + get_reference_of_expr( + rhs, + definition_ass_list, + reference_symbol, + reference_list, + include_self, + ); + } + Expr::Call(callee, args) => { + get_reference_of_expr( + callee, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + for expr in &args.0 { + get_reference_of_expr( + expr, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + } + } + Expr::If(test, consequent, alternative) => { + get_reference_of_expr( + test, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + get_reference_of_expr( + consequent, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + get_reference_of_expr( + alternative, + definition_ass_list, + reference_symbol.clone(), + reference_list, + include_self, + ); + } + Expr::Print(expr) => get_reference_of_expr( + expr, + definition_ass_list, + reference_symbol, + reference_list, + include_self, + ), + Expr::List(lst) => { + for expr in lst { + get_reference_of_expr( + expr, + definition_ass_list.clone(), + reference_symbol.clone(), + reference_list, + include_self, + ); + } + } + } +} diff --git a/numbat-lsp/src/semantic_token.rs b/numbat-lsp/src/semantic_token.rs new file mode 100644 index 000000000..b707424ea --- /dev/null +++ b/numbat-lsp/src/semantic_token.rs @@ -0,0 +1,100 @@ +use std::collections::HashMap; + +use tower_lsp::lsp_types::SemanticTokenType; + +use crate::chumsky::{Expr, Func, ImCompleteSemanticToken, Spanned}; + +pub const LEGEND_TYPE: &[SemanticTokenType] = &[ + SemanticTokenType::FUNCTION, + SemanticTokenType::VARIABLE, + SemanticTokenType::STRING, + SemanticTokenType::COMMENT, + SemanticTokenType::NUMBER, + SemanticTokenType::KEYWORD, + SemanticTokenType::OPERATOR, + SemanticTokenType::PARAMETER, +]; + +pub fn semantic_token_from_ast(ast: &HashMap) -> Vec { + let mut semantic_tokens = vec![]; + + ast.iter().for_each(|(_func_name, function)| { + function.args.iter().for_each(|(_, span)| { + semantic_tokens.push(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::PARAMETER) + .unwrap(), + }); + }); + let (_, span) = &function.name; + semantic_tokens.push(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::FUNCTION) + .unwrap(), + }); + semantic_token_from_expr(&function.body, &mut semantic_tokens); + }); + + semantic_tokens +} + +pub fn semantic_token_from_expr( + expr: &Spanned, + semantic_tokens: &mut Vec, +) { + match &expr.0 { + Expr::Error => {} + Expr::Value(_) => {} + Expr::List(_) => {} + Expr::Local((_name, span)) => { + semantic_tokens.push(ImCompleteSemanticToken { + start: span.start, + length: span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::VARIABLE) + .unwrap(), + }); + } + Expr::Let(_, rhs, rest, name_span) => { + semantic_tokens.push(ImCompleteSemanticToken { + start: name_span.start, + length: name_span.len(), + token_type: LEGEND_TYPE + .iter() + .position(|item| item == &SemanticTokenType::VARIABLE) + .unwrap(), + }); + semantic_token_from_expr(rhs, semantic_tokens); + semantic_token_from_expr(rest, semantic_tokens); + } + Expr::Then(first, rest) => { + semantic_token_from_expr(first, semantic_tokens); + semantic_token_from_expr(rest, semantic_tokens); + } + Expr::Binary(lhs, _op, rhs) => { + semantic_token_from_expr(lhs, semantic_tokens); + semantic_token_from_expr(rhs, semantic_tokens); + } + Expr::Call(expr, params) => { + semantic_token_from_expr(expr, semantic_tokens); + params.0.iter().for_each(|p| { + semantic_token_from_expr(p, semantic_tokens); + }); + } + Expr::If(test, consequent, alternative) => { + semantic_token_from_expr(test, semantic_tokens); + semantic_token_from_expr(consequent, semantic_tokens); + semantic_token_from_expr(alternative, semantic_tokens); + } + Expr::Print(expr) => { + semantic_token_from_expr(expr, semantic_tokens); + } + } +} diff --git a/numbat-lsp/src/utils.rs b/numbat-lsp/src/utils.rs new file mode 100644 index 000000000..e69de29bb diff --git a/numbat-lsp/tsconfig.json b/numbat-lsp/tsconfig.json new file mode 100644 index 000000000..23208872e --- /dev/null +++ b/numbat-lsp/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es2019", + "lib": ["ES2019"], + "outDir": "out", + "rootDir": "src", + "sourceMap": true + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + ".vscode-test" + ], + "references": [ + { "path": "./client" }, + ] +} diff --git a/numbat-lsp/webpack.config.js b/numbat-lsp/webpack.config.js new file mode 100644 index 000000000..2b0b38769 --- /dev/null +++ b/numbat-lsp/webpack.config.js @@ -0,0 +1,44 @@ +//@ts-check + +"use strict"; + +const path = require("path"); + +/**@type {import('webpack').Configuration}*/ +const config = { + target: "webworker", // vscode extensions run in webworker context for VS Code web 📖 -> https://webpack.js.org/configuration/target/#target + + entry: "./client/src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ + output: { + // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ + path: path.resolve(__dirname, "dist"), + filename: "extension.js", + libraryTarget: "commonjs2", + devtoolModuleFilenameTemplate: "../[resource-path]", + }, + devtool: "hidden-source-map", + externals: { + vscode: + "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ + }, + resolve: { + // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader + mainFields: ["browser", "module", "main"], // look for `browser` entry point in imported node modules + extensions: [".ts", ".js"], + alias: {}, + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: [ + { + loader: "ts-loader", + }, + ], + }, + ], + }, +}; +module.exports = config; diff --git a/numbat/src/lib.rs b/numbat/src/lib.rs index 259363e10..8e4704804 100644 --- a/numbat/src/lib.rs +++ b/numbat/src/lib.rs @@ -61,7 +61,7 @@ use resolver::CodeSource; use resolver::Resolver; use resolver::ResolverError; use thiserror::Error; -use typechecker::{TypeCheckError, TypeChecker}; +use typechecker::TypeChecker; pub use diagnostic::Diagnostic; pub use interpreter::InterpreterResult; @@ -71,6 +71,8 @@ pub use name_resolution::NameResolutionError; pub use parser::ParseError; pub use registry::BaseRepresentation; pub use registry::BaseRepresentationFactor; +pub use span::Span; +pub use typechecker::{IncompatibleDimensionsError, TypeCheckError}; pub use typed_ast::Statement; pub use typed_ast::Type; use unit::BaseUnitAndFactor;